Bug 1426596 - Update Angle to TreeTop for testing draft
authorChih-Yi Leu <subsevenx2001@gmail.com>
Tue, 09 Jan 2018 14:07:52 +0800
changeset 720335 77dc0efe35f6b4275a897ca219eac8771bf4219d
parent 720191 21ddfb9e6cc008e47da89db50e22697dc7b38635
child 720336 31fd5af7a5f05dfaa79293c01db32b30a2ec865c
push id95513
push userbmo:cleu@mozilla.com
push dateMon, 15 Jan 2018 09:32:04 +0000
bugs1426596
milestone59.0a1
Bug 1426596 - Update Angle to TreeTop for testing MozReview-Commit-ID: IhNNvC04wmH
gfx/angle/AUTHORS
gfx/angle/BUILD.gn
gfx/angle/CONTRIBUTORS
gfx/angle/DEPS
gfx/angle/DEPS.chromium
gfx/angle/OWNERS
gfx/angle/README.md
gfx/angle/include/EGL/eglext_angle.h
gfx/angle/include/GLES2/gl2ext_angle.h
gfx/angle/include/GLSLANG/ShaderLang.h
gfx/angle/include/GLSLANG/ShaderVars.h
gfx/angle/include/platform/Platform.h
gfx/angle/include/platform/WorkaroundsD3D.h
gfx/angle/moz.build
gfx/angle/src/angle.gyp
gfx/angle/src/commit_id.py
gfx/angle/src/common/angleutils.cpp
gfx/angle/src/common/angleutils.h
gfx/angle/src/common/angleutils_unittest.cpp
gfx/angle/src/common/bitset_utils.h
gfx/angle/src/common/gen_uniform_type_table.py
gfx/angle/src/common/mathutil.h
gfx/angle/src/common/mathutil_unittest.cpp
gfx/angle/src/common/platform.h
gfx/angle/src/common/string_utils.cpp
gfx/angle/src/common/string_utils.h
gfx/angle/src/common/string_utils_unittest.cpp
gfx/angle/src/common/third_party/murmurhash/LICENSE
gfx/angle/src/common/third_party/murmurhash/MurmurHash3.cpp
gfx/angle/src/common/third_party/murmurhash/MurmurHash3.h
gfx/angle/src/common/third_party/smhasher/LICENSE
gfx/angle/src/common/third_party/smhasher/README.angle
gfx/angle/src/common/third_party/smhasher/src/PMurHash.cpp
gfx/angle/src/common/third_party/smhasher/src/PMurHash.h
gfx/angle/src/common/uniform_type_info_autogen.cpp
gfx/angle/src/common/utilities.cpp
gfx/angle/src/common/utilities.h
gfx/angle/src/common/utilities_unittest.cpp
gfx/angle/src/compiler.gypi
gfx/angle/src/compiler/preprocessor/DiagnosticsBase.cpp
gfx/angle/src/compiler/preprocessor/DirectiveParser.cpp
gfx/angle/src/compiler/preprocessor/DirectiveParser.h
gfx/angle/src/compiler/preprocessor/ExpressionParser.cpp
gfx/angle/src/compiler/preprocessor/ExpressionParser.y
gfx/angle/src/compiler/preprocessor/Input.cpp
gfx/angle/src/compiler/preprocessor/Input.h
gfx/angle/src/compiler/preprocessor/Macro.cpp
gfx/angle/src/compiler/preprocessor/Macro.h
gfx/angle/src/compiler/preprocessor/MacroExpander.cpp
gfx/angle/src/compiler/preprocessor/MacroExpander.h
gfx/angle/src/compiler/preprocessor/Tokenizer.cpp
gfx/angle/src/compiler/preprocessor/Tokenizer.h
gfx/angle/src/compiler/preprocessor/Tokenizer.l
gfx/angle/src/compiler/translator/ASTMetadataHLSL.cpp
gfx/angle/src/compiler/translator/ArrayReturnValueToOutParameter.cpp
gfx/angle/src/compiler/translator/BaseTypes.h
gfx/angle/src/compiler/translator/BuiltInFunctionEmulator.cpp
gfx/angle/src/compiler/translator/BuiltInFunctionEmulatorGLSL.cpp
gfx/angle/src/compiler/translator/Cache.cpp
gfx/angle/src/compiler/translator/Cache.h
gfx/angle/src/compiler/translator/CallDAG.cpp
gfx/angle/src/compiler/translator/CallDAG.h
gfx/angle/src/compiler/translator/ClampPointSize.cpp
gfx/angle/src/compiler/translator/CollectVariables.cpp
gfx/angle/src/compiler/translator/Common.h
gfx/angle/src/compiler/translator/Compiler.cpp
gfx/angle/src/compiler/translator/Compiler.h
gfx/angle/src/compiler/translator/Declarator.cpp
gfx/angle/src/compiler/translator/Declarator.h
gfx/angle/src/compiler/translator/DeclareAndInitBuiltinsForInstancedMultiview.cpp
gfx/angle/src/compiler/translator/DeferGlobalInitializers.cpp
gfx/angle/src/compiler/translator/DeferGlobalInitializers.h
gfx/angle/src/compiler/translator/Diagnostics.cpp
gfx/angle/src/compiler/translator/Diagnostics.h
gfx/angle/src/compiler/translator/EmulateGLFragColorBroadcast.cpp
gfx/angle/src/compiler/translator/EmulatePrecision.cpp
gfx/angle/src/compiler/translator/EmulatePrecision.h
gfx/angle/src/compiler/translator/ExpandIntegerPowExpressions.cpp
gfx/angle/src/compiler/translator/ExtensionBehavior.cpp
gfx/angle/src/compiler/translator/ExtensionBehavior.h
gfx/angle/src/compiler/translator/FindMain.cpp
gfx/angle/src/compiler/translator/FindSymbolNode.cpp
gfx/angle/src/compiler/translator/FindSymbolNode.h
gfx/angle/src/compiler/translator/FlagStd140Structs.cpp
gfx/angle/src/compiler/translator/FlagStd140Structs.h
gfx/angle/src/compiler/translator/FoldExpressions.cpp
gfx/angle/src/compiler/translator/FoldExpressions.h
gfx/angle/src/compiler/translator/HashNames.cpp
gfx/angle/src/compiler/translator/HashNames.h
gfx/angle/src/compiler/translator/ImageFunctionHLSL.cpp
gfx/angle/src/compiler/translator/ImageFunctionHLSL.h
gfx/angle/src/compiler/translator/Initialize.cpp
gfx/angle/src/compiler/translator/InitializeDll.cpp
gfx/angle/src/compiler/translator/InitializeVariables.cpp
gfx/angle/src/compiler/translator/InitializeVariables.h
gfx/angle/src/compiler/translator/IntermNode.cpp
gfx/angle/src/compiler/translator/IntermNode.h
gfx/angle/src/compiler/translator/IntermNodePatternMatcher.cpp
gfx/angle/src/compiler/translator/IntermNodePatternMatcher.h
gfx/angle/src/compiler/translator/IntermNode_util.cpp
gfx/angle/src/compiler/translator/IntermNode_util.h
gfx/angle/src/compiler/translator/IntermTraverse.cpp
gfx/angle/src/compiler/translator/IntermTraverse.h
gfx/angle/src/compiler/translator/OutputGLSL.cpp
gfx/angle/src/compiler/translator/OutputGLSLBase.cpp
gfx/angle/src/compiler/translator/OutputGLSLBase.h
gfx/angle/src/compiler/translator/OutputHLSL.cpp
gfx/angle/src/compiler/translator/OutputHLSL.h
gfx/angle/src/compiler/translator/OutputTree.cpp
gfx/angle/src/compiler/translator/OutputVulkanGLSL.cpp
gfx/angle/src/compiler/translator/OutputVulkanGLSL.h
gfx/angle/src/compiler/translator/ParseContext.cpp
gfx/angle/src/compiler/translator/ParseContext.h
gfx/angle/src/compiler/translator/PruneEmptyDeclarations.cpp
gfx/angle/src/compiler/translator/PruneEmptyDeclarations.h
gfx/angle/src/compiler/translator/PruneNoOps.cpp
gfx/angle/src/compiler/translator/PruneNoOps.h
gfx/angle/src/compiler/translator/PrunePureLiteralStatements.cpp
gfx/angle/src/compiler/translator/PrunePureLiteralStatements.h
gfx/angle/src/compiler/translator/QualifierTypes.cpp
gfx/angle/src/compiler/translator/RecordConstantPrecision.cpp
gfx/angle/src/compiler/translator/RegenerateStructNames.cpp
gfx/angle/src/compiler/translator/RegenerateStructNames.h
gfx/angle/src/compiler/translator/RemoveArrayLengthMethod.cpp
gfx/angle/src/compiler/translator/RemoveArrayLengthMethod.h
gfx/angle/src/compiler/translator/RemoveDynamicIndexing.cpp
gfx/angle/src/compiler/translator/RemoveDynamicIndexing.h
gfx/angle/src/compiler/translator/RemoveEmptySwitchStatements.cpp
gfx/angle/src/compiler/translator/RemoveEmptySwitchStatements.h
gfx/angle/src/compiler/translator/RemoveNoOpCasesFromEndOfSwitchStatements.cpp
gfx/angle/src/compiler/translator/RemoveNoOpCasesFromEndOfSwitchStatements.h
gfx/angle/src/compiler/translator/RemoveSwitchFallThrough.cpp
gfx/angle/src/compiler/translator/RemoveSwitchFallThrough.h
gfx/angle/src/compiler/translator/RemoveUnreferencedVariables.cpp
gfx/angle/src/compiler/translator/RemoveUnreferencedVariables.h
gfx/angle/src/compiler/translator/RewriteDoWhile.cpp
gfx/angle/src/compiler/translator/RewriteElseBlocks.cpp
gfx/angle/src/compiler/translator/RewriteTexelFetchOffset.cpp
gfx/angle/src/compiler/translator/RunAtTheEndOfShader.cpp
gfx/angle/src/compiler/translator/ScalarizeVecAndMatConstructorArgs.cpp
gfx/angle/src/compiler/translator/SearchSymbol.cpp
gfx/angle/src/compiler/translator/SearchSymbol.h
gfx/angle/src/compiler/translator/SeparateExpressionsReturningArrays.cpp
gfx/angle/src/compiler/translator/ShaderLang.cpp
gfx/angle/src/compiler/translator/ShaderVars.cpp
gfx/angle/src/compiler/translator/SimplifyLoopConditions.cpp
gfx/angle/src/compiler/translator/SplitSequenceOperator.cpp
gfx/angle/src/compiler/translator/StaticType.cpp
gfx/angle/src/compiler/translator/StaticType.h
gfx/angle/src/compiler/translator/StructureHLSL.cpp
gfx/angle/src/compiler/translator/StructureHLSL.h
gfx/angle/src/compiler/translator/Symbol.cpp
gfx/angle/src/compiler/translator/Symbol.h
gfx/angle/src/compiler/translator/SymbolTable.cpp
gfx/angle/src/compiler/translator/SymbolTable.h
gfx/angle/src/compiler/translator/SymbolUniqueId.cpp
gfx/angle/src/compiler/translator/SymbolUniqueId.h
gfx/angle/src/compiler/translator/TranslatorESSL.cpp
gfx/angle/src/compiler/translator/TranslatorESSL.h
gfx/angle/src/compiler/translator/TranslatorGLSL.cpp
gfx/angle/src/compiler/translator/TranslatorGLSL.h
gfx/angle/src/compiler/translator/TranslatorHLSL.cpp
gfx/angle/src/compiler/translator/TranslatorHLSL.h
gfx/angle/src/compiler/translator/TranslatorVulkan.cpp
gfx/angle/src/compiler/translator/TranslatorVulkan.h
gfx/angle/src/compiler/translator/Types.cpp
gfx/angle/src/compiler/translator/Types.h
gfx/angle/src/compiler/translator/UnfoldShortCircuitToIf.cpp
gfx/angle/src/compiler/translator/UniformHLSL.cpp
gfx/angle/src/compiler/translator/UniformHLSL.h
gfx/angle/src/compiler/translator/UseInterfaceBlockFields.cpp
gfx/angle/src/compiler/translator/UtilsHLSL.cpp
gfx/angle/src/compiler/translator/UtilsHLSL.h
gfx/angle/src/compiler/translator/ValidateGlobalInitializer.cpp
gfx/angle/src/compiler/translator/ValidateGlobalInitializer.h
gfx/angle/src/compiler/translator/ValidateLimitations.cpp
gfx/angle/src/compiler/translator/ValidateOutputs.cpp
gfx/angle/src/compiler/translator/ValidateSwitch.cpp
gfx/angle/src/compiler/translator/ValidateSwitch.h
gfx/angle/src/compiler/translator/ValidateVaryingLocations.cpp
gfx/angle/src/compiler/translator/ValidateVaryingLocations.h
gfx/angle/src/compiler/translator/VariablePacker.cpp
gfx/angle/src/compiler/translator/VariablePacker.h
gfx/angle/src/compiler/translator/VectorizeVectorScalarArithmetic.cpp
gfx/angle/src/compiler/translator/VectorizeVectorScalarArithmetic.h
gfx/angle/src/compiler/translator/VersionGLSL.cpp
gfx/angle/src/compiler/translator/WrapSwitchStatementsInBlocks.cpp
gfx/angle/src/compiler/translator/WrapSwitchStatementsInBlocks.h
gfx/angle/src/compiler/translator/blocklayout.cpp
gfx/angle/src/compiler/translator/blocklayout.h
gfx/angle/src/compiler/translator/blocklayoutHLSL.cpp
gfx/angle/src/compiler/translator/blocklayoutHLSL.h
gfx/angle/src/compiler/translator/emulated_builtin_function_data_hlsl.json
gfx/angle/src/compiler/translator/emulated_builtin_functions_hlsl_autogen.cpp
gfx/angle/src/compiler/translator/generate_parser.sh
gfx/angle/src/compiler/translator/glslang.l
gfx/angle/src/compiler/translator/glslang.y
gfx/angle/src/compiler/translator/glslang_lex.cpp
gfx/angle/src/compiler/translator/glslang_tab.cpp
gfx/angle/src/compiler/translator/glslang_tab.h
gfx/angle/src/compiler/translator/util.cpp
gfx/angle/src/compiler/translator/util.h
gfx/angle/src/copy_compiler_dll.bat
gfx/angle/src/gpu_info_util/SystemInfo.cpp
gfx/angle/src/gpu_info_util/SystemInfo.h
gfx/angle/src/id/commit.h
gfx/angle/src/image_util/loadimage_etc.cpp
gfx/angle/src/libANGLE/AttributeMap.cpp
gfx/angle/src/libANGLE/AttributeMap.h
gfx/angle/src/libANGLE/BinaryStream.h
gfx/angle/src/libANGLE/Buffer.cpp
gfx/angle/src/libANGLE/Buffer.h
gfx/angle/src/libANGLE/Caps.cpp
gfx/angle/src/libANGLE/Caps.h
gfx/angle/src/libANGLE/Compiler.cpp
gfx/angle/src/libANGLE/Compiler.h
gfx/angle/src/libANGLE/Config.cpp
gfx/angle/src/libANGLE/Config.h
gfx/angle/src/libANGLE/Constants.h
gfx/angle/src/libANGLE/Context.cpp
gfx/angle/src/libANGLE/Context.h
gfx/angle/src/libANGLE/ContextState.cpp
gfx/angle/src/libANGLE/ContextState.h
gfx/angle/src/libANGLE/Debug.cpp
gfx/angle/src/libANGLE/Debug.h
gfx/angle/src/libANGLE/Display.cpp
gfx/angle/src/libANGLE/Display.h
gfx/angle/src/libANGLE/Error.cpp
gfx/angle/src/libANGLE/Error.h
gfx/angle/src/libANGLE/ErrorStrings.h
gfx/angle/src/libANGLE/Fence.cpp
gfx/angle/src/libANGLE/Fence.h
gfx/angle/src/libANGLE/Framebuffer.cpp
gfx/angle/src/libANGLE/Framebuffer.h
gfx/angle/src/libANGLE/FramebufferAttachment.cpp
gfx/angle/src/libANGLE/FramebufferAttachment.h
gfx/angle/src/libANGLE/HandleAllocator.cpp
gfx/angle/src/libANGLE/HandleAllocator.h
gfx/angle/src/libANGLE/HandleAllocator_unittest.cpp
gfx/angle/src/libANGLE/HandleRangeAllocator.cpp
gfx/angle/src/libANGLE/HandleRangeAllocator.h
gfx/angle/src/libANGLE/Image.cpp
gfx/angle/src/libANGLE/Image.h
gfx/angle/src/libANGLE/ImageIndex.cpp
gfx/angle/src/libANGLE/ImageIndex.h
gfx/angle/src/libANGLE/IndexRangeCache.cpp
gfx/angle/src/libANGLE/IndexRangeCache.h
gfx/angle/src/libANGLE/LoggingAnnotator.cpp
gfx/angle/src/libANGLE/LoggingAnnotator.h
gfx/angle/src/libANGLE/MemoryProgramCache.cpp
gfx/angle/src/libANGLE/PackedGLEnums.h
gfx/angle/src/libANGLE/PackedGLEnums_autogen.cpp
gfx/angle/src/libANGLE/PackedGLEnums_autogen.h
gfx/angle/src/libANGLE/Platform.cpp
gfx/angle/src/libANGLE/Program.cpp
gfx/angle/src/libANGLE/Program.h
gfx/angle/src/libANGLE/ProgramLinkedResources.cpp
gfx/angle/src/libANGLE/ProgramLinkedResources.h
gfx/angle/src/libANGLE/ProgramPipeline.cpp
gfx/angle/src/libANGLE/ProgramPipeline.h
gfx/angle/src/libANGLE/Query.h
gfx/angle/src/libANGLE/RefCountObject.h
gfx/angle/src/libANGLE/Renderbuffer.cpp
gfx/angle/src/libANGLE/Renderbuffer.h
gfx/angle/src/libANGLE/ResourceManager.cpp
gfx/angle/src/libANGLE/ResourceManager.h
gfx/angle/src/libANGLE/Sampler.cpp
gfx/angle/src/libANGLE/Sampler.h
gfx/angle/src/libANGLE/Shader.cpp
gfx/angle/src/libANGLE/Shader.h
gfx/angle/src/libANGLE/SizedMRUCache.h
gfx/angle/src/libANGLE/State.cpp
gfx/angle/src/libANGLE/State.h
gfx/angle/src/libANGLE/Stream.cpp
gfx/angle/src/libANGLE/Stream.h
gfx/angle/src/libANGLE/Surface.cpp
gfx/angle/src/libANGLE/Surface.h
gfx/angle/src/libANGLE/Surface_unittest.cpp
gfx/angle/src/libANGLE/Texture.cpp
gfx/angle/src/libANGLE/Texture.h
gfx/angle/src/libANGLE/TransformFeedback.cpp
gfx/angle/src/libANGLE/TransformFeedback.h
gfx/angle/src/libANGLE/Uniform.cpp
gfx/angle/src/libANGLE/Uniform.h
gfx/angle/src/libANGLE/UniformLinker.cpp
gfx/angle/src/libANGLE/UniformLinker.h
gfx/angle/src/libANGLE/VaryingPacking.cpp
gfx/angle/src/libANGLE/VaryingPacking.h
gfx/angle/src/libANGLE/VaryingPacking_unittest.cpp
gfx/angle/src/libANGLE/Version.h
gfx/angle/src/libANGLE/Version.inl
gfx/angle/src/libANGLE/VertexArray.cpp
gfx/angle/src/libANGLE/VertexArray.h
gfx/angle/src/libANGLE/VertexAttribute.cpp
gfx/angle/src/libANGLE/VertexAttribute.h
gfx/angle/src/libANGLE/angletypes.cpp
gfx/angle/src/libANGLE/angletypes.h
gfx/angle/src/libANGLE/entry_points_enum_autogen.h
gfx/angle/src/libANGLE/format_map_autogen.cpp
gfx/angle/src/libANGLE/formatutils.cpp
gfx/angle/src/libANGLE/formatutils.h
gfx/angle/src/libANGLE/gen_format_map.py
gfx/angle/src/libANGLE/gen_packed_gl_enums.py
gfx/angle/src/libANGLE/moz.build
gfx/angle/src/libANGLE/packed_gl_enums.json
gfx/angle/src/libANGLE/params.cpp
gfx/angle/src/libANGLE/params.h
gfx/angle/src/libANGLE/queryconversions.cpp
gfx/angle/src/libANGLE/queryconversions.h
gfx/angle/src/libANGLE/queryutils.cpp
gfx/angle/src/libANGLE/queryutils.h
gfx/angle/src/libANGLE/renderer/BufferImpl.h
gfx/angle/src/libANGLE/renderer/BufferImpl_mock.h
gfx/angle/src/libANGLE/renderer/ContextImpl.h
gfx/angle/src/libANGLE/renderer/DisplayImpl.h
gfx/angle/src/libANGLE/renderer/EGLImplFactory.h
gfx/angle/src/libANGLE/renderer/Format.h
gfx/angle/src/libANGLE/renderer/Format_ID_autogen.inl
gfx/angle/src/libANGLE/renderer/Format_table_autogen.cpp
gfx/angle/src/libANGLE/renderer/FramebufferAttachmentObjectImpl.h
gfx/angle/src/libANGLE/renderer/FramebufferImpl.h
gfx/angle/src/libANGLE/renderer/FramebufferImpl_mock.h
gfx/angle/src/libANGLE/renderer/ProgramImpl.h
gfx/angle/src/libANGLE/renderer/ProgramImpl_mock.h
gfx/angle/src/libANGLE/renderer/RenderbufferImpl.h
gfx/angle/src/libANGLE/renderer/StreamProducerImpl.h
gfx/angle/src/libANGLE/renderer/SurfaceImpl.h
gfx/angle/src/libANGLE/renderer/TextureImpl.cpp
gfx/angle/src/libANGLE/renderer/TextureImpl.h
gfx/angle/src/libANGLE/renderer/TextureImpl_mock.h
gfx/angle/src/libANGLE/renderer/VertexArrayImpl.h
gfx/angle/src/libANGLE/renderer/angle_format.py
gfx/angle/src/libANGLE/renderer/angle_format_map.json
gfx/angle/src/libANGLE/renderer/d3d/BufferD3D.cpp
gfx/angle/src/libANGLE/renderer/d3d/BufferD3D.h
gfx/angle/src/libANGLE/renderer/d3d/CompilerD3D.cpp
gfx/angle/src/libANGLE/renderer/d3d/CompilerD3D.h
gfx/angle/src/libANGLE/renderer/d3d/DeviceD3D.cpp
gfx/angle/src/libANGLE/renderer/d3d/DeviceD3D.h
gfx/angle/src/libANGLE/renderer/d3d/DisplayD3D.cpp
gfx/angle/src/libANGLE/renderer/d3d/DisplayD3D.h
gfx/angle/src/libANGLE/renderer/d3d/DynamicHLSL.cpp
gfx/angle/src/libANGLE/renderer/d3d/DynamicHLSL.h
gfx/angle/src/libANGLE/renderer/d3d/FramebufferD3D.cpp
gfx/angle/src/libANGLE/renderer/d3d/FramebufferD3D.h
gfx/angle/src/libANGLE/renderer/d3d/ImageD3D.cpp
gfx/angle/src/libANGLE/renderer/d3d/ImageD3D.h
gfx/angle/src/libANGLE/renderer/d3d/IndexBuffer.cpp
gfx/angle/src/libANGLE/renderer/d3d/IndexBuffer.h
gfx/angle/src/libANGLE/renderer/d3d/IndexDataManager.cpp
gfx/angle/src/libANGLE/renderer/d3d/IndexDataManager.h
gfx/angle/src/libANGLE/renderer/d3d/ProgramD3D.cpp
gfx/angle/src/libANGLE/renderer/d3d/ProgramD3D.h
gfx/angle/src/libANGLE/renderer/d3d/RenderTargetD3D.h
gfx/angle/src/libANGLE/renderer/d3d/RenderbufferD3D.cpp
gfx/angle/src/libANGLE/renderer/d3d/RenderbufferD3D.h
gfx/angle/src/libANGLE/renderer/d3d/RendererD3D.cpp
gfx/angle/src/libANGLE/renderer/d3d/RendererD3D.h
gfx/angle/src/libANGLE/renderer/d3d/ShaderD3D.cpp
gfx/angle/src/libANGLE/renderer/d3d/ShaderD3D.h
gfx/angle/src/libANGLE/renderer/d3d/TextureD3D.cpp
gfx/angle/src/libANGLE/renderer/d3d/TextureD3D.h
gfx/angle/src/libANGLE/renderer/d3d/TextureStorage.h
gfx/angle/src/libANGLE/renderer/d3d/VertexBuffer.h
gfx/angle/src/libANGLE/renderer/d3d/VertexDataManager.cpp
gfx/angle/src/libANGLE/renderer/d3d/VertexDataManager.h
gfx/angle/src/libANGLE/renderer/d3d/d3d11/Blit11.cpp
gfx/angle/src/libANGLE/renderer/d3d/d3d11/Blit11.h
gfx/angle/src/libANGLE/renderer/d3d/d3d11/Buffer11.cpp
gfx/angle/src/libANGLE/renderer/d3d/d3d11/Buffer11.h
gfx/angle/src/libANGLE/renderer/d3d/d3d11/Clear11.cpp
gfx/angle/src/libANGLE/renderer/d3d/d3d11/Clear11.h
gfx/angle/src/libANGLE/renderer/d3d/d3d11/Context11.cpp
gfx/angle/src/libANGLE/renderer/d3d/d3d11/Context11.h
gfx/angle/src/libANGLE/renderer/d3d/d3d11/Fence11.cpp
gfx/angle/src/libANGLE/renderer/d3d/d3d11/Framebuffer11.cpp
gfx/angle/src/libANGLE/renderer/d3d/d3d11/Framebuffer11.h
gfx/angle/src/libANGLE/renderer/d3d/d3d11/Image11.cpp
gfx/angle/src/libANGLE/renderer/d3d/d3d11/Image11.h
gfx/angle/src/libANGLE/renderer/d3d/d3d11/IndexBuffer11.cpp
gfx/angle/src/libANGLE/renderer/d3d/d3d11/IndexBuffer11.h
gfx/angle/src/libANGLE/renderer/d3d/d3d11/InputLayoutCache.cpp
gfx/angle/src/libANGLE/renderer/d3d/d3d11/InputLayoutCache.h
gfx/angle/src/libANGLE/renderer/d3d/d3d11/PixelTransfer11.cpp
gfx/angle/src/libANGLE/renderer/d3d/d3d11/RenderStateCache.cpp
gfx/angle/src/libANGLE/renderer/d3d/d3d11/RenderTarget11.h
gfx/angle/src/libANGLE/renderer/d3d/d3d11/Renderer11.cpp
gfx/angle/src/libANGLE/renderer/d3d/d3d11/Renderer11.h
gfx/angle/src/libANGLE/renderer/d3d/d3d11/ResourceManager11.cpp
gfx/angle/src/libANGLE/renderer/d3d/d3d11/ResourceManager11.h
gfx/angle/src/libANGLE/renderer/d3d/d3d11/ShaderExecutable11.h
gfx/angle/src/libANGLE/renderer/d3d/d3d11/StateManager11.cpp
gfx/angle/src/libANGLE/renderer/d3d/d3d11/StateManager11.h
gfx/angle/src/libANGLE/renderer/d3d/d3d11/StreamProducerD3DTexture.cpp
gfx/angle/src/libANGLE/renderer/d3d/d3d11/StreamProducerD3DTexture.h
gfx/angle/src/libANGLE/renderer/d3d/d3d11/StreamProducerNV12.cpp
gfx/angle/src/libANGLE/renderer/d3d/d3d11/StreamProducerNV12.h
gfx/angle/src/libANGLE/renderer/d3d/d3d11/SwapChain11.cpp
gfx/angle/src/libANGLE/renderer/d3d/d3d11/SwapChain11.h
gfx/angle/src/libANGLE/renderer/d3d/d3d11/TextureStorage11.cpp
gfx/angle/src/libANGLE/renderer/d3d/d3d11/TextureStorage11.h
gfx/angle/src/libANGLE/renderer/d3d/d3d11/VertexArray11.cpp
gfx/angle/src/libANGLE/renderer/d3d/d3d11/VertexArray11.h
gfx/angle/src/libANGLE/renderer/d3d/d3d11/VertexBuffer11.cpp
gfx/angle/src/libANGLE/renderer/d3d/d3d11/dxgi_format_map_autogen.cpp
gfx/angle/src/libANGLE/renderer/d3d/d3d11/gen_texture_format_table.py
gfx/angle/src/libANGLE/renderer/d3d/d3d11/renderer11_utils.cpp
gfx/angle/src/libANGLE/renderer/d3d/d3d11/renderer11_utils.h
gfx/angle/src/libANGLE/renderer/d3d/d3d11/shaders/Passthrough2D11.hlsl
gfx/angle/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/buffertotexture11_gs.h
gfx/angle/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/buffertotexture11_ps_4f.h
gfx/angle/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/buffertotexture11_ps_4i.h
gfx/angle/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/buffertotexture11_ps_4ui.h
gfx/angle/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/buffertotexture11_vs.h
gfx/angle/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/clear11_fl9vs.h
gfx/angle/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/clear11multiviewgs.h
gfx/angle/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/clear11multiviewvs.h
gfx/angle/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/clear11vs.h
gfx/angle/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/cleardepth11ps.h
gfx/angle/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/clearfloat11_fl9ps.h
gfx/angle/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/clearfloat11ps1.h
gfx/angle/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/clearfloat11ps2.h
gfx/angle/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/clearfloat11ps3.h
gfx/angle/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/clearfloat11ps4.h
gfx/angle/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/clearfloat11ps5.h
gfx/angle/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/clearfloat11ps6.h
gfx/angle/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/clearfloat11ps7.h
gfx/angle/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/clearfloat11ps8.h
gfx/angle/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/clearsint11ps1.h
gfx/angle/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/clearsint11ps2.h
gfx/angle/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/clearsint11ps3.h
gfx/angle/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/clearsint11ps4.h
gfx/angle/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/clearsint11ps5.h
gfx/angle/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/clearsint11ps6.h
gfx/angle/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/clearsint11ps7.h
gfx/angle/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/clearsint11ps8.h
gfx/angle/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/clearuint11ps1.h
gfx/angle/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/clearuint11ps2.h
gfx/angle/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/clearuint11ps3.h
gfx/angle/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/clearuint11ps4.h
gfx/angle/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/clearuint11ps5.h
gfx/angle/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/clearuint11ps6.h
gfx/angle/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/clearuint11ps7.h
gfx/angle/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/clearuint11ps8.h
gfx/angle/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftof_pm_luma_ps.h
gfx/angle/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftof_pm_lumaalpha_ps.h
gfx/angle/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftof_pm_rgb_ps.h
gfx/angle/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftof_pm_rgba_ps.h
gfx/angle/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftof_um_luma_ps.h
gfx/angle/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftof_um_lumaalpha_ps.h
gfx/angle/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftof_um_rgb_ps.h
gfx/angle/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftof_um_rgba_ps.h
gfx/angle/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftou_pm_rgb_ps.h
gfx/angle/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftou_pm_rgba_ps.h
gfx/angle/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftou_pt_rgb_ps.h
gfx/angle/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftou_pt_rgba_ps.h
gfx/angle/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftou_um_rgb_ps.h
gfx/angle/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftou_um_rgba_ps.h
gfx/angle/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthrough2d11vs.h
gfx/angle/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthrough3d11gs.h
gfx/angle/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthrough3d11vs.h
gfx/angle/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthrougha2d11ps.h
gfx/angle/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughdepth2d11ps.h
gfx/angle/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughlum2d11ps.h
gfx/angle/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughlum3d11ps.h
gfx/angle/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughlumalpha2d11ps.h
gfx/angle/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughlumalpha3d11ps.h
gfx/angle/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughr2d11ps.h
gfx/angle/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughr2di11ps.h
gfx/angle/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughr2dui11ps.h
gfx/angle/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughr3d11ps.h
gfx/angle/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughr3di11ps.h
gfx/angle/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughr3dui11ps.h
gfx/angle/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrg2d11ps.h
gfx/angle/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrg2di11ps.h
gfx/angle/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrg2dui11ps.h
gfx/angle/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrg3d11ps.h
gfx/angle/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrg3di11ps.h
gfx/angle/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrg3dui11ps.h
gfx/angle/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrgb2d11ps.h
gfx/angle/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrgb2di11ps.h
gfx/angle/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrgb2dui11ps.h
gfx/angle/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrgb3d11ps.h
gfx/angle/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrgb3di11ps.h
gfx/angle/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrgb3dui11ps.h
gfx/angle/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrgba2d11ps.h
gfx/angle/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrgba2di11ps.h
gfx/angle/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrgba2dms11ps.h
gfx/angle/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrgba2dui11ps.h
gfx/angle/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrgba3d11ps.h
gfx/angle/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrgba3di11ps.h
gfx/angle/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrgba3dui11ps.h
gfx/angle/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/resolvedepth11_ps.h
gfx/angle/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/resolvedepthstencil11_ps.h
gfx/angle/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/resolvedepthstencil11_vs.h
gfx/angle/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/resolvestencil11_ps.h
gfx/angle/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/swizzlef2darrayps.h
gfx/angle/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/swizzlef2dps.h
gfx/angle/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/swizzlef3dps.h
gfx/angle/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/swizzlei2darrayps.h
gfx/angle/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/swizzlei2dps.h
gfx/angle/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/swizzlei3dps.h
gfx/angle/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/swizzleui2darrayps.h
gfx/angle/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/swizzleui2dps.h
gfx/angle/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/swizzleui3dps.h
gfx/angle/src/libANGLE/renderer/d3d/d3d11/shaders/generate_shaders.bat
gfx/angle/src/libANGLE/renderer/d3d/d3d11/texture_format_data.json
gfx/angle/src/libANGLE/renderer/d3d/d3d11/texture_format_map.json
gfx/angle/src/libANGLE/renderer/d3d/d3d11/texture_format_table.h
gfx/angle/src/libANGLE/renderer/d3d/d3d11/texture_format_table_autogen.cpp
gfx/angle/src/libANGLE/renderer/d3d/d3d9/Buffer9.cpp
gfx/angle/src/libANGLE/renderer/d3d/d3d9/Buffer9.h
gfx/angle/src/libANGLE/renderer/d3d/d3d9/Context9.cpp
gfx/angle/src/libANGLE/renderer/d3d/d3d9/Context9.h
gfx/angle/src/libANGLE/renderer/d3d/d3d9/Framebuffer9.cpp
gfx/angle/src/libANGLE/renderer/d3d/d3d9/Framebuffer9.h
gfx/angle/src/libANGLE/renderer/d3d/d3d9/Image9.cpp
gfx/angle/src/libANGLE/renderer/d3d/d3d9/Image9.h
gfx/angle/src/libANGLE/renderer/d3d/d3d9/IndexBuffer9.h
gfx/angle/src/libANGLE/renderer/d3d/d3d9/Query9.h
gfx/angle/src/libANGLE/renderer/d3d/d3d9/RenderTarget9.h
gfx/angle/src/libANGLE/renderer/d3d/d3d9/Renderer9.cpp
gfx/angle/src/libANGLE/renderer/d3d/d3d9/Renderer9.h
gfx/angle/src/libANGLE/renderer/d3d/d3d9/ShaderExecutable9.h
gfx/angle/src/libANGLE/renderer/d3d/d3d9/StateManager9.cpp
gfx/angle/src/libANGLE/renderer/d3d/d3d9/StateManager9.h
gfx/angle/src/libANGLE/renderer/d3d/d3d9/SwapChain9.cpp
gfx/angle/src/libANGLE/renderer/d3d/d3d9/SwapChain9.h
gfx/angle/src/libANGLE/renderer/d3d/d3d9/TextureStorage9.cpp
gfx/angle/src/libANGLE/renderer/d3d/d3d9/TextureStorage9.h
gfx/angle/src/libANGLE/renderer/d3d/d3d9/VertexArray9.h
gfx/angle/src/libANGLE/renderer/d3d/d3d9/formatutils9.cpp
gfx/angle/src/libANGLE/renderer/d3d/d3d9/formatutils9.h
gfx/angle/src/libANGLE/renderer/d3d/d3d9/renderer9_utils.cpp
gfx/angle/src/libANGLE/renderer/d3d/d3d9/renderer9_utils.h
gfx/angle/src/libANGLE/renderer/d3d/d3d9/shaders/Blit.ps
gfx/angle/src/libANGLE/renderer/d3d/d3d9/shaders/compiled/componentmaskpremultps.h
gfx/angle/src/libANGLE/renderer/d3d/d3d9/shaders/compiled/componentmaskps.h
gfx/angle/src/libANGLE/renderer/d3d/d3d9/shaders/compiled/componentmaskunmultps.h
gfx/angle/src/libANGLE/renderer/d3d/d3d9/shaders/compiled/luminancepremultps.h
gfx/angle/src/libANGLE/renderer/d3d/d3d9/shaders/compiled/luminanceps.h
gfx/angle/src/libANGLE/renderer/d3d/d3d9/shaders/compiled/luminanceunmultps.h
gfx/angle/src/libANGLE/renderer/d3d/d3d9/shaders/compiled/passthroughps.h
gfx/angle/src/libANGLE/renderer/d3d/d3d9/shaders/compiled/standardvs.h
gfx/angle/src/libANGLE/renderer/d3d/d3d9/shaders/generate_shaders.bat
gfx/angle/src/libANGLE/renderer/gen_angle_format_table.py
gfx/angle/src/libANGLE/renderer/gl/BlitGL.cpp
gfx/angle/src/libANGLE/renderer/gl/BufferGL.cpp
gfx/angle/src/libANGLE/renderer/gl/BufferGL.h
gfx/angle/src/libANGLE/renderer/gl/ClearMultiviewGL.cpp
gfx/angle/src/libANGLE/renderer/gl/CompilerGL.cpp
gfx/angle/src/libANGLE/renderer/gl/CompilerGL.h
gfx/angle/src/libANGLE/renderer/gl/ContextGL.cpp
gfx/angle/src/libANGLE/renderer/gl/ContextGL.h
gfx/angle/src/libANGLE/renderer/gl/DispatchTableGL_autogen.cpp
gfx/angle/src/libANGLE/renderer/gl/DispatchTableGL_autogen.h
gfx/angle/src/libANGLE/renderer/gl/DisplayGL.cpp
gfx/angle/src/libANGLE/renderer/gl/DisplayGL.h
gfx/angle/src/libANGLE/renderer/gl/FramebufferGL.cpp
gfx/angle/src/libANGLE/renderer/gl/FramebufferGL.h
gfx/angle/src/libANGLE/renderer/gl/FunctionsGL.cpp
gfx/angle/src/libANGLE/renderer/gl/FunctionsGL.h
gfx/angle/src/libANGLE/renderer/gl/PathGL.cpp
gfx/angle/src/libANGLE/renderer/gl/PathGL.h
gfx/angle/src/libANGLE/renderer/gl/ProgramGL.cpp
gfx/angle/src/libANGLE/renderer/gl/ProgramGL.h
gfx/angle/src/libANGLE/renderer/gl/QueryGL.cpp
gfx/angle/src/libANGLE/renderer/gl/RenderbufferGL.cpp
gfx/angle/src/libANGLE/renderer/gl/RenderbufferGL.h
gfx/angle/src/libANGLE/renderer/gl/RendererGL.cpp
gfx/angle/src/libANGLE/renderer/gl/RendererGL.h
gfx/angle/src/libANGLE/renderer/gl/ShaderGL.cpp
gfx/angle/src/libANGLE/renderer/gl/StateManagerGL.cpp
gfx/angle/src/libANGLE/renderer/gl/StateManagerGL.h
gfx/angle/src/libANGLE/renderer/gl/SurfaceGL.cpp
gfx/angle/src/libANGLE/renderer/gl/SurfaceGL.h
gfx/angle/src/libANGLE/renderer/gl/TextureGL.cpp
gfx/angle/src/libANGLE/renderer/gl/TextureGL.h
gfx/angle/src/libANGLE/renderer/gl/TransformFeedbackGL.cpp
gfx/angle/src/libANGLE/renderer/gl/VertexArrayGL.cpp
gfx/angle/src/libANGLE/renderer/gl/VertexArrayGL.h
gfx/angle/src/libANGLE/renderer/gl/WorkaroundsGL.h
gfx/angle/src/libANGLE/renderer/gl/cgl/DisplayCGL.h
gfx/angle/src/libANGLE/renderer/gl/cgl/DisplayCGL.mm
gfx/angle/src/libANGLE/renderer/gl/cgl/IOSurfaceSurfaceCGL.h
gfx/angle/src/libANGLE/renderer/gl/cgl/IOSurfaceSurfaceCGL.mm
gfx/angle/src/libANGLE/renderer/gl/egl/DisplayEGL.cpp
gfx/angle/src/libANGLE/renderer/gl/egl/FunctionsEGL.cpp
gfx/angle/src/libANGLE/renderer/gl/egl/FunctionsEGLDL.cpp
gfx/angle/src/libANGLE/renderer/gl/egl/FunctionsEGLDL.h
gfx/angle/src/libANGLE/renderer/gl/egl/PbufferSurfaceEGL.cpp
gfx/angle/src/libANGLE/renderer/gl/egl/PbufferSurfaceEGL.h
gfx/angle/src/libANGLE/renderer/gl/egl/SurfaceEGL.cpp
gfx/angle/src/libANGLE/renderer/gl/egl/SurfaceEGL.h
gfx/angle/src/libANGLE/renderer/gl/egl/WindowSurfaceEGL.cpp
gfx/angle/src/libANGLE/renderer/gl/egl/WindowSurfaceEGL.h
gfx/angle/src/libANGLE/renderer/gl/egl/android/DisplayAndroid.cpp
gfx/angle/src/libANGLE/renderer/gl/egl/egl_utils.cpp
gfx/angle/src/libANGLE/renderer/gl/egl/egl_utils.h
gfx/angle/src/libANGLE/renderer/gl/egl/ozone/DisplayOzone.cpp
gfx/angle/src/libANGLE/renderer/gl/formatutilsgl.cpp
gfx/angle/src/libANGLE/renderer/gl/formatutilsgl.h
gfx/angle/src/libANGLE/renderer/gl/functionsgl_typedefs.h
gfx/angle/src/libANGLE/renderer/gl/generate_gl_dispatch_table.py
gfx/angle/src/libANGLE/renderer/gl/gl_bindings_data.json
gfx/angle/src/libANGLE/renderer/gl/glx/DisplayGLX.cpp
gfx/angle/src/libANGLE/renderer/gl/null_functions.cpp
gfx/angle/src/libANGLE/renderer/gl/null_functions.h
gfx/angle/src/libANGLE/renderer/gl/renderergl_utils.cpp
gfx/angle/src/libANGLE/renderer/gl/renderergl_utils.h
gfx/angle/src/libANGLE/renderer/gl/wgl/DisplayWGL.cpp
gfx/angle/src/libANGLE/renderer/gl/wgl/FunctionsWGL.cpp
gfx/angle/src/libANGLE/renderer/gl/wgl/FunctionsWGL.h
gfx/angle/src/libANGLE/renderer/null/BufferNULL.cpp
gfx/angle/src/libANGLE/renderer/null/BufferNULL.h
gfx/angle/src/libANGLE/renderer/null/ContextNULL.cpp
gfx/angle/src/libANGLE/renderer/null/ContextNULL.h
gfx/angle/src/libANGLE/renderer/null/DisplayNULL.cpp
gfx/angle/src/libANGLE/renderer/null/DisplayNULL.h
gfx/angle/src/libANGLE/renderer/null/FenceNVNULL.cpp
gfx/angle/src/libANGLE/renderer/null/FramebufferNULL.cpp
gfx/angle/src/libANGLE/renderer/null/FramebufferNULL.h
gfx/angle/src/libANGLE/renderer/null/ProgramNULL.cpp
gfx/angle/src/libANGLE/renderer/null/ProgramNULL.h
gfx/angle/src/libANGLE/renderer/null/RenderbufferNULL.cpp
gfx/angle/src/libANGLE/renderer/null/RenderbufferNULL.h
gfx/angle/src/libANGLE/renderer/null/SurfaceNULL.cpp
gfx/angle/src/libANGLE/renderer/null/SurfaceNULL.h
gfx/angle/src/libANGLE/renderer/null/TextureNULL.cpp
gfx/angle/src/libANGLE/renderer/null/TextureNULL.h
gfx/angle/src/libANGLE/renderer/renderer_utils.cpp
gfx/angle/src/libANGLE/renderer/renderer_utils.h
gfx/angle/src/libANGLE/renderer/vulkan/BufferVk.cpp
gfx/angle/src/libANGLE/renderer/vulkan/BufferVk.h
gfx/angle/src/libANGLE/renderer/vulkan/CommandBufferNode.cpp
gfx/angle/src/libANGLE/renderer/vulkan/CommandBufferNode.h
gfx/angle/src/libANGLE/renderer/vulkan/ContextVk.cpp
gfx/angle/src/libANGLE/renderer/vulkan/ContextVk.h
gfx/angle/src/libANGLE/renderer/vulkan/DisplayVk.cpp
gfx/angle/src/libANGLE/renderer/vulkan/DisplayVk.h
gfx/angle/src/libANGLE/renderer/vulkan/FramebufferVk.cpp
gfx/angle/src/libANGLE/renderer/vulkan/FramebufferVk.h
gfx/angle/src/libANGLE/renderer/vulkan/GlslangWrapper.cpp
gfx/angle/src/libANGLE/renderer/vulkan/GlslangWrapper.h
gfx/angle/src/libANGLE/renderer/vulkan/ProgramVk.cpp
gfx/angle/src/libANGLE/renderer/vulkan/ProgramVk.h
gfx/angle/src/libANGLE/renderer/vulkan/RenderbufferVk.cpp
gfx/angle/src/libANGLE/renderer/vulkan/RenderbufferVk.h
gfx/angle/src/libANGLE/renderer/vulkan/RendererVk.cpp
gfx/angle/src/libANGLE/renderer/vulkan/RendererVk.h
gfx/angle/src/libANGLE/renderer/vulkan/SurfaceVk.cpp
gfx/angle/src/libANGLE/renderer/vulkan/SurfaceVk.h
gfx/angle/src/libANGLE/renderer/vulkan/TextureVk.cpp
gfx/angle/src/libANGLE/renderer/vulkan/TextureVk.h
gfx/angle/src/libANGLE/renderer/vulkan/VertexArrayVk.cpp
gfx/angle/src/libANGLE/renderer/vulkan/VertexArrayVk.h
gfx/angle/src/libANGLE/renderer/vulkan/formatutilsvk.cpp
gfx/angle/src/libANGLE/renderer/vulkan/formatutilsvk.h
gfx/angle/src/libANGLE/renderer/vulkan/gen_vk_format_table.py
gfx/angle/src/libANGLE/renderer/vulkan/renderervk_utils.cpp
gfx/angle/src/libANGLE/renderer/vulkan/renderervk_utils.h
gfx/angle/src/libANGLE/renderer/vulkan/vk_format_map.json
gfx/angle/src/libANGLE/renderer/vulkan/vk_format_table_autogen.cpp
gfx/angle/src/libANGLE/validationEGL.cpp
gfx/angle/src/libANGLE/validationEGL.h
gfx/angle/src/libANGLE/validationES.cpp
gfx/angle/src/libANGLE/validationES.h
gfx/angle/src/libANGLE/validationES2.cpp
gfx/angle/src/libANGLE/validationES2.h
gfx/angle/src/libANGLE/validationES3.cpp
gfx/angle/src/libANGLE/validationES3.h
gfx/angle/src/libANGLE/validationES31.cpp
gfx/angle/src/libANGLE/validationES31.h
gfx/angle/src/libEGL/libEGL.cpp
gfx/angle/src/libEGL/libEGL.def
gfx/angle/src/libEGL/libEGL.rc
gfx/angle/src/libEGL/moz.build
gfx/angle/src/libGLESv2.gypi
gfx/angle/src/libGLESv2/entry_points_egl.cpp
gfx/angle/src/libGLESv2/entry_points_egl_ext.cpp
gfx/angle/src/libGLESv2/entry_points_egl_ext.h
gfx/angle/src/libGLESv2/entry_points_gles_2_0_autogen.cpp
gfx/angle/src/libGLESv2/entry_points_gles_2_0_autogen.h
gfx/angle/src/libGLESv2/entry_points_gles_2_0_ext.cpp
gfx/angle/src/libGLESv2/entry_points_gles_2_0_ext.h
gfx/angle/src/libGLESv2/entry_points_gles_2_0_ext_autogen.cpp
gfx/angle/src/libGLESv2/entry_points_gles_2_0_ext_autogen.h
gfx/angle/src/libGLESv2/entry_points_gles_3_0_autogen.cpp
gfx/angle/src/libGLESv2/entry_points_gles_3_0_autogen.h
gfx/angle/src/libGLESv2/entry_points_gles_3_1.cpp
gfx/angle/src/libGLESv2/entry_points_gles_3_1.h
gfx/angle/src/libGLESv2/entry_points_gles_3_1_autogen.cpp
gfx/angle/src/libGLESv2/entry_points_gles_3_1_autogen.h
gfx/angle/src/libGLESv2/gen_proc_table.py
gfx/angle/src/libGLESv2/libGLESv2.cpp
gfx/angle/src/libGLESv2/libGLESv2.def
gfx/angle/src/libGLESv2/libGLESv2.rc
gfx/angle/src/libGLESv2/moz.build
gfx/angle/src/libGLESv2/proc_table.h
gfx/angle/src/libGLESv2/proc_table_autogen.cpp
gfx/angle/src/libGLESv2/proc_table_data.json
gfx/angle/src/tests/BUILD.gn
gfx/angle/src/tests/angle_end2end_tests.gypi
gfx/angle/src/tests/angle_unittests.gypi
gfx/angle/src/tests/angle_unittests_utils.h
gfx/angle/src/tests/compiler_tests/ARB_texture_rectangle_test.cpp
gfx/angle/src/tests/compiler_tests/AtomicCounter_test.cpp
gfx/angle/src/tests/compiler_tests/BufferVariables_test.cpp
gfx/angle/src/tests/compiler_tests/CollectVariables_test.cpp
gfx/angle/src/tests/compiler_tests/ConstantFolding_test.cpp
gfx/angle/src/tests/compiler_tests/DebugShaderPrecision_test.cpp
gfx/angle/src/tests/compiler_tests/EXT_YUV_target_test.cpp
gfx/angle/src/tests/compiler_tests/ExtensionDirective_test.cpp
gfx/angle/src/tests/compiler_tests/GeometryShader_test.cpp
gfx/angle/src/tests/compiler_tests/InitOutputVariables_test.cpp
gfx/angle/src/tests/compiler_tests/IntermNode_test.cpp
gfx/angle/src/tests/compiler_tests/Pack_Unpack_test.cpp
gfx/angle/src/tests/compiler_tests/PrunePureLiteralStatements_test.cpp
gfx/angle/src/tests/compiler_tests/QualificationOrderESSL31_test.cpp
gfx/angle/src/tests/compiler_tests/RegenerateStructNames_test.cpp
gfx/angle/src/tests/compiler_tests/RemoveUnreferencedVariables_test.cpp
gfx/angle/src/tests/compiler_tests/RewriteDoWhile_test.cpp
gfx/angle/src/tests/compiler_tests/ScalarizeVecAndMatConstructorArgs_test.cpp
gfx/angle/src/tests/compiler_tests/ShaderImage_test.cpp
gfx/angle/src/tests/compiler_tests/ShaderValidation_test.cpp
gfx/angle/src/tests/compiler_tests/ShaderVariable_test.cpp
gfx/angle/src/tests/compiler_tests/TypeTracking_test.cpp
gfx/angle/src/tests/compiler_tests/VariablePacker_test.cpp
gfx/angle/src/tests/compiler_tests/VectorizeVectorScalarArithmetic_test.cpp
gfx/angle/src/tests/compiler_tests/WEBGL_multiview_test.cpp
gfx/angle/src/tests/deqp.gypi
gfx/angle/src/tests/deqp_support/deqp_gles2_test_expectations.txt
gfx/angle/src/tests/deqp_support/deqp_gles31_test_expectations.txt
gfx/angle/src/tests/deqp_support/deqp_gles3_test_expectations.txt
gfx/angle/src/tests/egl_tests/EGLContextCompatibilityTest.cpp
gfx/angle/src/tests/egl_tests/EGLIOSurfaceClientBufferTest.cpp
gfx/angle/src/tests/egl_tests/EGLSanityCheckTest.cpp
gfx/angle/src/tests/egl_tests/EGLStreamTest.cpp
gfx/angle/src/tests/gl_tests/BindGeneratesResourceTest.cpp
gfx/angle/src/tests/gl_tests/BindUniformLocationTest.cpp
gfx/angle/src/tests/gl_tests/BlendMinMaxTest.cpp
gfx/angle/src/tests/gl_tests/BufferDataTest.cpp
gfx/angle/src/tests/gl_tests/BuiltinVariableTest.cpp
gfx/angle/src/tests/gl_tests/ClearTest.cpp
gfx/angle/src/tests/gl_tests/ClientArraysTest.cpp
gfx/angle/src/tests/gl_tests/ComputeShaderTest.cpp
gfx/angle/src/tests/gl_tests/CopyTextureTest.cpp
gfx/angle/src/tests/gl_tests/CubeMapTextureTest.cpp
gfx/angle/src/tests/gl_tests/D3D11EmulatedIndexedBufferTest.cpp
gfx/angle/src/tests/gl_tests/D3D11FormatTablesTest.cpp
gfx/angle/src/tests/gl_tests/D3DImageFormatConversionTest.cpp
gfx/angle/src/tests/gl_tests/D3DTextureTest.cpp
gfx/angle/src/tests/gl_tests/DXT1CompressedTextureTest.cpp
gfx/angle/src/tests/gl_tests/FenceSyncTests.cpp
gfx/angle/src/tests/gl_tests/FramebufferTest.cpp
gfx/angle/src/tests/gl_tests/GLSLTest.cpp
gfx/angle/src/tests/gl_tests/GeometryShaderTest.cpp
gfx/angle/src/tests/gl_tests/IncompleteTextureTest.cpp
gfx/angle/src/tests/gl_tests/LinkAndRelinkTest.cpp
gfx/angle/src/tests/gl_tests/MultiviewDrawTest.cpp
gfx/angle/src/tests/gl_tests/OcclusionQueriesTest.cpp
gfx/angle/src/tests/gl_tests/PathRenderingTest.cpp
gfx/angle/src/tests/gl_tests/PointSpritesTest.cpp
gfx/angle/src/tests/gl_tests/ProgramBinaryTest.cpp
gfx/angle/src/tests/gl_tests/ProgramInterfaceTest.cpp
gfx/angle/src/tests/gl_tests/ProgramPipelineTest.cpp
gfx/angle/src/tests/gl_tests/ReadPixelsTest.cpp
gfx/angle/src/tests/gl_tests/RendererTest.cpp
gfx/angle/src/tests/gl_tests/RobustResourceInitTest.cpp
gfx/angle/src/tests/gl_tests/SRGBFramebufferTest.cpp
gfx/angle/src/tests/gl_tests/ShaderStorageBufferTest.cpp
gfx/angle/src/tests/gl_tests/SimpleOperationTest.cpp
gfx/angle/src/tests/gl_tests/SixteenBppTextureTest.cpp
gfx/angle/src/tests/gl_tests/StateChangeTest.cpp
gfx/angle/src/tests/gl_tests/SyncQueriesTest.cpp
gfx/angle/src/tests/gl_tests/TextureRectangleTest.cpp
gfx/angle/src/tests/gl_tests/TextureTest.cpp
gfx/angle/src/tests/gl_tests/TextureUploadFormatTest.cpp
gfx/angle/src/tests/gl_tests/TransformFeedbackTest.cpp
gfx/angle/src/tests/gl_tests/UniformBufferTest.cpp
gfx/angle/src/tests/gl_tests/VertexAttributeTest.cpp
gfx/angle/src/tests/gl_tests/WebGLCompatibilityTest.cpp
gfx/angle/src/tests/gl_tests/WebGLFramebufferTest.cpp
gfx/angle/src/tests/gl_tests/WebGLReadOutsideFramebufferTest.cpp
gfx/angle/src/tests/perf_tests/ANGLEPerfTest.cpp
gfx/angle/src/tests/perf_tests/ANGLEPerfTest.h
gfx/angle/src/tests/perf_tests/BindingPerf.cpp
gfx/angle/src/tests/perf_tests/BitSetIteratorPerf.cpp
gfx/angle/src/tests/perf_tests/BufferSubData.cpp
gfx/angle/src/tests/perf_tests/DrawCallPerf.cpp
gfx/angle/src/tests/perf_tests/DrawCallPerfParams.cpp
gfx/angle/src/tests/perf_tests/DrawCallPerfParams.h
gfx/angle/src/tests/perf_tests/DrawElementsPerf.cpp
gfx/angle/src/tests/perf_tests/IndexDataManagerTest.cpp
gfx/angle/src/tests/perf_tests/InstancingPerf.cpp
gfx/angle/src/tests/perf_tests/InterleavedAttributeData.cpp
gfx/angle/src/tests/perf_tests/LinkProgramPerfTest.cpp
gfx/angle/src/tests/perf_tests/MultiviewPerf.cpp
gfx/angle/src/tests/perf_tests/PointSprites.cpp
gfx/angle/src/tests/perf_tests/TexSubImage.cpp
gfx/angle/src/tests/perf_tests/TextureSampling.cpp
gfx/angle/src/tests/perf_tests/TexturesPerf.cpp
gfx/angle/src/tests/perf_tests/UniformsPerf.cpp
gfx/angle/src/tests/preprocessor_tests/if_test.cpp
gfx/angle/src/tests/preprocessor_tests/input_test.cpp
gfx/angle/src/tests/preprocessor_tests/location_test.cpp
gfx/angle/src/tests/test_utils/ANGLETest.cpp
gfx/angle/src/tests/test_utils/ANGLETest.h
gfx/angle/src/tests/test_utils/ConstantFoldingTest.h
gfx/angle/src/tests/test_utils/angle_test_configs.cpp
gfx/angle/src/tests/test_utils/angle_test_configs.h
gfx/angle/src/tests/test_utils/compiler_test.cpp
gfx/angle/src/tests/test_utils/compiler_test.h
gfx/angle/src/tests/test_utils/gl_raii.h
gfx/angle/src/tests/tests.gyp
gfx/angle/src/tests/third_party/gpu_test_expectations/angle-mods.patch
gfx/angle/src/tests/third_party/gpu_test_expectations/gpu_info.cc
gfx/angle/src/tests/third_party/gpu_test_expectations/gpu_info.h
gfx/angle/src/tests/third_party/gpu_test_expectations/gpu_test_config.cc
gfx/angle/src/tests/third_party/gpu_test_expectations/gpu_test_config.h
gfx/angle/src/tests/third_party/gpu_test_expectations/gpu_test_config_mac.h
gfx/angle/src/tests/third_party/gpu_test_expectations/gpu_test_config_mac.mm
gfx/angle/src/tests/third_party/gpu_test_expectations/gpu_test_expectations_parser.cc
gfx/angle/src/vulkan_support/BUILD.gn
gfx/angle/src/vulkan_support/dummy_spirv_tools_commit_id.h
gfx/angle/src/vulkan_support/vulkan.gypi
--- a/gfx/angle/AUTHORS
+++ b/gfx/angle/AUTHORS
@@ -1,9 +1,9 @@
-# This is the official list of The ANGLE Project Authors
+# This is the official list of The ANGLE Project Authors
 # for copyright purposes.
 # This file is distinct from the CONTRIBUTORS files.
 # See the latter for an explanation.
 
 # Names should be added to this file as
 #	Name or Organization
 # Email addresses for individuals are tracked elsewhere to avoid spam.
 
--- a/gfx/angle/BUILD.gn
+++ b/gfx/angle/BUILD.gn
@@ -2,23 +2,37 @@
 # Use of this source code is governed by a BSD-style license that can be
 # found in the LICENSE file.
 
 # import the use_x11 variable
 import("//build/config/dcheck_always_on.gni")
 import("//build/config/linux/pkg_config.gni")
 import("//build/config/ui.gni")
 import("//testing/libfuzzer/fuzzer_test.gni")
-import("//third_party/angle/gni/angle.gni")
-import("//ui/ozone/ozone.gni")
+import("gni/angle.gni")
 
 declare_args() {
   # Use the PCI lib to collect GPU information on Linux.
   use_libpci = is_linux && (!is_chromecast || is_cast_desktop_build) &&
                (use_x11 || use_ozone)
+
+  # Link in system libGL, to work with apitrace.  See doc/DebuggingTips.md.
+  angle_link_glx = false
+}
+
+if (!build_with_chromium) {
+  group("all") {
+    testonly = true
+    deps = [
+      ":angle_shader_translator",
+      ":translator_fuzzer",
+      "//samples:all",
+      "//src/tests:all",
+    ]
+  }
 }
 
 if (ozone_platform_gbm) {
   pkg_config("libdrm") {
     packages = [ "libdrm" ]
   }
 }
 
@@ -55,33 +69,41 @@ config("internal_config") {
   ]
 
   # Prevent the GL headers from redeclaring ANGLE entry points.
   defines = [
     "GL_GLEXT_PROTOTYPES",
     "EGL_EGLEXT_PROTOTYPES",
   ]
 
-  if (target_cpu == "x86") {
-    defines += [ "ANGLE_X86_CPU" ]
+  if (current_cpu == "x86" || current_cpu == "arm") {
+    defines += [ "ANGLE_IS_32_BIT_CPU" ]
   }
-  if (target_cpu == "x64") {
-    defines += [ "ANGLE_X64_CPU" ]
+  if (current_cpu == "x64" || current_cpu == "arm64") {
+    defines += [ "ANGLE_IS_64_BIT_CPU" ]
   }
 }
 
 config("extra_warnings") {
+  cflags = []
+
   # Enable more default warnings on Windows.
   if (is_win) {
-    cflags = [
+    cflags += [
       "/we4244",  # Conversion: possible loss of data.
       "/we4456",  # Variable shadowing.
       "/we4458",  # declaration hides class member.
+      "/we4800",  # forcing value to bool.
+      "/we4838",  # narrowing conversion.
     ]
   }
+  if (is_clang) {
+    # Remove when crbug.com/428099 is resolved.
+    cflags += [ "-Winconsistent-missing-override" ]
+  }
 }
 
 if (is_win) {
   copy("copy_compiler_dll") {
     sources = [
       "$windows_sdk_path/Redist/D3D/$target_cpu/d3dcompiler_47.dll",
     ]
     outputs = [
@@ -89,37 +111,27 @@ if (is_win) {
     ]
   }
 }
 
 angle_undefine_configs = [ "//build/config/compiler:default_include_dirs" ]
 
 # Holds the shared includes so we only need to list them once.
 source_set("includes") {
-  sources = [
-    "include/EGL/egl.h",
-    "include/EGL/eglext.h",
-    "include/EGL/eglplatform.h",
-    "include/GLES2/gl2.h",
-    "include/GLES2/gl2ext.h",
-    "include/GLES2/gl2platform.h",
-    "include/GLES3/gl3.h",
-    "include/GLES3/gl31.h",
-    "include/GLES3/gl32.h",
-    "include/GLES3/gl3platform.h",
-    "include/GLSLANG/ShaderLang.h",
-    "include/KHR/khrplatform.h",
-  ]
+  sources = rebase_path(gles_gypi.libangle_includes, ".", "src")
 }
 
 static_library("preprocessor") {
   sources = rebase_path(compiler_gypi.angle_preprocessor_sources, ".", "src")
 
   configs -= angle_undefine_configs
-  configs += [ ":internal_config" ]
+  configs += [
+    ":extra_warnings",
+    ":internal_config",
+  ]
 
   public_deps = [
     ":angle_common",
   ]
 }
 
 config("translator_disable_pool_alloc") {
   defines = [ "ANGLE_TRANSLATOR_DISABLE_POOL_ALLOC" ]
@@ -251,53 +263,57 @@ static_library("angle_gpu_info_util") {
   }
 
   if (is_mac) {
     sources +=
         rebase_path(gles_gypi.libangle_gpu_info_util_mac_sources, ".", "src")
     libs += [
       "IOKit.framework",
       "CoreFoundation.framework",
+      "CoreGraphics.framework",
     ]
   }
 }
 
 static_library("translator") {
   sources = rebase_path(compiler_gypi.angle_translator_sources, ".", "src")
   defines = []
 
-  if (angle_enable_essl || use_libfuzzer) {
+  if (angle_enable_essl || use_fuzzing_engine) {
     sources +=
         rebase_path(compiler_gypi.angle_translator_essl_sources, ".", "src")
     defines += [ "ANGLE_ENABLE_ESSL" ]
   }
 
-  if (angle_enable_glsl || use_libfuzzer) {
+  if (angle_enable_glsl || use_fuzzing_engine) {
     sources +=
         rebase_path(compiler_gypi.angle_translator_glsl_sources, ".", "src")
     defines += [ "ANGLE_ENABLE_GLSL" ]
   }
 
-  if (angle_enable_hlsl || use_libfuzzer) {
+  if (angle_enable_hlsl || use_fuzzing_engine) {
     sources +=
         rebase_path(compiler_gypi.angle_translator_hlsl_sources, ".", "src")
     defines += [ "ANGLE_ENABLE_HLSL" ]
   }
 
-  if (angle_enable_vulkan || use_libfuzzer) {
+  if (angle_enable_vulkan || use_fuzzing_engine) {
     sources += rebase_path(compiler_gypi.angle_translator_lib_vulkan_sources,
                            ".",
                            "src")
     defines += [ "ANGLE_ENABLE_VULKAN" ]
   }
 
   configs -= angle_undefine_configs
-  configs += [ ":internal_config" ]
+  configs += [
+    ":internal_config",
+    ":extra_warnings",
+  ]
   public_configs = [ ":external_config" ]
-  if (use_libfuzzer) {
+  if (use_fuzzing_engine) {
     all_dependent_configs = [ ":translator_disable_pool_alloc" ]
   }
 
   deps = [
     ":includes",
     ":preprocessor",
   ]
 
@@ -368,16 +384,19 @@ config("libANGLE_config") {
   if (angle_enable_d3d11) {
     defines += [ "ANGLE_ENABLE_D3D11" ]
   }
   if (angle_enable_gl) {
     defines += [ "ANGLE_ENABLE_OPENGL" ]
     if (use_x11) {
       defines += [ "ANGLE_USE_X11" ]
     }
+    if (angle_enable_gl_null) {
+      defines += [ "ANGLE_ENABLE_OPENGL_NULL" ]
+    }
   }
   if (angle_enable_vulkan) {
     defines += [ "ANGLE_ENABLE_VULKAN" ]
   }
   if (angle_enable_null) {
     defines += [ "ANGLE_ENABLE_NULL" ]
   }
   defines += [ "LIBANGLE_IMPLEMENTATION" ]
@@ -388,16 +407,20 @@ config("libANGLE_config") {
 }
 
 static_library("libANGLE") {
   sources = rebase_path(gles_gypi.libangle_sources, ".", "src")
 
   include_dirs = []
   libs = []
   defines = []
+  if (angle_link_glx) {
+    libs += [ "GL" ]
+    defines += [ "ANGLE_LINK_GLX" ]
+  }
   public_deps = [
     ":angle_common",
   ]
   deps = [
     ":angle_gpu_info_util",
     ":angle_image_util",
     ":commit_id",
     ":includes",
@@ -421,16 +444,19 @@ static_library("libANGLE") {
     sources += rebase_path(gles_gypi.libangle_d3d11_win32_sources, ".", "src")
     libs += [ "dxguid.lib" ]
   }
 
   if (angle_enable_gl) {
     sources += rebase_path(gles_gypi.libangle_gl_sources, ".", "src")
     include_dirs += [ "src/third_party/khronos" ]
 
+    if (angle_enable_gl_null) {
+      sources += rebase_path(gles_gypi.libangle_gl_null_sources, ".", "src")
+    }
     if (is_win) {
       sources += rebase_path(gles_gypi.libangle_gl_wgl_sources, ".", "src")
     }
     if (use_x11) {
       sources += rebase_path(gles_gypi.libangle_gl_glx_sources, ".", "src")
       deps += [ "src/third_party/libXNVCtrl:libXNVCtrl" ]
       libs += [
         "X11",
@@ -471,17 +497,17 @@ static_library("libANGLE") {
     sources += rebase_path(gles_gypi.libangle_vulkan_sources, ".", "src")
     if (is_win) {
       sources +=
           rebase_path(gles_gypi.libangle_vulkan_win32_sources, ".", "src")
     }
     if (is_linux) {
       sources += rebase_path(gles_gypi.libangle_vulkan_xcb_sources, ".", "src")
     }
-    deps += [ "//third_party/angle/src/vulkan_support:angle_vulkan" ]
+    deps += [ "src/vulkan_support:angle_vulkan" ]
   }
 
   if (angle_enable_null) {
     sources += rebase_path(gles_gypi.libangle_null_sources, ".", "src")
   }
 
   if (is_debug) {
     defines += [ "ANGLE_GENERATE_SHADER_DEBUG_INFO" ]
@@ -544,16 +570,17 @@ shared_library("libGLESv2") {
     ]
     public_configs = [ ":shared_library_public_config" ]
   }
 
   configs -= angle_undefine_configs
   configs += [
     ":commit_id_config",
     ":debug_annotations_config",
+    ":extra_warnings",
     ":internal_config",
   ]
 
   defines = [ "LIBGLESV2_IMPLEMENTATION" ]
   if (is_win) {
     defines += [ "GL_APICALL=" ]
   } else {
     defines += [ "GL_APICALL=__attribute__((visibility(\"default\")))" ]
@@ -568,16 +595,17 @@ shared_library("libGLESv2") {
 
 static_library("libGLESv2_static") {
   sources = rebase_path(gles_gypi.libglesv2_sources, ".", "src")
 
   configs -= angle_undefine_configs
   configs += [
     ":commit_id_config",
     ":debug_annotations_config",
+    ":extra_warnings",
     ":internal_config",
   ]
 
   public_configs = [ ":angle_static" ]
 
   deps = [
     ":includes",
     ":libANGLE",
--- a/gfx/angle/CONTRIBUTORS
+++ b/gfx/angle/CONTRIBUTORS
@@ -1,9 +1,9 @@
-# This is the official list of people who can contribute
+# This is the official list of people who can contribute
 # (and who have contributed) code to the ANGLE project
 # repository.
 # The AUTHORS file lists the copyright holders; this file
 # lists people.  For example, Google employees are listed here
 # but not in AUTHORS, because Google holds the copyright.
 #
 
 TransGaming Inc.
@@ -36,16 +36,17 @@ Google Inc.
  Gregg Tavares
  Jeff Timanus
  Ben Vanik
  Adrienne Walker
  thestig@chromium.org
  Justin Schuh
  Scott Graham
  Corentin Wallez
+ Kai Ninomiya
 
 Adobe Systems Inc.
  Alexandru Chiculita
  Steve Minns
  Max Vujovic
 
 Autodesk, Inc.
  Ranger Harke
--- a/gfx/angle/DEPS
+++ b/gfx/angle/DEPS
@@ -1,123 +1,155 @@
 vars = {
   'android_git': 'https://android.googlesource.com',
   'chromium_git': 'https://chromium.googlesource.com',
 }
 
 deps = {
 
-  'buildtools':
-    Var('chromium_git') + '/chromium/buildtools.git' + '@' + '98f00fa10dbad2cdbb2e297a66c3d6d5bc3994f3',
+  'build':
+    Var('chromium_git') + '/chromium/src/build.git' + '@' + '2f3b6e8ce9e783b2a09496d70eef2974506a41c8',
 
-  'testing/gmock':
-    Var('chromium_git') + '/external/googlemock.git' + '@' + '0421b6f358139f02e102c9c332ce19a33faf75be', # from svn revision 566
+  'buildtools':
+    Var('chromium_git') + '/chromium/buildtools.git' + '@' + '461b345a815c1c745ac0534a6a4bd52d123abe68',
 
-  'testing/gtest':
-    Var('chromium_git') + '/external/github.com/google/googletest.git' + '@' + '6f8a66431cb592dad629028a50b3dd418a408c87',
+  'testing':
+    Var('chromium_git') + '/chromium/src/testing' + '@' + '6dfa36ab2e5143fa2f7353e3af5d2935af2e61f7',
 
   # Cherry is a dEQP management GUI written in Go. We use it for viewing test results.
   'third_party/cherry':
-    Var('android_git') + '/platform/external/cherry' + '@' + 'd2e26b4d864ec2a6757e7f1174e464949ca5bf73',
+    Var('android_git') + '/platform/external/cherry' + '@' + '4f8fb08d33ca5ff05a1c638f04c85bbb8d8b52cc',
 
   'third_party/deqp/src':
     Var('android_git') + '/platform/external/deqp' + '@' + '455d82c60b096e7bd83b6a2f5ed70c61e4bfa759',
 
   'third_party/glslang-angle/src':
-    Var('android_git') + '/platform/external/shaderc/glslang' + '@' + '1e275c8486325aaab34734ad9a650c0121c5efdb',
+    Var('android_git') + '/platform/external/shaderc/glslang' + '@' + '2edde6665d9a56ead5ea0e55b4e64d9a803e6164',
 
-  'third_party/gyp':
-    Var('chromium_git') + '/external/gyp' + '@' + 'c6f471687407bf28ddfc63f1a8f47aeb7bf54edc',
+  'third_party/googletest/src':
+    Var('chromium_git') + '/external/github.com/google/googletest.git' + '@' + 'd175c8bf823e709d570772b038757fadf63bc632',
 
-  'third_party/libpng':
+  'third_party/libpng/src':
     Var('android_git') + '/platform/external/libpng' + '@' + '094e181e79a3d6c23fd005679025058b7df1ad6c',
 
   'third_party/spirv-headers/src':
-    Var('android_git') + '/platform/external/shaderc/spirv-headers' + '@' + 'c470b68225a04965bf87d35e143ae92f831e8110',
+    Var('android_git') + '/platform/external/shaderc/spirv-headers' + '@' + '98b01515724c428d0f0a5d01deffcce0f5f5e61c',
 
   'third_party/spirv-tools-angle/src':
-    Var('android_git') + '/platform/external/shaderc/spirv-tools' + '@' + '68c5f0436f1d4f1f137e608780190865d0b193ca',
+    Var('android_git') + '/platform/external/shaderc/spirv-tools' + '@' + '9996173f363729b3a97309685dbd4d78547a63a7',
 
   'third_party/vulkan-validation-layers/src':
-    Var('android_git') + '/platform/external/vulkan-validation-layers' + '@' + 'f47c534fee2f26f6b783209d56e0ade48e30eb8d',
+    Var('android_git') + '/platform/external/vulkan-validation-layers' + '@' + 'd5c8ed406ab2399a80e2847c03aa80b09b269b53',
 
   'third_party/zlib':
     Var('chromium_git') + '/chromium/src/third_party/zlib' + '@' + '24ab14872e8e068ba08cc31cc3d43bcc6d5cb832',
+
+  'tools/clang':
+    Var('chromium_git') + '/chromium/src/tools/clang.git' + '@' + 'e70074db10b27867e6c873adc3ac7e5f9ee0ff6e',
+
+  'tools/gyp':
+    Var('chromium_git') + '/external/gyp' + '@' + '5e2b3ddde7cda5eb6bc09a5546a76b00e49d888f',
 }
 
 hooks = [
   # Pull clang-format binaries using checked-in hashes.
   {
     'name': 'clang_format_win',
     'pattern': '.',
+    'condition': 'host_os == "win"',
     'action': [ 'download_from_google_storage',
                 '--no_resume',
                 '--platform=win32',
                 '--no_auth',
                 '--bucket', 'chromium-clang-format',
                 '-s', 'buildtools/win/clang-format.exe.sha1',
     ],
   },
   {
     'name': 'clang_format_mac',
     'pattern': '.',
+    'condition': 'host_os == "mac"',
     'action': [ 'download_from_google_storage',
                 '--no_resume',
                 '--platform=darwin',
                 '--no_auth',
                 '--bucket', 'chromium-clang-format',
                 '-s', 'buildtools/mac/clang-format.sha1',
     ],
   },
   {
     'name': 'clang_format_linux',
     'pattern': '.',
+    'condition': 'host_os == "linux"',
     'action': [ 'download_from_google_storage',
                 '--no_resume',
                 '--platform=linux*',
                 '--no_auth',
                 '--bucket', 'chromium-clang-format',
                 '-s', 'buildtools/linux64/clang-format.sha1',
     ],
   },
   # Pull GN binaries using checked-in hashes.
   {
     'name': 'gn_win',
     'pattern': '.',
+    'condition': 'host_os == "win"',
     'action': [ 'download_from_google_storage',
                 '--no_resume',
                 '--platform=win32',
                 '--no_auth',
                 '--bucket', 'chromium-gn',
                 '-s', 'buildtools/win/gn.exe.sha1',
     ],
   },
   {
     'name': 'gn_mac',
     'pattern': '.',
+    'condition': 'host_os == "mac"',
     'action': [ 'download_from_google_storage',
                 '--no_resume',
                 '--platform=darwin',
                 '--no_auth',
                 '--bucket', 'chromium-gn',
                 '-s', 'buildtools/mac/gn.sha1',
     ],
   },
   {
     'name': 'gn_linux64',
     'pattern': '.',
+    'condition': 'host_os == "linux"',
     'action': [ 'download_from_google_storage',
                 '--no_resume',
                 '--platform=linux*',
                 '--no_auth',
                 '--bucket', 'chromium-gn',
                 '-s', 'buildtools/linux64/gn.sha1',
     ],
   },
   {
+    # Note: On Win, this should run after win_toolchain, as it may use it.
+    'name': 'clang',
+    'pattern': '.',
+    'action': ['python', 'tools/clang/scripts/update.py', '--if-needed'],
+  },
+
+  # Pull rc binaries using checked-in hashes.
+  {
+    'name': 'rc_win',
+    'pattern': '.',
+    'condition': 'checkout_win and host_os == "win"',
+    'action': [ 'download_from_google_storage',
+                '--no_resume',
+                '--no_auth',
+                '--bucket', 'chromium-browser-clang/rc',
+                '-s', 'build/toolchain/win/rc/win/rc.exe.sha1',
+    ],
+  },
+
+  {
     # A change to a .gyp, .gypi, or to GYP itself should run the generator.
     'pattern': '.',
     'action': ['python', 'gyp/gyp_angle'],
   },
 ]
 
 recursedeps = [
   # buildtools provides clang_format.
--- a/gfx/angle/DEPS.chromium
+++ b/gfx/angle/DEPS.chromium
@@ -11,26 +11,26 @@
 
 vars = {
   'android_git': 'https://android.googlesource.com',
 
   # Current revision of dEQP.
   'deqp_revision': '455d82c60b096e7bd83b6a2f5ed70c61e4bfa759',
 
   # Current revision of glslang, the Khronos SPIRV compiler.
-  'glslang_revision': '1e275c8486325aaab34734ad9a650c0121c5efdb',
+  'glslang_revision': '2edde6665d9a56ead5ea0e55b4e64d9a803e6164',
 
   # Current revision fo the SPIRV-Headers Vulkan support library.
-  'spirv_headers_revision': 'c470b68225a04965bf87d35e143ae92f831e8110',
+  'spirv_headers_revision': '98b01515724c428d0f0a5d01deffcce0f5f5e61c',
 
   # Current revision of SPIRV-Tools for Vulkan.
-  'spirv_tools_revision': '68c5f0436f1d4f1f137e608780190865d0b193ca',
+  'spirv_tools_revision': '9996173f363729b3a97309685dbd4d78547a63a7',
 
   # Current revision of the Vulkan Validation Layers SDK.
-  'vulkan_revision': 'f47c534fee2f26f6b783209d56e0ade48e30eb8d',
+  'vulkan_revision': 'd5c8ed406ab2399a80e2847c03aa80b09b269b53',
 }
 
 deps = {
   'src/third_party/deqp/src':
     Var('android_git') + '/platform/external/deqp@' + Var('deqp_revision'),
 
   'src/third_party/glslang-angle/src':
     Var('android_git') + '/platform/external/shaderc/glslang@' + Var('glslang_revision'),
new file mode 100644
--- /dev/null
+++ b/gfx/angle/OWNERS
@@ -0,0 +1,6 @@
+# See https://chromium.googlesource.com/angle/angle/+/master/doc/ContributingCode.md#selecting-reviewers for per-file owners
+cwallez@chroimium.org
+fjhenigman@chromium.org
+geofflang@chromium.org
+jmadill@chromium.org
+ynovikov@chromium.org
--- a/gfx/angle/README.md
+++ b/gfx/angle/README.md
@@ -1,75 +1,21 @@
-# ANGLE - Almost Native Graphics Layer Engine
-
-The goal of ANGLE is to allow users of multiple operating systems to seamlessly run WebGL and other
-OpenGL ES content by translating OpenGL ES API calls to one of the hardware-supported APIs available
-for that platform. ANGLE currently provides translation from OpenGL ES 2.0 and 3.0 to desktop
-OpenGL, OpenGL ES, Direct3D 9, and Direct3D 11. Support for translation from OpenGL ES to Vulkan is
-underway, and future plans include compute shader support (ES 3.1) and MacOS support.
-
-### Level of OpenGL ES support via backing renderers
-
-|                |  Direct3D 9   |  Direct3D 11     |   Desktop GL   |    GL ES      |    Vulkan     |
-|----------------|:-------------:|:----------------:|:--------------:|:-------------:|:-------------:|
-| OpenGL ES 2.0  |    complete   |    complete      |    complete    |   complete    |  in progress  |
-| OpenGL ES 3.0  |               |    complete      |    complete    |  in progress  |  not started  |
-| OpenGL ES 3.1  |               |   not started    |   in progress  |  in progress  |  not started  |
+# ANGLE_gyp2mozbuild
+gyp to mozbuild scripts extract form Mozila's ANGLE fork.
 
-### Platform support via backing renderers
-
-|             |    Direct3D 9  |   Direct3D 11  |   Desktop GL  |    GL ES    |   Vulkan    |
-|------------:|:--------------:|:--------------:|:-------------:|:-----------:|:-----------:|
-| Windows     |    complete    |    complete    |   complete    |   complete  | in progress |
-| Linux       |                |                |   complete    |             |   planned   |
-| Mac OS X    |                |                |   in progress |             |             |
-| Chrome OS   |                |                |               |   complete  |   planned   |
-| Android     |                |                |               |   complete  |   planned   |
-
-ANGLE v1.0.772 was certified compliant by passing the ES 2.0.3 conformance tests in October 2011.
-ANGLE also provides an implementation of the EGL 1.4 specification.
-
-ANGLE is used as the default WebGL backend for both Google Chrome and Mozilla Firefox on Windows
-platforms. Chrome uses ANGLE for all graphics rendering on Windows, including the accelerated
-Canvas2D implementation and the Native Client sandbox environment.
+How to use it
+======================================================
+1. Copy all files here to an ANGLE repository (/path/to/ANGLE)
+2. Apply the git patches to ANGLE
+3. Execute gyp_mozbuild
+4. Manually fix moz.build under /path/to/ANGLE/src/libANGLE
 
-Portions of the ANGLE shader compiler are used as a shader validator and translator by WebGL
-implementations across multiple platforms. It is used on Mac OS X, Linux, and in mobile variants of
-the browsers. Having one shader validator helps to ensure that a consistent set of GLSL ES shaders
-are accepted across browsers and platforms. The shader translator can be used to translate shaders
-to other shading languages, and to optionally apply shader modifications to work around bugs or
-quirks in the native graphics drivers. The translator targets Desktop GLSL, Direct3D HLSL, and even
-ESSL for native GLES2 platforms.
-
-## Sources
-
-ANGLE repository is hosted by Chromium project and can be
-[browsed online](https://chromium.googlesource.com/angle/angle) or cloned with
-
-    git clone https://chromium.googlesource.com/angle/angle
-
-
-## Building
-
-View the [Dev setup instructions](doc/DevSetup.md). For generating a Windows Store version of ANGLE view the [Windows Store instructions](doc/BuildingAngleForWindowsStore.md)
+--(1) Move '../third_party/systeminfo/SystemInfo.cpp' from SOURCES to UNIFIED_SOURCE above.
+--(2) Move 'renderer/d3d/d3d11/win32/NativeWindow11Win32.cpp' from UNIFIED_SOURCE to SOURCE below
 
-## Contributing
-
-* Join our [Google group](https://groups.google.com/group/angleproject) to keep up to date.
-* Join us on IRC in the #ANGLEproject channel on FreeNode.
-* File bugs in the [issue tracker](http://code.google.com/p/angleproject/issues/list) (preferably with an isolated test-case).
-* [Choose an ANGLE branch](doc/ChoosingANGLEBranch.md) to track in your own project.
-
-
-* Read ANGLE development [documentation](doc).
-* Look at [pending](https://chromium-review.googlesource.com/#/q/project:angle/angle+status:open)
-  and [merged](https://chromium-review.googlesource.com/#/q/project:angle/angle+status:merged) changes.
-* Become a [code contributor](doc/ContributingCode.md).
-* Use ANGLE's [coding standard](doc/CodingStandard.md).
-* Learn how to [build ANGLE for Chromium development](doc/BuildingAngleForChromiumDevelopment.md).
-* Get help on [debugging ANGLE](doc/DebuggingTips.md).
-
-
-* Read about WebGL on the [Khronos WebGL Wiki](http://khronos.org/webgl/wiki/Main_Page).
-* Learn about implementation details in the [OpenGL Insights chapter on ANGLE](http://www.seas.upenn.edu/~pcozzi/OpenGLInsights/OpenGLInsights-ANGLE.pdf) and this [ANGLE presentation](https://drive.google.com/file/d/0Bw29oYeC09QbbHoxNE5EUFh0RGs/view?usp=sharing).
-* Learn about the past, present, and future of the ANGLE implementation in [this recent presentation](https://docs.google.com/presentation/d/1CucIsdGVDmdTWRUbg68IxLE5jXwCb2y1E9YVhQo0thg/pub?start=false&loop=false).
-* If you use ANGLE in your own project, we'd love to hear about it!
-
+5. rm -rf /path/to/gecko/gfx/angle
+6. mkdir -p /path/to/gecko/gfx/angle
+7. cp -r /path/to/ANGLE/[A-Z]* /path/to/ANGLE/{include,src,moz.build} /path/to/gecko/gfx/angle
+8. cd /path/to/gecko
+9. git add gfx/angle
+10. git add -f gfx/angle/src/id
+11. git commit
+12. Build
--- a/gfx/angle/include/EGL/eglext_angle.h
+++ b/gfx/angle/include/EGL/eglext_angle.h
@@ -7,20 +7,20 @@
 //   Currently we don't include this file directly, we patch eglext.h
 //   to include it implicitly so it is visible throughout our code.
 
 #ifndef INCLUDE_EGL_EGLEXT_ANGLE_
 #define INCLUDE_EGL_EGLEXT_ANGLE_
 
 // clang-format off
 
-#ifndef EGL_ANGLE_display_robust_resource_initialization
-#define EGL_ANGLE_display_robust_resource_initialization 1
-#define EGL_DISPLAY_ROBUST_RESOURCE_INITIALIZATION_ANGLE 0x3453
-#endif /* EGL_ANGLE_display_robust_resource_initialization */
+#ifndef EGL_ANGLE_robust_resource_initialization
+#define EGL_ANGLE_robust_resource_initialization 1
+#define EGL_ROBUST_RESOURCE_INITIALIZATION_ANGLE 0x3453
+#endif /* EGL_ANGLE_robust_resource_initialization */
 
 #ifndef EGL_ANGLE_keyed_mutex
 #define EGL_ANGLE_keyed_mutex 1
 #define EGL_DXGI_KEYED_MUTEX_ANGLE        0x33A2
 #endif /* EGL_ANGLE_keyed_mutex */
 
 #ifndef EGL_ANGLE_d3d_texture_client_buffer
 #define EGL_ANGLE_d3d_texture_client_buffer 1
@@ -46,26 +46,27 @@
 #ifndef EGL_ANGLE_platform_angle
 #define EGL_ANGLE_platform_angle 1
 #define EGL_PLATFORM_ANGLE_ANGLE          0x3202
 #define EGL_PLATFORM_ANGLE_TYPE_ANGLE     0x3203
 #define EGL_PLATFORM_ANGLE_MAX_VERSION_MAJOR_ANGLE 0x3204
 #define EGL_PLATFORM_ANGLE_MAX_VERSION_MINOR_ANGLE 0x3205
 #define EGL_PLATFORM_ANGLE_TYPE_DEFAULT_ANGLE 0x3206
 #define EGL_PLATFORM_ANGLE_DEBUG_LAYERS_ENABLED_ANGLE 0x3451
+#define EGL_PLATFORM_ANGLE_DEVICE_TYPE_ANGLE 0x3209
+#define EGL_PLATFORM_ANGLE_DEVICE_TYPE_HARDWARE_ANGLE 0x320A
+#define EGL_PLATFORM_ANGLE_DEVICE_TYPE_NULL_ANGLE 0x345E
 #endif /* EGL_ANGLE_platform_angle */
 
 #ifndef EGL_ANGLE_platform_angle_d3d
 #define EGL_ANGLE_platform_angle_d3d 1
 #define EGL_PLATFORM_ANGLE_TYPE_D3D9_ANGLE 0x3207
 #define EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE 0x3208
-#define EGL_PLATFORM_ANGLE_DEVICE_TYPE_ANGLE 0x3209
-#define EGL_PLATFORM_ANGLE_DEVICE_TYPE_HARDWARE_ANGLE 0x320A
-#define EGL_PLATFORM_ANGLE_DEVICE_TYPE_WARP_ANGLE 0x320B
-#define EGL_PLATFORM_ANGLE_DEVICE_TYPE_REFERENCE_ANGLE 0x320C
+#define EGL_PLATFORM_ANGLE_DEVICE_TYPE_D3D_WARP_ANGLE 0x320B
+#define EGL_PLATFORM_ANGLE_DEVICE_TYPE_D3D_REFERENCE_ANGLE 0x320C
 #define EGL_PLATFORM_ANGLE_ENABLE_AUTOMATIC_TRIM_ANGLE 0x320F
 #endif /* EGL_ANGLE_platform_angle_d3d */
 
 #ifndef EGL_ANGLE_platform_angle_opengl
 #define EGL_ANGLE_platform_angle_opengl 1
 #define EGL_PLATFORM_ANGLE_TYPE_OPENGL_ANGLE 0x320D
 #define EGL_PLATFORM_ANGLE_TYPE_OPENGLES_ANGLE 0x320E
 #endif /* EGL_ANGLE_platform_angle_opengl */
@@ -100,26 +101,26 @@
 
 #ifndef EGL_ANGLE_experimental_present_path
 #define EGL_ANGLE_experimental_present_path
 #define EGL_EXPERIMENTAL_PRESENT_PATH_ANGLE 0x33A4
 #define EGL_EXPERIMENTAL_PRESENT_PATH_FAST_ANGLE 0x33A9
 #define EGL_EXPERIMENTAL_PRESENT_PATH_COPY_ANGLE 0x33AA
 #endif /* EGL_ANGLE_experimental_present_path */
 
-#ifndef EGL_ANGLE_stream_producer_d3d_texture_nv12
-#define EGL_ANGLE_stream_producer_d3d_texture_nv12
+#ifndef EGL_ANGLE_stream_producer_d3d_texture
+#define EGL_ANGLE_stream_producer_d3d_texture
 #define EGL_D3D_TEXTURE_SUBRESOURCE_ID_ANGLE 0x33AB
-typedef EGLBoolean(EGLAPIENTRYP PFNEGLCREATESTREAMPRODUCERD3DTEXTURENV12ANGLEPROC)(EGLDisplay dpy, EGLStreamKHR stream, const EGLAttrib *attrib_list);
-typedef EGLBoolean(EGLAPIENTRYP PFNEGLSTREAMPOSTD3DTEXTURENV12ANGLEPROC)(EGLDisplay dpy, EGLStreamKHR stream, void *texture, const EGLAttrib *attrib_list);
+typedef EGLBoolean(EGLAPIENTRYP PFNEGLCREATESTREAMPRODUCERD3DTEXTUREANGLEPROC)(EGLDisplay dpy, EGLStreamKHR stream, const EGLAttrib *attrib_list);
+typedef EGLBoolean(EGLAPIENTRYP PFNEGLSTREAMPOSTD3DTEXTUREANGLEPROC)(EGLDisplay dpy, EGLStreamKHR stream, void *texture, const EGLAttrib *attrib_list);
 #ifdef EGL_EGLEXT_PROTOTYPES
-EGLAPI EGLBoolean EGLAPIENTRY eglCreateStreamProducerD3DTextureNV12ANGLE(EGLDisplay dpy, EGLStreamKHR stream, const EGLAttrib *attrib_list);
-EGLAPI EGLBoolean EGLAPIENTRY eglStreamPostD3DTextureNV12ANGLE(EGLDisplay dpy, EGLStreamKHR stream, void *texture, const EGLAttrib *attrib_list);
+EGLAPI EGLBoolean EGLAPIENTRY eglCreateStreamProducerD3DTextureANGLE(EGLDisplay dpy, EGLStreamKHR stream, const EGLAttrib *attrib_list);
+EGLAPI EGLBoolean EGLAPIENTRY eglStreamPostD3DTextureANGLE(EGLDisplay dpy, EGLStreamKHR stream, void *texture, const EGLAttrib *attrib_list);
 #endif
-#endif /* EGL_ANGLE_stream_producer_d3d_texture_nv12 */
+#endif /* EGL_ANGLE_stream_producer_d3d_texture */
 
 #ifndef EGL_ANGLE_create_context_webgl_compatibility
 #define EGL_ANGLE_create_context_webgl_compatibility 1
 #define EGL_CONTEXT_WEBGL_COMPATIBILITY_ANGLE 0x3AAC
 #endif /* EGL_ANGLE_create_context_webgl_compatibility */
 
 #ifndef EGL_ANGLE_display_texture_share_group
 #define EGL_ANGLE_display_texture_share_group 1
@@ -160,11 +161,20 @@ typedef EGLint (EGLAPIENTRYP PFNEGLPROGR
 #ifdef EGL_EGLEXT_PROTOTYPES
 EGLAPI EGLint EGLAPIENTRY eglProgramCacheGetAttribANGLE(EGLDisplay dpy, EGLenum attrib);
 EGLAPI void EGLAPIENTRY eglProgramCacheQueryANGLE(EGLDisplay dpy, EGLint index, void *key, EGLint *keysize, void *binary, EGLint *binarysize);
 EGLAPI void EGLAPIENTRY eglProgramCachePopulateANGLE(EGLDisplay dpy, const void *key, EGLint keysize, const void *binary, EGLint binarysize);
 EGLAPI EGLint EGLAPIENTRY eglProgramCacheResizeANGLE(EGLDisplay dpy, EGLint limit, EGLenum mode);
 #endif
 #endif /* EGL_ANGLE_program_cache_control */
 
+#ifndef EGL_ANGLE_iosurface_client_buffer
+#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 */
+
 // clang-format on
 
 #endif  // INCLUDE_EGL_EGLEXT_ANGLE_
--- a/gfx/angle/include/GLES2/gl2ext_angle.h
+++ b/gfx/angle/include/GLES2/gl2ext_angle.h
@@ -24,17 +24,17 @@
 typedef void (GL_APIENTRYP PFNGLREQUESTEXTENSIONANGLEPROC) (const GLchar *name);
 #ifdef GL_GLEXT_PROTOTYPES
 GL_APICALL void GL_APIENTRY glRequestExtensionANGLE (const GLchar *name);
 #endif
 #endif /* GL_ANGLE_webgl_compatibility */
 
 #ifndef GL_ANGLE_robust_resource_initialization
 #define GL_ANGLE_robust_resource_initialization 1
-#define GL_CONTEXT_ROBUST_RESOURCE_INITIALIZATION_ANGLE 0x93AB
+#define GL_ROBUST_RESOURCE_INITIALIZATION_ANGLE 0x93AB
 #endif /* GL_ANGLE_robust_resource_initialization */
 
 #ifndef GL_CHROMIUM_framebuffer_mixed_samples
 #define GL_CHROMIUM_frambuffer_mixed_samples 1
 #define GL_COVERAGE_MODULATION_CHROMIUM 0x9332
 typedef void (GL_APIENTRYP PFNGLCOVERAGEMODULATIONCHROMIUMPROC) (GLenum components);
 #ifdef GL_GLEXT_PROTOTYPES
 GL_APICALL void GL_APIENTRY glCoverageModulationCHROMIUM(GLenum components);
--- a/gfx/angle/include/GLSLANG/ShaderLang.h
+++ b/gfx/angle/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 182
+#define ANGLE_SH_VERSION 194
 
 enum ShShaderSpec
 {
     SH_GLES2_SPEC,
     SH_WEBGL_SPEC,
 
     SH_GLES3_SPEC,
     SH_WEBGL2_SPEC,
@@ -209,46 +209,59 @@ const ShCompileOptions SH_USE_UNUSED_STA
 // This flag works around a bug in unary minus operator on float numbers on Intel
 // Mac OSX 10.11 drivers. It works by translating -float into 0.0 - float.
 const ShCompileOptions SH_REWRITE_FLOAT_UNARY_MINUS_OPERATOR = UINT64_C(1) << 29;
 
 // This flag works around a bug in evaluating atan(y, x) on some NVIDIA OpenGL drivers.
 // It works by using an expression to emulate this function.
 const ShCompileOptions SH_EMULATE_ATAN2_FLOAT_FUNCTION = UINT64_C(1) << 30;
 
-// Set to 1 to translate gl_ViewID_OVR to an uniform so that the extension can be emulated.
-// "uniform highp uint ViewID_OVR".
-const ShCompileOptions SH_TRANSLATE_VIEWID_OVR_TO_UNIFORM = UINT64_C(1) << 31;
-
-// Set to initialize uninitialized local variables. Should only be used with GLSL output. In HLSL
-// output variables are initialized regardless of if this flag is set.
-const ShCompileOptions SH_INITIALIZE_UNINITIALIZED_LOCALS = UINT64_C(1) << 32;
+// Set to initialize uninitialized local and global temporary variables. Should only be used with
+// GLSL output. In HLSL output variables are initialized regardless of if this flag is set.
+const ShCompileOptions SH_INITIALIZE_UNINITIALIZED_LOCALS = UINT64_C(1) << 31;
 
 // The flag modifies the shader in the following way:
 // Every occurrence of gl_InstanceID is replaced by the global temporary variable InstanceID.
 // Every occurrence of gl_ViewID_OVR is replaced by the varying variable ViewID_OVR.
 // At the beginning of the body of main() in a vertex shader the following initializers are added:
 // ViewID_OVR = uint(gl_InstanceID) % num_views;
 // InstanceID = gl_InstanceID / num_views;
 // ViewID_OVR is added as a varying variable to both the vertex and fragment shaders.
-const ShCompileOptions SH_INITIALIZE_BUILTINS_FOR_INSTANCED_MULTIVIEW = UINT64_C(1) << 33;
+const ShCompileOptions SH_INITIALIZE_BUILTINS_FOR_INSTANCED_MULTIVIEW = UINT64_C(1) << 32;
 
 // With the flag enabled the GLSL/ESSL vertex shader is modified to include code for viewport
 // selection in the following way:
 // - Code to enable the extension NV_viewport_array2 is included.
 // - Code to select the viewport index or layer is inserted at the beginning of main after
 // ViewID_OVR's initialization.
 // - A declaration of the uniform multiviewBaseViewLayerIndex.
 // Note: The SH_INITIALIZE_BUILTINS_FOR_INSTANCED_MULTIVIEW flag also has to be enabled to have the
 // temporary variable ViewID_OVR declared and initialized.
-const ShCompileOptions SH_SELECT_VIEW_IN_NV_GLSL_VERTEX_SHADER = UINT64_C(1) << 34;
+const ShCompileOptions SH_SELECT_VIEW_IN_NV_GLSL_VERTEX_SHADER = UINT64_C(1) << 33;
 
 // If the flag is enabled, gl_PointSize is clamped to the maximum point size specified in
 // ShBuiltInResources in vertex shaders.
-const ShCompileOptions SH_CLAMP_POINT_SIZE = UINT64_C(1) << 35;
+const ShCompileOptions SH_CLAMP_POINT_SIZE = UINT64_C(1) << 34;
+
+// 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.
+const ShCompileOptions SH_REWRITE_VECTOR_SCALAR_ARITHMETIC = UINT64_C(1) << 35;
+
+// Don't use loops to initialize uninitialized variables. Only has an effect if some kind of
+// variable initialization is turned on.
+const ShCompileOptions SH_DONT_USE_LOOPS_TO_INITIALIZE_VARIABLES = UINT64_C(1) << 36;
+
+// Don't use D3D constant register zero when allocating space for uniforms. This is targeted to work
+// around a bug in NVIDIA D3D driver version 388.59 where in very specific cases the driver would
+// not handle constant register zero correctly. Only has an effect on HLSL translation.
+const ShCompileOptions SH_SKIP_D3D_CONSTANT_REGISTER_ZERO = UINT64_C(1) << 37;
 
 // Defines alternate strategies for implementing array index clamping.
 enum ShArrayIndexClampingStrategy
 {
     // Use the clamp intrinsic for array index clamping.
     SH_CLAMP_WITH_CLAMP_INTRINSIC = 1,
 
     // Use a user-defined function for array index clamping.
@@ -287,17 +300,17 @@ struct ShBuiltInResources
     int EXT_frag_depth;
     int EXT_shader_texture_lod;
     int WEBGL_debug_shader_precision;
     int EXT_shader_framebuffer_fetch;
     int NV_shader_framebuffer_fetch;
     int ARM_shader_framebuffer_fetch;
     int OVR_multiview;
     int EXT_YUV_target;
-    int OES_geometry_shader;
+    int EXT_geometry_shader;
 
     // Set to 1 to enable replacing GL_EXT_draw_buffers #extension directives
     // with GL_NV_draw_buffers in ESSL output. This flag can be used to emulate
     // EXT_draw_buffers by using it in combination with GLES3.0 glDrawBuffers
     // function. This applies to Tegra K1 devices.
     int NV_draw_buffers;
 
     // Set to 1 if highp precision is supported in the ESSL 1.00 version of the
@@ -413,17 +426,17 @@ struct ShBuiltInResources
     int MaxUniformBufferBindings;
 
     // maximum number of shader storage buffer bindings
     int MaxShaderStorageBufferBindings;
 
     // maximum point size (higher limit from ALIASED_POINT_SIZE_RANGE)
     float MaxPointSize;
 
-    // OES_geometry_shader constants
+    // EXT_geometry_shader constants
     int MaxGeometryUniformComponents;
     int MaxGeometryUniformBlocks;
     int MaxGeometryInputComponents;
     int MaxGeometryOutputComponents;
     int MaxGeometryOutputVertices;
     int MaxGeometryTotalOutputComponents;
     int MaxGeometryTextureImageUnits;
     int MaxGeometryAtomicCounterBuffers;
@@ -581,11 +594,16 @@ bool CheckVariablesWithinPackingLimits(i
 bool GetUniformBlockRegister(const ShHandle handle,
                              const std::string &uniformBlockName,
                              unsigned int *indexOut);
 
 // Gives a map from uniform names to compiler-assigned registers in the default uniform block.
 // Note that the map contains also registers of samplers that have been extracted from structs.
 const std::map<std::string, unsigned int> *GetUniformRegisterMap(const ShHandle handle);
 
+GLenum GetGeometryShaderInputPrimitiveType(const ShHandle handle);
+GLenum GetGeometryShaderOutputPrimitiveType(const ShHandle handle);
+int GetGeometryShaderInvocations(const ShHandle handle);
+int GetGeometryShaderMaxVertices(const ShHandle handle);
+
 }  // namespace sh
 
 #endif // GLSLANG_SHADERLANG_H_
--- a/gfx/angle/include/GLSLANG/ShaderVars.h
+++ b/gfx/angle/include/GLSLANG/ShaderVars.h
@@ -6,16 +6,17 @@
 // ShaderVars.h:
 //  Types to represent GL variables (varyings, uniforms, etc)
 //
 
 #ifndef GLSLANG_SHADERVARS_H_
 #define GLSLANG_SHADERVARS_H_
 
 #include <algorithm>
+#include <array>
 #include <string>
 #include <vector>
 
 // This type is defined here to simplify ANGLE's integration with glslang for SPIRv.
 using ShCompileOptions = uint64_t;
 
 namespace sh
 {
@@ -32,16 +33,18 @@ enum InterpolationType
 
 // Validate link & SSO consistency of interpolation qualifiers
 bool InterpolationTypesMatch(InterpolationType a, InterpolationType b);
 
 // Uniform block layout qualifier, see section 4.3.8.3 of the ESSL 3.00.4 spec
 enum BlockLayoutType
 {
     BLOCKLAYOUT_STANDARD,
+    BLOCKLAYOUT_STD140 = BLOCKLAYOUT_STANDARD,
+    BLOCKLAYOUT_STD430,  // Shader storage block layout qualifier
     BLOCKLAYOUT_PACKED,
     BLOCKLAYOUT_SHARED
 };
 
 // Interface Blocks, see section 4.3.9 of the ESSL 3.10 spec
 enum class BlockType
 {
     BLOCK_UNIFORM,
@@ -54,23 +57,45 @@ enum class BlockType
 
 // Base class for all variables defined in shaders, including Varyings, Uniforms, etc
 // Note: we must override the copy constructor and assignment operator so we can
 // work around excessive GCC binary bloating:
 // See https://code.google.com/p/angleproject/issues/detail?id=697
 struct ShaderVariable
 {
     ShaderVariable();
+    ShaderVariable(GLenum typeIn);
     ShaderVariable(GLenum typeIn, unsigned int arraySizeIn);
     ~ShaderVariable();
     ShaderVariable(const ShaderVariable &other);
     ShaderVariable &operator=(const ShaderVariable &other);
 
-    bool isArray() const { return arraySize > 0; }
-    unsigned int elementCount() const { return std::max(1u, arraySize); }
+    bool isArrayOfArrays() const { return arraySizes.size() >= 2u; }
+    bool isArray() const { return !arraySizes.empty(); }
+    unsigned int getArraySizeProduct() const;
+
+    // Array size 0 means not an array when passed to or returned from these functions.
+    // Note that setArraySize() is deprecated and should not be used inside ANGLE.
+    unsigned int getOutermostArraySize() const { return isArray() ? arraySizes.back() : 0; }
+    void setArraySize(unsigned int size);
+
+    // Turn this ShaderVariable from an array into a specific element in that array. Will update
+    // flattenedOffsetInParentArrays.
+    void indexIntoArray(unsigned int arrayIndex);
+
+    // Get the nth nested array size from the top. Caller is responsible for range checking
+    // arrayNestingIndex.
+    unsigned int getNestedArraySize(unsigned int arrayNestingIndex) const;
+
+    // This function should only be used with variables that are of a basic type or an array of a
+    // basic type. Shader interface variables that are enumerated according to rules in GLES 3.1
+    // spec section 7.3.1.1 page 77 are fine. For those variables the return value should match the
+    // ARRAY_SIZE value that can be queried through the API.
+    unsigned int getBasicTypeElementCount() const;
+
     bool isStruct() const { return !fields.empty(); }
 
     // All of the shader's variables are described using nested data
     // structures. This is needed in order to disambiguate similar looking
     // types, such as two structs containing the same fields, but in
     // different orders. "findInfoByMappedName" provides an easy query for
     // users to dive into the data structure and fetch the unique variable
     // instance corresponding to a dereferencing chain of the top-level
@@ -78,23 +103,34 @@ struct ShaderVariable
     // Given a mapped name like 'a[0].b.c[0]', return the ShaderVariable
     // that defines 'c' in |leafVar|, and the original name 'A[0].B.C[0]'
     // in |originalName|, based on the assumption that |this| defines 'a'.
     // If no match is found, return false.
     bool findInfoByMappedName(const std::string &mappedFullName,
                               const ShaderVariable **leafVar,
                               std::string* originalFullName) const;
 
-    bool isBuiltIn() const { return name.compare(0, 3, "gl_") == 0; }
+    bool isBuiltIn() const;
 
     GLenum type;
     GLenum precision;
     std::string name;
     std::string mappedName;
-    unsigned int arraySize;
+
+    // Used to make an array type. Outermost array size is stored at the end of the vector.
+    std::vector<unsigned int> arraySizes;
+
+    // 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;
+
     bool staticUse;
     std::vector<ShaderVariable> fields;
     std::string structName;
 
   protected:
     bool isSameVariableAtLinkTime(const ShaderVariable &other,
                                   bool matchPrecision,
                                   bool matchName) const;
@@ -129,16 +165,18 @@ struct Uniform : public VariableWithLoca
     bool operator==(const Uniform &other) const;
     bool operator!=(const Uniform &other) const
     {
         return !operator==(other);
     }
 
     int binding;
     int offset;
+    bool readonly;
+    bool writeonly;
 
     // Decide whether two uniforms are the same at shader link time,
     // assuming one from vertex shader and the other from fragment shader.
     // GLSL ES Spec 3.00.3, section 4.3.5.
     // GLSL ES Spec 3.10.4, section 4.4.5
     bool isSameUniformAtLinkTime(const Uniform &other) const;
 };
 
@@ -183,17 +221,17 @@ struct InterfaceBlockField : public Shad
 
     bool isRowMajorLayout;
 };
 
 struct Varying : public VariableWithLocation
 {
     Varying();
     ~Varying();
-    Varying(const Varying &otherg);
+    Varying(const Varying &other);
     Varying &operator=(const Varying &other);
     bool operator==(const Varying &other) const;
     bool operator!=(const Varying &other) const
     {
         return !operator==(other);
     }
 
     // Decide whether two varyings are the same at shader link time,
@@ -219,32 +257,46 @@ struct InterfaceBlock
 
     // Fields from blocks with non-empty instance names are prefixed with the block name.
     std::string fieldPrefix() const;
     std::string fieldMappedPrefix() const;
 
     // Decide whether two interface blocks are the same at shader link time.
     bool isSameInterfaceBlockAtLinkTime(const InterfaceBlock &other) const;
 
-    bool isBuiltIn() const { return name.compare(0, 3, "gl_") == 0; }
+    bool isBuiltIn() const;
+
+    bool isArray() const { return arraySize > 0; }
+    unsigned int elementCount() const { return std::max(1u, arraySize); }
 
     std::string name;
     std::string mappedName;
     std::string instanceName;
     unsigned int arraySize;
     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;
     BlockType blockType;
     std::vector<InterfaceBlockField> fields;
 };
 
 struct WorkGroupSize
 {
+    // Must have a trivial default constructor since it is used in YYSTYPE.
+    WorkGroupSize() = default;
+    explicit constexpr WorkGroupSize(int initialSize)
+        : localSizeQualifiers{initialSize, initialSize, initialSize}
+    {
+    }
+
     void fill(int fillValue);
     void setLocalSize(int localSizeX, int localSizeY, int localSizeZ);
 
     int &operator[](size_t index);
     int operator[](size_t index) const;
     size_t size() const;
 
     // Checks whether two work group size declarations match.
@@ -256,14 +308,14 @@ struct WorkGroupSize
     bool isAnyValueSet() const;
 
     // Checks whether all of the values are set.
     bool isDeclared() const;
 
     // Checks whether either all of the values are set, or none of them are.
     bool isLocalSizeValid() const;
 
-    int localSizeQualifiers[3];
+    std::array<int, 3> localSizeQualifiers;
 };
 
 }  // namespace sh
 
 #endif // GLSLANG_SHADERVARS_H_
--- a/gfx/angle/include/platform/Platform.h
+++ b/gfx/angle/include/platform/Platform.h
@@ -10,21 +10,21 @@
 #define ANGLE_PLATFORM_H
 
 #include <stdint.h>
 #include <array>
 
 #if defined(_WIN32)
 #   if !defined(LIBANGLE_IMPLEMENTATION)
 #       define ANGLE_PLATFORM_EXPORT __declspec(dllimport)
+#   else
+#       define ANGLE_PLATFORM_EXPORT __declspec(dllexport)
 #   endif
-#elif defined(__GNUC__)
-#   if defined(LIBANGLE_IMPLEMENTATION)
-#       define ANGLE_PLATFORM_EXPORT __attribute__((visibility ("default")))
-#   endif
+#elif defined(__GNUC__) || defined(__clang__)
+#   define ANGLE_PLATFORM_EXPORT __attribute__((visibility ("default")))
 #endif
 #if !defined(ANGLE_PLATFORM_EXPORT)
 #   define ANGLE_PLATFORM_EXPORT
 #endif
 
 #if defined(_WIN32)
 #   define ANGLE_APIENTRY __stdcall
 #else
@@ -259,18 +259,20 @@ inline void DefaultCacheProgram(Platform
     OP(histogramEnumeration, HistogramEnumeration)               \
     OP(histogramSparse, HistogramSparse)                         \
     OP(histogramBoolean, HistogramBoolean)                       \
     OP(overrideWorkaroundsD3D, OverrideWorkaroundsD3D)           \
     OP(cacheProgram, CacheProgram)
 
 #define ANGLE_PLATFORM_METHOD_DEF(Name, CapsName) CapsName##Func Name = Default##CapsName;
 
-struct PlatformMethods
+struct ANGLE_PLATFORM_EXPORT PlatformMethods
 {
+    PlatformMethods();
+
     // User data pointer for any implementation specific members. Put it at the start of the
     // platform structure so it doesn't become overwritten if one version of the platform
     // adds or removes new members.
     void *context = 0;
 
     ANGLE_PLATFORM_OP(ANGLE_PLATFORM_METHOD_DEF);
 };
 
--- a/gfx/angle/include/platform/WorkaroundsD3D.h
+++ b/gfx/angle/include/platform/WorkaroundsD3D.h
@@ -92,28 +92,44 @@ struct WorkaroundsD3D
     bool rewriteUnaryMinusOperator = false;
 
     // On some Intel drivers, using isnan() on highp float will get wrong answer. To work around
     // this bug, we use an expression to emulate function isnan().
     // Tracking bug: https://crbug.com/650547
     // This driver bug is fixed in 21.20.16.4542.
     bool emulateIsnanFloat = false;
 
-    // On some Intel drivers, using clear() may not take effect. One of such situation is to clear
-    // a target with width or height < 16. To work around this bug, we call clear() twice on these
-    // platforms. Tracking bug: https://crbug.com/655534
+    // On some Intel drivers, using clear() may not take effect. To work around this bug, we call
+    // clear() twice on these platforms.
+    // Tracking bug: https://crbug.com/655534
     bool callClearTwice = false;
 
     // On some Intel drivers, copying from staging storage to constant buffer storage does not
     // seem to work. Work around this by keeping system memory storage as a canonical reference
     // for buffer data.
     // D3D11-only workaround. See http://crbug.com/593024.
     bool useSystemMemoryForConstantBuffers = false;
 
     // This workaround is for the ANGLE_multiview extension. If enabled the viewport or render
     // target slice will be selected in the geometry shader stage. The workaround flag is added to
     // make it possible to select the code path in end2end and performance tests.
     bool selectViewInGeometryShader = false;
+
+    // When rendering with no render target on D3D, two bugs lead to incorrect behavior on Intel
+    // drivers < 4815. The rendering samples always pass neglecting discard statements in pixel
+    // shader.
+    // 1. If rendertarget is not set, the pixel shader will be recompiled to drop 'SV_TARGET'.
+    // When using a pixel shader with no 'SV_TARGET' in a draw, the pixels are always generated even
+    // if they should be discard by 'discard' statements.
+    // 2. If ID3D11BlendState.RenderTarget[].RenderTargetWriteMask is 0 and rendertarget is not set,
+    // then rendering samples also pass neglecting discard statements in pixel shader.
+    // So we add a dummy texture as render target in such case. See http://anglebug.com/2152
+    bool addDummyTextureNoRenderTarget = false;
+
+    // Don't use D3D constant register zero when allocating space for uniforms. This is targeted to
+    // work around a bug in NVIDIA D3D driver version 388.59 where in very specific cases the driver
+    // would not handle constant register zero correctly.
+    bool skipConstantRegisterZero = false;
 };
 
 }  // namespace angle
 
 #endif  // ANGLE_PLATFORM_WORKAROUNDSD3D_H_
--- a/gfx/angle/moz.build
+++ b/gfx/angle/moz.build
@@ -11,59 +11,61 @@
 UNIFIED_SOURCES += [
     'src/common/angleutils.cpp',
     'src/common/debug.cpp',
     'src/common/Float16ToFloat32.cpp',
     'src/common/mathutil.cpp',
     'src/common/MemoryBuffer.cpp',
     'src/common/string_utils.cpp',
     'src/common/third_party/base/anglebase/sha1.cc',
+    'src/common/third_party/smhasher/src/PMurHash.cpp',
     'src/common/tls.cpp',
     'src/common/uniform_type_info_autogen.cpp',
     'src/common/utilities.cpp',
     'src/compiler/preprocessor/DiagnosticsBase.cpp',
     'src/compiler/preprocessor/DirectiveHandlerBase.cpp',
     'src/compiler/preprocessor/DirectiveParser.cpp',
-    'src/compiler/preprocessor/ExpressionParser.cpp',
     'src/compiler/preprocessor/Input.cpp',
     'src/compiler/preprocessor/Lexer.cpp',
     'src/compiler/preprocessor/Macro.cpp',
     'src/compiler/preprocessor/MacroExpander.cpp',
     'src/compiler/preprocessor/Preprocessor.cpp',
     'src/compiler/preprocessor/Token.cpp',
+    'src/compiler/preprocessor/Tokenizer.cpp',
     'src/compiler/translator/AddAndTrueToLoopCondition.cpp',
     'src/compiler/translator/AddDefaultReturnStatements.cpp',
     'src/compiler/translator/ArrayReturnValueToOutParameter.cpp',
     'src/compiler/translator/ASTMetadataHLSL.cpp',
-    'src/compiler/translator/blocklayout.cpp',
     'src/compiler/translator/blocklayoutHLSL.cpp',
     'src/compiler/translator/BreakVariableAliasingInInnerLoops.cpp',
     'src/compiler/translator/BuiltInFunctionEmulator.cpp',
     'src/compiler/translator/BuiltInFunctionEmulatorGLSL.cpp',
     'src/compiler/translator/BuiltInFunctionEmulatorHLSL.cpp',
-    'src/compiler/translator/Cache.cpp',
     'src/compiler/translator/CallDAG.cpp',
     'src/compiler/translator/ClampPointSize.cpp',
     'src/compiler/translator/CodeGen.cpp',
     'src/compiler/translator/CollectVariables.cpp',
     'src/compiler/translator/Compiler.cpp',
     'src/compiler/translator/ConstantUnion.cpp',
+    'src/compiler/translator/Declarator.cpp',
     'src/compiler/translator/DeclareAndInitBuiltinsForInstancedMultiview.cpp',
     'src/compiler/translator/DeferGlobalInitializers.cpp',
     'src/compiler/translator/Diagnostics.cpp',
     'src/compiler/translator/DirectiveHandler.cpp',
     'src/compiler/translator/emulated_builtin_functions_hlsl_autogen.cpp',
     'src/compiler/translator/EmulatePrecision.cpp',
     'src/compiler/translator/ExpandIntegerPowExpressions.cpp',
     'src/compiler/translator/ExtensionBehavior.cpp',
     'src/compiler/translator/ExtensionGLSL.cpp',
     'src/compiler/translator/FindMain.cpp',
     'src/compiler/translator/FindSymbolNode.cpp',
     'src/compiler/translator/FlagStd140Structs.cpp',
+    'src/compiler/translator/FoldExpressions.cpp',
     'src/compiler/translator/HashNames.cpp',
+    'src/compiler/translator/ImageFunctionHLSL.cpp',
     'src/compiler/translator/InfoSink.cpp',
     'src/compiler/translator/Initialize.cpp',
     'src/compiler/translator/InitializeDll.cpp',
     'src/compiler/translator/InitializeVariables.cpp',
     'src/compiler/translator/IntermNode.cpp',
     'src/compiler/translator/IntermNode_util.cpp',
     'src/compiler/translator/IntermNodePatternMatcher.cpp',
     'src/compiler/translator/IntermTraverse.cpp',
@@ -71,69 +73,76 @@ UNIFIED_SOURCES += [
     'src/compiler/translator/Operator.cpp',
     'src/compiler/translator/OutputESSL.cpp',
     'src/compiler/translator/OutputGLSL.cpp',
     'src/compiler/translator/OutputGLSLBase.cpp',
     'src/compiler/translator/OutputHLSL.cpp',
     'src/compiler/translator/OutputTree.cpp',
     'src/compiler/translator/ParseContext.cpp',
     'src/compiler/translator/PoolAlloc.cpp',
-    'src/compiler/translator/PruneEmptyDeclarations.cpp',
-    'src/compiler/translator/PrunePureLiteralStatements.cpp',
+    'src/compiler/translator/PruneNoOps.cpp',
     'src/compiler/translator/QualifierTypes.cpp',
     'src/compiler/translator/RecordConstantPrecision.cpp',
     'src/compiler/translator/RegenerateStructNames.cpp',
     'src/compiler/translator/RemoveArrayLengthMethod.cpp',
     'src/compiler/translator/RemoveDynamicIndexing.cpp',
+    'src/compiler/translator/RemoveEmptySwitchStatements.cpp',
     'src/compiler/translator/RemoveInvariantDeclaration.cpp',
+    'src/compiler/translator/RemoveNoOpCasesFromEndOfSwitchStatements.cpp',
     'src/compiler/translator/RemovePow.cpp',
     'src/compiler/translator/RemoveSwitchFallThrough.cpp',
+    'src/compiler/translator/RemoveUnreferencedVariables.cpp',
     'src/compiler/translator/RewriteDoWhile.cpp',
     'src/compiler/translator/RewriteElseBlocks.cpp',
     'src/compiler/translator/RewriteUnaryMinusOperatorFloat.cpp',
     'src/compiler/translator/RunAtTheEndOfShader.cpp',
     'src/compiler/translator/ScalarizeVecAndMatConstructorArgs.cpp',
-    'src/compiler/translator/SearchSymbol.cpp',
     'src/compiler/translator/SeparateArrayInitialization.cpp',
     'src/compiler/translator/SeparateDeclarations.cpp',
     'src/compiler/translator/SeparateExpressionsReturningArrays.cpp',
     'src/compiler/translator/ShaderVars.cpp',
     'src/compiler/translator/SimplifyLoopConditions.cpp',
     'src/compiler/translator/SplitSequenceOperator.cpp',
+    'src/compiler/translator/StaticType.cpp',
     'src/compiler/translator/StructureHLSL.cpp',
+    'src/compiler/translator/Symbol.cpp',
     'src/compiler/translator/SymbolTable.cpp',
+    'src/compiler/translator/SymbolUniqueId.cpp',
     'src/compiler/translator/TextureFunctionHLSL.cpp',
     'src/compiler/translator/TranslatorESSL.cpp',
     'src/compiler/translator/TranslatorGLSL.cpp',
     'src/compiler/translator/TranslatorHLSL.cpp',
     'src/compiler/translator/Types.cpp',
     'src/compiler/translator/UnfoldShortCircuitAST.cpp',
     'src/compiler/translator/UnfoldShortCircuitToIf.cpp',
     'src/compiler/translator/UniformHLSL.cpp',
     'src/compiler/translator/UseInterfaceBlockFields.cpp',
     'src/compiler/translator/util.cpp',
     'src/compiler/translator/UtilsHLSL.cpp',
     'src/compiler/translator/ValidateGlobalInitializer.cpp',
     'src/compiler/translator/ValidateLimitations.cpp',
     'src/compiler/translator/ValidateMaxParameters.cpp',
     'src/compiler/translator/ValidateSwitch.cpp',
     'src/compiler/translator/ValidateVaryingLocations.cpp',
-    'src/compiler/translator/VariablePacker.cpp',
+    'src/compiler/translator/VectorizeVectorScalarArithmetic.cpp',
     'src/compiler/translator/VersionGLSL.cpp',
+    'src/compiler/translator/WrapSwitchStatementsInBlocks.cpp',
     'src/third_party/compiler/ArrayBoundsClamper.cpp',
 ]
 SOURCES += [
-    'src/compiler/preprocessor/Tokenizer.cpp',
+    'src/compiler/preprocessor/ExpressionParser.cpp',
+    'src/compiler/translator/blocklayout.cpp',
     'src/compiler/translator/EmulateGLFragColorBroadcast.cpp',
     'src/compiler/translator/glslang_lex.cpp',
     'src/compiler/translator/glslang_tab.cpp',
     'src/compiler/translator/RewriteTexelFetchOffset.cpp',
     'src/compiler/translator/RewriteUnaryMinusOperatorInt.cpp',
     'src/compiler/translator/ShaderLang.cpp',
     'src/compiler/translator/ValidateOutputs.cpp',
+    'src/compiler/translator/VariablePacker.cpp',
 ]
 if CONFIG['MOZ_WIDGET_TOOLKIT'] == 'cocoa':
     UNIFIED_SOURCES += [
         'src/common/system_utils_mac.cpp',
     ]
 if CONFIG['MOZ_WIDGET_TOOLKIT'] == 'windows':
     UNIFIED_SOURCES += [
         'src/common/system_utils_win.cpp',
@@ -142,20 +151,20 @@ if CONFIG['MOZ_WIDGET_TOOLKIT'] == 'wind
 
 if CONFIG['CC_TYPE'] in ('clang', 'gcc'):
     CXXFLAGS += [
         '-Wno-attributes',
         '-Wno-shadow',
         '-Wno-sign-compare',
         '-Wno-unknown-pragmas',
         '-Wno-unreachable-code',
+        '-Wno-missing-braces',
     ]
     if CONFIG['CC_TYPE'] == 'clang':
         CXXFLAGS += [
-            '-Wno-implicit-fallthrough',
             '-Wno-inconsistent-missing-override',
             '-Wno-unused-private-field',
         ]
     else:
         CXXFLAGS += [
             '-Wno-shadow-compatible-local',
             '-Wno-shadow-local',
         ]
@@ -193,14 +202,14 @@ if CONFIG['MOZ_WIDGET_TOOLKIT'] == 'wind
 DEFINES['ANGLE_ENABLE_HLSL'] = "1"
 DEFINES['ANGLE_ENABLE_GLSL'] = "1"
 DEFINES['ANGLE_ENABLE_ESSL'] = "1"
 DEFINES['ANGLE_ENABLE_KEYEDMUTEX'] = "1"
 
 EXPORTS.angle += [ 'include/GLSLANG/ShaderLang.h', 'include/GLSLANG/ShaderVars.h', 'include/platform/Platform.h' ]
 EXPORTS.angle.KHR += [ 'include/KHR/khrplatform.h' ]
 
-LOCAL_INCLUDES += [ 'include', 'src', 'src/common/third_party/base']
+LOCAL_INCLUDES += [ 'include', 'src', 'src/common/third_party/base', 'src/common/third_party/smhasher' ]
 
 # We allow warnings for third-party code that can be updated from upstream.
 AllowCompilerWarnings()
 
 FINAL_LIBRARY = 'gkmedias'
--- a/gfx/angle/src/angle.gyp
+++ b/gfx/angle/src/angle.gyp
@@ -10,57 +10,67 @@
         'angle_id_script_base': 'commit_id.py',
         'angle_id_script': '<(angle_gen_path)/<(angle_id_script_base)',
         'angle_id_header_base': 'commit.h',
         'angle_id_header': '<(angle_gen_path)/id/<(angle_id_header_base)',
         'angle_use_commit_id%': '<!(python <(angle_id_script_base) check ..)',
         'angle_enable_d3d9%': 0,
         'angle_enable_d3d11%': 0,
         'angle_enable_gl%': 0,
+        'angle_enable_gl_null%': 0,
         'angle_enable_vulkan%': 0,
         'angle_enable_essl%': 1, # Enable this for all configs by default
         'angle_enable_glsl%': 1, # Enable this for all configs by default
         'angle_enable_hlsl%': 0,
         'angle_link_glx%': 0,
         'angle_gl_library_type%': 'shared_library',
         'dcheck_always_on%': 0,
         'conditions':
         [
             ['OS=="win"',
             {
                 'angle_enable_gl%': 1,
+                'angle_enable_gl_null%': 1,
                 'angle_enable_d3d9%': 1,
                 'angle_enable_d3d11%': 1,
                 'angle_enable_hlsl%': 1,
-                'angle_enable_vulkan%': 1,
             }],
             ['OS=="linux" and use_x11==1 and chromeos==0',
             {
                 'angle_enable_gl%': 1,
-                'angle_enable_vulkan%': 1,
+                'angle_enable_gl_null%': 1,
             }],
             ['OS=="mac"',
             {
                 'angle_enable_gl%': 1,
+                'angle_enable_gl_null%': 1,
             }],
             ['use_ozone==1',
             {
                 'angle_enable_gl%': 1,
+                'angle_enable_gl_null%': 1,
             }],
         ],
         'angle_enable_null%': 1, # Available on all platforms
     },
     'includes':
     [
         'compiler.gypi',
         'libGLESv2.gypi',
         'libEGL.gypi',
-        'vulkan_support/vulkan.gypi',
     ],
 
+    'target_defaults':
+    {
+        'dependencies':
+        [
+            '../gyp/warnings.gyp:gyp_deprecation',
+        ],
+    },
+
     'targets':
     [
         {
             'target_name': 'angle_common',
             'type': 'static_library',
             'includes': [ '../gyp/common_defines.gypi', ],
             'sources':
             [
--- a/gfx/angle/src/commit_id.py
+++ b/gfx/angle/src/commit_id.py
@@ -18,16 +18,19 @@ cwd = sys.argv[2]
 if operation == 'check':
     index_path = os.path.join(cwd, '.git', 'index')
     if os.path.exists(index_path):
         print("1")
     else:
         print("0")
     sys.exit(0)
 
+if len(sys.argv) < 4 or operation != 'gen':
+    sys.exit(usage)
+
 output_file = sys.argv[3]
 commit_id_size = 12
 
 try:
     commit_id = grab_output('git rev-parse --short=%d HEAD' % commit_id_size, cwd)
     commit_date = grab_output('git show -s --format=%ci HEAD', cwd)
 except:
     commit_id = 'invalid-hash'
--- a/gfx/angle/src/common/angleutils.cpp
+++ b/gfx/angle/src/common/angleutils.cpp
@@ -9,19 +9,49 @@
 
 #include <stdio.h>
 
 #include <limits>
 #include <vector>
 
 namespace angle
 {
+// dirtyPointer is a special value that will make the comparison with any valid pointer fail and
+// force the renderer to re-apply the state.
 const uintptr_t DirtyPointer = std::numeric_limits<uintptr_t>::max();
 }
 
+std::string ArrayString(unsigned int i)
+{
+    // We assume that UINT_MAX and GL_INVALID_INDEX are equal.
+    ASSERT(i != UINT_MAX);
+
+    std::stringstream strstr;
+    strstr << "[";
+    strstr << i;
+    strstr << "]";
+    return strstr.str();
+}
+
+std::string ArrayIndexString(const std::vector<unsigned int> &indices)
+{
+    std::stringstream strstr;
+
+    for (auto indicesIt = indices.rbegin(); indicesIt != indices.rend(); ++indicesIt)
+    {
+        // We assume that UINT_MAX and GL_INVALID_INDEX are equal.
+        ASSERT(*indicesIt != UINT_MAX);
+        strstr << "[";
+        strstr << (*indicesIt);
+        strstr << "]";
+    }
+
+    return strstr.str();
+}
+
 size_t FormatStringIntoVector(const char *fmt, va_list vararg, std::vector<char>& outBuffer)
 {
     // The state of the va_list passed to vsnprintf is undefined after the call, do a copy in case
     // we need to grow the buffer.
     va_list varargCopy;
     va_copy(varargCopy, vararg);
 
     // Attempt to just print to the current buffer
--- a/gfx/angle/src/common/angleutils.h
+++ b/gfx/angle/src/common/angleutils.h
@@ -155,33 +155,21 @@ inline const char* MakeStaticString(cons
     if (it != strings.end())
     {
         return it->c_str();
     }
 
     return strings.insert(str).first->c_str();
 }
 
-inline std::string ArrayString(unsigned int i)
-{
-    // We assume UINT_MAX and GL_INVALID_INDEX are equal
-    // See DynamicHLSL.cpp
-    if (i == UINT_MAX)
-    {
-        return "";
-    }
+std::string ArrayString(unsigned int i);
 
-    std::stringstream strstr;
-
-    strstr << "[";
-    strstr << i;
-    strstr << "]";
-
-    return strstr.str();
-}
+// Indices are stored in vectors with the outermost index in the back. In the output of the function
+// the indices are reversed.
+std::string ArrayIndexString(const std::vector<unsigned int> &indices);
 
 inline std::string Str(int i)
 {
     std::stringstream strstr;
     strstr << i;
     return strstr.str();
 }
 
@@ -203,19 +191,18 @@ std::string ToString(const T &value)
 #define snprintf _snprintf
 #endif
 
 #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
-
-// Hidden enum for the NULL D3D device type.
-#define EGL_PLATFORM_ANGLE_DEVICE_TYPE_NULL_ANGLE 0x6AC0
+#define GL_UINT_64_ANGLEX 0x6ABF
+#define GL_BGRA8_SRGB_ANGLEX 0x6AC0
 
 // TODO(jmadill): Clean this up at some point.
 #define EGL_PLATFORM_ANGLE_PLATFORM_METHODS_ANGLEX 0x9999
 
 #define ANGLE_TRY_CHECKED_MATH(result)                     \
     if (!result.IsValid())                                 \
     {                                                      \
         return gl::InternalError() << "Integer overflow."; \
new file mode 100644
--- /dev/null
+++ b/gfx/angle/src/common/angleutils_unittest.cpp
@@ -0,0 +1,26 @@
+//
+// 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.
+//
+
+// angleutils_unittest.cpp: Unit tests for ANGLE's common utilities.
+
+#include "gtest/gtest.h"
+
+#include "common/angleutils.h"
+
+namespace
+{
+
+// Test that multiple array indices are written out in the right order.
+TEST(ArrayIndexString, MultipleArrayIndices)
+{
+    std::vector<unsigned int> indices;
+    indices.push_back(12);
+    indices.push_back(34);
+    indices.push_back(56);
+    EXPECT_EQ("[56][34][12]", ArrayIndexString(indices));
+}
+
+}  // anonymous namespace
--- a/gfx/angle/src/common/bitset_utils.h
+++ b/gfx/angle/src/common/bitset_utils.h
@@ -17,17 +17,17 @@
 #include "common/angleutils.h"
 #include "common/debug.h"
 #include "common/mathutil.h"
 #include "common/platform.h"
 
 namespace angle
 {
 
-template <size_t N, typename BitsT>
+template <size_t N, typename BitsT, typename ParamT = std::size_t>
 class BitSetT final
 {
   public:
     class Reference final
     {
       public:
         ~Reference() {}
         Reference &operator=(bool x)
@@ -68,20 +68,20 @@ class BitSetT final
     ~BitSetT();
 
     BitSetT(const BitSetT &other);
     BitSetT &operator=(const BitSetT &other);
 
     bool operator==(const BitSetT &other) const;
     bool operator!=(const BitSetT &other) const;
 
-    constexpr bool operator[](std::size_t pos) const;
-    Reference operator[](std::size_t pos) { return Reference(this, pos); }
+    constexpr bool operator[](ParamT pos) const;
+    Reference operator[](ParamT pos) { return Reference(this, pos); }
 
-    bool test(std::size_t pos) const;
+    bool test(ParamT pos) const;
 
     bool all() const;
     bool any() const;
     bool none() const;
     std::size_t count() const;
 
     constexpr std::size_t size() const { return N; }
 
@@ -91,32 +91,35 @@ class BitSetT final
     BitSetT operator~() const;
 
     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(std::size_t pos, bool value = true);
+    BitSetT &set(ParamT pos, bool value = true);
 
     BitSetT &reset();
-    BitSetT &reset(std::size_t pos);
+    BitSetT &reset(ParamT pos);
 
     BitSetT &flip();
-    BitSetT &flip(std::size_t pos);
+    BitSetT &flip(ParamT pos);
 
     unsigned long to_ulong() const { return static_cast<unsigned long>(mBits); }
     BitsT bits() const { return mBits; }
 
     Iterator begin() const { return Iterator(*this); }
     Iterator end() const { return Iterator(BitSetT()); }
 
   private:
-    constexpr static BitsT Bit(std::size_t x) { return (static_cast<BitsT>(1) << x); }
+    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; }
 
     BitsT mBits;
 };
 
 template <size_t N>
 class IterableBitSet : public std::bitset<N>
 {
@@ -197,302 +200,302 @@ unsigned long IterableBitSet<N>::Iterato
         }
 
         mBits >>= BitsPerWord;
         mOffset += BitsPerWord;
     }
     return 0;
 }
 
-template <size_t N, typename BitsT>
-BitSetT<N, BitsT>::BitSetT() : mBits(0)
+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>
-BitSetT<N, BitsT>::BitSetT(BitsT value) : mBits(value & Mask(N))
+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>
-BitSetT<N, BitsT>::~BitSetT()
+template <size_t N, typename BitsT, typename ParamT>
+BitSetT<N, BitsT, ParamT>::~BitSetT()
 {
 }
 
-template <size_t N, typename BitsT>
-BitSetT<N, BitsT>::BitSetT(const BitSetT &other) : mBits(other.mBits)
+template <size_t N, typename BitsT, typename ParamT>
+BitSetT<N, BitsT, ParamT>::BitSetT(const BitSetT &other) : mBits(other.mBits)
 {
 }
 
-template <size_t N, typename BitsT>
-BitSetT<N, BitsT> &BitSetT<N, BitsT>::operator=(const BitSetT &other)
+template <size_t N, typename BitsT, typename ParamT>
+BitSetT<N, BitsT, ParamT> &BitSetT<N, BitsT, ParamT>::operator=(const BitSetT &other)
 {
     mBits = other.mBits;
     return *this;
 }
 
-template <size_t N, typename BitsT>
-bool BitSetT<N, BitsT>::operator==(const BitSetT &other) const
+template <size_t N, typename BitsT, typename ParamT>
+bool BitSetT<N, BitsT, ParamT>::operator==(const BitSetT &other) const
 {
     return mBits == other.mBits;
 }
 
-template <size_t N, typename BitsT>
-bool BitSetT<N, BitsT>::operator!=(const BitSetT &other) const
+template <size_t N, typename BitsT, typename ParamT>
+bool BitSetT<N, BitsT, ParamT>::operator!=(const BitSetT &other) const
 {
     return mBits != other.mBits;
 }
 
-template <size_t N, typename BitsT>
-constexpr bool BitSetT<N, BitsT>::operator[](std::size_t pos) const
+template <size_t N, typename BitsT, typename ParamT>
+constexpr bool BitSetT<N, BitsT, ParamT>::operator[](ParamT pos) const
 {
     return test(pos);
 }
 
-template <size_t N, typename BitsT>
-bool BitSetT<N, BitsT>::test(std::size_t pos) const
+template <size_t N, typename BitsT, typename ParamT>
+bool BitSetT<N, BitsT, ParamT>::test(ParamT pos) const
 {
     return (mBits & Bit(pos)) != 0;
 }
 
-template <size_t N, typename BitsT>
-bool BitSetT<N, BitsT>::all() const
+template <size_t N, typename BitsT, typename ParamT>
+bool BitSetT<N, BitsT, ParamT>::all() const
 {
     ASSERT(mBits == (mBits & Mask(N)));
     return mBits == Mask(N);
 }
 
-template <size_t N, typename BitsT>
-bool BitSetT<N, BitsT>::any() const
+template <size_t N, typename BitsT, typename ParamT>
+bool BitSetT<N, BitsT, ParamT>::any() const
 {
     ASSERT(mBits == (mBits & Mask(N)));
     return (mBits != 0);
 }
 
-template <size_t N, typename BitsT>
-bool BitSetT<N, BitsT>::none() const
+template <size_t N, typename BitsT, typename ParamT>
+bool BitSetT<N, BitsT, ParamT>::none() const
 {
     ASSERT(mBits == (mBits & Mask(N)));
     return (mBits == 0);
 }
 
-template <size_t N, typename BitsT>
-std::size_t BitSetT<N, BitsT>::count() const
+template <size_t N, typename BitsT, typename ParamT>
+std::size_t BitSetT<N, BitsT, ParamT>::count() const
 {
     return gl::BitCount(mBits);
 }
 
-template <size_t N, typename BitsT>
-BitSetT<N, BitsT> &BitSetT<N, BitsT>::operator&=(const BitSetT &other)
+template <size_t N, typename BitsT, typename ParamT>
+BitSetT<N, BitsT, ParamT> &BitSetT<N, BitsT, ParamT>::operator&=(const BitSetT &other)
 {
     mBits &= other.mBits;
     return *this;
 }
 
-template <size_t N, typename BitsT>
-BitSetT<N, BitsT> &BitSetT<N, BitsT>::operator|=(const BitSetT &other)
+template <size_t N, typename BitsT, typename ParamT>
+BitSetT<N, BitsT, ParamT> &BitSetT<N, BitsT, ParamT>::operator|=(const BitSetT &other)
 {
     mBits |= other.mBits;
     return *this;
 }
 
-template <size_t N, typename BitsT>
-BitSetT<N, BitsT> &BitSetT<N, BitsT>::operator^=(const BitSetT &other)
+template <size_t N, typename BitsT, typename ParamT>
+BitSetT<N, BitsT, ParamT> &BitSetT<N, BitsT, ParamT>::operator^=(const BitSetT &other)
 {
     mBits = (mBits ^ other.mBits) & Mask(N);
     return *this;
 }
 
-template <size_t N, typename BitsT>
-BitSetT<N, BitsT> BitSetT<N, BitsT>::operator~() const
+template <size_t N, typename BitsT, typename ParamT>
+BitSetT<N, BitsT, ParamT> BitSetT<N, BitsT, ParamT>::operator~() const
 {
-    return BitSetT<N, BitsT>(~mBits & Mask(N));
+    return BitSetT<N, BitsT, ParamT>(~mBits & Mask(N));
 }
 
-template <size_t N, typename BitsT>
-BitSetT<N, BitsT> BitSetT<N, BitsT>::operator<<(std::size_t pos) const
+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>((mBits << pos) & Mask(N));
+    return BitSetT<N, BitsT, ParamT>((mBits << pos) & Mask(N));
 }
 
-template <size_t N, typename BitsT>
-BitSetT<N, BitsT> &BitSetT<N, BitsT>::operator<<=(std::size_t pos)
+template <size_t N, typename BitsT, typename ParamT>
+BitSetT<N, BitsT, ParamT> &BitSetT<N, BitsT, ParamT>::operator<<=(std::size_t pos)
 {
     mBits = (mBits << pos & Mask(N));
     return *this;
 }
 
-template <size_t N, typename BitsT>
-BitSetT<N, BitsT> BitSetT<N, BitsT>::operator>>(std::size_t pos) const
+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>(mBits >> pos);
+    return BitSetT<N, BitsT, ParamT>(mBits >> pos);
 }
 
-template <size_t N, typename BitsT>
-BitSetT<N, BitsT> &BitSetT<N, BitsT>::operator>>=(std::size_t pos)
+template <size_t N, typename BitsT, typename ParamT>
+BitSetT<N, BitsT, ParamT> &BitSetT<N, BitsT, ParamT>::operator>>=(std::size_t pos)
 {
     mBits = ((mBits >> pos) & Mask(N));
     return *this;
 }
 
-template <size_t N, typename BitsT>
-BitSetT<N, BitsT> &BitSetT<N, BitsT>::set()
+template <size_t N, typename BitsT, typename ParamT>
+BitSetT<N, BitsT, ParamT> &BitSetT<N, BitsT, ParamT>::set()
 {
     mBits = Mask(N);
     return *this;
 }
 
-template <size_t N, typename BitsT>
-BitSetT<N, BitsT> &BitSetT<N, BitsT>::set(std::size_t pos, bool value)
+template <size_t N, typename BitsT, typename ParamT>
+BitSetT<N, BitsT, ParamT> &BitSetT<N, BitsT, ParamT>::set(ParamT pos, bool value)
 {
     if (value)
     {
         mBits |= Bit(pos);
     }
     else
     {
         reset(pos);
     }
     return *this;
 }
 
-template <size_t N, typename BitsT>
-BitSetT<N, BitsT> &BitSetT<N, BitsT>::reset()
+template <size_t N, typename BitsT, typename ParamT>
+BitSetT<N, BitsT, ParamT> &BitSetT<N, BitsT, ParamT>::reset()
 {
     mBits = 0;
     return *this;
 }
 
-template <size_t N, typename BitsT>
-BitSetT<N, BitsT> &BitSetT<N, BitsT>::reset(std::size_t pos)
+template <size_t N, typename BitsT, typename ParamT>
+BitSetT<N, BitsT, ParamT> &BitSetT<N, BitsT, ParamT>::reset(ParamT pos)
 {
     mBits &= ~Bit(pos);
     return *this;
 }
 
-template <size_t N, typename BitsT>
-BitSetT<N, BitsT> &BitSetT<N, BitsT>::flip()
+template <size_t N, typename BitsT, typename ParamT>
+BitSetT<N, BitsT, ParamT> &BitSetT<N, BitsT, ParamT>::flip()
 {
     mBits ^= Mask(N);
     return *this;
 }
 
-template <size_t N, typename BitsT>
-BitSetT<N, BitsT> &BitSetT<N, BitsT>::flip(std::size_t pos)
+template <size_t N, typename BitsT, typename ParamT>
+BitSetT<N, BitsT, ParamT> &BitSetT<N, BitsT, ParamT>::flip(ParamT pos)
 {
     mBits ^= Bit(pos);
     return *this;
 }
 
-template <size_t N, typename BitsT>
-BitSetT<N, BitsT>::Iterator::Iterator(const BitSetT &bits) : mBitsCopy(bits), mCurrentBit(0)
+template <size_t N, typename BitsT, typename ParamT>
+BitSetT<N, BitsT, ParamT>::Iterator::Iterator(const BitSetT &bits) : mBitsCopy(bits), mCurrentBit(0)
 {
     if (bits.any())
     {
         mCurrentBit = getNextBit();
     }
 }
 
-template <size_t N, typename BitsT>
-typename BitSetT<N, BitsT>::Iterator &BitSetT<N, BitsT>::Iterator::operator++()
+template <size_t N, typename BitsT, typename ParamT>
+typename BitSetT<N, BitsT, ParamT>::Iterator &BitSetT<N, BitsT, ParamT>::Iterator::operator++()
 {
     ASSERT(mBitsCopy.any());
     mBitsCopy.reset(mCurrentBit);
     mCurrentBit = getNextBit();
     return *this;
 }
 
-template <size_t N, typename BitsT>
-bool BitSetT<N, BitsT>::Iterator::operator==(const Iterator &other) const
+template <size_t N, typename BitsT, typename ParamT>
+bool BitSetT<N, BitsT, ParamT>::Iterator::operator==(const Iterator &other) const
 {
     return mBitsCopy == other.mBitsCopy;
 }
 
-template <size_t N, typename BitsT>
-bool BitSetT<N, BitsT>::Iterator::operator!=(const Iterator &other) const
+template <size_t N, typename BitsT, typename ParamT>
+bool BitSetT<N, BitsT, ParamT>::Iterator::operator!=(const Iterator &other) const
 {
     return !(*this == other);
 }
 
-template <size_t N, typename BitsT>
-std::size_t BitSetT<N, BitsT>::Iterator::operator*() const
+template <size_t N, typename BitsT, typename ParamT>
+std::size_t BitSetT<N, BitsT, ParamT>::Iterator::operator*() const
 {
     return mCurrentBit;
 }
 
-template <size_t N, typename BitsT>
-std::size_t BitSetT<N, BitsT>::Iterator::getNextBit()
+template <size_t N, typename BitsT, typename ParamT>
+std::size_t BitSetT<N, BitsT, ParamT>::Iterator::getNextBit()
 {
     if (mBitsCopy.none())
     {
         return 0;
     }
 
     return gl::ScanForward(mBitsCopy.mBits);
 }
 
 template <size_t N>
 using BitSet32 = BitSetT<N, uint32_t>;
 
 // ScanForward for 64-bits requires a 64-bit implementation.
-#if defined(ANGLE_X64_CPU)
+#if defined(ANGLE_IS_64_BIT_CPU)
 template <size_t N>
 using BitSet64 = BitSetT<N, uint64_t>;
-#endif  // defined(ANGLE_X64_CPU)
+#endif  // defined(ANGLE_IS_64_BIT_CPU)
 
 namespace priv
 {
 
 template <size_t N, typename T>
 using EnableIfBitsFit = typename std::enable_if<N <= sizeof(T) * 8>::type;
 
 template <size_t N, typename Enable = void>
 struct GetBitSet
 {
     using Type = IterableBitSet<N>;
 };
 
 // Prefer 64-bit bitsets on 64-bit CPUs. They seem faster than 32-bit.
-#if defined(ANGLE_X64_CPU)
+#if defined(ANGLE_IS_64_BIT_CPU)
 template <size_t N>
 struct GetBitSet<N, EnableIfBitsFit<N, uint64_t>>
 {
     using Type = BitSet64<N>;
 };
 #else
 template <size_t N>
 struct GetBitSet<N, EnableIfBitsFit<N, uint32_t>>
 {
     using Type = BitSet32<N>;
 };
-#endif  // defined(ANGLE_X64_CPU)
+#endif  // defined(ANGLE_IS_64_BIT_CPU)
 
 }  // namespace priv
 
 template <size_t N>
 using BitSet = typename priv::GetBitSet<N>::Type;
 
 }  // angle
 
-template <size_t N, typename BitsT>
-inline angle::BitSetT<N, BitsT> operator&(const angle::BitSetT<N, BitsT> &lhs,
-                                          const angle::BitSetT<N, BitsT> &rhs)
+template <size_t N, typename BitsT, typename ParamT>
+inline angle::BitSetT<N, BitsT, ParamT> operator&(const angle::BitSetT<N, BitsT, ParamT> &lhs,
+                                                  const angle::BitSetT<N, BitsT, ParamT> &rhs)
 {
-    return angle::BitSetT<N, BitsT>(lhs.bits() & rhs.bits());
+    return angle::BitSetT<N, BitsT, ParamT>(lhs.bits() & rhs.bits());
 }
 
-template <size_t N, typename BitsT>
-inline angle::BitSetT<N, BitsT> operator|(const angle::BitSetT<N, BitsT> &lhs,
-                                          const angle::BitSetT<N, BitsT> &rhs)
+template <size_t N, typename BitsT, typename ParamT>
+inline angle::BitSetT<N, BitsT, ParamT> operator|(const angle::BitSetT<N, BitsT, ParamT> &lhs,
+                                                  const angle::BitSetT<N, BitsT, ParamT> &rhs)
 {
-    return angle::BitSetT<N, BitsT>(lhs.bits() | rhs.bits());
+    return angle::BitSetT<N, BitsT, ParamT>(lhs.bits() | rhs.bits());
 }
 
-template <size_t N, typename BitsT>
-inline angle::BitSetT<N, BitsT> operator^(const angle::BitSetT<N, BitsT> &lhs,
-                                          const angle::BitSetT<N, BitsT> &rhs)
+template <size_t N, typename BitsT, typename ParamT>
+inline angle::BitSetT<N, BitsT, ParamT> operator^(const angle::BitSetT<N, BitsT, ParamT> &lhs,
+                                                  const angle::BitSetT<N, BitsT, ParamT> &rhs)
 {
-    return angle::BitSetT<N, BitsT>(lhs.bits() ^ rhs.bits());
+    return angle::BitSetT<N, BitsT, ParamT>(lhs.bits() ^ rhs.bits());
 }
 
 #endif  // COMMON_BITSETITERATOR_H_
--- a/gfx/angle/src/common/gen_uniform_type_table.py
+++ b/gfx/angle/src/common/gen_uniform_type_table.py
@@ -67,25 +67,30 @@ all_uniform_types = [
     "GL_UNSIGNED_INT_SAMPLER_2D_MULTISAMPLE",
     "GL_UNSIGNED_INT_SAMPLER_3D",
     "GL_UNSIGNED_INT_SAMPLER_CUBE",
     "GL_UNSIGNED_INT_VEC2",
     "GL_UNSIGNED_INT_VEC3",
     "GL_UNSIGNED_INT_VEC4"
 ]
 
-# Uniform texture types.
+# Uniform texture types. Be wary of substrings finding the wrong types.
+# e.g. with 2D_MULTISAMPLE/2D_ARRAY and 2D.
 texture_types = {
     "2D": "2D",
-    "CUBE": "CUBE_MAP",
     "2D_ARRAY": "2D_ARRAY",
+    "2D_ARRAY_SHADOW": "2D_ARRAY",
+    "2D_MULTISAMPLE": "2D_MULTISAMPLE",
+    "2D_RECT_ANGLE": "2D",
+    "2D_SHADOW": "2D",
     "3D": "3D",
-    "MULTISAMPLE": "MULTISAMPLE",
+    "CUBE": "CUBE_MAP",
+    "CUBE_SHADOW": "CUBE_MAP",
+    "EXTERNAL_OES": "EXTERNAL_OES",
     "RECT": "RECTANGLE",
-    "EXTERNAL_OES": "EXTERNAL_OES"
 }
 
 template_cpp = """// GENERATED FILE - DO NOT EDIT.
 // Generated by {script_name}.
 //
 // Copyright {copyright_year} The ANGLE Project Authors. All rights reserved.
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
@@ -146,17 +151,17 @@ def get_component_type(uniform_type):
         return "GL_UNSIGNED_INT"
     elif uniform_type == "GL_NONE":
         return "GL_NONE"
     else:
         return "GL_INT"
 
 def get_texture_type(uniform_type):
     for sampler_type, tex_type in texture_types.items():
-        if sampler_type in uniform_type:
+        if uniform_type.endswith(sampler_type):
             return "GL_TEXTURE_" + tex_type
     return "GL_NONE"
 
 def get_transposed_type(uniform_type):
     if "_MAT" in uniform_type:
         if "x" in uniform_type:
             return "GL_FLOAT_MAT" + uniform_type[-1] + "x" + uniform_type[uniform_type.find("_MAT")+4]
         else:
--- a/gfx/angle/src/common/mathutil.h
+++ b/gfx/angle/src/common/mathutil.h
@@ -55,47 +55,62 @@ inline unsigned int ceilPow2(unsigned in
     x |= x >> 4;
     x |= x >> 8;
     x |= x >> 16;
     x++;
 
     return x;
 }
 
-inline int clampToInt(unsigned int x)
-{
-    return static_cast<int>(std::min(x, static_cast<unsigned int>(std::numeric_limits<int>::max())));
-}
-
 template <typename DestT, typename SrcT>
 inline DestT clampCast(SrcT value)
 {
-    static const DestT destLo = std::numeric_limits<DestT>::min();
-    static const DestT destHi = std::numeric_limits<DestT>::max();
-    static const SrcT srcLo = static_cast<SrcT>(destLo);
-    static const SrcT srcHi = static_cast<SrcT>(destHi);
+    // For floating-point types with denormalization, min returns the minimum positive normalized
+    // value. To find the value that has no values less than it, use numeric_limits::lowest.
+    constexpr const long double destLo =
+        static_cast<long double>(std::numeric_limits<DestT>::lowest());
+    constexpr const long double destHi =
+        static_cast<long double>(std::numeric_limits<DestT>::max());
+    constexpr const long double srcLo =
+        static_cast<long double>(std::numeric_limits<SrcT>::lowest());
+    constexpr long double srcHi = static_cast<long double>(std::numeric_limits<SrcT>::max());
+
+    if (destHi < srcHi)
+    {
+        DestT destMax = std::numeric_limits<DestT>::max();
+        if (value >= static_cast<SrcT>(destMax))
+        {
+            return destMax;
+        }
+    }
 
-    // When value is outside of or equal to the limits for DestT we use the DestT limit directly.
-    // This avoids undefined behaviors due to loss of precision when converting from floats to
-    // integers:
-    //    destHi for ints is 2147483647 but the closest float number is around 2147483648, so when
-    //  doing a conversion from float to int we run into an UB because the float is outside of the
-    //  range representable by the int.
-    if (value <= srcLo)
+    if (destLo > srcLo)
     {
-        return destLo;
+        DestT destLow = std::numeric_limits<DestT>::lowest();
+        if (value <= static_cast<SrcT>(destLow))
+        {
+            return destLow;
+        }
     }
-    else if (value >= srcHi)
-    {
-        return destHi;
-    }
-    else
-    {
-        return static_cast<DestT>(value);
-    }
+
+    return static_cast<DestT>(value);
+}
+
+// Specialize clampCast for bool->int conversion to avoid MSVS 2015 performance warning when the max
+// value is casted to the source type.
+template <>
+inline unsigned int clampCast(bool value)
+{
+    return static_cast<unsigned int>(value);
+}
+
+template <>
+inline int clampCast(bool value)
+{
+    return static_cast<int>(value);
 }
 
 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;
 }
@@ -608,16 +623,22 @@ class Range
 
     Iterator begin() const { return Iterator(mLow); }
 
     Iterator end() const { return Iterator(mHigh); }
 
     T low() const { return mLow; }
     T high() const { return mHigh; }
 
+    void invalidate()
+    {
+        mLow  = std::numeric_limits<T>::max();
+        mHigh = std::numeric_limits<T>::min();
+    }
+
   private:
     T mLow;
     T mHigh;
 };
 
 typedef Range<int> RangeI;
 typedef Range<unsigned int> RangeUI;
 
@@ -868,76 +889,76 @@ inline uint32_t BitfieldReverse(uint32_t
 }
 
 // Count the 1 bits.
 #if defined(ANGLE_PLATFORM_WINDOWS)
 inline int BitCount(uint32_t bits)
 {
     return static_cast<int>(__popcnt(bits));
 }
-#if defined(ANGLE_X64_CPU)
+#if defined(ANGLE_IS_64_BIT_CPU)
 inline int BitCount(uint64_t bits)
 {
     return static_cast<int>(__popcnt64(bits));
 }
-#endif  // defined(ANGLE_X64_CPU)
+#endif  // defined(ANGLE_IS_64_BIT_CPU)
 #endif  // defined(ANGLE_PLATFORM_WINDOWS)
 
 #if defined(ANGLE_PLATFORM_POSIX)
 inline int BitCount(uint32_t bits)
 {
     return __builtin_popcount(bits);
 }
 
-#if defined(ANGLE_X64_CPU)
+#if defined(ANGLE_IS_64_BIT_CPU)
 inline int BitCount(uint64_t bits)
 {
     return __builtin_popcountll(bits);
 }
-#endif  // defined(ANGLE_X64_CPU)
+#endif  // defined(ANGLE_IS_64_BIT_CPU)
 #endif  // defined(ANGLE_PLATFORM_POSIX)
 
 #if defined(ANGLE_PLATFORM_WINDOWS)
 // Return the index of the least significant bit set. Indexing is such that bit 0 is the least
 // significant bit. Implemented for different bit widths on different platforms.
 inline unsigned long ScanForward(uint32_t bits)
 {
     ASSERT(bits != 0u);
     unsigned long firstBitIndex = 0ul;
     unsigned char ret           = _BitScanForward(&firstBitIndex, bits);
     ASSERT(ret != 0u);
     return firstBitIndex;
 }
 
-#if defined(ANGLE_X64_CPU)
+#if defined(ANGLE_IS_64_BIT_CPU)
 inline unsigned long ScanForward(uint64_t bits)
 {
     ASSERT(bits != 0u);
     unsigned long firstBitIndex = 0ul;
     unsigned char ret           = _BitScanForward64(&firstBitIndex, bits);
     ASSERT(ret != 0u);
     return firstBitIndex;
 }
-#endif  // defined(ANGLE_X64_CPU)
+#endif  // defined(ANGLE_IS_64_BIT_CPU)
 #endif  // defined(ANGLE_PLATFORM_WINDOWS)
 
 #if defined(ANGLE_PLATFORM_POSIX)
 inline unsigned long ScanForward(uint32_t bits)
 {
     ASSERT(bits != 0u);
     return static_cast<unsigned long>(__builtin_ctz(bits));
 }
 
-#if defined(ANGLE_X64_CPU)
+#if defined(ANGLE_IS_64_BIT_CPU)
 inline unsigned long ScanForward(uint64_t bits)
 {
     ASSERT(bits != 0u);
     return static_cast<unsigned long>(__builtin_ctzll(bits));
 }
-#endif  // defined(ANGLE_X64_CPU)
+#endif  // defined(ANGLE_IS_64_BIT_CPU)
 #endif  // defined(ANGLE_PLATFORM_POSIX)
 
 // Return the index of the most significant bit set. Indexing is such that bit 0 is the least
 // significant bit.
 inline unsigned long ScanReverse(unsigned long bits)
 {
     ASSERT(bits != 0u);
 #if defined(ANGLE_PLATFORM_WINDOWS)
--- a/gfx/angle/src/common/mathutil_unittest.cpp
+++ b/gfx/angle/src/common/mathutil_unittest.cpp
@@ -270,35 +270,35 @@ TEST(MathUtilTest, BitfieldReverse)
 
 // Test BitCount, which counts 1 bits in an integer.
 TEST(MathUtilTest, BitCount)
 {
     EXPECT_EQ(0, gl::BitCount(0u));
     EXPECT_EQ(32, gl::BitCount(0xFFFFFFFFu));
     EXPECT_EQ(10, gl::BitCount(0x17103121u));
 
-#if defined(ANGLE_X64_CPU)
+#if defined(ANGLE_IS_64_BIT_CPU)
     EXPECT_EQ(0, gl::BitCount(0ull));
     EXPECT_EQ(32, gl::BitCount(0xFFFFFFFFull));
     EXPECT_EQ(10, gl::BitCount(0x17103121ull));
-#endif  // defined(ANGLE_X64_CPU)
+#endif  // defined(ANGLE_IS_64_BIT_CPU)
 }
 
 // Test ScanForward, which scans for the least significant 1 bit from a non-zero integer.
 TEST(MathUtilTest, ScanForward)
 {
     EXPECT_EQ(0ul, gl::ScanForward(1u));
     EXPECT_EQ(16ul, gl::ScanForward(0x80010000u));
     EXPECT_EQ(31ul, gl::ScanForward(0x80000000u));
 
-#if defined(ANGLE_X64_CPU)
+#if defined(ANGLE_IS_64_BIT_CPU)
     EXPECT_EQ(0ul, gl::ScanForward(1ull));
     EXPECT_EQ(16ul, gl::ScanForward(0x80010000ull));
     EXPECT_EQ(31ul, gl::ScanForward(0x80000000ull));
-#endif  // defined(ANGLE_X64_CPU)
+#endif  // defined(ANGLE_IS_64_BIT_CPU)
 }
 
 // Test ScanReverse, which scans for the most significant 1 bit from a non-zero integer.
 TEST(MathUtilTest, ScanReverse)
 {
     EXPECT_EQ(0ul, gl::ScanReverse(1ul));
     EXPECT_EQ(16ul, gl::ScanReverse(0x00010030ul));
     EXPECT_EQ(31ul, gl::ScanReverse(0x80000000ul));
--- a/gfx/angle/src/common/platform.h
+++ b/gfx/angle/src/common/platform.h
@@ -53,17 +53,18 @@
 #       define ANGLE_ENABLE_WINDOWS_STORE 1
 #   endif
 
 #   if defined(ANGLE_ENABLE_D3D9)
 #       include <d3d9.h>
 #       include <d3dcompiler.h>
 #   endif
 
-#   if defined(ANGLE_ENABLE_D3D11)
+// Include D3D11 headers when OpenGL is enabled on Windows for interop extensions.
+#if defined(ANGLE_ENABLE_D3D11) || defined(ANGLE_ENABLE_OPENGL)
 #include <d3d10_1.h>
 #include <d3d11.h>
 #include <d3d11_3.h>
 #include <d3dcompiler.h>
 #include <dxgi.h>
 #include <dxgi1_2.h>
 #   endif
 
@@ -86,13 +87,18 @@
 #if defined(_MSC_VER) && !defined(_M_ARM)
 #include <intrin.h>
 #define ANGLE_USE_SSE
 #elif defined(__GNUC__) && (defined(__x86_64__) || defined(__i386__))
 #include <x86intrin.h>
 #define ANGLE_USE_SSE
 #endif
 
+// Mips and arm devices need to include stddef for size_t.
+#if defined(__mips__) || defined(__arm__) || defined(__aarch64__)
+#include <stddef.h>
+#endif
+
 // The MemoryBarrier function name collides with a macro under Windows
 // We will undef the macro so that the function name does not get replaced
 #undef MemoryBarrier
 
 #endif // COMMON_PLATFORM_H_
--- a/gfx/angle/src/common/string_utils.cpp
+++ b/gfx/angle/src/common/string_utils.cpp
@@ -153,26 +153,36 @@ Optional<std::vector<wchar_t>> WidenStri
     if (err != 0)
     {
         return Optional<std::vector<wchar_t>>::Invalid();
     }
 #endif
     return Optional<std::vector<wchar_t>>(wcstring);
 }
 
+bool BeginsWith(const std::string &str, const std::string &prefix)
+{
+    return strncmp(str.c_str(), prefix.c_str(), prefix.length()) == 0;
+}
+
 bool BeginsWith(const std::string &str, const char *prefix)
 {
     return strncmp(str.c_str(), prefix, strlen(prefix)) == 0;
 }
 
 bool BeginsWith(const char *str, const char *prefix)
 {
     return strncmp(str, prefix, strlen(prefix)) == 0;
 }
 
+bool BeginsWith(const std::string &str, const std::string &prefix, const size_t prefixLength)
+{
+    return strncmp(str.c_str(), prefix.c_str(), prefixLength) == 0;
+}
+
 bool EndsWith(const std::string &str, const char *suffix)
 {
     const auto len = strlen(suffix);
     if (len > str.size())
         return false;
 
     const char *end = str.c_str() + str.size() - len;
 
@@ -182,9 +192,22 @@ bool EndsWith(const std::string &str, co
 void ToLower(std::string *str)
 {
     for (auto &ch : *str)
     {
         ch = static_cast<char>(::tolower(ch));
     }
 }
 
+bool ReplaceSubstring(std::string *str,
+                      const std::string &substring,
+                      const std::string &replacement)
+{
+    size_t replacePos = str->find(substring);
+    if (replacePos == std::string::npos)
+    {
+        return false;
+    }
+    str->replace(replacePos, substring.size(), replacement);
+    return true;
+}
+
 }  // namespace angle
--- a/gfx/angle/src/common/string_utils.h
+++ b/gfx/angle/src/common/string_utils.h
@@ -44,27 +44,42 @@ std::string TrimString(const std::string
 
 bool HexStringToUInt(const std::string &input, unsigned int *uintOut);
 
 bool ReadFileToString(const std::string &path, std::string *stringOut);
 
 Optional<std::vector<wchar_t>> WidenString(size_t length, const char *cString);
 
 // Check if the string str begins with the given prefix.
+// The comparison is case sensitive.
+bool BeginsWith(const std::string &str, const std::string &prefix);
+
+// Check if the string str begins with the given prefix.
 // Prefix may not be NULL and needs to be NULL terminated.
 // The comparison is case sensitive.
 bool BeginsWith(const std::string &str, const char *prefix);
 
 // Check if the string str begins with the given prefix.
 // str and prefix may not be NULL and need to be NULL terminated.
 // The comparison is case sensitive.
 bool BeginsWith(const char *str, const char *prefix);
 
+// Check if the string str begins with the first prefixLength characters of the given prefix.
+// The length of the prefix string should be greater than or equal to prefixLength.
+// The comparison is case sensitive.
+bool BeginsWith(const std::string &str, const std::string &prefix, const size_t prefixLength);
+
 // Check if the string str ends with the given suffix.
 // Suffix may not be NUL and needs to be NULL terminated.
 // The comparison is case sensitive.
 bool EndsWith(const std::string& str, const char* suffix);
 
 // Convert to lower-case.
 void ToLower(std::string *str);
-}
+
+// Replaces the substring 'substring' in 'str' with 'replacement'. Returns true if successful.
+bool ReplaceSubstring(std::string *str,
+                      const std::string &substring,
+                      const std::string &replacement);
+
+}  // namespace angle
 
 #endif // LIBANGLE_STRING_UTILS_H_
--- a/gfx/angle/src/common/string_utils_unittest.cpp
+++ b/gfx/angle/src/common/string_utils_unittest.cpp
@@ -133,31 +133,86 @@ TEST(StringUtilsTest, HexStringToUIntBas
     EXPECT_EQ(0xBADF00Du, uintValue);
 
     std::string testStringD("0x BADF00D");
     EXPECT_FALSE(HexStringToUInt(testStringD, &uintValue));
 }
 
 // Note: ReadFileToString is harder to test
 
-
-TEST(StringUtilsTest, BeginsEndsWith)
+class BeginsWithTest : public testing::Test
 {
-    ASSERT_FALSE(BeginsWith("foo", "bar"));
-    ASSERT_FALSE(BeginsWith("", "foo"));
-    ASSERT_FALSE(BeginsWith("foo", "foobar"));
+  public:
+    BeginsWithTest() : mMode(TestMode::CHAR_ARRAY) {}
+
+    enum class TestMode
+    {
+        CHAR_ARRAY,
+        STRING_AND_CHAR_ARRAY,
+        STRING
+    };
+
+    void setMode(TestMode mode) { mMode = mode; }
+
+    bool runBeginsWith(const char *str, const char *prefix)
+    {
+        if (mMode == TestMode::CHAR_ARRAY)
+        {
+            return BeginsWith(str, prefix);
+        }
+        if (mMode == TestMode::STRING_AND_CHAR_ARRAY)
+        {
+            return BeginsWith(std::string(str), prefix);
+        }
+        return BeginsWith(std::string(str), std::string(prefix));
+    }
+
+    void runTest()
+    {
+        ASSERT_FALSE(runBeginsWith("foo", "bar"));
+        ASSERT_FALSE(runBeginsWith("", "foo"));
+        ASSERT_FALSE(runBeginsWith("foo", "foobar"));
 
-    ASSERT_TRUE(BeginsWith("foobar", "foo"));
-    ASSERT_TRUE(BeginsWith("foobar", ""));
-    ASSERT_TRUE(BeginsWith("foo", "foo"));
-    ASSERT_TRUE(BeginsWith("", ""));
+        ASSERT_TRUE(runBeginsWith("foobar", "foo"));
+        ASSERT_TRUE(runBeginsWith("foobar", ""));
+        ASSERT_TRUE(runBeginsWith("foo", "foo"));
+        ASSERT_TRUE(runBeginsWith("", ""));
+    }
+
+  private:
+    TestMode mMode;
+};
+
+// Test that BeginsWith works correctly for const char * arguments.
+TEST_F(BeginsWithTest, CharArrays)
+{
+    setMode(TestMode::CHAR_ARRAY);
+    runTest();
+}
 
+// Test that BeginsWith works correctly for std::string and const char * arguments.
+TEST_F(BeginsWithTest, StringAndCharArray)
+{
+    setMode(TestMode::STRING_AND_CHAR_ARRAY);
+    runTest();
+}
+
+// Test that BeginsWith works correctly for std::string arguments.
+TEST_F(BeginsWithTest, Strings)
+{
+    setMode(TestMode::STRING);
+    runTest();
+}
+
+// Test that EndsWith works correctly.
+TEST(EndsWithTest, EndsWith)
+{
     ASSERT_FALSE(EndsWith("foo", "bar"));
     ASSERT_FALSE(EndsWith("", "bar"));
     ASSERT_FALSE(EndsWith("foo", "foobar"));
 
     ASSERT_TRUE(EndsWith("foobar", "bar"));
     ASSERT_TRUE(EndsWith("foobar", ""));
     ASSERT_TRUE(EndsWith("bar", "bar"));
     ASSERT_TRUE(EndsWith("", ""));
 }
 
-}
\ No newline at end of file
+}  // anonymous namespace
deleted file mode 100644
--- a/gfx/angle/src/common/third_party/murmurhash/LICENSE
+++ /dev/null
@@ -1,2 +0,0 @@
-// MurmurHash3 was written by Austin Appleby, and is placed in the public
-// domain. The author hereby disclaims copyright to this source code.
\ No newline at end of file
deleted file mode 100644
--- a/gfx/angle/src/common/third_party/murmurhash/MurmurHash3.cpp
+++ /dev/null
@@ -1,338 +0,0 @@
-//-----------------------------------------------------------------------------
-// MurmurHash3 was written by Austin Appleby, and is placed in the public
-// domain. The author hereby disclaims copyright to this source code.
-
-// Note - The x86 and x64 versions do _not_ produce the same results, as the
-// algorithms are optimized for their respective platforms. You can still
-// compile and run any of them on any platform, but your performance with the
-// non-native version will be less than optimal.
-
-#include "MurmurHash3.h"
-
-//-----------------------------------------------------------------------------
-// Platform-specific functions and macros
-
-// Microsoft Visual Studio
-
-#if defined(_MSC_VER)
-
-#define FORCE_INLINE	__forceinline
-
-#include <stdlib.h>
-
-#define ROTL32(x,y)	_rotl(x,y)
-#define ROTL64(x,y)	_rotl64(x,y)
-
-#define BIG_CONSTANT(x) (x)
-
-// Other compilers
-
-#else	// defined(_MSC_VER)
-
-#define	FORCE_INLINE inline __attribute__((always_inline))
-
-inline uint32_t rotl32 ( uint32_t x, int8_t r )
-{
-  return (x << r) | (x >> (32 - r));
-}
-
-inline uint64_t rotl64 ( uint64_t x, int8_t r )
-{
-  return (x << r) | (x >> (64 - r));
-}
-
-#define	ROTL32(x,y)	rotl32(x,y)
-#define ROTL64(x,y)	rotl64(x,y)
-
-#define BIG_CONSTANT(x) (x##LLU)
-
-#endif // !defined(_MSC_VER)
-
-//-----------------------------------------------------------------------------
-// Block read - if your platform needs to do endian-swapping or can only
-// handle aligned reads, do the conversion here
-
-FORCE_INLINE uint32_t getblock32 ( const uint32_t * p, int i )
-{
-  return p[i];
-}
-
-FORCE_INLINE uint64_t getblock64 ( const uint64_t * p, int i )
-{
-  return p[i];
-}
-
-//-----------------------------------------------------------------------------
-// Finalization mix - force all bits of a hash block to avalanche
-
-FORCE_INLINE uint32_t fmix32 ( uint32_t h )
-{
-  h ^= h >> 16;
-  h *= 0x85ebca6b;
-  h ^= h >> 13;
-  h *= 0xc2b2ae35;
-  h ^= h >> 16;
-
-  return h;
-}
-
-//----------
-
-FORCE_INLINE uint64_t fmix64 ( uint64_t k )
-{
-  k ^= k >> 33;
-  k *= BIG_CONSTANT(0xff51afd7ed558ccd);
-  k ^= k >> 33;
-  k *= BIG_CONSTANT(0xc4ceb9fe1a85ec53);
-  k ^= k >> 33;
-
-  return k;
-}
-
-//-----------------------------------------------------------------------------
-
-namespace angle
-{
-void MurmurHash3_x86_32 ( const void * key, int len,
-                          uint32_t seed, void * out )
-{
-  const uint8_t * data = (const uint8_t*)key;
-  const int nblocks = len / 4;
-
-  uint32_t h1 = seed;
-
-  const uint32_t c1 = 0xcc9e2d51;
-  const uint32_t c2 = 0x1b873593;
-
-  //----------
-  // body
-
-  const uint32_t * blocks = (const uint32_t *)(data + nblocks*4);
-
-  for(int i = -nblocks; i; i++)
-  {
-    uint32_t k1 = getblock32(blocks,i);
-
-    k1 *= c1;
-    k1 = ROTL32(k1,15);
-    k1 *= c2;
-    
-    h1 ^= k1;
-    h1 = ROTL32(h1,13); 
-    h1 = h1*5+0xe6546b64;
-  }
-
-  //----------
-  // tail
-
-  const uint8_t * tail = (const uint8_t*)(data + nblocks*4);
-
-  uint32_t k1 = 0;
-
-  switch(len & 3)
-  {
-  case 3: k1 ^= tail[2] << 16;
-  case 2: k1 ^= tail[1] << 8;
-  case 1: k1 ^= tail[0];
-          k1 *= c1; k1 = ROTL32(k1,15); k1 *= c2; h1 ^= k1;
-  };
-
-  //----------
-  // finalization
-
-  h1 ^= len;
-
-  h1 = fmix32(h1);
-
-  *(uint32_t*)out = h1;
-} 
-
-//-----------------------------------------------------------------------------
-
-void MurmurHash3_x86_128 ( const void * key, const int len,
-                           uint32_t seed, void * out )
-{
-  const uint8_t * data = (const uint8_t*)key;
-  const int nblocks = len / 16;
-
-  uint32_t h1 = seed;
-  uint32_t h2 = seed;
-  uint32_t h3 = seed;
-  uint32_t h4 = seed;
-
-  const uint32_t c1 = 0x239b961b; 
-  const uint32_t c2 = 0xab0e9789;
-  const uint32_t c3 = 0x38b34ae5; 
-  const uint32_t c4 = 0xa1e38b93;
-
-  //----------
-  // body
-
-  const uint32_t * blocks = (const uint32_t *)(data + nblocks*16);
-
-  for(int i = -nblocks; i; i++)
-  {
-    uint32_t k1 = getblock32(blocks,i*4+0);
-    uint32_t k2 = getblock32(blocks,i*4+1);
-    uint32_t k3 = getblock32(blocks,i*4+2);
-    uint32_t k4 = getblock32(blocks,i*4+3);
-
-    k1 *= c1; k1  = ROTL32(k1,15); k1 *= c2; h1 ^= k1;
-
-    h1 = ROTL32(h1,19); h1 += h2; h1 = h1*5+0x561ccd1b;
-
-    k2 *= c2; k2  = ROTL32(k2,16); k2 *= c3; h2 ^= k2;
-
-    h2 = ROTL32(h2,17); h2 += h3; h2 = h2*5+0x0bcaa747;
-
-    k3 *= c3; k3  = ROTL32(k3,17); k3 *= c4; h3 ^= k3;
-
-    h3 = ROTL32(h3,15); h3 += h4; h3 = h3*5+0x96cd1c35;
-
-    k4 *= c4; k4  = ROTL32(k4,18); k4 *= c1; h4 ^= k4;
-
-    h4 = ROTL32(h4,13); h4 += h1; h4 = h4*5+0x32ac3b17;
-  }
-
-  //----------
-  // tail
-
-  const uint8_t * tail = (const uint8_t*)(data + nblocks*16);
-
-  uint32_t k1 = 0;
-  uint32_t k2 = 0;
-  uint32_t k3 = 0;
-  uint32_t k4 = 0;
-
-  switch(len & 15)
-  {
-  case 15: k4 ^= tail[14] << 16;
-  case 14: k4 ^= tail[13] << 8;
-  case 13: k4 ^= tail[12] << 0;
-           k4 *= c4; k4  = ROTL32(k4,18); k4 *= c1; h4 ^= k4;
-
-  case 12: k3 ^= tail[11] << 24;
-  case 11: k3 ^= tail[10] << 16;
-  case 10: k3 ^= tail[ 9] << 8;
-  case  9: k3 ^= tail[ 8] << 0;
-           k3 *= c3; k3  = ROTL32(k3,17); k3 *= c4; h3 ^= k3;
-
-  case  8: k2 ^= tail[ 7] << 24;
-  case  7: k2 ^= tail[ 6] << 16;
-  case  6: k2 ^= tail[ 5] << 8;
-  case  5: k2 ^= tail[ 4] << 0;
-           k2 *= c2; k2  = ROTL32(k2,16); k2 *= c3; h2 ^= k2;
-
-  case  4: k1 ^= tail[ 3] << 24;
-  case  3: k1 ^= tail[ 2] << 16;
-  case  2: k1 ^= tail[ 1] << 8;
-  case  1: k1 ^= tail[ 0] << 0;
-           k1 *= c1; k1  = ROTL32(k1,15); k1 *= c2; h1 ^= k1;
-  };
-
-  //----------
-  // finalization
-
-  h1 ^= len; h2 ^= len; h3 ^= len; h4 ^= len;
-
-  h1 += h2; h1 += h3; h1 += h4;
-  h2 += h1; h3 += h1; h4 += h1;
-
-  h1 = fmix32(h1);
-  h2 = fmix32(h2);
-  h3 = fmix32(h3);
-  h4 = fmix32(h4);
-
-  h1 += h2; h1 += h3; h1 += h4;
-  h2 += h1; h3 += h1; h4 += h1;
-
-  ((uint32_t*)out)[0] = h1;
-  ((uint32_t*)out)[1] = h2;
-  ((uint32_t*)out)[2] = h3;
-  ((uint32_t*)out)[3] = h4;
-}
-
-//-----------------------------------------------------------------------------
-
-void MurmurHash3_x64_128 ( const void * key, const int len,
-                           const uint32_t seed, void * out )
-{
-  const uint8_t * data = (const uint8_t*)key;
-  const int nblocks = len / 16;
-
-  uint64_t h1 = seed;
-  uint64_t h2 = seed;
-
-  const uint64_t c1 = BIG_CONSTANT(0x87c37b91114253d5);
-  const uint64_t c2 = BIG_CONSTANT(0x4cf5ad432745937f);
-
-  //----------
-  // body
-
-  const uint64_t * blocks = (const uint64_t *)(data);
-
-  for(int i = 0; i < nblocks; i++)
-  {
-    uint64_t k1 = getblock64(blocks,i*2+0);
-    uint64_t k2 = getblock64(blocks,i*2+1);
-
-    k1 *= c1; k1  = ROTL64(k1,31); k1 *= c2; h1 ^= k1;
-
-    h1 = ROTL64(h1,27); h1 += h2; h1 = h1*5+0x52dce729;
-
-    k2 *= c2; k2  = ROTL64(k2,33); k2 *= c1; h2 ^= k2;
-
-    h2 = ROTL64(h2,31); h2 += h1; h2 = h2*5+0x38495ab5;
-  }
-
-  //----------
-  // tail
-
-  const uint8_t * tail = (const uint8_t*)(data + nblocks*16);
-
-  uint64_t k1 = 0;
-  uint64_t k2 = 0;
-
-  switch(len & 15)
-  {
-  case 15: k2 ^= ((uint64_t)tail[14]) << 48;
-  case 14: k2 ^= ((uint64_t)tail[13]) << 40;
-  case 13: k2 ^= ((uint64_t)tail[12]) << 32;
-  case 12: k2 ^= ((uint64_t)tail[11]) << 24;
-  case 11: k2 ^= ((uint64_t)tail[10]) << 16;
-  case 10: k2 ^= ((uint64_t)tail[ 9]) << 8;
-  case  9: k2 ^= ((uint64_t)tail[ 8]) << 0;
-           k2 *= c2; k2  = ROTL64(k2,33); k2 *= c1; h2 ^= k2;
-
-  case  8: k1 ^= ((uint64_t)tail[ 7]) << 56;
-  case  7: k1 ^= ((uint64_t)tail[ 6]) << 48;
-  case  6: k1 ^= ((uint64_t)tail[ 5]) << 40;
-  case  5: k1 ^= ((uint64_t)tail[ 4]) << 32;
-  case  4: k1 ^= ((uint64_t)tail[ 3]) << 24;
-  case  3: k1 ^= ((uint64_t)tail[ 2]) << 16;
-  case  2: k1 ^= ((uint64_t)tail[ 1]) << 8;
-  case  1: k1 ^= ((uint64_t)tail[ 0]) << 0;
-           k1 *= c1; k1  = ROTL64(k1,31); k1 *= c2; h1 ^= k1;
-  };
-
-  //----------
-  // finalization
-
-  h1 ^= len; h2 ^= len;
-
-  h1 += h2;
-  h2 += h1;
-
-  h1 = fmix64(h1);
-  h2 = fmix64(h2);
-
-  h1 += h2;
-  h2 += h1;
-
-  ((uint64_t*)out)[0] = h1;
-  ((uint64_t*)out)[1] = h2;
-}
-}
-
-//-----------------------------------------------------------------------------
-
deleted file mode 100644
--- a/gfx/angle/src/common/third_party/murmurhash/MurmurHash3.h
+++ /dev/null
@@ -1,40 +0,0 @@
-//-----------------------------------------------------------------------------
-// MurmurHash3 was written by Austin Appleby, and is placed in the public
-// domain. The author hereby disclaims copyright to this source code.
-
-#ifndef _MURMURHASH3_H_
-#define _MURMURHASH3_H_
-
-//-----------------------------------------------------------------------------
-// Platform-specific functions and macros
-
-// Microsoft Visual Studio
-
-#if defined(_MSC_VER) && (_MSC_VER < 1600)
-
-typedef unsigned char uint8_t;
-typedef unsigned int uint32_t;
-typedef unsigned __int64 uint64_t;
-
-// Other compilers
-
-#else	// defined(_MSC_VER)
-
-#include <stdint.h>
-
-#endif // !defined(_MSC_VER)
-
-//-----------------------------------------------------------------------------
-
-namespace angle
-{
-void MurmurHash3_x86_32  ( const void * key, int len, uint32_t seed, void * out );
-
-void MurmurHash3_x86_128 ( const void * key, int len, uint32_t seed, void * out );
-
-void MurmurHash3_x64_128 ( const void * key, int len, uint32_t seed, void * out );
-}
-
-//-----------------------------------------------------------------------------
-
-#endif // _MURMURHASH3_H_
new file mode 100644
--- /dev/null
+++ b/gfx/angle/src/common/third_party/smhasher/LICENSE
@@ -0,0 +1,23 @@
+All MurmurHash source files are placed in the public domain.
+
+The license below applies to all other code in SMHasher:
+
+Copyright (c) 2011 Google, Inc.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
new file mode 100644
--- /dev/null
+++ b/gfx/angle/src/common/third_party/smhasher/README.angle
@@ -0,0 +1,14 @@
+Name: SMHasher
+URL: http://code.google.com/p/smhasher/
+Version: 0
+Revision: 147
+License: MIT, Public Domain
+License File: LICENSE
+Security Critical: yes
+
+Description:
+This is a library containing the MurmurHash3 function, and a hashing function
+test suite.
+
+Licenses are MIT (SMHasher) and Public Domain (MurmurHash).
+
new file mode 100644
--- /dev/null
+++ b/gfx/angle/src/common/third_party/smhasher/src/PMurHash.cpp
@@ -0,0 +1,320 @@
+/*-----------------------------------------------------------------------------
+ * MurmurHash3 was written by Austin Appleby, and is placed in the public
+ * domain.
+ *
+ * This implementation was written by Shane Day, and is also public domain.
+ *
+ * This is a portable ANSI C implementation of MurmurHash3_x86_32 (Murmur3A)
+ * with support for progressive processing.
+ */
+
+/*-----------------------------------------------------------------------------
+ 
+If you want to understand the MurmurHash algorithm you would be much better
+off reading the original source. Just point your browser at:
+http://code.google.com/p/smhasher/source/browse/trunk/MurmurHash3.cpp
+
+
+What this version provides?
+
+1. Progressive data feeding. Useful when the entire payload to be hashed
+does not fit in memory or when the data is streamed through the application.
+Also useful when hashing a number of strings with a common prefix. A partial
+hash of a prefix string can be generated and reused for each suffix string.
+
+2. Portability. Plain old C so that it should compile on any old compiler.
+Both CPU endian and access-alignment neutral, but avoiding inefficient code
+when possible depending on CPU capabilities.
+
+3. Drop in. I personally like nice self contained public domain code, making it
+easy to pilfer without loads of refactoring to work properly in the existing
+application code & makefile structure and mucking around with licence files.
+Just copy PMurHash.h and PMurHash.c and you're ready to go.
+
+
+How does it work?
+
+We can only process entire 32 bit chunks of input, except for the very end
+that may be shorter. So along with the partial hash we need to give back to
+the caller a carry containing up to 3 bytes that we were unable to process.
+This carry also needs to record the number of bytes the carry holds. I use
+the low 2 bits as a count (0..3) and the carry bytes are shifted into the
+high byte in stream order.
+
+To handle endianess I simply use a macro that reads a uint32_t and define
+that macro to be a direct read on little endian machines, a read and swap
+on big endian machines, or a byte-by-byte read if the endianess is unknown.
+
+-----------------------------------------------------------------------------*/
+
+
+#include "PMurHash.h"
+
+/* I used ugly type names in the header to avoid potential conflicts with
+ * application or system typedefs & defines. Since I'm not including any more
+ * headers below here I can rename these so that the code reads like C99 */
+#undef uint32_t
+#define uint32_t MH_UINT32
+#undef uint8_t
+#define uint8_t  MH_UINT8
+
+/* MSVC warnings we choose to ignore */
+#if defined(_MSC_VER)
+  #pragma warning(disable: 4127) /* conditional expression is constant */
+#endif
+
+/*-----------------------------------------------------------------------------
+ * Endianess, misalignment capabilities and util macros
+ *
+ * The following 3 macros are defined in this section. The other macros defined
+ * are only needed to help derive these 3.
+ *
+ * READ_UINT32(x)   Read a little endian unsigned 32-bit int
+ * UNALIGNED_SAFE   Defined if READ_UINT32 works on non-word boundaries
+ * ROTL32(x,r)      Rotate x left by r bits
+ */
+
+/* Convention is to define __BYTE_ORDER == to one of these values */
+#if !defined(__BIG_ENDIAN)
+  #define __BIG_ENDIAN 4321
+#endif
+#if !defined(__LITTLE_ENDIAN)
+  #define __LITTLE_ENDIAN 1234
+#endif
+
+/* I386 */
+#if defined(_M_IX86) || defined(__i386__) || defined(__i386) || defined(i386)
+  #define __BYTE_ORDER __LITTLE_ENDIAN
+  #define UNALIGNED_SAFE
+#endif
+
+/* gcc 'may' define __LITTLE_ENDIAN__ or __BIG_ENDIAN__ to 1 (Note the trailing __),
+ * or even _LITTLE_ENDIAN or _BIG_ENDIAN (Note the single _ prefix) */
+#if !defined(__BYTE_ORDER)
+  #if defined(__LITTLE_ENDIAN__) && __LITTLE_ENDIAN__==1 || defined(_LITTLE_ENDIAN) && _LITTLE_ENDIAN==1
+    #define __BYTE_ORDER __LITTLE_ENDIAN
+  #elif defined(__BIG_ENDIAN__) && __BIG_ENDIAN__==1 || defined(_BIG_ENDIAN) && _BIG_ENDIAN==1
+    #define __BYTE_ORDER __BIG_ENDIAN
+  #endif
+#endif
+
+/* gcc (usually) defines xEL/EB macros for ARM and MIPS endianess */
+#if !defined(__BYTE_ORDER)
+  #if defined(__ARMEL__) || defined(__MIPSEL__)
+    #define __BYTE_ORDER __LITTLE_ENDIAN
+  #endif
+  #if defined(__ARMEB__) || defined(__MIPSEB__)
+    #define __BYTE_ORDER __BIG_ENDIAN
+  #endif
+#endif
+
+/* Now find best way we can to READ_UINT32 */
+#if __BYTE_ORDER==__LITTLE_ENDIAN
+  /* CPU endian matches murmurhash algorithm, so read 32-bit word directly */
+  #define READ_UINT32(ptr)   (*((uint32_t*)(ptr)))
+#elif __BYTE_ORDER==__BIG_ENDIAN
+  /* TODO: Add additional cases below where a compiler provided bswap32 is available */
+  #if defined(__GNUC__) && (__GNUC__>4 || (__GNUC__==4 && __GNUC_MINOR__>=3))
+    #define READ_UINT32(ptr)   (__builtin_bswap32(*((uint32_t*)(ptr))))
+  #else
+    /* Without a known fast bswap32 we're just as well off doing this */
+    #define READ_UINT32(ptr)   (ptr[0]|ptr[1]<<8|ptr[2]<<16|ptr[3]<<24)
+    #define UNALIGNED_SAFE
+  #endif
+#else
+  /* Unknown endianess so last resort is to read individual bytes */
+  #define READ_UINT32(ptr)   (ptr[0]|ptr[1]<<8|ptr[2]<<16|ptr[3]<<24)
+
+  /* Since we're not doing word-reads we can skip the messing about with realignment */
+  #define UNALIGNED_SAFE
+#endif
+
+/* Find best way to ROTL32 */
+#if defined(_MSC_VER)
+  #include <stdlib.h>  /* Microsoft put _rotl declaration in here */
+  #define ROTL32(x,r)  _rotl(x,r)
+#else
+  /* gcc recognises this code and generates a rotate instruction for CPUs with one */
+  #define ROTL32(x,r)  (((uint32_t)x << r) | ((uint32_t)x >> (32 - r)))
+#endif
+
+
+/*-----------------------------------------------------------------------------
+ * Core murmurhash algorithm macros */
+
+#define C1  (0xcc9e2d51)
+#define C2  (0x1b873593)
+
+/* This is the main processing body of the algorithm. It operates
+ * on each full 32-bits of input. */
+#define DOBLOCK(h1, k1) do{ \
+        k1 *= C1; \
+        k1 = ROTL32(k1,15); \
+        k1 *= C2; \
+        \
+        h1 ^= k1; \
+        h1 = ROTL32(h1,13); \
+        h1 = h1*5+0xe6546b64; \
+    }while(0)
+
+
+/* Append unaligned bytes to carry, forcing hash churn if we have 4 bytes */
+/* cnt=bytes to process, h1=name of h1 var, c=carry, n=bytes in c, ptr/len=payload */
+#define DOBYTES(cnt, h1, c, n, ptr, len) do{ \
+    int _i = cnt; \
+    while(_i--) { \
+        c = c>>8 | *ptr++<<24; \
+        n++; len--; \
+        if(n==4) { \
+            DOBLOCK(h1, c); \
+            n = 0; \
+        } \
+    } }while(0)
+
+/*---------------------------------------------------------------------------*/
+
+namespace angle
+{
+/* Main hashing function. Initialise carry to 0 and h1 to 0 or an initial seed
+ * if wanted. Both ph1 and pcarry are required arguments. */
+void PMurHash32_Process(uint32_t *ph1, uint32_t *pcarry, const void *key, int len)
+{
+  uint32_t h1 = *ph1;
+  uint32_t c = *pcarry;
+
+  const uint8_t *ptr = (uint8_t*)key;
+  const uint8_t *end;
+
+  /* Extract carry count from low 2 bits of c value */
+  int n = c & 3;
+
+#if defined(UNALIGNED_SAFE)
+  /* This CPU handles unaligned word access */
+
+  /* Consume any carry bytes */
+  int i = (4-n) & 3;
+  if(i && i <= len) {
+    DOBYTES(i, h1, c, n, ptr, len);
+  }
+
+  /* Process 32-bit chunks */
+  end = ptr + len/4*4;
+  for( ; ptr < end ; ptr+=4) {
+    uint32_t k1 = READ_UINT32(ptr);
+    DOBLOCK(h1, k1);
+  }
+
+#else /*UNALIGNED_SAFE*/
+  /* This CPU does not handle unaligned word access */
+
+  /* Consume enough so that the next data byte is word aligned */
+  int i = -(long)ptr & 3;
+  if(i && i <= len) {
+      DOBYTES(i, h1, c, n, ptr, len);
+  }
+
+  /* We're now aligned. Process in aligned blocks. Specialise for each possible carry count */
+  end = ptr + len/4*4;
+  switch(n) { /* how many bytes in c */
+  case 0: /* c=[----]  w=[3210]  b=[3210]=w            c'=[----] */
+    for( ; ptr < end ; ptr+=4) {
+      uint32_t k1 = READ_UINT32(ptr);
+      DOBLOCK(h1, k1);
+    }
+    break;
+  case 1: /* c=[0---]  w=[4321]  b=[3210]=c>>24|w<<8   c'=[4---] */
+    for( ; ptr < end ; ptr+=4) {
+      uint32_t k1 = c>>24;
+      c = READ_UINT32(ptr);
+      k1 |= c<<8;
+      DOBLOCK(h1, k1);
+    }
+    break;
+  case 2: /* c=[10--]  w=[5432]  b=[3210]=c>>16|w<<16  c'=[54--] */
+    for( ; ptr < end ; ptr+=4) {
+      uint32_t k1 = c>>16;
+      c = READ_UINT32(ptr);
+      k1 |= c<<16;
+      DOBLOCK(h1, k1);
+    }
+    break;
+  case 3: /* c=[210-]  w=[6543]  b=[3210]=c>>8|w<<24   c'=[654-] */
+    for( ; ptr < end ; ptr+=4) {
+      uint32_t k1 = c>>8;
+      c = READ_UINT32(ptr);
+      k1 |= c<<24;
+      DOBLOCK(h1, k1);
+    }
+  }
+#endif /*UNALIGNED_SAFE*/
+
+  /* Advance over whole 32-bit chunks, possibly leaving 1..3 bytes */
+  len -= len/4*4;
+
+  /* Append any remaining bytes into carry */
+  DOBYTES(len, h1, c, n, ptr, len);
+
+  /* Copy out new running hash and carry */
+  *ph1 = h1;
+  *pcarry = (c & ~0xff) | n;
+} 
+
+/*---------------------------------------------------------------------------*/
+
+/* Finalize a hash. To match the original Murmur3A the total_length must be provided */
+uint32_t PMurHash32_Result(uint32_t h, uint32_t carry, uint32_t total_length)
+{
+  uint32_t k1;
+  int n = carry & 3;
+  if(n) {
+    k1 = carry >> (4-n)*8;
+    k1 *= C1; k1 = ROTL32(k1,15); k1 *= C2; h ^= k1;
+  }
+  h ^= total_length;
+
+  /* fmix */
+  h ^= h >> 16;
+  h *= 0x85ebca6b;
+  h ^= h >> 13;
+  h *= 0xc2b2ae35;
+  h ^= h >> 16;
+
+  return h;
+}
+
+/*---------------------------------------------------------------------------*/
+
+/* Murmur3A compatable all-at-once */
+uint32_t PMurHash32(uint32_t seed, const void *key, int len)
+{
+  uint32_t h1=seed, carry=0;
+  PMurHash32_Process(&h1, &carry, key, len);
+  return PMurHash32_Result(h1, carry, len);
+}
+
+/*---------------------------------------------------------------------------*/
+
+/* Provide an API suitable for smhasher */
+void PMurHash32_test(const void *key, int len, uint32_t seed, void *out)
+{
+  uint32_t h1=seed, carry=0;
+  const uint8_t *ptr = (uint8_t*)key;
+  const uint8_t *end = ptr + len;
+
+#if 0 /* Exercise the progressive processing */
+  while(ptr < end) {
+    //const uint8_t *mid = ptr + rand()%(end-ptr)+1;
+    const uint8_t *mid = ptr + (rand()&0xF);
+    mid = mid<end?mid:end;
+    PMurHash32_Process(&h1, &carry, ptr, mid-ptr);
+    ptr = mid;
+  }
+#else
+  PMurHash32_Process(&h1, &carry, ptr, (int)(end-ptr));
+#endif
+  h1 = PMurHash32_Result(h1, carry, len);
+  *(uint32_t*)out = h1;
+}
+}
+
+/*---------------------------------------------------------------------------*/
new file mode 100644
--- /dev/null
+++ b/gfx/angle/src/common/third_party/smhasher/src/PMurHash.h
@@ -0,0 +1,59 @@
+/*-----------------------------------------------------------------------------
+ * MurmurHash3 was written by Austin Appleby, and is placed in the public
+ * domain.
+ *
+ * This implementation was written by Shane Day, and is also public domain.
+ *
+ * This is a portable ANSI C implementation of MurmurHash3_x86_32 (Murmur3A)
+ * with support for progressive processing.
+ */
+
+/* ------------------------------------------------------------------------- */
+/* Determine what native type to use for uint32_t */
+
+/* We can't use the name 'uint32_t' here because it will conflict with
+ * any version provided by the system headers or application. */
+
+/* First look for special cases */
+#if defined(_MSC_VER)
+  #define MH_UINT32 unsigned long
+#endif
+
+/* If the compiler says it's C99 then take its word for it */
+#if !defined(MH_UINT32) && ( \
+     defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L )
+  #include <stdint.h>
+  #define MH_UINT32 uint32_t
+#endif
+
+/* Otherwise try testing against max value macros from limit.h */
+#if !defined(MH_UINT32)
+  #include  <limits.h>
+  #if   (USHRT_MAX == 0xffffffffUL)
+    #define MH_UINT32 unsigned short
+  #elif (UINT_MAX == 0xffffffffUL)
+    #define MH_UINT32 unsigned int
+  #elif (ULONG_MAX == 0xffffffffUL)
+    #define MH_UINT32 unsigned long
+  #endif
+#endif
+
+#if !defined(MH_UINT32)
+  #error Unable to determine type name for unsigned 32-bit int
+#endif
+
+/* I'm yet to work on a platform where 'unsigned char' is not 8 bits */
+#define MH_UINT8  unsigned char
+
+
+/* ------------------------------------------------------------------------- */
+/* Prototypes */
+
+namespace angle
+{
+void PMurHash32_Process(MH_UINT32 *ph1, MH_UINT32 *pcarry, const void *key, int len);
+MH_UINT32 PMurHash32_Result(MH_UINT32 h1, MH_UINT32 carry, MH_UINT32 total_length);
+MH_UINT32 PMurHash32(MH_UINT32 seed, const void *key, int len);
+
+void PMurHash32_test(const void *key, int len, MH_UINT32 seed, void *out);
+}
--- a/gfx/angle/src/common/uniform_type_info_autogen.cpp
+++ b/gfx/angle/src/common/uniform_type_info_autogen.cpp
@@ -71,17 +71,17 @@ constexpr std::array<UniformTypeInfo, 59
      {GL_INT_IMAGE_3D, GL_INT, GL_TEXTURE_3D, GL_NONE, GL_NONE, 1, 1, 1, sizeof(GLint),
       sizeof(GLint) * 4, sizeof(GLint) * 1, false, false, true},
      {GL_INT_IMAGE_CUBE, GL_INT, GL_TEXTURE_CUBE_MAP, GL_NONE, GL_NONE, 1, 1, 1, sizeof(GLint),
       sizeof(GLint) * 4, sizeof(GLint) * 1, false, false, true},
      {GL_INT_SAMPLER_2D, GL_INT, GL_TEXTURE_2D, GL_NONE, GL_NONE, 1, 1, 1, sizeof(GLint),
       sizeof(GLint) * 4, sizeof(GLint) * 1, true, false, false},
      {GL_INT_SAMPLER_2D_ARRAY, GL_INT, GL_TEXTURE_2D_ARRAY, GL_NONE, GL_NONE, 1, 1, 1,
       sizeof(GLint), sizeof(GLint) * 4, sizeof(GLint) * 1, true, false, false},
-     {GL_INT_SAMPLER_2D_MULTISAMPLE, GL_INT, GL_TEXTURE_2D, GL_NONE, GL_NONE, 1, 1, 1,
+     {GL_INT_SAMPLER_2D_MULTISAMPLE, GL_INT, GL_TEXTURE_2D_MULTISAMPLE, GL_NONE, GL_NONE, 1, 1, 1,
       sizeof(GLint), sizeof(GLint) * 4, sizeof(GLint) * 1, true, false, false},
      {GL_INT_SAMPLER_3D, GL_INT, GL_TEXTURE_3D, GL_NONE, GL_NONE, 1, 1, 1, sizeof(GLint),
       sizeof(GLint) * 4, sizeof(GLint) * 1, true, false, false},
      {GL_INT_SAMPLER_CUBE, GL_INT, GL_TEXTURE_CUBE_MAP, GL_NONE, GL_NONE, 1, 1, 1, sizeof(GLint),
       sizeof(GLint) * 4, sizeof(GLint) * 1, true, false, false},
      {GL_INT_VEC2, GL_INT, GL_NONE, GL_NONE, GL_BOOL_VEC2, 1, 2, 2, sizeof(GLint),
       sizeof(GLint) * 4, sizeof(GLint) * 2, false, false, false},
      {GL_INT_VEC3, GL_INT, GL_NONE, GL_NONE, GL_BOOL_VEC3, 1, 3, 3, sizeof(GLint),
@@ -89,18 +89,18 @@ constexpr std::array<UniformTypeInfo, 59
      {GL_INT_VEC4, GL_INT, GL_NONE, GL_NONE, GL_BOOL_VEC4, 1, 4, 4, sizeof(GLint),
       sizeof(GLint) * 4, sizeof(GLint) * 4, false, false, false},
      {GL_SAMPLER_2D, GL_INT, GL_TEXTURE_2D, GL_NONE, GL_NONE, 1, 1, 1, sizeof(GLint),
       sizeof(GLint) * 4, sizeof(GLint) * 1, true, false, false},
      {GL_SAMPLER_2D_ARRAY, GL_INT, GL_TEXTURE_2D_ARRAY, GL_NONE, GL_NONE, 1, 1, 1, sizeof(GLint),
       sizeof(GLint) * 4, sizeof(GLint) * 1, true, false, false},
      {GL_SAMPLER_2D_ARRAY_SHADOW, GL_INT, GL_TEXTURE_2D_ARRAY, GL_NONE, GL_NONE, 1, 1, 1,
       sizeof(GLint), sizeof(GLint) * 4, sizeof(GLint) * 1, true, false, false},
-     {GL_SAMPLER_2D_MULTISAMPLE, GL_INT, GL_TEXTURE_2D, GL_NONE, GL_NONE, 1, 1, 1, sizeof(GLint),
-      sizeof(GLint) * 4, sizeof(GLint) * 1, true, false, false},
+     {GL_SAMPLER_2D_MULTISAMPLE, GL_INT, GL_TEXTURE_2D_MULTISAMPLE, GL_NONE, GL_NONE, 1, 1, 1,
+      sizeof(GLint), sizeof(GLint) * 4, sizeof(GLint) * 1, true, false, false},
      {GL_SAMPLER_2D_RECT_ANGLE, GL_INT, GL_TEXTURE_2D, GL_NONE, GL_NONE, 1, 1, 1, sizeof(GLint),
       sizeof(GLint) * 4, sizeof(GLint) * 1, true, false, false},
      {GL_SAMPLER_2D_SHADOW, GL_INT, GL_TEXTURE_2D, GL_NONE, GL_NONE, 1, 1, 1, sizeof(GLint),
       sizeof(GLint) * 4, sizeof(GLint) * 1, true, false, false},
      {GL_SAMPLER_3D, GL_INT, GL_TEXTURE_3D, GL_NONE, GL_NONE, 1, 1, 1, sizeof(GLint),
       sizeof(GLint) * 4, sizeof(GLint) * 1, true, false, false},
      {GL_SAMPLER_CUBE, GL_INT, GL_TEXTURE_CUBE_MAP, GL_NONE, GL_NONE, 1, 1, 1, sizeof(GLint),
       sizeof(GLint) * 4, sizeof(GLint) * 1, true, false, false},
@@ -119,18 +119,18 @@ constexpr std::array<UniformTypeInfo, 59
      {GL_UNSIGNED_INT_IMAGE_3D, GL_UNSIGNED_INT, GL_TEXTURE_3D, GL_NONE, GL_NONE, 1, 1, 1,
       sizeof(GLuint), sizeof(GLuint) * 4, sizeof(GLuint) * 1, false, false, true},
      {GL_UNSIGNED_INT_IMAGE_CUBE, GL_UNSIGNED_INT, GL_TEXTURE_CUBE_MAP, GL_NONE, GL_NONE, 1, 1, 1,
       sizeof(GLuint), sizeof(GLuint) * 4, sizeof(GLuint) * 1, false, false, true},
      {GL_UNSIGNED_INT_SAMPLER_2D, GL_UNSIGNED_INT, GL_TEXTURE_2D, GL_NONE, GL_NONE, 1, 1, 1,
       sizeof(GLuint), sizeof(GLuint) * 4, sizeof(GLuint) * 1, true, false, false},
      {GL_UNSIGNED_INT_SAMPLER_2D_ARRAY, GL_UNSIGNED_INT, GL_TEXTURE_2D_ARRAY, GL_NONE, GL_NONE, 1,
       1, 1, sizeof(GLuint), sizeof(GLuint) * 4, sizeof(GLuint) * 1, true, false, false},
-     {GL_UNSIGNED_INT_SAMPLER_2D_MULTISAMPLE, GL_UNSIGNED_INT, GL_TEXTURE_2D, GL_NONE, GL_NONE, 1,
-      1, 1, sizeof(GLuint), sizeof(GLuint) * 4, sizeof(GLuint) * 1, true, false, false},
+     {GL_UNSIGNED_INT_SAMPLER_2D_MULTISAMPLE, GL_UNSIGNED_INT, GL_TEXTURE_2D_MULTISAMPLE, GL_NONE,
+      GL_NONE, 1, 1, 1, sizeof(GLuint), sizeof(GLuint) * 4, sizeof(GLuint) * 1, true, false, false},
      {GL_UNSIGNED_INT_SAMPLER_3D, GL_UNSIGNED_INT, GL_TEXTURE_3D, GL_NONE, GL_NONE, 1, 1, 1,
       sizeof(GLuint), sizeof(GLuint) * 4, sizeof(GLuint) * 1, true, false, false},
      {GL_UNSIGNED_INT_SAMPLER_CUBE, GL_UNSIGNED_INT, GL_TEXTURE_CUBE_MAP, GL_NONE, GL_NONE, 1, 1, 1,
       sizeof(GLuint), sizeof(GLuint) * 4, sizeof(GLuint) * 1, true, false, false},
      {GL_UNSIGNED_INT_VEC2, GL_UNSIGNED_INT, GL_NONE, GL_NONE, GL_BOOL_VEC2, 1, 2, 2,
       sizeof(GLuint), sizeof(GLuint) * 4, sizeof(GLuint) * 2, false, false, false},
      {GL_UNSIGNED_INT_VEC3, GL_UNSIGNED_INT, GL_NONE, GL_NONE, GL_BOOL_VEC3, 1, 3, 3,
       sizeof(GLuint), sizeof(GLuint) * 4, sizeof(GLuint) * 3, false, false, false},
--- a/gfx/angle/src/common/utilities.cpp
+++ b/gfx/angle/src/common/utilities.cpp
@@ -2,16 +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.
 //
 
 // utilities.cpp: Conversion functions and other utility routines.
 
 #include "common/utilities.h"
+#include <GLSLANG/ShaderVars.h>
 #include "common/mathutil.h"
 #include "common/platform.h"
 
 #include <set>
 
 #if defined(ANGLE_ENABLE_WINDOWS_STORE)
 #  include <wrl.h>
 #  include <wrl/wrappers/corewrappers.h>
@@ -730,98 +731,170 @@ int VariableSortOrder(GLenum type)
           return 6;
 
       default:
         UNREACHABLE();
         return 0;
     }
 }
 
-std::string ParseResourceName(const std::string &name, size_t *outSubscript)
+std::string ParseResourceName(const std::string &name, std::vector<unsigned int> *outSubscripts)
 {
-    // Strip any trailing array operator and retrieve the subscript
-    size_t open = name.find_last_of('[');
-    size_t close = name.find_last_of(']');
-    bool hasIndex = (open != std::string::npos) && (close == name.length() - 1);
-    if (!hasIndex)
+    if (outSubscripts)
     {
-        if (outSubscript)
+        outSubscripts->clear();
+    }
+    // Strip any trailing array indexing operators and retrieve the subscripts.
+    size_t baseNameLength = name.length();
+    bool hasIndex         = true;
+    while (hasIndex)
+    {
+        size_t open  = name.find_last_of('[', baseNameLength - 1);
+        size_t close = name.find_last_of(']', baseNameLength - 1);
+        hasIndex     = (open != std::string::npos) && (close == baseNameLength - 1);
+        if (hasIndex)
         {
-            *outSubscript = GL_INVALID_INDEX;
-        }
-        return name;
-    }
-
-    if (outSubscript)
-    {
-        int index = atoi(name.substr(open + 1).c_str());
-        if (index >= 0)
-        {
-            *outSubscript = index;
-        }
-        else
-        {
-            *outSubscript = GL_INVALID_INDEX;
+            baseNameLength = open;
+            if (outSubscripts)
+            {
+                int index = atoi(name.substr(open + 1).c_str());
+                if (index >= 0)
+                {
+                    outSubscripts->push_back(index);
+                }
+                else
+                {
+                    outSubscripts->push_back(GL_INVALID_INDEX);
+                }
+            }
         }
     }
 
-    return name.substr(0, open);
-}
-
-template <>
-GLuint ConvertToGLuint(GLfloat param)
-{
-    return uiround<GLuint>(param);
+    return name.substr(0, baseNameLength);
 }
 
-template <>
-GLint ConvertToGLint(uint32_t param)
+const sh::ShaderVariable *FindShaderVarField(const sh::ShaderVariable &var,
+                                             const std::string &fullName)
 {
-    uint32_t max = static_cast<uint32_t>(std::numeric_limits<GLint>::max());
-    return static_cast<GLint>(param >= max ? max : param);
+    if (var.fields.empty())
+    {
+        return nullptr;
+    }
+    size_t pos = fullName.find_first_of(".");
+    if (pos == std::string::npos)
+    {
+        return nullptr;
+    }
+    std::string topName = fullName.substr(0, pos);
+    if (topName != var.name)
+    {
+        return nullptr;
+    }
+    std::string fieldName = fullName.substr(pos + 1);
+    if (fieldName.empty())
+    {
+        return nullptr;
+    }
+    for (const auto &field : var.fields)
+    {
+        if (field.name == fieldName)
+        {
+            return &field;
+        }
+    }
+    return nullptr;
 }
 
-template <>
-GLint ConvertToGLint(uint64_t param)
+unsigned int ArraySizeProduct(const std::vector<unsigned int> &arraySizes)
 {
-    uint64_t max = static_cast<uint64_t>(std::numeric_limits<GLint>::max());
-    return static_cast<GLint>(param >= max ? max : param);
+    unsigned int arraySizeProduct = 1u;
+    for (unsigned int arraySize : arraySizes)
+    {
+        arraySizeProduct *= arraySize;
+    }
+    return arraySizeProduct;
 }
 
-template <>
-GLint ConvertToGLint(GLfloat param)
+unsigned int ParseArrayIndex(const std::string &name, size_t *nameLengthWithoutArrayIndexOut)
 {
-    return iround<GLint>(param);
+    ASSERT(nameLengthWithoutArrayIndexOut != nullptr);
+
+    // Strip any trailing array operator and retrieve the subscript
+    size_t open = name.find_last_of('[');
+    if (open != std::string::npos && name.back() == ']')
+    {
+        bool indexIsValidDecimalNumber = true;
+        for (size_t i = open + 1; i < name.length() - 1u; ++i)
+        {
+            if (!isdigit(name[i]))
+            {
+                indexIsValidDecimalNumber = false;
+                break;
+            }
+        }
+        if (indexIsValidDecimalNumber)
+        {
+            errno = 0;  // reset global error flag.
+            unsigned long subscript =
+                strtoul(name.c_str() + open + 1, /*endptr*/ nullptr, /*radix*/ 10);
+
+            // Check if resulting integer is out-of-range or conversion error.
+            if ((subscript <= static_cast<unsigned long>(UINT_MAX)) &&
+                !(subscript == ULONG_MAX && errno == ERANGE) && !(errno != 0 && subscript == 0))
+            {
+                *nameLengthWithoutArrayIndexOut = open;
+                return static_cast<unsigned int>(subscript);
+            }
+        }
+    }
+
+    *nameLengthWithoutArrayIndexOut = name.length();
+    return GL_INVALID_INDEX;
 }
 
-template <>
-GLint ConvertFromGLfloat(GLfloat param)
+const char *GetGenericErrorMessage(GLenum error)
 {
-    return iround<GLint>(param);
-}
-template <>
-GLuint ConvertFromGLfloat(GLfloat param)
-{
-    return uiround<GLuint>(param);
+    switch (error)
+    {
+        case GL_NO_ERROR:
+            return "";
+        case GL_INVALID_ENUM:
+            return "Invalid enum.";
+        case GL_INVALID_VALUE:
+            return "Invalid value.";
+        case GL_INVALID_OPERATION:
+            return "Invalid operation.";
+        case GL_STACK_OVERFLOW:
+            return "Stack overflow.";
+        case GL_STACK_UNDERFLOW:
+            return "Stack underflow.";
+        case GL_OUT_OF_MEMORY:
+            return "Out of memory.";
+        case GL_INVALID_FRAMEBUFFER_OPERATION:
+            return "Invalid framebuffer operation.";
+        default:
+            UNREACHABLE();
+            return "Unknown error.";
+    }
 }
 
-unsigned int ParseAndStripArrayIndex(std::string *name)
+unsigned int ElementTypeSize(GLenum elementType)
 {
-    unsigned int subscript = GL_INVALID_INDEX;
-
-    // Strip any trailing array operator and retrieve the subscript
-    size_t open  = name->find_last_of('[');
-    size_t close = name->find_last_of(']');
-    if (open != std::string::npos && close == name->length() - 1)
+    switch (elementType)
     {
-        subscript = atoi(name->c_str() + open + 1);
-        name->erase(open);
+        case GL_UNSIGNED_BYTE:
+            return sizeof(GLubyte);
+        case GL_UNSIGNED_SHORT:
+            return sizeof(GLushort);
+        case GL_UNSIGNED_INT:
+            return sizeof(GLuint);
+        default:
+            UNREACHABLE();
+            return 0;
     }
-
-    return subscript;
 }
 
 }  // namespace gl
 
 namespace egl
 {
 static_assert(EGL_GL_TEXTURE_CUBE_MAP_NEGATIVE_X_KHR - EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_X_KHR == 1,
               "Unexpected EGL cube map enum value.");
@@ -869,16 +942,61 @@ bool IsTextureTarget(EGLenum target)
             return false;
     }
 }
 
 bool IsRenderbufferTarget(EGLenum target)
 {
     return target == EGL_GL_RENDERBUFFER_KHR;
 }
+
+const char *GetGenericErrorMessage(EGLint error)
+{
+    switch (error)
+    {
+        case EGL_SUCCESS:
+            return "";
+        case EGL_NOT_INITIALIZED:
+            return "Not initialized.";
+        case EGL_BAD_ACCESS:
+            return "Bad access.";
+        case EGL_BAD_ALLOC:
+            return "Bad allocation.";
+        case EGL_BAD_ATTRIBUTE:
+            return "Bad attribute.";
+        case EGL_BAD_CONFIG:
+            return "Bad config.";
+        case EGL_BAD_CONTEXT:
+            return "Bad context.";
+        case EGL_BAD_CURRENT_SURFACE:
+            return "Bad current surface.";
+        case EGL_BAD_DISPLAY:
+            return "Bad display.";
+        case EGL_BAD_MATCH:
+            return "Bad match.";
+        case EGL_BAD_NATIVE_WINDOW:
+            return "Bad native window.";
+        case EGL_BAD_PARAMETER:
+            return "Bad parameter.";
+        case EGL_BAD_SURFACE:
+            return "Bad surface.";
+        case EGL_CONTEXT_LOST:
+            return "Context lost.";
+        case EGL_BAD_STREAM_KHR:
+            return "Bad stream.";
+        case EGL_BAD_STATE_KHR:
+            return "Bad state.";
+        case EGL_BAD_DEVICE_EXT:
+            return "Bad device.";
+        default:
+            UNREACHABLE();
+            return "Unknown error.";
+    }
+}
+
 }  // namespace egl
 
 namespace egl_gl
 {
 GLenum EGLCubeMapTargetToGLCubeMapTarget(EGLenum eglTarget)
 {
     ASSERT(egl::IsCubeMapTextureTarget(eglTarget));
     return gl::LayerIndexToCubeMapTextureTarget(egl::CubeMapTextureTargetToLayerIndex(eglTarget));
@@ -903,16 +1021,32 @@ GLenum EGLImageTargetToGLTextureTarget(E
             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/src/common/utilities.h
+++ b/gfx/angle/src/common/utilities.h
@@ -7,22 +7,28 @@
 // utilities.h: Conversion functions and other utility routines.
 
 #ifndef COMMON_UTILITIES_H_
 #define COMMON_UTILITIES_H_
 
 #include <EGL/egl.h>
 #include <EGL/eglext.h>
 
-#include "angle_gl.h"
+#include <math.h>
 #include <string>
-#include <math.h>
+#include <vector>
+#include "angle_gl.h"
 
 #include "common/mathutil.h"
 
+namespace sh
+{
+struct ShaderVariable;
+}
+
 namespace gl
 {
 
 int VariableComponentCount(GLenum type);
 GLenum VariableComponentType(GLenum type);
 size_t VariableComponentSize(GLenum type);
 size_t VariableInternalSize(GLenum type);
 size_t VariableExternalSize(GLenum type);
@@ -44,192 +50,125 @@ GLenum VariableBoolVectorType(GLenum typ
 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 index.  Returns the base name of the resource.
-// outSubscript is set to GL_INVALID_INDEX if the provided name is not an array or the array index
-// is invalid.
-std::string ParseResourceName(const std::string &name, size_t *outSubscript);
+// 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.
+// Return nullptr if not found.
+const sh::ShaderVariable *FindShaderVarField(const sh::ShaderVariable &var,
+                                             const std::string &fullName);
 
 // Find the range of index values in the provided indices pointer.  Primitive restart indices are
 // only counted in the range if primitive restart is disabled.
 IndexRange ComputeIndexRange(GLenum indexType,
                              const GLvoid *indices,
                              size_t count,
                              bool primitiveRestartEnabled);
 
 // Get the primitive restart index value for the given index type.
 GLuint GetPrimitiveRestartIndex(GLenum indexType);
 
 bool IsTriangleMode(GLenum drawMode);
 bool IsIntegerFormat(GLenum unsizedFormat);
 
-// [OpenGL ES 3.0.2] Section 2.3.1 page 14
-// Data Conversion For State-Setting Commands
-// Floating-point values are rounded to the nearest integer, instead of truncated, as done by static_cast.
-template <typename outT> outT iround(GLfloat value) { return static_cast<outT>(value > 0.0f ? floor(value + 0.5f) : ceil(value - 0.5f)); }
-template <typename outT> outT uiround(GLfloat value) { return static_cast<outT>(value + 0.5f); }
-
-// Helper for converting arbitrary GL types to other GL types used in queries and state setting
-
-// TODO(jie.a.chen@intel.com): Add the conversion rule for all helpers as the spec requires:
-// "If a value is so large in magnitude that it cannot be represented with the requested type,"
-// "then the nearest value representable using the requested type is returned."
-
-template <typename ParamType>
-GLuint ConvertToGLuint(ParamType param)
-{
-    return static_cast<GLuint>(param);
-}
-template <>
-GLuint ConvertToGLuint(GLfloat param);
-
-template <typename ParamType>
-GLint ConvertToGLint(ParamType param)
-{
-    return static_cast<GLint>(param);
-}
-
-template <>
-GLint ConvertToGLint(uint32_t param);
-
-template <>
-GLint ConvertToGLint(uint64_t param);
-
-template <>
-GLint ConvertToGLint(GLfloat param);
-
-// Same conversion as uint
-template <typename ParamType>
-GLenum ConvertToGLenum(ParamType param)
-{
-    return static_cast<GLenum>(ConvertToGLuint(param));
-}
+// Returns the product of the sizes in the vector, or 1 if the vector is empty. Doesn't currently
+// perform overflow checks.
+unsigned int ArraySizeProduct(const std::vector<unsigned int> &arraySizes);
 
-template <typename ParamType>
-GLfloat ConvertToGLfloat(ParamType param)
-{
-    return static_cast<GLfloat>(param);
-}
-
-template <typename ParamType>
-ParamType ConvertFromGLfloat(GLfloat param)
-{
-    return static_cast<ParamType>(param);
-}
-template <>
-GLint ConvertFromGLfloat(GLfloat param);
-template <>
-GLuint ConvertFromGLfloat(GLfloat param);
-
-template <typename ParamType>
-ParamType ConvertFromGLenum(GLenum param)
-{
-    return static_cast<ParamType>(param);
-}
-
-template <typename ParamType>
-ParamType ConvertFromGLuint(GLuint param)
-{
-    return static_cast<ParamType>(param);
-}
-
-template <typename ParamType>
-ParamType ConvertFromGLint(GLint param)
-{
-    return static_cast<ParamType>(param);
-}
-
-template <typename ParamType>
-ParamType ConvertFromGLboolean(GLboolean param)
-{
-    return static_cast<ParamType>(param ? GL_TRUE : GL_FALSE);
-}
-
-template <typename ParamType>
-ParamType ConvertFromGLint64(GLint64 param)
-{
-    return clampCast<ParamType>(param);
-}
-
-unsigned int ParseAndStripArrayIndex(std::string *name);
+// Return the array index at the end of name, and write the length of name before the final array
+// index into nameLengthWithoutArrayIndexOut. In case name doesn't include an array index, return
+// GL_INVALID_INDEX and write the length of the original string.
+unsigned int ParseArrayIndex(const std::string &name, size_t *nameLengthWithoutArrayIndexOut);
 
 struct UniformTypeInfo final : angle::NonCopyable
 {
     constexpr UniformTypeInfo(GLenum type,
                               GLenum componentType,
-                              GLenum samplerTextureType,
+                              GLenum textureType,
                               GLenum transposedMatrixType,
                               GLenum boolVectorType,
                               int rowCount,
                               int columnCount,
                               int componentCount,
                               size_t componentSize,
                               size_t internalSize,
                               size_t externalSize,
                               bool isSampler,
                               bool isMatrixType,
                               bool isImageType)
         : type(type),
           componentType(componentType),
-          samplerTextureType(samplerTextureType),
+          textureType(textureType),
           transposedMatrixType(transposedMatrixType),
           boolVectorType(boolVectorType),
           rowCount(rowCount),
           columnCount(columnCount),
           componentCount(componentCount),
           componentSize(componentSize),
           internalSize(internalSize),
           externalSize(externalSize),
           isSampler(isSampler),
           isMatrixType(isMatrixType),
           isImageType(isImageType)
     {
     }
 
     GLenum type;
     GLenum componentType;
-    GLenum samplerTextureType;
+    GLenum textureType;
     GLenum transposedMatrixType;
     GLenum boolVectorType;
     int rowCount;
     int columnCount;
     int componentCount;
     size_t componentSize;
     size_t internalSize;
     size_t externalSize;
     bool isSampler;
     bool isMatrixType;
     bool isImageType;
 };
 
 const UniformTypeInfo &GetUniformTypeInfo(GLenum uniformType);
 
+const char *GetGenericErrorMessage(GLenum error);
+
+unsigned int ElementTypeSize(GLenum elementType);
+
 }  // namespace gl
 
 namespace egl
 {
 static const EGLenum FirstCubeMapTextureTarget = EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_X_KHR;
 static const EGLenum LastCubeMapTextureTarget = EGL_GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_KHR;
 bool IsCubeMapTextureTarget(EGLenum target);
 size_t CubeMapTextureTargetToLayerIndex(EGLenum target);
 EGLenum LayerIndexToCubeMapTextureTarget(size_t index);
 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/src/common/utilities_unittest.cpp
+++ b/gfx/angle/src/common/utilities_unittest.cpp
@@ -8,48 +8,173 @@
 #include "gmock/gmock.h"
 #include "gtest/gtest.h"
 
 #include "common/utilities.h"
 
 namespace
 {
 
+// Test parsing valid single array indices
 TEST(ParseResourceName, ArrayIndex)
 {
-    size_t index;
-    EXPECT_EQ("foo", gl::ParseResourceName("foo[123]", &index));
-    EXPECT_EQ(123u, index);
+    std::vector<unsigned int> indices;
+    EXPECT_EQ("foo", gl::ParseResourceName("foo[123]", &indices));
+    ASSERT_EQ(1u, indices.size());
+    EXPECT_EQ(123u, indices[0]);
 
-    EXPECT_EQ("bar", gl::ParseResourceName("bar[0]", &index));
-    EXPECT_EQ(0u, index);
+    EXPECT_EQ("bar", gl::ParseResourceName("bar[0]", &indices));
+    ASSERT_EQ(1u, indices.size());
+    EXPECT_EQ(0u, indices[0]);
 }
 
+// Parsing a negative array index should result in INVALID_INDEX.
 TEST(ParseResourceName, NegativeArrayIndex)
 {
-    size_t index;
-    EXPECT_EQ("foo", gl::ParseResourceName("foo[-1]", &index));
-    EXPECT_EQ(GL_INVALID_INDEX, index);
+    std::vector<unsigned int> indices;
+    EXPECT_EQ("foo", gl::ParseResourceName("foo[-1]", &indices));
+    ASSERT_EQ(1u, indices.size());
+    EXPECT_EQ(GL_INVALID_INDEX, indices.back());
 }
 
+// Parsing no array indices should result in an empty array.
 TEST(ParseResourceName, NoArrayIndex)
 {
-    size_t index;
-    EXPECT_EQ("foo", gl::ParseResourceName("foo", &index));
-    EXPECT_EQ(GL_INVALID_INDEX, index);
+    std::vector<unsigned int> indices;
+    EXPECT_EQ("foo", gl::ParseResourceName("foo", &indices));
+    EXPECT_TRUE(indices.empty());
 }
 
-TEST(ParseResourceName, NULLArrayIndex)
+// The ParseResourceName function should work when a nullptr is passed as the indices output vector.
+TEST(ParseResourceName, NULLArrayIndices)
 {
     EXPECT_EQ("foo", gl::ParseResourceName("foo[10]", nullptr));
 }
 
+// Parsing multiple array indices should result in outermost array indices being last in the vector.
+TEST(ParseResourceName, MultipleArrayIndices)
+{
+    std::vector<unsigned int> indices;
+    EXPECT_EQ("foo", gl::ParseResourceName("foo[12][34][56]", &indices));
+    ASSERT_EQ(3u, indices.size());
+    // Indices are sorted with outermost array index last.
+    EXPECT_EQ(56u, indices[0]);
+    EXPECT_EQ(34u, indices[1]);
+    EXPECT_EQ(12u, indices[2]);
+}
+
+// Trailing whitespace should not be accepted by ParseResourceName.
 TEST(ParseResourceName, TrailingWhitespace)
 {
-    size_t index;
-    EXPECT_EQ("foo ", gl::ParseResourceName("foo ", &index));
-    EXPECT_EQ(GL_INVALID_INDEX, index);
+    std::vector<unsigned int> indices;
+    EXPECT_EQ("foo ", gl::ParseResourceName("foo ", &indices));
+    EXPECT_TRUE(indices.empty());
+
+    EXPECT_EQ("foo[10] ", gl::ParseResourceName("foo[10] ", &indices));
+    EXPECT_TRUE(indices.empty());
+
+    EXPECT_EQ("foo[10][20] ", gl::ParseResourceName("foo[10][20] ", &indices));
+    EXPECT_TRUE(indices.empty());
+}
+
+// Parse a string without any index.
+TEST(ParseArrayIndex, NoArrayIndex)
+{
+    size_t nameLengthWithoutArrayIndex;
+    EXPECT_EQ(GL_INVALID_INDEX, gl::ParseArrayIndex("foo", &nameLengthWithoutArrayIndex));
+    EXPECT_EQ(3u, nameLengthWithoutArrayIndex);
+}
 
-    EXPECT_EQ("foo[10] ", gl::ParseResourceName("foo[10] ", &index));
-    EXPECT_EQ(GL_INVALID_INDEX, index);
+// Parse an empty string for an array index.
+TEST(ParseArrayIndex, EmptyString)
+{
+    size_t nameLengthWithoutArrayIndex;
+    EXPECT_EQ(GL_INVALID_INDEX, gl::ParseArrayIndex("", &nameLengthWithoutArrayIndex));
+    EXPECT_EQ(0u, nameLengthWithoutArrayIndex);
+}
+
+// A valid array index is parsed correctly from the end of the string.
+TEST(ParseArrayIndex, ArrayIndex)
+{
+    size_t nameLengthWithoutArrayIndex;
+    EXPECT_EQ(123u, gl::ParseArrayIndex("foo[123]", &nameLengthWithoutArrayIndex));
+    EXPECT_EQ(3u, nameLengthWithoutArrayIndex);
+}
+
+// An array index from the middle of the string is not parsed.
+TEST(ParseArrayIndex, ArrayIndexInMiddle)
+{
+    size_t nameLengthWithoutArrayIndex;
+    EXPECT_EQ(GL_INVALID_INDEX, gl::ParseArrayIndex("foo[123].bar", &nameLengthWithoutArrayIndex));
+    EXPECT_EQ(12u, nameLengthWithoutArrayIndex);
+}
+
+// Trailing whitespace in the parsed string is taken into account.
+TEST(ParseArrayIndex, TrailingWhitespace)
+{
+    size_t nameLengthWithoutArrayIndex;
+    EXPECT_EQ(GL_INVALID_INDEX, gl::ParseArrayIndex("foo[123] ", &nameLengthWithoutArrayIndex));
+    EXPECT_EQ(9u, nameLengthWithoutArrayIndex);
 }
 
+// Only the last index is parsed.
+TEST(ParseArrayIndex, MultipleArrayIndices)
+{
+    size_t nameLengthWithoutArrayIndex;
+    EXPECT_EQ(34u, gl::ParseArrayIndex("foo[12][34]", &nameLengthWithoutArrayIndex));
+    EXPECT_EQ(7u, nameLengthWithoutArrayIndex);
 }
+
+// GetProgramResourceLocation spec in GLES 3.1 November 2016 page 87 mentions "decimal" integer.
+// So an integer in hexadecimal format should not parse as an array index.
+TEST(ParseArrayIndex, HexArrayIndex)
+{
+    size_t nameLengthWithoutArrayIndex;
+    EXPECT_EQ(GL_INVALID_INDEX, gl::ParseArrayIndex("foo[0xff]", &nameLengthWithoutArrayIndex));
+    EXPECT_EQ(9u, nameLengthWithoutArrayIndex);
+}
+
+// GetProgramResourceLocation spec in GLES 3.1 November 2016 page 87 mentions that the array
+// index should not contain a leading plus sign.
+TEST(ParseArrayIndex, ArrayIndexLeadingPlus)
+{
+    size_t nameLengthWithoutArrayIndex;
+    EXPECT_EQ(GL_INVALID_INDEX, gl::ParseArrayIndex("foo[+1]", &nameLengthWithoutArrayIndex));
+    EXPECT_EQ(7u, nameLengthWithoutArrayIndex);
+}
+
+// GetProgramResourceLocation spec in GLES 3.1 November 2016 page 87 says that index should not
+// contain whitespace. Test leading whitespace.
+TEST(ParseArrayIndex, ArrayIndexLeadingWhiteSpace)
+{
+    size_t nameLengthWithoutArrayIndex;
+    EXPECT_EQ(GL_INVALID_INDEX, gl::ParseArrayIndex("foo[ 0]", &nameLengthWithoutArrayIndex));
+    EXPECT_EQ(7u, nameLengthWithoutArrayIndex);
+}
+
+// GetProgramResourceLocation spec in GLES 3.1 November 2016 page 87 says that index should not
+// contain whitespace. Test trailing whitespace.
+TEST(ParseArrayIndex, ArrayIndexTrailingWhiteSpace)
+{
+    size_t nameLengthWithoutArrayIndex;
+    EXPECT_EQ(GL_INVALID_INDEX, gl::ParseArrayIndex("foo[0 ]", &nameLengthWithoutArrayIndex));
+    EXPECT_EQ(7u, nameLengthWithoutArrayIndex);
+}
+
+// GetProgramResourceLocation spec in GLES 3.1 November 2016 page 87 says that index should only
+// contain an integer.
+TEST(ParseArrayIndex, ArrayIndexBogus)
+{
+    size_t nameLengthWithoutArrayIndex;
+    EXPECT_EQ(GL_INVALID_INDEX, gl::ParseArrayIndex("foo[0bogus]", &nameLengthWithoutArrayIndex));
+    EXPECT_EQ(11u, nameLengthWithoutArrayIndex);
+}
+
+// Verify that using an index value out-of-range fails.
+TEST(ParseArrayIndex, ArrayIndexOutOfRange)
+{
+    size_t nameLengthWithoutArrayIndex;
+    EXPECT_EQ(GL_INVALID_INDEX,
+              gl::ParseArrayIndex("foo[4294967296]", &nameLengthWithoutArrayIndex));
+    EXPECT_EQ(15u, nameLengthWithoutArrayIndex);
+}
+
+}  // anonymous namespace
--- a/gfx/angle/src/compiler.gypi
+++ b/gfx/angle/src/compiler.gypi
@@ -24,30 +24,30 @@
             '../include/angle_gl.h',
             'compiler/translator/AddAndTrueToLoopCondition.cpp',
             'compiler/translator/AddAndTrueToLoopCondition.h',
             'compiler/translator/BaseTypes.h',
             'compiler/translator/BuiltInFunctionEmulator.cpp',
             'compiler/translator/BuiltInFunctionEmulator.h',
             'compiler/translator/BreakVariableAliasingInInnerLoops.cpp',
             'compiler/translator/BreakVariableAliasingInInnerLoops.h',
-            'compiler/translator/Cache.cpp',
-            'compiler/translator/Cache.h',
             'compiler/translator/CallDAG.cpp',
             'compiler/translator/CallDAG.h',
             'compiler/translator/ClampPointSize.cpp',
             'compiler/translator/ClampPointSize.h',
             'compiler/translator/CodeGen.cpp',
             'compiler/translator/CollectVariables.cpp',
             'compiler/translator/CollectVariables.h',
             'compiler/translator/Common.h',
             'compiler/translator/Compiler.cpp',
             'compiler/translator/Compiler.h',
             'compiler/translator/ConstantUnion.cpp',
             'compiler/translator/ConstantUnion.h',
+            'compiler/translator/Declarator.cpp',
+            'compiler/translator/Declarator.h',
             'compiler/translator/DeclareAndInitBuiltinsForInstancedMultiview.h',
             'compiler/translator/DeclareAndInitBuiltinsForInstancedMultiview.cpp',
             'compiler/translator/DeferGlobalInitializers.cpp',
             'compiler/translator/DeferGlobalInitializers.h',
             'compiler/translator/Diagnostics.cpp',
             'compiler/translator/Diagnostics.h',
             'compiler/translator/DirectiveHandler.cpp',
             'compiler/translator/DirectiveHandler.h',
@@ -60,16 +60,18 @@
             'compiler/translator/ExtensionBehavior.cpp',
             'compiler/translator/ExtensionBehavior.h',
             'compiler/translator/FindMain.cpp',
             'compiler/translator/FindMain.h',
             'compiler/translator/FindSymbolNode.cpp',
             'compiler/translator/FindSymbolNode.h',
             'compiler/translator/FlagStd140Structs.cpp',
             'compiler/translator/FlagStd140Structs.h',
+            'compiler/translator/FoldExpressions.cpp',
+            'compiler/translator/FoldExpressions.h',
             'compiler/translator/HashNames.cpp',
             'compiler/translator/HashNames.h',
             'compiler/translator/InfoSink.cpp',
             'compiler/translator/InfoSink.h',
             'compiler/translator/Initialize.cpp',
             'compiler/translator/Initialize.h',
             'compiler/translator/InitializeDll.cpp',
             'compiler/translator/InitializeDll.h',
@@ -92,57 +94,65 @@
             'compiler/translator/OutputTree.cpp',
             'compiler/translator/OutputTree.h',
             'compiler/translator/ParamType.h',
             'compiler/translator/ParseContext.cpp',
             'compiler/translator/ParseContext.h',
             'compiler/translator/PoolAlloc.cpp',
             'compiler/translator/PoolAlloc.h',
             'compiler/translator/Pragma.h',
-            'compiler/translator/PruneEmptyDeclarations.cpp',
-            'compiler/translator/PruneEmptyDeclarations.h',
-            'compiler/translator/PrunePureLiteralStatements.cpp',
-            'compiler/translator/PrunePureLiteralStatements.h',
+            'compiler/translator/PruneNoOps.cpp',
+            'compiler/translator/PruneNoOps.h',
             'compiler/translator/QualifierTypes.h',
             'compiler/translator/QualifierTypes.cpp',
             'compiler/translator/RecordConstantPrecision.cpp',
             'compiler/translator/RecordConstantPrecision.h',
             'compiler/translator/RegenerateStructNames.cpp',
             'compiler/translator/RegenerateStructNames.h',
             'compiler/translator/RemoveArrayLengthMethod.cpp',
             'compiler/translator/RemoveArrayLengthMethod.h',
+            'compiler/translator/RemoveEmptySwitchStatements.cpp',
+            'compiler/translator/RemoveEmptySwitchStatements.h',
             'compiler/translator/RemoveInvariantDeclaration.cpp',
             'compiler/translator/RemoveInvariantDeclaration.h',
+            'compiler/translator/RemoveNoOpCasesFromEndOfSwitchStatements.cpp',
+            'compiler/translator/RemoveNoOpCasesFromEndOfSwitchStatements.h',
             'compiler/translator/RemovePow.cpp',
             'compiler/translator/RemovePow.h',
+            'compiler/translator/RemoveUnreferencedVariables.cpp',
+            'compiler/translator/RemoveUnreferencedVariables.h',
             'compiler/translator/RewriteDoWhile.cpp',
             'compiler/translator/RewriteDoWhile.h',
             'compiler/translator/RewriteTexelFetchOffset.cpp',
             'compiler/translator/RewriteTexelFetchOffset.h',
             'compiler/translator/RewriteUnaryMinusOperatorFloat.cpp',
             'compiler/translator/RewriteUnaryMinusOperatorFloat.h',
             'compiler/translator/RewriteUnaryMinusOperatorInt.cpp',
             'compiler/translator/RewriteUnaryMinusOperatorInt.h',
             'compiler/translator/RunAtTheEndOfShader.cpp',
             'compiler/translator/RunAtTheEndOfShader.h',
             'compiler/translator/ScalarizeVecAndMatConstructorArgs.cpp',
             'compiler/translator/ScalarizeVecAndMatConstructorArgs.h',
-            'compiler/translator/SearchSymbol.cpp',
-            'compiler/translator/SearchSymbol.h',
             'compiler/translator/SeparateDeclarations.cpp',
             'compiler/translator/SeparateDeclarations.h',
             'compiler/translator/Severity.h',
             'compiler/translator/ShaderLang.cpp',
             'compiler/translator/ShaderVars.cpp',
             'compiler/translator/SimplifyLoopConditions.cpp',
             'compiler/translator/SimplifyLoopConditions.h',
             'compiler/translator/SplitSequenceOperator.cpp',
             'compiler/translator/SplitSequenceOperator.h',
+            'compiler/translator/StaticType.cpp',
+            'compiler/translator/StaticType.h',
+            'compiler/translator/Symbol.cpp',
+            'compiler/translator/Symbol.h',
             'compiler/translator/SymbolTable.cpp',
             'compiler/translator/SymbolTable.h',
+            'compiler/translator/SymbolUniqueId.cpp',
+            'compiler/translator/SymbolUniqueId.h',
             'compiler/translator/Types.cpp',
             'compiler/translator/Types.h',
             'compiler/translator/UnfoldShortCircuitAST.cpp',
             'compiler/translator/UnfoldShortCircuitAST.h',
             'compiler/translator/UseInterfaceBlockFields.cpp',
             'compiler/translator/UseInterfaceBlockFields.h',
             'compiler/translator/ValidateGlobalInitializer.cpp',
             'compiler/translator/ValidateGlobalInitializer.h',
@@ -153,16 +163,18 @@
             'compiler/translator/ValidateOutputs.cpp',
             'compiler/translator/ValidateOutputs.h',
             'compiler/translator/ValidateSwitch.cpp',
             'compiler/translator/ValidateSwitch.h',
             'compiler/translator/ValidateVaryingLocations.cpp',
             'compiler/translator/ValidateVaryingLocations.h',
             'compiler/translator/VariablePacker.cpp',
             'compiler/translator/VariablePacker.h',
+            'compiler/translator/VectorizeVectorScalarArithmetic.cpp',
+            'compiler/translator/VectorizeVectorScalarArithmetic.h',
             'compiler/translator/blocklayout.cpp',
             'compiler/translator/blocklayout.h',
             'compiler/translator/glslang.h',
             'compiler/translator/glslang.l',
             'compiler/translator/glslang.y',
             'compiler/translator/glslang_lex.cpp',
             'compiler/translator/glslang_tab.cpp',
             'compiler/translator/glslang_tab.h',
@@ -217,24 +229,28 @@
             'compiler/translator/SeparateArrayInitialization.cpp',
             'compiler/translator/SeparateArrayInitialization.h',
             'compiler/translator/SeparateExpressionsReturningArrays.cpp',
             'compiler/translator/SeparateExpressionsReturningArrays.h',
             'compiler/translator/StructureHLSL.cpp',
             'compiler/translator/StructureHLSL.h',
             'compiler/translator/TextureFunctionHLSL.cpp',
             'compiler/translator/TextureFunctionHLSL.h',
+            'compiler/translator/ImageFunctionHLSL.cpp',
+            'compiler/translator/ImageFunctionHLSL.h',
             'compiler/translator/TranslatorHLSL.cpp',
             'compiler/translator/TranslatorHLSL.h',
             'compiler/translator/UnfoldShortCircuitToIf.cpp',
             'compiler/translator/UnfoldShortCircuitToIf.h',
             'compiler/translator/UniformHLSL.cpp',
             'compiler/translator/UniformHLSL.h',
             'compiler/translator/UtilsHLSL.cpp',
             'compiler/translator/UtilsHLSL.h',
+            'compiler/translator/WrapSwitchStatementsInBlocks.cpp',
+            'compiler/translator/WrapSwitchStatementsInBlocks.h',
             'compiler/translator/emulated_builtin_functions_hlsl_autogen.cpp',
         ],
         'angle_translator_lib_vulkan_sources':
         [
             'compiler/translator/OutputVulkanGLSL.cpp',
             'compiler/translator/OutputVulkanGLSL.h',
             'compiler/translator/TranslatorVulkan.cpp',
             'compiler/translator/TranslatorVulkan.h',
--- a/gfx/angle/src/compiler/preprocessor/DiagnosticsBase.cpp
+++ b/gfx/angle/src/compiler/preprocessor/DiagnosticsBase.cpp
@@ -113,16 +113,18 @@ const char *Diagnostics::message(ID id)
         case PP_INVALID_FILE_NUMBER:
             return "invalid file number";
         case PP_INVALID_LINE_DIRECTIVE:
             return "invalid line directive";
         case PP_NON_PP_TOKEN_BEFORE_EXTENSION_ESSL3:
             return "extension directive must occur before any non-preprocessor tokens in ESSL3";
         case PP_UNDEFINED_SHIFT:
             return "shift exponent is negative or undefined";
+        case PP_TOKENIZER_ERROR:
+            return "internal tokenizer error";
         // Errors end.
         // Warnings begin.
         case PP_EOF_IN_DIRECTIVE:
             return "unexpected end of file found in directive";
         case PP_CONDITIONAL_UNEXPECTED_TOKEN:
             return "unexpected token after conditional expression";
         case PP_UNRECOGNIZED_PRAGMA:
             return "unrecognized pragma";
--- a/gfx/angle/src/compiler/preprocessor/DirectiveParser.cpp
+++ b/gfx/angle/src/compiler/preprocessor/DirectiveParser.cpp
@@ -210,16 +210,20 @@ DirectiveParser::DirectiveParser(Tokeniz
       mMacroSet(macroSet),
       mDiagnostics(diagnostics),
       mDirectiveHandler(directiveHandler),
       mShaderVersion(100),
       mMaxMacroExpansionDepth(maxMacroExpansionDepth)
 {
 }
 
+DirectiveParser::~DirectiveParser()
+{
+}
+
 void DirectiveParser::lex(Token *token)
 {
     do
     {
         mTokenizer->lex(token);
 
         if (token->type == Token::PP_HASH)
         {
--- a/gfx/angle/src/compiler/preprocessor/DirectiveParser.h
+++ b/gfx/angle/src/compiler/preprocessor/DirectiveParser.h
@@ -21,16 +21,17 @@ class Tokenizer;
 class DirectiveParser : public Lexer
 {
   public:
     DirectiveParser(Tokenizer *tokenizer,
                     MacroSet *macroSet,
                     Diagnostics *diagnostics,
                     DirectiveHandler *directiveHandler,
                     int maxMacroExpansionDepth);
+    ~DirectiveParser() override;
 
     void lex(Token *token) override;
 
   private:
     void parseDirective(Token *token);
     void parseDefine(Token *token);
     void parseUndef(Token *token);
     void parseIf(Token *token);
--- a/gfx/angle/src/compiler/preprocessor/ExpressionParser.cpp
+++ b/gfx/angle/src/compiler/preprocessor/ExpressionParser.cpp
@@ -491,22 +491,19 @@ static const yytype_uint8 yytranslate[] 
        2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
        2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
        2,     2,     2,     2,     2,     2,     1,     2,     3,     4,
        5,     6,    10,    11,    14,    15,    16,    17,    23
 };
 
 #if YYDEBUG
   /* YYRLINE[YYN] -- Source line where rule number YYN was defined.  */
-static const yytype_uint16 yyrline[] =
-{
-       0,   108,   108,   115,   116,   127,   127,   148,   148,   169,
-     172,   175,   178,   181,   184,   187,   190,   193,   196,   221,
-     246,   249,   252,   278,   305,   308,   311,   314,   326,   329
-};
+static const yytype_uint16 yyrline[] = {0,   108, 108, 115, 116, 127, 127, 148, 148, 169,
+                                        172, 175, 178, 181, 184, 187, 190, 193, 196, 221,
+                                        243, 246, 249, 275, 302, 305, 308, 311, 323, 326};
 #endif
 
 #if YYDEBUG || YYERROR_VERBOSE || 0
 /* YYTNAME[SYMBOL-NUM] -- String name of the symbol SYMBOL-NUM.
    First, the terminals, then, starting at YYNTOKENS, nonterminals.  */
 static const char *const yytname[] =
 {
   "$end", "error", "$undefined", "TOK_CONST_INT", "TOK_IDENTIFIER",
@@ -1532,24 +1529,21 @@ yyreduce:
                 std::string text = stream.str();
                 context->diagnostics->report(pp::Diagnostics::PP_UNDEFINED_SHIFT,
                                              context->token->location,
                                              text.c_str());
                 *(context->valid) = false;
             }
             (yyval) = static_cast<YYSTYPE>(0);
         }
-        else if ((yyvsp[-2]) < 0)
-        {
-            // Logical shift left.
-            (yyval) = static_cast<YYSTYPE>(static_cast<UNSIGNED_TYPE>((yyvsp[-2])) << (yyvsp[0]));
-        }
         else
         {
-            (yyval) = (yyvsp[-2]) << (yyvsp[0]);
+            // Logical shift left. Casting to unsigned is needed to ensure there's no signed integer
+            // overflow, which some tools treat as an error.
+            (yyval) = static_cast<YYSTYPE>(static_cast<UNSIGNED_TYPE>((yyvsp[-2])) << (yyvsp[0]));
         }
     }
 
     break;
 
   case 20:
 
     {
--- a/gfx/angle/src/compiler/preprocessor/ExpressionParser.y
+++ b/gfx/angle/src/compiler/preprocessor/ExpressionParser.y
@@ -228,24 +228,21 @@ expression
                 std::string text = stream.str();
                 context->diagnostics->report(pp::Diagnostics::PP_UNDEFINED_SHIFT,
                                              context->token->location,
                                              text.c_str());
                 *(context->valid) = false;
             }
             $$ = static_cast<YYSTYPE>(0);
         }
-        else if ($1 < 0)
-        {
-            // Logical shift left.
-            $$ = static_cast<YYSTYPE>(static_cast<UNSIGNED_TYPE>($1) << $3);
-        }
         else
         {
-            $$ = $1 << $3;
+            // Logical shift left. Casting to unsigned is needed to ensure there's no signed integer
+            // overflow, which some tools treat as an error.
+            $$ = static_cast<YYSTYPE>(static_cast<UNSIGNED_TYPE>($1) << $3);
         }
     }
     | expression '-' expression {
         $$ = gl::WrappingDiff<YYSTYPE>($1, $3);
     }
     | expression '+' expression {
         $$ = gl::WrappingSum<YYSTYPE>($1, $3);
     }
--- a/gfx/angle/src/compiler/preprocessor/Input.cpp
+++ b/gfx/angle/src/compiler/preprocessor/Input.cpp
@@ -13,16 +13,20 @@
 
 namespace pp
 {
 
 Input::Input() : mCount(0), mString(0)
 {
 }
 
+Input::~Input()
+{
+}
+
 Input::Input(size_t count, const char *const string[], const int length[])
     : mCount(count), mString(string)
 {
     mLength.reserve(mCount);
     for (size_t i = 0; i < mCount; ++i)
     {
         int len = length ? length[i] : -1;
         mLength.push_back(len < 0 ? std::strlen(mString[i]) : len);
@@ -56,26 +60,36 @@ size_t Input::read(char *buf, size_t max
         const char *c = mString[mReadLoc.sIndex] + mReadLoc.cIndex;
         if ((*c) == '\\')
         {
             c = skipChar();
             if (c != nullptr && (*c) == '\n')
             {
                 // Line continuation of backslash + newline.
                 skipChar();
+                // Fake an EOF if the line number would overflow.
+                if (*lineNo == INT_MAX)
+                {
+                    return 0;
+                }
                 ++(*lineNo);
             }
             else if (c != nullptr && (*c) == '\r')
             {
                 // Line continuation. Could be backslash + '\r\n' or just backslash + '\r'.
                 c = skipChar();
                 if (c != nullptr && (*c) == '\n')
                 {
                     skipChar();
                 }
+                // Fake an EOF if the line number would overflow.
+                if (*lineNo == INT_MAX)
+                {
+                    return 0;
+                }
                 ++(*lineNo);
             }
             else
             {
                 // Not line continuation, so write the skipped backslash to buf.
                 *buf = '\\';
                 ++nRead;
             }
--- a/gfx/angle/src/compiler/preprocessor/Input.h
+++ b/gfx/angle/src/compiler/preprocessor/Input.h
@@ -13,16 +13,17 @@
 namespace pp
 {
 
 // Holds and reads input for Lexer.
 class Input
 {
   public:
     Input();
+    ~Input();
     Input(size_t count, const char *const string[], const int length[]);
 
     size_t count() const { return mCount; }
     const char *string(size_t index) const { return mString[index]; }
     size_t length(size_t index) const { return mLength[index]; }
 
     size_t read(char *buf, size_t maxSize, int *lineNo);
 
--- a/gfx/angle/src/compiler/preprocessor/Macro.cpp
+++ b/gfx/angle/src/compiler/preprocessor/Macro.cpp
@@ -7,16 +7,24 @@
 #include "compiler/preprocessor/Macro.h"
 
 #include "common/angleutils.h"
 #include "compiler/preprocessor/Token.h"
 
 namespace pp
 {
 
+Macro::Macro() : predefined(false), disabled(false), expansionCount(0), type(kTypeObj)
+{
+}
+
+Macro::~Macro()
+{
+}
+
 bool Macro::equals(const Macro &other) const
 {
     return (type == other.type) && (name == other.name) && (parameters == other.parameters) &&
            (replacements == other.replacements);
 }
 
 void PredefineMacro(MacroSet *macroSet, const char *name, int value)
 {
--- a/gfx/angle/src/compiler/preprocessor/Macro.h
+++ b/gfx/angle/src/compiler/preprocessor/Macro.h
@@ -22,17 +22,18 @@ struct Macro
     enum Type
     {
         kTypeObj,
         kTypeFunc
     };
     typedef std::vector<std::string> Parameters;
     typedef std::vector<Token> Replacements;
 
-    Macro() : predefined(false), disabled(false), expansionCount(0), type(kTypeObj) {}
+    Macro();
+    ~Macro();
     bool equals(const Macro &other) const;
 
     bool predefined;
     mutable bool disabled;
     mutable int expansionCount;
 
     Type type;
     std::string name;
--- a/gfx/angle/src/compiler/preprocessor/MacroExpander.cpp
+++ b/gfx/angle/src/compiler/preprocessor/MacroExpander.cpp
@@ -453,16 +453,20 @@ void MacroExpander::replaceMacroParams(c
         replacements->at(iRepl).setHasLeadingSpace(repl.hasLeadingSpace());
     }
 }
 
 MacroExpander::MacroContext::MacroContext() : macro(0), index(0)
 {
 }
 
+MacroExpander::MacroContext::~MacroContext()
+{
+}
+
 bool MacroExpander::MacroContext::empty() const
 {
     return index == replacements.size();
 }
 
 const Token &MacroExpander::MacroContext::get()
 {
     return replacements[index++];
--- a/gfx/angle/src/compiler/preprocessor/MacroExpander.h
+++ b/gfx/angle/src/compiler/preprocessor/MacroExpander.h
@@ -47,16 +47,17 @@ class MacroExpander : public Lexer
                           SourceLocation *closingParenthesisLocation);
     void replaceMacroParams(const Macro &macro,
                             const std::vector<MacroArg> &args,
                             std::vector<Token> *replacements);
 
     struct MacroContext
     {
         MacroContext();
+        ~MacroContext();
         bool empty() const;
         const Token &get();
         void unget();
 
         std::shared_ptr<Macro> macro;
         std::size_t index;
         std::vector<Token> replacements;
     };
--- a/gfx/angle/src/compiler/preprocessor/Tokenizer.cpp
+++ b/gfx/angle/src/compiler/preprocessor/Tokenizer.cpp
@@ -1675,21 +1675,28 @@ case YY_STATE_EOF(COMMENT):
         scanLoc->sIndex = sIndexMax; scanLoc->cIndex = 0;
         // FIXME: this is not 64-bit clean.
         yyfileno = static_cast<int>(sIndexMax); yylineno = 1;
     }
     yylloc->file = yyfileno;
     yylloc->line = yylineno;
     yylval->clear();
 
-    if (YY_START == COMMENT)
+    // Line number overflows fake EOFs to exit early, check for this case.
+    if (yylineno == INT_MAX)
+    {
+        yyextra->diagnostics->report(pp::Diagnostics::PP_TOKENIZER_ERROR,
+                                     pp::SourceLocation(yyfileno, yylineno),
+                                     "Integer overflow on line number");
+    }
+    else if (YY_START == COMMENT)
     {
         yyextra->diagnostics->report(pp::Diagnostics::PP_EOF_IN_COMMENT,
                                      pp::SourceLocation(yyfileno, yylineno),
-                                     "");
+                                     "EOF while in a comment");
     }
     yyterminate();
 }
 	YY_BREAK
 case 37:
 YY_RULE_SETUP
 ECHO;
 	YY_BREAK
--- a/gfx/angle/src/compiler/preprocessor/Tokenizer.h
+++ b/gfx/angle/src/compiler/preprocessor/Tokenizer.h
@@ -29,17 +29,17 @@ class Tokenizer : public Lexer
         // if text is buffered up in the scanner input buffer.
         Input::Location scanLoc;
 
         bool leadingSpace;
         bool lineStart;
     };
 
     Tokenizer(Diagnostics *diagnostics);
-    ~Tokenizer();
+    ~Tokenizer() override;
 
     bool init(size_t count, const char *const string[], const int length[]);
 
     void setFileNumber(int file);
     void setLineNumber(int line);
     void setMaxTokenSize(size_t maxTokenSize);
 
     void lex(Token *token) override;
--- a/gfx/angle/src/compiler/preprocessor/Tokenizer.l
+++ b/gfx/angle/src/compiler/preprocessor/Tokenizer.l
@@ -272,21 +272,27 @@ FRACTIONAL_CONSTANT  ({DIGIT}*"."{DIGIT}
         scanLoc->sIndex = sIndexMax; scanLoc->cIndex = 0;
         // FIXME: this is not 64-bit clean.
         yyfileno = static_cast<int>(sIndexMax); yylineno = 1;
     }
     yylloc->file = yyfileno;
     yylloc->line = yylineno;
     yylval->clear();
 
-    if (YY_START == COMMENT)
+    // Line number overflows fake EOFs to exit early, check for this case.
+    if (yylineno == INT_MAX) {
+        yyextra->diagnostics->report(pp::Diagnostics::PP_TOKENIZER_ERROR,
+                pp::SourceLocation(yyfileno, yylineno),
+                "Integer overflow on line number");
+    }
+    else if (YY_START == COMMENT)
     {
         yyextra->diagnostics->report(pp::Diagnostics::PP_EOF_IN_COMMENT,
                                      pp::SourceLocation(yyfileno, yylineno),
-                                     "");
+                                     "EOF while in a comment");
     }
     yyterminate();
 }
 
 %%
 
 namespace pp {
 
--- a/gfx/angle/src/compiler/translator/ASTMetadataHLSL.cpp
+++ b/gfx/angle/src/compiler/translator/ASTMetadataHLSL.cpp
@@ -114,27 +114,27 @@ class PullGradient : public TIntermTrave
     }
 
     bool visitAggregate(Visit visit, TIntermAggregate *node) override
     {
         if (visit == PreVisit)
         {
             if (node->getOp() == EOpCallFunctionInAST)
             {
-                size_t calleeIndex = mDag.findIndex(node->getFunctionSymbolInfo());
+                size_t calleeIndex = mDag.findIndex(node->getFunction()->uniqueId());
                 ASSERT(calleeIndex != CallDAG::InvalidIndex && calleeIndex < mIndex);
 
                 if ((*mMetadataList)[calleeIndex].mUsesGradient)
                 {
                     onGradient();
                 }
             }
             else if (node->getOp() == EOpCallBuiltInFunction)
             {
-                if (mGradientBuiltinFunctions.find(node->getFunctionSymbolInfo()->getName()) !=
+                if (mGradientBuiltinFunctions.find(node->getFunction()->name()) !=
                     mGradientBuiltinFunctions.end())
                 {
                     onGradient();
                 }
             }
         }
 
         return true;
@@ -283,17 +283,17 @@ class PullComputeDiscontinuousAndGradien
 
         return true;
     }
 
     bool visitAggregate(Visit visit, TIntermAggregate *node) override
     {
         if (visit == PreVisit && node->getOp() == EOpCallFunctionInAST)
         {
-            size_t calleeIndex = mDag.findIndex(node->getFunctionSymbolInfo());
+            size_t calleeIndex = mDag.findIndex(node->getFunction()->uniqueId());
             ASSERT(calleeIndex != CallDAG::InvalidIndex && calleeIndex < mIndex);
 
             if ((*mMetadataList)[calleeIndex].mHasGradientLoopInCallGraph)
             {
                 onGradientLoop();
             }
         }
 
@@ -362,17 +362,17 @@ class PushDiscontinuousLoops : public TI
 
     bool visitAggregate(Visit visit, TIntermAggregate *node) override
     {
         switch (node->getOp())
         {
             case EOpCallFunctionInAST:
                 if (visit == PreVisit && mNestedDiscont > 0)
                 {
-                    size_t calleeIndex = mDag.findIndex(node->getFunctionSymbolInfo());
+                    size_t calleeIndex = mDag.findIndex(node->getFunction()->uniqueId());
                     ASSERT(calleeIndex != CallDAG::InvalidIndex && calleeIndex < mIndex);
 
                     (*mMetadataList)[calleeIndex].mCalledInDiscontinuousLoop = true;
                 }
                 break;
             default:
                 break;
         }
--- a/gfx/angle/src/compiler/translator/ArrayReturnValueToOutParameter.cpp
+++ b/gfx/angle/src/compiler/translator/ArrayReturnValueToOutParameter.cpp
@@ -5,17 +5,19 @@
 //
 // 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
 {
 
@@ -23,72 +25,79 @@ void CopyAggregateChildren(TIntermAggreg
 {
     const TIntermSequence *fromSequence = from->getSequence();
     for (size_t ii = 0; ii < fromSequence->size(); ++ii)
     {
         to->getSequence()->push_back(fromSequence->at(ii));
     }
 }
 
-TIntermSymbol *CreateReturnValueSymbol(const TSymbolUniqueId &id, const TType &type)
-{
-    TIntermSymbol *node = new TIntermSymbol(id.get(), "angle_return", type);
-    node->setInternal(true);
-    node->getTypePointer()->setQualifier(EvqOut);
-    return node;
-}
-
-TIntermAggregate *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);
-    TIntermAggregate *replacementCall = TIntermAggregate::CreateFunctionCall(
-        TType(EbtVoid), originalCall->getFunctionSymbolInfo()->getId(),
-        originalCall->getFunctionSymbolInfo()->getNameObj(), replacementArguments);
-    replacementCall->setLine(originalCall->getLine());
-    return replacementCall;
-}
-
 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;
 
-    // Map from function symbol ids to array return value ids.
-    std::map<int, TSymbolUniqueId *> mReturnValueIds;
+    struct ChangedFunction
+    {
+        const TVariable *returnValueVariable;
+        const TFunction *func;
+    };
+
+    // Map from function symbol ids to the changed function.
+    std::map<int, ChangedFunction> mChangedFunctions;
+
+    const TString *const mReturnValueVariableName;
 };
 
+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)
+    : TIntermTraverser(true, false, true, symbolTable),
+      mFunctionWithArrayReturnValue(nullptr),
+      mReturnValueVariableName(NewPoolTString("angle_return"))
 {
 }
 
 bool ArrayReturnValueToOutParameterTraverser::visitFunctionDefinition(
     Visit visit,
     TIntermFunctionDefinition *node)
 {
     if (node->getFunctionPrototype()->isArray() && visit == PreVisit)
@@ -105,27 +114,35 @@ bool ArrayReturnValueToOutParameterTrave
 
 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.
-        TIntermFunctionPrototype *replacement =
-            new TIntermFunctionPrototype(TType(EbtVoid), node->getFunctionSymbolInfo()->getId());
-        CopyAggregateChildren(node, replacement);
-        const TSymbolUniqueId &functionId = node->getFunctionSymbolInfo()->getId();
-        if (mReturnValueIds.find(functionId.get()) == mReturnValueIds.end())
+        const TSymbolUniqueId &functionId = node->getFunction()->uniqueId();
+        if (mChangedFunctions.find(functionId.get()) == mChangedFunctions.end())
         {
-            mReturnValueIds[functionId.get()] = new TSymbolUniqueId(mSymbolTable);
+            TType returnValueVariableType(node->getType());
+            returnValueVariableType.setQualifier(EvqOut);
+            ChangedFunction changedFunction;
+            changedFunction.returnValueVariable =
+                new TVariable(mSymbolTable, mReturnValueVariableName, returnValueVariableType,
+                              SymbolType::AngleInternal);
+            changedFunction.func = new TFunction(mSymbolTable, &node->getFunction()->name(),
+                                                 StaticType::GetBasic<EbtVoid>(),
+                                                 node->getFunction()->symbolType(), false);
+            mChangedFunctions[functionId.get()] = changedFunction;
         }
+        TIntermFunctionPrototype *replacement =
+            new TIntermFunctionPrototype(mChangedFunctions[functionId.get()].func);
+        CopyAggregateChildren(node, replacement);
         replacement->getSequence()->push_back(
-            CreateReturnValueSymbol(*mReturnValueIds[functionId.get()], node->getType()));
-        *replacement->getFunctionSymbolInfo() = *node->getFunctionSymbolInfo();
+            new TIntermSymbol(mChangedFunctions[functionId.get()].returnValueVariable));
         replacement->setLine(node->getLine());
 
         queueReplacement(replacement, OriginalNode::IS_DROPPED);
     }
     return false;
 }
 
 bool ArrayReturnValueToOutParameterTraverser::visitAggregate(Visit visit, TIntermAggregate *node)
@@ -140,21 +157,31 @@ bool ArrayReturnValueToOutParameterTrave
         // 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)
         {
-            nextTemporaryId();
+            // replace
+            //   f();
+            // with
+            //   type s0[size]; f(s0);
             TIntermSequence replacements;
-            replacements.push_back(createTempDeclaration(node->getType()));
-            TIntermSymbol *returnSymbol = createTempSymbol(node->getType());
-            replacements.push_back(CreateReplacementCall(node, returnSymbol));
+
+            // type s0[size];
+            TIntermDeclaration *returnValueDeclaration = nullptr;
+            TVariable *returnValue = DeclareTempVariable(mSymbolTable, 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;
 }
 
@@ -163,21 +190,20 @@ bool ArrayReturnValueToOutParameterTrave
     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->getFunctionSymbolInfo()->getId();
-        ASSERT(mReturnValueIds.find(functionId.get()) != mReturnValueIds.end());
-        const TSymbolUniqueId &returnValueId = *mReturnValueIds[functionId.get()];
+            mFunctionWithArrayReturnValue->getFunction()->uniqueId();
+        ASSERT(mChangedFunctions.find(functionId.get()) != mChangedFunctions.end());
         TIntermSymbol *returnValueSymbol =
-            CreateReturnValueSymbol(returnValueId, expression->getType());
+            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);
@@ -191,17 +217,17 @@ bool ArrayReturnValueToOutParameterTrave
 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());
+            TIntermAggregate *replacementCall = createReplacementCall(rightAgg, node->getLeft());
             queueReplacement(replacementCall, OriginalNode::IS_DROPPED);
         }
     }
     return false;
 }
 
 }  // namespace
 
--- a/gfx/angle/src/compiler/translator/BaseTypes.h
+++ b/gfx/angle/src/compiler/translator/BaseTypes.h
@@ -124,68 +124,105 @@ enum TBasicType
     EbtAddress,  // should be deprecated??
 
     EbtAtomicCounter,
 
     // end of list
     EbtLast
 };
 
-inline TBasicType convertGImageToFloatImage(TBasicType type)
+constexpr const char *GetBasicMangledName(TBasicType t)
 {
-    switch (type)
-    {
-        case EbtGImage2D:
-            return EbtImage2D;
-        case EbtGImage3D:
-            return EbtImage3D;
-        case EbtGImage2DArray:
-            return EbtImage2DArray;
-        case EbtGImageCube:
-            return EbtImageCube;
-        default:
-            UNREACHABLE();
-    }
-    return EbtLast;
-}
-
-inline TBasicType convertGImageToIntImage(TBasicType type)
-{
-    switch (type)
+    switch (t)
     {
-        case EbtGImage2D:
-            return EbtIImage2D;
-        case EbtGImage3D:
-            return EbtIImage3D;
-        case EbtGImage2DArray:
-            return EbtIImage2DArray;
-        case EbtGImageCube:
-            return EbtIImageCube;
+        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:
-            UNREACHABLE();
+            // EbtVoid, EbtAddress and non types
+            return "";
     }
-    return EbtLast;
-}
-
-inline TBasicType convertGImageToUnsignedImage(TBasicType type)
-{
-    switch (type)
-    {
-        case EbtGImage2D:
-            return EbtUImage2D;
-        case EbtGImage3D:
-            return EbtUImage3D;
-        case EbtGImage2DArray:
-            return EbtUImage2DArray;
-        case EbtGImageCube:
-            return EbtUImageCube;
-        default:
-            UNREACHABLE();
-    }
-    return EbtLast;
 }
 
 const char *getBasicString(TBasicType t);
 
 inline bool IsSampler(TBasicType type)
 {
     return type > EbtGuardSamplerBegin && type < EbtGuardSamplerEnd;
 }
@@ -472,16 +509,116 @@ inline bool IsShadowSampler(TBasicType t
             return false;
         default:
             assert(!IsSampler(type));
     }
 
     return false;
 }
 
+inline bool IsImage2D(TBasicType type)
+{
+    switch (type)
+    {
+        case EbtImage2D:
+        case EbtIImage2D:
+        case EbtUImage2D:
+            return true;
+        case EbtImage3D:
+        case EbtIImage3D:
+        case EbtUImage3D:
+        case EbtImage2DArray:
+        case EbtIImage2DArray:
+        case EbtUImage2DArray:
+        case EbtImageCube:
+        case EbtIImageCube:
+        case EbtUImageCube:
+            return false;
+        default:
+            assert(!IsImage(type));
+    }
+
+    return false;
+}
+
+inline bool IsImage3D(TBasicType type)
+{
+    switch (type)
+    {
+        case EbtImage3D:
+        case EbtIImage3D:
+        case EbtUImage3D:
+            return true;
+        case EbtImage2D:
+        case EbtIImage2D:
+        case EbtUImage2D:
+        case EbtImage2DArray:
+        case EbtIImage2DArray:
+        case EbtUImage2DArray:
+        case EbtImageCube:
+        case EbtIImageCube:
+        case EbtUImageCube:
+            return false;
+        default:
+            assert(!IsImage(type));
+    }
+
+    return false;
+}
+
+inline bool IsImage2DArray(TBasicType type)
+{
+    switch (type)
+    {
+        case EbtImage2DArray:
+        case EbtIImage2DArray:
+        case EbtUImage2DArray:
+            return true;
+        case EbtImage2D:
+        case EbtIImage2D:
+        case EbtUImage2D:
+        case EbtImage3D:
+        case EbtIImage3D:
+        case EbtUImage3D:
+        case EbtImageCube:
+        case EbtIImageCube:
+        case EbtUImageCube:
+            return false;
+        default:
+            assert(!IsImage(type));
+    }
+
+    return false;
+}
+
+inline bool IsImageCube(TBasicType type)
+{
+    switch (type)
+    {
+        case EbtImageCube:
+        case EbtIImageCube:
+        case EbtUImageCube:
+            return true;
+        case EbtImage2D:
+        case EbtIImage2D:
+        case EbtUImage2D:
+        case EbtImage3D:
+        case EbtIImage3D:
+        case EbtUImage3D:
+        case EbtImage2DArray:
+        case EbtIImage2DArray:
+        case EbtUImage2DArray:
+            return false;
+        default:
+            assert(!IsImage(type));
+    }
+
+    return false;
+}
+
 inline bool IsInteger(TBasicType type)
 {
     return type == EbtInt || type == EbtUInt;
 }
 
 inline bool SupportsPrecision(TBasicType type)
 {
     return type == EbtFloat || type == EbtInt || type == EbtUInt || IsOpaqueType(type);
@@ -568,17 +705,17 @@ enum TQualifier
 
     // GLSL ES 3.1 memory qualifiers
     EvqReadOnly,
     EvqWriteOnly,
     EvqCoherent,
     EvqRestrict,
     EvqVolatile,
 
-    // GLSL ES 3.1 extension OES_geometry_shader qualifiers
+    // GLSL ES 3.1 extension EXT_geometry_shader qualifiers
     EvqGeometryIn,
     EvqGeometryOut,
     EvqPerVertexIn,    // gl_in
     EvqPrimitiveIDIn,  // gl_PrimitiveIDIn
     EvqInvocationID,   // gl_InvocationID
     EvqPrimitiveID,    // gl_PrimitiveID
     EvqLayer,          // gl_Layer
 
@@ -616,17 +753,18 @@ enum TLayoutMatrixPacking
     EmpColumnMajor
 };
 
 enum TLayoutBlockStorage
 {
     EbsUnspecified,
     EbsShared,
     EbsPacked,
-    EbsStd140
+    EbsStd140,
+    EbsStd430
 };
 
 enum TYuvCscStandardEXT
 {
     EycsUndefined,
     EycsItu601,
     EycsItu601FullRange,
     EycsItu709
@@ -641,64 +779,20 @@ enum TLayoutPrimitiveType
     EptTriangles,
     EptTrianglesAdjacency,
     EptLineStrip,
     EptTriangleStrip
 };
 
 struct TLayoutQualifier
 {
-    int location;
-    unsigned int locationsSpecified;
-    TLayoutMatrixPacking matrixPacking;
-    TLayoutBlockStorage blockStorage;
-
-    // Compute shader layout qualifiers.
-    sh::WorkGroupSize localSize;
-
-    int binding;
-    int offset;
-
-    // Image format layout qualifier
-    TLayoutImageInternalFormat imageInternalFormat;
-
-    // OVR_multiview num_views.
-    int numViews;
-
-    // EXT_YUV_target yuv layout qualifier.
-    bool yuv;
+    // Must have a trivial default constructor since it is used in YYSTYPE.
+    TLayoutQualifier() = default;
 
-    // OES_geometry_shader layout qualifiers.
-    TLayoutPrimitiveType primitiveType;
-    int invocations;
-    int maxVertices;
-
-    static TLayoutQualifier create()
-    {
-        TLayoutQualifier layoutQualifier;
-
-        layoutQualifier.location           = -1;
-        layoutQualifier.locationsSpecified = 0;
-        layoutQualifier.matrixPacking      = EmpUnspecified;
-        layoutQualifier.blockStorage       = EbsUnspecified;
-
-        layoutQualifier.localSize.fill(-1);
-        layoutQualifier.binding  = -1;
-        layoutQualifier.offset   = -1;
-        layoutQualifier.numViews = -1;
-        layoutQualifier.yuv      = false;
-
-        layoutQualifier.imageInternalFormat = EiifUnspecified;
-
-        layoutQualifier.primitiveType = EptUndefined;
-        layoutQualifier.invocations   = 0;
-        layoutQualifier.maxVertices   = -1;
-
-        return layoutQualifier;
-    }
+    constexpr static TLayoutQualifier Create() { return TLayoutQualifier(0); }
 
     bool isEmpty() const
     {
         return location == -1 && binding == -1 && offset == -1 && numViews == -1 && yuv == false &&
                matrixPacking == EmpUnspecified && blockStorage == EbsUnspecified &&
                !localSize.isAnyValueSet() && imageInternalFormat == EiifUnspecified &&
                primitiveType == EptUndefined && invocations == 0 && maxVertices == -1;
     }
@@ -715,50 +809,96 @@ struct TLayoutQualifier
 
         // we can have either the work group size specified, or number of views,
         // or yuv layout qualifier, or the other layout qualifiers.
         return (workSizeSpecified ? 1 : 0) + (numViewsSet ? 1 : 0) + (yuv ? 1 : 0) +
                    (otherLayoutQualifiersSpecified ? 1 : 0) + (geometryShaderSpecified ? 1 : 0) <=
                1;
     }
 
-    bool isLocalSizeEqual(const sh::WorkGroupSize &localSizeIn) const
+    bool isLocalSizeEqual(const WorkGroupSize &localSizeIn) const
     {
         return localSize.isWorkGroupSizeMatching(localSizeIn);
     }
+
+    int location;
+    unsigned int locationsSpecified;
+    TLayoutMatrixPacking matrixPacking;
+    TLayoutBlockStorage blockStorage;
+
+    // Compute shader layout qualifiers.
+    WorkGroupSize localSize;
+
+    int binding;
+    int offset;
+
+    // Image format layout qualifier
+    TLayoutImageInternalFormat imageInternalFormat;
+
+    // OVR_multiview num_views.
+    int numViews;
+
+    // EXT_YUV_target yuv layout qualifier.
+    bool yuv;
+
+    // OES_geometry_shader layout qualifiers.
+    TLayoutPrimitiveType primitiveType;
+    int invocations;
+    int maxVertices;
+
+  private:
+    explicit constexpr TLayoutQualifier(int /*placeholder*/)
+        : location(-1),
+          locationsSpecified(0),
+          matrixPacking(EmpUnspecified),
+          blockStorage(EbsUnspecified),
+          localSize(-1),
+          binding(-1),
+          offset(-1),
+          imageInternalFormat(EiifUnspecified),
+          numViews(-1),
+          yuv(false),
+          primitiveType(EptUndefined),
+          invocations(0),
+          maxVertices(-1)
+    {
+    }
 };
 
 struct TMemoryQualifier
 {
+    // Must have a trivial default constructor since it is used in YYSTYPE.
+    TMemoryQualifier() = default;
+
+    bool isEmpty() const
+    {
+        return !readonly && !writeonly && !coherent && !restrictQualifier && !volatileQualifier;
+    }
+
+    constexpr static TMemoryQualifier Create() { return TMemoryQualifier(0); }
+
     // GLSL ES 3.10 Revision 4, 4.9 Memory Access Qualifiers
     // An image can be qualified as both readonly and writeonly. It still can be can be used with
     // imageSize().
     bool readonly;
     bool writeonly;
     bool coherent;
 
     // restrict and volatile are reserved keywords in C/C++
     bool restrictQualifier;
     bool volatileQualifier;
-    static TMemoryQualifier create()
+
+  private:
+    explicit constexpr TMemoryQualifier(int /*placeholder*/)
+        : readonly(false),
+          writeonly(false),
+          coherent(false),
+          restrictQualifier(false),
+          volatileQualifier(false)
     {
-        TMemoryQualifier memoryQualifier;
-
-        memoryQualifier.readonly          = false;
-        memoryQualifier.writeonly         = false;
-        memoryQualifier.coherent          = false;
-        memoryQualifier.restrictQualifier = false;
-        memoryQualifier.volatileQualifier = false;
-
-        return memoryQualifier;
-    }
-
-    bool isEmpty()
-    {
-        return !readonly && !writeonly && !coherent && !restrictQualifier && !volatileQualifier;
     }
 };
 
 inline const char *getWorkGroupSizeString(size_t dimension)
 {
     switch (dimension)
     {
         case 0u:
@@ -865,16 +1005,18 @@ inline const char *getBlockStorageString
         case EbsUnspecified:
             return "bs_unspecified";
         case EbsShared:
             return "shared";
         case EbsPacked:
             return "packed";
         case EbsStd140:
             return "std140";
+        case EbsStd430:
+            return "std430";
         default:
             UNREACHABLE();
             return "unknown block storage";
     }
 }
 
 inline const char *getImageInternalFormatString(TLayoutImageInternalFormat iifq)
 {
--- a/gfx/angle/src/compiler/translator/BuiltInFunctionEmulator.cpp
+++ b/gfx/angle/src/compiler/translator/BuiltInFunctionEmulator.cpp
@@ -1,19 +1,19 @@
 //
 // 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/Cache.h"
 #include "compiler/translator/IntermTraverse.h"
 #include "compiler/translator/SymbolTable.h"
+#include "compiler/translator/StaticType.h"
 
 namespace sh
 {
 
 class BuiltInFunctionEmulator::BuiltInFunctionEmulationMarker : public TIntermTraverser
 {
   public:
     BuiltInFunctionEmulationMarker(BuiltInFunctionEmulator &emulator)
@@ -281,43 +281,47 @@ void BuiltInFunctionEmulator::addFunctio
 void BuiltInFunctionEmulator::WriteEmulatedFunctionName(TInfoSinkBase &out, const char *name)
 {
     ASSERT(name[strlen(name) - 1] != '(');
     out << name << "_emu";
 }
 
 FunctionId::FunctionId()
     : mOp(EOpNull),
-      mParam1(TCache::getType(EbtVoid)),
-      mParam2(TCache::getType(EbtVoid)),
-      mParam3(TCache::getType(EbtVoid)),
-      mParam4(TCache::getType(EbtVoid))
+      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(TCache::getType(EbtVoid)),
-      mParam3(TCache::getType(EbtVoid)),
-      mParam4(TCache::getType(EbtVoid))
+      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(TCache::getType(EbtVoid)),
-      mParam4(TCache::getType(EbtVoid))
+      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(TCache::getType(EbtVoid))
+    : 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)
--- a/gfx/angle/src/compiler/translator/BuiltInFunctionEmulatorGLSL.cpp
+++ b/gfx/angle/src/compiler/translator/BuiltInFunctionEmulatorGLSL.cpp
@@ -1,45 +1,45 @@
 //
 // 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/BuiltInFunctionEmulatorGLSL.h"
-#include "compiler/translator/Cache.h"
 #include "compiler/translator/SymbolTable.h"
+#include "compiler/translator/StaticType.h"
 #include "compiler/translator/VersionGLSL.h"
 
 namespace sh
 {
 
 void InitBuiltInAbsFunctionEmulatorForGLSLWorkarounds(BuiltInFunctionEmulator *emu,
                                                       sh::GLenum shaderType)
 {
     if (shaderType == GL_VERTEX_SHADER)
     {
-        const TType *int1 = TCache::getType(EbtInt);
+        const TType *int1 = StaticType::GetBasic<EbtInt>();
         emu->addEmulatedFunction(EOpAbs, 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 = TCache::getType(EbtFloat);
-    const TType *float2 = TCache::getType(EbtFloat, 2);
-    const TType *float3 = TCache::getType(EbtFloat, 3);
-    const TType *float4 = TCache::getType(EbtFloat, 4);
+    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,
         "bool isnan_emu(float x) { return (x > 0.0 || x < 0.0) ? false : x != 0.0; }");
     emu->addEmulatedFunction(
         EOpIsNan, float2,
         "bvec2 isnan_emu(vec2 x)\n"
@@ -72,30 +72,37 @@ void InitBuiltInIsnanFunctionEmulatorFor
         "        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 = TCache::getType(EbtFloat);
+    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>(),
+    };
     for (int dim = 2; dim <= 4; ++dim)
     {
-        const TType *floatVec = TCache::getType(EbtFloat, static_cast<unsigned char>(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)
         {
@@ -115,18 +122,18 @@ void InitBuiltInAtanFunctionEmulatorForG
 // 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 = TCache::getType(EbtFloat, 2);
-        const TType *uint1  = TCache::getType(EbtUInt);
+        const TType *float2 = StaticType::GetBasic<EbtFloat, 2>();
+        const TType *uint1  = StaticType::GetBasic<EbtUInt>();
 
         // clang-format off
         emu->addEmulatedFunction(EOpPackUnorm2x16, 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"
@@ -141,18 +148,18 @@ void InitBuiltInFunctionEmulatorForGLSLM
             "}\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 = TCache::getType(EbtFloat, 2);
-        const TType *uint1  = TCache::getType(EbtUInt);
+        const TType *float2 = StaticType::GetBasic<EbtFloat, 2>();
+        const TType *uint1  = StaticType::GetBasic<EbtUInt>();
 
         // clang-format off
         emu->addEmulatedFunction(EOpPackSnorm2x16, float2,
             "uint packSnorm2x16_emu(vec2 v)\n"
             "{\n"
             "    #if defined(GL_ARB_shading_language_packing)\n"
             "        return packSnorm2x16(v);\n"
             "    #else\n"
deleted file mode 100644
--- a/gfx/angle/src/compiler/translator/Cache.cpp
+++ /dev/null
@@ -1,95 +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.
-//
-
-// Cache.cpp: Implements a cache for various commonly created objects.
-
-#include <limits>
-
-#include "common/angleutils.h"
-#include "common/debug.h"
-#include "compiler/translator/Cache.h"
-
-namespace sh
-{
-
-namespace
-{
-
-class TScopedAllocator : angle::NonCopyable
-{
-  public:
-    TScopedAllocator(TPoolAllocator *allocator) : mPreviousAllocator(GetGlobalPoolAllocator())
-    {
-        SetGlobalPoolAllocator(allocator);
-    }
-    ~TScopedAllocator() { SetGlobalPoolAllocator(mPreviousAllocator); }
-
-  private:
-    TPoolAllocator *mPreviousAllocator;
-};
-
-}  // namespace
-
-TCache::TypeKey::TypeKey(TBasicType basicType,
-                         TPrecision precision,
-                         TQualifier qualifier,
-                         unsigned char primarySize,
-                         unsigned char secondarySize)
-{
-    static_assert(sizeof(components) <= sizeof(value), "TypeKey::value is too small");
-
-    const size_t MaxEnumValue = std::numeric_limits<EnumComponentType>::max();
-
-    // TODO: change to static_assert() once we deprecate MSVC 2013 support
-    ASSERT(MaxEnumValue >= EbtLast && MaxEnumValue >= EbpLast && MaxEnumValue >= EvqLast &&
-           "TypeKey::EnumComponentType is too small");
-
-    value                    = 0;
-    components.basicType     = static_cast<EnumComponentType>(basicType);
-    components.precision     = static_cast<EnumComponentType>(precision);
-    components.qualifier     = static_cast<EnumComponentType>(qualifier);
-    components.primarySize   = primarySize;
-    components.secondarySize = secondarySize;
-}
-
-TCache *TCache::sCache = nullptr;
-
-void TCache::initialize()
-{
-    if (sCache == nullptr)
-    {
-        sCache = new TCache();
-    }
-}
-
-void TCache::destroy()
-{
-    SafeDelete(sCache);
-}
-
-const TType *TCache::getType(TBasicType basicType,
-                             TPrecision precision,
-                             TQualifier qualifier,
-                             unsigned char primarySize,
-                             unsigned char secondarySize)
-{
-    TypeKey key(basicType, precision, qualifier, primarySize, secondarySize);
-    auto it = sCache->mTypes.find(key);
-    if (it != sCache->mTypes.end())
-    {
-        return it->second;
-    }
-
-    TScopedAllocator scopedAllocator(&sCache->mAllocator);
-
-    TType *type = new TType(basicType, precision, qualifier, primarySize, secondarySize);
-    type->realize();
-    sCache->mTypes.insert(std::make_pair(key, type));
-
-    return type;
-}
-
-}  // namespace sh
deleted file mode 100644
--- a/gfx/angle/src/compiler/translator/Cache.h
+++ /dev/null
@@ -1,84 +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.
-//
-
-// Cache.h: Implements a cache for various commonly created objects.
-
-#ifndef COMPILER_TRANSLATOR_CACHE_H_
-#define COMPILER_TRANSLATOR_CACHE_H_
-
-#include <stdint.h>
-#include <string.h>
-#include <map>
-
-#include "compiler/translator/Types.h"
-#include "compiler/translator/PoolAlloc.h"
-
-namespace sh
-{
-
-class TCache
-{
-  public:
-    static void initialize();
-    static void destroy();
-
-    static const TType *getType(TBasicType basicType, TPrecision precision)
-    {
-        return getType(basicType, precision, EvqTemporary, 1, 1);
-    }
-    static const TType *getType(TBasicType basicType,
-                                unsigned char primarySize   = 1,
-                                unsigned char secondarySize = 1)
-    {
-        return getType(basicType, EbpUndefined, EvqGlobal, primarySize, secondarySize);
-    }
-    static const TType *getType(TBasicType basicType,
-                                TQualifier qualifier,
-                                unsigned char primarySize   = 1,
-                                unsigned char secondarySize = 1)
-    {
-        return getType(basicType, EbpUndefined, qualifier, primarySize, secondarySize);
-    }
-    static const TType *getType(TBasicType basicType,
-                                TPrecision precision,
-                                TQualifier qualifier,
-                                unsigned char primarySize,
-                                unsigned char secondarySize);
-
-  private:
-    TCache() {}
-
-    union TypeKey {
-        TypeKey(TBasicType basicType,
-                TPrecision precision,
-                TQualifier qualifier,
-                unsigned char primarySize,
-                unsigned char secondarySize);
-
-        typedef uint8_t EnumComponentType;
-        struct
-        {
-            EnumComponentType basicType;
-            EnumComponentType precision;
-            EnumComponentType qualifier;
-            unsigned char primarySize;
-            unsigned char secondarySize;
-        } components;
-        uint64_t value;
-
-        bool operator<(const TypeKey &other) const { return value < other.value; }
-    };
-    typedef std::map<TypeKey, const TType *> TypeMap;
-
-    TypeMap mTypes;
-    TPoolAllocator mAllocator;
-
-    static TCache *sCache;
-};
-
-}  // namespace sh
-
-#endif  // COMPILER_TRANSLATOR_CACHE_H_
--- a/gfx/angle/src/compiler/translator/CallDAG.cpp
+++ b/gfx/angle/src/compiler/translator/CallDAG.cpp
@@ -18,30 +18,30 @@ namespace sh
 {
 
 // The CallDAGCreator does all the processing required to create the CallDAG
 // structure so that the latter contains only the necessary variables.
 class CallDAG::CallDAGCreator : public TIntermTraverser
 {
   public:
     CallDAGCreator(TDiagnostics *diagnostics)
-        : TIntermTraverser(true, false, true),
+        : TIntermTraverser(true, false, false),
           mDiagnostics(diagnostics),
           mCurrentFunction(nullptr),
           mCurrentIndex(0)
     {
     }
 
     InitResult assignIndices()
     {
         int skipped = 0;
         for (auto &it : mFunctions)
         {
             // Skip unimplemented functions
-            if (it.second.node)
+            if (it.second.definitionNode)
             {
                 InitResult result = assignIndicesInternal(&it.second);
                 if (result != INITDAG_SUCCESS)
                 {
                     return result;
                 }
             }
             else
@@ -60,100 +60,90 @@ class CallDAG::CallDAGCreator : public T
         ASSERT(idToIndex->empty());
 
         records->resize(mCurrentIndex);
 
         for (auto &it : mFunctions)
         {
             CreatorFunctionData &data = it.second;
             // Skip unimplemented functions
-            if (!data.node)
+            if (!data.definitionNode)
             {
                 continue;
             }
             ASSERT(data.index < records->size());
             Record &record = (*records)[data.index];
 
-            record.name = data.name.data();
-            record.node = data.node;
+            record.node = data.definitionNode;
 
             record.callees.reserve(data.callees.size());
             for (auto &callee : data.callees)
             {
                 record.callees.push_back(static_cast<int>(callee->index));
             }
 
-            (*idToIndex)[data.node->getFunctionSymbolInfo()->getId().get()] =
-                static_cast<int>(data.index);
+            (*idToIndex)[it.first] = static_cast<int>(data.index);
         }
     }
 
   private:
     struct CreatorFunctionData
     {
-        CreatorFunctionData() : node(nullptr), index(0), indexAssigned(false), visiting(false) {}
+        CreatorFunctionData()
+            : definitionNode(nullptr),
+              name(nullptr),
+              index(0),
+              indexAssigned(false),
+              visiting(false)
+        {
+        }
 
         std::set<CreatorFunctionData *> callees;
-        TIntermFunctionDefinition *node;
-        TString name;
+        TIntermFunctionDefinition *definitionNode;
+        const TString *name;
         size_t index;
         bool indexAssigned;
         bool visiting;
     };
 
     bool visitFunctionDefinition(Visit visit, TIntermFunctionDefinition *node) override
     {
-        // Create the record if need be and remember the node.
-        if (visit == PreVisit)
-        {
-            auto it = mFunctions.find(node->getFunctionSymbolInfo()->getId().get());
+        // Create the record if need be and remember the definition node.
+        mCurrentFunction = &mFunctions[node->getFunction()->uniqueId().get()];
+        // Name will be overwritten here. If we've already traversed the prototype of this function,
+        // it should have had the same name.
+        ASSERT(mCurrentFunction->name == nullptr ||
+               *mCurrentFunction->name == node->getFunction()->name());
+        mCurrentFunction->name           = &node->getFunction()->name();
+        mCurrentFunction->definitionNode = node;
 
-            if (it == mFunctions.end())
-            {
-                mCurrentFunction       = &mFunctions[node->getFunctionSymbolInfo()->getId().get()];
-                mCurrentFunction->name = node->getFunctionSymbolInfo()->getName();
-            }
-            else
-            {
-                mCurrentFunction = &it->second;
-                ASSERT(mCurrentFunction->name == node->getFunctionSymbolInfo()->getName());
-            }
-
-            mCurrentFunction->node = node;
-        }
-        else if (visit == PostVisit)
-        {
-            mCurrentFunction = nullptr;
-        }
-        return true;
+        node->getBody()->traverse(this);
+        mCurrentFunction = nullptr;
+        return false;
     }
 
     bool visitFunctionPrototype(Visit visit, TIntermFunctionPrototype *node) override
     {
-        ASSERT(visit == PreVisit);
-        if (mCurrentFunction != nullptr)
-        {
-            return false;
-        }
+        ASSERT(mCurrentFunction == nullptr);
 
         // Function declaration, create an empty record.
-        auto &record = mFunctions[node->getFunctionSymbolInfo()->getId().get()];
-        record.name  = node->getFunctionSymbolInfo()->getName();
+        auto &record = mFunctions[node->getFunction()->uniqueId().get()];
+        record.name  = &node->getFunction()->name();
 
         // No need to traverse the parameters.
         return false;
     }
 
-    // Aggregates the AST node for each function as well as the name of the functions called by it
+    // Track functions called from another function.
     bool visitAggregate(Visit visit, TIntermAggregate *node) override
     {
-        if (visit == PreVisit && node->getOp() == EOpCallFunctionInAST)
+        if (node->getOp() == EOpCallFunctionInAST)
         {
             // Function call, add the callees
-            auto it = mFunctions.find(node->getFunctionSymbolInfo()->getId().get());
+            auto it = mFunctions.find(node->getFunction()->uniqueId().get());
             ASSERT(it != mFunctions.end());
 
             // We might be traversing the initializer of a global variable. Even though function
             // calls in global scope are forbidden by the parser, some subsequent AST
             // transformations can add them to emulate particular features.
             if (mCurrentFunction)
             {
                 mCurrentFunction->callees.insert(&it->second);
@@ -201,19 +191,19 @@ class CallDAG::CallDAGCreator : public T
                 function->visiting      = false;
                 function->index         = mCurrentIndex++;
                 function->indexAssigned = true;
 
                 functionsToProcess.pop_back();
                 continue;
             }
 
-            if (!function->node)
+            if (!function->definitionNode)
             {
-                errorStream << "Undefined function '" << function->name
+                errorStream << "Undefined function '" << *function->name
                             << ")' used in the following call chain:";
                 result = INITDAG_UNDEFINED;
                 break;
             }
 
             if (function->indexAssigned)
             {
                 functionsToProcess.pop_back();
@@ -249,17 +239,17 @@ class CallDAG::CallDAGCreator : public T
             for (auto function : functionsToProcess)
             {
                 if (function->visiting)
                 {
                     if (!first)
                     {
                         errorStream << " -> ";
                     }
-                    errorStream << function->name << ")";
+                    errorStream << *function->name << ")";
                     first = false;
                 }
             }
             if (mDiagnostics)
             {
                 std::string errorStr = errorStream.str();
                 mDiagnostics->globalError(errorStr.c_str());
             }
@@ -282,19 +272,19 @@ CallDAG::CallDAG()
 }
 
 CallDAG::~CallDAG()
 {
 }
 
 const size_t CallDAG::InvalidIndex = std::numeric_limits<size_t>::max();
 
-size_t CallDAG::findIndex(const TFunctionSymbolInfo *functionInfo) const
+size_t CallDAG::findIndex(const TSymbolUniqueId &id) const
 {
-    auto it = mFunctionIdToIndex.find(functionInfo->getId().get());
+    auto it = mFunctionIdToIndex.find(id.get());
 
     if (it == mFunctionIdToIndex.end())
     {
         return InvalidIndex;
     }
     else
     {
         return it->second;
@@ -302,23 +292,16 @@ size_t CallDAG::findIndex(const TFunctio
 }
 
 const CallDAG::Record &CallDAG::getRecordFromIndex(size_t index) const
 {
     ASSERT(index != InvalidIndex && index < mRecords.size());
     return mRecords[index];
 }
 
-const CallDAG::Record &CallDAG::getRecord(const TIntermAggregate *function) const
-{
-    size_t index = findIndex(function->getFunctionSymbolInfo());
-    ASSERT(index != InvalidIndex && index < mRecords.size());
-    return mRecords[index];
-}
-
 size_t CallDAG::size() const
 {
     return mRecords.size();
 }
 
 void CallDAG::clear()
 {
     mRecords.clear();
--- a/gfx/angle/src/compiler/translator/CallDAG.h
+++ b/gfx/angle/src/compiler/translator/CallDAG.h
@@ -19,54 +19,52 @@ namespace sh
 {
 
 // The translator needs to analyze the the graph of the function calls
 // to run checks and analyses; since in GLSL recursion is not allowed
 // that graph is a DAG.
 // This class is used to precompute that function call DAG so that it
 // can be reused by multiple analyses.
 //
-// It stores a vector of function records, with one record per function.
+// It stores a vector of function records, with one record per defined function.
 // Records are accessed by index but a function symbol id can be converted
-// to the index of the corresponding record. The records mostly contain the
-// AST node of the function and the indices of the function's callees.
+// to the index of the corresponding record. The records contain the AST node
+// of the function definition and the indices of the function's callees.
 //
 // In addition, records are in reverse topological order: a function F being
 // called by a function G will have index index(F) < index(G), that way
 // depth-first analysis becomes analysis in the order of indices.
 
 class CallDAG : angle::NonCopyable
 {
   public:
     CallDAG();
     ~CallDAG();
 
     struct Record
     {
-        std::string name;
-        TIntermFunctionDefinition *node;
+        TIntermFunctionDefinition *node;  // Guaranteed to be non-null.
         std::vector<int> callees;
     };
 
     enum InitResult
     {
         INITDAG_SUCCESS,
         INITDAG_RECURSION,
         INITDAG_UNDEFINED,
     };
 
     // Returns INITDAG_SUCCESS if it was able to create the DAG, otherwise prints
     // the initialization error in diagnostics, if present.
     InitResult init(TIntermNode *root, TDiagnostics *diagnostics);
 
     // Returns InvalidIndex if the function wasn't found
-    size_t findIndex(const TFunctionSymbolInfo *functionInfo) const;
+    size_t findIndex(const TSymbolUniqueId &id) const;
 
     const Record &getRecordFromIndex(size_t index) const;
-    const Record &getRecord(const TIntermAggregate *function) const;
     size_t size() const;
     void clear();
 
     const static size_t InvalidIndex;
 
   private:
     std::vector<Record> mRecords;
     std::map<int, int> mFunctionIdToIndex;
--- a/gfx/angle/src/compiler/translator/ClampPointSize.cpp
+++ b/gfx/angle/src/compiler/translator/ClampPointSize.cpp
@@ -14,17 +14,17 @@
 #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, TString("gl_PointSize"), EbtFloat))
+    if (!FindSymbolNode(root, TString("gl_PointSize")))
     {
         return;
     }
 
     TIntermSymbol *pointSizeNode = ReferenceBuiltInVariable("gl_PointSize", *symbolTable, 100);
 
     TConstantUnion *maxPointSizeConstant = new TConstantUnion();
     maxPointSizeConstant->setFConst(maxPointSize);
--- a/gfx/angle/src/compiler/translator/CollectVariables.cpp
+++ b/gfx/angle/src/compiler/translator/CollectVariables.cpp
@@ -24,24 +24,26 @@ BlockLayoutType GetBlockLayoutType(TLayo
 {
     switch (blockStorage)
     {
         case EbsPacked:
             return BLOCKLAYOUT_PACKED;
         case EbsShared:
             return BLOCKLAYOUT_SHARED;
         case EbsStd140:
-            return BLOCKLAYOUT_STANDARD;
+            return BLOCKLAYOUT_STD140;
+        case EbsStd430:
+            return BLOCKLAYOUT_STD430;
         default:
             UNREACHABLE();
             return BLOCKLAYOUT_SHARED;
     }
 }
 
-// TODO(jiawei.shao@intel.com): implement GL_OES_shader_io_blocks.
+// TODO(jiawei.shao@intel.com): implement GL_EXT_shader_io_blocks.
 BlockType GetBlockType(TQualifier qualifier)
 {
     switch (qualifier)
     {
         case EvqUniform:
             return BlockType::BLOCK_UNIFORM;
         case EvqBuffer:
             return BlockType::BLOCK_BUFFER;
@@ -79,16 +81,29 @@ void MarkStaticallyUsed(ShaderVariable *
             {
                 MarkStaticallyUsed(&field);
             }
         }
         variable->staticUse = true;
     }
 }
 
+ShaderVariable *FindVariableInInterfaceBlock(const TString &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;
+    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:
     CollectVariablesTraverser(std::vector<Attribute> *attribs,
                               std::vector<OutputVariable> *outputVariables,
                               std::vector<Uniform> *uniforms,
@@ -103,26 +118,31 @@ class CollectVariablesTraverser : public
                               GLenum shaderType,
                               const TExtensionBehavior &extensionBehavior);
 
     void visitSymbol(TIntermSymbol *symbol) override;
     bool visitDeclaration(Visit, TIntermDeclaration *node) override;
     bool visitBinary(Visit visit, TIntermBinary *binaryNode) override;
 
   private:
-    std::string getMappedName(const TName &name) const;
+    std::string getMappedName(const TSymbol *symbol) const;
 
+    void setFieldOrVariableProperties(const TType &type, ShaderVariable *variableOut) const;
+    void setFieldProperties(const TType &type,
+                            const TString &name,
+                            ShaderVariable *variableOut) const;
     void setCommonVariableProperties(const TType &type,
-                                     const TName &name,
+                                     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 TType &interfaceBlockType,
+    void recordInterfaceBlock(const char *instanceName,
+                              const TType &interfaceBlockType,
                               InterfaceBlock *interfaceBlock) const;
     Uniform recordUniform(const TIntermSymbol &variable) const;
 
     void setBuiltInInfoFromSymbolTable(const char *name, ShaderVariable *info);
 
     void recordBuiltInVaryingUsed(const char *name,
                                   bool *addedFlag,
                                   std::vector<Varying> *varyings);
@@ -226,35 +246,37 @@ CollectVariablesTraverser::CollectVariab
       mLayerAdded(false),
       mHashFunction(hashFunction),
       mShaderVersion(shaderVersion),
       mShaderType(shaderType),
       mExtensionBehavior(extensionBehavior)
 {
 }
 
-std::string CollectVariablesTraverser::getMappedName(const TName &name) const
+std::string CollectVariablesTraverser::getMappedName(const TSymbol *symbol) const
 {
-    return HashName(name, mHashFunction, nullptr).c_str();
+    return HashName(symbol, mHashFunction, nullptr).c_str();
 }
 
 void CollectVariablesTraverser::setBuiltInInfoFromSymbolTable(const char *name,
                                                               ShaderVariable *info)
 {
     TVariable *symbolTableVar =
         reinterpret_cast<TVariable *>(mSymbolTable->findBuiltIn(name, mShaderVersion));
     ASSERT(symbolTableVar);
     const TType &type = symbolTableVar->getType();
 
     info->name       = name;
     info->mappedName = name;
     info->type       = GLVariableType(type);
-    ASSERT(!type.isArrayOfArrays());
-    info->arraySize = type.isArray() ? type.getOutermostArraySize() : 0;
     info->precision = GLVariablePrecision(type);
+    if (auto *arraySizes = type.getArraySizes())
+    {
+        info->arraySizes.assign(arraySizes->begin(), arraySizes->end());
+    }
 }
 
 void CollectVariablesTraverser::recordBuiltInVaryingUsed(const char *name,
                                                          bool *addedFlag,
                                                          std::vector<Varying> *varyings)
 {
     ASSERT(varyings);
     if (!(*addedFlag))
@@ -294,17 +316,17 @@ void CollectVariablesTraverser::recordBu
 }
 
 InterfaceBlock *CollectVariablesTraverser::recordGLInUsed(const TType &glInType)
 {
     if (!mPerVertexInAdded)
     {
         ASSERT(glInType.getQualifier() == EvqPerVertexIn);
         InterfaceBlock info;
-        recordInterfaceBlock(glInType, &info);
+        recordInterfaceBlock("gl_in", glInType, &info);
         info.staticUse = true;
 
         mPerVertexInAdded = true;
         mInBlocks->push_back(info);
         return &mInBlocks->back();
     }
     else
     {
@@ -316,120 +338,120 @@ InterfaceBlock *CollectVariablesTraverse
 // 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.
 void CollectVariablesTraverser::visitSymbol(TIntermSymbol *symbol)
 {
     ASSERT(symbol != nullptr);
 
-    if (symbol->getName().isInternal())
+    if (symbol->variable().symbolType() == SymbolType::AngleInternal ||
+        symbol->variable().symbolType() == SymbolType::Empty)
     {
-        // Internal variables are not collected.
+        // Internal variables or nameless variables are not collected.
         return;
     }
 
     ShaderVariable *var       = nullptr;
-    const TString &symbolName = symbol->getName().getString();
+
+    const TString &symbolName = symbol->getName();
 
-    if (IsVaryingIn(symbol->getQualifier()))
+    // Check the qualifier from the variable, not from the symbol node. The node may have a
+    // different qualifier if it's the result of a folded ternary node.
+    TQualifier qualifier = symbol->variable().getType().getQualifier();
+
+    if (IsVaryingIn(qualifier))
     {
         var = FindVariable(symbolName, mInputVaryings);
     }
-    else if (IsVaryingOut(symbol->getQualifier()))
+    else if (IsVaryingOut(qualifier))
     {
         var = FindVariable(symbolName, mOutputVaryings);
     }
     else if (symbol->getType().getBasicType() == EbtInterfaceBlock)
     {
         UNREACHABLE();
     }
     else if (symbolName == "gl_DepthRange")
     {
-        ASSERT(symbol->getQualifier() == EvqUniform);
+        ASSERT(qualifier == EvqUniform);
 
         if (!mDepthRangeAdded)
         {
             Uniform info;
             const char kName[] = "gl_DepthRange";
             info.name          = kName;
             info.mappedName    = kName;
             info.type          = GL_NONE;
-            info.arraySize     = 0;
             info.precision     = GL_NONE;
             info.staticUse     = true;
 
-            ShaderVariable nearInfo;
+            ShaderVariable nearInfo(GL_FLOAT);
             const char kNearName[] = "near";
             nearInfo.name          = kNearName;
             nearInfo.mappedName    = kNearName;
-            nearInfo.type          = GL_FLOAT;
-            nearInfo.arraySize     = 0;
             nearInfo.precision     = GL_HIGH_FLOAT;
             nearInfo.staticUse     = true;
 
-            ShaderVariable farInfo;
+            ShaderVariable farInfo(GL_FLOAT);
             const char kFarName[] = "far";
             farInfo.name          = kFarName;
             farInfo.mappedName    = kFarName;
-            farInfo.type          = GL_FLOAT;
-            farInfo.arraySize     = 0;
             farInfo.precision     = GL_HIGH_FLOAT;
             farInfo.staticUse     = true;
 
-            ShaderVariable diffInfo;
+            ShaderVariable diffInfo(GL_FLOAT);
             const char kDiffName[] = "diff";
             diffInfo.name          = kDiffName;
             diffInfo.mappedName    = kDiffName;
-            diffInfo.type          = GL_FLOAT;
-            diffInfo.arraySize     = 0;
             diffInfo.precision     = GL_HIGH_FLOAT;
             diffInfo.staticUse     = true;
 
             info.fields.push_back(nearInfo);
             info.fields.push_back(farInfo);
             info.fields.push_back(diffInfo);
 
             mUniforms->push_back(info);
             mDepthRangeAdded = true;
         }
     }
     else
     {
-        switch (symbol->getQualifier())
+        switch (qualifier)
         {
             case EvqAttribute:
             case EvqVertexIn:
                 var = FindVariable(symbolName, mAttribs);
                 break;
             case EvqFragmentOut:
                 var = FindVariable(symbolName, mOutputVariables);
                 break;
             case EvqUniform:
             {
                 const TInterfaceBlock *interfaceBlock = symbol->getType().getInterfaceBlock();
                 if (interfaceBlock)
                 {
-                    InterfaceBlock *namedBlock =
-                        FindVariable(interfaceBlock->name(), mUniformBlocks);
-                    ASSERT(namedBlock);
-                    var = FindVariable(symbolName, &namedBlock->fields);
-
-                    // Set static use on the parent interface block here
-                    namedBlock->staticUse = true;
+                    var = FindVariableInInterfaceBlock(symbolName, interfaceBlock, mUniformBlocks);
                 }
                 else
                 {
                     var = FindVariable(symbolName, mUniforms);
                 }
 
                 // It's an internal error to reference an undefined user uniform
                 ASSERT(symbolName.compare(0, 3, "gl_") != 0 || var);
             }
             break;
+            case EvqBuffer:
+            {
+                const TInterfaceBlock *interfaceBlock = symbol->getType().getInterfaceBlock();
+                var =
+                    FindVariableInInterfaceBlock(symbolName, interfaceBlock, mShaderStorageBlocks);
+            }
+            break;
             case EvqFragCoord:
                 recordBuiltInVaryingUsed("gl_FragCoord", &mFragCoordAdded, mInputVaryings);
                 return;
             case EvqFrontFacing:
                 recordBuiltInVaryingUsed("gl_FrontFacing", &mFrontFacingAdded, mInputVaryings);
                 return;
             case EvqPointCoord:
                 recordBuiltInVaryingUsed("gl_PointCoord", &mPointCoordAdded, mInputVaryings);
@@ -442,17 +464,16 @@ void CollectVariablesTraverser::visitSym
                 // 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.arraySize     = 0;
                     info.precision     = GL_HIGH_INT;  // Defined by spec.
                     info.staticUse     = true;
                     info.location      = -1;
                     mAttribs->push_back(info);
                     mInstanceIDAdded = true;
                 }
                 return;
             case EvqVertexID:
@@ -472,17 +493,18 @@ void CollectVariablesTraverser::visitSym
                 return;
             case EvqFragData:
                 if (!mFragDataAdded)
                 {
                     OutputVariable info;
                     setBuiltInInfoFromSymbolTable("gl_FragData", &info);
                     if (!IsExtensionEnabled(mExtensionBehavior, TExtension::EXT_draw_buffers))
                     {
-                        info.arraySize = 1;
+                        ASSERT(info.arraySizes.size() == 1u);
+                        info.arraySizes.back() = 1u;
                     }
                     info.staticUse = true;
                     mOutputVariables->push_back(info);
                     mFragDataAdded = true;
                 }
                 return;
             case EvqFragDepthEXT:
                 recordBuiltInFragmentOutputUsed("gl_FragDepthEXT", &mFragDepthEXTAdded);
@@ -500,28 +522,28 @@ void CollectVariablesTraverser::visitSym
                 return;
             case EvqInvocationID:
                 recordBuiltInVaryingUsed("gl_InvocationID", &mInvocationIDAdded, mInputVaryings);
                 break;
             case EvqPrimitiveIDIn:
                 recordBuiltInVaryingUsed("gl_PrimitiveIDIn", &mPrimitiveIDInAdded, mInputVaryings);
                 break;
             case EvqPrimitiveID:
-                if (mShaderType == GL_GEOMETRY_SHADER_OES)
+                if (mShaderType == GL_GEOMETRY_SHADER_EXT)
                 {
                     recordBuiltInVaryingUsed("gl_PrimitiveID", &mPrimitiveIDAdded, mOutputVaryings);
                 }
                 else
                 {
                     ASSERT(mShaderType == GL_FRAGMENT_SHADER);
                     recordBuiltInVaryingUsed("gl_PrimitiveID", &mPrimitiveIDAdded, mInputVaryings);
                 }
                 break;
             case EvqLayer:
-                if (mShaderType == GL_GEOMETRY_SHADER_OES)
+                if (mShaderType == GL_GEOMETRY_SHADER_EXT)
                 {
                     recordBuiltInVaryingUsed("gl_Layer", &mLayerAdded, mOutputVaryings);
                 }
                 else if (mShaderType == GL_FRAGMENT_SHADER)
                 {
                     recordBuiltInVaryingUsed("gl_Layer", &mLayerAdded, mInputVaryings);
                 }
                 else
@@ -535,155 +557,181 @@ void CollectVariablesTraverser::visitSym
         }
     }
     if (var)
     {
         MarkStaticallyUsed(var);
     }
 }
 
-void CollectVariablesTraverser::setCommonVariableProperties(const TType &type,
-                                                            const TName &name,
-                                                            ShaderVariable *variableOut) const
+void CollectVariablesTraverser::setFieldOrVariableProperties(const TType &type,
+                                                             ShaderVariable *variableOut) const
 {
     ASSERT(variableOut);
 
     const TStructure *structure = type.getStruct();
-
     if (!structure)
     {
         variableOut->type      = GLVariableType(type);
         variableOut->precision = GLVariablePrecision(type);
     }
     else
     {
         // Structures use a NONE type that isn't exposed outside ANGLE.
         variableOut->type       = GL_NONE;
-        variableOut->structName = structure->name().c_str();
+        if (structure->symbolType() != SymbolType::Empty)
+        {
+            variableOut->structName = structure->name().c_str();
+        }
 
         const TFieldList &fields = structure->fields();
 
-        for (TField *field : fields)
+        for (const TField *field : fields)
         {
             // Regardless of the variable type (uniform, in/out etc.) its fields are always plain
             // ShaderVariable objects.
             ShaderVariable fieldVariable;
-            setCommonVariableProperties(*field->type(), TName(field->name()), &fieldVariable);
+            setFieldProperties(*field->type(), field->name(), &fieldVariable);
             variableOut->fields.push_back(fieldVariable);
         }
     }
-    variableOut->name       = name.getString().c_str();
-    variableOut->mappedName = getMappedName(name);
+    if (auto *arraySizes = type.getArraySizes())
+    {
+        variableOut->arraySizes.assign(arraySizes->begin(), arraySizes->end());
+    }
+}
 
-    // TODO(oetuaho@nvidia.com): Uniforms can be arrays of arrays, so this assert will need to be
-    // removed.
-    ASSERT(!type.isArrayOfArrays());
-    variableOut->arraySize = type.isArray() ? type.getOutermostArraySize() : 0;
+void CollectVariablesTraverser::setFieldProperties(const TType &type,
+                                                   const TString &name,
+                                                   ShaderVariable *variableOut) const
+{
+    ASSERT(variableOut);
+    setFieldOrVariableProperties(type, variableOut);
+    variableOut->name       = name.c_str();
+    variableOut->mappedName = HashName(name, mHashFunction, nullptr).c_str();
+}
+
+void CollectVariablesTraverser::setCommonVariableProperties(const TType &type,
+                                                            const TVariable &variable,
+                                                            ShaderVariable *variableOut) const
+{
+    ASSERT(variableOut);
+
+    setFieldOrVariableProperties(type, variableOut);
+    ASSERT(variable.symbolType() != SymbolType::Empty);
+    variableOut->name       = variable.name().c_str();
+    variableOut->mappedName = getMappedName(&variable);
 }
 
 Attribute CollectVariablesTraverser::recordAttribute(const TIntermSymbol &variable) const
 {
     const TType &type = variable.getType();
     ASSERT(!type.getStruct());
 
     Attribute attribute;
-    setCommonVariableProperties(type, variable.getName(), &attribute);
+    setCommonVariableProperties(type, variable.variable(), &attribute);
 
     attribute.location = type.getLayoutQualifier().location;
     return attribute;
 }
 
 OutputVariable CollectVariablesTraverser::recordOutputVariable(const TIntermSymbol &variable) const
 {
     const TType &type = variable.getType();
     ASSERT(!type.getStruct());
 
     OutputVariable outputVariable;
-    setCommonVariableProperties(type, variable.getName(), &outputVariable);
+    setCommonVariableProperties(type, variable.variable(), &outputVariable);
 
     outputVariable.location = type.getLayoutQualifier().location;
     return outputVariable;
 }
 
 Varying CollectVariablesTraverser::recordVarying(const TIntermSymbol &variable) const
 {
     const TType &type = variable.getType();
 
     Varying varying;
-    setCommonVariableProperties(type, variable.getName(), &varying);
+    setCommonVariableProperties(type, variable.variable(), &varying);
     varying.location = type.getLayoutQualifier().location;
 
     switch (type.getQualifier())
     {
         case EvqVaryingIn:
         case EvqVaryingOut:
         case EvqVertexOut:
         case EvqSmoothOut:
         case EvqFlatOut:
         case EvqCentroidOut:
-            if (mSymbolTable->isVaryingInvariant(std::string(variable.getSymbol().c_str())) ||
-                type.isInvariant())
+        case EvqGeometryOut:
+            if (mSymbolTable->isVaryingInvariant(varying.name) || type.isInvariant())
             {
                 varying.isInvariant = true;
             }
             break;
         default:
             break;
     }
 
     varying.interpolation = GetInterpolationType(type.getQualifier());
     return varying;
 }
 
-// TODO(jiawei.shao@intel.com): implement GL_OES_shader_io_blocks.
-void CollectVariablesTraverser::recordInterfaceBlock(const TType &interfaceBlockType,
+// TODO(jiawei.shao@intel.com): implement GL_EXT_shader_io_blocks.
+void CollectVariablesTraverser::recordInterfaceBlock(const char *instanceName,
+                                                     const TType &interfaceBlockType,
                                                      InterfaceBlock *interfaceBlock) const
 {
     ASSERT(interfaceBlockType.getBasicType() == EbtInterfaceBlock);
     ASSERT(interfaceBlock);
 
     const TInterfaceBlock *blockType = interfaceBlockType.getInterfaceBlock();
     ASSERT(blockType);
 
     interfaceBlock->name       = blockType->name().c_str();
-    interfaceBlock->mappedName = getMappedName(TName(blockType->name()));
-    interfaceBlock->instanceName =
-        (blockType->hasInstanceName() ? blockType->instanceName().c_str() : "");
+    interfaceBlock->mappedName = getMappedName(blockType);
+    if (instanceName != nullptr)
+    {
+        interfaceBlock->instanceName = instanceName;
+    }
     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)
     {
-        interfaceBlock->isRowMajorLayout = (blockType->matrixPacking() == EmpRowMajor);
+        // TODO(oetuaho): Remove setting isRowMajorLayout.
+        interfaceBlock->isRowMajorLayout = false;
         interfaceBlock->binding          = blockType->blockBinding();
         interfaceBlock->layout           = GetBlockLayoutType(blockType->blockStorage());
     }
 
     // Gather field information
     for (const TField *field : blockType->fields())
     {
         const TType &fieldType = *field->type();
 
         InterfaceBlockField fieldVariable;
-        setCommonVariableProperties(fieldType, TName(field->name()), &fieldVariable);
+        setFieldProperties(fieldType, field->name(), &fieldVariable);
         fieldVariable.isRowMajorLayout =
             (fieldType.getLayoutQualifier().matrixPacking == EmpRowMajor);
         interfaceBlock->fields.push_back(fieldVariable);
     }
 }
 
 Uniform CollectVariablesTraverser::recordUniform(const TIntermSymbol &variable) const
 {
     Uniform uniform;
-    setCommonVariableProperties(variable.getType(), variable.getName(), &uniform);
+    setCommonVariableProperties(variable.getType(), variable.variable(), &uniform);
     uniform.binding  = variable.getType().getLayoutQualifier().binding;
     uniform.location = variable.getType().getLayoutQualifier().location;
     uniform.offset   = variable.getType().getLayoutQualifier().offset;
+    uniform.readonly  = variable.getType().getMemoryQualifier().readonly;
+    uniform.writeonly = variable.getType().getMemoryQualifier().writeonly;
     return uniform;
 }
 
 bool CollectVariablesTraverser::visitDeclaration(Visit, TIntermDeclaration *node)
 {
     const TIntermSequence &sequence = *(node->getSequence());
     ASSERT(!sequence.empty());
 
@@ -701,42 +749,46 @@ bool CollectVariablesTraverser::visitDec
 
     for (TIntermNode *variableNode : sequence)
     {
         // The only case in which the sequence will not contain a TIntermSymbol node is
         // initialization. It will contain a TInterBinary node in that case. Since attributes,
         // uniforms, varyings, outputs and interface blocks cannot be initialized in a shader, we
         // must have only TIntermSymbol nodes in the sequence in the cases we are interested in.
         const TIntermSymbol &variable = *variableNode->getAsSymbolNode();
-        if (variable.getName().isInternal())
+        if (variable.variable().symbolType() == SymbolType::AngleInternal)
         {
             // Internal variables are not collected.
             continue;
         }
 
-        // TODO(jiawei.shao@intel.com): implement GL_OES_shader_io_blocks.
+        // TODO(jiawei.shao@intel.com): implement GL_EXT_shader_io_blocks.
         if (typedNode.getBasicType() == EbtInterfaceBlock)
         {
             InterfaceBlock interfaceBlock;
-            recordInterfaceBlock(variable.getType(), &interfaceBlock);
+            recordInterfaceBlock(variable.variable().symbolType() != SymbolType::Empty
+                                     ? variable.getName().c_str()
+                                     : nullptr,
+                                 variable.getType(), &interfaceBlock);
 
             switch (qualifier)
             {
                 case EvqUniform:
                     mUniformBlocks->push_back(interfaceBlock);
                     break;
                 case EvqBuffer:
                     mShaderStorageBlocks->push_back(interfaceBlock);
                     break;
                 default:
                     UNREACHABLE();
             }
         }
         else
         {
+            ASSERT(variable.variable().symbolType() != SymbolType::Empty);
             switch (qualifier)
             {
                 case EvqAttribute:
                 case EvqVertexIn:
                     mAttribs->push_back(recordAttribute(variable));
                     break;
                 case EvqFragmentOut:
                     mOutputVariables->push_back(recordOutputVariable(variable));
@@ -760,17 +812,17 @@ bool CollectVariablesTraverser::visitDec
     }
 
     // None of the recorded variables can have initializers, so we don't need to traverse the
     // declarators.
     return false;
 }
 
 // TODO(jiawei.shao@intel.com): add search on mInBlocks and mOutBlocks when implementing
-// GL_OES_shader_io_blocks.
+// GL_EXT_shader_io_blocks.
 InterfaceBlock *CollectVariablesTraverser::findNamedInterfaceBlock(const TString &blockName) const
 {
     InterfaceBlock *namedBlock = FindVariable(blockName, mUniformBlocks);
     if (!namedBlock)
     {
         namedBlock = FindVariable(blockName, mShaderStorageBlocks);
     }
     return namedBlock;
--- a/gfx/angle/src/compiler/translator/Common.h
+++ b/gfx/angle/src/compiler/translator/Common.h
@@ -5,22 +5,24 @@
 //
 
 #ifndef COMPILER_TRANSLATOR_COMMON_H_
 #define COMPILER_TRANSLATOR_COMMON_H_
 
 #include <map>
 #include <sstream>
 #include <string>
+#include <unordered_map>
 #include <vector>
 #include <limits>
 #include <stdio.h>
 
 #include "common/angleutils.h"
 #include "common/debug.h"
+#include "common/third_party/smhasher/src/PMurHash.h"
 #include "compiler/translator/PoolAlloc.h"
 
 namespace sh
 {
 
 struct TSourceLoc
 {
     int first_file;
@@ -71,16 +73,33 @@ class TVector : public std::vector<T, po
     POOL_ALLOCATOR_NEW_DELETE();
 
     typedef typename std::vector<T, pool_allocator<T>>::size_type size_type;
     TVector() : std::vector<T, pool_allocator<T>>() {}
     TVector(const pool_allocator<T> &a) : std::vector<T, pool_allocator<T>>(a) {}
     TVector(size_type i) : std::vector<T, pool_allocator<T>>(i) {}
 };
 
+template <class K, class D, class H = std::hash<K>, class CMP = std::equal_to<K>>
+class TUnorderedMap : public std::unordered_map<K, D, H, CMP, pool_allocator<std::pair<const K, D>>>
+{
+  public:
+    POOL_ALLOCATOR_NEW_DELETE();
+    typedef pool_allocator<std::pair<const K, D>> tAllocator;
+
+    TUnorderedMap() : std::unordered_map<K, D, H, CMP, tAllocator>() {}
+    // use correct two-stage name lookup supported in gcc 3.4 and above
+    TUnorderedMap(const tAllocator &a)
+        : std::unordered_map<K, D, H, CMP, tAllocator>(
+              std::unordered_map<K, D, H, CMP, tAllocator>::key_compare(),
+              a)
+    {
+    }
+};
+
 template <class K, class D, class CMP = std::less<K>>
 class TMap : public std::map<K, D, CMP, pool_allocator<std::pair<const K, D>>>
 {
   public:
     POOL_ALLOCATOR_NEW_DELETE();
     typedef pool_allocator<std::pair<const K, D>> tAllocator;
 
     TMap() : std::map<K, D, CMP, tAllocator>() {}
@@ -99,9 +118,21 @@ inline TString str(T i)
     char buffer[((8 * sizeof(T)) / 3) + 3];
     const char *formatStr = std::numeric_limits<T>::is_signed ? "%d" : "%u";
     snprintf(buffer, sizeof(buffer), formatStr, i);
     return buffer;
 }
 
 }  // namespace sh
 
+namespace std
+{
+template <>
+struct hash<sh::TString>
+{
+    size_t operator()(const sh::TString &s) const
+    {
+        return angle::PMurHash32(0, s.data(), static_cast<int>(s.length()));
+    }
+};
+}  // namespace std
+
 #endif  // COMPILER_TRANSLATOR_COMMON_H_
--- a/gfx/angle/src/compiler/translator/Compiler.cpp
+++ b/gfx/angle/src/compiler/translator/Compiler.cpp
@@ -6,47 +6,52 @@
 
 #include "compiler/translator/Compiler.h"
 
 #include <sstream>
 
 #include "angle_gl.h"
 #include "common/utilities.h"
 #include "compiler/translator/AddAndTrueToLoopCondition.h"
-#include "compiler/translator/Cache.h"
 #include "compiler/translator/CallDAG.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/PruneEmptyDeclarations.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/util.h"
 #include "third_party/compiler/ArrayBoundsClamper.h"
 
 namespace sh
 {
 
 namespace
 {
 
@@ -148,17 +153,17 @@ int GetMaxUniformVectorsForShaderType(GL
         case GL_VERTEX_SHADER:
             return resources.MaxVertexUniformVectors;
         case GL_FRAGMENT_SHADER:
             return resources.MaxFragmentUniformVectors;
 
         // TODO (jiawei.shao@intel.com): check if we need finer-grained component counting
         case GL_COMPUTE_SHADER:
             return resources.MaxComputeUniformComponents / 4;
-        case GL_GEOMETRY_SHADER_OES:
+        case GL_GEOMETRY_SHADER_EXT:
             return resources.MaxGeometryUniformComponents / 4;
         default:
             UNREACHABLE();
             return -1;
     }
 }
 
 namespace
@@ -244,22 +249,22 @@ TCompiler::TCompiler(sh::GLenum type, Sh
       maxCallStackDepth(0),
       maxFunctionParameters(0),
       fragmentPrecisionHigh(false),
       clampingStrategy(SH_CLAMP_WITH_CLAMP_INTRINSIC),
       builtInFunctionEmulator(),
       mDiagnostics(infoSink.info),
       mSourcePath(nullptr),
       mComputeShaderLocalSizeDeclared(false),
+      mComputeShaderLocalSize(1),
       mGeometryShaderMaxVertices(-1),
       mGeometryShaderInvocations(0),
       mGeometryShaderInputPrimitiveType(EptUndefined),
       mGeometryShaderOutputPrimitiveType(EptUndefined)
 {
-    mComputeShaderLocalSize.fill(1);
 }
 
 TCompiler::~TCompiler()
 {
 }
 
 bool TCompiler::shouldRunLoopAndIndexingValidation(ShCompileOptions compileOptions) const
 {
@@ -328,268 +333,325 @@ TIntermBlock *TCompiler::compileTreeImpl
 
     parseContext.setFragmentPrecisionHighOnESSL1(fragmentPrecisionHigh);
 
     // We preserve symbols at the built-in level from compile-to-compile.
     // Start pushing the user-defined symbols at global level.
     TScopedSymbolTableLevel scopedSymbolLevel(&symbolTable);
 
     // Parse shader.
-    bool success = (PaParseStrings(numStrings - firstSource, &shaderStrings[firstSource], nullptr,
-                                   &parseContext) == 0) &&
-                   (parseContext.getTreeRoot() != nullptr);
+    if (PaParseStrings(numStrings - firstSource, &shaderStrings[firstSource], nullptr,
+                       &parseContext) != 0)
+    {
+        return nullptr;
+    }
 
-    shaderVersion = parseContext.getShaderVersion();
-    if (success && MapSpecToShaderVersion(shaderSpec) < shaderVersion)
+    if (parseContext.getTreeRoot() == nullptr)
+    {
+        return nullptr;
+    }
+
+    setASTMetadata(parseContext);
+
+    if (MapSpecToShaderVersion(shaderSpec) < shaderVersion)
     {
         mDiagnostics.globalError("unsupported shader version");
-        success = false;
+        return nullptr;
+    }
+
+    TIntermBlock *root = parseContext.getTreeRoot();
+    if (!checkAndSimplifyAST(root, parseContext, compileOptions))
+    {
+        return nullptr;
+    }
+
+    return root;
+}
+
+void TCompiler::setASTMetadata(const TParseContext &parseContext)
+{
+    shaderVersion = parseContext.getShaderVersion();
+
+    mPragma = parseContext.pragma();
+    symbolTable.setGlobalInvariant(mPragma.stdgl.invariantAll);
+
+    mComputeShaderLocalSizeDeclared = parseContext.isComputeShaderLocalSizeDeclared();
+    mComputeShaderLocalSize         = parseContext.getComputeShaderLocalSize();
+
+    mNumViews = parseContext.getNumViews();
+
+    // Highp might have been auto-enabled based on shader version
+    fragmentPrecisionHigh = parseContext.getFragmentPrecisionHigh();
+
+    if (shaderType == GL_GEOMETRY_SHADER_EXT)
+    {
+        mGeometryShaderInputPrimitiveType  = parseContext.getGeometryShaderInputPrimitiveType();
+        mGeometryShaderOutputPrimitiveType = parseContext.getGeometryShaderOutputPrimitiveType();
+        mGeometryShaderMaxVertices         = parseContext.getGeometryShaderMaxVertices();
+        mGeometryShaderInvocations         = parseContext.getGeometryShaderInvocations();
+    }
+}
+
+bool TCompiler::checkAndSimplifyAST(TIntermBlock *root,
+                                    const TParseContext &parseContext,
+                                    ShCompileOptions compileOptions)
+{
+    // Disallow expressions deemed too complex.
+    if ((compileOptions & SH_LIMIT_EXPRESSION_COMPLEXITY) && !limitExpressionComplexity(root))
+    {
+        return false;
+    }
+
+    if (shouldRunLoopAndIndexingValidation(compileOptions) &&
+        !ValidateLimitations(root, shaderType, &symbolTable, shaderVersion, &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);
+
+    // 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())
+    {
+        return false;
+    }
+
+    // Checks which functions are used and if "main" exists
+    functionMetadata.clear();
+    functionMetadata.resize(mCallDag.size());
+    if (!tagUsedFunctions())
+    {
+        return false;
+    }
+
+    if (!(compileOptions & SH_DONT_PRUNE_UNUSED_FUNCTIONS))
+    {
+        pruneUnusedFunctions(root);
     }
 
-    TIntermBlock *root = nullptr;
+    if (shaderVersion >= 310 && !ValidateVaryingLocations(root, &mDiagnostics, shaderType))
+    {
+        return false;
+    }
 
-    if (success)
+    if (shaderVersion >= 300 && shaderType == GL_FRAGMENT_SHADER &&
+        !ValidateOutputs(root, getExtensionBehavior(), compileResources.MaxDrawBuffers,
+                         &mDiagnostics))
     {
-        mPragma = parseContext.pragma();
-        symbolTable.setGlobalInvariant(mPragma.stdgl.invariantAll);
+        return false;
+    }
 
-        mComputeShaderLocalSizeDeclared = parseContext.isComputeShaderLocalSizeDeclared();
-        mComputeShaderLocalSize         = parseContext.getComputeShaderLocalSize();
-
-        mNumViews = parseContext.getNumViews();
+    // Fail compilation if precision emulation not supported.
+    if (getResources().WEBGL_debug_shader_precision && getPragma().debugShaderPrecision &&
+        !EmulatePrecision::SupportedInLanguage(outputType))
+    {
+        mDiagnostics.globalError("Precision emulation not supported for this output type.");
+        return false;
+    }
 
-        root = parseContext.getTreeRoot();
-
-        // Highp might have been auto-enabled based on shader version
-        fragmentPrecisionHigh = parseContext.getFragmentPrecisionHigh();
+    // Clamping uniform array bounds needs to happen after validateLimitations pass.
+    if (compileOptions & SH_CLAMP_INDIRECT_ARRAY_BOUNDS)
+    {
+        arrayBoundsClamper.MarkIndirectArrayBoundsForClamping(root);
+    }
 
-        if (success && shaderType == GL_GEOMETRY_SHADER_OES)
-        {
-            mGeometryShaderInputPrimitiveType = parseContext.getGeometryShaderInputPrimitiveType();
-            mGeometryShaderOutputPrimitiveType =
-                parseContext.getGeometryShaderOutputPrimitiveType();
-            mGeometryShaderMaxVertices = parseContext.getGeometryShaderMaxVertices();
-            mGeometryShaderInvocations = parseContext.getGeometryShaderInvocations();
-        }
+    if ((compileOptions & SH_INITIALIZE_BUILTINS_FOR_INSTANCED_MULTIVIEW) &&
+        parseContext.isExtensionEnabled(TExtension::OVR_multiview) &&
+        getShaderType() != GL_COMPUTE_SHADER)
+    {
+        DeclareAndInitBuiltinsForInstancedMultiview(root, mNumViews, shaderType, compileOptions,
+                                                    outputType, &symbolTable);
+    }
+
+    // This pass might emit short circuits so keep it before the short circuit unfolding
+    if (compileOptions & SH_REWRITE_DO_WHILE_LOOPS)
+        RewriteDoWhile(root, &symbolTable);
+
+    if (compileOptions & SH_ADD_AND_TRUE_TO_LOOP_CONDITION)
+        sh::AddAndTrueToLoopCondition(root);
 
-        // Disallow expressions deemed too complex.
-        if (success && (compileOptions & SH_LIMIT_EXPRESSION_COMPLEXITY))
-            success = limitExpressionComplexity(root);
+    if (compileOptions & SH_UNFOLD_SHORT_CIRCUIT)
+    {
+        UnfoldShortCircuitAST unfoldShortCircuit;
+        root->traverse(&unfoldShortCircuit);
+        unfoldShortCircuit.updateTree();
+    }
 
-        // Create the function DAG and check there is no recursion
-        if (success)
-            success = initCallDag(root);
+    if (compileOptions & SH_REMOVE_POW_WITH_CONSTANT_EXPONENT)
+    {
+        RemovePow(root);
+    }
 
-        if (success && (compileOptions & SH_LIMIT_CALL_STACK_DEPTH))
-            success = checkCallDepth();
+    if (compileOptions & SH_REGENERATE_STRUCT_NAMES)
+    {
+        RegenerateStructNames gen(&symbolTable);
+        root->traverse(&gen);
+    }
 
-        // Checks which functions are used and if "main" exists
-        if (success)
-        {
-            functionMetadata.clear();
-            functionMetadata.resize(mCallDag.size());
-            success = tagUsedFunctions();
-        }
+    if (shaderType == GL_FRAGMENT_SHADER && shaderVersion == 100 &&
+        compileResources.EXT_draw_buffers && compileResources.MaxDrawBuffers > 1 &&
+        IsExtensionEnabled(extensionBehavior, TExtension::EXT_draw_buffers))
+    {
+        EmulateGLFragColorBroadcast(root, compileResources.MaxDrawBuffers, &outputVariables,
+                                    &symbolTable, shaderVersion);
+    }
+
+    int simplifyScalarized = (compileOptions & SH_SCALARIZE_VEC_AND_MAT_CONSTRUCTOR_ARGS)
+                                 ? IntermNodePatternMatcher::kScalarizedVecOrMatConstructor
+                                 : 0;
+
+    // Split multi declarations and remove calls to array length().
+    // Note that SimplifyLoopConditions needs to be run before any other AST transformations
+    // that may need to generate new statements from loop conditions or loop expressions.
+    SimplifyLoopConditions(root,
+                           IntermNodePatternMatcher::kMultiDeclaration |
+                               IntermNodePatternMatcher::kArrayLengthMethod | simplifyScalarized,
+                           &getSymbolTable(), getShaderVersion());
+
+    // Note that separate declarations need to be run before other AST transformations that
+    // generate new statements from expressions.
+    SeparateDeclarations(root);
+
+    SplitSequenceOperator(root, IntermNodePatternMatcher::kArrayLengthMethod | simplifyScalarized,
+                          &getSymbolTable(), getShaderVersion());
 
-        if (success && !(compileOptions & SH_DONT_PRUNE_UNUSED_FUNCTIONS))
-            success = pruneUnusedFunctions(root);
+    RemoveArrayLengthMethod(root);
+
+    RemoveUnreferencedVariables(root, &symbolTable);
+
+    // 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);
 
-        // Prune empty declarations to work around driver bugs and to keep declaration output
-        // simple.
-        if (success)
-            PruneEmptyDeclarations(root);
+    if (compileOptions & SH_SCALARIZE_VEC_AND_MAT_CONSTRUCTOR_ARGS)
+    {
+        ScalarizeVecAndMatConstructorArgs(root, shaderType, fragmentPrecisionHigh, &symbolTable);
+    }
 
-        if (success && shaderVersion >= 310)
+    if (shouldCollectVariables(compileOptions))
+    {
+        ASSERT(!variablesCollected);
+        CollectVariables(root, &attributes, &outputVariables, &uniforms, &inputVaryings,
+                         &outputVaryings, &uniformBlocks, &shaderStorageBlocks, &inBlocks,
+                         hashFunction, &symbolTable, shaderVersion, shaderType, extensionBehavior);
+        collectInterfaceBlocks();
+        variablesCollected = true;
+        if (compileOptions & SH_USE_UNUSED_STANDARD_SHARED_BLOCKS)
         {
-            success = ValidateVaryingLocations(root, &mDiagnostics);
+            useAllMembersInUnusedStandardAndSharedBlocks(root);
         }
-
-        if (success && shaderVersion >= 300 && shaderType == GL_FRAGMENT_SHADER)
+        if (compileOptions & SH_ENFORCE_PACKING_RESTRICTIONS)
         {
-            success = ValidateOutputs(root, getExtensionBehavior(), compileResources.MaxDrawBuffers,
-                                      &mDiagnostics);
-        }
-
-        if (success && shouldRunLoopAndIndexingValidation(compileOptions))
-            success =
-                ValidateLimitations(root, shaderType, &symbolTable, shaderVersion, &mDiagnostics);
-
-        // Fail compilation if precision emulation not supported.
-        if (success && getResources().WEBGL_debug_shader_precision &&
-            getPragma().debugShaderPrecision)
-        {
-            if (!EmulatePrecision::SupportedInLanguage(outputType))
+            // Returns true if, after applying the packing rules in the GLSL ES 1.00.17 spec
+            // Appendix A, section 7, the shader does not use too many uniforms.
+            if (!CheckVariablesInPackingLimits(maxUniformVectors, uniforms))
             {
-                mDiagnostics.globalError("Precision emulation not supported for this output type.");
-                success = false;
+                mDiagnostics.globalError("too many uniforms");
+                return false;
             }
         }
-
-        // Built-in function emulation needs to happen after validateLimitations pass.
-        if (success)
-        {
-            // TODO(jmadill): Remove global pool allocator.
-            GetGlobalPoolAllocator()->lock();
-            initBuiltInFunctionEmulator(&builtInFunctionEmulator, compileOptions);
-            GetGlobalPoolAllocator()->unlock();
-            builtInFunctionEmulator.markBuiltInFunctionsForEmulation(root);
-        }
-
-        // Clamping uniform array bounds needs to happen after validateLimitations pass.
-        if (success && (compileOptions & SH_CLAMP_INDIRECT_ARRAY_BOUNDS))
-            arrayBoundsClamper.MarkIndirectArrayBoundsForClamping(root);
-
-        if (success && (compileOptions & SH_INITIALIZE_BUILTINS_FOR_INSTANCED_MULTIVIEW) &&
-            parseContext.isExtensionEnabled(TExtension::OVR_multiview) &&
-            getShaderType() != GL_COMPUTE_SHADER)
-        {
-            DeclareAndInitBuiltinsForInstancedMultiview(root, mNumViews, shaderType, compileOptions,
-                                                        outputType, &symbolTable);
-        }
-
-        // This pass might emit short circuits so keep it before the short circuit unfolding
-        if (success && (compileOptions & SH_REWRITE_DO_WHILE_LOOPS))
-            RewriteDoWhile(root, &symbolTable);
-
-        if (success && (compileOptions & SH_ADD_AND_TRUE_TO_LOOP_CONDITION))
-            sh::AddAndTrueToLoopCondition(root);
-
-        if (success && (compileOptions & SH_UNFOLD_SHORT_CIRCUIT))
-        {
-            UnfoldShortCircuitAST unfoldShortCircuit;
-            root->traverse(&unfoldShortCircuit);
-            unfoldShortCircuit.updateTree();
-        }
-
-        if (success && (compileOptions & SH_REMOVE_POW_WITH_CONSTANT_EXPONENT))
-        {
-            RemovePow(root);
-        }
-
-        if (success && shouldCollectVariables(compileOptions))
-        {
-            ASSERT(!variablesCollected);
-            CollectVariables(root, &attributes, &outputVariables, &uniforms, &inputVaryings,
-                             &outputVaryings, &uniformBlocks, &shaderStorageBlocks, &inBlocks,
-                             hashFunction, &symbolTable, shaderVersion, shaderType,
-                             extensionBehavior);
-            collectInterfaceBlocks();
-            variablesCollected = true;
-            if (compileOptions & SH_USE_UNUSED_STANDARD_SHARED_BLOCKS)
-            {
-                useAllMembersInUnusedStandardAndSharedBlocks(root);
-            }
-            if (compileOptions & SH_ENFORCE_PACKING_RESTRICTIONS)
-            {
-                // Returns true if, after applying the packing rules in the GLSL ES 1.00.17 spec
-                // Appendix A, section 7, the shader does not use too many uniforms.
-                success = CheckVariablesInPackingLimits(maxUniformVectors, uniforms);
-                if (!success)
-                {
-                    mDiagnostics.globalError("too many uniforms");
-                }
-            }
-            if (success && (compileOptions & SH_INIT_OUTPUT_VARIABLES))
-            {
-                initializeOutputVariables(root);
-            }
-        }
-
-        // gl_Position is always written in compatibility output mode.
-        // It may have been already initialized among other output variables, in that case we don't
-        // need to initialize it twice.
-        if (success && shaderType == GL_VERTEX_SHADER && !mGLPositionInitialized &&
-            ((compileOptions & SH_INIT_GL_POSITION) ||
-             (outputType == SH_GLSL_COMPATIBILITY_OUTPUT)))
+        if (compileOptions & SH_INIT_OUTPUT_VARIABLES)
         {
-            initializeGLPosition(root);
-            mGLPositionInitialized = true;
-        }
-
-        // Removing invariant declarations must be done after collecting variables.
-        // Otherwise, built-in invariant declarations don't apply.
-        if (success && RemoveInvariant(shaderType, shaderVersion, outputType, compileOptions))
-            sh::RemoveInvariantDeclaration(root);
-
-        if (success && (compileOptions & SH_SCALARIZE_VEC_AND_MAT_CONSTRUCTOR_ARGS))
-        {
-            ScalarizeVecAndMatConstructorArgs(root, shaderType, fragmentPrecisionHigh,
-                                              &symbolTable);
-        }
-
-        if (success && (compileOptions & SH_REGENERATE_STRUCT_NAMES))
-        {
-            RegenerateStructNames gen(&symbolTable, shaderVersion);
-            root->traverse(&gen);
-        }
-
-        if (success && shaderType == GL_FRAGMENT_SHADER && shaderVersion == 100 &&
-            compileResources.EXT_draw_buffers && compileResources.MaxDrawBuffers > 1 &&
-            IsExtensionEnabled(extensionBehavior, TExtension::EXT_draw_buffers))
-        {
-            EmulateGLFragColorBroadcast(root, compileResources.MaxDrawBuffers, &outputVariables,
-                                        &symbolTable, shaderVersion);
-        }
-
-        if (success)
-        {
-            DeferGlobalInitializers(root, needToInitializeGlobalsInAST(), &symbolTable);
-        }
-
-        // Split multi declarations and remove calls to array length().
-        if (success)
-        {
-            // Note that SimplifyLoopConditions needs to be run before any other AST transformations
-            // that may need to generate new statements from loop conditions or loop expressions.
-            SimplifyLoopConditions(root,
-                                   IntermNodePatternMatcher::kMultiDeclaration |
-                                       IntermNodePatternMatcher::kArrayLengthMethod,
-                                   &getSymbolTable(), getShaderVersion());
-
-            // Note that separate declarations need to be run before other AST transformations that
-            // generate new statements from expressions.
-            SeparateDeclarations(root);
-
-            SplitSequenceOperator(root, IntermNodePatternMatcher::kArrayLengthMethod,
-                                  &getSymbolTable(), getShaderVersion());
-
-            RemoveArrayLengthMethod(root);
-        }
-
-        if (success && (compileOptions & SH_INITIALIZE_UNINITIALIZED_LOCALS) && getOutputType())
-        {
-            // Initialize uninitialized local variables.
-            // In some cases initializing can generate extra statements in the parent block, such as
-            // when initializing nameless structs or initializing arrays in ESSL 1.00. In that case
-            // we need to first simplify loop conditions. We've already separated declarations
-            // earlier, which is also required. If we don't follow the Appendix A limitations, loop
-            // init statements can declare arrays or nameless structs and have multiple
-            // declarations.
-
-            if (!shouldRunLoopAndIndexingValidation(compileOptions))
-            {
-                SimplifyLoopConditions(root,
-                                           IntermNodePatternMatcher::kArrayDeclaration |
-                                           IntermNodePatternMatcher::kNamelessStructDeclaration,
-                                       &getSymbolTable(), getShaderVersion());
-            }
-            InitializeUninitializedLocals(root, getShaderVersion());
-        }
-
-        if (success && getShaderType() == GL_VERTEX_SHADER &&
-            (compileOptions & SH_CLAMP_POINT_SIZE))
-        {
-            ClampPointSize(root, compileResources.MaxPointSize, &getSymbolTable());
+            initializeOutputVariables(root);
         }
     }
 
-    if (success)
-        return root;
+    // Removing invariant declarations must be done after collecting variables.
+    // Otherwise, built-in invariant declarations don't apply.
+    if (RemoveInvariant(shaderType, shaderVersion, outputType, compileOptions))
+    {
+        RemoveInvariantDeclaration(root);
+    }
+
+    // gl_Position is always written in compatibility output mode.
+    // It may have been already initialized among other output variables, in that case we don't
+    // need to initialize it twice.
+    if (shaderType == GL_VERTEX_SHADER && !mGLPositionInitialized &&
+        ((compileOptions & SH_INIT_GL_POSITION) || (outputType == SH_GLSL_COMPATIBILITY_OUTPUT)))
+    {
+        initializeGLPosition(root);
+        mGLPositionInitialized = true;
+    }
+
+    // DeferGlobalInitializers needs to be run before other AST transformations that generate new
+    // statements from expressions. But it's fine to run DeferGlobalInitializers after the above
+    // SplitSequenceOperator and RemoveArrayLengthMethod since they only have an effect on the AST
+    // on ESSL >= 3.00, and the initializers that need to be deferred can only exist in ESSL < 3.00.
+    bool initializeLocalsAndGlobals =
+        (compileOptions & SH_INITIALIZE_UNINITIALIZED_LOCALS) && !IsOutputHLSL(getOutputType());
+    bool canUseLoopsToInitialize = !(compileOptions & SH_DONT_USE_LOOPS_TO_INITIALIZE_VARIABLES);
+    bool highPrecisionSupported =
+        shaderType != GL_FRAGMENT_SHADER || compileResources.FragmentPrecisionHigh;
+    DeferGlobalInitializers(root, initializeLocalsAndGlobals, canUseLoopsToInitialize,
+                            highPrecisionSupported, &symbolTable);
 
-    return nullptr;
+    if (initializeLocalsAndGlobals)
+    {
+        // Initialize uninitialized local variables.
+        // In some cases initializing can generate extra statements in the parent block, such as
+        // when initializing nameless structs or initializing arrays in ESSL 1.00. In that case
+        // we need to first simplify loop conditions. We've already separated declarations
+        // earlier, which is also required. If we don't follow the Appendix A limitations, loop
+        // init statements can declare arrays or nameless structs and have multiple
+        // declarations.
+
+        if (!shouldRunLoopAndIndexingValidation(compileOptions))
+        {
+            SimplifyLoopConditions(root,
+                                   IntermNodePatternMatcher::kArrayDeclaration |
+                                       IntermNodePatternMatcher::kNamelessStructDeclaration,
+                                   &getSymbolTable(), getShaderVersion());
+        }
+
+        InitializeUninitializedLocals(root, getShaderVersion(), canUseLoopsToInitialize,
+                                      highPrecisionSupported, &getSymbolTable());
+    }
+
+    if (getShaderType() == GL_VERTEX_SHADER && (compileOptions & SH_CLAMP_POINT_SIZE))
+    {
+        ClampPointSize(root, compileResources.MaxPointSize, &getSymbolTable());
+    }
+
+    if (compileOptions & SH_REWRITE_VECTOR_SCALAR_ARITHMETIC)
+    {
+        VectorizeVectorScalarArithmetic(root, &getSymbolTable());
+    }
+
+    return true;
 }
 
 bool TCompiler::compile(const char *const shaderStrings[],
                         size_t numStrings,
                         ShCompileOptions compileOptionsIn)
 {
 #if defined(ANGLE_ENABLE_FUZZER_CORPUS_OUTPUT)
     DumpFuzzerCase(shaderStrings, numStrings, shaderType, shaderSpec, outputType, compileOptionsIn);
@@ -611,17 +673,20 @@ bool TCompiler::compile(const char *cons
     TIntermBlock *root = compileTreeImpl(shaderStrings, numStrings, compileOptions);
 
     if (root)
     {
         if (compileOptions & SH_INTERMEDIATE_TREE)
             OutputTree(root, infoSink.info);
 
         if (compileOptions & SH_OBJECT_CODE)
-            translate(root, compileOptions);
+        {
+            PerformanceDiagnostics perfDiagnostics(&mDiagnostics);
+            translate(root, compileOptions, &perfDiagnostics);
+        }
 
         // The IntermNode tree doesn't need to be deleted here, since the
         // memory will be freed in a big chunk by the PoolAllocator.
         return true;
     }
     return false;
 }
 
@@ -648,17 +713,17 @@ bool TCompiler::InitBuiltInSymbolTable(c
 
     switch (shaderType)
     {
         case GL_FRAGMENT_SHADER:
             symbolTable.setDefaultPrecision(EbtInt, EbpMedium);
             break;
         case GL_VERTEX_SHADER:
         case GL_COMPUTE_SHADER:
-        case GL_GEOMETRY_SHADER_OES:
+        case GL_GEOMETRY_SHADER_EXT:
             symbolTable.setDefaultPrecision(EbtInt, EbpHigh);
             symbolTable.setDefaultPrecision(EbtFloat, EbpHigh);
             break;
         default:
             UNREACHABLE();
     }
     // Set defaults for sampler types that have default precision, even those that are
     // only available if an extension exists.
@@ -673,16 +738,18 @@ bool TCompiler::InitBuiltInSymbolTable(c
     initSamplerDefaultPrecision(EbtSampler2DRect);
 
     symbolTable.setDefaultPrecision(EbtAtomicCounter, EbpHigh);
 
     InsertBuiltInFunctions(shaderType, shaderSpec, resources, symbolTable);
 
     IdentifyBuiltIns(shaderType, shaderSpec, resources, symbolTable);
 
+    symbolTable.markBuiltInInitializationFinished();
+
     return true;
 }
 
 void TCompiler::initSamplerDefaultPrecision(TBasicType samplerType)
 {
     ASSERT(samplerType > EbtGuardSamplerBegin && samplerType < EbtGuardSamplerEnd);
     symbolTable.setDefaultPrecision(samplerType, EbpLow);
 }
@@ -713,17 +780,17 @@ void TCompiler::setResourceString()
         << ":EXT_blend_func_extended:" << compileResources.EXT_blend_func_extended
         << ":EXT_frag_depth:" << compileResources.EXT_frag_depth
         << ":EXT_shader_texture_lod:" << compileResources.EXT_shader_texture_lod
         << ":EXT_shader_framebuffer_fetch:" << compileResources.EXT_shader_framebuffer_fetch
         << ":NV_shader_framebuffer_fetch:" << compileResources.NV_shader_framebuffer_fetch
         << ":ARM_shader_framebuffer_fetch:" << compileResources.ARM_shader_framebuffer_fetch
         << ":OVR_multiview:" << compileResources.OVR_multiview
         << ":EXT_YUV_target:" << compileResources.EXT_YUV_target
-        << ":OES_geometry_shader:" << compileResources.OES_geometry_shader
+        << ":EXT_geometry_shader:" << compileResources.EXT_geometry_shader
         << ":MaxVertexOutputVectors:" << compileResources.MaxVertexOutputVectors
         << ":MaxFragmentInputVectors:" << compileResources.MaxFragmentInputVectors
         << ":MinProgramTexelOffset:" << compileResources.MinProgramTexelOffset
         << ":MaxProgramTexelOffset:" << compileResources.MaxProgramTexelOffset
         << ":MaxDualSourceDrawBuffers:" << compileResources.MaxDualSourceDrawBuffers
         << ":MaxViewsOVR:" << compileResources.MaxViewsOVR
         << ":NV_draw_buffers:" << compileResources.NV_draw_buffers
         << ":WEBGL_debug_shader_precision:" << compileResources.WEBGL_debug_shader_precision
@@ -807,16 +874,18 @@ void TCompiler::clearResults()
     mGeometryShaderInvocations         = 0;
     mGeometryShaderMaxVertices         = -1;
 
     builtInFunctionEmulator.cleanup();
 
     nameMap.clear();
 
     mSourcePath     = nullptr;
+
+    symbolTable.clearCompilationResults();
 }
 
 bool TCompiler::initCallDag(TIntermNode *root)
 {
     mCallDag.clear();
 
     switch (mCallDag.init(root, &mDiagnostics))
     {
@@ -849,24 +918,27 @@ bool TCompiler::checkCallDepth()
 
         depths[i] = depth;
 
         if (depth >= maxCallStackDepth)
         {
             // Trace back the function chain to have a meaningful info log.
             std::stringstream errorStream;
             errorStream << "Call stack too deep (larger than " << maxCallStackDepth
-                        << ") with the following call chain: " << record.name;
+                        << ") with the following call chain: "
+                        << record.node->getFunction()->name();
 
             int currentFunction = static_cast<int>(i);
             int currentDepth    = depth;
 
             while (currentFunction != -1)
             {
-                errorStream << " -> " << mCallDag.getRecordFromIndex(currentFunction).name;
+                errorStream
+                    << " -> "
+                    << mCallDag.getRecordFromIndex(currentFunction).node->getFunction()->name();
 
                 int nextFunction = -1;
                 for (auto &calleeIndex : mCallDag.getRecordFromIndex(currentFunction).callees)
                 {
                     if (depths[calleeIndex] == currentDepth - 1)
                     {
                         currentDepth--;
                         nextFunction = calleeIndex;
@@ -886,17 +958,17 @@ bool TCompiler::checkCallDepth()
     return true;
 }
 
 bool TCompiler::tagUsedFunctions()
 {
     // Search from main, starting from the end of the DAG as it usually is the root.
     for (size_t i = mCallDag.size(); i-- > 0;)
     {
-        if (mCallDag.getRecordFromIndex(i).name == "main")
+        if (mCallDag.getRecordFromIndex(i).node->getFunction()->isMain())
         {
             internalTagUsedFunction(i);
             return true;
         }
     }
 
     mDiagnostics.globalError("Missing main()");
     return false;
@@ -926,60 +998,58 @@ class TCompiler::UnusedPredicate
     {
     }
 
     bool operator()(TIntermNode *node)
     {
         const TIntermFunctionPrototype *asFunctionPrototype   = node->getAsFunctionPrototypeNode();
         const TIntermFunctionDefinition *asFunctionDefinition = node->getAsFunctionDefinition();
 
-        const TFunctionSymbolInfo *functionInfo = nullptr;
+        const TFunction *func = nullptr;
 
         if (asFunctionDefinition)
         {
-            functionInfo = asFunctionDefinition->getFunctionSymbolInfo();
+            func = asFunctionDefinition->getFunction();
         }
         else if (asFunctionPrototype)
         {
-            functionInfo = asFunctionPrototype->getFunctionSymbolInfo();
+            func = asFunctionPrototype->getFunction();
         }
-        if (functionInfo == nullptr)
+        if (func == nullptr)
         {
             return false;
         }
 
-        size_t callDagIndex = mCallDag->findIndex(functionInfo);
+        size_t callDagIndex = mCallDag->findIndex(func->uniqueId());
         if (callDagIndex == CallDAG::InvalidIndex)
         {
             // This happens only for unimplemented prototypes which are thus unused
             ASSERT(asFunctionPrototype);
             return true;
         }
 
         ASSERT(callDagIndex < mMetadatas->size());
         return !(*mMetadatas)[callDagIndex].used;
     }
 
   private:
     const CallDAG *mCallDag;
     const std::vector<FunctionMetadata> *mMetadatas;
 };
 
-bool TCompiler::pruneUnusedFunctions(TIntermBlock *root)
+void TCompiler::pruneUnusedFunctions(TIntermBlock *root)
 {
     UnusedPredicate isUnused(&mCallDag, &functionMetadata);
     TIntermSequence *sequence = root->getSequence();
 
     if (!sequence->empty())
     {
         sequence->erase(std::remove_if(sequence->begin(), sequence->end(), isUnused),
                         sequence->end());
     }
-
-    return true;
 }
 
 bool TCompiler::limitExpressionComplexity(TIntermBlock *root)
 {
     if (!IsASTDepthBelowLimit(root, maxExpressionComplexity))
     {
         mDiagnostics.globalError("Expression too complex.");
         return false;
@@ -1002,42 +1072,42 @@ bool TCompiler::shouldCollectVariables(S
 bool TCompiler::wereVariablesCollected() const
 {
     return variablesCollected;
 }
 
 void TCompiler::initializeGLPosition(TIntermBlock *root)
 {
     InitVariableList list;
-    sh::ShaderVariable var(GL_FLOAT_VEC4, 0);
+    sh::ShaderVariable var(GL_FLOAT_VEC4);
     var.name = "gl_Position";
     list.push_back(var);
-    InitializeVariables(root, list, symbolTable, shaderVersion, extensionBehavior);
+    InitializeVariables(root, list, &symbolTable, shaderVersion, extensionBehavior, false, false);
 }
 
 void TCompiler::useAllMembersInUnusedStandardAndSharedBlocks(TIntermBlock *root)
 {
     sh::InterfaceBlockList list;
 
     for (auto block : uniformBlocks)
     {
         if (!block.staticUse &&
-            (block.layout == sh::BLOCKLAYOUT_STANDARD || block.layout == sh::BLOCKLAYOUT_SHARED))
+            (block.layout == sh::BLOCKLAYOUT_STD140 || block.layout == sh::BLOCKLAYOUT_SHARED))
         {
             list.push_back(block);
         }
     }
 
     sh::UseInterfaceBlockFields(root, list, symbolTable);
 }
 
 void TCompiler::initializeOutputVariables(TIntermBlock *root)
 {
     InitVariableList list;
-    if (shaderType == GL_VERTEX_SHADER || shaderType == GL_GEOMETRY_SHADER_OES)
+    if (shaderType == GL_VERTEX_SHADER || shaderType == GL_GEOMETRY_SHADER_EXT)
     {
         for (auto var : outputVaryings)
         {
             list.push_back(var);
             if (var.name == "gl_Position")
             {
                 ASSERT(!mGLPositionInitialized);
                 mGLPositionInitialized = true;
@@ -1047,17 +1117,17 @@ void TCompiler::initializeOutputVariable
     else
     {
         ASSERT(shaderType == GL_FRAGMENT_SHADER);
         for (auto var : outputVariables)
         {
             list.push_back(var);
         }
     }
-    InitializeVariables(root, list, symbolTable, shaderVersion, extensionBehavior);
+    InitializeVariables(root, list, &symbolTable, shaderVersion, extensionBehavior, false, false);
 }
 
 const TExtensionBehavior &TCompiler::getExtensionBehavior() const
 {
     return extensionBehavior;
 }
 
 const char *TCompiler::getSourcePath() const
--- a/gfx/angle/src/compiler/translator/Compiler.h
+++ b/gfx/angle/src/compiler/translator/Compiler.h
@@ -25,16 +25,17 @@
 #include "compiler/translator/Pragma.h"
 #include "compiler/translator/SymbolTable.h"
 #include "third_party/compiler/ArrayBoundsClamper.h"
 
 namespace sh
 {
 
 class TCompiler;
+class TParseContext;
 #ifdef ANGLE_ENABLE_HLSL
 class TranslatorHLSL;
 #endif  // ANGLE_ENABLE_HLSL
 
 //
 // Helper function to identify specs that are based on the WebGL spec.
 //
 bool IsWebGLBasedSpec(ShShaderSpec spec);
@@ -151,18 +152,20 @@ class TCompiler : public TShHandleBase
     bool InitBuiltInSymbolTable(const ShBuiltInResources &resources);
     // Compute the string representation of the built-in resources
     void setResourceString();
     // Return false if the call depth is exceeded.
     bool checkCallDepth();
     // Add emulated functions to the built-in function emulator.
     virtual void initBuiltInFunctionEmulator(BuiltInFunctionEmulator *emu,
                                              ShCompileOptions compileOptions){};
-    // Translate to object code.
-    virtual void translate(TIntermBlock *root, ShCompileOptions compileOptions) = 0;
+    // Translate to object code. May generate performance warnings through the diagnostics.
+    virtual void translate(TIntermBlock *root,
+                           ShCompileOptions compileOptions,
+                           PerformanceDiagnostics *perfDiagnostics) = 0;
     // Insert statements to reference all members in unused uniform blocks with standard and shared
     // layout. This is to work around a Mac driver that treats unused standard/shared
     // uniform blocks as inactive.
     void useAllMembersInUnusedStandardAndSharedBlocks(TIntermBlock *root);
     // Insert statements to initialize output variables in the beginning of main().
     // This is to avoid undefined behaviors.
     void initializeOutputVariables(TIntermBlock *root);
     // Insert gl_Position = vec4(0,0,0,0) to the beginning of main().
@@ -181,17 +184,16 @@ class TCompiler : public TShHandleBase
     bool isVaryingDefined(const char *varyingName);
 
     const ArrayBoundsClamper &getArrayBoundsClamper() const;
     ShArrayIndexClampingStrategy getArrayIndexClampingStrategy() const;
     const BuiltInFunctionEmulator &getBuiltInFunctionEmulator() const;
 
     virtual bool shouldFlattenPragmaStdglInvariantAll() = 0;
     virtual bool shouldCollectVariables(ShCompileOptions compileOptions);
-    virtual bool needToInitializeGlobalsInAST() const { return IsWebGLBasedSpec(shaderSpec); }
 
     bool wereVariablesCollected() const;
     std::vector<sh::Attribute> attributes;
     std::vector<sh::OutputVariable> outputVariables;
     std::vector<sh::Uniform> uniforms;
     std::vector<sh::Varying> inputVaryings;
     std::vector<sh::Varying> outputVaryings;
     std::vector<sh::InterfaceBlock> interfaceBlocks;
@@ -211,22 +213,31 @@ class TCompiler : public TShHandleBase
     void collectInterfaceBlocks();
 
     bool variablesCollected;
 
     bool mGLPositionInitialized;
 
     // Removes unused function declarations and prototypes from the AST
     class UnusedPredicate;
-    bool pruneUnusedFunctions(TIntermBlock *root);
+    void pruneUnusedFunctions(TIntermBlock *root);
 
     TIntermBlock *compileTreeImpl(const char *const shaderStrings[],
                                   size_t numStrings,
                                   const ShCompileOptions compileOptions);
 
+    // Fetches and stores shader metadata that is not stored within the AST itself, such as shader
+    // version.
+    void setASTMetadata(const TParseContext &parseContext);
+
+    // Does checks that need to be run after parsing is complete and returns true if they pass.
+    bool checkAndSimplifyAST(TIntermBlock *root,
+                             const TParseContext &parseContext,
+                             ShCompileOptions compileOptions);
+
     sh::GLenum shaderType;
     ShShaderSpec shaderSpec;
     ShShaderOutput outputType;
 
     struct FunctionMetadata
     {
         FunctionMetadata() : used(false) {}
         bool used;
new file mode 100644
--- /dev/null
+++ b/gfx/angle/src/compiler/translator/Declarator.cpp
@@ -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.
+//
+// Declarator.cpp:
+//   Declarator type for parsing structure field declarators.
+
+#include "compiler/translator/Declarator.h"
+
+namespace sh
+{
+
+TDeclarator::TDeclarator(const TString *name, const TSourceLoc &line)
+    : mName(name), mArraySizes(nullptr), mLine(line)
+{
+    ASSERT(mName);
+}
+
+TDeclarator::TDeclarator(const TString *name,
+                         const TVector<unsigned int> *arraySizes,
+                         const TSourceLoc &line)
+    : mName(name), mArraySizes(arraySizes), mLine(line)
+{
+    ASSERT(mName);
+    ASSERT(mArraySizes);
+}
+
+bool TDeclarator::isArray() const
+{
+    return mArraySizes != nullptr && mArraySizes->size() > 0;
+}
+
+}  // namespace sh
new file mode 100644
--- /dev/null
+++ b/gfx/angle/src/compiler/translator/Declarator.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.
+//
+// Declarator.h:
+//   Declarator type for parsing structure field declarators.
+
+#ifndef COMPILER_TRANSLATOR_DECLARATOR_H_
+#define COMPILER_TRANSLATOR_DECLARATOR_H_
+
+#include "compiler/translator/Common.h"
+
+namespace sh
+{
+
+// Declarator like "a[2][4]". Only used for parsing structure field declarators.
+class TDeclarator : angle::NonCopyable
+{
+  public:
+    POOL_ALLOCATOR_NEW_DELETE();
+    TDeclarator(const TString *name, const TSourceLoc &line);
+
+    TDeclarator(const TString *name,
+                const TVector<unsigned int> *arraySizes,
+                const TSourceLoc &line);
+
+    const TString *name() const { return mName; }
+
+    bool isArray() const;
+    const TVector<unsigned int> *arraySizes() const { return mArraySizes; }
+
+    const TSourceLoc &line() const { return mLine; }
+
+  private:
+    const TString *const mName;
+
+    // Outermost array size is stored at the end of the vector.
+    const TVector<unsigned int> *const mArraySizes;
+
+    const TSourceLoc mLine;
+};
+
+using TDeclaratorList = TVector<TDeclarator *>;
+
+}  // namespace sh
+
+#endif  // COMPILER_TRANSLATOR_DECLARATOR_H_
--- a/gfx/angle/src/compiler/translator/DeclareAndInitBuiltinsForInstancedMultiview.cpp
+++ b/gfx/angle/src/compiler/translator/DeclareAndInitBuiltinsForInstancedMultiview.cpp
@@ -20,43 +20,44 @@ namespace sh
 {
 
 namespace
 {
 
 class ReplaceVariableTraverser : public TIntermTraverser
 {
   public:
-    ReplaceVariableTraverser(const TString &symbolName, TIntermSymbol *newSymbol)
-        : TIntermTraverser(true, false, false), mSymbolName(symbolName), mNewSymbol(newSymbol)
+    ReplaceVariableTraverser(const TVariable *toBeReplaced, const TVariable *replacement)
+        : TIntermTraverser(true, false, false),
+          mToBeReplaced(toBeReplaced),
+          mReplacement(replacement)
     {
     }
 
     void visitSymbol(TIntermSymbol *node) override
     {
-        TName &name = node->getName();
-        if (name.getString() == mSymbolName)
+        if (&node->variable() == mToBeReplaced)
         {
-            queueReplacement(mNewSymbol->deepCopy(), OriginalNode::IS_DROPPED);
+            queueReplacement(new TIntermSymbol(mReplacement), OriginalNode::IS_DROPPED);
         }
     }
 
   private:
-    TString mSymbolName;
-    TIntermSymbol *mNewSymbol;
+    const TVariable *const mToBeReplaced;
+    const TVariable *const mReplacement;
 };
 
 TIntermSymbol *CreateGLInstanceIDSymbol(const TSymbolTable &symbolTable)
 {
     return ReferenceBuiltInVariable("gl_InstanceID", symbolTable, 300);
 }
 
 // Adds the InstanceID and ViewID_OVR initializers to the end of the initializers' sequence.
-void InitializeViewIDAndInstanceID(TIntermTyped *viewIDSymbol,
-                                   TIntermTyped *instanceIDSymbol,
+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 =
@@ -75,82 +76,83 @@ void InitializeViewIDAndInstanceID(TInte
     // 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, instanceIDSymbol->deepCopy(), normalizedInstanceIDAsInt);
+        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, viewIDSymbol->deepCopy(), normalizedViewID);
+        new TIntermBinary(EOpAssign, new TIntermSymbol(viewID), normalizedViewID);
     initializers->push_back(viewIDInitializer);
 }
 
-// Replaces every occurrence of a symbol with the name specified in symbolName with newSymbolNode.
-void ReplaceSymbol(TIntermBlock *root, const TString &symbolName, TIntermSymbol *newSymbolNode)
+// Replaces every occurrence of a variable with another variable.
+void ReplaceSymbol(TIntermBlock *root, const TVariable *toBeReplaced, const TVariable *replacement)
 {
-    ReplaceVariableTraverser traverser(symbolName, newSymbolNode);
+    ReplaceVariableTraverser traverser(toBeReplaced, replacement);
     root->traverse(&traverser);
     traverser.updateTree();
 }
 
-void DeclareGlobalVariable(TIntermBlock *root, TIntermTyped *typedNode)
+void DeclareGlobalVariable(TIntermBlock *root, const TVariable *variable)
 {
+    TIntermDeclaration *declaration = new TIntermDeclaration();
+    declaration->appendDeclarator(new TIntermSymbol(variable));
+
     TIntermSequence *globalSequence = root->getSequence();
-    TIntermDeclaration *declaration = new TIntermDeclaration();
-    declaration->appendDeclarator(typedNode->deepCopy());
     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(TIntermTyped *viewIDSymbol,
-                                   TIntermTyped *multiviewBaseViewLayerIndexSymbol,
+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(viewIDSymbol);
+    viewIDSymbolCastArguments->push_back(new TIntermSymbol(viewID));
     TIntermAggregate *viewIDAsInt = TIntermAggregate::CreateConstructor(
         TType(EbtInt, EbpHigh, EvqTemporary), viewIDSymbolCastArguments);
 
     // Create a gl_ViewportIndex node.
     TIntermSymbol *viewportIndexSymbol =
         ReferenceBuiltInVariable("gl_ViewportIndex", 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 = new TIntermSymbol(0, "gl_Layer", TType(EbtInt, EbpHigh, EvqLayer));
+    TIntermSymbol *layerSymbol = ReferenceBuiltInVariable("gl_Layer", symbolTable, 0);
 
     // Create an int(ViewID_OVR) + multiviewBaseViewLayerIndex node
-    TIntermBinary *sumOfViewIDAndBaseViewIndex =
-        new TIntermBinary(EOpAdd, viewIDAsInt->deepCopy(), multiviewBaseViewLayerIndexSymbol);
+    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, multiviewBaseViewLayerIndexSymbol->deepCopy(),
+        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);
@@ -163,56 +165,62 @@ void DeclareAndInitBuiltinsForInstancedM
                                                  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;
-    TIntermSymbol *viewIDSymbol = new TIntermSymbol(symbolTable->nextUniqueId(), "ViewID_OVR",
-                                                    TType(EbtUInt, EbpHigh, viewIDQualifier));
-    viewIDSymbol->setInternal(true);
+    const TString *viewIDVariableName = NewPoolTString("ViewID_OVR");
+    const TVariable *viewID =
+        new TVariable(symbolTable, viewIDVariableName, TType(EbtUInt, EbpHigh, viewIDQualifier),
+                      SymbolType::AngleInternal);
 
-    DeclareGlobalVariable(root, viewIDSymbol);
-    ReplaceSymbol(root, "gl_ViewID_OVR", viewIDSymbol);
+    DeclareGlobalVariable(root, viewID);
+    ReplaceSymbol(root,
+                  static_cast<TVariable *>(symbolTable->findBuiltIn("gl_ViewID_OVR", 300, true)),
+                  viewID);
     if (shaderType == GL_VERTEX_SHADER)
     {
         // Replacing gl_InstanceID with InstanceID should happen before adding the initializers of
         // InstanceID and ViewID.
-        TIntermSymbol *instanceIDSymbol = new TIntermSymbol(
-            symbolTable->nextUniqueId(), "InstanceID", TType(EbtInt, EbpHigh, EvqGlobal));
-        instanceIDSymbol->setInternal(true);
-        DeclareGlobalVariable(root, instanceIDSymbol);
-        ReplaceSymbol(root, "gl_InstanceID", instanceIDSymbol);
+        const TString *instanceIDVariableName = NewPoolTString("InstanceID");
+        const TVariable *instanceID =
+            new TVariable(symbolTable, instanceIDVariableName, TType(EbtInt, EbpHigh, EvqGlobal),
+                          SymbolType::AngleInternal);
+        DeclareGlobalVariable(root, instanceID);
+        ReplaceSymbol(
+            root, static_cast<TVariable *>(symbolTable->findBuiltIn("gl_InstanceID", 300, true)),
+            instanceID);
 
         TIntermSequence *initializers = new TIntermSequence();
-        InitializeViewIDAndInstanceID(viewIDSymbol, instanceIDSymbol, numberOfViews, *symbolTable,
+        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.
-            TIntermSymbol *multiviewBaseViewLayerIndexSymbol =
-                new TIntermSymbol(symbolTable->nextUniqueId(), "multiviewBaseViewLayerIndex",
-                                  TType(EbtInt, EbpHigh, EvqUniform));
-            multiviewBaseViewLayerIndexSymbol->setInternal(true);
-            DeclareGlobalVariable(root, multiviewBaseViewLayerIndexSymbol);
+            const TString *multiviewBaseViewLayerIndexVariableName =
+                NewPoolTString("multiviewBaseViewLayerIndex");
+            const TVariable *multiviewBaseViewLayerIndex =
+                new TVariable(symbolTable, multiviewBaseViewLayerIndexVariableName,
+                              TType(EbtInt, EbpHigh, EvqUniform), SymbolType::AngleInternal);
+            DeclareGlobalVariable(root, multiviewBaseViewLayerIndex);
 
             // Setting a value to gl_ViewportIndex or gl_Layer should happen after ViewID_OVR's
             // initialization.
-            SelectViewIndexInVertexShader(viewIDSymbol->deepCopy(),
-                                          multiviewBaseViewLayerIndexSymbol->deepCopy(),
-                                          initializers, *symbolTable);
+            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);
     }
--- a/gfx/angle/src/compiler/translator/DeferGlobalInitializers.cpp
+++ b/gfx/angle/src/compiler/translator/DeferGlobalInitializers.cpp
@@ -24,131 +24,125 @@
 namespace sh
 {
 
 namespace
 {
 
 void GetDeferredInitializers(TIntermDeclaration *declaration,
                              bool initializeUninitializedGlobals,
-                             TIntermSequence *deferredInitializersOut)
+                             bool canUseLoopsToInitialize,
+                             bool highPrecisionSupported,
+                             TIntermSequence *deferredInitializersOut,
+                             TSymbolTable *symbolTable)
 {
-    // We iterate with an index instead of using an iterator since we're replacing the children of
-    // declaration inside the loop.
-    for (size_t i = 0; i < declaration->getSequence()->size(); ++i)
+    // SeparateDeclarations should have already been run.
+    ASSERT(declaration->getSequence()->size() == 1);
+
+    TIntermNode *declarator = declaration->getSequence()->back();
+    TIntermBinary *init     = declarator->getAsBinaryNode();
+    if (init)
     {
-        TIntermNode *declarator = declaration->getSequence()->at(i);
-        TIntermBinary *init     = declarator->getAsBinaryNode();
-        if (init)
+        TIntermSymbol *symbolNode = init->getLeft()->getAsSymbolNode();
+        ASSERT(symbolNode);
+        TIntermTyped *expression = init->getRight();
+
+        if ((expression->getQualifier() != EvqConst ||
+             (expression->getAsConstantUnion() == nullptr &&
+              !expression->isConstructorWithOnlyConstantUnionParameters())))
         {
-            TIntermSymbol *symbolNode = init->getLeft()->getAsSymbolNode();
-            ASSERT(symbolNode);
-            TIntermTyped *expression = init->getRight();
-
-            if ((expression->getQualifier() != EvqConst ||
-                 (expression->getAsConstantUnion() == nullptr &&
-                  !expression->isConstructorWithOnlyConstantUnionParameters())))
-            {
-                // 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 has not been constant
-                // folded, since otherwise there's a chance that HLSL output will generate extra
-                // statements from the initializer expression.
-                TIntermBinary *deferredInit =
-                    new TIntermBinary(EOpAssign, symbolNode->deepCopy(), init->getRight());
-                deferredInitializersOut->push_back(deferredInit);
+            // 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 has not been constant
+            // folded, 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)
-                {
-                    // All of the siblings in the same declaration need to have consistent
-                    // qualifiers.
-                    auto *siblings = declaration->getSequence();
-                    for (TIntermNode *siblingNode : *siblings)
-                    {
-                        TIntermBinary *siblingBinary = siblingNode->getAsBinaryNode();
-                        if (siblingBinary)
-                        {
-                            ASSERT(siblingBinary->getOp() == EOpInitialize);
-                            siblingBinary->getLeft()->getTypePointer()->setQualifier(EvqGlobal);
-                        }
-                        siblingNode->getAsTyped()->getTypePointer()->setQualifier(EvqGlobal);
-                    }
-                    // This node is one of the siblings.
-                    ASSERT(symbolNode->getQualifier() == EvqGlobal);
-                }
-                // Remove the initializer from the global scope and just declare the global instead.
-                declaration->replaceChildNode(init, symbolNode);
+            // 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)
+            {
+                symbolNode->getTypePointer()->setQualifier(EvqGlobal);
             }
-        }
-        else if (initializeUninitializedGlobals)
-        {
-            TIntermSymbol *symbolNode = declarator->getAsSymbolNode();
-            ASSERT(symbolNode);
+
+            TIntermBinary *deferredInit =
+                new TIntermBinary(EOpAssign, symbolNode->deepCopy(), init->getRight());
+            deferredInitializersOut->push_back(deferredInit);
 
-            // Ignore ANGLE internal variables.
-            if (symbolNode->getName().isInternal())
-                continue;
+            // 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);
 
-            if (symbolNode->getQualifier() == EvqGlobal && symbolNode->getSymbol() != "")
-            {
-                TIntermSequence *initCode = CreateInitCode(symbolNode);
-                deferredInitializersOut->insert(deferredInitializersOut->end(), initCode->begin(),
-                                                initCode->end());
-            }
+        // 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);
 
-    TSymbolUniqueId initGlobalsFunctionId(symbolTable);
-
-    const char *kInitGlobalsFunctionName = "initGlobals";
+    TFunction *initGlobalsFunction =
+        new TFunction(symbolTable, NewPoolTString("initGlobals"), new TType(EbtVoid),
+                      SymbolType::AngleInternal, false);
 
     TIntermFunctionPrototype *initGlobalsFunctionPrototype =
-        CreateInternalFunctionPrototypeNode(TType(), kInitGlobalsFunctionName, initGlobalsFunctionId);
+        CreateInternalFunctionPrototypeNode(*initGlobalsFunction);
     root->getSequence()->insert(root->getSequence()->begin(), initGlobalsFunctionPrototype);
-    TIntermFunctionDefinition *initGlobalsFunctionDefinition = CreateInternalFunctionDefinitionNode(
-        TType(), kInitGlobalsFunctionName, initGlobalsBlock, initGlobalsFunctionId);
+    TIntermFunctionDefinition *initGlobalsFunctionDefinition =
+        CreateInternalFunctionDefinitionNode(*initGlobalsFunction, initGlobalsBlock);
     root->appendStatement(initGlobalsFunctionDefinition);
 
-    TIntermAggregate *initGlobalsCall = CreateInternalFunctionCallNode(
-        TType(), kInitGlobalsFunctionName, initGlobalsFunctionId, new TIntermSequence());
+    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();
 
     // 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,
-                                    deferredInitializers);
+                                    canUseLoopsToInitialize, highPrecisionSupported,
+                                    deferredInitializers, symbolTable);
         }
     }
 
     // Add the function with initialization and the call to that.
     if (!deferredInitializers->empty())
     {
         InsertInitCallToMain(root, deferredInitializers, symbolTable);
     }
--- a/gfx/angle/src/compiler/translator/DeferGlobalInitializers.h
+++ b/gfx/angle/src/compiler/translator/DeferGlobalInitializers.h
@@ -19,13 +19,15 @@
 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_
--- a/gfx/angle/src/compiler/translator/Diagnostics.cpp
+++ b/gfx/angle/src/compiler/translator/Diagnostics.cpp
@@ -86,9 +86,20 @@ void TDiagnostics::print(ID id, const pp
 }
 
 void TDiagnostics::resetErrorCount()
 {
     mNumErrors   = 0;
     mNumWarnings = 0;
 }
 
+PerformanceDiagnostics::PerformanceDiagnostics(TDiagnostics *diagnostics)
+    : mDiagnostics(diagnostics)
+{
+    ASSERT(diagnostics);
+}
+
+void PerformanceDiagnostics::warning(const TSourceLoc &loc, const char *reason, const char *token)
+{
+    mDiagnostics->warning(loc, reason, token);
+}
+
 }  // namespace sh
--- a/gfx/angle/src/compiler/translator/Diagnostics.h
+++ b/gfx/angle/src/compiler/translator/Diagnostics.h
@@ -45,11 +45,23 @@ class TDiagnostics : public pp::Diagnost
     void print(ID id, const pp::SourceLocation &loc, const std::string &text) override;
 
   private:
     TInfoSinkBase &mInfoSink;
     int mNumErrors;
     int mNumWarnings;
 };
 
+// Diagnostics wrapper to use when the code is only allowed to generate warnings.
+class PerformanceDiagnostics : public angle::NonCopyable
+{
+  public:
+    PerformanceDiagnostics(TDiagnostics *diagnostics);
+
+    void warning(const TSourceLoc &loc, const char *reason, const char *token);
+
+  private:
+    TDiagnostics *mDiagnostics;
+};
+
 }  // namespace sh
 
 #endif  // COMPILER_TRANSLATOR_DIAGNOSTICS_H_
--- a/gfx/angle/src/compiler/translator/EmulateGLFragColorBroadcast.cpp
+++ b/gfx/angle/src/compiler/translator/EmulateGLFragColorBroadcast.cpp
@@ -11,16 +11,17 @@
 // 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
 {
 
 class GLFragColorBroadcastTraverser : public TIntermTraverser
@@ -65,17 +66,17 @@ TIntermBinary *GLFragColorBroadcastTrave
     TIntermTyped *fragDataIndex = constructGLFragDataNode(index);
     TIntermTyped *fragDataZero  = constructGLFragDataNode(0);
 
     return new TIntermBinary(EOpAssign, fragDataIndex, fragDataZero);
 }
 
 void GLFragColorBroadcastTraverser::visitSymbol(TIntermSymbol *node)
 {
-    if (node->getSymbol() == "gl_FragColor")
+    if (node->variable().symbolType() == SymbolType::BuiltIn && node->getName() == "gl_FragColor")
     {
         queueReplacement(constructGLFragDataNode(0), OriginalNode::IS_DROPPED);
         mGLFragColorUsed = true;
     }
 }
 
 void GLFragColorBroadcastTraverser::broadcastGLFragColor(TIntermBlock *root)
 {
@@ -114,15 +115,16 @@ void EmulateGLFragColorBroadcast(TInterm
         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.arraySize  = maxDrawBuffers;
+                var.arraySizes.push_back(maxDrawBuffers);
+                ASSERT(var.arraySizes.size() == 1u);
             }
         }
     }
 }
 
 }  // namespace sh
--- a/gfx/angle/src/compiler/translator/EmulatePrecision.cpp
+++ b/gfx/angle/src/compiler/translator/EmulatePrecision.cpp
@@ -422,59 +422,16 @@ void RoundingHelperWriterHLSL::writeMatr
 }
 
 bool canRoundFloat(const TType &type)
 {
     return type.getBasicType() == EbtFloat && !type.isArray() &&
            (type.getPrecision() == EbpLow || type.getPrecision() == EbpMedium);
 }
 
-TIntermAggregate *createInternalFunctionCallNode(const TType &type,
-                                                 TString name,
-                                                 TIntermSequence *arguments)
-{
-    TName nameObj(name);
-    nameObj.setInternal(true);
-    TIntermAggregate *callNode =
-        TIntermAggregate::Create(type, EOpCallInternalRawFunction, arguments);
-    callNode->getFunctionSymbolInfo()->setNameObj(nameObj);
-    return callNode;
-}
-
-TIntermAggregate *createRoundingFunctionCallNode(TIntermTyped *roundedChild)
-{
-    TString roundFunctionName;
-    if (roundedChild->getPrecision() == EbpMedium)
-        roundFunctionName = "angle_frm";
-    else
-        roundFunctionName      = "angle_frl";
-    TIntermSequence *arguments = new TIntermSequence();
-    arguments->push_back(roundedChild);
-    TIntermAggregate *callNode =
-        createInternalFunctionCallNode(roundedChild->getType(), roundFunctionName, arguments);
-    callNode->getFunctionSymbolInfo()->setKnownToNotHaveSideEffects(true);
-    return callNode;
-}
-
-TIntermAggregate *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";
-    TString functionName       = strstr.str().c_str();
-    TIntermSequence *arguments = new TIntermSequence();
-    arguments->push_back(left);
-    arguments->push_back(right);
-    return createInternalFunctionCallNode(left->getType(), functionName, arguments);
-}
-
 bool ParentUsesResult(TIntermNode *parent, TIntermTyped *node)
 {
     if (!parent)
     {
         return false;
     }
 
     TIntermBlock *blockParent = parent->getAsBlock();
@@ -743,9 +700,55 @@ bool EmulatePrecision::SupportedInLangua
             return true;
         default:
             // Other languages not yet supported
             return (outputLanguage == SH_GLSL_COMPATIBILITY_OUTPUT ||
                     sh::IsGLSL130OrNewer(outputLanguage));
     }
 }
 
+TFunction *EmulatePrecision::getInternalFunction(TString *functionName,
+                                                 const TType &returnType,
+                                                 TIntermSequence *arguments,
+                                                 bool knownToNotHaveSideEffects)
+{
+    TString mangledName = TFunction::GetMangledNameFromCall(*functionName, *arguments);
+    if (mInternalFunctions.find(mangledName) == mInternalFunctions.end())
+    {
+        mInternalFunctions[mangledName] =
+            new TFunction(mSymbolTable, functionName, new TType(returnType),
+                          SymbolType::AngleInternal, knownToNotHaveSideEffects);
+    }
+    return mInternalFunctions[mangledName];
+}
+
+TIntermAggregate *EmulatePrecision::createRoundingFunctionCallNode(TIntermTyped *roundedChild)
+{
+    const char *roundFunctionName;
+    if (roundedChild->getPrecision() == EbpMedium)
+        roundFunctionName = "angle_frm";
+    else
+        roundFunctionName = "angle_frl";
+    TString *functionName      = NewPoolTString(roundFunctionName);
+    TIntermSequence *arguments = new TIntermSequence();
+    arguments->push_back(roundedChild);
+    return TIntermAggregate::CreateRawFunctionCall(
+        *getInternalFunction(functionName, roundedChild->getType(), arguments, 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";
+    TString *functionName      = NewPoolTString(strstr.str().c_str());
+    TIntermSequence *arguments = new TIntermSequence();
+    arguments->push_back(left);
+    arguments->push_back(right);
+    return TIntermAggregate::CreateRawFunctionCall(
+        *getInternalFunction(functionName, left->getType(), arguments, false), arguments);
+}
+
 }  // namespace sh
--- a/gfx/angle/src/compiler/translator/EmulatePrecision.h
+++ b/gfx/angle/src/compiler/translator/EmulatePrecision.h
@@ -54,20 +54,32 @@ class EmulatePrecision : public TLValueT
         bool operator()(const TypePair &l, const TypePair &r) const
         {
             if (l.lType == r.lType)
                 return l.rType < r.rType;
             return l.lType < r.lType;
         }
     };
 
+    TFunction *getInternalFunction(TString *functionName,
+                                   const TType &returnType,
+                                   TIntermSequence *arguments,
+                                   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<TString, TFunction *> mInternalFunctions;
+
     bool mDeclaringVariables;
 };
 
 }  // namespace sh
 
 #endif  // COMPILER_TRANSLATOR_EMULATE_PRECISION_H_
--- a/gfx/angle/src/compiler/translator/ExpandIntegerPowExpressions.cpp
+++ b/gfx/angle/src/compiler/translator/ExpandIntegerPowExpressions.cpp
@@ -6,16 +6,17 @@
 // 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
 {
 
@@ -49,17 +50,16 @@ void Traverser::Apply(TIntermNode *root,
 
 Traverser::Traverser(TSymbolTable *symbolTable) : TIntermTraverser(true, false, false, symbolTable)
 {
 }
 
 void Traverser::nextIteration()
 {
     mFound = false;
-    nextTemporaryId();
 }
 
 bool Traverser::visitAggregate(Visit visit, TIntermAggregate *node)
 {
     if (mFound)
     {
         return false;
     }
@@ -67,68 +67,62 @@ bool Traverser::visitAggregate(Visit vis
     // Test 0: skip non-pow operators.
     if (node->getOp() != EOpPow)
     {
         return true;
     }
 
     const TIntermSequence *sequence = node->getSequence();
     ASSERT(sequence->size() == 2u);
-    const TIntermConstantUnion *constantNode = sequence->at(1)->getAsConstantUnion();
+    const TIntermConstantUnion *constantExponent = sequence->at(1)->getAsConstantUnion();
 
     // Test 1: check for a single constant.
-    if (!constantNode || constantNode->getNominalSize() != 1)
+    if (!constantExponent || constantExponent->getNominalSize() != 1)
     {
         return true;
     }
 
-    const TConstantUnion *constant = constantNode->getUnionArrayPointer();
-
-    TConstantUnion asFloat;
-    asFloat.cast(EbtFloat, *constant);
+    ASSERT(constantExponent->getBasicType() == EbtFloat);
+    float exponentValue = constantExponent->getUnionArrayPointer()->getFConst();
 
-    float value = asFloat.getFConst();
-
-    // Test 2: value is in the problematic range.
-    if (value < -5.0f || value > 9.0f)
+    // Test 2: exponentValue is in the problematic range.
+    if (exponentValue < -5.0f || exponentValue > 9.0f)
     {
         return true;
     }
 
-    // Test 3: value is integer or pretty close to an integer.
-    float absval = std::abs(value);
-    float frac   = absval - std::round(absval);
-    if (frac > 0.0001f)
+    // 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>(value);
+    int exponent = static_cast<int>(std::round(exponentValue));
     int n        = std::abs(exponent);
     if (n < 2)
     {
         return true;
     }
 
     // Potential problem case detected, apply workaround.
-    nextTemporaryId();
 
     TIntermTyped *lhs = sequence->at(0)->getAsTyped();
     ASSERT(lhs);
 
-    TIntermDeclaration *init = createTempInitDeclaration(lhs);
-    TIntermTyped *current    = createTempSymbol(lhs->getType());
-
-    insertStatementInParentBlock(init);
+    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, createTempSymbol(lhs->getType()));
+        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();
--- a/gfx/angle/src/compiler/translator/ExtensionBehavior.cpp
+++ b/gfx/angle/src/compiler/translator/ExtensionBehavior.cpp
@@ -13,24 +13,24 @@
 #include <string.h>
 
 #define LIST_EXTENSIONS(OP)             \
     OP(ARB_texture_rectangle)           \
     OP(ARM_shader_framebuffer_fetch)    \
     OP(EXT_blend_func_extended)         \
     OP(EXT_draw_buffers)                \
     OP(EXT_frag_depth)                  \
+    OP(EXT_geometry_shader)             \
     OP(EXT_shader_framebuffer_fetch)    \
     OP(EXT_shader_texture_lod)          \
     OP(EXT_YUV_target)                  \
     OP(NV_EGL_stream_consumer_external) \
     OP(NV_shader_framebuffer_fetch)     \
     OP(OES_EGL_image_external)          \
     OP(OES_EGL_image_external_essl3)    \
-    OP(OES_geometry_shader)             \
     OP(OES_standard_derivatives)        \
     OP(OVR_multiview)
 
 namespace sh
 {
 
 #define RETURN_EXTENSION_NAME_CASE(ext) \
     case TExtension::ext:               \
@@ -83,12 +83,13 @@ const char *GetBehaviorString(TBehavior 
             return nullptr;
     }
 }
 
 bool IsExtensionEnabled(const TExtensionBehavior &extBehavior, TExtension extension)
 {
     ASSERT(extension != TExtension::UNDEFINED);
     auto iter = extBehavior.find(extension);
-    return iter != extBehavior.end() && (iter->second == EBhEnable || iter->second == EBhRequire);
+    return iter != extBehavior.end() &&
+           (iter->second == EBhEnable || iter->second == EBhRequire || iter->second == EBhWarn);
 }
 
 }  // namespace sh
--- a/gfx/angle/src/compiler/translator/ExtensionBehavior.h
+++ b/gfx/angle/src/compiler/translator/ExtensionBehavior.h
@@ -18,24 +18,24 @@ enum class TExtension
 {
     UNDEFINED,  // Special value used to indicate no extension.
 
     ARB_texture_rectangle,
     ARM_shader_framebuffer_fetch,
     EXT_blend_func_extended,
     EXT_draw_buffers,
     EXT_frag_depth,
+    EXT_geometry_shader,
     EXT_shader_framebuffer_fetch,
     EXT_shader_texture_lod,
     EXT_YUV_target,
     NV_EGL_stream_consumer_external,
     NV_shader_framebuffer_fetch,
     OES_EGL_image_external,
     OES_EGL_image_external_essl3,
-    OES_geometry_shader,
     OES_standard_derivatives,
     OVR_multiview
 };
 
 enum TBehavior
 {
     EBhRequire,
     EBhEnable,
--- a/gfx/angle/src/compiler/translator/FindMain.cpp
+++ b/gfx/angle/src/compiler/translator/FindMain.cpp
@@ -4,26 +4,27 @@
 // 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->getFunctionSymbolInfo()->isMain())
+        if (nodeFunction != nullptr && nodeFunction->getFunction()->isMain())
         {
             return nodeFunction;
         }
     }
     return nullptr;
 }
 
 TIntermBlock *FindMainBody(TIntermBlock *root)
--- a/gfx/angle/src/compiler/translator/FindSymbolNode.cpp
+++ b/gfx/angle/src/compiler/translator/FindSymbolNode.cpp
@@ -4,55 +4,50 @@
 // 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/IntermTraverse.h"
+#include "compiler/translator/Symbol.h"
 
 namespace sh
 {
 
 namespace
 {
 
 class SymbolFinder : public TIntermTraverser
 {
   public:
-    SymbolFinder(const TString &symbolName, TBasicType basicType)
-        : TIntermTraverser(true, false, false),
-          mSymbolName(symbolName),
-          mNodeFound(nullptr),
-          mBasicType(basicType)
+    SymbolFinder(const TString &symbolName)
+        : TIntermTraverser(true, false, false), mSymbolName(symbolName), mNodeFound(nullptr)
     {
     }
 
     void visitSymbol(TIntermSymbol *node)
     {
-        if (node->getBasicType() == mBasicType && node->getSymbol() == mSymbolName)
+        if (node->variable().symbolType() != SymbolType::Empty && node->getName() == mSymbolName)
         {
             mNodeFound = node;
         }
     }
 
     bool isFound() const { return mNodeFound != nullptr; }
     const TIntermSymbol *getNode() const { return mNodeFound; }
 
   private:
     TString mSymbolName;
     TIntermSymbol *mNodeFound;
-    TBasicType mBasicType;
 };
 
 }  // anonymous namespace
 
-const TIntermSymbol *FindSymbolNode(TIntermNode *root,
-                                    const TString &symbolName,
-                                    TBasicType basicType)
+const TIntermSymbol *FindSymbolNode(TIntermNode *root, const TString &symbolName)
 {
-    SymbolFinder finder(symbolName, basicType);
+    SymbolFinder finder(symbolName);
     root->traverse(&finder);
     return finder.getNode();
 }
 
 }  // namespace sh
--- a/gfx/angle/src/compiler/translator/FindSymbolNode.h
+++ b/gfx/angle/src/compiler/translator/FindSymbolNode.h
@@ -13,15 +13,13 @@
 #include "compiler/translator/Common.h"
 
 namespace sh
 {
 
 class TIntermNode;
 class TIntermSymbol;
 
-const TIntermSymbol *FindSymbolNode(TIntermNode *root,
-                                    const TString &symbolName,
-                                    TBasicType basicType);
+const TIntermSymbol *FindSymbolNode(TIntermNode *root, const TString &symbolName);
 
 }  // namespace sh
 
 #endif  // COMPILER_TRANSLATOR_FIND_SYMBOL_H_
\ No newline at end of file
--- a/gfx/angle/src/compiler/translator/FlagStd140Structs.cpp
+++ b/gfx/angle/src/compiler/translator/FlagStd140Structs.cpp
@@ -1,77 +1,76 @@
 //
 // Copyright (c) 2013 The ANGLE Project Authors. All rights reserved.
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 //
+// FlagStd140Structs.cpp: Find structs in std140 blocks, where the padding added in the translator
+// conflicts with the "natural" unpadded type.
 
 #include "compiler/translator/FlagStd140Structs.h"
 
+#include "compiler/translator/IntermTraverse.h"
+#include "compiler/translator/SymbolTable.h"
+
 namespace sh
 {
 
-bool FlagStd140Structs::visitBinary(Visit visit, TIntermBinary *binaryNode)
+namespace
+{
+
+class FlagStd140StructsTraverser : public TIntermTraverser
 {
-    if (binaryNode->getRight()->getBasicType() == EbtStruct)
+  public:
+    FlagStd140StructsTraverser() : TIntermTraverser(true, false, false) {}
+
+    const std::vector<MappedStruct> getMappedStructs() const { return mMappedStructs; }
+
+  protected:
+    bool visitDeclaration(Visit visit, TIntermDeclaration *node) override;
+
+  private:
+    void mapBlockStructMembers(TIntermSymbol *blockDeclarator, TInterfaceBlock *block);
+
+    std::vector<MappedStruct> mMappedStructs;
+};
+
+void FlagStd140StructsTraverser::mapBlockStructMembers(TIntermSymbol *blockDeclarator,
+                                                       TInterfaceBlock *block)
+{
+    for (auto *field : block->fields())
     {
-        switch (binaryNode->getOp())
+        if (field->type()->getBasicType() == EbtStruct)
         {
-            case EOpIndexDirectInterfaceBlock:
-            case EOpIndexDirectStruct:
-                if (isInStd140InterfaceBlock(binaryNode->getLeft()))
-                {
-                    mFlaggedNodes.push_back(binaryNode);
-                }
-                break;
-
-            default:
-                break;
+            MappedStruct mappedStruct;
+            mappedStruct.blockDeclarator = blockDeclarator;
+            mappedStruct.field           = field;
+            mMappedStructs.push_back(mappedStruct);
         }
-        return false;
-    }
-
-    if (binaryNode->getOp() == EOpIndexDirectStruct)
-    {
-        return false;
-    }
-
-    return visit == PreVisit;
-}
-
-void FlagStd140Structs::visitSymbol(TIntermSymbol *symbol)
-{
-    if (isInStd140InterfaceBlock(symbol) && symbol->getBasicType() == EbtStruct)
-    {
-        mFlaggedNodes.push_back(symbol);
     }
 }
 
-bool FlagStd140Structs::isInStd140InterfaceBlock(TIntermTyped *node) const
+bool FlagStd140StructsTraverser::visitDeclaration(Visit visit, TIntermDeclaration *node)
 {
-    TIntermBinary *binaryNode = node->getAsBinaryNode();
-
-    if (binaryNode)
+    TIntermTyped *declarator = node->getSequence()->back()->getAsTyped();
+    if (declarator->getBasicType() == EbtInterfaceBlock)
     {
-        return isInStd140InterfaceBlock(binaryNode->getLeft());
+        TInterfaceBlock *block = declarator->getType().getInterfaceBlock();
+        if (block->blockStorage() == EbsStd140)
+        {
+            mapBlockStructMembers(declarator->getAsSymbolNode(), block);
+        }
     }
-
-    const TType &type = node->getType();
-
-    // determine if we are in the standard layout
-    const TInterfaceBlock *interfaceBlock = type.getInterfaceBlock();
-    if (interfaceBlock)
-    {
-        return (interfaceBlock->blockStorage() == EbsStd140);
-    }
-
     return false;
 }
 
-std::vector<TIntermTyped *> FlagStd140ValueStructs(TIntermNode *node)
+}  // anonymous namespace
+
+std::vector<MappedStruct> FlagStd140Structs(TIntermNode *node)
 {
-    FlagStd140Structs flaggingTraversal;
+    FlagStd140StructsTraverser flaggingTraversal;
 
     node->traverse(&flaggingTraversal);
 
-    return flaggingTraversal.getFlaggedNodes();
+    return flaggingTraversal.getMappedStructs();
 }
-}
+
+}  // namespace sh
--- a/gfx/angle/src/compiler/translator/FlagStd140Structs.h
+++ b/gfx/angle/src/compiler/translator/FlagStd140Structs.h
@@ -1,38 +1,30 @@
 //
 // Copyright (c) 2013 The ANGLE Project Authors. All rights reserved.
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 //
+// FlagStd140Structs.h: Find structs in std140 blocks, where the padding added in the translator
+// conflicts with the "natural" unpadded type.
 
 #ifndef COMPILER_TRANSLATOR_FLAGSTD140STRUCTS_H_
 #define COMPILER_TRANSLATOR_FLAGSTD140STRUCTS_H_
 
-#include "compiler/translator/IntermTraverse.h"
+#include <vector>
 
 namespace sh
 {
 
-// This class finds references to nested structs of std140 blocks that access
-// the nested struct "by value", where the padding added in the translator
-// conflicts with the "natural" unpadded type.
-class FlagStd140Structs : public TIntermTraverser
-{
-  public:
-    FlagStd140Structs() : TIntermTraverser(true, false, false) {}
+class TField;
+class TIntermNode;
+class TIntermSymbol;
 
-    const std::vector<TIntermTyped *> getFlaggedNodes() const { return mFlaggedNodes; }
-
-  protected:
-    bool visitBinary(Visit visit, TIntermBinary *binaryNode) override;
-    void visitSymbol(TIntermSymbol *symbol) override;
-
-  private:
-    bool isInStd140InterfaceBlock(TIntermTyped *node) const;
-
-    std::vector<TIntermTyped *> mFlaggedNodes;
+struct MappedStruct
+{
+    TIntermSymbol *blockDeclarator;
+    TField *field;
 };
 
-std::vector<TIntermTyped *> FlagStd140ValueStructs(TIntermNode *node);
+std::vector<MappedStruct> FlagStd140Structs(TIntermNode *node);
 }
 
 #endif  // COMPILER_TRANSLATOR_FLAGSTD140STRUCTS_H_
new file mode 100644
--- /dev/null
+++ b/gfx/angle/src/compiler/translator/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/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
new file mode 100644
--- /dev/null
+++ b/gfx/angle/src/compiler/translator/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_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/src/compiler/translator/HashNames.cpp
+++ b/gfx/angle/src/compiler/translator/HashNames.cpp
@@ -2,16 +2,17 @@
 // 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/HashNames.h"
 
 #include "compiler/translator/IntermNode.h"
+#include "compiler/translator/Symbol.h"
 
 namespace sh
 {
 
 namespace
 {
 
 // GLSL ES 3.00.6 section 3.9: the maximum length of an identifier is 1024 characters.
@@ -33,40 +34,50 @@ TString HashName(const TString &name, Sh
     TStringStream stream;
     stream << kHashedNamePrefix << std::hex << number;
     TString hashedName = stream.str();
     return hashedName;
 }
 
 }  // anonymous namespace
 
-TString HashName(const TName &name, ShHashFunction64 hashFunction, NameMap *nameMap)
+TString HashName(const TString &name, ShHashFunction64 hashFunction, NameMap *nameMap)
 {
-    if (name.getString().empty() || name.isInternal())
-    {
-        return name.getString();
-    }
     if (hashFunction == nullptr)
     {
-        if (name.getString().length() + kUnhashedNamePrefixLength > kESSLMaxIdentifierLength)
+        if (name.length() + kUnhashedNamePrefixLength > kESSLMaxIdentifierLength)
         {
             // If the identifier length is already close to the limit, we can't prefix it. This is
             // not a problem since there are no builtins or ANGLE's internal variables that would
             // have as long names and could conflict.
-            return name.getString();
+            return name;
         }
-        return kUnhashedNamePrefix + name.getString();
+        return kUnhashedNamePrefix + name;
     }
     if (nameMap)
     {
-        NameMap::const_iterator it = nameMap->find(name.getString().c_str());
+        NameMap::const_iterator it = nameMap->find(name.c_str());
         if (it != nameMap->end())
             return it->second.c_str();
     }
-    TString hashedName = HashName(name.getString(), hashFunction);
+    TString hashedName = HashName(name, hashFunction);
     if (nameMap)
     {
-        (*nameMap)[name.getString().c_str()] = hashedName.c_str();
+        (*nameMap)[name.c_str()] = hashedName.c_str();
     }
     return hashedName;
 }
 
+TString HashName(const TSymbol *symbol, ShHashFunction64 hashFunction, NameMap *nameMap)
+{
+    if (symbol->symbolType() == SymbolType::Empty)
+    {
+        return TString();
+    }
+    if (symbol->symbolType() == SymbolType::AngleInternal ||
+        symbol->symbolType() == SymbolType::BuiltIn)
+    {
+        return symbol->name();
+    }
+    return HashName(symbol->name(), hashFunction, nameMap);
+}
+
 }  // namespace sh
--- a/gfx/angle/src/compiler/translator/HashNames.h
+++ b/gfx/angle/src/compiler/translator/HashNames.h
@@ -12,17 +12,19 @@
 #include "GLSLANG/ShaderLang.h"
 #include "compiler/translator/Common.h"
 
 namespace sh
 {
 
 typedef std::map<TPersistString, TPersistString> NameMap;
 
-class TName;
+class TSymbol;
+
+TString HashName(const TString &name, ShHashFunction64 hashFunction, NameMap *nameMap);
 
 // Hash user-defined name for GLSL output, with special handling for internal names.
 // The nameMap parameter is optional and is used to cache hashed names if set.
-TString HashName(const TName &name, ShHashFunction64 hashFunction, NameMap *nameMap);
+TString HashName(const TSymbol *symbol, ShHashFunction64 hashFunction, NameMap *nameMap);
 
 }  // namespace sh
 
 #endif  // COMPILER_TRANSLATOR_HASHNAMES_H_
new file mode 100644
--- /dev/null
+++ b/gfx/angle/src/compiler/translator/ImageFunctionHLSL.cpp
@@ -0,0 +1,304 @@
+//
+// 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.
+//
+// ImageFunctionHLSL: Class for writing implementations of ESSL image functions into HLSL output.
+//
+
+#include "compiler/translator/ImageFunctionHLSL.h"
+#include "compiler/translator/UtilsHLSL.h"
+
+namespace sh
+{
+
+// static
+void ImageFunctionHLSL::OutputImageFunctionArgumentList(
+    TInfoSinkBase &out,
+    const ImageFunctionHLSL::ImageFunction &imageFunction)
+{
+    if (imageFunction.readonly)
+    {
+        out << TextureString(imageFunction.image, imageFunction.imageInternalFormat) << " tex";
+    }
+    else
+    {
+        out << RWTextureString(imageFunction.image, imageFunction.imageInternalFormat) << " tex";
+    }
+
+    if (imageFunction.method == ImageFunctionHLSL::ImageFunction::Method::LOAD ||
+        imageFunction.method == ImageFunctionHLSL::ImageFunction::Method::STORE)
+    {
+        switch (imageFunction.image)
+        {
+            case EbtImage2D:
+            case EbtIImage2D:
+            case EbtUImage2D:
+                out << ", int2 p";
+                break;
+            case EbtImage3D:
+            case EbtIImage3D:
+            case EbtUImage3D:
+            case EbtImageCube:
+            case EbtIImageCube:
+            case EbtUImageCube:
+            case EbtImage2DArray:
+            case EbtIImage2DArray:
+            case EbtUImage2DArray:
+                out << ", int3 p";
+                break;
+            default:
+                UNREACHABLE();
+        }
+
+        if (imageFunction.method == ImageFunctionHLSL::ImageFunction::Method::STORE)
+        {
+            switch (imageFunction.image)
+            {
+                case EbtImage2D:
+                case EbtImage3D:
+                case EbtImageCube:
+                case EbtImage2DArray:
+                    out << ", float4 data";
+                    break;
+                case EbtIImage2D:
+                case EbtIImage3D:
+                case EbtIImageCube:
+                case EbtIImage2DArray:
+                    out << ", int4 data";
+                    break;
+                case EbtUImage2D:
+                case EbtUImage3D:
+                case EbtUImageCube:
+                case EbtUImage2DArray:
+                    out << ", uint4 data";
+                    break;
+                default:
+                    UNREACHABLE();
+            }
+        }
+    }
+}
+
+// static
+void ImageFunctionHLSL::OutputImageSizeFunctionBody(
+    TInfoSinkBase &out,
+    const ImageFunctionHLSL::ImageFunction &imageFunction,
+    const TString &imageReference)
+{
+    if (IsImage3D(imageFunction.image) || IsImage2DArray(imageFunction.image) ||
+        IsImageCube(imageFunction.image))
+    {
+        // "depth" stores either the number of layers in an array texture or 3D depth
+        out << "    uint width; uint height; uint depth;\n"
+            << "    " << imageReference << ".GetDimensions(width, height, depth);\n";
+    }
+    else if (IsImage2D(imageFunction.image))
+    {
+        out << "    uint width; uint height;\n"
+            << "    " << imageReference << ".GetDimensions(width, height);\n";
+    }
+    else
+        UNREACHABLE();
+
+    if (strcmp(imageFunction.getReturnType(), "int3") == 0)
+    {
+        out << "    return int3(width, height, depth);\n";
+    }
+    else
+    {
+        out << "    return int2(width, height);\n";
+    }
+}
+
+// static
+void ImageFunctionHLSL::OutputImageLoadFunctionBody(
+    TInfoSinkBase &out,
+    const ImageFunctionHLSL::ImageFunction &imageFunction,
+    const TString &imageReference)
+{
+    if (IsImage3D(imageFunction.image) || IsImage2DArray(imageFunction.image) ||
+        IsImageCube(imageFunction.image))
+    {
+        out << "    return " << imageReference << "[uint3(p.x, p.y, p.z)];\n";
+    }
+    else if (IsImage2D(imageFunction.image))
+    {
+        out << "    return " << imageReference << "[uint2(p.x, p.y)];\n";
+    }
+    else
+        UNREACHABLE();
+}
+
+// static
+void ImageFunctionHLSL::OutputImageStoreFunctionBody(
+    TInfoSinkBase &out,
+    const ImageFunctionHLSL::ImageFunction &imageFunction,
+    const TString &imageReference)
+{
+    if (IsImage3D(imageFunction.image) || IsImage2DArray(imageFunction.image) ||
+        IsImage2D(imageFunction.image) || IsImageCube(imageFunction.image))
+    {
+        out << "    " << imageReference << "[p] = data;\n";
+    }
+    else
+        UNREACHABLE();
+}
+
+TString ImageFunctionHLSL::ImageFunction::name() const
+{
+    TString name = "gl_image";
+    if (readonly)
+    {
+        name += TextureTypeSuffix(image, imageInternalFormat);
+    }
+    else
+    {
+        name += RWTextureTypeSuffix(image, imageInternalFormat);
+    }
+
+    switch (method)
+    {
+        case Method::SIZE:
+            name += "Size";
+            break;
+        case Method::LOAD:
+            name += "Load";
+            break;
+        case Method::STORE:
+            name += "Store";
+            break;
+        default:
+            UNREACHABLE();
+    }
+
+    return name;
+}
+
+const char *ImageFunctionHLSL::ImageFunction::getReturnType() const
+{
+    if (method == ImageFunction::Method::SIZE)
+    {
+        switch (image)
+        {
+            case EbtImage2D:
+            case EbtIImage2D:
+            case EbtUImage2D:
+            case EbtImageCube:
+            case EbtIImageCube:
+            case EbtUImageCube:
+                return "int2";
+            case EbtImage3D:
+            case EbtIImage3D:
+            case EbtUImage3D:
+            case EbtImage2DArray:
+            case EbtIImage2DArray:
+            case EbtUImage2DArray:
+                return "int3";
+            default:
+                UNREACHABLE();
+        }
+    }
+    else if (method == ImageFunction::Method::LOAD)
+    {
+        switch (image)
+        {
+            case EbtImage2D:
+            case EbtImage3D:
+            case EbtImageCube:
+            case EbtImage2DArray:
+                return "float4";
+            case EbtIImage2D:
+            case EbtIImage3D:
+            case EbtIImageCube:
+            case EbtIImage2DArray:
+                return "int4";
+            case EbtUImage2D:
+            case EbtUImage3D:
+            case EbtUImageCube:
+            case EbtUImage2DArray:
+                return "uint4";
+            default:
+                UNREACHABLE();
+        }
+    }
+    else if (method == ImageFunction::Method::STORE)
+    {
+        return "void";
+    }
+    else
+    {
+        UNREACHABLE();
+    }
+    return "";
+}
+
+bool ImageFunctionHLSL::ImageFunction::operator<(const ImageFunction &rhs) const
+{
+    return std::tie(image, imageInternalFormat, readonly, method) <
+           std::tie(rhs.image, rhs.imageInternalFormat, rhs.readonly, rhs.method);
+}
+
+TString ImageFunctionHLSL::useImageFunction(const TString &name,
+                                            const TBasicType &type,
+                                            TLayoutImageInternalFormat imageInternalFormat,
+                                            bool readonly)
+{
+    ASSERT(IsImage(type));
+    ImageFunction imageFunction;
+    imageFunction.image               = type;
+    imageFunction.imageInternalFormat = imageInternalFormat;
+    imageFunction.readonly            = readonly;
+
+    if (name == "imageSize")
+    {
+        imageFunction.method = ImageFunction::Method::SIZE;
+    }
+    else if (name == "imageLoad")
+    {
+        imageFunction.method = ImageFunction::Method::LOAD;
+    }
+    else if (name == "imageStore")
+    {
+        imageFunction.method = ImageFunction::Method::STORE;
+    }
+    else
+        UNREACHABLE();
+
+    mUsesImage.insert(imageFunction);
+    return imageFunction.name();
+}
+
+void ImageFunctionHLSL::imageFunctionHeader(TInfoSinkBase &out)
+{
+    for (const ImageFunction &imageFunction : mUsesImage)
+    {
+        // Function header
+        out << imageFunction.getReturnType() << " " << imageFunction.name() << "(";
+
+        OutputImageFunctionArgumentList(out, imageFunction);
+
+        out << ")\n"
+               "{\n";
+
+        TString imageReference("tex");
+
+        if (imageFunction.method == ImageFunction::Method::SIZE)
+        {
+            OutputImageSizeFunctionBody(out, imageFunction, imageReference);
+        }
+        else if (imageFunction.method == ImageFunction::Method::LOAD)
+        {
+            OutputImageLoadFunctionBody(out, imageFunction, imageReference);
+        }
+        else
+        {
+            OutputImageStoreFunctionBody(out, imageFunction, imageReference);
+        }
+
+        out << "}\n"
+               "\n";
+    }
+}
+
+}  // namespace sh
new file mode 100644
--- /dev/null
+++ b/gfx/angle/src/compiler/translator/ImageFunctionHLSL.h
@@ -0,0 +1,76 @@
+//
+// 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.
+//
+// ImageFunctionHLSL: Class for writing implementations of ESSL image functions into HLSL output.
+//
+
+#ifndef COMPILER_TRANSLATOR_IMAGEFUNCTIONHLSL_H_
+#define COMPILER_TRANSLATOR_IMAGEFUNCTIONHLSL_H_
+
+#include <set>
+
+#include "GLSLANG/ShaderLang.h"
+#include "compiler/translator/BaseTypes.h"
+#include "compiler/translator/Common.h"
+#include "compiler/translator/InfoSink.h"
+#include "compiler/translator/Types.h"
+
+namespace sh
+{
+
+class ImageFunctionHLSL final : angle::NonCopyable
+{
+  public:
+    // Returns the name of the image function implementation to caller.
+    // The name that's passed in is the name of the GLSL image function that it should implement.
+    TString useImageFunction(const TString &name,
+                             const TBasicType &type,
+                             TLayoutImageInternalFormat imageInternalFormat,
+                             bool readonly);
+
+    void imageFunctionHeader(TInfoSinkBase &out);
+
+  private:
+    struct ImageFunction
+    {
+        // See ESSL 3.10.4 section 8.12 for reference about what the different methods below do.
+        enum class Method
+        {
+            SIZE,
+            LOAD,
+            STORE
+        };
+
+        TString name() const;
+
+        bool operator<(const ImageFunction &rhs) const;
+
+        const char *getReturnType() const;
+
+        TBasicType image;
+        TLayoutImageInternalFormat imageInternalFormat;
+        bool readonly;
+        Method method;
+    };
+
+    static void OutputImageFunctionArgumentList(
+        TInfoSinkBase &out,
+        const ImageFunctionHLSL::ImageFunction &imageFunction);
+    static void OutputImageSizeFunctionBody(TInfoSinkBase &out,
+                                            const ImageFunctionHLSL::ImageFunction &imageFunction,
+                                            const TString &imageReference);
+    static void OutputImageLoadFunctionBody(TInfoSinkBase &out,
+                                            const ImageFunctionHLSL::ImageFunction &imageFunction,
+                                            const TString &imageReference);
+    static void OutputImageStoreFunctionBody(TInfoSinkBase &out,
+                                             const ImageFunctionHLSL::ImageFunction &imageFunction,
+                                             const TString &imageReference);
+    using ImageFunctionSet = std::set<ImageFunction>;
+    ImageFunctionSet mUsesImage;
+};
+
+}  // namespace sh
+
+#endif  // COMPILER_TRANSLATOR_IMAGEFUNCTIONHLSL_H_
--- a/gfx/angle/src/compiler/translator/Initialize.cpp
+++ b/gfx/angle/src/compiler/translator/Initialize.cpp
@@ -6,43 +6,43 @@
 
 //
 // Create symbols that declare built-in definitions, add built-ins that
 // cannot be expressed in the files, and establish mappings between
 // built-in functions and operators.
 //
 
 #include "compiler/translator/Initialize.h"
-#include "compiler/translator/Cache.h"
+#include "compiler/translator/StaticType.h"
 
 #include "compiler/translator/IntermNode.h"
 #include "angle_gl.h"
 
 namespace sh
 {
 
 void InsertBuiltInFunctions(sh::GLenum type,
                             ShShaderSpec spec,
                             const ShBuiltInResources &resources,
                             TSymbolTable &symbolTable)
 {
-    const TType *voidType = TCache::getType(EbtVoid);
-    const TType *float1   = TCache::getType(EbtFloat);
-    const TType *float2   = TCache::getType(EbtFloat, 2);
-    const TType *float3   = TCache::getType(EbtFloat, 3);
-    const TType *float4   = TCache::getType(EbtFloat, 4);
-    const TType *int1     = TCache::getType(EbtInt);
-    const TType *int2     = TCache::getType(EbtInt, 2);
-    const TType *int3     = TCache::getType(EbtInt, 3);
-    const TType *uint1    = TCache::getType(EbtUInt);
-    const TType *bool1    = TCache::getType(EbtBool);
-    const TType *genType  = TCache::getType(EbtGenType);
-    const TType *genIType = TCache::getType(EbtGenIType);
-    const TType *genUType = TCache::getType(EbtGenUType);
-    const TType *genBType = TCache::getType(EbtGenBType);
+    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.
     //
     symbolTable.insertBuiltInOp(COMMON_BUILTINS, EOpRadians, genType, genType);
     symbolTable.insertBuiltInOp(COMMON_BUILTINS, EOpDegrees, genType, genType);
     symbolTable.insertBuiltInOp(COMMON_BUILTINS, EOpSin, genType, genType);
     symbolTable.insertBuiltInOp(COMMON_BUILTINS, EOpCos, genType, genType);
@@ -105,18 +105,18 @@ void InsertBuiltInFunctions(sh::GLenum t
     symbolTable.insertBuiltInOp(COMMON_BUILTINS, EOpMix, genType, genType, genType, float1);
     symbolTable.insertBuiltInOp(COMMON_BUILTINS, EOpMix, genType, genType, genType, genType);
     symbolTable.insertBuiltInOp(ESSL3_BUILTINS, EOpMix, genType, genType, genType, genBType);
     symbolTable.insertBuiltInOp(COMMON_BUILTINS, EOpStep, genType, genType, genType);
     symbolTable.insertBuiltInOp(COMMON_BUILTINS, EOpStep, genType, float1, genType);
     symbolTable.insertBuiltInOp(COMMON_BUILTINS, EOpSmoothStep, genType, genType, genType, genType);
     symbolTable.insertBuiltInOp(COMMON_BUILTINS, EOpSmoothStep, genType, float1, float1, genType);
 
-    const TType *outGenType = TCache::getType(EbtGenType, EvqOut);
-    const TType *outGenIType = TCache::getType(EbtGenIType, EvqOut);
+    const TType *outGenType  = StaticType::GetQualified<EbtGenType, EvqOut>();
+    const TType *outGenIType = StaticType::GetQualified<EbtGenIType, EvqOut>();
 
     symbolTable.insertBuiltInOp(ESSL3_BUILTINS, EOpModf, genType, genType, outGenType);
 
     symbolTable.insertBuiltInOp(ESSL3_BUILTINS, EOpIsNan, genBType, genType);
     symbolTable.insertBuiltInOp(ESSL3_BUILTINS, EOpIsInf, genBType, genType);
     symbolTable.insertBuiltInOp(ESSL3_BUILTINS, EOpFloatBitsToInt, genIType, genType);
     symbolTable.insertBuiltInOp(ESSL3_BUILTINS, EOpFloatBitsToUint, genUType, genType);
     symbolTable.insertBuiltInOp(ESSL3_BUILTINS, EOpIntBitsToFloat, genType, genIType);
@@ -145,25 +145,25 @@ void InsertBuiltInFunctions(sh::GLenum t
     symbolTable.insertBuiltInOp(COMMON_BUILTINS, EOpDot, float1, genType, genType);
     symbolTable.insertBuiltInOp(COMMON_BUILTINS, EOpCross, float3, float3, float3);
     symbolTable.insertBuiltInOp(COMMON_BUILTINS, EOpNormalize, genType, genType);
     symbolTable.insertBuiltInOp(COMMON_BUILTINS, EOpFaceforward, genType, genType, genType,
                                 genType);
     symbolTable.insertBuiltInOp(COMMON_BUILTINS, EOpReflect, genType, genType, genType);
     symbolTable.insertBuiltInOp(COMMON_BUILTINS, EOpRefract, genType, genType, genType, float1);
 
-    const TType *mat2   = TCache::getType(EbtFloat, 2, 2);
-    const TType *mat3   = TCache::getType(EbtFloat, 3, 3);
-    const TType *mat4   = TCache::getType(EbtFloat, 4, 4);
-    const TType *mat2x3 = TCache::getType(EbtFloat, 2, 3);
-    const TType *mat3x2 = TCache::getType(EbtFloat, 3, 2);
-    const TType *mat2x4 = TCache::getType(EbtFloat, 2, 4);
-    const TType *mat4x2 = TCache::getType(EbtFloat, 4, 2);
-    const TType *mat3x4 = TCache::getType(EbtFloat, 3, 4);
-    const TType *mat4x3 = TCache::getType(EbtFloat, 4, 3);
+    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.
     //
     symbolTable.insertBuiltInOp(COMMON_BUILTINS, EOpMulMatrixComponentWise, mat2, mat2, mat2);
     symbolTable.insertBuiltInOp(COMMON_BUILTINS, EOpMulMatrixComponentWise, mat3, mat3, mat3);
     symbolTable.insertBuiltInOp(COMMON_BUILTINS, EOpMulMatrixComponentWise, mat4, mat4, mat4);
     symbolTable.insertBuiltInOp(ESSL3_BUILTINS, EOpMulMatrixComponentWise, mat2x3, mat2x3, mat2x3);
@@ -196,20 +196,20 @@ void InsertBuiltInFunctions(sh::GLenum t
     symbolTable.insertBuiltInOp(ESSL3_BUILTINS, EOpDeterminant, float1, mat2);
     symbolTable.insertBuiltInOp(ESSL3_BUILTINS, EOpDeterminant, float1, mat3);
     symbolTable.insertBuiltInOp(ESSL3_BUILTINS, EOpDeterminant, float1, mat4);
 
     symbolTable.insertBuiltInOp(ESSL3_BUILTINS, EOpInverse, mat2, mat2);
     symbolTable.insertBuiltInOp(ESSL3_BUILTINS, EOpInverse, mat3, mat3);
     symbolTable.insertBuiltInOp(ESSL3_BUILTINS, EOpInverse, mat4, mat4);
 
-    const TType *vec  = TCache::getType(EbtVec);
-    const TType *ivec = TCache::getType(EbtIVec);
-    const TType *uvec = TCache::getType(EbtUVec);
-    const TType *bvec = TCache::getType(EbtBVec);
+    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.
     //
     symbolTable.insertBuiltInOp(COMMON_BUILTINS, EOpLessThanComponentWise, bvec, vec, vec);
     symbolTable.insertBuiltInOp(COMMON_BUILTINS, EOpLessThanComponentWise, bvec, ivec, ivec);
     symbolTable.insertBuiltInOp(ESSL3_BUILTINS, EOpLessThanComponentWise, bvec, uvec, uvec);
     symbolTable.insertBuiltInOp(COMMON_BUILTINS, EOpLessThanEqualComponentWise, bvec, vec, vec);
@@ -232,17 +232,17 @@ void InsertBuiltInFunctions(sh::GLenum t
     symbolTable.insertBuiltInOp(COMMON_BUILTINS, EOpNotEqualComponentWise, bvec, bvec, bvec);
     symbolTable.insertBuiltInOp(COMMON_BUILTINS, EOpAny, bool1, bvec);
     symbolTable.insertBuiltInOp(COMMON_BUILTINS, EOpAll, bool1, bvec);
     symbolTable.insertBuiltInOp(COMMON_BUILTINS, EOpLogicalNotComponentWise, bvec, bvec);
 
     //
     // Integer functions
     //
-    const TType *outGenUType = TCache::getType(EbtGenUType, EvqOut);
+    const TType *outGenUType = StaticType::GetQualified<EbtGenUType, EvqOut>();
 
     symbolTable.insertBuiltInOp(ESSL3_1_BUILTINS, EOpBitfieldExtract, genIType, genIType, int1,
                                 int1);
     symbolTable.insertBuiltInOp(ESSL3_1_BUILTINS, EOpBitfieldExtract, genUType, genUType, int1,
                                 int1);
     symbolTable.insertBuiltInOp(ESSL3_1_BUILTINS, EOpBitfieldInsert, genIType, genIType, genIType,
                                 int1, int1);
     symbolTable.insertBuiltInOp(ESSL3_1_BUILTINS, EOpBitfieldInsert, genUType, genUType, genUType,
@@ -259,41 +259,41 @@ void InsertBuiltInFunctions(sh::GLenum t
                                 outGenUType);
     symbolTable.insertBuiltInOp(ESSL3_1_BUILTINS, EOpUsubBorrow, genUType, genUType, genUType,
                                 outGenUType);
     symbolTable.insertBuiltInOp(ESSL3_1_BUILTINS, EOpUmulExtended, voidType, genUType, genUType,
                                 outGenUType, outGenUType);
     symbolTable.insertBuiltInOp(ESSL3_1_BUILTINS, EOpImulExtended, voidType, genIType, genIType,
                                 outGenIType, outGenIType);
 
-    const TType *sampler2D   = TCache::getType(EbtSampler2D);
-    const TType *samplerCube = TCache::getType(EbtSamplerCube);
+    const TType *sampler2D   = StaticType::GetBasic<EbtSampler2D>();
+    const TType *samplerCube = StaticType::GetBasic<EbtSamplerCube>();
 
     //
     // Texture Functions for GLSL ES 1.0
     //
     symbolTable.insertBuiltIn(ESSL1_BUILTINS, float4, "texture2D", sampler2D, float2);
     symbolTable.insertBuiltIn(ESSL1_BUILTINS, float4, "texture2DProj", sampler2D, float3);
     symbolTable.insertBuiltIn(ESSL1_BUILTINS, float4, "texture2DProj", sampler2D, float4);
     symbolTable.insertBuiltIn(ESSL1_BUILTINS, float4, "textureCube", samplerCube, float3);
 
     if (resources.OES_EGL_image_external || resources.NV_EGL_stream_consumer_external)
     {
-        const TType *samplerExternalOES = TCache::getType(EbtSamplerExternalOES);
+        const TType *samplerExternalOES = StaticType::GetBasic<EbtSamplerExternalOES>();
 
         symbolTable.insertBuiltIn(ESSL1_BUILTINS, float4, "texture2D", samplerExternalOES, float2);
         symbolTable.insertBuiltIn(ESSL1_BUILTINS, float4, "texture2DProj", samplerExternalOES,
                                   float3);
         symbolTable.insertBuiltIn(ESSL1_BUILTINS, float4, "texture2DProj", samplerExternalOES,
                                   float4);
     }
 
     if (resources.ARB_texture_rectangle)
     {
-        const TType *sampler2DRect = TCache::getType(EbtSampler2DRect);
+        const TType *sampler2DRect = StaticType::GetBasic<EbtSampler2DRect>();
 
         symbolTable.insertBuiltIn(ESSL1_BUILTINS, float4, "texture2DRect", sampler2DRect, float2);
         symbolTable.insertBuiltIn(ESSL1_BUILTINS, float4, "texture2DRectProj", sampler2DRect,
                                   float3);
         symbolTable.insertBuiltIn(ESSL1_BUILTINS, float4, "texture2DRectProj", sampler2DRect,
                                   float4);
     }
 
@@ -352,23 +352,23 @@ void InsertBuiltInFunctions(sh::GLenum t
         symbolTable.insertBuiltIn(ESSL1_BUILTINS, float4, "texture2DProjLod", sampler2D, float3,
                                   float1);
         symbolTable.insertBuiltIn(ESSL1_BUILTINS, float4, "texture2DProjLod", sampler2D, float4,
                                   float1);
         symbolTable.insertBuiltIn(ESSL1_BUILTINS, float4, "textureCubeLod", samplerCube, float3,
                                   float1);
     }
 
-    const TType *gvec4 = TCache::getType(EbtGVec4);
+    const TType *gvec4 = StaticType::GetBasic<EbtGVec4>();
 
-    const TType *gsampler2D      = TCache::getType(EbtGSampler2D);
-    const TType *gsamplerCube    = TCache::getType(EbtGSamplerCube);
-    const TType *gsampler3D      = TCache::getType(EbtGSampler3D);
-    const TType *gsampler2DArray = TCache::getType(EbtGSampler2DArray);
-    const TType *gsampler2DMS    = TCache::getType(EbtGSampler2DMS);
+    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
     //
     symbolTable.insertBuiltIn(ESSL3_BUILTINS, gvec4, "texture", gsampler2D, float2);
     symbolTable.insertBuiltIn(ESSL3_BUILTINS, gvec4, "texture", gsampler3D, float3);
     symbolTable.insertBuiltIn(ESSL3_BUILTINS, gvec4, "texture", gsamplerCube, float3);
     symbolTable.insertBuiltIn(ESSL3_BUILTINS, gvec4, "texture", gsampler2DArray, float3);
@@ -377,37 +377,38 @@ void InsertBuiltInFunctions(sh::GLenum t
     symbolTable.insertBuiltIn(ESSL3_BUILTINS, gvec4, "textureProj", gsampler3D, float4);
     symbolTable.insertBuiltIn(ESSL3_BUILTINS, gvec4, "textureLod", gsampler2D, float2, float1);
     symbolTable.insertBuiltIn(ESSL3_BUILTINS, gvec4, "textureLod", gsampler3D, float3, float1);
     symbolTable.insertBuiltIn(ESSL3_BUILTINS, gvec4, "textureLod", gsamplerCube, float3, float1);
     symbolTable.insertBuiltIn(ESSL3_BUILTINS, gvec4, "textureLod", gsampler2DArray, float3, float1);
 
     if (resources.OES_EGL_image_external_essl3)
     {
-        const TType *samplerExternalOES = TCache::getType(EbtSamplerExternalOES);
+        const TType *samplerExternalOES = StaticType::GetBasic<EbtSamplerExternalOES>();
 
         symbolTable.insertBuiltIn(ESSL3_BUILTINS, float4, "texture", samplerExternalOES, float2);
         symbolTable.insertBuiltIn(ESSL3_BUILTINS, float4, "textureProj", samplerExternalOES,
                                   float3);
         symbolTable.insertBuiltIn(ESSL3_BUILTINS, float4, "textureProj", samplerExternalOES,
                                   float4);
     }
 
     if (resources.EXT_YUV_target)
     {
-        const TType *samplerExternal2DY2YEXT = TCache::getType(EbtSamplerExternal2DY2YEXT);
+        const TType *samplerExternal2DY2YEXT =
+            StaticType::GetBasic<EbtSamplerExternal2DY2YEXT>();
 
         symbolTable.insertBuiltIn(ESSL3_BUILTINS, TExtension::EXT_YUV_target, float4, "texture",
                                   samplerExternal2DY2YEXT, float2);
         symbolTable.insertBuiltIn(ESSL3_BUILTINS, TExtension::EXT_YUV_target, float4, "textureProj",
                                   samplerExternal2DY2YEXT, float3);
         symbolTable.insertBuiltIn(ESSL3_BUILTINS, TExtension::EXT_YUV_target, float4, "textureProj",
                                   samplerExternal2DY2YEXT, float4);
 
-        const TType *yuvCscStandardEXT = TCache::getType(EbtYuvCscStandardEXT);
+        const TType *yuvCscStandardEXT = StaticType::GetBasic<EbtYuvCscStandardEXT>();
 
         symbolTable.insertBuiltIn(ESSL3_BUILTINS, TExtension::EXT_YUV_target, float3, "rgb_2_yuv",
                                   float3, yuvCscStandardEXT);
         symbolTable.insertBuiltIn(ESSL3_BUILTINS, TExtension::EXT_YUV_target, float3, "yuv_2_rgb",
                                   float3, yuvCscStandardEXT);
     }
 
     if (type == GL_FRAGMENT_SHADER)
@@ -418,42 +419,43 @@ void InsertBuiltInFunctions(sh::GLenum t
         symbolTable.insertBuiltIn(ESSL3_BUILTINS, gvec4, "texture", gsampler2DArray, float3,
                                   float1);
         symbolTable.insertBuiltIn(ESSL3_BUILTINS, gvec4, "textureProj", gsampler2D, float3, float1);
         symbolTable.insertBuiltIn(ESSL3_BUILTINS, gvec4, "textureProj", gsampler2D, float4, float1);
         symbolTable.insertBuiltIn(ESSL3_BUILTINS, gvec4, "textureProj", gsampler3D, float4, float1);
 
         if (resources.OES_EGL_image_external_essl3)
         {
-            const TType *samplerExternalOES = TCache::getType(EbtSamplerExternalOES);
+            const TType *samplerExternalOES = StaticType::GetBasic<EbtSamplerExternalOES>();
 
             symbolTable.insertBuiltIn(ESSL3_BUILTINS, float4, "texture", samplerExternalOES, float2,
                                       float1);
             symbolTable.insertBuiltIn(ESSL3_BUILTINS, float4, "textureProj", samplerExternalOES,
                                       float3, float1);
             symbolTable.insertBuiltIn(ESSL3_BUILTINS, float4, "textureProj", samplerExternalOES,
                                       float4, float1);
         }
 
         if (resources.EXT_YUV_target)
         {
-            const TType *samplerExternal2DY2YEXT = TCache::getType(EbtSamplerExternal2DY2YEXT);
+            const TType *samplerExternal2DY2YEXT =
+                StaticType::GetBasic<EbtSamplerExternal2DY2YEXT>();
 
             symbolTable.insertBuiltIn(ESSL3_BUILTINS, TExtension::EXT_YUV_target, float4, "texture",
                                       samplerExternal2DY2YEXT, float2, float1);
             symbolTable.insertBuiltIn(ESSL3_BUILTINS, TExtension::EXT_YUV_target, float4,
                                       "textureProj", samplerExternal2DY2YEXT, float3, float1);
             symbolTable.insertBuiltIn(ESSL3_BUILTINS, TExtension::EXT_YUV_target, float4,
                                       "textureProj", samplerExternal2DY2YEXT, float4, float1);
         }
     }
 
-    const TType *sampler2DShadow      = TCache::getType(EbtSampler2DShadow);
-    const TType *samplerCubeShadow    = TCache::getType(EbtSamplerCubeShadow);
-    const TType *sampler2DArrayShadow = TCache::getType(EbtSampler2DArrayShadow);
+    const TType *sampler2DShadow      = StaticType::GetBasic<EbtSampler2DShadow>();
+    const TType *samplerCubeShadow    = StaticType::GetBasic<EbtSamplerCubeShadow>();
+    const TType *sampler2DArrayShadow = StaticType::GetBasic<EbtSampler2DArrayShadow>();
 
     symbolTable.insertBuiltIn(ESSL3_BUILTINS, float1, "texture", sampler2DShadow, float3);
     symbolTable.insertBuiltIn(ESSL3_BUILTINS, float1, "texture", samplerCubeShadow, float4);
     symbolTable.insertBuiltIn(ESSL3_BUILTINS, float1, "texture", sampler2DArrayShadow, float4);
     symbolTable.insertBuiltIn(ESSL3_BUILTINS, float1, "textureProj", sampler2DShadow, float4);
     symbolTable.insertBuiltIn(ESSL3_BUILTINS, float1, "textureLod", sampler2DShadow, float3,
                               float1);
 
@@ -473,24 +475,25 @@ void InsertBuiltInFunctions(sh::GLenum t
     symbolTable.insertBuiltIn(ESSL3_BUILTINS, int3, "textureSize", gsampler2DArray, int1);
     symbolTable.insertBuiltIn(ESSL3_BUILTINS, int2, "textureSize", sampler2DShadow, int1);
     symbolTable.insertBuiltIn(ESSL3_BUILTINS, int2, "textureSize", samplerCubeShadow, int1);
     symbolTable.insertBuiltIn(ESSL3_BUILTINS, int3, "textureSize", sampler2DArrayShadow, int1);
     symbolTable.insertBuiltIn(ESSL3_BUILTINS, int2, "textureSize", gsampler2DMS);
 
     if (resources.OES_EGL_image_external_essl3)
     {
-        const TType *samplerExternalOES = TCache::getType(EbtSamplerExternalOES);
+        const TType *samplerExternalOES = StaticType::GetBasic<EbtSamplerExternalOES>();
 
         symbolTable.insertBuiltIn(ESSL3_BUILTINS, int2, "textureSize", samplerExternalOES, int1);
     }
 
     if (resources.EXT_YUV_target)
     {
-        const TType *samplerExternal2DY2YEXT = TCache::getType(EbtSamplerExternal2DY2YEXT);
+        const TType *samplerExternal2DY2YEXT =
+            StaticType::GetBasic<EbtSamplerExternal2DY2YEXT>();
 
         symbolTable.insertBuiltIn(ESSL3_BUILTINS, TExtension::EXT_YUV_target, int2, "textureSize",
                                   samplerExternal2DY2YEXT, int1);
     }
 
     if (type == GL_FRAGMENT_SHADER)
     {
         symbolTable.insertBuiltInOp(ESSL3_BUILTINS, EOpDFdx, genType, genType);
@@ -560,25 +563,26 @@ void InsertBuiltInFunctions(sh::GLenum t
                               float4, float1, int2);
 
     symbolTable.insertBuiltIn(ESSL3_BUILTINS, gvec4, "texelFetch", gsampler2D, int2, int1);
     symbolTable.insertBuiltIn(ESSL3_BUILTINS, gvec4, "texelFetch", gsampler3D, int3, int1);
     symbolTable.insertBuiltIn(ESSL3_BUILTINS, gvec4, "texelFetch", gsampler2DArray, int3, int1);
 
     if (resources.OES_EGL_image_external_essl3)
     {
-        const TType *samplerExternalOES = TCache::getType(EbtSamplerExternalOES);
+        const TType *samplerExternalOES = StaticType::GetBasic<EbtSamplerExternalOES>();
 
         symbolTable.insertBuiltIn(ESSL3_BUILTINS, float4, "texelFetch", samplerExternalOES, int2,
                                   int1);
     }
 
     if (resources.EXT_YUV_target)
     {
-        const TType *samplerExternal2DY2YEXT = TCache::getType(EbtSamplerExternal2DY2YEXT);
+        const TType *samplerExternal2DY2YEXT =
+            StaticType::GetBasic<EbtSamplerExternal2DY2YEXT>();
 
         symbolTable.insertBuiltIn(ESSL3_BUILTINS, TExtension::EXT_YUV_target, float4, "texelFetch",
                                   samplerExternal2DY2YEXT, int2, int1);
     }
 
     symbolTable.insertBuiltIn(ESSL3_BUILTINS, gvec4, "texelFetchOffset", gsampler2D, int2, int1,
                               int2);
     symbolTable.insertBuiltIn(ESSL3_BUILTINS, gvec4, "texelFetchOffset", gsampler3D, int3, int1,
@@ -625,25 +629,45 @@ void InsertBuiltInFunctions(sh::GLenum t
                               float2, float2, int2);
     symbolTable.insertBuiltIn(ESSL3_BUILTINS, gvec4, "textureProjGradOffset", gsampler2D, float4,
                               float2, float2, int2);
     symbolTable.insertBuiltIn(ESSL3_BUILTINS, gvec4, "textureProjGradOffset", gsampler3D, float4,
                               float3, float3, int3);
     symbolTable.insertBuiltIn(ESSL3_BUILTINS, float1, "textureProjGradOffset", sampler2DShadow,
                               float4, float2, float2, int2);
 
-    const TType *atomicCounter = TCache::getType(EbtAtomicCounter);
+    const TType *atomicCounter = StaticType::GetBasic<EbtAtomicCounter>();
     symbolTable.insertBuiltIn(ESSL3_1_BUILTINS, uint1, "atomicCounter", atomicCounter);
     symbolTable.insertBuiltIn(ESSL3_1_BUILTINS, uint1, "atomicCounterIncrement", atomicCounter);
     symbolTable.insertBuiltIn(ESSL3_1_BUILTINS, uint1, "atomicCounterDecrement", atomicCounter);
 
-    const TType *gimage2D      = TCache::getType(EbtGImage2D);
-    const TType *gimage3D      = TCache::getType(EbtGImage3D);
-    const TType *gimage2DArray = TCache::getType(EbtGImage2DArray);
-    const TType *gimageCube    = TCache::getType(EbtGImageCube);
+    // Insert all atomic memory functions
+    const TType *int1InOut  = StaticType::GetQualified<EbtInt, EvqInOut>();
+    const TType *uint1InOut = StaticType::GetQualified<EbtUInt, EvqInOut>();
+    symbolTable.insertBuiltIn(ESSL3_1_BUILTINS, uint1, "atomicAdd", uint1InOut, uint1);
+    symbolTable.insertBuiltIn(ESSL3_1_BUILTINS, int1, "atomicAdd", int1InOut, int1);
+    symbolTable.insertBuiltIn(ESSL3_1_BUILTINS, uint1, "atomicMin", uint1InOut, uint1);
+    symbolTable.insertBuiltIn(ESSL3_1_BUILTINS, int1, "atomicMin", int1InOut, int1);
+    symbolTable.insertBuiltIn(ESSL3_1_BUILTINS, uint1, "atomicMax", uint1InOut, uint1);
+    symbolTable.insertBuiltIn(ESSL3_1_BUILTINS, int1, "atomicMax", int1InOut, int1);
+    symbolTable.insertBuiltIn(ESSL3_1_BUILTINS, uint1, "atomicAnd", uint1InOut, uint1);
+    symbolTable.insertBuiltIn(ESSL3_1_BUILTINS, int1, "atomicAnd", int1InOut, int1);
+    symbolTable.insertBuiltIn(ESSL3_1_BUILTINS, uint1, "atomicOr", uint1InOut, uint1);
+    symbolTable.insertBuiltIn(ESSL3_1_BUILTINS, int1, "atomicOr", int1InOut, int1);
+    symbolTable.insertBuiltIn(ESSL3_1_BUILTINS, uint1, "atomicXor", uint1InOut, uint1);
+    symbolTable.insertBuiltIn(ESSL3_1_BUILTINS, int1, "atomicXor", int1InOut, int1);
+    symbolTable.insertBuiltIn(ESSL3_1_BUILTINS, uint1, "atomicExchange", uint1InOut, uint1);
+    symbolTable.insertBuiltIn(ESSL3_1_BUILTINS, int1, "atomicExchange", int1InOut, int1);
+    symbolTable.insertBuiltIn(ESSL3_1_BUILTINS, uint1, "atomicCompSwap", uint1InOut, uint1, uint1);
+    symbolTable.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>();
 
     symbolTable.insertBuiltIn(ESSL3_1_BUILTINS, voidType, "imageStore", gimage2D, int2, gvec4);
     symbolTable.insertBuiltIn(ESSL3_1_BUILTINS, voidType, "imageStore", gimage3D, int3, gvec4);
     symbolTable.insertBuiltIn(ESSL3_1_BUILTINS, voidType, "imageStore", gimage2DArray, int3, gvec4);
     symbolTable.insertBuiltIn(ESSL3_1_BUILTINS, voidType, "imageStore", gimageCube, int3, gvec4);
 
     symbolTable.insertBuiltIn(ESSL3_1_BUILTINS, gvec4, "imageLoad", gimage2D, int2);
     symbolTable.insertBuiltIn(ESSL3_1_BUILTINS, gvec4, "imageLoad", gimage3D, int3);
@@ -704,39 +728,39 @@ void InsertBuiltInFunctions(sh::GLenum t
         symbolTable.insertBuiltInFunctionNoParameters(ESSL3_1_BUILTINS, EOpBarrier, voidType,
                                                       "barrier");
         symbolTable.insertBuiltInFunctionNoParameters(ESSL3_1_BUILTINS, EOpMemoryBarrierShared,
                                                       voidType, "memoryBarrierShared");
         symbolTable.insertBuiltInFunctionNoParameters(ESSL3_1_BUILTINS, EOpGroupMemoryBarrier,
                                                       voidType, "groupMemoryBarrier");
     }
 
-    if (type == GL_GEOMETRY_SHADER_OES)
+    if (type == GL_GEOMETRY_SHADER_EXT)
     {
-        TExtension extension = TExtension::OES_geometry_shader;
+        TExtension extension = TExtension::EXT_geometry_shader;
         symbolTable.insertBuiltInFunctionNoParametersExt(ESSL3_1_BUILTINS, extension, EOpEmitVertex,
                                                          voidType, "EmitVertex");
         symbolTable.insertBuiltInFunctionNoParametersExt(ESSL3_1_BUILTINS, extension,
                                                          EOpEndPrimitive, voidType, "EndPrimitive");
     }
 
     //
     // Depth range in window coordinates
     //
-    TFieldList *fields       = NewPoolTFieldList();
+    TFieldList *fields       = new TFieldList();
     TSourceLoc zeroSourceLoc = {0, 0, 0, 0};
     auto highpFloat1         = new TType(EbtFloat, EbpHigh, EvqGlobal, 1);
     TField *near             = new TField(highpFloat1, NewPoolTString("near"), zeroSourceLoc);
     TField *far              = new TField(highpFloat1, NewPoolTString("far"), zeroSourceLoc);
     TField *diff             = new TField(highpFloat1, NewPoolTString("diff"), zeroSourceLoc);
     fields->push_back(near);
     fields->push_back(far);
     fields->push_back(diff);
-    TStructure *depthRangeStruct =
-        new TStructure(&symbolTable, NewPoolTString("gl_DepthRangeParameters"), fields);
+    TStructure *depthRangeStruct = new TStructure(
+        &symbolTable, NewPoolTString("gl_DepthRangeParameters"), fields, SymbolType::BuiltIn);
     symbolTable.insertStructType(COMMON_BUILTINS, depthRangeStruct);
     TType depthRangeType(depthRangeStruct);
     depthRangeType.setQualifier(EvqUniform);
     symbolTable.insertVariable(COMMON_BUILTINS, "gl_DepthRange", depthRangeType);
 
     //
     // Implementation dependent built-in constants.
     //
@@ -815,19 +839,19 @@ void InsertBuiltInFunctions(sh::GLenum t
                                resources.MaxVertexAtomicCounterBuffers, EbpMedium);
     symbolTable.insertConstInt(ESSL3_1_BUILTINS, "gl_MaxFragmentAtomicCounterBuffers",
                                resources.MaxFragmentAtomicCounterBuffers, EbpMedium);
     symbolTable.insertConstInt(ESSL3_1_BUILTINS, "gl_MaxCombinedAtomicCounterBuffers",
                                resources.MaxCombinedAtomicCounterBuffers, EbpMedium);
     symbolTable.insertConstInt(ESSL3_1_BUILTINS, "gl_MaxAtomicCounterBufferSize",
                                resources.MaxAtomicCounterBufferSize, EbpMedium);
 
-    if (resources.OES_geometry_shader)
+    if (resources.EXT_geometry_shader)
     {
-        TExtension ext = TExtension::OES_geometry_shader;
+        TExtension ext = TExtension::EXT_geometry_shader;
         symbolTable.insertConstIntExt(ESSL3_1_BUILTINS, ext, "gl_MaxGeometryInputComponents",
                                       resources.MaxGeometryInputComponents, EbpMedium);
         symbolTable.insertConstIntExt(ESSL3_1_BUILTINS, ext, "gl_MaxGeometryOutputComponents",
                                       resources.MaxGeometryOutputComponents, EbpMedium);
         symbolTable.insertConstIntExt(ESSL3_1_BUILTINS, ext, "gl_MaxGeometryImageUniforms",
                                       resources.MaxGeometryImageUniforms, EbpMedium);
         symbolTable.insertConstIntExt(ESSL3_1_BUILTINS, ext, "gl_MaxGeometryTextureImageUnits",
                                       resources.MaxGeometryTextureImageUnits, EbpMedium);
@@ -934,19 +958,19 @@ void IdentifyBuiltIns(sh::GLenum type,
             }
             else if (resources.ARM_shader_framebuffer_fetch)
             {
                 symbolTable.insertVariableExt(
                     ESSL1_BUILTINS, TExtension::ARM_shader_framebuffer_fetch, "gl_LastFragColorARM",
                     TType(EbtFloat, EbpMedium, EvqLastFragColor, 4));
             }
 
-            if (resources.OES_geometry_shader)
+            if (resources.EXT_geometry_shader)
             {
-                TExtension extension = TExtension::OES_geometry_shader;
+                TExtension extension = TExtension::EXT_geometry_shader;
                 symbolTable.insertVariableExt(ESSL3_1_BUILTINS, extension, "gl_PrimitiveID",
                                               TType(EbtInt, EbpHigh, EvqPrimitiveID, 1));
                 symbolTable.insertVariableExt(ESSL3_1_BUILTINS, extension, "gl_Layer",
                                               TType(EbtInt, EbpHigh, EvqLayer, 1));
             }
 
             break;
         }
@@ -959,16 +983,18 @@ void IdentifyBuiltIns(sh::GLenum type,
             symbolTable.insertVariable(ESSL3_BUILTINS, "gl_InstanceID",
                                        TType(EbtInt, EbpHigh, EvqInstanceID, 1));
             symbolTable.insertVariable(ESSL3_BUILTINS, "gl_VertexID",
                                        TType(EbtInt, EbpHigh, EvqVertexID, 1));
 
             // For internal use by ANGLE - not exposed to the parser.
             symbolTable.insertVariable(GLSL_BUILTINS, "gl_ViewportIndex",
                                        TType(EbtInt, EbpHigh, EvqViewportIndex));
+            // gl_Layer exists in other shader stages in ESSL, but not in vertex shader so far.
+            symbolTable.insertVariable(GLSL_BUILTINS, "gl_Layer", TType(EbtInt, EbpHigh, EvqLayer));
             break;
         }
         case GL_COMPUTE_SHADER:
         {
             symbolTable.insertVariable(ESSL3_1_BUILTINS, "gl_NumWorkGroups",
                                        TType(EbtUInt, EbpUndefined, EvqNumWorkGroups, 3));
             symbolTable.insertVariable(ESSL3_1_BUILTINS, "gl_WorkGroupSize",
                                        TType(EbtUInt, EbpUndefined, EvqWorkGroupSize, 3));
@@ -978,45 +1004,48 @@ void IdentifyBuiltIns(sh::GLenum type,
                                        TType(EbtUInt, EbpUndefined, EvqLocalInvocationID, 3));
             symbolTable.insertVariable(ESSL3_1_BUILTINS, "gl_GlobalInvocationID",
                                        TType(EbtUInt, EbpUndefined, EvqGlobalInvocationID, 3));
             symbolTable.insertVariable(ESSL3_1_BUILTINS, "gl_LocalInvocationIndex",
                                        TType(EbtUInt, EbpUndefined, EvqLocalInvocationIndex, 1));
             break;
         }
 
-        case GL_GEOMETRY_SHADER_OES:
+        case GL_GEOMETRY_SHADER_EXT:
         {
-            TExtension extension = TExtension::OES_geometry_shader;
+            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_OES_geometry_point_size.
-            const TString *glPerVertexString = NewPoolTString("gl_PerVertex");
-            symbolTable.insertInterfaceBlockNameExt(ESSL3_1_BUILTINS, extension, glPerVertexString);
-
-            TFieldList *fieldList    = NewPoolTFieldList();
+            // TODO(jiawei.shao@intel.com): implement GL_EXT_geometry_point_size.
+            TFieldList *glPerVertexFieldList = new TFieldList();
             TSourceLoc zeroSourceLoc = {0, 0, 0, 0};
             TField *glPositionField  = new TField(new TType(EbtFloat, EbpHigh, EvqPosition, 4),
                                                  NewPoolTString("gl_Position"), zeroSourceLoc);
-            fieldList->push_back(glPositionField);
+            glPerVertexFieldList->push_back(glPositionField);
 
-            TInterfaceBlock *glInBlock = new TInterfaceBlock(
-                glPerVertexString, fieldList, NewPoolTString("gl_in"), TLayoutQualifier::create());
+            const TString *glPerVertexString = NewPoolTString("gl_PerVertex");
+            TInterfaceBlock *glPerVertexInBlock =
+                new TInterfaceBlock(&symbolTable, glPerVertexString, glPerVertexFieldList,
+                                    TLayoutQualifier::Create(), SymbolType::BuiltIn, extension);
+            symbolTable.insertInterfaceBlock(ESSL3_1_BUILTINS, glPerVertexInBlock);
 
             // The array size of gl_in is undefined until we get a valid input primitive
             // declaration.
-            TType glInType(glInBlock, EvqPerVertexIn, TLayoutQualifier::create());
+            TType glInType(glPerVertexInBlock, EvqPerVertexIn, TLayoutQualifier::Create());
             glInType.makeArray(0u);
             symbolTable.insertVariableExt(ESSL3_1_BUILTINS, extension, "gl_in", glInType);
 
+            TInterfaceBlock *glPerVertexOutBlock =
+                new TInterfaceBlock(&symbolTable, glPerVertexString, glPerVertexFieldList,
+                                    TLayoutQualifier::Create(), SymbolType::BuiltIn);
             TType glPositionType(EbtFloat, EbpHigh, EvqPosition, 4);
-            glPositionType.setInterfaceBlock(new TInterfaceBlock(
-                glPerVertexString, fieldList, nullptr, TLayoutQualifier::create()));
+            glPositionType.setInterfaceBlock(glPerVertexOutBlock);
             symbolTable.insertVariableExt(ESSL3_1_BUILTINS, extension, "gl_Position",
                                           glPositionType);
+
             symbolTable.insertVariableExt(ESSL3_1_BUILTINS, extension, "gl_PrimitiveIDIn",
                                           TType(EbtInt, EbpHigh, EvqPrimitiveIDIn, 1));
             symbolTable.insertVariableExt(ESSL3_1_BUILTINS, extension, "gl_InvocationID",
                                           TType(EbtInt, EbpHigh, EvqInvocationID, 1));
             symbolTable.insertVariableExt(ESSL3_1_BUILTINS, extension, "gl_PrimitiveID",
                                           TType(EbtInt, EbpHigh, EvqPrimitiveID, 1));
             symbolTable.insertVariableExt(ESSL3_1_BUILTINS, extension, "gl_Layer",
                                           TType(EbtInt, EbpHigh, EvqLayer, 1));
@@ -1043,17 +1072,19 @@ void InitExtensionBehavior(const ShBuilt
         extBehavior[TExtension::OES_EGL_image_external_essl3] = EBhUndefined;
     }
     if (resources.NV_EGL_stream_consumer_external)
     {
         extBehavior[TExtension::NV_EGL_stream_consumer_external] = EBhUndefined;
     }
     if (resources.ARB_texture_rectangle)
     {
-        extBehavior[TExtension::ARB_texture_rectangle] = EBhUndefined;
+        // Special: ARB_texture_rectangle extension does not follow the standard for #extension
+        // directives - it is enabled by default. An extension directive may still disable it.
+        extBehavior[TExtension::ARB_texture_rectangle] = EBhEnable;
     }
     if (resources.EXT_blend_func_extended)
     {
         extBehavior[TExtension::EXT_blend_func_extended] = EBhUndefined;
     }
     if (resources.EXT_draw_buffers)
     {
         extBehavior[TExtension::EXT_draw_buffers] = EBhUndefined;
@@ -1081,23 +1112,30 @@ void InitExtensionBehavior(const ShBuilt
     if (resources.OVR_multiview)
     {
         extBehavior[TExtension::OVR_multiview] = EBhUndefined;
     }
     if (resources.EXT_YUV_target)
     {
         extBehavior[TExtension::EXT_YUV_target] = EBhUndefined;
     }
-    if (resources.OES_geometry_shader)
+    if (resources.EXT_geometry_shader)
     {
-        extBehavior[TExtension::OES_geometry_shader] = EBhUndefined;
+        extBehavior[TExtension::EXT_geometry_shader] = EBhUndefined;
     }
 }
 
 void ResetExtensionBehavior(TExtensionBehavior &extBehavior)
 {
-    for (auto ext_iter = extBehavior.begin(); ext_iter != extBehavior.end(); ++ext_iter)
+    for (auto &ext : extBehavior)
     {
-        ext_iter->second = EBhUndefined;
+        if (ext.first == TExtension::ARB_texture_rectangle)
+        {
+            ext.second = EBhEnable;
+        }
+        else
+        {
+            ext.second = EBhUndefined;
+        }
     }
 }
 
 }  // namespace sh
--- a/gfx/angle/src/compiler/translator/InitializeDll.cpp
+++ b/gfx/angle/src/compiler/translator/InitializeDll.cpp
@@ -1,15 +1,14 @@
 //
 // 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/Cache.h"
 #include "compiler/translator/InitializeDll.h"
 #include "compiler/translator/InitializeGlobals.h"
 
 #include "common/platform.h"
 
 #include <assert.h>
 
 namespace sh
@@ -18,20 +17,17 @@ namespace sh
 bool InitProcess()
 {
     if (!InitializePoolIndex())
     {
         assert(0 && "InitProcess(): Failed to initalize global pool");
         return false;
     }
 
-    TCache::initialize();
-
     return true;
 }
 
 void DetachProcess()
 {
     FreePoolIndex();
-    TCache::destroy();
 }
 
 }  // namespace sh
--- a/gfx/angle/src/compiler/translator/InitializeVariables.cpp
+++ b/gfx/angle/src/compiler/translator/InitializeVariables.cpp
@@ -15,212 +15,296 @@
 #include "compiler/translator/util.h"
 
 namespace sh
 {
 
 namespace
 {
 
-bool IsNamelessStruct(const TIntermTyped *node)
-{
-    return (node->getBasicType() == EbtStruct && node->getType().getStruct()->name() == "");
-}
+void AddArrayZeroInitSequence(const TIntermTyped *initializedNode,
+                              bool canUseLoopsToInitialize,
+                              bool highPrecisionSupported,
+                              TIntermSequence *initSequenceOut,
+                              TSymbolTable *symbolTable);
 
-void AddArrayZeroInitSequence(const TIntermTyped *initializedNode,
-                              TIntermSequence *initSequenceOut);
+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,
-                               TIntermSequence *initSequenceOut)
+                               bool canUseLoopsToInitialize,
+                               bool highPrecisionSupported,
+                               TIntermSequence *initSequenceOut,
+                               TSymbolTable *symbolTable)
 {
     ASSERT(initializedNode->getBasicType() == EbtStruct);
-    TStructure *structType = initializedNode->getType().getStruct();
+    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));
-        if (element->isArray())
-        {
-            AddArrayZeroInitSequence(element, initSequenceOut);
-        }
-        else if (element->getType().isStructureContainingArrays())
-        {
-            AddStructZeroInitSequence(element, initSequenceOut);
-        }
-        else
-        {
-            // Structs can't be defined inside structs, so the type of a struct field can't be a
-            // nameless struct.
-            ASSERT(!IsNamelessStruct(element));
-            initSequenceOut->push_back(CreateZeroInitAssignment(element));
-        }
+        // 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 AddArrayZeroInitSequence(const TIntermTyped *initializedNode, TIntermSequence *initSequenceOut)
+void AddArrayZeroInitStatementList(const TIntermTyped *initializedNode,
+                                   bool canUseLoopsToInitialize,
+                                   bool highPrecisionSupported,
+                                   TIntermSequence *initSequenceOut,
+                                   TSymbolTable *symbolTable)
 {
-    ASSERT(initializedNode->isArray());
-    // Assign the array elements one by one to keep the AST compatible with ESSL 1.00 which
-    // doesn't have array assignment.
-    // Note that it is important to have the array init in the right order to workaround
-    // http://crbug.com/709317
     for (unsigned int i = 0; i < initializedNode->getOutermostArraySize(); ++i)
     {
         TIntermBinary *element =
             new TIntermBinary(EOpIndexDirect, initializedNode->deepCopy(), CreateIndexNode(i));
-        if (element->isArray())
-        {
-            AddArrayZeroInitSequence(element, initSequenceOut);
-        }
-        else if (element->getType().isStructureContainingArrays())
-        {
-            AddStructZeroInitSequence(element, initSequenceOut);
-        }
-        else
-        {
-            initSequenceOut->push_back(CreateZeroInitAssignment(element));
-        }
+        AddZeroInitSequence(element, canUseLoopsToInitialize, highPrecisionSupported,
+                            initSequenceOut, symbolTable);
+    }
+}
+
+void AddArrayZeroInitForLoop(const TIntermTyped *initializedNode,
+                             bool highPrecisionSupported,
+                             TIntermSequence *initSequenceOut,
+                             TSymbolTable *symbolTable)
+{
+    ASSERT(initializedNode->isArray());
+    TVariable *indexVariable = CreateTempVariable(
+        symbolTable, TType(EbtInt, highPrecisionSupported ? EbpHigh : EbpMedium, EvqTemporary));
+
+    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,
-                    const TSymbolTable &symbolTable,
+                    TSymbolTable *symbolTable,
                     int shaderVersion,
-                    const TExtensionBehavior &extensionBehavior)
+                    const TExtensionBehavior &extensionBehavior,
+                    bool canUseLoopsToInitialize,
+                    bool highPrecisionSupported)
 {
     for (const auto &var : variables)
     {
         TString name = TString(var.name.c_str());
         size_t pos   = name.find_last_of('[');
         if (pos != TString::npos)
         {
             name = name.substr(0, pos);
         }
 
         TIntermTyped *initializedSymbol = nullptr;
         if (var.isBuiltIn())
         {
-            initializedSymbol = ReferenceBuiltInVariable(name, symbolTable, shaderVersion);
+            initializedSymbol = ReferenceBuiltInVariable(name, *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(name, symbolTable);
+            initializedSymbol = ReferenceGlobalVariable(name, *symbolTable);
         }
         ASSERT(initializedSymbol != nullptr);
 
-        TIntermSequence *initCode = CreateInitCode(initializedSymbol);
+        TIntermSequence *initCode = CreateInitCode(initializedSymbol, canUseLoopsToInitialize,
+                                                   highPrecisionSupported, symbolTable);
         mainBody->insert(mainBody->begin(), initCode->begin(), initCode->end());
     }
 }
 
 class InitializeLocalsTraverser : public TIntermTraverser
 {
   public:
-    InitializeLocalsTraverser(int shaderVersion)
-        : TIntermTraverser(true, false, false), mShaderVersion(shaderVersion)
+    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->getSymbol() == "")
+                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.
-                if (arrayConstructorUnavailable || IsNamelessStruct(symbol))
+                // 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));
+                    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)
+TIntermSequence *CreateInitCode(const TIntermTyped *initializedSymbol,
+                                bool canUseLoopsToInitialize,
+                                bool highPrecisionSupported,
+                                TSymbolTable *symbolTable)
 {
     TIntermSequence *initCode = new TIntermSequence();
-    if (initializedSymbol->isArray())
-    {
-        AddArrayZeroInitSequence(initializedSymbol, initCode);
-    }
-    else if (initializedSymbol->getType().isStructureContainingArrays() ||
-             IsNamelessStruct(initializedSymbol))
-    {
-        AddStructZeroInitSequence(initializedSymbol, initCode);
-    }
-    else
-    {
-        initCode->push_back(CreateZeroInitAssignment(initializedSymbol));
-    }
+    AddZeroInitSequence(initializedSymbol, canUseLoopsToInitialize, highPrecisionSupported,
+                        initCode, symbolTable);
     return initCode;
 }
 
-void InitializeUninitializedLocals(TIntermBlock *root, int shaderVersion)
+void InitializeUninitializedLocals(TIntermBlock *root,
+                                   int shaderVersion,
+                                   bool canUseLoopsToInitialize,
+                                   bool highPrecisionSupported,
+                                   TSymbolTable *symbolTable)
 {
-    InitializeLocalsTraverser traverser(shaderVersion);
+    InitializeLocalsTraverser traverser(shaderVersion, symbolTable, canUseLoopsToInitialize,
+                                        highPrecisionSupported);
     root->traverse(&traverser);
     traverser.updateTree();
 }
 
 void InitializeVariables(TIntermBlock *root,
                          const InitVariableList &vars,
-                         const TSymbolTable &symbolTable,
+                         TSymbolTable *symbolTable,
                          int shaderVersion,
-                         const TExtensionBehavior &extensionBehavior)
+                         const TExtensionBehavior &extensionBehavior,
+                         bool canUseLoopsToInitialize,
+                         bool highPrecisionSupported)
 {
     TIntermBlock *body = FindMainBody(root);
-    InsertInitCode(body->getSequence(), vars, symbolTable, shaderVersion, extensionBehavior);
+    InsertInitCode(body->getSequence(), vars, symbolTable, shaderVersion, extensionBehavior,
+                   canUseLoopsToInitialize, highPrecisionSupported);
 }
 
 }  // namespace sh
--- a/gfx/angle/src/compiler/translator/InitializeVariables.h
+++ b/gfx/angle/src/compiler/translator/InitializeVariables.h
@@ -13,32 +13,44 @@
 #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);
+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);
+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,
-                         const TSymbolTable &symbolTable,
+                         TSymbolTable *symbolTable,
                          int shaderVersion,
-                         const TExtensionBehavior &extensionBehavior);
+                         const TExtensionBehavior &extensionBehavior,
+                         bool canUseLoopsToInitialize,
+                         bool highPrecisionSupported);
 
 }  // namespace sh
 
 #endif  // COMPILER_TRANSLATOR_INITIALIZEVARIABLES_H_
--- a/gfx/angle/src/compiler/translator/IntermNode.cpp
+++ b/gfx/angle/src/compiler/translator/IntermNode.cpp
@@ -90,26 +90,22 @@ float VectorDotProduct(const TConstantUn
                        size_t paramArraySize)
 {
     float result = 0.0f;
     for (size_t i = 0; i < paramArraySize; i++)
         result += paramArray1[i].getFConst() * paramArray2[i].getFConst();
     return result;
 }
 
-TIntermTyped *CreateFoldedNode(const TConstantUnion *constArray,
-                               const TIntermTyped *originalNode,
-                               TQualifier qualifier)
+TIntermTyped *CreateFoldedNode(const TConstantUnion *constArray, const TIntermTyped *originalNode)
 {
-    if (constArray == nullptr)
-    {
-        return nullptr;
-    }
+    ASSERT(constArray != nullptr);
+    // Note that we inherit whatever qualifier the folded node had. Nodes may be constant folded
+    // without being qualified as constant.
     TIntermTyped *folded = new TIntermConstantUnion(constArray, originalNode->getType());
-    folded->getTypePointer()->setQualifier(qualifier);
     folded->setLine(originalNode->getLine());
     return folded;
 }
 
 angle::Matrix<float> GetMatrix(const TConstantUnion *paramArray,
                                const unsigned int &rows,
                                const unsigned int &cols)
 {
@@ -137,16 +133,52 @@ void SetUnionArrayFromMatrix(const angle
     // Transpose is used since the input Matrix is in row-major order,
     // whereas the actual result should be in column-major order.
     angle::Matrix<float> result       = m.transpose();
     std::vector<float> resultElements = result.elements();
     for (size_t i = 0; i < resultElements.size(); i++)
         resultArray[i].setFConst(resultElements[i]);
 }
 
+bool CanFoldAggregateBuiltInOp(TOperator op)
+{
+    switch (op)
+    {
+        case EOpAtan:
+        case EOpPow:
+        case EOpMod:
+        case EOpMin:
+        case EOpMax:
+        case EOpClamp:
+        case EOpMix:
+        case EOpStep:
+        case EOpSmoothStep:
+        case EOpLdexp:
+        case EOpMulMatrixComponentWise:
+        case EOpOuterProduct:
+        case EOpEqualComponentWise:
+        case EOpNotEqualComponentWise:
+        case EOpLessThanComponentWise:
+        case EOpLessThanEqualComponentWise:
+        case EOpGreaterThanComponentWise:
+        case EOpGreaterThanEqualComponentWise:
+        case EOpDistance:
+        case EOpDot:
+        case EOpCross:
+        case EOpFaceforward:
+        case EOpReflect:
+        case EOpRefract:
+        case EOpBitfieldExtract:
+        case EOpBitfieldInsert:
+            return true;
+        default:
+            return false;
+    }
+}
+
 }  // namespace anonymous
 
 ////////////////////////////////////////////////////////////////
 //
 // Member functions of the nodes used for building the tree.
 //
 ////////////////////////////////////////////////////////////////
 
@@ -266,71 +298,84 @@ bool TIntermAggregateBase::insertChildNo
     {
         return false;
     }
     auto it = getSequence()->begin() + position;
     getSequence()->insert(it, insertions.begin(), insertions.end());
     return true;
 }
 
+TIntermSymbol::TIntermSymbol(const TVariable *variable)
+    : TIntermTyped(variable->getType()), mVariable(variable)
+{
+}
+
+const TSymbolUniqueId &TIntermSymbol::uniqueId() const
+{
+    return mVariable->uniqueId();
+}
+
+const TString &TIntermSymbol::getName() const
+{
+    return mVariable->name();
+}
+
 TIntermAggregate *TIntermAggregate::CreateFunctionCall(const TFunction &func,
                                                        TIntermSequence *arguments)
 {
-    TIntermAggregate *callNode =
-        new TIntermAggregate(func.getReturnType(), EOpCallFunctionInAST, arguments);
-    callNode->getFunctionSymbolInfo()->setFromFunction(func);
-    return callNode;
+    return new TIntermAggregate(&func, func.getReturnType(), EOpCallFunctionInAST, arguments);
 }
 
-TIntermAggregate *TIntermAggregate::CreateFunctionCall(const TType &type,
-                                                       const TSymbolUniqueId &id,
-                                                       const TName &name,
-                                                       TIntermSequence *arguments)
+TIntermAggregate *TIntermAggregate::CreateRawFunctionCall(const TFunction &func,
+                                                          TIntermSequence *arguments)
 {
-    TIntermAggregate *callNode = new TIntermAggregate(type, EOpCallFunctionInAST, arguments);
-    callNode->getFunctionSymbolInfo()->setId(id);
-    callNode->getFunctionSymbolInfo()->setNameObj(name);
-    return callNode;
+    return new TIntermAggregate(&func, func.getReturnType(), EOpCallInternalRawFunction, arguments);
 }
 
 TIntermAggregate *TIntermAggregate::CreateBuiltInFunctionCall(const TFunction &func,
                                                               TIntermSequence *arguments)
 {
     TIntermAggregate *callNode =
-        new TIntermAggregate(func.getReturnType(), EOpCallBuiltInFunction, arguments);
-    callNode->getFunctionSymbolInfo()->setFromFunction(func);
+        new TIntermAggregate(&func, func.getReturnType(), EOpCallBuiltInFunction, arguments);
     // Note that name needs to be set before texture function type is determined.
     callNode->setBuiltInFunctionPrecision();
     return callNode;
 }
 
 TIntermAggregate *TIntermAggregate::CreateConstructor(const TType &type,
                                                       TIntermSequence *arguments)
 {
-    return new TIntermAggregate(type, EOpConstruct, arguments);
+    return new TIntermAggregate(nullptr, type, EOpConstruct, arguments);
 }
 
 TIntermAggregate *TIntermAggregate::Create(const TType &type,
                                            TOperator op,
                                            TIntermSequence *arguments)
 {
-    TIntermAggregate *node = new TIntermAggregate(type, op, arguments);
     ASSERT(op != EOpCallFunctionInAST);    // Should use CreateFunctionCall
+    ASSERT(op != EOpCallInternalRawFunction);  // Should use CreateRawFunctionCall
     ASSERT(op != EOpCallBuiltInFunction);  // Should use CreateBuiltInFunctionCall
-    ASSERT(!node->isConstructor());        // Should use CreateConstructor
-    return node;
+    ASSERT(op != EOpConstruct);            // Should use CreateConstructor
+    return new TIntermAggregate(nullptr, type, op, arguments);
 }
 
-TIntermAggregate::TIntermAggregate(const TType &type, TOperator op, TIntermSequence *arguments)
-    : TIntermOperator(op), mUseEmulatedFunction(false), mGotPrecisionFromChildren(false)
+TIntermAggregate::TIntermAggregate(const TFunction *func,
+                                   const TType &type,
+                                   TOperator op,
+                                   TIntermSequence *arguments)
+    : TIntermOperator(op),
+      mUseEmulatedFunction(false),
+      mGotPrecisionFromChildren(false),
+      mFunction(func)
 {
     if (arguments != nullptr)
     {
         mArguments.swap(*arguments);
     }
+    ASSERT(mFunction == nullptr || mFunction->symbolType() != SymbolType::Empty);
     setTypePrecisionAndQualifier(type);
 }
 
 void TIntermAggregate::setTypePrecisionAndQualifier(const TType &type)
 {
     setType(type);
     mType.setQualifier(EvqTemporary);
     if (!isFunctionCall())
@@ -435,60 +480,75 @@ void TIntermAggregate::setBuiltInFunctio
         if (typed && IsSampler(typed->getBasicType()))
         {
             precision = typed->getPrecision();
             break;
         }
     }
     // ESSL 3.0 spec section 8: textureSize always gets highp precision.
     // All other functions that take a sampler are assumed to be texture functions.
-    if (mFunctionInfo.getName().find("textureSize") == 0)
+    if (mFunction->name().find("textureSize") == 0)
         mType.setPrecision(EbpHigh);
     else
         mType.setPrecision(precision);
 }
 
 TString TIntermAggregate::getSymbolTableMangledName() const
 {
     ASSERT(!isConstructor());
     switch (mOp)
     {
         case EOpCallInternalRawFunction:
         case EOpCallBuiltInFunction:
         case EOpCallFunctionInAST:
-            return TFunction::GetMangledNameFromCall(mFunctionInfo.getName(), mArguments);
+            return TFunction::GetMangledNameFromCall(mFunction->name(), mArguments);
         default:
             TString opString = GetOperatorString(mOp);
             return TFunction::GetMangledNameFromCall(opString, mArguments);
     }
 }
 
+const char *TIntermAggregate::functionName() const
+{
+    ASSERT(!isConstructor());
+    switch (mOp)
+    {
+        case EOpCallInternalRawFunction:
+        case EOpCallBuiltInFunction:
+        case EOpCallFunctionInAST:
+            return mFunction->name().c_str();
+        default:
+            return GetOperatorString(mOp);
+    }
+}
+
 bool TIntermAggregate::hasSideEffects() const
 {
-    if (isFunctionCall() && mFunctionInfo.isKnownToNotHaveSideEffects())
+    if (isFunctionCall() && mFunction != nullptr && mFunction->isKnownToNotHaveSideEffects())
     {
         for (TIntermNode *arg : mArguments)
         {
             if (arg->getAsTyped()->hasSideEffects())
             {
                 return true;
             }
         }
         return false;
     }
     // Conservatively assume most aggregate operators have side-effects
     return true;
 }
 
 void TIntermBlock::appendStatement(TIntermNode *statement)
 {
-    // Declaration nodes with no children can appear if all the declarators just added constants to
-    // the symbol table instead of generating code. They're no-ops so they aren't added to blocks.
-    if (statement != nullptr && (statement->getAsDeclarationNode() == nullptr ||
-                                 !statement->getAsDeclarationNode()->getSequence()->empty()))
+    // Declaration nodes with no children can appear if it was an empty declaration or if all the
+    // declarators just added constants to the symbol table instead of generating code. We still
+    // need to add the declaration to the AST in that case because it might be relevant to the
+    // validity of switch/case.
+    if (statement != nullptr)
     {
         mStatements.push_back(statement);
     }
 }
 
 void TIntermFunctionPrototype::appendParameter(TIntermSymbol *parameter)
 {
     ASSERT(parameter != nullptr);
@@ -521,16 +581,17 @@ bool TIntermIfElse::replaceChildNode(TIn
     REPLACE_IF_IS(mFalseBlock, TIntermBlock, original, replacement);
     return false;
 }
 
 bool TIntermSwitch::replaceChildNode(TIntermNode *original, TIntermNode *replacement)
 {
     REPLACE_IF_IS(mInit, TIntermTyped, original, replacement);
     REPLACE_IF_IS(mStatementList, TIntermBlock, original, replacement);
+    ASSERT(mStatementList);
     return false;
 }
 
 bool TIntermCase::replaceChildNode(TIntermNode *original, TIntermNode *replacement)
 {
     REPLACE_IF_IS(mCondition, TIntermTyped, original, replacement);
     return false;
 }
@@ -558,82 +619,42 @@ bool TIntermTyped::isConstructorWithOnly
     return true;
 }
 
 TIntermConstantUnion::TIntermConstantUnion(const TIntermConstantUnion &node) : TIntermTyped(node)
 {
     mUnionArrayPointer = node.mUnionArrayPointer;
 }
 
-void TFunctionSymbolInfo::setFromFunction(const TFunction &function)
-{
-    setName(function.getName());
-    setId(TSymbolUniqueId(function));
-}
-
-TFunctionSymbolInfo::TFunctionSymbolInfo(const TSymbolUniqueId &id)
-    : mId(new TSymbolUniqueId(id)), mKnownToNotHaveSideEffects(false)
-{
-}
-
-TFunctionSymbolInfo::TFunctionSymbolInfo(const TFunctionSymbolInfo &info)
-    : mName(info.mName), mId(nullptr), mKnownToNotHaveSideEffects(info.mKnownToNotHaveSideEffects)
-{
-    if (info.mId)
-    {
-        mId = new TSymbolUniqueId(*info.mId);
-    }
-}
-
-TFunctionSymbolInfo &TFunctionSymbolInfo::operator=(const TFunctionSymbolInfo &info)
+TIntermFunctionPrototype::TIntermFunctionPrototype(const TFunction *function)
+    : TIntermTyped(function->getReturnType()), mFunction(function)
 {
-    mName = info.mName;
-    if (info.mId)
-    {
-        mId = new TSymbolUniqueId(*info.mId);
-    }
-    else
-    {
-        mId = nullptr;
-    }
-    return *this;
-}
-
-void TFunctionSymbolInfo::setId(const TSymbolUniqueId &id)
-{
-    mId = new TSymbolUniqueId(id);
-}
-
-const TSymbolUniqueId &TFunctionSymbolInfo::getId() const
-{
-    ASSERT(mId);
-    return *mId;
+    ASSERT(mFunction->symbolType() != SymbolType::Empty);
 }
 
 TIntermAggregate::TIntermAggregate(const TIntermAggregate &node)
     : TIntermOperator(node),
       mUseEmulatedFunction(node.mUseEmulatedFunction),
       mGotPrecisionFromChildren(node.mGotPrecisionFromChildren),
-      mFunctionInfo(node.mFunctionInfo)
+      mFunction(node.mFunction)
 {
     for (TIntermNode *arg : node.mArguments)
     {
         TIntermTyped *typedArg = arg->getAsTyped();
         ASSERT(typedArg != nullptr);
         TIntermTyped *argCopy = typedArg->deepCopy();
         mArguments.push_back(argCopy);
     }
 }
 
 TIntermAggregate *TIntermAggregate::shallowCopy() const
 {
     TIntermSequence *copySeq = new TIntermSequence();
     copySeq->insert(copySeq->begin(), getSequence()->begin(), getSequence()->end());
-    TIntermAggregate *copyNode         = new TIntermAggregate(mType, mOp, copySeq);
-    *copyNode->getFunctionSymbolInfo() = mFunctionInfo;
+    TIntermAggregate *copyNode = new TIntermAggregate(mFunction, mType, mOp, copySeq);
     copyNode->setLine(mLine);
     return copyNode;
 }
 
 TIntermSwizzle::TIntermSwizzle(const TIntermSwizzle &node) : TIntermTyped(node)
 {
     TIntermTyped *operandCopy = node.mOperand->deepCopy();
     ASSERT(operandCopy != nullptr);
@@ -933,41 +954,61 @@ TIntermLoop::TIntermLoop(TLoopType type,
     // the symbol table instead of generating code. They're no-ops so don't add them to the tree.
     if (mInit && mInit->getAsDeclarationNode() &&
         mInit->getAsDeclarationNode()->getSequence()->empty())
     {
         mInit = nullptr;
     }
 }
 
+TIntermIfElse::TIntermIfElse(TIntermTyped *cond, TIntermBlock *trueB, TIntermBlock *falseB)
+    : TIntermNode(), mCondition(cond), mTrueBlock(trueB), mFalseBlock(falseB)
+{
+    // Prune empty false blocks so that there won't be unnecessary operations done on it.
+    if (mFalseBlock && mFalseBlock->getSequence()->empty())
+    {
+        mFalseBlock = nullptr;
+    }
+}
+
+TIntermSwitch::TIntermSwitch(TIntermTyped *init, TIntermBlock *statementList)
+    : TIntermNode(), mInit(init), mStatementList(statementList)
+{
+    ASSERT(mStatementList);
+}
+
+void TIntermSwitch::setStatementList(TIntermBlock *statementList)
+{
+    ASSERT(statementList);
+    mStatementList = statementList;
+}
+
 // static
 TQualifier TIntermTernary::DetermineQualifier(TIntermTyped *cond,
                                               TIntermTyped *trueExpression,
                                               TIntermTyped *falseExpression)
 {
     if (cond->getQualifier() == EvqConst && trueExpression->getQualifier() == EvqConst &&
         falseExpression->getQualifier() == EvqConst)
     {
         return EvqConst;
     }
     return EvqTemporary;
 }
 
-TIntermTyped *TIntermTernary::fold()
+TIntermTyped *TIntermTernary::fold(TDiagnostics * /* diagnostics */)
 {
     if (mCondition->getAsConstantUnion())
     {
         if (mCondition->getAsConstantUnion()->getBConst(0))
         {
-            mTrueExpression->getTypePointer()->setQualifier(mType.getQualifier());
             return mTrueExpression;
         }
         else
         {
-            mFalseExpression->getTypePointer()->setQualifier(mType.getQualifier());
             return mFalseExpression;
         }
     }
     return this;
 }
 
 void TIntermSwizzle::promote()
 {
@@ -1268,61 +1309,60 @@ const TConstantUnion *TIntermConstantUni
     }
     else
     {
         UNREACHABLE();
         return nullptr;
     }
 }
 
-TIntermTyped *TIntermSwizzle::fold()
+TIntermTyped *TIntermSwizzle::fold(TDiagnostics * /* diagnostics */)
 {
     TIntermConstantUnion *operandConstant = mOperand->getAsConstantUnion();
     if (operandConstant == nullptr)
     {
         return this;
     }
 
     TConstantUnion *constArray = new TConstantUnion[mSwizzleOffsets.size()];
     for (size_t i = 0; i < mSwizzleOffsets.size(); ++i)
     {
         constArray[i] = *operandConstant->foldIndexing(mSwizzleOffsets.at(i));
     }
-    return CreateFoldedNode(constArray, this, mType.getQualifier());
+    return CreateFoldedNode(constArray, this);
 }
 
 TIntermTyped *TIntermBinary::fold(TDiagnostics *diagnostics)
 {
     TIntermConstantUnion *leftConstant  = mLeft->getAsConstantUnion();
     TIntermConstantUnion *rightConstant = mRight->getAsConstantUnion();
     switch (mOp)
     {
         case EOpComma:
         {
             if (mLeft->hasSideEffects())
             {
                 return this;
             }
-            mRight->getTypePointer()->setQualifier(mType.getQualifier());
             return mRight;
         }
         case EOpIndexDirect:
         {
             if (leftConstant == nullptr || rightConstant == nullptr)
             {
                 return this;
             }
             int index = rightConstant->getIConst(0);
 
             const TConstantUnion *constArray = leftConstant->foldIndexing(index);
             if (!constArray)
             {
                 return this;
             }
-            return CreateFoldedNode(constArray, this, mType.getQualifier());
+            return CreateFoldedNode(constArray, this);
         }
         case EOpIndexDirectStruct:
         {
             if (leftConstant == nullptr || rightConstant == nullptr)
             {
                 return this;
             }
             const TFieldList &fields = mLeft->getType().getStruct()->fields();
@@ -1330,17 +1370,17 @@ TIntermTyped *TIntermBinary::fold(TDiagn
 
             size_t previousFieldsSize = 0;
             for (size_t i = 0; i < index; ++i)
             {
                 previousFieldsSize += fields[i]->type()->getObjectSize();
             }
 
             const TConstantUnion *constArray = leftConstant->getUnionArrayPointer();
-            return CreateFoldedNode(constArray + previousFieldsSize, this, mType.getQualifier());
+            return CreateFoldedNode(constArray + previousFieldsSize, this);
         }
         case EOpIndexIndirect:
         case EOpIndexDirectInterfaceBlock:
             // Can never be constant folded.
             return this;
         default:
         {
             if (leftConstant == nullptr || rightConstant == nullptr)
@@ -1348,30 +1388,29 @@ TIntermTyped *TIntermBinary::fold(TDiagn
                 return this;
             }
             TConstantUnion *constArray =
                 leftConstant->foldBinary(mOp, rightConstant, diagnostics, mLeft->getLine());
             if (!constArray)
             {
                 return this;
             }
-
-            // Nodes may be constant folded without being qualified as constant.
-            return CreateFoldedNode(constArray, this, mType.getQualifier());
+            return CreateFoldedNode(constArray, this);
         }
     }
 }
 
 TIntermTyped *TIntermUnary::fold(TDiagnostics *diagnostics)
 {
     TConstantUnion *constArray = nullptr;
 
     if (mOp == EOpArrayLength)
     {
-        if (mOperand->hasSideEffects())
+        // The size of runtime-sized arrays may only be determined at runtime.
+        if (mOperand->hasSideEffects() || mOperand->getType().isUnsizedArray())
         {
             return this;
         }
         constArray = new TConstantUnion[1];
         constArray->setIConst(mOperand->getOutermostArraySize());
     }
     else
     {
@@ -1405,39 +1444,47 @@ TIntermTyped *TIntermUnary::fold(TDiagno
                 constArray = operandConstant->foldUnaryComponentWise(mOp, diagnostics);
                 break;
         }
     }
     if (constArray == nullptr)
     {
         return this;
     }
-
-    // Nodes may be constant folded without being qualified as constant.
-    return CreateFoldedNode(constArray, this, mType.getQualifier());
+    return CreateFoldedNode(constArray, this);
 }
 
 TIntermTyped *TIntermAggregate::fold(TDiagnostics *diagnostics)
 {
     // Make sure that all params are constant before actual constant folding.
     for (auto *param : *getSequence())
     {
         if (param->getAsConstantUnion() == nullptr)
         {
             return this;
         }
     }
     TConstantUnion *constArray = nullptr;
     if (isConstructor())
-        constArray = TIntermConstantUnion::FoldAggregateConstructor(this);
-    else
+    {
+        // TODO(oetuaho@nvidia.com): Add support for folding array constructors.
+        if (!isArray())
+        {
+            constArray = TIntermConstantUnion::FoldAggregateConstructor(this);
+        }
+    }
+    else if (CanFoldAggregateBuiltInOp(mOp))
+    {
         constArray = TIntermConstantUnion::FoldAggregateBuiltIn(this, diagnostics);
-
-    // Nodes may be constant folded without being qualified as constant.
-    return CreateFoldedNode(constArray, this, getQualifier());
+    }
+    if (constArray == nullptr)
+    {
+        return this;
+    }
+    return CreateFoldedNode(constArray, this);
 }
 
 //
 // The fold functions see if an operation on a constant can be done in place,
 // without generating run-time code.
 //
 // Returns the constant value to keep using or nullptr.
 //
@@ -2573,52 +2620,16 @@ TConstantUnion *TIntermConstantUnion::Fo
             resultArray[resultIndex].cast(basicType, argumentUnionArray[i]);
             ++resultIndex;
         }
     }
     ASSERT(resultIndex == resultSize);
     return resultArray;
 }
 
-bool TIntermAggregate::CanFoldAggregateBuiltInOp(TOperator op)
-{
-    switch (op)
-    {
-        case EOpAtan:
-        case EOpPow:
-        case EOpMod:
-        case EOpMin:
-        case EOpMax:
-        case EOpClamp:
-        case EOpMix:
-        case EOpStep:
-        case EOpSmoothStep:
-        case EOpLdexp:
-        case EOpMulMatrixComponentWise:
-        case EOpOuterProduct:
-        case EOpEqualComponentWise:
-        case EOpNotEqualComponentWise:
-        case EOpLessThanComponentWise:
-        case EOpLessThanEqualComponentWise:
-        case EOpGreaterThanComponentWise:
-        case EOpGreaterThanEqualComponentWise:
-        case EOpDistance:
-        case EOpDot:
-        case EOpCross:
-        case EOpFaceforward:
-        case EOpReflect:
-        case EOpRefract:
-        case EOpBitfieldExtract:
-        case EOpBitfieldInsert:
-            return true;
-        default:
-            return false;
-    }
-}
-
 // static
 TConstantUnion *TIntermConstantUnion::FoldAggregateBuiltIn(TIntermAggregate *aggregate,
                                                            TDiagnostics *diagnostics)
 {
     TOperator op              = aggregate->getOp();
     TIntermSequence *arguments = aggregate->getSequence();
     unsigned int argsCount     = static_cast<unsigned int>(arguments->size());
     std::vector<const TConstantUnion *> unionArrays(argsCount);
--- a/gfx/angle/src/compiler/translator/IntermNode.h
+++ b/gfx/angle/src/compiler/translator/IntermNode.h
@@ -20,16 +20,17 @@
 
 #include <algorithm>
 #include <queue>
 
 #include "common/angleutils.h"
 #include "compiler/translator/Common.h"
 #include "compiler/translator/ConstantUnion.h"
 #include "compiler/translator/Operator.h"
+#include "compiler/translator/SymbolUniqueId.h"
 #include "compiler/translator/Types.h"
 
 namespace sh
 {
 
 class TDiagnostics;
 
 class TIntermTraverser;
@@ -51,39 +52,18 @@ class TIntermTyped;
 class TIntermSymbol;
 class TIntermLoop;
 class TInfoSink;
 class TInfoSinkBase;
 class TIntermRaw;
 class TIntermBranch;
 
 class TSymbolTable;
-class TSymbolUniqueId;
 class TFunction;
-
-// Encapsulate an identifier string and track whether it is coming from the original shader code
-// (not internal) or from ANGLE (internal). Usually internal names shouldn't be decorated or hashed.
-class TName
-{
-  public:
-    POOL_ALLOCATOR_NEW_DELETE();
-    explicit TName(const TString &name) : mName(name), mIsInternal(false) {}
-    TName() : mName(), mIsInternal(false) {}
-    TName(const TName &) = default;
-    TName &operator=(const TName &) = default;
-
-    const TString &getString() const { return mName; }
-    void setString(const TString &string) { mName = string; }
-    bool isInternal() const { return mIsInternal; }
-    void setInternal(bool isInternal) { mIsInternal = isInternal; }
-
-  private:
-    TString mName;
-    bool mIsInternal;
-};
+class TVariable;
 
 //
 // Base class for the tree nodes
 //
 class TIntermNode : angle::NonCopyable
 {
   public:
     POOL_ALLOCATOR_NEW_DELETE();
@@ -101,16 +81,17 @@ class TIntermNode : angle::NonCopyable
 
     virtual void traverse(TIntermTraverser *) = 0;
     virtual TIntermTyped *getAsTyped() { return 0; }
     virtual TIntermConstantUnion *getAsConstantUnion() { return 0; }
     virtual TIntermFunctionDefinition *getAsFunctionDefinition() { return nullptr; }
     virtual TIntermAggregate *getAsAggregate() { return 0; }
     virtual TIntermBlock *getAsBlock() { return nullptr; }
     virtual TIntermFunctionPrototype *getAsFunctionPrototypeNode() { return nullptr; }
+    virtual TIntermInvariantDeclaration *getAsInvariantDeclarationNode() { return nullptr; }
     virtual TIntermDeclaration *getAsDeclarationNode() { return nullptr; }
     virtual TIntermSwizzle *getAsSwizzleNode() { return nullptr; }
     virtual TIntermBinary *getAsBinaryNode() { return 0; }
     virtual TIntermUnary *getAsUnaryNode() { return 0; }
     virtual TIntermTernary *getAsTernaryNode() { return nullptr; }
     virtual TIntermIfElse *getAsIfElseNode() { return nullptr; }
     virtual TIntermSwitch *getAsSwitchNode() { return 0; }
     virtual TIntermCase *getAsCaseNode() { return 0; }
@@ -143,16 +124,18 @@ class TIntermTyped : public TIntermNode
 {
   public:
     TIntermTyped(const TType &t) : mType(t) {}
 
     virtual TIntermTyped *deepCopy() const = 0;
 
     TIntermTyped *getAsTyped() override { return this; }
 
+    virtual TIntermTyped *fold(TDiagnostics *diagnostics) { return this; }
+
     // True if executing the expression represented by this node affects state, like values of
     // variables. False if the executing the expression only computes its return value without
     // affecting state. May return true conservatively.
     virtual bool hasSideEffects() const = 0;
 
     void setType(const TType &t) { mType = t; }
     void setTypePreservePrecision(const TType &t);
     const TType &getType() const { return mType; }
@@ -210,16 +193,17 @@ class TIntermLoop : public TIntermNode
     bool replaceChildNode(TIntermNode *original, TIntermNode *replacement) override;
 
     TLoopType getType() const { return mType; }
     TIntermNode *getInit() { return mInit; }
     TIntermTyped *getCondition() { return mCond; }
     TIntermTyped *getExpression() { return mExpr; }
     TIntermBlock *getBody() { return mBody; }
 
+    void setInit(TIntermNode *init) { mInit = init; }
     void setCondition(TIntermTyped *condition) { mCond = condition; }
     void setExpression(TIntermTyped *expression) { mExpr = expression; }
     void setBody(TIntermBlock *body) { mBody = body; }
 
   protected:
     TLoopType mType;
     TIntermNode *mInit;   // for-loop initialization
     TIntermTyped *mCond;  // loop exit condition
@@ -242,51 +226,40 @@ class TIntermBranch : public TIntermNode
     TOperator getFlowOp() { return mFlowOp; }
     TIntermTyped *getExpression() { return mExpression; }
 
   protected:
     TOperator mFlowOp;
     TIntermTyped *mExpression;  // non-zero except for "return exp;" statements
 };
 
-//
-// Nodes that correspond to symbols or constants in the source code.
-//
+// Nodes that correspond to variable symbols in the source code. These may be regular variables or
+// interface block instances. In declarations that only declare a struct type but no variables, a
+// TIntermSymbol node with an empty variable is used to store the type.
 class TIntermSymbol : public TIntermTyped
 {
   public:
-    // if symbol is initialized as symbol(sym), the memory comes from the poolallocator of sym.
-    // If sym comes from per process globalpoolallocator, then it causes increased memory usage
-    // per compile it is essential to use "symbol = sym" to assign to symbol
-    TIntermSymbol(int id, const TString &symbol, const TType &type)
-        : TIntermTyped(type), mId(id), mSymbol(symbol)
-    {
-    }
+    TIntermSymbol(const TVariable *variable);
 
     TIntermTyped *deepCopy() const override { return new TIntermSymbol(*this); }
 
     bool hasSideEffects() const override { return false; }
 
-    int getId() const { return mId; }
-    const TString &getSymbol() const { return mSymbol.getString(); }
-    const TName &getName() const { return mSymbol; }
-    TName &getName() { return mSymbol; }
-
-    void setInternal(bool internal) { mSymbol.setInternal(internal); }
+    const TSymbolUniqueId &uniqueId() const;
+    const TString &getName() const;
+    const TVariable &variable() const { return *mVariable; }
 
     void traverse(TIntermTraverser *it) override;
     TIntermSymbol *getAsSymbolNode() override { return this; }
     bool replaceChildNode(TIntermNode *, TIntermNode *) override { return false; }
 
-  protected:
-    const int mId;
-    TName mSymbol;
-
   private:
     TIntermSymbol(const TIntermSymbol &) = default;  // Note: not deleted, just private!
+
+    const TVariable *const mVariable;  // Guaranteed to be non-null
 };
 
 // A Raw node stores raw code, that the translator will insert verbatim
 // into the output stream. Useful for transformation operations that make
 // complex code that might not fit naturally into the GLSL model.
 class TIntermRaw : public TIntermTyped
 {
   public:
@@ -429,17 +402,17 @@ class TIntermSwizzle : public TIntermTyp
     bool hasSideEffects() const override { return mOperand->hasSideEffects(); }
 
     TIntermTyped *getOperand() { return mOperand; }
     void writeOffsetsAsXYZW(TInfoSinkBase *out) const;
 
     bool hasDuplicateOffsets() const;
     bool offsetsMatch(int offset) const;
 
-    TIntermTyped *fold();
+    TIntermTyped *fold(TDiagnostics *diagnostics) override;
 
   protected:
     TIntermTyped *mOperand;
     TVector<int> mSwizzleOffsets;
 
   private:
     void promote();
 
@@ -469,17 +442,17 @@ class TIntermBinary : public TIntermOper
 
     bool hasSideEffects() const override
     {
         return isAssignment() || mLeft->hasSideEffects() || mRight->hasSideEffects();
     }
 
     TIntermTyped *getLeft() const { return mLeft; }
     TIntermTyped *getRight() const { return mRight; }
-    TIntermTyped *fold(TDiagnostics *diagnostics);
+    TIntermTyped *fold(TDiagnostics *diagnostics) override;
 
     void setAddIndexClamp() { mAddIndexClamp = true; }
     bool getAddIndexClamp() { return mAddIndexClamp; }
 
   protected:
     TIntermTyped *mLeft;
     TIntermTyped *mRight;
 
@@ -504,17 +477,17 @@ class TIntermUnary : public TIntermOpera
 
     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);
+    TIntermTyped *fold(TDiagnostics *diagnostics) override;
 
     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
@@ -522,50 +495,16 @@ class TIntermUnary : public TIntermOpera
     bool mUseEmulatedFunction;
 
   private:
     void promote();
 
     TIntermUnary(const TIntermUnary &node);  // note: not deleted, just private!
 };
 
-class TFunctionSymbolInfo
-{
-  public:
-    POOL_ALLOCATOR_NEW_DELETE();
-    TFunctionSymbolInfo(const TSymbolUniqueId &id);
-    TFunctionSymbolInfo() : mId(nullptr), mKnownToNotHaveSideEffects(false) {}
-
-    TFunctionSymbolInfo(const TFunctionSymbolInfo &info);
-    TFunctionSymbolInfo &operator=(const TFunctionSymbolInfo &info);
-
-    void setFromFunction(const TFunction &function);
-
-    void setNameObj(const TName &name) { mName = name; }
-    const TName &getNameObj() const { return mName; }
-
-    const TString &getName() const { return mName.getString(); }
-    void setName(const TString &name) { mName.setString(name); }
-    bool isMain() const { return mName.getString() == "main"; }
-
-    void setKnownToNotHaveSideEffects(bool knownToNotHaveSideEffects)
-    {
-        mKnownToNotHaveSideEffects = knownToNotHaveSideEffects;
-    }
-    bool isKnownToNotHaveSideEffects() const { return mKnownToNotHaveSideEffects; }
-
-    void setId(const TSymbolUniqueId &functionId);
-    const TSymbolUniqueId &getId() const;
-
-  private:
-    TName mName;
-    TSymbolUniqueId *mId;
-    bool mKnownToNotHaveSideEffects;
-};
-
 typedef TVector<TIntermNode *> TIntermSequence;
 typedef TVector<int> TQualifierList;
 
 //
 // This is just to help yacc.
 //
 struct TIntermFunctionCallOrMethod
 {
@@ -594,22 +533,18 @@ class TIntermAggregateBase
 //
 // Nodes that operate on an arbitrary sized set of children.
 //
 class TIntermAggregate : public TIntermOperator, public TIntermAggregateBase
 {
   public:
     static TIntermAggregate *CreateFunctionCall(const TFunction &func, TIntermSequence *arguments);
 
-    // If using this, ensure that there's a consistent function definition with the same symbol id
-    // added to the AST.
-    static TIntermAggregate *CreateFunctionCall(const TType &type,
-                                                const TSymbolUniqueId &id,
-                                                const TName &name,
-                                                TIntermSequence *arguments);
+    static TIntermAggregate *CreateRawFunctionCall(const TFunction &func,
+                                                   TIntermSequence *arguments);
 
     static TIntermAggregate *CreateBuiltInFunctionCall(const TFunction &func,
                                                        TIntermSequence *arguments);
     static TIntermAggregate *CreateConstructor(const TType &type,
                                                TIntermSequence *arguments);
     static TIntermAggregate *Create(const TType &type, TOperator op, TIntermSequence *arguments);
     ~TIntermAggregate() {}
 
@@ -619,46 +554,50 @@ class TIntermAggregate : public TIntermO
     TIntermAggregate *shallowCopy() const;
 
     TIntermAggregate *getAsAggregate() override { return this; }
     void traverse(TIntermTraverser *it) override;
     bool replaceChildNode(TIntermNode *original, TIntermNode *replacement) override;
 
     bool hasSideEffects() const override;
 
-    static bool CanFoldAggregateBuiltInOp(TOperator op);
-    TIntermTyped *fold(TDiagnostics *diagnostics);
+    TIntermTyped *fold(TDiagnostics *diagnostics) override;
 
     TIntermSequence *getSequence() override { return &mArguments; }
     const TIntermSequence *getSequence() const override { return &mArguments; }
 
     TString getSymbolTableMangledName() const;
 
     void setUseEmulatedFunction() { mUseEmulatedFunction = true; }
     bool getUseEmulatedFunction() { return mUseEmulatedFunction; }
 
     // Returns true if changing parameter precision may affect the return value.
     bool gotPrecisionFromChildren() const { return mGotPrecisionFromChildren; }
 
-    TFunctionSymbolInfo *getFunctionSymbolInfo() { return &mFunctionInfo; }
-    const TFunctionSymbolInfo *getFunctionSymbolInfo() const { return &mFunctionInfo; }
+    const TFunction *getFunction() const { return mFunction; }
+
+    // Get the function name to display to the user in an error message.
+    const char *functionName() const;
 
   protected:
     TIntermSequence mArguments;
 
     // If set to true, replace the built-in function call with an emulated one
     // to work around driver bugs. Only for calls mapped to ops other than EOpCall*.
     bool mUseEmulatedFunction;
 
     bool mGotPrecisionFromChildren;
 
-    TFunctionSymbolInfo mFunctionInfo;
+    const TFunction *const mFunction;
 
   private:
-    TIntermAggregate(const TType &type, TOperator op, TIntermSequence *arguments);
+    TIntermAggregate(const TFunction *func,
+                     const TType &type,
+                     TOperator op,
+                     TIntermSequence *arguments);
 
     TIntermAggregate(const TIntermAggregate &node);  // note: not deleted, just private!
 
     void setTypePrecisionAndQualifier(const TType &type);
 
     bool areChildrenConstQualified();
 
     void setPrecisionFromChildren();
@@ -695,22 +634,17 @@ class TIntermBlock : public TIntermNode,
     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
 {
   public:
-    // TODO(oetuaho@nvidia.com): See if TFunctionSymbolInfo could be added to constructor
-    // parameters.
-    TIntermFunctionPrototype(const TType &type, const TSymbolUniqueId &id)
-        : TIntermTyped(type), mFunctionInfo(id)
-    {
-    }
+    TIntermFunctionPrototype(const TFunction *function);
     ~TIntermFunctionPrototype() {}
 
     TIntermFunctionPrototype *getAsFunctionPrototypeNode() override { return this; }
     void traverse(TIntermTraverser *it) override;
     bool replaceChildNode(TIntermNode *original, TIntermNode *replacement) override;
 
     TIntermTyped *deepCopy() const override
     {
@@ -724,23 +658,22 @@ class TIntermFunctionPrototype : public 
     }
 
     // Only intended for initially building the declaration.
     void appendParameter(TIntermSymbol *parameter);
 
     TIntermSequence *getSequence() override { return &mParameters; }
     const TIntermSequence *getSequence() const override { return &mParameters; }
 
-    TFunctionSymbolInfo *getFunctionSymbolInfo() { return &mFunctionInfo; }
-    const TFunctionSymbolInfo *getFunctionSymbolInfo() const { return &mFunctionInfo; }
+    const TFunction *getFunction() const { return mFunction; }
 
   protected:
     TIntermSequence mParameters;
 
-    TFunctionSymbolInfo mFunctionInfo;
+    const TFunction *const mFunction;
 };
 
 // Node for function definitions. The prototype child node stores the function header including
 // parameters, and the body child node stores the function body.
 class TIntermFunctionDefinition : public TIntermNode
 {
   public:
     TIntermFunctionDefinition(TIntermFunctionPrototype *prototype, TIntermBlock *body)
@@ -752,20 +685,17 @@ class TIntermFunctionDefinition : public
 
     TIntermFunctionDefinition *getAsFunctionDefinition() override { return this; }
     void traverse(TIntermTraverser *it) override;
     bool replaceChildNode(TIntermNode *original, TIntermNode *replacement) override;
 
     TIntermFunctionPrototype *getFunctionPrototype() const { return mPrototype; }
     TIntermBlock *getBody() const { return mBody; }
 
-    const TFunctionSymbolInfo *getFunctionSymbolInfo() const
-    {
-        return mPrototype->getFunctionSymbolInfo();
-    }
+    const TFunction *getFunction() const { return mPrototype->getFunction(); }
 
   private:
     TIntermFunctionPrototype *mPrototype;
     TIntermBlock *mBody;
 };
 
 // Struct, interface block or variable declaration. Can contain multiple variable declarators.
 class TIntermDeclaration : public TIntermNode, public TIntermAggregateBase
@@ -790,16 +720,18 @@ class TIntermDeclaration : public TInter
 };
 
 // Specialized declarations for attributing invariance.
 class TIntermInvariantDeclaration : public TIntermNode
 {
   public:
     TIntermInvariantDeclaration(TIntermSymbol *symbol, const TSourceLoc &line);
 
+    virtual TIntermInvariantDeclaration *getAsInvariantDeclarationNode() override { return this; }
+
     TIntermSymbol *getSymbol() { return mSymbol; }
 
     void traverse(TIntermTraverser *it) override;
     bool replaceChildNode(TIntermNode *original, TIntermNode *replacement) override;
 
   private:
     TIntermSymbol *mSymbol;
 };
@@ -821,37 +753,34 @@ class TIntermTernary : public TIntermTyp
     TIntermTyped *deepCopy() const override { return new TIntermTernary(*this); }
 
     bool hasSideEffects() const override
     {
         return mCondition->hasSideEffects() || mTrueExpression->hasSideEffects() ||
                mFalseExpression->hasSideEffects();
     }
 
-    TIntermTyped *fold();
+    TIntermTyped *fold(TDiagnostics *diagnostics) override;
 
   private:
     TIntermTernary(const TIntermTernary &node);  // Note: not deleted, just private!
 
     static TQualifier DetermineQualifier(TIntermTyped *cond,
                                          TIntermTyped *trueExpression,
                                          TIntermTyped *falseExpression);
 
     TIntermTyped *mCondition;
     TIntermTyped *mTrueExpression;
     TIntermTyped *mFalseExpression;
 };
 
 class TIntermIfElse : public TIntermNode
 {
   public:
-    TIntermIfElse(TIntermTyped *cond, TIntermBlock *trueB, TIntermBlock *falseB)
-        : TIntermNode(), mCondition(cond), mTrueBlock(trueB), mFalseBlock(falseB)
-    {
-    }
+    TIntermIfElse(TIntermTyped *cond, TIntermBlock *trueB, TIntermBlock *falseB);
 
     void traverse(TIntermTraverser *it) override;
     bool replaceChildNode(TIntermNode *original, TIntermNode *replacement) override;
 
     TIntermTyped *getCondition() const { return mCondition; }
     TIntermBlock *getTrueBlock() const { return mTrueBlock; }
     TIntermBlock *getFalseBlock() const { return mFalseBlock; }
     TIntermIfElse *getAsIfElseNode() override { return this; }
@@ -863,29 +792,28 @@ class TIntermIfElse : public TIntermNode
 };
 
 //
 // Switch statement.
 //
 class TIntermSwitch : public TIntermNode
 {
   public:
-    TIntermSwitch(TIntermTyped *init, TIntermBlock *statementList)
-        : TIntermNode(), mInit(init), mStatementList(statementList)
-    {
-    }
+    TIntermSwitch(TIntermTyped *init, TIntermBlock *statementList);
 
     void traverse(TIntermTraverser *it) override;
     bool replaceChildNode(TIntermNode *original, TIntermNode *replacement) override;
 
     TIntermSwitch *getAsSwitchNode() override { return this; }
 
     TIntermTyped *getInit() { return mInit; }
     TIntermBlock *getStatementList() { return mStatementList; }
-    void setStatementList(TIntermBlock *statementList) { mStatementList = statementList; }
+
+    // Must be called with a non-null statementList.
+    void setStatementList(TIntermBlock *statementList);
 
   protected:
     TIntermTyped *mInit;
     TIntermBlock *mStatementList;
 };
 
 //
 // Case label.
--- a/gfx/angle/src/compiler/translator/IntermNodePatternMatcher.cpp
+++ b/gfx/angle/src/compiler/translator/IntermNodePatternMatcher.cpp
@@ -6,20 +6,48 @@
 // 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() &&
@@ -100,16 +128,30 @@ bool IntermNodePatternMatcher::match(TIn
 
             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;
@@ -141,17 +183,17 @@ bool IntermNodePatternMatcher::match(TIn
                 return true;
             }
         }
     }
     if ((mMask & kNamelessStructDeclaration) != 0)
     {
         TIntermTyped *declarator = node->getSequence()->front()->getAsTyped();
         if (declarator->getBasicType() == EbtStruct &&
-            declarator->getType().getStruct()->name() == "")
+            declarator->getType().getStruct()->symbolType() == SymbolType::Empty)
         {
             return true;
         }
     }
     return false;
 }
 
 }  // namespace sh
--- a/gfx/angle/src/compiler/translator/IntermNodePatternMatcher.h
+++ b/gfx/angle/src/compiler/translator/IntermNodePatternMatcher.h
@@ -43,17 +43,21 @@ class IntermNodePatternMatcher
 
         // 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
+        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
--- a/gfx/angle/src/compiler/translator/IntermNode_util.cpp
+++ b/gfx/angle/src/compiler/translator/IntermNode_util.cpp
@@ -11,24 +11,16 @@
 #include "compiler/translator/SymbolTable.h"
 
 namespace sh
 {
 
 namespace
 {
 
-TName GetInternalFunctionName(const char *name)
-{
-    TString nameStr(name);
-    TName nameObj(nameStr);
-    nameObj.setInternal(true);
-    return nameObj;
-}
-
 const TFunction *LookUpBuiltInFunction(const TString &name,
                                        const TIntermSequence *arguments,
                                        const TSymbolTable &symbolTable,
                                        int shaderVersion)
 {
     TString mangledName = TFunction::GetMangledNameFromCall(name, *arguments);
     TSymbol *symbol     = symbolTable.findBuiltIn(mangledName, shaderVersion);
     if (symbol)
@@ -36,43 +28,25 @@ const TFunction *LookUpBuiltInFunction(c
         ASSERT(symbol->isFunction());
         return static_cast<const TFunction *>(symbol);
     }
     return nullptr;
 }
 
 }  // anonymous namespace
 
-TIntermFunctionPrototype *CreateInternalFunctionPrototypeNode(const TType &returnType,
-                                                              const char *name,
-                                                              const TSymbolUniqueId &functionId)
+TIntermFunctionPrototype *CreateInternalFunctionPrototypeNode(const TFunction &func)
 {
-    TIntermFunctionPrototype *functionNode = new TIntermFunctionPrototype(returnType, functionId);
-    functionNode->getFunctionSymbolInfo()->setNameObj(GetInternalFunctionName(name));
-    return functionNode;
+    return new TIntermFunctionPrototype(&func);
 }
 
-TIntermFunctionDefinition *CreateInternalFunctionDefinitionNode(const TType &returnType,
-                                                                const char *name,
-                                                                TIntermBlock *functionBody,
-                                                                const TSymbolUniqueId &functionId)
+TIntermFunctionDefinition *CreateInternalFunctionDefinitionNode(const TFunction &func,
+                                                                TIntermBlock *functionBody)
 {
-    TIntermFunctionPrototype *prototypeNode =
-        CreateInternalFunctionPrototypeNode(returnType, name, functionId);
-    return new TIntermFunctionDefinition(prototypeNode, functionBody);
-}
-
-TIntermAggregate *CreateInternalFunctionCallNode(const TType &returnType,
-                                                 const char *name,
-                                                 const TSymbolUniqueId &functionId,
-                                                 TIntermSequence *arguments)
-{
-    TIntermAggregate *functionNode = TIntermAggregate::CreateFunctionCall(
-        returnType, functionId, GetInternalFunctionName(name), arguments);
-    return functionNode;
+    return new TIntermFunctionDefinition(new TIntermFunctionPrototype(&func), functionBody);
 }
 
 TIntermTyped *CreateZeroNode(const TType &type)
 {
     TType constType(type);
     constType.setQualifier(EvqConst);
 
     if (!type.isArray() && type.getBasicType() != EbtStruct)
@@ -135,17 +109,17 @@ TIntermTyped *CreateZeroNode(const TType
         {
             arguments->push_back(CreateZeroNode(elementType));
         }
     }
     else
     {
         ASSERT(type.getBasicType() == EbtStruct);
 
-        TStructure *structure = type.getStruct();
+        const TStructure *structure = type.getStruct();
         for (const auto &field : structure->fields())
         {
             arguments->push_back(CreateZeroNode(*field->type()));
         }
     }
 
     return TIntermAggregate::CreateConstructor(constType, arguments);
 }
@@ -165,16 +139,90 @@ TIntermConstantUnion *CreateBoolNode(boo
     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, nullptr, 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(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, 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;
 
@@ -183,27 +231,27 @@ TIntermBlock *EnsureBlock(TIntermNode *n
     blockNode->appendStatement(node);
     return blockNode;
 }
 
 TIntermSymbol *ReferenceGlobalVariable(const TString &name, const TSymbolTable &symbolTable)
 {
     TVariable *var = reinterpret_cast<TVariable *>(symbolTable.findGlobal(name));
     ASSERT(var);
-    return new TIntermSymbol(var->getUniqueId(), name, var->getType());
+    return new TIntermSymbol(var);
 }
 
 TIntermSymbol *ReferenceBuiltInVariable(const TString &name,
                                         const TSymbolTable &symbolTable,
                                         int shaderVersion)
 {
     const TVariable *var =
         reinterpret_cast<const TVariable *>(symbolTable.findBuiltIn(name, shaderVersion, true));
     ASSERT(var);
-    return new TIntermSymbol(var->getUniqueId(), name, var->getType());
+    return new TIntermSymbol(var);
 }
 
 TIntermTyped *CreateBuiltInFunctionCallNode(const TString &name,
                                             TIntermSequence *arguments,
                                             const TSymbolTable &symbolTable,
                                             int shaderVersion)
 {
     const TFunction *fn = LookUpBuiltInFunction(name, arguments, symbolTable, shaderVersion);
--- a/gfx/angle/src/compiler/translator/IntermNode_util.h
+++ b/gfx/angle/src/compiler/translator/IntermNode_util.h
@@ -9,32 +9,45 @@
 #ifndef COMPILER_TRANSLATOR_INTERMNODEUTIL_H_
 #define COMPILER_TRANSLATOR_INTERMNODEUTIL_H_
 
 #include "compiler/translator/IntermNode.h"
 
 namespace sh
 {
 
-TIntermFunctionPrototype *CreateInternalFunctionPrototypeNode(const TType &returnType,
-                                                              const char *name,
-                                                              const TSymbolUniqueId &functionId);
-TIntermFunctionDefinition *CreateInternalFunctionDefinitionNode(const TType &returnType,
-                                                                const char *name,
-                                                                TIntermBlock *functionBody,
-                                                                const TSymbolUniqueId &functionId);
-TIntermAggregate *CreateInternalFunctionCallNode(const TType &returnType,
-                                                 const char *name,
-                                                 const TSymbolUniqueId &functionId,
-                                                 TIntermSequence *arguments);
+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 TString &name, const TSymbolTable &symbolTable);
 
--- a/gfx/angle/src/compiler/translator/IntermTraverse.cpp
+++ b/gfx/angle/src/compiler/translator/IntermTraverse.cpp
@@ -2,16 +2,17 @@
 // 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);
@@ -107,25 +108,33 @@ TIntermTraverser::TIntermTraverser(bool 
                                    bool postVisit,
                                    TSymbolTable *symbolTable)
     : preVisit(preVisit),
       inVisit(inVisit),
       postVisit(postVisit),
       mDepth(-1),
       mMaxDepth(0),
       mInGlobalScope(true),
-      mSymbolTable(symbolTable),
-      mTemporaryId(nullptr)
+      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;
@@ -162,99 +171,32 @@ void TIntermTraverser::insertStatementsI
 
 void TIntermTraverser::insertStatementInParentBlock(TIntermNode *statement)
 {
     TIntermSequence insertions;
     insertions.push_back(statement);
     insertStatementsInParentBlock(insertions);
 }
 
-TIntermSymbol *TIntermTraverser::createTempSymbol(const TType &type, TQualifier qualifier)
-{
-    // Each traversal uses at most one temporary variable, so the index stays the same within a
-    // single traversal.
-    TInfoSinkBase symbolNameOut;
-    ASSERT(mTemporaryId != nullptr);
-    symbolNameOut << "s" << (mTemporaryId->get());
-    TString symbolName = symbolNameOut.c_str();
-
-    TIntermSymbol *node = new TIntermSymbol(mTemporaryId->get(), symbolName, type);
-    node->setInternal(true);
-
-    ASSERT(qualifier == EvqTemporary || qualifier == EvqConst || qualifier == EvqGlobal);
-    node->getTypePointer()->setQualifier(qualifier);
-    // TODO(oetuaho): Might be useful to sanitize layout qualifier etc. on the type of the created
-    // symbol. This might need to be done in other places as well.
-    return node;
-}
-
-TIntermSymbol *TIntermTraverser::createTempSymbol(const TType &type)
-{
-    return createTempSymbol(type, EvqTemporary);
-}
-
-TIntermDeclaration *TIntermTraverser::createTempDeclaration(const TType &type)
-{
-    TIntermDeclaration *tempDeclaration = new TIntermDeclaration();
-    tempDeclaration->appendDeclarator(createTempSymbol(type));
-    return tempDeclaration;
-}
-
-TIntermDeclaration *TIntermTraverser::createTempInitDeclaration(TIntermTyped *initializer,
-                                                                TQualifier qualifier)
-{
-    ASSERT(initializer != nullptr);
-    TIntermSymbol *tempSymbol           = createTempSymbol(initializer->getType(), qualifier);
-    TIntermDeclaration *tempDeclaration = new TIntermDeclaration();
-    TIntermBinary *tempInit             = new TIntermBinary(EOpInitialize, tempSymbol, initializer);
-    tempDeclaration->appendDeclarator(tempInit);
-    return tempDeclaration;
-}
-
-TIntermDeclaration *TIntermTraverser::createTempInitDeclaration(TIntermTyped *initializer)
-{
-    return createTempInitDeclaration(initializer, EvqTemporary);
-}
-
-TIntermBinary *TIntermTraverser::createTempAssignment(TIntermTyped *rightNode)
-{
-    ASSERT(rightNode != nullptr);
-    TIntermSymbol *tempSymbol = createTempSymbol(rightNode->getType());
-    TIntermBinary *assignment = new TIntermBinary(EOpAssign, tempSymbol, rightNode);
-    return assignment;
-}
-
-void TIntermTraverser::nextTemporaryId()
-{
-    ASSERT(mSymbolTable);
-    if (!mTemporaryId)
-    {
-        mTemporaryId = new TSymbolUniqueId(mSymbolTable);
-        return;
-    }
-    *mTemporaryId = TSymbolUniqueId(mSymbolTable);
-}
-
 void TLValueTrackingTraverser::addToFunctionMap(const TSymbolUniqueId &id,
                                                 TIntermSequence *paramSequence)
 {
     mFunctionMap[id.get()] = paramSequence;
 }
 
 bool TLValueTrackingTraverser::isInFunctionMap(const TIntermAggregate *callNode) const
 {
     ASSERT(callNode->getOp() == EOpCallFunctionInAST);
-    return (mFunctionMap.find(callNode->getFunctionSymbolInfo()->getId().get()) !=
-            mFunctionMap.end());
+    return (mFunctionMap.find(callNode->getFunction()->uniqueId().get()) != mFunctionMap.end());
 }
 
 TIntermSequence *TLValueTrackingTraverser::getFunctionParameters(const TIntermAggregate *callNode)
 {
     ASSERT(isInFunctionMap(callNode));
-    return mFunctionMap[callNode->getFunctionSymbolInfo()->getId().get()];
+    return mFunctionMap[callNode->getFunction()->uniqueId().get()];
 }
 
 void TLValueTrackingTraverser::setInFunctionCallOutParameter(bool inOutParameter)
 {
     mInFunctionCallOutParameter = inOutParameter;
 }
 
 bool TLValueTrackingTraverser::isInFunctionCallOutParameter() const
@@ -728,17 +670,17 @@ TLValueTrackingTraverser::TLValueTrackin
       mShaderVersion(shaderVersion)
 {
     ASSERT(symbolTable);
 }
 
 void TLValueTrackingTraverser::traverseFunctionPrototype(TIntermFunctionPrototype *node)
 {
     TIntermSequence *sequence = node->getSequence();
-    addToFunctionMap(node->getFunctionSymbolInfo()->getId(), sequence);
+    addToFunctionMap(node->getFunction()->uniqueId(), sequence);
 
     TIntermTraverser::traverseFunctionPrototype(node);
 }
 
 void TLValueTrackingTraverser::traverseAggregate(TIntermAggregate *node)
 {
     ScopedNodeInTraversalPath addToPath(this, node);
 
--- a/gfx/angle/src/compiler/translator/IntermTraverse.h
+++ b/gfx/angle/src/compiler/translator/IntermTraverse.h
@@ -19,27 +19,25 @@ 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 do other bookkeeping on the tree to provide
+// 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.
+// 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);
@@ -140,86 +138,52 @@ class TIntermTraverser : angle::NonCopya
     {
         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 on the parent aggregate node
+    // 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;
     };
 
-    // To insert multiple nodes on the parent aggregate node
-    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;
-    };
-
-    // Helper to insert statements in the parent block (sequence) of the node currently being
-    // traversed.
+    // 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 from sequence nodes.
+    // 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);
 
-    // Helper to create a temporary symbol node with the given qualifier.
-    TIntermSymbol *createTempSymbol(const TType &type, TQualifier qualifier);
-    // Helper to create a temporary symbol node.
-    TIntermSymbol *createTempSymbol(const TType &type);
-    // Create a node that declares but doesn't initialize a temporary symbol.
-    TIntermDeclaration *createTempDeclaration(const TType &type);
-    // Create a node that initializes the current temporary symbol with initializer having the given
-    // qualifier.
-    TIntermDeclaration *createTempInitDeclaration(TIntermTyped *initializer, TQualifier qualifier);
-    // Create a node that initializes the current temporary symbol with initializer.
-    TIntermDeclaration *createTempInitDeclaration(TIntermTyped *initializer);
-    // Create a node that assigns rightNode to the current temporary symbol.
-    TIntermBinary *createTempAssignment(TIntermTyped *rightNode);
-    // Increment temporary symbol index.
-    void nextTemporaryId();
-
     enum class OriginalNode
     {
         BECOMES_CHILD,
         IS_DROPPED
     };
 
     void clearReplacementQueue();
 
@@ -239,21 +203,40 @@ class TIntermTraverser : angle::NonCopya
     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;
-    std::vector<NodeInsertMultipleEntry> mInsertions;
 
     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,
@@ -278,25 +261,24 @@ class TIntermTraverser : angle::NonCopya
             : 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;
-
-    TSymbolUniqueId *mTemporaryId;
 };
 
 // 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,
--- a/gfx/angle/src/compiler/translator/OutputGLSL.cpp
+++ b/gfx/angle/src/compiler/translator/OutputGLSL.cpp
@@ -36,34 +36,42 @@ bool TOutputGLSL::writeVariablePrecision
 {
     return false;
 }
 
 void TOutputGLSL::visitSymbol(TIntermSymbol *node)
 {
     TInfoSinkBase &out = objSink();
 
-    const TString &symbol = node->getSymbol();
-    if (symbol == "gl_FragDepthEXT")
+    // All the special cases are built-ins, so if it's not a built-in we can return early.
+    if (node->variable().symbolType() != SymbolType::BuiltIn)
+    {
+        TOutputGLSLBase::visitSymbol(node);
+        return;
+    }
+
+    // Some built-ins get a special translation.
+    const TString &name = node->getName();
+    if (name == "gl_FragDepthEXT")
     {
         out << "gl_FragDepth";
     }
-    else if (symbol == "gl_FragColor" && sh::IsGLSL130OrNewer(getShaderOutput()))
+    else if (name == "gl_FragColor" && sh::IsGLSL130OrNewer(getShaderOutput()))
     {
         out << "webgl_FragColor";
     }
-    else if (symbol == "gl_FragData" && sh::IsGLSL130OrNewer(getShaderOutput()))
+    else if (name == "gl_FragData" && sh::IsGLSL130OrNewer(getShaderOutput()))
     {
         out << "webgl_FragData";
     }
-    else if (symbol == "gl_SecondaryFragColorEXT")
+    else if (name == "gl_SecondaryFragColorEXT")
     {
         out << "angle_SecondaryFragColor";
     }
-    else if (symbol == "gl_SecondaryFragDataEXT")
+    else if (name == "gl_SecondaryFragDataEXT")
     {
         out << "angle_SecondaryFragData";
     }
     else
     {
         TOutputGLSLBase::visitSymbol(node);
     }
 }
--- a/gfx/angle/src/compiler/translator/OutputGLSLBase.cpp
+++ b/gfx/angle/src/compiler/translator/OutputGLSLBase.cpp
@@ -44,54 +44,16 @@ bool isSingleStatement(TIntermNode *node
     }
     else if (node->getAsCaseNode())
     {
         return false;
     }
     return true;
 }
 
-// If SH_SCALARIZE_VEC_AND_MAT_CONSTRUCTOR_ARGS is enabled, layout qualifiers are spilled whenever
-// variables with specified layout qualifiers are copied. Additional checks are needed against the
-// type and storage qualifier of the variable to verify that layout qualifiers have to be outputted.
-// TODO (mradev): Fix layout qualifier spilling in ScalarizeVecAndMatConstructorArgs and remove
-// NeedsToWriteLayoutQualifier.
-bool NeedsToWriteLayoutQualifier(const TType &type)
-{
-    if (type.getBasicType() == EbtInterfaceBlock)
-    {
-        return false;
-    }
-
-    const TLayoutQualifier &layoutQualifier = type.getLayoutQualifier();
-
-    if ((type.getQualifier() == EvqFragmentOut || type.getQualifier() == EvqVertexIn ||
-         IsVarying(type.getQualifier())) &&
-        layoutQualifier.location >= 0)
-    {
-        return true;
-    }
-
-    if (type.getQualifier() == EvqFragmentOut && layoutQualifier.yuv == true)
-    {
-        return true;
-    }
-
-    if (IsOpaqueType(type.getBasicType()) && layoutQualifier.binding != -1)
-    {
-        return true;
-    }
-
-    if (IsImage(type.getBasicType()) && layoutQualifier.imageInternalFormat != EiifUnspecified)
-    {
-        return true;
-    }
-    return false;
-}
-
 class CommaSeparatedListItemPrefixGenerator
 {
   public:
     CommaSeparatedListItemPrefixGenerator() : mFirst(true) {}
   private:
     bool mFirst;
 
     friend TInfoSinkBase &operator<<(TInfoSinkBase &out,
@@ -119,17 +81,17 @@ TOutputGLSLBase::TOutputGLSLBase(TInfoSi
                                  NameMap &nameMap,
                                  TSymbolTable *symbolTable,
                                  sh::GLenum shaderType,
                                  int shaderVersion,
                                  ShShaderOutput output,
                                  ShCompileOptions compileOptions)
     : TIntermTraverser(true, true, true, symbolTable),
       mObjSink(objSink),
-      mDeclaringVariables(false),
+      mDeclaringVariable(false),
       mClampingStrategy(clampingStrategy),
       mHashFunction(hashFunction),
       mNameMap(nameMap),
       mShaderType(shaderType),
       mShaderVersion(shaderVersion),
       mOutput(output),
       mCompileOptions(compileOptions)
 {
@@ -189,18 +151,20 @@ void TOutputGLSLBase::writeBuiltInFuncti
         out << "(";
     }
     else
     {
         writeTriplet(visit, nullptr, ", ", ")");
     }
 }
 
-void TOutputGLSLBase::writeLayoutQualifier(const TType &type)
+void TOutputGLSLBase::writeLayoutQualifier(TIntermTyped *variable)
 {
+    const TType &type = variable->getType();
+
     if (!NeedsToWriteLayoutQualifier(type))
     {
         return;
     }
 
     TInfoSinkBase &out                      = objSink();
     const TLayoutQualifier &layoutQualifier = type.getLayoutQualifier();
     out << "layout(";
@@ -337,23 +301,23 @@ void TOutputGLSLBase::writeVariableType(
     {
         ASSERT(IsImage(type.getBasicType()));
         out << "volatile ";
     }
 
     // Declare the struct if we have not done so already.
     if (type.getBasicType() == EbtStruct && !structDeclared(type.getStruct()))
     {
-        TStructure *structure = type.getStruct();
+        const TStructure *structure = type.getStruct();
 
         declareStruct(structure);
 
-        if (!structure->name().empty())
+        if (structure->symbolType() != SymbolType::Empty)
         {
-            mDeclaredStructs.insert(structure->uniqueId());
+            mDeclaredStructs.insert(structure->uniqueId().get());
         }
     }
     else if (type.getBasicType() == EbtInterfaceBlock)
     {
         TInterfaceBlock *interfaceBlock = type.getInterfaceBlock();
         declareInterfaceBlock(interfaceBlock);
     }
     else
@@ -370,18 +334,18 @@ void TOutputGLSLBase::writeFunctionParam
     for (TIntermSequence::const_iterator iter = args.begin(); iter != args.end(); ++iter)
     {
         const TIntermSymbol *arg = (*iter)->getAsSymbolNode();
         ASSERT(arg != nullptr);
 
         const TType &type = arg->getType();
         writeVariableType(type);
 
-        if (!arg->getName().getString().empty())
-            out << " " << hashName(arg->getName());
+        if (arg->variable().symbolType() != SymbolType::Empty)
+            out << " " << hashName(&arg->variable());
         if (type.isArray())
             out << ArrayString(type);
 
         // Put a comma if this is not the last argument.
         if (iter != args.end() - 1)
             out << ", ";
     }
 }
@@ -389,17 +353,17 @@ void TOutputGLSLBase::writeFunctionParam
 const TConstantUnion *TOutputGLSLBase::writeConstantUnion(const TType &type,
                                                           const TConstantUnion *pConstUnion)
 {
     TInfoSinkBase &out = objSink();
 
     if (type.getBasicType() == EbtStruct)
     {
         const TStructure *structure = type.getStruct();
-        out << hashName(TName(structure->name())) << "(";
+        out << hashName(structure) << "(";
 
         const TFieldList &fields = structure->fields();
         for (size_t i = 0; i < fields.size(); ++i)
         {
             const TType *fieldType = fields[i]->type();
             ASSERT(fieldType != nullptr);
             pConstUnion = writeConstantUnion(*fieldType, pConstUnion);
             if (i != fields.size() - 1)
@@ -464,19 +428,19 @@ void TOutputGLSLBase::writeConstructorTr
     {
         writeTriplet(visit, nullptr, ", ", ")");
     }
 }
 
 void TOutputGLSLBase::visitSymbol(TIntermSymbol *node)
 {
     TInfoSinkBase &out = objSink();
-    out << hashVariableName(node->getName());
+    out << hashName(&node->variable());
 
-    if (mDeclaringVariables && node->getType().isArray())
+    if (mDeclaringVariable && node->getType().isArray())
         out << ArrayString(node->getType());
 }
 
 void TOutputGLSLBase::visitConstantUnion(TIntermConstantUnion *node)
 {
     writeConstantUnion(node->getType(), node->getUnionArrayPointer());
 }
 
@@ -500,17 +464,17 @@ bool TOutputGLSLBase::visitBinary(Visit 
         case EOpComma:
             writeTriplet(visit, "(", ", ", ")");
             break;
         case EOpInitialize:
             if (visit == InVisit)
             {
                 out << " = ";
                 // RHS of initialize is not being declared.
-                mDeclaringVariables = false;
+                mDeclaringVariable = false;
             }
             break;
         case EOpAssign:
             writeTriplet(visit, "(", " = ", ")");
             break;
         case EOpAddAssign:
             writeTriplet(visit, "(", " += ", ")");
             break;
@@ -557,34 +521,52 @@ bool TOutputGLSLBase::visitBinary(Visit 
                 {
                     if (mClampingStrategy == SH_CLAMP_WITH_CLAMP_INTRINSIC)
                         out << "[int(clamp(float(";
                     else
                         out << "[webgl_int_clamp(";
                 }
                 else if (visit == PostVisit)
                 {
-                    int maxSize;
                     TIntermTyped *left = node->getLeft();
                     TType leftType     = left->getType();
 
-                    if (left->isArray())
+                    if (mClampingStrategy == SH_CLAMP_WITH_CLAMP_INTRINSIC)
+                        out << "), 0.0, float(";
+                    else
+                        out << ", 0, ";
+
+                    if (leftType.isUnsizedArray())
                     {
-                        // The shader will fail validation if the array length is not > 0.
-                        maxSize = static_cast<int>(leftType.getOutermostArraySize()) - 1;
+                        // For runtime-sized arrays in ESSL 3.10 we need to call the length method
+                        // to get the length to clamp against. See ESSL 3.10 section 4.1.9. Note
+                        // that a runtime-sized array expression is guaranteed not to have side
+                        // effects, so it's fine to add the expression to the output twice.
+                        ASSERT(mShaderVersion >= 310);
+                        ASSERT(!left->hasSideEffects());
+                        left->traverse(this);
+                        out << ".length() - 1";
                     }
                     else
                     {
-                        maxSize = leftType.getNominalSize() - 1;
+                        int maxSize;
+                        if (leftType.isArray())
+                        {
+                            maxSize = static_cast<int>(leftType.getOutermostArraySize()) - 1;
+                        }
+                        else
+                        {
+                            maxSize = leftType.getNominalSize() - 1;
+                        }
+                        out << maxSize;
                     }
-
                     if (mClampingStrategy == SH_CLAMP_WITH_CLAMP_INTRINSIC)
-                        out << "), 0.0, float(" << maxSize << ")))]";
+                        out << ")))]";
                     else
-                        out << ", 0, " << maxSize << ")]";
+                        out << ")]";
                 }
             }
             else
             {
                 writeTriplet(visit, nullptr, "[", "]");
             }
             break;
         case EOpIndexDirectStruct:
@@ -595,39 +577,31 @@ bool TOutputGLSLBase::visitBinary(Visit 
                 // node, where left child represents "foo" and right child "bar".
                 // The node itself represents ".". The struct field "bar" is
                 // actually stored as an index into TStructure::fields.
                 out << ".";
                 const TStructure *structure       = node->getLeft()->getType().getStruct();
                 const TIntermConstantUnion *index = node->getRight()->getAsConstantUnion();
                 const TField *field               = structure->fields()[index->getIConst(0)];
 
-                TString fieldName = field->name();
-                if (!mSymbolTable->findBuiltIn(structure->name(), mShaderVersion))
-                    fieldName = hashName(TName(fieldName));
-
-                out << fieldName;
+                out << hashFieldName(structure, field->name());
                 visitChildren = false;
             }
             break;
         case EOpIndexDirectInterfaceBlock:
             if (visit == InVisit)
             {
                 out << ".";
                 const TInterfaceBlock *interfaceBlock =
                     node->getLeft()->getType().getInterfaceBlock();
                 const TIntermConstantUnion *index = node->getRight()->getAsConstantUnion();
                 const TField *field               = interfaceBlock->fields()[index->getIConst(0)];
-
-                TString fieldName = field->name();
-                ASSERT(!mSymbolTable->findBuiltIn(interfaceBlock->name(), mShaderVersion) ||
+                ASSERT(interfaceBlock->symbolType() == SymbolType::UserDefined ||
                        interfaceBlock->name() == "gl_PerVertex");
-                fieldName = hashName(TName(fieldName));
-
-                out << fieldName;
+                out << hashFieldName(interfaceBlock, field->name());
                 visitChildren = false;
             }
             break;
 
         case EOpAdd:
             writeTriplet(visit, "(", " + ", ")");
             break;
         case EOpSub:
@@ -843,26 +817,19 @@ bool TOutputGLSLBase::visitIfElse(Visit 
         out << "else\n";
         visitCodeBlock(node->getFalseBlock());
     }
     return false;
 }
 
 bool TOutputGLSLBase::visitSwitch(Visit visit, TIntermSwitch *node)
 {
-    if (node->getStatementList())
-    {
-        writeTriplet(visit, "switch (", ") ", nullptr);
-        // The curly braces get written when visiting the statementList aggregate
-    }
-    else
-    {
-        // No statementList, so it won't output curly braces
-        writeTriplet(visit, "switch (", ") {", "}\n");
-    }
+    ASSERT(node->getStatementList());
+    writeTriplet(visit, "switch (", ") ", nullptr);
+    // The curly braces get written when visiting the statementList aggregate
     return true;
 }
 
 bool TOutputGLSLBase::visitCase(Visit visit, TIntermCase *node)
 {
     if (node->hasCondition())
     {
         writeTriplet(visit, "case (", nullptr, "):\n");
@@ -914,31 +881,31 @@ bool TOutputGLSLBase::visitFunctionDefin
     return false;
 }
 
 bool TOutputGLSLBase::visitInvariantDeclaration(Visit visit, TIntermInvariantDeclaration *node)
 {
     TInfoSinkBase &out = objSink();
     ASSERT(visit == PreVisit);
     const TIntermSymbol *symbol = node->getSymbol();
-    out << "invariant " << hashVariableName(symbol->getName());
+    out << "invariant " << hashName(&symbol->variable());
     return false;
 }
 
 bool TOutputGLSLBase::visitFunctionPrototype(Visit visit, TIntermFunctionPrototype *node)
 {
     TInfoSinkBase &out = objSink();
     ASSERT(visit == PreVisit);
 
     const TType &type = node->getType();
     writeVariableType(type);
     if (type.isArray())
         out << ArrayString(type);
 
-    out << " " << hashFunctionNameIfNeeded(*node->getFunctionSymbolInfo());
+    out << " " << hashFunctionNameIfNeeded(node->getFunction());
 
     out << "(";
     writeFunctionParameters(*(node->getSequence()));
     out << ")";
 
     return false;
 }
 
@@ -951,21 +918,21 @@ bool TOutputGLSLBase::visitAggregate(Vis
         case EOpCallFunctionInAST:
         case EOpCallInternalRawFunction:
         case EOpCallBuiltInFunction:
             // Function call.
             if (visit == PreVisit)
             {
                 if (node->getOp() == EOpCallBuiltInFunction)
                 {
-                    out << translateTextureFunction(node->getFunctionSymbolInfo()->getName());
+                    out << translateTextureFunction(node->getFunction()->name());
                 }
                 else
                 {
-                    out << hashFunctionNameIfNeeded(*node->getFunctionSymbolInfo());
+                    out << hashFunctionNameIfNeeded(node->getFunction());
                 }
                 out << "(";
             }
             else if (visit == InVisit)
                 out << ", ";
             else
                 out << ")";
             break;
@@ -1025,30 +992,33 @@ bool TOutputGLSLBase::visitAggregate(Vis
 bool TOutputGLSLBase::visitDeclaration(Visit visit, TIntermDeclaration *node)
 {
     TInfoSinkBase &out = objSink();
 
     // Variable declaration.
     if (visit == PreVisit)
     {
         const TIntermSequence &sequence = *(node->getSequence());
-        const TIntermTyped *variable    = sequence.front()->getAsTyped();
-        writeLayoutQualifier(variable->getType());
+        TIntermTyped *variable          = sequence.front()->getAsTyped();
+        writeLayoutQualifier(variable);
         writeVariableType(variable->getType());
-        out << " ";
-        mDeclaringVariables = true;
+        if (variable->getAsSymbolNode() == nullptr ||
+            variable->getAsSymbolNode()->variable().symbolType() != SymbolType::Empty)
+        {
+            out << " ";
+        }
+        mDeclaringVariable = true;
     }
     else if (visit == InVisit)
     {
-        out << ", ";
-        mDeclaringVariables = true;
+        UNREACHABLE();
     }
     else
     {
-        mDeclaringVariables = false;
+        mDeclaringVariable = false;
     }
     return true;
 }
 
 bool TOutputGLSLBase::visitLoop(Visit visit, TIntermLoop *node)
 {
     TInfoSinkBase &out = objSink();
 
@@ -1135,79 +1105,78 @@ void TOutputGLSLBase::visitCodeBlock(TIn
     else
     {
         out << "{\n}\n";  // Empty code block.
     }
 }
 
 TString TOutputGLSLBase::getTypeName(const TType &type)
 {
-    if (type.getBasicType() == EbtStruct)
-        return hashName(TName(type.getStruct()->name()));
-    else
-        return type.getBuiltInTypeNameString();
-}
-
-TString TOutputGLSLBase::hashName(const TName &name)
-{
-    return HashName(name, mHashFunction, &mNameMap);
+    return GetTypeName(type, mHashFunction, &mNameMap);
 }
 
-TString TOutputGLSLBase::hashVariableName(const TName &name)
+TString TOutputGLSLBase::hashName(const TSymbol *symbol)
 {
-    if (mSymbolTable->findBuiltIn(name.getString(), mShaderVersion) != nullptr ||
-        name.getString().substr(0, 3) == "gl_")
-    {
-        if (mCompileOptions & SH_TRANSLATE_VIEWID_OVR_TO_UNIFORM &&
-            name.getString() == "gl_ViewID_OVR")
-        {
-            TName uniformName(TString("ViewID_OVR"));
-            uniformName.setInternal(true);
-            return hashName(uniformName);
-        }
-        return name.getString();
-    }
-    return hashName(name);
+    return HashName(symbol, mHashFunction, &mNameMap);
 }
 
-TString TOutputGLSLBase::hashFunctionNameIfNeeded(const TFunctionSymbolInfo &info)
+TString TOutputGLSLBase::hashFieldName(const TSymbol *containingStruct, const TString &fieldName)
 {
-    if (info.isMain())
+    if (containingStruct->symbolType() == SymbolType::UserDefined ||
+        containingStruct->symbolType() == SymbolType::Empty)
     {
-        return info.getName();
+        return HashName(fieldName, mHashFunction, &mNameMap);
     }
     else
     {
-        return hashName(info.getNameObj());
+        return fieldName;
+    }
+}
+
+TString TOutputGLSLBase::hashFunctionNameIfNeeded(const TFunction *func)
+{
+    if (func->isMain())
+    {
+        return func->name();
+    }
+    else
+    {
+        return hashName(func);
     }
 }
 
 bool TOutputGLSLBase::structDeclared(const TStructure *structure) const
 {
     ASSERT(structure);
-    if (structure->name().empty())
+    if (structure->symbolType() == SymbolType::Empty)
     {
         return false;
     }
 
-    return (mDeclaredStructs.count(structure->uniqueId()) > 0);
+    return (mDeclaredStructs.count(structure->uniqueId().get()) > 0);
 }
 
 void TOutputGLSLBase::declareStruct(const TStructure *structure)
 {
     TInfoSinkBase &out = objSink();
 
-    out << "struct " << hashName(TName(structure->name())) << "{\n";
+    out << "struct ";
+
+    if (structure->symbolType() != SymbolType::Empty)
+    {
+        out << hashName(structure) << " ";
+    }
+    out << "{\n";
     const TFieldList &fields = structure->fields();
     for (size_t i = 0; i < fields.size(); ++i)
     {
         const TField *field = fields[i];
         if (writeVariablePrecision(field->type()->getPrecision()))
             out << " ";
-        out << getTypeName(*field->type()) << " " << hashName(TName(field->name()));
+        out << getTypeName(*field->type()) << " " << hashFieldName(structure, field->name());
         if (field->type()->isArray())
             out << ArrayString(*field->type());
         out << ";\n";
     }
     out << "}";
 }
 
 void TOutputGLSLBase::declareInterfaceBlockLayout(const TInterfaceBlock *interfaceBlock)
@@ -1227,61 +1196,67 @@ void TOutputGLSLBase::declareInterfaceBl
         case EbsPacked:
             out << "packed";
             break;
 
         case EbsStd140:
             out << "std140";
             break;
 
+        case EbsStd430:
+            out << "std430";
+            break;
+
         default:
             UNREACHABLE();
             break;
     }
 
-    out << ", ";
-
-    if (interfaceBlock->blockBinding() > 0)
-    {
-        out << "binding = " << interfaceBlock->blockBinding();
-        out << ", ";
-    }
-
-    switch (interfaceBlock->matrixPacking())
+    if (interfaceBlock->blockBinding() >= 0)
     {
-        case EmpUnspecified:
-        case EmpColumnMajor:
-            // Default matrix packing is column major.
-            out << "column_major";
-            break;
-
-        case EmpRowMajor:
-            out << "row_major";
-            break;
-
-        default:
-            UNREACHABLE();
-            break;
+        out << ", ";
+        out << "binding = " << interfaceBlock->blockBinding();
     }
 
     out << ") ";
 }
 
 void TOutputGLSLBase::declareInterfaceBlock(const TInterfaceBlock *interfaceBlock)
 {
     TInfoSinkBase &out = objSink();
 
-    out << hashName(TName(interfaceBlock->name())) << "{\n";
+    out << hashName(interfaceBlock) << "{\n";
     const TFieldList &fields = interfaceBlock->fields();
-    for (size_t i = 0; i < fields.size(); ++i)
+    for (const TField *field : fields)
     {
-        const TField *field = fields[i];
+        if (field->type()->isMatrix() || field->type()->isStructureContainingMatrices())
+        {
+            out << "layout(";
+            switch (field->type()->getLayoutQualifier().matrixPacking)
+            {
+                case EmpUnspecified:
+                case EmpColumnMajor:
+                    // Default matrix packing is column major.
+                    out << "column_major";
+                    break;
+
+                case EmpRowMajor:
+                    out << "row_major";
+                    break;
+
+                default:
+                    UNREACHABLE();
+                    break;
+            }
+            out << ") ";
+        }
+
         if (writeVariablePrecision(field->type()->getPrecision()))
             out << " ";
-        out << getTypeName(*field->type()) << " " << hashName(TName(field->name()));
+        out << getTypeName(*field->type()) << " " << hashFieldName(interfaceBlock, field->name());
         if (field->type()->isArray())
             out << ArrayString(*field->type());
         out << ";\n";
     }
     out << "}";
 }
 
 void WriteGeometryShaderLayoutQualifiers(TInfoSinkBase &out,
@@ -1327,9 +1302,47 @@ void WriteGeometryShaderLayoutQualifiers
                 out << ", ";
             }
             out << "max_vertices = " << maxVertices;
         }
         out << ") out;\n";
     }
 }
 
+// If SH_SCALARIZE_VEC_AND_MAT_CONSTRUCTOR_ARGS is enabled, layout qualifiers are spilled whenever
+// variables with specified layout qualifiers are copied. Additional checks are needed against the
+// type and storage qualifier of the variable to verify that layout qualifiers have to be outputted.
+// TODO (mradev): Fix layout qualifier spilling in ScalarizeVecAndMatConstructorArgs and remove
+// NeedsToWriteLayoutQualifier.
+bool NeedsToWriteLayoutQualifier(const TType &type)
+{
+    if (type.getBasicType() == EbtInterfaceBlock)
+    {
+        return false;
+    }
+
+    const TLayoutQualifier &layoutQualifier = type.getLayoutQualifier();
+
+    if ((type.getQualifier() == EvqFragmentOut || type.getQualifier() == EvqVertexIn ||
+         IsVarying(type.getQualifier())) &&
+        layoutQualifier.location >= 0)
+    {
+        return true;
+    }
+
+    if (type.getQualifier() == EvqFragmentOut && layoutQualifier.yuv == true)
+    {
+        return true;
+    }
+
+    if (IsOpaqueType(type.getBasicType()) && layoutQualifier.binding != -1)
+    {
+        return true;
+    }
+
+    if (IsImage(type.getBasicType()) && layoutQualifier.imageInternalFormat != EiifUnspecified)
+    {
+        return true;
+    }
+    return false;
+}
+
 }  // namespace sh
--- a/gfx/angle/src/compiler/translator/OutputGLSLBase.h
+++ b/gfx/angle/src/compiler/translator/OutputGLSLBase.h
@@ -27,25 +27,25 @@ class TOutputGLSLBase : public TIntermTr
                     sh::GLenum shaderType,
                     int shaderVersion,
                     ShShaderOutput output,
                     ShCompileOptions compileOptions);
 
     ShShaderOutput getShaderOutput() const { return mOutput; }
 
     // Return the original name if hash function pointer is NULL;
-    // otherwise return the hashed name. Has special handling for internal names, which are not
-    // hashed.
-    TString hashName(const TName &name);
+    // otherwise return the hashed name. Has special handling for internal names and built-ins,
+    // which are not hashed.
+    TString hashName(const TSymbol *symbol);
 
   protected:
     TInfoSinkBase &objSink() { return mObjSink; }
     void writeFloat(TInfoSinkBase &out, float f);
     void writeTriplet(Visit visit, const char *preStr, const char *inStr, const char *postStr);
-    virtual void writeLayoutQualifier(const TType &type);
+    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);
     const TConstantUnion *writeConstantUnion(const TType &type, const TConstantUnion *pConstUnion);
     void writeConstructorTriplet(Visit visit, const TType &type);
     TString getTypeName(const TType &type);
 
@@ -64,36 +64,35 @@ class TOutputGLSLBase : public TIntermTr
     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;
 
     void visitCodeBlock(TIntermBlock *node);
 
-    // Same as hashName(), but without hashing built-in variables.
-    TString hashVariableName(const TName &name);
-    // Same as hashName(), but without hashing internal functions or "main".
-    TString hashFunctionNameIfNeeded(const TFunctionSymbolInfo &info);
+    TString hashFieldName(const TSymbol *containingStruct, const TString &fieldName);
+    // Same as hashName(), but without hashing "main".
+    TString hashFunctionNameIfNeeded(const TFunction *func);
     // Used to translate function names for differences between ESSL and GLSL
     virtual TString translateTextureFunction(const TString &name) { return name; }
 
   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);
 
     TInfoSinkBase &mObjSink;
-    bool mDeclaringVariables;
+    bool mDeclaringVariable;
 
     // This set contains all the ids of the structs from every scope.
     std::set<int> mDeclaredStructs;
 
     ShArrayIndexClampingStrategy mClampingStrategy;
 
     // name hashing.
     ShHashFunction64 mHashFunction;
@@ -110,11 +109,13 @@ class TOutputGLSLBase : public TIntermTr
 };
 
 void WriteGeometryShaderLayoutQualifiers(TInfoSinkBase &out,
                                          sh::TLayoutPrimitiveType inputPrimitive,
                                          int invocations,
                                          sh::TLayoutPrimitiveType outputPrimitive,
                                          int maxVertices);
 
+bool NeedsToWriteLayoutQualifier(const TType &type);
+
 }  // namespace sh
 
 #endif  // COMPILER_TRANSLATOR_OUTPUTGLSLBASE_H_
--- a/gfx/angle/src/compiler/translator/OutputHLSL.cpp
+++ b/gfx/angle/src/compiler/translator/OutputHLSL.cpp
@@ -10,21 +10,21 @@
 #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/FlagStd140Structs.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/SearchSymbol.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/util.h"
 
@@ -33,26 +33,66 @@ namespace sh
 
 namespace
 {
 
 TString ArrayHelperFunctionName(const char *prefix, const TType &type)
 {
     TStringStream fnName;
     fnName << prefix << "_";
-    for (unsigned int arraySize : type.getArraySizes())
+    if (type.isArray())
     {
-        fnName << arraySize << "_";
+        for (unsigned int arraySize : *type.getArraySizes())
+        {
+            fnName << arraySize << "_";
+        }
     }
     fnName << TypeString(type);
     return fnName.str();
 }
 
+bool IsDeclarationWrittenOut(TIntermDeclaration *node)
+{
+    TIntermSequence *sequence = node->getSequence();
+    TIntermTyped *variable    = (*sequence)[0]->getAsTyped();
+    ASSERT(sequence->size() == 1);
+    ASSERT(variable);
+    return (variable->getQualifier() == EvqTemporary || variable->getQualifier() == EvqGlobal ||
+            variable->getQualifier() == EvqConst);
+}
+
+bool IsInStd140InterfaceBlock(TIntermTyped *node)
+{
+    TIntermBinary *binaryNode = node->getAsBinaryNode();
+
+    if (binaryNode)
+    {
+        return IsInStd140InterfaceBlock(binaryNode->getLeft());
+    }
+
+    const TType &type = node->getType();
+
+    // determine if we are in the standard layout
+    const TInterfaceBlock *interfaceBlock = type.getInterfaceBlock();
+    if (interfaceBlock)
+    {
+        return (interfaceBlock->blockStorage() == EbsStd140);
+    }
+
+    return false;
+}
+
 }  // anonymous namespace
 
+TReferencedBlock::TReferencedBlock(const TInterfaceBlock *aBlock,
+                                   const TVariable *aInstanceVariable)
+    : block(aBlock), instanceVariable(aInstanceVariable)
+{
+}
+
 void OutputHLSL::writeFloat(TInfoSinkBase &out, float f)
 {
     // This is known not to work for NaN on all drivers but make the best effort to output NaNs
     // regardless.
     if ((gl::isInf(f) || gl::isNaN(f)) && mShaderVersion >= 300 &&
         mOutputType == SH_HLSL_4_1_OUTPUT)
     {
         out << "asfloat(" << gl::bitCast<uint32_t>(f) << "u)";
@@ -104,26 +144,29 @@ const TConstantUnion *OutputHLSL::writeC
 
 OutputHLSL::OutputHLSL(sh::GLenum shaderType,
                        int shaderVersion,
                        const TExtensionBehavior &extensionBehavior,
                        const char *sourcePath,
                        ShShaderOutput outputType,
                        int numRenderTargets,
                        const std::vector<Uniform> &uniforms,
-                       ShCompileOptions compileOptions)
-    : TIntermTraverser(true, true, true),
+                       ShCompileOptions compileOptions,
+                       TSymbolTable *symbolTable,
+                       PerformanceDiagnostics *perfDiagnostics)
+    : TIntermTraverser(true, true, true, symbolTable),
       mShaderType(shaderType),
       mShaderVersion(shaderVersion),
       mExtensionBehavior(extensionBehavior),
       mSourcePath(sourcePath),
       mOutputType(outputType),
       mCompileOptions(compileOptions),
       mNumRenderTargets(numRenderTargets),
-      mCurrentFunctionMetadata(nullptr)
+      mCurrentFunctionMetadata(nullptr),
+      mPerfDiagnostics(perfDiagnostics)
 {
     mInsideFunction = false;
 
     mUsesFragColor               = false;
     mUsesFragData                = false;
     mUsesDepthRange              = false;
     mUsesFragCoord               = false;
     mUsesPointCoord              = false;
@@ -149,18 +192,23 @@ OutputHLSL::OutputHLSL(sh::GLenum shader
 
     mOutputLod0Function      = false;
     mInsideDiscontinuousLoop = false;
     mNestedLoopDepth         = 0;
 
     mExcessiveLoopIndex = nullptr;
 
     mStructureHLSL       = new StructureHLSL;
-    mUniformHLSL         = new UniformHLSL(mStructureHLSL, outputType, uniforms);
     mTextureFunctionHLSL = new TextureFunctionHLSL;
+    mImageFunctionHLSL   = new ImageFunctionHLSL;
+
+    unsigned int firstUniformRegister =
+        ((compileOptions & SH_SKIP_D3D_CONSTANT_REGISTER_ZERO) != 0) ? 1u : 0u;
+    mUniformHLSL =
+        new UniformHLSL(shaderType, mStructureHLSL, outputType, uniforms, firstUniformRegister);
 
     if (mOutputType == SH_HLSL_3_0_OUTPUT)
     {
         // Fragment shaders need dx_DepthRange, dx_ViewCoords and dx_DepthFront.
         // Vertex shaders need a slightly different set: dx_DepthRange, dx_ViewCoords and
         // dx_ViewAdjust.
         // In both cases total 3 uniform registers need to be reserved.
         mUniformHLSL->reserveUniformRegisters(3);
@@ -170,103 +218,81 @@ OutputHLSL::OutputHLSL(sh::GLenum shader
     mUniformHLSL->reserveUniformBlockRegisters(2);
 }
 
 OutputHLSL::~OutputHLSL()
 {
     SafeDelete(mStructureHLSL);
     SafeDelete(mUniformHLSL);
     SafeDelete(mTextureFunctionHLSL);
+    SafeDelete(mImageFunctionHLSL);
     for (auto &eqFunction : mStructEqualityFunctions)
     {
         SafeDelete(eqFunction);
     }
     for (auto &eqFunction : mArrayEqualityFunctions)
     {
         SafeDelete(eqFunction);
     }
 }
 
 void OutputHLSL::output(TIntermNode *treeRoot, TInfoSinkBase &objSink)
 {
-    const std::vector<TIntermTyped *> &flaggedStructs = FlagStd140ValueStructs(treeRoot);
-    makeFlaggedStructMaps(flaggedStructs);
-
     BuiltInFunctionEmulator builtInFunctionEmulator;
     InitBuiltInFunctionEmulatorForHLSL(&builtInFunctionEmulator);
     if ((mCompileOptions & SH_EMULATE_ISNAN_FLOAT_FUNCTION) != 0)
     {
         InitBuiltInIsnanFunctionEmulatorForHLSLWorkarounds(&builtInFunctionEmulator,
                                                            mShaderVersion);
     }
 
     builtInFunctionEmulator.markBuiltInFunctionsForEmulation(treeRoot);
 
     // Now that we are done changing the AST, do the analyses need for HLSL generation
     CallDAG::InitResult success = mCallDag.init(treeRoot, nullptr);
     ASSERT(success == CallDAG::INITDAG_SUCCESS);
     mASTMetadataList = CreateASTMetadataHLSL(treeRoot, mCallDag);
 
+    const std::vector<MappedStruct> std140Structs = FlagStd140Structs(treeRoot);
+    // TODO(oetuaho): The std140Structs could be filtered based on which ones actually get used in
+    // the shader code. When we add shader storage blocks we might also consider an alternative
+    // solution, since the struct mapping won't work very well for shader storage blocks.
+
     // Output the body and footer first to determine what has to go in the header
     mInfoSinkStack.push(&mBody);
     treeRoot->traverse(this);
     mInfoSinkStack.pop();
 
     mInfoSinkStack.push(&mFooter);
     mInfoSinkStack.pop();
 
     mInfoSinkStack.push(&mHeader);
-    header(mHeader, &builtInFunctionEmulator);
+    header(mHeader, std140Structs, &builtInFunctionEmulator);
     mInfoSinkStack.pop();
 
     objSink << mHeader.c_str();
     objSink << mBody.c_str();
     objSink << mFooter.c_str();
 
     builtInFunctionEmulator.cleanup();
 }
 
-void OutputHLSL::makeFlaggedStructMaps(const std::vector<TIntermTyped *> &flaggedStructs)
-{
-    for (unsigned int structIndex = 0; structIndex < flaggedStructs.size(); structIndex++)
-    {
-        TIntermTyped *flaggedNode = flaggedStructs[structIndex];
-
-        TInfoSinkBase structInfoSink;
-        mInfoSinkStack.push(&structInfoSink);
-
-        // This will mark the necessary block elements as referenced
-        flaggedNode->traverse(this);
-
-        TString structName(structInfoSink.c_str());
-        mInfoSinkStack.pop();
-
-        mFlaggedStructOriginalNames[flaggedNode] = structName;
-
-        for (size_t pos = structName.find('.'); pos != std::string::npos;
-             pos        = structName.find('.'))
-        {
-            structName.erase(pos, 1);
-        }
-
-        mFlaggedStructMappedNames[flaggedNode] = "map" + structName;
-    }
-}
-
 const std::map<std::string, unsigned int> &OutputHLSL::getUniformBlockRegisterMap() const
 {
     return mUniformHLSL->getUniformBlockRegisterMap();
 }
 
 const std::map<std::string, unsigned int> &OutputHLSL::getUniformRegisterMap() const
 {
     return mUniformHLSL->getUniformRegisterMap();
 }
 
-TString OutputHLSL::structInitializerString(int indent, const TType &type, const TString &name)
+TString OutputHLSL::structInitializerString(int indent,
+                                            const TType &type,
+                                            const TString &name) const
 {
     TString init;
 
     TString indentString;
     for (int spaces = 0; spaces < indent; spaces++)
     {
         indentString += "    ";
     }
@@ -312,65 +338,107 @@ TString OutputHLSL::structInitializerStr
     else
     {
         init += indentString + name;
     }
 
     return init;
 }
 
-void OutputHLSL::header(TInfoSinkBase &out, const BuiltInFunctionEmulator *builtInFunctionEmulator)
+TString OutputHLSL::generateStructMapping(const std::vector<MappedStruct> &std140Structs) const
+{
+    TString mappedStructs;
+
+    for (auto &mappedStruct : std140Structs)
+    {
+        TInterfaceBlock *interfaceBlock =
+            mappedStruct.blockDeclarator->getType().getInterfaceBlock();
+        if (mReferencedUniformBlocks.count(interfaceBlock->uniqueId().get()) == 0)
+        {
+            continue;
+        }
+
+        unsigned int instanceCount = 1u;
+        bool isInstanceArray       = mappedStruct.blockDeclarator->isArray();
+        if (isInstanceArray)
+        {
+            instanceCount = mappedStruct.blockDeclarator->getOutermostArraySize();
+        }
+
+        for (unsigned int instanceArrayIndex = 0; instanceArrayIndex < instanceCount;
+             ++instanceArrayIndex)
+        {
+            TString originalName;
+            TString mappedName("map");
+
+            if (mappedStruct.blockDeclarator->variable().symbolType() != SymbolType::Empty)
+            {
+                const TString &instanceName = mappedStruct.blockDeclarator->variable().name();
+                unsigned int instanceStringArrayIndex = GL_INVALID_INDEX;
+                if (isInstanceArray)
+                    instanceStringArrayIndex = instanceArrayIndex;
+                TString instanceString = mUniformHLSL->UniformBlockInstanceString(
+                    instanceName, instanceStringArrayIndex);
+                originalName += instanceString;
+                mappedName += instanceString;
+                originalName += ".";
+                mappedName += "_";
+            }
+
+            TString fieldName = Decorate(mappedStruct.field->name());
+            originalName += fieldName;
+            mappedName += fieldName;
+
+            TType *structType = mappedStruct.field->type();
+            mappedStructs +=
+                "static " + Decorate(structType->getStruct()->name()) + " " + mappedName;
+
+            if (structType->isArray())
+            {
+                mappedStructs += ArrayString(*mappedStruct.field->type());
+            }
+
+            mappedStructs += " =\n";
+            mappedStructs += structInitializerString(0, *structType, originalName);
+            mappedStructs += ";\n";
+        }
+    }
+    return mappedStructs;
+}
+
+void OutputHLSL::header(TInfoSinkBase &out,
+                        const std::vector<MappedStruct> &std140Structs,
+                        const BuiltInFunctionEmulator *builtInFunctionEmulator) const
 {
     TString varyings;
     TString attributes;
-    TString flaggedStructs;
-
-    for (std::map<TIntermTyped *, TString>::const_iterator flaggedStructIt =
-             mFlaggedStructMappedNames.begin();
-         flaggedStructIt != mFlaggedStructMappedNames.end(); flaggedStructIt++)
+    TString mappedStructs = generateStructMapping(std140Structs);
+
+    for (const auto &varying : mReferencedVaryings)
     {
-        TIntermTyped *structNode    = flaggedStructIt->first;
-        const TString &mappedName   = flaggedStructIt->second;
-        const TStructure &structure = *structNode->getType().getStruct();
-        const TString &originalName = mFlaggedStructOriginalNames[structNode];
-
-        flaggedStructs += "static " + Decorate(structure.name()) + " " + mappedName;
-        if (structNode->isArray())
-        {
-            flaggedStructs += ArrayString(structNode->getType());
-        }
-        flaggedStructs += " =\n";
-        flaggedStructs += structInitializerString(0, structNode->getType(), originalName);
-        flaggedStructs += ";\n";
-    }
-
-    for (ReferencedSymbols::const_iterator varying = mReferencedVaryings.begin();
-         varying != mReferencedVaryings.end(); varying++)
-    {
-        const TType &type   = varying->second->getType();
-        const TString &name = varying->second->getSymbol();
+        const TType &type   = varying.second->getType();
+        const TString &name = varying.second->name();
 
         // Program linking depends on this exact format
         varyings += "static " + InterpolationString(type.getQualifier()) + " " + TypeString(type) +
                     " " + Decorate(name) + ArrayString(type) + " = " + initializer(type) + ";\n";
     }
 
-    for (ReferencedSymbols::const_iterator attribute = mReferencedAttributes.begin();
-         attribute != mReferencedAttributes.end(); attribute++)
+    for (const auto &attribute : mReferencedAttributes)
     {
-        const TType &type   = attribute->second->getType();
-        const TString &name = attribute->second->getSymbol();
+        const TType &type   = attribute.second->getType();
+        const TString &name = attribute.second->name();
 
         attributes += "static " + TypeString(type) + " " + Decorate(name) + ArrayString(type) +
                       " = " + initializer(type) + ";\n";
     }
 
     out << mStructureHLSL->structsHeader();
 
-    mUniformHLSL->uniformsHeader(out, mOutputType, mReferencedUniforms);
+    mUniformHLSL->uniformsHeader(out, mOutputType, mReferencedUniforms, mSymbolTable);
     out << mUniformHLSL->uniformBlocksHeader(mReferencedUniformBlocks);
 
     if (!mEqualityFunctions.empty())
     {
         out << "\n// Equality functions\n\n";
         for (const auto &eqFunction : mEqualityFunctions)
         {
             out << eqFunction->functionDefinition << "\n";
@@ -422,22 +490,20 @@ void OutputHLSL::header(TInfoSinkBase &o
             IsExtensionEnabled(mExtensionBehavior, TExtension::EXT_draw_buffers);
 
         out << "// Varyings\n";
         out << varyings;
         out << "\n";
 
         if (mShaderVersion >= 300)
         {
-            for (ReferencedSymbols::const_iterator outputVariableIt =
-                     mReferencedOutputVariables.begin();
-                 outputVariableIt != mReferencedOutputVariables.end(); outputVariableIt++)
+            for (const auto &outputVariable : mReferencedOutputVariables)
             {
-                const TString &variableName = outputVariableIt->first;
-                const TType &variableType   = outputVariableIt->second->getType();
+                const TString &variableName = outputVariable.second->name();
+                const TType &variableType   = outputVariable.second->getType();
 
                 out << "static " + TypeString(variableType) + " out_" + variableName +
                            ArrayString(variableType) + " = " + initializer(variableType) + ";\n";
             }
         }
         else
         {
             const unsigned int numColorValues = usingMRTExtension ? mNumRenderTargets : 1;
@@ -553,21 +619,21 @@ void OutputHLSL::header(TInfoSinkBase &o
 
         if (mUsesDepthRange)
         {
             out << "static gl_DepthRangeParameters gl_DepthRange = {dx_DepthRange.x, "
                    "dx_DepthRange.y, dx_DepthRange.z};\n"
                    "\n";
         }
 
-        if (!flaggedStructs.empty())
+        if (!mappedStructs.empty())
         {
-            out << "// Std140 Structures accessed by value\n";
+            out << "// Structures from std140 blocks with padding removed\n";
             out << "\n";
-            out << flaggedStructs;
+            out << mappedStructs;
             out << "\n";
         }
 
         if (usingMRTExtension && mNumRenderTargets > 1)
         {
             out << "#define GL_USES_MRT\n";
         }
 
@@ -666,21 +732,21 @@ void OutputHLSL::header(TInfoSinkBase &o
 
         if (mUsesDepthRange)
         {
             out << "static gl_DepthRangeParameters gl_DepthRange = {dx_DepthRange.x, "
                    "dx_DepthRange.y, dx_DepthRange.z};\n"
                    "\n";
         }
 
-        if (!flaggedStructs.empty())
+        if (!mappedStructs.empty())
         {
-            out << "// Std140 Structures accessed by value\n";
+            out << "// Structures from std140 blocks with padding removed\n";
             out << "\n";
-            out << flaggedStructs;
+            out << mappedStructs;
             out << "\n";
         }
     }
     else  // Compute shader
     {
         ASSERT(mShaderType == GL_COMPUTE_SHADER);
 
         out << "cbuffer DriverConstants : register(b1)\n"
@@ -715,16 +781,17 @@ void OutputHLSL::header(TInfoSinkBase &o
         {
             out << "static uint gl_LocalInvocationIndex = uint(0);\n";
         }
     }
 
     bool getDimensionsIgnoresBaseLevel =
         (mCompileOptions & SH_HLSL_GET_DIMENSIONS_IGNORES_BASE_LEVEL) != 0;
     mTextureFunctionHLSL->textureFunctionHeader(out, mOutputType, getDimensionsIgnoresBaseLevel);
+    mImageFunctionHLSL->imageFunctionHeader(out);
 
     if (mUsesFragCoord)
     {
         out << "#define GL_USES_FRAG_COORD\n";
     }
 
     if (mUsesPointCoord)
     {
@@ -795,71 +862,86 @@ void OutputHLSL::header(TInfoSinkBase &o
                "\n";
     }
 
     builtInFunctionEmulator->outputEmulatedFunctions(out);
 }
 
 void OutputHLSL::visitSymbol(TIntermSymbol *node)
 {
+    const TVariable &variable = node->variable();
+
+    // Empty symbols can only appear in declarations and function arguments, and in either of those
+    // cases the symbol nodes are not visited.
+    ASSERT(variable.symbolType() != SymbolType::Empty);
+
     TInfoSinkBase &out = getInfoSink();
 
     // Handle accessing std140 structs by value
-    if (mFlaggedStructMappedNames.count(node) > 0)
+    if (IsInStd140InterfaceBlock(node) && node->getBasicType() == EbtStruct)
     {
-        out << mFlaggedStructMappedNames[node];
-        return;
+        out << "map";
     }
 
-    TString name = node->getSymbol();
+    const TString &name             = variable.name();
+    const TSymbolUniqueId &uniqueId = variable.uniqueId();
 
     if (name == "gl_DepthRange")
     {
         mUsesDepthRange = true;
         out << name;
     }
     else
     {
-        TQualifier qualifier = node->getQualifier();
+        const TType &variableType = variable.getType();
+        TQualifier qualifier      = variable.getType().getQualifier();
+
+        ensureStructDefined(variableType);
 
         if (qualifier == EvqUniform)
         {
-            const TType &nodeType                 = node->getType();
-            const TInterfaceBlock *interfaceBlock = nodeType.getInterfaceBlock();
+            const TInterfaceBlock *interfaceBlock = variableType.getInterfaceBlock();
 
             if (interfaceBlock)
             {
-                mReferencedUniformBlocks[interfaceBlock->name()] = node;
+                if (mReferencedUniformBlocks.count(interfaceBlock->uniqueId().get()) == 0)
+                {
+                    const TVariable *instanceVariable = nullptr;
+                    if (variableType.isInterfaceBlock())
+                    {
+                        instanceVariable = &variable;
+                    }
+                    mReferencedUniformBlocks[interfaceBlock->uniqueId().get()] =
+                        new TReferencedBlock(interfaceBlock, instanceVariable);
+                }
             }
             else
             {
-                mReferencedUniforms[name] = node;
+                mReferencedUniforms[uniqueId.get()] = &variable;
             }
 
-            ensureStructDefined(nodeType);
-
-            out << DecorateVariableIfNeeded(node->getName());
+            out << DecorateVariableIfNeeded(variable);
         }
         else if (qualifier == EvqAttribute || qualifier == EvqVertexIn)
         {
-            mReferencedAttributes[name] = node;
+            mReferencedAttributes[uniqueId.get()] = &variable;
             out << Decorate(name);
         }
         else if (IsVarying(qualifier))
         {
-            mReferencedVaryings[name] = node;
+            mReferencedVaryings[uniqueId.get()] = &variable;
             out << Decorate(name);
             if (name == "ViewID_OVR")
             {
                 mUsesViewID = true;
             }
         }
         else if (qualifier == EvqFragmentOut)
         {
-            mReferencedOutputVariables[name] = node;
+            mReferencedOutputVariables[uniqueId.get()] = &variable;
             out << "out_" << name;
         }
         else if (qualifier == EvqFragColor)
         {
             out << "gl_Color[0]";
             mUsesFragColor = true;
         }
         else if (qualifier == EvqFragData)
@@ -924,17 +1006,17 @@ void OutputHLSL::visitSymbol(TIntermSymb
         }
         else if (qualifier == EvqLocalInvocationIndex)
         {
             mUsesLocalInvocationIndex = true;
             out << name;
         }
         else
         {
-            out << DecorateVariableIfNeeded(node->getName());
+            out << DecorateVariableIfNeeded(variable);
         }
     }
 }
 
 void OutputHLSL::visitRaw(TIntermRaw *node)
 {
     getInfoSink() << node->getRawText();
 }
@@ -1035,23 +1117,16 @@ bool OutputHLSL::visitSwizzle(Visit visi
     }
     return true;
 }
 
 bool OutputHLSL::visitBinary(Visit visit, TIntermBinary *node)
 {
     TInfoSinkBase &out = getInfoSink();
 
-    // Handle accessing std140 structs by value
-    if (mFlaggedStructMappedNames.count(node) > 0)
-    {
-        out << mFlaggedStructMappedNames[node];
-        return false;
-    }
-
     switch (node->getOp())
     {
         case EOpComma:
             outputTriplet(out, visit, "(", ", ", ")");
             break;
         case EOpAssign:
             if (node->isArray())
             {
@@ -1177,21 +1252,26 @@ bool OutputHLSL::visitBinary(Visit visit
             break;
         case EOpIndexDirect:
         {
             const TType &leftType = node->getLeft()->getType();
             if (leftType.isInterfaceBlock())
             {
                 if (visit == PreVisit)
                 {
-                    TInterfaceBlock *interfaceBlock = leftType.getInterfaceBlock();
+                    TIntermSymbol *instanceArraySymbol = node->getLeft()->getAsSymbolNode();
+                    TInterfaceBlock *interfaceBlock    = leftType.getInterfaceBlock();
+                    if (mReferencedUniformBlocks.count(interfaceBlock->uniqueId().get()) == 0)
+                    {
+                        mReferencedUniformBlocks[interfaceBlock->uniqueId().get()] =
+                            new TReferencedBlock(interfaceBlock, &instanceArraySymbol->variable());
+                    }
                     const int arrayIndex = node->getRight()->getAsConstantUnion()->getIConst(0);
-                    mReferencedUniformBlocks[interfaceBlock->instanceName()] =
-                        node->getLeft()->getAsSymbolNode();
-                    out << mUniformHLSL->uniformBlockInstanceString(*interfaceBlock, arrayIndex);
+                    out << mUniformHLSL->UniformBlockInstanceString(instanceArraySymbol->getName(),
+                                                                    arrayIndex);
                     return false;
                 }
             }
             else if (ancestorEvaluatesToSamplerInStruct())
             {
                 // All parts of an expression that access a sampler in a struct need to use _ as
                 // separator to access the sampler variable that has been moved out of the struct.
                 outputTriplet(out, visit, "", "_", "");
@@ -1240,27 +1320,43 @@ bool OutputHLSL::visitBinary(Visit visit
                     out << "." + DecorateField(field->name(), *structure);
                 }
 
                 return false;
             }
         }
         break;
         case EOpIndexDirectInterfaceBlock:
+        {
+            bool structInStd140Block =
+                node->getBasicType() == EbtStruct && IsInStd140InterfaceBlock(node->getLeft());
+            if (visit == PreVisit && structInStd140Block)
+            {
+                out << "map";
+            }
             if (visit == InVisit)
             {
                 const TInterfaceBlock *interfaceBlock =
                     node->getLeft()->getType().getInterfaceBlock();
                 const TIntermConstantUnion *index = node->getRight()->getAsConstantUnion();
                 const TField *field               = interfaceBlock->fields()[index->getIConst(0)];
-                out << "." + Decorate(field->name());
+                if (structInStd140Block)
+                {
+                    out << "_";
+                }
+                else
+                {
+                    out << ".";
+                }
+                out << Decorate(field->name());
 
                 return false;
             }
             break;
+        }
         case EOpAdd:
             outputTriplet(out, visit, "(", " + ", ")");
             break;
         case EOpSub:
             outputTriplet(out, visit, "(", " - ", ")");
             break;
         case EOpMul:
             outputTriplet(out, visit, "(", " * ", ")");
@@ -1396,18 +1492,16 @@ bool OutputHLSL::visitUnary(Visit visit,
             break;
         case EOpSinh:
             outputTriplet(out, visit, "sinh(", "", ")");
             break;
         case EOpCosh:
             outputTriplet(out, visit, "cosh(", "", ")");
             break;
         case EOpTanh:
-            outputTriplet(out, visit, "tanh(", "", ")");
-            break;
         case EOpAsinh:
         case EOpAcosh:
         case EOpAtanh:
             ASSERT(node->getUseEmulatedFunction());
             writeEmulatedFunctionTriplet(out, visit, node->getOp());
             break;
         case EOpExp:
             outputTriplet(out, visit, "exp(", "", ")");
@@ -1565,32 +1659,33 @@ bool OutputHLSL::visitUnary(Visit visit,
 
     return true;
 }
 
 TString OutputHLSL::samplerNamePrefixFromStruct(TIntermTyped *node)
 {
     if (node->getAsSymbolNode())
     {
-        return node->getAsSymbolNode()->getSymbol();
+        ASSERT(node->getAsSymbolNode()->variable().symbolType() != SymbolType::Empty);
+        return node->getAsSymbolNode()->getName();
     }
     TIntermBinary *nodeBinary = node->getAsBinaryNode();
     switch (nodeBinary->getOp())
     {
         case EOpIndexDirect:
         {
             int index = nodeBinary->getRight()->getAsConstantUnion()->getIConst(0);
 
             TInfoSinkBase prefixSink;
             prefixSink << samplerNamePrefixFromStruct(nodeBinary->getLeft()) << "_" << index;
             return TString(prefixSink.c_str());
         }
         case EOpIndexDirectStruct:
         {
-            TStructure *s       = nodeBinary->getLeft()->getAsTyped()->getType().getStruct();
+            const TStructure *s = nodeBinary->getLeft()->getAsTyped()->getType().getStruct();
             int index           = nodeBinary->getRight()->getAsConstantUnion()->getIConst(0);
             const TField *field = s->fields()[index];
 
             TInfoSinkBase prefixSink;
             prefixSink << samplerNamePrefixFromStruct(nodeBinary->getLeft()) << "_"
                        << field->name();
             return TString(prefixSink.c_str());
         }
@@ -1605,31 +1700,43 @@ bool OutputHLSL::visitBlock(Visit visit,
     TInfoSinkBase &out = getInfoSink();
 
     if (mInsideFunction)
     {
         outputLineDirective(out, node->getLine().first_line);
         out << "{\n";
     }
 
-    for (TIntermSequence::iterator sit = node->getSequence()->begin();
-         sit != node->getSequence()->end(); sit++)
+    for (TIntermNode *statement : *node->getSequence())
     {
-        outputLineDirective(out, (*sit)->getLine().first_line);
-
-        (*sit)->traverse(this);
+        outputLineDirective(out, statement->getLine().first_line);
+
+        statement->traverse(this);
 
         // Don't output ; after case labels, they're terminated by :
         // This is needed especially since outputting a ; after a case statement would turn empty
         // case statements into non-empty case statements, disallowing fall-through from them.
-        // Also no need to output ; after if statements or sequences. This is done just for
-        // code clarity.
-        if ((*sit)->getAsCaseNode() == nullptr && (*sit)->getAsIfElseNode() == nullptr &&
-            (*sit)->getAsBlock() == nullptr)
+        // Also the output code is clearer if we don't output ; after statements where it is not
+        // needed:
+        //  * if statements
+        //  * switch statements
+        //  * blocks
+        //  * function definitions
+        //  * loops (do-while loops output the semicolon in VisitLoop)
+        //  * declarations that don't generate output.
+        if (statement->getAsCaseNode() == nullptr && statement->getAsIfElseNode() == nullptr &&
+            statement->getAsBlock() == nullptr && statement->getAsLoopNode() == nullptr &&
+            statement->getAsSwitchNode() == nullptr &&
+            statement->getAsFunctionDefinition() == nullptr &&
+            (statement->getAsDeclarationNode() == nullptr ||
+             IsDeclarationWrittenOut(statement->getAsDeclarationNode())) &&
+            statement->getAsInvariantDeclarationNode() == nullptr)
+        {
             out << ";\n";
+        }
     }
 
     if (mInsideFunction)
     {
         outputLineDirective(out, node->getLine().last_line);
         out << "}\n";
     }
 
@@ -1637,32 +1744,32 @@ bool OutputHLSL::visitBlock(Visit visit,
 }
 
 bool OutputHLSL::visitFunctionDefinition(Visit visit, TIntermFunctionDefinition *node)
 {
     TInfoSinkBase &out = getInfoSink();
 
     ASSERT(mCurrentFunctionMetadata == nullptr);
 
-    size_t index = mCallDag.findIndex(node->getFunctionSymbolInfo());
+    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->getFunctionSymbolInfo()->isMain())
+    if (node->getFunction()->isMain())
     {
         out << "gl_main(";
     }
     else
     {
-        out << DecorateFunctionIfNeeded(node->getFunctionSymbolInfo()->getNameObj())
-            << DisambiguateFunctionName(parameters) << (mOutputLod0Function ? "Lod0(" : "(");
+        out << DecorateFunctionIfNeeded(node->getFunction()) << DisambiguateFunctionName(parameters)
+            << (mOutputLod0Function ? "Lod0(" : "(");
     }
 
     for (unsigned int i = 0; i < parameters->size(); i++)
     {
         TIntermSymbol *symbol = (*parameters)[i]->getAsSymbolNode();
 
         if (symbol)
         {
@@ -1686,105 +1793,103 @@ bool OutputHLSL::visitFunctionDefinition
     node->getBody()->traverse(this);
     mInsideFunction = false;
 
     mCurrentFunctionMetadata = nullptr;
 
     bool needsLod0 = mASTMetadataList[index].mNeedsLod0;
     if (needsLod0 && !mOutputLod0Function && mShaderType == GL_FRAGMENT_SHADER)
     {
-        ASSERT(!node->getFunctionSymbolInfo()->isMain());
+        ASSERT(!node->getFunction()->isMain());
         mOutputLod0Function = true;
         node->traverse(this);
         mOutputLod0Function = false;
     }
 
     return false;
 }
 
 bool OutputHLSL::visitDeclaration(Visit visit, TIntermDeclaration *node)
 {
-    TInfoSinkBase &out = getInfoSink();
     if (visit == PreVisit)
     {
         TIntermSequence *sequence = node->getSequence();
-        TIntermTyped *variable    = (*sequence)[0]->getAsTyped();
+        TIntermTyped *declarator  = (*sequence)[0]->getAsTyped();
         ASSERT(sequence->size() == 1);
-        ASSERT(variable);
-
-        if ((variable->getQualifier() == EvqTemporary || variable->getQualifier() == EvqGlobal ||
-             variable->getQualifier() == EvqConst))
+        ASSERT(declarator);
+
+        if (IsDeclarationWrittenOut(node))
         {
-            ensureStructDefined(variable->getType());
-
-            if (!variable->getAsSymbolNode() ||
-                variable->getAsSymbolNode()->getSymbol() != "")  // Variable declaration
+            TInfoSinkBase &out = getInfoSink();
+            ensureStructDefined(declarator->getType());
+
+            if (!declarator->getAsSymbolNode() ||
+                declarator->getAsSymbolNode()->variable().symbolType() !=
+                    SymbolType::Empty)  // Variable declaration
             {
                 if (!mInsideFunction)
                 {
                     out << "static ";
                 }
 
-                out << TypeString(variable->getType()) + " ";
-
-                TIntermSymbol *symbol = variable->getAsSymbolNode();
+                out << TypeString(declarator->getType()) + " ";
+
+                TIntermSymbol *symbol = declarator->getAsSymbolNode();
 
                 if (symbol)
                 {
                     symbol->traverse(this);
                     out << ArrayString(symbol->getType());
                     out << " = " + initializer(symbol->getType());
                 }
                 else
                 {
-                    variable->traverse(this);
+                    declarator->traverse(this);
                 }
             }
-            else if (variable->getAsSymbolNode() &&
-                     variable->getAsSymbolNode()->getSymbol() == "")  // Type (struct) declaration
+        }
+        else if (IsVaryingOut(declarator->getQualifier()))
+        {
+            TIntermSymbol *symbol = declarator->getAsSymbolNode();
+            ASSERT(symbol);  // Varying declarations can't have initializers.
+
+            const TVariable &variable = symbol->variable();
+
+            if (variable.symbolType() != SymbolType::Empty)
             {
-                // Already added to constructor map
+                // Vertex outputs which are declared but not written to should still be declared to
+                // allow successful linking.
+                mReferencedVaryings[symbol->uniqueId().get()] = &variable;
             }
-            else
-                UNREACHABLE();
-        }
-        else if (IsVaryingOut(variable->getQualifier()))
-        {
-            TIntermSymbol *symbol = variable->getAsSymbolNode();
-            ASSERT(symbol);  // Varying declarations can't have initializers.
-
-            // Vertex outputs which are declared but not written to should still be declared to
-            // allow successful linking.
-            mReferencedVaryings[symbol->getSymbol()] = symbol;
         }
     }
     return false;
 }
 
 bool OutputHLSL::visitInvariantDeclaration(Visit visit, TIntermInvariantDeclaration *node)
 {
     // Do not do any translation
     return false;
 }
 
 bool OutputHLSL::visitFunctionPrototype(Visit visit, TIntermFunctionPrototype *node)
 {
     TInfoSinkBase &out = getInfoSink();
 
     ASSERT(visit == PreVisit);
-    size_t index = mCallDag.findIndex(node->getFunctionSymbolInfo());
+    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;
     }
 
     TIntermSequence *arguments = node->getSequence();
 
-    TString name = DecorateFunctionIfNeeded(node->getFunctionSymbolInfo()->getNameObj());
+    TString name = DecorateFunctionIfNeeded(node->getFunction());
     out << TypeString(node->getType()) << " " << name << DisambiguateFunctionName(arguments)
         << (mOutputLod0Function ? "Lod0(" : "(");
 
     for (unsigned int i = 0; i < arguments->size(); i++)
     {
         TIntermSymbol *symbol = (*arguments)[i]->getAsSymbolNode();
         ASSERT(symbol != nullptr);
 
@@ -1824,33 +1929,42 @@ bool OutputHLSL::visitAggregate(Visit vi
 
             bool lod0 = mInsideDiscontinuousLoop || mOutputLod0Function;
             if (node->getOp() == EOpCallFunctionInAST)
             {
                 if (node->isArray())
                 {
                     UNIMPLEMENTED();
                 }
-                size_t index = mCallDag.findIndex(node->getFunctionSymbolInfo());
+                size_t index = mCallDag.findIndex(node->getFunction()->uniqueId());
                 ASSERT(index != CallDAG::InvalidIndex);
                 lod0 &= mASTMetadataList[index].mNeedsLod0;
 
-                out << DecorateFunctionIfNeeded(node->getFunctionSymbolInfo()->getNameObj());
+                out << DecorateFunctionIfNeeded(node->getFunction());
                 out << DisambiguateFunctionName(node->getSequence());
                 out << (lod0 ? "Lod0(" : "(");
             }
             else if (node->getOp() == EOpCallInternalRawFunction)
             {
                 // This path is used for internal functions that don't have their definitions in the
                 // AST, such as precision emulation functions.
-                out << DecorateFunctionIfNeeded(node->getFunctionSymbolInfo()->getNameObj()) << "(";
+                out << DecorateFunctionIfNeeded(node->getFunction()) << "(";
+            }
+            else if (node->getFunction()->isImageFunction())
+            {
+                const TString &name       = node->getFunction()->name();
+                TType type                = (*arguments)[0]->getAsTyped()->getType();
+                TString imageFunctionName = mImageFunctionHLSL->useImageFunction(
+                    name, type.getBasicType(), type.getLayoutQualifier().imageInternalFormat,
+                    type.getMemoryQualifier().readonly);
+                out << imageFunctionName << "(";
             }
             else
             {
-                const TString &name    = node->getFunctionSymbolInfo()->getName();
+                const TString &name    = node->getFunction()->name();
                 TBasicType samplerType = (*arguments)[0]->getAsTyped()->getType().getBasicType();
                 int coords = 0;  // textureSize(gsampler2DMS) doesn't have a second argument.
                 if (arguments->size() > 1)
                 {
                     coords = (*arguments)[1]->getAsTyped()->getNominalSize();
                 }
                 TString textureFunctionName = mTextureFunctionHLSL->useTextureFunction(
                     name, samplerType, coords, arguments->size(), lod0, mShaderType);
@@ -1867,86 +1981,48 @@ bool OutputHLSL::visitAggregate(Visit vi
                     out << ", sampler_";
                 }
 
                 (*arg)->traverse(this);
 
                 if (typedArg->getType().isStructureContainingSamplers())
                 {
                     const TType &argType = typedArg->getType();
-                    TVector<TIntermSymbol *> samplerSymbols;
+                    TVector<const TVariable *> samplerSymbols;
                     TString structName = samplerNamePrefixFromStruct(typedArg);
-                    argType.createSamplerSymbols("angle_" + structName, "",
-                                                 &samplerSymbols, nullptr);
-                    for (const TIntermSymbol *sampler : samplerSymbols)
+                    argType.createSamplerSymbols("angle_" + structName, "", &samplerSymbols,
+                                                 nullptr, mSymbolTable);
+                    for (const TVariable *sampler : samplerSymbols)
                     {
                         if (mOutputType == SH_HLSL_4_0_FL9_3_OUTPUT)
                         {
-                            out << ", texture_" << sampler->getSymbol();
-                            out << ", sampler_" << sampler->getSymbol();
+                            out << ", texture_" << sampler->name();
+                            out << ", sampler_" << sampler->name();
                         }
                         else
                         {
                             // In case of HLSL 4.1+, this symbol is the sampler index, and in case
                             // of D3D9, it's the sampler variable.
-                            out << ", " + sampler->getSymbol();
+                            out << ", " + sampler->name();
                         }
                     }
                 }
 
                 if (arg < arguments->end() - 1)
                 {
                     out << ", ";
                 }
             }
 
             out << ")";
 
             return false;
         }
         case EOpConstruct:
-            if (node->getBasicType() == EbtStruct)
-            {
-                if (node->getType().isArray())
-                {
-                    UNIMPLEMENTED();
-                }
-                const TString &structName = StructNameString(*node->getType().getStruct());
-                mStructureHLSL->addConstructor(node->getType(), structName, node->getSequence());
-                outputTriplet(out, visit, (structName + "_ctor(").c_str(), ", ", ")");
-            }
-            else
-            {
-                const char *name = "";
-                if (node->getType().getNominalSize() == 1)
-                {
-                    switch (node->getBasicType())
-                    {
-                        case EbtFloat:
-                            name = "vec1";
-                            break;
-                        case EbtInt:
-                            name = "ivec1";
-                            break;
-                        case EbtUInt:
-                            name = "uvec1";
-                            break;
-                        case EbtBool:
-                            name = "bvec1";
-                            break;
-                        default:
-                            UNREACHABLE();
-                    }
-                }
-                else
-                {
-                    name = node->getType().getBuiltInTypeNameString();
-                }
-                outputConstructor(out, visit, node->getType(), name, node->getSequence());
-            }
+            outputConstructor(out, visit, node);
             break;
         case EOpEqualComponentWise:
             outputTriplet(out, visit, "(", " == ", ")");
             break;
         case EOpNotEqualComponentWise:
             outputTriplet(out, visit, "(", " != ", ")");
             break;
         case EOpLessThanComponentWise:
@@ -2130,28 +2206,23 @@ bool OutputHLSL::visitIfElse(Visit visit
 
     return false;
 }
 
 bool OutputHLSL::visitSwitch(Visit visit, TIntermSwitch *node)
 {
     TInfoSinkBase &out = getInfoSink();
 
-    if (node->getStatementList())
+    ASSERT(node->getStatementList());
+    if (visit == PreVisit)
     {
-        node->setStatementList(
-            RemoveSwitchFallThrough::removeFallThrough(node->getStatementList()));
-        outputTriplet(out, visit, "switch (", ") ", "");
-        // The curly braces get written when visiting the statementList aggregate
+        node->setStatementList(RemoveSwitchFallThrough(node->getStatementList(), mPerfDiagnostics));
     }
-    else
-    {
-        // No statementList, so it won't output curly braces
-        outputTriplet(out, visit, "switch (", ") {", "}\n");
-    }
+    outputTriplet(out, visit, "switch (", ") ", "");
+    // The curly braces get written when visiting the statementList block.
     return true;
 }
 
 bool OutputHLSL::visitCase(Visit visit, TIntermCase *node)
 {
     TInfoSinkBase &out = getInfoSink();
 
     if (node->hasCondition())
@@ -2240,85 +2311,75 @@ bool OutputHLSL::visitLoop(Visit visit, 
         out << "{;}\n";
     }
 
     outputLineDirective(out, node->getLine().first_line);
 
     if (node->getType() == ELoopDoWhile)
     {
         outputLineDirective(out, node->getCondition()->getLine().first_line);
-        out << "while(\n";
+        out << "while (";
 
         node->getCondition()->traverse(this);
 
-        out << ");";
+        out << ");\n";
     }
 
     out << "}\n";
 
     mInsideDiscontinuousLoop = wasDiscontinuous;
     mNestedLoopDepth--;
 
     return false;
 }
 
 bool OutputHLSL::visitBranch(Visit visit, TIntermBranch *node)
 {
-    TInfoSinkBase &out = getInfoSink();
-
-    switch (node->getFlowOp())
+    if (visit == PreVisit)
     {
-        case EOpKill:
-            outputTriplet(out, visit, "discard;\n", "", "");
-            break;
-        case EOpBreak:
-            if (visit == PreVisit)
-            {
+        TInfoSinkBase &out = getInfoSink();
+
+        switch (node->getFlowOp())
+        {
+            case EOpKill:
+                out << "discard";
+                break;
+            case EOpBreak:
                 if (mNestedLoopDepth > 1)
                 {
                     mUsesNestedBreak = true;
                 }
 
                 if (mExcessiveLoopIndex)
                 {
                     out << "{Break";
                     mExcessiveLoopIndex->traverse(this);
                     out << " = true; break;}\n";
                 }
                 else
                 {
-                    out << "break;\n";
+                    out << "break";
                 }
-            }
-            break;
-        case EOpContinue:
-            outputTriplet(out, visit, "continue;\n", "", "");
-            break;
-        case EOpReturn:
-            if (visit == PreVisit)
-            {
+                break;
+            case EOpContinue:
+                out << "continue";
+                break;
+            case EOpReturn:
                 if (node->getExpression())
                 {
                     out << "return ";
                 }
                 else
                 {
-                    out << "return;\n";
+                    out << "return";
                 }
-            }
-            else if (visit == PostVisit)
-            {
-                if (node->getExpression())
-                {
-                    out << ";\n";
-                }
-            }
-            break;
-        default:
-            UNREACHABLE();
+                break;
+            default:
+                UNREACHABLE();
+        }
     }
 
     return true;
 }
 
 // Handle loops with more than 254 iterations (unsupported by D3D9) by splitting them
 // (The D3D documentation says 255 iterations, but the compiler complains at anything more than
 // 254).
@@ -2366,17 +2427,17 @@ bool OutputHLSL::handleExcessiveLoop(TIn
         }
     }
 
     // Parse comparator and limit value
     if (index != nullptr && node->getCondition())
     {
         TIntermBinary *test = node->getCondition()->getAsBinaryNode();
 
-        if (test && test->getLeft()->getAsSymbolNode()->getId() == index->getId())
+        if (test && test->getLeft()->getAsSymbolNode()->uniqueId() == index->uniqueId())
         {
             TIntermConstantUnion *constant = test->getRight()->getAsConstantUnion();
 
             if (constant)
             {
                 if (constant->getBasicType() == EbtInt && constant->isScalar())
                 {
                     comparator = test->getOp();
@@ -2576,26 +2637,27 @@ void OutputHLSL::outputLineDirective(TIn
         out << "\n";
     }
 }
 
 TString OutputHLSL::argumentString(const TIntermSymbol *symbol)
 {
     TQualifier qualifier = symbol->getQualifier();
     const TType &type    = symbol->getType();
-    const TName &name    = symbol->getName();
+    const TVariable &variable = symbol->variable();
     TString nameStr;
 
-    if (name.getString().empty())  // HLSL demands named arguments, also for prototypes
+    if (variable.symbolType() ==
+        SymbolType::Empty)  // HLSL demands named arguments, also for prototypes
     {
         nameStr = "x" + str(mUniqueIndex++);
     }
     else
     {
-        nameStr = DecorateVariableIfNeeded(name);
+        nameStr = DecorateVariableIfNeeded(variable);
     }
 
     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);
@@ -2614,40 +2676,40 @@ TString OutputHLSL::argumentString(const
     argString << QualifierString(qualifier) << " " << TypeString(type) << " " << nameStr
               << ArrayString(type);
 
     // If the structure parameter contains samplers, they need to be passed into the function as
     // separate parameters. HLSL doesn't natively support samplers in structs.
     if (type.isStructureContainingSamplers())
     {
         ASSERT(qualifier != EvqOut && qualifier != EvqInOut);
-        TVector<TIntermSymbol *> samplerSymbols;
-        type.createSamplerSymbols("angle" + nameStr, "", &samplerSymbols, nullptr);
-        for (const TIntermSymbol *sampler : samplerSymbols)
+        TVector<const TVariable *> samplerSymbols;
+        type.createSamplerSymbols("angle" + nameStr, "", &samplerSymbols, nullptr, mSymbolTable);
+        for (const TVariable *sampler : samplerSymbols)
         {
             const TType &samplerType = sampler->getType();
             if (mOutputType == SH_HLSL_4_1_OUTPUT)
             {
-                argString << ", const uint " << sampler->getSymbol() << ArrayString(samplerType);
+                argString << ", const uint " << sampler->name() << ArrayString(samplerType);
             }
             else if (mOutputType == SH_HLSL_4_0_FL9_3_OUTPUT)
             {
                 ASSERT(IsSampler(samplerType.getBasicType()));
                 argString << ", " << QualifierString(qualifier) << " "
                           << TextureString(samplerType.getBasicType()) << " texture_"
-                          << sampler->getSymbol() << ArrayString(samplerType) << ", "
+                          << sampler->name() << ArrayString(samplerType) << ", "
                           << QualifierString(qualifier) << " "
                           << SamplerString(samplerType.getBasicType()) << " sampler_"
-                          << sampler->getSymbol() << ArrayString(samplerType);
+                          << sampler->name() << ArrayString(samplerType);
             }
             else
             {
                 ASSERT(IsSampler(samplerType.getBasicType()));
                 argString << ", " << QualifierString(qualifier) << " " << TypeString(samplerType)
-                          << " " << sampler->getSymbol() << ArrayString(samplerType);
+                          << " " << sampler->name() << ArrayString(samplerType);
             }
         }
     }
 
     return argString.str();
 }
 
 TString OutputHLSL::initializer(const TType &type)
@@ -2663,31 +2725,33 @@ TString OutputHLSL::initializer(const TT
         {
             string += ", ";
         }
     }
 
     return "{" + string + "}";
 }
 
-void OutputHLSL::outputConstructor(TInfoSinkBase &out,
-                                   Visit visit,
-                                   const TType &type,
-                                   const char *name,
-                                   const TIntermSequence *parameters)
+void OutputHLSL::outputConstructor(TInfoSinkBase &out, Visit visit, TIntermAggregate *node)
 {
-    if (type.isArray())
-    {
-        UNIMPLEMENTED();
-    }
+    // Array constructors should have been already pruned from the code.
+    ASSERT(!node->getType().isArray());
 
     if (visit == PreVisit)
     {
-        TString constructorName = mStructureHLSL->addConstructor(type, name, parameters);
-
+        TString constructorName;
+        if (node->getBasicType() == EbtStruct)
+        {
+            constructorName = mStructureHLSL->addStructConstructor(*node->getType().getStruct());
+        }
+        else
+        {
+            constructorName =
+                mStructureHLSL->addBuiltInConstructor(node->getType(), node->getSequence());
+        }
         out << constructorName << "(";
     }
     else if (visit == InVisit)
     {
         out << ", ";
     }
     else if (visit == PostVisit)
     {
@@ -2699,17 +2763,17 @@ const TConstantUnion *OutputHLSL::writeC
                                                      const TType &type,
                                                      const TConstantUnion *const constUnion)
 {
     const TConstantUnion *constUnionIterated = constUnion;
 
     const TStructure *structure = type.getStruct();
     if (structure)
     {
-        out << StructNameString(*structure) + "_ctor(";
+        out << mStructureHLSL->addStructConstructor(*structure) << "(";
 
         const TFieldList &fields = structure->fields();
 
         for (size_t i = 0; i < fields.size(); i++)
         {
             const TType *fieldType = fields[i]->type();
             constUnionIterated     = writeConstantUnion(out, *fieldType, constUnionIterated);
 
@@ -2753,20 +2817,20 @@ void OutputHLSL::writeEmulatedFunctionTr
         outputTriplet(out, visit, nullptr, ", ", ")");
     }
 }
 
 bool OutputHLSL::writeSameSymbolInitializer(TInfoSinkBase &out,
                                             TIntermSymbol *symbolNode,
                                             TIntermTyped *expression)
 {
-    sh::SearchSymbol searchSymbol(symbolNode->getSymbol());
-    expression->traverse(&searchSymbol);
-
-    if (searchSymbol.foundMatch())
+    ASSERT(symbolNode->variable().symbolType() != SymbolType::Empty);
+    const TIntermSymbol *symbolInInitializer = FindSymbolNode(expression, symbolNode->getName());
+
+    if (symbolInInitializer)
     {
         // Type already printed
         out << "t" + str(mUniqueIndex) + " = ";
         expression->traverse(this);
         out << ", ";
         symbolNode->traverse(this);
         out << " = t" + str(mUniqueIndex);
 
@@ -3026,17 +3090,17 @@ TString OutputHLSL::addArrayConstructInt
 
     mArrayConstructIntoFunctions.push_back(function);
 
     return function.functionName;
 }
 
 void OutputHLSL::ensureStructDefined(const TType &type)
 {
-    TStructure *structure = type.getStruct();
-
+    const TStructure *structure = type.getStruct();
     if (structure)
     {
-        mStructureHLSL->addConstructor(type, StructNameString(*structure), nullptr);
+        ASSERT(type.getBasicType() == EbtStruct);
+        mStructureHLSL->ensureStructDefined(*structure);
     }
 }
 
 }  // namespace sh
--- a/gfx/angle/src/compiler/translator/OutputHLSL.h
+++ b/gfx/angle/src/compiler/translator/OutputHLSL.h
@@ -9,40 +9,56 @@
 
 #include <list>
 #include <map>
 #include <stack>
 
 #include "angle_gl.h"
 #include "compiler/translator/ASTMetadataHLSL.h"
 #include "compiler/translator/Compiler.h"
+#include "compiler/translator/FlagStd140Structs.h"
 #include "compiler/translator/IntermTraverse.h"
 
 class BuiltInFunctionEmulator;
 
 namespace sh
 {
 class StructureHLSL;
 class TextureFunctionHLSL;
+class TSymbolTable;
+class TVariable;
+class ImageFunctionHLSL;
 class UnfoldShortCircuit;
 class UniformHLSL;
 
-typedef std::map<TString, TIntermSymbol *> ReferencedSymbols;
+struct TReferencedBlock : angle::NonCopyable
+{
+    POOL_ALLOCATOR_NEW_DELETE();
+    TReferencedBlock(const TInterfaceBlock *block, const TVariable *instanceVariable);
+    const TInterfaceBlock *block;
+    const TVariable *instanceVariable;  // May be nullptr if the block is not instanced.
+};
+
+// Maps from uniqueId to a variable.
+using ReferencedInterfaceBlocks = std::map<int, const TReferencedBlock *>;
+using ReferencedVariables       = std::map<int, const TVariable *>;
 
 class OutputHLSL : public TIntermTraverser
 {
   public:
     OutputHLSL(sh::GLenum shaderType,
                int shaderVersion,
                const TExtensionBehavior &extensionBehavior,
                const char *sourcePath,
                ShShaderOutput outputType,
                int numRenderTargets,
                const std::vector<Uniform> &uniforms,
-               ShCompileOptions compileOptions);
+               ShCompileOptions compileOptions,
+               TSymbolTable *symbolTable,
+               PerformanceDiagnostics *perfDiagnostics);
 
     ~OutputHLSL();
 
     void output(TIntermNode *treeRoot, TInfoSinkBase &objSink);
 
     const std::map<std::string, unsigned int> &getUniformBlockRegisterMap() const;
     const std::map<std::string, unsigned int> &getUniformRegisterMap() const;
 
@@ -52,71 +68,67 @@ class OutputHLSL : public TIntermTravers
     {
         ASSERT(!mInfoSinkStack.empty());
         return *mInfoSinkStack.top();
     }
 
     static bool canWriteAsHLSLLiteral(TIntermTyped *expression);
 
   protected:
-    void header(TInfoSinkBase &out, const BuiltInFunctionEmulator *builtInFunctionEmulator);
+    void header(TInfoSinkBase &out,
+                const std::vector<MappedStruct> &std140Structs,
+                const BuiltInFunctionEmulator *builtInFunctionEmulator) const;
 
     void writeFloat(TInfoSinkBase &out, float f);
     void writeSingleConstant(TInfoSinkBase &out, const TConstantUnion *const constUnion);
     const TConstantUnion *writeConstantUnionArray(TInfoSinkBase &out,
                                                   const TConstantUnion *const constUnion,
                                                   const size_t size);
 
     // Visit AST nodes and output their code to the body stream
-    void visitSymbol(TIntermSymbol *);
-    void visitRaw(TIntermRaw *);
-    void visitConstantUnion(TIntermConstantUnion *);
+    void visitSymbol(TIntermSymbol *) override;
+    void visitRaw(TIntermRaw *) override;
+    void visitConstantUnion(TIntermConstantUnion *) override;
     bool visitSwizzle(Visit visit, TIntermSwizzle *node) override;
-    bool visitBinary(Visit visit, TIntermBinary *);
-    bool visitUnary(Visit visit, TIntermUnary *);
-    bool visitTernary(Visit visit, TIntermTernary *);
-    bool visitIfElse(Visit visit, TIntermIfElse *);
-    bool visitSwitch(Visit visit, TIntermSwitch *);
-    bool visitCase(Visit visit, TIntermCase *);
+    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;
     bool visitFunctionDefinition(Visit visit, TIntermFunctionDefinition *node) override;
-    bool visitAggregate(Visit visit, TIntermAggregate *);
-    bool visitBlock(Visit visit, TIntermBlock *node);
-    bool visitInvariantDeclaration(Visit visit, TIntermInvariantDeclaration *node);
-    bool visitDeclaration(Visit visit, TIntermDeclaration *node);
-    bool visitLoop(Visit visit, TIntermLoop *);
-    bool visitBranch(Visit visit, TIntermBranch *);
+    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;
 
     bool handleExcessiveLoop(TInfoSinkBase &out, TIntermLoop *node);
 
     // Emit one of three strings depending on traverse phase. Called with literal strings so using
     // const char* instead of TString.
     void outputTriplet(TInfoSinkBase &out,
                        Visit visit,
                        const char *preString,
                        const char *inString,
                        const char *postString);
     void outputLineDirective(TInfoSinkBase &out, int line);
     TString argumentString(const TIntermSymbol *symbol);
 
-    // Emit constructor. Called with literal names so using const char* instead of TString.
-    void outputConstructor(TInfoSinkBase &out,
-                           Visit visit,
-                           const TType &type,
-                           const char *name,
-                           const TIntermSequence *parameters);
+    void outputConstructor(TInfoSinkBase &out, Visit visit, TIntermAggregate *node);
     const TConstantUnion *writeConstantUnion(TInfoSinkBase &out,
                                              const TType &type,
                                              const TConstantUnion *constUnion);
 
     void outputEqual(Visit visit, const TType &type, TOperator op, TInfoSinkBase &out);
     void outputAssign(Visit visit, const TType &type, TInfoSinkBase &out);
 
     void writeEmulatedFunctionTriplet(TInfoSinkBase &out, Visit visit, TOperator op);
-    void makeFlaggedStructMaps(const std::vector<TIntermTyped *> &flaggedStructs);
 
     // Returns true if it found a 'same symbol' initializer (initializer that references the
     // variable it's initting)
     bool writeSameSymbolInitializer(TInfoSinkBase &out,
                                     TIntermSymbol *symbolNode,
                                     TIntermTyped *expression);
     // Returns true if variable initializer could be written using literal {} notation.
     bool writeConstantInitialization(TInfoSinkBase &out,
@@ -148,25 +160,29 @@ class OutputHLSL : public TIntermTravers
     TInfoSinkBase mBody;
     TInfoSinkBase mFooter;
 
     // A stack is useful when we want to traverse in the header, or in helper functions, but not
     // always write to the body. Instead use an InfoSink stack to keep our current state intact.
     // TODO (jmadill): Just passing an InfoSink in function parameters would be simpler.
     std::stack<TInfoSinkBase *> mInfoSinkStack;
 
-    ReferencedSymbols mReferencedUniforms;
-    ReferencedSymbols mReferencedUniformBlocks;
-    ReferencedSymbols mReferencedAttributes;
-    ReferencedSymbols mReferencedVaryings;
-    ReferencedSymbols mReferencedOutputVariables;
+    ReferencedVariables mReferencedUniforms;
+
+    // Indexed by block id, not instance id.
+    ReferencedInterfaceBlocks mReferencedUniformBlocks;
+
+    ReferencedVariables mReferencedAttributes;
+    ReferencedVariables mReferencedVaryings;
+    ReferencedVariables mReferencedOutputVariables;
 
     StructureHLSL *mStructureHLSL;
     UniformHLSL *mUniformHLSL;
     TextureFunctionHLSL *mTextureFunctionHLSL;
+    ImageFunctionHLSL *mImageFunctionHLSL;
 
     // Parameters determining what goes in the header output
     bool mUsesFragColor;
     bool mUsesFragData;
     bool mUsesDepthRange;
     bool mUsesFragCoord;
     bool mUsesPointCoord;
     bool mUsesFrontFacing;
@@ -194,20 +210,17 @@ class OutputHLSL : public TIntermTravers
     MetadataList mASTMetadataList;
     ASTMetadataHLSL *mCurrentFunctionMetadata;
     bool mOutputLod0Function;
     bool mInsideDiscontinuousLoop;
     int mNestedLoopDepth;
 
     TIntermSymbol *mExcessiveLoopIndex;
 
-    TString structInitializerString(int indent, const TType &type, const TString &name);
-
-    std::map<TIntermTyped *, TString> mFlaggedStructMappedNames;
-    std::map<TIntermTyped *, TString> mFlaggedStructOriginalNames;
+    TString structInitializerString(int indent, const TType &type, const TString &name) const;
 
     struct HelperFunction
     {
         TString functionName;
         TString functionDefinition;
 
         virtual ~HelperFunction() {}
     };
@@ -232,15 +245,18 @@ class OutputHLSL : public TIntermTravers
 
     std::vector<ArrayHelperFunction> mArrayAssignmentFunctions;
 
     // The construct-into functions are functions that fill an N-element array passed as an out
     // parameter with the other N parameters of the function. This is used to work around that
     // arrays can't be return values in HLSL.
     std::vector<ArrayHelperFunction> mArrayConstructIntoFunctions;
 
+    PerformanceDiagnostics *mPerfDiagnostics;
+
   private:
+    TString generateStructMapping(const std::vector<MappedStruct> &std140Structs) const;
     TString samplerNamePrefixFromStruct(TIntermTyped *node);
     bool ancestorEvaluatesToSamplerInStruct();
 };
 }
 
 #endif  // COMPILER_TRANSLATOR_OUTPUTHLSL_H_
--- a/gfx/angle/src/compiler/translator/OutputTree.cpp
+++ b/gfx/angle/src/compiler/translator/OutputTree.cpp
@@ -8,21 +8,22 @@
 #include "compiler/translator/SymbolTable.h"
 
 namespace sh
 {
 
 namespace
 {
 
-void OutputFunction(TInfoSinkBase &out, const char *str, TFunctionSymbolInfo *info)
+void OutputFunction(TInfoSinkBase &out, const char *str, const TFunction *func)
 {
-    const char *internal = info->getNameObj().isInternal() ? " (internal function)" : "";
-    out << str << internal << ": " << info->getNameObj().getString() << " (symbol id "
-        << info->getId().get() << ")";
+    const char *internal =
+        (func->symbolType() == SymbolType::AngleInternal) ? " (internal function)" : "";
+    out << str << internal << ": " << func->name() << " (symbol id " << func->uniqueId().get()
+        << ")";
 }
 
 // Two purposes:
 // 1.  Show an example of how to iterate tree.  Functions can also directly call traverse() on
 //     children themselves to have finer grained control over the process than shown here, though
 //     that's not recommended if it can be avoided.
 // 2.  Print out a text based description of the tree.
 
@@ -75,18 +76,25 @@ void OutputTreeText(TInfoSinkBase &out, 
 // continue on to children.  If you process children yourself,
 // return false.
 //
 
 void TOutputTraverser::visitSymbol(TIntermSymbol *node)
 {
     OutputTreeText(mOut, node, mDepth);
 
-    mOut << "'" << node->getSymbol() << "' ";
-    mOut << "(symbol id " << node->getId() << ") ";
+    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);
     mOut << "vector swizzle (";
@@ -351,17 +359,17 @@ bool TOutputTraverser::visitInvariantDec
     OutputTreeText(mOut, node, mDepth);
     mOut << "Invariant Declaration:\n";
     return true;
 }
 
 bool TOutputTraverser::visitFunctionPrototype(Visit visit, TIntermFunctionPrototype *node)
 {
     OutputTreeText(mOut, node, mDepth);
-    OutputFunction(mOut, "Function Prototype", node->getFunctionSymbolInfo());
+    OutputFunction(mOut, "Function Prototype", node->getFunction());
     mOut << " (" << node->getCompleteString() << ")";
     mOut << "\n";
 
     return true;
 }
 
 bool TOutputTraverser::visitAggregate(Visit visit, TIntermAggregate *node)
 {
@@ -374,24 +382,24 @@ bool TOutputTraverser::visitAggregate(Vi
         return true;
     }
 
     // Give verbose names for some built-in functions that are easy to confuse with others, but
     // mostly use GLSL names for functions.
     switch (node->getOp())
     {
         case EOpCallFunctionInAST:
-            OutputFunction(mOut, "Call an user-defined function", node->getFunctionSymbolInfo());
+            OutputFunction(mOut, "Call an user-defined function", node->getFunction());
             break;
         case EOpCallInternalRawFunction:
             OutputFunction(mOut, "Call an internal function with raw implementation",
-                           node->getFunctionSymbolInfo());
+                           node->getFunction());
             break;
         case EOpCallBuiltInFunction:
-            OutputFunction(mOut, "Call a built-in function", node->getFunctionSymbolInfo());
+            OutputFunction(mOut, "Call a built-in function", node->getFunction());
             break;
 
         case EOpConstruct:
             // The type of the constructor will be printed below.
             mOut << "Construct";
             break;
 
         case EOpEqualComponentWise:
--- a/gfx/angle/src/compiler/translator/OutputVulkanGLSL.cpp
+++ b/gfx/angle/src/compiler/translator/OutputVulkanGLSL.cpp
@@ -6,86 +6,75 @@
 // OutputVulkanGLSL:
 //   Code that outputs shaders that fit GL_KHR_vulkan_glsl.
 //   The shaders are then fed into glslang to spit out SPIR-V (libANGLE-side).
 //   See: https://www.khronos.org/registry/vulkan/specs/misc/GL_KHR_vulkan_glsl.txt
 //
 
 #include "compiler/translator/OutputVulkanGLSL.h"
 
+#include "compiler/translator/util.h"
+
 namespace sh
 {
 
 TOutputVulkanGLSL::TOutputVulkanGLSL(TInfoSinkBase &objSink,
                                      ShArrayIndexClampingStrategy clampingStrategy,
                                      ShHashFunction64 hashFunction,
                                      NameMap &nameMap,
                                      TSymbolTable *symbolTable,
                                      sh::GLenum shaderType,
                                      int shaderVersion,
                                      ShShaderOutput output,
                                      ShCompileOptions compileOptions)
-    : TOutputGLSLBase(objSink,
-                      clampingStrategy,
-                      hashFunction,
-                      nameMap,
-                      symbolTable,
-                      shaderType,
-                      shaderVersion,
-                      output,
-                      compileOptions)
+    : TOutputGLSL(objSink,
+                  clampingStrategy,
+                  hashFunction,
+                  nameMap,
+                  symbolTable,
+                  shaderType,
+                  shaderVersion,
+                  output,
+                  compileOptions)
 {
 }
 
 // TODO(jmadill): This is not complete.
-void TOutputVulkanGLSL::writeLayoutQualifier(const TType &type)
+void TOutputVulkanGLSL::writeLayoutQualifier(TIntermTyped *variable)
 {
+    const TType &type = variable->getType();
+
+    bool needsCustomLayout =
+        (type.getQualifier() == EvqAttribute || type.getQualifier() == EvqFragmentOut ||
+         type.getQualifier() == EvqVertexIn || IsVarying(type.getQualifier()) ||
+         IsSampler(type.getBasicType()));
+
+    if (!NeedsToWriteLayoutQualifier(type) && !needsCustomLayout)
+    {
+        return;
+    }
+
     TInfoSinkBase &out                      = objSink();
     const TLayoutQualifier &layoutQualifier = type.getLayoutQualifier();
     out << "layout(";
 
-    if (type.getQualifier() == EvqAttribute || type.getQualifier() == EvqFragmentOut ||
-        type.getQualifier() == EvqVertexIn)
+    // This isn't super clean, but it gets the job done.
+    // See corresponding code in GlslangWrapper.cpp.
+    // TODO(jmadill): Ensure declarations are separated.
+
+    TIntermSymbol *symbol = variable->getAsSymbolNode();
+    ASSERT(symbol);
+
+    if (needsCustomLayout)
     {
-        // TODO(jmadill): Multiple output locations.
-        out << "location = "
-            << "0";
+        out << "@@ LAYOUT-" << symbol->getName() << " @@";
     }
 
     if (IsImage(type.getBasicType()) && layoutQualifier.imageInternalFormat != EiifUnspecified)
     {
         ASSERT(type.getQualifier() == EvqTemporary || type.getQualifier() == EvqUniform);
         out << getImageInternalFormatString(layoutQualifier.imageInternalFormat);
     }
 
     out << ") ";
 }
 
-bool TOutputVulkanGLSL::writeVariablePrecision(TPrecision precision)
-{
-    if (precision == EbpUndefined)
-        return false;
-
-    TInfoSinkBase &out = objSink();
-    out << getPrecisionString(precision);
-    return true;
-}
-
-void TOutputVulkanGLSL::visitSymbol(TIntermSymbol *node)
-{
-    TInfoSinkBase &out = objSink();
-
-    const TString &symbol = node->getSymbol();
-    if (symbol == "gl_FragColor")
-    {
-        out << "webgl_FragColor";
-    }
-    else if (symbol == "gl_FragData")
-    {
-        out << "webgl_FragData";
-    }
-    else
-    {
-        TOutputGLSLBase::visitSymbol(node);
-    }
-}
-
 }  // namespace sh
--- a/gfx/angle/src/compiler/translator/OutputVulkanGLSL.h
+++ b/gfx/angle/src/compiler/translator/OutputVulkanGLSL.h
@@ -9,28 +9,26 @@
 //   See: https://www.khronos.org/registry/vulkan/specs/misc/GL_KHR_vulkan_glsl.txt
 //
 
 #include "compiler/translator/OutputGLSL.h"
 
 namespace sh
 {
 
-class TOutputVulkanGLSL : public TOutputGLSLBase
+class TOutputVulkanGLSL : public TOutputGLSL
 {
   public:
     TOutputVulkanGLSL(TInfoSinkBase &objSink,
                       ShArrayIndexClampingStrategy clampingStrategy,
                       ShHashFunction64 hashFunction,
                       NameMap &nameMap,
                       TSymbolTable *symbolTable,
                       sh::GLenum shaderType,
                       int shaderVersion,
                       ShShaderOutput output,
                       ShCompileOptions compileOptions);
 
   protected:
-    void writeLayoutQualifier(const TType &type) override;
-    bool writeVariablePrecision(TPrecision precision) override;
-    void visitSymbol(TIntermSymbol *node) override;
+    void writeLayoutQualifier(TIntermTyped *variable) override;
 };
 
 }  // namespace sh
--- a/gfx/angle/src/compiler/translator/ParseContext.cpp
+++ b/gfx/angle/src/compiler/translator/ParseContext.cpp
@@ -6,18 +6,19 @@
 
 #include "compiler/translator/ParseContext.h"
 
 #include <stdarg.h>
 #include <stdio.h>
 
 #include "common/mathutil.h"
 #include "compiler/preprocessor/SourceLocation.h"
-#include "compiler/translator/Cache.h"
+#include "compiler/translator/Declarator.h"
 #include "compiler/translator/IntermNode_util.h"
+#include "compiler/translator/StaticType.h"
 #include "compiler/translator/ValidateGlobalInitializer.h"
 #include "compiler/translator/ValidateSwitch.h"
 #include "compiler/translator/glslang.h"
 #include "compiler/translator/util.h"
 
 namespace sh
 {
 
@@ -27,16 +28,32 @@ namespace sh
 //
 ////////////////////////////////////////////////////////////////////////
 
 namespace
 {
 
 const int kWebGLMaxStructNesting = 4;
 
+const std::array<const char *, 8> kAtomicBuiltin = {{"atomicAdd", "atomicMin", "atomicMax",
+                                                     "atomicAnd", "atomicOr", "atomicXor",
+                                                     "atomicExchange", "atomicCompSwap"}};
+
+bool IsAtomicBuiltin(const TString &name)
+{
+    for (size_t i = 0; i < kAtomicBuiltin.size(); ++i)
+    {
+        if (name.compare(kAtomicBuiltin[i]) == 0)
+        {
+            return true;
+        }
+    }
+    return false;
+}
+
 bool ContainsSampler(const TStructure *structType);
 
 bool ContainsSampler(const TType &type)
 {
     if (IsSampler(type.getBasicType()))
     {
         return true;
     }
@@ -66,17 +83,17 @@ const char *GetImageArgumentToken(TInter
            (imageNode->getAsBinaryNode()->getOp() == EOpIndexIndirect ||
             imageNode->getAsBinaryNode()->getOp() == EOpIndexDirect))
     {
         imageNode = imageNode->getAsBinaryNode()->getLeft();
     }
     TIntermSymbol *imageSymbol = imageNode->getAsSymbolNode();
     if (imageSymbol)
     {
-        return imageSymbol->getSymbol().c_str();
+        return imageSymbol->getName().c_str();
     }
     return "image";
 }
 
 bool CanSetDefaultPrecisionOnType(const TPublicType &type)
 {
     if (!SupportsPrecision(type.getBasicType()))
     {
@@ -111,16 +128,26 @@ GLuint GetGeometryShaderInputArraySize(T
         case EptTrianglesAdjacency:
             return 6u;
         default:
             UNREACHABLE();
             return 0u;
     }
 }
 
+bool IsBufferOrSharedVariable(TIntermTyped *var)
+{
+    if (var->isInterfaceBlock() || var->getQualifier() == EvqBuffer ||
+        var->getQualifier() == EvqShared)
+    {
+        return true;
+    }
+    return false;
+}
+
 }  // namespace
 
 // This tracks each binding point's current default offset for inheritance of subsequent
 // variables using the same binding, and keeps offsets unique and non overlapping.
 // See GLSL ES 3.1, section 4.4.6.
 class TParseContext::AtomicCounterBindingState
 {
   public:
@@ -187,34 +214,34 @@ TParseContext::TParseContext(TSymbolTabl
       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),
       mMaxImageUnits(resources.MaxImageUnits),
       mMaxCombinedTextureImageUnits(resources.MaxCombinedTextureImageUnits),
       mMaxUniformLocations(resources.MaxUniformLocations),
       mMaxUniformBufferBindings(resources.MaxUniformBufferBindings),
       mMaxAtomicCounterBindings(resources.MaxAtomicCounterBindings),
       mMaxShaderStorageBufferBindings(resources.MaxShaderStorageBufferBindings),
       mDeclaringFunction(false),
       mGeometryShaderInputPrimitiveType(EptUndefined),
       mGeometryShaderOutputPrimitiveType(EptUndefined),
       mGeometryShaderInvocations(0),
       mGeometryShaderMaxVertices(-1),
       mMaxGeometryShaderInvocations(resources.MaxGeometryShaderInvocations),
       mMaxGeometryShaderMaxVertices(resources.MaxGeometryOutputVertices),
-      mGeometryShaderInputArraySize(0)
-{
-    mComputeShaderLocalSize.fill(-1);
+      mGeometryShaderInputArraySize(0u)
+{
 }
 
 TParseContext::~TParseContext()
 {
 }
 
 bool TParseContext::parseVectorFields(const TSourceLoc &line,
                                       const TString &compString,
@@ -471,16 +498,17 @@ bool TParseContext::checkCanBeLValue(con
         case EvqConstReadOnly:
             message = "can't modify a const";
             break;
         case EvqAttribute:
             message = "can't modify an attribute";
             break;
         case EvqFragmentIn:
         case EvqVertexIn:
+        case EvqGeometryIn:
         case EvqFlatIn:
         case EvqSmoothIn:
         case EvqCentroidIn:
             message = "can't modify an input";
             break;
         case EvqUniform:
             message = "can't modify a uniform";
             break;
@@ -573,17 +601,20 @@ bool TParseContext::checkCanBeLValue(con
     if (message.empty())
         return true;
 
     //
     // If we get here, we have an error and a message.
     //
     if (symNode)
     {
-        const char *symbol = symNode->getSymbol().c_str();
+        // Symbol inside an expression can't be nameless.
+        ASSERT(symNode->variable().symbolType() != SymbolType::Empty);
+
+        const char *symbol = symNode->getName().c_str();
         std::stringstream reasonStream;
         reasonStream << "l-value required (" << message << " \"" << symbol << "\")";
         std::string reason = reasonStream.str();
         error(line, reason.c_str(), op);
     }
     else
     {
         std::stringstream reasonStream;
@@ -705,17 +736,17 @@ bool TParseContext::checkConstructorArgu
             error(line, "array constructor needs one argument per array element", "constructor");
             return false;
         }
         // GLSL ES 3.00 section 5.4.4: Each argument must be the same type as the element type of
         // the array.
         for (TIntermNode *const &argNode : *arguments)
         {
             const TType &argType = argNode->getAsTyped()->getType();
-            if (argType.isArray())
+            if (mShaderVersion < 310 && argType.isArray())
             {
                 error(line, "constructing from a non-dereferenced array", "constructor");
                 return false;
             }
             if (!argType.isElementTypeOf(type))
             {
                 error(line, "Array constructor argument has an incorrect type", "constructor");
                 return false;
@@ -902,16 +933,26 @@ void TParseContext::checkLocationIsNotSp
         {
             errorMsg =
                 "invalid layout qualifier: only valid on shader inputs, outputs, and uniforms";
         }
         error(location, errorMsg, "location");
     }
 }
 
+void TParseContext::checkStd430IsForShaderStorageBlock(const TSourceLoc &location,
+                                                       const TLayoutBlockStorage &blockStorage,
+                                                       const TQualifier &qualifier)
+{
+    if (blockStorage == EbsStd430 && qualifier != EvqBuffer)
+    {
+        error(location, "The std430 layout is supported only for shader storage blocks.", "std430");
+    }
+}
+
 void TParseContext::checkOutParameterIsNotOpaqueType(const TSourceLoc &line,
                                                      TQualifier qualifier,
                                                      const TType &type)
 {
     ASSERT(qualifier == EvqOut || qualifier == EvqInOut);
     if (IsOpaqueType(type.getBasicType()))
     {
         error(line, "opaque types cannot be output parameters", type.getBasicString());
@@ -986,17 +1027,17 @@ bool TParseContext::checkIsValidQualifie
 
     return true;
 }
 
 // See if this element type can be formed into an array.
 bool TParseContext::checkArrayElementIsNotArray(const TSourceLoc &line,
                                                 const TPublicType &elementType)
 {
-    if (elementType.array)
+    if (mShaderVersion < 310 && elementType.isArray())
     {
         error(line, "cannot declare arrays of arrays",
               TType(elementType).getCompleteString().c_str());
         return false;
     }
     return true;
 }
 
@@ -1011,70 +1052,75 @@ bool TParseContext::checkIsValidTypeAndQ
 {
     if (!checkArrayElementIsNotArray(indexLocation, elementType))
     {
         return false;
     }
     // In ESSL1.00 shaders, structs cannot be varying (section 4.3.5). This is checked elsewhere.
     // In ESSL3.00 shaders, struct inputs/outputs are allowed but not arrays of structs (section
     // 4.3.4).
+    // Geometry shader requires each user-defined input be declared as arrays or inside input
+    // blocks declared as arrays (GL_EXT_geometry_shader section 11.1gs.4.3). For the purposes of
+    // interface matching, such variables and blocks are treated as though they were not declared
+    // as arrays (GL_EXT_geometry_shader section 7.4.1).
     if (mShaderVersion >= 300 && elementType.getBasicType() == EbtStruct &&
-        sh::IsVarying(elementType.qualifier))
+        sh::IsVarying(elementType.qualifier) &&
+        !IsGeometryShaderInput(mShaderType, elementType.qualifier))
     {
         error(indexLocation, "cannot declare arrays of structs of this qualifier",
               TType(elementType).getCompleteString().c_str());
         return false;
     }
     return checkIsValidQualifierForArray(indexLocation, elementType);
 }
 
 // Enforce non-initializer type/qualifier rules.
 void TParseContext::checkCanBeDeclaredWithoutInitializer(const TSourceLoc &line,
                                                          const TString &identifier,
-                                                         TPublicType *type)
+                                                         TType *type)
 {
     ASSERT(type != nullptr);
-    if (type->qualifier == EvqConst)
+    if (type->getQualifier() == EvqConst)
     {
         // Make the qualifier make sense.
-        type->qualifier = EvqTemporary;
+        type->setQualifier(EvqTemporary);
 
         // Generate informative error messages for ESSL1.
         // In ESSL3 arrays and structures containing arrays can be constant.
         if (mShaderVersion < 300 && type->isStructureContainingArrays())
         {
             error(line,
                   "structures containing arrays may not be declared constant since they cannot be "
                   "initialized",
                   identifier.c_str());
         }
         else
         {
             error(line, "variables with qualifier 'const' must be initialized", identifier.c_str());
         }
-        return;
-    }
-    if (type->isUnsizedArray())
-    {
-        error(line, "implicitly sized arrays need to be initialized", identifier.c_str());
-    }
+    }
+    // This will make the type sized if it isn't sized yet.
+    checkIsNotUnsizedArray(line, "implicitly sized arrays need to be initialized",
+                           identifier.c_str(), type);
 }
 
 // Do some simple checks that are shared between all variable declarations,
 // and update the symbol table.
 //
 // Returns true if declaring the variable succeeded.
 //
 bool TParseContext::declareVariable(const TSourceLoc &line,
                                     const TString &identifier,
                                     const TType &type,
                                     TVariable **variable)
 {
     ASSERT((*variable) == nullptr);
 
+    (*variable) = new TVariable(&symbolTable, &identifier, type, SymbolType::UserDefined);
+
     checkBindingIsValid(line, type);
 
     bool needsReservedCheck = true;
 
     // gl_LastFragData may be redeclared with a new precision qualifier
     if (type.isArray() && identifier.compare(0, 15, "gl_LastFragData") == 0)
     {
         const TVariable *maxDrawBuffers = static_cast<const TVariable *>(
@@ -1085,32 +1131,31 @@ bool TParseContext::declareVariable(cons
                   identifier.c_str());
             return false;
         }
         else if (static_cast<int>(type.getOutermostArraySize()) ==
                  maxDrawBuffers->getConstPointer()->getIConst())
         {
             if (TSymbol *builtInSymbol = symbolTable.findBuiltIn(identifier, mShaderVersion))
             {
-                needsReservedCheck = !checkCanUseExtension(line, builtInSymbol->getExtension());
+                needsReservedCheck = !checkCanUseExtension(line, builtInSymbol->extension());
             }
         }
         else
         {
             error(line, "redeclaration of gl_LastFragData with size != gl_MaxDrawBuffers",
                   identifier.c_str());
             return false;
         }
     }
 
     if (needsReservedCheck && !checkIsNotReserved(line, identifier))
         return false;
 
-    (*variable) = symbolTable.declareVariable(&identifier, type);
-    if (!(*variable))
+    if (!symbolTable.declareVariable(*variable))
     {
         error(line, "redefinition", identifier.c_str());
         return false;
     }
 
     if (!checkIsNonVoid(line, identifier, type.getBasicType()))
         return false;
 
@@ -1142,39 +1187,97 @@ void TParseContext::checkIsParameterQual
     type->setQualifier(typeQualifier.qualifier);
 
     if (typeQualifier.precision != EbpUndefined)
     {
         type->setPrecision(typeQualifier.precision);
     }
 }
 
+template <size_t size>
+bool TParseContext::checkCanUseOneOfExtensions(const TSourceLoc &line,
+                                               const std::array<TExtension, size> &extensions)
+{
+    ASSERT(!extensions.empty());
+    const TExtensionBehavior &extBehavior = extensionBehavior();
+
+    bool canUseWithWarning    = false;
+    bool canUseWithoutWarning = false;
+
+    const char *errorMsgString   = "";
+    TExtension errorMsgExtension = TExtension::UNDEFINED;
+
+    for (TExtension extension : extensions)
+    {
+        auto extIter = extBehavior.find(extension);
+        if (canUseWithWarning)
+        {
+            // We already have an extension that we can use, but with a warning.
+            // See if we can use the alternative extension without a warning.
+            if (extIter == extBehavior.end())
+            {
+                continue;
+            }
+            if (extIter->second == EBhEnable || extIter->second == EBhRequire)
+            {
+                canUseWithoutWarning = true;
+                break;
+            }
+            continue;
+        }
+        if (extIter == extBehavior.end())
+        {
+            errorMsgString    = "extension is not supported";
+            errorMsgExtension = extension;
+        }
+        else if (extIter->second == EBhUndefined || extIter->second == EBhDisable)
+        {
+            errorMsgString    = "extension is disabled";
+            errorMsgExtension = extension;
+        }
+        else if (extIter->second == EBhWarn)
+        {
+            errorMsgExtension = extension;
+            canUseWithWarning = true;
+        }
+        else
+        {
+            ASSERT(extIter->second == EBhEnable || extIter->second == EBhRequire);
+            canUseWithoutWarning = true;
+            break;
+        }
+    }
+
+    if (canUseWithoutWarning)
+    {
+        return true;
+    }
+    if (canUseWithWarning)
+    {
+        warning(line, "extension is being used", GetExtensionNameString(errorMsgExtension));
+        return true;
+    }
+    error(line, errorMsgString, GetExtensionNameString(errorMsgExtension));
+    return false;
+}
+
+template bool TParseContext::checkCanUseOneOfExtensions(
+    const TSourceLoc &line,
+    const std::array<TExtension, 1> &extensions);
+template bool TParseContext::checkCanUseOneOfExtensions(
+    const TSourceLoc &line,
+    const std::array<TExtension, 2> &extensions);
+template bool TParseContext::checkCanUseOneOfExtensions(
+    const TSourceLoc &line,
+    const std::array<TExtension, 3> &extensions);
+
 bool TParseContext::checkCanUseExtension(const TSourceLoc &line, TExtension extension)
 {
     ASSERT(extension != TExtension::UNDEFINED);
-    const TExtensionBehavior &extBehavior   = extensionBehavior();
-    TExtensionBehavior::const_iterator iter = extBehavior.find(extension);
-    if (iter == extBehavior.end())
-    {
-        error(line, "extension is not supported", GetExtensionNameString(extension));
-        return false;
-    }
-    // In GLSL ES, an extension's default behavior is "disable".
-    if (iter->second == EBhDisable || iter->second == EBhUndefined)
-    {
-        error(line, "extension is disabled", GetExtensionNameString(extension));
-        return false;
-    }
-    if (iter->second == EBhWarn)
-    {
-        warning(line, "extension is being used", GetExtensionNameString(extension));
-        return true;
-    }
-
-    return true;
+    return checkCanUseOneOfExtensions(line, std::array<TExtension, 1u>{{extension}});
 }
 
 // ESSL 3.00.6 section 4.8 Empty Declarations: "The combinations of qualifiers that cause
 // compile-time or link-time errors are the same whether or not the declaration is empty".
 // This function implements all the checks that are done on qualifiers regardless of if the
 // declaration is empty.
 void TParseContext::declarationQualifierErrorCheck(const sh::TQualifier qualifier,
                                                    const sh::TLayoutQualifier &layoutQualifier,
@@ -1247,20 +1350,19 @@ void TParseContext::atomicCounterQualifi
         error(location, "location must not be set for atomic_uint", "layout");
     }
     if (publicType.layoutQualifier.binding == -1)
     {
         error(location, "no binding specified", "atomic counter");
     }
 }
 
-void TParseContext::emptyDeclarationErrorCheck(const TPublicType &publicType,
-                                               const TSourceLoc &location)
-{
-    if (publicType.isUnsizedArray())
+void TParseContext::emptyDeclarationErrorCheck(const TType &type, const TSourceLoc &location)
+{
+    if (type.isUnsizedArray())
     {
         // ESSL3 spec section 4.1.9: Array declaration which leaves the size unspecified is an
         // error. It is assumed that this applies to empty declarations as well.
         error(location, "empty array declaration needs to specify a size", "");
     }
 }
 
 // These checks are done for all declarations that are non-empty. They're done for non-empty
@@ -1311,19 +1413,19 @@ void TParseContext::nonEmptyDeclarationE
               getQualifierString(publicType.qualifier));
         return;
     }
 
     if (mShaderVersion >= 310 && publicType.qualifier == EvqUniform)
     {
         // Valid uniform declarations can't be unsized arrays since uniforms can't be initialized.
         // But invalid shaders may still reach here with an unsized array declaration.
-        if (!publicType.isUnsizedArray())
-        {
-            TType type(publicType);
+        TType type(publicType);
+        if (!type.isUnsizedArray())
+        {
             checkUniformLocationInRange(identifierLocation, type.getLocationCount(),
                                         publicType.layoutQualifier);
         }
     }
 
     // check for layout qualifier issues
     const TLayoutQualifier layoutQualifier = publicType.layoutQualifier;
 
@@ -1583,27 +1685,27 @@ void TParseContext::functionCallRValueLV
         TIntermTyped *argument = (*(fnCall->getSequence()))[i]->getAsTyped();
         if (!IsImage(argument->getBasicType()) && (IsQualifierUnspecified(qual) || qual == EvqIn ||
                                                    qual == EvqInOut || qual == EvqConstReadOnly))
         {
             if (argument->getMemoryQualifier().writeonly)
             {
                 error(argument->getLine(),
                       "Writeonly value cannot be passed for 'in' or 'inout' parameters.",
-                      fnCall->getFunctionSymbolInfo()->getName().c_str());
+                      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.",
-                      fnCall->getFunctionSymbolInfo()->getName().c_str());
+                      fnCall->functionName());
                 return;
             }
         }
     }
 }
 
 void TParseContext::checkInvariantVariableQualifier(bool invariant,
                                                     const TQualifier qualifier,
@@ -1624,23 +1726,16 @@ void TParseContext::checkInvariantVariab
     {
         if (!sh::CanBeInvariantESSL3OrGreater(qualifier))
         {
             error(invariantLocation, "Cannot be qualified as invariant.", "invariant");
         }
     }
 }
 
-bool TParseContext::supportsExtension(TExtension extension)
-{
-    const TExtensionBehavior &extbehavior   = extensionBehavior();
-    TExtensionBehavior::const_iterator iter = extbehavior.find(extension);
-    return (iter != extbehavior.end());
-}
-
 bool TParseContext::isExtensionEnabled(TExtension extension) const
 {
     return IsExtensionEnabled(extensionBehavior(), extension);
 }
 
 void TParseContext::handleExtensionDirective(const TSourceLoc &loc,
                                              const char *extName,
                                              const char *behavior)
@@ -1659,17 +1754,17 @@ void TParseContext::handlePragmaDirectiv
     pp::SourceLocation srcLoc;
     srcLoc.file = loc.first_file;
     srcLoc.line = loc.first_line;
     mDirectiveHandler.handlePragma(srcLoc, name, value, stdgl);
 }
 
 sh::WorkGroupSize TParseContext::getComputeShaderLocalSize() const
 {
-    sh::WorkGroupSize result;
+    sh::WorkGroupSize result(-1);
     for (size_t i = 0u; i < result.size(); ++i)
     {
         if (mComputeShaderLocalSizeDeclared && mComputeShaderLocalSize[i] == -1)
         {
             result[i] = 1;
         }
         else
         {
@@ -1707,19 +1802,19 @@ const TVariable *TParseContext::getNamed
     if (!symbol->isVariable())
     {
         error(location, "variable expected", name->c_str());
         return nullptr;
     }
 
     const TVariable *variable = static_cast<const TVariable *>(symbol);
 
-    if (variable->getExtension() != TExtension::UNDEFINED)
-    {
-        checkCanUseExtension(location, variable->getExtension());
+    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;
     }
@@ -1767,89 +1862,91 @@ TIntermTyped *TParseContext::parseVariab
 
     if (!variable)
     {
         TIntermTyped *node = CreateZeroNode(TType(EbtFloat, EbpHigh, EvqConst));
         node->setLine(location);
         return node;
     }
 
+    const TType &variableType = variable->getType();
     TIntermTyped *node = nullptr;
 
     if (variable->getConstPointer())
     {
         const TConstantUnion *constArray = variable->getConstPointer();
-        node = new TIntermConstantUnion(constArray, variable->getType());
-    }
-    else if (variable->getType().getQualifier() == EvqWorkGroupSize &&
-             mComputeShaderLocalSizeDeclared)
+        node                             = new TIntermConstantUnion(constArray, variableType);
+    }
+    else if (variableType.getQualifier() == EvqWorkGroupSize && mComputeShaderLocalSizeDeclared)
     {
         // gl_WorkGroupSize can be used to size arrays according to the ESSL 3.10.4 spec, so it
         // needs to be added to the AST as a constant and not as a symbol.
         sh::WorkGroupSize workGroupSize = getComputeShaderLocalSize();
         TConstantUnion *constArray      = new TConstantUnion[3];
         for (size_t i = 0; i < 3; ++i)
         {
             constArray[i].setUConst(static_cast<unsigned int>(workGroupSize[i]));
         }
 
-        ASSERT(variable->getType().getBasicType() == EbtUInt);
-        ASSERT(variable->getType().getObjectSize() == 3);
-
-        TType type(variable->getType());
+        ASSERT(variableType.getBasicType() == EbtUInt);
+        ASSERT(variableType.getObjectSize() == 3);
+
+        TType type(variableType);
         type.setQualifier(EvqConst);
         node = new TIntermConstantUnion(constArray, type);
     }
-    // TODO(jiawei.shao@intel.com): set array sizes for user-defined geometry shader inputs.
-    else if (variable->getType().getQualifier() == EvqPerVertexIn)
-    {
-        TType type(variable->getType());
-        type.setArraySize(0, mGeometryShaderInputArraySize);
-        node = new TIntermSymbol(variable->getUniqueId(), variable->getName(), type);
+    else if ((mGeometryShaderInputPrimitiveType != EptUndefined) &&
+             (variableType.getQualifier() == EvqPerVertexIn))
+    {
+        ASSERT(mGeometryShaderInputArraySize > 0u);
+
+        node = new TIntermSymbol(variable);
+        node->getTypePointer()->sizeOutermostUnsizedArray(mGeometryShaderInputArraySize);
     }
     else
     {
-        node = new TIntermSymbol(variable->getUniqueId(), variable->getName(), variable->getType());
+        node = new TIntermSymbol(variable);
     }
     ASSERT(node != nullptr);
     node->setLine(location);
     return node;
 }
 
 // Initializers show up in several places in the grammar.  Have one set of
 // code to handle them here.
 //
 // Returns true on success.
 bool TParseContext::executeInitializer(const TSourceLoc &line,
                                        const TString &identifier,
-                                       const TPublicType &pType,
+                                       TType type,
                                        TIntermTyped *initializer,
                                        TIntermBinary **initNode)
 {
     ASSERT(initNode != nullptr);
     ASSERT(*initNode == nullptr);
-    TType type = TType(pType);
-
-    TVariable *variable = nullptr;
+
     if (type.isUnsizedArray())
     {
         // In case initializer is not an array or type has more dimensions than initializer, this
         // will default to setting array sizes to 1. We have not checked yet whether the initializer
         // actually is an array or not. Having a non-array initializer for an unsized array will
         // result in an error later, so we don't generate an error message here.
-        type.sizeUnsizedArrays(initializer->getType().getArraySizes());
-    }
+        auto *arraySizes = initializer->getType().getArraySizes();
+        type.sizeUnsizedArrays(arraySizes);
+    }
+
+    TVariable *variable = nullptr;
     if (!declareVariable(line, identifier, type, &variable))
     {
         return false;
     }
 
     bool globalInitWarning = false;
     if (symbolTable.atGlobalLevel() &&
-        !ValidateGlobalInitializer(initializer, this, &globalInitWarning))
+        !ValidateGlobalInitializer(initializer, mShaderVersion, &globalInitWarning))
     {
         // Error message does not completely match behavior with ESSL 1.00, but
         // we want to steer developers towards only using constant expressions.
         error(line, "global variable initializers must be constant expressions", "=");
         return false;
     }
     if (globalInitWarning)
     {
@@ -1902,32 +1999,28 @@ bool TParseContext::executeInitializer(c
         if (initializer->getAsConstantUnion())
         {
             variable->shareConstPointer(initializer->getAsConstantUnion()->getUnionArrayPointer());
             ASSERT(*initNode == nullptr);
             return true;
         }
         else if (initializer->getAsSymbolNode())
         {
-            const TSymbol *symbol =
-                symbolTable.find(initializer->getAsSymbolNode()->getSymbol(), 0);
-            const TVariable *tVar = static_cast<const TVariable *>(symbol);
-
-            const TConstantUnion *constArray = tVar->getConstPointer();
+            const TVariable &var             = initializer->getAsSymbolNode()->variable();
+            const TConstantUnion *constArray = var.getConstPointer();
             if (constArray)
             {
                 variable->shareConstPointer(constArray);
                 ASSERT(*initNode == nullptr);
                 return true;
             }
         }
     }
 
-    TIntermSymbol *intermSymbol =
-        new TIntermSymbol(variable->getUniqueId(), variable->getName(), variable->getType());
+    TIntermSymbol *intermSymbol = new TIntermSymbol(variable);
     intermSymbol->setLine(line);
     *initNode = createAssign(EOpInitialize, intermSymbol, initializer, line);
     if (*initNode == nullptr)
     {
         assignError(line, "=", intermSymbol->getCompleteString(), initializer->getCompleteString());
         return false;
     }
 
@@ -1936,17 +2029,18 @@ bool TParseContext::executeInitializer(c
 
 TIntermNode *TParseContext::addConditionInitializer(const TPublicType &pType,
                                                     const TString &identifier,
                                                     TIntermTyped *initializer,
                                                     const TSourceLoc &loc)
 {
     checkIsScalarBool(loc, pType);
     TIntermBinary *initNode = nullptr;
-    if (executeInitializer(loc, identifier, pType, initializer, &initNode))
+    TType type(pType);
+    if (executeInitializer(loc, identifier, type, initializer, &initNode))
     {
         // The initializer is valid. The init condition needs to have a node - either the
         // initializer node, or a constant node in case the initialized variable is const and won't
         // be recorded in the AST.
         if (initNode == nullptr)
         {
             return initializer;
         }
@@ -2039,17 +2133,17 @@ TIntermNode *TParseContext::addIfElse(TI
     return node;
 }
 
 void TParseContext::addFullySpecifiedType(TPublicType *typeSpecifier)
 {
     checkPrecisionSpecified(typeSpecifier->getLine(), typeSpecifier->precision,
                             typeSpecifier->getBasicType());
 
-    if (mShaderVersion < 300 && typeSpecifier->array)
+    if (mShaderVersion < 300 && typeSpecifier->isArray())
     {
         error(typeSpecifier->getLine(), "not supported", "first-class array");
         typeSpecifier->clearArrayness();
     }
 }
 
 TPublicType TParseContext::addFullySpecifiedType(const TTypeQualifierBuilder &typeQualifierBuilder,
                                                  const TPublicType &typeSpecifier)
@@ -2073,17 +2167,17 @@ TPublicType TParseContext::addFullySpeci
 
     checkInvariantVariableQualifier(returnType.invariant, returnType.qualifier,
                                     typeSpecifier.getLine());
 
     checkWorkGroupSizeIsNotSpecified(typeSpecifier.getLine(), returnType.layoutQualifier);
 
     if (mShaderVersion < 300)
     {
-        if (typeSpecifier.array)
+        if (typeSpecifier.isArray())
         {
             error(typeSpecifier.getLine(), "not supported", "first-class array");
             returnType.clearArrayness();
         }
 
         if (returnType.qualifier == EvqAttribute &&
             (typeSpecifier.getBasicType() == EbtBool || typeSpecifier.getBasicType() == EbtInt))
         {
@@ -2130,17 +2224,17 @@ void TParseContext::checkInputOutputType
         error(qualifierLocation, "cannot be bool", getQualifierString(qualifier));
     }
 
     // Specific restrictions apply for vertex shader inputs and fragment shader outputs.
     switch (qualifier)
     {
         case EvqVertexIn:
             // ESSL 3.00 section 4.3.4
-            if (type.array)
+            if (type.isArray())
             {
                 error(qualifierLocation, "cannot be array", getQualifierString(qualifier));
             }
             // Vertex inputs with a struct type are disallowed in nonEmptyDeclarationErrorCheck
             return;
         case EvqFragmentOut:
             // ESSL 3.00 section 4.3.6
             if (type.typeSpecifierNonArray.isMatrix())
@@ -2164,17 +2258,17 @@ void TParseContext::checkInputOutputType
               getQualifierString(qualifier));
     }
 
     if (type.getBasicType() == EbtStruct)
     {
         // ESSL 3.00 sections 4.3.4 and 4.3.6.
         // These restrictions are only implied by the ESSL 3.00 spec, but
         // the ESSL 3.10 spec lists these restrictions explicitly.
-        if (type.array)
+        if (type.isArray())
         {
             error(qualifierLocation, "cannot be an array of structures",
                   getQualifierString(qualifier));
         }
         if (type.isStructureContainingArrays())
         {
             error(qualifierLocation, "cannot be a structure containing an array",
                   getQualifierString(qualifier));
@@ -2233,40 +2327,82 @@ void TParseContext::checkMemoryQualifier
     if (memoryQualifier.volatileQualifier)
     {
         error(location, reason.c_str(), "volatile");
     }
 }
 
 // Make sure there is no offset overlapping, and store the newly assigned offset to "type" in
 // intermediate tree.
-void TParseContext::checkAtomicCounterOffsetIsNotOverlapped(TPublicType &publicType,
-                                                            size_t size,
-                                                            bool forceAppend,
-                                                            const TSourceLoc &loc,
-                                                            TType &type)
-{
-    auto &bindingState = mAtomicCounterBindingStates[publicType.layoutQualifier.binding];
+void TParseContext::checkAtomicCounterOffsetDoesNotOverlap(bool forceAppend,
+                                                           const TSourceLoc &loc,
+                                                           TType *type)
+{
+    if (!IsAtomicCounter(type->getBasicType()))
+    {
+        return;
+    }
+
+    const size_t size = type->isArray() ? kAtomicCounterArrayStride * type->getArraySizeProduct()
+                                        : kAtomicCounterSize;
+    TLayoutQualifier layoutQualifier = type->getLayoutQualifier();
+    auto &bindingState               = mAtomicCounterBindingStates[layoutQualifier.binding];
     int offset;
-    if (publicType.layoutQualifier.offset == -1 || forceAppend)
+    if (layoutQualifier.offset == -1 || forceAppend)
     {
         offset = bindingState.appendSpan(size);
     }
     else
     {
-        offset = bindingState.insertSpan(publicType.layoutQualifier.offset, size);
+        offset = bindingState.insertSpan(layoutQualifier.offset, size);
     }
     if (offset == -1)
     {
         error(loc, "Offset overlapping", "atomic counter");
         return;
     }
-    TLayoutQualifier qualifier = type.getLayoutQualifier();
-    qualifier.offset           = offset;
-    type.setLayoutQualifier(qualifier);
+    layoutQualifier.offset = offset;
+    type->setLayoutQualifier(layoutQualifier);
+}
+
+void TParseContext::checkGeometryShaderInputAndSetArraySize(const TSourceLoc &location,
+                                                            const char *token,
+                                                            TType *type)
+{
+    if (IsGeometryShaderInput(mShaderType, type->getQualifier()))
+    {
+        if (type->isArray() && type->getOutermostArraySize() == 0u)
+        {
+            // Set size for the unsized geometry shader inputs if they are declared after a valid
+            // input primitive declaration.
+            if (mGeometryShaderInputPrimitiveType != EptUndefined)
+            {
+                ASSERT(mGeometryShaderInputArraySize > 0u);
+                type->sizeOutermostUnsizedArray(mGeometryShaderInputArraySize);
+            }
+            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 "
+                      "array input",
+                      token);
+            }
+        }
+        else if (type->isArray())
+        {
+            setGeometryShaderInputArraySize(type->getOutermostArraySize(), location);
+        }
+        else
+        {
+            error(location, "Geometry shader input variable must be declared as an array", token);
+        }
+    }
 }
 
 TIntermDeclaration *TParseContext::parseSingleDeclaration(
     TPublicType &publicType,
     const TSourceLoc &identifierOrTypeLocation,
     const TString &identifier)
 {
     TType type(publicType);
@@ -2292,108 +2428,98 @@ TIntermDeclaration *TParseContext::parse
         // the specification, but there are desktop OpenGL drivers that expect that this is the
         // behavior of the #pragma when specified in ESSL 1.00 fragment shaders.
         if (qualifier == EvqVaryingOut || qualifier == EvqVertexOut || qualifier == EvqVaryingIn)
         {
             type.setInvariant(true);
         }
     }
 
+    checkGeometryShaderInputAndSetArraySize(identifierOrTypeLocation, identifier.c_str(), &type);
+
     declarationQualifierErrorCheck(publicType.qualifier, publicType.layoutQualifier,
                                    identifierOrTypeLocation);
 
     bool emptyDeclaration = (identifier == "");
     mDeferredNonEmptyDeclarationErrorCheck = emptyDeclaration;
 
     TIntermSymbol *symbol = nullptr;
     if (emptyDeclaration)
     {
-        emptyDeclarationErrorCheck(publicType, identifierOrTypeLocation);
+        emptyDeclarationErrorCheck(type, identifierOrTypeLocation);
         // In most cases we don't need to create a symbol node for an empty declaration.
         // But if the empty declaration is declaring a struct type, the symbol node will store that.
         if (type.getBasicType() == EbtStruct)
         {
-            symbol = new TIntermSymbol(0, "", type);
+            TVariable *emptyVariable =
+                new TVariable(&symbolTable, nullptr, type, SymbolType::Empty);
+            symbol = new TIntermSymbol(emptyVariable);
         }
         else if (IsAtomicCounter(publicType.getBasicType()))
         {
             setAtomicCounterBindingDefaultOffset(publicType, identifierOrTypeLocation);
         }
     }
     else
     {
         nonEmptyDeclarationErrorCheck(publicType, identifierOrTypeLocation);
 
-        checkCanBeDeclaredWithoutInitializer(identifierOrTypeLocation, identifier, &publicType);
-
-        if (IsAtomicCounter(publicType.getBasicType()))
-        {
-
-            checkAtomicCounterOffsetIsNotOverlapped(publicType, kAtomicCounterSize, false,
-                                                    identifierOrTypeLocation, type);
-        }
+        checkCanBeDeclaredWithoutInitializer(identifierOrTypeLocation, identifier, &type);
+
+        checkAtomicCounterOffsetDoesNotOverlap(false, identifierOrTypeLocation, &type);
 
         TVariable *variable = nullptr;
-        declareVariable(identifierOrTypeLocation, identifier, type, &variable);
-
-        if (variable)
-        {
-            symbol = new TIntermSymbol(variable->getUniqueId(), identifier, type);
+        if (declareVariable(identifierOrTypeLocation, identifier, type, &variable))
+        {
+            symbol = new TIntermSymbol(variable);
         }
     }
 
     TIntermDeclaration *declaration = new TIntermDeclaration();
     declaration->setLine(identifierOrTypeLocation);
     if (symbol)
     {
         symbol->setLine(identifierOrTypeLocation);
         declaration->appendDeclarator(symbol);
     }
     return declaration;
 }
 
-TIntermDeclaration *TParseContext::parseSingleArrayDeclaration(TPublicType &publicType,
-                                                               const TSourceLoc &identifierLocation,
-                                                               const TString &identifier,
-                                                               const TSourceLoc &indexLocation,
-                                                               TIntermTyped *indexExpression)
+TIntermDeclaration *TParseContext::parseSingleArrayDeclaration(
+    TPublicType &elementType,
+    const TSourceLoc &identifierLocation,
+    const TString &identifier,
+    const TSourceLoc &indexLocation,
+    const TVector<unsigned int> &arraySizes)
 {
     mDeferredNonEmptyDeclarationErrorCheck = false;
 
-    declarationQualifierErrorCheck(publicType.qualifier, publicType.layoutQualifier,
+    declarationQualifierErrorCheck(elementType.qualifier, elementType.layoutQualifier,
                                    identifierLocation);
 
-    nonEmptyDeclarationErrorCheck(publicType, identifierLocation);
-
-    checkCanBeDeclaredWithoutInitializer(identifierLocation, identifier, &publicType);
-
-    checkIsValidTypeAndQualifierForArray(indexLocation, publicType);
-
-    TType arrayType(publicType);
-
-    unsigned int size = checkIsValidArraySize(identifierLocation, indexExpression);
-    // Make the type an array even if size check failed.
-    // This ensures useless error messages regarding the variable's non-arrayness won't follow.
-    arrayType.makeArray(size);
-
-    if (IsAtomicCounter(publicType.getBasicType()))
-    {
-        checkAtomicCounterOffsetIsNotOverlapped(publicType, kAtomicCounterArrayStride * size, false,
-                                                identifierLocation, arrayType);
-    }
-
-    TVariable *variable = nullptr;
-    declareVariable(identifierLocation, identifier, arrayType, &variable);
+    nonEmptyDeclarationErrorCheck(elementType, identifierLocation);
+
+    checkIsValidTypeAndQualifierForArray(indexLocation, elementType);
+
+    TType arrayType(elementType);
+    arrayType.makeArrays(arraySizes);
+
+    checkGeometryShaderInputAndSetArraySize(indexLocation, identifier.c_str(), &arrayType);
+
+    checkCanBeDeclaredWithoutInitializer(identifierLocation, identifier, &arrayType);
+
+    checkAtomicCounterOffsetDoesNotOverlap(false, identifierLocation, &arrayType);
 
     TIntermDeclaration *declaration = new TIntermDeclaration();
     declaration->setLine(identifierLocation);
 
-    if (variable)
-    {
-        TIntermSymbol *symbol = new TIntermSymbol(variable->getUniqueId(), identifier, arrayType);
+    TVariable *variable = nullptr;
+    if (declareVariable(identifierLocation, identifier, arrayType, &variable))
+    {
+        TIntermSymbol *symbol = new TIntermSymbol(variable);
         symbol->setLine(identifierLocation);
         declaration->appendDeclarator(symbol);
     }
 
     return declaration;
 }
 
 TIntermDeclaration *TParseContext::parseSingleInitDeclaration(const TPublicType &publicType,
@@ -2408,56 +2534,47 @@ TIntermDeclaration *TParseContext::parse
                                    identifierLocation);
 
     nonEmptyDeclarationErrorCheck(publicType, identifierLocation);
 
     TIntermDeclaration *declaration = new TIntermDeclaration();
     declaration->setLine(identifierLocation);
 
     TIntermBinary *initNode = nullptr;
-    if (executeInitializer(identifierLocation, identifier, publicType, initializer, &initNode))
+    TType type(publicType);
+    if (executeInitializer(identifierLocation, identifier, type, initializer, &initNode))
     {
         if (initNode)
         {
             declaration->appendDeclarator(initNode);
         }
     }
     return declaration;
 }
 
 TIntermDeclaration *TParseContext::parseSingleArrayInitDeclaration(
-    TPublicType &publicType,
+    TPublicType &elementType,
     const TSourceLoc &identifierLocation,
     const TString &identifier,
     const TSourceLoc &indexLocation,
-    TIntermTyped *indexExpression,
+    const TVector<unsigned int> &arraySizes,
     const TSourceLoc &initLocation,
     TIntermTyped *initializer)
 {
     mDeferredNonEmptyDeclarationErrorCheck = false;
 
-    declarationQualifierErrorCheck(publicType.qualifier, publicType.layoutQualifier,
+    declarationQualifierErrorCheck(elementType.qualifier, elementType.layoutQualifier,
                                    identifierLocation);
 
-    nonEmptyDeclarationErrorCheck(publicType, identifierLocation);
-
-    checkIsValidTypeAndQualifierForArray(indexLocation, publicType);
-
-    TPublicType arrayType(publicType);
-
-    unsigned int size = 0u;
-    // If indexExpression is nullptr, then the array will eventually get its size implicitly from
-    // the initializer.
-    if (indexExpression != nullptr)
-    {
-        size = checkIsValidArraySize(identifierLocation, indexExpression);
-    }
-    // Make the type an array even if size check failed.
-    // This ensures useless error messages regarding the variable's non-arrayness won't follow.
-    arrayType.setArraySize(size);
+    nonEmptyDeclarationErrorCheck(elementType, identifierLocation);
+
+    checkIsValidTypeAndQualifierForArray(indexLocation, elementType);
+
+    TType arrayType(elementType);
+    arrayType.makeArrays(arraySizes);
 
     TIntermDeclaration *declaration = new TIntermDeclaration();
     declaration->setLine(identifierLocation);
 
     // initNode will correspond to the whole of "type b[n] = initializer".
     TIntermBinary *initNode = nullptr;
     if (executeInitializer(identifierLocation, identifier, arrayType, initializer, &initNode))
     {
@@ -2515,17 +2632,17 @@ TIntermInvariantDeclaration *TParseConte
     const TType &type = variable->getType();
 
     checkInvariantVariableQualifier(typeQualifier.invariant, type.getQualifier(),
                                     typeQualifier.line);
     checkMemoryQualifierIsNotSpecified(typeQualifier.memoryQualifier, typeQualifier.line);
 
     symbolTable.addInvariantVarying(std::string(identifier->c_str()));
 
-    TIntermSymbol *intermSymbol = new TIntermSymbol(variable->getUniqueId(), *identifier, type);
+    TIntermSymbol *intermSymbol = new TIntermSymbol(variable);
     intermSymbol->setLine(identifierLoc);
 
     return new TIntermInvariantDeclaration(intermSymbol, identifierLoc);
 }
 
 void TParseContext::parseDeclarator(TPublicType &publicType,
                                     const TSourceLoc &identifierLocation,
                                     const TString &identifier,
@@ -2536,73 +2653,65 @@ void TParseContext::parseDeclarator(TPub
     if (mDeferredNonEmptyDeclarationErrorCheck)
     {
         nonEmptyDeclarationErrorCheck(publicType, identifierLocation);
         mDeferredNonEmptyDeclarationErrorCheck = false;
     }
 
     checkDeclaratorLocationIsNotSpecified(identifierLocation, publicType);
 
-    checkCanBeDeclaredWithoutInitializer(identifierLocation, identifier, &publicType);
+    TType type(publicType);
+
+    checkGeometryShaderInputAndSetArraySize(identifierLocation, identifier.c_str(), &type);
+
+    checkCanBeDeclaredWithoutInitializer(identifierLocation, identifier, &type);
+
+    checkAtomicCounterOffsetDoesNotOverlap(true, identifierLocation, &type);
 
     TVariable *variable = nullptr;
-    TType type(publicType);
-    if (IsAtomicCounter(publicType.getBasicType()))
-    {
-        checkAtomicCounterOffsetIsNotOverlapped(publicType, kAtomicCounterSize, true,
-                                                identifierLocation, type);
-    }
-    declareVariable(identifierLocation, identifier, type, &variable);
-
-    if (variable)
-    {
-        TIntermSymbol *symbol = new TIntermSymbol(variable->getUniqueId(), identifier, type);
+    if (declareVariable(identifierLocation, identifier, type, &variable))
+    {
+        TIntermSymbol *symbol = new TIntermSymbol(variable);
         symbol->setLine(identifierLocation);
         declarationOut->appendDeclarator(symbol);
     }
 }
 
-void TParseContext::parseArrayDeclarator(TPublicType &publicType,
+void TParseContext::parseArrayDeclarator(TPublicType &elementType,
                                          const TSourceLoc &identifierLocation,
                                          const TString &identifier,
                                          const TSourceLoc &arrayLocation,
-                                         TIntermTyped *indexExpression,
+                                         const TVector<unsigned int> &arraySizes,
                                          TIntermDeclaration *declarationOut)
 {
     // If the declaration starting this declarator list was empty (example: int,), some checks were
     // not performed.
     if (mDeferredNonEmptyDeclarationErrorCheck)
     {
-        nonEmptyDeclarationErrorCheck(publicType, identifierLocation);
+        nonEmptyDeclarationErrorCheck(elementType, identifierLocation);
         mDeferredNonEmptyDeclarationErrorCheck = false;
     }
 
-    checkDeclaratorLocationIsNotSpecified(identifierLocation, publicType);
-
-    checkCanBeDeclaredWithoutInitializer(identifierLocation, identifier, &publicType);
-
-    if (checkIsValidTypeAndQualifierForArray(arrayLocation, publicType))
-    {
-        TType arrayType   = TType(publicType);
-        unsigned int size = checkIsValidArraySize(arrayLocation, indexExpression);
-        arrayType.makeArray(size);
-
-        if (IsAtomicCounter(publicType.getBasicType()))
-        {
-            checkAtomicCounterOffsetIsNotOverlapped(publicType, kAtomicCounterArrayStride * size,
-                                                    true, identifierLocation, arrayType);
-        }
+    checkDeclaratorLocationIsNotSpecified(identifierLocation, elementType);
+
+    if (checkIsValidTypeAndQualifierForArray(arrayLocation, elementType))
+    {
+        TType arrayType(elementType);
+        arrayType.makeArrays(arraySizes);
+
+        checkGeometryShaderInputAndSetArraySize(identifierLocation, identifier.c_str(), &arrayType);
+
+        checkCanBeDeclaredWithoutInitializer(identifierLocation, identifier, &arrayType);
+
+        checkAtomicCounterOffsetDoesNotOverlap(true, identifierLocation, &arrayType);
 
         TVariable *variable = nullptr;
-        declareVariable(identifierLocation, identifier, arrayType, &variable);
-
-        if (variable)
-        {
-            TIntermSymbol *symbol =
-                new TIntermSymbol(variable->getUniqueId(), identifier, arrayType);
+        if (declareVariable(identifierLocation, identifier, arrayType, &variable))
+        {
+            TIntermSymbol *symbol = new TIntermSymbol(variable);
             symbol->setLine(identifierLocation);
             declarationOut->appendDeclarator(symbol);
         }
     }
 }
 
 void TParseContext::parseInitDeclarator(const TPublicType &publicType,
                                         const TSourceLoc &identifierLocation,
@@ -2617,73 +2726,73 @@ void TParseContext::parseInitDeclarator(
     {
         nonEmptyDeclarationErrorCheck(publicType, identifierLocation);
         mDeferredNonEmptyDeclarationErrorCheck = false;
     }
 
     checkDeclaratorLocationIsNotSpecified(identifierLocation, publicType);
 
     TIntermBinary *initNode = nullptr;
-    if (executeInitializer(identifierLocation, identifier, publicType, initializer, &initNode))
+    TType type(publicType);
+    if (executeInitializer(identifierLocation, identifier, type, initializer, &initNode))
     {
         //
         // build the intermediate representation
         //
         if (initNode)
         {
             declarationOut->appendDeclarator(initNode);
         }
     }
 }
 
-void TParseContext::parseArrayInitDeclarator(const TPublicType &publicType,
+void TParseContext::parseArrayInitDeclarator(const TPublicType &elementType,
                                              const TSourceLoc &identifierLocation,
                                              const TString &identifier,
                                              const TSourceLoc &indexLocation,
-                                             TIntermTyped *indexExpression,
+                                             const TVector<unsigned int> &arraySizes,
                                              const TSourceLoc &initLocation,
                                              TIntermTyped *initializer,
                                              TIntermDeclaration *declarationOut)
 {
     // If the declaration starting this declarator list was empty (example: int,), some checks were
     // not performed.
     if (mDeferredNonEmptyDeclarationErrorCheck)
     {
-        nonEmptyDeclarationErrorCheck(publicType, identifierLocation);
+        nonEmptyDeclarationErrorCheck(elementType, identifierLocation);
         mDeferredNonEmptyDeclarationErrorCheck = false;
     }
 
-    checkDeclaratorLocationIsNotSpecified(identifierLocation, publicType);
-
-    checkIsValidTypeAndQualifierForArray(indexLocation, publicType);
-
-    TPublicType arrayType(publicType);
-
-    unsigned int size = 0u;
-    // If indexExpression is nullptr, then the array will eventually get its size implicitly from
-    // the initializer.
-    if (indexExpression != nullptr)
-    {
-        size = checkIsValidArraySize(identifierLocation, indexExpression);
-    }
-    // Make the type an array even if size check failed.
-    // This ensures useless error messages regarding the variable's non-arrayness won't follow.
-    arrayType.setArraySize(size);
+    checkDeclaratorLocationIsNotSpecified(identifierLocation, elementType);
+
+    checkIsValidTypeAndQualifierForArray(indexLocation, elementType);
+
+    TType arrayType(elementType);
+    arrayType.makeArrays(arraySizes);
 
     // initNode will correspond to the whole of "b[n] = initializer".
     TIntermBinary *initNode = nullptr;
     if (executeInitializer(identifierLocation, identifier, arrayType, initializer, &initNode))
     {
         if (initNode)
         {
             declarationOut->appendDeclarator(initNode);
         }
     }
 }
 
+TIntermNode *TParseContext::addEmptyStatement(const TSourceLoc &location)
+{
+    // It's simpler to parse an empty statement as a constant expression rather than having a
+    // different type of node just for empty statements, that will be pruned from the AST anyway.
+    TIntermNode *node = CreateZeroNode(TType(EbtInt, EbpMedium));
+    node->setLine(location);
+    return node;
+}
+
 void TParseContext::setAtomicCounterBindingDefaultOffset(const TPublicType &publicType,
                                                          const TSourceLoc &location)
 {
     const TLayoutQualifier &layoutQualifier = publicType.layoutQualifier;
     checkAtomicCounterBindingIsValid(location, layoutQualifier.binding);
     if (layoutQualifier.binding == -1 || layoutQualifier.offset == -1)
     {
         error(location, "Requires both binding and offset", "layout");
@@ -2729,23 +2838,30 @@ bool TParseContext::checkPrimitiveTypeMa
             return true;
 
         default:
             UNREACHABLE();
             return false;
     }
 }
 
-void TParseContext::setGeometryShaderInputArraySizes()
-{
-    // TODO(jiawei.shao@intel.com): check former input array sizes match the input primitive
-    // declaration.
-    ASSERT(mGeometryShaderInputArraySize == 0);
-    mGeometryShaderInputArraySize =
-        GetGeometryShaderInputArraySize(mGeometryShaderInputPrimitiveType);
+void TParseContext::setGeometryShaderInputArraySize(unsigned int inputArraySize,
+                                                    const TSourceLoc &line)
+{
+    if (mGeometryShaderInputArraySize == 0u)
+    {
+        mGeometryShaderInputArraySize = inputArraySize;
+    }
+    else if (mGeometryShaderInputArraySize != inputArraySize)
+    {
+        error(line,
+              "Array size or input primitive declaration doesn't match the size of earlier sized "
+              "array inputs.",
+              "layout");
+    }
 }
 
 bool TParseContext::parseGeometryShaderInputLayoutQualifier(const TTypeQualifier &typeQualifier)
 {
     ASSERT(typeQualifier.qualifier == EvqGeometryIn);
 
     const TLayoutQualifier &layoutQualifier = typeQualifier.layoutQualifier;
 
@@ -2763,17 +2879,19 @@ bool TParseContext::parseGeometryShaderI
         {
             error(typeQualifier.line, "invalid primitive type for 'in' layout", "layout");
             return false;
         }
 
         if (mGeometryShaderInputPrimitiveType == EptUndefined)
         {
             mGeometryShaderInputPrimitiveType = layoutQualifier.primitiveType;
-            setGeometryShaderInputArraySizes();
+            setGeometryShaderInputArraySize(
+                GetGeometryShaderInputArraySize(mGeometryShaderInputPrimitiveType),
+                typeQualifier.line);
         }
         else if (mGeometryShaderInputPrimitiveType != layoutQualifier.primitiveType)
         {
             error(typeQualifier.line, "primitive doesn't match earlier input primitive declaration",
                   "layout");
             return false;
         }
     }
@@ -2874,16 +2992,19 @@ void TParseContext::parseGlobalLayoutQua
     checkMemoryQualifierIsNotSpecified(typeQualifier.memoryQualifier, typeQualifier.line);
 
     checkInternalFormatIsNotSpecified(typeQualifier.line, layoutQualifier.imageInternalFormat);
 
     checkYuvIsNotSpecified(typeQualifier.line, layoutQualifier.yuv);
 
     checkOffsetIsNotSpecified(typeQualifier.line, layoutQualifier.offset);
 
+    checkStd430IsForShaderStorageBlock(typeQualifier.line, layoutQualifier.blockStorage,
+                                       typeQualifier.qualifier);
+
     if (typeQualifier.qualifier == EvqComputeIn)
     {
         if (mComputeShaderLocalSizeDeclared &&
             !layoutQualifier.isLocalSizeEqual(mComputeShaderLocalSize))
         {
             error(typeQualifier.line, "Work group size does not match the previous declaration",
                   "layout");
             return;
@@ -3032,55 +3153,61 @@ void TParseContext::parseGlobalLayoutQua
     }
 }
 
 TIntermFunctionPrototype *TParseContext::createPrototypeNodeFromFunction(
     const TFunction &function,
     const TSourceLoc &location,
     bool insertParametersToSymbolTable)
 {
-    checkIsNotReserved(location, function.getName());
-
-    TIntermFunctionPrototype *prototype =
-        new TIntermFunctionPrototype(function.getReturnType(), TSymbolUniqueId(function));
-    // TODO(oetuaho@nvidia.com): Instead of converting the function information here, the node could
-    // point to the data that already exists in the symbol table.
-    prototype->getFunctionSymbolInfo()->setFromFunction(function);
+    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;
 
         // 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 (insertParametersToSymbolTable)
             {
-                TVariable *variable = symbolTable.declareVariable(param.name, *param.type);
-                if (variable)
-                {
-                    symbol = new TIntermSymbol(variable->getUniqueId(), variable->getName(),
-                                               variable->getType());
-                }
-                else
+                if (!symbolTable.declareVariable(variable))
                 {
                     error(location, "redefinition", param.name->c_str());
                 }
             }
+            // Unsized type of a named parameter should have already been checked and sanitized.
+            ASSERT(!param.type->isUnsizedArray());
+        }
+        else
+        {
+            if (param.type->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.
-            symbol = new TIntermSymbol(0, "", *param.type);
+            TVariable *emptyVariable =
+                new TVariable(&symbolTable, nullptr, *param.type, SymbolType::Empty);
+            symbol = new TIntermSymbol(emptyVariable);
         }
         symbol->setLine(location);
         prototype->appendParameter(symbol);
     }
     return prototype;
 }
 
 TIntermFunctionPrototype *TParseContext::addFunctionPrototypeDeclaration(
@@ -3118,17 +3245,17 @@ TIntermFunctionDefinition *TParseContext
     TIntermFunctionPrototype *functionPrototype,
     TIntermBlock *functionBody,
     const TSourceLoc &location)
 {
     // Check that non-void functions have at least one return statement.
     if (mCurrentFunctionType->getBasicType() != EbtVoid && !mFunctionReturnsValue)
     {
         error(location, "function does not return a value:",
-              functionPrototype->getFunctionSymbolInfo()->getName().c_str());
+              functionPrototype->getFunction()->name().c_str());
     }
 
     if (functionBody == nullptr)
     {
         functionBody = new TIntermBlock();
         functionBody->setLine(location);
     }
     TIntermFunctionDefinition *functionNode =
@@ -3145,17 +3272,17 @@ void TParseContext::parseFunctionDefinit
 {
     ASSERT(function);
     ASSERT(*function);
     const TSymbol *builtIn =
         symbolTable.findBuiltIn((*function)->getMangledName(), getShaderVersion());
 
     if (builtIn)
     {
-        error(location, "built-in functions cannot be redefined", (*function)->getName().c_str());
+        error(location, "built-in functions cannot be redefined", (*function)->name().c_str());
     }
     else
     {
         TFunction *prevDec = static_cast<TFunction *>(
             symbolTable.find((*function)->getMangledName(), getShaderVersion()));
 
         // Note: 'prevDec' could be 'function' if this is the first time we've seen function as it
         // would have just been put in the symbol table. Otherwise, we're looking up an earlier
@@ -3167,17 +3294,17 @@ void TParseContext::parseFunctionDefinit
             prevDec->swapParameters(**function);
 
             // The function definition will share the same symbol as any previous declaration.
             *function = prevDec;
         }
 
         if ((*function)->isDefined())
         {
-            error(location, "function already has a body", (*function)->getName().c_str());
+            error(location, "function already has a body", (*function)->name().c_str());
         }
 
         (*function)->setDefined();
     }
 
     // Remember the return type for later checking for return statements.
     mCurrentFunctionType  = &((*function)->getReturnType());
     mFunctionReturnsValue = false;
@@ -3194,24 +3321,34 @@ TFunction *TParseContext::parseFunctionD
     // In the case of ESSL 1.00 the prototype production code will also check for redeclarations.
     //
     // Return types and parameter qualifiers must match in all redeclarations, so those are checked
     // here.
     //
     TFunction *prevDec =
         static_cast<TFunction *>(symbolTable.find(function->getMangledName(), getShaderVersion()));
 
-    if (getShaderVersion() >= 300 &&
-        symbolTable.hasUnmangledBuiltInForShaderVersion(function->getName().c_str(),
-                                                        getShaderVersion()))
+    for (size_t i = 0u; i < function->getParamCount(); ++i)
+    {
+        auto &param = function->getParam(i);
+        if (param.type->isStructSpecifier())
+        {
+            // ESSL 3.00.6 section 12.10.
+            error(location, "Function parameter type cannot be a structure definition",
+                  function->name().c_str());
+        }
+    }
+
+    if (getShaderVersion() >= 300 && symbolTable.hasUnmangledBuiltInForShaderVersion(
+                                         function->name().c_str(), getShaderVersion()))
     {
         // With ESSL 3.00 and above, names of built-in functions cannot be redeclared as functions.
         // Therefore overloading or redefining builtin functions is an error.
         error(location, "Name of a built-in function cannot be redeclared as function",
-              function->getName().c_str());
+              function->name().c_str());
     }
     else if (prevDec)
     {
         if (prevDec->getReturnType() != function->getReturnType())
         {
             error(location, "function must have the same return type in all of its declarations",
                   function->getReturnType().getBasicString());
         }
@@ -3225,36 +3362,36 @@ TFunction *TParseContext::parseFunctionD
                       function->getParam(i).type->getQualifierString());
             }
         }
     }
 
     //
     // Check for previously declared variables using the same name.
     //
-    TSymbol *prevSym = symbolTable.find(function->getName(), getShaderVersion());
+    TSymbol *prevSym = symbolTable.find(function->name(), getShaderVersion());
     if (prevSym)
     {
         if (!prevSym->isFunction())
         {
-            error(location, "redefinition of a function", function->getName().c_str());
+            error(location, "redefinition of a function", function->name().c_str());
         }
     }
     else
     {
         // Insert the unmangled name to detect potential future redefinition as a variable.
         symbolTable.getOuterLevel()->insertUnmangled(function);
     }
 
     // We're at the inner scope level of the function's arguments and body statement.
     // Add the function prototype to the surrounding scope instead.
     symbolTable.getOuterLevel()->insert(function);
 
     // Raise error message if main function takes any parameters or return anything other than void
-    if (function->getName() == "main")
+    if (function->name() == "main")
     {
         if (function->getParamCount() > 0)
         {
             error(location, "function cannot take any parameter(s)", "main");
         }
         if (function->getReturnType().getBasicType() != EbtVoid)
         {
             error(location, "main function cannot return a value",
@@ -3286,39 +3423,45 @@ TFunction *TParseContext::parseFunctionH
     // make sure an opaque type is not involved as well...
     std::string reason(getBasicString(type.getBasicType()));
     reason += "s can't be function return values";
     checkIsNotOpaqueType(location, type.typeSpecifierNonArray, reason.c_str());
     if (mShaderVersion < 300)
     {
         // Array return values are forbidden, but there's also no valid syntax for declaring array
         // return values in ESSL 1.00.
-        ASSERT(type.arraySize == 0 || mDiagnostics->numErrors() > 0);
+        ASSERT(!type.isArray() || mDiagnostics->numErrors() > 0);
 
         if (type.isStructureContainingArrays())
         {
             // ESSL 1.00.17 section 6.1 Function Definitions
             error(location, "structures containing arrays can't be function return values",
                   TType(type).getCompleteString().c_str());
         }
     }
 
     // Add the function as a prototype after parsing it (we do not support recursion)
-    return new TFunction(&symbolTable, name, new TType(type));
+    return new TFunction(&symbolTable, name, new TType(type), SymbolType::UserDefined, false);
 }
 
 TFunction *TParseContext::addNonConstructorFunc(const TString *name, const TSourceLoc &loc)
 {
-    const TType *returnType = TCache::getType(EbtVoid, EbpUndefined);
-    return new TFunction(&symbolTable, name, returnType);
+    const TType *returnType = StaticType::GetQualified<EbtVoid, EvqTemporary>();
+    // TODO(oetuaho): Some more appropriate data structure than TFunction could be used here. We're
+    // really only interested in the mangled name of the function to look up the actual function
+    // from the symbol table. If we just had the name string and the types of the parameters that
+    // would be enough, but TFunction carries a lot of extra information in addition to that.
+    // Besides function calls we do have to store constructor calls in the same data structure, for
+    // them we need to store a TType.
+    return new TFunction(&symbolTable, name, returnType, SymbolType::NotResolved, false);
 }
 
 TFunction *TParseContext::addConstructorFunc(const TPublicType &publicType)
 {
-    if (mShaderVersion < 300 && publicType.array)
+    if (mShaderVersion < 300 && publicType.isArray())
     {
         error(publicType.getLine(), "array constructor supported in GLSL ES 3.00 and above only",
               "[]");
     }
     if (publicType.isStructSpecifier())
     {
         error(publicType.getLine(), "constructor can't be a structure definition",
               getBasicString(publicType.getBasicType()));
@@ -3327,65 +3470,87 @@ TFunction *TParseContext::addConstructor
     TType *type = new TType(publicType);
     if (!type->canBeConstructed())
     {
         error(publicType.getLine(), "cannot construct this type",
               getBasicString(publicType.getBasicType()));
         type->setBasicType(EbtFloat);
     }
 
-    return new TFunction(&symbolTable, nullptr, type, EOpConstruct);
+    return new TFunction(&symbolTable, nullptr, type, SymbolType::NotResolved, true, EOpConstruct);
+}
+
+void TParseContext::checkIsNotUnsizedArray(const TSourceLoc &line,
+                                           const char *errorMessage,
+                                           const char *token,
+                                           TType *arrayType)
+{
+    if (arrayType->isUnsizedArray())
+    {
+        error(line, errorMessage, token);
+        arrayType->sizeUnsizedArrays(nullptr);
+    }
+}
+
+TParameter TParseContext::parseParameterDeclarator(TType *type,
+                                                   const TString *name,
+                                                   const TSourceLoc &nameLoc)
+{
+    ASSERT(type);
+    checkIsNotUnsizedArray(nameLoc, "function parameter array must specify a size", name->c_str(),
+                           type);
+    if (type->getBasicType() == EbtVoid)
+    {
+        error(nameLoc, "illegal use of type 'void'", name->c_str());
+    }
+    checkIsNotReserved(nameLoc, *name);
+    TParameter param = {name, type};
+    return param;
 }
 
 TParameter TParseContext::parseParameterDeclarator(const TPublicType &publicType,
                                                    const TString *name,
                                                    const TSourceLoc &nameLoc)
 {
-    if (publicType.getBasicType() == EbtVoid)
-    {
-        error(nameLoc, "illegal use of type 'void'", name->c_str());
-    }
-    checkIsNotReserved(nameLoc, *name);
-    TType *type      = new TType(publicType);
-    TParameter param = {name, type};
-    return param;
+    TType *type = new TType(publicType);
+    return parseParameterDeclarator(type, name, nameLoc);
 }
 
-TParameter TParseContext::parseParameterArrayDeclarator(const TString *identifier,
-                                                        const TSourceLoc &identifierLoc,
-                                                        TIntermTyped *arraySize,
+TParameter TParseContext::parseParameterArrayDeclarator(const TString *name,
+                                                        const TSourceLoc &nameLoc,
+                                                        const TVector<unsigned int> &arraySizes,
                                                         const TSourceLoc &arrayLoc,
-                                                        TPublicType *type)
-{
-    checkArrayElementIsNotArray(arrayLoc, *type);
-    unsigned int size = checkIsValidArraySize(arrayLoc, arraySize);
-    type->setArraySize(size);
-    return parseParameterDeclarator(*type, identifier, identifierLoc);
+                                                        TPublicType *elementType)
+{
+    checkArrayElementIsNotArray(arrayLoc, *elementType);
+    TType *arrayType = new TType(*elementType);
+    arrayType->makeArrays(arraySizes);
+    return parseParameterDeclarator(arrayType, name, nameLoc);
 }
 
 bool TParseContext::checkUnsizedArrayConstructorArgumentDimensionality(TIntermSequence *arguments,
                                                                        TType type,
                                                                        const TSourceLoc &line)
 {
     if (arguments->empty())
     {
         error(line, "implicitly sized array constructor must have at least one argument", "[]");
         return false;
     }
     for (TIntermNode *arg : *arguments)
     {
         TIntermTyped *element = arg->getAsTyped();
         ASSERT(element);
-        size_t dimensionalityFromElement = element->getType().getArraySizes().size() + 1u;
-        if (dimensionalityFromElement > type.getArraySizes().size())
+        size_t dimensionalityFromElement = element->getType().getNumArraySizes() + 1u;
+        if (dimensionalityFromElement > type.getNumArraySizes())
         {
             error(line, "constructing from a non-dereferenced array", "constructor");
             return false;
         }
-        else if (dimensionalityFromElement < type.getArraySizes().size())
+        else if (dimensionalityFromElement < type.getNumArraySizes())
         {
             if (dimensionalityFromElement == 1u)
             {
                 error(line, "implicitly sized array of arrays constructor argument is not an array",
                       "constructor");
             }
             else
             {
@@ -3408,52 +3573,49 @@ bool TParseContext::checkUnsizedArrayCon
 TIntermTyped *TParseContext::addConstructor(TIntermSequence *arguments,
                                             TType type,
                                             const TSourceLoc &line)
 {
     if (type.isUnsizedArray())
     {
         if (!checkUnsizedArrayConstructorArgumentDimensionality(arguments, type, line))
         {
-            type.sizeUnsizedArrays(TVector<unsigned int>());
+            type.sizeUnsizedArrays(nullptr);
             return CreateZeroNode(type);
         }
         TIntermTyped *firstElement = arguments->at(0)->getAsTyped();
         ASSERT(firstElement);
-        type.setArraySize(type.getArraySizes().size() - 1u,
-                          static_cast<unsigned int>(arguments->size()));
-        for (size_t i = 0; i < firstElement->getType().getArraySizes().size(); ++i)
-        {
-            if (type.getArraySizes()[i] == 0u)
+        if (type.getOutermostArraySize() == 0u)
+        {
+            type.sizeOutermostUnsizedArray(static_cast<unsigned int>(arguments->size()));
+        }
+        for (size_t i = 0; i < firstElement->getType().getNumArraySizes(); ++i)
+        {
+            if ((*type.getArraySizes())[i] == 0u)
             {
-                type.setArraySize(i, firstElement->getType().getArraySizes().at(i));
+                type.setArraySize(i, (*firstElement->getType().getArraySizes())[i]);
             }
         }
         ASSERT(!type.isUnsizedArray());
     }
 
     if (!checkConstructorArguments(line, arguments, type))
     {
         return CreateZeroNode(type);
     }
 
     TIntermAggregate *constructorNode = TIntermAggregate::CreateConstructor(type, arguments);
     constructorNode->setLine(line);
 
-    // TODO(oetuaho@nvidia.com): Add support for folding array constructors.
-    if (!constructorNode->isArray())
-    {
-        return constructorNode->fold(mDiagnostics);
-    }
-    return constructorNode;
+    return constructorNode->fold(mDiagnostics);
 }
 
 //
 // Interface/uniform blocks
-// TODO(jiawei.shao@intel.com): implement GL_OES_shader_io_blocks.
+// TODO(jiawei.shao@intel.com): implement GL_EXT_shader_io_blocks.
 //
 TIntermDeclaration *TParseContext::addInterfaceBlock(
     const TTypeQualifierBuilder &typeQualifierBuilder,
     const TSourceLoc &nameLine,
     const TString &blockName,
     TFieldList *fieldList,
     const TString *instanceName,
     const TSourceLoc &instanceLine,
@@ -3503,16 +3665,18 @@ TIntermDeclaration *TParseContext::addIn
         checkBlockBindingIsValid(typeQualifier.line, typeQualifier.qualifier,
                                  typeQualifier.layoutQualifier.binding, arraySize);
     }
 
     checkYuvIsNotSpecified(typeQualifier.line, typeQualifier.layoutQualifier.yuv);
 
     TLayoutQualifier blockLayoutQualifier = typeQualifier.layoutQualifier;
     checkLocationIsNotSpecified(typeQualifier.line, blockLayoutQualifier);
+    checkStd430IsForShaderStorageBlock(typeQualifier.line, blockLayoutQualifier.blockStorage,
+                                       typeQualifier.qualifier);
 
     if (blockLayoutQualifier.matrixPacking == EmpUnspecified)
     {
         if (typeQualifier.qualifier == EvqUniform)
         {
             blockLayoutQualifier.matrixPacking = mDefaultUniformMatrixPacking;
         }
         else if (typeQualifier.qualifier == EvqBuffer)
@@ -3532,21 +3696,16 @@ TIntermDeclaration *TParseContext::addIn
             blockLayoutQualifier.blockStorage = mDefaultBufferBlockStorage;
         }
     }
 
     checkWorkGroupSizeIsNotSpecified(nameLine, blockLayoutQualifier);
 
     checkInternalFormatIsNotSpecified(nameLine, blockLayoutQualifier.imageInternalFormat);
 
-    if (!symbolTable.declareInterfaceBlockName(&blockName))
-    {
-        error(nameLine, "redefinition of an interface block name", blockName.c_str());
-    }
-
     // check for sampler types and apply layout qualifiers
     for (size_t memberIndex = 0; memberIndex < fieldList->size(); ++memberIndex)
     {
         TField *field    = (*fieldList)[memberIndex];
         TType *fieldType = field->type();
         if (IsOpaqueType(fieldType->getBasicType()))
         {
             std::string reason("unsupported type - ");
@@ -3604,16 +3763,25 @@ TIntermDeclaration *TParseContext::addIn
         {
             warning(field->line(),
                     "extraneous layout qualifier: only has an effect on matrix types",
                     getMatrixPackingString(fieldLayoutQualifier.matrixPacking));
         }
 
         fieldType->setLayoutQualifier(fieldLayoutQualifier);
 
+        if (mShaderVersion < 310 || memberIndex != fieldList->size() - 1u ||
+            typeQualifier.qualifier != EvqBuffer)
+        {
+            // ESSL 3.10 spec section 4.1.9 allows for runtime-sized arrays.
+            checkIsNotUnsizedArray(field->line(),
+                                   "array members of interface blocks must specify a size",
+                                   field->name().c_str(), field->type());
+        }
+
         if (typeQualifier.qualifier == EvqBuffer)
         {
             // set memory qualifiers
             // GLSL ES 3.10 session 4.9 [Memory Access Qualifiers]. When a block declaration is
             // qualified with a memory qualifier, it is as if all of its members were declared with
             // the same memory qualifier.
             const TMemoryQualifier &blockMemoryQualifier = typeQualifier.memoryQualifier;
             TMemoryQualifier fieldMemoryQualifier        = fieldType->getMemoryQualifier();
@@ -3623,71 +3791,73 @@ TIntermDeclaration *TParseContext::addIn
             fieldMemoryQualifier.restrictQualifier |= blockMemoryQualifier.restrictQualifier;
             fieldMemoryQualifier.volatileQualifier |= blockMemoryQualifier.volatileQualifier;
             // TODO(jiajia.qin@intel.com): Decide whether if readonly and writeonly buffer variable
             // is legal. See bug https://github.com/KhronosGroup/OpenGL-API/issues/7
             fieldType->setMemoryQualifier(fieldMemoryQualifier);
         }
     }
 
-    TInterfaceBlock *interfaceBlock =
-        new TInterfaceBlock(&blockName, fieldList, instanceName, blockLayoutQualifier);
+    TInterfaceBlock *interfaceBlock = new TInterfaceBlock(
+        &symbolTable, &blockName, fieldList, blockLayoutQualifier, SymbolType::UserDefined);
+    if (!symbolTable.declareInterfaceBlock(interfaceBlock))
+    {
+        error(nameLine, "redefinition of an interface block name", blockName.c_str());
+    }
+
     TType interfaceBlockType(interfaceBlock, typeQualifier.qualifier, blockLayoutQualifier);
     if (arrayIndex != nullptr)
     {
         interfaceBlockType.makeArray(arraySize);
     }
 
-    TString symbolName = "";
-    int symbolId       = 0;
-
-    if (!instanceName)
+    // The instance variable gets created to refer to the interface block type from the AST
+    // regardless of if there's an instance name. It's created as an empty symbol if there is no
+    // instance name.
+    TVariable *instanceVariable =
+        new TVariable(&symbolTable, instanceName, interfaceBlockType,
+                      instanceName ? SymbolType::UserDefined : SymbolType::Empty);
+
+    if (instanceVariable->symbolType() == SymbolType::Empty)
     {
         // define symbols for the members of the interface block
         for (size_t memberIndex = 0; memberIndex < fieldList->size(); ++memberIndex)
         {
             TField *field    = (*fieldList)[memberIndex];
             TType *fieldType = field->type();
 
             // set parent pointer of the field variable
             fieldType->setInterfaceBlock(interfaceBlock);
 
-            TVariable *fieldVariable = symbolTable.declareVariable(&field->name(), *fieldType);
-
-            if (fieldVariable)
+            TVariable *fieldVariable =
+                new TVariable(&symbolTable, &field->name(), *fieldType, SymbolType::UserDefined);
+            if (symbolTable.declareVariable(fieldVariable))
             {
                 fieldVariable->setQualifier(typeQualifier.qualifier);
             }
             else
             {
                 error(field->line(), "redefinition of an interface block member name",
                       field->name().c_str());
             }
         }
     }
     else
     {
         checkIsNotReserved(instanceLine, *instanceName);
 
         // add a symbol for this interface block
-        TVariable *instanceTypeDef = symbolTable.declareVariable(instanceName, interfaceBlockType);
-        if (instanceTypeDef)
-        {
-            instanceTypeDef->setQualifier(typeQualifier.qualifier);
-            symbolId = instanceTypeDef->getUniqueId();
-        }
-        else
+        if (!symbolTable.declareVariable(instanceVariable))
         {
             error(instanceLine, "redefinition of an interface block instance name",
                   instanceName->c_str());
         }
-        symbolName = *instanceName;
-    }
-
-    TIntermSymbol *blockSymbol = new TIntermSymbol(symbolId, symbolName, interfaceBlockType);
+    }
+
+    TIntermSymbol *blockSymbol = new TIntermSymbol(instanceVariable);
     blockSymbol->setLine(typeQualifier.line);
     TIntermDeclaration *declaration = new TIntermDeclaration();
     declaration->appendDeclarator(blockSymbol);
     declaration->setLine(nameLine);
 
     exitStructDeclaration();
     return declaration;
 }
@@ -3721,18 +3891,28 @@ void TParseContext::checkIsBelowStructNe
         return;
     }
 
     // We're already inside a structure definition at this point, so add
     // one to the field's struct nesting.
     if (1 + field.type()->getDeepestStructNesting() > kWebGLMaxStructNesting)
     {
         std::stringstream reasonStream;
-        reasonStream << "Reference of struct type " << field.type()->getStruct()->name().c_str()
-                     << " exceeds maximum allowed nesting level of " << kWebGLMaxStructNesting;
+        if (field.type()->getStruct()->symbolType() == SymbolType::Empty)
+        {
+            // This may happen in case there are nested struct definitions. While they are also
+            // invalid GLSL, they don't cause a syntax error.
+            reasonStream << "Struct nesting";
+        }
+        else
+        {
+            reasonStream << "Reference of struct type "
+                         << field.type()->getStruct()->name().c_str();
+        }
+        reasonStream << " exceeds maximum allowed nesting level of " << kWebGLMaxStructNesting;
         std::string reason = reasonStream.str();
         error(line, reason.c_str(), field.name().c_str());
         return;
     }
 }
 
 //
 // Parse an array index expression
@@ -3741,29 +3921,29 @@ TIntermTyped *TParseContext::addIndexExp
                                                 const TSourceLoc &location,
                                                 TIntermTyped *indexExpression)
 {
     if (!baseExpression->isArray() && !baseExpression->isMatrix() && !baseExpression->isVector())
     {
         if (baseExpression->getAsSymbolNode())
         {
             error(location, " left of '[' is not of type array, matrix, or vector ",
-                  baseExpression->getAsSymbolNode()->getSymbol().c_str());
+                  baseExpression->getAsSymbolNode()->getName().c_str());
         }
         else
         {
             error(location, " left of '[' is not of type array, matrix, or vector ", "expression");
         }
 
         return CreateZeroNode(TType(EbtFloat, EbpHigh, EvqConst));
     }
 
     if (baseExpression->getQualifier() == EvqPerVertexIn)
     {
-        ASSERT(mShaderType == GL_GEOMETRY_SHADER_OES);
+        ASSERT(mShaderType == GL_GEOMETRY_SHADER_EXT);
         if (mGeometryShaderInputPrimitiveType == EptUndefined)
         {
             error(location, "missing input primitive declaration before indexing gl_in.", "[");
             return CreateZeroNode(TType(EbtFloat, EbpHigh, EvqConst));
         }
     }
 
     TIntermConstantUnion *indexConstantUnion = indexExpression->getAsConstantUnion();
@@ -3771,17 +3951,17 @@ TIntermTyped *TParseContext::addIndexExp
     // TODO(oetuaho@nvidia.com): Get rid of indexConstantUnion == nullptr below once ANGLE is able
     // to constant fold all constant expressions. Right now we don't allow indexing interface blocks
     // or fragment outputs with expressions that ANGLE is not able to constant fold, even if the
     // index is a constant expression.
     if (indexExpression->getQualifier() != EvqConst || indexConstantUnion == nullptr)
     {
         if (baseExpression->isInterfaceBlock())
         {
-            // TODO(jiawei.shao@intel.com): implement GL_OES_shader_io_blocks.
+            // TODO(jiawei.shao@intel.com): implement GL_EXT_shader_io_blocks.
             switch (baseExpression->getQualifier())
             {
                 case EvqPerVertexIn:
                     break;
                 case EvqUniform:
                 case EvqBuffer:
                     error(location,
                           "array indexes for uniform block arrays and shader storage block arrays "
@@ -3820,95 +4000,104 @@ TIntermTyped *TParseContext::addIndexExp
         }
         else if (indexConstantUnion->getBasicType() == EbtUInt)
         {
             index = static_cast<int>(indexConstantUnion->getUConst(0));
         }
 
         int safeIndex = -1;
 
-        if (baseExpression->isArray())
-        {
-            if (baseExpression->getQualifier() == EvqFragData && index > 0)
+        if (index < 0)
+        {
+            outOfRangeError(outOfRangeIndexIsError, location, "index expression is negative", "[]");
+            safeIndex = 0;
+        }
+
+        if (!baseExpression->getType().isUnsizedArray())
+        {
+            if (baseExpression->isArray())
             {
-                if (!isExtensionEnabled(TExtension::EXT_draw_buffers))
+                if (baseExpression->getQualifier() == EvqFragData && index > 0)
                 {
-                    outOfRangeError(outOfRangeIndexIsError, location,
-                                    "array index for gl_FragData must be zero when "
-                                    "GL_EXT_draw_buffers is disabled",
-                                    "[");
-                    safeIndex = 0;
+                    if (!isExtensionEnabled(TExtension::EXT_draw_buffers))
+                    {
+                        outOfRangeError(outOfRangeIndexIsError, location,
+                                        "array index for gl_FragData must be zero when "
+                                        "GL_EXT_draw_buffers is disabled",
+                                        "[]");
+                        safeIndex = 0;
+                    }
                 }
             }
             // Only do generic out-of-range check if similar error hasn't already been reported.
             if (safeIndex < 0)
             {
-                safeIndex = checkIndexOutOfRange(outOfRangeIndexIsError, location, index,
-                                                 baseExpression->getOutermostArraySize(),
-                                                 "array index out of range");
+                if (baseExpression->isArray())
+                {
+                    safeIndex = checkIndexLessThan(outOfRangeIndexIsError, location, index,
+                                                   baseExpression->getOutermostArraySize(),
+                                                   "array index out of range");
+                }
+                else if (baseExpression->isMatrix())
+                {
+                    safeIndex = checkIndexLessThan(outOfRangeIndexIsError, location, index,
+                                                   baseExpression->getType().getCols(),
+                                                   "matrix field selection out of range");
+                }
+                else
+                {
+                    ASSERT(baseExpression->isVector());
+                    safeIndex = checkIndexLessThan(outOfRangeIndexIsError, location, index,
+                                                   baseExpression->getType().getNominalSize(),
+                                                   "vector field selection out of range");
+                }
             }
-        }
-        else if (baseExpression->isMatrix())
-        {
-            safeIndex = checkIndexOutOfRange(outOfRangeIndexIsError, location, index,
-                                             baseExpression->getType().getCols(),
-                                             "matrix field selection out of range");
-        }
-        else if (baseExpression->isVector())
-        {
-            safeIndex = checkIndexOutOfRange(outOfRangeIndexIsError, location, index,
-                                             baseExpression->getType().getNominalSize(),
-                                             "vector field selection out of range");
-        }
-
-        ASSERT(safeIndex >= 0);
-        // Data of constant unions can't be changed, because it may be shared with other
-        // constant unions or even builtins, like gl_MaxDrawBuffers. Instead use a new
-        // sanitized object.
-        if (safeIndex != index || indexConstantUnion->getBasicType() != EbtInt)
-        {
-            TConstantUnion *safeConstantUnion = new TConstantUnion();
-            safeConstantUnion->setIConst(safeIndex);
-            indexConstantUnion->replaceConstantUnion(safeConstantUnion);
-            indexConstantUnion->getTypePointer()->setBasicType(EbtInt);
-        }
-
-        TIntermBinary *node = new TIntermBinary(EOpIndexDirect, baseExpression, indexExpression);
-        node->setLine(location);
-        return node->fold(mDiagnostics);
-    }
-    else
-    {
-        TIntermBinary *node = new TIntermBinary(EOpIndexIndirect, baseExpression, indexExpression);
-        node->setLine(location);
-        // Indirect indexing can never be constant folded.
-        return node;
-    }
+
+            ASSERT(safeIndex >= 0);
+            // Data of constant unions can't be changed, because it may be shared with other
+            // constant unions or even builtins, like gl_MaxDrawBuffers. Instead use a new
+            // sanitized object.
+            if (safeIndex != index || indexConstantUnion->getBasicType() != EbtInt)
+            {
+                TConstantUnion *safeConstantUnion = new TConstantUnion();
+                safeConstantUnion->setIConst(safeIndex);
+                indexConstantUnion->replaceConstantUnion(safeConstantUnion);
+                indexConstantUnion->getTypePointer()->setBasicType(EbtInt);
+            }
+
+            TIntermBinary *node =
+                new TIntermBinary(EOpIndexDirect, baseExpression, indexExpression);
+            node->setLine(location);
+            return node->fold(mDiagnostics);
+        }
+    }
+
+    TIntermBinary *node = new TIntermBinary(EOpIndexIndirect, baseExpression, indexExpression);
+    node->setLine(location);
+    // Indirect indexing can never be constant folded.
+    return node;
 }
 
-int TParseContext::checkIndexOutOfRange(bool outOfRangeIndexIsError,
-                                        const TSourceLoc &location,
-                                        int index,
-                                        int arraySize,
-                                        const char *reason)
-{
-    if (index >= arraySize || index < 0)
+int TParseContext::checkIndexLessThan(bool outOfRangeIndexIsError,
+                                      const TSourceLoc &location,
+                                      int index,
+                                      int arraySize,
+                                      const char *reason)
+{
+    // Should not reach here with an unsized / runtime-sized array.
+    ASSERT(arraySize > 0);
+    // A negative index should already have been checked.
+    ASSERT(index >= 0);
+    if (index >= arraySize)
     {
         std::stringstream reasonStream;
         reasonStream << reason << " '" << index << "'";
         std::string token = reasonStream.str();
         outOfRangeError(outOfRangeIndexIsError, location, reason, "[]");
-        if (index < 0)
-        {
-            return 0;
-        }
-        else
-        {
-            return arraySize - 1;
-        }
+        return arraySize - 1;
     }
     return index;
 }
 
 TIntermTyped *TParseContext::addFieldSelectionExpression(TIntermTyped *baseExpression,
                                                          const TSourceLoc &dotLocation,
                                                          const TString &fieldString,
                                                          const TSourceLoc &fieldLocation)
@@ -3926,17 +4115,17 @@ TIntermTyped *TParseContext::addFieldSel
                                &fieldOffsets))
         {
             fieldOffsets.resize(1);
             fieldOffsets[0] = 0;
         }
         TIntermSwizzle *node = new TIntermSwizzle(baseExpression, fieldOffsets);
         node->setLine(dotLocation);
 
-        return node->fold();
+        return node->fold(mDiagnostics);
     }
     else if (baseExpression->getBasicType() == EbtStruct)
     {
         const TFieldList &fields = baseExpression->getType().getStruct()->fields();
         if (fields.empty())
         {
             error(dotLocation, "structure has no fields", "Internal Error");
             return baseExpression;
@@ -4022,17 +4211,17 @@ TIntermTyped *TParseContext::addFieldSel
         }
         return baseExpression;
     }
 }
 
 TLayoutQualifier TParseContext::parseLayoutQualifier(const TString &qualifierType,
                                                      const TSourceLoc &qualifierTypeLine)
 {
-    TLayoutQualifier qualifier = TLayoutQualifier::create();
+    TLayoutQualifier qualifier = TLayoutQualifier::Create();
 
     if (qualifierType == "shared")
     {
         if (sh::IsWebGLBasedSpec(mShaderSpec))
         {
             error(qualifierTypeLine, "Only std140 layout is allowed in WebGL", "shared");
         }
         qualifier.blockStorage = EbsShared;
@@ -4040,16 +4229,21 @@ TLayoutQualifier TParseContext::parseLay
     else if (qualifierType == "packed")
     {
         if (sh::IsWebGLBasedSpec(mShaderSpec))
         {
             error(qualifierTypeLine, "Only std140 layout is allowed in WebGL", "packed");
         }
         qualifier.blockStorage = EbsPacked;
     }
+    else if (qualifierType == "std430")
+    {
+        checkLayoutQualifierSupported(qualifierTypeLine, qualifierType, 310);
+        qualifier.blockStorage = EbsStd430;
+    }
     else if (qualifierType == "std140")
     {
         qualifier.blockStorage = EbsStd140;
     }
     else if (qualifierType == "row_major")
     {
         qualifier.matrixPacking = EmpRowMajor;
     }
@@ -4057,20 +4251,22 @@ TLayoutQualifier TParseContext::parseLay
     {
         qualifier.matrixPacking = EmpColumnMajor;
     }
     else if (qualifierType == "location")
     {
         error(qualifierTypeLine, "invalid layout qualifier: location requires an argument",
               qualifierType.c_str());
     }
-    else if (qualifierType == "yuv" && isExtensionEnabled(TExtension::EXT_YUV_target) &&
-             mShaderType == GL_FRAGMENT_SHADER)
-    {
-        qualifier.yuv = true;
+    else if (qualifierType == "yuv" && mShaderType == GL_FRAGMENT_SHADER)
+    {
+        if (checkCanUseExtension(qualifierTypeLine, TExtension::EXT_YUV_target))
+        {
+            qualifier.yuv = true;
+        }
     }
     else if (qualifierType == "rgba32f")
     {
         checkLayoutQualifierSupported(qualifierTypeLine, qualifierType, 310);
         qualifier.imageInternalFormat = EiifRGBA32F;
     }
     else if (qualifierType == "rgba16f")
     {
@@ -4127,57 +4323,54 @@ TLayoutQualifier TParseContext::parseLay
         checkLayoutQualifierSupported(qualifierTypeLine, qualifierType, 310);
         qualifier.imageInternalFormat = EiifRGBA8UI;
     }
     else if (qualifierType == "r32ui")
     {
         checkLayoutQualifierSupported(qualifierTypeLine, qualifierType, 310);
         qualifier.imageInternalFormat = EiifR32UI;
     }
-    else if (qualifierType == "points" && isExtensionEnabled(TExtension::OES_geometry_shader) &&
-             mShaderType == GL_GEOMETRY_SHADER_OES)
+    else if (qualifierType == "points" && mShaderType == GL_GEOMETRY_SHADER_EXT &&
+             checkCanUseExtension(qualifierTypeLine, TExtension::EXT_geometry_shader))
     {
         checkLayoutQualifierSupported(qualifierTypeLine, qualifierType, 310);
         qualifier.primitiveType = EptPoints;
     }
-    else if (qualifierType == "lines" && isExtensionEnabled(TExtension::OES_geometry_shader) &&
-             mShaderType == GL_GEOMETRY_SHADER_OES)
+    else if (qualifierType == "lines" && mShaderType == GL_GEOMETRY_SHADER_EXT &&
+             checkCanUseExtension(qualifierTypeLine, TExtension::EXT_geometry_shader))
     {
         checkLayoutQualifierSupported(qualifierTypeLine, qualifierType, 310);
         qualifier.primitiveType = EptLines;
     }
-    else if (qualifierType == "lines_adjacency" &&
-             isExtensionEnabled(TExtension::OES_geometry_shader) &&
-             mShaderType == GL_GEOMETRY_SHADER_OES)
+    else if (qualifierType == "lines_adjacency" && mShaderType == GL_GEOMETRY_SHADER_EXT &&
+             checkCanUseExtension(qualifierTypeLine, TExtension::EXT_geometry_shader))
     {
         checkLayoutQualifierSupported(qualifierTypeLine, qualifierType, 310);
         qualifier.primitiveType = EptLinesAdjacency;
     }
-    else if (qualifierType == "triangles" && isExtensionEnabled(TExtension::OES_geometry_shader) &&
-             mShaderType == GL_GEOMETRY_SHADER_OES)
+    else if (qualifierType == "triangles" && mShaderType == GL_GEOMETRY_SHADER_EXT &&
+             checkCanUseExtension(qualifierTypeLine, TExtension::EXT_geometry_shader))
     {
         checkLayoutQualifierSupported(qualifierTypeLine, qualifierType, 310);
         qualifier.primitiveType = EptTriangles;
     }
-    else if (qualifierType == "triangles_adjacency" &&
-             isExtensionEnabled(TExtension::OES_geometry_shader) &&
-             mShaderType == GL_GEOMETRY_SHADER_OES)
+    else if (qualifierType == "triangles_adjacency" && mShaderType == GL_GEOMETRY_SHADER_EXT &&
+             checkCanUseExtension(qualifierTypeLine, TExtension::EXT_geometry_shader))
     {
         checkLayoutQualifierSupported(qualifierTypeLine, qualifierType, 310);
         qualifier.primitiveType = EptTrianglesAdjacency;
     }
-    else if (qualifierType == "line_strip" && isExtensionEnabled(TExtension::OES_geometry_shader) &&
-             mShaderType == GL_GEOMETRY_SHADER_OES)
+    else if (qualifierType == "line_strip" && mShaderType == GL_GEOMETRY_SHADER_EXT &&
+             checkCanUseExtension(qualifierTypeLine, TExtension::EXT_geometry_shader))
     {
         checkLayoutQualifierSupported(qualifierTypeLine, qualifierType, 310);
         qualifier.primitiveType = EptLineStrip;
     }
-    else if (qualifierType == "triangle_strip" &&
-             isExtensionEnabled(TExtension::OES_geometry_shader) &&
-             mShaderType == GL_GEOMETRY_SHADER_OES)
+    else if (qualifierType == "triangle_strip" && mShaderType == GL_GEOMETRY_SHADER_EXT &&
+             checkCanUseExtension(qualifierTypeLine, TExtension::EXT_geometry_shader))
     {
         checkLayoutQualifierSupported(qualifierTypeLine, qualifierType, 310);
         qualifier.primitiveType = EptTriangleStrip;
     }
 
     else
     {
         error(qualifierTypeLine, "invalid layout qualifier", qualifierType.c_str());
@@ -4259,17 +4452,17 @@ void TParseContext::parseMaxVertices(int
     }
 }
 
 TLayoutQualifier TParseContext::parseLayoutQualifier(const TString &qualifierType,
                                                      const TSourceLoc &qualifierTypeLine,
                                                      int intValue,
                                                      const TSourceLoc &intValueLine)
 {
-    TLayoutQualifier qualifier = TLayoutQualifier::create();
+    TLayoutQualifier qualifier = TLayoutQualifier::Create();
 
     std::string intValueString = Str(intValue);
 
     if (qualifierType == "location")
     {
         // must check that location is non-negative
         if (intValue < 0)
         {
@@ -4318,30 +4511,30 @@ TLayoutQualifier TParseContext::parseLay
         parseLocalSize(qualifierType, qualifierTypeLine, intValue, intValueLine, intValueString, 1u,
                        &qualifier.localSize);
     }
     else if (qualifierType == "local_size_z")
     {
         parseLocalSize(qualifierType, qualifierTypeLine, intValue, intValueLine, intValueString, 2u,
                        &qualifier.localSize);
     }
-    else if (qualifierType == "num_views" && isExtensionEnabled(TExtension::OVR_multiview) &&
-             mShaderType == GL_VERTEX_SHADER)
-    {
-        parseNumViews(intValue, intValueLine, intValueString, &qualifier.numViews);
-    }
-    else if (qualifierType == "invocations" &&
-             isExtensionEnabled(TExtension::OES_geometry_shader) &&
-             mShaderType == GL_GEOMETRY_SHADER_OES)
+    else if (qualifierType == "num_views" && mShaderType == GL_VERTEX_SHADER)
+    {
+        if (checkCanUseExtension(qualifierTypeLine, TExtension::OVR_multiview))
+        {
+            parseNumViews(intValue, intValueLine, intValueString, &qualifier.numViews);
+        }
+    }
+    else if (qualifierType == "invocations" && mShaderType == GL_GEOMETRY_SHADER_EXT &&
+             checkCanUseExtension(qualifierTypeLine, TExtension::EXT_geometry_shader))
     {
         parseInvocations(intValue, intValueLine, intValueString, &qualifier.invocations);
     }
-    else if (qualifierType == "max_vertices" &&
-             isExtensionEnabled(TExtension::OES_geometry_shader) &&
-             mShaderType == GL_GEOMETRY_SHADER_OES)
+    else if (qualifierType == "max_vertices" && mShaderType == GL_GEOMETRY_SHADER_EXT &&
+             checkCanUseExtension(qualifierTypeLine, TExtension::EXT_geometry_shader))
     {
         parseMaxVertices(intValue, intValueLine, intValueString, &qualifier.maxVertices);
     }
 
     else
     {
         error(qualifierTypeLine, "invalid layout qualifier", qualifierType.c_str());
     }
@@ -4396,17 +4589,17 @@ TStorageQualifierWrapper *TParseContext:
                 error(loc, "storage qualifier supported in GLSL ES 3.00 and above only", "in");
             }
             return new TStorageQualifierWrapper(EvqFragmentIn, loc);
         }
         case GL_COMPUTE_SHADER:
         {
             return new TStorageQualifierWrapper(EvqComputeIn, loc);
         }
-        case GL_GEOMETRY_SHADER_OES:
+        case GL_GEOMETRY_SHADER_EXT:
         {
             return new TStorageQualifierWrapper(EvqGeometryIn, loc);
         }
         default:
         {
             UNREACHABLE();
             return new TStorageQualifierWrapper(EvqLast, loc);
         }
@@ -4437,17 +4630,17 @@ TStorageQualifierWrapper *TParseContext:
             }
             return new TStorageQualifierWrapper(EvqFragmentOut, loc);
         }
         case GL_COMPUTE_SHADER:
         {
             error(loc, "storage qualifier isn't supported in compute shaders", "out");
             return new TStorageQualifierWrapper(EvqLast, loc);
         }
-        case GL_GEOMETRY_SHADER_OES:
+        case GL_GEOMETRY_SHADER_EXT:
         {
             return new TStorageQualifierWrapper(EvqGeometryOut, loc);
         }
         default:
         {
             UNREACHABLE();
             return new TStorageQualifierWrapper(EvqLast, loc);
         }
@@ -4466,130 +4659,146 @@ TStorageQualifierWrapper *TParseContext:
 TLayoutQualifier TParseContext::joinLayoutQualifiers(TLayoutQualifier leftQualifier,
                                                      TLayoutQualifier rightQualifier,
                                                      const TSourceLoc &rightQualifierLocation)
 {
     return sh::JoinLayoutQualifiers(leftQualifier, rightQualifier, rightQualifierLocation,
                                     mDiagnostics);
 }
 
-TField *TParseContext::parseStructDeclarator(TString *identifier, const TSourceLoc &loc)
+TDeclarator *TParseContext::parseStructDeclarator(const TString *identifier, const TSourceLoc &loc)
+{
+    checkIsNotReserved(loc, *identifier);
+    return new TDeclarator(identifier, loc);
+}
+
+TDeclarator *TParseContext::parseStructArrayDeclarator(const TString *identifier,
+                                                       const TSourceLoc &loc,
+                                                       const TVector<unsigned int> *arraySizes)
 {
     checkIsNotReserved(loc, *identifier);
-    TType *type = new TType(EbtVoid, EbpUndefined);
-    return new TField(type, identifier, loc);
+    return new TDeclarator(identifier, arraySizes, loc);
 }
 
-TField *TParseContext::parseStructArrayDeclarator(TString *identifier,
-                                                  const TSourceLoc &loc,
-                                                  TIntermTyped *arraySize,
-                                                  const TSourceLoc &arraySizeLoc)
-{
-    checkIsNotReserved(loc, *identifier);
-
-    TType *type       = new TType(EbtVoid, EbpUndefined);
-    unsigned int size = checkIsValidArraySize(arraySizeLoc, arraySize);
-    type->makeArray(size);
-
-    return new TField(type, identifier, loc);
+void TParseContext::checkDoesNotHaveDuplicateFieldName(const TFieldList::const_iterator begin,
+                                                       const TFieldList::const_iterator end,
+                                                       const TString &name,
+                                                       const TSourceLoc &location)
+{
+    for (auto fieldIter = begin; fieldIter != end; ++fieldIter)
+    {
+        if ((*fieldIter)->name() == name)
+        {
+            error(location, "duplicate field name in structure", name.c_str());
+        }
+    }
+}
+
+TFieldList *TParseContext::addStructFieldList(TFieldList *fields, const TSourceLoc &location)
+{
+    for (TFieldList::const_iterator fieldIter = fields->begin(); fieldIter != fields->end();
+         ++fieldIter)
+    {
+        checkDoesNotHaveDuplicateFieldName(fields->begin(), fieldIter, (*fieldIter)->name(),
+                                           location);
+    }
+    return fields;
 }
 
 TFieldList *TParseContext::combineStructFieldLists(TFieldList *processedFields,
                                                    const TFieldList *newlyAddedFields,
                                                    const TSourceLoc &location)
 {
     for (TField *field : *newlyAddedFields)
     {
-        for (TField *oldField : *processedFields)
-        {
-            if (oldField->name() == field->name())
-            {
-                error(location, "duplicate field name in structure", field->name().c_str());
-            }
-        }
+        checkDoesNotHaveDuplicateFieldName(processedFields->begin(), processedFields->end(),
+                                           field->name(), location);
         processedFields->push_back(field);
     }
     return processedFields;
 }
 
 TFieldList *TParseContext::addStructDeclaratorListWithQualifiers(
     const TTypeQualifierBuilder &typeQualifierBuilder,
     TPublicType *typeSpecifier,
-    TFieldList *fieldList)
+    const TDeclaratorList *declaratorList)
 {
     TTypeQualifier typeQualifier = typeQualifierBuilder.getVariableTypeQualifier(mDiagnostics);
 
     typeSpecifier->qualifier       = typeQualifier.qualifier;
     typeSpecifier->layoutQualifier = typeQualifier.layoutQualifier;
     typeSpecifier->memoryQualifier = typeQualifier.memoryQualifier;
     typeSpecifier->invariant       = typeQualifier.invariant;
     if (typeQualifier.precision != EbpUndefined)
     {
         typeSpecifier->precision = typeQualifier.precision;
     }
-    return addStructDeclaratorList(*typeSpecifier, fieldList);
+    return addStructDeclaratorList(*typeSpecifier, declaratorList);
 }
 
 TFieldList *TParseContext::addStructDeclaratorList(const TPublicType &typeSpecifier,
-                                                   TFieldList *declaratorList)
+                                                   const TDeclaratorList *declaratorList)
 {
     checkPrecisionSpecified(typeSpecifier.getLine(), typeSpecifier.precision,
                             typeSpecifier.getBasicType());
 
-    checkIsNonVoid(typeSpecifier.getLine(), (*declaratorList)[0]->name(),
+    checkIsNonVoid(typeSpecifier.getLine(), *(*declaratorList)[0]->name(),
                    typeSpecifier.getBasicType());
 
     checkWorkGroupSizeIsNotSpecified(typeSpecifier.getLine(), typeSpecifier.layoutQualifier);
 
-    for (unsigned int i = 0; i < declaratorList->size(); ++i)
-    {
-        auto declaratorArraySizes = (*declaratorList)[i]->type()->getArraySizes();
-        // don't allow arrays of arrays
-        if (!declaratorArraySizes.empty())
-        {
+    TFieldList *fieldList = new TFieldList();
+
+    for (const TDeclarator *declarator : *declaratorList)
+    {
+        TType *type = new TType(typeSpecifier);
+        if (declarator->isArray())
+        {
+            // Don't allow arrays of arrays in ESSL < 3.10.
             checkArrayElementIsNotArray(typeSpecifier.getLine(), typeSpecifier);
-        }
-
-        TType *type = (*declaratorList)[i]->type();
-        *type       = TType(typeSpecifier);
-        for (unsigned int arraySize : declaratorArraySizes)
-        {
-            type->makeArray(arraySize);
-        }
-
-        checkIsBelowStructNestingLimit(typeSpecifier.getLine(), *(*declaratorList)[i]);
-    }
-
-    return declaratorList;
+            type->makeArrays(*declarator->arraySizes());
+        }
+
+        TField *field = new TField(type, declarator->name(), declarator->line());
+        checkIsBelowStructNestingLimit(typeSpecifier.getLine(), *field);
+        fieldList->push_back(field);
+    }
+
+    return fieldList;
 }
 
 TTypeSpecifierNonArray TParseContext::addStructure(const TSourceLoc &structLine,
                                                    const TSourceLoc &nameLine,
                                                    const TString *structName,
                                                    TFieldList *fieldList)
 {
-    TStructure *structure = new TStructure(&symbolTable, structName, fieldList);
+    SymbolType structSymbolType = SymbolType::UserDefined;
+    if (structName == nullptr)
+    {
+        structSymbolType = SymbolType::Empty;
+    }
+    TStructure *structure = new TStructure(&symbolTable, structName, fieldList, structSymbolType);
 
     // Store a bool in the struct if we're at global scope, to allow us to
     // skip the local struct scoping workaround in HLSL.
     structure->setAtGlobalScope(symbolTable.atGlobalLevel());
 
-    if (!structName->empty())
+    if (structSymbolType != SymbolType::Empty)
     {
         checkIsNotReserved(nameLine, *structName);
         if (!symbolTable.declareStructType(structure))
         {
             error(nameLine, "redefinition of a struct", structName->c_str());
         }
     }
 
     // ensure we do not specify any storage qualifiers on the struct members
     for (unsigned int typeListIndex = 0; typeListIndex < fieldList->size(); typeListIndex++)
     {
-        const TField &field        = *(*fieldList)[typeListIndex];
+        TField &field              = *(*fieldList)[typeListIndex];
         const TQualifier qualifier = field.type()->getQualifier();
         switch (qualifier)
         {
             case EvqGlobal:
             case EvqTemporary:
                 break;
             default:
                 error(field.line(), "invalid qualifier on struct member",
@@ -4601,16 +4810,19 @@ TTypeSpecifierNonArray TParseContext::ad
             error(field.line(), "invalid qualifier on struct member", "invariant");
         }
         // ESSL 3.10 section 4.1.8 -- atomic_uint or images are not allowed as structure member.
         if (IsImage(field.type()->getBasicType()) || IsAtomicCounter(field.type()->getBasicType()))
         {
             error(field.line(), "disallowed type in struct", field.type()->getBasicString());
         }
 
+        checkIsNotUnsizedArray(field.line(), "array members of structs must specify a size",
+                               field.name().c_str(), field.type());
+
         checkMemoryQualifierIsNotSpecified(field.type()->getMemoryQualifier(), field.line());
 
         checkBindingIsNotSpecified(field.line(), field.type()->getLayoutQualifier().binding);
 
         checkLocationIsNotSpecified(field.line(), field.type()->getLayoutQualifier());
     }
 
     TTypeSpecifierNonArray typeSpecifierNonArray;
@@ -4628,22 +4840,21 @@ TIntermSwitch *TParseContext::addSwitch(
     if ((switchType != EbtInt && switchType != EbtUInt) || init->isMatrix() || init->isArray() ||
         init->isVector())
     {
         error(init->getLine(), "init-expression in a switch statement must be a scalar integer",
               "switch");
         return nullptr;
     }
 
-    if (statementList)
-    {
-        if (!ValidateSwitchStatementList(switchType, mDiagnostics, statementList, loc))
-        {
-            return nullptr;
-        }
+    ASSERT(statementList);
+    if (!ValidateSwitchStatementList(switchType, mShaderVersion, mDiagnostics, statementList, loc))
+    {
+        ASSERT(mDiagnostics->numErrors() > 0);
+        return nullptr;
     }
 
     TIntermSwitch *node = new TIntermSwitch(init, statementList);
     node->setLine(loc);
     return node;
 }
 
 TIntermCase *TParseContext::addCase(TIntermTyped *condition, const TSourceLoc &loc)
@@ -4756,16 +4967,40 @@ TIntermTyped *TParseContext::addUnaryMat
 TIntermTyped *TParseContext::addUnaryMathLValue(TOperator op,
                                                 TIntermTyped *child,
                                                 const TSourceLoc &loc)
 {
     checkCanBeLValue(loc, GetOperatorString(op), child);
     return addUnaryMath(op, child, loc);
 }
 
+TIntermTyped *TParseContext::expressionOrFoldedResult(TIntermTyped *expression)
+{
+    // If we can, we should return the folded version of the expression for subsequent parsing. This
+    // enables folding the containing expression during parsing as well, instead of the separate
+    // FoldExpressions() step where folding nested expressions requires multiple full AST
+    // traversals.
+
+    // Even if folding fails the fold() functions return some node representing the expression,
+    // typically the original node. So "folded" can be assumed to be non-null.
+    TIntermTyped *folded = expression->fold(mDiagnostics);
+    ASSERT(folded != nullptr);
+    if (folded->getQualifier() == expression->getQualifier())
+    {
+        // We need this expression to have the correct qualifier when validating the consuming
+        // expression. So we can only return the folded node from here in case it has the same
+        // qualifier as the original expression. In this kind of a cases the qualifier of the folded
+        // node is EvqConst, whereas the qualifier of the expression is EvqTemporary:
+        //  1. (true ? 1.0 : non_constant)
+        //  2. (non_constant, 1.0)
+        return folded;
+    }
+    return expression;
+}
+
 bool TParseContext::binaryOpCommonCheck(TOperator op,
                                         TIntermTyped *left,
                                         TIntermTyped *right,
                                         const TSourceLoc &loc)
 {
     // Check opaque types are not allowed to be operands in expressions other than array indexing
     // and structure member selection.
     if (IsOpaqueType(left->getBasicType()) || IsOpaqueType(right->getBasicType()))
@@ -4838,43 +5073,44 @@ bool TParseContext::binaryOpCommonCheck(
                 ASSERT(left->getType().getInterfaceBlock());
                 break;
             default:
                 error(loc, "Invalid operation for interface blocks", GetOperatorString(op));
                 return false;
         }
     }
 
-    if (left->isArray() || right->isArray())
-    {
+    if (left->isArray() != right->isArray())
+    {
+        error(loc, "array / non-array mismatch", GetOperatorString(op));
+        return false;
+    }
+
+    if (left->isArray())
+    {
+        ASSERT(right->isArray());
         if (mShaderVersion < 300)
         {
             error(loc, "Invalid operation for arrays", GetOperatorString(op));
             return false;
         }
 
-        if (left->isArray() != right->isArray())
-        {
-            error(loc, "array / non-array mismatch", GetOperatorString(op));
-            return false;
-        }
-
         switch (op)
         {
             case EOpEqual:
             case EOpNotEqual:
             case EOpAssign:
             case EOpInitialize:
                 break;
             default:
                 error(loc, "Invalid operation for arrays", GetOperatorString(op));
                 return false;
         }
         // At this point, size of implicitly sized arrays should be resolved.
-        if (left->getType().getArraySizes() != right->getType().getArraySizes())
+        if (*left->getType().getArraySizes() != *right->getType().getArraySizes())
         {
             error(loc, "array size mismatch", GetOperatorString(op));
             return false;
         }
     }
 
     // Check ops which require integer / ivec parameters
     bool isBitShift = false;
@@ -5204,17 +5440,18 @@ TIntermTyped *TParseContext::addComma(TI
         error(loc,
               "sequence operator is not allowed for void, arrays, or structs containing arrays",
               ",");
     }
 
     TIntermBinary *commaNode   = new TIntermBinary(EOpComma, left, right);
     TQualifier resultQualifier = TIntermBinary::GetCommaQualifier(mShaderVersion, left, right);
     commaNode->getTypePointer()->setQualifier(resultQualifier);
-    return commaNode->fold(mDiagnostics);
+
+    return expressionOrFoldedResult(commaNode);
 }
 
 TIntermBranch *TParseContext::addBranch(TOperator op, const TSourceLoc &loc)
 {
     switch (op)
     {
         case EOpContinue:
             if (mLoopNestingLevel <= 0)
@@ -5267,17 +5504,17 @@ TIntermBranch *TParseContext::addBranch(
     TIntermBranch *node = new TIntermBranch(op, expression);
     node->setLine(loc);
     return node;
 }
 
 void TParseContext::checkTextureGather(TIntermAggregate *functionCall)
 {
     ASSERT(functionCall->getOp() == EOpCallBuiltInFunction);
-    const TString &name        = functionCall->getFunctionSymbolInfo()->getName();
+    const TString &name        = functionCall->getFunction()->name();
     bool isTextureGather       = (name == "textureGather");
     bool isTextureGatherOffset = (name == "textureGatherOffset");
     if (isTextureGather || isTextureGatherOffset)
     {
         TIntermNode *componentNode = nullptr;
         TIntermSequence *arguments = functionCall->getSequence();
         ASSERT(arguments->size() >= 2u && arguments->size() <= 4u);
         const TIntermTyped *sampler = arguments->front()->getAsTyped();
@@ -5333,17 +5570,17 @@ void TParseContext::checkTextureGather(T
             }
         }
     }
 }
 
 void TParseContext::checkTextureOffsetConst(TIntermAggregate *functionCall)
 {
     ASSERT(functionCall->getOp() == EOpCallBuiltInFunction);
-    const TString &name        = functionCall->getFunctionSymbolInfo()->getName();
+    const TString &name                    = functionCall->getFunction()->name();
     TIntermNode *offset        = nullptr;
     TIntermSequence *arguments = functionCall->getSequence();
     bool useTextureGatherOffsetConstraints = false;
     if (name == "texelFetchOffset" || name == "textureLodOffset" ||
         name == "textureProjLodOffset" || name == "textureGradOffset" ||
         name == "textureProjGradOffset")
     {
         offset = arguments->back();
@@ -5407,21 +5644,51 @@ void TParseContext::checkTextureOffsetCo
                     error(offset->getLine(), "Texture offset value out of valid range",
                           token.c_str());
                 }
             }
         }
     }
 }
 
+void TParseContext::checkAtomicMemoryBuiltinFunctions(TIntermAggregate *functionCall)
+{
+    ASSERT(functionCall->getOp() == EOpCallBuiltInFunction);
+    const TString &functionName = functionCall->getFunction()->name();
+    if (IsAtomicBuiltin(functionName))
+    {
+        TIntermSequence *arguments = functionCall->getSequence();
+        TIntermTyped *memNode      = (*arguments)[0]->getAsTyped();
+
+        if (IsBufferOrSharedVariable(memNode))
+        {
+            return;
+        }
+
+        while (memNode->getAsBinaryNode())
+        {
+            memNode = memNode->getAsBinaryNode()->getLeft();
+            if (IsBufferOrSharedVariable(memNode))
+            {
+                return;
+            }
+        }
+
+        error(memNode->getLine(),
+              "The value passed to the mem argument of an atomic memory function does not "
+              "correspond to a buffer or shared variable.",
+              functionName.c_str());
+    }
+}
+
 // GLSL ES 3.10 Revision 4, 4.9 Memory Access Qualifiers
 void TParseContext::checkImageMemoryAccessForBuiltinFunctions(TIntermAggregate *functionCall)
 {
     ASSERT(functionCall->getOp() == EOpCallBuiltInFunction);
-    const TString &name = functionCall->getFunctionSymbolInfo()->getName();
+    const TString &name = functionCall->getFunction()->name();
 
     if (name.compare(0, 5, "image") == 0)
     {
         TIntermSequence *arguments = functionCall->getSequence();
         TIntermTyped *imageNode    = (*arguments)[0]->getAsTyped();
 
         const TMemoryQualifier &memoryQualifier = imageNode->getMemoryQualifier();
 
@@ -5512,97 +5779,98 @@ TIntermSequence *TParseContext::createEm
 
 TIntermTyped *TParseContext::addFunctionCallOrMethod(TFunction *fnCall,
                                                      TIntermSequence *arguments,
                                                      TIntermNode *thisNode,
                                                      const TSourceLoc &loc)
 {
     if (thisNode != nullptr)
     {
-        return addMethod(fnCall, arguments, thisNode, loc);
+        return addMethod(fnCall->name(), arguments, thisNode, loc);
     }
 
     TOperator op = fnCall->getBuiltInOp();
     if (op == EOpConstruct)
     {
         return addConstructor(arguments, fnCall->getReturnType(), loc);
     }
     else
     {
         ASSERT(op == EOpNull);
-        return addNonConstructorFunctionCall(fnCall, arguments, loc);
+        return addNonConstructorFunctionCall(fnCall->name(), arguments, loc);
     }
 }
 
-TIntermTyped *TParseContext::addMethod(TFunction *fnCall,
+TIntermTyped *TParseContext::addMethod(const TString &name,
                                        TIntermSequence *arguments,
                                        TIntermNode *thisNode,
                                        const TSourceLoc &loc)
 {
     TIntermTyped *typedThis    = thisNode->getAsTyped();
     // It's possible for the name pointer in the TFunction to be null in case it gets parsed as
     // a constructor. But such a TFunction can't reach here, since the lexer goes into FIELDS
     // mode after a dot, which makes type identifiers to be parsed as FIELD_SELECTION instead.
-    // So accessing fnCall->getName() below is safe.
-    if (fnCall->getName() != "length")
-    {
-        error(loc, "invalid method", fnCall->getName().c_str());
+    // So accessing fnCall->name() below is safe.
+    if (name != "length")
+    {
+        error(loc, "invalid method", name.c_str());
     }
     else if (!arguments->empty())
     {
         error(loc, "method takes no parameters", "length");
     }
     else if (typedThis == nullptr || !typedThis->isArray())
     {
         error(loc, "length can only be called on arrays", "length");
     }
     else if (typedThis->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, typedThis);
         node->setLine(loc);
         return node->fold(mDiagnostics);
     }
     return CreateZeroNode(TType(EbtInt, EbpUndefined, EvqConst));
 }
 
-TIntermTyped *TParseContext::addNonConstructorFunctionCall(TFunction *fnCall,
+TIntermTyped *TParseContext::addNonConstructorFunctionCall(const TString &name,
                                                            TIntermSequence *arguments,
                                                            const TSourceLoc &loc)
 {
     // First find by unmangled name to check whether the function name has been
     // hidden by a variable name or struct typename.
     // If a function is found, check for one with a matching argument list.
     bool builtIn;
-    const TSymbol *symbol = symbolTable.find(fnCall->getName(), mShaderVersion, &builtIn);
+    const TSymbol *symbol = symbolTable.find(name, mShaderVersion, &builtIn);
     if (symbol != nullptr && !symbol->isFunction())
     {
-        error(loc, "function name expected", fnCall->getName().c_str());
+        error(loc, "function name expected", name.c_str());
     }
     else
     {
-        symbol = symbolTable.find(TFunction::GetMangledNameFromCall(fnCall->getName(), *arguments),
+        symbol = symbolTable.find(TFunction::GetMangledNameFromCall(name, *arguments),
                                   mShaderVersion, &builtIn);
         if (symbol == nullptr)
         {
-            error(loc, "no matching overloaded function found", fnCall->getName().c_str());
+            error(loc, "no matching overloaded function found", name.c_str());
         }
         else
         {
             const TFunction *fnCandidate = static_cast<const TFunction *>(symbol);
             //
             // A declared function.
             //
-            if (builtIn && fnCandidate->getExtension() != TExtension::UNDEFINED)
+            if (builtIn && fnCandidate->extension() != TExtension::UNDEFINED)
             {
-                checkCanUseExtension(loc, fnCandidate->getExtension());
+                checkCanUseExtension(loc, fnCandidate->extension());
             }
             TOperator op = fnCandidate->getBuiltInOp();
             if (builtIn && op != EOpNull)
             {
                 // A function call mapped to a built-in operation.
                 if (fnCandidate->getParamCount() == 1)
                 {
                     // Treat it like a built-in unary operator.
@@ -5615,26 +5883,19 @@ TIntermTyped *TParseContext::addNonConst
                 {
                     TIntermAggregate *callNode =
                         TIntermAggregate::Create(fnCandidate->getReturnType(), op, arguments);
                     callNode->setLine(loc);
 
                     // Some built-in functions have out parameters too.
                     functionCallRValueLValueErrorCheck(fnCandidate, callNode);
 
-                    if (TIntermAggregate::CanFoldAggregateBuiltInOp(callNode->getOp()))
-                    {
-                        // See if we can constant fold a built-in. Note that this may be possible
-                        // even if it is not const-qualified.
-                        return callNode->fold(mDiagnostics);
-                    }
-                    else
-                    {
-                        return callNode;
-                    }
+                    // See if we can constant fold a built-in. Note that this may be possible
+                    // even if it is not const-qualified.
+                    return callNode->fold(mDiagnostics);
                 }
             }
             else
             {
                 // This is a real function call
                 TIntermAggregate *callNode = nullptr;
 
                 // If builtIn == false, the function is user defined - could be an overloaded
@@ -5642,16 +5903,17 @@ TIntermTyped *TParseContext::addNonConst
                 // if builtIn == true, it's a builtIn function with no op associated with it.
                 // This needs to happen after the function info including name is set.
                 if (builtIn)
                 {
                     callNode = TIntermAggregate::CreateBuiltInFunctionCall(*fnCandidate, arguments);
                     checkTextureOffsetConst(callNode);
                     checkTextureGather(callNode);
                     checkImageMemoryAccessForBuiltinFunctions(callNode);
+                    checkAtomicMemoryBuiltinFunctions(callNode);
                 }
                 else
                 {
                     callNode = TIntermAggregate::CreateFunctionCall(*fnCandidate, arguments);
                     checkImageMemoryAccessForUserDefinedFunctions(fnCandidate, callNode);
                 }
 
                 functionCallRValueLValueErrorCheck(fnCandidate, callNode);
@@ -5725,22 +5987,19 @@ TIntermTyped *TParseContext::addTernaryS
     // WebGL2 section 5.26, the following results in an error:
     // "Ternary operator applied to void, arrays, or structs containing arrays"
     if (mShaderSpec == SH_WEBGL2_SPEC && trueExpression->getBasicType() == EbtVoid)
     {
         error(loc, "ternary operator is not allowed for void", "?:");
         return falseExpression;
     }
 
-    // Note that the node resulting from here can be a constant union without being qualified as
-    // constant.
     TIntermTernary *node = new TIntermTernary(cond, trueExpression, falseExpression);
     node->setLine(loc);
-
-    return node->fold();
+    return expressionOrFoldedResult(node);
 }
 
 //
 // Parse an array of strings using yyparse.
 //
 // Returns 0 for success.
 //
 int PaParseStrings(size_t count,
--- a/gfx/angle/src/compiler/translator/ParseContext.h
+++ b/gfx/angle/src/compiler/translator/ParseContext.h
@@ -1,22 +1,23 @@
 //
 // 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_PARSECONTEXT_H_
 #define COMPILER_TRANSLATOR_PARSECONTEXT_H_
 
+#include "compiler/preprocessor/Preprocessor.h"
 #include "compiler/translator/Compiler.h"
+#include "compiler/translator/Declarator.h"
 #include "compiler/translator/Diagnostics.h"
 #include "compiler/translator/DirectiveHandler.h"
+#include "compiler/translator/QualifierTypes.h"
 #include "compiler/translator/SymbolTable.h"
-#include "compiler/translator/QualifierTypes.h"
-#include "compiler/preprocessor/Preprocessor.h"
 
 namespace sh
 {
 
 struct TMatrixFields
 {
     bool wholeRow;
     bool wholeCol;
@@ -130,30 +131,42 @@ class TParseContext : angle::NonCopyable
     bool checkIsScalarBool(const TSourceLoc &line, const TIntermTyped *type);
     void checkIsScalarBool(const TSourceLoc &line, const TPublicType &pType);
     bool checkIsNotOpaqueType(const TSourceLoc &line,
                               const TTypeSpecifierNonArray &pType,
                               const char *reason);
     void checkDeclaratorLocationIsNotSpecified(const TSourceLoc &line, const TPublicType &pType);
     void checkLocationIsNotSpecified(const TSourceLoc &location,
                                      const TLayoutQualifier &layoutQualifier);
+    void checkStd430IsForShaderStorageBlock(const TSourceLoc &location,
+                                            const TLayoutBlockStorage &blockStorage,
+                                            const TQualifier &qualifier);
     void checkIsParameterQualifierValid(const TSourceLoc &line,
                                         const TTypeQualifierBuilder &typeQualifierBuilder,
                                         TType *type);
+
+    // Check if at least one of the specified extensions can be used, and generate error/warning as
+    // appropriate according to the spec.
+    // This function is only needed for a few different small constant sizes of extension array, and
+    // we want to avoid unnecessary dynamic allocations. That's why checkCanUseOneOfExtensions is a
+    // template function rather than one taking a vector.
+    template <size_t size>
+    bool checkCanUseOneOfExtensions(const TSourceLoc &line,
+                                    const std::array<TExtension, size> &extensions);
     bool checkCanUseExtension(const TSourceLoc &line, TExtension extension);
 
     // Done for all declarations, whether empty or not.
     void declarationQualifierErrorCheck(const sh::TQualifier qualifier,
                                         const sh::TLayoutQualifier &layoutQualifier,
                                         const TSourceLoc &location);
     // Done for the first non-empty declarator in a declaration.
     void nonEmptyDeclarationErrorCheck(const TPublicType &publicType,
                                        const TSourceLoc &identifierLocation);
     // Done only for empty declarations.
-    void emptyDeclarationErrorCheck(const TPublicType &publicType, const TSourceLoc &location);
+    void emptyDeclarationErrorCheck(const TType &type, const TSourceLoc &location);
 
     void checkLayoutQualifierSupported(const TSourceLoc &location,
                                        const TString &layoutQualifierName,
                                        int versionRequired);
     bool checkWorkGroupSizeIsNotSpecified(const TSourceLoc &location,
                                           const TLayoutQualifier &layoutQualifier);
     void functionCallRValueLValueErrorCheck(const TFunction *fnCandidate, TIntermAggregate *fnCall);
     void checkInvariantVariableQualifier(bool invariant,
@@ -163,29 +176,29 @@ class TParseContext : angle::NonCopyable
                                         const TPublicType &type,
                                         const TSourceLoc &qualifierLocation);
     void checkLocalVariableConstStorageQualifier(const TQualifierWrapperBase &qualifier);
     const TPragma &pragma() const { return mDirectiveHandler.pragma(); }
     const TExtensionBehavior &extensionBehavior() const
     {
         return mDirectiveHandler.extensionBehavior();
     }
-    bool supportsExtension(TExtension extension);
+
     bool isExtensionEnabled(TExtension extension) const;
     void handleExtensionDirective(const TSourceLoc &loc, const char *extName, const char *behavior);
     void handlePragmaDirective(const TSourceLoc &loc,
                                const char *name,
                                const char *value,
                                bool stdgl);
 
     // Returns true on success. *initNode may still be nullptr on success in case the initialization
     // is not needed in the AST.
     bool executeInitializer(const TSourceLoc &line,
                             const TString &identifier,
-                            const TPublicType &pType,
+                            TType type,
                             TIntermTyped *initializer,
                             TIntermBinary **initNode);
     TIntermNode *addConditionInitializer(const TPublicType &pType,
                                          const TString &identifier,
                                          TIntermTyped *initializer,
                                          const TSourceLoc &loc);
     TIntermNode *addLoop(TLoopType type,
                          TIntermNode *init,
@@ -200,70 +213,72 @@ class TParseContext : angle::NonCopyable
 
     void addFullySpecifiedType(TPublicType *typeSpecifier);
     TPublicType addFullySpecifiedType(const TTypeQualifierBuilder &typeQualifierBuilder,
                                       const TPublicType &typeSpecifier);
 
     TIntermDeclaration *parseSingleDeclaration(TPublicType &publicType,
                                                const TSourceLoc &identifierOrTypeLocation,
                                                const TString &identifier);
-    TIntermDeclaration *parseSingleArrayDeclaration(TPublicType &publicType,
+    TIntermDeclaration *parseSingleArrayDeclaration(TPublicType &elementType,
                                                     const TSourceLoc &identifierLocation,
                                                     const TString &identifier,
                                                     const TSourceLoc &indexLocation,
-                                                    TIntermTyped *indexExpression);
+                                                    const TVector<unsigned int> &arraySizes);
     TIntermDeclaration *parseSingleInitDeclaration(const TPublicType &publicType,
                                                    const TSourceLoc &identifierLocation,
                                                    const TString &identifier,
                                                    const TSourceLoc &initLocation,
                                                    TIntermTyped *initializer);
 
     // Parse a declaration like "type a[n] = initializer"
     // Note that this does not apply to declarations like "type[n] a = initializer"
-    TIntermDeclaration *parseSingleArrayInitDeclaration(TPublicType &publicType,
+    TIntermDeclaration *parseSingleArrayInitDeclaration(TPublicType &elementType,
                                                         const TSourceLoc &identifierLocation,
                                                         const TString &identifier,
                                                         const TSourceLoc &indexLocation,
-                                                        TIntermTyped *indexExpression,
+                                                        const TVector<unsigned int> &arraySizes,
                                                         const TSourceLoc &initLocation,
                                                         TIntermTyped *initializer);
 
     TIntermInvariantDeclaration *parseInvariantDeclaration(
         const TTypeQualifierBuilder &typeQualifierBuilder,
         const TSourceLoc &identifierLoc,
         const TString *identifier,
         const TSymbol *symbol);
 
     void parseDeclarator(TPublicType &publicType,
                          const TSourceLoc &identifierLocation,
                          const TString &identifier,
                          TIntermDeclaration *declarationOut);
-    void parseArrayDeclarator(TPublicType &publicType,
+    void parseArrayDeclarator(TPublicType &elementType,
                               const TSourceLoc &identifierLocation,
                               const TString &identifier,
                               const TSourceLoc &arrayLocation,
-                              TIntermTyped *indexExpression,
+                              const TVector<unsigned int> &arraySizes,
                               TIntermDeclaration *declarationOut);
     void parseInitDeclarator(const TPublicType &publicType,
                              const TSourceLoc &identifierLocation,
                              const TString &identifier,
                              const TSourceLoc &initLocation,
                              TIntermTyped *initializer,
                              TIntermDeclaration *declarationOut);
 
     // Parse a declarator like "a[n] = initializer"
-    void parseArrayInitDeclarator(const TPublicType &publicType,
+    void parseArrayInitDeclarator(const TPublicType &elementType,
                                   const TSourceLoc &identifierLocation,
                                   const TString &identifier,
                                   const TSourceLoc &indexLocation,
-                                  TIntermTyped *indexExpression,
+                                  const TVector<unsigned int> &arraySizes,
                                   const TSourceLoc &initLocation,
                                   TIntermTyped *initializer,
                                   TIntermDeclaration *declarationOut);
 
+    TIntermNode *addEmptyStatement(const TSourceLoc &location);
+
     void parseDefaultPrecisionQualifier(const TPrecision precision,
                                         const TPublicType &type,
                                         const TSourceLoc &loc);
     void parseGlobalLayoutQualifier(const TTypeQualifierBuilder &typeQualifierBuilder);
 
     TIntermFunctionPrototype *addFunctionPrototypeDeclaration(const TFunction &parsedFunction,
                                                               const TSourceLoc &location);
     TIntermFunctionDefinition *addFunctionDefinition(TIntermFunctionPrototype *functionPrototype,
@@ -276,45 +291,51 @@ class TParseContext : angle::NonCopyable
     TFunction *parseFunctionHeader(const TPublicType &type,
                                    const TString *name,
                                    const TSourceLoc &location);
     TFunction *addNonConstructorFunc(const TString *name, const TSourceLoc &loc);
     TFunction *addConstructorFunc(const TPublicType &publicType);
     TParameter parseParameterDeclarator(const TPublicType &publicType,
                                         const TString *name,
                                         const TSourceLoc &nameLoc);
-    TParameter parseParameterArrayDeclarator(const TString *identifier,
-                                             const TSourceLoc &identifierLoc,
-                                             TIntermTyped *arraySize,
+
+    TParameter parseParameterArrayDeclarator(const TString *name,
+                                             const TSourceLoc &nameLoc,
+                                             const TVector<unsigned int> &arraySizes,
                                              const TSourceLoc &arrayLoc,
-                                             TPublicType *type);
+                                             TPublicType *elementType);
 
     TIntermTyped *addIndexExpression(TIntermTyped *baseExpression,
                                      const TSourceLoc &location,
                                      TIntermTyped *indexExpression);
     TIntermTyped *addFieldSelectionExpression(TIntermTyped *baseExpression,
                                               const TSourceLoc &dotLocation,
                                               const TString &fieldString,
                                               const TSourceLoc &fieldLocation);
 
     // Parse declarator for a single field
-    TField *parseStructDeclarator(TString *identifier, const TSourceLoc &loc);
-    TField *parseStructArrayDeclarator(TString *identifier,
-                                       const TSourceLoc &loc,
-                                       TIntermTyped *arraySize,
-                                       const TSourceLoc &arraySizeLoc);
+    TDeclarator *parseStructDeclarator(const TString *identifier, const TSourceLoc &loc);
+    TDeclarator *parseStructArrayDeclarator(const TString *identifier,
+                                            const TSourceLoc &loc,
+                                            const TVector<unsigned int> *arraySizes);
 
+    void checkDoesNotHaveDuplicateFieldName(const TFieldList::const_iterator begin,
+                                            const TFieldList::const_iterator end,
+                                            const TString &name,
+                                            const TSourceLoc &location);
+    TFieldList *addStructFieldList(TFieldList *fields, const TSourceLoc &location);
     TFieldList *combineStructFieldLists(TFieldList *processedFields,
                                         const TFieldList *newlyAddedFields,
                                         const TSourceLoc &location);
     TFieldList *addStructDeclaratorListWithQualifiers(
         const TTypeQualifierBuilder &typeQualifierBuilder,
         TPublicType *typeSpecifier,
-        TFieldList *fieldList);
-    TFieldList *addStructDeclaratorList(const TPublicType &typeSpecifier, TFieldList *fieldList);
+        const TDeclaratorList *declaratorList);
+    TFieldList *addStructDeclaratorList(const TPublicType &typeSpecifier,
+                                        const TDeclaratorList *declaratorList);
     TTypeSpecifierNonArray addStructure(const TSourceLoc &structLine,
                                         const TSourceLoc &nameLine,
                                         const TString *structName,
                                         TFieldList *fieldList);
 
     TIntermDeclaration *addInterfaceBlock(const TTypeQualifierBuilder &typeQualifierBuilder,
                                           const TSourceLoc &nameLine,
                                           const TString &blockName,
@@ -392,16 +413,17 @@ class TParseContext : angle::NonCopyable
     TIntermBranch *addBranch(TOperator op, const TSourceLoc &loc);
     TIntermBranch *addBranch(TOperator op, TIntermTyped *expression, const TSourceLoc &loc);
 
     void checkTextureGather(TIntermAggregate *functionCall);
     void checkTextureOffsetConst(TIntermAggregate *functionCall);
     void checkImageMemoryAccessForBuiltinFunctions(TIntermAggregate *functionCall);
     void checkImageMemoryAccessForUserDefinedFunctions(const TFunction *functionDefinition,
                                                        const TIntermAggregate *functionCall);
+    void checkAtomicMemoryBuiltinFunctions(TIntermAggregate *functionCall);
     TIntermSequence *createEmptyArgumentsList();
 
     // fnCall is only storing the built-in op, and function name or constructor type. arguments
     // has the arguments.
     TIntermTyped *addFunctionCallOrMethod(TFunction *fnCall,
                                           TIntermSequence *arguments,
                                           TIntermNode *thisNode,
                                           const TSourceLoc &loc);
@@ -432,33 +454,38 @@ class TParseContext : angle::NonCopyable
     class AtomicCounterBindingState;
     constexpr static size_t kAtomicCounterSize = 4;
     // UNIFORM_ARRAY_STRIDE for atomic counter arrays is an implementation-dependent value which
     // can be queried after a program is linked according to ES 3.10 section 7.7.1. This is
     // controversial with the offset inheritance as described in ESSL 3.10 section 4.4.6. Currently
     // we treat it as always 4 in favour of the original interpretation in
     // "ARB_shader_atomic_counters".
     // TODO(jie.a.chen@intel.com): Double check this once the spec vagueness is resolved.
+    // Note that there may be tests in AtomicCounter_test that will need to be updated as well.
     constexpr static size_t kAtomicCounterArrayStride = 4;
 
     // Returns a clamped index. If it prints out an error message, the token is "[]".
-    int checkIndexOutOfRange(bool outOfRangeIndexIsError,
-                             const TSourceLoc &location,
-                             int index,
-                             int arraySize,
-                             const char *reason);
+    int checkIndexLessThan(bool outOfRangeIndexIsError,
+                           const TSourceLoc &location,
+                           int index,
+                           int arraySize,
+                           const char *reason);
 
     bool declareVariable(const TSourceLoc &line,
                          const TString &identifier,
                          const TType &type,
                          TVariable **variable);
 
     void checkCanBeDeclaredWithoutInitializer(const TSourceLoc &line,
                                               const TString &identifier,
-                                              TPublicType *type);
+                                              TType *type);
+
+    TParameter parseParameterDeclarator(TType *type,
+                                        const TString *name,
+                                        const TSourceLoc &nameLoc);
 
     bool checkIsValidTypeAndQualifierForArray(const TSourceLoc &indexLocation,
                                               const TPublicType &elementType);
     // Done for all atomic counter declarations, whether empty or not.
     void atomicCounterQualifierErrorCheck(const TPublicType &publicType,
                                           const TSourceLoc &location);
 
     // Assumes that multiplication op has already been set based on the types.
@@ -467,21 +494,19 @@ class TParseContext : angle::NonCopyable
     void checkOutParameterIsNotOpaqueType(const TSourceLoc &line,
                                           TQualifier qualifier,
                                           const TType &type);
 
     void checkInternalFormatIsNotSpecified(const TSourceLoc &location,
                                            TLayoutImageInternalFormat internalFormat);
     void checkMemoryQualifierIsNotSpecified(const TMemoryQualifier &memoryQualifier,
                                             const TSourceLoc &location);
-    void checkAtomicCounterOffsetIsNotOverlapped(TPublicType &publicType,
-                                                 size_t size,
-                                                 bool forceAppend,
-                                                 const TSourceLoc &loc,
-                                                 TType &type);
+    void checkAtomicCounterOffsetDoesNotOverlap(bool forceAppend,
+                                                const TSourceLoc &loc,
+                                                TType *type);
     void checkBindingIsValid(const TSourceLoc &identifierLocation, const TType &type);
     void checkBindingIsNotSpecified(const TSourceLoc &location, int binding);
     void checkOffsetIsNotSpecified(const TSourceLoc &location, int offset);
     void checkImageBindingIsValid(const TSourceLoc &location,
                                   int binding,
                                   int arrayTotalElementCount);
     void checkSamplerBindingIsValid(const TSourceLoc &location,
                                     int binding,
@@ -497,54 +522,70 @@ class TParseContext : angle::NonCopyable
                                      const TLayoutQualifier &layoutQualifier);
 
     void checkYuvIsNotSpecified(const TSourceLoc &location, bool yuv);
 
     bool checkUnsizedArrayConstructorArgumentDimensionality(TIntermSequence *arguments,
                                                             TType type,
                                                             const TSourceLoc &line);
 
+    // Will set the size of the outermost array according to geometry shader input layout.
+    void checkGeometryShaderInputAndSetArraySize(const TSourceLoc &location,
+                                                 const char *token,
+                                                 TType *type);
+
+    // Will size any unsized array type so unsized arrays won't need to be taken into account
+    // further along the line in parsing.
+    void checkIsNotUnsizedArray(const TSourceLoc &line,
+                                const char *errorMessage,
+                                const char *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 *addMethod(TFunction *fnCall,
+    TIntermTyped *addMethod(const TString &name,
                             TIntermSequence *arguments,
                             TIntermNode *thisNode,
                             const TSourceLoc &loc);
     TIntermTyped *addConstructor(TIntermSequence *arguments,
                                  TType type,
                                  const TSourceLoc &line);
-    TIntermTyped *addNonConstructorFunctionCall(TFunction *fnCall,
+    TIntermTyped *addNonConstructorFunctionCall(const TString &name,
                                                 TIntermSequence *arguments,
                                                 const TSourceLoc &loc);
 
+    // Return either the original expression or the folded version of the expression in case the
+    // folded node will validate the same way during subsequent parsing.
+    TIntermTyped *expressionOrFoldedResult(TIntermTyped *expression);
+
     // Return true if the checks pass
     bool binaryOpCommonCheck(TOperator op,
                              TIntermTyped *left,
                              TIntermTyped *right,
                              const TSourceLoc &loc);
 
     TIntermFunctionPrototype *createPrototypeNodeFromFunction(const TFunction &function,
                                                               const TSourceLoc &location,
                                                               bool insertParametersToSymbolTable);
 
     void setAtomicCounterBindingDefaultOffset(const TPublicType &declaration,
                                               const TSourceLoc &location);
 
     bool checkPrimitiveTypeMatchesTypeQualifier(const TTypeQualifier &typeQualifier);
     bool parseGeometryShaderInputLayoutQualifier(const TTypeQualifier &typeQualifier);
     bool parseGeometryShaderOutputLayoutQualifier(const TTypeQualifier &typeQualifier);
-    void setGeometryShaderInputArraySizes();
+    void setGeometryShaderInputArraySize(unsigned int inputArraySize, const TSourceLoc &line);
 
     // Set to true when the last/current declarator list was started with an empty declaration. The
     // non-empty declaration error check will need to be performed if the empty declaration is
     // followed by a declarator.
     bool mDeferredNonEmptyDeclarationErrorCheck;
 
     sh::GLenum mShaderType;    // vertex or fragment language (future: pack or unpack)
     ShShaderSpec mShaderSpec;  // The language specification compiler conforms to - GLES2 or WebGL.
@@ -601,18 +642,19 @@ 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;
-    int mGeometryShaderInputArraySize;  // Track if all input array sizes are same and matches the
-                                        // latter input primitive declaration.
+
+    // Track if all input array sizes are same and matches the latter input primitive declaration.
+    unsigned int mGeometryShaderInputArraySize;
 };
 
 int PaParseStrings(size_t count,
                    const char *const string[],
                    const int length[],
                    TParseContext *context);
 
 }  // namespace sh
deleted file mode 100644
--- a/gfx/angle/src/compiler/translator/PruneEmptyDeclarations.cpp
+++ /dev/null
@@ -1,115 +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 PruneEmptyDeclarations function prunes unnecessary empty declarations and declarators from
-// the AST.
-
-#include "compiler/translator/PruneEmptyDeclarations.h"
-
-#include "compiler/translator/IntermTraverse.h"
-
-namespace sh
-{
-
-namespace
-{
-
-class PruneEmptyDeclarationsTraverser : private TIntermTraverser
-{
-  public:
-    static void apply(TIntermNode *root);
-
-  private:
-    PruneEmptyDeclarationsTraverser();
-    bool visitDeclaration(Visit, TIntermDeclaration *node) override;
-};
-
-void PruneEmptyDeclarationsTraverser::apply(TIntermNode *root)
-{
-    PruneEmptyDeclarationsTraverser prune;
-    root->traverse(&prune);
-    prune.updateTree();
-}
-
-PruneEmptyDeclarationsTraverser::PruneEmptyDeclarationsTraverser()
-    : TIntermTraverser(true, false, false)
-{
-}
-
-bool PruneEmptyDeclarationsTraverser::visitDeclaration(Visit, TIntermDeclaration *node)
-{
-    TIntermSequence *sequence = node->getSequence();
-    if (sequence->size() >= 1)
-    {
-        TIntermSymbol *sym = sequence->front()->getAsSymbolNode();
-        // Prune declarations without a variable name, unless it's an interface block declaration.
-        if (sym != nullptr && sym->getSymbol() == "" && !sym->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, sym, emptyReplacement));
-            }
-            else if (sym->getBasicType() != EbtStruct)
-            {
-                // Single struct declarations may just declare the struct type and no variables, so
-                // they should not be pruned. All other single empty declarations can be pruned
-                // entirely. Example of an empty declaration that will be pruned:
-                // float;
-                TIntermSequence emptyReplacement;
-                TIntermBlock *parentAsBlock = getParentNode()->getAsBlock();
-                // The declaration may be inside a block or in a loop init expression.
-                ASSERT(parentAsBlock != nullptr || getParentNode()->getAsLoopNode() != nullptr);
-                if (parentAsBlock)
-                {
-                    mMultiReplacements.push_back(
-                        NodeReplaceWithMultipleEntry(parentAsBlock, node, emptyReplacement));
-                }
-                else
-                {
-                    queueReplacement(nullptr, OriginalNode::IS_DROPPED);
-                }
-            }
-            else if (sym->getType().getQualifier() != EvqGlobal &&
-                     sym->getType().getQualifier() != EvqTemporary)
-            {
-                // We've hit 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."
-
-                if (mInGlobalScope)
-                {
-                    sym->getTypePointer()->setQualifier(EvqGlobal);
-                }
-                else
-                {
-                    sym->getTypePointer()->setQualifier(EvqTemporary);
-                }
-            }
-        }
-    }
-    return false;
-}
-
-}  // namespace
-
-void PruneEmptyDeclarations(TIntermNode *root)
-{
-    PruneEmptyDeclarationsTraverser::apply(root);
-}
-
-}  // namespace sh
deleted file mode 100644
--- a/gfx/angle/src/compiler/translator/PruneEmptyDeclarations.h
+++ /dev/null
@@ -1,19 +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 PruneEmptyDeclarations function prunes unnecessary empty declarations and declarators from
-// the AST.
-
-#ifndef COMPILER_TRANSLATOR_PRUNEEMPTYDECLARATIONS_H_
-#define COMPILER_TRANSLATOR_PRUNEEMPTYDECLARATIONS_H_
-
-namespace sh
-{
-class TIntermNode;
-
-void PruneEmptyDeclarations(TIntermNode *root);
-}
-
-#endif  // COMPILER_TRANSLATOR_PRUNEEMPTYDECLARATIONS_H_
new file mode 100644
--- /dev/null
+++ b/gfx/angle/src/compiler/translator/PruneNoOps.cpp
@@ -0,0 +1,158 @@
+//
+// 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);
+
+  private:
+    PruneNoOpsTraverser();
+    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)
+{
+    PruneNoOpsTraverser prune;
+    root->traverse(&prune);
+    prune.updateTree();
+}
+
+PruneNoOpsTraverser::PruneNoOpsTraverser() : TIntermTraverser(true, false, false)
+{
+}
+
+bool PruneNoOpsTraverser::visitDeclaration(Visit, TIntermDeclaration *node)
+{
+    TIntermSequence *sequence = node->getSequence();
+    if (sequence->size() >= 1)
+    {
+        TIntermSymbol *sym = sequence->front()->getAsSymbolNode();
+        // Prune declarations without a variable name, unless it's an interface block declaration.
+        if (sym != nullptr && sym->variable().symbolType() == SymbolType::Empty &&
+            !sym->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, sym, emptyReplacement));
+            }
+            else if (sym->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 (sym->getType().getQualifier() != EvqGlobal &&
+                     sym->getType().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."
+
+                if (mInGlobalScope)
+                {
+                    sym->getTypePointer()->setQualifier(EvqGlobal);
+                }
+                else
+                {
+                    sym->getTypePointer()->setQualifier(EvqTemporary);
+                }
+            }
+        }
+    }
+    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)
+{
+    PruneNoOpsTraverser::apply(root);
+}
+
+}  // namespace sh
new file mode 100644
--- /dev/null
+++ b/gfx/angle/src/compiler/translator/PruneNoOps.h
@@ -0,0 +1,24 @@
+//
+// 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;
+
+void PruneNoOps(TIntermBlock *root);
+}
+
+#endif  // COMPILER_TRANSLATOR_PRUNENOOPS_H_
deleted file mode 100644
--- a/gfx/angle/src/compiler/translator/PrunePureLiteralStatements.cpp
+++ /dev/null
@@ -1,91 +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.
-//
-// PrunePureLiteralStatements.cpp: Removes statements that are literals and nothing else.
-
-#include "compiler/translator/PrunePureLiteralStatements.h"
-
-#include "compiler/translator/IntermTraverse.h"
-
-namespace sh
-{
-
-namespace
-{
-
-class PrunePureLiteralStatementsTraverser : public TIntermTraverser
-{
-  public:
-    PrunePureLiteralStatementsTraverser() : TIntermTraverser(true, false, false) {}
-
-    bool visitBlock(Visit visit, TIntermBlock *node) override
-    {
-        TIntermSequence *statements = node->getSequence();
-        if (statements == nullptr)
-        {
-            return false;
-        }
-
-        // Empty case statements at the end of a switch are invalid: if the last statements
-        // of a block was a pure literal, also delete all the case statements directly preceding it.
-        bool deleteCaseStatements = false;
-        for (int i = static_cast<int>(statements->size()); i-- > 0;)
-        {
-            TIntermNode *statement = (*statements)[i];
-
-            if (statement->getAsConstantUnion() != nullptr)
-            {
-                TIntermSequence emptyReplacement;
-                mMultiReplacements.push_back(
-                    NodeReplaceWithMultipleEntry(node, statement, emptyReplacement));
-
-                if (i == static_cast<int>(statements->size()) - 1)
-                {
-                    deleteCaseStatements = true;
-                }
-
-                continue;
-            }
-
-            if (deleteCaseStatements)
-            {
-                if (statement->getAsCaseNode() != nullptr)
-                {
-                    TIntermSequence emptyReplacement;
-                    mMultiReplacements.push_back(
-                        NodeReplaceWithMultipleEntry(node, statement, emptyReplacement));
-                }
-                else
-                {
-                    deleteCaseStatements = false;
-                }
-            }
-        }
-
-        return true;
-    }
-
-    bool visitLoop(Visit visit, TIntermLoop *loop) override
-    {
-        TIntermTyped *expr = loop->getExpression();
-        if (expr != nullptr && expr->getAsConstantUnion() != nullptr)
-        {
-            loop->setExpression(nullptr);
-        }
-
-        return true;
-    }
-};
-
-}  // namespace
-
-void PrunePureLiteralStatements(TIntermNode *root)
-{
-    PrunePureLiteralStatementsTraverser prune;
-    root->traverse(&prune);
-    prune.updateTree();
-}
-
-}  // namespace sh
deleted file mode 100644
--- a/gfx/angle/src/compiler/translator/PrunePureLiteralStatements.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.
-//
-// PrunePureLiteralStatements.h: Removes statements that are literals and nothing else.
-
-#ifndef COMPILER_TRANSLATOR_PRUNEPURELITERALSTATEMENTS_H_
-#define COMPILER_TRANSLATOR_PRUNEPURELITERALSTATEMENTS_H_
-
-namespace sh
-{
-class TIntermNode;
-
-void PrunePureLiteralStatements(TIntermNode *root);
-}
-
-#endif  // COMPILER_TRANSLATOR_PRUNEPURELITERALSTATEMENTS_H_
--- a/gfx/angle/src/compiler/translator/QualifierTypes.cpp
+++ b/gfx/angle/src/compiler/translator/QualifierTypes.cpp
@@ -303,52 +303,58 @@ bool JoinVariableStorageQualifier(TQuali
         case EvqSmooth:
         {
             switch (storageQualifier)
             {
                 case EvqCentroid:
                     *joinedQualifier = EvqCentroid;
                     break;
                 case EvqVertexOut:
+                case EvqGeometryOut:
                     *joinedQualifier = EvqSmoothOut;
                     break;
                 case EvqFragmentIn:
+                case EvqGeometryIn:
                     *joinedQualifier = EvqSmoothIn;
                     break;
                 default:
                     return false;
             }
             break;
         }
         case EvqFlat:
         {
             switch (storageQualifier)
             {
                 case EvqCentroid:
                     *joinedQualifier = EvqFlat;
                     break;
                 case EvqVertexOut:
+                case EvqGeometryOut:
                     *joinedQualifier = EvqFlatOut;
                     break;
                 case EvqFragmentIn:
+                case EvqGeometryIn:
                     *joinedQualifier = EvqFlatIn;
                     break;
                 default:
                     return false;
             }
             break;
         }
         case EvqCentroid:
         {
             switch (storageQualifier)
             {
                 case EvqVertexOut:
+                case EvqGeometryOut:
                     *joinedQualifier = EvqCentroidOut;
                     break;
                 case EvqFragmentIn:
+                case EvqGeometryIn:
                     *joinedQualifier = EvqCentroidIn;
                     break;
                 default:
                     return false;
             }
             break;
         }
         default:
@@ -680,18 +686,18 @@ unsigned int TMemoryQualifierWrapper::ge
 }
 
 unsigned int TPrecisionQualifierWrapper::getRank() const
 {
     return 5u;
 }
 
 TTypeQualifier::TTypeQualifier(TQualifier scope, const TSourceLoc &loc)
-    : layoutQualifier(TLayoutQualifier::create()),
-      memoryQualifier(TMemoryQualifier::create()),
+    : layoutQualifier(TLayoutQualifier::Create()),
+      memoryQualifier(TMemoryQualifier::Create()),
       precision(EbpUndefined),
       qualifier(scope),
       invariant(false),
       line(loc)
 {
     ASSERT(IsScopeQualifier(qualifier));
 }
 
--- a/gfx/angle/src/compiler/translator/RecordConstantPrecision.cpp
+++ b/gfx/angle/src/compiler/translator/RecordConstantPrecision.cpp
@@ -12,16 +12,17 @@
 // 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
 {
 
@@ -131,26 +132,25 @@ void RecordConstantPrecisionTraverser::v
 
     // 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.
-    TIntermSequence insertions;
-    insertions.push_back(createTempInitDeclaration(node, EvqConst));
-    insertStatementsInParentBlock(insertions);
-    queueReplacement(createTempSymbol(node->getType()), OriginalNode::IS_DROPPED);
+    TIntermDeclaration *variableDeclaration = nullptr;
+    TVariable *variable = DeclareTempVariable(mSymbolTable, node, EvqConst, &variableDeclaration);
+    insertStatementInParentBlock(variableDeclaration);
+    queueReplacement(CreateTempSymbolNode(variable), OriginalNode::IS_DROPPED);
     mFoundHigherPrecisionConstant = true;
 }
 
 void RecordConstantPrecisionTraverser::nextIteration()
 {
-    nextTemporaryId();
     mFoundHigherPrecisionConstant = false;
 }
 
 }  // namespace
 
 void RecordConstantPrecision(TIntermNode *root, TSymbolTable *symbolTable)
 {
     RecordConstantPrecisionTraverser traverser(symbolTable);
--- a/gfx/angle/src/compiler/translator/RegenerateStructNames.cpp
+++ b/gfx/angle/src/compiler/translator/RegenerateStructNames.cpp
@@ -14,23 +14,24 @@ void RegenerateStructNames::visitSymbol(
 {
     ASSERT(symbol);
     TType *type = symbol->getTypePointer();
     ASSERT(type);
     TStructure *userType = type->getStruct();
     if (!userType)
         return;
 
-    if (mSymbolTable->findBuiltIn(userType->name(), mShaderVersion))
+    if (userType->symbolType() == SymbolType::BuiltIn ||
+        userType->symbolType() == SymbolType::Empty)
     {
-        // Built-in struct, do not touch it.
+        // Built-in struct or nameless struct, do not touch it.
         return;
     }
 
-    int uniqueId = userType->uniqueId();
+    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,
--- a/gfx/angle/src/compiler/translator/RegenerateStructNames.h
+++ b/gfx/angle/src/compiler/translator/RegenerateStructNames.h
@@ -13,30 +13,26 @@
 #include <set>
 
 namespace sh
 {
 
 class RegenerateStructNames : public TIntermTraverser
 {
   public:
-    RegenerateStructNames(TSymbolTable *symbolTable, int shaderVersion)
-        : TIntermTraverser(true, false, false, symbolTable),
-          mShaderVersion(shaderVersion),
-          mScopeDepth(0)
+    RegenerateStructNames(TSymbolTable *symbolTable)
+        : TIntermTraverser(true, false, false, symbolTable), mScopeDepth(0)
     {
     }
 
   protected:
     void visitSymbol(TIntermSymbol *) override;
     bool visitBlock(Visit, TIntermBlock *block) override;
 
   private:
-    int mShaderVersion;
-
     // 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;
 };
 
--- a/gfx/angle/src/compiler/translator/RemoveArrayLengthMethod.cpp
+++ b/gfx/angle/src/compiler/translator/RemoveArrayLengthMethod.cpp
@@ -11,16 +11,18 @@
 //   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
 {
@@ -40,17 +42,18 @@ class RemoveArrayLengthTraverser : publi
     bool foundArrayLength() const { return mFoundArrayLength; }
 
   private:
     bool mFoundArrayLength;
 };
 
 bool RemoveArrayLengthTraverser::visitUnary(Visit visit, TIntermUnary *node)
 {
-    if (node->getOp() == EOpArrayLength)
+    // 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());
--- a/gfx/angle/src/compiler/translator/RemoveArrayLengthMethod.h
+++ b/gfx/angle/src/compiler/translator/RemoveArrayLengthMethod.h
@@ -11,16 +11,18 @@
 //   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);
 
--- a/gfx/angle/src/compiler/translator/RemoveDynamicIndexing.cpp
+++ b/gfx/angle/src/compiler/translator/RemoveDynamicIndexing.cpp
@@ -4,16 +4,17 @@
 // 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/SymbolTable.h"
 
 namespace sh
 {
@@ -52,39 +53,40 @@ std::string GetIndexFunctionName(const T
             default:
                 UNREACHABLE();
         }
         nameSink << type.getNominalSize();
     }
     return nameSink.str();
 }
 
-TIntermSymbol *CreateBaseSymbol(const TType &type, TQualifier qualifier, TSymbolTable *symbolTable)
+TIntermSymbol *CreateBaseSymbol(const TType &type, TSymbolTable *symbolTable)
 {
-    TIntermSymbol *symbol = new TIntermSymbol(symbolTable->nextUniqueId(), "base", type);
-    symbol->setInternal(true);
-    symbol->getTypePointer()->setQualifier(qualifier);
-    return symbol;
+    TString *baseString = NewPoolTString("base");
+    TVariable *baseVariable =
+        new TVariable(symbolTable, baseString, type, SymbolType::AngleInternal);
+    return new TIntermSymbol(baseVariable);
 }
 
 TIntermSymbol *CreateIndexSymbol(TSymbolTable *symbolTable)
 {
-    TIntermSymbol *symbol =
-        new TIntermSymbol(symbolTable->nextUniqueId(), "index", TType(EbtInt, EbpHigh));
-    symbol->setInternal(true);
-    symbol->getTypePointer()->setQualifier(EvqIn);
-    return symbol;
+    TString *indexString     = NewPoolTString("index");
+    TVariable *indexVariable = new TVariable(
+        symbolTable, indexString, TType(EbtInt, EbpHigh, EvqIn), SymbolType::AngleInternal);
+    return new TIntermSymbol(indexVariable);
 }
 
 TIntermSymbol *CreateValueSymbol(const TType &type, TSymbolTable *symbolTable)
 {
-    TIntermSymbol *symbol = new TIntermSymbol(symbolTable->nextUniqueId(), "value", type);
-    symbol->setInternal(true);
-    symbol->getTypePointer()->setQualifier(EvqIn);
-    return symbol;
+    TString *valueString = NewPoolTString("value");
+    TType valueType(type);
+    valueType.setQualifier(EvqIn);
+    TVariable *valueVariable =
+        new TVariable(symbolTable, valueString, valueType, SymbolType::AngleInternal);
+    return new TIntermSymbol(valueVariable);
 }
 
 TIntermConstantUnion *CreateIntConstantNode(int i)
 {
     TConstantUnion *constant = new TConstantUnion();
     constant->setIConst(i);
     return new TIntermConstantUnion(constant, TType(EbtInt, EbpHigh));
 }
@@ -94,27 +96,27 @@ TIntermTyped *EnsureSignedInt(TIntermTyp
     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)
+TType *GetFieldType(const TType &indexedType)
 {
     if (indexedType.isMatrix())
     {
-        TType fieldType = TType(indexedType.getBasicType(), indexedType.getPrecision());
-        fieldType.setPrimarySize(static_cast<unsigned char>(indexedType.getRows()));
+        TType *fieldType = new TType(indexedType.getBasicType(), indexedType.getPrecision());
+        fieldType->setPrimarySize(static_cast<unsigned char>(indexedType.getRows()));
         return fieldType;
     }
     else
     {
-        return TType(indexedType.getBasicType(), indexedType.getPrecision());
+        return new TType(indexedType.getBasicType(), indexedType.getPrecision());
     }
 }
 
 // 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.
@@ -151,60 +153,55 @@ TType GetFieldType(const TType &indexedT
 //    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(TType type,
+TIntermFunctionDefinition *GetIndexFunctionDefinition(const TType &type,
                                                       bool write,
-                                                      const TSymbolUniqueId &functionId,
+                                                      const TFunction &func,
                                                       TSymbolTable *symbolTable)
 {
     ASSERT(!type.isArray());
-    // 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.
-    type.setPrecision(EbpHigh);
 
-    TType fieldType = GetFieldType(type);
+    const TType *fieldType = GetFieldType(type);
     int numCases    = 0;
     if (type.isMatrix())
     {
         numCases = type.getCols();
     }
     else
     {
         numCases = type.getNominalSize();
     }
 
-    TType returnType(EbtVoid);
-    if (!write)
-    {
-        returnType = fieldType;
-    }
+    std::string functionName                = GetIndexFunctionName(type, write);
+    TIntermFunctionPrototype *prototypeNode = CreateInternalFunctionPrototypeNode(func);
 
-    std::string functionName                = GetIndexFunctionName(type, write);
-    TIntermFunctionPrototype *prototypeNode =
-        CreateInternalFunctionPrototypeNode(returnType, functionName.c_str(), functionId);
+    TType baseType(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);
 
-    TQualifier baseQualifier     = EvqInOut;
-    if (!write)
-        baseQualifier        = EvqIn;
-    TIntermSymbol *baseParam = CreateBaseSymbol(type, baseQualifier, symbolTable);
+    TIntermSymbol *baseParam = CreateBaseSymbol(baseType, symbolTable);
     prototypeNode->getSequence()->push_back(baseParam);
     TIntermSymbol *indexParam = CreateIndexSymbol(symbolTable);
     prototypeNode->getSequence()->push_back(indexParam);
     TIntermSymbol *valueParam = nullptr;
     if (write)
     {
-        valueParam = CreateValueSymbol(fieldType, symbolTable);
+        valueParam = CreateValueSymbol(*fieldType, 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);
@@ -276,47 +273,54 @@ TIntermFunctionDefinition *GetIndexFunct
     TIntermFunctionDefinition *indexingFunction =
         new TIntermFunctionDefinition(prototypeNode, bodyNode);
     return indexingFunction;
 }
 
 class RemoveDynamicIndexingTraverser : public TLValueTrackingTraverser
 {
   public:
-    RemoveDynamicIndexingTraverser(TSymbolTable *symbolTable, int shaderVersion);
+    RemoveDynamicIndexingTraverser(TSymbolTable *symbolTable,
+                                   int shaderVersion,
+                                   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, TSymbolUniqueId *> mIndexedVecAndMatrixTypes;
-    std::map<TType, TSymbolUniqueId *> mWrittenVecAndMatrixTypes;
+    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,
-                                                               int shaderVersion)
+RemoveDynamicIndexingTraverser::RemoveDynamicIndexingTraverser(
+    TSymbolTable *symbolTable,
+    int shaderVersion,
+    PerformanceDiagnostics *perfDiagnostics)
     : TLValueTrackingTraverser(true, false, false, symbolTable, shaderVersion),
       mUsedTreeInsertion(false),
-      mRemoveIndexSideEffectsInSubtree(false)
+      mRemoveIndexSideEffectsInSubtree(false),
+      mPerfDiagnostics(perfDiagnostics)
 {
 }
 
 void RemoveDynamicIndexingTraverser::insertHelperDefinitions(TIntermNode *root)
 {
     TIntermBlock *rootBlock = root->getAsBlock();
     ASSERT(rootBlock != nullptr);
     TIntermSequence insertions;
@@ -325,53 +329,49 @@ void RemoveDynamicIndexingTraverser::ins
         insertions.push_back(
             GetIndexFunctionDefinition(type.first, false, *type.second, mSymbolTable));
     }
     for (auto &type : mWrittenVecAndMatrixTypes)
     {
         insertions.push_back(
             GetIndexFunctionDefinition(type.first, true, *type.second, mSymbolTable));
     }
-    mInsertions.push_back(NodeInsertMultipleEntry(rootBlock, 0, insertions, TIntermSequence()));
+    rootBlock->insertChildNodes(0, insertions);
 }
 
 // Create a call to dyn_index_*() based on an indirect indexing op node
 TIntermAggregate *CreateIndexFunctionCall(TIntermBinary *node,
                                           TIntermTyped *index,
-                                          const TSymbolUniqueId &functionId)
+                                          TFunction *indexingFunction)
 {
     ASSERT(node->getOp() == EOpIndexIndirect);
     TIntermSequence *arguments = new TIntermSequence();
     arguments->push_back(node->getLeft());
     arguments->push_back(index);
 
-    TType fieldType                = GetFieldType(node->getLeft()->getType());
-    std::string functionName       = GetIndexFunctionName(node->getLeft()->getType(), false);
     TIntermAggregate *indexingCall =
-        CreateInternalFunctionCallNode(fieldType, functionName.c_str(), functionId, arguments);
+        TIntermAggregate::CreateFunctionCall(*indexingFunction, arguments);
     indexingCall->setLine(node->getLine());
-    indexingCall->getFunctionSymbolInfo()->setKnownToNotHaveSideEffects(true);
     return indexingCall;
 }
 
 TIntermAggregate *CreateIndexedWriteFunctionCall(TIntermBinary *node,
-                                                 TIntermTyped *index,
-                                                 TIntermTyped *writtenValue,
-                                                 const TSymbolUniqueId &functionId)
+                                                 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(index->deepCopy());
-    arguments->push_back(writtenValue);
+    arguments->push_back(CreateTempSymbolNode(index));
+    arguments->push_back(CreateTempSymbolNode(writtenValue));
 
-    std::string functionName           = GetIndexFunctionName(node->getLeft()->getType(), true);
     TIntermAggregate *indexedWriteCall =
-        CreateInternalFunctionCallNode(TType(EbtVoid), functionName.c_str(), functionId, arguments);
+        TIntermAggregate::CreateFunctionCall(*indexedWriteFunction, arguments);
     indexedWriteCall->setLine(node->getLine());
     return indexedWriteCall;
 }
 
 bool RemoveDynamicIndexingTraverser::visitBinary(Visit visit, TIntermBinary *node)
 {
     if (mUsedTreeInsertion)
         return false;
@@ -381,47 +381,56 @@ bool RemoveDynamicIndexingTraverser::vis
         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.
-
-            // Init the temp variable holding the index
-            TIntermDeclaration *initIndex = createTempInitDeclaration(node->getRight());
-            insertStatementInParentBlock(initIndex);
+            TIntermDeclaration *indexVariableDeclaration = nullptr;
+            TVariable *indexVariable = DeclareTempVariable(mSymbolTable, node->getRight(),
+                                                           EvqTemporary, &indexVariableDeclaration);
+            insertStatementInParentBlock(indexVariableDeclaration);
             mUsedTreeInsertion = true;
 
             // Replace the index with the temp variable
-            TIntermSymbol *tempIndex = createTempSymbol(node->getRight()->getType());
+            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();
-            TSymbolUniqueId *indexingFunctionId = new TSymbolUniqueId(mSymbolTable);
+            TString *indexingFunctionName =
+                NewPoolTString(GetIndexFunctionName(type, false).c_str());
+            TFunction *indexingFunction = nullptr;
             if (mIndexedVecAndMatrixTypes.find(type) == mIndexedVecAndMatrixTypes.end())
             {
-                mIndexedVecAndMatrixTypes[type] = indexingFunctionId;
+                indexingFunction =
+                    new TFunction(mSymbolTable, indexingFunctionName, GetFieldType(type),
+                                  SymbolType::AngleInternal, true);
+                mIndexedVecAndMatrixTypes[type] = indexingFunction;
             }
             else
             {
-                indexingFunctionId = mIndexedVecAndMatrixTypes[type];
+                indexingFunction = mIndexedVecAndMatrixTypes[type];
             }
 
             if (write)
             {
                 // Convert:
                 //   v_expr[index_expr]++;
                 // to this:
                 //   int s0 = index_expr; float s1 = dyn_index(v_expr, s0); s1++;
@@ -446,91 +455,98 @@ bool RemoveDynamicIndexingTraverser::vis
                     // 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
 
-                TSymbolUniqueId *indexedWriteFunctionId = new TSymbolUniqueId(mSymbolTable);
+                TFunction *indexedWriteFunction = nullptr;
                 if (mWrittenVecAndMatrixTypes.find(type) == mWrittenVecAndMatrixTypes.end())
                 {
-                    mWrittenVecAndMatrixTypes[type] = indexedWriteFunctionId;
+                    TString *functionName = NewPoolTString(
+                        GetIndexFunctionName(node->getLeft()->getType(), true).c_str());
+                    indexedWriteFunction =
+                        new TFunction(mSymbolTable, functionName, new TType(EbtVoid),
+                                      SymbolType::AngleInternal, false);
+                    mWrittenVecAndMatrixTypes[type] = indexedWriteFunction;
                 }
                 else
                 {
-                    indexedWriteFunctionId = mWrittenVecAndMatrixTypes[type];
+                    indexedWriteFunction = mWrittenVecAndMatrixTypes[type];
                 }
-                TType fieldType = GetFieldType(type);
 
                 TIntermSequence insertionsBefore;
                 TIntermSequence insertionsAfter;
 
                 // Store the index in a temporary signed int variable.
+                // s0 = index_expr;
                 TIntermTyped *indexInitializer = EnsureSignedInt(node->getRight());
-                TIntermDeclaration *initIndex  = createTempInitDeclaration(indexInitializer);
-                initIndex->setLine(node->getLine());
-                insertionsBefore.push_back(initIndex);
-
-                // Create a node for referring to the index after the nextTemporaryId() call
-                // below.
-                TIntermSymbol *tempIndex = createTempSymbol(indexInitializer->getType());
+                TIntermDeclaration *indexVariableDeclaration = nullptr;
+                TVariable *indexVariable                     = DeclareTempVariable(
+                    mSymbolTable, indexInitializer, EvqTemporary, &indexVariableDeclaration);
+                insertionsBefore.push_back(indexVariableDeclaration);
 
-                TIntermAggregate *indexingCall =
-                    CreateIndexFunctionCall(node, tempIndex, *indexingFunctionId);
+                // 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);
 
-                nextTemporaryId();  // From now on, creating temporary symbols that refer to the
-                                    // field value.
-                insertionsBefore.push_back(createTempInitDeclaration(indexingCall));
-
+                // dyn_index_write(v_expr, s0, s1);
                 TIntermAggregate *indexedWriteCall = CreateIndexedWriteFunctionCall(
-                    node, tempIndex, createTempSymbol(fieldType), *indexedWriteFunctionId);
+                    node, indexVariable, fieldVariable, indexedWriteFunction);
                 insertionsAfter.push_back(indexedWriteCall);
                 insertStatementsInParentBlock(insertionsBefore, insertionsAfter);
-                queueReplacement(createTempSymbol(fieldType), OriginalNode::IS_DROPPED);
+
+                // 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()), *indexingFunctionId);
+                    node, EnsureSignedInt(node->getRight()), indexingFunction);
                 queueReplacement(indexingCall, OriginalNode::IS_DROPPED);
             }
         }
     }
     return !mUsedTreeInsertion;
 }
 
 void RemoveDynamicIndexingTraverser::nextIteration()
 {
     mUsedTreeInsertion               = false;
     mRemoveIndexSideEffectsInSubtree = false;
-    nextTemporaryId();
 }
 
 }  // namespace
 
-void RemoveDynamicIndexing(TIntermNode *root, TSymbolTable *symbolTable, int shaderVersion)
+void RemoveDynamicIndexing(TIntermNode *root,
+                           TSymbolTable *symbolTable,
+                           int shaderVersion,
+                           PerformanceDiagnostics *perfDiagnostics)
 {
-    RemoveDynamicIndexingTraverser traverser(symbolTable, shaderVersion);
+    RemoveDynamicIndexingTraverser traverser(symbolTable, shaderVersion, perfDiagnostics);
     do
     {
         traverser.nextIteration();
         root->traverse(&traverser);
         traverser.updateTree();
     } while (traverser.usedTreeInsertion());
-    // TOOD(oetuaho@nvidia.com): It might be nicer to add the helper definitions also in the middle
+    // 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);
-    traverser.updateTree();
 }
 
 }  // namespace sh
--- a/gfx/angle/src/compiler/translator/RemoveDynamicIndexing.h
+++ b/gfx/angle/src/compiler/translator/RemoveDynamicIndexing.h
@@ -10,14 +10,18 @@
 #ifndef COMPILER_TRANSLATOR_REMOVEDYNAMICINDEXING_H_
 #define COMPILER_TRANSLATOR_REMOVEDYNAMICINDEXING_H_
 
 namespace sh
 {
 
 class TIntermNode;
 class TSymbolTable;
+class PerformanceDiagnostics;
 
-void RemoveDynamicIndexing(TIntermNode *root, TSymbolTable *symbolTable, int shaderVersion);
+void RemoveDynamicIndexing(TIntermNode *root,
+                           TSymbolTable *symbolTable,
+                           int shaderVersion,
+                           PerformanceDiagnostics *perfDiagnostics);
 
 }  // namespace sh
 
 #endif  // COMPILER_TRANSLATOR_REMOVEDYNAMICINDEXING_H_
new file mode 100644
--- /dev/null
+++ b/gfx/angle/src/compiler/translator/RemoveEmptySwitchStatements.cpp
@@ -0,0 +1,56 @@
+//
+// 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
new file mode 100644
--- /dev/null
+++ b/gfx/angle/src/compiler/translator/RemoveEmptySwitchStatements.h
@@ -0,0 +1,18 @@
+//
+// 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
new file mode 100644
--- /dev/null
+++ b/gfx/angle/src/compiler/translator/RemoveNoOpCasesFromEndOfSwitchStatements.cpp
@@ -0,0 +1,116 @@
+//
+// 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
new file mode 100644
--- /dev/null
+++ b/gfx/angle/src/compiler/translator/RemoveNoOpCasesFromEndOfSwitchStatements.h
@@ -0,0 +1,21 @@
+//
+// 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_
--- a/gfx/angle/src/compiler/translator/RemoveSwitchFallThrough.cpp
+++ b/gfx/angle/src/compiler/translator/RemoveSwitchFallThrough.cpp
@@ -1,174 +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/RemoveSwitchFallThrough.h"
 
+#include "compiler/translator/Diagnostics.h"
+#include "compiler/translator/IntermTraverse.h"
+
 namespace sh
 {
 
-TIntermBlock *RemoveSwitchFallThrough::removeFallThrough(TIntermBlock *statementList)
+namespace
+{
+
+class RemoveSwitchFallThroughTraverser : public TIntermTraverser
 {
-    RemoveSwitchFallThrough rm(statementList);
+  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);
-    bool lastStatementWasBreak = rm.mLastStatementWasBreak;
-    rm.mLastStatementWasBreak  = true;
+    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();
-    if (!lastStatementWasBreak)
-    {
-        TIntermBranch *finalBreak = new TIntermBranch(EOpBreak, nullptr);
-        rm.mStatementListOut->getSequence()->push_back(finalBreak);
-    }
     return rm.mStatementListOut;
 }
 
-RemoveSwitchFallThrough::RemoveSwitchFallThrough(TIntermBlock *statementList)
+RemoveSwitchFallThroughTraverser::RemoveSwitchFallThroughTraverser(
+    TIntermBlock *statementList,
+    PerformanceDiagnostics *perfDiagnostics)
     : TIntermTraverser(true, false, false),
       mStatementList(statementList),
       mLastStatementWasBreak(false),
-      mPreviousCase(nullptr)
+      mPreviousCase(nullptr),
+      mPerfDiagnostics(perfDiagnostics)
 {
     mStatementListOut = new TIntermBlock();
 }
 
-void RemoveSwitchFallThrough::visitSymbol(TIntermSymbol *node)
+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 RemoveSwitchFallThrough::visitConstantUnion(TIntermConstantUnion *node)
+void RemoveSwitchFallThroughTraverser::visitConstantUnion(TIntermConstantUnion *node)
 {
-    // Conditions of case labels are not traversed, so this is some other constant
-    // Could be just a statement like "0;"
+    // 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 RemoveSwitchFallThrough::visitBinary(Visit, TIntermBinary *node)
+bool RemoveSwitchFallThroughTraverser::visitBinary(Visit, TIntermBinary *node)
 {
     mPreviousCase->getSequence()->push_back(node);
     mLastStatementWasBreak = false;
     return false;
 }
 
-bool RemoveSwitchFallThrough::visitUnary(Visit, TIntermUnary *node)
+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 RemoveSwitchFallThrough::visitTernary(Visit, TIntermTernary *node)
+bool RemoveSwitchFallThroughTraverser::visitSwizzle(Visit, TIntermSwizzle *node)
 {
     mPreviousCase->getSequence()->push_back(node);
     mLastStatementWasBreak = false;
     return false;
 }
 
-bool RemoveSwitchFallThrough::visitIfElse(Visit, TIntermIfElse *node)
+bool RemoveSwitchFallThroughTraverser::visitIfElse(Visit, TIntermIfElse *node)
 {
     mPreviousCase->getSequence()->push_back(node);
     mLastStatementWasBreak = false;
     return false;
 }
 
-bool RemoveSwitchFallThrough::visitSwitch(Visit, TIntermSwitch *node)
+bool RemoveSwitchFallThroughTraverser::visitSwitch(Visit, TIntermSwitch *node)
 {
     mPreviousCase->getSequence()->push_back(node);
     mLastStatementWasBreak = false;
     // Don't go into nested switch statements
     return false;
 }
 
-void RemoveSwitchFallThrough::outputSequence(TIntermSequence *sequence, size_t startIndex)
+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 RemoveSwitchFallThrough::handlePreviousCase()
+void RemoveSwitchFallThroughTraverser::handlePreviousCase()
 {
     if (mPreviousCase)
         mCasesSharingBreak.push_back(mPreviousCase);
     if (mLastStatementWasBreak)
     {
-        bool labelsWithNoStatements = true;
         for (size_t i = 0; i < mCasesSharingBreak.size(); ++i)
         {
-            if (mCasesSharingBreak.at(i)->getSequence()->size() > 1)
-            {
-                labelsWithNoStatements = false;
-            }
-            if (labelsWithNoStatements)
+            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 RemoveSwitchFallThrough::visitCase(Visit, TIntermCase *node)
+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 RemoveSwitchFallThrough::visitAggregate(Visit, TIntermAggregate *node)
+bool RemoveSwitchFallThroughTraverser::visitAggregate(Visit, TIntermAggregate *node)
 {
     mPreviousCase->getSequence()->push_back(node);
     mLastStatementWasBreak = false;
     return false;
 }
 
-bool RemoveSwitchFallThrough::visitBlock(Visit, TIntermBlock *node)
+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 = false;
+        mLastStatementWasBreak = DoesBlockAlwaysBreak(node);
         return false;
     }
     return true;
 }
 
-bool RemoveSwitchFallThrough::visitLoop(Visit, TIntermLoop *node)
+bool RemoveSwitchFallThroughTraverser::visitLoop(Visit, TIntermLoop *node)
 {
     mPreviousCase->getSequence()->push_back(node);
     mLastStatementWasBreak = false;
     return false;
 }
 
-bool RemoveSwitchFallThrough::visitBranch(Visit, TIntermBranch *node)
+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
--- a/gfx/angle/src/compiler/translator/RemoveSwitchFallThrough.h
+++ b/gfx/angle/src/compiler/translator/RemoveSwitchFallThrough.h
@@ -1,50 +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_REMOVESWITCHFALLTHROUGH_H_
 #define COMPILER_TRANSLATOR_REMOVESWITCHFALLTHROUGH_H_
 
-#include "compiler/translator/IntermTraverse.h"
-
 namespace sh
 {
 
-class RemoveSwitchFallThrough : public TIntermTraverser
-{
-  public:
-    // When given a statementList from a switch AST node, return an updated
-    // statementList that has fall-through removed.
-    static TIntermBlock *removeFallThrough(TIntermBlock *statementList);
-
-  private:
-    RemoveSwitchFallThrough(TIntermBlock *statementList);
+class TIntermBlock;
+class PerformanceDiagnostics;
 
-    void visitSymbol(TIntermSymbol *node) override;
-    void visitConstantUnion(TIntermConstantUnion *node) override;
-    bool visitBinary(Visit, TIntermBinary *node) override;
-    bool visitUnary(Visit, TIntermUnary *node) override;
-    bool visitTernary(Visit visit, TIntermTernary *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;
-};
+// 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_
new file mode 100644
--- /dev/null
+++ b/gfx/angle/src/compiler/translator/RemoveUnreferencedVariables.cpp
@@ -0,0 +1,359 @@
+//
+// 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();
+        if ((*mStructIdRefCounts)[structId] > 1u)
+        {
+            // 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, nullptr, 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)
+        {
+            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 (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/src/compiler/translator/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_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_
--- a/gfx/angle/src/compiler/translator/RewriteDoWhile.cpp
+++ b/gfx/angle/src/compiler/translator/RewriteDoWhile.cpp
@@ -4,16 +4,17 @@
 // 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"
 
 namespace sh
 {
 
 namespace
 {
 
@@ -65,39 +66,26 @@ class DoWhileRewriter : public TIntermTr
             TIntermLoop *loop      = statement->getAsLoopNode();
 
             if (loop == nullptr || loop->getType() != ELoopDoWhile)
             {
                 continue;
             }
 
             // Found a loop to change.
-            nextTemporaryId();
-
-            TType boolType = TType(EbtBool);
+            TType boolType(EbtBool);
+            TVariable *conditionVariable = CreateTempVariable(mSymbolTable, boolType);
 
             // bool temp = false;
-            TIntermDeclaration *tempDeclaration = nullptr;
-            {
-                TConstantUnion *falseConstant = new TConstantUnion();
-                falseConstant->setBConst(false);
-                TIntermTyped *falseValue = new TIntermConstantUnion(falseConstant, boolType);
-
-                tempDeclaration = createTempInitDeclaration(falseValue);
-            }
+            TIntermDeclaration *tempDeclaration =
+                CreateTempInitDeclarationNode(conditionVariable, CreateBoolNode(false));
 
             // temp = true;
-            TIntermBinary *assignTrue = nullptr;
-            {
-                TConstantUnion *trueConstant = new TConstantUnion();
-                trueConstant->setBConst(true);
-                TIntermTyped *trueValue = new TIntermConstantUnion(trueConstant, boolType);
-
-                assignTrue = createTempAssignment(trueValue);
-            }
+            TIntermBinary *assignTrue =
+                CreateTempAssignmentNode(conditionVariable, CreateBoolNode(true));
 
             // if (temp) {
             //   if (!CONDITION) {
             //     break;
             //   }
             // }
             TIntermIfElse *breakIf = nullptr;
             {
@@ -109,37 +97,34 @@ class DoWhileRewriter : public TIntermTr
                 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(createTempSymbol(boolType), innerIfBlock, nullptr);
+                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;
             {
-                TConstantUnion *trueConstant = new TConstantUnion();
-                trueConstant->setBConst(true);
-                TIntermTyped *trueValue = new TIntermConstantUnion(trueConstant, boolType);
-
                 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, trueValue, nullptr, body);
+                newLoop = new TIntermLoop(ELoopWhile, nullptr, CreateBoolNode(true), nullptr, body);
             }
 
             TIntermSequence replacement;
             replacement.push_back(tempDeclaration);
             replacement.push_back(newLoop);
 
             node->replaceChildNodeWithMultiple(loop, replacement);
         }
--- a/gfx/angle/src/compiler/translator/RewriteElseBlocks.cpp
+++ b/gfx/angle/src/compiler/translator/RewriteElseBlocks.cpp
@@ -64,19 +64,19 @@ bool ElseBlockRewriter::visitBlock(Visit
     }
     return true;
 }
 
 TIntermNode *ElseBlockRewriter::rewriteIfElse(TIntermIfElse *ifElse)
 {
     ASSERT(ifElse != nullptr);
 
-    nextTemporaryId();
-
-    TIntermDeclaration *storeCondition = createTempInitDeclaration(ifElse->getCondition());
+    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;
@@ -86,24 +86,24 @@ TIntermNode *ElseBlockRewriter::rewriteI
         // 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 = createTempSymbol(boolType);
+        TIntermSymbol *conditionSymbolElse = CreateTempSymbolNode(conditionVariable);
         TIntermUnary *negatedCondition     = new TIntermUnary(EOpLogicalNot, conditionSymbolElse);
         TIntermIfElse *falseIfElse =
             new TIntermIfElse(negatedCondition, ifElse->getFalseBlock(), negatedElse);
         falseBlock = EnsureBlock(falseIfElse);
     }
 
-    TIntermSymbol *conditionSymbolSel = createTempSymbol(boolType);
+    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;
--- a/gfx/angle/src/compiler/translator/RewriteTexelFetchOffset.cpp
+++ b/gfx/angle/src/compiler/translator/RewriteTexelFetchOffset.cpp
@@ -67,17 +67,18 @@ bool Traverser::visitAggregate(Visit vis
     }
 
     // Decide if the node represents the call of texelFetchOffset.
     if (node->getOp() != EOpCallBuiltInFunction)
     {
         return true;
     }
 
-    if (node->getFunctionSymbolInfo()->getName() != "texelFetchOffset")
+    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);
 
--- a/gfx/angle/src/compiler/translator/RunAtTheEndOfShader.cpp
+++ b/gfx/angle/src/compiler/translator/RunAtTheEndOfShader.cpp
@@ -61,43 +61,43 @@ bool ContainsReturn(TIntermNode *node)
 }
 
 void WrapMainAndAppend(TIntermBlock *root,
                        TIntermFunctionDefinition *main,
                        TIntermNode *codeToRun,
                        TSymbolTable *symbolTable)
 {
     // Replace main() with main0() with the same body.
-    TSymbolUniqueId oldMainId(symbolTable);
-    std::stringstream oldMainName;
-    oldMainName << "main" << oldMainId.get();
-    TIntermFunctionDefinition *oldMain = CreateInternalFunctionDefinitionNode(
-        TType(EbtVoid), oldMainName.str().c_str(), main->getBody(), oldMainId);
+    TFunction *oldMain =
+        new TFunction(symbolTable, nullptr, new TType(EbtVoid), SymbolType::AngleInternal, false);
+    TIntermFunctionDefinition *oldMainDefinition =
+        CreateInternalFunctionDefinitionNode(*oldMain, main->getBody());
 
-    bool replaced = root->replaceChildNode(main, oldMain);
+    bool replaced = root->replaceChildNode(main, oldMainDefinition);
     ASSERT(replaced);
 
     // void main()
-    TIntermFunctionPrototype *newMainProto = new TIntermFunctionPrototype(
-        TType(EbtVoid), main->getFunctionPrototype()->getFunctionSymbolInfo()->getId());
-    newMainProto->getFunctionSymbolInfo()->setName("main");
+    TFunction *newMain = new TFunction(symbolTable, NewPoolTString("main"), new TType(EbtVoid),
+                                       SymbolType::UserDefined, false);
+    TIntermFunctionPrototype *newMainProto = new TIntermFunctionPrototype(newMain);
 
     // {
     //     main0();
     //     codeToRun
     // }
     TIntermBlock *newMainBody     = new TIntermBlock();
-    TIntermAggregate *oldMainCall = CreateInternalFunctionCallNode(
-        TType(EbtVoid), oldMainName.str().c_str(), oldMainId, new TIntermSequence());
+    TIntermAggregate *oldMainCall =
+        TIntermAggregate::CreateFunctionCall(*oldMain, new TIntermSequence());
     newMainBody->appendStatement(oldMainCall);
     newMainBody->appendStatement(codeToRun);
 
     // Add the new main() to the root node.
-    TIntermFunctionDefinition *newMain = new TIntermFunctionDefinition(newMainProto, newMainBody);
-    root->appendStatement(newMain);
+    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))
--- a/gfx/angle/src/compiler/translator/ScalarizeVecAndMatConstructorArgs.cpp
+++ b/gfx/angle/src/compiler/translator/ScalarizeVecAndMatConstructorArgs.cpp
@@ -10,47 +10,26 @@
 
 #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
 {
 
-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;
-}
-
 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);
@@ -61,17 +40,18 @@ TIntermBinary *ConstructMatrixIndexBinar
 class ScalarizeArgsTraverser : public TIntermTraverser
 {
   public:
     ScalarizeArgsTraverser(sh::GLenum shaderType,
                            bool fragmentPrecisionHigh,
                            TSymbolTable *symbolTable)
         : TIntermTraverser(true, false, false, symbolTable),
           mShaderType(shaderType),
-          mFragmentPrecisionHigh(fragmentPrecisionHigh)
+          mFragmentPrecisionHigh(fragmentPrecisionHigh),
+          mNodesToScalarize(IntermNodePatternMatcher::kScalarizedVecOrMatConstructor)
     {
     }
 
   protected:
     bool visitAggregate(Visit visit, TIntermAggregate *node) override;
     bool visitBlock(Visit visit, TIntermBlock *node) override;
 
   private:
@@ -81,32 +61,40 @@ class ScalarizeArgsTraverser : public TI
     //   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.
-    void createTempVariable(TIntermTyped *original);
+    TVariable *createTempVariable(TIntermTyped *original);
 
     std::vector<TIntermSequence> mBlockStack;
 
     sh::GLenum mShaderType;
     bool mFragmentPrecisionHigh;
+
+    IntermNodePatternMatcher mNodesToScalarize;
 };
 
 bool ScalarizeArgsTraverser::visitAggregate(Visit visit, TIntermAggregate *node)
 {
-    if (visit == PreVisit && node->getOp() == EOpConstruct)
+    ASSERT(visit == PreVisit);
+    if (mNodesToScalarize.match(node, getParentNode()))
     {
-        if (node->getType().isVector() && ContainsMatrixNode(*(node->getSequence())))
+        if (node->getType().isVector())
+        {
             scalarizeArgs(node, false, true);
-        else if (node->getType().isMatrix() && ContainsVectorNode(*(node->getSequence())))
+        }
+        else
+        {
+            ASSERT(node->getType().isMatrix());
             scalarizeArgs(node, true, false);
+        }
     }
     return true;
 }
 
 bool ScalarizeArgsTraverser::visitBlock(Visit visit, TIntermBlock *node)
 {
     mBlockStack.push_back(TIntermSequence());
     {
@@ -129,104 +117,105 @@ bool ScalarizeArgsTraverser::visitBlock(
 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 original(*sequence);
+    TIntermSequence originalArgs(*sequence);
     sequence->clear();
-    for (size_t ii = 0; ii < original.size(); ++ii)
+    for (TIntermNode *originalArgNode : originalArgs)
     {
         ASSERT(size > 0);
-        TIntermTyped *node = original[ii]->getAsTyped();
-        ASSERT(node);
-        createTempVariable(node);
-        if (node->isScalar())
+        TIntermTyped *originalArg = originalArgNode->getAsTyped();
+        ASSERT(originalArg);
+        TVariable *argVariable = createTempVariable(originalArg);
+        if (originalArg->isScalar())
         {
-            sequence->push_back(createTempSymbol(node->getType()));
+            sequence->push_back(CreateTempSymbolNode(argVariable));
             size--;
         }
-        else if (node->isVector())
+        else if (originalArg->isVector())
         {
             if (scalarizeVector)
             {
-                int repeat = std::min(size, node->getNominalSize());
+                int repeat = std::min(size, originalArg->getNominalSize());
                 size -= repeat;
                 for (int index = 0; index < repeat; ++index)
                 {
-                    TIntermSymbol *symbolNode = createTempSymbol(node->getType());
+                    TIntermSymbol *symbolNode = CreateTempSymbolNode(argVariable);
                     TIntermBinary *newNode    = ConstructVectorIndexBinaryNode(symbolNode, index);
                     sequence->push_back(newNode);
                 }
             }
             else
             {
-                TIntermSymbol *symbolNode = createTempSymbol(node->getType());
+                TIntermSymbol *symbolNode = CreateTempSymbolNode(argVariable);
                 sequence->push_back(symbolNode);
-                size -= node->getNominalSize();
+                size -= originalArg->getNominalSize();
             }
         }
         else
         {
-            ASSERT(node->isMatrix());
+            ASSERT(originalArg->isMatrix());
             if (scalarizeMatrix)
             {
                 int colIndex = 0, rowIndex = 0;
-                int repeat = std::min(size, node->getCols() * node->getRows());
+                int repeat = std::min(size, originalArg->getCols() * originalArg->getRows());
                 size -= repeat;
                 while (repeat > 0)
                 {
-                    TIntermSymbol *symbolNode = createTempSymbol(node->getType());
+                    TIntermSymbol *symbolNode = CreateTempSymbolNode(argVariable);
                     TIntermBinary *newNode =
                         ConstructMatrixIndexBinaryNode(symbolNode, colIndex, rowIndex);
                     sequence->push_back(newNode);
                     rowIndex++;
-                    if (rowIndex >= node->getRows())
+                    if (rowIndex >= originalArg->getRows())
                     {
                         rowIndex = 0;
                         colIndex++;
                     }
                     repeat--;
                 }
             }
             else
             {
-                TIntermSymbol *symbolNode = createTempSymbol(node->getType());
+                TIntermSymbol *symbolNode = CreateTempSymbolNode(argVariable);
                 sequence->push_back(symbolNode);
-                size -= node->getCols() * node->getRows();
+                size -= originalArg->getCols() * originalArg->getRows();
             }
         }
     }
 }
 
-void ScalarizeArgsTraverser::createTempVariable(TIntermTyped *original)
+TVariable *ScalarizeArgsTraverser::createTempVariable(TIntermTyped *original)
 {
     ASSERT(original);
-    nextTemporaryId();
-    TIntermDeclaration *decl = createTempInitDeclaration(original);
 
-    TType type = original->getType();
+    TType type(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.
-        TIntermBinary *init = decl->getSequence()->at(0)->getAsBinaryNode();
-        init->getTypePointer()->setPrecision(mFragmentPrecisionHigh ? EbpHigh : EbpMedium);
-        init->getLeft()->getTypePointer()->setPrecision(mFragmentPrecisionHigh ? EbpHigh
-                                                                               : EbpMedium);
+        type.setPrecision(mFragmentPrecisionHigh ? EbpHigh : EbpMedium);
     }
 
+    TVariable *variable = CreateTempVariable(mSymbolTable, type);
+
     ASSERT(mBlockStack.size() > 0);
     TIntermSequence &sequence = mBlockStack.back();
-    sequence.push_back(decl);
+    TIntermDeclaration *declaration = CreateTempInitDeclarationNode(variable, original);
+    sequence.push_back(declaration);
+
+    return variable;
 }
 
 }  // namespace anonymous
 
 void ScalarizeVecAndMatConstructorArgs(TIntermBlock *root,
                                        sh::GLenum shaderType,
                                        bool fragmentPrecisionHigh,
                                        TSymbolTable *symbolTable)
deleted file mode 100644
--- a/gfx/angle/src/compiler/translator/SearchSymbol.cpp
+++ /dev/null
@@ -1,38 +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.
-//
-// SearchSymbol is an AST traverser to detect the use of a given symbol name
-//
-
-#include "compiler/translator/SearchSymbol.h"
-
-#include "compiler/translator/InfoSink.h"
-
-namespace sh
-{
-SearchSymbol::SearchSymbol(const TString &symbol)
-    : TIntermTraverser(true, false, false), mSymbol(symbol)
-{
-    match = false;
-}
-
-void SearchSymbol::traverse(TIntermNode *node)
-{
-    node->traverse(this);
-}
-
-void SearchSymbol::visitSymbol(TIntermSymbol *symbolNode)
-{
-    if (symbolNode->getSymbol() == mSymbol)
-    {
-        match = true;
-    }
-}
-
-bool SearchSymbol::foundMatch() const
-{
-    return match;
-}
-}
deleted file mode 100644
--- a/gfx/angle/src/compiler/translator/SearchSymbol.h
+++ /dev/null
@@ -1,33 +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.
-//
-// SearchSymbol is an AST traverser to detect the use of a given symbol name
-//
-
-#ifndef COMPILER_TRANSLATOR_SEARCHSYMBOL_H_
-#define COMPILER_TRANSLATOR_SEARCHSYMBOL_H_
-
-#include "compiler/translator/IntermTraverse.h"
-#include "compiler/translator/ParseContext.h"
-
-namespace sh
-{
-class SearchSymbol : public TIntermTraverser
-{
-  public:
-    SearchSymbol(const TString &symbol);
-
-    void traverse(TIntermNode *node);
-    void visitSymbol(TIntermSymbol *symbolNode) override;
-
-    bool foundMatch() const;
-
-  protected:
-    const TString &mSymbol;
-    bool match;
-};
-}
-
-#endif  // COMPILER_TRANSLATOR_SEARCHSYMBOL_H_
--- a/gfx/angle/src/compiler/translator/SeparateExpressionsReturningArrays.cpp
+++ b/gfx/angle/src/compiler/translator/SeparateExpressionsReturningArrays.cpp
@@ -7,16 +7,17 @@
 // 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
 {
 
@@ -68,49 +69,52 @@ bool SeparateExpressionsTraverser::visit
 
     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.
-    insertions.push_back(createTempInitDeclaration(node->getLeft()));
+    TIntermDeclaration *arrayVariableDeclaration;
+    TVariable *arrayVariable =
+        DeclareTempVariable(mSymbolTable, node->getLeft(), EvqTemporary, &arrayVariableDeclaration);
+    insertions.push_back(arrayVariableDeclaration);
     insertStatementsInParentBlock(insertions);
 
-    queueReplacement(createTempSymbol(node->getType()), OriginalNode::IS_DROPPED);
+    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;
 
-    TIntermSequence insertions;
-    insertions.push_back(createTempInitDeclaration(node->shallowCopy()));
-    insertStatementsInParentBlock(insertions);
+    TIntermDeclaration *arrayVariableDeclaration;
+    TVariable *arrayVariable = DeclareTempVariable(mSymbolTable, node->shallowCopy(), EvqTemporary,
+                                                   &arrayVariableDeclaration);
+    insertStatementInParentBlock(arrayVariableDeclaration);
 
-    queueReplacement(createTempSymbol(node->getType()), OriginalNode::IS_DROPPED);
+    queueReplacement(CreateTempSymbolNode(arrayVariable), OriginalNode::IS_DROPPED);
 
     return false;
 }
 
 void SeparateExpressionsTraverser::nextIteration()
 {
     mFoundArrayExpression = false;
-    nextTemporaryId();
 }
 
 }  // namespace
 
 void SeparateExpressionsReturningArrays(TIntermNode *root, TSymbolTable *symbolTable)
 {
     SeparateExpressionsTraverser traverser(symbolTable);
     // Separate one expression at a time, and reset the traverser between iterations.
--- a/gfx/angle/src/compiler/translator/ShaderLang.cpp
+++ b/gfx/angle/src/compiler/translator/ShaderLang.cpp
@@ -107,16 +107,45 @@ TranslatorHLSL *GetTranslatorHLSLFromHan
 {
     if (!handle)
         return nullptr;
     TShHandleBase *base = static_cast<TShHandleBase *>(handle);
     return base->getAsTranslatorHLSL();
 }
 #endif  // ANGLE_ENABLE_HLSL
 
+GLenum GetGeometryShaderPrimitiveTypeEnum(sh::TLayoutPrimitiveType primitiveType)
+{
+    switch (primitiveType)
+    {
+        case EptPoints:
+            return GL_POINTS;
+        case EptLines:
+            return GL_LINES;
+        case EptLinesAdjacency:
+            return GL_LINES_ADJACENCY_EXT;
+        case EptTriangles:
+            return GL_TRIANGLES;
+        case EptTrianglesAdjacency:
+            return GL_TRIANGLES_ADJACENCY_EXT;
+
+        case EptLineStrip:
+            return GL_LINE_STRIP;
+        case EptTriangleStrip:
+            return GL_TRIANGLE_STRIP;
+
+        case EptUndefined:
+            return GL_INVALID_VALUE;
+
+        default:
+            UNREACHABLE();
+            return GL_INVALID_VALUE;
+    }
+}
+
 }  // anonymous namespace
 
 //
 // Driver must call this first, once, before doing any other compiler operations.
 // Subsequent calls to this function are no-op.
 //
 bool Initialize()
 {
@@ -169,17 +198,17 @@ void InitBuiltInResources(ShBuiltInResou
     resources->EXT_frag_depth                  = 0;
     resources->EXT_shader_texture_lod          = 0;
     resources->WEBGL_debug_shader_precision    = 0;
     resources->EXT_shader_framebuffer_fetch    = 0;
     resources->NV_shader_framebuffer_fetch     = 0;
     resources->ARM_shader_framebuffer_fetch    = 0;
     resources->OVR_multiview                   = 0;
     resources->EXT_YUV_target                  = 0;
-    resources->OES_geometry_shader             = 0;
+    resources->EXT_geometry_shader             = 0;
 
     resources->NV_draw_buffers = 0;
 
     // Disable highp precision in fragment shader by default.
     resources->FragmentPrecisionHigh = 0;
 
     // GLSL ES 3.0 constants.
     resources->MaxVertexOutputVectors  = 16;
@@ -238,16 +267,17 @@ void InitBuiltInResources(ShBuiltInResou
     resources->MaxAtomicCounterBindings  = 1;
 
     resources->MaxVertexAtomicCounterBuffers   = 0;
     resources->MaxFragmentAtomicCounterBuffers = 0;
     resources->MaxCombinedAtomicCounterBuffers = 1;
     resources->MaxAtomicCounterBufferSize      = 32;
 
     resources->MaxUniformBufferBindings = 32;
+    resources->MaxShaderStorageBufferBindings = 4;
 
     resources->MaxGeometryUniformComponents     = 1024;
     resources->MaxGeometryUniformBlocks         = 12;
     resources->MaxGeometryInputComponents       = 64;
     resources->MaxGeometryOutputComponents      = 64;
     resources->MaxGeometryOutputVertices        = 256;
     resources->MaxGeometryTotalOutputComponents = 1024;
     resources->MaxGeometryTextureImageUnits     = 16;
@@ -496,9 +526,53 @@ const std::map<std::string, unsigned int
     ASSERT(translator);
 
     return translator->getUniformRegisterMap();
 #else
     return nullptr;
 #endif  // ANGLE_ENABLE_HLSL
 }
 
+GLenum GetGeometryShaderInputPrimitiveType(const ShHandle handle)
+{
+    ASSERT(handle);
+
+    TShHandleBase *base = static_cast<TShHandleBase *>(handle);
+    TCompiler *compiler = base->getAsCompiler();
+    ASSERT(compiler);
+
+    return GetGeometryShaderPrimitiveTypeEnum(compiler->getGeometryShaderInputPrimitiveType());
+}
+
+GLenum GetGeometryShaderOutputPrimitiveType(const ShHandle handle)
+{
+    ASSERT(handle);
+
+    TShHandleBase *base = static_cast<TShHandleBase *>(handle);
+    TCompiler *compiler = base->getAsCompiler();
+    ASSERT(compiler);
+
+    return GetGeometryShaderPrimitiveTypeEnum(compiler->getGeometryShaderOutputPrimitiveType());
+}
+
+int GetGeometryShaderInvocations(const ShHandle handle)
+{
+    ASSERT(handle);
+
+    TShHandleBase *base = static_cast<TShHandleBase *>(handle);
+    TCompiler *compiler = base->getAsCompiler();
+    ASSERT(compiler);
+
+    return compiler->getGeometryShaderInvocations();
+}
+
+int GetGeometryShaderMaxVertices(const ShHandle handle)
+{
+    ASSERT(handle);
+
+    TShHandleBase *base = static_cast<TShHandleBase *>(handle);
+    TCompiler *compiler = base->getAsCompiler();
+    ASSERT(compiler);
+
+    return compiler->getGeometryShaderMaxVertices();
+}
+
 }  // namespace sh
--- a/gfx/angle/src/compiler/translator/ShaderVars.cpp
+++ b/gfx/angle/src/compiler/translator/ShaderVars.cpp
@@ -5,16 +5,17 @@
 //
 // ShaderVars.cpp:
 //  Methods for GL variable types (varyings, uniforms, etc)
 //
 
 #include <GLSLANG/ShaderLang.h>
 
 #include "common/debug.h"
+#include "common/utilities.h"
 
 namespace sh
 {
 
 namespace
 {
 
 InterpolationType GetNonAuxiliaryInterpolationType(InterpolationType interpolation)
@@ -25,71 +26,124 @@ InterpolationType GetNonAuxiliaryInterpo
 // The ES 3.0 spec is not clear on this point, but the ES 3.1 spec, and discussion
 // on Khronos.org, clarifies that a smooth/flat mismatch produces a link error,
 // but auxiliary qualifier mismatch (centroid) does not.
 bool InterpolationTypesMatch(InterpolationType a, InterpolationType b)
 {
     return (GetNonAuxiliaryInterpolationType(a) == GetNonAuxiliaryInterpolationType(b));
 }
 
-ShaderVariable::ShaderVariable() : type(0), precision(0), arraySize(0), staticUse(false)
+ShaderVariable::ShaderVariable()
+    : type(0), precision(0), flattenedOffsetInParentArrays(0), staticUse(false)
+{
+}
+
+ShaderVariable::ShaderVariable(GLenum typeIn)
+    : type(typeIn), precision(0), flattenedOffsetInParentArrays(0), staticUse(false)
 {
 }
 
 ShaderVariable::ShaderVariable(GLenum typeIn, unsigned int arraySizeIn)
-    : type(typeIn), precision(0), arraySize(arraySizeIn), staticUse(false)
+    : type(typeIn), precision(0), flattenedOffsetInParentArrays(0), staticUse(false)
 {
+    ASSERT(arraySizeIn != 0);
+    arraySizes.push_back(arraySizeIn);
 }
 
 ShaderVariable::~ShaderVariable()
 {
 }
 
 ShaderVariable::ShaderVariable(const ShaderVariable &other)
     : type(other.type),
       precision(other.precision),
       name(other.name),
       mappedName(other.mappedName),
-      arraySize(other.arraySize),
+      arraySizes(other.arraySizes),
+      flattenedOffsetInParentArrays(other.flattenedOffsetInParentArrays),
       staticUse(other.staticUse),
       fields(other.fields),
       structName(other.structName)
 {
 }
 
 ShaderVariable &ShaderVariable::operator=(const ShaderVariable &other)
 {
     type       = other.type;
     precision  = other.precision;
     name       = other.name;
     mappedName = other.mappedName;
-    arraySize  = other.arraySize;
+    arraySizes                    = other.arraySizes;
     staticUse  = other.staticUse;
+    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 || arraySize != other.arraySize ||
+        mappedName != other.mappedName || arraySizes != other.arraySizes ||
         staticUse != other.staticUse || 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;
     }
     return true;
 }
 
+void ShaderVariable::setArraySize(unsigned int size)
+{
+    arraySizes.clear();
+    if (size != 0)
+    {
+        arraySizes.push_back(size);
+    }
+}
+
+unsigned int ShaderVariable::getArraySizeProduct() const
+{
+    return gl::ArraySizeProduct(arraySizes);
+}
+
+void ShaderVariable::indexIntoArray(unsigned int arrayIndex)
+{
+    ASSERT(isArray());
+    flattenedOffsetInParentArrays =
+        arrayIndex + getOutermostArraySize() * flattenedOffsetInParentArrays;
+    arraySizes.pop_back();
+}
+
+unsigned int ShaderVariable::getNestedArraySize(unsigned int arrayNestingIndex) const
+{
+    ASSERT(arraySizes.size() > arrayNestingIndex);
+    return arraySizes[arraySizes.size() - 1u - arrayNestingIndex];
+}
+
+unsigned int ShaderVariable::getBasicTypeElementCount() const
+{
+    // GLES 3.1 Nov 2016 section 7.3.1.1 page 77 specifies that a separate entry should be generated
+    // for each array element when dealing with an array of arrays or an array of structs.
+    ASSERT(!isArrayOfArrays());
+    ASSERT(!isStruct() || !isArray());
+
+    // GLES 3.1 Nov 2016 page 82.
+    if (isArray())
+    {
+        return getOutermostArraySize();
+    }
+    return 1u;
+}
+
 bool ShaderVariable::findInfoByMappedName(const std::string &mappedFullName,
                                           const ShaderVariable **leafVar,
                                           std::string *originalFullName) const
 {
     ASSERT(leafVar && originalFullName);
     // There are three cases:
     // 1) the top variable is of struct type;
     // 2) the top variable is an array;
@@ -150,28 +204,33 @@ bool ShaderVariable::findInfoByMappedNam
                 *leafVar          = fieldVar;
                 return true;
             }
         }
         return false;
     }
 }
 
+bool ShaderVariable::isBuiltIn() const
+{
+    return (name.size() >= 4 && name[0] == 'g' && name[1] == 'l' && name[2] == '_');
+}
+
 bool ShaderVariable::isSameVariableAtLinkTime(const ShaderVariable &other,
                                               bool matchPrecision,
                                               bool matchName) const
 {
     if (type != other.type)
         return false;
     if (matchPrecision && precision != other.precision)
         return false;
     if (matchName && name != other.name)
         return false;
     ASSERT(!matchName || mappedName == other.mappedName);
-    if (arraySize != other.arraySize)
+    if (arraySizes != other.arraySizes)
         return false;
     if (fields.size() != other.fields.size())
         return false;
 
     // [OpenGL ES 3.1 SPEC Chapter 7.4.1]
     // Variables declared as structures are considered to match in type if and only if structure
     // members match in name, type, qualification, and declaration order.
     for (size_t ii = 0; ii < fields.size(); ++ii)
@@ -181,41 +240,48 @@ bool ShaderVariable::isSameVariableAtLin
             return false;
         }
     }
     if (structName != other.structName)
         return false;
     return true;
 }
 
-Uniform::Uniform() : binding(-1), offset(-1)
+Uniform::Uniform() : binding(-1), offset(-1), readonly(false), writeonly(false)
+
 {
 }
 
 Uniform::~Uniform()
 {
 }
 
 Uniform::Uniform(const Uniform &other)
-    : VariableWithLocation(other), binding(other.binding), offset(other.offset)
+    : VariableWithLocation(other),
+      binding(other.binding),
+      offset(other.offset),
+      readonly(other.readonly),
+      writeonly(other.writeonly)
 {
 }
 
 Uniform &Uniform::operator=(const Uniform &other)
 {
     VariableWithLocation::operator=(other);
     binding                 = other.binding;
     offset                        = other.offset;
+    readonly                      = other.readonly;
+    writeonly                     = other.writeonly;
     return *this;
 }
 
 bool Uniform::operator==(const Uniform &other) const
 {
     return VariableWithLocation::operator==(other) && binding == other.binding &&
-           offset == other.offset;
+           offset == other.offset && readonly == other.readonly && writeonly == other.writeonly;
 }
 
 bool Uniform::isSameUniformAtLinkTime(const Uniform &other) const
 {
     // Enforce a consistent match.
     // https://cvs.khronos.org/bugzilla/show_bug.cgi?id=16261
     if (binding != -1 && other.binding != -1 && binding != other.binding)
     {
@@ -224,16 +290,20 @@ bool Uniform::isSameUniformAtLinkTime(co
     if (location != -1 && other.location != -1 && location != other.location)
     {
         return false;
     }
     if (offset != other.offset)
     {
         return false;
     }
+    if (readonly != other.readonly || writeonly != other.writeonly)
+    {
+        return false;
+    }
     return VariableWithLocation::isSameVariableAtLinkTime(other, true, true);
 }
 
 VariableWithLocation::VariableWithLocation() : location(-1)
 {
 }
 
 VariableWithLocation::~VariableWithLocation()
@@ -447,16 +517,21 @@ bool InterfaceBlock::isSameInterfaceBloc
         {
             return false;
         }
     }
 
     return true;
 }
 
+bool InterfaceBlock::isBuiltIn() const
+{
+    return (name.size() >= 4 && name[0] == 'g' && name[1] == 'l' && name[2] == '_');
+}
+
 void WorkGroupSize::fill(int fillValue)
 {
     localSizeQualifiers[0] = fillValue;
     localSizeQualifiers[1] = fillValue;
     localSizeQualifiers[2] = fillValue;
 }
 
 void WorkGroupSize::setLocalSize(int localSizeX, int localSizeY, int localSizeZ)
--- a/gfx/angle/src/compiler/translator/SimplifyLoopConditions.cpp
+++ b/gfx/angle/src/compiler/translator/SimplifyLoopConditions.cpp
@@ -146,74 +146,75 @@ void SimplifyLoopConditionsTraverser::tr
     {
         node->getExpression()->traverse(this);
     }
 
     mInsideLoopInitConditionOrExpression = false;
 
     if (mFoundLoopToChange)
     {
-        nextTemporaryId();
+        TType boolType(EbtBool, EbpUndefined, EvqTemporary);
+        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; }
-            TIntermSequence tempInitSeq;
-            tempInitSeq.push_back(createTempInitDeclaration(node->getCondition()->deepCopy()));
-            insertStatementsInParentBlock(tempInitSeq);
+            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(
-                createTempAssignment(node->getCondition()->deepCopy()));
+                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(createTempSymbol(node->getCondition()->getType()));
+            node->setCondition(CreateTempSymbolNode(conditionVariable));
         }
         else if (loopType == ELoopDoWhile)
         {
             // Transform:
             //   do {
             //     body;
             //   } while (expr);
             // into
             //   bool s0 = true;
             //   do {
             //     { body; }
             //     s0 = expr;
             //   } while (s0);
-            TIntermSequence tempInitSeq;
-            tempInitSeq.push_back(createTempInitDeclaration(CreateBoolNode(true)));
-            insertStatementsInParentBlock(tempInitSeq);
+            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(
-                createTempAssignment(node->getCondition()->deepCopy()));
+                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(createTempSymbol(node->getCondition()->getType()));
+            node->setCondition(CreateTempSymbolNode(conditionVariable));
         }
         else if (loopType == ELoopFor)
         {
             // Move the loop condition inside the loop.
             // Transform:
             //   for (init; expr; exprB) { body; }
             // into
             //   {
@@ -239,40 +240,41 @@ void SimplifyLoopConditionsTraverser::tr
             if (node->getCondition())
             {
                 conditionInitializer = node->getCondition()->deepCopy();
             }
             else
             {
                 conditionInitializer = CreateBoolNode(true);
             }
-            loopScopeSequence->push_back(createTempInitDeclaration(conditionInitializer));
+            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(
-                    createTempAssignment(node->getCondition()->deepCopy()));
+                    CreateTempAssignmentNode(conditionVariable, node->getCondition()->deepCopy()));
             }
 
             // Create "while(s0) { whileLoopBody }"
-            TIntermLoop *whileLoop = new TIntermLoop(
-                ELoopWhile, nullptr, createTempSymbol(conditionInitializer->getType()), nullptr,
-                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.
         }
--- a/gfx/angle/src/compiler/translator/SplitSequenceOperator.cpp
+++ b/gfx/angle/src/compiler/translator/SplitSequenceOperator.cpp
@@ -53,17 +53,16 @@ SplitSequenceOperatorTraverser::SplitSeq
       mPatternToSplitMatcher(patternsToSplitMask)
 {
 }
 
 void SplitSequenceOperatorTraverser::nextIteration()
 {
     mFoundExpressionToSplit = false;
     mInsideSequenceOperator = 0;
-    nextTemporaryId();
 }
 
 bool SplitSequenceOperatorTraverser::visitAggregate(Visit visit, TIntermAggregate *node)
 {
     if (mFoundExpressionToSplit)
         return false;
 
     if (mInsideSequenceOperator > 0 && visit == PreVisit)
new file mode 100644
--- /dev/null
+++ b/gfx/angle/src/compiler/translator/StaticType.cpp
@@ -0,0 +1,74 @@
+//
+// 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
new file mode 100644
--- /dev/null
+++ b/gfx/angle/src/compiler/translator/StaticType.h
@@ -0,0 +1,235 @@
+//
+// 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.
+//
+
+#ifndef COMPILER_TRANSLATOR_STATIC_TYPE_H_
+#define COMPILER_TRANSLATOR_STATIC_TYPE_H_
+
+#include "compiler/translator/Types.h"
+
+namespace sh
+{
+
+namespace StaticType
+{
+
+namespace Helpers
+{
+
+//
+// Generation and static allocation of type mangled name values.
+//
+
+// Size of the maximum possible constexpr-generated mangled name.
+// If this value is too small, the compiler will produce errors.
+static constexpr size_t kStaticMangledNameMaxLength = 10;
+
+// 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] = {};
+};
+
+// 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';
+    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,
+          TQualifier qualifier,
+          unsigned char primarySize,
+          unsigned char secondarySize>
+static constexpr StaticMangledName kMangledNameInstance =
+    BuildStaticMangledName(basicType, precision, qualifier, primarySize, secondarySize);
+
+//
+// Generation and static allocation of TType values.
+//
+
+// This "variable" contains every constexpr-generated TType.
+// If kInstance<B, P, Q, PS, SS> is used anywhere (specifally
+// in Get, below), this is where the appropriate type will be stored.
+template <TBasicType basicType,
+          TPrecision precision,
+          TQualifier qualifier,
+          unsigned char primarySize,
+          unsigned char secondarySize>
+static constexpr TType kInstance =
+    TType(basicType,
+          precision,
+          qualifier,
+          primarySize,
+          secondarySize,
+          kMangledNameInstance<basicType, precision, qualifier, primarySize, secondarySize>.name);
+
+}  // namespace Helpers
+
+//
+// Fully-qualified type lookup.
+//
+
+template <TBasicType basicType,
+          TPrecision precision,
+          TQualifier qualifier,
+          unsigned char primarySize,
+          unsigned char secondarySize>
+constexpr const TType *Get()
+{
+    static_assert(1 <= primarySize && primarySize <= 4, "primarySize out of bounds");
+    static_assert(1 <= secondarySize && secondarySize <= 4, "secondarySize out of bounds");
+    return &Helpers::kInstance<basicType, precision, qualifier, primarySize, secondarySize>;
+}
+
+//
+// Overloads
+//
+
+template <TBasicType basicType, unsigned char primarySize = 1, unsigned char secondarySize = 1>
+constexpr const TType *GetBasic()
+{
+    return Get<basicType, EbpUndefined, EvqGlobal, primarySize, secondarySize>();
+}
+
+template <TBasicType basicType,
+          TQualifier qualifier,
+          unsigned char primarySize   = 1,
+          unsigned char secondarySize = 1>
+const TType *GetQualified()
+{
+    return Get<basicType, EbpUndefined, qualifier, primarySize, secondarySize>();
+}
+
+// Dynamic lookup methods (convert runtime values to template args)
+
+namespace Helpers
+{
+
+// Helper which takes secondarySize statically but primarySize dynamically.
+template <TBasicType basicType,
+          TPrecision precision,
+          TQualifier qualifier,
+          unsigned char secondarySize>
+constexpr const TType *GetForVecMatHelper(unsigned char primarySize)
+{
+    static_assert(basicType == EbtFloat || basicType == EbtInt || basicType == EbtUInt ||
+                      basicType == EbtBool,
+                  "unsupported basicType");
+    switch (primarySize)
+    {
+        case 1:
+            return Get<basicType, precision, qualifier, 1, secondarySize>();
+        case 2:
+            return Get<basicType, precision, qualifier, 2, secondarySize>();
+        case 3:
+            return Get<basicType, precision, qualifier, 3, secondarySize>();
+        case 4:
+            return Get<basicType, precision, qualifier, 4, secondarySize>();
+        default:
+            UNREACHABLE();
+            return GetBasic<EbtVoid>();
+    }
+}
+
+}  // namespace Helpers
+
+template <TBasicType basicType,
+          TPrecision precision = EbpUndefined,
+          TQualifier qualifier = EvqGlobal>
+constexpr const TType *GetForVecMat(unsigned char primarySize, unsigned char secondarySize = 1)
+{
+    static_assert(basicType == EbtFloat || basicType == EbtInt || basicType == EbtUInt ||
+                      basicType == EbtBool,
+                  "unsupported basicType");
+    switch (secondarySize)
+    {
+        case 1:
+            return Helpers::GetForVecMatHelper<basicType, precision, qualifier, 1>(primarySize);
+        case 2:
+            return Helpers::GetForVecMatHelper<basicType, precision, qualifier, 2>(primarySize);
+        case 3:
+            return Helpers::GetForVecMatHelper<basicType, precision, qualifier, 3>(primarySize);
+        case 4:
+            return Helpers::GetForVecMatHelper<basicType, precision, qualifier, 4>(primarySize);
+        default:
+            UNREACHABLE();
+            return GetBasic<EbtVoid>();
+    }
+}
+
+template <TBasicType basicType, TPrecision precision = EbpUndefined>
+constexpr const TType *GetForVec(TQualifier qualifier, unsigned char size)
+{
+    switch (qualifier)
+    {
+        case EvqGlobal:
+            return Helpers::GetForVecMatHelper<basicType, precision, EvqGlobal, 1>(size);
+        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/src/compiler/translator/StructureHLSL.cpp
+++ b/gfx/angle/src/compiler/translator/StructureHLSL.cpp
@@ -1,27 +1,98 @@
 //
 // 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.
 //
 // StructureHLSL.cpp:
-//   Definitions of methods for HLSL translation of GLSL structures.
+//   HLSL translation of GLSL constructors and structures.
 //
 
 #include "compiler/translator/StructureHLSL.h"
 #include "common/utilities.h"
 #include "compiler/translator/OutputHLSL.h"
 #include "compiler/translator/Types.h"
 #include "compiler/translator/util.h"
 #include "compiler/translator/UtilsHLSL.h"
 
 namespace sh
 {
 
+namespace
+{
+
+TString Define(const TStructure &structure,
+               bool useHLSLRowMajorPacking,
+               bool useStd140Packing,
+               Std140PaddingHelper *padHelper)
+{
+    const TFieldList &fields = structure.fields();
+    const bool isNameless    = (structure.symbolType() == SymbolType::Empty);
+    const TString &structName =
+        QualifiedStructNameString(structure, useHLSLRowMajorPacking, useStd140Packing);
+    const TString declareString = (isNameless ? "struct" : "struct " + structName);
+
+    TString string;
+    string += declareString +
+              "\n"
+              "{\n";
+
+    for (const TField *field : fields)
+    {
+        const TType &fieldType = *field->type();
+        if (!IsSampler(fieldType.getBasicType()))
+        {
+            const TStructure *fieldStruct = fieldType.getStruct();
+            const TString &fieldTypeString =
+                fieldStruct ? QualifiedStructNameString(*fieldStruct, useHLSLRowMajorPacking,
+                                                        useStd140Packing)
+                            : TypeString(fieldType);
+
+            if (padHelper)
+            {
+                string += padHelper->prePaddingString(fieldType);
+            }
+
+            string += "    " + fieldTypeString + " " + DecorateField(field->name(), structure) +
+                      ArrayString(fieldType) + ";\n";
+
+            if (padHelper)
+            {
+                string += padHelper->postPaddingString(fieldType, useHLSLRowMajorPacking);
+            }
+        }
+    }
+
+    // Nameless structs do not finish with a semicolon and newline, to leave room for an instance
+    // variable
+    string += (isNameless ? "} " : "};\n");
+
+    return string;
+}
+
+TString WriteParameterList(const std::vector<TType> &parameters)
+{
+    TString parameterList;
+    for (size_t parameter = 0u; parameter < parameters.size(); parameter++)
+    {
+        const TType &paramType = parameters[parameter];
+
+        parameterList += TypeString(paramType) + " x" + str(parameter) + ArrayString(paramType);
+
+        if (parameter < parameters.size() - 1u)
+        {
+            parameterList += ", ";
+        }
+    }
+    return parameterList;
+}
+
+}  // anonymous namespace
+
 Std140PaddingHelper::Std140PaddingHelper(const std::map<TString, int> &structElementIndexes,
                                          unsigned *uniqueCounter)
     : mPaddingCounter(uniqueCounter), mElementIndex(0), mStructElementIndexes(&structElementIndexes)
 {
 }
 
 Std140PaddingHelper::Std140PaddingHelper(const Std140PaddingHelper &other)
     : mPaddingCounter(other.mPaddingCounter),
@@ -98,17 +169,17 @@ TString Std140PaddingHelper::prePaddingS
 TString Std140PaddingHelper::postPaddingString(const TType &type, bool useHLSLRowMajorPacking)
 {
     if (!type.isMatrix() && !type.isArray() && type.getBasicType() != EbtStruct)
     {
         return "";
     }
 
     int numComponents     = 0;
-    TStructure *structure = type.getStruct();
+    const TStructure *structure = type.getStruct();
 
     if (type.isMatrix())
     {
         // This method can also be called from structureString, which does not use layout
         // qualifiers.
         // Thus, use the method parameter for determining the matrix packing.
         //
         // Note HLSL row major packing corresponds to GL API column-major, and vice-versa, since we
@@ -154,206 +225,172 @@ Std140PaddingHelper StructureHLSL::getPa
 
 TString StructureHLSL::defineQualified(const TStructure &structure,
                                        bool useHLSLRowMajorPacking,
                                        bool useStd140Packing)
 {
     if (useStd140Packing)
     {
         Std140PaddingHelper padHelper = getPaddingHelper();
-        return define(structure, useHLSLRowMajorPacking, useStd140Packing, &padHelper);
+        return Define(structure, useHLSLRowMajorPacking, useStd140Packing, &padHelper);
     }
     else
     {
-        return define(structure, useHLSLRowMajorPacking, useStd140Packing, nullptr);
+        return Define(structure, useHLSLRowMajorPacking, useStd140Packing, nullptr);
     }
 }
 
 TString StructureHLSL::defineNameless(const TStructure &structure)
 {
-    return define(structure, false, false, nullptr);
+    return Define(structure, false, false, nullptr);
 }
 
-TString StructureHLSL::define(const TStructure &structure,
-                              bool useHLSLRowMajorPacking,
-                              bool useStd140Packing,
-                              Std140PaddingHelper *padHelper)
+StructureHLSL::DefinedStructs::iterator StructureHLSL::defineVariants(const TStructure &structure,
+                                                                      const TString &name)
 {
-    const TFieldList &fields = structure.fields();
-    const bool isNameless    = (structure.name() == "");
-    const TString &structName =
-        QualifiedStructNameString(structure, useHLSLRowMajorPacking, useStd140Packing);
-    const TString declareString = (isNameless ? "struct" : "struct " + structName);
+    ASSERT(mDefinedStructs.find(name) == mDefinedStructs.end());
 
-    TString string;
-    string += declareString +
-              "\n"
-              "{\n";
-
-    for (const TField *field : fields)
+    for (const TField *field : structure.fields())
     {
-        const TType &fieldType = *field->type();
-        if (!IsSampler(fieldType.getBasicType()))
+        const TType *fieldType = field->type();
+        if (fieldType->getBasicType() == EbtStruct)
         {
-            const TStructure *fieldStruct = fieldType.getStruct();
-            const TString &fieldTypeString =
-                fieldStruct ? QualifiedStructNameString(*fieldStruct, useHLSLRowMajorPacking,
-                                                        useStd140Packing)
-                            : TypeString(fieldType);
-
-            if (padHelper)
-            {
-                string += padHelper->prePaddingString(fieldType);
-            }
-
-            string += "    " + fieldTypeString + " " + DecorateField(field->name(), structure) +
-                      ArrayString(fieldType) + ";\n";
-
-            if (padHelper)
-            {
-                string += padHelper->postPaddingString(fieldType, useHLSLRowMajorPacking);
-            }
+            ensureStructDefined(*fieldType->getStruct());
         }
     }
 
-    // Nameless structs do not finish with a semicolon and newline, to leave room for an instance
-    // variable
-    string += (isNameless ? "} " : "};\n");
+    DefinedStructs::iterator addedStruct =
+        mDefinedStructs.insert(std::make_pair(name, new TStructProperties())).first;
+    // Add element index
+    storeStd140ElementIndex(structure, false);
+    storeStd140ElementIndex(structure, true);
+
+    const TString &structString = defineQualified(structure, false, false);
 
-    return string;
+    ASSERT(std::find(mStructDeclarations.begin(), mStructDeclarations.end(), structString) ==
+           mStructDeclarations.end());
+    // Add row-major packed struct for interface blocks
+    TString rowMajorString = "#pragma pack_matrix(row_major)\n" +
+                             defineQualified(structure, true, false) +
+                             "#pragma pack_matrix(column_major)\n";
+
+    TString std140String         = defineQualified(structure, false, true);
+    TString std140RowMajorString = "#pragma pack_matrix(row_major)\n" +
+                                   defineQualified(structure, true, true) +
+                                   "#pragma pack_matrix(column_major)\n";
+
+    mStructDeclarations.push_back(structString);
+    mStructDeclarations.push_back(rowMajorString);
+    mStructDeclarations.push_back(std140String);
+    mStructDeclarations.push_back(std140RowMajorString);
+    return addedStruct;
 }
 
-TString StructureHLSL::addConstructor(const TType &type,
-                                      const TString &name,
-                                      const TIntermSequence *parameters)
+void StructureHLSL::ensureStructDefined(const TStructure &structure)
 {
+    const TString name = StructNameString(structure);
+    if (name == "")
+    {
+        return;  // Nameless structures are not defined
+    }
+    if (mDefinedStructs.find(name) == mDefinedStructs.end())
+    {
+        defineVariants(structure, name);
+    }
+}
+
+TString StructureHLSL::addStructConstructor(const TStructure &structure)
+{
+    const TString name = StructNameString(structure);
+
     if (name == "")
     {
         return TString();  // Nameless structures don't have constructors
     }
 
-    if (type.getStruct() && mStructNames.find(name) != mStructNames.end())
+    auto definedStruct = mDefinedStructs.find(name);
+    if (definedStruct == mDefinedStructs.end())
+    {
+        definedStruct = defineVariants(structure, name);
+    }
+    const TString constructorFunctionName = TString(name) + "_ctor";
+    TString *constructor                  = &definedStruct->second->constructor;
+    if (!constructor->empty())
+    {
+        return constructorFunctionName;  // Already added
+    }
+    *constructor += name + " " + constructorFunctionName + "(";
+
+    std::vector<TType> ctorParameters;
+    const TFieldList &fields = structure.fields();
+    for (const TField *field : fields)
     {
-        return TString(name);  // Already added
+        const TType *fieldType = field->type();
+        if (!IsSampler(fieldType->getBasicType()))
+        {
+            ctorParameters.push_back(*fieldType);
+        }
     }
+    // Structs that have sampler members should not have constructor calls, and otherwise structs
+    // are guaranteed to be non-empty by the grammar. Structs can't contain empty declarations
+    // either.
+    ASSERT(!ctorParameters.empty());
+
+    *constructor += WriteParameterList(ctorParameters);
+
+    *constructor +=
+        ")\n"
+        "{\n"
+        "    " +
+        name + " structure = { ";
+
+    for (size_t parameterIndex = 0u; parameterIndex < ctorParameters.size(); ++parameterIndex)
+    {
+        *constructor += "x" + str(parameterIndex);
+        if (parameterIndex < ctorParameters.size() - 1u)
+        {
+            *constructor += ", ";
+        }
+    }
+    *constructor +=
+        "};\n"
+        "    return structure;\n"
+        "}\n";
+
+    return constructorFunctionName;
+}
+
+TString StructureHLSL::addBuiltInConstructor(const TType &type, const TIntermSequence *parameters)
+{
+    ASSERT(!type.isArray());
+    ASSERT(type.getStruct() == nullptr);
+    ASSERT(parameters);
 
     TType ctorType = type;
-    while (ctorType.isArray())
-    {
-        ctorType.toArrayElementType();
-    }
     ctorType.setPrecision(EbpHigh);
     ctorType.setQualifier(EvqTemporary);
 
-    typedef std::vector<TType> ParameterArray;
-    ParameterArray ctorParameters;
-
-    TString constructorFunctionName;
-
-    const TStructure *structure = type.getStruct();
-    if (structure)
-    {
-        const TFieldList &fields = structure->fields();
-        for (const TField *field : fields)
-        {
-            const TType *fieldType = field->type();
-            if (!IsSampler(fieldType->getBasicType()))
-            {
-                ctorParameters.push_back(*fieldType);
-            }
-            if (fieldType->getBasicType() == EbtStruct)
-            {
-                addConstructor(*fieldType, StructNameString(*fieldType->getStruct()), nullptr);
-            }
-        }
-
-        mStructNames.insert(name);
-
-        // Add element index
-        storeStd140ElementIndex(*structure, false);
-        storeStd140ElementIndex(*structure, true);
-
-        const TString &structString = defineQualified(*structure, false, false);
-
-        if (std::find(mStructDeclarations.begin(), mStructDeclarations.end(), structString) ==
-            mStructDeclarations.end())
-        {
-            // Add row-major packed struct for interface blocks
-            TString rowMajorString = "#pragma pack_matrix(row_major)\n" +
-                                     defineQualified(*structure, true, false) +
-                                     "#pragma pack_matrix(column_major)\n";
-
-            TString std140String         = defineQualified(*structure, false, true);
-            TString std140RowMajorString = "#pragma pack_matrix(row_major)\n" +
-                                           defineQualified(*structure, true, true) +
-                                           "#pragma pack_matrix(column_major)\n";
+    const TString constructorFunctionName =
+        TString(type.getBuiltInTypeNameString()) + "_ctor" + DisambiguateFunctionName(parameters);
+    TString constructor = TypeString(ctorType) + " " + constructorFunctionName + "(";
 
-            mStructDeclarations.push_back(structString);
-            mStructDeclarations.push_back(rowMajorString);
-            mStructDeclarations.push_back(std140String);
-            mStructDeclarations.push_back(std140RowMajorString);
-        }
-
-        constructorFunctionName = TString(name);
-    }
-    else if (parameters)
+    std::vector<TType> ctorParameters;
+    for (auto parameter : *parameters)
     {
-        for (auto parameter : *parameters)
-        {
-            const TType &paramType = parameter->getAsTyped()->getType();
-            ctorParameters.push_back(paramType);
-        }
-        constructorFunctionName = TString(name) + DisambiguateFunctionName(parameters);
+        const TType &paramType = parameter->getAsTyped()->getType();
+        ASSERT(!paramType.isArray());
+        ctorParameters.push_back(paramType);
     }
-    else
-        UNREACHABLE();
-
-    TString constructor;
-
-    if (ctorType.getStruct())
-    {
-        constructor += name + " " + name + "_ctor(";
-    }
-    else  // Built-in type
-    {
-        constructor += TypeString(ctorType) + " " + constructorFunctionName + "(";
-    }
-
-    for (unsigned int parameter = 0; parameter < ctorParameters.size(); parameter++)
-    {
-        const TType &paramType = ctorParameters[parameter];
-
-        constructor += TypeString(paramType) + " x" + str(parameter) + ArrayString(paramType);
-
-        if (parameter < ctorParameters.size() - 1)
-        {
-            constructor += ", ";
-        }
-    }
+    constructor += WriteParameterList(ctorParameters);
 
     constructor +=
         ")\n"
-        "{\n";
-
-    if (ctorType.getStruct())
-    {
-        constructor += "    " + name + " structure";
-        if (ctorParameters.empty())
-        {
-            constructor += ";\n";
-        }
-        else
-        {
-            constructor += " = { ";
-        }
-    }
-    else
-    {
-        constructor += "    return " + TypeString(ctorType) + "(";
-    }
+        "{\n"
+        "    return " +
+        TypeString(ctorType) + "(";
 
     if (ctorType.isMatrix() && ctorParameters.size() == 1)
     {
         int rows               = ctorType.getRows();
         int cols               = ctorType.getCols();
         const TType &parameter = ctorParameters[0];
 
         if (parameter.isScalar())
@@ -398,42 +435,28 @@ TString StructureHLSL::addConstructor(co
             ASSERT(rows == 2 && cols == 2 && parameter.isVector() &&
                    parameter.getNominalSize() == 4);
 
             constructor += "x0";
         }
     }
     else
     {
-        size_t remainingComponents = 0;
-        if (ctorType.getStruct())
-        {
-            remainingComponents = ctorParameters.size();
-        }
-        else
-        {
-            remainingComponents = ctorType.getObjectSize();
-        }
+        size_t remainingComponents = ctorType.getObjectSize();
         size_t parameterIndex = 0;
 
         while (remainingComponents > 0)
         {
             const TType &parameter     = ctorParameters[parameterIndex];
             const size_t parameterSize = parameter.getObjectSize();
             bool moreParameters        = parameterIndex + 1 < ctorParameters.size();
 
             constructor += "x" + str(parameterIndex);
 
-            if (ctorType.getStruct())
-            {
-                ASSERT(remainingComponents == 1 || moreParameters);
-
-                --remainingComponents;
-            }
-            else if (parameter.isScalar())
+            if (parameter.isScalar())
             {
                 remainingComponents -= parameter.getObjectSize();
             }
             else if (parameter.isVector())
             {
                 if (remainingComponents == parameterSize || moreParameters)
                 {
                     ASSERT(parameterSize <= remainingComponents);
@@ -499,65 +522,58 @@ TString StructureHLSL::addConstructor(co
                             constructor += ", x" + str(parameterIndex);
                         }
                     }
 
                     column++;
                 }
             }
             else
+            {
                 UNREACHABLE();
+            }
 
             if (moreParameters)
             {
                 parameterIndex++;
             }
 
             if (remainingComponents)
             {
                 constructor += ", ";
             }
         }
     }
 
-    if (ctorType.getStruct())
-    {
-        if (!ctorParameters.empty())
-        {
-            constructor += "};\n";
-        }
-        constructor +=
-            "    return structure;\n"
-            "}\n";
-    }
-    else
-    {
-        constructor +=
-            ");\n"
-            "}\n";
-    }
+    constructor +=
+        ");\n"
+        "}\n";
 
-    mConstructors.insert(constructor);
+    mBuiltInConstructors.insert(constructor);
 
     return constructorFunctionName;
 }
 
 std::string StructureHLSL::structsHeader() const
 {
     TInfoSinkBase out;
 
-    for (size_t structIndex = 0; structIndex < mStructDeclarations.size(); structIndex++)
+    for (auto &declaration : mStructDeclarations)
     {
-        out << mStructDeclarations[structIndex];
+        out << declaration;
     }
 
-    for (Constructors::const_iterator constructor = mConstructors.begin();
-         constructor != mConstructors.end(); constructor++)
+    for (auto &structure : mDefinedStructs)
     {
-        out << *constructor;
+        out << structure.second->constructor;
+    }
+
+    for (auto &constructor : mBuiltInConstructors)
+    {
+        out << constructor;
     }
 
     return out.str();
 }
 
 void StructureHLSL::storeStd140ElementIndex(const TStructure &structure,
                                             bool useHLSLRowMajorPacking)
 {
--- a/gfx/angle/src/compiler/translator/StructureHLSL.h
+++ b/gfx/angle/src/compiler/translator/StructureHLSL.h
@@ -1,15 +1,15 @@
 //
 // 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.
 //
 // StructureHLSL.h:
-//   Interfaces of methods for HLSL translation of GLSL structures.
+//   HLSL translation of GLSL constructors and structures.
 //
 
 #ifndef COMPILER_TRANSLATOR_STRUCTUREHLSL_H_
 #define COMPILER_TRANSLATOR_STRUCTUREHLSL_H_
 
 #include "compiler/translator/Common.h"
 #include "compiler/translator/IntermNode.h"
 
@@ -44,45 +44,55 @@ class Std140PaddingHelper
     const std::map<TString, int> *mStructElementIndexes;
 };
 
 class StructureHLSL : angle::NonCopyable
 {
   public:
     StructureHLSL();
 
-    // Returns the name of the constructor function. "name" parameter is the name of the type being
-    // constructed.
-    TString addConstructor(const TType &type,
-                           const TString &name,
-                           const TIntermSequence *parameters);
+    // Returns the name of the constructor function.
+    TString addStructConstructor(const TStructure &structure);
+    TString addBuiltInConstructor(const TType &type, const TIntermSequence *parameters);
+
+    static TString defineNameless(const TStructure &structure);
+    void ensureStructDefined(const TStructure &structure);
+
     std::string structsHeader() const;
 
-    TString defineQualified(const TStructure &structure,
-                            bool useHLSLRowMajorPacking,
-                            bool useStd140Packing);
-    static TString defineNameless(const TStructure &structure);
-
     Std140PaddingHelper getPaddingHelper();
 
   private:
     unsigned mUniquePaddingCounter;
 
     std::map<TString, int> mStd140StructElementIndexes;
 
-    typedef std::set<TString> StructNames;
-    StructNames mStructNames;
+    struct TStructProperties : public angle::NonCopyable
+    {
+        POOL_ALLOCATOR_NEW_DELETE();
+
+        TStructProperties() {}
 
-    typedef std::set<TString> Constructors;
-    Constructors mConstructors;
+        // Constructor is an empty string in case the struct doesn't have a constructor yet.
+        TString constructor;
+    };
 
+    // Map from struct name to struct properties.
+    typedef std::map<TString, TStructProperties *> DefinedStructs;
+    DefinedStructs mDefinedStructs;
+
+    // Struct declarations need to be kept in a vector instead of having them inside mDefinedStructs
+    // since maintaining the original order is necessary for nested structs.
     typedef std::vector<TString> StructDeclarations;
     StructDeclarations mStructDeclarations;
 
+    typedef std::set<TString> BuiltInConstructors;
+    BuiltInConstructors mBuiltInConstructors;
+
     void storeStd140ElementIndex(const TStructure &structure, bool useHLSLRowMajorPacking);
-    static TString define(const TStructure &structure,
-                          bool useHLSLRowMajorPacking,
-                          bool useStd140Packing,
-                          Std140PaddingHelper *padHelper);
+    TString defineQualified(const TStructure &structure,
+                            bool useHLSLRowMajorPacking,
+                            bool useStd140Packing);
+    DefinedStructs::iterator defineVariants(const TStructure &structure, const TString &name);
 };
 }
 
 #endif  // COMPILER_TRANSLATOR_STRUCTUREHLSL_H_
new file mode 100644
--- /dev/null
+++ b/gfx/angle/src/compiler/translator/Symbol.cpp
@@ -0,0 +1,198 @@
+//
+// 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.
+//
+// Symbol.cpp: Symbols representing variables, functions, structures and interface blocks.
+//
+
+#if defined(_MSC_VER)
+#pragma warning(disable : 4718)
+#endif
+
+#include "compiler/translator/Symbol.h"
+
+#include "compiler/translator/SymbolTable.h"
+
+namespace sh
+{
+
+namespace
+{
+
+static const char kFunctionMangledNameSeparator = '(';
+
+}  // anonymous namespace
+
+TSymbol::TSymbol(TSymbolTable *symbolTable,
+                 const TString *name,
+                 SymbolType symbolType,
+                 TExtension extension)
+    : mName(name),
+      mUniqueId(symbolTable->nextUniqueId()),
+      mSymbolType(symbolType),
+      mExtension(extension)
+{
+    ASSERT(mSymbolType == SymbolType::BuiltIn || mExtension == TExtension::UNDEFINED);
+    ASSERT(mName != nullptr || mSymbolType == SymbolType::AngleInternal ||
+           mSymbolType == SymbolType::NotResolved || mSymbolType == SymbolType::Empty);
+    ASSERT(mName == nullptr || *mName != "");
+}
+
+const TString &TSymbol::name() const
+{
+    if (mName != nullptr)
+    {
+        return *mName;
+    }
+    ASSERT(mSymbolType == SymbolType::AngleInternal);
+    TInfoSinkBase symbolNameOut;
+    symbolNameOut << "s" << mUniqueId.get();
+    return *NewPoolTString(symbolNameOut.c_str());
+}
+
+const TString &TSymbol::getMangledName() const
+{
+    ASSERT(mSymbolType != SymbolType::Empty);
+    return name();
+}
+
+TVariable::TVariable(TSymbolTable *symbolTable,
+                     const TString *name,
+                     const TType &t,
+                     SymbolType symbolType,
+                     TExtension extension)
+    : TSymbol(symbolTable, name, symbolType, extension), type(t), unionArray(nullptr)
+{
+}
+
+TStructure::TStructure(TSymbolTable *symbolTable,
+                       const TString *name,
+                       const TFieldList *fields,
+                       SymbolType symbolType)
+    : TSymbol(symbolTable, name, symbolType), TFieldListCollection(fields)
+{
+}
+
+void TStructure::createSamplerSymbols(const TString &namePrefix,
+                                      const TString &apiNamePrefix,
+                                      TVector<const TVariable *> *outputSymbols,
+                                      TMap<const TVariable *, TString> *outputSymbolsToAPINames,
+                                      TSymbolTable *symbolTable) const
+{
+    ASSERT(containsSamplers());
+    for (const auto *field : *mFields)
+    {
+        const TType *fieldType = field->type();
+        if (IsSampler(fieldType->getBasicType()) || fieldType->isStructureContainingSamplers())
+        {
+            TString fieldName    = namePrefix + "_" + field->name();
+            TString fieldApiName = apiNamePrefix + "." + field->name();
+            fieldType->createSamplerSymbols(fieldName, fieldApiName, outputSymbols,
+                                            outputSymbolsToAPINames, symbolTable);
+        }
+    }
+}
+
+void TStructure::setName(const TString &name)
+{
+    TString *mutableName = const_cast<TString *>(mName);
+    *mutableName         = name;
+}
+
+TInterfaceBlock::TInterfaceBlock(TSymbolTable *symbolTable,
+                                 const TString *name,
+                                 const TFieldList *fields,
+                                 const TLayoutQualifier &layoutQualifier,
+                                 SymbolType symbolType,
+                                 TExtension extension)
+    : TSymbol(symbolTable, name, symbolType, extension),
+      TFieldListCollection(fields),
+      mBlockStorage(layoutQualifier.blockStorage),
+      mBinding(layoutQualifier.binding)
+{
+    ASSERT(name != nullptr);
+}
+
+TFunction::TFunction(TSymbolTable *symbolTable,
+                     const TString *name,
+                     const TType *retType,
+                     SymbolType symbolType,
+                     bool knownToNotHaveSideEffects,
+                     TOperator tOp,
+                     TExtension extension)
+    : TSymbol(symbolTable, name, symbolType, extension),
+      returnType(retType),
+      mangledName(nullptr),
+      op(tOp),
+      defined(false),
+      mHasPrototypeDeclaration(false),
+      mKnownToNotHaveSideEffects(knownToNotHaveSideEffects)
+{
+    // Functions with an empty name are not allowed.
+    ASSERT(symbolType != SymbolType::Empty);
+    ASSERT(name != nullptr || symbolType == SymbolType::AngleInternal || tOp != EOpNull);
+}
+
+//
+// Functions have buried pointers to delete.
+//
+TFunction::~TFunction()
+{
+    clearParameters();
+}
+
+void TFunction::clearParameters()
+{
+    for (TParamList::iterator i = parameters.begin(); i != parameters.end(); ++i)
+        delete (*i).type;
+    parameters.clear();
+    mangledName = nullptr;
+}
+
+void TFunction::swapParameters(const TFunction &parametersSource)
+{
+    clearParameters();
+    for (auto parameter : parametersSource.parameters)
+    {
+        addParameter(parameter);
+    }
+}
+
+const TString *TFunction::buildMangledName() const
+{
+    std::string newName = name().c_str();
+    newName += kFunctionMangledNameSeparator;
+
+    for (const auto &p : parameters)
+    {
+        newName += p.type->getMangledName();
+    }
+    return NewPoolTString(newName.c_str());
+}
+
+const TString &TFunction::GetMangledNameFromCall(const TString &functionName,
+                                                 const TIntermSequence &arguments)
+{
+    std::string newName = functionName.c_str();
+    newName += kFunctionMangledNameSeparator;
+
+    for (TIntermNode *argument : arguments)
+    {
+        newName += argument->getAsTyped()->getType().getMangledName();
+    }
+    return *NewPoolTString(newName.c_str());
+}
+
+bool TFunction::isMain() const
+{
+    return symbolType() == SymbolType::UserDefined && name() == "main";
+}
+
+bool TFunction::isImageFunction() const
+{
+    return symbolType() == SymbolType::BuiltIn &&
+           (name() == "imageSize" || name() == "imageLoad" || name() == "imageStore");
+}
+
+}  // namespace sh
new file mode 100644
--- /dev/null
+++ b/gfx/angle/src/compiler/translator/Symbol.h
@@ -0,0 +1,253 @@
+//
+// 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.
+//
+// Symbol.h: Symbols representing variables, functions, structures and interface blocks.
+//
+
+#ifndef COMPILER_TRANSLATOR_SYMBOL_H_
+#define COMPILER_TRANSLATOR_SYMBOL_H_
+
+#include "common/angleutils.h"
+#include "compiler/translator/ExtensionBehavior.h"
+#include "compiler/translator/IntermNode.h"
+#include "compiler/translator/SymbolUniqueId.h"
+
+namespace sh
+{
+
+class TSymbolTable;
+
+enum class SymbolType
+{
+    BuiltIn,
+    UserDefined,
+    AngleInternal,
+    Empty,  // Meaning symbol without a name.
+    NotResolved
+};
+
+// Symbol base class. (Can build functions or variables out of these...)
+class TSymbol : angle::NonCopyable
+{
+  public:
+    POOL_ALLOCATOR_NEW_DELETE();
+    TSymbol(TSymbolTable *symbolTable,
+            const TString *name,
+            SymbolType symbolType,
+            TExtension extension = TExtension::UNDEFINED);
+
+    virtual ~TSymbol()
+    {
+        // don't delete name, it's from the pool
+    }
+
+    // Don't call name() or getMangledName() for empty symbols (symbolType == SymbolType::Empty).
+    const TString &name() const;
+    virtual const TString &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; }
+    TExtension extension() const { return mExtension; }
+
+  protected:
+    const TString *const mName;
+
+  private:
+    const TSymbolUniqueId mUniqueId;
+    const SymbolType mSymbolType;
+    const TExtension mExtension;
+};
+
+// Variable.
+// May store the value of a constant variable of any type (float, int, bool or struct).
+class TVariable : public TSymbol
+{
+  public:
+    TVariable(TSymbolTable *symbolTable,
+              const TString *name,
+              const TType &t,
+              SymbolType symbolType,
+              TExtension ext = TExtension::UNDEFINED);
+
+    ~TVariable() override {}
+    bool isVariable() const override { return true; }
+    TType &getType() { return type; }
+    const TType &getType() const { return type; }
+    void setQualifier(TQualifier qualifier) { type.setQualifier(qualifier); }
+
+    const TConstantUnion *getConstPointer() const { return unionArray; }
+
+    void shareConstPointer(const TConstantUnion *constArray) { unionArray = constArray; }
+
+  private:
+    TType type;
+    const TConstantUnion *unionArray;
+};
+
+// Struct type.
+class TStructure : public TSymbol, public TFieldListCollection
+{
+  public:
+    TStructure(TSymbolTable *symbolTable,
+               const TString *name,
+               const TFieldList *fields,
+               SymbolType symbolType);
+
+    bool isStruct() const override { return true; }
+
+    void createSamplerSymbols(const TString &namePrefix,
+                              const TString &apiNamePrefix,
+                              TVector<const TVariable *> *outputSymbols,
+                              TMap<const TVariable *, TString> *outputSymbolsToAPINames,
+                              TSymbolTable *symbolTable) const;
+
+    void setAtGlobalScope(bool atGlobalScope) { mAtGlobalScope = atGlobalScope; }
+    bool atGlobalScope() const { return mAtGlobalScope; }
+
+  private:
+    // 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 TString &name);
+
+    bool mAtGlobalScope;
+};
+
+// Interface block. Note that this contains the block name, not the instance name. Interface block
+// instances are stored as TVariable.
+class TInterfaceBlock : public TSymbol, public TFieldListCollection
+{
+  public:
+    TInterfaceBlock(TSymbolTable *symbolTable,
+                    const TString *name,
+                    const TFieldList *fields,
+                    const TLayoutQualifier &layoutQualifier,
+                    SymbolType symbolType,
+                    TExtension extension = TExtension::UNDEFINED);
+
+    TLayoutBlockStorage blockStorage() const { return mBlockStorage; }
+    int blockBinding() const { return mBinding; }
+
+  private:
+    TLayoutBlockStorage mBlockStorage;
+    int mBinding;
+
+    // Note that we only record matrix packing on a per-field granularity.
+};
+
+// Immutable version of TParameter.
+struct TConstParameter
+{
+    TConstParameter() : name(nullptr), type(nullptr) {}
+    explicit TConstParameter(const TString *n) : name(n), type(nullptr) {}
+    explicit TConstParameter(const TType *t) : name(nullptr), type(t) {}
+    TConstParameter(const TString *n, const TType *t) : name(n), type(t) {}
+
+    // Both constructor arguments must be const.
+    TConstParameter(TString *n, TType *t)       = delete;
+    TConstParameter(const TString *n, TType *t) = delete;
+    TConstParameter(TString *n, const TType *t) = delete;
+
+    const TString *const name;
+    const TType *const type;
+};
+
+// The function sub-class of symbols and the parser will need to
+// share this definition of a function parameter.
+struct TParameter
+{
+    // Destructively converts to TConstParameter.
+    // This method resets name and type to nullptrs to make sure
+    // their content cannot be modified after the call.
+    TConstParameter turnToConst()
+    {
+        const TString *constName = name;
+        const TType *constType   = type;
+        name                     = nullptr;
+        type                     = nullptr;
+        return TConstParameter(constName, constType);
+    }
+
+    const TString *name;
+    TType *type;
+};
+
+// The function sub-class of a symbol.
+class TFunction : public TSymbol
+{
+  public:
+    TFunction(TSymbolTable *symbolTable,
+              const TString *name,
+              const TType *retType,
+              SymbolType symbolType,
+              bool knownToNotHaveSideEffects,
+              TOperator tOp        = EOpNull,
+              TExtension extension = TExtension::UNDEFINED);
+
+    ~TFunction() override;
+    bool isFunction() const override { return true; }
+
+    void addParameter(const TConstParameter &p)
+    {
+        parameters.push_back(p);
+        mangledName = nullptr;
+    }
+
+    void swapParameters(const TFunction &parametersSource);
+
+    const TString &getMangledName() const override
+    {
+        if (mangledName == nullptr)
+        {
+            mangledName = buildMangledName();
+        }
+        return *mangledName;
+    }
+
+    static const TString &GetMangledNameFromCall(const TString &functionName,
+                                                 const TIntermSequence &arguments);
+
+    const TType &getReturnType() const { return *returnType; }
+
+    TOperator getBuiltInOp() const { return op; }
+
+    void setDefined() { defined = true; }
+    bool isDefined() { return defined; }
+    void setHasPrototypeDeclaration() { mHasPrototypeDeclaration = true; }
+    bool hasPrototypeDeclaration() const { return mHasPrototypeDeclaration; }
+
+    size_t getParamCount() const { return parameters.size(); }
+    const TConstParameter &getParam(size_t i) const { return parameters[i]; }
+
+    bool isKnownToNotHaveSideEffects() const { return mKnownToNotHaveSideEffects; }
+
+    bool isMain() const;
+    bool isImageFunction() const;
+
+  private:
+    void clearParameters();
+
+    const TString *buildMangledName() const;
+
+    typedef TVector<TConstParameter> TParamList;
+    TParamList parameters;
+    const TType *returnType;
+    mutable const TString *mangledName;
+    // TODO(oetuaho): Remove op from TFunction once TFunction is not used for looking up builtins or
+    // constructors.
+    TOperator op;
+    bool defined;
+    bool mHasPrototypeDeclaration;
+    bool mKnownToNotHaveSideEffects;
+};
+
+}  // namespace sh
+
+#endif  // COMPILER_TRANSLATOR_SYMBOL_H_
--- a/gfx/angle/src/compiler/translator/SymbolTable.cpp
+++ b/gfx/angle/src/compiler/translator/SymbolTable.cpp
@@ -8,100 +8,25 @@
 //
 
 #if defined(_MSC_VER)
 #pragma warning(disable : 4718)
 #endif
 
 #include "compiler/translator/SymbolTable.h"
 
-#include "compiler/translator/Cache.h"
 #include "compiler/translator/IntermNode.h"
+#include "compiler/translator/StaticType.h"
 
 #include <stdio.h>
 #include <algorithm>
 
 namespace sh
 {
 
-namespace
-{
-
-static const char kFunctionMangledNameSeparator = '(';
-
-}  // anonymous namespace
-
-TSymbolUniqueId::TSymbolUniqueId(TSymbolTable *symbolTable) : mId(symbolTable->nextUniqueId())
-{
-}
-
-TSymbolUniqueId::TSymbolUniqueId(const TSymbol &symbol) : mId(symbol.getUniqueId())
-{
-}
-
-int TSymbolUniqueId::get() const
-{
-    return mId;
-}
-
-TSymbol::TSymbol(TSymbolTable *symbolTable, const TString *n)
-    : uniqueId(symbolTable->nextUniqueId()), name(n), extension(TExtension::UNDEFINED)
-{
-}
-
-//
-// Functions have buried pointers to delete.
-//
-TFunction::~TFunction()
-{
-    clearParameters();
-}
-
-void TFunction::clearParameters()
-{
-    for (TParamList::iterator i = parameters.begin(); i != parameters.end(); ++i)
-        delete (*i).type;
-    parameters.clear();
-    mangledName = nullptr;
-}
-
-void TFunction::swapParameters(const TFunction &parametersSource)
-{
-    clearParameters();
-    for (auto parameter : parametersSource.parameters)
-    {
-        addParameter(parameter);
-    }
-}
-
-const TString *TFunction::buildMangledName() const
-{
-    std::string newName = getName().c_str();
-    newName += kFunctionMangledNameSeparator;
-
-    for (const auto &p : parameters)
-    {
-        newName += p.type->getMangledName().c_str();
-    }
-    return NewPoolTString(newName.c_str());
-}
-
-const TString &TFunction::GetMangledNameFromCall(const TString &functionName,
-                                                 const TIntermSequence &arguments)
-{
-    std::string newName = functionName.c_str();
-    newName += kFunctionMangledNameSeparator;
-
-    for (TIntermNode *argument : arguments)
-    {
-        newName += argument->getAsTyped()->getType().getMangledName().c_str();
-    }
-    return *NewPoolTString(newName.c_str());
-}
-
 //
 // Symbol table levels are a map of pointers to symbols that have to be deleted.
 //
 TSymbolTableLevel::~TSymbolTableLevel()
 {
     for (tLevel::iterator it = level.begin(); it != level.end(); ++it)
         delete (*it).second;
 }
@@ -112,17 +37,17 @@ bool TSymbolTableLevel::insert(TSymbol *
     tInsertResult result = level.insert(tLevelPair(symbol->getMangledName(), symbol));
 
     return result.second;
 }
 
 bool TSymbolTableLevel::insertUnmangled(TFunction *function)
 {
     // returning true means symbol was added to the table
-    tInsertResult result = level.insert(tLevelPair(function->getName(), function));
+    tInsertResult result = level.insert(tLevelPair(function->name(), function));
 
     return result.second;
 }
 
 TSymbol *TSymbolTableLevel::find(const TString &name) const
 {
     tLevel::const_iterator it = level.find(name);
     if (it == level.end())
@@ -197,133 +122,124 @@ TSymbol *TSymbolTable::findBuiltIn(const
 }
 
 TSymbolTable::~TSymbolTable()
 {
     while (table.size() > 0)
         pop();
 }
 
-bool IsGenType(const TType *type)
+constexpr bool IsGenType(const TType *type)
 {
     if (type)
     {
         TBasicType basicType = type->getBasicType();
         return basicType == EbtGenType || basicType == EbtGenIType || basicType == EbtGenUType ||
                basicType == EbtGenBType;
     }
 
     return false;
 }
 
-bool IsVecType(const TType *type)
+constexpr bool IsVecType(const TType *type)
 {
     if (type)
     {
         TBasicType basicType = type->getBasicType();
         return basicType == EbtVec || basicType == EbtIVec || basicType == EbtUVec ||
                basicType == EbtBVec;
     }
 
     return false;
 }
 
-const TType *SpecificType(const TType *type, int size)
+constexpr const TType *SpecificType(const TType *type, int size)
 {
     ASSERT(size >= 1 && size <= 4);
 
     if (!type)
     {
         return nullptr;
     }
 
     ASSERT(!IsVecType(type));
 
     switch (type->getBasicType())
     {
         case EbtGenType:
-            return TCache::getType(EbtFloat, type->getQualifier(),
-                                   static_cast<unsigned char>(size));
+            return StaticType::GetForVec<EbtFloat>(type->getQualifier(),
+                                                            static_cast<unsigned char>(size));
         case EbtGenIType:
-            return TCache::getType(EbtInt, type->getQualifier(), static_cast<unsigned char>(size));
+            return StaticType::GetForVec<EbtInt>(type->getQualifier(),
+                                                          static_cast<unsigned char>(size));
         case EbtGenUType:
-            return TCache::getType(EbtUInt, type->getQualifier(), static_cast<unsigned char>(size));
+            return StaticType::GetForVec<EbtUInt>(type->getQualifier(),
+                                                           static_cast<unsigned char>(size));
         case EbtGenBType:
-            return TCache::getType(EbtBool, type->getQualifier(), static_cast<unsigned char>(size));
+            return StaticType::GetForVec<EbtBool>(type->getQualifier(),
+                                                           static_cast<unsigned char>(size));
         default:
             return type;
     }
 }
 
-const TType *VectorType(const TType *type, int size)
+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 TCache::getType(EbtFloat, static_cast<unsigned char>(size));
+            return StaticType::GetForVecMat<EbtFloat>(static_cast<unsigned char>(size));
         case EbtIVec:
-            return TCache::getType(EbtInt, static_cast<unsigned char>(size));
+            return StaticType::GetForVecMat<EbtInt>(static_cast<unsigned char>(size));
         case EbtUVec:
-            return TCache::getType(EbtUInt, static_cast<unsigned char>(size));
+            return StaticType::GetForVecMat<EbtUInt>(static_cast<unsigned char>(size));
         case EbtBVec:
-            return TCache::getType(EbtBool, static_cast<unsigned char>(size));
+            return StaticType::GetForVecMat<EbtBool>(static_cast<unsigned char>(size));
         default:
             return type;
     }
 }
 
-TVariable *TSymbolTable::declareVariable(const TString *name, const TType &type)
+bool TSymbolTable::declareVariable(TVariable *variable)
 {
-    return insertVariable(currentLevel(), name, type);
+    ASSERT(variable->symbolType() == SymbolType::UserDefined);
+    return insertVariable(currentLevel(), variable);
 }
 
-TVariable *TSymbolTable::declareStructType(TStructure *str)
+bool TSymbolTable::declareStructType(TStructure *str)
 {
     return insertStructType(currentLevel(), str);
 }
 
-TInterfaceBlockName *TSymbolTable::declareInterfaceBlockName(const TString *name)
+bool TSymbolTable::declareInterfaceBlock(TInterfaceBlock *interfaceBlock)
 {
-    TInterfaceBlockName *blockNameSymbol = new TInterfaceBlockName(this, name);
-    if (insert(currentLevel(), blockNameSymbol))
-    {
-        return blockNameSymbol;
-    }
-    return nullptr;
-}
-
-TInterfaceBlockName *TSymbolTable::insertInterfaceBlockNameExt(ESymbolLevel level,
-                                                               TExtension ext,
-                                                               const TString *name)
-{
-    TInterfaceBlockName *blockNameSymbol = new TInterfaceBlockName(this, name);
-    if (insert(level, ext, blockNameSymbol))
-    {
-        return blockNameSymbol;
-    }
-    return nullptr;
+    return insert(currentLevel(), interfaceBlock);
 }
 
 TVariable *TSymbolTable::insertVariable(ESymbolLevel level, const char *name, const TType &type)
 {
-    return insertVariable(level, NewPoolTString(name), type);
+    ASSERT(level <= LAST_BUILTIN_LEVEL);
+    return insertVariable(level, NewPoolTString(name), type, SymbolType::BuiltIn);
 }
 
-TVariable *TSymbolTable::insertVariable(ESymbolLevel level, const TString *name, const TType &type)
+TVariable *TSymbolTable::insertVariable(ESymbolLevel level,
+                                        const TString *name,
+                                        const TType &type,
+                                        SymbolType symbolType)
 {
-    TVariable *var = new TVariable(this, name, type);
+    TVariable *var = new TVariable(this, name, type, symbolType);
     if (insert(level, var))
     {
         // Do lazy initialization for struct types, so we allocate to the current scope.
         if (var->getType().getBasicType() == EbtStruct)
         {
             var->getType().realize();
         }
         return var;
@@ -331,37 +247,44 @@ TVariable *TSymbolTable::insertVariable(
     return nullptr;
 }
 
 TVariable *TSymbolTable::insertVariableExt(ESymbolLevel level,
                                            TExtension ext,
                                            const char *name,
                                            const TType &type)
 {
-    TVariable *var = new TVariable(this, NewPoolTString(name), type);
-    if (insert(level, ext, var))
+    TVariable *var = new TVariable(this, NewPoolTString(name), type, SymbolType::BuiltIn, ext);
+    if (insert(level, var))
     {
         if (var->getType().getBasicType() == EbtStruct)
         {
             var->getType().realize();
         }
         return var;
     }
     return nullptr;
 }
 
-TVariable *TSymbolTable::insertStructType(ESymbolLevel level, TStructure *str)
+bool TSymbolTable::insertVariable(ESymbolLevel level, TVariable *variable)
+{
+    ASSERT(variable);
+    return insert(level, variable);
+}
+
+bool TSymbolTable::insertStructType(ESymbolLevel level, TStructure *str)
 {
-    TVariable *var = new TVariable(this, &str->name(), TType(str), true);
-    if (insert(level, var))
-    {
-        var->getType().realize();
-        return var;
-    }
-    return nullptr;
+    ASSERT(str);
+    return insert(level, str);
+}
+
+bool TSymbolTable::insertInterfaceBlock(ESymbolLevel level, TInterfaceBlock *interfaceBlock)
+{
+    ASSERT(interfaceBlock);
+    return insert(level, interfaceBlock);
 }
 
 void TSymbolTable::insertBuiltIn(ESymbolLevel level,
                                  TOperator op,
                                  TExtension ext,
                                  const TType *rvalue,
                                  const char *name,
                                  const TType *ptype1,
@@ -369,80 +292,81 @@ void TSymbolTable::insertBuiltIn(ESymbol
                                  const TType *ptype3,
                                  const TType *ptype4,
                                  const TType *ptype5)
 {
     if (ptype1->getBasicType() == EbtGSampler2D)
     {
         insertUnmangledBuiltInName(name, level);
         bool gvec4 = (rvalue->getBasicType() == EbtGVec4);
-        insertBuiltIn(level, gvec4 ? TCache::getType(EbtFloat, 4) : rvalue, name,
-                      TCache::getType(EbtSampler2D), ptype2, ptype3, ptype4, ptype5);
-        insertBuiltIn(level, gvec4 ? TCache::getType(EbtInt, 4) : rvalue, name,
-                      TCache::getType(EbtISampler2D), ptype2, ptype3, ptype4, ptype5);
-        insertBuiltIn(level, gvec4 ? TCache::getType(EbtUInt, 4) : rvalue, name,
-                      TCache::getType(EbtUSampler2D), ptype2, ptype3, ptype4, ptype5);
+        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)
     {
         insertUnmangledBuiltInName(name, level);
         bool gvec4 = (rvalue->getBasicType() == EbtGVec4);
-        insertBuiltIn(level, gvec4 ? TCache::getType(EbtFloat, 4) : rvalue, name,
-                      TCache::getType(EbtSampler3D), ptype2, ptype3, ptype4, ptype5);
-        insertBuiltIn(level, gvec4 ? TCache::getType(EbtInt, 4) : rvalue, name,
-                      TCache::getType(EbtISampler3D), ptype2, ptype3, ptype4, ptype5);
-        insertBuiltIn(level, gvec4 ? TCache::getType(EbtUInt, 4) : rvalue, name,
-                      TCache::getType(EbtUSampler3D), ptype2, ptype3, ptype4, ptype5);
+        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)
     {
         insertUnmangledBuiltInName(name, level);
         bool gvec4 = (rvalue->getBasicType() == EbtGVec4);
-        insertBuiltIn(level, gvec4 ? TCache::getType(EbtFloat, 4) : rvalue, name,
-                      TCache::getType(EbtSamplerCube), ptype2, ptype3, ptype4, ptype5);
-        insertBuiltIn(level, gvec4 ? TCache::getType(EbtInt, 4) : rvalue, name,
-                      TCache::getType(EbtISamplerCube), ptype2, ptype3, ptype4, ptype5);
-        insertBuiltIn(level, gvec4 ? TCache::getType(EbtUInt, 4) : rvalue, name,
-                      TCache::getType(EbtUSamplerCube), ptype2, ptype3, ptype4, ptype5);
+        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)
     {
         insertUnmangledBuiltInName(name, level);
         bool gvec4 = (rvalue->getBasicType() == EbtGVec4);
-        insertBuiltIn(level, gvec4 ? TCache::getType(EbtFloat, 4) : rvalue, name,
-                      TCache::getType(EbtSampler2DArray), ptype2, ptype3, ptype4, ptype5);
-        insertBuiltIn(level, gvec4 ? TCache::getType(EbtInt, 4) : rvalue, name,
-                      TCache::getType(EbtISampler2DArray), ptype2, ptype3, ptype4, ptype5);
-        insertBuiltIn(level, gvec4 ? TCache::getType(EbtUInt, 4) : rvalue, name,
-                      TCache::getType(EbtUSampler2DArray), ptype2, ptype3, ptype4, ptype5);
+        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)
     {
         insertUnmangledBuiltInName(name, level);
         bool gvec4 = (rvalue->getBasicType() == EbtGVec4);
-        insertBuiltIn(level, gvec4 ? TCache::getType(EbtFloat, 4) : rvalue, name,
-                      TCache::getType(EbtSampler2DMS), ptype2, ptype3, ptype4, ptype5);
-        insertBuiltIn(level, gvec4 ? TCache::getType(EbtInt, 4) : rvalue, name,
-                      TCache::getType(EbtISampler2DMS), ptype2, ptype3, ptype4, ptype5);
-        insertBuiltIn(level, gvec4 ? TCache::getType(EbtUInt, 4) : rvalue, name,
-                      TCache::getType(EbtUSampler2DMS), ptype2, ptype3, ptype4, ptype5);
+        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()))
     {
         insertUnmangledBuiltInName(name, level);
 
-        const TType *floatType    = TCache::getType(EbtFloat, 4);
-        const TType *intType      = TCache::getType(EbtInt, 4);
-        const TType *unsignedType = TCache::getType(EbtUInt, 4);
+        const TType *floatType    = StaticType::GetBasic<EbtFloat, 4>();
+        const TType *intType      = StaticType::GetBasic<EbtInt, 4>();
+        const TType *unsignedType = StaticType::GetBasic<EbtUInt, 4>();
 
-        const TType *floatImage =
-            TCache::getType(convertGImageToFloatImage(ptype1->getBasicType()));
-        const TType *intImage = TCache::getType(convertGImageToIntImage(ptype1->getBasicType()));
-        const TType *unsignedImage =
-            TCache::getType(convertGImageToUnsignedImage(ptype1->getBasicType()));
+        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);
@@ -484,17 +408,18 @@ void TSymbolTable::insertBuiltIn(ESymbol
                       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
     {
-        TFunction *function = new TFunction(this, NewPoolTString(name), rvalue, op, ext);
+        TFunction *function =
+            new TFunction(this, NewPoolTString(name), rvalue, SymbolType::BuiltIn, false, op, ext);
 
         function->addParameter(TConstParameter(ptype1));
 
         if (ptype2)
         {
             function->addParameter(TConstParameter(ptype2));
         }
 
@@ -550,27 +475,29 @@ void TSymbolTable::insertBuiltInOp(ESymb
 }
 
 void TSymbolTable::insertBuiltInFunctionNoParameters(ESymbolLevel level,
                                                      TOperator op,
                                                      const TType *rvalue,
                                                      const char *name)
 {
     insertUnmangledBuiltInName(name, level);
-    insert(level, new TFunction(this, NewPoolTString(name), rvalue, op));
+    insert(level,
+           new TFunction(this, NewPoolTString(name), rvalue, SymbolType::BuiltIn, false, op));
 }
 
 void TSymbolTable::insertBuiltInFunctionNoParametersExt(ESymbolLevel level,
                                                         TExtension ext,
                                                         TOperator op,
                                                         const TType *rvalue,
                                                         const char *name)
 {
     insertUnmangledBuiltInName(name, level);
-    insert(level, new TFunction(this, NewPoolTString(name), rvalue, op, ext));
+    insert(level,
+           new TFunction(this, NewPoolTString(name), rvalue, SymbolType::BuiltIn, false, op, ext));
 }
 
 TPrecision TSymbolTable::getDefaultPrecision(TBasicType type) const
 {
     if (!SupportsPrecision(type))
         return EbpUndefined;
 
     // unsigned integers use the same precision as signed
@@ -591,16 +518,17 @@ TPrecision TSymbolTable::getDefaultPreci
         level--;
     }
     return prec;
 }
 
 void TSymbolTable::insertUnmangledBuiltInName(const char *name, ESymbolLevel level)
 {
     ASSERT(level >= 0 && level < static_cast<ESymbolLevel>(table.size()));
+    ASSERT(mUserDefinedUniqueIdsStart == -1);
     table[level]->insertUnmangledBuiltInName(std::string(name));
 }
 
 bool TSymbolTable::hasUnmangledBuiltInAtLevel(const char *name, ESymbolLevel level)
 {
     ASSERT(level >= 0 && level < static_cast<ESymbolLevel>(table.size()));
     return table[level]->hasUnmangledBuiltIn(std::string(name));
 }
@@ -627,9 +555,28 @@ bool TSymbolTable::hasUnmangledBuiltInFo
         if (table[level]->hasUnmangledBuiltIn(name))
         {
             return true;
         }
     }
     return false;
 }
 
+void TSymbolTable::markBuiltInInitializationFinished()
+{
+    mUserDefinedUniqueIdsStart = mUniqueIdCounter;
+}
+
+void TSymbolTable::clearCompilationResults()
+{
+    mUniqueIdCounter = mUserDefinedUniqueIdsStart;
+
+    // User-defined scopes should have already been cleared when the compilation finished.
+    ASSERT(table.size() == LAST_BUILTIN_LEVEL + 1u);
+}
+
+int TSymbolTable::nextUniqueIdValue()
+{
+    ASSERT(mUniqueIdCounter < std::numeric_limits<int>::max());
+    return ++mUniqueIdCounter;
+}
+
 }  // namespace sh
--- a/gfx/angle/src/compiler/translator/SymbolTable.h
+++ b/gfx/angle/src/compiler/translator/SymbolTable.h
@@ -33,221 +33,25 @@
 #include <array>
 #include <assert.h>
 #include <set>
 
 #include "common/angleutils.h"
 #include "compiler/translator/ExtensionBehavior.h"
 #include "compiler/translator/InfoSink.h"
 #include "compiler/translator/IntermNode.h"
+#include "compiler/translator/Symbol.h"
 
 namespace sh
 {
 
-// Encapsulates a unique id for a symbol.
-class TSymbolUniqueId
-{
-  public:
-    POOL_ALLOCATOR_NEW_DELETE();
-    TSymbolUniqueId(TSymbolTable *symbolTable);
-    TSymbolUniqueId(const TSymbol &symbol);
-    TSymbolUniqueId(const TSymbolUniqueId &) = default;
-    TSymbolUniqueId &operator=(const TSymbolUniqueId &) = default;
-
-    int get() const;
-
-  private:
-    int mId;
-};
-
-// Symbol base class. (Can build functions or variables out of these...)
-class TSymbol : angle::NonCopyable
-{
-  public:
-    POOL_ALLOCATOR_NEW_DELETE();
-    TSymbol(TSymbolTable *symbolTable, const TString *n);
-
-    virtual ~TSymbol()
-    {
-        // don't delete name, it's from the pool
-    }
-
-    const TString &getName() const { return *name; }
-    virtual const TString &getMangledName() const { return getName(); }
-    virtual bool isFunction() const { return false; }
-    virtual bool isVariable() const { return false; }
-    int getUniqueId() const { return uniqueId; }
-    void relateToExtension(TExtension ext) { extension = ext; }
-    TExtension getExtension() const { return extension; }
-
-  private:
-    const int uniqueId;
-    const TString *name;
-    TExtension extension;
-};
-
-// Variable, meaning a symbol that's not a function.
-//
-// May store the value of a constant variable of any type (float, int, bool or struct).
-class TVariable : public TSymbol
-{
-  public:
-    ~TVariable() override {}
-    bool isVariable() const override { return true; }
-    TType &getType() { return type; }
-    const TType &getType() const { return type; }
-    bool isUserType() const { return userType; }
-    void setQualifier(TQualifier qualifier) { type.setQualifier(qualifier); }
-
-    const TConstantUnion *getConstPointer() const { return unionArray; }
-
-    void shareConstPointer(const TConstantUnion *constArray) { unionArray = constArray; }
-
-  private:
-    friend class TSymbolTable;
-
-    TVariable(TSymbolTable *symbolTable,
-              const TString *name,
-              const TType &t,
-              bool isUserTypeDefinition = false)
-        : TSymbol(symbolTable, name), type(t), userType(isUserTypeDefinition), unionArray(0)
-    {
-    }
-
-    TType type;
-
-    // Set to true if this represents a struct type, as opposed to a variable.
-    bool userType;
-
-    // we are assuming that Pool Allocator will free the memory
-    // allocated to unionArray when this object is destroyed.
-    const TConstantUnion *unionArray;
-};
-
-// Immutable version of TParameter.
-struct TConstParameter
-{
-    TConstParameter() : name(nullptr), type(nullptr) {}
-    explicit TConstParameter(const TString *n) : name(n), type(nullptr) {}
-    explicit TConstParameter(const TType *t) : name(nullptr), type(t) {}
-    TConstParameter(const TString *n, const TType *t) : name(n), type(t) {}
-
-    // Both constructor arguments must be const.
-    TConstParameter(TString *n, TType *t)       = delete;
-    TConstParameter(const TString *n, TType *t) = delete;
-    TConstParameter(TString *n, const TType *t) = delete;
-
-    const TString *const name;
-    const TType *const type;
-};
-
-// The function sub-class of symbols and the parser will need to
-// share this definition of a function parameter.
-struct TParameter
-{
-    // Destructively converts to TConstParameter.
-    // This method resets name and type to nullptrs to make sure
-    // their content cannot be modified after the call.
-    TConstParameter turnToConst()
-    {
-        const TString *constName = name;
-        const TType *constType   = type;
-        name                     = nullptr;
-        type                     = nullptr;
-        return TConstParameter(constName, constType);
-    }
-
-    const TString *name;
-    TType *type;
-};
-
-// The function sub-class of a symbol.
-class TFunction : public TSymbol
-{
-  public:
-    TFunction(TSymbolTable *symbolTable,
-              const TString *name,
-              const TType *retType,
-              TOperator tOp  = EOpNull,
-              TExtension ext = TExtension::UNDEFINED)
-        : TSymbol(symbolTable, name),
-          returnType(retType),
-          mangledName(nullptr),
-          op(tOp),
-          defined(false),
-          mHasPrototypeDeclaration(false)
-    {
-        relateToExtension(ext);
-    }
-    ~TFunction() override;
-    bool isFunction() const override { return true; }
-
-    void addParameter(const TConstParameter &p)
-    {
-        parameters.push_back(p);
-        mangledName = nullptr;
-    }
-
-    void swapParameters(const TFunction &parametersSource);
-
-    const TString &getMangledName() const override
-    {
-        if (mangledName == nullptr)
-        {
-            mangledName = buildMangledName();
-        }
-        return *mangledName;
-    }
-
-    static const TString &GetMangledNameFromCall(const TString &functionName,
-                                                 const TIntermSequence &arguments);
-
-    const TType &getReturnType() const { return *returnType; }
-
-    TOperator getBuiltInOp() const { return op; }
-
-    void setDefined() { defined = true; }
-    bool isDefined() { return defined; }
-    void setHasPrototypeDeclaration() { mHasPrototypeDeclaration = true; }
-    bool hasPrototypeDeclaration() const { return mHasPrototypeDeclaration; }
-
-    size_t getParamCount() const { return parameters.size(); }
-    const TConstParameter &getParam(size_t i) const { return parameters[i]; }
-
-  private:
-    void clearParameters();
-
-    const TString *buildMangledName() const;
-
-    typedef TVector<TConstParameter> TParamList;
-    TParamList parameters;
-    const TType *returnType;
-    mutable const TString *mangledName;
-    TOperator op;
-    bool defined;
-    bool mHasPrototypeDeclaration;
-};
-
-// Interface block name sub-symbol
-class TInterfaceBlockName : public TSymbol
-{
-  public:
-    virtual ~TInterfaceBlockName() {}
-
-  private:
-    friend class TSymbolTable;
-    TInterfaceBlockName(TSymbolTable *symbolTable, const TString *name) : TSymbol(symbolTable, name)
-    {
-    }
-};
-
 class TSymbolTableLevel
 {
   public:
-    typedef TMap<TString, TSymbol *> tLevel;
+    typedef TUnorderedMap<TString, TSymbol *> tLevel;
     typedef tLevel::const_iterator const_iterator;
     typedef const tLevel::value_type tLevelPair;
     typedef std::pair<tLevel::iterator, bool> tInsertResult;
 
     TSymbolTableLevel() : mGlobalInvariant(false) {}
     ~TSymbolTableLevel();
 
     bool insert(TSymbol *symbol);
@@ -297,17 +101,17 @@ const int ESSL3_1_BUILTINS   = 3;
 // 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;
 
 class TSymbolTable : angle::NonCopyable
 {
   public:
-    TSymbolTable() : mUniqueIdCounter(0)
+    TSymbolTable() : mUniqueIdCounter(0), mUserDefinedUniqueIdsStart(-1)
     {
         // The symbol table cannot be used until push() is called, but
         // the lack of an initial call to push() can be used to detect
         // that the symbol table has not been preloaded with built-ins.
     }
 
     ~TSymbolTable();
 
@@ -328,66 +132,66 @@ class TSymbolTable : angle::NonCopyable
         delete table.back();
         table.pop_back();
 
         delete precisionStack.back();
         precisionStack.pop_back();
     }
 
     // The declare* entry points are used when parsing and declare symbols at the current scope.
-    // They return the created symbol in case the declaration was successful, and nullptr if the
-    // declaration failed due to redefinition.
-    TVariable *declareVariable(const TString *name, const TType &type);
-    TVariable *declareStructType(TStructure *str);
-    TInterfaceBlockName *declareInterfaceBlockName(const TString *name);
+    // They return the created symbol / true in case the declaration was successful, and nullptr /
+    // false if the declaration failed due to redefinition.
+    bool declareVariable(TVariable *variable);
+    bool declareStructType(TStructure *str);
+    bool declareInterfaceBlock(TInterfaceBlock *interfaceBlock);
 
     // The insert* entry points are used when initializing the symbol table with built-ins.
-    // They return the created symbol in case the declaration was successful, and nullptr if the
-    // declaration failed due to redefinition.
+    // 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 char *name, const TType &type);
     TVariable *insertVariableExt(ESymbolLevel level,
                                  TExtension ext,
                                  const char *name,
                                  const TType &type);
-    TVariable *insertStructType(ESymbolLevel level, TStructure *str);
-    TInterfaceBlockName *insertInterfaceBlockNameExt(ESymbolLevel level,
-                                                     TExtension ext,
-                                                     const TString *name);
+    bool insertVariable(ESymbolLevel level, TVariable *variable);
+    bool insertStructType(ESymbolLevel level, TStructure *str);
+    bool insertInterfaceBlock(ESymbolLevel level, TInterfaceBlock *interfaceBlock);
 
     bool insertConstInt(ESymbolLevel level, const char *name, int value, TPrecision precision)
     {
-        TVariable *constant =
-            new TVariable(this, NewPoolTString(name), TType(EbtInt, precision, EvqConst, 1));
+        TVariable *constant = new TVariable(
+            this, NewPoolTString(name), TType(EbtInt, precision, EvqConst, 1), SymbolType::BuiltIn);
         TConstantUnion *unionArray = new TConstantUnion[1];
         unionArray[0].setIConst(value);
         constant->shareConstPointer(unionArray);
         return insert(level, constant);
     }
 
     bool insertConstIntExt(ESymbolLevel level,
                            TExtension ext,
                            const char *name,
                            int value,
                            TPrecision precision)
     {
         TVariable *constant =
-            new TVariable(this, NewPoolTString(name), TType(EbtInt, precision, EvqConst, 1));
+            new TVariable(this, NewPoolTString(name), TType(EbtInt, precision, EvqConst, 1),
+                          SymbolType::BuiltIn, ext);
         TConstantUnion *unionArray = new TConstantUnion[1];
         unionArray[0].setIConst(value);
         constant->shareConstPointer(unionArray);
-        return insert(level, ext, constant);
+        return insert(level, constant);
     }
 
     bool insertConstIvec3(ESymbolLevel level,
                           const char *name,
                           const std::array<int, 3> &values,
                           TPrecision precision)
     {
-        TVariable *constantIvec3 =
-            new TVariable(this, NewPoolTString(name), TType(EbtInt, precision, EvqConst, 3));
+        TVariable *constantIvec3 = new TVariable(
+            this, NewPoolTString(name), TType(EbtInt, precision, EvqConst, 3), SymbolType::BuiltIn);
 
         TConstantUnion *unionArray = new TConstantUnion[3];
         for (size_t index = 0u; index < 3u; ++index)
         {
             unionArray[index].setIConst(values[index]);
         }
         constantIvec3->shareConstPointer(unionArray);
 
@@ -509,42 +313,54 @@ class TSymbolTable : angle::NonCopyable
     }
 
     void setGlobalInvariant(bool invariant)
     {
         ASSERT(atGlobalLevel());
         table[currentLevel()]->setGlobalInvariant(invariant);
     }
 
-    int nextUniqueId() { return ++mUniqueIdCounter; }
+    const TSymbolUniqueId nextUniqueId() { return TSymbolUniqueId(this); }
 
     // Checks whether there is a built-in accessible by a shader with the specified version.
     bool hasUnmangledBuiltInForShaderVersion(const char *name, int shaderVersion);
 
+    void markBuiltInInitializationFinished();
+    void clearCompilationResults();
+
   private:
+    friend class TSymbolUniqueId;
+    int nextUniqueIdValue();
+
     ESymbolLevel currentLevel() const { return static_cast<ESymbolLevel>(table.size() - 1); }
 
-    TVariable *insertVariable(ESymbolLevel level, const TString *name, const TType &type);
-
-    bool insert(ESymbolLevel level, TSymbol *symbol) { return table[level]->insert(symbol); }
+    TVariable *insertVariable(ESymbolLevel level,
+                              const TString *name,
+                              const TType &type,
+                              SymbolType symbolType);
 
-    bool insert(ESymbolLevel level, TExtension ext, TSymbol *symbol)
+    bool insert(ESymbolLevel level, TSymbol *symbol)
     {
-        symbol->relateToExtension(ext);
+        ASSERT(level > LAST_BUILTIN_LEVEL || mUserDefinedUniqueIdsStart == -1);
         return table[level]->insert(symbol);
     }
 
     // Used to insert unmangled functions to check redeclaration of built-ins in ESSL 3.00 and
     // above.
     void insertUnmangledBuiltInName(const char *name, ESymbolLevel level);
 
     bool hasUnmangledBuiltInAtLevel(const char *name, ESymbolLevel level);
 
     std::vector<TSymbolTableLevel *> table;
     typedef TMap<TBasicType, TPrecision> PrecisionStackLevel;
     std::vector<PrecisionStackLevel *> precisionStack;
 
     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;
 };
 
 }  // namespace sh
 
 #endif  // COMPILER_TRANSLATOR_SYMBOLTABLE_H_
new file mode 100644
--- /dev/null
+++ b/gfx/angle/src/compiler/translator/SymbolUniqueId.cpp
@@ -0,0 +1,36 @@
+//
+// 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.
+//
+// SymbolUniqueId.cpp: Encapsulates a unique id for a symbol.
+
+#include "compiler/translator/SymbolUniqueId.h"
+
+#include "compiler/translator/SymbolTable.h"
+
+namespace sh
+{
+
+TSymbolUniqueId::TSymbolUniqueId(TSymbolTable *symbolTable) : mId(symbolTable->nextUniqueIdValue())
+{
+}
+
+TSymbolUniqueId::TSymbolUniqueId(const TSymbol &symbol) : mId(symbol.uniqueId().get())
+{
+}
+
+TSymbolUniqueId::TSymbolUniqueId(const TSymbolUniqueId &) = default;
+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
new file mode 100644
--- /dev/null
+++ b/gfx/angle/src/compiler/translator/SymbolUniqueId.h
@@ -0,0 +1,37 @@
+//
+// 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.
+//
+// SymbolUniqueId.h: Encapsulates a unique id for a symbol.
+
+#ifndef COMPILER_TRANSLATOR_SYMBOLUNIQUEID_H_
+#define COMPILER_TRANSLATOR_SYMBOLUNIQUEID_H_
+
+#include "compiler/translator/Common.h"
+
+namespace sh
+{
+
+class TSymbolTable;
+class TSymbol;
+
+class TSymbolUniqueId
+{
+  public:
+    POOL_ALLOCATOR_NEW_DELETE();
+    explicit TSymbolUniqueId(TSymbolTable *symbolTable);
+    explicit TSymbolUniqueId(const TSymbol &symbol);
+    TSymbolUniqueId(const TSymbolUniqueId &);
+    TSymbolUniqueId &operator=(const TSymbolUniqueId &);
+    bool operator==(const TSymbolUniqueId &) const;
+
+    int get() const;
+
+  private:
+    int mId;
+};
+
+}  // namespace sh
+
+#endif  // COMPILER_TRANSLATOR_SYMBOLUNIQUEID_H_
--- a/gfx/angle/src/compiler/translator/TranslatorESSL.cpp
+++ b/gfx/angle/src/compiler/translator/TranslatorESSL.cpp
@@ -3,17 +3,16 @@
 // 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 "compiler/translator/BuiltInFunctionEmulatorGLSL.h"
 #include "compiler/translator/EmulatePrecision.h"
-#include "compiler/translator/PrunePureLiteralStatements.h"
 #include "compiler/translator/RecordConstantPrecision.h"
 #include "compiler/translator/OutputESSL.h"
 #include "angle_gl.h"
 
 namespace sh
 {
 
 TranslatorESSL::TranslatorESSL(sh::GLenum type, ShShaderSpec spec)
@@ -25,22 +24,20 @@ void TranslatorESSL::initBuiltInFunction
                                                  ShCompileOptions compileOptions)
 {
     if (compileOptions & SH_EMULATE_ATAN2_FLOAT_FUNCTION)
     {
         InitBuiltInAtanFunctionEmulatorForGLSLWorkarounds(emu);
     }
 }
 
-void TranslatorESSL::translate(TIntermBlock *root, ShCompileOptions compileOptions)
+void TranslatorESSL::translate(TIntermBlock *root,
+                               ShCompileOptions compileOptions,
+                               PerformanceDiagnostics * /*perfDiagnostics*/)
 {
-    // The ESSL output doesn't define a default precision for float, so float literal statements
-    // end up with no precision which is invalid ESSL.
-    PrunePureLiteralStatements(root);
-
     TInfoSinkBase &sink = getInfoSink().obj;
 
     int shaderVer = getShaderVersion();
     if (shaderVer > 100)
     {
         sink << "#version " << shaderVer << " es\n";
     }
 
@@ -90,52 +87,44 @@ void TranslatorESSL::translate(TIntermBl
 
     if (getShaderType() == GL_COMPUTE_SHADER && isComputeShaderLocalSizeDeclared())
     {
         const sh::WorkGroupSize &localSize = getComputeShaderLocalSize();
         sink << "layout (local_size_x=" << localSize[0] << ", local_size_y=" << localSize[1]
              << ", local_size_z=" << localSize[2] << ") in;\n";
     }
 
-    if (getShaderType() == GL_GEOMETRY_SHADER_OES)
+    if (getShaderType() == GL_GEOMETRY_SHADER_EXT)
     {
         WriteGeometryShaderLayoutQualifiers(
             sink, getGeometryShaderInputPrimitiveType(), getGeometryShaderInvocations(),
             getGeometryShaderOutputPrimitiveType(), getGeometryShaderMaxVertices());
     }
 
     // Write translated shader.
     TOutputESSL outputESSL(sink, getArrayIndexClampingStrategy(), getHashFunction(), getNameMap(),
                            &getSymbolTable(), getShaderType(), shaderVer, precisionEmulation,
                            compileOptions);
 
-    if (compileOptions & SH_TRANSLATE_VIEWID_OVR_TO_UNIFORM)
-    {
-        TName uniformName(TString("ViewID_OVR"));
-        uniformName.setInternal(true);
-        sink << "highp uniform int " << outputESSL.hashName(uniformName) << ";\n";
-    }
-
     root->traverse(&outputESSL);
 }
 
 bool TranslatorESSL::shouldFlattenPragmaStdglInvariantAll()
 {
     // Not necessary when translating to ESSL.
     return false;
 }
 
 void TranslatorESSL::writeExtensionBehavior(ShCompileOptions compileOptions)
 {
     TInfoSinkBase &sink                   = getInfoSink().obj;
     const TExtensionBehavior &extBehavior = getExtensionBehavior();
     const bool isMultiviewExtEmulated =
-        (compileOptions &
-         (SH_TRANSLATE_VIEWID_OVR_TO_UNIFORM | SH_INITIALIZE_BUILTINS_FOR_INSTANCED_MULTIVIEW |
-          SH_SELECT_VIEW_IN_NV_GLSL_VERTEX_SHADER)) != 0u;
+        (compileOptions & (SH_INITIALIZE_BUILTINS_FOR_INSTANCED_MULTIVIEW |
+                           SH_SELECT_VIEW_IN_NV_GLSL_VERTEX_SHADER)) != 0u;
     for (TExtensionBehavior::const_iterator iter = extBehavior.begin(); iter != extBehavior.end();
          ++iter)
     {
         if (iter->second != EBhUndefined)
         {
             const bool isMultiview = (iter->first == TExtension::OVR_multiview);
             if (getResources().NV_shader_framebuffer_fetch &&
                 iter->first == TExtension::EXT_shader_framebuffer_fetch)
@@ -154,23 +143,23 @@ void TranslatorESSL::writeExtensionBehav
                     (compileOptions & SH_SELECT_VIEW_IN_NV_GLSL_VERTEX_SHADER) != 0u)
                 {
                     // Emit the NV_viewport_array2 extension in a vertex shader if the
                     // SH_SELECT_VIEW_IN_NV_GLSL_VERTEX_SHADER option is set and the
                     // OVR_multiview(2) extension is requested.
                     sink << "#extension GL_NV_viewport_array2 : require\n";
                 }
             }
-            else if (iter->first == TExtension::OES_geometry_shader)
+            else if (iter->first == TExtension::EXT_geometry_shader)
             {
-                sink << "#ifdef GL_OES_geometry_shader\n"
+                sink << "#ifdef GL_EXT_geometry_shader\n"
+                     << "#extension GL_EXT_geometry_shader : " << GetBehaviorString(iter->second)
+                     << "\n"
+                     << "#elif defined GL_OES_geometry_shader\n"
                      << "#extension GL_OES_geometry_shader : " << GetBehaviorString(iter->second)
-                     << "\n"
-                     << "#elif defined GL_EXT_geometry_shader\n"
-                     << "#extension GL_EXT_geometry_shader : " << GetBehaviorString(iter->second)
                      << "\n";
                 if (iter->second == EBhRequire)
                 {
                     sink << "#else\n"
                          << "#error \"No geometry shader extensions available.\" // Only generate "
                             "this if the extension is \"required\"\n";
                 }
                 sink << "#endif\n";
--- a/gfx/angle/src/compiler/translator/TranslatorESSL.h
+++ b/gfx/angle/src/compiler/translator/TranslatorESSL.h
@@ -16,17 +16,19 @@ class TranslatorESSL : public TCompiler
 {
   public:
     TranslatorESSL(sh::GLenum type, ShShaderSpec spec);
 
   protected:
     void initBuiltInFunctionEmulator(BuiltInFunctionEmulator *emu,
                                      ShCompileOptions compileOptions) override;
 
-    void translate(TIntermBlock *root, ShCompileOptions compileOptions) override;
+    void translate(TIntermBlock *root,
+                   ShCompileOptions compileOptions,
+                   PerformanceDiagnostics *perfDiagnostics) override;
     bool shouldFlattenPragmaStdglInvariantAll() override;
 
   private:
     void writeExtensionBehavior(ShCompileOptions compileOptions);
 };
 
 }  // namespace sh
 
--- a/gfx/angle/src/compiler/translator/TranslatorGLSL.cpp
+++ b/gfx/angle/src/compiler/translator/TranslatorGLSL.cpp
@@ -40,17 +40,19 @@ void TranslatorGLSL::initBuiltInFunction
     {
         InitBuiltInAtanFunctionEmulatorForGLSLWorkarounds(emu);
     }
 
     int targetGLSLVersion = ShaderOutputTypeToGLSLVersion(getOutputType());
     InitBuiltInFunctionEmulatorForGLSLMissingFunctions(emu, getShaderType(), targetGLSLVersion);
 }
 
-void TranslatorGLSL::translate(TIntermBlock *root, ShCompileOptions compileOptions)
+void TranslatorGLSL::translate(TIntermBlock *root,
+                               ShCompileOptions compileOptions,
+                               PerformanceDiagnostics * /*perfDiagnostics*/)
 {
     TInfoSinkBase &sink = getInfoSink().obj;
 
     // Write GLSL version.
     writeVersion(root);
 
     // Write extension behaviour as needed
     writeExtensionBehavior(root, compileOptions);
@@ -195,35 +197,28 @@ void TranslatorGLSL::translate(TIntermBl
 
     if (getShaderType() == GL_COMPUTE_SHADER && isComputeShaderLocalSizeDeclared())
     {
         const sh::WorkGroupSize &localSize = getComputeShaderLocalSize();
         sink << "layout (local_size_x=" << localSize[0] << ", local_size_y=" << localSize[1]
              << ", local_size_z=" << localSize[2] << ") in;\n";
     }
 
-    if (getShaderType() == GL_GEOMETRY_SHADER_OES)
+    if (getShaderType() == GL_GEOMETRY_SHADER_EXT)
     {
         WriteGeometryShaderLayoutQualifiers(
             sink, getGeometryShaderInputPrimitiveType(), getGeometryShaderInvocations(),
             getGeometryShaderOutputPrimitiveType(), getGeometryShaderMaxVertices());
     }
 
     // Write translated shader.
     TOutputGLSL outputGLSL(sink, getArrayIndexClampingStrategy(), getHashFunction(), getNameMap(),
                            &getSymbolTable(), getShaderType(), getShaderVersion(), getOutputType(),
                            compileOptions);
 
-    if (compileOptions & SH_TRANSLATE_VIEWID_OVR_TO_UNIFORM)
-    {
-        TName uniformName(TString("ViewID_OVR"));
-        uniformName.setInternal(true);
-        sink << "uniform int " << outputGLSL.hashName(uniformName) << ";\n";
-    }
-
     root->traverse(&outputGLSL);
 }
 
 bool TranslatorGLSL::shouldFlattenPragmaStdglInvariantAll()
 {
     // Required when outputting to any GLSL version greater than 1.20, but since ANGLE doesn't
     // translate to that version, return true for the next higher version.
     return IsGLSL130OrNewer(getOutputType());
@@ -271,17 +266,17 @@ void TranslatorGLSL::writeExtensionBehav
             }
 
             if (iter.first == TExtension::EXT_draw_buffers)
             {
                 sink << "#extension GL_ARB_draw_buffers : " << GetBehaviorString(iter.second)
                      << "\n";
             }
 
-            if (iter.first == TExtension::OES_geometry_shader)
+            if (iter.first == TExtension::EXT_geometry_shader)
             {
                 sink << "#extension GL_ARB_geometry_shader4 : " << GetBehaviorString(iter.second)
                      << "\n";
             }
         }
 
         const bool isMultiview = (iter.first == TExtension::OVR_multiview);
         if (isMultiview && getShaderType() == GL_VERTEX_SHADER &&
--- a/gfx/angle/src/compiler/translator/TranslatorGLSL.h
+++ b/gfx/angle/src/compiler/translator/TranslatorGLSL.h
@@ -16,17 +16,19 @@ class TranslatorGLSL : public TCompiler
 {
   public:
     TranslatorGLSL(sh::GLenum type, ShShaderSpec spec, ShShaderOutput output);
 
   protected:
     void initBuiltInFunctionEmulator(BuiltInFunctionEmulator *emu,
                                      ShCompileOptions compileOptions) override;
 
-    void translate(TIntermBlock *root, ShCompileOptions compileOptions) override;
+    void translate(TIntermBlock *root,
+                   ShCompileOptions compileOptions,
+                   PerformanceDiagnostics *perfDiagnostics) override;
     bool shouldFlattenPragmaStdglInvariantAll() override;
     bool shouldCollectVariables(ShCompileOptions compileOptions) override;
 
   private:
     void writeVersion(TIntermNode *root);
     void writeExtensionBehavior(TIntermNode *root, ShCompileOptions compileOptions);
     void conditionallyOutputInvariantDeclaration(const char *builtinVaryingName);
 };
--- a/gfx/angle/src/compiler/translator/TranslatorHLSL.cpp
+++ b/gfx/angle/src/compiler/translator/TranslatorHLSL.cpp
@@ -9,35 +9,39 @@
 #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/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"
 
 namespace sh
 {
 
 TranslatorHLSL::TranslatorHLSL(sh::GLenum type, ShShaderSpec spec, ShShaderOutput output)
     : TCompiler(type, spec, output)
 {
 }
 
-void TranslatorHLSL::translate(TIntermBlock *root, ShCompileOptions compileOptions)
+void TranslatorHLSL::translate(TIntermBlock *root,
+                               ShCompileOptions compileOptions,
+                               PerformanceDiagnostics *perfDiagnostics)
 {
     const ShBuiltInResources &resources = getResources();
     int numRenderTargets                = resources.EXT_draw_buffers ? resources.MaxDrawBuffers : 1;
 
     sh::AddDefaultReturnStatements(root);
 
     // Note that SimplifyLoopConditions needs to be run before any other AST transformations that
     // may need to generate new statements from loop conditions or loop expressions.
@@ -64,32 +68,41 @@ void TranslatorHLSL::translate(TIntermBl
 
     // HLSL doesn't support arrays as return values, we'll need to make functions that have an array
     // as a return value to use an out parameter to transfer the array data instead.
     ArrayReturnValueToOutParameter(root, &getSymbolTable());
 
     if (!shouldRunLoopAndIndexingValidation(compileOptions))
     {
         // HLSL doesn't support dynamic indexing of vectors and matrices.
-        RemoveDynamicIndexing(root, &getSymbolTable(), getShaderVersion());
+        RemoveDynamicIndexing(root, &getSymbolTable(), getShaderVersion(), perfDiagnostics);
     }
 
     // Work around D3D9 bug that would manifest in vertex shaders with selection blocks which
     // use a vertex attribute as a condition, and some related computation in the else block.
     if (getOutputType() == SH_HLSL_3_0_OUTPUT && getShaderType() == GL_VERTEX_SHADER)
     {
         sh::RewriteElseBlocks(root, &getSymbolTable());
     }
 
     // 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());
+    }
+
     bool precisionEmulation =
         getResources().WEBGL_debug_shader_precision && getPragma().debugShaderPrecision;
 
     if (precisionEmulation)
     {
         EmulatePrecision emulatePrecision(&getSymbolTable(), getShaderVersion());
         root->traverse(&emulatePrecision);
         emulatePrecision.updateTree();
@@ -110,17 +123,17 @@ void TranslatorHLSL::translate(TIntermBl
     if (((compileOptions & SH_REWRITE_INTEGER_UNARY_MINUS_OPERATOR) != 0) &&
         getShaderType() == GL_VERTEX_SHADER)
     {
         sh::RewriteUnaryMinusOperatorInt(root);
     }
 
     sh::OutputHLSL outputHLSL(getShaderType(), getShaderVersion(), getExtensionBehavior(),
                               getSourcePath(), getOutputType(), numRenderTargets, getUniforms(),
-                              compileOptions);
+                              compileOptions, &getSymbolTable(), perfDiagnostics);
 
     outputHLSL.output(root, getInfoSink().obj);
 
     mUniformBlockRegisterMap   = outputHLSL.getUniformBlockRegisterMap();
     mUniformRegisterMap        = outputHLSL.getUniformRegisterMap();
 }
 
 bool TranslatorHLSL::shouldFlattenPragmaStdglInvariantAll()
--- a/gfx/angle/src/compiler/translator/TranslatorHLSL.h
+++ b/gfx/angle/src/compiler/translator/TranslatorHLSL.h
@@ -19,24 +19,23 @@ class TranslatorHLSL : public TCompiler
     TranslatorHLSL *getAsTranslatorHLSL() override { return this; }
 
     bool hasUniformBlock(const std::string &interfaceBlockName) const;
     unsigned int getUniformBlockRegister(const std::string &interfaceBlockName) const;
 
     const std::map<std::string, unsigned int> *getUniformRegisterMap() const;
 
   protected:
-    void translate(TIntermBlock *root, ShCompileOptions compileOptions) override;
+    void translate(TIntermBlock *root,
+                   ShCompileOptions compileOptions,
+                   PerformanceDiagnostics *perfDiagnostics) override;
     bool shouldFlattenPragmaStdglInvariantAll() override;
 
     // collectVariables needs to be run always so registers can be assigned.
     bool shouldCollectVariables(ShCompileOptions compileOptions) override { return true; }
 
-    // Globals are initialized in output so it is redundant to initialize them in the AST.
-    bool needToInitializeGlobalsInAST() const override { return false; }
-
     std::map<std::string, unsigned int> mUniformBlockRegisterMap;
     std::map<std::string, unsigned int> mUniformRegisterMap;
 };
 
 }  // namespace sh
 
 #endif  // COMPILER_TRANSLATOR_TRANSLATORHLSL_H_
--- a/gfx/angle/src/compiler/translator/TranslatorVulkan.cpp
+++ b/gfx/angle/src/compiler/translator/TranslatorVulkan.cpp
@@ -7,32 +7,128 @@
 //   A GLSL-based translator that outputs shaders that fit GL_KHR_vulkan_glsl.
 //   The shaders are then fed into glslang to spit out SPIR-V (libANGLE-side).
 //   See: https://www.khronos.org/registry/vulkan/specs/misc/GL_KHR_vulkan_glsl.txt
 //
 
 #include "compiler/translator/TranslatorVulkan.h"
 
 #include "angle_gl.h"
+#include "common/utilities.h"
 #include "compiler/translator/OutputVulkanGLSL.h"
+#include "compiler/translator/util.h"
 
 namespace sh
 {
 
+class DeclareDefaultUniformsTraverser : public TIntermTraverser
+{
+  public:
+    DeclareDefaultUniformsTraverser(TInfoSinkBase *sink,
+                                    ShHashFunction64 hashFunction,
+                                    NameMap *nameMap)
+        : TIntermTraverser(true, true, true),
+          mSink(sink),
+          mHashFunction(hashFunction),
+          mNameMap(nameMap),
+          mInDefaultUniform(false)
+    {
+    }
+
+    bool visitDeclaration(Visit visit, TIntermDeclaration *node) override
+    {
+        const TIntermSequence &sequence = *(node->getSequence());
+
+        // TODO(jmadill): Compound declarations.
+        ASSERT(sequence.size() == 1);
+
+        TIntermTyped *variable = sequence.front()->getAsTyped();
+        const TType &type      = variable->getType();
+        bool isUniform = (type.getQualifier() == EvqUniform) && !IsOpaqueType(type.getBasicType());
+
+        if (visit == PreVisit)
+        {
+            if (isUniform)
+            {
+                (*mSink) << "    " << GetTypeName(type, mHashFunction, mNameMap) << " ";
+                mInDefaultUniform = true;
+            }
+        }
+        else if (visit == InVisit)
+        {
+            mInDefaultUniform = isUniform;
+        }
+        else if (visit == PostVisit)
+        {
+            if (isUniform)
+            {
+                (*mSink) << ";\n";
+
+                // Remove the uniform declaration from the tree so it isn't parsed again.
+                TIntermSequence emptyReplacement;
+                mMultiReplacements.push_back(NodeReplaceWithMultipleEntry(
+                    getParentNode()->getAsBlock(), node, emptyReplacement));
+            }
+
+            mInDefaultUniform = false;
+        }
+        return true;
+    }
+
+    void visitSymbol(TIntermSymbol *symbol) override
+    {
+        if (mInDefaultUniform)
+        {
+            const TString &name = symbol->variable().name();
+            ASSERT(name.substr(0, 3) != "gl_");
+            (*mSink) << HashName(name, mHashFunction, mNameMap);
+        }
+    }
+
+  private:
+    TInfoSinkBase *mSink;
+    ShHashFunction64 mHashFunction;
+    NameMap *mNameMap;
+    bool mInDefaultUniform;
+};
+
 TranslatorVulkan::TranslatorVulkan(sh::GLenum type, ShShaderSpec spec)
     : TCompiler(type, spec, SH_GLSL_450_CORE_OUTPUT)
 {
 }
 
-void TranslatorVulkan::translate(TIntermBlock *root, ShCompileOptions compileOptions)
+void TranslatorVulkan::translate(TIntermBlock *root,
+                                 ShCompileOptions compileOptions,
+                                 PerformanceDiagnostics * /*perfDiagnostics*/)
 {
     TInfoSinkBase &sink = getInfoSink().obj;
 
     sink << "#version 450 core\n";
 
+    // Write out default uniforms into a uniform block assigned to a specific set/binding.
+    int defaultUniformCount = 0;
+    for (const auto &uniform : getUniforms())
+    {
+        if (!uniform.isBuiltIn() && uniform.staticUse && !gl::IsOpaqueType(uniform.type))
+        {
+            ++defaultUniformCount;
+        }
+    }
+
+    if (defaultUniformCount > 0)
+    {
+        sink << "\nlayout(@@ DEFAULT-UNIFORMS-SET-BINDING @@) uniform defaultUniforms\n{\n";
+
+        DeclareDefaultUniformsTraverser defaultTraverser(&sink, getHashFunction(), &getNameMap());
+        root->traverse(&defaultTraverser);
+        defaultTraverser.updateTree();
+
+        sink << "};\n";
+    }
+
     // Declare gl_FragColor and glFragData as webgl_FragColor and webgl_FragData
     // if it's core profile shaders and they are used.
     if (getShaderType() == GL_FRAGMENT_SHADER)
     {
         bool hasGLFragColor = false;
         bool hasGLFragData  = false;
 
         for (const auto &outputVar : outputVariables)
--- a/gfx/angle/src/compiler/translator/TranslatorVulkan.h
+++ b/gfx/angle/src/compiler/translator/TranslatorVulkan.h
@@ -18,15 +18,17 @@ namespace sh
 {
 
 class TranslatorVulkan : public TCompiler
 {
   public:
     TranslatorVulkan(sh::GLenum type, ShShaderSpec spec);
 
   protected:
-    void translate(TIntermBlock *root, ShCompileOptions compileOptions) override;
+    void translate(TIntermBlock *root,
+                   ShCompileOptions compileOptions,
+                   PerformanceDiagnostics *perfDiagnostics) override;
     bool shouldFlattenPragmaStdglInvariantAll() override;
 };
 
 }  // namespace sh
 
 #endif  // COMPILER_TRANSLATOR_TRANSLATORVULKAN_H_
--- a/gfx/angle/src/compiler/translator/Types.cpp
+++ b/gfx/angle/src/compiler/translator/Types.cpp
@@ -108,41 +108,165 @@ const char *getBasicString(TBasicType t)
         case EbtAtomicCounter:
             return "atomic_uint";
         default:
             UNREACHABLE();
             return "unknown type";
     }
 }
 
+// TType implementation.
+TType::TType()
+    : type(EbtVoid),
+      precision(EbpUndefined),
+      qualifier(EvqGlobal),
+      invariant(false),
+      memoryQualifier(TMemoryQualifier::Create()),
+      layoutQualifier(TLayoutQualifier::Create()),
+      primarySize(0),
+      secondarySize(0),
+      mArraySizes(nullptr),
+      mInterfaceBlock(nullptr),
+      mStructure(nullptr),
+      mIsStructSpecifier(false),
+      mMangledName(nullptr)
+{
+}
+
+TType::TType(TBasicType t, unsigned char ps, unsigned char ss)
+    : type(t),
+      precision(EbpUndefined),
+      qualifier(EvqGlobal),
+      invariant(false),
+      memoryQualifier(TMemoryQualifier::Create()),
+      layoutQualifier(TLayoutQualifier::Create()),
+      primarySize(ps),
+      secondarySize(ss),
+      mArraySizes(nullptr),
+      mInterfaceBlock(nullptr),
+      mStructure(nullptr),
+      mIsStructSpecifier(false),
+      mMangledName(nullptr)
+{
+}
+
+TType::TType(TBasicType t, TPrecision p, TQualifier q, unsigned char ps, unsigned char ss)
+    : type(t),
+      precision(p),
+      qualifier(q),
+      invariant(false),
+      memoryQualifier(TMemoryQualifier::Create()),
+      layoutQualifier(TLayoutQualifier::Create()),
+      primarySize(ps),
+      secondarySize(ss),
+      mArraySizes(nullptr),
+      mInterfaceBlock(nullptr),
+      mStructure(nullptr),
+      mIsStructSpecifier(false),
+      mMangledName(nullptr)
+{
+}
+
 TType::TType(const TPublicType &p)
     : type(p.getBasicType()),
       precision(p.precision),
       qualifier(p.qualifier),
       invariant(p.invariant),
       memoryQualifier(p.memoryQualifier),
       layoutQualifier(p.layoutQualifier),
       primarySize(p.getPrimarySize()),
       secondarySize(p.getSecondarySize()),
-      interfaceBlock(0),
-      structure(0)
+      mArraySizes(nullptr),
+      mInterfaceBlock(nullptr),
+      mStructure(nullptr),
+      mIsStructSpecifier(false),
+      mMangledName(nullptr)
 {
     ASSERT(primarySize <= 4);
     ASSERT(secondarySize <= 4);
-    if (p.array)
+    if (p.isArray())
     {
-        makeArray(p.arraySize);
+        mArraySizes = new TVector<unsigned int>(*p.arraySizes);
     }
     if (p.getUserDef())
-        structure = p.getUserDef();
+    {
+        mStructure         = p.getUserDef();
+        mIsStructSpecifier = p.isStructSpecifier();
+    }
+}
+
+TType::TType(TStructure *userDef)
+    : type(EbtStruct),
+      precision(EbpUndefined),
+      qualifier(EvqTemporary),
+      invariant(false),
+      memoryQualifier(TMemoryQualifier::Create()),
+      layoutQualifier(TLayoutQualifier::Create()),
+      primarySize(1),
+      secondarySize(1),
+      mArraySizes(nullptr),
+      mInterfaceBlock(nullptr),
+      mStructure(userDef),
+      mIsStructSpecifier(false),
+      mMangledName(nullptr)
+{
 }
 
-bool TStructure::equals(const TStructure &other) const
+TType::TType(TInterfaceBlock *interfaceBlockIn,
+             TQualifier qualifierIn,
+             TLayoutQualifier layoutQualifierIn)
+    : type(EbtInterfaceBlock),
+      precision(EbpUndefined),
+      qualifier(qualifierIn),
+      invariant(false),
+      memoryQualifier(TMemoryQualifier::Create()),
+      layoutQualifier(layoutQualifierIn),
+      primarySize(1),
+      secondarySize(1),
+      mArraySizes(nullptr),
+      mInterfaceBlock(interfaceBlockIn),
+      mStructure(0),
+      mIsStructSpecifier(false),
+      mMangledName(nullptr)
 {
-    return (uniqueId() == other.uniqueId());
+}
+
+TType::TType(const TType &t)
+    : type(t.type),
+      precision(t.precision),
+      qualifier(t.qualifier),
+      invariant(t.invariant),
+      memoryQualifier(t.memoryQualifier),
+      layoutQualifier(t.layoutQualifier),
+      primarySize(t.primarySize),
+      secondarySize(t.secondarySize),
+      mArraySizes(t.mArraySizes ? new TVector<unsigned int>(*t.mArraySizes) : nullptr),
+      mInterfaceBlock(t.mInterfaceBlock),
+      mStructure(t.mStructure),
+      mIsStructSpecifier(t.mIsStructSpecifier),
+      mMangledName(t.mMangledName)
+{
+}
+
+TType &TType::operator=(const TType &t)
+{
+    type               = t.type;
+    precision          = t.precision;
+    qualifier          = t.qualifier;
+    invariant          = t.invariant;
+    memoryQualifier    = t.memoryQualifier;
+    layoutQualifier    = t.layoutQualifier;
+    primarySize        = t.primarySize;
+    secondarySize      = t.secondarySize;
+    mArraySizes        = t.mArraySizes ? new TVector<unsigned int>(*t.mArraySizes) : nullptr;
+    mInterfaceBlock    = t.mInterfaceBlock;
+    mStructure         = t.mStructure;
+    mIsStructSpecifier = t.mIsStructSpecifier;
+    mMangledName       = t.mMangledName;
+    return *this;
 }
 
 bool TType::canBeConstructed() const
 {
     switch (type)
     {
         case EbtFloat:
         case EbtInt:
@@ -276,417 +400,482 @@ TString TType::getCompleteString() const
     TStringStream stream;
 
     if (invariant)
         stream << "invariant ";
     if (qualifier != EvqTemporary && qualifier != EvqGlobal)
         stream << getQualifierString() << " ";
     if (precision != EbpUndefined)
         stream << getPrecisionString() << " ";
-    for (auto arraySizeIter = mArraySizes.rbegin(); arraySizeIter != mArraySizes.rend();
-         ++arraySizeIter)
+    if (mArraySizes)
     {
-        stream << "array[" << (*arraySizeIter) << "] of ";
+        for (auto arraySizeIter = mArraySizes->rbegin(); arraySizeIter != mArraySizes->rend();
+             ++arraySizeIter)
+        {
+            stream << "array[" << (*arraySizeIter) << "] of ";
+        }
     }
     if (isMatrix())
         stream << getCols() << "X" << getRows() << " matrix of ";
     else if (isVector())
         stream << getNominalSize() << "-component vector of ";
 
     stream << getBasicString();
     return stream.str();
 }
 
+int TType::getDeepestStructNesting() const
+{
+    return mStructure ? mStructure->deepestNesting() : 0;
+}
+
+bool TType::isNamelessStruct() const
+{
+    return mStructure && mStructure->symbolType() == SymbolType::Empty;
+}
+
+bool TType::isStructureContainingArrays() const
+{
+    return mStructure ? mStructure->containsArrays() : false;
+}
+
+bool TType::isStructureContainingMatrices() const
+{
+    return mStructure ? mStructure->containsMatrices() : false;
+}
+
+bool TType::isStructureContainingType(TBasicType t) const
+{
+    return mStructure ? mStructure->containsType(t) : false;
+}
+
+bool TType::isStructureContainingSamplers() const
+{
+    return mStructure ? mStructure->containsSamplers() : false;
+}
+
 //
 // Recursively generate mangled names.
 //
-TString TType::buildMangledName() const
+const char *TType::buildMangledName() const
 {
     TString mangledName;
     if (isMatrix())
         mangledName += 'm';
     else if (isVector())
         mangledName += 'v';
 
-    switch (type)
+    const char *basicMangledName = GetBasicMangledName(type);
+    if (basicMangledName != nullptr)
+    {
+        mangledName += basicMangledName;
+    }
+    else
     {
-        case EbtFloat:
-            mangledName += 'f';
-            break;
-        case EbtInt:
-            mangledName += 'i';
-            break;
-        case EbtUInt:
-            mangledName += 'u';
-            break;
-        case EbtBool:
-            mangledName += 'b';
-            break;
-        case EbtYuvCscStandardEXT:
-            mangledName += "ycs";
-            break;
-        case EbtSampler2D:
-            mangledName += "s2";
-            break;
-        case EbtSampler3D:
-            mangledName += "s3";
-            break;
-        case EbtSamplerCube:
-            mangledName += "sC";
-            break;
-        case EbtSampler2DArray:
-            mangledName += "s2a";
-            break;
-        case EbtSamplerExternalOES:
-            mangledName += "sext";
-            break;
-        case EbtSamplerExternal2DY2YEXT:
-            mangledName += "sext2y2y";
-            break;
-        case EbtSampler2DRect:
-            mangledName += "s2r";
-            break;
-        case EbtSampler2DMS:
-            mangledName += "s2ms";
-            break;
-        case EbtISampler2D:
-            mangledName += "is2";
-            break;
-        case EbtISampler3D:
-            mangledName += "is3";
-            break;
-        case EbtISamplerCube:
-            mangledName += "isC";
-            break;
-        case EbtISampler2DArray:
-            mangledName += "is2a";
-            break;
-        case EbtISampler2DMS:
-            mangledName += "is2ms";
-            break;
-        case EbtUSampler2D:
-            mangledName += "us2";
-            break;
-        case EbtUSampler3D:
-            mangledName += "us3";
-            break;
-        case EbtUSamplerCube:
-            mangledName += "usC";
-            break;
-        case EbtUSampler2DArray:
-            mangledName += "us2a";
-            break;
-        case EbtUSampler2DMS:
-            mangledName += "us2ms";
-            break;
-        case EbtSampler2DShadow:
-            mangledName += "s2s";
-            break;
-        case EbtSamplerCubeShadow:
-            mangledName += "sCs";
-            break;
-        case EbtSampler2DArrayShadow:
-            mangledName += "s2as";
-            break;
-        case EbtImage2D:
-            mangledName += "im2";
-            break;
-        case EbtIImage2D:
-            mangledName += "iim2";
-            break;
-        case EbtUImage2D:
-            mangledName += "uim2";
-            break;
-        case EbtImage3D:
-            mangledName += "im3";
-            break;
-        case EbtIImage3D:
-            mangledName += "iim3";
-            break;
-        case EbtUImage3D:
-            mangledName += "uim3";
-            break;
-        case EbtImage2DArray:
-            mangledName += "im2a";
-            break;
-        case EbtIImage2DArray:
-            mangledName += "iim2a";
-            break;
-        case EbtUImage2DArray:
-            mangledName += "uim2a";
-            break;
-        case EbtImageCube:
-            mangledName += "imc";
-            break;
-        case EbtIImageCube:
-            mangledName += "iimc";
-            break;
-        case EbtUImageCube:
-            mangledName += "uimc";
-            break;
-        case EbtAtomicCounter:
-            mangledName += "ac";
-            break;
-        case EbtStruct:
-            mangledName += structure->mangledName();
-            break;
-        case EbtInterfaceBlock:
-            mangledName += interfaceBlock->mangledName();
-            break;
-        default:
-            // EbtVoid, EbtAddress and non types
-            break;
+        ASSERT(type == EbtStruct || type == EbtInterfaceBlock);
+        switch (type)
+        {
+            case EbtStruct:
+                mangledName += "struct-";
+                if (mStructure->symbolType() != SymbolType::Empty)
+                {
+                    mangledName += mStructure->name();
+                }
+                mangledName += mStructure->mangledFieldList();
+                break;
+            case EbtInterfaceBlock:
+                mangledName += "iblock-";
+                mangledName += mInterfaceBlock->name();
+                mangledName += mInterfaceBlock->mangledFieldList();
+                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());
     }
 
-    for (unsigned int arraySize : mArraySizes)
+    if (mArraySizes)
     {
-        char buf[20];
-        snprintf(buf, sizeof(buf), "%d", arraySize);
-        mangledName += '[';
-        mangledName += buf;
-        mangledName += ']';
+        for (unsigned int arraySize : *mArraySizes)
+        {
+            char buf[20];
+            snprintf(buf, sizeof(buf), "%d", arraySize);
+            mangledName += '[';
+            mangledName += buf;
+            mangledName += ']';
+        }
     }
-    return mangledName;
+
+    mangledName += ';';
+
+    // Copy string contents into a pool-allocated buffer, so we never need to call delete.
+    size_t requiredSize = mangledName.size() + 1;
+    char *buffer = reinterpret_cast<char *>(GetGlobalPoolAllocator()->allocate(requiredSize));
+    memcpy(buffer, mangledName.c_str(), requiredSize);
+    return buffer;
 }
 
 size_t TType::getObjectSize() const
 {
     size_t totalSize;
 
     if (getBasicType() == EbtStruct)
-        totalSize = structure->objectSize();
+        totalSize = mStructure->objectSize();
     else
         totalSize = primarySize * secondarySize;
 
     if (totalSize == 0)
         return 0;
 
-    for (size_t arraySize : mArraySizes)
+    if (mArraySizes)
     {
-        if (arraySize > INT_MAX / totalSize)
-            totalSize = INT_MAX;
-        else
-            totalSize *= arraySize;
+        for (size_t arraySize : *mArraySizes)
+        {
+            if (arraySize > INT_MAX / totalSize)
+                totalSize = INT_MAX;
+            else
+                totalSize *= arraySize;
+        }
     }
 
     return totalSize;
 }
 
 int TType::getLocationCount() const
 {
     int count = 1;
 
     if (getBasicType() == EbtStruct)
     {
-        count = structure->getLocationCount();
+        count = mStructure->getLocationCount();
     }
 
     if (count == 0)
     {
         return 0;
     }
 
-    for (unsigned int arraySize : mArraySizes)
+    if (mArraySizes)
     {
-        if (arraySize > static_cast<unsigned int>(std::numeric_limits<int>::max() / count))
+        for (unsigned int arraySize : *mArraySizes)
         {
-            count = std::numeric_limits<int>::max();
-        }
-        else
-        {
-            count *= static_cast<int>(arraySize);
+            if (arraySize > static_cast<unsigned int>(std::numeric_limits<int>::max() / count))
+            {
+                count = std::numeric_limits<int>::max();
+            }
+            else
+            {
+                count *= static_cast<int>(arraySize);
+            }
         }
     }
 
     return count;
 }
 
 unsigned int TType::getArraySizeProduct() const
 {
+    if (!mArraySizes)
+        return 1u;
+
     unsigned int product = 1u;
-    for (unsigned int arraySize : mArraySizes)
+
+    for (unsigned int arraySize : *mArraySizes)
     {
         product *= arraySize;
     }
     return product;
 }
 
 bool TType::isUnsizedArray() const
 {
-    for (unsigned int arraySize : mArraySizes)
+    if (!mArraySizes)
+        return false;
+
+    for (unsigned int arraySize : *mArraySizes)
     {
         if (arraySize == 0u)
         {
             return true;
         }
     }
     return false;
 }
 
 bool TType::sameNonArrayType(const TType &right) const
 {
     return (type == right.type && primarySize == right.primarySize &&
-            secondarySize == right.secondarySize && structure == right.structure);
+            secondarySize == right.secondarySize && mStructure == right.mStructure);
 }
 
 bool TType::isElementTypeOf(const TType &arrayType) const
 {
     if (!sameNonArrayType(arrayType))
     {
         return false;
     }
-    if (arrayType.mArraySizes.size() != mArraySizes.size() + 1u)
+    if (arrayType.getNumArraySizes() != getNumArraySizes() + 1u)
     {
         return false;
     }
-    for (size_t i = 0; i < mArraySizes.size(); ++i)
+    if (isArray())
     {
-        if (mArraySizes[i] != arrayType.mArraySizes[i])
+        for (size_t i = 0; i < mArraySizes->size(); ++i)
         {
-            return false;
+            if ((*mArraySizes)[i] != (*arrayType.mArraySizes)[i])
+            {
+                return false;
+            }
         }
     }
     return true;
 }
 
-void TType::sizeUnsizedArrays(const TVector<unsigned int> &arraySizes)
+void TType::sizeUnsizedArrays(const TVector<unsigned int> *newArraySizes)
 {
-    for (size_t i = 0u; i < mArraySizes.size(); ++i)
+    size_t newArraySizesSize = newArraySizes ? newArraySizes->size() : 0;
+    for (size_t i = 0u; i < getNumArraySizes(); ++i)
     {
-        if (mArraySizes[i] == 0)
+        if ((*mArraySizes)[i] == 0)
         {
-            if (i < arraySizes.size())
+            if (i < newArraySizesSize)
             {
-                mArraySizes[i] = arraySizes[i];
+                ASSERT(newArraySizes != nullptr);
+                (*mArraySizes)[i] = (*newArraySizes)[i];
             }
             else
             {
-                mArraySizes[i] = 1u;
+                (*mArraySizes)[i] = 1u;
             }
         }
     }
     invalidateMangledName();
 }
 
-TStructure::TStructure(TSymbolTable *symbolTable, const TString *name, TFieldList *fields)
-    : TFieldListCollection(name, fields),
-      mDeepestNesting(0),
-      mUniqueId(symbolTable->nextUniqueId()),
-      mAtGlobalScope(false)
+void TType::sizeOutermostUnsizedArray(unsigned int arraySize)
+{
+    ASSERT(isArray());
+    ASSERT(mArraySizes->back() == 0u);
+    mArraySizes->back() = arraySize;
+}
+
+void TType::setBasicType(TBasicType t)
 {
+    if (type != t)
+    {
+        type = t;
+        invalidateMangledName();
+    }
+}
+
+void TType::setPrimarySize(unsigned char ps)
+{
+    if (primarySize != ps)
+    {
+        ASSERT(ps <= 4);
+        primarySize = ps;
+        invalidateMangledName();
+    }
 }
 
-bool TStructure::containsArrays() const
+void TType::setSecondarySize(unsigned char ss)
 {
-    for (size_t i = 0; i < mFields->size(); ++i)
+    if (secondarySize != ss)
     {
-        const TType *fieldType = (*mFields)[i]->type();
-        if (fieldType->isArray() || fieldType->isStructureContainingArrays())
-            return true;
+        ASSERT(ss <= 4);
+        secondarySize = ss;
+        invalidateMangledName();
     }
-    return false;
+}
+
+void TType::makeArray(unsigned int s)
+{
+    if (!mArraySizes)
+        mArraySizes = new TVector<unsigned int>();
+
+    mArraySizes->push_back(s);
+    invalidateMangledName();
+}
+
+void TType::makeArrays(const TVector<unsigned int> &sizes)
+{
+    if (!mArraySizes)
+        mArraySizes = new TVector<unsigned int>();
+
+    mArraySizes->insert(mArraySizes->end(), sizes.begin(), sizes.end());
+    invalidateMangledName();
 }
 
-bool TStructure::containsType(TBasicType type) const
+void TType::setArraySize(size_t arrayDimension, unsigned int s)
 {
-    for (size_t i = 0; i < mFields->size(); ++i)
+    ASSERT(mArraySizes != nullptr);
+    ASSERT(arrayDimension < mArraySizes->size());
+    if (mArraySizes->at(arrayDimension) != s)
     {
-        const TType *fieldType = (*mFields)[i]->type();
-        if (fieldType->getBasicType() == type || fieldType->isStructureContainingType(type))
-            return true;
+        (*mArraySizes)[arrayDimension] = s;
+        invalidateMangledName();
     }
-    return false;
+}
+
+void TType::toArrayElementType()
+{
+    ASSERT(mArraySizes != nullptr);
+    if (mArraySizes->size() > 0)
+    {
+        mArraySizes->pop_back();
+        invalidateMangledName();
+    }
 }
 
-bool TStructure::containsSamplers() const
+void TType::setInterfaceBlock(TInterfaceBlock *interfaceBlockIn)
 {
-    for (size_t i = 0; i < mFields->size(); ++i)
+    if (mInterfaceBlock != interfaceBlockIn)
+    {
+        mInterfaceBlock = interfaceBlockIn;
+        invalidateMangledName();
+    }
+}
+
+void TType::setStruct(TStructure *s)
+{
+    if (mStructure != s)
     {
-        const TType *fieldType = (*mFields)[i]->type();
-        if (IsSampler(fieldType->getBasicType()) || fieldType->isStructureContainingSamplers())
-            return true;
+        mStructure = s;
+        invalidateMangledName();
+    }
+}
+
+const char *TType::getMangledName() const
+{
+    if (mMangledName == nullptr)
+    {
+        mMangledName = buildMangledName();
     }
-    return false;
+
+    return mMangledName;
+}
+
+void TType::realize()
+{
+    getMangledName();
+}
+
+void TType::invalidateMangledName()
+{
+    mMangledName = nullptr;
 }
 
 void TType::createSamplerSymbols(const TString &namePrefix,
                                  const TString &apiNamePrefix,
-                                 TVector<TIntermSymbol *> *outputSymbols,
-                                 TMap<TIntermSymbol *, TString> *outputSymbolsToAPINames) const
+                                 TVector<const TVariable *> *outputSymbols,
+                                 TMap<const TVariable *, TString> *outputSymbolsToAPINames,
+                                 TSymbolTable *symbolTable) const
 {
     if (isStructureContainingSamplers())
     {
         if (isArray())
         {
             TType elementType(*this);
             elementType.toArrayElementType();
             for (unsigned int arrayIndex = 0u; arrayIndex < getOutermostArraySize(); ++arrayIndex)
             {
                 TStringStream elementName;
                 elementName << namePrefix << "_" << arrayIndex;
                 TStringStream elementApiName;
                 elementApiName << apiNamePrefix << "[" << arrayIndex << "]";
                 elementType.createSamplerSymbols(elementName.str(), elementApiName.str(),
-                                                 outputSymbols, outputSymbolsToAPINames);
+                                                 outputSymbols, outputSymbolsToAPINames,
+                                                 symbolTable);
             }
         }
         else
         {
-            structure->createSamplerSymbols(namePrefix, apiNamePrefix, outputSymbols,
-                                            outputSymbolsToAPINames);
+            mStructure->createSamplerSymbols(namePrefix, apiNamePrefix, outputSymbols,
+                                             outputSymbolsToAPINames, symbolTable);
         }
         return;
     }
+
     ASSERT(IsSampler(type));
-    TIntermSymbol *symbol = new TIntermSymbol(0, namePrefix, *this);
-    outputSymbols->push_back(symbol);
+    TVariable *variable   = new TVariable(symbolTable, NewPoolTString(namePrefix.c_str()), *this,
+                                        SymbolType::AngleInternal);
+    outputSymbols->push_back(variable);
     if (outputSymbolsToAPINames)
     {
-        (*outputSymbolsToAPINames)[symbol] = apiNamePrefix;
+        (*outputSymbolsToAPINames)[variable] = apiNamePrefix;
     }
 }
 
-void TStructure::createSamplerSymbols(const TString &namePrefix,
-                                      const TString &apiNamePrefix,
-                                      TVector<TIntermSymbol *> *outputSymbols,
-                                      TMap<TIntermSymbol *, TString> *outputSymbolsToAPINames) const
+TFieldListCollection::TFieldListCollection(const TFieldList *fields)
+    : mFields(fields), mObjectSize(0), mDeepestNesting(0)
+{
+}
+
+bool TFieldListCollection::containsArrays() const
+{
+    for (const auto *field : *mFields)
+    {
+        const TType *fieldType = field->type();
+        if (fieldType->isArray() || fieldType->isStructureContainingArrays())
+            return true;
+    }
+    return false;
+}
+
+bool TFieldListCollection::containsMatrices() const
 {
-    ASSERT(containsSamplers());
-    for (auto &field : *mFields)
+    for (const auto *field : *mFields)
+    {
+        const TType *fieldType = field->type();
+        if (fieldType->isMatrix() || fieldType->isStructureContainingMatrices())
+            return true;
+    }
+    return false;
+}
+
+bool TFieldListCollection::containsType(TBasicType type) const
+{
+    for (const auto *field : *mFields)
+    {
+        const TType *fieldType = field->type();
+        if (fieldType->getBasicType() == type || fieldType->isStructureContainingType(type))
+            return true;
+    }
+    return false;
+}
+
+bool TFieldListCollection::containsSamplers() const
+{
+    for (const auto *field : *mFields)
     {
         const TType *fieldType = field->type();
         if (IsSampler(fieldType->getBasicType()) || fieldType->isStructureContainingSamplers())
-        {
-            TString fieldName    = namePrefix + "_" + field->name();
-            TString fieldApiName = apiNamePrefix + "." + field->name();
-            fieldType->createSamplerSymbols(fieldName, fieldApiName, outputSymbols,
-                                            outputSymbolsToAPINames);
-        }
+            return true;
     }
+    return false;
 }
 
-TString TFieldListCollection::buildMangledName(const TString &mangledNamePrefix) const
+TString TFieldListCollection::buildMangledFieldList() const
 {
-    TString mangledName(mangledNamePrefix);
-    mangledName += *mName;
-    for (size_t i = 0; i < mFields->size(); ++i)
+    TString mangledName;
+    for (const auto *field : *mFields)
     {
         mangledName += '-';
-        mangledName += (*mFields)[i]->type()->getMangledName();
+        mangledName += field->type()->getMangledName();
     }
     return mangledName;
 }
 
 size_t TFieldListCollection::calculateObjectSize() const
 {
     size_t size = 0;
     for (const TField *field : *mFields)
@@ -695,16 +884,23 @@ size_t TFieldListCollection::calculateOb
         if (fieldSize > INT_MAX - size)
             size = INT_MAX;
         else
             size += fieldSize;
     }
     return size;
 }
 
+size_t TFieldListCollection::objectSize() const
+{
+    if (mObjectSize == 0)
+        mObjectSize = calculateObjectSize();
+    return mObjectSize;
+}
+
 int TFieldListCollection::getLocationCount() const
 {
     int count = 0;
     for (const TField *field : *mFields)
     {
         int fieldCount = field->type()->getLocationCount();
         if (fieldCount > std::numeric_limits<int>::max() - count)
         {
@@ -713,17 +909,96 @@ int TFieldListCollection::getLocationCou
         else
         {
             count += fieldCount;
         }
     }
     return count;
 }
 
-int TStructure::calculateDeepestNesting() const
+int TFieldListCollection::deepestNesting() const
+{
+    if (mDeepestNesting == 0)
+        mDeepestNesting = calculateDeepestNesting();
+    return mDeepestNesting;
+}
+
+const TString &TFieldListCollection::mangledFieldList() const
+{
+    if (mMangledFieldList.empty())
+        mMangledFieldList = buildMangledFieldList();
+    return mMangledFieldList;
+}
+
+int TFieldListCollection::calculateDeepestNesting() const
 {
     int maxNesting = 0;
     for (size_t i = 0; i < mFields->size(); ++i)
         maxNesting = std::max(maxNesting, (*mFields)[i]->type()->getDeepestStructNesting());
     return 1 + maxNesting;
 }
 
+// TPublicType implementation.
+void TPublicType::initialize(const TTypeSpecifierNonArray &typeSpecifier, TQualifier q)
+{
+    typeSpecifierNonArray = typeSpecifier;
+    layoutQualifier       = TLayoutQualifier::Create();
+    memoryQualifier       = TMemoryQualifier::Create();
+    qualifier             = q;
+    invariant             = false;
+    precision             = EbpUndefined;
+    arraySizes            = nullptr;
+}
+
+void TPublicType::initializeBasicType(TBasicType basicType)
+{
+    typeSpecifierNonArray.type          = basicType;
+    typeSpecifierNonArray.primarySize   = 1;
+    typeSpecifierNonArray.secondarySize = 1;
+    layoutQualifier                     = TLayoutQualifier::Create();
+    memoryQualifier                     = TMemoryQualifier::Create();
+    qualifier                           = EvqTemporary;
+    invariant                           = false;
+    precision                           = EbpUndefined;
+    arraySizes                          = nullptr;
+}
+
+bool TPublicType::isStructureContainingArrays() const
+{
+    if (!typeSpecifierNonArray.userDef)
+    {
+        return false;
+    }
+
+    return typeSpecifierNonArray.userDef->containsArrays();
+}
+
+bool TPublicType::isStructureContainingType(TBasicType t) const
+{
+    if (!typeSpecifierNonArray.userDef)
+    {
+        return false;
+    }
+
+    return typeSpecifierNonArray.userDef->containsType(t);
+}
+
+void TPublicType::setArraySizes(TVector<unsigned int> *sizes)
+{
+    arraySizes = sizes;
+}
+
+bool TPublicType::isArray() const
+{
+    return arraySizes && !arraySizes->empty();
+}
+
+void TPublicType::clearArrayness()
+{
+    arraySizes = nullptr;
+}
+
+bool TPublicType::isAggregate() const
+{
+    return isArray() || typeSpecifierNonArray.isMatrix() || typeSpecifierNonArray.isVector();
+}
+
 }  // namespace sh
--- a/gfx/angle/src/compiler/translator/Types.h
+++ b/gfx/angle/src/compiler/translator/Types.h
@@ -7,278 +7,154 @@
 #ifndef COMPILER_TRANSLATOR_TYPES_H_
 #define COMPILER_TRANSLATOR_TYPES_H_
 
 #include "common/angleutils.h"
 #include "common/debug.h"
 
 #include "compiler/translator/BaseTypes.h"
 #include "compiler/translator/Common.h"
+#include "compiler/translator/SymbolUniqueId.h"
 
 namespace sh
 {
 
 struct TPublicType;
 class TType;
+class TInterfaceBlock;
+class TStructure;
 class TSymbol;
+class TVariable;
 class TIntermSymbol;
 class TSymbolTable;
 
 class TField : angle::NonCopyable
 {
   public:
     POOL_ALLOCATOR_NEW_DELETE();
-    TField(TType *type, TString *name, const TSourceLoc &line)
+    TField(TType *type, const TString *name, const TSourceLoc &line)
         : mType(type), mName(name), mLine(line)
     {
+        ASSERT(mName);
     }
 
     // TODO(alokp): We should only return const type.
     // Fix it by tweaking grammar.
     TType *type() { return mType; }
     const TType *type() const { return mType; }
-
     const TString &name() const { return *mName; }
     const TSourceLoc &line() const { return mLine; }
 
   private:
     TType *mType;
-    TString *mName;
-    TSourceLoc mLine;
+    const TString *mName;
+    const TSourceLoc mLine;
 };
 
 typedef TVector<TField *> TFieldList;
-inline TFieldList *NewPoolTFieldList()
-{
-    void *memory = GetGlobalPoolAllocator()->allocate(sizeof(TFieldList));
-    return new (memory) TFieldList;
-}
 
 class TFieldListCollection : angle::NonCopyable
 {
   public:
-    const TString &name() const { return *mName; }
     const TFieldList &fields() const { return *mFields; }
 
-    size_t objectSize() const
-    {
-        if (mObjectSize == 0)
-            mObjectSize = calculateObjectSize();
-        return mObjectSize;
-    }
-
-    // How many locations the field list consumes as a uniform.
-    int getLocationCount() const;
-
-  protected:
-    TFieldListCollection(const TString *name, TFieldList *fields)
-        : mName(name), mFields(fields), mObjectSize(0)
-    {
-    }
-    TString buildMangledName(const TString &mangledNamePrefix) const;
-    size_t calculateObjectSize() const;
-
-    const TString *mName;
-    TFieldList *mFields;
-
-    mutable TString mMangledName;
-    mutable size_t mObjectSize;
-};
-
-// May also represent interface blocks
-class TStructure : public TFieldListCollection
-{
-  public:
-    POOL_ALLOCATOR_NEW_DELETE();
-    TStructure(TSymbolTable *symbolTable, const TString *name, TFieldList *fields);
-
-    int deepestNesting() const
-    {
-        if (mDeepestNesting == 0)
-            mDeepestNesting = calculateDeepestNesting();
-        return mDeepestNesting;
-    }
     bool containsArrays() const;
+    bool containsMatrices() const;
     bool containsType(TBasicType t) const;
     bool containsSamplers() const;
 
-    void createSamplerSymbols(const TString &namePrefix,
-                              const TString &apiNamePrefix,
-                              TVector<TIntermSymbol *> *outputSymbols,
-                              TMap<TIntermSymbol *, TString> *outputSymbolsToAPINames) const;
-
-    bool equals(const TStructure &other) const;
+    size_t objectSize() const;
+    // How many locations the field list consumes as a uniform.
+    int getLocationCount() const;
+    int deepestNesting() const;
+    const TString &mangledFieldList() const;
 
-    int uniqueId() const
-    {
-        ASSERT(mUniqueId != 0);
-        return mUniqueId;
-    }
-
-    void setAtGlobalScope(bool atGlobalScope) { mAtGlobalScope = atGlobalScope; }
+  protected:
+    TFieldListCollection(const TFieldList *fields);
 
-    bool atGlobalScope() const { return mAtGlobalScope; }
-
-    const TString &mangledName() const
-    {
-        if (mMangledName.empty())
-            mMangledName = buildMangledName("struct-");
-        return mMangledName;
-    }
+    const TFieldList *mFields;
 
   private:
-    // 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 TString &name)
-    {
-        TString *mutableName = const_cast<TString *>(mName);
-        *mutableName         = name;
-    }
-
+    size_t calculateObjectSize() const;
     int calculateDeepestNesting() const;
-
-    mutable int mDeepestNesting;
-    const int mUniqueId;
-    bool mAtGlobalScope;
-};
+    TString buildMangledFieldList() const;
 
-class TInterfaceBlock : public TFieldListCollection
-{
-  public:
-    POOL_ALLOCATOR_NEW_DELETE();
-    TInterfaceBlock(const TString *name,
-                    TFieldList *fields,
-                    const TString *instanceName,
-                    const TLayoutQualifier &layoutQualifier)
-        : TFieldListCollection(name, fields),
-          mInstanceName(instanceName),
-          mBlockStorage(layoutQualifier.blockStorage),
-          mMatrixPacking(layoutQualifier.matrixPacking),
-          mBinding(layoutQualifier.binding)
-    {
-    }
-
-    const TString &instanceName() const { return *mInstanceName; }
-    bool hasInstanceName() const { return mInstanceName != nullptr; }
-    TLayoutBlockStorage blockStorage() const { return mBlockStorage; }
-    TLayoutMatrixPacking matrixPacking() const { return mMatrixPacking; }
-    int blockBinding() const { return mBinding; }
-    const TString &mangledName() const
-    {
-        if (mMangledName.empty())
-            mMangledName = buildMangledName("iblock-");
-        return mMangledName;
-    }
-
-  private:
-    const TString *mInstanceName;  // for interface block instance names
-    TLayoutBlockStorage mBlockStorage;
-    TLayoutMatrixPacking mMatrixPacking;
-    int mBinding;
+    mutable size_t mObjectSize;
+    mutable int mDeepestNesting;
+    mutable TString mMangledFieldList;
 };
 
 //
 // Base class for things that have a type.
 //
 class TType
 {
   public:
     POOL_ALLOCATOR_NEW_DELETE();
-    TType()
-        : type(EbtVoid),
-          precision(EbpUndefined),
-          qualifier(EvqGlobal),
-          invariant(false),
-          memoryQualifier(TMemoryQualifier::create()),
-          layoutQualifier(TLayoutQualifier::create()),
-          primarySize(0),
-          secondarySize(0),
-          interfaceBlock(nullptr),
-          structure(nullptr)
-    {
-    }
-    explicit TType(TBasicType t, unsigned char ps = 1, unsigned char ss = 1)
-        : type(t),
-          precision(EbpUndefined),
-          qualifier(EvqGlobal),
-          invariant(false),
-          memoryQualifier(TMemoryQualifier::create()),
-          layoutQualifier(TLayoutQualifier::create()),
-          primarySize(ps),
-          secondarySize(ss),
-          interfaceBlock(0),
-          structure(0)
-    {
-    }
+    TType();
+    explicit TType(TBasicType t, unsigned char ps = 1, unsigned char ss = 1);
     TType(TBasicType t,
           TPrecision p,
           TQualifier q     = EvqTemporary,
           unsigned char ps = 1,
-          unsigned char ss = 1)
+          unsigned char ss = 1);
+    explicit TType(const TPublicType &p);
+    explicit TType(TStructure *userDef);
+    TType(TInterfaceBlock *interfaceBlockIn,
+          TQualifier qualifierIn,
+          TLayoutQualifier layoutQualifierIn);
+    TType(const TType &t);
+    TType &operator=(const TType &t);
+
+    constexpr TType(TBasicType t,
+                    TPrecision p,
+                    TQualifier q,
+                    unsigned char ps,
+                    unsigned char ss,
+                    const char *mangledName)
         : type(t),
           precision(p),
           qualifier(q),
           invariant(false),
-          memoryQualifier(TMemoryQualifier::create()),
-          layoutQualifier(TLayoutQualifier::create()),
+          memoryQualifier(TMemoryQualifier::Create()),
+          layoutQualifier(TLayoutQualifier::Create()),
           primarySize(ps),
           secondarySize(ss),
-          interfaceBlock(0),
-          structure(0)
-    {
-    }
-    explicit TType(const TPublicType &p);
-    explicit TType(TStructure *userDef)
-        : type(EbtStruct),
-          precision(EbpUndefined),
-          qualifier(EvqTemporary),
-          invariant(false),
-          memoryQualifier(TMemoryQualifier::create()),
-          layoutQualifier(TLayoutQualifier::create()),
-          primarySize(1),
-          secondarySize(1),
-          interfaceBlock(0),
-          structure(userDef)
-    {
-    }
-    TType(TInterfaceBlock *interfaceBlockIn,
-          TQualifier qualifierIn,
-          TLayoutQualifier layoutQualifierIn)
-        : type(EbtInterfaceBlock),
-          precision(EbpUndefined),
-          qualifier(qualifierIn),
-          invariant(false),
-          memoryQualifier(TMemoryQualifier::create()),
-          layoutQualifier(layoutQualifierIn),
-          primarySize(1),
-          secondarySize(1),
-          interfaceBlock(interfaceBlockIn),
-          structure(0)
+          mArraySizes(nullptr),
+          mInterfaceBlock(nullptr),
+          mStructure(nullptr),
+          mIsStructSpecifier(false),
+          mMangledName(mangledName)
     {
     }
 
-    TType(const TType &) = default;
-    TType &operator=(const TType &) = default;
-
-    TBasicType getBasicType() const { return type; }
-    void setBasicType(TBasicType t)
+    constexpr TType(TType &&t)
+        : type(t.type),
+          precision(t.precision),
+          qualifier(t.qualifier),
+          invariant(t.invariant),
+          memoryQualifier(t.memoryQualifier),
+          layoutQualifier(t.layoutQualifier),
+          primarySize(t.primarySize),
+          secondarySize(t.secondarySize),
+          mArraySizes(t.mArraySizes),
+          mInterfaceBlock(t.mInterfaceBlock),
+          mStructure(t.mStructure),
+          mIsStructSpecifier(t.mIsStructSpecifier),
+          mMangledName(t.mMangledName)
     {
-        if (type != t)
-        {
-            type = t;
-            invalidateMangledName();
-        }
     }
 
+    constexpr TBasicType getBasicType() const { return type; }
+    void setBasicType(TBasicType t);
+
     TPrecision getPrecision() const { return precision; }
     void setPrecision(TPrecision p) { precision = p; }
 
-    TQualifier getQualifier() const { return qualifier; }
+    constexpr TQualifier getQualifier() const { return qualifier; }
     void setQualifier(TQualifier q) { qualifier = q; }
 
     bool isInvariant() const { return invariant; }
 
     void setInvariant(bool i) { invariant = i; }
 
     TMemoryQualifier getMemoryQualifier() const { return memoryQualifier; }
     void setMemoryQualifier(const TMemoryQualifier &mq) { memoryQualifier = mq; }
@@ -293,151 +169,111 @@ class TType
         ASSERT(isMatrix());
         return primarySize;
     }
     int getRows() const
     {
         ASSERT(isMatrix());
         return secondarySize;
     }
-    void setPrimarySize(unsigned char ps)
-    {
-        if (primarySize != ps)
-        {
-            ASSERT(ps <= 4);
-            primarySize = ps;
-            invalidateMangledName();
-        }
-    }
-    void setSecondarySize(unsigned char ss)
-    {
-        if (secondarySize != ss)
-        {
-            ASSERT(ss <= 4);
-            secondarySize = ss;
-            invalidateMangledName();
-        }
-    }
+    void setPrimarySize(unsigned char ps);
+    void setSecondarySize(unsigned char ss);
 
     // Full size of single instance of type
     size_t getObjectSize() const;
 
     // Get how many locations this type consumes as a uniform.
     int getLocationCount() const;
 
     bool isMatrix() const { return primarySize > 1 && secondarySize > 1; }
     bool isNonSquareMatrix() const { return isMatrix() && primarySize != secondarySize; }
-    bool isArray() const { return !mArraySizes.empty(); }
-    bool isArrayOfArrays() const { return mArraySizes.size() > 1u; }
-    const TVector<unsigned int> &getArraySizes() const { return mArraySizes; }
+    bool isArray() const { return mArraySizes != nullptr && !mArraySizes->empty(); }
+    bool isArrayOfArrays() const { return isArray() && mArraySizes->size() > 1u; }
+    size_t getNumArraySizes() const { return isArray() ? mArraySizes->size() : 0; }
+    const TVector<unsigned int> *getArraySizes() const { return mArraySizes; }
     unsigned int getArraySizeProduct() const;
     bool isUnsizedArray() const;
-    unsigned int getOutermostArraySize() const { return mArraySizes.back(); }
-    void makeArray(unsigned int s)
-    {
-        mArraySizes.push_back(s);
-        invalidateMangledName();
+    unsigned int getOutermostArraySize() const {
+         ASSERT(isArray());
+         return mArraySizes->back();
     }
+    void makeArray(unsigned int s);
+
+    // sizes contain new outermost array sizes.
+    void makeArrays(const TVector<unsigned int> &sizes);
     // Here, the array dimension value 0 corresponds to the innermost array.
-    void setArraySize(size_t arrayDimension, unsigned int s)
-    {
-        ASSERT(arrayDimension < mArraySizes.size());
-        if (mArraySizes.at(arrayDimension) != s)
-        {
-            mArraySizes[arrayDimension] = s;
-            invalidateMangledName();
-        }
-    }
+    void setArraySize(size_t arrayDimension, unsigned int s);
 
-    // Will set unsized array sizes according to arraySizes. In case there are more unsized arrays
-    // than there are sizes in arraySizes, defaults to setting array sizes to 1.
-    void sizeUnsizedArrays(const TVector<unsigned int> &arraySizes);
+    // Will set unsized array sizes according to newArraySizes. In case there are more
+    // unsized arrays than there are sizes in newArraySizes, defaults to setting any
+    // remaining array sizes to 1.
+    void sizeUnsizedArrays(const TVector<unsigned int> *newArraySizes);
+
+    // Will size the outermost array according to arraySize.
+    void sizeOutermostUnsizedArray(unsigned int arraySize);
 
     // Note that the array element type might still be an array type in GLSL ES version >= 3.10.
-    void toArrayElementType()
-    {
-        if (mArraySizes.size() > 0)
-        {
-            mArraySizes.pop_back();
-            invalidateMangledName();
-        }
-    }
+    void toArrayElementType();
 
-    TInterfaceBlock *getInterfaceBlock() const { return interfaceBlock; }
-    void setInterfaceBlock(TInterfaceBlock *interfaceBlockIn)
-    {
-        if (interfaceBlock != interfaceBlockIn)
-        {
-            interfaceBlock = interfaceBlockIn;
-            invalidateMangledName();
-        }
-    }
+    TInterfaceBlock *getInterfaceBlock() const { return mInterfaceBlock; }
+    void setInterfaceBlock(TInterfaceBlock *interfaceBlockIn);
     bool isInterfaceBlock() const { return type == EbtInterfaceBlock; }
 
     bool isVector() const { return primarySize > 1 && secondarySize == 1; }
     bool isScalar() const
     {
-        return primarySize == 1 && secondarySize == 1 && !structure && !isArray();
+        return primarySize == 1 && secondarySize == 1 && !mStructure && !isArray();
     }
     bool isScalarFloat() const { return isScalar() && type == EbtFloat; }
     bool isScalarInt() const { return isScalar() && (type == EbtInt || type == EbtUInt); }
 
     bool canBeConstructed() const;
 
-    TStructure *getStruct() const { return structure; }
-    void setStruct(TStructure *s)
-    {
-        if (structure != s)
-        {
-            structure = s;
-            invalidateMangledName();
-        }
-    }
+    TStructure *getStruct() { return mStructure; }
+    const TStructure *getStruct() const { return mStructure; }
+    void setStruct(TStructure *s);
 
-    const TString &getMangledName() const
-    {
-        if (mangled.empty())
-        {
-            mangled = buildMangledName();
-            mangled += ';';
-        }
-
-        return mangled;
-    }
+    const char *getMangledName() const;
 
     bool sameNonArrayType(const TType &right) const;
 
     // Returns true if arrayType is an array made of this type.
     bool isElementTypeOf(const TType &arrayType) const;
 
     bool operator==(const TType &right) const
     {
+        size_t numArraySizesL = getNumArraySizes();
+        size_t numArraySizesR = right.getNumArraySizes();
+        bool arraySizesEqual  = numArraySizesL == numArraySizesR &&
+                               (numArraySizesL == 0 || *mArraySizes == *right.mArraySizes);
         return type == right.type && primarySize == right.primarySize &&
-               secondarySize == right.secondarySize && mArraySizes == right.mArraySizes &&
-               structure == right.structure;
+               secondarySize == right.secondarySize && arraySizesEqual &&
+               mStructure == right.mStructure;
         // don't check the qualifier, it's not ever what's being sought after
     }
     bool operator!=(const TType &right) const { return !operator==(right); }
     bool operator<(const TType &right) const
     {
         if (type != right.type)
             return type < right.type;
         if (primarySize != right.primarySize)
             return primarySize < right.primarySize;
         if (secondarySize != right.secondarySize)
             return secondarySize < right.secondarySize;
-        if (mArraySizes.size() != right.mArraySizes.size())
-            return mArraySizes.size() < right.mArraySizes.size();
-        for (size_t i = 0; i < mArraySizes.size(); ++i)
+        size_t numArraySizesL = getNumArraySizes();
+        size_t numArraySizesR = right.getNumArraySizes();
+        if (numArraySizesL != numArraySizesR)
+            return numArraySizesL < numArraySizesR;
+        for (size_t i = 0; i < numArraySizesL; ++i)
         {
-            if (mArraySizes[i] != right.mArraySizes[i])
-                return mArraySizes[i] < right.mArraySizes[i];
+            if ((*mArraySizes)[i] != (*right.mArraySizes)[i])
+                return (*mArraySizes)[i] < (*right.mArraySizes)[i];
         }
-        if (structure != right.structure)
-            return structure < right.structure;
+        if (mStructure != right.mStructure)
+            return mStructure < right.mStructure;
 
         return false;
     }
 
     const char *getBasicString() const { return sh::getBasicString(type); }
 
     const char *getPrecisionString() const { return sh::getPrecisionString(precision); }
     const char *getQualifierString() const { return sh::getQualifierString(qualifier); }
@@ -453,68 +289,64 @@ class TType
     //   };
     //   struct nesting2 {
     //     nesting1 field1;
     //     vec4 field2;
     //   };
     // For type "nesting2", this method would return 2 -- the number
     // of structures through which indirection must occur to reach the
     // deepest field (nesting2.field1.position).
-    int getDeepestStructNesting() const { return structure ? structure->deepestNesting() : 0; }
+    int getDeepestStructNesting() const;
 
-    bool isStructureContainingArrays() const
-    {
-        return structure ? structure->containsArrays() : false;
-    }
+    bool isNamelessStruct() const;
 
-    bool isStructureContainingType(TBasicType t) const
-    {
-        return structure ? structure->containsType(t) : false;
-    }
+    bool isStructureContainingArrays() const;
+    bool isStructureContainingMatrices() const;
+    bool isStructureContainingType(TBasicType t) const;
+    bool isStructureContainingSamplers() const;
 
-    bool isStructureContainingSamplers() const
-    {
-        return structure ? structure->containsSamplers() : false;
-    }
+    bool isStructSpecifier() const { return mIsStructSpecifier; }
 
     void createSamplerSymbols(const TString &namePrefix,
                               const TString &apiNamePrefix,
-                              TVector<TIntermSymbol *> *outputSymbols,
-                              TMap<TIntermSymbol *, TString> *outputSymbolsToAPINames) const;
+                              TVector<const TVariable *> *outputSymbols,
+                              TMap<const TVariable *, TString> *outputSymbolsToAPINames,
+                              TSymbolTable *symbolTable) const;
 
     // Initializes all lazily-initialized members.
-    void realize() { getMangledName(); }
+    void realize();
 
   private:
-    void invalidateMangledName() { mangled = ""; }
-    TString buildMangledName() const;
+    void invalidateMangledName();
+    const char *buildMangledName() const;
 
     TBasicType type;
     TPrecision precision;
     TQualifier qualifier;
     bool invariant;
     TMemoryQualifier memoryQualifier;
     TLayoutQualifier layoutQualifier;
     unsigned char primarySize;    // size of vector or cols matrix
     unsigned char secondarySize;  // rows of a matrix
 
     // Used to make an array type. Outermost array size is stored at the end of the vector. Having 0
     // in this vector means an unsized array.
-    TVector<unsigned int> mArraySizes;
+    TVector<unsigned int> *mArraySizes;
 
     // This is set only in the following two cases:
     // 1) Represents an interface block.
     // 2) Represents the member variable of an unnamed interface block.
     // It's nullptr also for members of named interface blocks.
-    TInterfaceBlock *interfaceBlock;
+    TInterfaceBlock *mInterfaceBlock;
 
     // 0 unless this is a struct
-    TStructure *structure;
+    TStructure *mStructure;
+    bool mIsStructSpecifier;
 
-    mutable TString mangled;
+    mutable const char *mMangledName;
 };
 
 // TTypeSpecifierNonArray stores all of the necessary fields for type_specifier_nonarray from the
 // grammar
 struct TTypeSpecifierNonArray
 {
     TBasicType type;
     unsigned char primarySize;    // size of vector or cols of matrix
@@ -566,95 +398,48 @@ struct TTypeSpecifierNonArray
 // just be used while recognizing the grammar, not anything else.  Pointers
 // could be used, but also trying to avoid lots of memory management overhead.
 //
 // Not as bad as it looks, there is no actual assumption that the fields
 // match up or are name the same or anything like that.
 //
 struct TPublicType
 {
-    TTypeSpecifierNonArray typeSpecifierNonArray;
-    TLayoutQualifier layoutQualifier;
-    TMemoryQualifier memoryQualifier;
-    TQualifier qualifier;
-    bool invariant;
-    TPrecision precision;
-    bool array;
-    int arraySize;
+    // Must have a trivial default constructor since it is used in YYSTYPE.
+    TPublicType() = default;
 
-    void initialize(const TTypeSpecifierNonArray &typeSpecifier, TQualifier q)
-    {
-        typeSpecifierNonArray = typeSpecifier;
-        layoutQualifier       = TLayoutQualifier::create();
-        memoryQualifier       = TMemoryQualifier::create();
-        qualifier             = q;
-        invariant             = false;
-        precision             = EbpUndefined;
-        array                 = false;
-        arraySize             = 0;
-    }
-
-    void initializeBasicType(TBasicType basicType)
-    {
-        typeSpecifierNonArray.type          = basicType;
-        typeSpecifierNonArray.primarySize   = 1;
-        typeSpecifierNonArray.secondarySize = 1;
-        layoutQualifier                     = TLayoutQualifier::create();
-        memoryQualifier                     = TMemoryQualifier::create();
-        qualifier                           = EvqTemporary;
-        invariant                           = false;
-        precision                           = EbpUndefined;
-        array                               = false;
-        arraySize                           = 0;
-    }
+    void initialize(const TTypeSpecifierNonArray &typeSpecifier, TQualifier q);
+    void initializeBasicType(TBasicType basicType);
 
     TBasicType getBasicType() const { return typeSpecifierNonArray.type; }
     void setBasicType(TBasicType basicType) { typeSpecifierNonArray.type = basicType; }
 
     unsigned char getPrimarySize() const { return typeSpecifierNonArray.primarySize; }
     unsigned char getSecondarySize() const { return typeSpecifierNonArray.secondarySize; }
 
     TStructure *getUserDef() const { return typeSpecifierNonArray.userDef; }
     const TSourceLoc &getLine() const { return typeSpecifierNonArray.line; }
 
     bool isStructSpecifier() const { return typeSpecifierNonArray.isStructSpecifier; }
 
-    bool isStructureContainingArrays() const
-    {
-        if (!typeSpecifierNonArray.userDef)
-        {
-            return false;
-        }
-
-        return typeSpecifierNonArray.userDef->containsArrays();
-    }
-
-    bool isStructureContainingType(TBasicType t) const
-    {
-        if (!typeSpecifierNonArray.userDef)
-        {
-            return false;
-        }
+    bool isStructureContainingArrays() const;
+    bool isStructureContainingType(TBasicType t) const;
+    void setArraySizes(TVector<unsigned int> *sizes);
+    bool isArray() const;
+    void clearArrayness();
+    bool isAggregate() const;
 
-        return typeSpecifierNonArray.userDef->containsType(t);
-    }
+    TTypeSpecifierNonArray typeSpecifierNonArray;
+    TLayoutQualifier layoutQualifier;
+    TMemoryQualifier memoryQualifier;
+    TQualifier qualifier;
+    bool invariant;
+    TPrecision precision;
 
-    bool isUnsizedArray() const { return array && arraySize == 0; }
-    void setArraySize(int s)
-    {
-        array     = true;
-        arraySize = s;
-    }
-    void clearArrayness()
-    {
-        array     = false;
-        arraySize = 0;
-    }
-
-    bool isAggregate() const
-    {
-        return array || typeSpecifierNonArray.isMatrix() || typeSpecifierNonArray.isVector();
-    }
+    // Either nullptr or empty in case the type is not an array. The last element is the outermost
+    // array size. Note that due to bison restrictions, copies of the public type created by the
+    // copy constructor share the same arraySizes pointer.
+    const TVector<unsigned int> *arraySizes;
 };
 
 }  // namespace sh
 
 #endif  // COMPILER_TRANSLATOR_TYPES_H_
--- a/gfx/angle/src/compiler/translator/UnfoldShortCircuitToIf.cpp
+++ b/gfx/angle/src/compiler/translator/UnfoldShortCircuitToIf.cpp
@@ -7,16 +7,17 @@
 // 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"
 
 namespace sh
 {
 
 namespace
 {
 
@@ -70,56 +71,60 @@ bool UnfoldShortCircuitTraverser::visitB
         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;
             TType boolType(EbtBool, EbpUndefined, EvqTemporary);
+            TVariable *resultVariable = CreateTempVariable(mSymbolTable, boolType);
 
             ASSERT(node->getLeft()->getType() == boolType);
-            insertions.push_back(createTempInitDeclaration(node->getLeft()));
+            insertions.push_back(CreateTempInitDeclarationNode(resultVariable, node->getLeft()));
 
             TIntermBlock *assignRightBlock = new TIntermBlock();
             ASSERT(node->getRight()->getType() == boolType);
-            assignRightBlock->getSequence()->push_back(createTempAssignment(node->getRight()));
+            assignRightBlock->getSequence()->push_back(
+                CreateTempAssignmentNode(resultVariable, node->getRight()));
 
             TIntermUnary *notTempSymbol =
-                new TIntermUnary(EOpLogicalNot, createTempSymbol(boolType));
+                new TIntermUnary(EOpLogicalNot, CreateTempSymbolNode(resultVariable));
             TIntermIfElse *ifNode = new TIntermIfElse(notTempSymbol, assignRightBlock, nullptr);
             insertions.push_back(ifNode);
 
             insertStatementsInParentBlock(insertions);
 
-            queueReplacement(createTempSymbol(boolType), OriginalNode::IS_DROPPED);
+            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;
             TType boolType(EbtBool, EbpUndefined, EvqTemporary);
+            TVariable *resultVariable = CreateTempVariable(mSymbolTable, boolType);
 
             ASSERT(node->getLeft()->getType() == boolType);
-            insertions.push_back(createTempInitDeclaration(node->getLeft()));
+            insertions.push_back(CreateTempInitDeclarationNode(resultVariable, node->getLeft()));
 
             TIntermBlock *assignRightBlock = new TIntermBlock();
             ASSERT(node->getRight()->getType() == boolType);
-            assignRightBlock->getSequence()->push_back(createTempAssignment(node->getRight()));
+            assignRightBlock->getSequence()->push_back(
+                CreateTempAssignmentNode(resultVariable, node->getRight()));
 
             TIntermIfElse *ifNode =
-                new TIntermIfElse(createTempSymbol(boolType), assignRightBlock, nullptr);
+                new TIntermIfElse(CreateTempSymbolNode(resultVariable), assignRightBlock, nullptr);
             insertions.push_back(ifNode);
 
             insertStatementsInParentBlock(insertions);
 
-            queueReplacement(createTempSymbol(boolType), OriginalNode::IS_DROPPED);
+            queueReplacement(CreateTempSymbolNode(resultVariable), OriginalNode::IS_DROPPED);
             return false;
         }
         default:
             UNREACHABLE();
             return true;
     }
 }
 
@@ -133,44 +138,46 @@ bool UnfoldShortCircuitTraverser::visitT
 
     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 = createTempDeclaration(node->getType());
+    TIntermDeclaration *tempDeclaration = nullptr;
+    TVariable *resultVariable =
+        DeclareTempVariable(mSymbolTable, node->getType(), EvqTemporary, &tempDeclaration);
     insertions.push_back(tempDeclaration);
 
     TIntermBlock *trueBlock       = new TIntermBlock();
-    TIntermBinary *trueAssignment = createTempAssignment(node->getTrueExpression());
+    TIntermBinary *trueAssignment =
+        CreateTempAssignmentNode(resultVariable, node->getTrueExpression());
     trueBlock->getSequence()->push_back(trueAssignment);
 
     TIntermBlock *falseBlock       = new TIntermBlock();
-    TIntermBinary *falseAssignment = createTempAssignment(node->getFalseExpression());
+    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 = createTempSymbol(node->getType());
+    TIntermSymbol *ternaryResult = CreateTempSymbolNode(resultVariable);
     queueReplacement(ternaryResult, OriginalNode::IS_DROPPED);
 
     return false;
 }
 
 void UnfoldShortCircuitTraverser::nextIteration()
 {
     mFoundShortCircuit = false;
-    nextTemporaryId();
 }
 
 }  // namespace
 
 void UnfoldShortCircuitToIf(TIntermNode *root, TSymbolTable *symbolTable)
 {
     UnfoldShortCircuitTraverser traverser(symbolTable);
     // Unfold one operator at a time, and reset the traverser between iterations.
--- a/gfx/angle/src/compiler/translator/UniformHLSL.cpp
+++ b/gfx/angle/src/compiler/translator/UniformHLSL.cpp
@@ -33,17 +33,17 @@ static const char *UniformRegisterPrefix
     }
 }
 
 static TString InterfaceBlockFieldTypeString(const TField &field, TLayoutBlockStorage blockStorage)
 {
     const TType &fieldType                   = *field.type();
     const TLayoutMatrixPacking matrixPacking = fieldType.getLayoutQualifier().matrixPacking;
     ASSERT(matrixPacking != EmpUnspecified);
-    TStructure *structure = fieldType.getStruct();
+    const TStructure *structure = fieldType.getStruct();
 
     if (fieldType.isMatrix())
     {
         // Use HLSL row-major packing for GLSL column-major matrices
         const TString &matrixPackString =
             (matrixPacking == EmpRowMajor ? "column_major" : "row_major");
         return matrixPackString + " " + TypeString(fieldType);
     }
@@ -87,22 +87,27 @@ void OutputSamplerIndexArrayInitializer(
             out << (startIndex + i);
         }
     }
     out << "}";
 }
 
 }  // anonymous namespace
 
-UniformHLSL::UniformHLSL(StructureHLSL *structureHLSL,
+UniformHLSL::UniformHLSL(sh::GLenum shaderType,
+                         StructureHLSL *structureHLSL,
                          ShShaderOutput outputType,
-                         const std::vector<Uniform> &uniforms)
-    : mUniformRegister(0),
+                         const std::vector<Uniform> &uniforms,
+                         unsigned int firstUniformRegister)
+    : mUniformRegister(firstUniformRegister),
       mUniformBlockRegister(0),
-      mSamplerRegister(0),
+      mTextureRegister(0),
+      mRWTextureRegister(0),
+      mSamplerCount(0),
+      mShaderType(shaderType),
       mStructureHLSL(structureHLSL),
       mOutputType(outputType),
       mUniforms(uniforms)
 {
 }
 
 void UniformHLSL::reserveUniformRegisters(unsigned int registerCount)
 {
@@ -126,29 +131,46 @@ const Uniform *UniformHLSL::findUniformB
 
     return nullptr;
 }
 
 unsigned int UniformHLSL::assignUniformRegister(const TType &type,
                                                 const TString &name,
                                                 unsigned int *outRegisterCount)
 {
-    unsigned int registerIndex =
-        (IsSampler(type.getBasicType()) ? mSamplerRegister : mUniformRegister);
-
+    unsigned int registerIndex;
     const Uniform *uniform = findUniformByName(name);
     ASSERT(uniform);
 
+    if (IsSampler(type.getBasicType()) ||
+        (IsImage(type.getBasicType()) && type.getMemoryQualifier().readonly))
+    {
+        registerIndex = mTextureRegister;
+    }
+    else if (IsImage(type.getBasicType()))
+    {
+        registerIndex = mRWTextureRegister;
+    }
+    else
+    {
+        registerIndex = mUniformRegister;
+    }
+
     mUniformRegisterMap[uniform->name] = registerIndex;
 
     unsigned int registerCount = HLSLVariableRegisterCount(*uniform, mOutputType);
 
-    if (gl::IsSamplerType(uniform->type))
+    if (IsSampler(type.getBasicType()) ||
+        (IsImage(type.getBasicType()) && type.getMemoryQualifier().readonly))
     {
-        mSamplerRegister += registerCount;
+        mTextureRegister += registerCount;
+    }
+    else if (IsImage(type.getBasicType()))
+    {
+        mRWTextureRegister += registerCount;
     }
     else
     {
         mUniformRegister += registerCount;
     }
     if (outRegisterCount)
     {
         *outRegisterCount = registerCount;
@@ -157,43 +179,43 @@ unsigned int UniformHLSL::assignUniformR
 }
 
 unsigned int UniformHLSL::assignSamplerInStructUniformRegister(const TType &type,
                                                                const TString &name,
                                                                unsigned int *outRegisterCount)
 {
     // Sampler that is a field of a uniform structure.
     ASSERT(IsSampler(type.getBasicType()));
-    unsigned int registerIndex                     = mSamplerRegister;
+    unsigned int registerIndex                     = mTextureRegister;
     mUniformRegisterMap[std::string(name.c_str())] = registerIndex;
     unsigned int registerCount = type.isArray() ? type.getArraySizeProduct() : 1u;
-    mSamplerRegister += registerCount;
+    mTextureRegister += registerCount;
     if (outRegisterCount)
     {
         *outRegisterCount = registerCount;
     }
     return registerIndex;
 }
 
 void UniformHLSL::outputHLSLSamplerUniformGroup(
     TInfoSinkBase &out,
-    const HLSLTextureSamplerGroup textureGroup,
-    const TVector<const TIntermSymbol *> &group,
-    const TMap<const TIntermSymbol *, TString> &samplerInStructSymbolsToAPINames,
+    const HLSLTextureGroup textureGroup,
+    const TVector<const TVariable *> &group,
+    const TMap<const TVariable *, TString> &samplerInStructSymbolsToAPINames,
     unsigned int *groupTextureRegisterIndex)
 {
     if (group.empty())
     {
         return;
     }
     unsigned int groupRegisterCount = 0;
-    for (const TIntermSymbol *uniform : group)
+    for (const TVariable *uniform : group)
     {
         const TType &type   = uniform->getType();
-        const TString &name = uniform->getSymbol();
+        const TString &name = uniform->name();
         unsigned int registerCount;
 
         // The uniform might be just a regular sampler or one extracted from a struct.
         unsigned int samplerArrayIndex = 0u;
         const Uniform *uniformByName   = findUniformByName(name);
         if (uniformByName)
         {
             samplerArrayIndex = assignUniformRegister(type, name, &registerCount);
@@ -204,24 +226,24 @@ void UniformHLSL::outputHLSLSamplerUnifo
                    samplerInStructSymbolsToAPINames.end());
             samplerArrayIndex = assignSamplerInStructUniformRegister(
                 type, samplerInStructSymbolsToAPINames.at(uniform), &registerCount);
         }
         groupRegisterCount += registerCount;
 
         if (type.isArray())
         {
-            out << "static const uint " << DecorateVariableIfNeeded(uniform->getName())
-                << ArrayString(type) << " = ";
+            out << "static const uint " << DecorateVariableIfNeeded(*uniform) << ArrayString(type)
+                << " = ";
             OutputSamplerIndexArrayInitializer(out, type, samplerArrayIndex);
             out << ";\n";
         }
         else
         {
-            out << "static const uint " << DecorateVariableIfNeeded(uniform->getName()) << " = "
+            out << "static const uint " << DecorateVariableIfNeeded(*uniform) << " = "
                 << samplerArrayIndex << ";\n";
         }
     }
     TString suffix = TextureGroupSuffix(textureGroup);
     // Since HLSL_TEXTURE_2D is the first group, it has a fixed offset of zero.
     if (textureGroup != HLSL_TEXTURE_2D)
     {
         out << "static const uint textureIndexOffset" << suffix << " = "
@@ -235,244 +257,288 @@ void UniformHLSL::outputHLSLSamplerUnifo
     out << "uniform " << SamplerString(textureGroup) << " samplers" << suffix << "["
         << groupRegisterCount << "]"
         << " : register(s" << (*groupTextureRegisterIndex) << ");\n";
     *groupTextureRegisterIndex += groupRegisterCount;
 }
 
 void UniformHLSL::outputHLSL4_0_FL9_3Sampler(TInfoSinkBase &out,
                                              const TType &type,
-                                             const TName &name,
+                                             const TVariable &variable,
                                              const unsigned int registerIndex)
 {
     out << "uniform " << SamplerString(type.getBasicType()) << " sampler_"
-        << DecorateVariableIfNeeded(name) << ArrayString(type) << " : register(s"
+        << DecorateVariableIfNeeded(variable) << ArrayString(type) << " : register(s"
         << str(registerIndex) << ");\n";
     out << "uniform " << TextureString(type.getBasicType()) << " texture_"
-        << DecorateVariableIfNeeded(name) << ArrayString(type) << " : register(t"
+        << DecorateVariableIfNeeded(variable) << ArrayString(type) << " : register(t"
+        << str(registerIndex) << ");\n";
+}
+
+void UniformHLSL::outputHLSL4_1_FL11Texture(TInfoSinkBase &out,
+                                            const TType &type,
+                                            const TVariable &variable,
+                                            const unsigned int registerIndex)
+{
+    // TODO(xinghua.cao@intel.com): if image2D variable is bound on one layer of Texture3D or
+    // Texture2DArray. Translate this variable to HLSL Texture3D object or HLSL Texture2DArray
+    // object, or create a temporary Texture2D to save content of the layer and bind the
+    // temporary Texture2D to image2D variable.
+    out << "uniform "
+        << TextureString(type.getBasicType(), type.getLayoutQualifier().imageInternalFormat) << " "
+        << DecorateVariableIfNeeded(variable) << ArrayString(type) << " : register(t"
         << str(registerIndex) << ");\n";
+    return;
+}
+
+void UniformHLSL::outputHLSL4_1_FL11RWTexture(TInfoSinkBase &out,
+                                              const TType &type,
+                                              const TVariable &variable,
+                                              const unsigned int registerIndex)
+{
+    // TODO(xinghua.cao@intel.com): if image2D variable is bound on one layer of Texture3D or
+    // Texture2DArray. Translate this variable to HLSL RWTexture3D object or HLSL RWTexture2DArray
+    // object, or create a temporary Texture2D to save content of the layer and bind the
+    // temporary Texture2D to image2D variable.
+    if (mShaderType == GL_COMPUTE_SHADER)
+    {
+        out << "uniform "
+            << RWTextureString(type.getBasicType(), type.getLayoutQualifier().imageInternalFormat)
+            << " " << DecorateVariableIfNeeded(variable) << ArrayString(type) << " : register(u"
+            << str(registerIndex) << ");\n";
+    }
+    else
+    {
+        // TODO(xinghua.cao@intel.com): Support images in vertex shader and fragment shader,
+        // which are needed to sync binding value when linking program.
+    }
+    return;
 }
 
 void UniformHLSL::outputUniform(TInfoSinkBase &out,
                                 const TType &type,
-                                const TName &name,
+                                const TVariable &variable,
                                 const unsigned int registerIndex)
 {
     const TStructure *structure = type.getStruct();
     // If this is a nameless struct, we need to use its full definition, rather than its (empty)
     // name.
     // TypeString() will invoke defineNameless in this case; qualifier prefixes are unnecessary for
     // nameless structs in ES, as nameless structs cannot be used anywhere that layout qualifiers
     // are permitted.
-    const TString &typeName = ((structure && !structure->name().empty())
+    const TString &typeName = ((structure && structure->symbolType() != SymbolType::Empty)
                                    ? QualifiedStructNameString(*structure, false, false)
                                    : TypeString(type));
 
     const TString &registerString =
         TString("register(") + UniformRegisterPrefix(type) + str(registerIndex) + ")";
 
     out << "uniform " << typeName << " ";
 
-    out << DecorateVariableIfNeeded(name);
+    out << DecorateVariableIfNeeded(variable);
 
     out << ArrayString(type) << " : " << registerString << ";\n";
 }
 
 void UniformHLSL::uniformsHeader(TInfoSinkBase &out,
                                  ShShaderOutput outputType,
-                                 const ReferencedSymbols &referencedUniforms)
+                                 const ReferencedVariables &referencedUniforms,
+                                 TSymbolTable *symbolTable)
 {
     if (!referencedUniforms.empty())
     {
         out << "// Uniforms\n\n";
     }
     // In the case of HLSL 4, sampler uniforms need to be grouped by type before the code is
     // written. They are grouped based on the combination of the HLSL texture type and
     // HLSL sampler type, enumerated in HLSLTextureSamplerGroup.
-    TVector<TVector<const TIntermSymbol *>> groupedSamplerUniforms(HLSL_TEXTURE_MAX + 1);
-    TMap<const TIntermSymbol *, TString> samplerInStructSymbolsToAPINames;
+    TVector<TVector<const TVariable *>> groupedSamplerUniforms(HLSL_TEXTURE_MAX + 1);
+    TMap<const TVariable *, TString> samplerInStructSymbolsToAPINames;
+    TVector<const TVariable *> imageUniformsHLSL41Output;
     for (auto &uniformIt : referencedUniforms)
     {
         // Output regular uniforms. Group sampler uniforms by type.
-        const TIntermSymbol &uniform = *uniformIt.second;
-        const TType &type            = uniform.getType();
-        const TName &name            = uniform.getName();
+        const TVariable &variable = *uniformIt.second;
+        const TType &type         = variable.getType();
 
         if (outputType == SH_HLSL_4_1_OUTPUT && IsSampler(type.getBasicType()))
         {
-            HLSLTextureSamplerGroup group = TextureGroup(type.getBasicType());
-            groupedSamplerUniforms[group].push_back(&uniform);
+            HLSLTextureGroup group = TextureGroup(type.getBasicType());
+            groupedSamplerUniforms[group].push_back(&variable);
         }
         else if (outputType == SH_HLSL_4_0_FL9_3_OUTPUT && IsSampler(type.getBasicType()))
         {
-            unsigned int registerIndex = assignUniformRegister(type, name.getString(), nullptr);
-            outputHLSL4_0_FL9_3Sampler(out, type, name, registerIndex);
+            unsigned int registerIndex = assignUniformRegister(type, variable.name(), nullptr);
+            outputHLSL4_0_FL9_3Sampler(out, type, variable, registerIndex);
+        }
+        else if (outputType == SH_HLSL_4_1_OUTPUT && IsImage(type.getBasicType()))
+        {
+            imageUniformsHLSL41Output.push_back(&variable);
         }
         else
         {
             if (type.isStructureContainingSamplers())
             {
-                TVector<TIntermSymbol *> samplerSymbols;
-                TMap<TIntermSymbol *, TString> symbolsToAPINames;
-                type.createSamplerSymbols("angle_" + name.getString(), name.getString(),
-                                          &samplerSymbols, &symbolsToAPINames);
-                for (TIntermSymbol *sampler : samplerSymbols)
+                TVector<const TVariable *> samplerSymbols;
+                TMap<const TVariable *, TString> symbolsToAPINames;
+                type.createSamplerSymbols("angle_" + variable.name(), variable.name(),
+                                          &samplerSymbols, &symbolsToAPINames, symbolTable);
+                for (const TVariable *sampler : samplerSymbols)
                 {
                     const TType &samplerType = sampler->getType();
 
-                    // Will use angle_ prefix instead of regular prefix.
-                    sampler->setInternal(true);
-                    const TName &samplerName = sampler->getName();
-
                     if (outputType == SH_HLSL_4_1_OUTPUT)
                     {
-                        HLSLTextureSamplerGroup group = TextureGroup(samplerType.getBasicType());
+                        HLSLTextureGroup group = TextureGroup(samplerType.getBasicType());
                         groupedSamplerUniforms[group].push_back(sampler);
                         samplerInStructSymbolsToAPINames[sampler] = symbolsToAPINames[sampler];
                     }
                     else if (outputType == SH_HLSL_4_0_FL9_3_OUTPUT)
                     {
                         unsigned int registerIndex = assignSamplerInStructUniformRegister(
                             samplerType, symbolsToAPINames[sampler], nullptr);
-                        outputHLSL4_0_FL9_3Sampler(out, samplerType, samplerName, registerIndex);
+                        outputHLSL4_0_FL9_3Sampler(out, samplerType, *sampler, registerIndex);
                     }
                     else
                     {
                         ASSERT(outputType == SH_HLSL_3_0_OUTPUT);
                         unsigned int registerIndex = assignSamplerInStructUniformRegister(
                             samplerType, symbolsToAPINames[sampler], nullptr);
-                        outputUniform(out, samplerType, samplerName, registerIndex);
+                        outputUniform(out, samplerType, *sampler, registerIndex);
                     }
                 }
             }
-            unsigned int registerIndex = assignUniformRegister(type, name.getString(), nullptr);
-            outputUniform(out, type, name, registerIndex);
+            unsigned int registerIndex = assignUniformRegister(type, variable.name(), nullptr);
+            outputUniform(out, type, variable, registerIndex);
         }
     }
 
     if (outputType == SH_HLSL_4_1_OUTPUT)
     {
         unsigned int groupTextureRegisterIndex = 0;
         // TEXTURE_2D is special, index offset is assumed to be 0 and omitted in that case.
         ASSERT(HLSL_TEXTURE_MIN == HLSL_TEXTURE_2D);
         for (int groupId = HLSL_TEXTURE_MIN; groupId < HLSL_TEXTURE_MAX; ++groupId)
         {
             outputHLSLSamplerUniformGroup(
-                out, HLSLTextureSamplerGroup(groupId), groupedSamplerUniforms[groupId],
+                out, HLSLTextureGroup(groupId), groupedSamplerUniforms[groupId],
                 samplerInStructSymbolsToAPINames, &groupTextureRegisterIndex);
         }
+        mSamplerCount = groupTextureRegisterIndex;
+
+        for (const TVariable *image : imageUniformsHLSL41Output)
+        {
+            const TType &type          = image->getType();
+            unsigned int registerIndex = assignUniformRegister(type, image->name(), nullptr);
+            if (type.getMemoryQualifier().readonly)
+            {
+                outputHLSL4_1_FL11Texture(out, type, *image, registerIndex);
+            }
+            else
+            {
+                outputHLSL4_1_FL11RWTexture(out, type, *image, registerIndex);
+            }
+        }
     }
 }
 
 void UniformHLSL::samplerMetadataUniforms(TInfoSinkBase &out, const char *reg)
 {
-    // If mSamplerRegister is 0 the shader doesn't use any textures.
-    if (mSamplerRegister > 0)
+    // If mSamplerCount is 0 the shader doesn't use any textures for samplers.
+    if (mSamplerCount > 0)
     {
         out << "    struct SamplerMetadata\n"
                "    {\n"
                "        int baseLevel;\n"
                "        int internalFormatBits;\n"
                "        int wrapModes;\n"
                "        int padding;\n"
                "    };\n"
                "    SamplerMetadata samplerMetadata["
-            << mSamplerRegister << "] : packoffset(" << reg << ");\n";
+            << mSamplerCount << "] : packoffset(" << reg << ");\n";
     }
 }
 
-TString UniformHLSL::uniformBlocksHeader(const ReferencedSymbols &referencedInterfaceBlocks)
+TString UniformHLSL::uniformBlocksHeader(const ReferencedInterfaceBlocks &referencedInterfaceBlocks)
 {
     TString interfaceBlocks;
 
-    for (ReferencedSymbols::const_iterator interfaceBlockIt = referencedInterfaceBlocks.begin();
-         interfaceBlockIt != referencedInterfaceBlocks.end(); interfaceBlockIt++)
+    for (const auto &blockReference : referencedInterfaceBlocks)
     {
-        const TType &nodeType                 = interfaceBlockIt->second->getType();
-        const TInterfaceBlock &interfaceBlock = *nodeType.getInterfaceBlock();
-
-        // nodeType.isInterfaceBlock() == false means the node is a field of a uniform block which
-        // doesn't have instance name, so this block cannot be an array.
-        unsigned int interfaceBlockArraySize = 0u;
-        if (nodeType.isInterfaceBlock() && nodeType.isArray())
-        {
-            interfaceBlockArraySize = nodeType.getOutermostArraySize();
-        }
-        unsigned int activeRegister = mUniformBlockRegister;
-
-        mUniformBlockRegisterMap[interfaceBlock.name().c_str()] = activeRegister;
-        mUniformBlockRegister += std::max(1u, interfaceBlockArraySize);
-
-        // FIXME: interface block field names
-
-        if (interfaceBlock.hasInstanceName())
+        const TInterfaceBlock &interfaceBlock = *blockReference.second->block;
+        const TVariable *instanceVariable     = blockReference.second->instanceVariable;
+        if (instanceVariable != nullptr)
         {
             interfaceBlocks += uniformBlockStructString(interfaceBlock);
         }
 
-        if (interfaceBlockArraySize > 0)
+        unsigned int activeRegister                             = mUniformBlockRegister;
+        mUniformBlockRegisterMap[interfaceBlock.name().c_str()] = activeRegister;
+
+        if (instanceVariable != nullptr && instanceVariable->getType().isArray())
         {
-            for (unsigned int arrayIndex = 0; arrayIndex < interfaceBlockArraySize; arrayIndex++)
+            unsigned int instanceArraySize = instanceVariable->getType().getOutermostArraySize();
+            for (unsigned int arrayIndex = 0; arrayIndex < instanceArraySize; arrayIndex++)
             {
-                interfaceBlocks +=
-                    uniformBlockString(interfaceBlock, activeRegister + arrayIndex, arrayIndex);
+                interfaceBlocks += uniformBlockString(interfaceBlock, instanceVariable,
+                                                      activeRegister + arrayIndex, arrayIndex);
             }
+            mUniformBlockRegister += instanceArraySize;
         }
         else
         {
-            interfaceBlocks += uniformBlockString(interfaceBlock, activeRegister, GL_INVALID_INDEX);
+            interfaceBlocks += uniformBlockString(interfaceBlock, instanceVariable, activeRegister,
+                                                  GL_INVALID_INDEX);
+            mUniformBlockRegister += 1u;
         }
     }
 
     return (interfaceBlocks.empty() ? "" : ("// Uniform Blocks\n\n" + interfaceBlocks));
 }
 
 TString UniformHLSL::uniformBlockString(const TInterfaceBlock &interfaceBlock,
+                                        const TVariable *instanceVariable,
                                         unsigned int registerIndex,
                                         unsigned int arrayIndex)
 {
     const TString &arrayIndexString =
         (arrayIndex != GL_INVALID_INDEX ? Decorate(str(arrayIndex)) : "");
     const TString &blockName = interfaceBlock.name() + arrayIndexString;
     TString hlsl;
 
     hlsl += "cbuffer " + blockName + " : register(b" + str(registerIndex) +
             ")\n"
             "{\n";
 
-    if (interfaceBlock.hasInstanceName())
+    if (instanceVariable != nullptr)
     {
         hlsl += "    " + InterfaceBlockStructName(interfaceBlock) + " " +
-                uniformBlockInstanceString(interfaceBlock, arrayIndex) + ";\n";
+                UniformBlockInstanceString(instanceVariable->name(), arrayIndex) + ";\n";
     }
     else
     {
         const TLayoutBlockStorage blockStorage = interfaceBlock.blockStorage();
         hlsl += uniformBlockMembersString(interfaceBlock, blockStorage);
     }
 
     hlsl += "};\n\n";
 
     return hlsl;
 }
 
-TString UniformHLSL::uniformBlockInstanceString(const TInterfaceBlock &interfaceBlock,
+TString UniformHLSL::UniformBlockInstanceString(const TString &instanceName,
                                                 unsigned int arrayIndex)
 {
-    if (!interfaceBlock.hasInstanceName())
+    if (arrayIndex != GL_INVALID_INDEX)
     {
-        return "";
-    }
-    else if (arrayIndex != GL_INVALID_INDEX)
-    {
-        return DecoratePrivate(interfaceBlock.instanceName()) + "_" + str(arrayIndex);
+        return DecoratePrivate(instanceName) + "_" + str(arrayIndex);
     }
     else
     {
-        return Decorate(interfaceBlock.instanceName());
+        return Decorate(instanceName);
     }
 }
 
 TString UniformHLSL::uniformBlockMembersString(const TInterfaceBlock &interfaceBlock,
                                                TLayoutBlockStorage blockStorage)
 {
     TString hlsl;
 
--- a/gfx/angle/src/compiler/translator/UniformHLSL.h
+++ b/gfx/angle/src/compiler/translator/UniformHLSL.h
@@ -11,85 +11,99 @@
 #define COMPILER_TRANSLATOR_UNIFORMHLSL_H_
 
 #include "compiler/translator/OutputHLSL.h"
 #include "compiler/translator/UtilsHLSL.h"
 
 namespace sh
 {
 class StructureHLSL;
+class TSymbolTable;
 
 class UniformHLSL : angle::NonCopyable
 {
   public:
-    UniformHLSL(StructureHLSL *structureHLSL,
+    UniformHLSL(sh::GLenum shaderType,
+                StructureHLSL *structureHLSL,
                 ShShaderOutput outputType,
-                const std::vector<Uniform> &uniforms);
+                const std::vector<Uniform> &uniforms,
+                unsigned int firstUniformRegister);
 
     void reserveUniformRegisters(unsigned int registerCount);
     void reserveUniformBlockRegisters(unsigned int registerCount);
     void uniformsHeader(TInfoSinkBase &out,
                         ShShaderOutput outputType,
-                        const ReferencedSymbols &referencedUniforms);
+                        const ReferencedVariables &referencedUniforms,
+                        TSymbolTable *symbolTable);
 
     // Must be called after uniformsHeader
     void samplerMetadataUniforms(TInfoSinkBase &out, const char *reg);
 
-    TString uniformBlocksHeader(const ReferencedSymbols &referencedInterfaceBlocks);
+    TString uniformBlocksHeader(const ReferencedInterfaceBlocks &referencedInterfaceBlocks);
 
     // Used for direct index references
-    static TString uniformBlockInstanceString(const TInterfaceBlock &interfaceBlock,
-                                              unsigned int arrayIndex);
+    static TString UniformBlockInstanceString(const TString &instanceName, unsigned int arrayIndex);
 
     const std::map<std::string, unsigned int> &getUniformBlockRegisterMap() const
     {
         return mUniformBlockRegisterMap;
     }
     const std::map<std::string, unsigned int> &getUniformRegisterMap() const
     {
         return mUniformRegisterMap;
     }
 
   private:
     TString uniformBlockString(const TInterfaceBlock &interfaceBlock,
+                               const TVariable *instanceVariable,
                                unsigned int registerIndex,
                                unsigned int arrayIndex);
     TString uniformBlockMembersString(const TInterfaceBlock &interfaceBlock,
                                       TLayoutBlockStorage blockStorage);
     TString uniformBlockStructString(const TInterfaceBlock &interfaceBlock);
     const Uniform *findUniformByName(const TString &name) const;
 
     void outputHLSL4_0_FL9_3Sampler(TInfoSinkBase &out,
                                     const TType &type,
-                                    const TName &name,
+                                    const TVariable &variable,
                                     const unsigned int registerIndex);
-
+    void outputHLSL4_1_FL11Texture(TInfoSinkBase &out,
+                                   const TType &type,
+                                   const TVariable &variable,
+                                   const unsigned int registerIndex);
+    void outputHLSL4_1_FL11RWTexture(TInfoSinkBase &out,
+                                     const TType &type,
+                                     const TVariable &variable,
+                                     const unsigned int registerIndex);
     void outputUniform(TInfoSinkBase &out,
                        const TType &type,
-                       const TName &name,
+                       const TVariable &variable,
                        const unsigned int registerIndex);
 
     // Returns the uniform's register index
     unsigned int assignUniformRegister(const TType &type,
                                        const TString &name,
                                        unsigned int *outRegisterCount);
     unsigned int assignSamplerInStructUniformRegister(const TType &type,
                                                       const TString &name,
                                                       unsigned int *outRegisterCount);
 
     void outputHLSLSamplerUniformGroup(
         TInfoSinkBase &out,
-        const HLSLTextureSamplerGroup textureGroup,
-        const TVector<const TIntermSymbol *> &group,
-        const TMap<const TIntermSymbol *, TString> &samplerInStructSymbolsToAPINames,
+        const HLSLTextureGroup textureGroup,
+        const TVector<const TVariable *> &group,
+        const TMap<const TVariable *, TString> &samplerInStructSymbolsToAPINames,
         unsigned int *groupTextureRegisterIndex);
 
     unsigned int mUniformRegister;
     unsigned int mUniformBlockRegister;
-    unsigned int mSamplerRegister;
+    unsigned int mTextureRegister;
+    unsigned int mRWTextureRegister;
+    unsigned int mSamplerCount;
+    sh::GLenum mShaderType;
     StructureHLSL *mStructureHLSL;
     ShShaderOutput mOutputType;
 
     const std::vector<Uniform> &mUniforms;
     std::map<std::string, unsigned int> mUniformBlockRegisterMap;
     std::map<std::string, unsigned int> mUniformRegisterMap;
 };
 }
--- a/gfx/angle/src/compiler/translator/UseInterfaceBlockFields.cpp
+++ b/gfx/angle/src/compiler/translator/UseInterfaceBlockFields.cpp
@@ -17,43 +17,41 @@
 #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)
 {
     TString name = TString(var.name.c_str());
-    if (var.isArray())
-    {
-        size_t pos = name.find_last_of('[');
-        if (pos != TString::npos)
-        {
-            name = name.substr(0, pos);
-        }
-    }
+    ASSERT(name.find_last_of('[') == TString::npos);
     TIntermSymbol *symbol = ReferenceGlobalVariable(name, symbolTable);
-    if (var.isArray())
-    {
-        for (unsigned int i = 0u; i < var.arraySize; ++i)
-        {
-            TIntermBinary *element =
-                new TIntermBinary(EOpIndexDirect, symbol->deepCopy(), CreateIndexNode(i));
-            sequence->insert(sequence->begin(), element);
-        }
-    }
-    else
-    {
-        sequence->insert(sequence->begin(), symbol);
-    }
+    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));
--- a/gfx/angle/src/compiler/translator/UtilsHLSL.cpp
+++ b/gfx/angle/src/compiler/translator/UtilsHLSL.cpp
@@ -22,29 +22,30 @@ TString SamplerString(const TBasicType t
         return "SamplerComparisonState";
     }
     else
     {
         return "SamplerState";
     }
 }
 
-TString SamplerString(HLSLTextureSamplerGroup type)
+TString SamplerString(HLSLTextureGroup type)
 {
     if (type >= HLSL_COMPARISON_SAMPLER_GROUP_BEGIN && type <= HLSL_COMPARISON_SAMPLER_GROUP_END)
     {
         return "SamplerComparisonState";
     }
     else
     {
         return "SamplerState";
     }
 }
 
-HLSLTextureSamplerGroup TextureGroup(const TBasicType type)
+HLSLTextureGroup TextureGroup(const TBasicType type, TLayoutImageInternalFormat imageInternalFormat)
+
 {
     switch (type)
     {
         case EbtSampler2D:
             return HLSL_TEXTURE_2D;
         case EbtSamplerCube:
             return HLSL_TEXTURE_CUBE;
         case EbtSamplerExternalOES:
@@ -76,34 +77,180 @@ HLSLTextureSamplerGroup TextureGroup(con
         case EbtUSampler2DMS:
             return HLSL_TEXTURE_2D_MS_UINT4;
         case EbtSampler2DShadow:
             return HLSL_TEXTURE_2D_COMPARISON;
         case EbtSamplerCubeShadow:
             return HLSL_TEXTURE_CUBE_COMPARISON;
         case EbtSampler2DArrayShadow:
             return HLSL_TEXTURE_2D_ARRAY_COMPARISON;
+        case EbtImage2D:
+        {
+            switch (imageInternalFormat)
+            {
+                case EiifRGBA32F:
+                case EiifRGBA16F:
+                case EiifR32F:
+                    return HLSL_TEXTURE_2D;
+                case EiifRGBA8:
+                    return HLSL_TEXTURE_2D_UNORM;
+                case EiifRGBA8_SNORM:
+                    return HLSL_TEXTURE_2D_SNORM;
+                default:
+                    UNREACHABLE();
+            }
+        }
+        case EbtIImage2D:
+        {
+            switch (imageInternalFormat)
+            {
+                case EiifRGBA32I:
+                case EiifRGBA16I:
+                case EiifRGBA8I:
+                case EiifR32I:
+                    return HLSL_TEXTURE_2D_INT4;
+                default:
+                    UNREACHABLE();
+            }
+        }
+        case EbtUImage2D:
+        {
+            switch (imageInternalFormat)
+            {
+
+                case EiifRGBA32UI:
+                case EiifRGBA16UI:
+                case EiifRGBA8UI:
+                case EiifR32UI:
+                    return HLSL_TEXTURE_2D_UINT4;
+                default:
+                    UNREACHABLE();
+            }
+        }
+        case EbtImage3D:
+        {
+            switch (imageInternalFormat)
+            {
+                case EiifRGBA32F:
+                case EiifRGBA16F:
+                case EiifR32F:
+                    return HLSL_TEXTURE_3D;
+                case EiifRGBA8:
+                    return HLSL_TEXTURE_3D_UNORM;
+                case EiifRGBA8_SNORM:
+                    return HLSL_TEXTURE_3D_SNORM;
+                default:
+                    UNREACHABLE();
+            }
+        }
+        case EbtIImage3D:
+        {
+            switch (imageInternalFormat)
+            {
+                case EiifRGBA32I:
+                case EiifRGBA16I:
+                case EiifRGBA8I:
+                case EiifR32I:
+                    return HLSL_TEXTURE_3D_INT4;
+                default:
+                    UNREACHABLE();
+            }
+        }
+        case EbtUImage3D:
+        {
+            switch (imageInternalFormat)
+            {
+                case EiifRGBA32UI:
+                case EiifRGBA16UI:
+                case EiifRGBA8UI:
+                case EiifR32UI:
+                    return HLSL_TEXTURE_3D_UINT4;
+                default:
+                    UNREACHABLE();
+            }
+        }
+        case EbtImage2DArray:
+        case EbtImageCube:
+        {
+            switch (imageInternalFormat)
+            {
+                case EiifRGBA32F:
+                case EiifRGBA16F:
+                case EiifR32F:
+                    return HLSL_TEXTURE_2D_ARRAY;
+                case EiifRGBA8:
+                    return HLSL_TEXTURE_2D_ARRAY_UNORN;
+                case EiifRGBA8_SNORM:
+                    return HLSL_TEXTURE_2D_ARRAY_SNORM;
+                default:
+                    UNREACHABLE();
+            }
+        }
+        case EbtIImage2DArray:
+        case EbtIImageCube:
+        {
+            switch (imageInternalFormat)
+            {
+                case EiifRGBA32I:
+                case EiifRGBA16I:
+                case EiifRGBA8I:
+                case EiifR32I:
+                    return HLSL_TEXTURE_2D_ARRAY_INT4;
+                default:
+                    UNREACHABLE();
+            }
+        }
+        case EbtUImage2DArray:
+        case EbtUImageCube:
+        {
+            switch (imageInternalFormat)
+            {
+                case EiifRGBA32UI:
+                case EiifRGBA16UI:
+                case EiifRGBA8UI:
+                case EiifR32UI:
+                    return HLSL_TEXTURE_2D_ARRAY_UINT4;
+                default:
+                    UNREACHABLE();
+            }
+        }
         default:
             UNREACHABLE();
     }
     return HLSL_TEXTURE_UNKNOWN;
 }
 
-TString TextureString(const HLSLTextureSamplerGroup type)
+TString TextureString(const HLSLTextureGroup textureGroup)
 {
-    switch (type)
+    switch (textureGroup)
     {
         case HLSL_TEXTURE_2D:
-            return "Texture2D";
+            return "Texture2D<float4>";
         case HLSL_TEXTURE_CUBE:
-            return "TextureCube";
+            return "TextureCube<float4>";
         case HLSL_TEXTURE_2D_ARRAY:
-            return "Texture2DArray";
+            return "Texture2DArray<float4>";
         case HLSL_TEXTURE_3D:
-            return "Texture3D";
+            return "Texture3D<float4>";
+        case HLSL_TEXTURE_2D_UNORM:
+            return "Texture2D<unorm float4>";
+        case HLSL_TEXTURE_CUBE_UNORM:
+            return "TextureCube<unorm float4>";
+        case HLSL_TEXTURE_2D_ARRAY_UNORN:
+            return "Texture2DArray<unorm float4>";
+        case HLSL_TEXTURE_3D_UNORM:
+            return "Texture3D<unorm float4>";
+        case HLSL_TEXTURE_2D_SNORM:
+            return "Texture2D<snorm float4>";
+        case HLSL_TEXTURE_CUBE_SNORM:
+            return "TextureCube<snorm float4>";
+        case HLSL_TEXTURE_2D_ARRAY_SNORM:
+            return "Texture2DArray<snorm float4>";
+        case HLSL_TEXTURE_3D_SNORM:
+            return "Texture3D<snorm float4>";
         case HLSL_TEXTURE_2D_MS:
             return "Texture2DMS<float4>";
         case HLSL_TEXTURE_2D_INT4:
             return "Texture2D<int4>";
         case HLSL_TEXTURE_3D_INT4:
             return "Texture3D<int4>";
         case HLSL_TEXTURE_2D_ARRAY_INT4:
             return "Texture2DArray<int4>";
@@ -122,36 +269,52 @@ TString TextureString(const HLSLTextureS
         case HLSL_TEXTURE_CUBE_COMPARISON:
             return "TextureCube";
         case HLSL_TEXTURE_2D_ARRAY_COMPARISON:
             return "Texture2DArray";
         default:
             UNREACHABLE();
     }
 
-    return "<unknown texture type>";
+    return "<unknown read texture type>";
 }
 
-TString TextureString(const TBasicType type)
+TString TextureString(const TBasicType type, TLayoutImageInternalFormat imageInternalFormat)
 {
-    return TextureString(TextureGroup(type));
+    return TextureString(TextureGroup(type, imageInternalFormat));
 }
 
-TString TextureGroupSuffix(const HLSLTextureSamplerGroup type)
+TString TextureGroupSuffix(const HLSLTextureGroup type)
 {
     switch (type)
     {
         case HLSL_TEXTURE_2D:
             return "2D";
         case HLSL_TEXTURE_CUBE:
             return "Cube";
         case HLSL_TEXTURE_2D_ARRAY:
             return "2DArray";
         case HLSL_TEXTURE_3D:
             return "3D";
+        case HLSL_TEXTURE_2D_UNORM:
+            return "2D_unorm_float4_";
+        case HLSL_TEXTURE_CUBE_UNORM:
+            return "Cube_unorm_float4_";
+        case HLSL_TEXTURE_2D_ARRAY_UNORN:
+            return "2DArray_unorm_float4_";
+        case HLSL_TEXTURE_3D_UNORM:
+            return "3D_unorm_float4_";
+        case HLSL_TEXTURE_2D_SNORM:
+            return "2D_snorm_float4_";
+        case HLSL_TEXTURE_CUBE_SNORM:
+            return "Cube_snorm_float4_";
+        case HLSL_TEXTURE_2D_ARRAY_SNORM:
+            return "2DArray_snorm_float4_";
+        case HLSL_TEXTURE_3D_SNORM:
+            return "3D_snorm_float4_";
         case HLSL_TEXTURE_2D_MS:
             return "2DMS";
         case HLSL_TEXTURE_2D_INT4:
             return "2D_int4_";
         case HLSL_TEXTURE_3D_INT4:
             return "3D_int4_";
         case HLSL_TEXTURE_2D_ARRAY_INT4:
             return "2DArray_int4_";
@@ -173,40 +336,368 @@ TString TextureGroupSuffix(const HLSLTex
             return "2DArray_comparison";
         default:
             UNREACHABLE();
     }
 
     return "<unknown texture type>";
 }
 
-TString TextureGroupSuffix(const TBasicType type)
+TString TextureGroupSuffix(const TBasicType type, TLayoutImageInternalFormat imageInternalFormat)
 {
-    return TextureGroupSuffix(TextureGroup(type));
+    return TextureGroupSuffix(TextureGroup(type, imageInternalFormat));
 }
 
-TString TextureTypeSuffix(const TBasicType type)
+TString TextureTypeSuffix(const TBasicType type, TLayoutImageInternalFormat imageInternalFormat)
 {
     switch (type)
     {
         case EbtISamplerCube:
             return "Cube_int4_";
         case EbtUSamplerCube:
             return "Cube_uint4_";
         case EbtSamplerExternalOES:
             return "_External";
+        case EbtImageCube:
+        {
+            switch (imageInternalFormat)
+            {
+                case EiifRGBA32F:
+                case EiifRGBA16F:
+                case EiifR32F:
+                    return "Cube_float4_";
+                case EiifRGBA8:
+                    return "Cube_unorm_float4_";
+                case EiifRGBA8_SNORM:
+                    return "Cube_snorm_float4_";
+                default:
+                    UNREACHABLE();
+            }
+        }
+        case EbtIImageCube:
+        {
+            switch (imageInternalFormat)
+            {
+                case EiifRGBA32I:
+                case EiifRGBA16I:
+                case EiifRGBA8I:
+                case EiifR32I:
+                    return "Cube_int4_";
+                default:
+                    UNREACHABLE();
+            }
+        }
+        case EbtUImageCube:
+        {
+            switch (imageInternalFormat)
+            {
+                case EiifRGBA32UI:
+                case EiifRGBA16UI:
+                case EiifRGBA8UI:
+                case EiifR32UI:
+                    return "Cube_uint4_";
+                default:
+                    UNREACHABLE();
+            }
+        }
         default:
             // All other types are identified by their group suffix
-            return TextureGroupSuffix(type);
+            return TextureGroupSuffix(type, imageInternalFormat);
+    }
+}
+
+HLSLRWTextureGroup RWTextureGroup(const TBasicType type,
+                                  TLayoutImageInternalFormat imageInternalFormat)
+
+{
+    switch (type)
+    {
+        case EbtImage2D:
+        {
+            switch (imageInternalFormat)
+            {
+                case EiifRGBA32F:
+                case EiifRGBA16F:
+                case EiifR32F:
+                    return HLSL_RWTEXTURE_2D_FLOAT4;
+                case EiifRGBA8:
+                    return HLSL_RWTEXTURE_2D_UNORM;
+                case EiifRGBA8_SNORM:
+                    return HLSL_RWTEXTURE_2D_SNORM;
+                default:
+                    UNREACHABLE();
+            }
+        }
+        case EbtIImage2D:
+        {
+            switch (imageInternalFormat)
+            {
+                case EiifRGBA32I:
+                case EiifRGBA16I:
+                case EiifRGBA8I:
+                case EiifR32I:
+                    return HLSL_RWTEXTURE_2D_INT4;
+                default:
+                    UNREACHABLE();
+            }
+        }
+        case EbtUImage2D:
+        {
+            switch (imageInternalFormat)
+            {
+
+                case EiifRGBA32UI:
+                case EiifRGBA16UI:
+                case EiifRGBA8UI:
+                case EiifR32UI:
+                    return HLSL_RWTEXTURE_2D_UINT4;
+                default:
+                    UNREACHABLE();
+            }
+        }
+        case EbtImage3D:
+        {
+            switch (imageInternalFormat)
+            {
+                case EiifRGBA32F:
+                case EiifRGBA16F:
+                case EiifR32F:
+                    return HLSL_RWTEXTURE_3D_FLOAT4;
+                case EiifRGBA8:
+                    return HLSL_RWTEXTURE_3D_UNORM;
+                case EiifRGBA8_SNORM:
+                    return HLSL_RWTEXTURE_3D_SNORM;
+                default:
+                    UNREACHABLE();
+            }
+        }
+        case EbtIImage3D:
+        {
+            switch (imageInternalFormat)
+            {
+                case EiifRGBA32I:
+                case EiifRGBA16I:
+                case EiifRGBA8I:
+                case EiifR32I:
+                    return HLSL_RWTEXTURE_3D_INT4;
+                default:
+                    UNREACHABLE();
+            }
+        }
+        case EbtUImage3D:
+        {
+            switch (imageInternalFormat)
+            {
+                case EiifRGBA32UI:
+                case EiifRGBA16UI:
+                case EiifRGBA8UI:
+                case EiifR32UI:
+                    return HLSL_RWTEXTURE_3D_UINT4;
+                default:
+                    UNREACHABLE();
+            }
+        }
+        case EbtImage2DArray:
+        case EbtImageCube:
+        {
+            switch (imageInternalFormat)
+            {
+                case EiifRGBA32F:
+                case EiifRGBA16F:
+                case EiifR32F:
+                    return HLSL_RWTEXTURE_2D_ARRAY_FLOAT4;
+                case EiifRGBA8:
+                    return HLSL_RWTEXTURE_2D_ARRAY_UNORN;
+                case EiifRGBA8_SNORM:
+                    return HLSL_RWTEXTURE_2D_ARRAY_SNORM;
+                default:
+                    UNREACHABLE();
+            }
+        }
+        case EbtIImage2DArray:
+        case EbtIImageCube:
+        {
+            switch (imageInternalFormat)
+            {
+                case EiifRGBA32I:
+                case EiifRGBA16I:
+                case EiifRGBA8I:
+                case EiifR32I:
+                    return HLSL_RWTEXTURE_2D_ARRAY_INT4;
+                default:
+                    UNREACHABLE();
+            }
+        }
+        case EbtUImage2DArray:
+        case EbtUImageCube:
+        {
+            switch (imageInternalFormat)
+            {
+                case EiifRGBA32UI:
+                case EiifRGBA16UI:
+                case EiifRGBA8UI:
+                case EiifR32UI:
+                    return HLSL_RWTEXTURE_2D_ARRAY_UINT4;
+                default:
+                    UNREACHABLE();
+            }
+        }
+        default:
+            UNREACHABLE();
+    }
+    return HLSL_RWTEXTURE_UNKNOWN;
+}
+
+TString RWTextureString(const HLSLRWTextureGroup RWTextureGroup)
+{
+    switch (RWTextureGroup)
+    {
+        case HLSL_RWTEXTURE_2D_FLOAT4:
+            return "RWTexture2D<float4>";
+        case HLSL_RWTEXTURE_2D_ARRAY_FLOAT4:
+            return "RWTexture2DArray<float4>";
+        case HLSL_RWTEXTURE_3D_FLOAT4:
+            return "RWTexture3D<float4>";
+        case HLSL_RWTEXTURE_2D_UNORM:
+            return "RWTexture2D<unorm float4>";
+        case HLSL_RWTEXTURE_2D_ARRAY_UNORN:
+            return "RWTexture2DArray<unorm float4>";
+        case HLSL_RWTEXTURE_3D_UNORM:
+            return "RWTexture3D<unorm float4>";
+        case HLSL_RWTEXTURE_2D_SNORM:
+            return "RWTexture2D<snorm float4>";
+        case HLSL_RWTEXTURE_2D_ARRAY_SNORM:
+            return "RWTexture2DArray<snorm float4>";
+        case HLSL_RWTEXTURE_3D_SNORM:
+            return "RWTexture3D<snorm float4>";
+        case HLSL_RWTEXTURE_2D_UINT4:
+            return "RWTexture2D<uint4>";
+        case HLSL_RWTEXTURE_2D_ARRAY_UINT4:
+            return "RWTexture2DArray<uint4>";
+        case HLSL_RWTEXTURE_3D_UINT4:
+            return "RWTexture3D<uint4>";
+        case HLSL_RWTEXTURE_2D_INT4:
+            return "RWTexture2D<int4>";
+        case HLSL_RWTEXTURE_2D_ARRAY_INT4:
+            return "RWTexture2DArray<int4>";
+        case HLSL_RWTEXTURE_3D_INT4:
+            return "RWTexture3D<int4>";
+        default:
+            UNREACHABLE();
+    }
+
+    return "<unknown read and write texture type>";
+}
+
+TString RWTextureString(const TBasicType type, TLayoutImageInternalFormat imageInternalFormat)
+{
+    return RWTextureString(RWTextureGroup(type, imageInternalFormat));
+}
+
+TString RWTextureGroupSuffix(const HLSLRWTextureGroup type)
+{
+    switch (type)
+    {
+        case HLSL_RWTEXTURE_2D_FLOAT4:
+            return "RW2D_float4_";
+        case HLSL_RWTEXTURE_2D_ARRAY_FLOAT4:
+            return "RW2DArray_float4_";
+        case HLSL_RWTEXTURE_3D_FLOAT4:
+            return "RW3D_float4_";
+        case HLSL_RWTEXTURE_2D_UNORM:
+            return "RW2D_unorm_float4_";
+        case HLSL_RWTEXTURE_2D_ARRAY_UNORN:
+            return "RW2DArray_unorm_float4_";
+        case HLSL_RWTEXTURE_3D_UNORM:
+            return "RW3D_unorm_float4_";
+        case HLSL_RWTEXTURE_2D_SNORM:
+            return "RW2D_snorm_float4_";
+        case HLSL_RWTEXTURE_2D_ARRAY_SNORM:
+            return "RW2DArray_snorm_float4_";
+        case HLSL_RWTEXTURE_3D_SNORM:
+            return "RW3D_snorm_float4_";
+        case HLSL_RWTEXTURE_2D_UINT4:
+            return "RW2D_uint4_";
+        case HLSL_RWTEXTURE_2D_ARRAY_UINT4:
+            return "RW2DArray_uint4_";
+        case HLSL_RWTEXTURE_3D_UINT4:
+            return "RW3D_uint4_";
+        case HLSL_RWTEXTURE_2D_INT4:
+            return "RW2D_int4_";
+        case HLSL_RWTEXTURE_2D_ARRAY_INT4:
+            return "RW2DArray_int4_";
+        case HLSL_RWTEXTURE_3D_INT4:
+            return "RW3D_int4_";
+        default:
+            UNREACHABLE();
+    }
+
+    return "<unknown read and write resource>";
+}
+
+TString RWTextureGroupSuffix(const TBasicType type, TLayoutImageInternalFormat imageInternalFormat)
+{
+    return RWTextureGroupSuffix(RWTextureGroup(type, imageInternalFormat));
+}
+
+TString RWTextureTypeSuffix(const TBasicType type, TLayoutImageInternalFormat imageInternalFormat)
+{
+    switch (type)
+    {
+        case EbtImageCube:
+        {
+            switch (imageInternalFormat)
+            {
+                case EiifRGBA32F:
+                case EiifRGBA16F:
+                case EiifR32F:
+                    return "RWCube_float4_";
+                case EiifRGBA8:
+                    return "RWCube_unorm_float4_";
+                case EiifRGBA8_SNORM:
+                    return "RWCube_unorm_float4_";
+                default:
+                    UNREACHABLE();
+            }
+        }
+        case EbtIImageCube:
+        {
+            switch (imageInternalFormat)
+            {
+                case EiifRGBA32I:
+                case EiifRGBA16I:
+                case EiifRGBA8I:
+                case EiifR32I:
+                    return "RWCube_int4_";
+                default:
+                    UNREACHABLE();
+            }
+        }
+        case EbtUImageCube:
+        {
+            switch (imageInternalFormat)
+            {
+                case EiifRGBA32UI:
+                case EiifRGBA16UI:
+                case EiifRGBA8UI:
+                case EiifR32UI:
+                    return "RWCube_uint4_";
+                default:
+                    UNREACHABLE();
+            }
+        }
+        default:
+            // All other types are identified by their group suffix
+            return TextureGroupSuffix(type, imageInternalFormat);
     }
 }
 
 TString DecorateField(const TString &string, const TStructure &structure)
 {
-    if (structure.name().compare(0, 3, "gl_") != 0)
+    if (structure.symbolType() != SymbolType::BuiltIn)
     {
         return Decorate(string);
     }
 
     return string;
 }
 
 TString DecoratePrivate(const TString &privateText)
@@ -219,54 +710,54 @@ TString Decorate(const TString &string)
     if (string.compare(0, 3, "gl_") != 0)
     {
         return "_" + string;
     }
 
     return string;
 }
 
-TString DecorateVariableIfNeeded(const TName &name)
+TString DecorateVariableIfNeeded(const TVariable &variable)
 {
-    if (name.isInternal())
+    if (variable.symbolType() == SymbolType::AngleInternal)
     {
+        const TString &name = variable.name();
         // The name should not have a prefix reserved for user-defined variables or functions.
-        ASSERT(name.getString().compare(0, 2, "f_") != 0);
-        ASSERT(name.getString().compare(0, 1, "_") != 0);
-        return name.getString();
+        ASSERT(name.compare(0, 2, "f_") != 0);
+        ASSERT(name.compare(0, 1, "_") != 0);
+        return name;
     }
     else
     {
-        return Decorate(name.getString());
+        return Decorate(variable.name());
     }
 }
 
-TString DecorateFunctionIfNeeded(const TName &name)
+TString DecorateFunctionIfNeeded(const TFunction *func)
 {
-    if (name.isInternal())
+    if (func->symbolType() == SymbolType::AngleInternal)
     {
         // The name should not have a prefix reserved for user-defined variables or functions.
-        ASSERT(name.getString().compare(0, 2, "f_") != 0);
-        ASSERT(name.getString().compare(0, 1, "_") != 0);
-        return name.getString();
+        ASSERT(func->name().compare(0, 2, "f_") != 0);
+        ASSERT(func->name().compare(0, 1, "_") != 0);
+        return func->name();
     }
-    ASSERT(name.getString().compare(0, 3, "gl_") != 0);
+    ASSERT(func->name().compare(0, 3, "gl_") != 0);
     // Add an additional f prefix to functions so that they're always disambiguated from variables.
     // This is necessary in the corner case where a variable declaration hides a function that it
     // uses in its initializer.
-    return "f_" + name.getString();
+    return "f_" + func->name();
 }
 
 TString TypeString(const TType &type)
 {
     const TStructure *structure = type.getStruct();
     if (structure)
     {
-        const TString &typeName = structure->name();
-        if (typeName != "")
+        if (structure->symbolType() != SymbolType::Empty)
         {
             return StructNameString(*structure);
         }
         else  // Nameless structure, define in place
         {
             return StructureHLSL::defineNameless(*structure);
         }
     }
@@ -351,36 +842,36 @@ TString TypeString(const TType &type)
     }
 
     UNREACHABLE();
     return "<unknown type>";
 }
 
 TString StructNameString(const TStructure &structure)
 {
-    if (structure.name().empty())
+    if (structure.symbolType() == SymbolType::Empty)
     {
         return "";
     }
 
     // For structures at global scope we use a consistent
     // translation so that we can link between shader stages.
     if (structure.atGlobalScope())
     {
         return Decorate(structure.name());
     }
 
-    return "ss" + str(structure.uniqueId()) + "_" + structure.name();
+    return "ss" + str(structure.uniqueId().get()) + "_" + structure.name();
 }
 
 TString QualifiedStructNameString(const TStructure &structure,
                                   bool useHLSLRowMajorPacking,
                                   bool useStd140Packing)
 {
-    if (structure.name() == "")
+    if (structure.symbolType() == SymbolType::Empty)
     {
         return "";
     }
 
     TString prefix = "";
 
     // Structs packed with row-major matrices in HLSL are prefixed with "rm"
     // GLSL column-major maps to HLSL row-major, and the converse is true
@@ -464,16 +955,16 @@ TString DisambiguateFunctionName(const T
             // 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()->name() != "");
+            ASSERT(paramType.getStruct()->symbolType() != SymbolType::Empty);
             disambiguatingString += "_" + TypeString(paramType);
         }
     }
     return disambiguatingString;
 }
 
 }  // namespace sh
--- a/gfx/angle/src/compiler/translator/UtilsHLSL.h
+++ b/gfx/angle/src/compiler/translator/UtilsHLSL.h
@@ -11,31 +11,37 @@
 #define COMPILER_TRANSLATOR_UTILSHLSL_H_
 
 #include <vector>
 #include "compiler/translator/IntermNode.h"
 #include "compiler/translator/Types.h"
 
 #include "angle_gl.h"
 
-class TName;
-
 namespace sh
 {
 
-// Unique combinations of HLSL Texture type and HLSL Sampler type.
-enum HLSLTextureSamplerGroup
+// HLSL Texture type for GLSL sampler type and readonly image type.
+enum HLSLTextureGroup
 {
-    // Regular samplers
+    // read resources
     HLSL_TEXTURE_2D,
     HLSL_TEXTURE_MIN = HLSL_TEXTURE_2D,
 
     HLSL_TEXTURE_CUBE,
     HLSL_TEXTURE_2D_ARRAY,
     HLSL_TEXTURE_3D,
+    HLSL_TEXTURE_2D_UNORM,
+    HLSL_TEXTURE_CUBE_UNORM,
+    HLSL_TEXTURE_2D_ARRAY_UNORN,
+    HLSL_TEXTURE_3D_UNORM,
+    HLSL_TEXTURE_2D_SNORM,
+    HLSL_TEXTURE_CUBE_SNORM,
+    HLSL_TEXTURE_2D_ARRAY_SNORM,
+    HLSL_TEXTURE_3D_SNORM,
     HLSL_TEXTURE_2D_MS,
     HLSL_TEXTURE_2D_INT4,
     HLSL_TEXTURE_3D_INT4,
     HLSL_TEXTURE_2D_ARRAY_INT4,
     HLSL_TEXTURE_2D_MS_INT4,
     HLSL_TEXTURE_2D_UINT4,
     HLSL_TEXTURE_3D_UINT4,
     HLSL_TEXTURE_2D_ARRAY_UINT4,
@@ -49,28 +55,66 @@ enum HLSLTextureSamplerGroup
 
     HLSL_COMPARISON_SAMPLER_GROUP_BEGIN = HLSL_TEXTURE_2D_COMPARISON,
     HLSL_COMPARISON_SAMPLER_GROUP_END   = HLSL_TEXTURE_2D_ARRAY_COMPARISON,
 
     HLSL_TEXTURE_UNKNOWN,
     HLSL_TEXTURE_MAX = HLSL_TEXTURE_UNKNOWN
 };
 
-HLSLTextureSamplerGroup TextureGroup(const TBasicType type);
-TString TextureString(const HLSLTextureSamplerGroup type);
-TString TextureString(const TBasicType type);
-TString TextureGroupSuffix(const HLSLTextureSamplerGroup type);
-TString TextureGroupSuffix(const TBasicType type);
-TString TextureTypeSuffix(const TBasicType type);
+// HLSL RWTexture type for GLSL read and write image type.
+enum HLSLRWTextureGroup
+{
+    // read/write resource
+    HLSL_RWTEXTURE_2D_FLOAT4,
+    HLSL_RWTEXTURE_MIN = HLSL_RWTEXTURE_2D_FLOAT4,
+    HLSL_RWTEXTURE_2D_ARRAY_FLOAT4,
+    HLSL_RWTEXTURE_3D_FLOAT4,
+    HLSL_RWTEXTURE_2D_UNORM,
+    HLSL_RWTEXTURE_2D_ARRAY_UNORN,
+    HLSL_RWTEXTURE_3D_UNORM,
+    HLSL_RWTEXTURE_2D_SNORM,
+    HLSL_RWTEXTURE_2D_ARRAY_SNORM,
+    HLSL_RWTEXTURE_3D_SNORM,
+    HLSL_RWTEXTURE_2D_UINT4,
+    HLSL_RWTEXTURE_2D_ARRAY_UINT4,
+    HLSL_RWTEXTURE_3D_UINT4,
+    HLSL_RWTEXTURE_2D_INT4,
+    HLSL_RWTEXTURE_2D_ARRAY_INT4,
+    HLSL_RWTEXTURE_3D_INT4,
+
+    HLSL_RWTEXTURE_UNKNOWN,
+    HLSL_RWTEXTURE_MAX = HLSL_RWTEXTURE_UNKNOWN
+};
+
+HLSLTextureGroup TextureGroup(const TBasicType type,
+                              TLayoutImageInternalFormat imageInternalFormat = EiifUnspecified);
+TString TextureString(const HLSLTextureGroup textureGroup);
+TString TextureString(const TBasicType type,
+                      TLayoutImageInternalFormat imageInternalFormat = EiifUnspecified);
+TString TextureGroupSuffix(const HLSLTextureGroup type);
+TString TextureGroupSuffix(const TBasicType type,
+                           TLayoutImageInternalFormat imageInternalFormat = EiifUnspecified);
+TString TextureTypeSuffix(const TBasicType type,
+                          TLayoutImageInternalFormat imageInternalFormat = EiifUnspecified);
+HLSLRWTextureGroup RWTextureGroup(const TBasicType type,
+                                  TLayoutImageInternalFormat imageInternalFormat);
+TString RWTextureString(const HLSLRWTextureGroup textureGroup);
+TString RWTextureString(const TBasicType type, TLayoutImageInternalFormat imageInternalFormat);
+TString RWTextureGroupSuffix(const HLSLRWTextureGroup type);
+TString RWTextureGroupSuffix(const TBasicType type, TLayoutImageInternalFormat imageInternalFormat);
+TString RWTextureTypeSuffix(const TBasicType type, TLayoutImageInternalFormat imageInternalFormat);
+
 TString SamplerString(const TBasicType type);
-TString SamplerString(HLSLTextureSamplerGroup type);
+TString SamplerString(HLSLTextureGroup type);
+
 // Adds a prefix to user-defined names to avoid naming clashes.
 TString Decorate(const TString &string);
-TString DecorateVariableIfNeeded(const TName &name);
-TString DecorateFunctionIfNeeded(const TName &name);
+TString DecorateVariableIfNeeded(const TVariable &variable);
+TString DecorateFunctionIfNeeded(const TFunction *func);
 TString DecorateField(const TString &string, const TStructure &structure);
 TString DecoratePrivate(const TString &privateText);
 TString TypeString(const TType &type);
 TString StructNameString(const TStructure &structure);
 TString QualifiedStructNameString(const TStructure &structure,
                                   bool useHLSLRowMajorPacking,
                                   bool useStd140Packing);
 TString InterpolationString(TQualifier qualifier);
--- a/gfx/angle/src/compiler/translator/ValidateGlobalInitializer.cpp
+++ b/gfx/angle/src/compiler/translator/ValidateGlobalInitializer.cpp
@@ -2,74 +2,91 @@
 // 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/ParseContext.h"
 
 namespace sh
 {
 
 namespace
 {
 
 class ValidateGlobalInitializerTraverser : public TIntermTraverser
 {
   public:
-    ValidateGlobalInitializerTraverser(const TParseContext *context);
+    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 issueWarning() const { return mIssueWarning; }
 
   private:
-    const TParseContext *mContext;
+    int mShaderVersion;
     bool mIsValid;
     bool mIssueWarning;
 };
 
 void ValidateGlobalInitializerTraverser::visitSymbol(TIntermSymbol *node)
 {
-    const TSymbol *sym =
-        mContext->symbolTable.find(node->getSymbol(), mContext->getShaderVersion());
-    if (sym->isVariable())
+    // ESSL 1.00 section 4.3 (or ESSL 3.00 section 4.3):
+    // Global initializers must be constant expressions.
+    switch (node->getType().getQualifier())
     {
-        // ESSL 1.00 section 4.3 (or ESSL 3.00 section 4.3):
-        // Global initializers must be constant expressions.
-        const TVariable *var = static_cast<const TVariable *>(sym);
-        switch (var->getType().getQualifier())
-        {
-            case EvqConst:
-                break;
-            case EvqGlobal:
-            case EvqTemporary:
-            case EvqUniform:
-                // We allow these cases to be compatible with legacy ESSL 1.00 content.
-                // Implement stricter rules for ESSL 3.00 since there's no legacy content to deal
-                // with.
-                if (mContext->getShaderVersion() >= 300)
-                {
-                    mIsValid = false;
-                }
-                else
-                {
-                    mIssueWarning = true;
-                }
-                break;
-            default:
+        case EvqConst:
+            break;
+        case EvqGlobal:
+        case EvqTemporary:
+        case EvqUniform:
+            // We allow these cases to be compatible with legacy ESSL 1.00 content.
+            // Implement stricter rules for ESSL 3.00 since there's no legacy content to deal
+            // with.
+            if (mShaderVersion >= 300)
+            {
                 mIsValid = false;
-        }
+            }
+            else
+            {
+                mIssueWarning = true;
+            }
+            break;
+        default:
+            mIsValid = false;
+    }
+}
+
+void ValidateGlobalInitializerTraverser::visitConstantUnion(TIntermConstantUnion *node)
+{
+    // Constant unions that are not constant expressions may result from folding a ternary
+    // expression.
+    switch (node->getType().getQualifier())
+    {
+        case EvqConst:
+            break;
+        case EvqTemporary:
+            if (mShaderVersion >= 300)
+            {
+                mIsValid = false;
+            }
+            else
+            {
+                mIssueWarning = true;
+            }
+            break;
+        default:
+            UNREACHABLE();
     }
 }
 
 bool ValidateGlobalInitializerTraverser::visitAggregate(Visit visit, TIntermAggregate *node)
 {
     // Disallow calls to user-defined functions and texture lookup functions in global variable
     // initializers.
     // This is done simply by disabling all function calls - built-in math functions don't use
@@ -94,27 +111,28 @@ bool ValidateGlobalInitializerTraverser:
 {
     if (node->isAssignment())
     {
         mIsValid = false;
     }
     return true;
 }
 
-ValidateGlobalInitializerTraverser::ValidateGlobalInitializerTraverser(const TParseContext *context)
-    : TIntermTraverser(true, false, false), mContext(context), mIsValid(true), mIssueWarning(false)
+ValidateGlobalInitializerTraverser::ValidateGlobalInitializerTraverser(int shaderVersion)
+    : TIntermTraverser(true, false, false),
+      mShaderVersion(shaderVersion),
+      mIsValid(true),
+      mIssueWarning(false)
 {
 }
 
 }  // namespace
 
-bool ValidateGlobalInitializer(TIntermTyped *initializer,
-                               const TParseContext *context,
-                               bool *warning)
+bool ValidateGlobalInitializer(TIntermTyped *initializer, int shaderVersion, bool *warning)
 {
-    ValidateGlobalInitializerTraverser validate(context);
+    ValidateGlobalInitializerTraverser validate(shaderVersion);
     initializer->traverse(&validate);
     ASSERT(warning != nullptr);
     *warning = validate.issueWarning();
     return validate.isValid();
 }
 
 }  // namespace sh
--- a/gfx/angle/src/compiler/translator/ValidateGlobalInitializer.h
+++ b/gfx/angle/src/compiler/translator/ValidateGlobalInitializer.h
@@ -6,18 +6,15 @@
 
 #ifndef COMPILER_TRANSLATOR_VALIDATEGLOBALINITIALIZER_H_
 #define COMPILER_TRANSLATOR_VALIDATEGLOBALINITIALIZER_H_
 
 namespace sh
 {
 
 class TIntermTyped;
-class TParseContext;
 
 // Returns true if the initializer is valid.
-bool ValidateGlobalInitializer(TIntermTyped *initializer,
-                               const TParseContext *context,
-                               bool *warning);
+bool ValidateGlobalInitializer(TIntermTyped *initializer, int shaderVersion, bool *warning);
 
 }  // namespace sh
 
 #endif  // COMPILER_TRANSLATOR_VALIDATEGLOBALINITIALIZER_H_
--- a/gfx/angle/src/compiler/translator/ValidateLimitations.cpp
+++ b/gfx/angle/src/compiler/translator/ValidateLimitations.cpp
@@ -20,17 +20,17 @@ namespace
 int GetLoopSymbolId(TIntermLoop *loop)
 {
     // Here we assume all the operations are valid, because the loop node is
     // already validated before this call.
     TIntermSequence *declSeq = loop->getInit()->getAsDeclarationNode()->getSequence();
     TIntermBinary *declInit  = (*declSeq)[0]->getAsBinaryNode();
     TIntermSymbol *symbol    = declInit->getLeft()->getAsSymbolNode();
 
-    return symbol->getId();
+    return symbol->uniqueId().get();
 }
 
 // Traverses a node to check if it represents a constant index expression.
 // Definition:
 // constant-index-expressions are a superset of constant-expressions.
 // Constant-index-expressions can include loop indices as defined in
 // GLSL ES 1.0 spec, Appendix A, section 4.
 // The following are constant-index-expressions:
@@ -50,17 +50,17 @@ class ValidateConstIndexExpr : public TI
 
     void visitSymbol(TIntermSymbol *symbol) override
     {
         // Only constants and loop indices are allowed in a
         // constant index expression.
         if (mValid)
         {
             bool isLoopSymbol = std::find(mLoopSymbolIds.begin(), mLoopSymbolIds.end(),
-                                          symbol->getId()) != mLoopSymbolIds.end();
+                                          symbol->uniqueId().get()) != mLoopSymbolIds.end();
             mValid = (symbol->getQualifier() == EvqConst) || isLoopSymbol;
         }
     }
 
   private:
     bool mValid;
     const std::vector<int> mLoopSymbolIds;
 };
@@ -77,17 +77,16 @@ class ValidateLimitationsTraverser : pub
 
     void visitSymbol(TIntermSymbol *node) override;
     bool visitBinary(Visit, TIntermBinary *) override;
     bool visitLoop(Visit, TIntermLoop *) override;
 
   private:
     void error(TSourceLoc loc, const char *reason, const char *token);
 
-    bool withinLoopBody() const;
     bool isLoopIndex(TIntermSymbol *symbol);
     bool validateLoopType(TIntermLoop *node);
 
     bool validateForLoopHeader(TIntermLoop *node);
     // If valid, return the index symbol id; Otherwise, return -1.
     int validateForLoopInit(TIntermLoop *node);
     bool validateForLoopCond(TIntermLoop *node, int indexSymbolId);
     bool validateForLoopExpr(TIntermLoop *node, int indexSymbolId);
@@ -115,17 +114,17 @@ ValidateLimitationsTraverser::ValidateLi
 }
 
 void ValidateLimitationsTraverser::visitSymbol(TIntermSymbol *node)
 {
     if (isLoopIndex(node) && isLValueRequiredHere())
     {
         error(node->getLine(),
               "Loop index cannot be statically assigned to within the body of the loop",
-              node->getSymbol().c_str());
+              node->getName().c_str());
     }
 }
 
 bool ValidateLimitationsTraverser::visitBinary(Visit, TIntermBinary *node)
 {
     // Check indexing.
     switch (node->getOp())
     {
@@ -159,24 +158,19 @@ bool ValidateLimitationsTraverser::visit
     return false;
 }
 
 void ValidateLimitationsTraverser::error(TSourceLoc loc, const char *reason, const char *token)
 {
     mDiagnostics->error(loc, reason, token);
 }
 
-bool ValidateLimitationsTraverser::withinLoopBody() const
-{
-    return !mLoopSymbolIds.empty();
-}
-
 bool ValidateLimitationsTraverser::isLoopIndex(TIntermSymbol *symbol)
 {
-    return std::find(mLoopSymbolIds.begin(), mLoopSymbolIds.end(), symbol->getId()) !=
+    return std::find(mLoopSymbolIds.begin(), mLoopSymbolIds.end(), symbol->uniqueId().get()) !=
            mLoopSymbolIds.end();
 }
 
 bool ValidateLimitationsTraverser::validateLoopType(TIntermLoop *node)
 {
     TLoopType type = node->getType();
     if (type == ELoopFor)
         return true;
@@ -249,21 +243,21 @@ int ValidateLimitationsTraverser::valida
     {
         error(symbol->getLine(), "Invalid type for loop index", getBasicString(type));
         return -1;
     }
     // The loop index is initialized with constant expression.
     if (!isConstExpr(declInit->getRight()))
     {
         error(declInit->getLine(), "Loop index cannot be initialized with non-constant expression",
-              symbol->getSymbol().c_str());
+              symbol->getName().c_str());
         return -1;
     }
 
-    return symbol->getId();
+    return symbol->uniqueId().get();
 }
 
 bool ValidateLimitationsTraverser::validateForLoopCond(TIntermLoop *node, int indexSymbolId)
 {
     TIntermNode *cond = node->getCondition();
     if (cond == nullptr)
     {
         error(node->getLine(), "Missing condition", "for");
@@ -281,19 +275,19 @@ bool ValidateLimitationsTraverser::valid
     }
     // Loop index should be to the left of relational operator.
     TIntermSymbol *symbol = binOp->getLeft()->getAsSymbolNode();
     if (symbol == nullptr)
     {
         error(binOp->getLine(), "Invalid condition", "for");
         return false;
     }
-    if (symbol->getId() != indexSymbolId)
+    if (symbol->uniqueId().get() != indexSymbolId)
     {
-        error(symbol->getLine(), "Expected loop index", symbol->getSymbol().c_str());
+        error(symbol->getLine(), "Expected loop index", symbol->getName().c_str());
         return false;
     }
     // Relational operator is one of: > >= < <= == or !=.
     switch (binOp->getOp())
     {
         case EOpEqual:
         case EOpNotEqual:
         case EOpLessThan:
@@ -305,17 +299,17 @@ bool ValidateLimitationsTraverser::valid
             error(binOp->getLine(), "Invalid relational operator",
                   GetOperatorString(binOp->getOp()));
             break;
     }
     // Loop index must be compared with a constant.
     if (!isConstExpr(binOp->getRight()))
     {
         error(binOp->getLine(), "Loop index cannot be compared with non-constant expression",
-              symbol->getSymbol().c_str());
+              symbol->getName().c_str());
         return false;
     }
 
     return true;
 }
 
 bool ValidateLimitationsTraverser::validateForLoopExpr(TIntermLoop *node, int indexSymbolId)
 {
@@ -352,19 +346,19 @@ bool ValidateLimitationsTraverser::valid
     }
 
     // The operand must be loop index.
     if (symbol == nullptr)
     {
         error(expr->getLine(), "Invalid expression", "for");
         return false;
     }
-    if (symbol->getId() != indexSymbolId)
+    if (symbol->uniqueId().get() != indexSymbolId)
     {
-        error(symbol->getLine(), "Expected loop index", symbol->getSymbol().c_str());
+        error(symbol->getLine(), "Expected loop index", symbol->getName().c_str());
         return false;
     }
 
     // The operator is one of: ++ -- += -=.
     switch (op)
     {
         case EOpPostIncrement:
         case EOpPostDecrement:
@@ -382,17 +376,17 @@ bool ValidateLimitationsTraverser::valid
     }
 
     // Loop index must be incremented/decremented with a constant.
     if (binOp != nullptr)
     {
         if (!isConstExpr(binOp->getRight()))
         {
             error(binOp->getLine(), "Loop index cannot be modified by non-constant expression",
-                  symbol->getSymbol().c_str());
+                  symbol->getName().c_str());
             return false;
         }
     }
 
     return true;
 }
 
 bool ValidateLimitationsTraverser::isConstExpr(TIntermNode *node)
--- a/gfx/angle/src/compiler/translator/ValidateOutputs.cpp
+++ b/gfx/angle/src/compiler/translator/ValidateOutputs.cpp
@@ -15,19 +15,20 @@
 #include "compiler/translator/IntermTraverse.h"
 #include "compiler/translator/ParseContext.h"
 
 namespace sh
 {
 
 namespace
 {
+
 void error(const TIntermSymbol &symbol, const char *reason, TDiagnostics *diagnostics)
 {
-    diagnostics->error(symbol.getLine(), reason, symbol.getSymbol().c_str());
+    diagnostics->error(symbol.getLine(), reason, symbol.getName().c_str());
 }
 
 class ValidateOutputsTraverser : public TIntermTraverser
 {
   public:
     ValidateOutputsTraverser(const TExtensionBehavior &extBehavior, int maxDrawBuffers);
 
     void validate(TDiagnostics *diagnostics) const;
@@ -38,39 +39,40 @@ class ValidateOutputsTraverser : public 
     int mMaxDrawBuffers;
     bool mAllowUnspecifiedOutputLocationResolution;
     bool mUsesFragDepth;
 
     typedef std::vector<TIntermSymbol *> OutputVector;
     OutputVector mOutputs;
     OutputVector mUnspecifiedLocationOutputs;
     OutputVector mYuvOutputs;
-    std::set<std::string> mVisitedSymbols;
+    std::set<int> mVisitedSymbols;  // Visited symbol ids.
 };
 
 ValidateOutputsTraverser::ValidateOutputsTraverser(const TExtensionBehavior &extBehavior,
                                                    int maxDrawBuffers)
     : TIntermTraverser(true, false, false),
       mMaxDrawBuffers(maxDrawBuffers),
       mAllowUnspecifiedOutputLocationResolution(
           IsExtensionEnabled(extBehavior, TExtension::EXT_blend_func_extended)),
       mUsesFragDepth(false)
 {
 }
 
 void ValidateOutputsTraverser::visitSymbol(TIntermSymbol *symbol)
 {
-    TString name         = symbol->getSymbol();
-    TQualifier qualifier = symbol->getQualifier();
-
-    if (mVisitedSymbols.count(name.c_str()) == 1)
+    if (symbol->variable().symbolType() == SymbolType::Empty)
         return;
 
-    mVisitedSymbols.insert(name.c_str());
+    if (mVisitedSymbols.count(symbol->uniqueId().get()) == 1)
+        return;
 
+    mVisitedSymbols.insert(symbol->uniqueId().get());
+
+    TQualifier qualifier = symbol->getQualifier();
     if (qualifier == EvqFragmentOut)
     {
         if (symbol->getType().getLayoutQualifier().location != -1)
         {
             mOutputs.push_back(symbol);
         }
         else if (symbol->getType().getLayoutQualifier().yuv == true)
         {
@@ -106,17 +108,17 @@ void ValidateOutputsTraverser::validate(
         {
             for (size_t elementIndex = 0; elementIndex < elementCount; elementIndex++)
             {
                 const size_t offsetLocation = location + elementIndex;
                 if (validOutputs[offsetLocation])
                 {
                     std::stringstream strstr;
                     strstr << "conflicting output locations with previously defined output '"
-                           << validOutputs[offsetLocation]->getSymbol() << "'";
+                           << validOutputs[offsetLocation]->getName() << "'";
                     error(*symbol, strstr.str().c_str(), diagnostics);
                 }
                 else
                 {
                     validOutputs[offsetLocation] = symbol;
                 }
             }
         }
--- a/gfx/angle/src/compiler/translator/ValidateSwitch.cpp
+++ b/gfx/angle/src/compiler/translator/ValidateSwitch.cpp
@@ -14,65 +14,72 @@ namespace sh
 
 namespace
 {
 
 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 visitBinary(Visit, TIntermBinary *) override;
     bool visitUnary(Visit, TIntermUnary *) override;
     bool visitTernary(Visit, TIntermTernary *) override;
+    bool visitSwizzle(Visit, TIntermSwizzle *) override;
     bool visitIfElse(Visit visit, TIntermIfElse *) override;
     bool visitSwitch(Visit, TIntermSwitch *) override;
     bool visitCase(Visit, TIntermCase *node) override;
     bool visitAggregate(Visit, TIntermAggregate *) override;
     bool visitLoop(Visit visit, TIntermLoop *) override;
     bool visitBranch(Visit, TIntermBranch *) override;
 
   private:
-    ValidateSwitch(TBasicType switchType, TDiagnostics *context);
+    ValidateSwitch(TBasicType switchType, int shaderVersion, 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, diagnostics);
+    ValidateSwitch validate(switchType, shaderVersion, diagnostics);
     ASSERT(statementList);
     statementList->traverse(&validate);
     return validate.validateInternal(loc);
 }
 
-ValidateSwitch::ValidateSwitch(TBasicType switchType, TDiagnostics *diagnostics)
+ValidateSwitch::ValidateSwitch(TBasicType switchType, int shaderVersion, TDiagnostics *diagnostics)
     : TIntermTraverser(true, false, true),
       mSwitchType(switchType),
+      mShaderVersion(shaderVersion),
       mDiagnostics(diagnostics),
       mCaseTypeMismatch(false),
       mFirstCaseFound(false),
       mStatementBeforeCase(false),
       mLastStatementWasCase(false),
       mControlFlowDepth(0),
       mCaseInsideControlFlow(false),
       mDefaultCount(0),
@@ -91,16 +98,35 @@ void ValidateSwitch::visitConstantUnion(
 {
     // Conditions of case labels are not traversed, so this is some other constant
     // Could be just a statement like "0;"
     if (!mFirstCaseFound)
         mStatementBeforeCase = true;
     mLastStatementWasCase    = false;
 }
 
+bool ValidateSwitch::visitDeclaration(Visit, TIntermDeclaration *)
+{
+    if (!mFirstCaseFound)
+        mStatementBeforeCase = true;
+    mLastStatementWasCase    = false;
+    return true;
+}
+
+bool ValidateSwitch::visitBlock(Visit, TIntermBlock *)
+{
+    if (getParentNode() != nullptr)
+    {
+        if (!mFirstCaseFound)
+            mStatementBeforeCase = true;
+        mLastStatementWasCase    = false;
+    }
+    return true;
+}
+
 bool ValidateSwitch::visitBinary(Visit, TIntermBinary *)
 {
     if (!mFirstCaseFound)
         mStatementBeforeCase = true;
     mLastStatementWasCase    = false;
     return true;
 }
 
@@ -115,16 +141,24 @@ bool ValidateSwitch::visitUnary(Visit, T
 bool ValidateSwitch::visitTernary(Visit, TIntermTernary *)
 {
     if (!mFirstCaseFound)
         mStatementBeforeCase = true;
     mLastStatementWasCase    = false;
     return true;
 }
 
+bool ValidateSwitch::visitSwizzle(Visit, TIntermSwizzle *)
+{
+    if (!mFirstCaseFound)
+        mStatementBeforeCase = true;
+    mLastStatementWasCase    = false;
+    return true;
+}
+
 bool ValidateSwitch::visitIfElse(Visit visit, TIntermIfElse *)
 {
     if (visit == PreVisit)
         ++mControlFlowDepth;
     if (visit == PostVisit)
         --mControlFlowDepth;
     if (!mFirstCaseFound)
         mStatementBeforeCase = true;
@@ -242,29 +276,44 @@ 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)
     {
-        mDiagnostics->error(
-            loc, "no statement between the last label and the end of the switch statement",
-            "switch");
+        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");
+        }
     }
-    return !mStatementBeforeCase && !mLastStatementWasCase && !mCaseInsideControlFlow &&
+    return !mStatementBeforeCase && !lastStatementWasCaseError && !mCaseInsideControlFlow &&
            !mCaseTypeMismatch && mDefaultCount <= 1 && !mDuplicateCases;
 }
 
 }  // anonymous namespace
 
 bool ValidateSwitchStatementList(TBasicType switchType,
+                                 int shaderVersion,
                                  TDiagnostics *diagnostics,
                                  TIntermBlock *statementList,
                                  const TSourceLoc &loc)
 {
-    return ValidateSwitch::validate(switchType, diagnostics, statementList, loc);
+    return ValidateSwitch::validate(switchType, shaderVersion, diagnostics, statementList, loc);
 }
 
 }  // namespace sh
--- a/gfx/angle/src/compiler/translator/ValidateSwitch.h
+++ b/gfx/angle/src/compiler/translator/ValidateSwitch.h
@@ -13,15 +13,16 @@
 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/src/compiler/translator/ValidateVaryingLocations.cpp
+++ b/gfx/angle/src/compiler/translator/ValidateVaryingLocations.cpp
@@ -6,117 +6,138 @@
 // 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/util.h"
 
 namespace sh
 {
 
 namespace
 {
 
 void error(const TIntermSymbol &symbol, const char *reason, TDiagnostics *diagnostics)
 {
-    diagnostics->error(symbol.getLine(), reason, symbol.getSymbol().c_str());
+    diagnostics->error(symbol.getLine(), reason, symbol.getName().c_str());
 }
 
-int GetLocationCount(const TIntermSymbol *varying)
+int GetLocationCount(const TIntermSymbol *varying, bool ignoreVaryingArraySize)
 {
     const auto &varyingType = varying->getType();
     if (varyingType.getStruct() != nullptr)
     {
         ASSERT(!varyingType.isArray());
         int totalLocation = 0;
         for (const auto *field : varyingType.getStruct()->fields())
         {
             const auto *fieldType = field->type();
             ASSERT(fieldType->getStruct() == nullptr && !fieldType->isArray());
 
             totalLocation += fieldType->getSecondarySize();
         }
         return totalLocation;
     }
+    // [GL_EXT_shader_io_blocks SPEC Chapter 4.4.1]
+    // Geometry shader inputs, tessellation control shader inputs and outputs, and tessellation
+    // evaluation inputs all have an additional level of arrayness relative to other shader inputs
+    // and outputs. This outer array level is removed from the type before considering how many
+    // locations the type consumes.
+    else if (ignoreVaryingArraySize)
+    {
+        // Array-of-arrays cannot be inputs or outputs of a geometry shader.
+        // (GL_EXT_geometry_shader SPEC issues(5))
+        ASSERT(!varyingType.isArrayOfArrays());
+        return varyingType.getSecondarySize();
+    }
     else
     {
         return varyingType.getSecondarySize() * static_cast<int>(varyingType.getArraySizeProduct());
     }
 }
 
 using VaryingVector = std::vector<const TIntermSymbol *>;
 
-void ValidateShaderInterface(TDiagnostics *diagnostics, VaryingVector &varyingVector)
+void ValidateShaderInterface(TDiagnostics *diagnostics,
+                             VaryingVector &varyingVector,
+                             bool ignoreVaryingArraySize)
 {
     // Location conflicts can only happen when there are two or more varyings in varyingVector.
     if (varyingVector.size() <= 1)
     {
         return;
     }
 
     std::map<int, const TIntermSymbol *> locationMap;
     for (const TIntermSymbol *varying : varyingVector)
     {
         const int location = varying->getType().getLayoutQualifier().location;
         ASSERT(location >= 0);
 
-        const int elementCount = GetLocationCount(varying);
+        const int elementCount = GetLocationCount(varying, ignoreVaryingArraySize);
         for (int elementIndex = 0; elementIndex < elementCount; ++elementIndex)
         {
             const int offsetLocation = location + elementIndex;
             if (locationMap.find(offsetLocation) != locationMap.end())
             {
                 std::stringstream strstr;
-                strstr << "'" << varying->getSymbol()
+                strstr << "'" << varying->getName()
                        << "' conflicting location with previously defined '"
-                       << locationMap[offsetLocation]->getSymbol() << "'";
+                       << locationMap[offsetLocation]->getName() << "'";
                 error(*varying, strstr.str().c_str(), diagnostics);
             }
             else
             {
                 locationMap[offsetLocation] = varying;
             }
         }
     }
 }
 
 class ValidateVaryingLocationsTraverser : public TIntermTraverser
 {
   public:
-    ValidateVaryingLocationsTraverser();
+    ValidateVaryingLocationsTraverser(GLenum shaderType);
     void validate(TDiagnostics *diagnostics);
 
   private:
     bool visitDeclaration(Visit visit, TIntermDeclaration *node) override;
     bool visitFunctionDefinition(Visit visit, TIntermFunctionDefinition *node) override;
 
     VaryingVector mInputVaryingsWithLocation;
     VaryingVector mOutputVaryingsWithLocation;
+    GLenum mShaderType;
 };
 
-ValidateVaryingLocationsTraverser::ValidateVaryingLocationsTraverser()
-    : TIntermTraverser(true, false, false)
+ValidateVaryingLocationsTraverser::ValidateVaryingLocationsTraverser(GLenum shaderType)
+    : TIntermTraverser(true, false, false), mShaderType(shaderType)
 {
 }
 
 bool ValidateVaryingLocationsTraverser::visitDeclaration(Visit visit, TIntermDeclaration *node)
 {
     const TIntermSequence &sequence = *(node->getSequence());
     ASSERT(!sequence.empty());
 
     const TIntermSymbol *symbol = sequence.front()->getAsSymbolNode();
     if (symbol == nullptr)
     {
         return false;
     }
 
+    if (symbol->variable().symbolType() == SymbolType::Empty)
+    {
+        return false;
+    }
+
     // Collect varyings that have explicit 'location' qualifiers.
     const TQualifier qualifier = symbol->getQualifier();
     if (symbol->getType().getLayoutQualifier().location != -1)
     {
         if (IsVaryingIn(qualifier))
         {
             mInputVaryingsWithLocation.push_back(symbol);
         }
@@ -135,24 +156,25 @@ bool ValidateVaryingLocationsTraverser::
     // We stop traversing function definitions because varyings cannot be defined in a function.
     return false;
 }
 
 void ValidateVaryingLocationsTraverser::validate(TDiagnostics *diagnostics)
 {
     ASSERT(diagnostics);
 
-    ValidateShaderInterface(diagnostics, mInputVaryingsWithLocation);
-    ValidateShaderInterface(diagnostics, mOutputVaryingsWithLocation);
+    ValidateShaderInterface(diagnostics, mInputVaryingsWithLocation,
+                            mShaderType == GL_GEOMETRY_SHADER_EXT);
+    ValidateShaderInterface(diagnostics, mOutputVaryingsWithLocation, false);
 }
 
 }  // anonymous namespace
 
-bool ValidateVaryingLocations(TIntermBlock *root, TDiagnostics *diagnostics)
+bool ValidateVaryingLocations(TIntermBlock *root, TDiagnostics *diagnostics, GLenum shaderType)
 {
-    ValidateVaryingLocationsTraverser varyingValidator;
+    ValidateVaryingLocationsTraverser varyingValidator(shaderType);
     root->traverse(&varyingValidator);
     int numErrorsBefore = diagnostics->numErrors();
     varyingValidator.validate(diagnostics);
     return (diagnostics->numErrors() == numErrorsBefore);
 }
 
 }  // namespace sh
\ No newline at end of file
--- a/gfx/angle/src/compiler/translator/ValidateVaryingLocations.h
+++ b/gfx/angle/src/compiler/translator/ValidateVaryingLocations.h
@@ -5,19 +5,21 @@
 //
 // The ValidateVaryingLocations function checks if there exists location conflicts on shader
 // varyings.
 //
 
 #ifndef COMPILER_TRANSLATOR_VALIDATEVARYINGLOCATIONS_H_
 #define COMPILER_TRANSLATOR_VALIDATEVARYINGLOCATIONS_H_
 
+#include "GLSLANG/ShaderVars.h"
+
 namespace sh
 {
 
 class TIntermBlock;
 class TDiagnostics;
 
-bool ValidateVaryingLocations(TIntermBlock *root, TDiagnostics *diagnostics);
+bool ValidateVaryingLocations(TIntermBlock *root, TDiagnostics *diagnostics, GLenum shaderType);
 
 }  // namespace sh
 
 #endif
\ No newline at end of file
--- a/gfx/angle/src/compiler/translator/VariablePacker.cpp
+++ b/gfx/angle/src/compiler/translator/VariablePacker.cpp
@@ -14,86 +14,88 @@
 #include "common/utilities.h"
 
 namespace sh
 {
 
 namespace
 {
 
+// Expand the variable so that struct variables are split into their individual fields.
+// Will not set the mappedName or staticUse fields on the expanded variables.
 void ExpandVariable(const ShaderVariable &variable,
                     const std::string &name,
-                    const std::string &mappedName,
-                    bool markStaticUse,
                     std::vector<ShaderVariable> *expanded);
 
-void ExpandUserDefinedVariable(const ShaderVariable &variable,
-                               const std::string &name,
-                               const std::string &mappedName,
-                               bool markStaticUse,
-                               std::vector<ShaderVariable> *expanded)
+void ExpandStructVariable(const ShaderVariable &variable,
+                          const std::string &name,
+                          std::vector<ShaderVariable> *expanded)
 {
     ASSERT(variable.isStruct());
 
     const std::vector<ShaderVariable> &fields = variable.fields;
 
     for (size_t fieldIndex = 0; fieldIndex < fields.size(); fieldIndex++)
     {
         const ShaderVariable &field = fields[fieldIndex];
-        ExpandVariable(field, name + "." + field.name, mappedName + "." + field.mappedName,
-                       markStaticUse, expanded);
+        ExpandVariable(field, name + "." + field.name, expanded);
+    }
+}
+
+void ExpandStructArrayVariable(const ShaderVariable &variable,
+                               unsigned int arrayNestingIndex,
+                               const std::string &name,
+                               std::vector<ShaderVariable> *expanded)
+{
+    // Nested arrays are processed starting from outermost (arrayNestingIndex 0u) and ending at the
+    // innermost.
+    const unsigned int currentArraySize = variable.getNestedArraySize(arrayNestingIndex);
+    for (unsigned int arrayElement = 0u; arrayElement < currentArraySize; ++arrayElement)
+    {
+        const std::string elementName = name + ArrayString(arrayElement);
+        if (arrayNestingIndex + 1u < variable.arraySizes.size())
+        {
+            ExpandStructArrayVariable(variable, arrayNestingIndex + 1u, elementName, expanded);
+        }
+        else
+        {
+            ExpandStructVariable(variable, elementName, expanded);
+        }
     }
 }
 
 void ExpandVariable(const ShaderVariable &variable,
                     const std::string &name,
-                    const std::string &mappedName,
-                    bool markStaticUse,
                     std::vector<ShaderVariable> *expanded)
 {
     if (variable.isStruct())
     {
         if (variable.isArray())
         {
-            for (unsigned int elementIndex = 0; elementIndex < variable.elementCount();
-                 elementIndex++)
-            {
-                std::string lname       = name + ::ArrayString(elementIndex);
-                std::string lmappedName = mappedName + ::ArrayString(elementIndex);
-                ExpandUserDefinedVariable(variable, lname, lmappedName, markStaticUse, expanded);
-            }
+            ExpandStructArrayVariable(variable, 0u, name, expanded);
         }
         else
         {
-            ExpandUserDefinedVariable(variable, name, mappedName, markStaticUse, expanded);
+            ExpandStructVariable(variable, name, expanded);
         }
     }
     else
     {
         ShaderVariable expandedVar = variable;
-
         expandedVar.name       = name;
-        expandedVar.mappedName = mappedName;
-
-        // Mark all expanded fields as used if the parent is used
-        if (markStaticUse)
-        {
-            expandedVar.staticUse = true;
-        }
-
-        if (expandedVar.isArray())
-        {
-            expandedVar.name += "[0]";
-            expandedVar.mappedName += "[0]";
-        }
 
         expanded->push_back(expandedVar);
     }
 }
 
+int GetVariablePackingRows(const ShaderVariable &variable)
+{
+    return GetTypePackingRows(variable.type) * variable.getArraySizeProduct();
+}
+
 class VariablePacker
 {
   public:
     bool checkExpandedVariablesWithinPackingLimits(unsigned int maxVectors,
                                                    std::vector<sh::ShaderVariable> *variables);
 
   private:
     static const int kNumColumns      = 4;
@@ -115,17 +117,17 @@ struct TVariableInfoComparer
     {
         int lhsSortOrder = gl::VariableSortOrder(lhs.type);
         int rhsSortOrder = gl::VariableSortOrder(rhs.type);
         if (lhsSortOrder != rhsSortOrder)
         {
             return lhsSortOrder < rhsSortOrder;
         }
         // Sort by largest first.
-        return lhs.arraySize > rhs.arraySize;
+        return lhs.getArraySizeProduct() > rhs.getArraySizeProduct();
     }
 };
 
 unsigned VariablePacker::makeColumnFlags(int column, int numComponentsPerRow)
 {
     return ((kColumnMask << (kNumColumns - numComponentsPerRow)) & kColumnMask) >> column;
 }
 
@@ -210,55 +212,55 @@ bool VariablePacker::checkExpandedVariab
     topNonFullRow_    = 0;
     bottomNonFullRow_ = maxRows_ - 1;
 
     // Check whether each variable fits in the available vectors.
     for (const sh::ShaderVariable &variable : *variables)
     {
         // Structs should have been expanded before reaching here.
         ASSERT(!variable.isStruct());
-        if (variable.elementCount() > maxVectors / GetVariablePackingRows(variable.type))
+        if (variable.getArraySizeProduct() > maxVectors / GetTypePackingRows(variable.type))
         {
             return false;
         }
     }
 
     // As per GLSL 1.017 Appendix A, Section 7 variables are packed in specific
     // order by type, then by size of array, largest first.
     std::sort(variables->begin(), variables->end(), TVariableInfoComparer());
     rows_.clear();
     rows_.resize(maxVectors, 0);
 
     // Packs the 4 column variables.
     size_t ii = 0;
     for (; ii < variables->size(); ++ii)
     {
         const sh::ShaderVariable &variable = (*variables)[ii];
-        if (GetVariablePackingComponentsPerRow(variable.type) != 4)
+        if (GetTypePackingComponentsPerRow(variable.type) != 4)
         {
             break;
         }
-        topNonFullRow_ += GetVariablePackingRows(variable.type) * variable.elementCount();
+        topNonFullRow_ += GetVariablePackingRows(variable);
     }
 
     if (topNonFullRow_ > maxRows_)
     {
         return false;
     }
 
     // Packs the 3 column variables.
     int num3ColumnRows = 0;
     for (; ii < variables->size(); ++ii)
     {
         const sh::ShaderVariable &variable = (*variables)[ii];
-        if (GetVariablePackingComponentsPerRow(variable.type) != 3)
+        if (GetTypePackingComponentsPerRow(variable.type) != 3)
         {
             break;
         }
-        num3ColumnRows += GetVariablePackingRows(variable.type) * variable.elementCount();
+        num3ColumnRows += GetVariablePackingRows(variable);
     }
 
     if (topNonFullRow_ + num3ColumnRows > maxRows_)
     {
         return false;
     }
 
     fillColumns(topNonFullRow_, num3ColumnRows, 0, 3);
@@ -266,21 +268,21 @@ bool VariablePacker::checkExpandedVariab
     // Packs the 2 column variables.
     int top2ColumnRow            = topNonFullRow_ + num3ColumnRows;
     int twoColumnRowsAvailable   = maxRows_ - top2ColumnRow;
     int rowsAvailableInColumns01 = twoColumnRowsAvailable;
     int rowsAvailableInColumns23 = twoColumnRowsAvailable;
     for (; ii < variables->size(); ++ii)
     {
         const sh::ShaderVariable &variable = (*variables)[ii];
-        if (GetVariablePackingComponentsPerRow(variable.type) != 2)
+        if (GetTypePackingComponentsPerRow(variable.type) != 2)
         {
             break;
         }
-        int numRows = GetVariablePackingRows(variable.type) * variable.elementCount();
+        int numRows = GetVariablePackingRows(variable);
         if (numRows <= rowsAvailableInColumns01)
         {
             rowsAvailableInColumns01 -= numRows;
         }
         else if (numRows <= rowsAvailableInColumns23)
         {
             rowsAvailableInColumns23 -= numRows;
         }
@@ -294,18 +296,18 @@ bool VariablePacker::checkExpandedVariab
     int numRowsUsedInColumns23 = twoColumnRowsAvailable - rowsAvailableInColumns23;
     fillColumns(top2ColumnRow, numRowsUsedInColumns01, 0, 2);
     fillColumns(maxRows_ - numRowsUsedInColumns23, numRowsUsedInColumns23, 2, 2);
 
     // Packs the 1 column variables.
     for (; ii < variables->size(); ++ii)
     {
         const sh::ShaderVariable &variable = (*variables)[ii];
-        ASSERT(1 == GetVariablePackingComponentsPerRow(variable.type));
-        int numRows        = GetVariablePackingRows(variable.type) * variable.elementCount();
+        ASSERT(1 == GetTypePackingComponentsPerRow(variable.type));
+        int numRows        = GetVariablePackingRows(variable);
         int smallestColumn = -1;
         int smallestSize   = maxRows_ + 1;
         int topRow         = -1;
         for (int column = 0; column < kNumColumns; ++column)
         {
             int row  = 0;
             int size = 0;
             if (searchColumn(column, numRows, &row, &size))
@@ -329,17 +331,17 @@ bool VariablePacker::checkExpandedVariab
 
     ASSERT(variables->size() == ii);
 
     return true;
 }
 
 }  // anonymous namespace
 
-int GetVariablePackingComponentsPerRow(sh::GLenum type)
+int GetTypePackingComponentsPerRow(sh::GLenum type)
 {
     switch (type)
     {
         case GL_FLOAT_MAT4:
         case GL_FLOAT_MAT2:
         case GL_FLOAT_MAT2x4:
         case GL_FLOAT_MAT3x4:
         case GL_FLOAT_MAT4x2:
@@ -363,17 +365,17 @@ int GetVariablePackingComponentsPerRow(s
         case GL_UNSIGNED_INT_VEC2:
             return 2;
         default:
             ASSERT(gl::VariableComponentCount(type) == 1);
             return 1;
     }
 }
 
-int GetVariablePackingRows(sh::GLenum type)
+int GetTypePackingRows(sh::GLenum type)
 {
     switch (type)
     {
         case GL_FLOAT_MAT4:
         case GL_FLOAT_MAT2x4:
         case GL_FLOAT_MAT3x4:
         case GL_FLOAT_MAT4x3:
         case GL_FLOAT_MAT4x2:
@@ -392,18 +394,17 @@ int GetVariablePackingRows(sh::GLenum ty
 
 template <typename T>
 bool CheckVariablesInPackingLimits(unsigned int maxVectors, const std::vector<T> &variables)
 {
     VariablePacker packer;
     std::vector<sh::ShaderVariable> expandedVariables;
     for (const ShaderVariable &variable : variables)
     {
-        ExpandVariable(variable, variable.name, variable.mappedName, variable.staticUse,
-                       &expandedVariables);
+        ExpandVariable(variable, variable.name, &expandedVariables);
     }
     return packer.checkExpandedVariablesWithinPackingLimits(maxVectors, &expandedVariables);
 }
 
 template bool CheckVariablesInPackingLimits<ShaderVariable>(
     unsigned int maxVectors,
     const std::vector<ShaderVariable> &variables);
 template bool CheckVariablesInPackingLimits<Uniform>(unsigned int maxVectors,
--- a/gfx/angle/src/compiler/translator/VariablePacker.h
+++ b/gfx/angle/src/compiler/translator/VariablePacker.h
@@ -12,20 +12,20 @@
 #include <vector>
 
 #include <GLSLANG/ShaderLang.h>
 
 namespace sh
 {
 
 // Gets how many components in a row a data type takes.
-int GetVariablePackingComponentsPerRow(sh::GLenum type);
+int GetTypePackingComponentsPerRow(sh::GLenum type);
 
 // Gets how many rows a data type takes.
-int GetVariablePackingRows(sh::GLenum type);
+int GetTypePackingRows(sh::GLenum type);
 
 // Returns true if the passed in variables pack in maxVectors.
 // T should be ShaderVariable or one of the subclasses of ShaderVariable.
 template <typename T>
 bool CheckVariablesInPackingLimits(unsigned int maxVectors, const std::vector<T> &variables);
 
 }  // namespace sh
 
new file mode 100644
--- /dev/null
+++ b/gfx/angle/src/compiler/translator/VectorizeVectorScalarArithmetic.cpp
@@ -0,0 +1,286 @@
+// 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
+    TIntermBinary *replacementSequence = new TIntermBinary(
+        EOpComma, replacementSequenceLeft, CreateTempSymbolNode(tempAssignmentTarget));
+
+    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/src/compiler/translator/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_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/src/compiler/translator/VersionGLSL.cpp
+++ b/gfx/angle/src/compiler/translator/VersionGLSL.cpp
@@ -2,16 +2,17 @@
 // 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.
 //
 
 #include "compiler/translator/VersionGLSL.h"
 
 #include "angle_gl.h"
+#include "compiler/translator/Symbol.h"
 
 namespace sh
 {
 
 int ShaderOutputTypeToGLSLVersion(ShShaderOutput output)
 {
     switch (output)
     {
@@ -71,17 +72,17 @@ TVersionGLSL::TVersionGLSL(sh::GLenum ty
     if (type == GL_COMPUTE_SHADER)
     {
         ensureVersionIsAtLeast(GLSL_VERSION_430);
     }
 }
 
 void TVersionGLSL::visitSymbol(TIntermSymbol *node)
 {
-    if (node->getSymbol() == "gl_PointCoord")
+    if (node->variable().symbolType() == SymbolType::BuiltIn && node->getName() == "gl_PointCoord")
     {
         ensureVersionIsAtLeast(GLSL_VERSION_120);
     }
 }
 
 bool TVersionGLSL::visitDeclaration(Visit, TIntermDeclaration *node)
 {
     const TIntermSequence &sequence = *(node->getSequence());
new file mode 100644
--- /dev/null
+++ b/gfx/angle/src/compiler/translator/WrapSwitchStatementsInBlocks.cpp
@@ -0,0 +1,132 @@
+//
+// 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
new file mode 100644
--- /dev/null
+++ b/gfx/angle/src/compiler/translator/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_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/src/compiler/translator/blocklayout.cpp
+++ b/gfx/angle/src/compiler/translator/blocklayout.cpp
@@ -10,35 +10,169 @@
 #include "compiler/translator/blocklayout.h"
 
 #include "common/mathutil.h"
 #include "common/utilities.h"
 
 namespace sh
 {
 
+namespace
+{
+bool IsRowMajorLayout(const InterfaceBlockField &var)
+{
+    return var.isRowMajorLayout;
+}
+
+bool IsRowMajorLayout(const ShaderVariable &var)
+{
+    return false;
+}
+
+template <typename VarT>
+void GetUniformBlockInfo(const std::vector<VarT> &fields,
+                         const std::string &prefix,
+                         sh::BlockLayoutEncoder *encoder,
+                         bool inRowMajorLayout,
+                         BlockLayoutMap *blockInfoOut);
+
+template <typename VarT>
+void GetUniformBlockStructMemberInfo(const std::vector<VarT> &fields,
+                                     const std::string &fieldName,
+                                     sh::BlockLayoutEncoder *encoder,
+                                     bool inRowMajorLayout,
+                                     BlockLayoutMap *blockInfoOut)
+{
+    encoder->enterAggregateType();
+    GetUniformBlockInfo(fields, fieldName, encoder, inRowMajorLayout, blockInfoOut);
+    encoder->exitAggregateType();
+}
+
+template <typename VarT>
+void GetUniformBlockStructArrayMemberInfo(const VarT &field,
+                                          unsigned int arrayNestingIndex,
+                                          const std::string &arrayName,
+                                          sh::BlockLayoutEncoder *encoder,
+                                          bool inRowMajorLayout,
+                                          BlockLayoutMap *blockInfoOut)
+{
+    // Nested arrays are processed starting from outermost (arrayNestingIndex 0u) and ending at the
+    // innermost.
+    const unsigned int currentArraySize = field.getNestedArraySize(arrayNestingIndex);
+    for (unsigned int arrayElement = 0u; arrayElement < currentArraySize; ++arrayElement)
+    {
+        const std::string elementName = arrayName + ArrayString(arrayElement);
+        if (arrayNestingIndex + 1u < field.arraySizes.size())
+        {
+            GetUniformBlockStructArrayMemberInfo(field, arrayNestingIndex + 1u, elementName,
+                                                 encoder, inRowMajorLayout, blockInfoOut);
+        }
+        else
+        {
+            GetUniformBlockStructMemberInfo(field.fields, elementName, encoder, inRowMajorLayout,
+                                            blockInfoOut);
+        }
+    }
+}
+
+template <typename VarT>
+void GetUniformBlockArrayOfArraysMemberInfo(const VarT &field,
+                                            unsigned int arrayNestingIndex,
+                                            const std::string &arrayName,
+                                            sh::BlockLayoutEncoder *encoder,
+                                            bool isRowMajorMatrix,
+                                            BlockLayoutMap *blockInfoOut)
+{
+    const unsigned int currentArraySize = field.getNestedArraySize(arrayNestingIndex);
+    for (unsigned int arrayElement = 0u; arrayElement < currentArraySize; ++arrayElement)
+    {
+        const std::string elementName = arrayName + ArrayString(arrayElement);
+        if (arrayNestingIndex + 2u < field.arraySizes.size())
+        {
+            GetUniformBlockArrayOfArraysMemberInfo(field, arrayNestingIndex + 1u, elementName,
+                                                   encoder, isRowMajorMatrix, blockInfoOut);
+        }
+        else
+        {
+            std::vector<unsigned int> innermostArraySize(
+                1u, field.getNestedArraySize(arrayNestingIndex + 1u));
+            (*blockInfoOut)[elementName] =
+                encoder->encodeType(field.type, innermostArraySize, isRowMajorMatrix);
+        }
+    }
+}
+
+template <typename VarT>
+void GetUniformBlockInfo(const std::vector<VarT> &fields,
+                         const std::string &prefix,
+                         sh::BlockLayoutEncoder *encoder,
+                         bool inRowMajorLayout,
+                         BlockLayoutMap *blockInfoOut)
+{
+    for (const VarT &field : fields)
+    {
+        // Skip samplers. On Vulkan we use this for the default uniform block, so samplers may be
+        // included.
+        if (gl::IsSamplerType(field.type))
+        {
+            continue;
+        }
+
+        const std::string &fieldName = (prefix.empty() ? field.name : prefix + "." + field.name);
+
+        bool rowMajorLayout = (inRowMajorLayout || IsRowMajorLayout(field));
+
+        if (field.isStruct())
+        {
+            if (field.isArray())
+            {
+                GetUniformBlockStructArrayMemberInfo(field, 0u, fieldName, encoder, rowMajorLayout,
+                                                     blockInfoOut);
+            }
+            else
+            {
+                GetUniformBlockStructMemberInfo(field.fields, fieldName, encoder, rowMajorLayout,
+                                                blockInfoOut);
+            }
+        }
+        else if (field.isArrayOfArrays())
+        {
+            GetUniformBlockArrayOfArraysMemberInfo(field, 0u, fieldName, encoder,
+                                                   rowMajorLayout && gl::IsMatrixType(field.type),
+                                                   blockInfoOut);
+        }
+        else
+        {
+            (*blockInfoOut)[fieldName] = encoder->encodeType(
+                field.type, field.arraySizes, rowMajorLayout && gl::IsMatrixType(field.type));
+        }
+    }
+}
+
+}  // anonymous namespace
+
 BlockLayoutEncoder::BlockLayoutEncoder() : mCurrentOffset(0)
 {
 }
 
 BlockMemberInfo BlockLayoutEncoder::encodeType(GLenum type,
-                                               unsigned int arraySize,
+                                               const std::vector<unsigned int> &arraySizes,
                                                bool isRowMajorMatrix)
 {
     int arrayStride;
     int matrixStride;
 
-    getBlockLayoutInfo(type, arraySize, isRowMajorMatrix, &arrayStride, &matrixStride);
+    getBlockLayoutInfo(type, arraySizes, isRowMajorMatrix, &arrayStride, &matrixStride);
 
     const BlockMemberInfo memberInfo(static_cast<int>(mCurrentOffset * BytesPerComponent),
                                      static_cast<int>(arrayStride * BytesPerComponent),
                                      static_cast<int>(matrixStride * BytesPerComponent),
                                      isRowMajorMatrix);
 
-    advanceOffset(type, arraySize, isRowMajorMatrix, arrayStride, matrixStride);
+    advanceOffset(type, arraySizes, isRowMajorMatrix, arrayStride, matrixStride);
 
     return memberInfo;
 }
 
 // static
 size_t BlockLayoutEncoder::getBlockRegister(const BlockMemberInfo &info)
 {
     return (info.offset / BytesPerComponent) / ComponentsPerRegister;
@@ -65,40 +199,40 @@ void Std140BlockEncoder::enterAggregateT
 }
 
 void Std140BlockEncoder::exitAggregateType()
 {
     nextRegister();
 }
 
 void Std140BlockEncoder::getBlockLayoutInfo(GLenum type,
-                                            unsigned int arraySize,
+                                            const std::vector<unsigned int> &arraySizes,
                                             bool isRowMajorMatrix,
                                             int *arrayStrideOut,
                                             int *matrixStrideOut)
 {
     // We assume we are only dealing with 4 byte components (no doubles or half-words currently)
     ASSERT(gl::VariableComponentSize(gl::VariableComponentType(type)) == BytesPerComponent);
 
     size_t baseAlignment = 0;
     int matrixStride     = 0;
     int arrayStride      = 0;
 
     if (gl::IsMatrixType(type))
     {
         baseAlignment = ComponentsPerRegister;
         matrixStride  = ComponentsPerRegister;
 
-        if (arraySize > 0)
+        if (!arraySizes.empty())
         {
             const int numRegisters = gl::MatrixRegisterCount(type, isRowMajorMatrix);
             arrayStride            = ComponentsPerRegister * numRegisters;
         }
     }
-    else if (arraySize > 0)
+    else if (!arraySizes.empty())
     {
         baseAlignment = ComponentsPerRegister;
         arrayStride   = ComponentsPerRegister;
     }
     else
     {
         const int numComponents = gl::VariableComponentCount(type);
         baseAlignment           = (numComponents == 3 ? 4u : static_cast<size_t>(numComponents));
@@ -106,29 +240,51 @@ void Std140BlockEncoder::getBlockLayoutI
 
     mCurrentOffset = rx::roundUp(mCurrentOffset, baseAlignment);
 
     *matrixStrideOut = matrixStride;
     *arrayStrideOut  = arrayStride;
 }
 
 void Std140BlockEncoder::advanceOffset(GLenum type,
-                                       unsigned int arraySize,
+                                       const std::vector<unsigned int> &arraySizes,
                                        bool isRowMajorMatrix,
                                        int arrayStride,
                                        int matrixStride)
 {
-    if (arraySize > 0)
+    if (!arraySizes.empty())
     {
-        mCurrentOffset += arrayStride * arraySize;
+        mCurrentOffset += arrayStride * gl::ArraySizeProduct(arraySizes);
     }
     else if (gl::IsMatrixType(type))
     {
         ASSERT(matrixStride == ComponentsPerRegister);
         const int numRegisters = gl::MatrixRegisterCount(type, isRowMajorMatrix);
         mCurrentOffset += ComponentsPerRegister * numRegisters;
     }
     else
     {
         mCurrentOffset += gl::VariableComponentCount(type);
     }
 }
+
+void GetUniformBlockInfo(const std::vector<InterfaceBlockField> &fields,
+                         const std::string &prefix,
+                         sh::BlockLayoutEncoder *encoder,
+                         BlockLayoutMap *blockInfoOut)
+{
+    // Matrix packing is always recorded in individual fields, so they'll set the row major layout
+    // flag to true if needed.
+    GetUniformBlockInfo(fields, prefix, encoder, false, blockInfoOut);
 }
+
+void GetUniformBlockInfo(const std::vector<Uniform> &uniforms,
+                         const std::string &prefix,
+                         sh::BlockLayoutEncoder *encoder,
+                         BlockLayoutMap *blockInfoOut)
+{
+    // Matrix packing is always recorded in individual fields, so they'll set the row major layout
+    // flag to true if needed.
+    GetUniformBlockInfo(uniforms, prefix, encoder, false, blockInfoOut);
+}
+
+
+}  // namespace sh
--- a/gfx/angle/src/compiler/translator/blocklayout.h
+++ b/gfx/angle/src/compiler/translator/blocklayout.h
@@ -6,56 +6,81 @@
 // blocklayout.h:
 //   Methods and classes related to uniform layout and packing in GLSL and HLSL.
 //
 
 #ifndef COMMON_BLOCKLAYOUT_H_
 #define COMMON_BLOCKLAYOUT_H_
 
 #include <cstddef>
+#include <map>
 #include <vector>
 
 #include "angle_gl.h"
 #include <GLSLANG/ShaderLang.h>
 
 namespace sh
 {
 struct ShaderVariable;
 struct InterfaceBlockField;
 struct Uniform;
 struct Varying;
 struct InterfaceBlock;
 
 struct BlockMemberInfo
 {
-    BlockMemberInfo() : offset(-1), arrayStride(-1), matrixStride(-1), isRowMajorMatrix(false) {}
+    BlockMemberInfo()
+        : offset(-1),
+          arrayStride(-1),
+          matrixStride(-1),
+          isRowMajorMatrix(false),
+          topLevelArrayStride(-1)
+    {
+    }
 
     BlockMemberInfo(int offset, int arrayStride, int matrixStride, bool isRowMajorMatrix)
         : offset(offset),
           arrayStride(arrayStride),
           matrixStride(matrixStride),
-          isRowMajorMatrix(isRowMajorMatrix)
+          isRowMajorMatrix(isRowMajorMatrix),
+          topLevelArrayStride(-1)
     {
     }
 
-    static BlockMemberInfo getDefaultBlockInfo() { return BlockMemberInfo(-1, -1, -1, false); }
+    BlockMemberInfo(int offset,
+                    int arrayStride,
+                    int matrixStride,
+                    bool isRowMajorMatrix,
+                    int topLevelArrayStride)
+        : offset(offset),
+          arrayStride(arrayStride),
+          matrixStride(matrixStride),
+          isRowMajorMatrix(isRowMajorMatrix),
+          topLevelArrayStride(topLevelArrayStride)
+    {
+    }
+
+    static BlockMemberInfo getDefaultBlockInfo() { return BlockMemberInfo(-1, -1, -1, false, -1); }
 
     int offset;
     int arrayStride;
     int matrixStride;
     bool isRowMajorMatrix;
+    int topLevelArrayStride;  // Only used for shader storage block members.
 };
 
 class BlockLayoutEncoder
 {
   public:
     BlockLayoutEncoder();
     virtual ~BlockLayoutEncoder() {}
 
-    BlockMemberInfo encodeType(GLenum type, unsigned int arraySize, bool isRowMajorMatrix);
+    BlockMemberInfo encodeType(GLenum type,
+                               const std::vector<unsigned int> &arraySizes,
+                               bool isRowMajorMatrix);
 
     size_t getBlockSize() const { return mCurrentOffset * BytesPerComponent; }
 
     virtual void enterAggregateType() = 0;
     virtual void exitAggregateType()  = 0;
 
     static const size_t BytesPerComponent           = 4u;
     static const unsigned int ComponentsPerRegister = 4u;
@@ -64,45 +89,59 @@ class BlockLayoutEncoder
     static size_t getBlockRegisterElement(const BlockMemberInfo &info);
 
   protected:
     size_t mCurrentOffset;
 
     void nextRegister();
 
     virtual void getBlockLayoutInfo(GLenum type,
-                                    unsigned int arraySize,
+                                    const std::vector<unsigned int> &arraySizes,
                                     bool isRowMajorMatrix,
                                     int *arrayStrideOut,
                                     int *matrixStrideOut) = 0;
     virtual void advanceOffset(GLenum type,
-                               unsigned int arraySize,
+                               const std::vector<unsigned int> &arraySizes,
                                bool isRowMajorMatrix,
                                int arrayStride,
-                               int matrixStride) = 0;
+                               int matrixStride)          = 0;
 };
 
 // Block layout according to the std140 block layout
 // See "Standard Uniform Block Layout" in Section 2.11.6 of the OpenGL ES 3.0 specification
 
 class Std140BlockEncoder : public BlockLayoutEncoder
 {
   public:
     Std140BlockEncoder();
 
     void enterAggregateType() override;
     void exitAggregateType() override;
 
   protected:
     void getBlockLayoutInfo(GLenum type,
-                            unsigned int arraySize,
+                            const std::vector<unsigned int> &arraySizes,
                             bool isRowMajorMatrix,
                             int *arrayStrideOut,
                             int *matrixStrideOut) override;
     void advanceOffset(GLenum type,
-                       unsigned int arraySize,
+                       const std::vector<unsigned int> &arraySizes,
                        bool isRowMajorMatrix,
                        int arrayStride,
                        int matrixStride) override;
 };
-}
+
+using BlockLayoutMap = std::map<std::string, BlockMemberInfo>;
+
+void GetUniformBlockInfo(const std::vector<InterfaceBlockField> &fields,
+                         const std::string &prefix,
+                         sh::BlockLayoutEncoder *encoder,
+                         BlockLayoutMap *blockInfoOut);
+
+// Used for laying out the default uniform block on the Vulkan backend.
+void GetUniformBlockInfo(const std::vector<Uniform> &uniforms,
+                         const std::string &prefix,
+                         sh::BlockLayoutEncoder *encoder,
+                         BlockLayoutMap *blockInfoOut);
+
+}  // namespace sh
 
 #endif  // COMMON_BLOCKLAYOUT_H_
--- a/gfx/angle/src/compiler/translator/blocklayoutHLSL.cpp
+++ b/gfx/angle/src/compiler/translator/blocklayoutHLSL.cpp
@@ -25,48 +25,48 @@ void HLSLBlockEncoder::enterAggregateTyp
     nextRegister();
 }
 
 void HLSLBlockEncoder::exitAggregateType()
 {
 }
 
 void HLSLBlockEncoder::getBlockLayoutInfo(GLenum typeIn,
-                                          unsigned int arraySize,
+                                          const std::vector<unsigned int> &arraySizes,
                                           bool isRowMajorMatrix,
                                           int *arrayStrideOut,
                                           int *matrixStrideOut)
 {
     GLenum type = (mTransposeMatrices ? gl::TransposeMatrixType(typeIn) : typeIn);
 
     // We assume we are only dealing with 4 byte components (no doubles or half-words currently)
     ASSERT(gl::VariableComponentSize(gl::VariableComponentType(type)) == BytesPerComponent);
 
     int matrixStride = 0;
     int arrayStride  = 0;
 
     // if variables are not to be packed, or we're about to
     // pack a matrix or array, skip to the start of the next
     // register
-    if (!isPacked() || gl::IsMatrixType(type) || arraySize > 0)
+    if (!isPacked() || gl::IsMatrixType(type) || !arraySizes.empty())
     {
         nextRegister();
     }
 
     if (gl::IsMatrixType(type))
     {
         matrixStride = ComponentsPerRegister;
 
-        if (arraySize > 0)
+        if (!arraySizes.empty())
         {
             const int numRegisters = gl::MatrixRegisterCount(type, isRowMajorMatrix);
             arrayStride            = ComponentsPerRegister * numRegisters;
         }
     }
-    else if (arraySize > 0)
+    else if (!arraySizes.empty())
     {
         arrayStride = ComponentsPerRegister;
     }
     else if (isPacked())
     {
         int numComponents = gl::VariableComponentCount(type);
         if ((numComponents + (mCurrentOffset % ComponentsPerRegister)) > ComponentsPerRegister)
         {
@@ -74,26 +74,26 @@ void HLSLBlockEncoder::getBlockLayoutInf
         }
     }
 
     *matrixStrideOut = matrixStride;
     *arrayStrideOut  = arrayStride;
 }
 
 void HLSLBlockEncoder::advanceOffset(GLenum typeIn,
-                                     unsigned int arraySize,
+                                     const std::vector<unsigned int> &arraySizes,
                                      bool isRowMajorMatrix,
                                      int arrayStride,
                                      int matrixStride)
 {
     GLenum type = (mTransposeMatrices ? gl::TransposeMatrixType(typeIn) : typeIn);
 
-    if (arraySize > 0)
+    if (!arraySizes.empty())
     {
-        mCurrentOffset += arrayStride * (arraySize - 1);
+        mCurrentOffset += arrayStride * (gl::ArraySizeProduct(arraySizes) - 1);
     }
 
     if (gl::IsMatrixType(type))
     {
         ASSERT(matrixStride == ComponentsPerRegister);
         const int numRegisters  = gl::MatrixRegisterCount(type, isRowMajorMatrix);
         const int numComponents = gl::MatrixComponentCount(type, isRowMajorMatrix);
         mCurrentOffset += ComponentsPerRegister * (numRegisters - 1);
@@ -130,32 +130,32 @@ HLSLBlockEncoder::HLSLBlockEncoderStrate
     }
 }
 
 template <class ShaderVarType>
 void HLSLVariableRegisterCount(const ShaderVarType &variable, HLSLBlockEncoder *encoder)
 {
     if (variable.isStruct())
     {
-        for (size_t arrayElement = 0; arrayElement < variable.elementCount(); arrayElement++)
+        for (size_t arrayElement = 0; arrayElement < variable.getArraySizeProduct(); arrayElement++)
         {
             encoder->enterAggregateType();
 
             for (size_t fieldIndex = 0; fieldIndex < variable.fields.size(); fieldIndex++)
             {
                 HLSLVariableRegisterCount(variable.fields[fieldIndex], encoder);
             }
 
             encoder->exitAggregateType();
         }
     }
     else
     {
         // We operate only on varyings and uniforms, which do not have matrix layout qualifiers
-        encoder->encodeType(variable.type, variable.arraySize, false);
+        encoder->encodeType(variable.type, variable.arraySizes, false);
     }
 }
 
 unsigned int HLSLVariableRegisterCount(const Uniform &variable, ShShaderOutput outputType)
 {
     HLSLBlockEncoder encoder(HLSLBlockEncoder::GetStrategyFor(outputType), true);
     HLSLVariableRegisterCount(variable, &encoder);
 
--- a/gfx/angle/src/compiler/translator/blocklayoutHLSL.h
+++ b/gfx/angle/src/compiler/translator/blocklayoutHLSL.h
@@ -30,35 +30,35 @@ class HLSLBlockEncoder : public BlockLay
     enum HLSLBlockEncoderStrategy
     {
         ENCODE_PACKED,
         ENCODE_LOOSE
     };
 
     HLSLBlockEncoder(HLSLBlockEncoderStrategy strategy, bool transposeMatrices);
 
-    virtual void enterAggregateType();
-    virtual void exitAggregateType();
+    void enterAggregateType() override;
+    void exitAggregateType() override;
     void skipRegisters(unsigned int numRegisters);
 
     bool isPacked() const { return mEncoderStrategy == ENCODE_PACKED; }
 
     static HLSLBlockEncoderStrategy GetStrategyFor(ShShaderOutput outputType);
 
   protected:
-    virtual void getBlockLayoutInfo(GLenum type,
-                                    unsigned int arraySize,
-                                    bool isRowMajorMatrix,
-                                    int *arrayStrideOut,
-                                    int *matrixStrideOut);
-    virtual void advanceOffset(GLenum type,
-                               unsigned int arraySize,
-                               bool isRowMajorMatrix,
-                               int arrayStride,
-                               int matrixStride);
+    void getBlockLayoutInfo(GLenum type,
+                            const std::vector<unsigned int> &arraySizes,
+                            bool isRowMajorMatrix,
+                            int *arrayStrideOut,
+                            int *matrixStrideOut) override;
+    void advanceOffset(GLenum type,
+                       const std::vector<unsigned int> &arraySizes,
+                       bool isRowMajorMatrix,
+                       int arrayStride,
+                       int matrixStride) override;
 
     HLSLBlockEncoderStrategy mEncoderStrategy;
     bool mTransposeMatrices;
 };
 
 // This method returns the number of used registers for a ShaderVariable. It is dependent on the
 // HLSLBlockEncoder class to count the number of used registers in a struct (which are individually
 // packed according to the same rules).
--- a/gfx/angle/src/compiler/translator/emulated_builtin_function_data_hlsl.json
+++ b/gfx/angle/src/compiler/translator/emulated_builtin_function_data_hlsl.json
@@ -1373,10 +1373,53 @@
          "uint4 x",
          "uint4 y",
          "out uint4 borrow"
       ],
       "body":[
          "borrow = uint4(x < y);",
          "return x - y;"
       ]
+   },
+   {
+      "comment":[
+         "We emulate tanh just to avoid overflow on large arguments."
+      ],
+      "op":"tanh",
+      "return_type":"float",
+      "args":[
+         "float x"
+      ],
+      "body":[
+         "return (abs(x) > 15.0) ? sign(x) : tanh(x);"
+      ]
+   },
+   {
+      "op":"tanh",
+      "return_type":"float2",
+      "args":[
+         "float2 x"
+      ],
+      "body":[
+         "return (abs(x) > 15.0) ? sign(x) : tanh(x);"
+      ]
+   },
+   {
+      "op":"tanh",
+      "return_type":"float3",
+      "args":[
+         "float3 x"
+      ],
+      "body":[
+         "return (abs(x) > 15.0) ? sign(x) : tanh(x);"
+      ]
+   },
+   {
+      "op":"tanh",
+      "return_type":"float4",
+      "args":[
+         "float4 x"
+      ],
+      "body":[
+         "return (abs(x) > 15.0) ? sign(x) : tanh(x);"
+      ]
    }
 ]
--- a/gfx/angle/src/compiler/translator/emulated_builtin_functions_hlsl_autogen.cpp
+++ b/gfx/angle/src/compiler/translator/emulated_builtin_functions_hlsl_autogen.cpp
@@ -835,16 +835,37 @@ constexpr FunctionPair g_hlslFunctions[]
      "    return x - y;\n"
      "}\n"},
     {{EOpUsubBorrow, ParamType::Uint4, ParamType::Uint4, ParamType::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},
+     "float tanh_emu(float x)\n"
+     "{\n"
+     "    return (abs(x) > 15.0) ? sign(x) : tanh(x);\n"
+     "}\n"},
+    {{EOpTanh, ParamType::Float2},
+     "float2 tanh_emu(float2 x)\n"
+     "{\n"
+     "    return (abs(x) > 15.0) ? sign(x) : tanh(x);\n"
+     "}\n"},
+    {{EOpTanh, ParamType::Float3},
+     "float3 tanh_emu(float3 x)\n"
+     "{\n"
+     "    return (abs(x) > 15.0) ? sign(x) : tanh(x);\n"
+     "}\n"},
+    {{EOpTanh, ParamType::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)
 {
     for (size_t index = 0; index < ArraySize(g_hlslFunctions); ++index)
     {
         const auto &function = g_hlslFunctions[index];
old mode 100644
new mode 100755
--- a/gfx/angle/src/compiler/translator/glslang.l
+++ b/gfx/angle/src/compiler/translator/glslang.l
@@ -434,24 +434,22 @@ yy_size_t string_input(char* buf, yy_siz
         YY_FATAL_ERROR("Input buffer overflow");
     else if (len > 0)
         buf[len++] = ' ';
     return len;
 }
 
 int check_type(yyscan_t yyscanner) {
     struct yyguts_t* yyg = (struct yyguts_t*) yyscanner;
-    
+
     int token = IDENTIFIER;
     TSymbol* symbol = yyextra->symbolTable.find(yytext, yyextra->getShaderVersion());
-    if (symbol && symbol->isVariable()) {
-        TVariable* variable = static_cast<TVariable*>(symbol);
-        if (variable->isUserType()) {
-            token = TYPE_NAME;
-        }
+    if (symbol && symbol->isStruct())
+    {
+        token = TYPE_NAME;
     }
     yylval->lex.symbol = symbol;
     return token;
 }
 
 int reserved_word(yyscan_t yyscanner) {
     struct yyguts_t* yyg = (struct yyguts_t*) yyscanner;
 
--- a/gfx/angle/src/compiler/translator/glslang.y
+++ b/gfx/angle/src/compiler/translator/glslang.y
@@ -34,17 +34,17 @@ WHICH GENERATES THE GLSL ES PARSER (glsl
 #pragma warning(disable: 4189)
 #pragma warning(disable: 4244)
 #pragma warning(disable: 4505)
 #pragma warning(disable: 4701)
 #pragma warning(disable: 4702)
 #endif
 
 #include "angle_gl.h"
-#include "compiler/translator/Cache.h"
+#include "compiler/translator/Declarator.h"
 #include "compiler/translator/SymbolTable.h"
 #include "compiler/translator/ParseContext.h"
 #include "GLSLANG/ShaderLang.h"
 
 #define YYENABLE_NLS 0
 
 using namespace sh;
 
@@ -81,24 +81,26 @@ using namespace sh;
             TIntermAggregate *intermAggregate;
             TIntermBlock *intermBlock;
             TIntermDeclaration *intermDeclaration;
             TIntermFunctionPrototype *intermFunctionPrototype;
             TIntermSwitch *intermSwitch;
             TIntermCase *intermCase;
         };
         union {
+            TVector<unsigned int> *arraySizes;
             TTypeSpecifierNonArray typeSpecifierNonArray;
             TPublicType type;
             TPrecision precision;
             TLayoutQualifier layoutQualifier;
             TQualifier qualifier;
             TFunction *function;
             TParameter param;
-            TField *field;
+            TDeclarator *declarator;
+            TDeclaratorList *declaratorList;
             TFieldList *fieldList;
             TQualifierWrapperBase *qualifierWrapper;
             TTypeQualifierBuilder *typeQualifierBuilder;
         };
     } interm;
 }
 
 %{
@@ -200,41 +202,45 @@ extern void yyerror(YYLTYPE* yylloc, TPa
 %type <interm.intermTypedNode> conditional_expression constant_expression
 %type <interm.intermTypedNode> logical_or_expression logical_xor_expression logical_and_expression
 %type <interm.intermTypedNode> shift_expression and_expression exclusive_or_expression inclusive_or_expression
 %type <interm.intermTypedNode> function_call initializer
 
 %type <interm.intermNode> condition conditionopt
 %type <interm.intermBlock> translation_unit
 %type <interm.intermNode> function_definition statement simple_statement
-%type <interm.intermBlock> statement_list compound_statement compound_statement_no_new_scope
+%type <interm.intermBlock> statement_list compound_statement_with_scope compound_statement_no_new_scope
 %type <interm.intermNode> declaration_statement selection_statement expression_statement
 %type <interm.intermNode> declaration external_declaration
 %type <interm.intermNode> for_init_statement
 %type <interm.nodePair> selection_rest_statement for_rest_statement
 %type <interm.intermSwitch> switch_statement
 %type <interm.intermCase> case_label
 %type <interm.intermNode> iteration_statement jump_statement statement_no_new_scope statement_with_scope
 %type <interm> single_declaration init_declarator_list
 
 %type <interm.param> parameter_declaration parameter_declarator parameter_type_specifier
 %type <interm.layoutQualifier> layout_qualifier_id_list layout_qualifier_id
 
+// Note: array_specifier guaranteed to be non-null.
+%type <interm.arraySizes> array_specifier
+
 %type <interm.type> fully_specified_type type_specifier
 
 %type <interm.precision> precision_qualifier
 %type <interm.layoutQualifier> layout_qualifier
 %type <interm.qualifier> interpolation_qualifier
 %type <interm.qualifierWrapper> storage_qualifier single_type_qualifier invariant_qualifier
 %type <interm.typeQualifierBuilder> type_qualifier
 
 %type <interm.typeSpecifierNonArray> type_specifier_nonarray struct_specifier
 %type <interm.type> type_specifier_no_prec
-%type <interm.field> struct_declarator
-%type <interm.fieldList> struct_declarator_list struct_declaration struct_declaration_list
+%type <interm.declarator> struct_declarator
+%type <interm.declaratorList> struct_declarator_list
+%type <interm.fieldList> struct_declaration struct_declaration_list
 %type <interm.function> function_header function_declarator function_identifier
 %type <interm.function> function_header_with_parameters function_call_header
 %type <interm> function_call_header_with_parameters function_call_header_no_parameters function_call_generic function_prototype
 %type <interm> function_call_or_method
 
 %type <lex> enter_struct
 
 %start translation_unit
@@ -274,17 +280,18 @@ primary_expression
         $$ = context->addScalarLiteral(unionArray, @1);
     }
     | BOOLCONSTANT {
         TConstantUnion *unionArray = new TConstantUnion[1];
         unionArray->setBConst($1.b);
         $$ = context->addScalarLiteral(unionArray, @1);
     }
     | YUVCSCSTANDARDEXTCONSTANT {
-        if (!context->isExtensionEnabled(TExtension::EXT_YUV_target)) {
+        if (!context->checkCanUseExtension(@1, TExtension::EXT_YUV_target))
+        {
            context->error(@1, "unsupported value", $1.string->c_str());
         }
         TConstantUnion *unionArray = new TConstantUnion[1];
         unionArray->setYuvCscStandardEXTConst(getYuvCscStandardEXT($1.string->c_str()));
         $$ = context->addScalarLiteral(unionArray, @1);
     }
     | LEFT_PAREN expression RIGHT_PAREN {
         $$ = $2;
@@ -676,18 +683,18 @@ function_header
     }
     ;
 
 parameter_declarator
     // Type + name
     : type_specifier identifier {
         $$ = context->parseParameterDeclarator($1, $2.string, @2);
     }
-    | type_specifier identifier LEFT_BRACKET constant_expression RIGHT_BRACKET {
-        $$ = context->parseParameterArrayDeclarator($2.string, @2, $4, @3, &$1);
+    | type_specifier identifier array_specifier {
+        $$ = context->parseParameterArrayDeclarator($2.string, @2, *($3), @3, &$1);
     }
     ;
 
 parameter_declaration
     : type_qualifier parameter_declarator {
         $$ = $2;
         context->checkIsParameterQualifierValid(@2, *$1, $2.type);
     }
@@ -715,58 +722,48 @@ parameter_type_specifier
 init_declarator_list
     : single_declaration {
         $$ = $1;
     }
     | init_declarator_list COMMA identifier {
         $$ = $1;
         context->parseDeclarator($$.type, @3, *$3.string, $$.intermDeclaration);
     }
-    | init_declarator_list COMMA identifier LEFT_BRACKET constant_expression RIGHT_BRACKET {
-        $$ = $1;
-        context->parseArrayDeclarator($$.type, @3, *$3.string, @4, $5, $$.intermDeclaration);
-    }
-    | init_declarator_list COMMA identifier LEFT_BRACKET RIGHT_BRACKET EQUAL initializer {
-        ES3_OR_NEWER("[]", @3, "implicitly sized array");
+    | init_declarator_list COMMA identifier array_specifier {
         $$ = $1;
-        context->parseArrayInitDeclarator($$.type, @3, *$3.string, @4, nullptr, @6, $7, $$.intermDeclaration);
+        context->parseArrayDeclarator($$.type, @3, *$3.string, @4, *($4), $$.intermDeclaration);
     }
-    | init_declarator_list COMMA identifier LEFT_BRACKET constant_expression RIGHT_BRACKET EQUAL initializer {
-        ES3_OR_NEWER("=", @7, "first-class arrays (array initializer)");
+    | init_declarator_list COMMA identifier array_specifier EQUAL initializer {
+        ES3_OR_NEWER("=", @5, "first-class arrays (array initializer)");
         $$ = $1;
-        context->parseArrayInitDeclarator($$.type, @3, *$3.string, @4, $5, @7, $8, $$.intermDeclaration);
+        context->parseArrayInitDeclarator($$.type, @3, *$3.string, @4, *($4), @5, $6, $$.intermDeclaration);
     }
     | init_declarator_list COMMA identifier EQUAL initializer {
         $$ = $1;
         context->parseInitDeclarator($$.type, @3, *$3.string, @4, $5, $$.intermDeclaration);
     }
     ;
 
 single_declaration
     : fully_specified_type {
         $$.type = $1;
         $$.intermDeclaration = context->parseSingleDeclaration($$.type, @1, "");
     }
     | fully_specified_type identifier {
         $$.type = $1;
         $$.intermDeclaration = context->parseSingleDeclaration($$.type, @2, *$2.string);
     }
-    | fully_specified_type identifier LEFT_BRACKET constant_expression RIGHT_BRACKET {
-        $$.type = $1;
-        $$.intermDeclaration = context->parseSingleArrayDeclaration($$.type, @2, *$2.string, @3, $4);
-    }
-    | fully_specified_type identifier LEFT_BRACKET RIGHT_BRACKET EQUAL initializer {
-        ES3_OR_NEWER("[]", @3, "implicitly sized array");
+    | fully_specified_type identifier array_specifier {
         $$.type = $1;
-        $$.intermDeclaration = context->parseSingleArrayInitDeclaration($$.type, @2, *$2.string, @3, nullptr, @5, $6);
+        $$.intermDeclaration = context->parseSingleArrayDeclaration($$.type, @2, *$2.string, @3, *($3));
     }
-    | fully_specified_type identifier LEFT_BRACKET constant_expression RIGHT_BRACKET EQUAL initializer {
-        ES3_OR_NEWER("=", @6, "first-class arrays (array initializer)");
+    | fully_specified_type identifier array_specifier EQUAL initializer {
+        ES3_OR_NEWER("[]", @3, "first-class arrays (array initializer)");
         $$.type = $1;
-        $$.intermDeclaration = context->parseSingleArrayInitDeclaration($$.type, @2, *$2.string, @3, $4, @6, $7);
+        $$.intermDeclaration = context->parseSingleArrayInitDeclaration($$.type, @2, *$2.string, @3, *($3), @4, $5);
     }
     | fully_specified_type identifier EQUAL initializer {
         $$.type = $1;
         $$.intermDeclaration = context->parseSingleInitDeclaration($$.type, @2, *$2.string, @3, $4);
     }
     ;
 
 fully_specified_type
@@ -931,25 +928,47 @@ layout_qualifier_id
         $$ = context->parseLayoutQualifier("shared", @1);
     }
     ;
 
 type_specifier_no_prec
     : type_specifier_nonarray {
         $$.initialize($1, (context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary));
     }
-    | type_specifier_nonarray LEFT_BRACKET RIGHT_BRACKET {
-        ES3_OR_NEWER("[]", @2, "implicitly sized array");
+    | type_specifier_nonarray array_specifier {
         $$.initialize($1, (context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary));
-        $$.setArraySize(0);
+        $$.setArraySizes($2);
+    }
+    ;
+
+array_specifier
+    : LEFT_BRACKET RIGHT_BRACKET {
+        ES3_OR_NEWER("[]", @1, "implicitly sized array");
+        $$ = new TVector<unsigned int>();
+        $$->push_back(0u);
     }
-    | type_specifier_nonarray LEFT_BRACKET constant_expression RIGHT_BRACKET {
-        $$.initialize($1, (context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary));
+    | LEFT_BRACKET constant_expression RIGHT_BRACKET {
+        $$ = new TVector<unsigned int>();
+        unsigned int size = context->checkIsValidArraySize(@1, $2);
+        // Make the type an array even if size check failed.
+        // This ensures useless error messages regarding a variable's non-arrayness won't follow.
+        $$->push_back(size);
+    }
+    | array_specifier LEFT_BRACKET RIGHT_BRACKET {
+        ES3_1_ONLY("[]", @2, "arrays of arrays");
+        $$ = $1;
+        $$->insert($$->begin(), 0u);
+    }
+    | array_specifier LEFT_BRACKET constant_expression RIGHT_BRACKET {
+        ES3_1_ONLY("[]", @2, "arrays of arrays");
+        $$ = $1;
         unsigned int size = context->checkIsValidArraySize(@2, $3);
-        $$.setArraySize(size);
+        // Make the type an array even if size check failed.
+        // This ensures useless error messages regarding a variable's non-arrayness won't follow.
+        $$->insert($$->begin(), size);
     }
     ;
 
 type_specifier_nonarray
     : VOID_TYPE {
         $$.initialize(EbtVoid, @1);
     }
     | FLOAT_TYPE {
@@ -1044,17 +1063,18 @@ type_specifier_nonarray
         $$.initialize(EbtFloat, @1);
         $$.setMatrix(3, 4);
     }
     | MATRIX4x3 {
         $$.initialize(EbtFloat, @1);
         $$.setMatrix(4, 3);
     }
     | YUVCSCSTANDARDEXT {
-        if (!context->isExtensionEnabled(TExtension::EXT_YUV_target)) {
+        if (!context->checkCanUseExtension(@1, TExtension::EXT_YUV_target))
+        {
             context->error(@1, "unsupported type", "yuvCscStandardEXT");
         }
         $$.initialize(EbtYuvCscStandardEXT, @1);
     }
     | SAMPLER2D {
         $$.initialize(EbtSampler2D, @1);
     }
     | SAMPLER3D {
@@ -1104,37 +1124,39 @@ type_specifier_nonarray
     }
     | SAMPLERCUBESHADOW {
         $$.initialize(EbtSamplerCubeShadow, @1);
     }
     | SAMPLER2DARRAYSHADOW {
         $$.initialize(EbtSampler2DArrayShadow, @1);
     }
     | SAMPLER_EXTERNAL_OES {
-        if (!context->supportsExtension(TExtension::OES_EGL_image_external) &&
-            !context->supportsExtension(TExtension::NV_EGL_stream_consumer_external)) {
+        constexpr std::array<TExtension, 3u> extensions{ { TExtension::NV_EGL_stream_consumer_external,
+                                                           TExtension::OES_EGL_image_external_essl3,
+                                                           TExtension::OES_EGL_image_external } };
+        if (!context->checkCanUseOneOfExtensions(@1, extensions))
+        {
             context->error(@1, "unsupported type", "samplerExternalOES");
         }
         $$.initialize(EbtSamplerExternalOES, @1);
     }
     | SAMPLEREXTERNAL2DY2YEXT {
-        if (!context->isExtensionEnabled(TExtension::EXT_YUV_target)) {
+        if (!context->checkCanUseExtension(@1, TExtension::EXT_YUV_target))
+        {
             context->error(@1, "unsupported type", "__samplerExternal2DY2YEXT");
         }
         $$.initialize(EbtSamplerExternal2DY2YEXT, @1);
     }
     | SAMPLER2DRECT {
-        if (!context->supportsExtension(TExtension::ARB_texture_rectangle)) {
+        if (!context->checkCanUseExtension(@1, TExtension::ARB_texture_rectangle))
+        {
             context->error(@1, "unsupported type", "sampler2DRect");
         }
         $$.initialize(EbtSampler2DRect, @1);
     }
-    | struct_specifier {
-        $$ = $1;
-    }
     | IMAGE2D {
         $$.initialize(EbtImage2D, @1);
     }
     | IIMAGE2D {
         $$.initialize(EbtIImage2D, @1);
     }
     | UIMAGE2D {
         $$.initialize(EbtUImage2D, @1);
@@ -1164,35 +1186,38 @@ type_specifier_nonarray
         $$.initialize(EbtIImageCube, @1);
     }
     | UIMAGECUBE {
         $$.initialize(EbtUImageCube, @1);
     }
     | ATOMICUINT {
         $$.initialize(EbtAtomicCounter, @1);
     }
+    | struct_specifier {
+        $$ = $1;
+    }
     | TYPE_NAME {
         // This is for user defined type names. The lexical phase looked up the type.
-        TType& structure = static_cast<TVariable*>($1.symbol)->getType();
-        $$.initializeStruct(structure.getStruct(), false, @1);
+        TStructure *structure = static_cast<TStructure*>($1.symbol);
+        $$.initializeStruct(structure, false, @1);
     }
     ;
 
 struct_specifier
     : STRUCT identifier LEFT_BRACE { context->enterStructDeclaration(@2, *$2.string); } struct_declaration_list RIGHT_BRACE {
         $$ = context->addStructure(@1, @2, $2.string, $5);
     }
     | STRUCT LEFT_BRACE { context->enterStructDeclaration(@2, *$2.string); } struct_declaration_list RIGHT_BRACE {
-        $$ = context->addStructure(@1, @$, NewPoolTString(""), $4);
+        $$ = context->addStructure(@1, @$, nullptr, $4);
     }
     ;
 
 struct_declaration_list
     : struct_declaration {
-        $$ = $1;
+        $$ = context->addStructFieldList($1, @1);
     }
     | struct_declaration_list struct_declaration {
         $$ = context->combineStructFieldLists($1, $2, @2);
     }
     ;
 
 struct_declaration
     : type_specifier struct_declarator_list SEMICOLON {
@@ -1201,60 +1226,63 @@ struct_declaration
     | type_qualifier type_specifier struct_declarator_list SEMICOLON {
         // ES3 Only, but errors should be handled elsewhere
         $$ = context->addStructDeclaratorListWithQualifiers(*$1, &$2, $3);
     }
     ;
 
 struct_declarator_list
     : struct_declarator {
-        $$ = NewPoolTFieldList();
+        $$ = new TDeclaratorList();
         $$->push_back($1);
     }
     | struct_declarator_list COMMA struct_declarator {
         $$->push_back($3);
     }
     ;
 
 struct_declarator
     : identifier {
         $$ = context->parseStructDeclarator($1.string, @1);
     }
-    | identifier LEFT_BRACKET constant_expression RIGHT_BRACKET {
-        $$ = context->parseStructArrayDeclarator($1.string, @1, $3, @3);
+    | identifier array_specifier {
+        $$ = context->parseStructArrayDeclarator($1.string, @1, $2);
     }
     ;
 
 initializer
     : assignment_expression { $$ = $1; }
     ;
 
 declaration_statement
     : declaration { $$ = $1; }
     ;
 
 statement
-    : compound_statement  { $$ = $1; }
-    | simple_statement    { $$ = $1; }
+    : compound_statement_with_scope { $$ = $1; }
+    | simple_statement              { $$ = $1; }
     ;
 
 // Grammar Note:  Labeled statements for SWITCH only; 'goto' is not supported.
 
 simple_statement
     : declaration_statement { $$ = $1; }
     | expression_statement  { $$ = $1; }
     | selection_statement   { $$ = $1; }
     | switch_statement      { $$ = $1; }
     | case_label            { $$ = $1; }
     | iteration_statement   { $$ = $1; }
     | jump_statement        { $$ = $1; }
     ;
 
-compound_statement
-    : LEFT_BRACE RIGHT_BRACE { $$ = 0; }
+compound_statement_with_scope
+    : LEFT_BRACE RIGHT_BRACE {
+        $$ = new TIntermBlock();
+        $$->setLine(@$);
+    }
     | LEFT_BRACE { context->symbolTable.push(); } statement_list { context->symbolTable.pop(); } RIGHT_BRACE {
         $3->setLine(@$);
         $$ = $3;
     }
     ;
 
 statement_no_new_scope
     : compound_statement_no_new_scope { $$ = $1; }
@@ -1262,19 +1290,20 @@ statement_no_new_scope
     ;
 
 statement_with_scope
     : { context->symbolTable.push(); } compound_statement_no_new_scope { context->symbolTable.pop(); $$ = $2; }
     | { context->symbolTable.push(); } simple_statement                { context->symbolTable.pop(); $$ = $2; }
     ;
 
 compound_statement_no_new_scope
-    // Statement that doesn't create a new scope, for selection_statement, iteration_statement
+    // Statement that doesn't create a new scope for iteration_statement, function definition (scope is created for parameters)
     : LEFT_BRACE RIGHT_BRACE {
-        $$ = nullptr;
+        $$ = new TIntermBlock();
+        $$->setLine(@$);
     }
     | LEFT_BRACE statement_list RIGHT_BRACE {
         $2->setLine(@$);
         $$ = $2;
     }
     ;
 
 statement_list
@@ -1284,17 +1313,17 @@ statement_list
     }
     | statement_list statement {
         $$ = $1;
         $$->appendStatement($2);
     }
     ;
 
 expression_statement
-    : SEMICOLON  { $$ = 0; }
+    : SEMICOLON  { $$ = context->addEmptyStatement(@$); }
     | expression SEMICOLON  { $$ = $1; }
     ;
 
 selection_statement
     : IF LEFT_PAREN expression RIGHT_PAREN selection_rest_statement {
         $$ = context->addIfElse($3, $5, @1);
     }
     ;
@@ -1305,18 +1334,20 @@ selection_rest_statement
         $$.node2 = $3;
     }
     | statement_with_scope {
         $$.node1 = $1;
         $$.node2 = nullptr;
     }
     ;
 
+// Note that we've diverged from the spec grammar here a bit for the sake of simplicity.
+// We're reusing compound_statement_with_scope instead of having separate rules for switch.
 switch_statement
-    : SWITCH LEFT_PAREN expression RIGHT_PAREN { context->incrSwitchNestingLevel(); } compound_statement {
+    : SWITCH LEFT_PAREN expression RIGHT_PAREN { context->incrSwitchNestingLevel(); } compound_statement_with_scope {
         $$ = context->addSwitch($3, $6, @1);
         context->decrSwitchNestingLevel();
     }
     ;
 
 case_label
     : CASE constant_expression COLON {
         $$ = context->addCase($2, @1);
--- a/gfx/angle/src/compiler/translator/glslang_lex.cpp
+++ b/gfx/angle/src/compiler/translator/glslang_lex.cpp
@@ -3790,24 +3790,22 @@ yy_size_t string_input(char* buf, yy_siz
         YY_FATAL_ERROR("Input buffer overflow");
     else if (len > 0)
         buf[len++] = ' ';
     return len;
 }
 
 int check_type(yyscan_t yyscanner) {
     struct yyguts_t* yyg = (struct yyguts_t*) yyscanner;
-    
+
     int token = IDENTIFIER;
     TSymbol* symbol = yyextra->symbolTable.find(yytext, yyextra->getShaderVersion());
-    if (symbol && symbol->isVariable()) {
-        TVariable* variable = static_cast<TVariable*>(symbol);
-        if (variable->isUserType()) {
-            token = TYPE_NAME;
-        }
+    if (symbol && symbol->isStruct())
+    {
+        token = TYPE_NAME;
     }
     yylval->lex.symbol = symbol;
     return token;
 }
 
 int reserved_word(yyscan_t yyscanner) {
     struct yyguts_t* yyg = (struct yyguts_t*) yyscanner;
 
--- a/gfx/angle/src/compiler/translator/glslang_tab.cpp
+++ b/gfx/angle/src/compiler/translator/glslang_tab.cpp
@@ -84,17 +84,17 @@
 #pragma warning(disable: 4189)
 #pragma warning(disable: 4244)
 #pragma warning(disable: 4505)
 #pragma warning(disable: 4701)
 #pragma warning(disable: 4702)
 #endif
 
 #include "angle_gl.h"
-#include "compiler/translator/Cache.h"
+#include "compiler/translator/Declarator.h"
 #include "compiler/translator/SymbolTable.h"
 #include "compiler/translator/ParseContext.h"
 #include "GLSLANG/ShaderLang.h"
 
 #define YYENABLE_NLS 0
 
 using namespace sh;
 
@@ -322,24 +322,26 @@ union YYSTYPE
             TIntermAggregate *intermAggregate;
             TIntermBlock *intermBlock;
             TIntermDeclaration *intermDeclaration;
             TIntermFunctionPrototype *intermFunctionPrototype;
             TIntermSwitch *intermSwitch;
             TIntermCase *intermCase;
         };
         union {
+            TVector<unsigned int> *arraySizes;
             TTypeSpecifierNonArray typeSpecifierNonArray;
             TPublicType type;
             TPrecision precision;
             TLayoutQualifier layoutQualifier;
             TQualifier qualifier;
             TFunction *function;
             TParameter param;
-            TField *field;
+            TDeclarator *declarator;
+            TDeclaratorList *declaratorList;
             TFieldList *fieldList;
             TQualifierWrapperBase *qualifierWrapper;
             TTypeQualifierBuilder *typeQualifierBuilder;
         };
     } interm;
 
 
 };
@@ -664,28 +666,28 @@ union yyalloc
             (Dst)[yyi] = (Src)[yyi];            \
         }                                       \
       while (0)
 #  endif
 # endif
 #endif /* !YYCOPY_NEEDED */
 
 /* YYFINAL -- State number of the termination state.  */
-#define YYFINAL  134
+#define YYFINAL  135
 /* YYLAST -- Last index in YYTABLE.  */
-#define YYLAST   3031
+#define YYLAST   2897
 
 /* YYNTOKENS -- Number of terminals.  */
 #define YYNTOKENS  154
 /* YYNNTS -- Number of nonterminals.  */
-#define YYNNTS  94
+#define YYNNTS  95
 /* YYNRULES -- Number of rules.  */
-#define YYNRULES  296
+#define YYNRULES  297
 /* YYNSTATES -- Number of states.  */
-#define YYNSTATES  432
+#define YYNSTATES  423
 
 /* YYTRANSLATE[YYX] -- Symbol number corresponding to YYX as returned
    by yylex, with out-of-bounds checking.  */
 #define YYUNDEFTOK  2
 #define YYMAXUTOK   408
 
 #define YYTRANSLATE(YYX)                                                \
   ((unsigned int) (YYX) <= YYMAXUTOK ? yytranslate[YYX] : YYUNDEFTOK)
@@ -736,46 +738,46 @@ static const yytype_uint8 yytranslate[] 
      135,   136,   137,   138,   139,   140,   141,   142,   143,   144,
      145,   146,   147,   148,   149,   150,   151,   152,   153
 };
 
 #if YYDEBUG
   /* YYRLINE[YYN] -- Source line where rule number YYN was defined.  */
 static const yytype_uint16 yyrline[] =
 {
-       0,   244,   244,   245,   248,   258,   261,   266,   271,   276,
-     281,   289,   295,   298,   301,   304,   307,   310,   316,   323,
-     329,   333,   341,   344,   350,   354,   361,   366,   373,   381,
-     384,   387,   393,   396,   399,   402,   409,   410,   411,   412,
-     420,   421,   424,   427,   434,   435,   438,   444,   445,   449,
-     456,   457,   460,   463,   466,   472,   473,   476,   482,   483,
-     490,   491,   498,   499,   506,   507,   513,   514,   520,   521,
-     527,   528,   534,   535,   541,   542,   543,   544,   548,   549,
-     550,   554,   558,   562,   566,   573,   576,   582,   589,   596,
-     599,   602,   606,   610,   614,   618,   622,   629,   636,   639,
-     646,   654,   671,   681,   684,   690,   694,   698,   702,   709,
-     716,   719,   723,   727,   732,   737,   744,   748,   752,   756,
-     761,   766,   773,   777,   783,   786,   792,   796,   803,   809,
-     813,   817,   820,   823,   832,   837,   841,   844,   847,   850,
-     853,   857,   860,   864,   867,   870,   873,   876,   879,   886,
-     893,   896,   899,   905,   912,   915,   921,   924,   927,   930,
-     936,   939,   944,   952,   955,   958,   961,   964,   967,   971,
-     975,   979,   983,   987,   991,   995,   999,  1003,  1007,  1011,
-    1015,  1019,  1023,  1027,  1031,  1035,  1039,  1043,  1047,  1051,
-    1057,  1060,  1063,  1066,  1069,  1072,  1075,  1078,  1081,  1084,
-    1087,  1090,  1093,  1096,  1099,  1102,  1105,  1108,  1111,  1118,
-    1124,  1130,  1133,  1136,  1139,  1142,  1145,  1148,  1151,  1154,
-    1157,  1160,  1163,  1166,  1169,  1172,  1180,  1180,  1183,  1183,
-    1189,  1192,  1198,  1201,  1208,  1212,  1218,  1221,  1227,  1231,
-    1235,  1236,  1242,  1243,  1244,  1245,  1246,  1247,  1248,  1252,
-    1253,  1253,  1253,  1260,  1261,  1265,  1265,  1266,  1266,  1271,
-    1274,  1281,  1285,  1292,  1293,  1297,  1303,  1307,  1314,  1314,
-    1321,  1324,  1330,  1334,  1340,  1340,  1345,  1345,  1349,  1349,
-    1357,  1360,  1366,  1369,  1375,  1379,  1386,  1389,  1392,  1395,
-    1398,  1406,  1412,  1418,  1421,  1427,  1427
+       0,   251,   251,   252,   255,   265,   268,   273,   278,   283,
+     288,   297,   303,   306,   309,   312,   315,   318,   324,   331,
+     337,   341,   349,   352,   358,   362,   369,   374,   381,   389,
+     392,   395,   401,   404,   407,   410,   417,   418,   419,   420,
+     428,   429,   432,   435,   442,   443,   446,   452,   453,   457,
+     464,   465,   468,   471,   474,   480,   481,   484,   490,   491,
+     498,   499,   506,   507,   514,   515,   521,   522,   528,   529,
+     535,   536,   542,   543,   549,   550,   551,   552,   556,   557,
+     558,   562,   566,   570,   574,   581,   584,   590,   597,   604,
+     607,   610,   614,   618,   622,   626,   630,   637,   644,   647,
+     654,   662,   679,   689,   692,   698,   702,   706,   710,   717,
+     724,   727,   731,   735,   740,   747,   751,   755,   759,   764,
+     771,   775,   781,   784,   790,   794,   801,   807,   811,   815,
+     818,   821,   830,   835,   839,   842,   845,   848,   851,   855,
+     858,   862,   865,   868,   871,   874,   877,   884,   891,   894,
+     897,   903,   910,   913,   919,   922,   925,   928,   934,   937,
+     944,   949,   956,   961,   972,   975,   978,   981,   984,   987,
+     991,   995,   999,  1003,  1007,  1011,  1015,  1019,  1023,  1027,
+    1031,  1035,  1039,  1043,  1047,  1051,  1055,  1059,  1063,  1067,
+    1071,  1078,  1081,  1084,  1087,  1090,  1093,  1096,  1099,  1102,
+    1105,  1108,  1111,  1114,  1117,  1120,  1123,  1126,  1129,  1132,
+    1142,  1149,  1156,  1159,  1162,  1165,  1168,  1171,  1174,  1177,
+    1180,  1183,  1186,  1189,  1192,  1195,  1198,  1206,  1206,  1209,
+    1209,  1215,  1218,  1224,  1227,  1234,  1238,  1244,  1247,  1253,
+    1257,  1261,  1262,  1268,  1269,  1270,  1271,  1272,  1273,  1274,
+    1278,  1282,  1282,  1282,  1289,  1290,  1294,  1294,  1295,  1295,
+    1300,  1304,  1311,  1315,  1322,  1323,  1327,  1333,  1337,  1346,
+    1346,  1353,  1356,  1362,  1366,  1372,  1372,  1377,  1377,  1381,
+    1381,  1389,  1392,  1398,  1401,  1407,  1411,  1418,  1421,  1424,
+    1427,  1430,  1438,  1444,  1450,  1453,  1459,  1459
 };
 #endif
 
 #if YYDEBUG || YYERROR_VERBOSE || 0
 /* YYTNAME[SYMBOL-NUM] -- String name of the symbol SYMBOL-NUM.
    First, the terminals, then, starting at YYNTOKENS, nonterminals.  */
 static const char *const yytname[] =
 {
@@ -823,21 +825,21 @@ static const char *const yytname[] =
   "function_prototype", "function_declarator",
   "function_header_with_parameters", "function_header",
   "parameter_declarator", "parameter_declaration",
   "parameter_type_specifier", "init_declarator_list", "single_declaration",
   "fully_specified_type", "interpolation_qualifier", "type_qualifier",
   "invariant_qualifier", "single_type_qualifier", "storage_qualifier",
   "type_specifier", "precision_qualifier", "layout_qualifier",
   "layout_qualifier_id_list", "layout_qualifier_id",
-  "type_specifier_no_prec", "type_specifier_nonarray", "struct_specifier",
-  "$@1", "$@2", "struct_declaration_list", "struct_declaration",
-  "struct_declarator_list", "struct_declarator", "initializer",
-  "declaration_statement", "statement", "simple_statement",
-  "compound_statement", "$@3", "$@4", "statement_no_new_scope",
+  "type_specifier_no_prec", "array_specifier", "type_specifier_nonarray",
+  "struct_specifier", "$@1", "$@2", "struct_declaration_list",
+  "struct_declaration", "struct_declarator_list", "struct_declarator",
+  "initializer", "declaration_statement", "statement", "simple_statement",
+  "compound_statement_with_scope", "$@3", "$@4", "statement_no_new_scope",
   "statement_with_scope", "$@5", "$@6", "compound_statement_no_new_scope",
   "statement_list", "expression_statement", "selection_statement",
   "selection_rest_statement", "switch_statement", "$@7", "case_label",
   "condition", "iteration_statement", "$@8", "$@9", "$@10",
   "for_init_statement", "conditionopt", "for_rest_statement",
   "jump_statement", "translation_unit", "external_declaration",
   "function_definition", "$@11", YY_NULLPTR
 };
@@ -862,514 +864,497 @@ static const yytype_uint16 yytoknum[] =
      365,   366,   367,   368,   369,   370,   371,   372,   373,   374,
      375,   376,   377,   378,   379,   380,   381,   382,   383,   384,
      385,   386,   387,   388,   389,   390,   391,   392,   393,   394,
      395,   396,   397,   398,   399,   400,   401,   402,   403,   404,
      405,   406,   407,   408
 };
 # endif
 
-#define YYPACT_NINF -369
+#define YYPACT_NINF -366
 
 #define yypact_value_is_default(Yystate) \
-  (!!((Yystate) == (-369)))
-
-#define YYTABLE_NINF -256
+  (!!((Yystate) == (-366)))
+
+#define YYTABLE_NINF -257
 
 #define yytable_value_is_error(Yytable_value) \
   0
 
   /* YYPACT[STATE-NUM] -- Index in YYTABLE of the portion describing
      STATE-NUM.  */
 static const yytype_int16 yypact[] =
 {
-    2639,  -369,  -369,  -369,  -369,    80,  -369,  -369,  -369,  -369,
-    -369,  -369,  -369,  -369,  -369,  -369,  -369,  -369,  -369,  -369,
-    -369,  -369,  -369,  -369,  -369,  -369,  -369,  -369,  -369,  -369,
-    -369,  -369,  -369,  -369,  -369,  -369,  -369,  -369,  -369,  -369,
-    -369,  -369,  -369,  -369,  -369,  -369,  -369,  -369,   -75,  -369,
-    -369,  -369,  -369,  -369,  -369,  -369,  -369,  -369,  -369,  -369,
-    -369,  -369,  -369,  -369,  -369,  -369,  -369,  -369,  -369,  -369,
-    -369,  -369,  -369,  -369,  -369,  -369,  -369,  -369,  -369,  -369,
-    -369,  -369,  -369,  -369,  -109,  -369,  -369,  -369,  -105,   -79,
-     -66,  2740,   -73,  -369,    -8,  -369,  1373,  -369,  -369,  -369,
-    -369,  -369,  -369,  -369,   -27,  -369,  2538,  -369,  -369,  2928,
-    -369,  -369,  -369,   -31,   -45,  -369,   -18,  -369,  2740,  -369,
-    -369,  -369,  2740,     8,     8,  -369,    -1,   -93,  -100,  -369,
-    2740,  -369,  -369,  1468,  -369,  -369,   -96,  2740,  -369,  -369,
-       1,   -59,  -369,   417,  -369,  -369,  -369,  -369,    10,   -76,
-    -369,  1592,  1961,  -369,  -369,  2740,     8,  2205,  -369,  -369,
-       3,  -369,  -369,  -369,  -369,  -369,  1961,  1961,  1961,  -369,
-    -369,  -369,  -369,  -369,  -369,  -369,   -74,  -369,  -369,  -369,
-      23,   -57,  2082,    26,  -369,  1961,    24,   -52,    36,   -88,
-      33,     6,    30,    34,    57,    69,   -99,  -369,    56,  -369,
-    -369,  2316,  2740,    46,  -369,   -45,    50,    51,  -369,    64,
-      65,    59,  1716,    66,  1961,    67,    73,    72,  -369,  -369,
-      39,  -369,  -369,   -33,  -369,  -105,    78,  -369,  -369,  -369,
-    -369,   559,  -369,  -369,  -369,  -369,  -369,  -369,  1961,  1837,
-    1961,    70,    77,  -369,  -369,     8,    79,    -6,  -369,   -85,
-    -369,  -369,  -369,   -50,  -369,  -369,  1961,  2834,  -369,  -369,
-    1961,    81,  -369,  -369,  -369,  1961,  1961,  1961,  1961,  1961,
-    1961,  1961,  1961,  1961,  1961,  1961,  1961,  1961,  1961,  1961,
-    1961,  1961,  1961,  1961,  1961,  -369,  -369,  2427,  -369,  -369,
-    -369,  -369,  -369,    82,  -369,  1961,  -369,  -369,    -2,  1961,
-      76,  -369,  -369,  -369,   701,  -369,  -369,  -369,  -369,  -369,
-    -369,  -369,  -369,  -369,  -369,  -369,  1961,  1961,  -369,  -369,
-    -369,    84,    83,    85,  -369,  1961,    86,     4,  1961,     8,
-    -369,  -110,  -369,  -369,    88,    87,  -369,    93,  -369,  -369,
-    -369,  -369,  -369,    24,    24,   -52,   -52,    36,    36,    36,
-      36,   -88,   -88,    33,     6,    30,    34,    57,    69,    35,
-    -369,   152,   -18,   985,  1127,   -49,  -369,   -48,  -369,  1250,
-     701,  -369,  -369,  -369,  1961,    89,  -369,  1961,  -369,    96,
-    -369,  1961,  -369,  -369,  1961,   100,  -369,  -369,  -369,  -369,
-    1250,    82,  -369,    87,     8,  2740,    95,    97,  -369,  1961,
-    -369,  -369,   102,  -369,  1961,  -369,    99,   105,   216,  -369,
-     108,   104,   843,  -369,  -369,   106,   -29,  1961,   843,    82,
-    -369,  1961,  -369,  -369,  -369,  -369,   107,    87,  -369,  -369,
-    -369,  -369
+    2505,  -366,  -366,  -366,  -366,   144,  -366,  -366,  -366,  -366,
+    -366,  -366,  -366,  -366,  -366,  -366,  -366,  -366,  -366,  -366,
+    -366,  -366,  -366,  -366,  -366,  -366,  -366,  -366,  -366,  -366,
+    -366,  -366,  -366,  -366,  -366,  -366,  -366,  -366,  -366,  -366,
+    -366,  -366,  -366,  -366,  -366,  -366,  -366,  -366,   -68,  -366,
+    -366,  -366,  -366,  -366,  -366,  -366,  -366,  -366,  -366,  -366,
+    -366,  -366,  -366,  -366,  -366,  -366,  -366,  -366,  -366,  -366,
+    -366,  -366,  -366,  -366,  -366,  -366,  -366,  -366,  -366,  -366,
+    -366,  -366,  -366,  -366,   -99,  -366,  -366,  -366,   -97,   -85,
+     -87,  2606,   -45,  -366,   -32,  -366,  1363,  -366,  -366,  -366,
+    -366,  -366,  -366,  -366,   -42,  -366,  2404,  -366,  -366,  2794,
+    -366,  -366,  -366,   -40,   -41,  -366,   -31,  -366,  2606,  -366,
+    -366,  -366,  2606,   -18,   -18,  -366,   -10,  -107,   -51,  -366,
+    2606,  -366,  -366,  1458,   -20,  -366,  -366,   -13,  2606,  -366,
+    -366,   -91,   -50,  -366,   407,  -366,  -366,  -366,  -366,   -42,
+     -67,  -366,  1827,   -64,  -366,  -366,  2606,   -18,  2071,  -366,
+    -366,    16,  -366,  -366,  -366,  -366,  -366,  1827,  1827,  1827,
+    -366,  -366,  -366,  -366,  -366,  -366,  -366,   -58,  -366,  -366,
+    -366,    57,   -38,  1948,    24,  -366,  1827,     6,    13,    60,
+     -86,    58,    25,    38,    45,    79,    78,   -94,  -366,    65,
+    -366,  1582,  -366,  2182,  2606,    74,  -366,   -41,    59,    62,
+    -366,    70,    76,    67,  1706,    80,  1827,    71,    81,    73,
+    -366,  -366,    39,  -366,  -366,   -21,  -366,   -97,    84,  -366,
+    -366,  -366,  -366,   549,  -366,  -366,  -366,  -366,  -366,  -366,
+     -20,  1827,   -53,  -366,  -366,  1827,   -18,   -42,   -16,  -366,
+     -82,  -366,  -366,  -366,   -29,  -366,  -366,  1827,  2700,  -366,
+    -366,  1827,    85,  -366,  -366,  -366,  1827,  1827,  1827,  1827,
+    1827,  1827,  1827,  1827,  1827,  1827,  1827,  1827,  1827,  1827,
+    1827,  1827,  1827,  1827,  1827,  1827,  -366,  -366,    82,  -366,
+    2293,  -366,  -366,  -366,  -366,  -366,    83,  -366,  1827,  -366,
+    -366,    -1,  1827,    86,  -366,  -366,  -366,   691,  -366,  -366,
+    -366,  -366,  -366,  -366,  -366,  -366,  -366,  -366,  -366,  1827,
+    1827,  -366,  -366,  -366,  -366,  1827,  -366,     3,   -20,   -18,
+    -366,   -96,  -366,  -366,    88,    89,  -366,    92,  -366,  -366,
+    -366,  -366,  -366,     6,     6,    13,    13,    60,    60,    60,
+      60,   -86,   -86,    58,    25,    38,    45,    79,    78,    46,
+    -366,  -366,   155,   -31,   975,  1117,   -27,  -366,   -26,  -366,
+    1240,   691,  -366,  -366,  -366,  -366,  -366,  1827,  -366,  -366,
+    1827,    93,  -366,  -366,  -366,  -366,  1240,    83,  -366,    89,
+     -18,  2606,    94,    95,    98,  -366,  1827,  -366,    87,    97,
+     202,  -366,   100,    96,   833,  -366,   101,   -24,  1827,   833,
+      83,  -366,  1827,  -366,  -366,  -366,  -366,   102,    89,  -366,
+    -366,  -366,  -366
 };
 
   /* YYDEFACT[STATE-NUM] -- Default reduction number in state STATE-NUM.
      Performed when YYTABLE does not specify something else to do.  Zero
      means the default is an error.  */
 static const yytype_uint16 yydefact[] =
 {
-       0,   128,   150,   151,   152,     0,   134,   136,   167,   164,
-     165,   166,   171,   172,   173,   174,   175,   176,   168,   169,
-     170,   177,   178,   179,   180,   181,   182,   137,   138,   139,
-     141,   142,   135,   183,   184,   185,   186,   187,   188,   140,
-     125,   124,   143,   144,   145,   146,   147,   148,     0,   163,
-     190,   192,   208,   210,   193,   195,   196,   197,   198,   200,
-     201,   202,   203,   194,   199,   204,   191,   205,   206,   207,
-     209,   212,   213,   214,   215,   216,   217,   218,   219,   220,
-     221,   222,   223,   224,     0,   189,   225,   294,   295,     0,
-      99,    98,     0,   110,   116,   132,     0,   133,   126,   129,
-     122,   131,   130,   149,   160,   211,     0,   291,   293,     0,
-       2,     3,   228,     0,     0,    89,     0,    97,     0,   106,
-     100,   108,     0,   109,     0,    90,     2,   117,     0,    95,
-       0,   127,   123,     0,     1,   292,     0,     0,   226,   159,
-     156,     0,   154,     0,   296,   101,   105,   107,   103,   111,
-     102,     0,     0,    88,    96,     0,     0,     0,   230,    10,
-       4,     8,     6,     7,     9,    31,     0,     0,     0,   161,
-      38,    37,    39,    36,     5,    12,    32,    14,    19,    20,
-       0,     0,    25,     0,    40,     0,    44,    47,    50,    55,
-      58,    60,    62,    64,    66,    68,    70,    87,     0,    29,
-      91,     0,     0,     0,   153,     0,     0,     0,   276,     0,
-       0,     0,     0,     0,     0,     0,     0,   250,   259,   263,
-      40,    72,    85,     0,   239,     0,   149,   242,   261,   241,
-     240,     0,   243,   244,   245,   246,   247,   248,     0,     0,
-       0,     0,     0,   238,   121,     0,   236,     0,   234,     0,
-     231,    33,    34,     0,    16,    17,     0,     0,    23,    22,
-       0,   163,    26,    28,    35,     0,     0,     0,     0,     0,
+       0,   126,   148,   149,   150,     0,   132,   134,   168,   165,
+     166,   167,   172,   173,   174,   175,   176,   177,   169,   170,
+     171,   178,   179,   180,   181,   182,   183,   135,   136,   137,
+     139,   140,   133,   184,   185,   186,   187,   188,   189,   138,
+     123,   122,   141,   142,   143,   144,   145,   146,     0,   164,
+     191,   193,   209,   211,   194,   196,   197,   198,   199,   201,
+     202,   203,   204,   195,   200,   205,   192,   206,   207,   208,
+     210,   212,   213,   214,   215,   216,   217,   218,   219,   220,
+     221,   222,   223,   224,     0,   190,   226,   295,   296,     0,
+      99,    98,     0,   110,   115,   130,     0,   131,   124,   127,
+     120,   129,   128,   147,   158,   225,     0,   292,   294,     0,
+       2,     3,   229,     0,     0,    89,     0,    97,     0,   106,
+     100,   108,     0,   109,     0,    90,     2,   116,     0,    95,
+       0,   125,   121,     0,   159,     1,   293,     0,     0,   227,
+     157,   154,     0,   152,     0,   297,   101,   105,   107,   103,
+     111,   102,     0,   117,    88,    96,     0,     0,     0,   231,
+      10,     4,     8,     6,     7,     9,    31,     0,     0,     0,
+     160,    38,    37,    39,    36,     5,    12,    32,    14,    19,
+      20,     0,     0,    25,     0,    40,     0,    44,    47,    50,
+      55,    58,    60,    62,    64,    66,    68,    70,    87,     0,
+      29,     0,    91,     0,     0,     0,   151,     0,     0,     0,
+     277,     0,     0,     0,     0,     0,     0,     0,     0,   251,
+     260,   264,    40,    72,    85,     0,   240,     0,   147,   243,
+     262,   242,   241,     0,   244,   245,   246,   247,   248,   249,
+     104,     0,   112,   239,   119,     0,     0,   237,     0,   235,
+       0,   232,    33,    34,     0,    16,    17,     0,     0,    23,
+      22,     0,   164,    26,    28,    35,     0,     0,     0,     0,
        0,     0,     0,     0,     0,     0,     0,     0,     0,     0,
-       0,     0,     0,     0,     0,   162,   229,     0,   157,   158,
-     155,   287,   286,   257,   278,     0,   290,   288,     0,     0,
-       0,   271,   274,   249,     0,    75,    76,    78,    77,    80,
-      81,    82,    83,    84,    79,    74,     0,     0,   264,   260,
-     262,     0,     0,     0,   115,     0,   118,     0,     0,     0,
-     232,     0,    92,    11,     0,    18,    30,    15,    21,    27,
+       0,     0,     0,     0,     0,     0,   161,   162,     0,   230,
+       0,   155,   156,   153,   288,   287,   258,   279,     0,   291,
+     289,     0,     0,     0,   272,   275,   250,     0,    75,    76,
+      78,    77,    80,    81,    82,    83,    84,    79,    74,     0,
+       0,   265,   261,   263,   114,     0,   118,     0,   238,     0,
+     233,     0,    92,    11,     0,    18,    30,    15,    21,    27,
       41,    42,    43,    46,    45,    48,    49,    53,    54,    51,
       52,    56,    57,    59,    61,    63,    65,    67,    69,     0,
-     227,     0,     0,     0,     0,     0,   289,     0,   270,     0,
-     251,    73,    86,   104,     0,   112,   119,     0,   233,     0,
-     235,     0,    93,    13,     0,     0,   256,   258,   281,   280,
-     283,   257,   268,   272,     0,     0,     0,     0,   113,     0,
-     120,   237,     0,    71,     0,   282,     0,     0,   267,   265,
-       0,     0,     0,   252,   114,     0,     0,   284,     0,   257,
-     269,     0,   254,   275,   253,    94,     0,   285,   279,   266,
-     273,   277
+     163,   228,     0,     0,     0,     0,     0,   290,     0,   271,
+       0,   252,    73,    86,   113,   234,   236,     0,    93,    13,
+       0,     0,   257,   259,   282,   281,   284,   258,   269,   273,
+       0,     0,     0,     0,     0,    71,     0,   283,     0,     0,
+     268,   266,     0,     0,     0,   253,     0,     0,   285,     0,
+     258,   270,     0,   255,   276,   254,    94,     0,   286,   280,
+     267,   274,   278
 };
 
   /* YYPGOTO[NTERM-NUM].  */
 static const yytype_int16 yypgoto[] =
 {
-    -369,   -47,  -369,  -369,  -369,  -369,  -369,  -369,   -12,  -369,
-    -369,  -369,  -369,    53,  -369,   -86,   -91,  -147,   -84,   -30,
-     -28,   -25,   -24,   -32,   -23,  -369,  -115,  -140,  -369,  -163,
-    -141,  -369,    11,    13,  -369,  -369,  -369,   130,   135,   134,
-    -369,  -369,  -345,  -369,   -87,  -369,   -90,  -369,   -89,   253,
-    -369,  -369,    58,     0,  -369,  -369,  -369,  -369,  -123,  -148,
-      16,   -67,  -224,   -95,  -223,  -343,  -146,  -369,  -369,  -153,
-    -368,  -369,  -369,  -113,   -36,   -94,  -369,  -369,  -369,  -369,
-    -369,  -119,  -369,  -369,  -369,  -369,  -369,  -369,  -369,  -369,
-    -369,   166,  -369,  -369
+    -366,   -47,  -366,  -366,  -366,  -366,  -366,  -366,   -15,  -366,
+    -366,  -366,  -366,     4,  -366,   -83,   -80,  -142,   -84,   -39,
+     -48,   -44,   -37,   -36,   -46,  -366,  -128,  -144,  -366,  -157,
+    -195,  -366,    17,    23,  -366,  -366,  -366,   122,   128,   126,
+    -366,  -366,  -344,  -366,   -78,  -366,   -92,  -366,   -89,   247,
+    -366,  -366,    47,     0,  -112,  -366,  -366,  -366,  -366,  -122,
+    -148,     7,   -74,  -227,  -109,  -224,  -353,  -145,  -366,  -366,
+    -151,  -365,  -366,  -366,  -113,   -43,  -106,  -366,  -366,  -366,
+    -366,  -366,  -126,  -366,  -366,  -366,  -366,  -366,  -366,  -366,
+    -366,  -366,   156,  -366,  -366
 };
 
   /* YYDEFGOTO[NTERM-NUM].  */
 static const yytype_int16 yydefgoto[] =
 {
-      -1,   246,   174,   175,   176,   334,   177,   178,   179,   180,
-     181,   182,   183,   220,   185,   186,   187,   188,   189,   190,
-     191,   192,   193,   194,   195,   196,   221,   222,   316,   223,
-     198,   130,   224,   225,    89,    90,    91,   119,   120,   121,
+      -1,   247,   175,   176,   177,   334,   178,   179,   180,   181,
+     182,   183,   184,   222,   186,   187,   188,   189,   190,   191,
+     192,   193,   194,   195,   196,   197,   223,   224,   319,   225,
+     199,   130,   226,   227,    89,    90,    91,   119,   120,   121,
       92,    93,    94,    95,    96,    97,    98,    99,   100,   101,
-     102,   141,   142,   199,   104,   105,   202,   137,   157,   158,
-     247,   248,   244,   227,   228,   229,   230,   304,   397,   423,
-     361,   362,   363,   424,   231,   232,   233,   409,   234,   410,
-     235,   396,   236,   369,   293,   364,   390,   406,   407,   237,
-     106,   107,   108,   116
+     102,   142,   143,   200,   134,   104,   105,   204,   138,   158,
+     159,   248,   249,   244,   229,   230,   231,   232,   307,   393,
+     414,   362,   363,   364,   415,   233,   234,   235,   401,   236,
+     402,   237,   392,   238,   370,   296,   365,   386,   398,   399,
+     239,   106,   107,   108,   116
 };
 
   /* YYTABLE[YYPACT[STATE-NUM]] -- What to do in state STATE-NUM.  If
      positive, shift that token.  If negative, reduce the rule whose
      number is the opposite.  If YYTABLE_NINF, syntax error.  */
 static const yytype_int16 yytable[] =
 {
-     103,   113,   123,   144,   122,   253,   131,   132,   320,   250,
-     242,    87,   243,    88,   201,   139,   324,   331,   197,   283,
-     387,   114,   381,   408,   394,   272,   273,   110,   111,   123,
-     382,   122,   131,   123,   153,   115,   197,   254,   255,   151,
-     154,   156,   262,   155,   200,   394,   152,   127,   156,   298,
-     155,   429,   117,   250,   284,   332,   239,   140,   256,   112,
-     274,   275,   257,   240,   124,   131,   245,   125,   156,   422,
-     155,   118,   204,   300,   259,   422,   148,   149,   205,   287,
-     260,   333,   391,   392,     2,     3,     4,   317,   317,   317,
-     268,   103,   269,   335,   126,   111,   103,   321,   323,   197,
-     243,   376,   426,   138,   317,   133,   103,   318,   317,   136,
-     110,   111,   156,   156,   155,   155,   143,    87,   103,    88,
-     339,   359,   103,   197,   197,   347,   348,   349,   350,   150,
-     103,   329,   365,   -30,   330,   317,   367,   103,   366,   250,
-     203,   329,   238,   226,   378,   270,   271,   320,   276,   277,
-     398,   288,   289,   400,   258,   103,   263,   103,   278,   305,
-     306,   307,   308,   309,   310,   311,   312,   313,   314,   265,
-     266,   267,   317,   384,   281,   414,   371,   372,   315,   345,
-     346,   279,   343,   344,   280,   243,   184,   379,   282,   285,
-     291,   292,   351,   352,   294,   295,   299,   430,   156,   296,
-     155,   103,   103,   302,   184,   301,   393,   303,   -29,   325,
-     326,   328,   -24,   197,   368,   385,  -255,   373,   375,   251,
-     252,   383,   374,   -31,   317,   377,   412,   393,   399,   401,
-     404,   226,   413,   419,   243,   415,   418,   243,   264,   417,
-     402,   416,   217,   421,   403,   338,   425,   431,   353,   386,
-     357,   354,   146,   145,   427,   355,   147,   356,   109,   243,
-     358,   327,   380,   290,   420,   428,   197,   184,   370,   388,
-     389,   405,   135,     0,     0,     0,     0,     0,     0,     0,
-       0,   243,   395,     0,     0,     0,     0,   103,     0,     0,
-       0,   184,   184,     0,     0,     0,     0,     0,     0,     0,
-       0,     0,     0,   395,   226,   131,   132,     0,     0,     0,
-       0,     0,     0,     0,     0,     0,     0,     0,   340,   341,
-     342,   184,   184,   184,   184,   184,   184,   184,   184,   184,
-     184,   184,   184,   184,   184,   184,   184,     0,     0,     0,
-       0,     0,     0,     0,     0,     0,     0,   411,     0,     0,
+     103,   113,   123,   145,   131,   198,   288,   132,   243,   323,
+     251,   383,   254,   122,   324,   153,   203,    87,   326,   140,
+     331,   303,   400,    88,   284,   133,   390,   273,   274,   123,
+     131,   114,   152,   123,   110,   111,   377,   240,   242,   263,
+     122,   157,   390,   115,   378,   420,   117,   127,   205,   157,
+     118,   413,   156,   255,   256,   251,   413,   301,   332,   285,
+     156,   141,   275,   276,   131,   133,   112,   246,   201,   157,
+     126,   111,   241,   198,   257,   245,   149,   150,   258,   201,
+     156,   206,   290,   154,   110,   111,   325,   207,   198,   155,
+     133,   103,   124,   260,   139,   125,   103,   243,   374,   261,
+     335,   243,   333,   144,   387,   388,   103,   417,   320,   137,
+     320,   320,   201,   320,   157,   157,   320,   339,   103,   321,
+     151,   329,   103,    87,   330,   156,   156,   202,   359,    88,
+     103,   347,   348,   349,   350,   328,   320,   185,   103,   367,
+     329,   366,   251,   375,   228,   368,   -30,   323,     2,     3,
+       4,   266,   267,   268,   264,   269,   103,   270,   103,   308,
+     309,   310,   311,   312,   313,   314,   315,   316,   317,   271,
+     272,   252,   253,   277,   278,   372,   373,   279,   318,   291,
+     292,   243,   394,   320,   380,   421,   343,   344,   259,   280,
+     265,   345,   346,   351,   352,   281,   282,   283,   286,   294,
+     297,   157,   295,   103,   103,   185,   298,   299,   306,   304,
+     302,   305,   156,   389,   -29,   360,   -24,  -256,   381,   410,
+     185,   379,   -31,   396,   369,   404,   320,   408,   409,   389,
+     405,   406,   354,   228,   219,   412,   395,   355,   358,   407,
+     353,   416,   422,   338,   147,   356,   146,   357,   148,   198,
+     382,   418,   109,   327,   293,   376,   384,   411,   419,   385,
+     397,     0,   136,     0,   371,     0,     0,     0,   243,     0,
+     340,   341,   342,   185,   185,   185,   185,   185,   185,   185,
+     185,   185,   185,   185,   185,   185,   185,   185,   185,     0,
+     103,     0,   391,     0,     0,     0,     0,     0,     0,   131,
+       0,     0,   132,     0,     0,     0,     0,   228,   391,     0,
        0,     0,     0,     0,     0,     0,     0,     0,     0,     0,
-       0,     0,     0,   226,   226,     0,     0,     0,     0,   226,
-     226,     0,     0,     0,     0,     0,     0,     0,     0,     0,
-       0,   184,     0,     0,     0,     0,     0,     0,     0,     0,
-     226,     0,     0,     0,     0,   103,     0,     0,     0,     0,
+       0,     0,     0,     0,     0,     0,     0,     0,     0,     0,
+       0,     0,     0,     0,     0,     0,     0,     0,     0,     0,
+       0,     0,     0,   403,     0,     0,     0,     0,     0,     0,
        0,     0,     0,     0,     0,     0,     0,     0,     0,     0,
-       0,     0,   226,     0,     0,     0,     0,     0,   226,     0,
+       0,     0,     0,     0,   228,   228,     0,     0,     0,     0,
+     228,   228,     0,     0,     0,     0,     0,     0,     0,     0,
+       0,   185,     0,     0,     0,     0,   228,     0,     0,     0,
+       0,   103,     0,     0,     0,     0,     0,     0,     0,     0,
+       0,     0,     0,     0,   228,     0,     0,     0,     0,   228,
        1,     2,     3,     4,     5,     6,     7,     8,     9,    10,
-      11,   206,   207,   208,   184,   209,   210,   211,   212,   213,
-     214,   215,    12,    13,    14,    15,    16,    17,    18,    19,
+      11,   208,   209,   210,     0,   211,   212,   213,   214,   215,
+     216,   217,    12,    13,    14,    15,    16,    17,    18,    19,
       20,    21,    22,    23,    24,    25,    26,    27,    28,    29,
       30,    31,    32,    33,    34,    35,    36,    37,    38,    39,
       40,    41,    42,    43,    44,    45,    46,    47,    48,    49,
-     216,    50,    51,    52,    53,    54,    55,    56,    57,    58,
+     218,    50,    51,    52,    53,    54,    55,    56,    57,    58,
       59,    60,    61,    62,    63,    64,    65,    66,     0,    67,
       68,    69,    70,    71,    72,    73,    74,    75,    76,    77,
-      78,    79,    80,    81,    82,    83,    84,    85,   159,   160,
-      86,   161,   162,   163,   164,   165,     0,     0,   166,   167,
+      78,    79,    80,    81,    82,    83,    84,    85,   160,   161,
+      86,   162,   163,   164,   165,   166,     0,     0,   167,   168,
        0,     0,     0,     0,     0,     0,     0,     0,     0,     0,
-       0,     0,     0,     0,     0,     0,     0,   168,     0,     0,
-       0,   217,   218,     0,     0,     0,     0,   219,   170,   171,
-     172,   173,     1,     2,     3,     4,     5,     6,     7,     8,
-       9,    10,    11,   206,   207,   208,     0,   209,   210,   211,
-     212,   213,   214,   215,    12,    13,    14,    15,    16,    17,
+       0,     0,     0,     0,     0,     0,     0,   169,     0,     0,
+       0,   219,   220,     0,     0,     0,     0,   221,   171,   172,
+     173,   174,     1,     2,     3,     4,     5,     6,     7,     8,
+       9,    10,    11,   208,   209,   210,     0,   211,   212,   213,
+     214,   215,   216,   217,    12,    13,    14,    15,    16,    17,
       18,    19,    20,    21,    22,    23,    24,    25,    26,    27,
       28,    29,    30,    31,    32,    33,    34,    35,    36,    37,
       38,    39,    40,    41,    42,    43,    44,    45,    46,    47,
-      48,    49,   216,    50,    51,    52,    53,    54,    55,    56,
+      48,    49,   218,    50,    51,    52,    53,    54,    55,    56,
       57,    58,    59,    60,    61,    62,    63,    64,    65,    66,
        0,    67,    68,    69,    70,    71,    72,    73,    74,    75,
       76,    77,    78,    79,    80,    81,    82,    83,    84,    85,
-     159,   160,    86,   161,   162,   163,   164,   165,     0,     0,
-     166,   167,     0,     0,     0,     0,     0,     0,     0,     0,
-       0,     0,     0,     0,     0,     0,     0,     0,     0,   168,
-       0,     0,     0,   217,   319,     0,     0,     0,     0,   219,
-     170,   171,   172,   173,     1,     2,     3,     4,     5,     6,
-       7,     8,     9,    10,    11,   206,   207,   208,     0,   209,
-     210,   211,   212,   213,   214,   215,    12,    13,    14,    15,
+     160,   161,    86,   162,   163,   164,   165,   166,     0,     0,
+     167,   168,     0,     0,     0,     0,     0,     0,     0,     0,
+       0,     0,     0,     0,     0,     0,     0,     0,     0,   169,
+       0,     0,     0,   219,   322,     0,     0,     0,     0,   221,
+     171,   172,   173,   174,     1,     2,     3,     4,     5,     6,
+       7,     8,     9,    10,    11,   208,   209,   210,     0,   211,
+     212,   213,   214,   215,   216,   217,    12,    13,    14,    15,
       16,    17,    18,    19,    20,    21,    22,    23,    24,    25,
       26,    27,    28,    29,    30,    31,    32,    33,    34,    35,
       36,    37,    38,    39,    40,    41,    42,    43,    44,    45,
-      46,    47,    48,    49,   216,    50,    51,    52,    53,    54,
+      46,    47,    48,    49,   218,    50,    51,    52,    53,    54,
       55,    56,    57,    58,    59,    60,    61,    62,    63,    64,
       65,    66,     0,    67,    68,    69,    70,    71,    72,    73,
       74,    75,    76,    77,    78,    79,    80,    81,    82,    83,
-      84,    85,   159,   160,    86,   161,   162,   163,   164,   165,
-       0,     0,   166,   167,     0,     0,     0,     0,     0,     0,
+      84,    85,   160,   161,    86,   162,   163,   164,   165,   166,
+       0,     0,   167,   168,     0,     0,     0,     0,     0,     0,
        0,     0,     0,     0,     0,     0,     0,     0,     0,     0,
-       0,   168,     0,     0,     0,   217,     0,     0,     0,     0,
-       0,   219,   170,   171,   172,   173,     1,     2,     3,     4,
-       5,     6,     7,     8,     9,    10,    11,   206,   207,   208,
-       0,   209,   210,   211,   212,   213,   214,   215,    12,    13,
+       0,   169,     0,     0,     0,   219,     0,     0,     0,     0,
+       0,   221,   171,   172,   173,   174,     1,     2,     3,     4,
+       5,     6,     7,     8,     9,    10,    11,   208,   209,   210,
+       0,   211,   212,   213,   214,   215,   216,   217,    12,    13,
       14,    15,    16,    17,    18,    19,    20,    21,    22,    23,
       24,    25,    26,    27,    28,    29,    30,    31,    32,    33,
       34,    35,    36,    37,    38,    39,    40,    41,    42,    43,
-      44,    45,    46,    47,    48,    49,   216,    50,    51,    52,
+      44,    45,    46,    47,    48,    49,   218,    50,    51,    52,
       53,    54,    55,    56,    57,    58,    59,    60,    61,    62,
       63,    64,    65,    66,     0,    67,    68,    69,    70,    71,
       72,    73,    74,    75,    76,    77,    78,    79,    80,    81,
-      82,    83,    84,    85,   159,   160,    86,   161,   162,   163,
-     164,   165,     0,     0,   166,   167,     0,     0,     0,     0,
+      82,    83,    84,    85,   160,   161,    86,   162,   163,   164,
+     165,   166,     0,     0,   167,   168,     0,     0,     0,     0,
        0,     0,     0,     0,     0,     0,     0,     0,     0,     0,
-       0,     0,     0,   168,     0,     0,     0,   143,     0,     0,
-       0,     0,     0,   219,   170,   171,   172,   173,     1,     2,
-       3,     4,     5,     6,     7,     8,     9,    10,    11,   206,
-     207,   208,     0,   209,   210,   211,   212,   213,   214,   215,
+       0,     0,     0,   169,     0,     0,     0,   144,     0,     0,
+       0,     0,     0,   221,   171,   172,   173,   174,     1,     2,
+       3,     4,     5,     6,     7,     8,     9,    10,    11,   208,
+     209,   210,     0,   211,   212,   213,   214,   215,   216,   217,
       12,    13,    14,    15,    16,    17,    18,    19,    20,    21,
       22,    23,    24,    25,    26,    27,    28,    29,    30,    31,
       32,    33,    34,    35,    36,    37,    38,    39,    40,    41,
-      42,    43,    44,    45,    46,    47,    48,    49,   216,    50,
+      42,    43,    44,    45,    46,    47,    48,    49,   218,    50,
       51,    52,    53,    54,    55,    56,    57,    58,    59,    60,
       61,    62,    63,    64,    65,    66,     0,    67,    68,    69,
       70,    71,    72,    73,    74,    75,    76,    77,    78,    79,
-      80,    81,    82,    83,    84,    85,   159,   160,    86,   161,
-     162,   163,   164,   165,     0,     0,   166,   167,     0,     0,
+      80,    81,    82,    83,    84,    85,   160,   161,    86,   162,
+     163,   164,   165,   166,     0,     0,   167,   168,     0,     0,
        0,     0,     0,     0,     0,     0,     0,     0,     0,     0,
-       0,     0,     0,     0,     0,   168,     0,     0,     0,     0,
-       0,     0,     0,     0,     0,   219,   170,   171,   172,   173,
+       0,     0,     0,     0,     0,   169,     0,     0,     0,     0,
+       0,     0,     0,     0,     0,   221,   171,   172,   173,   174,
        1,     2,     3,     4,     5,     6,     7,     8,     9,    10,
       11,     0,     0,     0,     0,     0,     0,     0,     0,     0,
        0,     0,    12,    13,    14,    15,    16,    17,    18,    19,
       20,    21,    22,    23,    24,    25,    26,    27,    28,    29,
       30,    31,    32,    33,    34,    35,    36,    37,    38,    39,
       40,    41,    42,    43,    44,    45,    46,    47,    48,    49,
        0,    50,    51,    52,    53,    54,    55,    56,    57,    58,
       59,    60,    61,    62,    63,    64,    65,    66,     0,    67,
       68,    69,    70,    71,    72,    73,    74,    75,    76,    77,
-      78,    79,    80,    81,    82,    83,    84,    85,   159,   160,
-      86,   161,   162,   163,   164,   165,     0,     0,   166,   167,
+      78,    79,    80,    81,    82,    83,    84,    85,   160,   161,
+      86,   162,   163,   164,   165,   166,     0,     0,   167,   168,
        0,     0,     0,     0,     0,     0,     0,     0,     0,     0,
-       0,     0,     0,     1,     2,     3,     4,   168,     6,     7,
-       8,     9,    10,    11,     0,     0,     0,   219,   170,   171,
-     172,   173,     0,     0,     0,    12,    13,    14,    15,    16,
+       0,     0,     0,     1,     2,     3,     4,   169,     6,     7,
+       8,     9,    10,    11,     0,     0,     0,   221,   171,   172,
+     173,   174,     0,     0,     0,    12,    13,    14,    15,    16,
       17,    18,    19,    20,    21,    22,    23,    24,    25,    26,
       27,    28,    29,    30,    31,    32,    33,    34,    35,    36,
       37,    38,    39,    40,    41,    42,    43,    44,    45,    46,
       47,    48,    49,     0,    50,    51,    52,    53,    54,    55,
       56,    57,    58,    59,    60,    61,    62,    63,    64,    65,
       66,     0,    67,    68,    69,    70,    71,    72,    73,    74,
       75,    76,    77,    78,    79,    80,    81,    82,    83,    84,
-      85,   159,   160,    86,   161,   162,   163,   164,   165,     0,
-       0,   166,   167,     0,     0,     0,     0,     0,     0,     0,
+      85,   160,   161,    86,   162,   163,   164,   165,   166,     0,
+       0,   167,   168,     0,     0,     0,     0,     0,     0,     0,
        0,     0,     0,     0,     0,     0,     1,     2,     3,     4,
-     168,     6,     7,     8,     9,    10,    11,     0,     0,     0,
-       0,   170,   171,   172,   173,     0,     0,     0,    12,    13,
+     169,     6,     7,     8,     9,    10,    11,     0,     0,     0,
+       0,   171,   172,   173,   174,     0,     0,     0,    12,    13,
       14,    15,    16,    17,    18,    19,    20,    21,    22,    23,
       24,    25,    26,    27,    28,    29,    30,    31,    32,    33,
       34,    35,    36,    37,    38,    39,    40,    41,    42,    43,
       44,    45,    46,    47,    48,    49,     0,    50,    51,    52,
       53,    54,    55,    56,    57,    58,    59,    60,    61,    62,
       63,    64,    65,    66,     0,    67,    68,    69,    70,    71,
       72,    73,    74,    75,    76,    77,    78,    79,    80,    81,
       82,    83,    84,    85,     0,   128,    86,     0,     8,     9,
       10,    11,     0,     0,     0,     0,     0,     0,     0,     0,
        0,     0,     0,    12,    13,    14,    15,    16,    17,    18,
       19,    20,    21,    22,    23,    24,    25,    26,     0,     0,
        0,     0,     0,   129,    33,    34,    35,    36,    37,    38,
        0,     0,     0,     0,     0,     0,     0,     0,     0,    48,
       49,     0,    50,    51,    52,    53,    54,    55,    56,    57,
       58,    59,    60,    61,    62,    63,    64,    65,    66,     0,
       67,    68,    69,    70,    71,    72,    73,    74,    75,    76,
-      77,    78,    79,    80,    81,    82,    83,     0,    85,   159,
-     160,    86,   161,   162,   163,   164,   165,     0,     0,   166,
-     167,     0,     0,     0,     0,     0,     0,     0,     0,     0,
-       0,     0,     0,     0,     0,     0,     0,     0,   168,     0,
-       0,   169,     8,     9,    10,    11,     0,     0,     0,   170,
-     171,   172,   173,     0,     0,     0,     0,    12,    13,    14,
+      77,    78,    79,    80,    81,    82,    83,     0,    85,   160,
+     161,    86,   162,   163,   164,   165,   166,     0,     0,   167,
+     168,     0,     0,     0,     0,     0,     0,     0,     0,     0,
+       0,     0,     0,     0,     0,     0,     0,     0,   169,     0,
+       0,   170,     8,     9,    10,    11,     0,     0,     0,   171,
+     172,   173,   174,     0,     0,     0,     0,    12,    13,    14,
       15,    16,    17,    18,    19,    20,    21,    22,    23,    24,
       25,    26,     0,     0,     0,     0,     0,     0,    33,    34,
       35,    36,    37,    38,     0,     0,     0,     0,     0,     0,
        0,     0,     0,    48,    49,     0,    50,    51,    52,    53,
       54,    55,    56,    57,    58,    59,    60,    61,    62,    63,
       64,    65,    66,     0,    67,    68,    69,    70,    71,    72,
       73,    74,    75,    76,    77,    78,    79,    80,    81,    82,
-      83,     0,    85,   159,   160,    86,   161,   162,   163,   164,
-     165,     0,     0,   166,   167,     0,     0,     0,     0,     0,
+      83,     0,    85,   160,   161,    86,   162,   163,   164,   165,
+     166,     0,     0,   167,   168,     0,     0,     0,     0,     0,
        0,     0,     0,     0,     0,     0,     0,     0,     0,     0,
-       0,     0,   168,     0,     0,   241,     8,     9,    10,    11,
-       0,     0,     0,   170,   171,   172,   173,     0,     0,     0,
+       0,     0,   169,     0,     0,   287,     8,     9,    10,    11,
+       0,     0,     0,   171,   172,   173,   174,     0,     0,     0,
        0,    12,    13,    14,    15,    16,    17,    18,    19,    20,
       21,    22,    23,    24,    25,    26,     0,     0,     0,     0,
        0,     0,    33,    34,    35,    36,    37,    38,     0,     0,
        0,     0,     0,     0,     0,     0,     0,    48,    49,     0,
       50,    51,    52,    53,    54,    55,    56,    57,    58,    59,
       60,    61,    62,    63,    64,    65,    66,     0,    67,    68,
       69,    70,    71,    72,    73,    74,    75,    76,    77,    78,
-      79,    80,    81,    82,    83,     0,    85,   159,   160,    86,
-     161,   162,   163,   164,   165,     0,     0,   166,   167,     0,
+      79,    80,    81,    82,    83,     0,    85,   160,   161,    86,
+     162,   163,   164,   165,   166,     0,     0,   167,   168,     0,
        0,     0,     0,     0,     0,     0,     0,     0,     0,     0,
-       0,     0,     0,     0,     0,     0,   168,     8,     9,    10,
-      11,     0,     0,     0,     0,     0,   297,   170,   171,   172,
-     173,     0,    12,    13,    14,    15,    16,    17,    18,    19,
+       0,     0,     0,     0,     0,     0,   169,     8,     9,    10,
+      11,     0,     0,     0,     0,     0,   300,   171,   172,   173,
+     174,     0,    12,    13,    14,    15,    16,    17,    18,    19,
       20,    21,    22,    23,    24,    25,    26,     0,     0,     0,
        0,     0,     0,    33,    34,    35,    36,    37,    38,     0,
        0,     0,     0,     0,     0,     0,     0,     0,    48,    49,
        0,    50,    51,    52,    53,    54,    55,    56,    57,    58,
       59,    60,    61,    62,    63,    64,    65,    66,     0,    67,
       68,    69,    70,    71,    72,    73,    74,    75,    76,    77,
-      78,    79,    80,    81,    82,    83,     0,    85,   159,   160,
-      86,   161,   162,   163,   164,   165,     0,     0,   166,   167,
+      78,    79,    80,    81,    82,    83,     0,    85,   160,   161,
+      86,   162,   163,   164,   165,   166,     0,     0,   167,   168,
        0,     0,     0,     0,     0,     0,     0,     0,     0,     0,
-       0,     0,     0,     0,     0,     0,     0,   168,     0,     0,
-     322,     8,     9,    10,    11,     0,     0,     0,   170,   171,
-     172,   173,     0,     0,     0,     0,    12,    13,    14,    15,
+       0,     0,     0,     0,     0,     0,     0,   169,     8,     9,
+      10,    11,     0,     0,     0,     0,     0,     0,   171,   172,
+     173,   174,     0,    12,    13,    14,    15,    16,    17,    18,
+      19,    20,    21,    22,    23,    24,    25,    26,     0,     0,
+       0,     0,     0,     0,    33,    34,    35,    36,    37,    38,
+       0,     0,     0,     0,     0,     0,     0,     0,     0,    48,
+     262,     0,    50,    51,    52,    53,    54,    55,    56,    57,
+      58,    59,    60,    61,    62,    63,    64,    65,    66,     0,
+      67,    68,    69,    70,    71,    72,    73,    74,    75,    76,
+      77,    78,    79,    80,    81,    82,    83,     0,    85,   160,
+     161,    86,   162,   163,   164,   165,   166,     0,     0,   167,
+     168,     0,     0,     0,     0,     0,     0,     0,     0,     0,
+       0,     0,     0,     0,     1,     2,     3,     4,   169,     6,
+       7,     8,     9,    10,    11,     0,     0,     0,     0,   171,
+     172,   173,   174,     0,     0,     0,    12,    13,    14,    15,
       16,    17,    18,    19,    20,    21,    22,    23,    24,    25,
-      26,     0,     0,     0,     0,     0,     0,    33,    34,    35,
-      36,    37,    38,     0,     0,     0,     0,     0,     0,     0,
-       0,     0,    48,    49,     0,    50,    51,    52,    53,    54,
+      26,    27,    28,    29,    30,    31,    32,    33,    34,    35,
+      36,    37,    38,    39,    40,    41,    42,    43,    44,    45,
+      46,    47,    48,    49,     0,    50,    51,    52,    53,    54,
       55,    56,    57,    58,    59,    60,    61,    62,    63,    64,
       65,    66,     0,    67,    68,    69,    70,    71,    72,    73,
       74,    75,    76,    77,    78,    79,    80,    81,    82,    83,
-       0,    85,   159,   160,    86,   161,   162,   163,   164,   165,
-       0,     0,   166,   167,     0,     0,     0,     0,     0,     0,
-       0,     0,     0,     0,     0,     0,     0,     0,     0,     0,
-       0,   168,     8,     9,    10,    11,     0,     0,     0,     0,
-       0,     0,   170,   171,   172,   173,     0,    12,    13,    14,
+      84,    85,     0,     0,    86,     0,     0,     0,     0,     0,
+       0,     0,     0,     0,     0,     1,     2,     3,     4,     0,
+       6,     7,     8,     9,    10,    11,     0,     0,     0,     0,
+       0,     0,     0,     0,     0,     0,   250,    12,    13,    14,
       15,    16,    17,    18,    19,    20,    21,    22,    23,    24,
-      25,    26,     0,     0,     0,     0,     0,     0,    33,    34,
-      35,    36,    37,    38,     0,     0,     0,     0,     0,     0,
-       0,     0,     0,    48,   261,     0,    50,    51,    52,    53,
+      25,    26,    27,    28,    29,    30,    31,    32,    33,    34,
+      35,    36,    37,    38,    39,    40,    41,    42,    43,    44,
+      45,    46,    47,    48,    49,     0,    50,    51,    52,    53,
       54,    55,    56,    57,    58,    59,    60,    61,    62,    63,
       64,    65,    66,     0,    67,    68,    69,    70,    71,    72,
       73,    74,    75,    76,    77,    78,    79,    80,    81,    82,
-      83,     0,    85,   159,   160,    86,   161,   162,   163,   164,
-     165,     0,     0,   166,   167,     0,     0,     0,     0,     0,
-       0,     0,     0,     0,     0,     0,     0,     0,     1,     2,
-       3,     4,   168,     6,     7,     8,     9,    10,    11,     0,
-       0,     0,     0,   170,   171,   172,   173,     0,     0,     0,
+      83,    84,    85,     0,     0,    86,     0,     0,     0,     0,
+       0,     0,     0,     0,     0,     0,     1,     2,     3,     4,
+       0,     6,     7,     8,     9,    10,    11,     0,     0,     0,
+       0,     0,     0,     0,     0,     0,     0,   289,    12,    13,
+      14,    15,    16,    17,    18,    19,    20,    21,    22,    23,
+      24,    25,    26,    27,    28,    29,    30,    31,    32,    33,
+      34,    35,    36,    37,    38,    39,    40,    41,    42,    43,
+      44,    45,    46,    47,    48,    49,     0,    50,    51,    52,
+      53,    54,    55,    56,    57,    58,    59,    60,    61,    62,
+      63,    64,    65,    66,     0,    67,    68,    69,    70,    71,
+      72,    73,    74,    75,    76,    77,    78,    79,    80,    81,
+      82,    83,    84,    85,     0,     0,    86,     0,     0,     0,
+       0,     0,     0,     0,   135,     0,     0,     1,     2,     3,
+       4,     5,     6,     7,     8,     9,    10,    11,     0,     0,
+       0,     0,     0,     0,     0,     0,     0,     0,   361,    12,
+      13,    14,    15,    16,    17,    18,    19,    20,    21,    22,
+      23,    24,    25,    26,    27,    28,    29,    30,    31,    32,
+      33,    34,    35,    36,    37,    38,    39,    40,    41,    42,
+      43,    44,    45,    46,    47,    48,    49,     0,    50,    51,
+      52,    53,    54,    55,    56,    57,    58,    59,    60,    61,
+      62,    63,    64,    65,    66,     0,    67,    68,    69,    70,
+      71,    72,    73,    74,    75,    76,    77,    78,    79,    80,
+      81,    82,    83,    84,    85,     0,     0,    86,     1,     2,
+       3,     4,     5,     6,     7,     8,     9,    10,    11,     0,
+       0,     0,     0,     0,     0,     0,     0,     0,     0,     0,
       12,    13,    14,    15,    16,    17,    18,    19,    20,    21,
       22,    23,    24,    25,    26,    27,    28,    29,    30,    31,
       32,    33,    34,    35,    36,    37,    38,    39,    40,    41,
       42,    43,    44,    45,    46,    47,    48,    49,     0,    50,
       51,    52,    53,    54,    55,    56,    57,    58,    59,    60,
       61,    62,    63,    64,    65,    66,     0,    67,    68,    69,
       70,    71,    72,    73,    74,    75,    76,    77,    78,    79,
-      80,    81,    82,    83,    84,    85,     0,     0,    86,     0,
-       0,     0,     0,     0,     0,     0,     0,     0,     0,     1,
+      80,    81,    82,    83,    84,    85,     0,     0,    86,     1,
        2,     3,     4,     0,     6,     7,     8,     9,    10,    11,
        0,     0,     0,     0,     0,     0,     0,     0,     0,     0,
-     249,    12,    13,    14,    15,    16,    17,    18,    19,    20,
+       0,    12,    13,    14,    15,    16,    17,    18,    19,    20,
       21,    22,    23,    24,    25,    26,    27,    28,    29,    30,
       31,    32,    33,    34,    35,    36,    37,    38,    39,    40,
       41,    42,    43,    44,    45,    46,    47,    48,    49,     0,
       50,    51,    52,    53,    54,    55,    56,    57,    58,    59,
       60,    61,    62,    63,    64,    65,    66,     0,    67,    68,
       69,    70,    71,    72,    73,    74,    75,    76,    77,    78,
       79,    80,    81,    82,    83,    84,    85,     0,     0,    86,
-       0,     0,     0,     0,     0,     0,     0,     0,     0,     0,
-       1,     2,     3,     4,     0,     6,     7,     8,     9,    10,
-      11,     0,     0,     0,     0,     0,     0,     0,     0,     0,
-       0,   286,    12,    13,    14,    15,    16,    17,    18,    19,
-      20,    21,    22,    23,    24,    25,    26,    27,    28,    29,
-      30,    31,    32,    33,    34,    35,    36,    37,    38,    39,
-      40,    41,    42,    43,    44,    45,    46,    47,    48,    49,
-       0,    50,    51,    52,    53,    54,    55,    56,    57,    58,
-      59,    60,    61,    62,    63,    64,    65,    66,     0,    67,
-      68,    69,    70,    71,    72,    73,    74,    75,    76,    77,
-      78,    79,    80,    81,    82,    83,    84,    85,     0,     0,
-      86,     0,     0,     0,     0,     0,     0,     0,   134,     0,
-       0,     1,     2,     3,     4,     5,     6,     7,     8,     9,
-      10,    11,     0,     0,     0,     0,     0,     0,     0,     0,
-       0,     0,   360,    12,    13,    14,    15,    16,    17,    18,
-      19,    20,    21,    22,    23,    24,    25,    26,    27,    28,
-      29,    30,    31,    32,    33,    34,    35,    36,    37,    38,
-      39,    40,    41,    42,    43,    44,    45,    46,    47,    48,
-      49,     0,    50,    51,    52,    53,    54,    55,    56,    57,
-      58,    59,    60,    61,    62,    63,    64,    65,    66,     0,
-      67,    68,    69,    70,    71,    72,    73,    74,    75,    76,
-      77,    78,    79,    80,    81,    82,    83,    84,    85,     0,
-       0,    86,     1,     2,     3,     4,     5,     6,     7,     8,
-       9,    10,    11,     0,     0,     0,     0,     0,     0,     0,
-       0,     0,     0,     0,    12,    13,    14,    15,    16,    17,
-      18,    19,    20,    21,    22,    23,    24,    25,    26,    27,
-      28,    29,    30,    31,    32,    33,    34,    35,    36,    37,
-      38,    39,    40,    41,    42,    43,    44,    45,    46,    47,
-      48,    49,     0,    50,    51,    52,    53,    54,    55,    56,
-      57,    58,    59,    60,    61,    62,    63,    64,    65,    66,
-       0,    67,    68,    69,    70,    71,    72,    73,    74,    75,
-      76,    77,    78,    79,    80,    81,    82,    83,    84,    85,
-       0,     0,    86,     1,     2,     3,     4,     0,     6,     7,
        8,     9,    10,    11,     0,     0,     0,     0,     0,     0,
        0,     0,     0,     0,     0,    12,    13,    14,    15,    16,
       17,    18,    19,    20,    21,    22,    23,    24,    25,    26,
-      27,    28,    29,    30,    31,    32,    33,    34,    35,    36,
-      37,    38,    39,    40,    41,    42,    43,    44,    45,    46,
-      47,    48,    49,     0,    50,    51,    52,    53,    54,    55,
+       0,     0,     0,     0,     0,     0,    33,    34,    35,    36,
+      37,    38,     0,     0,     0,     0,     0,     0,     0,     0,
+       0,    48,    49,     0,    50,    51,    52,    53,    54,    55,
       56,    57,    58,    59,    60,    61,    62,    63,    64,    65,
       66,     0,    67,    68,    69,    70,    71,    72,    73,    74,
-      75,    76,    77,    78,    79,    80,    81,    82,    83,    84,
-      85,     0,     0,    86,     8,     9,    10,    11,     0,     0,
+      75,    76,    77,    78,    79,    80,    81,    82,    83,     0,
+      85,     0,   336,    86,     8,     9,    10,    11,   337,     0,
        0,     0,     0,     0,     0,     0,     0,     0,     0,    12,
       13,    14,    15,    16,    17,    18,    19,    20,    21,    22,
       23,    24,    25,    26,     0,     0,     0,     0,     0,     0,
       33,    34,    35,    36,    37,    38,     0,     0,     0,     0,
        0,     0,     0,     0,     0,    48,    49,     0,    50,    51,
       52,    53,    54,    55,    56,    57,    58,    59,    60,    61,
       62,    63,    64,    65,    66,     0,    67,    68,    69,    70,
       71,    72,    73,    74,    75,    76,    77,    78,    79,    80,
-      81,    82,    83,     0,    85,     0,   336,    86,     8,     9,
-      10,    11,   337,     0,     0,     0,     0,     0,     0,     0,
-       0,     0,     0,    12,    13,    14,    15,    16,    17,    18,
-      19,    20,    21,    22,    23,    24,    25,    26,     0,     0,
-       0,     0,     0,     0,    33,    34,    35,    36,    37,    38,
-       0,     0,     0,     0,     0,     0,     0,     0,     0,    48,
-      49,     0,    50,    51,    52,    53,    54,    55,    56,    57,
-      58,    59,    60,    61,    62,    63,    64,    65,    66,     0,
-      67,    68,    69,    70,    71,    72,    73,    74,    75,    76,
-      77,    78,    79,    80,    81,    82,    83,     0,    85,     0,
-       0,    86
+      81,    82,    83,     0,    85,     0,     0,    86
 };
 
 static const yytype_int16 yycheck[] =
 {
-       0,    48,    91,   116,    91,   168,    96,    96,   231,   157,
-     151,     0,   152,     0,   137,    60,   240,   102,   133,   118,
-     363,   130,   132,   391,   369,   113,   114,   102,   103,   118,
-     140,   118,   122,   122,   134,   140,   151,   111,   112,   132,
-     140,   130,   182,   130,   140,   390,   139,    94,   137,   212,
-     137,   419,   131,   201,   153,   140,   132,   102,   132,   134,
-     148,   149,   136,   139,   137,   155,   155,   140,   157,   412,
-     157,   137,   131,   214,   131,   418,   123,   124,   137,   202,
-     137,   131,   131,   131,     4,     5,     6,   137,   137,   137,
-     142,    91,   144,   256,   102,   103,    96,   238,   239,   214,
-     240,   325,   131,   134,   137,   132,   106,   140,   137,   109,
-     102,   103,   201,   202,   201,   202,   134,   106,   118,   106,
-     260,   284,   122,   238,   239,   272,   273,   274,   275,   130,
-     130,   137,   295,   130,   140,   137,   299,   137,   140,   287,
-     139,   137,   132,   143,   140,   109,   110,   370,   115,   116,
-     374,   105,   106,   377,   131,   155,   130,   157,   152,   120,
-     121,   122,   123,   124,   125,   126,   127,   128,   129,   145,
-     146,   147,   137,   138,   117,   399,   316,   317,   139,   270,
-     271,   151,   268,   269,   150,   325,   133,   328,   119,   133,
-     140,   140,   276,   277,   130,   130,   130,   421,   287,   140,
-     287,   201,   202,   130,   151,   138,   369,   135,   130,   139,
-     133,   132,   131,   328,   138,    63,   134,   133,   133,   166,
-     167,   133,   139,   130,   137,   139,   131,   390,   139,   133,
-     130,   231,   135,    17,   374,   133,   131,   377,   185,   140,
-     381,   404,   134,   139,   384,   257,   140,   140,   278,   362,
-     282,   279,   122,   118,   417,   280,   122,   281,     5,   399,
-     283,   245,   329,   205,   410,   418,   381,   214,   304,   364,
-     364,   390,   106,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
-      -1,   421,   369,    -1,    -1,    -1,    -1,   287,    -1,    -1,
-      -1,   238,   239,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
-      -1,    -1,    -1,   390,   304,   395,   395,    -1,    -1,    -1,
-      -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,   265,   266,
-     267,   268,   269,   270,   271,   272,   273,   274,   275,   276,
-     277,   278,   279,   280,   281,   282,   283,    -1,    -1,    -1,
-      -1,    -1,    -1,    -1,    -1,    -1,    -1,   394,    -1,    -1,
+       0,    48,    91,   116,    96,   133,   201,    96,   152,   233,
+     158,   364,   169,    91,   241,   127,   138,     0,   245,    60,
+     102,   216,   387,     0,   118,   132,   370,   113,   114,   118,
+     122,   130,   139,   122,   102,   103,   132,   149,   150,   183,
+     118,   130,   386,   140,   140,   410,   131,    94,   139,   138,
+     137,   404,   130,   111,   112,   203,   409,   214,   140,   153,
+     138,   102,   148,   149,   156,   132,   134,   156,   132,   158,
+     102,   103,   139,   201,   132,   139,   123,   124,   136,   132,
+     158,   131,   204,   134,   102,   103,   139,   137,   216,   140,
+     132,    91,   137,   131,   134,   140,    96,   241,   325,   137,
+     257,   245,   131,   134,   131,   131,   106,   131,   137,   109,
+     137,   137,   132,   137,   203,   204,   137,   261,   118,   140,
+     130,   137,   122,   106,   140,   203,   204,   140,   285,   106,
+     130,   273,   274,   275,   276,   247,   137,   133,   138,   140,
+     137,   298,   290,   140,   144,   302,   130,   371,     4,     5,
+       6,   145,   146,   147,   130,   142,   156,   144,   158,   120,
+     121,   122,   123,   124,   125,   126,   127,   128,   129,   109,
+     110,   167,   168,   115,   116,   319,   320,   152,   139,   105,
+     106,   325,   377,   137,   138,   412,   269,   270,   131,   151,
+     186,   271,   272,   277,   278,   150,   117,   119,   133,   140,
+     130,   290,   140,   203,   204,   201,   130,   140,   135,   138,
+     130,   130,   290,   370,   130,   133,   131,   134,    63,    17,
+     216,   133,   130,   130,   138,   131,   137,   140,   131,   386,
+     135,   133,   280,   233,   134,   139,   380,   281,   284,   396,
+     279,   140,   140,   258,   122,   282,   118,   283,   122,   377,
+     363,   408,     5,   246,   207,   329,   365,   402,   409,   365,
+     386,    -1,   106,    -1,   307,    -1,    -1,    -1,   412,    -1,
+     266,   267,   268,   269,   270,   271,   272,   273,   274,   275,
+     276,   277,   278,   279,   280,   281,   282,   283,   284,    -1,
+     290,    -1,   370,    -1,    -1,    -1,    -1,    -1,    -1,   391,
+      -1,    -1,   391,    -1,    -1,    -1,    -1,   307,   386,    -1,
       -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
-      -1,    -1,    -1,   363,   364,    -1,    -1,    -1,    -1,   369,
-     370,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
-      -1,   328,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
-     390,    -1,    -1,    -1,    -1,   395,    -1,    -1,    -1,    -1,
+      -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
+      -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
+      -1,    -1,    -1,   390,    -1,    -1,    -1,    -1,    -1,    -1,
       -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
-      -1,    -1,   412,    -1,    -1,    -1,    -1,    -1,   418,    -1,
+      -1,    -1,    -1,    -1,   364,   365,    -1,    -1,    -1,    -1,
+     370,   371,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
+      -1,   377,    -1,    -1,    -1,    -1,   386,    -1,    -1,    -1,
+      -1,   391,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
+      -1,    -1,    -1,    -1,   404,    -1,    -1,    -1,    -1,   409,
        3,     4,     5,     6,     7,     8,     9,    10,    11,    12,
-      13,    14,    15,    16,   381,    18,    19,    20,    21,    22,
+      13,    14,    15,    16,    -1,    18,    19,    20,    21,    22,
       23,    24,    25,    26,    27,    28,    29,    30,    31,    32,
       33,    34,    35,    36,    37,    38,    39,    40,    41,    42,
       43,    44,    45,    46,    47,    48,    49,    50,    51,    52,
       53,    54,    55,    56,    57,    58,    59,    60,    61,    62,
       63,    64,    65,    66,    67,    68,    69,    70,    71,    72,
       73,    74,    75,    76,    77,    78,    79,    80,    -1,    82,
       83,    84,    85,    86,    87,    88,    89,    90,    91,    92,
       93,    94,    95,    96,    97,    98,    99,   100,   101,   102,
@@ -1512,244 +1497,230 @@ static const yytype_int16 yycheck[] =
       -1,    -1,    -1,    46,    47,    48,    49,    50,    51,    -1,
       -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    61,    62,
       -1,    64,    65,    66,    67,    68,    69,    70,    71,    72,
       73,    74,    75,    76,    77,    78,    79,    80,    -1,    82,
       83,    84,    85,    86,    87,    88,    89,    90,    91,    92,
       93,    94,    95,    96,    97,    98,    -1,   100,   101,   102,
      103,   104,   105,   106,   107,   108,    -1,    -1,   111,   112,
       -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
-      -1,    -1,    -1,    -1,    -1,    -1,    -1,   130,    -1,    -1,
-     133,    10,    11,    12,    13,    -1,    -1,    -1,   141,   142,
-     143,   144,    -1,    -1,    -1,    -1,    25,    26,    27,    28,
+      -1,    -1,    -1,    -1,    -1,    -1,    -1,   130,    10,    11,
+      12,    13,    -1,    -1,    -1,    -1,    -1,    -1,   141,   142,
+     143,   144,    -1,    25,    26,    27,    28,    29,    30,    31,
+      32,    33,    34,    35,    36,    37,    38,    39,    -1,    -1,
+      -1,    -1,    -1,    -1,    46,    47,    48,    49,    50,    51,
+      -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    61,
+      62,    -1,    64,    65,    66,    67,    68,    69,    70,    71,
+      72,    73,    74,    75,    76,    77,    78,    79,    80,    -1,
+      82,    83,    84,    85,    86,    87,    88,    89,    90,    91,
+      92,    93,    94,    95,    96,    97,    98,    -1,   100,   101,
+     102,   103,   104,   105,   106,   107,   108,    -1,    -1,   111,
+     112,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
+      -1,    -1,    -1,    -1,     3,     4,     5,     6,   130,     8,
+       9,    10,    11,    12,    13,    -1,    -1,    -1,    -1,   141,
+     142,   143,   144,    -1,    -1,    -1,    25,    26,    27,    28,
       29,    30,    31,    32,    33,    34,    35,    36,    37,    38,
-      39,    -1,    -1,    -1,    -1,    -1,    -1,    46,    47,    48,
-      49,    50,    51,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
-      -1,    -1,    61,    62,    -1,    64,    65,    66,    67,    68,
+      39,    40,    41,    42,    43,    44,    45,    46,    47,    48,
+      49,    50,    51,    52,    53,    54,    55,    56,    57,    58,
+      59,    60,    61,    62,    -1,    64,    65,    66,    67,    68,
       69,    70,    71,    72,    73,    74,    75,    76,    77,    78,
       79,    80,    -1,    82,    83,    84,    85,    86,    87,    88,
       89,    90,    91,    92,    93,    94,    95,    96,    97,    98,
-      -1,   100,   101,   102,   103,   104,   105,   106,   107,   108,
-      -1,    -1,   111,   112,    -1,    -1,    -1,    -1,    -1,    -1,
-      -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
-      -1,   130,    10,    11,    12,    13,    -1,    -1,    -1,    -1,
-      -1,    -1,   141,   142,   143,   144,    -1,    25,    26,    27,
+      99,   100,    -1,    -1,   103,    -1,    -1,    -1,    -1,    -1,
+      -1,    -1,    -1,    -1,    -1,     3,     4,     5,     6,    -1,
+       8,     9,    10,    11,    12,    13,    -1,    -1,    -1,    -1,
+      -1,    -1,    -1,    -1,    -1,    -1,   135,    25,    26,    27,
       28,    29,    30,    31,    32,    33,    34,    35,    36,    37,
-      38,    39,    -1,    -1,    -1,    -1,    -1,    -1,    46,    47,
-      48,    49,    50,    51,    -1,    -1,    -1,    -1,    -1,    -1,
-      -1,    -1,    -1,    61,    62,    -1,    64,    65,    66,    67,
+      38,    39,    40,    41,    42,    43,    44,    45,    46,    47,
+      48,    49,    50,    51,    52,    53,    54,    55,    56,    57,
+      58,    59,    60,    61,    62,    -1,    64,    65,    66,    67,
       68,    69,    70,    71,    72,    73,    74,    75,    76,    77,
       78,    79,    80,    -1,    82,    83,    84,    85,    86,    87,
       88,    89,    90,    91,    92,    93,    94,    95,    96,    97,
-      98,    -1,   100,   101,   102,   103,   104,   105,   106,   107,
-     108,    -1,    -1,   111,   112,    -1,    -1,    -1,    -1,    -1,
-      -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,     3,     4,
-       5,     6,   130,     8,     9,    10,    11,    12,    13,    -1,
-      -1,    -1,    -1,   141,   142,   143,   144,    -1,    -1,    -1,
+      98,    99,   100,    -1,    -1,   103,    -1,    -1,    -1,    -1,
+      -1,    -1,    -1,    -1,    -1,    -1,     3,     4,     5,     6,
+      -1,     8,     9,    10,    11,    12,    13,    -1,    -1,    -1,
+      -1,    -1,    -1,    -1,    -1,    -1,    -1,   135,    25,    26,
+      27,    28,    29,    30,    31,    32,    33,    34,    35,    36,
+      37,    38,    39,    40,    41,    42,    43,    44,    45,    46,
+      47,    48,    49,    50,    51,    52,    53,    54,    55,    56,
+      57,    58,    59,    60,    61,    62,    -1,    64,    65,    66,
+      67,    68,    69,    70,    71,    72,    73,    74,    75,    76,
+      77,    78,    79,    80,    -1,    82,    83,    84,    85,    86,
+      87,    88,    89,    90,    91,    92,    93,    94,    95,    96,
+      97,    98,    99,   100,    -1,    -1,   103,    -1,    -1,    -1,
+      -1,    -1,    -1,    -1,     0,    -1,    -1,     3,     4,     5,
+       6,     7,     8,     9,    10,    11,    12,    13,    -1,    -1,
+      -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,   135,    25,
+      26,    27,    28,    29,    30,    31,    32,    33,    34,    35,
+      36,    37,    38,    39,    40,    41,    42,    43,    44,    45,
+      46,    47,    48,    49,    50,    51,    52,    53,    54,    55,
+      56,    57,    58,    59,    60,    61,    62,    -1,    64,    65,
+      66,    67,    68,    69,    70,    71,    72,    73,    74,    75,
+      76,    77,    78,    79,    80,    -1,    82,    83,    84,    85,
+      86,    87,    88,    89,    90,    91,    92,    93,    94,    95,
+      96,    97,    98,    99,   100,    -1,    -1,   103,     3,     4,
+       5,     6,     7,     8,     9,    10,    11,    12,    13,    -1,
+      -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
       25,    26,    27,    28,    29,    30,    31,    32,    33,    34,
       35,    36,    37,    38,    39,    40,    41,    42,    43,    44,
       45,    46,    47,    48,    49,    50,    51,    52,    53,    54,
       55,    56,    57,    58,    59,    60,    61,    62,    -1,    64,
       65,    66,    67,    68,    69,    70,    71,    72,    73,    74,
       75,    76,    77,    78,    79,    80,    -1,    82,    83,    84,
       85,    86,    87,    88,    89,    90,    91,    92,    93,    94,
-      95,    96,    97,    98,    99,   100,    -1,    -1,   103,    -1,
-      -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,     3,
+      95,    96,    97,    98,    99,   100,    -1,    -1,   103,     3,
        4,     5,     6,    -1,     8,     9,    10,    11,    12,    13,
       -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
-     135,    25,    26,    27,    28,    29,    30,    31,    32,    33,
+      -1,    25,    26,    27,    28,    29,    30,    31,    32,    33,
       34,    35,    36,    37,    38,    39,    40,    41,    42,    43,
       44,    45,    46,    47,    48,    49,    50,    51,    52,    53,
       54,    55,    56,    57,    58,    59,    60,    61,    62,    -1,
       64,    65,    66,    67,    68,    69,    70,    71,    72,    73,
       74,    75,    76,    77,    78,    79,    80,    -1,    82,    83,
       84,    85,    86,    87,    88,    89,    90,    91,    92,    93,
       94,    95,    96,    97,    98,    99,   100,    -1,    -1,   103,
-      -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
-       3,     4,     5,     6,    -1,     8,     9,    10,    11,    12,
-      13,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
-      -1,   135,    25,    26,    27,    28,    29,    30,    31,    32,
-      33,    34,    35,    36,    37,    38,    39,    40,    41,    42,
-      43,    44,    45,    46,    47,    48,    49,    50,    51,    52,
-      53,    54,    55,    56,    57,    58,    59,    60,    61,    62,
-      -1,    64,    65,    66,    67,    68,    69,    70,    71,    72,
-      73,    74,    75,    76,    77,    78,    79,    80,    -1,    82,
-      83,    84,    85,    86,    87,    88,    89,    90,    91,    92,
-      93,    94,    95,    96,    97,    98,    99,   100,    -1,    -1,
-     103,    -1,    -1,    -1,    -1,    -1,    -1,    -1,     0,    -1,
-      -1,     3,     4,     5,     6,     7,     8,     9,    10,    11,
-      12,    13,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
-      -1,    -1,   135,    25,    26,    27,    28,    29,    30,    31,
-      32,    33,    34,    35,    36,    37,    38,    39,    40,    41,
-      42,    43,    44,    45,    46,    47,    48,    49,    50,    51,
-      52,    53,    54,    55,    56,    57,    58,    59,    60,    61,
-      62,    -1,    64,    65,    66,    67,    68,    69,    70,    71,
-      72,    73,    74,    75,    76,    77,    78,    79,    80,    -1,
-      82,    83,    84,    85,    86,    87,    88,    89,    90,    91,
-      92,    93,    94,    95,    96,    97,    98,    99,   100,    -1,
-      -1,   103,     3,     4,     5,     6,     7,     8,     9,    10,
-      11,    12,    13,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
-      -1,    -1,    -1,    -1,    25,    26,    27,    28,    29,    30,
-      31,    32,    33,    34,    35,    36,    37,    38,    39,    40,
-      41,    42,    43,    44,    45,    46,    47,    48,    49,    50,
-      51,    52,    53,    54,    55,    56,    57,    58,    59,    60,
-      61,    62,    -1,    64,    65,    66,    67,    68,    69,    70,
-      71,    72,    73,    74,    75,    76,    77,    78,    79,    80,
-      -1,    82,    83,    84,    85,    86,    87,    88,    89,    90,
-      91,    92,    93,    94,    95,    96,    97,    98,    99,   100,
-      -1,    -1,   103,     3,     4,     5,     6,    -1,     8,     9,
       10,    11,    12,    13,    -1,    -1,    -1,    -1,    -1,    -1,
       -1,    -1,    -1,    -1,    -1,    25,    26,    27,    28,    29,
       30,    31,    32,    33,    34,    35,    36,    37,    38,    39,
-      40,    41,    42,    43,    44,    45,    46,    47,    48,    49,
-      50,    51,    52,    53,    54,    55,    56,    57,    58,    59,
-      60,    61,    62,    -1,    64,    65,    66,    67,    68,    69,
+      -1,    -1,    -1,    -1,    -1,    -1,    46,    47,    48,    49,
+      50,    51,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
+      -1,    61,    62,    -1,    64,    65,    66,    67,    68,    69,
       70,    71,    72,    73,    74,    75,    76,    77,    78,    79,
       80,    -1,    82,    83,    84,    85,    86,    87,    88,    89,
-      90,    91,    92,    93,    94,    95,    96,    97,    98,    99,
-     100,    -1,    -1,   103,    10,    11,    12,    13,    -1,    -1,
+      90,    91,    92,    93,    94,    95,    96,    97,    98,    -1,
+     100,    -1,   102,   103,    10,    11,    12,    13,   108,    -1,
       -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    25,
       26,    27,    28,    29,    30,    31,    32,    33,    34,    35,
       36,    37,    38,    39,    -1,    -1,    -1,    -1,    -1,    -1,
       46,    47,    48,    49,    50,    51,    -1,    -1,    -1,    -1,
       -1,    -1,    -1,    -1,    -1,    61,    62,    -1,    64,    65,
       66,    67,    68,    69,    70,    71,    72,    73,    74,    75,
       76,    77,    78,    79,    80,    -1,    82,    83,    84,    85,
       86,    87,    88,    89,    90,    91,    92,    93,    94,    95,
-      96,    97,    98,    -1,   100,    -1,   102,   103,    10,    11,
-      12,    13,   108,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
-      -1,    -1,    -1,    25,    26,    27,    28,    29,    30,    31,
-      32,    33,    34,    35,    36,    37,    38,    39,    -1,    -1,
-      -1,    -1,    -1,    -1,    46,    47,    48,    49,    50,    51,
-      -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    61,
-      62,    -1,    64,    65,    66,    67,    68,    69,    70,    71,
-      72,    73,    74,    75,    76,    77,    78,    79,    80,    -1,
-      82,    83,    84,    85,    86,    87,    88,    89,    90,    91,
-      92,    93,    94,    95,    96,    97,    98,    -1,   100,    -1,
-      -1,   103
+      96,    97,    98,    -1,   100,    -1,    -1,   103
 };
 
   /* YYSTOS[STATE-NUM] -- The (internal number of the) accessing
      symbol of state STATE-NUM.  */
 static const yytype_uint8 yystos[] =
 {
        0,     3,     4,     5,     6,     7,     8,     9,    10,    11,
       12,    13,    25,    26,    27,    28,    29,    30,    31,    32,
       33,    34,    35,    36,    37,    38,    39,    40,    41,    42,
       43,    44,    45,    46,    47,    48,    49,    50,    51,    52,
       53,    54,    55,    56,    57,    58,    59,    60,    61,    62,
       64,    65,    66,    67,    68,    69,    70,    71,    72,    73,
       74,    75,    76,    77,    78,    79,    80,    82,    83,    84,
       85,    86,    87,    88,    89,    90,    91,    92,    93,    94,
       95,    96,    97,    98,    99,   100,   103,   186,   187,   188,
      189,   190,   194,   195,   196,   197,   198,   199,   200,   201,
-     202,   203,   204,   207,   208,   209,   244,   245,   246,   203,
-     102,   103,   134,   155,   130,   140,   247,   131,   137,   191,
+     202,   203,   204,   207,   209,   210,   245,   246,   247,   203,
+     102,   103,   134,   155,   130,   140,   248,   131,   137,   191,
      192,   193,   198,   202,   137,   140,   102,   155,   102,   140,
-     185,   200,   202,   132,     0,   245,   207,   211,   134,    60,
-     102,   205,   206,   134,   227,   192,   191,   193,   155,   155,
-     130,   132,   139,   134,   140,   198,   202,   212,   213,   101,
-     102,   104,   105,   106,   107,   108,   111,   112,   130,   133,
-     141,   142,   143,   144,   156,   157,   158,   160,   161,   162,
-     163,   164,   165,   166,   167,   168,   169,   170,   171,   172,
-     173,   174,   175,   176,   177,   178,   179,   180,   184,   207,
-     140,   212,   210,   139,   131,   137,    14,    15,    16,    18,
-      19,    20,    21,    22,    23,    24,    63,   134,   135,   140,
-     167,   180,   181,   183,   186,   187,   207,   217,   218,   219,
-     220,   228,   229,   230,   232,   234,   236,   243,   132,   132,
-     139,   133,   184,   181,   216,   202,   155,   214,   215,   135,
-     213,   167,   167,   183,   111,   112,   132,   136,   131,   131,
-     137,    62,   181,   130,   167,   145,   146,   147,   142,   144,
-     109,   110,   113,   114,   148,   149,   115,   116,   152,   151,
-     150,   117,   119,   118,   153,   133,   135,   212,   105,   106,
-     206,   140,   140,   238,   130,   130,   140,   140,   183,   130,
-     184,   138,   130,   135,   221,   120,   121,   122,   123,   124,
-     125,   126,   127,   128,   129,   139,   182,   137,   140,   135,
-     218,   184,   133,   184,   216,   139,   133,   214,   132,   137,
+     185,   200,   202,   132,   208,     0,   246,   207,   212,   134,
+      60,   102,   205,   206,   134,   228,   192,   191,   193,   155,
+     155,   130,   139,   208,   134,   140,   198,   202,   213,   214,
+     101,   102,   104,   105,   106,   107,   108,   111,   112,   130,
+     133,   141,   142,   143,   144,   156,   157,   158,   160,   161,
+     162,   163,   164,   165,   166,   167,   168,   169,   170,   171,
+     172,   173,   174,   175,   176,   177,   178,   179,   180,   184,
+     207,   132,   140,   213,   211,   139,   131,   137,    14,    15,
+      16,    18,    19,    20,    21,    22,    23,    24,    63,   134,
+     135,   140,   167,   180,   181,   183,   186,   187,   207,   218,
+     219,   220,   221,   229,   230,   231,   233,   235,   237,   244,
+     208,   139,   208,   181,   217,   139,   202,   155,   215,   216,
+     135,   214,   167,   167,   183,   111,   112,   132,   136,   131,
+     131,   137,    62,   181,   130,   167,   145,   146,   147,   142,
+     144,   109,   110,   113,   114,   148,   149,   115,   116,   152,
+     151,   150,   117,   119,   118,   153,   133,   133,   184,   135,
+     213,   105,   106,   206,   140,   140,   239,   130,   130,   140,
+     140,   183,   130,   184,   138,   130,   135,   222,   120,   121,
+     122,   123,   124,   125,   126,   127,   128,   129,   139,   182,
+     137,   140,   135,   219,   217,   139,   217,   215,   208,   137,
      140,   102,   140,   131,   159,   183,   102,   108,   162,   181,
      167,   167,   167,   169,   169,   170,   170,   171,   171,   171,
      171,   172,   172,   173,   174,   175,   176,   177,   178,   183,
-     135,   224,   225,   226,   239,   183,   140,   183,   138,   237,
-     228,   181,   181,   133,   139,   133,   216,   139,   140,   184,
-     215,   132,   140,   133,   138,    63,   227,   219,   217,   229,
-     240,   131,   131,   183,   196,   198,   235,   222,   216,   139,
-     216,   133,   184,   181,   130,   235,   241,   242,   224,   231,
-     233,   155,   131,   135,   216,   133,   183,   140,   131,    17,
-     220,   139,   219,   223,   227,   140,   131,   183,   223,   224,
-     216,   140
+     133,   135,   225,   226,   227,   240,   183,   140,   183,   138,
+     238,   229,   181,   181,   217,   140,   216,   132,   140,   133,
+     138,    63,   228,   220,   218,   230,   241,   131,   131,   183,
+     196,   198,   236,   223,   184,   181,   130,   236,   242,   243,
+     225,   232,   234,   155,   131,   135,   133,   183,   140,   131,
+      17,   221,   139,   220,   224,   228,   140,   131,   183,   224,
+     225,   217,   140
 };
 
   /* YYR1[YYN] -- Symbol number of symbol that rule YYN derives.  */
 static const yytype_uint8 yyr1[] =
 {
        0,   154,   155,   155,   156,   157,   157,   157,   157,   157,
      157,   157,   158,   158,   158,   158,   158,   158,   159,   160,
      161,   161,   162,   162,   163,   163,   164,   164,   165,   166,
      166,   166,   167,   167,   167,   167,   168,   168,   168,   168,
      169,   169,   169,   169,   170,   170,   170,   171,   171,   171,
      172,   172,   172,   172,   172,   173,   173,   173,   174,   174,
      175,   175,   176,   176,   177,   177,   178,   178,   179,   179,
      180,   180,   181,   181,   182,   182,   182,   182,   182,   182,
      182,   182,   182,   182,   182,   183,   183,   184,   185,   186,
      186,   186,   186,   186,   186,   186,   186,   187,   188,   188,
      189,   189,   190,   191,   191,   192,   192,   192,   192,   193,
-     194,   194,   194,   194,   194,   194,   195,   195,   195,   195,
-     195,   195,   196,   196,   197,   197,   198,   198,   199,   200,
-     200,   200,   200,   200,   201,   201,   201,   201,   201,   201,
-     201,   201,   201,   201,   201,   201,   201,   201,   201,   202,
-     203,   203,   203,   204,   205,   205,   206,   206,   206,   206,
-     207,   207,   207,   208,   208,   208,   208,   208,   208,   208,
-     208,   208,   208,   208,   208,   208,   208,   208,   208,   208,
-     208,   208,   208,   208,   208,   208,   208,   208,   208,   208,
-     208,   208,   208,   208,   208,   208,   208,   208,   208,   208,
-     208,   208,   208,   208,   208,   208,   208,   208,   208,   208,
-     208,   208,   208,   208,   208,   208,   208,   208,   208,   208,
-     208,   208,   208,   208,   208,   208,   210,   209,   211,   209,
-     212,   212,   213,   213,   214,   214,   215,   215,   216,   217,
-     218,   218,   219,   219,   219,   219,   219,   219,   219,   220,
-     221,   222,   220,   223,   223,   225,   224,   226,   224,   227,
-     227,   228,   228,   229,   229,   230,   231,   231,   233,   232,
-     234,   234,   235,   235,   237,   236,   238,   236,   239,   236,
-     240,   240,   241,   241,   242,   242,   243,   243,   243,   243,
-     243,   244,   244,   245,   245,   247,   246
+     194,   194,   194,   194,   194,   195,   195,   195,   195,   195,
+     196,   196,   197,   197,   198,   198,   199,   200,   200,   200,
+     200,   200,   201,   201,   201,   201,   201,   201,   201,   201,
+     201,   201,   201,   201,   201,   201,   201,   202,   203,   203,
+     203,   204,   205,   205,   206,   206,   206,   206,   207,   207,
+     208,   208,   208,   208,   209,   209,   209,   209,   209,   209,
+     209,   209,   209,   209,   209,   209,   209,   209,   209,   209,
+     209,   209,   209,   209,   209,   209,   209,   209,   209,   209,
+     209,   209,   209,   209,   209,   209,   209,   209,   209,   209,
+     209,   209,   209,   209,   209,   209,   209,   209,   209,   209,
+     209,   209,   209,   209,   209,   209,   209,   209,   209,   209,
+     209,   209,   209,   209,   209,   209,   209,   211,   210,   212,
+     210,   213,   213,   214,   214,   215,   215,   216,   216,   217,
+     218,   219,   219,   220,   220,   220,   220,   220,   220,   220,
+     221,   222,   223,   221,   224,   224,   226,   225,   227,   225,
+     228,   228,   229,   229,   230,   230,   231,   232,   232,   234,
+     233,   235,   235,   236,   236,   238,   237,   239,   237,   240,
+     237,   241,   241,   242,   242,   243,   243,   244,   244,   244,
+     244,   244,   245,   245,   246,   246,   248,   247
 };
 
   /* YYR2[YYN] -- Number of symbols on the right hand side of rule YYN.  */
 static const yytype_uint8 yyr2[] =
 {
        0,     2,     1,     1,     1,     1,     1,     1,     1,     1,
        1,     3,     1,     4,     1,     3,     2,     2,     1,     1,
        1,     3,     2,     2,     2,     1,     2,     3,     2,     1,
        1,     1,     1,     2,     2,     2,     1,     1,     1,     1,
        1,     3,     3,     3,     1,     3,     3,     1,     3,     3,
        1,     3,     3,     3,     3,     1,     3,     3,     1,     3,
        1,     3,     1,     3,     1,     3,     1,     3,     1,     3,
        1,     5,     1,     3,     1,     1,     1,     1,     1,     1,
        1,     1,     1,     1,     1,     1,     3,     1,     2,     2,
        2,     4,     5,     6,     9,     2,     3,     2,     1,     1,
-       2,     3,     3,     2,     5,     2,     1,     2,     1,     1,
-       1,     3,     6,     7,     8,     5,     1,     2,     5,     6,
-       7,     4,     1,     2,     1,     1,     1,     2,     1,     1,
+       2,     3,     3,     2,     3,     2,     1,     2,     1,     1,
+       1,     3,     4,     6,     5,     1,     2,     3,     5,     4,
+       1,     2,     1,     1,     1,     2,     1,     1,     1,     1,
        1,     1,     1,     1,     1,     1,     1,     1,     1,     1,
        1,     1,     1,     1,     1,     1,     1,     1,     1,     1,
-       1,     1,     1,     4,     1,     3,     1,     3,     3,     1,
-       1,     3,     4,     1,     1,     1,     1,     1,     1,     1,
+       1,     4,     1,     3,     1,     3,     3,     1,     1,     2,
+       2,     3,     3,     4,     1,     1,     1,     1,     1,     1,
        1,     1,     1,     1,     1,     1,     1,     1,     1,     1,
        1,     1,     1,     1,     1,     1,     1,     1,     1,     1,
        1,     1,     1,     1,     1,     1,     1,     1,     1,     1,
        1,     1,     1,     1,     1,     1,     1,     1,     1,     1,
        1,     1,     1,     1,     1,     1,     1,     1,     1,     1,
-       1,     1,     1,     1,     1,     1,     0,     6,     0,     5,
-       1,     2,     3,     4,     1,     3,     1,     4,     1,     1,
-       1,     1,     1,     1,     1,     1,     1,     1,     1,     2,
-       0,     0,     5,     1,     1,     0,     2,     0,     2,     2,
-       3,     1,     2,     1,     2,     5,     3,     1,     0,     6,
-       3,     2,     1,     4,     0,     6,     0,     8,     0,     7,
-       1,     1,     1,     0,     2,     3,     2,     2,     2,     3,
-       2,     1,     2,     1,     1,     0,     3
+       1,     1,     1,     1,     1,     1,     1,     0,     6,     0,
+       5,     1,     2,     3,     4,     1,     3,     1,     2,     1,
+       1,     1,     1,     1,     1,     1,     1,     1,     1,     1,
+       2,     0,     0,     5,     1,     1,     0,     2,     0,     2,
+       2,     3,     1,     2,     1,     2,     5,     3,     1,     0,
+       6,     3,     2,     1,     4,     0,     6,     0,     8,     0,
+       7,     1,     1,     1,     0,     2,     3,     2,     2,     2,
+       3,     2,     1,     2,     1,     1,     0,     3
 };
 
 
 #define yyerrok         (yyerrstatus = 0)
 #define yyclearin       (yychar = YYEMPTY)
 #define YYEMPTY         (-2)
 #define YYEOF           0
 
@@ -2581,17 +2552,18 @@ yyreduce:
         (yyval.interm.intermTypedNode) = context->addScalarLiteral(unionArray, (yylsp[0]));
     }
 
     break;
 
   case 10:
 
     {
-        if (!context->isExtensionEnabled(TExtension::EXT_YUV_target)) {
+        if (!context->checkCanUseExtension((yylsp[0]), TExtension::EXT_YUV_target))
+        {
            context->error((yylsp[0]), "unsupported value", (yyvsp[0].lex).string->c_str());
         }
         TConstantUnion *unionArray = new TConstantUnion[1];
         unionArray->setYuvCscStandardEXTConst(getYuvCscStandardEXT((yyvsp[0].lex).string->c_str()));
         (yyval.interm.intermTypedNode) = context->addScalarLiteral(unionArray, (yylsp[0]));
     }
 
     break;
@@ -3345,17 +3317,17 @@ yyreduce:
         (yyval.interm.param) = context->parseParameterDeclarator((yyvsp[-1].interm.type), (yyvsp[0].lex).string, (yylsp[0]));
     }
 
     break;
 
   case 104:
 
     {
-        (yyval.interm.param) = context->parseParameterArrayDeclarator((yyvsp[-3].lex).string, (yylsp[-3]), (yyvsp[-1].interm.intermTypedNode), (yylsp[-2]), &(yyvsp[-4].interm.type));
+        (yyval.interm.param) = context->parseParameterArrayDeclarator((yyvsp[-1].lex).string, (yylsp[-1]), *((yyvsp[0].interm.arraySizes)), (yylsp[0]), &(yyvsp[-2].interm.type));
     }
 
     break;
 
   case 105:
 
     {
         (yyval.interm.param) = (yyvsp[0].interm.param);
@@ -3415,875 +3387,887 @@ yyreduce:
         context->parseDeclarator((yyval.interm).type, (yylsp[0]), *(yyvsp[0].lex).string, (yyval.interm).intermDeclaration);
     }
 
     break;
 
   case 112:
 
     {
-        (yyval.interm) = (yyvsp[-5].interm);
-        context->parseArrayDeclarator((yyval.interm).type, (yylsp[-3]), *(yyvsp[-3].lex).string, (yylsp[-2]), (yyvsp[-1].interm.intermTypedNode), (yyval.interm).intermDeclaration);
+        (yyval.interm) = (yyvsp[-3].interm);
+        context->parseArrayDeclarator((yyval.interm).type, (yylsp[-1]), *(yyvsp[-1].lex).string, (yylsp[0]), *((yyvsp[0].interm.arraySizes)), (yyval.interm).intermDeclaration);
     }
 
     break;
 
   case 113:
 
     {
-        ES3_OR_NEWER("[]", (yylsp[-4]), "implicitly sized array");
-        (yyval.interm) = (yyvsp[-6].interm);
-        context->parseArrayInitDeclarator((yyval.interm).type, (yylsp[-4]), *(yyvsp[-4].lex).string, (yylsp[-3]), nullptr, (yylsp[-1]), (yyvsp[0].interm.intermTypedNode), (yyval.interm).intermDeclaration);
+        ES3_OR_NEWER("=", (yylsp[-1]), "first-class arrays (array initializer)");
+        (yyval.interm) = (yyvsp[-5].interm);
+        context->parseArrayInitDeclarator((yyval.interm).type, (yylsp[-3]), *(yyvsp[-3].lex).string, (yylsp[-2]), *((yyvsp[-2].interm.arraySizes)), (yylsp[-1]), (yyvsp[0].interm.intermTypedNode), (yyval.interm).intermDeclaration);
     }
 
     break;
 
   case 114:
 
     {
-        ES3_OR_NEWER("=", (yylsp[-1]), "first-class arrays (array initializer)");
-        (yyval.interm) = (yyvsp[-7].interm);
-        context->parseArrayInitDeclarator((yyval.interm).type, (yylsp[-5]), *(yyvsp[-5].lex).string, (yylsp[-4]), (yyvsp[-3].interm.intermTypedNode), (yylsp[-1]), (yyvsp[0].interm.intermTypedNode), (yyval.interm).intermDeclaration);
+        (yyval.interm) = (yyvsp[-4].interm);
+        context->parseInitDeclarator((yyval.interm).type, (yylsp[-2]), *(yyvsp[-2].lex).string, (yylsp[-1]), (yyvsp[0].interm.intermTypedNode), (yyval.interm).intermDeclaration);
     }
 
     break;
 
   case 115:
 
     {
-        (yyval.interm) = (yyvsp[-4].interm);
-        context->parseInitDeclarator((yyval.interm).type, (yylsp[-2]), *(yyvsp[-2].lex).string, (yylsp[-1]), (yyvsp[0].interm.intermTypedNode), (yyval.interm).intermDeclaration);
+        (yyval.interm).type = (yyvsp[0].interm.type);
+        (yyval.interm).intermDeclaration = context->parseSingleDeclaration((yyval.interm).type, (yylsp[0]), "");
     }
 
     break;
 
   case 116:
 
     {
-        (yyval.interm).type = (yyvsp[0].interm.type);
-        (yyval.interm).intermDeclaration = context->parseSingleDeclaration((yyval.interm).type, (yylsp[0]), "");
+        (yyval.interm).type = (yyvsp[-1].interm.type);
+        (yyval.interm).intermDeclaration = context->parseSingleDeclaration((yyval.interm).type, (yylsp[0]), *(yyvsp[0].lex).string);
     }
 
     break;
 
   case 117:
 
     {
-        (yyval.interm).type = (yyvsp[-1].interm.type);
-        (yyval.interm).intermDeclaration = context->parseSingleDeclaration((yyval.interm).type, (yylsp[0]), *(yyvsp[0].lex).string);
+        (yyval.interm).type = (yyvsp[-2].interm.type);
+        (yyval.interm).intermDeclaration = context->parseSingleArrayDeclaration((yyval.interm).type, (yylsp[-1]), *(yyvsp[-1].lex).string, (yylsp[0]), *((yyvsp[0].interm.arraySizes)));
     }
 
     break;
 
   case 118:
 
     {
+        ES3_OR_NEWER("[]", (yylsp[-2]), "first-class arrays (array initializer)");
         (yyval.interm).type = (yyvsp[-4].interm.type);
-        (yyval.interm).intermDeclaration = context->parseSingleArrayDeclaration((yyval.interm).type, (yylsp[-3]), *(yyvsp[-3].lex).string, (yylsp[-2]), (yyvsp[-1].interm.intermTypedNode));
+        (yyval.interm).intermDeclaration = context->parseSingleArrayInitDeclaration((yyval.interm).type, (yylsp[-3]), *(yyvsp[-3].lex).string, (yylsp[-2]), *((yyvsp[-2].interm.arraySizes)), (yylsp[-1]), (yyvsp[0].interm.intermTypedNode));
     }
 
     break;
 
   case 119:
 
     {
-        ES3_OR_NEWER("[]", (yylsp[-3]), "implicitly sized array");
-        (yyval.interm).type = (yyvsp[-5].interm.type);
-        (yyval.interm).intermDeclaration = context->parseSingleArrayInitDeclaration((yyval.interm).type, (yylsp[-4]), *(yyvsp[-4].lex).string, (yylsp[-3]), nullptr, (yylsp[-1]), (yyvsp[0].interm.intermTypedNode));
+        (yyval.interm).type = (yyvsp[-3].interm.type);
+        (yyval.interm).intermDeclaration = context->parseSingleInitDeclaration((yyval.interm).type, (yylsp[-2]), *(yyvsp[-2].lex).string, (yylsp[-1]), (yyvsp[0].interm.intermTypedNode));
     }
 
     break;
 
   case 120:
 
     {
-        ES3_OR_NEWER("=", (yylsp[-1]), "first-class arrays (array initializer)");
-        (yyval.interm).type = (yyvsp[-6].interm.type);
-        (yyval.interm).intermDeclaration = context->parseSingleArrayInitDeclaration((yyval.interm).type, (yylsp[-5]), *(yyvsp[-5].lex).string, (yylsp[-4]), (yyvsp[-3].interm.intermTypedNode), (yylsp[-1]), (yyvsp[0].interm.intermTypedNode));
+        context->addFullySpecifiedType(&(yyvsp[0].interm.type));
+        (yyval.interm.type) = (yyvsp[0].interm.type);
     }
 
     break;
 
   case 121:
 
     {
-        (yyval.interm).type = (yyvsp[-3].interm.type);
-        (yyval.interm).intermDeclaration = context->parseSingleInitDeclaration((yyval.interm).type, (yylsp[-2]), *(yyvsp[-2].lex).string, (yylsp[-1]), (yyvsp[0].interm.intermTypedNode));
+        (yyval.interm.type) = context->addFullySpecifiedType(*(yyvsp[-1].interm.typeQualifierBuilder), (yyvsp[0].interm.type));
     }
 
     break;
 
   case 122:
 
     {
-        context->addFullySpecifiedType(&(yyvsp[0].interm.type));
-        (yyval.interm.type) = (yyvsp[0].interm.type);
+        (yyval.interm.qualifier) = EvqSmooth;
     }
 
     break;
 
   case 123:
 
     {
-        (yyval.interm.type) = context->addFullySpecifiedType(*(yyvsp[-1].interm.typeQualifierBuilder), (yyvsp[0].interm.type));
+        (yyval.interm.qualifier) = EvqFlat;
     }
 
     break;
 
   case 124:
 
     {
-        (yyval.interm.qualifier) = EvqSmooth;
+        (yyval.interm.typeQualifierBuilder) = context->createTypeQualifierBuilder((yylsp[0]));
+        (yyval.interm.typeQualifierBuilder)->appendQualifier((yyvsp[0].interm.qualifierWrapper));
     }
 
     break;
 
   case 125:
 
     {
-        (yyval.interm.qualifier) = EvqFlat;
+        (yyval.interm.typeQualifierBuilder) = (yyvsp[-1].interm.typeQualifierBuilder);
+        (yyval.interm.typeQualifierBuilder)->appendQualifier((yyvsp[0].interm.qualifierWrapper));
     }
 
     break;
 
   case 126:
 
     {
-        (yyval.interm.typeQualifierBuilder) = context->createTypeQualifierBuilder((yylsp[0]));
-        (yyval.interm.typeQualifierBuilder)->appendQualifier((yyvsp[0].interm.qualifierWrapper));
+        // empty
     }
 
     break;
 
   case 127:
 
     {
-        (yyval.interm.typeQualifierBuilder) = (yyvsp[-1].interm.typeQualifierBuilder);
-        (yyval.interm.typeQualifierBuilder)->appendQualifier((yyvsp[0].interm.qualifierWrapper));
+        context->checkLocalVariableConstStorageQualifier(*(yyvsp[0].interm.qualifierWrapper));
+        (yyval.interm.qualifierWrapper) = (yyvsp[0].interm.qualifierWrapper);
     }
 
     break;
 
   case 128:
 
     {
-        // empty
+        context->checkIsAtGlobalLevel((yylsp[0]), "layout");
+        (yyval.interm.qualifierWrapper) = new TLayoutQualifierWrapper((yyvsp[0].interm.layoutQualifier), (yylsp[0]));
     }
 
     break;
 
   case 129:
 
     {
-        context->checkLocalVariableConstStorageQualifier(*(yyvsp[0].interm.qualifierWrapper));
-        (yyval.interm.qualifierWrapper) = (yyvsp[0].interm.qualifierWrapper);
+        (yyval.interm.qualifierWrapper) = new TPrecisionQualifierWrapper((yyvsp[0].interm.precision), (yylsp[0]));
     }
 
     break;
 
   case 130:
 
     {
-        context->checkIsAtGlobalLevel((yylsp[0]), "layout");
-        (yyval.interm.qualifierWrapper) = new TLayoutQualifierWrapper((yyvsp[0].interm.layoutQualifier), (yylsp[0]));
+        (yyval.interm.qualifierWrapper) = new TInterpolationQualifierWrapper((yyvsp[0].interm.qualifier), (yylsp[0]));
     }
 
     break;
 
   case 131:
 
     {
-        (yyval.interm.qualifierWrapper) = new TPrecisionQualifierWrapper((yyvsp[0].interm.precision), (yylsp[0]));
+        context->checkIsAtGlobalLevel((yylsp[0]), "invariant");
+        (yyval.interm.qualifierWrapper) = new TInvariantQualifierWrapper((yylsp[0]));
     }
 
     break;
 
   case 132:
 
     {
-        (yyval.interm.qualifierWrapper) = new TInterpolationQualifierWrapper((yyvsp[0].interm.qualifier), (yylsp[0]));
-    }
-
-    break;
-
-  case 133:
-
-    {
-        context->checkIsAtGlobalLevel((yylsp[0]), "invariant");
-        (yyval.interm.qualifierWrapper) = new TInvariantQualifierWrapper((yylsp[0]));
-    }
-
-    break;
-
-  case 134:
-
-    {
         VERTEX_ONLY("attribute", (yylsp[0]));
         ES2_ONLY("attribute", (yylsp[0]));
         (yyval.interm.qualifierWrapper) = context->parseGlobalStorageQualifier(EvqAttribute, (yylsp[0]));
     }
 
     break;
 
-  case 135:
+  case 133:
 
     {
         ES2_ONLY("varying", (yylsp[0]));
         (yyval.interm.qualifierWrapper) = context->parseVaryingQualifier((yylsp[0]));
     }
 
     break;
 
+  case 134:
+
+    {
+        (yyval.interm.qualifierWrapper) = new TStorageQualifierWrapper(EvqConst, (yylsp[0]));
+    }
+
+    break;
+
+  case 135:
+
+    {
+        (yyval.interm.qualifierWrapper) = context->parseInQualifier((yylsp[0]));
+    }
+
+    break;
+
   case 136:
 
     {
-        (yyval.interm.qualifierWrapper) = new TStorageQualifierWrapper(EvqConst, (yylsp[0]));
+        (yyval.interm.qualifierWrapper) = context->parseOutQualifier((yylsp[0]));
     }
 
     break;
 
   case 137:
 
     {
-        (yyval.interm.qualifierWrapper) = context->parseInQualifier((yylsp[0]));
+        (yyval.interm.qualifierWrapper) = context->parseInOutQualifier((yylsp[0]));
     }
 
     break;
 
   case 138:
 
     {
-        (yyval.interm.qualifierWrapper) = context->parseOutQualifier((yylsp[0]));
+        ES3_OR_NEWER("centroid", (yylsp[0]), "storage qualifier");
+        (yyval.interm.qualifierWrapper) = new TStorageQualifierWrapper(EvqCentroid, (yylsp[0]));
     }
 
     break;
 
   case 139:
 
     {
-        (yyval.interm.qualifierWrapper) = context->parseInOutQualifier((yylsp[0]));
+        (yyval.interm.qualifierWrapper) = context->parseGlobalStorageQualifier(EvqUniform, (yylsp[0]));
     }
 
     break;
 
   case 140:
 
     {
-        ES3_OR_NEWER("centroid", (yylsp[0]), "storage qualifier");
-        (yyval.interm.qualifierWrapper) = new TStorageQualifierWrapper(EvqCentroid, (yylsp[0]));
+        ES3_1_ONLY("buffer", (yylsp[0]), "storage qualifier");
+        (yyval.interm.qualifierWrapper) = context->parseGlobalStorageQualifier(EvqBuffer, (yylsp[0]));
     }
 
     break;
 
   case 141:
 
     {
-        (yyval.interm.qualifierWrapper) = context->parseGlobalStorageQualifier(EvqUniform, (yylsp[0]));
+        (yyval.interm.qualifierWrapper) = new TMemoryQualifierWrapper(EvqReadOnly, (yylsp[0]));
     }
 
     break;
 
   case 142:
 
     {
-        ES3_1_ONLY("buffer", (yylsp[0]), "storage qualifier");
-        (yyval.interm.qualifierWrapper) = context->parseGlobalStorageQualifier(EvqBuffer, (yylsp[0]));
+        (yyval.interm.qualifierWrapper) = new TMemoryQualifierWrapper(EvqWriteOnly, (yylsp[0]));
     }
 
     break;
 
   case 143:
 
     {
-        (yyval.interm.qualifierWrapper) = new TMemoryQualifierWrapper(EvqReadOnly, (yylsp[0]));
+        (yyval.interm.qualifierWrapper) = new TMemoryQualifierWrapper(EvqCoherent, (yylsp[0]));
     }
 
     break;
 
   case 144:
 
     {
-        (yyval.interm.qualifierWrapper) = new TMemoryQualifierWrapper(EvqWriteOnly, (yylsp[0]));
+        (yyval.interm.qualifierWrapper) = new TMemoryQualifierWrapper(EvqRestrict, (yylsp[0]));
     }
 
     break;
 
   case 145:
 
     {
-        (yyval.interm.qualifierWrapper) = new TMemoryQualifierWrapper(EvqCoherent, (yylsp[0]));
+        (yyval.interm.qualifierWrapper) = new TMemoryQualifierWrapper(EvqVolatile, (yylsp[0]));
     }
 
     break;
 
   case 146:
 
     {
-        (yyval.interm.qualifierWrapper) = new TMemoryQualifierWrapper(EvqRestrict, (yylsp[0]));
+        COMPUTE_ONLY("shared", (yylsp[0]));
+        (yyval.interm.qualifierWrapper) = context->parseGlobalStorageQualifier(EvqShared, (yylsp[0]));
     }
 
     break;
 
   case 147:
 
     {
-        (yyval.interm.qualifierWrapper) = new TMemoryQualifierWrapper(EvqVolatile, (yylsp[0]));
+        (yyval.interm.type) = (yyvsp[0].interm.type);
+        (yyval.interm.type).precision = context->symbolTable.getDefaultPrecision((yyvsp[0].interm.type).getBasicType());
     }
 
     break;
 
   case 148:
 
     {
-        COMPUTE_ONLY("shared", (yylsp[0]));
-        (yyval.interm.qualifierWrapper) = context->parseGlobalStorageQualifier(EvqShared, (yylsp[0]));
+        (yyval.interm.precision) = EbpHigh;
     }
 
     break;
 
   case 149:
 
     {
-        (yyval.interm.type) = (yyvsp[0].interm.type);
-        (yyval.interm.type).precision = context->symbolTable.getDefaultPrecision((yyvsp[0].interm.type).getBasicType());
+        (yyval.interm.precision) = EbpMedium;
     }
 
     break;
 
   case 150:
 
     {
-        (yyval.interm.precision) = EbpHigh;
+        (yyval.interm.precision) = EbpLow;
     }
 
     break;
 
   case 151:
 
     {
-        (yyval.interm.precision) = EbpMedium;
+        ES3_OR_NEWER_OR_MULTIVIEW("layout", (yylsp[-3]), "qualifier");
+        (yyval.interm.layoutQualifier) = (yyvsp[-1].interm.layoutQualifier);
     }
 
     break;
 
   case 152:
 
     {
-        (yyval.interm.precision) = EbpLow;
+        (yyval.interm.layoutQualifier) = (yyvsp[0].interm.layoutQualifier);
     }
 
     break;
 
   case 153:
 
     {
-        ES3_OR_NEWER_OR_MULTIVIEW("layout", (yylsp[-3]), "qualifier");
-        (yyval.interm.layoutQualifier) = (yyvsp[-1].interm.layoutQualifier);
+        (yyval.interm.layoutQualifier) = context->joinLayoutQualifiers((yyvsp[-2].interm.layoutQualifier), (yyvsp[0].interm.layoutQualifier), (yylsp[0]));
     }
 
     break;
 
   case 154:
 
     {
-        (yyval.interm.layoutQualifier) = (yyvsp[0].interm.layoutQualifier);
+        (yyval.interm.layoutQualifier) = context->parseLayoutQualifier(*(yyvsp[0].lex).string, (yylsp[0]));
     }
 
     break;
 
   case 155:
 
     {
-        (yyval.interm.layoutQualifier) = context->joinLayoutQualifiers((yyvsp[-2].interm.layoutQualifier), (yyvsp[0].interm.layoutQualifier), (yylsp[0]));
+        (yyval.interm.layoutQualifier) = context->parseLayoutQualifier(*(yyvsp[-2].lex).string, (yylsp[-2]), (yyvsp[0].lex).i, (yylsp[0]));
     }
 
     break;
 
   case 156:
 
     {
-        (yyval.interm.layoutQualifier) = context->parseLayoutQualifier(*(yyvsp[0].lex).string, (yylsp[0]));
+        (yyval.interm.layoutQualifier) = context->parseLayoutQualifier(*(yyvsp[-2].lex).string, (yylsp[-2]), (yyvsp[0].lex).i, (yylsp[0]));
     }
 
     break;
 
   case 157:
 
     {
-        (yyval.interm.layoutQualifier) = context->parseLayoutQualifier(*(yyvsp[-2].lex).string, (yylsp[-2]), (yyvsp[0].lex).i, (yylsp[0]));
+        (yyval.interm.layoutQualifier) = context->parseLayoutQualifier("shared", (yylsp[0]));
     }
 
     break;
 
   case 158:
 
     {
-        (yyval.interm.layoutQualifier) = context->parseLayoutQualifier(*(yyvsp[-2].lex).string, (yylsp[-2]), (yyvsp[0].lex).i, (yylsp[0]));
+        (yyval.interm.type).initialize((yyvsp[0].interm.typeSpecifierNonArray), (context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary));
     }
 
     break;
 
   case 159:
 
     {
-        (yyval.interm.layoutQualifier) = context->parseLayoutQualifier("shared", (yylsp[0]));
+        (yyval.interm.type).initialize((yyvsp[-1].interm.typeSpecifierNonArray), (context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary));
+        (yyval.interm.type).setArraySizes((yyvsp[0].interm.arraySizes));
     }
 
     break;
 
   case 160:
 
     {
-        (yyval.interm.type).initialize((yyvsp[0].interm.typeSpecifierNonArray), (context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary));
+        ES3_OR_NEWER("[]", (yylsp[-1]), "implicitly sized array");
+        (yyval.interm.arraySizes) = new TVector<unsigned int>();
+        (yyval.interm.arraySizes)->push_back(0u);
     }
 
     break;
 
   case 161:
 
     {
-        ES3_OR_NEWER("[]", (yylsp[-1]), "implicitly sized array");
-        (yyval.interm.type).initialize((yyvsp[-2].interm.typeSpecifierNonArray), (context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary));
-        (yyval.interm.type).setArraySize(0);
+        (yyval.interm.arraySizes) = new TVector<unsigned int>();
+        unsigned int size = context->checkIsValidArraySize((yylsp[-2]), (yyvsp[-1].interm.intermTypedNode));
+        // Make the type an array even if size check failed.
+        // This ensures useless error messages regarding a variable's non-arrayness won't follow.
+        (yyval.interm.arraySizes)->push_back(size);
     }
 
     break;
 
   case 162:
 
     {
-        (yyval.interm.type).initialize((yyvsp[-3].interm.typeSpecifierNonArray), (context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary));
-        unsigned int size = context->checkIsValidArraySize((yylsp[-2]), (yyvsp[-1].interm.intermTypedNode));
-        (yyval.interm.type).setArraySize(size);
+        ES3_1_ONLY("[]", (yylsp[-1]), "arrays of arrays");
+        (yyval.interm.arraySizes) = (yyvsp[-2].interm.arraySizes);
+        (yyval.interm.arraySizes)->insert((yyval.interm.arraySizes)->begin(), 0u);
     }
 
     break;
 
   case 163:
 
     {
-        (yyval.interm.typeSpecifierNonArray).initialize(EbtVoid, (yylsp[0]));
+        ES3_1_ONLY("[]", (yylsp[-2]), "arrays of arrays");
+        (yyval.interm.arraySizes) = (yyvsp[-3].interm.arraySizes);
+        unsigned int size = context->checkIsValidArraySize((yylsp[-2]), (yyvsp[-1].interm.intermTypedNode));
+        // Make the type an array even if size check failed.
+        // This ensures useless error messages regarding a variable's non-arrayness won't follow.
+        (yyval.interm.arraySizes)->insert((yyval.interm.arraySizes)->begin(), size);
     }
 
     break;
 
   case 164:
 
     {
-        (yyval.interm.typeSpecifierNonArray).initialize(EbtFloat, (yylsp[0]));
+        (yyval.interm.typeSpecifierNonArray).initialize(EbtVoid, (yylsp[0]));
     }
 
     break;
 
   case 165:
 
     {
-        (yyval.interm.typeSpecifierNonArray).initialize(EbtInt, (yylsp[0]));
+        (yyval.interm.typeSpecifierNonArray).initialize(EbtFloat, (yylsp[0]));
     }
 
     break;
 
   case 166:
 
     {
-        (yyval.interm.typeSpecifierNonArray).initialize(EbtUInt, (yylsp[0]));
+        (yyval.interm.typeSpecifierNonArray).initialize(EbtInt, (yylsp[0]));
     }
 
     break;
 
   case 167:
 
     {
-        (yyval.interm.typeSpecifierNonArray).initialize(EbtBool, (yylsp[0]));
+        (yyval.interm.typeSpecifierNonArray).initialize(EbtUInt, (yylsp[0]));
     }
 
     break;
 
   case 168:
 
     {
-        (yyval.interm.typeSpecifierNonArray).initialize(EbtFloat, (yylsp[0]));
-        (yyval.interm.typeSpecifierNonArray).setAggregate(2);
+        (yyval.interm.typeSpecifierNonArray).initialize(EbtBool, (yylsp[0]));
     }
 
     break;
 
   case 169:
 
     {
         (yyval.interm.typeSpecifierNonArray).initialize(EbtFloat, (yylsp[0]));
-        (yyval.interm.typeSpecifierNonArray).setAggregate(3);
+        (yyval.interm.typeSpecifierNonArray).setAggregate(2);
     }
 
     break;
 
   case 170:
 
     {
         (yyval.interm.typeSpecifierNonArray).initialize(EbtFloat, (yylsp[0]));
-        (yyval.interm.typeSpecifierNonArray).setAggregate(4);
+        (yyval.interm.typeSpecifierNonArray).setAggregate(3);
     }
 
     break;
 
   case 171:
 
     {
-        (yyval.interm.typeSpecifierNonArray).initialize(EbtBool, (yylsp[0]));
-        (yyval.interm.typeSpecifierNonArray).setAggregate(2);
+        (yyval.interm.typeSpecifierNonArray).initialize(EbtFloat, (yylsp[0]));
+        (yyval.interm.typeSpecifierNonArray).setAggregate(4);
     }
 
     break;
 
   case 172:
 
     {
         (yyval.interm.typeSpecifierNonArray).initialize(EbtBool, (yylsp[0]));
-        (yyval.interm.typeSpecifierNonArray).setAggregate(3);
+        (yyval.interm.typeSpecifierNonArray).setAggregate(2);
     }
 
     break;
 
   case 173:
 
     {
         (yyval.interm.typeSpecifierNonArray).initialize(EbtBool, (yylsp[0]));
-        (yyval.interm.typeSpecifierNonArray).setAggregate(4);
+        (yyval.interm.typeSpecifierNonArray).setAggregate(3);
     }
 
     break;
 
   case 174:
 
     {
-        (yyval.interm.typeSpecifierNonArray).initialize(EbtInt, (yylsp[0]));
-        (yyval.interm.typeSpecifierNonArray).setAggregate(2);
+        (yyval.interm.typeSpecifierNonArray).initialize(EbtBool, (yylsp[0]));
+        (yyval.interm.typeSpecifierNonArray).setAggregate(4);
     }
 
     break;
 
   case 175:
 
     {
         (yyval.interm.typeSpecifierNonArray).initialize(EbtInt, (yylsp[0]));
-        (yyval.interm.typeSpecifierNonArray).setAggregate(3);
+        (yyval.interm.typeSpecifierNonArray).setAggregate(2);
     }
 
     break;
 
   case 176:
 
     {
         (yyval.interm.typeSpecifierNonArray).initialize(EbtInt, (yylsp[0]));
-        (yyval.interm.typeSpecifierNonArray).setAggregate(4);
+        (yyval.interm.typeSpecifierNonArray).setAggregate(3);
     }
 
     break;
 
   case 177:
 
     {
-        (yyval.interm.typeSpecifierNonArray).initialize(EbtUInt, (yylsp[0]));
-        (yyval.interm.typeSpecifierNonArray).setAggregate(2);
+        (yyval.interm.typeSpecifierNonArray).initialize(EbtInt, (yylsp[0]));
+        (yyval.interm.typeSpecifierNonArray).setAggregate(4);
     }
 
     break;
 
   case 178:
 
     {
         (yyval.interm.typeSpecifierNonArray).initialize(EbtUInt, (yylsp[0]));
-        (yyval.interm.typeSpecifierNonArray).setAggregate(3);
+        (yyval.interm.typeSpecifierNonArray).setAggregate(2);
     }
 
     break;
 
   case 179:
 
     {
         (yyval.interm.typeSpecifierNonArray).initialize(EbtUInt, (yylsp[0]));
-        (yyval.interm.typeSpecifierNonArray).setAggregate(4);
+        (yyval.interm.typeSpecifierNonArray).setAggregate(3);
     }
 
     break;
 
   case 180:
 
     {
-        (yyval.interm.typeSpecifierNonArray).initialize(EbtFloat, (yylsp[0]));
-        (yyval.interm.typeSpecifierNonArray).setMatrix(2, 2);
+        (yyval.interm.typeSpecifierNonArray).initialize(EbtUInt, (yylsp[0]));
+        (yyval.interm.typeSpecifierNonArray).setAggregate(4);
     }
 
     break;
 
   case 181:
 
     {
         (yyval.interm.typeSpecifierNonArray).initialize(EbtFloat, (yylsp[0]));
-        (yyval.interm.typeSpecifierNonArray).setMatrix(3, 3);
+        (yyval.interm.typeSpecifierNonArray).setMatrix(2, 2);
     }
 
     break;
 
   case 182:
 
     {
         (yyval.interm.typeSpecifierNonArray).initialize(EbtFloat, (yylsp[0]));
-        (yyval.interm.typeSpecifierNonArray).setMatrix(4, 4);
+        (yyval.interm.typeSpecifierNonArray).setMatrix(3, 3);
     }
 
     break;
 
   case 183:
 
     {
         (yyval.interm.typeSpecifierNonArray).initialize(EbtFloat, (yylsp[0]));
-        (yyval.interm.typeSpecifierNonArray).setMatrix(2, 3);
+        (yyval.interm.typeSpecifierNonArray).setMatrix(4, 4);
     }
 
     break;
 
   case 184:
 
     {
         (yyval.interm.typeSpecifierNonArray).initialize(EbtFloat, (yylsp[0]));
-        (yyval.interm.typeSpecifierNonArray).setMatrix(3, 2);
+        (yyval.interm.typeSpecifierNonArray).setMatrix(2, 3);
     }
 
     break;
 
   case 185:
 
     {
         (yyval.interm.typeSpecifierNonArray).initialize(EbtFloat, (yylsp[0]));
-        (yyval.interm.typeSpecifierNonArray).setMatrix(2, 4);
+        (yyval.interm.typeSpecifierNonArray).setMatrix(3, 2);
     }
 
     break;
 
   case 186:
 
     {
         (yyval.interm.typeSpecifierNonArray).initialize(EbtFloat, (yylsp[0]));
-        (yyval.interm.typeSpecifierNonArray).setMatrix(4, 2);
+        (yyval.interm.typeSpecifierNonArray).setMatrix(2, 4);
     }
 
     break;
 
   case 187:
 
     {
         (yyval.interm.typeSpecifierNonArray).initialize(EbtFloat, (yylsp[0]));
-        (yyval.interm.typeSpecifierNonArray).setMatrix(3, 4);
+        (yyval.interm.typeSpecifierNonArray).setMatrix(4, 2);
     }
 
     break;
 
   case 188:
 
     {
         (yyval.interm.typeSpecifierNonArray).initialize(EbtFloat, (yylsp[0]));
-        (yyval.interm.typeSpecifierNonArray).setMatrix(4, 3);
+        (yyval.interm.typeSpecifierNonArray).setMatrix(3, 4);
     }
 
     break;
 
   case 189:
 
     {
-        if (!context->isExtensionEnabled(TExtension::EXT_YUV_target)) {
-            context->error((yylsp[0]), "unsupported type", "yuvCscStandardEXT");
-        }
-        (yyval.interm.typeSpecifierNonArray).initialize(EbtYuvCscStandardEXT, (yylsp[0]));
+        (yyval.interm.typeSpecifierNonArray).initialize(EbtFloat, (yylsp[0]));
+        (yyval.interm.typeSpecifierNonArray).setMatrix(4, 3);
     }
 
     break;
 
   case 190:
 
     {
-        (yyval.interm.typeSpecifierNonArray).initialize(EbtSampler2D, (yylsp[0]));
+        if (!context->checkCanUseExtension((yylsp[0]), TExtension::EXT_YUV_target))
+        {
+            context->error((yylsp[0]), "unsupported type", "yuvCscStandardEXT");
+        }
+        (yyval.interm.typeSpecifierNonArray).initialize(EbtYuvCscStandardEXT, (yylsp[0]));
     }
 
     break;
 
   case 191:
 
     {
-        (yyval.interm.typeSpecifierNonArray).initialize(EbtSampler3D, (yylsp[0]));
+        (yyval.interm.typeSpecifierNonArray).initialize(EbtSampler2D, (yylsp[0]));
     }
 
     break;
 
   case 192:
 
     {
-        (yyval.interm.typeSpecifierNonArray).initialize(EbtSamplerCube, (yylsp[0]));
+        (yyval.interm.typeSpecifierNonArray).initialize(EbtSampler3D, (yylsp[0]));
     }
 
     break;
 
   case 193:
 
     {
-        (yyval.interm.typeSpecifierNonArray).initialize(EbtSampler2DArray, (yylsp[0]));
+        (yyval.interm.typeSpecifierNonArray).initialize(EbtSamplerCube, (yylsp[0]));
     }
 
     break;
 
   case 194:
 
     {
-        (yyval.interm.typeSpecifierNonArray).initialize(EbtSampler2DMS, (yylsp[0]));
+        (yyval.interm.typeSpecifierNonArray).initialize(EbtSampler2DArray, (yylsp[0]));
     }
 
     break;
 
   case 195:
 
     {
-        (yyval.interm.typeSpecifierNonArray).initialize(EbtISampler2D, (yylsp[0]));
+        (yyval.interm.typeSpecifierNonArray).initialize(EbtSampler2DMS, (yylsp[0]));
     }
 
     break;
 
   case 196:
 
     {
-        (yyval.interm.typeSpecifierNonArray).initialize(EbtISampler3D, (yylsp[0]));
+        (yyval.interm.typeSpecifierNonArray).initialize(EbtISampler2D, (yylsp[0]));
     }
 
     break;
 
   case 197:
 
     {
-        (yyval.interm.typeSpecifierNonArray).initialize(EbtISamplerCube, (yylsp[0]));
+        (yyval.interm.typeSpecifierNonArray).initialize(EbtISampler3D, (yylsp[0]));
     }
 
     break;
 
   case 198:
 
     {
-        (yyval.interm.typeSpecifierNonArray).initialize(EbtISampler2DArray, (yylsp[0]));
+        (yyval.interm.typeSpecifierNonArray).initialize(EbtISamplerCube, (yylsp[0]));
     }
 
     break;
 
   case 199:
 
     {
-        (yyval.interm.typeSpecifierNonArray).initialize(EbtISampler2DMS, (yylsp[0]));
+        (yyval.interm.typeSpecifierNonArray).initialize(EbtISampler2DArray, (yylsp[0]));
     }
 
     break;
 
   case 200:
 
     {
-        (yyval.interm.typeSpecifierNonArray).initialize(EbtUSampler2D, (yylsp[0]));
+        (yyval.interm.typeSpecifierNonArray).initialize(EbtISampler2DMS, (yylsp[0]));
     }
 
     break;
 
   case 201:
 
     {
-        (yyval.interm.typeSpecifierNonArray).initialize(EbtUSampler3D, (yylsp[0]));
+        (yyval.interm.typeSpecifierNonArray).initialize(EbtUSampler2D, (yylsp[0]));
     }
 
     break;
 
   case 202:
 
     {
-        (yyval.interm.typeSpecifierNonArray).initialize(EbtUSamplerCube, (yylsp[0]));
+        (yyval.interm.typeSpecifierNonArray).initialize(EbtUSampler3D, (yylsp[0]));
     }
 
     break;
 
   case 203:
 
     {
-        (yyval.interm.typeSpecifierNonArray).initialize(EbtUSampler2DArray, (yylsp[0]));
+        (yyval.interm.typeSpecifierNonArray).initialize(EbtUSamplerCube, (yylsp[0]));
     }
 
     break;
 
   case 204:
 
     {
-        (yyval.interm.typeSpecifierNonArray).initialize(EbtUSampler2DMS, (yylsp[0]));
+        (yyval.interm.typeSpecifierNonArray).initialize(EbtUSampler2DArray, (yylsp[0]));
     }
 
     break;
 
   case 205:
 
     {
-        (yyval.interm.typeSpecifierNonArray).initialize(EbtSampler2DShadow, (yylsp[0]));
+        (yyval.interm.typeSpecifierNonArray).initialize(EbtUSampler2DMS, (yylsp[0]));
     }
 
     break;
 
   case 206:
 
     {
-        (yyval.interm.typeSpecifierNonArray).initialize(EbtSamplerCubeShadow, (yylsp[0]));
+        (yyval.interm.typeSpecifierNonArray).initialize(EbtSampler2DShadow, (yylsp[0]));
     }
 
     break;
 
   case 207:
 
     {
-        (yyval.interm.typeSpecifierNonArray).initialize(EbtSampler2DArrayShadow, (yylsp[0]));
+        (yyval.interm.typeSpecifierNonArray).initialize(EbtSamplerCubeShadow, (yylsp[0]));
     }
 
     break;
 
   case 208:
 
     {
-        if (!context->supportsExtension(TExtension::OES_EGL_image_external) &&
-            !context->supportsExtension(TExtension::NV_EGL_stream_consumer_external)) {
-            context->error((yylsp[0]), "unsupported type", "samplerExternalOES");
-        }
-        (yyval.interm.typeSpecifierNonArray).initialize(EbtSamplerExternalOES, (yylsp[0]));
+        (yyval.interm.typeSpecifierNonArray).initialize(EbtSampler2DArrayShadow, (yylsp[0]));
     }
 
     break;
 
   case 209:
 
     {
-        if (!context->isExtensionEnabled(TExtension::EXT_YUV_target)) {
-            context->error((yylsp[0]), "unsupported type", "__samplerExternal2DY2YEXT");
+        constexpr std::array<TExtension, 3u> extensions{ { TExtension::NV_EGL_stream_consumer_external,
+                                                           TExtension::OES_EGL_image_external_essl3,
+                                                           TExtension::OES_EGL_image_external } };
+        if (!context->checkCanUseOneOfExtensions((yylsp[0]), extensions))
+        {
+            context->error((yylsp[0]), "unsupported type", "samplerExternalOES");
         }
-        (yyval.interm.typeSpecifierNonArray).initialize(EbtSamplerExternal2DY2YEXT, (yylsp[0]));
+        (yyval.interm.typeSpecifierNonArray).initialize(EbtSamplerExternalOES, (yylsp[0]));
     }
 
     break;
 
   case 210:
 
     {
-        if (!context->supportsExtension(TExtension::ARB_texture_rectangle)) {
-            context->error((yylsp[0]), "unsupported type", "sampler2DRect");
+        if (!context->checkCanUseExtension((yylsp[0]), TExtension::EXT_YUV_target))
+        {
+            context->error((yylsp[0]), "unsupported type", "__samplerExternal2DY2YEXT");
         }
-        (yyval.interm.typeSpecifierNonArray).initialize(EbtSampler2DRect, (yylsp[0]));
+        (yyval.interm.typeSpecifierNonArray).initialize(EbtSamplerExternal2DY2YEXT, (yylsp[0]));
     }
 
     break;
 
   case 211:
 
     {
-        (yyval.interm.typeSpecifierNonArray) = (yyvsp[0].interm.typeSpecifierNonArray);
+        if (!context->checkCanUseExtension((yylsp[0]), TExtension::ARB_texture_rectangle))
+        {
+            context->error((yylsp[0]), "unsupported type", "sampler2DRect");
+        }
+        (yyval.interm.typeSpecifierNonArray).initialize(EbtSampler2DRect, (yylsp[0]));
     }
 
     break;
 
   case 212:
 
     {
         (yyval.interm.typeSpecifierNonArray).initialize(EbtImage2D, (yylsp[0]));
@@ -4385,138 +4369,140 @@ yyreduce:
         (yyval.interm.typeSpecifierNonArray).initialize(EbtAtomicCounter, (yylsp[0]));
     }
 
     break;
 
   case 225:
 
     {
-        // This is for user defined type names. The lexical phase looked up the type.
-        TType& structure = static_cast<TVariable*>((yyvsp[0].lex).symbol)->getType();
-        (yyval.interm.typeSpecifierNonArray).initializeStruct(structure.getStruct(), false, (yylsp[0]));
+        (yyval.interm.typeSpecifierNonArray) = (yyvsp[0].interm.typeSpecifierNonArray);
     }
 
     break;
 
   case 226:
 
-    { context->enterStructDeclaration((yylsp[-1]), *(yyvsp[-1].lex).string); }
+    {
+        // This is for user defined type names. The lexical phase looked up the type.
+        TStructure *structure = static_cast<TStructure*>((yyvsp[0].lex).symbol);
+        (yyval.interm.typeSpecifierNonArray).initializeStruct(structure, false, (yylsp[0]));
+    }
 
     break;
 
   case 227:
 
-    {
-        (yyval.interm.typeSpecifierNonArray) = context->addStructure((yylsp[-5]), (yylsp[-4]), (yyvsp[-4].lex).string, (yyvsp[-1].interm.fieldList));
-    }
+    { context->enterStructDeclaration((yylsp[-1]), *(yyvsp[-1].lex).string); }
 
     break;
 
   case 228:
 
-    { context->enterStructDeclaration((yylsp[0]), *(yyvsp[0].lex).string); }
+    {
+        (yyval.interm.typeSpecifierNonArray) = context->addStructure((yylsp[-5]), (yylsp[-4]), (yyvsp[-4].lex).string, (yyvsp[-1].interm.fieldList));
+    }
 
     break;
 
   case 229:
 
-    {
-        (yyval.interm.typeSpecifierNonArray) = context->addStructure((yylsp[-4]), (yyloc), NewPoolTString(""), (yyvsp[-1].interm.fieldList));
-    }
+    { context->enterStructDeclaration((yylsp[0]), *(yyvsp[0].lex).string); }
 
     break;
 
   case 230:
 
     {
-        (yyval.interm.fieldList) = (yyvsp[0].interm.fieldList);
+        (yyval.interm.typeSpecifierNonArray) = context->addStructure((yylsp[-4]), (yyloc), nullptr, (yyvsp[-1].interm.fieldList));
     }
 
     break;
 
   case 231:
 
     {
-        (yyval.interm.fieldList) = context->combineStructFieldLists((yyvsp[-1].interm.fieldList), (yyvsp[0].interm.fieldList), (yylsp[0]));
+        (yyval.interm.fieldList) = context->addStructFieldList((yyvsp[0].interm.fieldList), (yylsp[0]));
     }
 
     break;
 
   case 232:
 
     {
-        (yyval.interm.fieldList) = context->addStructDeclaratorList((yyvsp[-2].interm.type), (yyvsp[-1].interm.fieldList));
+        (yyval.interm.fieldList) = context->combineStructFieldLists((yyvsp[-1].interm.fieldList), (yyvsp[0].interm.fieldList), (yylsp[0]));
     }
 
     break;
 
   case 233:
 
     {
-        // ES3 Only, but errors should be handled elsewhere
-        (yyval.interm.fieldList) = context->addStructDeclaratorListWithQualifiers(*(yyvsp[-3].interm.typeQualifierBuilder), &(yyvsp[-2].interm.type), (yyvsp[-1].interm.fieldList));
+        (yyval.interm.fieldList) = context->addStructDeclaratorList((yyvsp[-2].interm.type), (yyvsp[-1].interm.declaratorList));
     }
 
     break;
 
   case 234:
 
     {
-        (yyval.interm.fieldList) = NewPoolTFieldList();
-        (yyval.interm.fieldList)->push_back((yyvsp[0].interm.field));
+        // ES3 Only, but errors should be handled elsewhere
+        (yyval.interm.fieldList) = context->addStructDeclaratorListWithQualifiers(*(yyvsp[-3].interm.typeQualifierBuilder), &(yyvsp[-2].interm.type), (yyvsp[-1].interm.declaratorList));
     }
 
     break;
 
   case 235:
 
     {
-        (yyval.interm.fieldList)->push_back((yyvsp[0].interm.field));
+        (yyval.interm.declaratorList) = new TDeclaratorList();
+        (yyval.interm.declaratorList)->push_back((yyvsp[0].interm.declarator));
     }
 
     break;
 
   case 236:
 
     {
-        (yyval.interm.field) = context->parseStructDeclarator((yyvsp[0].lex).string, (yylsp[0]));
+        (yyval.interm.declaratorList)->push_back((yyvsp[0].interm.declarator));
     }
 
     break;
 
   case 237:
 
     {
-        (yyval.interm.field) = context->parseStructArrayDeclarator((yyvsp[-3].lex).string, (yylsp[-3]), (yyvsp[-1].interm.intermTypedNode), (yylsp[-1]));
+        (yyval.interm.declarator) = context->parseStructDeclarator((yyvsp[0].lex).string, (yylsp[0]));
     }
 
     break;
 
   case 238:
 
-    { (yyval.interm.intermTypedNode) = (yyvsp[0].interm.intermTypedNode); }
+    {
+        (yyval.interm.declarator) = context->parseStructArrayDeclarator((yyvsp[-1].lex).string, (yylsp[-1]), (yyvsp[0].interm.arraySizes));
+    }
 
     break;
 
   case 239:
 
-    { (yyval.interm.intermNode) = (yyvsp[0].interm.intermNode); }
+    { (yyval.interm.intermTypedNode) = (yyvsp[0].interm.intermTypedNode); }
 
     break;
 
   case 240:
 
-    { (yyval.interm.intermNode) = (yyvsp[0].interm.intermBlock); }
+    { (yyval.interm.intermNode) = (yyvsp[0].interm.intermNode); }
 
     break;
 
   case 241:
 
-    { (yyval.interm.intermNode) = (yyvsp[0].interm.intermNode); }
+    { (yyval.interm.intermNode) = (yyvsp[0].interm.intermBlock); }
 
     break;
 
   case 242:
 
     { (yyval.interm.intermNode) = (yyvsp[0].interm.intermNode); }
 
     break;
@@ -4530,277 +4516,279 @@ yyreduce:
   case 244:
 
     { (yyval.interm.intermNode) = (yyvsp[0].interm.intermNode); }
 
     break;
 
   case 245:
 
-    { (yyval.interm.intermNode) = (yyvsp[0].interm.intermSwitch); }
+    { (yyval.interm.intermNode) = (yyvsp[0].interm.intermNode); }
 
     break;
 
   case 246:
 
-    { (yyval.interm.intermNode) = (yyvsp[0].interm.intermCase); }
+    { (yyval.interm.intermNode) = (yyvsp[0].interm.intermSwitch); }
 
     break;
 
   case 247:
 
-    { (yyval.interm.intermNode) = (yyvsp[0].interm.intermNode); }
+    { (yyval.interm.intermNode) = (yyvsp[0].interm.intermCase); }
 
     break;
 
   case 248:
 
     { (yyval.interm.intermNode) = (yyvsp[0].interm.intermNode); }
 
     break;
 
   case 249:
 
-    { (yyval.interm.intermBlock) = 0; }
+    { (yyval.interm.intermNode) = (yyvsp[0].interm.intermNode); }
 
     break;
 
   case 250:
 
-    { context->symbolTable.push(); }
+    {
+        (yyval.interm.intermBlock) = new TIntermBlock();
+        (yyval.interm.intermBlock)->setLine((yyloc));
+    }
 
     break;
 
   case 251:
 
-    { context->symbolTable.pop(); }
+    { context->symbolTable.push(); }
 
     break;
 
   case 252:
 
-    {
-        (yyvsp[-2].interm.intermBlock)->setLine((yyloc));
-        (yyval.interm.intermBlock) = (yyvsp[-2].interm.intermBlock);
-    }
+    { context->symbolTable.pop(); }
 
     break;
 
   case 253:
 
-    { (yyval.interm.intermNode) = (yyvsp[0].interm.intermBlock); }
+    {
+        (yyvsp[-2].interm.intermBlock)->setLine((yyloc));
+        (yyval.interm.intermBlock) = (yyvsp[-2].interm.intermBlock);
+    }
 
     break;
 
   case 254:
 
-    { (yyval.interm.intermNode) = (yyvsp[0].interm.intermNode); }
+    { (yyval.interm.intermNode) = (yyvsp[0].interm.intermBlock); }
 
     break;
 
   case 255:
 
-    { context->symbolTable.push(); }
+    { (yyval.interm.intermNode) = (yyvsp[0].interm.intermNode); }
 
     break;
 
   case 256:
 
-    { context->symbolTable.pop(); (yyval.interm.intermNode) = (yyvsp[0].interm.intermBlock); }
+    { context->symbolTable.push(); }
 
     break;
 
   case 257:
 
-    { context->symbolTable.push(); }
+    { context->symbolTable.pop(); (yyval.interm.intermNode) = (yyvsp[0].interm.intermBlock); }
 
     break;
 
   case 258:
 
-    { context->symbolTable.pop(); (yyval.interm.intermNode) = (yyvsp[0].interm.intermNode); }
+    { context->symbolTable.push(); }
 
     break;
 
   case 259:
 
-    {
-        (yyval.interm.intermBlock) = nullptr;
-    }
+    { context->symbolTable.pop(); (yyval.interm.intermNode) = (yyvsp[0].interm.intermNode); }
 
     break;
 
   case 260:
 
     {
-        (yyvsp[-1].interm.intermBlock)->setLine((yyloc));
-        (yyval.interm.intermBlock) = (yyvsp[-1].interm.intermBlock);
+        (yyval.interm.intermBlock) = new TIntermBlock();
+        (yyval.interm.intermBlock)->setLine((yyloc));
     }
 
     break;
 
   case 261:
 
     {
-        (yyval.interm.intermBlock) = new TIntermBlock();
-        (yyval.interm.intermBlock)->appendStatement((yyvsp[0].interm.intermNode));
+        (yyvsp[-1].interm.intermBlock)->setLine((yyloc));
+        (yyval.interm.intermBlock) = (yyvsp[-1].interm.intermBlock);
     }
 
     break;
 
   case 262:
 
     {
-        (yyval.interm.intermBlock) = (yyvsp[-1].interm.intermBlock);
+        (yyval.interm.intermBlock) = new TIntermBlock();
         (yyval.interm.intermBlock)->appendStatement((yyvsp[0].interm.intermNode));
     }
 
     break;
 
   case 263:
 
-    { (yyval.interm.intermNode) = 0; }
+    {
+        (yyval.interm.intermBlock) = (yyvsp[-1].interm.intermBlock);
+        (yyval.interm.intermBlock)->appendStatement((yyvsp[0].interm.intermNode));
+    }
 
     break;
 
   case 264:
 
-    { (yyval.interm.intermNode) = (yyvsp[-1].interm.intermTypedNode); }
+    { (yyval.interm.intermNode) = context->addEmptyStatement((yyloc)); }
 
     break;
 
   case 265:
 
-    {
-        (yyval.interm.intermNode) = context->addIfElse((yyvsp[-2].interm.intermTypedNode), (yyvsp[0].interm.nodePair), (yylsp[-4]));
-    }
+    { (yyval.interm.intermNode) = (yyvsp[-1].interm.intermTypedNode); }
 
     break;
 
   case 266:
 
     {
-        (yyval.interm.nodePair).node1 = (yyvsp[-2].interm.intermNode);
-        (yyval.interm.nodePair).node2 = (yyvsp[0].interm.intermNode);
+        (yyval.interm.intermNode) = context->addIfElse((yyvsp[-2].interm.intermTypedNode), (yyvsp[0].interm.nodePair), (yylsp[-4]));
     }
 
     break;
 
   case 267:
 
     {
-        (yyval.interm.nodePair).node1 = (yyvsp[0].interm.intermNode);
-        (yyval.interm.nodePair).node2 = nullptr;
+        (yyval.interm.nodePair).node1 = (yyvsp[-2].interm.intermNode);
+        (yyval.interm.nodePair).node2 = (yyvsp[0].interm.intermNode);
     }
 
     break;
 
   case 268:
 
-    { context->incrSwitchNestingLevel(); }
+    {
+        (yyval.interm.nodePair).node1 = (yyvsp[0].interm.intermNode);
+        (yyval.interm.nodePair).node2 = nullptr;
+    }
 
     break;
 
   case 269:
 
+    { context->incrSwitchNestingLevel(); }
+
+    break;
+
+  case 270:
+
     {
         (yyval.interm.intermSwitch) = context->addSwitch((yyvsp[-3].interm.intermTypedNode), (yyvsp[0].interm.intermBlock), (yylsp[-5]));
         context->decrSwitchNestingLevel();
     }
 
     break;
 
-  case 270:
-
-    {
-        (yyval.interm.intermCase) = context->addCase((yyvsp[-1].interm.intermTypedNode), (yylsp[-2]));
-    }
-
-    break;
-
   case 271:
 
     {
-        (yyval.interm.intermCase) = context->addDefault((yylsp[-1]));
+        (yyval.interm.intermCase) = context->addCase((yyvsp[-1].interm.intermTypedNode), (yylsp[-2]));
     }
 
     break;
 
   case 272:
 
     {
-        (yyval.interm.intermNode) = (yyvsp[0].interm.intermTypedNode);
-        context->checkIsScalarBool((yyvsp[0].interm.intermTypedNode)->getLine(), (yyvsp[0].interm.intermTypedNode));
+        (yyval.interm.intermCase) = context->addDefault((yylsp[-1]));
     }
 
     break;
 
   case 273:
 
     {
-        (yyval.interm.intermNode) = context->addConditionInitializer((yyvsp[-3].interm.type), *(yyvsp[-2].lex).string, (yyvsp[0].interm.intermTypedNode), (yylsp[-2]));
+        (yyval.interm.intermNode) = (yyvsp[0].interm.intermTypedNode);
+        context->checkIsScalarBool((yyvsp[0].interm.intermTypedNode)->getLine(), (yyvsp[0].interm.intermTypedNode));
     }
 
     break;
 
   case 274:
 
-    { context->symbolTable.push(); context->incrLoopNestingLevel(); }
+    {
+        (yyval.interm.intermNode) = context->addConditionInitializer((yyvsp[-3].interm.type), *(yyvsp[-2].lex).string, (yyvsp[0].interm.intermTypedNode), (yylsp[-2]));
+    }
 
     break;
 
   case 275:
 
+    { context->symbolTable.push(); context->incrLoopNestingLevel(); }
+
+    break;
+
+  case 276:
+
     {
         context->symbolTable.pop();
         (yyval.interm.intermNode) = context->addLoop(ELoopWhile, 0, (yyvsp[-2].interm.intermNode), 0, (yyvsp[0].interm.intermNode), (yylsp[-5]));
         context->decrLoopNestingLevel();
     }
 
     break;
 
-  case 276:
+  case 277:
 
     { context->incrLoopNestingLevel(); }
 
     break;
 
-  case 277:
+  case 278:
 
     {
         (yyval.interm.intermNode) = context->addLoop(ELoopDoWhile, 0, (yyvsp[-2].interm.intermTypedNode), 0, (yyvsp[-5].interm.intermNode), (yylsp[-4]));
         context->decrLoopNestingLevel();
     }
 
     break;
 
-  case 278:
+  case 279:
 
     { context->symbolTable.push(); context->incrLoopNestingLevel(); }
 
     break;
 
-  case 279:
+  case 280:
 
     {
         context->symbolTable.pop();
         (yyval.interm.intermNode) = context->addLoop(ELoopFor, (yyvsp[-3].interm.intermNode), (yyvsp[-2].interm.nodePair).node1, reinterpret_cast<TIntermTyped*>((yyvsp[-2].interm.nodePair).node2), (yyvsp[0].interm.intermNode), (yylsp[-6]));
         context->decrLoopNestingLevel();
     }
 
     break;
 
-  case 280:
-
-    {
-        (yyval.interm.intermNode) = (yyvsp[0].interm.intermNode);
-    }
-
-    break;
-
   case 281:
 
     {
         (yyval.interm.intermNode) = (yyvsp[0].interm.intermNode);
     }
 
     break;
 
@@ -4810,125 +4798,133 @@ yyreduce:
         (yyval.interm.intermNode) = (yyvsp[0].interm.intermNode);
     }
 
     break;
 
   case 283:
 
     {
-        (yyval.interm.intermNode) = nullptr;
+        (yyval.interm.intermNode) = (yyvsp[0].interm.intermNode);
     }
 
     break;
 
   case 284:
 
     {
-        (yyval.interm.nodePair).node1 = (yyvsp[-1].interm.intermNode);
-        (yyval.interm.nodePair).node2 = 0;
+        (yyval.interm.intermNode) = nullptr;
     }
 
     break;
 
   case 285:
 
     {
-        (yyval.interm.nodePair).node1 = (yyvsp[-2].interm.intermNode);
-        (yyval.interm.nodePair).node2 = (yyvsp[0].interm.intermTypedNode);
+        (yyval.interm.nodePair).node1 = (yyvsp[-1].interm.intermNode);
+        (yyval.interm.nodePair).node2 = 0;
     }
 
     break;
 
   case 286:
 
     {
-        (yyval.interm.intermNode) = context->addBranch(EOpContinue, (yylsp[-1]));
+        (yyval.interm.nodePair).node1 = (yyvsp[-2].interm.intermNode);
+        (yyval.interm.nodePair).node2 = (yyvsp[0].interm.intermTypedNode);
     }
 
     break;
 
   case 287:
 
     {
-        (yyval.interm.intermNode) = context->addBranch(EOpBreak, (yylsp[-1]));
+        (yyval.interm.intermNode) = context->addBranch(EOpContinue, (yylsp[-1]));
     }
 
     break;
 
   case 288:
 
     {
-        (yyval.interm.intermNode) = context->addBranch(EOpReturn, (yylsp[-1]));
+        (yyval.interm.intermNode) = context->addBranch(EOpBreak, (yylsp[-1]));
     }
 
     break;
 
   case 289:
 
     {
-        (yyval.interm.intermNode) = context->addBranch(EOpReturn, (yyvsp[-1].interm.intermTypedNode), (yylsp[-2]));
+        (yyval.interm.intermNode) = context->addBranch(EOpReturn, (yylsp[-1]));
     }
 
     break;
 
   case 290:
 
     {
-        (yyval.interm.intermNode) = context->addBranch(EOpKill, (yylsp[-1]));
+        (yyval.interm.intermNode) = context->addBranch(EOpReturn, (yyvsp[-1].interm.intermTypedNode), (yylsp[-2]));
     }
 
     break;
 
   case 291:
 
     {
+        (yyval.interm.intermNode) = context->addBranch(EOpKill, (yylsp[-1]));
+    }
+
+    break;
+
+  case 292:
+
+    {
         (yyval.interm.intermBlock) = new TIntermBlock();
         (yyval.interm.intermBlock)->setLine((yyloc));
         (yyval.interm.intermBlock)->appendStatement((yyvsp[0].interm.intermNode));
         context->setTreeRoot((yyval.interm.intermBlock));
     }
 
     break;
 
-  case 292:
+  case 293:
 
     {
         (yyval.interm.intermBlock)->appendStatement((yyvsp[0].interm.intermNode));
     }
 
     break;
 
-  case 293:
-
-    {
-        (yyval.interm.intermNode) = (yyvsp[0].interm.intermNode);
-    }
-
-    break;
-
   case 294:
 
     {
         (yyval.interm.intermNode) = (yyvsp[0].interm.intermNode);
     }
 
     break;
 
   case 295:
 
     {
-        context->parseFunctionDefinitionHeader((yylsp[0]), &((yyvsp[0].interm).function), &((yyvsp[0].interm).intermFunctionPrototype));
+        (yyval.interm.intermNode) = (yyvsp[0].interm.intermNode);
     }
 
     break;
 
   case 296:
 
     {
+        context->parseFunctionDefinitionHeader((yylsp[0]), &((yyvsp[0].interm).function), &((yyvsp[0].interm).intermFunctionPrototype));
+    }
+
+    break;
+
+  case 297:
+
+    {
         (yyval.interm.intermNode) = context->addFunctionDefinition((yyvsp[-2].interm).intermFunctionPrototype, (yyvsp[0].interm.intermBlock), (yylsp[-2]));
     }
 
     break;
 
 
 
       default: break;
--- a/gfx/angle/src/compiler/translator/glslang_tab.h
+++ b/gfx/angle/src/compiler/translator/glslang_tab.h
@@ -233,24 +233,26 @@ union YYSTYPE
             TIntermAggregate *intermAggregate;
             TIntermBlock *intermBlock;
             TIntermDeclaration *intermDeclaration;
             TIntermFunctionPrototype *intermFunctionPrototype;
             TIntermSwitch *intermSwitch;
             TIntermCase *intermCase;
         };
         union {
+            TVector<unsigned int> *arraySizes;
             TTypeSpecifierNonArray typeSpecifierNonArray;
             TPublicType type;
             TPrecision precision;
             TLayoutQualifier layoutQualifier;
             TQualifier qualifier;
             TFunction *function;
             TParameter param;
-            TField *field;
+            TDeclarator *declarator;
+            TDeclaratorList *declaratorList;
             TFieldList *fieldList;
             TQualifierWrapperBase *qualifierWrapper;
             TTypeQualifierBuilder *typeQualifierBuilder;
         };
     } interm;
 
 
 };
--- a/gfx/angle/src/compiler/translator/util.cpp
+++ b/gfx/angle/src/compiler/translator/util.cpp
@@ -18,16 +18,34 @@ bool atoi_clamp(const char *str, unsigne
     if (!success)
         *value = std::numeric_limits<unsigned int>::max();
     return success;
 }
 
 namespace sh
 {
 
+namespace
+{
+
+bool IsInterpolationIn(TQualifier qualifier)
+{
+    switch (qualifier)
+    {
+        case EvqSmoothIn:
+        case EvqFlatIn:
+        case EvqCentroidIn:
+            return true;
+        default:
+            return false;
+    }
+}
+
+}  // anonymous namespace
+
 float NumericLexFloat32OutOfRangeToInfinity(const std::string &str)
 {
     // Parses a decimal string using scientific notation into a floating point number.
     // Out-of-range values are converted to infinity. Values that are too small to be
     // represented are converted to zero.
 
     // The mantissa in decimal scientific notation. The magnitude of the mantissa integer does not
     // matter.
@@ -433,34 +451,51 @@ GLenum GLVariablePrecision(const TType &
 
     // Other types (boolean, sampler) don't have a precision
     return GL_NONE;
 }
 
 TString ArrayString(const TType &type)
 {
     TStringStream arrayString;
-    const TVector<unsigned int> &arraySizes = type.getArraySizes();
+    if (!type.isArray())
+        return arrayString.str();
+
+    const TVector<unsigned int> &arraySizes = *type.getArraySizes();
     for (auto arraySizeIter = arraySizes.rbegin(); arraySizeIter != arraySizes.rend();
          ++arraySizeIter)
     {
-        arrayString << "[" << (*arraySizeIter) << "]";
+        arrayString << "[";
+        if (*arraySizeIter > 0)
+        {
+            arrayString << (*arraySizeIter);
+        }
+        arrayString << "]";
     }
     return arrayString.str();
 }
 
+TString GetTypeName(const TType &type, ShHashFunction64 hashFunction, NameMap *nameMap)
+{
+    if (type.getBasicType() == EbtStruct)
+        return HashName(type.getStruct(), hashFunction, nameMap);
+    else
+        return type.getBuiltInTypeNameString();
+}
+
 bool IsVaryingOut(TQualifier qualifier)
 {
     switch (qualifier)
     {
         case EvqVaryingOut:
         case EvqSmoothOut:
         case EvqFlatOut:
         case EvqCentroidOut:
         case EvqVertexOut:
+        case EvqGeometryOut:
             return true;
 
         default:
             break;
     }
 
     return false;
 }
@@ -469,44 +504,53 @@ bool IsVaryingIn(TQualifier qualifier)
 {
     switch (qualifier)
     {
         case EvqVaryingIn:
         case EvqSmoothIn:
         case EvqFlatIn:
         case EvqCentroidIn:
         case EvqFragmentIn:
+        case EvqGeometryIn:
             return true;
 
         default:
             break;
     }
 
     return false;
 }
 
 bool IsVarying(TQualifier qualifier)
 {
     return IsVaryingIn(qualifier) || IsVaryingOut(qualifier);
 }
 
+bool IsGeometryShaderInput(GLenum shaderType, TQualifier qualifier)
+{
+    return (qualifier == EvqGeometryIn) ||
+           ((shaderType == GL_GEOMETRY_SHADER_EXT) && IsInterpolationIn(qualifier));
+}
+
 InterpolationType GetInterpolationType(TQualifier qualifier)
 {
     switch (qualifier)
     {
         case EvqFlatIn:
         case EvqFlatOut:
             return INTERPOLATION_FLAT;
 
         case EvqSmoothIn:
         case EvqSmoothOut:
         case EvqVertexOut:
         case EvqFragmentIn:
         case EvqVaryingIn:
         case EvqVaryingOut:
+        case EvqGeometryIn:
+        case EvqGeometryOut:
             return INTERPOLATION_SMOOTH;
 
         case EvqCentroidIn:
         case EvqCentroidOut:
             return INTERPOLATION_CENTROID;
 
         default:
             UNREACHABLE();
--- a/gfx/angle/src/compiler/translator/util.h
+++ b/gfx/angle/src/compiler/translator/util.h
@@ -7,16 +7,17 @@
 #ifndef COMPILER_TRANSLATOR_UTIL_H_
 #define COMPILER_TRANSLATOR_UTIL_H_
 
 #include <stack>
 
 #include "angle_gl.h"
 #include <GLSLANG/ShaderLang.h>
 
+#include "compiler/translator/HashNames.h"
 #include "compiler/translator/Operator.h"
 #include "compiler/translator/Types.h"
 
 // If overflow happens, clamp the value to UINT_MIN or UINT_MAX.
 // Return false if overflow happens.
 bool atoi_clamp(const char *str, unsigned int *value);
 
 namespace sh
@@ -33,22 +34,25 @@ float NumericLexFloat32OutOfRangeToInfin
 // Return false if overflow happens.
 bool strtof_clamp(const std::string &str, float *value);
 
 GLenum GLVariableType(const TType &type);
 GLenum GLVariablePrecision(const TType &type);
 bool IsVaryingIn(TQualifier qualifier);
 bool IsVaryingOut(TQualifier qualifier);
 bool IsVarying(TQualifier qualifier);
+bool IsGeometryShaderInput(GLenum shaderType, TQualifier qualifier);
 InterpolationType GetInterpolationType(TQualifier qualifier);
 
 // Returns array brackets including size with outermost array size first, as specified in GLSL ES
 // 3.10 section 4.1.9.
 TString ArrayString(const TType &type);
 
+TString GetTypeName(const TType &type, ShHashFunction64 hashFunction, NameMap *nameMap);
+
 TType GetShaderVariableBasicType(const sh::ShaderVariable &var);
 
 bool IsBuiltinOutputVariable(TQualifier qualifier);
 bool IsBuiltinFragmentInputVariable(TQualifier qualifier);
 bool CanBeInvariantESSL1(TQualifier qualifier);
 bool CanBeInvariantESSL3OrGreater(TQualifier qualifier);
 bool IsOutputESSL(ShShaderOutput output);
 bool IsOutputGLSL(ShShaderOutput output);
--- a/gfx/angle/src/copy_compiler_dll.bat
+++ b/gfx/angle/src/copy_compiler_dll.bat
@@ -1,9 +1,9 @@
-@echo off
-set _arch=%1
-set _arch=%_arch:Win32=x86%
-copy %2"\Redist\D3D\"%_arch%"\d3dcompiler_47.dll" %3 > NUL
-:: This is equivalent to `touch', see:
-:: https://technet.microsoft.com/en-us/library/bb490886.aspx
-:: This avoids rerunning because this batch file is also copied to the gen dir,
-:: so it's timestamp would otherwise be newer than the dll.
-copy /b %3\d3dcompiler_47.dll+,, %3\d3dcompiler_47.dll > NUL
+@echo off
+set _arch=%1
+set _arch=%_arch:Win32=x86%
+copy %2"\Redist\D3D\"%_arch%"\d3dcompiler_47.dll" %3 > NUL
+:: This is equivalent to `touch', see:
+:: https://technet.microsoft.com/en-us/library/bb490886.aspx
+:: This avoids rerunning because this batch file is also copied to the gen dir,
+:: so it's timestamp would otherwise be newer than the dll.
+copy /b %3\d3dcompiler_47.dll+,, %3\d3dcompiler_47.dll > NUL
--- a/gfx/angle/src/gpu_info_util/SystemInfo.cpp
+++ b/gfx/angle/src/gpu_info_util/SystemInfo.cpp
@@ -12,16 +12,28 @@
 #include <sstream>
 
 #include "common/debug.h"
 #include "common/string_utils.h"
 
 namespace angle
 {
 
+GPUDeviceInfo::GPUDeviceInfo() = default;
+
+GPUDeviceInfo::~GPUDeviceInfo() = default;
+
+GPUDeviceInfo::GPUDeviceInfo(const GPUDeviceInfo &other) = default;
+
+SystemInfo::SystemInfo() = default;
+
+SystemInfo::~SystemInfo() = default;
+
+SystemInfo::SystemInfo(const SystemInfo &other) = default;
+
 bool IsAMD(VendorID vendorId)
 {
     return vendorId == kVendorID_AMD;
 }
 
 bool IsIntel(VendorID vendorId)
 {
     return vendorId == kVendorID_Intel;
--- a/gfx/angle/src/gpu_info_util/SystemInfo.h
+++ b/gfx/angle/src/gpu_info_util/SystemInfo.h
@@ -21,26 +21,36 @@ using DeviceID = uint32_t;
 
 constexpr VendorID kVendorID_AMD      = 0x1002;
 constexpr VendorID kVendorID_Intel    = 0x8086;
 constexpr VendorID kVendorID_Nvidia   = 0x10DE;
 constexpr VendorID kVendorID_Qualcomm = 0x5143;
 
 struct GPUDeviceInfo
 {
+    GPUDeviceInfo();
+    ~GPUDeviceInfo();
+
+    GPUDeviceInfo(const GPUDeviceInfo &other);
+
     VendorID vendorId = 0;
     DeviceID deviceId = 0;
 
     std::string driverVendor;
     std::string driverVersion;
     std::string driverDate;
 };
 
 struct SystemInfo
 {
+    SystemInfo();
+    ~SystemInfo();
+
+    SystemInfo(const SystemInfo &other);
+
     std::vector<GPUDeviceInfo> gpus;
     int primaryGPUIndex = -1;
     int activeGPUIndex  = -1;
 
     bool isOptimus       = false;
     bool isAMDSwitchable = false;
 
     // Only available on macOS
--- a/gfx/angle/src/id/commit.h
+++ b/gfx/angle/src/id/commit.h
@@ -1,3 +1,3 @@
-#define ANGLE_COMMIT_HASH "db3422764a9b"
+#define ANGLE_COMMIT_HASH "47c9888c35ca"
 #define ANGLE_COMMIT_HASH_SIZE 12
-#define ANGLE_COMMIT_DATE "2017-09-28 16:39:41 +0000"
+#define ANGLE_COMMIT_DATE "2018-01-08 21:00:54 +0000"
--- a/gfx/angle/src/image_util/loadimage_etc.cpp
+++ b/gfx/angle/src/image_util/loadimage_etc.cpp
@@ -11,34 +11,37 @@
 #include "common/mathutil.h"
 
 #include "image_util/imageformats.h"
 
 namespace angle
 {
 namespace
 {
+
+using IntensityModifier = const int[4];
+
 // Table 3.17.2 sorted according to table 3.17.3
 // clang-format off
-static const int intensityModifierDefault[][4] =
+static IntensityModifier intensityModifierDefault[] =
 {
     {  2,   8,  -2,   -8 },
     {  5,  17,  -5,  -17 },
     {  9,  29,  -9,  -29 },
     { 13,  42, -13,  -42 },
     { 18,  60, -18,  -60 },
     { 24,  80, -24,  -80 },
     { 33, 106, -33, -106 },
     { 47, 183, -47, -183 },
 };
 // clang-format on
 
 // Table C.12, intensity modifier for non opaque punchthrough alpha
 // clang-format off
-static const int intensityModifierNonOpaque[][4] =
+static IntensityModifier intensityModifierNonOpaque[] =
 {
     { 0,   8, 0,   -8 },
     { 0,  17, 0,  -17 },
     { 0,  29, 0,  -29 },
     { 0,  42, 0,  -42 },
     { 0,  60, 0,  -60 },
     { 0,  80, 0,  -80 },
     { 0, 106, 0, -106 },
@@ -395,17 +398,17 @@ struct ETC2Block
                                              int g1,
                                              int b1,
                                              int r2,
                                              int g2,
                                              int b2,
                                              const uint8_t alphaValues[4][4],
                                              bool nonOpaquePunchThroughAlpha) const
     {
-        const auto intensityModifier =
+        const IntensityModifier *intensityModifier =
             nonOpaquePunchThroughAlpha ? intensityModifierNonOpaque : intensityModifierDefault;
 
         R8G8B8A8 subblockColors0[4];
         R8G8B8A8 subblockColors1[4];
         for (size_t modifierIdx = 0; modifierIdx < 4; modifierIdx++)
         {
             const int i1                 = intensityModifier[u.idht.mode.idm.cw1][modifierIdx];
             subblockColors0[modifierIdx] = createRGBA(r1 + i1, g1 + i1, b1 + i1);
@@ -1073,17 +1076,17 @@ struct ETC2Block
         //   With those information, we can only encode used subblock colors
         //   to BC1, and copy the bits to the right pixels.
         // Fully decode and encode need to process 16 RGBA pixels. With this
         //   algorithm, it's 8 pixels at maximum for a individual or
         //   differential block. Saves us bandwidth and computations.
 
         static const size_t kNumColors = 8;
 
-        const auto intensityModifier =
+        const IntensityModifier *intensityModifier =
             nonOpaquePunchThroughAlpha ? intensityModifierNonOpaque : intensityModifierDefault;
 
         // Compute the colors that pixels can have in each subblock both for
         // the decoding of the RGBA data and BC1 encoding
         R8G8B8A8 subblockColors[kNumColors];
         for (size_t modifierIdx = 0; modifierIdx < 4; modifierIdx++)
         {
             if (nonOpaquePunchThroughAlpha && (modifierIdx == 2))
--- a/gfx/angle/src/libANGLE/AttributeMap.cpp
+++ b/gfx/angle/src/libANGLE/AttributeMap.cpp
@@ -1,39 +1,57 @@
 //
 // 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/AttributeMap.h"
 
+#include "common/debug.h"
+
 namespace egl
 {
 
 AttributeMap::AttributeMap()
 {
 }
 
+AttributeMap::AttributeMap(const AttributeMap &other) = default;
+
+AttributeMap::~AttributeMap() = default;
+
 void AttributeMap::insert(EGLAttrib key, EGLAttrib value)
 {
     mAttributes[key] = value;
 }
 
 bool AttributeMap::contains(EGLAttrib key) const
 {
     return (mAttributes.find(key) != mAttributes.end());
 }
 
+EGLAttrib AttributeMap::get(EGLAttrib key) const
+{
+    auto iter = mAttributes.find(key);
+    ASSERT(iter != mAttributes.end());
+    return iter->second;
+}
+
 EGLAttrib AttributeMap::get(EGLAttrib key, EGLAttrib defaultValue) const
 {
     auto iter = mAttributes.find(key);
     return (mAttributes.find(key) != mAttributes.end()) ? iter->second : defaultValue;
 }
 
+EGLint AttributeMap::getAsInt(EGLAttrib key) const
+{
+    return static_cast<EGLint>(get(key));
+}
+
 EGLint AttributeMap::getAsInt(EGLAttrib key, EGLint defaultValue) const
 {
     return static_cast<EGLint>(get(key, static_cast<EGLAttrib>(defaultValue)));
 }
 
 bool AttributeMap::isEmpty() const
 {
     return mAttributes.empty();
--- a/gfx/angle/src/libANGLE/AttributeMap.h
+++ b/gfx/angle/src/libANGLE/AttributeMap.h
@@ -15,20 +15,24 @@
 
 namespace egl
 {
 
 class AttributeMap final
 {
   public:
     AttributeMap();
+    AttributeMap(const AttributeMap &other);
+    ~AttributeMap();
 
     void insert(EGLAttrib key, EGLAttrib value);
     bool contains(EGLAttrib key) const;
+    EGLAttrib get(EGLAttrib key) const;
     EGLAttrib get(EGLAttrib key, EGLAttrib defaultValue) const;
+    EGLint getAsInt(EGLAttrib key) const;
     EGLint getAsInt(EGLAttrib key, EGLint defaultValue) const;
     bool isEmpty() const;
     std::vector<EGLint> toIntVector() const;
 
     typedef std::map<EGLAttrib, EGLAttrib>::const_iterator const_iterator;
 
     const_iterator begin() const;
     const_iterator end() const;
--- a/gfx/angle/src/libANGLE/BinaryStream.h
+++ b/gfx/angle/src/libANGLE/BinaryStream.h
@@ -41,16 +41,26 @@ class BinaryInputStream : angle::NonCopy
     }
 
     template <class IntT>
     void readInt(IntT *outValue)
     {
         *outValue = readInt<IntT>();
     }
 
+    template <class IntT, class VectorElementT>
+    void readIntVector(std::vector<VectorElementT> *param)
+    {
+        unsigned int size = readInt<unsigned int>();
+        for (unsigned int index = 0; index < size; ++index)
+        {
+            param->push_back(readInt<IntT>());
+        }
+    }
+
     bool readBool()
     {
         int value = 0;
         read(&value);
         return (value > 0);
     }
 
     void readBool(bool *outValue)
@@ -165,19 +175,18 @@ class BinaryInputStream : angle::NonCopy
         read(v, 1);
     }
 
 };
 
 class BinaryOutputStream : angle::NonCopyable
 {
   public:
-    BinaryOutputStream()
-    {
-    }
+    BinaryOutputStream();
+    ~BinaryOutputStream();
 
     // writeInt also handles bool types
     template <class IntT>
     void writeInt(IntT param)
     {
         ASSERT(angle::IsValueInRangeForNumericType<int>(param));
         int intValue = static_cast<int>(param);
         write(&intValue, 1);
@@ -192,16 +201,26 @@ class BinaryOutputStream : angle::NonCop
             writeInt(-1);
         }
         else
         {
             writeInt(param);
         }
     }
 
+    template <class IntT>
+    void writeIntVector(std::vector<IntT> param)
+    {
+        writeInt(param.size());
+        for (IntT element : param)
+        {
+            writeIntOrNegOne(element);
+        }
+    }
+
     void writeString(const std::string &v)
     {
         writeInt(v.length());
         write(v.c_str(), v.length());
     }
 
     void writeBytes(const unsigned char *bytes, size_t count)
     {
@@ -225,11 +244,18 @@ class BinaryOutputStream : angle::NonCop
     void write(const T *v, size_t num)
     {
         static_assert(std::is_fundamental<T>::value, "T must be a fundamental type.");
         const char *asBytes = reinterpret_cast<const char*>(v);
         mData.insert(mData.end(), asBytes, asBytes + num * sizeof(T));
     }
 
 };
+
+inline BinaryOutputStream::BinaryOutputStream()
+{
+}
+
+inline BinaryOutputStream::~BinaryOutputStream() = default;
+
 }  // namespace gl
 
 #endif  // LIBANGLE_BINARYSTREAM_H_
--- a/gfx/angle/src/libANGLE/Buffer.cpp
+++ b/gfx/angle/src/libANGLE/Buffer.cpp
@@ -14,17 +14,17 @@
 #include "libANGLE/renderer/BufferImpl.h"
 #include "libANGLE/renderer/GLImplFactory.h"
 
 namespace gl
 {
 
 BufferState::BufferState()
     : mLabel(),
-      mUsage(GL_STATIC_DRAW),
+      mUsage(BufferUsage::StaticDraw),
       mSize(0),
       mAccessFlags(0),
       mAccess(GL_WRITE_ONLY_OES),
       mMapped(GL_FALSE),
       mMapPointer(nullptr),
       mMapOffset(0),
       mMapLength(0)
 {
@@ -58,20 +58,20 @@ void Buffer::setLabel(const std::string 
 }
 
 const std::string &Buffer::getLabel() const
 {
     return mState.mLabel;
 }
 
 Error Buffer::bufferData(const Context *context,
-                         GLenum target,
+                         BufferBinding target,
                          const void *data,
                          GLsizeiptr size,
-                         GLenum usage)
+                         BufferUsage usage)
 {
     const void *dataForImpl = data;
 
     // If we are using robust resource init, make sure the buffer starts cleared.
     // Note: the Context is checked for nullptr because of some testing code.
     // TODO(jmadill): Investigate lazier clearing.
     if (context && context->getGLState().isRobustResourceInitEnabled() && !data && size > 0)
     {
@@ -85,17 +85,17 @@ Error Buffer::bufferData(const Context *
     mIndexRangeCache.clear();
     mState.mUsage = usage;
     mState.mSize  = size;
 
     return NoError();
 }
 
 Error Buffer::bufferSubData(const Context *context,
-                            GLenum target,
+                            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));
 
--- a/gfx/angle/src/libANGLE/Buffer.h
+++ b/gfx/angle/src/libANGLE/Buffer.h
@@ -10,16 +10,17 @@
 
 #ifndef LIBANGLE_BUFFER_H_
 #define LIBANGLE_BUFFER_H_
 
 #include "common/angleutils.h"
 #include "libANGLE/Debug.h"
 #include "libANGLE/Error.h"
 #include "libANGLE/IndexRangeCache.h"
+#include "libANGLE/PackedGLEnums.h"
 #include "libANGLE/RefCountObject.h"
 
 namespace rx
 {
 class BufferImpl;
 class GLImplFactory;
 };
 
@@ -31,31 +32,31 @@ class Context;
 class BufferState final : angle::NonCopyable
 {
   public:
     BufferState();
     ~BufferState();
 
     const std::string &getLabel();
 
-    GLenum getUsage() const { return mUsage; }
+    BufferUsage getUsage() const { return mUsage; }
     GLbitfield getAccessFlags() const { return mAccessFlags; }
     GLenum getAccess() const { return mAccess; }
     GLboolean isMapped() const { return mMapped; }
     void *getMapPointer() const { return mMapPointer; }
     GLint64 getMapOffset() const { return mMapOffset; }
     GLint64 getMapLength() const { return mMapLength; }
     GLint64 getSize() const { return mSize; }
 
   private:
     friend class Buffer;
 
     std::string mLabel;
 
-    GLenum mUsage;
+    BufferUsage mUsage;
     GLint64 mSize;
     GLbitfield mAccessFlags;
     GLenum mAccess;
     GLboolean mMapped;
     void *mMapPointer;
     GLint64 mMapOffset;
     GLint64 mMapLength;
 };
@@ -66,22 +67,22 @@ class Buffer final : public RefCountObje
     Buffer(rx::GLImplFactory *factory, GLuint id);
     ~Buffer() override;
     Error onDestroy(const Context *context) override;
 
     void setLabel(const std::string &label) override;
     const std::string &getLabel() const override;
 
     Error bufferData(const Context *context,
-                     GLenum target,
+                     BufferBinding target,
                      const void *data,
                      GLsizeiptr size,
-                     GLenum usage);
+                     BufferUsage usage);
     Error bufferSubData(const Context *context,
-                        GLenum target,
+                        BufferBinding target,
                         const void *data,
                         GLsizeiptr size,
                         GLintptr offset);
     Error copyBufferSubData(const Context *context,
                             Buffer *source,
                             GLintptr sourceOffset,
                             GLintptr destOffset,
                             GLsizeiptr size);
@@ -94,17 +95,17 @@ class Buffer final : public RefCountObje
 
     Error getIndexRange(const gl::Context *context,
                         GLenum type,
                         size_t offset,
                         size_t count,
                         bool primitiveRestartEnabled,
                         IndexRange *outRange) const;
 
-    GLenum getUsage() const { return mState.mUsage; }
+    BufferUsage getUsage() const { return mState.mUsage; }
     GLbitfield getAccessFlags() const { return mState.mAccessFlags; }
     GLenum getAccess() const { return mState.mAccess; }
     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; }
 
--- a/gfx/angle/src/libANGLE/Caps.cpp
+++ b/gfx/angle/src/libANGLE/Caps.cpp
@@ -30,16 +30,20 @@ namespace gl
 TextureCaps::TextureCaps()
     : texturable(false),
       filterable(false),
       renderable(false),
       sampleCounts()
 {
 }
 
+TextureCaps::TextureCaps(const TextureCaps &other) = default;
+
+TextureCaps::~TextureCaps() = default;
+
 GLuint TextureCaps::getMaxSamples() const
 {
     return !sampleCounts.empty() ? *sampleCounts.rbegin() : 0;
 }
 
 GLuint TextureCaps::getNearestSamples(GLuint requestedSamples) const
 {
     if (requestedSamples == 0)
@@ -79,69 +83,65 @@ TextureCaps GenerateMinimumTextureCaps(G
         {
             caps.sampleCounts.insert(4);
         }
     }
 
     return caps;
 }
 
-void TextureCapsMap::insert(GLenum internalFormat, const TextureCaps &caps)
+TextureCapsMap::TextureCapsMap()
 {
-    mCapsMap[internalFormat] = caps;
 }
 
-void TextureCapsMap::remove(GLenum internalFormat)
+TextureCapsMap::~TextureCapsMap()
 {
-    InternalFormatToCapsMap::iterator i = mCapsMap.find(internalFormat);
-    if (i != mCapsMap.end())
-    {
-        mCapsMap.erase(i);
-    }
+}
+
+void TextureCapsMap::insert(GLenum internalFormat, const TextureCaps &caps)
+{
+    angle::Format::ID formatID = angle::Format::InternalFormatToID(internalFormat);
+    get(formatID)              = caps;
 }
 
 void TextureCapsMap::clear()
 {
-    mCapsMap.clear();
+    mFormatData.fill(TextureCaps());
 }
 
 const TextureCaps &TextureCapsMap::get(GLenum internalFormat) const
 {
-    static TextureCaps defaultUnsupportedTexture;
-    InternalFormatToCapsMap::const_iterator iter = mCapsMap.find(internalFormat);
-    return (iter != mCapsMap.end()) ? iter->second : defaultUnsupportedTexture;
+    angle::Format::ID formatID = angle::Format::InternalFormatToID(internalFormat);
+    return get(formatID);
 }
 
-TextureCapsMap::const_iterator TextureCapsMap::begin() const
+const TextureCaps &TextureCapsMap::get(angle::Format::ID formatID) const
 {
-    return mCapsMap.begin();
+    return mFormatData[static_cast<size_t>(formatID)];
 }
 
-TextureCapsMap::const_iterator TextureCapsMap::end() const
+TextureCaps &TextureCapsMap::get(angle::Format::ID formatID)
 {
-    return mCapsMap.end();
+    return mFormatData[static_cast<size_t>(formatID)];
 }
 
-size_t TextureCapsMap::size() const
+void TextureCapsMap::set(angle::Format::ID formatID, const TextureCaps &caps)
 {
-    return mCapsMap.size();
+    get(formatID) = caps;
 }
 
-TextureCapsMap GenerateMinimumTextureCapsMap(const Version &clientVersion,
-                                             const Extensions &extensions)
+void InitMinimumTextureCapsMap(const Version &clientVersion,
+                               const Extensions &extensions,
+                               TextureCapsMap *capsMap)
 {
-    TextureCapsMap capsMap;
-
     for (GLenum internalFormat : GetAllSizedInternalFormats())
     {
-        capsMap.insert(internalFormat,
-                       GenerateMinimumTextureCaps(internalFormat, clientVersion, extensions));
+        capsMap->insert(internalFormat,
+                        GenerateMinimumTextureCaps(internalFormat, clientVersion, extensions));
     }
-
-    return capsMap;
 }
 
 Extensions::Extensions()
     : elementIndexUint(false),
       packedDepthStencil(false),
       getProgramBinary(false),
       rgb8rgba8(false),
       textureFormatBGRA8888(false),
@@ -167,32 +167,28 @@ Extensions::Extensions()
       depth32(false),
       textureStorage(false),
       textureNPOT(false),
       drawBuffers(false),
       textureFilterAnisotropic(false),
       maxTextureAnisotropy(0.0f),
       occlusionQueryBoolean(false),
       fence(false),
-      timerQuery(false),
       disjointTimerQuery(false),
       queryCounterBitsTimeElapsed(0),
       queryCounterBitsTimestamp(0),
       robustness(false),
       robustBufferAccessBehavior(false),
       blendMinMax(false),
       framebufferBlit(false),
       framebufferMultisample(false),
       instancedArrays(false),
       packReverseRowOrder(false),
       standardDerivatives(false),
       shaderTextureLOD(false),
-      shaderFramebufferFetch(false),
-      ARMshaderFramebufferFetch(false),
-      NVshaderFramebufferFetch(false),
       fragDepth(false),
       multiview(false),
       maxViews(1u),
       textureUsage(false),
       translatedShaderSource(false),
       fboRenderMipmap(false),
       discardFramebuffer(false),
       debugMarker(false),
@@ -226,17 +222,18 @@ Extensions::Extensions()
       multisampleCompatibility(false),
       framebufferMixedSamples(false),
       textureNorm16(false),
       pathRendering(false),
       surfacelessContext(false),
       clientArrays(false),
       robustResourceInitialization(false),
       programCacheControl(false),
-      textureRectangle(false)
+      textureRectangle(false),
+      geometryShader(false)
 {
 }
 
 std::vector<std::string> Extensions::getStrings() const
 {
     std::vector<std::string> extensionStrings;
 
     for (const auto &extensionInfo : GetExtensionInfoMap())
@@ -615,80 +612,76 @@ const ExtensionInfoMap &GetExtensionInfo
             info.ExtensionsMember = member;
             return info;
         };
 
         // clang-format off
         ExtensionInfoMap map;
         map["GL_OES_element_index_uint"] = enableableExtension(&Extensions::elementIndexUint);
         map["GL_OES_packed_depth_stencil"] = esOnlyExtension(&Extensions::packedDepthStencil);
-        map["GL_OES_get_program_binary"] = esOnlyExtension(&Extensions::getProgramBinary);
-        map["GL_OES_rgb8_rgba8"] = esOnlyExtension(&Extensions::rgb8rgba8);
-        map["GL_EXT_texture_format_BGRA8888"] = esOnlyExtension(&Extensions::textureFormatBGRA8888);
+        map["GL_OES_get_program_binary"] = enableableExtension(&Extensions::getProgramBinary);
+        map["GL_OES_rgb8_rgba8"] = enableableExtension(&Extensions::rgb8rgba8);
+        map["GL_EXT_texture_format_BGRA8888"] = enableableExtension(&Extensions::textureFormatBGRA8888);
         map["GL_EXT_read_format_bgra"] = esOnlyExtension(&Extensions::readFormatBGRA);
-        map["GL_NV_pixel_buffer_object"] = esOnlyExtension(&Extensions::pixelBufferObject);
-        map["GL_OES_mapbuffer"] = esOnlyExtension(&Extensions::mapBuffer);
-        map["GL_EXT_map_buffer_range"] = esOnlyExtension(&Extensions::mapBufferRange);
+        map["GL_NV_pixel_buffer_object"] = enableableExtension(&Extensions::pixelBufferObject);
+        map["GL_OES_mapbuffer"] = enableableExtension(&Extensions::mapBuffer);
+        map["GL_EXT_map_buffer_range"] = enableableExtension(&Extensions::mapBufferRange);
         map["GL_EXT_color_buffer_half_float"] = enableableExtension(&Extensions::colorBufferHalfFloat);
         map["GL_OES_texture_half_float"] = enableableExtension(&Extensions::textureHalfFloat);
         map["GL_OES_texture_half_float_linear"] = enableableExtension(&Extensions::textureHalfFloatLinear);
         map["GL_OES_texture_float"] = enableableExtension(&Extensions::textureFloat);
         map["GL_OES_texture_float_linear"] = enableableExtension(&Extensions::textureFloatLinear);
-        map["GL_EXT_texture_rg"] = esOnlyExtension(&Extensions::textureRG);
-        map["GL_EXT_texture_compression_dxt1"] = esOnlyExtension(&Extensions::textureCompressionDXT1);
-        map["GL_ANGLE_texture_compression_dxt3"] = esOnlyExtension(&Extensions::textureCompressionDXT3);
-        map["GL_ANGLE_texture_compression_dxt5"] = esOnlyExtension(&Extensions::textureCompressionDXT5);
-        map["GL_EXT_texture_compression_s3tc_srgb"] = esOnlyExtension(&Extensions::textureCompressionS3TCsRGB);
-        map["GL_KHR_texture_compression_astc_hdr"] = esOnlyExtension(&Extensions::textureCompressionASTCHDR);
-        map["GL_KHR_texture_compression_astc_ldr"] = esOnlyExtension(&Extensions::textureCompressionASTCLDR);
-        map["GL_OES_compressed_ETC1_RGB8_texture"] = esOnlyExtension(&Extensions::compressedETC1RGB8Texture);
-        map["GL_EXT_sRGB"] = esOnlyExtension(&Extensions::sRGB);
+        map["GL_EXT_texture_rg"] = enableableExtension(&Extensions::textureRG);
+        map["GL_EXT_texture_compression_dxt1"] = enableableExtension(&Extensions::textureCompressionDXT1);
+        map["GL_ANGLE_texture_compression_dxt3"] = enableableExtension(&Extensions::textureCompressionDXT3);
+        map["GL_ANGLE_texture_compression_dxt5"] = enableableExtension(&Extensions::textureCompressionDXT5);
+        map["GL_EXT_texture_compression_s3tc_srgb"] = enableableExtension(&Extensions::textureCompressionS3TCsRGB);
+        map["GL_KHR_texture_compression_astc_hdr"] = enableableExtension(&Extensions::textureCompressionASTCHDR);
+        map["GL_KHR_texture_compression_astc_ldr"] = enableableExtension(&Extensions::textureCompressionASTCLDR);
+        map["GL_OES_compressed_ETC1_RGB8_texture"] = enableableExtension(&Extensions::compressedETC1RGB8Texture);
+        map["GL_EXT_sRGB"] = enableableExtension(&Extensions::sRGB);
         map["GL_ANGLE_depth_texture"] = esOnlyExtension(&Extensions::depthTextures);
         map["GL_OES_depth32"] = esOnlyExtension(&Extensions::depth32);
         map["GL_EXT_texture_storage"] = esOnlyExtension(&Extensions::textureStorage);
         map["GL_OES_texture_npot"] = enableableExtension(&Extensions::textureNPOT);
         map["GL_EXT_draw_buffers"] = enableableExtension(&Extensions::drawBuffers);
         map["GL_EXT_texture_filter_anisotropic"] = enableableExtension(&Extensions::textureFilterAnisotropic);
-        map["GL_EXT_occlusion_query_boolean"] = esOnlyExtension(&Extensions::occlusionQueryBoolean);
+        map["GL_EXT_occlusion_query_boolean"] = enableableExtension(&Extensions::occlusionQueryBoolean);
         map["GL_NV_fence"] = esOnlyExtension(&Extensions::fence);
-        map["GL_ANGLE_timer_query"] = esOnlyExtension(&Extensions::timerQuery);
-        map["GL_EXT_disjoint_timer_query"] = esOnlyExtension(&Extensions::disjointTimerQuery);
+        map["GL_EXT_disjoint_timer_query"] = enableableExtension(&Extensions::disjointTimerQuery);
         map["GL_EXT_robustness"] = esOnlyExtension(&Extensions::robustness);
         map["GL_KHR_robust_buffer_access_behavior"] = esOnlyExtension(&Extensions::robustBufferAccessBehavior);
-        map["GL_EXT_blend_minmax"] = esOnlyExtension(&Extensions::blendMinMax);
-        map["GL_ANGLE_framebuffer_blit"] = esOnlyExtension(&Extensions::framebufferBlit);
-        map["GL_ANGLE_framebuffer_multisample"] = esOnlyExtension(&Extensions::framebufferMultisample);
-        map["GL_ANGLE_instanced_arrays"] = esOnlyExtension(&Extensions::instancedArrays);
-        map["GL_ANGLE_pack_reverse_row_order"] = esOnlyExtension(&Extensions::packReverseRowOrder);
+        map["GL_EXT_blend_minmax"] = enableableExtension(&Extensions::blendMinMax);
+        map["GL_ANGLE_framebuffer_blit"] = enableableExtension(&Extensions::framebufferBlit);
+        map["GL_ANGLE_framebuffer_multisample"] = enableableExtension(&Extensions::framebufferMultisample);
+        map["GL_ANGLE_instanced_arrays"] = enableableExtension(&Extensions::instancedArrays);
+        map["GL_ANGLE_pack_reverse_row_order"] = enableableExtension(&Extensions::packReverseRowOrder);
         map["GL_OES_standard_derivatives"] = enableableExtension(&Extensions::standardDerivatives);
         map["GL_EXT_shader_texture_lod"] = enableableExtension(&Extensions::shaderTextureLOD);
-        map["GL_NV_shader_framebuffer_fetch"] = esOnlyExtension(&Extensions::NVshaderFramebufferFetch);
-        map["GL_ARM_shader_framebuffer_fetch"] = esOnlyExtension(&Extensions::ARMshaderFramebufferFetch);
-        map["GL_EXT_shader_framebuffer_fetch"] = esOnlyExtension(&Extensions::shaderFramebufferFetch);
         map["GL_EXT_frag_depth"] = enableableExtension(&Extensions::fragDepth);
         map["GL_ANGLE_multiview"] = enableableExtension(&Extensions::multiview);
-        map["GL_ANGLE_texture_usage"] = esOnlyExtension(&Extensions::textureUsage);
+        map["GL_ANGLE_texture_usage"] = enableableExtension(&Extensions::textureUsage);
         map["GL_ANGLE_translated_shader_source"] = esOnlyExtension(&Extensions::translatedShaderSource);
-        map["GL_OES_fbo_render_mipmap"] = esOnlyExtension(&Extensions::fboRenderMipmap);
+        map["GL_OES_fbo_render_mipmap"] = enableableExtension(&Extensions::fboRenderMipmap);
         map["GL_EXT_discard_framebuffer"] = esOnlyExtension(&Extensions::discardFramebuffer);
         map["GL_EXT_debug_marker"] = esOnlyExtension(&Extensions::debugMarker);
         map["GL_OES_EGL_image"] = esOnlyExtension(&Extensions::eglImage);
         map["GL_OES_EGL_image_external"] = esOnlyExtension(&Extensions::eglImageExternal);
         map["GL_OES_EGL_image_external_essl3"] = esOnlyExtension(&Extensions::eglImageExternalEssl3);
         map["GL_NV_EGL_stream_consumer_external"] = esOnlyExtension(&Extensions::eglStreamConsumerExternal);
-        map["GL_EXT_unpack_subimage"] = esOnlyExtension(&Extensions::unpackSubimage);
-        map["GL_NV_pack_subimage"] = esOnlyExtension(&Extensions::packSubimage);
+        map["GL_EXT_unpack_subimage"] = enableableExtension(&Extensions::unpackSubimage);
+        map["GL_NV_pack_subimage"] = enableableExtension(&Extensions::packSubimage);
         map["GL_EXT_color_buffer_float"] = enableableExtension(&Extensions::colorBufferFloat);
         map["GL_OES_vertex_array_object"] = esOnlyExtension(&Extensions::vertexArrayObject);
         map["GL_KHR_debug"] = esOnlyExtension(&Extensions::debug);
         // TODO(jmadill): Enable this when complete.
         //map["GL_KHR_no_error"] = esOnlyExtension(&Extensions::noError);
-        map["GL_ANGLE_lossy_etc_decode"] = esOnlyExtension(&Extensions::lossyETCDecode);
+        map["GL_ANGLE_lossy_etc_decode"] = enableableExtension(&Extensions::lossyETCDecode);
         map["GL_CHROMIUM_bind_uniform_location"] = esOnlyExtension(&Extensions::bindUniformLocation);
-        map["GL_CHROMIUM_sync_query"] = esOnlyExtension(&Extensions::syncQuery);
+        map["GL_CHROMIUM_sync_query"] = enableableExtension(&Extensions::syncQuery);
         map["GL_CHROMIUM_copy_texture"] = esOnlyExtension(&Extensions::copyTexture);
         map["GL_CHROMIUM_copy_compressed_texture"] = esOnlyExtension(&Extensions::copyCompressedTexture);
         map["GL_ANGLE_webgl_compatibility"] = esOnlyExtension(&Extensions::webglCompatibility);
         map["GL_ANGLE_request_extension"] = esOnlyExtension(&Extensions::requestExtension);
         map["GL_CHROMIUM_bind_generates_resource"] = esOnlyExtension(&Extensions::bindGeneratesResource);
         map["GL_ANGLE_robust_client_memory"] = esOnlyExtension(&Extensions::robustClientMemory);
         map["GL_EXT_texture_sRGB_decode"] = esOnlyExtension(&Extensions::textureSRGBDecode);
         map["GL_EXT_sRGB_write_control"] = esOnlyExtension(&Extensions::sRGBWriteControl);
@@ -698,29 +691,32 @@ const ExtensionInfoMap &GetExtensionInfo
         map["GL_CHROMIUM_framebuffer_mixed_samples"] = esOnlyExtension(&Extensions::framebufferMixedSamples);
         map["GL_EXT_texture_norm16"] = esOnlyExtension(&Extensions::textureNorm16);
         map["GL_CHROMIUM_path_rendering"] = esOnlyExtension(&Extensions::pathRendering);
         map["GL_OES_surfaceless_context"] = esOnlyExtension(&Extensions::surfacelessContext);
         map["GL_ANGLE_client_arrays"] = esOnlyExtension(&Extensions::clientArrays);
         map["GL_ANGLE_robust_resource_initialization"] = esOnlyExtension(&Extensions::robustResourceInitialization);
         map["GL_ANGLE_program_cache_control"] = esOnlyExtension(&Extensions::programCacheControl);
         map["GL_ANGLE_texture_rectangle"] = enableableExtension(&Extensions::textureRectangle);
+        map["GL_EXT_geometry_shader"] = enableableExtension(&Extensions::geometryShader);
         // clang-format on
 
         return map;
     };
 
     static const ExtensionInfoMap extensionInfo = buildExtensionInfoMap();
     return extensionInfo;
 }
 
 TypePrecision::TypePrecision() : range({{0, 0}}), precision(0)
 {
 }
 
+TypePrecision::TypePrecision(const TypePrecision &other) = default;
+
 void TypePrecision::setIEEEFloat()
 {
     range     = {{127, 127}};
     precision = 23;
 }
 
 void TypePrecision::setTwosComplementInt(unsigned int bits)
 {
@@ -846,27 +842,50 @@ Caps::Caps()
       shaderStorageBufferOffsetAlignment(0),
 
       // Table 20.48
       maxTransformFeedbackInterleavedComponents(0),
       maxTransformFeedbackSeparateAttributes(0),
       maxTransformFeedbackSeparateComponents(0),
 
       // Table 20.49
-      maxSamples(0)
+      maxSamples(0),
+
+      // Table 20.40 (cont.) (GL_EXT_geometry_shader)
+      maxFramebufferLayers(0),
+      layerProvokingVertex(0),
 
+      // Table 20.43gs (GL_EXT_geometry_shader)
+      maxGeometryUniformComponents(0),
+      maxGeometryUniformBlocks(0),
+      maxGeometryInputComponents(0),
+      maxGeometryOutputComponents(0),
+      maxGeometryOutputVertices(0),
+      maxGeometryTotalOutputComponents(0),
+      maxGeometryTextureImageUnits(0),
+      maxGeometryAtomicCounterBuffers(0),
+      maxGeometryAtomicCounters(0),
+      maxGeometryShaderStorageBlocks(0),
+      maxGeometryShaderInvocations(0),
+
+      // Table 20.46 (GL_EXT_geometry_shader)
+      maxGeometryImageUniforms(0),
+      maxCombinedGeometryUniformComponents(0)
 {
     for (size_t i = 0; i < 3; ++i)
     {
         maxComputeWorkGroupCount[i] = 0;
         maxComputeWorkGroupSize[i]  = 0;
     }
 }
 
-Caps GenerateMinimumCaps(const Version &clientVersion)
+Caps::Caps(const Caps &other) = default;
+Caps::~Caps()                 = default;
+
+Caps GenerateMinimumCaps(const Version &clientVersion, const Extensions &extensions)
 {
     Caps caps;
 
     if (clientVersion >= Version(2, 0))
     {
         // Table 6.18
         caps.max2DTextureSize      = 64;
         caps.maxCubeMapTextureSize = 16;
@@ -1043,16 +1062,52 @@ Caps GenerateMinimumCaps(const Version &
         caps.maxImageUnits                      = 4;
         caps.maxCombinedImageUniforms           = 4;
         caps.maxShaderStorageBufferBindings     = 4;
         caps.maxShaderStorageBlockSize          = 1 << 27;
         caps.maxCombinedShaderStorageBlocks     = 4;
         caps.shaderStorageBufferOffsetAlignment = 256;
     }
 
+    if (extensions.textureRectangle)
+    {
+        caps.maxRectangleTextureSize = 64;
+    }
+
+    if (extensions.geometryShader)
+    {
+        // Table 20.40 (GL_EXT_geometry_shader)
+        caps.maxFramebufferLayers = 256;
+        caps.layerProvokingVertex = GL_LAST_VERTEX_CONVENTION_EXT;
+
+        // Table 20.43gs (GL_EXT_geometry_shader)
+        caps.maxGeometryUniformComponents     = 1024;
+        caps.maxGeometryUniformBlocks         = 12;
+        caps.maxGeometryInputComponents       = 64;
+        caps.maxGeometryOutputComponents      = 64;
+        caps.maxGeometryOutputVertices        = 256;
+        caps.maxGeometryTotalOutputComponents = 1024;
+        caps.maxGeometryTextureImageUnits     = 16;
+        caps.maxGeometryAtomicCounterBuffers  = 0;
+        caps.maxGeometryAtomicCounters        = 0;
+        caps.maxGeometryShaderStorageBlocks   = 0;
+        caps.maxGeometryShaderInvocations     = 32;
+
+        // Table 20.46 (GL_EXT_geometry_shader)
+        caps.maxGeometryImageUniforms = 0;
+        caps.maxCombinedGeometryUniformComponents =
+            caps.maxGeometryUniformBlocks * static_cast<GLuint>(caps.maxUniformBlockSize / 4) +
+            caps.maxGeometryUniformComponents;
+
+        // Table 20.46 (GL_EXT_geometry_shader)
+        caps.maxUniformBufferBindings     = 48;
+        caps.maxCombinedUniformBlocks     = 36;
+        caps.maxCombinedTextureImageUnits = 64;
+    }
+
     return caps;
 }
 }
 
 namespace egl
 {
 
 Caps::Caps()
@@ -1081,26 +1136,28 @@ DisplayExtensions::DisplayExtensions()
       glRenderbufferImage(false),
       getAllProcAddresses(false),
       flexibleSurfaceCompatibility(false),
       directComposition(false),
       createContextNoError(false),
       stream(false),
       streamConsumerGLTexture(false),
       streamConsumerGLTextureYUV(false),
-      streamProducerD3DTextureNV12(false),
+      streamProducerD3DTexture(false),
       createContextWebGLCompatibility(false),
       createContextBindGeneratesResource(false),
       getSyncValues(false),
       swapBuffersWithDamage(false),
       pixelFormatFloat(false),
       surfacelessContext(false),
       displayTextureShareGroup(false),
       createContextClientArrays(false),
-      programCacheControl(false)
+      programCacheControl(false),
+      robustResourceInitialization(false),
+      iosurfaceClientBuffer(false)
 {
 }
 
 std::vector<std::string> DisplayExtensions::getStrings() const
 {
     std::vector<std::string> extensionStrings;
 
     // clang-format off
@@ -1124,26 +1181,28 @@ std::vector<std::string> DisplayExtensio
     InsertExtensionString("EGL_KHR_gl_texture_cubemap_image",                    glTextureCubemapImage,              &extensionStrings);
     InsertExtensionString("EGL_KHR_gl_texture_3D_image",                         glTexture3DImage,                   &extensionStrings);
     InsertExtensionString("EGL_KHR_gl_renderbuffer_image",                       glRenderbufferImage,                &extensionStrings);
     InsertExtensionString("EGL_KHR_get_all_proc_addresses",                      getAllProcAddresses,                &extensionStrings);
     InsertExtensionString("EGL_KHR_stream",                                      stream,                             &extensionStrings);
     InsertExtensionString("EGL_KHR_stream_consumer_gltexture",                   streamConsumerGLTexture,            &extensionStrings);
     InsertExtensionString("EGL_NV_stream_consumer_gltexture_yuv",                streamConsumerGLTextureYUV,         &extensionStrings);
     InsertExtensionString("EGL_ANGLE_flexible_surface_compatibility",            flexibleSurfaceCompatibility,       &extensionStrings);
-    InsertExtensionString("EGL_ANGLE_stream_producer_d3d_texture_nv12",          streamProducerD3DTextureNV12,       &extensionStrings);
+    InsertExtensionString("EGL_ANGLE_stream_producer_d3d_texture",               streamProducerD3DTexture,           &extensionStrings);
     InsertExtensionString("EGL_ANGLE_create_context_webgl_compatibility",        createContextWebGLCompatibility,    &extensionStrings);
     InsertExtensionString("EGL_CHROMIUM_create_context_bind_generates_resource", createContextBindGeneratesResource, &extensionStrings);
     InsertExtensionString("EGL_CHROMIUM_sync_control",                           getSyncValues,                      &extensionStrings);
     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);
     // TODO(jmadill): Enable this when complete.
     //InsertExtensionString("KHR_create_context_no_error",                       createContextNoError,               &extensionStrings);
     // clang-format on
 
     return extensionStrings;
 }
 
 DeviceExtensions::DeviceExtensions()
@@ -1168,21 +1227,22 @@ ClientExtensions::ClientExtensions()
       platformANGLE(false),
       platformANGLED3D(false),
       platformANGLEOpenGL(false),
       platformANGLEVulkan(false),
       deviceCreation(false),
       deviceCreationD3D11(false),
       x11Visual(false),
       experimentalPresentPath(false),
-      clientGetAllProcAddresses(false),
-      displayRobustResourceInitialization(false)
+      clientGetAllProcAddresses(false)
 {
 }
 
+ClientExtensions::ClientExtensions(const ClientExtensions &other) = default;
+
 std::vector<std::string> ClientExtensions::getStrings() const
 {
     std::vector<std::string> extensionStrings;
 
     // clang-format off
     //                   | Extension name                         | Supported flag           | Output vector   |
     InsertExtensionString("EGL_EXT_client_extensions",             clientExtensions,          &extensionStrings);
     InsertExtensionString("EGL_EXT_platform_base",                 platformBase,              &extensionStrings);
@@ -1192,15 +1252,14 @@ std::vector<std::string> ClientExtension
     InsertExtensionString("EGL_ANGLE_platform_angle_opengl",       platformANGLEOpenGL,       &extensionStrings);
     InsertExtensionString("EGL_ANGLE_platform_angle_null",         platformANGLENULL,         &extensionStrings);
     InsertExtensionString("EGL_ANGLE_platform_angle_vulkan",       platformANGLEVulkan,       &extensionStrings);
     InsertExtensionString("EGL_ANGLE_device_creation",             deviceCreation,            &extensionStrings);
     InsertExtensionString("EGL_ANGLE_device_creation_d3d11",       deviceCreationD3D11,       &extensionStrings);
     InsertExtensionString("EGL_ANGLE_x11_visual",                  x11Visual,                 &extensionStrings);
     InsertExtensionString("EGL_ANGLE_experimental_present_path",   experimentalPresentPath,   &extensionStrings);
     InsertExtensionString("EGL_KHR_client_get_all_proc_addresses", clientGetAllProcAddresses, &extensionStrings);
-    InsertExtensionString("EGL_ANGLE_display_robust_resource_initialization", displayRobustResourceInitialization, &extensionStrings);
     // clang-format on
 
     return extensionStrings;
 }
 
 }  // namespace egl
--- a/gfx/angle/src/libANGLE/Caps.h
+++ b/gfx/angle/src/libANGLE/Caps.h
@@ -3,18 +3,19 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 //
 
 #ifndef LIBANGLE_CAPS_H_
 #define LIBANGLE_CAPS_H_
 
 #include "angle_gl.h"
+#include "libANGLE/Version.h"
 #include "libANGLE/angletypes.h"
-#include "libANGLE/Version.h"
+#include "libANGLE/renderer/Format.h"
 
 #include <map>
 #include <set>
 #include <string>
 #include <vector>
 #include <array>
 
 namespace gl
@@ -22,16 +23,18 @@ namespace gl
 
 struct Extensions;
 
 typedef std::set<GLuint> SupportedSampleSet;
 
 struct TextureCaps
 {
     TextureCaps();
+    TextureCaps(const TextureCaps &other);
+    ~TextureCaps();
 
     // Supports for basic texturing: glTexImage, glTexSubImage, etc
     bool texturable;
 
     // Support for linear or anisotropic filtering
     bool filterable;
 
     // Support for being used as a framebuffer attachment or renderbuffer format
@@ -47,39 +50,42 @@ struct TextureCaps
     // there are no sample counts available
     GLuint getNearestSamples(GLuint requestedSamples) const;
 };
 
 TextureCaps GenerateMinimumTextureCaps(GLenum internalFormat,
                                        const Version &clientVersion,
                                        const Extensions &extensions);
 
-class TextureCapsMap
+class TextureCapsMap final : angle::NonCopyable
 {
   public:
-    typedef std::map<GLenum, TextureCaps>::const_iterator const_iterator;
+    TextureCapsMap();
+    ~TextureCapsMap();
 
+    // These methods are deprecated. Please use angle::Format for new features.
     void insert(GLenum internalFormat, const TextureCaps &caps);
-    void remove(GLenum internalFormat);
-    void clear();
-
     const TextureCaps &get(GLenum internalFormat) const;
 
-    const_iterator begin() const;
-    const_iterator end() const;
+    void clear();
 
-    size_t size() const;
+    // Prefer using angle::Format methods.
+    const TextureCaps &get(angle::Format::ID formatID) const;
+    void set(angle::Format::ID formatID, const TextureCaps &caps);
 
   private:
-    typedef std::map<GLenum, TextureCaps> InternalFormatToCapsMap;
-    InternalFormatToCapsMap mCapsMap;
+    TextureCaps &get(angle::Format::ID formatID);
+
+    // Indexed by angle::Format::ID
+    std::array<TextureCaps, angle::kNumANGLEFormats> mFormatData;
 };
 
-TextureCapsMap GenerateMinimumTextureCapsMap(const Version &clientVersion,
-                                             const Extensions &extensions);
+void InitMinimumTextureCapsMap(const Version &clientVersion,
+                               const Extensions &extensions,
+                               TextureCapsMap *capsMap);
 
 struct Extensions
 {
     Extensions();
 
     // Generate a vector of supported extension strings
     std::vector<std::string> getStrings() const;
 
@@ -202,19 +208,16 @@ struct Extensions
     GLfloat maxTextureAnisotropy;
 
     // GL_EXT_occlusion_query_boolean
     bool occlusionQueryBoolean;
 
     // GL_NV_fence
     bool fence;
 
-    // GL_ANGLE_timer_query
-    bool timerQuery;
-
     // GL_EXT_disjoint_timer_query
     bool disjointTimerQuery;
     GLuint queryCounterBitsTimeElapsed;
     GLuint queryCounterBitsTimestamp;
 
     // GL_EXT_robustness
     bool robustness;
 
@@ -237,25 +240,16 @@ struct Extensions
     bool packReverseRowOrder;
 
     // GL_OES_standard_derivatives
     bool standardDerivatives;
 
     // GL_EXT_shader_texture_lod
     bool shaderTextureLOD;
 
-    // GL_EXT_shader_framebuffer_fetch
-    bool shaderFramebufferFetch;
-
-    // GL_ARM_shader_framebuffer_fetch
-    bool ARMshaderFramebufferFetch;
-
-    // GL_NV_shader_framebuffer_fetch
-    bool NVshaderFramebufferFetch;
-
     // GL_EXT_frag_depth
     bool fragDepth;
 
     // ANGLE_multiview
     bool multiview;
     GLuint maxViews;
 
     // GL_ANGLE_texture_usage
@@ -371,16 +365,19 @@ struct Extensions
     // GL_ANGLE_robust_resource_initialization
     bool robustResourceInitialization;
 
     // GL_ANGLE_program_cache_control
     bool programCacheControl;
 
     // GL_ANGLE_texture_rectangle
     bool textureRectangle;
+
+    // GL_EXT_geometry_shader
+    bool geometryShader;
 };
 
 struct ExtensionInfo
 {
     // If this extension can be enabled with glRequestExtension (GL_ANGLE_request_extension)
     bool Requestable = false;
 
     // Pointer to a boolean member of the Extensions struct
@@ -413,31 +410,34 @@ struct Limitations
     // Renderer doesn't support Simultaneous use of GL_CONSTANT_ALPHA/GL_ONE_MINUS_CONSTANT_ALPHA
     // and GL_CONSTANT_COLOR/GL_ONE_MINUS_CONSTANT_COLOR blend functions.
     bool noSimultaneousConstantColorAndAlphaBlendFunc;
 };
 
 struct TypePrecision
 {
     TypePrecision();
+    TypePrecision(const TypePrecision &other);
 
     void setIEEEFloat();
     void setTwosComplementInt(unsigned int bits);
     void setSimulatedFloat(unsigned int range, unsigned int precision);
     void setSimulatedInt(unsigned int range);
 
     void get(GLint *returnRange, GLint *returnPrecision) const;
 
     std::array<GLint, 2> range;
     GLint precision;
 };
 
 struct Caps
 {
     Caps();
+    Caps(const Caps &other);
+    ~Caps();
 
     // ES 3.1 (April 29, 2015) 20.39: implementation dependent values
     GLuint64 maxElementIndex;
     GLuint max3DTextureSize;
     GLuint max2DTextureSize;
     GLuint maxRectangleTextureSize;
     GLuint maxArrayTextureLayers;
     GLfloat maxLODBias;
@@ -552,19 +552,42 @@ struct Caps
 
     // ES 3.1 (April 29, 2015) Table 20.48: implementation dependent transform feedback limits
     GLuint maxTransformFeedbackInterleavedComponents;
     GLuint maxTransformFeedbackSeparateAttributes;
     GLuint maxTransformFeedbackSeparateComponents;
 
     // ES 3.1 (April 29, 2015) Table 20.49: Framebuffer Dependent Values
     GLuint maxSamples;
+
+    // GL_EXT_geometry_shader (May 31, 2016) Table 20.40: Implementation-Dependent Values (cont.)
+    GLuint maxFramebufferLayers;
+    GLuint layerProvokingVertex;
+
+    // GL_EXT_geometry_shader (May 31, 2016) Table 20.43gs: Implementation dependent geometry shader
+    // limits
+    GLuint maxGeometryUniformComponents;
+    GLuint maxGeometryUniformBlocks;
+    GLuint maxGeometryInputComponents;
+    GLuint maxGeometryOutputComponents;
+    GLuint maxGeometryOutputVertices;
+    GLuint maxGeometryTotalOutputComponents;
+    GLuint maxGeometryTextureImageUnits;
+    GLuint maxGeometryAtomicCounterBuffers;
+    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;
 };
 
-Caps GenerateMinimumCaps(const Version &clientVersion);
+Caps GenerateMinimumCaps(const Version &clientVersion, const Extensions &extensions);
 }
 
 namespace egl
 {
 
 struct Caps
 {
     Caps();
@@ -650,18 +673,18 @@ struct DisplayExtensions
     bool stream;
 
     // EGL_KHR_stream_consumer_gltexture
     bool streamConsumerGLTexture;
 
     // EGL_NV_stream_consumer_gltexture_yuv
     bool streamConsumerGLTextureYUV;
 
-    // EGL_ANGLE_stream_producer_d3d_texture_nv12
-    bool streamProducerD3DTextureNV12;
+    // EGL_ANGLE_stream_producer_d3d_texture
+    bool streamProducerD3DTexture;
 
     // EGL_ANGLE_create_context_webgl_compatibility
     bool createContextWebGLCompatibility;
 
     // EGL_CHROMIUM_create_context_bind_generates_resource
     bool createContextBindGeneratesResource;
 
     // EGL_CHROMIUM_get_sync_values
@@ -679,32 +702,39 @@ struct DisplayExtensions
     // EGL_ANGLE_display_texture_share_group
     bool displayTextureShareGroup;
 
     // EGL_ANGLE_create_context_client_arrays
     bool createContextClientArrays;
 
     // EGL_ANGLE_program_cache_control
     bool programCacheControl;
+
+    // EGL_ANGLE_robust_resource_initialization
+    bool robustResourceInitialization;
+
+    // EGL_ANGLE_iosurface_client_buffer
+    bool iosurfaceClientBuffer;
 };
 
 struct DeviceExtensions
 {
     DeviceExtensions();
 
     // Generate a vector of supported extension strings
     std::vector<std::string> getStrings() const;
 
     // EGL_ANGLE_device_d3d
     bool deviceD3D;
 };
 
 struct ClientExtensions
 {
     ClientExtensions();
+    ClientExtensions(const ClientExtensions &other);
 
     // Generate a vector of supported extension strings
     std::vector<std::string> getStrings() const;
 
     // EGL_EXT_client_extensions
     bool clientExtensions;
 
     // EGL_EXT_platform_base
@@ -737,16 +767,13 @@ struct ClientExtensions
     // EGL_ANGLE_x11_visual
     bool x11Visual;
 
     // EGL_ANGLE_experimental_present_path
     bool experimentalPresentPath;
 
     // EGL_KHR_client_get_all_proc_addresses
     bool clientGetAllProcAddresses;
-
-    // EGL_ANGLE_display_robust_resource_initialization
-    bool displayRobustResourceInitialization;
 };
 
 }  // namespace egl
 
 #endif // LIBANGLE_CAPS_H_
--- a/gfx/angle/src/libANGLE/Compiler.cpp
+++ b/gfx/angle/src/libANGLE/Compiler.cpp
@@ -45,17 +45,18 @@ Compiler::Compiler(rx::GLImplFactory *im
     : mImplementation(implFactory->createCompiler()),
       mSpec(SelectShaderSpec(state.getClientMajorVersion(),
                              state.getClientMinorVersion(),
                              state.getExtensions().webglCompatibility)),
       mOutputType(mImplementation->getTranslatorOutputType()),
       mResources(),
       mFragmentCompiler(nullptr),
       mVertexCompiler(nullptr),
-      mComputeCompiler(nullptr)
+      mComputeCompiler(nullptr),
+      mGeometryCompiler(nullptr)
 {
     ASSERT(state.getClientMajorVersion() == 2 || state.getClientMajorVersion() == 3);
 
     const gl::Caps &caps             = state.getCaps();
     const gl::Extensions &extensions = state.getExtensions();
 
     sh::InitBuiltInResources(&mResources);
     mResources.MaxVertexAttribs             = caps.maxVertexAttributes;
@@ -124,16 +125,31 @@ Compiler::Compiler(rx::GLImplFactory *im
 
     // Needed by point size clamping workaround
     mResources.MaxPointSize = caps.maxAliasedPointSize;
 
     if (state.getClientMajorVersion() == 2 && !extensions.drawBuffers)
     {
         mResources.MaxDrawBuffers = 1;
     }
+
+    // Geometry Shader constants
+    mResources.EXT_geometry_shader              = extensions.geometryShader;
+    mResources.MaxGeometryUniformComponents     = caps.maxGeometryUniformComponents;
+    mResources.MaxGeometryUniformBlocks         = caps.maxGeometryUniformBlocks;
+    mResources.MaxGeometryInputComponents       = caps.maxGeometryInputComponents;
+    mResources.MaxGeometryOutputComponents      = caps.maxGeometryOutputComponents;
+    mResources.MaxGeometryOutputVertices        = caps.maxGeometryOutputVertices;
+    mResources.MaxGeometryTotalOutputComponents = caps.maxGeometryTotalOutputComponents;
+    mResources.MaxGeometryTextureImageUnits     = caps.maxGeometryTextureImageUnits;
+    mResources.MaxGeometryAtomicCounterBuffers  = caps.maxGeometryAtomicCounterBuffers;
+    mResources.MaxGeometryAtomicCounters        = caps.maxGeometryAtomicCounters;
+    mResources.MaxGeometryShaderStorageBlocks   = caps.maxGeometryShaderStorageBlocks;
+    mResources.MaxGeometryShaderInvocations     = caps.maxGeometryShaderInvocations;
+    mResources.MaxGeometryImageUniforms         = caps.maxGeometryImageUniforms;
 }
 
 Compiler::~Compiler()
 {
     if (mFragmentCompiler)
     {
         sh::Destruct(mFragmentCompiler);
         mFragmentCompiler = nullptr;
@@ -155,16 +171,25 @@ Compiler::~Compiler()
     {
         sh::Destruct(mComputeCompiler);
         mComputeCompiler = nullptr;
 
         ASSERT(activeCompilerHandles > 0);
         activeCompilerHandles--;
     }
 
+    if (mGeometryCompiler)
+    {
+        sh::Destruct(mGeometryCompiler);
+        mGeometryCompiler = nullptr;
+
+        ASSERT(activeCompilerHandles > 0);
+        activeCompilerHandles--;
+    }
+
     if (activeCompilerHandles == 0)
     {
         sh::Finalize();
     }
 
     ANGLE_SWALLOW_ERR(mImplementation->release());
 }
 
@@ -178,16 +203,19 @@ ShHandle Compiler::getCompilerHandle(GLe
             break;
 
         case GL_FRAGMENT_SHADER:
             compiler = &mFragmentCompiler;
             break;
         case GL_COMPUTE_SHADER:
             compiler = &mComputeCompiler;
             break;
+        case GL_GEOMETRY_SHADER_EXT:
+            compiler = &mGeometryCompiler;
+            break;
         default:
             UNREACHABLE();
             return nullptr;
     }
 
     if (!(*compiler))
     {
         if (activeCompilerHandles == 0)
--- a/gfx/angle/src/libANGLE/Compiler.h
+++ b/gfx/angle/src/libANGLE/Compiler.h
@@ -38,13 +38,14 @@ class Compiler final : public RefCountOb
     std::unique_ptr<rx::CompilerImpl> mImplementation;
     ShShaderSpec mSpec;
     ShShaderOutput mOutputType;
     ShBuiltInResources mResources;
 
     ShHandle mFragmentCompiler;
     ShHandle mVertexCompiler;
     ShHandle mComputeCompiler;
+    ShHandle mGeometryCompiler;
 };
 
 }  // namespace gl
 
 #endif // LIBANGLE_COMPILER_H_
--- a/gfx/angle/src/libANGLE/Config.cpp
+++ b/gfx/angle/src/libANGLE/Config.cpp
@@ -58,16 +58,32 @@ Config::Config()
       transparentRedValue(0),
       transparentGreenValue(0),
       transparentBlueValue(0),
       optimalOrientation(0),
       colorComponentType(EGL_COLOR_COMPONENT_TYPE_FIXED_EXT)
 {
 }
 
+Config::~Config()
+{
+}
+
+Config::Config(const Config &other) = default;
+
+Config &Config::operator=(const Config &other) = default;
+
+ConfigSet::ConfigSet() = default;
+
+ConfigSet::ConfigSet(const ConfigSet &other) = default;
+
+ConfigSet &ConfigSet::operator=(const ConfigSet &other) = default;
+
+ConfigSet::~ConfigSet() = default;
+
 EGLint ConfigSet::add(const Config &config)
 {
     // Set the config's ID to a small number that starts at 1 ([EGL 1.5] section 3.4)
     EGLint id = static_cast<EGLint>(mConfigs.size()) + 1;
 
     Config copyConfig(config);
     copyConfig.configID = id;
     mConfigs.insert(std::make_pair(id, copyConfig));
--- a/gfx/angle/src/libANGLE/Config.h
+++ b/gfx/angle/src/libANGLE/Config.h
@@ -22,16 +22,19 @@
 #include <vector>
 
 namespace egl
 {
 
 struct Config
 {
     Config();
+    ~Config();
+    Config(const Config &other);
+    Config &operator=(const Config &other);
 
     GLenum renderTargetFormat;      // TODO(geofflang): remove this
     GLenum depthStencilFormat;      // TODO(geofflang): remove this
 
     EGLint bufferSize;              // Depth of the color buffer
     EGLint redSize;                 // Bits of Red in the color buffer
     EGLint greenSize;               // Bits of Green in the color buffer
     EGLint blueSize;                // Bits of Blue in the color buffer
@@ -66,28 +69,33 @@ struct Config
     EGLint transparentBlueValue;    // Transparent blue value
     EGLint optimalOrientation;      // Optimal window surface orientation
     EGLenum colorComponentType;     // Color component type
 };
 
 class ConfigSet
 {
   public:
+    ConfigSet();
+    ConfigSet(const ConfigSet &other);
+    ~ConfigSet();
+    ConfigSet &operator=(const ConfigSet &other);
+
     EGLint add(const Config &config);
     const Config &get(EGLint id) const;
 
     void clear();
 
     size_t size() const;
 
     bool contains(const Config *config) const;
 
     // Filter configurations based on the table in [EGL 1.5] section 3.4.1.2 page 29
     std::vector<const Config*> filter(const AttributeMap &attributeMap) const;
 
   private:
-    typedef std::map<EGLint, const Config> ConfigMap;
+    typedef std::map<EGLint, Config> ConfigMap;
     ConfigMap mConfigs;
 };
 
 }
 
 #endif   // INCLUDE_CONFIG_H_
--- a/gfx/angle/src/libANGLE/Constants.h
+++ b/gfx/angle/src/libANGLE/Constants.h
@@ -49,13 +49,14 @@ enum
     IMPLEMENTATION_MAX_CUBE_MAP_TEXTURE_SIZE   = 16384,
     IMPLEMENTATION_MAX_3D_TEXTURE_SIZE         = 2048,
     IMPLEMENTATION_MAX_2D_ARRAY_TEXTURE_LAYERS = 2048,
 
     // 1+log2 of max of MAX_*_TEXTURE_SIZE
     IMPLEMENTATION_MAX_TEXTURE_LEVELS = 15,
 
     // Limit active textures so we can use fast bitsets.
-    IMPLEMENTATION_MAX_ACTIVE_TEXTURES = 64,
+    IMPLEMENTATION_MAX_SHADER_TEXTURES = 32,
+    IMPLEMENTATION_MAX_ACTIVE_TEXTURES = IMPLEMENTATION_MAX_SHADER_TEXTURES * 2,
 };
 }
 
 #endif // LIBANGLE_CONSTANTS_H_
--- a/gfx/angle/src/libANGLE/Context.cpp
+++ b/gfx/angle/src/libANGLE/Context.cpp
@@ -36,16 +36,17 @@
 #include "libANGLE/TransformFeedback.h"
 #include "libANGLE/VertexArray.h"
 #include "libANGLE/Workarounds.h"
 #include "libANGLE/formatutils.h"
 #include "libANGLE/queryconversions.h"
 #include "libANGLE/queryutils.h"
 #include "libANGLE/renderer/ContextImpl.h"
 #include "libANGLE/renderer/EGLImplFactory.h"
+#include "libANGLE/renderer/Format.h"
 #include "libANGLE/validationES.h"
 
 namespace
 {
 
 #define ANGLE_HANDLE_ERR(X) \
     handleError(X);         \
     return;
@@ -113,17 +114,17 @@ gl::Error GetQueryObjectParameter(gl::Qu
         case GL_QUERY_RESULT_EXT:
             return query->getResult(params);
         case GL_QUERY_RESULT_AVAILABLE_EXT:
         {
             bool available;
             gl::Error error = query->isResultAvailable(&available);
             if (!error.isError())
             {
-                *params = gl::ConvertFromGLboolean<T>(available);
+                *params = gl::CastFromStateValue<T>(pname, static_cast<GLuint>(available));
             }
             return error;
         }
         default:
             UNREACHABLE();
             return gl::InternalError() << "Unreachable Error";
     }
 }
@@ -158,26 +159,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_KHR, 0);
-    if (!attrib)
-    {
-        attrib = attribs.get(EGL_CONTEXT_OPENGL_RESET_NOTIFICATION_STRATEGY_EXT, 0);
-    }
-    if (!attrib)
-    {
-        attrib = 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();
@@ -213,16 +206,21 @@ bool GetBindGeneratesResource(const egl:
     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);
 }
 
+bool GetRobustResourceInit(const egl::AttributeMap &attribs)
+{
+    return (attribs.get(EGL_ROBUST_RESOURCE_INITIALIZATION_ANGLE, EGL_FALSE) == EGL_TRUE);
+}
+
 std::string GetObjectLabelFromPointer(GLsizei length, const GLchar *label)
 {
     std::string labelName;
     if (label != nullptr)
     {
         size_t labelLength = length < 0 ? strlen(label) : length;
         labelName          = std::string(label, labelLength);
     }
@@ -260,18 +258,17 @@ 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,
-                 bool robustResourceInit)
+                 const egl::DisplayExtensions &displayExtensions)
 
     : ValidationContext(shareContext,
                         shareTextures,
                         GetClientVersion(attribs),
                         &mGLState,
                         mCaps,
                         mTextureCaps,
                         mExtensions,
@@ -292,27 +289,28 @@ Context::Context(rx::EGLImplFactory *imp
       mSurfacelessFramebuffer(nullptr),
       mWebGLContext(GetWebGLContext(attribs)),
       mMemoryProgramCache(memoryProgramCache),
       mScratchBuffer(1000u),
       mZeroFilledBuffer(1000u)
 {
     mImplementation->setMemoryProgramCache(memoryProgramCache);
 
-    initCaps(displayExtensions);
+    bool robustResourceInit = GetRobustResourceInit(attribs);
+    initCaps(displayExtensions, robustResourceInit);
     initWorkarounds();
 
     mGLState.initialize(this, GetDebug(attribs), GetBindGeneratesResource(attribs),
                         GetClientArraysEnabled(attribs), robustResourceInit,
                         mMemoryProgramCache != nullptr);
 
     mFenceNVHandleAllocator.setBaseHandle(0);
 
     // [OpenGL ES 2.0.24] section 3.7 page 83:
-    // In the initial state, TEXTURE_2D and TEXTURE_CUBE_MAP have twodimensional
+    // 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);
@@ -328,89 +326,74 @@ Context::Context(rx::EGLImplFactory *imp
         mZeroTextures[GL_TEXTURE_2D_ARRAY].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);
 
-        bindGenericAtomicCounterBuffer(0);
         for (unsigned int i = 0; i < mCaps.maxAtomicCounterBufferBindings; i++)
         {
-            bindIndexedAtomicCounterBuffer(0, i, 0, 0);
+            bindBufferRange(BufferBinding::AtomicCounter, 0, i, 0, 0);
         }
 
-        bindGenericShaderStorageBuffer(0);
         for (unsigned int i = 0; i < mCaps.maxShaderStorageBufferBindings; i++)
         {
-            bindIndexedShaderStorageBuffer(0, i, 0, 0);
+            bindBufferRange(BufferBinding::ShaderStorage, i, 0, 0, 0);
         }
     }
 
-    if (mExtensions.textureRectangle)
+    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);
     }
 
-    if (mExtensions.eglImageExternal || mExtensions.eglStreamConsumerExternal)
+    if (nativeExtensions.eglImageExternal || nativeExtensions.eglStreamConsumerExternal)
     {
         Texture *zeroTextureExternal =
             new Texture(mImplementation.get(), 0, GL_TEXTURE_EXTERNAL_OES);
         mZeroTextures[GL_TEXTURE_EXTERNAL_OES].set(this, zeroTextureExternal);
     }
 
     mGLState.initializeZeroTextures(this, mZeroTextures);
 
     bindVertexArray(0);
-    bindArrayBuffer(0);
-    bindDrawIndirectBuffer(0);
-    bindElementArrayBuffer(0);
-
-    bindRenderbuffer(GL_RENDERBUFFER, 0);
-
-    bindGenericUniformBuffer(0);
-    for (unsigned int i = 0; i < mCaps.maxUniformBufferBindings; i++)
-    {
-        bindIndexedUniformBuffer(0, i, 0, -1);
-    }
-
-    bindCopyReadBuffer(0);
-    bindCopyWriteBuffer(0);
-    bindPixelPackBuffer(0);
-    bindPixelUnpackBuffer(0);
 
     if (getClientVersion() >= Version(3, 0))
     {
         // [OpenGL ES 3.0.2] section 2.14.1 pg 85:
         // In the initial state, a default transform feedback object is bound and treated as
         // a transform feedback object with a name of zero. That object is bound any time
         // BindTransformFeedback is called with id of zero
         bindTransformFeedback(GL_TRANSFORM_FEEDBACK, 0);
     }
 
+    for (auto type : angle::AllEnums<BufferBinding>())
+    {
+        bindBuffer(type, 0);
+    }
+
+    bindRenderbuffer(GL_RENDERBUFFER, 0);
+
+    for (unsigned int i = 0; i < mCaps.maxUniformBufferBindings; i++)
+    {
+        bindBufferRange(BufferBinding::Uniform, i, 0, 0, -1);
+    }
+
     // Initialize dirty bit masks
-    // TODO(jmadill): additional ES3 state
-    mTexImageDirtyBits.set(State::DIRTY_BIT_UNPACK_ALIGNMENT);
-    mTexImageDirtyBits.set(State::DIRTY_BIT_UNPACK_ROW_LENGTH);
-    mTexImageDirtyBits.set(State::DIRTY_BIT_UNPACK_IMAGE_HEIGHT);
-    mTexImageDirtyBits.set(State::DIRTY_BIT_UNPACK_SKIP_IMAGES);
-    mTexImageDirtyBits.set(State::DIRTY_BIT_UNPACK_SKIP_ROWS);
-    mTexImageDirtyBits.set(State::DIRTY_BIT_UNPACK_SKIP_PIXELS);
+    mTexImageDirtyBits.set(State::DIRTY_BIT_UNPACK_STATE);
     mTexImageDirtyBits.set(State::DIRTY_BIT_UNPACK_BUFFER_BINDING);
     // No dirty objects.
 
     // Readpixels uses the pack state and read FBO
-    mReadPixelsDirtyBits.set(State::DIRTY_BIT_PACK_ALIGNMENT);
-    mReadPixelsDirtyBits.set(State::DIRTY_BIT_PACK_REVERSE_ROW_ORDER);
-    mReadPixelsDirtyBits.set(State::DIRTY_BIT_PACK_ROW_LENGTH);
-    mReadPixelsDirtyBits.set(State::DIRTY_BIT_PACK_SKIP_ROWS);
-    mReadPixelsDirtyBits.set(State::DIRTY_BIT_PACK_SKIP_PIXELS);
+    mReadPixelsDirtyBits.set(State::DIRTY_BIT_PACK_STATE);
     mReadPixelsDirtyBits.set(State::DIRTY_BIT_PACK_BUFFER_BINDING);
     mReadPixelsDirtyObjects.set(State::DIRTY_OBJECT_READ_FRAMEBUFFER);
 
     mClearDirtyBits.set(State::DIRTY_BIT_RASTERIZER_DISCARD_ENABLED);
     mClearDirtyBits.set(State::DIRTY_BIT_SCISSOR_TEST_ENABLED);
     mClearDirtyBits.set(State::DIRTY_BIT_SCISSOR);
     mClearDirtyBits.set(State::DIRTY_BIT_VIEWPORT);
     mClearDirtyBits.set(State::DIRTY_BIT_CLEAR_COLOR);
@@ -423,16 +406,24 @@ Context::Context(rx::EGLImplFactory *imp
     mClearDirtyObjects.set(State::DIRTY_OBJECT_DRAW_FRAMEBUFFER);
 
     mBlitDirtyBits.set(State::DIRTY_BIT_SCISSOR_TEST_ENABLED);
     mBlitDirtyBits.set(State::DIRTY_BIT_SCISSOR);
     mBlitDirtyBits.set(State::DIRTY_BIT_FRAMEBUFFER_SRGB);
     mBlitDirtyObjects.set(State::DIRTY_OBJECT_READ_FRAMEBUFFER);
     mBlitDirtyObjects.set(State::DIRTY_OBJECT_DRAW_FRAMEBUFFER);
 
+    // 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);
+
     handleError(mImplementation->initialize());
 }
 
 egl::Error Context::onDestroy(const egl::Display *display)
 {
     for (auto fence : mFenceNVMap)
     {
         SafeDelete(fence.second);
@@ -485,16 +476,18 @@ egl::Error Context::onDestroy(const egl:
     mState.mTextures->release(this);
     mState.mRenderbuffers->release(this);
     mState.mSamplers->release(this);
     mState.mSyncs->release(this);
     mState.mPaths->release(this);
     mState.mFramebuffers->release(this);
     mState.mPipelines->release(this);
 
+    mImplementation->onDestroy(this);
+
     return egl::NoError();
 }
 
 Context::~Context()
 {
 }
 
 egl::Error Context::makeCurrent(egl::Display *display, egl::Surface *surface)
@@ -632,28 +625,37 @@ GLuint Context::createPaths(GLsizei rang
 }
 
 // Returns an unused framebuffer name
 GLuint Context::createFramebuffer()
 {
     return mState.mFramebuffers->createFramebuffer();
 }
 
-GLuint Context::createFenceNV()
-{
-    GLuint handle = mFenceNVHandleAllocator.allocate();
-    mFenceNVMap.assign(handle, new FenceNV(mImplementation->createFenceNV()));
-    return handle;
+void Context::genFencesNV(GLsizei n, GLuint *fences)
+{
+    for (int i = 0; i < n; i++)
+    {
+        GLuint handle = mFenceNVHandleAllocator.allocate();
+        mFenceNVMap.assign(handle, new FenceNV(mImplementation->createFenceNV()));
+        fences[i] = handle;
+    }
 }
 
 GLuint Context::createProgramPipeline()
 {
     return mState.mPipelines->createProgramPipeline();
 }
 
+GLuint Context::createShaderProgramv(GLenum type, GLsizei count, const GLchar *const *strings)
+{
+    UNIMPLEMENTED();
+    return 0u;
+}
+
 void Context::deleteBuffer(GLuint buffer)
 {
     if (mState.mBuffers->getBuffer(buffer))
     {
         detachBuffer(buffer);
     }
 
     mState.mBuffers->deleteObject(this, buffer);
@@ -734,19 +736,19 @@ void Context::setPathCommands(GLuint pat
                               GLenum coordType,
                               const void *coords)
 {
     auto *pathObject = mState.mPaths->getPath(path);
 
     handleError(pathObject->setCommands(numCommands, commands, numCoords, coordType, coords));
 }
 
-void Context::setPathParameterf(GLuint path, GLenum pname, GLfloat value)
-{
-    auto *pathObj = mState.mPaths->getPath(path);
+void Context::pathParameterf(GLuint path, GLenum pname, GLfloat value)
+{
+    Path *pathObj = mState.mPaths->getPath(path);
 
     switch (pname)
     {
         case GL_PATH_STROKE_WIDTH_CHROMIUM:
             pathObj->setStrokeWidth(value);
             break;
         case GL_PATH_END_CAPS_CHROMIUM:
             pathObj->setEndCaps(static_cast<GLenum>(value));
@@ -761,19 +763,25 @@ void Context::setPathParameterf(GLuint p
             pathObj->setStrokeBound(value);
             break;
         default:
             UNREACHABLE();
             break;
     }
 }
 
-void Context::getPathParameterfv(GLuint path, GLenum pname, GLfloat *value) const
-{
-    const auto *pathObj = mState.mPaths->getPath(path);
+void Context::pathParameteri(GLuint path, GLenum pname, GLint value)
+{
+    // TODO(jmadill): Should use proper clamping/casting.
+    pathParameterf(path, pname, static_cast<GLfloat>(value));
+}
+
+void Context::getPathParameterfv(GLuint path, GLenum pname, GLfloat *value)
+{
+    const Path *pathObj = mState.mPaths->getPath(path);
 
     switch (pname)
     {
         case GL_PATH_STROKE_WIDTH_CHROMIUM:
             *value = pathObj->getStrokeWidth();
             break;
         case GL_PATH_END_CAPS_CHROMIUM:
             *value = static_cast<GLfloat>(pathObj->getEndCaps());
@@ -788,38 +796,51 @@ void Context::getPathParameterfv(GLuint 
             *value = pathObj->getStrokeBound();
             break;
         default:
             UNREACHABLE();
             break;
     }
 }
 
+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)
 {
     mGLState.setPathStencilFunc(func, ref, mask);
 }
 
 void Context::deleteFramebuffer(GLuint framebuffer)
 {
     if (mState.mFramebuffers->getFramebuffer(framebuffer))
     {
         detachFramebuffer(framebuffer);
     }
 
     mState.mFramebuffers->deleteObject(this, framebuffer);
 }
 
-void Context::deleteFenceNV(GLuint fence)
-{
-    FenceNV *fenceObject = nullptr;
-    if (mFenceNVMap.erase(fence, &fenceObject))
-    {
-        mFenceNVHandleAllocator.release(fence);
-        delete fenceObject;
+void Context::deleteFencesNV(GLsizei n, const GLuint *fences)
+{
+    for (int i = 0; i < n; i++)
+    {
+        GLuint fence = fences[i];
+
+        FenceNV *fenceObject = nullptr;
+        if (mFenceNVMap.erase(fence, &fenceObject))
+        {
+            mFenceNVHandleAllocator.release(fence);
+            delete fenceObject;
+        }
     }
 }
 
 Buffer *Context::getBuffer(GLuint handle) const
 {
     return mState.mBuffers->getBuffer(handle);
 }
 
@@ -940,34 +961,16 @@ void Context::getObjectPtrLabel(const vo
     GetObjectLabelBase(objectLabel, bufSize, length, label);
 }
 
 bool Context::isSampler(GLuint samplerName) const
 {
     return mState.mSamplers->isSampler(samplerName);
 }
 
-void Context::bindArrayBuffer(GLuint bufferHandle)
-{
-    Buffer *buffer = mState.mBuffers->checkBufferAllocation(mImplementation.get(), bufferHandle);
-    mGLState.setArrayBufferBinding(this, buffer);
-}
-
-void Context::bindDrawIndirectBuffer(GLuint bufferHandle)
-{
-    Buffer *buffer = mState.mBuffers->checkBufferAllocation(mImplementation.get(), bufferHandle);
-    mGLState.setDrawIndirectBufferBinding(this, buffer);
-}
-
-void Context::bindElementArrayBuffer(GLuint bufferHandle)
-{
-    Buffer *buffer = mState.mBuffers->checkBufferAllocation(mImplementation.get(), bufferHandle);
-    mGLState.setElementArrayBuffer(this, buffer);
-}
-
 void Context::bindTexture(GLenum target, GLuint handle)
 {
     Texture *texture = nullptr;
 
     if (handle == 0)
     {
         texture = mZeroTextures[target].get();
     }
@@ -1024,105 +1027,26 @@ void Context::bindImageTexture(GLuint un
                                GLint layer,
                                GLenum access,
                                GLenum format)
 {
     Texture *tex = mState.mTextures->getTexture(texture);
     mGLState.setImageUnit(this, unit, tex, level, layered, layer, access, format);
 }
 
-void Context::bindGenericUniformBuffer(GLuint bufferHandle)
-{
-    Buffer *buffer = mState.mBuffers->checkBufferAllocation(mImplementation.get(), bufferHandle);
-    mGLState.setGenericUniformBufferBinding(this, buffer);
-}
-
-void Context::bindIndexedUniformBuffer(GLuint bufferHandle,
-                                       GLuint index,
-                                       GLintptr offset,
-                                       GLsizeiptr size)
-{
-    Buffer *buffer = mState.mBuffers->checkBufferAllocation(mImplementation.get(), bufferHandle);
-    mGLState.setIndexedUniformBufferBinding(this, index, buffer, offset, size);
-}
-
-void Context::bindGenericTransformFeedbackBuffer(GLuint bufferHandle)
-{
-    Buffer *buffer = mState.mBuffers->checkBufferAllocation(mImplementation.get(), bufferHandle);
-    mGLState.getCurrentTransformFeedback()->bindGenericBuffer(this, buffer);
-}
-
-void Context::bindIndexedTransformFeedbackBuffer(GLuint bufferHandle,
-                                                 GLuint index,
-                                                 GLintptr offset,
-                                                 GLsizeiptr size)
-{
-    Buffer *buffer = mState.mBuffers->checkBufferAllocation(mImplementation.get(), bufferHandle);
-    mGLState.getCurrentTransformFeedback()->bindIndexedBuffer(this, index, buffer, offset, size);
-}
-
-void Context::bindGenericAtomicCounterBuffer(GLuint bufferHandle)
-{
-    Buffer *buffer = mState.mBuffers->checkBufferAllocation(mImplementation.get(), bufferHandle);
-    mGLState.setGenericAtomicCounterBufferBinding(this, buffer);
-}
-
-void Context::bindIndexedAtomicCounterBuffer(GLuint bufferHandle,
-                                             GLuint index,
-                                             GLintptr offset,
-                                             GLsizeiptr size)
-{
-    Buffer *buffer = mState.mBuffers->checkBufferAllocation(mImplementation.get(), bufferHandle);
-    mGLState.setIndexedAtomicCounterBufferBinding(this, index, buffer, offset, size);
-}
-
-void Context::bindGenericShaderStorageBuffer(GLuint bufferHandle)
-{
-    Buffer *buffer = mState.mBuffers->checkBufferAllocation(mImplementation.get(), bufferHandle);
-    mGLState.setGenericShaderStorageBufferBinding(this, buffer);
-}
-
-void Context::bindIndexedShaderStorageBuffer(GLuint bufferHandle,
-                                             GLuint index,
-                                             GLintptr offset,
-                                             GLsizeiptr size)
-{
-    Buffer *buffer = mState.mBuffers->checkBufferAllocation(mImplementation.get(), bufferHandle);
-    mGLState.setIndexedShaderStorageBufferBinding(this, index, buffer, offset, size);
-}
-
-void Context::bindCopyReadBuffer(GLuint bufferHandle)
-{
-    Buffer *buffer = mState.mBuffers->checkBufferAllocation(mImplementation.get(), bufferHandle);
-    mGLState.setCopyReadBufferBinding(this, buffer);
-}
-
-void Context::bindCopyWriteBuffer(GLuint bufferHandle)
-{
-    Buffer *buffer = mState.mBuffers->checkBufferAllocation(mImplementation.get(), bufferHandle);
-    mGLState.setCopyWriteBufferBinding(this, buffer);
-}
-
-void Context::bindPixelPackBuffer(GLuint bufferHandle)
-{
-    Buffer *buffer = mState.mBuffers->checkBufferAllocation(mImplementation.get(), bufferHandle);
-    mGLState.setPixelPackBufferBinding(this, buffer);
-}
-
-void Context::bindPixelUnpackBuffer(GLuint bufferHandle)
-{
-    Buffer *buffer = mState.mBuffers->checkBufferAllocation(mImplementation.get(), bufferHandle);
-    mGLState.setPixelUnpackBufferBinding(this, buffer);
-}
-
 void Context::useProgram(GLuint program)
 {
     mGLState.setProgram(this, getProgram(program));
 }
 
+void Context::useProgramStages(GLuint pipeline, GLbitfield stages, GLuint program)
+{
+    UNIMPLEMENTED();
+}
+
 void Context::bindTransformFeedback(GLenum target, GLuint transformFeedbackHandle)
 {
     ASSERT(target == GL_TRANSFORM_FEEDBACK);
     TransformFeedback *transformFeedback =
         checkTransformFeedbackAllocation(transformFeedbackHandle);
     mGLState.setTransformFeedbackBinding(this, transformFeedback);
 }
 
@@ -1609,16 +1533,63 @@ void Context::getIntegervImpl(GLenum pna
             *params = mCaps.maxShaderStorageBufferBindings;
             break;
         case GL_MAX_COMBINED_SHADER_STORAGE_BLOCKS:
             *params = mCaps.maxCombinedShaderStorageBlocks;
             break;
         case GL_SHADER_STORAGE_BUFFER_OFFSET_ALIGNMENT:
             *params = mCaps.shaderStorageBufferOffsetAlignment;
             break;
+
+        // GL_EXT_geometry_shader
+        case GL_MAX_FRAMEBUFFER_LAYERS_EXT:
+            *params = mCaps.maxFramebufferLayers;
+            break;
+        case GL_LAYER_PROVOKING_VERTEX_EXT:
+            *params = mCaps.layerProvokingVertex;
+            break;
+        case GL_MAX_GEOMETRY_UNIFORM_COMPONENTS_EXT:
+            *params = mCaps.maxGeometryUniformComponents;
+            break;
+        case GL_MAX_GEOMETRY_UNIFORM_BLOCKS_EXT:
+            *params = mCaps.maxGeometryUniformBlocks;
+            break;
+        case GL_MAX_COMBINED_GEOMETRY_UNIFORM_COMPONENTS_EXT:
+            *params = mCaps.maxCombinedGeometryUniformComponents;
+            break;
+        case GL_MAX_GEOMETRY_INPUT_COMPONENTS_EXT:
+            *params = mCaps.maxGeometryInputComponents;
+            break;
+        case GL_MAX_GEOMETRY_OUTPUT_COMPONENTS_EXT:
+            *params = mCaps.maxGeometryOutputComponents;
+            break;
+        case GL_MAX_GEOMETRY_OUTPUT_VERTICES_EXT:
+            *params = mCaps.maxGeometryOutputVertices;
+            break;
+        case GL_MAX_GEOMETRY_TOTAL_OUTPUT_COMPONENTS_EXT:
+            *params = mCaps.maxGeometryTotalOutputComponents;
+            break;
+        case GL_MAX_GEOMETRY_SHADER_INVOCATIONS_EXT:
+            *params = mCaps.maxGeometryShaderInvocations;
+            break;
+        case GL_MAX_GEOMETRY_TEXTURE_IMAGE_UNITS_EXT:
+            *params = mCaps.maxGeometryTextureImageUnits;
+            break;
+        case GL_MAX_GEOMETRY_ATOMIC_COUNTER_BUFFERS_EXT:
+            *params = mCaps.maxGeometryAtomicCounterBuffers;
+            break;
+        case GL_MAX_GEOMETRY_ATOMIC_COUNTERS_EXT:
+            *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;
         default:
             mGLState.getIntegerv(this, pname, params);
             break;
     }
 }
 
 void Context::getInteger64vImpl(GLenum pname, GLint64 *params)
 {
@@ -1728,29 +1699,29 @@ void Context::getBooleani_v(GLenum targe
         mGLState.getBooleani_v(target, index, data);
     }
     else
     {
         CastIndexedStateValues(this, nativeType, target, index, numParams, data);
     }
 }
 
-void Context::getBufferParameteriv(GLenum target, GLenum pname, GLint *params)
+void Context::getBufferParameteriv(BufferBinding target, GLenum pname, GLint *params)
 {
     Buffer *buffer = mGLState.getTargetBuffer(target);
     QueryBufferParameteriv(buffer, pname, params);
 }
 
 void Context::getFramebufferAttachmentParameteriv(GLenum target,
                                                   GLenum attachment,
                                                   GLenum pname,
                                                   GLint *params)
 {
     const Framebuffer *framebuffer = mGLState.getTargetFramebuffer(target);
-    QueryFramebufferAttachmentParameteriv(framebuffer, attachment, pname, params);
+    QueryFramebufferAttachmentParameteriv(this, framebuffer, attachment, pname, params);
 }
 
 void Context::getRenderbufferParameteriv(GLenum target, GLenum pname, GLint *params)
 {
     Renderbuffer *renderbuffer = mGLState.getCurrentRenderbuffer();
     QueryRenderbufferiv(this, renderbuffer, pname, params);
 }
 
@@ -1760,16 +1731,31 @@ void Context::getTexParameterfv(GLenum t
     QueryTexParameterfv(texture, pname, params);
 }
 
 void Context::getTexParameteriv(GLenum 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);
+    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);
+    QueryTexLevelParameterfv(texture, target, level, pname, params);
+}
+
 void Context::texParameterf(GLenum 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)
@@ -1790,90 +1776,100 @@ void Context::texParameteriv(GLenum targ
 {
     Texture *texture = getTargetTexture(target);
     SetTexParameteriv(this, texture, pname, params);
     onTextureChange(texture);
 }
 
 void Context::drawArrays(GLenum mode, GLint first, GLsizei count)
 {
-    syncRendererState();
+    ANGLE_CONTEXT_TRY(prepareForDraw());
     ANGLE_CONTEXT_TRY(mImplementation->drawArrays(this, mode, first, count));
     MarkTransformFeedbackBufferUsage(mGLState.getCurrentTransformFeedback());
 }
 
 void Context::drawArraysInstanced(GLenum mode, GLint first, GLsizei count, GLsizei instanceCount)
 {
-    syncRendererState();
+    ANGLE_CONTEXT_TRY(prepareForDraw());
     ANGLE_CONTEXT_TRY(
         mImplementation->drawArraysInstanced(this, mode, first, count, instanceCount));
     MarkTransformFeedbackBufferUsage(mGLState.getCurrentTransformFeedback());
 }
 
 void Context::drawElements(GLenum mode, GLsizei count, GLenum type, const void *indices)
 {
-    syncRendererState();
+    ANGLE_CONTEXT_TRY(prepareForDraw());
     ANGLE_CONTEXT_TRY(mImplementation->drawElements(this, mode, count, type, indices));
 }
 
 void Context::drawElementsInstanced(GLenum mode,
                                     GLsizei count,
                                     GLenum type,
                                     const void *indices,
                                     GLsizei instances)
 {
-    syncRendererState();
+    ANGLE_CONTEXT_TRY(prepareForDraw());
     ANGLE_CONTEXT_TRY(
         mImplementation->drawElementsInstanced(this, mode, count, type, indices, instances));
 }
 
 void Context::drawRangeElements(GLenum mode,
                                 GLuint start,
                                 GLuint end,
                                 GLsizei count,
                                 GLenum type,
                                 const void *indices)
 {
-    syncRendererState();
+    ANGLE_CONTEXT_TRY(prepareForDraw());
     ANGLE_CONTEXT_TRY(
         mImplementation->drawRangeElements(this, mode, start, end, count, type, indices));
 }
 
 void Context::drawArraysIndirect(GLenum mode, const void *indirect)
 {
-    syncRendererState();
+    ANGLE_CONTEXT_TRY(prepareForDraw());
     ANGLE_CONTEXT_TRY(mImplementation->drawArraysIndirect(this, mode, indirect));
 }
 
 void Context::drawElementsIndirect(GLenum mode, GLenum type, const void *indirect)
 {
-    syncRendererState();
+    ANGLE_CONTEXT_TRY(prepareForDraw());
     ANGLE_CONTEXT_TRY(mImplementation->drawElementsIndirect(this, mode, type, indirect));
 }
 
 void Context::flush()
 {
-    handleError(mImplementation->flush());
+    handleError(mImplementation->flush(this));
 }
 
 void Context::finish()
 {
-    handleError(mImplementation->finish());
+    handleError(mImplementation->finish(this));
 }
 
 void Context::insertEventMarker(GLsizei length, const char *marker)
 {
     ASSERT(mImplementation);
     mImplementation->insertEventMarker(length, marker);
 }
 
 void Context::pushGroupMarker(GLsizei length, const char *marker)
 {
     ASSERT(mImplementation);
-    mImplementation->pushGroupMarker(length, marker);
+
+    if (marker == nullptr)
+    {
+        // From the EXT_debug_marker spec,
+        // "If <marker> is null then an empty string is pushed on the stack."
+        mImplementation->pushGroupMarker(length, "");
+    }
+    else
+    {
+        mImplementation->pushGroupMarker(length, marker);
+    }
 }
 
 void Context::popGroupMarker()
 {
     ASSERT(mImplementation);
     mImplementation->popGroupMarker();
 }
 
@@ -2157,22 +2153,19 @@ void Context::handleError(const Error &e
     {
         GLenum code = error.getCode();
         mErrors.insert(code);
         if (code == GL_OUT_OF_MEMORY && getWorkarounds().loseContextOnOutOfMemory)
         {
             markContextLost();
         }
 
-        if (!error.getMessage().empty())
-        {
-            auto *debug = &mGLState.getDebug();
-            debug->insertMessage(GL_DEBUG_SOURCE_API, GL_DEBUG_TYPE_ERROR, error.getID(),
-                                 GL_DEBUG_SEVERITY_HIGH, error.getMessage());
-        }
+        ASSERT(!error.getMessage().empty());
+        mGLState.getDebug().insertMessage(GL_DEBUG_SOURCE_API, GL_DEBUG_TYPE_ERROR, error.getID(),
+                                          GL_DEBUG_SEVERITY_HIGH, error.getMessage());
     }
 }
 
 // Get one of the recorded errors and clear its flag, if any.
 // [OpenGL ES 2.0.24] section 2.5 page 13.
 GLenum Context::getError()
 {
     if (mErrors.empty())
@@ -2198,17 +2191,17 @@ void Context::markContextLost()
     mContextLost = true;
 }
 
 bool Context::isContextLost()
 {
     return mContextLost;
 }
 
-GLenum Context::getResetStatus()
+GLenum Context::getGraphicsResetStatus()
 {
     // Even if the application doesn't want to know about resets, we want to know
     // as it will allow us to skip all the calls.
     if (mResetStrategy == GL_NO_RESET_NOTIFICATION_EXT)
     {
         if (!mContextLost && mImplementation->getResetStatus() != GL_NO_ERROR)
         {
             mContextLost = true;
@@ -2262,17 +2255,17 @@ EGLenum Context::getClientType() const
 EGLenum Context::getRenderBuffer() const
 {
     const Framebuffer *framebuffer = mState.mFramebuffers->getFramebuffer(0);
     if (framebuffer == nullptr)
     {
         return EGL_NONE;
     }
 
-    const FramebufferAttachment *backAttachment = framebuffer->getAttachment(GL_BACK);
+    const FramebufferAttachment *backAttachment = framebuffer->getAttachment(this, GL_BACK);
     ASSERT(backAttachment != nullptr);
     return backAttachment->getSurface()->getRenderBuffer();
 }
 
 VertexArray *Context::checkVertexArrayAllocation(GLuint vertexArrayHandle)
 {
     // Only called after a prior call to Gen.
     VertexArray *vertexArray = getVertexArray(vertexArrayHandle);
@@ -2564,22 +2557,33 @@ const GLubyte *Context::getStringi(GLenu
     }
 }
 
 size_t Context::getExtensionStringCount() const
 {
     return mExtensionStrings.size();
 }
 
+bool Context::isExtensionRequestable(const char *name)
+{
+    const ExtensionInfoMap &extensionInfos = GetExtensionInfoMap();
+    auto extension                         = extensionInfos.find(name);
+
+    const Extensions &nativeExtensions = mImplementation->getNativeExtensions();
+    return extension != extensionInfos.end() && extension->second.Requestable &&
+           nativeExtensions.*(extension->second.ExtensionsMember);
+}
+
 void Context::requestExtension(const char *name)
 {
     const ExtensionInfoMap &extensionInfos = GetExtensionInfoMap();
     ASSERT(extensionInfos.find(name) != extensionInfos.end());
     const auto &extension = extensionInfos.at(name);
     ASSERT(extension.Requestable);
+    ASSERT(mImplementation->getNativeExtensions().*(extension.ExtensionsMember));
 
     if (mExtensions.*(extension.ExtensionsMember))
     {
         // Extension already enabled
         return;
     }
 
     mExtensions.*(extension.ExtensionsMember) = true;
@@ -2589,17 +2593,17 @@ 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();
     for (auto &zeroTexture : mZeroTextures)
     {
-        zeroTexture.second->signalDirty();
+        zeroTexture.second->signalDirty(InitState::Initialized);
     }
 
     mState.mFramebuffers->invalidateFramebufferComplenessCache();
 }
 
 size_t Context::getRequestableExtensionStringCount() const
 {
     return mRequestableExtensionStrings.size();
@@ -2621,17 +2625,17 @@ bool Context::hasActiveTransformFeedback
         if (pair.second != nullptr && pair.second->hasBoundProgram(program))
         {
             return true;
         }
     }
     return false;
 }
 
-void Context::initCaps(const egl::DisplayExtensions &displayExtensions)
+void Context::initCaps(const egl::DisplayExtensions &displayExtensions, bool robustResourceInit)
 {
     mCaps = mImplementation->getNativeCaps();
 
     mExtensions = mImplementation->getNativeExtensions();
 
     mLimitations = mImplementation->getNativeLimitations();
 
     if (getClientVersion() < Version(3, 0))
@@ -2639,16 +2643,22 @@ void Context::initCaps(const egl::Displa
         // Disable ES3+ extensions
         mExtensions.colorBufferFloat      = false;
         mExtensions.eglImageExternalEssl3 = false;
         mExtensions.textureNorm16         = false;
         mExtensions.multiview             = false;
         mExtensions.maxViews              = 1u;
     }
 
+    if (getClientVersion() < ES_3_1)
+    {
+        // Disable ES3.1+ extensions
+        mExtensions.geometryShader = false;
+    }
+
     if (getClientVersion() > Version(2, 0))
     {
         // FIXME(geofflang): Don't support EXT_sRGB in non-ES2 contexts
         // mExtensions.sRGB = false;
     }
 
     // Some extensions are always available because they are implemented in the GL layer.
     mExtensions.bindUniformLocation   = true;
@@ -2669,18 +2679,17 @@ void Context::initCaps(const egl::Displa
     mExtensions.maxDebugLoggedMessages  = 1024;
     mExtensions.maxDebugGroupStackDepth = 1024;
     mExtensions.maxLabelLength          = 1024;
 
     // Explicitly enable GL_ANGLE_robust_client_memory
     mExtensions.robustClientMemory = true;
 
     // Determine robust resource init availability from EGL.
-    mExtensions.robustResourceInitialization =
-        egl::Display::GetClientExtensions().displayRobustResourceInitialization;
+    mExtensions.robustResourceInitialization = robustResourceInit;
 
     // mExtensions.robustBufferAccessBehavior is true only if robust access is true and the backend
     // supports it.
     mExtensions.robustBufferAccessBehavior =
         mRobustAccess && mExtensions.robustBufferAccessBehavior;
 
     // Enable the cache control query unconditionally.
     mExtensions.programCacheControl = true;
@@ -2723,21 +2732,19 @@ void Context::initCaps(const egl::Displa
     updateCaps();
 }
 
 void Context::updateCaps()
 {
     mCaps.compressedTextureFormats.clear();
     mTextureCaps.clear();
 
-    for (auto capsIt : mImplementation->getNativeTextureCaps())
-    {
-        GLenum sizedInternalFormat = capsIt.first;
-        TextureCaps formatCaps     = capsIt.second;
-
+    for (GLenum sizedInternalFormat : GetAllSizedInternalFormats())
+    {
+        TextureCaps formatCaps = mImplementation->getNativeTextureCaps().get(sizedInternalFormat);
         const InternalFormat &formatInfo = GetSizedInternalFormatInfo(sizedInternalFormat);
 
         // Update the format caps based on the client version and extensions.
         // Caps are AND'd with the renderer caps because some core formats are still unsupported in
         // ES3.
         formatCaps.texturable =
             formatCaps.texturable && formatInfo.textureSupport(getClientVersion(), mExtensions);
         formatCaps.renderable =
@@ -2808,26 +2815,66 @@ void Context::updateCaps()
         mTextureCaps.insert(sizedInternalFormat, formatCaps);
     }
 
     // If program binary is disabled, blank out the memory cache pointer.
     if (!mImplementation->getNativeExtensions().getProgramBinary)
     {
         mMemoryProgramCache = nullptr;
     }
+
+    // Compute which buffer types are allowed
+    mValidBufferBindings.reset();
+    mValidBufferBindings.set(BufferBinding::ElementArray);
+    mValidBufferBindings.set(BufferBinding::Array);
+
+    if (mExtensions.pixelBufferObject || getClientVersion() >= ES_3_0)
+    {
+        mValidBufferBindings.set(BufferBinding::PixelPack);
+        mValidBufferBindings.set(BufferBinding::PixelUnpack);
+    }
+
+    if (getClientVersion() >= ES_3_0)
+    {
+        mValidBufferBindings.set(BufferBinding::CopyRead);
+        mValidBufferBindings.set(BufferBinding::CopyWrite);
+        mValidBufferBindings.set(BufferBinding::TransformFeedback);
+        mValidBufferBindings.set(BufferBinding::Uniform);
+    }
+
+    if (getClientVersion() >= ES_3_1)
+    {
+        mValidBufferBindings.set(BufferBinding::AtomicCounter);
+        mValidBufferBindings.set(BufferBinding::ShaderStorage);
+        mValidBufferBindings.set(BufferBinding::DrawIndirect);
+        mValidBufferBindings.set(BufferBinding::DispatchIndirect);
+    }
 }
 
 void Context::initWorkarounds()
 {
     // Apply back-end workarounds.
     mImplementation->applyNativeWorkarounds(&mWorkarounds);
 
     // Lose the context upon out of memory error if the application is
     // expecting to watch for those events.
-    mWorkarounds.loseContextOnOutOfMemory = false;
+    mWorkarounds.loseContextOnOutOfMemory = (mResetStrategy == GL_LOSE_CONTEXT_ON_RESET_EXT);
+}
+
+Error Context::prepareForDraw()
+{
+    syncRendererState();
+
+    if (isRobustResourceInitEnabled())
+    {
+        ANGLE_TRY(mGLState.clearUnclearedActiveTextures(this));
+        ANGLE_TRY(mGLState.getDrawFramebuffer()->ensureDrawAttachmentsInitialized(this));
+    }
+
+    return NoError();
 }
 
 void Context::syncRendererState()
 {
     mGLState.syncDirtyObjects(this);
     const State::DirtyBits &dirtyBits = mGLState.getDirtyBits();
     mImplementation->syncState(this, dirtyBits);
     mGLState.clearDirtyBits();
@@ -2935,17 +2982,17 @@ void Context::copyTexImage2D(GLenum targ
                              GLsizei height,
                              GLint border)
 {
     // Only sync the read FBO
     mGLState.syncDirtyObject(this, GL_READ_FRAMEBUFFER);
 
     Rectangle sourceArea(x, y, width, height);
 
-    const Framebuffer *framebuffer = mGLState.getReadFramebuffer();
+    Framebuffer *framebuffer = mGLState.getReadFramebuffer();
     Texture *texture =
         getTargetTexture(IsCubeMapTextureTarget(target) ? GL_TEXTURE_CUBE_MAP : target);
     handleError(texture->copyImage(this, target, level, sourceArea, internalformat, framebuffer));
 }
 
 void Context::copyTexSubImage2D(GLenum target,
                                 GLint level,
                                 GLint xoffset,
@@ -2961,17 +3008,17 @@ void Context::copyTexSubImage2D(GLenum t
     }
 
     // Only sync the read FBO
     mGLState.syncDirtyObject(this, GL_READ_FRAMEBUFFER);
 
     Offset destOffset(xoffset, yoffset, 0);
     Rectangle sourceArea(x, y, width, height);
 
-    const Framebuffer *framebuffer = mGLState.getReadFramebuffer();
+    Framebuffer *framebuffer = mGLState.getReadFramebuffer();
     Texture *texture =
         getTargetTexture(IsCubeMapTextureTarget(target) ? GL_TEXTURE_CUBE_MAP : target);
     handleError(texture->copySubImage(this, target, level, destOffset, sourceArea, framebuffer));
 }
 
 void Context::copyTexSubImage3D(GLenum target,
                                 GLint level,
                                 GLint xoffset,
@@ -2988,18 +3035,18 @@ void Context::copyTexSubImage3D(GLenum t
     }
 
     // Only sync the read FBO
     mGLState.syncDirtyObject(this, GL_READ_FRAMEBUFFER);
 
     Offset destOffset(xoffset, yoffset, zoffset);
     Rectangle sourceArea(x, y, width, height);
 
-    const Framebuffer *framebuffer = mGLState.getReadFramebuffer();
-    Texture *texture               = getTargetTexture(target);
+    Framebuffer *framebuffer = mGLState.getReadFramebuffer();
+    Texture *texture         = getTargetTexture(target);
     handleError(texture->copySubImage(this, target, level, destOffset, sourceArea, framebuffer));
 }
 
 void Context::framebufferTexture2D(GLenum target,
                                    GLenum attachment,
                                    GLenum textarget,
                                    GLuint texture,
                                    GLint level)
@@ -3396,132 +3443,139 @@ void Context::compressedTexSubImage3D(GL
 }
 
 void Context::generateMipmap(GLenum target)
 {
     Texture *texture = getTargetTexture(target);
     handleError(texture->generateMipmap(this));
 }
 
-void Context::copyTextureCHROMIUM(GLuint sourceId,
-                                  GLint sourceLevel,
-                                  GLenum destTarget,
-                                  GLuint destId,
-                                  GLint destLevel,
-                                  GLint internalFormat,
-                                  GLenum destType,
-                                  GLboolean unpackFlipY,
-                                  GLboolean unpackPremultiplyAlpha,
-                                  GLboolean unpackUnmultiplyAlpha)
+void Context::copyTexture(GLuint sourceId,
+                          GLint sourceLevel,
+                          GLenum destTarget,
+                          GLuint destId,
+                          GLint destLevel,
+                          GLint internalFormat,
+                          GLenum destType,
+                          GLboolean unpackFlipY,
+                          GLboolean unpackPremultiplyAlpha,
+                          GLboolean unpackUnmultiplyAlpha)
 {
     syncStateForTexImage();
 
     gl::Texture *sourceTexture = getTexture(sourceId);
     gl::Texture *destTexture   = getTexture(destId);
-    handleError(destTexture->copyTexture(
-        this, destTarget, destLevel, internalFormat, destType, sourceLevel, unpackFlipY == GL_TRUE,
-        unpackPremultiplyAlpha == GL_TRUE, unpackUnmultiplyAlpha == GL_TRUE, sourceTexture));
-}
-
-void Context::copySubTextureCHROMIUM(GLuint sourceId,
-                                     GLint sourceLevel,
-                                     GLenum destTarget,
-                                     GLuint destId,
-                                     GLint destLevel,
-                                     GLint xoffset,
-                                     GLint yoffset,
-                                     GLint x,
-                                     GLint y,
-                                     GLsizei width,
-                                     GLsizei height,
-                                     GLboolean unpackFlipY,
-                                     GLboolean unpackPremultiplyAlpha,
-                                     GLboolean unpackUnmultiplyAlpha)
+    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,
+                             GLuint destId,
+                             GLint destLevel,
+                             GLint xoffset,
+                             GLint yoffset,
+                             GLint x,
+                             GLint y,
+                             GLsizei width,
+                             GLsizei height,
+                             GLboolean unpackFlipY,
+                             GLboolean unpackPremultiplyAlpha,
+                             GLboolean unpackUnmultiplyAlpha)
 {
     // Zero sized copies are valid but no-ops
     if (width == 0 || height == 0)
     {
         return;
     }
 
     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, unpackFlipY == GL_TRUE,
-        unpackPremultiplyAlpha == GL_TRUE, unpackUnmultiplyAlpha == GL_TRUE, sourceTexture));
-}
-
-void Context::compressedCopyTextureCHROMIUM(GLuint sourceId, GLuint destId)
+    handleError(destTexture->copySubTexture(this, destTarget, destLevel, offset, sourceLevel, area,
+                                            ConvertToBool(unpackFlipY),
+                                            ConvertToBool(unpackPremultiplyAlpha),
+                                            ConvertToBool(unpackUnmultiplyAlpha), sourceTexture));
+}
+
+void Context::compressedCopyTexture(GLuint sourceId, GLuint destId)
 {
     syncStateForTexImage();
 
     gl::Texture *sourceTexture = getTexture(sourceId);
     gl::Texture *destTexture   = getTexture(destId);
     handleError(destTexture->copyCompressedTexture(this, sourceTexture));
 }
 
-void Context::getBufferPointerv(GLenum target, GLenum pname, void **params)
+void Context::getBufferPointerv(BufferBinding target, GLenum pname, void **params)
 {
     Buffer *buffer = mGLState.getTargetBuffer(target);
     ASSERT(buffer);
 
     QueryBufferPointerv(buffer, pname, params);
 }
 
-void *Context::mapBuffer(GLenum target, GLenum access)
+void *Context::mapBuffer(BufferBinding target, GLenum access)
 {
     Buffer *buffer = mGLState.getTargetBuffer(target);
     ASSERT(buffer);
 
     Error error = buffer->map(this, access);
     if (error.isError())
     {
         handleError(error);
         return nullptr;
     }
 
     return buffer->getMapPointer();
 }
 
-GLboolean Context::unmapBuffer(GLenum target)
+GLboolean Context::unmapBuffer(BufferBinding target)
 {
     Buffer *buffer = mGLState.getTargetBuffer(target);
     ASSERT(buffer);
 
     GLboolean result;
     Error error = buffer->unmap(this, &result);
     if (error.isError())
     {
         handleError(error);
         return GL_FALSE;
     }
 
     return result;
 }
 
-void *Context::mapBufferRange(GLenum target, GLintptr offset, GLsizeiptr length, GLbitfield access)
+void *Context::mapBufferRange(BufferBinding target,
+                              GLintptr offset,
+                              GLsizeiptr length,
+                              GLbitfield access)
 {
     Buffer *buffer = mGLState.getTargetBuffer(target);
     ASSERT(buffer);
 
     Error error = buffer->mapRange(this, offset, length, access);
     if (error.isError())
     {
         handleError(error);
         return nullptr;
     }
 
     return buffer->getMapPointer();
 }
 
-void Context::flushMappedBufferRange(GLenum /*target*/, GLintptr /*offset*/, GLsizeiptr /*length*/)
+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);
 }
@@ -3536,16 +3590,21 @@ void Context::syncStateForClear()
     syncRendererState(mClearDirtyBits, mClearDirtyObjects);
 }
 
 void Context::syncStateForBlit()
 {
     syncRendererState(mBlitDirtyBits, mBlitDirtyObjects);
 }
 
+void Context::activeShaderProgram(GLuint pipeline, GLuint program)
+{
+    UNIMPLEMENTED();
+}
+
 void Context::activeTexture(GLenum texture)
 {
     mGLState.setActiveSampler(texture - GL_TEXTURE0);
 }
 
 void Context::blendColor(GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha)
 {
     mGLState.setBlendColor(clamp01(red), clamp01(green), clamp01(blue), clamp01(alpha));
@@ -3583,32 +3642,33 @@ void Context::clearDepthf(GLfloat depth)
 
 void Context::clearStencil(GLint s)
 {
     mGLState.setStencilClearValue(s);
 }
 
 void Context::colorMask(GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha)
 {
-    mGLState.setColorMask(red == GL_TRUE, green == GL_TRUE, blue == GL_TRUE, alpha == GL_TRUE);
-}
-
-void Context::cullFace(GLenum mode)
+    mGLState.setColorMask(ConvertToBool(red), ConvertToBool(green), ConvertToBool(blue),
+                          ConvertToBool(alpha));
+}
+
+void Context::cullFace(CullFaceMode mode)
 {
     mGLState.setCullMode(mode);
 }
 
 void Context::depthFunc(GLenum func)
 {
     mGLState.setDepthFunc(func);
 }
 
 void Context::depthMask(GLboolean flag)
 {
-    mGLState.setDepthMask(flag != GL_FALSE);
+    mGLState.setDepthMask(ConvertToBool(flag));
 }
 
 void Context::depthRangef(GLfloat zNear, GLfloat zFar)
 {
     mGLState.setDepthRange(zNear, zFar);
 }
 
 void Context::disable(GLenum cap)
@@ -3723,17 +3783,17 @@ void Context::pixelStorei(GLenum pname, 
 
 void Context::polygonOffset(GLfloat factor, GLfloat units)
 {
     mGLState.setPolygonOffsetParams(factor, units);
 }
 
 void Context::sampleCoverage(GLfloat value, GLboolean invert)
 {
-    mGLState.setSampleCoverageParams(clamp01(value), invert == GL_TRUE);
+    mGLState.setSampleCoverageParams(clamp01(value), ConvertToBool(invert));
 }
 
 void Context::sampleMaski(GLuint maskNumber, GLbitfield mask)
 {
     mGLState.setSampleMaskParams(maskNumber, mask);
 }
 
 void Context::scissor(GLint x, GLint y, GLsizei width, GLsizei height)
@@ -3829,61 +3889,61 @@ void Context::vertexAttrib4fv(GLuint ind
 
 void Context::vertexAttribPointer(GLuint index,
                                   GLint size,
                                   GLenum type,
                                   GLboolean normalized,
                                   GLsizei stride,
                                   const void *ptr)
 {
-    mGLState.setVertexAttribPointer(this, index, mGLState.getTargetBuffer(GL_ARRAY_BUFFER), size,
-                                    type, normalized == GL_TRUE, false, stride, ptr);
+    mGLState.setVertexAttribPointer(this, index, mGLState.getTargetBuffer(BufferBinding::Array),
+                                    size, type, ConvertToBool(normalized), false, stride, ptr);
 }
 
 void Context::vertexAttribFormat(GLuint attribIndex,
                                  GLint size,
                                  GLenum type,
                                  GLboolean normalized,
                                  GLuint relativeOffset)
 {
-    mGLState.setVertexAttribFormat(attribIndex, size, type, normalized == GL_TRUE, false,
+    mGLState.setVertexAttribFormat(attribIndex, size, type, ConvertToBool(normalized), false,
                                    relativeOffset);
 }
 
 void Context::vertexAttribIFormat(GLuint attribIndex,
                                   GLint size,
                                   GLenum type,
                                   GLuint relativeOffset)
 {
     mGLState.setVertexAttribFormat(attribIndex, size, type, false, true, relativeOffset);
 }
 
 void Context::vertexAttribBinding(GLuint attribIndex, GLuint bindingIndex)
 {
     mGLState.setVertexAttribBinding(this, attribIndex, bindingIndex);
 }
 
-void Context::setVertexBindingDivisor(GLuint bindingIndex, GLuint divisor)
+void Context::vertexBindingDivisor(GLuint bindingIndex, GLuint divisor)
 {
     mGLState.setVertexBindingDivisor(bindingIndex, divisor);
 }
 
 void Context::viewport(GLint x, GLint y, GLsizei width, GLsizei height)
 {
     mGLState.setViewportParams(x, y, width, height);
 }
 
 void Context::vertexAttribIPointer(GLuint index,
                                    GLint size,
                                    GLenum type,
                                    GLsizei stride,
                                    const void *pointer)
 {
-    mGLState.setVertexAttribPointer(this, index, mGLState.getTargetBuffer(GL_ARRAY_BUFFER), size,
-                                    type, false, true, stride, pointer);
+    mGLState.setVertexAttribPointer(this, index, mGLState.getTargetBuffer(BufferBinding::Array),
+                                    size, type, false, true, stride, pointer);
 }
 
 void Context::vertexAttribI4i(GLuint index, GLint x, GLint y, GLint z, GLint w)
 {
     GLint vals[4] = {x, y, z, w};
     mGLState.setVertexAttribi(index, vals);
 }
 
@@ -3949,17 +4009,17 @@ void Context::debugMessageControl(GLenum
                                   GLenum type,
                                   GLenum severity,
                                   GLsizei count,
                                   const GLuint *ids,
                                   GLboolean enabled)
 {
     std::vector<GLuint> idVector(ids, ids + count);
     mGLState.getDebug().setMessageControl(source, type, severity, std::move(idVector),
-                                          (enabled != GL_FALSE));
+                                          ConvertToBool(enabled));
 }
 
 void Context::debugMessageInsert(GLenum source,
                                  GLenum type,
                                  GLuint id,
                                  GLenum severity,
                                  GLsizei length,
                                  const GLchar *buf)
@@ -3985,57 +4045,62 @@ GLuint Context::getDebugMessageLog(GLuin
     return static_cast<GLuint>(mGLState.getDebug().getMessages(count, bufSize, sources, types, ids,
                                                                severities, lengths, messageLog));
 }
 
 void Context::pushDebugGroup(GLenum source, GLuint id, GLsizei length, const GLchar *message)
 {
     std::string msg(message, (length > 0) ? static_cast<size_t>(length) : strlen(message));
     mGLState.getDebug().pushGroup(source, id, std::move(msg));
+    mImplementation->pushDebugGroup(source, id, length, message);
 }
 
 void Context::popDebugGroup()
 {
     mGLState.getDebug().popGroup();
-}
-
-void Context::bufferData(GLenum target, GLsizeiptr size, const void *data, GLenum usage)
+    mImplementation->popDebugGroup();
+}
+
+void Context::bufferData(BufferBinding target, GLsizeiptr size, const void *data, BufferUsage usage)
 {
     Buffer *buffer = mGLState.getTargetBuffer(target);
     ASSERT(buffer);
     handleError(buffer->bufferData(this, target, data, size, usage));
 }
 
-void Context::bufferSubData(GLenum target, GLintptr offset, GLsizeiptr size, const void *data)
+void Context::bufferSubData(BufferBinding target,
+                            GLintptr offset,
+                            GLsizeiptr size,
+                            const void *data)
 {
     if (data == nullptr)
     {
         return;
     }
 
     Buffer *buffer = mGLState.getTargetBuffer(target);
     ASSERT(buffer);
     handleError(buffer->bufferSubData(this, target, data, size, offset));
 }
 
 void Context::attachShader(GLuint program, GLuint shader)
 {
-    auto programObject = mState.mShaderPrograms->getProgram(program);
-    auto shaderObject  = mState.mShaderPrograms->getShader(shader);
+    Program *programObject = mState.mShaderPrograms->getProgram(program);
+    Shader *shaderObject   = mState.mShaderPrograms->getShader(shader);
     ASSERT(programObject && shaderObject);
     programObject->attachShader(shaderObject);
 }
 
 const Workarounds &Context::getWorkarounds() const
 {
     return mWorkarounds;
 }
 
-void Context::copyBufferSubData(GLenum readTarget,
-                                GLenum writeTarget,
+void Context::copyBufferSubData(BufferBinding readTarget,
+                                BufferBinding writeTarget,
                                 GLintptr readOffset,
                                 GLintptr writeOffset,
                                 GLsizeiptr size)
 {
     // if size is zero, the copy is a successful no-op
     if (size == 0)
     {
         return;
@@ -4051,100 +4116,35 @@ void Context::copyBufferSubData(GLenum r
 void Context::bindAttribLocation(GLuint program, GLuint index, const GLchar *name)
 {
     Program *programObject = getProgram(program);
     // TODO(jmadill): Re-use this from the validation if possible.
     ASSERT(programObject);
     programObject->bindAttributeLocation(index, name);
 }
 
-void Context::bindBuffer(GLenum target, GLuint buffer)
-{
-    switch (target)
-    {
-        case GL_ARRAY_BUFFER:
-            bindArrayBuffer(buffer);
-            break;
-        case GL_ELEMENT_ARRAY_BUFFER:
-            bindElementArrayBuffer(buffer);
-            break;
-        case GL_COPY_READ_BUFFER:
-            bindCopyReadBuffer(buffer);
-            break;
-        case GL_COPY_WRITE_BUFFER:
-            bindCopyWriteBuffer(buffer);
-            break;
-        case GL_PIXEL_PACK_BUFFER:
-            bindPixelPackBuffer(buffer);
-            break;
-        case GL_PIXEL_UNPACK_BUFFER:
-            bindPixelUnpackBuffer(buffer);
-            break;
-        case GL_UNIFORM_BUFFER:
-            bindGenericUniformBuffer(buffer);
-            break;
-        case GL_TRANSFORM_FEEDBACK_BUFFER:
-            bindGenericTransformFeedbackBuffer(buffer);
-            break;
-        case GL_ATOMIC_COUNTER_BUFFER:
-            bindGenericAtomicCounterBuffer(buffer);
-            break;
-        case GL_SHADER_STORAGE_BUFFER:
-            bindGenericShaderStorageBuffer(buffer);
-            break;
-        case GL_DRAW_INDIRECT_BUFFER:
-            bindDrawIndirectBuffer(buffer);
-            break;
-        case GL_DISPATCH_INDIRECT_BUFFER:
-            if (buffer != 0)
-            {
-                // Binding buffers to this binding point is not implemented yet.
-                UNIMPLEMENTED();
-            }
-            break;
-
-        default:
-            UNREACHABLE();
-            break;
-    }
-}
-
-void Context::bindBufferBase(GLenum target, GLuint index, GLuint buffer)
+void Context::bindBuffer(BufferBinding target, GLuint buffer)
+{
+    Buffer *bufferObject = mState.mBuffers->checkBufferAllocation(mImplementation.get(), buffer);
+    mGLState.setBufferBinding(this, target, bufferObject);
+}
+
+void Context::bindBufferBase(BufferBinding target, GLuint index, GLuint buffer)
 {
     bindBufferRange(target, index, buffer, 0, 0);
 }
 
-void Context::bindBufferRange(GLenum target,
+void Context::bindBufferRange(BufferBinding target,
                               GLuint index,
                               GLuint buffer,
                               GLintptr offset,
                               GLsizeiptr size)
 {
-    switch (target)
-    {
-        case GL_TRANSFORM_FEEDBACK_BUFFER:
-            bindIndexedTransformFeedbackBuffer(buffer, index, offset, size);
-            bindGenericTransformFeedbackBuffer(buffer);
-            break;
-        case GL_UNIFORM_BUFFER:
-            bindIndexedUniformBuffer(buffer, index, offset, size);
-            bindGenericUniformBuffer(buffer);
-            break;
-        case GL_ATOMIC_COUNTER_BUFFER:
-            bindIndexedAtomicCounterBuffer(buffer, index, offset, size);
-            bindGenericAtomicCounterBuffer(buffer);
-            break;
-        case GL_SHADER_STORAGE_BUFFER:
-            bindIndexedShaderStorageBuffer(buffer, index, offset, size);
-            bindGenericShaderStorageBuffer(buffer);
-            break;
-        default:
-            UNREACHABLE();
-            break;
-    }
+    Buffer *bufferObject = mState.mBuffers->checkBufferAllocation(mImplementation.get(), buffer);
+    mGLState.setIndexedBufferBinding(this, target, index, bufferObject, offset, size);
 }
 
 void Context::bindFramebuffer(GLenum target, GLuint framebuffer)
 {
     if (target == GL_READ_FRAMEBUFFER || target == GL_FRAMEBUFFER)
     {
         bindReadFramebuffer(framebuffer);
     }
@@ -4168,17 +4168,17 @@ void Context::texStorage2DMultisample(GL
                                       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,
-                                               fixedsamplelocations));
+                                               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);
     const Framebuffer *framebuffer = mGLState.getDrawFramebuffer();
@@ -4226,17 +4226,17 @@ 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::setFramebufferParameteri(GLenum target, GLenum pname, GLint param)
+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
 {
@@ -4252,26 +4252,45 @@ Error Context::getZeroFilledBuffer(size_
 {
     if (!mZeroFilledBuffer.getInitialized(requstedSizeBytes, zeroBufferOut, 0))
     {
         return OutOfMemory() << "Failed to allocate internal buffer.";
     }
     return NoError();
 }
 
+Error Context::prepareForDispatch()
+{
+    syncRendererState(mComputeDirtyBits, mComputeDirtyObjects);
+
+    if (isRobustResourceInitEnabled())
+    {
+        ANGLE_TRY(mGLState.clearUnclearedActiveTextures(this));
+    }
+
+    return NoError();
+}
+
 void Context::dispatchCompute(GLuint numGroupsX, GLuint numGroupsY, GLuint numGroupsZ)
 {
     if (numGroupsX == 0u || numGroupsY == 0u || numGroupsZ == 0u)
     {
         return;
     }
 
+    ANGLE_CONTEXT_TRY(prepareForDispatch());
     handleError(mImplementation->dispatchCompute(this, numGroupsX, numGroupsY, numGroupsZ));
 }
 
+void Context::dispatchComputeIndirect(GLintptr indirect)
+{
+    ANGLE_CONTEXT_TRY(prepareForDispatch());
+    handleError(mImplementation->dispatchComputeIndirect(this, indirect));
+}
+
 void Context::texStorage2D(GLenum target,
                            GLsizei levels,
                            GLenum internalFormat,
                            GLsizei width,
                            GLsizei height)
 {
     Extents size(width, height, 1);
     Texture *texture = getTargetTexture(target);
@@ -4285,16 +4304,26 @@ void Context::texStorage3D(GLenum target
                            GLsizei height,
                            GLsizei depth)
 {
     Extents size(width, height, depth);
     Texture *texture = getTargetTexture(target);
     handleError(texture->setStorage(this, target, levels, internalFormat, size));
 }
 
+void Context::memoryBarrier(GLbitfield barriers)
+{
+    handleError(mImplementation->memoryBarrier(this, barriers));
+}
+
+void Context::memoryBarrierByRegion(GLbitfield barriers)
+{
+    handleError(mImplementation->memoryBarrierByRegion(this, barriers));
+}
+
 GLenum Context::checkFramebufferStatus(GLenum target)
 {
     Framebuffer *framebuffer = mGLState.getTargetFramebuffer(target);
     ASSERT(framebuffer);
 
     return framebuffer->checkStatus(this);
 }
 
@@ -4479,23 +4508,36 @@ void Context::getIntegerv(GLenum pname, 
 
 void Context::getProgramiv(GLuint program, GLenum pname, GLint *params)
 {
     Program *programObject = getProgram(program);
     ASSERT(programObject);
     QueryProgramiv(this, programObject, 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);
     ASSERT(programObject);
     programObject->getInfoLog(bufsize, length, infolog);
 }
 
+void Context::getProgramPipelineInfoLog(GLuint pipeline,
+                                        GLsizei bufSize,
+                                        GLsizei *length,
+                                        GLchar *infoLog)
+{
+    UNIMPLEMENTED();
+}
+
 void Context::getShaderiv(GLuint shader, GLenum pname, GLint *params)
 {
     Shader *shaderObject = getShader(shader);
     ASSERT(shaderObject);
     QueryShaderiv(this, shaderObject, pname, params);
 }
 
 void Context::getShaderInfoLog(GLuint shader, GLsizei bufsize, GLsizei *length, GLchar *infolog)
@@ -4856,16 +4898,21 @@ void Context::uniformMatrix4fv(GLint loc
 
 void Context::validateProgram(GLuint program)
 {
     Program *programObject = getProgram(program);
     ASSERT(programObject);
     programObject->validate(mCaps);
 }
 
+void Context::validateProgramPipeline(GLuint pipeline)
+{
+    UNIMPLEMENTED();
+}
+
 void Context::getProgramBinary(GLuint program,
                                GLsizei bufSize,
                                GLsizei *length,
                                GLenum *binaryFormat,
                                void *binary)
 {
     Program *programObject = getProgram(program);
     ASSERT(programObject != nullptr);
@@ -5189,17 +5236,17 @@ void Context::getActiveUniformsiv(GLuint
                                   const GLuint *uniformIndices,
                                   GLenum pname,
                                   GLint *params)
 {
     const Program *programObject = getProgram(program);
     for (int uniformId = 0; uniformId < uniformCount; uniformId++)
     {
         const GLuint index = uniformIndices[uniformId];
-        params[uniformId]  = programObject->getActiveUniformi(index, pname);
+        params[uniformId]  = GetUniformResourceProperty(programObject, index, pname);
     }
 }
 
 GLuint Context::getUniformBlockIndex(GLuint program, const GLchar *uniformBlockName)
 {
     const Program *programObject = getProgram(program);
     return programObject->getUniformBlockIndex(uniformBlockName);
 }
@@ -5279,17 +5326,17 @@ void Context::getInteger64v(GLenum pname
         getInteger64vImpl(pname, params);
     }
     else
     {
         CastStateValues(this, nativeType, pname, numParams, params);
     }
 }
 
-void Context::getBufferParameteri64v(GLenum target, GLenum pname, GLint64 *params)
+void Context::getBufferParameteri64v(BufferBinding target, GLenum pname, GLint64 *params)
 {
     Buffer *buffer = mGLState.getTargetBuffer(target);
     QueryBufferParameteri64v(buffer, pname, params);
 }
 
 void Context::genSamplers(GLsizei count, GLuint *samplers)
 {
     for (int i = 0; i < count; i++)
@@ -5318,27 +5365,287 @@ void Context::getInternalformativ(GLenum
                                   GLenum pname,
                                   GLsizei bufSize,
                                   GLint *params)
 {
     const TextureCaps &formatCaps = mTextureCaps.get(internalformat);
     QueryInternalFormativ(formatCaps, 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};
+    programUniform2iv(program, location, 1, xy);
+}
+
+void Context::programUniform3i(GLuint program, GLint location, GLint v0, GLint v1, GLint v2)
+{
+    GLint xyz[3] = {v0, v1, v2};
+    programUniform3iv(program, location, 1, xyz);
+}
+
+void Context::programUniform4i(GLuint program,
+                               GLint location,
+                               GLint v0,
+                               GLint v1,
+                               GLint v2,
+                               GLint v3)
+{
+    GLint xyzw[4] = {v0, v1, v2, v3};
+    programUniform4iv(program, location, 1, xyzw);
+}
+
+void Context::programUniform1ui(GLuint program, GLint location, GLuint v0)
+{
+    programUniform1uiv(program, location, 1, &v0);
+}
+
+void Context::programUniform2ui(GLuint program, GLint location, GLuint v0, GLuint v1)
+{
+    GLuint xy[2] = {v0, v1};
+    programUniform2uiv(program, location, 1, xy);
+}
+
+void Context::programUniform3ui(GLuint program, GLint location, GLuint v0, GLuint v1, GLuint v2)
+{
+    GLuint xyz[3] = {v0, v1, v2};
+    programUniform3uiv(program, location, 1, xyz);
+}
+
+void Context::programUniform4ui(GLuint program,
+                                GLint location,
+                                GLuint v0,
+                                GLuint v1,
+                                GLuint v2,
+                                GLuint v3)
+{
+    GLuint xyzw[4] = {v0, v1, v2, v3};
+    programUniform4uiv(program, location, 1, xyzw);
+}
+
+void Context::programUniform1f(GLuint program, GLint location, GLfloat v0)
+{
+    programUniform1fv(program, location, 1, &v0);
+}
+
+void Context::programUniform2f(GLuint program, GLint location, GLfloat v0, GLfloat v1)
+{
+    GLfloat xy[2] = {v0, v1};
+    programUniform2fv(program, location, 1, xy);
+}
+
+void Context::programUniform3f(GLuint program, GLint location, GLfloat v0, GLfloat v1, GLfloat v2)
+{
+    GLfloat xyz[3] = {v0, v1, v2};
+    programUniform3fv(program, location, 1, xyz);
+}
+
+void Context::programUniform4f(GLuint program,
+                               GLint location,
+                               GLfloat v0,
+                               GLfloat v1,
+                               GLfloat v2,
+                               GLfloat v3)
+{
+    GLfloat xyzw[4] = {v0, v1, v2, v3};
+    programUniform4fv(program, location, 1, xyzw);
+}
+
 void Context::programUniform1iv(GLuint program, GLint location, GLsizei count, const GLint *value)
 {
     Program *programObject = getProgram(program);
     ASSERT(programObject);
     if (programObject->setUniform1iv(location, count, value) ==
         Program::SetUniformResult::SamplerChanged)
     {
         mGLState.setObjectDirty(GL_PROGRAM);
     }
 }
 
+void Context::programUniform2iv(GLuint program, GLint location, GLsizei count, const GLint *value)
+{
+    Program *programObject = getProgram(program);
+    ASSERT(programObject);
+    programObject->setUniform2iv(location, count, value);
+}
+
+void Context::programUniform3iv(GLuint program, GLint location, GLsizei count, const GLint *value)
+{
+    Program *programObject = getProgram(program);
+    ASSERT(programObject);
+    programObject->setUniform3iv(location, count, value);
+}
+
+void Context::programUniform4iv(GLuint program, GLint location, GLsizei count, const GLint *value)
+{
+    Program *programObject = getProgram(program);
+    ASSERT(programObject);
+    programObject->setUniform4iv(location, count, value);
+}
+
+void Context::programUniform1uiv(GLuint program, GLint location, GLsizei count, const GLuint *value)
+{
+    Program *programObject = getProgram(program);
+    ASSERT(programObject);
+    programObject->setUniform1uiv(location, count, value);
+}
+
+void Context::programUniform2uiv(GLuint program, GLint location, GLsizei count, const GLuint *value)
+{
+    Program *programObject = getProgram(program);
+    ASSERT(programObject);
+    programObject->setUniform2uiv(location, count, value);
+}
+
+void Context::programUniform3uiv(GLuint program, GLint location, GLsizei count, const GLuint *value)
+{
+    Program *programObject = getProgram(program);
+    ASSERT(programObject);
+    programObject->setUniform3uiv(location, count, value);
+}
+
+void Context::programUniform4uiv(GLuint program, GLint location, GLsizei count, const GLuint *value)
+{
+    Program *programObject = getProgram(program);
+    ASSERT(programObject);
+    programObject->setUniform4uiv(location, count, value);
+}
+
+void Context::programUniform1fv(GLuint program, GLint location, GLsizei count, const GLfloat *value)
+{
+    Program *programObject = getProgram(program);
+    ASSERT(programObject);
+    programObject->setUniform1fv(location, count, value);
+}
+
+void Context::programUniform2fv(GLuint program, GLint location, GLsizei count, const GLfloat *value)
+{
+    Program *programObject = getProgram(program);
+    ASSERT(programObject);
+    programObject->setUniform2fv(location, count, value);
+}
+
+void Context::programUniform3fv(GLuint program, GLint location, GLsizei count, const GLfloat *value)
+{
+    Program *programObject = getProgram(program);
+    ASSERT(programObject);
+    programObject->setUniform3fv(location, count, value);
+}
+
+void Context::programUniform4fv(GLuint program, GLint location, GLsizei count, const GLfloat *value)
+{
+    Program *programObject = getProgram(program);
+    ASSERT(programObject);
+    programObject->setUniform4fv(location, count, value);
+}
+
+void Context::programUniformMatrix2fv(GLuint program,
+                                      GLint location,
+                                      GLsizei count,
+                                      GLboolean transpose,
+                                      const GLfloat *value)
+{
+    Program *programObject = getProgram(program);
+    ASSERT(programObject);
+    programObject->setUniformMatrix2fv(location, count, transpose, value);
+}
+
+void Context::programUniformMatrix3fv(GLuint program,
+                                      GLint location,
+                                      GLsizei count,
+                                      GLboolean transpose,
+                                      const GLfloat *value)
+{
+    Program *programObject = getProgram(program);
+    ASSERT(programObject);
+    programObject->setUniformMatrix3fv(location, count, transpose, value);
+}
+
+void Context::programUniformMatrix4fv(GLuint program,
+                                      GLint location,
+                                      GLsizei count,
+                                      GLboolean transpose,
+                                      const GLfloat *value)
+{
+    Program *programObject = getProgram(program);
+    ASSERT(programObject);
+    programObject->setUniformMatrix4fv(location, count, transpose, value);
+}
+
+void Context::programUniformMatrix2x3fv(GLuint program,
+                                        GLint location,
+                                        GLsizei count,
+                                        GLboolean transpose,
+                                        const GLfloat *value)
+{
+    Program *programObject = getProgram(program);
+    ASSERT(programObject);
+    programObject->setUniformMatrix2x3fv(location, count, transpose, value);
+}
+
+void Context::programUniformMatrix3x2fv(GLuint program,
+                                        GLint location,
+                                        GLsizei count,
+                                        GLboolean transpose,
+                                        const GLfloat *value)
+{
+    Program *programObject = getProgram(program);
+    ASSERT(programObject);
+    programObject->setUniformMatrix3x2fv(location, count, transpose, value);
+}
+
+void Context::programUniformMatrix2x4fv(GLuint program,
+                                        GLint location,
+                                        GLsizei count,
+                                        GLboolean transpose,
+                                        const GLfloat *value)
+{
+    Program *programObject = getProgram(program);
+    ASSERT(programObject);
+    programObject->setUniformMatrix2x4fv(location, count, transpose, value);
+}
+
+void Context::programUniformMatrix4x2fv(GLuint program,
+                                        GLint location,
+                                        GLsizei count,
+                                        GLboolean transpose,
+                                        const GLfloat *value)
+{
+    Program *programObject = getProgram(program);
+    ASSERT(programObject);
+    programObject->setUniformMatrix4x2fv(location, count, transpose, value);
+}
+
+void Context::programUniformMatrix3x4fv(GLuint program,
+                                        GLint location,
+                                        GLsizei count,
+                                        GLboolean transpose,
+                                        const GLfloat *value)
+{
+    Program *programObject = getProgram(program);
+    ASSERT(programObject);
+    programObject->setUniformMatrix3x4fv(location, count, transpose, value);
+}
+
+void Context::programUniformMatrix4x3fv(GLuint program,
+                                        GLint location,
+                                        GLsizei count,
+                                        GLboolean transpose,
+                                        const GLfloat *value)
+{
+    Program *programObject = getProgram(program);
+    ASSERT(programObject);
+    programObject->setUniformMatrix4x3fv(location, count, transpose, value);
+}
+
 void Context::onTextureChange(const Texture *texture)
 {
     // Conservatively assume all textures are dirty.
     // TODO(jmadill): More fine-grained update.
     mGLState.setObjectDirty(GL_TEXTURE);
 }
 
 void Context::genProgramPipelines(GLsizei count, GLuint *pipelines)
@@ -5365,9 +5672,150 @@ GLboolean Context::isProgramPipeline(GLu
     if (pipeline == 0)
     {
         return GL_FALSE;
     }
 
     return (getProgramPipeline(pipeline) ? GL_TRUE : GL_FALSE);
 }
 
+void Context::finishFenceNV(GLuint fence)
+{
+    FenceNV *fenceObject = getFenceNV(fence);
+
+    ASSERT(fenceObject && fenceObject->isSet());
+    handleError(fenceObject->finish());
+}
+
+void Context::getFenceivNV(GLuint fence, GLenum pname, GLint *params)
+{
+    FenceNV *fenceObject = getFenceNV(fence);
+
+    ASSERT(fenceObject && fenceObject->isSet());
+
+    switch (pname)
+    {
+        case GL_FENCE_STATUS_NV:
+        {
+            // GL_NV_fence spec:
+            // Once the status of a fence has been finished (via FinishFenceNV) or tested and
+            // the returned status is TRUE (via either TestFenceNV or GetFenceivNV querying the
+            // FENCE_STATUS_NV), the status remains TRUE until the next SetFenceNV of the fence.
+            GLboolean status = GL_TRUE;
+            if (fenceObject->getStatus() != GL_TRUE)
+            {
+                ANGLE_CONTEXT_TRY(fenceObject->test(&status));
+            }
+            *params = status;
+            break;
+        }
+
+        case GL_FENCE_CONDITION_NV:
+        {
+            *params = static_cast<GLint>(fenceObject->getCondition());
+            break;
+        }
+
+        default:
+            UNREACHABLE();
+    }
+}
+
+void Context::getTranslatedShaderSource(GLuint shader,
+                                        GLsizei bufsize,
+                                        GLsizei *length,
+                                        GLchar *source)
+{
+    Shader *shaderObject = getShader(shader);
+    ASSERT(shaderObject);
+    shaderObject->getTranslatedSourceWithDebugInfo(this, bufsize, length, source);
+}
+
+void Context::getnUniformfv(GLuint program, GLint location, GLsizei bufSize, GLfloat *params)
+{
+    Program *programObject = getProgram(program);
+    ASSERT(programObject);
+
+    programObject->getUniformfv(this, location, params);
+}
+
+void Context::getnUniformiv(GLuint program, GLint location, GLsizei bufSize, GLint *params)
+{
+    Program *programObject = getProgram(program);
+    ASSERT(programObject);
+
+    programObject->getUniformiv(this, location, params);
+}
+
+GLboolean Context::isFenceNV(GLuint fence)
+{
+    FenceNV *fenceObject = getFenceNV(fence);
+
+    if (fenceObject == nullptr)
+    {
+        return GL_FALSE;
+    }
+
+    // GL_NV_fence spec:
+    // A name returned by GenFencesNV, but not yet set via SetFenceNV, is not the name of an
+    // existing fence.
+    return fenceObject->isSet();
+}
+
+void Context::readnPixels(GLint x,
+                          GLint y,
+                          GLsizei width,
+                          GLsizei height,
+                          GLenum format,
+                          GLenum type,
+                          GLsizei bufSize,
+                          void *data)
+{
+    return readPixels(x, y, width, height, format, type, data);
+}
+
+void Context::setFenceNV(GLuint fence, GLenum condition)
+{
+    ASSERT(condition == GL_ALL_COMPLETED_NV);
+
+    FenceNV *fenceObject = getFenceNV(fence);
+    ASSERT(fenceObject != nullptr);
+    handleError(fenceObject->set(condition));
+}
+
+GLboolean Context::testFenceNV(GLuint fence)
+{
+    FenceNV *fenceObject = getFenceNV(fence);
+
+    ASSERT(fenceObject != nullptr);
+    ASSERT(fenceObject->isSet() == GL_TRUE);
+
+    GLboolean result = GL_TRUE;
+    Error error      = fenceObject->test(&result);
+    if (error.isError())
+    {
+        handleError(error);
+        return GL_TRUE;
+    }
+
+    return result;
+}
+
+void Context::eGLImageTargetTexture2D(GLenum 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)
+{
+    Renderbuffer *renderbuffer = mGLState.getCurrentRenderbuffer();
+    egl::Image *imageObject    = reinterpret_cast<egl::Image *>(image);
+    handleError(renderbuffer->setStorageEGLImageTarget(this, imageObject));
+}
+
+void Context::texStorage1D(GLenum target, GLsizei levels, GLenum internalformat, GLsizei width)
+{
+    UNIMPLEMENTED();
+}
+
 }  // namespace gl
--- a/gfx/angle/src/libANGLE/Context.h
+++ b/gfx/angle/src/libANGLE/Context.h
@@ -16,16 +16,17 @@
 #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/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"
 
 namespace rx
 {
@@ -64,34 +65,34 @@ class Context final : public ValidationC
 {
   public:
     Context(rx::EGLImplFactory *implFactory,
             const egl::Config *config,
             const Context *shareContext,
             TextureManager *shareTextures,
             MemoryProgramCache *memoryProgramCache,
             const egl::AttributeMap &attribs,
-            const egl::DisplayExtensions &displayExtensions,
-            bool robustResourceInit);
+            const egl::DisplayExtensions &displayExtensions);
 
     egl::Error onDestroy(const egl::Display *display);
     ~Context() override;
 
     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 createProgram();
     GLuint createTexture();
     GLuint createRenderbuffer();
     GLuint createPaths(GLsizei range);
     GLuint createProgramPipeline();
+    GLuint createShaderProgramv(GLenum 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);
@@ -100,96 +101,79 @@ class Context final : public ValidationC
     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);
-    void setPathParameterf(GLuint path, GLenum pname, GLfloat value);
-    void getPathParameterfv(GLuint path, GLenum pname, GLfloat *value) const;
+    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);
 
     // 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.
-    GLuint createFenceNV();
-    void deleteFenceNV(GLuint fence);
+    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);
 
-    void bindArrayBuffer(GLuint bufferHandle);
-    void bindElementArrayBuffer(GLuint bufferHandle);
     void bindTexture(GLenum 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);
     void bindImageTexture(GLuint unit,
                           GLuint texture,
                           GLint level,
                           GLboolean layered,
                           GLint layer,
                           GLenum access,
                           GLenum format);
-    void bindGenericUniformBuffer(GLuint bufferHandle);
-    void bindIndexedUniformBuffer(GLuint bufferHandle,
-                                  GLuint index,
-                                  GLintptr offset,
-                                  GLsizeiptr size);
-    void bindGenericTransformFeedbackBuffer(GLuint bufferHandle);
-    void bindIndexedTransformFeedbackBuffer(GLuint bufferHandle,
-                                            GLuint index,
-                                            GLintptr offset,
-                                            GLsizeiptr size);
-    void bindGenericAtomicCounterBuffer(GLuint bufferHandle);
-    void bindIndexedAtomicCounterBuffer(GLuint bufferHandle,
-                                        GLuint index,
-                                        GLintptr offset,
-                                        GLsizeiptr size);
-    void bindGenericShaderStorageBuffer(GLuint bufferHandle);
-    void bindIndexedShaderStorageBuffer(GLuint bufferHandle,
-                                        GLuint index,
-                                        GLintptr offset,
-                                        GLsizeiptr size);
-    void bindCopyReadBuffer(GLuint bufferHandle);
-    void bindCopyWriteBuffer(GLuint bufferHandle);
-    void bindPixelPackBuffer(GLuint bufferHandle);
-    void bindPixelUnpackBuffer(GLuint bufferHandle);
     void useProgram(GLuint program);
+    void useProgramStages(GLuint pipeline, GLbitfield stages, GLuint program);
     void bindTransformFeedback(GLenum target, GLuint transformFeedbackHandle);
-    void bindDrawIndirectBuffer(GLuint bufferHandle);
     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 getQueryObjectiv(GLuint id, GLenum pname, GLint *params);
     void getQueryObjectuiv(GLuint id, GLenum pname, GLuint *params);
     void getQueryObjecti64v(GLuint id, GLenum pname, GLint64 *params);
     void getQueryObjectui64v(GLuint id, GLenum pname, GLuint64 *params);
 
     void vertexAttribDivisor(GLuint index, GLuint divisor);
-    void setVertexBindingDivisor(GLuint bindingIndex, GLuint divisor);
+    void vertexBindingDivisor(GLuint bindingIndex, GLuint divisor);
 
-    void getBufferParameteriv(GLenum target, GLenum pname, GLint *params);
+    void getBufferParameteriv(BufferBinding target, GLenum pname, GLint *params);
     void getFramebufferAttachmentParameteriv(GLenum target,
                                              GLenum attachment,
                                              GLenum pname,
                                              GLint *params);
     void getRenderbufferParameteriv(GLenum target, GLenum pname, 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 samplerParameteri(GLuint sampler, GLenum pname, GLint param);
     void samplerParameteriv(GLuint sampler, GLenum pname, const GLint *param);
     void samplerParameterf(GLuint sampler, GLenum pname, GLfloat param);
@@ -261,27 +245,28 @@ class Context final : public ValidationC
     void getIntegerv(GLenum pname, GLint *params);
     void getIntegervImpl(GLenum pname, GLint *params);
     void getInteger64vImpl(GLenum pname, GLint64 *params);
     void getPointerv(GLenum pname, void **params) const;
     void getBooleani_v(GLenum target, GLuint index, GLboolean *data);
     void getIntegeri_v(GLenum target, GLuint index, GLint *data);
     void getInteger64i_v(GLenum target, GLuint index, 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);
     void clearColor(GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha);
     void clearDepthf(GLfloat depth);
     void clearStencil(GLint s);
     void colorMask(GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha);
-    void cullFace(GLenum mode);
+    void cullFace(CullFaceMode mode);
     void depthFunc(GLenum func);
     void depthMask(GLboolean flag);
     void depthRangef(GLfloat zNear, GLfloat zFar);
     void disable(GLenum cap);
     void disableVertexAttribArray(GLuint index);
     void enable(GLenum cap);
     void enableVertexAttribArray(GLuint index);
     void frontFace(GLenum mode);
@@ -541,52 +526,55 @@ class Context final : public ValidationC
                                  GLint yoffset,
                                  GLint zoffset,
                                  GLsizei width,
                                  GLsizei height,
                                  GLsizei depth,
                                  GLenum format,
                                  GLsizei imageSize,
                                  const void *data);
-    void copyTextureCHROMIUM(GLuint sourceId,
-                             GLint sourceLevel,
-                             GLenum destTarget,
-                             GLuint destId,
-                             GLint destLevel,
-                             GLint internalFormat,
-                             GLenum destType,
-                             GLboolean unpackFlipY,
-                             GLboolean unpackPremultiplyAlpha,
-                             GLboolean unpackUnmultiplyAlpha);
-    void copySubTextureCHROMIUM(GLuint sourceId,
-                                GLint sourceLevel,
-                                GLenum destTarget,
-                                GLuint destId,
-                                GLint destLevel,
-                                GLint xoffset,
-                                GLint yoffset,
-                                GLint x,
-                                GLint y,
-                                GLsizei width,
-                                GLsizei height,
-                                GLboolean unpackFlipY,
-                                GLboolean unpackPremultiplyAlpha,
-                                GLboolean unpackUnmultiplyAlpha);
-    void compressedCopyTextureCHROMIUM(GLuint sourceId, GLuint destId);
+    void copyTexture(GLuint sourceId,
+                     GLint sourceLevel,
+                     GLenum destTarget,
+                     GLuint destId,
+                     GLint destLevel,
+                     GLint internalFormat,
+                     GLenum destType,
+                     GLboolean unpackFlipY,
+                     GLboolean unpackPremultiplyAlpha,
+                     GLboolean unpackUnmultiplyAlpha);
+    void copySubTexture(GLuint sourceId,
+                        GLint sourceLevel,
+                        GLenum 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 flush();
     void finish();
 
-    void getBufferPointerv(GLenum target, GLenum pname, void **params);
-    void *mapBuffer(GLenum target, GLenum access);
-    GLboolean unmapBuffer(GLenum target);
-    void *mapBufferRange(GLenum target, GLintptr offset, GLsizeiptr length, GLbitfield access);
-    void flushMappedBufferRange(GLenum target, GLintptr offset, GLsizeiptr length);
+    void getBufferPointerv(BufferBinding target, GLenum pname, 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);
 
     void beginTransformFeedback(GLenum primitiveMode);
 
     bool hasActiveTransformFeedback(GLuint program) const;
 
     void insertEventMarker(GLsizei length, const char *marker);
     void pushGroupMarker(GLsizei length, const char *marker);
     void popGroupMarker();
@@ -663,41 +651,41 @@ class Context final : public ValidationC
                                              const GLfloat *transformValues);
     void bindFragmentInputLocation(GLuint program, GLint location, const GLchar *name);
     void programPathFragmentInputGen(GLuint program,
                                      GLint location,
                                      GLenum genMode,
                                      GLint components,
                                      const GLfloat *coeffs);
 
-    void bufferData(GLenum target, GLsizeiptr size, const void *data, GLenum usage);
-    void bufferSubData(GLenum target, GLintptr offset, GLsizeiptr size, const void *data);
+    void bufferData(BufferBinding target, GLsizeiptr size, const void *data, BufferUsage usage);
+    void bufferSubData(BufferBinding target, GLintptr offset, GLsizeiptr size, const void *data);
     void attachShader(GLuint program, GLuint shader);
     void bindAttribLocation(GLuint program, GLuint index, const GLchar *name);
-    void bindBuffer(GLenum target, GLuint buffer);
-    void bindBufferBase(GLenum target, GLuint index, GLuint buffer);
-    void bindBufferRange(GLenum target,
+    void bindBuffer(BufferBinding target, GLuint buffer);
+    void bindBufferBase(BufferBinding target, GLuint index, GLuint buffer);
+    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,
                                  GLsizei samples,
                                  GLenum internalformat,
                                  GLsizei width,
                                  GLsizei height,
                                  GLboolean fixedsamplelocations);
 
     void getMultisamplefv(GLenum pname, GLuint index, GLfloat *val);
 
-    void copyBufferSubData(GLenum readTarget,
-                           GLenum writeTarget,
+    void copyBufferSubData(BufferBinding readTarget,
+                           BufferBinding writeTarget,
                            GLintptr readOffset,
                            GLintptr writeOffset,
                            GLsizeiptr size);
 
     GLenum checkFramebufferStatus(GLenum target);
     void compileShader(GLuint shader);
     void deleteBuffers(GLsizei n, const GLuint *buffers);
     void deleteFramebuffers(GLsizei n, const GLuint *framebuffers);
@@ -720,17 +708,22 @@ 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 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 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);
@@ -772,16 +765,17 @@ class Context final : public ValidationC
     void uniform4f(GLint location, GLfloat x, GLfloat y, GLfloat z, GLfloat w);
     void uniform4fv(GLint location, GLsizei count, const GLfloat *v);
     void uniform4i(GLint location, GLint x, GLint y, GLint z, GLint w);
     void uniform4iv(GLint location, GLsizei count, const GLint *v);
     void uniformMatrix2fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
     void uniformMatrix3fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
     void uniformMatrix4fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
     void validateProgram(GLuint program);
+    void validateProgramPipeline(GLuint pipeline);
 
     void genQueries(GLsizei n, GLuint *ids);
     void deleteQueries(GLsizei n, const GLuint *ids);
     GLboolean isQuery(GLuint id);
 
     void uniform1ui(GLint location, GLuint v0);
     void uniform2ui(GLint location, GLuint v0, GLuint v1);
     void uniform3ui(GLint location, GLuint v0, GLuint v1, GLuint v2);
@@ -871,88 +865,200 @@ class Context final : public ValidationC
 
     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 getBufferParameteri64v(GLenum target, GLenum pname, GLint64 *params);
+    void getBufferParameteri64v(BufferBinding target, GLenum pname, 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 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);
+    void programUniform4ui(GLuint program,
+                           GLint location,
+                           GLuint v0,
+                           GLuint v1,
+                           GLuint v2,
+                           GLuint v3);
+    void programUniform1f(GLuint program, GLint location, GLfloat v0);
+    void programUniform2f(GLuint program, GLint location, GLfloat v0, GLfloat v1);
+    void programUniform3f(GLuint program, GLint location, GLfloat v0, GLfloat v1, GLfloat v2);
+    void programUniform4f(GLuint program,
+                          GLint location,
+                          GLfloat v0,
+                          GLfloat v1,
+                          GLfloat v2,
+                          GLfloat v3);
     void programUniform1iv(GLuint program, GLint location, GLsizei count, const GLint *value);
+    void programUniform2iv(GLuint program, GLint location, GLsizei count, const GLint *value);
+    void programUniform3iv(GLuint program, GLint location, GLsizei count, const GLint *value);
+    void programUniform4iv(GLuint program, GLint location, GLsizei count, const GLint *value);
+    void programUniform1uiv(GLuint program, GLint location, GLsizei count, const GLuint *value);
+    void programUniform2uiv(GLuint program, GLint location, GLsizei count, const GLuint *value);
+    void programUniform3uiv(GLuint program, GLint location, GLsizei count, const GLuint *value);
+    void programUniform4uiv(GLuint program, GLint location, GLsizei count, const GLuint *value);
+    void programUniform1fv(GLuint program, GLint location, GLsizei count, const GLfloat *value);
+    void programUniform2fv(GLuint program, GLint location, GLsizei count, const GLfloat *value);
+    void programUniform3fv(GLuint program, GLint location, GLsizei count, const GLfloat *value);
+    void programUniform4fv(GLuint program, GLint location, GLsizei count, const GLfloat *value);
+
+    void programUniformMatrix2fv(GLuint program,
+                                 GLint location,
+                                 GLsizei count,
+                                 GLboolean transpose,
+                                 const GLfloat *value);
+
+    void programUniformMatrix3fv(GLuint program,
+                                 GLint location,
+                                 GLsizei count,
+                                 GLboolean transpose,
+                                 const GLfloat *value);
+
+    void programUniformMatrix4fv(GLuint program,
+                                 GLint location,
+                                 GLsizei count,
+                                 GLboolean transpose,
+                                 const GLfloat *value);
+
+    void programUniformMatrix2x3fv(GLuint program,
+                                   GLint location,
+                                   GLsizei count,
+                                   GLboolean transpose,
+                                   const GLfloat *value);
+
+    void programUniformMatrix3x2fv(GLuint program,
+                                   GLint location,
+                                   GLsizei count,
+                                   GLboolean transpose,
+                                   const GLfloat *value);
+
+    void programUniformMatrix2x4fv(GLuint program,
+                                   GLint location,
+                                   GLsizei count,
+                                   GLboolean transpose,
+                                   const GLfloat *value);
+
+    void programUniformMatrix4x2fv(GLuint program,
+                                   GLint location,
+                                   GLsizei count,
+                                   GLboolean transpose,
+                                   const GLfloat *value);
+
+    void programUniformMatrix3x4fv(GLuint program,
+                                   GLint location,
+                                   GLsizei count,
+                                   GLboolean transpose,
+                                   const GLfloat *value);
+
+    void programUniformMatrix4x3fv(GLuint program,
+                                   GLint location,
+                                   GLsizei count,
+                                   GLboolean transpose,
+                                   const GLfloat *value);
 
     void deleteProgramPipelines(GLsizei n, const GLuint *pipelines);
     void genProgramPipelines(GLsizei n, GLuint *pipelines);
     GLboolean isProgramPipeline(GLuint pipeline);
 
-    // Consumes the error.
-    void handleError(const Error &error) override;
-
-    GLenum getError();
-    void markContextLost();
-    bool isContextLost();
-    GLenum getResetStatus();
-    bool isResetNotificationEnabled();
-
-    const egl::Config *getConfig() const;
-    EGLenum getClientType() const;
-    EGLenum getRenderBuffer() const;
-
-    const GLubyte *getString(GLenum name) const;
-    const GLubyte *getStringi(GLenum name, GLuint index) const;
-
-    size_t getExtensionStringCount() const;
-
-    void requestExtension(const char *name);
-    size_t getRequestableExtensionStringCount() const;
-
-    rx::ContextImpl *getImplementation() const { return mImplementation.get(); }
-    const Workarounds &getWorkarounds() const;
+    void getTranslatedShaderSource(GLuint shader, GLsizei bufsize, GLsizei *length, GLchar *source);
+    void getnUniformfv(GLuint program, GLint location, GLsizei bufSize, GLfloat *params);
+    void getnUniformiv(GLuint program, GLint location, GLsizei bufSize, GLint *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 eGLImageTargetRenderbufferStorage(GLenum target, GLeglImageOES image);
 
     void getFramebufferParameteriv(GLenum target, GLenum pname, GLint *params);
-    void setFramebufferParameteri(GLenum target, GLenum pname, GLint param);
-
-    Error getScratchBuffer(size_t requestedSizeBytes, angle::MemoryBuffer **scratchBufferOut) const;
-    Error getZeroFilledBuffer(size_t requstedSizeBytes, angle::MemoryBuffer **zeroBufferOut) const;
+    void framebufferParameteri(GLenum target, GLenum pname, GLint param);
 
     void dispatchCompute(GLuint numGroupsX, GLuint numGroupsY, GLuint numGroupsZ);
-
-    MemoryProgramCache *getMemoryProgramCache() const { return mMemoryProgramCache; }
+    void dispatchComputeIndirect(GLintptr indirect);
 
-    template <EntryPoint EP, typename... ParamsT>
-    void gatherParams(ParamsT &&... params);
-
+    void texStorage1D(GLenum target, GLsizei levels, GLenum internalformat, GLsizei width);
     void texStorage2D(GLenum target,
                       GLsizei levels,
                       GLenum internalFormat,
                       GLsizei width,
                       GLsizei height);
     void texStorage3D(GLenum 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;
+
+    GLenum getError();
+    void markContextLost();
+    bool isContextLost();
+    GLenum getGraphicsResetStatus();
+    bool isResetNotificationEnabled();
+
+    const egl::Config *getConfig() const;
+    EGLenum getClientType() const;
+    EGLenum getRenderBuffer() const;
+
+    const GLubyte *getString(GLenum name) const;
+    const GLubyte *getStringi(GLenum name, GLuint index) const;
+
+    size_t getExtensionStringCount() const;
+
+    bool isExtensionRequestable(const char *name);
+    void requestExtension(const char *name);
+    size_t getRequestableExtensionStringCount() const;
+
+    rx::ContextImpl *getImplementation() const { return mImplementation.get(); }
+    const Workarounds &getWorkarounds() const;
+
+    Error getScratchBuffer(size_t requestedSizeBytes, angle::MemoryBuffer **scratchBufferOut) const;
+    Error getZeroFilledBuffer(size_t requstedSizeBytes, angle::MemoryBuffer **zeroBufferOut) const;
+
+    Error prepareForDispatch();
+
+    MemoryProgramCache *getMemoryProgramCache() const { return mMemoryProgramCache; }
+
+    template <EntryPoint EP, typename... ParamsT>
+    void gatherParams(ParamsT &&... params);
+
     // Notification for a state change in a Texture.
     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(); }
+
   private:
+    Error prepareForDraw();
     void syncRendererState();
     void syncRendererState(const State::DirtyBits &bitMask, const State::DirtyObjects &objectMask);
     void syncStateForReadPixels();
     void syncStateForTexImage();
     void syncStateForClear();
     void syncStateForBlit();
     VertexArray *checkVertexArrayAllocation(GLuint vertexArrayHandle);
     TransformFeedback *checkTransformFeedbackAllocation(GLuint transformFeedback);
@@ -965,17 +1071,17 @@ class Context final : public ValidationC
     void detachTransformFeedback(GLuint transformFeedback);
     void detachSampler(GLuint sampler);
     void detachProgramPipeline(GLuint pipeline);
 
     void initRendererString();
     void initVersionStrings();
     void initExtensionStrings();
 
-    void initCaps(const egl::DisplayExtensions &displayExtensions);
+    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;
 
     std::unique_ptr<rx::ContextImpl> mImplementation;
 
@@ -1035,16 +1141,18 @@ class Context final : public ValidationC
     State::DirtyBits mTexImageDirtyBits;
     State::DirtyObjects mTexImageDirtyObjects;
     State::DirtyBits mReadPixelsDirtyBits;
     State::DirtyObjects mReadPixelsDirtyObjects;
     State::DirtyBits mClearDirtyBits;
     State::DirtyObjects mClearDirtyObjects;
     State::DirtyBits mBlitDirtyBits;
     State::DirtyObjects mBlitDirtyObjects;
+    State::DirtyBits mComputeDirtyBits;
+    State::DirtyObjects mComputeDirtyObjects;
 
     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;
 };
 
--- a/gfx/angle/src/libANGLE/ContextState.cpp
+++ b/gfx/angle/src/libANGLE/ContextState.cpp
@@ -131,16 +131,20 @@ ValidationContext::ValidationContext(con
              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
@@ -148,22 +152,16 @@ bool ValidationContext::getQueryParamete
     switch (pname)
     {
         case GL_COMPRESSED_TEXTURE_FORMATS:
         {
             *type      = GL_INT;
             *numParams = static_cast<unsigned int>(getCaps().compressedTextureFormats.size());
             return true;
         }
-        case GL_PROGRAM_BINARY_FORMATS_OES:
-        {
-            *type      = GL_INT;
-            *numParams = static_cast<unsigned int>(getCaps().programBinaryFormats.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:
@@ -172,23 +170,20 @@ bool ValidationContext::getQueryParamete
         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: // equivalent to DRAW_FRAMEBUFFER_BINDING_ANGLE
-        case GL_DRAW_FRAMEBUFFER_BINDING_ANGLE:
-        case GL_READ_FRAMEBUFFER_BINDING_ANGLE:
+        case GL_FRAMEBUFFER_BINDING:
         case GL_RENDERBUFFER_BINDING:
         case GL_CURRENT_PROGRAM:
         case GL_PACK_ALIGNMENT:
-        case GL_PACK_REVERSE_ROW_ORDER_ANGLE:
         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:
@@ -223,22 +218,31 @@ bool ValidationContext::getQueryParamete
         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:
-        case GL_NUM_PROGRAM_BINARY_FORMATS_OES:
         {
             *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;
@@ -437,33 +441,61 @@ bool ValidationContext::getQueryParamete
             case GL_FRAMEBUFFER_SRGB_EXT:
                 *type      = GL_BOOL;
                 *numParams = 1;
                 return true;
         }
     }
 
     if (getExtensions().robustResourceInitialization &&
-        pname == GL_CONTEXT_ROBUST_RESOURCE_INITIALIZATION_ANGLE)
+        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;
@@ -628,16 +660,17 @@ bool ValidationContext::getQueryParamete
     {
         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:
@@ -684,16 +717,41 @@ bool ValidationContext::getQueryParamete
             *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))
@@ -723,25 +781,36 @@ bool ValidationContext::getIndexedQueryP
 
     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:
--- a/gfx/angle/src/libANGLE/ContextState.h
+++ b/gfx/angle/src/libANGLE/ContextState.h
@@ -96,17 +96,17 @@ class ValidationContext : angle::NonCopy
                       TextureManager *shareTextures,
                       const Version &clientVersion,
                       State *state,
                       const Caps &caps,
                       const TextureCapsMap &textureCaps,
                       const Extensions &extensions,
                       const Limitations &limitations,
                       bool skipValidation);
-    virtual ~ValidationContext() {}
+    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(); }
@@ -135,21 +135,26 @@ class ValidationContext : angle::NonCopy
     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
--- a/gfx/angle/src/libANGLE/Debug.cpp
+++ b/gfx/angle/src/libANGLE/Debug.cpp
@@ -11,28 +11,52 @@
 #include "common/debug.h"
 
 #include <algorithm>
 #include <tuple>
 
 namespace gl
 {
 
+Debug::Control::Control()
+{
+}
+
+Debug::Control::~Control()
+{
+}
+
+Debug::Control::Control(const Control &other) = default;
+
+Debug::Group::Group()
+{
+}
+
+Debug::Group::~Group()
+{
+}
+
+Debug::Group::Group(const Group &other) = default;
+
 Debug::Debug()
     : mOutputEnabled(false),
       mCallbackFunction(nullptr),
       mCallbackUserParam(nullptr),
       mMessages(),
       mMaxLoggedMessages(0),
       mOutputSynchronous(false),
       mGroups()
 {
     pushDefaultGroup();
 }
 
+Debug::~Debug()
+{
+}
+
 void Debug::setMaxLoggedMessages(GLuint maxLoggedMessages)
 {
     mMaxLoggedMessages = maxLoggedMessages;
 }
 
 void Debug::setOutputEnabled(bool enabled)
 {
     mOutputEnabled = enabled;
--- a/gfx/angle/src/libANGLE/Debug.h
+++ b/gfx/angle/src/libANGLE/Debug.h
@@ -26,16 +26,17 @@ class LabeledObject
     virtual void setLabel(const std::string &label) = 0;
     virtual const std::string &getLabel() const = 0;
 };
 
 class Debug : angle::NonCopyable
 {
   public:
     Debug();
+    ~Debug();
 
     void setMaxLoggedMessages(GLuint maxLoggedMessages);
 
     void setOutputEnabled(bool enabled);
     bool isOutputEnabled() const;
 
     void setOutputSynchronous(bool synchronous);
     bool isOutputSynchronous() const;
@@ -86,25 +87,33 @@ class Debug : angle::NonCopyable
         GLenum type;
         GLuint id;
         GLenum severity;
         std::string message;
     };
 
     struct Control
     {
+        Control();
+        ~Control();
+        Control(const Control &other);
+
         GLenum source;
         GLenum type;
         GLenum severity;
         std::vector<GLuint> ids;
         bool enabled;
     };
 
     struct Group
     {
+        Group();
+        ~Group();
+        Group(const Group &other);
+
         GLenum source;
         GLuint id;
         std::string message;
 
         std::vector<Control> controls;
     };
 
     bool mOutputEnabled;
--- a/gfx/angle/src/libANGLE/Display.cpp
+++ b/gfx/angle/src/libANGLE/Display.cpp
@@ -263,16 +263,24 @@ void ANGLESetDefaultDisplayPlatform(angl
     ANGLEResetDisplayPlatform(display);
     platformMethods->logError   = Display_logError;
     platformMethods->logWarning = Display_logWarning;
     platformMethods->logInfo    = Display_logInfo;
 }
 
 }  // anonymous namespace
 
+DisplayState::DisplayState()
+{
+}
+
+DisplayState::~DisplayState()
+{
+}
+
 // static
 Display *Display::GetDisplayFromNativeDisplay(EGLNativeDisplayType nativeDisplay,
                                               const AttributeMap &attribMap)
 {
     Display *display = nullptr;
 
     ANGLEPlatformDisplayMap *displays = GetANGLEPlatformDisplayMap();
     const auto &iter                  = displays->find(nativeDisplay);
@@ -488,17 +496,17 @@ Error Display::initialize()
     {
         // For EGL_PLATFORM_DEVICE_EXT, mDevice should always be populated using
         // an external device
         ASSERT(mDevice != nullptr);
     }
 
     mProxyContext.reset(nullptr);
     gl::Context *proxyContext = new gl::Context(mImplementation, nullptr, nullptr, nullptr, nullptr,
-                                                egl::AttributeMap(), mDisplayExtensions, false);
+                                                egl::AttributeMap(), mDisplayExtensions);
     mProxyContext.reset(proxyContext);
 
     mInitialized = true;
 
     return NoError();
 }
 
 Error Display::terminate()
@@ -752,17 +760,17 @@ Error Display::createContext(const Confi
     // A program cache size of zero indicates it should be disabled.
     if (mMemoryProgramCache.maxSize() == 0)
     {
         cachePointer = nullptr;
     }
 
     gl::Context *context =
         new gl::Context(mImplementation, configuration, shareContext, shareTextures, cachePointer,
-                        attribs, mDisplayExtensions, isRobustResourceInitEnabled());
+                        attribs, mDisplayExtensions);
 
     ASSERT(context != nullptr);
     mContextSet.insert(context);
 
     ASSERT(outContext != nullptr);
     *outContext = context;
     return NoError();
 }
@@ -975,19 +983,16 @@ static ClientExtensions GenerateClientEx
 #endif
 
 #if defined(ANGLE_USE_X11)
     extensions.x11Visual = true;
 #endif
 
     extensions.clientGetAllProcAddresses = true;
 
-    // TODO(jmadill): Not fully implemented yet, but exposed everywhere.
-    extensions.displayRobustResourceInitialization = true;
-
     return extensions;
 }
 
 template <typename T>
 static std::string GenerateExtensionsString(const T &extensions)
 {
     std::vector<std::string> extensionsVector = extensions.getStrings();
 
@@ -1114,22 +1119,16 @@ Device *Display::getDevice() const
     return mDevice;
 }
 
 gl::Version Display::getMaxSupportedESVersion() const
 {
     return mImplementation->getMaxSupportedESVersion();
 }
 
-bool Display::isRobustResourceInitEnabled() const
-{
-    return (mAttributeMap.get(EGL_DISPLAY_ROBUST_RESOURCE_INITIALIZATION_ANGLE, EGL_FALSE) ==
-            EGL_TRUE);
-}
-
 EGLint Display::programCacheGetAttrib(EGLenum attrib) const
 {
     switch (attrib)
     {
         case EGL_PROGRAM_CACHE_KEY_LENGTH_ANGLE:
             return static_cast<EGLint>(gl::kProgramHashLength);
 
         case EGL_PROGRAM_CACHE_SIZE_ANGLE:
--- a/gfx/angle/src/libANGLE/Display.h
+++ b/gfx/angle/src/libANGLE/Display.h
@@ -40,16 +40,19 @@ class Image;
 class Surface;
 class Stream;
 class Thread;
 
 using SurfaceSet = std::set<Surface *>;
 
 struct DisplayState final : private angle::NonCopyable
 {
+    DisplayState();
+    ~DisplayState();
+
     SurfaceSet surfaceSet;
 };
 
 // Constant coded here as a sanity limit.
 constexpr EGLAttrib kProgramCacheSizeAbsoluteMax = 0x4000000;
 
 class Display final : angle::NonCopyable
 {
@@ -153,18 +156,16 @@ class Display final : angle::NonCopyable
     rx::DisplayImpl *getImplementation() const { return mImplementation; }
     Device *getDevice() const;
     EGLenum getPlatform() const { return mPlatform; }
 
     gl::Version getMaxSupportedESVersion() const;
 
     const DisplayState &getState() const { return mState; }
 
-    bool isRobustResourceInitEnabled() const;
-
     gl::Context *getProxyContext() const { return mProxyContext.get(); }
 
   private:
     Display(EGLenum platform, EGLNativeDisplayType displayId, Device *eglDevice);
 
     void setAttributes(rx::DisplayImpl *impl, const AttributeMap &attribMap);
 
     Error restoreLostDevice();
--- a/gfx/angle/src/libANGLE/Error.cpp
+++ b/gfx/angle/src/libANGLE/Error.cpp
@@ -6,37 +6,47 @@
 
 // Error.cpp: Implements the egl::Error and gl::Error classes which encapsulate API errors
 // and optional error messages.
 
 #include "libANGLE/Error.h"
 
 #include "common/angleutils.h"
 #include "common/debug.h"
+#include "common/utilities.h"
 
 #include <cstdarg>
 
+namespace
+{
+std::unique_ptr<std::string> EmplaceErrorString(std::string &&message)
+{
+    return message.empty() ? std::unique_ptr<std::string>()
+                           : std::unique_ptr<std::string>(new std::string(std::move(message)));
+}
+}  // anonymous namespace
+
 namespace gl
 {
 
 Error::Error(GLenum errorCode, std::string &&message)
-    : mCode(errorCode), mID(errorCode), mMessage(new std::string(std::move(message)))
+    : mCode(errorCode), mID(errorCode), mMessage(EmplaceErrorString(std::move(message)))
 {
 }
 
 Error::Error(GLenum errorCode, GLuint id, std::string &&message)
-    : mCode(errorCode), mID(id), mMessage(new std::string(std::move(message)))
+    : mCode(errorCode), mID(id), mMessage(EmplaceErrorString(std::move(message)))
 {
 }
 
 void Error::createMessageString() const
 {
     if (!mMessage)
     {
-        mMessage.reset(new std::string);
+        mMessage.reset(new std::string(GetGenericErrorMessage(mCode)));
     }
 }
 
 const std::string &Error::getMessage() const
 {
     createMessageString();
     return *mMessage;
 }
@@ -64,30 +74,30 @@ std::ostream &operator<<(std::ostream &o
 }
 
 }  // namespace gl
 
 namespace egl
 {
 
 Error::Error(EGLint errorCode, std::string &&message)
-    : mCode(errorCode), mID(errorCode), mMessage(new std::string(std::move(message)))
+    : mCode(errorCode), mID(errorCode), mMessage(EmplaceErrorString(std::move(message)))
 {
 }
 
 Error::Error(EGLint errorCode, EGLint id, std::string &&message)
-    : mCode(errorCode), mID(id), mMessage(new std::string(std::move(message)))
+    : mCode(errorCode), mID(id), mMessage(EmplaceErrorString(std::move(message)))
 {
 }
 
 void Error::createMessageString() const
 {
     if (!mMessage)
     {
-        mMessage.reset(new std::string);
+        mMessage.reset(new std::string(GetGenericErrorMessage(mCode)));
     }
 }
 
 const std::string &Error::getMessage() const
 {
     createMessageString();
     return *mMessage;
 }
--- a/gfx/angle/src/libANGLE/Error.h
+++ b/gfx/angle/src/libANGLE/Error.h
@@ -82,16 +82,17 @@ namespace gl
 class ANGLE_NO_DISCARD Error final
 {
   public:
     explicit inline Error(GLenum errorCode);
     Error(GLenum errorCode, std::string &&message);
     Error(GLenum errorCode, GLuint id, std::string &&message);
     inline Error(const Error &other);
     inline Error(Error &&other);
+    inline ~Error() = default;
 
     // automatic error type conversion
     inline Error(egl::Error &&eglErr);
     inline Error(egl::Error eglErr);
 
     inline Error &operator=(const Error &other);
     inline Error &operator=(Error &&other);
 
@@ -152,16 +153,17 @@ namespace egl
 class ANGLE_NO_DISCARD Error final
 {
   public:
     explicit inline Error(EGLint errorCode);
     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 &operator=(const Error &other);
     inline Error &operator=(Error &&other);
 
--- a/gfx/angle/src/libANGLE/ErrorStrings.h
+++ b/gfx/angle/src/libANGLE/ErrorStrings.h
@@ -21,28 +21,31 @@ ERRMSG(CompressedTextureDimensionsMustMa
        "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(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, "Compressed textures do not support mipmap generation.");
+ERRMSG(GenerateMipmapNotAllowed, "Texture format does not support mipmap generation.");
 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(InvalidAttachment, "Invalid Attachment Type.");
 ERRMSG(InvalidBlendEquation, "Invalid blend equation.");
@@ -59,24 +62,29 @@ ERRMSG(InvalidCoverMode, "Invalid cover 
 ERRMSG(InvalidCullMode, "Cull mode not recognized.");
 ERRMSG(InvalidDebugSeverity, "Invalid debug severity.");
 ERRMSG(InvalidDebugSource, "Invalid debug source.");
 ERRMSG(InvalidDebugType, "Invalid debug type.");
 ERRMSG(InvalidDepthRange, "Near value cannot be greater than far.");
 ERRMSG(InvalidDrawMode, "Invalid draw mode.");
 ERRMSG(InvalidDrawModeTransformFeedback,
        "Draw mode must match current transform feedback object's draw mode.");
+ERRMSG(InvalidFence, "Invalid fence object.");
+ERRMSG(InvalidFenceState, "Fence must be set.");
 ERRMSG(InvalidFillMode, "Invalid fill mode.");
 ERRMSG(InvalidFilterTexture, "Texture only supports NEAREST and LINEAR filtering.");
 ERRMSG(InvalidFormat, "Invalid format.");
 ERRMSG(InvalidFramebufferTarget, "Invalid framebuffer target.");
 ERRMSG(InvalidFramebufferTextureLevel, "Mipmap level must be 0 when attaching a texture.");
-ERRMSG(InvalidFramebufferTextureParameter, "Invalid parameter name for framebuffer attachment.");
+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(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.");
@@ -119,23 +127,30 @@ ERRMSG(NegativeBufferSize, "Negative buf
 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(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.");
 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(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.");
@@ -154,16 +169,18 @@ ERRMSG(TransformFeedbackDoesNotExist, "T
 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(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(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.");
 }
 #undef ERRMSG
--- a/gfx/angle/src/libANGLE/Fence.cpp
+++ b/gfx/angle/src/libANGLE/Fence.cpp
@@ -78,16 +78,21 @@ Sync::Sync(rx::SyncImpl *impl, GLuint id
     : RefCountObject(id),
       mFence(impl),
       mLabel(),
       mCondition(GL_SYNC_GPU_COMMANDS_COMPLETE),
       mFlags(0)
 {
 }
 
+Error Sync::onDestroy(const Context *context)
+{
+    return NoError();
+}
+
 Sync::~Sync()
 {
     SafeDelete(mFence);
 }
 
 void Sync::setLabel(const std::string &label)
 {
     mLabel = label;
--- a/gfx/angle/src/libANGLE/Fence.h
+++ b/gfx/angle/src/libANGLE/Fence.h
@@ -47,19 +47,19 @@ class FenceNV final : angle::NonCopyable
     GLboolean mStatus;
     GLenum mCondition;
 };
 
 class Sync final : public RefCountObject, public LabeledObject
 {
   public:
     Sync(rx::SyncImpl *impl, GLuint id);
-    virtual ~Sync();
+    ~Sync() override;
 
-    Error onDestroy(const Context *context) override { return NoError(); }
+    Error onDestroy(const Context *context) override;
 
     void setLabel(const std::string &label) override;
     const std::string &getLabel() const override;
 
     Error set(GLenum condition, GLbitfield flags);
     Error clientWait(GLbitfield flags, GLuint64 timeout, GLenum *outResult);
     Error serverWait(GLbitfield flags, GLuint64 timeout);
     Error getStatus(GLint *outResult) const;
--- a/gfx/angle/src/libANGLE/Framebuffer.cpp
+++ b/gfx/angle/src/libANGLE/Framebuffer.cpp
@@ -14,16 +14,17 @@
 #include "common/utilities.h"
 #include "libANGLE/Config.h"
 #include "libANGLE/Context.h"
 #include "libANGLE/Display.h"
 #include "libANGLE/FramebufferAttachment.h"
 #include "libANGLE/Renderbuffer.h"
 #include "libANGLE/Surface.h"
 #include "libANGLE/Texture.h"
+#include "libANGLE/angletypes.h"
 #include "libANGLE/formatutils.h"
 #include "libANGLE/renderer/ContextImpl.h"
 #include "libANGLE/renderer/FramebufferImpl.h"
 #include "libANGLE/renderer/GLImplFactory.h"
 #include "libANGLE/renderer/RenderbufferImpl.h"
 #include "libANGLE/renderer/SurfaceImpl.h"
 
 using namespace angle;
@@ -132,31 +133,31 @@ bool CheckAttachmentCompleteness(const C
 
     return true;
 };
 
 bool CheckAttachmentSampleCompleteness(const Context *context,
                                        const FramebufferAttachment &attachment,
                                        bool colorAttachment,
                                        Optional<int> *samples,
-                                       Optional<GLboolean> *fixedSampleLocations)
+                                       Optional<bool> *fixedSampleLocations)
 {
     ASSERT(attachment.isAttached());
 
     if (attachment.type() == GL_TEXTURE)
     {
         const Texture *texture = attachment.getTexture();
         ASSERT(texture);
 
         const ImageIndex &attachmentImageIndex = attachment.getTextureImageIndex();
 
         // ES3.1 (section 9.4) requires that the value of TEXTURE_FIXED_SAMPLE_LOCATIONS should be
         // the same for all attached textures.
-        GLboolean fixedSampleloc = texture->getFixedSampleLocations(attachmentImageIndex.type,
-                                                                    attachmentImageIndex.mipIndex);
+        bool fixedSampleloc = texture->getFixedSampleLocations(attachmentImageIndex.type,
+                                                               attachmentImageIndex.mipIndex);
         if (fixedSampleLocations->valid() && fixedSampleloc != fixedSampleLocations->value())
         {
             return false;
         }
         else
         {
             *fixedSampleLocations = fixedSampleloc;
         }
@@ -191,39 +192,97 @@ bool CheckAttachmentSampleCompleteness(c
     else
     {
         *samples = attachment.getSamples();
     }
 
     return true;
 }
 
+// Needed to index into the attachment arrays/bitsets.
+static_assert(static_cast<size_t>(IMPLEMENTATION_MAX_FRAMEBUFFER_ATTACHMENTS) ==
+                  gl::Framebuffer::DIRTY_BIT_COLOR_ATTACHMENT_MAX,
+              "Framebuffer Dirty bit mismatch");
+static_assert(static_cast<size_t>(IMPLEMENTATION_MAX_FRAMEBUFFER_ATTACHMENTS) ==
+                  gl::Framebuffer::DIRTY_BIT_DEPTH_ATTACHMENT,
+              "Framebuffer Dirty bit mismatch");
+static_assert(static_cast<size_t>(IMPLEMENTATION_MAX_FRAMEBUFFER_ATTACHMENTS + 1) ==
+                  gl::Framebuffer::DIRTY_BIT_STENCIL_ATTACHMENT,
+              "Framebuffer Dirty bit mismatch");
+
+Error InitAttachment(const Context *context, FramebufferAttachment *attachment)
+{
+    ASSERT(attachment->isAttached());
+    if (attachment->initState() == InitState::MayNeedInit)
+    {
+        ANGLE_TRY(attachment->initializeContents(context));
+    }
+    return NoError();
+}
+
+bool IsColorMaskedOut(const BlendState &blend)
+{
+    return (!blend.colorMaskRed && !blend.colorMaskGreen && !blend.colorMaskBlue &&
+            !blend.colorMaskAlpha);
+}
+
+bool IsDepthMaskedOut(const DepthStencilState &depthStencil)
+{
+    return !depthStencil.depthMask;
+}
+
+bool IsStencilMaskedOut(const DepthStencilState &depthStencil)
+{
+    return ((depthStencil.stencilMask & depthStencil.stencilWritemask) == 0);
+}
+
+bool IsClearBufferMaskedOut(const Context *context, GLenum buffer)
+{
+    switch (buffer)
+    {
+        case GL_COLOR:
+            return IsColorMaskedOut(context->getGLState().getBlendState());
+        case GL_DEPTH:
+            return IsDepthMaskedOut(context->getGLState().getDepthStencilState());
+        case GL_STENCIL:
+            return IsStencilMaskedOut(context->getGLState().getDepthStencilState());
+        case GL_DEPTH_STENCIL:
+            return IsDepthMaskedOut(context->getGLState().getDepthStencilState()) &&
+                   IsStencilMaskedOut(context->getGLState().getDepthStencilState());
+        default:
+            UNREACHABLE();
+            return true;
+    }
+}
+
 }  // anonymous namespace
 
 // This constructor is only used for default framebuffers.
 FramebufferState::FramebufferState()
     : mLabel(),
       mColorAttachments(1),
       mDrawBufferStates(1, GL_BACK),
       mReadBufferState(GL_BACK),
+      mDrawBufferTypeMask(),
       mDefaultWidth(0),
       mDefaultHeight(0),
       mDefaultSamples(0),
       mDefaultFixedSampleLocations(GL_FALSE),
       mWebGLDepthStencilConsistent(true)
 {
     ASSERT(mDrawBufferStates.size() > 0);
     mEnabledDrawBuffers.set(0);
 }
 
 FramebufferState::FramebufferState(const Caps &caps)
     : mLabel(),
       mColorAttachments(caps.maxColorAttachments),
       mDrawBufferStates(caps.maxDrawBuffers, GL_NONE),
       mReadBufferState(GL_COLOR_ATTACHMENT0_EXT),
+      mDrawBufferTypeMask(),
       mDefaultWidth(0),
       mDefaultHeight(0),
       mDefaultSamples(0),
       mDefaultFixedSampleLocations(GL_FALSE),
       mWebGLDepthStencilConsistent(true)
 {
     ASSERT(mDrawBufferStates.size() > 0);
     mDrawBufferStates[0] = GL_COLOR_ATTACHMENT0_EXT;
@@ -233,55 +292,86 @@ FramebufferState::~FramebufferState()
 {
 }
 
 const std::string &FramebufferState::getLabel()
 {
     return mLabel;
 }
 
-const FramebufferAttachment *FramebufferState::getAttachment(GLenum attachment) const
+const FramebufferAttachment *FramebufferState::getAttachment(const Context *context,
+                                                             GLenum attachment) const
 {
     if (attachment >= GL_COLOR_ATTACHMENT0 && attachment <= GL_COLOR_ATTACHMENT15)
     {
         return getColorAttachment(attachment - GL_COLOR_ATTACHMENT0);
     }
 
+    // WebGL1 allows a developer to query for attachment parameters even when "inconsistant" (i.e.
+    // multiple conflicting attachment points) and requires us to return the framebuffer attachment
+    // associated with WebGL.
     switch (attachment)
     {
         case GL_COLOR:
         case GL_BACK:
             return getColorAttachment(0);
         case GL_DEPTH:
         case GL_DEPTH_ATTACHMENT:
-            return getDepthAttachment();
+            if (context->isWebGL1())
+            {
+                return getWebGLDepthAttachment();
+            }
+            else
+            {
+                return getDepthAttachment();
+            }
         case GL_STENCIL:
         case GL_STENCIL_ATTACHMENT:
-            return getStencilAttachment();
+            if (context->isWebGL1())
+            {
+                return getWebGLStencilAttachment();
+            }
+            else
+            {
+                return getStencilAttachment();
+            }
         case GL_DEPTH_STENCIL:
         case GL_DEPTH_STENCIL_ATTACHMENT:
-            return getDepthStencilAttachment();
+            if (context->isWebGL1())
+            {
+                return getWebGLDepthStencilAttachment();
+            }
+            else
+            {
+                return getDepthStencilAttachment();
+            }
         default:
             UNREACHABLE();
             return nullptr;
     }
 }
 
+size_t FramebufferState::getReadIndex() const
+{
+    ASSERT(mReadBufferState == GL_BACK ||
+           (mReadBufferState >= GL_COLOR_ATTACHMENT0 && mReadBufferState <= GL_COLOR_ATTACHMENT15));
+    size_t readIndex = (mReadBufferState == GL_BACK
+                            ? 0
+                            : static_cast<size_t>(mReadBufferState - GL_COLOR_ATTACHMENT0));
+    ASSERT(readIndex < mColorAttachments.size());
+    return readIndex;
+}
+
 const FramebufferAttachment *FramebufferState::getReadAttachment() const
 {
     if (mReadBufferState == GL_NONE)
     {
         return nullptr;
     }
-    ASSERT(mReadBufferState == GL_BACK ||
-           (mReadBufferState >= GL_COLOR_ATTACHMENT0 && mReadBufferState <= GL_COLOR_ATTACHMENT15));
-    size_t readIndex = (mReadBufferState == GL_BACK
-                            ? 0
-                            : static_cast<size_t>(mReadBufferState - GL_COLOR_ATTACHMENT0));
-    ASSERT(readIndex < mColorAttachments.size());
+    size_t readIndex = getReadIndex();
     return mColorAttachments[readIndex].isAttached() ? &mColorAttachments[readIndex] : nullptr;
 }
 
 const FramebufferAttachment *FramebufferState::getFirstNonNullAttachment() const
 {
     auto *colorAttachment = getFirstColorAttachment();
     if (colorAttachment)
     {
@@ -332,21 +422,36 @@ const FramebufferAttachment *Framebuffer
                                                            : nullptr;
 }
 
 const FramebufferAttachment *FramebufferState::getDepthAttachment() const
 {
     return mDepthAttachment.isAttached() ? &mDepthAttachment : nullptr;
 }
 
+const FramebufferAttachment *FramebufferState::getWebGLDepthAttachment() const
+{
+    return mWebGLDepthAttachment.isAttached() ? &mWebGLDepthAttachment : nullptr;
+}
+
+const FramebufferAttachment *FramebufferState::getWebGLDepthStencilAttachment() const
+{
+    return mWebGLDepthStencilAttachment.isAttached() ? &mWebGLDepthStencilAttachment : nullptr;
+}
+
 const FramebufferAttachment *FramebufferState::getStencilAttachment() const
 {
     return mStencilAttachment.isAttached() ? &mStencilAttachment : nullptr;
 }
 
+const FramebufferAttachment *FramebufferState::getWebGLStencilAttachment() const
+{
+    return mWebGLStencilAttachment.isAttached() ? &mWebGLStencilAttachment : nullptr;
+}
+
 const FramebufferAttachment *FramebufferState::getDepthStencilAttachment() const
 {
     // A valid depth-stencil attachment has the same resource bound to both the
     // depth and stencil attachment points.
     if (mDepthAttachment.isAttached() && mStencilAttachment.isAttached() &&
         mDepthAttachment == mStencilAttachment)
     {
         return &mDepthAttachment;
@@ -366,19 +471,19 @@ bool FramebufferState::attachmentsHaveSa
         }
 
         if (!attachmentSize.valid())
         {
             attachmentSize = attachment.getSize();
             return false;
         }
 
-        const Extents &size = attachment.getSize();
-        return size.width != attachmentSize.value().width ||
-            size.height != attachmentSize.value().height;
+        const auto &prevSize = attachmentSize.value();
+        const auto &curSize  = attachment.getSize();
+        return (curSize.width != prevSize.width || curSize.height != prevSize.height);
     };
 
     for (const auto &attachment : mColorAttachments)
     {
         if (hasMismatchedSize(attachment))
         {
             return false;
         }
@@ -396,17 +501,25 @@ const gl::FramebufferAttachment *Framebu
 {
     ASSERT(drawBufferIdx < mDrawBufferStates.size());
     if (mDrawBufferStates[drawBufferIdx] != GL_NONE)
     {
         // ES3 spec: "If the GL is bound to a draw framebuffer object, the ith buffer listed in bufs
         // must be COLOR_ATTACHMENTi or NONE"
         ASSERT(mDrawBufferStates[drawBufferIdx] == GL_COLOR_ATTACHMENT0 + drawBufferIdx ||
                (drawBufferIdx == 0 && mDrawBufferStates[drawBufferIdx] == GL_BACK));
-        return getAttachment(mDrawBufferStates[drawBufferIdx]);
+
+        if (mDrawBufferStates[drawBufferIdx] == GL_BACK)
+        {
+            return getColorAttachment(0);
+        }
+        else
+        {
+            return getColorAttachment(mDrawBufferStates[drawBufferIdx] - GL_COLOR_ATTACHMENT0);
+        }
     }
     else
     {
         return nullptr;
     }
 }
 
 size_t FramebufferState::getDrawBufferCount() const
@@ -490,16 +603,24 @@ int FramebufferState::getBaseViewIndex()
     const FramebufferAttachment *attachment = getFirstNonNullAttachment();
     if (attachment == nullptr)
     {
         return GL_NONE;
     }
     return attachment->getBaseViewIndex();
 }
 
+Box FramebufferState::getDimensions() const
+{
+    ASSERT(attachmentsHaveSameDimensions());
+    ASSERT(getFirstNonNullAttachment() != nullptr);
+    Extents extents = getFirstNonNullAttachment()->getSize();
+    return Box(0, 0, 0, extents.width, extents.height, extents.depth);
+}
+
 Framebuffer::Framebuffer(const Caps &caps, rx::GLImplFactory *factory, GLuint id)
     : mState(caps),
       mImpl(factory->createFramebuffer(mState)),
       mId(id),
       mCachedStatus(),
       mDirtyDepthAttachmentBinding(this, DIRTY_BIT_DEPTH_ATTACHMENT),
       mDirtyStencilAttachmentBinding(this, DIRTY_BIT_STENCIL_ATTACHMENT)
 {
@@ -546,27 +667,29 @@ Framebuffer::Framebuffer(const egl::Disp
     {
         setAttachmentImpl(proxyContext, GL_FRAMEBUFFER_DEFAULT, GL_STENCIL,
                           gl::ImageIndex::MakeInvalid(), surface,
                           FramebufferAttachment::kDefaultNumViews,
                           FramebufferAttachment::kDefaultBaseViewIndex,
                           FramebufferAttachment::kDefaultMultiviewLayout,
                           FramebufferAttachment::kDefaultViewportOffsets);
     }
+    mState.mDrawBufferTypeMask.setIndex(getDrawbufferWriteType(0), 0);
 }
 
 Framebuffer::Framebuffer(rx::GLImplFactory *factory)
     : mState(),
       mImpl(factory->createFramebuffer(mState)),
       mId(0),
       mCachedStatus(GL_FRAMEBUFFER_UNDEFINED_OES),
       mDirtyDepthAttachmentBinding(this, DIRTY_BIT_DEPTH_ATTACHMENT),
       mDirtyStencilAttachmentBinding(this, DIRTY_BIT_STENCIL_ATTACHMENT)
 {
     mDirtyColorAttachmentBindings.emplace_back(this, DIRTY_BIT_COLOR_ATTACHMENT_0);
+    mState.mDrawBufferTypeMask.setIndex(getDrawbufferWriteType(0), 0);
 }
 
 Framebuffer::~Framebuffer()
 {
     SafeDelete(mImpl);
 }
 
 void Framebuffer::onDestroy(const Context *context)
@@ -659,16 +782,17 @@ bool Framebuffer::detachMatchingAttachme
                                            GLenum matchType,
                                            GLuint matchId,
                                            size_t dirtyBit)
 {
     if (attachment->isAttached() && attachment->type() == matchType && attachment->id() == matchId)
     {
         attachment->detach(context);
         mDirtyBits.set(dirtyBit);
+        mState.mResourceNeedsInit.set(dirtyBit, false);
         return true;
     }
 
     return false;
 }
 
 const FramebufferAttachment *Framebuffer::getColorbuffer(size_t colorAttachment) const
 {
@@ -716,19 +840,20 @@ const FramebufferAttachment *Framebuffer
     return mState.getFirstColorAttachment();
 }
 
 const FramebufferAttachment *Framebuffer::getFirstNonNullAttachment() const
 {
     return mState.getFirstNonNullAttachment();
 }
 
-const FramebufferAttachment *Framebuffer::getAttachment(GLenum attachment) const
+const FramebufferAttachment *Framebuffer::getAttachment(const Context *context,
+                                                        GLenum attachment) const
 {
-    return mState.getAttachment(attachment);
+    return mState.getAttachment(context, attachment);
 }
 
 size_t Framebuffer::getDrawbufferStateCount() const
 {
     return mState.mDrawBufferStates.size();
 }
 
 GLenum Framebuffer::getDrawBufferState(size_t drawBuffer) const
@@ -747,18 +872,22 @@ void Framebuffer::setDrawBuffers(size_t 
     auto &drawStates = mState.mDrawBufferStates;
 
     ASSERT(count <= drawStates.size());
     std::copy(buffers, buffers + count, drawStates.begin());
     std::fill(drawStates.begin() + count, drawStates.end(), GL_NONE);
     mDirtyBits.set(DIRTY_BIT_DRAW_BUFFERS);
 
     mState.mEnabledDrawBuffers.reset();
+    mState.mDrawBufferTypeMask.reset();
+
     for (size_t index = 0; index < count; ++index)
     {
+        mState.mDrawBufferTypeMask.setIndex(getDrawbufferWriteType(index), index);
+
         if (drawStates[index] != GL_NONE && mState.mColorAttachments[index].isAttached())
         {
             mState.mEnabledDrawBuffers.set(index);
         }
     }
 }
 
 const FramebufferAttachment *Framebuffer::getDrawBuffer(size_t drawBuffer) const
@@ -781,16 +910,26 @@ GLenum Framebuffer::getDrawbufferWriteTy
         case GL_UNSIGNED_INT:
             return componentType;
 
         default:
             return GL_FLOAT;
     }
 }
 
+ComponentTypeMask Framebuffer::getDrawBufferTypeMask() const
+{
+    return mState.mDrawBufferTypeMask;
+}
+
+DrawBufferMask Framebuffer::getDrawBufferMask() const
+{
+    return mState.mEnabledDrawBuffers;
+}
+
 bool Framebuffer::hasEnabledDrawBuffer() const
 {
     for (size_t drawbufferIdx = 0; drawbufferIdx < mState.mDrawBufferStates.size(); ++drawbufferIdx)
     {
         if (getDrawBuffer(drawbufferIdx) != nullptr)
         {
             return true;
         }
@@ -874,17 +1013,17 @@ GLenum Framebuffer::checkStatusImpl(cons
 {
     const ContextState &state = context->getContextState();
 
     ASSERT(mId != 0);
 
     bool hasAttachments = false;
     Optional<unsigned int> colorbufferSize;
     Optional<int> samples;
-    Optional<GLboolean> fixedSampleLocations;
+    Optional<bool> fixedSampleLocations;
     bool hasRenderbuffer = false;
 
     const FramebufferAttachment *firstAttachment = getFirstNonNullAttachment();
 
     for (const FramebufferAttachment &colorAttachment : mState.mColorAttachments)
     {
         if (colorAttachment.isAttached())
         {
@@ -1051,125 +1190,258 @@ GLenum Framebuffer::checkStatusImpl(cons
 
     // ES3.1(section 9.4) requires that if the attached images are a mix of renderbuffers and
     // textures, the value of TEXTURE_FIXED_SAMPLE_LOCATIONS must be TRUE for all attached textures.
     if (fixedSampleLocations.valid() && hasRenderbuffer && !fixedSampleLocations.value())
     {
         return GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE;
     }
 
+    // The WebGL conformance tests implicitly define that all framebuffer
+    // attachments must be unique. For example, the same level of a texture can
+    // not be attached to two different color attachments.
+    if (state.getExtensions().webglCompatibility)
+    {
+        if (!mState.colorAttachmentsAreUniqueImages())
+        {
+            return GL_FRAMEBUFFER_UNSUPPORTED;
+        }
+    }
+
     syncState(context);
-    if (!mImpl->checkStatus())
+    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.
+
     return mImpl->discard(context, count, attachments);
 }
 
 Error Framebuffer::invalidate(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.
+
     return mImpl->invalidate(context, count, attachments);
 }
 
+bool Framebuffer::partialClearNeedsInit(const Context *context,
+                                        bool color,
+                                        bool depth,
+                                        bool stencil)
+{
+    const auto &glState = context->getGLState();
+
+    if (!glState.isRobustResourceInitEnabled())
+    {
+        return false;
+    }
+
+    // Scissors can affect clearing.
+    // TODO(jmadill): Check for complete scissor overlap.
+    if (glState.isScissorTestEnabled())
+    {
+        return true;
+    }
+
+    // If colors masked, we must clear before we clear. Do a simple check.
+    // TODO(jmadill): Filter out unused color channels from the test.
+    if (color)
+    {
+        const auto &blend = glState.getBlendState();
+        if (!(blend.colorMaskRed && blend.colorMaskGreen && blend.colorMaskBlue &&
+              blend.colorMaskAlpha))
+        {
+            return true;
+        }
+    }
+
+    const auto &depthStencil = glState.getDepthStencilState();
+    ASSERT(depthStencil.stencilBackMask == depthStencil.stencilMask);
+    if (stencil && depthStencil.stencilMask != depthStencil.stencilWritemask)
+    {
+        return true;
+    }
+
+    return false;
+}
+
 Error Framebuffer::invalidateSub(const Context *context,
                                  size_t count,
                                  const GLenum *attachments,
                                  const gl::Rectangle &area)
 {
+    // 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): Make a invalidate no-op in WebGL 2.0.
+
     return mImpl->invalidateSub(context, count, attachments, area);
 }
 
 Error Framebuffer::clear(const gl::Context *context, GLbitfield mask)
 {
-    if (context->getGLState().isRasterizerDiscardEnabled())
+    const auto &glState = context->getGLState();
+    if (glState.isRasterizerDiscardEnabled())
     {
         return NoError();
     }
 
-    return mImpl->clear(context, mask);
+    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 gl::Context *context,
                                  GLenum buffer,
                                  GLint drawbuffer,
                                  const GLfloat *values)
 {
-    if (context->getGLState().isRasterizerDiscardEnabled())
+    if (context->getGLState().isRasterizerDiscardEnabled() ||
+        IsClearBufferMaskedOut(context, buffer))
     {
         return NoError();
     }
 
-    return mImpl->clearBufferfv(context, buffer, drawbuffer, values);
+    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 gl::Context *context,
                                   GLenum buffer,
                                   GLint drawbuffer,
                                   const GLuint *values)
 {
-    if (context->getGLState().isRasterizerDiscardEnabled())
+    if (context->getGLState().isRasterizerDiscardEnabled() ||
+        IsClearBufferMaskedOut(context, buffer))
     {
         return NoError();
     }
 
-    return mImpl->clearBufferuiv(context, buffer, drawbuffer, values);
+    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 gl::Context *context,
                                  GLenum buffer,
                                  GLint drawbuffer,
                                  const GLint *values)
 {
-    if (context->getGLState().isRasterizerDiscardEnabled())
+    if (context->getGLState().isRasterizerDiscardEnabled() ||
+        IsClearBufferMaskedOut(context, buffer))
     {
         return NoError();
     }
 
-    return mImpl->clearBufferiv(context, buffer, drawbuffer, values);
+    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 gl::Context *context,
                                  GLenum buffer,
                                  GLint drawbuffer,
                                  GLfloat depth,
                                  GLint stencil)
 {
-    if (context->getGLState().isRasterizerDiscardEnabled())
+    if (context->getGLState().isRasterizerDiscardEnabled() ||
+        IsClearBufferMaskedOut(context, buffer))
     {
         return NoError();
     }
 
-    return mImpl->clearBufferfi(context, buffer, drawbuffer, depth, stencil);
+    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
 {
     return mImpl->getImplementationColorReadFormat(context);
 }
 
 GLenum Framebuffer::getImplementationColorReadType(const Context *context) const
 {
     return mImpl->getImplementationColorReadType(context);
 }
 
 Error Framebuffer::readPixels(const gl::Context *context,
                               const Rectangle &area,
                               GLenum format,
                               GLenum type,
-                              void *pixels) const
+                              void *pixels)
 {
+    ANGLE_TRY(ensureReadAttachmentInitialized(context, GL_COLOR_BUFFER_BIT));
     ANGLE_TRY(mImpl->readPixels(context, area, format, type, pixels));
 
-    Buffer *unpackBuffer = context->getGLState().getUnpackState().pixelBuffer.get();
+    Buffer *unpackBuffer = context->getGLState().getTargetBuffer(gl::BufferBinding::PixelUnpack);
     if (unpackBuffer)
     {
         unpackBuffer->onPixelUnpack();
     }
 
     return NoError();
 }
 
@@ -1198,16 +1470,22 @@ Error Framebuffer::blit(const gl::Contex
         blitMask &= ~GL_DEPTH_BUFFER_BIT;
     }
 
     if (!blitMask)
     {
         return NoError();
     }
 
+    auto *sourceFBO = context->getGLState().getReadFramebuffer();
+    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)
 {
     if (complete(context))
     {
         return getCachedSamples(context);
@@ -1435,17 +1713,17 @@ void Framebuffer::setAttachmentImpl(cons
             updateAttachment(context, &mState.mDepthAttachment, DIRTY_BIT_DEPTH_ATTACHMENT,
                              &mDirtyDepthAttachmentBinding, type, binding, textureIndex,
                              attachmentObj, numViews, baseViewIndex, multiviewLayout,
                              viewportOffsets);
             updateAttachment(context, &mState.mStencilAttachment, DIRTY_BIT_STENCIL_ATTACHMENT,
                              &mDirtyStencilAttachmentBinding, type, binding, textureIndex,
                              attachmentObj, numViews, baseViewIndex, multiviewLayout,
                              viewportOffsets);
-            return;
+            break;
         }
 
         case GL_DEPTH:
         case GL_DEPTH_ATTACHMENT:
             updateAttachment(context, &mState.mDepthAttachment, DIRTY_BIT_DEPTH_ATTACHMENT,
                              &mDirtyDepthAttachmentBinding, type, binding, textureIndex, resource,
                              numViews, baseViewIndex, multiviewLayout, viewportOffsets);
             break;
@@ -1474,19 +1752,22 @@ void Framebuffer::setAttachmentImpl(cons
                              &mDirtyColorAttachmentBindings[colorIndex], type, binding,
                              textureIndex, resource, numViews, baseViewIndex, multiviewLayout,
                              viewportOffsets);
 
             // TODO(jmadill): ASSERT instead of checking the attachment exists in
             // formsRenderingFeedbackLoopWith
             bool enabled = (type != GL_NONE && getDrawBufferState(colorIndex) != GL_NONE);
             mState.mEnabledDrawBuffers.set(colorIndex, enabled);
+            mState.mDrawBufferTypeMask.setIndex(getDrawbufferWriteType(colorIndex), colorIndex);
         }
         break;
     }
+
+    mAttachedTextures.reset();
 }
 
 void Framebuffer::updateAttachment(const Context *context,
                                    FramebufferAttachment *attachment,
                                    size_t dirtyBit,
                                    OnAttachmentDirtyBinding *onDirtyBinding,
                                    GLenum type,
                                    GLenum binding,
@@ -1495,16 +1776,17 @@ void Framebuffer::updateAttachment(const
                                    GLsizei numViews,
                                    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);
     BindResourceChannel(onDirtyBinding, resource);
 }
 
 void Framebuffer::resetAttachment(const Context *context, GLenum binding)
 {
     setAttachment(context, GL_NONE, binding, ImageIndex::MakeInvalid(), nullptr);
 }
 
@@ -1516,20 +1798,23 @@ void Framebuffer::syncState(const Contex
         mDirtyBits.reset();
         if (mId != 0)
         {
             mCachedStatus.reset();
         }
     }
 }
 
-void Framebuffer::signal(uint32_t token)
+void Framebuffer::signal(size_t dirtyBit, InitState state)
 {
     // TOOD(jmadill): Make this only update individual attachments to do less work.
     mCachedStatus.reset();
+
+    // Mark the appropriate init flag.
+    mState.mResourceNeedsInit.set(dirtyBit, state == InitState::MayNeedInit);
 }
 
 bool Framebuffer::complete(const Context *context)
 {
     return (checkStatus(context) == GL_FRAMEBUFFER_COMPLETE);
 }
 
 bool Framebuffer::cachedComplete() const
@@ -1631,17 +1916,17 @@ GLint Framebuffer::getDefaultHeight() co
     return mState.getDefaultHeight();
 }
 
 GLint Framebuffer::getDefaultSamples() const
 {
     return mState.getDefaultSamples();
 }
 
-GLboolean Framebuffer::getDefaultFixedSampleLocations() const
+bool Framebuffer::getDefaultFixedSampleLocations() const
 {
     return mState.getDefaultFixedSampleLocations();
 }
 
 void Framebuffer::setDefaultWidth(GLint defaultWidth)
 {
     mState.mDefaultWidth = defaultWidth;
     mDirtyBits.set(DIRTY_BIT_DEFAULT_WIDTH);
@@ -1654,17 +1939,17 @@ void Framebuffer::setDefaultHeight(GLint
 }
 
 void Framebuffer::setDefaultSamples(GLint defaultSamples)
 {
     mState.mDefaultSamples = defaultSamples;
     mDirtyBits.set(DIRTY_BIT_DEFAULT_SAMPLES);
 }
 
-void Framebuffer::setDefaultFixedSampleLocations(GLboolean defaultFixedSampleLocations)
+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)
 {
@@ -1691,9 +1976,276 @@ const std::vector<Offset> *Framebuffer::
     return mState.getViewportOffsets();
 }
 
 GLenum Framebuffer::getMultiviewLayout() const
 {
     return mState.getMultiviewLayout();
 }
 
+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.
+    for (size_t bit : mState.mResourceNeedsInit)
+    {
+        switch (bit)
+        {
+            case DIRTY_BIT_DEPTH_ATTACHMENT:
+                ANGLE_TRY(InitAttachment(context, &mState.mDepthAttachment));
+                break;
+            case DIRTY_BIT_STENCIL_ATTACHMENT:
+                ANGLE_TRY(InitAttachment(context, &mState.mStencilAttachment));
+                break;
+            default:
+                ANGLE_TRY(InitAttachment(context, &mState.mColorAttachments[bit]));
+                break;
+        }
+    }
+
+    mState.mResourceNeedsInit.reset();
+    return NoError();
+}
+
+Error Framebuffer::ensureReadAttachmentInitialized(const Context *context, GLbitfield blitMask)
+{
+    if (!context->isRobustResourceInitEnabled() || mState.mResourceNeedsInit.none())
+    {
+        return NoError();
+    }
+
+    if ((blitMask & GL_COLOR_BUFFER_BIT) != 0 && mState.mReadBufferState != GL_NONE)
+    {
+        size_t readIndex = mState.getReadIndex();
+        if (mState.mResourceNeedsInit[readIndex])
+        {
+            ANGLE_TRY(InitAttachment(context, &mState.mColorAttachments[readIndex]));
+            mState.mResourceNeedsInit.reset(readIndex);
+        }
+    }
+
+    if ((blitMask & GL_DEPTH_BUFFER_BIT) != 0 && hasDepth())
+    {
+        if (mState.mResourceNeedsInit[DIRTY_BIT_DEPTH_ATTACHMENT])
+        {
+            ANGLE_TRY(InitAttachment(context, &mState.mDepthAttachment));
+            mState.mResourceNeedsInit.reset(DIRTY_BIT_DEPTH_ATTACHMENT);
+        }
+    }
+
+    if ((blitMask & GL_STENCIL_BUFFER_BIT) != 0 && hasStencil())
+    {
+        if (mState.mResourceNeedsInit[DIRTY_BIT_STENCIL_ATTACHMENT])
+        {
+            ANGLE_TRY(InitAttachment(context, &mState.mStencilAttachment));
+            mState.mResourceNeedsInit.reset(DIRTY_BIT_STENCIL_ATTACHMENT);
+        }
+    }
+
+    return NoError();
+}
+
+void Framebuffer::markDrawAttachmentsInitialized(bool color, bool depth, bool stencil)
+{
+    // Mark attachments as initialized.
+    if (color)
+    {
+        for (auto colorIndex : mState.mEnabledDrawBuffers)
+        {
+            auto &colorAttachment = mState.mColorAttachments[colorIndex];
+            ASSERT(colorAttachment.isAttached());
+            colorAttachment.setInitState(InitState::Initialized);
+            mState.mResourceNeedsInit.reset(colorIndex);
+        }
+    }
+
+    if (depth && mState.mDepthAttachment.isAttached())
+    {
+        mState.mDepthAttachment.setInitState(InitState::Initialized);
+        mState.mResourceNeedsInit.reset(DIRTY_BIT_DEPTH_ATTACHMENT);
+    }
+
+    if (stencil && mState.mStencilAttachment.isAttached())
+    {
+        mState.mStencilAttachment.setInitState(InitState::Initialized);
+        mState.mResourceNeedsInit.reset(DIRTY_BIT_STENCIL_ATTACHMENT);
+    }
+}
+
+void Framebuffer::markBufferInitialized(GLenum bufferType, GLint bufferIndex)
+{
+    switch (bufferType)
+    {
+        case GL_COLOR:
+        {
+            ASSERT(bufferIndex < static_cast<GLint>(mState.mColorAttachments.size()));
+            if (mState.mColorAttachments[bufferIndex].isAttached())
+            {
+                mState.mColorAttachments[bufferIndex].setInitState(InitState::Initialized);
+                mState.mResourceNeedsInit.reset(bufferIndex);
+            }
+            break;
+        }
+        case GL_DEPTH:
+        {
+            if (mState.mDepthAttachment.isAttached())
+            {
+                mState.mDepthAttachment.setInitState(InitState::Initialized);
+                mState.mResourceNeedsInit.reset(DIRTY_BIT_DEPTH_ATTACHMENT);
+            }
+            break;
+        }
+        case GL_STENCIL:
+        {
+            if (mState.mStencilAttachment.isAttached())
+            {
+                mState.mStencilAttachment.setInitState(InitState::Initialized);
+                mState.mResourceNeedsInit.reset(DIRTY_BIT_STENCIL_ATTACHMENT);
+            }
+            break;
+        }
+        case GL_DEPTH_STENCIL:
+        {
+            if (mState.mDepthAttachment.isAttached())
+            {
+                mState.mDepthAttachment.setInitState(InitState::Initialized);
+                mState.mResourceNeedsInit.reset(DIRTY_BIT_DEPTH_ATTACHMENT);
+            }
+            if (mState.mStencilAttachment.isAttached())
+            {
+                mState.mStencilAttachment.setInitState(InitState::Initialized);
+                mState.mResourceNeedsInit.reset(DIRTY_BIT_STENCIL_ATTACHMENT);
+            }
+            break;
+        }
+        default:
+            UNREACHABLE();
+            break;
+    }
+}
+
+Box Framebuffer::getDimensions() const
+{
+    return mState.getDimensions();
+}
+
+Error Framebuffer::ensureBufferInitialized(const Context *context,
+                                           GLenum bufferType,
+                                           GLint bufferIndex)
+{
+    ASSERT(context->isRobustResourceInitEnabled());
+
+    if (mState.mResourceNeedsInit.none())
+    {
+        return NoError();
+    }
+
+    switch (bufferType)
+    {
+        case GL_COLOR:
+        {
+            ASSERT(bufferIndex < static_cast<GLint>(mState.mColorAttachments.size()));
+            if (mState.mResourceNeedsInit[bufferIndex])
+            {
+                ANGLE_TRY(InitAttachment(context, &mState.mColorAttachments[bufferIndex]));
+                mState.mResourceNeedsInit.reset(bufferIndex);
+            }
+            break;
+        }
+        case GL_DEPTH:
+        {
+            if (mState.mResourceNeedsInit[DIRTY_BIT_DEPTH_ATTACHMENT])
+            {
+                ANGLE_TRY(InitAttachment(context, &mState.mDepthAttachment));
+                mState.mResourceNeedsInit.reset(DIRTY_BIT_DEPTH_ATTACHMENT);
+            }
+            break;
+        }
+        case GL_STENCIL:
+        {
+            if (mState.mResourceNeedsInit[DIRTY_BIT_STENCIL_ATTACHMENT])
+            {
+                ANGLE_TRY(InitAttachment(context, &mState.mStencilAttachment));
+                mState.mResourceNeedsInit.reset(DIRTY_BIT_STENCIL_ATTACHMENT);
+            }
+            break;
+        }
+        case GL_DEPTH_STENCIL:
+        {
+            if (mState.mResourceNeedsInit[DIRTY_BIT_DEPTH_ATTACHMENT])
+            {
+                ANGLE_TRY(InitAttachment(context, &mState.mDepthAttachment));
+                mState.mResourceNeedsInit.reset(DIRTY_BIT_DEPTH_ATTACHMENT);
+            }
+            if (mState.mResourceNeedsInit[DIRTY_BIT_STENCIL_ATTACHMENT])
+            {
+                ANGLE_TRY(InitAttachment(context, &mState.mStencilAttachment));
+                mState.mResourceNeedsInit.reset(DIRTY_BIT_STENCIL_ATTACHMENT);
+            }
+            break;
+        }
+        default:
+            UNREACHABLE();
+            break;
+    }
+
+    return NoError();
+}
+
+bool Framebuffer::partialBufferClearNeedsInit(const Context *context, GLenum bufferType)
+{
+    if (!context->isRobustResourceInitEnabled() || mState.mResourceNeedsInit.none())
+    {
+        return false;
+    }
+
+    switch (bufferType)
+    {
+        case GL_COLOR:
+            return partialClearNeedsInit(context, true, false, false);
+        case GL_DEPTH:
+            return partialClearNeedsInit(context, false, true, false);
+        case GL_STENCIL:
+            return partialClearNeedsInit(context, false, false, true);
+        case GL_DEPTH_STENCIL:
+            return partialClearNeedsInit(context, false, true, true);
+        default:
+            UNREACHABLE();
+            return false;
+    }
+}
+
+bool Framebuffer::hasTextureAttachment(const Texture *texture) const
+{
+    if (!mAttachedTextures.valid())
+    {
+        std::set<const FramebufferAttachmentObject *> attachedTextures;
+
+        for (const auto &colorAttachment : mState.mColorAttachments)
+        {
+            if (colorAttachment.isAttached() && colorAttachment.type() == GL_TEXTURE)
+            {
+                attachedTextures.insert(colorAttachment.getResource());
+            }
+        }
+
+        if (mState.mDepthAttachment.isAttached() && mState.mDepthAttachment.type() == GL_TEXTURE)
+        {
+            attachedTextures.insert(mState.mDepthAttachment.getResource());
+        }
+
+        if (mState.mStencilAttachment.isAttached() &&
+            mState.mStencilAttachment.type() == GL_TEXTURE)
+        {
+            attachedTextures.insert(mState.mStencilAttachment.getResource());
+        }
+
+        mAttachedTextures = std::move(attachedTextures);
+    }
+
+    return (mAttachedTextures.value().count(texture) > 0);
+}
+
 }  // namespace gl
--- a/gfx/angle/src/libANGLE/Framebuffer.h
+++ b/gfx/angle/src/libANGLE/Framebuffer.h
@@ -53,18 +53,19 @@ struct Rectangle;
 class FramebufferState final : angle::NonCopyable
 {
   public:
     FramebufferState();
     explicit FramebufferState(const Caps &caps);
     ~FramebufferState();
 
     const std::string &getLabel();
+    size_t getReadIndex() const;
 
-    const FramebufferAttachment *getAttachment(GLenum attachment) const;
+    const FramebufferAttachment *getAttachment(const Context *context, GLenum attachment) const;
     const FramebufferAttachment *getReadAttachment() const;
     const FramebufferAttachment *getFirstNonNullAttachment() const;
     const FramebufferAttachment *getFirstColorAttachment() const;
     const FramebufferAttachment *getDepthOrStencilAttachment() const;
     const FramebufferAttachment *getStencilOrDepthStencilAttachment() const;
     const FramebufferAttachment *getColorAttachment(size_t colorAttachment) const;
     const FramebufferAttachment *getDepthAttachment() const;
     const FramebufferAttachment *getStencilAttachment() const;
@@ -75,70 +76,79 @@ class FramebufferState final : angle::No
     GLenum getReadBufferState() const { return mReadBufferState; }
     const std::vector<FramebufferAttachment> &getColorAttachments() const
     {
         return mColorAttachments;
     }
 
     bool attachmentsHaveSameDimensions() const;
     bool colorAttachmentsAreUniqueImages() const;
+    Box getDimensions() const;
 
     const FramebufferAttachment *getDrawBuffer(size_t drawBufferIdx) const;
     size_t getDrawBufferCount() const;
 
     GLint getDefaultWidth() const { return mDefaultWidth; };
     GLint getDefaultHeight() const { return mDefaultHeight; };
     GLint getDefaultSamples() const { return mDefaultSamples; };
-    GLboolean getDefaultFixedSampleLocations() const { return mDefaultFixedSampleLocations; };
+    bool getDefaultFixedSampleLocations() const { return mDefaultFixedSampleLocations; };
 
     bool hasDepth() const;
     bool hasStencil() const;
 
     GLenum getMultiviewLayout() const;
     GLsizei getNumViews() const;
     const std::vector<Offset> *getViewportOffsets() const;
     GLint getBaseViewIndex() const;
 
   private:
+    const FramebufferAttachment *getWebGLDepthStencilAttachment() const;
+    const FramebufferAttachment *getWebGLDepthAttachment() const;
+    const FramebufferAttachment *getWebGLStencilAttachment() const;
+
     friend class Framebuffer;
 
     std::string mLabel;
 
     std::vector<FramebufferAttachment> mColorAttachments;
     FramebufferAttachment mDepthAttachment;
     FramebufferAttachment mStencilAttachment;
 
     std::vector<GLenum> mDrawBufferStates;
     GLenum mReadBufferState;
     DrawBufferMask mEnabledDrawBuffers;
+    ComponentTypeMask mDrawBufferTypeMask;
 
     GLint mDefaultWidth;
     GLint mDefaultHeight;
     GLint mDefaultSamples;
-    GLboolean mDefaultFixedSampleLocations;
+    bool mDefaultFixedSampleLocations;
 
     // It's necessary to store all this extra state so we can restore attachments
     // when DEPTH_STENCIL/DEPTH/STENCIL is unbound in WebGL 1.
     FramebufferAttachment mWebGLDepthStencilAttachment;
     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 OnAttachmentDirtyReceiver
 {
   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);
 
-    virtual ~Framebuffer();
+    ~Framebuffer() override;
     void onDestroy(const Context *context);
     void destroyDefault(const egl::Display *display);
 
     void setLabel(const std::string &label) override;
     const std::string &getLabel() const override;
 
     rx::FramebufferImpl *getImplementation() const { return mImpl; }
 
@@ -174,28 +184,30 @@ class Framebuffer final : public Labeled
     const FramebufferAttachment *getDepthStencilBuffer() const;
     const FramebufferAttachment *getDepthOrStencilbuffer() const;
     const FramebufferAttachment *getStencilOrDepthStencilAttachment() const;
     const FramebufferAttachment *getReadColorbuffer() const;
     GLenum getReadColorbufferType() const;
     const FramebufferAttachment *getFirstColorbuffer() const;
     const FramebufferAttachment *getFirstNonNullAttachment() const;
 
-    const FramebufferAttachment *getAttachment(GLenum attachment) const;
+    const FramebufferAttachment *getAttachment(const Context *context, GLenum attachment) const;
     GLenum getMultiviewLayout() const;
     GLsizei getNumViews() const;
     GLint getBaseViewIndex() const;
     const std::vector<Offset> *getViewportOffsets() const;
 
     size_t getDrawbufferStateCount() const;
     GLenum getDrawBufferState(size_t drawBuffer) const;
     const std::vector<GLenum> &getDrawBufferStates() const;
     void setDrawBuffers(size_t count, const GLenum *buffers);
     const FramebufferAttachment *getDrawBuffer(size_t drawBuffer) const;
     GLenum getDrawbufferWriteType(size_t drawBuffer) const;
+    ComponentTypeMask getDrawBufferTypeMask() const;
+    DrawBufferMask getDrawBufferMask() const;
     bool hasEnabledDrawBuffer() const;
 
     GLenum getReadBufferState() const;
     void setReadBuffer(GLenum buffer);
 
     size_t getNumColorBuffers() const;
     bool hasDepth() const;
     bool hasStencil() const;
@@ -205,21 +217,21 @@ class Framebuffer final : public Labeled
     // This method calls checkStatus.
     int getSamples(const Context *context);
 
     Error getSamplePosition(size_t index, GLfloat *xy) const;
 
     GLint getDefaultWidth() const;
     GLint getDefaultHeight() const;
     GLint getDefaultSamples() const;
-    GLboolean getDefaultFixedSampleLocations() const;
+    bool getDefaultFixedSampleLocations() const;
     void setDefaultWidth(GLint defaultWidth);
     void setDefaultHeight(GLint defaultHeight);
     void setDefaultSamples(GLint defaultSamples);
-    void setDefaultFixedSampleLocations(GLboolean defaultFixedSampleLocations);
+    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);
@@ -260,54 +272,60 @@ class Framebuffer final : public Labeled
                         GLint stencil);
 
     GLenum getImplementationColorReadFormat(const Context *context) const;
     GLenum getImplementationColorReadType(const Context *context) const;
     Error readPixels(const gl::Context *context,
                      const gl::Rectangle &area,
                      GLenum format,
                      GLenum type,
-                     void *pixels) const;
+                     void *pixels);
 
     Error blit(const gl::Context *context,
                const Rectangle &sourceArea,
                const Rectangle &destArea,
                GLbitfield mask,
                GLenum filter);
 
-    enum DirtyBitType : uint32_t
+    enum DirtyBitType : size_t
     {
         DIRTY_BIT_COLOR_ATTACHMENT_0,
         DIRTY_BIT_COLOR_ATTACHMENT_MAX =
             DIRTY_BIT_COLOR_ATTACHMENT_0 + gl::IMPLEMENTATION_MAX_FRAMEBUFFER_ATTACHMENTS,
         DIRTY_BIT_DEPTH_ATTACHMENT = DIRTY_BIT_COLOR_ATTACHMENT_MAX,
         DIRTY_BIT_STENCIL_ATTACHMENT,
         DIRTY_BIT_DRAW_BUFFERS,
         DIRTY_BIT_READ_BUFFER,
         DIRTY_BIT_DEFAULT_WIDTH,
         DIRTY_BIT_DEFAULT_HEIGHT,
         DIRTY_BIT_DEFAULT_SAMPLES,
         DIRTY_BIT_DEFAULT_FIXED_SAMPLE_LOCATIONS,
         DIRTY_BIT_UNKNOWN,
         DIRTY_BIT_MAX = DIRTY_BIT_UNKNOWN
     };
 
-    typedef angle::BitSet<DIRTY_BIT_MAX> DirtyBits;
+    using DirtyBits = angle::BitSet<DIRTY_BIT_MAX>;
     bool hasAnyDirtyBit() const { return mDirtyBits.any(); }
 
     void syncState(const Context *context);
 
-    // angle::SignalReceiver implementation
-    void signal(uint32_t token) override;
+    // OnAttachmentChangedReceiver implementation
+    void signal(size_t dirtyBit, InitState state) override;
 
     bool formsRenderingFeedbackLoopWith(const State &state) const;
     bool formsCopyingFeedbackLoopWith(GLuint copyTextureID,
                                       GLint copyTextureLevel,
                                       GLint copyTextureLayer) const;
 
+    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);
@@ -342,23 +360,37 @@ class Framebuffer final : public Labeled
                           GLenum binding,
                           const ImageIndex &textureIndex,
                           FramebufferAttachmentObject *resource,
                           GLsizei numViews,
                           GLuint baseViewIndex,
                           GLenum multiviewLayout,
                           const GLint *viewportOffsets);
 
+    void markDrawAttachmentsInitialized(bool color, bool depth, bool stencil);
+    void markBufferInitialized(GLenum bufferType, GLint bufferIndex);
+    Error ensureBufferInitialized(const Context *context, GLenum bufferType, GLint bufferIndex);
+
+    // Checks that we have a partially masked clear:
+    // * some color channels are masked out
+    // * some stencil values are masked out
+    // * scissor test partially overlaps the framebuffer
+    bool partialClearNeedsInit(const Context *context, bool color, bool depth, bool stencil);
+    bool partialBufferClearNeedsInit(const Context *context, GLenum bufferType);
+
     FramebufferState mState;
     rx::FramebufferImpl *mImpl;
     GLuint mId;
 
     Optional<GLenum> mCachedStatus;
     std::vector<OnAttachmentDirtyBinding> mDirtyColorAttachmentBindings;
     OnAttachmentDirtyBinding mDirtyDepthAttachmentBinding;
     OnAttachmentDirtyBinding mDirtyStencilAttachmentBinding;
 
     DirtyBits mDirtyBits;
+
+    // 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/src/libANGLE/FramebufferAttachment.cpp
+++ b/gfx/angle/src/libANGLE/FramebufferAttachment.cpp
@@ -6,22 +6,23 @@
 
 // FramebufferAttachment.cpp: the gl::FramebufferAttachment class and its derived classes
 // objects and related functionality. [OpenGL ES 2.0.24] section 4.4.3 page 108.
 
 #include "libANGLE/FramebufferAttachment.h"
 
 #include "common/utilities.h"
 #include "libANGLE/Config.h"
+#include "libANGLE/Context.h"
 #include "libANGLE/Renderbuffer.h"
 #include "libANGLE/Surface.h"
 #include "libANGLE/Texture.h"
 #include "libANGLE/formatutils.h"
+#include "libANGLE/renderer/FramebufferAttachmentObjectImpl.h"
 #include "libANGLE/renderer/FramebufferImpl.h"
-#include "libANGLE/renderer/FramebufferAttachmentObjectImpl.h"
 
 namespace gl
 {
 
 namespace
 {
 
 std::vector<Offset> TransformViewportOffsetArrayToVectorOfOffsets(const GLint *viewportOffsets,
@@ -314,23 +315,71 @@ bool FramebufferAttachment::operator==(c
     return true;
 }
 
 bool FramebufferAttachment::operator!=(const FramebufferAttachment &other) const
 {
     return !(*this == other);
 }
 
+InitState FramebufferAttachment::initState() const
+{
+    return mResource ? mResource->initState(mTarget.textureIndex()) : InitState::Initialized;
+}
+
+Error FramebufferAttachment::initializeContents(const Context *context)
+{
+    ASSERT(mResource);
+    ANGLE_TRY(mResource->initializeContents(context, mTarget.textureIndex()));
+    setInitState(InitState::Initialized);
+    return NoError();
+}
+
+void FramebufferAttachment::setInitState(InitState initState) const
+{
+    ASSERT(mResource);
+    mResource->setInitState(mTarget.textureIndex(), initState);
+}
+
+////// FramebufferAttachmentObject Implementation //////
+
+FramebufferAttachmentObject::FramebufferAttachmentObject()
+{
+}
+
+FramebufferAttachmentObject::~FramebufferAttachmentObject()
+{
+}
+
 Error FramebufferAttachmentObject::getAttachmentRenderTarget(
     const Context *context,
     GLenum binding,
     const ImageIndex &imageIndex,
     rx::FramebufferAttachmentRenderTarget **rtOut) const
 {
     return getAttachmentImpl()->getAttachmentRenderTarget(context, binding, imageIndex, rtOut);
 }
 
 OnAttachmentDirtyChannel *FramebufferAttachmentObject::getDirtyChannel()
 {
     return &mDirtyChannel;
 }
 
+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())
+    {
+        ImageIndex fullMipIndex = imageIndex;
+        fullMipIndex.layerIndex = ImageIndex::ENTIRE_LEVEL;
+        return getAttachmentImpl()->initializeContents(context, fullMipIndex);
+    }
+    else
+    {
+        return getAttachmentImpl()->initializeContents(context, imageIndex);
+    }
+}
+
 }  // namespace gl
--- a/gfx/angle/src/libANGLE/FramebufferAttachment.h
+++ b/gfx/angle/src/libANGLE/FramebufferAttachment.h
@@ -38,19 +38,25 @@ class FramebufferAttachmentObjectImpl;
 
 namespace gl
 {
 class FramebufferAttachmentObject;
 struct Format;
 class Renderbuffer;
 class Texture;
 
-using OnAttachmentDirtyBinding  = angle::ChannelBinding<>;
-using OnAttachmentDirtyChannel  = angle::BroadcastChannel<>;
-using OnAttachmentDirtyReceiver = angle::SignalReceiver<>;
+enum class InitState
+{
+    MayNeedInit,
+    Initialized,
+};
+
+using OnAttachmentDirtyBinding  = angle::ChannelBinding<size_t, InitState>;
+using OnAttachmentDirtyChannel  = angle::BroadcastChannel<size_t, InitState>;
+using OnAttachmentDirtyReceiver = angle::SignalReceiver<size_t, InitState>;
 
 // FramebufferAttachment implements a GL framebuffer attachment.
 // Attachments are "light" containers, which store pointers to ref-counted GL objects.
 // We support GL texture (2D/3D/Cube/2D array) and renderbuffer object attachments.
 // Note: Our old naming scheme used the term "Renderbuffer" for both GL renderbuffers and for
 // framebuffer attachments, which confused their usage.
 
 class FramebufferAttachment final
@@ -114,16 +120,19 @@ class FramebufferAttachment final
     GLsizei getSamples() const;
     GLenum type() const { return mType; }
     bool isAttached() const { return mType != GL_NONE; }
 
     Renderbuffer *getRenderbuffer() const;
     Texture *getTexture() const;
     const egl::Surface *getSurface() const;
     FramebufferAttachmentObject *getResource() const;
+    InitState initState() const;
+    Error initializeContents(const Context *context);
+    void setInitState(InitState initState) const;
 
     // "T" must be static_castable from FramebufferAttachmentRenderTarget
     template <typename T>
     gl::Error getRenderTarget(const Context *context, T **rtOut) const
     {
         static_assert(std::is_base_of<rx::FramebufferAttachmentRenderTarget, T>(),
                       "Invalid RenderTarget class.");
         return getRenderTargetImpl(
@@ -173,33 +182,39 @@ class FramebufferAttachment final
     GLint mBaseViewIndex;
     std::vector<Offset> mViewportOffsets;
 };
 
 // A base class for objects that FBO Attachments may point to.
 class FramebufferAttachmentObject
 {
   public:
-    FramebufferAttachmentObject() {}
-    virtual ~FramebufferAttachmentObject() {}
+    FramebufferAttachmentObject();
+    virtual ~FramebufferAttachmentObject();
 
     virtual Extents getAttachmentSize(const ImageIndex &imageIndex) const = 0;
     virtual const Format &getAttachmentFormat(GLenum binding,
                                               const ImageIndex &imageIndex) const = 0;
     virtual GLsizei getAttachmentSamples(const ImageIndex &imageIndex) const      = 0;
 
     virtual void onAttach(const Context *context) = 0;
     virtual void onDetach(const Context *context) = 0;
     virtual GLuint getId() const = 0;
 
+    // These are used for robust resource initialization.
+    virtual InitState initState(const ImageIndex &imageIndex) const = 0;
+    virtual void setInitState(const ImageIndex &imageIndex, InitState initState) = 0;
+
     Error getAttachmentRenderTarget(const Context *context,
                                     GLenum binding,
                                     const ImageIndex &imageIndex,
                                     rx::FramebufferAttachmentRenderTarget **rtOut) const;
 
+    Error initializeContents(const Context *context, const ImageIndex &imageIndex);
+
     OnAttachmentDirtyChannel *getDirtyChannel();
 
   protected:
     virtual rx::FramebufferAttachmentObjectImpl *getAttachmentImpl() const = 0;
 
     OnAttachmentDirtyChannel mDirtyChannel;
 };
 
--- a/gfx/angle/src/libANGLE/HandleAllocator.cpp
+++ b/gfx/angle/src/libANGLE/HandleAllocator.cpp
@@ -5,31 +5,32 @@
 //
 
 // HandleAllocator.cpp: Implements the gl::HandleAllocator class, which is used
 // to allocate GL handles.
 
 #include "libANGLE/HandleAllocator.h"
 
 #include <algorithm>
+#include <functional>
 
 #include "common/debug.h"
 
 namespace gl
 {
 
 struct HandleAllocator::HandleRangeComparator
 {
     bool operator()(const HandleRange &range, GLuint handle) const
     {
         return (range.end < handle);
     }
 };
 
-HandleAllocator::HandleAllocator() : mBaseValue(1), mNextValue(1)
+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)
 {
     mUnallocatedList.push_back(HandleRange(1, maximumHandleValue));
 }
@@ -47,19 +48,25 @@ void HandleAllocator::setBaseHandle(GLui
 
 GLuint HandleAllocator::allocate()
 {
     ASSERT(!mUnallocatedList.empty() || !mReleasedList.empty());
 
     // Allocate from released list, logarithmic time for pop_heap.
     if (!mReleasedList.empty())
     {
-        std::pop_heap(mReleasedList.begin(), mReleasedList.end());
+        std::pop_heap(mReleasedList.begin(), mReleasedList.end(), std::greater<GLuint>());
         GLuint reusedHandle = mReleasedList.back();
         mReleasedList.pop_back();
+
+        if (mLoggingEnabled)
+        {
+            WARN() << "HandleAllocator::allocate reusing " << reusedHandle << std::endl;
+        }
+
         return reusedHandle;
     }
 
     // Allocate from unallocated list, constant time.
     auto listIt = mUnallocatedList.begin();
 
     GLuint freeListHandle = listIt->begin;
     ASSERT(freeListHandle > 0);
@@ -68,28 +75,43 @@ GLuint HandleAllocator::allocate()
     {
         mUnallocatedList.erase(listIt);
     }
     else
     {
         listIt->begin++;
     }
 
+    if (mLoggingEnabled)
+    {
+        WARN() << "HandleAllocator::allocate allocating " << freeListHandle << std::endl;
+    }
+
     return freeListHandle;
 }
 
 void HandleAllocator::release(GLuint handle)
 {
+    if (mLoggingEnabled)
+    {
+        WARN() << "HandleAllocator::release releasing " << handle << std::endl;
+    }
+
     // Add to released list, logarithmic time for push_heap.
     mReleasedList.push_back(handle);
-    std::push_heap(mReleasedList.begin(), mReleasedList.end());
+    std::push_heap(mReleasedList.begin(), mReleasedList.end(), std::greater<GLuint>());
 }
 
 void HandleAllocator::reserve(GLuint handle)
 {
+    if (mLoggingEnabled)
+    {
+        WARN() << "HandleAllocator::reserve reserving " << handle << std::endl;
+    }
+
     // Clear from released list -- might be a slow operation.
     if (!mReleasedList.empty())
     {
         auto releasedIt = std::find(mReleasedList.begin(), mReleasedList.end(), handle);
         if (releasedIt != mReleasedList.end())
         {
             mReleasedList.erase(releasedIt);
             return;
@@ -134,9 +156,14 @@ void HandleAllocator::reset()
 {
     mUnallocatedList.clear();
     mUnallocatedList.push_back(HandleRange(1, std::numeric_limits<GLuint>::max()));
     mReleasedList.clear();
     mBaseValue = 1;
     mNextValue = 1;
 }
 
+void HandleAllocator::enableLogging(bool enabled)
+{
+    mLoggingEnabled = enabled;
+}
+
 }  // namespace gl
--- a/gfx/angle/src/libANGLE/HandleAllocator.h
+++ b/gfx/angle/src/libANGLE/HandleAllocator.h
@@ -29,16 +29,18 @@ class HandleAllocator final : angle::Non
 
     void setBaseHandle(GLuint value);
 
     GLuint allocate();
     void release(GLuint handle);
     void reserve(GLuint handle);
     void reset();
 
+    void enableLogging(bool enabled);
+
   private:
     GLuint mBaseValue;
     GLuint mNextValue;
     typedef std::vector<GLuint> HandleList;
     HandleList mFreeValues;
 
     // Represents an inclusive range [begin, end]
     struct HandleRange
@@ -51,13 +53,15 @@ class HandleAllocator final : angle::Non
 
     struct HandleRangeComparator;
 
     // The freelist consists of never-allocated handles, stored
     // as ranges, and handles that were previously allocated and
     // released, stored in a heap.
     std::vector<HandleRange> mUnallocatedList;
     std::vector<GLuint> mReleasedList;
+
+    bool mLoggingEnabled;
 };
 
 }  // namespace gl
 
 #endif   // LIBANGLE_HANDLEALLOCATOR_H_
--- a/gfx/angle/src/libANGLE/HandleAllocator_unittest.cpp
+++ b/gfx/angle/src/libANGLE/HandleAllocator_unittest.cpp
@@ -145,9 +145,29 @@ TEST(HandleAllocatorTest, Reset)
         allocator.reserve(3);
         EXPECT_EQ(1u, allocator.allocate());
         EXPECT_EQ(2u, allocator.allocate());
         EXPECT_EQ(4u, allocator.allocate());
         allocator.reset();
     }
 }
 
+// Covers a particular bug with reserving and allocating sub ranges.
+TEST(HandleAllocatorTest, ReserveAndAllocateIterated)
+{
+    gl::HandleAllocator allocator;
+
+    for (int iteration = 0; iteration < 3; ++iteration)
+    {
+        allocator.reserve(5);
+        allocator.reserve(6);
+        GLuint a = allocator.allocate();
+        GLuint b = allocator.allocate();
+        GLuint c = allocator.allocate();
+        allocator.release(c);
+        allocator.release(a);
+        allocator.release(b);
+        allocator.release(5);
+        allocator.release(6);
+    }
+}
+
 }  // anonymous namespace
--- a/gfx/angle/src/libANGLE/HandleRangeAllocator.cpp
+++ b/gfx/angle/src/libANGLE/HandleRangeAllocator.cpp
@@ -22,16 +22,20 @@ const GLuint HandleRangeAllocator::kInva
 
 HandleRangeAllocator::HandleRangeAllocator()
 {
     // Simplify the code by making sure that lower_bound(id) never
     // returns the beginning of the map, if id is valid (eg != kInvalidHandle).
     mUsed.insert(std::make_pair(0u, 0u));
 }
 
+HandleRangeAllocator::~HandleRangeAllocator()
+{
+}
+
 GLuint HandleRangeAllocator::allocate()
 {
     return allocateRange(1u);
 }
 
 GLuint HandleRangeAllocator::allocateAtOrAbove(GLuint wanted)
 {
     if (wanted == 0u || wanted == 1u)
--- a/gfx/angle/src/libANGLE/HandleRangeAllocator.h
+++ b/gfx/angle/src/libANGLE/HandleRangeAllocator.h
@@ -20,16 +20,17 @@ namespace gl
 
 // Allocates contiguous ranges of path object handles.
 class HandleRangeAllocator final : angle::NonCopyable
 {
   public:
     static const GLuint kInvalidHandle;
 
     HandleRangeAllocator();
+    ~HandleRangeAllocator();
 
     // Allocates a new path handle.
     GLuint allocate();
 
     // Allocates a handle starting at or above the value of |wanted|.
     // Note: may wrap if it starts near limit.
     GLuint allocateAtOrAbove(GLuint wanted);
 
--- a/gfx/angle/src/libANGLE/Image.cpp
+++ b/gfx/angle/src/libANGLE/Image.cpp
@@ -40,17 +40,18 @@ gl::ImageIndex GetImageIndex(EGLenum egl
     else
     {
         ASSERT(layer == 0);
         return gl::ImageIndex::MakeGeneric(target, mip);
     }
 }
 }  // anonymous namespace
 
-ImageSibling::ImageSibling(GLuint id) : RefCountObject(id), mSourcesOf(), mTargetOf()
+ImageSibling::ImageSibling(GLuint id)
+    : RefCountObject(id), FramebufferAttachmentObject(), mSourcesOf(), mTargetOf()
 {
 }
 
 ImageSibling::~ImageSibling()
 {
     // EGL images should hold a ref to their targets and siblings, a Texture should not be deletable
     // while it is attached to an EGL image.
     // Child class should orphan images before destruction.
@@ -72,17 +73,17 @@ gl::Error ImageSibling::orphanImages(con
         // Can't be a target and have sources.
         ASSERT(mSourcesOf.empty());
 
         ANGLE_TRY(mTargetOf->orphanSibling(context, this));
         mTargetOf.set(context, nullptr);
     }
     else
     {
-        for (auto &sourceImage : mSourcesOf)
+        for (egl::Image *sourceImage : mSourcesOf)
         {
             ANGLE_TRY(sourceImage->orphanSibling(context, this));
         }
         mSourcesOf.clear();
     }
 
     return gl::NoError();
 }
@@ -94,28 +95,50 @@ void ImageSibling::addImageSource(egl::I
 }
 
 void ImageSibling::removeImageSource(egl::Image *imageSource)
 {
     ASSERT(mSourcesOf.find(imageSource) != mSourcesOf.end());
     mSourcesOf.erase(imageSource);
 }
 
+bool ImageSibling::isEGLImageTarget() const
+{
+    return (mTargetOf.get() != nullptr);
+}
+
+gl::InitState ImageSibling::sourceEGLImageInitState() const
+{
+    ASSERT(isEGLImageTarget());
+    return mTargetOf->sourceInitState();
+}
+
+void ImageSibling::setSourceEGLImageInitState(gl::InitState initState) const
+{
+    ASSERT(isEGLImageTarget());
+    mTargetOf->setInitState(initState);
+}
+
 ImageState::ImageState(EGLenum target, ImageSibling *buffer, const AttributeMap &attribs)
     : imageIndex(GetImageIndex(target, attribs)), source(buffer), targets()
 {
 }
 
+ImageState::~ImageState()
+{
+}
+
 Image::Image(rx::EGLImplFactory *factory,
              EGLenum target,
              ImageSibling *buffer,
              const AttributeMap &attribs)
     : RefCountObject(0),
       mState(target, buffer, attribs),
-      mImplementation(factory->createImage(mState, target, attribs))
+      mImplementation(factory->createImage(mState, target, attribs)),
+      mOrphanedAndNeedsInit(false)
 {
     ASSERT(mImplementation != nullptr);
     ASSERT(buffer != nullptr);
 
     mState.source->addImageSource(this);
 }
 
 gl::Error Image::onDestroy(const gl::Context *context)
@@ -148,16 +171,18 @@ gl::Error Image::orphanSibling(const gl:
     // notify impl
     ANGLE_TRY(mImplementation->orphan(context, sibling));
 
     if (mState.source.get() == sibling)
     {
         // If the sibling is the source, it cannot be a target.
         ASSERT(mState.targets.find(sibling) == mState.targets.end());
         mState.source.set(context, nullptr);
+        mOrphanedAndNeedsInit =
+            (sibling->initState(mState.imageIndex) == gl::InitState::MayNeedInit);
     }
     else
     {
         mState.targets.erase(sibling);
     }
 
     return gl::NoError();
 }
@@ -187,9 +212,34 @@ rx::ImageImpl *Image::getImplementation(
     return mImplementation;
 }
 
 Error Image::initialize()
 {
     return mImplementation->initialize();
 }
 
+bool Image::orphaned() const
+{
+    return (mState.source.get() == nullptr);
+}
+
+gl::InitState Image::sourceInitState() const
+{
+    if (orphaned())
+    {
+        return mOrphanedAndNeedsInit ? gl::InitState::MayNeedInit : gl::InitState::Initialized;
+    }
+
+    return mState.source->initState(mState.imageIndex);
+}
+
+void Image::setInitState(gl::InitState initState)
+{
+    if (orphaned())
+    {
+        mOrphanedAndNeedsInit = false;
+    }
+
+    return mState.source->setInitState(mState.imageIndex, initState);
+}
+
 }  // namespace egl
--- a/gfx/angle/src/libANGLE/Image.h
+++ b/gfx/angle/src/libANGLE/Image.h
@@ -30,17 +30,21 @@ class Image;
 
 // Only currently Renderbuffers and Textures can be bound with images. This makes the relationship
 // explicit, and also ensures that an image sibling can determine if it's been initialized or not,
 // which is important for the robust resource init extension with Textures and EGLImages.
 class ImageSibling : public gl::RefCountObject, public gl::FramebufferAttachmentObject
 {
   public:
     ImageSibling(GLuint id);
-    virtual ~ImageSibling();
+    ~ImageSibling() override;
+
+    bool isEGLImageTarget() const;
+    gl::InitState sourceEGLImageInitState() const;
+    void setSourceEGLImageInitState(gl::InitState initState) const;
 
   protected:
     // Set the image target of this sibling
     void setTargetImage(const gl::Context *context, egl::Image *imageTarget);
 
     // Orphan all EGL image sources and targets
     gl::Error orphanImages(const gl::Context *context);
 
@@ -55,51 +59,57 @@ class ImageSibling : public gl::RefCount
 
     std::set<Image *> mSourcesOf;
     gl::BindingPointer<Image> mTargetOf;
 };
 
 struct ImageState : private angle::NonCopyable
 {
     ImageState(EGLenum target, ImageSibling *buffer, const AttributeMap &attribs);
+    ~ImageState();
 
     gl::ImageIndex imageIndex;
     gl::BindingPointer<ImageSibling> source;
     std::set<ImageSibling *> targets;
 };
 
 class Image final : public gl::RefCountObject
 {
   public:
     Image(rx::EGLImplFactory *factory,
           EGLenum target,
           ImageSibling *buffer,
           const AttributeMap &attribs);
 
     gl::Error onDestroy(const gl::Context *context) override;
-    ~Image();
+    ~Image() override;
 
     const gl::Format &getFormat() const;
     size_t getWidth() const;
     size_t getHeight() const;
     size_t getSamples() const;
 
     Error initialize();
 
     rx::ImageImpl *getImplementation() const;
 
+    bool orphaned() const;
+    gl::InitState sourceInitState() const;
+    void setInitState(gl::InitState initState);
+
   private:
     friend class ImageSibling;
 
     // Called from ImageSibling only notify the image that a new target sibling exists for state
     // tracking.
     void addTargetSibling(ImageSibling *sibling);
 
     // Called from ImageSibling only to notify the image that a sibling (source or target) has
     // been respecified and state tracking should be updated.
     gl::Error orphanSibling(const gl::Context *context, ImageSibling *sibling);
 
     ImageState mState;
     rx::ImageImpl *mImplementation;
+    bool mOrphanedAndNeedsInit;
 };
 }  // namespace egl
 
 #endif  // LIBANGLE_IMAGE_H_
--- a/gfx/angle/src/libANGLE/ImageIndex.cpp
+++ b/gfx/angle/src/libANGLE/ImageIndex.cpp
@@ -115,16 +115,18 @@ bool ImageIndex::operator!=(const ImageI
 {
     return !(*this == other);
 }
 
 ImageIndex::ImageIndex(GLenum typeIn, GLint mipIndexIn, GLint layerIndexIn, GLint numLayersIn)
     : type(typeIn), 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<GLint>(minMip, maxMip),
                               Range<GLint>(ImageIndex::ENTIRE_LEVEL, ImageIndex::ENTIRE_LEVEL),
                               nullptr);
 }
 
 ImageIndexIterator ImageIndexIterator::MakeRectangle(GLint minMip, GLint maxMip)
--- a/gfx/angle/src/libANGLE/ImageIndex.h
+++ b/gfx/angle/src/libANGLE/ImageIndex.h
@@ -52,16 +52,18 @@ struct ImageIndex
     friend class ImageIndexIterator;
 
     ImageIndex(GLenum typeIn, GLint mipIndexIn, GLint layerIndexIn, GLint numLayersIn);
 };
 
 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();
 
     ImageIndex next();
--- a/gfx/angle/src/libANGLE/IndexRangeCache.cpp
+++ b/gfx/angle/src/libANGLE/IndexRangeCache.cpp
@@ -10,16 +10,24 @@
 #include "libANGLE/IndexRangeCache.h"
 
 #include "common/debug.h"
 #include "libANGLE/formatutils.h"
 
 namespace gl
 {
 
+IndexRangeCache::IndexRangeCache()
+{
+}
+
+IndexRangeCache::~IndexRangeCache()
+{
+}
+
 void IndexRangeCache::addRange(GLenum type,
                                size_t offset,
                                size_t count,
                                bool primitiveRestartEnabled,
                                const IndexRange &range)
 {
     mIndexRangeCache[IndexRangeKey(type, offset, count, primitiveRestartEnabled)] = range;
 }
--- a/gfx/angle/src/libANGLE/IndexRangeCache.h
+++ b/gfx/angle/src/libANGLE/IndexRangeCache.h
@@ -18,16 +18,19 @@
 #include <map>
 
 namespace gl
 {
 
 class IndexRangeCache
 {
   public:
+    IndexRangeCache();
+    ~IndexRangeCache();
+
     void addRange(GLenum type,
                   size_t offset,
                   size_t count,
                   bool primitiveRestartEnabled,
                   const IndexRange &range);
     bool findRange(GLenum type,
                    size_t offset,
                    size_t count,
--- a/gfx/angle/src/libANGLE/LoggingAnnotator.cpp
+++ b/gfx/angle/src/libANGLE/LoggingAnnotator.cpp
@@ -8,16 +8,21 @@
 
 #include "libANGLE/LoggingAnnotator.h"
 
 #include <platform/Platform.h>
 
 namespace angle
 {
 
+bool LoggingAnnotator::getStatus()
+{
+    return false;
+}
+
 void LoggingAnnotator::logMessage(const gl::LogMessage &msg) const
 {
     auto *plat = ANGLEPlatformCurrent();
     if (plat != nullptr)
     {
         switch (msg.getSeverity())
         {
             case gl::LOG_ERR:
--- a/gfx/angle/src/libANGLE/LoggingAnnotator.h
+++ b/gfx/angle/src/libANGLE/LoggingAnnotator.h
@@ -17,15 +17,15 @@ namespace angle
 class LoggingAnnotator : public gl::DebugAnnotator
 {
   public:
     LoggingAnnotator(){};
     ~LoggingAnnotator() override{};
     void beginEvent(const wchar_t *eventName) override {}
     void endEvent() override {}
     void setMarker(const wchar_t *markerName) override {}
-    bool getStatus() override { return false; }
+    bool getStatus() override;
     void logMessage(const gl::LogMessage &msg) const override;
 };
 
 }  // namespace angle
 
 #endif  // LIBANGLE_LOGGINGANNOTATOR_H_
--- a/gfx/angle/src/libANGLE/MemoryProgramCache.cpp
+++ b/gfx/angle/src/libANGLE/MemoryProgramCache.cpp
@@ -37,29 +37,29 @@ enum CacheResult
 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->writeInt(var.arraySize);
+    stream->writeIntVector(var.arraySizes);
     stream->writeInt(var.staticUse);
     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();
-    var->arraySize  = stream->readInt<unsigned int>();
+    stream->readIntVector<unsigned int>(&var->arraySizes);
     var->staticUse  = stream->readBool();
     var->structName = stream->readString();
 }
 
 void WriteShaderVariableBuffer(BinaryOutputStream *stream, const ShaderVariableBuffer &var)
 {
     stream->writeInt(var.binding);
     stream->writeInt(var.dataSize);
@@ -85,16 +85,48 @@ void LoadShaderVariableBuffer(BinaryInpu
 
     unsigned int numMembers = stream->readInt<unsigned int>();
     for (unsigned int blockMemberIndex = 0; blockMemberIndex < numMembers; blockMemberIndex++)
     {
         var->memberIndexes.push_back(stream->readInt<unsigned int>());
     }
 }
 
+void WriteBufferVariable(BinaryOutputStream *stream, const BufferVariable &var)
+{
+    WriteShaderVar(stream, var);
+
+    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);
+}
+
+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();
+}
+
 void WriteInterfaceBlock(BinaryOutputStream *stream, const InterfaceBlock &block)
 {
     stream->writeString(block.name);
     stream->writeString(block.mappedName);
     stream->writeInt(block.isArray);
     stream->writeInt(block.arrayElement);
 
     WriteShaderVariableBuffer(stream, block);
@@ -132,17 +164,17 @@ HashStream &operator<<(HashStream &strea
     if (shader)
     {
         stream << shader->getSourceString().c_str() << shader->getSourceString().length()
                << shader->getCompilerResourcesString().c_str();
     }
     return stream;
 }
 
-HashStream &operator<<(HashStream &stream, const Program::Bindings &bindings)
+HashStream &operator<<(HashStream &stream, const ProgramBindings &bindings)
 {
     for (const auto &binding : bindings)
     {
         stream << binding.first << binding.second;
     }
     return stream;
 }
 
@@ -195,16 +227,21 @@ LinkResult MemoryProgramCache::Deseriali
     }
 
     state->mComputeShaderLocalSize[0] = stream.readInt<int>();
     state->mComputeShaderLocalSize[1] = stream.readInt<int>();
     state->mComputeShaderLocalSize[2] = 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>();
+
     static_assert(MAX_VERTEX_ATTRIBS <= sizeof(unsigned long) * 8,
                   "Too many vertex attribs for mask");
     state->mActiveAttribLocationsMask = stream.readInt<unsigned long>();
 
     unsigned int attribCount = stream.readInt<unsigned int>();
     ASSERT(state->mAttributes.empty());
     for (unsigned int attribIndex = 0; attribIndex < attribCount; ++attribIndex)
     {
@@ -233,17 +270,17 @@ LinkResult MemoryProgramCache::Deseriali
     }
 
     const unsigned int uniformIndexCount = stream.readInt<unsigned int>();
     ASSERT(state->mUniformLocations.empty());
     for (unsigned int uniformIndexIndex = 0; uniformIndexIndex < uniformIndexCount;
          uniformIndexIndex++)
     {
         VariableLocation variable;
-        stream.readInt(&variable.element);
+        stream.readInt(&variable.arrayIndex);
         stream.readInt(&variable.index);
         stream.readBool(&variable.ignored);
 
         state->mUniformLocations.push_back(variable);
     }
 
     unsigned int uniformBlockCount = stream.readInt<unsigned int>();
     ASSERT(state->mUniformBlocks.empty());
@@ -252,16 +289,25 @@ LinkResult MemoryProgramCache::Deseriali
     {
         InterfaceBlock uniformBlock;
         LoadInterfaceBlock(&stream, &uniformBlock);
         state->mUniformBlocks.push_back(uniformBlock);
 
         state->mActiveUniformBlockBindings.set(uniformBlockIndex, uniformBlock.binding != 0);
     }
 
+    unsigned int bufferVariableCount = stream.readInt<unsigned int>();
+    ASSERT(state->mBufferVariables.empty());
+    for (unsigned int index = 0; index < bufferVariableCount; ++index)
+    {
+        BufferVariable bufferVariable;
+        LoadBufferVariable(&stream, &bufferVariable);
+        state->mBufferVariables.push_back(bufferVariable);
+    }
+
     unsigned int shaderStorageBlockCount = stream.readInt<unsigned int>();
     ASSERT(state->mShaderStorageBlocks.empty());
     for (unsigned int shaderStorageBlockIndex = 0;
          shaderStorageBlockIndex < shaderStorageBlockCount; ++shaderStorageBlockIndex)
     {
         InterfaceBlock shaderStorageBlock;
         LoadInterfaceBlock(&stream, &shaderStorageBlock);
         state->mShaderStorageBlocks.push_back(shaderStorageBlock);
@@ -288,17 +334,17 @@ LinkResult MemoryProgramCache::Deseriali
     }
 
     ASSERT(state->mLinkedTransformFeedbackVaryings.empty());
     for (unsigned int transformFeedbackVaryingIndex = 0;
          transformFeedbackVaryingIndex < transformFeedbackVaryingCount;
          ++transformFeedbackVaryingIndex)
     {
         sh::Varying varying;
-        stream.readInt(&varying.arraySize);
+        stream.readIntVector<unsigned int>(&varying.arraySizes);
         stream.readInt(&varying.type);
         stream.readString(&varying.name);
 
         GLuint arrayIndex = stream.readInt<GLuint>();
 
         state->mLinkedTransformFeedbackVaryings.emplace_back(varying, arrayIndex);
     }
 
@@ -310,33 +356,36 @@ LinkResult MemoryProgramCache::Deseriali
     {
         sh::OutputVariable output;
         LoadShaderVar(&stream, &output);
         output.location = stream.readInt<int>();
         state->mOutputVariables.push_back(output);
     }
 
     unsigned int outputVarCount = stream.readInt<unsigned int>();
+    ASSERT(state->mOutputLocations.empty());
     for (unsigned int outputIndex = 0; outputIndex < outputVarCount; ++outputIndex)
     {
-        int locationIndex = stream.readInt<int>();
         VariableLocation locationData;
-        stream.readInt(&locationData.element);
+        stream.readInt(&locationData.arrayIndex);
         stream.readInt(&locationData.index);
         stream.readBool(&locationData.ignored);
-        state->mOutputLocations[locationIndex] = locationData;
+        state->mOutputLocations.push_back(locationData);
     }
 
     unsigned int outputTypeCount = stream.readInt<unsigned int>();
     for (unsigned int outputIndex = 0; outputIndex < outputTypeCount; ++outputIndex)
     {
         state->mOutputVariableTypes.push_back(stream.readInt<GLenum>());
     }
-    static_assert(IMPLEMENTATION_MAX_DRAW_BUFFERS < 8 * sizeof(uint32_t),
-                  "All bits of DrawBufferMask can be contained in an uint32_t");
+
+    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>();
 
     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)
     {
@@ -361,16 +410,19 @@ 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>();
+
     return program->getImplementation()->load(context, infoLog, &stream);
 }
 
 // static
 void MemoryProgramCache::Serialize(const Context *context,
                                    const gl::Program *program,
                                    angle::MemoryBuffer *binaryOut)
 {
@@ -396,16 +448,21 @@ void MemoryProgramCache::Serialize(const
     const auto &computeLocalSize = state.getComputeShaderLocalSize();
 
     stream.writeInt(computeLocalSize[0]);
     stream.writeInt(computeLocalSize[1]);
     stream.writeInt(computeLocalSize[2]);
 
     stream.writeInt(state.mNumViews);
 
+    static_assert(MAX_VERTEX_ATTRIBS * 2 <= sizeof(uint32_t) * 8,
+                  "All bits of mAttributesTypeMask types and mask fit into 32 bits each");
+    stream.writeInt(static_cast<int>(state.mAttributesTypeMask.to_ulong()));
+    stream.writeInt(static_cast<int>(state.mAttributesMask.to_ulong()));
+
     stream.writeInt(state.getActiveAttribLocationsMask().to_ulong());
 
     stream.writeInt(state.getAttributes().size());
     for (const sh::Attribute &attrib : state.getAttributes())
     {
         WriteShaderVar(&stream, attrib);
         stream.writeInt(attrib.location);
     }
@@ -422,27 +479,33 @@ void MemoryProgramCache::Serialize(const
         stream.writeInt(uniform.blockInfo.arrayStride);
         stream.writeInt(uniform.blockInfo.matrixStride);
         stream.writeInt(uniform.blockInfo.isRowMajorMatrix);
     }
 
     stream.writeInt(state.getUniformLocations().size());
     for (const auto &variable : state.getUniformLocations())
     {
-        stream.writeInt(variable.element);
+        stream.writeInt(variable.arrayIndex);
         stream.writeIntOrNegOne(variable.index);
         stream.writeInt(variable.ignored);
     }
 
     stream.writeInt(state.getUniformBlocks().size());
     for (const InterfaceBlock &uniformBlock : state.getUniformBlocks())
     {
         WriteInterfaceBlock(&stream, uniformBlock);
     }
 
+    stream.writeInt(state.getBufferVariables().size());
+    for (const BufferVariable &bufferVariable : state.getBufferVariables())
+    {
+        WriteBufferVariable(&stream, bufferVariable);
+    }
+
     stream.writeInt(state.getShaderStorageBlocks().size());
     for (const InterfaceBlock &shaderStorageBlock : state.getShaderStorageBlocks())
     {
         WriteInterfaceBlock(&stream, shaderStorageBlock);
     }
 
     stream.writeInt(state.mAtomicCounterBuffers.size());
     for (const auto &atomicCounterBuffer : state.mAtomicCounterBuffers)
@@ -456,50 +519,51 @@ void MemoryProgramCache::Serialize(const
     {
         WARN() << "Saving program binary with transform feedback, which is not supported on this "
                   "driver.";
     }
 
     stream.writeInt(state.getLinkedTransformFeedbackVaryings().size());
     for (const auto &var : state.getLinkedTransformFeedbackVaryings())
     {
-        stream.writeInt(var.arraySize);
+        stream.writeIntVector(var.arraySizes);
         stream.writeInt(var.type);
         stream.writeString(var.name);
 
         stream.writeIntOrNegOne(var.arrayIndex);
     }
 
     stream.writeInt(state.getTransformFeedbackBufferMode());
 
     stream.writeInt(state.getOutputVariables().size());
     for (const sh::OutputVariable &output : state.getOutputVariables())
     {
         WriteShaderVar(&stream, output);
         stream.writeInt(output.location);
     }
 
     stream.writeInt(state.getOutputLocations().size());
-    for (const auto &outputPair : state.getOutputLocations())
+    for (const auto &outputVar : state.getOutputLocations())
     {
-        stream.writeInt(outputPair.first);
-        stream.writeIntOrNegOne(outputPair.second.element);
-        stream.writeIntOrNegOne(outputPair.second.index);
-        stream.writeInt(outputPair.second.ignored);
+        stream.writeInt(outputVar.arrayIndex);
+        stream.writeIntOrNegOne(outputVar.index);
+        stream.writeInt(outputVar.ignored);
     }
 
     stream.writeInt(state.mOutputVariableTypes.size());
     for (const auto &outputVariableType : state.mOutputVariableTypes)
     {
         stream.writeInt(outputVariableType);
     }
 
-    static_assert(IMPLEMENTATION_MAX_DRAW_BUFFERS < 8 * sizeof(uint32_t),
-                  "All bits of DrawBufferMask can be contained in an uint32_t");
-    stream.writeInt(static_cast<uint32_t>(state.mActiveOutputVariables.to_ulong()));
+    static_assert(
+        IMPLEMENTATION_MAX_DRAW_BUFFERS * 2 <= 8 * sizeof(uint32_t),
+        "All bits of mDrawBufferTypeMask and mActiveOutputVariables can be contained in 32 bits");
+    stream.writeInt(static_cast<int>(state.mDrawBufferTypeMask.to_ulong()));
+    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);
@@ -518,31 +582,33 @@ void MemoryProgramCache::Serialize(const
         {
             stream.writeInt(imageBinding.boundImageUnits[i]);
         }
     }
 
     stream.writeInt(state.getAtomicCounterUniformRange().low());
     stream.writeInt(state.getAtomicCounterUniformRange().high());
 
+    stream.writeInt(state.getLinkedShaderStages().to_ulong());
+
     program->getImplementation()->save(context, &stream);
 
     ASSERT(binaryOut);
     binaryOut->resize(stream.length());
     memcpy(binaryOut->data(), stream.data(), stream.length());
 }
 
 // static
 void MemoryProgramCache::ComputeHash(const Context *context,
                                      const Program *program,
                                      ProgramHash *hashOut)
 {
-    auto vertexShader   = program->getAttachedVertexShader();
-    auto fragmentShader = program->getAttachedFragmentShader();
-    auto computeShader  = program->getAttachedComputeShader();
+    const Shader *vertexShader   = program->getAttachedVertexShader();
+    const Shader *fragmentShader = program->getAttachedFragmentShader();
+    const Shader *computeShader  = program->getAttachedComputeShader();
 
     // Compute the program hash. Start with the shader hashes and resource strings.
     HashStream hashStream;
     hashStream << vertexShader << fragmentShader << computeShader;
 
     // 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);
new file mode 100644
--- /dev/null
+++ b/gfx/angle/src/libANGLE/PackedGLEnums.h
@@ -0,0 +1,134 @@
+// 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.
+//
+// PackedGLEnums_autogen.h:
+//   Declares ANGLE-specific enums classes for GLEnum and functions operating
+//   on them.
+
+#ifndef LIBANGLE_PACKEDGLENUMS_H_
+#define LIBANGLE_PACKEDGLENUMS_H_
+
+#include "libANGLE/PackedGLEnums_autogen.h"
+
+#include <array>
+#include <bitset>
+#include <cstddef>
+
+#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()
+{
+    using UnderlyingType = typename std::underlying_type<E>::type;
+    return static_cast<UnderlyingType>(E::EnumCount);
+}
+
+// Implementation of AllEnums which allows iterating over all the possible values for a packed enums
+// like so:
+//     for (auto value : AllEnums<MyPackedEnum>()) {
+//         // Do something with the enum.
+//     }
+
+template <typename E>
+class EnumIterator final
+{
+  private:
+    using UnderlyingType = typename std::underlying_type<E>::type;
+
+  public:
+    EnumIterator(E value) : mValue(static_cast<UnderlyingType>(value)) {}
+    EnumIterator &operator++()
+    {
+        mValue++;
+        return *this;
+    }
+    bool operator==(const EnumIterator &other) const { return mValue == other.mValue; }
+    bool operator!=(const EnumIterator &other) const { return mValue != other.mValue; }
+    E operator*() const { return static_cast<E>(mValue); }
+
+  private:
+    UnderlyingType mValue;
+};
+
+template <typename E>
+struct AllEnums
+{
+    EnumIterator<E> begin() const { return {static_cast<E>(0)}; }
+    EnumIterator<E> end() const { return {E::InvalidEnum}; }
+};
+
+// PackedEnumMap<E, T> is like an std::array<T, E::EnumCount> but is indexed with enum values. It
+// implements all of the std::array interface except with enum values instead of indices.
+template <typename E, typename T>
+class PackedEnumMap
+{
+  private:
+    using UnderlyingType          = typename std::underlying_type<E>::type;
+    using Storage                 = std::array<T, EnumSize<E>()>;
+
+    Storage mData;
+
+  public:
+    // types:
+    using value_type      = T;
+    using pointer         = T *;
+    using const_pointer   = const T *;
+    using reference       = T &;
+    using const_reference = const T &;
+
+    using size_type       = size_t;
+    using difference_type = ptrdiff_t;
+
+    using iterator               = typename Storage::iterator;
+    using const_iterator         = typename Storage::const_iterator;
+    using reverse_iterator       = std::reverse_iterator<iterator>;
+    using const_reverse_iterator = std::reverse_iterator<const_iterator>;
+
+    // No explicit construct/copy/destroy for aggregate type
+    void fill(const T &u) { mData.fill(u); }
+    void swap(PackedEnumMap<E, T> &a) noexcept { mData.swap(a.mData); }
+
+    // iterators:
+    iterator begin() noexcept { return mData.begin(); }
+    const_iterator begin() const noexcept { return mData.begin(); }
+    iterator end() noexcept { return mData.end(); }
+    const_iterator end() const noexcept { return mData.end(); }
+
+    reverse_iterator rbegin() noexcept { return mData.rbegin(); }
+    const_reverse_iterator rbegin() const noexcept { return mData.rbegin(); }
+    reverse_iterator rend() noexcept { return mData.rend(); }
+    const_reverse_iterator rend() const noexcept { return mData.rend(); }
+
+    // capacity:
+    constexpr size_type size() const noexcept { return mData.size(); }
+    constexpr size_type max_size() const noexcept { return mData.max_size(); }
+    constexpr bool empty() const noexcept { return mData.empty(); }
+
+    // element access:
+    reference operator[](E n) { return mData[static_cast<UnderlyingType>(n)]; }
+    const_reference operator[](E n) const { return mData[static_cast<UnderlyingType>(n)]; }
+    const_reference at(E n) const { return mData.at(static_cast<UnderlyingType>(n)); }
+    reference at(E n) { return mData.at(static_cast<UnderlyingType>(n)); }
+
+    reference front() { return mData.front(); }
+    const_reference front() const { return mData.front(); }
+    reference back() { return mData.back(); }
+    const_reference back() const { return mData.back(); }
+
+    T *data() noexcept { return mData.data(); }
+    const T *data() const noexcept { return mData.data(); }
+};
+
+// 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
+
+#endif  // LIBANGLE_PACKEDGLENUMS_H_
new file mode 100644
--- /dev/null
+++ b/gfx/angle/src/libANGLE/PackedGLEnums_autogen.cpp
@@ -0,0 +1,174 @@
+// GENERATED FILE - DO NOT EDIT.
+// Generated by gen_packed_gl_enums.py using data from packed_gl_enums.json.
+//
+// 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_autogen.cpp:
+//   Implements ANGLE-specific enums classes for GLEnum and functions operating
+//   on them.
+
+#include "libANGLE/PackedGLEnums_autogen.h"
+#include "common/debug.h"
+
+namespace gl
+{
+
+template <>
+BufferBinding FromGLenum<BufferBinding>(GLenum from)
+{
+    switch (from)
+    {
+        case GL_ARRAY_BUFFER:
+            return BufferBinding::Array;
+        case GL_ATOMIC_COUNTER_BUFFER:
+            return BufferBinding::AtomicCounter;
+        case GL_COPY_READ_BUFFER:
+            return BufferBinding::CopyRead;
+        case GL_COPY_WRITE_BUFFER:
+            return BufferBinding::CopyWrite;
+        case GL_DISPATCH_INDIRECT_BUFFER:
+            return BufferBinding::DispatchIndirect;
+        case GL_DRAW_INDIRECT_BUFFER:
+            return BufferBinding::DrawIndirect;
+        case GL_ELEMENT_ARRAY_BUFFER:
+            return BufferBinding::ElementArray;
+        case GL_PIXEL_PACK_BUFFER:
+            return BufferBinding::PixelPack;
+        case GL_PIXEL_UNPACK_BUFFER:
+            return BufferBinding::PixelUnpack;
+        case GL_SHADER_STORAGE_BUFFER:
+            return BufferBinding::ShaderStorage;
+        case GL_TRANSFORM_FEEDBACK_BUFFER:
+            return BufferBinding::TransformFeedback;
+        case GL_UNIFORM_BUFFER:
+            return BufferBinding::Uniform;
+        default:
+            return BufferBinding::InvalidEnum;
+    }
+}
+
+GLenum ToGLenum(BufferBinding from)
+{
+    switch (from)
+    {
+        case BufferBinding::Array:
+            return GL_ARRAY_BUFFER;
+        case BufferBinding::AtomicCounter:
+            return GL_ATOMIC_COUNTER_BUFFER;
+        case BufferBinding::CopyRead:
+            return GL_COPY_READ_BUFFER;
+        case BufferBinding::CopyWrite:
+            return GL_COPY_WRITE_BUFFER;
+        case BufferBinding::DispatchIndirect:
+            return GL_DISPATCH_INDIRECT_BUFFER;
+        case BufferBinding::DrawIndirect:
+            return GL_DRAW_INDIRECT_BUFFER;
+        case BufferBinding::ElementArray:
+            return GL_ELEMENT_ARRAY_BUFFER;
+        case BufferBinding::PixelPack:
+            return GL_PIXEL_PACK_BUFFER;
+        case BufferBinding::PixelUnpack:
+            return GL_PIXEL_UNPACK_BUFFER;
+        case BufferBinding::ShaderStorage:
+            return GL_SHADER_STORAGE_BUFFER;
+        case BufferBinding::TransformFeedback:
+            return GL_TRANSFORM_FEEDBACK_BUFFER;
+        case BufferBinding::Uniform:
+            return GL_UNIFORM_BUFFER;
+        default:
+            UNREACHABLE();
+            return GL_NONE;
+    }
+}
+
+template <>
+BufferUsage FromGLenum<BufferUsage>(GLenum from)
+{
+    switch (from)
+    {
+        case GL_DYNAMIC_COPY:
+            return BufferUsage::DynamicCopy;
+        case GL_DYNAMIC_DRAW:
+            return BufferUsage::DynamicDraw;
+        case GL_DYNAMIC_READ:
+            return BufferUsage::DynamicRead;
+        case GL_STATIC_COPY:
+            return BufferUsage::StaticCopy;
+        case GL_STATIC_DRAW:
+            return BufferUsage::StaticDraw;
+        case GL_STATIC_READ:
+            return BufferUsage::StaticRead;
+        case GL_STREAM_COPY:
+            return BufferUsage::StreamCopy;
+        case GL_STREAM_DRAW:
+            return BufferUsage::StreamDraw;
+        case GL_STREAM_READ:
+            return BufferUsage::StreamRead;
+        default:
+            return BufferUsage::InvalidEnum;
+    }
+}
+
+GLenum ToGLenum(BufferUsage from)
+{
+    switch (from)
+    {
+        case BufferUsage::DynamicCopy:
+            return GL_DYNAMIC_COPY;
+        case BufferUsage::DynamicDraw:
+            return GL_DYNAMIC_DRAW;
+        case BufferUsage::DynamicRead:
+            return GL_DYNAMIC_READ;
+        case BufferUsage::StaticCopy:
+            return GL_STATIC_COPY;
+        case BufferUsage::StaticDraw:
+            return GL_STATIC_DRAW;
+        case BufferUsage::StaticRead:
+            return GL_STATIC_READ;
+        case BufferUsage::StreamCopy:
+            return GL_STREAM_COPY;
+        case BufferUsage::StreamDraw:
+            return GL_STREAM_DRAW;
+        case BufferUsage::StreamRead:
+            return GL_STREAM_READ;
+        default:
+            UNREACHABLE();
+            return GL_NONE;
+    }
+}
+
+template <>
+CullFaceMode FromGLenum<CullFaceMode>(GLenum from)
+{
+    switch (from)
+    {
+        case GL_BACK:
+            return CullFaceMode::Back;
+        case GL_FRONT:
+            return CullFaceMode::Front;
+        case GL_FRONT_AND_BACK:
+            return CullFaceMode::FrontAndBack;
+        default:
+            return CullFaceMode::InvalidEnum;
+    }
+}
+
+GLenum ToGLenum(CullFaceMode from)
+{
+    switch (from)
+    {
+        case CullFaceMode::Back:
+            return GL_BACK;
+        case CullFaceMode::Front:
+            return GL_FRONT;
+        case CullFaceMode::FrontAndBack:
+            return GL_FRONT_AND_BACK;
+        default:
+            UNREACHABLE();
+            return GL_NONE;
+    }
+}
+
+}  // namespace gl
new file mode 100644
--- /dev/null
+++ b/gfx/angle/src/libANGLE/PackedGLEnums_autogen.h
@@ -0,0 +1,84 @@
+// GENERATED FILE - DO NOT EDIT.
+// Generated by gen_packed_gl_enums.py using data from packed_gl_enums.json.
+//
+// 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_autogen.h:
+//   Declares ANGLE-specific enums classes for GLEnum and functions operating
+//   on them.
+
+#ifndef LIBANGLE_PACKEDGLENUMS_AUTOGEN_H_
+#define LIBANGLE_PACKEDGLENUMS_AUTOGEN_H_
+
+#include <angle_gl.h>
+
+#include <cstdint>
+
+namespace gl
+{
+
+template <typename Enum>
+Enum FromGLenum(GLenum from);
+
+enum class BufferBinding : uint8_t
+{
+    Array             = 0,
+    AtomicCounter     = 1,
+    CopyRead          = 2,
+    CopyWrite         = 3,
+    DispatchIndirect  = 4,
+    DrawIndirect      = 5,
+    ElementArray      = 6,
+    PixelPack         = 7,
+    PixelUnpack       = 8,
+    ShaderStorage     = 9,
+    TransformFeedback = 10,
+    Uniform           = 11,
+
+    InvalidEnum = 12,
+    EnumCount   = 12,
+};
+
+template <>
+BufferBinding FromGLenum<BufferBinding>(GLenum from);
+GLenum ToGLenum(BufferBinding from);
+
+enum class BufferUsage : uint8_t
+{
+    DynamicCopy = 0,
+    DynamicDraw = 1,
+    DynamicRead = 2,
+    StaticCopy  = 3,
+    StaticDraw  = 4,
+    StaticRead  = 5,
+    StreamCopy  = 6,
+    StreamDraw  = 7,
+    StreamRead  = 8,
+
+    InvalidEnum = 9,
+    EnumCount   = 9,
+};
+
+template <>
+BufferUsage FromGLenum<BufferUsage>(GLenum from);
+GLenum ToGLenum(BufferUsage from);
+
+enum class CullFaceMode : uint8_t
+{
+    Back         = 0,
+    Front        = 1,
+    FrontAndBack = 2,
+
+    InvalidEnum = 3,
+    EnumCount   = 3,
+};
+
+template <>
+CullFaceMode FromGLenum<CullFaceMode>(GLenum from);
+GLenum ToGLenum(CullFaceMode from);
+
+}  // namespace gl
+
+#endif  // LIBANGLE_PACKEDGLENUMS_AUTOGEN_H_
--- a/gfx/angle/src/libANGLE/Platform.cpp
+++ b/gfx/angle/src/libANGLE/Platform.cpp
@@ -13,16 +13,20 @@
 #include "common/debug.h"
 
 namespace
 {
 // TODO(jmadill): Make methods owned by egl::Display.
 angle::PlatformMethods g_platformMethods;
 }  // anonymous namespace
 
+angle::PlatformMethods::PlatformMethods()
+{
+}
+
 angle::PlatformMethods *ANGLEPlatformCurrent()
 {
     return &g_platformMethods;
 }
 
 bool ANGLE_APIENTRY ANGLEGetDisplayPlatform(angle::EGLDisplayType display,
                                             const char *const methodNames[],
                                             unsigned int methodNameCount,
--- a/gfx/angle/src/libANGLE/Program.cpp
+++ b/gfx/angle/src/libANGLE/Program.cpp
@@ -9,23 +9,24 @@
 
 #include "libANGLE/Program.h"
 
 #include <algorithm>
 
 #include "common/bitset_utils.h"
 #include "common/debug.h"
 #include "common/platform.h"
+#include "common/string_utils.h"
 #include "common/utilities.h"
 #include "compiler/translator/blocklayout.h"
 #include "libANGLE/Context.h"
 #include "libANGLE/MemoryProgramCache.h"
+#include "libANGLE/ProgramLinkedResources.h"
 #include "libANGLE/ResourceManager.h"
 #include "libANGLE/Uniform.h"
-#include "libANGLE/UniformLinker.h"
 #include "libANGLE/VaryingPacking.h"
 #include "libANGLE/features.h"
 #include "libANGLE/histogram_macros.h"
 #include "libANGLE/queryconversions.h"
 #include "libANGLE/renderer/GLImplFactory.h"
 #include "libANGLE/renderer/ProgramImpl.h"
 #include "platform/Platform.h"
 
@@ -65,29 +66,29 @@ GLuint UniformStateQueryCast(GLint value
 {
     return clampCast<GLuint>(value);
 }
 
 // From-Boolean-to-Anything Casts
 template <>
 GLfloat UniformStateQueryCast(GLboolean value)
 {
-    return (value == GL_TRUE ? 1.0f : 0.0f);
+    return (ConvertToBool(value) ? 1.0f : 0.0f);
 }
 
 template <>
 GLint UniformStateQueryCast(GLboolean value)
 {
-    return (value == GL_TRUE ? 1 : 0);
+    return (ConvertToBool(value) ? 1 : 0);
 }
 
 template <>
 GLuint UniformStateQueryCast(GLboolean value)
 {
-    return (value == GL_TRUE ? 1u : 0u);
+    return (ConvertToBool(value) ? 1u : 0u);
 }
 
 // Default to static_cast
 template <typename DestT, typename SrcT>
 DestT UniformStateQueryCast(SrcT value)
 {
     return static_cast<DestT>(value);
 }
@@ -100,97 +101,108 @@ void UniformStateQueryCastLoop(DestT *da
         // We only work with strides of 4 bytes for uniform components. (GLfloat/GLint)
         // Don't use SrcT stride directly since GLboolean has a stride of 1 byte.
         size_t offset               = comp * 4;
         const SrcT *typedSrcPointer = reinterpret_cast<const SrcT *>(&srcPointer[offset]);
         dataOut[comp]               = UniformStateQueryCast<DestT>(*typedSrcPointer);
     }
 }
 
-// true if varying x has a higher priority in packing than y
-bool ComparePackedVarying(const PackedVarying &x, const PackedVarying &y)
-{
-    // If the PackedVarying 'x' or 'y' to be compared is an array element, this clones an equivalent
-    // non-array shader variable 'vx' or 'vy' for actual comparison instead.
-    sh::ShaderVariable vx, vy;
-    const sh::ShaderVariable *px, *py;
-    if (x.isArrayElement())
-    {
-        vx           = *x.varying;
-        vx.arraySize = 0;
-        px           = &vx;
-    }
-    else
-    {
-        px = x.varying;
-    }
-
-    if (y.isArrayElement())
-    {
-        vy           = *y.varying;
-        vy.arraySize = 0;
-        py           = &vy;
-    }
-    else
-    {
-        py = y.varying;
-    }
-
-    return gl::CompareShaderVar(*px, *py);
-}
-
 template <typename VarT>
 GLuint GetResourceIndexFromName(const std::vector<VarT> &list, const std::string &name)
 {
-    size_t subscript     = GL_INVALID_INDEX;
-    std::string baseName = ParseResourceName(name, &subscript);
-
-    // The app is not allowed to specify array indices other than 0 for arrays of basic types
-    if (subscript != 0 && subscript != GL_INVALID_INDEX)
-    {
-        return GL_INVALID_INDEX;
-    }
-
+    std::string nameAsArrayName = name + "[0]";
     for (size_t index = 0; index < list.size(); index++)
     {
         const VarT &resource = list[index];
-        if (resource.name == baseName)
+        if (resource.name == name || (resource.isArray() && resource.name == nameAsArrayName))
         {
-            if (resource.isArray() || subscript == GL_INVALID_INDEX)
-            {
-                return static_cast<GLuint>(index);
-            }
+            return static_cast<GLuint>(index);
         }
     }
 
     return GL_INVALID_INDEX;
 }
 
+template <typename VarT>
+GLint GetVariableLocation(const std::vector<VarT> &list,
+                          const std::vector<VariableLocation> &locationList,
+                          const std::string &name)
+{
+    size_t nameLengthWithoutArrayIndex;
+    unsigned int arrayIndex = ParseArrayIndex(name, &nameLengthWithoutArrayIndex);
+
+    for (size_t location = 0u; location < locationList.size(); ++location)
+    {
+        const VariableLocation &variableLocation = locationList[location];
+        if (!variableLocation.used())
+        {
+            continue;
+        }
+
+        const VarT &variable = list[variableLocation.index];
+
+        if (angle::BeginsWith(variable.name, name))
+        {
+            if (name.length() == variable.name.length())
+            {
+                ASSERT(name == variable.name);
+                // GLES 3.1 November 2016 page 87.
+                // The string exactly matches the name of the active variable.
+                return static_cast<GLint>(location);
+            }
+            if (name.length() + 3u == variable.name.length() && variable.isArray())
+            {
+                ASSERT(name + "[0]" == variable.name);
+                // The string identifies the base name of an active array, where the string would
+                // exactly match the name of the variable if the suffix "[0]" were appended to the
+                // string.
+                return static_cast<GLint>(location);
+            }
+        }
+        if (variable.isArray() && variableLocation.arrayIndex == arrayIndex &&
+            nameLengthWithoutArrayIndex + 3u == variable.name.length() &&
+            angle::BeginsWith(variable.name, name, nameLengthWithoutArrayIndex))
+        {
+            ASSERT(name.substr(0u, nameLengthWithoutArrayIndex) + "[0]" == variable.name);
+            // The string identifies an active element of the array, where the string ends with the
+            // concatenation of the "[" character, an integer (with no "+" sign, extra leading
+            // zeroes, or whitespace) identifying an array element, and the "]" character, the
+            // integer is less than the number of active elements of the array variable, and where
+            // the string would exactly match the enumerated name of the array if the decimal
+            // integer were replaced with zero.
+            return static_cast<GLint>(location);
+        }
+    }
+
+    return -1;
+}
+
 void CopyStringToBuffer(GLchar *buffer, const std::string &string, GLsizei bufSize, GLsizei *length)
 {
     ASSERT(bufSize > 0);
     strncpy(buffer, string.c_str(), bufSize);
     buffer[bufSize - 1] = '\0';
 
     if (length)
     {
         *length = static_cast<GLsizei>(strlen(buffer));
     }
 }
 
 bool IncludeSameArrayElement(const std::set<std::string> &nameSet, const std::string &name)
 {
-    size_t subscript     = GL_INVALID_INDEX;
-    std::string baseName = ParseResourceName(name, &subscript);
-    for (auto it = nameSet.begin(); it != nameSet.end(); ++it)
+    std::vector<unsigned int> subscripts;
+    std::string baseName = ParseResourceName(name, &subscripts);
+    for (auto nameInSet : nameSet)
     {
-        size_t arrayIndex     = GL_INVALID_INDEX;
-        std::string arrayName = ParseResourceName(*it, &arrayIndex);
-        if (baseName == arrayName && (subscript == GL_INVALID_INDEX ||
-                                      arrayIndex == GL_INVALID_INDEX || subscript == arrayIndex))
+        std::vector<unsigned int> arrayIndices;
+        std::string arrayName = ParseResourceName(nameInSet, &arrayIndices);
+        if (baseName == arrayName &&
+            (subscripts.empty() || arrayIndices.empty() || subscripts == arrayIndices))
         {
             return true;
         }
     }
     return false;
 }
 
 bool validateInterfaceBlocksCount(GLuint maxInterfaceBlocks,
@@ -209,20 +221,137 @@ bool validateInterfaceBlocksCount(GLuint
                 infoLog << errorMessage << maxInterfaceBlocks << ")";
                 return false;
             }
         }
     }
     return true;
 }
 
+GLuint GetInterfaceBlockIndex(const std::vector<InterfaceBlock> &list, const std::string &name)
+{
+    std::vector<unsigned int> subscripts;
+    std::string baseName = ParseResourceName(name, &subscripts);
+
+    unsigned int numBlocks = static_cast<unsigned int>(list.size());
+    for (unsigned int blockIndex = 0; blockIndex < numBlocks; blockIndex++)
+    {
+        const auto &block = list[blockIndex];
+        if (block.name == baseName)
+        {
+            const bool arrayElementZero =
+                (subscripts.empty() && (!block.isArray || block.arrayElement == 0));
+            const bool arrayElementMatches =
+                (subscripts.size() == 1 && subscripts[0] == block.arrayElement);
+            if (arrayElementMatches || arrayElementZero)
+            {
+                return blockIndex;
+            }
+        }
+    }
+
+    return GL_INVALID_INDEX;
+}
+
+void GetInterfaceBlockName(const GLuint index,
+                           const std::vector<InterfaceBlock> &list,
+                           GLsizei bufSize,
+                           GLsizei *length,
+                           GLchar *name)
+{
+    ASSERT(index < list.size());
+
+    const auto &block = list[index];
+
+    if (bufSize > 0)
+    {
+        std::string blockName = block.name;
+
+        if (block.isArray)
+        {
+            blockName += ArrayString(block.arrayElement);
+        }
+        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())
+    {
+        blockLinker->addShaderBlocks(GL_FRAGMENT_SHADER,
+                                     &state.getAttachedFragmentShader()->getUniformBlocks(context));
+    }
+
+    if (state.getAttachedComputeShader())
+    {
+        blockLinker->addShaderBlocks(GL_COMPUTE_SHADER,
+                                     &state.getAttachedComputeShader()->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())
+    {
+        blockLinker->addShaderBlocks(
+            GL_FRAGMENT_SHADER,
+            &state.getAttachedFragmentShader()->getShaderStorageBlocks(context));
+    }
+
+    if (state.getAttachedComputeShader())
+    {
+        blockLinker->addShaderBlocks(
+            GL_COMPUTE_SHADER, &state.getAttachedComputeShader()->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;
+    for (const auto &ref : varyings)
+    {
+        const sh::Varying *varying = ref.second.get();
+        if (varying->name == name)
+        {
+            var = varying;
+            break;
+        }
+        var = FindShaderVarField(*varying, name);
+        if (var != nullptr)
+        {
+            break;
+        }
+    }
+    return var;
+}
+
 }  // anonymous namespace
 
 const char *const g_fakepath = "C:\\fakepath";
 
+// InfoLog implementation.
 InfoLog::InfoLog()
 {
 }
 
 InfoLog::~InfoLog()
 {
 }
 
@@ -280,116 +409,138 @@ void InfoLog::appendSanitized(const char
     }
     while (found != std::string::npos);
 
     *mLazyStream << message << std::endl;
 }
 
 void InfoLog::reset()
 {
+    if (mLazyStream)
+    {
+        mLazyStream.reset(nullptr);
+    }
 }
 
-VariableLocation::VariableLocation() : element(0), index(kUnused), ignored(false)
+bool InfoLog::empty() const
+{
+    if (!mLazyStream)
+    {
+        return true;
+    }
+
+    return mLazyStream->rdbuf()->in_avail() == 0;
+}
+
+// VariableLocation implementation.
+VariableLocation::VariableLocation() : arrayIndex(0), index(kUnused), ignored(false)
 {
 }
 
-VariableLocation::VariableLocation(unsigned int element, unsigned int index)
-    : element(element), index(index), 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)
+    : textureType(textureTypeIn), boundTextureUnits(elementCount, 0), unreferenced(unreferenced)
 {
 }
 
-void Program::Bindings::bindLocation(GLuint index, const std::string &name)
+SamplerBinding::SamplerBinding(const SamplerBinding &other) = default;
+
+SamplerBinding::~SamplerBinding() = default;
+
+// ProgramBindings implementation.
+ProgramBindings::ProgramBindings()
+{
+}
+
+ProgramBindings::~ProgramBindings()
+{
+}
+
+void ProgramBindings::bindLocation(GLuint index, const std::string &name)
 {
     mBindings[name] = index;
 }
 
-int Program::Bindings::getBinding(const std::string &name) const
+int ProgramBindings::getBinding(const std::string &name) const
 {
     auto iter = mBindings.find(name);
     return (iter != mBindings.end()) ? iter->second : -1;
 }
 
-Program::Bindings::const_iterator Program::Bindings::begin() const
+ProgramBindings::const_iterator ProgramBindings::begin() const
 {
     return mBindings.begin();
 }
 
-Program::Bindings::const_iterator Program::Bindings::end() const
+ProgramBindings::const_iterator ProgramBindings::end() const
 {
     return mBindings.end();
 }
 
+// ImageBinding implementation.
+ImageBinding::ImageBinding(size_t count) : boundImageUnits(count, 0)
+{
+}
+ImageBinding::ImageBinding(GLuint imageUnit, size_t count)
+{
+    for (size_t index = 0; index < count; ++index)
+    {
+        boundImageUnits.push_back(imageUnit + static_cast<GLuint>(index));
+    }
+}
+
+ImageBinding::ImageBinding(const ImageBinding &other) = default;
+
+ImageBinding::~ImageBinding() = default;
+
+// ProgramState implementation.
 ProgramState::ProgramState()
     : mLabel(),
       mAttachedFragmentShader(nullptr),
       mAttachedVertexShader(nullptr),
       mAttachedComputeShader(nullptr),
+      mAttachedGeometryShader(nullptr),
       mTransformFeedbackBufferMode(GL_INTERLEAVED_ATTRIBS),
+      mMaxActiveAttribLocation(0),
       mSamplerUniformRange(0, 0),
       mImageUniformRange(0, 0),
       mAtomicCounterUniformRange(0, 0),
       mBinaryRetrieveableHint(false),
       mNumViews(-1)
 {
     mComputeShaderLocalSize.fill(1);
 }
 
 ProgramState::~ProgramState()
 {
-    ASSERT(!mAttachedVertexShader && !mAttachedFragmentShader && !mAttachedComputeShader);
+    ASSERT(!mAttachedVertexShader && !mAttachedFragmentShader && !mAttachedComputeShader &&
+           !mAttachedGeometryShader);
 }
 
 const std::string &ProgramState::getLabel()
 {
     return mLabel;
 }
 
-GLint ProgramState::getUniformLocation(const std::string &name) const
-{
-    size_t subscript     = GL_INVALID_INDEX;
-    std::string baseName = ParseResourceName(name, &subscript);
-
-    for (size_t location = 0; location < mUniformLocations.size(); ++location)
-    {
-        const VariableLocation &uniformLocation = mUniformLocations[location];
-        if (!uniformLocation.used())
-        {
-            continue;
-        }
-
-        const LinkedUniform &uniform = mUniforms[uniformLocation.index];
-
-        if (uniform.name == baseName)
-        {
-            if (uniform.isArray())
-            {
-                if (uniformLocation.element == subscript ||
-                    (uniformLocation.element == 0 && subscript == GL_INVALID_INDEX))
-                {
-                    return static_cast<GLint>(location);
-                }
-            }
-            else
-            {
-                if (subscript == GL_INVALID_INDEX)
-                {
-                    return static_cast<GLint>(location);
-                }
-            }
-        }
-    }
-
-    return -1;
-}
-
 GLuint ProgramState::getUniformIndexFromName(const std::string &name) const
 {
     return GetResourceIndexFromName(mUniforms, name);
 }
 
+GLuint ProgramState::getBufferVariableIndexFromName(const std::string &name) const
+{
+    return GetResourceIndexFromName(mBufferVariables, name);
+}
+
 GLuint ProgramState::getUniformIndexFromLocation(GLint location) const
 {
     ASSERT(location >= 0 && static_cast<size_t>(location) < mUniformLocations.size());
     return mUniformLocations[location].index;
 }
 
 Optional<GLuint> ProgramState::getSamplerIndex(GLint location) const
 {
@@ -460,20 +611,26 @@ void Program::onDestroy(const Context *c
     }
 
     if (mState.mAttachedComputeShader != nullptr)
     {
         mState.mAttachedComputeShader->release(context);
         mState.mAttachedComputeShader = nullptr;
     }
 
+    if (mState.mAttachedGeometryShader != nullptr)
+    {
+        mState.mAttachedGeometryShader->release(context);
+        mState.mAttachedGeometryShader = nullptr;
+    }
+
     mProgram->destroy(context);
 
     ASSERT(!mState.mAttachedVertexShader && !mState.mAttachedFragmentShader &&
-           !mState.mAttachedComputeShader);
+           !mState.mAttachedComputeShader && !mState.mAttachedGeometryShader);
     SafeDelete(mProgram);
 
     delete this;
 }
 
 void Program::setLabel(const std::string &label)
 {
     mState.mLabel = label;
@@ -504,16 +661,23 @@ void Program::attachShader(Shader *shade
         }
         case GL_COMPUTE_SHADER:
         {
             ASSERT(!mState.mAttachedComputeShader);
             mState.mAttachedComputeShader = shader;
             mState.mAttachedComputeShader->addRef();
             break;
         }
+        case GL_GEOMETRY_SHADER_EXT:
+        {
+            ASSERT(!mState.mAttachedGeometryShader);
+            mState.mAttachedGeometryShader = shader;
+            mState.mAttachedGeometryShader->addRef();
+            break;
+        }
         default:
             UNREACHABLE();
     }
 }
 
 void Program::detachShader(const Context *context, Shader *shader)
 {
     switch (shader->getType())
@@ -534,36 +698,42 @@ void Program::detachShader(const Context
         }
         case GL_COMPUTE_SHADER:
         {
             ASSERT(mState.mAttachedComputeShader == shader);
             shader->release(context);
             mState.mAttachedComputeShader = nullptr;
             break;
         }
+        case GL_GEOMETRY_SHADER_EXT:
+        {
+            ASSERT(mState.mAttachedGeometryShader == shader);
+            shader->release(context);
+            mState.mAttachedGeometryShader = nullptr;
+            break;
+        }
         default:
             UNREACHABLE();
     }
 }
 
 int Program::getAttachedShadersCount() const
 {
     return (mState.mAttachedVertexShader ? 1 : 0) + (mState.mAttachedFragmentShader ? 1 : 0) +
-           (mState.mAttachedComputeShader ? 1 : 0);
+           (mState.mAttachedComputeShader ? 1 : 0) + (mState.mAttachedGeometryShader ? 1 : 0);
 }
 
 void Program::bindAttributeLocation(GLuint index, const char *name)
 {
     mAttributeBindings.bindLocation(index, name);
 }
 
 void Program::bindUniformLocation(GLuint index, const char *name)
 {
-    // Bind the base uniform name only since array indices other than 0 cannot be bound
-    mUniformLocationBindings.bindLocation(index, ParseResourceName(name, nullptr));
+    mUniformLocationBindings.bindLocation(index, name);
 }
 
 void Program::bindFragmentInputLocation(GLint index, const char *name)
 {
     mFragmentInputBindings.bindLocation(index, name);
 }
 
 BindingInfo Program::getFragmentInputBindingInfo(const Context *context, GLint index) const
@@ -571,31 +741,32 @@ BindingInfo Program::getFragmentInputBin
     BindingInfo ret;
     ret.type  = GL_NONE;
     ret.valid = false;
 
     Shader *fragmentShader = mState.getAttachedFragmentShader();
     ASSERT(fragmentShader);
 
     // Find the actual fragment shader varying we're interested in
-    const std::vector<sh::Varying> &inputs = fragmentShader->getVaryings(context);
+    const std::vector<sh::Varying> &inputs = fragmentShader->getInputVaryings(context);
 
     for (const auto &binding : mFragmentInputBindings)
     {
         if (binding.second != static_cast<GLuint>(index))
             continue;
 
         ret.valid = true;
 
-        std::string originalName = binding.first;
-        unsigned int arrayIndex  = ParseAndStripArrayIndex(&originalName);
+        size_t nameLengthWithoutArrayIndex;
+        unsigned int arrayIndex = ParseArrayIndex(binding.first, &nameLengthWithoutArrayIndex);
 
         for (const auto &in : inputs)
         {
-            if (in.name == originalName)
+            if (in.name.length() == nameLengthWithoutArrayIndex &&
+                angle::BeginsWith(in.name, binding.first, nameLengthWithoutArrayIndex))
             {
                 if (in.isArray())
                 {
                     // The client wants to bind either "name" or "name[0]".
                     // GL ES 3.1 spec refers to active array names with language such as:
                     // "if the string identifies the base name of an active array, where the
                     // string would exactly match the name of the variable if the suffix "[0]"
                     // were appended to the string".
@@ -665,89 +836,50 @@ Error Program::link(const gl::Context *c
         ANGLE_HISTOGRAM_COUNTS("GPU.ANGLE.ProgramCache.ProgramCacheHitTimeUS", us);
         return NoError();
     }
 
     // Cache load failed, fall through to normal linking.
     unlink();
     mInfoLog.reset();
 
-    const Caps &caps = data.getCaps();
-
-    auto vertexShader   = mState.mAttachedVertexShader;
-    auto fragmentShader = mState.mAttachedFragmentShader;
-    auto computeShader  = mState.mAttachedComputeShader;
-
-    bool isComputeShaderAttached   = (computeShader != nullptr);
-    bool nonComputeShadersAttached = (vertexShader != nullptr || fragmentShader != nullptr);
-    // Check whether we both have a compute and non-compute shaders attached.
-    // If there are of both types attached, then linking should fail.
-    // OpenGL ES 3.10, 7.3 Program Objects, under LinkProgram
-    if (isComputeShaderAttached == true && nonComputeShadersAttached == true)
+    if (!linkValidateShaders(context, mInfoLog))
     {
-        mInfoLog << "Both a compute and non-compute shaders are attached to the same program.";
         return NoError();
     }
 
-    if (computeShader)
+    if (mState.mAttachedComputeShader)
     {
-        if (!computeShader->isCompiled(context))
-        {
-            mInfoLog << "Attached compute shader is not compiled.";
-            return NoError();
-        }
-        ASSERT(computeShader->getType() == GL_COMPUTE_SHADER);
-
-        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())
-        {
-            mInfoLog << "Work group size is not specified.";
-            return NoError();
-        }
-
         if (!linkUniforms(context, mInfoLog, mUniformLocationBindings))
         {
             return NoError();
         }
 
         if (!linkInterfaceBlocks(context, mInfoLog))
         {
             return NoError();
         }
 
-        gl::VaryingPacking noPacking(0, PackMode::ANGLE_RELAXED);
-        ANGLE_TRY_RESULT(mProgram->link(context, noPacking, mInfoLog), mLinked);
+        ProgramLinkedResources resources = {
+            {0, PackMode::ANGLE_RELAXED},
+            {&mState.mUniformBlocks, &mState.mUniforms},
+            {&mState.mShaderStorageBlocks, &mState.mBufferVariables},
+            {&mState.mAtomicCounterBuffers}};
+
+        InitUniformBlockLinker(context, mState, &resources.uniformBlockLinker);
+        InitShaderStorageBlockLinker(context, mState, &resources.shaderStorageBlockLinker);
+
+        ANGLE_TRY_RESULT(mProgram->link(context, resources, mInfoLog), mLinked);
         if (!mLinked)
         {
             return NoError();
         }
     }
     else
     {
-        if (!fragmentShader || !fragmentShader->isCompiled(context))
-        {
-            return NoError();
-        }
-        ASSERT(fragmentShader->getType() == GL_FRAGMENT_SHADER);
-
-        if (!vertexShader || !vertexShader->isCompiled(context))
-        {
-            return NoError();
-        }
-        ASSERT(vertexShader->getType() == GL_VERTEX_SHADER);
-
-        if (fragmentShader->getShaderVersion(context) != vertexShader->getShaderVersion(context))
-        {
-            mInfoLog << "Fragment shader version does not match vertex shader version.";
-            return NoError();
-        }
-
         if (!linkAttributes(context, mInfoLog))
         {
             return NoError();
         }
 
         if (!linkVaryings(context, mInfoLog))
         {
             return NoError();
@@ -765,90 +897,119 @@ Error Program::link(const gl::Context *c
 
         if (!linkValidateGlobalNames(context, mInfoLog))
         {
             return NoError();
         }
 
         const auto &mergedVaryings = getMergedVaryings(context);
 
-        mState.mNumViews = vertexShader->getNumViews(context);
+        ASSERT(mState.mAttachedVertexShader);
+        mState.mNumViews = mState.mAttachedVertexShader->getNumViews(context);
 
         linkOutputVariables(context);
 
-        // Validate we can pack the varyings.
-        std::vector<PackedVarying> packedVaryings = getPackedVaryings(mergedVaryings);
-
         // Map the varyings to the register file
         // In WebGL, we use a slightly different handling for packing variables.
         auto packMode = data.getExtensions().webglCompatibility ? PackMode::WEBGL_STRICT
                                                                 : PackMode::ANGLE_RELAXED;
-        VaryingPacking varyingPacking(data.getCaps().maxVaryingVectors, packMode);
-        if (!varyingPacking.packUserVaryings(mInfoLog, packedVaryings,
-                                             mState.getTransformFeedbackVaryingNames()))
+
+        ProgramLinkedResources resources = {
+            {data.getCaps().maxVaryingVectors, packMode},
+            {&mState.mUniformBlocks, &mState.mUniforms},
+            {&mState.mShaderStorageBlocks, &mState.mBufferVariables},
+            {&mState.mAtomicCounterBuffers}};
+
+        InitUniformBlockLinker(context, mState, &resources.uniformBlockLinker);
+        InitShaderStorageBlockLinker(context, mState, &resources.shaderStorageBlockLinker);
+
+        if (!linkValidateTransformFeedback(context, mInfoLog, mergedVaryings, context->getCaps()))
         {
             return NoError();
         }
 
-        if (!linkValidateTransformFeedback(context, mInfoLog, mergedVaryings, caps))
+        if (!resources.varyingPacking.collectAndPackUserVaryings(
+                mInfoLog, mergedVaryings, mState.getTransformFeedbackVaryingNames()))
         {
             return NoError();
         }
 
-        ANGLE_TRY_RESULT(mProgram->link(context, varyingPacking, mInfoLog), mLinked);
+        ANGLE_TRY_RESULT(mProgram->link(context, resources, mInfoLog), mLinked);
         if (!mLinked)
         {
             return NoError();
         }
 
         gatherTransformFeedbackVaryings(mergedVaryings);
     }
 
-    gatherAtomicCounterBuffers();
-    gatherInterfaceBlockInfo(context);
+    initInterfaceBlockBindings();
 
     setUniformValuesFromBindingQualifiers();
 
+    // According to GLES 3.0/3.1 spec for LinkProgram and UseProgram,
+    // Only successfully linked program can replace the executables.
+    ASSERT(mLinked);
+    updateLinkedShaderStages();
+
     // Mark implementation-specific unreferenced uniforms as ignored.
     mProgram->markUnusedUniformLocations(&mState.mUniformLocations, &mState.mSamplerBindings);
 
     // Save to the program cache.
     if (cache && (mState.mLinkedTransformFeedbackVaryings.empty() ||
                   !context->getWorkarounds().disableProgramCachingForTransformFeedback))
     {
         cache->putProgram(programHash, context, this);
     }
 
-    // Because we do lazy init in ensureUniformBlocksInitialized,
-    // we must initialize them when linking shaders,
-    // otherwise, we will have no shaders for getting uniform blocks
-    // information from shaders when doing draw calls.
-    mProgram->ensureUniformBlocksInitialized();
-
     double delta = platform->currentTime(platform) - startTime;
     int us       = static_cast<int>(delta * 1000000.0);
     ANGLE_HISTOGRAM_COUNTS("GPU.ANGLE.ProgramCache.ProgramCacheMissTimeUS", us);
 
     return NoError();
 }
 
+void Program::updateLinkedShaderStages()
+{
+    mState.mLinkedShaderStages.reset();
+
+    if (mState.mAttachedVertexShader)
+    {
+        mState.mLinkedShaderStages.set(SHADER_VERTEX);
+    }
+
+    if (mState.mAttachedFragmentShader)
+    {
+        mState.mLinkedShaderStages.set(SHADER_FRAGMENT);
+    }
+
+    if (mState.mAttachedComputeShader)
+    {
+        mState.mLinkedShaderStages.set(SHADER_COMPUTE);
+    }
+}
+
 // Returns the program object to an unlinked state, before re-linking, or at destruction
 void Program::unlink()
 {
     mState.mAttributes.clear();
+    mState.mAttributesTypeMask.reset();
+    mState.mAttributesMask.reset();
     mState.mActiveAttribLocationsMask.reset();
+    mState.mMaxActiveAttribLocation = 0;
     mState.mLinkedTransformFeedbackVaryings.clear();
     mState.mUniforms.clear();
     mState.mUniformLocations.clear();
     mState.mUniformBlocks.clear();
     mState.mActiveUniformBlockBindings.reset();
     mState.mAtomicCounterBuffers.clear();
     mState.mOutputVariables.clear();
     mState.mOutputLocations.clear();
     mState.mOutputVariableTypes.clear();
+    mState.mDrawBufferTypeMask.reset();
     mState.mActiveOutputVariables.reset();
     mState.mComputeShaderLocalSize.fill(1);
     mState.mSamplerBindings.clear();
     mState.mImageBindings.clear();
     mState.mNumViews = -1;
 
     mValidated = false;
 
@@ -1031,16 +1192,25 @@ void Program::getAttachedShaders(GLsizei
     {
         if (total < maxCount)
         {
             shaders[total] = mState.mAttachedFragmentShader->getHandle();
             total++;
         }
     }
 
+    if (mState.mAttachedGeometryShader)
+    {
+        if (total < maxCount)
+        {
+            shaders[total] = mState.mAttachedGeometryShader->getHandle();
+            total++;
+        }
+    }
+
     if (count)
     {
         *count = total;
     }
 }
 
 GLuint Program::getAttributeLocation(const std::string &name) const
 {
@@ -1114,103 +1284,105 @@ GLint Program::getActiveAttributeMaxLeng
         maxLength = std::max(attrib.name.length() + 1, maxLength);
     }
 
     return static_cast<GLint>(maxLength);
 }
 
 GLuint Program::getInputResourceIndex(const GLchar *name) const
 {
-    for (GLuint attributeIndex = 0; attributeIndex < mState.mAttributes.size(); ++attributeIndex)
-    {
-        const sh::Attribute &attribute = mState.mAttributes[attributeIndex];
-        if (attribute.name == name)
-        {
-            return attributeIndex;
-        }
-    }
-    return GL_INVALID_INDEX;
+    return GetResourceIndexFromName(mState.mAttributes, std::string(name));
 }
 
 GLuint Program::getOutputResourceIndex(const GLchar *name) const
 {
     return GetResourceIndexFromName(mState.mOutputVariables, std::string(name));
 }
 
 size_t Program::getOutputResourceCount() const
 {
     return (mLinked ? mState.mOutputVariables.size() : 0);
 }
 
-void Program::getInputResourceName(GLuint index,
-                                   GLsizei bufSize,
-                                   GLsizei *length,
-                                   GLchar *name) const
-{
-    GLint size;
-    GLenum type;
-    getActiveAttribute(index, bufSize, length, &size, &type, name);
-}
-
-void Program::getOutputResourceName(GLuint index,
-                                    GLsizei bufSize,
-                                    GLsizei *length,
-                                    GLchar *name) const
+template <typename T>
+void Program::getResourceName(GLuint index,
+                              const std::vector<T> &resources,
+                              GLsizei bufSize,
+                              GLsizei *length,
+                              GLchar *name) const
 {
     if (length)
     {
         *length = 0;
     }
 
     if (!mLinked)
     {
         if (bufSize > 0)
         {
             name[0] = '\0';
         }
         return;
     }
-    ASSERT(index < mState.mOutputVariables.size());
-    const auto &output = mState.mOutputVariables[index];
+    ASSERT(index < resources.size());
+    const auto &resource = resources[index];
 
     if (bufSize > 0)
     {
-        std::string nameWithArray = (output.isArray() ? output.name + "[0]" : output.name);
-
-        CopyStringToBuffer(name, nameWithArray, bufSize, length);
+        CopyStringToBuffer(name, resource.name, bufSize, length);
     }
 }
 
+void Program::getInputResourceName(GLuint index,
+                                   GLsizei bufSize,
+                                   GLsizei *length,
+                                   GLchar *name) const
+{
+    getResourceName(index, mState.mAttributes, bufSize, length, name);
+}
+
+void Program::getOutputResourceName(GLuint index,
+                                    GLsizei bufSize,
+                                    GLsizei *length,
+                                    GLchar *name) const
+{
+    getResourceName(index, mState.mOutputVariables, bufSize, length, name);
+}
+
+void Program::getUniformResourceName(GLuint index,
+                                     GLsizei bufSize,
+                                     GLsizei *length,
+                                     GLchar *name) const
+{
+    getResourceName(index, mState.mUniforms, bufSize, length, name);
+}
+
+void Program::getBufferVariableResourceName(GLuint index,
+                                            GLsizei bufSize,
+                                            GLsizei *length,
+                                            GLchar *name) const
+{
+    getResourceName(index, mState.mBufferVariables, bufSize, length, name);
+}
+
 const sh::Attribute &Program::getInputResource(GLuint index) const
 {
     ASSERT(index < mState.mAttributes.size());
     return mState.mAttributes[index];
 }
 
 const sh::OutputVariable &Program::getOutputResource(GLuint index) const
 {
     ASSERT(index < mState.mOutputVariables.size());
     return mState.mOutputVariables[index];
 }
 
 GLint Program::getFragDataLocation(const std::string &name) const
 {
-    std::string baseName(name);
-    unsigned int arrayIndex = ParseAndStripArrayIndex(&baseName);
-    for (auto outputPair : mState.mOutputLocations)
-    {
-        const VariableLocation &locationInfo     = outputPair.second;
-        const sh::OutputVariable &outputVariable = mState.mOutputVariables[locationInfo.index];
-        if (outputVariable.name == baseName &&
-            (arrayIndex == GL_INVALID_INDEX || arrayIndex == locationInfo.element))
-        {
-            return static_cast<GLint>(outputPair.first);
-        }
-    }
-    return -1;
+    return GetVariableLocation(mState.mOutputVariables, mState.mOutputLocations, name);
 }
 
 void Program::getActiveUniform(GLuint index,
                                GLsizei bufsize,
                                GLsizei *length,
                                GLint *size,
                                GLenum *type,
                                GLchar *name) const
@@ -1219,24 +1391,20 @@ void Program::getActiveUniform(GLuint in
     {
         // index must be smaller than getActiveUniformCount()
         ASSERT(index < mState.mUniforms.size());
         const LinkedUniform &uniform = mState.mUniforms[index];
 
         if (bufsize > 0)
         {
             std::string string = uniform.name;
-            if (uniform.isArray())
-            {
-                string += "[0]";
-            }
             CopyStringToBuffer(name, string, bufsize, length);
         }
 
-        *size = uniform.elementCount();
+        *size = clampCast<GLint>(uniform.getBasicTypeElementCount());
         *type = uniform.type;
     }
     else
     {
         if (bufsize > 0)
         {
             name[0] = '\0';
         }
@@ -1258,16 +1426,21 @@ GLint Program::getActiveUniformCount() c
         return static_cast<GLint>(mState.mUniforms.size());
     }
     else
     {
         return 0;
     }
 }
 
+size_t Program::getActiveBufferVariableCount() const
+{
+    return mLinked ? mState.mBufferVariables.size() : 0;
+}
+
 GLint Program::getActiveUniformMaxLength() const
 {
     size_t maxLength = 0;
 
     if (mLinked)
     {
         for (const LinkedUniform &uniform : mState.mUniforms)
         {
@@ -1281,38 +1454,16 @@ GLint Program::getActiveUniformMaxLength
                 maxLength = std::max(length, maxLength);
             }
         }
     }
 
     return static_cast<GLint>(maxLength);
 }
 
-GLint Program::getActiveUniformi(GLuint index, GLenum pname) const
-{
-    ASSERT(static_cast<size_t>(index) < mState.mUniforms.size());
-    const LinkedUniform &uniform = mState.mUniforms[index];
-    switch (pname)
-    {
-      case GL_UNIFORM_TYPE:         return static_cast<GLint>(uniform.type);
-      case GL_UNIFORM_SIZE:         return static_cast<GLint>(uniform.elementCount());
-      case GL_UNIFORM_NAME_LENGTH:  return static_cast<GLint>(uniform.name.size() + 1 + (uniform.isArray() ? 3 : 0));
-      case GL_UNIFORM_BLOCK_INDEX:
-          return uniform.bufferIndex;
-      case GL_UNIFORM_OFFSET:       return uniform.blockInfo.offset;
-      case GL_UNIFORM_ARRAY_STRIDE: return uniform.blockInfo.arrayStride;
-      case GL_UNIFORM_MATRIX_STRIDE: return uniform.blockInfo.matrixStride;
-      case GL_UNIFORM_IS_ROW_MAJOR: return static_cast<GLint>(uniform.blockInfo.isRowMajorMatrix);
-      default:
-        UNREACHABLE();
-        break;
-    }
-    return 0;
-}
-
 bool Program::isValidUniformLocation(GLint location) const
 {
     ASSERT(angle::IsValueInRangeForNumericType<GLint>(mState.mUniformLocations.size()));
     return (location >= 0 && static_cast<size_t>(location) < mState.mUniformLocations.size() &&
             mState.mUniformLocations[static_cast<size_t>(location)].used());
 }
 
 const LinkedUniform &Program::getUniformByLocation(GLint location) const
@@ -1333,19 +1484,25 @@ const std::vector<VariableLocation> &Pro
 }
 
 const LinkedUniform &Program::getUniformByIndex(GLuint index) const
 {
     ASSERT(index < static_cast<size_t>(mState.mUniforms.size()));
     return mState.mUniforms[index];
 }
 
+const BufferVariable &Program::getBufferVariableByIndex(GLuint index) const
+{
+    ASSERT(index < static_cast<size_t>(mState.mBufferVariables.size()));
+    return mState.mBufferVariables[index];
+}
+
 GLint Program::getUniformLocation(const std::string &name) const
 {
-    return mState.getUniformLocation(name);
+    return GetVariableLocation(mState.mUniforms, mState.mUniformLocations, name);
 }
 
 GLuint Program::getUniformIndex(const std::string &name) const
 {
     return mState.getUniformIndexFromName(name);
 }
 
 void Program::setUniform1fv(GLint location, GLsizei count, const GLfloat *v)
@@ -1557,17 +1714,17 @@ bool Program::isFlaggedForDeletion() con
 }
 
 void Program::validate(const Caps &caps)
 {
     mInfoLog.reset();
 
     if (mLinked)
     {
-        mValidated = (mProgram->validate(caps, &mInfoLog) == GL_TRUE);
+        mValidated = ConvertToBool(mProgram->validate(caps, &mInfoLog));
     }
     else
     {
         mInfoLog << "Program has not been successfully linked.";
     }
 }
 
 bool Program::validateSamplers(InfoLog *infoLog, const Caps &caps)
@@ -1644,39 +1801,41 @@ bool Program::isValidated() const
     return mValidated;
 }
 
 GLuint Program::getActiveUniformBlockCount() const
 {
     return static_cast<GLuint>(mState.mUniformBlocks.size());
 }
 
+GLuint Program::getActiveAtomicCounterBufferCount() const
+{
+    return static_cast<GLuint>(mState.mAtomicCounterBuffers.size());
+}
+
 GLuint Program::getActiveShaderStorageBlockCount() const
 {
     return static_cast<GLuint>(mState.mShaderStorageBlocks.size());
 }
 
-void Program::getActiveUniformBlockName(GLuint uniformBlockIndex, GLsizei bufSize, GLsizei *length, GLchar *uniformBlockName) const
+void Program::getActiveUniformBlockName(const GLuint blockIndex,
+                                        GLsizei bufSize,
+                                        GLsizei *length,
+                                        GLchar *blockName) const
 {
-    ASSERT(
-        uniformBlockIndex <
-        mState.mUniformBlocks.size());  // index must be smaller than getActiveUniformBlockCount()
-
-    const InterfaceBlock &uniformBlock = mState.mUniformBlocks[uniformBlockIndex];
-
-    if (bufSize > 0)
-    {
-        std::string string = uniformBlock.name;
-
-        if (uniformBlock.isArray)
-        {
-            string += ArrayString(uniformBlock.arrayElement);
-        }
-        CopyStringToBuffer(uniformBlockName, string, bufSize, length);
-    }
+    GetInterfaceBlockName(blockIndex, mState.mUniformBlocks, bufSize, length, blockName);
+}
+
+void Program::getActiveShaderStorageBlockName(const GLuint blockIndex,
+                                              GLsizei bufSize,
+                                              GLsizei *length,
+                                              GLchar *blockName) const
+{
+
+    GetInterfaceBlockName(blockIndex, mState.mShaderStorageBlocks, bufSize, length, blockName);
 }
 
 GLint Program::getActiveUniformBlockMaxLength() const
 {
     int maxLength = 0;
 
     if (mLinked)
     {
@@ -1692,44 +1851,36 @@ GLint Program::getActiveUniformBlockMaxL
         }
     }
 
     return maxLength;
 }
 
 GLuint Program::getUniformBlockIndex(const std::string &name) const
 {
-    size_t subscript     = GL_INVALID_INDEX;
-    std::string baseName = ParseResourceName(name, &subscript);
-
-    unsigned int numUniformBlocks = static_cast<unsigned int>(mState.mUniformBlocks.size());
-    for (unsigned int blockIndex = 0; blockIndex < numUniformBlocks; blockIndex++)
-    {
-        const InterfaceBlock &uniformBlock = mState.mUniformBlocks[blockIndex];
-        if (uniformBlock.name == baseName)
-        {
-            const bool arrayElementZero =
-                (subscript == GL_INVALID_INDEX &&
-                 (!uniformBlock.isArray || uniformBlock.arrayElement == 0));
-            if (subscript == uniformBlock.arrayElement || arrayElementZero)
-            {
-                return blockIndex;
-            }
-        }
-    }
-
-    return GL_INVALID_INDEX;
+    return GetInterfaceBlockIndex(mState.mUniformBlocks, name);
+}
+
+GLuint Program::getShaderStorageBlockIndex(const std::string &name) const
+{
+    return GetInterfaceBlockIndex(mState.mShaderStorageBlocks, name);
 }
 
 const InterfaceBlock &Program::getUniformBlockByIndex(GLuint index) const
 {
     ASSERT(index < static_cast<GLuint>(mState.mUniformBlocks.size()));
     return mState.mUniformBlocks[index];
 }
 
+const InterfaceBlock &Program::getShaderStorageBlockByIndex(GLuint index) const
+{
+    ASSERT(index < static_cast<GLuint>(mState.mShaderStorageBlocks.size()));
+    return mState.mShaderStorageBlocks[index];
+}
+
 void Program::bindUniformBlock(GLuint uniformBlockIndex, GLuint uniformBlockBinding)
 {
     mState.mUniformBlocks[uniformBlockIndex].binding = uniformBlockBinding;
     mState.mActiveUniformBlockBindings.set(uniformBlockIndex, uniformBlockBinding != 0);
     mProgram->setUniformBlockBinding(uniformBlockIndex, uniformBlockBinding);
 }
 
 GLuint Program::getUniformBlockBinding(GLuint uniformBlockIndex) const
@@ -1812,25 +1963,106 @@ GLsizei Program::getTransformFeedbackVar
     }
 }
 
 GLenum Program::getTransformFeedbackBufferMode() const
 {
     return mState.mTransformFeedbackBufferMode;
 }
 
+bool Program::linkValidateShaders(const Context *context, InfoLog &infoLog)
+{
+    Shader *vertexShader   = mState.mAttachedVertexShader;
+    Shader *fragmentShader = mState.mAttachedFragmentShader;
+    Shader *computeShader  = mState.mAttachedComputeShader;
+
+    bool isComputeShaderAttached  = (computeShader != nullptr);
+    bool isGraphicsShaderAttached = (vertexShader != nullptr || fragmentShader != nullptr);
+    // Check whether we both have a compute and non-compute shaders attached.
+    // If there are of both types attached, then linking should fail.
+    // OpenGL ES 3.10, 7.3 Program Objects, under LinkProgram
+    if (isComputeShaderAttached == true && isGraphicsShaderAttached == true)
+    {
+        infoLog << "Both compute and graphics shaders are attached to the same program.";
+        return false;
+    }
+
+    if (computeShader)
+    {
+        if (!computeShader->isCompiled(context))
+        {
+            infoLog << "Attached compute shader is not compiled.";
+            return false;
+        }
+        ASSERT(computeShader->getType() == GL_COMPUTE_SHADER);
+
+        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.";
+            return false;
+        }
+    }
+    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);
+
+        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);
+
+        if (fragmentShader->getShaderVersion(context) != vertexShader->getShaderVersion(context))
+        {
+            infoLog << "Fragment shader version does not match vertex shader version.";
+            return false;
+        }
+    }
+
+    return true;
+}
+
+GLuint Program::getTransformFeedbackVaryingResourceIndex(const GLchar *name) const
+{
+    for (GLuint tfIndex = 0; tfIndex < mState.mLinkedTransformFeedbackVaryings.size(); ++tfIndex)
+    {
+        const auto &tf = mState.mLinkedTransformFeedbackVaryings[tfIndex];
+        if (tf.nameWithArrayIndex() == name)
+        {
+            return tfIndex;
+        }
+    }
+    return GL_INVALID_INDEX;
+}
+
+const TransformFeedbackVarying &Program::getTransformFeedbackVaryingResource(GLuint index) const
+{
+    ASSERT(index < mState.mLinkedTransformFeedbackVaryings.size());
+    return mState.mLinkedTransformFeedbackVaryings[index];
+}
+
 bool Program::linkVaryings(const Context *context, InfoLog &infoLog) const
 {
     Shader *vertexShader   = mState.mAttachedVertexShader;
     Shader *fragmentShader = mState.mAttachedFragmentShader;
 
     ASSERT(vertexShader->getShaderVersion(context) == fragmentShader->getShaderVersion(context));
 
-    const std::vector<sh::Varying> &vertexVaryings   = vertexShader->getVaryings(context);
-    const std::vector<sh::Varying> &fragmentVaryings = fragmentShader->getVaryings(context);
+    const std::vector<sh::Varying> &vertexVaryings   = vertexShader->getOutputVaryings(context);
+    const std::vector<sh::Varying> &fragmentVaryings = fragmentShader->getInputVaryings(context);
 
     std::map<GLuint, std::string> staticFragmentInputLocations;
 
     for (const sh::Varying &output : fragmentVaryings)
     {
         bool matched = false;
 
         // Built-in varyings obey special rules
@@ -1839,17 +2071,17 @@ bool Program::linkVaryings(const Context
             continue;
         }
 
         for (const sh::Varying &input : vertexVaryings)
         {
             if (output.name == input.name)
             {
                 ASSERT(!input.isBuiltIn());
-                if (!linkValidateVaryings(infoLog, output.name, input, output,
+                if (!LinkValidateVaryings(infoLog, output.name, input, output,
                                           vertexShader->getShaderVersion(context)))
                 {
                     return false;
                 }
 
                 matched = true;
                 break;
             }
@@ -1893,17 +2125,17 @@ bool Program::linkVaryings(const Context
 
     // TODO(jmadill): verify no unmatched vertex varyings?
 
     return true;
 }
 
 bool Program::linkUniforms(const Context *context,
                            InfoLog &infoLog,
-                           const Bindings &uniformLocationBindings)
+                           const ProgramBindings &uniformLocationBindings)
 {
     UniformLinker linker(mState);
     if (!linker.link(context, infoLog, uniformLocationBindings))
     {
         return false;
     }
 
     linker.getResults(&mState.mUniforms, &mState.mUniformLocations);
@@ -1946,22 +2178,23 @@ void Program::linkSamplerAndImageBinding
     {
         // ES3.1 (section 7.6.1) and GLSL ES3.1 (section 4.4.5), Uniform*i{v} commands
         // cannot load values into a uniform defined as an image. if declare without a
         // binding qualifier, any uniform image variable (include all elements of
         // unbound image array) shoud be bound to unit zero.
         auto &imageUniform = mState.mUniforms[imageIndex];
         if (imageUniform.binding == -1)
         {
-            mState.mImageBindings.emplace_back(ImageBinding(imageUniform.elementCount()));
+            mState.mImageBindings.emplace_back(
+                ImageBinding(imageUniform.getBasicTypeElementCount()));
         }
         else
         {
             mState.mImageBindings.emplace_back(
-                ImageBinding(imageUniform.binding, imageUniform.elementCount()));
+                ImageBinding(imageUniform.binding, imageUniform.getBasicTypeElementCount()));
         }
     }
 
     high = low;
 
     for (auto samplerIter = mState.mUniforms.rbegin() + mState.mImageUniformRange.length();
          samplerIter != mState.mUniforms.rend() && samplerIter->isSampler(); ++samplerIter)
     {
@@ -1971,61 +2204,68 @@ 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);
         mState.mSamplerBindings.emplace_back(
-            SamplerBinding(textureType, samplerUniform.elementCount(), false));
+            SamplerBinding(textureType, samplerUniform.getBasicTypeElementCount(), false));
     }
 }
 
 bool Program::linkAtomicCounterBuffers()
 {
     for (unsigned int index : mState.mAtomicCounterUniformRange)
     {
         auto &uniform = mState.mUniforms[index];
+        uniform.blockInfo.offset           = uniform.offset;
+        uniform.blockInfo.arrayStride      = (uniform.isArray() ? 4 : 0);
+        uniform.blockInfo.matrixStride     = 0;
+        uniform.blockInfo.isRowMajorMatrix = false;
+
         bool found    = false;
         for (unsigned int bufferIndex = 0; bufferIndex < mState.mAtomicCounterBuffers.size();
              ++bufferIndex)
         {
             auto &buffer = mState.mAtomicCounterBuffers[bufferIndex];
             if (buffer.binding == uniform.binding)
             {
                 buffer.memberIndexes.push_back(index);
                 uniform.bufferIndex = bufferIndex;
                 found               = true;
+                buffer.unionReferencesWith(uniform);
                 break;
             }
         }
         if (!found)
         {
             AtomicCounterBuffer atomicCounterBuffer;
             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.
 
     return true;
 }
 
-bool Program::linkValidateInterfaceBlockFields(InfoLog &infoLog,
+bool Program::LinkValidateInterfaceBlockFields(InfoLog &infoLog,
                                                const std::string &uniformName,
                                                const sh::InterfaceBlockField &vertexUniform,
                                                const sh::InterfaceBlockField &fragmentUniform,
                                                bool webglCompatibility)
 {
     // If webgl, validate precision of UBO fields, otherwise don't.  See Khronos bug 10287.
-    if (!linkValidateVariablesBase(infoLog, uniformName, vertexUniform, fragmentUniform,
+    if (!LinkValidateVariablesBase(infoLog, uniformName, vertexUniform, fragmentUniform,
                                    webglCompatibility))
     {
         return false;
     }
 
     if (vertexUniform.isRowMajorLayout != fragmentUniform.isRowMajorLayout)
     {
         infoLog << "Matrix packings for " << uniformName << " differ between vertex and fragment shaders";
@@ -2052,16 +2292,21 @@ bool Program::linkAttributes(const Conte
         return false;
     }
 
     std::vector<sh::Attribute *> usedAttribMap(maxAttribs, nullptr);
 
     // Link attributes that have a binding location
     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);
         if (attribute.location == -1 && bindingLocation != -1)
         {
             attribute.location = bindingLocation;
         }
 
         if (attribute.location != -1)
         {
@@ -2117,52 +2362,66 @@ bool Program::linkAttributes(const Conte
                 infoLog << "Too many active attributes (" << attribute.name << ")";
                 return false;
             }
 
             attribute.location = availableIndex;
         }
     }
 
+    ASSERT(mState.mAttributesTypeMask.none());
+    ASSERT(mState.mAttributesMask.none());
+
     for (const sh::Attribute &attribute : mState.mAttributes)
     {
         ASSERT(attribute.location != -1);
-        int regs = VariableRegisterCount(attribute.type);
-
-        for (int r = 0; r < regs; r++)
+        unsigned int regs = static_cast<unsigned int>(VariableRegisterCount(attribute.type));
+
+        for (unsigned int r = 0; r < regs; r++)
         {
-            mState.mActiveAttribLocationsMask.set(attribute.location + r);
+            unsigned int location = static_cast<unsigned int>(attribute.location) + r;
+            mState.mActiveAttribLocationsMask.set(location);
+            mState.mMaxActiveAttribLocation =
+                std::max(mState.mMaxActiveAttribLocation, location + 1);
+
+            // gl_VertexID and gl_InstanceID are active attributes but don't have a bound attribute.
+            if (!attribute.isBuiltIn())
+            {
+                mState.mAttributesTypeMask.setIndex(VariableComponentType(attribute.type),
+                                                    location);
+                mState.mAttributesMask.set(location);
+            }
         }
     }
 
     return true;
 }
 
-bool Program::validateVertexAndFragmentInterfaceBlocks(
+bool Program::ValidateGraphicsInterfaceBlocks(
     const std::vector<sh::InterfaceBlock> &vertexInterfaceBlocks,
     const std::vector<sh::InterfaceBlock> &fragmentInterfaceBlocks,
     InfoLog &infoLog,
-    bool webglCompatibility) const
+    bool webglCompatibility)
 {
     // Check that interface blocks defined in the vertex and fragment shaders are identical
     typedef std::map<std::string, const sh::InterfaceBlock *> InterfaceBlockMap;
     InterfaceBlockMap linkedInterfaceBlocks;
 
     for (const sh::InterfaceBlock &vertexInterfaceBlock : vertexInterfaceBlocks)
     {
         linkedInterfaceBlocks[vertexInterfaceBlock.name] = &vertexInterfaceBlock;
     }
 
     for (const sh::InterfaceBlock &fragmentInterfaceBlock : fragmentInterfaceBlocks)
     {
         auto entry = linkedInterfaceBlocks.find(fragmentInterfaceBlock.name);
         if (entry != linkedInterfaceBlocks.end())
         {
             const sh::InterfaceBlock &vertexInterfaceBlock = *entry->second;
-            if (!areMatchingInterfaceBlocks(infoLog, vertexInterfaceBlock, fragmentInterfaceBlock,
+            if (!AreMatchingInterfaceBlocks(infoLog, vertexInterfaceBlock, fragmentInterfaceBlock,
                                             webglCompatibility))
             {
                 return false;
             }
         }
         // TODO(jiajia.qin@intel.com): Add
         // MAX_COMBINED_UNIFORM_BLOCKS/MAX_COMBINED_SHADER_STORAGE_BLOCKS validation.
     }
@@ -2215,18 +2474,18 @@ bool Program::linkInterfaceBlocks(const 
             "Fragment shader uniform block count exceeds GL_MAX_FRAGMENT_UNIFORM_BLOCKS (",
             infoLog))
     {
 
         return false;
     }
 
     bool webglCompatibility = context->getExtensions().webglCompatibility;
-    if (!validateVertexAndFragmentInterfaceBlocks(vertexUniformBlocks, fragmentUniformBlocks,
-                                                  infoLog, webglCompatibility))
+    if (!ValidateGraphicsInterfaceBlocks(vertexUniformBlocks, fragmentUniformBlocks, infoLog,
+                                         webglCompatibility))
     {
         return false;
     }
 
     if (context->getClientVersion() >= Version(3, 1))
     {
         const auto &vertexShaderStorageBlocks   = vertexShader.getShaderStorageBlocks(context);
         const auto &fragmentShaderStorageBlocks = fragmentShader.getShaderStorageBlocks(context);
@@ -2244,47 +2503,45 @@ bool Program::linkInterfaceBlocks(const 
                                           "Fragment shader shader storage block count exceeds "
                                           "GL_MAX_FRAGMENT_SHADER_STORAGE_BLOCKS (",
                                           infoLog))
         {
 
             return false;
         }
 
-        if (!validateVertexAndFragmentInterfaceBlocks(vertexShaderStorageBlocks,
-                                                      fragmentShaderStorageBlocks, infoLog,
-                                                      webglCompatibility))
+        if (!ValidateGraphicsInterfaceBlocks(vertexShaderStorageBlocks, fragmentShaderStorageBlocks,
+                                             infoLog, webglCompatibility))
         {
             return false;
         }
     }
     return true;
 }
 
-bool Program::areMatchingInterfaceBlocks(InfoLog &infoLog,
+bool Program::AreMatchingInterfaceBlocks(InfoLog &infoLog,
                                          const sh::InterfaceBlock &vertexInterfaceBlock,
                                          const sh::InterfaceBlock &fragmentInterfaceBlock,
-                                         bool webglCompatibility) const
+                                         bool webglCompatibility)
 {
-    const char* blockName = vertexInterfaceBlock.name.c_str();
+    const char *blockName = vertexInterfaceBlock.name.c_str();
     // validate blocks for the same member types
     if (vertexInterfaceBlock.fields.size() != fragmentInterfaceBlock.fields.size())
     {
         infoLog << "Types for interface block '" << blockName
                 << "' differ between vertex and fragment shaders";
         return false;
     }
     if (vertexInterfaceBlock.arraySize != fragmentInterfaceBlock.arraySize)
     {
         infoLog << "Array sizes differ for interface block '" << blockName
                 << "' between vertex and fragment shaders";
         return false;
     }
     if (vertexInterfaceBlock.layout != fragmentInterfaceBlock.layout ||
-        vertexInterfaceBlock.isRowMajorLayout != fragmentInterfaceBlock.isRowMajorLayout ||
         vertexInterfaceBlock.binding != fragmentInterfaceBlock.binding)
     {
         infoLog << "Layout qualifiers differ for interface block '" << blockName
                 << "' between vertex and fragment shaders";
         return false;
     }
     const unsigned int numBlockMembers =
         static_cast<unsigned int>(vertexInterfaceBlock.fields.size());
@@ -2296,34 +2553,37 @@ bool Program::areMatchingInterfaceBlocks
         {
             infoLog << "Name mismatch for field " << blockMemberIndex
                     << " of interface block '" << blockName
                     << "': (in vertex: '" << vertexMember.name
                     << "', in fragment: '" << fragmentMember.name << "')";
             return false;
         }
         std::string memberName = "interface block '" + vertexInterfaceBlock.name + "' member '" + vertexMember.name + "'";
-        if (!linkValidateInterfaceBlockFields(infoLog, memberName, vertexMember, fragmentMember,
+        if (!LinkValidateInterfaceBlockFields(infoLog, memberName, vertexMember, fragmentMember,
                                               webglCompatibility))
         {
             return false;
         }
     }
     return true;
 }
 
-bool Program::linkValidateVariablesBase(InfoLog &infoLog, const std::string &variableName, const sh::ShaderVariable &vertexVariable,
-                                              const sh::ShaderVariable &fragmentVariable, bool validatePrecision)
+bool Program::LinkValidateVariablesBase(InfoLog &infoLog,
+                                        const std::string &variableName,
+                                        const sh::ShaderVariable &vertexVariable,
+                                        const sh::ShaderVariable &fragmentVariable,
+                                        bool validatePrecision)
 {
     if (vertexVariable.type != fragmentVariable.type)
     {
         infoLog << "Types for " << variableName << " differ between vertex and fragment shaders";
         return false;
     }
-    if (vertexVariable.arraySize != fragmentVariable.arraySize)
+    if (vertexVariable.arraySizes != fragmentVariable.arraySizes)
     {
         infoLog << "Array sizes for " << variableName << " differ between vertex and fragment shaders";
         return false;
     }
     if (validatePrecision && vertexVariable.precision != fragmentVariable.precision)
     {
         infoLog << "Precisions for " << variableName << " differ between vertex and fragment shaders";
         return false;
@@ -2353,32 +2613,33 @@ bool Program::linkValidateVariablesBase(
                     << ": (in vertex: '" << vertexMember.name
                     << "', in fragment: '" << fragmentMember.name << "')";
             return false;
         }
 
         const std::string memberName = variableName.substr(0, variableName.length() - 1) + "." +
                                        vertexMember.name + "'";
 
-        if (!linkValidateVariablesBase(infoLog, vertexMember.name, vertexMember, fragmentMember, validatePrecision))
+        if (!LinkValidateVariablesBase(infoLog, vertexMember.name, vertexMember, fragmentMember,
+                                       validatePrecision))
         {
             return false;
         }
     }
 
     return true;
 }
 
-bool Program::linkValidateVaryings(InfoLog &infoLog,
+bool Program::LinkValidateVaryings(InfoLog &infoLog,
                                    const std::string &varyingName,
                                    const sh::Varying &vertexVarying,
                                    const sh::Varying &fragmentVarying,
                                    int shaderVersion)
 {
-    if (!linkValidateVariablesBase(infoLog, varyingName, vertexVarying, fragmentVarying, false))
+    if (!LinkValidateVariablesBase(infoLog, varyingName, vertexVarying, fragmentVarying, false))
     {
         return false;
     }
 
     if (!sh::InterpolationTypesMatch(vertexVarying.interpolation, fragmentVarying.interpolation))
     {
         infoLog << "Interpolation types for " << varyingName
                 << " differ between vertex and fragment shaders.";
@@ -2394,18 +2655,18 @@ bool Program::linkValidateVaryings(InfoL
 
     return true;
 }
 
 bool Program::linkValidateBuiltInVaryings(const Context *context, InfoLog &infoLog) const
 {
     Shader *vertexShader         = mState.mAttachedVertexShader;
     Shader *fragmentShader       = mState.mAttachedFragmentShader;
-    const auto &vertexVaryings   = vertexShader->getVaryings(context);
-    const auto &fragmentVaryings = fragmentShader->getVaryings(context);
+    const auto &vertexVaryings   = vertexShader->getOutputVaryings(context);
+    const auto &fragmentVaryings = fragmentShader->getInputVaryings(context);
     int shaderVersion            = vertexShader->getShaderVersion(context);
 
     if (shaderVersion != 100)
     {
         // Only ESSL 1.0 has restrictions on matching input and output invariance
         return true;
     }
 
@@ -2463,98 +2724,126 @@ bool Program::linkValidateBuiltInVarying
         return false;
     }
 
     return true;
 }
 
 bool Program::linkValidateTransformFeedback(const gl::Context *context,
                                             InfoLog &infoLog,
-                                            const Program::MergedVaryings &varyings,
+                                            const ProgramMergedVaryings &varyings,
                                             const Caps &caps) const
 {
-    size_t totalComponents = 0;
-
+
+    // Validate the tf names regardless of the actual program varyings.
     std::set<std::string> uniqueNames;
-
     for (const std::string &tfVaryingName : mState.mTransformFeedbackVaryingNames)
     {
-        bool found = false;
-        size_t subscript     = GL_INVALID_INDEX;
-        std::string baseName = ParseResourceName(tfVaryingName, &subscript);
-
-        for (const auto &ref : varyings)
-        {
-            const sh::Varying *varying = ref.second.get();
-
-            if (baseName == varying->name)
-            {
-                if (uniqueNames.count(tfVaryingName) > 0)
-                {
-                    infoLog << "Two transform feedback varyings specify the same output variable ("
-                            << tfVaryingName << ").";
-                    return false;
-                }
-                if (context->getClientVersion() >= Version(3, 1))
-                {
-                    if (IncludeSameArrayElement(uniqueNames, tfVaryingName))
-                    {
-                        infoLog
-                            << "Two transform feedback varyings include the same array element ("
-                            << tfVaryingName << ").";
-                        return false;
-                    }
-                }
-                else if (varying->isArray())
-                {
-                    infoLog << "Capture of arrays is undefined and not supported.";
-                    return false;
-                }
-
-                uniqueNames.insert(tfVaryingName);
-
-                // TODO(jmadill): Investigate implementation limits on D3D11
-                size_t elementCount =
-                    ((varying->isArray() && subscript == GL_INVALID_INDEX) ? varying->elementCount()
-                                                                           : 1);
-                size_t componentCount = VariableComponentCount(varying->type) * elementCount;
-                if (mState.mTransformFeedbackBufferMode == GL_SEPARATE_ATTRIBS &&
-                    componentCount > caps.maxTransformFeedbackSeparateComponents)
-                {
-                    infoLog << "Transform feedback varying's " << varying->name << " components ("
-                            << componentCount << ") exceed the maximum separate components ("
-                            << caps.maxTransformFeedbackSeparateComponents << ").";
-                    return false;
-                }
-
-                totalComponents += componentCount;
-                found = true;
-                break;
-            }
-        }
         if (context->getClientVersion() < Version(3, 1) &&
             tfVaryingName.find('[') != std::string::npos)
         {
             infoLog << "Capture of array elements is undefined and not supported.";
             return false;
         }
-        // All transform feedback varyings are expected to exist since packUserVaryings checks for
-        // them.
-        ASSERT(found);
+        if (context->getClientVersion() >= Version(3, 1))
+        {
+            if (IncludeSameArrayElement(uniqueNames, tfVaryingName))
+            {
+                infoLog << "Two transform feedback varyings include the same array element ("
+                        << tfVaryingName << ").";
+                return false;
+            }
+        }
+        else
+        {
+            if (uniqueNames.count(tfVaryingName) > 0)
+            {
+                infoLog << "Two transform feedback varyings specify the same output variable ("
+                        << tfVaryingName << ").";
+                return false;
+            }
+        }
+        uniqueNames.insert(tfVaryingName);
     }
 
-    if (mState.mTransformFeedbackBufferMode == GL_INTERLEAVED_ATTRIBS &&
-        totalComponents > caps.maxTransformFeedbackInterleavedComponents)
+    // Validate against program varyings.
+    size_t totalComponents = 0;
+    for (const std::string &tfVaryingName : mState.mTransformFeedbackVaryingNames)
     {
-        infoLog << "Transform feedback varying total components (" << totalComponents
-                << ") exceed the maximum interleaved components ("
-                << caps.maxTransformFeedbackInterleavedComponents << ").";
-        return false;
+        std::vector<unsigned int> subscripts;
+        std::string baseName = ParseResourceName(tfVaryingName, &subscripts);
+
+        const sh::ShaderVariable *var = FindVaryingOrField(varyings, baseName);
+        if (var == nullptr)
+        {
+            infoLog << "Transform feedback varying " << tfVaryingName
+                    << " does not exist in the vertex shader.";
+            return false;
+        }
+
+        // Validate the matching variable.
+        if (var->isStruct())
+        {
+            infoLog << "Struct cannot be captured directly (" << baseName << ").";
+            return false;
+        }
+
+        size_t elementCount   = 0;
+        size_t componentCount = 0;
+
+        if (var->isArray())
+        {
+            if (context->getClientVersion() < Version(3, 1))
+            {
+                infoLog << "Capture of arrays is undefined and not supported.";
+                return false;
+            }
+
+            // GLSL ES 3.10 section 4.3.6: A vertex output can't be an array of arrays.
+            ASSERT(!var->isArrayOfArrays());
+
+            if (!subscripts.empty() && subscripts[0] >= var->getOutermostArraySize())
+            {
+                infoLog << "Cannot capture outbound array element '" << tfVaryingName << "'.";
+                return false;
+            }
+            elementCount = (subscripts.empty() ? var->getOutermostArraySize() : 1);
+        }
+        else
+        {
+            if (!subscripts.empty())
+            {
+                infoLog << "Varying '" << baseName
+                        << "' is not an array to be captured by element.";
+                return false;
+            }
+            elementCount = 1;
+        }
+
+        // TODO(jmadill): Investigate implementation limits on D3D11
+        componentCount = VariableComponentCount(var->type) * elementCount;
+        if (mState.mTransformFeedbackBufferMode == GL_SEPARATE_ATTRIBS &&
+            componentCount > caps.maxTransformFeedbackSeparateComponents)
+        {
+            infoLog << "Transform feedback varying " << tfVaryingName << " components ("
+                    << componentCount << ") exceed the maximum separate components ("
+                    << caps.maxTransformFeedbackSeparateComponents << ").";
+            return false;
+        }
+
+        totalComponents += componentCount;
+        if (mState.mTransformFeedbackBufferMode == GL_INTERLEAVED_ATTRIBS &&
+            totalComponents > caps.maxTransformFeedbackInterleavedComponents)
+        {
+            infoLog << "Transform feedback varying total components (" << totalComponents
+                    << ") exceed the maximum interleaved components ("
+                    << caps.maxTransformFeedbackInterleavedComponents << ").";
+            return false;
+        }
     }
-
     return true;
 }
 
 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 =
@@ -2578,514 +2867,203 @@ bool Program::linkValidateGlobalNames(co
                 infoLog << "Name conflicts between a uniform and an attribute: " << attrib.name;
                 return false;
             }
         }
     }
     return true;
 }
 
-void Program::gatherTransformFeedbackVaryings(const Program::MergedVaryings &varyings)
+void Program::gatherTransformFeedbackVaryings(const ProgramMergedVaryings &varyings)
 {
     // Gather the linked varyings that are used for transform feedback, they should all exist.
     mState.mLinkedTransformFeedbackVaryings.clear();
     for (const std::string &tfVaryingName : mState.mTransformFeedbackVaryingNames)
     {
+        std::vector<unsigned int> subscripts;
+        std::string baseName = ParseResourceName(tfVaryingName, &subscripts);
         size_t subscript     = GL_INVALID_INDEX;
-        std::string baseName = ParseResourceName(tfVaryingName, &subscript);
+        if (!subscripts.empty())
+        {
+            subscript = subscripts.back();
+        }
         for (const auto &ref : varyings)
         {
             const sh::Varying *varying = ref.second.get();
             if (baseName == varying->name)
             {
                 mState.mLinkedTransformFeedbackVaryings.emplace_back(
                     *varying, static_cast<GLuint>(subscript));
                 break;
             }
+            else if (varying->isStruct())
+            {
+                const auto *field = FindShaderVarField(*varying, tfVaryingName);
+                if (field != nullptr)
+                {
+                    mState.mLinkedTransformFeedbackVaryings.emplace_back(*field, *varying);
+                    break;
+                }
+            }
         }
     }
 }
 
-Program::MergedVaryings Program::getMergedVaryings(const Context *context) const
+ProgramMergedVaryings Program::getMergedVaryings(const Context *context) const
 {
-    MergedVaryings merged;
-
-    for (const sh::Varying &varying : mState.mAttachedVertexShader->getVaryings(context))
+    ProgramMergedVaryings merged;
+
+    for (const sh::Varying &varying : mState.mAttachedVertexShader->getOutputVaryings(context))
     {
         merged[varying.name].vertex = &varying;
     }
 
-    for (const sh::Varying &varying : mState.mAttachedFragmentShader->getVaryings(context))
+    for (const sh::Varying &varying : mState.mAttachedFragmentShader->getInputVaryings(context))
     {
         merged[varying.name].fragment = &varying;
     }
 
     return merged;
 }
 
-std::vector<PackedVarying> Program::getPackedVaryings(
-    const Program::MergedVaryings &mergedVaryings) const
-{
-    const std::vector<std::string> &tfVaryings = mState.getTransformFeedbackVaryingNames();
-    std::vector<PackedVarying> packedVaryings;
-    std::set<std::string> uniqueFullNames;
-
-    for (const auto &ref : mergedVaryings)
-    {
-        const sh::Varying *input  = ref.second.vertex;
-        const sh::Varying *output = ref.second.fragment;
-
-        // Only pack varyings that have a matched input or output, plus special builtins.
-        if ((input && output) || (output && output->isBuiltIn()))
-        {
-            // Will get the vertex shader interpolation by default.
-            auto interpolation = ref.second.get()->interpolation;
-
-            // Note that we lose the vertex shader static use information here. The data for the
-            // variable is taken from the fragment shader.
-            if (output->isStruct())
-            {
-                ASSERT(!output->isArray());
-                for (const auto &field : output->fields)
-                {
-                    ASSERT(!field.isStruct() && !field.isArray());
-                    packedVaryings.push_back(PackedVarying(field, interpolation, output->name));
-                }
-            }
-            else
-            {
-                packedVaryings.push_back(PackedVarying(*output, interpolation));
-            }
-            continue;
-        }
-
-        // Keep Transform FB varyings in the merged list always.
-        if (!input)
-        {
-            continue;
-        }
-
-        for (const std::string &tfVarying : tfVaryings)
-        {
-            size_t subscript     = GL_INVALID_INDEX;
-            std::string baseName = ParseResourceName(tfVarying, &subscript);
-            if (uniqueFullNames.count(tfVarying) > 0)
-            {
-                continue;
-            }
-            if (baseName == input->name)
-            {
-                // Transform feedback for varying structs is underspecified.
-                // See Khronos bug 9856.
-                // TODO(jmadill): Figure out how to be spec-compliant here.
-                if (!input->isStruct())
-                {
-                    packedVaryings.push_back(PackedVarying(*input, input->interpolation));
-                    packedVaryings.back().vertexOnly = true;
-                    packedVaryings.back().arrayIndex = static_cast<GLuint>(subscript);
-                    uniqueFullNames.insert(tfVarying);
-                }
-                if (subscript == GL_INVALID_INDEX)
-                {
-                    break;
-                }
-            }
-        }
-    }
-
-    std::sort(packedVaryings.begin(), packedVaryings.end(), ComparePackedVarying);
-
-    return packedVaryings;
-}
-
 void Program::linkOutputVariables(const Context *context)
 {
     Shader *fragmentShader = mState.mAttachedFragmentShader;
     ASSERT(fragmentShader != nullptr);
 
     ASSERT(mState.mOutputVariableTypes.empty());
     ASSERT(mState.mActiveOutputVariables.none());
+    ASSERT(mState.mDrawBufferTypeMask.none());
 
     // Gather output variable types
     for (const auto &outputVariable : fragmentShader->getActiveOutputVariables(context))
     {
         if (outputVariable.isBuiltIn() && outputVariable.name != "gl_FragColor" &&
             outputVariable.name != "gl_FragData")
         {
             continue;
         }
 
         unsigned int baseLocation =
             (outputVariable.location == -1 ? 0u
                                            : static_cast<unsigned int>(outputVariable.location));
-        for (unsigned int elementIndex = 0; elementIndex < outputVariable.elementCount();
-             elementIndex++)
+
+        // GLSL ES 3.10 section 4.3.6: Output variables cannot be arrays of arrays or arrays of
+        // structures, so we may use getBasicTypeElementCount().
+        unsigned int elementCount = outputVariable.getBasicTypeElementCount();
+        for (unsigned int elementIndex = 0; elementIndex < elementCount; elementIndex++)
         {
             const unsigned int location = baseLocation + elementIndex;
             if (location >= mState.mOutputVariableTypes.size())
             {
                 mState.mOutputVariableTypes.resize(location + 1, GL_NONE);
             }
             ASSERT(location < mState.mActiveOutputVariables.size());
             mState.mActiveOutputVariables.set(location);
             mState.mOutputVariableTypes[location] = VariableComponentType(outputVariable.type);
+            mState.mDrawBufferTypeMask.setIndex(mState.mOutputVariableTypes[location], location);
         }
     }
 
     // Skip this step for GLES2 shaders.
     if (fragmentShader->getShaderVersion(context) == 100)
         return;
 
     mState.mOutputVariables = fragmentShader->getActiveOutputVariables(context);
     // TODO(jmadill): any caps validation here?
 
     for (unsigned int outputVariableIndex = 0; outputVariableIndex < mState.mOutputVariables.size();
          outputVariableIndex++)
     {
         const sh::OutputVariable &outputVariable = mState.mOutputVariables[outputVariableIndex];
 
+        if (outputVariable.isArray())
+        {
+            // We're following the GLES 3.1 November 2016 spec section 7.3.1.1 Naming Active
+            // Resources and including [0] at the end of array variable names.
+            mState.mOutputVariables[outputVariableIndex].name += "[0]";
+            mState.mOutputVariables[outputVariableIndex].mappedName += "[0]";
+        }
+
         // Don't store outputs for gl_FragDepth, gl_FragColor, etc.
         if (outputVariable.isBuiltIn())
             continue;
 
         // Since multiple output locations must be specified, use 0 for non-specified locations.
-        int baseLocation = (outputVariable.location == -1 ? 0 : outputVariable.location);
-
-        for (unsigned int elementIndex = 0; elementIndex < outputVariable.elementCount();
-             elementIndex++)
+        unsigned int baseLocation =
+            (outputVariable.location == -1 ? 0u
+                                           : static_cast<unsigned int>(outputVariable.location));
+
+        // GLSL ES 3.10 section 4.3.6: Output variables cannot be arrays of arrays or arrays of
+        // structures, so we may use getBasicTypeElementCount().
+        unsigned int elementCount = outputVariable.getBasicTypeElementCount();
+        for (unsigned int elementIndex = 0; elementIndex < elementCount; elementIndex++)
         {
-            const int location = baseLocation + elementIndex;
-            ASSERT(mState.mOutputLocations.count(location) == 0);
-            unsigned int element = outputVariable.isArray() ? elementIndex : GL_INVALID_INDEX;
-            mState.mOutputLocations[location] = VariableLocation(element, outputVariableIndex);
+            const unsigned int location = baseLocation + elementIndex;
+            if (location >= mState.mOutputLocations.size())
+            {
+                mState.mOutputLocations.resize(location + 1);
+            }
+            ASSERT(!mState.mOutputLocations.at(location).used());
+            if (outputVariable.isArray())
+            {
+                mState.mOutputLocations[location] =
+                    VariableLocation(elementIndex, outputVariableIndex);
+            }
+            else
+            {
+                VariableLocation locationInfo;
+                locationInfo.index                = outputVariableIndex;
+                mState.mOutputLocations[location] = locationInfo;
+            }
         }
     }
 }
 
 void Program::setUniformValuesFromBindingQualifiers()
 {
     for (unsigned int samplerIndex : mState.mSamplerUniformRange)
     {
         const auto &samplerUniform = mState.mUniforms[samplerIndex];
         if (samplerUniform.binding != -1)
         {
-            GLint location = mState.getUniformLocation(samplerUniform.name);
+            GLint location = getUniformLocation(samplerUniform.name);
             ASSERT(location != -1);
             std::vector<GLint> boundTextureUnits;
-            for (unsigned int elementIndex = 0; elementIndex < samplerUniform.elementCount();
-                 ++elementIndex)
+            for (unsigned int elementIndex = 0;
+                 elementIndex < samplerUniform.getBasicTypeElementCount(); ++elementIndex)
             {
                 boundTextureUnits.push_back(samplerUniform.binding + elementIndex);
             }
             setUniform1iv(location, static_cast<GLsizei>(boundTextureUnits.size()),
                           boundTextureUnits.data());
         }
     }
 }
 
-void Program::gatherAtomicCounterBuffers()
-{
-    // TODO(jie.a.chen@intel.com): Get the actual OFFSET and ARRAY_STRIDE from the backend for each
-    // counter.
-    // TODO(jie.a.chen@intel.com): Get the actual BUFFER_DATA_SIZE from backend for each buffer.
-}
-
-void Program::gatherComputeBlockInfo(const std::vector<sh::InterfaceBlock> &computeBlocks)
-{
-    for (const sh::InterfaceBlock &computeBlock : computeBlocks)
-    {
-
-        // Only 'packed' blocks are allowed to be considered inactive.
-        if (!computeBlock.staticUse && computeBlock.layout == sh::BLOCKLAYOUT_PACKED)
-            continue;
-
-        defineInterfaceBlock(computeBlock, GL_COMPUTE_SHADER);
-    }
-}
-
-void Program::gatherVertexAndFragmentBlockInfo(
-    const std::vector<sh::InterfaceBlock> &vertexInterfaceBlocks,
-    const std::vector<sh::InterfaceBlock> &fragmentInterfaceBlocks)
+void Program::initInterfaceBlockBindings()
 {
-    std::set<std::string> visitedList;
-
-    for (const sh::InterfaceBlock &vertexBlock : vertexInterfaceBlocks)
-    {
-        // Only 'packed' blocks are allowed to be considered inactive.
-        if (!vertexBlock.staticUse && vertexBlock.layout == sh::BLOCKLAYOUT_PACKED)
-            continue;
-
-        defineInterfaceBlock(vertexBlock, GL_VERTEX_SHADER);
-        visitedList.insert(vertexBlock.name);
-    }
-
-    for (const sh::InterfaceBlock &fragmentBlock : fragmentInterfaceBlocks)
-    {
-        // Only 'packed' blocks are allowed to be considered inactive.
-        if (!fragmentBlock.staticUse && fragmentBlock.layout == sh::BLOCKLAYOUT_PACKED)
-            continue;
-
-        if (visitedList.count(fragmentBlock.name) > 0)
-        {
-            if (fragmentBlock.blockType == sh::BlockType::BLOCK_UNIFORM)
-            {
-                for (InterfaceBlock &block : mState.mUniformBlocks)
-                {
-                    if (block.name == fragmentBlock.name)
-                    {
-                        block.fragmentStaticUse = fragmentBlock.staticUse;
-                    }
-                }
-            }
-            else
-            {
-                ASSERT(fragmentBlock.blockType == sh::BlockType::BLOCK_BUFFER);
-                for (InterfaceBlock &block : mState.mShaderStorageBlocks)
-                {
-                    if (block.name == fragmentBlock.name)
-                    {
-                        block.fragmentStaticUse = fragmentBlock.staticUse;
-                    }
-                }
-            }
-
-            continue;
-        }
-
-        defineInterfaceBlock(fragmentBlock, GL_FRAGMENT_SHADER);
-        visitedList.insert(fragmentBlock.name);
-    }
-}
-
-void Program::gatherInterfaceBlockInfo(const Context *context)
-{
-    ASSERT(mState.mUniformBlocks.empty());
-    ASSERT(mState.mShaderStorageBlocks.empty());
-
-    if (mState.mAttachedComputeShader)
-    {
-        Shader *computeShader = mState.getAttachedComputeShader();
-
-        gatherComputeBlockInfo(computeShader->getUniformBlocks(context));
-        gatherComputeBlockInfo(computeShader->getShaderStorageBlocks(context));
-        return;
-    }
-
-    Shader *vertexShader   = mState.getAttachedVertexShader();
-    Shader *fragmentShader = mState.getAttachedFragmentShader();
-
-    gatherVertexAndFragmentBlockInfo(vertexShader->getUniformBlocks(context),
-                                     fragmentShader->getUniformBlocks(context));
-    if (context->getClientVersion() >= Version(3, 1))
-    {
-        gatherVertexAndFragmentBlockInfo(vertexShader->getShaderStorageBlocks(context),
-                                         fragmentShader->getShaderStorageBlocks(context));
-    }
-
     // Set initial bindings from shader.
     for (unsigned int blockIndex = 0; blockIndex < mState.mUniformBlocks.size(); blockIndex++)
     {
         InterfaceBlock &uniformBlock = mState.mUniformBlocks[blockIndex];
         bindUniformBlock(blockIndex, uniformBlock.binding);
     }
 }
 
-template <typename VarT>
-void Program::defineUniformBlockMembers(const std::vector<VarT> &fields,
-                                        const std::string &prefix,
-                                        const std::string &mappedPrefix,
-                                        int blockIndex)
-{
-    for (const VarT &field : fields)
-    {
-        const std::string &fullName = (prefix.empty() ? field.name : prefix + "." + field.name);
-
-        const std::string &fullMappedName =
-            (mappedPrefix.empty() ? field.mappedName : mappedPrefix + "." + field.mappedName);
-
-        if (field.isStruct())
-        {
-            for (unsigned int arrayElement = 0; arrayElement < field.elementCount(); arrayElement++)
-            {
-                const std::string uniformElementName =
-                    fullName + (field.isArray() ? ArrayString(arrayElement) : "");
-                const std::string uniformElementMappedName =
-                    fullMappedName + (field.isArray() ? ArrayString(arrayElement) : "");
-                defineUniformBlockMembers(field.fields, uniformElementName,
-                                          uniformElementMappedName, blockIndex);
-            }
-        }
-        else
-        {
-            // If getBlockMemberInfo returns false, the uniform is optimized out.
-            sh::BlockMemberInfo memberInfo;
-            if (!mProgram->getUniformBlockMemberInfo(fullName, fullMappedName, &memberInfo))
-            {
-                continue;
-            }
-
-            LinkedUniform newUniform(field.type, field.precision, fullName, field.arraySize, -1, -1,
-                                     -1, blockIndex, memberInfo);
-            newUniform.mappedName = fullMappedName;
-
-            // Since block uniforms have no location, we don't need to store them in the uniform
-            // locations list.
-            mState.mUniforms.push_back(newUniform);
-        }
-    }
-}
-
-void Program::defineInterfaceBlock(const sh::InterfaceBlock &interfaceBlock, GLenum shaderType)
-{
-    size_t blockSize = 0;
-    std::vector<unsigned int> blockIndexes;
-
-    if (interfaceBlock.blockType == sh::BlockType::BLOCK_UNIFORM)
-    {
-        int blockIndex = static_cast<int>(mState.mUniformBlocks.size());
-        // Track the first and last uniform index to determine the range of active uniforms in the
-        // block.
-        size_t firstBlockUniformIndex = mState.mUniforms.size();
-        defineUniformBlockMembers(interfaceBlock.fields, interfaceBlock.fieldPrefix(),
-                                  interfaceBlock.fieldMappedPrefix(), blockIndex);
-        size_t lastBlockUniformIndex = mState.mUniforms.size();
-
-        for (size_t blockUniformIndex = firstBlockUniformIndex;
-             blockUniformIndex < lastBlockUniformIndex; ++blockUniformIndex)
-        {
-            blockIndexes.push_back(static_cast<unsigned int>(blockUniformIndex));
-        }
-    }
-    else
-    {
-        // TODO(jiajia.qin@intel.com) : Add buffer variables support and calculate the block index.
-        ASSERT(interfaceBlock.blockType == sh::BlockType::BLOCK_BUFFER);
-    }
-    // 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);
-    if (interfaceBlock.arraySize > 0)
-    {
-        for (unsigned int arrayElement = 0; arrayElement < interfaceBlock.arraySize; ++arrayElement)
-        {
-            // TODO(jiajia.qin@intel.com) : use GetProgramResourceiv to calculate BUFFER_DATA_SIZE
-            // of UniformBlock and ShaderStorageBlock.
-            if (interfaceBlock.blockType == sh::BlockType::BLOCK_UNIFORM)
-            {
-                // Don't define this block at all if it's not active in the implementation.
-                if (!mProgram->getUniformBlockSize(
-                        interfaceBlock.name + ArrayString(arrayElement),
-                        interfaceBlock.mappedName + ArrayString(arrayElement), &blockSize))
-                {
-                    continue;
-                }
-            }
-
-            InterfaceBlock block(interfaceBlock.name, interfaceBlock.mappedName, true, arrayElement,
-                                 blockBinding + arrayElement);
-            block.memberIndexes = blockIndexes;
-
-            switch (shaderType)
-            {
-                case GL_VERTEX_SHADER:
-                {
-                    block.vertexStaticUse = interfaceBlock.staticUse;
-                    break;
-                }
-                case GL_FRAGMENT_SHADER:
-                {
-                    block.fragmentStaticUse = interfaceBlock.staticUse;
-                    break;
-                }
-                case GL_COMPUTE_SHADER:
-                {
-                    block.computeStaticUse = interfaceBlock.staticUse;
-                    break;
-                }
-                default:
-                    UNREACHABLE();
-            }
-
-            // 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);
-            if (interfaceBlock.blockType == sh::BlockType::BLOCK_UNIFORM)
-            {
-                mState.mUniformBlocks.push_back(block);
-            }
-            else
-            {
-                ASSERT(interfaceBlock.blockType == sh::BlockType::BLOCK_BUFFER);
-                mState.mShaderStorageBlocks.push_back(block);
-            }
-        }
-    }
-    else
-    {
-        // TODO(jiajia.qin@intel.com) : use GetProgramResourceiv to calculate BUFFER_DATA_SIZE
-        // of UniformBlock and ShaderStorageBlock.
-        if (interfaceBlock.blockType == sh::BlockType::BLOCK_UNIFORM)
-        {
-            if (!mProgram->getUniformBlockSize(interfaceBlock.name, interfaceBlock.mappedName,
-                                               &blockSize))
-            {
-                return;
-            }
-        }
-
-        InterfaceBlock block(interfaceBlock.name, interfaceBlock.mappedName, false, 0,
-                             blockBinding);
-        block.memberIndexes = blockIndexes;
-
-        switch (shaderType)
-        {
-            case GL_VERTEX_SHADER:
-            {
-                block.vertexStaticUse = interfaceBlock.staticUse;
-                break;
-            }
-            case GL_FRAGMENT_SHADER:
-            {
-                block.fragmentStaticUse = interfaceBlock.staticUse;
-                break;
-            }
-            case GL_COMPUTE_SHADER:
-            {
-                block.computeStaticUse = interfaceBlock.staticUse;
-                break;
-            }
-            default:
-                UNREACHABLE();
-        }
-
-        block.dataSize = static_cast<unsigned int>(blockSize);
-        if (interfaceBlock.blockType == sh::BlockType::BLOCK_UNIFORM)
-        {
-            mState.mUniformBlocks.push_back(block);
-        }
-        else
-        {
-            ASSERT(interfaceBlock.blockType == sh::BlockType::BLOCK_BUFFER);
-            mState.mShaderStorageBlocks.push_back(block);
-        }
-    }
-}
-
 void Program::updateSamplerUniform(const VariableLocation &locationInfo,
                                    GLsizei clampedCount,
                                    const GLint *v)
 {
     ASSERT(mState.isSamplerUniformIndex(locationInfo.index));
     GLuint samplerIndex = mState.getSamplerIndexFromUniformIndex(locationInfo.index);
     std::vector<GLuint> *boundTextureUnits =
         &mState.mSamplerBindings[samplerIndex].boundTextureUnits;
 
-    std::copy(v, v + clampedCount, boundTextureUnits->begin() + locationInfo.element);
+    std::copy(v, v + clampedCount, boundTextureUnits->begin() + locationInfo.arrayIndex);
 
     // Invalidate the validation cache.
     mCachedValidateSamplersResult.reset();
 }
 
 template <typename T>
 GLsizei Program::clampUniformCount(const VariableLocation &locationInfo,
                                    GLsizei count,
@@ -3094,17 +3072,18 @@ GLsizei Program::clampUniformCount(const
 {
     if (count == 1)
         return 1;
 
     const LinkedUniform &linkedUniform = mState.mUniforms[locationInfo.index];
 
     // OpenGL ES 3.0.4 spec pg 67: "Values for any array element that exceeds the highest array
     // element index used, as reported by GetActiveUniform, will be ignored by the GL."
-    unsigned int remainingElements = linkedUniform.elementCount() - locationInfo.element;
+    unsigned int remainingElements =
+        linkedUniform.getBasicTypeElementCount() - locationInfo.arrayIndex;
     GLsizei maxElementCount =
         static_cast<GLsizei>(remainingElements * linkedUniform.getElementComponents());
 
     if (count * vectorSize > maxElementCount)
     {
         return maxElementCount / vectorSize;
     }
 
@@ -3123,17 +3102,18 @@ GLsizei Program::clampMatrixUniformCount
     {
         return clampUniformCount(locationInfo, count, cols * rows, v);
     }
 
     const LinkedUniform &linkedUniform = mState.mUniforms[locationInfo.index];
 
     // OpenGL ES 3.0.4 spec pg 67: "Values for any array element that exceeds the highest array
     // element index used, as reported by GetActiveUniform, will be ignored by the GL."
-    unsigned int remainingElements = linkedUniform.elementCount() - locationInfo.element;
+    unsigned int remainingElements =
+        linkedUniform.getBasicTypeElementCount() - locationInfo.arrayIndex;
     return std::min(count, static_cast<GLsizei>(remainingElements));
 }
 
 // Driver differences mean that doing the uniform value cast ourselves gives consistent results.
 // EG: on NVIDIA drivers, it was observed that getUniformi for MAX_INT+1 returned MIN_INT.
 template <typename DestT>
 void Program::getUniformInternal(const Context *context,
                                  DestT *dataOut,
--- a/gfx/angle/src/libANGLE/Program.h
+++ b/gfx/angle/src/libANGLE/Program.h
@@ -44,17 +44,16 @@ struct Caps;
 class Context;
 class ContextState;
 class Shader;
 class ShaderProgramManager;
 class State;
 class InfoLog;
 class Buffer;
 class Framebuffer;
-struct PackedVarying;
 
 extern const char * const g_fakepath;
 
 class InfoLog : angle::NonCopyable
 {
   public:
     InfoLog();
     ~InfoLog();
@@ -115,16 +114,18 @@ class InfoLog : angle::NonCopyable
         ensureInitialized();
         StreamHelper helper(mLazyStream.get());
         helper << value;
         return helper;
     }
 
     std::string str() const { return mLazyStream ? mLazyStream->str() : ""; }
 
+    bool empty() const;
+
   private:
     void ensureInitialized()
     {
         if (!mLazyStream)
         {
             mLazyStream.reset(new std::stringstream());
         }
     }
@@ -133,26 +134,29 @@ class InfoLog : angle::NonCopyable
 };
 
 // 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 element, unsigned int index);
+    VariableLocation(unsigned int arrayIndex, unsigned int index);
 
     // If used is false, it means this location is only used to fill an empty space in an array,
     // and there is no corresponding uniform variable for this location. It can also mean the
     // uniform was optimized out by the implementation.
     bool used() const { return (index != kUnused); }
     void markUnused() { index = kUnused; }
     void markIgnored() { ignored = true; }
 
-    unsigned int element;
+    // "arrayIndex" stores the index of the innermost GLSL array. It's zero for non-arrays.
+    unsigned int arrayIndex;
+    // "index" is an index of the variable. The variable contains the indices for other than the
+    // innermost GLSL arrays.
     unsigned int index;
 
     // If this location was bound to an unreferenced uniform.  Setting data on this uniform is a
     // no-op.
     bool ignored;
 };
 
 // Information about a variable binding.
@@ -171,20 +175,19 @@ 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)
-        : textureType(textureTypeIn), boundTextureUnits(elementCount, 0), unreferenced(unreferenced)
-    {
-    }
+    SamplerBinding(GLenum textureTypeIn, size_t elementCount, bool unreferenced);
+    SamplerBinding(const SamplerBinding &other);
+    ~SamplerBinding();
 
     // Necessary for retrieving active textures from the GL state.
     GLenum 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.
@@ -193,57 +196,71 @@ struct SamplerBinding
 
 // A varying with tranform feedback enabled. If it's an array, either the whole array or one of its
 // elements specified by 'arrayIndex' can set to be enabled.
 struct TransformFeedbackVarying : public sh::Varying
 {
     TransformFeedbackVarying(const sh::Varying &varyingIn, GLuint index)
         : sh::Varying(varyingIn), arrayIndex(index)
     {
+        ASSERT(!isArrayOfArrays());
     }
+
+    TransformFeedbackVarying(const sh::ShaderVariable &field, const sh::Varying &parent)
+        : arrayIndex(GL_INVALID_INDEX)
+    {
+        sh::ShaderVariable *thisVar = this;
+        *thisVar                    = field;
+        interpolation               = parent.interpolation;
+        isInvariant                 = parent.isInvariant;
+        name                        = parent.name + "." + name;
+    }
+
     std::string nameWithArrayIndex() const
     {
         std::stringstream fullNameStr;
         fullNameStr << name;
         if (arrayIndex != GL_INVALID_INDEX)
         {
             fullNameStr << "[" << arrayIndex << "]";
         }
         return fullNameStr.str();
     }
-    GLsizei size() const { return (arrayIndex == GL_INVALID_INDEX ? elementCount() : 1); }
+    GLsizei size() const
+    {
+        return (isArray() && arrayIndex == GL_INVALID_INDEX ? getOutermostArraySize() : 1);
+    }
 
     GLuint arrayIndex;
 };
 
 struct ImageBinding
 {
-    ImageBinding(size_t count) : boundImageUnits(count, 0) {}
-    ImageBinding(GLuint imageUnit, size_t count)
-    {
-        for (size_t index = 0; index < count; ++index)
-        {
-            boundImageUnits.push_back(imageUnit + static_cast<GLuint>(index));
-        }
-    }
+    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; }
     const std::vector<std::string> &getTransformFeedbackVaryingNames() const
     {
         return mTransformFeedbackVaryingNames;
     }
     GLint getTransformFeedbackBufferMode() const { return mTransformFeedbackBufferMode; }
     GLuint getUniformBlockBinding(GLuint uniformBlockIndex) const
     {
         ASSERT(uniformBlockIndex < mUniformBlocks.size());
@@ -258,111 +275,158 @@ class ProgramState final : angle::NonCop
     {
         return mActiveUniformBlockBindings;
     }
     const std::vector<sh::Attribute> &getAttributes() const { return mAttributes; }
     const AttributesMask &getActiveAttribLocationsMask() const
     {
         return mActiveAttribLocationsMask;
     }
+    unsigned int getMaxActiveAttribLocation() const { return mMaxActiveAttribLocation; }
     DrawBufferMask getActiveOutputVariables() const { return mActiveOutputVariables; }
     const std::vector<sh::OutputVariable> &getOutputVariables() const { return mOutputVariables; }
-    const std::map<int, VariableLocation> &getOutputLocations() const { return mOutputLocations; }
+    const std::vector<VariableLocation> &getOutputLocations() const { return mOutputLocations; }
     const std::vector<LinkedUniform> &getUniforms() const { return mUniforms; }
     const std::vector<VariableLocation> &getUniformLocations() const { return mUniformLocations; }
     const std::vector<InterfaceBlock> &getUniformBlocks() const { return mUniformBlocks; }
     const std::vector<InterfaceBlock> &getShaderStorageBlocks() const
     {
         return mShaderStorageBlocks;
     }
+    const std::vector<BufferVariable> &getBufferVariables() const { return mBufferVariables; }
     const std::vector<SamplerBinding> &getSamplerBindings() const { return mSamplerBindings; }
     const std::vector<ImageBinding> &getImageBindings() const { return mImageBindings; }
     const sh::WorkGroupSize &getComputeShaderLocalSize() const { return mComputeShaderLocalSize; }
     const RangeUI &getSamplerUniformRange() const { return mSamplerUniformRange; }
     const RangeUI &getImageUniformRange() const { return mImageUniformRange; }
     const RangeUI &getAtomicCounterUniformRange() const { return mAtomicCounterUniformRange; }
 
     const std::vector<TransformFeedbackVarying> &getLinkedTransformFeedbackVaryings() const
     {
         return mLinkedTransformFeedbackVaryings;
     }
     const std::vector<AtomicCounterBuffer> &getAtomicCounterBuffers() const
     {
         return mAtomicCounterBuffers;
     }
 
-    GLint getUniformLocation(const std::string &name) const;
     GLuint getUniformIndexFromName(const std::string &name) const;
     GLuint getUniformIndexFromLocation(GLint location) const;
     Optional<GLuint> getSamplerIndex(GLint location) const;
     bool isSamplerUniformIndex(GLuint index) const;
     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; }
+
   private:
     friend class MemoryProgramCache;
     friend class Program;
 
     std::string mLabel;
 
     sh::WorkGroupSize mComputeShaderLocalSize;
 
     Shader *mAttachedFragmentShader;
     Shader *mAttachedVertexShader;
     Shader *mAttachedComputeShader;
+    Shader *mAttachedGeometryShader;
 
     std::vector<std::string> mTransformFeedbackVaryingNames;
     std::vector<TransformFeedbackVarying> mLinkedTransformFeedbackVaryings;
     GLenum mTransformFeedbackBufferMode;
 
     // For faster iteration on the blocks currently being bound.
     UniformBlockBindingMask mActiveUniformBlockBindings;
 
     std::vector<sh::Attribute> mAttributes;
     angle::BitSet<MAX_VERTEX_ATTRIBS> mActiveAttribLocationsMask;
+    unsigned int mMaxActiveAttribLocation;
+    ComponentTypeMask mAttributesTypeMask;
+    // mAttributesMask is identical to mActiveAttribLocationsMask with built-in attributes removed.
+    AttributesMask mAttributesMask;
 
     // Uniforms are sorted in order:
     //  1. Non-opaque uniforms
     //  2. Sampler uniforms
     //  3. Image uniforms
     //  4. Atomic counter uniforms
     //  5. Uniform block uniforms
     // This makes opaque uniform validation easier, since we don't need a separate list.
+    // For generating the entries and naming them we follow the spec: GLES 3.1 November 2016 section
+    // 7.3.1.1 Naming Active Resources. There's a separate entry for each struct member and each
+    // inner array of an array of arrays. Names and mapped names of uniforms that are arrays include
+    // [0] in the end. This makes implementation of queries simpler.
     std::vector<LinkedUniform> mUniforms;
+
     std::vector<VariableLocation> mUniformLocations;
     std::vector<InterfaceBlock> mUniformBlocks;
+    std::vector<BufferVariable> mBufferVariables;
     std::vector<InterfaceBlock> mShaderStorageBlocks;
     std::vector<AtomicCounterBuffer> mAtomicCounterBuffers;
     RangeUI mSamplerUniformRange;
     RangeUI mImageUniformRange;
     RangeUI mAtomicCounterUniformRange;
 
     // An array of the samplers that are used by the program
     std::vector<gl::SamplerBinding> mSamplerBindings;
 
     // An array of the images that are used by the program
     std::vector<gl::ImageBinding> mImageBindings;
 
+    // Names and mapped names of output variables that are arrays include [0] in the end, similarly
+    // to uniforms.
     std::vector<sh::OutputVariable> mOutputVariables;
-    std::map<int, VariableLocation> mOutputLocations;
+    std::vector<VariableLocation> mOutputLocations;
     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;
 
     // ANGLE_multiview.
     int mNumViews;
 };
 
+class ProgramBindings final : angle::NonCopyable
+{
+  public:
+    ProgramBindings();
+    ~ProgramBindings();
+
+    void bindLocation(GLuint index, const std::string &name);
+    int getBinding(const std::string &name) const;
+
+    using const_iterator = std::unordered_map<std::string, GLuint>::const_iterator;
+    const_iterator begin() const;
+    const_iterator end() const;
+
+  private:
+    std::unordered_map<std::string, GLuint> mBindings;
+};
+
+struct ProgramVaryingRef
+{
+    const sh::Varying *get() const { return vertex ? vertex : fragment; }
+
+    const sh::Varying *vertex   = nullptr;
+    const sh::Varying *fragment = nullptr;
+};
+
+using ProgramMergedVaryings = std::map<std::string, ProgramVaryingRef>;
+
 class Program final : angle::NonCopyable, public LabeledObject
 {
   public:
     Program(rx::GLImplFactory *factory, ShaderProgramManager *manager, GLuint handle);
     void onDestroy(const Context *context);
 
     GLuint id() const { return mHandle; }
 
@@ -373,32 +437,37 @@ class Program final : angle::NonCopyable
 
     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; }
 
     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]; }
+
     Error loadBinary(const Context *context,
                      GLenum binaryFormat,
                      const void *binary,
                      GLsizei length);
     Error saveBinary(const Context *context,
                      GLenum *binaryFormat,
                      void *binary,
                      GLsizei bufSize,
@@ -437,24 +506,26 @@ class Program final : angle::NonCopyable
 
     void getActiveUniform(GLuint index,
                           GLsizei bufsize,
                           GLsizei *length,
                           GLint *size,
                           GLenum *type,
                           GLchar *name) const;
     GLint getActiveUniformCount() const;
+    size_t getActiveBufferVariableCount() const;
     GLint getActiveUniformMaxLength() const;
-    GLint getActiveUniformi(GLuint index, GLenum pname) const;
     bool isValidUniformLocation(GLint location) const;
     const LinkedUniform &getUniformByLocation(GLint location) const;
     const VariableLocation &getUniformLocation(GLint location) const;
     const std::vector<VariableLocation> &getUniformLocations() const;
     const LinkedUniform &getUniformByIndex(GLuint index) const;
 
+    const BufferVariable &getBufferVariableByIndex(GLuint index) const;
+
     enum SetUniformResult
     {
         SamplerChanged,
         NoSamplerChange,
     };
 
     GLint getUniformLocation(const std::string &name) const;
     GLuint getUniformIndex(const std::string &name) const;
@@ -479,36 +550,48 @@ class Program final : angle::NonCopyable
     void setUniformMatrix4x2fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
     void setUniformMatrix3x4fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
     void setUniformMatrix4x3fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
 
     void getUniformfv(const Context *context, GLint location, GLfloat *params) const;
     void getUniformiv(const Context *context, GLint location, GLint *params) const;
     void getUniformuiv(const Context *context, GLint location, GLuint *params) const;
 
-    void getActiveUniformBlockName(GLuint uniformBlockIndex, GLsizei bufSize, GLsizei *length, GLchar *uniformBlockName) const;
+    void getActiveUniformBlockName(const GLuint blockIndex,
+                                   GLsizei bufSize,
+                                   GLsizei *length,
+                                   GLchar *blockName) const;
+    void getActiveShaderStorageBlockName(const GLuint blockIndex,
+                                         GLsizei bufSize,
+                                         GLsizei *length,
+                                         GLchar *blockName) const;
     GLuint getActiveUniformBlockCount() const;
+    GLuint getActiveAtomicCounterBufferCount() const;
     GLuint getActiveShaderStorageBlockCount() const;
     GLint getActiveUniformBlockMaxLength() const;
 
     GLuint getUniformBlockIndex(const std::string &name) const;
+    GLuint getShaderStorageBlockIndex(const std::string &name) const;
 
     void bindUniformBlock(GLuint uniformBlockIndex, GLuint uniformBlockBinding);
     GLuint getUniformBlockBinding(GLuint uniformBlockIndex) const;
     GLuint getShaderStorageBlockBinding(GLuint shaderStorageBlockIndex) const;
 
     const InterfaceBlock &getUniformBlockByIndex(GLuint index) const;
+    const InterfaceBlock &getShaderStorageBlockByIndex(GLuint index) const;
 
     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 bool linkValidateInterfaceBlockFields(InfoLog &infoLog,
+    static bool LinkValidateInterfaceBlockFields(InfoLog &infoLog,
                                                  const std::string &uniformName,
                                                  const sh::InterfaceBlockField &vertexUniform,
                                                  const sh::InterfaceBlockField &fragmentUniform,
                                                  bool webglCompatibility);
 
     void addRef();
     void release(const Context *context);
     unsigned int getRefCount() const;
@@ -526,121 +609,100 @@ class Program final : angle::NonCopyable
     }
 
     const std::vector<SamplerBinding> &getSamplerBindings() const
     {
         return mState.mSamplerBindings;
     }
 
     const std::vector<ImageBinding> &getImageBindings() const { return mState.mImageBindings; }
+    const sh::WorkGroupSize &getComputeShaderLocalSize() const
+    {
+        return mState.mComputeShaderLocalSize;
+    }
 
     const ProgramState &getState() const { return mState; }
 
-    static bool linkValidateVariablesBase(InfoLog &infoLog,
+    static bool LinkValidateVariablesBase(InfoLog &infoLog,
                                           const std::string &variableName,
                                           const sh::ShaderVariable &vertexVariable,
                                           const sh::ShaderVariable &fragmentVariable,
                                           bool validatePrecision);
 
     GLuint getInputResourceIndex(const GLchar *name) const;
     GLuint getOutputResourceIndex(const GLchar *name) const;
     void getInputResourceName(GLuint index, GLsizei bufSize, GLsizei *length, GLchar *name) const;
     void getOutputResourceName(GLuint index, GLsizei bufSize, GLsizei *length, GLchar *name) const;
+    void getUniformResourceName(GLuint index, GLsizei bufSize, GLsizei *length, GLchar *name) const;
+    void getBufferVariableResourceName(GLuint index,
+                                       GLsizei bufSize,
+                                       GLsizei *length,
+                                       GLchar *name) const;
     const sh::Attribute &getInputResource(GLuint index) const;
     const sh::OutputVariable &getOutputResource(GLuint index) const;
 
-    class Bindings final : angle::NonCopyable
-    {
-      public:
-        void bindLocation(GLuint index, const std::string &name);
-        int getBinding(const std::string &name) const;
-
-        typedef std::unordered_map<std::string, GLuint>::const_iterator const_iterator;
-        const_iterator begin() const;
-        const_iterator end() const;
-
-      private:
-        std::unordered_map<std::string, GLuint> mBindings;
-    };
-
-    const Bindings &getAttributeBindings() const { return mAttributeBindings; }
-    const Bindings &getUniformLocationBindings() const { return mUniformLocationBindings; }
-    const Bindings &getFragmentInputBindings() const { return mFragmentInputBindings; }
+    const ProgramBindings &getAttributeBindings() const { return mAttributeBindings; }
+    const ProgramBindings &getUniformLocationBindings() const { return mUniformLocationBindings; }
+    const ProgramBindings &getFragmentInputBindings() const { return mFragmentInputBindings; }
 
     int getNumViews() const { return mState.getNumViews(); }
     bool usesMultiview() const { return mState.usesMultiview(); }
 
-  private:
-    ~Program();
+    ComponentTypeMask getDrawBufferTypeMask() const { return mState.mDrawBufferTypeMask; }
+    ComponentTypeMask getAttributesTypeMask() const { return mState.mAttributesTypeMask; }
+    AttributesMask getAttributesMask() const { return mState.mAttributesMask; }
 
-    struct VaryingRef
-    {
-        const sh::Varying *get() const { return vertex ? vertex : fragment; }
-
-        const sh::Varying *vertex   = nullptr;
-        const sh::Varying *fragment = nullptr;
-    };
-
-    using MergedVaryings = std::map<std::string, VaryingRef>;
+  private:
+    ~Program() override;
 
     void unlink();
 
+    bool linkValidateShaders(const Context *context, InfoLog &infoLog);
     bool linkAttributes(const Context *context, InfoLog &infoLog);
-    bool validateVertexAndFragmentInterfaceBlocks(
+    static bool ValidateGraphicsInterfaceBlocks(
         const std::vector<sh::InterfaceBlock> &vertexInterfaceBlocks,
         const std::vector<sh::InterfaceBlock> &fragmentInterfaceBlocks,
         InfoLog &infoLog,
-        bool webglCompatibility) const;
+        bool webglCompatibility);
     bool linkInterfaceBlocks(const Context *context, InfoLog &infoLog);
     bool linkVaryings(const Context *context, InfoLog &infoLog) const;
 
     bool linkUniforms(const Context *context,
                       InfoLog &infoLog,
-                      const Bindings &uniformLocationBindings);
+                      const ProgramBindings &uniformLocationBindings);
     void linkSamplerAndImageBindings();
     bool linkAtomicCounterBuffers();
 
-    bool areMatchingInterfaceBlocks(InfoLog &infoLog,
-                                    const sh::InterfaceBlock &vertexInterfaceBlock,
-                                    const sh::InterfaceBlock &fragmentInterfaceBlock,
-                                    bool webglCompatibility) const;
+    void updateLinkedShaderStages();
 
-    static bool linkValidateVaryings(InfoLog &infoLog,
+    static bool AreMatchingInterfaceBlocks(InfoLog &infoLog,
+                                           const sh::InterfaceBlock &vertexInterfaceBlock,
+                                           const sh::InterfaceBlock &fragmentInterfaceBlock,
+                                           bool webglCompatibility);
+
+    static bool LinkValidateVaryings(InfoLog &infoLog,
                                      const std::string &varyingName,
                                      const sh::Varying &vertexVarying,
                                      const sh::Varying &fragmentVarying,
                                      int shaderVersion);
     bool linkValidateBuiltInVaryings(const Context *context, InfoLog &infoLog) const;
     bool linkValidateTransformFeedback(const gl::Context *context,
                                        InfoLog &infoLog,
-                                       const MergedVaryings &linkedVaryings,
+                                       const ProgramMergedVaryings &linkedVaryings,
                                        const Caps &caps) const;
     bool linkValidateGlobalNames(const Context *context, InfoLog &infoLog) const;
 
-    void gatherTransformFeedbackVaryings(const MergedVaryings &varyings);
+    void gatherTransformFeedbackVaryings(const ProgramMergedVaryings &varyings);
 
-    MergedVaryings getMergedVaryings(const Context *context) const;
-    std::vector<PackedVarying> getPackedVaryings(const MergedVaryings &mergedVaryings) const;
+    ProgramMergedVaryings getMergedVaryings(const Context *context) const;
     void linkOutputVariables(const Context *context);
 
     void setUniformValuesFromBindingQualifiers();
 
-    void gatherAtomicCounterBuffers();
-    void gatherComputeBlockInfo(const std::vector<sh::InterfaceBlock> &computeBlocks);
-    void gatherVertexAndFragmentBlockInfo(
-        const std::vector<sh::InterfaceBlock> &vertexInterfaceBlocks,
-        const std::vector<sh::InterfaceBlock> &fragmentInterfaceBlocks);
-    void gatherInterfaceBlockInfo(const Context *context);
-    template <typename VarT>
-    void defineUniformBlockMembers(const std::vector<VarT> &fields,
-                                   const std::string &prefix,
-                                   const std::string &mappedPrefix,
-                                   int blockIndex);
-
-    void defineInterfaceBlock(const sh::InterfaceBlock &interfaceBlock, GLenum shaderType);
+    void initInterfaceBlockBindings();
 
     // Both these function update the cached uniform values and return a modified "count"
     // so that the uniform update doesn't overflow the uniform.
     template <typename T>
     GLsizei clampUniformCount(const VariableLocation &locationInfo,
                               GLsizei count,
                               int vectorSize,
                               const T *v);
@@ -653,29 +715,36 @@ class Program final : angle::NonCopyable
 
     template <typename DestT>
     void getUniformInternal(const Context *context,
                             DestT *dataOut,
                             GLint location,
                             GLenum nativeType,
                             int components) const;
 
+    template <typename T>
+    void getResourceName(GLuint index,
+                         const std::vector<T> &resources,
+                         GLsizei bufSize,
+                         GLsizei *length,
+                         GLchar *name) const;
+
     ProgramState mState;
     rx::ProgramImpl *mProgram;
 
     bool mValidated;
 
-    Bindings mAttributeBindings;
+    ProgramBindings mAttributeBindings;
 
     // Note that this has nothing to do with binding layout qualifiers that can be set for some
     // uniforms in GLES3.1+. It is used to pre-set the location of uniforms.
-    Bindings mUniformLocationBindings;
+    ProgramBindings mUniformLocationBindings;
 
     // CHROMIUM_path_rendering
-    Bindings mFragmentInputBindings;
+    ProgramBindings mFragmentInputBindings;
 
     bool mLinked;
     bool mDeleteStatus;   // Flag to indicate that the program can be deleted when no longer in use
 
     unsigned int mRefCount;
 
     ShaderProgramManager *mResourceManager;
     const GLuint mHandle;
new file mode 100644
--- /dev/null
+++ b/gfx/angle/src/libANGLE/ProgramLinkedResources.cpp
@@ -0,0 +1,1060 @@
+//
+// 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.
+//
+
+// UniformLinker.cpp: implements link-time checks for default block uniforms, and generates uniform
+// locations. Populates data structures related to uniforms so that they can be stored in program
+// state.
+
+#include "libANGLE/ProgramLinkedResources.h"
+
+#include "common/string_utils.h"
+#include "common/utilities.h"
+#include "libANGLE/Caps.h"
+#include "libANGLE/Context.h"
+#include "libANGLE/Shader.h"
+#include "libANGLE/features.h"
+
+namespace gl
+{
+
+namespace
+{
+
+LinkedUniform *FindUniform(std::vector<LinkedUniform> &list, const std::string &name)
+{
+    for (LinkedUniform &uniform : list)
+    {
+        if (uniform.name == name)
+            return &uniform;
+    }
+
+    return nullptr;
+}
+
+int GetUniformLocationBinding(const ProgramBindings &uniformLocationBindings,
+                              const sh::Uniform &uniform)
+{
+    int binding = uniformLocationBindings.getBinding(uniform.name);
+    if (uniform.isArray() && binding == -1)
+    {
+        // Bindings for array uniforms can be set either with or without [0] in the end.
+        ASSERT(angle::EndsWith(uniform.name, "[0]"));
+        std::string nameWithoutIndex = uniform.name.substr(0u, uniform.name.length() - 3u);
+        return uniformLocationBindings.getBinding(nameWithoutIndex);
+    }
+    return binding;
+}
+
+}  // 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 &linkedUniform = *(entry->second);
+            const std::string &uniformName   = "uniform '" + linkedUniform.name + "'";
+            if (!LinkValidateUniforms(infoLog, uniformName, linkedUniform, fragmentUniform))
+            {
+                return false;
+            }
+        }
+    }
+    return true;
+}
+
+// GLSL ES Spec 3.00.3, section 4.3.5.
+bool UniformLinker::LinkValidateUniforms(InfoLog &infoLog,
+                                         const std::string &uniformName,
+                                         const sh::Uniform &vertexUniform,
+                                         const sh::Uniform &fragmentUniform)
+{
+#if ANGLE_PROGRAM_LINK_VALIDATE_UNIFORM_PRECISION == ANGLE_ENABLED
+    const bool validatePrecision = true;
+#else
+    const bool validatePrecision = false;
+#endif
+
+    if (!Program::LinkValidateVariablesBase(infoLog, uniformName, vertexUniform, fragmentUniform,
+                                            validatePrecision))
+    {
+        return false;
+    }
+
+    // GLSL ES Spec 3.10.4, section 4.4.5.
+    if (vertexUniform.binding != -1 && fragmentUniform.binding != -1 &&
+        vertexUniform.binding != fragmentUniform.binding)
+    {
+        infoLog << "Binding layout qualifiers for " << uniformName
+                << " differ between vertex and fragment shaders.";
+        return false;
+    }
+
+    // GLSL ES Spec 3.10.4, section 9.2.1.
+    if (vertexUniform.location != -1 && fragmentUniform.location != -1 &&
+        vertexUniform.location != fragmentUniform.location)
+    {
+        infoLog << "Location layout qualifiers for " << uniformName
+                << " differ between vertex and fragment shaders.";
+        return false;
+    }
+    if (vertexUniform.offset != fragmentUniform.offset)
+    {
+        infoLog << "Offset layout qualifiers for " << uniformName
+                << " differ between vertex and fragment shaders.";
+        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))
+    {
+        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();
+
+    // Gather uniforms that have their location pre-set and uniforms that don't yet have a location.
+    std::vector<VariableLocation> unlocatedUniforms;
+    std::map<GLuint, VariableLocation> preLocatedUniforms;
+
+    for (size_t uniformIndex = 0; uniformIndex < mUniforms.size(); uniformIndex++)
+    {
+        const LinkedUniform &uniform = mUniforms[uniformIndex];
+
+        if (uniform.isBuiltIn() || IsAtomicCounterType(uniform.type))
+        {
+            continue;
+        }
+
+        int preSetLocation = GetUniformLocationBinding(uniformLocationBindings, uniform);
+        int shaderLocation = uniform.location;
+
+        if (shaderLocation != -1)
+        {
+            preSetLocation = shaderLocation;
+        }
+
+        unsigned int elementCount = uniform.getBasicTypeElementCount();
+        for (unsigned int arrayIndex = 0; arrayIndex < elementCount; arrayIndex++)
+        {
+            VariableLocation location(arrayIndex, static_cast<unsigned int>(uniformIndex));
+
+            if ((arrayIndex == 0 && preSetLocation != -1) || shaderLocation != -1)
+            {
+                int elementLocation                 = preSetLocation + arrayIndex;
+                preLocatedUniforms[elementLocation] = location;
+            }
+            else
+            {
+                unlocatedUniforms.push_back(location);
+            }
+        }
+    }
+
+    // Make enough space for all uniforms, with pre-set locations or not.
+    mUniformLocations.resize(
+        std::max(unlocatedUniforms.size() + preLocatedUniforms.size() + ignoredLocations.size(),
+                 static_cast<size_t>(maxUniformLocation + 1)));
+
+    // Assign uniforms with pre-set locations
+    for (const auto &uniform : preLocatedUniforms)
+    {
+        mUniformLocations[uniform.first] = uniform.second;
+    }
+
+    // Assign ignored uniforms
+    for (const auto &ignoredLocation : ignoredLocations)
+    {
+        mUniformLocations[ignoredLocation].markIgnored();
+    }
+
+    // Automatically assign locations for the rest of the uniforms
+    size_t nextUniformLocation = 0;
+    for (const auto &unlocatedUniform : unlocatedUniforms)
+    {
+        while (mUniformLocations[nextUniformLocation].used() ||
+               mUniformLocations[nextUniformLocation].ignored)
+        {
+            nextUniformLocation++;
+        }
+
+        ASSERT(nextUniformLocation < mUniformLocations.size());
+        mUniformLocations[nextUniformLocation] = unlocatedUniform;
+        nextUniformLocation++;
+    }
+
+    return true;
+}
+
+bool UniformLinker::gatherUniformLocationsAndCheckConflicts(
+    InfoLog &infoLog,
+    const ProgramBindings &uniformLocationBindings,
+    std::set<GLuint> *reservedLocations,
+    std::set<GLuint> *ignoredLocations,
+    int *maxUniformLocation)
+{
+    for (const LinkedUniform &uniform : mUniforms)
+    {
+        if (uniform.isBuiltIn())
+        {
+            continue;
+        }
+
+        int apiBoundLocation = GetUniformLocationBinding(uniformLocationBindings, uniform);
+        int shaderLocation   = uniform.location;
+
+        if (shaderLocation != -1)
+        {
+            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())
+                {
+                    infoLog << "Multiple uniforms bound to location " << elementLocation << ".";
+                    return false;
+                }
+                reservedLocations->insert(elementLocation);
+                if (!uniform.staticUse)
+                {
+                    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())
+            {
+                infoLog << "Multiple uniforms bound to location " << apiBoundLocation << ".";
+                return false;
+            }
+            reservedLocations->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())
+        {
+            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)
+        {
+            ++uniformIter;
+        }
+        else
+        {
+            uniformIter = mUniforms.erase(uniformIter);
+        }
+    }
+}
+
+bool UniformLinker::flattenUniformsAndCheckCapsForShader(
+    const Context *context,
+    Shader *shader,
+    GLuint maxUniformComponents,
+    GLuint maxTextureImageUnits,
+    GLuint maxImageUnits,
+    GLuint maxAtomicCounters,
+    const std::string &componentsErrorMessage,
+    const std::string &samplerErrorMessage,
+    const std::string &imageErrorMessage,
+    const std::string &atomicCounterErrorMessage,
+    std::vector<LinkedUniform> &samplerUniforms,
+    std::vector<LinkedUniform> &imageUniforms,
+    std::vector<LinkedUniform> &atomicCounterUniforms,
+    InfoLog &infoLog)
+{
+    ShaderUniformCount shaderUniformCount;
+    for (const sh::Uniform &uniform : shader->getUniforms(context))
+    {
+        shaderUniformCount += flattenUniform(uniform, &samplerUniforms, &imageUniforms,
+                                             &atomicCounterUniforms, shader->getType());
+    }
+
+    if (shaderUniformCount.vectorCount > maxUniformComponents)
+    {
+        infoLog << componentsErrorMessage << maxUniformComponents << ").";
+        return false;
+    }
+
+    if (shaderUniformCount.samplerCount > maxTextureImageUnits)
+    {
+        infoLog << samplerErrorMessage << maxTextureImageUnits << ").";
+        return false;
+    }
+
+    if (shaderUniformCount.imageCount > maxImageUnits)
+    {
+        infoLog << imageErrorMessage << maxImageUnits << ").";
+        return false;
+    }
+
+    if (shaderUniformCount.atomicCounterCount > maxAtomicCounters)
+    {
+        infoLog << atomicCounterErrorMessage << maxAtomicCounters << ").";
+        return false;
+    }
+
+    return true;
+}
+
+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())
+    {
+        Shader *computeShader = mState.getAttachedComputeShader();
+
+        // 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 (",
+                "Compute shader image count exceeds MAX_COMPUTE_IMAGE_UNIFORMS (",
+                "Compute shader atomic counter count exceeds MAX_COMPUTE_ATOMIC_COUNTERS (",
+                samplerUniforms, imageUniforms, atomicCounterUniforms, infoLog))
+        {
+            return false;
+        }
+    }
+    else
+    {
+        Shader *vertexShader = mState.getAttachedVertexShader();
+
+        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();
+
+        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;
+        }
+    }
+
+    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)
+{
+    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)
+    {
+        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,
+    bool markStaticUse,
+    int binding,
+    int offset,
+    int *location)
+{
+    // Nested arrays are processed starting from outermost (arrayNestingIndex 0u) and ending at the
+    // innermost.
+    ShaderUniformCount shaderUniformCount;
+    const unsigned int currentArraySize = uniform.getNestedArraySize(arrayNestingIndex);
+    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);
+        }
+        else
+        {
+            shaderUniformCount += flattenStructUniform(
+                uniform.fields, elementName, elementMappedName, samplerUniforms, imageUniforms,
+                atomicCounterUniforms, shaderType, 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,
+    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);
+    }
+    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,
+    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);
+    }
+    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,
+    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);
+        }
+        else
+        {
+            shaderUniformCount += flattenStructUniform(
+                uniform.fields, fullName, fullMappedName, samplerUniforms, imageUniforms,
+                atomicCounterUniforms, shaderType, 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);
+    }
+
+    // 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)
+    {
+        uniformList = samplerUniforms;
+    }
+    else if (isImage)
+    {
+        uniformList = imageUniforms;
+    }
+    else if (isAtomicCounter)
+    {
+        uniformList = atomicCounterUniforms;
+    }
+
+    std::string fullNameWithArrayIndex(fullName);
+    std::string fullMappedNameWithArrayIndex(fullMappedName);
+
+    if (uniform.isArray())
+    {
+        // We're following the GLES 3.1 November 2016 spec section 7.3.1.1 Naming Active Resources
+        // and including [0] at the end of array variable names.
+        fullNameWithArrayIndex += "[0]";
+        fullMappedNameWithArrayIndex += "[0]";
+    }
+
+    LinkedUniform *existingUniform = FindUniform(*uniformList, fullNameWithArrayIndex);
+    if (existingUniform)
+    {
+        if (binding != -1)
+        {
+            existingUniform->binding = binding;
+        }
+        if (offset != -1)
+        {
+            existingUniform->offset = offset;
+        }
+        if (*location != -1)
+        {
+            existingUniform->location = *location;
+        }
+        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.staticUse                     = markStaticUse;
+        linkedUniform.flattenedOffsetInParentArrays = uniform.flattenedOffsetInParentArrays;
+        if (markStaticUse)
+        {
+            linkedUniform.setStaticUse(shaderType, true);
+        }
+
+        uniformList->push_back(linkedUniform);
+    }
+
+    // Struct and array of arrays uniforms get flattened so we can use getBasicTypeElementCount().
+    unsigned int elementCount = uniform.getBasicTypeElementCount();
+
+    // Samplers and images aren't "real" uniforms, so they don't count towards register usage.
+    // Likewise, don't count "real" uniforms towards opaque count.
+    shaderUniformCount.vectorCount =
+        (IsOpaqueType(uniform.type) ? 0 : (VariableRegisterCount(uniform.type) * elementCount));
+    shaderUniformCount.samplerCount       = (isSampler ? elementCount : 0);
+    shaderUniformCount.imageCount         = (isImage ? elementCount : 0);
+    shaderUniformCount.atomicCounterCount = (isAtomicCounter ? elementCount : 0);
+
+    if (*location != -1)
+    {
+        *location += elementCount;
+    }
+
+    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)
+        {
+            atomicCounterCount += uniform.getBasicTypeElementCount();
+            if (atomicCounterCount > caps.maxCombinedAtomicCounters)
+            {
+                infoLog << "atomic counter count exceeds MAX_COMBINED_ATOMIC_COUNTERS"
+                        << caps.maxCombinedAtomicCounters << ").";
+                return false;
+            }
+        }
+    }
+    return true;
+}
+
+// InterfaceBlockLinker implementation.
+InterfaceBlockLinker::InterfaceBlockLinker(std::vector<InterfaceBlock> *blocksOut)
+    : mBlocksOut(blocksOut)
+{
+}
+
+InterfaceBlockLinker::~InterfaceBlockLinker()
+{
+}
+
+void InterfaceBlockLinker::addShaderBlocks(GLenum 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;
+
+        for (const auto &block : *shaderBlocks.second)
+        {
+            // Only 'packed' blocks are allowed to be considered inactive.
+            if (!block.staticUse && block.layout == sh::BLOCKLAYOUT_PACKED)
+                continue;
+
+            if (visitedList.count(block.name) > 0)
+            {
+                if (block.staticUse)
+                {
+                    for (InterfaceBlock &priorBlock : *mBlocksOut)
+                    {
+                        if (block.name == priorBlock.name)
+                        {
+                            priorBlock.setStaticUse(shaderType, true);
+                            // TODO(jiajia.qin@intel.com): update the block members static use.
+                        }
+                    }
+                }
+            }
+            else
+            {
+                defineInterfaceBlock(getBlockSize, getMemberInfo, block, shaderType);
+                visitedList.insert(block.name);
+            }
+        }
+    }
+}
+
+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) 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;
+    }
+    for (unsigned int arrayElement = 0u; arrayElement < entryGenerationArraySize; ++arrayElement)
+    {
+        const std::string elementName       = prefix + ArrayString(arrayElement);
+        const std::string elementMappedName = mappedPrefix + ArrayString(arrayElement);
+        if (arrayNestingIndex + 1u < field.arraySizes.size())
+        {
+            defineArrayOfStructsBlockMembers(getMemberInfo, field, arrayNestingIndex + 1u,
+                                             elementName, elementMappedName, blockIndex, false,
+                                             topLevelArraySize);
+        }
+        else
+        {
+            defineBlockMembers(getMemberInfo, field.fields, elementName, elementMappedName,
+                               blockIndex, false, topLevelArraySize);
+        }
+    }
+}
+
+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) 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,
+                          singleEntryForTopLevelArray, topLevelArraySize);
+    }
+}
+
+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) 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.'
+        nextArraySize = field.getOutermostArraySize();
+    }
+
+    if (field.isStruct())
+    {
+        if (field.isArray())
+        {
+            defineArrayOfStructsBlockMembers(getMemberInfo, field, 0u, fullName, fullMappedName,
+                                             blockIndex, singleEntryForTopLevelArray,
+                                             nextArraySize);
+        }
+        else
+        {
+            ASSERT(nextArraySize == topLevelArraySize);
+            defineBlockMembers(getMemberInfo, field.fields, fullName, fullMappedName, blockIndex,
+                               false, nextArraySize);
+        }
+        return;
+    }
+    if (field.isArrayOfArrays())
+    {
+        unsigned int entryGenerationArraySize = field.getOutermostArraySize();
+        if (singleEntryForTopLevelArray)
+        {
+            entryGenerationArraySize = 1u;
+        }
+        for (unsigned int arrayElement = 0u; arrayElement < entryGenerationArraySize;
+             ++arrayElement)
+        {
+            VarT fieldElement = field;
+            fieldElement.indexIntoArray(arrayElement);
+            const std::string elementName       = fullName + ArrayString(arrayElement);
+            const std::string elementMappedName = fullMappedName + ArrayString(arrayElement);
+
+            defineBlockMember(getMemberInfo, fieldElement, elementName, elementMappedName,
+                              blockIndex, false, nextArraySize);
+        }
+        return;
+    }
+
+    // If getBlockMemberInfo returns false, the variable is optimized out.
+    sh::BlockMemberInfo memberInfo;
+    if (!getMemberInfo(fullName, fullMappedName, &memberInfo))
+    {
+        return;
+    }
+
+    std::string fullNameWithArrayIndex       = fullName;
+    std::string fullMappedNameWithArrayIndex = fullMappedName;
+
+    if (field.isArray())
+    {
+        fullNameWithArrayIndex += "[0]";
+        fullMappedNameWithArrayIndex += "[0]";
+    }
+
+    ASSERT(nextArraySize == topLevelArraySize);
+    defineBlockMemberImpl(field, fullNameWithArrayIndex, fullMappedNameWithArrayIndex, blockIndex,
+                          memberInfo, nextArraySize);
+}
+
+void InterfaceBlockLinker::defineInterfaceBlock(const GetBlockSize &getBlockSize,
+                                                const GetBlockMemberInfo &getMemberInfo,
+                                                const sh::InterfaceBlock &interfaceBlock,
+                                                GLenum 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();
+    defineBlockMembers(getMemberInfo, interfaceBlock.fields, interfaceBlock.fieldPrefix(),
+                       interfaceBlock.fieldMappedPrefix(), blockIndex,
+                       interfaceBlock.blockType == sh::BlockType::BLOCK_BUFFER, 1);
+    size_t lastBlockMemberIndex = getCurrentBlockMemberIndex();
+
+    for (size_t blockMemberIndex = firstBlockMemberIndex; blockMemberIndex < lastBlockMemberIndex;
+         ++blockMemberIndex)
+    {
+        blockIndexes.push_back(static_cast<unsigned int>(blockMemberIndex));
+    }
+
+    for (unsigned int arrayElement = 0; arrayElement < interfaceBlock.elementCount();
+         ++arrayElement)
+    {
+        std::string blockArrayName       = interfaceBlock.name;
+        std::string blockMappedArrayName = interfaceBlock.mappedName;
+        if (interfaceBlock.isArray())
+        {
+            blockArrayName += ArrayString(arrayElement);
+            blockMappedArrayName += ArrayString(arrayElement);
+        }
+
+        // Don't define this block at all if it's not active in the implementation.
+        if (!getBlockSize(blockArrayName, blockMappedArrayName, &blockSize))
+        {
+            continue;
+        }
+
+        // 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);
+
+        // 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);
+    }
+}
+
+// UniformBlockLinker implementation.
+UniformBlockLinker::UniformBlockLinker(std::vector<InterfaceBlock> *blocksOut,
+                                       std::vector<LinkedUniform> *uniformsOut)
+    : InterfaceBlockLinker(blocksOut), mUniformsOut(uniformsOut)
+{
+}
+
+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*/) const
+{
+    LinkedUniform newUniform(field.type, field.precision, fullName, field.arraySizes, -1, -1, -1,
+                             blockIndex, memberInfo);
+    newUniform.mappedName = fullMappedName;
+    // TODO(jiajia.qin@intel.com): update the block memeber static use.
+
+    // 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();
+}
+
+// ShaderStorageBlockLinker implementation.
+ShaderStorageBlockLinker::ShaderStorageBlockLinker(std::vector<InterfaceBlock> *blocksOut,
+                                                   std::vector<BufferVariable> *bufferVariablesOut)
+    : InterfaceBlockLinker(blocksOut), mBufferVariablesOut(bufferVariablesOut)
+{
+}
+
+ShaderStorageBlockLinker::~ShaderStorageBlockLinker()
+{
+}
+
+void ShaderStorageBlockLinker::defineBlockMemberImpl(const sh::ShaderVariable &field,
+                                                     const std::string &fullName,
+                                                     const std::string &fullMappedName,
+                                                     int blockIndex,
+                                                     const sh::BlockMemberInfo &memberInfo,
+                                                     int topLevelArraySize) const
+{
+    BufferVariable newBufferVariable(field.type, field.precision, fullName, field.arraySizes,
+                                     blockIndex, memberInfo);
+    newBufferVariable.mappedName = fullMappedName;
+    // TODO(jiajia.qin@intel.com): update the block memeber static use.
+
+    newBufferVariable.topLevelArraySize = topLevelArraySize;
+
+    mBufferVariablesOut->push_back(newBufferVariable);
+}
+
+size_t ShaderStorageBlockLinker::getCurrentBlockMemberIndex() const
+{
+    return mBufferVariablesOut->size();
+}
+
+// AtomicCounterBufferLinker implementation.
+AtomicCounterBufferLinker::AtomicCounterBufferLinker(
+    std::vector<AtomicCounterBuffer> *atomicCounterBuffersOut)
+    : mAtomicCounterBuffersOut(atomicCounterBuffersOut)
+{
+}
+
+AtomicCounterBufferLinker::~AtomicCounterBufferLinker()
+{
+}
+
+void AtomicCounterBufferLinker::link(const std::map<int, unsigned int> &sizeMap) const
+{
+    for (auto &atomicCounterBuffer : *mAtomicCounterBuffersOut)
+    {
+        auto bufferSize = sizeMap.find(atomicCounterBuffer.binding);
+        ASSERT(bufferSize != sizeMap.end());
+        atomicCounterBuffer.dataSize = bufferSize->second;
+    }
+}
+
+}  // namespace gl
new file mode 100644
--- /dev/null
+++ b/gfx/angle/src/libANGLE/ProgramLinkedResources.h
@@ -0,0 +1,308 @@
+//
+// 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.
+//
+
+// UniformLinker.h: implements link-time checks for default block uniforms, and generates 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/VaryingPacking.h"
+
+#include <functional>
+
+namespace sh
+{
+struct BlockMemberInfo;
+struct InterfaceBlock;
+struct ShaderVariable;
+struct Uniform;
+}
+
+namespace gl
+{
+struct BufferVariable;
+struct Caps;
+class Context;
+class InfoLog;
+struct InterfaceBlock;
+struct LinkedUniform;
+class ProgramState;
+class ProgramBindings;
+class Shader;
+struct VariableLocation;
+struct ShaderVariableBuffer;
+
+using AtomicCounterBuffer = ShaderVariableBuffer;
+
+class UniformLinker final : angle::NonCopyable
+{
+  public:
+    UniformLinker(const ProgramState &state);
+    ~UniformLinker();
+
+    bool link(const Context *context,
+              InfoLog &infoLog,
+              const ProgramBindings &uniformLocationBindings);
+
+    void getResults(std::vector<LinkedUniform> *uniforms,
+                    std::vector<VariableLocation> *uniformLocations);
+
+  private:
+    struct ShaderUniformCount
+    {
+        ShaderUniformCount() : vectorCount(0), samplerCount(0), imageCount(0), atomicCounterCount(0)
+        {
+        }
+        ShaderUniformCount(const ShaderUniformCount &other) = default;
+        ShaderUniformCount &operator=(const ShaderUniformCount &other) = default;
+
+        ShaderUniformCount &operator+=(const ShaderUniformCount &other)
+        {
+            vectorCount += other.vectorCount;
+            samplerCount += other.samplerCount;
+            imageCount += other.imageCount;
+            atomicCounterCount += other.atomicCounterCount;
+            return *this;
+        }
+
+        unsigned int vectorCount;
+        unsigned int samplerCount;
+        unsigned int imageCount;
+        unsigned int atomicCounterCount;
+    };
+
+    bool validateGraphicsUniforms(const Context *context, InfoLog &infoLog) const;
+
+    static bool LinkValidateUniforms(InfoLog &infoLog,
+                                     const std::string &uniformName,
+                                     const sh::Uniform &vertexUniform,
+                                     const sh::Uniform &fragmentUniform);
+
+    bool flattenUniformsAndCheckCapsForShader(const Context *context,
+                                              Shader *shader,
+                                              GLuint maxUniformComponents,
+                                              GLuint maxTextureImageUnits,
+                                              GLuint maxImageUnits,
+                                              GLuint maxAtomicCounters,
+                                              const std::string &componentsErrorMessage,
+                                              const std::string &samplerErrorMessage,
+                                              const std::string &imageErrorMessage,
+                                              const std::string &atomicCounterErrorMessage,
+                                              std::vector<LinkedUniform> &samplerUniforms,
+                                              std::vector<LinkedUniform> &imageUniforms,
+                                              std::vector<LinkedUniform> &atomicCounterUniforms,
+                                              InfoLog &infoLog);
+
+    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);
+
+    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,
+        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,
+                                            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,
+                                           bool markStaticUse,
+                                           int binding,
+                                           int offset,
+                                           int *location);
+
+    // markStaticUse is given as a separate parameter because it is 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,
+                                          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;
+};
+
+// This class is intended to be used during the link step to store interface block information.
+// It is called by the Impl class during ProgramImpl::link so that it has access to the
+// real block size and layout.
+class InterfaceBlockLinker : angle::NonCopyable
+{
+  public:
+    virtual ~InterfaceBlockLinker();
+
+    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);
+
+    // 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;
+
+    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) 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) const;
+
+    virtual void defineBlockMemberImpl(const sh::ShaderVariable &field,
+                                       const std::string &fullName,
+                                       const std::string &fullMappedName,
+                                       int blockIndex,
+                                       const sh::BlockMemberInfo &memberInfo,
+                                       int topLevelArraySize) const             = 0;
+    virtual size_t getCurrentBlockMemberIndex() const                           = 0;
+
+    using ShaderBlocks = std::pair<GLenum, 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) 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) const override;
+    size_t getCurrentBlockMemberIndex() const override;
+    std::vector<LinkedUniform> *mUniformsOut;
+};
+
+class ShaderStorageBlockLinker final : public InterfaceBlockLinker
+{
+  public:
+    ShaderStorageBlockLinker(std::vector<InterfaceBlock> *blocksOut,
+                             std::vector<BufferVariable> *bufferVariablesOut);
+    ~ShaderStorageBlockLinker() override;
+
+  private:
+    void defineBlockMemberImpl(const sh::ShaderVariable &field,
+                               const std::string &fullName,
+                               const std::string &fullMappedName,
+                               int blockIndex,
+                               const sh::BlockMemberInfo &memberInfo,
+                               int topLevelArraySize) const override;
+    size_t getCurrentBlockMemberIndex() const override;
+    std::vector<BufferVariable> *mBufferVariablesOut;
+};
+
+class AtomicCounterBufferLinker final : angle::NonCopyable
+{
+  public:
+    AtomicCounterBufferLinker(std::vector<AtomicCounterBuffer> *atomicCounterBuffersOut);
+    ~AtomicCounterBufferLinker();
+
+    void link(const std::map<int, unsigned int> &sizeMap) const;
+
+  private:
+    std::vector<AtomicCounterBuffer> *mAtomicCounterBuffersOut;
+};
+
+// The link operation is responsible for finishing the link of uniform and interface blocks.
+// This way it can filter out unreferenced resources and still have access to the info.
+// TODO(jmadill): Integrate uniform linking/filtering as well as interface blocks.
+struct ProgramLinkedResources
+{
+    VaryingPacking varyingPacking;
+    UniformBlockLinker uniformBlockLinker;
+    ShaderStorageBlockLinker shaderStorageBlockLinker;
+    AtomicCounterBufferLinker atomicCounterBufferLinker;
+};
+
+}  // namespace gl
+
+#endif  // LIBANGLE_UNIFORMLINKER_H_
--- a/gfx/angle/src/libANGLE/ProgramPipeline.cpp
+++ b/gfx/angle/src/libANGLE/ProgramPipeline.cpp
@@ -37,16 +37,21 @@ ProgramPipeline::ProgramPipeline(rx::GLI
     ASSERT(mProgramPipeline);
 }
 
 ProgramPipeline::~ProgramPipeline()
 {
     mProgramPipeline.release();
 }
 
+Error ProgramPipeline::onDestroy(const Context *context)
+{
+    return NoError();
+}
+
 void ProgramPipeline::setLabel(const std::string &label)
 {
     mState.mLabel = label;
 }
 
 const std::string &ProgramPipeline::getLabel() const
 {
     return mState.mLabel;
--- a/gfx/angle/src/libANGLE/ProgramPipeline.h
+++ b/gfx/angle/src/libANGLE/ProgramPipeline.h
@@ -43,17 +43,17 @@ class ProgramPipelineState final : angle
 };
 
 class ProgramPipeline final : public RefCountObject, public LabeledObject
 {
   public:
     ProgramPipeline(rx::GLImplFactory *factory, GLuint handle);
     ~ProgramPipeline() override;
 
-    Error onDestroy(const Context *context) override { return NoError(); }
+    Error onDestroy(const Context *context) override;
 
     void setLabel(const std::string &label) override;
     const std::string &getLabel() const override;
 
     rx::ProgramPipelineImpl *getImplementation() const;
 
   private:
     std::unique_ptr<rx::ProgramPipelineImpl> mProgramPipeline;
--- a/gfx/angle/src/libANGLE/Query.h
+++ b/gfx/angle/src/libANGLE/Query.h
@@ -25,17 +25,17 @@ class QueryImpl;
 namespace gl
 {
 
 class Query final : public RefCountObject, public LabeledObject
 {
   public:
     Query(rx::QueryImpl *impl, GLuint id);
     void destroy(const gl::Context *context) {}
-    virtual ~Query();
+    ~Query() override;
 
     void setLabel(const std::string &label) override;
     const std::string &getLabel() const override;
 
     Error begin();
     Error end();
     Error queryCounter();
     Error getResult(GLint *params);
--- a/gfx/angle/src/libANGLE/RefCountObject.h
+++ b/gfx/angle/src/libANGLE/RefCountObject.h
@@ -21,34 +21,34 @@
 namespace gl
 {
 class Context;
 
 class RefCountObjectNoID : angle::NonCopyable
 {
   public:
     RefCountObjectNoID() : mRefCount(0) {}
-    virtual Error onDestroy(const Context *context) { return NoError(); }
+    virtual Error onDestroy(const Context *context);
 
     void addRef() const { ++mRefCount; }
 
     void release() const
     {
         ASSERT(mRefCount > 0);
 
         if (--mRefCount == 0)
         {
             delete this;
         }
     }
 
     size_t getRefCount() const { return mRefCount; }
 
   protected:
-    virtual ~RefCountObjectNoID() { ASSERT(mRefCount == 0); }
+    virtual ~RefCountObjectNoID();
 
     // A specialized release method for objects which need a destroy context.
     void release(const gl::Context *context)
     {
         ASSERT(mRefCount > 0);
         if (--mRefCount == 0)
         {
             ANGLE_SWALLOW_ERR(onDestroy(context));
@@ -56,16 +56,26 @@ class RefCountObjectNoID : angle::NonCop
         }
     }
 
     template <class ObjectType>
     friend class BindingPointer;
     mutable std::size_t mRefCount;
 };
 
+inline RefCountObjectNoID::~RefCountObjectNoID()
+{
+    ASSERT(mRefCount == 0);
+}
+
+inline Error RefCountObjectNoID::onDestroy(const Context *context)
+{
+    return NoError();
+}
+
 template <class ObjectType>
 class BindingPointer;
 
 class RefCountObject : RefCountObjectNoID
 {
   public:
     explicit RefCountObject(GLuint id) : mId(id) {}
 
--- a/gfx/angle/src/libANGLE/Renderbuffer.cpp
+++ b/gfx/angle/src/libANGLE/Renderbuffer.cpp
@@ -21,17 +21,18 @@ namespace gl
 {
 Renderbuffer::Renderbuffer(rx::RenderbufferImpl *impl, GLuint id)
     : egl::ImageSibling(id),
       mRenderbuffer(impl),
       mLabel(),
       mWidth(0),
       mHeight(0),
       mFormat(GL_RGBA4),
-      mSamples(0)
+      mSamples(0),
+      mInitState(InitState::MayNeedInit)
 {
 }
 
 Error Renderbuffer::onDestroy(const Context *context)
 {
     ANGLE_TRY(orphanImages(context));
 
     if (mRenderbuffer)
@@ -66,17 +67,18 @@ Error Renderbuffer::setStorage(const Con
 
     ANGLE_TRY(mRenderbuffer->setStorage(context, internalformat, width, height));
 
     mWidth          = static_cast<GLsizei>(width);
     mHeight         = static_cast<GLsizei>(height);
     mFormat         = Format(internalformat);
     mSamples = 0;
 
-    mDirtyChannel.signal();
+    mInitState = InitState::MayNeedInit;
+    mDirtyChannel.signal(mInitState);
 
     return NoError();
 }
 
 Error Renderbuffer::setStorageMultisample(const Context *context,
                                           size_t samples,
                                           GLenum internalformat,
                                           size_t width,
@@ -87,17 +89,18 @@ Error Renderbuffer::setStorageMultisampl
     ANGLE_TRY(
         mRenderbuffer->setStorageMultisample(context, samples, internalformat, width, height));
 
     mWidth          = static_cast<GLsizei>(width);
     mHeight         = static_cast<GLsizei>(height);
     mFormat         = Format(internalformat);
     mSamples        = static_cast<GLsizei>(samples);
 
-    mDirtyChannel.signal();
+    mInitState = InitState::MayNeedInit;
+    mDirtyChannel.signal(mInitState);
 
     return NoError();
 }
 
 Error Renderbuffer::setStorageEGLImageTarget(const Context *context, egl::Image *image)
 {
     ANGLE_TRY(orphanImages(context));
 
@@ -105,17 +108,18 @@ Error Renderbuffer::setStorageEGLImageTa
 
     setTargetImage(context, image);
 
     mWidth          = static_cast<GLsizei>(image->getWidth());
     mHeight         = static_cast<GLsizei>(image->getHeight());
     mFormat         = Format(image->getFormat());
     mSamples        = 0;
 
-    mDirtyChannel.signal();
+    mInitState = image->sourceInitState();
+    mDirtyChannel.signal(mInitState);
 
     return NoError();
 }
 
 rx::RenderbufferImpl *Renderbuffer::getImplementation() const
 {
     ASSERT(mRenderbuffer);
     return mRenderbuffer;
@@ -185,9 +189,47 @@ GLuint Renderbuffer::getId() const
 {
     return id();
 }
 
 Extents Renderbuffer::getAttachmentSize(const gl::ImageIndex & /*imageIndex*/) const
 {
     return Extents(mWidth, mHeight, 1);
 }
+
+const Format &Renderbuffer::getAttachmentFormat(GLenum /*binding*/,
+                                                const ImageIndex & /*imageIndex*/) const
+{
+    return getFormat();
+}
+GLsizei Renderbuffer::getAttachmentSamples(const ImageIndex & /*imageIndex*/) const
+{
+    return getSamples();
+}
+
+InitState Renderbuffer::initState(const gl::ImageIndex & /*imageIndex*/) const
+{
+    if (isEGLImageTarget())
+    {
+        return sourceEGLImageInitState();
+    }
+
+    return mInitState;
+}
+
+void Renderbuffer::setInitState(const gl::ImageIndex & /*imageIndex*/, InitState initState)
+{
+    if (isEGLImageTarget())
+    {
+        setSourceEGLImageInitState(initState);
+    }
+    else
+    {
+        mInitState = initState;
+    }
+}
+
+rx::FramebufferAttachmentObjectImpl *Renderbuffer::getAttachmentImpl() const
+{
+    return mRenderbuffer;
+}
+
 }  // namespace gl
--- a/gfx/angle/src/libANGLE/Renderbuffer.h
+++ b/gfx/angle/src/libANGLE/Renderbuffer.h
@@ -27,17 +27,17 @@ namespace gl
 // FramebufferAttachment and Framebuffer for how they are applied to an FBO via an
 // attachment point.
 
 class Renderbuffer final : public egl::ImageSibling,
                            public LabeledObject
 {
   public:
     Renderbuffer(rx::RenderbufferImpl *impl, GLuint id);
-    virtual ~Renderbuffer();
+    ~Renderbuffer() override;
 
     Error onDestroy(const Context *context) override;
 
     void setLabel(const std::string &label) override;
     const std::string &getLabel() const override;
 
     Error setStorage(const Context *context, GLenum internalformat, size_t width, size_t height);
     Error setStorageMultisample(const Context *context,
@@ -57,38 +57,37 @@ class Renderbuffer final : public egl::I
     GLuint getGreenSize() const;
     GLuint getBlueSize() const;
     GLuint getAlphaSize() const;
     GLuint getDepthSize() const;
     GLuint getStencilSize() const;
 
     // FramebufferAttachmentObject Impl
     Extents getAttachmentSize(const ImageIndex &imageIndex) const override;
-    const Format &getAttachmentFormat(GLenum /*binding*/,
-                                      const ImageIndex & /*imageIndex*/) const override
-    {
-        return getFormat();
-    }
-    GLsizei getAttachmentSamples(const ImageIndex & /*imageIndex*/) const override
-    {
-        return getSamples();
-    }
+    const Format &getAttachmentFormat(GLenum binding, const ImageIndex &imageIndex) const override;
+    GLsizei getAttachmentSamples(const ImageIndex &imageIndex) const override;
 
     void onAttach(const Context *context) override;
     void onDetach(const Context *context) override;
     GLuint getId() const override;
 
+    InitState initState(const ImageIndex &imageIndex) const override;
+    void setInitState(const ImageIndex &imageIndex, InitState initState) override;
+
   private:
-    rx::FramebufferAttachmentObjectImpl *getAttachmentImpl() const override { return mRenderbuffer; }
+    rx::FramebufferAttachmentObjectImpl *getAttachmentImpl() const override;
 
     rx::RenderbufferImpl *mRenderbuffer;
 
     std::string mLabel;
 
     GLsizei mWidth;
     GLsizei mHeight;
     Format mFormat;
     GLsizei mSamples;
+
+    // For robust resource init.
+    InitState mInitState;
 };
 
-}
+}  // namespace gl
 
 #endif   // LIBANGLE_RENDERBUFFER_H_
--- a/gfx/angle/src/libANGLE/ResourceManager.cpp
+++ b/gfx/angle/src/libANGLE/ResourceManager.cpp
@@ -130,16 +130,20 @@ GLuint BufferManager::createBuffer()
 
 Buffer *BufferManager::getBuffer(GLuint handle) const
 {
     return mObjectMap.query(handle);
 }
 
 // ShaderProgramManager Implementation.
 
+ShaderProgramManager::ShaderProgramManager()
+{
+}
+
 ShaderProgramManager::~ShaderProgramManager()
 {
     ASSERT(mPrograms.empty());
     ASSERT(mShaders.empty());
 }
 
 void ShaderProgramManager::reset(const Context *context)
 {
@@ -154,17 +158,18 @@ void ShaderProgramManager::reset(const C
     }
     mShaders.clear();
 }
 
 GLuint ShaderProgramManager::createShader(rx::GLImplFactory *factory,
                                           const gl::Limitations &rendererLimitations,
                                           GLenum type)
 {
-    ASSERT(type == GL_VERTEX_SHADER || type == GL_FRAGMENT_SHADER || type == GL_COMPUTE_SHADER);
+    ASSERT(type == GL_VERTEX_SHADER || type == GL_FRAGMENT_SHADER || type == GL_COMPUTE_SHADER ||
+           type == GL_GEOMETRY_SHADER_EXT);
     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);
@@ -243,21 +248,28 @@ Texture *TextureManager::getTexture(GLui
 }
 
 void TextureManager::signalAllTexturesDirty() const
 {
     for (const auto &texture : mObjectMap)
     {
         if (texture.second)
         {
-            texture.second->signalDirty();
+            // We don't know if the Texture needs init, but that's ok, since it will only force
+            // a re-check, and will not initialize the pixels if it's not needed.
+            texture.second->signalDirty(InitState::MayNeedInit);
         }
     }
 }
 
+void TextureManager::enableHandleAllocatorLogging()
+{
+    mHandleAllocator.enableLogging(true);
+}
+
 // RenderbufferManager Implementation.
 
 // static
 Renderbuffer *RenderbufferManager::AllocateNewObject(rx::GLImplFactory *factory, GLuint handle)
 {
     Renderbuffer *renderbuffer = new Renderbuffer(factory->createRenderbuffer(), handle);
     renderbuffer->addRef();
     return renderbuffer;
@@ -329,33 +341,37 @@ GLuint SyncManager::createSync(rx::GLImp
 
 Sync *SyncManager::getSync(GLuint handle) const
 {
     return mObjectMap.query(handle);
 }
 
 // PathManager Implementation.
 
+PathManager::PathManager()
+{
+}
+
 ErrorOrResult<GLuint> PathManager::createPaths(rx::GLImplFactory *factory, GLsizei range)
 {
     // Allocate client side handles.
     const GLuint client = mHandleAllocator.allocateRange(static_cast<GLuint>(range));
     if (client == HandleRangeAllocator::kInvalidHandle)
         return OutOfMemory() << "Failed to allocate path handle range.";
 
     const auto &paths = factory->createPaths(range);
     if (paths.empty())
     {
         mHandleAllocator.releaseRange(client, range);
         return OutOfMemory() << "Failed to allocate path objects.";
     }
 
     for (GLsizei i = 0; i < range; ++i)
     {
-        const auto impl = paths[static_cast<unsigned>(i)];
+        rx::PathImpl *impl = paths[static_cast<unsigned>(i)];
         const auto id   = client + i;
         mPaths.assign(id, new Path(impl));
     }
     return client;
 }
 
 void PathManager::deletePaths(GLuint first, GLsizei range)
 {
--- a/gfx/angle/src/libANGLE/ResourceManager.h
+++ b/gfx/angle/src/libANGLE/ResourceManager.h
@@ -121,16 +121,18 @@ class BufferManager : public TypedResour
 
   protected:
     ~BufferManager() override {}
 };
 
 class ShaderProgramManager : public ResourceManagerBase<HandleAllocator>
 {
   public:
+    ShaderProgramManager();
+
     GLuint createShader(rx::GLImplFactory *factory,
                         const Limitations &rendererLimitations,
                         GLenum 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);
@@ -160,16 +162,18 @@ class TextureManager : public TypedResou
     Texture *checkTextureAllocation(rx::GLImplFactory *factory, GLuint handle, GLenum target)
     {
         return checkObjectAllocation(factory, handle, target);
     }
 
     static Texture *AllocateNewObject(rx::GLImplFactory *factory, GLuint handle, GLenum target);
     static void DeleteObject(const Context *context, Texture *texture);
 
+    void enableHandleAllocatorLogging();
+
   protected:
     ~TextureManager() override {}
 };
 
 class RenderbufferManager
     : public TypedResourceManager<Renderbuffer, HandleAllocator, RenderbufferManager>
 {
   public:
@@ -217,16 +221,18 @@ class SyncManager : public TypedResource
 
   protected:
     ~SyncManager() override {}
 };
 
 class PathManager : public ResourceManagerBase<HandleRangeAllocator>
 {
   public:
+    PathManager();
+
     ErrorOrResult<GLuint> createPaths(rx::GLImplFactory *factory, GLsizei range);
     void deletePaths(GLuint first, GLsizei range);
     Path *getPath(GLuint handle) const;
     bool hasPath(GLuint handle) const;
 
   protected:
     ~PathManager() override;
     void reset(const Context *context) override;
--- a/gfx/angle/src/libANGLE/Sampler.cpp
+++ b/gfx/angle/src/libANGLE/Sampler.cpp
@@ -20,16 +20,21 @@ Sampler::Sampler(rx::GLImplFactory *fact
 {
 }
 
 Sampler::~Sampler()
 {
     SafeDelete(mImpl);
 }
 
+Error Sampler::onDestroy(const Context *context)
+{
+    return NoError();
+}
+
 void Sampler::setLabel(const std::string &label)
 {
     mLabel = label;
 }
 
 const std::string &Sampler::getLabel() const
 {
     return mLabel;
--- a/gfx/angle/src/libANGLE/Sampler.h
+++ b/gfx/angle/src/libANGLE/Sampler.h
@@ -24,17 +24,17 @@ namespace gl
 {
 
 class Sampler final : public RefCountObject, public LabeledObject
 {
   public:
     Sampler(rx::GLImplFactory *factory, GLuint id);
     ~Sampler() override;
 
-    Error onDestroy(const Context *context) override { return NoError(); }
+    Error onDestroy(const Context *context) override;
 
     void setLabel(const std::string &label) override;
     const std::string &getLabel() const override;
 
     void setMinFilter(GLenum minFilter);
     GLenum getMinFilter() const;
 
     void setMagFilter(GLenum magFilter);
--- a/gfx/angle/src/libANGLE/Shader.cpp
+++ b/gfx/angle/src/libANGLE/Shader.cpp
@@ -52,17 +52,17 @@ const std::vector<VarT> &GetShaderVariab
 
 }  // anonymous namespace
 
 // true if varying x has a higher priority in packing than y
 bool CompareShaderVar(const sh::ShaderVariable &x, const sh::ShaderVariable &y)
 {
     if (x.type == y.type)
     {
-        return x.arraySize > y.arraySize;
+        return x.getArraySizeProduct() > y.getArraySizeProduct();
     }
 
     // Special case for handling structs: we sort these to the end of the list
     if (x.type == GL_NONE)
     {
         return false;
     }
 
@@ -74,16 +74,20 @@ bool CompareShaderVar(const sh::ShaderVa
     return gl::VariableSortOrder(x.type) < gl::VariableSortOrder(y.type);
 }
 
 ShaderState::ShaderState(GLenum shaderType)
     : mLabel(),
       mShaderType(shaderType),
       mShaderVersion(100),
       mNumViews(-1),
+      mGeometryShaderInputPrimitiveType(GL_INVALID_VALUE),
+      mGeometryShaderOutputPrimitiveType(GL_INVALID_VALUE),
+      mGeometryShaderInvocations(1),
+      mGeometryShaderMaxVertices(-1),
       mCompileStatus(CompileStatus::NOT_COMPILED)
 {
     mLocalSize.fill(-1);
 }
 
 ShaderState::~ShaderState()
 {
 }
@@ -263,23 +267,28 @@ void Shader::getTranslatedSourceWithDebu
     GetSourceImpl(debugInfo, bufSize, length, buffer);
 }
 
 void Shader::compile(const Context *context)
 {
     mState.mTranslatedSource.clear();
     mInfoLog.clear();
     mState.mShaderVersion = 100;
-    mState.mVaryings.clear();
+    mState.mInputVaryings.clear();
+    mState.mOutputVaryings.clear();
     mState.mUniforms.clear();
     mState.mUniformBlocks.clear();
     mState.mShaderStorageBlocks.clear();
     mState.mActiveAttributes.clear();
     mState.mActiveOutputVariables.clear();
     mState.mNumViews = -1;
+    mState.mGeometryShaderInputPrimitiveType  = GL_INVALID_VALUE;
+    mState.mGeometryShaderOutputPrimitiveType = GL_INVALID_VALUE;
+    mState.mGeometryShaderInvocations         = 1;
+    mState.mGeometryShaderMaxVertices         = -1;
 
     mState.mCompileStatus = CompileStatus::COMPILE_REQUESTED;
     mBoundCompiler.set(context, context->getCompiler());
 
     // Cache the compile source and options for compilation. Must be done now, since the source
     // can change before the link call or another call that resolves the compile.
 
     std::stringstream sourceStream;
@@ -355,45 +364,59 @@ void Shader::resolveCompile(const Contex
     shaderStream << "\n\n";
     shaderStream << mState.mTranslatedSource;
     mState.mTranslatedSource = shaderStream.str();
 #endif  // !defined(NDEBUG)
 
     // Gather the shader information
     mState.mShaderVersion = sh::GetShaderVersion(compilerHandle);
 
-    mState.mVaryings        = GetShaderVariables(sh::GetVaryings(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:
         {
             mState.mLocalSize = sh::GetComputeShaderLocalGroupSize(compilerHandle);
             break;
         }
         case GL_VERTEX_SHADER:
         {
             {
+                mState.mOutputVaryings = GetShaderVariables(sh::GetOutputVaryings(compilerHandle));
                 mState.mActiveAttributes =
                     GetActiveShaderVariables(sh::GetAttributes(compilerHandle));
                 mState.mNumViews = sh::GetVertexShaderNumViews(compilerHandle);
             }
             break;
         }
         case GL_FRAGMENT_SHADER:
         {
+            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.mVaryings.begin(), mState.mVaryings.end(), CompareShaderVar);
+            std::sort(mState.mInputVaryings.begin(), mState.mInputVaryings.end(), CompareShaderVar);
             mState.mActiveOutputVariables =
                 GetActiveShaderVariables(sh::GetOutputVariables(compilerHandle));
             break;
         }
+        case GL_GEOMETRY_SHADER_EXT:
+        {
+            mState.mInputVaryings  = GetShaderVariables(sh::GetInputVaryings(compilerHandle));
+            mState.mOutputVaryings = GetShaderVariables(sh::GetOutputVaryings(compilerHandle));
+
+            mState.mGeometryShaderInputPrimitiveType =
+                sh::GetGeometryShaderInputPrimitiveType(compilerHandle);
+            mState.mGeometryShaderOutputPrimitiveType =
+                sh::GetGeometryShaderOutputPrimitiveType(compilerHandle);
+            mState.mGeometryShaderInvocations = sh::GetGeometryShaderInvocations(compilerHandle);
+            mState.mGeometryShaderMaxVertices = sh::GetGeometryShaderMaxVertices(compilerHandle);
+            break;
+        }
         default:
             UNREACHABLE();
     }
 
     ASSERT(!mState.mTranslatedSource.empty());
 
     bool success = mImplementation->postTranslateCompile(mBoundCompiler.get(), &mInfoLog);
     mState.mCompileStatus = success ? CompileStatus::COMPILED : CompileStatus::NOT_COMPILED;
@@ -436,20 +459,26 @@ bool Shader::isCompiled(const Context *c
 }
 
 int Shader::getShaderVersion(const Context *context)
 {
     resolveCompile(context);
     return mState.mShaderVersion;
 }
 
-const std::vector<sh::Varying> &Shader::getVaryings(const Context *context)
+const std::vector<sh::Varying> &Shader::getInputVaryings(const Context *context)
 {
     resolveCompile(context);
-    return mState.getVaryings();
+    return mState.getInputVaryings();
+}
+
+const std::vector<sh::Varying> &Shader::getOutputVaryings(const Context *context)
+{
+    resolveCompile(context);
+    return mState.getOutputVaryings();
 }
 
 const std::vector<sh::Uniform> &Shader::getUniforms(const Context *context)
 {
     resolveCompile(context);
     return mState.getUniforms();
 }
 
@@ -475,17 +504,19 @@ const std::vector<sh::OutputVariable> &S
 {
     resolveCompile(context);
     return mState.getActiveOutputVariables();
 }
 
 std::string Shader::getTransformFeedbackVaryingMappedName(const std::string &tfVaryingName,
                                                           const Context *context)
 {
-    const auto &varyings = getVaryings(context);
+    // TODO(jiawei.shao@intel.com): support transform feedback on geometry shader.
+    ASSERT(mState.getShaderType() == GL_VERTEX_SHADER);
+    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)
             {
@@ -498,16 +529,22 @@ std::string Shader::getTransformFeedback
     else
     {
         for (const auto &varying : varyings)
         {
             if (varying.name == tfVaryingName)
             {
                 return varying.mappedName;
             }
+            else if (varying.isStruct())
+            {
+                const auto *field = FindShaderVarField(varying, tfVaryingName);
+                ASSERT(field != nullptr && !field->isStruct() && !field->isArray());
+                return varying.mappedName + "." + field->mappedName;
+            }
         }
     }
     UNREACHABLE();
     return std::string();
 }
 
 const sh::WorkGroupSize &Shader::getWorkGroupSize(const Context *context)
 {
--- a/gfx/angle/src/libANGLE/Shader.h
+++ b/gfx/angle/src/libANGLE/Shader.h
@@ -57,17 +57,18 @@ class ShaderState final : angle::NonCopy
     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; }
     int getShaderVersion() const { return mShaderVersion; }
 
-    const std::vector<sh::Varying> &getVaryings() const { return mVaryings; }
+    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::OutputVariable> &getActiveOutputVariables() const
@@ -84,26 +85,33 @@ class ShaderState final : angle::NonCopy
 
     GLenum mShaderType;
     int mShaderVersion;
     std::string mTranslatedSource;
     std::string mSource;
 
     sh::WorkGroupSize mLocalSize;
 
-    std::vector<sh::Varying> mVaryings;
+    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> mActiveAttributes;
     std::vector<sh::OutputVariable> mActiveOutputVariables;
 
     // ANGLE_multiview.
     int mNumViews;
 
+    // Geometry Shader.
+    GLenum mGeometryShaderInputPrimitiveType;
+    GLenum mGeometryShaderOutputPrimitiveType;
+    int mGeometryShaderInvocations;
+    int mGeometryShaderMaxVertices;
+
     // Indicates if this shader has been successfully compiled
     CompileStatus mCompileStatus;
 };
 
 class Shader final : angle::NonCopyable, public LabeledObject
 {
   public:
     Shader(ShaderProgramManager *manager,
@@ -146,17 +154,18 @@ class Shader final : angle::NonCopyable,
     void addRef();
     void release(const Context *context);
     unsigned int getRefCount() const;
     bool isFlaggedForDeletion() const;
     void flagForDeletion();
 
     int getShaderVersion(const Context *context);
 
-    const std::vector<sh::Varying> &getVaryings(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::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
@@ -166,17 +175,17 @@ class Shader final : angle::NonCopyable,
 
     const sh::WorkGroupSize &getWorkGroupSize(const Context *context);
 
     int getNumViews(const Context *context);
 
     const std::string &getCompilerResourcesString() const;
 
   private:
-    virtual ~Shader();
+    ~Shader() override;
     static void GetSourceImpl(const std::string &source,
                               GLsizei bufSize,
                               GLsizei *length,
                               char *buffer);
 
     void resolveCompile(const Context *context);
 
     ShaderState mState;
--- a/gfx/angle/src/libANGLE/SizedMRUCache.h
+++ b/gfx/angle/src/libANGLE/SizedMRUCache.h
@@ -4,17 +4,17 @@
 // found in the LICENSE file.
 //
 // SizedMRUCache.h: A hashing map that stores blobs of sized, untyped data.
 
 #ifndef LIBANGLE_SIZED_MRU_CACHE_H_
 #define LIBANGLE_SIZED_MRU_CACHE_H_
 
 #include <anglebase/containers/mru_cache.h>
-#include "common/third_party/murmurhash/MurmurHash3.h"
+#include "common/third_party/smhasher/src/PMurHash.h"
 
 namespace angle
 {
 
 template <typename Key, typename Value>
 class SizedMRUCache final : angle::NonCopyable
 {
   public:
@@ -153,20 +153,22 @@ void TrimCache(size_t maxStates, size_t 
     if (cache->size() >= kGarbageCollectionLimit)
     {
         WARN() << "Overflowed the " << name << " cache limit of " << (maxStates / 2)
                << " elements, removing the least recently used to make room.";
         cache->ShrinkToSize(maxStates / 2);
     }
 }
 
+// Computes a hash of struct "key". Any structs passed to this function must be multiples of
+// 4 bytes, since the PMurhHas32 method can only operate increments of 4-byte words.
 template <typename T>
 std::size_t ComputeGenericHash(const T &key)
 {
     static const unsigned int seed = 0xABCDEF98;
 
-    std::size_t hash = 0;
-    MurmurHash3_x86_32(&key, sizeof(key), seed, &hash);
-    return hash;
+    // We can't support "odd" alignments.
+    static_assert(sizeof(key) % 4 == 0, "ComputeGenericHash requires aligned types");
+    return PMurHash32(seed, &key, sizeof(T));
 }
 
 }  // namespace angle
 #endif  // LIBANGLE_SIZED_MRU_CACHE_H_
--- a/gfx/angle/src/libANGLE/State.cpp
+++ b/gfx/angle/src/libANGLE/State.cpp
@@ -7,26 +7,28 @@
 // State.cpp: Implements the State class, encapsulating raw GL state.
 
 #include "libANGLE/State.h"
 
 #include <limits>
 #include <string.h>
 
 #include "common/bitset_utils.h"
+#include "common/mathutil.h"
 #include "common/matrix_utils.h"
-#include "common/mathutil.h"
+#include "libANGLE/Caps.h"
 #include "libANGLE/Context.h"
-#include "libANGLE/Caps.h"
 #include "libANGLE/Debug.h"
 #include "libANGLE/Framebuffer.h"
 #include "libANGLE/FramebufferAttachment.h"
 #include "libANGLE/Query.h"
 #include "libANGLE/VertexArray.h"
 #include "libANGLE/formatutils.h"
+#include "libANGLE/queryconversions.h"
+#include "libANGLE/renderer/ContextImpl.h"
 
 namespace
 {
 
 GLenum ActiveQueryType(const GLenum type)
 {
     return (type == GL_ANY_SAMPLES_PASSED_CONSERVATIVE) ? GL_ANY_SAMPLES_PASSED : type;
 }
@@ -78,16 +80,17 @@ void State::initialize(const Context *co
                        bool debug,
                        bool bindGeneratesResource,
                        bool clientArraysEnabled,
                        bool robustResourceInit,
                        bool programBinaryCacheEnabled)
 {
     const Caps &caps             = context->getCaps();
     const Extensions &extensions = context->getExtensions();
+    const Extensions &nativeExtensions = context->getImplementation()->getNativeExtensions();
     const Version &clientVersion = context->getClientVersion();
 
     mMaxDrawBuffers = caps.maxDrawBuffers;
     mMaxCombinedTextureImageUnits = caps.maxCombinedTextureImageUnits;
 
     setColorClearValue(0.0f, 0.0f, 0.0f, 0.0f);
 
     mDepthClearValue = 1.0f;
@@ -134,16 +137,22 @@ void State::initialize(const Context *co
     mBlend.colorMaskGreen = 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);
     if (clientVersion >= Version(3, 0))
     {
         // TODO: These could also be enabled via extension
         mSamplerTextures[GL_TEXTURE_2D_ARRAY].resize(caps.maxCombinedTextureImageUnits);
@@ -152,26 +161,27 @@ void State::initialize(const Context *co
     if (clientVersion >= Version(3, 1))
     {
         mSamplerTextures[GL_TEXTURE_2D_MULTISAMPLE].resize(caps.maxCombinedTextureImageUnits);
 
         mAtomicCounterBuffers.resize(caps.maxAtomicCounterBufferBindings);
         mShaderStorageBuffers.resize(caps.maxShaderStorageBufferBindings);
         mImageUnits.resize(caps.maxImageUnits);
     }
-    if (extensions.textureRectangle)
+    if (nativeExtensions.textureRectangle)
     {
         mSamplerTextures[GL_TEXTURE_RECTANGLE_ANGLE].resize(caps.maxCombinedTextureImageUnits);
     }
-    if (extensions.eglImageExternal || extensions.eglStreamConsumerExternal)
+    if (nativeExtensions.eglImageExternal || nativeExtensions.eglStreamConsumerExternal)
     {
         mSamplerTextures[GL_TEXTURE_EXTERNAL_OES].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(OnAttachmentDirtyBinding(this, textureIndex));
     }
 
     mSamplers.resize(caps.maxCombinedTextureImageUnits);
 
@@ -186,21 +196,18 @@ void State::initialize(const Context *co
     mReadFramebuffer = nullptr;
     mDrawFramebuffer = nullptr;
 
     mPrimitiveRestart = false;
 
     mDebug.setOutputEnabled(debug);
     mDebug.setMaxLoggedMessages(extensions.maxDebugLoggedMessages);
 
-    if (extensions.framebufferMultisample)
-    {
-        mMultiSampling = true;
-        mSampleAlphaToOne = false;
-    }
+    mMultiSampling    = true;
+    mSampleAlphaToOne = false;
 
     mCoverageModulation = GL_NONE;
 
     angle::Matrix<GLfloat>::setToIdentity(mPathMatrixProj);
     angle::Matrix<GLfloat>::setToIdentity(mPathMatrixMV);
     mPathStencilFunc = GL_ALWAYS;
     mPathStencilRef  = 0;
     mPathStencilMask = std::numeric_limits<GLuint>::max();
@@ -229,54 +236,48 @@ void State::reset(const Context *context
         imageUnit.texture.set(context, nullptr);
         imageUnit.level   = 0;
         imageUnit.layered = false;
         imageUnit.layer   = 0;
         imageUnit.access  = GL_READ_ONLY;
         imageUnit.format  = GL_R32UI;
     }
 
-    mArrayBuffer.set(context, nullptr);
-    mDrawIndirectBuffer.set(context, nullptr);
     mRenderbuffer.set(context, nullptr);
 
+    for (auto type : angle::AllEnums<BufferBinding>())
+    {
+        mBoundBuffers[type].set(context, nullptr);
+    }
+
     if (mProgram)
     {
         mProgram->release(context);
     }
     mProgram = nullptr;
 
     mProgramPipeline.set(context, nullptr);
 
     mTransformFeedback.set(context, nullptr);
 
     for (State::ActiveQueryMap::iterator i = mActiveQueries.begin(); i != mActiveQueries.end(); i++)
     {
         i->second.set(context, nullptr);
     }
 
-    mGenericUniformBuffer.set(context, nullptr);
-    for (BufferVector::iterator bufItr = mUniformBuffers.begin(); bufItr != mUniformBuffers.end(); ++bufItr)
+    for (auto &buf : mUniformBuffers)
     {
-        bufItr->set(context, nullptr);
+        buf.set(context, nullptr);
     }
 
-    mCopyReadBuffer.set(context, nullptr);
-    mCopyWriteBuffer.set(context, nullptr);
-
-    mPack.pixelBuffer.set(context, nullptr);
-    mUnpack.pixelBuffer.set(context, nullptr);
-
-    mGenericAtomicCounterBuffer.set(context, nullptr);
     for (auto &buf : mAtomicCounterBuffers)
     {
         buf.set(context, nullptr);
     }
 
-    mGenericShaderStorageBuffer.set(context, nullptr);
     for (auto &buf : mShaderStorageBuffers)
     {
         buf.set(context, nullptr);
     }
 
     angle::Matrix<GLfloat>::setToIdentity(mPathMatrixProj);
     angle::Matrix<GLfloat>::setToIdentity(mPathMatrixMV);
     mPathStencilFunc = GL_ALWAYS;
@@ -355,17 +356,17 @@ bool State::isCullFaceEnabled() const
 }
 
 void State::setCullFace(bool enabled)
 {
     mRasterizer.cullFace = enabled;
     mDirtyBits.set(DIRTY_BIT_CULL_FACE_ENABLED);
 }
 
-void State::setCullMode(GLenum mode)
+void State::setCullMode(CullFaceMode mode)
 {
     mRasterizer.cullMode = mode;
     mDirtyBits.set(DIRTY_BIT_CULL_FACE);
 }
 
 void State::setFrontFace(GLenum front)
 {
     mRasterizer.frontFace = front;
@@ -580,17 +581,18 @@ void State::setSampleMaskEnabled(bool en
     mSampleMask = enabled;
     mDirtyBits.set(DIRTY_BIT_SAMPLE_MASK_ENABLED);
 }
 
 void State::setSampleMaskParams(GLuint maskNumber, GLbitfield mask)
 {
     ASSERT(maskNumber < mMaxSampleMaskWords);
     mSampleMaskValues[maskNumber] = mask;
-    mDirtyBits.set(DIRTY_BIT_SAMPLE_MASK_WORD_0 + maskNumber);
+    // TODO(jmadill): Use a child dirty bit if we ever use more than two words.
+    mDirtyBits.set(DIRTY_BIT_SAMPLE_MASK);
 }
 
 GLbitfield State::getSampleMaskWord(GLuint maskNumber) const
 {
     ASSERT(maskNumber < mMaxSampleMaskWords);
     return mSampleMaskValues[maskNumber];
 }
 
@@ -725,17 +727,17 @@ bool State::getEnableFeature(GLenum feat
       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_CONTEXT_ROBUST_RESOURCE_INITIALIZATION_ANGLE:
+      case GL_ROBUST_RESOURCE_INITIALIZATION_ANGLE:
           return mRobustResourceInit;
       case GL_PROGRAM_CACHE_ENABLED_ANGLE:
           return mProgramBinaryCacheEnabled;
 
       default:
           UNREACHABLE();
           return false;
     }
@@ -1092,22 +1094,16 @@ bool State::removeVertexArrayBinding(GLu
         mDirtyBits.set(DIRTY_BIT_VERTEX_ARRAY_BINDING);
         mDirtyObjects.set(DIRTY_OBJECT_VERTEX_ARRAY);
         return true;
     }
 
     return false;
 }
 
-void State::setElementArrayBuffer(const Context *context, Buffer *buffer)
-{
-    getVertexArray()->setElementArrayBuffer(context, buffer);
-    mDirtyObjects.set(DIRTY_OBJECT_VERTEX_ARRAY);
-}
-
 void State::bindVertexBuffer(const Context *context,
                              GLuint bindingIndex,
                              Buffer *boundBuffer,
                              GLintptr offset,
                              GLsizei stride)
 {
     getVertexArray()->bindVertexBuffer(context, bindingIndex, boundBuffer, offset, stride);
     mDirtyObjects.set(DIRTY_OBJECT_VERTEX_ARRAY);
@@ -1162,16 +1158,17 @@ Program *State::getProgram() const
 {
     return mProgram;
 }
 
 void State::setTransformFeedbackBinding(const Context *context,
                                         TransformFeedback *transformFeedback)
 {
     mTransformFeedback.set(context, transformFeedback);
+    mDirtyBits.set(DIRTY_BIT_TRANSFORM_FEEDBACK_BINDING);
 }
 
 TransformFeedback *State::getCurrentTransformFeedback() const
 {
     return mTransformFeedback.get();
 }
 
 bool State::isTransformFeedbackActiveUnpaused() const
@@ -1244,151 +1241,123 @@ Query *State::getActiveQuery(GLenum targ
     const auto it = mActiveQueries.find(target);
 
     // All query types should already exist in the activeQueries map
     ASSERT(it != mActiveQueries.end());
 
     return it->second.get();
 }
 
-void State::setArrayBufferBinding(const Context *context, Buffer *buffer)
-{
-    mArrayBuffer.set(context, buffer);
-}
-
-GLuint State::getArrayBufferId() const
-{
-    return mArrayBuffer.id();
-}
-
-void State::setDrawIndirectBufferBinding(const Context *context, Buffer *buffer)
+void State::setBufferBinding(const Context *context, BufferBinding target, Buffer *buffer)
 {
-    mDrawIndirectBuffer.set(context, buffer);
-    mDirtyBits.set(DIRTY_BIT_DRAW_INDIRECT_BUFFER_BINDING);
-}
-
-void State::setGenericUniformBufferBinding(const Context *context, Buffer *buffer)
-{
-    mGenericUniformBuffer.set(context, buffer);
+    switch (target)
+    {
+        case BufferBinding::PixelPack:
+            mBoundBuffers[target].set(context, buffer);
+            mDirtyBits.set(DIRTY_BIT_PACK_BUFFER_BINDING);
+            break;
+        case BufferBinding::PixelUnpack:
+            mBoundBuffers[target].set(context, buffer);
+            mDirtyBits.set(DIRTY_BIT_UNPACK_BUFFER_BINDING);
+            break;
+        case BufferBinding::DrawIndirect:
+            mBoundBuffers[target].set(context, buffer);
+            mDirtyBits.set(DIRTY_BIT_DRAW_INDIRECT_BUFFER_BINDING);
+            break;
+        case BufferBinding::DispatchIndirect:
+            mBoundBuffers[target].set(context, buffer);
+            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);
+            mDirtyBits.set(DIRTY_BIT_SHADER_STORAGE_BUFFER_BINDING);
+            break;
+        default:
+            mBoundBuffers[target].set(context, buffer);
+            break;
+    }
 }
+void State::setIndexedBufferBinding(const Context *context,
+                                    BufferBinding target,
+                                    GLuint index,
+                                    Buffer *buffer,
+                                    GLintptr offset,
+                                    GLsizeiptr size)
+{
+    setBufferBinding(context, target, buffer);
 
-void State::setIndexedUniformBufferBinding(const Context *context,
-                                           GLuint index,
-                                           Buffer *buffer,
-                                           GLintptr offset,
-                                           GLsizeiptr size)
-{
-    mUniformBuffers[index].set(context, buffer, offset, size);
+    switch (target)
+    {
+        case BufferBinding::TransformFeedback:
+            mTransformFeedback->bindIndexedBuffer(context, index, buffer, offset, size);
+            break;
+        case BufferBinding::Uniform:
+            mUniformBuffers[index].set(context, buffer, offset, size);
+            mDirtyBits.set(DIRTY_BIT_UNIFORM_BUFFER_BINDINGS);
+            break;
+        case BufferBinding::AtomicCounter:
+            mAtomicCounterBuffers[index].set(context, buffer, offset, size);
+            break;
+        case BufferBinding::ShaderStorage:
+            mShaderStorageBuffers[index].set(context, buffer, offset, size);
+            break;
+        default:
+            UNREACHABLE();
+            break;
+    }
 }
 
 const OffsetBindingPointer<Buffer> &State::getIndexedUniformBuffer(size_t index) const
 {
     ASSERT(static_cast<size_t>(index) < mUniformBuffers.size());
     return mUniformBuffers[index];
 }
 
-void State::setGenericAtomicCounterBufferBinding(const Context *context, Buffer *buffer)
-{
-    mGenericAtomicCounterBuffer.set(context, buffer);
-}
-
-void State::setIndexedAtomicCounterBufferBinding(const Context *context,
-                                                 GLuint index,
-                                                 Buffer *buffer,
-                                                 GLintptr offset,
-                                                 GLsizeiptr size)
-{
-    ASSERT(static_cast<size_t>(index) < mAtomicCounterBuffers.size());
-    mAtomicCounterBuffers[index].set(context, buffer, offset, size);
-}
-
 const OffsetBindingPointer<Buffer> &State::getIndexedAtomicCounterBuffer(size_t index) const
 {
     ASSERT(static_cast<size_t>(index) < mAtomicCounterBuffers.size());
     return mAtomicCounterBuffers[index];
 }
 
-void State::setGenericShaderStorageBufferBinding(const Context *context, Buffer *buffer)
-{
-    mGenericShaderStorageBuffer.set(context, buffer);
-}
-
-void State::setIndexedShaderStorageBufferBinding(const Context *context,
-                                                 GLuint index,
-                                                 Buffer *buffer,
-                                                 GLintptr offset,
-                                                 GLsizeiptr size)
-{
-    ASSERT(static_cast<size_t>(index) < mShaderStorageBuffers.size());
-    mShaderStorageBuffers[index].set(context, buffer, offset, size);
-}
-
 const OffsetBindingPointer<Buffer> &State::getIndexedShaderStorageBuffer(size_t index) const
 {
     ASSERT(static_cast<size_t>(index) < mShaderStorageBuffers.size());
     return mShaderStorageBuffers[index];
 }
 
-void State::setCopyReadBufferBinding(const Context *context, Buffer *buffer)
-{
-    mCopyReadBuffer.set(context, buffer);
-}
-
-void State::setCopyWriteBufferBinding(const Context *context, Buffer *buffer)
-{
-    mCopyWriteBuffer.set(context, buffer);
-}
-
-void State::setPixelPackBufferBinding(const Context *context, Buffer *buffer)
-{
-    mPack.pixelBuffer.set(context, buffer);
-    mDirtyBits.set(DIRTY_BIT_PACK_BUFFER_BINDING);
-}
-
-void State::setPixelUnpackBufferBinding(const Context *context, Buffer *buffer)
-{
-    mUnpack.pixelBuffer.set(context, buffer);
-    mDirtyBits.set(DIRTY_BIT_UNPACK_BUFFER_BINDING);
-}
-
-Buffer *State::getTargetBuffer(GLenum target) const
+Buffer *State::getTargetBuffer(BufferBinding target) const
 {
     switch (target)
     {
-      case GL_ARRAY_BUFFER:              return mArrayBuffer.get();
-      case GL_COPY_READ_BUFFER:          return mCopyReadBuffer.get();
-      case GL_COPY_WRITE_BUFFER:         return mCopyWriteBuffer.get();
-      case GL_ELEMENT_ARRAY_BUFFER:      return getVertexArray()->getElementArrayBuffer().get();
-      case GL_PIXEL_PACK_BUFFER:         return mPack.pixelBuffer.get();
-      case GL_PIXEL_UNPACK_BUFFER:       return mUnpack.pixelBuffer.get();
-      case GL_TRANSFORM_FEEDBACK_BUFFER: return mTransformFeedback->getGenericBuffer().get();
-      case GL_UNIFORM_BUFFER:            return mGenericUniformBuffer.get();
-      case GL_ATOMIC_COUNTER_BUFFER:
-          return mGenericAtomicCounterBuffer.get();
-      case GL_SHADER_STORAGE_BUFFER:
-          return mGenericShaderStorageBuffer.get();
-      case GL_DRAW_INDIRECT_BUFFER:
-          return mDrawIndirectBuffer.get();
-      default:
-          UNREACHABLE();
-          return nullptr;
+        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)
 {
-    BindingPointer<Buffer> *buffers[] = {
-        &mArrayBuffer,        &mGenericAtomicCounterBuffer, &mCopyReadBuffer,
-        &mCopyWriteBuffer,    &mDrawIndirectBuffer,         &mPack.pixelBuffer,
-        &mUnpack.pixelBuffer, &mGenericUniformBuffer,       &mGenericShaderStorageBuffer};
-    for (auto buffer : buffers)
+    for (auto &buffer : mBoundBuffers)
     {
-        if (buffer->id() == bufferName)
+        if (buffer.id() == bufferName)
         {
-            buffer->set(context, nullptr);
+            buffer.set(context, nullptr);
         }
     }
 
     TransformFeedback *curTransformFeedback = getCurrentTransformFeedback();
     if (curTransformFeedback)
     {
         curTransformFeedback->detachBuffer(context, bufferName);
     }
@@ -1401,31 +1370,37 @@ void State::setEnableVertexAttribArray(u
     getVertexArray()->enableAttribute(attribNum, enabled);
     mDirtyObjects.set(DIRTY_OBJECT_VERTEX_ARRAY);
 }
 
 void State::setVertexAttribf(GLuint index, const GLfloat values[4])
 {
     ASSERT(static_cast<size_t>(index) < mVertexAttribCurrentValues.size());
     mVertexAttribCurrentValues[index].setFloatValues(values);
-    mDirtyBits.set(DIRTY_BIT_CURRENT_VALUE_0 + index);
+    mDirtyBits.set(DIRTY_BIT_CURRENT_VALUES);
+    mDirtyCurrentValues.set(index);
+    mCurrentValuesTypeMask.setIndex(GL_FLOAT, index);
 }
 
 void State::setVertexAttribu(GLuint index, const GLuint values[4])
 {
     ASSERT(static_cast<size_t>(index) < mVertexAttribCurrentValues.size());
     mVertexAttribCurrentValues[index].setUnsignedIntValues(values);
-    mDirtyBits.set(DIRTY_BIT_CURRENT_VALUE_0 + index);
+    mDirtyBits.set(DIRTY_BIT_CURRENT_VALUES);
+    mDirtyCurrentValues.set(index);
+    mCurrentValuesTypeMask.setIndex(GL_UNSIGNED_INT, index);
 }
 
 void State::setVertexAttribi(GLuint index, const GLint values[4])
 {
     ASSERT(static_cast<size_t>(index) < mVertexAttribCurrentValues.size());
     mVertexAttribCurrentValues[index].setIntValues(values);
-    mDirtyBits.set(DIRTY_BIT_CURRENT_VALUE_0 + index);
+    mDirtyBits.set(DIRTY_BIT_CURRENT_VALUES);
+    mDirtyCurrentValues.set(index);
+    mCurrentValuesTypeMask.setIndex(GL_INT, index);
 }
 
 void State::setVertexAttribPointer(const Context *context,
                                    unsigned int attribNum,
                                    Buffer *boundBuffer,
                                    GLint size,
                                    GLenum type,
                                    bool normalized,
@@ -1445,69 +1420,74 @@ void State::setVertexAttribDivisor(const
 }
 
 const VertexAttribCurrentValueData &State::getVertexAttribCurrentValue(size_t attribNum) const
 {
     ASSERT(attribNum < mVertexAttribCurrentValues.size());
     return mVertexAttribCurrentValues[attribNum];
 }
 
+const std::vector<VertexAttribCurrentValueData> &State::getVertexAttribCurrentValues() const
+{
+    return mVertexAttribCurrentValues;
+}
+
 const void *State::getVertexAttribPointer(unsigned int attribNum) const
 {
     return getVertexArray()->getVertexAttribute(attribNum).pointer;
 }
 
 void State::setPackAlignment(GLint alignment)
 {
     mPack.alignment = alignment;
-    mDirtyBits.set(DIRTY_BIT_PACK_ALIGNMENT);
+    mDirtyBits.set(DIRTY_BIT_PACK_STATE);
 }
 
 GLint State::getPackAlignment() const
 {
     return mPack.alignment;
 }
 
 void State::setPackReverseRowOrder(bool reverseRowOrder)
 {
     mPack.reverseRowOrder = reverseRowOrder;
-    mDirtyBits.set(DIRTY_BIT_PACK_REVERSE_ROW_ORDER);
+    mDirtyBits.set(DIRTY_BIT_PACK_STATE);
 }
 
 bool State::getPackReverseRowOrder() const
 {
     return mPack.reverseRowOrder;
 }
 
 void State::setPackRowLength(GLint rowLength)
 {
     mPack.rowLength = rowLength;
-    mDirtyBits.set(DIRTY_BIT_PACK_ROW_LENGTH);
+    mDirtyBits.set(DIRTY_BIT_PACK_STATE);
 }
 
 GLint State::getPackRowLength() const
 {
     return mPack.rowLength;
 }
 
 void State::setPackSkipRows(GLint skipRows)
 {
     mPack.skipRows = skipRows;
-    mDirtyBits.set(DIRTY_BIT_PACK_SKIP_ROWS);
+    mDirtyBits.set(DIRTY_BIT_PACK_STATE);
 }
 
 GLint State::getPackSkipRows() const
 {
     return mPack.skipRows;
 }
 
 void State::setPackSkipPixels(GLint skipPixels)
 {
     mPack.skipPixels = skipPixels;
-    mDirtyBits.set(DIRTY_BIT_PACK_SKIP_PIXELS);
+    mDirtyBits.set(DIRTY_BIT_PACK_STATE);
 }
 
 GLint State::getPackSkipPixels() const
 {
     return mPack.skipPixels;
 }
 
 const PixelPackState &State::getPackState() const
@@ -1518,72 +1498,72 @@ const PixelPackState &State::getPackStat
 PixelPackState &State::getPackState()
 {
     return mPack;
 }
 
 void State::setUnpackAlignment(GLint alignment)
 {
     mUnpack.alignment = alignment;
-    mDirtyBits.set(DIRTY_BIT_UNPACK_ALIGNMENT);
+    mDirtyBits.set(DIRTY_BIT_UNPACK_STATE);
 }
 
 GLint State::getUnpackAlignment() const
 {
     return mUnpack.alignment;
 }
 
 void State::setUnpackRowLength(GLint rowLength)
 {
     mUnpack.rowLength = rowLength;
-    mDirtyBits.set(DIRTY_BIT_UNPACK_ROW_LENGTH);
+    mDirtyBits.set(DIRTY_BIT_UNPACK_STATE);
 }
 
 GLint State::getUnpackRowLength() const
 {
     return mUnpack.rowLength;
 }
 
 void State::setUnpackImageHeight(GLint imageHeight)
 {
     mUnpack.imageHeight = imageHeight;
-    mDirtyBits.set(DIRTY_BIT_UNPACK_IMAGE_HEIGHT);
+    mDirtyBits.set(DIRTY_BIT_UNPACK_STATE);
 }
 
 GLint State::getUnpackImageHeight() const
 {
     return mUnpack.imageHeight;
 }
 
 void State::setUnpackSkipImages(GLint skipImages)
 {
     mUnpack.skipImages = skipImages;
-    mDirtyBits.set(DIRTY_BIT_UNPACK_SKIP_IMAGES);
+    mDirtyBits.set(DIRTY_BIT_UNPACK_STATE);
 }
 
 GLint State::getUnpackSkipImages() const
 {
     return mUnpack.skipImages;
 }
 
 void State::setUnpackSkipRows(GLint skipRows)
 {
     mUnpack.skipRows = skipRows;
-    mDirtyBits.set(DIRTY_BIT_UNPACK_SKIP_ROWS);
+    mDirtyBits.set(DIRTY_BIT_UNPACK_STATE);
 }
 
 GLint State::getUnpackSkipRows() const
 {
     return mUnpack.skipRows;
 }
 
 void State::setUnpackSkipPixels(GLint skipPixels)
 {
     mUnpack.skipPixels = skipPixels;
-    mDirtyBits.set(DIRTY_BIT_UNPACK_SKIP_PIXELS);
+    mDirtyBits.set(DIRTY_BIT_UNPACK_STATE);
 }
 
 GLint State::getUnpackSkipPixels() const
 {
     return mUnpack.skipPixels;
 }
 
 const PixelUnpackState &State::getUnpackState() const
@@ -1691,17 +1671,19 @@ void State::getBooleanv(GLenum pname, GL
       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_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;
@@ -1732,17 +1714,17 @@ void State::getBooleanv(GLenum pname, GL
           *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_CONTEXT_ROBUST_RESOURCE_INITIALIZATION_ANGLE:
+      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();
@@ -1806,21 +1788,25 @@ void State::getIntegerv(const Context *c
 
     // 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)
     {
-      case GL_ARRAY_BUFFER_BINDING:                     *params = mArrayBuffer.id();                              break;
-      case GL_DRAW_INDIRECT_BUFFER_BINDING:
-          *params = mDrawIndirectBuffer.id();
-          break;
-      case GL_ELEMENT_ARRAY_BUFFER_BINDING:             *params = getVertexArray()->getElementArrayBuffer().id(); break;
+        case GL_ARRAY_BUFFER_BINDING:
+            *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;
@@ -1849,35 +1835,43 @@ void State::getIntegerv(const Context *c
           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 = clampToInt(mDepthStencil.stencilMask);          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 = clampToInt(mDepthStencil.stencilBackMask);      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 = clampToInt(mDepthStencil.stencilWritemask);     break;
-      case GL_STENCIL_BACK_WRITEMASK:                   *params = clampToInt(mDepthStencil.stencilBackWritemask); 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:
@@ -1916,18 +1910,22 @@ void State::getIntegerv(const Context *c
         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 = mRasterizer.cullMode;   break;
-      case GL_FRONT_FACE:                       *params = mRasterizer.frontFace;  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();
 
@@ -2006,36 +2004,37 @@ void State::getIntegerv(const Context *c
                                         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 = mGenericUniformBuffer.id();
-        break;
+          *params = mBoundBuffers[BufferBinding::Uniform].id();
+          break;
       case GL_TRANSFORM_FEEDBACK_BINDING:
         *params = mTransformFeedback.id();
         break;
       case GL_TRANSFORM_FEEDBACK_BUFFER_BINDING:
-        *params = mTransformFeedback->getGenericBuffer().id();
-        break;
+          ASSERT(mTransformFeedback.get() != nullptr);
+          *params = mTransformFeedback->getGenericBuffer().id();
+          break;
       case GL_COPY_READ_BUFFER_BINDING:
-        *params = mCopyReadBuffer.id();
-        break;
+          *params = mBoundBuffers[BufferBinding::CopyRead].id();
+          break;
       case GL_COPY_WRITE_BUFFER_BINDING:
-        *params = mCopyWriteBuffer.id();
-        break;
+          *params = mBoundBuffers[BufferBinding::CopyWrite].id();
+          break;
       case GL_PIXEL_PACK_BUFFER_BINDING:
-        *params = mPack.pixelBuffer.id();
-        break;
+          *params = mBoundBuffers[BufferBinding::PixelPack].id();
+          break;
       case GL_PIXEL_UNPACK_BUFFER_BINDING:
-        *params = mUnpack.pixelBuffer.id();
-        break;
+          *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:
@@ -2051,20 +2050,23 @@ void State::getIntegerv(const Context *c
           *params = static_cast<GLint>(mMultiSampling);
           break;
       case GL_SAMPLE_ALPHA_TO_ONE_EXT:
           *params = static_cast<GLint>(mSampleAlphaToOne);
       case GL_COVERAGE_MODULATION_CHROMIUM:
           *params = static_cast<GLint>(mCoverageModulation);
           break;
       case GL_ATOMIC_COUNTER_BUFFER_BINDING:
-          *params = mGenericAtomicCounterBuffer.id();
+          *params = mBoundBuffers[BufferBinding::AtomicCounter].id();
           break;
       case GL_SHADER_STORAGE_BUFFER_BINDING:
-          *params = mGenericShaderStorageBuffer.id();
+          *params = mBoundBuffers[BufferBinding::ShaderStorage].id();
+          break;
+      case GL_DISPATCH_INDIRECT_BUFFER_BINDING:
+          *params = mBoundBuffers[BufferBinding::DispatchIndirect].id();
           break;
       default:
         UNREACHABLE();
         break;
     }
 }
 
 void State::getPointerv(GLenum pname, void **params) const
@@ -2118,16 +2120,36 @@ void State::getIntegeri_v(GLenum target,
       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)
 {
@@ -2168,28 +2190,36 @@ void State::getInteger64i_v(GLenum targe
       default:
           UNREACHABLE();
           break;
     }
 }
 
 void State::getBooleani_v(GLenum target, GLuint index, GLboolean *data)
 {
-    UNREACHABLE();
+    switch (target)
+    {
+        case GL_IMAGE_BINDING_LAYERED:
+            ASSERT(static_cast<size_t>(index) < mImageUnits.size());
+            *data = mImageUnits[index].layered;
+            break;
+        default:
+            UNREACHABLE();
+            break;
+    }
 }
 
-bool State::hasMappedBuffer(GLenum target) const
+bool State::hasMappedBuffer(BufferBinding target) const
 {
-    if (target == GL_ARRAY_BUFFER)
+    if (target == BufferBinding::Array)
     {
         const VertexArray *vao     = getVertexArray();
         const auto &vertexAttribs = vao->getVertexAttributes();
         const auto &vertexBindings = vao->getVertexBindings();
-        size_t maxEnabledAttrib = vao->getMaxEnabledAttribute();
-        for (size_t attribIndex = 0; attribIndex < maxEnabledAttrib; attribIndex++)
+        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;
             }
         }
@@ -2250,65 +2280,74 @@ void State::syncProgramTextures(const Co
         return;
     }
 
     ASSERT(mDirtyObjects[DIRTY_OBJECT_PROGRAM_TEXTURES]);
     mDirtyBits.set(DIRTY_BIT_TEXTURE_BINDINGS);
 
     ActiveTextureMask newActiveTextures;
 
+    // Initialize to the 'Initialized' state and set to 'MayNeedInit' if any texture is not
+    // initialized.
+    mCachedTexturesInitState = InitState::Initialized;
+
     for (const SamplerBinding &samplerBinding : mProgram->getSamplerBindings())
     {
         if (samplerBinding.unreferenced)
             continue;
 
         GLenum 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());
 
-            if (texture != nullptr)
+            ASSERT(texture);
+
+            // Mark the texture binding bit as dirty if the texture completeness changes.
+            // TODO(jmadill): Use specific dirty bit for completeness change.
+            if (texture->isSamplerComplete(context, sampler) &&
+                !mDrawFramebuffer->hasTextureAttachment(texture))
             {
-                // Mark the texture binding bit as dirty if the texture completeness changes.
-                // TODO(jmadill): Use specific dirty bit for completeness change.
-                if (texture->isSamplerComplete(context, sampler))
-                {
-                    texture->syncState();
-                    mCompleteTextureCache[textureUnitIndex] = texture;
-                }
-                else
-                {
-                    mCompleteTextureCache[textureUnitIndex] = nullptr;
-                }
+                texture->syncState();
+                mCompleteTextureCache[textureUnitIndex] = texture;
+            }
+            else
+            {
+                mCompleteTextureCache[textureUnitIndex] = nullptr;
+            }
 
-                // Bind the texture unconditionally, to recieve completeness change notifications.
-                mCompleteTextureBindings[textureUnitIndex].bind(texture->getDirtyChannel());
-                newActiveTextures.set(textureUnitIndex);
-                mCompleteTexturesMask.set(textureUnitIndex);
-            }
+            // Bind the texture unconditionally, to recieve completeness change notifications.
+            mCompleteTextureBindings[textureUnitIndex].bind(texture->getDirtyChannel());
+            mActiveTexturesMask.set(textureUnitIndex);
+            newActiveTextures.set(textureUnitIndex);
 
             if (sampler != nullptr)
             {
                 sampler->syncState(context);
             }
+
+            if (texture->initState() == InitState::MayNeedInit)
+            {
+                mCachedTexturesInitState = InitState::MayNeedInit;
+            }
         }
     }
 
     // Unset now missing textures.
-    ActiveTextureMask negativeMask = mCompleteTexturesMask & ~newActiveTextures;
+    ActiveTextureMask negativeMask = mActiveTexturesMask & ~newActiveTextures;
     if (negativeMask.any())
     {
         for (auto textureIndex : negativeMask)
         {
             mCompleteTextureBindings[textureIndex].reset();
             mCompleteTextureCache[textureIndex] = nullptr;
-            mCompleteTexturesMask.reset(textureIndex);
+            mActiveTexturesMask.reset(textureIndex);
         }
     }
 }
 
 void State::syncDirtyObject(const Context *context, GLenum target)
 {
     DirtyObjects localSet;
 
@@ -2394,16 +2433,51 @@ void State::setImageUnit(const Context *
 }
 
 const ImageUnit &State::getImageUnit(GLuint unit) const
 {
     return mImageUnits[unit];
 }
 
 // Handle a dirty texture event.
-void State::signal(uint32_t textureIndex)
+void State::signal(size_t textureIndex, InitState initState)
 {
     // Conservatively assume all textures are dirty.
     // TODO(jmadill): More fine-grained update.
     mDirtyObjects.set(DIRTY_OBJECT_PROGRAM_TEXTURES);
+
+    if (initState == InitState::MayNeedInit)
+    {
+        mCachedTexturesInitState = InitState::MayNeedInit;
+    }
+}
+
+Error State::clearUnclearedActiveTextures(const Context *context)
+{
+    ASSERT(mRobustResourceInit);
+
+    if (mCachedTexturesInitState == InitState::Initialized)
+    {
+        return NoError();
+    }
+
+    for (auto textureIndex : mActiveTexturesMask)
+    {
+        Texture *texture = mCompleteTextureCache[textureIndex];
+        if (texture)
+        {
+            ANGLE_TRY(texture->ensureInitialized(context));
+        }
+    }
+
+    mCachedTexturesInitState = InitState::Initialized;
+
+    return NoError();
+}
+
+AttributesMask State::getAndResetDirtyCurrentValues() const
+{
+    AttributesMask retVal = mDirtyCurrentValues;
+    mDirtyCurrentValues.reset();
+    return retVal;
 }
 
 }  // namespace gl
--- a/gfx/angle/src/libANGLE/State.h
+++ b/gfx/angle/src/libANGLE/State.h
@@ -29,23 +29,21 @@
 
 namespace gl
 {
 class Query;
 class VertexArray;
 class Context;
 struct Caps;
 
-typedef std::map<GLenum, BindingPointer<Texture>> TextureMap;
-
 class State : public OnAttachmentDirtyReceiver, angle::NonCopyable
 {
   public:
     State();
-    ~State();
+    ~State() override;
 
     void initialize(const Context *context,
                     bool debug,
                     bool bindGeneratesResource,
                     bool clientArraysEnabled,
                     bool robustResourceInit,
                     bool programBinaryCacheEnabled);
     void reset(const Context *context);
@@ -74,17 +72,17 @@ class State : public OnAttachmentDirtyRe
 
     // Primitive restart
     bool isPrimitiveRestartEnabled() const;
     void setPrimitiveRestart(bool enabled);
 
     // Face culling state manipulation
     bool isCullFaceEnabled() const;
     void setCullFace(bool enabled);
-    void setCullMode(GLenum mode);
+    void setCullMode(CullFaceMode mode);
     void setFrontFace(GLenum front);
 
     // Depth test state manipulation
     bool isDepthTestEnabled() const;
     void setDepthTest(bool enabled);
     void setDepthFunc(GLenum depthFunc);
     void setDepthRange(float zNear, float zFar);
     float getNearPlane() const;
@@ -227,60 +225,29 @@ class State : public OnAttachmentDirtyRe
     GLuint getActiveQueryId(GLenum target) const;
     Query *getActiveQuery(GLenum target) const;
 
     // Program Pipeline binding manipulation
     void setProgramPipelineBinding(const Context *context, ProgramPipeline *pipeline);
     void detachProgramPipeline(const Context *context, GLuint pipeline);
 
     //// Typed buffer binding point manipulation ////
-    // GL_ARRAY_BUFFER
-    void setArrayBufferBinding(const Context *context, Buffer *buffer);
-    GLuint getArrayBufferId() const;
-
-    void setDrawIndirectBufferBinding(const Context *context, Buffer *buffer);
-    Buffer *getDrawIndirectBuffer() const { return mDrawIndirectBuffer.get(); }
-
-    // GL_UNIFORM_BUFFER - Both indexed and generic targets
-    void setGenericUniformBufferBinding(const Context *context, Buffer *buffer);
-    void setIndexedUniformBufferBinding(const Context *context,
-                                        GLuint index,
-                                        Buffer *buffer,
-                                        GLintptr offset,
-                                        GLsizeiptr size);
-    const OffsetBindingPointer<Buffer> &getIndexedUniformBuffer(size_t index) const;
+    void setBufferBinding(const Context *context, BufferBinding target, Buffer *buffer);
+    Buffer *getTargetBuffer(BufferBinding target) const;
+    void setIndexedBufferBinding(const Context *context,
+                                 BufferBinding target,
+                                 GLuint index,
+                                 Buffer *buffer,
+                                 GLintptr offset,
+                                 GLsizeiptr size);
 
-    // GL_ATOMIC_COUNTER_BUFFER - Both indexed and generic targets
-    void setGenericAtomicCounterBufferBinding(const Context *context, Buffer *buffer);
-    void setIndexedAtomicCounterBufferBinding(const Context *context,
-                                              GLuint index,
-                                              Buffer *buffer,
-                                              GLintptr offset,
-                                              GLsizeiptr size);
+    const OffsetBindingPointer<Buffer> &getIndexedUniformBuffer(size_t index) const;
     const OffsetBindingPointer<Buffer> &getIndexedAtomicCounterBuffer(size_t index) const;
-
-    // GL_SHADER_STORAGE_BUFFER - Both indexed and generic targets
-    void setGenericShaderStorageBufferBinding(const Context *context, Buffer *buffer);
-    void setIndexedShaderStorageBufferBinding(const Context *context,
-                                              GLuint index,
-                                              Buffer *buffer,
-                                              GLintptr offset,
-                                              GLsizeiptr size);
     const OffsetBindingPointer<Buffer> &getIndexedShaderStorageBuffer(size_t index) const;
 
-    // GL_COPY_[READ/WRITE]_BUFFER
-    void setCopyReadBufferBinding(const Context *context, Buffer *buffer);
-    void setCopyWriteBufferBinding(const Context *context, Buffer *buffer);
-
-    // GL_PIXEL[PACK/UNPACK]_BUFFER
-    void setPixelPackBufferBinding(const Context *context, Buffer *buffer);
-    void setPixelUnpackBufferBinding(const Context *context, Buffer *buffer);
-
-    // Retrieve typed buffer by target (non-indexed)
-    Buffer *getTargetBuffer(GLenum target) const;
     // Detach a buffer from all bindings
     void detachBuffer(const Context *context, GLuint bufferName);
 
     // 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]);
@@ -291,16 +258,17 @@ class State : public OnAttachmentDirtyRe
                                 GLint size,
                                 GLenum type,
                                 bool normalized,
                                 bool pureInteger,
                                 GLsizei stride,
                                 const void *pointer);
     void setVertexAttribDivisor(const Context *context, GLuint index, GLuint divisor);
     const VertexAttribCurrentValueData &getVertexAttribCurrentValue(size_t attribNum) const;
+    const std::vector<VertexAttribCurrentValueData> &getVertexAttribCurrentValues() const;
     const void *getVertexAttribPointer(unsigned int attribNum) const;
     void bindVertexBuffer(const Context *context,
                           GLuint bindingIndex,
                           Buffer *boundBuffer,
                           GLintptr offset,
                           GLsizei stride);
     void setVertexAttribFormat(GLuint attribIndex,
                                GLint size,
@@ -366,17 +334,17 @@ class State : public OnAttachmentDirtyRe
     void getBooleanv(GLenum pname, GLboolean *params);
     void getFloatv(GLenum pname, GLfloat *params);
     void 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(GLenum target) const;
+    bool hasMappedBuffer(BufferBinding target) const;
     bool isRobustResourceInitEnabled() const { return mRobustResourceInit; }
 
     // Sets the dirty bit for the program executable.
     void onProgramExecutableChange(Program *program);
 
     enum DirtyBitType
     {
         DIRTY_BIT_SCISSOR_TEST_ENABLED,
@@ -387,19 +355,18 @@ class State : public OnAttachmentDirtyRe
         DIRTY_BIT_BLEND_COLOR,
         DIRTY_BIT_BLEND_FUNCS,
         DIRTY_BIT_BLEND_EQUATIONS,
         DIRTY_BIT_COLOR_MASK,
         DIRTY_BIT_SAMPLE_ALPHA_TO_COVERAGE_ENABLED,
         DIRTY_BIT_SAMPLE_COVERAGE_ENABLED,
         DIRTY_BIT_SAMPLE_COVERAGE,
         DIRTY_BIT_SAMPLE_MASK_ENABLED,
-        DIRTY_BIT_SAMPLE_MASK_WORD_0,
-        DIRTY_BIT_SAMPLE_MASK_WORD_MAX = DIRTY_BIT_SAMPLE_MASK_WORD_0 + MAX_SAMPLE_MASK_WORDS,
-        DIRTY_BIT_DEPTH_TEST_ENABLED   = DIRTY_BIT_SAMPLE_MASK_WORD_MAX,
+        DIRTY_BIT_SAMPLE_MASK,
+        DIRTY_BIT_DEPTH_TEST_ENABLED,
         DIRTY_BIT_DEPTH_FUNC,
         DIRTY_BIT_DEPTH_MASK,
         DIRTY_BIT_STENCIL_TEST_ENABLED,
         DIRTY_BIT_STENCIL_FUNCS_FRONT,
         DIRTY_BIT_STENCIL_FUNCS_BACK,
         DIRTY_BIT_STENCIL_OPS_FRONT,
         DIRTY_BIT_STENCIL_OPS_BACK,
         DIRTY_BIT_STENCIL_WRITEMASK_FRONT,
@@ -410,96 +377,100 @@ class State : public OnAttachmentDirtyRe
         DIRTY_BIT_POLYGON_OFFSET_FILL_ENABLED,
         DIRTY_BIT_POLYGON_OFFSET,
         DIRTY_BIT_RASTERIZER_DISCARD_ENABLED,
         DIRTY_BIT_LINE_WIDTH,
         DIRTY_BIT_PRIMITIVE_RESTART_ENABLED,
         DIRTY_BIT_CLEAR_COLOR,
         DIRTY_BIT_CLEAR_DEPTH,
         DIRTY_BIT_CLEAR_STENCIL,
-        DIRTY_BIT_UNPACK_ALIGNMENT,
-        DIRTY_BIT_UNPACK_ROW_LENGTH,
-        DIRTY_BIT_UNPACK_IMAGE_HEIGHT,
-        DIRTY_BIT_UNPACK_SKIP_IMAGES,
-        DIRTY_BIT_UNPACK_SKIP_ROWS,
-        DIRTY_BIT_UNPACK_SKIP_PIXELS,
+        DIRTY_BIT_UNPACK_STATE,
         DIRTY_BIT_UNPACK_BUFFER_BINDING,
-        DIRTY_BIT_PACK_ALIGNMENT,
-        DIRTY_BIT_PACK_REVERSE_ROW_ORDER,
-        DIRTY_BIT_PACK_ROW_LENGTH,
-        DIRTY_BIT_PACK_SKIP_ROWS,
-        DIRTY_BIT_PACK_SKIP_PIXELS,
+        DIRTY_BIT_PACK_STATE,
         DIRTY_BIT_PACK_BUFFER_BINDING,
         DIRTY_BIT_DITHER_ENABLED,
         DIRTY_BIT_GENERATE_MIPMAP_HINT,
         DIRTY_BIT_SHADER_DERIVATIVE_HINT,
         DIRTY_BIT_READ_FRAMEBUFFER_BINDING,
         DIRTY_BIT_DRAW_FRAMEBUFFER_BINDING,
         DIRTY_BIT_RENDERBUFFER_BINDING,
         DIRTY_BIT_VERTEX_ARRAY_BINDING,
         DIRTY_BIT_DRAW_INDIRECT_BUFFER_BINDING,
+        DIRTY_BIT_DISPATCH_INDIRECT_BUFFER_BINDING,
+        DIRTY_BIT_SHADER_STORAGE_BUFFER_BINDING,
+        // TODO(jmadill): Fine-grained dirty bits for each index.
+        DIRTY_BIT_UNIFORM_BUFFER_BINDINGS,
         DIRTY_BIT_PROGRAM_BINDING,
         DIRTY_BIT_PROGRAM_EXECUTABLE,
         // TODO(jmadill): Fine-grained dirty bits for each texture/sampler.
         DIRTY_BIT_TEXTURE_BINDINGS,
         DIRTY_BIT_SAMPLER_BINDINGS,
+        DIRTY_BIT_TRANSFORM_FEEDBACK_BINDING,
         DIRTY_BIT_MULTISAMPLING,
         DIRTY_BIT_SAMPLE_ALPHA_TO_ONE,
         DIRTY_BIT_COVERAGE_MODULATION,         // CHROMIUM_framebuffer_mixed_samples
         DIRTY_BIT_PATH_RENDERING_MATRIX_MV,    // CHROMIUM_path_rendering path model view matrix
         DIRTY_BIT_PATH_RENDERING_MATRIX_PROJ,  // CHROMIUM_path_rendering path projection matrix
         DIRTY_BIT_PATH_RENDERING_STENCIL_STATE,
         DIRTY_BIT_FRAMEBUFFER_SRGB,  // GL_EXT_sRGB_write_control
-        DIRTY_BIT_CURRENT_VALUE_0,
-        DIRTY_BIT_CURRENT_VALUE_MAX = DIRTY_BIT_CURRENT_VALUE_0 + MAX_VERTEX_ATTRIBS,
-        DIRTY_BIT_INVALID           = DIRTY_BIT_CURRENT_VALUE_MAX,
-        DIRTY_BIT_MAX               = DIRTY_BIT_INVALID,
+        DIRTY_BIT_CURRENT_VALUES,
+        DIRTY_BIT_INVALID,
+        DIRTY_BIT_MAX = DIRTY_BIT_INVALID,
     };
 
+    static_assert(DIRTY_BIT_MAX <= 64, "State dirty bits must be capped at 64");
+
     // TODO(jmadill): Consider storing dirty objects in a list instead of by binding.
     enum DirtyObjectType
     {
         DIRTY_OBJECT_READ_FRAMEBUFFER,
         DIRTY_OBJECT_DRAW_FRAMEBUFFER,
         DIRTY_OBJECT_VERTEX_ARRAY,
         // Use a very coarse bit for any program or texture change.
         // TODO(jmadill): Fine-grained dirty bits for each texture/sampler.
         DIRTY_OBJECT_PROGRAM_TEXTURES,
         DIRTY_OBJECT_UNKNOWN,
         DIRTY_OBJECT_MAX = DIRTY_OBJECT_UNKNOWN,
     };
 
-    typedef angle::BitSet<DIRTY_BIT_MAX> DirtyBits;
+    using DirtyBits = angle::BitSet<DIRTY_BIT_MAX>;
     const DirtyBits &getDirtyBits() const { return mDirtyBits; }
     void clearDirtyBits() { mDirtyBits.reset(); }
     void clearDirtyBits(const DirtyBits &bitset) { mDirtyBits &= ~bitset; }
     void setAllDirtyBits() { mDirtyBits.set(); }
 
-    typedef angle::BitSet<DIRTY_OBJECT_MAX> DirtyObjects;
+    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);
     void setObjectDirty(GLenum target);
 
+    // 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,
                       GLint level,
                       GLboolean layered,
                       GLint layer,
                       GLenum access,
                       GLenum format);
 
     const ImageUnit &getImageUnit(GLuint unit) const;
     const std::vector<Texture *> &getCompleteTextureCache() const { return mCompleteTextureCache; }
+    ComponentTypeMask getCurrentValuesTypeMask() const { return mCurrentValuesTypeMask; }
 
     // Handle a dirty texture event.
-    void signal(uint32_t textureIndex) override;
+    void signal(size_t textureIndex, InitState initState) override;
+
+    Error clearUnclearedActiveTextures(const Context *context);
 
   private:
     void syncProgramTextures(const Context *context);
 
     // Cached values from Context's caps
     GLuint mMaxDrawBuffers;
     GLuint mMaxCombinedTextureImageUnits;
 
@@ -531,27 +502,26 @@ class State : public OnAttachmentDirtyRe
 
     bool mBindGeneratesResource;
     bool mClientArraysEnabled;
 
     Rectangle mViewport;
     float mNearZ;
     float mFarZ;
 
-    BindingPointer<Buffer> mArrayBuffer;
-    BindingPointer<Buffer> mDrawIndirectBuffer;
     Framebuffer *mReadFramebuffer;
     Framebuffer *mDrawFramebuffer;
     BindingPointer<Renderbuffer> mRenderbuffer;
     Program *mProgram;
     BindingPointer<ProgramPipeline> mProgramPipeline;
 
     typedef std::vector<VertexAttribCurrentValueData> VertexAttribVector;
     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;
     TextureBindingMap mSamplerTextures;
 
@@ -567,44 +537,46 @@ class State : public OnAttachmentDirtyRe
     // 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.
 
     // 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<OnAttachmentDirtyBinding> mCompleteTextureBindings;
+    InitState mCachedTexturesInitState;
     using ActiveTextureMask = angle::BitSet<IMPLEMENTATION_MAX_ACTIVE_TEXTURES>;
-    ActiveTextureMask mCompleteTexturesMask;
+    ActiveTextureMask mActiveTexturesMask;
 
     typedef std::vector<BindingPointer<Sampler>> SamplerBindingVector;
     SamplerBindingVector mSamplers;
 
     typedef std::vector<ImageUnit> ImageUnitVector;
     ImageUnitVector mImageUnits;
 
     typedef std::map<GLenum, BindingPointer<Query>> ActiveQueryMap;
     ActiveQueryMap mActiveQueries;
 
-    BindingPointer<Buffer> mGenericUniformBuffer;
-    typedef std::vector<OffsetBindingPointer<Buffer>> BufferVector;
+    // 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.
+    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> mGenericAtomicCounterBuffer;
-    BufferVector mAtomicCounterBuffers;
-
-    BindingPointer<Buffer> mGenericShaderStorageBuffer;
-    BufferVector mShaderStorageBuffers;
-
-    BindingPointer<Buffer> mCopyReadBuffer;
-    BindingPointer<Buffer> mCopyWriteBuffer;
-
+    BindingPointer<Buffer> mPixelUnpackBuffer;
     PixelUnpackState mUnpack;
+    BindingPointer<Buffer> mPixelPackBuffer;
     PixelPackState mPack;
 
     bool mPrimitiveRestart;
 
     Debug mDebug;
 
     bool mMultiSampling;
     bool mSampleAlphaToOne;
@@ -624,13 +596,14 @@ class State : public OnAttachmentDirtyRe
     // GL_ANGLE_robust_resource_intialization
     bool mRobustResourceInit;
 
     // GL_ANGLE_program_cache_control
     bool mProgramBinaryCacheEnabled;
 
     DirtyBits mDirtyBits;
     DirtyObjects mDirtyObjects;
+    mutable AttributesMask mDirtyCurrentValues;
 };
 
 }  // namespace gl
 
 #endif  // LIBANGLE_STATE_H_
--- a/gfx/angle/src/libANGLE/Stream.cpp
+++ b/gfx/angle/src/libANGLE/Stream.cpp
@@ -120,17 +120,17 @@ Error Stream::createConsumerGLTextureExt
     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);
         ASSERT(mPlanes[0].texture != nullptr);
         mPlanes[0].texture->bindStream(this);
         mConsumerType = ConsumerType::GLTextureRGB;
-        mPlaneCount = 1;
+        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
@@ -155,39 +155,39 @@ Error Stream::createConsumerGLTextureExt
     }
 
     mContext = context;
     mState   = EGL_STREAM_STATE_CONNECTING_KHR;
 
     return NoError();
 }
 
-Error Stream::createProducerD3D11TextureNV12(const AttributeMap &attributes)
+Error Stream::createProducerD3D11Texture(const AttributeMap &attributes)
 {
     ASSERT(mState == EGL_STREAM_STATE_CONNECTING_KHR);
     ASSERT(mConsumerType == ConsumerType::GLTextureRGB ||
            mConsumerType == ConsumerType::GLTextureYUV);
     ASSERT(mProducerType == ProducerType::NoProducer);
 
-    mProducerImplementation = mDisplay->getImplementation()->createStreamProducerD3DTextureNV12(
-        mConsumerType, attributes);
-    mProducerType = ProducerType::D3D11TextureNV12;
+    mProducerImplementation =
+        mDisplay->getImplementation()->createStreamProducerD3DTexture(mConsumerType, attributes);
+    mProducerType = ProducerType::D3D11Texture;
     mState        = EGL_STREAM_STATE_EMPTY_KHR;
 
     return NoError();
 }
 
 // Called when the consumer of this stream starts using the stream
 Error Stream::consumerAcquire(const gl::Context *context)
 {
     ASSERT(mState == EGL_STREAM_STATE_NEW_FRAME_AVAILABLE_KHR ||
            mState == EGL_STREAM_STATE_OLD_FRAME_AVAILABLE_KHR);
     ASSERT(mConsumerType == ConsumerType::GLTextureRGB ||
            mConsumerType == ConsumerType::GLTextureYUV);
-    ASSERT(mProducerType == ProducerType::D3D11TextureNV12);
+    ASSERT(mProducerType == ProducerType::D3D11Texture);
 
     mState = EGL_STREAM_STATE_OLD_FRAME_AVAILABLE_KHR;
     mConsumerFrame++;
 
     // Bind the planes to the gl textures
     for (int i = 0; i < mPlaneCount; i++)
     {
         if (mPlanes[i].texture != nullptr)
@@ -201,17 +201,17 @@ Error Stream::consumerAcquire(const gl::
 }
 
 Error Stream::consumerRelease(const gl::Context *context)
 {
     ASSERT(mState == EGL_STREAM_STATE_NEW_FRAME_AVAILABLE_KHR ||
            mState == EGL_STREAM_STATE_OLD_FRAME_AVAILABLE_KHR);
     ASSERT(mConsumerType == ConsumerType::GLTextureRGB ||
            mConsumerType == ConsumerType::GLTextureYUV);
-    ASSERT(mProducerType == ProducerType::D3D11TextureNV12);
+    ASSERT(mProducerType == ProducerType::D3D11Texture);
 
     // Release the images
     for (int i = 0; i < mPlaneCount; i++)
     {
         if (mPlanes[i].texture != nullptr)
         {
             ANGLE_TRY(mPlanes[i].texture->releaseImageFromStream(context));
         }
@@ -221,33 +221,33 @@ Error Stream::consumerRelease(const gl::
 }
 
 bool Stream::isConsumerBoundToContext(const gl::Context *context) const
 {
     ASSERT(context != nullptr);
     return (context == mContext);
 }
 
-Error Stream::validateD3D11NV12Texture(void *texture, const AttributeMap &attributes) const
+Error Stream::validateD3D11Texture(void *texture, const AttributeMap &attributes) const
 {
     ASSERT(mConsumerType == ConsumerType::GLTextureRGB ||
            mConsumerType == ConsumerType::GLTextureYUV);
-    ASSERT(mProducerType == ProducerType::D3D11TextureNV12);
+    ASSERT(mProducerType == ProducerType::D3D11Texture);
     ASSERT(mProducerImplementation != nullptr);
 
-    return mProducerImplementation->validateD3DNV12Texture(texture, attributes);
+    return mProducerImplementation->validateD3DTexture(texture, attributes);
 }
 
-Error Stream::postD3D11NV12Texture(void *texture, const AttributeMap &attributes)
+Error Stream::postD3D11Texture(void *texture, const AttributeMap &attributes)
 {
     ASSERT(mConsumerType == ConsumerType::GLTextureRGB ||
            mConsumerType == ConsumerType::GLTextureYUV);
-    ASSERT(mProducerType == ProducerType::D3D11TextureNV12);
+    ASSERT(mProducerType == ProducerType::D3D11Texture);
 
-    mProducerImplementation->postD3DNV12Texture(texture, attributes);
+    mProducerImplementation->postD3DTexture(texture, attributes);
     mProducerFrame++;
 
     mState = EGL_STREAM_STATE_NEW_FRAME_AVAILABLE_KHR;
 
     return NoError();
 }
 
 // This is called when a texture object associated with this stream is destroyed. Even if multiple
--- a/gfx/angle/src/libANGLE/Stream.h
+++ b/gfx/angle/src/libANGLE/Stream.h
@@ -46,17 +46,17 @@ class Stream final : angle::NonCopyable
         NoConsumer,
         GLTextureRGB,
         GLTextureYUV,
     };
 
     enum class ProducerType
     {
         NoProducer,
-        D3D11TextureNV12,
+        D3D11Texture,
     };
 
     // A GL texture interpretation of a part of a producer frame. For use with GL texture consumers
     struct GLTextureDescription
     {
         unsigned int width;
         unsigned int height;
         unsigned int internalFormat;
@@ -80,29 +80,29 @@ class Stream final : angle::NonCopyable
     EGLint getPlaneCount() const;
 
     rx::StreamProducerImpl *getImplementation();
 
     // Consumer creation methods
     Error createConsumerGLTextureExternal(const AttributeMap &attributes, gl::Context *context);
 
     // Producer creation methods
-    Error createProducerD3D11TextureNV12(const AttributeMap &attributes);
+    Error createProducerD3D11Texture(const AttributeMap &attributes);
 
     // Consumer methods
     Error consumerAcquire(const gl::Context *context);
     Error consumerRelease(const gl::Context *context);
 
     // Some consumers are bound to GL contexts. This validates that a given context is bound to the
     // stream's consumer
     bool isConsumerBoundToContext(const gl::Context *context) const;
 
     // Producer methods
-    Error validateD3D11NV12Texture(void *texture, const AttributeMap &attributes) const;
-    Error postD3D11NV12Texture(void *texture, const AttributeMap &attributes);
+    Error validateD3D11Texture(void *texture, const AttributeMap &attributes) const;
+    Error postD3D11Texture(void *texture, const AttributeMap &attributes);
 
   private:
     // Associated display
     Display *mDisplay;
 
     // Producer Implementation
     rx::StreamProducerImpl *mProducerImplementation;
 
--- a/gfx/angle/src/libANGLE/Surface.cpp
+++ b/gfx/angle/src/libANGLE/Surface.cpp
@@ -7,38 +7,36 @@
 // Surface.cpp: Implements the egl::Surface class, representing a drawing surface
 // such as the client area of a window, including any back buffers.
 // Implements EGLSurface and related functionality. [EGL 1.4] section 2.2 page 3.
 
 #include "libANGLE/Surface.h"
 
 #include <EGL/eglext.h>
 
-#include <iostream>
-
 #include "libANGLE/Config.h"
 #include "libANGLE/Context.h"
 #include "libANGLE/Display.h"
 #include "libANGLE/Framebuffer.h"
 #include "libANGLE/Texture.h"
 #include "libANGLE/Thread.h"
 #include "libANGLE/formatutils.h"
 #include "libANGLE/renderer/EGLImplFactory.h"
 
 namespace egl
 {
 
-SurfaceState::SurfaceState(const egl::Config *configIn)
-    : defaultFramebuffer(nullptr), config(configIn)
+SurfaceState::SurfaceState(const egl::Config *configIn, const AttributeMap &attributesIn)
+    : defaultFramebuffer(nullptr), config(configIn), attributes(attributesIn)
 {
 }
 
 Surface::Surface(EGLint surfaceType, const egl::Config *config, const AttributeMap &attributes)
     : FramebufferAttachmentObject(),
-      mState(config),
+      mState(config, attributes),
       mImplementation(nullptr),
       mCurrentCount(0),
       mDestroyed(false),
       mType(surfaceType),
       mPostSubBufferRequested(false),
       mLargestPbuffer(false),
       mGLColorspace(EGL_GL_COLORSPACE_LINEAR),
       mVGAlphaFormat(EGL_VG_ALPHA_FORMAT_NONPRE),
@@ -54,17 +52,17 @@ Surface::Surface(EGLint surfaceType, con
       mTextureFormat(EGL_NO_TEXTURE),
       mTextureTarget(EGL_NO_TEXTURE),
       // FIXME: Determine actual pixel aspect ratio
       mPixelAspectRatio(static_cast<EGLint>(1.0 * EGL_DISPLAY_SCALING)),
       mRenderBuffer(EGL_BACK_BUFFER),
       mSwapBehavior(EGL_NONE),
       mOrientation(0),
       mTexture(),
-      mBackFormat(config->renderTargetFormat),
+      mColorFormat(config->renderTargetFormat),
       mDSFormat(config->depthStencilFormat)
 {
     mPostSubBufferRequested = (attributes.get(EGL_POST_SUB_BUFFER_SUPPORTED_NV, EGL_FALSE) == EGL_TRUE);
     mFlexibleSurfaceCompatibilityRequested =
         (attributes.get(EGL_FLEXIBLE_SURFACE_COMPATIBILITY_SUPPORTED_ANGLE, EGL_FALSE) == EGL_TRUE);
 
     if (mType == EGL_PBUFFER_BIT)
     {
@@ -75,16 +73,19 @@ Surface::Surface(EGLint surfaceType, con
         static_cast<EGLenum>(attributes.get(EGL_GL_COLORSPACE, EGL_GL_COLORSPACE_LINEAR));
     mVGAlphaFormat =
         static_cast<EGLenum>(attributes.get(EGL_VG_ALPHA_FORMAT, EGL_VG_ALPHA_FORMAT_NONPRE));
     mVGColorspace = static_cast<EGLenum>(attributes.get(EGL_VG_COLORSPACE, EGL_VG_COLORSPACE_sRGB));
     mMipmapTexture = (attributes.get(EGL_MIPMAP_TEXTURE, EGL_FALSE) == EGL_TRUE);
 
     mDirectComposition = (attributes.get(EGL_DIRECT_COMPOSITION_ANGLE, EGL_FALSE) == EGL_TRUE);
 
+    mRobustResourceInitialization =
+        (attributes.get(EGL_ROBUST_RESOURCE_INITIALIZATION_ANGLE, EGL_FALSE) == EGL_TRUE);
+
     mFixedSize = (attributes.get(EGL_FIXED_SIZE_ANGLE, EGL_FALSE) == EGL_TRUE);
     if (mFixedSize)
     {
         mFixedWidth  = static_cast<size_t>(attributes.get(EGL_WIDTH, 0));
         mFixedHeight = static_cast<size_t>(attributes.get(EGL_HEIGHT, 0));
     }
 
     if (mType != EGL_WINDOW_BIT)
@@ -95,16 +96,21 @@ Surface::Surface(EGLint surfaceType, con
 
     mOrientation = static_cast<EGLint>(attributes.get(EGL_SURFACE_ORIENTATION_ANGLE, 0));
 }
 
 Surface::~Surface()
 {
 }
 
+rx::FramebufferAttachmentObjectImpl *Surface::getAttachmentImpl() const
+{
+    return mImplementation;
+}
+
 Error Surface::destroyImpl(const Display *display)
 {
     if (mState.defaultFramebuffer)
     {
         mState.defaultFramebuffer->destroyDefault(display);
     }
     if (mImplementation)
     {
@@ -374,17 +380,17 @@ void Surface::releaseTexImageFromTexture
 
 gl::Extents Surface::getAttachmentSize(const gl::ImageIndex & /*target*/) const
 {
     return gl::Extents(getWidth(), getHeight(), 1);
 }
 
 const gl::Format &Surface::getAttachmentFormat(GLenum binding, const gl::ImageIndex &target) const
 {
-    return (binding == GL_BACK ? mBackFormat : mDSFormat);
+    return (binding == GL_BACK ? mColorFormat : mDSFormat);
 }
 
 GLsizei Surface::getAttachmentSamples(const gl::ImageIndex &target) const
 {
     return getConfig()->samples;
 }
 
 GLuint Surface::getId() const
@@ -393,16 +399,27 @@ GLuint Surface::getId() const
     return 0;
 }
 
 gl::Framebuffer *Surface::createDefaultFramebuffer(const Display *display)
 {
     return new gl::Framebuffer(display, this);
 }
 
+gl::InitState Surface::initState(const gl::ImageIndex & /*imageIndex*/) const
+{
+    // TODO(jmadill): Lazy surface init.
+    return gl::InitState::Initialized;
+}
+
+void Surface::setInitState(const gl::ImageIndex & /*imageIndex*/, gl::InitState /*initState*/)
+{
+    // No-op.
+}
+
 WindowSurface::WindowSurface(rx::EGLImplFactory *implFactory,
                              const egl::Config *config,
                              EGLNativeWindowType window,
                              const AttributeMap &attribs)
     : Surface(EGL_WINDOW_BIT, config, attribs)
 {
     mImplementation = implFactory->createWindowSurface(mState, window, attribs);
 }
@@ -423,16 +440,23 @@ PbufferSurface::PbufferSurface(rx::EGLIm
                                const Config *config,
                                EGLenum buftype,
                                EGLClientBuffer clientBuffer,
                                const AttributeMap &attribs)
     : Surface(EGL_PBUFFER_BIT, config, attribs)
 {
     mImplementation =
         implFactory->createPbufferFromClientBuffer(mState, buftype, clientBuffer, attribs);
+
+    if (buftype == EGL_IOSURFACE_ANGLE)
+    {
+        GLenum internalFormat = static_cast<GLenum>(attribs.get(EGL_TEXTURE_INTERNAL_FORMAT_ANGLE));
+        GLenum type           = static_cast<GLenum>(attribs.get(EGL_TEXTURE_TYPE_ANGLE));
+        mColorFormat          = gl::Format(internalFormat, type);
+    }
 }
 
 PbufferSurface::~PbufferSurface()
 {
 }
 
 PixmapSurface::PixmapSurface(rx::EGLImplFactory *implFactory,
                              const Config *config,
@@ -442,9 +466,24 @@ PixmapSurface::PixmapSurface(rx::EGLImpl
 {
     mImplementation = implFactory->createPixmapSurface(mState, nativePixmap, attribs);
 }
 
 PixmapSurface::~PixmapSurface()
 {
 }
 
+// SurfaceDeleter implementation.
+
+SurfaceDeleter::SurfaceDeleter(const Display *display) : mDisplay(display)
+{
+}
+
+SurfaceDeleter::~SurfaceDeleter()
+{
+}
+
+void SurfaceDeleter::operator()(Surface *surface)
+{
+    ANGLE_SWALLOW_ERR(surface->onDestroy(mDisplay));
+}
+
 }  // namespace egl
--- a/gfx/angle/src/libANGLE/Surface.h
+++ b/gfx/angle/src/libANGLE/Surface.h
@@ -9,16 +9,17 @@
 // Implements EGLSurface and related functionality. [EGL 1.4] section 2.2 page 3.
 
 #ifndef LIBANGLE_SURFACE_H_
 #define LIBANGLE_SURFACE_H_
 
 #include <EGL/egl.h>
 
 #include "common/angleutils.h"
+#include "libANGLE/AttributeMap.h"
 #include "libANGLE/Error.h"
 #include "libANGLE/FramebufferAttachment.h"
 #include "libANGLE/RefCountObject.h"
 #include "libANGLE/formatutils.h"
 #include "libANGLE/renderer/SurfaceImpl.h"
 
 namespace gl
 {
@@ -28,26 +29,26 @@ class Texture;
 
 namespace rx
 {
 class EGLImplFactory;
 }
 
 namespace egl
 {
-class AttributeMap;
 class Display;
 struct Config;
 
 struct SurfaceState final : private angle::NonCopyable
 {
-    SurfaceState(const egl::Config *configIn);
+    SurfaceState(const egl::Config *configIn, const AttributeMap &attributesIn);
 
     gl::Framebuffer *defaultFramebuffer;
     const egl::Config *config;
+    AttributeMap attributes;
 };
 
 class Surface : public gl::FramebufferAttachmentObject
 {
   public:
     rx::SurfaceImpl *getImplementation() const { return mImplementation; }
 
     EGLint getType() const;
@@ -114,20 +115,27 @@ class Surface : public gl::FramebufferAt
     bool flexibleSurfaceCompatibilityRequested() const
     {
         return mFlexibleSurfaceCompatibilityRequested;
     }
     EGLint getOrientation() const { return mOrientation; }
 
     bool directComposition() const { return mDirectComposition; }
 
+    gl::InitState initState(const gl::ImageIndex &imageIndex) const override;
+    void setInitState(const gl::ImageIndex &imageIndex, gl::InitState initState) override;
+
+    bool isRobustResourceInitEnabled() const { return mRobustResourceInitialization; }
+
+    const gl::Format &getBindTexImageFormat() const { return mColorFormat; }
+
   protected:
     Surface(EGLint surfaceType, const egl::Config *config, const AttributeMap &attributes);
-    virtual ~Surface();
-    rx::FramebufferAttachmentObjectImpl *getAttachmentImpl() const override { return mImplementation; }
+    ~Surface() override;
+    rx::FramebufferAttachmentObjectImpl *getAttachmentImpl() const override;
 
     gl::Framebuffer *createDefaultFramebuffer(const Display *display);
 
     // ANGLE-only method, used internally
     friend class gl::Texture;
     void releaseTexImageFromTexture(const gl::Context *context);
 
     SurfaceState mState;
@@ -151,28 +159,30 @@ class Surface : public gl::FramebufferAt
     EGLenum mMultisampleResolve;
 
     bool mFixedSize;
     size_t mFixedWidth;
     size_t mFixedHeight;
 
     bool mDirectComposition;
 
+    bool mRobustResourceInitialization;
+
     EGLenum mTextureFormat;
     EGLenum mTextureTarget;
 
     EGLint mPixelAspectRatio;      // Display aspect ratio
     EGLenum mRenderBuffer;         // Render buffer
     EGLenum mSwapBehavior;         // Buffer swap behavior
 
     EGLint mOrientation;
 
     gl::BindingPointer<gl::Texture> mTexture;
 
-    gl::Format mBackFormat;
+    gl::Format mColorFormat;
     gl::Format mDSFormat;
 
   private:
     Error destroyImpl(const Display *display);
 };
 
 class WindowSurface final : public Surface
 {
@@ -207,13 +217,24 @@ class PixmapSurface final : public Surfa
                   const Config *config,
                   NativePixmapType nativePixmap,
                   const AttributeMap &attribs);
 
   protected:
     ~PixmapSurface() override;
 };
 
-using SurfacePointer = angle::UniqueObjectPointer<Surface, Display>;
+class SurfaceDeleter final
+{
+  public:
+    SurfaceDeleter(const Display *display);
+    ~SurfaceDeleter();
+    void operator()(Surface *surface);
+
+  private:
+    const Display *mDisplay;
+};
+
+using SurfacePointer = angle::UniqueObjectPointerBase<Surface, SurfaceDeleter>;
 
 }  // namespace egl
 
 #endif   // LIBANGLE_SURFACE_H_
--- a/gfx/angle/src/libANGLE/Surface_unittest.cpp
+++ b/gfx/angle/src/libANGLE/Surface_unittest.cpp
@@ -20,17 +20,17 @@ using namespace rx;
 using namespace testing;
 
 namespace
 {
 
 class MockSurfaceImpl : public rx::SurfaceImpl
 {
   public:
-    MockSurfaceImpl() : SurfaceImpl(mockState), mockState(nullptr) {}
+    MockSurfaceImpl() : SurfaceImpl(mockState), mockState(nullptr, egl::AttributeMap()) {}
     virtual ~MockSurfaceImpl() { destructor(); }
 
     MOCK_METHOD1(destroy, void(const egl::Display *));
     MOCK_METHOD1(initialize, egl::Error(const egl::Display *));
     MOCK_METHOD1(createDefaultFramebuffer, rx::FramebufferImpl *(const gl::FramebufferState &data));
     MOCK_METHOD1(swap, egl::Error(const gl::Context *));
     MOCK_METHOD3(swapWithDamage, egl::Error(const gl::Context *, EGLint *, EGLint));
     MOCK_METHOD5(postSubBuffer, egl::Error(const gl::Context *, EGLint, EGLint, EGLint, EGLint));
--- a/gfx/angle/src/libANGLE/Texture.cpp
+++ b/gfx/angle/src/libANGLE/Texture.cpp
@@ -31,16 +31,42 @@ bool IsPointSampled(const SamplerState &
              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)
+{
+    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));
+}
+
+InitState DetermineInitState(const Context *context, const uint8_t *pixels)
+{
+    // Can happen in tests.
+    if (!context || !context->isRobustResourceInitEnabled())
+        return InitState::Initialized;
+
+    const auto &glState = context->getGLState();
+    return (pixels == nullptr && glState.getTargetBuffer(gl::BufferBinding::PixelUnpack) == nullptr)
+               ? InitState::MayNeedInit
+               : InitState::Initialized;
+}
+
 }  // namespace
 
 bool IsMipmapFiltered(const SamplerState &samplerState)
 {
     switch (samplerState.minFilter)
     {
         case GL_NEAREST:
         case GL_LINEAR:
@@ -91,17 +117,23 @@ TextureState::TextureState(GLenum target
       mSwizzleState(GL_RED, GL_GREEN, GL_BLUE, GL_ALPHA),
       mSamplerState(SamplerState::CreateDefaultForTarget(target)),
       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) *
+                  (target == GL_TEXTURE_CUBE_MAP ? 6 : 1)),
+      mInitState(InitState::MayNeedInit)
+{
+}
+
+TextureState::~TextureState()
 {
 }
 
 bool TextureState::swizzleRequired() const
 {
     return mSwizzleState.swizzleRequired();
 }
 
@@ -399,66 +431,77 @@ bool TextureState::computeLevelCompleten
     return true;
 }
 
 GLenum TextureState::getBaseImageTarget() const
 {
     return mTarget == GL_TEXTURE_CUBE_MAP ? FirstCubeMapTextureTarget : mTarget;
 }
 
-ImageDesc::ImageDesc() : ImageDesc(Extents(0, 0, 0), Format::Invalid(), 0, GL_TRUE)
+ImageDesc::ImageDesc()
+    : ImageDesc(Extents(0, 0, 0), Format::Invalid(), 0, GL_TRUE, InitState::Initialized)
 {
 }
 
-ImageDesc::ImageDesc(const Extents &size, const Format &format)
-    : size(size), format(format), samples(0), fixedSampleLocations(GL_TRUE)
+ImageDesc::ImageDesc(const Extents &size, const Format &format, const InitState initState)
+    : size(size), format(format), samples(0), fixedSampleLocations(GL_TRUE), initState(initState)
 {
 }
 
 ImageDesc::ImageDesc(const Extents &size,
                      const Format &format,
                      const GLsizei samples,
-                     const GLboolean fixedSampleLocations)
-    : size(size), format(format), samples(samples), fixedSampleLocations(fixedSampleLocations)
+                     const bool fixedSampleLocations,
+                     const InitState initState)
+    : size(size),
+      format(format),
+      samples(samples),
+      fixedSampleLocations(fixedSampleLocations),
+      initState(initState)
 {
 }
 
 const ImageDesc &TextureState::getImageDesc(GLenum 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)
 {
     size_t descIndex = GetImageDescIndex(target, level);
     ASSERT(descIndex < mImageDescs.size());
     mImageDescs[descIndex] = desc;
+    if (desc.initState == InitState::MayNeedInit)
+    {
+        mInitState = InitState::MayNeedInit;
+    }
 }
 
 const ImageDesc &TextureState::getImageDesc(const ImageIndex &imageIndex) const
 {
     return getImageDesc(imageIndex.type, imageIndex.mipIndex);
 }
 
 void TextureState::setImageDescChain(GLuint baseLevel,
                                      GLuint maxLevel,
                                      Extents baseSize,
-                                     const Format &format)
+                                     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)
                               ? baseSize.depth
                               : std::max<int>(baseSize.depth >> relativeLevel, 1));
-        ImageDesc levelInfo(levelSize, format);
+        ImageDesc levelInfo(levelSize, format, initState);
 
         if (mTarget == GL_TEXTURE_CUBE_MAP)
         {
             for (GLenum face = FirstCubeMapTextureTarget; face <= LastCubeMapTextureTarget; face++)
             {
                 setImageDesc(face, level, levelInfo);
             }
         }
@@ -467,20 +510,21 @@ void TextureState::setImageDescChain(GLu
             setImageDesc(mTarget, level, levelInfo);
         }
     }
 }
 
 void TextureState::setImageDescChainMultisample(Extents baseSize,
                                                 const Format &format,
                                                 GLsizei samples,
-                                                GLboolean fixedSampleLocations)
+                                                bool fixedSampleLocations,
+                                                InitState initState)
 {
     ASSERT(mTarget == GL_TEXTURE_2D_MULTISAMPLE);
-    ImageDesc levelInfo(baseSize, format, samples, fixedSampleLocations);
+    ImageDesc levelInfo(baseSize, format, samples, fixedSampleLocations, initState);
     setImageDesc(mTarget, 0, levelInfo);
 }
 
 void TextureState::clearImageDesc(GLenum target, size_t level)
 {
     setImageDesc(target, level, ImageDesc());
 }
 
@@ -819,17 +863,17 @@ const Format &Texture::getFormat(GLenum 
 
 GLsizei Texture::getSamples(GLenum target, size_t level) const
 {
     ASSERT(target == mState.mTarget ||
            (mState.mTarget == GL_TEXTURE_CUBE_MAP && IsCubeMapTextureTarget(target)));
     return mState.getImageDesc(target, level).samples;
 }
 
-GLboolean Texture::getFixedSampleLocations(GLenum target, size_t level) const
+bool Texture::getFixedSampleLocations(GLenum target, size_t level) const
 {
     ASSERT(target == mState.mTarget ||
            (mState.mTarget == GL_TEXTURE_CUBE_MAP && IsCubeMapTextureTarget(target)));
     return mState.getImageDesc(target, level).fixedSampleLocations;
 }
 
 GLuint Texture::getMipmapMaxLevel() const
 {
@@ -846,19 +890,19 @@ egl::Surface *Texture::getBoundSurface()
     return mBoundSurface;
 }
 
 egl::Stream *Texture::getBoundStream() const
 {
     return mBoundStream;
 }
 
-void Texture::signalDirty() const
+void Texture::signalDirty(InitState initState) const
 {
-    mDirtyChannel.signal();
+    mDirtyChannel.signal(initState);
     invalidateCompletenessCache();
 }
 
 Error Texture::setImage(const Context *context,
                         const PixelUnpackState &unpackState,
                         GLenum target,
                         size_t level,
                         GLenum internalFormat,
@@ -872,33 +916,37 @@ Error Texture::setImage(const Context *c
 
     // 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));
 
-    mState.setImageDesc(target, level, ImageDesc(size, Format(internalFormat, type)));
-    signalDirty();
+    InitState initState = DetermineInitState(context, pixels);
+    mState.setImageDesc(target, level, ImageDesc(size, Format(internalFormat, type), initState));
+    signalDirty(initState);
 
     return NoError();
 }
 
 Error Texture::setSubImage(const Context *context,
                            const PixelUnpackState &unpackState,
                            GLenum target,
                            size_t level,
                            const Box &area,
                            GLenum format,
                            GLenum type,
                            const uint8_t *pixels)
 {
     ASSERT(target == mState.mTarget ||
            (mState.mTarget == GL_TEXTURE_CUBE_MAP && IsCubeMapTextureTarget(target)));
+
+    ANGLE_TRY(ensureSubImageInitialized(context, target, level, area));
+
     return mTexture->setSubImage(context, target, level, area, format, type, unpackState, pixels);
 }
 
 Error Texture::setCompressedImage(const Context *context,
                                   const PixelUnpackState &unpackState,
                                   GLenum target,
                                   size_t level,
                                   GLenum internalFormat,
@@ -911,120 +959,153 @@ Error Texture::setCompressedImage(const 
 
     // 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));
 
-    mState.setImageDesc(target, level, ImageDesc(size, Format(internalFormat)));
-    signalDirty();
+    InitState initState = DetermineInitState(context, pixels);
+    mState.setImageDesc(target, level, ImageDesc(size, Format(internalFormat), initState));
+    signalDirty(initState);
 
     return NoError();
 }
 
 Error Texture::setCompressedSubImage(const Context *context,
                                      const PixelUnpackState &unpackState,
                                      GLenum target,
                                      size_t 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)));
 
+    ANGLE_TRY(ensureSubImageInitialized(context, target, level, area));
+
     return mTexture->setCompressedSubImage(context, target, level, area, format, unpackState,
                                            imageSize, pixels);
 }
 
 Error Texture::copyImage(const Context *context,
                          GLenum target,
                          size_t level,
                          const Rectangle &sourceArea,
                          GLenum internalFormat,
-                         const Framebuffer *source)
+                         Framebuffer *source)
 {
     ASSERT(target == mState.mTarget ||
            (mState.mTarget == GL_TEXTURE_CUBE_MAP && IsCubeMapTextureTarget(target)));
 
     // 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));
 
     const InternalFormat &internalFormatInfo =
         GetInternalFormatInfo(internalFormat, GL_UNSIGNED_BYTE);
-    mState.setImageDesc(target, level, ImageDesc(Extents(sourceArea.width, sourceArea.height, 1),
-                                                 Format(internalFormatInfo)));
-    signalDirty();
+
+    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(InitState::Initialized);
 
     return NoError();
 }
 
 Error Texture::copySubImage(const Context *context,
                             GLenum target,
                             size_t level,
                             const Offset &destOffset,
                             const Rectangle &sourceArea,
-                            const Framebuffer *source)
+                            Framebuffer *source)
 {
     ASSERT(target == mState.mTarget ||
            (mState.mTarget == GL_TEXTURE_CUBE_MAP && IsCubeMapTextureTarget(target)));
 
+    // 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);
 }
 
 Error Texture::copyTexture(const Context *context,
                            GLenum target,
                            size_t level,
                            GLenum internalFormat,
                            GLenum type,
                            size_t sourceLevel,
                            bool unpackFlipY,
                            bool unpackPremultiplyAlpha,
                            bool unpackUnmultiplyAlpha,
-                           const Texture *source)
+                           Texture *source)
 {
     ASSERT(target == mState.mTarget ||
            (mState.mTarget == GL_TEXTURE_CUBE_MAP && IsCubeMapTextureTarget(target)));
 
     // 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));
 
     const auto &sourceDesc   = source->mState.getImageDesc(source->getTarget(), 0);
     const InternalFormat &internalFormatInfo = GetInternalFormatInfo(internalFormat, type);
-    mState.setImageDesc(target, level, ImageDesc(sourceDesc.size, Format(internalFormatInfo)));
-    signalDirty();
+    mState.setImageDesc(
+        target, level,
+        ImageDesc(sourceDesc.size, Format(internalFormatInfo), InitState::Initialized));
+
+    signalDirty(InitState::Initialized);
 
     return NoError();
 }
 
 Error Texture::copySubTexture(const Context *context,
                               GLenum target,
                               size_t level,
                               const Offset &destOffset,
                               size_t sourceLevel,
                               const Rectangle &sourceArea,
                               bool unpackFlipY,
                               bool unpackPremultiplyAlpha,
                               bool unpackUnmultiplyAlpha,
-                              const Texture *source)
+                              Texture *source)
 {
     ASSERT(target == mState.mTarget ||
            (mState.mTarget == GL_TEXTURE_CUBE_MAP && IsCubeMapTextureTarget(target)));
 
+    // 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,
                                     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
@@ -1052,53 +1133,54 @@ Error Texture::setStorage(const Context 
     ANGLE_TRY(releaseTexImageInternal(context));
     ANGLE_TRY(orphanImages(context));
 
     ANGLE_TRY(mTexture->setStorage(context, target, 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));
+    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:
     // GLES 3.0.4 section 3.8.10 pg 158:
     // "For immutable-format textures, levelbase is clamped to the range[0;levels],levelmax is then
     // clamped to the range[levelbase;levels].
     mDirtyBits.set(DIRTY_BIT_BASE_LEVEL);
     mDirtyBits.set(DIRTY_BIT_MAX_LEVEL);
 
-    signalDirty();
+    signalDirty(InitState::MayNeedInit);
 
     return NoError();
 }
 
 Error Texture::setStorageMultisample(const Context *context,
                                      GLenum target,
                                      GLsizei samples,
                                      GLint internalFormat,
                                      const Extents &size,
-                                     GLboolean fixedSampleLocations)
+                                     bool fixedSampleLocations)
 {
     ASSERT(target == mState.mTarget);
 
     // 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,
                                               fixedSampleLocations));
 
     mState.mImmutableFormat = true;
     mState.mImmutableLevels = static_cast<GLuint>(1);
     mState.clearImageDescs();
-    mState.setImageDescChainMultisample(size, Format(internalFormat), samples,
-                                        fixedSampleLocations);
+    mState.setImageDescChainMultisample(size, Format(internalFormat), samples, fixedSampleLocations,
+                                        InitState::MayNeedInit);
 
-    signalDirty();
+    signalDirty(InitState::MayNeedInit);
 
     return NoError();
 }
 
 Error Texture::generateMipmap(const Context *context)
 {
     // Release from previous calls to eglBindTexImage, to avoid calling the Impl after
     ANGLE_TRY(releaseTexImageInternal(context));
@@ -1111,24 +1193,34 @@ Error Texture::generateMipmap(const Cont
     }
 
     const GLuint baseLevel = mState.getEffectiveBaseLevel();
     const GLuint maxLevel  = mState.getMipmapMaxLevel();
 
     if (maxLevel > baseLevel)
     {
         syncState();
-        ANGLE_TRY(mTexture->generateMipmap(context));
-
         const ImageDesc &baseImageInfo =
             mState.getImageDesc(mState.getBaseImageTarget(), baseLevel);
-        mState.setImageDescChain(baseLevel, maxLevel, baseImageInfo.size, baseImageInfo.format);
+
+        // Clear the base image immediately if necessary.
+        if (context->isRobustResourceInitEnabled() &&
+            baseImageInfo.initState == InitState::MayNeedInit)
+        {
+            ANGLE_TRY(initializeContents(
+                context, GetImageIndexFromDescIndex(mState.getBaseImageTarget(), baseLevel)));
+        }
+
+        ANGLE_TRY(mTexture->generateMipmap(context));
+
+        mState.setImageDescChain(baseLevel, maxLevel, baseImageInfo.size, baseImageInfo.format,
+                                 InitState::Initialized);
     }
 
-    signalDirty();
+    signalDirty(InitState::Initialized);
 
     return NoError();
 }
 
 Error Texture::bindTexImageFromSurface(const Context *context, egl::Surface *surface)
 {
     ASSERT(surface);
 
@@ -1138,32 +1230,32 @@ Error Texture::bindTexImageFromSurface(c
     }
 
     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);
     Extents size(surface->getWidth(), surface->getHeight(), 1);
-    ImageDesc desc(size, Format(surface->getConfig()->renderTargetFormat));
+    ImageDesc desc(size, surface->getBindTexImageFormat(), InitState::Initialized);
     mState.setImageDesc(mState.mTarget, 0, desc);
-    signalDirty();
+    signalDirty(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);
-    signalDirty();
+    signalDirty(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
@@ -1182,30 +1274,31 @@ void Texture::releaseStream()
 
 Error Texture::acquireImageFromStream(const Context *context,
                                       const egl::Stream::GLTextureDescription &desc)
 {
     ASSERT(mBoundStream != nullptr);
     ANGLE_TRY(mTexture->setImageExternal(context, mState.mTarget, mBoundStream, desc));
 
     Extents size(desc.width, desc.height, 1);
-    mState.setImageDesc(mState.mTarget, 0, ImageDesc(size, Format(desc.internalFormat)));
-    signalDirty();
+    mState.setImageDesc(mState.mTarget, 0,
+                        ImageDesc(size, Format(desc.internalFormat), InitState::Initialized));
+    signalDirty(InitState::Initialized);
     return NoError();
 }
 
 Error Texture::releaseImageFromStream(const Context *context)
 {
     ASSERT(mBoundStream != nullptr);
     ANGLE_TRY(mTexture->setImageExternal(context, mState.mTarget, nullptr,
                                          egl::Stream::GLTextureDescription()));
 
     // Set to incomplete
     mState.clearImageDesc(mState.mTarget, 0);
-    signalDirty();
+    signalDirty(InitState::Initialized);
     return NoError();
 }
 
 Error Texture::releaseTexImageInternal(const Context *context)
 {
     if (mBoundSurface)
     {
         // Notify the surface
@@ -1228,19 +1321,21 @@ Error Texture::setEGLImageTarget(const C
 
     ANGLE_TRY(mTexture->setEGLImageTarget(context, target, 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()));
-    signalDirty();
+    mState.setImageDesc(target, 0, ImageDesc(size, imageTarget->getFormat(), initState));
+    signalDirty(initState);
 
     return NoError();
 }
 
 Extents Texture::getAttachmentSize(const ImageIndex &imageIndex) const
 {
     return mState.getImageDesc(imageIndex).size;
 }
@@ -1304,9 +1399,86 @@ Texture::SamplerCompletenessCache::Sampl
 {
 }
 
 void Texture::invalidateCompletenessCache() const
 {
     mCompletenessCache.context = 0;
 }
 
+Error Texture::ensureInitialized(const Context *context)
+{
+    if (!context->isRobustResourceInitEnabled() || mState.mInitState == InitState::Initialized)
+    {
+        return NoError();
+    }
+
+    bool anyDirty = false;
+
+    for (size_t descIndex = 0; descIndex < mState.mImageDescs.size(); ++descIndex)
+    {
+        auto &imageDesc = mState.mImageDescs[descIndex];
+        if (imageDesc.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;
+        }
+    }
+    if (anyDirty)
+    {
+        signalDirty(InitState::Initialized);
+    }
+    mState.mInitState = InitState::Initialized;
+
+    return NoError();
+}
+
+InitState Texture::initState(const ImageIndex &imageIndex) const
+{
+    return mState.getImageDesc(imageIndex).initState;
+}
+
+InitState Texture::initState() const
+{
+    return mState.mInitState;
+}
+
+void Texture::setInitState(const ImageIndex &imageIndex, InitState initState)
+{
+    ImageDesc newDesc = mState.getImageDesc(imageIndex);
+    newDesc.initState = initState;
+    mState.setImageDesc(imageIndex.type, imageIndex.mipIndex, newDesc);
+}
+
+Error Texture::ensureSubImageInitialized(const Context *context,
+                                         GLenum 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);
+    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)
+        {
+            ANGLE_TRY(initializeContents(context, imageIndex));
+        }
+        setInitState(imageIndex, InitState::Initialized);
+    }
+
+    return NoError();
+}
+
 }  // namespace gl
--- a/gfx/angle/src/libANGLE/Texture.h
+++ b/gfx/angle/src/libANGLE/Texture.h
@@ -45,29 +45,33 @@ class Framebuffer;
 class Sampler;
 class Texture;
 
 bool IsMipmapFiltered(const SamplerState &samplerState);
 
 struct ImageDesc final
 {
     ImageDesc();
-    ImageDesc(const Extents &size, const Format &format);
+    ImageDesc(const Extents &size, const Format &format, const InitState initState);
     ImageDesc(const Extents &size,
               const Format &format,
               const GLsizei samples,
-              const GLboolean fixedSampleLocations);
+              const bool fixedSampleLocations,
+              const InitState initState);
 
     ImageDesc(const ImageDesc &other) = default;
     ImageDesc &operator=(const ImageDesc &other) = default;
 
     Extents size;
     Format format;
     GLsizei samples;
-    GLboolean fixedSampleLocations;
+    bool fixedSampleLocations;
+
+    // Needed for robust resource initialization.
+    InitState initState;
 };
 
 struct SwizzleState final
 {
     SwizzleState();
     SwizzleState(GLenum red, GLenum green, GLenum blue, GLenum alpha);
     SwizzleState(const SwizzleState &other) = default;
     SwizzleState &operator=(const SwizzleState &other) = default;
@@ -82,16 +86,17 @@ struct SwizzleState final
     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();
 
     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;
 
@@ -122,21 +127,23 @@ struct TextureState final : private angl
     bool computeLevelCompleteness(GLenum target, size_t level) const;
 
     GLenum getBaseImageTarget() const;
 
     void setImageDesc(GLenum target, size_t level, const ImageDesc &desc);
     void setImageDescChain(GLuint baselevel,
                            GLuint maxLevel,
                            Extents baseSize,
-                           const Format &format);
+                           const Format &format,
+                           InitState initState);
     void setImageDescChainMultisample(Extents baseSize,
                                       const Format &format,
                                       GLsizei samples,
-                                      GLboolean fixedSampleLocations);
+                                      bool fixedSampleLocations,
+                                      InitState initState);
 
     void clearImageDesc(GLenum target, size_t level);
     void clearImageDescs();
 
     const GLenum mTarget;
 
     SwizzleState mSwizzleState;
 
@@ -149,17 +156,17 @@ struct TextureState final : private angl
 
     bool mImmutableFormat;
     GLuint mImmutableLevels;
 
     // From GL_ANGLE_texture_usage
     GLenum mUsage;
 
     std::vector<ImageDesc> mImageDescs;
-
+    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
 {
@@ -238,17 +245,17 @@ class Texture final : public egl::ImageS
     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;
-    GLboolean getFixedSampleLocations(GLenum target, size_t level) const;
+    bool getFixedSampleLocations(GLenum target, size_t level) const;
     const Format &getFormat(GLenum 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,
@@ -286,81 +293,87 @@ class Texture final : public egl::ImageS
                                 size_t imageSize,
                                 const uint8_t *pixels);
 
     Error copyImage(const Context *context,
                     GLenum target,
                     size_t level,
                     const Rectangle &sourceArea,
                     GLenum internalFormat,
-                    const Framebuffer *source);
+                    Framebuffer *source);
     Error copySubImage(const Context *context,
                        GLenum target,
                        size_t level,
                        const Offset &destOffset,
                        const Rectangle &sourceArea,
-                       const Framebuffer *source);
+                       Framebuffer *source);
 
     Error copyTexture(const Context *context,
                       GLenum target,
                       size_t level,
                       GLenum internalFormat,
                       GLenum type,
                       size_t sourceLevel,
                       bool unpackFlipY,
                       bool unpackPremultiplyAlpha,
                       bool unpackUnmultiplyAlpha,
-                      const Texture *source);
+                      Texture *source);
     Error copySubTexture(const Context *context,
                          GLenum target,
                          size_t level,
                          const Offset &destOffset,
                          size_t sourceLevel,
                          const Rectangle &sourceArea,
                          bool unpackFlipY,
                          bool unpackPremultiplyAlpha,
                          bool unpackUnmultiplyAlpha,
-                         const Texture *source);
+                         Texture *source);
     Error copyCompressedTexture(const Context *context, const Texture *source);
 
     Error setStorage(const Context *context,
                      GLenum target,
                      GLsizei levels,
                      GLenum internalFormat,
                      const Extents &size);
 
     Error setStorageMultisample(const Context *context,
                                 GLenum target,
                                 GLsizei samples,
                                 GLint internalformat,
                                 const Extents &size,
-                                GLboolean fixedSampleLocations);
+                                bool fixedSampleLocations);
 
     Error setEGLImageTarget(const Context *context, GLenum target, egl::Image *imageTarget);
 
     Error generateMipmap(const Context *context);
 
     egl::Surface *getBoundSurface() const;
     egl::Stream *getBoundStream() const;
 
-    void signalDirty() const;
+    void signalDirty(InitState initState) const;
 
     bool isSamplerComplete(const Context *context, const Sampler *optionalSampler);
 
     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;
 
     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;
+    void setInitState(const ImageIndex &imageIndex, InitState initState) override;
+
     enum DirtyBitType
     {
         // Sampler state
         DIRTY_BIT_MIN_FILTER,
         DIRTY_BIT_MAG_FILTER,
         DIRTY_BIT_WRAP_S,
         DIRTY_BIT_WRAP_T,
         DIRTY_BIT_WRAP_R,
@@ -402,25 +415,29 @@ class Texture final : public egl::ImageS
     friend class egl::Stream;
     void bindStream(egl::Stream *stream);
     void releaseStream();
     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,
+                                    size_t level,
+                                    const gl::Box &area);
 
     TextureState mState;
     DirtyBits mDirtyBits;
     rx::TextureImpl *mTexture;
 
     std::string mLabel;
 
-    Error releaseTexImageInternal(const Context *context);
-
     egl::Surface *mBoundSurface;
     egl::Stream *mBoundStream;
 
     struct SamplerCompletenessCache
     {
         SamplerCompletenessCache();
 
         // Context used to generate this cache entry
--- a/gfx/angle/src/libANGLE/TransformFeedback.cpp
+++ b/gfx/angle/src/libANGLE/TransformFeedback.cpp
@@ -22,16 +22,20 @@ TransformFeedbackState::TransformFeedbac
       mPrimitiveMode(GL_NONE),
       mPaused(false),
       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];
--- a/gfx/angle/src/libANGLE/TransformFeedback.h
+++ b/gfx/angle/src/libANGLE/TransformFeedback.h
@@ -26,16 +26,17 @@ class Buffer;
 struct Caps;
 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;
 
@@ -50,17 +51,17 @@ class TransformFeedbackState final : ang
     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);
-    virtual ~TransformFeedback();
+    ~TransformFeedback() override;
     Error onDestroy(const Context *context) override;
 
     void setLabel(const std::string &label) override;
     const std::string &getLabel() const override;
 
     void begin(const Context *context, GLenum primitiveMode, Program *program);
     void end(const Context *context);
     void pause();
--- a/gfx/angle/src/libANGLE/Uniform.cpp
+++ b/gfx/angle/src/libANGLE/Uniform.cpp
@@ -8,64 +8,109 @@
 
 #include "common/utilities.h"
 
 #include <cstring>
 
 namespace gl
 {
 
+StaticallyUsed::StaticallyUsed()
+    : vertexStaticUse(false), fragmentStaticUse(false), computeStaticUse(false)
+{
+}
+
+StaticallyUsed::~StaticallyUsed()
+{
+}
+
+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;
+
+        case GL_FRAGMENT_SHADER:
+            fragmentStaticUse = used;
+            break;
+
+        case GL_COMPUTE_SHADER:
+            computeStaticUse = used;
+            break;
+
+        default:
+            UNREACHABLE();
+    }
+}
+
+void StaticallyUsed::unionReferencesWith(const StaticallyUsed &other)
+{
+    vertexStaticUse |= other.vertexStaticUse;
+    fragmentStaticUse |= other.fragmentStaticUse;
+    computeStaticUse |= other.computeStaticUse;
+}
+
 LinkedUniform::LinkedUniform()
     : typeInfo(nullptr), bufferIndex(-1), blockInfo(sh::BlockMemberInfo::getDefaultBlockInfo())
 {
 }
 
 LinkedUniform::LinkedUniform(GLenum typeIn,
                              GLenum precisionIn,
                              const std::string &nameIn,
-                             unsigned int arraySizeIn,
+                             const std::vector<unsigned int> &arraySizesIn,
                              const int bindingIn,
                              const int offsetIn,
                              const int locationIn,
                              const int bufferIndexIn,
                              const sh::BlockMemberInfo &blockInfoIn)
     : typeInfo(&GetUniformTypeInfo(typeIn)), bufferIndex(bufferIndexIn), blockInfo(blockInfoIn)
 {
     type      = typeIn;
     precision = precisionIn;
     name      = nameIn;
-    arraySize = arraySizeIn;
+    arraySizes = arraySizesIn;
     binding   = bindingIn;
     offset    = offsetIn;
     location  = locationIn;
+    ASSERT(!isArrayOfArrays());
+    ASSERT(!isArray() || !isStruct());
 }
 
 LinkedUniform::LinkedUniform(const sh::Uniform &uniform)
     : sh::Uniform(uniform),
       typeInfo(&GetUniformTypeInfo(type)),
       bufferIndex(-1),
       blockInfo(sh::BlockMemberInfo::getDefaultBlockInfo())
 {
+    ASSERT(!isArrayOfArrays());
+    ASSERT(!isArray() || !isStruct());
 }
 
 LinkedUniform::LinkedUniform(const LinkedUniform &uniform)
     : sh::Uniform(uniform),
+      StaticallyUsed(uniform),
       typeInfo(uniform.typeInfo),
       bufferIndex(uniform.bufferIndex),
       blockInfo(uniform.blockInfo)
 {
 }
 
 LinkedUniform &LinkedUniform::operator=(const LinkedUniform &uniform)
 {
     sh::Uniform::operator=(uniform);
+    StaticallyUsed::operator=(uniform);
     typeInfo             = uniform.typeInfo;
     bufferIndex          = uniform.bufferIndex;
     blockInfo            = uniform.blockInfo;
-
     return *this;
 }
 
 LinkedUniform::~LinkedUniform()
 {
 }
 
 bool LinkedUniform::isInDefaultBlock() const
@@ -98,29 +143,54 @@ size_t LinkedUniform::getElementSize() c
     return typeInfo->externalSize;
 }
 
 size_t LinkedUniform::getElementComponents() const
 {
     return typeInfo->componentCount;
 }
 
-ShaderVariableBuffer::ShaderVariableBuffer()
-    : binding(0),
-      dataSize(0),
-      vertexStaticUse(false),
-      fragmentStaticUse(false),
-      computeStaticUse(false)
+BufferVariable::BufferVariable()
+    : bufferIndex(-1), blockInfo(sh::BlockMemberInfo::getDefaultBlockInfo()), topLevelArraySize(-1)
 {
 }
 
+BufferVariable::BufferVariable(GLenum typeIn,
+                               GLenum precisionIn,
+                               const std::string &nameIn,
+                               const std::vector<unsigned int> &arraySizesIn,
+                               const int bufferIndexIn,
+                               const sh::BlockMemberInfo &blockInfoIn)
+    : bufferIndex(bufferIndexIn), blockInfo(blockInfoIn), topLevelArraySize(-1)
+{
+    type      = typeIn;
+    precision = precisionIn;
+    name      = nameIn;
+    arraySizes = arraySizesIn;
+}
+
+BufferVariable::~BufferVariable()
+{
+}
+
+ShaderVariableBuffer::ShaderVariableBuffer() : binding(0), dataSize(0)
+{
+}
+
+ShaderVariableBuffer::ShaderVariableBuffer(const ShaderVariableBuffer &other) = default;
+
 ShaderVariableBuffer::~ShaderVariableBuffer()
 {
 }
 
+int ShaderVariableBuffer::numActiveVariables() const
+{
+    return static_cast<int>(memberIndexes.size());
+}
+
 InterfaceBlock::InterfaceBlock() : isArray(false), arrayElement(0)
 {
 }
 
 InterfaceBlock::InterfaceBlock(const std::string &nameIn,
                                const std::string &mappedNameIn,
                                bool isArrayIn,
                                unsigned int arrayElementIn,
--- a/gfx/angle/src/libANGLE/Uniform.h
+++ b/gfx/angle/src/libANGLE/Uniform.h
@@ -15,81 +15,107 @@
 #include "common/MemoryBuffer.h"
 #include "compiler/translator/blocklayout.h"
 #include "libANGLE/angletypes.h"
 
 namespace gl
 {
 struct UniformTypeInfo;
 
+struct StaticallyUsed
+{
+    StaticallyUsed();
+    StaticallyUsed(const StaticallyUsed &rhs);
+    virtual ~StaticallyUsed();
+
+    StaticallyUsed &operator=(const StaticallyUsed &rhs);
+
+    void setStaticUse(GLenum shaderType, bool used);
+    void unionReferencesWith(const StaticallyUsed &other);
+
+    bool vertexStaticUse;
+    bool fragmentStaticUse;
+    bool computeStaticUse;
+};
+
 // Helper struct representing a single shader uniform
-struct LinkedUniform : public sh::Uniform
+struct LinkedUniform : public sh::Uniform, public StaticallyUsed
 {
     LinkedUniform();
     LinkedUniform(GLenum type,
                   GLenum precision,
                   const std::string &name,
-                  unsigned int arraySize,
+                  const std::vector<unsigned int> &arraySizes,
                   const int binding,
                   const int offset,
                   const int location,
                   const int bufferIndex,
                   const sh::BlockMemberInfo &blockInfo);
     LinkedUniform(const sh::Uniform &uniform);
     LinkedUniform(const LinkedUniform &uniform);
     LinkedUniform &operator=(const LinkedUniform &uniform);
-    ~LinkedUniform();
+    ~LinkedUniform() override;
 
     bool isSampler() const;
     bool isImage() const;
     bool isAtomicCounter() const;
     bool isInDefaultBlock() const;
     bool isField() const;
     size_t getElementSize() const;
     size_t getElementComponents() const;
 
     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
+{
+    BufferVariable();
+    BufferVariable(GLenum type,
+                   GLenum precision,
+                   const std::string &name,
+                   const std::vector<unsigned int> &arraySizes,
+                   const int bufferIndex,
+                   const sh::BlockMemberInfo &blockInfo);
+    ~BufferVariable() override;
+
+    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
+struct ShaderVariableBuffer : public StaticallyUsed
 {
     ShaderVariableBuffer();
-    virtual ~ShaderVariableBuffer();
-    ShaderVariableBuffer(const ShaderVariableBuffer &other) = default;
-    ShaderVariableBuffer &operator=(const ShaderVariableBuffer &other) = default;
-    int numActiveVariables() const { return static_cast<int>(memberIndexes.size()); }
+    ShaderVariableBuffer(const ShaderVariableBuffer &other);
+    ~ShaderVariableBuffer() override;
+    int numActiveVariables() const;
 
     int binding;
     unsigned int dataSize;
     std::vector<unsigned int> memberIndexes;
-
-    bool vertexStaticUse;
-    bool fragmentStaticUse;
-    bool computeStaticUse;
 };
 
 using AtomicCounterBuffer = ShaderVariableBuffer;
 
 // Helper struct representing a single shader interface block
 struct InterfaceBlock : public ShaderVariableBuffer
 {
     InterfaceBlock();
     InterfaceBlock(const std::string &nameIn,
                    const std::string &mappedNameIn,
                    bool isArrayIn,
                    unsigned int arrayElementIn,
                    int bindingIn);
-    InterfaceBlock(const InterfaceBlock &other) = default;
-    InterfaceBlock &operator=(const InterfaceBlock &other) = default;
 
     std::string nameWithArrayIndex() const;
     std::string mappedNameWithArrayIndex() const;
 
     std::string name;
     std::string mappedName;
     bool isArray;
     unsigned int arrayElement;
deleted file mode 100644
--- a/gfx/angle/src/libANGLE/UniformLinker.cpp
+++ /dev/null
@@ -1,586 +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.
-//
-
-// UniformLinker.cpp: implements link-time checks for default block uniforms, and generates uniform
-// locations. Populates data structures related to uniforms so that they can be stored in program
-// state.
-
-#include "libANGLE/UniformLinker.h"
-
-#include "common/utilities.h"
-#include "libANGLE/Caps.h"
-#include "libANGLE/Context.h"
-#include "libANGLE/Shader.h"
-#include "libANGLE/features.h"
-
-namespace gl
-{
-
-namespace
-{
-
-LinkedUniform *FindUniform(std::vector<LinkedUniform> &list, const std::string &name)
-{
-    for (LinkedUniform &uniform : list)
-    {
-        if (uniform.name == name)
-            return &uniform;
-    }
-
-    return nullptr;
-}
-
-}  // anonymouse namespace
-
-UniformLinker::UniformLinker(const ProgramState &state) : mState(state)
-{
-}
-
-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 Program::Bindings &uniformLocationBindings)
-{
-    if (mState.getAttachedVertexShader() && mState.getAttachedFragmentShader())
-    {
-        ASSERT(mState.getAttachedComputeShader() == nullptr);
-        if (!validateVertexAndFragmentUniforms(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::validateVertexAndFragmentUniforms(const Context *context,
-                                                      InfoLog &infoLog) const
-{
-    // Check that uniforms defined in the vertex and fragment shaders are identical
-    std::map<std::string, LinkedUniform> 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] = LinkedUniform(vertexUniform);
-    }
-
-    for (const sh::Uniform &fragmentUniform : fragmentUniforms)
-    {
-        auto entry = linkedUniforms.find(fragmentUniform.name);
-        if (entry != linkedUniforms.end())
-        {
-            LinkedUniform *linkedUniform   = &entry->second;
-            const std::string &uniformName = "uniform '" + linkedUniform->name + "'";
-            if (!linkValidateUniforms(infoLog, uniformName, *linkedUniform, fragmentUniform))
-            {
-                return false;
-            }
-        }
-    }
-    return true;
-}
-
-// GLSL ES Spec 3.00.3, section 4.3.5.
-bool UniformLinker::linkValidateUniforms(InfoLog &infoLog,
-                                         const std::string &uniformName,
-                                         const sh::Uniform &vertexUniform,
-                                         const sh::Uniform &fragmentUniform)
-{
-#if ANGLE_PROGRAM_LINK_VALIDATE_UNIFORM_PRECISION == ANGLE_ENABLED
-    const bool validatePrecision = true;
-#else
-    const bool validatePrecision = false;
-#endif
-
-    if (!Program::linkValidateVariablesBase(infoLog, uniformName, vertexUniform, fragmentUniform,
-                                            validatePrecision))
-    {
-        return false;
-    }
-
-    // GLSL ES Spec 3.10.4, section 4.4.5.
-    if (vertexUniform.binding != -1 && fragmentUniform.binding != -1 &&
-        vertexUniform.binding != fragmentUniform.binding)
-    {
-        infoLog << "Binding layout qualifiers for " << uniformName
-                << " differ between vertex and fragment shaders.";
-        return false;
-    }
-
-    // GLSL ES Spec 3.10.4, section 9.2.1.
-    if (vertexUniform.location != -1 && fragmentUniform.location != -1 &&
-        vertexUniform.location != fragmentUniform.location)
-    {
-        infoLog << "Location layout qualifiers for " << uniformName
-                << " differ between vertex and fragment shaders.";
-        return false;
-    }
-    if (vertexUniform.offset != fragmentUniform.offset)
-    {
-        infoLog << "Offset layout qualifiers for " << uniformName
-                << " differ between vertex and fragment shaders.";
-        return false;
-    }
-
-    return true;
-}
-
-bool UniformLinker::indexUniforms(InfoLog &infoLog,
-                                  const Program::Bindings &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))
-    {
-        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();
-
-    // Gather uniforms that have their location pre-set and uniforms that don't yet have a location.
-    std::vector<VariableLocation> unlocatedUniforms;
-    std::map<GLuint, VariableLocation> preLocatedUniforms;
-
-    for (size_t uniformIndex = 0; uniformIndex < mUniforms.size(); uniformIndex++)
-    {
-        const LinkedUniform &uniform = mUniforms[uniformIndex];
-
-        if (uniform.isBuiltIn())
-        {
-            continue;
-        }
-
-        int preSetLocation = uniformLocationBindings.getBinding(uniform.name);
-        int shaderLocation = uniform.location;
-
-        if (shaderLocation != -1)
-        {
-            preSetLocation = shaderLocation;
-        }
-
-        for (unsigned int arrayIndex = 0; arrayIndex < uniform.elementCount(); arrayIndex++)
-        {
-            VariableLocation location(arrayIndex, static_cast<unsigned int>(uniformIndex));
-
-            if ((arrayIndex == 0 && preSetLocation != -1) || shaderLocation != -1)
-            {
-                int elementLocation                 = preSetLocation + arrayIndex;
-                preLocatedUniforms[elementLocation] = location;
-            }
-            else
-            {
-                unlocatedUniforms.push_back(location);
-            }
-        }
-    }
-
-    // Make enough space for all uniforms, with pre-set locations or not.
-    mUniformLocations.resize(
-        std::max(unlocatedUniforms.size() + preLocatedUniforms.size() + ignoredLocations.size(),
-                 static_cast<size_t>(maxUniformLocation + 1)));
-
-    // Assign uniforms with pre-set locations
-    for (const auto &uniform : preLocatedUniforms)
-    {
-        mUniformLocations[uniform.first] = uniform.second;
-    }
-
-    // Assign ignored uniforms
-    for (const auto &ignoredLocation : ignoredLocations)
-    {
-        mUniformLocations[ignoredLocation].markIgnored();
-    }
-
-    // Automatically assign locations for the rest of the uniforms
-    size_t nextUniformLocation = 0;
-    for (const auto &unlocatedUniform : unlocatedUniforms)
-    {
-        while (mUniformLocations[nextUniformLocation].used() ||
-               mUniformLocations[nextUniformLocation].ignored)
-        {
-            nextUniformLocation++;
-        }
-
-        ASSERT(nextUniformLocation < mUniformLocations.size());
-        mUniformLocations[nextUniformLocation] = unlocatedUniform;
-        nextUniformLocation++;
-    }
-
-    return true;
-}
-
-bool UniformLinker::gatherUniformLocationsAndCheckConflicts(
-    InfoLog &infoLog,
-    const Program::Bindings &uniformLocationBindings,
-    std::set<GLuint> *reservedLocations,
-    std::set<GLuint> *ignoredLocations,
-    int *maxUniformLocation)
-{
-    for (const LinkedUniform &uniform : mUniforms)
-    {
-        if (uniform.isBuiltIn())
-        {
-            continue;
-        }
-
-        int apiBoundLocation = uniformLocationBindings.getBinding(uniform.name);
-        int shaderLocation   = uniform.location;
-
-        if (shaderLocation != -1)
-        {
-            for (unsigned int arrayIndex = 0; arrayIndex < uniform.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())
-                {
-                    infoLog << "Multiple uniforms bound to location " << elementLocation << ".";
-                    return false;
-                }
-                reservedLocations->insert(elementLocation);
-                if (!uniform.staticUse)
-                {
-                    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())
-            {
-                infoLog << "Multiple uniforms bound to location " << apiBoundLocation << ".";
-                return false;
-            }
-            reservedLocations->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())
-        {
-            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)
-        {
-            ++uniformIter;
-        }
-        else
-        {
-            uniformIter = mUniforms.erase(uniformIter);
-        }
-    }
-}
-
-bool UniformLinker::flattenUniformsAndCheckCapsForShader(
-    const Context *context,
-    Shader *shader,
-    GLuint maxUniformComponents,
-    GLuint maxTextureImageUnits,
-    GLuint maxImageUnits,
-    GLuint maxAtomicCounters,
-    const std::string &componentsErrorMessage,
-    const std::string &samplerErrorMessage,
-    const std::string &imageErrorMessage,
-    const std::string &atomicCounterErrorMessage,
-    std::vector<LinkedUniform> &samplerUniforms,
-    std::vector<LinkedUniform> &imageUniforms,
-    std::vector<LinkedUniform> &atomicCounterUniforms,
-    InfoLog &infoLog)
-{
-    ShaderUniformCount shaderUniformCount;
-    for (const sh::Uniform &uniform : shader->getUniforms(context))
-    {
-        shaderUniformCount +=
-            flattenUniform(uniform, &samplerUniforms, &imageUniforms, &atomicCounterUniforms);
-    }
-
-    if (shaderUniformCount.vectorCount > maxUniformComponents)
-    {
-        infoLog << componentsErrorMessage << maxUniformComponents << ").";
-        return false;
-    }
-
-    if (shaderUniformCount.samplerCount > maxTextureImageUnits)
-    {
-        infoLog << samplerErrorMessage << maxTextureImageUnits << ").";
-        return false;
-    }
-
-    if (shaderUniformCount.imageCount > maxImageUnits)
-    {
-        infoLog << imageErrorMessage << maxImageUnits << ").";
-        return false;
-    }
-
-    if (shaderUniformCount.atomicCounterCount > maxAtomicCounters)
-    {
-        infoLog << atomicCounterErrorMessage << maxAtomicCounters << ").";
-        return false;
-    }
-
-    return true;
-}
-
-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())
-    {
-        Shader *computeShader = mState.getAttachedComputeShader();
-
-        // 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 (",
-                "Compute shader image count exceeds MAX_COMPUTE_IMAGE_UNIFORMS (",
-                "Compute shader atomic counter count exceeds MAX_COMPUTE_ATOMIC_COUNTERS (",
-                samplerUniforms, imageUniforms, atomicCounterUniforms, infoLog))
-        {
-            return false;
-        }
-    }
-    else
-    {
-        Shader *vertexShader = mState.getAttachedVertexShader();
-
-        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();
-
-        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;
-        }
-    }
-
-    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)
-{
-    int location                          = uniform.location;
-    ShaderUniformCount shaderUniformCount = flattenUniformImpl(
-        uniform, uniform.name, uniform.mappedName, samplerUniforms, imageUniforms,
-        atomicCounterUniforms, uniform.staticUse, uniform.binding, uniform.offset, &location);
-    if (uniform.staticUse)
-    {
-        return shaderUniformCount;
-    }
-    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,
-    bool markStaticUse,
-    int binding,
-    int offset,
-    int *location)
-{
-    ASSERT(location);
-    ShaderUniformCount shaderUniformCount;
-
-    if (uniform.isStruct())
-    {
-        for (unsigned int elementIndex = 0; elementIndex < uniform.elementCount(); elementIndex++)
-        {
-            const std::string &elementString = (uniform.isArray() ? ArrayString(elementIndex) : "");
-
-            for (size_t fieldIndex = 0; fieldIndex < uniform.fields.size(); fieldIndex++)
-            {
-                const sh::ShaderVariable &field  = uniform.fields[fieldIndex];
-                const std::string &fieldFullName = (fullName + elementString + "." + field.name);
-                const std::string &fieldFullMappedName =
-                    (fullMappedName + elementString + "." + field.mappedName);
-
-                shaderUniformCount += flattenUniformImpl(
-                    field, fieldFullName, fieldFullMappedName, samplerUniforms, imageUniforms,
-                    atomicCounterUniforms, markStaticUse, -1, -1, location);
-            }
-        }
-
-        return shaderUniformCount;
-    }
-
-    // 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)
-    {
-        uniformList = samplerUniforms;
-    }
-    else if (isImage)
-    {
-        uniformList = imageUniforms;
-    }
-    else if (isAtomicCounter)
-    {
-        uniformList = atomicCounterUniforms;
-    }
-    LinkedUniform *existingUniform = FindUniform(*uniformList, fullName);
-    if (existingUniform)
-    {
-        if (binding != -1)
-        {
-            existingUniform->binding = binding;
-        }
-        if (offset != -1)
-        {
-            existingUniform->offset = offset;
-        }
-        if (*location != -1)
-        {
-            existingUniform->location = *location;
-        }
-        if (markStaticUse)
-        {
-            existingUniform->staticUse = true;
-        }
-    }
-    else
-    {
-        LinkedUniform linkedUniform(uniform.type, uniform.precision, fullName, uniform.arraySize,
-                                    binding, -1, *location, -1,
-                                    sh::BlockMemberInfo::getDefaultBlockInfo());
-        linkedUniform.mappedName = fullMappedName;
-        linkedUniform.staticUse = markStaticUse;
-
-        uniformList->push_back(linkedUniform);
-    }
-
-    unsigned int elementCount = uniform.elementCount();
-
-    // Samplers and images aren't "real" uniforms, so they don't count towards register usage.
-    // Likewise, don't count "real" uniforms towards opaque count.
-    shaderUniformCount.vectorCount =
-        (IsOpaqueType(uniform.type) ? 0 : (VariableRegisterCount(uniform.type) * elementCount));
-    shaderUniformCount.samplerCount = (isSampler ? elementCount : 0);
-    shaderUniformCount.imageCount   = (isImage ? elementCount : 0);
-    shaderUniformCount.atomicCounterCount = (isAtomicCounter ? elementCount : 0);
-
-    if (*location != -1)
-    {
-        *location += elementCount;
-    }
-
-    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)
-        {
-            atomicCounterCount += uniform.elementCount();
-            if (atomicCounterCount > caps.maxCombinedAtomicCounters)
-            {
-                infoLog << "atomic counter count exceeds MAX_COMBINED_ATOMIC_COUNTERS"
-                        << caps.maxCombinedAtomicCounters << ").";
-                return false;
-            }
-        }
-    }
-    return true;
-}
-
-}  // namespace gl
deleted file mode 100644
--- a/gfx/angle/src/libANGLE/UniformLinker.h
+++ /dev/null
@@ -1,114 +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.
-//
-
-// UniformLinker.h: implements link-time checks for default block uniforms, and generates 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 "libANGLE/Program.h"
-#include "libANGLE/Uniform.h"
-
-namespace gl
-{
-
-class UniformLinker
-{
-  public:
-    UniformLinker(const ProgramState &state);
-
-    bool link(const Context *context,
-              InfoLog &infoLog,
-              const Program::Bindings &uniformLocationBindings);
-
-    void getResults(std::vector<LinkedUniform> *uniforms,
-                    std::vector<VariableLocation> *uniformLocations);
-
-  private:
-    struct ShaderUniformCount
-    {
-        ShaderUniformCount() : vectorCount(0), samplerCount(0), imageCount(0), atomicCounterCount(0)
-        {
-        }
-        ShaderUniformCount(const ShaderUniformCount &other) = default;
-        ShaderUniformCount &operator=(const ShaderUniformCount &other) = default;
-
-        ShaderUniformCount &operator+=(const ShaderUniformCount &other)
-        {
-            vectorCount += other.vectorCount;
-            samplerCount += other.samplerCount;
-            imageCount += other.imageCount;
-            atomicCounterCount += other.atomicCounterCount;
-            return *this;
-        }
-
-        unsigned int vectorCount;
-        unsigned int samplerCount;
-        unsigned int imageCount;
-        unsigned int atomicCounterCount;
-    };
-
-    bool validateVertexAndFragmentUniforms(const Context *context, InfoLog &infoLog) const;
-
-    static bool linkValidateUniforms(InfoLog &infoLog,
-                                     const std::string &uniformName,
-                                     const sh::Uniform &vertexUniform,
-                                     const sh::Uniform &fragmentUniform);
-
-    bool flattenUniformsAndCheckCapsForShader(const Context *context,
-                                              Shader *shader,
-                                              GLuint maxUniformComponents,
-                                              GLuint maxTextureImageUnits,
-                                              GLuint maxImageUnits,
-                                              GLuint maxAtomicCounters,
-                                              const std::string &componentsErrorMessage,
-                                              const std::string &samplerErrorMessage,
-                                              const std::string &imageErrorMessage,
-                                              const std::string &atomicCounterErrorMessage,
-                                              std::vector<LinkedUniform> &samplerUniforms,
-                                              std::vector<LinkedUniform> &imageUniforms,
-                                              std::vector<LinkedUniform> &atomicCounterUniforms,
-                                              InfoLog &infoLog);
-
-    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);
-
-    // markStaticUse is given as a separate parameter because it is 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,
-                                          bool markStaticUse,
-                                          int binding,
-                                          int offset,
-                                          int *location);
-
-    bool indexUniforms(InfoLog &infoLog, const Program::Bindings &uniformLocationBindings);
-    bool gatherUniformLocationsAndCheckConflicts(InfoLog &infoLog,
-                                                 const Program::Bindings &uniformLocationBindings,
-                                                 std::set<GLuint> *reservedLocations,
-                                                 std::set<GLuint> *ignoredLocations,
-                                                 int *maxUniformLocation);
-    void pruneUnusedUniforms();
-
-    const ProgramState &mState;
-    std::vector<LinkedUniform> mUniforms;
-    std::vector<VariableLocation> mUniformLocations;
-};
-
-}  // namespace gl
-
-#endif  // LIBANGLE_UNIFORMLINKER_H_
--- a/gfx/angle/src/libANGLE/VaryingPacking.cpp
+++ b/gfx/angle/src/libANGLE/VaryingPacking.cpp
@@ -8,26 +8,66 @@
 //   to the spec, or using custom packing algorithms. We also keep a register
 //   allocation list for the D3D renderer.
 //
 
 #include "libANGLE/VaryingPacking.h"
 
 #include "common/utilities.h"
 #include "libANGLE/Program.h"
+#include "libANGLE/Shader.h"
 
 namespace gl
 {
 
+namespace
+{
+
+// true if varying x has a higher priority in packing than y
+bool ComparePackedVarying(const PackedVarying &x, const PackedVarying &y)
+{
+    // If the PackedVarying 'x' or 'y' to be compared is an array element, this clones an equivalent
+    // non-array shader variable 'vx' or 'vy' for actual comparison instead.
+    sh::ShaderVariable vx, vy;
+    const sh::ShaderVariable *px, *py;
+    if (x.isArrayElement())
+    {
+        vx           = *x.varying;
+        vx.arraySizes.clear();
+        px           = &vx;
+    }
+    else
+    {
+        px = x.varying;
+    }
+
+    if (y.isArrayElement())
+    {
+        vy           = *y.varying;
+        vy.arraySizes.clear();
+        py           = &vy;
+    }
+    else
+    {
+        py = y.varying;
+    }
+
+    return gl::CompareShaderVar(*px, *py);
+}
+
+}  // anonymous namespace
+
 // Implementation of VaryingPacking
 VaryingPacking::VaryingPacking(GLuint maxVaryingVectors, PackMode packMode)
     : mRegisterMap(maxVaryingVectors), mPackMode(packMode)
 {
 }
 
+VaryingPacking::~VaryingPacking() = default;
+
 // Packs varyings into generic varying registers, using the algorithm from
 // See [OpenGL ES Shading Language 1.00 rev. 17] appendix A section 7 page 111
 // Also [OpenGL ES Shading Language 3.00 rev. 4] Section 11 page 119
 // Returns false if unsuccessful.
 bool VaryingPacking::packVarying(const PackedVarying &packedVarying)
 {
     const auto &varying = *packedVarying.varying;
 
@@ -43,17 +83,20 @@ bool VaryingPacking::packVarying(const P
     // "Variables of type mat2 occupies 2 complete rows."
     // For non-WebGL contexts, we allow mat2 to occupy only two columns per row.
     if (mPackMode == PackMode::WEBGL_STRICT && varying.type == GL_FLOAT_MAT2)
     {
         varyingColumns = 4;
     }
 
     // "Arrays of size N are assumed to take N times the size of the base type"
-    varyingRows *= (packedVarying.isArrayElement() ? 1 : varying.elementCount());
+    // GLSL ES 3.10 section 4.3.6: Output variables cannot be arrays of arrays or arrays of
+    // structures, so we may use getBasicTypeElementCount().
+    const unsigned int elementCount = varying.getBasicTypeElementCount();
+    varyingRows *= (packedVarying.isArrayElement() ? 1 : elementCount);
 
     unsigned int maxVaryingVectors = static_cast<unsigned int>(mRegisterMap.size());
 
     // Fail if we are packing a single over-large varying.
     if (varyingRows > maxVaryingVectors)
     {
         return false;
     }
@@ -195,17 +238,20 @@ void VaryingPacking::insert(unsigned int
     GLenum transposedType = gl::TransposeMatrixType(varying.type);
     varyingRows           = gl::VariableRowCount(transposedType);
     varyingColumns        = gl::VariableColumnCount(transposedType);
 
     PackedVaryingRegister registerInfo;
     registerInfo.packedVarying  = &packedVarying;
     registerInfo.registerColumn = registerColumn;
 
-    for (unsigned int arrayElement = 0; arrayElement < varying.elementCount(); ++arrayElement)
+    // GLSL ES 3.10 section 4.3.6: Output variables cannot be arrays of arrays or arrays of
+    // structures, so we may use getBasicTypeElementCount().
+    const unsigned int arrayElementCount = varying.getBasicTypeElementCount();
+    for (unsigned int arrayElement = 0; arrayElement < arrayElementCount; ++arrayElement)
     {
         if (packedVarying.isArrayElement() && arrayElement != packedVarying.arrayIndex)
         {
             continue;
         }
         for (unsigned int varyingRow = 0; varyingRow < varyingRows; ++varyingRow)
         {
             registerInfo.registerRow     = registerRow + (arrayElement * varyingRows) + varyingRow;
@@ -221,85 +267,127 @@ void VaryingPacking::insert(unsigned int
             for (unsigned int columnIndex = 0; columnIndex < varyingColumns; ++columnIndex)
             {
                 mRegisterMap[registerInfo.registerRow][registerColumn + columnIndex] = true;
             }
         }
     }
 }
 
+bool VaryingPacking::collectAndPackUserVaryings(gl::InfoLog &infoLog,
+                                                const ProgramMergedVaryings &mergedVaryings,
+                                                const std::vector<std::string> &tfVaryings)
+{
+    std::set<std::string> uniqueFullNames;
+    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.
+        if (((input && output) || (output && output->isBuiltIn())) && output->staticUse)
+        {
+            // Will get the vertex shader interpolation by default.
+            auto interpolation = ref.second.get()->interpolation;
+
+            // Note that we lose the vertex shader static use information here. The data for the
+            // variable is taken from the fragment shader.
+            if (output->isStruct())
+            {
+                ASSERT(!output->isArray());
+                for (const auto &field : output->fields)
+                {
+                    ASSERT(!field.isStruct() && !field.isArray());
+                    mPackedVaryings.push_back(PackedVarying(field, interpolation, output->name));
+                    uniqueFullNames.insert(mPackedVaryings.back().fullName());
+                }
+            }
+            else
+            {
+                mPackedVaryings.push_back(PackedVarying(*output, interpolation));
+                uniqueFullNames.insert(mPackedVaryings.back().fullName());
+            }
+            continue;
+        }
+
+        // Keep Transform FB varyings in the merged list always.
+        if (!input)
+        {
+            continue;
+        }
+
+        for (const std::string &tfVarying : tfVaryings)
+        {
+            std::vector<unsigned int> subscripts;
+            std::string baseName = ParseResourceName(tfVarying, &subscripts);
+            size_t subscript     = GL_INVALID_INDEX;
+            if (!subscripts.empty())
+            {
+                subscript = subscripts.back();
+            }
+            // Already packed for fragment shader.
+            if (uniqueFullNames.count(tfVarying) > 0 || uniqueFullNames.count(baseName) > 0)
+            {
+                continue;
+            }
+            if (input->isStruct())
+            {
+                const sh::ShaderVariable *field = FindShaderVarField(*input, tfVarying);
+                if (field != nullptr)
+                {
+                    ASSERT(!field->isStruct() && !field->isArray());
+                    mPackedVaryings.emplace_back(*field, input->interpolation, input->name);
+                    mPackedVaryings.back().vertexOnly = true;
+                    mPackedVaryings.back().arrayIndex = GL_INVALID_INDEX;
+                    uniqueFullNames.insert(tfVarying);
+                }
+            }
+            // Array as a whole and array element conflict has already been checked in
+            // linkValidateTransformFeedback.
+            else if (baseName == input->name)
+            {
+                // only pack varyings that are not builtins.
+                if (tfVarying.compare(0, 3, "gl_") != 0)
+                {
+                    mPackedVaryings.emplace_back(*input, input->interpolation);
+                    mPackedVaryings.back().vertexOnly = true;
+                    mPackedVaryings.back().arrayIndex = static_cast<GLuint>(subscript);
+                    uniqueFullNames.insert(tfVarying);
+                }
+                // Continue to match next array element for 'input' if the current match is array
+                // element.
+                if (subscript == GL_INVALID_INDEX)
+                {
+                    break;
+                }
+            }
+        }
+    }
+
+    std::sort(mPackedVaryings.begin(), mPackedVaryings.end(), ComparePackedVarying);
+
+    return packUserVaryings(infoLog, mPackedVaryings, tfVaryings);
+}
+
 // See comment on packVarying.
 bool VaryingPacking::packUserVaryings(gl::InfoLog &infoLog,
                                       const std::vector<PackedVarying> &packedVaryings,
                                       const std::vector<std::string> &transformFeedbackVaryings)
 {
-    std::set<std::string> uniqueVaryingNames;
 
     // "Variables are packed into the registers one at a time so that they each occupy a contiguous
     // subrectangle. No splitting of variables is permitted."
     for (const PackedVarying &packedVarying : packedVaryings)
     {
-        const auto &varying = *packedVarying.varying;
-
-        // Do not assign registers to built-in or unreferenced varyings
-        if (!varying.staticUse && !packedVarying.isStructField())
-        {
-            continue;
-        }
-
-        ASSERT(!varying.isStruct());
-        ASSERT(uniqueVaryingNames.count(packedVarying.nameWithArrayIndex()) == 0);
-
-        if (packVarying(packedVarying))
-        {
-            uniqueVaryingNames.insert(packedVarying.nameWithArrayIndex());
-        }
-        else
+        if (!packVarying(packedVarying))
         {
-            infoLog << "Could not pack varying " << packedVarying.nameWithArrayIndex();
-            return false;
-        }
-    }
-
-    // Make sure transform feedback varyings aren't optimized out.
-    for (const std::string &transformFeedbackVaryingName : transformFeedbackVaryings)
-    {
-        size_t subscript              = GL_INVALID_INDEX;
-        std::string tfVaryingBaseName = ParseResourceName(transformFeedbackVaryingName, &subscript);
-
-        bool found = (uniqueVaryingNames.count(transformFeedbackVaryingName) > 0 ||
-                      uniqueVaryingNames.count(tfVaryingBaseName) > 0);
-
-        if (!found)
-        {
-            for (const PackedVarying &packedVarying : packedVaryings)
-            {
-                const auto &varying = *packedVarying.varying;
-                if (tfVaryingBaseName == varying.name)
-                {
-                    // only pack varyings that are not builtins.
-                    if (transformFeedbackVaryingName.compare(0, 3, "gl_") != 0)
-                    {
-                        if (!packVarying(packedVarying))
-                        {
-                            infoLog << "Could not pack varying " << varying.name;
-                            return false;
-                        }
-                        uniqueVaryingNames.insert(packedVarying.nameWithArrayIndex());
-                    }
-                    found = true;
-                    break;
-                }
-            }
-        }
-
-        if (!found)
-        {
-            infoLog << "Transform feedback varying " << transformFeedbackVaryingName
-                    << " does not exist in the vertex shader.";
+            infoLog << "Could not pack varying " << packedVarying.fullName();
             return false;
         }
     }
 
     // Sort the packed register list
     std::sort(mRegisterList.begin(), mRegisterList.end());
 
     // Assign semantic indices
--- a/gfx/angle/src/libANGLE/VaryingPacking.h
+++ b/gfx/angle/src/libANGLE/VaryingPacking.h
@@ -12,19 +12,24 @@
 #ifndef LIBANGLE_VARYINGPACKING_H_
 #define LIBANGLE_VARYINGPACKING_H_
 
 #include <GLSLANG/ShaderVars.h>
 
 #include "angle_gl.h"
 #include "common/angleutils.h"
 
+#include <map>
+
 namespace gl
 {
 class InfoLog;
+struct ProgramVaryingRef;
+
+using ProgramMergedVaryings = std::map<std::string, ProgramVaryingRef>;
 
 struct PackedVarying
 {
     PackedVarying(const sh::ShaderVariable &varyingIn, sh::InterpolationType interpolationIn)
         : PackedVarying(varyingIn, interpolationIn, "")
     {
     }
     PackedVarying(const sh::ShaderVariable &varyingIn,
@@ -37,19 +42,24 @@ struct PackedVarying
           arrayIndex(GL_INVALID_INDEX)
     {
     }
 
     bool isStructField() const { return !parentStructName.empty(); }
 
     bool isArrayElement() const { return arrayIndex != GL_INVALID_INDEX; }
 
-    std::string nameWithArrayIndex() const
+    std::string fullName() const
     {
         std::stringstream fullNameStr;
+        if (isStructField())
+        {
+            fullNameStr << parentStructName << ".";
+        }
+
         fullNameStr << varying->name;
         if (arrayIndex != GL_INVALID_INDEX)
         {
             fullNameStr << "[" << arrayIndex << "]";
         }
         return fullNameStr.str();
     }
 
@@ -87,17 +97,27 @@ struct PackedVaryingRegister final
     }
 
     unsigned int sortOrder() const
     {
         // TODO(jmadill): Handle interpolation types
         return registerRow * 4 + registerColumn;
     }
 
-    bool isStructField() const { return !structFieldName.empty(); }
+    std::string tfVaryingName() const
+    {
+        if (packedVarying->isArrayElement() || packedVarying->isStructField())
+        {
+            return packedVarying->fullName();
+        }
+        else
+        {
+            return packedVarying->varying->name;
+        }
+    }
 
     // Index to the array of varyings.
     const PackedVarying *packedVarying;
 
     // The array element of the packed varying.
     unsigned int varyingArrayIndex;
 
     // The row of the array element of the packed varying.
@@ -106,39 +126,41 @@ struct PackedVaryingRegister final
     // The register row to which we've assigned this packed varying.
     unsigned int registerRow;
 
     // The column of the register row into which we've packed this varying.
     unsigned int registerColumn;
 
     // Assigned after packing
     unsigned int semanticIndex;
-
-    // Struct member this varying corresponds to.
-    std::string structFieldName;
 };
 
 // Supported packing modes:
 enum class PackMode
 {
     // We treat mat2 arrays as taking two full rows.
     WEBGL_STRICT,
 
     // We allow mat2 to take a 2x2 chunk.
     ANGLE_RELAXED,
 };
 
 class VaryingPacking final : angle::NonCopyable
 {
   public:
     VaryingPacking(GLuint maxVaryingVectors, PackMode packMode);
+    ~VaryingPacking();
 
     bool packUserVaryings(gl::InfoLog &infoLog,
                           const std::vector<PackedVarying> &packedVaryings,
-                          const std::vector<std::string> &transformFeedbackVaryings);
+                          const std::vector<std::string> &tfVaryings);
+
+    bool collectAndPackUserVaryings(gl::InfoLog &infoLog,
+                                    const ProgramMergedVaryings &mergedVaryings,
+                                    const std::vector<std::string> &tfVaryings);
 
     struct Register
     {
         Register() { data[0] = data[1] = data[2] = data[3] = false; }
 
         bool &operator[](unsigned int index) { return data[index]; }
         bool operator[](unsigned int index) const { return data[index]; }
 
@@ -163,15 +185,16 @@ class VaryingPacking final : angle::NonC
                 unsigned int varyingRows,
                 unsigned int varyingColumns) const;
     void insert(unsigned int registerRow,
                 unsigned int registerColumn,
                 const PackedVarying &packedVarying);
 
     std::vector<Register> mRegisterMap;
     std::vector<PackedVaryingRegister> mRegisterList;
+    std::vector<PackedVarying> mPackedVaryings;
 
     PackMode mPackMode;
 };
 
 }  // namespace gl
 
 #endif  // LIBANGLE_VARYINGPACKING_H_
--- a/gfx/angle/src/libANGLE/VaryingPacking_unittest.cpp
+++ b/gfx/angle/src/libANGLE/VaryingPacking_unittest.cpp
@@ -2,21 +2,24 @@
 // Copyright 2016 The ANGLE Project Authors. All rights reserved.
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 //
 // VaryingPacking_unittest.cpp:
 //   Tests for ANGLE's internal varying packing algorithm.
 //
 
-#include "libANGLE/VaryingPacking.h"
-
 #include <gtest/gtest.h>
+// 'None' is defined as 'struct None {};' in
+// third_party/googletest/src/googletest/include/gtest/internal/gtest-type-util.h.
+// But 'None' is also define as a numberic constant 0L in <X11/X.h>.
+// So we need to include gtest first to avoid such conflict.
 
 #include "libANGLE/Program.h"
+#include "libANGLE/VaryingPacking.h"
 
 using namespace gl;
 
 namespace
 {
 
 class VaryingPackingTest : public ::testing::TestWithParam<GLuint>
 {
@@ -64,17 +67,20 @@ std::vector<sh::Varying> MakeVaryings(GL
         std::stringstream strstr;
         strstr << type << index;
 
         sh::Varying varying;
         varying.type          = type;
         varying.precision     = GL_MEDIUM_FLOAT;
         varying.name          = strstr.str();
         varying.mappedName    = strstr.str();
-        varying.arraySize     = static_cast<unsigned int>(arraySize);
+        if (arraySize > 0)
+        {
+            varying.arraySizes.push_back(static_cast<unsigned int>(arraySize));
+        }
         varying.staticUse     = true;
         varying.interpolation = sh::INTERPOLATION_FLAT;
         varying.isInvariant   = false;
 
         varyings.push_back(varying);
     }
 
     return varyings;
--- a/gfx/angle/src/libANGLE/Version.h
+++ b/gfx/angle/src/libANGLE/Version.h
@@ -4,28 +4,26 @@
 // found in the LICENSE file.
 //
 
 // Version.h: Encapsulation of a GL version.
 
 #ifndef LIBANGLE_VERSION_H_
 #define LIBANGLE_VERSION_H_
 
-#include <angle_gl.h>
-
 namespace gl
 {
 
 struct Version
 {
     constexpr Version();
-    constexpr Version(GLuint major, GLuint minor);
+    constexpr Version(unsigned int major, unsigned int minor);
 
-    GLuint major;
-    GLuint minor;
+    unsigned int major;
+    unsigned int minor;
 };
 
 bool operator==(const Version &a, const Version &b);
 bool operator!=(const Version &a, const Version &b);
 bool operator>=(const Version &a, const Version &b);
 bool operator<=(const Version &a, const Version &b);
 bool operator<(const Version &a, const Version &b);
 bool operator>(const Version &a, const Version &b);
--- a/gfx/angle/src/libANGLE/Version.inl
+++ b/gfx/angle/src/libANGLE/Version.inl
@@ -15,17 +15,17 @@ constexpr Version::Version()
     : Version(0, 0)
 {
 }
 
 // Avoid conflicts with linux system defines
 #undef major
 #undef minor
 
-constexpr Version::Version(GLuint major_, GLuint minor_)
+constexpr Version::Version(unsigned int major_, unsigned int minor_)
     : major(major_),
       minor(minor_)
 {
 }
 
 inline bool operator==(const Version &a, const Version &b)
 {
     return std::tie(a.major, a.minor) == std::tie(b.major, b.minor);
@@ -51,9 +51,9 @@ inline bool operator<(const Version &a, 
     return std::tie(a.major, a.minor) < std::tie(b.major, b.minor);
 }
 
 inline bool operator>(const Version &a, const Version &b)
 {
     return std::tie(a.major, a.minor) > std::tie(b.major, b.minor);
 }
 
-}
+}  // namespace gl
--- a/gfx/angle/src/libANGLE/VertexArray.cpp
+++ b/gfx/angle/src/libANGLE/VertexArray.cpp
@@ -11,17 +11,17 @@
 #include "libANGLE/Context.h"
 #include "libANGLE/renderer/GLImplFactory.h"
 #include "libANGLE/renderer/VertexArrayImpl.h"
 
 namespace gl
 {
 
 VertexArrayState::VertexArrayState(size_t maxAttribs, size_t maxAttribBindings)
-    : mLabel(), mVertexBindings(maxAttribBindings), mMaxEnabledAttribute(0)
+    : mLabel(), mVertexBindings(maxAttribBindings)
 {
     ASSERT(maxAttribs <= maxAttribBindings);
 
     for (size_t i = 0; i < maxAttribs; i++)
     {
         mVertexAttributes.emplace_back(static_cast<GLuint>(i));
     }
 }
@@ -170,16 +170,18 @@ void VertexArray::setVertexAttribFormatI
 
     VertexAttribute *attrib = &mState.mVertexAttributes[attribIndex];
 
     attrib->size           = size;
     attrib->type           = type;
     attrib->normalized     = normalized;
     attrib->pureInteger    = pureInteger;
     attrib->relativeOffset = relativeOffset;
+    mState.mVertexAttributesTypeMask.setIndex(GetVertexAttributeBaseType(*attrib), attribIndex);
+    mState.mEnabledAttributesMask.set(attribIndex);
 }
 
 void VertexArray::setVertexAttribFormat(size_t attribIndex,
                                         GLint size,
                                         GLenum type,
                                         bool normalized,
                                         bool pureInteger,
                                         GLuint relativeOffset)
@@ -197,32 +199,23 @@ void VertexArray::setVertexAttribDivisor
     setVertexBindingDivisor(attribIndex, divisor);
 }
 
 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);
 
     // Update state cache
-    if (enabledState)
-    {
-        mState.mMaxEnabledAttribute = std::max(attribIndex + 1, mState.mMaxEnabledAttribute);
-    }
-    else if (mState.mMaxEnabledAttribute == attribIndex + 1)
-    {
-        while (mState.mMaxEnabledAttribute > 0 &&
-               !mState.mVertexAttributes[mState.mMaxEnabledAttribute - 1].enabled)
-        {
-            --mState.mMaxEnabledAttribute;
-        }
-    }
+    mState.mEnabledAttributesMask.set(attribIndex, enabledState);
 }
 
 void VertexArray::setVertexAttribPointer(const Context *context,
                                          size_t attribIndex,
                                          gl::Buffer *boundBuffer,
                                          GLint size,
                                          GLenum type,
                                          bool normalized,
--- a/gfx/angle/src/libANGLE/VertexArray.h
+++ b/gfx/angle/src/libANGLE/VertexArray.h
@@ -37,17 +37,17 @@ class VertexArrayState final : angle::No
     VertexArrayState(size_t maxAttribs, size_t maxBindings);
     ~VertexArrayState();
 
     const std::string &getLabel() const { return mLabel; }
 
     const BindingPointer<Buffer> &getElementArrayBuffer() const { return mElementArrayBuffer; }
     size_t getMaxAttribs() const { return mVertexAttributes.size(); }
     size_t getMaxBindings() const { return mVertexBindings.size(); }
-    size_t getMaxEnabledAttribute() const { return mMaxEnabledAttribute; }
+    const AttributesMask &getEnabledAttributesMask() const { return mEnabledAttributesMask; }
     const std::vector<VertexAttribute> &getVertexAttributes() const { return mVertexAttributes; }
     const VertexAttribute &getVertexAttribute(size_t attribIndex) const
     {
         return mVertexAttributes[attribIndex];
     }
     const std::vector<VertexBinding> &getVertexBindings() const { return mVertexBindings; }
     const VertexBinding &getVertexBinding(size_t bindingIndex) const
     {
@@ -63,17 +63,18 @@ class VertexArrayState final : angle::No
     }
 
   private:
     friend class VertexArray;
     std::string mLabel;
     std::vector<VertexAttribute> mVertexAttributes;
     BindingPointer<Buffer> mElementArrayBuffer;
     std::vector<VertexBinding> mVertexBindings;
-    size_t mMaxEnabledAttribute;
+    AttributesMask mEnabledAttributesMask;
+    ComponentTypeMask mVertexAttributesTypeMask;
 };
 
 class VertexArray final : public LabeledObject
 {
   public:
     VertexArray(rx::GLImplFactory *factory, GLuint id, size_t maxAttribs, size_t maxAttribBindings);
 
     void onDestroy(const Context *context);
@@ -142,17 +143,20 @@ class VertexArray final : public Labeled
     }
     const std::vector<VertexBinding> &getVertexBindings() const
     {
         return mState.getVertexBindings();
     }
 
     rx::VertexArrayImpl *getImplementation() const { return mVertexArray; }
 
-    size_t getMaxEnabledAttribute() const { return mState.getMaxEnabledAttribute(); }
+    const AttributesMask &getEnabledAttributesMask() const
+    {
+        return mState.getEnabledAttributesMask();
+    }
 
     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,
@@ -184,18 +188,21 @@ class VertexArray final : public Labeled
 
     using DirtyBits = angle::BitSet<DIRTY_BIT_MAX>;
 
     static size_t GetVertexIndexFromDirtyBit(size_t dirtyBit);
 
     void syncState(const Context *context);
     bool hasAnyDirtyBit() const { return mDirtyBits.any(); }
 
+    ComponentTypeMask getAttributesTypeMask() const { return mState.mVertexAttributesTypeMask; }
+    AttributesMask getAttributesMask() const { return mState.mEnabledAttributesMask; }
+
   private:
-    ~VertexArray();
+    ~VertexArray() override;
 
     GLuint mId;
 
     VertexArrayState mState;
     DirtyBits mDirtyBits;
 
     rx::VertexArrayImpl *mVertexArray;
 };
--- a/gfx/angle/src/libANGLE/VertexAttribute.cpp
+++ b/gfx/angle/src/libANGLE/VertexAttribute.cpp
@@ -17,16 +17,20 @@ VertexBinding::VertexBinding() : mStride
 {
 }
 
 VertexBinding::VertexBinding(VertexBinding &&binding)
 {
     *this = std::move(binding);
 }
 
+VertexBinding::~VertexBinding()
+{
+}
+
 VertexBinding &VertexBinding::operator=(VertexBinding &&binding)
 {
     if (this != &binding)
     {
         mStride  = binding.mStride;
         mDivisor = binding.mDivisor;
         mOffset  = binding.mOffset;
         std::swap(binding.mBuffer, mBuffer);
--- a/gfx/angle/src/libANGLE/VertexAttribute.h
+++ b/gfx/angle/src/libANGLE/VertexAttribute.h
@@ -19,16 +19,17 @@ class VertexArray;
 // Implementation of Generic Vertex Attribute Bindings for ES3.1. The members are intentionally made
 // private in order to hide implementation details.
 //
 class VertexBinding final : angle::NonCopyable
 {
   public:
     VertexBinding();
     VertexBinding(VertexBinding &&binding);
+    ~VertexBinding();
     VertexBinding &operator=(VertexBinding &&binding);
 
     GLuint getStride() const { return mStride; }
     void setStride(GLuint strideIn) { mStride = strideIn; }
 
     GLuint getDivisor() const { return mDivisor; }
     void setDivisor(GLuint divisorIn) { mDivisor = divisorIn; }
 
@@ -47,17 +48,17 @@ class VertexBinding final : angle::NonCo
 };
 
 //
 // Implementation of Generic Vertex Attributes for ES3.1
 //
 struct VertexAttribute final : private angle::NonCopyable
 {
     explicit VertexAttribute(GLuint bindingIndex);
-    VertexAttribute(VertexAttribute &&attrib);
+    explicit VertexAttribute(VertexAttribute &&attrib);
     VertexAttribute &operator=(VertexAttribute &&attrib);
 
     bool enabled;  // For glEnable/DisableVertexAttribArray
     GLenum type;
     GLuint size;
     bool normalized;
     bool pureInteger;
 
--- a/gfx/angle/src/libANGLE/angletypes.cpp
+++ b/gfx/angle/src/libANGLE/angletypes.cpp
@@ -40,17 +40,17 @@ PrimitiveType GetPrimitiveType(GLenum dr
 }
 
 RasterizerState::RasterizerState()
 {
     memset(this, 0, sizeof(RasterizerState));
 
     rasterizerDiscard   = false;
     cullFace            = false;
-    cullMode            = GL_BACK;
+    cullMode            = CullFaceMode::Back;
     frontFace           = GL_CCW;
     polygonOffsetFill   = false;
     polygonOffsetFactor = 0.0f;
     polygonOffsetUnits  = 0.0f;
     pointDrawMode       = false;
     multiSample         = false;
 }
 
@@ -74,16 +74,21 @@ BlendState::BlendState()
     destBlendRGB          = GL_ZERO;
     destBlendAlpha        = GL_ZERO;
     blendEquationRGB      = GL_FUNC_ADD;
     blendEquationAlpha    = GL_FUNC_ADD;
     sampleAlphaToCoverage = false;
     dither                = true;
 }
 
+BlendState::BlendState(const BlendState &other)
+{
+    memcpy(this, &other, sizeof(BlendState));
+}
+
 bool operator==(const BlendState &a, const BlendState &b)
 {
     return memcmp(&a, &b, sizeof(BlendState)) == 0;
 }
 
 bool operator!=(const BlendState &a, const BlendState &b)
 {
     return !(a == b);
@@ -106,16 +111,21 @@ DepthStencilState::DepthStencilState()
     stencilFail              = GL_KEEP;
     stencilPassDepthFail     = GL_KEEP;
     stencilPassDepthPass     = GL_KEEP;
     stencilBackFail          = GL_KEEP;
     stencilBackPassDepthFail = GL_KEEP;
     stencilBackPassDepthPass = GL_KEEP;
 }
 
+DepthStencilState::DepthStencilState(const DepthStencilState &other)
+{
+    memcpy(this, &other, sizeof(DepthStencilState));
+}
+
 bool operator==(const DepthStencilState &a, const DepthStencilState &b)
 {
     return memcmp(&a, &b, sizeof(DepthStencilState)) == 0;
 }
 
 bool operator!=(const DepthStencilState &a, const DepthStencilState &b)
 {
     return !(a == b);
@@ -133,33 +143,44 @@ SamplerState::SamplerState()
     maxAnisotropy = 1.0f;
     minLod        = -1000.0f;
     maxLod        = 1000.0f;
     compareMode   = GL_NONE;
     compareFunc   = GL_LEQUAL;
     sRGBDecode    = GL_DECODE_EXT;
 }
 
+SamplerState::SamplerState(const SamplerState &other) = default;
+
 // static
 SamplerState SamplerState::CreateDefaultForTarget(GLenum target)
 {
     SamplerState state;
 
-    // According to OES_EGL_image_external: 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)
+    // 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)
     {
         state.minFilter = GL_LINEAR;
         state.wrapS     = GL_CLAMP_TO_EDGE;
         state.wrapT     = GL_CLAMP_TO_EDGE;
     }
 
     return state;
 }
 
+ImageUnit::ImageUnit()
+    : texture(), level(0), layered(false), layer(0), access(GL_READ_ONLY), format(GL_R32UI)
+{
+}
+
+ImageUnit::ImageUnit(const ImageUnit &other) = default;
+
+ImageUnit::~ImageUnit() = default;
+
 static void MinMax(int a, int b, int *minimum, int *maximum)
 {
     if (a < b)
     {
         *minimum = a;
         *maximum = b;
     }
     else
@@ -230,9 +251,95 @@ bool operator==(const Extents &lhs, cons
 {
     return lhs.width == rhs.width && lhs.height == rhs.height && lhs.depth == rhs.depth;
 }
 
 bool operator!=(const Extents &lhs, const Extents &rhs)
 {
     return !(lhs == rhs);
 }
+
+ComponentTypeMask::ComponentTypeMask()
+{
+    mTypeMask.reset();
+}
+
+ComponentTypeMask::ComponentTypeMask(const ComponentTypeMask &other) = default;
+
+ComponentTypeMask::~ComponentTypeMask() = default;
+
+void ComponentTypeMask::reset()
+{
+    mTypeMask.reset();
+}
+
+bool ComponentTypeMask::none()
+{
+    return mTypeMask.none();
+}
+
+void ComponentTypeMask::setIndex(GLenum type, size_t index)
+{
+    ASSERT(index <= MAX_COMPONENT_TYPE_MASK_INDEX);
+
+    mTypeMask &= ~(0x10001 << index);
+
+    uint32_t m = 0;
+    switch (type)
+    {
+        case GL_INT:
+            m = 0x00001;
+            break;
+        case GL_UNSIGNED_INT:
+            m = 0x10000;
+            break;
+        case GL_FLOAT:
+            m = 0x10001;
+            break;
+        case GL_NONE:
+            m = 0x00000;
+            break;
+        default:
+            UNREACHABLE();
+    }
+
+    mTypeMask |= m << index;
+}
+
+unsigned long ComponentTypeMask::to_ulong() const
+{
+    return mTypeMask.to_ulong();
+}
+
+void ComponentTypeMask::from_ulong(unsigned long mask)
+{
+    mTypeMask = 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,
+                  "Output/input masks should fit into 16 bits - 1 bit per draw buffer. The "
+                  "corresponding type masks should fit into 32 bits - 2 bits per draw buffer.");
+    static_assert(MAX_VERTEX_ATTRIBS <= MAX_COMPONENT_TYPE_MASK_INDEX,
+                  "Output/input masks should fit into 16 bits - 1 bit per attrib. The "
+                  "corresponding type masks should fit into 32 bits - 2 bits per attrib.");
+
+    // For performance reasons, draw buffer and attribute type validation is done using bit masks.
+    // We store two bits representing the type split, with the low bit in the lower 16 bits of the
+    // variable, and the high bit in the upper 16 bits of the variable. This is done so we can AND
+    // with the elswewhere used DrawBufferMask or AttributeMask.
+
+    // OR the masks with themselves, shifted 16 bits. This is to match our split type bits.
+    outputMask |= (outputMask << MAX_COMPONENT_TYPE_MASK_INDEX);
+    inputMask |= (inputMask << MAX_COMPONENT_TYPE_MASK_INDEX);
+
+    // 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);
+}
+
 }  // namespace gl
--- a/gfx/angle/src/libANGLE/angletypes.h
+++ b/gfx/angle/src/libANGLE/angletypes.h
@@ -7,21 +7,23 @@
 // 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/bitset_utils.h"
 #include "libANGLE/Constants.h"
 #include "libANGLE/Error.h"
+#include "libANGLE/PackedGLEnums.h"
 #include "libANGLE/RefCountObject.h"
 
 #include <stdint.h>
 
 #include <bitset>
+#include <map>
 #include <unordered_map>
 
 namespace gl
 {
 class Buffer;
 class Texture;
 
 enum PrimitiveType
@@ -33,21 +35,23 @@ enum PrimitiveType
     PRIMITIVE_TRIANGLES,
     PRIMITIVE_TRIANGLE_STRIP,
     PRIMITIVE_TRIANGLE_FAN,
     PRIMITIVE_TYPE_MAX,
 };
 
 PrimitiveType GetPrimitiveType(GLenum drawMode);
 
-enum SamplerType
+enum ShaderType
 {
-    SAMPLER_PIXEL,
-    SAMPLER_VERTEX,
-    SAMPLER_COMPUTE
+    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)
         : x(x_in), y(y_in), width(width_in), height(height_in)
     {
@@ -117,17 +121,17 @@ struct Box
 };
 
 struct RasterizerState final
 {
     // This will zero-initialize the struct, including padding.
     RasterizerState();
 
     bool cullFace;
-    GLenum cullMode;
+    CullFaceMode cullMode;
     GLenum frontFace;
 
     bool polygonOffsetFill;
     GLfloat polygonOffsetFactor;
     GLfloat polygonOffsetUnits;
 
     bool pointDrawMode;
     bool multiSample;
@@ -137,16 +141,17 @@ struct RasterizerState final
 
 bool operator==(const RasterizerState &a, const RasterizerState &b);
 bool operator!=(const RasterizerState &a, const RasterizerState &b);
 
 struct BlendState final
 {
     // This will zero-initialize the struct, including padding.
     BlendState();
+    BlendState(const BlendState &other);
 
     bool blend;
     GLenum sourceBlendRGB;
     GLenum destBlendRGB;
     GLenum sourceBlendAlpha;
     GLenum destBlendAlpha;
     GLenum blendEquationRGB;
     GLenum blendEquationAlpha;
@@ -163,16 +168,17 @@ struct BlendState final
 
 bool operator==(const BlendState &a, const BlendState &b);
 bool operator!=(const BlendState &a, const BlendState &b);
 
 struct DepthStencilState final
 {
     // This will zero-initialize the struct, including padding.
     DepthStencilState();
+    DepthStencilState(const DepthStencilState &other);
 
     bool depthTest;
     GLenum depthFunc;
     bool depthMask;
 
     bool stencilTest;
     GLenum stencilFunc;
     GLuint stencilMask;
@@ -191,16 +197,17 @@ struct DepthStencilState final
 bool operator==(const DepthStencilState &a, const DepthStencilState &b);
 bool operator!=(const DepthStencilState &a, const DepthStencilState &b);
 
 // 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);
 
     GLenum minFilter;
     GLenum magFilter;
 
     GLenum wrapS;
     GLenum wrapT;
@@ -239,99 +246,92 @@ struct DrawElementsIndirectCommand
     GLint baseVertex;
     GLuint baseInstance;
 };
 static_assert(sizeof(DrawElementsIndirectCommand) == 20,
               "Unexpected size of DrawElementsIndirectCommand");
 
 struct ImageUnit
 {
-    ImageUnit()
-        : texture(), level(0), layered(false), layer(0), access(GL_READ_ONLY), format(GL_R32UI)
-    {
-    }
+    ImageUnit();
+    ImageUnit(const ImageUnit &other);
+    ~ImageUnit();
 
     BindingPointer<Texture> texture;
     GLint level;
     GLboolean layered;
     GLint layer;
     GLenum access;
     GLenum format;
 };
 
-struct PixelStoreStateBase : private angle::NonCopyable
+struct PixelStoreStateBase
 {
-    BindingPointer<Buffer> pixelBuffer;
     GLint alignment   = 4;
     GLint rowLength   = 0;
     GLint skipRows    = 0;
     GLint skipPixels  = 0;
     GLint imageHeight = 0;
     GLint skipImages  = 0;
-
-  protected:
-    void copyFrom(const Context *context, const PixelStoreStateBase &other)
-    {
-        pixelBuffer.set(context, other.pixelBuffer.get());
-        alignment   = other.alignment;
-        rowLength   = other.rowLength;
-        skipRows    = other.skipRows;
-        skipPixels  = other.skipPixels;
-        imageHeight = other.imageHeight;
-        skipImages  = other.skipImages;
-    }
 };
 
 struct PixelUnpackState : PixelStoreStateBase
 {
-    PixelUnpackState() {}
-
-    PixelUnpackState(GLint alignmentIn, GLint rowLengthIn)
-    {
-        alignment = alignmentIn;
-        rowLength = rowLengthIn;
-    }
-
-    void copyFrom(const Context *context, const PixelUnpackState &other)
-    {
-        PixelStoreStateBase::copyFrom(context, other);
-    }
 };
 
 struct PixelPackState : PixelStoreStateBase
 {
-    PixelPackState() {}
-
-    PixelPackState(GLint alignmentIn, bool reverseRowOrderIn)
-        : reverseRowOrder(reverseRowOrderIn)
-    {
-        alignment = alignmentIn;
-    }
-
-    void copyFrom(const Context *context, const PixelPackState &other)
-    {
-        PixelStoreStateBase::copyFrom(context, other);
-        reverseRowOrder = other.reverseRowOrder;
-    }
-
     bool reverseRowOrder = false;
 };
 
 // Used in Program and VertexArray.
 using AttributesMask = angle::BitSet<MAX_VERTEX_ATTRIBS>;
 
 // Used in Program
 using UniformBlockBindingMask = angle::BitSet<IMPLEMENTATION_MAX_COMBINED_SHADER_UNIFORM_BUFFERS>;
 
-// Used in Framebuffer
+// Used in Framebuffer / Program
 using DrawBufferMask = angle::BitSet<IMPLEMENTATION_MAX_DRAW_BUFFERS>;
 
+constexpr size_t MAX_COMPONENT_TYPE_MASK_INDEX = 16;
+struct ComponentTypeMask final
+{
+    ComponentTypeMask();
+    ComponentTypeMask(const ComponentTypeMask &other);
+    ~ComponentTypeMask();
+    void reset();
+    bool none();
+    void setIndex(GLenum type, size_t index);
+    unsigned long to_ulong() const;
+    void from_ulong(unsigned long mask);
+    static bool Validate(unsigned long outputTypes,
+                         unsigned long inputTypes,
+                         unsigned long outputMask,
+                         unsigned long inputMask);
+
+  private:
+    // 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>>;
+
+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>;
+
 }  // 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
@@ -421,28 +421,52 @@ inline GLenum FramebufferBindingToEnum(F
         case FramebufferBindingBoth:
             return GL_FRAMEBUFFER;
         default:
             UNREACHABLE();
             return GL_NONE;
     }
 }
 
-// Helper class for wrapping an onDestroy function.
 template <typename ObjT, typename ContextT>
-class UniqueObjectPointer : angle::NonCopyable
+class DestroyThenDelete
 {
   public:
-    UniqueObjectPointer(const ContextT *context) : mObject(nullptr), mContext(context) {}
-    UniqueObjectPointer(ObjT *obj, const ContextT *context) : mObject(obj), mContext(context) {}
-    ~UniqueObjectPointer()
+    DestroyThenDelete(const ContextT *context) : mContext(context) {}
+
+    void operator()(ObjT *obj)
+    {
+        ANGLE_SWALLOW_ERR(obj->onDestroy(mContext));
+        delete obj;
+    }
+
+  private:
+    const ContextT *mContext;
+};
+
+// Helper class for wrapping an onDestroy function.
+template <typename ObjT, typename DeleterT>
+class UniqueObjectPointerBase : angle::NonCopyable
+{
+  public:
+    template <typename ContextT>
+    UniqueObjectPointerBase(const ContextT *context) : mObject(nullptr), mDeleter(context)
+    {
+    }
+
+    template <typename ContextT>
+    UniqueObjectPointerBase(ObjT *obj, const ContextT *context) : mObject(obj), mDeleter(context)
+    {
+    }
+
+    ~UniqueObjectPointerBase()
     {
         if (mObject)
         {
-            ANGLE_SWALLOW_ERR(mObject->onDestroy(mContext));
+            mDeleter(mObject);
         }
     }
 
     ObjT *operator->() const { return mObject; }
 
     ObjT *release()
     {
         auto obj = mObject;
@@ -451,25 +475,29 @@ class UniqueObjectPointer : angle::NonCo
     }
 
     ObjT *get() const { return mObject; }
 
     void reset(ObjT *obj)
     {
         if (mObject)
         {
-            ANGLE_SWALLOW_ERR(mObject->onDestroy(mContext));
+            mDeleter(mObject);
         }
         mObject = obj;
     }
 
   private:
     ObjT *mObject;
-    const ContextT *mContext;
+    DeleterT mDeleter;
 };
+
+template <typename ObjT, typename ContextT>
+using UniqueObjectPointer = UniqueObjectPointerBase<ObjT, DestroyThenDelete<ObjT, ContextT>>;
+
 }  // namespace angle
 
 namespace gl
 {
 class ContextState;
 
 }  // namespace gl
 
--- a/gfx/angle/src/libANGLE/entry_points_enum_autogen.h
+++ b/gfx/angle/src/libANGLE/entry_points_enum_autogen.h
@@ -1,268 +1,395 @@
 // GENERATED FILE - DO NOT EDIT.
 // Generated by generate_entry_points.py using data from gl.xml.
 //
-// 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.
 //
 // entry_points_enum_autogen.h:
 //   Defines the GLES entry points enumeration.
 
 #ifndef LIBGLESV2_ENTRYPOINTSENUM_AUTOGEN_H_
 #define LIBGLESV2_ENTRYPOINTSENUM_AUTOGEN_H_
 
 namespace gl
 {
 enum class EntryPoint
 {
     Invalid,
+    ActiveShaderProgram,
     ActiveTexture,
     AttachShader,
+    BeginQuery,
+    BeginQueryEXT,
+    BeginTransformFeedback,
     BindAttribLocation,
     BindBuffer,
+    BindBufferBase,
+    BindBufferRange,
     BindFramebuffer,
+    BindImageTexture,
+    BindProgramPipeline,
     BindRenderbuffer,
+    BindSampler,
     BindTexture,
+    BindTransformFeedback,
+    BindVertexArray,
+    BindVertexArrayOES,
+    BindVertexBuffer,
     BlendColor,
     BlendEquation,
     BlendEquationSeparate,
     BlendFunc,
     BlendFuncSeparate,
+    BlitFramebuffer,
+    BlitFramebufferANGLE,
     BufferData,
     BufferSubData,
     CheckFramebufferStatus,
     Clear,
+    ClearBufferfi,
+    ClearBufferfv,
+    ClearBufferiv,
+    ClearBufferuiv,
     ClearColor,
     ClearDepthf,
     ClearStencil,
+    ClientWaitSync,
     ColorMask,
     CompileShader,
     CompressedTexImage2D,
+    CompressedTexImage3D,
     CompressedTexSubImage2D,
+    CompressedTexSubImage3D,
+    CopyBufferSubData,
     CopyTexImage2D,
     CopyTexSubImage2D,
+    CopyTexSubImage3D,
     CreateProgram,
     CreateShader,
+    CreateShaderProgramv,
     CullFace,
+    DebugMessageCallbackKHR,
+    DebugMessageControlKHR,
+    DebugMessageInsertKHR,
     DeleteBuffers,
+    DeleteFencesNV,
     DeleteFramebuffers,
     DeleteProgram,
+    DeleteProgramPipelines,
+    DeleteQueries,
+    DeleteQueriesEXT,
     DeleteRenderbuffers,
+    DeleteSamplers,
     DeleteShader,
+    DeleteSync,
     DeleteTextures,
+    DeleteTransformFeedbacks,
+    DeleteVertexArrays,
+    DeleteVertexArraysOES,
     DepthFunc,
     DepthMask,
     DepthRangef,
     DetachShader,
     Disable,
     DisableVertexAttribArray,
+    DiscardFramebufferEXT,
+    DispatchCompute,
+    DispatchComputeIndirect,
     DrawArrays,
+    DrawArraysIndirect,
+    DrawArraysInstanced,
+    DrawArraysInstancedANGLE,
+    DrawBuffers,
+    DrawBuffersEXT,
     DrawElements,
+    DrawElementsIndirect,
+    DrawElementsInstanced,
+    DrawElementsInstancedANGLE,
+    DrawRangeElements,
+    EGLImageTargetRenderbufferStorageOES,
+    EGLImageTargetTexture2DOES,
     Enable,
     EnableVertexAttribArray,
+    EndQuery,
+    EndQueryEXT,
+    EndTransformFeedback,
+    FenceSync,
     Finish,
+    FinishFenceNV,
     Flush,
+    FlushMappedBufferRange,
+    FlushMappedBufferRangeEXT,
+    FramebufferParameteri,
     FramebufferRenderbuffer,
     FramebufferTexture2D,
+    FramebufferTextureLayer,
     FrontFace,
     GenBuffers,
-    GenerateMipmap,
+    GenFencesNV,
     GenFramebuffers,
+    GenProgramPipelines,
+    GenQueries,
+    GenQueriesEXT,
     GenRenderbuffers,
+    GenSamplers,
     GenTextures,
+    GenTransformFeedbacks,
+    GenVertexArrays,
+    GenVertexArraysOES,
+    GenerateMipmap,
     GetActiveAttrib,
     GetActiveUniform,
+    GetActiveUniformBlockName,
+    GetActiveUniformBlockiv,
+    GetActiveUniformsiv,
     GetAttachedShaders,
     GetAttribLocation,
+    GetBooleani_v,
     GetBooleanv,
+    GetBufferParameteri64v,
     GetBufferParameteriv,
+    GetBufferPointerv,
+    GetBufferPointervOES,
+    GetDebugMessageLogKHR,
     GetError,
+    GetFenceivNV,
     GetFloatv,
+    GetFragDataLocation,
     GetFramebufferAttachmentParameteriv,
+    GetFramebufferParameteriv,
+    GetGraphicsResetStatusEXT,
+    GetInteger64i_v,
+    GetInteger64v,
+    GetIntegeri_v,
     GetIntegerv,
-    GetProgramiv,
+    GetInternalformativ,
+    GetMultisamplefv,
+    GetObjectLabelKHR,
+    GetObjectPtrLabelKHR,
+    GetPointervKHR,
+    GetProgramBinary,
+    GetProgramBinaryOES,
     GetProgramInfoLog,
+    GetProgramInterfaceiv,
+    GetProgramPipelineInfoLog,
+    GetProgramPipelineiv,
+    GetProgramResourceIndex,
+    GetProgramResourceLocation,
+    GetProgramResourceName,
+    GetProgramResourceiv,
+    GetProgramiv,
+    GetQueryObjecti64vEXT,
+    GetQueryObjectivEXT,
+    GetQueryObjectui64vEXT,
+    GetQueryObjectuiv,
+    GetQueryObjectuivEXT,
+    GetQueryiv,
+    GetQueryivEXT,
     GetRenderbufferParameteriv,
-    GetShaderiv,
+    GetSamplerParameterfv,
+    GetSamplerParameteriv,
     GetShaderInfoLog,
     GetShaderPrecisionFormat,
     GetShaderSource,
+    GetShaderiv,
     GetString,
+    GetStringi,
+    GetSynciv,
+    GetTexLevelParameterfv,
+    GetTexLevelParameteriv,
     GetTexParameterfv,
     GetTexParameteriv,
+    GetTransformFeedbackVarying,
+    GetTranslatedShaderSourceANGLE,
+    GetUniformBlockIndex,
+    GetUniformIndices,
+    GetUniformLocation,
     GetUniformfv,
     GetUniformiv,
-    GetUniformLocation,
+    GetUniformuiv,
+    GetVertexAttribIiv,
+    GetVertexAttribIuiv,
+    GetVertexAttribPointerv,
     GetVertexAttribfv,
     GetVertexAttribiv,
-    GetVertexAttribPointerv,
+    GetnUniformfvEXT,
+    GetnUniformivEXT,
     Hint,
+    InsertEventMarkerEXT,
+    InvalidateFramebuffer,
+    InvalidateSubFramebuffer,
     IsBuffer,
     IsEnabled,
+    IsFenceNV,
     IsFramebuffer,
     IsProgram,
+    IsProgramPipeline,
+    IsQuery,
+    IsQueryEXT,
     IsRenderbuffer,
+    IsSampler,
     IsShader,
+    IsSync,
     IsTexture,
+    IsTransformFeedback,
+    IsVertexArray,
+    IsVertexArrayOES,
     LineWidth,
     LinkProgram,
+    MapBufferOES,
+    MapBufferRange,
+    MapBufferRangeEXT,
+    MemoryBarrier,
+    MemoryBarrierByRegion,
+    ObjectLabelKHR,
+    ObjectPtrLabelKHR,
+    PauseTransformFeedback,
     PixelStorei,
     PolygonOffset,
+    PopDebugGroupKHR,
+    PopGroupMarkerEXT,
+    ProgramBinary,
+    ProgramBinaryOES,
+    ProgramParameteri,
+    ProgramUniform1f,
+    ProgramUniform1fv,
+    ProgramUniform1i,
+    ProgramUniform1iv,
+    ProgramUniform1ui,
+    ProgramUniform1uiv,
+    ProgramUniform2f,
+    ProgramUniform2fv,
+    ProgramUniform2i,
+    ProgramUniform2iv,
+    ProgramUniform2ui,
+    ProgramUniform2uiv,
+    ProgramUniform3f,
+    ProgramUniform3fv,
+    ProgramUniform3i,
+    ProgramUniform3iv,
+    ProgramUniform3ui,
+    ProgramUniform3uiv,
+    ProgramUniform4f,
+    ProgramUniform4fv,
+    ProgramUniform4i,
+    ProgramUniform4iv,
+    ProgramUniform4ui,
+    ProgramUniform4uiv,
+    ProgramUniformMatrix2fv,
+    ProgramUniformMatrix2x3fv,
+    ProgramUniformMatrix2x4fv,
+    ProgramUniformMatrix3fv,
+    ProgramUniformMatrix3x2fv,
+    ProgramUniformMatrix3x4fv,
+    ProgramUniformMatrix4fv,
+    ProgramUniformMatrix4x2fv,
+    ProgramUniformMatrix4x3fv,
+    PushDebugGroupKHR,
+    PushGroupMarkerEXT,
+    QueryCounterEXT,
+    ReadBuffer,
     ReadPixels,
+    ReadnPixelsEXT,
     ReleaseShaderCompiler,
     RenderbufferStorage,
+    RenderbufferStorageMultisample,
+    RenderbufferStorageMultisampleANGLE,
+    ResumeTransformFeedback,
     SampleCoverage,
+    SampleMaski,
+    SamplerParameterf,
+    SamplerParameterfv,
+    SamplerParameteri,
+    SamplerParameteriv,
     Scissor,
+    SetFenceNV,
     ShaderBinary,
     ShaderSource,
     StencilFunc,
     StencilFuncSeparate,
     StencilMask,
     StencilMaskSeparate,
     StencilOp,
     StencilOpSeparate,
+    TestFenceNV,
     TexImage2D,
+    TexImage3D,
     TexParameterf,
     TexParameterfv,
     TexParameteri,
     TexParameteriv,
+    TexStorage1DEXT,
+    TexStorage2D,
+    TexStorage2DEXT,
+    TexStorage2DMultisample,
+    TexStorage3D,
+    TexStorage3DEXT,
     TexSubImage2D,
+    TexSubImage3D,
+    TransformFeedbackVaryings,
     Uniform1f,
     Uniform1fv,
     Uniform1i,
     Uniform1iv,
+    Uniform1ui,
+    Uniform1uiv,
     Uniform2f,
     Uniform2fv,
     Uniform2i,
     Uniform2iv,
+    Uniform2ui,
+    Uniform2uiv,
     Uniform3f,
     Uniform3fv,
     Uniform3i,
     Uniform3iv,
+    Uniform3ui,
+    Uniform3uiv,
     Uniform4f,
     Uniform4fv,
     Uniform4i,
     Uniform4iv,
+    Uniform4ui,
+    Uniform4uiv,
+    UniformBlockBinding,
     UniformMatrix2fv,
+    UniformMatrix2x3fv,
+    UniformMatrix2x4fv,
     UniformMatrix3fv,
+    UniformMatrix3x2fv,
+    UniformMatrix3x4fv,
     UniformMatrix4fv,
+    UniformMatrix4x2fv,
+    UniformMatrix4x3fv,
+    UnmapBuffer,
+    UnmapBufferOES,
     UseProgram,
+    UseProgramStages,
     ValidateProgram,
+    ValidateProgramPipeline,
     VertexAttrib1f,
     VertexAttrib1fv,
     VertexAttrib2f,
     VertexAttrib2fv,
     VertexAttrib3f,
     VertexAttrib3fv,
     VertexAttrib4f,
     VertexAttrib4fv,
-    VertexAttribPointer,
-    Viewport,
-    ReadBuffer,
-    DrawRangeElements,
-    TexImage3D,
-    TexSubImage3D,
-    CopyTexSubImage3D,
-    CompressedTexImage3D,
-    CompressedTexSubImage3D,
-    GenQueries,
-    DeleteQueries,
-    IsQuery,
-    BeginQuery,
-    EndQuery,
-    GetQueryiv,
-    GetQueryObjectuiv,
-    UnmapBuffer,
-    GetBufferPointerv,
-    DrawBuffers,
-    UniformMatrix2x3fv,
-    UniformMatrix3x2fv,
-    UniformMatrix2x4fv,
-    UniformMatrix4x2fv,
-    UniformMatrix3x4fv,
-    UniformMatrix4x3fv,
-    BlitFramebuffer,
-    RenderbufferStorageMultisample,
-    FramebufferTextureLayer,
-    MapBufferRange,
-    FlushMappedBufferRange,
-    BindVertexArray,
-    DeleteVertexArrays,
-    GenVertexArrays,
-    IsVertexArray,
-    GetIntegeri_v,
-    BeginTransformFeedback,
-    EndTransformFeedback,
-    BindBufferRange,
-    BindBufferBase,
-    TransformFeedbackVaryings,
-    GetTransformFeedbackVarying,
-    VertexAttribIPointer,
-    GetVertexAttribIiv,
-    GetVertexAttribIuiv,
+    VertexAttribBinding,
+    VertexAttribDivisor,
+    VertexAttribDivisorANGLE,
+    VertexAttribFormat,
     VertexAttribI4i,
+    VertexAttribI4iv,
     VertexAttribI4ui,
-    VertexAttribI4iv,
     VertexAttribI4uiv,
-    GetUniformuiv,
-    GetFragDataLocation,
-    Uniform1ui,
-    Uniform2ui,
-    Uniform3ui,
-    Uniform4ui,
-    Uniform1uiv,
-    Uniform2uiv,
-    Uniform3uiv,
-    Uniform4uiv,
-    ClearBufferiv,
-    ClearBufferuiv,
-    ClearBufferfv,
-    ClearBufferfi,
-    GetStringi,
-    CopyBufferSubData,
-    GetUniformIndices,
-    GetActiveUniformsiv,
-    GetUniformBlockIndex,
-    GetActiveUniformBlockiv,
-    GetActiveUniformBlockName,
-    UniformBlockBinding,
-    DrawArraysInstanced,
-    DrawElementsInstanced,
-    FenceSync,
-    IsSync,
-    DeleteSync,
-    ClientWaitSync,
-    WaitSync,
-    GetInteger64v,
-    GetSynciv,
-    GetInteger64i_v,
-    GetBufferParameteri64v,
-    GenSamplers,
-    DeleteSamplers,
-    IsSampler,
-    BindSampler,
-    SamplerParameteri,
-    SamplerParameteriv,
-    SamplerParameterf,
-    SamplerParameterfv,
-    GetSamplerParameteriv,
-    GetSamplerParameterfv,
-    VertexAttribDivisor,
-    BindTransformFeedback,
-    DeleteTransformFeedbacks,
-    GenTransformFeedbacks,
-    IsTransformFeedback,
-    PauseTransformFeedback,
-    ResumeTransformFeedback,
-    GetProgramBinary,
-    ProgramBinary,
-    ProgramParameteri,
-    InvalidateFramebuffer,
-    InvalidateSubFramebuffer,
-    TexStorage2D,
-    TexStorage3D,
-    GetInternalformativ,
-    DrawElementsInstancedANGLE
+    VertexAttribIFormat,
+    VertexAttribIPointer,
+    VertexAttribPointer,
+    VertexBindingDivisor,
+    Viewport,
+    WaitSync
 };
 }  // namespace gl
 #endif  // LIBGLESV2_ENTRY_POINTS_ENUM_AUTOGEN_H_
--- a/gfx/angle/src/libANGLE/format_map_autogen.cpp
+++ b/gfx/angle/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 2016 The ANGLE Project Authors. All rights reserved.
+// 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.
 //
 // 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/src/libANGLE/formatutils.cpp
+++ b/gfx/angle/src/libANGLE/formatutils.cpp
@@ -296,16 +296,18 @@ InternalFormat::InternalFormat()
       componentType(GL_NONE),
       colorEncoding(GL_NONE),
       textureSupport(NeverSupported),
       renderSupport(NeverSupported),
       filterSupport(NeverSupported)
 {
 }
 
+InternalFormat::InternalFormat(const InternalFormat &other) = default;
+
 bool InternalFormat::isLUMA() const
 {
     return ((redBits + greenBits + blueBits + depthBits + stencilBits) == 0 &&
             (luminanceBits + alphaBits) > 0);
 }
 
 GLenum InternalFormat::getReadPixelsFormat() const
 {
@@ -761,17 +763,17 @@ static InternalFormatInfoMap BuildIntern
     AddCompressedFormat(&map, GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC,          4, 4, 128, 4, GL_RGBA, GL_UNSIGNED_BYTE, true,  RequireES<3, 0>, NeverSupported, AlwaysSupported);
 
     // From GL_EXT_texture_compression_dxt1
     //                       | Internal format                   |W |H | BS |CC| Format | Type            | SRGB | Supported                                         | Renderable    | Filterable    |
     AddCompressedFormat(&map, GL_COMPRESSED_RGB_S3TC_DXT1_EXT,    4, 4,  64, 3, GL_RGB,  GL_UNSIGNED_BYTE, false, RequireExt<&Extensions::textureCompressionDXT1>,    NeverSupported, AlwaysSupported);
     AddCompressedFormat(&map, GL_COMPRESSED_RGBA_S3TC_DXT1_EXT,   4, 4,  64, 4, GL_RGBA, GL_UNSIGNED_BYTE, false, RequireExt<&Extensions::textureCompressionDXT1>,    NeverSupported, AlwaysSupported);
 
     // From GL_ANGLE_texture_compression_dxt3
-    AddCompressedFormat(&map, GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE, 4, 4, 128, 4, GL_RGBA, GL_UNSIGNED_BYTE, false, RequireExt<&Extensions::textureCompressionDXT5>,    NeverSupported, AlwaysSupported);
+    AddCompressedFormat(&map, GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE, 4, 4, 128, 4, GL_RGBA, GL_UNSIGNED_BYTE, false, RequireExt<&Extensions::textureCompressionDXT3>,    NeverSupported, AlwaysSupported);
 
     // From GL_ANGLE_texture_compression_dxt5
     AddCompressedFormat(&map, GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE, 4, 4, 128, 4, GL_RGBA, GL_UNSIGNED_BYTE, false, RequireExt<&Extensions::textureCompressionDXT5>,    NeverSupported, AlwaysSupported);
 
     // From GL_OES_compressed_ETC1_RGB8_texture
     AddCompressedFormat(&map, GL_ETC1_RGB8_OES,                   4, 4,  64, 3, GL_RGB,  GL_UNSIGNED_BYTE, false, RequireExt<&Extensions::compressedETC1RGB8Texture>, NeverSupported, AlwaysSupported);
 
     // From GL_EXT_texture_compression_s3tc_srgb
@@ -840,17 +842,17 @@ 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, RequireESOrExt<3, 0, &Extensions::rgb8rgba8>, RequireESOrExt<3, 0, &Extensions::rgb8rgba8>, AlwaysSupported);
+    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_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,  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);
@@ -1054,58 +1056,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);
@@ -1116,19 +1127,19 @@ ErrorOrResult<GLuint> InternalFormat::co
     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,
-                                                       GLuint depthPitch,
-                                                       const PixelStoreStateBase &state,
-                                                       bool is3D) const
+                                                           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);
     auto checkedSkipImagesBytes = checkedSkipImages * checkedDepthPitch;
@@ -1137,53 +1148,54 @@ ErrorOrResult<GLuint> InternalFormat::co
         checkedSkipImagesBytes = 0;
     }
     auto skipBytes = checkedSkipImagesBytes + checkedSkipRows * checkedRowPitch +
                      checkedSkipPixels * checkedPixelBytes;
     ANGLE_TRY_CHECKED_MATH(skipBytes);
     return skipBytes.ValueOrDie();
 }
 
-ErrorOrResult<GLuint> InternalFormat::computePackUnpackEndByte(const Extents &size,
-                                                               const PixelStoreStateBase &state,
-                                                               bool is3D) const
+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(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/src/libANGLE/formatutils.h
+++ b/gfx/angle/src/libANGLE/formatutils.h
@@ -46,39 +46,45 @@ struct Type
 };
 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,
                                            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
--- a/gfx/angle/src/libANGLE/gen_format_map.py
+++ b/gfx/angle/src/libANGLE/gen_format_map.py
@@ -179,9 +179,8 @@ with open('format_map_autogen.cpp', 'wt'
         data_source_name = input_script,
         es3_data_source_name = combo_data_file,
         copyright_year = date.today().year,
         format_cases = format_cases,
         es3_format_cases = es3_format_cases,
         es3_type_cases = es3_type_cases,
         es3_combo_cases = es3_combo_cases)
     out_file.write(output_cpp)
-    out_file.close()
new file mode 100644
--- /dev/null
+++ b/gfx/angle/src/libANGLE/gen_packed_gl_enums.py
@@ -0,0 +1,176 @@
+# 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.
+#
+# gen_packed_gl_enums.py:
+#  Code generation for the packed GL enums.
+
+import datetime, json, os, sys
+from collections import namedtuple
+
+Enum = namedtuple('Enum', ['name', 'values', 'max_value'])
+EnumValue = namedtuple('EnumValue', ['name', 'gl_name', 'value'])
+
+kJsonFileName = "packed_gl_enums.json"
+
+def load_enums(path):
+    with open(path) as map_file:
+        enums_dict = json.loads(map_file.read())
+
+    enums = []
+    for (enum_name, values_dict) in enums_dict.iteritems():
+
+        values = []
+        i = 0
+        for (value_name, value_gl_name) in sorted(values_dict.iteritems()):
+            values.append(EnumValue(value_name, value_gl_name, i))
+            i += 1
+
+        assert(i < 255) # This makes sure enums fit in the uint8_t
+        enums.append(Enum(enum_name, values, i))
+
+    enums.sort(key=lambda enum: enum.name)
+    return enums
+
+header_template = """// GENERATED FILE - DO NOT EDIT.
+// Generated by {script_name} using data from {data_source_name}.
+//
+// Copyright {copyright_year} The ANGLE Project 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_autogen.h:
+//   Declares ANGLE-specific enums classes for GLEnum and functions operating
+//   on them.
+
+#ifndef LIBANGLE_PACKEDGLENUMS_AUTOGEN_H_
+#define LIBANGLE_PACKEDGLENUMS_AUTOGEN_H_
+
+#include <angle_gl.h>
+
+#include <cstdint>
+
+namespace gl
+{{
+
+template<typename Enum>
+Enum FromGLenum(GLenum from);
+{content}
+}}  // namespace gl
+
+#endif // LIBANGLE_PACKEDGLENUMS_AUTOGEN_H_
+"""
+
+enum_declaration_template = """
+enum class {enum_name} : uint8_t
+{{
+{value_declarations}
+
+    InvalidEnum = {max_value},
+    EnumCount = {max_value},
+}};
+
+template<>
+{enum_name} FromGLenum<{enum_name}>(GLenum from);
+GLenum ToGLenum({enum_name} from);
+"""
+
+def write_header(enums, path):
+    content = ['']
+
+    for enum in enums:
+        value_declarations = []
+        for value in enum.values:
+            value_declarations.append('    ' + value.name + ' = ' + str(value.value) + ',')
+
+        content.append(enum_declaration_template.format(
+            enum_name = enum.name,
+            max_value = str(enum.max_value),
+            value_declarations = '\n'.join(value_declarations)
+        ))
+
+    header = header_template.format(
+        content = ''.join(content),
+        copyright_year = datetime.date.today().year,
+        data_source_name = kJsonFileName,
+        script_name = sys.argv[0]
+    )
+
+    with (open(path, 'wt')) as f:
+        f.write(header)
+
+cpp_template = """// GENERATED FILE - DO NOT EDIT.
+// Generated by {script_name} using data from {data_source_name}.
+//
+// Copyright {copyright_year} The ANGLE Project 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_autogen.cpp:
+//   Implements ANGLE-specific enums classes for GLEnum and functions operating
+//   on them.
+
+#include "common/debug.h"
+#include "libANGLE/PackedGLEnums_autogen.h"
+
+namespace gl
+{{
+{content}
+}}  // namespace gl
+"""
+
+enum_implementation_template = """
+template<>
+{enum_name} FromGLenum<{enum_name}>(GLenum from)
+{{
+    switch(from)
+    {{
+{from_glenum_cases}
+        default: return {enum_name}::InvalidEnum;
+    }}
+}}
+
+GLenum ToGLenum({enum_name} from)
+{{
+    switch(from)
+    {{
+{to_glenum_cases}
+        default: UNREACHABLE(); return GL_NONE;
+    }}
+}}
+"""
+
+def write_cpp(enums, path):
+    content = ['']
+
+    for enum in enums:
+        from_glenum_cases = []
+        to_glenum_cases = []
+        for value in enum.values:
+            qualified_name = enum.name + '::' + value.name
+            from_glenum_cases.append('        case ' + value.gl_name + ': return ' + qualified_name + ';')
+            to_glenum_cases.append('        case ' + qualified_name + ': return ' + value.gl_name + ';')
+
+        content.append(enum_implementation_template.format(
+            enum_name = enum.name,
+            from_glenum_cases = '\n'.join(from_glenum_cases),
+            max_value = str(enum.max_value),
+            to_glenum_cases = '\n'.join(to_glenum_cases)
+        ))
+
+    cpp = cpp_template.format(
+        content = ''.join(content),
+        copyright_year = datetime.date.today().year,
+        data_source_name = kJsonFileName,
+        script_name = sys.argv[0]
+    )
+
+    with (open(path, 'wt')) as f:
+        f.write(cpp)
+
+if __name__ == '__main__':
+    path_prefix = os.path.dirname(os.path.realpath(__file__)) + os.path.sep
+    enums = load_enums(path_prefix + kJsonFileName)
+
+    write_header(enums, path_prefix + 'PackedGLEnums_autogen.h')
+    write_cpp(enums, path_prefix + 'PackedGLEnums_autogen.cpp')
old mode 100755
new mode 100644
--- a/gfx/angle/src/libANGLE/moz.build
+++ b/gfx/angle/src/libANGLE/moz.build
@@ -13,60 +13,61 @@ UNIFIED_SOURCES += [
     '../common/debug.cpp',
     '../common/event_tracer.cpp',
     '../common/Float16ToFloat32.cpp',
     '../common/mathutil.cpp',
     '../common/MemoryBuffer.cpp',
     '../common/string_utils.cpp',
     '../common/system_utils_win.cpp',
     '../common/third_party/base/anglebase/sha1.cc',
-    '../common/third_party/murmurhash/MurmurHash3.cpp',
+    '../common/third_party/smhasher/src/PMurHash.cpp',
     '../common/tls.cpp',
     '../common/uniform_type_info_autogen.cpp',
     '../common/utilities.cpp',
     '../compiler/preprocessor/DiagnosticsBase.cpp',
     '../compiler/preprocessor/DirectiveHandlerBase.cpp',
     '../compiler/preprocessor/DirectiveParser.cpp',
-    '../compiler/preprocessor/ExpressionParser.cpp',
     '../compiler/preprocessor/Input.cpp',
     '../compiler/preprocessor/Lexer.cpp',
     '../compiler/preprocessor/Macro.cpp',
     '../compiler/preprocessor/MacroExpander.cpp',
     '../compiler/preprocessor/Preprocessor.cpp',
     '../compiler/preprocessor/Token.cpp',
+    '../compiler/preprocessor/Tokenizer.cpp',
     '../compiler/translator/AddAndTrueToLoopCondition.cpp',
     '../compiler/translator/AddDefaultReturnStatements.cpp',
     '../compiler/translator/ArrayReturnValueToOutParameter.cpp',
     '../compiler/translator/ASTMetadataHLSL.cpp',
-    '../compiler/translator/blocklayout.cpp',
     '../compiler/translator/blocklayoutHLSL.cpp',
     '../compiler/translator/BreakVariableAliasingInInnerLoops.cpp',
     '../compiler/translator/BuiltInFunctionEmulator.cpp',
     '../compiler/translator/BuiltInFunctionEmulatorGLSL.cpp',
     '../compiler/translator/BuiltInFunctionEmulatorHLSL.cpp',
-    '../compiler/translator/Cache.cpp',
     '../compiler/translator/CallDAG.cpp',
     '../compiler/translator/ClampPointSize.cpp',
     '../compiler/translator/CodeGen.cpp',
     '../compiler/translator/CollectVariables.cpp',
     '../compiler/translator/Compiler.cpp',
     '../compiler/translator/ConstantUnion.cpp',
+    '../compiler/translator/Declarator.cpp',
     '../compiler/translator/DeclareAndInitBuiltinsForInstancedMultiview.cpp',
     '../compiler/translator/DeferGlobalInitializers.cpp',
     '../compiler/translator/Diagnostics.cpp',
     '../compiler/translator/DirectiveHandler.cpp',
     '../compiler/translator/emulated_builtin_functions_hlsl_autogen.cpp',
     '../compiler/translator/EmulatePrecision.cpp',
     '../compiler/translator/ExpandIntegerPowExpressions.cpp',
     '../compiler/translator/ExtensionBehavior.cpp',
     '../compiler/translator/ExtensionGLSL.cpp',
     '../compiler/translator/FindMain.cpp',
     '../compiler/translator/FindSymbolNode.cpp',
     '../compiler/translator/FlagStd140Structs.cpp',
+    '../compiler/translator/FoldExpressions.cpp',
     '../compiler/translator/HashNames.cpp',
+    '../compiler/translator/ImageFunctionHLSL.cpp',
     '../compiler/translator/InfoSink.cpp',
     '../compiler/translator/Initialize.cpp',
     '../compiler/translator/InitializeDll.cpp',
     '../compiler/translator/InitializeVariables.cpp',
     '../compiler/translator/IntermNode.cpp',
     '../compiler/translator/IntermNode_util.cpp',
     '../compiler/translator/IntermNodePatternMatcher.cpp',
     '../compiler/translator/IntermTraverse.cpp',
@@ -74,60 +75,64 @@ UNIFIED_SOURCES += [
     '../compiler/translator/Operator.cpp',
     '../compiler/translator/OutputESSL.cpp',
     '../compiler/translator/OutputGLSL.cpp',
     '../compiler/translator/OutputGLSLBase.cpp',
     '../compiler/translator/OutputHLSL.cpp',
     '../compiler/translator/OutputTree.cpp',
     '../compiler/translator/ParseContext.cpp',
     '../compiler/translator/PoolAlloc.cpp',
-    '../compiler/translator/PruneEmptyDeclarations.cpp',
-    '../compiler/translator/PrunePureLiteralStatements.cpp',
+    '../compiler/translator/PruneNoOps.cpp',
     '../compiler/translator/QualifierTypes.cpp',
     '../compiler/translator/RecordConstantPrecision.cpp',
     '../compiler/translator/RegenerateStructNames.cpp',
     '../compiler/translator/RemoveArrayLengthMethod.cpp',
     '../compiler/translator/RemoveDynamicIndexing.cpp',
+    '../compiler/translator/RemoveEmptySwitchStatements.cpp',
     '../compiler/translator/RemoveInvariantDeclaration.cpp',
+    '../compiler/translator/RemoveNoOpCasesFromEndOfSwitchStatements.cpp',
     '../compiler/translator/RemovePow.cpp',
     '../compiler/translator/RemoveSwitchFallThrough.cpp',
+    '../compiler/translator/RemoveUnreferencedVariables.cpp',
     '../compiler/translator/RewriteDoWhile.cpp',
     '../compiler/translator/RewriteElseBlocks.cpp',
     '../compiler/translator/RewriteUnaryMinusOperatorFloat.cpp',
     '../compiler/translator/RunAtTheEndOfShader.cpp',
     '../compiler/translator/ScalarizeVecAndMatConstructorArgs.cpp',
-    '../compiler/translator/SearchSymbol.cpp',
     '../compiler/translator/SeparateArrayInitialization.cpp',
     '../compiler/translator/SeparateDeclarations.cpp',
     '../compiler/translator/SeparateExpressionsReturningArrays.cpp',
     '../compiler/translator/ShaderVars.cpp',
     '../compiler/translator/SimplifyLoopConditions.cpp',
     '../compiler/translator/SplitSequenceOperator.cpp',
+    '../compiler/translator/StaticType.cpp',
     '../compiler/translator/StructureHLSL.cpp',
+    '../compiler/translator/Symbol.cpp',
     '../compiler/translator/SymbolTable.cpp',
+    '../compiler/translator/SymbolUniqueId.cpp',
     '../compiler/translator/TextureFunctionHLSL.cpp',
     '../compiler/translator/TranslatorESSL.cpp',
     '../compiler/translator/TranslatorGLSL.cpp',
     '../compiler/translator/TranslatorHLSL.cpp',
     '../compiler/translator/Types.cpp',
     '../compiler/translator/UnfoldShortCircuitAST.cpp',
     '../compiler/translator/UnfoldShortCircuitToIf.cpp',
     '../compiler/translator/UniformHLSL.cpp',
     '../compiler/translator/UseInterfaceBlockFields.cpp',
     '../compiler/translator/util.cpp',
     '../compiler/translator/UtilsHLSL.cpp',
     '../compiler/translator/ValidateGlobalInitializer.cpp',
     '../compiler/translator/ValidateLimitations.cpp',
     '../compiler/translator/ValidateMaxParameters.cpp',
     '../compiler/translator/ValidateSwitch.cpp',
     '../compiler/translator/ValidateVaryingLocations.cpp',
-    '../compiler/translator/VariablePacker.cpp',
+    '../compiler/translator/VectorizeVectorScalarArithmetic.cpp',
     '../compiler/translator/VersionGLSL.cpp',
+    '../compiler/translator/WrapSwitchStatementsInBlocks.cpp',
     '../third_party/compiler/ArrayBoundsClamper.cpp',
-    '../third_party/systeminfo/SystemInfo.cpp',
     'angletypes.cpp',
     'AttributeMap.cpp',
     'Buffer.cpp',
     'Caps.cpp',
     'Compiler.cpp',
     'Config.cpp',
     'Context.cpp',
     'ContextState.cpp',
@@ -142,20 +147,22 @@ UNIFIED_SOURCES += [
     'FramebufferAttachment.cpp',
     'HandleAllocator.cpp',
     'HandleRangeAllocator.cpp',
     'Image.cpp',
     'ImageIndex.cpp',
     'IndexRangeCache.cpp',
     'LoggingAnnotator.cpp',
     'MemoryProgramCache.cpp',
+    'PackedGLEnums_autogen.cpp',
     'params.cpp',
     'Path.cpp',
     'Platform.cpp',
     'Program.cpp',
+    'ProgramLinkedResources.cpp',
     'ProgramPipeline.cpp',
     'Query.cpp',
     'queryconversions.cpp',
     'queryutils.cpp',
     'Renderbuffer.cpp',
     'renderer/ContextImpl.cpp',
     'renderer/d3d/BufferD3D.cpp',
     'renderer/d3d/CompilerD3D.cpp',
@@ -202,20 +209,22 @@ UNIFIED_SOURCES += [
     'renderer/DisplayImpl.cpp',
     'renderer/driver_utils.cpp',
     'renderer/Format_table_autogen.cpp',
     'renderer/gl/BlitGL.cpp',
     'renderer/gl/BufferGL.cpp',
     'renderer/gl/ClearMultiviewGL.cpp',
     'renderer/gl/CompilerGL.cpp',
     'renderer/gl/ContextGL.cpp',
+    'renderer/gl/DispatchTableGL_autogen.cpp',
     'renderer/gl/DisplayGL.cpp',
     'renderer/gl/FenceNVGL.cpp',
     'renderer/gl/formatutilsgl.cpp',
     'renderer/gl/FunctionsGL.cpp',
+    'renderer/gl/null_functions.cpp',
     'renderer/gl/PathGL.cpp',
     'renderer/gl/ProgramGL.cpp',
     'renderer/gl/ProgramPipelineGL.cpp',
     'renderer/gl/QueryGL.cpp',
     'renderer/gl/RenderbufferGL.cpp',
     'renderer/gl/RendererGL.cpp',
     'renderer/gl/renderergl_utils.cpp',
     'renderer/gl/SamplerGL.cpp',
@@ -262,42 +271,44 @@ UNIFIED_SOURCES += [
     'Shader.cpp',
     'State.cpp',
     'Stream.cpp',
     'Surface.cpp',
     'Texture.cpp',
     'Thread.cpp',
     'TransformFeedback.cpp',
     'Uniform.cpp',
-    'UniformLinker.cpp',
     'validationEGL.cpp',
     'validationES.cpp',
     'validationES2.cpp',
     'validationES3.cpp',
     'validationES31.cpp',
     'VaryingPacking.cpp',
     'VertexArray.cpp',
     'VertexAttribute.cpp',
     'WorkerThread.cpp',
 ]
 SOURCES += [
-    '../compiler/preprocessor/Tokenizer.cpp',
+    '../compiler/preprocessor/ExpressionParser.cpp',
+    '../compiler/translator/blocklayout.cpp',
     '../compiler/translator/EmulateGLFragColorBroadcast.cpp',
     '../compiler/translator/glslang_lex.cpp',
     '../compiler/translator/glslang_tab.cpp',
     '../compiler/translator/RewriteTexelFetchOffset.cpp',
     '../compiler/translator/RewriteUnaryMinusOperatorInt.cpp',
     '../compiler/translator/ShaderLang.cpp',
     '../compiler/translator/ValidateOutputs.cpp',
+    '../compiler/translator/VariablePacker.cpp',
     '../gpu_info_util/SystemInfo.cpp',
     '../gpu_info_util/SystemInfo_win.cpp',
     '../image_util/copyimage.cpp',
     '../image_util/imageformats.cpp',
     '../image_util/loadimage.cpp',
     '../image_util/loadimage_etc.cpp',
+    '../third_party/systeminfo/SystemInfo.cpp',
     'Display.cpp',
     'renderer/d3d/DisplayD3D.cpp',
     'renderer/d3d/HLSLCompiler.cpp',
     'renderer/gl/FramebufferGL.cpp',
 ]
 if CONFIG['MOZ_HAS_WINSDK_WITH_D3D']:
     UNIFIED_SOURCES += [
         'renderer/d3d/d3d11/Blit11.cpp',
@@ -318,58 +329,54 @@ if CONFIG['MOZ_HAS_WINSDK_WITH_D3D']:
         'renderer/d3d/d3d11/Query11.cpp',
         'renderer/d3d/d3d11/Renderer11.cpp',
         'renderer/d3d/d3d11/renderer11_utils.cpp',
         'renderer/d3d/d3d11/RenderStateCache.cpp',
         'renderer/d3d/d3d11/RenderTarget11.cpp',
         'renderer/d3d/d3d11/ResourceManager11.cpp',
         'renderer/d3d/d3d11/ShaderExecutable11.cpp',
         'renderer/d3d/d3d11/StateManager11.cpp',
-        'renderer/d3d/d3d11/StreamProducerNV12.cpp',
+        'renderer/d3d/d3d11/StreamProducerD3DTexture.cpp',
         'renderer/d3d/d3d11/texture_format_table.cpp',
         'renderer/d3d/d3d11/texture_format_table_autogen.cpp',
         'renderer/d3d/d3d11/TextureStorage11.cpp',
         'renderer/d3d/d3d11/TransformFeedback11.cpp',
         'renderer/d3d/d3d11/Trim11.cpp',
         'renderer/d3d/d3d11/VertexArray11.cpp',
         'renderer/d3d/d3d11/VertexBuffer11.cpp',
     ]
 if CONFIG['MOZ_HAS_WINSDK_WITH_D3D']:
     SOURCES += [
         'renderer/d3d/d3d11/SwapChain11.cpp',
         'renderer/d3d/d3d11/win32/NativeWindow11Win32.cpp',
     ]
 
-CXXFLAGS += CONFIG['SSE2_FLAGS']
 
 if CONFIG['CC_TYPE'] in ('clang', 'gcc'):
     CXXFLAGS += [
         '-Wno-attributes',
         '-Wno-shadow',
         '-Wno-sign-compare',
         '-Wno-unknown-pragmas',
         '-Wno-unreachable-code',
+        '-Wno-missing-braces',
     ]
     if CONFIG['CC_TYPE'] == 'clang':
         CXXFLAGS += [
             '-Wno-inconsistent-missing-override',
             '-Wno-unused-private-field',
         ]
     else:
         CXXFLAGS += [
             '-Wno-shadow-compatible-local',
             '-Wno-shadow-local',
         ]
 
-if CONFIG['CC_TYPE'] == 'msvc':
-    CXXFLAGS += [
-        '-wd4018', # '>' : signed/unsigned mismatch
-        '-wd4530', # C++ exception handler used, without /EHsc
-        '-wd5038', # C5038: initializer list order warnings
-    ]
+if CONFIG['CC_TYPE'] in ('msvc', 'clang-cl'):
+    CXXFLAGS += ['-wd5038'] # C5038: initializer list order warnings
 
 if CONFIG['MOZ_DIRECTX_SDK_PATH'] and not CONFIG['MOZ_HAS_WINSDK_WITH_D3D']:
     LOCAL_INCLUDES += ['%' + '%s/include/' % CONFIG['MOZ_DIRECTX_SDK_PATH']]
 
 DEFINES['_CRT_SECURE_NO_DEPRECATE'] = True
 DEFINES['_HAS_EXCEPTIONS'] = 0
 
 if not CONFIG['MOZ_DEBUG']:
@@ -385,17 +392,17 @@ DEFINES['ANGLE_NO_EXCEPTIONS'] = True
 
 # We need these defined to nothing so that we don't get bogus dllimport declspecs
 DEFINES['GL_APICALL'] = ""
 DEFINES['GL_GLEXT_PROTOTYPES'] = ""
 DEFINES['EGLAPI'] = ""
 
 
 
-LOCAL_INCLUDES += [ '../../include', '../../src', '../../src/common/third_party/base', '../../src/third_party/khronos', ]
+LOCAL_INCLUDES += [ '../../include', '../../src', '../../src/common/third_party/base', '../../src/common/third_party/smhasher', '../../src/third_party/khronos' ]
 
 DEFINES['LIBANGLE_IMPLEMENTATION'] = "1"
 DEFINES['ANGLE_ENABLE_HLSL'] = "1"
 DEFINES['ANGLE_ENABLE_KEYEDMUTEX'] = "1"
 DEFINES['ANGLE_DEFAULT_D3D11'] = "0"
 
 DEFINES['GPU_INFO_USE_SETUPAPI'] = True
 DEFINES['NTDDI_VERSION'] = 0x06020000
new file mode 100644
--- /dev/null
+++ b/gfx/angle/src/libANGLE/packed_gl_enums.json
@@ -0,0 +1,35 @@
+{
+    "BufferBinding":
+    {
+        "Array": "GL_ARRAY_BUFFER",
+        "AtomicCounter": "GL_ATOMIC_COUNTER_BUFFER",
+        "CopyRead": "GL_COPY_READ_BUFFER",
+        "CopyWrite": "GL_COPY_WRITE_BUFFER",
+        "DispatchIndirect": "GL_DISPATCH_INDIRECT_BUFFER",
+        "DrawIndirect": "GL_DRAW_INDIRECT_BUFFER",
+        "ElementArray": "GL_ELEMENT_ARRAY_BUFFER",
+        "PixelPack": "GL_PIXEL_PACK_BUFFER",
+        "PixelUnpack": "GL_PIXEL_UNPACK_BUFFER",
+        "ShaderStorage": "GL_SHADER_STORAGE_BUFFER",
+        "TransformFeedback": "GL_TRANSFORM_FEEDBACK_BUFFER",
+        "Uniform": "GL_UNIFORM_BUFFER"
+    },
+    "BufferUsage":
+    {
+        "DynamicCopy": "GL_DYNAMIC_COPY",
+        "DynamicDraw": "GL_DYNAMIC_DRAW",
+        "DynamicRead": "GL_DYNAMIC_READ",
+        "StaticCopy": "GL_STATIC_COPY",
+        "StaticDraw": "GL_STATIC_DRAW",
+        "StaticRead": "GL_STATIC_READ",
+        "StreamCopy": "GL_STREAM_COPY",
+        "StreamDraw": "GL_STREAM_DRAW",
+        "StreamRead": "GL_STREAM_READ"
+    },
+    "CullFaceMode":
+    {
+        "Back": "GL_BACK",
+        "Front": "GL_FRONT",
+        "FrontAndBack": "GL_FRONT_AND_BACK"
+    }
+}
--- a/gfx/angle/src/libANGLE/params.cpp
+++ b/gfx/angle/src/libANGLE/params.cpp
@@ -15,19 +15,29 @@
 
 namespace gl
 {
 
 // static
 constexpr ParamTypeInfo ParamsBase::TypeInfo;
 constexpr ParamTypeInfo HasIndexRange::TypeInfo;
 
+HasIndexRange::HasIndexRange()
+    : ParamsBase(nullptr), mContext(nullptr), mCount(0), mType(GL_NONE), mIndices(nullptr)
+{
+}
+
+HasIndexRange::HasIndexRange(Context *context, GLsizei count, GLenum type, const void *indices)
+    : ParamsBase(context), mContext(context), mCount(count), mType(type), mIndices(indices)
+{
+}
+
 const Optional<IndexRange> &HasIndexRange::getIndexRange() const
 {
-    if (mIndexRange.valid())
+    if (mIndexRange.valid() || !mContext)
     {
         return mIndexRange;
     }
 
     const State &state = mContext->getGLState();
 
     const gl::VertexArray *vao     = state.getVertexArray();
     gl::Buffer *elementArrayBuffer = vao->getElementArrayBuffer().get();
--- a/gfx/angle/src/libANGLE/params.h
+++ b/gfx/angle/src/libANGLE/params.h
@@ -66,20 +66,19 @@ template <EntryPoint EP, typename... Arg
 ANGLE_INLINE void ParamsBase::Factory(EntryPointParamType<EP> *objBuffer, ArgsT... args)
 {
     new (objBuffer) EntryPointParamType<EP>(args...);
 }
 
 class HasIndexRange : public ParamsBase
 {
   public:
-    HasIndexRange(Context *context, GLsizei count, GLenum type, const void *indices)
-        : ParamsBase(context), mContext(context), mCount(count), mType(type), mIndices(indices)
-    {
-    }
+    // Dummy placeholder that can't generate an index range.
+    HasIndexRange();
+    HasIndexRange(Context *context, GLsizei count, GLenum type, const void *indices);
 
     template <EntryPoint EP, typename... ArgsT>
     static void Factory(HasIndexRange *objBuffer, ArgsT... args);
 
     const Optional<IndexRange> &getIndexRange() const;
 
     ANGLE_PARAM_TYPE_INFO(HasIndexRange, ParamsBase);
 
@@ -213,16 +212,23 @@ struct DefaultReturnValue<EntryPoint::Ge
 
 // Specialized enum error value.
 template <>
 struct DefaultReturnValue<EntryPoint::ClientWaitSync, GLenum>
 {
     static constexpr GLenum kValue = GL_WAIT_FAILED;
 };
 
+// glTestFenceNV should still return TRUE for an invalid fence.
+template <>
+struct DefaultReturnValue<EntryPoint::TestFenceNV, GLboolean>
+{
+    static constexpr GLboolean kValue = GL_TRUE;
+};
+
 template <EntryPoint EP, typename ReturnType>
 constexpr ANGLE_INLINE ReturnType GetDefaultReturnValue()
 {
     return DefaultReturnValue<EP, ReturnType>::kValue;
 }
 
 }  // namespace gl
 
--- a/gfx/angle/src/libANGLE/queryconversions.cpp
+++ b/gfx/angle/src/libANGLE/queryconversions.cpp
@@ -19,90 +19,154 @@ namespace gl
 namespace
 {
 
 GLint64 ExpandFloatToInteger(GLfloat value)
 {
     return static_cast<GLint64>((static_cast<double>(0xFFFFFFFFULL) * value - 1.0) / 2.0);
 }
 
-template <typename QueryT>
-QueryT ClampToQueryRange(GLint64 value)
+template <typename QueryT, typename NativeT>
+QueryT CastFromStateValueToInt(GLenum pname, NativeT value)
 {
-    const GLint64 min = static_cast<GLint64>(std::numeric_limits<QueryT>::min());
-    const GLint64 max = static_cast<GLint64>(std::numeric_limits<QueryT>::max());
-    return static_cast<QueryT>(clamp(value, min, max));
-}
-
-template <typename QueryT, typename NativeT>
-QueryT CastStateValueToInt(GLenum pname, NativeT value)
-{
-    GLenum queryType  = GLTypeToGLenum<QueryT>::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)
         {
-            return ClampToQueryRange<QueryT>(ExpandFloatToInteger(static_cast<GLfloat>(value)));
+            return clampCast<QueryT>(ExpandFloatToInteger(static_cast<GLfloat>(value)));
         }
         else
         {
-            return gl::iround<QueryT>(static_cast<GLfloat>(value));
+            return clampCast<QueryT>(std::round(value));
         }
     }
 
-    // Clamp 64-bit int values when casting to int
-    if (nativeType == GL_INT_64_ANGLEX && queryType == GL_INT)
+    return clampCast<QueryT>(value);
+}
+
+template <typename NativeT, typename QueryT>
+NativeT CastQueryValueToInt(GLenum pname, QueryT value)
+{
+    GLenum queryType = GLTypeToGLenum<QueryT>::value;
+
+    if (queryType == GL_FLOAT)
     {
-        GLint64 minIntValue = static_cast<GLint64>(std::numeric_limits<GLint>::min());
-        GLint64 maxIntValue = static_cast<GLint64>(std::numeric_limits<GLint>::max());
-        GLint64 clampedValue = std::max(std::min(static_cast<GLint64>(value), maxIntValue), minIntValue);
-        return static_cast<QueryT>(clampedValue);
+        return static_cast<NativeT>(std::round(value));
     }
 
-    return static_cast<QueryT>(value);
+    return static_cast<NativeT>(value);
+}
+
+}  // anonymous namespace
+
+// ES 3.10 Section 2.2.2
+// When querying bitmasks(such as SAMPLE_MASK_VALUE or STENCIL_WRITEMASK) with GetIntegerv, the
+// mask value is treated as a signed integer, so that mask values with the high bit set will not be
+// clamped when returned as signed integers.
+GLint CastMaskValue(const Context *context, GLuint value)
+{
+    return (context->getClientVersion() >= Version(3, 1) ? static_cast<GLint>(value)
+                                                         : clampCast<GLint>(value));
 }
 
+template <typename QueryT, typename InternalT>
+QueryT CastFromGLintStateValue(GLenum pname, InternalT value)
+{
+    return CastFromStateValue<QueryT, GLint>(pname, clampCast<GLint, InternalT>(value));
+}
+
+template GLfloat CastFromGLintStateValue<GLfloat, GLenum>(GLenum pname, GLenum value);
+template GLint CastFromGLintStateValue<GLint, GLenum>(GLenum pname, GLenum value);
+template GLint64 CastFromGLintStateValue<GLint64, GLenum>(GLenum pname, GLenum value);
+template GLuint CastFromGLintStateValue<GLuint, GLenum>(GLenum pname, GLenum value);
+template GLfloat CastFromGLintStateValue<GLfloat, bool>(GLenum pname, bool value);
+template GLuint CastFromGLintStateValue<GLuint, bool>(GLenum pname, bool value);
+template GLint CastFromGLintStateValue<GLint, bool>(GLenum pname, bool value);
+
 template <typename QueryT, typename NativeT>
-QueryT CastStateValue(GLenum pname, NativeT value)
+QueryT CastFromStateValue(GLenum pname, NativeT value)
 {
     GLenum queryType = GLTypeToGLenum<QueryT>::value;
 
     switch (queryType)
     {
         case GL_INT:
-            return CastStateValueToInt<QueryT, NativeT>(pname, value);
         case GL_INT_64_ANGLEX:
-            return CastStateValueToInt<QueryT, NativeT>(pname, value);
+        case GL_UNSIGNED_INT:
+        case GL_UINT_64_ANGLEX:
+            return CastFromStateValueToInt<QueryT, NativeT>(pname, value);
         case GL_FLOAT:
             return static_cast<QueryT>(value);
         case GL_BOOL:
             return static_cast<QueryT>(value == static_cast<NativeT>(0) ? GL_FALSE : GL_TRUE);
         default:
             UNREACHABLE();
             return 0;
     }
 }
+template GLint CastFromStateValue<GLint, GLint>(GLenum pname, GLint value);
+template GLint CastFromStateValue<GLint, GLint64>(GLenum pname, GLint64 value);
+template GLint64 CastFromStateValue<GLint64, GLint>(GLenum pname, GLint value);
+template GLint64 CastFromStateValue<GLint64, GLint64>(GLenum pname, GLint64 value);
+template GLfloat CastFromStateValue<GLfloat, GLint>(GLenum pname, GLint value);
+template GLfloat CastFromStateValue<GLfloat, GLfloat>(GLenum pname, GLfloat value);
+template GLint CastFromStateValue<GLint, GLfloat>(GLenum pname, GLfloat value);
+template GLuint CastFromStateValue<GLuint, GLint>(GLenum pname, GLint value);
+template GLuint CastFromStateValue<GLuint, GLuint>(GLenum pname, GLuint value);
+template GLint CastFromStateValue<GLint, GLboolean>(GLenum pname, GLboolean value);
+template GLint64 CastFromStateValue<GLint64, GLboolean>(GLenum pname, GLboolean value);
+template GLint CastFromStateValue<GLint, GLuint>(GLenum pname, GLuint value);
+template GLint64 CastFromStateValue<GLint64, GLuint>(GLenum pname, GLuint value);
+template GLuint64 CastFromStateValue<GLuint64, GLuint>(GLenum pname, GLuint value);
 
-}  // anonymous namespace
+template <typename NativeT, typename QueryT>
+NativeT CastQueryValueTo(GLenum pname, QueryT value)
+{
+    GLenum nativeType = GLTypeToGLenum<NativeT>::value;
+
+    switch (nativeType)
+    {
+        case GL_INT:
+        case GL_INT_64_ANGLEX:
+        case GL_UNSIGNED_INT:
+        case GL_UINT_64_ANGLEX:
+            return CastQueryValueToInt<NativeT, QueryT>(pname, value);
+        case GL_FLOAT:
+            return static_cast<NativeT>(value);
+        case GL_BOOL:
+            return static_cast<NativeT>(value == static_cast<QueryT>(0) ? GL_FALSE : GL_TRUE);
+        default:
+            UNREACHABLE();
+            return 0;
+    }
+}
+
+template GLint CastQueryValueTo<GLint, GLfloat>(GLenum pname, GLfloat value);
+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)
 {
     if (nativeType == GL_INT)
     {
         std::vector<GLint> intParams(numParams, 0);
         context->getIntegervImpl(pname, intParams.data());
 
         for (unsigned int i = 0; i < numParams; ++i)
         {
-            outParams[i] = CastStateValue<QueryT>(pname, intParams[i]);
+            outParams[i] = CastFromStateValue<QueryT>(pname, intParams[i]);
         }
     }
     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)
@@ -112,35 +176,35 @@ void CastStateValues(Context *context, G
     }
     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)
         {
-            outParams[i] = CastStateValue<QueryT>(pname, floatParams[i]);
+            outParams[i] = CastFromStateValue<QueryT>(pname, floatParams[i]);
         }
     }
     else if (nativeType == GL_INT_64_ANGLEX)
     {
         std::vector<GLint64> int64Params(numParams, 0);
         context->getInteger64v(pname, int64Params.data());
 
         for (unsigned int i = 0; i < numParams; ++i)
         {
-            outParams[i] = CastStateValue<QueryT>(pname, int64Params[i]);
+            outParams[i] = CastFromStateValue<QueryT>(pname, int64Params[i]);
         }
     }
     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
+// 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 *);
 template void CastStateValues<GLuint>(Context *, GLenum, GLenum, unsigned int, GLuint *);
 template void CastStateValues<GLfloat>(Context *, GLenum, GLenum, unsigned int, GLfloat *);
 template void CastStateValues<GLint64>(Context *, GLenum, GLenum, unsigned int, GLint64 *);
 
 template <typename QueryT>
@@ -153,17 +217,17 @@ void CastIndexedStateValues(Context *con
 {
     if (nativeType == GL_INT)
     {
         std::vector<GLint> intParams(numParams, 0);
         context->getIntegeri_v(pname, index, intParams.data());
 
         for (unsigned int i = 0; i < numParams; ++i)
         {
-            outParams[i] = CastStateValue<QueryT>(pname, intParams[i]);
+            outParams[i] = CastFromStateValue<QueryT>(pname, intParams[i]);
         }
     }
     else if (nativeType == GL_BOOL)
     {
         std::vector<GLboolean> boolParams(numParams, GL_FALSE);
         context->getBooleani_v(pname, index, boolParams.data());
 
         for (unsigned int i = 0; i < numParams; ++i)
@@ -174,17 +238,17 @@ void CastIndexedStateValues(Context *con
     }
     else if (nativeType == GL_INT_64_ANGLEX)
     {
         std::vector<GLint64> int64Params(numParams, 0);
         context->getInteger64i_v(pname, index, int64Params.data());
 
         for (unsigned int i = 0; i < numParams; ++i)
         {
-            outParams[i] = CastStateValue<QueryT>(pname, int64Params[i]);
+            outParams[i] = CastFromStateValue<QueryT>(pname, int64Params[i]);
         }
     }
     else
         UNREACHABLE();
 }
 
 template void CastIndexedStateValues<GLboolean>(Context *,
                                                 GLenum,
--- a/gfx/angle/src/libANGLE/queryconversions.h
+++ b/gfx/angle/src/libANGLE/queryconversions.h
@@ -13,17 +13,18 @@
 #include "common/angleutils.h"
 
 namespace gl
 {
 class Context;
 
 // Helper class for converting a GL type to a GLenum:
 // We can't use CastStateValueEnum generally, because of GLboolean + GLubyte overlap.
-// We restrict our use to CastStateValue, where it eliminates duplicate parameters.
+// We restrict our use to CastFromStateValue and CastQueryValueTo, where it eliminates
+// duplicate parameters.
 
 template <typename GLType>
 struct GLTypeToGLenum
 {
     // static constexpr GLenum value;
 };
 
 template <>
@@ -42,27 +43,73 @@ struct GLTypeToGLenum<GLboolean>
     static constexpr GLenum value = GL_BOOL;
 };
 template <>
 struct GLTypeToGLenum<GLint64>
 {
     static constexpr GLenum value = GL_INT_64_ANGLEX;
 };
 template <>
+struct GLTypeToGLenum<GLuint64>
+{
+    static constexpr GLenum value = GL_UINT_64_ANGLEX;
+};
+template <>
 struct GLTypeToGLenum<GLfloat>
 {
     static constexpr GLenum value = GL_FLOAT;
 };
 
-// The GL state query API types are: bool, int, uint, float, int64
+GLint CastMaskValue(const Context *context, GLuint value);
+
+template <typename QueryT, typename InternalT>
+QueryT CastFromGLintStateValue(GLenum pname, InternalT value);
+
+template <typename QueryT, typename NativeT>
+QueryT CastFromStateValue(GLenum pname, NativeT value);
+
+template <typename NativeT, typename QueryT>
+NativeT CastQueryValueTo(GLenum pname, QueryT value);
+
+template <typename ParamType>
+GLenum ConvertToGLenum(GLenum pname, ParamType param)
+{
+    return static_cast<GLenum>(CastQueryValueTo<GLuint>(pname, param));
+}
+
+template <typename ParamType>
+GLenum ConvertToGLenum(ParamType param)
+{
+    return ConvertToGLenum(GL_NONE, param);
+}
+
+template <typename ParamType>
+GLenum ConvertToGLint(ParamType param)
+{
+    return CastQueryValueTo<GLint>(GL_NONE, param);
+}
+
+template <typename ParamType>
+bool ConvertToBool(ParamType param)
+{
+    return param != GL_FALSE;
+}
+
+template <typename ParamType>
+GLboolean ConvertToGLBoolean(ParamType param)
+{
+    return param ? GL_TRUE : GL_FALSE;
+}
+
+// The GL state query API types are: bool, int, uint, float, int64, uint64
 template <typename QueryT>
 void CastStateValues(Context *context, GLenum nativeType, GLenum pname,
                      unsigned int numParams, QueryT *outParams);
 
-// The GL state query API types are: bool, int, uint, float, int64
+// The GL state query API types are: bool, int, uint, float, int64, uint64
 template <typename QueryT>
 void CastIndexedStateValues(Context *context,
                             GLenum nativeType,
                             GLenum pname,
                             GLuint index,
                             unsigned int numParams,
                             QueryT *outParams);
 }
--- a/gfx/angle/src/libANGLE/queryutils.cpp
+++ b/gfx/angle/src/libANGLE/queryutils.cpp
@@ -18,480 +18,463 @@
 #include "libANGLE/Program.h"
 #include "libANGLE/Renderbuffer.h"
 #include "libANGLE/Sampler.h"
 #include "libANGLE/Shader.h"
 #include "libANGLE/Surface.h"
 #include "libANGLE/Texture.h"
 #include "libANGLE/Uniform.h"
 #include "libANGLE/VertexAttribute.h"
+#include "libANGLE/queryconversions.h"
 
 namespace gl
 {
 
 namespace
 {
+
 template <typename ParamType>
 void QueryTexLevelParameterBase(const Texture *texture,
                                 GLenum target,
                                 GLint level,
                                 GLenum pname,
                                 ParamType *params)
 {
     ASSERT(texture != nullptr);
     const InternalFormat *info = texture->getTextureState().getImageDesc(target, level).format.info;
 
     switch (pname)
     {
         case GL_TEXTURE_RED_TYPE:
-            *params = ConvertFromGLenum<ParamType>(info->redBits ? info->componentType : GL_NONE);
+            *params = CastFromGLintStateValue<ParamType>(
+                pname, info->redBits ? info->componentType : GL_NONE);
             break;
         case GL_TEXTURE_GREEN_TYPE:
-            *params = ConvertFromGLenum<ParamType>(info->greenBits ? info->componentType : GL_NONE);
+            *params = CastFromGLintStateValue<ParamType>(
+                pname, info->greenBits ? info->componentType : GL_NONE);
             break;
         case GL_TEXTURE_BLUE_TYPE:
-            *params = ConvertFromGLenum<ParamType>(info->blueBits ? info->componentType : GL_NONE);
+            *params = CastFromGLintStateValue<ParamType>(
+                pname, info->blueBits ? info->componentType : GL_NONE);
             break;
         case GL_TEXTURE_ALPHA_TYPE:
-            *params = ConvertFromGLenum<ParamType>(info->alphaBits ? info->componentType : GL_NONE);
+            *params = CastFromGLintStateValue<ParamType>(
+                pname, info->alphaBits ? info->componentType : GL_NONE);
             break;
         case GL_TEXTURE_DEPTH_TYPE:
-            *params = ConvertFromGLenum<ParamType>(info->depthBits ? info->componentType : GL_NONE);
+            *params = CastFromGLintStateValue<ParamType>(
+                pname, info->depthBits ? info->componentType : GL_NONE);
             break;
         case GL_TEXTURE_RED_SIZE:
-            *params = ConvertFromGLuint<ParamType>(info->redBits);
+            *params = CastFromGLintStateValue<ParamType>(pname, info->redBits);
             break;
         case GL_TEXTURE_GREEN_SIZE:
-            *params = ConvertFromGLuint<ParamType>(info->greenBits);
+            *params = CastFromGLintStateValue<ParamType>(pname, info->greenBits);
             break;
         case GL_TEXTURE_BLUE_SIZE:
-            *params = ConvertFromGLuint<ParamType>(info->blueBits);
+            *params = CastFromGLintStateValue<ParamType>(pname, info->blueBits);
             break;
         case GL_TEXTURE_ALPHA_SIZE:
-            *params = ConvertFromGLuint<ParamType>(info->alphaBits);
+            *params = CastFromGLintStateValue<ParamType>(pname, info->alphaBits);
             break;
         case GL_TEXTURE_DEPTH_SIZE:
-            *params = ConvertFromGLuint<ParamType>(info->depthBits);
+            *params = CastFromGLintStateValue<ParamType>(pname, info->depthBits);
             break;
         case GL_TEXTURE_STENCIL_SIZE:
-            *params = ConvertFromGLuint<ParamType>(info->stencilBits);
+            *params = CastFromGLintStateValue<ParamType>(pname, info->stencilBits);
             break;
         case GL_TEXTURE_SHARED_SIZE:
-            *params = ConvertFromGLuint<ParamType>(info->sharedBits);
+            *params = CastFromGLintStateValue<ParamType>(pname, info->sharedBits);
             break;
         case GL_TEXTURE_INTERNAL_FORMAT:
-            *params =
-                ConvertFromGLenum<ParamType>(info->internalFormat ? info->internalFormat : GL_RGBA);
+            *params = CastFromGLintStateValue<ParamType>(
+                pname, info->internalFormat ? info->internalFormat : GL_RGBA);
             break;
         case GL_TEXTURE_WIDTH:
-            *params =
-                ConvertFromGLint<ParamType>(static_cast<GLint>(texture->getWidth(target, level)));
+            *params = CastFromGLintStateValue<ParamType>(
+                pname, static_cast<uint32_t>(texture->getWidth(target, level)));
             break;
         case GL_TEXTURE_HEIGHT:
-            *params =
-                ConvertFromGLint<ParamType>(static_cast<GLint>(texture->getHeight(target, level)));
+            *params = CastFromGLintStateValue<ParamType>(
+                pname, static_cast<uint32_t>(texture->getHeight(target, level)));
             break;
         case GL_TEXTURE_DEPTH:
-            *params =
-                ConvertFromGLint<ParamType>(static_cast<GLint>(texture->getDepth(target, level)));
+            *params = CastFromGLintStateValue<ParamType>(
+                pname, static_cast<uint32_t>(texture->getDepth(target, level)));
             break;
         case GL_TEXTURE_SAMPLES:
-            *params = ConvertFromGLint<ParamType>(texture->getSamples(target, level));
+            *params = CastFromStateValue<ParamType>(pname, texture->getSamples(target, level));
             break;
         case GL_TEXTURE_FIXED_SAMPLE_LOCATIONS:
-            *params =
-                ConvertFromGLboolean<ParamType>(texture->getFixedSampleLocations(target, level));
+            *params = CastFromStateValue<ParamType>(
+                pname, static_cast<GLint>(texture->getFixedSampleLocations(target, level)));
             break;
         case GL_TEXTURE_COMPRESSED:
-            *params = ConvertFromGLboolean<ParamType>(info->compressed);
+            *params = CastFromStateValue<ParamType>(pname, static_cast<GLint>(info->compressed));
             break;
         default:
             UNREACHABLE();
             break;
     }
 }
 
 template <typename ParamType>
 void QueryTexParameterBase(const Texture *texture, GLenum pname, ParamType *params)
 {
     ASSERT(texture != nullptr);
 
     switch (pname)
     {
         case GL_TEXTURE_MAG_FILTER:
-            *params = ConvertFromGLenum<ParamType>(texture->getMagFilter());
+            *params = CastFromGLintStateValue<ParamType>(pname, texture->getMagFilter());
             break;
         case GL_TEXTURE_MIN_FILTER:
-            *params = ConvertFromGLenum<ParamType>(texture->getMinFilter());
+            *params = CastFromGLintStateValue<ParamType>(pname, texture->getMinFilter());
             break;
         case GL_TEXTURE_WRAP_S:
-            *params = ConvertFromGLenum<ParamType>(texture->getWrapS());
+            *params = CastFromGLintStateValue<ParamType>(pname, texture->getWrapS());
             break;
         case GL_TEXTURE_WRAP_T:
-            *params = ConvertFromGLenum<ParamType>(texture->getWrapT());
+            *params = CastFromGLintStateValue<ParamType>(pname, texture->getWrapT());
             break;
         case GL_TEXTURE_WRAP_R:
-            *params = ConvertFromGLenum<ParamType>(texture->getWrapR());
+            *params = CastFromGLintStateValue<ParamType>(pname, texture->getWrapR());
             break;
         case GL_TEXTURE_IMMUTABLE_FORMAT:
-            *params = ConvertFromGLboolean<ParamType>(texture->getImmutableFormat());
+            *params = CastFromGLintStateValue<ParamType>(pname, texture->getImmutableFormat());
             break;
         case GL_TEXTURE_IMMUTABLE_LEVELS:
-            *params = ConvertFromGLuint<ParamType>(texture->getImmutableLevels());
+            *params = CastFromGLintStateValue<ParamType>(pname, texture->getImmutableLevels());
             break;
         case GL_TEXTURE_USAGE_ANGLE:
-            *params = ConvertFromGLenum<ParamType>(texture->getUsage());
+            *params = CastFromGLintStateValue<ParamType>(pname, texture->getUsage());
             break;
         case GL_TEXTURE_MAX_ANISOTROPY_EXT:
-            *params = ConvertFromGLfloat<ParamType>(texture->getMaxAnisotropy());
+            *params = CastFromStateValue<ParamType>(pname, texture->getMaxAnisotropy());
             break;
         case GL_TEXTURE_SWIZZLE_R:
-            *params = ConvertFromGLenum<ParamType>(texture->getSwizzleRed());
+            *params = CastFromGLintStateValue<ParamType>(pname, texture->getSwizzleRed());
             break;
         case GL_TEXTURE_SWIZZLE_G:
-            *params = ConvertFromGLenum<ParamType>(texture->getSwizzleGreen());
+            *params = CastFromGLintStateValue<ParamType>(pname, texture->getSwizzleGreen());
             break;
         case GL_TEXTURE_SWIZZLE_B:
-            *params = ConvertFromGLenum<ParamType>(texture->getSwizzleBlue());
+            *params = CastFromGLintStateValue<ParamType>(pname, texture->getSwizzleBlue());
             break;
         case GL_TEXTURE_SWIZZLE_A:
-            *params = ConvertFromGLenum<ParamType>(texture->getSwizzleAlpha());
+            *params = CastFromGLintStateValue<ParamType>(pname, texture->getSwizzleAlpha());
             break;
         case GL_TEXTURE_BASE_LEVEL:
-            *params = ConvertFromGLuint<ParamType>(texture->getBaseLevel());
+            *params = CastFromGLintStateValue<ParamType>(pname, texture->getBaseLevel());
             break;
         case GL_TEXTURE_MAX_LEVEL:
-            *params = ConvertFromGLuint<ParamType>(texture->getMaxLevel());
+            *params = CastFromGLintStateValue<ParamType>(pname, texture->getMaxLevel());
             break;
         case GL_TEXTURE_MIN_LOD:
-            *params = ConvertFromGLfloat<ParamType>(texture->getSamplerState().minLod);
+            *params = CastFromStateValue<ParamType>(pname, texture->getSamplerState().minLod);
             break;
         case GL_TEXTURE_MAX_LOD:
-            *params = ConvertFromGLfloat<ParamType>(texture->getSamplerState().maxLod);
+            *params = CastFromStateValue<ParamType>(pname, texture->getSamplerState().maxLod);
             break;
         case GL_TEXTURE_COMPARE_MODE:
-            *params = ConvertFromGLenum<ParamType>(texture->getCompareMode());
+            *params = CastFromGLintStateValue<ParamType>(pname, texture->getCompareMode());
             break;
         case GL_TEXTURE_COMPARE_FUNC:
-            *params = ConvertFromGLenum<ParamType>(texture->getCompareFunc());
+            *params = CastFromGLintStateValue<ParamType>(pname, texture->getCompareFunc());
             break;
         case GL_TEXTURE_SRGB_DECODE_EXT:
-            *params = ConvertFromGLenum<ParamType>(texture->getSRGBDecode());
+            *params = CastFromGLintStateValue<ParamType>(pname, texture->getSRGBDecode());
             break;
         default:
             UNREACHABLE();
             break;
     }
 }
 
 template <typename ParamType>
 void SetTexParameterBase(Context *context, Texture *texture, GLenum pname, const ParamType *params)
 {
     ASSERT(texture != nullptr);
 
     switch (pname)
     {
         case GL_TEXTURE_WRAP_S:
-            texture->setWrapS(ConvertToGLenum(params[0]));
+            texture->setWrapS(ConvertToGLenum(pname, params[0]));
             break;
         case GL_TEXTURE_WRAP_T:
-            texture->setWrapT(ConvertToGLenum(params[0]));
+            texture->setWrapT(ConvertToGLenum(pname, params[0]));
             break;
         case GL_TEXTURE_WRAP_R:
-            texture->setWrapR(ConvertToGLenum(params[0]));
+            texture->setWrapR(ConvertToGLenum(pname, params[0]));
             break;
         case GL_TEXTURE_MIN_FILTER:
-            texture->setMinFilter(ConvertToGLenum(params[0]));
+            texture->setMinFilter(ConvertToGLenum(pname, params[0]));
             break;
         case GL_TEXTURE_MAG_FILTER:
-            texture->setMagFilter(ConvertToGLenum(params[0]));
+            texture->setMagFilter(ConvertToGLenum(pname, params[0]));
             break;
         case GL_TEXTURE_USAGE_ANGLE:
-            texture->setUsage(ConvertToGLenum(params[0]));
+            texture->setUsage(ConvertToGLenum(pname, params[0]));
             break;
         case GL_TEXTURE_MAX_ANISOTROPY_EXT:
-            texture->setMaxAnisotropy(ConvertToGLfloat(params[0]));
+            texture->setMaxAnisotropy(CastQueryValueTo<GLfloat>(pname, params[0]));
             break;
         case GL_TEXTURE_COMPARE_MODE:
-            texture->setCompareMode(ConvertToGLenum(params[0]));
+            texture->setCompareMode(ConvertToGLenum(pname, params[0]));
             break;
         case GL_TEXTURE_COMPARE_FUNC:
-            texture->setCompareFunc(ConvertToGLenum(params[0]));
+            texture->setCompareFunc(ConvertToGLenum(pname, params[0]));
             break;
         case GL_TEXTURE_SWIZZLE_R:
-            texture->setSwizzleRed(ConvertToGLenum(params[0]));
+            texture->setSwizzleRed(ConvertToGLenum(pname, params[0]));
             break;
         case GL_TEXTURE_SWIZZLE_G:
-            texture->setSwizzleGreen(ConvertToGLenum(params[0]));
+            texture->setSwizzleGreen(ConvertToGLenum(pname, params[0]));
             break;
         case GL_TEXTURE_SWIZZLE_B:
-            texture->setSwizzleBlue(ConvertToGLenum(params[0]));
+            texture->setSwizzleBlue(ConvertToGLenum(pname, params[0]));
             break;
         case GL_TEXTURE_SWIZZLE_A:
-            texture->setSwizzleAlpha(ConvertToGLenum(params[0]));
+            texture->setSwizzleAlpha(ConvertToGLenum(pname, params[0]));
             break;
         case GL_TEXTURE_BASE_LEVEL:
         {
-            context->handleError(texture->setBaseLevel(context, ConvertToGLuint(params[0])));
+            context->handleError(texture->setBaseLevel(
+                context, clampCast<GLuint>(CastQueryValueTo<GLint>(pname, params[0]))));
             break;
         }
         case GL_TEXTURE_MAX_LEVEL:
-            texture->setMaxLevel(ConvertToGLuint(params[0]));
+            texture->setMaxLevel(clampCast<GLuint>(CastQueryValueTo<GLint>(pname, params[0])));
             break;
         case GL_TEXTURE_MIN_LOD:
-            texture->setMinLod(ConvertToGLfloat(params[0]));
+            texture->setMinLod(CastQueryValueTo<GLfloat>(pname, params[0]));
             break;
         case GL_TEXTURE_MAX_LOD:
-            texture->setMaxLod(ConvertToGLfloat(params[0]));
+            texture->setMaxLod(CastQueryValueTo<GLfloat>(pname, params[0]));
             break;
         case GL_DEPTH_STENCIL_TEXTURE_MODE:
-            texture->setDepthStencilTextureMode(ConvertToGLenum(params[0]));
+            texture->setDepthStencilTextureMode(ConvertToGLenum(pname, params[0]));
             break;
         case GL_TEXTURE_SRGB_DECODE_EXT:
-            texture->setSRGBDecode(ConvertToGLenum(params[0]));
+            texture->setSRGBDecode(ConvertToGLenum(pname, params[0]));
             break;
         default:
             UNREACHABLE();
             break;
     }
 }
 
 template <typename ParamType>
 void QuerySamplerParameterBase(const Sampler *sampler, GLenum pname, ParamType *params)
 {
     switch (pname)
     {
         case GL_TEXTURE_MIN_FILTER:
-            *params = ConvertFromGLenum<ParamType>(sampler->getMinFilter());
+            *params = CastFromGLintStateValue<ParamType>(pname, sampler->getMinFilter());
             break;
         case GL_TEXTURE_MAG_FILTER:
-            *params = ConvertFromGLenum<ParamType>(sampler->getMagFilter());
+            *params = CastFromGLintStateValue<ParamType>(pname, sampler->getMagFilter());
             break;
         case GL_TEXTURE_WRAP_S:
-            *params = ConvertFromGLenum<ParamType>(sampler->getWrapS());
+            *params = CastFromGLintStateValue<ParamType>(pname, sampler->getWrapS());
             break;
         case GL_TEXTURE_WRAP_T:
-            *params = ConvertFromGLenum<ParamType>(sampler->getWrapT());
+            *params = CastFromGLintStateValue<ParamType>(pname, sampler->getWrapT());
             break;
         case GL_TEXTURE_WRAP_R:
-            *params = ConvertFromGLenum<ParamType>(sampler->getWrapR());
+            *params = CastFromGLintStateValue<ParamType>(pname, sampler->getWrapR());
             break;
         case GL_TEXTURE_MAX_ANISOTROPY_EXT:
-            *params = ConvertFromGLfloat<ParamType>(sampler->getMaxAnisotropy());
+            *params = CastFromStateValue<ParamType>(pname, sampler->getMaxAnisotropy());
             break;
         case GL_TEXTURE_MIN_LOD:
-            *params = ConvertFromGLfloat<ParamType>(sampler->getMinLod());
+            *params = CastFromStateValue<ParamType>(pname, sampler->getMinLod());
             break;
         case GL_TEXTURE_MAX_LOD:
-            *params = ConvertFromGLfloat<ParamType>(sampler->getMaxLod());
+            *params = CastFromStateValue<ParamType>(pname, sampler->getMaxLod());
             break;
         case GL_TEXTURE_COMPARE_MODE:
-            *params = ConvertFromGLenum<ParamType>(sampler->getCompareMode());
+            *params = CastFromGLintStateValue<ParamType>(pname, sampler->getCompareMode());
             break;
         case GL_TEXTURE_COMPARE_FUNC:
-            *params = ConvertFromGLenum<ParamType>(sampler->getCompareFunc());
+            *params = CastFromGLintStateValue<ParamType>(pname, sampler->getCompareFunc());
             break;
         case GL_TEXTURE_SRGB_DECODE_EXT:
-            *params = ConvertFromGLenum<ParamType>(sampler->getSRGBDecode());
+            *params = CastFromGLintStateValue<ParamType>(pname, sampler->getSRGBDecode());
             break;
         default:
             UNREACHABLE();
             break;
     }
 }
 
 template <typename ParamType>
 void SetSamplerParameterBase(Sampler *sampler, GLenum pname, const ParamType *params)
 {
     switch (pname)
     {
         case GL_TEXTURE_WRAP_S:
-            sampler->setWrapS(ConvertToGLenum(params[0]));
+            sampler->setWrapS(ConvertToGLenum(pname, params[0]));
             break;
         case GL_TEXTURE_WRAP_T:
-            sampler->setWrapT(ConvertToGLenum(params[0]));
+            sampler->setWrapT(ConvertToGLenum(pname, params[0]));
             break;
         case GL_TEXTURE_WRAP_R:
-            sampler->setWrapR(ConvertToGLenum(params[0]));
+            sampler->setWrapR(ConvertToGLenum(pname, params[0]));
             break;
         case GL_TEXTURE_MIN_FILTER:
-            sampler->setMinFilter(ConvertToGLenum(params[0]));
+            sampler->setMinFilter(ConvertToGLenum(pname, params[0]));
             break;
         case GL_TEXTURE_MAG_FILTER:
-            sampler->setMagFilter(ConvertToGLenum(params[0]));
+            sampler->setMagFilter(ConvertToGLenum(pname, params[0]));
             break;
         case GL_TEXTURE_MAX_ANISOTROPY_EXT:
-            sampler->setMaxAnisotropy(ConvertToGLfloat(params[0]));
+            sampler->setMaxAnisotropy(CastQueryValueTo<GLfloat>(pname, params[0]));
             break;
         case GL_TEXTURE_COMPARE_MODE:
-            sampler->setCompareMode(ConvertToGLenum(params[0]));
+            sampler->setCompareMode(ConvertToGLenum(pname, params[0]));
             break;
         case GL_TEXTURE_COMPARE_FUNC:
-            sampler->setCompareFunc(ConvertToGLenum(params[0]));
+            sampler->setCompareFunc(ConvertToGLenum(pname, params[0]));
             break;
         case GL_TEXTURE_MIN_LOD:
-            sampler->setMinLod(ConvertToGLfloat(params[0]));
+            sampler->setMinLod(CastQueryValueTo<GLfloat>(pname, params[0]));
             break;
         case GL_TEXTURE_MAX_LOD:
-            sampler->setMaxLod(ConvertToGLfloat(params[0]));
+            sampler->setMaxLod(CastQueryValueTo<GLfloat>(pname, params[0]));
             break;
         case GL_TEXTURE_SRGB_DECODE_EXT:
-            sampler->setSRGBDecode(ConvertToGLenum(params[0]));
+            sampler->setSRGBDecode(ConvertToGLenum(pname, params[0]));
             break;
         default:
             UNREACHABLE();
             break;
     }
 }
 
-template <typename ParamType, typename CurrentDataType>
-ParamType ConvertCurrentValue(CurrentDataType currentValue)
-{
-    return static_cast<ParamType>(currentValue);
-}
-
-template <>
-GLint ConvertCurrentValue(GLfloat currentValue)
-{
-    return iround<GLint>(currentValue);
-}
-
 // Warning: you should ensure binding really matches attrib.bindingIndex before using this function.
 template <typename ParamType, typename CurrentDataType, size_t CurrentValueCount>
 void QueryVertexAttribBase(const VertexAttribute &attrib,
                            const VertexBinding &binding,
                            const CurrentDataType (&currentValueData)[CurrentValueCount],
                            GLenum pname,
                            ParamType *params)
 {
     switch (pname)
     {
         case GL_CURRENT_VERTEX_ATTRIB:
             for (size_t i = 0; i < CurrentValueCount; ++i)
             {
-                params[i] = ConvertCurrentValue<ParamType>(currentValueData[i]);
+                params[i] = CastFromStateValue<ParamType>(pname, currentValueData[i]);
             }
             break;
         case GL_VERTEX_ATTRIB_ARRAY_ENABLED:
-            *params = ConvertFromGLboolean<ParamType>(attrib.enabled);
+            *params = CastFromStateValue<ParamType>(pname, static_cast<GLint>(attrib.enabled));
             break;
         case GL_VERTEX_ATTRIB_ARRAY_SIZE:
-            *params = ConvertFromGLuint<ParamType>(attrib.size);
+            *params = CastFromGLintStateValue<ParamType>(pname, attrib.size);
             break;
         case GL_VERTEX_ATTRIB_ARRAY_STRIDE:
-            *params = ConvertFromGLuint<ParamType>(attrib.vertexAttribArrayStride);
+            *params = CastFromGLintStateValue<ParamType>(pname, attrib.vertexAttribArrayStride);
             break;
         case GL_VERTEX_ATTRIB_ARRAY_TYPE:
-            *params = ConvertFromGLenum<ParamType>(attrib.type);
+            *params = CastFromGLintStateValue<ParamType>(pname, attrib.type);
             break;
         case GL_VERTEX_ATTRIB_ARRAY_NORMALIZED:
-            *params = ConvertFromGLboolean<ParamType>(attrib.normalized);
+            *params = CastFromStateValue<ParamType>(pname, static_cast<GLint>(attrib.normalized));
             break;
         case GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING:
-            *params = ConvertFromGLuint<ParamType>(binding.getBuffer().id());
+            *params = CastFromGLintStateValue<ParamType>(pname, binding.getBuffer().id());
             break;
         case GL_VERTEX_ATTRIB_ARRAY_DIVISOR:
-            *params = ConvertFromGLuint<ParamType>(binding.getDivisor());
+            *params = CastFromGLintStateValue<ParamType>(pname, binding.getDivisor());
             break;
         case GL_VERTEX_ATTRIB_ARRAY_INTEGER:
-            *params = ConvertFromGLboolean<ParamType>(attrib.pureInteger);
+            *params = CastFromGLintStateValue<ParamType>(pname, attrib.pureInteger);
             break;
         case GL_VERTEX_ATTRIB_BINDING:
-            *params = ConvertFromGLuint<ParamType>(attrib.bindingIndex);
+            *params = CastFromGLintStateValue<ParamType>(pname, attrib.bindingIndex);
             break;
         case GL_VERTEX_ATTRIB_RELATIVE_OFFSET:
-            *params = ConvertFromGLuint<ParamType>(attrib.relativeOffset);
+            *params = CastFromGLintStateValue<ParamType>(pname, attrib.relativeOffset);
             break;
         default:
             UNREACHABLE();
             break;
     }
 }
 
 template <typename ParamType>
 void QueryBufferParameterBase(const Buffer *buffer, GLenum pname, ParamType *params)
 {
     ASSERT(buffer != nullptr);
 
     switch (pname)
     {
         case GL_BUFFER_USAGE:
-            *params = ConvertFromGLenum<ParamType>(buffer->getUsage());
+            *params = CastFromGLintStateValue<ParamType>(pname, ToGLenum(buffer->getUsage()));
             break;
         case GL_BUFFER_SIZE:
-            *params = ConvertFromGLint64<ParamType>(buffer->getSize());
+            *params = CastFromStateValue<ParamType>(pname, buffer->getSize());
             break;
         case GL_BUFFER_ACCESS_FLAGS:
-            *params = ConvertFromGLuint<ParamType>(buffer->getAccessFlags());
+            *params = CastFromGLintStateValue<ParamType>(pname, buffer->getAccessFlags());
             break;
         case GL_BUFFER_ACCESS_OES:
-            *params = ConvertFromGLenum<ParamType>(buffer->getAccess());
+            *params = CastFromGLintStateValue<ParamType>(pname, buffer->getAccess());
             break;
         case GL_BUFFER_MAPPED:
-            *params = ConvertFromGLboolean<ParamType>(buffer->isMapped());
+            *params = CastFromStateValue<ParamType>(pname, buffer->isMapped());
             break;
         case GL_BUFFER_MAP_OFFSET:
-            *params = ConvertFromGLint64<ParamType>(buffer->getMapOffset());
+            *params = CastFromStateValue<ParamType>(pname, buffer->getMapOffset());
             break;
         case GL_BUFFER_MAP_LENGTH:
-            *params = ConvertFromGLint64<ParamType>(buffer->getMapLength());
+            *params = CastFromStateValue<ParamType>(pname, buffer->getMapLength());
             break;
         default:
             UNREACHABLE();
             break;
     }
 }
 
-GLint GetLocationVariableProperty(const sh::VariableWithLocation &var, GLenum prop)
+GLint GetCommonVariableProperty(const sh::ShaderVariable &var, GLenum prop)
 {
     switch (prop)
     {
         case GL_TYPE:
-            return ConvertToGLint(var.type);
+            return clampCast<GLint>(var.type);
 
         case GL_ARRAY_SIZE:
-            // TODO(jie.a.chen@intel.com): check array of array.
-            if (var.isArray() && !var.isStruct())
-            {
-                return ConvertToGLint(var.elementCount());
-            }
-            return 1;
+            // Queryable variables are guaranteed not to be arrays of arrays or arrays of structs,
+            // see GLES 3.1 spec section 7.3.1.1 page 77.
+            return clampCast<GLint>(var.getBasicTypeElementCount());
 
         case GL_NAME_LENGTH:
-        {
-            size_t length = var.name.size();
-            if (var.isArray())
-            {
-                // Counts "[0]".
-                length += 3;
-            }
             // ES31 spec p84: This counts the terminating null char.
-            ++length;
-            return ConvertToGLint(length);
-        }
-
-        case GL_LOCATION:
-            return var.location;
+            return clampCast<GLint>(var.name.size() + 1u);
 
         default:
             UNREACHABLE();
             return GL_INVALID_VALUE;
     }
 }
 
 GLint GetInputResourceProperty(const Program *program, GLuint index, GLenum prop)
 {
     const auto &attribute = program->getInputResource(index);
     switch (prop)
     {
         case GL_TYPE:
         case GL_ARRAY_SIZE:
+        case GL_NAME_LENGTH:
+            return GetCommonVariableProperty(attribute, prop);
+
         case GL_LOCATION:
-        case GL_NAME_LENGTH:
-            return GetLocationVariableProperty(attribute, prop);
+            return program->getAttributeLocation(attribute.name);
 
         case GL_REFERENCED_BY_VERTEX_SHADER:
             return 1;
 
         case GL_REFERENCED_BY_FRAGMENT_SHADER:
         case GL_REFERENCED_BY_COMPUTE_SHADER:
             return 0;
 
@@ -503,72 +486,100 @@ GLint GetInputResourceProperty(const Pro
 
 GLint GetOutputResourceProperty(const Program *program, GLuint index, const GLenum prop)
 {
     const auto &outputVariable = program->getOutputResource(index);
     switch (prop)
     {
         case GL_TYPE:
         case GL_ARRAY_SIZE:
+        case GL_NAME_LENGTH:
+            return GetCommonVariableProperty(outputVariable, prop);
+
         case GL_LOCATION:
-        case GL_NAME_LENGTH:
-            return GetLocationVariableProperty(outputVariable, prop);
+            return program->getFragDataLocation(outputVariable.name);
 
         case GL_REFERENCED_BY_VERTEX_SHADER:
             return 0;
 
         case GL_REFERENCED_BY_FRAGMENT_SHADER:
             return 1;
 
         case GL_REFERENCED_BY_COMPUTE_SHADER:
             return 0;
 
         default:
             UNREACHABLE();
             return GL_INVALID_VALUE;
     }
 }
 
+GLint GetTransformFeedbackVaryingResourceProperty(const Program *program,
+                                                  GLuint index,
+                                                  const GLenum prop)
+{
+    const auto &tfVariable = program->getTransformFeedbackVaryingResource(index);
+    switch (prop)
+    {
+        case GL_TYPE:
+            return clampCast<GLint>(tfVariable.type);
+
+        case GL_ARRAY_SIZE:
+            return clampCast<GLint>(tfVariable.size());
+
+        case GL_NAME_LENGTH:
+            return clampCast<GLint>(tfVariable.nameWithArrayIndex().size() + 1);
+
+        default:
+            UNREACHABLE();
+            return GL_INVALID_VALUE;
+    }
+}
+
 GLint QueryProgramInterfaceActiveResources(const Program *program, GLenum programInterface)
 {
     switch (programInterface)
     {
         case GL_PROGRAM_INPUT:
-            return ConvertToGLint(program->getAttributes().size());
+            return clampCast<GLint>(program->getAttributes().size());
 
         case GL_PROGRAM_OUTPUT:
-            return ConvertToGLint(program->getState().getOutputVariables().size());
+            return clampCast<GLint>(program->getState().getOutputVariables().size());
 
         case GL_UNIFORM:
-            return ConvertToGLint(program->getState().getUniforms().size());
+            return clampCast<GLint>(program->getState().getUniforms().size());
 
         case GL_UNIFORM_BLOCK:
-            return ConvertToGLint(program->getState().getUniformBlocks().size());
+            return clampCast<GLint>(program->getState().getUniformBlocks().size());
 
-        // TODO(jie.a.chen@intel.com): more interfaces.
-        case GL_TRANSFORM_FEEDBACK_VARYING:
+        case GL_ATOMIC_COUNTER_BUFFER:
+            return clampCast<GLint>(program->getState().getAtomicCounterBuffers().size());
+
         case GL_BUFFER_VARIABLE:
+            return clampCast<GLint>(program->getState().getBufferVariables().size());
+
         case GL_SHADER_STORAGE_BLOCK:
-        case GL_ATOMIC_COUNTER_BUFFER:
-            UNIMPLEMENTED();
-            return 0;
+            return clampCast<GLint>(program->getState().getShaderStorageBlocks().size());
+
+        case GL_TRANSFORM_FEEDBACK_VARYING:
+            return clampCast<GLint>(program->getTransformFeedbackVaryingCount());
 
         default:
             UNREACHABLE();
             return 0;
     }
 }
 
 template <typename T, typename M>
 GLint FindMaxSize(const std::vector<T> &resources, M member)
 {
     GLint max = 0;
     for (const T &resource : resources)
     {
-        max = std::max(max, ConvertToGLint((resource.*member).size()));
+        max = std::max(max, clampCast<GLint>((resource.*member).size()));
     }
     return max;
 }
 
 GLint QueryProgramInterfaceMaxNameLength(const Program *program, GLenum programInterface)
 {
     GLint maxNameLength = 0;
     switch (programInterface)
@@ -586,61 +597,221 @@ GLint QueryProgramInterfaceMaxNameLength
             maxNameLength = FindMaxSize(program->getState().getUniforms(), &LinkedUniform::name);
             break;
 
         case GL_UNIFORM_BLOCK:
             maxNameLength =
                 FindMaxSize(program->getState().getUniformBlocks(), &InterfaceBlock::name);
             break;
 
-        // TODO(jie.a.chen@intel.com): more interfaces.
+        case GL_BUFFER_VARIABLE:
+            maxNameLength =
+                FindMaxSize(program->getState().getBufferVariables(), &BufferVariable::name);
+            break;
+
+        case GL_SHADER_STORAGE_BLOCK:
+            maxNameLength =
+                FindMaxSize(program->getState().getShaderStorageBlocks(), &InterfaceBlock::name);
+            break;
+
         case GL_TRANSFORM_FEEDBACK_VARYING:
-        case GL_BUFFER_VARIABLE:
-        case GL_SHADER_STORAGE_BLOCK:
-            UNIMPLEMENTED();
-            return 0;
+            maxNameLength = clampCast<GLint>(program->getTransformFeedbackVaryingMaxLength() - 1);
+            break;
 
         default:
             UNREACHABLE();
             return 0;
     }
     // This length includes an extra character for the null terminator.
     return (maxNameLength == 0 ? 0 : maxNameLength + 1);
 }
 
 GLint QueryProgramInterfaceMaxNumActiveVariables(const Program *program, GLenum programInterface)
 {
     switch (programInterface)
     {
         case GL_UNIFORM_BLOCK:
             return FindMaxSize(program->getState().getUniformBlocks(),
                                &InterfaceBlock::memberIndexes);
+        case GL_ATOMIC_COUNTER_BUFFER:
+            return FindMaxSize(program->getState().getAtomicCounterBuffers(),
+                               &AtomicCounterBuffer::memberIndexes);
 
-        // TODO(jie.a.chen@intel.com): more interfaces.
         case GL_SHADER_STORAGE_BLOCK:
-        case GL_ATOMIC_COUNTER_BUFFER:
-            UNIMPLEMENTED();
-            return 0;
+            return FindMaxSize(program->getState().getShaderStorageBlocks(),
+                               &InterfaceBlock::memberIndexes);
 
         default:
             UNREACHABLE();
             return 0;
     }
 }
 
+GLenum GetUniformPropertyEnum(GLenum prop)
+{
+    switch (prop)
+    {
+        case GL_UNIFORM_TYPE:
+            return GL_TYPE;
+        case GL_UNIFORM_SIZE:
+            return GL_ARRAY_SIZE;
+        case GL_UNIFORM_NAME_LENGTH:
+            return GL_NAME_LENGTH;
+        case GL_UNIFORM_BLOCK_INDEX:
+            return GL_BLOCK_INDEX;
+        case GL_UNIFORM_OFFSET:
+            return GL_OFFSET;
+        case GL_UNIFORM_ARRAY_STRIDE:
+            return GL_ARRAY_STRIDE;
+        case GL_UNIFORM_MATRIX_STRIDE:
+            return GL_MATRIX_STRIDE;
+        case GL_UNIFORM_IS_ROW_MAJOR:
+            return GL_IS_ROW_MAJOR;
+
+        default:
+            return prop;
+    }
+}
+
+GLenum GetUniformBlockPropertyEnum(GLenum prop)
+{
+    switch (prop)
+    {
+        case GL_UNIFORM_BLOCK_BINDING:
+            return GL_BUFFER_BINDING;
+
+        case GL_UNIFORM_BLOCK_DATA_SIZE:
+            return GL_BUFFER_DATA_SIZE;
+
+        case GL_UNIFORM_BLOCK_NAME_LENGTH:
+            return GL_NAME_LENGTH;
+
+        case GL_UNIFORM_BLOCK_ACTIVE_UNIFORMS:
+            return GL_NUM_ACTIVE_VARIABLES;
+
+        case GL_UNIFORM_BLOCK_ACTIVE_UNIFORM_INDICES:
+            return GL_ACTIVE_VARIABLES;
+
+        case GL_UNIFORM_BLOCK_REFERENCED_BY_VERTEX_SHADER:
+            return GL_REFERENCED_BY_VERTEX_SHADER;
+
+        case GL_UNIFORM_BLOCK_REFERENCED_BY_FRAGMENT_SHADER:
+            return GL_REFERENCED_BY_FRAGMENT_SHADER;
+
+        default:
+            return prop;
+    }
+}
+
+void GetShaderVariableBufferResourceProperty(const ShaderVariableBuffer &buffer,
+                                             GLenum pname,
+                                             GLint *params,
+                                             GLsizei bufSize,
+                                             GLsizei *outputPosition)
+
+{
+    switch (pname)
+    {
+        case GL_BUFFER_BINDING:
+            params[(*outputPosition)++] = buffer.binding;
+            break;
+        case GL_BUFFER_DATA_SIZE:
+            params[(*outputPosition)++] = clampCast<GLint>(buffer.dataSize);
+            break;
+        case GL_NUM_ACTIVE_VARIABLES:
+            params[(*outputPosition)++] = buffer.numActiveVariables();
+            break;
+        case GL_ACTIVE_VARIABLES:
+            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);
+            break;
+        case GL_REFERENCED_BY_FRAGMENT_SHADER:
+            params[(*outputPosition)++] = static_cast<GLint>(buffer.fragmentStaticUse);
+            break;
+        case GL_REFERENCED_BY_COMPUTE_SHADER:
+            params[(*outputPosition)++] = static_cast<GLint>(buffer.computeStaticUse);
+            break;
+        default:
+            UNREACHABLE();
+            break;
+    }
+}
+
+void GetInterfaceBlockResourceProperty(const InterfaceBlock &block,
+                                       GLenum pname,
+                                       GLint *params,
+                                       GLsizei bufSize,
+                                       GLsizei *outputPosition)
+{
+    if (pname == GL_NAME_LENGTH)
+    {
+        params[(*outputPosition)++] = clampCast<GLint>(block.nameWithArrayIndex().size() + 1);
+        return;
+    }
+    GetShaderVariableBufferResourceProperty(block, pname, params, bufSize, outputPosition);
+}
+
+void GetUniformBlockResourceProperty(const Program *program,
+                                     GLuint blockIndex,
+                                     GLenum pname,
+                                     GLint *params,
+                                     GLsizei bufSize,
+                                     GLsizei *outputPosition)
+
+{
+    ASSERT(*outputPosition < bufSize);
+    const auto &block = program->getUniformBlockByIndex(blockIndex);
+    GetInterfaceBlockResourceProperty(block, pname, params, bufSize, outputPosition);
+}
+
+void GetShaderStorageBlockResourceProperty(const Program *program,
+                                           GLuint blockIndex,
+                                           GLenum pname,
+                                           GLint *params,
+                                           GLsizei bufSize,
+                                           GLsizei *outputPosition)
+
+{
+    ASSERT(*outputPosition < bufSize);
+    const auto &block = program->getShaderStorageBlockByIndex(blockIndex);
+    GetInterfaceBlockResourceProperty(block, pname, params, bufSize, outputPosition);
+}
+
+void GetAtomicCounterBufferResourceProperty(const Program *program,
+                                            GLuint index,
+                                            GLenum pname,
+                                            GLint *params,
+                                            GLsizei bufSize,
+                                            GLsizei *outputPosition)
+
+{
+    ASSERT(*outputPosition < bufSize);
+    const auto &buffer = program->getState().getAtomicCounterBuffers()[index];
+    GetShaderVariableBufferResourceProperty(buffer, pname, params, bufSize, outputPosition);
+}
+
 }  // anonymous namespace
 
-void QueryFramebufferAttachmentParameteriv(const Framebuffer *framebuffer,
+void QueryFramebufferAttachmentParameteriv(const Context *context,
+                                           const Framebuffer *framebuffer,
                                            GLenum attachment,
                                            GLenum pname,
                                            GLint *params)
 {
     ASSERT(framebuffer);
 
-    const FramebufferAttachment *attachmentObject = framebuffer->getAttachment(attachment);
+    const FramebufferAttachment *attachmentObject = framebuffer->getAttachment(context, attachment);
+
     if (attachmentObject == nullptr)
     {
         // ES 2.0.25 spec pg 127 states that if the value of FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE
         // is NONE, then querying any other pname will generate INVALID_ENUM.
 
         // ES 3.0.2 spec pg 235 states that if the attachment type is none,
         // GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME will return zero and be an
         // INVALID_OPERATION for all other pnames
@@ -811,27 +982,38 @@ void QueryProgramiv(const Context *conte
             return;
         case GL_ACTIVE_UNIFORM_BLOCK_MAX_NAME_LENGTH:
             *params = program->getActiveUniformBlockMaxLength();
             break;
         case GL_TRANSFORM_FEEDBACK_BUFFER_MODE:
             *params = program->getTransformFeedbackBufferMode();
             break;
         case GL_TRANSFORM_FEEDBACK_VARYINGS:
-            *params = program->getTransformFeedbackVaryingCount();
+            *params = clampCast<GLint>(program->getTransformFeedbackVaryingCount());
             break;
         case GL_TRANSFORM_FEEDBACK_VARYING_MAX_LENGTH:
             *params = program->getTransformFeedbackVaryingMaxLength();
             break;
         case GL_PROGRAM_BINARY_RETRIEVABLE_HINT:
             *params = program->getBinaryRetrievableHint();
             break;
         case GL_PROGRAM_SEPARABLE:
             *params = program->isSeparable();
             break;
+        case GL_COMPUTE_WORK_GROUP_SIZE:
+        {
+            const sh::WorkGroupSize &localSize = program->getComputeShaderLocalSize();
+            params[0]                          = localSize[0];
+            params[1]                          = localSize[1];
+            params[2]                          = localSize[2];
+        }
+        break;
+        case GL_ACTIVE_ATOMIC_COUNTER_BUFFERS:
+            *params = program->getActiveAtomicCounterBufferCount();
+            break;
         default:
             UNREACHABLE();
             break;
     }
 }
 
 void QueryRenderbufferiv(const Context *context,
                          const Renderbuffer *renderbuffer,
@@ -1005,59 +1187,29 @@ void QueryVertexAttribIuiv(const VertexA
     QueryVertexAttribBase(attrib, binding, currentValueData.UnsignedIntValues, pname, params);
 }
 
 void QueryActiveUniformBlockiv(const Program *program,
                                GLuint uniformBlockIndex,
                                GLenum pname,
                                GLint *params)
 {
-    const InterfaceBlock &uniformBlock = program->getUniformBlockByIndex(uniformBlockIndex);
-    switch (pname)
-    {
-        case GL_UNIFORM_BLOCK_BINDING:
-            *params = ConvertToGLint(program->getUniformBlockBinding(uniformBlockIndex));
-            break;
-        case GL_UNIFORM_BLOCK_DATA_SIZE:
-            *params = ConvertToGLint(uniformBlock.dataSize);
-            break;
-        case GL_UNIFORM_BLOCK_NAME_LENGTH:
-            *params = ConvertToGLint(uniformBlock.nameWithArrayIndex().size() + 1);
-            break;
-        case GL_UNIFORM_BLOCK_ACTIVE_UNIFORMS:
-            *params = ConvertToGLint(uniformBlock.memberIndexes.size());
-            break;
-        case GL_UNIFORM_BLOCK_ACTIVE_UNIFORM_INDICES:
-            for (size_t blockMemberIndex = 0; blockMemberIndex < uniformBlock.memberIndexes.size();
-                 blockMemberIndex++)
-            {
-                params[blockMemberIndex] =
-                    ConvertToGLint(uniformBlock.memberIndexes[blockMemberIndex]);
-            }
-            break;
-        case GL_UNIFORM_BLOCK_REFERENCED_BY_VERTEX_SHADER:
-            *params = ConvertToGLint(uniformBlock.vertexStaticUse);
-            break;
-        case GL_UNIFORM_BLOCK_REFERENCED_BY_FRAGMENT_SHADER:
-            *params = ConvertToGLint(uniformBlock.fragmentStaticUse);
-            break;
-        default:
-            UNREACHABLE();
-            break;
-    }
+    GLenum prop = GetUniformBlockPropertyEnum(pname);
+    QueryProgramResourceiv(program, GL_UNIFORM_BLOCK, uniformBlockIndex, 1, &prop,
+                           std::numeric_limits<GLsizei>::max(), nullptr, params);
 }
 
 void QueryInternalFormativ(const TextureCaps &format, GLenum pname, GLsizei bufSize, GLint *params)
 {
     switch (pname)
     {
         case GL_NUM_SAMPLE_COUNTS:
             if (bufSize != 0)
             {
-                *params = static_cast<GLint>(format.sampleCounts.size());
+                *params = clampCast<GLint>(format.sampleCounts.size());
             }
             break;
 
         case GL_SAMPLES:
         {
             size_t returnCount   = std::min<size_t>(bufSize, format.sampleCounts.size());
             auto sampleReverseIt = format.sampleCounts.rbegin();
             for (size_t sampleIndex = 0; sampleIndex < returnCount; ++sampleIndex)
@@ -1084,17 +1236,17 @@ void QueryFramebufferParameteriv(const F
             break;
         case GL_FRAMEBUFFER_DEFAULT_HEIGHT:
             *params = framebuffer->getDefaultHeight();
             break;
         case GL_FRAMEBUFFER_DEFAULT_SAMPLES:
             *params = framebuffer->getDefaultSamples();
             break;
         case GL_FRAMEBUFFER_DEFAULT_FIXED_SAMPLE_LOCATIONS:
-            *params = framebuffer->getDefaultFixedSampleLocations();
+            *params = ConvertToGLBoolean(framebuffer->getDefaultFixedSampleLocations());
             break;
         default:
             UNREACHABLE();
             break;
     }
 }
 
 Error QuerySynciv(const Sync *sync, GLenum pname, GLsizei bufSize, GLsizei *length, GLint *values)
@@ -1109,23 +1261,23 @@ Error QuerySynciv(const Sync *sync, GLen
             *length = 0;
         }
         return NoError();
     }
 
     switch (pname)
     {
         case GL_OBJECT_TYPE:
-            *values = ConvertToGLint(GL_SYNC_FENCE);
+            *values = clampCast<GLint>(GL_SYNC_FENCE);
             break;
         case GL_SYNC_CONDITION:
-            *values = ConvertToGLint(sync->getCondition());
+            *values = clampCast<GLint>(sync->getCondition());
             break;
         case GL_SYNC_FLAGS:
-            *values = ConvertToGLint(sync->getFlags());
+            *values = clampCast<GLint>(sync->getFlags());
             break;
         case GL_SYNC_STATUS:
             ANGLE_TRY(sync->getStatus(values));
             break;
 
         default:
             UNREACHABLE();
             break;
@@ -1190,62 +1342,161 @@ void SetFramebufferParameteri(Framebuffe
             break;
         case GL_FRAMEBUFFER_DEFAULT_HEIGHT:
             framebuffer->setDefaultHeight(param);
             break;
         case GL_FRAMEBUFFER_DEFAULT_SAMPLES:
             framebuffer->setDefaultSamples(param);
             break;
         case GL_FRAMEBUFFER_DEFAULT_FIXED_SAMPLE_LOCATIONS:
-            framebuffer->setDefaultFixedSampleLocations(static_cast<GLboolean>(param));
+            framebuffer->setDefaultFixedSampleLocations(ConvertToBool(param));
             break;
         default:
             UNREACHABLE();
             break;
     }
 }
 
 void SetProgramParameteri(Program *program, GLenum pname, GLint value)
 {
     ASSERT(program);
 
     switch (pname)
     {
         case GL_PROGRAM_BINARY_RETRIEVABLE_HINT:
-            program->setBinaryRetrievableHint(value != GL_FALSE);
+            program->setBinaryRetrievableHint(ConvertToBool(value));
             break;
         case GL_PROGRAM_SEPARABLE:
-            program->setSeparable(value != GL_FALSE);
+            program->setSeparable(ConvertToBool(value));
             break;
         default:
             UNREACHABLE();
             break;
     }
 }
 
+GLint GetUniformResourceProperty(const Program *program, GLuint index, const GLenum prop)
+{
+    const auto &uniform = program->getUniformByIndex(index);
+    GLenum resourceProp = GetUniformPropertyEnum(prop);
+    switch (resourceProp)
+    {
+        case GL_TYPE:
+        case GL_ARRAY_SIZE:
+        case GL_NAME_LENGTH:
+            return GetCommonVariableProperty(uniform, resourceProp);
+
+        case GL_LOCATION:
+            return program->getUniformLocation(uniform.name);
+
+        case GL_BLOCK_INDEX:
+            return (uniform.isAtomicCounter() ? -1 : uniform.bufferIndex);
+
+        case GL_OFFSET:
+            return uniform.blockInfo.offset;
+
+        case GL_ARRAY_STRIDE:
+            return uniform.blockInfo.arrayStride;
+
+        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;
+
+        case GL_REFERENCED_BY_FRAGMENT_SHADER:
+            return uniform.fragmentStaticUse;
+
+        case GL_REFERENCED_BY_COMPUTE_SHADER:
+            return uniform.computeStaticUse;
+
+        case GL_ATOMIC_COUNTER_BUFFER_INDEX:
+            return (uniform.isAtomicCounter() ? uniform.bufferIndex : -1);
+
+        default:
+            UNREACHABLE();
+            return 0;
+    }
+}
+
+GLint GetBufferVariableResourceProperty(const Program *program, GLuint index, const GLenum prop)
+{
+    const auto &bufferVariable = program->getBufferVariableByIndex(index);
+    switch (prop)
+    {
+        case GL_TYPE:
+        case GL_ARRAY_SIZE:
+        case GL_NAME_LENGTH:
+            return GetCommonVariableProperty(bufferVariable, prop);
+
+        case GL_BLOCK_INDEX:
+            return bufferVariable.bufferIndex;
+
+        case GL_OFFSET:
+            return bufferVariable.blockInfo.offset;
+
+        case GL_ARRAY_STRIDE:
+            return bufferVariable.blockInfo.arrayStride;
+
+        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;
+
+        case GL_REFERENCED_BY_FRAGMENT_SHADER:
+            return bufferVariable.fragmentStaticUse;
+
+        case GL_REFERENCED_BY_COMPUTE_SHADER:
+            return bufferVariable.computeStaticUse;
+
+        case GL_TOP_LEVEL_ARRAY_SIZE:
+            return bufferVariable.topLevelArraySize;
+
+        case GL_TOP_LEVEL_ARRAY_STRIDE:
+            return bufferVariable.blockInfo.topLevelArrayStride;
+
+        default:
+            UNREACHABLE();
+            return 0;
+    }
+}
+
 GLuint QueryProgramResourceIndex(const Program *program,
                                  GLenum programInterface,
                                  const GLchar *name)
 {
     switch (programInterface)
     {
         case GL_PROGRAM_INPUT:
             return program->getInputResourceIndex(name);
 
         case GL_PROGRAM_OUTPUT:
             return program->getOutputResourceIndex(name);
 
-        // TODO(jie.a.chen@intel.com): more interfaces.
         case GL_UNIFORM:
+            return program->getState().getUniformIndexFromName(name);
+
+        case GL_BUFFER_VARIABLE:
+            return program->getState().getBufferVariableIndexFromName(name);
+
+        case GL_SHADER_STORAGE_BLOCK:
+            return program->getShaderStorageBlockIndex(name);
+
         case GL_UNIFORM_BLOCK:
+            return program->getUniformBlockIndex(name);
+
         case GL_TRANSFORM_FEEDBACK_VARYING:
-        case GL_BUFFER_VARIABLE:
-        case GL_SHADER_STORAGE_BLOCK:
-            UNIMPLEMENTED();
-            return GL_INVALID_INDEX;
+            return program->getTransformFeedbackVaryingResourceIndex(name);
 
         default:
             UNREACHABLE();
             return GL_INVALID_INDEX;
     }
 }
 
 void QueryProgramResourceName(const Program *program,
@@ -1260,23 +1511,34 @@ void QueryProgramResourceName(const Prog
         case GL_PROGRAM_INPUT:
             program->getInputResourceName(index, bufSize, length, name);
             break;
 
         case GL_PROGRAM_OUTPUT:
             program->getOutputResourceName(index, bufSize, length, name);
             break;
 
-        // TODO(jie.a.chen@intel.com): more interfaces.
         case GL_UNIFORM:
+            program->getUniformResourceName(index, bufSize, length, name);
+            break;
+
+        case GL_BUFFER_VARIABLE:
+            program->getBufferVariableResourceName(index, bufSize, length, name);
+            break;
+
+        case GL_SHADER_STORAGE_BLOCK:
+            program->getActiveShaderStorageBlockName(index, bufSize, length, name);
+            break;
+
         case GL_UNIFORM_BLOCK:
+            program->getActiveUniformBlockName(index, bufSize, length, name);
+            break;
+
         case GL_TRANSFORM_FEEDBACK_VARYING:
-        case GL_BUFFER_VARIABLE:
-        case GL_SHADER_STORAGE_BLOCK:
-            UNIMPLEMENTED();
+            program->getTransformFeedbackVarying(index, bufSize, length, nullptr, nullptr, name);
             break;
 
         default:
             UNREACHABLE();
     }
 }
 
 GLint QueryProgramResourceLocation(const Program *program,
@@ -1286,24 +1548,18 @@ GLint QueryProgramResourceLocation(const
     switch (programInterface)
     {
         case GL_PROGRAM_INPUT:
             return program->getAttributeLocation(name);
 
         case GL_PROGRAM_OUTPUT:
             return program->getFragDataLocation(name);
 
-        // TODO(jie.a.chen@intel.com): more interfaces.
         case GL_UNIFORM:
-        case GL_UNIFORM_BLOCK:
-        case GL_TRANSFORM_FEEDBACK_VARYING:
-        case GL_BUFFER_VARIABLE:
-        case GL_SHADER_STORAGE_BLOCK:
-            UNIMPLEMENTED();
-            return -1;
+            return program->getUniformLocation(name);
 
         default:
             UNREACHABLE();
             return -1;
     }
 }
 
 void QueryProgramResourceiv(const Program *program,
@@ -1319,49 +1575,75 @@ void QueryProgramResourceiv(const Progra
     {
         if (length != nullptr)
         {
             *length = 0;
         }
         return;
     }
 
-    GLsizei count = std::min(propCount, bufSize);
-    if (length != nullptr)
-    {
-        *length = count;
-    }
-
-    for (GLsizei i = 0; i < count; i++)
+    GLsizei pos = 0;
+    for (GLsizei i = 0; i < propCount; i++)
     {
         switch (programInterface)
         {
             case GL_PROGRAM_INPUT:
                 params[i] = GetInputResourceProperty(program, index, props[i]);
+                ++pos;
                 break;
 
             case GL_PROGRAM_OUTPUT:
                 params[i] = GetOutputResourceProperty(program, index, props[i]);
+                ++pos;
+                break;
+
+            case GL_UNIFORM:
+                params[i] = GetUniformResourceProperty(program, index, props[i]);
+                ++pos;
+                break;
+
+            case GL_BUFFER_VARIABLE:
+                params[i] = GetBufferVariableResourceProperty(program, index, props[i]);
+                ++pos;
                 break;
 
-            // TODO(jie.a.chen@intel.com): more interfaces.
-            case GL_UNIFORM:
             case GL_UNIFORM_BLOCK:
+                GetUniformBlockResourceProperty(program, index, props[i], params, bufSize, &pos);
+                break;
+
+            case GL_SHADER_STORAGE_BLOCK:
+                GetShaderStorageBlockResourceProperty(program, index, props[i], params, bufSize,
+                                                      &pos);
+                break;
+
+            case GL_ATOMIC_COUNTER_BUFFER:
+                GetAtomicCounterBufferResourceProperty(program, index, props[i], params, bufSize,
+                                                       &pos);
+                break;
+
             case GL_TRANSFORM_FEEDBACK_VARYING:
-            case GL_BUFFER_VARIABLE:
-            case GL_SHADER_STORAGE_BLOCK:
-            case GL_ATOMIC_COUNTER_BUFFER:
-                UNIMPLEMENTED();
-                params[i] = GL_INVALID_VALUE;
+                params[i] = GetTransformFeedbackVaryingResourceProperty(program, index, props[i]);
+                ++pos;
                 break;
 
             default:
                 UNREACHABLE();
                 params[i] = GL_INVALID_VALUE;
         }
+        if (pos == bufSize)
+        {
+            // Most properties return one value, but GL_ACTIVE_VARIABLES returns an array of values.
+            // This checks not to break buffer bounds for such case.
+            break;
+        }
+    }
+
+    if (length != nullptr)
+    {
+        *length = pos;
     }
 }
 
 void QueryProgramInterfaceiv(const Program *program,
                              GLenum programInterface,
                              GLenum pname,
                              GLint *params)
 {
@@ -1501,16 +1783,41 @@ void QueryConfigAttrib(const Config *con
             *value = config->colorComponentType;
             break;
         default:
             UNREACHABLE();
             break;
     }
 }
 
+void QueryContextAttrib(const gl::Context *context, EGLint attribute, EGLint *value)
+{
+    switch (attribute)
+    {
+        case EGL_CONFIG_ID:
+            *value = context->getConfig()->configID;
+            break;
+        case EGL_CONTEXT_CLIENT_TYPE:
+            *value = context->getClientType();
+            break;
+        case EGL_CONTEXT_CLIENT_VERSION:
+            *value = context->getClientMajorVersion();
+            break;
+        case EGL_RENDER_BUFFER:
+            *value = context->getRenderBuffer();
+            break;
+        case EGL_ROBUST_RESOURCE_INITIALIZATION_ANGLE:
+            *value = context->isRobustResourceInitEnabled();
+            break;
+        default:
+            UNREACHABLE();
+            break;
+    }
+}
+
 void QuerySurfaceAttrib(const Surface *surface, EGLint attribute, EGLint *value)
 {
     switch (attribute)
     {
         case EGL_GL_COLORSPACE:
             *value = surface->getGLColorspace();
             break;
         case EGL_VG_ALPHA_FORMAT:
@@ -1591,16 +1898,19 @@ void QuerySurfaceAttrib(const Surface *s
             *value = surface->flexibleSurfaceCompatibilityRequested();
             break;
         case EGL_SURFACE_ORIENTATION_ANGLE:
             *value = surface->getOrientation();
             break;
         case EGL_DIRECT_COMPOSITION_ANGLE:
             *value = surface->directComposition();
             break;
+        case EGL_ROBUST_RESOURCE_INITIALIZATION_ANGLE:
+            *value = surface->isRobustResourceInitEnabled();
+            break;
         default:
             UNREACHABLE();
             break;
     }
 }
 
 void SetSurfaceAttrib(Surface *surface, EGLint attribute, EGLint value)
 {
--- a/gfx/angle/src/libANGLE/queryutils.h
+++ b/gfx/angle/src/libANGLE/queryutils.h
@@ -27,17 +27,18 @@ class Sampler;
 class Shader;
 class Texture;
 struct TextureCaps;
 struct UniformBlock;
 struct VertexAttribute;
 class VertexBinding;
 struct VertexAttribCurrentValueData;
 
-void QueryFramebufferAttachmentParameteriv(const Framebuffer *framebuffer,
+void QueryFramebufferAttachmentParameteriv(const Context *context,
+                                           const Framebuffer *framebuffer,
                                            GLenum attachment,
                                            GLenum pname,
                                            GLint *params);
 void QueryBufferParameteriv(const Buffer *buffer, GLenum pname, GLint *params);
 void QueryBufferParameteri64v(const Buffer *buffer, GLenum pname, GLint64 *params);
 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,
@@ -108,16 +109,18 @@ void SetSamplerParameterf(Sampler *sampl
 void SetSamplerParameterfv(Sampler *sampler, GLenum pname, const GLfloat *params);
 void SetSamplerParameteri(Sampler *sampler, GLenum pname, GLint param);
 void SetSamplerParameteriv(Sampler *sampler, GLenum pname, const GLint *params);
 
 void SetFramebufferParameteri(Framebuffer *framebuffer, GLenum pname, GLint param);
 
 void SetProgramParameteri(Program *program, GLenum pname, GLint value);
 
+GLint GetUniformResourceProperty(const Program *program, GLuint index, const GLenum prop);
+
 GLuint QueryProgramResourceIndex(const Program *program,
                                  GLenum programInterface,
                                  const GLchar *name);
 
 void QueryProgramResourceName(const Program *program,
                               GLenum programInterface,
                               GLuint index,
                               GLsizei bufSize,
@@ -145,14 +148,16 @@ void QueryProgramInterfaceiv(const Progr
 
 namespace egl
 {
 struct Config;
 class Surface;
 
 void QueryConfigAttrib(const Config *config, EGLint attribute, EGLint *value);
 
+void QueryContextAttrib(const gl::Context *context, EGLint attribute, EGLint *value);
+
 void QuerySurfaceAttrib(const Surface *surface, EGLint attribute, EGLint *value);
 void SetSurfaceAttrib(Surface *surface, EGLint attribute, EGLint value);
 
 }  // namespace egl
 
 #endif  // LIBANGLE_QUERYUTILS_H_
--- a/gfx/angle/src/libANGLE/renderer/BufferImpl.h
+++ b/gfx/angle/src/libANGLE/renderer/BufferImpl.h
@@ -7,16 +7,17 @@
 // 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/PackedGLEnums.h"
 
 #include <stdint.h>
 
 namespace gl
 {
 class BufferState;
 class Context;
 }
@@ -26,25 +27,25 @@ namespace rx
 class BufferImpl : angle::NonCopyable
 {
   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,
-                              GLenum target,
+                              gl::BufferBinding target,
                               const void *data,
                               size_t size,
-                              GLenum usage) = 0;
+                              gl::BufferUsage usage)                                = 0;
     virtual gl::Error setSubData(const gl::Context *context,
-                                 GLenum target,
+                                 gl::BufferBinding target,
                                  const void *data,
                                  size_t size,
-                                 size_t offset) = 0;
+                                 size_t offset)                                     = 0;
     virtual gl::Error copySubData(const gl::Context *context,
                                   BufferImpl *source,
                                   GLintptr sourceOffset,
                                   GLintptr destOffset,
                                   GLsizeiptr size) = 0;
     virtual gl::Error map(const gl::Context *context, GLenum access, void **mapPtr) = 0;
     virtual gl::Error mapRange(const gl::Context *context,
                                size_t offset,
--- a/gfx/angle/src/libANGLE/renderer/BufferImpl_mock.h
+++ b/gfx/angle/src/libANGLE/renderer/BufferImpl_mock.h
@@ -17,18 +17,21 @@
 namespace rx
 {
 class MockBufferImpl : public BufferImpl
 {
   public:
     MockBufferImpl() : BufferImpl(mMockState) {}
     ~MockBufferImpl() { destructor(); }
 
-    MOCK_METHOD5(setData, gl::Error(const gl::Context *, GLenum, const void *, size_t, GLenum));
-    MOCK_METHOD5(setSubData, gl::Error(const gl::Context *, GLenum, const void *, size_t, size_t));
+    MOCK_METHOD5(
+        setData,
+        gl::Error(const gl::Context *, gl::BufferBinding, const void *, size_t, gl::BufferUsage));
+    MOCK_METHOD5(setSubData,
+                 gl::Error(const gl::Context *, gl::BufferBinding, const void *, size_t, size_t));
     MOCK_METHOD5(
         copySubData,
         gl::Error(const gl::Context *contextImpl, BufferImpl *, GLintptr, GLintptr, GLsizeiptr));
     MOCK_METHOD3(map, gl::Error(const gl::Context *contextImpl, GLenum, void **));
     MOCK_METHOD5(mapRange,
                  gl::Error(const gl::Context *contextImpl, size_t, size_t, GLbitfield, void **));
     MOCK_METHOD2(unmap, gl::Error(const gl::Context *contextImpl, GLboolean *result));
 
--- a/gfx/angle/src/libANGLE/renderer/ContextImpl.h
+++ b/gfx/angle/src/libANGLE/renderer/ContextImpl.h
@@ -24,23 +24,25 @@ struct Workarounds;
 }
 
 namespace rx
 {
 class ContextImpl : public GLImplFactory
 {
   public:
     ContextImpl(const gl::ContextState &state);
-    virtual ~ContextImpl();
+    ~ContextImpl() override;
+
+    virtual void onDestroy(const gl::Context *context) {}
 
     virtual gl::Error initialize() = 0;
 
     // Flush and finish.
-    virtual gl::Error flush()  = 0;
-    virtual gl::Error finish() = 0;
+    virtual gl::Error flush(const gl::Context *context)  = 0;
+    virtual gl::Error finish(const gl::Context *context) = 0;
 
     // Drawing methods.
     virtual gl::Error drawArrays(const gl::Context *context,
                                  GLenum mode,
                                  GLint first,
                                  GLsizei count) = 0;
     virtual gl::Error drawArraysInstanced(const gl::Context *context,
                                           GLenum mode,
@@ -123,21 +125,25 @@ class ContextImpl : public GLImplFactory
 
     // Device loss
     virtual GLenum getResetStatus() = 0;
 
     // Vendor and description strings.
     virtual std::string getVendorString() const        = 0;
     virtual std::string getRendererDescription() const = 0;
 
-    // Debug markers.
+    // EXT_debug_marker
     virtual void insertEventMarker(GLsizei length, const char *marker) = 0;
     virtual void pushGroupMarker(GLsizei length, const char *marker)   = 0;
     virtual void popGroupMarker() = 0;
 
+    // KHR_debug
+    virtual void pushDebugGroup(GLenum source, GLuint id, GLsizei length, const char *message) = 0;
+    virtual void popDebugGroup()                                                               = 0;
+
     // State sync with dirty bits.
     virtual void syncState(const gl::Context *context, const gl::State::DirtyBits &dirtyBits) = 0;
 
     // Disjoint timer queries
     virtual GLint getGPUDisjoint() = 0;
     virtual GLint64 getTimestamp() = 0;
 
     // Context switching
@@ -150,16 +156,20 @@ class ContextImpl : public GLImplFactory
     virtual const gl::Limitations &getNativeLimitations() const    = 0;
 
     virtual void applyNativeWorkarounds(gl::Workarounds *workarounds) const {}
 
     virtual gl::Error dispatchCompute(const gl::Context *context,
                                       GLuint numGroupsX,
                                       GLuint numGroupsY,
                                       GLuint numGroupsZ) = 0;
+    virtual gl::Error dispatchComputeIndirect(const gl::Context *context, GLintptr indirect) = 0;
+
+    virtual gl::Error memoryBarrier(const gl::Context *context, GLbitfield barriers)         = 0;
+    virtual gl::Error memoryBarrierByRegion(const gl::Context *context, GLbitfield barriers) = 0;
 
     const gl::ContextState &getContextState() { return mState; }
     int getClientMajorVersion() const { return mState.getClientMajorVersion(); }
     int getClientMinorVersion() const { return mState.getClientMinorVersion(); }
     const gl::State &getGLState() const { return mState.getState(); }
     const gl::Caps &getCaps() const { return mState.getCaps(); }
     const gl::TextureCapsMap &getTextureCaps() const { return mState.getTextureCaps(); }
     const gl::Extensions &getExtensions() const { return mState.getExtensions(); }
--- a/gfx/angle/src/libANGLE/renderer/DisplayImpl.h
+++ b/gfx/angle/src/libANGLE/renderer/DisplayImpl.h
@@ -43,17 +43,17 @@ class ImageImpl;
 struct ConfigDesc;
 class DeviceImpl;
 class StreamProducerImpl;
 
 class DisplayImpl : public EGLImplFactory
 {
   public:
     DisplayImpl(const egl::DisplayState &state);
-    virtual ~DisplayImpl();
+    ~DisplayImpl() override;
 
     virtual egl::Error initialize(egl::Display *display) = 0;
     virtual void terminate() = 0;
 
     virtual egl::Error makeCurrent(egl::Surface *drawSurface, egl::Surface *readSurface, gl::Context *context) = 0;
 
     virtual egl::ConfigSet generateConfigs() = 0;
 
--- a/gfx/angle/src/libANGLE/renderer/EGLImplFactory.h
+++ b/gfx/angle/src/libANGLE/renderer/EGLImplFactory.h
@@ -53,16 +53,16 @@ class EGLImplFactory : angle::NonCopyabl
                                              const egl::AttributeMap &attribs) = 0;
 
     virtual ImageImpl *createImage(const egl::ImageState &state,
                                    EGLenum target,
                                    const egl::AttributeMap &attribs) = 0;
 
     virtual ContextImpl *createContext(const gl::ContextState &state) = 0;
 
-    virtual StreamProducerImpl *createStreamProducerD3DTextureNV12(
+    virtual StreamProducerImpl *createStreamProducerD3DTexture(
         egl::Stream::ConsumerType consumerType,
         const egl::AttributeMap &attribs) = 0;
 };
 
 }  // namespace rx
 
 #endif  // LIBANGLE_RENDERER_EGLIMPLFACTORY_H_
--- a/gfx/angle/src/libANGLE/renderer/Format.h
+++ b/gfx/angle/src/libANGLE/renderer/Format.h
@@ -7,17 +7,16 @@
 //   A universal description of typed GPU storage. Across multiple
 //   renderer back-ends, there are common formats and some distinct
 //   permutations, this enum encapsulates them all. Formats apply to
 //   textures, but could also apply to any typed data.
 
 #ifndef LIBANGLE_RENDERER_FORMAT_H_
 #define LIBANGLE_RENDERER_FORMAT_H_
 
-#include "libANGLE/formatutils.h"
 #include "libANGLE/renderer/renderer_utils.h"
 
 namespace angle
 {
 
 struct Format final : private angle::NonCopyable
 {
     enum class ID;
--- a/gfx/angle/src/libANGLE/renderer/Format_ID_autogen.inl
+++ b/gfx/angle/src/libANGLE/renderer/Format_ID_autogen.inl
@@ -1,12 +1,12 @@
 // GENERATED FILE - DO NOT EDIT.
 // Generated by gen_angle_format_table.py using data from angle_format_data.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.
 //
 // ANGLE format enumeration.
 
 namespace angle
 {
 
@@ -43,16 +43,17 @@ enum class Format::ID
     ASTC_8x6_SRGB_BLOCK,
     ASTC_8x6_UNORM_BLOCK,
     ASTC_8x8_SRGB_BLOCK,
     ASTC_8x8_UNORM_BLOCK,
     B4G4R4A4_UNORM,
     B5G5R5A1_UNORM,
     B5G6R5_UNORM,
     B8G8R8A8_UNORM,
+    B8G8R8A8_UNORM_SRGB,
     B8G8R8X8_UNORM,
     BC1_RGBA_UNORM_BLOCK,
     BC1_RGBA_UNORM_SRGB_BLOCK,
     BC1_RGB_UNORM_BLOCK,
     BC1_RGB_UNORM_SRGB_BLOCK,
     BC2_RGBA_UNORM_BLOCK,
     BC2_RGBA_UNORM_SRGB_BLOCK,
     BC3_RGBA_UNORM_BLOCK,
@@ -62,16 +63,18 @@ enum class Format::ID
     D24_UNORM_S8_UINT,
     D32_FLOAT,
     D32_FLOAT_S8X24_UINT,
     D32_UNORM,
     EAC_R11G11_SNORM_BLOCK,
     EAC_R11G11_UNORM_BLOCK,
     EAC_R11_SNORM_BLOCK,
     EAC_R11_UNORM_BLOCK,
+    ETC1_LOSSY_DECODE_R8G8B8_UNORM_BLOCK,
+    ETC1_R8G8B8_UNORM_BLOCK,
     ETC2_R8G8B8A1_SRGB_BLOCK,
     ETC2_R8G8B8A1_UNORM_BLOCK,
     ETC2_R8G8B8A8_SRGB_BLOCK,
     ETC2_R8G8B8A8_UNORM_BLOCK,
     ETC2_R8G8B8_SRGB_BLOCK,
     ETC2_R8G8B8_UNORM_BLOCK,
     L16A16_FLOAT,
     L16_FLOAT,
@@ -134,9 +137,11 @@ enum class Format::ID
     R8_SINT,
     R8_SNORM,
     R8_UINT,
     R8_UNORM,
     R9G9B9E5_SHAREDEXP,
     S8_UINT
 };
 
+constexpr uint32_t kNumANGLEFormats = 128;
+
 }  // namespace angle
--- a/gfx/angle/src/libANGLE/renderer/Format_table_autogen.cpp
+++ b/gfx/angle/src/libANGLE/renderer/Format_table_autogen.cpp
@@ -1,12 +1,12 @@
 // GENERATED FILE - DO NOT EDIT.
 // Generated by gen_angle_format_table.py using data from angle_format_data.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.
 //
 // ANGLE Format table:
 //   Queries for typed format information from the ANGLE format enum.
 
 #include "libANGLE/renderer/Format.h"
 
@@ -55,16 +55,17 @@ constexpr Format g_formatInfoTable[] = {
     { 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_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 },
@@ -74,16 +75,18 @@ constexpr Format g_formatInfoTable[] = {
     { 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 },
@@ -152,148 +155,278 @@ constexpr Format g_formatInfoTable[] = {
     // clang-format on
 };
 
 // static
 Format::ID Format::InternalFormatToID(GLenum internalFormat)
 {
     switch (internalFormat)
     {
-        // clang-format off
-        case GL_RGBA16_EXT: return Format::ID::R16G16B16A16_UNORM;
-        case GL_ETC1_RGB8_LOSSY_DECODE_ANGLE: return Format::ID::NONE;
-        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_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_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_SRGB_ALPHA_S3TC_DXT1_EXT: return Format::ID::BC1_RGBA_UNORM_SRGB_BLOCK;
-        case GL_LUMINANCE32F_EXT: return Format::ID::L32_FLOAT;
-        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_RGB16_SNORM_EXT: return Format::ID::R16G16B16_SNORM;
-        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_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_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_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_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::NONE;
-        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_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_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;
-        default: return Format::ID::NONE;
-            // clang-format on
+        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_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_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_SRGB_ALPHA_S3TC_DXT1_EXT:
+            return Format::ID::BC1_RGBA_UNORM_SRGB_BLOCK;
+        case GL_LUMINANCE32F_EXT:
+            return Format::ID::L32_FLOAT;
+        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_RGB16_SNORM_EXT:
+            return Format::ID::R16G16B16_SNORM;
+        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_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_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_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_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_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;
+        default:
+            return Format::ID::NONE;
     }
 }
 
 // static
 const Format &Format::Get(ID id)
 {
     return g_formatInfoTable[static_cast<size_t>(id)];
 }
--- a/gfx/angle/src/libANGLE/renderer/FramebufferAttachmentObjectImpl.h
+++ b/gfx/angle/src/libANGLE/renderer/FramebufferAttachmentObjectImpl.h
@@ -20,18 +20,35 @@ class FramebufferAttachmentObjectImpl : 
 {
   public:
     FramebufferAttachmentObjectImpl() {}
     virtual ~FramebufferAttachmentObjectImpl() {}
 
     virtual gl::Error getAttachmentRenderTarget(const gl::Context *context,
                                                 GLenum binding,
                                                 const gl::ImageIndex &imageIndex,
-                                                FramebufferAttachmentRenderTarget **rtOut)
-    {
-        UNIMPLEMENTED();
-        return gl::OutOfMemory() << "getAttachmentRenderTarget not supported.";
-    }
+                                                FramebufferAttachmentRenderTarget **rtOut);
+
+    virtual gl::Error initializeContents(const gl::Context *context,
+                                         const gl::ImageIndex &imageIndex);
 };
 
+inline gl::Error FramebufferAttachmentObjectImpl::getAttachmentRenderTarget(
+    const gl::Context *context,
+    GLenum binding,
+    const gl::ImageIndex &imageIndex,
+    FramebufferAttachmentRenderTarget **rtOut)
+{
+    UNIMPLEMENTED();
+    return gl::OutOfMemory() << "getAttachmentRenderTarget not supported.";
+}
+
+inline gl::Error FramebufferAttachmentObjectImpl::initializeContents(
+    const gl::Context *context,
+    const gl::ImageIndex &imageIndex)
+{
+    UNIMPLEMENTED();
+    return gl::OutOfMemory() << "initialize not supported.";
+}
+
 }  // namespace rx
 
 #endif  // LIBANGLE_RENDERER_FRAMEBUFFER_ATTACHMENT_OBJECT_IMPL_H_
--- a/gfx/angle/src/libANGLE/renderer/FramebufferImpl.h
+++ b/gfx/angle/src/libANGLE/renderer/FramebufferImpl.h
@@ -73,17 +73,17 @@ class FramebufferImpl : angle::NonCopyab
                                  void *pixels) = 0;
 
     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 = 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 getSamplePosition(size_t index, GLfloat *xy) const = 0;
 
     const gl::FramebufferState &getState() const { return mState; }
 
--- a/gfx/angle/src/libANGLE/renderer/FramebufferImpl_mock.h
+++ b/gfx/angle/src/libANGLE/renderer/FramebufferImpl_mock.h
@@ -43,29 +43,29 @@ class MockFramebufferImpl : public rx::F
 
     MOCK_METHOD5(blit,
                  gl::Error(const gl::Context *,
                            const gl::Rectangle &,
                            const gl::Rectangle &,
                            GLbitfield,
                            GLenum));
 
-    MOCK_CONST_METHOD0(checkStatus, bool());
+    MOCK_CONST_METHOD1(checkStatus, bool(const gl::Context *));
 
     MOCK_METHOD2(syncState, void(const gl::Context *, const gl::Framebuffer::DirtyBits &));
 
     MOCK_METHOD0(destructor, void());
 };
 
 inline ::testing::NiceMock<MockFramebufferImpl> *MakeFramebufferMock()
 {
     ::testing::NiceMock<MockFramebufferImpl> *framebufferImpl =
         new ::testing::NiceMock<MockFramebufferImpl>();
     // TODO(jmadill): add ON_CALLS for other returning methods
-    ON_CALL(*framebufferImpl, checkStatus()).WillByDefault(::testing::Return(true));
+    ON_CALL(*framebufferImpl, checkStatus(testing::_)).WillByDefault(::testing::Return(true));
 
     // We must mock the destructor since NiceMock doesn't work for destructors.
     EXPECT_CALL(*framebufferImpl, destructor()).Times(1).RetiresOnSaturation();
 
     return framebufferImpl;
 }
 
 }  // namespace rx
--- a/gfx/angle/src/libANGLE/renderer/ProgramImpl.h
+++ b/gfx/angle/src/libANGLE/renderer/ProgramImpl.h
@@ -15,44 +15,43 @@
 #include "libANGLE/Program.h"
 #include "libANGLE/Shader.h"
 
 #include <map>
 
 namespace gl
 {
 class Context;
-class VaryingPacking;
+struct ProgramLinkedResources;
 }
 
 namespace sh
 {
 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::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;
 
     virtual gl::LinkResult link(const gl::Context *context,
-                                const gl::VaryingPacking &packing,
-                                gl::InfoLog &infoLog) = 0;
+                                const gl::ProgramLinkedResources &resources,
+                                gl::InfoLog &infoLog)                      = 0;
     virtual GLboolean validate(const gl::Caps &caps, gl::InfoLog *infoLog) = 0;
 
     virtual void setUniform1fv(GLint location, GLsizei count, const GLfloat *v) = 0;
     virtual void setUniform2fv(GLint location, GLsizei count, const GLfloat *v) = 0;
     virtual void setUniform3fv(GLint location, GLsizei count, const GLfloat *v) = 0;
     virtual void setUniform4fv(GLint location, GLsizei count, const GLfloat *v) = 0;
     virtual void setUniform1iv(GLint location, GLsizei count, const GLint *v) = 0;
     virtual void setUniform2iv(GLint location, GLsizei count, const GLint *v) = 0;
@@ -79,45 +78,30 @@ class ProgramImpl : angle::NonCopyable
     virtual void getUniformiv(const gl::Context *context, GLint location, GLint *params) const = 0;
     virtual void getUniformuiv(const gl::Context *context,
                                GLint location,
                                GLuint *params) const = 0;
 
     // TODO: synchronize in syncState when dirty bits exist.
     virtual void setUniformBlockBinding(GLuint uniformBlockIndex, GLuint uniformBlockBinding) = 0;
 
-    // May only be called after a successful link operation.
-    // Return false for inactive blocks.
-    virtual bool getUniformBlockSize(const std::string &blockName,
-                                     const std::string &blockMappedName,
-                                     size_t *sizeOut) const = 0;
-
-    // May only be called after a successful link operation.
-    // Returns false for inactive members.
-    virtual bool getUniformBlockMemberInfo(const std::string &memberUniformName,
-                                           const std::string &memberUniformMappedName,
-                                           sh::BlockMemberInfo *memberInfoOut) const = 0;
     // CHROMIUM_path_rendering
     // Set parameters to control fragment shader input variable interpolation
     virtual void setPathFragmentInputGen(const std::string &inputName,
                                          GLenum genMode,
                                          GLint components,
                                          const GLfloat *coeffs) = 0;
 
     // Implementation-specific method for ignoring unreferenced uniforms. Some implementations may
     // perform more extensive analysis and ignore some locations that ANGLE doesn't detect as
     // unreferenced. This method is not required to be overriden by a back-end.
     virtual void markUnusedUniformLocations(std::vector<gl::VariableLocation> *uniformLocations,
                                             std::vector<gl::SamplerBinding> *samplerBindings)
     {
     }
 
-    virtual void ensureUniformBlocksInitialized()
-    {
-    }
-
   protected:
     const gl::ProgramState &mState;
 };
 
 }  // namespace rx
 
 #endif // LIBANGLE_RENDERER_PROGRAMIMPL_H_
--- a/gfx/angle/src/libANGLE/renderer/ProgramImpl_mock.h
+++ b/gfx/angle/src/libANGLE/renderer/ProgramImpl_mock.h
@@ -7,16 +7,17 @@
 //   Defines a mock of the ProgramImpl class.
 //
 
 #ifndef LIBANGLE_RENDERER_PROGRAMIMPLMOCK_H_
 #define LIBANGLE_RENDERER_PROGRAMIMPLMOCK_H_
 
 #include "gmock/gmock.h"
 
+#include "libANGLE/ProgramLinkedResources.h"
 #include "libANGLE/renderer/ProgramImpl.h"
 
 namespace rx
 {
 
 class MockProgramImpl : public rx::ProgramImpl
 {
   public:
@@ -24,17 +25,19 @@ class MockProgramImpl : public rx::Progr
     virtual ~MockProgramImpl() { destructor(); }
 
     MOCK_METHOD3(load, gl::LinkResult(const gl::Context *, gl::InfoLog &, gl::BinaryInputStream *));
     MOCK_METHOD2(save, void(const gl::Context *, gl::BinaryOutputStream *));
     MOCK_METHOD1(setBinaryRetrievableHint, void(bool));
     MOCK_METHOD1(setSeparable, void(bool));
 
     MOCK_METHOD3(link,
-                 gl::LinkResult(const gl::Context *, const gl::VaryingPacking &, gl::InfoLog &));
+                 gl::LinkResult(const gl::Context *,
+                                const gl::ProgramLinkedResources &,
+                                gl::InfoLog &));
     MOCK_METHOD2(validate, GLboolean(const gl::Caps &, gl::InfoLog *));
 
     MOCK_METHOD3(setUniform1fv, void(GLint, GLsizei, const GLfloat *));
     MOCK_METHOD3(setUniform2fv, void(GLint, GLsizei, const GLfloat *));
     MOCK_METHOD3(setUniform3fv, void(GLint, GLsizei, const GLfloat *));
     MOCK_METHOD3(setUniform4fv, void(GLint, GLsizei, const GLfloat *));
     MOCK_METHOD3(setUniform1iv, void(GLint, GLsizei, const GLint *));
     MOCK_METHOD3(setUniform2iv, void(GLint, GLsizei, const GLint *));
@@ -55,20 +58,16 @@ class MockProgramImpl : public rx::Progr
     MOCK_METHOD4(setUniformMatrix3x4fv, void(GLint, GLsizei, GLboolean, const GLfloat *));
     MOCK_METHOD4(setUniformMatrix4x3fv, void(GLint, GLsizei, GLboolean, const GLfloat *));
 
     MOCK_CONST_METHOD3(getUniformfv, void(const gl::Context *, GLint, GLfloat *));
     MOCK_CONST_METHOD3(getUniformiv, void(const gl::Context *, GLint, GLint *));
     MOCK_CONST_METHOD3(getUniformuiv, void(const gl::Context *, GLint, GLuint *));
 
     MOCK_METHOD2(setUniformBlockBinding, void(GLuint, GLuint));
-    MOCK_CONST_METHOD3(getUniformBlockSize,
-                       bool(const std::string &, const std::string &, size_t *));
-    MOCK_CONST_METHOD3(getUniformBlockMemberInfo,
-                       bool(const std::string &, const std::string &, sh::BlockMemberInfo *));
     MOCK_METHOD4(setPathFragmentInputGen,
                  void(const std::string &, GLenum, GLint, const GLfloat *));
 
     MOCK_METHOD0(destructor, void());
 };
 
 inline ::testing::NiceMock<MockProgramImpl> *MakeProgramMock()
 {
--- a/gfx/angle/src/libANGLE/renderer/RenderbufferImpl.h
+++ b/gfx/angle/src/libANGLE/renderer/RenderbufferImpl.h
@@ -21,26 +21,30 @@ class Image;
 
 namespace rx
 {
 
 class RenderbufferImpl : public FramebufferAttachmentObjectImpl
 {
   public:
     RenderbufferImpl() {}
-    virtual ~RenderbufferImpl() {}
-    virtual gl::Error onDestroy(const gl::Context *context) { return gl::NoError(); }
+    ~RenderbufferImpl() override {}
+    virtual gl::Error onDestroy(const gl::Context *context);
 
     virtual gl::Error setStorage(const gl::Context *context,
                                  GLenum internalformat,
                                  size_t width,
                                  size_t height) = 0;
     virtual gl::Error setStorageMultisample(const gl::Context *context,
                                             size_t samples,
                                             GLenum internalformat,
                                             size_t width,
                                             size_t height) = 0;
     virtual gl::Error setStorageEGLImageTarget(const gl::Context *context, egl::Image *image) = 0;
 };
 
+inline gl::Error RenderbufferImpl::onDestroy(const gl::Context *context)
+{
+    return gl::NoError();
+}
 }
 
 #endif   // LIBANGLE_RENDERER_RENDERBUFFERIMPL_H_
--- a/gfx/angle/src/libANGLE/renderer/StreamProducerImpl.h
+++ b/gfx/angle/src/libANGLE/renderer/StreamProducerImpl.h
@@ -18,21 +18,22 @@ namespace rx
 class StreamProducerImpl : angle::NonCopyable
 {
   public:
     explicit StreamProducerImpl() {}
     virtual ~StreamProducerImpl() {}
 
     // Validates the ability for the producer to accept an arbitrary pointer to a frame. All
     // pointers should be validated through this function before being used to produce a frame.
-    virtual egl::Error validateD3DNV12Texture(void *pointer, const egl::AttributeMap &attributes) const = 0;
+    virtual egl::Error validateD3DTexture(void *pointer,
+                                          const egl::AttributeMap &attributes) const = 0;
 
     // Constructs a frame from an arbitrary external pointer that points to producer specific frame
     // data. Replaces the internal frame with the new one.
-    virtual void postD3DNV12Texture(void *pointer, const egl::AttributeMap &attributes) = 0;
+    virtual void postD3DTexture(void *pointer, const egl::AttributeMap &attributes) = 0;
 
     // Returns an OpenGL texture interpretation of some frame attributes for the purpose of
     // constructing an OpenGL texture from a frame. Depending on the producer and consumer, some
     // frames may have multiple "planes" with different OpenGL texture representations.
     virtual egl::Stream::GLTextureDescription getGLFrameDescription(int planeIndex) = 0;
 };
 }  // namespace rx
 
--- a/gfx/angle/src/libANGLE/renderer/SurfaceImpl.h
+++ b/gfx/angle/src/libANGLE/renderer/SurfaceImpl.h
@@ -33,17 +33,17 @@ class Thread;
 namespace rx
 {
 class FramebufferImpl;
 
 class SurfaceImpl : public FramebufferAttachmentObjectImpl
 {
   public:
     SurfaceImpl(const egl::SurfaceState &surfaceState);
-    virtual ~SurfaceImpl();
+    ~SurfaceImpl() override;
     virtual void destroy(const egl::Display *display) {}
 
     virtual egl::Error initialize(const egl::Display *display)                           = 0;
     virtual FramebufferImpl *createDefaultFramebuffer(const gl::FramebufferState &state) = 0;
     virtual egl::Error swap(const gl::Context *context)                                  = 0;
     virtual egl::Error swapWithDamage(const gl::Context *context, EGLint *rects, EGLint n_rects);
     virtual egl::Error postSubBuffer(const gl::Context *context,
                                      EGLint x,
--- a/gfx/angle/src/libANGLE/renderer/TextureImpl.cpp
+++ b/gfx/angle/src/libANGLE/renderer/TextureImpl.cpp
@@ -14,16 +14,21 @@ namespace rx
 TextureImpl::TextureImpl(const gl::TextureState &state) : mState(state)
 {
 }
 
 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,
                                    GLenum internalFormat,
                                    GLenum type,
                                    size_t sourceLevel,
                                    bool unpackFlipY,
                                    bool unpackPremultiplyAlpha,
--- a/gfx/angle/src/libANGLE/renderer/TextureImpl.h
+++ b/gfx/angle/src/libANGLE/renderer/TextureImpl.h
@@ -39,19 +39,19 @@ struct TextureState;
 namespace rx
 {
 class ContextImpl;
 
 class TextureImpl : public FramebufferAttachmentObjectImpl
 {
   public:
     TextureImpl(const gl::TextureState &state);
-    virtual ~TextureImpl();
+    ~TextureImpl() override;
 
-    virtual gl::Error onDestroy(const gl::Context *context) { return gl::NoError(); }
+    virtual gl::Error onDestroy(const gl::Context *context);
 
     virtual gl::Error setImage(const gl::Context *context,
                                GLenum target,
                                size_t level,
                                GLenum internalFormat,
                                const gl::Extents &size,
                                GLenum format,
                                GLenum type,
@@ -125,17 +125,17 @@ class TextureImpl : public FramebufferAt
                                  GLenum internalFormat,
                                  const gl::Extents &size) = 0;
 
     virtual gl::Error setStorageMultisample(const gl::Context *context,
                                             GLenum target,
                                             GLsizei samples,
                                             GLint internalformat,
                                             const gl::Extents &size,
-                                            GLboolean fixedSampleLocations) = 0;
+                                            bool fixedSampleLocations) = 0;
 
     virtual gl::Error setEGLImageTarget(const gl::Context *context,
                                         GLenum target,
                                         egl::Image *image) = 0;
 
     virtual gl::Error setImageExternal(const gl::Context *context,
                                        GLenum target,
                                        egl::Stream *stream,
--- a/gfx/angle/src/libANGLE/renderer/TextureImpl_mock.h
+++ b/gfx/angle/src/libANGLE/renderer/TextureImpl_mock.h
@@ -108,19 +108,18 @@ class MockTextureImpl : public TextureIm
     MOCK_METHOD1(releaseTexImage, gl::Error(const gl::Context *));
 
     MOCK_METHOD4(getAttachmentRenderTarget,
                  gl::Error(const gl::Context *,
                            GLenum,
                            const gl::ImageIndex &,
                            FramebufferAttachmentRenderTarget **));
 
-    MOCK_METHOD6(
-        setStorageMultisample,
-        gl::Error(const gl::Context *, GLenum, GLsizei, GLint, const gl::Extents &, GLboolean));
+    MOCK_METHOD6(setStorageMultisample,
+                 gl::Error(const gl::Context *, GLenum, GLsizei, GLint, const gl::Extents &, bool));
 
     MOCK_METHOD2(setBaseLevel, gl::Error(const gl::Context *, GLuint));
 
     MOCK_METHOD1(syncState, void(const gl::Texture::DirtyBits &));
 
     MOCK_METHOD0(destructor, void());
 
   protected:
--- a/gfx/angle/src/libANGLE/renderer/VertexArrayImpl.h
+++ b/gfx/angle/src/libANGLE/renderer/VertexArrayImpl.h
@@ -15,23 +15,23 @@
 
 namespace rx
 {
 class ContextImpl;
 
 class VertexArrayImpl : angle::NonCopyable
 {
   public:
-    VertexArrayImpl(const gl::VertexArrayState &data) : mData(data) {}
+    VertexArrayImpl(const gl::VertexArrayState &state) : mState(state) {}
     virtual void syncState(const gl::Context *context, const gl::VertexArray::DirtyBits &dirtyBits)
     {
     }
 
     virtual void destroy(const gl::Context *context) {}
     virtual ~VertexArrayImpl() {}
 
   protected:
-    const gl::VertexArrayState &mData;
+    const gl::VertexArrayState &mState;
 };
 
 }
 
 #endif // LIBANGLE_RENDERER_VERTEXARRAYIMPL_H_
--- a/gfx/angle/src/libANGLE/renderer/angle_format.py
+++ b/gfx/angle/src/libANGLE/renderer/angle_format.py
@@ -16,19 +16,17 @@ def reject_duplicate_keys(pairs):
         if key in found_keys:
            raise ValueError("duplicate key: %r" % (key,))
         else:
            found_keys[key] = value
     return found_keys
 
 def load_json(path):
     with open(path) as map_file:
-        file_data = map_file.read()
-        map_file.close()
-        return json.loads(file_data, object_pairs_hook=reject_duplicate_keys)
+        return json.loads(map_file.read(), object_pairs_hook=reject_duplicate_keys)
 
 def load_forward_table(path):
     pairs = load_json(path)
     reject_duplicate_keys(pairs)
     return { gl: angle for gl, angle in pairs }
 
 def load_inverse_table(path):
     pairs = load_json(path)
--- a/gfx/angle/src/libANGLE/renderer/angle_format_map.json
+++ b/gfx/angle/src/libANGLE/renderer/angle_format_map.json
@@ -1,16 +1,17 @@
 [
   [ "GL_ALPHA16F_EXT", "A16_FLOAT" ],
   [ "GL_ALPHA32F_EXT", "A32_FLOAT" ],
   [ "GL_ALPHA8_EXT", "A8_UNORM" ],
   [ "GL_BGR565_ANGLEX", "B5G6R5_UNORM" ],
   [ "GL_BGR5_A1_ANGLEX", "B5G5R5A1_UNORM" ],
   [ "GL_BGRA4_ANGLEX", "B4G4R4A4_UNORM" ],
   [ "GL_BGRA8_EXT", "B8G8R8A8_UNORM" ],
+  [ "GL_BGRA8_SRGB_ANGLEX", "B8G8R8A8_UNORM_SRGB"],
   [ "GL_BGRX8_ANGLEX", "B8G8R8X8_UNORM" ],
   [ "GL_COMPRESSED_R11_EAC", "EAC_R11_UNORM_BLOCK" ],
   [ "GL_COMPRESSED_RG11_EAC", "EAC_R11G11_UNORM_BLOCK" ],
   [ "GL_COMPRESSED_RGB8_ETC2", "ETC2_R8G8B8_UNORM_BLOCK" ],
   [ "GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2", "ETC2_R8G8B8A1_UNORM_BLOCK" ],
   [ "GL_COMPRESSED_RGBA8_ETC2_EAC", "ETC2_R8G8B8A8_UNORM_BLOCK" ],
   [ "GL_COMPRESSED_RGBA_S3TC_DXT1_EXT", "BC1_RGBA_UNORM_BLOCK" ],
   [ "GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE", "BC2_RGBA_UNORM_BLOCK" ],
@@ -54,18 +55,18 @@
   [ "GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT", "BC3_RGBA_UNORM_SRGB_BLOCK" ],
   [ "GL_COMPRESSED_SRGB_S3TC_DXT1_EXT", "BC1_RGB_UNORM_SRGB_BLOCK" ],
   [ "GL_DEPTH24_STENCIL8", "D24_UNORM_S8_UINT" ],
   [ "GL_DEPTH32F_STENCIL8", "D32_FLOAT_S8X24_UINT" ],
   [ "GL_DEPTH_COMPONENT16", "D16_UNORM" ],
   [ "GL_DEPTH_COMPONENT24", "D24_UNORM" ],
   [ "GL_DEPTH_COMPONENT32F", "D32_FLOAT" ],
   [ "GL_DEPTH_COMPONENT32_OES", "D32_UNORM" ],
-  [ "GL_ETC1_RGB8_OES", "NONE" ],
-  [ "GL_ETC1_RGB8_LOSSY_DECODE_ANGLE", "NONE" ],
+  [ "GL_ETC1_RGB8_OES", "ETC1_R8G8B8_UNORM_BLOCK" ],
+  [ "GL_ETC1_RGB8_LOSSY_DECODE_ANGLE", "ETC1_LOSSY_DECODE_R8G8B8_UNORM_BLOCK" ],
   [ "GL_LUMINANCE16F_EXT", "L16_FLOAT" ],
   [ "GL_LUMINANCE32F_EXT", "L32_FLOAT" ],
   [ "GL_LUMINANCE8_ALPHA8_EXT", "L8A8_UNORM" ],
   [ "GL_LUMINANCE8_EXT", "L8_UNORM" ],
   [ "GL_LUMINANCE_ALPHA16F_EXT", "L16A16_FLOAT" ],
   [ "GL_LUMINANCE_ALPHA32F_EXT", "L32A32_FLOAT" ],
   [ "GL_NONE", "NONE" ],
   [ "GL_R11F_G11F_B10F", "R11G11B10_FLOAT" ],
--- a/gfx/angle/src/libANGLE/renderer/d3d/BufferD3D.cpp
+++ b/gfx/angle/src/libANGLE/renderer/d3d/BufferD3D.cpp
@@ -42,45 +42,45 @@ void BufferD3D::emptyStaticBufferCache()
     mStaticBufferCacheTotalSize = 0;
 }
 
 void BufferD3D::updateSerial()
 {
     mSerial = mNextSerial++;
 }
 
-void BufferD3D::updateD3DBufferUsage(const gl::Context *context, GLenum usage)
+void BufferD3D::updateD3DBufferUsage(const gl::Context *context, gl::BufferUsage usage)
 {
     switch (usage)
     {
-        case GL_STATIC_DRAW:
-        case GL_STATIC_READ:
-        case GL_STATIC_COPY:
+        case gl::BufferUsage::StaticCopy:
+        case gl::BufferUsage::StaticDraw:
+        case gl::BufferUsage::StaticRead:
             mUsage = D3DBufferUsage::STATIC;
             initializeStaticData(context);
             break;
 
-        case GL_STREAM_DRAW:
-        case GL_STREAM_READ:
-        case GL_STREAM_COPY:
-        case GL_DYNAMIC_READ:
-        case GL_DYNAMIC_COPY:
-        case GL_DYNAMIC_DRAW:
+        case gl::BufferUsage::DynamicCopy:
+        case gl::BufferUsage::DynamicDraw:
+        case gl::BufferUsage::DynamicRead:
+        case gl::BufferUsage::StreamCopy:
+        case gl::BufferUsage::StreamDraw:
+        case gl::BufferUsage::StreamRead:
             mUsage = D3DBufferUsage::DYNAMIC;
             break;
         default:
             UNREACHABLE();
     }
 }
 
 void BufferD3D::initializeStaticData(const gl::Context *context)
 {
     if (mStaticVertexBuffers.empty())
     {
-        auto newStaticBuffer = new StaticVertexBufferInterface(mFactory);
+        StaticVertexBufferInterface *newStaticBuffer = new StaticVertexBufferInterface(mFactory);
         mStaticVertexBuffers.push_back(
             std::unique_ptr<StaticVertexBufferInterface>(newStaticBuffer));
     }
     if (!mStaticIndexBuffer)
     {
         mStaticIndexBuffer = new StaticIndexBufferInterface(mFactory);
     }
 }
@@ -129,17 +129,17 @@ StaticVertexBufferInterface *BufferD3D::
     // in the same draw call. It will not delete currently bound buffers, however, because they
     // are ref counted.
     if (currentTotalSize > sizeThreshold)
     {
         emptyStaticBufferCache();
     }
 
     // At this point, we must create a new static buffer for the attribute data.
-    auto newStaticBuffer = new StaticVertexBufferInterface(mFactory);
+    StaticVertexBufferInterface *newStaticBuffer = new StaticVertexBufferInterface(mFactory);
     newStaticBuffer->setAttribute(attribute, binding);
     mStaticVertexBuffers.push_back(std::unique_ptr<StaticVertexBufferInterface>(newStaticBuffer));
     return newStaticBuffer;
 }
 
 void BufferD3D::invalidateStaticData(const gl::Context *context)
 {
     emptyStaticBufferCache();
@@ -163,17 +163,17 @@ void BufferD3D::invalidateStaticData(con
 void BufferD3D::promoteStaticUsage(const gl::Context *context, int dataSize)
 {
     if (mUsage == D3DBufferUsage::DYNAMIC)
     {
         mUnmodifiedDataUse += dataSize;
 
         if (mUnmodifiedDataUse > 3 * getSize())
         {
-            updateD3DBufferUsage(context, GL_STATIC_DRAW);
+            updateD3DBufferUsage(context, gl::BufferUsage::StaticDraw);
         }
     }
 }
 
 gl::Error BufferD3D::getIndexRange(const gl::Context *context,
                                    GLenum type,
                                    size_t offset,
                                    size_t count,
--- a/gfx/angle/src/libANGLE/renderer/d3d/BufferD3D.h
+++ b/gfx/angle/src/libANGLE/renderer/d3d/BufferD3D.h
@@ -32,17 +32,17 @@ enum class D3DBufferUsage
     STATIC,
     DYNAMIC,
 };
 
 class BufferD3D : public BufferImpl
 {
   public:
     BufferD3D(const gl::BufferState &state, BufferFactoryD3D *factory);
-    virtual ~BufferD3D();
+    ~BufferD3D() override;
 
     unsigned int getSerial() const { return mSerial; }
 
     virtual size_t getSize() const = 0;
     virtual bool supportsDirectBinding() const = 0;
     virtual gl::Error markTransformFeedbackUsage(const gl::Context *context) = 0;
     virtual gl::Error getData(const gl::Context *context, const uint8_t **outData) = 0;
 
@@ -64,17 +64,17 @@ class BufferD3D : public BufferImpl
                             bool primitiveRestartEnabled,
                             gl::IndexRange *outRange) override;
 
     BufferFactoryD3D *getFactory() const { return mFactory; }
     D3DBufferUsage getUsage() const { return mUsage; }
 
   protected:
     void updateSerial();
-    void updateD3DBufferUsage(const gl::Context *context, GLenum usage);
+    void updateD3DBufferUsage(const gl::Context *context, gl::BufferUsage usage);
     void emptyStaticBufferCache();
 
     BufferFactoryD3D *mFactory;
     unsigned int mSerial;
     static unsigned int mNextSerial;
 
     std::vector<std::unique_ptr<StaticVertexBufferInterface>> mStaticVertexBuffers;
     StaticIndexBufferInterface *mStaticIndexBuffer;
--- a/gfx/angle/src/libANGLE/renderer/d3d/CompilerD3D.cpp
+++ b/gfx/angle/src/libANGLE/renderer/d3d/CompilerD3D.cpp
@@ -12,9 +12,19 @@
 namespace rx
 {
 
 CompilerD3D::CompilerD3D(ShShaderOutput translatorOutputType)
     : mTranslatorOutputType(translatorOutputType)
 {
 }
 
+gl::Error CompilerD3D::release()
+{
+    return gl::NoError();
+}
+
+ShShaderOutput CompilerD3D::getTranslatorOutputType() const
+{
+    return mTranslatorOutputType;
+}
+
 }  // namespace rx
--- a/gfx/angle/src/libANGLE/renderer/d3d/CompilerD3D.h
+++ b/gfx/angle/src/libANGLE/renderer/d3d/CompilerD3D.h
@@ -16,18 +16,18 @@ namespace rx
 {
 
 class CompilerD3D : public CompilerImpl
 {
   public:
     CompilerD3D(ShShaderOutput translatorOutputType);
     ~CompilerD3D() override {}
 
-    gl::Error release() override { return gl::NoError(); }
-    ShShaderOutput getTranslatorOutputType() const override { return mTranslatorOutputType; }
+    gl::Error release() override;
+    ShShaderOutput getTranslatorOutputType() const override;
 
   private:
     ShShaderOutput mTranslatorOutputType;
 };
 
 }
 
 #endif // LIBANGLE_RENDERER_COMPILERD3D_H_
--- a/gfx/angle/src/libANGLE/renderer/d3d/DeviceD3D.cpp
+++ b/gfx/angle/src/libANGLE/renderer/d3d/DeviceD3D.cpp
@@ -93,9 +93,13 @@ EGLint DeviceD3D::getType()
     return mDeviceType;
 }
 
 void DeviceD3D::generateExtensions(egl::DeviceExtensions *outExtensions) const
 {
     outExtensions->deviceD3D = true;
 }
 
+bool DeviceD3D::deviceExternallySourced()
+{
+    return mDeviceExternallySourced;
 }
+}
--- a/gfx/angle/src/libANGLE/renderer/d3d/DeviceD3D.h
+++ b/gfx/angle/src/libANGLE/renderer/d3d/DeviceD3D.h
@@ -20,17 +20,17 @@ class DeviceD3D : public DeviceImpl
   public:
     DeviceD3D();
     ~DeviceD3D() override;
 
     egl::Error initialize(void *device, EGLint deviceType, EGLBoolean external);
     egl::Error getDevice(void **outValue) override;
     EGLint getType() override;
     void generateExtensions(egl::DeviceExtensions *outExtensions) const override;
-    bool deviceExternallySourced() override { return mDeviceExternallySourced; }
+    bool deviceExternallySourced() override;
 
   private:
     void *mDevice;
     EGLint mDeviceType;
     bool mDeviceExternallySourced;
     bool mIsInitialized;
 };
 
--- a/gfx/angle/src/libANGLE/renderer/d3d/DisplayD3D.cpp
+++ b/gfx/angle/src/libANGLE/renderer/d3d/DisplayD3D.cpp
@@ -201,22 +201,22 @@ egl::Error DisplayD3D::getDevice(DeviceI
 }
 
 ContextImpl *DisplayD3D::createContext(const gl::ContextState &state)
 {
     ASSERT(mRenderer != nullptr);
     return mRenderer->createContext(state);
 }
 
-StreamProducerImpl *DisplayD3D::createStreamProducerD3DTextureNV12(
+StreamProducerImpl *DisplayD3D::createStreamProducerD3DTexture(
     egl::Stream::ConsumerType consumerType,
     const egl::AttributeMap &attribs)
 {
     ASSERT(mRenderer != nullptr);
-    return mRenderer->createStreamProducerD3DTextureNV12(consumerType, attribs);
+    return mRenderer->createStreamProducerD3DTexture(consumerType, attribs);
 }
 
 egl::Error DisplayD3D::makeCurrent(egl::Surface *drawSurface, egl::Surface *readSurface, gl::Context *context)
 {
     return egl::NoError();
 }
 
 egl::Error DisplayD3D::initialize(egl::Display *display)
@@ -242,33 +242,33 @@ bool DisplayD3D::testDeviceLost()
 {
     ASSERT(mRenderer != nullptr);
     return mRenderer->testDeviceLost();
 }
 
 egl::Error DisplayD3D::restoreLostDevice(const egl::Display *display)
 {
     // Release surface resources to make the Reset() succeed
-    for (auto &surface : mState.surfaceSet)
+    for (egl::Surface *surface : mState.surfaceSet)
     {
         if (surface->getBoundTexture())
         {
             ANGLE_TRY(surface->releaseTexImage(display->getProxyContext(), EGL_BACK_BUFFER));
         }
         SurfaceD3D *surfaceD3D = GetImplAs<SurfaceD3D>(surface);
         surfaceD3D->releaseSwapChain();
     }
 
     if (!mRenderer->resetDevice())
     {
         return egl::EglBadAlloc();
     }
 
     // Restore any surfaces that may have been lost
-    for (const auto &surface : mState.surfaceSet)
+    for (const egl::Surface *surface : mState.surfaceSet)
     {
         SurfaceD3D *surfaceD3D = GetImplAs<SurfaceD3D>(surface);
 
         ANGLE_TRY(surfaceD3D->resetSwapChain(display));
     }
 
     return egl::NoError();
 }
@@ -319,17 +319,17 @@ void DisplayD3D::generateCaps(egl::Caps 
     // Display must be initialized to generate caps
     ASSERT(mRenderer != nullptr);
 
     outCaps->textureNPOT = mRenderer->getNativeExtensions().textureNPOT;
 }
 
 egl::Error DisplayD3D::waitClient(const gl::Context *context) const
 {
-    for (auto &surface : mState.surfaceSet)
+    for (egl::Surface *surface : mState.surfaceSet)
     {
         SurfaceD3D *surfaceD3D = GetImplAs<SurfaceD3D>(surface);
         ANGLE_TRY(surfaceD3D->checkForOutOfDateSwapChain(context));
     }
 
     return egl::NoError();
 }
 
--- a/gfx/angle/src/libANGLE/renderer/d3d/DisplayD3D.h
+++ b/gfx/angle/src/libANGLE/renderer/d3d/DisplayD3D.h
@@ -17,17 +17,17 @@ namespace rx
 class RendererD3D;
 
 class DisplayD3D : public DisplayImpl
 {
   public:
     DisplayD3D(const egl::DisplayState &state);
 
     egl::Error initialize(egl::Display *display) override;
-    virtual void terminate() override;
+    void terminate() override;
 
     // Surface creation
     SurfaceImpl *createWindowSurface(const egl::SurfaceState &state,
                                      EGLNativeWindowType window,
                                      const egl::AttributeMap &attribs) override;
     SurfaceImpl *createPbufferSurface(const egl::SurfaceState &state,
                                       const egl::AttributeMap &attribs) override;
     SurfaceImpl *createPbufferFromClientBuffer(const egl::SurfaceState &state,
@@ -39,19 +39,18 @@ class DisplayD3D : public DisplayImpl
                                      const egl::AttributeMap &attribs) override;
 
     ImageImpl *createImage(const egl::ImageState &state,
                            EGLenum target,
                            const egl::AttributeMap &attribs) override;
 
     ContextImpl *createContext(const gl::ContextState &state) override;
 
-    StreamProducerImpl *createStreamProducerD3DTextureNV12(
-        egl::Stream::ConsumerType consumerType,
-        const egl::AttributeMap &attribs) override;
+    StreamProducerImpl *createStreamProducerD3DTexture(egl::Stream::ConsumerType consumerType,
+                                                       const egl::AttributeMap &attribs) override;
 
     egl::Error makeCurrent(egl::Surface *drawSurface, egl::Surface *readSurface, gl::Context *context) override;
 
     egl::ConfigSet generateConfigs() override;
 
     bool testDeviceLost() override;
     egl::Error restoreLostDevice(const egl::Display *display) override;
 
--- a/gfx/angle/src/libANGLE/renderer/d3d/DynamicHLSL.cpp
+++ b/gfx/angle/src/libANGLE/renderer/d3d/DynamicHLSL.cpp
@@ -3,16 +3,17 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 //
 // DynamicHLSL.cpp: Implementation for link and run-time HLSL generation
 //
 
 #include "libANGLE/renderer/d3d/DynamicHLSL.h"
 
+#include "common/string_utils.h"
 #include "common/utilities.h"
 #include "compiler/translator/blocklayoutHLSL.h"
 #include "libANGLE/Context.h"
 #include "libANGLE/Program.h"
 #include "libANGLE/Shader.h"
 #include "libANGLE/VaryingPacking.h"
 #include "libANGLE/formatutils.h"
 #include "libANGLE/renderer/d3d/ProgramD3D.h"
@@ -143,16 +144,21 @@ void WriteArrayString(std::ostringstream
     strstr << i;
     strstr << "]";
 }
 
 constexpr const char *VERTEX_ATTRIBUTE_STUB_STRING = "@@ VERTEX ATTRIBUTES @@";
 constexpr const char *PIXEL_OUTPUT_STUB_STRING     = "@@ PIXEL OUTPUT @@";
 }  // anonymous namespace
 
+// BuiltinInfo implementation
+
+BuiltinInfo::BuiltinInfo()  = default;
+BuiltinInfo::~BuiltinInfo() = default;
+
 // DynamicHLSL implementation
 
 DynamicHLSL::DynamicHLSL(RendererD3D *const renderer) : mRenderer(renderer)
 {
 }
 
 std::string DynamicHLSL::generateVertexShaderForInputLayout(
     const std::string &sourceShader,
@@ -267,18 +273,19 @@ std::string DynamicHLSL::generateVertexS
     structStream << "};\n"
                     "\n"
                     "void initAttributes(VS_INPUT input)\n"
                     "{\n"
                  << initStream.str() << "}\n";
 
     std::string vertexHLSL(sourceShader);
 
-    size_t copyInsertionPos = vertexHLSL.find(VERTEX_ATTRIBUTE_STUB_STRING);
-    vertexHLSL.replace(copyInsertionPos, strlen(VERTEX_ATTRIBUTE_STUB_STRING), structStream.str());
+    bool success =
+        angle::ReplaceSubstring(&vertexHLSL, VERTEX_ATTRIBUTE_STUB_STRING, structStream.str());
+    ASSERT(success);
 
     return vertexHLSL;
 }
 
 std::string DynamicHLSL::generatePixelShaderForOutputSignature(
     const std::string &sourceShader,
     const std::vector<PixelShaderOutputVariable> &outputVariables,
     bool usesFragDepth,
@@ -343,19 +350,19 @@ std::string DynamicHLSL::generatePixelSh
                          "PS_OUTPUT generateOutput()\n"
                          "{\n"
                          "    PS_OUTPUT output;\n"
                       << copyStream.str() << "    return output;\n"
                                              "}\n";
 
     std::string pixelHLSL(sourceShader);
 
-    size_t outputInsertionPos = pixelHLSL.find(PIXEL_OUTPUT_STUB_STRING);
-    pixelHLSL.replace(outputInsertionPos, strlen(PIXEL_OUTPUT_STUB_STRING),
-                      declarationStream.str());
+    bool success =
+        angle::ReplaceSubstring(&pixelHLSL, PIXEL_OUTPUT_STUB_STRING, declarationStream.str());
+    ASSERT(success);
 
     return pixelHLSL;
 }
 
 void DynamicHLSL::generateVaryingLinkHLSL(const VaryingPacking &varyingPacking,
                                           const BuiltinInfo &builtins,
                                           bool programUsesPointSize,
                                           std::ostringstream &hlslStream) const
@@ -479,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[SHADER_VERTEX];
+    const auto &vertexBuiltins = builtinsD3D[gl::SHADER_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"
@@ -645,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[SHADER_PIXEL];
+    const auto &pixelBuiltins = builtinsD3D[gl::SHADER_FRAGMENT];
 
     std::ostringstream pixelStream;
     pixelStream << fragmentShaderGL->getTranslatedSource(context);
     pixelStream << "struct PS_INPUT\n";
     generateVaryingLinkHLSL(varyingPacking, pixelBuiltins, builtinsD3D.usesPointSize(),
                             pixelStream);
     pixelStream << "\n";
 
@@ -919,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[SHADER_VERTEX];
+    const auto &vertexBuiltins = builtinsD3D[gl::SHADER_VERTEX];
 
     preambleStream << "struct GS_INPUT\n";
     generateVaryingLinkHLSL(varyingPacking, vertexBuiltins, builtinsD3D.usesPointSize(),
                             preambleStream);
     preambleStream << "\n"
                    << "struct GS_OUTPUT\n";
-    generateVaryingLinkHLSL(varyingPacking, builtinsD3D[SHADER_GEOMETRY],
+    generateVaryingLinkHLSL(varyingPacking, builtinsD3D[gl::SHADER_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)
@@ -944,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[SHADER_GEOMETRY].glViewportIndex.enabled &&
-                   builtinsD3D[SHADER_GEOMETRY].glLayer.enabled);
+            ASSERT(builtinsD3D[gl::SHADER_GEOMETRY].glViewportIndex.enabled &&
+                   builtinsD3D[gl::SHADER_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";
         }
     }
 
@@ -977,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[SHADER_GEOMETRY].glViewportIndex.enabled &&
-               builtinsD3D[SHADER_GEOMETRY].glLayer.enabled);
+        ASSERT(builtinsD3D[gl::SHADER_GEOMETRY].glViewportIndex.enabled &&
+               builtinsD3D[gl::SHADER_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"
@@ -1258,31 +1265,41 @@ void DynamicHLSL::getPixelShaderOutputKe
             outPixelShaderKey->push_back(outputKeyVariable);
         }
     }
     else
     {
         const auto &shaderOutputVars =
             metadata.getFragmentShader()->getData().getActiveOutputVariables();
 
-        for (auto outputPair : programData.getOutputLocations())
+        for (size_t outputLocationIndex = 0u;
+             outputLocationIndex < programData.getOutputLocations().size(); ++outputLocationIndex)
         {
-            const VariableLocation &outputLocation   = outputPair.second;
+            const VariableLocation &outputLocation =
+                programData.getOutputLocations().at(outputLocationIndex);
+            if (!outputLocation.used())
+            {
+                continue;
+            }
             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 =
-                (outputLocation.element == GL_INVALID_INDEX ? "" : Str(outputLocation.element));
+                (outputVariable.isArray() ? Str(outputLocation.arrayIndex) : "");
 
             ASSERT(outputVariable.staticUse);
 
             PixelShaderOutputVariable outputKeyVariable;
             outputKeyVariable.type        = outputVariable.type;
             outputKeyVariable.name        = variableName + elementString;
-            outputKeyVariable.source      = variableName + ArrayString(outputLocation.element);
-            outputKeyVariable.outputIndex = outputPair.first;
+            outputKeyVariable.source =
+                variableName +
+                (outputVariable.isArray() ? ArrayString(outputLocation.arrayIndex) : "");
+            outputKeyVariable.outputIndex = outputLocationIndex;
 
             outPixelShaderKey->push_back(outputKeyVariable);
         }
     }
 }
 
 // BuiltinVarying Implementation.
 BuiltinVarying::BuiltinVarying() : enabled(false), index(0), systemValue(false)
@@ -1307,40 +1324,42 @@ void BuiltinVarying::enable(const std::s
     semantic = semanticVal;
     index    = indexVal;
 }
 
 // BuiltinVaryingsD3D Implementation.
 BuiltinVaryingsD3D::BuiltinVaryingsD3D(const ProgramD3DMetadata &metadata,
                                        const VaryingPacking &packing)
 {
-    updateBuiltins(SHADER_VERTEX, metadata, packing);
-    updateBuiltins(SHADER_PIXEL, metadata, packing);
+    updateBuiltins(gl::SHADER_VERTEX, metadata, packing);
+    updateBuiltins(gl::SHADER_FRAGMENT, metadata, packing);
     if (metadata.getRendererMajorShaderModel() >= 4)
     {
-        updateBuiltins(SHADER_GEOMETRY, metadata, packing);
+        updateBuiltins(gl::SHADER_GEOMETRY, metadata, packing);
     }
 }
 
-void BuiltinVaryingsD3D::updateBuiltins(ShaderType shaderType,
+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];
 
     if (metadata.getRendererMajorShaderModel() >= 4)
     {
         builtins->dxPosition.enableSystem("SV_Position");
     }
-    else if (shaderType == SHADER_PIXEL)
+    else if (shaderType == gl::SHADER_FRAGMENT)
     {
         builtins->dxPosition.enableSystem("VPOS");
     }
     else
     {
         builtins->dxPosition.enableSystem("POSITION");
     }
 
@@ -1349,60 +1368,60 @@ void BuiltinVaryingsD3D::updateBuiltins(
         builtins->glPosition.enable(userSemantic, reservedSemanticIndex++);
     }
 
     if (metadata.usesFragCoord())
     {
         builtins->glFragCoord.enable(userSemantic, reservedSemanticIndex++);
     }
 
-    if (shaderType == SHADER_VERTEX ? metadata.addsPointCoordToVertexShader()
-                                    : metadata.usesPointCoord())
+    if (shaderType == gl::SHADER_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 == SHADER_VERTEX && metadata.hasANGLEMultiviewEnabled())
+    if (shaderType == gl::SHADER_VERTEX && metadata.hasANGLEMultiviewEnabled())
     {
         builtins->glViewIDOVR.enable(userSemantic, reservedSemanticIndex++);
         if (metadata.canSelectViewInVertexShader())
         {
             builtins->glViewportIndex.enableSystem("SV_ViewportArrayIndex");
             builtins->glLayer.enableSystem("SV_RenderTargetArrayIndex");
         }
     }
 
-    if (shaderType == SHADER_PIXEL && metadata.hasANGLEMultiviewEnabled())
+    if (shaderType == gl::SHADER_FRAGMENT && metadata.hasANGLEMultiviewEnabled())
     {
         builtins->glViewIDOVR.enable(userSemantic, reservedSemanticIndex++);
     }
 
-    if (shaderType == SHADER_GEOMETRY && metadata.hasANGLEMultiviewEnabled())
+    if (shaderType == gl::SHADER_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 != SHADER_PIXEL || metadata.getRendererMajorShaderModel() >= 4))
+        (shaderType != gl::SHADER_FRAGMENT || metadata.getRendererMajorShaderModel() >= 4))
     {
         builtins->glPointSize.enableSystem("PSIZE");
     }
 }
 
 }  // namespace rx
--- a/gfx/angle/src/libANGLE/renderer/d3d/DynamicHLSL.h
+++ b/gfx/angle/src/libANGLE/renderer/d3d/DynamicHLSL.h
@@ -11,16 +11,17 @@
 
 #include <map>
 #include <vector>
 
 #include "angle_gl.h"
 #include "common/angleutils.h"
 #include "libANGLE/Constants.h"
 #include "libANGLE/Program.h"
+#include "libANGLE/angletypes.h"
 #include "libANGLE/formatutils.h"
 #include "libANGLE/renderer/d3d/RendererD3D.h"
 
 namespace sh
 {
 struct Attribute;
 struct ShaderVariable;
 }
@@ -66,16 +67,19 @@ struct BuiltinVarying final : private an
     bool enabled;
     std::string semantic;
     unsigned int index;
     bool systemValue;
 };
 
 struct BuiltinInfo
 {
+    BuiltinInfo();
+    ~BuiltinInfo();
+
     BuiltinVarying dxPosition;
     BuiltinVarying glPosition;
     BuiltinVarying glFragCoord;
     BuiltinVarying glPointCoord;
     BuiltinVarying glPointSize;
     BuiltinVarying glViewIDOVR;
     BuiltinVarying glViewportIndex;
     BuiltinVarying glLayer;
@@ -87,28 +91,32 @@ inline std::string GetVaryingSemantic(in
     // In D3D11 we manually compute gl_PointCoord in the GS.
     return ((programUsesPointSize && majorShaderModel < 4) ? "COLOR" : "TEXCOORD");
 }
 
 class BuiltinVaryingsD3D
 {
   public:
     BuiltinVaryingsD3D(const ProgramD3DMetadata &metadata, const gl::VaryingPacking &packing);
+    ~BuiltinVaryingsD3D();
 
-    bool usesPointSize() const { return mBuiltinInfo[SHADER_VERTEX].glPointSize.enabled; }
+    bool usesPointSize() const { return mBuiltinInfo[gl::SHADER_VERTEX].glPointSize.enabled; }
 
-    const BuiltinInfo &operator[](ShaderType shaderType) const { return mBuiltinInfo[shaderType]; }
-    BuiltinInfo &operator[](ShaderType shaderType) { return mBuiltinInfo[shaderType]; }
+    const BuiltinInfo &operator[](gl::ShaderType shaderType) const
+    {
+        return mBuiltinInfo[shaderType];
+    }
+    BuiltinInfo &operator[](gl::ShaderType shaderType) { return mBuiltinInfo[shaderType]; }
 
   private:
-    void updateBuiltins(ShaderType shaderType,
+    void updateBuiltins(gl::ShaderType shaderType,
                         const ProgramD3DMetadata &metadata,
                         const gl::VaryingPacking &packing);
 
-    std::array<BuiltinInfo, SHADER_TYPE_MAX> mBuiltinInfo;
+    std::array<BuiltinInfo, gl::SHADER_TYPE_MAX> mBuiltinInfo;
 };
 
 class DynamicHLSL : angle::NonCopyable
 {
   public:
     explicit DynamicHLSL(RendererD3D *const renderer);
 
     std::string generateVertexShaderForInputLayout(
--- a/gfx/angle/src/libANGLE/renderer/d3d/FramebufferD3D.cpp
+++ b/gfx/angle/src/libANGLE/renderer/d3d/FramebufferD3D.cpp
@@ -82,18 +82,22 @@ ClearParameters GetClearParameters(const
             clearParams.clearStencil = true;
         }
     }
 
     return clearParams;
 }
 }
 
+ClearParameters::ClearParameters() = default;
+
+ClearParameters::ClearParameters(const ClearParameters &other) = default;
+
 FramebufferD3D::FramebufferD3D(const gl::FramebufferState &data, RendererD3D *renderer)
-    : FramebufferImpl(data), mRenderer(renderer)
+    : FramebufferImpl(data), mRenderer(renderer), mDummyAttachment()
 {
 }
 
 FramebufferD3D::~FramebufferD3D()
 {
 }
 
 gl::Error FramebufferD3D::clear(const gl::Context *context, GLbitfield mask)
@@ -248,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 &formatInfo = gl::GetInternalFormatInfo(format, type);
+    const gl::InternalFormat &sizedFormatInfo = gl::GetInternalFormatInfo(format, type);
 
     GLuint outputPitch = 0;
-
-    ANGLE_TRY_RESULT(formatInfo.computeRowPitch(area.width, packState.alignment, packState.rowLength),
+    ANGLE_TRY_RESULT(sizedFormatInfo.computeRowPitch(type, origArea.width, packState.alignment,
+                                                     packState.rowLength),
                      outputPitch);
     GLuint outputSkipBytes = 0;
-    ANGLE_TRY_RESULT(formatInfo.computeSkipBytes(outputPitch, 0, packState, false),
+    ANGLE_TRY_RESULT(sizedFormatInfo.computeSkipBytes(outputPitch, 0, packState, false),
                      outputSkipBytes);
     outputSkipBytes +=
-        (area.x - origArea.x) * formatInfo.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,
@@ -280,30 +284,35 @@ gl::Error FramebufferD3D::blit(const gl:
     const gl::Rectangle *scissor = glState.isScissorTestEnabled() ? &glState.getScissor() : nullptr;
     ANGLE_TRY(blitImpl(context, sourceArea, destArea, scissor, (mask & GL_COLOR_BUFFER_BIT) != 0,
                        (mask & GL_DEPTH_BUFFER_BIT) != 0, (mask & GL_STENCIL_BUFFER_BIT) != 0,
                        filter, sourceFramebuffer));
 
     return gl::NoError();
 }
 
-bool FramebufferD3D::checkStatus() const
+bool FramebufferD3D::checkStatus(const gl::Context *context) const
 {
     // if we have both a depth and stencil buffer, they must refer to the same object
     // since we only support packed_depth_stencil and not separate depth and stencil
     if (mState.getDepthAttachment() != nullptr && mState.getStencilAttachment() != nullptr &&
         mState.getDepthStencilAttachment() == nullptr)
     {
         return false;
     }
 
-    // D3D11 does not allow for overlapping RenderTargetViews
-    if (!mState.colorAttachmentsAreUniqueImages())
+    // D3D11 does not allow for overlapping RenderTargetViews.
+    // If WebGL compatibility is enabled, this has already been checked at a higher level.
+    ASSERT(!context->getExtensions().webglCompatibility || mState.colorAttachmentsAreUniqueImages());
+    if (!context->getExtensions().webglCompatibility)
     {
-        return false;
+        if (!mState.colorAttachmentsAreUniqueImages())
+        {
+            return false;
+        }
     }
 
     // D3D requires all render targets to have the same dimensions.
     if (!mState.attachmentsHaveSameDimensions())
     {
         return false;
     }
 
@@ -359,15 +368,63 @@ const gl::AttachmentList &FramebufferD3D
             colorAttachmentsForRender.push_back(&colorAttachment);
         }
         else if (!workarounds.mrtPerfWorkaround)
         {
             colorAttachmentsForRender.push_back(nullptr);
         }
     }
 
+    // When rendering with no render target on D3D, two bugs lead to incorrect behavior on Intel
+    // drivers < 4815. The rendering samples always pass neglecting discard statements in pixel
+    // shader. We add a dummy texture as render target in such case.
+    if (mRenderer->getWorkarounds().addDummyTextureNoRenderTarget &&
+        colorAttachmentsForRender.empty() && activeProgramOutputs.any())
+    {
+        static_assert(static_cast<size_t>(activeProgramOutputs.size()) <= 32,
+                      "Size of active program outputs should less or equal than 32.");
+        const GLuint activeProgramLocation = static_cast<GLuint>(
+            gl::ScanForward(static_cast<uint32_t>(activeProgramOutputs.bits())));
+
+        if (mDummyAttachment.isAttached() &&
+            (mDummyAttachment.getBinding() - GL_COLOR_ATTACHMENT0) == activeProgramLocation)
+        {
+            colorAttachmentsForRender.push_back(&mDummyAttachment);
+        }
+        else
+        {
+            // Remove dummy attachment to prevents us from leaking it, and the program may require
+            // 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));
+            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);
+            }
+        }
+    }
+
     mColorAttachmentsForRender = std::move(colorAttachmentsForRender);
     mCurrentActiveProgramOutputs = activeProgramOutputs;
 
     return mColorAttachmentsForRender.value();
 }
 
+void FramebufferD3D::destroy(const gl::Context *context)
+{
+    if (mDummyAttachment.isAttached())
+    {
+        mDummyAttachment.detach(context);
+    }
+}
+
 }  // namespace rx
--- a/gfx/angle/src/libANGLE/renderer/d3d/FramebufferD3D.h
+++ b/gfx/angle/src/libANGLE/renderer/d3d/FramebufferD3D.h
@@ -27,16 +27,19 @@ typedef std::vector<const FramebufferAtt
 
 namespace rx
 {
 class RendererD3D;
 class RenderTargetD3D;
 
 struct ClearParameters
 {
+    ClearParameters();
+    ClearParameters(const ClearParameters &other);
+
     bool clearColor[gl::IMPLEMENTATION_MAX_DRAW_BUFFERS];
     gl::ColorF colorF;
     gl::ColorI colorI;
     gl::ColorUI colorUI;
     GLenum colorType;
     bool colorMaskRed;
     bool colorMaskGreen;
     bool colorMaskBlue;
@@ -52,17 +55,17 @@ struct ClearParameters
     bool scissorEnabled;
     gl::Rectangle scissor;
 };
 
 class FramebufferD3D : public FramebufferImpl
 {
   public:
     FramebufferD3D(const gl::FramebufferState &data, RendererD3D *renderer);
-    virtual ~FramebufferD3D();
+    ~FramebufferD3D() override;
 
     gl::Error clear(const gl::Context *context, GLbitfield mask) override;
     gl::Error clearBufferfv(const gl::Context *context,
                             GLenum buffer,
                             GLint drawbuffer,
                             const GLfloat *values) override;
     gl::Error clearBufferuiv(const gl::Context *context,
                              GLenum buffer,
@@ -87,23 +90,25 @@ class FramebufferD3D : public Framebuffe
                          void *pixels) override;
 
     gl::Error blit(const gl::Context *context,
                    const gl::Rectangle &sourceArea,
                    const gl::Rectangle &destArea,
                    GLbitfield mask,
                    GLenum filter) override;
 
-    bool checkStatus() const override;
+    bool checkStatus(const gl::Context *context) const override;
 
     void 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;
 
     virtual gl::Error readPixelsImpl(const gl::Context *context,
                                      const gl::Rectangle &area,
                                      GLenum format,
                                      GLenum type,
                                      size_t outputPitch,
@@ -120,12 +125,14 @@ class FramebufferD3D : public Framebuffe
                                GLenum filter,
                                const gl::Framebuffer *sourceFramebuffer) = 0;
 
     virtual GLenum getRenderTargetImplementationFormat(RenderTargetD3D *renderTarget) const = 0;
 
     RendererD3D *mRenderer;
     Optional<gl::AttachmentList> mColorAttachmentsForRender;
     gl::DrawBufferMask mCurrentActiveProgramOutputs;
+
+    gl::FramebufferAttachment mDummyAttachment;
 };
 }
 
 #endif  // LIBANGLE_RENDERER_D3D_FRAMBUFFERD3D_H_
--- a/gfx/angle/src/libANGLE/renderer/d3d/ImageD3D.cpp
+++ b/gfx/angle/src/libANGLE/renderer/d3d/ImageD3D.cpp
@@ -5,17 +5,16 @@
 //
 
 // Image.h: Implements the rx::Image class, an abstract base class for the
 // renderer-specific classes which will define the interface to the underlying
 // surfaces or resources.
 
 #include "libANGLE/renderer/d3d/ImageD3D.h"
 
-#include "libANGLE/formatutils.h"
 #include "libANGLE/Framebuffer.h"
 #include "libANGLE/FramebufferAttachment.h"
 #include "libANGLE/renderer/d3d/FramebufferD3D.h"
 #include "libANGLE/renderer/d3d/RenderTargetD3D.h"
 
 namespace rx
 {
 
@@ -25,18 +24,39 @@ ImageD3D::ImageD3D()
       mDepth(0),
       mInternalFormat(GL_NONE),
       mRenderable(false),
       mTarget(GL_NONE),
       mDirty(false)
 {
 }
 
-GLenum
-ImageD3D::getSizedInputFormat(GLenum inputType) const
+gl::Error ImageD3D::setManagedSurface2D(const gl::Context *context,
+                                        TextureStorage *storage,
+                                        int level)
+{
+    return gl::NoError();
+}
+
+gl::Error ImageD3D::setManagedSurfaceCube(const gl::Context *context,
+                                          TextureStorage *storage,
+                                          int face,
+                                          int level)
 {
-    const auto &internalFormat = gl::GetSizedInternalFormatInfo(mInternalFormat);
-    const auto &unsizedInternalFormat = internalFormat.format;
-    const auto &sizedIF = gl::GetInternalFormatInfo(unsizedInternalFormat, inputType);
-    return sizedIF.sizedInternalFormat;
+    return gl::NoError();
+}
+
+gl::Error ImageD3D::setManagedSurface3D(const gl::Context *context,
+                                        TextureStorage *storage,
+                                        int level)
+{
+    return gl::NoError();
+}
+
+gl::Error ImageD3D::setManagedSurface2DArray(const gl::Context *context,
+                                             TextureStorage *storage,
+                                             int layer,
+                                             int level)
+{
+    return gl::NoError();
 }
 
 }  // namespace rx
--- a/gfx/angle/src/libANGLE/renderer/d3d/ImageD3D.h
+++ b/gfx/angle/src/libANGLE/renderer/d3d/ImageD3D.h
@@ -47,54 +47,40 @@ class ImageD3D : angle::NonCopyable
     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;
 
-    GLenum getSizedInputFormat(GLenum inputType) const;
-
     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,
                                          const gl::Box &area,
                                          const void *input) = 0;
 
     virtual gl::Error setManagedSurface2D(const gl::Context *context,
                                           TextureStorage *storage,
-                                          int level)
-    {
-        return gl::NoError();
-    }
+                                          int level);
     virtual gl::Error setManagedSurfaceCube(const gl::Context *context,
                                             TextureStorage *storage,
                                             int face,
-                                            int level)
-    {
-        return gl::NoError();
-    }
+                                            int level);
     virtual gl::Error setManagedSurface3D(const gl::Context *context,
                                           TextureStorage *storage,
-                                          int level)
-    {
-        return gl::NoError();
-    }
+                                          int level);
     virtual gl::Error setManagedSurface2DArray(const gl::Context *context,
                                                TextureStorage *storage,
                                                int layer,
-                                               int level)
-    {
-        return gl::NoError();
-    }
+                                               int level);
     virtual gl::Error copyToStorage(const gl::Context *context,
                                     TextureStorage *storage,
                                     const gl::ImageIndex &index,
                                     const gl::Box &region) = 0;
 
     virtual gl::Error copyFromTexStorage(const gl::Context *context,
                                          const gl::ImageIndex &imageIndex,
                                          TextureStorage *source) = 0;
--- a/gfx/angle/src/libANGLE/renderer/d3d/IndexBuffer.cpp
+++ b/gfx/angle/src/libANGLE/renderer/d3d/IndexBuffer.cpp
@@ -141,30 +141,22 @@ StreamingIndexBufferInterface::~Streamin
 }
 
 gl::Error StreamingIndexBufferInterface::reserveBufferSpace(unsigned int size, GLenum indexType)
 {
     unsigned int curBufferSize = getBufferSize();
     unsigned int writePos = getWritePosition();
     if (size > curBufferSize)
     {
-        gl::Error error = setBufferSize(std::max(size, 2 * curBufferSize), indexType);
-        if (error.isError())
-        {
-            return error;
-        }
+        ANGLE_TRY(setBufferSize(std::max(size, 2 * curBufferSize), indexType));
         setWritePosition(0);
     }
     else if (writePos + size > curBufferSize || writePos + size < writePos)
     {
-        gl::Error error = discard();
-        if (error.isError())
-        {
-            return error;
-        }
+        ANGLE_TRY(discard());
         setWritePosition(0);
     }
 
     return gl::NoError();
 }
 
 
 StaticIndexBufferInterface::StaticIndexBufferInterface(BufferFactoryD3D *factory)
@@ -189,9 +181,9 @@ gl::Error StaticIndexBufferInterface::re
     }
     else
     {
         UNREACHABLE();
         return gl::InternalError() << "Internal static index buffers can't be resized";
     }
 }
 
-}
+}  // namespace rx
--- a/gfx/angle/src/libANGLE/renderer/d3d/IndexBuffer.h
+++ b/gfx/angle/src/libANGLE/renderer/d3d/IndexBuffer.h
@@ -76,25 +76,25 @@ class IndexBufferInterface : angle::NonC
     unsigned int mWritePosition;
     bool mDynamic;
 };
 
 class StreamingIndexBufferInterface : public IndexBufferInterface
 {
   public:
     explicit StreamingIndexBufferInterface(BufferFactoryD3D *factory);
-    ~StreamingIndexBufferInterface();
+    ~StreamingIndexBufferInterface() override;
 
     gl::Error reserveBufferSpace(unsigned int size, GLenum indexType) override;
 };
 
 class StaticIndexBufferInterface : public IndexBufferInterface
 {
   public:
     explicit StaticIndexBufferInterface(BufferFactoryD3D *factory);
-    ~StaticIndexBufferInterface();
+    ~StaticIndexBufferInterface() override;
 
     gl::Error reserveBufferSpace(unsigned int size, GLenum indexType) override;
 };
 
 }
 
 #endif // LIBANGLE_RENDERER_D3D_INDEXBUFFER_H_
--- a/gfx/angle/src/libANGLE/renderer/d3d/IndexDataManager.cpp
+++ b/gfx/angle/src/libANGLE/renderer/d3d/IndexDataManager.cpp
@@ -94,201 +94,123 @@ gl::Error StreamInIndexBuffer(IndexBuffe
 
     if (count > (std::numeric_limits<unsigned int>::max() >> dstTypeInfo.bytesShift))
     {
         return gl::OutOfMemory() << "Reserving " << count << " indices of " << dstTypeInfo.bytes
                                  << " bytes each exceeds the maximum buffer size.";
     }
 
     unsigned int bufferSizeRequired = count << dstTypeInfo.bytesShift;
-    gl::Error error                 = buffer->reserveBufferSpace(bufferSizeRequired, dstType);
-    if (error.isError())
-    {
-        return error;
-    }
+    ANGLE_TRY(buffer->reserveBufferSpace(bufferSizeRequired, dstType));
 
     void *output = nullptr;
-    error        = buffer->mapBuffer(bufferSizeRequired, &output, offset);
-    if (error.isError())
-    {
-        return error;
-    }
+    ANGLE_TRY(buffer->mapBuffer(bufferSizeRequired, &output, offset));
 
     ConvertIndices(srcType, dstType, data, count, output, usePrimitiveRestartFixedIndex);
 
-    error = buffer->unmapBuffer();
-    if (error.isError())
+    ANGLE_TRY(buffer->unmapBuffer());
+    return gl::NoError();
+}
+
+unsigned int ElementTypeSize(GLenum elementType)
+{
+    switch (elementType)
     {
-        return error;
+        case GL_UNSIGNED_BYTE:
+            return sizeof(GLubyte);
+        case GL_UNSIGNED_SHORT:
+            return sizeof(GLushort);
+        case GL_UNSIGNED_INT:
+            return sizeof(GLuint);
+        default:
+            UNREACHABLE();
+            return 0;
     }
-
-    return gl::NoError();
 }
 
 }  // anonymous namespace
 
-IndexDataManager::IndexDataManager(BufferFactoryD3D *factory, RendererClass rendererClass)
-    : mFactory(factory),
-      mRendererClass(rendererClass),
-      mStreamingBufferShort(),
-      mStreamingBufferInt()
+bool IsOffsetAligned(GLenum elementType, unsigned int offset)
+{
+    return (offset % ElementTypeSize(elementType) == 0);
+}
+
+// IndexDataManager implementation.
+IndexDataManager::IndexDataManager(BufferFactoryD3D *factory)
+    : mFactory(factory), mStreamingBufferShort(), mStreamingBufferInt()
 {
 }
 
 IndexDataManager::~IndexDataManager()
 {
 }
 
 void IndexDataManager::deinitialize()
 {
     mStreamingBufferShort.reset();
     mStreamingBufferInt.reset();
 }
 
-// static
-bool IndexDataManager::UsePrimitiveRestartWorkaround(bool primitiveRestartFixedIndexEnabled,
-                                                     GLenum type,
-                                                     RendererClass rendererClass)
-{
-    // 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 &&
-            rendererClass == RENDERER_D3D11);
-}
-
-// static
-bool IndexDataManager::IsStreamingIndexData(const gl::Context *context,
-                                            GLenum srcType,
-                                            RendererClass rendererClass)
-{
-    const auto &glState = context->getGLState();
-    bool primitiveRestartWorkaround =
-        UsePrimitiveRestartWorkaround(glState.isPrimitiveRestartEnabled(), srcType, rendererClass);
-    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;
-    }
-
-    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;
-}
-
 // This function translates a GL-style indices into DX-style indices, with their description
 // returned in translated.
 // GL can specify vertex data in immediate mode (pointer to CPU array of indices), which is not
 // possible in DX and requires streaming (Case 1). If the GL indices are specified with a buffer
 // (Case 2), in a format supported by DX (subcase a) then all is good.
 // When we have a buffer with an unsupported format (subcase b) then we need to do some translation:
 // we will start by falling back to streaming, and after a while will start using a static
 // translated copy of the index buffer.
 gl::Error IndexDataManager::prepareIndexData(const gl::Context *context,
                                              GLenum srcType,
+                                             GLenum dstType,
                                              GLsizei count,
                                              gl::Buffer *glBuffer,
                                              const void *indices,
-                                             TranslatedIndexData *translated,
-                                             bool primitiveRestartFixedIndexEnabled)
+                                             TranslatedIndexData *translated)
 {
-    // Avoid D3D11's primitive restart index value
-    // see http://msdn.microsoft.com/en-us/library/windows/desktop/bb205124(v=vs.85).aspx
-    bool hasPrimitiveRestartIndex =
-        translated->indexRange.vertexIndexCount < static_cast<size_t>(count) ||
-        translated->indexRange.end == gl::GetPrimitiveRestartIndex(srcType);
-    bool primitiveRestartWorkaround =
-        UsePrimitiveRestartWorkaround(primitiveRestartFixedIndexEnabled, srcType, mRendererClass) &&
-        hasPrimitiveRestartIndex;
-
-    // We should never have to deal with MAX_UINT indices, since we restrict it via
-    // MAX_ELEMENT_INDEX.
-    ASSERT(!(mRendererClass == RENDERER_D3D11 && !primitiveRestartFixedIndexEnabled &&
-             hasPrimitiveRestartIndex && srcType == GL_UNSIGNED_INT));
-
-    const GLenum dstType = (srcType == GL_UNSIGNED_INT || primitiveRestartWorkaround)
-                               ? GL_UNSIGNED_INT
-                               : GL_UNSIGNED_SHORT;
-
     const gl::Type &srcTypeInfo = gl::GetTypeInfo(srcType);
     const gl::Type &dstTypeInfo = gl::GetTypeInfo(dstType);
 
     BufferD3D *buffer = glBuffer ? GetImplAs<BufferD3D>(glBuffer) : nullptr;
 
     translated->indexType                 = dstType;
     translated->srcIndexData.srcBuffer    = buffer;
     translated->srcIndexData.srcIndices   = indices;
     translated->srcIndexData.srcIndexType = srcType;
     translated->srcIndexData.srcCount     = count;
 
+    // Context can be nullptr in perf tests.
+    bool primitiveRestartFixedIndexEnabled =
+        context ? context->getGLState().isPrimitiveRestartEnabled() : false;
+
     // Case 1: the indices are passed by pointer, which forces the streaming of index data
     if (glBuffer == nullptr)
     {
         translated->storage = nullptr;
         return streamIndexData(indices, count, srcType, dstType, primitiveRestartFixedIndexEnabled,
                                translated);
     }
 
     // Case 2: the indices are already in a buffer
     unsigned int offset = static_cast<unsigned int>(reinterpret_cast<uintptr_t>(indices));
     ASSERT(srcTypeInfo.bytes * static_cast<unsigned int>(count) + offset <= buffer->getSize());
 
-    bool offsetAligned;
-    switch (srcType)
-    {
-        case GL_UNSIGNED_BYTE:
-            offsetAligned = (offset % sizeof(GLubyte) == 0);
-            break;
-        case GL_UNSIGNED_SHORT:
-            offsetAligned = (offset % sizeof(GLushort) == 0);
-            break;
-        case GL_UNSIGNED_INT:
-            offsetAligned = (offset % sizeof(GLuint) == 0);
-            break;
-        default:
-            UNREACHABLE();
-            offsetAligned = false;
-    }
+    bool offsetAligned = IsOffsetAligned(srcType, offset);
 
     // Case 2a: the buffer can be used directly
     if (offsetAligned && buffer->supportsDirectBinding() && dstType == srcType)
     {
         translated->storage     = buffer;
         translated->indexBuffer = nullptr;
         translated->serial      = buffer->getSerial();
         translated->startIndex  = (offset >> srcTypeInfo.bytesShift);
         translated->startOffset = offset;
         return gl::NoError();
     }
-    else
-    {
-        translated->storage = nullptr;
-    }
+
+    translated->storage = nullptr;
 
     // Case 2b: use a static translated copy or fall back to streaming
     StaticIndexBufferInterface *staticBuffer = buffer->getStaticIndexBuffer();
 
     bool staticBufferInitialized = staticBuffer && staticBuffer->getBufferSize() != 0;
     bool staticBufferUsable =
         staticBuffer && offsetAligned && staticBuffer->getIndexType() == dstType;
 
@@ -296,51 +218,35 @@ gl::Error IndexDataManager::prepareIndex
     {
         buffer->invalidateStaticData(context);
         staticBuffer = nullptr;
     }
 
     if (staticBuffer == nullptr || !offsetAligned)
     {
         const uint8_t *bufferData = nullptr;
-        gl::Error error           = buffer->getData(context, &bufferData);
-        if (error.isError())
-        {
-            return error;
-        }
+        ANGLE_TRY(buffer->getData(context, &bufferData));
         ASSERT(bufferData != nullptr);
 
-        error = streamIndexData(bufferData + offset, count, srcType, dstType,
-                                primitiveRestartFixedIndexEnabled, translated);
-        if (error.isError())
-        {
-            return error;
-        }
+        ANGLE_TRY(streamIndexData(bufferData + offset, count, srcType, dstType,
+                                  primitiveRestartFixedIndexEnabled, translated));
         buffer->promoteStaticUsage(context, count << srcTypeInfo.bytesShift);
     }
     else
     {
         if (!staticBufferInitialized)
         {
             const uint8_t *bufferData = nullptr;
-            gl::Error error           = buffer->getData(context, &bufferData);
-            if (error.isError())
-            {
-                return error;
-            }
+            ANGLE_TRY(buffer->getData(context, &bufferData));
             ASSERT(bufferData != nullptr);
 
             unsigned int convertCount =
                 static_cast<unsigned int>(buffer->getSize()) >> srcTypeInfo.bytesShift;
-            error = StreamInIndexBuffer(staticBuffer, bufferData, convertCount, srcType, dstType,
-                                        primitiveRestartFixedIndexEnabled, nullptr);
-            if (error.isError())
-            {
-                return error;
-            }
+            ANGLE_TRY(StreamInIndexBuffer(staticBuffer, bufferData, convertCount, srcType, dstType,
+                                          primitiveRestartFixedIndexEnabled, nullptr));
         }
         ASSERT(offsetAligned && staticBuffer->getIndexType() == dstType);
 
         translated->indexBuffer = staticBuffer->getIndexBuffer();
         translated->serial      = staticBuffer->getSerial();
         translated->startIndex  = (offset >> srcTypeInfo.bytesShift);
         translated->startOffset = (offset >> srcTypeInfo.bytesShift) << dstTypeInfo.bytesShift;
     }
@@ -353,21 +259,17 @@ gl::Error IndexDataManager::streamIndexD
                                             GLenum srcType,
                                             GLenum dstType,
                                             bool usePrimitiveRestartFixedIndex,
                                             TranslatedIndexData *translated)
 {
     const gl::Type &dstTypeInfo = gl::GetTypeInfo(dstType);
 
     IndexBufferInterface *indexBuffer = nullptr;
-    gl::Error error                   = getStreamingIndexBuffer(dstType, &indexBuffer);
-    if (error.isError())
-    {
-        return error;
-    }
+    ANGLE_TRY(getStreamingIndexBuffer(dstType, &indexBuffer));
     ASSERT(indexBuffer != nullptr);
 
     unsigned int offset;
     ANGLE_TRY(StreamInIndexBuffer(indexBuffer, data, count, srcType, dstType,
                                   usePrimitiveRestartFixedIndex, &offset));
 
     translated->indexBuffer = indexBuffer->getIndexBuffer();
     translated->serial      = indexBuffer->getSerial();
@@ -391,9 +293,28 @@ gl::Error IndexDataManager::getStreaming
         StreamingBuffer newBuffer(new StreamingIndexBufferInterface(mFactory));
         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)
+{
+    // 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))
+        {
+            return GL_UNSIGNED_INT;
+        }
+    }
+
+    return (srcType == GL_UNSIGNED_INT) ? GL_UNSIGNED_INT : GL_UNSIGNED_SHORT;
+}
+
 }  // namespace rx
--- a/gfx/angle/src/libANGLE/renderer/d3d/IndexDataManager.h
+++ b/gfx/angle/src/libANGLE/renderer/d3d/IndexDataManager.h
@@ -45,62 +45,61 @@ struct SourceIndexData
     const void *srcIndices;
     unsigned int srcCount;
     GLenum srcIndexType;
     bool srcIndicesChanged;
 };
 
 struct TranslatedIndexData
 {
-    gl::IndexRange indexRange;
     unsigned int startIndex;
     unsigned int startOffset;  // In bytes
 
     IndexBuffer *indexBuffer;
     BufferD3D *storage;
     GLenum indexType;
     unsigned int serial;
 
     SourceIndexData srcIndexData;
 };
 
 class IndexDataManager : angle::NonCopyable
 {
   public:
-    explicit IndexDataManager(BufferFactoryD3D *factory, RendererClass rendererClass);
+    explicit IndexDataManager(BufferFactoryD3D *factory);
     virtual ~IndexDataManager();
 
     void deinitialize();
 
-    static bool UsePrimitiveRestartWorkaround(bool primitiveRestartFixedIndexEnabled,
-                                              GLenum type,
-                                              RendererClass rendererClass);
-    static bool IsStreamingIndexData(const gl::Context *context,
-                                     GLenum srcType,
-                                     RendererClass rendererClass);
     gl::Error prepareIndexData(const gl::Context *context,
                                GLenum srcType,
+                               GLenum dstType,
                                GLsizei count,
                                gl::Buffer *glBuffer,
                                const void *indices,
-                               TranslatedIndexData *translated,
-                               bool primitiveRestartFixedIndexEnabled);
+                               TranslatedIndexData *translated);
 
   private:
     gl::Error streamIndexData(const void *data,
                               unsigned int count,
                               GLenum srcType,
                               GLenum dstType,
                               bool usePrimitiveRestartFixedIndex,
                               TranslatedIndexData *translated);
     gl::Error getStreamingIndexBuffer(GLenum destinationIndexType,
                                       IndexBufferInterface **outBuffer);
 
     using StreamingBuffer = std::unique_ptr<StreamingIndexBufferInterface>;
 
     BufferFactoryD3D *const mFactory;
-    RendererClass mRendererClass;
     std::unique_ptr<StreamingIndexBufferInterface> mStreamingBufferShort;
     std::unique_ptr<StreamingIndexBufferInterface> mStreamingBufferInt;
 };
+
+GLenum GetIndexTranslationDestType(GLenum srcType,
+                                   const gl::HasIndexRange &lazyIndexRange,
+                                   bool usePrimitiveRestartWorkaround);
+
+bool IsOffsetAligned(GLenum elementType, unsigned int offset);
+
 }  // namespace rx
 
 #endif  // LIBANGLE_INDEXDATAMANAGER_H_
--- a/gfx/angle/src/libANGLE/renderer/d3d/ProgramD3D.cpp
+++ b/gfx/angle/src/libANGLE/renderer/d3d/ProgramD3D.cpp
@@ -4,30 +4,30 @@
 // found in the LICENSE file.
 //
 
 // ProgramD3D.cpp: Defines the rx::ProgramD3D class which implements rx::ProgramImpl.
 
 #include "libANGLE/renderer/d3d/ProgramD3D.h"
 
 #include "common/bitset_utils.h"
+#include "common/string_utils.h"
 #include "common/utilities.h"
 #include "libANGLE/Context.h"
 #include "libANGLE/Framebuffer.h"
 #include "libANGLE/FramebufferAttachment.h"
 #include "libANGLE/Program.h"
+#include "libANGLE/ProgramLinkedResources.h"
 #include "libANGLE/Uniform.h"
-#include "libANGLE/VaryingPacking.h"
 #include "libANGLE/VertexArray.h"
 #include "libANGLE/features.h"
 #include "libANGLE/queryconversions.h"
 #include "libANGLE/renderer/ContextImpl.h"
 #include "libANGLE/renderer/d3d/DynamicHLSL.h"
 #include "libANGLE/renderer/d3d/FramebufferD3D.h"
-#include "libANGLE/renderer/d3d/RendererD3D.h"
 #include "libANGLE/renderer/d3d/ShaderD3D.h"
 #include "libANGLE/renderer/d3d/ShaderExecutableD3D.h"
 #include "libANGLE/renderer/d3d/VertexDataManager.h"
 
 using namespace angle;
 
 namespace rx
 {
@@ -47,17 +47,17 @@ void GetDefaultInputLayoutFromShader(con
         {
             GLenum transposedType = gl::TransposeMatrixType(shaderAttr.type);
 
             for (size_t rowIndex = 0;
                  static_cast<int>(rowIndex) < gl::VariableRowCount(transposedType); ++rowIndex)
             {
                 GLenum componentType = gl::VariableComponentType(transposedType);
                 GLuint components    = static_cast<GLuint>(gl::VariableColumnCount(transposedType));
-                bool pureInt = (componentType != GL_FLOAT);
+                bool pureInt         = (componentType != GL_FLOAT);
                 gl::VertexFormatType defaultType =
                     gl::GetVertexFormatType(componentType, GL_FALSE, components, pureInt);
 
                 inputLayoutOut->push_back(defaultType);
             }
         }
     }
 }
@@ -70,62 +70,16 @@ void GetDefaultOutputLayoutFromShader(
 
     if (!shaderOutputVars.empty())
     {
         outputLayoutOut->push_back(GL_COLOR_ATTACHMENT0 +
                                    static_cast<unsigned int>(shaderOutputVars[0].outputIndex));
     }
 }
 
-bool IsRowMajorLayout(const sh::InterfaceBlockField &var)
-{
-    return var.isRowMajorLayout;
-}
-
-bool IsRowMajorLayout(const sh::ShaderVariable &var)
-{
-    return false;
-}
-
-template <typename VarT>
-void GetUniformBlockInfo(const std::vector<VarT> &fields,
-                         const std::string &prefix,
-                         sh::BlockLayoutEncoder *encoder,
-                         bool inRowMajorLayout,
-                         std::map<std::string, sh::BlockMemberInfo> *blockInfoOut)
-{
-    for (const VarT &field : fields)
-    {
-        const std::string &fieldName = (prefix.empty() ? field.name : prefix + "." + field.name);
-
-        if (field.isStruct())
-        {
-            bool rowMajorLayout = (inRowMajorLayout || IsRowMajorLayout(field));
-
-            for (unsigned int arrayElement = 0; arrayElement < field.elementCount(); arrayElement++)
-            {
-                encoder->enterAggregateType();
-
-                const std::string uniformElementName =
-                    fieldName + (field.isArray() ? ArrayString(arrayElement) : "");
-                GetUniformBlockInfo(field.fields, uniformElementName, encoder, rowMajorLayout,
-                                    blockInfoOut);
-
-                encoder->exitAggregateType();
-            }
-        }
-        else
-        {
-            bool isRowMajorMatrix = (gl::IsMatrixType(field.type) && inRowMajorLayout);
-            (*blockInfoOut)[fieldName] =
-                encoder->encodeType(field.type, field.arraySize, isRowMajorMatrix);
-        }
-    }
-}
-
 template <typename T, int cols, int rows>
 bool TransposeExpandMatrix(T *target, const GLfloat *value)
 {
     constexpr int targetWidth  = 4;
     constexpr int targetHeight = rows;
     constexpr int srcWidth     = rows;
     constexpr int srcHeight    = cols;
 
@@ -151,18 +105,18 @@ bool TransposeExpandMatrix(T *target, co
     return true;
 }
 
 template <typename T, int cols, int rows>
 bool ExpandMatrix(T *target, const GLfloat *value)
 {
     constexpr int targetWidth  = 4;
     constexpr int targetHeight = rows;
-    constexpr int srcWidth = cols;
-    constexpr int srcHeight = rows;
+    constexpr int srcWidth     = cols;
+    constexpr int srcHeight    = rows;
 
     constexpr int copyWidth  = std::min(targetWidth, srcWidth);
     constexpr int copyHeight = std::min(targetHeight, srcHeight);
 
     T staging[targetWidth * targetHeight] = {0};
 
     for (int y = 0; y < copyHeight; y++)
     {
@@ -239,67 +193,171 @@ void GetMatrixUniform(GLint columns, GLi
 }
 
 template <typename NonFloatT>
 void GetMatrixUniform(GLint columns, GLint rows, NonFloatT *dataOut, const NonFloatT *source)
 {
     UNREACHABLE();
 }
 
+class UniformBlockInfo final : angle::NonCopyable
+{
+  public:
+    UniformBlockInfo() {}
+
+    void getShaderBlockInfo(const gl::Context *context, gl::Shader *shader);
+
+    bool getBlockSize(const std::string &name, const std::string &mappedName, size_t *sizeOut);
+    bool getBlockMemberInfo(const std::string &name,
+                            const std::string &mappedName,
+                            sh::BlockMemberInfo *infoOut);
+
+  private:
+    size_t getBlockInfo(const sh::InterfaceBlock &interfaceBlock);
+
+    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)
+            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);
+
+    // define member uniforms
+    sh::Std140BlockEncoder std140Encoder;
+    sh::HLSLBlockEncoder hlslEncoder(sh::HLSLBlockEncoder::ENCODE_PACKED, false);
+    sh::BlockLayoutEncoder *encoder = nullptr;
+
+    if (interfaceBlock.layout == sh::BLOCKLAYOUT_STD140)
+    {
+        encoder = &std140Encoder;
+    }
+    else
+    {
+        encoder = &hlslEncoder;
+    }
+
+    sh::GetUniformBlockInfo(interfaceBlock.fields, interfaceBlock.fieldPrefix(), encoder,
+                            &mBlockLayout);
+
+    return encoder->getBlockSize();
+}
+
+bool UniformBlockInfo::getBlockSize(const std::string &name,
+                                    const std::string &mappedName,
+                                    size_t *sizeOut)
+{
+    size_t nameLengthWithoutArrayIndex;
+    gl::ParseArrayIndex(name, &nameLengthWithoutArrayIndex);
+    std::string baseName = name.substr(0u, nameLengthWithoutArrayIndex);
+    auto sizeIter        = mBlockSizes.find(baseName);
+    if (sizeIter == mBlockSizes.end())
+    {
+        *sizeOut = 0;
+        return false;
+    }
+
+    *sizeOut = sizeIter->second;
+    return true;
+};
+
+bool UniformBlockInfo::getBlockMemberInfo(const std::string &name,
+                                          const std::string &mappedName,
+                                          sh::BlockMemberInfo *infoOut)
+{
+    auto infoIter = mBlockLayout.find(name);
+    if (infoIter == mBlockLayout.end())
+    {
+        *infoOut = sh::BlockMemberInfo::getDefaultBlockInfo();
+        return false;
+    }
+
+    *infoOut = infoIter->second;
+    return true;
+};
+
 }  // anonymous namespace
 
 // D3DUniform Implementation
 
 D3DUniform::D3DUniform(GLenum type,
+                       HLSLRegisterType reg,
                        const std::string &nameIn,
-                       unsigned int arraySizeIn,
+                       const std::vector<unsigned int> &arraySizesIn,
                        bool defaultBlock)
     : typeInfo(gl::GetUniformTypeInfo(type)),
       name(nameIn),
-      arraySize(arraySizeIn),
+      arraySizes(arraySizesIn),
       vsData(nullptr),
       psData(nullptr),
       csData(nullptr),
+      regType(reg),
       vsRegisterIndex(GL_INVALID_INDEX),
       psRegisterIndex(GL_INVALID_INDEX),
       csRegisterIndex(GL_INVALID_INDEX),
       registerCount(0),
       registerElement(0)
 {
     // We use data storage for default block uniforms to cache values that are sent to D3D during
     // rendering
     // Uniform blocks/buffers are treated separately by the Renderer (ES3 path only)
     if (defaultBlock)
     {
         // Use the row count as register count, will work for non-square matrices.
-        registerCount = typeInfo.rowCount * elementCount();
+        registerCount = typeInfo.rowCount * getArraySizeProduct();
     }
 }
 
 D3DUniform::~D3DUniform()
 {
 }
 
+unsigned int D3DUniform::getArraySizeProduct() const
+{
+    return gl::ArraySizeProduct(arraySizes);
+}
+
 const uint8_t *D3DUniform::getDataPtrToElement(size_t elementIndex) const
 {
-    ASSERT((arraySize == 0 && elementIndex == 0) || (arraySize > 0 && elementIndex < arraySize));
+    ASSERT((!isArray() && elementIndex == 0) ||
+           (isArray() && elementIndex < getArraySizeProduct()));
 
     if (isSampler())
     {
         return reinterpret_cast<const uint8_t *>(&mSamplerData[elementIndex]);
     }
 
     return firstNonNullData() + (elementIndex > 0 ? (typeInfo.internalSize * elementIndex) : 0u);
 }
 
 bool D3DUniform::isSampler() const
 {
     return typeInfo.isSampler;
 }
 
+bool D3DUniform::isImage() const
+{
+    return typeInfo.isImageType;
+}
+
 bool D3DUniform::isReferencedByVertexShader() const
 {
     return vsRegisterIndex != GL_INVALID_INDEX;
 }
 
 bool D3DUniform::isReferencedByFragmentShader() const
 {
     return psRegisterIndex != GL_INVALID_INDEX;
@@ -500,17 +558,17 @@ void ProgramD3D::VertexExecutable::getSi
         gl::VertexFormatType vertexFormatType = inputLayout[index];
         if (vertexFormatType == gl::VERTEX_FORMAT_INVALID)
             continue;
 
         VertexConversionType conversionType = renderer->getVertexConversionType(vertexFormatType);
         if ((conversionType & VERTEX_CONVERT_GPU) == 0)
             continue;
 
-        GLenum componentType = renderer->getVertexComponentType(vertexFormatType);
+        GLenum componentType   = renderer->getVertexComponentType(vertexFormatType);
         (*signatureOut)[index] = GetAttribType(componentType);
     }
 }
 
 bool ProgramD3D::VertexExecutable::matchesSignature(const Signature &signature) const
 {
     size_t limit = std::max(mSignature.size(), signature.size());
     for (size_t index = 0; index < limit; ++index)
@@ -535,16 +593,20 @@ ProgramD3D::PixelExecutable::~PixelExecu
 {
     SafeDelete(mShaderExecutable);
 }
 
 ProgramD3D::Sampler::Sampler() : active(false), logicalTextureUnit(0), textureType(GL_TEXTURE_2D)
 {
 }
 
+ProgramD3D::Image::Image() : active(false), logicalImageUnit(0)
+{
+}
+
 unsigned int ProgramD3D::mCurrentSerial = 1;
 
 ProgramD3D::ProgramD3D(const gl::ProgramState &state, RendererD3D *renderer)
     : ProgramImpl(state),
       mRenderer(renderer),
       mDynamicHLSL(nullptr),
       mGeometryExecutables(gl::PRIMITIVE_TYPE_MAX),
       mComputeExecutable(nullptr),
@@ -552,16 +614,18 @@ ProgramD3D::ProgramD3D(const gl::Program
       mUsesFlatInterpolation(false),
       mVertexUniformStorage(nullptr),
       mFragmentUniformStorage(nullptr),
       mComputeUniformStorage(nullptr),
       mUsedVertexSamplerRange(0),
       mUsedPixelSamplerRange(0),
       mUsedComputeSamplerRange(0),
       mDirtySamplerMapping(true),
+      mUsedComputeImageRange(0),
+      mUsedComputeReadonlyImageRange(0),
       mSerial(issueSerial()),
       mVertexUniformsDirty(true),
       mFragmentUniformsDirty(true),
       mComputeUniformsDirty(true)
 {
     mDynamicHLSL = new DynamicHLSL(renderer);
 }
 
@@ -594,39 +658,39 @@ bool ProgramD3D::usesGeometryShader(GLen
     return usesGeometryShaderForPointSpriteEmulation();
 }
 
 bool ProgramD3D::usesInstancedPointSpriteEmulation() const
 {
     return mRenderer->getWorkarounds().useInstancedPointSpriteEmulation;
 }
 
-GLint ProgramD3D::getSamplerMapping(gl::SamplerType type,
+GLint ProgramD3D::getSamplerMapping(gl::ShaderType type,
                                     unsigned int samplerIndex,
                                     const gl::Caps &caps) const
 {
     GLint logicalTextureUnit = -1;
 
     switch (type)
     {
-        case gl::SAMPLER_PIXEL:
+        case gl::SHADER_FRAGMENT:
             ASSERT(samplerIndex < caps.maxTextureImageUnits);
             if (samplerIndex < mSamplersPS.size() && mSamplersPS[samplerIndex].active)
             {
                 logicalTextureUnit = mSamplersPS[samplerIndex].logicalTextureUnit;
             }
             break;
-        case gl::SAMPLER_VERTEX:
+        case gl::SHADER_VERTEX:
             ASSERT(samplerIndex < caps.maxVertexTextureImageUnits);
             if (samplerIndex < mSamplersVS.size() && mSamplersVS[samplerIndex].active)
             {
                 logicalTextureUnit = mSamplersVS[samplerIndex].logicalTextureUnit;
             }
             break;
-        case gl::SAMPLER_COMPUTE:
+        case gl::SHADER_COMPUTE:
             ASSERT(samplerIndex < caps.maxComputeTextureImageUnits);
             if (samplerIndex < mSamplersCS.size() && mSamplersCS[samplerIndex].active)
             {
                 logicalTextureUnit = mSamplersCS[samplerIndex].logicalTextureUnit;
             }
             break;
         default:
             UNREACHABLE();
@@ -638,48 +702,48 @@ 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::SamplerType type, unsigned int samplerIndex) const
+GLenum ProgramD3D::getSamplerTextureType(gl::ShaderType type, unsigned int samplerIndex) const
 {
     switch (type)
     {
-        case gl::SAMPLER_PIXEL:
+        case gl::SHADER_FRAGMENT:
             ASSERT(samplerIndex < mSamplersPS.size());
             ASSERT(mSamplersPS[samplerIndex].active);
             return mSamplersPS[samplerIndex].textureType;
-        case gl::SAMPLER_VERTEX:
+        case gl::SHADER_VERTEX:
             ASSERT(samplerIndex < mSamplersVS.size());
             ASSERT(mSamplersVS[samplerIndex].active);
             return mSamplersVS[samplerIndex].textureType;
-        case gl::SAMPLER_COMPUTE:
+        case gl::SHADER_COMPUTE:
             ASSERT(samplerIndex < mSamplersCS.size());
             ASSERT(mSamplersCS[samplerIndex].active);
             return mSamplersCS[samplerIndex].textureType;
         default:
             UNREACHABLE();
     }
 
     return GL_TEXTURE_2D;
 }
 
-GLuint ProgramD3D::getUsedSamplerRange(gl::SamplerType type) const
+GLuint ProgramD3D::getUsedSamplerRange(gl::ShaderType type) const
 {
     switch (type)
     {
-        case gl::SAMPLER_PIXEL:
+        case gl::SHADER_FRAGMENT:
             return mUsedPixelSamplerRange;
-        case gl::SAMPLER_VERTEX:
+        case gl::SHADER_VERTEX:
             return mUsedVertexSamplerRange;
-        case gl::SAMPLER_COMPUTE:
+        case gl::SHADER_COMPUTE:
             return mUsedComputeSamplerRange;
         default:
             UNREACHABLE();
             return 0u;
     }
 }
 
 ProgramD3D::SamplerMapping ProgramD3D::updateSamplerMapping()
@@ -692,17 +756,17 @@ ProgramD3D::SamplerMapping ProgramD3D::u
     mDirtySamplerMapping = false;
 
     // Retrieve sampler uniform values
     for (const D3DUniform *d3dUniform : mD3DUniforms)
     {
         if (!d3dUniform->isSampler())
             continue;
 
-        int count = d3dUniform->elementCount();
+        int count = d3dUniform->getArraySizeProduct();
 
         if (d3dUniform->isReferencedByFragmentShader())
         {
             unsigned int firstIndex = d3dUniform->psRegisterIndex;
 
             for (int i = 0; i < count; i++)
             {
                 unsigned int samplerIndex = firstIndex + i;
@@ -746,16 +810,62 @@ ProgramD3D::SamplerMapping ProgramD3D::u
                 }
             }
         }
     }
 
     return SamplerMapping::WasDirty;
 }
 
+GLint ProgramD3D::getImageMapping(gl::ShaderType type,
+                                  unsigned int imageIndex,
+                                  bool readonly,
+                                  const gl::Caps &caps) const
+{
+    GLint logicalImageUnit = -1;
+    ASSERT(imageIndex < caps.maxImageUnits);
+    switch (type)
+    {
+        case gl::SHADER_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;
+            }
+            break;
+        // TODO(xinghua.cao@intel.com): add image mapping for vertex shader and pixel shader.
+        default:
+            UNREACHABLE();
+    }
+
+    if (logicalImageUnit >= 0 && logicalImageUnit < static_cast<GLint>(caps.maxImageUnits))
+    {
+        return logicalImageUnit;
+    }
+
+    return -1;
+}
+
+GLuint ProgramD3D::getUsedImageRange(gl::ShaderType type, bool readonly) const
+{
+    switch (type)
+    {
+        case gl::SHADER_COMPUTE:
+            return readonly ? mUsedComputeReadonlyImageRange : mUsedComputeImageRange;
+        // TODO(xinghua.cao@intel.com): add image range of vertex shader and pixel shader.
+        default:
+            UNREACHABLE();
+            return 0u;
+    }
+}
+
 gl::LinkResult ProgramD3D::load(const gl::Context *context,
                                 gl::InfoLog &infoLog,
                                 gl::BinaryInputStream *stream)
 {
     // TODO(jmadill): Use Renderer from contextImpl.
 
     reset();
 
@@ -806,36 +916,57 @@ gl::LinkResult ProgramD3D::load(const gl
     {
         Sampler sampler;
         stream->readBool(&sampler.active);
         stream->readInt(&sampler.logicalTextureUnit);
         stream->readInt(&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);
+        stream->readInt(&image.logicalImageUnit);
+        mImagesCS.push_back(image);
+    }
+
+    const unsigned int csReadonlyImageCount = stream->readInt<unsigned int>();
+    for (unsigned int i = 0; i < csReadonlyImageCount; ++i)
+    {
+        Image image;
+        stream->readBool(&image.active);
+        stream->readInt(&image.logicalImageUnit);
+        mReadonlyImagesCS.push_back(image);
+    }
+
     stream->readInt(&mUsedVertexSamplerRange);
     stream->readInt(&mUsedPixelSamplerRange);
     stream->readInt(&mUsedComputeSamplerRange);
+    stream->readInt(&mUsedComputeImageRange);
+    stream->readInt(&mUsedComputeReadonlyImageRange);
 
     const unsigned int uniformCount = stream->readInt<unsigned int>();
     if (stream->error())
     {
         infoLog << "Invalid program binary.";
         return false;
     }
 
     const auto &linkedUniforms = mState.getUniforms();
     ASSERT(mD3DUniforms.empty());
     for (unsigned int uniformIndex = 0; uniformIndex < uniformCount; uniformIndex++)
     {
         const gl::LinkedUniform &linkedUniform = linkedUniforms[uniformIndex];
 
         D3DUniform *d3dUniform =
-            new D3DUniform(linkedUniform.type, linkedUniform.name, linkedUniform.arraySize,
-                           linkedUniform.isInDefaultBlock());
+            new D3DUniform(linkedUniform.type, HLSLRegisterType::None, linkedUniform.name,
+                           linkedUniform.arraySizes, linkedUniform.isInDefaultBlock());
+        stream->readInt<HLSLRegisterType>(&d3dUniform->regType);
         stream->readInt(&d3dUniform->psRegisterIndex);
         stream->readInt(&d3dUniform->vsRegisterIndex);
         stream->readInt(&d3dUniform->csRegisterIndex);
         stream->readInt(&d3dUniform->registerCount);
         stream->readInt(&d3dUniform->registerElement);
 
         mD3DUniforms.push_back(d3dUniform);
     }
@@ -910,18 +1041,18 @@ gl::LinkResult ProgramD3D::load(const gl
             inputLayout[inputIndex] = stream->readInt<gl::VertexFormatType>();
         }
 
         unsigned int vertexShaderSize             = stream->readInt<unsigned int>();
         const unsigned char *vertexShaderFunction = binary + stream->offset();
 
         ShaderExecutableD3D *shaderExecutable = nullptr;
 
-        ANGLE_TRY(mRenderer->loadExecutable(vertexShaderFunction, vertexShaderSize, SHADER_VERTEX,
-                                            mStreamOutVaryings, separateAttribs,
+        ANGLE_TRY(mRenderer->loadExecutable(vertexShaderFunction, vertexShaderSize,
+                                            gl::SHADER_VERTEX, mStreamOutVaryings, separateAttribs,
                                             &shaderExecutable));
 
         if (!shaderExecutable)
         {
             infoLog << "Could not create vertex shader.";
             return false;
         }
 
@@ -945,19 +1076,19 @@ 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, SHADER_PIXEL,
-                                            mStreamOutVaryings, separateAttribs,
-                                            &shaderExecutable));
+        ANGLE_TRY(mRenderer->loadExecutable(pixelShaderFunction, pixelShaderSize,
+                                            gl::SHADER_FRAGMENT, mStreamOutVaryings,
+                                            separateAttribs, &shaderExecutable));
 
         if (!shaderExecutable)
         {
             infoLog << "Could not create pixel shader.";
             return false;
         }
 
         // add new binary
@@ -975,18 +1106,18 @@ gl::LinkResult ProgramD3D::load(const gl
         {
             continue;
         }
 
         const unsigned char *geometryShaderFunction = binary + stream->offset();
 
         ShaderExecutableD3D *geometryExecutable = nullptr;
         ANGLE_TRY(mRenderer->loadExecutable(geometryShaderFunction, geometryShaderSize,
-                                            SHADER_GEOMETRY, mStreamOutVaryings, separateAttribs,
-                                            &geometryExecutable));
+                                            gl::SHADER_GEOMETRY, mStreamOutVaryings,
+                                            separateAttribs, &geometryExecutable));
 
         if (!geometryExecutable)
         {
             infoLog << "Could not create geometry shader.";
             return false;
         }
 
         mGeometryExecutables[geometryExeIndex].reset(geometryExecutable);
@@ -996,17 +1127,17 @@ 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,
-                                            SHADER_COMPUTE, std::vector<D3DVarying>(), false,
+                                            gl::SHADER_COMPUTE, std::vector<D3DVarying>(), false,
                                             &computeExecutable));
 
         if (!computeExecutable)
         {
             infoLog << "Could not create compute shader.";
             return false;
         }
 
@@ -1053,35 +1184,48 @@ void ProgramD3D::save(const gl::Context 
     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->writeInt(mImagesCS.size());
+    for (unsigned int i = 0; i < mImagesCS.size(); ++i)
+    {
+        stream->writeInt(mImagesCS[i].active);
+        stream->writeInt(mImagesCS[i].logicalImageUnit);
+    }
+
+    stream->writeInt(mReadonlyImagesCS.size());
+    for (unsigned int i = 0; i < mReadonlyImagesCS.size(); ++i)
+    {
+        stream->writeInt(mReadonlyImagesCS[i].active);
+        stream->writeInt(mReadonlyImagesCS[i].logicalImageUnit);
+    }
+
     stream->writeInt(mUsedVertexSamplerRange);
     stream->writeInt(mUsedPixelSamplerRange);
     stream->writeInt(mUsedComputeSamplerRange);
+    stream->writeInt(mUsedComputeImageRange);
+    stream->writeInt(mUsedComputeReadonlyImageRange);
 
     stream->writeInt(mD3DUniforms.size());
     for (const D3DUniform *uniform : mD3DUniforms)
     {
         // Type, name and arraySize are redundant, so aren't stored in the binary.
+        stream->writeInt(static_cast<unsigned int>(uniform->regType));
         stream->writeIntOrNegOne(uniform->psRegisterIndex);
         stream->writeIntOrNegOne(uniform->vsRegisterIndex);
         stream->writeIntOrNegOne(uniform->csRegisterIndex);
         stream->writeInt(uniform->registerCount);
         stream->writeInt(uniform->registerElement);
     }
 
-    // Ensure we init the uniform block structure data if we should.
-    // http://anglebug.com/1637
-    ensureUniformBlocksInitialized();
-
     stream->writeInt(mD3DUniformBlocks.size());
     for (const D3DUniformBlock &uniformBlock : mD3DUniformBlocks)
     {
         stream->writeIntOrNegOne(uniformBlock.psRegisterIndex);
         stream->writeIntOrNegOne(uniformBlock.vsRegisterIndex);
         stream->writeIntOrNegOne(uniformBlock.csRegisterIndex);
     }
 
@@ -1208,17 +1352,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, SHADER_PIXEL, mStreamOutVaryings,
+        *currentInfoLog, finalPixelHLSL, gl::SHADER_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;
@@ -1249,17 +1393,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, SHADER_VERTEX, mStreamOutVaryings,
+        *currentInfoLog, finalVertexHLSL, gl::SHADER_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;
@@ -1306,17 +1450,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, SHADER_GEOMETRY, mStreamOutVaryings,
+        *currentInfoLog, geometryHLSL, gl::SHADER_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;
     }
@@ -1451,19 +1595,28 @@ gl::LinkResult ProgramD3D::compileProgra
     GetGeometryExecutableTask geometryTask(this, context);
 
     std::array<WaitableEvent, 3> waitEvents = {{workerPool->postWorkerTask(&vertexTask),
                                                 workerPool->postWorkerTask(&pixelTask),
                                                 workerPool->postWorkerTask(&geometryTask)}};
 
     WaitableEvent::WaitMany(&waitEvents);
 
-    infoLog << vertexTask.getInfoLog().str();
-    infoLog << pixelTask.getInfoLog().str();
-    infoLog << geometryTask.getInfoLog().str();
+    if (!vertexTask.getInfoLog().empty())
+    {
+        infoLog << vertexTask.getInfoLog().str();
+    }
+    if (!pixelTask.getInfoLog().empty())
+    {
+        infoLog << pixelTask.getInfoLog().str();
+    }
+    if (!geometryTask.getInfoLog().empty())
+    {
+        infoLog << geometryTask.getInfoLog().str();
+    }
 
     ANGLE_TRY(vertexTask.getError());
     ANGLE_TRY(pixelTask.getError());
     ANGLE_TRY(geometryTask.getError());
 
     ShaderExecutableD3D *defaultVertexExecutable = vertexTask.getResult();
     ShaderExecutableD3D *defaultPixelExecutable  = pixelTask.getResult();
     ShaderExecutableD3D *pointGS                 = geometryTask.getResult();
@@ -1500,17 +1653,17 @@ gl::LinkResult ProgramD3D::compileComput
                                                     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, SHADER_COMPUTE,
+    ANGLE_TRY(mRenderer->compileToExecutable(infoLog, computeShader, gl::SHADER_COMPUTE,
                                              std::vector<D3DVarying>(), false,
                                              angle::CompilerWorkaroundsD3D(), &computeExecutable));
 
     if (computeExecutable == nullptr)
     {
         ERR() << "Error compiling dynamic compute executable:" << std::endl
               << infoLog.str() << std::endl;
     }
@@ -1520,43 +1673,43 @@ gl::LinkResult ProgramD3D::compileComput
         computeShaderD3D->appendDebugInfo(computeExecutable->getDebugInfo());
         mComputeExecutable.reset(computeExecutable);
     }
 
     return mComputeExecutable.get() != nullptr;
 }
 
 gl::LinkResult ProgramD3D::link(const gl::Context *context,
-                                const gl::VaryingPacking &packing,
+                                const gl::ProgramLinkedResources &resources,
                                 gl::InfoLog &infoLog)
 {
     const auto &data = context->getContextState();
 
     reset();
 
     gl::Shader *computeShader = mState.getAttachedComputeShader();
     if (computeShader)
     {
         mSamplersCS.resize(data.getCaps().maxComputeTextureImageUnits);
+        mImagesCS.resize(data.getCaps().maxImageUnits);
+        mReadonlyImagesCS.resize(data.getCaps().maxImageUnits);
 
         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;
         }
-
-        initUniformBlockInfo(context, computeShader);
     }
     else
     {
         gl::Shader *vertexShader   = mState.getAttachedVertexShader();
         gl::Shader *fragmentShader = mState.getAttachedFragmentShader();
 
         const ShaderD3D *vertexShaderD3D   = GetImplAs<ShaderD3D>(vertexShader);
         const ShaderD3D *fragmentShaderD3D = GetImplAs<ShaderD3D>(fragmentShader);
@@ -1575,100 +1728,85 @@ gl::LinkResult ProgramD3D::link(const gl
                 return false;
             }
         }
 
         // TODO(jmadill): Implement more sophisticated component packing in D3D9.
         // We can fail here because we use one semantic per GLSL varying. D3D11 can pack varyings
         // intelligently, but D3D9 assumes one semantic per register.
         if (mRenderer->getRendererClass() == RENDERER_D3D9 &&
-            packing.getMaxSemanticIndex() > data.getCaps().maxVaryingVectors)
+            resources.varyingPacking.getMaxSemanticIndex() > data.getCaps().maxVaryingVectors)
         {
             infoLog << "Cannot pack these varyings on D3D9.";
             return false;
         }
 
         ProgramD3DMetadata metadata(mRenderer, vertexShaderD3D, fragmentShaderD3D);
-        BuiltinVaryingsD3D builtins(metadata, packing);
-
-        mDynamicHLSL->generateShaderLinkHLSL(context, mState, metadata, packing, builtins,
-                                             &mPixelHLSL, &mVertexHLSL);
+        BuiltinVaryingsD3D builtins(metadata, resources.varyingPacking);
+
+        mDynamicHLSL->generateShaderLinkHLSL(context, mState, metadata, resources.varyingPacking,
+                                             builtins, &mPixelHLSL, &mVertexHLSL);
 
         mUsesPointSize = vertexShaderD3D->usesPointSize();
         mDynamicHLSL->getPixelShaderOutputKey(data, mState, metadata, &mPixelShaderKey);
-        mUsesFragDepth = metadata.usesFragDepth();
+        mUsesFragDepth            = metadata.usesFragDepth();
         mUsesViewID               = metadata.usesViewID();
         mHasANGLEMultiviewEnabled = metadata.hasANGLEMultiviewEnabled();
 
         // Cache if we use flat shading
         mUsesFlatInterpolation =
-            (FindFlatInterpolationVarying(fragmentShader->getVaryings(context)) ||
-             FindFlatInterpolationVarying(vertexShader->getVaryings(context)));
+            (FindFlatInterpolationVarying(fragmentShader->getInputVaryings(context)) ||
+             FindFlatInterpolationVarying(vertexShader->getOutputVaryings(context)));
 
         if (mRenderer->getMajorShaderModel() >= 4)
         {
             mGeometryShaderPreamble = mDynamicHLSL->generateGeometryShaderPreamble(
-                packing, builtins, mHasANGLEMultiviewEnabled,
+                resources.varyingPacking, builtins, mHasANGLEMultiviewEnabled,
                 metadata.canSelectViewInVertexShader());
         }
 
         initAttribLocationsToD3DSemantic(context);
 
         defineUniformsAndAssignRegisters(context);
 
-        gatherTransformFeedbackVaryings(packing, builtins[SHADER_VERTEX]);
+        gatherTransformFeedbackVaryings(resources.varyingPacking, builtins[gl::SHADER_VERTEX]);
 
         gl::LinkResult result = compileProgramExecutables(context, infoLog);
         if (result.isError())
         {
             infoLog << result.getError().getMessage();
             return result;
         }
         else if (!result.getResult())
         {
             infoLog << "Failed to create D3D shaders.";
             return result;
         }
-
-        initUniformBlockInfo(context, vertexShader);
-        initUniformBlockInfo(context, fragmentShader);
     }
 
+    linkResources(context, resources);
+
     return true;
 }
 
 GLboolean ProgramD3D::validate(const gl::Caps & /*caps*/, gl::InfoLog * /*infoLog*/)
 {
     // TODO(jmadill): Do something useful here?
     return GL_TRUE;
 }
 
-void ProgramD3D::initUniformBlockInfo(const gl::Context *context, gl::Shader *shader)
+void ProgramD3D::initializeUniformBlocks()
 {
-    for (const sh::InterfaceBlock &interfaceBlock : shader->getUniformBlocks(context))
-    {
-        if (!interfaceBlock.staticUse && interfaceBlock.layout == sh::BLOCKLAYOUT_PACKED)
-            continue;
-
-        if (mBlockDataSizes.count(interfaceBlock.name) > 0)
-            continue;
-
-        size_t dataSize                      = getUniformBlockInfo(interfaceBlock);
-        mBlockDataSizes[interfaceBlock.name] = dataSize;
-    }
-}
-
-void ProgramD3D::ensureUniformBlocksInitialized()
-{
-    // Lazy init.
-    if (mState.getUniformBlocks().empty() || !mD3DUniformBlocks.empty())
+    if (mState.getUniformBlocks().empty())
     {
         return;
     }
 
+    ASSERT(mD3DUniformBlocks.empty());
+
     // Assign registers and update sizes.
     const ShaderD3D *vertexShaderD3D = SafeGetImplAs<ShaderD3D>(mState.getAttachedVertexShader());
     const ShaderD3D *fragmentShaderD3D =
         SafeGetImplAs<ShaderD3D>(mState.getAttachedFragmentShader());
     const ShaderD3D *computeShaderD3D = SafeGetImplAs<ShaderD3D>(mState.getAttachedComputeShader());
 
     for (const gl::InterfaceBlock &uniformBlock : mState.getUniformBlocks())
     {
@@ -1738,17 +1876,17 @@ void ProgramD3D::initializeUniformStorag
     mComputeUniformStorage =
         std::unique_ptr<UniformStorageD3D>(mRenderer->createUniformStorage(computeRegisters * 16u));
 
     // Iterate the uniforms again to assign data pointers to default block uniforms.
     for (D3DUniform *d3dUniform : mD3DUniforms)
     {
         if (d3dUniform->isSampler())
         {
-            d3dUniform->mSamplerData.resize(d3dUniform->elementCount(), 0);
+            d3dUniform->mSamplerData.resize(d3dUniform->getArraySizeProduct(), 0);
             continue;
         }
 
         if (d3dUniform->isReferencedByVertexShader())
         {
             d3dUniform->vsData = mVertexUniformStorage->getDataPointer(d3dUniform->vsRegisterIndex,
                                                                        d3dUniform->registerElement);
         }
@@ -1771,18 +1909,16 @@ void ProgramD3D::updateUniformBufferCach
                                           unsigned int reservedVertex,
                                           unsigned int reservedFragment)
 {
     if (mState.getUniformBlocks().empty())
     {
         return;
     }
 
-    ensureUniformBlocksInitialized();
-
     mVertexUBOCache.clear();
     mFragmentUBOCache.clear();
 
     for (unsigned int uniformBlockIndex = 0; uniformBlockIndex < mD3DUniformBlocks.size();
          uniformBlockIndex++)
     {
         const D3DUniformBlock &uniformBlock = mD3DUniformBlocks[uniformBlockIndex];
         GLuint blockBinding                 = mState.getUniformBlockBinding(uniformBlockIndex);
@@ -1974,19 +2110,19 @@ void ProgramD3D::setUniform3uiv(GLint lo
     setUniformInternal(location, count, v, GL_UNSIGNED_INT_VEC3);
 }
 
 void ProgramD3D::setUniform4uiv(GLint location, GLsizei count, const GLuint *v)
 {
     setUniformInternal(location, count, v, GL_UNSIGNED_INT_VEC4);
 }
 
-void ProgramD3D::setUniformBlockBinding(GLuint /*uniformBlockIndex*/,
-                                        GLuint /*uniformBlockBinding*/)
+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)
     {
@@ -2020,119 +2156,222 @@ void ProgramD3D::defineUniformsAndAssign
     }
 
     // Initialize the D3DUniform list to mirror the indexing of the GL layer.
     for (const gl::LinkedUniform &glUniform : mState.getUniforms())
     {
         if (!glUniform.isInDefaultBlock())
             continue;
 
-        auto mapEntry = uniformMap.find(glUniform.name);
+        std::string name = glUniform.name;
+        if (glUniform.isArray())
+        {
+            // In the program state, array uniform names include [0] as in the program resource
+            // spec. Here we don't include it.
+            // TODO(oetuaho@nvidia.com): consider using the same uniform naming here as in the GL
+            // layer.
+            ASSERT(angle::EndsWith(name, "[0]"));
+            name.resize(name.length() - 3);
+        }
+        auto mapEntry = uniformMap.find(name);
         ASSERT(mapEntry != uniformMap.end());
         mD3DUniforms.push_back(mapEntry->second);
     }
 
     assignAllSamplerRegisters();
+    assignAllImageRegisters();
     initializeUniformStorage();
 }
 
 void ProgramD3D::defineUniformBase(const gl::Shader *shader,
                                    const sh::Uniform &uniform,
                                    D3DUniformMap *uniformMap)
 {
-    // Samplers get their registers assigned in assignAllSamplerRegisters.
-    if (uniform.isBuiltIn() || gl::IsSamplerType(uniform.type))
+    // Samplers get their registers assigned in assignAllSamplerRegisters, and images get their
+    // registers assigned in assignAllImageRegisters.
+    if (gl::IsSamplerType(uniform.type))
+    {
+        defineUniform(shader->getType(), uniform, uniform.name, HLSLRegisterType::Texture, nullptr,
+                      uniformMap);
+        return;
+    }
+    else if (gl::IsImageType(uniform.type))
     {
-        defineUniform(shader->getType(), uniform, uniform.name, nullptr, uniformMap);
+        if (uniform.readonly)
+        {
+            defineUniform(shader->getType(), uniform, uniform.name, HLSLRegisterType::Texture,
+                          nullptr, uniformMap);
+        }
+        else
+        {
+            defineUniform(shader->getType(), uniform, uniform.name,
+                          HLSLRegisterType::UnorderedAccessView, nullptr, uniformMap);
+        }
+        mImageBindingMap[uniform.name] = uniform.binding;
+        return;
+    }
+    else if (uniform.isBuiltIn())
+    {
+        defineUniform(shader->getType(), uniform, uniform.name, HLSLRegisterType::None, nullptr,
+                      uniformMap);
         return;
     }
 
     const ShaderD3D *shaderD3D = GetImplAs<ShaderD3D>(shader);
-
     unsigned int startRegister = shaderD3D->getUniformRegister(uniform.name);
-    ShShaderOutput outputType = shaderD3D->getCompilerOutputType();
+    ShShaderOutput outputType  = shaderD3D->getCompilerOutputType();
     sh::HLSLBlockEncoder encoder(sh::HLSLBlockEncoder::GetStrategyFor(outputType), true);
     encoder.skipRegisters(startRegister);
 
-    defineUniform(shader->getType(), uniform, uniform.name, &encoder, uniformMap);
+    defineUniform(shader->getType(), uniform, uniform.name, HLSLRegisterType::None, &encoder,
+                  uniformMap);
 }
 
 D3DUniform *ProgramD3D::getD3DUniformByName(const std::string &name)
 {
     for (D3DUniform *d3dUniform : mD3DUniforms)
     {
         if (d3dUniform->name == name)
         {
             return d3dUniform;
         }
     }
 
     return nullptr;
 }
 
+void ProgramD3D::defineStructUniformFields(GLenum shaderType,
+                                           const std::vector<sh::ShaderVariable> &fields,
+                                           const std::string &namePrefix,
+                                           const HLSLRegisterType regType,
+                                           sh::HLSLBlockEncoder *encoder,
+                                           D3DUniformMap *uniformMap)
+{
+    if (encoder)
+        encoder->enterAggregateType();
+
+    for (size_t fieldIndex = 0; fieldIndex < fields.size(); fieldIndex++)
+    {
+        const sh::ShaderVariable &field  = fields[fieldIndex];
+        const std::string &fieldFullName = (namePrefix + "." + field.name);
+
+        // Samplers get their registers assigned in assignAllSamplerRegisters.
+        // Also they couldn't use the same encoder as the rest of the struct, since they are
+        // extracted out of the struct by the shader translator.
+        if (gl::IsSamplerType(field.type))
+        {
+            defineUniform(shaderType, field, fieldFullName, regType, nullptr, uniformMap);
+        }
+        else
+        {
+            defineUniform(shaderType, field, fieldFullName, regType, encoder, uniformMap);
+        }
+    }
+
+    if (encoder)
+        encoder->exitAggregateType();
+}
+
+void ProgramD3D::defineArrayOfStructsUniformFields(GLenum 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
+    // innermost.
+    const unsigned int currentArraySize = uniform.getNestedArraySize(arrayNestingIndex);
+    for (unsigned int arrayElement = 0u; arrayElement < currentArraySize; ++arrayElement)
+    {
+        const std::string &elementString = prefix + ArrayString(arrayElement);
+        if (arrayNestingIndex + 1u < uniform.arraySizes.size())
+        {
+            defineArrayOfStructsUniformFields(shaderType, uniform, arrayNestingIndex + 1u,
+                                              elementString, regType, encoder, uniformMap);
+        }
+        else
+        {
+            defineStructUniformFields(shaderType, uniform.fields, elementString, regType, encoder,
+                                      uniformMap);
+        }
+    }
+}
+
+void ProgramD3D::defineArrayUniformElements(GLenum shaderType,
+                                            const sh::ShaderVariable &uniform,
+                                            const std::string &fullName,
+                                            const HLSLRegisterType regType,
+                                            sh::HLSLBlockEncoder *encoder,
+                                            D3DUniformMap *uniformMap)
+{
+    if (encoder)
+        encoder->enterAggregateType();
+
+    sh::ShaderVariable uniformElement = uniform;
+    uniformElement.arraySizes.pop_back();
+    for (unsigned int arrayIndex = 0u; arrayIndex < uniform.getOutermostArraySize(); ++arrayIndex)
+    {
+        std::string elementFullName = fullName + ArrayString(arrayIndex);
+        defineUniform(shaderType, uniformElement, elementFullName, regType, encoder, uniformMap);
+    }
+
+    if (encoder)
+        encoder->exitAggregateType();
+}
+
 void ProgramD3D::defineUniform(GLenum shaderType,
                                const sh::ShaderVariable &uniform,
                                const std::string &fullName,
+                               const HLSLRegisterType regType,
                                sh::HLSLBlockEncoder *encoder,
                                D3DUniformMap *uniformMap)
 {
     if (uniform.isStruct())
     {
-        for (unsigned int elementIndex = 0; elementIndex < uniform.elementCount(); elementIndex++)
+        if (uniform.isArray())
+        {
+            defineArrayOfStructsUniformFields(shaderType, uniform, 0u, fullName, regType, encoder,
+                                              uniformMap);
+        }
+        else
         {
-            const std::string &elementString = (uniform.isArray() ? ArrayString(elementIndex) : "");
-
-            if (encoder)
-                encoder->enterAggregateType();
-
-            for (size_t fieldIndex = 0; fieldIndex < uniform.fields.size(); fieldIndex++)
-            {
-                const sh::ShaderVariable &field  = uniform.fields[fieldIndex];
-                const std::string &fieldFullName = (fullName + elementString + "." + field.name);
-
-                // Samplers get their registers assigned in assignAllSamplerRegisters.
-                // Also they couldn't use the same encoder as the rest of the struct, since they are
-                // extracted out of the struct by the shader translator.
-                if (gl::IsSamplerType(field.type))
-                {
-                    defineUniform(shaderType, field, fieldFullName, nullptr, uniformMap);
-                }
-                else
-                {
-                    defineUniform(shaderType, field, fieldFullName, encoder, uniformMap);
-                }
-            }
-
-            if (encoder)
-                encoder->exitAggregateType();
+            defineStructUniformFields(shaderType, uniform.fields, fullName, regType, encoder,
+                                      uniformMap);
         }
         return;
     }
+    if (uniform.isArrayOfArrays())
+    {
+        defineArrayUniformElements(shaderType, uniform, fullName, regType, encoder, uniformMap);
+        return;
+    }
 
     // Not a struct. Arrays are treated as aggregate types.
     if (uniform.isArray() && encoder)
     {
         encoder->enterAggregateType();
     }
 
     // Advance the uniform offset, to track registers allocation for structs
     sh::BlockMemberInfo blockInfo =
-        encoder ? encoder->encodeType(uniform.type, uniform.arraySize, false)
+        encoder ? encoder->encodeType(uniform.type, uniform.arraySizes, false)
                 : sh::BlockMemberInfo::getDefaultBlockInfo();
 
     auto uniformMapEntry   = uniformMap->find(fullName);
     D3DUniform *d3dUniform = nullptr;
 
     if (uniformMapEntry != uniformMap->end())
     {
         d3dUniform = uniformMapEntry->second;
     }
     else
     {
-        d3dUniform = new D3DUniform(uniform.type, fullName, uniform.arraySize, true);
+        d3dUniform = new D3DUniform(uniform.type, regType, fullName, uniform.arraySizes, true);
         (*uniformMap)[fullName] = d3dUniform;
     }
 
     if (encoder)
     {
         d3dUniform->registerElement =
             static_cast<unsigned int>(sh::HLSLBlockEncoder::getBlockRegisterElement(blockInfo));
         unsigned int reg =
@@ -2164,32 +2403,32 @@ template <typename T>
 void ProgramD3D::setUniformImpl(const gl::VariableLocation &locationInfo,
                                 GLsizei count,
                                 const T *v,
                                 uint8_t *targetData,
                                 GLenum uniformType)
 {
     D3DUniform *targetUniform = mD3DUniforms[locationInfo.index];
     const int components      = targetUniform->typeInfo.componentCount;
-    unsigned int arrayElement = locationInfo.element;
+    const unsigned int arrayElementOffset = locationInfo.arrayIndex;
 
     if (targetUniform->typeInfo.type == uniformType)
     {
-        T *dest         = reinterpret_cast<T *>(targetData) + arrayElement * 4;
+        T *dest         = reinterpret_cast<T *>(targetData) + arrayElementOffset * 4;
         const T *source = v;
 
         for (GLint i = 0; i < count; i++, dest += 4, source += components)
         {
             memcpy(dest, source, components * sizeof(T));
         }
     }
     else
     {
         ASSERT(targetUniform->typeInfo.type == gl::VariableBoolVectorType(uniformType));
-        GLint *boolParams = reinterpret_cast<GLint *>(targetData) + arrayElement * 4;
+        GLint *boolParams = reinterpret_cast<GLint *>(targetData) + arrayElementOffset * 4;
 
         for (GLint i = 0; i < count; i++)
         {
             GLint *dest     = boolParams + (i * 4);
             const T *source = v + (i * components);
 
             for (int c = 0; c < components; c++)
             {
@@ -2204,17 +2443,17 @@ void ProgramD3D::setUniformInternal(GLin
 {
     const gl::VariableLocation &locationInfo = mState.getUniformLocations()[location];
     D3DUniform *targetUniform                = mD3DUniforms[locationInfo.index];
 
     if (targetUniform->typeInfo.isSampler)
     {
         ASSERT(uniformType == GL_INT);
         size_t size = count * sizeof(T);
-        auto dest   = &targetUniform->mSamplerData[locationInfo.element];
+        GLint *dest = &targetUniform->mSamplerData[locationInfo.arrayIndex];
         if (memcmp(dest, v, size) != 0)
         {
             memcpy(dest, v, size);
             mDirtySamplerMapping = true;
         }
         return;
     }
 
@@ -2242,23 +2481,24 @@ bool ProgramD3D::setUniformMatrixfvImpl(
                                         GLsizei countIn,
                                         GLboolean transpose,
                                         const GLfloat *value,
                                         uint8_t *targetData,
                                         GLenum targetUniformType)
 {
     D3DUniform *targetUniform = getD3DUniformFromLocation(location);
 
-    unsigned int elementCount = targetUniform->elementCount();
-    unsigned int arrayElement = mState.getUniformLocations()[location].element;
-    unsigned int count        = std::min(elementCount - arrayElement, static_cast<unsigned int>(countIn));
+    unsigned int elementCount       = targetUniform->getArraySizeProduct();
+    unsigned int arrayElementOffset = mState.getUniformLocations()[location].arrayIndex;
+    unsigned int count =
+        std::min(elementCount - arrayElementOffset, static_cast<unsigned int>(countIn));
 
     const unsigned int targetMatrixStride = (4 * rows);
-    GLfloat *target = reinterpret_cast<GLfloat *>(targetData + arrayElement * sizeof(GLfloat) *
-                                                                   targetMatrixStride);
+    GLfloat *target                       = reinterpret_cast<GLfloat *>(
+        targetData + arrayElementOffset * sizeof(GLfloat) * targetMatrixStride);
 
     bool dirty = false;
 
     for (unsigned int i = 0; i < count; i++)
     {
         // Internally store matrices as transposed versions to accomodate HLSL matrix indexing
         if (transpose == GL_FALSE)
         {
@@ -2307,84 +2547,72 @@ void ProgramD3D::setUniformMatrixfvInter
         if (setUniformMatrixfvImpl<cols, rows>(location, countIn, transpose, value,
                                                targetUniform->csData, targetUniformType))
         {
             mComputeUniformsDirty = true;
         }
     }
 }
 
-size_t ProgramD3D::getUniformBlockInfo(const sh::InterfaceBlock &interfaceBlock)
-{
-    ASSERT(interfaceBlock.staticUse || 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_STANDARD)
-    {
-        encoder = &std140Encoder;
-    }
-    else
-    {
-        encoder = &hlslEncoder;
-    }
-
-    GetUniformBlockInfo(interfaceBlock.fields, interfaceBlock.fieldPrefix(), encoder,
-                        interfaceBlock.isRowMajorLayout, &mBlockInfo);
-
-    return encoder->getBlockSize();
-}
-
 void ProgramD3D::assignAllSamplerRegisters()
 {
-    for (D3DUniform *d3dUniform : mD3DUniforms)
+    for (size_t uniformIndex = 0; uniformIndex < mD3DUniforms.size(); ++uniformIndex)
     {
-        if (d3dUniform->isSampler())
+        if (mD3DUniforms[uniformIndex]->isSampler())
         {
-            assignSamplerRegisters(d3dUniform);
+            assignSamplerRegisters(uniformIndex);
         }
     }
 }
 
-void ProgramD3D::assignSamplerRegisters(D3DUniform *d3dUniform)
+void ProgramD3D::assignSamplerRegisters(size_t uniformIndex)
 {
+    D3DUniform *d3dUniform = mD3DUniforms[uniformIndex];
     ASSERT(d3dUniform->isSampler());
+    // 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();
     if (computeShader)
     {
         const ShaderD3D *computeShaderD3D = GetImplAs<ShaderD3D>(mState.getAttachedComputeShader());
-        ASSERT(computeShaderD3D->hasUniform(d3dUniform));
-        d3dUniform->csRegisterIndex = computeShaderD3D->getUniformRegister(d3dUniform->name);
+        ASSERT(computeShaderD3D->hasUniform(baseName));
+        d3dUniform->csRegisterIndex =
+            computeShaderD3D->getUniformRegister(baseName) + registerOffset;
         ASSERT(d3dUniform->csRegisterIndex != GL_INVALID_INDEX);
-        AssignSamplers(d3dUniform->csRegisterIndex, d3dUniform->typeInfo, d3dUniform->arraySize,
-                       mSamplersCS, &mUsedComputeSamplerRange);
+        AssignSamplers(d3dUniform->csRegisterIndex, d3dUniform->typeInfo,
+                       d3dUniform->getArraySizeProduct(), mSamplersCS, &mUsedComputeSamplerRange);
     }
     else
     {
         const ShaderD3D *vertexShaderD3D = GetImplAs<ShaderD3D>(mState.getAttachedVertexShader());
         const ShaderD3D *fragmentShaderD3D =
             GetImplAs<ShaderD3D>(mState.getAttachedFragmentShader());
-        ASSERT(vertexShaderD3D->hasUniform(d3dUniform) ||
-               fragmentShaderD3D->hasUniform(d3dUniform));
-        if (vertexShaderD3D->hasUniform(d3dUniform))
+        ASSERT(vertexShaderD3D->hasUniform(baseName) || fragmentShaderD3D->hasUniform(baseName));
+        if (vertexShaderD3D->hasUniform(baseName))
         {
-            d3dUniform->vsRegisterIndex = vertexShaderD3D->getUniformRegister(d3dUniform->name);
+            d3dUniform->vsRegisterIndex =
+                vertexShaderD3D->getUniformRegister(baseName) + registerOffset;
             ASSERT(d3dUniform->vsRegisterIndex != GL_INVALID_INDEX);
-            AssignSamplers(d3dUniform->vsRegisterIndex, d3dUniform->typeInfo, d3dUniform->arraySize,
-                           mSamplersVS, &mUsedVertexSamplerRange);
+            AssignSamplers(d3dUniform->vsRegisterIndex, d3dUniform->typeInfo,
+                           d3dUniform->getArraySizeProduct(), mSamplersVS,
+                           &mUsedVertexSamplerRange);
         }
-        if (fragmentShaderD3D->hasUniform(d3dUniform))
+        if (fragmentShaderD3D->hasUniform(baseName))
         {
-            d3dUniform->psRegisterIndex = fragmentShaderD3D->getUniformRegister(d3dUniform->name);
+            d3dUniform->psRegisterIndex =
+                fragmentShaderD3D->getUniformRegister(baseName) + registerOffset;
             ASSERT(d3dUniform->psRegisterIndex != GL_INVALID_INDEX);
-            AssignSamplers(d3dUniform->psRegisterIndex, d3dUniform->typeInfo, d3dUniform->arraySize,
-                           mSamplersPS, &mUsedPixelSamplerRange);
+            AssignSamplers(d3dUniform->psRegisterIndex, d3dUniform->typeInfo,
+                           d3dUniform->getArraySizeProduct(), mSamplersPS, &mUsedPixelSamplerRange);
         }
     }
 }
 
 // static
 void ProgramD3D::AssignSamplers(unsigned int startSamplerIndex,
                                 const gl::UniformTypeInfo &typeInfo,
                                 unsigned int samplerCount,
@@ -2393,62 +2621,155 @@ void ProgramD3D::AssignSamplers(unsigned
 {
     unsigned int samplerIndex = startSamplerIndex;
 
     do
     {
         ASSERT(samplerIndex < outSamplers.size());
         Sampler *sampler            = &outSamplers[samplerIndex];
         sampler->active             = true;
-        sampler->textureType        = typeInfo.samplerTextureType;
+        sampler->textureType        = typeInfo.textureType;
         sampler->logicalTextureUnit = 0;
         *outUsedRange               = std::max(samplerIndex + 1, *outUsedRange);
         samplerIndex++;
     } while (samplerIndex < startSamplerIndex + samplerCount);
 }
 
+void ProgramD3D::assignAllImageRegisters()
+{
+    for (size_t uniformIndex = 0; uniformIndex < mD3DUniforms.size(); ++uniformIndex)
+    {
+        if (mD3DUniforms[uniformIndex]->isImage())
+        {
+            assignImageRegisters(uniformIndex);
+        }
+    }
+}
+
+void ProgramD3D::assignImageRegisters(size_t uniformIndex)
+{
+    D3DUniform *d3dUniform = mD3DUniforms[uniformIndex];
+    ASSERT(d3dUniform->isImage());
+    // 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();
+    if (computeShader)
+    {
+        const ShaderD3D *computeShaderD3D = GetImplAs<ShaderD3D>(mState.getAttachedComputeShader());
+        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)
+        {
+            AssignImages(d3dUniform->csRegisterIndex, bindingIter->second,
+                         d3dUniform->getArraySizeProduct(), mReadonlyImagesCS,
+                         &mUsedComputeReadonlyImageRange);
+        }
+        else if (d3dUniform->regType == HLSLRegisterType::UnorderedAccessView)
+        {
+            AssignImages(d3dUniform->csRegisterIndex, bindingIter->second,
+                         d3dUniform->getArraySizeProduct(), mImagesCS, &mUsedComputeImageRange);
+        }
+        else
+        {
+            UNREACHABLE();
+        }
+    }
+    else
+    {
+        // TODO(xinghua.cao@intel.com): Implement image variables in vertex shader and pixel shader.
+        UNIMPLEMENTED();
+    }
+}
+
+// static
+void ProgramD3D::AssignImages(unsigned int startImageIndex,
+                              int startLogicalImageUnit,
+                              unsigned int imageCount,
+                              std::vector<Image> &outImages,
+                              GLuint *outUsedRange)
+{
+    unsigned int imageIndex = startImageIndex;
+    // If declare without a binding qualifier, any uniform image variable (include all elements of
+    // unbound image array) shoud be bound to unit zero.
+    if (startLogicalImageUnit == -1)
+    {
+        ASSERT(imageIndex < outImages.size());
+        Image *image            = &outImages[imageIndex];
+        image->active           = true;
+        image->logicalImageUnit = 0;
+        *outUsedRange           = std::max(imageIndex + 1, *outUsedRange);
+        return;
+    }
+
+    unsigned int logcalImageUnit = startLogicalImageUnit;
+    do
+    {
+        ASSERT(imageIndex < outImages.size());
+        Image *image            = &outImages[imageIndex];
+        image->active           = true;
+        image->logicalImageUnit = logcalImageUnit;
+        *outUsedRange           = std::max(imageIndex + 1, *outUsedRange);
+        imageIndex++;
+        logcalImageUnit++;
+    } while (imageIndex < startImageIndex + imageCount);
+}
+
 void ProgramD3D::reset()
 {
     mVertexExecutables.clear();
     mPixelExecutables.clear();
 
     for (auto &geometryExecutable : mGeometryExecutables)
     {
         geometryExecutable.reset(nullptr);
     }
 
     mComputeExecutable.reset(nullptr);
 
     mVertexHLSL.clear();
     mVertexWorkarounds = angle::CompilerWorkaroundsD3D();
 
     mPixelHLSL.clear();
-    mPixelWorkarounds = angle::CompilerWorkaroundsD3D();
-    mUsesFragDepth = false;
+    mPixelWorkarounds         = angle::CompilerWorkaroundsD3D();
+    mUsesFragDepth            = false;
     mHasANGLEMultiviewEnabled = false;
     mUsesViewID               = false;
     mPixelShaderKey.clear();
-    mUsesPointSize = false;
+    mUsesPointSize         = false;
     mUsesFlatInterpolation = false;
 
     SafeDeleteContainer(mD3DUniforms);
     mD3DUniformBlocks.clear();
 
     mVertexUniformStorage.reset(nullptr);
     mFragmentUniformStorage.reset(nullptr);
     mComputeUniformStorage.reset(nullptr);
 
     mSamplersPS.clear();
     mSamplersVS.clear();
     mSamplersCS.clear();
-
-    mUsedVertexSamplerRange = 0;
-    mUsedPixelSamplerRange  = 0;
-    mUsedComputeSamplerRange = 0;
-    mDirtySamplerMapping    = true;
+    mImagesCS.clear();
+    mReadonlyImagesCS.clear();
+
+    mUsedVertexSamplerRange        = 0;
+    mUsedPixelSamplerRange         = 0;
+    mUsedComputeSamplerRange       = 0;
+    mDirtySamplerMapping           = true;
+    mUsedComputeImageRange         = 0;
+    mUsedComputeReadonlyImageRange = 0;
 
     mAttribLocationToD3DSemantic.fill(-1);
 
     mStreamOutVaryings.clear();
 
     mGeometryShaderPreamble.clear();
 
     dirtyAllUniforms();
@@ -2581,35 +2902,26 @@ void ProgramD3D::gatherTransformFeedback
         {
             if (builtins.glPointSize.enabled)
             {
                 mStreamOutVaryings.push_back(D3DVarying("PSIZE", 0, 1, outputSlot));
             }
         }
         else
         {
-            size_t subscript     = GL_INVALID_INDEX;
-            std::string baseName = gl::ParseResourceName(tfVaryingName, &subscript);
             for (const auto &registerInfo : varyingPacking.getRegisterList())
             {
                 const auto &varying   = *registerInfo.packedVarying->varying;
                 GLenum transposedType = gl::TransposeMatrixType(varying.type);
-                int componentCount = gl::VariableColumnCount(transposedType);
-                ASSERT(!varying.isBuiltIn());
-
-                // Transform feedback for varying structs is underspecified.
-                // See Khronos bug 9856.
-                // TODO(jmadill): Figure out how to be spec-compliant here.
-                if (registerInfo.packedVarying->isStructField() || varying.isStruct())
-                    continue;
+                int componentCount    = gl::VariableColumnCount(transposedType);
+                ASSERT(!varying.isBuiltIn() && !varying.isStruct());
 
                 // There can be more than one register assigned to a particular varying, and each
                 // register needs its own stream out entry.
-                if (baseName == registerInfo.packedVarying->varying->name &&
-                    (subscript == GL_INVALID_INDEX || subscript == registerInfo.varyingArrayIndex))
+                if (registerInfo.tfVaryingName() == tfVaryingName)
                 {
                     mStreamOutVaryings.push_back(D3DVarying(
                         varyingSemantic, registerInfo.semanticIndex, componentCount, outputSlot));
                 }
             }
         }
     }
 }
@@ -2619,49 +2931,16 @@ D3DUniform *ProgramD3D::getD3DUniformFro
     return mD3DUniforms[mState.getUniformLocations()[location].index];
 }
 
 const D3DUniform *ProgramD3D::getD3DUniformFromLocation(GLint location) const
 {
     return mD3DUniforms[mState.getUniformLocations()[location].index];
 }
 
-bool ProgramD3D::getUniformBlockSize(const std::string &blockName,
-                                     const std::string & /* blockMappedName */,
-                                     size_t *sizeOut) const
-{
-    std::string baseName = blockName;
-    gl::ParseAndStripArrayIndex(&baseName);
-
-    auto sizeIter = mBlockDataSizes.find(baseName);
-    if (sizeIter == mBlockDataSizes.end())
-    {
-        *sizeOut = 0;
-        return false;
-    }
-
-    *sizeOut = sizeIter->second;
-    return true;
-}
-
-bool ProgramD3D::getUniformBlockMemberInfo(const std::string &memberUniformName,
-                                           const std::string & /* memberUniformMappedName */,
-                                           sh::BlockMemberInfo *memberInfoOut) const
-{
-    auto infoIter = mBlockInfo.find(memberUniformName);
-    if (infoIter == mBlockInfo.end())
-    {
-        *memberInfoOut = sh::BlockMemberInfo::getDefaultBlockInfo();
-        return false;
-    }
-
-    *memberInfoOut = infoIter->second;
-    return true;
-}
-
 void ProgramD3D::setPathFragmentInputGen(const std::string &inputName,
                                          GLenum genMode,
                                          GLint components,
                                          const GLfloat *coeffs)
 {
     UNREACHABLE();
 }
 
@@ -2689,17 +2968,17 @@ bool ProgramD3D::hasPixelExecutableForCa
 
 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.element);
+    const uint8_t *srcPointer       = targetUniform->getDataPtrToElement(locationInfo.arrayIndex);
 
     if (gl::IsMatrixType(uniform.type))
     {
         GetMatrixUniform(gl::VariableColumnCount(uniform.type), gl::VariableRowCount(uniform.type),
                          dataOut, reinterpret_cast<const DestT *>(srcPointer));
     }
     else
     {
@@ -2743,9 +3022,61 @@ void ProgramD3D::updateCachedPixelExecut
         if (mPixelExecutables[executableIndex]->matchesSignature(mPixelShaderOutputLayoutCache))
         {
             mCachedPixelExecutableIndex = executableIndex;
             break;
         }
     }
 }
 
+void ProgramD3D::linkResources(const gl::Context *context,
+                               const gl::ProgramLinkedResources &resources)
+{
+    UniformBlockInfo uniformBlockInfo;
+
+    if (mState.getAttachedVertexShader())
+    {
+        uniformBlockInfo.getShaderBlockInfo(context, mState.getAttachedVertexShader());
+    }
+
+    if (mState.getAttachedFragmentShader())
+    {
+        uniformBlockInfo.getShaderBlockInfo(context, mState.getAttachedFragmentShader());
+    }
+
+    if (mState.getAttachedComputeShader())
+    {
+        uniformBlockInfo.getShaderBlockInfo(context, mState.getAttachedComputeShader());
+    }
+
+    // Gather interface block info.
+    auto getUniformBlockSize = [&uniformBlockInfo](const std::string &name,
+                                                   const std::string &mappedName, size_t *sizeOut) {
+        return uniformBlockInfo.getBlockSize(name, mappedName, sizeOut);
+    };
+
+    auto getUniformBlockMemberInfo = [&uniformBlockInfo](const std::string &name,
+                                                         const std::string &mappedName,
+                                                         sh::BlockMemberInfo *infoOut) {
+        return uniformBlockInfo.getBlockMemberInfo(name, mappedName, infoOut);
+    };
+
+    resources.uniformBlockLinker.linkBlocks(getUniformBlockSize, getUniformBlockMemberInfo);
+    initializeUniformBlocks();
+
+    // TODO(jiajia.qin@intel.com): Determine correct shader storage block info.
+    auto getShaderStorageBlockSize = [](const std::string &name, const std::string &mappedName,
+                                        size_t *sizeOut) {
+        *sizeOut = 0;
+        return true;
+    };
+
+    auto getShaderStorageBlockMemberInfo =
+        [](const std::string &name, const std::string &mappedName, sh::BlockMemberInfo *infoOut) {
+            *infoOut = sh::BlockMemberInfo::getDefaultBlockInfo();
+            return true;
+        };
+
+    resources.shaderStorageBlockLinker.linkBlocks(getShaderStorageBlockSize,
+                                                  getShaderStorageBlockMemberInfo);
+}
+
 }  // namespace rx
--- a/gfx/angle/src/libANGLE/renderer/d3d/ProgramD3D.h
+++ b/gfx/angle/src/libANGLE/renderer/d3d/ProgramD3D.h
@@ -12,58 +12,73 @@
 #include <string>
 #include <vector>
 
 #include "compiler/translator/blocklayoutHLSL.h"
 #include "libANGLE/Constants.h"
 #include "libANGLE/formatutils.h"
 #include "libANGLE/renderer/ProgramImpl.h"
 #include "libANGLE/renderer/d3d/DynamicHLSL.h"
+#include "libANGLE/renderer/d3d/RendererD3D.h"
 #include "platform/WorkaroundsD3D.h"
 
 namespace rx
 {
 class RendererD3D;
 class UniformStorageD3D;
 class ShaderExecutableD3D;
 
 #if !defined(ANGLE_COMPILE_OPTIMIZATION_LEVEL)
 // WARNING: D3DCOMPILE_OPTIMIZATION_LEVEL3 may lead to a DX9 shader compiler hang.
 // It should only be used selectively to work around specific bugs.
 #define ANGLE_COMPILE_OPTIMIZATION_LEVEL D3DCOMPILE_OPTIMIZATION_LEVEL1
 #endif
 
+enum class HLSLRegisterType : uint8_t
+{
+    None                = 0,
+    Texture             = 1,
+    UnorderedAccessView = 2
+};
+
 // Helper struct representing a single shader uniform
 // TODO(jmadill): Make uniform blocks shared between all programs, so we don't need separate
 // register indices.
 struct D3DUniform : private angle::NonCopyable
 {
-    D3DUniform(GLenum type, const std::string &nameIn, unsigned int arraySizeIn, bool defaultBlock);
+    D3DUniform(GLenum type,
+               HLSLRegisterType reg,
+               const std::string &nameIn,
+               const std::vector<unsigned int> &arraySizesIn,
+               bool defaultBlock);
     ~D3DUniform();
 
     bool isSampler() const;
-    unsigned int elementCount() const { return std::max(1u, arraySize); }
+    bool isImage() const;
+    bool isArray() const { return !arraySizes.empty(); }
+    unsigned int getArraySizeProduct() const;
     bool isReferencedByVertexShader() const;
     bool isReferencedByFragmentShader() const;
     bool isReferencedByComputeShader() const;
 
     const uint8_t *firstNonNullData() const;
     const uint8_t *getDataPtrToElement(size_t elementIndex) const;
 
     // Duplicated from the GL layer
     const gl::UniformTypeInfo &typeInfo;
-    std::string name;
-    unsigned int arraySize;
+    std::string name;  // Names of arrays don't include [0], unlike at the GL layer.
+    std::vector<unsigned int> arraySizes;
 
     // Pointer to a system copies of the data. Separate pointers for each uniform storage type.
     uint8_t *vsData;
     uint8_t *psData;
     uint8_t *csData;
 
     // Register information.
+    HLSLRegisterType regType;
     unsigned int vsRegisterIndex;
     unsigned int psRegisterIndex;
     unsigned int csRegisterIndex;
     unsigned int registerCount;
 
     // Register "elements" are used for uniform structs in ES3, to appropriately identify single
     // uniforms
     // inside aggregate types, which are packed according C-like structure rules.
@@ -146,34 +161,41 @@ class ProgramD3DMetadata final : angle::
     const ShaderD3D *mVertexShader;
     const ShaderD3D *mFragmentShader;
 };
 
 class ProgramD3D : public ProgramImpl
 {
   public:
     ProgramD3D(const gl::ProgramState &data, RendererD3D *renderer);
-    virtual ~ProgramD3D();
+    ~ProgramD3D() override;
 
     const std::vector<PixelShaderOutputVariable> &getPixelShaderKey() { return mPixelShaderKey; }
 
-    GLint getSamplerMapping(gl::SamplerType type,
+    GLint getSamplerMapping(gl::ShaderType type,
                             unsigned int samplerIndex,
                             const gl::Caps &caps) const;
-    GLenum getSamplerTextureType(gl::SamplerType type, unsigned int samplerIndex) const;
-    GLuint getUsedSamplerRange(gl::SamplerType type) const;
+    GLenum getSamplerTextureType(gl::ShaderType type, unsigned int samplerIndex) const;
+    GLuint getUsedSamplerRange(gl::ShaderType type) const;
 
     enum SamplerMapping
     {
         WasDirty,
         WasClean,
     };
 
     SamplerMapping updateSamplerMapping();
 
+    GLint getImageMapping(gl::ShaderType type,
+                          unsigned int imageIndex,
+                          bool readonly,
+                          const gl::Caps &caps) const;
+    GLuint getUsedImageRange(gl::ShaderType type, bool readonly) const;
+    GLenum getImageTextureType(gl::ShaderType type, unsigned int imageIndex, bool readonly) const;
+
     bool usesPointSize() const { return mUsesPointSize; }
     bool usesPointSpriteEmulation() const;
     bool usesGeometryShader(GLenum drawMode) const;
     bool usesGeometryShaderForPointSpriteEmulation() const;
     bool usesInstancedPointSpriteEmulation() const;
 
     gl::LinkResult load(const gl::Context *context,
                         gl::InfoLog &infoLog,
@@ -187,95 +209,88 @@ class ProgramD3D : public ProgramImpl
     gl::Error getGeometryExecutableForPrimitiveType(const gl::Context *context,
                                                     GLenum drawMode,
                                                     ShaderExecutableD3D **outExecutable,
                                                     gl::InfoLog *infoLog);
     gl::Error getPixelExecutableForCachedOutputLayout(ShaderExecutableD3D **outExectuable,
                                                       gl::InfoLog *infoLog);
     gl::Error getComputeExecutable(ShaderExecutableD3D **outExecutable);
     gl::LinkResult link(const gl::Context *context,
-                        const gl::VaryingPacking &packing,
+                        const gl::ProgramLinkedResources &resources,
                         gl::InfoLog &infoLog) override;
     GLboolean validate(const gl::Caps &caps, gl::InfoLog *infoLog) override;
 
-    bool getUniformBlockSize(const std::string &blockName,
-                             const std::string &blockMappedName,
-                             size_t *sizeOut) const override;
-    bool getUniformBlockMemberInfo(const std::string &memberUniformName,
-                                   const std::string &memberUniformMappedName,
-                                   sh::BlockMemberInfo *memberInfoOut) const override;
     void setPathFragmentInputGen(const std::string &inputName,
                                  GLenum genMode,
                                  GLint components,
                                  const GLfloat *coeffs) override;
 
     void initializeUniformStorage();
     void updateUniformBufferCache(const gl::Caps &caps,
                                   unsigned int reservedVertex,
                                   unsigned int reservedFragment);
     const std::vector<GLint> &getVertexUniformBufferCache() const;
     const std::vector<GLint> &getFragmentUniformBufferCache() const;
 
     void dirtyAllUniforms();
 
-    void setUniform1fv(GLint location, GLsizei count, const GLfloat *v);
-    void setUniform2fv(GLint location, GLsizei count, const GLfloat *v);
-    void setUniform3fv(GLint location, GLsizei count, const GLfloat *v);
-    void setUniform4fv(GLint location, GLsizei count, const GLfloat *v);
-    void setUniform1iv(GLint location, GLsizei count, const GLint *v);
-    void setUniform2iv(GLint location, GLsizei count, const GLint *v);
-    void setUniform3iv(GLint location, GLsizei count, const GLint *v);
-    void setUniform4iv(GLint location, GLsizei count, const GLint *v);
-    void setUniform1uiv(GLint location, GLsizei count, const GLuint *v);
-    void setUniform2uiv(GLint location, GLsizei count, const GLuint *v);
-    void setUniform3uiv(GLint location, GLsizei count, const GLuint *v);
-    void setUniform4uiv(GLint location, GLsizei count, const GLuint *v);
+    void setUniform1fv(GLint location, GLsizei count, const GLfloat *v) override;
+    void setUniform2fv(GLint location, GLsizei count, const GLfloat *v) override;
+    void setUniform3fv(GLint location, GLsizei count, const GLfloat *v) override;
+    void setUniform4fv(GLint location, GLsizei count, const GLfloat *v) override;
+    void setUniform1iv(GLint location, GLsizei count, const GLint *v) override;
+    void setUniform2iv(GLint location, GLsizei count, const GLint *v) override;
+    void setUniform3iv(GLint location, GLsizei count, const GLint *v) override;
+    void setUniform4iv(GLint location, GLsizei count, const GLint *v) override;
+    void setUniform1uiv(GLint location, GLsizei count, const GLuint *v) override;
+    void setUniform2uiv(GLint location, GLsizei count, const GLuint *v) override;
+    void setUniform3uiv(GLint location, GLsizei count, const GLuint *v) override;
+    void setUniform4uiv(GLint location, GLsizei count, const GLuint *v) override;
     void setUniformMatrix2fv(GLint location,
                              GLsizei count,
                              GLboolean transpose,
-                             const GLfloat *value);
+                             const GLfloat *value) override;
     void setUniformMatrix3fv(GLint location,
                              GLsizei count,
                              GLboolean transpose,
-                             const GLfloat *value);
+                             const GLfloat *value) override;
     void setUniformMatrix4fv(GLint location,
                              GLsizei count,
                              GLboolean transpose,
-                             const GLfloat *value);
+                             const GLfloat *value) override;
     void setUniformMatrix2x3fv(GLint location,
                                GLsizei count,
                                GLboolean transpose,
-                               const GLfloat *value);
+                               const GLfloat *value) override;
     void setUniformMatrix3x2fv(GLint location,
                                GLsizei count,
                                GLboolean transpose,
-                               const GLfloat *value);
+                               const GLfloat *value) override;
     void setUniformMatrix2x4fv(GLint location,
                                GLsizei count,
                                GLboolean transpose,
-                               const GLfloat *value);
+                               const GLfloat *value) override;
     void setUniformMatrix4x2fv(GLint location,
                                GLsizei count,
                                GLboolean transpose,
-                               const GLfloat *value);
+                               const GLfloat *value) override;
     void setUniformMatrix3x4fv(GLint location,
                                GLsizei count,
                                GLboolean transpose,
-                               const GLfloat *value);
+                               const GLfloat *value) override;
     void setUniformMatrix4x3fv(GLint location,
                                GLsizei count,
                                GLboolean transpose,
-                               const GLfloat *value);
+                               const GLfloat *value) override;
 
     void getUniformfv(const gl::Context *context, GLint location, GLfloat *params) const override;
     void getUniformiv(const gl::Context *context, GLint location, GLint *params) const override;
     void getUniformuiv(const gl::Context *context, GLint location, GLuint *params) const override;
 
     void setUniformBlockBinding(GLuint uniformBlockIndex, GLuint uniformBlockBinding) override;
-    void ensureUniformBlocksInitialized() override;
 
     UniformStorageD3D &getVertexUniformStorage() const { return *mVertexUniformStorage.get(); }
     UniformStorageD3D &getFragmentUniformStorage() const { return *mFragmentUniformStorage.get(); }
     UniformStorageD3D &getComputeUniformStorage() const { return *mComputeUniformStorage.get(); }
 
     unsigned int getSerial() const;
 
     const AttribIndexArray &getAttribLocationToD3DSemantics() const
@@ -364,36 +379,71 @@ class ProgramD3D : public ProgramImpl
     {
         Sampler();
 
         bool active;
         GLint logicalTextureUnit;
         GLenum 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,
+                                   const std::vector<sh::ShaderVariable> &fields,
+                                   const std::string &namePrefix,
+                                   const HLSLRegisterType regType,
+                                   sh::HLSLBlockEncoder *encoder,
+                                   D3DUniformMap *uniformMap);
+    void defineArrayOfStructsUniformFields(GLenum shaderType,
+                                           const sh::ShaderVariable &uniform,
+                                           unsigned int arrayNestingIndex,
+                                           const std::string &prefix,
+                                           const HLSLRegisterType regType,
+                                           sh::HLSLBlockEncoder *encoder,
+                                           D3DUniformMap *uniformMap);
+    void defineArrayUniformElements(GLenum shaderType,
+                                    const sh::ShaderVariable &uniform,
+                                    const std::string &fullName,
+                                    const HLSLRegisterType regType,
+                                    sh::HLSLBlockEncoder *encoder,
+                                    D3DUniformMap *uniformMap);
     void defineUniform(GLenum shaderType,
                        const sh::ShaderVariable &uniform,
                        const std::string &fullName,
+                       const HLSLRegisterType regType,
                        sh::HLSLBlockEncoder *encoder,
                        D3DUniformMap *uniformMap);
     void assignAllSamplerRegisters();
-    void assignSamplerRegisters(D3DUniform *d3dUniform);
+    void assignSamplerRegisters(size_t uniformIndex);
 
     static void AssignSamplers(unsigned int startSamplerIndex,
                                const gl::UniformTypeInfo &typeInfo,
                                unsigned int samplerCount,
                                std::vector<Sampler> &outSamplers,
                                GLuint *outUsedRange);
 
+    void assignAllImageRegisters();
+    void assignImageRegisters(size_t uniformIndex);
+    static void AssignImages(unsigned int startImageIndex,
+                             int startLogicalImageUnit,
+                             unsigned int imageCount,
+                             std::vector<Image> &outImages,
+                             GLuint *outUsedRange);
+
     template <typename DestT>
     void getUniformInternal(GLint location, DestT *dataOut) const;
 
     template <typename T>
     void setUniformImpl(const gl::VariableLocation &locationInfo,
                         GLsizei count,
                         const T *v,
                         uint8_t *targetData,
@@ -424,25 +474,25 @@ class ProgramD3D : public ProgramImpl
                                          const BuiltinInfo &builtins);
     D3DUniform *getD3DUniformByName(const std::string &name);
     D3DUniform *getD3DUniformFromLocation(GLint location);
     const D3DUniform *getD3DUniformFromLocation(GLint location) const;
 
     void initAttribLocationsToD3DSemantic(const gl::Context *context);
 
     void reset();
-
-    void initUniformBlockInfo(const gl::Context *context, gl::Shader *shader);
-    size_t getUniformBlockInfo(const sh::InterfaceBlock &interfaceBlock);
+    void initializeUniformBlocks();
 
     void updateCachedInputLayoutFromShader(const gl::Context *context);
     void updateCachedOutputLayoutFromShader();
     void updateCachedVertexExecutableIndex();
     void updateCachedPixelExecutableIndex();
 
+    void linkResources(const gl::Context *context, const gl::ProgramLinkedResources &resources);
+
     RendererD3D *mRenderer;
     DynamicHLSL *mDynamicHLSL;
 
     std::vector<std::unique_ptr<VertexExecutable>> mVertexExecutables;
     std::vector<std::unique_ptr<PixelExecutable>> mPixelExecutables;
     std::vector<std::unique_ptr<ShaderExecutableD3D>> mGeometryExecutables;
     std::unique_ptr<ShaderExecutableD3D> mComputeExecutable;
 
@@ -471,41 +521,44 @@ class ProgramD3D : public ProgramImpl
     std::vector<Sampler> mSamplersPS;
     std::vector<Sampler> mSamplersVS;
     std::vector<Sampler> mSamplersCS;
     GLuint mUsedVertexSamplerRange;
     GLuint mUsedPixelSamplerRange;
     GLuint mUsedComputeSamplerRange;
     bool mDirtySamplerMapping;
 
+    std::vector<Image> mImagesCS;
+    std::vector<Image> mReadonlyImagesCS;
+    GLuint mUsedComputeImageRange;
+    GLuint mUsedComputeReadonlyImageRange;
+
     // Cache for pixel shader output layout to save reallocations.
     std::vector<GLenum> mPixelShaderOutputLayoutCache;
     Optional<size_t> mCachedPixelExecutableIndex;
 
     AttribIndexArray mAttribLocationToD3DSemantic;
 
     unsigned int mSerial;
 
     std::vector<GLint> mVertexUBOCache;
     std::vector<GLint> mFragmentUBOCache;
     VertexExecutable::Signature mCachedVertexSignature;
     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;
 
-    std::map<std::string, sh::BlockMemberInfo> mBlockInfo;
-    std::map<std::string, size_t> mBlockDataSizes;
-
     static unsigned int issueSerial();
     static unsigned int mCurrentSerial;
 
     Serial mCurrentVertexArrayStateSerial;
 };
 }  // namespace rx
 
 #endif  // LIBANGLE_RENDERER_D3D_PROGRAMD3D_H_
--- a/gfx/angle/src/libANGLE/renderer/d3d/RenderTargetD3D.h
+++ b/gfx/angle/src/libANGLE/renderer/d3d/RenderTargetD3D.h
@@ -16,17 +16,17 @@
 
 namespace rx
 {
 
 class RenderTargetD3D : public FramebufferAttachmentRenderTarget
 {
   public:
     RenderTargetD3D();
-    virtual ~RenderTargetD3D();
+    ~RenderTargetD3D() override;
 
     virtual GLsizei getWidth() const = 0;
     virtual GLsizei getHeight() const = 0;
     virtual GLsizei getDepth() const = 0;
     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; }
--- a/gfx/angle/src/libANGLE/renderer/d3d/RenderbufferD3D.cpp
+++ b/gfx/angle/src/libANGLE/renderer/d3d/RenderbufferD3D.cpp
@@ -113,9 +113,18 @@ gl::Error RenderbufferD3D::getAttachment
 void RenderbufferD3D::deleteRenderTarget(const gl::Context *context)
 {
     if (mRenderTarget)
     {
         mRenderTarget->signalDirty(context);
         SafeDelete(mRenderTarget);
     }
 }
+
+gl::Error RenderbufferD3D::initializeContents(const gl::Context *context,
+                                              const gl::ImageIndex &imageIndex)
+{
+    RenderTargetD3D *renderTarget = nullptr;
+    ANGLE_TRY(getRenderTarget(context, &renderTarget));
+    return mRenderer->initRenderTarget(renderTarget);
+}
+
 }  // namespace rx
--- a/gfx/angle/src/libANGLE/renderer/d3d/RenderbufferD3D.h
+++ b/gfx/angle/src/libANGLE/renderer/d3d/RenderbufferD3D.h
@@ -20,17 +20,17 @@ class EGLImageD3D;
 class RendererD3D;
 class RenderTargetD3D;
 class SwapChainD3D;
 
 class RenderbufferD3D : public RenderbufferImpl
 {
   public:
     RenderbufferD3D(RendererD3D *renderer);
-    virtual ~RenderbufferD3D();
+    ~RenderbufferD3D() override;
 
     gl::Error onDestroy(const gl::Context *context) override;
 
     gl::Error setStorage(const gl::Context *context,
                          GLenum internalformat,
                          size_t width,
                          size_t height) override;
     gl::Error setStorageMultisample(const gl::Context *context,
@@ -41,16 +41,19 @@ class RenderbufferD3D : public Renderbuf
     gl::Error setStorageEGLImageTarget(const gl::Context *context, egl::Image *image) override;
 
     gl::Error getRenderTarget(const gl::Context *context, RenderTargetD3D **outRenderTarget);
     gl::Error getAttachmentRenderTarget(const gl::Context *context,
                                         GLenum binding,
                                         const gl::ImageIndex &imageIndex,
                                         FramebufferAttachmentRenderTarget **rtOut) override;
 
+    gl::Error initializeContents(const gl::Context *context,
+                                 const gl::ImageIndex &imageIndex) override;
+
   private:
     void deleteRenderTarget(const gl::Context *context);
 
     RendererD3D *mRenderer;
     RenderTargetD3D *mRenderTarget;
     EGLImageD3D *mImage;
 };
 
--- a/gfx/angle/src/libANGLE/renderer/d3d/RendererD3D.cpp
+++ b/gfx/angle/src/libANGLE/renderer/d3d/RendererD3D.cpp
@@ -46,22 +46,17 @@ RendererD3D::RendererD3D(egl::Display *d
 
 RendererD3D::~RendererD3D()
 {
     cleanup();
 }
 
 void RendererD3D::cleanup()
 {
-    for (auto &incompleteTexture : mIncompleteTextures)
-    {
-        ANGLE_SWALLOW_ERR(incompleteTexture.second->onDestroy(mDisplay->getProxyContext()));
-        incompleteTexture.second.set(mDisplay->getProxyContext(), nullptr);
-    }
-    mIncompleteTextures.clear();
+    mIncompleteTextures.onDestroy(mDisplay->getProxyContext());
 }
 
 bool RendererD3D::skipDraw(const gl::State &glState, GLenum drawMode)
 {
     if (drawMode == GL_POINTS)
     {
         bool usesPointSize = GetImplAs<ProgramD3D>(glState.getProgram())->usesPointSize();
 
@@ -73,103 +68,30 @@ bool RendererD3D::skipDraw(const gl::Sta
             // Notify developers of risking undefined behavior.
             WARN() << "Point rendering without writing to gl_PointSize.";
             return true;
         }
     }
     else if (gl::IsTriangleMode(drawMode))
     {
         if (glState.getRasterizerState().cullFace &&
-            glState.getRasterizerState().cullMode == GL_FRONT_AND_BACK)
+            glState.getRasterizerState().cullMode == gl::CullFaceMode::FrontAndBack)
         {
             return true;
         }
     }
 
     return false;
 }
 
-size_t RendererD3D::getBoundFramebufferTextures(const gl::ContextState &data,
-                                                FramebufferTextureArray *outTextureArray)
-{
-    size_t textureCount = 0;
-
-    const gl::Framebuffer *drawFramebuffer = data.getState().getDrawFramebuffer();
-    for (size_t i = 0; i < drawFramebuffer->getNumColorBuffers(); i++)
-    {
-        const gl::FramebufferAttachment *attachment = drawFramebuffer->getColorbuffer(i);
-        if (attachment && attachment->type() == GL_TEXTURE)
-        {
-            (*outTextureArray)[textureCount++] = attachment->getTexture();
-        }
-    }
-
-    const gl::FramebufferAttachment *depthStencilAttachment =
-        drawFramebuffer->getDepthOrStencilbuffer();
-    if (depthStencilAttachment && depthStencilAttachment->type() == GL_TEXTURE)
-    {
-        (*outTextureArray)[textureCount++] = depthStencilAttachment->getTexture();
-    }
-
-    std::sort(outTextureArray->begin(), outTextureArray->begin() + textureCount);
-
-    return textureCount;
-}
-
 gl::Error RendererD3D::getIncompleteTexture(const gl::Context *context,
                                             GLenum type,
                                             gl::Texture **textureOut)
 {
-    if (mIncompleteTextures.find(type) == mIncompleteTextures.end())
-    {
-        GLImplFactory *implFactory = context->getImplementation();
-        const GLubyte color[] = {0, 0, 0, 255};
-        const gl::Extents colorSize(1, 1, 1);
-        const gl::PixelUnpackState unpack(1, 0);
-        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;
-
-        // Skip the API layer to avoid needing to pass the Context and mess with dirty bits.
-        gl::Texture *t =
-            new gl::Texture(implFactory, std::numeric_limits<GLuint>::max(), createType);
-        if (createType == GL_TEXTURE_2D_MULTISAMPLE)
-        {
-            ANGLE_TRY(t->setStorageMultisample(nullptr, createType, 1, GL_RGBA8, colorSize, true));
-        }
-        else
-        {
-            ANGLE_TRY(t->setStorage(nullptr, createType, 1, GL_RGBA8, colorSize));
-        }
-        if (type == GL_TEXTURE_CUBE_MAP)
-        {
-            for (GLenum face = GL_TEXTURE_CUBE_MAP_POSITIVE_X;
-                 face <= GL_TEXTURE_CUBE_MAP_NEGATIVE_Z; face++)
-            {
-                ANGLE_TRY(t->getImplementation()->setSubImage(nullptr, face, 0, area, GL_RGBA8,
-                                                              GL_UNSIGNED_BYTE, unpack, color));
-            }
-        }
-        else if (type == GL_TEXTURE_2D_MULTISAMPLE)
-        {
-            gl::ColorF clearValue(0, 0, 0, 1);
-            gl::ImageIndex index = gl::ImageIndex::Make2DMultisample();
-            ANGLE_TRY(GetImplAs<TextureD3D>(t)->clearLevel(context, index, clearValue, 1.0f, 0));
-        }
-        else
-        {
-            ANGLE_TRY(t->getImplementation()->setSubImage(nullptr, createType, 0, area, GL_RGBA8,
-                                                          GL_UNSIGNED_BYTE, unpack, color));
-        }
-        mIncompleteTextures[type].set(context, t);
-    }
-
-    *textureOut = mIncompleteTextures[type].get();
-    return gl::NoError();
+    return mIncompleteTextures.getIncompleteTexture(context, type, this, textureOut);
 }
 
 GLenum RendererD3D::getResetStatus()
 {
     if (!mDeviceLost)
     {
         if (testDeviceLost())
         {
@@ -262,32 +184,48 @@ const gl::Limitations &RendererD3D::getN
     return mNativeLimitations;
 }
 
 angle::WorkerThreadPool *RendererD3D::getWorkerThreadPool()
 {
     return &mWorkerThreadPool;
 }
 
-bool RendererD3D::isRobustResourceInitEnabled() const
-{
-    return mDisplay->isRobustResourceInitEnabled();
-}
-
 Serial RendererD3D::generateSerial()
 {
     return mSerialFactory.generate();
 }
 
 bool InstancedPointSpritesActive(ProgramD3D *programD3D, GLenum mode)
 {
     return programD3D->usesPointSize() && programD3D->usesInstancedPointSpriteEmulation() &&
            mode == GL_POINTS;
 }
 
+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);
+    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*/)
+{
+    // No-op by default. Only implemented in D3D11.
+}
+
 unsigned int GetBlendSampleMask(const gl::State &glState, int samples)
 {
     unsigned int mask   = 0;
     if (glState.isSampleCoverageEnabled())
     {
         GLfloat coverageValue = glState.getSampleCoverageValue();
         if (coverageValue != 0)
         {
@@ -311,12 +249,17 @@ unsigned int GetBlendSampleMask(const gl
             mask = ~mask;
         }
     }
     else
     {
         mask = 0xFFFFFFFF;
     }
 
+    if (glState.isSampleMaskEnabled())
+    {
+        mask &= glState.getSampleMaskWord(0);
+    }
+
     return mask;
 }
 
 }  // namespace rx
--- a/gfx/angle/src/libANGLE/renderer/d3d/RendererD3D.h
+++ b/gfx/angle/src/libANGLE/renderer/d3d/RendererD3D.h
@@ -13,16 +13,17 @@
 
 #include "common/Color.h"
 #include "common/MemoryBuffer.h"
 #include "common/debug.h"
 #include "libANGLE/ContextState.h"
 #include "libANGLE/Device.h"
 #include "libANGLE/Version.h"
 #include "libANGLE/WorkerThread.h"
+#include "libANGLE/angletypes.h"
 #include "libANGLE/formatutils.h"
 #include "libANGLE/renderer/d3d/VertexDataManager.h"
 #include "libANGLE/renderer/d3d/formatutilsD3D.h"
 #include "libANGLE/renderer/renderer_utils.h"
 #include "platform/WorkaroundsD3D.h"
 
 namespace egl
 {
@@ -67,25 +68,16 @@ struct DeviceIdentifier
 };
 
 enum RendererClass
 {
     RENDERER_D3D11,
     RENDERER_D3D9
 };
 
-enum ShaderType
-{
-    SHADER_VERTEX,
-    SHADER_PIXEL,
-    SHADER_GEOMETRY,
-    SHADER_COMPUTE,
-    SHADER_TYPE_MAX
-};
-
 // Useful for unit testing
 class BufferFactoryD3D : angle::NonCopyable
 {
   public:
     BufferFactoryD3D() {}
     virtual ~BufferFactoryD3D() {}
 
     virtual VertexBuffer *createVertexBuffer() = 0;
@@ -99,25 +91,23 @@ class BufferFactoryD3D : angle::NonCopya
     // function.
     virtual gl::ErrorOrResult<unsigned int> getVertexSpaceRequired(
         const gl::VertexAttribute &attrib,
         const gl::VertexBinding &binding,
         GLsizei count,
         GLsizei instances) const = 0;
 };
 
-using AttribIndexArray = std::array<int, gl::MAX_VERTEX_ATTRIBS>;
-using FramebufferTextureArray =
-    std::array<gl::Texture *, gl::IMPLEMENTATION_MAX_FRAMEBUFFER_ATTACHMENTS>;
+using AttribIndexArray = gl::AttribArray<int>;
 
-class RendererD3D : public BufferFactoryD3D
+class RendererD3D : public BufferFactoryD3D, public MultisampleTextureInitializer
 {
   public:
     explicit RendererD3D(egl::Display *display);
-    virtual ~RendererD3D();
+    ~RendererD3D() override;
 
     virtual egl::Error initialize() = 0;
 
     virtual egl::ConfigSet generateConfigs() = 0;
     virtual void generateDisplayExtensions(egl::DisplayExtensions *outExtensions) const = 0;
 
     virtual ContextImpl *createContext(const gl::ContextState &state) = 0;
 
@@ -205,23 +195,23 @@ class RendererD3D : public BufferFactory
 
     // RenderTarget creation
     virtual gl::Error createRenderTarget(int width, int height, GLenum format, GLsizei samples, RenderTargetD3D **outRT) = 0;
     virtual gl::Error createRenderTargetCopy(RenderTargetD3D *source, RenderTargetD3D **outRT) = 0;
 
     // Shader operations
     virtual gl::Error loadExecutable(const uint8_t *function,
                                      size_t length,
-                                     ShaderType type,
+                                     gl::ShaderType type,
                                      const std::vector<D3DVarying> &streamOutVaryings,
                                      bool separatedOutputBuffers,
-                                     ShaderExecutableD3D **outExecutable) = 0;
+                                     ShaderExecutableD3D **outExecutable)      = 0;
     virtual gl::Error compileToExecutable(gl::InfoLog &infoLog,
                                           const std::string &shaderHLSL,
-                                          ShaderType type,
+                                          gl::ShaderType type,
                                           const std::vector<D3DVarying> &streamOutVaryings,
                                           bool separatedOutputBuffers,
                                           const angle::CompilerWorkaroundsD3D &workarounds,
                                           ShaderExecutableD3D **outExectuable) = 0;
     virtual gl::Error ensureHLSLCompilerInitialized()                          = 0;
 
     virtual UniformStorageD3D *createUniformStorage(size_t storageSize) = 0;
 
@@ -251,17 +241,17 @@ class RendererD3D : public BufferFactory
     virtual TextureStorage *createTextureStorageCube(GLenum internalformat, bool renderTarget, int size, int levels, bool hintLevelZeroOnly) = 0;
     virtual TextureStorage *createTextureStorage3D(GLenum internalformat, bool renderTarget, GLsizei width, GLsizei height, GLsizei depth, int levels) = 0;
     virtual TextureStorage *createTextureStorage2DArray(GLenum internalformat, bool renderTarget, GLsizei width, GLsizei height, GLsizei depth, int levels) = 0;
     virtual TextureStorage *createTextureStorage2DMultisample(GLenum internalformat,
                                                               GLsizei width,
                                                               GLsizei height,
                                                               int levels,
                                                               int samples,
-                                                              GLboolean fixedSampleLocations) = 0;
+                                                              bool fixedSampleLocations) = 0;
 
     // Buffer-to-texture and Texture-to-buffer copies
     virtual bool supportsFastCopyBufferToTexture(GLenum internalFormat) const = 0;
     virtual gl::Error fastCopyBufferToTexture(const gl::Context *context,
                                               const gl::PixelUnpackState &unpack,
                                               unsigned int offset,
                                               RenderTargetD3D *destRenderTarget,
                                               GLenum destinationFormat,
@@ -288,56 +278,57 @@ class RendererD3D : public BufferFactory
                                         const float clearDepthValue,
                                         const unsigned int clearStencilValue) = 0;
 
     virtual egl::Error getEGLDevice(DeviceImpl **device) = 0;
 
     bool presentPathFastEnabled() const { return mPresentPathFastEnabled; }
 
     // Stream creation
-    virtual StreamProducerImpl *createStreamProducerD3DTextureNV12(
+    virtual StreamProducerImpl *createStreamProducerD3DTexture(
         egl::Stream::ConsumerType consumerType,
         const egl::AttributeMap &attribs) = 0;
 
     const gl::Caps &getNativeCaps() const;
     const gl::TextureCapsMap &getNativeTextureCaps() const;
     const gl::Extensions &getNativeExtensions() const;
     const gl::Limitations &getNativeLimitations() const;
 
     // Necessary hack for default framebuffers in D3D.
     virtual FramebufferImpl *createDefaultFramebuffer(const gl::FramebufferState &state) = 0;
 
     virtual gl::Version getMaxSupportedESVersion() const = 0;
 
-    angle::WorkerThreadPool *getWorkerThreadPool();
+    gl::Error initRenderTarget(RenderTargetD3D *renderTarget);
 
-    bool isRobustResourceInitEnabled() const;
-
-    size_t getBoundFramebufferTextures(const gl::ContextState &data,
-                                       FramebufferTextureArray *outTextureArray);
+    angle::WorkerThreadPool *getWorkerThreadPool();
 
     gl::Error getIncompleteTexture(const gl::Context *context,
                                    GLenum type,
                                    gl::Texture **textureOut);
 
     Serial generateSerial();
 
     virtual bool canSelectViewInVertexShader() const = 0;
 
+    gl::Error initializeMultisampleTextureToBlack(const gl::Context *context,
+                                                  gl::Texture *glTexture) override;
+
+    // Should really be handled by Program dirty bits, but that requires splitting Program9/11.
+    virtual void onDirtyUniformBlockBinding(GLuint uniformBlockIndex);
+
   protected:
     virtual bool getLUID(LUID *adapterLuid) const = 0;
     virtual void generateCaps(gl::Caps *outCaps,
                               gl::TextureCapsMap *outTextureCaps,
                               gl::Extensions *outExtensions,
                               gl::Limitations *outLimitations) const = 0;
 
     void cleanup();
 
-    // dirtyPointer is a special value that will make the comparison with any valid pointer fail and force the renderer to re-apply the state.
-
     bool skipDraw(const gl::State &glState, GLenum drawMode);
 
     egl::Display *mDisplay;
 
     bool mPresentPathFastEnabled;
 
   private:
     void ensureCapsInitialized() const;
@@ -345,17 +336,17 @@ class RendererD3D : public BufferFactory
     virtual angle::WorkaroundsD3D generateWorkarounds() const = 0;
 
     mutable bool mCapsInitialized;
     mutable gl::Caps mNativeCaps;
     mutable gl::TextureCapsMap mNativeTextureCaps;
     mutable gl::Extensions mNativeExtensions;
     mutable gl::Limitations mNativeLimitations;
 
-    gl::TextureMap mIncompleteTextures;
+    IncompleteTextureSet mIncompleteTextures;
 
     mutable bool mWorkaroundsInitialized;
     mutable angle::WorkaroundsD3D mWorkarounds;
 
     bool mDisjoint;
     bool mDeviceLost;
 
     angle::WorkerThreadPool mWorkerThreadPool;
--- a/gfx/angle/src/libANGLE/renderer/d3d/ShaderD3D.cpp
+++ b/gfx/angle/src/libANGLE/renderer/d3d/ShaderD3D.cpp
@@ -68,16 +68,20 @@ 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.skipConstantRegisterZero)
+    {
+        mAdditionalOptions |= SH_SKIP_D3D_CONSTANT_REGISTER_ZERO;
+    }
     if (extensions.multiview)
     {
         mAdditionalOptions |= SH_INITIALIZE_BUILTINS_FOR_INSTANCED_MULTIVIEW;
     }
 }
 
 ShaderD3D::~ShaderD3D()
 {
@@ -177,19 +181,19 @@ ShCompileOptions ShaderD3D::prepareSourc
 #endif
 
     additionalOptions |= mAdditionalOptions;
 
     *shaderSourceStream << source;
     return additionalOptions;
 }
 
-bool ShaderD3D::hasUniform(const D3DUniform *d3dUniform) const
+bool ShaderD3D::hasUniform(const std::string &name) const
 {
-    return mUniformRegisterMap.find(d3dUniform->name) != mUniformRegisterMap.end();
+    return mUniformRegisterMap.find(name) != mUniformRegisterMap.end();
 }
 
 const std::map<std::string, unsigned int> &GetUniformRegisterMap(
     const std::map<std::string, unsigned int> *uniformRegisterMap)
 {
     ASSERT(uniformRegisterMap);
     return *uniformRegisterMap;
 }
--- a/gfx/angle/src/libANGLE/renderer/d3d/ShaderD3D.h
+++ b/gfx/angle/src/libANGLE/renderer/d3d/ShaderD3D.h
@@ -31,28 +31,28 @@ class RendererD3D;
 struct D3DUniform;
 
 class ShaderD3D : public ShaderImpl
 {
   public:
     ShaderD3D(const gl::ShaderState &data,
               const angle::WorkaroundsD3D &workarounds,
               const gl::Extensions &extensions);
-    virtual ~ShaderD3D();
+    ~ShaderD3D() override;
 
     // ShaderImpl implementation
     ShCompileOptions prepareSourceAndReturnOptions(std::stringstream *sourceStream,
                                                    std::string *sourcePath) override;
     bool postTranslateCompile(gl::Compiler *compiler, std::string *infoLog) override;
     std::string getDebugInfo() const override;
 
     // D3D-specific methods
     void uncompile();
 
-    bool hasUniform(const D3DUniform *d3dUniform) const;
+    bool hasUniform(const std::string &name) const;
 
     // Query regular uniforms with their name. Query sampler fields of structs with field selection
     // using dot (.) operator.
     unsigned int getUniformRegister(const std::string &uniformName) const;
 
     unsigned int getUniformBlockRegister(const std::string &blockName) const;
     void appendDebugInfo(const std::string &info) const { mDebugInfo += info; }
 
--- a/gfx/angle/src/libANGLE/renderer/d3d/TextureD3D.cpp
+++ b/gfx/angle/src/libANGLE/renderer/d3d/TextureD3D.cpp
@@ -30,29 +30,29 @@
 namespace rx
 {
 
 namespace
 {
 
 gl::Error GetUnpackPointer(const gl::Context *context,
                            const gl::PixelUnpackState &unpack,
+                           gl::Buffer *unpackBuffer,
                            const uint8_t *pixels,
                            ptrdiff_t layerOffset,
                            const uint8_t **pointerOut)
 {
-    if (unpack.pixelBuffer.id() != 0)
+    if (unpackBuffer)
     {
         // Do a CPU readback here, if we have an unpack buffer bound and the fast GPU path is not supported
-        gl::Buffer *pixelBuffer = unpack.pixelBuffer.get();
         ptrdiff_t offset = reinterpret_cast<ptrdiff_t>(pixels);
 
         // TODO: this is the only place outside of renderer that asks for a buffers raw data.
         // This functionality should be moved into renderer and the getData method of BufferImpl removed.
-        BufferD3D *bufferD3D = GetImplAs<BufferD3D>(pixelBuffer);
+        BufferD3D *bufferD3D = GetImplAs<BufferD3D>(unpackBuffer);
         ASSERT(bufferD3D);
         const uint8_t *bufferData = nullptr;
         ANGLE_TRY(bufferD3D->getData(context, &bufferData));
         *pointerOut = bufferData + offset;
     }
     else
     {
         *pointerOut = pixels;
@@ -102,22 +102,23 @@ gl::Error TextureD3D::getNativeTexture(c
     ASSERT(outStorage);
 
     *outStorage = mTexStorage;
     return gl::NoError();
 }
 
 gl::Error TextureD3D::getImageAndSyncFromStorage(const gl::Context *context,
                                                  const gl::ImageIndex &index,
-                                                 ImageD3D **outImage) const
+                                                 ImageD3D **outImage)
 {
     ImageD3D *image = getImage(index);
-    if (mTexStorage)
+    if (mTexStorage && mTexStorage->isRenderTarget())
     {
         ANGLE_TRY(image->copyFromTexStorage(context, index, mTexStorage));
+        mDirtyImages = true;
     }
     *outImage = image;
     return gl::NoError();
 }
 
 GLint TextureD3D::getLevelZeroWidth() const
 {
     ASSERT(gl::CountLeadingZeros(static_cast<uint32_t>(getBaseLevelWidth())) > getBaseLevel());
@@ -148,21 +149,16 @@ GLint TextureD3D::getBaseLevelHeight() c
 }
 
 GLint TextureD3D::getBaseLevelDepth() const
 {
     const ImageD3D *baseImage = getBaseLevelImage();
     return (baseImage ? baseImage->getDepth() : 0);
 }
 
-bool TextureD3D::shouldForceReleaseImagesOnSetImage(const uint8_t *pixels) const
-{
-    return mRenderer->isRobustResourceInitEnabled() && pixels == nullptr;
-}
-
 // Note: "base level image" is loosely defined to be any image from the base level,
 // where in the base of 2D array textures and cube maps there are several. Don't use
 // 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);
 }
@@ -177,17 +173,17 @@ gl::Error TextureD3D::setStorage(const g
     return gl::InternalError();
 }
 
 gl::Error TextureD3D::setStorageMultisample(const gl::Context *context,
                                             GLenum target,
                                             GLsizei samples,
                                             GLint internalFormat,
                                             const gl::Extents &size,
-                                            GLboolean fixedSampleLocations)
+                                            bool fixedSampleLocations)
 {
     UNREACHABLE();
     return gl::InternalError();
 }
 
 bool TextureD3D::shouldUseSetData(const ImageD3D *image) const
 {
     if (!mRenderer->getWorkarounds().setDataFasterThanImageUpload)
@@ -216,28 +212,30 @@ bool TextureD3D::shouldUseSetData(const 
 gl::Error TextureD3D::setImageImpl(const gl::Context *context,
                                    const gl::ImageIndex &index,
                                    GLenum type,
                                    const gl::PixelUnpackState &unpack,
                                    const uint8_t *pixels,
                                    ptrdiff_t layerOffset)
 {
     ImageD3D *image = getImage(index);
+    gl::Buffer *unpackBuffer =
+        context->getGLState().getTargetBuffer(gl::BufferBinding::PixelUnpack);
     ASSERT(image);
 
     // No-op
     if (image->getWidth() == 0 || image->getHeight() == 0 || image->getDepth() == 0)
     {
         return gl::NoError();
     }
 
     // We no longer need the "GLenum format" parameter to TexImage to determine what data format "pixels" contains.
     // From our image internal format we know how many channels to expect, and "type" gives the format of pixel's components.
     const uint8_t *pixelData = nullptr;
-    ANGLE_TRY(GetUnpackPointer(context, unpack, pixels, layerOffset, &pixelData));
+    ANGLE_TRY(GetUnpackPointer(context, unpack, unpackBuffer, pixels, layerOffset, &pixelData));
 
     if (pixelData != nullptr)
     {
         if (shouldUseSetData(image))
         {
             ANGLE_TRY(
                 mTexStorage->setData(context, index, image, nullptr, type, unpack, pixelData));
         }
@@ -260,17 +258,19 @@ gl::Error TextureD3D::subImage(const gl:
                                GLenum format,
                                GLenum type,
                                const gl::PixelUnpackState &unpack,
                                const uint8_t *pixels,
                                ptrdiff_t layerOffset)
 {
     // CPU readback & copy where direct GPU copy is not supported
     const uint8_t *pixelData = nullptr;
-    ANGLE_TRY(GetUnpackPointer(context, unpack, pixels, layerOffset, &pixelData));
+    gl::Buffer *unpackBuffer =
+        context->getGLState().getTargetBuffer(gl::BufferBinding::PixelUnpack);
+    ANGLE_TRY(GetUnpackPointer(context, unpack, unpackBuffer, pixels, layerOffset, &pixelData));
 
     if (pixelData != nullptr)
     {
         ImageD3D *image = getImage(index);
         ASSERT(image);
 
         if (shouldUseSetData(image))
         {
@@ -297,17 +297,19 @@ gl::Error TextureD3D::setCompressedImage
     if (image->getWidth() == 0 || image->getHeight() == 0 || image->getDepth() == 0)
     {
         return gl::NoError();
     }
 
     // We no longer need the "GLenum format" parameter to TexImage to determine what data format "pixels" contains.
     // From our image internal format we know how many channels to expect, and "type" gives the format of pixel's components.
     const uint8_t *pixelData = nullptr;
-    ANGLE_TRY(GetUnpackPointer(context, unpack, pixels, layerOffset, &pixelData));
+    gl::Buffer *unpackBuffer =
+        context->getGLState().getTargetBuffer(gl::BufferBinding::PixelUnpack);
+    ANGLE_TRY(GetUnpackPointer(context, unpack, unpackBuffer, pixels, layerOffset, &pixelData));
 
     if (pixelData != nullptr)
     {
         gl::Box fullImageArea(0, 0, 0, image->getWidth(), image->getHeight(), image->getDepth());
         ANGLE_TRY(image->loadCompressedData(context, fullImageArea, pixelData));
 
         mDirtyImages = true;
     }
@@ -319,34 +321,37 @@ gl::Error TextureD3D::subImageCompressed
                                          const gl::ImageIndex &index,
                                          const gl::Box &area,
                                          GLenum format,
                                          const gl::PixelUnpackState &unpack,
                                          const uint8_t *pixels,
                                          ptrdiff_t layerOffset)
 {
     const uint8_t *pixelData = nullptr;
-    ANGLE_TRY(GetUnpackPointer(context, unpack, pixels, layerOffset, &pixelData));
+    gl::Buffer *unpackBuffer =
+        context->getGLState().getTargetBuffer(gl::BufferBinding::PixelUnpack);
+    ANGLE_TRY(GetUnpackPointer(context, unpack, unpackBuffer, pixels, layerOffset, &pixelData));
 
     if (pixelData != nullptr)
     {
         ImageD3D *image = getImage(index);
         ASSERT(image);
 
         ANGLE_TRY(image->loadCompressedData(context, area, pixelData));
 
         mDirtyImages = true;
     }
 
     return gl::NoError();
 }
 
-bool TextureD3D::isFastUnpackable(const gl::PixelUnpackState &unpack, GLenum sizedInternalFormat)
+bool TextureD3D::isFastUnpackable(const gl::Buffer *unpackBuffer, GLenum sizedInternalFormat)
 {
-    return unpack.pixelBuffer.id() != 0 && mRenderer->supportsFastCopyBufferToTexture(sizedInternalFormat);
+    return unpackBuffer != nullptr &&
+           mRenderer->supportsFastCopyBufferToTexture(sizedInternalFormat);
 }
 
 gl::Error TextureD3D::fastUnpackPixels(const gl::Context *context,
                                        const gl::PixelUnpackState &unpack,
                                        const uint8_t *pixels,
                                        const gl::Box &destArea,
                                        GLenum sizedInternalFormat,
                                        GLenum type,
@@ -504,16 +509,18 @@ gl::Error TextureD3D::generateMipmapUsin
             {
                 // CPU-side mipmapping
                 ANGLE_TRY(
                     mRenderer->generateMipmap(context, getImage(destIndex), getImage(sourceIndex)));
             }
         }
     }
 
+    mDirtyImages = true;
+
     if (mTexStorage)
     {
         ANGLE_TRY(updateStorage(context));
     }
 
     return gl::NoError();
 }
 
@@ -570,17 +577,21 @@ gl::Error TextureD3D::ensureRenderTarget
         }
     }
 
     return gl::NoError();
 }
 
 bool TextureD3D::canCreateRenderTargetForImage(const gl::ImageIndex &index) const
 {
+    if (index.type == GL_TEXTURE_2D_MULTISAMPLE)
+        return true;
+
     ImageD3D *image = getImage(index);
+    ASSERT(image);
     bool levelsComplete = (isImageComplete(index) && isImageComplete(getImageIndex(0, 0)));
     return (image->isRenderableFormat() && levelsComplete);
 }
 
 gl::Error TextureD3D::commitRegion(const gl::Context *context,
                                    const gl::ImageIndex &index,
                                    const gl::Box &region)
 {
@@ -631,49 +642,110 @@ gl::Error TextureD3D::setBaseLevel(const
     return gl::NoError();
 }
 
 void TextureD3D::syncState(const gl::Texture::DirtyBits &dirtyBits)
 {
     // TODO(geofflang): Use dirty bits
 }
 
-gl::Error TextureD3D::clearLevel(const gl::Context *context,
-                                 const gl::ImageIndex &index,
-                                 const gl::ColorF &clearColorValue,
-                                 const float clearDepthValue,
-                                 const unsigned int clearStencilValue)
-{
-    TextureStorage *storage = nullptr;
-    ANGLE_TRY(getNativeTexture(context, &storage));
-    RenderTargetD3D *renderTargetD3D = nullptr;
-    ANGLE_TRY(storage->getRenderTarget(context, index, &renderTargetD3D));
-
-    ANGLE_TRY(mRenderer->clearRenderTarget(renderTargetD3D, clearColorValue, clearDepthValue,
-                                           clearStencilValue));
-
-    return gl::NoError();
-}
-
 gl::Error TextureD3D::releaseTexStorage(const gl::Context *context)
 {
     if (!mTexStorage)
     {
         return gl::NoError();
     }
     auto err = mTexStorage->onDestroy(context);
     SafeDelete(mTexStorage);
     return err;
 }
 
 gl::Error TextureD3D::onDestroy(const gl::Context *context)
 {
     return releaseTexStorage(context);
 }
 
+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)
+    {
+        imageIndex.layerIndex = gl::ImageIndex::ENTIRE_LEVEL;
+    }
+    else if (imageIndex.type == GL_TEXTURE_2D_ARRAY &&
+             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();
+    }
+
+    // Force image clean.
+    ImageD3D *image = getImage(imageIndex);
+    if (image)
+    {
+        image->markClean();
+    }
+
+    // Fast path: can use a render target clear.
+    if (canCreateRenderTargetForImage(imageIndex))
+    {
+        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(formatInfo.type, image->getWidth(), 1, 0),
+                     imageBytes);
+    imageBytes *= image->getHeight() * image->getDepth();
+
+    gl::PixelUnpackState defaultUnpackState;
+
+    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()));
+    }
+    else
+    {
+        gl::Box fullImageArea(0, 0, 0, image->getWidth(), image->getHeight(), image->getDepth());
+        ANGLE_TRY(image->loadData(context, fullImageArea, defaultUnpackState, 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();
+        }
+        else
+        {
+            mDirtyImages = true;
+        }
+    }
+    return gl::NoError();
+}
+
 TextureD3D_2D::TextureD3D_2D(const gl::TextureState &state, RendererD3D *renderer)
     : TextureD3D(state, renderer)
 {
     mEGLImageTarget = false;
     for (auto &image : mImageArray)
     {
         image.reset(renderer->createImage());
     }
@@ -762,23 +834,25 @@ gl::Error TextureD3D_2D::setImage(const 
 {
     ASSERT(target == GL_TEXTURE_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,
-                            shouldForceReleaseImagesOnSetImage(pixels)));
+    ANGLE_TRY(redefineImage(context, level, internalFormatInfo.sizedInternalFormat, size, false));
 
     gl::ImageIndex index = gl::ImageIndex::Make2D(level);
 
     // Attempt a fast gpu copy of the pixel data to the surface
-    if (isFastUnpackable(unpack, internalFormatInfo.sizedInternalFormat) && isLevelComplete(level))
+    gl::Buffer *unpackBuffer =
+        context->getGLState().getTargetBuffer(gl::BufferBinding::PixelUnpack);
+    if (isFastUnpackable(unpackBuffer, internalFormatInfo.sizedInternalFormat) &&
+        isLevelComplete(level))
     {
         // 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);
 
         ANGLE_TRY(fastUnpackPixels(context, unpack, pixels, destArea,
@@ -806,17 +880,20 @@ gl::Error TextureD3D_2D::setSubImage(con
                                      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);
-    if (isFastUnpackable(unpack, getInternalFormat(level)) && isLevelComplete(level))
+
+    gl::Buffer *unpackBuffer =
+        context->getGLState().getTargetBuffer(gl::BufferBinding::PixelUnpack);
+    if (isFastUnpackable(unpackBuffer, getInternalFormat(level)) && isLevelComplete(level))
     {
         RenderTargetD3D *renderTarget = nullptr;
         ANGLE_TRY(getRenderTarget(context, index, &renderTarget));
         ASSERT(!mImageArray[level]->isDirty());
 
         return fastUnpackPixels(context, unpack, pixels, area, getInternalFormat(level), type,
                                 renderTarget);
     }
@@ -834,18 +911,17 @@ gl::Error TextureD3D_2D::setCompressedIm
                                             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);
 
     // compressed formats don't have separate sized internal formats-- we can just use the compressed format directly
-    ANGLE_TRY(redefineImage(context, level, internalFormat, size,
-                            shouldForceReleaseImagesOnSetImage(pixels)));
+    ANGLE_TRY(redefineImage(context, level, internalFormat, size, false));
 
     return setCompressedImageImpl(context, gl::ImageIndex::Make2D(level), unpack, pixels, 0);
 }
 
 gl::Error TextureD3D_2D::setCompressedSubImage(const gl::Context *context,
                                                GLenum target,
                                                size_t level,
                                                const gl::Box &area,
@@ -871,39 +947,41 @@ gl::Error TextureD3D_2D::copyImage(const
 {
     ASSERT(target == GL_TEXTURE_2D);
 
     GLint level = static_cast<GLint>(imageLevel);
     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,
-                            mRenderer->isRobustResourceInitEnabled()));
+                            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 &&
-        !mRenderer->isRobustResourceInitEnabled())
+    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,
-                           gl::PixelUnpackState(1, 0), zero->data()));
+                           internalFormatInfo.format, internalFormatInfo.type, unpack,
+                           zero->data()));
     }
 
     gl::Rectangle sourceArea;
     if (!ClipRectangle(origSourceArea, gl::Rectangle(0, 0, fbSize.width, fbSize.height),
                        &sourceArea))
     {
         // Empty source area, nothing to do.
         return gl::NoError();
@@ -1027,16 +1105,21 @@ gl::Error TextureD3D_2D::copyTexture(con
         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(mRenderer->copyImage(context, destImage, sourceImage, sourceRect, destOffset,
                                        unpackFlipY, unpackPremultiplyAlpha, unpackUnmultiplyAlpha));
+
+        mDirtyImages = true;
+
+        gl::Box destRegion(destOffset, size);
+        ANGLE_TRY(commitRegion(context, destImageIndex, destRegion));
     }
 
     return gl::NoError();
 }
 
 gl::Error TextureD3D_2D::copySubTexture(const gl::Context *context,
                                         GLenum target,
                                         size_t level,
@@ -1071,16 +1154,21 @@ gl::Error TextureD3D_2D::copySubTexture(
         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(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));
     }
 
     return gl::NoError();
 }
 
 gl::Error TextureD3D_2D::copyCompressedTexture(const gl::Context *context,
                                                const gl::Texture *source)
 {
@@ -1368,26 +1456,32 @@ gl::Error TextureD3D_2D::setCompleteTexS
 
     mDirtyImages = true;
 
     return gl::NoError();
 }
 
 gl::Error TextureD3D_2D::updateStorage(const gl::Context *context)
 {
+    if (!mDirtyImages)
+    {
+        return gl::NoError();
+    }
+
     ASSERT(mTexStorage != nullptr);
     GLint storageLevels = mTexStorage->getLevelCount();
     for (int level = 0; level < storageLevels; level++)
     {
         if (mImageArray[level]->isDirty() && isLevelComplete(level))
         {
             ANGLE_TRY(updateStorageLevel(context, level));
         }
     }
 
+    mDirtyImages = false;
     return gl::NoError();
 }
 
 gl::Error TextureD3D_2D::updateStorageLevel(const gl::Context *context, int level)
 {
     ASSERT(level <= static_cast<int>(mImageArray.size()) && mImageArray[level] != nullptr);
     ASSERT(isLevelComplete(level));
 
@@ -1558,18 +1652,17 @@ gl::Error TextureD3D_Cube::setImage(cons
                                     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.layerIndex, static_cast<GLint>(level),
-                            internalFormatInfo.sizedInternalFormat, size,
-                            shouldForceReleaseImagesOnSetImage(pixels)));
+                            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::Box &area,
@@ -1594,17 +1687,17 @@ gl::Error TextureD3D_Cube::setCompressed
                                               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, shouldForceReleaseImagesOnSetImage(pixels)));
+                            internalFormat, size, false));
 
     gl::ImageIndex index = gl::ImageIndex::MakeCube(target, static_cast<GLint>(level));
     return setCompressedImageImpl(context, index, unpack, pixels, 0);
 }
 
 gl::Error TextureD3D_Cube::setCompressedSubImage(const gl::Context *context,
                                                  GLenum target,
                                                  size_t level,
@@ -1632,40 +1725,41 @@ gl::Error TextureD3D_Cube::copyImage(con
     int faceIndex              = static_cast<int>(gl::CubeMapTextureTargetToLayerIndex(target));
     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,
-                            internalFormatInfo.sizedInternalFormat, size,
-                            mRenderer->isRobustResourceInitEnabled()));
+                            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 &&
-        !mRenderer->isRobustResourceInitEnabled())
+        !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,
-                           gl::PixelUnpackState(1, 0), zero->data()));
+                           internalFormatInfo.format, internalFormatInfo.type, unpack,
+                           zero->data()));
     }
 
     gl::Rectangle sourceArea;
     if (!ClipRectangle(origSourceArea, gl::Rectangle(0, 0, fbSize.width, fbSize.height),
                        &sourceArea))
     {
         // Empty source area, nothing to do.
         return gl::NoError();
@@ -1720,23 +1814,18 @@ gl::Error TextureD3D_Cube::copySubImage(
 
     GLint level          = static_cast<GLint>(imageLevel);
     gl::ImageIndex index = gl::ImageIndex::MakeCube(target, 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)
     {
-        gl::Error error = mImageArray[faceIndex][level]->copyFromFramebuffer(context, destOffset,
-                                                                             sourceArea, source);
-        if (error.isError())
-        {
-            return error;
-        }
-
+        ANGLE_TRY(mImageArray[faceIndex][level]->copyFromFramebuffer(context, destOffset,
+                                                                     sourceArea, source));
         mDirtyImages = true;
     }
     else
     {
         ANGLE_TRY(ensureRenderTarget(context));
         if (isValidFaceLevel(faceIndex, level))
         {
             ANGLE_TRY(updateStorageFaceLevel(context, faceIndex, level));
@@ -1797,16 +1886,21 @@ gl::Error TextureD3D_Cube::copyTexture(c
 
         gl::ImageIndex destImageIndex =
             gl::ImageIndex::MakeCube(target, static_cast<GLint>(destLevel));
         ImageD3D *destImage = nullptr;
         ANGLE_TRY(getImageAndSyncFromStorage(context, destImageIndex, &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));
     }
 
     return gl::NoError();
 }
 
 gl::Error TextureD3D_Cube::copySubTexture(const gl::Context *context,
                                           GLenum target,
                                           size_t level,
@@ -1844,16 +1938,21 @@ gl::Error TextureD3D_Cube::copySubTextur
 
         gl::ImageIndex destImageIndex =
             gl::ImageIndex::MakeCube(target, static_cast<GLint>(destLevel));
         ImageD3D *destImage = nullptr;
         ANGLE_TRY(getImageAndSyncFromStorage(context, destImageIndex, &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));
     }
 
     return gl::NoError();
 }
 
 gl::Error TextureD3D_Cube::setStorage(const gl::Context *context,
                                       GLenum target,
                                       size_t levels,
@@ -2050,29 +2149,35 @@ gl::Error TextureD3D_Cube::setCompleteTe
     mTexStorage = newCompleteTexStorage;
 
     mDirtyImages = true;
     return gl::NoError();
 }
 
 gl::Error TextureD3D_Cube::updateStorage(const gl::Context *context)
 {
+    if (!mDirtyImages)
+    {
+        return gl::NoError();
+    }
+
     ASSERT(mTexStorage != nullptr);
     GLint storageLevels = mTexStorage->getLevelCount();
     for (int face = 0; face < 6; face++)
     {
         for (int level = 0; level < storageLevels; level++)
         {
             if (mImageArray[face][level]->isDirty() && isFaceLevelComplete(face, level))
             {
                 ANGLE_TRY(updateStorageFaceLevel(context, face, level));
             }
         }
     }
 
+    mDirtyImages = false;
     return gl::NoError();
 }
 
 bool TextureD3D_Cube::isValidFaceLevel(int faceIndex, int level) const
 {
     return (mTexStorage ? (level >= 0 && level < mTexStorage->getLevelCount()) : 0);
 }
 
@@ -2306,25 +2411,26 @@ gl::Error TextureD3D_3D::setImage(const 
                                   GLenum type,
                                   const gl::PixelUnpackState &unpack,
                                   const uint8_t *pixels)
 {
     ASSERT(target == GL_TEXTURE_3D);
     const gl::InternalFormat &internalFormatInfo = gl::GetInternalFormatInfo(internalFormat, type);
 
     GLint level = static_cast<GLint>(imageLevel);
-    ANGLE_TRY(redefineImage(context, level, internalFormatInfo.sizedInternalFormat, size,
-                            shouldForceReleaseImagesOnSetImage(pixels)));
+    ANGLE_TRY(redefineImage(context, level, 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
-    if (isFastUnpackable(unpack, internalFormatInfo.sizedInternalFormat) && !size.empty() &&
+    gl::Buffer *unpackBuffer =
+        context->getGLState().getTargetBuffer(gl::BufferBinding::PixelUnpack);
+    if (isFastUnpackable(unpackBuffer, internalFormatInfo.sizedInternalFormat) && !size.empty() &&
         isLevelComplete(level))
     {
         // 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));
 
@@ -2355,17 +2461,19 @@ gl::Error TextureD3D_3D::setSubImage(con
                                      const uint8_t *pixels)
 {
     ASSERT(target == GL_TEXTURE_3D);
 
     GLint level          = static_cast<GLint>(imageLevel);
     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
-    if (isFastUnpackable(unpack, getInternalFormat(level)) && isLevelComplete(level))
+    gl::Buffer *unpackBuffer =
+        context->getGLState().getTargetBuffer(gl::BufferBinding::PixelUnpack);
+    if (isFastUnpackable(unpackBuffer, getInternalFormat(level)) && isLevelComplete(level))
     {
         RenderTargetD3D *destRenderTarget = nullptr;
         ANGLE_TRY(getRenderTarget(context, index, &destRenderTarget));
         ASSERT(!mImageArray[level]->isDirty());
 
         return fastUnpackPixels(context, unpack, pixels, area, getInternalFormat(level), type,
                                 destRenderTarget);
     }
@@ -2383,18 +2491,17 @@ gl::Error TextureD3D_3D::setCompressedIm
                                             const gl::PixelUnpackState &unpack,
                                             size_t imageSize,
                                             const uint8_t *pixels)
 {
     ASSERT(target == GL_TEXTURE_3D);
 
     GLint level = static_cast<GLint>(imageLevel);
     // compressed formats don't have separate sized internal formats-- we can just use the compressed format directly
-    ANGLE_TRY(redefineImage(context, level, internalFormat, size,
-                            shouldForceReleaseImagesOnSetImage(pixels)));
+    ANGLE_TRY(redefineImage(context, level, internalFormat, size, false));
 
     gl::ImageIndex index = gl::ImageIndex::Make3D(level);
     return setCompressedImageImpl(context, index, unpack, pixels, 0);
 }
 
 gl::Error TextureD3D_3D::setCompressedSubImage(const gl::Context *context,
                                                GLenum target,
                                                size_t level,
@@ -2452,16 +2559,18 @@ gl::Error TextureD3D_3D::copySubImage(co
     bool syncTexStorage = mTexStorage && isLevelComplete(level);
     if (syncTexStorage)
     {
         gl::ImageIndex index = gl::ImageIndex::Make3D(level);
         ANGLE_TRY(mImageArray[level]->copyFromTexStorage(context, index, mTexStorage));
     }
     ANGLE_TRY(mImageArray[level]->copyFromFramebuffer(context, clippedDestOffset, clippedSourceArea,
                                                       source));
+    mDirtyImages = true;
+
     if (syncTexStorage)
     {
         ANGLE_TRY(updateStorageLevel(context, level));
     }
 
     return gl::NoError();
 }
 
@@ -2611,26 +2720,32 @@ gl::Error TextureD3D_3D::setCompleteTexS
     // We do not support managed 3D storage, as that is D3D9/ES2-only
     ASSERT(!mTexStorage->isManaged());
 
     return gl::NoError();
 }
 
 gl::Error TextureD3D_3D::updateStorage(const gl::Context *context)
 {
+    if (!mDirtyImages)
+    {
+        return gl::NoError();
+    }
+
     ASSERT(mTexStorage != nullptr);
     GLint storageLevels = mTexStorage->getLevelCount();
     for (int level = 0; level < storageLevels; level++)
     {
         if (mImageArray[level]->isDirty() && isLevelComplete(level))
         {
             ANGLE_TRY(updateStorageLevel(context, level));
         }
     }
 
+    mDirtyImages = false;
     return gl::NoError();
 }
 
 bool TextureD3D_3D::isValidLevel(int level) const
 {
     return (mTexStorage ? (level >= 0 && level < mTexStorage->getLevelCount()) : 0);
 }
 
@@ -2797,16 +2912,17 @@ ImageD3D *TextureD3D_2DArray::getImage(i
     ASSERT((layer == 0 && mLayerCounts[level] == 0) ||
            layer < mLayerCounts[level]);
     return (mImageArray[level] ? mImageArray[level][layer] : nullptr);
 }
 
 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);
     return (mImageArray[index.mipIndex] ? mImageArray[index.mipIndex][index.layerIndex] : nullptr);
 }
 
 GLsizei TextureD3D_2DArray::getLayerCount(int level) const
 {
@@ -2849,26 +2965,24 @@ gl::Error TextureD3D_2DArray::setImage(c
                                        const gl::Extents &size,
                                        GLenum format,
                                        GLenum type,
                                        const gl::PixelUnpackState &unpack,
                                        const uint8_t *pixels)
 {
     ASSERT(target == GL_TEXTURE_2D_ARRAY);
 
+    const gl::InternalFormat &formatInfo = gl::GetInternalFormatInfo(internalFormat, type);
+
     GLint level = static_cast<GLint>(imageLevel);
-
-    const gl::InternalFormat &formatInfo = gl::GetInternalFormatInfo(internalFormat, type);
-    ANGLE_TRY(redefineImage(context, level, formatInfo.sizedInternalFormat, size,
-                            shouldForceReleaseImagesOnSetImage(pixels)));
-
-    const gl::InternalFormat &inputFormat = gl::GetInternalFormatInfo(format, type);
-    GLsizei inputDepthPitch               = 0;
-    ANGLE_TRY_RESULT(inputFormat.computeDepthPitch(size.width, size.height, unpack.alignment,
-                                                   unpack.rowLength, unpack.imageHeight),
+    ANGLE_TRY(redefineImage(context, level, formatInfo.sizedInternalFormat, size, false));
+
+    GLsizei inputDepthPitch              = 0;
+    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));
     }
@@ -2881,22 +2995,22 @@ gl::Error TextureD3D_2DArray::setSubImag
                                           size_t imageLevel,
                                           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 &inputFormat = gl::GetInternalFormatInfo(format, type);
-    GLsizei inputDepthPitch               = 0;
-    ANGLE_TRY_RESULT(inputFormat.computeDepthPitch(area.width, area.height, unpack.alignment,
-                                                   unpack.rowLength, unpack.imageHeight),
+    GLint level                          = static_cast<GLint>(imageLevel);
+    const gl::InternalFormat &formatInfo =
+        gl::GetInternalFormatInfo(getInternalFormat(level), type);
+    GLsizei inputDepthPitch              = 0;
+    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);
@@ -2917,23 +3031,22 @@ gl::Error TextureD3D_2DArray::setCompres
                                                  const gl::PixelUnpackState &unpack,
                                                  size_t imageSize,
                                                  const uint8_t *pixels)
 {
     ASSERT(target == GL_TEXTURE_2D_ARRAY);
 
     GLint level = static_cast<GLint>(imageLevel);
     // compressed formats don't have separate sized internal formats-- we can just use the compressed format directly
-    ANGLE_TRY(redefineImage(context, level, internalFormat, size,
-                            shouldForceReleaseImagesOnSetImage(pixels)));
+    ANGLE_TRY(redefineImage(context, level, 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));
@@ -2951,17 +3064,17 @@ gl::Error TextureD3D_2DArray::setCompres
                                                     size_t imageSize,
                                                     const uint8_t *pixels)
 {
     ASSERT(target == GL_TEXTURE_2D_ARRAY);
 
     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);
@@ -3185,26 +3298,32 @@ gl::Error TextureD3D_2DArray::setComplet
     // We do not support managed 2D array storage, as managed storage is ES2/D3D9 only
     ASSERT(!mTexStorage->isManaged());
 
     return gl::NoError();
 }
 
 gl::Error TextureD3D_2DArray::updateStorage(const gl::Context *context)
 {
+    if (!mDirtyImages)
+    {
+        return gl::NoError();
+    }
+
     ASSERT(mTexStorage != nullptr);
     GLint storageLevels = mTexStorage->getLevelCount();
     for (int level = 0; level < storageLevels; level++)
     {
         if (isLevelComplete(level))
         {
             ANGLE_TRY(updateStorageLevel(context, level));
         }
     }
 
+    mDirtyImages = false;
     return gl::NoError();
 }
 
 bool TextureD3D_2DArray::isValidLevel(int level) const
 {
     return (mTexStorage ? (level >= 0 && level < mTexStorage->getLevelCount()) : 0);
 }
 
@@ -3715,17 +3834,17 @@ gl::Error TextureD3D_2DMultisample::copy
     return gl::InternalError();
 }
 
 gl::Error TextureD3D_2DMultisample::setStorageMultisample(const gl::Context *context,
                                                           GLenum target,
                                                           GLsizei samples,
                                                           GLint internalFormat,
                                                           const gl::Extents &size,
-                                                          GLboolean fixedSampleLocations)
+                                                          bool fixedSampleLocations)
 {
     ASSERT(target == GL_TEXTURE_2D_MULTISAMPLE && size.depth == 1);
 
     TexStoragePointer storage(context);
     storage.reset(mRenderer->createTextureStorage2DMultisample(internalFormat, size.width,
                                                                size.height, static_cast<int>(0),
                                                                samples, fixedSampleLocations));
 
@@ -3783,18 +3902,17 @@ gl::ImageIndex TextureD3D_2DMultisample:
 
 bool TextureD3D_2DMultisample::isValidIndex(const gl::ImageIndex &index) const
 {
     return (mTexStorage && index.type == GL_TEXTURE_2D_MULTISAMPLE && index.mipIndex == 0);
 }
 
 GLsizei TextureD3D_2DMultisample::getLayerCount(int level) const
 {
-    UNIMPLEMENTED();
-    return GLsizei();
+    return 1;
 }
 
 void TextureD3D_2DMultisample::markAllImagesDirty()
 {
 }
 
 gl::Error TextureD3D_2DMultisample::initializeStorage(const gl::Context *context, bool renderTarget)
 {
--- a/gfx/angle/src/libANGLE/renderer/d3d/TextureD3D.h
+++ b/gfx/angle/src/libANGLE/renderer/d3d/TextureD3D.h
@@ -31,48 +31,48 @@ class TextureStorage;
 
 template <typename T>
 using TexLevelsArray = std::array<T, gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS>;
 
 class TextureD3D : public TextureImpl
 {
   public:
     TextureD3D(const gl::TextureState &data, RendererD3D *renderer);
-    virtual ~TextureD3D();
+    ~TextureD3D() override;
 
     gl::Error onDestroy(const gl::Context *context) override;
 
     gl::Error getNativeTexture(const gl::Context *context, TextureStorage **outStorage);
 
     bool hasDirtyImages() const { return mDirtyImages; }
     void resetDirty() { mDirtyImages = false; }
 
     virtual ImageD3D *getImage(const gl::ImageIndex &index) const = 0;
     virtual GLsizei getLayerCount(int level) const = 0;
 
     gl::Error getImageAndSyncFromStorage(const gl::Context *context,
                                          const gl::ImageIndex &index,
-                                         ImageD3D **outImage) const;
+                                         ImageD3D **outImage);
 
     GLint getBaseLevelWidth() const;
     GLint getBaseLevelHeight() const;
     GLenum getBaseLevelInternalFormat() const;
 
     gl::Error setStorage(const gl::Context *context,
                          GLenum target,
                          size_t levels,
                          GLenum internalFormat,
-                         const gl::Extents &size);
+                         const gl::Extents &size) override;
 
     gl::Error setStorageMultisample(const gl::Context *context,
                                     GLenum target,
                                     GLsizei samples,
                                     GLint internalFormat,
                                     const gl::Extents &size,
-                                    GLboolean fixedSampleLocations) override;
+                                    bool fixedSampleLocations) override;
 
     bool isImmutable() const { return mImmutable; }
 
     virtual gl::Error getRenderTarget(const gl::Context *context,
                                       const gl::ImageIndex &index,
                                       RenderTargetD3D **outRT) = 0;
 
     // Returns an iterator over all "Images" for this particular Texture.
@@ -95,21 +95,18 @@ class TextureD3D : public TextureImpl
                                         GLenum binding,
                                         const gl::ImageIndex &imageIndex,
                                         FramebufferAttachmentRenderTarget **rtOut) override;
 
     gl::Error setBaseLevel(const gl::Context *context, GLuint baseLevel) override;
 
     void syncState(const gl::Texture::DirtyBits &dirtyBits) override;
 
-    gl::Error clearLevel(const gl::Context *context,
-                         const gl::ImageIndex &index,
-                         const gl::ColorF &clearColorValue,
-                         const float clearDepthValue,
-                         const unsigned int clearStencilValue);
+    gl::Error initializeContents(const gl::Context *context,
+                                 const gl::ImageIndex &imageIndex) override;
 
   protected:
     gl::Error setImageImpl(const gl::Context *context,
                            const gl::ImageIndex &index,
                            GLenum type,
                            const gl::PixelUnpackState &unpack,
                            const uint8_t *pixels,
                            ptrdiff_t layerOffset);
@@ -128,17 +125,17 @@ class TextureD3D : public TextureImpl
                                      ptrdiff_t layerOffset);
     gl::Error subImageCompressed(const gl::Context *context,
                                  const gl::ImageIndex &index,
                                  const gl::Box &area,
                                  GLenum format,
                                  const gl::PixelUnpackState &unpack,
                                  const uint8_t *pixels,
                                  ptrdiff_t layerOffset);
-    bool isFastUnpackable(const gl::PixelUnpackState &unpack, GLenum sizedInternalFormat);
+    bool isFastUnpackable(const gl::Buffer *unpackBuffer, GLenum sizedInternalFormat);
     gl::Error fastUnpackPixels(const gl::Context *context,
                                const gl::PixelUnpackState &unpack,
                                const uint8_t *pixels,
                                const gl::Box &destArea,
                                GLenum sizedInternalFormat,
                                GLenum type,
                                RenderTargetD3D *destRenderTarget);
 
@@ -165,18 +162,16 @@ class TextureD3D : public TextureImpl
     gl::Error releaseTexStorage(const gl::Context *context);
 
     GLuint getBaseLevel() const { return mBaseLevel; };
 
     virtual void markAllImagesDirty() = 0;
 
     GLint getBaseLevelDepth() const;
 
-    bool shouldForceReleaseImagesOnSetImage(const uint8_t *pixels) const;
-
     RendererD3D *mRenderer;
 
     bool mDirtyImages;
 
     bool mImmutable;
     TextureStorage *mTexStorage;
 
   private:
@@ -190,17 +185,17 @@ class TextureD3D : public TextureImpl
 
     GLuint mBaseLevel;
 };
 
 class TextureD3D_2D : public TextureD3D
 {
   public:
     TextureD3D_2D(const gl::TextureState &data, RendererD3D *renderer);
-    virtual ~TextureD3D_2D();
+    ~TextureD3D_2D() override;
 
     gl::Error onDestroy(const gl::Context *context) override;
 
     ImageD3D *getImage(int level, int layer) const;
     ImageD3D *getImage(const gl::ImageIndex &index) const override;
     GLsizei getLayerCount(int level) const override;
 
     GLsizei getWidth(GLint level) const;
@@ -310,17 +305,17 @@ class TextureD3D_2D : public TextureD3D
     gl::Error setCompleteTexStorage(const gl::Context *context,
                                     TextureStorage *newCompleteTexStorage) override;
 
     gl::Error updateStorage(const gl::Context *context) override;
     gl::Error initMipmapImages(const gl::Context *context) override;
 
     bool isValidLevel(int level) const;
     bool isLevelComplete(int level) const;
-    virtual bool isImageComplete(const gl::ImageIndex &index) const;
+    bool isImageComplete(const gl::ImageIndex &index) const override;
 
     gl::Error updateStorageLevel(const gl::Context *context, int level);
 
     gl::Error redefineImage(const gl::Context *context,
                             size_t level,
                             GLenum internalformat,
                             const gl::Extents &size,
                             bool forceRelease);
@@ -328,17 +323,17 @@ class TextureD3D_2D : public TextureD3D
     bool mEGLImageTarget;
     TexLevelsArray<std::unique_ptr<ImageD3D>> mImageArray;
 };
 
 class TextureD3D_Cube : public TextureD3D
 {
   public:
     TextureD3D_Cube(const gl::TextureState &data, RendererD3D *renderer);
-    virtual ~TextureD3D_Cube();
+    ~TextureD3D_Cube() override;
 
     gl::Error onDestroy(const gl::Context *context) override;
 
     ImageD3D *getImage(int level, int layer) const;
     ImageD3D *getImage(const gl::ImageIndex &index) const override;
     GLsizei getLayerCount(int level) const override;
 
     GLenum getInternalFormat(GLint level, GLint layer) const;
@@ -446,34 +441,34 @@ class TextureD3D_Cube : public TextureD3
                                     TextureStorage *newCompleteTexStorage) override;
 
     gl::Error updateStorage(const gl::Context *context) override;
     gl::Error initMipmapImages(const gl::Context *context) override;
 
     bool isValidFaceLevel(int faceIndex, int level) const;
     bool isFaceLevelComplete(int faceIndex, int level) const;
     bool isCubeComplete() const;
-    virtual bool isImageComplete(const gl::ImageIndex &index) const;
+    bool isImageComplete(const gl::ImageIndex &index) const override;
     gl::Error updateStorageFaceLevel(const gl::Context *context, int faceIndex, int level);
 
     gl::Error redefineImage(const gl::Context *context,
                             int faceIndex,
                             GLint level,
                             GLenum internalformat,
                             const gl::Extents &size,
                             bool forceRelease);
 
     std::array<TexLevelsArray<std::unique_ptr<ImageD3D>>, 6> mImageArray;
 };
 
 class TextureD3D_3D : public TextureD3D
 {
   public:
     TextureD3D_3D(const gl::TextureState &data, RendererD3D *renderer);
-    virtual ~TextureD3D_3D();
+    ~TextureD3D_3D() override;
 
     gl::Error onDestroy(const gl::Context *context) override;
 
     ImageD3D *getImage(int level, int layer) const;
     ImageD3D *getImage(const gl::ImageIndex &index) const override;
     GLsizei getLayerCount(int level) const override;
 
     GLsizei getWidth(GLint level) const;
@@ -562,39 +557,39 @@ class TextureD3D_3D : public TextureD3D
     gl::Error setCompleteTexStorage(const gl::Context *context,
                                     TextureStorage *newCompleteTexStorage) override;
 
     gl::Error updateStorage(const gl::Context *context) override;
     gl::Error initMipmapImages(const gl::Context *context) override;
 
     bool isValidLevel(int level) const;
     bool isLevelComplete(int level) const;
-    virtual bool isImageComplete(const gl::ImageIndex &index) const;
+    bool isImageComplete(const gl::ImageIndex &index) const override;
     gl::Error updateStorageLevel(const gl::Context *context, int level);
 
     gl::Error redefineImage(const gl::Context *context,
                             GLint level,
                             GLenum internalformat,
                             const gl::Extents &size,
                             bool forceRelease);
 
     TexLevelsArray<std::unique_ptr<ImageD3D>> mImageArray;
 };
 
 class TextureD3D_2DArray : public TextureD3D
 {
   public:
     TextureD3D_2DArray(const gl::TextureState &data, RendererD3D *renderer);
-    virtual ~TextureD3D_2DArray();
+    ~TextureD3D_2DArray() override;
 
     gl::Error onDestroy(const gl::Context *context) override;
 
     virtual ImageD3D *getImage(int level, int layer) const;
-    virtual ImageD3D *getImage(const gl::ImageIndex &index) const;
-    virtual GLsizei getLayerCount(int level) const;
+    ImageD3D *getImage(const gl::ImageIndex &index) const override;
+    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,
@@ -675,17 +670,17 @@ class TextureD3D_2DArray : public Textur
     gl::Error setCompleteTexStorage(const gl::Context *context,
                                     TextureStorage *newCompleteTexStorage) override;
 
     gl::Error updateStorage(const gl::Context *context) override;
     gl::Error initMipmapImages(const gl::Context *context) override;
 
     bool isValidLevel(int level) const;
     bool isLevelComplete(int level) const;
-    virtual bool isImageComplete(const gl::ImageIndex &index) const;
+    bool isImageComplete(const gl::ImageIndex &index) const override;
     gl::Error updateStorageLevel(const gl::Context *context, int level);
 
     void deleteImages();
     gl::Error redefineImage(const gl::Context *context,
                             GLint level,
                             GLenum internalformat,
                             const gl::Extents &size,
                             bool forceRelease);
@@ -852,34 +847,34 @@ class TextureD3D_2DMultisample : public 
                            const gl::Rectangle &sourceArea,
                            const gl::Framebuffer *source) override;
 
     gl::Error setStorageMultisample(const gl::Context *context,
                                     GLenum target,
                                     GLsizei samples,
                                     GLint internalFormat,
                                     const gl::Extents &size,
-                                    GLboolean fixedSampleLocations) override;
+                                    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,
                                 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;
     bool isValidIndex(const gl::ImageIndex &index) const override;
 
-    virtual GLsizei getLayerCount(int level) const;
+    GLsizei getLayerCount(int level) const override;
 
   protected:
     void markAllImagesDirty() override;
 
   private:
     gl::Error initializeStorage(const gl::Context *context, bool renderTarget) override;
     gl::Error createCompleteStorage(bool renderTarget,
                                     TexStoragePointer *outTexStorage) const override;
--- a/gfx/angle/src/libANGLE/renderer/d3d/TextureStorage.h
+++ b/gfx/angle/src/libANGLE/renderer/d3d/TextureStorage.h
@@ -30,20 +30,17 @@ class RenderTargetD3D;
 class ImageD3D;
 
 class TextureStorage : angle::NonCopyable
 {
   public:
     TextureStorage() {}
     virtual ~TextureStorage() {}
 
-    virtual gl::Error onDestroy(const gl::Context *context)
-    {
-        return gl::NoError();
-    }
+    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;
     virtual int getLevelCount() const = 0;
 
     virtual gl::Error getRenderTarget(const gl::Context *context,
@@ -59,19 +56,27 @@ class TextureStorage : angle::NonCopyabl
                               ImageD3D *image,
                               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)
-    {
-        return gl::NoError();
-    }
+                                                    bool useLevelZeroTexture);
 };
 
+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();
+}
+
 using TexStoragePointer = angle::UniqueObjectPointer<TextureStorage, gl::Context>;
 
 }  // namespace rx
 
 #endif // LIBANGLE_RENDERER_D3D_TEXTURESTORAGE_H_
--- a/gfx/angle/src/libANGLE/renderer/d3d/VertexBuffer.h
+++ b/gfx/angle/src/libANGLE/renderer/d3d/VertexBuffer.h
@@ -99,17 +99,17 @@ class VertexBufferInterface : angle::Non
     VertexBuffer *mVertexBuffer;
     bool mDynamic;
 };
 
 class StreamingVertexBufferInterface : public VertexBufferInterface
 {
   public:
     StreamingVertexBufferInterface(BufferFactoryD3D *factory, std::size_t initialSize);
-    ~StreamingVertexBufferInterface();
+    ~StreamingVertexBufferInterface() override;
 
     gl::Error storeDynamicAttribute(const gl::VertexAttribute &attrib,
                                     const gl::VertexBinding &binding,
                                     GLenum currentValueType,
                                     GLint start,
                                     GLsizei count,
                                     GLsizei instances,
                                     unsigned int *outStreamOffset,
@@ -126,17 +126,17 @@ class StreamingVertexBufferInterface : p
     unsigned int mWritePosition;
     unsigned int mReservedSpace;
 };
 
 class StaticVertexBufferInterface : public VertexBufferInterface
 {
   public:
     explicit StaticVertexBufferInterface(BufferFactoryD3D *factory);
-    ~StaticVertexBufferInterface();
+    ~StaticVertexBufferInterface() override;
 
     // Warning: you should ensure binding really matches attrib.bindingIndex before using these
     // functions.
     gl::Error storeStaticAttribute(const gl::VertexAttribute &attrib,
                                    const gl::VertexBinding &binding,
                                    GLint start,
                                    GLsizei count,
                                    GLsizei instances,
--- a/gfx/angle/src/libANGLE/renderer/d3d/VertexDataManager.cpp
+++ b/gfx/angle/src/libANGLE/renderer/d3d/VertexDataManager.cpp
@@ -121,16 +121,18 @@ TranslatedAttribute::TranslatedAttribute
       stride(0),
       vertexBuffer(),
       storage(nullptr),
       serial(0),
       divisor(0)
 {
 }
 
+TranslatedAttribute::TranslatedAttribute(const TranslatedAttribute &other) = default;
+
 gl::ErrorOrResult<unsigned int> TranslatedAttribute::computeOffset(GLint startVertex) const
 {
     if (!usesFirstVertexOffset)
     {
         return baseOffset;
     }
 
     CheckedNumeric<unsigned int> offset;
--- a/gfx/angle/src/libANGLE/renderer/d3d/VertexDataManager.h
+++ b/gfx/angle/src/libANGLE/renderer/d3d/VertexDataManager.h
@@ -43,16 +43,17 @@ class VertexBufferBinding final
 
   private:
     VertexBuffer *mBoundVertexBuffer;
 };
 
 struct TranslatedAttribute
 {
     TranslatedAttribute();
+    TranslatedAttribute(const TranslatedAttribute &other);
 
     // Computes the correct offset from baseOffset, usesFirstVertexOffset, stride and startVertex.
     // Can throw an error on integer overflow.
     gl::ErrorOrResult<unsigned int> computeOffset(GLint startVertex) const;
 
     bool active;
 
     const gl::VertexAttribute *attribute;
--- a/gfx/angle/src/libANGLE/renderer/d3d/d3d11/Blit11.cpp
+++ b/gfx/angle/src/libANGLE/renderer/d3d/d3d11/Blit11.cpp
@@ -22,16 +22,17 @@
 namespace rx
 {
 
 namespace
 {
 
 // Include inline shaders in the anonymous namespace to make sure no symbols are exported
 #include "libANGLE/renderer/d3d/d3d11/shaders/compiled/passthrough2d11vs.h"
+#include "libANGLE/renderer/d3d/d3d11/shaders/compiled/passthrougha2d11ps.h"
 #include "libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughdepth2d11ps.h"
 #include "libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughlum2d11ps.h"
 #include "libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughlumalpha2d11ps.h"
 #include "libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughr2d11ps.h"
 #include "libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughr2di11ps.h"
 #include "libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughr2dui11ps.h"
 #include "libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrg2d11ps.h"
 #include "libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrg2di11ps.h"
@@ -552,16 +553,24 @@ DXGI_FORMAT GetStencilSRVFormat(const d3
         default:
             UNREACHABLE();
             return DXGI_FORMAT_UNKNOWN;
     }
 }
 
 }  // namespace
 
+Blit11::Shader::Shader() = default;
+
+Blit11::Shader::Shader(Shader &&other) = default;
+
+Blit11::Shader::~Shader() = default;
+
+Blit11::Shader &Blit11::Shader::operator=(Blit11::Shader &&other) = default;
+
 Blit11::Blit11(Renderer11 *renderer)
     : mRenderer(renderer),
       mResourcesInitialized(false),
       mVertexBuffer(),
       mPointSampler(),
       mLinearSampler(),
       mScissorEnabledRasterizerState(),
       mScissorDisabledRasterizerState(),
@@ -988,17 +997,16 @@ gl::Error Blit11::getShaderSupport(const
 gl::Error Blit11::swizzleTexture(const gl::Context *context,
                                  const d3d11::SharedSRV &source,
                                  const d3d11::RenderTargetView &dest,
                                  const gl::Extents &size,
                                  const gl::SwizzleState &swizzleTarget)
 {
     ANGLE_TRY(initResources());
 
-    HRESULT result;
     ID3D11DeviceContext *deviceContext = mRenderer->getDeviceContext();
 
     D3D11_SHADER_RESOURCE_VIEW_DESC sourceSRVDesc;
     source.get()->GetDesc(&sourceSRVDesc);
 
     GLenum componentType = d3d11::GetComponentType(sourceSRVDesc.Format);
     if (componentType == GL_NONE)
     {
@@ -1036,54 +1044,45 @@ gl::Error Blit11::swizzleTexture(const g
             break;
     }
 
     const Shader *shader = nullptr;
     ANGLE_TRY(getSwizzleShader(shaderType, sourceSRVDesc.ViewDimension, &shader));
 
     // Set vertices
     D3D11_MAPPED_SUBRESOURCE mappedResource;
-    result =
-        deviceContext->Map(mVertexBuffer.get(), 0, D3D11_MAP_WRITE_DISCARD, 0, &mappedResource);
-    if (FAILED(result))
-    {
-        return gl::OutOfMemory() << "Failed to map internal vertex buffer for swizzle, "
-                                 << gl::FmtHR(result);
-    }
+    ANGLE_TRY(mRenderer->mapResource(mVertexBuffer.get(), 0, D3D11_MAP_WRITE_DISCARD, 0,
+                                     &mappedResource));
 
     ShaderSupport support;
     ANGLE_TRY(getShaderSupport(*shader, &support));
 
     UINT stride    = 0;
     UINT drawCount = 0;
     D3D11_PRIMITIVE_TOPOLOGY topology;
 
     gl::Box area(0, 0, 0, size.width, size.height, size.depth);
     support.vertexWriteFunction(area, size, area, size, mappedResource.pData, &stride, &drawCount,
                                 &topology);
 
     deviceContext->Unmap(mVertexBuffer.get(), 0);
 
     // Set constant buffer
-    result = deviceContext->Map(mSwizzleCB.get(), 0, D3D11_MAP_WRITE_DISCARD, 0, &mappedResource);
-    if (FAILED(result))
-    {
-        return gl::OutOfMemory() << "Failed to map internal constant buffer for swizzle, "
-                                 << gl::FmtHR(result);
-    }
+    ANGLE_TRY(
+        mRenderer->mapResource(mSwizzleCB.get(), 0, D3D11_MAP_WRITE_DISCARD, 0, &mappedResource));
 
     unsigned int *swizzleIndices = reinterpret_cast<unsigned int *>(mappedResource.pData);
     swizzleIndices[0]            = GetSwizzleIndex(swizzleTarget.swizzleRed);
     swizzleIndices[1]            = GetSwizzleIndex(swizzleTarget.swizzleGreen);
     swizzleIndices[2]            = GetSwizzleIndex(swizzleTarget.swizzleBlue);
     swizzleIndices[3]            = GetSwizzleIndex(swizzleTarget.swizzleAlpha);
 
     deviceContext->Unmap(mSwizzleCB.get(), 0);
 
-    auto stateManager = mRenderer->getStateManager();
+    StateManager11 *stateManager = mRenderer->getStateManager();
 
     // Apply vertex buffer
     stateManager->setSingleVertexBuffer(&mVertexBuffer, stride, 0);
 
     // Apply constant buffer
     stateManager->setPixelConstantBuffer(0, &mSwizzleCB);
 
     // Apply state
@@ -1125,17 +1124,16 @@ gl::Error Blit11::copyTexture(const gl::
                               GLenum destFormat,
                               GLenum filter,
                               bool maskOffAlpha,
                               bool unpackPremultiplyAlpha,
                               bool unpackUnmultiplyAlpha)
 {
     ANGLE_TRY(initResources());
 
-    HRESULT result;
     ID3D11DeviceContext *deviceContext = mRenderer->getDeviceContext();
 
     // Determine if the source format is a signed integer format, the destFormat will already
     // be GL_XXXX_INTEGER but it does not tell us if it is signed or unsigned.
     D3D11_SHADER_RESOURCE_VIEW_DESC sourceSRVDesc;
     source.get()->GetDesc(&sourceSRVDesc);
 
     GLenum componentType = d3d11::GetComponentType(sourceSRVDesc.Format);
@@ -1151,34 +1149,29 @@ gl::Error Blit11::copyTexture(const gl::
     ANGLE_TRY(getBlitShader(destFormat, sourceFormat, isSigned, unpackPremultiplyAlpha,
                             unpackUnmultiplyAlpha, dimension, &shader));
 
     ShaderSupport support;
     ANGLE_TRY(getShaderSupport(*shader, &support));
 
     // Set vertices
     D3D11_MAPPED_SUBRESOURCE mappedResource;
-    result =
-        deviceContext->Map(mVertexBuffer.get(), 0, D3D11_MAP_WRITE_DISCARD, 0, &mappedResource);
-    if (FAILED(result))
-    {
-        return gl::OutOfMemory() << "Failed to map internal vertex buffer for texture copy, "
-                                 << gl::FmtHR(result);
-    }
+    ANGLE_TRY(mRenderer->mapResource(mVertexBuffer.get(), 0, D3D11_MAP_WRITE_DISCARD, 0,
+                                     &mappedResource));
 
     UINT stride    = 0;
     UINT drawCount = 0;
     D3D11_PRIMITIVE_TOPOLOGY topology;
 
     support.vertexWriteFunction(sourceArea, sourceSize, destArea, destSize, mappedResource.pData,
                                 &stride, &drawCount, &topology);
 
     deviceContext->Unmap(mVertexBuffer.get(), 0);
 
-    auto stateManager = mRenderer->getStateManager();
+    StateManager11 *stateManager = mRenderer->getStateManager();
 
     // Apply vertex buffer
     stateManager->setSingleVertexBuffer(&mVertexBuffer, stride, 0);
 
     // Apply state
     if (maskOffAlpha)
     {
         ANGLE_TRY(mAlphaMaskBlendState.resolve(mRenderer));
@@ -1255,39 +1248,33 @@ gl::Error Blit11::copyDepth(const gl::Co
                             const gl::Extents &sourceSize,
                             const d3d11::DepthStencilView &dest,
                             const gl::Box &destArea,
                             const gl::Extents &destSize,
                             const gl::Rectangle *scissor)
 {
     ANGLE_TRY(initResources());
 
-    HRESULT result;
     ID3D11DeviceContext *deviceContext = mRenderer->getDeviceContext();
 
     // Set vertices
     D3D11_MAPPED_SUBRESOURCE mappedResource;
-    result =
-        deviceContext->Map(mVertexBuffer.get(), 0, D3D11_MAP_WRITE_DISCARD, 0, &mappedResource);
-    if (FAILED(result))
-    {
-        return gl::OutOfMemory() << "Failed to map internal vertex buffer for texture copy, "
-                                 << gl::FmtHR(result);
-    }
+    ANGLE_TRY(mRenderer->mapResource(mVertexBuffer.get(), 0, D3D11_MAP_WRITE_DISCARD, 0,
+                                     &mappedResource));
 
     UINT stride    = 0;
     UINT drawCount = 0;
     D3D11_PRIMITIVE_TOPOLOGY topology;
 
     Write2DVertices(sourceArea, sourceSize, destArea, destSize, mappedResource.pData, &stride,
                     &drawCount, &topology);
 
     deviceContext->Unmap(mVertexBuffer.get(), 0);
 
-    auto stateManager = mRenderer->getStateManager();
+    StateManager11 *stateManager = mRenderer->getStateManager();
 
     // Apply vertex buffer
     stateManager->setSingleVertexBuffer(&mVertexBuffer, stride, 0);
 
     // Apply state
     stateManager->setSimpleBlendState(nullptr);
     stateManager->setDepthStencilState(&mDepthStencilState, 0xFFFFFFFF);
 
@@ -1423,32 +1410,25 @@ gl::Error Blit11::copyAndConvertImpl(con
     ANGLE_TRY_RESULT(mRenderer->createStagingTexture(ResourceType::Texture2D, source.getFormatSet(),
                                                      sourceSize, StagingAccess::READ),
                      sourceStaging);
 
     deviceContext->CopySubresourceRegion(sourceStaging.get(), 0, 0, 0, 0, source.get(),
                                          sourceSubresource, nullptr);
 
     D3D11_MAPPED_SUBRESOURCE sourceMapping;
-    HRESULT result = deviceContext->Map(sourceStaging.get(), 0, D3D11_MAP_READ, 0, &sourceMapping);
-    if (FAILED(result))
-    {
-        return gl::OutOfMemory()
-               << "Failed to map internal source staging texture for depth stencil blit, "
-               << gl::FmtHR(result);
-    }
+    ANGLE_TRY(mRenderer->mapResource(sourceStaging.get(), 0, D3D11_MAP_READ, 0, &sourceMapping));
 
     D3D11_MAPPED_SUBRESOURCE destMapping;
-    result = deviceContext->Map(destStaging.get(), 0, D3D11_MAP_WRITE, 0, &destMapping);
-    if (FAILED(result))
+    gl::Error error =
+        mRenderer->mapResource(destStaging.get(), 0, D3D11_MAP_WRITE, 0, &destMapping);
+    if (error.isError())
     {
         deviceContext->Unmap(sourceStaging.get(), 0);
-        return gl::OutOfMemory()
-               << "Failed to map internal destination staging texture for depth stencil blit, "
-               << gl::FmtHR(result);
+        return error;
     }
 
     // Clip dest area to the destination size
     gl::Rectangle clipRect = gl::Rectangle(0, 0, destSize.width, destSize.height);
 
     // Clip dest area to the scissor
     if (scissor)
     {
@@ -1611,18 +1591,17 @@ gl::Error Blit11::getBlitShader(GLenum d
                                          ShaderData(g_PS_PassthroughRG2D),
                                          "Blit11 2D RG pixel shader"));
             break;
         case BLITSHADER_2D_RF:
             ANGLE_TRY(addBlitShaderToMap(blitShaderType, SHADER_2D, ShaderData(g_PS_PassthroughR2D),
                                          "Blit11 2D R pixel shader"));
             break;
         case BLITSHADER_2D_ALPHA:
-            ANGLE_TRY(addBlitShaderToMap(blitShaderType, SHADER_2D,
-                                         ShaderData(g_PS_PassthroughRGBA2D),
+            ANGLE_TRY(addBlitShaderToMap(blitShaderType, SHADER_2D, ShaderData(g_PS_PassthroughA2D),
                                          "Blit11 2D alpha pixel shader"));
             break;
         case BLITSHADER_2D_LUMA:
             ANGLE_TRY(addBlitShaderToMap(blitShaderType, SHADER_2D,
                                          ShaderData(g_PS_PassthroughLum2D),
                                          "Blit11 2D lum pixel shader"));
             break;
         case BLITSHADER_2D_LUMAALPHA:
@@ -1947,17 +1926,17 @@ 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::SAMPLER_PIXEL, 0, &depth->getShaderResourceView());
+    stateManager->setShaderResourceShared(gl::SHADER_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)
@@ -1990,17 +1969,17 @@ gl::Error Blit11::initResolveDepthOnly(c
     dsvDesc.Texture2D.MipSlice = 0;
     dsvDesc.ViewDimension      = D3D11_DSV_DIMENSION_TEXTURE2D;
 
     ANGLE_TRY(mRenderer->allocateResource(dsvDesc, mResolvedDepth.get(), &mResolvedDepthDSView));
     mResolvedDepthDSView.setDebugName("Blit11::mResolvedDepthDSView");
 
     // Possibly D3D11 bug or undefined behaviour: Clear the DSV so that our first render
     // works as expected. Otherwise the results of the first use seem to be incorrect.
-    auto context = mRenderer->getDeviceContext();
+    ID3D11DeviceContext *context = mRenderer->getDeviceContext();
     context->ClearDepthStencilView(mResolvedDepthDSView.get(), D3D11_CLEAR_DEPTH, 1.0f, 0);
 
     return gl::NoError();
 }
 
 gl::Error Blit11::initResolveDepthStencil(const gl::Extents &extents)
 {
     // Check if we need to recreate depth stencil view
@@ -2105,19 +2084,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::SAMPLER_PIXEL, 0,
+    stateManager->setShaderResourceShared(gl::SHADER_FRAGMENT, 0,
                                           &depthStencil->getShaderResourceView());
-    stateManager->setShaderResource(gl::SAMPLER_PIXEL, 1, &mStencilSRV);
+    stateManager->setShaderResource(gl::SHADER_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/src/libANGLE/renderer/d3d/d3d11/Blit11.h
+++ b/gfx/angle/src/libANGLE/renderer/d3d/d3d11/Blit11.h
@@ -8,17 +8,17 @@
 
 #ifndef LIBANGLE_RENDERER_D3D_D3D11_BLIT11_H_
 #define LIBANGLE_RENDERER_D3D_D3D11_BLIT11_H_
 
 #include "common/angleutils.h"
 #include "libANGLE/Error.h"
 #include "libANGLE/angletypes.h"
 #include "libANGLE/renderer/d3d/d3d11/ResourceManager11.h"
-#include "libANGLE/renderer/d3d/d3d11/Renderer11.h"
+#include "libANGLE/renderer/d3d/d3d11/renderer11_utils.h"
 
 #include <map>
 
 namespace rx
 {
 class Renderer11;
 
 class Blit11 : angle::NonCopyable
@@ -189,16 +189,21 @@ class Blit11 : angle::NonCopyable
     enum ShaderDimension
     {
         SHADER_2D,
         SHADER_3D,
     };
 
     struct Shader
     {
+        Shader();
+        Shader(Shader &&other);
+        ~Shader();
+        Shader &operator=(Shader &&other);
+
         ShaderDimension dimension;
         d3d11::PixelShader pixelShader;
     };
 
     struct ShaderSupport
     {
         const d3d11::InputLayout *inputLayout;
         const d3d11::VertexShader *vertexShader;
--- a/gfx/angle/src/libANGLE/renderer/d3d/d3d11/Buffer11.cpp
+++ b/gfx/angle/src/libANGLE/renderer/d3d/d3d11/Buffer11.cpp
@@ -290,43 +290,44 @@ class Buffer11::SystemMemoryStorage : pu
 };
 
 Buffer11::Buffer11(const gl::BufferState &state, Renderer11 *renderer)
     : BufferD3D(state, renderer),
       mRenderer(renderer),
       mSize(0),
       mMappedStorage(nullptr),
       mBufferStorages({}),
+      mLatestBufferStorage(nullptr),
       mDeallocThresholds({}),
       mIdleness({}),
       mConstantBufferStorageAdditionalSize(0),
       mMaxConstantBufferLruCount(0)
 {
 }
 
 Buffer11::~Buffer11()
 {
-    for (auto &storage : mBufferStorages)
+    for (BufferStorage *&storage : mBufferStorages)
     {
         SafeDelete(storage);
     }
 
     for (auto &p : mConstantBufferRangeStoragesCache)
     {
         SafeDelete(p.second.storage);
     }
 
     mRenderer->onBufferDelete(this);
 }
 
 gl::Error Buffer11::setData(const gl::Context *context,
-                            GLenum target,
+                            gl::BufferBinding target,
                             const void *data,
                             size_t size,
-                            GLenum usage)
+                            gl::BufferUsage usage)
 {
     updateD3DBufferUsage(context, usage);
     ANGLE_TRY(setSubData(context, target, data, size, 0));
     return gl::NoError();
 }
 
 gl::Error Buffer11::getData(const gl::Context *context, const uint8_t **outData)
 {
@@ -343,29 +344,29 @@ gl::ErrorOrResult<Buffer11::SystemMemory
     const gl::Context *context)
 {
     BufferStorage *storage = nullptr;
     ANGLE_TRY_RESULT(getBufferStorage(context, BUFFER_USAGE_SYSTEM_MEMORY), storage);
     return GetAs<SystemMemoryStorage>(storage);
 }
 
 gl::Error Buffer11::setSubData(const gl::Context *context,
-                               GLenum target,
+                               gl::BufferBinding target,
                                const void *data,
                                size_t size,
                                size_t offset)
 {
     size_t requiredSize = size + offset;
 
     if (data && size > 0)
     {
         // Use system memory storage for dynamic buffers.
         // Try using a constant storage for constant buffers
         BufferStorage *writeBuffer = nullptr;
-        if (target == GL_UNIFORM_BUFFER)
+        if (target == gl::BufferBinding::Uniform)
         {
             // If we are a very large uniform buffer, keep system memory storage around so that we
             // aren't forced to read back from a constant buffer. We also check the workaround for
             // Intel - this requires us to use system memory so we don't end up having to copy from
             // a constant buffer to a staging buffer.
             // TODO(jmadill): Use Context caps.
             if (offset == 0 && size >= mSize &&
                 size <= static_cast<UINT>(mRenderer->getNativeCaps().maxUniformBlockSize) &&
@@ -393,17 +394,17 @@ gl::Error Buffer11::setSubData(const gl:
         // completely fill the buffer
         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));
-        writeBuffer->setDataRevision(writeBuffer->getDataRevision() + 1);
+        onStorageUpdate(writeBuffer);
 
         // Notify any vertex arrays that we have dirty data.
         // TODO(jmadill): Use a more fine grained notification for data updates.
         mDirectBroadcastChannel.signal(context);
     }
 
     mSize = std::max(mSize, requiredSize);
     invalidateStaticData(context);
@@ -426,21 +427,23 @@ gl::Error Buffer11::copySubData(const gl
     if (!copyDest)
     {
         ANGLE_TRY_RESULT(getStagingStorage(context), copyDest);
     }
 
     BufferStorage *copySource = nullptr;
     ANGLE_TRY_RESULT(sourceBuffer->getLatestBufferStorage(context), copySource);
 
-    if (!copySource || !copyDest)
+    if (!copySource)
     {
-        return gl::OutOfMemory() << "Failed to allocate internal staging buffer.";
+        ANGLE_TRY_RESULT(sourceBuffer->getStagingStorage(context), copySource);
     }
 
+    ASSERT(copySource && copyDest);
+
     // A staging buffer is needed if there is no cpu-cpu or gpu-gpu copy path avaiable.
     if (!copyDest->isGPUAccessible() && !copySource->isCPUAccessible(GL_MAP_READ_BIT))
     {
         ANGLE_TRY_RESULT(sourceBuffer->getStagingStorage(context), copySource);
     }
     else if (!copySource->isGPUAccessible() && !copyDest->isCPUAccessible(GL_MAP_WRITE_BIT))
     {
         ANGLE_TRY_RESULT(getStagingStorage(context), copyDest);
@@ -460,21 +463,24 @@ gl::Error Buffer11::copySubData(const gl
         {
             ANGLE_TRY_RESULT(getStagingStorage(context), copySource);
         }
     }
 
     CopyResult copyResult = CopyResult::NOT_RECREATED;
     ANGLE_TRY_RESULT(copyDest->copyFromStorage(context, copySource, sourceOffset, size, destOffset),
                      copyResult);
-    copyDest->setDataRevision(copyDest->getDataRevision() + 1);
+    onStorageUpdate(copyDest);
 
     mSize = std::max<size_t>(mSize, destOffset + size);
     invalidateStaticData(context);
 
+    // Also notify that direct buffers are dirty.
+    mDirectBroadcastChannel.signal(context);
+
     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);
@@ -508,17 +514,17 @@ gl::Error Buffer11::mapRange(const gl::C
     if (!mMappedStorage)
     {
         return gl::OutOfMemory() << "Failed to allocate mappable internal buffer.";
     }
 
     if ((access & GL_MAP_WRITE_BIT) > 0)
     {
         // Update the data revision immediately, since the data might be changed at any time
-        mMappedStorage->setDataRevision(mMappedStorage->getDataRevision() + 1);
+        onStorageUpdate(mMappedStorage);
         invalidateStaticData(context);
     }
 
     uint8_t *mappedBuffer = nullptr;
     ANGLE_TRY(mMappedStorage->map(offset, length, access, &mappedBuffer));
     ASSERT(mappedBuffer);
 
     *mapPtr = static_cast<void *>(mappedBuffer);
@@ -540,17 +546,17 @@ gl::Error Buffer11::unmap(const gl::Cont
 gl::Error Buffer11::markTransformFeedbackUsage(const gl::Context *context)
 {
     BufferStorage *transformFeedbackStorage = nullptr;
     ANGLE_TRY_RESULT(getBufferStorage(context, BUFFER_USAGE_VERTEX_OR_TRANSFORM_FEEDBACK),
                      transformFeedbackStorage);
 
     if (transformFeedbackStorage)
     {
-        transformFeedbackStorage->setDataRevision(transformFeedbackStorage->getDataRevision() + 1);
+        onStorageUpdate(transformFeedbackStorage);
     }
 
     invalidateStaticData(context);
     return gl::NoError();
 }
 
 void Buffer11::updateDeallocThreshold(BufferUsage usage)
 {
@@ -689,22 +695,19 @@ gl::ErrorOrResult<const d3d11::ShaderRes
 
 gl::Error Buffer11::packPixels(const gl::Context *context,
                                const gl::FramebufferAttachment &readAttachment,
                                const PackPixelsParams &params)
 {
     PackStorage *packStorage = nullptr;
     ANGLE_TRY_RESULT(getPackStorage(context), packStorage);
 
-    BufferStorage *latestStorage = nullptr;
-    ANGLE_TRY_RESULT(getLatestBufferStorage(context), latestStorage);
-
     ASSERT(packStorage);
     ANGLE_TRY(packStorage->packPixels(context, readAttachment, params));
-    packStorage->setDataRevision(latestStorage ? latestStorage->getDataRevision() + 1 : 1);
+    onStorageUpdate(packStorage);
 
     return gl::NoError();
 }
 
 size_t Buffer11::getTotalCPUBufferMemoryBytes() const
 {
     size_t allocationSize = 0;
 
@@ -750,16 +753,17 @@ Buffer11::BufferStorage *Buffer11::alloc
     switch (usage)
     {
         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, &mDirectBroadcastChannel);
         default:
             return new NativeStorage(mRenderer, usage, nullptr);
     }
 }
 
 gl::ErrorOrResult<Buffer11::BufferStorage *> Buffer11::getConstantBufferRangeStorage(
@@ -828,92 +832,90 @@ gl::Error Buffer11::updateBufferStorage(
                                         size_t sourceOffset,
                                         size_t storageSize)
 {
     BufferStorage *latestBuffer = nullptr;
     ANGLE_TRY_RESULT(getLatestBufferStorage(context), latestBuffer);
 
     ASSERT(storage);
 
-    if (latestBuffer && latestBuffer->getDataRevision() > storage->getDataRevision())
+    if (!latestBuffer)
+    {
+        onStorageUpdate(storage);
+        return gl::NoError();
+    }
+
+    if (latestBuffer->getDataRevision() <= storage->getDataRevision())
     {
-        // Copy through a staging buffer if we're copying from or to a non-staging, mappable
-        // buffer storage. This is because we can't map a GPU buffer, and copy CPU
-        // data directly. If we're already using a staging buffer we're fine.
-        if (latestBuffer->getUsage() != BUFFER_USAGE_STAGING &&
-            storage->getUsage() != BUFFER_USAGE_STAGING &&
-            (!latestBuffer->isCPUAccessible(GL_MAP_READ_BIT) ||
-             !storage->isCPUAccessible(GL_MAP_WRITE_BIT)))
-        {
-            NativeStorage *stagingBuffer = nullptr;
-            ANGLE_TRY_RESULT(getStagingStorage(context), stagingBuffer);
+        return gl::NoError();
+    }
 
-            CopyResult copyResult = CopyResult::NOT_RECREATED;
-            ANGLE_TRY_RESULT(stagingBuffer->copyFromStorage(context, latestBuffer, 0,
-                                                            latestBuffer->getSize(), 0),
-                             copyResult);
-            stagingBuffer->setDataRevision(latestBuffer->getDataRevision());
-
-            latestBuffer = stagingBuffer;
-        }
+    // Copy through a staging buffer if we're copying from or to a non-staging, mappable
+    // buffer storage. This is because we can't map a GPU buffer, and copy CPU
+    // data directly. If we're already using a staging buffer we're fine.
+    if (latestBuffer->getUsage() != BUFFER_USAGE_STAGING &&
+        storage->getUsage() != BUFFER_USAGE_STAGING &&
+        (!latestBuffer->isCPUAccessible(GL_MAP_READ_BIT) ||
+         !storage->isCPUAccessible(GL_MAP_WRITE_BIT)))
+    {
+        NativeStorage *stagingBuffer = nullptr;
+        ANGLE_TRY_RESULT(getStagingStorage(context), stagingBuffer);
 
         CopyResult copyResult = CopyResult::NOT_RECREATED;
         ANGLE_TRY_RESULT(
-            storage->copyFromStorage(context, latestBuffer, sourceOffset, storageSize, 0),
+            stagingBuffer->copyFromStorage(context, latestBuffer, 0, latestBuffer->getSize(), 0),
             copyResult);
-        // If the D3D buffer has been recreated, we should update our serial.
-        if (copyResult == CopyResult::RECREATED)
-        {
-            updateSerial();
-        }
-        storage->setDataRevision(latestBuffer->getDataRevision());
+        onCopyStorage(stagingBuffer, latestBuffer);
+
+        latestBuffer = stagingBuffer;
     }
 
+    CopyResult copyResult = CopyResult::NOT_RECREATED;
+    ANGLE_TRY_RESULT(storage->copyFromStorage(context, latestBuffer, sourceOffset, storageSize, 0),
+                     copyResult);
+    // If the D3D buffer has been recreated, we should update our serial.
+    if (copyResult == CopyResult::RECREATED)
+    {
+        updateSerial();
+    }
+    onCopyStorage(storage, latestBuffer);
     return gl::NoError();
 }
 
 gl::ErrorOrResult<Buffer11::BufferStorage *> Buffer11::getLatestBufferStorage(
     const gl::Context *context) const
 {
-    // Even though we iterate over all the direct buffers, it is expected that only
-    // 1 or 2 will be present.
-    BufferStorage *latestStorage = nullptr;
-    DataRevision latestRevision  = 0;
-    for (auto &storage : mBufferStorages)
+    // resize buffer
+    if (mLatestBufferStorage && mLatestBufferStorage->getSize() < mSize)
     {
-        if (storage && (!latestStorage || storage->getDataRevision() > latestRevision))
-        {
-            latestStorage  = storage;
-            latestRevision = storage->getDataRevision();
-        }
+        ANGLE_TRY(mLatestBufferStorage->resize(context, mSize, true));
     }
 
-    // resize buffer
-    if (latestStorage && latestStorage->getSize() < mSize)
-    {
-        ANGLE_TRY(latestStorage->resize(context, mSize, true));
-    }
-
-    return latestStorage;
+    return mLatestBufferStorage;
 }
 
 gl::ErrorOrResult<Buffer11::NativeStorage *> Buffer11::getStagingStorage(const gl::Context *context)
 {
     BufferStorage *stagingStorage = nullptr;
     ANGLE_TRY_RESULT(getBufferStorage(context, BUFFER_USAGE_STAGING), stagingStorage);
     return GetAs<NativeStorage>(stagingStorage);
 }
 
 gl::ErrorOrResult<Buffer11::PackStorage *> Buffer11::getPackStorage(const gl::Context *context)
 {
     BufferStorage *packStorage = nullptr;
     ANGLE_TRY_RESULT(getBufferStorage(context, BUFFER_USAGE_PIXEL_PACK), packStorage);
     return GetAs<PackStorage>(packStorage);
 }
 
+size_t Buffer11::getSize() const
+{
+    return mSize;
+}
+
 bool Buffer11::supportsDirectBinding() const
 {
     // 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)
@@ -937,16 +939,34 @@ OnBufferDataDirtyChannel *Buffer11::getS
     return &mStaticBroadcastChannel;
 }
 
 OnBufferDataDirtyChannel *Buffer11::getDirectBroadcastChannel()
 {
     return &mDirectBroadcastChannel;
 }
 
+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.
+    if (dest->getUsage() < mLatestBufferStorage->getUsage())
+    {
+        mLatestBufferStorage = dest;
+    }
+}
+
+void Buffer11::onStorageUpdate(BufferStorage *updatedStorage)
+{
+    updatedStorage->setDataRevision(updatedStorage->getDataRevision() + 1);
+    mLatestBufferStorage = updatedStorage;
+}
+
 // Buffer11::BufferStorage implementation
 
 Buffer11::BufferStorage::BufferStorage(Renderer11 *renderer, BufferUsage usage)
     : mRenderer(renderer), mRevision(0), mUsage(usage), mBufferSize(0)
 {
 }
 
 gl::Error Buffer11::BufferStorage::setData(const uint8_t *data, size_t offset, size_t size)
@@ -1170,26 +1190,20 @@ void Buffer11::NativeStorage::FillBuffer
 gl::Error Buffer11::NativeStorage::map(size_t offset,
                                        size_t length,
                                        GLbitfield access,
                                        uint8_t **mapPointerOut)
 {
     ASSERT(isCPUAccessible(access));
 
     D3D11_MAPPED_SUBRESOURCE mappedResource;
-    ID3D11DeviceContext *context = mRenderer->getDeviceContext();
     D3D11_MAP d3dMapType         = gl_d3d11::GetD3DMapTypeFromBits(mUsage, access);
     UINT d3dMapFlag = ((access & GL_MAP_UNSYNCHRONIZED_BIT) != 0 ? D3D11_MAP_FLAG_DO_NOT_WAIT : 0);
 
-    HRESULT result = context->Map(mBuffer.get(), 0, d3dMapType, d3dMapFlag, &mappedResource);
-    ASSERT(SUCCEEDED(result));
-    if (FAILED(result))
-    {
-        return gl::OutOfMemory() << "Failed to map native storage in Buffer11::NativeStorage::map";
-    }
+    ANGLE_TRY(mRenderer->mapResource(mBuffer.get(), 0, d3dMapType, d3dMapFlag, &mappedResource));
     ASSERT(mappedResource.pData);
     *mapPointerOut = static_cast<uint8_t *>(mappedResource.pData) + offset;
     return gl::NoError();
 }
 
 void Buffer11::NativeStorage::unmap()
 {
     ASSERT(isCPUAccessible(GL_MAP_WRITE_BIT) || isCPUAccessible(GL_MAP_READ_BIT));
@@ -1468,17 +1482,17 @@ gl::Error Buffer11::PackStorage::packPix
 
     RenderTarget11 *renderTarget = nullptr;
     ANGLE_TRY(readAttachment.getRenderTarget(context, &renderTarget));
 
     const TextureHelper11 &srcTexture = renderTarget->getTexture();
     ASSERT(srcTexture.valid());
     unsigned int srcSubresource = renderTarget->getSubresourceIndex();
 
-    mQueuedPackCommand.reset(new PackPixelsParams(context, params));
+    mQueuedPackCommand.reset(new PackPixelsParams(params));
 
     gl::Extents srcTextureSize(params.area.width, params.area.height, 1);
     if (!mStagingTexture.get() || mStagingTexture.getFormat() != srcTexture.getFormat() ||
         mStagingTexture.getExtents() != srcTextureSize)
     {
         ANGLE_TRY_RESULT(
             mRenderer->createStagingTexture(srcTexture.getTextureType(), srcTexture.getFormatSet(),
                                             srcTextureSize, StagingAccess::READ),
--- a/gfx/angle/src/libANGLE/renderer/d3d/d3d11/Buffer11.h
+++ b/gfx/angle/src/libANGLE/renderer/d3d/d3d11/Buffer11.h
@@ -46,17 +46,17 @@ enum BufferUsage
 };
 
 typedef size_t DataRevision;
 
 class Buffer11 : public BufferD3D
 {
   public:
     Buffer11(const gl::BufferState &state, Renderer11 *renderer);
-    virtual ~Buffer11();
+    ~Buffer11() override;
 
     gl::ErrorOrResult<ID3D11Buffer *> getBuffer(const gl::Context *context, BufferUsage usage);
     gl::ErrorOrResult<ID3D11Buffer *> getEmulatedIndexedBuffer(const gl::Context *context,
                                                                SourceIndexData *indexInfo,
                                                                const TranslatedAttribute &attribute,
                                                                GLint startVertex);
     gl::Error getConstantBufferRange(const gl::Context *context,
                                      GLintptr offset,
@@ -68,30 +68,30 @@ class Buffer11 : public BufferD3D
                                                                 DXGI_FORMAT srvFormat);
     bool isMapped() const { return mMappedStorage != nullptr; }
     gl::Error packPixels(const gl::Context *context,
                          const gl::FramebufferAttachment &readAttachment,
                          const PackPixelsParams &params);
     size_t getTotalCPUBufferMemoryBytes() const;
 
     // BufferD3D implementation
-    size_t getSize() const override { return mSize; }
+    size_t getSize() const override;
     bool supportsDirectBinding() const override;
     gl::Error getData(const gl::Context *context, const uint8_t **outData) override;
     void initializeStaticData(const gl::Context *context) override;
     void invalidateStaticData(const gl::Context *context) override;
 
     // BufferImpl implementation
     gl::Error setData(const gl::Context *context,
-                      GLenum target,
+                      gl::BufferBinding target,
                       const void *data,
                       size_t size,
-                      GLenum usage) override;
+                      gl::BufferUsage usage) override;
     gl::Error setSubData(const gl::Context *context,
-                         GLenum target,
+                         gl::BufferBinding target,
                          const void *data,
                          size_t size,
                          size_t offset) override;
     gl::Error copySubData(const gl::Context *context,
                           BufferImpl *source,
                           GLintptr sourceOffset,
                           GLintptr destOffset,
                           GLsizeiptr size) override;
@@ -147,22 +147,31 @@ class Buffer11 : public BufferD3D
     void updateDeallocThreshold(BufferUsage usage);
 
     // Free the storage if we decide it isn't being used very often.
     gl::Error checkForDeallocation(const gl::Context *context, BufferUsage usage);
 
     // For some cases of uniform buffer storage, we can't deallocate system memory storage.
     bool canDeallocateSystemMemory() const;
 
+    // Updates data revisions and latest storage.
+    void onCopyStorage(BufferStorage *dest, BufferStorage *source);
+    void onStorageUpdate(BufferStorage *updatedStorage);
+
     Renderer11 *mRenderer;
     size_t mSize;
 
     BufferStorage *mMappedStorage;
 
+    // Buffer storages are sorted by usage. It's important that the latest buffer storage picks
+    // the lowest usage in the case where two storages are tied on data revision - this ensures
+    // we never do anything dangerous like map a uniform buffer over a staging or system memory
+    // copy.
     std::array<BufferStorage *, BUFFER_USAGE_COUNT> mBufferStorages;
+    BufferStorage *mLatestBufferStorage;
 
     // These two arrays are used to track when to free unused storage.
     std::array<unsigned int, BUFFER_USAGE_COUNT> mDeallocThresholds;
     std::array<unsigned int, BUFFER_USAGE_COUNT> mIdleness;
 
     // 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.
--- a/gfx/angle/src/libANGLE/renderer/d3d/d3d11/Clear11.cpp
+++ b/gfx/angle/src/libANGLE/renderer/d3d/d3d11/Clear11.cpp
@@ -1,9 +1,9 @@
-//
+
 // Copyright (c) 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.
 //
 
 // Clear11.cpp: Framebuffer clear utility class.
 
 #include "libANGLE/renderer/d3d/d3d11/Clear11.h"
@@ -51,19 +51,18 @@
 #include "libANGLE/renderer/d3d/d3d11/shaders/compiled/clearuint11ps7.h"
 #include "libANGLE/renderer/d3d/d3d11/shaders/compiled/clearuint11ps8.h"
 
 namespace rx
 {
 
 namespace
 {
-
-static constexpr uint32_t g_ConstantBufferSize = sizeof(RtvDsvClearInfo<float>);
-static constexpr uint32_t g_VertexSize         = sizeof(d3d11::PositionVertex);
+constexpr uint32_t g_ConstantBufferSize = sizeof(RtvDsvClearInfo<float>);
+constexpr uint32_t g_VertexSize         = sizeof(d3d11::PositionVertex);
 
 // Updates color, depth and alpha components of cached CB if necessary.
 // Returns true if any constants are updated, false otherwise.
 template <typename T>
 bool UpdateDataCache(RtvDsvClearInfo<T> *dataCache,
                      const gl::Color<T> &color,
                      const float *zValue,
                      const uint32_t numRtvs,
@@ -302,18 +301,16 @@ gl::Error Clear11::ensureResourcesInitia
     mBlendStateKey.blendState.sourceBlendRGB        = GL_ONE;
     mBlendStateKey.blendState.sourceBlendAlpha      = GL_ONE;
     mBlendStateKey.blendState.destBlendRGB          = GL_ZERO;
     mBlendStateKey.blendState.destBlendAlpha        = GL_ZERO;
     mBlendStateKey.blendState.blendEquationRGB      = GL_FUNC_ADD;
     mBlendStateKey.blendState.blendEquationAlpha    = GL_FUNC_ADD;
     mBlendStateKey.blendState.sampleAlphaToCoverage = false;
     mBlendStateKey.blendState.dither                = true;
-    mBlendStateKey.mrt                              = false;
-    memset(mBlendStateKey.rtvMasks, 0, sizeof(mBlendStateKey.rtvMasks));
 
     mResourcesInitialized = true;
     return gl::NoError();
 }
 
 bool Clear11::useVertexBuffer() const
 {
     return (mRenderer->getRenderer11DeviceCaps().featureLevel <= D3D_FEATURE_LEVEL_9_3);
@@ -420,17 +417,17 @@ gl::Error Clear11::clearFramebuffer(cons
 
     const auto *depthStencilAttachment = fboData.getDepthOrStencilAttachment();
     if (depthStencilAttachment != nullptr)
     {
         framebufferSize = depthStencilAttachment->getSize();
     }
     else
     {
-        const auto colorAttachment = fboData.getFirstColorAttachment();
+        const gl::FramebufferAttachment *colorAttachment = fboData.getFirstColorAttachment();
 
         if (!colorAttachment)
         {
             UNREACHABLE();
             return gl::InternalError();
         }
 
         framebufferSize = colorAttachment->getSize();
@@ -687,17 +684,17 @@ gl::Error Clear11::clearFramebuffer(cons
 
     ASSERT(numRtvs <= mRenderer->getNativeCaps().maxDrawBuffers);
 
     // Setup BlendStateKey parameters
     mBlendStateKey.blendState.colorMaskRed   = clearParams.colorMaskRed;
     mBlendStateKey.blendState.colorMaskGreen = clearParams.colorMaskGreen;
     mBlendStateKey.blendState.colorMaskBlue  = clearParams.colorMaskBlue;
     mBlendStateKey.blendState.colorMaskAlpha = clearParams.colorMaskAlpha;
-    mBlendStateKey.mrt                       = numRtvs > 1;
+    mBlendStateKey.rtvMax                    = numRtvs;
     memcpy(mBlendStateKey.rtvMasks, &rtvMasks[0], sizeof(mBlendStateKey.rtvMasks));
 
     // Get BlendState
     const d3d11::BlendState *blendState = nullptr;
     ANGLE_TRY(mRenderer->getBlendState(mBlendStateKey, &blendState));
 
     const d3d11::DepthStencilState *dsState = nullptr;
     const float *zValue              = nullptr;
@@ -739,22 +736,18 @@ gl::Error Clear11::clearFramebuffer(cons
 
     ANGLE_TRY(ensureConstantBufferCreated());
 
     if (dirtyCb)
     {
         // Update the constant buffer with the updated cache contents
         // TODO(Shahmeer): Consider using UpdateSubresource1 D3D11_COPY_DISCARD where possible.
         D3D11_MAPPED_SUBRESOURCE mappedResource;
-        HRESULT result = deviceContext->Map(mConstantBuffer.get(), 0, D3D11_MAP_WRITE_DISCARD, 0,
-                                            &mappedResource);
-        if (FAILED(result))
-        {
-            return gl::OutOfMemory() << "Clear11: Failed to map CB, " << gl::FmtHR(result);
-        }
+        ANGLE_TRY(mRenderer->mapResource(mConstantBuffer.get(), 0, D3D11_MAP_WRITE_DISCARD, 0,
+                                         &mappedResource));
 
         memcpy(mappedResource.pData, &mShaderData, g_ConstantBufferSize);
         deviceContext->Unmap(mConstantBuffer.get(), 0);
     }
 
     auto *stateManager = mRenderer->getStateManager();
 
     // Set the viewport to be the same size as the framebuffer.
@@ -827,9 +820,10 @@ gl::Error Clear11::clearFramebuffer(cons
         {
             ASSERT(hasLayeredLayout);
             deviceContext->DrawInstanced(6, static_cast<UINT>(fboData.getNumViews()), 0, 0);
         }
     }
 
     return gl::NoError();
 }
+
 }  // namespace rx
--- a/gfx/angle/src/libANGLE/renderer/d3d/d3d11/Clear11.h
+++ b/gfx/angle/src/libANGLE/renderer/d3d/d3d11/Clear11.h
@@ -10,17 +10,17 @@
 #define LIBANGLE_RENDERER_D3D_D3D11_CLEAR11_H_
 
 #include <map>
 #include <vector>
 
 #include "libANGLE/angletypes.h"
 #include "libANGLE/Error.h"
 #include "libANGLE/Framebuffer.h"
-#include "libANGLE/renderer/d3d/d3d11/Renderer11.h"
+#include "libANGLE/renderer/d3d/d3d11/renderer11_utils.h"
 
 namespace rx
 {
 class Renderer11;
 class RenderTarget11;
 struct ClearParameters;
 
 template <typename T>
--- a/gfx/angle/src/libANGLE/renderer/d3d/d3d11/Context11.cpp
+++ b/gfx/angle/src/libANGLE/renderer/d3d/d3d11/Context11.cpp
@@ -142,22 +142,22 @@ ProgramPipelineImpl *Context11::createPr
     return new ProgramPipeline11(data);
 }
 
 std::vector<PathImpl *> Context11::createPaths(GLsizei)
 {
     return std::vector<PathImpl *>();
 }
 
-gl::Error Context11::flush()
+gl::Error Context11::flush(const gl::Context *context)
 {
     return mRenderer->flush();
 }
 
-gl::Error Context11::finish()
+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);
@@ -256,16 +256,28 @@ void Context11::pushGroupMarker(GLsizei 
     }
 }
 
 void Context11::popGroupMarker()
 {
     mRenderer->getAnnotator()->endEvent();
 }
 
+void Context11::pushDebugGroup(GLenum source, GLuint id, GLsizei length, const char *message)
+{
+    // Fall through to the EXT_debug_marker functions
+    pushGroupMarker(length, message);
+}
+
+void Context11::popDebugGroup()
+{
+    // Fall through to the EXT_debug_marker functions
+    popGroupMarker();
+}
+
 void Context11::syncState(const gl::Context *context, const gl::State::DirtyBits &dirtyBits)
 {
     mRenderer->getStateManager()->syncState(context, dirtyBits);
 }
 
 GLint Context11::getGPUDisjoint()
 {
     return mRenderer->getGPUDisjoint();
@@ -304,16 +316,22 @@ const gl::Limitations &Context11::getNat
 gl::Error Context11::dispatchCompute(const gl::Context *context,
                                      GLuint numGroupsX,
                                      GLuint numGroupsY,
                                      GLuint numGroupsZ)
 {
     return mRenderer->dispatchCompute(context, numGroupsX, numGroupsY, numGroupsZ);
 }
 
+gl::Error Context11::dispatchComputeIndirect(const gl::Context *context, GLintptr indirect)
+{
+    UNIMPLEMENTED();
+    return gl::InternalError();
+}
+
 gl::Error Context11::triggerDrawCallProgramRecompilation(const gl::Context *context,
                                                          GLenum drawMode)
 {
     const auto &glState    = context->getGLState();
     const auto *va11       = GetImplAs<VertexArray11>(glState.getVertexArray());
     const auto *drawFBO    = glState.getDrawFramebuffer();
     gl::Program *program   = glState.getProgram();
     ProgramD3D *programD3D = GetImplAs<ProgramD3D>(program);
@@ -385,9 +403,21 @@ gl::Error Context11::triggerDrawCallProg
 }
 
 gl::Error Context11::prepareForDrawCall(const gl::Context *context, GLenum drawMode)
 {
     ANGLE_TRY(mRenderer->getStateManager()->updateState(context, drawMode));
     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/src/libANGLE/renderer/d3d/d3d11/Context11.h
+++ b/gfx/angle/src/libANGLE/renderer/d3d/d3d11/Context11.h
@@ -58,18 +58,18 @@ class Context11 : public ContextImpl
 
     // Program Pipeline object creation
     ProgramPipelineImpl *createProgramPipeline(const gl::ProgramPipelineState &data) override;
 
     // Path object creation.
     std::vector<PathImpl *> createPaths(GLsizei) override;
 
     // Flush and finish.
-    gl::Error flush() override;
-    gl::Error finish() override;
+    gl::Error flush(const gl::Context *context) override;
+    gl::Error finish(const gl::Context *context) override;
 
     // Drawing methods.
     gl::Error drawArrays(const gl::Context *context,
                          GLenum mode,
                          GLint first,
                          GLsizei count) override;
     gl::Error drawArraysInstanced(const gl::Context *context,
                                   GLenum mode,
@@ -105,21 +105,25 @@ class Context11 : public ContextImpl
 
     // Device loss
     GLenum getResetStatus() override;
 
     // Vendor and description strings.
     std::string getVendorString() const override;
     std::string getRendererDescription() const override;
 
-    // Debug markers.
+    // EXT_debug_marker
     void insertEventMarker(GLsizei length, const char *marker) override;
     void pushGroupMarker(GLsizei length, const char *marker) override;
     void popGroupMarker() override;
 
+    // KHR_debug
+    void pushDebugGroup(GLenum source, GLuint id, GLsizei length, const char *message) override;
+    void popDebugGroup() override;
+
     // State sync with dirty bits.
     void syncState(const gl::Context *context, const gl::State::DirtyBits &dirtyBits) override;
 
     // Disjoint timer queries
     GLint getGPUDisjoint() override;
     GLint64 getTimestamp() override;
 
     // Context switching
@@ -132,16 +136,20 @@ class Context11 : public ContextImpl
     const gl::Limitations &getNativeLimitations() const override;
 
     Renderer11 *getRenderer() const { return mRenderer; }
 
     gl::Error dispatchCompute(const gl::Context *context,
                               GLuint numGroupsX,
                               GLuint numGroupsY,
                               GLuint numGroupsZ) override;
+    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);
 
     Renderer11 *mRenderer;
 };
--- a/gfx/angle/src/libANGLE/renderer/d3d/d3d11/Fence11.cpp
+++ b/gfx/angle/src/libANGLE/renderer/d3d/d3d11/Fence11.cpp
@@ -164,19 +164,25 @@ gl::Error Sync11::clientWait(GLbitfield 
         *outResult = GL_TIMEOUT_EXPIRED;
         return gl::NoError();
     }
 
     LARGE_INTEGER currentCounter = {};
     BOOL success                 = QueryPerformanceCounter(&currentCounter);
     ASSERT(success);
 
-    LONGLONG timeoutInSeconds = static_cast<LONGLONG>(timeout) * static_cast<LONGLONG>(1000000ll);
+    LONGLONG timeoutInSeconds = static_cast<LONGLONG>(timeout / 1000000000ull);
     LONGLONG endCounter       = currentCounter.QuadPart + mCounterFrequency * timeoutInSeconds;
 
+    // Extremely unlikely, but if mCounterFrequency is large enough, endCounter can wrap
+    if (endCounter < currentCounter.QuadPart)
+    {
+        endCounter = MAXLONGLONG;
+    }
+
     int loopCount = 0;
     while (currentCounter.QuadPart < endCounter && !result)
     {
         loopCount++;
         ScheduleYield();
         success = QueryPerformanceCounter(&currentCounter);
         ASSERT(success);
 
--- a/gfx/angle/src/libANGLE/renderer/d3d/d3d11/Framebuffer11.cpp
+++ b/gfx/angle/src/libANGLE/renderer/d3d/d3d11/Framebuffer11.cpp
@@ -66,17 +66,18 @@ void UpdateCachedRenderTarget(const gl::
         gl::Error error = attachment->getRenderTarget(context, &newRenderTarget);
         if (error.isError())
         {
             ERR() << "Internal rendertarget error: " << error;
         }
     }
     if (newRenderTarget != cachedRenderTarget)
     {
-        auto channel = (newRenderTarget ? newRenderTarget->getBroadcastChannel() : nullptr);
+        OnRenderTargetDirtyChannel *channel =
+            (newRenderTarget ? newRenderTarget->getBroadcastChannel() : nullptr);
         channelBinding->bind(channel);
         cachedRenderTarget = newRenderTarget;
     }
 }
 }  // anonymous namespace
 
 Framebuffer11::Framebuffer11(const gl::FramebufferState &data, Renderer11 *renderer)
     : FramebufferD3D(data, renderer),
@@ -101,17 +102,17 @@ gl::Error Framebuffer11::markAttachments
     const auto &colorAttachments = mState.getColorAttachments();
     for (size_t drawBuffer : mState.getEnabledDrawBuffers())
     {
         const gl::FramebufferAttachment &colorAttachment = colorAttachments[drawBuffer];
         ASSERT(colorAttachment.isAttached());
         ANGLE_TRY(MarkAttachmentsDirty(context, &colorAttachment));
     }
 
-    auto dsAttachment = mState.getDepthOrStencilAttachment();
+    const gl::FramebufferAttachment *dsAttachment = mState.getDepthOrStencilAttachment();
     if (dsAttachment)
     {
         ANGLE_TRY(MarkAttachmentsDirty(context, dsAttachment));
     }
 
     return gl::NoError();
 }
 
@@ -193,17 +194,18 @@ gl::Error Framebuffer11::invalidateBase(
           default:
             {
                 // Handle color attachments
                 ASSERT((attachments[i] >= GL_COLOR_ATTACHMENT0 && attachments[i] <= GL_COLOR_ATTACHMENT15) ||
                        (attachments[i] == GL_COLOR));
 
                 size_t colorIndex =
                     (attachments[i] == GL_COLOR ? 0u : (attachments[i] - GL_COLOR_ATTACHMENT0));
-                auto colorAttachment = mState.getColorAttachment(colorIndex);
+                const gl::FramebufferAttachment *colorAttachment =
+                    mState.getColorAttachment(colorIndex);
                 if (colorAttachment)
                 {
                     ANGLE_TRY(invalidateAttachment(context, colorAttachment));
                 }
                 break;
             }
         }
     }
@@ -279,22 +281,22 @@ gl::Error Framebuffer11::readPixelsImpl(
                                         GLenum type,
                                         size_t outputPitch,
                                         const gl::PixelPackState &pack,
                                         uint8_t *pixels)
 {
     const gl::FramebufferAttachment *readAttachment = mState.getReadAttachment();
     ASSERT(readAttachment);
 
-    gl::Buffer *packBuffer = pack.pixelBuffer.get();
+    gl::Buffer *packBuffer = context->getGLState().getTargetBuffer(gl::BufferBinding::PixelPack);
     if (packBuffer != nullptr)
     {
         Buffer11 *packBufferStorage = GetImplAs<Buffer11>(packBuffer);
         PackPixelsParams packParams(area, format, type, static_cast<GLuint>(outputPitch), pack,
-                                    reinterpret_cast<ptrdiff_t>(pixels));
+                                    packBuffer, reinterpret_cast<ptrdiff_t>(pixels));
 
         return packBufferStorage->packPixels(context, *readAttachment, packParams);
     }
 
     return mRenderer->readFromAttachment(context, *readAttachment, area, format, type,
                                          static_cast<GLuint>(outputPitch), pack, pixels);
 }
 
--- a/gfx/angle/src/libANGLE/renderer/d3d/d3d11/Framebuffer11.h
+++ b/gfx/angle/src/libANGLE/renderer/d3d/d3d11/Framebuffer11.h
@@ -16,17 +16,17 @@
 namespace rx
 {
 class Renderer11;
 
 class Framebuffer11 : public FramebufferD3D, public OnRenderTargetDirtyReceiver
 {
   public:
     Framebuffer11(const gl::FramebufferState &data, Renderer11 *renderer);
-    virtual ~Framebuffer11();
+    ~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,
                          const GLenum *attachments) override;
     gl::Error invalidateSub(const gl::Context *context,
                             size_t count,
                             const GLenum *attachments,
--- a/gfx/angle/src/libANGLE/renderer/d3d/d3d11/Image11.cpp
+++ b/gfx/angle/src/libANGLE/renderer/d3d/d3d11/Image11.cpp
@@ -132,18 +132,17 @@ gl::Error Image11::CopyImage(const gl::C
 }
 
 bool Image11::isDirty() const
 {
     // If mDirty is true AND mStagingTexture doesn't exist AND mStagingTexture doesn't need to be
     // recovered from TextureStorage AND the texture doesn't require init data (i.e. a blank new
     // texture will suffice) AND robust resource initialization is not enabled then isDirty should
     // still return false.
-    if (mDirty && !mStagingTexture.valid() && !mRecoverFromStorage &&
-        !mRenderer->isRobustResourceInitEnabled())
+    if (mDirty && !mStagingTexture.valid() && !mRecoverFromStorage)
     {
         const Renderer11DeviceCaps &deviceCaps = mRenderer->getRenderer11DeviceCaps();
         const auto &formatInfo                 = d3d11::Format::Get(mInternalFormat, deviceCaps);
         if (formatInfo.dataInitializerFunction == nullptr)
         {
             return false;
         }
     }
@@ -250,18 +249,17 @@ bool Image11::redefine(GLenum target,
 
         // 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();
-        mDirty = (formatInfo.dataInitializerFunction != nullptr) ||
-                 mRenderer->isRobustResourceInitEnabled();
+        mDirty = (formatInfo.dataInitializerFunction != nullptr);
 
         return true;
     }
 
     return false;
 }
 
 DXGI_FORMAT Image11::getDXGIFormat() const
@@ -274,40 +272,39 @@ DXGI_FORMAT Image11::getDXGIFormat() con
 }
 
 // Store the pixel rectangle designated by xoffset,yoffset,width,height with pixels stored as
 // format/type at input
 // into the target pixel rectangle.
 gl::Error Image11::loadData(const gl::Context *context,
                             const gl::Box &area,
                             const gl::PixelUnpackState &unpack,
-                            GLenum inputType,
+                            GLenum type,
                             const void *input,
                             bool applySkipImages)
 {
-    const auto sizedInputFormat = getSizedInputFormat(inputType);
-    const gl::InternalFormat &inputFormat = gl::GetSizedInternalFormatInfo(sizedInputFormat);
+    const gl::InternalFormat &formatInfo = gl::GetSizedInternalFormatInfo(mInternalFormat);
     GLuint inputRowPitch                 = 0;
     ANGLE_TRY_RESULT(
-        inputFormat.computeRowPitch(area.width, unpack.alignment, unpack.rowLength),
+        formatInfo.computeRowPitch(type, area.width, unpack.alignment, unpack.rowLength),
         inputRowPitch);
     GLuint inputDepthPitch = 0;
-    ANGLE_TRY_RESULT(gl::InternalFormat::computeDepthPitch(area.height, unpack.imageHeight, inputRowPitch),
+    ANGLE_TRY_RESULT(formatInfo.computeDepthPitch(area.height, unpack.imageHeight, inputRowPitch),
                      inputDepthPitch);
     GLuint inputSkipBytes = 0;
     ANGLE_TRY_RESULT(
-        inputFormat.computeSkipBytes(inputRowPitch, inputDepthPitch, unpack, applySkipImages),
+        formatInfo.computeSkipBytes(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()(inputType).loadFunction;
+    LoadImageFunction loadFunction = d3dFormatInfo.getLoadFunctions()(type).loadFunction;
 
     D3D11_MAPPED_SUBRESOURCE mappedImage;
     ANGLE_TRY(map(context, D3D11_MAP_WRITE, &mappedImage));
 
     uint8_t *offsetMappedData = (reinterpret_cast<uint8_t *>(mappedImage.pData) +
                                  (area.y * mappedImage.RowPitch + area.x * outputPixelSize +
                                   area.z * mappedImage.DepthPitch));
     loadFunction(area.width, area.height, area.depth,
@@ -320,19 +317,19 @@ 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(gl::InternalFormat::computeDepthPitch(area.height, 0, inputRowPitch), inputDepthPitch);
+    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;
 
     ASSERT(area.x % outputBlockWidth == 0);
     ASSERT(area.y % outputBlockHeight == 0);
@@ -567,16 +564,17 @@ gl::Error Image11::createStagingTexture(
             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)
     {
         D3D11_TEXTURE2D_DESC desc;
         desc.Width              = width;
         desc.Height             = height;
@@ -601,16 +599,17 @@ gl::Error Image11::createStagingTexture(
             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);
     }
     else
     {
         UNREACHABLE();
     }
 
     mDirty = false;
@@ -621,30 +620,19 @@ gl::Error Image11::map(const gl::Context
 {
     // We must recover from the TextureStorage if necessary, even for D3D11_MAP_WRITE.
     ANGLE_TRY(recoverFromAssociatedStorage(context));
 
     const TextureHelper11 *stagingTexture = nullptr;
     unsigned int subresourceIndex  = 0;
     ANGLE_TRY(getStagingTexture(&stagingTexture, &subresourceIndex));
 
-    ID3D11DeviceContext *deviceContext = mRenderer->getDeviceContext();
-
     ASSERT(stagingTexture && stagingTexture->valid());
-    HRESULT result = deviceContext->Map(stagingTexture->get(), subresourceIndex, mapType, 0, map);
 
-    if (FAILED(result))
-    {
-        // this can fail if the device is removed (from TDR)
-        if (d3d11::isDeviceLostError(result))
-        {
-            mRenderer->notifyDeviceLost();
-        }
-        return gl::OutOfMemory() << "Failed to map staging texture, " << gl::FmtHR(result);
-    }
+    ANGLE_TRY(mRenderer->mapResource(stagingTexture->get(), subresourceIndex, mapType, 0, map));
 
     mDirty = true;
 
     return gl::NoError();
 }
 
 void Image11::unmap()
 {
--- a/gfx/angle/src/libANGLE/renderer/d3d/d3d11/Image11.h
+++ b/gfx/angle/src/libANGLE/renderer/d3d/d3d11/Image11.h
@@ -26,33 +26,33 @@ class Renderer11;
 class TextureHelper11;
 class TextureStorage11;
 struct Renderer11DeviceCaps;
 
 class Image11 : public ImageD3D
 {
   public:
     Image11(Renderer11 *renderer);
-    virtual ~Image11();
+    ~Image11() override;
 
     static gl::Error GenerateMipmap(const gl::Context *context,
                                     Image11 *dest,
                                     Image11 *src,
                                     const Renderer11DeviceCaps &rendererCaps);
     static gl::Error CopyImage(const gl::Context *context,
                                Image11 *dest,
                                Image11 *source,
                                const gl::Rectangle &sourceRect,
                                const gl::Offset &destOffset,
                                bool unpackFlipY,
                                bool unpackPremultiplyAlpha,
                                bool unpackUnmultiplyAlpha,
                                const Renderer11DeviceCaps &rendererCaps);
 
-    virtual bool isDirty() const;
+    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;
 
--- a/gfx/angle/src/libANGLE/renderer/d3d/d3d11/IndexBuffer11.cpp
+++ b/gfx/angle/src/libANGLE/renderer/d3d/d3d11/IndexBuffer11.cpp
@@ -66,25 +66,19 @@ gl::Error IndexBuffer11::mapBuffer(unsig
     }
 
     // Check for integer overflows and out-out-bounds map requests
     if (offset + size < offset || offset + size > mBufferSize)
     {
         return gl::OutOfMemory() << "Index buffer map range is not inside the buffer.";
     }
 
-    ID3D11DeviceContext *dxContext = mRenderer->getDeviceContext();
-
     D3D11_MAPPED_SUBRESOURCE mappedResource;
-    HRESULT result =
-        dxContext->Map(mBuffer.get(), 0, D3D11_MAP_WRITE_NO_OVERWRITE, 0, &mappedResource);
-    if (FAILED(result))
-    {
-        return gl::OutOfMemory() << "Failed to map internal index buffer, " << gl::FmtHR(result);
-    }
+    ANGLE_TRY(
+        mRenderer->mapResource(mBuffer.get(), 0, D3D11_MAP_WRITE_NO_OVERWRITE, 0, &mappedResource));
 
     *outMappedMemory = reinterpret_cast<char*>(mappedResource.pData) + offset;
     return gl::NoError();
 }
 
 gl::Error IndexBuffer11::unmapBuffer()
 {
     if (!mBuffer.valid())
@@ -124,21 +118,18 @@ gl::Error IndexBuffer11::discard()
     if (!mBuffer.valid())
     {
         return gl::OutOfMemory() << "Internal index buffer is not initialized.";
     }
 
     ID3D11DeviceContext *dxContext = mRenderer->getDeviceContext();
 
     D3D11_MAPPED_SUBRESOURCE mappedResource;
-    HRESULT result = dxContext->Map(mBuffer.get(), 0, D3D11_MAP_WRITE_DISCARD, 0, &mappedResource);
-    if (FAILED(result))
-    {
-        return gl::OutOfMemory() << "Failed to map internal index buffer, " << gl::FmtHR(result);
-    }
+    ANGLE_TRY(
+        mRenderer->mapResource(mBuffer.get(), 0, D3D11_MAP_WRITE_DISCARD, 0, &mappedResource));
 
     dxContext->Unmap(mBuffer.get(), 0);
 
     return gl::NoError();
 }
 
 DXGI_FORMAT IndexBuffer11::getIndexFormat() const
 {
--- a/gfx/angle/src/libANGLE/renderer/d3d/d3d11/IndexBuffer11.h
+++ b/gfx/angle/src/libANGLE/renderer/d3d/d3d11/IndexBuffer11.h
@@ -15,28 +15,28 @@
 namespace rx
 {
 class Renderer11;
 
 class IndexBuffer11 : public IndexBuffer
 {
   public:
     explicit IndexBuffer11(Renderer11 *const renderer);
-    virtual ~IndexBuffer11();
+    ~IndexBuffer11() override;
 
-    virtual gl::Error initialize(unsigned int bufferSize, GLenum indexType, bool dynamic);
+    gl::Error initialize(unsigned int bufferSize, GLenum indexType, bool dynamic) override;
 
-    virtual gl::Error mapBuffer(unsigned int offset, unsigned int size, void** outMappedMemory);
-    virtual gl::Error unmapBuffer();
+    gl::Error mapBuffer(unsigned int offset, unsigned int size, void **outMappedMemory) override;
+    gl::Error unmapBuffer() override;
 
-    virtual GLenum getIndexType() const;
-    virtual unsigned int getBufferSize() const;
-    virtual gl::Error setSize(unsigned int bufferSize, GLenum indexType);
+    GLenum getIndexType() const override;
+    unsigned int getBufferSize() const override;
+    gl::Error setSize(unsigned int bufferSize, GLenum indexType) override;
 
-    virtual gl::Error discard();
+    gl::Error discard() override;
 
     DXGI_FORMAT getIndexFormat() const;
     const d3d11::Buffer &getBuffer() const;
 
   private:
     Renderer11 *const mRenderer;
 
     d3d11::Buffer mBuffer;
--- a/gfx/angle/src/libANGLE/renderer/d3d/d3d11/InputLayoutCache.cpp
+++ b/gfx/angle/src/libANGLE/renderer/d3d/d3d11/InputLayoutCache.cpp
@@ -5,29 +5,29 @@
 //
 
 // InputLayoutCache.cpp: Defines InputLayoutCache, a class that builds and caches
 // D3D11 input layouts.
 
 #include "libANGLE/renderer/d3d/d3d11/InputLayoutCache.h"
 
 #include "common/bitset_utils.h"
-#include "common/third_party/murmurhash/MurmurHash3.h"
 #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
 {
@@ -70,16 +70,18 @@ struct PackedAttribute
 };
 
 } // anonymous namespace
 
 PackedAttributeLayout::PackedAttributeLayout() : numAttributes(0), flags(0), attributeData({})
 {
 }
 
+PackedAttributeLayout::PackedAttributeLayout(const PackedAttributeLayout &other) = default;
+
 void PackedAttributeLayout::addAttributeData(GLenum glType,
                                              UINT semanticIndex,
                                              gl::VertexFormatType vertexFormatType,
                                              unsigned int divisor)
 {
     gl::AttributeType attribType = gl::GetAttributeType(glType);
 
     PackedAttribute packedAttrib;
@@ -120,17 +122,17 @@ void InputLayoutCache::clear()
     mPointSpriteIndexBuffer.reset();
 }
 
 gl::Error InputLayoutCache::applyVertexBuffers(
     const gl::Context *context,
     const std::vector<const TranslatedAttribute *> &currentAttributes,
     GLenum mode,
     GLint start,
-    TranslatedIndexData *indexInfo)
+    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();
@@ -155,18 +157,21 @@ gl::Error InputLayoutCache::applyVertexB
             // 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 && (indexInfo != nullptr))
+            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);
@@ -299,17 +304,17 @@ gl::Error InputLayoutCache::updateVertex
 }
 
 gl::Error InputLayoutCache::updateInputLayout(
     Renderer11 *renderer,
     const gl::State &state,
     const std::vector<const TranslatedAttribute *> &currentAttributes,
     GLenum mode,
     const AttribIndexArray &sortedSemanticIndices,
-    GLsizei numIndicesPerInstance)
+    const DrawCallVertexParams &vertexParams)
 {
     gl::Program *program         = state.getProgram();
     const auto &shaderAttributes = program->getAttributes();
     PackedAttributeLayout layout;
 
     ProgramD3D *programD3D = GetImplAs<ProgramD3D>(program);
     bool programUsesInstancedPointSprites =
         programD3D->usesPointSize() && programD3D->usesInstancedPointSpriteEmulation();
@@ -320,17 +325,17 @@ gl::Error InputLayoutCache::updateInputL
         layout.flags |= PackedAttributeLayout::FLAG_USES_INSTANCED_SPRITES;
     }
 
     if (instancedPointSpritesActive)
     {
         layout.flags |= PackedAttributeLayout::FLAG_INSTANCED_SPRITES_ACTIVE;
     }
 
-    if (numIndicesPerInstance > 0)
+    if (vertexParams.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;
@@ -362,44 +367,44 @@ gl::Error InputLayoutCache::updateInputL
             inputLayout = &it->second;
         }
         else
         {
             angle::TrimCache(mLayoutCache.max_size() / 2, kGCLimit, "input layout", &mLayoutCache);
 
             d3d11::InputLayout newInputLayout;
             ANGLE_TRY(createInputLayout(renderer, sortedSemanticIndices, currentAttributes, mode,
-                                        program, numIndicesPerInstance, &newInputLayout));
+                                        program, vertexParams, &newInputLayout));
 
             auto insertIt = mLayoutCache.Put(layout, std::move(newInputLayout));
             inputLayout   = &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,
-    GLsizei numIndicesPerInstance,
+    const DrawCallVertexParams &vertexParams,
     d3d11::InputLayout *inputLayoutOut)
 {
     ProgramD3D *programD3D = GetImplAs<ProgramD3D>(program);
     auto featureLevel      = renderer->getRenderer11DeviceCaps().featureLevel;
 
     bool programUsesInstancedPointSprites =
         programD3D->usesPointSize() && programD3D->usesInstancedPointSpriteEmulation();
 
     unsigned int inputElementCount = 0;
-    std::array<D3D11_INPUT_ELEMENT_DESC, gl::MAX_VERTEX_ATTRIBS> inputElements;
+    gl::AttribArray<D3D11_INPUT_ELEMENT_DESC> inputElements;
 
     for (size_t attribIndex = 0; attribIndex < currentAttributes.size(); ++attribIndex)
     {
         const auto &attrib    = *currentAttributes[attribIndex];
         const int sortedIndex = sortedSemanticIndices[attribIndex];
 
         D3D11_INPUT_CLASSIFICATION inputClass =
             attrib.divisor > 0 ? D3D11_INPUT_PER_INSTANCE_DATA : D3D11_INPUT_PER_VERTEX_DATA;
@@ -428,16 +433,24 @@ gl::Error InputLayoutCache::createInputL
     if (programUsesInstancedPointSprites)
     {
         // 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)
+        {
+            // This may trigger an evaluation of the index range.
+            numIndicesPerInstance = vertexParams.vertexCount();
+        }
+
         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)
             {
                 inputElements[elementIndex].InputSlotClass       = D3D11_INPUT_PER_INSTANCE_DATA;
                 inputElements[elementIndex].InstanceDataStepRate = 1;
--- a/gfx/angle/src/libANGLE/renderer/d3d/d3d11/InputLayoutCache.h
+++ b/gfx/angle/src/libANGLE/renderer/d3d/d3d11/InputLayoutCache.h
@@ -22,17 +22,40 @@
 #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
 {
-struct PackedAttributeLayout;
+class DrawCallVertexParams;
+struct PackedAttributeLayout
+{
+    PackedAttributeLayout();
+    PackedAttributeLayout(const PackedAttributeLayout &other);
+
+    void addAttributeData(GLenum glType,
+                          UINT semanticIndex,
+                          gl::VertexFormatType vertexFormatType,
+                          unsigned int divisor);
+
+    bool operator==(const PackedAttributeLayout &other) const;
+
+    enum Flags
+    {
+        FLAG_USES_INSTANCED_SPRITES     = 0x1,
+        FLAG_INSTANCED_SPRITES_ACTIVE   = 0x2,
+        FLAG_INSTANCED_RENDERING_ACTIVE = 0x4,
+    };
+
+    uint32_t numAttributes;
+    uint32_t flags;
+    gl::AttribArray<uint32_t> attributeData;
+};
 }  // namespace rx
 
 namespace std
 {
 template <>
 struct hash<rx::PackedAttributeLayout>
 {
     size_t operator()(const rx::PackedAttributeLayout &value) const
@@ -50,75 +73,53 @@ class Program;
 namespace rx
 {
 struct TranslatedAttribute;
 struct TranslatedIndexData;
 struct SourceIndexData;
 class ProgramD3D;
 class Renderer11;
 
-struct PackedAttributeLayout
-{
-    PackedAttributeLayout();
-    void addAttributeData(GLenum glType,
-                          UINT semanticIndex,
-                          gl::VertexFormatType vertexFormatType,
-                          unsigned int divisor);
-
-    bool operator==(const PackedAttributeLayout &other) const;
-
-    enum Flags
-    {
-        FLAG_USES_INSTANCED_SPRITES     = 0x1,
-        FLAG_INSTANCED_SPRITES_ACTIVE   = 0x2,
-        FLAG_INSTANCED_RENDERING_ACTIVE = 0x4,
-    };
-
-    size_t numAttributes;
-    unsigned int flags;
-    std::array<uint32_t, gl::MAX_VERTEX_ATTRIBS> attributeData;
-};
-
 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,
-                                 TranslatedIndexData *indexInfo);
+                                 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,
-                                GLsizei numIndicesPerInstance);
+                                const DrawCallVertexParams &vertexParams);
 
   private:
     gl::Error createInputLayout(Renderer11 *renderer,
                                 const AttribIndexArray &sortedSemanticIndices,
                                 const std::vector<const TranslatedAttribute *> &currentAttributes,
                                 GLenum mode,
                                 gl::Program *program,
-                                GLsizei numIndicesPerInstance,
+                                const DrawCallVertexParams &vertexParams,
                                 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;
 
--- a/gfx/angle/src/libANGLE/renderer/d3d/d3d11/PixelTransfer11.cpp
+++ b/gfx/angle/src/libANGLE/renderer/d3d/d3d11/PixelTransfer11.cpp
@@ -148,17 +148,18 @@ gl::Error PixelTransfer11::copyBufferToT
     ANGLE_TRY(loadResources());
 
     gl::Extents destSize = destRenderTarget->getExtents();
 
     ASSERT(destArea.x >= 0 && destArea.x + destArea.width  <= destSize.width  &&
            destArea.y >= 0 && destArea.y + destArea.height <= destSize.height &&
            destArea.z >= 0 && destArea.z + destArea.depth  <= destSize.depth  );
 
-    const gl::Buffer &sourceBuffer = *unpack.pixelBuffer.get();
+    const gl::Buffer &sourceBuffer =
+        *context->getGLState().getTargetBuffer(gl::BufferBinding::PixelUnpack);
 
     ASSERT(mRenderer->supportsFastCopyBufferToTexture(destinationFormat));
 
     const d3d11::PixelShader *pixelShader = findBufferToTexturePS(destinationFormat);
     ASSERT(pixelShader);
 
     // The SRV must be in the proper read format, which may be different from the destination format
     // EG: for half float data, we can load full precision floats with implicit conversion
@@ -182,20 +183,20 @@ gl::Error PixelTransfer11::copyBufferToT
     CopyShaderParams shaderParams;
     setBufferToTextureCopyParams(destArea, destSize, sourceglFormatInfo.sizedInternalFormat, unpack,
                                  offset, &shaderParams);
 
     ID3D11DeviceContext *deviceContext = mRenderer->getDeviceContext();
 
     // Are we doing a 2D or 3D copy?
     const auto *geometryShader = ((destSize.depth > 1) ? &mBufferToTextureGS : nullptr);
-    auto stateManager          = mRenderer->getStateManager();
+    StateManager11 *stateManager = mRenderer->getStateManager();
 
     stateManager->setDrawShaders(&mBufferToTextureVS, geometryShader, pixelShader);
-    stateManager->setShaderResource(gl::SAMPLER_PIXEL, 0, bufferSRV);
+    stateManager->setShaderResource(gl::SHADER_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/src/libANGLE/renderer/d3d/d3d11/RenderStateCache.cpp
+++ b/gfx/angle/src/libANGLE/renderer/d3d/d3d11/RenderStateCache.cpp
@@ -7,17 +7,16 @@
 // RenderStateCache.cpp: Defines rx::RenderStateCache, a cache of Direct3D render
 // state objects.
 
 #include "libANGLE/renderer/d3d/d3d11/RenderStateCache.h"
 
 #include <float.h>
 
 #include "common/debug.h"
-#include "common/third_party/murmurhash/MurmurHash3.h"
 #include "libANGLE/Framebuffer.h"
 #include "libANGLE/FramebufferAttachment.h"
 #include "libANGLE/renderer/d3d/FramebufferD3D.h"
 #include "libANGLE/renderer/d3d/d3d11/renderer11_utils.h"
 #include "libANGLE/renderer/d3d/d3d11/Renderer11.h"
 
 namespace rx
 {
@@ -51,41 +50,27 @@ d3d11::BlendStateKey RenderStateCache::G
     d3d11::BlendStateKey key;
     FramebufferD3D *framebufferD3D         = GetImplAs<FramebufferD3D>(framebuffer);
     const gl::AttachmentList &colorbuffers = framebufferD3D->getColorAttachmentsForRender(context);
     const UINT8 blendStateMask =
         gl_d3d11::ConvertColorMask(blendState.colorMaskRed, blendState.colorMaskGreen,
                                    blendState.colorMaskBlue, blendState.colorMaskAlpha);
 
     key.blendState = blendState;
-    key.mrt        = false;
 
     for (size_t i = 0; i < colorbuffers.size(); i++)
     {
         const gl::FramebufferAttachment *attachment = colorbuffers[i];
 
         if (attachment)
         {
-            if (i > 0)
-            {
-                key.mrt = true;
-            }
-
+            key.rtvMax = static_cast<uint32_t>(i) + 1;
             key.rtvMasks[i] =
                 (gl_d3d11::GetColorMask(*attachment->getFormat().info)) & blendStateMask;
         }
-        else
-        {
-            key.rtvMasks[i] = 0;
-        }
-    }
-
-    for (size_t i = colorbuffers.size(); i < D3D11_SIMULTANEOUS_RENDER_TARGET_COUNT; i++)
-    {
-        key.rtvMasks[i] = 0;
     }
 
     return key;
 }
 
 gl::Error RenderStateCache::getBlendState(Renderer11 *renderer,
                                           const d3d11::BlendStateKey &key,
                                           const d3d11::BlendState **outBlendState)
@@ -100,17 +85,17 @@ gl::Error RenderStateCache::getBlendStat
     TrimCache(kMaxStates, kGCLimit, "blend state", &mBlendStateCache);
 
     // Create a new blend state and insert it into the cache
     D3D11_BLEND_DESC blendDesc;
     D3D11_RENDER_TARGET_BLEND_DESC &rtDesc0 = blendDesc.RenderTarget[0];
     const gl::BlendState &blendState        = key.blendState;
 
     blendDesc.AlphaToCoverageEnable  = blendState.sampleAlphaToCoverage;
-    blendDesc.IndependentBlendEnable = key.mrt ? TRUE : FALSE;
+    blendDesc.IndependentBlendEnable = key.rtvMax > 1 ? TRUE : FALSE;
 
     rtDesc0 = {};
 
     if (blendState.blend)
     {
         rtDesc0.BlendEnable    = true;
         rtDesc0.SrcBlend       = gl_d3d11::ConvertBlendFunc(blendState.sourceBlendRGB, false);
         rtDesc0.DestBlend      = gl_d3d11::ConvertBlendFunc(blendState.destBlendRGB, false);
@@ -139,17 +124,17 @@ gl::Error RenderStateCache::getBlendStat
 
 gl::Error RenderStateCache::getRasterizerState(Renderer11 *renderer,
                                                const gl::RasterizerState &rasterState,
                                                bool scissorEnabled,
                                                ID3D11RasterizerState **outRasterizerState)
 {
     d3d11::RasterizerStateKey key;
     key.rasterizerState = rasterState;
-    key.scissorEnabled = scissorEnabled;
+    key.scissorEnabled  = scissorEnabled ? 1 : 0;
 
     auto keyIter = mRasterizerStateCache.Get(key);
     if (keyIter != mRasterizerStateCache.end())
     {
         *outRasterizerState = keyIter->second.get();
         return gl::NoError();
     }
 
--- a/gfx/angle/src/libANGLE/renderer/d3d/d3d11/RenderTarget11.h
+++ b/gfx/angle/src/libANGLE/renderer/d3d/d3d11/RenderTarget11.h
@@ -19,17 +19,17 @@ namespace rx
 {
 class SwapChain11;
 class Renderer11;
 
 class RenderTarget11 : public RenderTargetD3D
 {
   public:
     RenderTarget11(const d3d11::Format &formatSet);
-    virtual ~RenderTarget11();
+    ~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;
@@ -62,17 +62,17 @@ class TextureRenderTarget11 : public Ren
                           const TextureHelper11 &resource,
                           const d3d11::SharedSRV &srv,
                           GLenum internalFormat,
                           const d3d11::Format &formatSet,
                           GLsizei width,
                           GLsizei height,
                           GLsizei depth,
                           GLsizei samples);
-    virtual ~TextureRenderTarget11();
+    ~TextureRenderTarget11() override;
 
     GLsizei getWidth() const override;
     GLsizei getHeight() const override;
     GLsizei getDepth() const override;
     GLenum getInternalFormat() const override;
     GLsizei getSamples() const override;
 
     const TextureHelper11 &getTexture() const override;
@@ -100,17 +100,17 @@ class TextureRenderTarget11 : public Ren
     // targets.
     d3d11::SharedSRV mBlitShaderResource;
 };
 
 class SurfaceRenderTarget11 : public RenderTarget11
 {
   public:
     SurfaceRenderTarget11(SwapChain11 *swapChain, Renderer11 *renderer, bool depth);
-    virtual ~SurfaceRenderTarget11();
+    ~SurfaceRenderTarget11() override;
 
     GLsizei getWidth() const override;
     GLsizei getHeight() const override;
     GLsizei getDepth() const override;
     GLenum getInternalFormat() const override;
     GLsizei getSamples() const override;
 
     const TextureHelper11 &getTexture() const override;
--- a/gfx/angle/src/libANGLE/renderer/d3d/d3d11/Renderer11.cpp
+++ b/gfx/angle/src/libANGLE/renderer/d3d/d3d11/Renderer11.cpp
@@ -42,17 +42,17 @@
 #include "libANGLE/renderer/d3d/d3d11/Fence11.h"
 #include "libANGLE/renderer/d3d/d3d11/Framebuffer11.h"
 #include "libANGLE/renderer/d3d/d3d11/Image11.h"
 #include "libANGLE/renderer/d3d/d3d11/IndexBuffer11.h"
 #include "libANGLE/renderer/d3d/d3d11/PixelTransfer11.h"
 #include "libANGLE/renderer/d3d/d3d11/Query11.h"
 #include "libANGLE/renderer/d3d/d3d11/RenderTarget11.h"
 #include "libANGLE/renderer/d3d/d3d11/ShaderExecutable11.h"
-#include "libANGLE/renderer/d3d/d3d11/StreamProducerNV12.h"
+#include "libANGLE/renderer/d3d/d3d11/StreamProducerD3DTexture.h"
 #include "libANGLE/renderer/d3d/d3d11/SwapChain11.h"
 #include "libANGLE/renderer/d3d/d3d11/TextureStorage11.h"
 #include "libANGLE/renderer/d3d/d3d11/TransformFeedback11.h"
 #include "libANGLE/renderer/d3d/d3d11/Trim11.h"
 #include "libANGLE/renderer/d3d/d3d11/VertexArray11.h"
 #include "libANGLE/renderer/d3d/d3d11/VertexBuffer11.h"
 #include "libANGLE/renderer/d3d/d3d11/dxgi_support_table.h"
 #include "libANGLE/renderer/d3d/d3d11/formatutils11.h"
@@ -75,22 +75,16 @@
 #endif
 
 // Enable ANGLE_SKIP_DXGI_1_2_CHECK if there is not a possibility of using cross-process
 // HWNDs or the Windows 7 Platform Update (KB2670838) is expected to be installed.
 #ifndef ANGLE_SKIP_DXGI_1_2_CHECK
 #define ANGLE_SKIP_DXGI_1_2_CHECK 0
 #endif
 
-#ifdef _DEBUG
-// this flag enables suppressing some spurious warnings that pop up in certain WebGL samples
-// and conformance tests. to enable all warnings, remove this define.
-#define ANGLE_SUPPRESS_D3D11_HAZARD_WARNINGS 1
-#endif
-
 namespace rx
 {
 
 namespace
 {
 
 enum
 {
@@ -353,41 +347,52 @@ void GetTriFanIndices(const void *indice
             CopyTriangleFanIndices<GLuint>(indices, &(*bufferOut)[0], numTris);
             break;
         default:
             UNREACHABLE();
             break;
     }
 }
 
-bool DrawCallNeedsTranslation(const gl::Context *context, GLenum mode, GLenum type)
+bool DrawCallNeedsTranslation(const gl::Context *context, GLenum mode)
 {
     const auto &glState     = context->getGLState();
-    const auto &vertexArray = glState.getVertexArray();
-    auto *vertexArray11     = GetImplAs<VertexArray11>(vertexArray);
+    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->hasDynamicAttrib(context) || mode == GL_LINE_LOOP || mode == GL_TRIANGLE_FAN)
+    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;
     }
 
-    if (type != GL_NONE)
-    {
-        // Only non-streaming index data can be directly used to draw since they don't
-        // need the indices and count informations.
-        return IndexDataManager::IsStreamingIndexData(context, type, RENDERER_D3D11);
-    }
+    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 &&
+        desc.Texture2DArray.ArraySize > 1)
+        return true;
+    if (desc.ViewDimension == D3D11_RTV_DIMENSION_TEXTURE2DMSARRAY &&
+        desc.Texture2DMSArray.ArraySize > 1)
+        return true;
     return false;
 }
 
 int GetAdjustedInstanceCount(const gl::Program *program, int instanceCount)
 {
     if (!program->usesMultiview())
     {
         return instanceCount;
@@ -423,21 +428,23 @@ void PopulateFormatDeviceCaps(ID3D11Devi
 
         *outMaxSamples = sampleCount;
     }
 }
 
 bool CullsEverything(const gl::State &glState)
 {
     return (glState.getRasterizerState().cullFace &&
-            glState.getRasterizerState().cullMode == GL_FRONT_AND_BACK);
+            glState.getRasterizerState().cullMode == gl::CullFaceMode::FrontAndBack);
 }
 
 }  // anonymous namespace
 
+Renderer11DeviceCaps::Renderer11DeviceCaps() = default;
+
 Renderer11::Renderer11(egl::Display *display)
     : RendererD3D(display),
       mCreateDebugDevice(false),
       mStateCache(),
       mStateManager(this),
       mLastHistogramUpdateTime(
           ANGLEPlatformCurrent()->monotonicallyIncreasingTime(ANGLEPlatformCurrent())),
       mDebug(nullptr),
@@ -522,21 +529,21 @@ Renderer11::Renderer11(egl::Display *dis
         EGLint requestedDeviceType = static_cast<EGLint>(attributes.get(
             EGL_PLATFORM_ANGLE_DEVICE_TYPE_ANGLE, EGL_PLATFORM_ANGLE_DEVICE_TYPE_HARDWARE_ANGLE));
         switch (requestedDeviceType)
         {
             case EGL_PLATFORM_ANGLE_DEVICE_TYPE_HARDWARE_ANGLE:
                 mRequestedDriverType = D3D_DRIVER_TYPE_HARDWARE;
                 break;
 
-            case EGL_PLATFORM_ANGLE_DEVICE_TYPE_WARP_ANGLE:
+            case EGL_PLATFORM_ANGLE_DEVICE_TYPE_D3D_WARP_ANGLE:
                 mRequestedDriverType = D3D_DRIVER_TYPE_WARP;
                 break;
 
-            case EGL_PLATFORM_ANGLE_DEVICE_TYPE_REFERENCE_ANGLE:
+            case EGL_PLATFORM_ANGLE_DEVICE_TYPE_D3D_REFERENCE_ANGLE:
                 mRequestedDriverType = D3D_DRIVER_TYPE_REFERENCE;
                 break;
 
             case EGL_PLATFORM_ANGLE_DEVICE_TYPE_NULL_ANGLE:
                 mRequestedDriverType = D3D_DRIVER_TYPE_NULL;
                 break;
 
             default:
@@ -702,18 +709,18 @@ egl::Error Renderer11::initialize()
 
         if (!mDxgiFactory || FAILED(result))
         {
             return egl::EglNotInitialized(D3D11_INIT_OTHER_ERROR)
                    << "Could not create DXGI factory.";
         }
     }
 
-// Disable some spurious D3D11 debug warnings to prevent them from flooding the output log
-#if defined(ANGLE_SUPPRESS_D3D11_HAZARD_WARNINGS) && defined(_DEBUG)
+    // Disable some spurious D3D11 debug warnings to prevent them from flooding the output log
+    if (mCreateDebugDevice)
     {
         TRACE_EVENT0("gpu.angle", "Renderer11::initialize (HideWarnings)");
         ID3D11InfoQueue *infoQueue;
         result = mDevice->QueryInterface(__uuidof(ID3D11InfoQueue), (void **)&infoQueue);
 
         if (SUCCEEDED(result))
         {
             D3D11_MESSAGE_ID hideMessages[] = {
@@ -722,27 +729,34 @@ egl::Error Renderer11::initialize()
             D3D11_INFO_QUEUE_FILTER filter = {};
             filter.DenyList.NumIDs         = static_cast<unsigned int>(ArraySize(hideMessages));
             filter.DenyList.pIDList        = hideMessages;
 
             infoQueue->AddStorageFilterEntries(&filter);
             SafeRelease(infoQueue);
         }
     }
-#endif
 
 #if !defined(NDEBUG)
     mDebug = d3d11::DynamicCastComObject<ID3D11Debug>(mDevice);
 #endif
 
     ANGLE_TRY(initializeDevice());
 
     return egl::NoError();
 }
 
+HRESULT Renderer11::callD3D11CreateDevice(PFN_D3D11_CREATE_DEVICE createDevice, bool debug)
+{
+    return createDevice(
+        nullptr, mRequestedDriverType, nullptr, debug ? D3D11_CREATE_DEVICE_DEBUG : 0,
+        mAvailableFeatureLevels.data(), static_cast<unsigned int>(mAvailableFeatureLevels.size()),
+        D3D11_SDK_VERSION, &mDevice, &(mRenderer11DeviceCaps.featureLevel), &mDeviceContext);
+}
+
 egl::Error Renderer11::initializeD3DDevice()
 {
     HRESULT result = S_OK;
 
     if (!mCreatedWithDeviceEXT)
     {
 #if !defined(ANGLE_ENABLE_WINDOWS_STORE)
         PFN_D3D11_CREATE_DEVICE D3D11CreateDevice = nullptr;
@@ -770,59 +784,49 @@ egl::Error Renderer11::initializeD3DDevi
                        << "Could not retrieve D3D11CreateDevice address.";
             }
         }
 #endif
 
         if (mCreateDebugDevice)
         {
             TRACE_EVENT0("gpu.angle", "D3D11CreateDevice (Debug)");
-            result = D3D11CreateDevice(nullptr, mRequestedDriverType, nullptr,
-                                       D3D11_CREATE_DEVICE_DEBUG, mAvailableFeatureLevels.data(),
-                                       static_cast<unsigned int>(mAvailableFeatureLevels.size()),
-                                       D3D11_SDK_VERSION, &mDevice,
-                                       &(mRenderer11DeviceCaps.featureLevel), &mDeviceContext);
-
-            if (result == E_INVALIDARG &&
+            result = callD3D11CreateDevice(D3D11CreateDevice, true);
+
+            if (result == E_INVALIDARG && mAvailableFeatureLevels.size() > 1u &&
                 mAvailableFeatureLevels[0] == D3D_FEATURE_LEVEL_11_1)
             {
-                // In some older Windows platform, D3D11.1 is not supported which returns E_INVALIDARG
-                // so we omit the 11.1 feature level flag and try again
-                result = D3D11CreateDevice(nullptr, mRequestedDriverType, nullptr,
-                                           D3D11_CREATE_DEVICE_DEBUG, mAvailableFeatureLevels.data()+1,
-                                           static_cast<unsigned int>(mAvailableFeatureLevels.size())-1,
-                                           D3D11_SDK_VERSION, &mDevice,
-                                           &(mRenderer11DeviceCaps.featureLevel), &mDeviceContext);
+                // On older Windows platforms, D3D11.1 is not supported which returns E_INVALIDARG.
+                // Try again without passing D3D_FEATURE_LEVEL_11_1 in case we have other feature
+                // levels to fall back on.
+                mAvailableFeatureLevels.erase(mAvailableFeatureLevels.begin());
+                result = callD3D11CreateDevice(D3D11CreateDevice, true);
             }
 
             if (!mDevice || FAILED(result))
             {
                 WARN() << "Failed creating Debug D3D11 device - falling back to release runtime.";
             }
         }
 
         if (!mDevice || FAILED(result))
         {
             SCOPED_ANGLE_HISTOGRAM_TIMER("GPU.ANGLE.D3D11CreateDeviceMS");
             TRACE_EVENT0("gpu.angle", "D3D11CreateDevice");
 
-            result = D3D11CreateDevice(
-                nullptr, mRequestedDriverType, nullptr, 0, mAvailableFeatureLevels.data(),
-                static_cast<unsigned int>(mAvailableFeatureLevels.size()), D3D11_SDK_VERSION,
-                &mDevice, &(mRenderer11DeviceCaps.featureLevel), &mDeviceContext);
-
-            if (result == E_INVALIDARG &&
+            result = callD3D11CreateDevice(D3D11CreateDevice, false);
+
+            if (result == E_INVALIDARG && mAvailableFeatureLevels.size() > 1u &&
                 mAvailableFeatureLevels[0] == D3D_FEATURE_LEVEL_11_1)
             {
-                // In some older Windows platform, D3D11.1 is not supported which returns E_INVALIDARG
-                // so we omit the 11.1 feature level flag and try again
-                result = D3D11CreateDevice(
-                    nullptr, mRequestedDriverType, nullptr, 0, mAvailableFeatureLevels.data()+1,
-                    static_cast<unsigned int>(mAvailableFeatureLevels.size())-1, D3D11_SDK_VERSION,
-                    &mDevice, &(mRenderer11DeviceCaps.featureLevel), &mDeviceContext);
+                // On older Windows platforms, D3D11.1 is not supported which returns E_INVALIDARG.
+                // Try again without passing D3D_FEATURE_LEVEL_11_1 in case we have other feature
+                // levels to fall back on.
+                mAvailableFeatureLevels.erase(mAvailableFeatureLevels.begin());
+                result = callD3D11CreateDevice(D3D11CreateDevice, false);
             }
 
             // Cleanup done by destructor
             if (!mDevice || FAILED(result))
             {
                 ANGLE_HISTOGRAM_SPARSE_SLOWLY("GPU.ANGLE.D3D11CreateDeviceError",
                                               static_cast<int>(result));
                 return egl::EglNotInitialized(D3D11_INIT_CREATEDEVICE_ERROR)
@@ -850,16 +854,18 @@ egl::Error Renderer11::initializeD3DDevi
 
         // The Renderer11 adds a ref to the inputted D3D11 device, like D3D11CreateDevice does.
         mDevice = d3dDevice;
         mDevice->AddRef();
         mDevice->GetImmediateContext(&mDeviceContext);
         mRenderer11DeviceCaps.featureLevel = mDevice->GetFeatureLevel();
     }
 
+    mResourceManager11.setAllocationsInitialized(mCreateDebugDevice);
+
     d3d11::SetDebugName(mDeviceContext, "DeviceContext");
 
     return egl::NoError();
 }
 
 // do any one-time device initialization
 // NOTE: this is also needed after a device lost/reset
 // to reset the scene status and ensure the default states are reset.
@@ -984,17 +990,17 @@ void Renderer11::populateRenderer11Devic
                              &mRenderer11DeviceCaps.B5G5R5A1support,
                              &mRenderer11DeviceCaps.B5G5R5A1maxSamples);
 
     IDXGIAdapter2 *dxgiAdapter2 = d3d11::DynamicCastComObject<IDXGIAdapter2>(mDxgiAdapter);
     mRenderer11DeviceCaps.supportsDXGI1_2 = (dxgiAdapter2 != nullptr);
     SafeRelease(dxgiAdapter2);
 }
 
-gl::SupportedSampleSet Renderer11::generateSampleSetFromCaps(
+gl::SupportedSampleSet Renderer11::generateSampleSetForEGLConfig(
     const gl::TextureCaps &colorBufferFormatCaps,
     const gl::TextureCaps &depthStencilBufferFormatCaps) const
 {
     gl::SupportedSampleSet sampleCounts;
 
     // Generate a new set from the set intersection of sample counts between the color and depth
     // format caps.
     std::set_intersection(colorBufferFormatCaps.sampleCounts.begin(),
@@ -1010,21 +1016,18 @@ gl::SupportedSampleSet Renderer11::gener
         sampleCounts = colorBufferFormatCaps.sampleCounts;
     }
     else if (colorBufferFormatCaps.sampleCounts.empty())
     {
         // Likewise, add back the depth sample counts to the supported sample set.
         sampleCounts = depthStencilBufferFormatCaps.sampleCounts;
     }
 
-    // In EGL, no multisampling is 0, in D3D its 1, so if 1 exists, insert 0 for EGL to match.
-    if (sampleCounts.find(1) != sampleCounts.end())
-    {
-        sampleCounts.insert(0);
-    }
+    // Always support 0 samples
+    sampleCounts.insert(0);
 
     return sampleCounts;
 }
 
 egl::ConfigSet Renderer11::generateConfigs()
 {
     std::vector<GLenum> colorBufferFormats;
 
@@ -1086,17 +1089,17 @@ egl::ConfigSet Renderer11::generateConfi
 
             const gl::InternalFormat &colorBufferFormatInfo =
                 gl::GetSizedInternalFormatInfo(colorBufferInternalFormat);
             const gl::InternalFormat &depthStencilBufferFormatInfo =
                 gl::GetSizedInternalFormatInfo(depthStencilBufferInternalFormat);
             const gl::Version &maxVersion = getMaxSupportedESVersion();
 
             const gl::SupportedSampleSet sampleCounts =
-                generateSampleSetFromCaps(colorBufferFormatCaps, depthStencilBufferFormatCaps);
+                generateSampleSetForEGLConfig(colorBufferFormatCaps, depthStencilBufferFormatCaps);
 
             for (GLuint sampleCount : sampleCounts)
             {
                 egl::Config config;
                 config.renderTargetFormat = colorBufferInternalFormat;
                 config.depthStencilFormat = depthStencilBufferInternalFormat;
                 config.bufferSize         = colorBufferFormatInfo.pixelBytes * 8;
                 config.redSize            = colorBufferFormatInfo.redBits;
@@ -1200,33 +1203,32 @@ void Renderer11::generateDisplayExtensio
     outExtensions->imageBase             = true;
     outExtensions->glTexture2DImage      = true;
     outExtensions->glTextureCubemapImage = true;
     outExtensions->glRenderbufferImage   = true;
 
     outExtensions->stream                     = true;
     outExtensions->streamConsumerGLTexture    = true;
     outExtensions->streamConsumerGLTextureYUV = true;
-    // Not all D3D11 devices support NV12 textures
-    if (getNV12TextureSupport())
-    {
-        outExtensions->streamProducerD3DTextureNV12 = true;
-    }
+    outExtensions->streamProducerD3DTexture   = true;
 
     outExtensions->flexibleSurfaceCompatibility = true;
     outExtensions->directComposition            = !!mDCompModule;
 
     // Contexts are virtualized so textures can be shared globally
     outExtensions->displayTextureShareGroup = true;
 
     // getSyncValues requires direct composition.
     outExtensions->getSyncValues = outExtensions->directComposition;
 
     // D3D11 can be used without a swap chain
     outExtensions->surfacelessContext = true;
+
+    // All D3D feature levels support robust resource init
+    outExtensions->robustResourceInitialization = true;
 }
 
 gl::Error Renderer11::flush()
 {
     mDeviceContext->Flush();
     return gl::NoError();
 }
 
@@ -1506,18 +1508,18 @@ gl::Error Renderer11::drawArrays(const g
 {
     const auto &glState = context->getGLState();
 
     if (!applyPrimitiveType(glState, mode, count))
     {
         return gl::NoError();
     }
 
-    ANGLE_TRY(
-        mStateManager.applyVertexBuffer(context, mode, startVertex, count, instances, nullptr));
+    DrawCallVertexParams vertexParams(startVertex, count, instances);
+    ANGLE_TRY(mStateManager.applyVertexBuffer(context, mode, vertexParams, false));
 
     if (glState.isTransformFeedbackActiveUnpaused())
     {
         ANGLE_TRY(markTransformFeedbackUsage(context));
     }
 
     gl::Program *program = glState.getProgram();
     ASSERT(program != nullptr);
@@ -1638,50 +1640,32 @@ gl::Error Renderer11::drawElements(const
     {
         return gl::NoError();
     }
 
     // Transform feedback is not allowed for DrawElements, this error should have been caught at the
     // API validation layer.
     ASSERT(!glState.isTransformFeedbackActiveUnpaused());
 
-    TranslatedIndexData indexInfo;
+    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());
+    int baseVertex  = -startVertex;
+
     const gl::Program *program    = glState.getProgram();
     GLsizei adjustedInstanceCount = GetAdjustedInstanceCount(program, instances);
 
-    if (!DrawCallNeedsTranslation(context, mode, type))
-    {
-        ANGLE_TRY(mStateManager.applyIndexBuffer(context, nullptr, 0, type, &indexInfo));
-        ANGLE_TRY(mStateManager.applyVertexBuffer(context, mode, 0, 0, 0, &indexInfo));
-        const gl::Type &typeInfo = gl::GetTypeInfo(type);
-        unsigned int startIndexLocation =
-            static_cast<unsigned int>(reinterpret_cast<const uintptr_t>(indices)) / typeInfo.bytes;
-        if (adjustedInstanceCount > 0)
-        {
-            mDeviceContext->DrawIndexedInstanced(count, adjustedInstanceCount, startIndexLocation,
-                                                 0, 0);
-        }
-        else
-        {
-            mDeviceContext->DrawIndexed(count, startIndexLocation, 0);
-        }
-        return gl::NoError();
-    }
-
-    indexInfo.indexRange = context->getParams<gl::HasIndexRange>().getIndexRange().value();
-
-    ANGLE_TRY(mStateManager.applyIndexBuffer(context, indices, count, type, &indexInfo));
-    size_t vertexCount = indexInfo.indexRange.vertexCount();
-    ANGLE_TRY(mStateManager.applyVertexBuffer(
-        context, mode, static_cast<GLsizei>(indexInfo.indexRange.start),
-        static_cast<GLsizei>(vertexCount), instances, &indexInfo));
-
-    int startVertex = static_cast<int>(indexInfo.indexRange.start);
-    int baseVertex  = -startVertex;
-
     if (mode == GL_LINE_LOOP)
     {
         return drawLineLoop(context, count, type, indices, baseVertex, adjustedInstanceCount);
     }
 
     if (mode == GL_TRIANGLE_FAN)
     {
         return drawTriangleFan(context, count, type, indices, baseVertex, adjustedInstanceCount);
@@ -1720,17 +1704,17 @@ gl::Error Renderer11::drawElements(const
         mDeviceContext->DrawIndexedInstanced(6, count, 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 = static_cast<GLsizei>(indexInfo.indexRange.vertexCount());
+    GLsizei elementsToRender = vertexParams.vertexCount();
 
     // Each instance being rendered requires the inputlayout cache to reapply buffers and offsets.
     for (GLsizei i = 0; i < instances; i++)
     {
         ANGLE_TRY(mStateManager.updateVertexOffsetsForPointSpritesEmulation(startVertex, i));
         mDeviceContext->DrawIndexedInstanced(6, elementsToRender, 0, 0, 0);
     }
     mStateManager.invalidateVertexBuffer();
@@ -1744,40 +1728,42 @@ gl::Error Renderer11::drawArraysIndirect
     const auto &glState = context->getGLState();
     ASSERT(!glState.isTransformFeedbackActiveUnpaused());
 
     if (!applyPrimitiveType(glState, mode, std::numeric_limits<int>::max() - 1))
     {
         return gl::NoError();
     }
 
-    gl::Buffer *drawIndirectBuffer = glState.getDrawIndirectBuffer();
+    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, GL_NONE))
+    if (!DrawCallNeedsTranslation(context, mode))
     {
-        ANGLE_TRY(mStateManager.applyVertexBuffer(context, mode, 0, 0, 0, nullptr));
+        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;
 
-    ANGLE_TRY(mStateManager.applyVertexBuffer(context, mode, first, count, instances, nullptr));
+    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);
@@ -1795,61 +1781,63 @@ gl::Error Renderer11::drawElementsIndire
     const auto &glState = context->getGLState();
     ASSERT(!glState.isTransformFeedbackActiveUnpaused());
 
     if (!applyPrimitiveType(glState, mode, std::numeric_limits<int>::max() - 1))
     {
         return gl::NoError();
     }
 
-    gl::Buffer *drawIndirectBuffer = glState.getDrawIndirectBuffer();
+    gl::Buffer *drawIndirectBuffer = glState.getTargetBuffer(gl::BufferBinding::DrawIndirect);
     ASSERT(drawIndirectBuffer);
     Buffer11 *storage = GetImplAs<Buffer11>(drawIndirectBuffer);
     uintptr_t offset  = reinterpret_cast<uintptr_t>(indirect);
 
-    TranslatedIndexData indexInfo;
-    if (!DrawCallNeedsTranslation(context, mode, type))
+    // 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, &indexInfo));
-        ANGLE_TRY(mStateManager.applyVertexBuffer(context, mode, 0, 0, 0, &indexInfo));
+        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);
-    GLuint count      = cmd->count;
+    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);
-    uint8_t *indices         = static_cast<uint8_t *>(0) + firstIndex * typeInfo.bytes;
-
-    gl::Buffer *elementArrayBuffer = glState.getVertexArray()->getElementArrayBuffer().get();
-    ASSERT(elementArrayBuffer);
-    gl::IndexRange indexRange;
-    ANGLE_TRY(elementArrayBuffer->getIndexRange(context, type, reinterpret_cast<size_t>(indices),
-                                                count, glState.isPrimitiveRestartEnabled(),
-                                                &indexRange));
-
-    indexInfo.indexRange = indexRange;
-    ANGLE_TRY(mStateManager.applyIndexBuffer(context, indices, count, type, &indexInfo));
-    size_t vertexCount = indexRange.vertexCount();
-    ANGLE_TRY(mStateManager.applyVertexBuffer(
-        context, mode, static_cast<GLsizei>(indexRange.start) + baseVertex,
-        static_cast<GLsizei>(vertexCount), instances, &indexInfo));
-
-    int baseVertexLocation = -static_cast<int>(indexRange.start);
+    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);
@@ -2312,28 +2300,16 @@ bool Renderer11::getShareHandleSupport()
         return true;
     }
 
     ASSERT(mCreatedWithDeviceEXT || mRequestedDriverType == D3D_DRIVER_TYPE_HARDWARE);
     mSupportsShareHandles = true;
     return true;
 }
 
-bool Renderer11::getNV12TextureSupport() const
-{
-    HRESULT result;
-    UINT formatSupport;
-    result = mDevice->CheckFormatSupport(DXGI_FORMAT_NV12, &formatSupport);
-    if (result == E_FAIL)
-    {
-        return false;
-    }
-    return (formatSupport & D3D11_FORMAT_SUPPORT_TEXTURE2D) != 0;
-}
-
 int Renderer11::getMajorShaderModel() const
 {
     switch (mRenderer11DeviceCaps.featureLevel)
     {
         case D3D_FEATURE_LEVEL_11_1:
         case D3D_FEATURE_LEVEL_11_0:
             return D3D11_SHADER_MAJOR_VERSION;  // 5
         case D3D_FEATURE_LEVEL_10_1:
@@ -2815,26 +2791,26 @@ gl::Error Renderer11::createRenderTarget
                                           0, 0, 0, source11->getTexture().get(),
                                           source11->getSubresourceIndex(), nullptr);
     *outRT = newRT;
     return gl::NoError();
 }
 
 gl::Error Renderer11::loadExecutable(const uint8_t *function,
                                      size_t length,
-                                     ShaderType type,
+                                     gl::ShaderType type,
                                      const std::vector<D3DVarying> &streamOutVaryings,
                                      bool separatedOutputBuffers,
                                      ShaderExecutableD3D **outExecutable)
 {
     ShaderData shaderData(function, length);
 
     switch (type)
     {
-        case SHADER_VERTEX:
+        case gl::SHADER_VERTEX:
         {
             d3d11::VertexShader vertexShader;
             d3d11::GeometryShader streamOutShader;
             ANGLE_TRY(allocateResource(shaderData, &vertexShader));
 
             if (!streamOutVaryings.empty())
             {
                 std::vector<D3D11_SO_DECLARATION_ENTRY> soDeclaration;
@@ -2855,67 +2831,67 @@ gl::Error Renderer11::loadExecutable(con
 
                 ANGLE_TRY(allocateResource(shaderData, &soDeclaration, &streamOutShader));
             }
 
             *outExecutable = new ShaderExecutable11(function, length, std::move(vertexShader),
                                                     std::move(streamOutShader));
         }
         break;
-        case SHADER_PIXEL:
+        case gl::SHADER_FRAGMENT:
         {
             d3d11::PixelShader pixelShader;
             ANGLE_TRY(allocateResource(shaderData, &pixelShader));
             *outExecutable = new ShaderExecutable11(function, length, std::move(pixelShader));
         }
         break;
-        case SHADER_GEOMETRY:
+        case gl::SHADER_GEOMETRY:
         {
             d3d11::GeometryShader geometryShader;
             ANGLE_TRY(allocateResource(shaderData, &geometryShader));
             *outExecutable = new ShaderExecutable11(function, length, std::move(geometryShader));
         }
         break;
-        case SHADER_COMPUTE:
+        case gl::SHADER_COMPUTE:
         {
             d3d11::ComputeShader computeShader;
             ANGLE_TRY(allocateResource(shaderData, &computeShader));
             *outExecutable = new ShaderExecutable11(function, length, std::move(computeShader));
         }
         break;
         default:
             UNREACHABLE();
             return gl::InternalError();
     }
 
     return gl::NoError();
 }
 
 gl::Error Renderer11::compileToExecutable(gl::InfoLog &infoLog,
                                           const std::string &shaderHLSL,
-                                          ShaderType type,
+                                          gl::ShaderType type,
                                           const std::vector<D3DVarying> &streamOutVaryings,
                                           bool separatedOutputBuffers,
                                           const angle::CompilerWorkaroundsD3D &workarounds,
                                           ShaderExecutableD3D **outExectuable)
 {
     std::stringstream profileStream;
 
     switch (type)
     {
-        case SHADER_VERTEX:
+        case gl::SHADER_VERTEX:
             profileStream << "vs";
             break;
-        case SHADER_PIXEL:
+        case gl::SHADER_FRAGMENT:
             profileStream << "ps";
             break;
-        case SHADER_GEOMETRY:
+        case gl::SHADER_GEOMETRY:
             profileStream << "gs";
             break;
-        case SHADER_COMPUTE:
+        case gl::SHADER_COMPUTE:
             profileStream << "cs";
             break;
         default:
             UNREACHABLE();
             return gl::InternalError();
     }
 
     profileStream << "_" << getMajorShaderModel() << "_" << getMinorShaderModel()
@@ -3003,21 +2979,21 @@ VertexBuffer *Renderer11::createVertexBu
     return new VertexBuffer11(this);
 }
 
 IndexBuffer *Renderer11::createIndexBuffer()
 {
     return new IndexBuffer11(this);
 }
 
-StreamProducerImpl *Renderer11::createStreamProducerD3DTextureNV12(
+StreamProducerImpl *Renderer11::createStreamProducerD3DTexture(
     egl::Stream::ConsumerType consumerType,
     const egl::AttributeMap &attribs)
 {
-    return new StreamProducerNV12(this);
+    return new StreamProducerD3DTexture(this);
 }
 
 bool Renderer11::supportsFastCopyBufferToTexture(GLenum internalFormat) const
 {
     ASSERT(getNativeExtensions().pixelBufferObject);
 
     const gl::InternalFormat &internalFormatInfo = gl::GetSizedInternalFormatInfo(internalFormat);
     const d3d11::Format &d3d11FormatInfo =
@@ -3182,17 +3158,17 @@ TextureStorage *Renderer11::createTextur
                                         levels);
 }
 
 TextureStorage *Renderer11::createTextureStorage2DMultisample(GLenum internalformat,
                                                               GLsizei width,
                                                               GLsizei height,
                                                               int levels,
                                                               int samples,
-                                                              GLboolean fixedSampleLocations)
+                                                              bool fixedSampleLocations)
 {
     return new TextureStorage11_2DMultisample(this, internalformat, width, height, levels, samples,
                                               fixedSampleLocations);
 }
 
 gl::Error Renderer11::readFromAttachment(const gl::Context *context,
                                          const gl::FramebufferAttachment &srcAttachment,
                                          const gl::Rectangle &sourceArea,
@@ -3292,52 +3268,46 @@ gl::Error Renderer11::readFromAttachment
     {
         srcBox.front = static_cast<UINT>(srcAttachment.layer());
     }
     srcBox.back = srcBox.front + 1;
 
     mDeviceContext->CopySubresourceRegion(stagingHelper.get(), 0, 0, 0, 0, srcTexture->get(),
                                           sourceSubResource, &srcBox);
 
+    gl::Buffer *packBuffer = context->getGLState().getTargetBuffer(gl::BufferBinding::PixelPack);
     if (!invertTexture)
     {
-        PackPixelsParams packParams(safeArea, format, type, outputPitch, pack, 0);
+        PackPixelsParams packParams(safeArea, format, type, outputPitch, pack, packBuffer, 0);
         return packPixels(stagingHelper, packParams, pixelsOut);
     }
 
-    gl::PixelPackState invertTexturePack;
-
     // Create a new PixelPackState with reversed row order. Note that we can't just assign
     // 'invertTexturePack' to be 'pack' (or memcpy) since that breaks the ref counting/object
     // tracking in the 'pixelBuffer' members, causing leaks. Instead we must use
     // pixelBuffer.set() twice, which performs the addRef/release correctly
+    gl::PixelPackState invertTexturePack;
     invertTexturePack.alignment = pack.alignment;
-    invertTexturePack.pixelBuffer.set(context, pack.pixelBuffer.get());
     invertTexturePack.reverseRowOrder = !pack.reverseRowOrder;
 
-    PackPixelsParams packParams(safeArea, format, type, outputPitch, invertTexturePack, 0);
+    PackPixelsParams packParams(safeArea, format, type, outputPitch, invertTexturePack, packBuffer,
+                                0);
     gl::Error error = packPixels(stagingHelper, packParams, pixelsOut);
-    invertTexturePack.pixelBuffer.set(context, nullptr);
     ANGLE_TRY(error);
     return gl::NoError();
 }
 
 gl::Error Renderer11::packPixels(const TextureHelper11 &textureHelper,
                                  const PackPixelsParams &params,
                                  uint8_t *pixelsOut)
 {
     ID3D11Resource *readResource = textureHelper.get();
 
     D3D11_MAPPED_SUBRESOURCE mapping;
-    HRESULT hr = mDeviceContext->Map(readResource, 0, D3D11_MAP_READ, 0, &mapping);
-    if (FAILED(hr))
-    {
-        ASSERT(hr == E_OUTOFMEMORY);
-        return gl::OutOfMemory() << "Failed to map internal texture for reading, " << gl::FmtHR(hr);
-    }
+    ANGLE_TRY(mapResource(readResource, 0, D3D11_MAP_READ, 0, &mapping));
 
     uint8_t *source = static_cast<uint8_t *>(mapping.pData);
     int inputPitch  = static_cast<int>(mapping.RowPitch);
 
     const auto &formatInfo = textureHelper.getFormatSet();
     ASSERT(formatInfo.format().glInternalFormat != GL_NONE);
 
     PackPixels(params, formatInfo.format(), inputPitch, source, pixelsOut);
@@ -3652,17 +3622,22 @@ gl::Error Renderer11::blitRenderbufferRe
     }
 
     return gl::NoError();
 }
 
 bool Renderer11::isES3Capable() const
 {
     return (d3d11_gl::GetMaximumClientVersion(mRenderer11DeviceCaps.featureLevel).major > 2);
-};
+}
+
+RendererClass Renderer11::getRendererClass() const
+{
+    return RENDERER_D3D11;
+}
 
 void Renderer11::onSwap()
 {
     // Send histogram updates every half hour
     const double kHistogramUpdateInterval = 30 * 60;
 
     auto *platform                   = ANGLEPlatformCurrent();
     const double currentTime         = platform->monotonicallyIncreasingTime(platform);
@@ -3675,17 +3650,17 @@ void Renderer11::onSwap()
     }
 }
 
 void Renderer11::updateHistograms()
 {
     // Update the buffer CPU memory histogram
     {
         size_t sizeSum = 0;
-        for (auto &buffer : mAliveBuffers)
+        for (const Buffer11 *buffer : mAliveBuffers)
         {
             sizeSum += buffer->getTotalCPUBufferMemoryBytes();
         }
         const int kOneMegaByte = 1024 * 1024;
         ANGLE_HISTOGRAM_MEMORY_MB("GPU.ANGLE.Buffer11CPUMemoryMB",
                                   static_cast<int>(sizeSum) / kOneMegaByte);
     }
 }
@@ -3823,18 +3798,18 @@ gl::ErrorOrResult<unsigned int> Renderer
     return elementSize * elementCount;
 }
 
 void Renderer11::generateCaps(gl::Caps *outCaps,
                               gl::TextureCapsMap *outTextureCaps,
                               gl::Extensions *outExtensions,
                               gl::Limitations *outLimitations) const
 {
-    d3d11_gl::GenerateCaps(mDevice, mDeviceContext, mRenderer11DeviceCaps, outCaps, outTextureCaps,
-                           outExtensions, outLimitations);
+    d3d11_gl::GenerateCaps(mDevice, mDeviceContext, mRenderer11DeviceCaps, getWorkarounds(),
+                           outCaps, outTextureCaps, outExtensions, outLimitations);
 }
 
 angle::WorkaroundsD3D Renderer11::generateWorkarounds() const
 {
     return d3d11::GenerateWorkarounds(mRenderer11DeviceCaps, mAdapterDescription);
 }
 
 egl::Error Renderer11::getEGLDevice(DeviceImpl **device)
@@ -4011,31 +3986,79 @@ gl::Error Renderer11::getSamplerState(co
     return mStateCache.getSamplerState(this, samplerState, outSamplerState);
 }
 
 gl::Error Renderer11::clearRenderTarget(RenderTargetD3D *renderTarget,
                                         const gl::ColorF &clearColorValue,
                                         const float clearDepthValue,
                                         const unsigned int clearStencilValue)
 {
-    RenderTarget11 *renderTarget11     = GetAs<RenderTarget11>(renderTarget);
-    const d3d11::RenderTargetView &rtv = renderTarget11->getRenderTargetView();
-    ASSERT(rtv.valid());
-
-    mDeviceContext->ClearRenderTargetView(rtv.get(), &clearColorValue.red);
-
+    RenderTarget11 *rt11 = GetAs<RenderTarget11>(renderTarget);
+
+    if (rt11->getDepthStencilView().valid())
+    {
+        const auto &format    = rt11->getFormatSet();
+        const UINT clearFlags = (format.format().depthBits > 0 ? D3D11_CLEAR_DEPTH : 0) |
+                                (format.format().stencilBits ? D3D11_CLEAR_STENCIL : 0);
+        mDeviceContext->ClearDepthStencilView(rt11->getDepthStencilView().get(), clearFlags,
+                                              clearDepthValue,
+                                              static_cast<UINT8>(clearStencilValue));
+        return gl::NoError();
+    }
+
+    ASSERT(rt11->getRenderTargetView().valid());
+    ID3D11RenderTargetView *rtv = rt11->getRenderTargetView().get();
+
+    // There are complications with some types of RTV and FL 9_3 with ClearRenderTargetView.
+    // See https://msdn.microsoft.com/en-us/library/windows/desktop/ff476388(v=vs.85).aspx
+    ASSERT(mRenderer11DeviceCaps.featureLevel > D3D_FEATURE_LEVEL_9_3 || !IsArrayRTV(rtv));
+
+    const auto &d3d11Format = rt11->getFormatSet();
+    const auto &glFormat    = gl::GetSizedInternalFormatInfo(renderTarget->getInternalFormat());
+
+    gl::ColorF safeClearColor = clearColorValue;
+
+    if (d3d11Format.format().alphaBits > 0 && glFormat.alphaBits == 0)
+    {
+        safeClearColor.alpha = 1.0f;
+    }
+
+    mDeviceContext->ClearRenderTargetView(rtv, &safeClearColor.red);
     return gl::NoError();
 }
 
 bool Renderer11::canSelectViewInVertexShader() const
 {
     return !getWorkarounds().selectViewInGeometryShader &&
            getRenderer11DeviceCaps().supportsVpRtIndexWriteFromVertexShader;
 }
 
+gl::Error Renderer11::mapResource(ID3D11Resource *resource,
+                                  UINT subResource,
+                                  D3D11_MAP mapType,
+                                  UINT mapFlags,
+                                  D3D11_MAPPED_SUBRESOURCE *mappedResource)
+{
+    HRESULT hr = mDeviceContext->Map(resource, subResource, mapType, mapFlags, mappedResource);
+    if (FAILED(hr))
+    {
+        if (d3d11::isDeviceLostError(hr))
+        {
+            this->notifyDeviceLost();
+        }
+
+        // Note: gl::OutOfMemory is used instead of gl::InternalError to avoid requiring
+        // additional context queries. This is needed as gl::InternalError corresponds to
+        // GL_INVALID_OPERATION, which does not uniquely identify a device reset error.
+        return gl::OutOfMemory() << "Failed to map D3D11 resource." << gl::FmtHR(hr);
+    }
+
+    return gl::NoError();
+}
+
 gl::Error Renderer11::markTransformFeedbackUsage(const gl::Context *context)
 {
     const gl::State &glState                       = context->getGLState();
     const gl::TransformFeedback *transformFeedback = glState.getCurrentTransformFeedback();
     for (size_t i = 0; i < transformFeedback->getIndexedBufferCount(); i++)
     {
         const gl::OffsetBindingPointer<gl::Buffer> &binding =
             transformFeedback->getIndexedBuffer(i);
@@ -4044,9 +4067,14 @@ gl::Error Renderer11::markTransformFeedb
             BufferD3D *bufferD3D = GetImplAs<BufferD3D>(binding.get());
             ANGLE_TRY(bufferD3D->markTransformFeedbackUsage(context));
         }
     }
 
     return gl::NoError();
 }
 
+void Renderer11::onDirtyUniformBlockBinding(GLuint /*uniformBlockIndex*/)
+{
+    mStateManager.invalidateProgramUniformBuffers();
+}
+
 }  // namespace rx
--- a/gfx/angle/src/libANGLE/renderer/d3d/d3d11/Renderer11.h
+++ b/gfx/angle/src/libANGLE/renderer/d3d/d3d11/Renderer11.h
@@ -40,16 +40,18 @@ struct PackPixelsParams;
 class PixelTransfer11;
 class RenderTarget11;
 class StreamingIndexBufferInterface;
 class Trim11;
 class VertexDataManager;
 
 struct Renderer11DeviceCaps
 {
+    Renderer11DeviceCaps();
+
     D3D_FEATURE_LEVEL featureLevel;
     bool supportsDXGI1_2;                // Support for DXGI 1.2
     bool supportsClearView;              // Support for ID3D11DeviceContext1::ClearView
     bool supportsConstantBufferOffsets;  // Support for Constant buffer offset
     bool supportsVpRtIndexWriteFromVertexShader;  // VP/RT can be selected in the Vertex Shader
                                                   // stage.
     bool supportsMultisampledDepthStencilSRVs;  // D3D feature level 10.0 no longer allows creation
                                                 // of textures with both the bind SRV and DSV flags
@@ -107,17 +109,17 @@ enum D3D11InitError
     D3D11_INIT_CREATEDEVICE_NULL,
     NUM_D3D11_INIT_ERRORS
 };
 
 class Renderer11 : public RendererD3D
 {
   public:
     explicit Renderer11(egl::Display *display);
-    virtual ~Renderer11();
+    ~Renderer11() override;
 
     egl::Error initialize() override;
     bool resetDevice() override;
 
     egl::ConfigSet generateConfigs() override;
     void generateDisplayExtensions(egl::DisplayExtensions *outExtensions) const override;
 
     ContextImpl *createContext(const gl::ContextState &state) override;
@@ -157,18 +159,16 @@ class Renderer11 : public RendererD3D
 
     unsigned int getReservedVertexUniformVectors() const;
     unsigned int getReservedFragmentUniformVectors() const;
     unsigned int getReservedVertexUniformBuffers() const;
     unsigned int getReservedFragmentUniformBuffers() const;
 
     bool getShareHandleSupport() const;
 
-    bool getNV12TextureSupport() const;
-
     int getMajorShaderModel() const override;
     int getMinorShaderModel() const override;
     std::string getShaderModelSuffix() const override;
 
     // Pixel operations
     gl::Error copyImage2D(const gl::Context *context,
                           const gl::Framebuffer *framebuffer,
                           const gl::Rectangle &sourceRect,
@@ -223,23 +223,23 @@ class Renderer11 : public RendererD3D
                                  GLenum format,
                                  GLsizei samples,
                                  RenderTargetD3D **outRT) override;
     gl::Error createRenderTargetCopy(RenderTargetD3D *source, RenderTargetD3D **outRT) override;
 
     // Shader operations
     gl::Error loadExecutable(const uint8_t *function,
                              size_t length,
-                             ShaderType type,
+                             gl::ShaderType type,
                              const std::vector<D3DVarying> &streamOutVaryings,
                              bool separatedOutputBuffers,
                              ShaderExecutableD3D **outExecutable) override;
     gl::Error compileToExecutable(gl::InfoLog &infoLog,
                                   const std::string &shaderHLSL,
-                                  ShaderType type,
+                                  gl::ShaderType type,
                                   const std::vector<D3DVarying> &streamOutVaryings,
                                   bool separatedOutputBuffers,
                                   const angle::CompilerWorkaroundsD3D &workarounds,
                                   ShaderExecutableD3D **outExectuable) override;
     gl::Error ensureHLSLCompilerInitialized() override;
 
     UniformStorageD3D *createUniformStorage(size_t storageSize) override;
 
@@ -286,25 +286,24 @@ class Renderer11 : public RendererD3D
                                                 GLsizei height,
                                                 GLsizei depth,
                                                 int levels) override;
     TextureStorage *createTextureStorage2DMultisample(GLenum internalformat,
                                                       GLsizei width,
                                                       GLsizei height,
                                                       int levels,
                                                       int samples,
-                                                      GLboolean fixedSampleLocations) override;
+                                                      bool fixedSampleLocations) override;
 
     VertexBuffer *createVertexBuffer() override;
     IndexBuffer *createIndexBuffer() override;
 
     // Stream Creation
-    StreamProducerImpl *createStreamProducerD3DTextureNV12(
-        egl::Stream::ConsumerType consumerType,
-        const egl::AttributeMap &attribs) override;
+    StreamProducerImpl *createStreamProducerD3DTexture(egl::Stream::ConsumerType consumerType,
+                                                       const egl::AttributeMap &attribs) override;
 
     // D3D11-renderer specific methods
     ID3D11Device *getDevice() { return mDevice; }
     void *getD3DDevice() override;
     ID3D11DeviceContext *getDeviceContext() { return mDeviceContext; };
     ID3D11DeviceContext1 *getDeviceContext1IfSupported() { return mDeviceContext1; };
     IDXGIFactory *getDxgiFactory() { return mDxgiFactory; };
 
@@ -366,17 +365,17 @@ class Renderer11 : public RendererD3D
                                    const gl::Rectangle *scissor,
                                    bool colorBlit,
                                    bool depthBlit,
                                    bool stencilBlit);
 
     bool isES3Capable() const;
     const Renderer11DeviceCaps &getRenderer11DeviceCaps() const { return mRenderer11DeviceCaps; };
 
-    RendererClass getRendererClass() const override { return RENDERER_D3D11; }
+    RendererClass getRendererClass() const override;
     StateManager11 *getStateManager() { return &mStateManager; }
 
     void onSwap();
     void onBufferCreate(const Buffer11 *created);
     void onBufferDelete(const Buffer11 *deleted);
 
     egl::Error getEGLDevice(DeviceImpl **device) override;
 
@@ -455,16 +454,24 @@ class Renderer11 : public RendererD3D
 
     gl::Error clearRenderTarget(RenderTargetD3D *renderTarget,
                                 const gl::ColorF &clearColorValue,
                                 const float clearDepthValue,
                                 const unsigned int clearStencilValue) override;
 
     bool canSelectViewInVertexShader() const override;
 
+    void onDirtyUniformBlockBinding(GLuint uniformBlockIndex) override;
+
+    gl::Error mapResource(ID3D11Resource *resource,
+                          UINT subResource,
+                          D3D11_MAP mapType,
+                          UINT mapFlags,
+                          D3D11_MAPPED_SUBRESOURCE *mappedResource);
+
   private:
     void generateCaps(gl::Caps *outCaps,
                       gl::TextureCapsMap *outTextureCaps,
                       gl::Extensions *outExtensions,
                       gl::Limitations *outLimitations) const override;
 
     angle::WorkaroundsD3D generateWorkarounds() const override;
 
@@ -492,20 +499,21 @@ class Renderer11 : public RendererD3D
 
     gl::Error copyImageInternal(const gl::Context *context,
                                 const gl::Framebuffer *framebuffer,
                                 const gl::Rectangle &sourceRect,
                                 GLenum destFormat,
                                 const gl::Offset &destOffset,
                                 RenderTargetD3D *destRenderTarget);
 
-    gl::SupportedSampleSet generateSampleSetFromCaps(
+    gl::SupportedSampleSet generateSampleSetForEGLConfig(
         const gl::TextureCaps &colorBufferFormatCaps,
         const gl::TextureCaps &depthStencilBufferFormatCaps) const;
 
+    HRESULT callD3D11CreateDevice(PFN_D3D11_CREATE_DEVICE createDevice, bool debug);
     egl::Error initializeD3DDevice();
     egl::Error initializeDevice();
     void releaseDeviceResources();
     void release();
 
     d3d11::ANGLED3D11DeviceType getDeviceType() const;
 
     gl::Error markTransformFeedbackUsage(const gl::Context *context);
@@ -564,127 +572,10 @@ class Renderer11 : public RendererD3D
     gl::DebugAnnotator *mAnnotator;
 
     mutable Optional<bool> mSupportsShareHandles;
     ResourceManager11 mResourceManager11;
 
     TextureHelper11 mCachedResolveTexture;
 };
 
-namespace d3d11
-{
-
-template <ResourceType ResourceT>
-class LazyResource : angle::NonCopyable
-{
-  public:
-    constexpr LazyResource() : mResource() {}
-    virtual ~LazyResource() {}
-
-    virtual gl::Error resolve(Renderer11 *renderer) = 0;
-    void reset() { mResource.reset(); }
-    GetD3D11Type<ResourceT> *get() const
-    {
-        ASSERT(mResource.valid());
-        return mResource.get();
-    }
-
-    const Resource11<GetD3D11Type<ResourceT>> &getObj() const { return mResource; }
-
-  protected:
-    LazyResource(LazyResource &&other) : mResource(std::move(other.mResource)) {}
-    gl::Error resolveImpl(Renderer11 *renderer,
-                          const GetDescType<ResourceT> &desc,
-                          GetInitDataType<ResourceT> *initData,
-                          const char *name)
-    {
-        if (!mResource.valid())
-        {
-            ANGLE_TRY(renderer->allocateResource(desc, initData, &mResource));
-            mResource.setDebugName(name);
-        }
-        return gl::NoError();
-    }
-
-    Resource11<GetD3D11Type<ResourceT>> mResource;
-};
-
-template <typename D3D11ShaderType>
-class LazyShader final : public LazyResource<GetResourceTypeFromD3D11<D3D11ShaderType>()>
-{
-  public:
-    // All parameters must be constexpr. Not supported in VS2013.
-    constexpr LazyShader(const BYTE *byteCode, size_t byteCodeSize, const char *name)
-        : mByteCode(byteCode, byteCodeSize), mName(name)
-    {
-    }
-
-    constexpr LazyShader(LazyShader &&shader)
-        : LazyResource<GetResourceTypeFromD3D11<D3D11ShaderType>()>(std::move(shader)),
-          mByteCode(std::move(shader.mByteCode)),
-          mName(shader.mName)
-    {
-    }
-
-    gl::Error resolve(Renderer11 *renderer) override
-    {
-        return this->resolveImpl(renderer, mByteCode, nullptr, mName);
-    }
-
-  private:
-    ShaderData mByteCode;
-    const char *mName;
-};
-
-class LazyInputLayout final : public LazyResource<ResourceType::InputLayout>
-{
-  public:
-    constexpr LazyInputLayout(const D3D11_INPUT_ELEMENT_DESC *inputDesc,
-                              size_t inputDescLen,
-                              const BYTE *byteCode,
-                              size_t byteCodeLen,
-                              const char *debugName)
-        : mInputDesc(inputDesc, inputDescLen),
-          mByteCode(byteCode, byteCodeLen),
-          mDebugName(debugName)
-    {
-    }
-
-    gl::Error resolve(Renderer11 *renderer) override
-    {
-        return resolveImpl(renderer, mInputDesc, &mByteCode, mDebugName);
-    }
-
-  private:
-    InputElementArray mInputDesc;
-    ShaderData mByteCode;
-    const char *mDebugName;
-};
-
-class LazyBlendState final : public LazyResource<ResourceType::BlendState>
-{
-  public:
-    LazyBlendState(const D3D11_BLEND_DESC &desc, const char *debugName)
-        : mDesc(desc), mDebugName(debugName)
-    {
-    }
-
-
-    gl::Error resolve(Renderer11 *renderer)
-    {
-        return resolveImpl(renderer, mDesc, nullptr, mDebugName);
-    }
-
-
-  private:
-    D3D11_BLEND_DESC mDesc;
-    const char *mDebugName;
-};
-
-
-
-
-
-
-}  // namespace d3d11
-
 }  // namespace rx
 #endif  // LIBANGLE_RENDERER_D3D_D3D11_RENDERER11_H_
--- a/gfx/angle/src/libANGLE/renderer/d3d/d3d11/ResourceManager11.cpp
+++ b/gfx/angle/src/libANGLE/renderer/d3d/d3d11/ResourceManager11.cpp
@@ -12,72 +12,80 @@
 #include "libANGLE/renderer/d3d/d3d11/Renderer11.h"
 #include "libANGLE/renderer/d3d/d3d11/formatutils11.h"
 
 namespace rx
 {
 
 namespace
 {
-size_t ComputeMippedMemoryUsage(unsigned int width,
-                                unsigned int height,
-                                unsigned int depth,
-                                size_t pixelSize,
-                                unsigned int mipLevels)
+
+constexpr uint8_t kDebugInitTextureDataValue = 0x48;
+constexpr FLOAT kDebugColorInitClearValue[4] = {0.3f, 0.5f, 0.7f, 0.5f};
+constexpr FLOAT kDebugDepthInitValue         = 0.2f;
+constexpr UINT8 kDebugStencilInitValue       = 3;
+
+uint64_t ComputeMippedMemoryUsage(unsigned int width,
+                                  unsigned int height,
+                                  unsigned int depth,
+                                  uint64_t pixelSize,
+                                  unsigned int mipLevels)
 {
-    size_t sizeSum = 0;
+    uint64_t sizeSum = 0;
 
     for (unsigned int level = 0; level < mipLevels; ++level)
     {
         unsigned int mipWidth  = std::max(width >> level, 1u);
         unsigned int mipHeight = std::max(height >> level, 1u);
         unsigned int mipDepth  = std::max(depth >> level, 1u);
-        sizeSum += static_cast<size_t>(mipWidth * mipHeight * mipDepth) * pixelSize;
+        sizeSum += static_cast<uint64_t>(mipWidth * mipHeight * mipDepth) * pixelSize;
     }
 
     return sizeSum;
 }
 
-size_t ComputeMemoryUsage(const D3D11_TEXTURE2D_DESC *desc)
+uint64_t ComputeMemoryUsage(const D3D11_TEXTURE2D_DESC *desc)
 {
     ASSERT(desc);
-    size_t pixelBytes = static_cast<size_t>(d3d11::GetDXGIFormatSizeInfo(desc->Format).pixelBytes);
+    uint64_t pixelBytes =
+        static_cast<uint64_t>(d3d11::GetDXGIFormatSizeInfo(desc->Format).pixelBytes);
     return ComputeMippedMemoryUsage(desc->Width, desc->Height, 1, pixelBytes, desc->MipLevels);
 }
 
-size_t ComputeMemoryUsage(const D3D11_TEXTURE3D_DESC *desc)
+uint64_t ComputeMemoryUsage(const D3D11_TEXTURE3D_DESC *desc)
 {
     ASSERT(desc);
-    size_t pixelBytes = static_cast<size_t>(d3d11::GetDXGIFormatSizeInfo(desc->Format).pixelBytes);
+    uint64_t pixelBytes =
+        static_cast<uint64_t>(d3d11::GetDXGIFormatSizeInfo(desc->Format).pixelBytes);
     return ComputeMippedMemoryUsage(desc->Width, desc->Height, desc->Depth, pixelBytes,
                                     desc->MipLevels);
 }
 
-size_t ComputeMemoryUsage(const D3D11_BUFFER_DESC *desc)
+uint64_t ComputeMemoryUsage(const D3D11_BUFFER_DESC *desc)
 {
     ASSERT(desc);
-    return static_cast<size_t>(desc->ByteWidth);
+    return static_cast<uint64_t>(desc->ByteWidth);
 }
 
 template <typename T>
-size_t ComputeMemoryUsage(const T *desc)
+uint64_t ComputeMemoryUsage(const T *desc)
 {
     return 0;
 }
 
 template <ResourceType ResourceT>
-size_t ComputeGenericMemoryUsage(ID3D11DeviceChild *genericResource)
+uint64_t ComputeGenericMemoryUsage(ID3D11DeviceChild *genericResource)
 {
     auto *typedResource = static_cast<GetD3D11Type<ResourceT> *>(genericResource);
     GetDescType<ResourceT> desc;
     typedResource->GetDesc(&desc);
     return ComputeMemoryUsage(&desc);
 }
 
-size_t ComputeGenericMemoryUsage(ResourceType resourceType, ID3D11DeviceChild *resource)
+uint64_t ComputeGenericMemoryUsage(ResourceType resourceType, ID3D11DeviceChild *resource)
 {
     switch (resourceType)
     {
         case ResourceType::Texture2D:
             return ComputeGenericMemoryUsage<ResourceType::Texture2D>(resource);
         case ResourceType::Texture3D:
             return ComputeGenericMemoryUsage<ResourceType::Texture3D>(resource);
         case ResourceType::Buffer:
@@ -198,16 +206,24 @@ HRESULT CreateResource(ID3D11Device *dev
                        const D3D11_SHADER_RESOURCE_VIEW_DESC *desc,
                        ID3D11Resource *resource,
                        ID3D11ShaderResourceView **resourceOut)
 {
     return device->CreateShaderResourceView(resource, desc, resourceOut);
 }
 
 HRESULT CreateResource(ID3D11Device *device,
+                       const D3D11_UNORDERED_ACCESS_VIEW_DESC *desc,
+                       ID3D11Resource *resource,
+                       ID3D11UnorderedAccessView **resourceOut)
+{
+    return device->CreateUnorderedAccessView(resource, desc, resourceOut);
+}
+
+HRESULT CreateResource(ID3D11Device *device,
                        const D3D11_TEXTURE2D_DESC *desc,
                        const D3D11_SUBRESOURCE_DATA *initData,
                        ID3D11Texture2D **texture)
 {
     return device->CreateTexture2D(desc, initData, texture);
 }
 
 HRESULT CreateResource(ID3D11Device *device,
@@ -278,27 +294,27 @@ gl::Error ClearResource(Renderer11 *rend
             else
             {
                 dsvDesc.ViewDimension = D3D11_DSV_DIMENSION_TEXTURE2DMS;
             }
 
             d3d11::DepthStencilView dsv;
             ANGLE_TRY(renderer->allocateResource(dsvDesc, texture, &dsv));
 
-            context->ClearDepthStencilView(dsv.get(), clearFlags, 1.0f, 0);
+            context->ClearDepthStencilView(dsv.get(), clearFlags, kDebugDepthInitValue,
+                                           kDebugStencilInitValue);
         }
     }
     else
     {
         ASSERT((desc->BindFlags & D3D11_BIND_RENDER_TARGET) != 0);
         d3d11::RenderTargetView rtv;
         ANGLE_TRY(renderer->allocateResourceNoDesc(texture, &rtv));
 
-        const FLOAT zero[4] = {0.0f, 0.0f, 0.0f, 0.0f};
-        context->ClearRenderTargetView(rtv.get(), zero);
+        context->ClearRenderTargetView(rtv.get(), kDebugColorInitClearValue);
     }
 
     return gl::NoError();
 }
 
 template <>
 gl::Error ClearResource(Renderer11 *renderer,
                         const D3D11_TEXTURE3D_DESC *desc,
@@ -307,112 +323,109 @@ gl::Error ClearResource(Renderer11 *rend
     ID3D11DeviceContext *context = renderer->getDeviceContext();
 
     ASSERT((desc->BindFlags & D3D11_BIND_DEPTH_STENCIL) == 0);
     ASSERT((desc->BindFlags & D3D11_BIND_RENDER_TARGET) != 0);
 
     d3d11::RenderTargetView rtv;
     ANGLE_TRY(renderer->allocateResourceNoDesc(texture, &rtv));
 
-    const FLOAT zero[4] = {0.0f, 0.0f, 0.0f, 0.0f};
-    context->ClearRenderTargetView(rtv.get(), zero);
+    context->ClearRenderTargetView(rtv.get(), kDebugColorInitClearValue);
     return gl::NoError();
 }
 
 #define ANGLE_RESOURCE_STRINGIFY_OP(NAME, RESTYPE, D3D11TYPE, DESCTYPE, INITDATATYPE) #RESTYPE,
 
 constexpr std::array<const char *, NumResourceTypes> kResourceTypeNames = {
     {ANGLE_RESOURCE_TYPE_OP(Stringify, ANGLE_RESOURCE_STRINGIFY_OP)}};
 static_assert(kResourceTypeNames[NumResourceTypes - 1] != nullptr,
               "All members must be initialized.");
 
 }  // anonymous namespace
 
 // ResourceManager11 Implementation.
 ResourceManager11::ResourceManager11()
-    : mAllocatedResourceCounts({{}}), mAllocatedResourceDeviceMemory({{}})
+    : mInitializeAllocations(false),
+      mAllocatedResourceCounts({{}}),
+      mAllocatedResourceDeviceMemory({{}})
 {
 }
 
 ResourceManager11::~ResourceManager11()
 {
     for (size_t count : mAllocatedResourceCounts)
     {
         ASSERT(count == 0);
     }
 
-    for (size_t memorySize : mAllocatedResourceDeviceMemory)
+    for (uint64_t memorySize : mAllocatedResourceDeviceMemory)
     {
         ASSERT(memorySize == 0);
     }
 }
 
 template <typename T>
 gl::Error ResourceManager11::allocate(Renderer11 *renderer,
                                       const GetDescFromD3D11<T> *desc,
                                       GetInitDataFromD3D11<T> *initData,
                                       Resource11<T> *resourceOut)
 {
     ID3D11Device *device = renderer->getDevice();
     T *resource          = nullptr;
 
     GetInitDataFromD3D11<T> *shadowInitData = initData;
-    if (!shadowInitData && renderer->isRobustResourceInitEnabled())
+    if (!shadowInitData && mInitializeAllocations)
     {
         shadowInitData = createInitDataIfNeeded<T>(desc);
     }
 
-    // In Windows 32-bit, it's possible that mAllocatedResourceDeviceMemory
-    // exceeds UINT32_MAX leading to a delayed crash when we release
-    // the context, we should prevent that happen
-    const auto resourceSize = ComputeMemoryUsage(desc);
-    if (mAllocatedResourceDeviceMemory[ResourceTypeIndex<T>()] >
-        mAllocatedResourceDeviceMemory[ResourceTypeIndex<T>()] +
-        resourceSize) {
-        return gl::OutOfMemory() << "Error: Internal Memory Counter overflow";
-    }
-
     HRESULT hr = CreateResource(device, desc, shadowInitData, &resource);
     if (FAILED(hr))
     {
         ASSERT(!resource);
         if (d3d11::isDeviceLostError(hr))
         {
             renderer->notifyDeviceLost();
         }
         return gl::OutOfMemory() << "Error allocating "
                                  << std::string(kResourceTypeNames[ResourceTypeIndex<T>()]) << ". "
                                  << gl::FmtHR(hr);
     }
 
-    if (!shadowInitData && renderer->isRobustResourceInitEnabled())
+    if (!shadowInitData && mInitializeAllocations)
     {
         ANGLE_TRY(ClearResource(renderer, desc, resource));
     }
 
     ASSERT(resource);
-    incrResource(GetResourceTypeFromD3D11<T>(), resourceSize);
+    incrResource(GetResourceTypeFromD3D11<T>(), ComputeMemoryUsage(desc));
     *resourceOut = std::move(Resource11<T>(resource, this));
     return gl::NoError();
 }
 
-void ResourceManager11::incrResource(ResourceType resourceType, size_t memorySize)
+void ResourceManager11::incrResource(ResourceType resourceType, uint64_t memorySize)
 {
-    mAllocatedResourceCounts[ResourceTypeIndex(resourceType)]++;
-    ASSERT(mAllocatedResourceDeviceMemory[ResourceTypeIndex(resourceType)] + memorySize >=
-           mAllocatedResourceDeviceMemory[ResourceTypeIndex(resourceType)]);
-    mAllocatedResourceDeviceMemory[ResourceTypeIndex(resourceType)] += memorySize;
+    size_t typeIndex = ResourceTypeIndex(resourceType);
+
+    mAllocatedResourceCounts[typeIndex]++;
+    mAllocatedResourceDeviceMemory[typeIndex] += memorySize;
+
+    // This checks for integer overflow.
+    ASSERT(mAllocatedResourceCounts[typeIndex] > 0);
+    ASSERT(mAllocatedResourceDeviceMemory[typeIndex] >= memorySize);
 }
 
-void ResourceManager11::decrResource(ResourceType resourceType, size_t memorySize)
+void ResourceManager11::decrResource(ResourceType resourceType, uint64_t memorySize)
 {
-    ASSERT(mAllocatedResourceCounts[ResourceTypeIndex(resourceType)] > 0);
-    mAllocatedResourceCounts[ResourceTypeIndex(resourceType)]--;
-    ASSERT(mAllocatedResourceDeviceMemory[ResourceTypeIndex(resourceType)] >= memorySize);
-    mAllocatedResourceDeviceMemory[ResourceTypeIndex(resourceType)] -= memorySize;
+    size_t typeIndex = ResourceTypeIndex(resourceType);
+
+    ASSERT(mAllocatedResourceCounts[typeIndex] > 0);
+    mAllocatedResourceCounts[typeIndex]--;
+    ASSERT(mAllocatedResourceDeviceMemory[typeIndex] >= memorySize);
+    mAllocatedResourceDeviceMemory[typeIndex] -= memorySize;
 }
 
 void ResourceManager11::onReleaseGeneric(ResourceType resourceType, ID3D11DeviceChild *resource)
 {
     ASSERT(resource);
     decrResource(resourceType, ComputeGenericMemoryUsage(resourceType, resource));
 }
 
@@ -423,21 +436,21 @@ const D3D11_SUBRESOURCE_DATA *ResourceMa
     ASSERT(desc);
 
     if ((desc->BindFlags & (D3D11_BIND_DEPTH_STENCIL | D3D11_BIND_RENDER_TARGET)) != 0)
     {
         // This will be done using ClearView methods.
         return nullptr;
     }
 
-    size_t requiredSize = ComputeMemoryUsage(desc);
+    size_t requiredSize = static_cast<size_t>(ComputeMemoryUsage(desc));
     if (mZeroMemory.size() < requiredSize)
     {
         mZeroMemory.resize(requiredSize);
-        mZeroMemory.fill(0);
+        mZeroMemory.fill(kDebugInitTextureDataValue);
     }
 
     const auto &formatSizeInfo = d3d11::GetDXGIFormatSizeInfo(desc->Format);
 
     UINT subresourceCount = desc->MipLevels * desc->ArraySize;
     if (mShadowInitData.size() < subresourceCount)
     {
         mShadowInitData.resize(subresourceCount);
@@ -469,21 +482,21 @@ const D3D11_SUBRESOURCE_DATA *ResourceMa
     ASSERT(desc);
 
     if ((desc->BindFlags & D3D11_BIND_RENDER_TARGET) != 0)
     {
         // This will be done using ClearView methods.
         return nullptr;
     }
 
-    size_t requiredSize = ComputeMemoryUsage(desc);
+    size_t requiredSize = static_cast<size_t>(ComputeMemoryUsage(desc));
     if (mZeroMemory.size() < requiredSize)
     {
         mZeroMemory.resize(requiredSize);
-        mZeroMemory.fill(0);
+        mZeroMemory.fill(kDebugInitTextureDataValue);
     }
 
     const auto &formatSizeInfo = d3d11::GetDXGIFormatSizeInfo(desc->Format);
 
     UINT subresourceCount = desc->MipLevels;
     if (mShadowInitData.size() < subresourceCount)
     {
         mShadowInitData.resize(subresourceCount);
@@ -507,16 +520,21 @@ const D3D11_SUBRESOURCE_DATA *ResourceMa
 
 template <typename T>
 GetInitDataFromD3D11<T> *ResourceManager11::createInitDataIfNeeded(const GetDescFromD3D11<T> *desc)
 {
     // No-op.
     return nullptr;
 }
 
+void ResourceManager11::setAllocationsInitialized(bool initialize)
+{
+    mInitializeAllocations = initialize;
+}
+
 #define ANGLE_INSTANTIATE_OP(NAME, RESTYPE, D3D11TYPE, DESCTYPE, INITDATATYPE)  \
     \
 template \
 gl::Error                                                                       \
     ResourceManager11::allocate(Renderer11 *, const DESCTYPE *, INITDATATYPE *, \
                                 Resource11<D3D11TYPE> *);
 
 ANGLE_RESOURCE_TYPE_OP(Instantitate, ANGLE_INSTANTIATE_OP)
--- a/gfx/angle/src/libANGLE/renderer/d3d/d3d11/ResourceManager11.h
+++ b/gfx/angle/src/libANGLE/renderer/d3d/d3d11/ResourceManager11.h
@@ -37,36 +37,38 @@ class ResourceManager11;
 template <typename T>
 class SharedResource11;
 class TextureHelper11;
 
 using InputElementArray = WrappedArray<D3D11_INPUT_ELEMENT_DESC>;
 using ShaderData        = WrappedArray<uint8_t>;
 
 // Format: ResourceType, D3D11 type, DESC type, init data type.
-#define ANGLE_RESOURCE_TYPE_OP(NAME, OP)                                                     \
-    OP(NAME, BlendState, ID3D11BlendState, D3D11_BLEND_DESC, void)                           \
-    OP(NAME, Buffer, ID3D11Buffer, D3D11_BUFFER_DESC, const D3D11_SUBRESOURCE_DATA)          \
-    OP(NAME, ComputeShader, ID3D11ComputeShader, ShaderData, void)                           \
-    OP(NAME, DepthStencilState, ID3D11DepthStencilState, D3D11_DEPTH_STENCIL_DESC, void)     \
-    OP(NAME, DepthStencilView, ID3D11DepthStencilView, D3D11_DEPTH_STENCIL_VIEW_DESC,        \
-       ID3D11Resource)                                                                       \
-    OP(NAME, GeometryShader, ID3D11GeometryShader, ShaderData,                               \
-       const std::vector<D3D11_SO_DECLARATION_ENTRY>)                                        \
-    OP(NAME, InputLayout, ID3D11InputLayout, InputElementArray, const ShaderData)            \
-    OP(NAME, PixelShader, ID3D11PixelShader, ShaderData, void)                               \
-    OP(NAME, Query, ID3D11Query, D3D11_QUERY_DESC, void)                                     \
-    OP(NAME, RasterizerState, ID3D11RasterizerState, D3D11_RASTERIZER_DESC, void)            \
-    OP(NAME, RenderTargetView, ID3D11RenderTargetView, D3D11_RENDER_TARGET_VIEW_DESC,        \
-       ID3D11Resource)                                                                       \
-    OP(NAME, SamplerState, ID3D11SamplerState, D3D11_SAMPLER_DESC, void)                     \
-    OP(NAME, ShaderResourceView, ID3D11ShaderResourceView, D3D11_SHADER_RESOURCE_VIEW_DESC,  \
-       ID3D11Resource)                                                                       \
-    OP(NAME, Texture2D, ID3D11Texture2D, D3D11_TEXTURE2D_DESC, const D3D11_SUBRESOURCE_DATA) \
-    OP(NAME, Texture3D, ID3D11Texture3D, D3D11_TEXTURE3D_DESC, const D3D11_SUBRESOURCE_DATA) \
+#define ANGLE_RESOURCE_TYPE_OP(NAME, OP)                                                       \
+    OP(NAME, BlendState, ID3D11BlendState, D3D11_BLEND_DESC, void)                             \
+    OP(NAME, Buffer, ID3D11Buffer, D3D11_BUFFER_DESC, const D3D11_SUBRESOURCE_DATA)            \
+    OP(NAME, ComputeShader, ID3D11ComputeShader, ShaderData, void)                             \
+    OP(NAME, DepthStencilState, ID3D11DepthStencilState, D3D11_DEPTH_STENCIL_DESC, void)       \
+    OP(NAME, DepthStencilView, ID3D11DepthStencilView, D3D11_DEPTH_STENCIL_VIEW_DESC,          \
+       ID3D11Resource)                                                                         \
+    OP(NAME, GeometryShader, ID3D11GeometryShader, ShaderData,                                 \
+       const std::vector<D3D11_SO_DECLARATION_ENTRY>)                                          \
+    OP(NAME, InputLayout, ID3D11InputLayout, InputElementArray, const ShaderData)              \
+    OP(NAME, PixelShader, ID3D11PixelShader, ShaderData, void)                                 \
+    OP(NAME, Query, ID3D11Query, D3D11_QUERY_DESC, void)                                       \
+    OP(NAME, RasterizerState, ID3D11RasterizerState, D3D11_RASTERIZER_DESC, void)              \
+    OP(NAME, RenderTargetView, ID3D11RenderTargetView, D3D11_RENDER_TARGET_VIEW_DESC,          \
+       ID3D11Resource)                                                                         \
+    OP(NAME, SamplerState, ID3D11SamplerState, D3D11_SAMPLER_DESC, void)                       \
+    OP(NAME, ShaderResourceView, ID3D11ShaderResourceView, D3D11_SHADER_RESOURCE_VIEW_DESC,    \
+       ID3D11Resource)                                                                         \
+    OP(NAME, UnorderedAccessView, ID3D11UnorderedAccessView, D3D11_UNORDERED_ACCESS_VIEW_DESC, \
+       ID3D11Resource)                                                                         \
+    OP(NAME, Texture2D, ID3D11Texture2D, D3D11_TEXTURE2D_DESC, const D3D11_SUBRESOURCE_DATA)   \
+    OP(NAME, Texture3D, ID3D11Texture3D, D3D11_TEXTURE3D_DESC, const D3D11_SUBRESOURCE_DATA)   \
     OP(NAME, VertexShader, ID3D11VertexShader, ShaderData, void)
 
 #define ANGLE_RESOURCE_TYPE_LIST(NAME, RESTYPE, D3D11TYPE, DESCTYPE, INITDATATYPE) RESTYPE,
 
 enum class ResourceType
 {
     ANGLE_RESOURCE_TYPE_OP(List, ANGLE_RESOURCE_TYPE_LIST) Last
 };
@@ -312,25 +314,29 @@ class ResourceManager11 final : angle::N
     template <typename T>
     void onRelease(T *resource)
     {
         onReleaseGeneric(GetResourceTypeFromD3D11<T>(), resource);
     }
 
     void onReleaseGeneric(ResourceType resourceType, ID3D11DeviceChild *resource);
 
+    void setAllocationsInitialized(bool initialize);
+
   private:
-    void incrResource(ResourceType resourceType, size_t memorySize);
-    void decrResource(ResourceType resourceType, size_t memorySize);
+    void incrResource(ResourceType resourceType, uint64_t memorySize);
+    void decrResource(ResourceType resourceType, uint64_t memorySize);
 
     template <typename T>
     GetInitDataFromD3D11<T> *createInitDataIfNeeded(const GetDescFromD3D11<T> *desc);
 
+    bool mInitializeAllocations;
+
     std::array<size_t, NumResourceTypes> mAllocatedResourceCounts;
-    std::array<size_t, NumResourceTypes> mAllocatedResourceDeviceMemory;
+    std::array<uint64_t, NumResourceTypes> mAllocatedResourceDeviceMemory;
     angle::MemoryBuffer mZeroMemory;
 
     std::vector<D3D11_SUBRESOURCE_DATA> mShadowInitData;
 };
 
 template <typename ResourceT>
 TypedData<ResourceT>::~TypedData()
 {
@@ -348,15 +354,16 @@ TypedData<ResourceT>::~TypedData()
 #define ANGLE_RESOURCE_TYPE_CLASS(NAME, RESTYPE, D3D11TYPE, DESCTYPE, INITDATATYPE) \
     using RESTYPE = Resource11<D3D11TYPE>;
 
 namespace d3d11
 {
 ANGLE_RESOURCE_TYPE_OP(ClassList, ANGLE_RESOURCE_TYPE_CLASS)
 
 using SharedSRV = SharedResource11<ID3D11ShaderResourceView>;
+using SharedUAV = SharedResource11<ID3D11UnorderedAccessView>;
 }  // namespace d3d11
 
 #undef ANGLE_RESOURCE_TYPE_CLASS
 
 }  // namespace rx
 
 #endif  // LIBANGLE_RENDERER_D3D_D3D11_RESOURCEFACTORY11_H_
--- a/gfx/angle/src/libANGLE/renderer/d3d/d3d11/ShaderExecutable11.h
+++ b/gfx/angle/src/libANGLE/renderer/d3d/d3d11/ShaderExecutable11.h
@@ -24,17 +24,17 @@ class ShaderExecutable11 : public Shader
     ShaderExecutable11(const void *function, size_t length, d3d11::PixelShader &&executable);
     ShaderExecutable11(const void *function,
                        size_t length,
                        d3d11::VertexShader &&executable,
                        d3d11::GeometryShader &&streamOut);
     ShaderExecutable11(const void *function, size_t length, d3d11::GeometryShader &&executable);
     ShaderExecutable11(const void *function, size_t length, d3d11::ComputeShader &&executable);
 
-    virtual ~ShaderExecutable11();
+    ~ShaderExecutable11() override;
 
     const d3d11::PixelShader &getPixelShader() const;
     const d3d11::VertexShader &getVertexShader() const;
     const d3d11::GeometryShader &getGeometryShader() const;
     const d3d11::GeometryShader &getStreamOutShader() const;
     const d3d11::ComputeShader &getComputeShader() const;
 
   private:
@@ -44,17 +44,17 @@ class ShaderExecutable11 : public Shader
     d3d11::GeometryShader mStreamOutExecutable;
     d3d11::ComputeShader mComputeExecutable;
 };
 
 class UniformStorage11 : public UniformStorageD3D
 {
   public:
     UniformStorage11(size_t initialSize);
-    virtual ~UniformStorage11();
+    ~UniformStorage11() override;
 
     gl::Error getConstantBuffer(Renderer11 *renderer, const d3d11::Buffer **bufferOut);
 
   private:
     d3d11::Buffer mConstantBuffer;
 };
 
 }  // namespace rx
--- a/gfx/angle/src/libANGLE/renderer/d3d/d3d11/StateManager11.cpp
+++ b/gfx/angle/src/libANGLE/renderer/d3d/d3d11/StateManager11.cpp
@@ -174,83 +174,113 @@ void UpdateUniformBuffer(ID3D11DeviceCon
                          const d3d11::Buffer *buffer)
 {
     deviceContext->UpdateSubresource(buffer->get(), 0, nullptr, storage->getDataPointer(0, 0), 0,
                                      0);
 }
 
 }  // anonymous namespace
 
-// StateManager11::SRVCache Implementation.
-
-void StateManager11::SRVCache::update(size_t resourceIndex, ID3D11ShaderResourceView *srv)
+// StateManager11::ViewCache Implementation.
+template <typename ViewType, typename DescType>
+StateManager11::ViewCache<ViewType, DescType>::ViewCache() : mHighestUsedView(0)
+{
+}
+
+template <typename ViewType, typename DescType>
+StateManager11::ViewCache<ViewType, DescType>::~ViewCache()
 {
-    ASSERT(resourceIndex < mCurrentSRVs.size());
-    SRVRecord *record = &mCurrentSRVs[resourceIndex];
-
-    record->srv = reinterpret_cast<uintptr_t>(srv);
-    if (srv)
+}
+
+template <typename ViewType, typename DescType>
+void StateManager11::ViewCache<ViewType, DescType>::update(size_t resourceIndex, ViewType *view)
+{
+    ASSERT(resourceIndex < mCurrentViews.size());
+    ViewRecord<DescType> *record = &mCurrentViews[resourceIndex];
+
+    record->view = reinterpret_cast<uintptr_t>(view);
+    if (view)
     {
-        record->resource = reinterpret_cast<uintptr_t>(GetViewResource(srv));
-        srv->GetDesc(&record->desc);
-        mHighestUsedSRV = std::max(resourceIndex + 1, mHighestUsedSRV);
+        record->resource = reinterpret_cast<uintptr_t>(GetViewResource(view));
+        view->GetDesc(&record->desc);
+        mHighestUsedView = std::max(resourceIndex + 1, mHighestUsedView);
     }
     else
     {
         record->resource = 0;
 
-        if (resourceIndex + 1 == mHighestUsedSRV)
+        if (resourceIndex + 1 == mHighestUsedView)
         {
             do
             {
-                --mHighestUsedSRV;
-            } while (mHighestUsedSRV > 0 && mCurrentSRVs[mHighestUsedSRV].srv == 0);
+                --mHighestUsedView;
+            } while (mHighestUsedView > 0 && mCurrentViews[mHighestUsedView].view == 0);
         }
     }
 }
 
-void StateManager11::SRVCache::clear()
+template <typename ViewType, typename DescType>
+void StateManager11::ViewCache<ViewType, DescType>::clear()
 {
-    if (mCurrentSRVs.empty())
+    if (mCurrentViews.empty())
     {
         return;
     }
 
-    memset(&mCurrentSRVs[0], 0, sizeof(SRVRecord) * mCurrentSRVs.size());
-    mHighestUsedSRV = 0;
+    memset(&mCurrentViews[0], 0, sizeof(ViewRecord<DescType>) * mCurrentViews.size());
+    mHighestUsedView = 0;
+}
+
+StateManager11::SRVCache *StateManager11::getSRVCache(gl::ShaderType shaderType)
+{
+    switch (shaderType)
+    {
+        case gl::SHADER_VERTEX:
+            return &mCurVertexSRVs;
+        case gl::SHADER_FRAGMENT:
+            return &mCurPixelSRVs;
+        case gl::SHADER_COMPUTE:
+            return &mCurComputeSRVs;
+        default:
+            UNREACHABLE();
+            return &mCurVertexSRVs;
+    }
 }
 
 // ShaderConstants11 implementation
-
 ShaderConstants11::ShaderConstants11()
     : mVertexDirty(true),
       mPixelDirty(true),
       mComputeDirty(true),
       mSamplerMetadataVSDirty(true),
       mSamplerMetadataPSDirty(true),
       mSamplerMetadataCSDirty(true)
 {
 }
 
+ShaderConstants11::~ShaderConstants11()
+{
+}
+
 void ShaderConstants11::init(const gl::Caps &caps)
 {
     mSamplerMetadataVS.resize(caps.maxVertexTextureImageUnits);
     mSamplerMetadataPS.resize(caps.maxTextureImageUnits);
     mSamplerMetadataCS.resize(caps.maxComputeTextureImageUnits);
 }
 
-size_t ShaderConstants11::getRequiredBufferSize(gl::SamplerType samplerType) const
+size_t ShaderConstants11::getRequiredBufferSize(gl::ShaderType shaderType) const
 {
-    switch (samplerType)
+    switch (shaderType)
     {
-        case gl::SAMPLER_VERTEX:
+        case gl::SHADER_VERTEX:
             return sizeof(Vertex) + mSamplerMetadataVS.size() * sizeof(SamplerMetadata);
-        case gl::SAMPLER_PIXEL:
+        case gl::SHADER_FRAGMENT:
             return sizeof(Pixel) + mSamplerMetadataPS.size() * sizeof(SamplerMetadata);
-        case gl::SAMPLER_COMPUTE:
+        case gl::SHADER_COMPUTE:
             return sizeof(Compute) + mSamplerMetadataCS.size() * sizeof(SamplerMetadata);
         default:
             UNREACHABLE();
             return 0;
     }
 }
 
 void ShaderConstants11::markDirty()
@@ -415,75 +445,75 @@ void ShaderConstants11::onViewportChange
     mPixel.viewScale[1] = presentPathFast ? 1.0f : -1.0f;
     // Updates to the multiviewWriteToViewportIndex member are to be handled whenever the draw
     // framebuffer's layout is changed.
 
     mVertex.viewScale[0] = mPixel.viewScale[0];
     mVertex.viewScale[1] = mPixel.viewScale[1];
 }
 
-void ShaderConstants11::onSamplerChange(gl::SamplerType samplerType,
+void ShaderConstants11::onSamplerChange(gl::ShaderType shaderType,
                                         unsigned int samplerIndex,
                                         const gl::Texture &texture)
 {
-    switch (samplerType)
+    switch (shaderType)
     {
-        case gl::SAMPLER_VERTEX:
+        case gl::SHADER_VERTEX:
             if (updateSamplerMetadata(&mSamplerMetadataVS[samplerIndex], texture))
             {
                 mSamplerMetadataVSDirty = true;
             }
             break;
-        case gl::SAMPLER_PIXEL:
+        case gl::SHADER_FRAGMENT:
             if (updateSamplerMetadata(&mSamplerMetadataPS[samplerIndex], texture))
             {
                 mSamplerMetadataPSDirty = true;
             }
             break;
-        case gl::SAMPLER_COMPUTE:
+        case gl::SHADER_COMPUTE:
             if (updateSamplerMetadata(&mSamplerMetadataCS[samplerIndex], texture))
             {
                 mSamplerMetadataCSDirty = true;
             }
             break;
         default:
             UNREACHABLE();
             break;
     }
 }
 
-gl::Error ShaderConstants11::updateBuffer(ID3D11DeviceContext *deviceContext,
-                                          gl::SamplerType samplerType,
+gl::Error ShaderConstants11::updateBuffer(Renderer11 *renderer,
+                                          gl::ShaderType shaderType,
                                           const ProgramD3D &programD3D,
                                           const d3d11::Buffer &driverConstantBuffer)
 {
     bool dirty                 = false;
     size_t dataSize            = 0;
     const uint8_t *data        = nullptr;
     const uint8_t *samplerData = nullptr;
 
-    switch (samplerType)
+    switch (shaderType)
     {
-        case gl::SAMPLER_VERTEX:
+        case gl::SHADER_VERTEX:
             dirty                   = mVertexDirty || mSamplerMetadataVSDirty;
             dataSize                = sizeof(Vertex);
             data                    = reinterpret_cast<const uint8_t *>(&mVertex);
             samplerData             = reinterpret_cast<const uint8_t *>(mSamplerMetadataVS.data());
             mVertexDirty            = false;
             mSamplerMetadataVSDirty = false;
             break;
-        case gl::SAMPLER_PIXEL:
+        case gl::SHADER_FRAGMENT:
             dirty                   = mPixelDirty || mSamplerMetadataPSDirty;
             dataSize                = sizeof(Pixel);
             data                    = reinterpret_cast<const uint8_t *>(&mPixel);
             samplerData             = reinterpret_cast<const uint8_t *>(mSamplerMetadataPS.data());
             mPixelDirty             = false;
             mSamplerMetadataPSDirty = false;
             break;
-        case gl::SAMPLER_COMPUTE:
+        case gl::SHADER_COMPUTE:
             dirty                   = mComputeDirty || mSamplerMetadataCSDirty;
             dataSize                = sizeof(Compute);
             data                    = reinterpret_cast<const uint8_t *>(&mCompute);
             samplerData             = reinterpret_cast<const uint8_t *>(mSamplerMetadataCS.data());
             mComputeDirty           = false;
             mSamplerMetadataCSDirty = false;
             break;
         default:
@@ -495,30 +525,25 @@ gl::Error ShaderConstants11::updateBuffe
 
     if (!dirty)
     {
         return gl::NoError();
     }
 
     // Previous buffer contents are discarded, so we need to refresh the whole buffer.
     D3D11_MAPPED_SUBRESOURCE mapping = {0};
-    HRESULT result =
-        deviceContext->Map(driverConstantBuffer.get(), 0, D3D11_MAP_WRITE_DISCARD, 0, &mapping);
-
-    if (FAILED(result))
-    {
-        return gl::OutOfMemory() << "Internal error mapping constant buffer: " << gl::FmtHR(result);
-    }
-
-    size_t samplerDataBytes = sizeof(SamplerMetadata) * programD3D.getUsedSamplerRange(samplerType);
+    ANGLE_TRY(
+        renderer->mapResource(driverConstantBuffer.get(), 0, D3D11_MAP_WRITE_DISCARD, 0, &mapping));
+
+    size_t samplerDataBytes = sizeof(SamplerMetadata) * programD3D.getUsedSamplerRange(shaderType);
 
     memcpy(mapping.pData, data, dataSize);
     memcpy(reinterpret_cast<uint8_t *>(mapping.pData) + dataSize, samplerData, samplerDataBytes);
 
-    deviceContext->Unmap(driverConstantBuffer.get(), 0);
+    renderer->getDeviceContext()->Unmap(driverConstantBuffer.get(), 0);
 
     return gl::NoError();
 }
 
 static const GLenum QueryTypes[] = {GL_ANY_SAMPLES_PASSED, GL_ANY_SAMPLES_PASSED_CONSERVATIVE,
                                     GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN, GL_TIME_ELAPSED_EXT,
                                     GL_COMMANDS_COMPLETED_CHROMIUM};
 
@@ -545,19 +570,19 @@ StateManager11::StateManager11(Renderer1
       mInputLayoutIsDirty(false),
       mVertexAttribsNeedTranslation(false),
       mDirtyVertexBufferRange(gl::MAX_VERTEX_ATTRIBS, 0),
       mCurrentPrimitiveTopology(D3D_PRIMITIVE_TOPOLOGY_UNDEFINED),
       mDirtySwizzles(false),
       mAppliedIB(nullptr),
       mAppliedIBFormat(DXGI_FORMAT_UNKNOWN),
       mAppliedIBOffset(0),
-      mAppliedIBChanged(false),
+      mIndexBufferIsDirty(false),
       mVertexDataManager(renderer),
-      mIndexDataManager(renderer, RENDERER_D3D11),
+      mIndexDataManager(renderer),
       mIsMultiviewEnabled(false),
       mEmptySerial(mRenderer->generateSerial()),
       mIsTransformFeedbackCurrentlyActiveUnpaused(false)
 {
     mCurBlendState.blend                 = false;
     mCurBlendState.sourceBlendRGB        = GL_ONE;
     mCurBlendState.destBlendRGB          = GL_ZERO;
     mCurBlendState.sourceBlendAlpha      = GL_ONE;
@@ -584,17 +609,17 @@ StateManager11::StateManager11(Renderer1
     mCurDepthStencilState.stencilBackMask          = static_cast<GLuint>(-1);
     mCurDepthStencilState.stencilBackFail          = GL_KEEP;
     mCurDepthStencilState.stencilBackPassDepthFail = GL_KEEP;
     mCurDepthStencilState.stencilBackPassDepthPass = GL_KEEP;
     mCurDepthStencilState.stencilBackWritemask     = static_cast<GLuint>(-1);
 
     mCurRasterState.rasterizerDiscard   = false;
     mCurRasterState.cullFace            = false;
-    mCurRasterState.cullMode            = GL_BACK;
+    mCurRasterState.cullMode            = gl::CullFaceMode::Back;
     mCurRasterState.frontFace           = GL_CCW;
     mCurRasterState.polygonOffsetFill   = false;
     mCurRasterState.polygonOffsetFactor = 0.0f;
     mCurRasterState.polygonOffsetUnits  = 0.0f;
     mCurRasterState.pointDrawMode       = false;
     mCurRasterState.multiSample         = false;
 
     // Start with all internal dirty bits set.
@@ -608,39 +633,63 @@ StateManager11::StateManager11(Renderer1
     mCurrentVertexOffsets.fill(std::numeric_limits<UINT>::max());
 }
 
 StateManager11::~StateManager11()
 {
 }
 
 template <typename SRVType>
-void StateManager11::setShaderResourceInternal(gl::SamplerType shaderType,
+void StateManager11::setShaderResourceInternal(gl::ShaderType shaderType,
                                                UINT resourceSlot,
                                                const SRVType *srv)
 {
-    auto &currentSRVs = (shaderType == gl::SAMPLER_VERTEX ? mCurVertexSRVs : mCurPixelSRVs);
-
-    ASSERT(static_cast<size_t>(resourceSlot) < currentSRVs.size());
-    const SRVRecord &record = currentSRVs[resourceSlot];
-
-    if (record.srv != reinterpret_cast<uintptr_t>(srv))
+    auto *currentSRVs = getSRVCache(shaderType);
+    ASSERT(static_cast<size_t>(resourceSlot) < currentSRVs->size());
+    const ViewRecord<D3D11_SHADER_RESOURCE_VIEW_DESC> &record = (*currentSRVs)[resourceSlot];
+
+    if (record.view != reinterpret_cast<uintptr_t>(srv))
     {
-        auto deviceContext               = mRenderer->getDeviceContext();
+        ID3D11DeviceContext *deviceContext = mRenderer->getDeviceContext();
         ID3D11ShaderResourceView *srvPtr = srv ? srv->get() : nullptr;
-        if (shaderType == gl::SAMPLER_VERTEX)
+        switch (shaderType)
         {
-            deviceContext->VSSetShaderResources(resourceSlot, 1, &srvPtr);
+            case gl::SHADER_VERTEX:
+                deviceContext->VSSetShaderResources(resourceSlot, 1, &srvPtr);
+                break;
+            case gl::SHADER_FRAGMENT:
+                deviceContext->PSSetShaderResources(resourceSlot, 1, &srvPtr);
+                break;
+            case gl::SHADER_COMPUTE:
+                deviceContext->CSSetShaderResources(resourceSlot, 1, &srvPtr);
+                break;
+            default:
+                UNREACHABLE();
         }
-        else
-        {
-            deviceContext->PSSetShaderResources(resourceSlot, 1, &srvPtr);
-        }
-
-        currentSRVs.update(resourceSlot, srvPtr);
+
+        currentSRVs->update(resourceSlot, srvPtr);
+    }
+}
+
+template <typename UAVType>
+void StateManager11::setUnorderedAccessViewInternal(gl::ShaderType shaderType,
+                                                    UINT resourceSlot,
+                                                    const UAVType *uav)
+{
+    ASSERT(shaderType == gl::SHADER_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);
+
+        mCurComputeUAVs.update(resourceSlot, uavPtr);
     }
 }
 
 void StateManager11::updateStencilSizeIfChanged(bool depthStencilInitialized,
                                                 unsigned int stencilSize)
 {
     if (!depthStencilInitialized || stencilSize != mCurStencilSize)
     {
@@ -685,20 +734,20 @@ 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::SAMPLER_COMPUTE));
+    ANGLE_TRY(generateSwizzlesForShader(context, gl::SHADER_COMPUTE));
 
     // TODO(jmadill): More complete implementation.
-    ANGLE_TRY(syncTextures(context));
+    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)
 {
@@ -936,16 +985,21 @@ 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;
+                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_PROGRAM_EXECUTABLE:
@@ -965,26 +1019,26 @@ void StateManager11::syncState(const gl:
                     const gl::Program *program = state.getProgram();
                     int numViews               = 1;
                     if (program != nullptr && program->usesMultiview())
                     {
                         numViews = program->getNumViews();
                     }
                     vao11->markAllAttributeDivisorsForAdjustment(numViews);
                 }
+                break;
             }
-            break;
-            default:
-                if (dirtyBit >= gl::State::DIRTY_BIT_CURRENT_VALUE_0 &&
-                    dirtyBit < gl::State::DIRTY_BIT_CURRENT_VALUE_MAX)
+            case gl::State::DIRTY_BIT_CURRENT_VALUES:
+            {
+                for (auto attribIndex : state.getAndResetDirtyCurrentValues())
                 {
-                    size_t attribIndex =
-                        static_cast<size_t>(dirtyBit - gl::State::DIRTY_BIT_CURRENT_VALUE_0);
                     invalidateCurrentValueAttrib(attribIndex);
                 }
+            }
+            default:
                 break;
         }
     }
 
     // TODO(jmadill): Input layout and vertex buffer state.
 }
 
 void StateManager11::handleMultiviewDrawFramebufferChange(const gl::Context *context)
@@ -1450,16 +1504,21 @@ void StateManager11::setRenderTargets(ID
 {
     bool anyDirty = false;
 
     for (UINT rtvIndex = 0; rtvIndex < numRTVs; ++rtvIndex)
     {
         anyDirty = anyDirty || unsetConflictingView(rtvs[rtvIndex]);
     }
 
+    if (dsv)
+    {
+        anyDirty = anyDirty || unsetConflictingView(dsv);
+    }
+
     if (anyDirty)
     {
         mInternalDirtyBits.set(DIRTY_BIT_TEXTURE_AND_SAMPLER_STATE);
     }
 
     mRenderer->getDeviceContext()->OMSetRenderTargets(numRTVs, (numRTVs > 0) ? rtvs : nullptr, dsv);
     mInternalDirtyBits.set(DIRTY_BIT_RENDER_TARGET);
 }
@@ -1498,79 +1557,112 @@ gl::Error StateManager11::onMakeCurrent(
             ANGLE_TRY(query11->resume());
             mCurrentQueries.insert(query11);
         }
     }
 
     return gl::NoError();
 }
 
-gl::Error StateManager11::clearTextures(gl::SamplerType samplerType,
-                                        size_t rangeStart,
-                                        size_t rangeEnd)
+gl::Error StateManager11::clearSRVs(gl::ShaderType shaderType, size_t rangeStart, size_t rangeEnd)
 {
     if (rangeStart == rangeEnd)
     {
         return gl::NoError();
     }
 
-    auto &currentSRVs = (samplerType == gl::SAMPLER_VERTEX ? mCurVertexSRVs : mCurPixelSRVs);
-
-    gl::Range<size_t> clearRange(rangeStart, std::min(rangeEnd, currentSRVs.highestUsed()));
+    auto *currentSRVs = getSRVCache(shaderType);
+    gl::Range<size_t> clearRange(rangeStart, std::min(rangeEnd, currentSRVs->highestUsed()));
+    if (clearRange.empty())
+    {
+        return gl::NoError();
+    }
+
+    ID3D11DeviceContext *deviceContext = mRenderer->getDeviceContext();
+    switch (shaderType)
+    {
+        case gl::SHADER_VERTEX:
+            deviceContext->VSSetShaderResources(static_cast<unsigned int>(clearRange.low()),
+                                                static_cast<unsigned int>(clearRange.length()),
+                                                &mNullSRVs[0]);
+            break;
+        case gl::SHADER_FRAGMENT:
+            deviceContext->PSSetShaderResources(static_cast<unsigned int>(clearRange.low()),
+                                                static_cast<unsigned int>(clearRange.length()),
+                                                &mNullSRVs[0]);
+            break;
+        case gl::SHADER_COMPUTE:
+            deviceContext->CSSetShaderResources(static_cast<unsigned int>(clearRange.low()),
+                                                static_cast<unsigned int>(clearRange.length()),
+                                                &mNullSRVs[0]);
+            break;
+        default:
+            UNREACHABLE();
+            break;
+    }
+
+    for (size_t samplerIndex : clearRange)
+    {
+        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);
+    if (rangeStart == rangeEnd)
+    {
+        return gl::NoError();
+    }
+
+    gl::Range<size_t> clearRange(rangeStart, std::min(rangeEnd, mCurComputeUAVs.highestUsed()));
     if (clearRange.empty())
     {
         return gl::NoError();
     }
 
     auto deviceContext = mRenderer->getDeviceContext();
-    if (samplerType == gl::SAMPLER_VERTEX)
-    {
-        deviceContext->VSSetShaderResources(static_cast<unsigned int>(clearRange.low()),
-                                            static_cast<unsigned int>(clearRange.length()),
-                                            &mNullSRVs[0]);
-    }
-    else
+    deviceContext->CSSetUnorderedAccessViews(static_cast<unsigned int>(clearRange.low()),
+                                             static_cast<unsigned int>(clearRange.length()),
+                                             &mNullUAVs[0], nullptr);
+
+    for (size_t index : clearRange)
     {
-        deviceContext->PSSetShaderResources(static_cast<unsigned int>(clearRange.low()),
-                                            static_cast<unsigned int>(clearRange.length()),
-                                            &mNullSRVs[0]);
-    }
-
-    for (size_t samplerIndex : clearRange)
-    {
-        currentSRVs.update(samplerIndex, nullptr);
+        mCurComputeUAVs.update(index, nullptr);
     }
 
     return gl::NoError();
 }
 
 bool StateManager11::unsetConflictingView(ID3D11View *view)
 {
     uintptr_t resource = reinterpret_cast<uintptr_t>(GetViewResource(view));
-    return unsetConflictingSRVs(gl::SAMPLER_VERTEX, resource, nullptr) ||
-           unsetConflictingSRVs(gl::SAMPLER_PIXEL, resource, nullptr);
+    return unsetConflictingSRVs(gl::SHADER_VERTEX, resource, nullptr) ||
+           unsetConflictingSRVs(gl::SHADER_FRAGMENT, resource, nullptr);
 }
 
-bool StateManager11::unsetConflictingSRVs(gl::SamplerType samplerType,
+bool StateManager11::unsetConflictingSRVs(gl::ShaderType shaderType,
                                           uintptr_t resource,
                                           const gl::ImageIndex *index)
 {
-    auto &currentSRVs = (samplerType == gl::SAMPLER_VERTEX ? mCurVertexSRVs : mCurPixelSRVs);
+    auto *currentSRVs = getSRVCache(shaderType);
 
     bool foundOne = false;
 
-    for (size_t resourceIndex = 0; resourceIndex < currentSRVs.size(); ++resourceIndex)
+    for (size_t resourceIndex = 0; resourceIndex < currentSRVs->size(); ++resourceIndex)
     {
-        auto &record = currentSRVs[resourceIndex];
-
-        if (record.srv && record.resource == resource &&
+        auto &record = (*currentSRVs)[resourceIndex];
+
+        if (record.view && record.resource == resource &&
             (!index || ImageIndexConflictsWithSRV(*index, record.desc)))
         {
             setShaderResourceInternal<d3d11::ShaderResourceView>(
-                samplerType, static_cast<UINT>(resourceIndex), nullptr);
+                shaderType, static_cast<UINT>(resourceIndex), nullptr);
             foundOne = true;
         }
     }
 
     return foundOne;
 }
 
 void StateManager11::unsetConflictingAttachmentResources(
@@ -1579,35 +1671,42 @@ 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::SAMPLER_VERTEX, resourcePtr, &index);
-        unsetConflictingSRVs(gl::SAMPLER_PIXEL, resourcePtr, &index);
+        unsetConflictingSRVs(gl::SHADER_VERTEX, resourcePtr, &index);
+        unsetConflictingSRVs(gl::SHADER_FRAGMENT, resourcePtr, &index);
     }
     else if (attachment->type() == GL_FRAMEBUFFER_DEFAULT)
     {
         uintptr_t resourcePtr = reinterpret_cast<uintptr_t>(resource);
-        unsetConflictingSRVs(gl::SAMPLER_VERTEX, resourcePtr, nullptr);
-        unsetConflictingSRVs(gl::SAMPLER_PIXEL, resourcePtr, nullptr);
+        unsetConflictingSRVs(gl::SHADER_VERTEX, resourcePtr, nullptr);
+        unsetConflictingSRVs(gl::SHADER_FRAGMENT, resourcePtr, nullptr);
     }
 }
 
 gl::Error StateManager11::initialize(const gl::Caps &caps, const gl::Extensions &extensions)
 {
     mCurVertexSRVs.initialize(caps.maxVertexTextureImageUnits);
     mCurPixelSRVs.initialize(caps.maxTextureImageUnits);
 
+    // TODO(xinghua.cao@intel.com): need to add compute shader texture image units.
+    mCurComputeSRVs.initialize(caps.maxImageUnits);
+
+    mCurComputeUAVs.initialize(caps.maxImageUnits);
+
     // Initialize cached NULL SRV block
     mNullSRVs.resize(caps.maxTextureImageUnits, nullptr);
 
+    mNullUAVs.resize(caps.maxImageUnits, nullptr);
+
     mCurrentValueAttribs.resize(caps.maxVertexAttributes);
 
     mForceSetVertexSamplerStates.resize(caps.maxVertexTextureImageUnits, true);
     mForceSetPixelSamplerStates.resize(caps.maxTextureImageUnits, true);
     mForceSetComputeSamplerStates.resize(caps.maxComputeTextureImageUnits, true);
 
     mCurVertexSamplerStates.resize(caps.maxVertexTextureImageUnits);
     mCurPixelSamplerStates.resize(caps.maxTextureImageUnits);
@@ -1742,17 +1841,17 @@ gl::Error StateManager11::syncCurrentVal
 
     for (auto attribIndex : dirtyActiveAttribs)
     {
         if (vertexAttributes[attribIndex].enabled)
             continue;
 
         const auto *attrib                   = &vertexAttributes[attribIndex];
         const auto &currentValue             = glState.getVertexAttribCurrentValue(attribIndex);
-        auto currentValueAttrib              = &mCurrentValueAttribs[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,
@@ -1892,17 +1991,18 @@ gl::Error StateManager11::updateState(co
     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(jmadill): This can be recomputed only on framebuffer changes.
+    // 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);
     }
 
@@ -1969,27 +2069,27 @@ gl::Error StateManager11::updateState(co
     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::SamplerType shaderType,
+void StateManager11::setShaderResourceShared(gl::ShaderType shaderType,
                                              UINT resourceSlot,
                                              const d3d11::SharedSRV *srv)
 {
     setShaderResourceInternal(shaderType, resourceSlot, srv);
 
     // TODO(jmadill): Narrower dirty region.
     mInternalDirtyBits.set(DIRTY_BIT_TEXTURE_AND_SAMPLER_STATE);
 }
 
-void StateManager11::setShaderResource(gl::SamplerType shaderType,
+void StateManager11::setShaderResource(gl::ShaderType shaderType,
                                        UINT resourceSlot,
                                        const d3d11::ShaderResourceView *srv)
 {
     setShaderResourceInternal(shaderType, resourceSlot, srv);
 
     // TODO(jmadill): Narrower dirty region.
     mInternalDirtyBits.set(DIRTY_BIT_TEXTURE_AND_SAMPLER_STATE);
 }
@@ -2190,17 +2290,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::SAMPLER_PIXEL, 0, &srv);
+    setShaderResourceInternal(gl::SHADER_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)
 {
@@ -2217,113 +2317,92 @@ void StateManager11::setScissorRectD3D(c
     mRenderer->getDeviceContext()->RSSetScissorRects(1, &d3dRect);
     mInternalDirtyBits.set(DIRTY_BIT_SCISSOR_STATE);
 }
 
 // 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::SamplerType shaderType,
-                                        const FramebufferTextureArray &framebufferTextures,
-                                        size_t framebufferTextureCount)
+gl::Error StateManager11::applyTextures(const gl::Context *context, gl::ShaderType shaderType)
 {
+    ASSERT(shaderType != gl::SHADER_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();
 
     unsigned int samplerRange = programD3D->getUsedSamplerRange(shaderType);
     for (unsigned int samplerIndex = 0; samplerIndex < samplerRange; samplerIndex++)
     {
-        GLenum textureType = programD3D->getSamplerTextureType(shaderType, samplerIndex);
-        GLint textureUnit  = programD3D->getSamplerMapping(shaderType, samplerIndex, caps);
-        if (textureUnit != -1)
+        GLint textureUnit = programD3D->getSamplerMapping(shaderType, samplerIndex, caps);
+        ASSERT(textureUnit != -1);
+        gl::Texture *texture = completeTextures[textureUnit];
+
+        // A nullptr texture indicates incomplete.
+        if (texture)
         {
-            gl::Texture *texture = completeTextures[textureUnit];
-
-            // A nullptr texture indicates incomplete.
-            if (texture &&
-                !std::binary_search(framebufferTextures.begin(),
-                                    framebufferTextures.begin() + framebufferTextureCount, texture))
-            {
-                gl::Sampler *samplerObject = glState.getSampler(textureUnit);
-
-                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
-            {
-                // 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));
-            }
+            gl::Sampler *samplerObject = glState.getSampler(textureUnit);
+
+            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
         {
-            // No texture bound to this slot even though it is used by the shader, bind a NULL
-            // texture
-            ANGLE_TRY(setTexture(context, shaderType, samplerIndex, nullptr));
+            GLenum 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::SAMPLER_PIXEL) ? caps.maxTextureImageUnits
-                                                            : caps.maxVertexTextureImageUnits;
-    ANGLE_TRY(clearTextures(shaderType, samplerRange, samplerCount));
+    size_t samplerCount = (shaderType == gl::SHADER_FRAGMENT) ? caps.maxTextureImageUnits
+                                                              : caps.maxVertexTextureImageUnits;
+    ANGLE_TRY(clearSRVs(shaderType, samplerRange, samplerCount));
 
     return gl::NoError();
 }
 
 gl::Error StateManager11::syncTextures(const gl::Context *context)
 {
-    FramebufferTextureArray framebufferTextures;
-    size_t framebufferSerialCount =
-        mRenderer->getBoundFramebufferTextures(context->getContextState(), &framebufferTextures);
-
-    ANGLE_TRY(
-        applyTextures(context, gl::SAMPLER_VERTEX, framebufferTextures, framebufferSerialCount));
-    ANGLE_TRY(
-        applyTextures(context, gl::SAMPLER_PIXEL, framebufferTextures, framebufferSerialCount));
+    ANGLE_TRY(applyTextures(context, gl::SHADER_VERTEX));
+    ANGLE_TRY(applyTextures(context, gl::SHADER_FRAGMENT));
     return gl::NoError();
 }
 
 gl::Error StateManager11::setSamplerState(const gl::Context *context,
-                                          gl::SamplerType type,
+                                          gl::ShaderType type,
                                           int index,
                                           gl::Texture *texture,
                                           const gl::SamplerState &samplerState)
 {
 #if !defined(NDEBUG)
     // Storage should exist, texture should be complete. Only verified in Debug.
     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::SAMPLER_PIXEL)
+    if (type == gl::SHADER_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));
@@ -2331,17 +2410,17 @@ gl::Error StateManager11::setSamplerStat
             ASSERT(dxSamplerState != nullptr);
             deviceContext->PSSetSamplers(index, 1, &dxSamplerState);
 
             mCurPixelSamplerStates[index] = samplerState;
         }
 
         mForceSetPixelSamplerStates[index] = false;
     }
-    else if (type == gl::SAMPLER_VERTEX)
+    else if (type == gl::SHADER_VERTEX)
     {
         ASSERT(static_cast<unsigned int>(index) <
                mRenderer->getNativeCaps().maxVertexTextureImageUnits);
 
         if (mForceSetVertexSamplerStates[index] ||
             memcmp(&samplerState, &mCurVertexSamplerStates[index], sizeof(gl::SamplerState)) != 0)
         {
             ID3D11SamplerState *dxSamplerState = nullptr;
@@ -2350,17 +2429,17 @@ gl::Error StateManager11::setSamplerStat
             ASSERT(dxSamplerState != nullptr);
             deviceContext->VSSetSamplers(index, 1, &dxSamplerState);
 
             mCurVertexSamplerStates[index] = samplerState;
         }
 
         mForceSetVertexSamplerStates[index] = false;
     }
-    else if (type == gl::SAMPLER_COMPUTE)
+    else if (type == gl::SHADER_COMPUTE)
     {
         ASSERT(static_cast<unsigned int>(index) <
                mRenderer->getNativeCaps().maxComputeTextureImageUnits);
 
         if (mForceSetComputeSamplerStates[index] ||
             memcmp(&samplerState, &mCurComputeSamplerStates[index], sizeof(gl::SamplerState)) != 0)
         {
             ID3D11SamplerState *dxSamplerState = nullptr;
@@ -2381,53 +2460,136 @@ gl::Error StateManager11::setSamplerStat
     // sampler state since having it in contiguous memory makes it possible to memcpy to a constant
     // buffer, and it doesn't affect the state set by PSSetSamplers/VSSetSamplers.
     mShaderConstants.onSamplerChange(type, index, *texture);
 
     return gl::NoError();
 }
 
 gl::Error StateManager11::setTexture(const gl::Context *context,
-                                     gl::SamplerType type,
+                                     gl::ShaderType type,
                                      int index,
                                      gl::Texture *texture)
 {
+    ASSERT(type != gl::SHADER_COMPUTE);
     const d3d11::SharedSRV *textureSRV = nullptr;
 
     if (texture)
     {
         TextureD3D *textureImpl = GetImplAs<TextureD3D>(texture);
 
         TextureStorage *texStorage = nullptr;
         ANGLE_TRY(textureImpl->getNativeTexture(context, &texStorage));
 
         // Texture should be complete and have a storage
         ASSERT(texStorage);
 
         TextureStorage11 *storage11 = GetAs<TextureStorage11>(texStorage);
 
-        ANGLE_TRY(storage11->getSRV(context, texture->getTextureState(), &textureSRV));
+        ANGLE_TRY(storage11->getSRVForSampler(context, texture->getTextureState(), &textureSRV));
 
         // 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::SAMPLER_PIXEL &&
+        (type == gl::SHADER_FRAGMENT &&
          static_cast<unsigned int>(index) < mRenderer->getNativeCaps().maxTextureImageUnits) ||
-        (type == gl::SAMPLER_VERTEX &&
+        (type == gl::SHADER_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);
+    for (unsigned int readonlyImageIndex = 0; readonlyImageIndex < readonlyImageRange;
+         readonlyImageIndex++)
+    {
+        GLint imageUnitIndex =
+            programD3D->getImageMapping(gl::SHADER_COMPUTE, readonlyImageIndex, true, 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));
+    }
+
+    // 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));
+
+    return gl::NoError();
+}
+
+gl::Error StateManager11::setTextureForImage(const gl::Context *context,
+                                             gl::ShaderType type,
+                                             int index,
+                                             bool readonly,
+                                             const gl::ImageUnit &imageUnit)
+{
+    TextureD3D *textureImpl = nullptr;
+    if (!imageUnit.texture.get())
+    {
+        return gl::NoError();
+    }
+
+    textureImpl                = GetImplAs<TextureD3D>(imageUnit.texture.get());
+    TextureStorage *texStorage = nullptr;
+    ANGLE_TRY(textureImpl->getNativeTexture(context, &texStorage));
+    // Texture should be complete and have a storage
+    ASSERT(texStorage);
+    TextureStorage11 *storage11 = GetAs<TextureStorage11>(texStorage);
+
+    if (readonly)
+    {
+        const d3d11::SharedSRV *textureSRV = nullptr;
+        ANGLE_TRY(storage11->getSRVForImage(context, imageUnit, &textureSRV));
+        // 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());
+        ASSERT((static_cast<unsigned int>(index) < mRenderer->getNativeCaps().maxImageUnits));
+        setShaderResourceInternal(type, index, textureSRV);
+    }
+    else
+    {
+        const d3d11::SharedUAV *textureUAV = nullptr;
+        ANGLE_TRY(storage11->getUAVForImage(context, imageUnit, &textureUAV));
+        // If we get an invalid UAV here, something went wrong in the texture class and we're
+        // unexpectedly missing the unordered access view.
+        ASSERT(textureUAV->valid());
+        ASSERT((static_cast<unsigned int>(index) < mRenderer->getNativeCaps().maxImageUnits));
+        setUnorderedAccessViewInternal(type, index, textureUAV);
+    }
+
+    textureImpl->resetDirty();
+    return gl::NoError();
+}
+
 // Things that affect a program's dirtyness:
 // 1. Directly changing the program executable -> triggered in StateManager11::syncState.
 // 2. The vertex attribute layout              -> triggered in VertexArray11::syncState/signal.
 // 3. The fragment shader's rendertargets      -> triggered in Framebuffer11::syncState/signal.
 // 4. Enabling/disabling rasterizer discard.   -> triggered in StateManager11::syncState.
 // 5. Enabling/disabling transform feedback.   -> checked in StateManager11::updateState.
 // 6. An internal shader was used.             -> triggered in StateManager11::set*Shader.
 // 7. Drawing with/without point sprites.      -> checked in StateManager11::updateState.
@@ -2485,52 +2647,44 @@ gl::Error StateManager11::syncProgram(co
     // Explicitly clear the shaders dirty bit.
     mInternalDirtyBits.reset(DIRTY_BIT_SHADERS);
 
     return gl::NoError();
 }
 
 gl::Error StateManager11::applyVertexBuffer(const gl::Context *context,
                                             GLenum mode,
-                                            GLint first,
-                                            GLsizei count,
-                                            GLsizei instances,
-                                            TranslatedIndexData *indexInfo)
+                                            const DrawCallVertexParams &vertexParams,
+                                            bool isIndexedRendering)
 {
     const auto &state       = context->getGLState();
-    const auto &vertexArray = state.getVertexArray();
-    auto *vertexArray11     = GetImplAs<VertexArray11>(vertexArray);
+    const gl::VertexArray *vertexArray = state.getVertexArray();
+    VertexArray11 *vertexArray11       = GetImplAs<VertexArray11>(vertexArray);
 
     if (mVertexAttribsNeedTranslation)
     {
-        ANGLE_TRY(vertexArray11->updateDirtyAndDynamicAttribs(context, &mVertexDataManager, first,
-                                                              count, instances));
+        ANGLE_TRY(vertexArray11->updateDirtyAndDynamicAttribs(context, &mVertexDataManager,
+                                                              vertexParams));
         mInputLayoutIsDirty = true;
 
         // Determine if we need to update attribs on the next draw.
-        mVertexAttribsNeedTranslation = (vertexArray11->hasDynamicAttrib(context));
+        mVertexAttribsNeedTranslation = (vertexArray11->hasActiveDynamicAttrib(context));
     }
 
-    if (!mLastFirstVertex.valid() || mLastFirstVertex.value() != first)
+    if (!mLastFirstVertex.valid() || mLastFirstVertex.value() != vertexParams.firstVertex())
     {
-        mLastFirstVertex    = first;
+        mLastFirstVertex    = vertexParams.firstVertex();
         mInputLayoutIsDirty = true;
     }
 
     if (!mInputLayoutIsDirty)
     {
         return gl::NoError();
     }
 
-    GLsizei numIndicesPerInstance = 0;
-    if (instances > 0)
-    {
-        numIndicesPerInstance = count;
-    }
-
     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);
 
@@ -2548,46 +2702,61 @@ gl::Error StateManager11::applyVertexBuf
                 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, numIndicesPerInstance));
+                                                  sortedSemanticIndices, vertexParams));
 
     // Update the applied vertex buffers.
-    ANGLE_TRY(
-        mInputLayoutCache.applyVertexBuffers(context, mCurrentAttributes, mode, first, indexInfo));
+    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, count);
+    vertexArray11->clearDirtyAndPromoteDynamicAttribs(context, vertexParams);
 
     mInputLayoutIsDirty = false;
     return gl::NoError();
 }
 
 gl::Error StateManager11::applyIndexBuffer(const gl::Context *context,
                                            const void *indices,
                                            GLsizei count,
                                            GLenum type,
-                                           TranslatedIndexData *indexInfo)
+                                           const gl::HasIndexRange &lazyIndexRange,
+                                           bool usePrimitiveRestartWorkaround)
 {
-    const auto &glState            = context->getGLState();
-    gl::VertexArray *vao           = glState.getVertexArray();
+    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)
+    {
+        // No streaming or index buffer application necessary.
+        return gl::NoError();
+    }
+
     gl::Buffer *elementArrayBuffer = vao->getElementArrayBuffer().get();
-    ANGLE_TRY(mIndexDataManager.prepareIndexData(context, type, count, elementArrayBuffer, indices,
-                                                 indexInfo, glState.isPrimitiveRestartEnabled()));
+
+    TranslatedIndexData *indexInfo = vao11->getCachedIndexInfo();
+    ANGLE_TRY(mIndexDataManager.prepareIndexData(context, type, destElementType, count,
+                                                 elementArrayBuffer, indices, indexInfo));
 
     ID3D11Buffer *buffer = nullptr;
     DXGI_FORMAT bufferFormat =
         (indexInfo->indexType == GL_UNSIGNED_INT) ? DXGI_FORMAT_R32_UINT : DXGI_FORMAT_R16_UINT;
 
     if (indexInfo->storage)
     {
         Buffer11 *storage = GetAs<Buffer11>(indexInfo->storage);
@@ -2596,25 +2765,38 @@ gl::Error StateManager11::applyIndexBuff
     else
     {
         IndexBuffer11 *indexBuffer = GetAs<IndexBuffer11>(indexInfo->indexBuffer);
         buffer                     = indexBuffer->getBuffer().get();
     }
 
     // Track dirty indices in the index range cache.
     indexInfo->srcIndexData.srcIndicesChanged =
-        setIndexBuffer(buffer, bufferFormat, indexInfo->startOffset);
-
+        syncIndexBuffer(buffer, bufferFormat, indexInfo->startOffset);
+
+    mIndexBufferIsDirty = false;
+
+    vao11->setCachedIndexInfoValid();
     return gl::NoError();
 }
 
-bool StateManager11::setIndexBuffer(ID3D11Buffer *buffer,
+void StateManager11::setIndexBuffer(ID3D11Buffer *buffer,
                                     DXGI_FORMAT indexFormat,
                                     unsigned int offset)
 {
+    if (syncIndexBuffer(buffer, indexFormat, offset))
+    {
+        mIndexBufferIsDirty = true;
+    }
+}
+
+bool StateManager11::syncIndexBuffer(ID3D11Buffer *buffer,
+                                     DXGI_FORMAT indexFormat,
+                                     unsigned int offset)
+{
     if (buffer != mAppliedIB || indexFormat != mAppliedIBFormat || offset != mAppliedIBOffset)
     {
         mRenderer->getDeviceContext()->IASetIndexBuffer(buffer, indexFormat, offset);
 
         mAppliedIB       = buffer;
         mAppliedIBFormat = indexFormat;
         mAppliedIBOffset = offset;
         return true;
@@ -2649,18 +2831,17 @@ gl::Error StateManager11::generateSwizzl
         TextureStorage11 *storage11          = GetAs<TextureStorage11>(texStorage);
         const gl::TextureState &textureState = texture->getTextureState();
         ANGLE_TRY(storage11->generateSwizzles(context, textureState.getSwizzleState()));
     }
 
     return gl::NoError();
 }
 
-gl::Error StateManager11::generateSwizzlesForShader(const gl::Context *context,
-                                                    gl::SamplerType type)
+gl::Error StateManager11::generateSwizzlesForShader(const gl::Context *context, gl::ShaderType type)
 {
     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++)
     {
@@ -2677,18 +2858,18 @@ gl::Error StateManager11::generateSwizzl
         }
     }
 
     return gl::NoError();
 }
 
 gl::Error StateManager11::generateSwizzles(const gl::Context *context)
 {
-    ANGLE_TRY(generateSwizzlesForShader(context, gl::SAMPLER_VERTEX));
-    ANGLE_TRY(generateSwizzlesForShader(context, gl::SAMPLER_PIXEL));
+    ANGLE_TRY(generateSwizzlesForShader(context, gl::SHADER_VERTEX));
+    ANGLE_TRY(generateSwizzlesForShader(context, gl::SHADER_FRAGMENT));
     return gl::NoError();
 }
 
 gl::Error StateManager11::applyUniforms(ProgramD3D *programD3D)
 {
     UniformStorage11 *vertexUniformStorage =
         GetAs<UniformStorage11>(&programD3D->getVertexUniformStorage());
     UniformStorage11 *fragmentUniformStorage =
@@ -2737,45 +2918,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::SAMPLER_VERTEX);
+        size_t requiredSize = mShaderConstants.getRequiredBufferSize(gl::SHADER_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::SAMPLER_PIXEL);
+        size_t requiredSize = mShaderConstants.getRequiredBufferSize(gl::SHADER_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(deviceContext, gl::SAMPLER_VERTEX, programD3D,
+    ANGLE_TRY(mShaderConstants.updateBuffer(mRenderer, gl::SHADER_VERTEX, programD3D,
                                             mDriverConstantBufferVS));
-    ANGLE_TRY(mShaderConstants.updateBuffer(deviceContext, gl::SAMPLER_PIXEL, programD3D,
+    ANGLE_TRY(mShaderConstants.updateBuffer(mRenderer, gl::SHADER_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())
         {
@@ -2810,27 +2991,27 @@ gl::Error StateManager11::applyComputeUn
         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::SAMPLER_COMPUTE);
+        size_t requiredSize = mShaderConstants.getRequiredBufferSize(gl::SHADER_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(deviceContext, gl::SAMPLER_COMPUTE, *programD3D,
+    ANGLE_TRY(mShaderConstants.updateBuffer(mRenderer, gl::SHADER_COMPUTE, *programD3D,
                                             mDriverConstantBufferCS));
 
     return gl::NoError();
 }
 
 gl::Error StateManager11::syncUniformBuffers(const gl::Context *context, ProgramD3D *programD3D)
 {
     unsigned int reservedVertex   = mRenderer->getReservedVertexUniformBuffers();
@@ -2839,16 +3020,18 @@ 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();
+
     for (size_t bufferIndex = 0; bufferIndex < vertexUniformBuffers.size(); bufferIndex++)
     {
         GLint binding = vertexUniformBuffers[bufferIndex];
 
         if (binding == -1)
         {
             continue;
         }
@@ -2891,16 +3074,18 @@ gl::Error StateManager11::syncUniformBuf
         else
         {
             deviceContext->VSSetConstantBuffers(appliedIndex, 1, constantBuffer->getPointer());
         }
 
         mCurrentConstantBufferVS[appliedIndex]       = constantBuffer->getSerial();
         mCurrentConstantBufferVSOffset[appliedIndex] = uniformBufferOffset;
         mCurrentConstantBufferVSSize[appliedIndex]   = uniformBufferSize;
+
+        mOnConstantBufferDirtyReceiver.bindVS(bufferIndex, bufferStorage);
     }
 
     for (size_t bufferIndex = 0; bufferIndex < fragmentUniformBuffers.size(); bufferIndex++)
     {
         GLint binding = fragmentUniformBuffers[bufferIndex];
 
         if (binding == -1)
         {
@@ -2944,16 +3129,18 @@ gl::Error StateManager11::syncUniformBuf
         else
         {
             deviceContext->PSSetConstantBuffers(appliedIndex, 1, constantBuffer->getPointer());
         }
 
         mCurrentConstantBufferPS[appliedIndex]       = constantBuffer->getSerial();
         mCurrentConstantBufferPSOffset[appliedIndex] = uniformBufferOffset;
         mCurrentConstantBufferPSSize[appliedIndex]   = uniformBufferSize;
+
+        mOnConstantBufferDirtyReceiver.bindPS(bufferIndex, bufferStorage);
     }
 
     return gl::NoError();
 }
 
 gl::Error StateManager11::syncTransformFeedbackBuffers(const gl::Context *context)
 {
     const auto &glState = context->getGLState();
@@ -2985,9 +3172,127 @@ 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()
+{
+    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()
+{
+}
+
+void StateManager11::OnConstantBufferDirtyReceiver::signal(size_t messageID,
+                                                           const gl::Context *context)
+{
+    StateManager11 *stateManager = GetImplAs<Context11>(context)->getRenderer()->getStateManager();
+    stateManager->invalidateProgramUniformBuffers();
+}
+
+void StateManager11::OnConstantBufferDirtyReceiver::bindVS(size_t index, Buffer11 *buffer)
+{
+    ASSERT(buffer);
+    ASSERT(index < mBindingsVS.size());
+    mBindingsVS[index].bind(buffer->getDirectBroadcastChannel());
+}
+
+void StateManager11::OnConstantBufferDirtyReceiver::bindPS(size_t index, Buffer11 *buffer)
+{
+    ASSERT(buffer);
+    ASSERT(index < mBindingsPS.size());
+    mBindingsPS[index].bind(buffer->getDirectBroadcastChannel());
+}
+
+void StateManager11::OnConstantBufferDirtyReceiver::reset()
+{
+    for (OnBufferDataDirtyBinding &vsBinding : mBindingsVS)
+    {
+        vsBinding.bind(nullptr);
+    }
+
+    for (OnBufferDataDirtyBinding &psBinding : mBindingsPS)
+    {
+        psBinding.bind(nullptr);
+    }
+}
+
 }  // namespace rx
--- a/gfx/angle/src/libANGLE/renderer/d3d/d3d11/StateManager11.h
+++ b/gfx/angle/src/libANGLE/renderer/d3d/d3d11/StateManager11.h
@@ -18,41 +18,42 @@
 #include "libANGLE/renderer/d3d/RendererD3D.h"
 #include "libANGLE/renderer/d3d/d3d11/InputLayoutCache.h"
 #include "libANGLE/renderer/d3d/d3d11/Query11.h"
 #include "libANGLE/renderer/d3d/d3d11/RenderStateCache.h"
 #include "libANGLE/renderer/d3d/d3d11/renderer11_utils.h"
 
 namespace rx
 {
-
+class Buffer11;
 struct RenderTargetDesc;
 struct Renderer11DeviceCaps;
 
 class ShaderConstants11 : angle::NonCopyable
 {
   public:
     ShaderConstants11();
+    ~ShaderConstants11();
 
     void init(const gl::Caps &caps);
-    size_t getRequiredBufferSize(gl::SamplerType samplerType) const;
+    size_t getRequiredBufferSize(gl::ShaderType shaderType) const;
     void markDirty();
 
     void setComputeWorkGroups(GLuint numGroupsX, GLuint numGroupsY, GLuint numGroupsZ);
     void setMultiviewWriteToViewportIndex(GLfloat index);
     void onViewportChange(const gl::Rectangle &glViewport,
                           const D3D11_VIEWPORT &dxViewport,
                           bool is9_3,
                           bool presentPathFast);
-    void onSamplerChange(gl::SamplerType samplerType,
+    void onSamplerChange(gl::ShaderType shaderType,
                          unsigned int samplerIndex,
                          const gl::Texture &texture);
 
-    gl::Error updateBuffer(ID3D11DeviceContext *deviceContext,
-                           gl::SamplerType samplerType,
+    gl::Error updateBuffer(Renderer11 *renderer,
+                           gl::ShaderType shaderType,
                            const ProgramD3D &programD3D,
                            const d3d11::Buffer &driverConstantBuffer);
 
   private:
     struct Vertex
     {
         Vertex()
             : depthRange{.0f},
@@ -135,16 +136,45 @@ class ShaderConstants11 : angle::NonCopy
     std::vector<SamplerMetadata> mSamplerMetadataVS;
     bool mSamplerMetadataVSDirty;
     std::vector<SamplerMetadata> mSamplerMetadataPS;
     bool mSamplerMetadataPSDirty;
     std::vector<SamplerMetadata> mSamplerMetadataCS;
     bool mSamplerMetadataCSDirty;
 };
 
+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();
@@ -180,16 +210,19 @@ class StateManager11 final : angle::NonC
     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();
+
     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);
@@ -201,20 +234,20 @@ class StateManager11 final : angle::NonC
                                  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);
 
-    void setShaderResourceShared(gl::SamplerType shaderType,
+    void setShaderResourceShared(gl::ShaderType shaderType,
                                  UINT resourceSlot,
                                  const d3d11::SharedSRV *srv);
-    void setShaderResource(gl::SamplerType shaderType,
+    void setShaderResource(gl::ShaderType shaderType,
                            UINT resourceSlot,
                            const d3d11::ShaderResourceView *srv);
     void setPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY primitiveTopology);
 
     void setDrawShaders(const d3d11::VertexShader *vertexShader,
                         const d3d11::GeometryShader *geometryShader,
                         const d3d11::PixelShader *pixelShader);
     void setVertexShader(const d3d11::VertexShader *shader);
@@ -231,46 +264,49 @@ class StateManager11 final : angle::NonC
     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,
-                                GLint first,
-                                GLsizei count,
-                                GLsizei instances,
-                                TranslatedIndexData *indexInfo);
+                                const DrawCallVertexParams &vertexParams,
+                                bool isIndexedRendering);
 
     gl::Error applyIndexBuffer(const gl::Context *context,
                                const void *indices,
                                GLsizei count,
                                GLenum type,
-                               TranslatedIndexData *indexInfo);
+                               const gl::HasIndexRange &lazyIndexRange,
+                               bool usePrimitiveRestartWorkaround);
 
-    bool setIndexBuffer(ID3D11Buffer *buffer, DXGI_FORMAT indexFormat, unsigned int offset);
+    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; }
 
   private:
     template <typename SRVType>
-    void setShaderResourceInternal(gl::SamplerType shaderType,
+    void setShaderResourceInternal(gl::ShaderType shaderType,
                                    UINT resourceSlot,
                                    const SRVType *srv);
+    template <typename UAVType>
+    void setUnorderedAccessViewInternal(gl::ShaderType shaderType,
+                                        UINT resourceSlot,
+                                        const UAVType *uav);
 
     bool unsetConflictingView(ID3D11View *view);
-    bool unsetConflictingSRVs(gl::SamplerType shaderType,
+    bool unsetConflictingSRVs(gl::ShaderType shaderType,
                               uintptr_t resource,
                               const gl::ImageIndex *index);
     void unsetConflictingAttachmentResources(const gl::FramebufferAttachment *attachment,
                                              ID3D11Resource *resource);
 
     gl::Error syncBlendState(const gl::Context *context,
                              const gl::Framebuffer *framebuffer,
                              const gl::BlendState &blendState,
@@ -286,58 +322,62 @@ class StateManager11 final : angle::NonC
     void syncViewport(const gl::Context *context);
 
     void checkPresentPath(const gl::Context *context);
 
     gl::Error syncFramebuffer(const gl::Context *context, gl::Framebuffer *framebuffer);
     gl::Error syncProgram(const gl::Context *context, GLenum drawMode);
 
     gl::Error syncTextures(const gl::Context *context);
-    gl::Error applyTextures(const gl::Context *context,
-                            gl::SamplerType shaderType,
-                            const FramebufferTextureArray &framebufferTextures,
-                            size_t framebufferTextureCount);
+    gl::Error applyTextures(const gl::Context *context, gl::ShaderType shaderType);
+    gl::Error syncTexturesForCompute(const gl::Context *context);
 
     gl::Error setSamplerState(const gl::Context *context,
-                              gl::SamplerType type,
+                              gl::ShaderType type,
                               int index,
                               gl::Texture *texture,
                               const gl::SamplerState &sampler);
     gl::Error setTexture(const gl::Context *context,
-                         gl::SamplerType type,
+                         gl::ShaderType type,
                          int index,
                          gl::Texture *texture);
+    gl::Error setTextureForImage(const gl::Context *context,
+                                 gl::ShaderType type,
+                                 int index,
+                                 bool readonly,
+                                 const gl::ImageUnit &imageUnit);
 
     // Faster than calling setTexture a jillion times
-    gl::Error clearTextures(gl::SamplerType samplerType, size_t rangeStart, size_t rangeEnd);
+    gl::Error clearSRVs(gl::ShaderType shaderType, size_t rangeStart, size_t rangeEnd);
+    gl::Error clearUAVs(gl::ShaderType shaderType, size_t rangeStart, size_t rangeEnd);
     void handleMultiviewDrawFramebufferChange(const gl::Context *context);
 
-    gl::Error syncVertexAttributes(const gl::Context *context);
     gl::Error syncCurrentValueAttribs(const gl::State &glState);
 
     gl::Error generateSwizzle(const gl::Context *context, gl::Texture *texture);
-    gl::Error generateSwizzlesForShader(const gl::Context *context, gl::SamplerType type);
+    gl::Error generateSwizzlesForShader(const gl::Context *context, gl::ShaderType type);
     gl::Error generateSwizzles(const gl::Context *context);
 
     gl::Error applyDriverUniforms(const ProgramD3D &programD3D);
     gl::Error applyUniforms(ProgramD3D *programD3D);
 
     gl::Error syncUniformBuffers(const gl::Context *context, ProgramD3D *programD3D);
     gl::Error syncTransformFeedbackBuffers(const gl::Context *context);
 
     // These are currently only called internally.
     void invalidateTexturesAndSamplers();
     void invalidateDriverUniforms();
     void invalidateProgramUniforms();
-    void invalidateProgramUniformBuffers();
     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);
+
     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,
@@ -398,66 +438,75 @@ class StateManager11 final : angle::NonC
     // EGL_ANGLE_experimental_present_path variables
     bool mCurPresentPathFastEnabled;
     int mCurPresentPathFastColorBufferHeight;
 
     // Queries that are currently active in this state
     std::set<Query11 *> mCurrentQueries;
 
     // Currently applied textures
-    struct SRVRecord
+    template <typename DescType>
+    struct ViewRecord
     {
-        uintptr_t srv;
+        uintptr_t view;
         uintptr_t resource;
-        D3D11_SHADER_RESOURCE_VIEW_DESC desc;
+        DescType desc;
     };
 
-    // A cache of current SRVs that also tracks the highest 'used' (non-NULL) SRV
+    // A cache of current Views that also tracks the highest 'used' (non-NULL) View.
     // We might want to investigate a more robust approach that is also fast when there's
-    // a large gap between used SRVs (e.g. if SRV 0 and 7 are non-NULL, this approach will
-    // waste time on SRVs 1-6.)
-    class SRVCache : angle::NonCopyable
+    // a large gap between used Views (e.g. if View 0 and 7 are non-NULL, this approach will
+    // waste time on Views 1-6.)
+    template <typename ViewType, typename DescType>
+    class ViewCache : angle::NonCopyable
     {
       public:
-        SRVCache() : mHighestUsedSRV(0) {}
+        ViewCache();
+        ~ViewCache();
 
-        void initialize(size_t size) { mCurrentSRVs.resize(size); }
+        void initialize(size_t size) { mCurrentViews.resize(size); }
 
-        size_t size() const { return mCurrentSRVs.size(); }
-        size_t highestUsed() const { return mHighestUsedSRV; }
+        size_t size() const { return mCurrentViews.size(); }
+        size_t highestUsed() const { return mHighestUsedView; }
 
-        const SRVRecord &operator[](size_t index) const { return mCurrentSRVs[index]; }
+        const ViewRecord<DescType> &operator[](size_t index) const { return mCurrentViews[index]; }
         void clear();
-        void update(size_t resourceIndex, ID3D11ShaderResourceView *srv);
+        void update(size_t resourceIndex, ViewType *view);
 
       private:
-        std::vector<SRVRecord> mCurrentSRVs;
-        size_t mHighestUsedSRV;
+        std::vector<ViewRecord<DescType>> mCurrentViews;
+        size_t mHighestUsedView;
     };
 
+    using SRVCache = ViewCache<ID3D11ShaderResourceView, D3D11_SHADER_RESOURCE_VIEW_DESC>;
+    using UAVCache = ViewCache<ID3D11UnorderedAccessView, D3D11_UNORDERED_ACCESS_VIEW_DESC>;
     SRVCache mCurVertexSRVs;
     SRVCache mCurPixelSRVs;
+    SRVCache mCurComputeSRVs;
+    UAVCache mCurComputeUAVs;
+    SRVCache *getSRVCache(gl::ShaderType shaderType);
 
     // A block of NULL pointers, cached so we don't re-allocate every draw call
     std::vector<ID3D11ShaderResourceView *> mNullSRVs;
+    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.
-    std::array<ID3D11Buffer *, gl::MAX_VERTEX_ATTRIBS> mCurrentVertexBuffers;
-    std::array<UINT, gl::MAX_VERTEX_ATTRIBS> mCurrentVertexStrides;
-    std::array<UINT, gl::MAX_VERTEX_ATTRIBS> mCurrentVertexOffsets;
+    gl::AttribArray<ID3D11Buffer *> mCurrentVertexBuffers;
+    gl::AttribArray<UINT> mCurrentVertexStrides;
+    gl::AttribArray<UINT> mCurrentVertexOffsets;
     gl::RangeUI mDirtyVertexBufferRange;
 
     // Currently applied primitive topology
     D3D11_PRIMITIVE_TOPOLOGY mCurrentPrimitiveTopology;
 
     // Currently applied shaders
     ResourceSerial mAppliedVertexShader;
     ResourceSerial mAppliedGeometryShader;
@@ -476,17 +525,17 @@ class StateManager11 final : angle::NonC
 
     // Special dirty bit for swizzles. Since they use internal shaders, must be done in a pre-pass.
     bool mDirtySwizzles;
 
     // Currently applied index buffer
     ID3D11Buffer *mAppliedIB;
     DXGI_FORMAT mAppliedIBFormat;
     unsigned int mAppliedIBOffset;
-    bool mAppliedIBChanged;
+    bool mIndexBufferIsDirty;
 
     // Vertex, index and input layouts
     VertexDataManager mVertexDataManager;
     IndexDataManager mIndexDataManager;
     InputLayoutCache mInputLayoutCache;
     std::vector<const TranslatedAttribute *> mCurrentAttributes;
     Optional<GLint> mLastFirstVertex;
 
@@ -512,16 +561,34 @@ class StateManager11 final : angle::NonC
     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 OnBufferDataDirtyReceiver
+    {
+      public:
+        OnConstantBufferDirtyReceiver();
+        ~OnConstantBufferDirtyReceiver() override;
+
+        void signal(size_t messageID, const gl::Context *context) override;
+
+        void reset();
+        void bindVS(size_t index, Buffer11 *buffer);
+        void bindPS(size_t index, Buffer11 *buffer);
+
+      private:
+        std::vector<OnBufferDataDirtyBinding> mBindingsVS;
+        std::vector<OnBufferDataDirtyBinding> mBindingsPS;
+    };
+    OnConstantBufferDirtyReceiver mOnConstantBufferDirtyReceiver;
+
     // Currently applied transform feedback buffers
     Serial mAppliedTFSerial;
 
     Serial mEmptySerial;
 
     bool mIsTransformFeedbackCurrentlyActiveUnpaused;
 };
 
new file mode 100644
--- /dev/null
+++ b/gfx/angle/src/libANGLE/renderer/d3d/d3d11/StreamProducerD3DTexture.cpp
@@ -0,0 +1,141 @@
+//
+// 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.
+//
+
+// StreamProducerD3DTexture.cpp: Implements the stream producer for D3D11 textures
+
+#include "libANGLE/renderer/d3d/d3d11/StreamProducerD3DTexture.h"
+
+#include "common/utilities.h"
+#include "libANGLE/renderer/d3d/d3d11/Renderer11.h"
+#include "libANGLE/renderer/d3d/d3d11/renderer11_utils.h"
+
+namespace rx
+{
+
+namespace
+{
+
+egl::Error GetGLDescFromTex(ID3D11Texture2D *const tex,
+                            const UINT planeIndex,
+                            egl::Stream::GLTextureDescription *const out)
+{
+    if (!tex)
+        return egl::EglBadParameter() << "Texture is null";
+
+    D3D11_TEXTURE2D_DESC desc;
+    tex->GetDesc(&desc);
+
+    if (desc.Width < 1 || desc.Height < 1)
+        return egl::EglBadParameter() << "Width or height < 1";
+
+    out->width     = desc.Width;
+    out->height    = desc.Height;
+    out->mipLevels = 0;
+
+    UINT maxPlaneIndex = 0;
+    switch (desc.Format)
+    {
+        case DXGI_FORMAT_NV12:
+            // The UV plane of NV12 textures has half the width/height of the Y plane
+            if ((desc.Width % 2) != 0 || (desc.Height % 2) != 0)
+                return egl::EglBadParameter() << "NV12 tetxures must have even width and height.";
+
+            maxPlaneIndex = 1;
+            if (planeIndex == 0)
+            {
+                out->internalFormat = GL_R8;
+            }
+            else
+            {
+                out->internalFormat = GL_RG8;
+                out->width /= 2;
+                out->height /= 2;
+            }
+            break;
+
+        case DXGI_FORMAT_R8_UNORM:
+            out->internalFormat = GL_R8;
+            break;
+        case DXGI_FORMAT_R8G8_UNORM:
+            out->internalFormat = GL_RG8;
+            break;
+        case DXGI_FORMAT_R8G8B8A8_UNORM:
+            out->internalFormat = GL_RGBA8;
+            break;
+
+        default:
+            return egl::EglBadParameter() << "Unsupported format";
+    }
+
+    if (planeIndex > maxPlaneIndex)  // Just kidding, there's no plane out there.
+        return egl::EglBadParameter() << "Plane out of range";
+
+    return egl::NoError();
+}
+
+}  // namespace
+
+StreamProducerD3DTexture::StreamProducerD3DTexture(Renderer11 *renderer)
+    : mRenderer(renderer), mTexture(nullptr), mArraySlice(0), mPlaneOffset(0)
+{
+}
+
+StreamProducerD3DTexture::~StreamProducerD3DTexture()
+{
+    SafeRelease(mTexture);
+}
+
+egl::Error StreamProducerD3DTexture::validateD3DTexture(void *pointer,
+                                                        const egl::AttributeMap &attributes) const
+{
+    ID3D11Texture2D *textureD3D = static_cast<ID3D11Texture2D *>(pointer);
+
+    // Check that the texture originated from our device
+    ID3D11Device *device;
+    textureD3D->GetDevice(&device);
+    if (device != mRenderer->getDevice())
+    {
+        return egl::EglBadParameter() << "Texture not created on ANGLE D3D device";
+    }
+
+    const auto planeId = static_cast<UINT>(attributes.get(EGL_NATIVE_BUFFER_PLANE_OFFSET_IMG, 0));
+    egl::Stream::GLTextureDescription unused;
+    return GetGLDescFromTex(textureD3D, planeId, &unused);
+}
+
+void StreamProducerD3DTexture::postD3DTexture(void *pointer, const egl::AttributeMap &attributes)
+{
+    ASSERT(pointer != nullptr);
+    ID3D11Texture2D *textureD3D = static_cast<ID3D11Texture2D *>(pointer);
+
+    // Release the previous texture if there is one
+    SafeRelease(mTexture);
+
+    mTexture = textureD3D;
+    mTexture->AddRef();
+    mPlaneOffset = static_cast<UINT>(attributes.get(EGL_NATIVE_BUFFER_PLANE_OFFSET_IMG, 0));
+    mArraySlice  = static_cast<UINT>(attributes.get(EGL_D3D_TEXTURE_SUBRESOURCE_ID_ANGLE, 0));
+}
+
+egl::Stream::GLTextureDescription StreamProducerD3DTexture::getGLFrameDescription(int planeIndex)
+{
+    const auto planeOffsetIndex = static_cast<UINT>(planeIndex + mPlaneOffset);
+    egl::Stream::GLTextureDescription ret;
+    ANGLE_SWALLOW_ERR(GetGLDescFromTex(mTexture, planeOffsetIndex, &ret));
+    return ret;
+}
+
+ID3D11Texture2D *StreamProducerD3DTexture::getD3DTexture()
+{
+    return mTexture;
+}
+
+UINT StreamProducerD3DTexture::getArraySlice()
+{
+    return mArraySlice;
+}
+
+}  // namespace rx
new file mode 100644
--- /dev/null
+++ b/gfx/angle/src/libANGLE/renderer/d3d/d3d11/StreamProducerD3DTexture.h
@@ -0,0 +1,44 @@
+//
+// 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.
+//
+
+// StreamProducerD3DTexture.h: Interface for a D3D11 texture stream producer
+
+#ifndef LIBANGLE_RENDERER_D3D_D3D11_STREAM11_H_
+#define LIBANGLE_RENDERER_D3D_D3D11_STREAM11_H_
+
+#include "libANGLE/renderer/StreamProducerImpl.h"
+
+namespace rx
+{
+class Renderer11;
+
+class StreamProducerD3DTexture : public StreamProducerImpl
+{
+  public:
+    StreamProducerD3DTexture(Renderer11 *renderer);
+    ~StreamProducerD3DTexture() override;
+
+    egl::Error validateD3DTexture(void *pointer,
+                                  const egl::AttributeMap &attributes) const override;
+    void postD3DTexture(void *pointer, const egl::AttributeMap &attributes) override;
+    egl::Stream::GLTextureDescription getGLFrameDescription(int planeIndex) override;
+
+    // Gets a pointer to the internal D3D texture
+    ID3D11Texture2D *getD3DTexture();
+
+    // Gets the slice index for the D3D texture that the frame is in
+    UINT getArraySlice();
+
+  private:
+    Renderer11 *mRenderer;
+
+    ID3D11Texture2D *mTexture;
+    UINT mArraySlice;
+    UINT mPlaneOffset;
+};
+}  // namespace rx
+
+#endif  // LIBANGLE_RENDERER_D3D_D3D11_STREAM11_H_
deleted file mode 100644
--- a/gfx/angle/src/libANGLE/renderer/d3d/d3d11/StreamProducerNV12.cpp
+++ /dev/null
@@ -1,160 +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.
-//
-
-// StreamProducerNV12.cpp: Implements the stream producer for NV12 textures
-
-#include "libANGLE/renderer/d3d/d3d11/StreamProducerNV12.h"
-
-#include "common/utilities.h"
-#include "libANGLE/renderer/d3d/d3d11/Renderer11.h"
-#include "libANGLE/renderer/d3d/d3d11/renderer11_utils.h"
-
-namespace rx
-{
-
-static egl::Stream::GLTextureDescription getGLDescFromTex(ID3D11Texture2D* tex,
-                                                          UINT planeIndex,
-                                                          const char** const out_error)
-{
-    *out_error = "Undocumented error";
-
-    egl::Stream::GLTextureDescription ret = { 0 };
-    if (!tex)
-    {
-        *out_error = "Texture is null";
-        return ret;
-    }
-
-    D3D11_TEXTURE2D_DESC desc;
-    tex->GetDesc(&desc);
-
-    if (desc.Width < 1 || desc.Height < 1)
-    {
-        *out_error = "Width or height < 1";
-        return ret;
-    }
-
-    ret.width = desc.Width;
-    ret.height = desc.Height;
-    ret.mipLevels = 0;
-
-    UINT maxPlaneIndex = 0;
-    switch (desc.Format) {
-    case DXGI_FORMAT_NV12:
-        // The UV plane of NV12 textures has half the width/height of the Y plane
-        if ((desc.Width % 2) != 0 || (desc.Height % 2) != 0)
-        {
-            *out_error = "NV12 tetxures must have even width and height.";
-            break; // Bad width/height.
-        }
-
-        maxPlaneIndex = 1;
-        if (planeIndex == 0)
-        {
-            ret.internalFormat = GL_R8;
-        }
-        else
-        {
-            ret.internalFormat = GL_RG8;
-            ret.width  /= 2;
-            ret.height /= 2;
-        }
-        break;
-
-    case DXGI_FORMAT_R8_UNORM:
-        ret.internalFormat = GL_R8;
-        break;
-    case DXGI_FORMAT_R8G8_UNORM:
-        ret.internalFormat = GL_RG8;
-        break;
-    case DXGI_FORMAT_R8G8B8A8_UNORM:
-        ret.internalFormat = GL_RGBA8;
-        break;
-    case DXGI_FORMAT_B8G8R8A8_UNORM:
-        ret.internalFormat = GL_BGRA8_EXT;
-        break;
-
-    default:
-        *out_error = "Unsupported format";
-        return ret;
-    }
-
-    if (planeIndex > maxPlaneIndex)
-    {
-        // Just kidding, there's no plane out there.
-        ret.internalFormat = 0;
-        *out_error = "Plane out of range";
-    }
-
-    return ret;
-}
-
-
-StreamProducerNV12::StreamProducerNV12(Renderer11 *renderer)
-    : mRenderer(renderer), mTexture(nullptr), mArraySlice(0), mPlaneOffset(0)
-{
-}
-
-StreamProducerNV12::~StreamProducerNV12()
-{
-    SafeRelease(mTexture);
-}
-
-egl::Error StreamProducerNV12::validateD3DNV12Texture(void *pointer, const egl::AttributeMap &attributes) const
-{
-    ID3D11Texture2D *textureD3D = static_cast<ID3D11Texture2D *>(pointer);
-
-    // Check that the texture originated from our device
-    ID3D11Device *device;
-    textureD3D->GetDevice(&device);
-    if (device != mRenderer->getDevice())
-    {
-        return egl::EglBadParameter() << "Texture not created on ANGLE D3D device";
-    }
-
-    const auto planeId = static_cast<UINT>(attributes.get(EGL_NATIVE_BUFFER_PLANE_OFFSET_IMG, 0));
-    const char* errorText;
-    const auto glDesc = getGLDescFromTex(textureD3D, planeId, &errorText);
-    if (!glDesc.internalFormat)
-    {
-        return egl::EglBadParameter() << errorText;
-    }
-
-    return egl::NoError();
-}
-
-void StreamProducerNV12::postD3DNV12Texture(void *pointer, const egl::AttributeMap &attributes)
-{
-    ASSERT(pointer != nullptr);
-    ID3D11Texture2D *textureD3D = static_cast<ID3D11Texture2D *>(pointer);
-
-    // Release the previous texture if there is one
-    SafeRelease(mTexture);
-
-    mTexture = textureD3D;
-    mTexture->AddRef();
-    mPlaneOffset = static_cast<UINT>(attributes.get(EGL_NATIVE_BUFFER_PLANE_OFFSET_IMG, 0));
-    mArraySlice = static_cast<UINT>(attributes.get(EGL_D3D_TEXTURE_SUBRESOURCE_ID_ANGLE, 0));
-}
-
-egl::Stream::GLTextureDescription StreamProducerNV12::getGLFrameDescription(int planeIndex)
-{
-    const char* errorText;
-    return getGLDescFromTex(mTexture, static_cast<UINT>(planeIndex + mPlaneOffset),
-                            &errorText);
-}
-
-ID3D11Texture2D *StreamProducerNV12::getD3DTexture()
-{
-    return mTexture;
-}
-
-UINT StreamProducerNV12::getArraySlice()
-{
-    return mArraySlice;
-}
-
-}  // namespace rx
deleted file mode 100644
--- a/gfx/angle/src/libANGLE/renderer/d3d/d3d11/StreamProducerNV12.h
+++ /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.
-//
-
-// StreamProducerNV12.h: Interface for a NV12 texture stream producer
-
-#ifndef LIBANGLE_RENDERER_D3D_D3D11_STREAM11_H_
-#define LIBANGLE_RENDERER_D3D_D3D11_STREAM11_H_
-
-#include "libANGLE/renderer/StreamProducerImpl.h"
-
-namespace rx
-{
-class Renderer11;
-
-class StreamProducerNV12 : public StreamProducerImpl
-{
-  public:
-    StreamProducerNV12(Renderer11 *renderer);
-    ~StreamProducerNV12() override;
-
-    egl::Error validateD3DNV12Texture(void *pointer, const egl::AttributeMap &attributes) const override;
-    void postD3DNV12Texture(void *pointer, const egl::AttributeMap &attributes) override;
-    egl::Stream::GLTextureDescription getGLFrameDescription(int planeIndex) override;
-
-    // Gets a pointer to the internal D3D texture
-    ID3D11Texture2D *getD3DTexture();
-
-    // Gets the slice index for the D3D texture that the frame is in
-    UINT getArraySlice();
-
-  private:
-    Renderer11 *mRenderer;
-
-    ID3D11Texture2D *mTexture;
-    UINT mArraySlice;
-    UINT mPlaneOffset;
-};
-}  // namespace rx
-
-#endif  // LIBANGLE_RENDERER_D3D_D3D11_STREAM11_H_
--- a/gfx/angle/src/libANGLE/renderer/d3d/d3d11/SwapChain11.cpp
+++ b/gfx/angle/src/libANGLE/renderer/d3d/d3d11/SwapChain11.cpp
@@ -208,23 +208,17 @@ EGLint SwapChain11::resetOffscreenColorB
     // See EGL_ANGLE_d3d_share_handle_client_buffer and EGL_ANGLE_d3d_texture_client_buffer
     if (mAppCreatedShareHandle || mD3DTexture != nullptr)
     {
         if (mAppCreatedShareHandle)
         {
             ID3D11Resource *tempResource11;
             HRESULT result = device->OpenSharedResource(mShareHandle, __uuidof(ID3D11Resource),
                                                         (void **)&tempResource11);
-
-            if (FAILED(result))
-            {
-                ERR() << "Could not open shared handle. " << gl::FmtHR(result);
-                release();
-                return EGL_BAD_SURFACE;
-            }
+            ASSERT(SUCCEEDED(result));
 
             mOffscreenTexture.set(d3d11::DynamicCastComObject<ID3D11Texture2D>(tempResource11),
                                   backbufferFormatInfo);
             SafeRelease(tempResource11);
         }
         else if (mD3DTexture != nullptr)
         {
             mOffscreenTexture.set(d3d11::DynamicCastComObject<ID3D11Texture2D>(mD3DTexture),
@@ -824,17 +818,17 @@ EGLint SwapChain11::copyOffscreenToBackb
 
     d3d11::SetPositionTexCoordVertex(&vertices[0], x1, y1, u1, v1);
     d3d11::SetPositionTexCoordVertex(&vertices[1], x1, y2, u1, v2);
     d3d11::SetPositionTexCoordVertex(&vertices[2], x2, y1, u2, v1);
     d3d11::SetPositionTexCoordVertex(&vertices[3], x2, y2, u2, v2);
 
     deviceContext->Unmap(mQuadVB.get(), 0);
 
-    auto stateManager = mRenderer->getStateManager();
+    StateManager11 *stateManager = mRenderer->getStateManager();
 
     constexpr UINT stride = sizeof(d3d11::PositionTexCoordVertex);
     stateManager->setSingleVertexBuffer(&mQuadVB, stride, 0);
 
     // Apply state
     stateManager->setDepthStencilState(nullptr, 0xFFFFFFFF);
     stateManager->setSimpleBlendState(nullptr);
     stateManager->setRasterizerState(&mPassThroughRS);
@@ -998,21 +992,36 @@ const d3d11::SharedSRV &SwapChain11::get
     return mDepthStencilSRView;
 }
 
 const TextureHelper11 &SwapChain11::getDepthStencilTexture()
 {
     return mDepthStencilTexture;
 }
 
+void *SwapChain11::getKeyedMutex()
+{
+    return mKeyedMutex;
+}
+
 void SwapChain11::recreate()
 {
     // possibly should use this method instead of reset
 }
 
+RenderTargetD3D *SwapChain11::getColorRenderTarget()
+{
+    return &mColorRenderTarget;
+}
+
+RenderTargetD3D *SwapChain11::getDepthStencilRenderTarget()
+{
+    return &mDepthStencilRenderTarget;
+}
+
 egl::Error SwapChain11::getSyncValues(EGLuint64KHR *ust, EGLuint64KHR *msc, EGLuint64KHR *sbc)
 {
     if (!mSwapChain)
     {
         return egl::EglNotInitialized() << "Swap chain uninitialized";
     }
 
     DXGI_FRAME_STATISTICS stats = {};
--- a/gfx/angle/src/libANGLE/renderer/d3d/d3d11/SwapChain11.h
+++ b/gfx/angle/src/libANGLE/renderer/d3d/d3d11/SwapChain11.h
@@ -24,46 +24,46 @@ class SwapChain11 final : public SwapCha
     SwapChain11(Renderer11 *renderer,
                 NativeWindow11 *nativeWindow,
                 HANDLE shareHandle,
                 IUnknown *d3dTexture,
                 GLenum backBufferFormat,
                 GLenum depthBufferFormat,
                 EGLint orientation,
                 EGLint samples);
-    virtual ~SwapChain11();
+    ~SwapChain11() override;
 
     EGLint resize(const gl::Context *context,
                   EGLint backbufferWidth,
                   EGLint backbufferHeight) override;
     EGLint reset(const gl::Context *context,
                  EGLint backbufferWidth,
                  EGLint backbufferHeight,
                  EGLint swapInterval) override;
     EGLint swapRect(const gl::Context *context,
                     EGLint x,
                     EGLint y,
                     EGLint width,
                     EGLint height) override;
     void recreate() override;
 
-    RenderTargetD3D *getColorRenderTarget() override { return &mColorRenderTarget; }
-    RenderTargetD3D *getDepthStencilRenderTarget() override { return &mDepthStencilRenderTarget; }
+    RenderTargetD3D *getColorRenderTarget() override;
+    RenderTargetD3D *getDepthStencilRenderTarget() override;
 
     const TextureHelper11 &getOffscreenTexture();
     const d3d11::RenderTargetView &getRenderTarget();
     const d3d11::SharedSRV &getRenderTargetShaderResource();
 
     const TextureHelper11 &getDepthStencilTexture();
     const d3d11::DepthStencilView &getDepthStencil();
     const d3d11::SharedSRV &getDepthStencilShaderResource();
 
     EGLint getWidth() const { return mWidth; }
     EGLint getHeight() const { return mHeight; }
-    void *getKeyedMutex() override { return mKeyedMutex; }
+    void *getKeyedMutex() override;
     EGLint getSamples() const { return mEGLSamples; }
 
     egl::Error getSyncValues(EGLuint64KHR *ust, EGLuint64KHR *msc, EGLuint64KHR *sbc) override;
 
   private:
     void release();
     void initPassThroughResources();
 
--- a/gfx/angle/src/libANGLE/renderer/d3d/d3d11/TextureStorage11.cpp
+++ b/gfx/angle/src/libANGLE/renderer/d3d/d3d11/TextureStorage11.cpp
@@ -9,29 +9,29 @@
 // texture.
 
 #include "libANGLE/renderer/d3d/d3d11/TextureStorage11.h"
 
 #include <tuple>
 
 #include "common/MemoryBuffer.h"
 #include "common/utilities.h"
+#include "libANGLE/ImageIndex.h"
 #include "libANGLE/formatutils.h"
-#include "libANGLE/ImageIndex.h"
-#include "libANGLE/renderer/d3d/d3d11/Blit11.h"
-#include "libANGLE/renderer/d3d/d3d11/formatutils11.h"
-#include "libANGLE/renderer/d3d/d3d11/Image11.h"
-#include "libANGLE/renderer/d3d/d3d11/Renderer11.h"
-#include "libANGLE/renderer/d3d/d3d11/renderer11_utils.h"
-#include "libANGLE/renderer/d3d/d3d11/RenderTarget11.h"
-#include "libANGLE/renderer/d3d/d3d11/StreamProducerNV12.h"
-#include "libANGLE/renderer/d3d/d3d11/SwapChain11.h"
-#include "libANGLE/renderer/d3d/d3d11/texture_format_table.h"
 #include "libANGLE/renderer/d3d/EGLImageD3D.h"
 #include "libANGLE/renderer/d3d/TextureD3D.h"
+#include "libANGLE/renderer/d3d/d3d11/Blit11.h"
+#include "libANGLE/renderer/d3d/d3d11/Image11.h"
+#include "libANGLE/renderer/d3d/d3d11/RenderTarget11.h"
+#include "libANGLE/renderer/d3d/d3d11/Renderer11.h"
+#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)
@@ -59,27 +59,55 @@ void InvalidateRenderTargetContainer(con
     for (auto &rt : *renderTargetContainer)
     {
         InvalidateRenderTarget(context, GetRenderTarget(&rt));
     }
 }
 
 }  // anonymous namespace
 
-TextureStorage11::SRVKey::SRVKey(int baseLevel, int mipLevels, bool swizzle, bool dropStencil)
+TextureStorage11::SamplerKey::SamplerKey()
+    : baseLevel(0), mipLevels(0), swizzle(false), dropStencil(false)
+{
+}
+
+TextureStorage11::SamplerKey::SamplerKey(int baseLevel,
+                                         int mipLevels,
+                                         bool swizzle,
+                                         bool dropStencil)
     : baseLevel(baseLevel), mipLevels(mipLevels), swizzle(swizzle), dropStencil(dropStencil)
 {
 }
 
-bool TextureStorage11::SRVKey::operator<(const SRVKey &rhs) const
+bool TextureStorage11::SamplerKey::operator<(const SamplerKey &rhs) const
 {
     return std::tie(baseLevel, mipLevels, swizzle, dropStencil) <
            std::tie(rhs.baseLevel, rhs.mipLevels, rhs.swizzle, rhs.dropStencil);
 }
 
+TextureStorage11::ImageKey::ImageKey()
+    : level(0), layered(false), layer(0), access(GL_READ_ONLY), format(GL_R32UI)
+{
+}
+
+TextureStorage11::ImageKey::ImageKey(int level,
+                                     bool layered,
+                                     int layer,
+                                     GLenum access,
+                                     GLenum format)
+    : level(level), layered(layered), layer(layer), access(access), format(format)
+{
+}
+
+bool TextureStorage11::ImageKey::operator<(const ImageKey &rhs) const
+{
+    return std::tie(level, layered, layer, access, format) <
+           std::tie(rhs.level, rhs.layered, rhs.layer, rhs.access, rhs.format);
+}
+
 TextureStorage11::TextureStorage11(Renderer11 *renderer,
                                    UINT bindFlags,
                                    UINT miscFlags,
                                    GLenum internalFormat)
     : mRenderer(renderer),
       mTopLevel(0),
       mMipLevels(0),
       mFormatInfo(d3d11::Format::Get(internalFormat, mRenderer->getRenderer11DeviceCaps())),
@@ -89,30 +117,36 @@ TextureStorage11::TextureStorage11(Rende
       mDropStencilTexture(),
       mBindFlags(bindFlags),
       mMiscFlags(miscFlags)
 {
 }
 
 TextureStorage11::~TextureStorage11()
 {
-    mSrvCache.clear();
+    mSrvCacheForSampler.clear();
 }
 
 DWORD TextureStorage11::GetTextureBindFlags(GLenum internalFormat,
                                             const Renderer11DeviceCaps &renderer11DeviceCaps,
                                             bool renderTarget)
 {
     UINT bindFlags = 0;
 
     const d3d11::Format &formatInfo = d3d11::Format::Get(internalFormat, renderer11DeviceCaps);
     if (formatInfo.srvFormat != DXGI_FORMAT_UNKNOWN)
     {
         bindFlags |= D3D11_BIND_SHADER_RESOURCE;
     }
+    if (formatInfo.uavFormat != DXGI_FORMAT_UNKNOWN &&
+        renderer11DeviceCaps.featureLevel >= d3d11_gl::GetMinimumFeatureLevelForES31())
+    {
+        // If we find performance issues later on some specific GPUs, this may be the cause.
+        bindFlags |= D3D11_BIND_UNORDERED_ACCESS;
+    }
     if (formatInfo.dsvFormat != DXGI_FORMAT_UNKNOWN)
     {
         bindFlags |= D3D11_BIND_DEPTH_STENCIL;
     }
     if (formatInfo.rtvFormat != DXGI_FORMAT_UNKNOWN && renderTarget)
     {
         bindFlags |= D3D11_BIND_RENDER_TARGET;
     }
@@ -186,28 +220,34 @@ int TextureStorage11::getLevelHeight(int
     return std::max(static_cast<int>(mTextureHeight) >> mipLevel, 1);
 }
 
 int TextureStorage11::getLevelDepth(int mipLevel) const
 {
     return std::max(static_cast<int>(mTextureDepth) >> mipLevel, 1);
 }
 
+gl::Error TextureStorage11::getMippedResource(const gl::Context *context,
+                                              const TextureHelper11 **outResource)
+{
+    return getResource(context, outResource);
+}
+
 UINT TextureStorage11::getSubresourceIndex(const gl::ImageIndex &index) const
 {
     UINT mipSlice    = static_cast<UINT>(index.mipIndex + mTopLevel);
     UINT arraySlice  = static_cast<UINT>(index.hasLayer() ? index.layerIndex : 0);
     UINT subresource = D3D11CalcSubresource(mipSlice, arraySlice, mMipLevels);
     ASSERT(subresource != std::numeric_limits<UINT>::max());
     return subresource;
 }
 
-gl::Error TextureStorage11::getSRV(const gl::Context *context,
-                                   const gl::TextureState &textureState,
-                                   const d3d11::SharedSRV **outSRV)
+gl::Error TextureStorage11::getSRVForSampler(const gl::Context *context,
+                                             const gl::TextureState &textureState,
+                                             const d3d11::SharedSRV **outSRV)
 {
     // Make sure to add the level offset for our tiny compressed texture workaround
     const GLuint effectiveBaseLevel = textureState.getEffectiveBaseLevel();
     bool swizzleRequired            = textureState.swizzleRequired();
     bool mipmapping                 = gl::IsMipmapFiltered(textureState.getSamplerState());
     unsigned int mipLevels =
         mipmapping ? (textureState.getEffectiveMaxLevel() - effectiveBaseLevel + 1) : 1;
 
@@ -238,50 +278,50 @@ gl::Error TextureStorage11::getSRV(const
     // 2. this is a stencil texture.
     bool hasStencil = (mFormatInfo.format().stencilBits > 0);
     // 3. the texture has a 1x1 or 2x2 mip.
     int effectiveTopLevel = effectiveBaseLevel + mipLevels - 1;
     bool hasSmallMips =
         (getLevelWidth(effectiveTopLevel) <= 2 || getLevelHeight(effectiveTopLevel) <= 2);
 
     bool useDropStencil = (workaround && hasStencil && hasSmallMips);
-    SRVKey key(effectiveBaseLevel, mipLevels, swizzleRequired, useDropStencil);
+    SamplerKey key(effectiveBaseLevel, mipLevels, swizzleRequired, useDropStencil);
     if (useDropStencil)
     {
         // Ensure drop texture gets created.
         DropStencil result = DropStencil::CREATED;
         ANGLE_TRY_RESULT(ensureDropStencilTexture(context), result);
 
         // Clear the SRV cache if necessary.
         // TODO(jmadill): Re-use find query result.
-        auto srvEntry = mSrvCache.find(key);
-        if (result == DropStencil::CREATED && srvEntry != mSrvCache.end())
+        auto srvEntry = mSrvCacheForSampler.find(key);
+        if (result == DropStencil::CREATED && srvEntry != mSrvCacheForSampler.end())
         {
-            mSrvCache.erase(key);
+            mSrvCacheForSampler.erase(key);
         }
     }
 
-    ANGLE_TRY(getCachedOrCreateSRV(context, key, outSRV));
+    ANGLE_TRY(getCachedOrCreateSRVForSampler(context, key, outSRV));
 
     return gl::NoError();
 }
 
-gl::Error TextureStorage11::getCachedOrCreateSRV(const gl::Context *context,
-                                                 const SRVKey &key,
-                                                 const d3d11::SharedSRV **outSRV)
+gl::Error TextureStorage11::getCachedOrCreateSRVForSampler(const gl::Context *context,
+                                                           const SamplerKey &key,
+                                                           const d3d11::SharedSRV **outSRV)
 {
-    auto iter = mSrvCache.find(key);
-    if (iter != mSrvCache.end())
+    auto iter = mSrvCacheForSampler.find(key);
+    if (iter != mSrvCacheForSampler.end())
     {
         *outSRV = &iter->second;
         return gl::NoError();
     }
 
     const TextureHelper11 *texture = nullptr;
-    DXGI_FORMAT format      = DXGI_FORMAT_UNKNOWN;
+    DXGI_FORMAT format             = DXGI_FORMAT_UNKNOWN;
 
     if (key.swizzle)
     {
         const auto &swizzleFormat =
             mFormatInfo.getSwizzleFormat(mRenderer->getRenderer11DeviceCaps());
         ASSERT(!key.dropStencil || swizzleFormat.format().stencilBits == 0);
         ANGLE_TRY(getSwizzleTexture(&texture));
         format = swizzleFormat.srvFormat;
@@ -295,19 +335,19 @@ gl::Error TextureStorage11::getCachedOrC
     else
     {
         ANGLE_TRY(getResource(context, &texture));
         format = mFormatInfo.srvFormat;
     }
 
     d3d11::SharedSRV srv;
 
-    ANGLE_TRY(createSRV(context, key.baseLevel, key.mipLevels, format, *texture, &srv));
-
-    const auto &insertIt = mSrvCache.insert(std::make_pair(key, std::move(srv)));
+    ANGLE_TRY(createSRVForSampler(context, key.baseLevel, key.mipLevels, format, *texture, &srv));
+
+    const auto &insertIt = mSrvCacheForSampler.insert(std::make_pair(key, std::move(srv)));
     *outSRV              = &insertIt.first->second;
 
     return gl::NoError();
 }
 
 gl::Error TextureStorage11::getSRVLevel(const gl::Context *context,
                                         int mipLevel,
                                         bool blitSRV,
@@ -327,18 +367,18 @@ gl::Error TextureStorage11::getSRVLevel(
         }
         else
         {
             const TextureHelper11 *resource = nullptr;
             ANGLE_TRY(getResource(context, &resource));
 
             DXGI_FORMAT resourceFormat =
                 blitSRV ? mFormatInfo.blitSRVFormat : mFormatInfo.srvFormat;
-            ANGLE_TRY(
-                createSRV(context, mipLevel, 1, resourceFormat, *resource, &levelSRVs[mipLevel]));
+            ANGLE_TRY(createSRVForSampler(context, mipLevel, 1, resourceFormat, *resource,
+                                          &levelSRVs[mipLevel]));
         }
     }
 
     *outSRV = &levelSRVs[mipLevel];
 
     return gl::NoError();
 }
 
@@ -361,19 +401,83 @@ gl::Error TextureStorage11::getSRVLevels
     if (mRenderer->getWorkarounds().zeroMaxLodWorkaround)
     {
         // We must ensure that the level zero texture is in sync with mipped texture.
         ANGLE_TRY(useLevelZeroWorkaroundTexture(context, mipLevels == 1));
     }
 
     // TODO(jmadill): Assert we don't need to drop stencil.
 
-    SRVKey key(baseLevel, mipLevels, false, false);
-    ANGLE_TRY(getCachedOrCreateSRV(context, key, outSRV));
-
+    SamplerKey key(baseLevel, mipLevels, false, false);
+    ANGLE_TRY(getCachedOrCreateSRVForSampler(context, key, outSRV));
+
+    return gl::NoError();
+}
+
+gl::Error TextureStorage11::getSRVForImage(const gl::Context *context,
+                                           const gl::ImageUnit &imageUnit,
+                                           const d3d11::SharedSRV **outSRV)
+{
+    // TODO(Xinghua.cao@intel.com): Add solution to handle swizzle required.
+    ImageKey key(imageUnit.level, imageUnit.layered, imageUnit.layer, imageUnit.access,
+                 imageUnit.format);
+    ANGLE_TRY(getCachedOrCreateSRVForImage(context, key, outSRV));
+    return gl::NoError();
+}
+
+gl::Error TextureStorage11::getCachedOrCreateSRVForImage(const gl::Context *context,
+                                                         const ImageKey &key,
+                                                         const d3d11::SharedSRV **outSRV)
+{
+    auto iter = mSrvCacheForImage.find(key);
+    if (iter != mSrvCacheForImage.end())
+    {
+        *outSRV = &iter->second;
+        return gl::NoError();
+    }
+    const TextureHelper11 *texture = nullptr;
+    ANGLE_TRY(getResource(context, &texture));
+    DXGI_FORMAT format =
+        d3d11::Format::Get(key.format, mRenderer->getRenderer11DeviceCaps()).srvFormat;
+    d3d11::SharedSRV srv;
+    ANGLE_TRY(createSRVForImage(context, key.level, format, *texture, &srv));
+    const auto &insertIt = mSrvCacheForImage.insert(std::make_pair(key, std::move(srv)));
+    *outSRV              = &insertIt.first->second;
+    return gl::NoError();
+}
+
+gl::Error TextureStorage11::getUAVForImage(const gl::Context *context,
+                                           const gl::ImageUnit &imageUnit,
+                                           const d3d11::SharedUAV **outUAV)
+{
+    // TODO(Xinghua.cao@intel.com): Add solution to handle swizzle required.
+    ImageKey key(imageUnit.level, imageUnit.layered, imageUnit.layer, imageUnit.access,
+                 imageUnit.format);
+    ANGLE_TRY(getCachedOrCreateUAVForImage(context, key, outUAV));
+    return gl::NoError();
+}
+
+gl::Error TextureStorage11::getCachedOrCreateUAVForImage(const gl::Context *context,
+                                                         const ImageKey &key,
+                                                         const d3d11::SharedUAV **outUAV)
+{
+    auto iter = mUavCacheForImage.find(key);
+    if (iter != mUavCacheForImage.end())
+    {
+        *outUAV = &iter->second;
+        return gl::NoError();
+    }
+    const TextureHelper11 *texture = nullptr;
+    ANGLE_TRY(getResource(context, &texture));
+    DXGI_FORMAT format =
+        d3d11::Format::Get(key.format, mRenderer->getRenderer11DeviceCaps()).uavFormat;
+    d3d11::SharedUAV uav;
+    ANGLE_TRY(createUAVForImage(context, key.level, format, *texture, &uav));
+    const auto &insertIt = mUavCacheForImage.insert(std::make_pair(key, std::move(uav)));
+    *outUAV              = &insertIt.first->second;
     return gl::NoError();
 }
 
 const d3d11::Format &TextureStorage11::getFormatSet() const
 {
     return mFormatInfo;
 }
 
@@ -468,17 +572,17 @@ gl::Error TextureStorage11::updateSubres
 
     ASSERT(dstTexture->valid());
 
     const d3d11::DXGIFormatSize &dxgiFormatSizeInfo =
         d3d11::GetDXGIFormatSizeInfo(mFormatInfo.texFormat);
     if (!fullCopy && mFormatInfo.dsvFormat != DXGI_FORMAT_UNKNOWN)
     {
         // CopySubresourceRegion cannot copy partial depth stencils, use the blitter instead
-        Blit11 *blitter        = mRenderer->getBlitter();
+        Blit11 *blitter = mRenderer->getBlitter();
         return blitter->copyDepthStencil(srcTexture, sourceSubresource, copyArea, texSize,
                                          *dstTexture, dstSubresource, copyArea, texSize, nullptr);
     }
 
     D3D11_BOX srcBox;
     srcBox.left = copyArea.x;
     srcBox.top  = copyArea.y;
     srcBox.right =
@@ -565,17 +669,17 @@ gl::Error TextureStorage11::generateMipm
     markLevelDirty(destIndex.mipIndex);
 
     RenderTargetD3D *source = nullptr;
     ANGLE_TRY(getRenderTarget(context, sourceIndex, &source));
 
     RenderTargetD3D *dest = nullptr;
     ANGLE_TRY(getRenderTarget(context, destIndex, &dest));
 
-    auto rt11                              = GetAs<RenderTarget11>(source);
+    RenderTarget11 *rt11                   = GetAs<RenderTarget11>(source);
     const d3d11::SharedSRV &sourceSRV      = rt11->getBlitShaderResourceView();
     const d3d11::RenderTargetView &destRTV = rt11->getRenderTargetView();
 
     gl::Box sourceArea(0, 0, 0, source->getWidth(), source->getHeight(), source->getDepth());
     gl::Extents sourceSize(source->getWidth(), source->getHeight(), source->getDepth());
 
     gl::Box destArea(0, 0, 0, dest->getWidth(), dest->getHeight(), dest->getDepth());
     gl::Extents destSize(dest->getWidth(), dest->getHeight(), dest->getDepth());
@@ -593,106 +697,106 @@ void TextureStorage11::verifySwizzleExis
     {
         ASSERT(mSwizzleCache[level] == swizzleState);
     }
 }
 
 void TextureStorage11::clearSRVCache()
 {
     markDirty();
-    mSrvCache.clear();
+    mSrvCacheForSampler.clear();
 
     for (size_t level = 0; level < mLevelSRVs.size(); level++)
     {
         mLevelSRVs[level].reset();
         mLevelBlitSRVs[level].reset();
     }
 }
 
 gl::Error TextureStorage11::copyToStorage(const gl::Context *context, TextureStorage *destStorage)
 {
     ASSERT(destStorage);
 
     const TextureHelper11 *sourceResouce = nullptr;
     ANGLE_TRY(getResource(context, &sourceResouce));
 
-    TextureStorage11 *dest11     = GetAs<TextureStorage11>(destStorage);
+    TextureStorage11 *dest11            = GetAs<TextureStorage11>(destStorage);
     const TextureHelper11 *destResource = nullptr;
     ANGLE_TRY(dest11->getResource(context, &destResource));
 
     ID3D11DeviceContext *immediateContext = mRenderer->getDeviceContext();
     immediateContext->CopyResource(destResource->get(), sourceResouce->get());
 
     dest11->markDirty();
 
     return gl::NoError();
 }
 
 gl::Error TextureStorage11::setData(const gl::Context *context,
                                     const gl::ImageIndex &index,
                                     ImageD3D *image,
                                     const gl::Box *destBox,
-                                    GLenum inputType,
+                                    GLenum type,
                                     const gl::PixelUnpackState &unpack,
                                     const uint8_t *pixelData)
 {
     ASSERT(!image->isDirty());
 
     markLevelDirty(index.mipIndex);
 
     const TextureHelper11 *resource = nullptr;
     ANGLE_TRY(getResource(context, &resource));
     ASSERT(resource && resource->valid());
 
     UINT destSubresource = getSubresourceIndex(index);
 
-    const auto sizedInputFormat = image->getSizedInputFormat(inputType);
-    const gl::InternalFormat &inputFormat = gl::GetSizedInternalFormatInfo(sizedInputFormat);
+    const gl::InternalFormat &internalFormatInfo =
+        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(inputFormat.depthBits == 0 || fullUpdate);
+    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
     // different logic. Will implemnent this in a follow-up patch, and ensure we do not use SetData
     // with compressed formats in the calling logic.
-    ASSERT(!inputFormat.compressed);
+    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(
-        inputFormat.computeRowPitch(width, unpack.alignment, unpack.rowLength),
+        internalFormatInfo.computeRowPitch(type, width, unpack.alignment, unpack.rowLength),
         srcRowPitch);
     GLuint srcDepthPitch = 0;
-    ANGLE_TRY_RESULT(gl::InternalFormat::computeDepthPitch(height, unpack.imageHeight, srcRowPitch),
+    ANGLE_TRY_RESULT(internalFormatInfo.computeDepthPitch(height, unpack.imageHeight, srcRowPitch),
                      srcDepthPitch);
     GLuint srcSkipBytes = 0;
     ANGLE_TRY_RESULT(
-        inputFormat.computeSkipBytes(srcRowPitch, srcDepthPitch, unpack, index.is3D()),
+        internalFormatInfo.computeSkipBytes(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;
 
     UINT bufferRowPitch   = static_cast<unsigned int>(outputPixelSize) * width;
     UINT bufferDepthPitch = bufferRowPitch * height;
 
-    const size_t neededSize        = bufferDepthPitch * depth;
+    const size_t neededSize               = bufferDepthPitch * depth;
     angle::MemoryBuffer *conversionBuffer = nullptr;
-    const uint8_t *data            = nullptr;
-
-    LoadImageFunctionInfo loadFunctionInfo = d3d11Format.getLoadFunctions()(inputType);
+    const uint8_t *data                   = nullptr;
+
+    LoadImageFunctionInfo loadFunctionInfo = d3d11Format.getLoadFunctions()(type);
     if (loadFunctionInfo.requiresConversion)
     {
         ANGLE_TRY(mRenderer->getScratchMemoryBuffer(neededSize, &conversionBuffer));
         loadFunctionInfo.loadFunction(width, height, depth, pixelData + srcSkipBytes, srcRowPitch,
                                       srcDepthPitch, conversionBuffer->data(), bufferRowPitch,
                                       bufferDepthPitch);
         data = conversionBuffer->data();
     }
@@ -744,18 +848,18 @@ TextureStorage11_2D::TextureStorage11_2D
       mTexture(swapchain->getOffscreenTexture()),
       mLevelZeroTexture(),
       mLevelZeroRenderTarget(nullptr),
       mUseLevelZeroTexture(false),
       mSwizzleTexture()
 {
     for (unsigned int i = 0; i < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS; i++)
     {
-        mAssociatedImages[i]     = nullptr;
-        mRenderTarget[i]         = nullptr;
+        mAssociatedImages[i] = nullptr;
+        mRenderTarget[i]     = nullptr;
     }
 
     D3D11_TEXTURE2D_DESC texDesc;
     mTexture.getDesc(&texDesc);
     mMipLevels     = texDesc.MipLevels;
     mTextureWidth  = texDesc.Width;
     mTextureHeight = texDesc.Height;
     mTextureDepth  = 1;
@@ -781,18 +885,18 @@ TextureStorage11_2D::TextureStorage11_2D
       mHasKeyedMutex(false),
       mLevelZeroTexture(),
       mLevelZeroRenderTarget(nullptr),
       mUseLevelZeroTexture(hintLevelZeroOnly && levels > 1),
       mSwizzleTexture()
 {
     for (unsigned int i = 0; i < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS; i++)
     {
-        mAssociatedImages[i]     = nullptr;
-        mRenderTarget[i]         = nullptr;
+        mAssociatedImages[i] = nullptr;
+        mRenderTarget[i]     = nullptr;
     }
 
     d3d11::MakeValidSize(false, mFormatInfo.texFormat, &width, &height, &mTopLevel);
     mMipLevels     = mTopLevel + levels;
     mTextureWidth  = width;
     mTextureHeight = height;
     mTextureDepth  = 1;
 
@@ -1151,22 +1255,22 @@ gl::Error TextureStorage11_2D::getRender
     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();
 }
 
-gl::Error TextureStorage11_2D::createSRV(const gl::Context *context,
-                                         int baseLevel,
-                                         int mipLevels,
-                                         DXGI_FORMAT format,
-                                         const TextureHelper11 &texture,
-                                         d3d11::SharedSRV *outSRV) const
+gl::Error TextureStorage11_2D::createSRVForSampler(const gl::Context *context,
+                                                   int baseLevel,
+                                                   int mipLevels,
+                                                   DXGI_FORMAT format,
+                                                   const TextureHelper11 &texture,
+                                                   d3d11::SharedSRV *outSRV)
 {
     ASSERT(outSRV);
 
     D3D11_SHADER_RESOURCE_VIEW_DESC srvDesc;
     srvDesc.Format                    = format;
     srvDesc.ViewDimension             = D3D11_SRV_DIMENSION_TEXTURE2D;
     srvDesc.Texture2D.MostDetailedMip = mTopLevel + baseLevel;
     srvDesc.Texture2D.MipLevels       = mipLevels;
@@ -1178,33 +1282,66 @@ gl::Error TextureStorage11_2D::createSRV
         ASSERT(mTopLevel == 0);
         ASSERT(baseLevel == 0);
         // This code also assumes that the incoming texture equals either mLevelZeroTexture or
         // mTexture.
 
         if (mipLevels == 1 && mMipLevels > 1)
         {
             // We must use a SRV on the level-zero-only texture.
-            ASSERT(mLevelZeroTexture.valid() && texture == mLevelZeroTexture);
+            ANGLE_TRY(ensureTextureExists(1));
             srvTexture = &mLevelZeroTexture;
         }
         else
         {
             ASSERT(mipLevels == static_cast<int>(mMipLevels));
             ASSERT(mTexture.valid() && texture == mTexture);
             srvTexture = &mTexture;
         }
     }
 
     ANGLE_TRY(mRenderer->allocateResource(srvDesc, srvTexture->get(), outSRV));
     outSRV->setDebugName("TexStorage2D.SRV");
 
     return gl::NoError();
 }
 
+gl::Error TextureStorage11_2D::createSRVForImage(const gl::Context *context,
+                                                 int level,
+                                                 DXGI_FORMAT format,
+                                                 const TextureHelper11 &texture,
+                                                 d3d11::SharedSRV *outSRV)
+{
+    ASSERT(outSRV);
+    D3D11_SHADER_RESOURCE_VIEW_DESC srvDesc;
+    srvDesc.Format                    = format;
+    srvDesc.ViewDimension             = D3D11_SRV_DIMENSION_TEXTURE2D;
+    srvDesc.Texture2D.MostDetailedMip = mTopLevel + level;
+    srvDesc.Texture2D.MipLevels       = 1;
+    ANGLE_TRY(mRenderer->allocateResource(srvDesc, texture.get(), outSRV));
+    outSRV->setDebugName("TexStorage2D.SRVForImage");
+    return gl::NoError();
+}
+
+gl::Error TextureStorage11_2D::createUAVForImage(const gl::Context *context,
+                                                 int level,
+                                                 DXGI_FORMAT format,
+                                                 const TextureHelper11 &texture,
+                                                 d3d11::SharedUAV *outUAV)
+{
+    ASSERT(outUAV);
+    D3D11_UNORDERED_ACCESS_VIEW_DESC uavDesc;
+    uavDesc.Format                    = format;
+    uavDesc.ViewDimension             = D3D11_UAV_DIMENSION_TEXTURE2D;
+    uavDesc.Texture2D.MipSlice        = mTopLevel + level;
+    ANGLE_TRY(mRenderer->allocateResource(uavDesc, texture.get(), outUAV));
+    outUAV->setDebugName("TexStorage2D.UAVForImage");
+    return gl::NoError();
+}
+
 gl::Error TextureStorage11_2D::getSwizzleTexture(const TextureHelper11 **outTexture)
 {
     ASSERT(outTexture);
 
     if (!mSwizzleTexture.valid())
     {
         const auto &format = mFormatInfo.getSwizzleFormat(mRenderer->getRenderer11DeviceCaps());
 
@@ -1286,20 +1423,20 @@ gl::ErrorOrResult<TextureStorage11::Drop
 }
 
 TextureStorage11_External::TextureStorage11_External(
     Renderer11 *renderer,
     egl::Stream *stream,
     const egl::Stream::GLTextureDescription &glDesc)
     : TextureStorage11(renderer, D3D11_BIND_SHADER_RESOURCE, 0, glDesc.internalFormat)
 {
-    ASSERT(stream->getProducerType() == egl::Stream::ProducerType::D3D11TextureNV12);
-    StreamProducerNV12 *producer = static_cast<StreamProducerNV12 *>(stream->getImplementation());
+    ASSERT(stream->getProducerType() == egl::Stream::ProducerType::D3D11Texture);
+    auto *producer = static_cast<StreamProducerD3DTexture *>(stream->getImplementation());
     mTexture.set(producer->getD3DTexture(), mFormatInfo);
-    mSubresourceIndex            = producer->getArraySlice();
+    mSubresourceIndex = producer->getArraySlice();
     mTexture.get()->AddRef();
     mMipLevels = 1;
 
     D3D11_TEXTURE2D_DESC desc;
     mTexture.getDesc(&desc);
     mTextureWidth  = desc.Width;
     mTextureHeight = desc.Height;
     mTextureDepth  = 1;
@@ -1383,22 +1520,22 @@ gl::Error TextureStorage11_External::get
                                                      const gl::ImageIndex &index,
                                                      RenderTargetD3D **outRT)
 {
     // Render targets are not supported for external textures
     UNREACHABLE();
     return gl::InternalError();
 }
 
-gl::Error TextureStorage11_External::createSRV(const gl::Context *context,
-                                               int baseLevel,
-                                               int mipLevels,
-                                               DXGI_FORMAT format,
-                                               const TextureHelper11 &texture,
-                                               d3d11::SharedSRV *outSRV) const
+gl::Error TextureStorage11_External::createSRVForSampler(const gl::Context *context,
+                                                         int baseLevel,
+                                                         int mipLevels,
+                                                         DXGI_FORMAT format,
+                                                         const TextureHelper11 &texture,
+                                                         d3d11::SharedSRV *outSRV)
 {
     // Since external textures are treates as non-mipmapped textures, we ignore mipmap levels and
     // use the specified subresource ID the storage was created with.
     ASSERT(mipLevels == 1);
     ASSERT(outSRV);
 
     D3D11_SHADER_RESOURCE_VIEW_DESC srvDesc;
     srvDesc.Format        = format;
@@ -1410,16 +1547,36 @@ gl::Error TextureStorage11_External::cre
     srvDesc.Texture2DArray.ArraySize       = 1;
 
     ANGLE_TRY(mRenderer->allocateResource(srvDesc, texture.get(), outSRV));
     outSRV->setDebugName("TexStorage2D.SRV");
 
     return gl::NoError();
 }
 
+gl::Error TextureStorage11_External::createSRVForImage(const gl::Context *context,
+                                                       int level,
+                                                       DXGI_FORMAT format,
+                                                       const TextureHelper11 &texture,
+                                                       d3d11::SharedSRV *outSRV)
+{
+    UNREACHABLE();
+    return gl::InternalError();
+}
+
+gl::Error TextureStorage11_External::createUAVForImage(const gl::Context *context,
+                                                       int level,
+                                                       DXGI_FORMAT format,
+                                                       const TextureHelper11 &texture,
+                                                       d3d11::SharedUAV *outUAV)
+{
+    UNREACHABLE();
+    return gl::InternalError();
+}
+
 gl::Error TextureStorage11_External::getSwizzleTexture(const TextureHelper11 **outTexture)
 {
     UNIMPLEMENTED();
     return gl::InternalError();
 }
 
 gl::Error TextureStorage11_External::getSwizzleRenderTarget(int mipLevel,
                                                             const d3d11::RenderTargetView **outRTV)
@@ -1458,22 +1615,22 @@ gl::Error TextureStorage11_EGLImage::get
     ANGLE_TRY(checkForUpdatedRenderTarget(context));
 
     RenderTarget11 *renderTarget11 = nullptr;
     ANGLE_TRY(getImageRenderTarget(context, &renderTarget11));
     *outResource = &renderTarget11->getTexture();
     return gl::NoError();
 }
 
-gl::Error TextureStorage11_EGLImage::getSRV(const gl::Context *context,
-                                            const gl::TextureState &textureState,
-                                            const d3d11::SharedSRV **outSRV)
+gl::Error TextureStorage11_EGLImage::getSRVForSampler(const gl::Context *context,
+                                                      const gl::TextureState &textureState,
+                                                      const d3d11::SharedSRV **outSRV)
 {
     ANGLE_TRY(checkForUpdatedRenderTarget(context));
-    return TextureStorage11::getSRV(context, textureState, outSRV);
+    return TextureStorage11::getSRVForSampler(context, textureState, outSRV);
 }
 
 gl::Error TextureStorage11_EGLImage::getMippedResource(const gl::Context *context,
                                                        const TextureHelper11 **)
 {
     // This shouldn't be called unless the zero max LOD workaround is active.
     // EGL images are unavailable in this configuration.
     UNREACHABLE();
@@ -1494,17 +1651,17 @@ gl::Error TextureStorage11_EGLImage::get
 
 gl::Error TextureStorage11_EGLImage::copyToStorage(const gl::Context *context,
                                                    TextureStorage *destStorage)
 {
     const TextureHelper11 *sourceResouce = nullptr;
     ANGLE_TRY(getResource(context, &sourceResouce));
 
     ASSERT(destStorage);
-    TextureStorage11_2D *dest11  = GetAs<TextureStorage11_2D>(destStorage);
+    TextureStorage11_2D *dest11         = GetAs<TextureStorage11_2D>(destStorage);
     const TextureHelper11 *destResource = nullptr;
     ANGLE_TRY(dest11->getResource(context, &destResource));
 
     ID3D11DeviceContext *immediateContext = mRenderer->getDeviceContext();
     immediateContext->CopyResource(destResource->get(), sourceResouce->get());
 
     dest11->markDirty();
 
@@ -1599,22 +1756,22 @@ gl::Error TextureStorage11_EGLImage::che
     {
         clearSRVCache();
         mCurrentRenderTarget = reinterpret_cast<uintptr_t>(renderTarget11);
     }
 
     return gl::NoError();
 }
 
-gl::Error TextureStorage11_EGLImage::createSRV(const gl::Context *context,
-                                               int baseLevel,
-                                               int mipLevels,
-                                               DXGI_FORMAT format,
-                                               const TextureHelper11 &texture,
-                                               d3d11::SharedSRV *outSRV) const
+gl::Error TextureStorage11_EGLImage::createSRVForSampler(const gl::Context *context,
+                                                         int baseLevel,
+                                                         int mipLevels,
+                                                         DXGI_FORMAT format,
+                                                         const TextureHelper11 &texture,
+                                                         d3d11::SharedSRV *outSRV)
 {
     ASSERT(baseLevel == 0);
     ASSERT(mipLevels == 1);
     ASSERT(outSRV);
 
     // Create a new SRV only for the swizzle texture.  Otherwise just return the Image's
     // RenderTarget's SRV.
     if (texture == mSwizzleTexture)
@@ -1636,16 +1793,36 @@ gl::Error TextureStorage11_EGLImage::cre
         ASSERT(texture == renderTarget->getTexture());
 
         *outSRV = renderTarget->getShaderResourceView().makeCopy();
     }
 
     return gl::NoError();
 }
 
+gl::Error TextureStorage11_EGLImage::createSRVForImage(const gl::Context *context,
+                                                       int level,
+                                                       DXGI_FORMAT format,
+                                                       const TextureHelper11 &texture,
+                                                       d3d11::SharedSRV *outSRV)
+{
+    UNREACHABLE();
+    return gl::InternalError();
+}
+
+gl::Error TextureStorage11_EGLImage::createUAVForImage(const gl::Context *context,
+                                                       int level,
+                                                       DXGI_FORMAT format,
+                                                       const TextureHelper11 &texture,
+                                                       d3d11::SharedUAV *outUAV)
+{
+    UNREACHABLE();
+    return gl::InternalError();
+}
+
 gl::Error TextureStorage11_EGLImage::getImageRenderTarget(const gl::Context *context,
                                                           RenderTarget11 **outRT) const
 {
     RenderTargetD3D *renderTargetD3D = nullptr;
     ANGLE_TRY(mImage->getRenderTarget(context, &renderTargetD3D));
     *outRT = GetAs<RenderTarget11>(renderTargetD3D);
     return gl::NoError();
 }
@@ -1988,17 +2165,17 @@ gl::Error TextureStorage11_Cube::createR
 {
     D3D11_SHADER_RESOURCE_VIEW_DESC srvDesc;
     srvDesc.Format                         = resourceFormat;
     srvDesc.Texture2DArray.MostDetailedMip = mTopLevel + index.mipIndex;
     srvDesc.Texture2DArray.MipLevels       = 1;
     srvDesc.Texture2DArray.FirstArraySlice = index.layerIndex;
     srvDesc.Texture2DArray.ArraySize       = 1;
 
-    if (mRenderer->getRenderer11DeviceCaps().featureLevel <= D3D_FEATURE_LEVEL_9_3)
+    if (mRenderer->getRenderer11DeviceCaps().featureLevel <= D3D_FEATURE_LEVEL_10_0)
     {
         srvDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURECUBE;
     }
     else
     {
         // Will be used with Texture2D sampler, not TextureCube
         srvDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2DARRAY;
     }
@@ -2108,22 +2285,22 @@ gl::Error TextureStorage11_Cube::getRend
         }
     }
 
     ASSERT(outRT);
     *outRT = mRenderTarget[faceIndex][level].get();
     return gl::NoError();
 }
 
-gl::Error TextureStorage11_Cube::createSRV(const gl::Context *context,
-                                           int baseLevel,
-                                           int mipLevels,
-                                           DXGI_FORMAT format,
-                                           const TextureHelper11 &texture,
-                                           d3d11::SharedSRV *outSRV) const
+gl::Error TextureStorage11_Cube::createSRVForSampler(const gl::Context *context,
+                                                     int baseLevel,
+                                                     int mipLevels,
+                                                     DXGI_FORMAT format,
+                                                     const TextureHelper11 &texture,
+                                                     d3d11::SharedSRV *outSRV)
 {
     ASSERT(outSRV);
 
     D3D11_SHADER_RESOURCE_VIEW_DESC srvDesc;
     srvDesc.Format = format;
 
     // Unnormalized integer cube maps are not supported by DX11; we emulate them as an array of six
     // 2D textures
@@ -2150,33 +2327,70 @@ gl::Error TextureStorage11_Cube::createS
         ASSERT(mTopLevel == 0);
         ASSERT(baseLevel == 0);
         // This code also assumes that the incoming texture equals either mLevelZeroTexture or
         // mTexture.
 
         if (mipLevels == 1 && mMipLevels > 1)
         {
             // We must use a SRV on the level-zero-only texture.
-            ASSERT(mLevelZeroTexture.valid() && texture == mLevelZeroTexture);
+            ANGLE_TRY(ensureTextureExists(1));
             srvTexture = &mLevelZeroTexture;
         }
         else
         {
             ASSERT(mipLevels == static_cast<int>(mMipLevels));
             ASSERT(mTexture.valid() && texture == mTexture);
             srvTexture = &mTexture;
         }
     }
 
     ANGLE_TRY(mRenderer->allocateResource(srvDesc, srvTexture->get(), outSRV));
     outSRV->setDebugName("TexStorageCube.SRV");
 
     return gl::NoError();
 }
 
+gl::Error TextureStorage11_Cube::createSRVForImage(const gl::Context *context,
+                                                   int level,
+                                                   DXGI_FORMAT format,
+                                                   const TextureHelper11 &texture,
+                                                   d3d11::SharedSRV *outSRV)
+{
+    ASSERT(outSRV);
+    D3D11_SHADER_RESOURCE_VIEW_DESC srvDesc;
+    srvDesc.Format                         = format;
+    srvDesc.ViewDimension                  = D3D11_SRV_DIMENSION_TEXTURE2DARRAY;
+    srvDesc.Texture2DArray.MostDetailedMip = mTopLevel + level;
+    srvDesc.Texture2DArray.MipLevels       = 1;
+    srvDesc.Texture2DArray.FirstArraySlice = 0;
+    srvDesc.Texture2DArray.ArraySize       = gl::CUBE_FACE_COUNT;
+    ANGLE_TRY(mRenderer->allocateResource(srvDesc, texture.get(), outSRV));
+    outSRV->setDebugName("TexStorageCube.SRVForImage");
+    return gl::NoError();
+}
+
+gl::Error TextureStorage11_Cube::createUAVForImage(const gl::Context *context,
+                                                   int level,
+                                                   DXGI_FORMAT format,
+                                                   const TextureHelper11 &texture,
+                                                   d3d11::SharedUAV *outUAV)
+{
+    ASSERT(outUAV);
+    D3D11_UNORDERED_ACCESS_VIEW_DESC uavDesc;
+    uavDesc.Format                         = format;
+    uavDesc.ViewDimension                  = D3D11_UAV_DIMENSION_TEXTURE2DARRAY;
+    uavDesc.Texture2DArray.MipSlice        = mTopLevel + level;
+    uavDesc.Texture2DArray.FirstArraySlice = 0;
+    uavDesc.Texture2DArray.ArraySize       = gl::CUBE_FACE_COUNT;
+    ANGLE_TRY(mRenderer->allocateResource(uavDesc, texture.get(), outUAV));
+    outUAV->setDebugName("TexStorageCube.UAVForImage");
+    return gl::NoError();
+}
+
 gl::Error TextureStorage11_Cube::getSwizzleTexture(const TextureHelper11 **outTexture)
 {
     ASSERT(outTexture);
 
     if (!mSwizzleTexture.valid())
     {
         const auto &format = mFormatInfo.getSwizzleFormat(mRenderer->getRenderer11DeviceCaps());
 
@@ -2295,18 +2509,18 @@ TextureStorage11_3D::TextureStorage11_3D
           GetTextureMiscFlags(internalformat,
                               renderer->getRenderer11DeviceCaps(),
                               renderTarget,
                               levels),
           internalformat)
 {
     for (unsigned int i = 0; i < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS; i++)
     {
-        mAssociatedImages[i]     = nullptr;
-        mLevelRenderTargets[i]   = nullptr;
+        mAssociatedImages[i]   = nullptr;
+        mLevelRenderTargets[i] = nullptr;
     }
 
     // adjust size if needed for compressed textures
     d3d11::MakeValidSize(false, mFormatInfo.texFormat, &width, &height, &mTopLevel);
 
     mMipLevels     = mTopLevel + levels;
     mTextureWidth  = width;
     mTextureHeight = height;
@@ -2420,37 +2634,72 @@ gl::Error TextureStorage11_3D::getResour
         ANGLE_TRY(mRenderer->allocateTexture(desc, mFormatInfo, &mTexture));
         mTexture.setDebugName("TexStorage3D.Texture");
     }
 
     *outResource = &mTexture;
     return gl::NoError();
 }
 
-gl::Error TextureStorage11_3D::createSRV(const gl::Context *context,
-                                         int baseLevel,
-                                         int mipLevels,
-                                         DXGI_FORMAT format,
-                                         const TextureHelper11 &texture,
-                                         d3d11::SharedSRV *outSRV) const
+gl::Error TextureStorage11_3D::createSRVForSampler(const gl::Context *context,
+                                                   int baseLevel,
+                                                   int mipLevels,
+                                                   DXGI_FORMAT format,
+                                                   const TextureHelper11 &texture,
+                                                   d3d11::SharedSRV *outSRV)
 {
     ASSERT(outSRV);
 
     D3D11_SHADER_RESOURCE_VIEW_DESC srvDesc;
     srvDesc.Format                    = format;
     srvDesc.ViewDimension             = D3D11_SRV_DIMENSION_TEXTURE3D;
     srvDesc.Texture3D.MostDetailedMip = baseLevel;
     srvDesc.Texture3D.MipLevels       = mipLevels;
 
     ANGLE_TRY(mRenderer->allocateResource(srvDesc, texture.get(), outSRV));
     outSRV->setDebugName("TexStorage3D.SRV");
 
     return gl::NoError();
 }
 
+gl::Error TextureStorage11_3D::createSRVForImage(const gl::Context *context,
+                                                 int level,
+                                                 DXGI_FORMAT format,
+                                                 const TextureHelper11 &texture,
+                                                 d3d11::SharedSRV *outSRV)
+{
+    ASSERT(outSRV);
+    D3D11_SHADER_RESOURCE_VIEW_DESC srvDesc;
+    srvDesc.Format                    = format;
+    srvDesc.ViewDimension             = D3D11_SRV_DIMENSION_TEXTURE3D;
+    srvDesc.Texture3D.MostDetailedMip = mTopLevel + level;
+    srvDesc.Texture3D.MipLevels       = 1;
+    ANGLE_TRY(mRenderer->allocateResource(srvDesc, texture.get(), outSRV));
+    outSRV->setDebugName("TexStorage3D.SRVForImage");
+    return gl::NoError();
+}
+
+gl::Error TextureStorage11_3D::createUAVForImage(const gl::Context *context,
+                                                 int level,
+                                                 DXGI_FORMAT format,
+                                                 const TextureHelper11 &texture,
+                                                 d3d11::SharedUAV *outUAV)
+{
+    ASSERT(outUAV);
+    D3D11_UNORDERED_ACCESS_VIEW_DESC uavDesc;
+    uavDesc.Format                = format;
+    uavDesc.ViewDimension         = D3D11_UAV_DIMENSION_TEXTURE3D;
+    uavDesc.Texture3D.MipSlice    = mTopLevel + level;
+    uavDesc.Texture3D.FirstWSlice = 0;
+    uavDesc.Texture3D.WSize       = mTextureDepth;
+    ANGLE_TRY(mRenderer->allocateResource(uavDesc, texture.get(), outUAV));
+    outUAV->setDebugName("TexStorage3D.UAVForImage");
+    return gl::NoError();
+}
+
 gl::Error TextureStorage11_3D::getRenderTarget(const gl::Context *context,
                                                const gl::ImageIndex &index,
                                                RenderTargetD3D **outRT)
 {
     const int mipLevel = index.mipIndex;
     ASSERT(mipLevel >= 0 && mipLevel < getLevelCount());
 
     ASSERT(mFormatInfo.rtvFormat != DXGI_FORMAT_UNKNOWN);
@@ -2727,37 +2976,74 @@ gl::Error TextureStorage11_2DArray::getR
         ANGLE_TRY(mRenderer->allocateTexture(desc, mFormatInfo, &mTexture));
         mTexture.setDebugName("TexStorage2DArray.Texture");
     }
 
     *outResource = &mTexture;
     return gl::NoError();
 }
 
-gl::Error TextureStorage11_2DArray::createSRV(const gl::Context *context,
-                                              int baseLevel,
-                                              int mipLevels,
-                                              DXGI_FORMAT format,
-                                              const TextureHelper11 &texture,
-                                              d3d11::SharedSRV *outSRV) const
+gl::Error TextureStorage11_2DArray::createSRVForSampler(const gl::Context *context,
+                                                        int baseLevel,
+                                                        int mipLevels,
+                                                        DXGI_FORMAT format,
+                                                        const TextureHelper11 &texture,
+                                                        d3d11::SharedSRV *outSRV)
 {
     D3D11_SHADER_RESOURCE_VIEW_DESC srvDesc;
     srvDesc.Format                         = format;
     srvDesc.ViewDimension                  = D3D11_SRV_DIMENSION_TEXTURE2DARRAY;
     srvDesc.Texture2DArray.MostDetailedMip = mTopLevel + baseLevel;
     srvDesc.Texture2DArray.MipLevels       = mipLevels;
     srvDesc.Texture2DArray.FirstArraySlice = 0;
     srvDesc.Texture2DArray.ArraySize       = mTextureDepth;
 
     ANGLE_TRY(mRenderer->allocateResource(srvDesc, texture.get(), outSRV));
     outSRV->setDebugName("TexStorage2DArray.SRV");
 
     return gl::NoError();
 }
 
+gl::Error TextureStorage11_2DArray::createSRVForImage(const gl::Context *context,
+                                                      int level,
+                                                      DXGI_FORMAT format,
+                                                      const TextureHelper11 &texture,
+                                                      d3d11::SharedSRV *outSRV)
+{
+    ASSERT(outSRV);
+    D3D11_SHADER_RESOURCE_VIEW_DESC srvDesc;
+    srvDesc.Format                         = format;
+    srvDesc.ViewDimension                  = D3D11_SRV_DIMENSION_TEXTURE2DARRAY;
+    srvDesc.Texture2DArray.MostDetailedMip = mTopLevel + level;
+    srvDesc.Texture2DArray.MipLevels       = 1;
+    srvDesc.Texture2DArray.FirstArraySlice = 0;
+    srvDesc.Texture2DArray.ArraySize       = mTextureDepth;
+    ANGLE_TRY(mRenderer->allocateResource(srvDesc, texture.get(), outSRV));
+    outSRV->setDebugName("TexStorage2DArray.SRVForImage");
+    return gl::NoError();
+}
+
+gl::Error TextureStorage11_2DArray::createUAVForImage(const gl::Context *context,
+                                                      int level,
+                                                      DXGI_FORMAT format,
+                                                      const TextureHelper11 &texture,
+                                                      d3d11::SharedUAV *outUAV)
+{
+    ASSERT(outUAV);
+    D3D11_UNORDERED_ACCESS_VIEW_DESC uavDesc;
+    uavDesc.Format                         = format;
+    uavDesc.ViewDimension                  = D3D11_UAV_DIMENSION_TEXTURE2DARRAY;
+    uavDesc.Texture2DArray.MipSlice        = mTopLevel + level;
+    uavDesc.Texture2DArray.FirstArraySlice = 0;
+    uavDesc.Texture2DArray.ArraySize       = mTextureDepth;
+    ANGLE_TRY(mRenderer->allocateResource(uavDesc, texture.get(), outUAV));
+    outUAV->setDebugName("TexStorage2DArray.UAVForImage");
+    return gl::NoError();
+}
+
 gl::Error TextureStorage11_2DArray::createRenderTargetSRV(const TextureHelper11 &texture,
                                                           const gl::ImageIndex &index,
                                                           DXGI_FORMAT resourceFormat,
                                                           d3d11::SharedSRV *srv) const
 {
     D3D11_SHADER_RESOURCE_VIEW_DESC srvDesc;
     srvDesc.Format                         = resourceFormat;
     srvDesc.ViewDimension                  = D3D11_SRV_DIMENSION_TEXTURE2DARRAY;
@@ -2772,18 +3058,18 @@ gl::Error TextureStorage11_2DArray::crea
 }
 
 gl::Error TextureStorage11_2DArray::getRenderTarget(const gl::Context *context,
                                                     const gl::ImageIndex &index,
                                                     RenderTargetD3D **outRT)
 {
     ASSERT(index.hasLayer());
 
-    const int mipLevel = index.mipIndex;
-    const int layer    = index.layerIndex;
+    const int mipLevel  = index.mipIndex;
+    const int layer     = index.layerIndex;
     const int numLayers = index.numLayers;
 
     ASSERT(mipLevel >= 0 && mipLevel < getLevelCount());
 
     LevelLayerRangeKey key(mipLevel, layer, numLayers);
     if (mRenderTargets.find(key) == mRenderTargets.end())
     {
         const TextureHelper11 *texture = nullptr;
@@ -2935,17 +3221,17 @@ gl::ErrorOrResult<TextureStorage11::Drop
 }
 
 TextureStorage11_2DMultisample::TextureStorage11_2DMultisample(Renderer11 *renderer,
                                                                GLenum internalformat,
                                                                GLsizei width,
                                                                GLsizei height,
                                                                int levels,
                                                                int samples,
-                                                               GLboolean fixedSampleLocations)
+                                                               bool fixedSampleLocations)
     : TextureStorage11(
           renderer,
           GetTextureBindFlags(internalformat, renderer->getRenderer11DeviceCaps(), true),
           GetTextureMiscFlags(internalformat, renderer->getRenderer11DeviceCaps(), true, levels),
           internalformat),
       mTexture(),
       mRenderTarget(nullptr)
 {
@@ -3020,17 +3306,17 @@ gl::Error TextureStorage11_2DMultisample
         D3D11_TEXTURE2D_DESC desc;
         ZeroMemory(&desc, sizeof(desc));
         desc.Width          = mTextureWidth;  // Compressed texture size constraints?
         desc.Height         = mTextureHeight;
         desc.MipLevels      = mipLevels;
         desc.ArraySize      = 1;
         desc.Format         = mFormatInfo.texFormat;
         desc.Usage          = D3D11_USAGE_DEFAULT;
-        desc.BindFlags      = getBindFlags();
+        desc.BindFlags      = getBindFlags() & ~D3D11_BIND_UNORDERED_ACCESS;
         desc.CPUAccessFlags = 0;
         desc.MiscFlags      = getMiscFlags();
 
         const gl::TextureCaps &textureCaps =
             mRenderer->getNativeTextureCaps().get(mFormatInfo.internalFormat);
         GLuint supportedSamples = textureCaps.getNearestSamples(mSamples);
         desc.SampleDesc.Count   = (supportedSamples == 0) ? 1 : supportedSamples;
         desc.SampleDesc.Quality = static_cast<UINT>(D3D11_STANDARD_MULTISAMPLE_PATTERN);
@@ -3097,34 +3383,54 @@ gl::Error TextureStorage11_2DMultisample
     mRenderTarget.reset(new TextureRenderTarget11(
         std::move(dsv), *texture, *srv, mFormatInfo.internalFormat, getFormatSet(),
         getLevelWidth(level), getLevelHeight(level), 1, mSamples));
 
     *outRT = mRenderTarget.get();
     return gl::NoError();
 }
 
-gl::Error TextureStorage11_2DMultisample::createSRV(const gl::Context *context,
-                                                    int baseLevel,
-                                                    int mipLevels,
-                                                    DXGI_FORMAT format,
-                                                    const TextureHelper11 &texture,
-                                                    d3d11::SharedSRV *outSRV) const
+gl::Error TextureStorage11_2DMultisample::createSRVForSampler(const gl::Context *context,
+                                                              int baseLevel,
+                                                              int mipLevels,
+                                                              DXGI_FORMAT format,
+                                                              const TextureHelper11 &texture,
+                                                              d3d11::SharedSRV *outSRV)
 {
     ASSERT(outSRV);
 
     D3D11_SHADER_RESOURCE_VIEW_DESC srvDesc;
     srvDesc.Format        = format;
     srvDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2DMS;
 
     ANGLE_TRY(mRenderer->allocateResource(srvDesc, texture.get(), outSRV));
     outSRV->setDebugName("TexStorage2DMS.SRV");
     return gl::NoError();
 }
 
+gl::Error TextureStorage11_2DMultisample::createSRVForImage(const gl::Context *context,
+                                                            int level,
+                                                            DXGI_FORMAT format,
+                                                            const TextureHelper11 &texture,
+                                                            d3d11::SharedSRV *outSRV)
+{
+    UNREACHABLE();
+    return gl::InternalError();
+}
+
+gl::Error TextureStorage11_2DMultisample::createUAVForImage(const gl::Context *context,
+                                                            int level,
+                                                            DXGI_FORMAT format,
+                                                            const TextureHelper11 &texture,
+                                                            d3d11::SharedUAV *outUAV)
+{
+    UNREACHABLE();
+    return gl::InternalError();
+}
+
 gl::Error TextureStorage11_2DMultisample::getSwizzleTexture(const TextureHelper11 **outTexture)
 {
     UNIMPLEMENTED();
     return gl::InternalError() << "getSwizzleTexture is unimplemented.";
 }
 
 gl::Error TextureStorage11_2DMultisample::getSwizzleRenderTarget(
     int mipLevel,
--- a/gfx/angle/src/libANGLE/renderer/d3d/d3d11/TextureStorage11.h
+++ b/gfx/angle/src/libANGLE/renderer/d3d/d3d11/TextureStorage11.h
@@ -1,16 +1,17 @@
 //
 // Copyright (c) 2012-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.
 //
 
 // TextureStorage11.h: Defines the abstract rx::TextureStorage11 class and its concrete derived
-// classes TextureStorage11_2D and TextureStorage11_Cube, which act as the interface to the D3D11 texture.
+// classes TextureStorage11_2D and TextureStorage11_Cube, which act as the interface to the D3D11
+// texture.
 
 #ifndef LIBANGLE_RENDERER_D3D_D3D11_TEXTURESTORAGE11_H_
 #define LIBANGLE_RENDERER_D3D_D3D11_TEXTURESTORAGE11_H_
 
 #include "libANGLE/Error.h"
 #include "libANGLE/Texture.h"
 #include "libANGLE/renderer/d3d/TextureStorage.h"
 #include "libANGLE/renderer/d3d/d3d11/renderer11_utils.h"
@@ -40,18 +41,23 @@ using TexLevelArray = std::array<T, gl::
 template <typename T>
 using CubeFaceArray = std::array<T, gl::CUBE_FACE_COUNT>;
 
 class TextureStorage11 : public TextureStorage
 {
   public:
     ~TextureStorage11() override;
 
-    static DWORD GetTextureBindFlags(GLenum internalFormat, const Renderer11DeviceCaps &renderer11DeviceCaps, bool renderTarget);
-    static DWORD GetTextureMiscFlags(GLenum internalFormat, const Renderer11DeviceCaps &renderer11DeviceCaps, bool renderTarget, int levels);
+    static DWORD GetTextureBindFlags(GLenum internalFormat,
+                                     const Renderer11DeviceCaps &renderer11DeviceCaps,
+                                     bool renderTarget);
+    static DWORD GetTextureMiscFlags(GLenum internalFormat,
+                                     const Renderer11DeviceCaps &renderer11DeviceCaps,
+                                     bool renderTarget,
+                                     int levels);
 
     UINT getBindFlags() const;
     UINT getMiscFlags() const;
     const d3d11::Format &getFormatSet() const;
     gl::Error getSRVLevels(const gl::Context *context,
                            GLint baseLevel,
                            GLint maxLevel,
                            const d3d11::SharedSRV **outSRV);
@@ -84,44 +90,47 @@ class TextureStorage11 : public TextureS
     gl::Error setData(const gl::Context *context,
                       const gl::ImageIndex &index,
                       ImageD3D *image,
                       const gl::Box *destBox,
                       GLenum type,
                       const gl::PixelUnpackState &unpack,
                       const uint8_t *pixelData) override;
 
-    virtual gl::Error getSRV(const gl::Context *context,
-                             const gl::TextureState &textureState,
+    virtual gl::Error getSRVForSampler(const gl::Context *context,
+                                       const gl::TextureState &textureState,
+                                       const d3d11::SharedSRV **outSRV);
+    gl::Error getSRVForImage(const gl::Context *context,
+                             const gl::ImageUnit &imageUnit,
                              const d3d11::SharedSRV **outSRV);
+    gl::Error getUAVForImage(const gl::Context *context,
+                             const gl::ImageUnit &imageUnit,
+                             const d3d11::SharedUAV **outUAV);
     virtual UINT getSubresourceIndex(const gl::ImageIndex &index) const;
     virtual gl::Error getResource(const gl::Context *context,
-                                  const TextureHelper11 **outResource) = 0;
-    virtual void associateImage(Image11* image, const gl::ImageIndex &index) = 0;
-    virtual void disassociateImage(const gl::ImageIndex &index, Image11* expectedImage) = 0;
+                                  const TextureHelper11 **outResource)                  = 0;
+    virtual void associateImage(Image11 *image, const gl::ImageIndex &index)            = 0;
+    virtual void disassociateImage(const gl::ImageIndex &index, Image11 *expectedImage) = 0;
     virtual void verifyAssociatedImageValid(const gl::ImageIndex &index,
-                                            Image11 *expectedImage) = 0;
+                                            Image11 *expectedImage)                     = 0;
     virtual gl::Error releaseAssociatedImage(const gl::Context *context,
                                              const gl::ImageIndex &index,
-                                             Image11 *incomingImage) = 0;
+                                             Image11 *incomingImage)                    = 0;
 
   protected:
     TextureStorage11(Renderer11 *renderer, UINT bindFlags, UINT miscFlags, GLenum internalFormat);
     int getLevelWidth(int mipLevel) const;
     int getLevelHeight(int mipLevel) const;
     int getLevelDepth(int mipLevel) const;
 
     // Some classes (e.g. TextureStorage11_2D) will override getMippedResource.
     virtual gl::Error getMippedResource(const gl::Context *context,
-                                        const TextureHelper11 **outResource)
-    {
-        return getResource(context, outResource);
-    }
+                                        const TextureHelper11 **outResource);
 
-    virtual gl::Error getSwizzleTexture(const TextureHelper11 **outTexture) = 0;
+    virtual gl::Error getSwizzleTexture(const TextureHelper11 **outTexture)          = 0;
     virtual gl::Error getSwizzleRenderTarget(int mipLevel,
                                              const d3d11::RenderTargetView **outRTV) = 0;
     gl::Error getSRVLevel(const gl::Context *context,
                           int mipLevel,
                           bool blitSRV,
                           const d3d11::SharedSRV **outSRV);
 
     // Get a version of a depth texture with only depth information, not stencil.
@@ -129,22 +138,32 @@ class TextureStorage11 : public TextureS
     {
         CREATED,
         ALREADY_EXISTS
     };
     virtual gl::ErrorOrResult<DropStencil> ensureDropStencilTexture(const gl::Context *context);
     gl::Error initDropStencilTexture(const gl::Context *context, const gl::ImageIndexIterator &it);
 
     // The baseLevel parameter should *not* have mTopLevel applied.
-    virtual gl::Error createSRV(const gl::Context *context,
-                                int baseLevel,
-                                int mipLevels,
-                                DXGI_FORMAT format,
-                                const TextureHelper11 &texture,
-                                d3d11::SharedSRV *outSRV) const = 0;
+    virtual gl::Error createSRVForSampler(const gl::Context *context,
+                                          int baseLevel,
+                                          int mipLevels,
+                                          DXGI_FORMAT format,
+                                          const TextureHelper11 &texture,
+                                          d3d11::SharedSRV *outSRV) = 0;
+    virtual gl::Error createSRVForImage(const gl::Context *context,
+                                        int level,
+                                        DXGI_FORMAT format,
+                                        const TextureHelper11 &texture,
+                                        d3d11::SharedSRV *outSRV)   = 0;
+    virtual gl::Error createUAVForImage(const gl::Context *context,
+                                        int level,
+                                        DXGI_FORMAT format,
+                                        const TextureHelper11 &texture,
+                                        d3d11::SharedUAV *outUAV)   = 0;
 
     void verifySwizzleExists(const gl::SwizzleState &swizzleState);
 
     // Clear all cached non-swizzle SRVs and invalidate the swizzle cache.
     void clearSRVCache();
 
     Renderer11 *mRenderer;
     int mTopLevel;
@@ -157,43 +176,75 @@ class TextureStorage11 : public TextureS
 
     TexLevelArray<gl::SwizzleState> mSwizzleCache;
     TextureHelper11 mDropStencilTexture;
 
   private:
     const UINT mBindFlags;
     const UINT mMiscFlags;
 
-    struct SRVKey
+    struct SamplerKey
     {
-        SRVKey(int baseLevel, int mipLevels, bool swizzle, bool dropStencil);
+        SamplerKey();
+        SamplerKey(int baseLevel, int mipLevels, bool swizzle, bool dropStencil);
+
+        bool operator<(const SamplerKey &rhs) const;
 
-        bool operator<(const SRVKey &rhs) const;
+        int baseLevel;
+        int mipLevels;
+        bool swizzle;
+        bool dropStencil;
+    };
+
+    gl::Error getCachedOrCreateSRVForSampler(const gl::Context *context,
+                                             const SamplerKey &key,
+                                             const d3d11::SharedSRV **outSRV);
+
+    using SRVCacheForSampler = std::map<SamplerKey, d3d11::SharedSRV>;
+    SRVCacheForSampler mSrvCacheForSampler;
 
-        int baseLevel    = 0;  // Without mTopLevel applied.
-        int mipLevels    = 0;
-        bool swizzle     = false;
-        bool dropStencil = false;
+    struct ImageKey
+    {
+        ImageKey();
+        ImageKey(int level, bool layered, int layer, GLenum access, GLenum format);
+        bool operator<(const ImageKey &rhs) const;
+        int level;
+        bool layered;
+        int layer;
+        GLenum access;
+        GLenum format;
     };
-    typedef std::map<SRVKey, d3d11::SharedSRV> SRVCache;
 
-    gl::Error getCachedOrCreateSRV(const gl::Context *context,
-                                   const SRVKey &key,
-                                   const d3d11::SharedSRV **outSRV);
+    gl::Error getCachedOrCreateSRVForImage(const gl::Context *context,
+                                           const ImageKey &key,
+                                           const d3d11::SharedSRV **outSRV);
+    gl::Error getCachedOrCreateUAVForImage(const gl::Context *context,
+                                           const ImageKey &key,
+                                           const d3d11::SharedUAV **outUAV);
 
-    SRVCache mSrvCache;
+    using SRVCacheForImage = std::map<ImageKey, d3d11::SharedSRV>;
+    SRVCacheForImage mSrvCacheForImage;
+    using UAVCacheForImage = std::map<ImageKey, d3d11::SharedUAV>;
+    UAVCacheForImage mUavCacheForImage;
+
     TexLevelArray<d3d11::SharedSRV> mLevelSRVs;
     TexLevelArray<d3d11::SharedSRV> mLevelBlitSRVs;
 };
 
 class TextureStorage11_2D : public TextureStorage11
 {
   public:
     TextureStorage11_2D(Renderer11 *renderer, SwapChain11 *swapchain);
-    TextureStorage11_2D(Renderer11 *renderer, GLenum internalformat, bool renderTarget, GLsizei width, GLsizei height, int levels, bool hintLevelZeroOnly = false);
+    TextureStorage11_2D(Renderer11 *renderer,
+                        GLenum internalformat,
+                        bool renderTarget,
+                        GLsizei width,
+                        GLsizei height,
+                        int levels,
+                        bool hintLevelZeroOnly = false);
     ~TextureStorage11_2D() override;
 
     gl::Error onDestroy(const gl::Context *context) override;
 
     gl::Error getResource(const gl::Context *context, const TextureHelper11 **outResource) override;
     gl::Error getMippedResource(const gl::Context *context,
                                 const TextureHelper11 **outResource) override;
     gl::Error getRenderTarget(const gl::Context *context,
@@ -216,36 +267,48 @@ class TextureStorage11_2D : public Textu
     gl::Error getSwizzleTexture(const TextureHelper11 **outTexture) override;
     gl::Error getSwizzleRenderTarget(int mipLevel, const d3d11::RenderTargetView **outRTV) override;
 
     gl::ErrorOrResult<DropStencil> ensureDropStencilTexture(const gl::Context *context) override;
 
     gl::Error ensureTextureExists(int mipLevels);
 
   private:
-    gl::Error createSRV(const gl::Context *context,
-                        int baseLevel,
-                        int mipLevels,
-                        DXGI_FORMAT format,
-                        const TextureHelper11 &texture,
-                        d3d11::SharedSRV *outSRV) const override;
+    gl::Error createSRVForSampler(const gl::Context *context,
+                                  int baseLevel,
+                                  int mipLevels,
+                                  DXGI_FORMAT format,
+                                  const TextureHelper11 &texture,
+                                  d3d11::SharedSRV *outSRV) override;
+    gl::Error createSRVForImage(const gl::Context *context,
+                                int level,
+                                DXGI_FORMAT format,
+                                const TextureHelper11 &texture,
+                                d3d11::SharedSRV *outSRV) override;
+    gl::Error createUAVForImage(const gl::Context *context,
+                                int level,
+                                DXGI_FORMAT format,
+                                const TextureHelper11 &texture,
+                                d3d11::SharedUAV *outUAV) override;
 
     TextureHelper11 mTexture;
     TexLevelArray<std::unique_ptr<RenderTarget11>> mRenderTarget;
     bool mHasKeyedMutex;
 
     // These are members related to the zero max-LOD workaround.
-    // D3D11 Feature Level 9_3 can't disable mipmaps on a mipmapped texture (i.e. solely sample from level zero).
-    // These members are used to work around this limitation.
-    // Usually only mTexture XOR mLevelZeroTexture will exist.
-    // For example, if an app creates a texture with only one level, then 9_3 will only create mLevelZeroTexture.
-    // However, in some scenarios, both textures have to be created. This incurs additional memory overhead.
-    // One example of this is an application that creates a texture, calls glGenerateMipmap, and then disables mipmaps on the texture.
-    // A more likely example is an app that creates an empty texture, renders to it, and then calls glGenerateMipmap
-    // TODO: In this rendering scenario, release the mLevelZeroTexture after mTexture has been created to save memory.
+    // D3D11 Feature Level 9_3 can't disable mipmaps on a mipmapped texture (i.e. solely sample from
+    // level zero). These members are used to work around this limitation. Usually only mTexture XOR
+    // mLevelZeroTexture will exist. For example, if an app creates a texture with only one level,
+    // then 9_3 will only create mLevelZeroTexture. However, in some scenarios, both textures have
+    // to be created. This incurs additional memory overhead. One example of this is an application
+    // that creates a texture, calls glGenerateMipmap, and then disables mipmaps on the texture. A
+    // more likely example is an app that creates an empty texture, renders to it, and then calls
+    // glGenerateMipmap
+    // TODO: In this rendering scenario, release the mLevelZeroTexture after mTexture has been
+    // created to save memory.
     TextureHelper11 mLevelZeroTexture;
     std::unique_ptr<RenderTarget11> mLevelZeroRenderTarget;
     bool mUseLevelZeroTexture;
 
     // Swizzle-related variables
     TextureHelper11 mSwizzleTexture;
     TexLevelArray<d3d11::RenderTargetView> mSwizzleRenderTargets;
 
@@ -278,22 +341,32 @@ class TextureStorage11_External : public
                                      const gl::ImageIndex &index,
                                      Image11 *incomingImage) override;
 
   protected:
     gl::Error getSwizzleTexture(const TextureHelper11 **outTexture) override;
     gl::Error getSwizzleRenderTarget(int mipLevel, const d3d11::RenderTargetView **outRTV) override;
 
   private:
-    gl::Error createSRV(const gl::Context *context,
-                        int baseLevel,
-                        int mipLevels,
-                        DXGI_FORMAT format,
-                        const TextureHelper11 &texture,
-                        d3d11::SharedSRV *outSRV) const override;
+    gl::Error createSRVForSampler(const gl::Context *context,
+                                  int baseLevel,
+                                  int mipLevels,
+                                  DXGI_FORMAT format,
+                                  const TextureHelper11 &texture,
+                                  d3d11::SharedSRV *outSRV) override;
+    gl::Error createSRVForImage(const gl::Context *context,
+                                int level,
+                                DXGI_FORMAT format,
+                                const TextureHelper11 &texture,
+                                d3d11::SharedSRV *outSRV) override;
+    gl::Error createUAVForImage(const gl::Context *context,
+                                int level,
+                                DXGI_FORMAT format,
+                                const TextureHelper11 &texture,
+                                d3d11::SharedUAV *outUAV) override;
 
     TextureHelper11 mTexture;
     int mSubresourceIndex;
     bool mHasKeyedMutex;
 
     Image11 *mAssociatedImage;
 };
 
@@ -301,19 +374,19 @@ class TextureStorage11_EGLImage final : 
 {
   public:
     TextureStorage11_EGLImage(Renderer11 *renderer,
                               EGLImageD3D *eglImage,
                               RenderTarget11 *renderTarget11);
     ~TextureStorage11_EGLImage() override;
 
     gl::Error getResource(const gl::Context *context, const TextureHelper11 **outResource) override;
-    gl::Error getSRV(const gl::Context *context,
-                     const gl::TextureState &textureState,
-                     const d3d11::SharedSRV **outSRV) override;
+    gl::Error getSRVForSampler(const gl::Context *context,
+                               const gl::TextureState &textureState,
+                               const d3d11::SharedSRV **outSRV) override;
     gl::Error getMippedResource(const gl::Context *context,
                                 const TextureHelper11 **outResource) override;
     gl::Error getRenderTarget(const gl::Context *context,
                               const gl::ImageIndex &index,
                               RenderTargetD3D **outRT) override;
 
     gl::Error copyToStorage(const gl::Context *context, TextureStorage *destStorage) override;
 
@@ -331,37 +404,52 @@ class TextureStorage11_EGLImage final : 
     gl::Error getSwizzleTexture(const TextureHelper11 **outTexture) override;
     gl::Error getSwizzleRenderTarget(int mipLevel, const d3d11::RenderTargetView **outRTV) override;
 
   private:
     // Check if the EGL image's render target has been updated due to orphaning and delete
     // any SRVs and other resources based on the image's old render target.
     gl::Error checkForUpdatedRenderTarget(const gl::Context *context);
 
-    gl::Error createSRV(const gl::Context *context,
-                        int baseLevel,
-                        int mipLevels,
-                        DXGI_FORMAT format,
-                        const TextureHelper11 &texture,
-                        d3d11::SharedSRV *outSRV) const override;
+    gl::Error createSRVForSampler(const gl::Context *context,
+                                  int baseLevel,
+                                  int mipLevels,
+                                  DXGI_FORMAT format,
+                                  const TextureHelper11 &texture,
+                                  d3d11::SharedSRV *outSRV) override;
+    gl::Error createSRVForImage(const gl::Context *context,
+                                int level,
+                                DXGI_FORMAT format,
+                                const TextureHelper11 &texture,
+                                d3d11::SharedSRV *outSRV) override;
+    gl::Error createUAVForImage(const gl::Context *context,
+                                int level,
+                                DXGI_FORMAT format,
+                                const TextureHelper11 &texture,
+                                d3d11::SharedUAV *outUAV) override;
 
     gl::Error getImageRenderTarget(const gl::Context *context, RenderTarget11 **outRT) const;
 
     EGLImageD3D *mImage;
     uintptr_t mCurrentRenderTarget;
 
     // Swizzle-related variables
     TextureHelper11 mSwizzleTexture;
     std::vector<d3d11::RenderTargetView> mSwizzleRenderTargets;
 };
 
 class TextureStorage11_Cube : public TextureStorage11
 {
   public:
-    TextureStorage11_Cube(Renderer11 *renderer, GLenum internalformat, bool renderTarget, int size, int levels, bool hintLevelZeroOnly);
+    TextureStorage11_Cube(Renderer11 *renderer,
+                          GLenum internalformat,
+                          bool renderTarget,
+                          int size,
+                          int levels,
+                          bool hintLevelZeroOnly);
     ~TextureStorage11_Cube() override;
 
     gl::Error onDestroy(const gl::Context *context) override;
 
     UINT getSubresourceIndex(const gl::ImageIndex &index) const override;
 
     gl::Error getResource(const gl::Context *context, const TextureHelper11 **outResource) override;
     gl::Error getMippedResource(const gl::Context *context,
@@ -386,46 +474,62 @@ class TextureStorage11_Cube : public Tex
     gl::Error getSwizzleTexture(const TextureHelper11 **outTexture) override;
     gl::Error getSwizzleRenderTarget(int mipLevel, const d3d11::RenderTargetView **outRTV) override;
 
     gl::ErrorOrResult<DropStencil> ensureDropStencilTexture(const gl::Context *context) override;
 
     gl::Error ensureTextureExists(int mipLevels);
 
   private:
-    gl::Error createSRV(const gl::Context *context,
-                        int baseLevel,
-                        int mipLevels,
-                        DXGI_FORMAT format,
-                        const TextureHelper11 &texture,
-                        d3d11::SharedSRV *outSRV) const override;
+    gl::Error createSRVForSampler(const gl::Context *context,
+                                  int baseLevel,
+                                  int mipLevels,
+                                  DXGI_FORMAT format,
+                                  const TextureHelper11 &texture,
+                                  d3d11::SharedSRV *outSRV) override;
+    gl::Error createSRVForImage(const gl::Context *context,
+                                int level,
+                                DXGI_FORMAT format,
+                                const TextureHelper11 &texture,
+                                d3d11::SharedSRV *outSRV) override;
+    gl::Error createUAVForImage(const gl::Context *context,
+                                int level,
+                                DXGI_FORMAT format,
+                                const TextureHelper11 &texture,
+                                d3d11::SharedUAV *outUAV) override;
     gl::Error createRenderTargetSRV(const TextureHelper11 &texture,
                                     const gl::ImageIndex &index,
                                     DXGI_FORMAT resourceFormat,
                                     d3d11::SharedSRV *srv) const;
 
     TextureHelper11 mTexture;
     CubeFaceArray<TexLevelArray<std::unique_ptr<RenderTarget11>>> mRenderTarget;
 
-    // Level-zero workaround members. See TextureStorage11_2D's workaround members for a description.
+    // Level-zero workaround members. See TextureStorage11_2D's workaround members for a
+    // description.
     TextureHelper11 mLevelZeroTexture;
     CubeFaceArray<std::unique_ptr<RenderTarget11>> mLevelZeroRenderTarget;
     bool mUseLevelZeroTexture;
 
     TextureHelper11 mSwizzleTexture;
     TexLevelArray<d3d11::RenderTargetView> mSwizzleRenderTargets;
 
     CubeFaceArray<TexLevelArray<Image11 *>> mAssociatedImages;
 };
 
 class TextureStorage11_3D : public TextureStorage11
 {
   public:
-    TextureStorage11_3D(Renderer11 *renderer, GLenum internalformat, bool renderTarget,
-                        GLsizei width, GLsizei height, GLsizei depth, int levels);
+    TextureStorage11_3D(Renderer11 *renderer,
+                        GLenum internalformat,
+                        bool renderTarget,
+                        GLsizei width,
+                        GLsizei height,
+                        GLsizei depth,
+                        int levels);
     ~TextureStorage11_3D() override;
 
     gl::Error onDestroy(const gl::Context *context) override;
 
     gl::Error getResource(const gl::Context *context, const TextureHelper11 **outResource) override;
 
     // Handles both layer and non-layer RTs
     gl::Error getRenderTarget(const gl::Context *context,
@@ -439,40 +543,55 @@ class TextureStorage11_3D : public Textu
                                      const gl::ImageIndex &index,
                                      Image11 *incomingImage) override;
 
   protected:
     gl::Error getSwizzleTexture(const TextureHelper11 **outTexture) override;
     gl::Error getSwizzleRenderTarget(int mipLevel, const d3d11::RenderTargetView **outRTV) override;
 
   private:
-    gl::Error createSRV(const gl::Context *context,
-                        int baseLevel,
-                        int mipLevels,
-                        DXGI_FORMAT format,
-                        const TextureHelper11 &texture,
-                        d3d11::SharedSRV *outSRV) const override;
+    gl::Error createSRVForSampler(const gl::Context *context,
+                                  int baseLevel,
+                                  int mipLevels,
+                                  DXGI_FORMAT format,
+                                  const TextureHelper11 &texture,
+                                  d3d11::SharedSRV *outSRV) override;
+    gl::Error createSRVForImage(const gl::Context *context,
+                                int level,
+                                DXGI_FORMAT format,
+                                const TextureHelper11 &texture,
+                                d3d11::SharedSRV *outSRV) override;
+    gl::Error createUAVForImage(const gl::Context *context,
+                                int level,
+                                DXGI_FORMAT format,
+                                const TextureHelper11 &texture,
+                                d3d11::SharedUAV *outUAV) override;
 
     typedef std::pair<int, int> LevelLayerKey;
     std::map<LevelLayerKey, std::unique_ptr<RenderTarget11>> mLevelLayerRenderTargets;
 
     TexLevelArray<std::unique_ptr<RenderTarget11>> mLevelRenderTargets;
 
     TextureHelper11 mTexture;
     TextureHelper11 mSwizzleTexture;
     TexLevelArray<d3d11::RenderTargetView> mSwizzleRenderTargets;
 
     TexLevelArray<Image11 *> mAssociatedImages;
 };
 
 class TextureStorage11_2DArray : public TextureStorage11
 {
   public:
-    TextureStorage11_2DArray(Renderer11 *renderer, GLenum internalformat, bool renderTarget,
-                             GLsizei width, GLsizei height, GLsizei depth, int levels);
+    TextureStorage11_2DArray(Renderer11 *renderer,
+                             GLenum internalformat,
+                             bool renderTarget,
+                             GLsizei width,
+                             GLsizei height,
+                             GLsizei depth,
+                             int levels);
     ~TextureStorage11_2DArray() override;
 
     gl::Error onDestroy(const gl::Context *context) override;
 
     gl::Error getResource(const gl::Context *context, const TextureHelper11 **outResource) override;
     gl::Error getRenderTarget(const gl::Context *context,
                               const gl::ImageIndex &index,
                               RenderTargetD3D **outRT) override;
@@ -510,22 +629,32 @@ class TextureStorage11_2DArray : public 
             return numLayers < other.numLayers;
         }
         int mipLevel;
         int layer;
         int numLayers;
     };
 
   private:
-    gl::Error createSRV(const gl::Context *context,
-                        int baseLevel,
-                        int mipLevels,
-                        DXGI_FORMAT format,
-                        const TextureHelper11 &texture,
-                        d3d11::SharedSRV *outSRV) const override;
+    gl::Error createSRVForSampler(const gl::Context *context,
+                                  int baseLevel,
+                                  int mipLevels,
+                                  DXGI_FORMAT format,
+                                  const TextureHelper11 &texture,
+                                  d3d11::SharedSRV *outSRV) override;
+    gl::Error createSRVForImage(const gl::Context *context,
+                                int level,
+                                DXGI_FORMAT format,
+                                const TextureHelper11 &texture,
+                                d3d11::SharedSRV *outSRV) override;
+    gl::Error createUAVForImage(const gl::Context *context,
+                                int level,
+                                DXGI_FORMAT format,
+                                const TextureHelper11 &texture,
+                                d3d11::SharedUAV *outUAV) override;
     gl::Error createRenderTargetSRV(const TextureHelper11 &texture,
                                     const gl::ImageIndex &index,
                                     DXGI_FORMAT resourceFormat,
                                     d3d11::SharedSRV *srv) const;
 
     std::map<LevelLayerRangeKey, std::unique_ptr<RenderTarget11>> mRenderTargets;
 
     TextureHelper11 mTexture;
@@ -541,17 +670,17 @@ class TextureStorage11_2DMultisample : p
 {
   public:
     TextureStorage11_2DMultisample(Renderer11 *renderer,
                                    GLenum internalformat,
                                    GLsizei width,
                                    GLsizei height,
                                    int levels,
                                    int samples,
-                                   GLboolean fixedSampleLocations);
+                                   bool fixedSampleLocations);
     ~TextureStorage11_2DMultisample() override;
 
     gl::Error onDestroy(const gl::Context *context) override;
 
     gl::Error getResource(const gl::Context *context, const TextureHelper11 **outResource) override;
     gl::Error getRenderTarget(const gl::Context *context,
                               const gl::ImageIndex &index,
                               RenderTargetD3D **outRT) override;
@@ -569,22 +698,32 @@ class TextureStorage11_2DMultisample : p
     gl::Error getSwizzleTexture(const TextureHelper11 **outTexture) override;
     gl::Error getSwizzleRenderTarget(int mipLevel, const d3d11::RenderTargetView **outRTV) override;
 
     gl::ErrorOrResult<DropStencil> ensureDropStencilTexture(const gl::Context *context) override;
 
     gl::Error ensureTextureExists(int mipLevels);
 
   private:
-    gl::Error createSRV(const gl::Context *context,
-                        int baseLevel,
-                        int mipLevels,
-                        DXGI_FORMAT format,
-                        const TextureHelper11 &texture,
-                        d3d11::SharedSRV *outSRV) const override;
+    gl::Error createSRVForSampler(const gl::Context *context,
+                                  int baseLevel,
+                                  int mipLevels,
+                                  DXGI_FORMAT format,
+                                  const TextureHelper11 &texture,
+                                  d3d11::SharedSRV *outSRV) override;
+    gl::Error createSRVForImage(const gl::Context *context,
+                                int level,
+                                DXGI_FORMAT format,
+                                const TextureHelper11 &texture,
+                                d3d11::SharedSRV *outSRV) override;
+    gl::Error createUAVForImage(const gl::Context *context,
+                                int level,
+                                DXGI_FORMAT format,
+                                const TextureHelper11 &texture,
+                                d3d11::SharedUAV *outUAV) override;
 
     TextureHelper11 mTexture;
     std::unique_ptr<RenderTarget11> mRenderTarget;
 
     unsigned int mSamples;
     GLboolean mFixedSampleLocations;
 };
 }
--- a/gfx/angle/src/libANGLE/renderer/d3d/d3d11/VertexArray11.cpp
+++ b/gfx/angle/src/libANGLE/renderer/d3d/d3d11/VertexArray11.cpp
@@ -14,91 +14,182 @@
 #include "libANGLE/renderer/d3d/d3d11/Buffer11.h"
 #include "libANGLE/renderer/d3d/d3d11/Context11.h"
 
 using namespace angle;
 
 namespace rx
 {
 
+namespace
+{
+OnBufferDataDirtyChannel *GetBufferBroadcastChannel(Buffer11 *buffer11,
+                                                    IndexStorageType storageType)
+{
+    switch (storageType)
+    {
+        case IndexStorageType::Direct:
+            return buffer11->getDirectBroadcastChannel();
+        case IndexStorageType::Static:
+            return buffer11->getStaticBroadcastChannel();
+        case IndexStorageType::Dynamic:
+            return buffer11 ? buffer11->getStaticBroadcastChannel() : nullptr;
+        default:
+            UNREACHABLE();
+            return nullptr;
+    }
+}
+}  // anonymous namespace
+
 VertexArray11::VertexArray11(const gl::VertexArrayState &data)
     : VertexArrayImpl(data),
       mAttributeStorageTypes(data.getMaxAttribs(), VertexStorageType::CURRENT_VALUE),
       mTranslatedAttribs(data.getMaxAttribs()),
-      mCurrentBuffers(data.getMaxAttribs()),
-      mAppliedNumViewsToDivisor(1)
+      mCurrentArrayBuffers(data.getMaxAttribs()),
+      mCurrentElementArrayBuffer(),
+      mOnArrayBufferDataDirty(),
+      mOnElementArrayBufferDataDirty(this, mCurrentArrayBuffers.size()),
+      mAppliedNumViewsToDivisor(1),
+      mLastElementType(GL_NONE),
+      mLastDrawElementsOffset(0),
+      mCurrentElementArrayStorage(IndexStorageType::Invalid),
+      mCachedIndexInfoValid(false)
 {
-    for (size_t attribIndex = 0; attribIndex < mCurrentBuffers.size(); ++attribIndex)
+    for (size_t attribIndex = 0; attribIndex < mCurrentArrayBuffers.size(); ++attribIndex)
     {
-        mOnBufferDataDirty.emplace_back(this, attribIndex);
+        mOnArrayBufferDataDirty.emplace_back(this, attribIndex);
     }
 }
 
+VertexArray11::~VertexArray11()
+{
+}
+
 void VertexArray11::destroy(const gl::Context *context)
 {
-    for (auto &buffer : mCurrentBuffers)
+    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)
 {
     ASSERT(dirtyBits.any());
 
     // 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.
-    auto renderer       = GetImplAs<Context11>(context)->getRenderer();
+    Renderer11 *renderer = GetImplAs<Context11>(context)->getRenderer();
     mCurrentStateSerial = renderer->generateSerial();
 
     // TODO(jmadill): Individual attribute invalidation.
     renderer->getStateManager()->invalidateVertexBuffer();
 
     for (auto dirtyBit : dirtyBits)
     {
         if (dirtyBit == gl::VertexArray::DIRTY_BIT_ELEMENT_ARRAY_BUFFER)
-            continue;
-
-        size_t index = gl::VertexArray::GetVertexIndexFromDirtyBit(dirtyBit);
-        // TODO(jiawei.shao@intel.com): Vertex Attrib Bindings
-        ASSERT(index == mData.getBindingIndexFromAttribIndex(index));
-        mAttribsToUpdate.set(index);
+        {
+            mCachedIndexInfoValid = false;
+            mLastElementType      = GL_NONE;
+        }
+        else
+        {
+            size_t index = gl::VertexArray::GetVertexIndexFromDirtyBit(dirtyBit);
+            // TODO(jiawei.shao@intel.com): Vertex Attrib Bindings
+            ASSERT(index == mState.getBindingIndexFromAttribIndex(index));
+            mAttribsToUpdate.set(index);
+        }
     }
 }
 
 bool VertexArray11::flushAttribUpdates(const gl::Context *context)
 {
-    const gl::Program *program  = context->getGLState().getProgram();
-    const auto &activeLocations = program->getActiveAttribLocationsMask();
-
     if (mAttribsToUpdate.any())
     {
+        const auto &activeLocations =
+            context->getGLState().getProgram()->getActiveAttribLocationsMask();
+
         // 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;
     }
 
     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);
+    }
+
+    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)
+    {
+        Buffer11 *newBuffer11 = SafeGetImplAs<Buffer11>(newBuffer);
+
+        auto *newChannel = GetBufferBroadcastChannel(newBuffer11, newStorageType);
+
+        mCurrentElementArrayStorage = newStorageType;
+        mOnElementArrayBufferDataDirty.bind(newChannel);
+        needsTranslation = true;
+    }
+
+    if (mLastDrawElementsOffset != offset)
+    {
+        needsTranslation        = true;
+        mLastDrawElementsOffset = offset;
+    }
+
+    if (mLastElementType != elementType)
+    {
+        needsTranslation = true;
+        mLastElementType = elementType;
+    }
+
+    // TODO(jmadill): We should probably promote static usage immediately, because this can change
+    // the storage type for dynamic buffers.
+    return needsTranslation || !mCachedIndexInfoValid;
+}
+
 void VertexArray11::updateVertexAttribStorage(const gl::Context *context, size_t attribIndex)
 {
-    const auto &attrib = mData.getVertexAttribute(attribIndex);
-    const auto &binding = mData.getBindingFromAttribIndex(attribIndex);
+    const auto &attrib  = mState.getVertexAttribute(attribIndex);
+    const auto &binding = mState.getBindingFromAttribIndex(attribIndex);
 
     // Note: having an unchanged storage type doesn't mean the attribute is clean.
     auto oldStorageType = mAttributeStorageTypes[attribIndex];
     auto newStorageType = ClassifyAttributeStorage(attrib, binding);
 
     mAttributeStorageTypes[attribIndex] = newStorageType;
 
     StateManager11 *stateManager = GetImplAs<Context11>(context)->getRenderer()->getStateManager();
@@ -119,17 +210,17 @@ void VertexArray11::updateVertexAttribSt
 
         if (oldStorageType == VertexStorageType::DYNAMIC)
         {
             ASSERT(mDynamicAttribsMask[attribIndex]);
             mDynamicAttribsMask.reset(attribIndex);
         }
     }
 
-    gl::Buffer *oldBufferGL = mCurrentBuffers[attribIndex].get();
+    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)
     {
         OnBufferDataDirtyChannel *newChannel = nullptr;
 
@@ -151,46 +242,41 @@ void VertexArray11::updateVertexAttribSt
                     newChannel = newBuffer11->getStaticBroadcastChannel();
                     break;
                 default:
                     UNREACHABLE();
                     break;
             }
         }
 
-        mOnBufferDataDirty[attribIndex].bind(newChannel);
-        mCurrentBuffers[attribIndex].set(context, binding.getBuffer().get());
+        mOnArrayBufferDataDirty[attribIndex].bind(newChannel);
+        mCurrentArrayBuffers[attribIndex].set(context, binding.getBuffer().get());
     }
 }
 
-bool VertexArray11::hasDynamicAttrib(const gl::Context *context)
+bool VertexArray11::hasActiveDynamicAttrib(const gl::Context *context)
 {
     flushAttribUpdates(context);
-    return mDynamicAttribsMask.any();
-}
-
-bool VertexArray11::hasDirtyOrDynamicAttrib(const gl::Context *context)
-{
-    flushAttribUpdates(context);
-    return mAttribsToTranslate.any() || mDynamicAttribsMask.any();
+    const auto &activeLocations =
+        context->getGLState().getProgram()->getActiveAttribLocationsMask();
+    auto activeDynamicAttribs = (mDynamicAttribsMask & activeLocations);
+    return activeDynamicAttribs.any();
 }
 
 gl::Error VertexArray11::updateDirtyAndDynamicAttribs(const gl::Context *context,
                                                       VertexDataManager *vertexDataManager,
-                                                      GLint start,
-                                                      GLsizei count,
-                                                      GLsizei instances)
+                                                      const DrawCallVertexParams &vertexParams)
 {
     flushAttribUpdates(context);
 
     const auto &glState         = context->getGLState();
     const gl::Program *program  = glState.getProgram();
     const auto &activeLocations = program->getActiveAttribLocationsMask();
-    const auto &attribs         = mData.getVertexAttributes();
-    const auto &bindings        = mData.getVertexBindings();
+    const auto &attribs         = mState.getVertexAttributes();
+    const auto &bindings        = mState.getVertexBindings();
     mAppliedNumViewsToDivisor =
         (program != nullptr && program->usesMultiview()) ? program->getNumViews() : 1;
 
     if (mAttribsToTranslate.any())
     {
         // Skip attrib locations the program doesn't use, saving for the next frame.
         gl::AttributesMask dirtyActiveAttribs = (mAttribsToTranslate & activeLocations);
 
@@ -226,69 +312,102 @@ gl::Error VertexArray11::updateDirtyAndD
                     break;
             }
         }
     }
 
     if (mDynamicAttribsMask.any())
     {
         auto activeDynamicAttribs = (mDynamicAttribsMask & activeLocations);
+        if (activeDynamicAttribs.none())
+        {
+            return gl::NoError();
+        }
 
         for (auto dynamicAttribIndex : activeDynamicAttribs)
         {
             auto *dynamicAttrib = &mTranslatedAttribs[dynamicAttribIndex];
             const auto &currentValue = glState.getVertexAttribCurrentValue(dynamicAttribIndex);
 
             // 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, start, count, instances));
+            context, &mTranslatedAttribs, activeDynamicAttribs, vertexParams.firstVertex(),
+            vertexParams.vertexCount(), vertexParams.instances()));
     }
 
     return gl::NoError();
 }
 
 const std::vector<TranslatedAttribute> &VertexArray11::getTranslatedAttribs() const
 {
     return mTranslatedAttribs;
 }
 
 void VertexArray11::signal(size_t channelID, const gl::Context *context)
 {
-    ASSERT(mAttributeStorageTypes[channelID] != VertexStorageType::CURRENT_VALUE);
+    if (channelID == mAttributeStorageTypes.size())
+    {
+        mCachedIndexInfoValid   = false;
+        mLastElementType        = GL_NONE;
+        mLastDrawElementsOffset = 0;
+    }
+    else
+    {
+        ASSERT(mAttributeStorageTypes[channelID] != VertexStorageType::CURRENT_VALUE);
 
-    // This can change a buffer's storage, we'll need to re-check.
-    mAttribsToUpdate.set(channelID);
+        // This can change a buffer's storage, we'll need to re-check.
+        mAttribsToUpdate.set(channelID);
 
-    // Changing the vertex attribute state can affect the vertex shader.
-    Renderer11 *renderer = GetImplAs<Context11>(context)->getRenderer();
-    renderer->getStateManager()->invalidateShaders();
+        // 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, GLsizei count)
+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);
-    VertexDataManager::PromoteDynamicAttribs(context, mTranslatedAttribs, activeDynamicAttribs,
-                                             count);
+    if (activeDynamicAttribs.any())
+    {
+        VertexDataManager::PromoteDynamicAttribs(context, mTranslatedAttribs, activeDynamicAttribs,
+                                                 vertexParams.vertexCount());
+    }
 }
 
 void VertexArray11::markAllAttributeDivisorsForAdjustment(int numViews)
 {
     if (mAppliedNumViewsToDivisor != numViews)
     {
         mAppliedNumViewsToDivisor = numViews;
         mAttribsToUpdate.set();
     }
 }
 
+TranslatedIndexData *VertexArray11::getCachedIndexInfo()
+{
+    return &mCachedIndexInfo;
+}
+
+void VertexArray11::setCachedIndexInfoValid()
+{
+    mCachedIndexInfoValid = true;
+}
+
+bool VertexArray11::isCachedIndexInfoValid() const
+{
+    return mCachedIndexInfoValid;
+}
+
 }  // namespace rx
--- a/gfx/angle/src/libANGLE/renderer/d3d/d3d11/VertexArray11.h
+++ b/gfx/angle/src/libANGLE/renderer/d3d/d3d11/VertexArray11.h
@@ -7,74 +7,93 @@
 // VertexArray11.h: Defines the rx::VertexArray11 class which implements rx::VertexArrayImpl.
 
 #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 OnBufferDataDirtyReceiver
 {
   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.
-    bool hasDynamicAttrib(const gl::Context *context);
-    bool hasDirtyOrDynamicAttrib(const gl::Context *context);
+    bool hasActiveDynamicAttrib(const gl::Context *context);
     gl::Error updateDirtyAndDynamicAttribs(const gl::Context *context,
                                            VertexDataManager *vertexDataManager,
-                                           GLint start,
-                                           GLsizei count,
-                                           GLsizei instances);
-    void clearDirtyAndPromoteDynamicAttribs(const gl::Context *context, GLsizei count);
+                                           const DrawCallVertexParams &vertexParams);
+    void clearDirtyAndPromoteDynamicAttribs(const gl::Context *context,
+                                            const DrawCallVertexParams &vertexParams);
 
     const std::vector<TranslatedAttribute> &getTranslatedAttribs() const;
 
     // SignalReceiver implementation
     void signal(size_t channelID, const gl::Context *context) 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.
+    bool updateElementArrayStorage(const gl::Context *context,
+                                   GLenum elementType,
+                                   GLenum destElementType,
+                                   const void *indices);
+
+    TranslatedIndexData *getCachedIndexInfo();
+    void setCachedIndexInfoValid();
+    bool isCachedIndexInfoValid() const;
+
   private:
     void updateVertexAttribStorage(const gl::Context *context, size_t attribIndex);
 
     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;
 
     // 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>> mCurrentBuffers;
+    std::vector<gl::BindingPointer<gl::Buffer>> mCurrentArrayBuffers;
+    gl::BindingPointer<gl::Buffer> mCurrentElementArrayBuffer;
 
-    std::vector<OnBufferDataDirtyBinding> mOnBufferDataDirty;
+    std::vector<OnBufferDataDirtyBinding> mOnArrayBufferDataDirty;
+    OnBufferDataDirtyBinding 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;
+    IndexStorageType mCurrentElementArrayStorage;
+    TranslatedIndexData mCachedIndexInfo;
+    bool mCachedIndexInfoValid;
 };
 
 }  // namespace rx
 
 #endif // LIBANGLE_RENDERER_D3D_D3D11_VERTEXARRAY11_H_
--- a/gfx/angle/src/libANGLE/renderer/d3d/d3d11/VertexBuffer11.cpp
+++ b/gfx/angle/src/libANGLE/renderer/d3d/d3d11/VertexBuffer11.cpp
@@ -65,27 +65,20 @@ gl::Error VertexBuffer11::initialize(uns
 
     return gl::NoError();
 }
 
 gl::Error VertexBuffer11::mapResource()
 {
     if (mMappedResourceData == nullptr)
     {
-        ID3D11DeviceContext *dxContext = mRenderer->getDeviceContext();
-
         D3D11_MAPPED_SUBRESOURCE mappedResource;
 
-        HRESULT result =
-            dxContext->Map(mBuffer.get(), 0, D3D11_MAP_WRITE_NO_OVERWRITE, 0, &mappedResource);
-        if (FAILED(result))
-        {
-            return gl::OutOfMemory()
-                   << "Failed to map internal vertex buffer, " << gl::FmtHR(result);
-        }
+        ANGLE_TRY(mRenderer->mapResource(mBuffer.get(), 0, D3D11_MAP_WRITE_NO_OVERWRITE, 0,
+                                         &mappedResource));
 
         mMappedResourceData = reinterpret_cast<uint8_t *>(mappedResource.pData);
     }
 
     return gl::NoError();
 }
 
 void VertexBuffer11::hintUnmapResource()
@@ -156,27 +149,21 @@ gl::Error VertexBuffer11::setBufferSize(
 
 gl::Error VertexBuffer11::discard()
 {
     if (!mBuffer.valid())
     {
         return gl::OutOfMemory() << "Internal vertex buffer is not initialized.";
     }
 
-    ID3D11DeviceContext *dxContext = mRenderer->getDeviceContext();
+    D3D11_MAPPED_SUBRESOURCE mappedResource;
+    ANGLE_TRY(
+        mRenderer->mapResource(mBuffer.get(), 0, D3D11_MAP_WRITE_DISCARD, 0, &mappedResource));
 
-    D3D11_MAPPED_SUBRESOURCE mappedResource;
-    HRESULT result = dxContext->Map(mBuffer.get(), 0, D3D11_MAP_WRITE_DISCARD, 0, &mappedResource);
-    if (FAILED(result))
-    {
-        return gl::OutOfMemory() << "Failed to map internal buffer for discarding, "
-                                 << gl::FmtHR(result);
-    }
-
-    dxContext->Unmap(mBuffer.get(), 0);
+    mRenderer->getDeviceContext()->Unmap(mBuffer.get(), 0);
 
     return gl::NoError();
 }
 
 const d3d11::Buffer &VertexBuffer11::getBuffer() const
 {
     return mBuffer;
 }
--- a/gfx/angle/src/libANGLE/renderer/d3d/d3d11/dxgi_format_map_autogen.cpp
+++ b/gfx/angle/src/libANGLE/renderer/d3d/d3d11/dxgi_format_map_autogen.cpp
@@ -1,12 +1,12 @@
 // GENERATED FILE - DO NOT EDIT.
 // Generated by gen_dxgi_format_table.py using data from dxgi_format_data.json.
 //
-// Copyright 2016 The ANGLE Project Authors. All rights reserved.
+// 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.
 //
 // DXGI format info:
 //   Determining metadata about a DXGI format.
 
 #include "libANGLE/renderer/Format.h"
 
@@ -287,17 +287,17 @@ const Format &GetFormat(DXGI_FORMAT dxgi
             return Format::Get(Format::ID::B5G5R5A1_UNORM);
         case DXGI_FORMAT_B5G6R5_UNORM:
             return Format::Get(Format::ID::B5G6R5_UNORM);
         case DXGI_FORMAT_B8G8R8A8_TYPELESS:
             break;
         case DXGI_FORMAT_B8G8R8A8_UNORM:
             return Format::Get(Format::ID::B8G8R8A8_UNORM);
         case DXGI_FORMAT_B8G8R8A8_UNORM_SRGB:
-            break;
+            return Format::Get(Format::ID::B8G8R8A8_UNORM_SRGB);
         case DXGI_FORMAT_B8G8R8X8_TYPELESS:
             break;
         case DXGI_FORMAT_B8G8R8X8_UNORM:
             return Format::Get(Format::ID::B8G8R8X8_UNORM);
         case DXGI_FORMAT_B8G8R8X8_UNORM_SRGB:
             break;
         case DXGI_FORMAT_BC1_TYPELESS:
             break;
--- a/gfx/angle/src/libANGLE/renderer/d3d/d3d11/gen_texture_format_table.py
+++ b/gfx/angle/src/libANGLE/renderer/d3d/d3d11/gen_texture_format_table.py
@@ -82,17 +82,17 @@ def get_swizzle_format_id(internal_forma
         raise ValueError('no bits information for determining swizzleformat for format: ' + internal_format)
 
     bits = angle_format['bits']
     max_component_bits = max(bits.itervalues())
     channels_different = not all([component_bits == bits.itervalues().next() for component_bits in bits.itervalues()])
 
     # The format itself can be used for swizzles if it can be accessed as a render target and
     # sampled and the bit count for all 4 channels is the same.
-    if "rtvFormat" in angle_format and "srvFormat" in angle_format and not channels_different and len(angle_format['channels']) == 4:
+    if "rtvFormat" in angle_format and "srvFormat" in angle_format and "uavFormat" in angle_format and not channels_different and len(angle_format['channels']) == 4:
         return angle_format["glInternalFormat"] if "glInternalFormat" in angle_format else internal_format
 
     b = int(math.ceil(float(max_component_bits) / 8) * 8)
 
     # Depth formats need special handling, since combined depth/stencil formats don't have a clearly
     # defined component type.
     if angle_format['channels'].find('d') >= 0:
         if b == 24 or b == 32:
@@ -139,31 +139,33 @@ def get_blit_srv_format(angle_format):
     return angle_format["srvFormat"] if "srvFormat" in angle_format else "DXGI_FORMAT_UNKNOWN"
 
 
 format_entry_template = """{space}{{
 {space}    static constexpr Format info({internalFormat},
 {space}                                 angle::Format::ID::{formatName},
 {space}                                 {texFormat},
 {space}                                 {srvFormat},
+{space}                                 {uavFormat},
 {space}                                 {rtvFormat},
 {space}                                 {dsvFormat},
 {space}                                 {blitSRVFormat},
 {space}                                 {swizzleFormat},
 {space}                                 {initializer});
 {space}    return info;
 {space}}}
 """
 
 split_format_entry_template = """{space}    {condition}
 {space}    {{
 {space}        static constexpr Format info({internalFormat},
 {space}                                     angle::Format::ID::{formatName},
 {space}                                     {texFormat},
 {space}                                     {srvFormat},
+{space}                                     {uavFormat},
 {space}                                     {rtvFormat},
 {space}                                     {dsvFormat},
 {space}                                     {blitSRVFormat},
 {space}                                     {swizzleFormat},
 {space}                                     {initializer});
 {space}        return info;
 {space}    }}
 """
@@ -173,16 +175,17 @@ def json_to_table_data(internal_format, 
     table_data = ""
 
     parsed = {
         "space": "        ",
         "internalFormat": internal_format,
         "formatName": format_name,
         "texFormat": "DXGI_FORMAT_UNKNOWN",
         "srvFormat": "DXGI_FORMAT_UNKNOWN",
+        "uavFormat": "DXGI_FORMAT_UNKNOWN",
         "rtvFormat": "DXGI_FORMAT_UNKNOWN",
         "dsvFormat": "DXGI_FORMAT_UNKNOWN",
         "condition": prefix,
     }
 
     for k, v in json.iteritems():
         parsed[k] = v
 
--- a/gfx/angle/src/libANGLE/renderer/d3d/d3d11/renderer11_utils.cpp
+++ b/gfx/angle/src/libANGLE/renderer/d3d/d3d11/renderer11_utils.cpp
@@ -7,25 +7,31 @@
 // renderer11_utils.cpp: Conversion functions and other utility routines
 // specific to the D3D11 renderer.
 
 #include "libANGLE/renderer/d3d/d3d11/renderer11_utils.h"
 
 #include <algorithm>
 
 #include "common/debug.h"
-#include "libANGLE/formatutils.h"
+#include "libANGLE/Buffer.h"
+#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/Renderer11.h"
-#include "libANGLE/renderer/d3d/d3d11/RenderTarget11.h"
 #include "libANGLE/renderer/d3d/d3d11/texture_format_table.h"
-#include "libANGLE/renderer/d3d/FramebufferD3D.h"
 #include "libANGLE/renderer/driver_utils.h"
 #include "platform/Platform.h"
 #include "platform/WorkaroundsD3D.h"
 
 namespace rx
 {
 
 namespace d3d11_gl
@@ -41,16 +47,19 @@ static constexpr std::array<SamplePositi
      {{0.375f, 0.125f, 0.875f, 0.375f, 0.125f, 0.625f, 0.625f, 0.875f}},
      {{0.5625f, 0.3125f, 0.4375f, 0.6875f, 0.8125f, 0.5625f, 0.3125f, 0.1875f, 0.1875f, 0.8125f,
        0.0625f, 0.4375f, 0.6875f, 0.9375f, 0.9375f, 0.0625f}},
      {{0.5625f, 0.5625f, 0.4375f, 0.3125f, 0.3125f, 0.625f,  0.75f,   0.4375f,
        0.1875f, 0.375f,  0.625f,  0.8125f, 0.8125f, 0.6875f, 0.6875f, 0.1875f,
        0.375f,  0.875f,  0.5f,    0.0625f, 0.25f,   0.125f,  0.125f,  0.75f,
        0.0f,    0.5f,    0.9375f, 0.25f,   0.875f,  0.9375f, 0.0625f, 0.0f}}}};
 
+// TODO(xinghua.cao@intel.com): Get a more accurate limit.
+static D3D_FEATURE_LEVEL kMinimumFeatureLevelForES31 = D3D_FEATURE_LEVEL_11_0;
+
 // Helper functor for querying DXGI support. Saves passing the parameters repeatedly.
 class DXGISupportHelper : angle::NonCopyable
 {
   public:
     DXGISupportHelper(ID3D11Device *device, D3D_FEATURE_LEVEL featureLevel)
         : mDevice(device), mFeatureLevel(featureLevel)
     {
     }
@@ -916,16 +925,44 @@ size_t GetMaximumComputeTextureUnits(D3D
         case D3D_FEATURE_LEVEL_11_1:
         case D3D_FEATURE_LEVEL_11_0:
             return D3D11_COMMONSHADER_SAMPLER_SLOT_COUNT;
         default:
             return 0;
     }
 }
 
+size_t GetMaximumImageUnits(D3D_FEATURE_LEVEL featureLevel)
+{
+    switch (featureLevel)
+    {
+        case D3D_FEATURE_LEVEL_11_1:
+        case D3D_FEATURE_LEVEL_11_0:
+            // TODO(xinghua.cao@intel.com): Get a more accurate limit. For now using
+            // the minimum requirement for GLES 3.1.
+            return 4;
+        default:
+            return 0;
+    }
+}
+
+size_t GetMaximumComputeImageUniforms(D3D_FEATURE_LEVEL featureLevel)
+{
+    switch (featureLevel)
+    {
+        case D3D_FEATURE_LEVEL_11_1:
+        case D3D_FEATURE_LEVEL_11_0:
+            // TODO(xinghua.cao@intel.com): Get a more accurate limit. For now using
+            // the minimum requirement for GLES 3.1.
+            return 4;
+        default:
+            return 0;
+    }
+}
+
 int GetMinimumTexelOffset(D3D_FEATURE_LEVEL featureLevel)
 {
     switch (featureLevel)
     {
         case D3D_FEATURE_LEVEL_11_1:
         case D3D_FEATURE_LEVEL_11_0:
             return D3D11_COMMONSHADER_TEXEL_OFFSET_MAX_NEGATIVE;
 
@@ -1169,16 +1206,21 @@ gl::Version GetMaximumClientVersion(D3D_
             return gl::Version(2, 0);
 
         default:
             UNREACHABLE();
             return gl::Version(0, 0);
     }
 }
 
+D3D_FEATURE_LEVEL GetMinimumFeatureLevelForES31()
+{
+    return kMinimumFeatureLevelForES31;
+}
+
 unsigned int GetMaxViewportAndScissorRectanglesPerPipeline(D3D_FEATURE_LEVEL featureLevel)
 {
     switch (featureLevel)
     {
         case D3D_FEATURE_LEVEL_11_1:
         case D3D_FEATURE_LEVEL_11_0:
             return D3D11_VIEWPORT_AND_SCISSORRECT_OBJECT_COUNT_PER_PIPELINE;
         case D3D_FEATURE_LEVEL_10_1:
@@ -1201,18 +1243,44 @@ bool IsMultiviewSupported(D3D_FEATURE_LE
         case D3D_FEATURE_LEVEL_11_1:
         case D3D_FEATURE_LEVEL_11_0:
             return true;
         default:
             return false;
     }
 }
 
-void GenerateCaps(ID3D11Device *device, ID3D11DeviceContext *deviceContext, const Renderer11DeviceCaps &renderer11DeviceCaps, gl::Caps *caps,
-                  gl::TextureCapsMap *textureCapsMap, gl::Extensions *extensions, gl::Limitations *limitations)
+unsigned int GetMaxSampleMaskWords(D3D_FEATURE_LEVEL featureLevel)
+{
+    switch (featureLevel)
+    {
+        // D3D10+ only allows 1 sample mask.
+        case D3D_FEATURE_LEVEL_11_1:
+        case D3D_FEATURE_LEVEL_11_0:
+        case D3D_FEATURE_LEVEL_10_1:
+        case D3D_FEATURE_LEVEL_10_0:
+            return 1u;
+        case D3D_FEATURE_LEVEL_9_3:
+        case D3D_FEATURE_LEVEL_9_2:
+        case D3D_FEATURE_LEVEL_9_1:
+            return 0u;
+        default:
+            UNREACHABLE();
+            return 0u;
+    }
+}
+
+void GenerateCaps(ID3D11Device *device,
+                  ID3D11DeviceContext *deviceContext,
+                  const Renderer11DeviceCaps &renderer11DeviceCaps,
+                  const angle::WorkaroundsD3D &workarounds,
+                  gl::Caps *caps,
+                  gl::TextureCapsMap *textureCapsMap,
+                  gl::Extensions *extensions,
+                  gl::Limitations *limitations)
 {
     D3D_FEATURE_LEVEL featureLevel = renderer11DeviceCaps.featureLevel;
     const gl::FormatSet &allFormats = gl::GetAllSizedInternalFormats();
     for (GLenum internalFormat : allFormats)
     {
         gl::TextureCaps textureCaps = GenerateTextureFormatCaps(
             GetMaximumClientVersion(featureLevel), internalFormat, device, renderer11DeviceCaps);
         textureCapsMap->insert(internalFormat, textureCaps);
@@ -1277,58 +1345,71 @@ void GenerateCaps(ID3D11Device *device, 
     caps->fragmentMediumpInt.setTwosComplementInt(32);
     caps->fragmentLowpInt.setTwosComplementInt(32);
 
     // We do not wait for server fence objects internally, so report a max timeout of zero.
     caps->maxServerWaitTimeout = 0;
 
     // Vertex shader limits
     caps->maxVertexAttributes = static_cast<GLuint>(GetMaximumVertexInputSlots(featureLevel));
-    caps->maxVertexUniformComponents =
-        static_cast<GLuint>(GetMaximumVertexUniformVectors(featureLevel)) * 4;
     caps->maxVertexUniformVectors =
         static_cast<GLuint>(GetMaximumVertexUniformVectors(featureLevel));
+    if (workarounds.skipConstantRegisterZero)
+    {
+        caps->maxVertexUniformVectors -= 1;
+    }
+    caps->maxVertexUniformComponents = caps->maxVertexUniformVectors * 4;
     caps->maxVertexUniformBlocks = static_cast<GLuint>(GetMaximumVertexUniformBlocks(featureLevel));
     caps->maxVertexOutputComponents =
         static_cast<GLuint>(GetMaximumVertexOutputVectors(featureLevel)) * 4;
     caps->maxVertexTextureImageUnits =
         static_cast<GLuint>(GetMaximumVertexTextureUnits(featureLevel));
 
     // Vertex Attribute Bindings are emulated on D3D11.
     caps->maxVertexAttribBindings = caps->maxVertexAttributes;
     // Experimental testing confirmed there is no explicit limit on maximum buffer offset in D3D11.
     caps->maxVertexAttribRelativeOffset = std::numeric_limits<GLint>::max();
     // Experimental testing confirmed 2048 is the maximum stride that D3D11 can support on all
     // platforms.
     caps->maxVertexAttribStride = 2048;
 
     // Fragment shader limits
-    caps->maxFragmentUniformComponents =
-        static_cast<GLuint>(GetMaximumPixelUniformVectors(featureLevel)) * 4;
     caps->maxFragmentUniformVectors =
         static_cast<GLuint>(GetMaximumPixelUniformVectors(featureLevel));
+    if (workarounds.skipConstantRegisterZero)
+    {
+        caps->maxFragmentUniformVectors -= 1;
+    }
+    caps->maxFragmentUniformComponents = caps->maxFragmentUniformVectors * 4;
     caps->maxFragmentUniformBlocks =
         static_cast<GLuint>(GetMaximumPixelUniformBlocks(featureLevel));
     caps->maxFragmentInputComponents =
         static_cast<GLuint>(GetMaximumPixelInputVectors(featureLevel)) * 4;
     caps->maxTextureImageUnits  = static_cast<GLuint>(GetMaximumPixelTextureUnits(featureLevel));
     caps->minProgramTexelOffset = GetMinimumTexelOffset(featureLevel);
     caps->maxProgramTexelOffset = GetMaximumTexelOffset(featureLevel);
 
     // Compute shader limits
     caps->maxComputeWorkGroupCount = GetMaxComputeWorkGroupCount(featureLevel);
     caps->maxComputeWorkGroupSize  = GetMaxComputeWorkGroupSize(featureLevel);
     caps->maxComputeWorkGroupInvocations =
         static_cast<GLuint>(GetMaxComputeWorkGroupInvocations(featureLevel));
     caps->maxComputeUniformComponents =
         static_cast<GLuint>(GetMaximumComputeUniformVectors(featureLevel)) * 4;
+    if (workarounds.skipConstantRegisterZero)
+    {
+        caps->maxComputeUniformComponents -= 4;
+    }
     caps->maxComputeUniformBlocks =
         static_cast<GLuint>(GetMaximumComputeUniformBlocks(featureLevel));
     caps->maxComputeTextureImageUnits =
         static_cast<GLuint>(GetMaximumComputeTextureUnits(featureLevel));
+    caps->maxImageUnits = static_cast<GLuint>(GetMaximumImageUnits(featureLevel));
+    caps->maxComputeImageUniforms =
+        static_cast<GLuint>(GetMaximumComputeImageUniforms(featureLevel));
 
     // Aggregate shader limits
     caps->maxUniformBufferBindings = caps->maxVertexUniformBlocks + caps->maxFragmentUniformBlocks;
     caps->maxUniformBlockSize = GetMaximumConstantBufferSize(featureLevel);
 
     // TODO(oetuaho): Get a more accurate limit. For now using the minimum requirement for GLES 3.1.
     caps->maxUniformLocations = 1024;
 
@@ -1361,16 +1442,19 @@ void GenerateCaps(ID3D11Device *device, 
 
     // Defer the computation of multisample limits to Context::updateCaps() where max*Samples values
     // are determined according to available sample counts for each individual format.
     caps->maxSamples             = std::numeric_limits<GLint>::max();
     caps->maxColorTextureSamples = std::numeric_limits<GLint>::max();
     caps->maxDepthTextureSamples = std::numeric_limits<GLint>::max();
     caps->maxIntegerSamples      = std::numeric_limits<GLint>::max();
 
+    // Sample mask words limits
+    caps->maxSampleMaskWords = GetMaxSampleMaskWords(featureLevel);
+
     // Framebuffer limits
     caps->maxFramebufferSamples = std::numeric_limits<GLint>::max();
     caps->maxFramebufferWidth =
         static_cast<GLuint>(GetMaximumRenderToBufferWindowSize(featureLevel));
     caps->maxFramebufferHeight = caps->maxFramebufferWidth;
 
     // GL extension support
     extensions->setTextureExtensionSupport(*textureCapsMap);
@@ -1383,17 +1467,16 @@ void GenerateCaps(ID3D11Device *device, 
     extensions->mapBufferRange = true;
     extensions->textureNPOT = GetNPOTTextureSupport(featureLevel);
     extensions->drawBuffers = GetMaximumSimultaneousRenderTargets(featureLevel) > 1;
     extensions->textureStorage = true;
     extensions->textureFilterAnisotropic = true;
     extensions->maxTextureAnisotropy = GetMaximumAnisotropy(featureLevel);
     extensions->occlusionQueryBoolean = GetOcclusionQuerySupport(featureLevel);
     extensions->fence = GetEventQuerySupport(featureLevel);
-    extensions->timerQuery = false; // Unimplemented
     extensions->disjointTimerQuery          = true;
     extensions->queryCounterBitsTimeElapsed = 64;
     extensions->queryCounterBitsTimestamp =
         0;  // Timestamps cannot be supported due to D3D11 limitations
     extensions->robustness = true;
     // Direct3D guarantees to return zero for any resource that is accessed out of bounds.
     // See https://msdn.microsoft.com/en-us/library/windows/desktop/ff476332(v=vs.85).aspx
     // and https://msdn.microsoft.com/en-us/library/windows/desktop/ff476900(v=vs.85).aspx
@@ -1576,31 +1659,31 @@ UINT8 ConvertColorMask(bool red, bool gr
     }
     if (alpha)
     {
         mask |= D3D11_COLOR_WRITE_ENABLE_ALPHA;
     }
     return mask;
 }
 
-D3D11_CULL_MODE ConvertCullMode(bool cullEnabled, GLenum cullMode)
+D3D11_CULL_MODE ConvertCullMode(bool cullEnabled, gl::CullFaceMode cullMode)
 {
     D3D11_CULL_MODE cull = D3D11_CULL_NONE;
 
     if (cullEnabled)
     {
         switch (cullMode)
         {
-            case GL_FRONT:
+            case gl::CullFaceMode::Front:
                 cull = D3D11_CULL_FRONT;
                 break;
-            case GL_BACK:
+            case gl::CullFaceMode::Back:
                 cull = D3D11_CULL_BACK;
                 break;
-            case GL_FRONT_AND_BACK:
+            case gl::CullFaceMode::FrontAndBack:
                 cull = D3D11_CULL_NONE;
                 break;
             default:
                 UNREACHABLE();
         }
     }
     else
     {
@@ -2021,16 +2104,88 @@ HRESULT SetDebugName(ID3D11DeviceChild *
         return resource->SetPrivateData(WKPDID_D3DDebugObjectName,
                                         static_cast<unsigned int>(strlen(name)), name);
     }
 #else
     return S_OK;
 #endif
 }
 
+// Keep this in cpp file where it has visibility of Renderer11.h, otherwise calling
+// allocateResource is only compatible with Clang and MSVS, which support calling a
+// method on a forward declared class in a template.
+template <ResourceType ResourceT>
+gl::Error LazyResource<ResourceT>::resolveImpl(Renderer11 *renderer,
+                                               const GetDescType<ResourceT> &desc,
+                                               GetInitDataType<ResourceT> *initData,
+                                               const char *name)
+{
+    if (!mResource.valid())
+    {
+        ANGLE_TRY(renderer->allocateResource(desc, initData, &mResource));
+        mResource.setDebugName(name);
+    }
+    return gl::NoError();
+}
+
+template gl::Error LazyResource<ResourceType::BlendState>::resolveImpl(Renderer11 *renderer,
+                                                                       const D3D11_BLEND_DESC &desc,
+                                                                       void *initData,
+                                                                       const char *name);
+template gl::Error LazyResource<ResourceType::ComputeShader>::resolveImpl(Renderer11 *renderer,
+                                                                          const ShaderData &desc,
+                                                                          void *initData,
+                                                                          const char *name);
+template gl::Error LazyResource<ResourceType::GeometryShader>::resolveImpl(
+    Renderer11 *renderer,
+    const ShaderData &desc,
+    const std::vector<D3D11_SO_DECLARATION_ENTRY> *initData,
+    const char *name);
+template gl::Error LazyResource<ResourceType::InputLayout>::resolveImpl(
+    Renderer11 *renderer,
+    const InputElementArray &desc,
+    const ShaderData *initData,
+    const char *name);
+template gl::Error LazyResource<ResourceType::PixelShader>::resolveImpl(Renderer11 *renderer,
+                                                                        const ShaderData &desc,
+                                                                        void *initData,
+                                                                        const char *name);
+template gl::Error LazyResource<ResourceType::VertexShader>::resolveImpl(Renderer11 *renderer,
+                                                                         const ShaderData &desc,
+                                                                         void *initData,
+                                                                         const char *name);
+
+LazyInputLayout::LazyInputLayout(const D3D11_INPUT_ELEMENT_DESC *inputDesc,
+                                 size_t inputDescLen,
+                                 const BYTE *byteCode,
+                                 size_t byteCodeLen,
+                                 const char *debugName)
+    : mInputDesc(inputDesc, inputDescLen), mByteCode(byteCode, byteCodeLen), mDebugName(debugName)
+{
+}
+
+LazyInputLayout::~LazyInputLayout()
+{
+}
+
+gl::Error LazyInputLayout::resolve(Renderer11 *renderer)
+{
+    return resolveImpl(renderer, mInputDesc, &mByteCode, mDebugName);
+}
+
+LazyBlendState::LazyBlendState(const D3D11_BLEND_DESC &desc, const char *debugName)
+    : mDesc(desc), mDebugName(debugName)
+{
+}
+
+gl::Error LazyBlendState::resolve(Renderer11 *renderer)
+{
+    return resolveImpl(renderer, mDesc, nullptr, mDebugName);
+}
+
 angle::WorkaroundsD3D GenerateWorkarounds(const Renderer11DeviceCaps &deviceCaps,
                                           const DXGI_ADAPTER_DESC &adapterDesc)
 {
     bool is9_3 = (deviceCaps.featureLevel <= D3D_FEATURE_LEVEL_9_3);
 
     angle::WorkaroundsD3D workarounds;
     workarounds.mrtPerfWorkaround = true;
     workarounds.setDataFasterThanImageUpload = true;
@@ -2054,37 +2209,34 @@ angle::WorkaroundsD3D GenerateWorkaround
         }
     }
 
     // TODO(jmadill): Disable workaround when we have a fixed compiler DLL.
     workarounds.expandIntegerPowExpressions = true;
 
     workarounds.flushAfterEndingTransformFeedback = IsNvidia(adapterDesc.VendorId);
     workarounds.getDimensionsIgnoresBaseLevel     = IsNvidia(adapterDesc.VendorId);
+    workarounds.skipConstantRegisterZero          = IsNvidia(adapterDesc.VendorId);
 
     if (IsIntel(adapterDesc.VendorId))
     {
+        IntelDriverVersion capsVersion = d3d11_gl::GetIntelDriverVersion(deviceCaps.driverVersion);
+
         workarounds.preAddTexelFetchOffsets           = true;
         workarounds.useSystemMemoryForConstantBuffers = true;
-        workarounds.disableB5G6R5Support =
-            d3d11_gl::GetIntelDriverVersion(deviceCaps.driverVersion) < IntelDriverVersion(4539);
+        workarounds.disableB5G6R5Support              = capsVersion < IntelDriverVersion(4539);
+        workarounds.addDummyTextureNoRenderTarget     = capsVersion < IntelDriverVersion(4815);
         if (IsSkylake(adapterDesc.DeviceId))
         {
-            workarounds.callClearTwice =
-                d3d11_gl::GetIntelDriverVersion(deviceCaps.driverVersion) <
-                IntelDriverVersion(4771);
-            workarounds.emulateIsnanFloat =
-                d3d11_gl::GetIntelDriverVersion(deviceCaps.driverVersion) <
-                IntelDriverVersion(4542);
+            workarounds.callClearTwice    = capsVersion < IntelDriverVersion(4771);
+            workarounds.emulateIsnanFloat = capsVersion < IntelDriverVersion(4542);
         }
         else if (IsBroadwell(adapterDesc.DeviceId) || IsHaswell(adapterDesc.DeviceId))
         {
-            workarounds.rewriteUnaryMinusOperator =
-                d3d11_gl::GetIntelDriverVersion(deviceCaps.driverVersion) <
-                IntelDriverVersion(4624);
+            workarounds.rewriteUnaryMinusOperator = capsVersion < IntelDriverVersion(4624);
         }
     }
 
     // TODO(jmadill): Disable when we have a fixed driver version.
     workarounds.emulateTinyStencilTextures = IsAMD(adapterDesc.VendorId);
 
     // The tiny stencil texture workaround involves using CopySubresource or UpdateSubresource on a
     // depth stencil texture.  This is not allowed until feature level 10.1 but since it is not
@@ -2202,9 +2354,93 @@ bool UsePresentPathFast(const Renderer11
     {
         return false;
     }
 
     return (framebufferAttachment->type() == GL_FRAMEBUFFER_DEFAULT &&
             renderer->presentPathFastEnabled());
 }
 
+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)
+{
+    // 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/src/libANGLE/renderer/d3d/d3d11/renderer11_utils.h
+++ b/gfx/angle/src/libANGLE/renderer/d3d/d3d11/renderer11_utils.h
@@ -38,17 +38,17 @@ using RTVArray          = std::array<ID3
 
 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);
 
-D3D11_CULL_MODE ConvertCullMode(bool cullEnabled, GLenum cullMode);
+D3D11_CULL_MODE ConvertCullMode(bool cullEnabled, gl::CullFaceMode cullMode);
 
 D3D11_COMPARISON_FUNC ConvertComparison(GLenum comparison);
 D3D11_DEPTH_WRITE_MASK ConvertDepthMask(bool depthWriteEnabled);
 UINT8 ConvertStencilMask(GLuint stencilmask);
 D3D11_STENCIL_OP ConvertStencilOp(GLenum stencilOp);
 
 D3D11_FILTER ConvertFilter(GLenum minFilter, GLenum magFilter, float maxAnisotropy, GLenum comparisonMode);
 D3D11_TEXTURE_ADDRESS_MODE ConvertTextureWrap(GLenum wrap);
@@ -63,21 +63,29 @@ UINT8 GetColorMask(const gl::InternalFor
 namespace d3d11_gl
 {
 
 unsigned int GetReservedVertexUniformVectors(D3D_FEATURE_LEVEL featureLevel);
 
 unsigned int GetReservedFragmentUniformVectors(D3D_FEATURE_LEVEL featureLevel);
 
 gl::Version GetMaximumClientVersion(D3D_FEATURE_LEVEL featureLevel);
-void GenerateCaps(ID3D11Device *device, ID3D11DeviceContext *deviceContext, const Renderer11DeviceCaps &renderer11DeviceCaps, gl::Caps *caps,
-                  gl::TextureCapsMap *textureCapsMap, gl::Extensions *extensions, gl::Limitations *limitations);
+void GenerateCaps(ID3D11Device *device,
+                  ID3D11DeviceContext *deviceContext,
+                  const Renderer11DeviceCaps &renderer11DeviceCaps,
+                  const angle::WorkaroundsD3D &workarounds,
+                  gl::Caps *caps,
+                  gl::TextureCapsMap *textureCapsMap,
+                  gl::Extensions *extensions,
+                  gl::Limitations *limitations);
 
 void GetSamplePosition(GLsizei sampleCount, size_t index, GLfloat *xy);
 
+D3D_FEATURE_LEVEL GetMinimumFeatureLevelForES31();
+
 }  // namespace d3d11_gl
 
 namespace d3d11
 {
 
 enum ANGLED3D11DeviceType
 {
     ANGLE_D3D11_DEVICE_TYPE_UNKNOWN,
@@ -123,30 +131,35 @@ struct PositionVertex
 };
 
 struct BlendStateKey final
 {
     // This will zero-initialize the struct, including padding.
     BlendStateKey();
 
     gl::BlendState blendState;
-    bool mrt;
+
+    // An int so struct size rounds nicely.
+    uint32_t rtvMax;
+
     uint8_t rtvMasks[D3D11_SIMULTANEOUS_RENDER_TARGET_COUNT];
 };
 
 bool operator==(const BlendStateKey &a, const BlendStateKey &b);
 bool operator!=(const BlendStateKey &a, const BlendStateKey &b);
 
 struct RasterizerStateKey final
 {
     // This will zero-initialize the struct, including padding.
     RasterizerStateKey();
 
     gl::RasterizerState rasterizerState;
-    bool scissorEnabled;
+
+    // Use a 32-bit int to round the struct nicely.
+    uint32_t scissorEnabled;
 };
 
 bool operator==(const RasterizerStateKey &a, const RasterizerStateKey &b);
 bool operator!=(const RasterizerStateKey &a, const RasterizerStateKey &b);
 
 template <typename outType>
 outType* DynamicCastComObject(IUnknown* object)
 {
@@ -173,16 +186,101 @@ inline bool isDeviceLostError(HRESULT er
       case DXGI_ERROR_DRIVER_INTERNAL_ERROR:
       case DXGI_ERROR_NOT_CURRENTLY_AVAILABLE:
         return true;
       default:
         return false;
     }
 }
 
+template <ResourceType ResourceT>
+class LazyResource : angle::NonCopyable
+{
+  public:
+    constexpr LazyResource() : mResource() {}
+    virtual ~LazyResource() {}
+
+    virtual gl::Error resolve(Renderer11 *renderer) = 0;
+    void reset() { mResource.reset(); }
+    GetD3D11Type<ResourceT> *get() const
+    {
+        ASSERT(mResource.valid());
+        return mResource.get();
+    }
+
+    const Resource11<GetD3D11Type<ResourceT>> &getObj() const { return mResource; }
+
+  protected:
+    LazyResource(LazyResource &&other) : mResource(std::move(other.mResource)) {}
+
+    // Specialized in the cpp file to avoid MSVS/Clang specific code.
+    gl::Error resolveImpl(Renderer11 *renderer,
+                          const GetDescType<ResourceT> &desc,
+                          GetInitDataType<ResourceT> *initData,
+                          const char *name);
+
+    Resource11<GetD3D11Type<ResourceT>> mResource;
+};
+
+template <typename D3D11ShaderType>
+class LazyShader final : public LazyResource<GetResourceTypeFromD3D11<D3D11ShaderType>()>
+{
+  public:
+    // All parameters must be constexpr. Not supported in VS2013.
+    constexpr LazyShader(const BYTE *byteCode, size_t byteCodeSize, const char *name)
+        : mByteCode(byteCode, byteCodeSize), mName(name)
+    {
+    }
+
+    constexpr LazyShader(LazyShader &&shader)
+        : LazyResource<GetResourceTypeFromD3D11<D3D11ShaderType>()>(std::move(shader)),
+          mByteCode(std::move(shader.mByteCode)),
+          mName(shader.mName)
+    {
+    }
+
+    gl::Error resolve(Renderer11 *renderer) override
+    {
+        return this->resolveImpl(renderer, mByteCode, nullptr, mName);
+    }
+
+  private:
+    ShaderData mByteCode;
+    const char *mName;
+};
+
+class LazyInputLayout final : public LazyResource<ResourceType::InputLayout>
+{
+  public:
+    LazyInputLayout(const D3D11_INPUT_ELEMENT_DESC *inputDesc,
+                    size_t inputDescLen,
+                    const BYTE *byteCode,
+                    size_t byteCodeLen,
+                    const char *debugName);
+    ~LazyInputLayout() override;
+
+    gl::Error resolve(Renderer11 *renderer) override;
+
+  private:
+    InputElementArray mInputDesc;
+    ShaderData mByteCode;
+    const char *mDebugName;
+};
+
+class LazyBlendState final : public LazyResource<ResourceType::BlendState>
+{
+  public:
+    LazyBlendState(const D3D11_BLEND_DESC &desc, const char *debugName);
+
+    gl::Error resolve(Renderer11 *renderer) override;
+
+  private:
+    D3D11_BLEND_DESC mDesc;
+    const char *mDebugName;
+};
 
 // Copy data to small D3D11 buffers, such as for small constant buffers, which use one struct to
 // represent an entire buffer.
 template <class T>
 void SetBufferData(ID3D11DeviceContext *context, ID3D11Buffer *constantBuffer, const T &value)
 {
     D3D11_MAPPED_SUBRESOURCE mappedResource = {};
     HRESULT result = context->Map(constantBuffer, 0, D3D11_MAP_WRITE_DISCARD, 0, &mappedResource);
@@ -233,17 +331,17 @@ struct GenericData
 
 // A helper class which wraps a 2D or 3D texture.
 class TextureHelper11 : public Resource11Base<ID3D11Resource, std::shared_ptr, GenericData>
 {
   public:
     TextureHelper11();
     TextureHelper11(TextureHelper11 &&other);
     TextureHelper11(const TextureHelper11 &other);
-    ~TextureHelper11();
+    ~TextureHelper11() override;
     TextureHelper11 &operator=(TextureHelper11 &&other);
     TextureHelper11 &operator=(const TextureHelper11 &other);
 
     bool is2D() const { return mData->resourceType == ResourceType::Texture2D; }
     bool is3D() const { return mData->resourceType == ResourceType::Texture3D; }
     ResourceType getTextureType() const { return mData->resourceType; }
     gl::Extents getExtents() const { return mExtents; }
     DXGI_FORMAT getFormat() const { return mFormatSet->texFormat; }
@@ -251,17 +349,17 @@ class TextureHelper11 : public Resource1
     int getSampleCount() const { return mSampleCount; }
 
     template <typename DescT, typename ResourceT>
     void init(Resource11<ResourceT> &&texture, const DescT &desc, const d3d11::Format &format)
     {
         std::swap(mData->manager, texture.mData->manager);
 
         // Can't use std::swap because texture is typed, and here we use ID3D11Resource.
-        auto temp             = mData->object;
+        ID3D11Resource *temp  = mData->object;
         mData->object         = texture.mData->object;
         texture.mData->object = static_cast<ResourceT *>(temp);
 
         mFormatSet = &format;
         initDesc(desc);
     }
 
     template <typename ResourceT>
@@ -294,16 +392,42 @@ 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.
+    Static,
+
+    // Direct indexes are never transated and are used directly from the source buffer. They are
+    // the fastest available path.
+    Direct,
+
+    // 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);
 
 // Used for state change notifications between buffers and vertex arrays.
 using OnBufferDataDirtyBinding  = angle::ChannelBinding<size_t, const gl::Context *>;
 using OnBufferDataDirtyChannel  = angle::BroadcastChannel<size_t, const gl::Context *>;
 using OnBufferDataDirtyReceiver = angle::SignalReceiver<size_t, const gl::Context *>;
 
 // Used for state change notifications between RenderTarget11 and Framebuffer11.
 using OnRenderTargetDirtyBinding  = angle::ChannelBinding<size_t, const gl::Context *>;
--- a/gfx/angle/src/libANGLE/renderer/d3d/d3d11/shaders/Passthrough2D11.hlsl
+++ b/gfx/angle/src/libANGLE/renderer/d3d/d3d11/shaders/Passthrough2D11.hlsl
@@ -17,16 +17,21 @@ float PS_PassthroughDepth2D(in float4 in
     return TextureF.Sample(Sampler, inTexCoord).r;
 }
 
 float4 PS_PassthroughRGBA2D(in float4 inPosition : SV_POSITION, in float2 inTexCoord : TEXCOORD0) : SV_TARGET0
 {
     return TextureF.Sample(Sampler, inTexCoord).rgba;
 }
 
+float4 PS_PassthroughA2D(in float4 inPosition : SV_POSITION, in float2 inTexCoord : TEXCOORD0) : SV_TARGET0
+{
+    return float4(0.0f, 0.0f, 0.0f, TextureF.Sample(Sampler, inTexCoord).a);
+}
+
 float4 PS_PassthroughRGBA2DMS(in float4 inPosition : SV_POSITION, in float2 inTexCoord : TEXCORD0, in uint inSampleIndex : SV_SAMPLEINDEX) : SV_TARGET0
 {
     return TextureF_MS.sample[inSampleIndex][inTexCoord].rgba;
 }
 
 uint4 PS_PassthroughRGBA2DUI(in float4 inPosition : SV_POSITION, in float2 inTexCoord : TEXCOORD0) : SV_TARGET0
 {
     uint2 size;
--- a/gfx/angle/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/buffertotexture11_gs.h
+++ b/gfx/angle/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/buffertotexture11_gs.h
@@ -1,165 +1,165 @@
-#if 0
-//
-// Generated by Microsoft (R) HLSL Shader Compiler 6.3.9600.16384
-//
-//
-//
-// Input signature:
-//
-// Name                 Index   Mask Register SysValue  Format   Used
-// -------------------- ----- ------ -------- -------- ------- ------
-// SV_Position              0   xyzw        0      POS   float   xyzw
-// TEXCOORD                 0   x           1     NONE    uint   x   
-// LAYER                    0    y          1     NONE    uint    y  
-//
-//
-// Output signature:
-//
-// Name                 Index   Mask Register SysValue  Format   Used
-// -------------------- ----- ------ -------- -------- ------- ------
-// SV_Position              0   xyzw        0      POS   float   xyzw
-// TEXCOORD                 0   x           1     NONE    uint   x   
-// SV_RenderTargetArrayIndex     0    y          1  RTINDEX    uint    y  
-//
-gs_4_0
-dcl_input_siv v[1][0].xyzw, position
-dcl_input v[1][1].x
-dcl_input v[1][1].y
-dcl_inputprimitive point 
-dcl_outputtopology pointlist 
-dcl_output_siv o0.xyzw, position
-dcl_output o1.x
-dcl_output_siv o1.y, rendertarget_array_index
-dcl_maxout 1
-mov o0.xyzw, v[0][0].xyzw
-mov o1.x, v[0][1].x
-mov o1.y, v[0][1].y
-emit 
-ret 
-// Approximately 5 instruction slots used
-#endif
-
-const BYTE g_GS_BufferToTexture[] =
-{
-     68,  88,  66,  67,  79, 166, 
-    191,  97,  16,  63, 142, 167, 
-    231,  92, 119,  74,  86,   7, 
-     58, 165,   1,   0,   0,   0, 
-    212,   2,   0,   0,   5,   0, 
-      0,   0,  52,   0,   0,   0, 
-    140,   0,   0,   0,   0,   1, 
-      0,   0, 136,   1,   0,   0, 
-     88,   2,   0,   0,  82,  68, 
-     69,  70,  80,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-     28,   0,   0,   0,   0,   4, 
-     83,  71,   0,   1,   0,   0, 
-     28,   0,   0,   0,  77, 105, 
-     99, 114, 111, 115, 111, 102, 
-    116,  32,  40,  82,  41,  32, 
-     72,  76,  83,  76,  32,  83, 
-    104,  97, 100, 101, 114,  32, 
-     67, 111, 109, 112, 105, 108, 
-    101, 114,  32,  54,  46,  51, 
-     46,  57,  54,  48,  48,  46, 
-     49,  54,  51,  56,  52,   0, 
-    171, 171,  73,  83,  71,  78, 
-    108,   0,   0,   0,   3,   0, 
-      0,   0,   8,   0,   0,   0, 
-     80,   0,   0,   0,   0,   0, 
-      0,   0,   1,   0,   0,   0, 
-      3,   0,   0,   0,   0,   0, 
-      0,   0,  15,  15,   0,   0, 
-     92,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      1,   0,   0,   0,   1,   0, 
-      0,   0,   1,   1,   0,   0, 
-    101,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      1,   0,   0,   0,   1,   0, 
-      0,   0,   2,   2,   0,   0, 
-     83,  86,  95,  80, 111, 115, 
-    105, 116, 105, 111, 110,   0, 
-     84,  69,  88,  67,  79,  79, 
-     82,  68,   0,  76,  65,  89, 
-     69,  82,   0, 171,  79,  83, 
-     71,  78, 128,   0,   0,   0, 
-      3,   0,   0,   0,   8,   0, 
-      0,   0,  80,   0,   0,   0, 
-      0,   0,   0,   0,   1,   0, 
-      0,   0,   3,   0,   0,   0, 
-      0,   0,   0,   0,  15,   0, 
-      0,   0,  92,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   1,   0,   0,   0, 
-      1,   0,   0,   0,   1,  14, 
-      0,   0, 101,   0,   0,   0, 
-      0,   0,   0,   0,   4,   0, 
-      0,   0,   1,   0,   0,   0, 
-      1,   0,   0,   0,   2,  13, 
-      0,   0,  83,  86,  95,  80, 
-    111, 115, 105, 116, 105, 111, 
-    110,   0,  84,  69,  88,  67, 
-     79,  79,  82,  68,   0,  83, 
-     86,  95,  82, 101, 110, 100, 
-    101, 114,  84,  97, 114, 103, 
-    101, 116,  65, 114, 114,  97, 
-    121,  73, 110, 100, 101, 120, 
-      0, 171,  83,  72,  68,  82, 
-    200,   0,   0,   0,  64,   0, 
-      2,   0,  50,   0,   0,   0, 
-     97,   0,   0,   5, 242,  16, 
-     32,   0,   1,   0,   0,   0, 
-      0,   0,   0,   0,   1,   0, 
-      0,   0,  95,   0,   0,   4, 
-     18,  16,  32,   0,   1,   0, 
-      0,   0,   1,   0,   0,   0, 
-     95,   0,   0,   4,  34,  16, 
-     32,   0,   1,   0,   0,   0, 
-      1,   0,   0,   0,  93,   8, 
-      0,   1,  92,   8,   0,   1, 
-    103,   0,   0,   4, 242,  32, 
-     16,   0,   0,   0,   0,   0, 
-      1,   0,   0,   0, 101,   0, 
-      0,   3,  18,  32,  16,   0, 
-      1,   0,   0,   0, 103,   0, 
-      0,   4,  34,  32,  16,   0, 
-      1,   0,   0,   0,   4,   0, 
-      0,   0,  94,   0,   0,   2, 
-      1,   0,   0,   0,  54,   0, 
-      0,   6, 242,  32,  16,   0, 
-      0,   0,   0,   0,  70,  30, 
-     32,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,  54,   0, 
-      0,   6,  18,  32,  16,   0, 
-      1,   0,   0,   0,  10,  16, 
-     32,   0,   0,   0,   0,   0, 
-      1,   0,   0,   0,  54,   0, 
-      0,   6,  34,  32,  16,   0, 
-      1,   0,   0,   0,  26,  16, 
-     32,   0,   0,   0,   0,   0, 
-      1,   0,   0,   0,  19,   0, 
-      0,   1,  62,   0,   0,   1, 
-     83,  84,  65,  84, 116,   0, 
-      0,   0,   5,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   6,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      1,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      1,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   1,   0, 
-      0,   0,   1,   0,   0,   0, 
-      1,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0
-};
+#if 0
+//
+// Generated by Microsoft (R) HLSL Shader Compiler 6.3.9600.16384
+//
+//
+//
+// Input signature:
+//
+// Name                 Index   Mask Register SysValue  Format   Used
+// -------------------- ----- ------ -------- -------- ------- ------
+// SV_Position              0   xyzw        0      POS   float   xyzw
+// TEXCOORD                 0   x           1     NONE    uint   x   
+// LAYER                    0    y          1     NONE    uint    y  
+//
+//
+// Output signature:
+//
+// Name                 Index   Mask Register SysValue  Format   Used
+// -------------------- ----- ------ -------- -------- ------- ------
+// SV_Position              0   xyzw        0      POS   float   xyzw
+// TEXCOORD                 0   x           1     NONE    uint   x   
+// SV_RenderTargetArrayIndex     0    y          1  RTINDEX    uint    y  
+//
+gs_4_0
+dcl_input_siv v[1][0].xyzw, position
+dcl_input v[1][1].x
+dcl_input v[1][1].y
+dcl_inputprimitive point 
+dcl_outputtopology pointlist 
+dcl_output_siv o0.xyzw, position
+dcl_output o1.x
+dcl_output_siv o1.y, rendertarget_array_index
+dcl_maxout 1
+mov o0.xyzw, v[0][0].xyzw
+mov o1.x, v[0][1].x
+mov o1.y, v[0][1].y
+emit 
+ret 
+// Approximately 5 instruction slots used
+#endif
+
+const BYTE g_GS_BufferToTexture[] =
+{
+     68,  88,  66,  67,  79, 166, 
+    191,  97,  16,  63, 142, 167, 
+    231,  92, 119,  74,  86,   7, 
+     58, 165,   1,   0,   0,   0, 
+    212,   2,   0,   0,   5,   0, 
+      0,   0,  52,   0,   0,   0, 
+    140,   0,   0,   0,   0,   1, 
+      0,   0, 136,   1,   0,   0, 
+     88,   2,   0,   0,  82,  68, 
+     69,  70,  80,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+     28,   0,   0,   0,   0,   4, 
+     83,  71,   0,   1,   0,   0, 
+     28,   0,   0,   0,  77, 105, 
+     99, 114, 111, 115, 111, 102, 
+    116,  32,  40,  82,  41,  32, 
+     72,  76,  83,  76,  32,  83, 
+    104,  97, 100, 101, 114,  32, 
+     67, 111, 109, 112, 105, 108, 
+    101, 114,  32,  54,  46,  51, 
+     46,  57,  54,  48,  48,  46, 
+     49,  54,  51,  56,  52,   0, 
+    171, 171,  73,  83,  71,  78, 
+    108,   0,   0,   0,   3,   0, 
+      0,   0,   8,   0,   0,   0, 
+     80,   0,   0,   0,   0,   0, 
+      0,   0,   1,   0,   0,   0, 
+      3,   0,   0,   0,   0,   0, 
+      0,   0,  15,  15,   0,   0, 
+     92,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      1,   0,   0,   0,   1,   0, 
+      0,   0,   1,   1,   0,   0, 
+    101,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      1,   0,   0,   0,   1,   0, 
+      0,   0,   2,   2,   0,   0, 
+     83,  86,  95,  80, 111, 115, 
+    105, 116, 105, 111, 110,   0, 
+     84,  69,  88,  67,  79,  79, 
+     82,  68,   0,  76,  65,  89, 
+     69,  82,   0, 171,  79,  83, 
+     71,  78, 128,   0,   0,   0, 
+      3,   0,   0,   0,   8,   0, 
+      0,   0,  80,   0,   0,   0, 
+      0,   0,   0,   0,   1,   0, 
+      0,   0,   3,   0,   0,   0, 
+      0,   0,   0,   0,  15,   0, 
+      0,   0,  92,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   1,   0,   0,   0, 
+      1,   0,   0,   0,   1,  14, 
+      0,   0, 101,   0,   0,   0, 
+      0,   0,   0,   0,   4,   0, 
+      0,   0,   1,   0,   0,   0, 
+      1,   0,   0,   0,   2,  13, 
+      0,   0,  83,  86,  95,  80, 
+    111, 115, 105, 116, 105, 111, 
+    110,   0,  84,  69,  88,  67, 
+     79,  79,  82,  68,   0,  83, 
+     86,  95,  82, 101, 110, 100, 
+    101, 114,  84,  97, 114, 103, 
+    101, 116,  65, 114, 114,  97, 
+    121,  73, 110, 100, 101, 120, 
+      0, 171,  83,  72,  68,  82, 
+    200,   0,   0,   0,  64,   0, 
+      2,   0,  50,   0,   0,   0, 
+     97,   0,   0,   5, 242,  16, 
+     32,   0,   1,   0,   0,   0, 
+      0,   0,   0,   0,   1,   0, 
+      0,   0,  95,   0,   0,   4, 
+     18,  16,  32,   0,   1,   0, 
+      0,   0,   1,   0,   0,   0, 
+     95,   0,   0,   4,  34,  16, 
+     32,   0,   1,   0,   0,   0, 
+      1,   0,   0,   0,  93,   8, 
+      0,   1,  92,   8,   0,   1, 
+    103,   0,   0,   4, 242,  32, 
+     16,   0,   0,   0,   0,   0, 
+      1,   0,   0,   0, 101,   0, 
+      0,   3,  18,  32,  16,   0, 
+      1,   0,   0,   0, 103,   0, 
+      0,   4,  34,  32,  16,   0, 
+      1,   0,   0,   0,   4,   0, 
+      0,   0,  94,   0,   0,   2, 
+      1,   0,   0,   0,  54,   0, 
+      0,   6, 242,  32,  16,   0, 
+      0,   0,   0,   0,  70,  30, 
+     32,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,  54,   0, 
+      0,   6,  18,  32,  16,   0, 
+      1,   0,   0,   0,  10,  16, 
+     32,   0,   0,   0,   0,   0, 
+      1,   0,   0,   0,  54,   0, 
+      0,   6,  34,  32,  16,   0, 
+      1,   0,   0,   0,  26,  16, 
+     32,   0,   0,   0,   0,   0, 
+      1,   0,   0,   0,  19,   0, 
+      0,   1,  62,   0,   0,   1, 
+     83,  84,  65,  84, 116,   0, 
+      0,   0,   5,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   6,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      1,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      1,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   1,   0, 
+      0,   0,   1,   0,   0,   0, 
+      1,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0
+};
--- a/gfx/angle/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/buffertotexture11_ps_4f.h
+++ b/gfx/angle/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/buffertotexture11_ps_4f.h
@@ -1,229 +1,229 @@
-#if 0
-//
-// Generated by Microsoft (R) HLSL Shader Compiler 6.3.9600.16384
-//
-//
-// Buffer Definitions: 
-//
-// cbuffer BufferCopyParams
-// {
-//
-//   uint FirstPixelOffset;             // Offset:    0 Size:     4 [unused]
-//   uint PixelsPerRow;                 // Offset:    4 Size:     4 [unused]
-//   uint RowStride;                    // Offset:    8 Size:     4 [unused]
-//   uint RowsPerSlice;                 // Offset:   12 Size:     4 [unused]
-//   float2 PositionOffset;             // Offset:   16 Size:     8 [unused]
-//   float2 PositionScale;              // Offset:   24 Size:     8 [unused]
-//   int2 TexLocationOffset;            // Offset:   32 Size:     8 [unused]
-//   int2 TexLocationScale;             // Offset:   40 Size:     8 [unused]
-//   uint FirstSlice;                   // Offset:   48 Size:     4 [unused]
-//
-// }
-//
-//
-// Resource Bindings:
-//
-// Name                                 Type  Format         Dim Slot Elements
-// ------------------------------ ---------- ------- ----------- ---- --------
-// Buffer4F                          texture  float4         buf    0        1
-// BufferCopyParams                  cbuffer      NA          NA    0        1
-//
-//
-//
-// Input signature:
-//
-// Name                 Index   Mask Register SysValue  Format   Used
-// -------------------- ----- ------ -------- -------- ------- ------
-// SV_Position              0   xyzw        0      POS   float       
-// TEXCOORD                 0   x           1     NONE    uint   x   
-//
-//
-// Output signature:
-//
-// Name                 Index   Mask Register SysValue  Format   Used
-// -------------------- ----- ------ -------- -------- ------- ------
-// SV_Target                0   xyzw        0   TARGET   float   xyzw
-//
-ps_4_0
-dcl_constantbuffer cb0[1], immediateIndexed
-dcl_resource_buffer (float,float,float,float) t0
-dcl_input_ps constant v1.x
-dcl_output o0.xyzw
-ld o0.xyzw, v1.xxxx, t0.xyzw
-ret 
-// Approximately 2 instruction slots used
-#endif
-
-const BYTE g_PS_BufferToTexture_4F[] =
-{
-     68,  88,  66,  67, 176,  15, 
-     76, 123, 100,  38, 152,  23, 
-    150,  99, 165, 184, 222, 157, 
-    235,  80,   1,   0,   0,   0, 
-    252,   3,   0,   0,   5,   0, 
-      0,   0,  52,   0,   0,   0, 
-    140,   2,   0,   0, 228,   2, 
-      0,   0,  24,   3,   0,   0, 
-    128,   3,   0,   0,  82,  68, 
-     69,  70,  80,   2,   0,   0, 
-      1,   0,   0,   0, 120,   0, 
-      0,   0,   2,   0,   0,   0, 
-     28,   0,   0,   0,   0,   4, 
-    255, 255,   0,   1,   0,   0, 
-     28,   2,   0,   0,  92,   0, 
-      0,   0,   2,   0,   0,   0, 
-      5,   0,   0,   0,   1,   0, 
-      0,   0, 255, 255, 255, 255, 
-      0,   0,   0,   0,   1,   0, 
-      0,   0,  13,   0,   0,   0, 
-    101,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      1,   0,   0,   0,   1,   0, 
-      0,   0,  66, 117, 102, 102, 
-    101, 114,  52,  70,   0,  66, 
-    117, 102, 102, 101, 114,  67, 
-    111, 112, 121,  80,  97, 114, 
-     97, 109, 115,   0, 171, 171, 
-    101,   0,   0,   0,   9,   0, 
-      0,   0, 144,   0,   0,   0, 
-     64,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-    104,   1,   0,   0,   0,   0, 
-      0,   0,   4,   0,   0,   0, 
-      0,   0,   0,   0, 124,   1, 
-      0,   0,   0,   0,   0,   0, 
-    140,   1,   0,   0,   4,   0, 
-      0,   0,   4,   0,   0,   0, 
-      0,   0,   0,   0, 124,   1, 
-      0,   0,   0,   0,   0,   0, 
-    153,   1,   0,   0,   8,   0, 
-      0,   0,   4,   0,   0,   0, 
-      0,   0,   0,   0, 124,   1, 
-      0,   0,   0,   0,   0,   0, 
-    163,   1,   0,   0,  12,   0, 
-      0,   0,   4,   0,   0,   0, 
-      0,   0,   0,   0, 124,   1, 
-      0,   0,   0,   0,   0,   0, 
-    176,   1,   0,   0,  16,   0, 
-      0,   0,   8,   0,   0,   0, 
-      0,   0,   0,   0, 192,   1, 
-      0,   0,   0,   0,   0,   0, 
-    208,   1,   0,   0,  24,   0, 
-      0,   0,   8,   0,   0,   0, 
-      0,   0,   0,   0, 192,   1, 
-      0,   0,   0,   0,   0,   0, 
-    222,   1,   0,   0,  32,   0, 
-      0,   0,   8,   0,   0,   0, 
-      0,   0,   0,   0, 240,   1, 
-      0,   0,   0,   0,   0,   0, 
-      0,   2,   0,   0,  40,   0, 
-      0,   0,   8,   0,   0,   0, 
-      0,   0,   0,   0, 240,   1, 
-      0,   0,   0,   0,   0,   0, 
-     17,   2,   0,   0,  48,   0, 
-      0,   0,   4,   0,   0,   0, 
-      0,   0,   0,   0, 124,   1, 
-      0,   0,   0,   0,   0,   0, 
-     70, 105, 114, 115, 116,  80, 
-    105, 120, 101, 108,  79, 102, 
-    102, 115, 101, 116,   0, 171, 
-    171, 171,   0,   0,  19,   0, 
-      1,   0,   1,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-     80, 105, 120, 101, 108, 115, 
-     80, 101, 114,  82, 111, 119, 
-      0,  82, 111, 119,  83, 116, 
-    114, 105, 100, 101,   0,  82, 
-    111, 119, 115,  80, 101, 114, 
-     83, 108, 105,  99, 101,   0, 
-     80, 111, 115, 105, 116, 105, 
-    111, 110,  79, 102, 102, 115, 
-    101, 116,   0, 171,   1,   0, 
-      3,   0,   1,   0,   2,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,  80, 111, 115, 105, 
-    116, 105, 111, 110,  83,  99, 
-     97, 108, 101,   0,  84, 101, 
-    120,  76, 111,  99,  97, 116, 
-    105, 111, 110,  79, 102, 102, 
-    115, 101, 116,   0,   1,   0, 
-      2,   0,   1,   0,   2,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,  84, 101, 120,  76, 
-    111,  99,  97, 116, 105, 111, 
-    110,  83,  99,  97, 108, 101, 
-      0,  70, 105, 114, 115, 116, 
-     83, 108, 105,  99, 101,   0, 
-     77, 105,  99, 114, 111, 115, 
-    111, 102, 116,  32,  40,  82, 
-     41,  32,  72,  76,  83,  76, 
-     32,  83, 104,  97, 100, 101, 
-    114,  32,  67, 111, 109, 112, 
-    105, 108, 101, 114,  32,  54, 
-     46,  51,  46,  57,  54,  48, 
-     48,  46,  49,  54,  51,  56, 
-     52,   0, 171, 171,  73,  83, 
-     71,  78,  80,   0,   0,   0, 
-      2,   0,   0,   0,   8,   0, 
-      0,   0,  56,   0,   0,   0, 
-      0,   0,   0,   0,   1,   0, 
-      0,   0,   3,   0,   0,   0, 
-      0,   0,   0,   0,  15,   0, 
-      0,   0,  68,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   1,   0,   0,   0, 
-      1,   0,   0,   0,   1,   1, 
-      0,   0,  83,  86,  95,  80, 
-    111, 115, 105, 116, 105, 111, 
-    110,   0,  84,  69,  88,  67, 
-     79,  79,  82,  68,   0, 171, 
-    171, 171,  79,  83,  71,  78, 
-     44,   0,   0,   0,   1,   0, 
-      0,   0,   8,   0,   0,   0, 
-     32,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      3,   0,   0,   0,   0,   0, 
-      0,   0,  15,   0,   0,   0, 
-     83,  86,  95,  84,  97, 114, 
-    103, 101, 116,   0, 171, 171, 
-     83,  72,  68,  82,  96,   0, 
-      0,   0,  64,   0,   0,   0, 
-     24,   0,   0,   0,  89,   0, 
-      0,   4,  70, 142,  32,   0, 
-      0,   0,   0,   0,   1,   0, 
-      0,   0,  88,   8,   0,   4, 
-      0, 112,  16,   0,   0,   0, 
-      0,   0,  85,  85,   0,   0, 
-     98,   8,   0,   3,  18,  16, 
-     16,   0,   1,   0,   0,   0, 
-    101,   0,   0,   3, 242,  32, 
-     16,   0,   0,   0,   0,   0, 
-     45,   0,   0,   7, 242,  32, 
-     16,   0,   0,   0,   0,   0, 
-      6,  16,  16,   0,   1,   0, 
-      0,   0,  70, 126,  16,   0, 
-      0,   0,   0,   0,  62,   0, 
-      0,   1,  83,  84,  65,  84, 
-    116,   0,   0,   0,   2,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   2,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   1,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   1,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0
-};
+#if 0
+//
+// Generated by Microsoft (R) HLSL Shader Compiler 6.3.9600.16384
+//
+//
+// Buffer Definitions: 
+//
+// cbuffer BufferCopyParams
+// {
+//
+//   uint FirstPixelOffset;             // Offset:    0 Size:     4 [unused]
+//   uint PixelsPerRow;                 // Offset:    4 Size:     4 [unused]
+//   uint RowStride;                    // Offset:    8 Size:     4 [unused]
+//   uint RowsPerSlice;                 // Offset:   12 Size:     4 [unused]
+//   float2 PositionOffset;             // Offset:   16 Size:     8 [unused]
+//   float2 PositionScale;              // Offset:   24 Size:     8 [unused]
+//   int2 TexLocationOffset;            // Offset:   32 Size:     8 [unused]
+//   int2 TexLocationScale;             // Offset:   40 Size:     8 [unused]
+//   uint FirstSlice;                   // Offset:   48 Size:     4 [unused]
+//
+// }
+//
+//
+// Resource Bindings:
+//
+// Name                                 Type  Format         Dim Slot Elements
+// ------------------------------ ---------- ------- ----------- ---- --------
+// Buffer4F                          texture  float4         buf    0        1
+// BufferCopyParams                  cbuffer      NA          NA    0        1
+//
+//
+//
+// Input signature:
+//
+// Name                 Index   Mask Register SysValue  Format   Used
+// -------------------- ----- ------ -------- -------- ------- ------
+// SV_Position              0   xyzw        0      POS   float       
+// TEXCOORD                 0   x           1     NONE    uint   x   
+//
+//
+// Output signature:
+//
+// Name                 Index   Mask Register SysValue  Format   Used
+// -------------------- ----- ------ -------- -------- ------- ------
+// SV_Target                0   xyzw        0   TARGET   float   xyzw
+//
+ps_4_0
+dcl_constantbuffer cb0[1], immediateIndexed
+dcl_resource_buffer (float,float,float,float) t0
+dcl_input_ps constant v1.x
+dcl_output o0.xyzw
+ld o0.xyzw, v1.xxxx, t0.xyzw
+ret 
+// Approximately 2 instruction slots used
+#endif
+
+const BYTE g_PS_BufferToTexture_4F[] =
+{
+     68,  88,  66,  67, 176,  15, 
+     76, 123, 100,  38, 152,  23, 
+    150,  99, 165, 184, 222, 157, 
+    235,  80,   1,   0,   0,   0, 
+    252,   3,   0,   0,   5,   0, 
+      0,   0,  52,   0,   0,   0, 
+    140,   2,   0,   0, 228,   2, 
+      0,   0,  24,   3,   0,   0, 
+    128,   3,   0,   0,  82,  68, 
+     69,  70,  80,   2,   0,   0, 
+      1,   0,   0,   0, 120,   0, 
+      0,   0,   2,   0,   0,   0, 
+     28,   0,   0,   0,   0,   4, 
+    255, 255,   0,   1,   0,   0, 
+     28,   2,   0,   0,  92,   0, 
+      0,   0,   2,   0,   0,   0, 
+      5,   0,   0,   0,   1,   0, 
+      0,   0, 255, 255, 255, 255, 
+      0,   0,   0,   0,   1,   0, 
+      0,   0,  13,   0,   0,   0, 
+    101,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      1,   0,   0,   0,   1,   0, 
+      0,   0,  66, 117, 102, 102, 
+    101, 114,  52,  70,   0,  66, 
+    117, 102, 102, 101, 114,  67, 
+    111, 112, 121,  80,  97, 114, 
+     97, 109, 115,   0, 171, 171, 
+    101,   0,   0,   0,   9,   0, 
+      0,   0, 144,   0,   0,   0, 
+     64,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+    104,   1,   0,   0,   0,   0, 
+      0,   0,   4,   0,   0,   0, 
+      0,   0,   0,   0, 124,   1, 
+      0,   0,   0,   0,   0,   0, 
+    140,   1,   0,   0,   4,   0, 
+      0,   0,   4,   0,   0,   0, 
+      0,   0,   0,   0, 124,   1, 
+      0,   0,   0,   0,   0,   0, 
+    153,   1,   0,   0,   8,   0, 
+      0,   0,   4,   0,   0,   0, 
+      0,   0,   0,   0, 124,   1, 
+      0,   0,   0,   0,   0,   0, 
+    163,   1,   0,   0,  12,   0, 
+      0,   0,   4,   0,   0,   0, 
+      0,   0,   0,   0, 124,   1, 
+      0,   0,   0,   0,   0,   0, 
+    176,   1,   0,   0,  16,   0, 
+      0,   0,   8,   0,   0,   0, 
+      0,   0,   0,   0, 192,   1, 
+      0,   0,   0,   0,   0,   0, 
+    208,   1,   0,   0,  24,   0, 
+      0,   0,   8,   0,   0,   0, 
+      0,   0,   0,   0, 192,   1, 
+      0,   0,   0,   0,   0,   0, 
+    222,   1,   0,   0,  32,   0, 
+      0,   0,   8,   0,   0,   0, 
+      0,   0,   0,   0, 240,   1, 
+      0,   0,   0,   0,   0,   0, 
+      0,   2,   0,   0,  40,   0, 
+      0,   0,   8,   0,   0,   0, 
+      0,   0,   0,   0, 240,   1, 
+      0,   0,   0,   0,   0,   0, 
+     17,   2,   0,   0,  48,   0, 
+      0,   0,   4,   0,   0,   0, 
+      0,   0,   0,   0, 124,   1, 
+      0,   0,   0,   0,   0,   0, 
+     70, 105, 114, 115, 116,  80, 
+    105, 120, 101, 108,  79, 102, 
+    102, 115, 101, 116,   0, 171, 
+    171, 171,   0,   0,  19,   0, 
+      1,   0,   1,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+     80, 105, 120, 101, 108, 115, 
+     80, 101, 114,  82, 111, 119, 
+      0,  82, 111, 119,  83, 116, 
+    114, 105, 100, 101,   0,  82, 
+    111, 119, 115,  80, 101, 114, 
+     83, 108, 105,  99, 101,   0, 
+     80, 111, 115, 105, 116, 105, 
+    111, 110,  79, 102, 102, 115, 
+    101, 116,   0, 171,   1,   0, 
+      3,   0,   1,   0,   2,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,  80, 111, 115, 105, 
+    116, 105, 111, 110,  83,  99, 
+     97, 108, 101,   0,  84, 101, 
+    120,  76, 111,  99,  97, 116, 
+    105, 111, 110,  79, 102, 102, 
+    115, 101, 116,   0,   1,   0, 
+      2,   0,   1,   0,   2,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,  84, 101, 120,  76, 
+    111,  99,  97, 116, 105, 111, 
+    110,  83,  99,  97, 108, 101, 
+      0,  70, 105, 114, 115, 116, 
+     83, 108, 105,  99, 101,   0, 
+     77, 105,  99, 114, 111, 115, 
+    111, 102, 116,  32,  40,  82, 
+     41,  32,  72,  76,  83,  76, 
+     32,  83, 104,  97, 100, 101, 
+    114,  32,  67, 111, 109, 112, 
+    105, 108, 101, 114,  32,  54, 
+     46,  51,  46,  57,  54,  48, 
+     48,  46,  49,  54,  51,  56, 
+     52,   0, 171, 171,  73,  83, 
+     71,  78,  80,   0,   0,   0, 
+      2,   0,   0,   0,   8,   0, 
+      0,   0,  56,   0,   0,   0, 
+      0,   0,   0,   0,   1,   0, 
+      0,   0,   3,   0,   0,   0, 
+      0,   0,   0,   0,  15,   0, 
+      0,   0,  68,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   1,   0,   0,   0, 
+      1,   0,   0,   0,   1,   1, 
+      0,   0,  83,  86,  95,  80, 
+    111, 115, 105, 116, 105, 111, 
+    110,   0,  84,  69,  88,  67, 
+     79,  79,  82,  68,   0, 171, 
+    171, 171,  79,  83,  71,  78, 
+     44,   0,   0,   0,   1,   0, 
+      0,   0,   8,   0,   0,   0, 
+     32,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      3,   0,   0,   0,   0,   0, 
+      0,   0,  15,   0,   0,   0, 
+     83,  86,  95,  84,  97, 114, 
+    103, 101, 116,   0, 171, 171, 
+     83,  72,  68,  82,  96,   0, 
+      0,   0,  64,   0,   0,   0, 
+     24,   0,   0,   0,  89,   0, 
+      0,   4,  70, 142,  32,   0, 
+      0,   0,   0,   0,   1,   0, 
+      0,   0,  88,   8,   0,   4, 
+      0, 112,  16,   0,   0,   0, 
+      0,   0,  85,  85,   0,   0, 
+     98,   8,   0,   3,  18,  16, 
+     16,   0,   1,   0,   0,   0, 
+    101,   0,   0,   3, 242,  32, 
+     16,   0,   0,   0,   0,   0, 
+     45,   0,   0,   7, 242,  32, 
+     16,   0,   0,   0,   0,   0, 
+      6,  16,  16,   0,   1,   0, 
+      0,   0,  70, 126,  16,   0, 
+      0,   0,   0,   0,  62,   0, 
+      0,   1,  83,  84,  65,  84, 
+    116,   0,   0,   0,   2,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   2,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   1,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   1,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0
+};
--- a/gfx/angle/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/buffertotexture11_ps_4i.h
+++ b/gfx/angle/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/buffertotexture11_ps_4i.h
@@ -1,128 +1,128 @@
-#if 0
-//
-// Generated by Microsoft (R) HLSL Shader Compiler 6.3.9600.16384
-//
-//
-// Resource Bindings:
-//
-// Name                                 Type  Format         Dim Slot Elements
-// ------------------------------ ---------- ------- ----------- ---- --------
-// Buffer4I                          texture   sint4         buf    0        1
-//
-//
-//
-// Input signature:
-//
-// Name                 Index   Mask Register SysValue  Format   Used
-// -------------------- ----- ------ -------- -------- ------- ------
-// SV_Position              0   xyzw        0      POS   float       
-// TEXCOORD                 0   x           1     NONE    uint   x   
-//
-//
-// Output signature:
-//
-// Name                 Index   Mask Register SysValue  Format   Used
-// -------------------- ----- ------ -------- -------- ------- ------
-// SV_Target                0   xyzw        0   TARGET     int   xyzw
-//
-ps_4_0
-dcl_resource_buffer (sint,sint,sint,sint) t0
-dcl_input_ps constant v1.x
-dcl_output o0.xyzw
-ld o0.xyzw, v1.xxxx, t0.xyzw
-ret 
-// Approximately 2 instruction slots used
-#endif
-
-const BYTE g_PS_BufferToTexture_4I[] =
-{
-     68,  88,  66,  67, 154, 139, 
-     95, 210,  76,  52, 228,  55, 
-      1, 175,  60,  90,  13, 234, 
-    138,   3,   1,   0,   0,   0, 
-     20,   2,   0,   0,   5,   0, 
-      0,   0,  52,   0,   0,   0, 
-    180,   0,   0,   0,  12,   1, 
-      0,   0,  64,   1,   0,   0, 
-    152,   1,   0,   0,  82,  68, 
-     69,  70, 120,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   1,   0,   0,   0, 
-     28,   0,   0,   0,   0,   4, 
-    255, 255,   0,   1,   0,   0, 
-     69,   0,   0,   0,  60,   0, 
-      0,   0,   2,   0,   0,   0, 
-      3,   0,   0,   0,   1,   0, 
-      0,   0, 255, 255, 255, 255, 
-      0,   0,   0,   0,   1,   0, 
-      0,   0,  13,   0,   0,   0, 
-     66, 117, 102, 102, 101, 114, 
-     52,  73,   0,  77, 105,  99, 
-    114, 111, 115, 111, 102, 116, 
-     32,  40,  82,  41,  32,  72, 
-     76,  83,  76,  32,  83, 104, 
-     97, 100, 101, 114,  32,  67, 
-    111, 109, 112, 105, 108, 101, 
-    114,  32,  54,  46,  51,  46, 
-     57,  54,  48,  48,  46,  49, 
-     54,  51,  56,  52,   0, 171, 
-     73,  83,  71,  78,  80,   0, 
-      0,   0,   2,   0,   0,   0, 
-      8,   0,   0,   0,  56,   0, 
-      0,   0,   0,   0,   0,   0, 
-      1,   0,   0,   0,   3,   0, 
-      0,   0,   0,   0,   0,   0, 
-     15,   0,   0,   0,  68,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   1,   0, 
-      0,   0,   1,   0,   0,   0, 
-      1,   1,   0,   0,  83,  86, 
-     95,  80, 111, 115, 105, 116, 
-    105, 111, 110,   0,  84,  69, 
-     88,  67,  79,  79,  82,  68, 
-      0, 171, 171, 171,  79,  83, 
-     71,  78,  44,   0,   0,   0, 
-      1,   0,   0,   0,   8,   0, 
-      0,   0,  32,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   2,   0,   0,   0, 
-      0,   0,   0,   0,  15,   0, 
-      0,   0,  83,  86,  95,  84, 
-     97, 114, 103, 101, 116,   0, 
-    171, 171,  83,  72,  68,  82, 
-     80,   0,   0,   0,  64,   0, 
-      0,   0,  20,   0,   0,   0, 
-     88,   8,   0,   4,   0, 112, 
-     16,   0,   0,   0,   0,   0, 
-     51,  51,   0,   0,  98,   8, 
-      0,   3,  18,  16,  16,   0, 
-      1,   0,   0,   0, 101,   0, 
-      0,   3, 242,  32,  16,   0, 
-      0,   0,   0,   0,  45,   0, 
-      0,   7, 242,  32,  16,   0, 
-      0,   0,   0,   0,   6,  16, 
-     16,   0,   1,   0,   0,   0, 
-     70, 126,  16,   0,   0,   0, 
-      0,   0,  62,   0,   0,   1, 
-     83,  84,  65,  84, 116,   0, 
-      0,   0,   2,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   2,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      1,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   1,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0
-};
+#if 0
+//
+// Generated by Microsoft (R) HLSL Shader Compiler 6.3.9600.16384
+//
+//
+// Resource Bindings:
+//
+// Name                                 Type  Format         Dim Slot Elements
+// ------------------------------ ---------- ------- ----------- ---- --------
+// Buffer4I                          texture   sint4         buf    0        1
+//
+//
+//
+// Input signature:
+//
+// Name                 Index   Mask Register SysValue  Format   Used
+// -------------------- ----- ------ -------- -------- ------- ------
+// SV_Position              0   xyzw        0      POS   float       
+// TEXCOORD                 0   x           1     NONE    uint   x   
+//
+//
+// Output signature:
+//
+// Name                 Index   Mask Register SysValue  Format   Used
+// -------------------- ----- ------ -------- -------- ------- ------
+// SV_Target                0   xyzw        0   TARGET     int   xyzw
+//
+ps_4_0
+dcl_resource_buffer (sint,sint,sint,sint) t0
+dcl_input_ps constant v1.x
+dcl_output o0.xyzw
+ld o0.xyzw, v1.xxxx, t0.xyzw
+ret 
+// Approximately 2 instruction slots used
+#endif
+
+const BYTE g_PS_BufferToTexture_4I[] =
+{
+     68,  88,  66,  67, 154, 139, 
+     95, 210,  76,  52, 228,  55, 
+      1, 175,  60,  90,  13, 234, 
+    138,   3,   1,   0,   0,   0, 
+     20,   2,   0,   0,   5,   0, 
+      0,   0,  52,   0,   0,   0, 
+    180,   0,   0,   0,  12,   1, 
+      0,   0,  64,   1,   0,   0, 
+    152,   1,   0,   0,  82,  68, 
+     69,  70, 120,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   1,   0,   0,   0, 
+     28,   0,   0,   0,   0,   4, 
+    255, 255,   0,   1,   0,   0, 
+     69,   0,   0,   0,  60,   0, 
+      0,   0,   2,   0,   0,   0, 
+      3,   0,   0,   0,   1,   0, 
+      0,   0, 255, 255, 255, 255, 
+      0,   0,   0,   0,   1,   0, 
+      0,   0,  13,   0,   0,   0, 
+     66, 117, 102, 102, 101, 114, 
+     52,  73,   0,  77, 105,  99, 
+    114, 111, 115, 111, 102, 116, 
+     32,  40,  82,  41,  32,  72, 
+     76,  83,  76,  32,  83, 104, 
+     97, 100, 101, 114,  32,  67, 
+    111, 109, 112, 105, 108, 101, 
+    114,  32,  54,  46,  51,  46, 
+     57,  54,  48,  48,  46,  49, 
+     54,  51,  56,  52,   0, 171, 
+     73,  83,  71,  78,  80,   0, 
+      0,   0,   2,   0,   0,   0, 
+      8,   0,   0,   0,  56,   0, 
+      0,   0,   0,   0,   0,   0, 
+      1,   0,   0,   0,   3,   0, 
+      0,   0,   0,   0,   0,   0, 
+     15,   0,   0,   0,  68,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   1,   0, 
+      0,   0,   1,   0,   0,   0, 
+      1,   1,   0,   0,  83,  86, 
+     95,  80, 111, 115, 105, 116, 
+    105, 111, 110,   0,  84,  69, 
+     88,  67,  79,  79,  82,  68, 
+      0, 171, 171, 171,  79,  83, 
+     71,  78,  44,   0,   0,   0, 
+      1,   0,   0,   0,   8,   0, 
+      0,   0,  32,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   2,   0,   0,   0, 
+      0,   0,   0,   0,  15,   0, 
+      0,   0,  83,  86,  95,  84, 
+     97, 114, 103, 101, 116,   0, 
+    171, 171,  83,  72,  68,  82, 
+     80,   0,   0,   0,  64,   0, 
+      0,   0,  20,   0,   0,   0, 
+     88,   8,   0,   4,   0, 112, 
+     16,   0,   0,   0,   0,   0, 
+     51,  51,   0,   0,  98,   8, 
+      0,   3,  18,  16,  16,   0, 
+      1,   0,   0,   0, 101,   0, 
+      0,   3, 242,  32,  16,   0, 
+      0,   0,   0,   0,  45,   0, 
+      0,   7, 242,  32,  16,   0, 
+      0,   0,   0,   0,   6,  16, 
+     16,   0,   1,   0,   0,   0, 
+     70, 126,  16,   0,   0,   0, 
+      0,   0,  62,   0,   0,   1, 
+     83,  84,  65,  84, 116,   0, 
+      0,   0,   2,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   2,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      1,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   1,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0
+};
--- a/gfx/angle/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/buffertotexture11_ps_4ui.h
+++ b/gfx/angle/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/buffertotexture11_ps_4ui.h
@@ -1,128 +1,128 @@
-#if 0
-//
-// Generated by Microsoft (R) HLSL Shader Compiler 6.3.9600.16384
-//
-//
-// Resource Bindings:
-//
-// Name                                 Type  Format         Dim Slot Elements
-// ------------------------------ ---------- ------- ----------- ---- --------
-// Buffer4UI                         texture   uint4         buf    0        1
-//
-//
-//
-// Input signature:
-//
-// Name                 Index   Mask Register SysValue  Format   Used
-// -------------------- ----- ------ -------- -------- ------- ------
-// SV_Position              0   xyzw        0      POS   float       
-// TEXCOORD                 0   x           1     NONE    uint   x   
-//
-//
-// Output signature:
-//
-// Name                 Index   Mask Register SysValue  Format   Used
-// -------------------- ----- ------ -------- -------- ------- ------
-// SV_Target                0   xyzw        0   TARGET    uint   xyzw
-//
-ps_4_0
-dcl_resource_buffer (uint,uint,uint,uint) t0
-dcl_input_ps constant v1.x
-dcl_output o0.xyzw
-ld o0.xyzw, v1.xxxx, t0.xyzw
-ret 
-// Approximately 2 instruction slots used
-#endif
-
-const BYTE g_PS_BufferToTexture_4UI[] =
-{
-     68,  88,  66,  67,  25, 164, 
-      1, 224, 250, 219,  16, 200, 
-     83,  99,  38, 137, 116, 129, 
-    200,  39,   1,   0,   0,   0, 
-     20,   2,   0,   0,   5,   0, 
-      0,   0,  52,   0,   0,   0, 
-    180,   0,   0,   0,  12,   1, 
-      0,   0,  64,   1,   0,   0, 
-    152,   1,   0,   0,  82,  68, 
-     69,  70, 120,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   1,   0,   0,   0, 
-     28,   0,   0,   0,   0,   4, 
-    255, 255,   0,   1,   0,   0, 
-     70,   0,   0,   0,  60,   0, 
-      0,   0,   2,   0,   0,   0, 
-      4,   0,   0,   0,   1,   0, 
-      0,   0, 255, 255, 255, 255, 
-      0,   0,   0,   0,   1,   0, 
-      0,   0,  13,   0,   0,   0, 
-     66, 117, 102, 102, 101, 114, 
-     52,  85,  73,   0,  77, 105, 
-     99, 114, 111, 115, 111, 102, 
-    116,  32,  40,  82,  41,  32, 
-     72,  76,  83,  76,  32,  83, 
-    104,  97, 100, 101, 114,  32, 
-     67, 111, 109, 112, 105, 108, 
-    101, 114,  32,  54,  46,  51, 
-     46,  57,  54,  48,  48,  46, 
-     49,  54,  51,  56,  52,   0, 
-     73,  83,  71,  78,  80,   0, 
-      0,   0,   2,   0,   0,   0, 
-      8,   0,   0,   0,  56,   0, 
-      0,   0,   0,   0,   0,   0, 
-      1,   0,   0,   0,   3,   0, 
-      0,   0,   0,   0,   0,   0, 
-     15,   0,   0,   0,  68,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   1,   0, 
-      0,   0,   1,   0,   0,   0, 
-      1,   1,   0,   0,  83,  86, 
-     95,  80, 111, 115, 105, 116, 
-    105, 111, 110,   0,  84,  69, 
-     88,  67,  79,  79,  82,  68, 
-      0, 171, 171, 171,  79,  83, 
-     71,  78,  44,   0,   0,   0, 
-      1,   0,   0,   0,   8,   0, 
-      0,   0,  32,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   1,   0,   0,   0, 
-      0,   0,   0,   0,  15,   0, 
-      0,   0,  83,  86,  95,  84, 
-     97, 114, 103, 101, 116,   0, 
-    171, 171,  83,  72,  68,  82, 
-     80,   0,   0,   0,  64,   0, 
-      0,   0,  20,   0,   0,   0, 
-     88,   8,   0,   4,   0, 112, 
-     16,   0,   0,   0,   0,   0, 
-     68,  68,   0,   0,  98,   8, 
-      0,   3,  18,  16,  16,   0, 
-      1,   0,   0,   0, 101,   0, 
-      0,   3, 242,  32,  16,   0, 
-      0,   0,   0,   0,  45,   0, 
-      0,   7, 242,  32,  16,   0, 
-      0,   0,   0,   0,   6,  16, 
-     16,   0,   1,   0,   0,   0, 
-     70, 126,  16,   0,   0,   0, 
-      0,   0,  62,   0,   0,   1, 
-     83,  84,  65,  84, 116,   0, 
-      0,   0,   2,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   2,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      1,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   1,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0
-};
+#if 0
+//
+// Generated by Microsoft (R) HLSL Shader Compiler 6.3.9600.16384
+//
+//
+// Resource Bindings:
+//
+// Name                                 Type  Format         Dim Slot Elements
+// ------------------------------ ---------- ------- ----------- ---- --------
+// Buffer4UI                         texture   uint4         buf    0        1
+//
+//
+//
+// Input signature:
+//
+// Name                 Index   Mask Register SysValue  Format   Used
+// -------------------- ----- ------ -------- -------- ------- ------
+// SV_Position              0   xyzw        0      POS   float       
+// TEXCOORD                 0   x           1     NONE    uint   x   
+//
+//
+// Output signature:
+//
+// Name                 Index   Mask Register SysValue  Format   Used
+// -------------------- ----- ------ -------- -------- ------- ------
+// SV_Target                0   xyzw        0   TARGET    uint   xyzw
+//
+ps_4_0
+dcl_resource_buffer (uint,uint,uint,uint) t0
+dcl_input_ps constant v1.x
+dcl_output o0.xyzw
+ld o0.xyzw, v1.xxxx, t0.xyzw
+ret 
+// Approximately 2 instruction slots used
+#endif
+
+const BYTE g_PS_BufferToTexture_4UI[] =
+{
+     68,  88,  66,  67,  25, 164, 
+      1, 224, 250, 219,  16, 200, 
+     83,  99,  38, 137, 116, 129, 
+    200,  39,   1,   0,   0,   0, 
+     20,   2,   0,   0,   5,   0, 
+      0,   0,  52,   0,   0,   0, 
+    180,   0,   0,   0,  12,   1, 
+      0,   0,  64,   1,   0,   0, 
+    152,   1,   0,   0,  82,  68, 
+     69,  70, 120,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   1,   0,   0,   0, 
+     28,   0,   0,   0,   0,   4, 
+    255, 255,   0,   1,   0,   0, 
+     70,   0,   0,   0,  60,   0, 
+      0,   0,   2,   0,   0,   0, 
+      4,   0,   0,   0,   1,   0, 
+      0,   0, 255, 255, 255, 255, 
+      0,   0,   0,   0,   1,   0, 
+      0,   0,  13,   0,   0,   0, 
+     66, 117, 102, 102, 101, 114, 
+     52,  85,  73,   0,  77, 105, 
+     99, 114, 111, 115, 111, 102, 
+    116,  32,  40,  82,  41,  32, 
+     72,  76,  83,  76,  32,  83, 
+    104,  97, 100, 101, 114,  32, 
+     67, 111, 109, 112, 105, 108, 
+    101, 114,  32,  54,  46,  51, 
+     46,  57,  54,  48,  48,  46, 
+     49,  54,  51,  56,  52,   0, 
+     73,  83,  71,  78,  80,   0, 
+      0,   0,   2,   0,   0,   0, 
+      8,   0,   0,   0,  56,   0, 
+      0,   0,   0,   0,   0,   0, 
+      1,   0,   0,   0,   3,   0, 
+      0,   0,   0,   0,   0,   0, 
+     15,   0,   0,   0,  68,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   1,   0, 
+      0,   0,   1,   0,   0,   0, 
+      1,   1,   0,   0,  83,  86, 
+     95,  80, 111, 115, 105, 116, 
+    105, 111, 110,   0,  84,  69, 
+     88,  67,  79,  79,  82,  68, 
+      0, 171, 171, 171,  79,  83, 
+     71,  78,  44,   0,   0,   0, 
+      1,   0,   0,   0,   8,   0, 
+      0,   0,  32,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   1,   0,   0,   0, 
+      0,   0,   0,   0,  15,   0, 
+      0,   0,  83,  86,  95,  84, 
+     97, 114, 103, 101, 116,   0, 
+    171, 171,  83,  72,  68,  82, 
+     80,   0,   0,   0,  64,   0, 
+      0,   0,  20,   0,   0,   0, 
+     88,   8,   0,   4,   0, 112, 
+     16,   0,   0,   0,   0,   0, 
+     68,  68,   0,   0,  98,   8, 
+      0,   3,  18,  16,  16,   0, 
+      1,   0,   0,   0, 101,   0, 
+      0,   3, 242,  32,  16,   0, 
+      0,   0,   0,   0,  45,   0, 
+      0,   7, 242,  32,  16,   0, 
+      0,   0,   0,   0,   6,  16, 
+     16,   0,   1,   0,   0,   0, 
+     70, 126,  16,   0,   0,   0, 
+      0,   0,  62,   0,   0,   1, 
+     83,  84,  65,  84, 116,   0, 
+      0,   0,   2,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   2,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      1,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   1,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0
+};
--- a/gfx/angle/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/buffertotexture11_vs.h
+++ b/gfx/angle/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/buffertotexture11_vs.h
@@ -1,311 +1,311 @@
-#if 0
-//
-// Generated by Microsoft (R) HLSL Shader Compiler 6.3.9600.16384
-//
-//
-// Buffer Definitions: 
-//
-// cbuffer BufferCopyParams
-// {
-//
-//   uint FirstPixelOffset;             // Offset:    0 Size:     4
-//   uint PixelsPerRow;                 // Offset:    4 Size:     4
-//   uint RowStride;                    // Offset:    8 Size:     4
-//   uint RowsPerSlice;                 // Offset:   12 Size:     4
-//   float2 PositionOffset;             // Offset:   16 Size:     8
-//   float2 PositionScale;              // Offset:   24 Size:     8
-//   int2 TexLocationOffset;            // Offset:   32 Size:     8 [unused]
-//   int2 TexLocationScale;             // Offset:   40 Size:     8 [unused]
-//   uint FirstSlice;                   // Offset:   48 Size:     4
-//
-// }
-//
-//
-// Resource Bindings:
-//
-// Name                                 Type  Format         Dim Slot Elements
-// ------------------------------ ---------- ------- ----------- ---- --------
-// BufferCopyParams                  cbuffer      NA          NA    0        1
-//
-//
-//
-// Input signature:
-//
-// Name                 Index   Mask Register SysValue  Format   Used
-// -------------------- ----- ------ -------- -------- ------- ------
-// SV_VertexID              0   x           0   VERTID    uint   x   
-//
-//
-// Output signature:
-//
-// Name                 Index   Mask Register SysValue  Format   Used
-// -------------------- ----- ------ -------- -------- ------- ------
-// SV_Position              0   xyzw        0      POS   float   xyzw
-// TEXCOORD                 0   x           1     NONE    uint   x   
-// LAYER                    0    y          1     NONE    uint    y  
-//
-vs_4_0
-dcl_constantbuffer cb0[4], immediateIndexed
-dcl_input_sgv v0.x, vertex_id
-dcl_output_siv o0.xyzw, position
-dcl_output o1.x
-dcl_output o1.y
-dcl_temps 2
-mov o0.zw, l(0,0,0,1.000000)
-imul null, r0.xy, cb0[0].wwww, cb0[0].yzyy
-udiv r0.z, null, v0.x, r0.x
-imad r0.x, -r0.z, r0.x, v0.x
-imad r0.y, r0.z, r0.y, cb0[0].x
-iadd o1.y, r0.z, cb0[3].x
-udiv r0.z, null, r0.x, cb0[0].y
-imad r0.x, -r0.z, cb0[0].y, r0.x
-utof r1.xy, r0.xzxx
-imad r0.y, r0.z, cb0[0].z, r0.y
-iadd o1.x, r0.x, r0.y
-mad o0.xy, cb0[1].zwzz, r1.xyxx, cb0[1].xyxx
-ret 
-// Approximately 13 instruction slots used
-#endif
-
-const BYTE g_VS_BufferToTexture[] =
-{
-     68,  88,  66,  67,  39, 207, 
-    138,  15,  42, 195, 141, 208, 
-      2, 107, 135, 197, 122,  36, 
-    114, 227,   1,   0,   0,   0, 
-    152,   5,   0,   0,   5,   0, 
-      0,   0,  52,   0,   0,   0, 
-    100,   2,   0,   0, 152,   2, 
-      0,   0,  12,   3,   0,   0, 
-     28,   5,   0,   0,  82,  68, 
-     69,  70,  40,   2,   0,   0, 
-      1,   0,   0,   0,  80,   0, 
-      0,   0,   1,   0,   0,   0, 
-     28,   0,   0,   0,   0,   4, 
-    254, 255,   0,   1,   0,   0, 
-    244,   1,   0,   0,  60,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   1,   0, 
-      0,   0,   1,   0,   0,   0, 
-     66, 117, 102, 102, 101, 114, 
-     67, 111, 112, 121,  80,  97, 
-    114,  97, 109, 115,   0, 171, 
-    171, 171,  60,   0,   0,   0, 
-      9,   0,   0,   0, 104,   0, 
-      0,   0,  64,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,  64,   1,   0,   0, 
-      0,   0,   0,   0,   4,   0, 
-      0,   0,   2,   0,   0,   0, 
-     84,   1,   0,   0,   0,   0, 
-      0,   0, 100,   1,   0,   0, 
-      4,   0,   0,   0,   4,   0, 
-      0,   0,   2,   0,   0,   0, 
-     84,   1,   0,   0,   0,   0, 
-      0,   0, 113,   1,   0,   0, 
-      8,   0,   0,   0,   4,   0, 
-      0,   0,   2,   0,   0,   0, 
-     84,   1,   0,   0,   0,   0, 
-      0,   0, 123,   1,   0,   0, 
-     12,   0,   0,   0,   4,   0, 
-      0,   0,   2,   0,   0,   0, 
-     84,   1,   0,   0,   0,   0, 
-      0,   0, 136,   1,   0,   0, 
-     16,   0,   0,   0,   8,   0, 
-      0,   0,   2,   0,   0,   0, 
-    152,   1,   0,   0,   0,   0, 
-      0,   0, 168,   1,   0,   0, 
-     24,   0,   0,   0,   8,   0, 
-      0,   0,   2,   0,   0,   0, 
-    152,   1,   0,   0,   0,   0, 
-      0,   0, 182,   1,   0,   0, 
-     32,   0,   0,   0,   8,   0, 
-      0,   0,   0,   0,   0,   0, 
-    200,   1,   0,   0,   0,   0, 
-      0,   0, 216,   1,   0,   0, 
-     40,   0,   0,   0,   8,   0, 
-      0,   0,   0,   0,   0,   0, 
-    200,   1,   0,   0,   0,   0, 
-      0,   0, 233,   1,   0,   0, 
-     48,   0,   0,   0,   4,   0, 
-      0,   0,   2,   0,   0,   0, 
-     84,   1,   0,   0,   0,   0, 
-      0,   0,  70, 105, 114, 115, 
-    116,  80, 105, 120, 101, 108, 
-     79, 102, 102, 115, 101, 116, 
-      0, 171, 171, 171,   0,   0, 
-     19,   0,   1,   0,   1,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,  80, 105, 120, 101, 
-    108, 115,  80, 101, 114,  82, 
-    111, 119,   0,  82, 111, 119, 
-     83, 116, 114, 105, 100, 101, 
-      0,  82, 111, 119, 115,  80, 
-    101, 114,  83, 108, 105,  99, 
-    101,   0,  80, 111, 115, 105, 
-    116, 105, 111, 110,  79, 102, 
-    102, 115, 101, 116,   0, 171, 
-      1,   0,   3,   0,   1,   0, 
-      2,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,  80, 111, 
-    115, 105, 116, 105, 111, 110, 
-     83,  99,  97, 108, 101,   0, 
-     84, 101, 120,  76, 111,  99, 
-     97, 116, 105, 111, 110,  79, 
-    102, 102, 115, 101, 116,   0, 
-      1,   0,   2,   0,   1,   0, 
-      2,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,  84, 101, 
-    120,  76, 111,  99,  97, 116, 
-    105, 111, 110,  83,  99,  97, 
-    108, 101,   0,  70, 105, 114, 
-    115, 116,  83, 108, 105,  99, 
-    101,   0,  77, 105,  99, 114, 
-    111, 115, 111, 102, 116,  32, 
-     40,  82,  41,  32,  72,  76, 
-     83,  76,  32,  83, 104,  97, 
-    100, 101, 114,  32,  67, 111, 
-    109, 112, 105, 108, 101, 114, 
-     32,  54,  46,  51,  46,  57, 
-     54,  48,  48,  46,  49,  54, 
-     51,  56,  52,   0, 171, 171, 
-     73,  83,  71,  78,  44,   0, 
-      0,   0,   1,   0,   0,   0, 
-      8,   0,   0,   0,  32,   0, 
-      0,   0,   0,   0,   0,   0, 
-      6,   0,   0,   0,   1,   0, 
-      0,   0,   0,   0,   0,   0, 
-      1,   1,   0,   0,  83,  86, 
-     95,  86, 101, 114, 116, 101, 
-    120,  73,  68,   0,  79,  83, 
-     71,  78, 108,   0,   0,   0, 
-      3,   0,   0,   0,   8,   0, 
-      0,   0,  80,   0,   0,   0, 
-      0,   0,   0,   0,   1,   0, 
-      0,   0,   3,   0,   0,   0, 
-      0,   0,   0,   0,  15,   0, 
-      0,   0,  92,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   1,   0,   0,   0, 
-      1,   0,   0,   0,   1,  14, 
-      0,   0, 101,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   1,   0,   0,   0, 
-      1,   0,   0,   0,   2,  13, 
-      0,   0,  83,  86,  95,  80, 
-    111, 115, 105, 116, 105, 111, 
-    110,   0,  84,  69,  88,  67, 
-     79,  79,  82,  68,   0,  76, 
-     65,  89,  69,  82,   0, 171, 
-     83,  72,  68,  82,   8,   2, 
-      0,   0,  64,   0,   1,   0, 
-    130,   0,   0,   0,  89,   0, 
-      0,   4,  70, 142,  32,   0, 
-      0,   0,   0,   0,   4,   0, 
-      0,   0,  96,   0,   0,   4, 
-     18,  16,  16,   0,   0,   0, 
-      0,   0,   6,   0,   0,   0, 
-    103,   0,   0,   4, 242,  32, 
-     16,   0,   0,   0,   0,   0, 
-      1,   0,   0,   0, 101,   0, 
-      0,   3,  18,  32,  16,   0, 
-      1,   0,   0,   0, 101,   0, 
-      0,   3,  34,  32,  16,   0, 
-      1,   0,   0,   0, 104,   0, 
-      0,   2,   2,   0,   0,   0, 
-     54,   0,   0,   8, 194,  32, 
-     16,   0,   0,   0,   0,   0, 
-      2,  64,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-    128,  63,  38,   0,   0,  10, 
-      0, 208,   0,   0,  50,   0, 
-     16,   0,   0,   0,   0,   0, 
-    246, 143,  32,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-    150, 133,  32,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-     78,   0,   0,   8,  66,   0, 
-     16,   0,   0,   0,   0,   0, 
-      0, 208,   0,   0,  10,  16, 
-     16,   0,   0,   0,   0,   0, 
-     10,   0,  16,   0,   0,   0, 
-      0,   0,  35,   0,   0,  10, 
-     18,   0,  16,   0,   0,   0, 
-      0,   0,  42,   0,  16, 128, 
-     65,   0,   0,   0,   0,   0, 
-      0,   0,  10,   0,  16,   0, 
-      0,   0,   0,   0,  10,  16, 
-     16,   0,   0,   0,   0,   0, 
-     35,   0,   0,  10,  34,   0, 
-     16,   0,   0,   0,   0,   0, 
-     42,   0,  16,   0,   0,   0, 
-      0,   0,  26,   0,  16,   0, 
-      0,   0,   0,   0,  10, 128, 
-     32,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,  30,   0, 
-      0,   8,  34,  32,  16,   0, 
-      1,   0,   0,   0,  42,   0, 
-     16,   0,   0,   0,   0,   0, 
-     10, 128,  32,   0,   0,   0, 
-      0,   0,   3,   0,   0,   0, 
-     78,   0,   0,   9,  66,   0, 
-     16,   0,   0,   0,   0,   0, 
-      0, 208,   0,   0,  10,   0, 
-     16,   0,   0,   0,   0,   0, 
-     26, 128,  32,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-     35,   0,   0,  11,  18,   0, 
-     16,   0,   0,   0,   0,   0, 
-     42,   0,  16, 128,  65,   0, 
-      0,   0,   0,   0,   0,   0, 
-     26, 128,  32,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-     10,   0,  16,   0,   0,   0, 
-      0,   0,  86,   0,   0,   5, 
-     50,   0,  16,   0,   1,   0, 
-      0,   0, 134,   0,  16,   0, 
-      0,   0,   0,   0,  35,   0, 
-      0,  10,  34,   0,  16,   0, 
-      0,   0,   0,   0,  42,   0, 
-     16,   0,   0,   0,   0,   0, 
-     42, 128,  32,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-     26,   0,  16,   0,   0,   0, 
-      0,   0,  30,   0,   0,   7, 
-     18,  32,  16,   0,   1,   0, 
-      0,   0,  10,   0,  16,   0, 
-      0,   0,   0,   0,  26,   0, 
-     16,   0,   0,   0,   0,   0, 
-     50,   0,   0,  11,  50,  32, 
-     16,   0,   0,   0,   0,   0, 
-    230, 138,  32,   0,   0,   0, 
-      0,   0,   1,   0,   0,   0, 
-     70,   0,  16,   0,   1,   0, 
-      0,   0,  70, 128,  32,   0, 
-      0,   0,   0,   0,   1,   0, 
-      0,   0,  62,   0,   0,   1, 
-     83,  84,  65,  84, 116,   0, 
-      0,   0,  13,   0,   0,   0, 
-      2,   0,   0,   0,   0,   0, 
-      0,   0,   4,   0,   0,   0, 
-      1,   0,   0,   0,   7,   0, 
-      0,   0,   2,   0,   0,   0, 
-      1,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      1,   0,   0,   0,   0,   0, 
-      0,   0,   1,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0
-};
+#if 0
+//
+// Generated by Microsoft (R) HLSL Shader Compiler 6.3.9600.16384
+//
+//
+// Buffer Definitions: 
+//
+// cbuffer BufferCopyParams
+// {
+//
+//   uint FirstPixelOffset;             // Offset:    0 Size:     4
+//   uint PixelsPerRow;                 // Offset:    4 Size:     4
+//   uint RowStride;                    // Offset:    8 Size:     4
+//   uint RowsPerSlice;                 // Offset:   12 Size:     4
+//   float2 PositionOffset;             // Offset:   16 Size:     8
+//   float2 PositionScale;              // Offset:   24 Size:     8
+//   int2 TexLocationOffset;            // Offset:   32 Size:     8 [unused]
+//   int2 TexLocationScale;             // Offset:   40 Size:     8 [unused]
+//   uint FirstSlice;                   // Offset:   48 Size:     4
+//
+// }
+//
+//
+// Resource Bindings:
+//
+// Name                                 Type  Format         Dim Slot Elements
+// ------------------------------ ---------- ------- ----------- ---- --------
+// BufferCopyParams                  cbuffer      NA          NA    0        1
+//
+//
+//
+// Input signature:
+//
+// Name                 Index   Mask Register SysValue  Format   Used
+// -------------------- ----- ------ -------- -------- ------- ------
+// SV_VertexID              0   x           0   VERTID    uint   x   
+//
+//
+// Output signature:
+//
+// Name                 Index   Mask Register SysValue  Format   Used
+// -------------------- ----- ------ -------- -------- ------- ------
+// SV_Position              0   xyzw        0      POS   float   xyzw
+// TEXCOORD                 0   x           1     NONE    uint   x   
+// LAYER                    0    y          1     NONE    uint    y  
+//
+vs_4_0
+dcl_constantbuffer cb0[4], immediateIndexed
+dcl_input_sgv v0.x, vertex_id
+dcl_output_siv o0.xyzw, position
+dcl_output o1.x
+dcl_output o1.y
+dcl_temps 2
+mov o0.zw, l(0,0,0,1.000000)
+imul null, r0.xy, cb0[0].wwww, cb0[0].yzyy
+udiv r0.z, null, v0.x, r0.x
+imad r0.x, -r0.z, r0.x, v0.x
+imad r0.y, r0.z, r0.y, cb0[0].x
+iadd o1.y, r0.z, cb0[3].x
+udiv r0.z, null, r0.x, cb0[0].y
+imad r0.x, -r0.z, cb0[0].y, r0.x
+utof r1.xy, r0.xzxx
+imad r0.y, r0.z, cb0[0].z, r0.y
+iadd o1.x, r0.x, r0.y
+mad o0.xy, cb0[1].zwzz, r1.xyxx, cb0[1].xyxx
+ret 
+// Approximately 13 instruction slots used
+#endif
+
+const BYTE g_VS_BufferToTexture[] =
+{
+     68,  88,  66,  67,  39, 207, 
+    138,  15,  42, 195, 141, 208, 
+      2, 107, 135, 197, 122,  36, 
+    114, 227,   1,   0,   0,   0, 
+    152,   5,   0,   0,   5,   0, 
+      0,   0,  52,   0,   0,   0, 
+    100,   2,   0,   0, 152,   2, 
+      0,   0,  12,   3,   0,   0, 
+     28,   5,   0,   0,  82,  68, 
+     69,  70,  40,   2,   0,   0, 
+      1,   0,   0,   0,  80,   0, 
+      0,   0,   1,   0,   0,   0, 
+     28,   0,   0,   0,   0,   4, 
+    254, 255,   0,   1,   0,   0, 
+    244,   1,   0,   0,  60,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   1,   0, 
+      0,   0,   1,   0,   0,   0, 
+     66, 117, 102, 102, 101, 114, 
+     67, 111, 112, 121,  80,  97, 
+    114,  97, 109, 115,   0, 171, 
+    171, 171,  60,   0,   0,   0, 
+      9,   0,   0,   0, 104,   0, 
+      0,   0,  64,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,  64,   1,   0,   0, 
+      0,   0,   0,   0,   4,   0, 
+      0,   0,   2,   0,   0,   0, 
+     84,   1,   0,   0,   0,   0, 
+      0,   0, 100,   1,   0,   0, 
+      4,   0,   0,   0,   4,   0, 
+      0,   0,   2,   0,   0,   0, 
+     84,   1,   0,   0,   0,   0, 
+      0,   0, 113,   1,   0,   0, 
+      8,   0,   0,   0,   4,   0, 
+      0,   0,   2,   0,   0,   0, 
+     84,   1,   0,   0,   0,   0, 
+      0,   0, 123,   1,   0,   0, 
+     12,   0,   0,   0,   4,   0, 
+      0,   0,   2,   0,   0,   0, 
+     84,   1,   0,   0,   0,   0, 
+      0,   0, 136,   1,   0,   0, 
+     16,   0,   0,   0,   8,   0, 
+      0,   0,   2,   0,   0,   0, 
+    152,   1,   0,   0,   0,   0, 
+      0,   0, 168,   1,   0,   0, 
+     24,   0,   0,   0,   8,   0, 
+      0,   0,   2,   0,   0,   0, 
+    152,   1,   0,   0,   0,   0, 
+      0,   0, 182,   1,   0,   0, 
+     32,   0,   0,   0,   8,   0, 
+      0,   0,   0,   0,   0,   0, 
+    200,   1,   0,   0,   0,   0, 
+      0,   0, 216,   1,   0,   0, 
+     40,   0,   0,   0,   8,   0, 
+      0,   0,   0,   0,   0,   0, 
+    200,   1,   0,   0,   0,   0, 
+      0,   0, 233,   1,   0,   0, 
+     48,   0,   0,   0,   4,   0, 
+      0,   0,   2,   0,   0,   0, 
+     84,   1,   0,   0,   0,   0, 
+      0,   0,  70, 105, 114, 115, 
+    116,  80, 105, 120, 101, 108, 
+     79, 102, 102, 115, 101, 116, 
+      0, 171, 171, 171,   0,   0, 
+     19,   0,   1,   0,   1,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,  80, 105, 120, 101, 
+    108, 115,  80, 101, 114,  82, 
+    111, 119,   0,  82, 111, 119, 
+     83, 116, 114, 105, 100, 101, 
+      0,  82, 111, 119, 115,  80, 
+    101, 114,  83, 108, 105,  99, 
+    101,   0,  80, 111, 115, 105, 
+    116, 105, 111, 110,  79, 102, 
+    102, 115, 101, 116,   0, 171, 
+      1,   0,   3,   0,   1,   0, 
+      2,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,  80, 111, 
+    115, 105, 116, 105, 111, 110, 
+     83,  99,  97, 108, 101,   0, 
+     84, 101, 120,  76, 111,  99, 
+     97, 116, 105, 111, 110,  79, 
+    102, 102, 115, 101, 116,   0, 
+      1,   0,   2,   0,   1,   0, 
+      2,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,  84, 101, 
+    120,  76, 111,  99,  97, 116, 
+    105, 111, 110,  83,  99,  97, 
+    108, 101,   0,  70, 105, 114, 
+    115, 116,  83, 108, 105,  99, 
+    101,   0,  77, 105,  99, 114, 
+    111, 115, 111, 102, 116,  32, 
+     40,  82,  41,  32,  72,  76, 
+     83,  76,  32,  83, 104,  97, 
+    100, 101, 114,  32,  67, 111, 
+    109, 112, 105, 108, 101, 114, 
+     32,  54,  46,  51,  46,  57, 
+     54,  48,  48,  46,  49,  54, 
+     51,  56,  52,   0, 171, 171, 
+     73,  83,  71,  78,  44,   0, 
+      0,   0,   1,   0,   0,   0, 
+      8,   0,   0,   0,  32,   0, 
+      0,   0,   0,   0,   0,   0, 
+      6,   0,   0,   0,   1,   0, 
+      0,   0,   0,   0,   0,   0, 
+      1,   1,   0,   0,  83,  86, 
+     95,  86, 101, 114, 116, 101, 
+    120,  73,  68,   0,  79,  83, 
+     71,  78, 108,   0,   0,   0, 
+      3,   0,   0,   0,   8,   0, 
+      0,   0,  80,   0,   0,   0, 
+      0,   0,   0,   0,   1,   0, 
+      0,   0,   3,   0,   0,   0, 
+      0,   0,   0,   0,  15,   0, 
+      0,   0,  92,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   1,   0,   0,   0, 
+      1,   0,   0,   0,   1,  14, 
+      0,   0, 101,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   1,   0,   0,   0, 
+      1,   0,   0,   0,   2,  13, 
+      0,   0,  83,  86,  95,  80, 
+    111, 115, 105, 116, 105, 111, 
+    110,   0,  84,  69,  88,  67, 
+     79,  79,  82,  68,   0,  76, 
+     65,  89,  69,  82,   0, 171, 
+     83,  72,  68,  82,   8,   2, 
+      0,   0,  64,   0,   1,   0, 
+    130,   0,   0,   0,  89,   0, 
+      0,   4,  70, 142,  32,   0, 
+      0,   0,   0,   0,   4,   0, 
+      0,   0,  96,   0,   0,   4, 
+     18,  16,  16,   0,   0,   0, 
+      0,   0,   6,   0,   0,   0, 
+    103,   0,   0,   4, 242,  32, 
+     16,   0,   0,   0,   0,   0, 
+      1,   0,   0,   0, 101,   0, 
+      0,   3,  18,  32,  16,   0, 
+      1,   0,   0,   0, 101,   0, 
+      0,   3,  34,  32,  16,   0, 
+      1,   0,   0,   0, 104,   0, 
+      0,   2,   2,   0,   0,   0, 
+     54,   0,   0,   8, 194,  32, 
+     16,   0,   0,   0,   0,   0, 
+      2,  64,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+    128,  63,  38,   0,   0,  10, 
+      0, 208,   0,   0,  50,   0, 
+     16,   0,   0,   0,   0,   0, 
+    246, 143,  32,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+    150, 133,  32,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+     78,   0,   0,   8,  66,   0, 
+     16,   0,   0,   0,   0,   0, 
+      0, 208,   0,   0,  10,  16, 
+     16,   0,   0,   0,   0,   0, 
+     10,   0,  16,   0,   0,   0, 
+      0,   0,  35,   0,   0,  10, 
+     18,   0,  16,   0,   0,   0, 
+      0,   0,  42,   0,  16, 128, 
+     65,   0,   0,   0,   0,   0, 
+      0,   0,  10,   0,  16,   0, 
+      0,   0,   0,   0,  10,  16, 
+     16,   0,   0,   0,   0,   0, 
+     35,   0,   0,  10,  34,   0, 
+     16,   0,   0,   0,   0,   0, 
+     42,   0,  16,   0,   0,   0, 
+      0,   0,  26,   0,  16,   0, 
+      0,   0,   0,   0,  10, 128, 
+     32,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,  30,   0, 
+      0,   8,  34,  32,  16,   0, 
+      1,   0,   0,   0,  42,   0, 
+     16,   0,   0,   0,   0,   0, 
+     10, 128,  32,   0,   0,   0, 
+      0,   0,   3,   0,   0,   0, 
+     78,   0,   0,   9,  66,   0, 
+     16,   0,   0,   0,   0,   0, 
+      0, 208,   0,   0,  10,   0, 
+     16,   0,   0,   0,   0,   0, 
+     26, 128,  32,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+     35,   0,   0,  11,  18,   0, 
+     16,   0,   0,   0,   0,   0, 
+     42,   0,  16, 128,  65,   0, 
+      0,   0,   0,   0,   0,   0, 
+     26, 128,  32,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+     10,   0,  16,   0,   0,   0, 
+      0,   0,  86,   0,   0,   5, 
+     50,   0,  16,   0,   1,   0, 
+      0,   0, 134,   0,  16,   0, 
+      0,   0,   0,   0,  35,   0, 
+      0,  10,  34,   0,  16,   0, 
+      0,   0,   0,   0,  42,   0, 
+     16,   0,   0,   0,   0,   0, 
+     42, 128,  32,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+     26,   0,  16,   0,   0,   0, 
+      0,   0,  30,   0,   0,   7, 
+     18,  32,  16,   0,   1,   0, 
+      0,   0,  10,   0,  16,   0, 
+      0,   0,   0,   0,  26,   0, 
+     16,   0,   0,   0,   0,   0, 
+     50,   0,   0,  11,  50,  32, 
+     16,   0,   0,   0,   0,   0, 
+    230, 138,  32,   0,   0,   0, 
+      0,   0,   1,   0,   0,   0, 
+     70,   0,  16,   0,   1,   0, 
+      0,   0,  70, 128,  32,   0, 
+      0,   0,   0,   0,   1,   0, 
+      0,   0,  62,   0,   0,   1, 
+     83,  84,  65,  84, 116,   0, 
+      0,   0,  13,   0,   0,   0, 
+      2,   0,   0,   0,   0,   0, 
+      0,   0,   4,   0,   0,   0, 
+      1,   0,   0,   0,   7,   0, 
+      0,   0,   2,   0,   0,   0, 
+      1,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      1,   0,   0,   0,   0,   0, 
+      0,   0,   1,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0
+};
--- a/gfx/angle/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/clear11_fl9vs.h
+++ b/gfx/angle/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/clear11_fl9vs.h
@@ -1,136 +1,136 @@
-#if 0
-//
-// Generated by Microsoft (R) HLSL Shader Compiler 6.3.9600.16384
-//
-//
-//
-// Input signature:
-//
-// Name                 Index   Mask Register SysValue  Format   Used
-// -------------------- ----- ------ -------- -------- ------- ------
-// POSITION                 0   xyzw        0     NONE   float   xyzw
-//
-//
-// Output signature:
-//
-// Name                 Index   Mask Register SysValue  Format   Used
-// -------------------- ----- ------ -------- -------- ------- ------
-// SV_POSITION              0   xyzw        0      POS   float   xyzw
-//
-//
-// Runtime generated constant mappings:
-//
-// Target Reg                               Constant Description
-// ---------- --------------------------------------------------
-// c0                              Vertex Shader position offset
-//
-//
-// Level9 shader bytecode:
-//
-    vs_2_x
-    dcl_texcoord v0
-    mad oPos.xy, v0.w, c0, v0
-    mov oPos.zw, v0
-
-// approximately 2 instruction slots used
-vs_4_0
-dcl_input v0.xyzw
-dcl_output_siv o0.xyzw, position
-mov o0.xyzw, v0.xyzw
-ret 
-// Approximately 2 instruction slots used
-#endif
-
-const BYTE g_VS_Clear_FL9[] =
-{
-     68,  88,  66,  67, 176,  74, 
-    193, 175,  25,  51, 252,  39, 
-    176, 214, 107,  38, 137, 209, 
-    240, 189,   1,   0,   0,   0, 
-     28,   2,   0,   0,   6,   0, 
-      0,   0,  56,   0,   0,   0, 
-    156,   0,   0,   0, 224,   0, 
-      0,   0,  92,   1,   0,   0, 
-    180,   1,   0,   0, 232,   1, 
-      0,   0,  65, 111, 110,  57, 
-     92,   0,   0,   0,  92,   0, 
-      0,   0,   0,   2, 254, 255, 
-     52,   0,   0,   0,  40,   0, 
-      0,   0,   0,   0,  36,   0, 
-      0,   0,  36,   0,   0,   0, 
-     36,   0,   0,   0,  36,   0, 
-      1,   0,  36,   0,   0,   0, 
-      0,   0,   1,   2, 254, 255, 
-     31,   0,   0,   2,   5,   0, 
-      0, 128,   0,   0,  15, 144, 
-      4,   0,   0,   4,   0,   0, 
-      3, 192,   0,   0, 255, 144, 
-      0,   0, 228, 160,   0,   0, 
-    228, 144,   1,   0,   0,   2, 
-      0,   0,  12, 192,   0,   0, 
-    228, 144, 255, 255,   0,   0, 
-     83,  72,  68,  82,  60,   0, 
-      0,   0,  64,   0,   1,   0, 
-     15,   0,   0,   0,  95,   0, 
-      0,   3, 242,  16,  16,   0, 
-      0,   0,   0,   0, 103,   0, 
-      0,   4, 242,  32,  16,   0, 
-      0,   0,   0,   0,   1,   0, 
-      0,   0,  54,   0,   0,   5, 
-    242,  32,  16,   0,   0,   0, 
-      0,   0,  70,  30,  16,   0, 
-      0,   0,   0,   0,  62,   0, 
-      0,   1,  83,  84,  65,  84, 
-    116,   0,   0,   0,   2,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   2,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   1,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   1,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-     82,  68,  69,  70,  80,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,  28,   0,   0,   0, 
-      0,   4, 254, 255,   0,   1, 
-      0,   0,  28,   0,   0,   0, 
-     77, 105,  99, 114, 111, 115, 
-    111, 102, 116,  32,  40,  82, 
-     41,  32,  72,  76,  83,  76, 
-     32,  83, 104,  97, 100, 101, 
-    114,  32,  67, 111, 109, 112, 
-    105, 108, 101, 114,  32,  54, 
-     46,  51,  46,  57,  54,  48, 
-     48,  46,  49,  54,  51,  56, 
-     52,   0, 171, 171,  73,  83, 
-     71,  78,  44,   0,   0,   0, 
-      1,   0,   0,   0,   8,   0, 
-      0,   0,  32,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   3,   0,   0,   0, 
-      0,   0,   0,   0,  15,  15, 
-      0,   0,  80,  79,  83,  73, 
-     84,  73,  79,  78,   0, 171, 
-    171, 171,  79,  83,  71,  78, 
-     44,   0,   0,   0,   1,   0, 
-      0,   0,   8,   0,   0,   0, 
-     32,   0,   0,   0,   0,   0, 
-      0,   0,   1,   0,   0,   0, 
-      3,   0,   0,   0,   0,   0, 
-      0,   0,  15,   0,   0,   0, 
-     83,  86,  95,  80,  79,  83, 
-     73,  84,  73,  79,  78,   0
-};
+#if 0
+//
+// Generated by Microsoft (R) HLSL Shader Compiler 6.3.9600.16384
+//
+//
+//
+// Input signature:
+//
+// Name                 Index   Mask Register SysValue  Format   Used
+// -------------------- ----- ------ -------- -------- ------- ------
+// POSITION                 0   xyzw        0     NONE   float   xyzw
+//
+//
+// Output signature:
+//
+// Name                 Index   Mask Register SysValue  Format   Used
+// -------------------- ----- ------ -------- -------- ------- ------
+// SV_POSITION              0   xyzw        0      POS   float   xyzw
+//
+//
+// Runtime generated constant mappings:
+//
+// Target Reg                               Constant Description
+// ---------- --------------------------------------------------
+// c0                              Vertex Shader position offset
+//
+//
+// Level9 shader bytecode:
+//
+    vs_2_x
+    dcl_texcoord v0
+    mad oPos.xy, v0.w, c0, v0
+    mov oPos.zw, v0
+
+// approximately 2 instruction slots used
+vs_4_0
+dcl_input v0.xyzw
+dcl_output_siv o0.xyzw, position
+mov o0.xyzw, v0.xyzw
+ret 
+// Approximately 2 instruction slots used
+#endif
+
+const BYTE g_VS_Clear_FL9[] =
+{
+     68,  88,  66,  67, 176,  74, 
+    193, 175,  25,  51, 252,  39, 
+    176, 214, 107,  38, 137, 209, 
+    240, 189,   1,   0,   0,   0, 
+     28,   2,   0,   0,   6,   0, 
+      0,   0,  56,   0,   0,   0, 
+    156,   0,   0,   0, 224,   0, 
+      0,   0,  92,   1,   0,   0, 
+    180,   1,   0,   0, 232,   1, 
+      0,   0,  65, 111, 110,  57, 
+     92,   0,   0,   0,  92,   0, 
+      0,   0,   0,   2, 254, 255, 
+     52,   0,   0,   0,  40,   0, 
+      0,   0,   0,   0,  36,   0, 
+      0,   0,  36,   0,   0,   0, 
+     36,   0,   0,   0,  36,   0, 
+      1,   0,  36,   0,   0,   0, 
+      0,   0,   1,   2, 254, 255, 
+     31,   0,   0,   2,   5,   0, 
+      0, 128,   0,   0,  15, 144, 
+      4,   0,   0,   4,   0,   0, 
+      3, 192,   0,   0, 255, 144, 
+      0,   0, 228, 160,   0,   0, 
+    228, 144,   1,   0,   0,   2, 
+      0,   0,  12, 192,   0,   0, 
+    228, 144, 255, 255,   0,   0, 
+     83,  72,  68,  82,  60,   0, 
+      0,   0,  64,   0,   1,   0, 
+     15,   0,   0,   0,  95,   0, 
+      0,   3, 242,  16,  16,   0, 
+      0,   0,   0,   0, 103,   0, 
+      0,   4, 242,  32,  16,   0, 
+      0,   0,   0,   0,   1,   0, 
+      0,   0,  54,   0,   0,   5, 
+    242,  32,  16,   0,   0,   0, 
+      0,   0,  70,  30,  16,   0, 
+      0,   0,   0,   0,  62,   0, 
+      0,   1,  83,  84,  65,  84, 
+    116,   0,   0,   0,   2,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   2,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   1,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   1,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+     82,  68,  69,  70,  80,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,  28,   0,   0,   0, 
+      0,   4, 254, 255,   0,   1, 
+      0,   0,  28,   0,   0,   0, 
+     77, 105,  99, 114, 111, 115, 
+    111, 102, 116,  32,  40,  82, 
+     41,  32,  72,  76,  83,  76, 
+     32,  83, 104,  97, 100, 101, 
+    114,  32,  67, 111, 109, 112, 
+    105, 108, 101, 114,  32,  54, 
+     46,  51,  46,  57,  54,  48, 
+     48,  46,  49,  54,  51,  56, 
+     52,   0, 171, 171,  73,  83, 
+     71,  78,  44,   0,   0,   0, 
+      1,   0,   0,   0,   8,   0, 
+      0,   0,  32,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   3,   0,   0,   0, 
+      0,   0,   0,   0,  15,  15, 
+      0,   0,  80,  79,  83,  73, 
+     84,  73,  79,  78,   0, 171, 
+    171, 171,  79,  83,  71,  78, 
+     44,   0,   0,   0,   1,   0, 
+      0,   0,   8,   0,   0,   0, 
+     32,   0,   0,   0,   0,   0, 
+      0,   0,   1,   0,   0,   0, 
+      3,   0,   0,   0,   0,   0, 
+      0,   0,  15,   0,   0,   0, 
+     83,  86,  95,  80,  79,  83, 
+     73,  84,  73,  79,  78,   0
+};
--- a/gfx/angle/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/clear11multiviewgs.h
+++ b/gfx/angle/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/clear11multiviewgs.h
@@ -1,84 +1,84 @@
-#if 0
-//
-// Generated by Microsoft (R) HLSL Shader Compiler 6.3.9600.16384
-//
-//
-//
-// Input signature:
-//
-// Name                 Index   Mask Register SysValue  Format   Used
-// -------------------- ----- ------ -------- -------- ------- ------
-// SV_Position              0   xyzw        0      POS   float   xyzw
-// TEXCOORD                 0   x           1     NONE    uint   x   
-//
-//
-// Output signature:
-//
-// Name                 Index   Mask Register SysValue  Format   Used
-// -------------------- ----- ------ -------- -------- ------- ------
-// SV_Position              0   xyzw        0      POS   float   xyzw
-// SV_RenderTargetArrayIndex     0   x           1  RTINDEX    uint   x   
-//
-gs_4_0
-dcl_input_siv v[3][0].xyzw, position
-dcl_input v[3][1].x
-dcl_temps 1
-dcl_inputprimitive triangle 
-dcl_outputtopology trianglestrip 
-dcl_output_siv o0.xyzw, position
-dcl_output_siv o1.x, rendertarget_array_index
-dcl_maxout 3
-mov r0.x, l(0)
-loop 
-  ige r0.y, r0.x, l(3)
-  breakc_nz r0.y
-  mov o0.xyzw, v[r0.x + 0][0].xyzw
-  mov o1.x, v[r0.x + 0][1].x
-  emit 
-  iadd r0.x, r0.x, l(1)
-endloop 
-cut 
-ret 
-// Approximately 11 instruction slots used
-#endif
-
-const BYTE g_GS_Multiview_Clear[] = {
-    68,  88,  66,  67,  244, 54,  208, 241, 128, 215, 208, 159, 113, 168, 148, 173, 167, 24,  78,
-    189, 1,   0,   0,   0,   216, 2,   0,   0,   5,   0,   0,   0,   52,  0,   0,   0,   140, 0,
-    0,   0,   228, 0,   0,   0,   76,  1,   0,   0,   92,  2,   0,   0,   82,  68,  69,  70,  80,
-    0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   28,  0,   0,   0,
-    0,   4,   83,  71,  0,   1,   0,   0,   28,  0,   0,   0,   77,  105, 99,  114, 111, 115, 111,
-    102, 116, 32,  40,  82,  41,  32,  72,  76,  83,  76,  32,  83,  104, 97,  100, 101, 114, 32,
-    67,  111, 109, 112, 105, 108, 101, 114, 32,  54,  46,  51,  46,  57,  54,  48,  48,  46,  49,
-    54,  51,  56,  52,  0,   171, 171, 73,  83,  71,  78,  80,  0,   0,   0,   2,   0,   0,   0,
-    8,   0,   0,   0,   56,  0,   0,   0,   0,   0,   0,   0,   1,   0,   0,   0,   3,   0,   0,
-    0,   0,   0,   0,   0,   15,  15,  0,   0,   68,  0,   0,   0,   0,   0,   0,   0,   0,   0,
-    0,   0,   1,   0,   0,   0,   1,   0,   0,   0,   1,   1,   0,   0,   83,  86,  95,  80,  111,
-    115, 105, 116, 105, 111, 110, 0,   84,  69,  88,  67,  79,  79,  82,  68,  0,   171, 171, 171,
-    79,  83,  71,  78,  96,  0,   0,   0,   2,   0,   0,   0,   8,   0,   0,   0,   56,  0,   0,
-    0,   0,   0,   0,   0,   1,   0,   0,   0,   3,   0,   0,   0,   0,   0,   0,   0,   15,  0,
-    0,   0,   68,  0,   0,   0,   0,   0,   0,   0,   4,   0,   0,   0,   1,   0,   0,   0,   1,
-    0,   0,   0,   1,   14,  0,   0,   83,  86,  95,  80,  111, 115, 105, 116, 105, 111, 110, 0,
-    83,  86,  95,  82,  101, 110, 100, 101, 114, 84,  97,  114, 103, 101, 116, 65,  114, 114, 97,
-    121, 73,  110, 100, 101, 120, 0,   171, 171, 83,  72,  68,  82,  8,   1,   0,   0,   64,  0,
-    2,   0,   66,  0,   0,   0,   97,  0,   0,   5,   242, 16,  32,  0,   3,   0,   0,   0,   0,
-    0,   0,   0,   1,   0,   0,   0,   95,  0,   0,   4,   18,  16,  32,  0,   3,   0,   0,   0,
-    1,   0,   0,   0,   104, 0,   0,   2,   1,   0,   0,   0,   93,  24,  0,   1,   92,  40,  0,
-    1,   103, 0,   0,   4,   242, 32,  16,  0,   0,   0,   0,   0,   1,   0,   0,   0,   103, 0,
-    0,   4,   18,  32,  16,  0,   1,   0,   0,   0,   4,   0,   0,   0,   94,  0,   0,   2,   3,
-    0,   0,   0,   54,  0,   0,   5,   18,  0,   16,  0,   0,   0,   0,   0,   1,   64,  0,   0,
-    0,   0,   0,   0,   48,  0,   0,   1,   33,  0,   0,   7,   34,  0,   16,  0,   0,   0,   0,
-    0,   10,  0,   16,  0,   0,   0,   0,   0,   1,   64,  0,   0,   3,   0,   0,   0,   3,   0,
-    4,   3,   26,  0,   16,  0,   0,   0,   0,   0,   54,  0,   0,   7,   242, 32,  16,  0,   0,
-    0,   0,   0,   70,  30,  160, 0,   10,  0,   16,  0,   0,   0,   0,   0,   0,   0,   0,   0,
-    54,  0,   0,   7,   18,  32,  16,  0,   1,   0,   0,   0,   10,  16,  160, 0,   10,  0,   16,
-    0,   0,   0,   0,   0,   1,   0,   0,   0,   19,  0,   0,   1,   30,  0,   0,   7,   18,  0,
-    16,  0,   0,   0,   0,   0,   10,  0,   16,  0,   0,   0,   0,   0,   1,   64,  0,   0,   1,
-    0,   0,   0,   22,  0,   0,   1,   9,   0,   0,   1,   62,  0,   0,   1,   83,  84,  65,  84,
-    116, 0,   0,   0,   11,  0,   0,   0,   1,   0,   0,   0,   0,   0,   0,   0,   4,   0,   0,
-    0,   0,   0,   0,   0,   2,   0,   0,   0,   0,   0,   0,   0,   1,   0,   0,   0,   1,   0,
-    0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   1,   0,   0,   0,   1,
-    0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
-    0,   0,   0,   0,   1,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
-    0,   3,   0,   0,   0,   5,   0,   0,   0,   3,   0,   0,   0,   0,   0,   0,   0,   0,   0,
-    0,   0,   0,   0,   0,   0};
+#if 0
+//
+// Generated by Microsoft (R) HLSL Shader Compiler 6.3.9600.16384
+//
+//
+//
+// Input signature:
+//
+// Name                 Index   Mask Register SysValue  Format   Used
+// -------------------- ----- ------ -------- -------- ------- ------
+// SV_Position              0   xyzw        0      POS   float   xyzw
+// TEXCOORD                 0   x           1     NONE    uint   x   
+//
+//
+// Output signature:
+//
+// Name                 Index   Mask Register SysValue  Format   Used
+// -------------------- ----- ------ -------- -------- ------- ------
+// SV_Position              0   xyzw        0      POS   float   xyzw
+// SV_RenderTargetArrayIndex     0   x           1  RTINDEX    uint   x   
+//
+gs_4_0
+dcl_input_siv v[3][0].xyzw, position
+dcl_input v[3][1].x
+dcl_temps 1
+dcl_inputprimitive triangle 
+dcl_outputtopology trianglestrip 
+dcl_output_siv o0.xyzw, position
+dcl_output_siv o1.x, rendertarget_array_index
+dcl_maxout 3
+mov r0.x, l(0)
+loop 
+  ige r0.y, r0.x, l(3)
+  breakc_nz r0.y
+  mov o0.xyzw, v[r0.x + 0][0].xyzw
+  mov o1.x, v[r0.x + 0][1].x
+  emit 
+  iadd r0.x, r0.x, l(1)
+endloop 
+cut 
+ret 
+// Approximately 11 instruction slots used
+#endif
+
+const BYTE g_GS_Multiview_Clear[] = {
+    68,  88,  66,  67,  244, 54,  208, 241, 128, 215, 208, 159, 113, 168, 148, 173, 167, 24,  78,
+    189, 1,   0,   0,   0,   216, 2,   0,   0,   5,   0,   0,   0,   52,  0,   0,   0,   140, 0,
+    0,   0,   228, 0,   0,   0,   76,  1,   0,   0,   92,  2,   0,   0,   82,  68,  69,  70,  80,
+    0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   28,  0,   0,   0,
+    0,   4,   83,  71,  0,   1,   0,   0,   28,  0,   0,   0,   77,  105, 99,  114, 111, 115, 111,
+    102, 116, 32,  40,  82,  41,  32,  72,  76,  83,  76,  32,  83,  104, 97,  100, 101, 114, 32,
+    67,  111, 109, 112, 105, 108, 101, 114, 32,  54,  46,  51,  46,  57,  54,  48,  48,  46,  49,
+    54,  51,  56,  52,  0,   171, 171, 73,  83,  71,  78,  80,  0,   0,   0,   2,   0,   0,   0,
+    8,   0,   0,   0,   56,  0,   0,   0,   0,   0,   0,   0,   1,   0,   0,   0,   3,   0,   0,
+    0,   0,   0,   0,   0,   15,  15,  0,   0,   68,  0,   0,   0,   0,   0,   0,   0,   0,   0,
+    0,   0,   1,   0,   0,   0,   1,   0,   0,   0,   1,   1,   0,   0,   83,  86,  95,  80,  111,
+    115, 105, 116, 105, 111, 110, 0,   84,  69,  88,  67,  79,  79,  82,  68,  0,   171, 171, 171,
+    79,  83,  71,  78,  96,  0,   0,   0,   2,   0,   0,   0,   8,   0,   0,   0,   56,  0,   0,
+    0,   0,   0,   0,   0,   1,   0,   0,   0,   3,   0,   0,   0,   0,   0,   0,   0,   15,  0,
+    0,   0,   68,  0,   0,   0,   0,   0,   0,   0,   4,   0,   0,   0,   1,   0,   0,   0,   1,
+    0,   0,   0,   1,   14,  0,   0,   83,  86,  95,  80,  111, 115, 105, 116, 105, 111, 110, 0,
+    83,  86,  95,  82,  101, 110, 100, 101, 114, 84,  97,  114, 103, 101, 116, 65,  114, 114, 97,
+    121, 73,  110, 100, 101, 120, 0,   171, 171, 83,  72,  68,  82,  8,   1,   0,   0,   64,  0,
+    2,   0,   66,  0,   0,   0,   97,  0,   0,   5,   242, 16,  32,  0,   3,   0,   0,   0,   0,
+    0,   0,   0,   1,   0,   0,   0,   95,  0,   0,   4,   18,  16,  32,  0,   3,   0,   0,   0,
+    1,   0,   0,   0,   104, 0,   0,   2,   1,   0,   0,   0,   93,  24,  0,   1,   92,  40,  0,
+    1,   103, 0,   0,   4,   242, 32,  16,  0,   0,   0,   0,   0,   1,   0,   0,   0,   103, 0,
+    0,   4,   18,  32,  16,  0,   1,   0,   0,   0,   4,   0,   0,   0,   94,  0,   0,   2,   3,
+    0,   0,   0,   54,  0,   0,   5,   18,  0,   16,  0,   0,   0,   0,   0,   1,   64,  0,   0,
+    0,   0,   0,   0,   48,  0,   0,   1,   33,  0,   0,   7,   34,  0,   16,  0,   0,   0,   0,
+    0,   10,  0,   16,  0,   0,   0,   0,   0,   1,   64,  0,   0,   3,   0,   0,   0,   3,   0,
+    4,   3,   26,  0,   16,  0,   0,   0,   0,   0,   54,  0,   0,   7,   242, 32,  16,  0,   0,
+    0,   0,   0,   70,  30,  160, 0,   10,  0,   16,  0,   0,   0,   0,   0,   0,   0,   0,   0,
+    54,  0,   0,   7,   18,  32,  16,  0,   1,   0,   0,   0,   10,  16,  160, 0,   10,  0,   16,
+    0,   0,   0,   0,   0,   1,   0,   0,   0,   19,  0,   0,   1,   30,  0,   0,   7,   18,  0,
+    16,  0,   0,   0,   0,   0,   10,  0,   16,  0,   0,   0,   0,   0,   1,   64,  0,   0,   1,
+    0,   0,   0,   22,  0,   0,   1,   9,   0,   0,   1,   62,  0,   0,   1,   83,  84,  65,  84,
+    116, 0,   0,   0,   11,  0,   0,   0,   1,   0,   0,   0,   0,   0,   0,   0,   4,   0,   0,
+    0,   0,   0,   0,   0,   2,   0,   0,   0,   0,   0,   0,   0,   1,   0,   0,   0,   1,   0,
+    0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   1,   0,   0,   0,   1,
+    0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+    0,   0,   0,   0,   1,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+    0,   3,   0,   0,   0,   5,   0,   0,   0,   3,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+    0,   0,   0,   0,   0,   0};
--- a/gfx/angle/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/clear11multiviewvs.h
+++ b/gfx/angle/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/clear11multiviewvs.h
@@ -1,81 +1,81 @@
-#if 0
-//
-// Generated by Microsoft (R) HLSL Shader Compiler 6.3.9600.16384
-//
-//
-//
-// Input signature:
-//
-// Name                 Index   Mask Register SysValue  Format   Used
-// -------------------- ----- ------ -------- -------- ------- ------
-// SV_VertexID              0   x           0   VERTID    uint   x   
-// SV_InstanceID            0   x           1   INSTID    uint   x   
-//
-//
-// Output signature:
-//
-// Name                 Index   Mask Register SysValue  Format   Used
-// -------------------- ----- ------ -------- -------- ------- ------
-// SV_POSITION              0   xyzw        0      POS   float   xyzw
-// TEXCOORD                 0   x           1     NONE    uint   x   
-//
-vs_4_0
-dcl_immediateConstantBuffer { { -1.000000, 1.000000, 0, 0},
-                              { 1.000000, -1.000000, 0, 0},
-                              { -1.000000, -1.000000, 0, 0},
-                              { -1.000000, 1.000000, 0, 0},
-                              { 1.000000, 1.000000, 0, 0},
-                              { 1.000000, -1.000000, 0, 0} }
-dcl_input_sgv v0.x, vertex_id
-dcl_input_sgv v1.x, instance_id
-dcl_output_siv o0.xyzw, position
-dcl_output o1.x
-dcl_temps 1
-mov r0.x, v0.x
-mov o0.xy, icb[r0.x + 0].xyxx
-mov o0.zw, l(0,0,0,1.000000)
-mov o1.x, v1.x
-ret 
-// Approximately 5 instruction slots used
-#endif
-
-const BYTE g_VS_Multiview_Clear[] = {
-    68,  88,  66,  67,  45,  246, 70,  124, 58,  101, 157, 14,  171, 136, 167, 118, 133, 161, 59,
-    68,  1,   0,   0,   0,   220, 2,   0,   0,   5,   0,   0,   0,   52,  0,   0,   0,   140, 0,
-    0,   0,   232, 0,   0,   0,   64,  1,   0,   0,   96,  2,   0,   0,   82,  68,  69,  70,  80,
-    0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   28,  0,   0,   0,
-    0,   4,   254, 255, 0,   1,   0,   0,   28,  0,   0,   0,   77,  105, 99,  114, 111, 115, 111,
-    102, 116, 32,  40,  82,  41,  32,  72,  76,  83,  76,  32,  83,  104, 97,  100, 101, 114, 32,
-    67,  111, 109, 112, 105, 108, 101, 114, 32,  54,  46,  51,  46,  57,  54,  48,  48,  46,  49,
-    54,  51,  56,  52,  0,   171, 171, 73,  83,  71,  78,  84,  0,   0,   0,   2,   0,   0,   0,
-    8,   0,   0,   0,   56,  0,   0,   0,   0,   0,   0,   0,   6,   0,   0,   0,   1,   0,   0,
-    0,   0,   0,   0,   0,   1,   1,   0,   0,   68,  0,   0,   0,   0,   0,   0,   0,   8,   0,
-    0,   0,   1,   0,   0,   0,   1,   0,   0,   0,   1,   1,   0,   0,   83,  86,  95,  86,  101,
-    114, 116, 101, 120, 73,  68,  0,   83,  86,  95,  73,  110, 115, 116, 97,  110, 99,  101, 73,
-    68,  0,   171, 171, 79,  83,  71,  78,  80,  0,   0,   0,   2,   0,   0,   0,   8,   0,   0,
-    0,   56,  0,   0,   0,   0,   0,   0,   0,   1,   0,   0,   0,   3,   0,   0,   0,   0,   0,
-    0,   0,   15,  0,   0,   0,   68,  0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   1,
-    0,   0,   0,   1,   0,   0,   0,   1,   14,  0,   0,   83,  86,  95,  80,  79,  83,  73,  84,
-    73,  79,  78,  0,   84,  69,  88,  67,  79,  79,  82,  68,  0,   171, 171, 171, 83,  72,  68,
-    82,  24,  1,   0,   0,   64,  0,   1,   0,   70,  0,   0,   0,   53,  24,  0,   0,   26,  0,
-    0,   0,   0,   0,   128, 191, 0,   0,   128, 63,  0,   0,   0,   0,   0,   0,   0,   0,   0,
-    0,   128, 63,  0,   0,   128, 191, 0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   128, 191,
-    0,   0,   128, 191, 0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   128, 191, 0,   0,   128,
-    63,  0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   128, 63,  0,   0,   128, 63,  0,   0,
-    0,   0,   0,   0,   0,   0,   0,   0,   128, 63,  0,   0,   128, 191, 0,   0,   0,   0,   0,
-    0,   0,   0,   96,  0,   0,   4,   18,  16,  16,  0,   0,   0,   0,   0,   6,   0,   0,   0,
-    96,  0,   0,   4,   18,  16,  16,  0,   1,   0,   0,   0,   8,   0,   0,   0,   103, 0,   0,
-    4,   242, 32,  16,  0,   0,   0,   0,   0,   1,   0,   0,   0,   101, 0,   0,   3,   18,  32,
-    16,  0,   1,   0,   0,   0,   104, 0,   0,   2,   1,   0,   0,   0,   54,  0,   0,   5,   18,
-    0,   16,  0,   0,   0,   0,   0,   10,  16,  16,  0,   0,   0,   0,   0,   54,  0,   0,   6,
-    50,  32,  16,  0,   0,   0,   0,   0,   70,  144, 144, 0,   10,  0,   16,  0,   0,   0,   0,
-    0,   54,  0,   0,   8,   194, 32,  16,  0,   0,   0,   0,   0,   2,   64,  0,   0,   0,   0,
-    0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   128, 63,  54,  0,   0,   5,   18,
-    32,  16,  0,   1,   0,   0,   0,   10,  16,  16,  0,   1,   0,   0,   0,   62,  0,   0,   1,
-    83,  84,  65,  84,  116, 0,   0,   0,   5,   0,   0,   0,   1,   0,   0,   0,   6,   0,   0,
-    0,   4,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   1,   0,
-    0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
-    0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
-    0,   0,   0,   0,   0,   0,   0,   0,   4,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
-    0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
-    0,   0,   0,   0,   0,   0,   0,   0,   0,   0};
+#if 0
+//
+// Generated by Microsoft (R) HLSL Shader Compiler 6.3.9600.16384
+//
+//
+//
+// Input signature:
+//
+// Name                 Index   Mask Register SysValue  Format   Used
+// -------------------- ----- ------ -------- -------- ------- ------
+// SV_VertexID              0   x           0   VERTID    uint   x   
+// SV_InstanceID            0   x           1   INSTID    uint   x   
+//
+//
+// Output signature:
+//
+// Name                 Index   Mask Register SysValue  Format   Used
+// -------------------- ----- ------ -------- -------- ------- ------
+// SV_POSITION              0   xyzw        0      POS   float   xyzw
+// TEXCOORD                 0   x           1     NONE    uint   x   
+//
+vs_4_0
+dcl_immediateConstantBuffer { { -1.000000, 1.000000, 0, 0},
+                              { 1.000000, -1.000000, 0, 0},
+                              { -1.000000, -1.000000, 0, 0},
+                              { -1.000000, 1.000000, 0, 0},
+                              { 1.000000, 1.000000, 0, 0},
+                              { 1.000000, -1.000000, 0, 0} }
+dcl_input_sgv v0.x, vertex_id
+dcl_input_sgv v1.x, instance_id
+dcl_output_siv o0.xyzw, position
+dcl_output o1.x
+dcl_temps 1
+mov r0.x, v0.x
+mov o0.xy, icb[r0.x + 0].xyxx
+mov o0.zw, l(0,0,0,1.000000)
+mov o1.x, v1.x
+ret 
+// Approximately 5 instruction slots used
+#endif
+
+const BYTE g_VS_Multiview_Clear[] = {
+    68,  88,  66,  67,  45,  246, 70,  124, 58,  101, 157, 14,  171, 136, 167, 118, 133, 161, 59,
+    68,  1,   0,   0,   0,   220, 2,   0,   0,   5,   0,   0,   0,   52,  0,   0,   0,   140, 0,
+    0,   0,   232, 0,   0,   0,   64,  1,   0,   0,   96,  2,   0,   0,   82,  68,  69,  70,  80,
+    0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   28,  0,   0,   0,
+    0,   4,   254, 255, 0,   1,   0,   0,   28,  0,   0,   0,   77,  105, 99,  114, 111, 115, 111,
+    102, 116, 32,  40,  82,  41,  32,  72,  76,  83,  76,  32,  83,  104, 97,  100, 101, 114, 32,
+    67,  111, 109, 112, 105, 108, 101, 114, 32,  54,  46,  51,  46,  57,  54,  48,  48,  46,  49,
+    54,  51,  56,  52,  0,   171, 171, 73,  83,  71,  78,  84,  0,   0,   0,   2,   0,   0,   0,
+    8,   0,   0,   0,   56,  0,   0,   0,   0,   0,   0,   0,   6,   0,   0,   0,   1,   0,   0,
+    0,   0,   0,   0,   0,   1,   1,   0,   0,   68,  0,   0,   0,   0,   0,   0,   0,   8,   0,
+    0,   0,   1,   0,   0,   0,   1,   0,   0,   0,   1,   1,   0,   0,   83,  86,  95,  86,  101,
+    114, 116, 101, 120, 73,  68,  0,   83,  86,  95,  73,  110, 115, 116, 97,  110, 99,  101, 73,
+    68,  0,   171, 171, 79,  83,  71,  78,  80,  0,   0,   0,   2,   0,   0,   0,   8,   0,   0,
+    0,   56,  0,   0,   0,   0,   0,   0,   0,   1,   0,   0,   0,   3,   0,   0,   0,   0,   0,
+    0,   0,   15,  0,   0,   0,   68,  0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   1,
+    0,   0,   0,   1,   0,   0,   0,   1,   14,  0,   0,   83,  86,  95,  80,  79,  83,  73,  84,
+    73,  79,  78,  0,   84,  69,  88,  67,  79,  79,  82,  68,  0,   171, 171, 171, 83,  72,  68,
+    82,  24,  1,   0,   0,   64,  0,   1,   0,   70,  0,   0,   0,   53,  24,  0,   0,   26,  0,
+    0,   0,   0,   0,   128, 191, 0,   0,   128, 63,  0,   0,   0,   0,   0,   0,   0,   0,   0,
+    0,   128, 63,  0,   0,   128, 191, 0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   128, 191,
+    0,   0,   128, 191, 0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   128, 191, 0,   0,   128,
+    63,  0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   128, 63,  0,   0,   128, 63,  0,   0,
+    0,   0,   0,   0,   0,   0,   0,   0,   128, 63,  0,   0,   128, 191, 0,   0,   0,   0,   0,
+    0,   0,   0,   96,  0,   0,   4,   18,  16,  16,  0,   0,   0,   0,   0,   6,   0,   0,   0,
+    96,  0,   0,   4,   18,  16,  16,  0,   1,   0,   0,   0,   8,   0,   0,   0,   103, 0,   0,
+    4,   242, 32,  16,  0,   0,   0,   0,   0,   1,   0,   0,   0,   101, 0,   0,   3,   18,  32,
+    16,  0,   1,   0,   0,   0,   104, 0,   0,   2,   1,   0,   0,   0,   54,  0,   0,   5,   18,
+    0,   16,  0,   0,   0,   0,   0,   10,  16,  16,  0,   0,   0,   0,   0,   54,  0,   0,   6,
+    50,  32,  16,  0,   0,   0,   0,   0,   70,  144, 144, 0,   10,  0,   16,  0,   0,   0,   0,
+    0,   54,  0,   0,   8,   194, 32,  16,  0,   0,   0,   0,   0,   2,   64,  0,   0,   0,   0,
+    0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   128, 63,  54,  0,   0,   5,   18,
+    32,  16,  0,   1,   0,   0,   0,   10,  16,  16,  0,   1,   0,   0,   0,   62,  0,   0,   1,
+    83,  84,  65,  84,  116, 0,   0,   0,   5,   0,   0,   0,   1,   0,   0,   0,   6,   0,   0,
+    0,   4,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   1,   0,
+    0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+    0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+    0,   0,   0,   0,   0,   0,   0,   0,   4,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+    0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+    0,   0,   0,   0,   0,   0,   0,   0,   0,   0};
--- a/gfx/angle/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/clear11vs.h
+++ b/gfx/angle/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/clear11vs.h
@@ -1,141 +1,141 @@
-#if 0
-//
-// Generated by Microsoft (R) HLSL Shader Compiler 6.3.9600.16384
-//
-//
-//
-// Input signature:
-//
-// Name                 Index   Mask Register SysValue  Format   Used
-// -------------------- ----- ------ -------- -------- ------- ------
-// SV_VertexID              0   x           0   VERTID    uint   x   
-//
-//
-// Output signature:
-//
-// Name                 Index   Mask Register SysValue  Format   Used
-// -------------------- ----- ------ -------- -------- ------- ------
-// SV_POSITION              0   xyzw        0      POS   float   xyzw
-//
-vs_4_0
-dcl_immediateConstantBuffer { { -1.000000, 1.000000, 0, 0},
-                              { 1.000000, -1.000000, 0, 0},
-                              { -1.000000, -1.000000, 0, 0},
-                              { -1.000000, 1.000000, 0, 0},
-                              { 1.000000, 1.000000, 0, 0},
-                              { 1.000000, -1.000000, 0, 0} }
-dcl_input_sgv v0.x, vertex_id
-dcl_output_siv o0.xyzw, position
-dcl_temps 1
-mov r0.x, v0.x
-mov o0.xy, icb[r0.x + 0].xyxx
-mov o0.zw, l(0,0,0,1.000000)
-ret 
-// Approximately 4 instruction slots used
-#endif
-
-const BYTE g_VS_Clear[] =
-{
-     68,  88,  66,  67, 170,  97, 
-     47,  88, 112,  76, 249,  40, 
-    248, 151, 133,  76, 228, 131, 
-     60, 115,   1,   0,   0,   0, 
-     96,   2,   0,   0,   5,   0, 
-      0,   0,  52,   0,   0,   0, 
-    140,   0,   0,   0, 192,   0, 
-      0,   0, 244,   0,   0,   0, 
-    228,   1,   0,   0,  82,  68, 
-     69,  70,  80,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-     28,   0,   0,   0,   0,   4, 
-    254, 255,   0,   1,   0,   0, 
-     28,   0,   0,   0,  77, 105, 
-     99, 114, 111, 115, 111, 102, 
-    116,  32,  40,  82,  41,  32, 
-     72,  76,  83,  76,  32,  83, 
-    104,  97, 100, 101, 114,  32, 
-     67, 111, 109, 112, 105, 108, 
-    101, 114,  32,  54,  46,  51, 
-     46,  57,  54,  48,  48,  46, 
-     49,  54,  51,  56,  52,   0, 
-    171, 171,  73,  83,  71,  78, 
-     44,   0,   0,   0,   1,   0, 
-      0,   0,   8,   0,   0,   0, 
-     32,   0,   0,   0,   0,   0, 
-      0,   0,   6,   0,   0,   0, 
-      1,   0,   0,   0,   0,   0, 
-      0,   0,   1,   1,   0,   0, 
-     83,  86,  95,  86, 101, 114, 
-    116, 101, 120,  73,  68,   0, 
-     79,  83,  71,  78,  44,   0, 
-      0,   0,   1,   0,   0,   0, 
-      8,   0,   0,   0,  32,   0, 
-      0,   0,   0,   0,   0,   0, 
-      1,   0,   0,   0,   3,   0, 
-      0,   0,   0,   0,   0,   0, 
-     15,   0,   0,   0,  83,  86, 
-     95,  80,  79,  83,  73,  84, 
-     73,  79,  78,   0,  83,  72, 
-     68,  82, 232,   0,   0,   0, 
-     64,   0,   1,   0,  58,   0, 
-      0,   0,  53,  24,   0,   0, 
-     26,   0,   0,   0,   0,   0, 
-    128, 191,   0,   0, 128,  63, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0, 128,  63, 
-      0,   0, 128, 191,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0, 128, 191,   0,   0, 
-    128, 191,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-    128, 191,   0,   0, 128,  63, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0, 128,  63, 
-      0,   0, 128,  63,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0, 128,  63,   0,   0, 
-    128, 191,   0,   0,   0,   0, 
-      0,   0,   0,   0,  96,   0, 
-      0,   4,  18,  16,  16,   0, 
-      0,   0,   0,   0,   6,   0, 
-      0,   0, 103,   0,   0,   4, 
-    242,  32,  16,   0,   0,   0, 
-      0,   0,   1,   0,   0,   0, 
-    104,   0,   0,   2,   1,   0, 
-      0,   0,  54,   0,   0,   5, 
-     18,   0,  16,   0,   0,   0, 
-      0,   0,  10,  16,  16,   0, 
-      0,   0,   0,   0,  54,   0, 
-      0,   6,  50,  32,  16,   0, 
-      0,   0,   0,   0,  70, 144, 
-    144,   0,  10,   0,  16,   0, 
-      0,   0,   0,   0,  54,   0, 
-      0,   8, 194,  32,  16,   0, 
-      0,   0,   0,   0,   2,  64, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0, 128,  63, 
-     62,   0,   0,   1,  83,  84, 
-     65,  84, 116,   0,   0,   0, 
-      4,   0,   0,   0,   1,   0, 
-      0,   0,   6,   0,   0,   0, 
-      2,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   1,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   3,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0
-};
+#if 0
+//
+// Generated by Microsoft (R) HLSL Shader Compiler 6.3.9600.16384
+//
+//
+//
+// Input signature:
+//
+// Name                 Index   Mask Register SysValue  Format   Used
+// -------------------- ----- ------ -------- -------- ------- ------
+// SV_VertexID              0   x           0   VERTID    uint   x   
+//
+//
+// Output signature:
+//
+// Name                 Index   Mask Register SysValue  Format   Used
+// -------------------- ----- ------ -------- -------- ------- ------
+// SV_POSITION              0   xyzw        0      POS   float   xyzw
+//
+vs_4_0
+dcl_immediateConstantBuffer { { -1.000000, 1.000000, 0, 0},
+                              { 1.000000, -1.000000, 0, 0},
+                              { -1.000000, -1.000000, 0, 0},
+                              { -1.000000, 1.000000, 0, 0},
+                              { 1.000000, 1.000000, 0, 0},
+                              { 1.000000, -1.000000, 0, 0} }
+dcl_input_sgv v0.x, vertex_id
+dcl_output_siv o0.xyzw, position
+dcl_temps 1
+mov r0.x, v0.x
+mov o0.xy, icb[r0.x + 0].xyxx
+mov o0.zw, l(0,0,0,1.000000)
+ret 
+// Approximately 4 instruction slots used
+#endif
+
+const BYTE g_VS_Clear[] =
+{
+     68,  88,  66,  67, 170,  97, 
+     47,  88, 112,  76, 249,  40, 
+    248, 151, 133,  76, 228, 131, 
+     60, 115,   1,   0,   0,   0, 
+     96,   2,   0,   0,   5,   0, 
+      0,   0,  52,   0,   0,   0, 
+    140,   0,   0,   0, 192,   0, 
+      0,   0, 244,   0,   0,   0, 
+    228,   1,   0,   0,  82,  68, 
+     69,  70,  80,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+     28,   0,   0,   0,   0,   4, 
+    254, 255,   0,   1,   0,   0, 
+     28,   0,   0,   0,  77, 105, 
+     99, 114, 111, 115, 111, 102, 
+    116,  32,  40,  82,  41,  32, 
+     72,  76,  83,  76,  32,  83, 
+    104,  97, 100, 101, 114,  32, 
+     67, 111, 109, 112, 105, 108, 
+    101, 114,  32,  54,  46,  51, 
+     46,  57,  54,  48,  48,  46, 
+     49,  54,  51,  56,  52,   0, 
+    171, 171,  73,  83,  71,  78, 
+     44,   0,   0,   0,   1,   0, 
+      0,   0,   8,   0,   0,   0, 
+     32,   0,   0,   0,   0,   0, 
+      0,   0,   6,   0,   0,   0, 
+      1,   0,   0,   0,   0,   0, 
+      0,   0,   1,   1,   0,   0, 
+     83,  86,  95,  86, 101, 114, 
+    116, 101, 120,  73,  68,   0, 
+     79,  83,  71,  78,  44,   0, 
+      0,   0,   1,   0,   0,   0, 
+      8,   0,   0,   0,  32,   0, 
+      0,   0,   0,   0,   0,   0, 
+      1,   0,   0,   0,   3,   0, 
+      0,   0,   0,   0,   0,   0, 
+     15,   0,   0,   0,  83,  86, 
+     95,  80,  79,  83,  73,  84, 
+     73,  79,  78,   0,  83,  72, 
+     68,  82, 232,   0,   0,   0, 
+     64,   0,   1,   0,  58,   0, 
+      0,   0,  53,  24,   0,   0, 
+     26,   0,   0,   0,   0,   0, 
+    128, 191,   0,   0, 128,  63, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0, 128,  63, 
+      0,   0, 128, 191,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0, 128, 191,   0,   0, 
+    128, 191,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+    128, 191,   0,   0, 128,  63, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0, 128,  63, 
+      0,   0, 128,  63,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0, 128,  63,   0,   0, 
+    128, 191,   0,   0,   0,   0, 
+      0,   0,   0,   0,  96,   0, 
+      0,   4,  18,  16,  16,   0, 
+      0,   0,   0,   0,   6,   0, 
+      0,   0, 103,   0,   0,   4, 
+    242,  32,  16,   0,   0,   0, 
+      0,   0,   1,   0,   0,   0, 
+    104,   0,   0,   2,   1,   0, 
+      0,   0,  54,   0,   0,   5, 
+     18,   0,  16,   0,   0,   0, 
+      0,   0,  10,  16,  16,   0, 
+      0,   0,   0,   0,  54,   0, 
+      0,   6,  50,  32,  16,   0, 
+      0,   0,   0,   0,  70, 144, 
+    144,   0,  10,   0,  16,   0, 
+      0,   0,   0,   0,  54,   0, 
+      0,   8, 194,  32,  16,   0, 
+      0,   0,   0,   0,   2,  64, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0, 128,  63, 
+     62,   0,   0,   1,  83,  84, 
+     65,  84, 116,   0,   0,   0, 
+      4,   0,   0,   0,   1,   0, 
+      0,   0,   6,   0,   0,   0, 
+      2,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   1,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   3,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0
+};
--- a/gfx/angle/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/cleardepth11ps.h
+++ b/gfx/angle/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/cleardepth11ps.h
@@ -1,75 +1,75 @@
-#if 0
-//
-// Generated by Microsoft (R) HLSL Shader Compiler 6.3.9600.16384
-//
-//
-// Buffer Definitions: 
-//
-// cbuffer DepthOnlyData
-// {
-//
-//   float zValue_Depth;                // Offset:   16 Size:     4
-//
-// }
-//
-//
-// Resource Bindings:
-//
-// Name                                 Type  Format         Dim Slot Elements
-// ------------------------------ ---------- ------- ----------- ---- --------
-// DepthOnlyData                     cbuffer      NA          NA    0        1
-//
-//
-//
-// Input signature:
-//
-// Name                 Index   Mask Register SysValue  Format   Used
-// -------------------- ----- ------ -------- -------- ------- ------
-// SV_POSITION              0   xyzw        0      POS   float       
-//
-//
-// Output signature:
-//
-// Name                 Index   Mask Register SysValue  Format   Used
-// -------------------- ----- ------ -------- -------- ------- ------
-// SV_DEPTH                 0    N/A   oDepth    DEPTH   float    YES
-//
-ps_4_0
-dcl_constantbuffer cb0[2], immediateIndexed
-dcl_output oDepth
-mov oDepth, cb0[1].x
-ret 
-// Approximately 2 instruction slots used
-#endif
-
-const BYTE g_PS_ClearDepth[] = {
-    68,  88,  66,  67,  118, 105, 246, 232, 152, 45,  90,  172, 38,  100, 140, 153, 229, 217, 123,
-    120, 1,   0,   0,   0,   48,  2,   0,   0,   5,   0,   0,   0,   52,  0,   0,   0,   12,  1,
-    0,   0,   64,  1,   0,   0,   116, 1,   0,   0,   180, 1,   0,   0,   82,  68,  69,  70,  208,
-    0,   0,   0,   1,   0,   0,   0,   76,  0,   0,   0,   1,   0,   0,   0,   28,  0,   0,   0,
-    0,   4,   255, 255, 0,   1,   0,   0,   156, 0,   0,   0,   60,  0,   0,   0,   0,   0,   0,
-    0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   1,   0,
-    0,   0,   1,   0,   0,   0,   68,  101, 112, 116, 104, 79,  110, 108, 121, 68,  97,  116, 97,
-    0,   171, 171, 60,  0,   0,   0,   1,   0,   0,   0,   100, 0,   0,   0,   32,  0,   0,   0,
-    0,   0,   0,   0,   0,   0,   0,   0,   124, 0,   0,   0,   16,  0,   0,   0,   4,   0,   0,
-    0,   2,   0,   0,   0,   140, 0,   0,   0,   0,   0,   0,   0,   122, 86,  97,  108, 117, 101,
-    95,  68,  101, 112, 116, 104, 0,   171, 171, 171, 0,   0,   3,   0,   1,   0,   1,   0,   0,
-    0,   0,   0,   0,   0,   0,   0,   77,  105, 99,  114, 111, 115, 111, 102, 116, 32,  40,  82,
-    41,  32,  72,  76,  83,  76,  32,  83,  104, 97,  100, 101, 114, 32,  67,  111, 109, 112, 105,
-    108, 101, 114, 32,  54,  46,  51,  46,  57,  54,  48,  48,  46,  49,  54,  51,  56,  52,  0,
-    171, 171, 73,  83,  71,  78,  44,  0,   0,   0,   1,   0,   0,   0,   8,   0,   0,   0,   32,
-    0,   0,   0,   0,   0,   0,   0,   1,   0,   0,   0,   3,   0,   0,   0,   0,   0,   0,   0,
-    15,  0,   0,   0,   83,  86,  95,  80,  79,  83,  73,  84,  73,  79,  78,  0,   79,  83,  71,
-    78,  44,  0,   0,   0,   1,   0,   0,   0,   8,   0,   0,   0,   32,  0,   0,   0,   0,   0,
-    0,   0,   0,   0,   0,   0,   3,   0,   0,   0,   255, 255, 255, 255, 1,   14,  0,   0,   83,
-    86,  95,  68,  69,  80,  84,  72,  0,   171, 171, 171, 83,  72,  68,  82,  56,  0,   0,   0,
-    64,  0,   0,   0,   14,  0,   0,   0,   89,  0,   0,   4,   70,  142, 32,  0,   0,   0,   0,
-    0,   2,   0,   0,   0,   101, 0,   0,   2,   1,   192, 0,   0,   54,  0,   0,   5,   1,   192,
-    0,   0,   10,  128, 32,  0,   0,   0,   0,   0,   1,   0,   0,   0,   62,  0,   0,   1,   83,
-    84,  65,  84,  116, 0,   0,   0,   2,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
-    1,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   1,   0,   0,
-    0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
-    0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
-    0,   0,   0,   0,   0,   0,   0,   1,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
-    0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
-    0,   0,   0,   0,   0,   0,   0,   0,   0};
+#if 0
+//
+// Generated by Microsoft (R) HLSL Shader Compiler 6.3.9600.16384
+//
+//
+// Buffer Definitions: 
+//
+// cbuffer DepthOnlyData
+// {
+//
+//   float zValue_Depth;                // Offset:   16 Size:     4
+//
+// }
+//
+//
+// Resource Bindings:
+//
+// Name                                 Type  Format         Dim Slot Elements
+// ------------------------------ ---------- ------- ----------- ---- --------
+// DepthOnlyData                     cbuffer      NA          NA    0        1
+//
+//
+//
+// Input signature:
+//
+// Name                 Index   Mask Register SysValue  Format   Used
+// -------------------- ----- ------ -------- -------- ------- ------
+// SV_POSITION              0   xyzw        0      POS   float       
+//
+//
+// Output signature:
+//
+// Name                 Index   Mask Register SysValue  Format   Used
+// -------------------- ----- ------ -------- -------- ------- ------
+// SV_DEPTH                 0    N/A   oDepth    DEPTH   float    YES
+//
+ps_4_0
+dcl_constantbuffer cb0[2], immediateIndexed
+dcl_output oDepth
+mov oDepth, cb0[1].x
+ret 
+// Approximately 2 instruction slots used
+#endif
+
+const BYTE g_PS_ClearDepth[] = {
+    68,  88,  66,  67,  118, 105, 246, 232, 152, 45,  90,  172, 38,  100, 140, 153, 229, 217, 123,
+    120, 1,   0,   0,   0,   48,  2,   0,   0,   5,   0,   0,   0,   52,  0,   0,   0,   12,  1,
+    0,   0,   64,  1,   0,   0,   116, 1,   0,   0,   180, 1,   0,   0,   82,  68,  69,  70,  208,
+    0,   0,   0,   1,   0,   0,   0,   76,  0,   0,   0,   1,   0,   0,   0,   28,  0,   0,   0,
+    0,   4,   255, 255, 0,   1,   0,   0,   156, 0,   0,   0,   60,  0,   0,   0,   0,   0,   0,
+    0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   1,   0,
+    0,   0,   1,   0,   0,   0,   68,  101, 112, 116, 104, 79,  110, 108, 121, 68,  97,  116, 97,
+    0,   171, 171, 60,  0,   0,   0,   1,   0,   0,   0,   100, 0,   0,   0,   32,  0,   0,   0,
+    0,   0,   0,   0,   0,   0,   0,   0,   124, 0,   0,   0,   16,  0,   0,   0,   4,   0,   0,
+    0,   2,   0,   0,   0,   140, 0,   0,   0,   0,   0,   0,   0,   122, 86,  97,  108, 117, 101,
+    95,  68,  101, 112, 116, 104, 0,   171, 171, 171, 0,   0,   3,   0,   1,   0,   1,   0,   0,
+    0,   0,   0,   0,   0,   0,   0,   77,  105, 99,  114, 111, 115, 111, 102, 116, 32,  40,  82,
+    41,  32,  72,  76,  83,  76,  32,  83,  104, 97,  100, 101, 114, 32,  67,  111, 109, 112, 105,
+    108, 101, 114, 32,  54,  46,  51,  46,  57,  54,  48,  48,  46,  49,  54,  51,  56,  52,  0,
+    171, 171, 73,  83,  71,  78,  44,  0,   0,   0,   1,   0,   0,   0,   8,   0,   0,   0,   32,
+    0,   0,   0,   0,   0,   0,   0,   1,   0,   0,   0,   3,   0,   0,   0,   0,   0,   0,   0,
+    15,  0,   0,   0,   83,  86,  95,  80,  79,  83,  73,  84,  73,  79,  78,  0,   79,  83,  71,
+    78,  44,  0,   0,   0,   1,   0,   0,   0,   8,   0,   0,   0,   32,  0,   0,   0,   0,   0,
+    0,   0,   0,   0,   0,   0,   3,   0,   0,   0,   255, 255, 255, 255, 1,   14,  0,   0,   83,
+    86,  95,  68,  69,  80,  84,  72,  0,   171, 171, 171, 83,  72,  68,  82,  56,  0,   0,   0,
+    64,  0,   0,   0,   14,  0,   0,   0,   89,  0,   0,   4,   70,  142, 32,  0,   0,   0,   0,
+    0,   2,   0,   0,   0,   101, 0,   0,   2,   1,   192, 0,   0,   54,  0,   0,   5,   1,   192,
+    0,   0,   10,  128, 32,  0,   0,   0,   0,   0,   1,   0,   0,   0,   62,  0,   0,   1,   83,
+    84,  65,  84,  116, 0,   0,   0,   2,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+    1,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   1,   0,   0,
+    0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+    0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+    0,   0,   0,   0,   0,   0,   0,   1,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+    0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+    0,   0,   0,   0,   0,   0,   0,   0,   0};
--- a/gfx/angle/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/clearfloat11_fl9ps.h
+++ b/gfx/angle/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/clearfloat11_fl9ps.h
@@ -1,244 +1,244 @@
-#if 0
-//
-// Generated by Microsoft (R) HLSL Shader Compiler 6.3.9600.16384
-//
-//
-// Buffer Definitions: 
-//
-// cbuffer ColorAndDepthDataFloat
-// {
-//
-//   float4 color_Float;                // Offset:    0 Size:    16
-//   float zValueF_Float;               // Offset:   16 Size:     4
-//
-// }
-//
-//
-// Resource Bindings:
-//
-// Name                                 Type  Format         Dim Slot Elements
-// ------------------------------ ---------- ------- ----------- ---- --------
-// ColorAndDepthDataFloat            cbuffer      NA          NA    0        1
-//
-//
-//
-// Input signature:
-//
-// Name                 Index   Mask Register SysValue  Format   Used
-// -------------------- ----- ------ -------- -------- ------- ------
-// SV_POSITION              0   xyzw        0      POS   float       
-//
-//
-// Output signature:
-//
-// Name                 Index   Mask Register SysValue  Format   Used
-// -------------------- ----- ------ -------- -------- ------- ------
-// SV_TARGET                0   xyzw        0   TARGET   float   xyzw
-// SV_TARGET                1   xyzw        1   TARGET   float   xyzw
-// SV_TARGET                2   xyzw        2   TARGET   float   xyzw
-// SV_TARGET                3   xyzw        3   TARGET   float   xyzw
-// SV_DEPTH                 0    N/A   oDepth    DEPTH   float    YES
-//
-//
-// Constant buffer to DX9 shader constant mappings:
-//
-// Target Reg Buffer  Start Reg # of Regs        Data Conversion
-// ---------- ------- --------- --------- ----------------------
-// c0         cb0             0         2  ( FLT, FLT, FLT, FLT)
-//
-//
-// Level9 shader bytecode:
-//
-    ps_2_x
-    mov oC0, c0
-    mov oC1, c0
-    mov oC2, c0
-    mov oC3, c0
-    mov oDepth, c1.x
-
-// approximately 5 instruction slots used
-ps_4_0
-dcl_constantbuffer cb0[2], immediateIndexed
-dcl_output o0.xyzw
-dcl_output o1.xyzw
-dcl_output o2.xyzw
-dcl_output o3.xyzw
-dcl_output oDepth
-mov o0.xyzw, cb0[0].xyzw
-mov o1.xyzw, cb0[0].xyzw
-mov o2.xyzw, cb0[0].xyzw
-mov o3.xyzw, cb0[0].xyzw
-mov oDepth, cb0[1].x
-ret 
-// Approximately 6 instruction slots used
-#endif
-
-const BYTE g_PS_ClearFloat_FL9[] =
-{
-     68,  88,  66,  67,  50, 112, 
-    200, 244,  43, 179,  42,  60, 
-      1,  54, 148, 142, 159,  31, 
-    160, 168,   1,   0,   0,   0, 
-    228,   3,   0,   0,   6,   0, 
-      0,   0,  56,   0,   0,   0, 
-    180,   0,   0,   0, 132,   1, 
-      0,   0,   0,   2,   0,   0, 
-     20,   3,   0,   0,  72,   3, 
-      0,   0,  65, 111, 110,  57, 
-    116,   0,   0,   0, 116,   0, 
-      0,   0,   0,   2, 255, 255, 
-     68,   0,   0,   0,  48,   0, 
-      0,   0,   1,   0,  36,   0, 
-      0,   0,  48,   0,   0,   0, 
-     48,   0,   0,   0,  36,   0, 
-      0,   0,  48,   0,   0,   0, 
-      0,   0,   2,   0,   0,   0, 
-      0,   0,   0,   0,   1,   2, 
-    255, 255,   1,   0,   0,   2, 
-      0,   8,  15, 128,   0,   0, 
-    228, 160,   1,   0,   0,   2, 
-      1,   8,  15, 128,   0,   0, 
-    228, 160,   1,   0,   0,   2, 
-      2,   8,  15, 128,   0,   0, 
-    228, 160,   1,   0,   0,   2, 
-      3,   8,  15, 128,   0,   0, 
-    228, 160,   1,   0,   0,   2, 
-      0,   8,  15, 144,   1,   0, 
-      0, 160, 255, 255,   0,   0, 
-     83,  72,  68,  82, 200,   0, 
-      0,   0,  64,   0,   0,   0, 
-     50,   0,   0,   0,  89,   0, 
-      0,   4,  70, 142,  32,   0, 
-      0,   0,   0,   0,   2,   0, 
-      0,   0, 101,   0,   0,   3, 
-    242,  32,  16,   0,   0,   0, 
-      0,   0, 101,   0,   0,   3, 
-    242,  32,  16,   0,   1,   0, 
-      0,   0, 101,   0,   0,   3, 
-    242,  32,  16,   0,   2,   0, 
-      0,   0, 101,   0,   0,   3, 
-    242,  32,  16,   0,   3,   0, 
-      0,   0, 101,   0,   0,   2, 
-      1, 192,   0,   0,  54,   0, 
-      0,   6, 242,  32,  16,   0, 
-      0,   0,   0,   0,  70, 142, 
-     32,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,  54,   0, 
-      0,   6, 242,  32,  16,   0, 
-      1,   0,   0,   0,  70, 142, 
-     32,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,  54,   0, 
-      0,   6, 242,  32,  16,   0, 
-      2,   0,   0,   0,  70, 142, 
-     32,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,  54,   0, 
-      0,   6, 242,  32,  16,   0, 
-      3,   0,   0,   0,  70, 142, 
-     32,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,  54,   0, 
-      0,   5,   1, 192,   0,   0, 
-     10, 128,  32,   0,   0,   0, 
-      0,   0,   1,   0,   0,   0, 
-     62,   0,   0,   1,  83,  84, 
-     65,  84, 116,   0,   0,   0, 
-      6,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      5,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   1,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   5,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,  82,  68,  69,  70, 
-     12,   1,   0,   0,   1,   0, 
-      0,   0,  84,   0,   0,   0, 
-      1,   0,   0,   0,  28,   0, 
-      0,   0,   0,   4, 255, 255, 
-      0,   1,   0,   0, 216,   0, 
-      0,   0,  60,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   1,   0,   0,   0, 
-      1,   0,   0,   0,  67, 111, 
-    108, 111, 114,  65, 110, 100, 
-     68, 101, 112, 116, 104,  68, 
-     97, 116,  97,  70, 108, 111, 
-     97, 116,   0, 171,  60,   0, 
-      0,   0,   2,   0,   0,   0, 
-    108,   0,   0,   0,  32,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0, 156,   0, 
-      0,   0,   0,   0,   0,   0, 
-     16,   0,   0,   0,   2,   0, 
-      0,   0, 168,   0,   0,   0, 
-      0,   0,   0,   0, 184,   0, 
-      0,   0,  16,   0,   0,   0, 
-      4,   0,   0,   0,   2,   0, 
-      0,   0, 200,   0,   0,   0, 
-      0,   0,   0,   0,  99, 111, 
-    108, 111, 114,  95,  70, 108, 
-    111,  97, 116,   0,   1,   0, 
-      3,   0,   1,   0,   4,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0, 122,  86,  97, 108, 
-    117, 101,  70,  95,  70, 108, 
-    111,  97, 116,   0, 171, 171, 
-      0,   0,   3,   0,   1,   0, 
-      1,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,  77, 105, 
-     99, 114, 111, 115, 111, 102, 
-    116,  32,  40,  82,  41,  32, 
-     72,  76,  83,  76,  32,  83, 
-    104,  97, 100, 101, 114,  32, 
-     67, 111, 109, 112, 105, 108, 
-    101, 114,  32,  54,  46,  51, 
-     46,  57,  54,  48,  48,  46, 
-     49,  54,  51,  56,  52,   0, 
-    171, 171,  73,  83,  71,  78, 
-     44,   0,   0,   0,   1,   0, 
-      0,   0,   8,   0,   0,   0, 
-     32,   0,   0,   0,   0,   0, 
-      0,   0,   1,   0,   0,   0, 
-      3,   0,   0,   0,   0,   0, 
-      0,   0,  15,   0,   0,   0, 
-     83,  86,  95,  80,  79,  83, 
-     73,  84,  73,  79,  78,   0, 
-     79,  83,  71,  78, 148,   0, 
-      0,   0,   5,   0,   0,   0, 
-      8,   0,   0,   0, 128,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   3,   0, 
-      0,   0,   0,   0,   0,   0, 
-     15,   0,   0,   0, 128,   0, 
-      0,   0,   1,   0,   0,   0, 
-      0,   0,   0,   0,   3,   0, 
-      0,   0,   1,   0,   0,   0, 
-     15,   0,   0,   0, 128,   0, 
-      0,   0,   2,   0,   0,   0, 
-      0,   0,   0,   0,   3,   0, 
-      0,   0,   2,   0,   0,   0, 
-     15,   0,   0,   0, 128,   0, 
-      0,   0,   3,   0,   0,   0, 
-      0,   0,   0,   0,   3,   0, 
-      0,   0,   3,   0,   0,   0, 
-     15,   0,   0,   0, 138,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   3,   0, 
-      0,   0, 255, 255, 255, 255, 
-      1,  14,   0,   0,  83,  86, 
-     95,  84,  65,  82,  71,  69, 
-     84,   0,  83,  86,  95,  68, 
-     69,  80,  84,  72,   0, 171
-};
+#if 0
+//
+// Generated by Microsoft (R) HLSL Shader Compiler 6.3.9600.16384
+//
+//
+// Buffer Definitions: 
+//
+// cbuffer ColorAndDepthDataFloat
+// {
+//
+//   float4 color_Float;                // Offset:    0 Size:    16
+//   float zValueF_Float;               // Offset:   16 Size:     4
+//
+// }
+//
+//
+// Resource Bindings:
+//
+// Name                                 Type  Format         Dim Slot Elements
+// ------------------------------ ---------- ------- ----------- ---- --------
+// ColorAndDepthDataFloat            cbuffer      NA          NA    0        1
+//
+//
+//
+// Input signature:
+//
+// Name                 Index   Mask Register SysValue  Format   Used
+// -------------------- ----- ------ -------- -------- ------- ------
+// SV_POSITION              0   xyzw        0      POS   float       
+//
+//
+// Output signature:
+//
+// Name                 Index   Mask Register SysValue  Format   Used
+// -------------------- ----- ------ -------- -------- ------- ------
+// SV_TARGET                0   xyzw        0   TARGET   float   xyzw
+// SV_TARGET                1   xyzw        1   TARGET   float   xyzw
+// SV_TARGET                2   xyzw        2   TARGET   float   xyzw
+// SV_TARGET                3   xyzw        3   TARGET   float   xyzw
+// SV_DEPTH                 0    N/A   oDepth    DEPTH   float    YES
+//
+//
+// Constant buffer to DX9 shader constant mappings:
+//
+// Target Reg Buffer  Start Reg # of Regs        Data Conversion
+// ---------- ------- --------- --------- ----------------------
+// c0         cb0             0         2  ( FLT, FLT, FLT, FLT)
+//
+//
+// Level9 shader bytecode:
+//
+    ps_2_x
+    mov oC0, c0
+    mov oC1, c0
+    mov oC2, c0
+    mov oC3, c0
+    mov oDepth, c1.x
+
+// approximately 5 instruction slots used
+ps_4_0
+dcl_constantbuffer cb0[2], immediateIndexed
+dcl_output o0.xyzw
+dcl_output o1.xyzw
+dcl_output o2.xyzw
+dcl_output o3.xyzw
+dcl_output oDepth
+mov o0.xyzw, cb0[0].xyzw
+mov o1.xyzw, cb0[0].xyzw
+mov o2.xyzw, cb0[0].xyzw
+mov o3.xyzw, cb0[0].xyzw
+mov oDepth, cb0[1].x
+ret 
+// Approximately 6 instruction slots used
+#endif
+
+const BYTE g_PS_ClearFloat_FL9[] =
+{
+     68,  88,  66,  67,  50, 112, 
+    200, 244,  43, 179,  42,  60, 
+      1,  54, 148, 142, 159,  31, 
+    160, 168,   1,   0,   0,   0, 
+    228,   3,   0,   0,   6,   0, 
+      0,   0,  56,   0,   0,   0, 
+    180,   0,   0,   0, 132,   1, 
+      0,   0,   0,   2,   0,   0, 
+     20,   3,   0,   0,  72,   3, 
+      0,   0,  65, 111, 110,  57, 
+    116,   0,   0,   0, 116,   0, 
+      0,   0,   0,   2, 255, 255, 
+     68,   0,   0,   0,  48,   0, 
+      0,   0,   1,   0,  36,   0, 
+      0,   0,  48,   0,   0,   0, 
+     48,   0,   0,   0,  36,   0, 
+      0,   0,  48,   0,   0,   0, 
+      0,   0,   2,   0,   0,   0, 
+      0,   0,   0,   0,   1,   2, 
+    255, 255,   1,   0,   0,   2, 
+      0,   8,  15, 128,   0,   0, 
+    228, 160,   1,   0,   0,   2, 
+      1,   8,  15, 128,   0,   0, 
+    228, 160,   1,   0,   0,   2, 
+      2,   8,  15, 128,   0,   0, 
+    228, 160,   1,   0,   0,   2, 
+      3,   8,  15, 128,   0,   0, 
+    228, 160,   1,   0,   0,   2, 
+      0,   8,  15, 144,   1,   0, 
+      0, 160, 255, 255,   0,   0, 
+     83,  72,  68,  82, 200,   0, 
+      0,   0,  64,   0,   0,   0, 
+     50,   0,   0,   0,  89,   0, 
+      0,   4,  70, 142,  32,   0, 
+      0,   0,   0,   0,   2,   0, 
+      0,   0, 101,   0,   0,   3, 
+    242,  32,  16,   0,   0,   0, 
+      0,   0, 101,   0,   0,   3, 
+    242,  32,  16,   0,   1,   0, 
+      0,   0, 101,   0,   0,   3, 
+    242,  32,  16,   0,   2,   0, 
+      0,   0, 101,   0,   0,   3, 
+    242,  32,  16,   0,   3,   0, 
+      0,   0, 101,   0,   0,   2, 
+      1, 192,   0,   0,  54,   0, 
+      0,   6, 242,  32,  16,   0, 
+      0,   0,   0,   0,  70, 142, 
+     32,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,  54,   0, 
+      0,   6, 242,  32,  16,   0, 
+      1,   0,   0,   0,  70, 142, 
+     32,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,  54,   0, 
+      0,   6, 242,  32,  16,   0, 
+      2,   0,   0,   0,  70, 142, 
+     32,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,  54,   0, 
+      0,   6, 242,  32,  16,   0, 
+      3,   0,   0,   0,  70, 142, 
+     32,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,  54,   0, 
+      0,   5,   1, 192,   0,   0, 
+     10, 128,  32,   0,   0,   0, 
+      0,   0,   1,   0,   0,   0, 
+     62,   0,   0,   1,  83,  84, 
+     65,  84, 116,   0,   0,   0, 
+      6,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      5,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   1,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   5,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,  82,  68,  69,  70, 
+     12,   1,   0,   0,   1,   0, 
+      0,   0,  84,   0,   0,   0, 
+      1,   0,   0,   0,  28,   0, 
+      0,   0,   0,   4, 255, 255, 
+      0,   1,   0,   0, 216,   0, 
+      0,   0,  60,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   1,   0,   0,   0, 
+      1,   0,   0,   0,  67, 111, 
+    108, 111, 114,  65, 110, 100, 
+     68, 101, 112, 116, 104,  68, 
+     97, 116,  97,  70, 108, 111, 
+     97, 116,   0, 171,  60,   0, 
+      0,   0,   2,   0,   0,   0, 
+    108,   0,   0,   0,  32,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0, 156,   0, 
+      0,   0,   0,   0,   0,   0, 
+     16,   0,   0,   0,   2,   0, 
+      0,   0, 168,   0,   0,   0, 
+      0,   0,   0,   0, 184,   0, 
+      0,   0,  16,   0,   0,   0, 
+      4,   0,   0,   0,   2,   0, 
+      0,   0, 200,   0,   0,   0, 
+      0,   0,   0,   0,  99, 111, 
+    108, 111, 114,  95,  70, 108, 
+    111,  97, 116,   0,   1,   0, 
+      3,   0,   1,   0,   4,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0, 122,  86,  97, 108, 
+    117, 101,  70,  95,  70, 108, 
+    111,  97, 116,   0, 171, 171, 
+      0,   0,   3,   0,   1,   0, 
+      1,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,  77, 105, 
+     99, 114, 111, 115, 111, 102, 
+    116,  32,  40,  82,  41,  32, 
+     72,  76,  83,  76,  32,  83, 
+    104,  97, 100, 101, 114,  32, 
+     67, 111, 109, 112, 105, 108, 
+    101, 114,  32,  54,  46,  51, 
+     46,  57,  54,  48,  48,  46, 
+     49,  54,  51,  56,  52,   0, 
+    171, 171,  73,  83,  71,  78, 
+     44,   0,   0,   0,   1,   0, 
+      0,   0,   8,   0,   0,   0, 
+     32,   0,   0,   0,   0,   0, 
+      0,   0,   1,   0,   0,   0, 
+      3,   0,   0,   0,   0,   0, 
+      0,   0,  15,   0,   0,   0, 
+     83,  86,  95,  80,  79,  83, 
+     73,  84,  73,  79,  78,   0, 
+     79,  83,  71,  78, 148,   0, 
+      0,   0,   5,   0,   0,   0, 
+      8,   0,   0,   0, 128,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   3,   0, 
+      0,   0,   0,   0,   0,   0, 
+     15,   0,   0,   0, 128,   0, 
+      0,   0,   1,   0,   0,   0, 
+      0,   0,   0,   0,   3,   0, 
+      0,   0,   1,   0,   0,   0, 
+     15,   0,   0,   0, 128,   0, 
+      0,   0,   2,   0,   0,   0, 
+      0,   0,   0,   0,   3,   0, 
+      0,   0,   2,   0,   0,   0, 
+     15,   0,   0,   0, 128,   0, 
+      0,   0,   3,   0,   0,   0, 
+      0,   0,   0,   0,   3,   0, 
+      0,   0,   3,   0,   0,   0, 
+     15,   0,   0,   0, 138,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   3,   0, 
+      0,   0, 255, 255, 255, 255, 
+      1,  14,   0,   0,  83,  86, 
+     95,  84,  65,  82,  71,  69, 
+     84,   0,  83,  86,  95,  68, 
+     69,  80,  84,  72,   0, 171
+};
--- a/gfx/angle/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/clearfloat11ps1.h
+++ b/gfx/angle/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/clearfloat11ps1.h
@@ -1,86 +1,86 @@
-#if 0
-//
-// Generated by Microsoft (R) HLSL Shader Compiler 6.3.9600.16384
-//
-//
-// Buffer Definitions: 
-//
-// cbuffer ColorAndDepthDataFloat
-// {
-//
-//   float4 color_Float;                // Offset:    0 Size:    16
-//   float zValueF_Float;               // Offset:   16 Size:     4
-//
-// }
-//
-//
-// Resource Bindings:
-//
-// Name                                 Type  Format         Dim Slot Elements
-// ------------------------------ ---------- ------- ----------- ---- --------
-// ColorAndDepthDataFloat            cbuffer      NA          NA    0        1
-//
-//
-//
-// Input signature:
-//
-// Name                 Index   Mask Register SysValue  Format   Used
-// -------------------- ----- ------ -------- -------- ------- ------
-// SV_POSITION              0   xyzw        0      POS   float       
-//
-//
-// Output signature:
-//
-// Name                 Index   Mask Register SysValue  Format   Used
-// -------------------- ----- ------ -------- -------- ------- ------
-// SV_TARGET                0   xyzw        0   TARGET   float   xyzw
-// SV_DEPTH                 0    N/A   oDepth    DEPTH   float    YES
-//
-ps_4_0
-dcl_constantbuffer cb0[2], immediateIndexed
-dcl_output o0.xyzw
-dcl_output oDepth
-mov o0.xyzw, cb0[0].xyzw
-mov oDepth, cb0[1].x
-ret 
-// Approximately 3 instruction slots used
-#endif
-
-const BYTE g_PS_ClearFloat1[] = {
-    68,  88,  66,  67,  193, 98,  147, 208, 43,  53,  161, 136, 243, 53,  114, 47,  211, 102, 138,
-    40,  1,   0,   0,   0,   176, 2,   0,   0,   5,   0,   0,   0,   52,  0,   0,   0,   72,  1,
-    0,   0,   124, 1,   0,   0,   208, 1,   0,   0,   52,  2,   0,   0,   82,  68,  69,  70,  12,
-    1,   0,   0,   1,   0,   0,   0,   84,  0,   0,   0,   1,   0,   0,   0,   28,  0,   0,   0,
-    0,   4,   255, 255, 0,   1,   0,   0,   216, 0,   0,   0,   60,  0,   0,   0,   0,   0,   0,
-    0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   1,   0,
-    0,   0,   1,   0,   0,   0,   67,  111, 108, 111, 114, 65,  110, 100, 68,  101, 112, 116, 104,
-    68,  97,  116, 97,  70,  108, 111, 97,  116, 0,   171, 60,  0,   0,   0,   2,   0,   0,   0,
-    108, 0,   0,   0,   32,  0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   156, 0,   0,
-    0,   0,   0,   0,   0,   16,  0,   0,   0,   2,   0,   0,   0,   168, 0,   0,   0,   0,   0,
-    0,   0,   184, 0,   0,   0,   16,  0,   0,   0,   4,   0,   0,   0,   2,   0,   0,   0,   200,
-    0,   0,   0,   0,   0,   0,   0,   99,  111, 108, 111, 114, 95,  70,  108, 111, 97,  116, 0,
-    1,   0,   3,   0,   1,   0,   4,   0,   0,   0,   0,   0,   0,   0,   0,   0,   122, 86,  97,
-    108, 117, 101, 70,  95,  70,  108, 111, 97,  116, 0,   171, 171, 0,   0,   3,   0,   1,   0,
-    1,   0,   0,   0,   0,   0,   0,   0,   0,   0,   77,  105, 99,  114, 111, 115, 111, 102, 116,
-    32,  40,  82,  41,  32,  72,  76,  83,  76,  32,  83,  104, 97,  100, 101, 114, 32,  67,  111,
-    109, 112, 105, 108, 101, 114, 32,  54,  46,  51,  46,  57,  54,  48,  48,  46,  49,  54,  51,
-    56,  52,  0,   171, 171, 73,  83,  71,  78,  44,  0,   0,   0,   1,   0,   0,   0,   8,   0,
-    0,   0,   32,  0,   0,   0,   0,   0,   0,   0,   1,   0,   0,   0,   3,   0,   0,   0,   0,
-    0,   0,   0,   15,  0,   0,   0,   83,  86,  95,  80,  79,  83,  73,  84,  73,  79,  78,  0,
-    79,  83,  71,  78,  76,  0,   0,   0,   2,   0,   0,   0,   8,   0,   0,   0,   56,  0,   0,
-    0,   0,   0,   0,   0,   0,   0,   0,   0,   3,   0,   0,   0,   0,   0,   0,   0,   15,  0,
-    0,   0,   66,  0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   3,   0,   0,   0,   255,
-    255, 255, 255, 1,   14,  0,   0,   83,  86,  95,  84,  65,  82,  71,  69,  84,  0,   83,  86,
-    95,  68,  69,  80,  84,  72,  0,   171, 83,  72,  68,  82,  92,  0,   0,   0,   64,  0,   0,
-    0,   23,  0,   0,   0,   89,  0,   0,   4,   70,  142, 32,  0,   0,   0,   0,   0,   2,   0,
-    0,   0,   101, 0,   0,   3,   242, 32,  16,  0,   0,   0,   0,   0,   101, 0,   0,   2,   1,
-    192, 0,   0,   54,  0,   0,   6,   242, 32,  16,  0,   0,   0,   0,   0,   70,  142, 32,  0,
-    0,   0,   0,   0,   0,   0,   0,   0,   54,  0,   0,   5,   1,   192, 0,   0,   10,  128, 32,
-    0,   0,   0,   0,   0,   1,   0,   0,   0,   62,  0,   0,   1,   83,  84,  65,  84,  116, 0,
-    0,   0,   3,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   2,   0,   0,   0,   0,
-    0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   1,   0,   0,   0,   0,   0,   0,   0,
-    0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
-    0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
-    0,   0,   2,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
-    0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
-    0,   0,   0,   0};
+#if 0
+//
+// Generated by Microsoft (R) HLSL Shader Compiler 6.3.9600.16384
+//
+//
+// Buffer Definitions: 
+//
+// cbuffer ColorAndDepthDataFloat
+// {
+//
+//   float4 color_Float;                // Offset:    0 Size:    16
+//   float zValueF_Float;               // Offset:   16 Size:     4
+//
+// }
+//
+//
+// Resource Bindings:
+//
+// Name                                 Type  Format         Dim Slot Elements
+// ------------------------------ ---------- ------- ----------- ---- --------
+// ColorAndDepthDataFloat            cbuffer      NA          NA    0        1
+//
+//
+//
+// Input signature:
+//
+// Name                 Index   Mask Register SysValue  Format   Used
+// -------------------- ----- ------ -------- -------- ------- ------
+// SV_POSITION              0   xyzw        0      POS   float       
+//
+//
+// Output signature:
+//
+// Name                 Index   Mask Register SysValue  Format   Used
+// -------------------- ----- ------ -------- -------- ------- ------
+// SV_TARGET                0   xyzw        0   TARGET   float   xyzw
+// SV_DEPTH                 0    N/A   oDepth    DEPTH   float    YES
+//
+ps_4_0
+dcl_constantbuffer cb0[2], immediateIndexed
+dcl_output o0.xyzw
+dcl_output oDepth
+mov o0.xyzw, cb0[0].xyzw
+mov oDepth, cb0[1].x
+ret 
+// Approximately 3 instruction slots used
+#endif
+
+const BYTE g_PS_ClearFloat1[] = {
+    68,  88,  66,  67,  193, 98,  147, 208, 43,  53,  161, 136, 243, 53,  114, 47,  211, 102, 138,
+    40,  1,   0,   0,   0,   176, 2,   0,   0,   5,   0,   0,   0,   52,  0,   0,   0,   72,  1,
+    0,   0,   124, 1,   0,   0,   208, 1,   0,   0,   52,  2,   0,   0,   82,  68,  69,  70,  12,
+    1,   0,   0,   1,   0,   0,   0,   84,  0,   0,   0,   1,   0,   0,   0,   28,  0,   0,   0,
+    0,   4,   255, 255, 0,   1,   0,   0,   216, 0,   0,   0,   60,  0,   0,   0,   0,   0,   0,
+    0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   1,   0,
+    0,   0,   1,   0,   0,   0,   67,  111, 108, 111, 114, 65,  110, 100, 68,  101, 112, 116, 104,
+    68,  97,  116, 97,  70,  108, 111, 97,  116, 0,   171, 60,  0,   0,   0,   2,   0,   0,   0,
+    108, 0,   0,   0,   32,  0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   156, 0,   0,
+    0,   0,   0,   0,   0,   16,  0,   0,   0,   2,   0,   0,   0,   168, 0,   0,   0,   0,   0,
+    0,   0,   184, 0,   0,   0,   16,  0,   0,   0,   4,   0,   0,   0,   2,   0,   0,   0,   200,
+    0,   0,   0,   0,   0,   0,   0,   99,  111, 108, 111, 114, 95,  70,  108, 111, 97,  116, 0,
+    1,   0,   3,   0,   1,   0,   4,   0,   0,   0,   0,   0,   0,   0,   0,   0,   122, 86,  97,
+    108, 117, 101, 70,  95,  70,  108, 111, 97,  116, 0,   171, 171, 0,   0,   3,   0,   1,   0,
+    1,   0,   0,   0,   0,   0,   0,   0,   0,   0,   77,  105, 99,  114, 111, 115, 111, 102, 116,
+    32,  40,  82,  41,  32,  72,  76,  83,  76,  32,  83,  104, 97,  100, 101, 114, 32,  67,  111,
+    109, 112, 105, 108, 101, 114, 32,  54,  46,  51,  46,  57,  54,  48,  48,  46,  49,  54,  51,
+    56,  52,  0,   171, 171, 73,  83,  71,  78,  44,  0,   0,   0,   1,   0,   0,   0,   8,   0,
+    0,   0,   32,  0,   0,   0,   0,   0,   0,   0,   1,   0,   0,   0,   3,   0,   0,   0,   0,
+    0,   0,   0,   15,  0,   0,   0,   83,  86,  95,  80,  79,  83,  73,  84,  73,  79,  78,  0,
+    79,  83,  71,  78,  76,  0,   0,   0,   2,   0,   0,   0,   8,   0,   0,   0,   56,  0,   0,
+    0,   0,   0,   0,   0,   0,   0,   0,   0,   3,   0,   0,   0,   0,   0,   0,   0,   15,  0,
+    0,   0,   66,  0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   3,   0,   0,   0,   255,
+    255, 255, 255, 1,   14,  0,   0,   83,  86,  95,  84,  65,  82,  71,  69,  84,  0,   83,  86,
+    95,  68,  69,  80,  84,  72,  0,   171, 83,  72,  68,  82,  92,  0,   0,   0,   64,  0,   0,
+    0,   23,  0,   0,   0,   89,  0,   0,   4,   70,  142, 32,  0,   0,   0,   0,   0,   2,   0,
+    0,   0,   101, 0,   0,   3,   242, 32,  16,  0,   0,   0,   0,   0,   101, 0,   0,   2,   1,
+    192, 0,   0,   54,  0,   0,   6,   242, 32,  16,  0,   0,   0,   0,   0,   70,  142, 32,  0,
+    0,   0,   0,   0,   0,   0,   0,   0,   54,  0,   0,   5,   1,   192, 0,   0,   10,  128, 32,
+    0,   0,   0,   0,   0,   1,   0,   0,   0,   62,  0,   0,   1,   83,  84,  65,  84,  116, 0,
+    0,   0,   3,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   2,   0,   0,   0,   0,
+    0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   1,   0,   0,   0,   0,   0,   0,   0,
+    0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+    0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+    0,   0,   2,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+    0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+    0,   0,   0,   0};
--- a/gfx/angle/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/clearfloat11ps2.h
+++ b/gfx/angle/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/clearfloat11ps2.h
@@ -1,92 +1,92 @@
-#if 0
-//
-// Generated by Microsoft (R) HLSL Shader Compiler 6.3.9600.16384
-//
-//
-// Buffer Definitions: 
-//
-// cbuffer ColorAndDepthDataFloat
-// {
-//
-//   float4 color_Float;                // Offset:    0 Size:    16
-//   float zValueF_Float;               // Offset:   16 Size:     4
-//
-// }
-//
-//
-// Resource Bindings:
-//
-// Name                                 Type  Format         Dim Slot Elements
-// ------------------------------ ---------- ------- ----------- ---- --------
-// ColorAndDepthDataFloat            cbuffer      NA          NA    0        1
-//
-//
-//
-// Input signature:
-//
-// Name                 Index   Mask Register SysValue  Format   Used
-// -------------------- ----- ------ -------- -------- ------- ------
-// SV_POSITION              0   xyzw        0      POS   float       
-//
-//
-// Output signature:
-//
-// Name                 Index   Mask Register SysValue  Format   Used
-// -------------------- ----- ------ -------- -------- ------- ------
-// SV_TARGET                0   xyzw        0   TARGET   float   xyzw
-// SV_TARGET                1   xyzw        1   TARGET   float   xyzw
-// SV_DEPTH                 0    N/A   oDepth    DEPTH   float    YES
-//
-ps_4_0
-dcl_constantbuffer cb0[2], immediateIndexed
-dcl_output o0.xyzw
-dcl_output o1.xyzw
-dcl_output oDepth
-mov o0.xyzw, cb0[0].xyzw
-mov o1.xyzw, cb0[0].xyzw
-mov oDepth, cb0[1].x
-ret 
-// Approximately 4 instruction slots used
-#endif
-
-const BYTE g_PS_ClearFloat2[] = {
-    68,  88,  66,  67,  108, 104, 239, 227, 97,  196, 142, 3,   142, 195, 239, 186, 183, 205, 245,
-    112, 1,   0,   0,   0,   236, 2,   0,   0,   5,   0,   0,   0,   52,  0,   0,   0,   72,  1,
-    0,   0,   124, 1,   0,   0,   232, 1,   0,   0,   112, 2,   0,   0,   82,  68,  69,  70,  12,
-    1,   0,   0,   1,   0,   0,   0,   84,  0,   0,   0,   1,   0,   0,   0,   28,  0,   0,   0,
-    0,   4,   255, 255, 0,   1,   0,   0,   216, 0,   0,   0,   60,  0,   0,   0,   0,   0,   0,
-    0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   1,   0,
-    0,   0,   1,   0,   0,   0,   67,  111, 108, 111, 114, 65,  110, 100, 68,  101, 112, 116, 104,
-    68,  97,  116, 97,  70,  108, 111, 97,  116, 0,   171, 60,  0,   0,   0,   2,   0,   0,   0,
-    108, 0,   0,   0,   32,  0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   156, 0,   0,
-    0,   0,   0,   0,   0,   16,  0,   0,   0,   2,   0,   0,   0,   168, 0,   0,   0,   0,   0,
-    0,   0,   184, 0,   0,   0,   16,  0,   0,   0,   4,   0,   0,   0,   2,   0,   0,   0,   200,
-    0,   0,   0,   0,   0,   0,   0,   99,  111, 108, 111, 114, 95,  70,  108, 111, 97,  116, 0,
-    1,   0,   3,   0,   1,   0,   4,   0,   0,   0,   0,   0,   0,   0,   0,   0,   122, 86,  97,
-    108, 117, 101, 70,  95,  70,  108, 111, 97,  116, 0,   171, 171, 0,   0,   3,   0,   1,   0,
-    1,   0,   0,   0,   0,   0,   0,   0,   0,   0,   77,  105, 99,  114, 111, 115, 111, 102, 116,
-    32,  40,  82,  41,  32,  72,  76,  83,  76,  32,  83,  104, 97,  100, 101, 114, 32,  67,  111,
-    109, 112, 105, 108, 101, 114, 32,  54,  46,  51,  46,  57,  54,  48,  48,  46,  49,  54,  51,
-    56,  52,  0,   171, 171, 73,  83,  71,  78,  44,  0,   0,   0,   1,   0,   0,   0,   8,   0,
-    0,   0,   32,  0,   0,   0,   0,   0,   0,   0,   1,   0,   0,   0,   3,   0,   0,   0,   0,
-    0,   0,   0,   15,  0,   0,   0,   83,  86,  95,  80,  79,  83,  73,  84,  73,  79,  78,  0,
-    79,  83,  71,  78,  100, 0,   0,   0,   3,   0,   0,   0,   8,   0,   0,   0,   80,  0,   0,
-    0,   0,   0,   0,   0,   0,   0,   0,   0,   3,   0,   0,   0,   0,   0,   0,   0,   15,  0,
-    0,   0,   80,  0,   0,   0,   1,   0,   0,   0,   0,   0,   0,   0,   3,   0,   0,   0,   1,
-    0,   0,   0,   15,  0,   0,   0,   90,  0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
-    3,   0,   0,   0,   255, 255, 255, 255, 1,   14,  0,   0,   83,  86,  95,  84,  65,  82,  71,
-    69,  84,  0,   83,  86,  95,  68,  69,  80,  84,  72,  0,   171, 83,  72,  68,  82,  128, 0,
-    0,   0,   64,  0,   0,   0,   32,  0,   0,   0,   89,  0,   0,   4,   70,  142, 32,  0,   0,
-    0,   0,   0,   2,   0,   0,   0,   101, 0,   0,   3,   242, 32,  16,  0,   0,   0,   0,   0,
-    101, 0,   0,   3,   242, 32,  16,  0,   1,   0,   0,   0,   101, 0,   0,   2,   1,   192, 0,
-    0,   54,  0,   0,   6,   242, 32,  16,  0,   0,   0,   0,   0,   70,  142, 32,  0,   0,   0,
-    0,   0,   0,   0,   0,   0,   54,  0,   0,   6,   242, 32,  16,  0,   1,   0,   0,   0,   70,
-    142, 32,  0,   0,   0,   0,   0,   0,   0,   0,   0,   54,  0,   0,   5,   1,   192, 0,   0,
-    10,  128, 32,  0,   0,   0,   0,   0,   1,   0,   0,   0,   62,  0,   0,   1,   83,  84,  65,
-    84,  116, 0,   0,   0,   4,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   3,   0,
-    0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   1,   0,   0,   0,   0,
-    0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
-    0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
-    0,   0,   0,   0,   0,   3,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
-    0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
-    0,   0,   0,   0,   0,   0,   0};
+#if 0
+//
+// Generated by Microsoft (R) HLSL Shader Compiler 6.3.9600.16384
+//
+//
+// Buffer Definitions: 
+//
+// cbuffer ColorAndDepthDataFloat
+// {
+//
+//   float4 color_Float;                // Offset:    0 Size:    16
+//   float zValueF_Float;               // Offset:   16 Size:     4
+//
+// }
+//
+//
+// Resource Bindings:
+//
+// Name                                 Type  Format         Dim Slot Elements
+// ------------------------------ ---------- ------- ----------- ---- --------
+// ColorAndDepthDataFloat            cbuffer      NA          NA    0        1
+//
+//
+//
+// Input signature:
+//
+// Name                 Index   Mask Register SysValue  Format   Used
+// -------------------- ----- ------ -------- -------- ------- ------
+// SV_POSITION              0   xyzw        0      POS   float       
+//
+//
+// Output signature:
+//
+// Name                 Index   Mask Register SysValue  Format   Used
+// -------------------- ----- ------ -------- -------- ------- ------
+// SV_TARGET                0   xyzw        0   TARGET   float   xyzw
+// SV_TARGET                1   xyzw        1   TARGET   float   xyzw
+// SV_DEPTH                 0    N/A   oDepth    DEPTH   float    YES
+//
+ps_4_0
+dcl_constantbuffer cb0[2], immediateIndexed
+dcl_output o0.xyzw
+dcl_output o1.xyzw
+dcl_output oDepth
+mov o0.xyzw, cb0[0].xyzw
+mov o1.xyzw, cb0[0].xyzw
+mov oDepth, cb0[1].x
+ret 
+// Approximately 4 instruction slots used
+#endif
+
+const BYTE g_PS_ClearFloat2[] = {
+    68,  88,  66,  67,  108, 104, 239, 227, 97,  196, 142, 3,   142, 195, 239, 186, 183, 205, 245,
+    112, 1,   0,   0,   0,   236, 2,   0,   0,   5,   0,   0,   0,   52,  0,   0,   0,   72,  1,
+    0,   0,   124, 1,   0,   0,   232, 1,   0,   0,   112, 2,   0,   0,   82,  68,  69,  70,  12,
+    1,   0,   0,   1,   0,   0,   0,   84,  0,   0,   0,   1,   0,   0,   0,   28,  0,   0,   0,
+    0,   4,   255, 255, 0,   1,   0,   0,   216, 0,   0,   0,   60,  0,   0,   0,   0,   0,   0,
+    0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   1,   0,
+    0,   0,   1,   0,   0,   0,   67,  111, 108, 111, 114, 65,  110, 100, 68,  101, 112, 116, 104,
+    68,  97,  116, 97,  70,  108, 111, 97,  116, 0,   171, 60,  0,   0,   0,   2,   0,   0,   0,
+    108, 0,   0,   0,   32,  0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   156, 0,   0,
+    0,   0,   0,   0,   0,   16,  0,   0,   0,   2,   0,   0,   0,   168, 0,   0,   0,   0,   0,
+    0,   0,   184, 0,   0,   0,   16,  0,   0,   0,   4,   0,   0,   0,   2,   0,   0,   0,   200,
+    0,   0,   0,   0,   0,   0,   0,   99,  111, 108, 111, 114, 95,  70,  108, 111, 97,  116, 0,
+    1,   0,   3,   0,   1,   0,   4,   0,   0,   0,   0,   0,   0,   0,   0,   0,   122, 86,  97,
+    108, 117, 101, 70,  95,  70,  108, 111, 97,  116, 0,   171, 171, 0,   0,   3,   0,   1,   0,
+    1,   0,   0,   0,   0,   0,   0,   0,   0,   0,   77,  105, 99,  114, 111, 115, 111, 102, 116,
+    32,  40,  82,  41,  32,  72,  76,  83,  76,  32,  83,  104, 97,  100, 101, 114, 32,  67,  111,
+    109, 112, 105, 108, 101, 114, 32,  54,  46,  51,  46,  57,  54,  48,  48,  46,  49,  54,  51,
+    56,  52,  0,   171, 171, 73,  83,  71,  78,  44,  0,   0,   0,   1,   0,   0,   0,   8,   0,
+    0,   0,   32,  0,   0,   0,   0,   0,   0,   0,   1,   0,   0,   0,   3,   0,   0,   0,   0,
+    0,   0,   0,   15,  0,   0,   0,   83,  86,  95,  80,  79,  83,  73,  84,  73,  79,  78,  0,
+    79,  83,  71,  78,  100, 0,   0,   0,   3,   0,   0,   0,   8,   0,   0,   0,   80,  0,   0,
+    0,   0,   0,   0,   0,   0,   0,   0,   0,   3,   0,   0,   0,   0,   0,   0,   0,   15,  0,
+    0,   0,   80,  0,   0,   0,   1,   0,   0,   0,   0,   0,   0,   0,   3,   0,   0,   0,   1,
+    0,   0,   0,   15,  0,   0,   0,   90,  0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+    3,   0,   0,   0,   255, 255, 255, 255, 1,   14,  0,   0,   83,  86,  95,  84,  65,  82,  71,
+    69,  84,  0,   83,  86,  95,  68,  69,  80,  84,  72,  0,   171, 83,  72,  68,  82,  128, 0,
+    0,   0,   64,  0,   0,   0,   32,  0,   0,   0,   89,  0,   0,   4,   70,  142, 32,  0,   0,
+    0,   0,   0,   2,   0,   0,   0,   101, 0,   0,   3,   242, 32,  16,  0,   0,   0,   0,   0,
+    101, 0,   0,   3,   242, 32,  16,  0,   1,   0,   0,   0,   101, 0,   0,   2,   1,   192, 0,
+    0,   54,  0,   0,   6,   242, 32,  16,  0,   0,   0,   0,   0,   70,  142, 32,  0,   0,   0,
+    0,   0,   0,   0,   0,   0,   54,  0,   0,   6,   242, 32,  16,  0,   1,   0,   0,   0,   70,
+    142, 32,  0,   0,   0,   0,   0,   0,   0,   0,   0,   54,  0,   0,   5,   1,   192, 0,   0,
+    10,  128, 32,  0,   0,   0,   0,   0,   1,   0,   0,   0,   62,  0,   0,   1,   83,  84,  65,
+    84,  116, 0,   0,   0,   4,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   3,   0,
+    0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   1,   0,   0,   0,   0,
+    0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+    0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+    0,   0,   0,   0,   0,   3,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+    0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+    0,   0,   0,   0,   0,   0,   0};
--- a/gfx/angle/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/clearfloat11ps3.h
+++ b/gfx/angle/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/clearfloat11ps3.h
@@ -1,98 +1,98 @@
-#if 0
-//
-// Generated by Microsoft (R) HLSL Shader Compiler 6.3.9600.16384
-//
-//
-// Buffer Definitions: 
-//
-// cbuffer ColorAndDepthDataFloat
-// {
-//
-//   float4 color_Float;                // Offset:    0 Size:    16
-//   float zValueF_Float;               // Offset:   16 Size:     4
-//
-// }
-//
-//
-// Resource Bindings:
-//
-// Name                                 Type  Format         Dim Slot Elements
-// ------------------------------ ---------- ------- ----------- ---- --------
-// ColorAndDepthDataFloat            cbuffer      NA          NA    0        1
-//
-//
-//
-// Input signature:
-//
-// Name                 Index   Mask Register SysValue  Format   Used
-// -------------------- ----- ------ -------- -------- ------- ------
-// SV_POSITION              0   xyzw        0      POS   float       
-//
-//
-// Output signature:
-//
-// Name                 Index   Mask Register SysValue  Format   Used
-// -------------------- ----- ------ -------- -------- ------- ------
-// SV_TARGET                0   xyzw        0   TARGET   float   xyzw
-// SV_TARGET                1   xyzw        1   TARGET   float   xyzw
-// SV_TARGET                2   xyzw        2   TARGET   float   xyzw
-// SV_DEPTH                 0    N/A   oDepth    DEPTH   float    YES
-//
-ps_4_0
-dcl_constantbuffer cb0[2], immediateIndexed
-dcl_output o0.xyzw
-dcl_output o1.xyzw
-dcl_output o2.xyzw
-dcl_output oDepth
-mov o0.xyzw, cb0[0].xyzw
-mov o1.xyzw, cb0[0].xyzw
-mov o2.xyzw, cb0[0].xyzw
-mov oDepth, cb0[1].x
-ret 
-// Approximately 5 instruction slots used
-#endif
-
-const BYTE g_PS_ClearFloat3[] = {
-    68,  88,  66,  67,  84,  28,  124, 78,  93,  18,  144, 54,  107, 173, 223, 168, 80,  58,  53,
-    212, 1,   0,   0,   0,   40,  3,   0,   0,   5,   0,   0,   0,   52,  0,   0,   0,   72,  1,
-    0,   0,   124, 1,   0,   0,   0,   2,   0,   0,   172, 2,   0,   0,   82,  68,  69,  70,  12,
-    1,   0,   0,   1,   0,   0,   0,   84,  0,   0,   0,   1,   0,   0,   0,   28,  0,   0,   0,
-    0,   4,   255, 255, 0,   1,   0,   0,   216, 0,   0,   0,   60,  0,   0,   0,   0,   0,   0,
-    0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   1,   0,
-    0,   0,   1,   0,   0,   0,   67,  111, 108, 111, 114, 65,  110, 100, 68,  101, 112, 116, 104,
-    68,  97,  116, 97,  70,  108, 111, 97,  116, 0,   171, 60,  0,   0,   0,   2,   0,   0,   0,
-    108, 0,   0,   0,   32,  0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   156, 0,   0,
-    0,   0,   0,   0,   0,   16,  0,   0,   0,   2,   0,   0,   0,   168, 0,   0,   0,   0,   0,
-    0,   0,   184, 0,   0,   0,   16,  0,   0,   0,   4,   0,   0,   0,   2,   0,   0,   0,   200,
-    0,   0,   0,   0,   0,   0,   0,   99,  111, 108, 111, 114, 95,  70,  108, 111, 97,  116, 0,
-    1,   0,   3,   0,   1,   0,   4,   0,   0,   0,   0,   0,   0,   0,   0,   0,   122, 86,  97,
-    108, 117, 101, 70,  95,  70,  108, 111, 97,  116, 0,   171, 171, 0,   0,   3,   0,   1,   0,
-    1,   0,   0,   0,   0,   0,   0,   0,   0,   0,   77,  105, 99,  114, 111, 115, 111, 102, 116,
-    32,  40,  82,  41,  32,  72,  76,  83,  76,  32,  83,  104, 97,  100, 101, 114, 32,  67,  111,
-    109, 112, 105, 108, 101, 114, 32,  54,  46,  51,  46,  57,  54,  48,  48,  46,  49,  54,  51,
-    56,  52,  0,   171, 171, 73,  83,  71,  78,  44,  0,   0,   0,   1,   0,   0,   0,   8,   0,
-    0,   0,   32,  0,   0,   0,   0,   0,   0,   0,   1,   0,   0,   0,   3,   0,   0,   0,   0,
-    0,   0,   0,   15,  0,   0,   0,   83,  86,  95,  80,  79,  83,  73,  84,  73,  79,  78,  0,
-    79,  83,  71,  78,  124, 0,   0,   0,   4,   0,   0,   0,   8,   0,   0,   0,   104, 0,   0,
-    0,   0,   0,   0,   0,   0,   0,   0,   0,   3,   0,   0,   0,   0,   0,   0,   0,   15,  0,
-    0,   0,   104, 0,   0,   0,   1,   0,   0,   0,   0,   0,   0,   0,   3,   0,   0,   0,   1,
-    0,   0,   0,   15,  0,   0,   0,   104, 0,   0,   0,   2,   0,   0,   0,   0,   0,   0,   0,
-    3,   0,   0,   0,   2,   0,   0,   0,   15,  0,   0,   0,   114, 0,   0,   0,   0,   0,   0,
-    0,   0,   0,   0,   0,   3,   0,   0,   0,   255, 255, 255, 255, 1,   14,  0,   0,   83,  86,
-    95,  84,  65,  82,  71,  69,  84,  0,   83,  86,  95,  68,  69,  80,  84,  72,  0,   171, 83,
-    72,  68,  82,  164, 0,   0,   0,   64,  0,   0,   0,   41,  0,   0,   0,   89,  0,   0,   4,
-    70,  142, 32,  0,   0,   0,   0,   0,   2,   0,   0,   0,   101, 0,   0,   3,   242, 32,  16,
-    0,   0,   0,   0,   0,   101, 0,   0,   3,   242, 32,  16,  0,   1,   0,   0,   0,   101, 0,
-    0,   3,   242, 32,  16,  0,   2,   0,   0,   0,   101, 0,   0,   2,   1,   192, 0,   0,   54,
-    0,   0,   6,   242, 32,  16,  0,   0,   0,   0,   0,   70,  142, 32,  0,   0,   0,   0,   0,
-    0,   0,   0,   0,   54,  0,   0,   6,   242, 32,  16,  0,   1,   0,   0,   0,   70,  142, 32,
-    0,   0,   0,   0,   0,   0,   0,   0,   0,   54,  0,   0,   6,   242, 32,  16,  0,   2,   0,
-    0,   0,   70,  142, 32,  0,   0,   0,   0,   0,   0,   0,   0,   0,   54,  0,   0,   5,   1,
-    192, 0,   0,   10,  128, 32,  0,   0,   0,   0,   0,   1,   0,   0,   0,   62,  0,   0,   1,
-    83,  84,  65,  84,  116, 0,   0,   0,   5,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
-    0,   4,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   1,   0,
-    0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
-    0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
-    0,   0,   0,   0,   0,   0,   0,   0,   4,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
-    0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
-    0,   0,   0,   0,   0,   0,   0,   0,   0,   0};
+#if 0
+//
+// Generated by Microsoft (R) HLSL Shader Compiler 6.3.9600.16384
+//
+//
+// Buffer Definitions: 
+//
+// cbuffer ColorAndDepthDataFloat
+// {
+//
+//   float4 color_Float;                // Offset:    0 Size:    16
+//   float zValueF_Float;               // Offset:   16 Size:     4
+//
+// }
+//
+//
+// Resource Bindings:
+//
+// Name                                 Type  Format         Dim Slot Elements
+// ------------------------------ ---------- ------- ----------- ---- --------
+// ColorAndDepthDataFloat            cbuffer      NA          NA    0        1
+//
+//
+//
+// Input signature:
+//
+// Name                 Index   Mask Register SysValue  Format   Used
+// -------------------- ----- ------ -------- -------- ------- ------
+// SV_POSITION              0   xyzw        0      POS   float       
+//
+//
+// Output signature:
+//
+// Name                 Index   Mask Register SysValue  Format   Used
+// -------------------- ----- ------ -------- -------- ------- ------
+// SV_TARGET                0   xyzw        0   TARGET   float   xyzw
+// SV_TARGET                1   xyzw        1   TARGET   float   xyzw
+// SV_TARGET                2   xyzw        2   TARGET   float   xyzw
+// SV_DEPTH                 0    N/A   oDepth    DEPTH   float    YES
+//
+ps_4_0
+dcl_constantbuffer cb0[2], immediateIndexed
+dcl_output o0.xyzw
+dcl_output o1.xyzw
+dcl_output o2.xyzw
+dcl_output oDepth
+mov o0.xyzw, cb0[0].xyzw
+mov o1.xyzw, cb0[0].xyzw
+mov o2.xyzw, cb0[0].xyzw
+mov oDepth, cb0[1].x
+ret 
+// Approximately 5 instruction slots used
+#endif
+
+const BYTE g_PS_ClearFloat3[] = {
+    68,  88,  66,  67,  84,  28,  124, 78,  93,  18,  144, 54,  107, 173, 223, 168, 80,  58,  53,
+    212, 1,   0,   0,   0,   40,  3,   0,   0,   5,   0,   0,   0,   52,  0,   0,   0,   72,  1,
+    0,   0,   124, 1,   0,   0,   0,   2,   0,   0,   172, 2,   0,   0,   82,  68,  69,  70,  12,
+    1,   0,   0,   1,   0,   0,   0,   84,  0,   0,   0,   1,   0,   0,   0,   28,  0,   0,   0,
+    0,   4,   255, 255, 0,   1,   0,   0,   216, 0,   0,   0,   60,  0,   0,   0,   0,   0,   0,
+    0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   1,   0,
+    0,   0,   1,   0,   0,   0,   67,  111, 108, 111, 114, 65,  110, 100, 68,  101, 112, 116, 104,
+    68,  97,  116, 97,  70,  108, 111, 97,  116, 0,   171, 60,  0,   0,   0,   2,   0,   0,   0,
+    108, 0,   0,   0,   32,  0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   156, 0,   0,
+    0,   0,   0,   0,   0,   16,  0,   0,   0,   2,   0,   0,   0,   168, 0,   0,   0,   0,   0,
+    0,   0,   184, 0,   0,   0,   16,  0,   0,   0,   4,   0,   0,   0,   2,   0,   0,   0,   200,
+    0,   0,   0,   0,   0,   0,   0,   99,  111, 108, 111, 114, 95,  70,  108, 111, 97,  116, 0,
+    1,   0,   3,   0,   1,   0,   4,   0,   0,   0,   0,   0,   0,   0,   0,   0,   122, 86,  97,
+    108, 117, 101, 70,  95,  70,  108, 111, 97,  116, 0,   171, 171, 0,   0,   3,   0,   1,   0,
+    1,   0,   0,   0,   0,   0,   0,   0,   0,   0,   77,  105, 99,  114, 111, 115, 111, 102, 116,
+    32,  40,  82,  41,  32,  72,  76,  83,  76,  32,  83,  104, 97,  100, 101, 114, 32,  67,  111,
+    109, 112, 105, 108, 101, 114, 32,  54,  46,  51,  46,  57,  54,  48,  48,  46,  49,  54,  51,
+    56,  52,  0,   171, 171, 73,  83,  71,  78,  44,  0,   0,   0,   1,   0,   0,   0,   8,   0,
+    0,   0,   32,  0,   0,   0,   0,   0,   0,   0,   1,   0,   0,   0,   3,   0,   0,   0,   0,
+    0,   0,   0,   15,  0,   0,   0,   83,  86,  95,  80,  79,  83,  73,  84,  73,  79,  78,  0,
+    79,  83,  71,  78,  124, 0,   0,   0,   4,   0,   0,   0,   8,   0,   0,   0,   104, 0,   0,
+    0,   0,   0,   0,   0,   0,   0,   0,   0,   3,   0,   0,   0,   0,   0,   0,   0,   15,  0,
+    0,   0,   104, 0,   0,   0,   1,   0,   0,   0,   0,   0,   0,   0,   3,   0,   0,   0,   1,
+    0,   0,   0,   15,  0,   0,   0,   104, 0,   0,   0,   2,   0,   0,   0,   0,   0,   0,   0,
+    3,   0,   0,   0,   2,   0,   0,   0,   15,  0,   0,   0,   114, 0,   0,   0,   0,   0,   0,
+    0,   0,   0,   0,   0,   3,   0,   0,   0,   255, 255, 255, 255, 1,   14,  0,   0,   83,  86,
+    95,  84,  65,  82,  71,  69,  84,  0,   83,  86,  95,  68,  69,  80,  84,  72,  0,   171, 83,
+    72,  68,  82,  164, 0,   0,   0,   64,  0,   0,   0,   41,  0,   0,   0,   89,  0,   0,   4,
+    70,  142, 32,  0,   0,   0,   0,   0,   2,   0,   0,   0,   101, 0,   0,   3,   242, 32,  16,
+    0,   0,   0,   0,   0,   101, 0,   0,   3,   242, 32,  16,  0,   1,   0,   0,   0,   101, 0,
+    0,   3,   242, 32,  16,  0,   2,   0,   0,   0,   101, 0,   0,   2,   1,   192, 0,   0,   54,
+    0,   0,   6,   242, 32,  16,  0,   0,   0,   0,   0,   70,  142, 32,  0,   0,   0,   0,   0,
+    0,   0,   0,   0,   54,  0,   0,   6,   242, 32,  16,  0,   1,   0,   0,   0,   70,  142, 32,
+    0,   0,   0,   0,   0,   0,   0,   0,   0,   54,  0,   0,   6,   242, 32,  16,  0,   2,   0,
+    0,   0,   70,  142, 32,  0,   0,   0,   0,   0,   0,   0,   0,   0,   54,  0,   0,   5,   1,
+    192, 0,   0,   10,  128, 32,  0,   0,   0,   0,   0,   1,   0,   0,   0,   62,  0,   0,   1,
+    83,  84,  65,  84,  116, 0,   0,   0,   5,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+    0,   4,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   1,   0,
+    0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+    0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+    0,   0,   0,   0,   0,   0,   0,   0,   4,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+    0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+    0,   0,   0,   0,   0,   0,   0,   0,   0,   0};
--- a/gfx/angle/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/clearfloat11ps4.h
+++ b/gfx/angle/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/clearfloat11ps4.h
@@ -1,104 +1,104 @@
-#if 0
-//
-// Generated by Microsoft (R) HLSL Shader Compiler 6.3.9600.16384
-//
-//
-// Buffer Definitions: 
-//
-// cbuffer ColorAndDepthDataFloat
-// {
-//
-//   float4 color_Float;                // Offset:    0 Size:    16
-//   float zValueF_Float;               // Offset:   16 Size:     4
-//
-// }
-//
-//
-// Resource Bindings:
-//
-// Name                                 Type  Format         Dim Slot Elements
-// ------------------------------ ---------- ------- ----------- ---- --------
-// ColorAndDepthDataFloat            cbuffer      NA          NA    0        1
-//
-//
-//
-// Input signature:
-//
-// Name                 Index   Mask Register SysValue  Format   Used
-// -------------------- ----- ------ -------- -------- ------- ------
-// SV_POSITION              0   xyzw        0      POS   float       
-//
-//
-// Output signature:
-//
-// Name                 Index   Mask Register SysValue  Format   Used
-// -------------------- ----- ------ -------- -------- ------- ------
-// SV_TARGET                0   xyzw        0   TARGET   float   xyzw
-// SV_TARGET                1   xyzw        1   TARGET   float   xyzw
-// SV_TARGET                2   xyzw        2   TARGET   float   xyzw
-// SV_TARGET                3   xyzw        3   TARGET   float   xyzw
-// SV_DEPTH                 0    N/A   oDepth    DEPTH   float    YES
-//
-ps_4_0
-dcl_constantbuffer cb0[2], immediateIndexed
-dcl_output o0.xyzw
-dcl_output o1.xyzw
-dcl_output o2.xyzw
-dcl_output o3.xyzw
-dcl_output oDepth
-mov o0.xyzw, cb0[0].xyzw
-mov o1.xyzw, cb0[0].xyzw
-mov o2.xyzw, cb0[0].xyzw
-mov o3.xyzw, cb0[0].xyzw
-mov oDepth, cb0[1].x
-ret 
-// Approximately 6 instruction slots used
-#endif
-
-const BYTE g_PS_ClearFloat4[] = {
-    68,  88,  66,  67,  207, 141, 9,   109, 48,  1,   5,   41,  68,  133, 156, 207, 12,  211, 147,
-    112, 1,   0,   0,   0,   100, 3,   0,   0,   5,   0,   0,   0,   52,  0,   0,   0,   72,  1,
-    0,   0,   124, 1,   0,   0,   24,  2,   0,   0,   232, 2,   0,   0,   82,  68,  69,  70,  12,
-    1,   0,   0,   1,   0,   0,   0,   84,  0,   0,   0,   1,   0,   0,   0,   28,  0,   0,   0,
-    0,   4,   255, 255, 0,   1,   0,   0,   216, 0,   0,   0,   60,  0,   0,   0,   0,   0,   0,
-    0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   1,   0,
-    0,   0,   1,   0,   0,   0,   67,  111, 108, 111, 114, 65,  110, 100, 68,  101, 112, 116, 104,
-    68,  97,  116, 97,  70,  108, 111, 97,  116, 0,   171, 60,  0,   0,   0,   2,   0,   0,   0,
-    108, 0,   0,   0,   32,  0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   156, 0,   0,
-    0,   0,   0,   0,   0,   16,  0,   0,   0,   2,   0,   0,   0,   168, 0,   0,   0,   0,   0,
-    0,   0,   184, 0,   0,   0,   16,  0,   0,   0,   4,   0,   0,   0,   2,   0,   0,   0,   200,
-    0,   0,   0,   0,   0,   0,   0,   99,  111, 108, 111, 114, 95,  70,  108, 111, 97,  116, 0,
-    1,   0,   3,   0,   1,   0,   4,   0,   0,   0,   0,   0,   0,   0,   0,   0,   122, 86,  97,
-    108, 117, 101, 70,  95,  70,  108, 111, 97,  116, 0,   171, 171, 0,   0,   3,   0,   1,   0,
-    1,   0,   0,   0,   0,   0,   0,   0,   0,   0,   77,  105, 99,  114, 111, 115, 111, 102, 116,
-    32,  40,  82,  41,  32,  72,  76,  83,  76,  32,  83,  104, 97,  100, 101, 114, 32,  67,  111,
-    109, 112, 105, 108, 101, 114, 32,  54,  46,  51,  46,  57,  54,  48,  48,  46,  49,  54,  51,
-    56,  52,  0,   171, 171, 73,  83,  71,  78,  44,  0,   0,   0,   1,   0,   0,   0,   8,   0,
-    0,   0,   32,  0,   0,   0,   0,   0,   0,   0,   1,   0,   0,   0,   3,   0,   0,   0,   0,
-    0,   0,   0,   15,  0,   0,   0,   83,  86,  95,  80,  79,  83,  73,  84,  73,  79,  78,  0,
-    79,  83,  71,  78,  148, 0,   0,   0,   5,   0,   0,   0,   8,   0,   0,   0,   128, 0,   0,
-    0,   0,   0,   0,   0,   0,   0,   0,   0,   3,   0,   0,   0,   0,   0,   0,   0,   15,  0,
-    0,   0,   128, 0,   0,   0,   1,   0,   0,   0,   0,   0,   0,   0,   3,   0,   0,   0,   1,
-    0,   0,   0,   15,  0,   0,   0,   128, 0,   0,   0,   2,   0,   0,   0,   0,   0,   0,   0,
-    3,   0,   0,   0,   2,   0,   0,   0,   15,  0,   0,   0,   128, 0,   0,   0,   3,   0,   0,
-    0,   0,   0,   0,   0,   3,   0,   0,   0,   3,   0,   0,   0,   15,  0,   0,   0,   138, 0,
-    0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   3,   0,   0,   0,   255, 255, 255, 255, 1,
-    14,  0,   0,   83,  86,  95,  84,  65,  82,  71,  69,  84,  0,   83,  86,  95,  68,  69,  80,
-    84,  72,  0,   171, 83,  72,  68,  82,  200, 0,   0,   0,   64,  0,   0,   0,   50,  0,   0,
-    0,   89,  0,   0,   4,   70,  142, 32,  0,   0,   0,   0,   0,   2,   0,   0,   0,   101, 0,
-    0,   3,   242, 32,  16,  0,   0,   0,   0,   0,   101, 0,   0,   3,   242, 32,  16,  0,   1,
-    0,   0,   0,   101, 0,   0,   3,   242, 32,  16,  0,   2,   0,   0,   0,   101, 0,   0,   3,
-    242, 32,  16,  0,   3,   0,   0,   0,   101, 0,   0,   2,   1,   192, 0,   0,   54,  0,   0,
-    6,   242, 32,  16,  0,   0,   0,   0,   0,   70,  142, 32,  0,   0,   0,   0,   0,   0,   0,
-    0,   0,   54,  0,   0,   6,   242, 32,  16,  0,   1,   0,   0,   0,   70,  142, 32,  0,   0,
-    0,   0,   0,   0,   0,   0,   0,   54,  0,   0,   6,   242, 32,  16,  0,   2,   0,   0,   0,
-    70,  142, 32,  0,   0,   0,   0,   0,   0,   0,   0,   0,   54,  0,   0,   6,   242, 32,  16,
-    0,   3,   0,   0,   0,   70,  142, 32,  0,   0,   0,   0,   0,   0,   0,   0,   0,   54,  0,
-    0,   5,   1,   192, 0,   0,   10,  128, 32,  0,   0,   0,   0,   0,   1,   0,   0,   0,   62,
-    0,   0,   1,   83,  84,  65,  84,  116, 0,   0,   0,   6,   0,   0,   0,   0,   0,   0,   0,
-    0,   0,   0,   0,   5,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
-    0,   1,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
-    0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
-    0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   5,   0,   0,   0,   0,   0,   0,   0,
-    0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
-    0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0};
+#if 0
+//
+// Generated by Microsoft (R) HLSL Shader Compiler 6.3.9600.16384
+//
+//
+// Buffer Definitions: 
+//
+// cbuffer ColorAndDepthDataFloat
+// {
+//
+//   float4 color_Float;                // Offset:    0 Size:    16
+//   float zValueF_Float;               // Offset:   16 Size:     4
+//
+// }
+//
+//
+// Resource Bindings:
+//
+// Name                                 Type  Format         Dim Slot Elements
+// ------------------------------ ---------- ------- ----------- ---- --------
+// ColorAndDepthDataFloat            cbuffer      NA          NA    0        1
+//
+//
+//
+// Input signature:
+//
+// Name                 Index   Mask Register SysValue  Format   Used
+// -------------------- ----- ------ -------- -------- ------- ------
+// SV_POSITION              0   xyzw        0      POS   float       
+//
+//
+// Output signature:
+//
+// Name                 Index   Mask Register SysValue  Format   Used
+// -------------------- ----- ------ -------- -------- ------- ------
+// SV_TARGET                0   xyzw        0   TARGET   float   xyzw
+// SV_TARGET                1   xyzw        1   TARGET   float   xyzw
+// SV_TARGET                2   xyzw        2   TARGET   float   xyzw
+// SV_TARGET                3   xyzw        3   TARGET   float   xyzw
+// SV_DEPTH                 0    N/A   oDepth    DEPTH   float    YES
+//
+ps_4_0
+dcl_constantbuffer cb0[2], immediateIndexed
+dcl_output o0.xyzw
+dcl_output o1.xyzw
+dcl_output o2.xyzw
+dcl_output o3.xyzw
+dcl_output oDepth
+mov o0.xyzw, cb0[0].xyzw
+mov o1.xyzw, cb0[0].xyzw
+mov o2.xyzw, cb0[0].xyzw
+mov o3.xyzw, cb0[0].xyzw
+mov oDepth, cb0[1].x
+ret 
+// Approximately 6 instruction slots used
+#endif
+
+const BYTE g_PS_ClearFloat4[] = {
+    68,  88,  66,  67,  207, 141, 9,   109, 48,  1,   5,   41,  68,  133, 156, 207, 12,  211, 147,
+    112, 1,   0,   0,   0,   100, 3,   0,   0,   5,   0,   0,   0,   52,  0,   0,   0,   72,  1,
+    0,   0,   124, 1,   0,   0,   24,  2,   0,   0,   232, 2,   0,   0,   82,  68,  69,  70,  12,
+    1,   0,   0,   1,   0,   0,   0,   84,  0,   0,   0,   1,   0,   0,   0,   28,  0,   0,   0,
+    0,   4,   255, 255, 0,   1,   0,   0,   216, 0,   0,   0,   60,  0,   0,   0,   0,   0,   0,
+    0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   1,   0,
+    0,   0,   1,   0,   0,   0,   67,  111, 108, 111, 114, 65,  110, 100, 68,  101, 112, 116, 104,
+    68,  97,  116, 97,  70,  108, 111, 97,  116, 0,   171, 60,  0,   0,   0,   2,   0,   0,   0,
+    108, 0,   0,   0,   32,  0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   156, 0,   0,
+    0,   0,   0,   0,   0,   16,  0,   0,   0,   2,   0,   0,   0,   168, 0,   0,   0,   0,   0,
+    0,   0,   184, 0,   0,   0,   16,  0,   0,   0,   4,   0,   0,   0,   2,   0,   0,   0,   200,
+    0,   0,   0,   0,   0,   0,   0,   99,  111, 108, 111, 114, 95,  70,  108, 111, 97,  116, 0,
+    1,   0,   3,   0,   1,   0,   4,   0,   0,   0,   0,   0,   0,   0,   0,   0,   122, 86,  97,
+    108, 117, 101, 70,  95,  70,  108, 111, 97,  116, 0,   171, 171, 0,   0,   3,   0,   1,   0,
+    1,   0,   0,   0,   0,   0,   0,   0,   0,   0,   77,  105, 99,  114, 111, 115, 111, 102, 116,
+    32,  40,  82,  41,  32,  72,  76,  83,  76,  32,  83,  104, 97,  100, 101, 114, 32,  67,  111,
+    109, 112, 105, 108, 101, 114, 32,  54,  46,  51,  46,  57,  54,  48,  48,  46,  49,  54,  51,
+    56,  52,  0,   171, 171, 73,  83,  71,  78,  44,  0,   0,   0,   1,   0,   0,   0,   8,   0,
+    0,   0,   32,  0,   0,   0,   0,   0,   0,   0,   1,   0,   0,   0,   3,   0,   0,   0,   0,
+    0,   0,   0,   15,  0,   0,   0,   83,  86,  95,  80,  79,  83,  73,  84,  73,  79,  78,  0,
+    79,  83,  71,  78,  148, 0,   0,   0,   5,   0,   0,   0,   8,   0,   0,   0,   128, 0,   0,
+    0,   0,   0,   0,   0,   0,   0,   0,   0,   3,   0,   0,   0,   0,   0,   0,   0,   15,  0,
+    0,   0,   128, 0,   0,   0,   1,   0,   0,   0,   0,   0,   0,   0,   3,   0,   0,   0,   1,
+    0,   0,   0,   15,  0,   0,   0,   128, 0,   0,   0,   2,   0,   0,   0,   0,   0,   0,   0,
+    3,   0,   0,   0,   2,   0,   0,   0,   15,  0,   0,   0,   128, 0,   0,   0,   3,   0,   0,
+    0,   0,   0,   0,   0,   3,   0,   0,   0,   3,   0,   0,   0,   15,  0,   0,   0,   138, 0,
+    0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   3,   0,   0,   0,   255, 255, 255, 255, 1,
+    14,  0,   0,   83,  86,  95,  84,  65,  82,  71,  69,  84,  0,   83,  86,  95,  68,  69,  80,
+    84,  72,  0,   171, 83,  72,  68,  82,  200, 0,   0,   0,   64,  0,   0,   0,   50,  0,   0,
+    0,   89,  0,   0,   4,   70,  142, 32,  0,   0,   0,   0,   0,   2,   0,   0,   0,   101, 0,
+    0,   3,   242, 32,  16,  0,   0,   0,   0,   0,   101, 0,   0,   3,   242, 32,  16,  0,   1,
+    0,   0,   0,   101, 0,   0,   3,   242, 32,  16,  0,   2,   0,   0,   0,   101, 0,   0,   3,
+    242, 32,  16,  0,   3,   0,   0,   0,   101, 0,   0,   2,   1,   192, 0,   0,   54,  0,   0,
+    6,   242, 32,  16,  0,   0,   0,   0,   0,   70,  142, 32,  0,   0,   0,   0,   0,   0,   0,
+    0,   0,   54,  0,   0,   6,   242, 32,  16,  0,   1,   0,   0,   0,   70,  142, 32,  0,   0,
+    0,   0,   0,   0,   0,   0,   0,   54,  0,   0,   6,   242, 32,  16,  0,   2,   0,   0,   0,
+    70,  142, 32,  0,   0,   0,   0,   0,   0,   0,   0,   0,   54,  0,   0,   6,   242, 32,  16,
+    0,   3,   0,   0,   0,   70,  142, 32,  0,   0,   0,   0,   0,   0,   0,   0,   0,   54,  0,
+    0,   5,   1,   192, 0,   0,   10,  128, 32,  0,   0,   0,   0,   0,   1,   0,   0,   0,   62,
+    0,   0,   1,   83,  84,  65,  84,  116, 0,   0,   0,   6,   0,   0,   0,   0,   0,   0,   0,
+    0,   0,   0,   0,   5,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+    0,   1,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+    0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+    0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   5,   0,   0,   0,   0,   0,   0,   0,
+    0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+    0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0};
--- a/gfx/angle/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/clearfloat11ps5.h
+++ b/gfx/angle/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/clearfloat11ps5.h
@@ -1,110 +1,110 @@
-#if 0
-//
-// Generated by Microsoft (R) HLSL Shader Compiler 6.3.9600.16384
-//
-//
-// Buffer Definitions: 
-//
-// cbuffer ColorAndDepthDataFloat
-// {
-//
-//   float4 color_Float;                // Offset:    0 Size:    16
-//   float zValueF_Float;               // Offset:   16 Size:     4
-//
-// }
-//
-//
-// Resource Bindings:
-//
-// Name                                 Type  Format         Dim Slot Elements
-// ------------------------------ ---------- ------- ----------- ---- --------
-// ColorAndDepthDataFloat            cbuffer      NA          NA    0        1
-//
-//
-//
-// Input signature:
-//
-// Name                 Index   Mask Register SysValue  Format   Used
-// -------------------- ----- ------ -------- -------- ------- ------
-// SV_POSITION              0   xyzw        0      POS   float       
-//
-//
-// Output signature:
-//
-// Name                 Index   Mask Register SysValue  Format   Used
-// -------------------- ----- ------ -------- -------- ------- ------
-// SV_TARGET                0   xyzw        0   TARGET   float   xyzw
-// SV_TARGET                1   xyzw        1   TARGET   float   xyzw
-// SV_TARGET                2   xyzw        2   TARGET   float   xyzw
-// SV_TARGET                3   xyzw        3   TARGET   float   xyzw
-// SV_TARGET                4   xyzw        4   TARGET   float   xyzw
-// SV_DEPTH                 0    N/A   oDepth    DEPTH   float    YES
-//
-ps_4_0
-dcl_constantbuffer cb0[2], immediateIndexed
-dcl_output o0.xyzw
-dcl_output o1.xyzw
-dcl_output o2.xyzw
-dcl_output o3.xyzw
-dcl_output o4.xyzw
-dcl_output oDepth
-mov o0.xyzw, cb0[0].xyzw
-mov o1.xyzw, cb0[0].xyzw
-mov o2.xyzw, cb0[0].xyzw
-mov o3.xyzw, cb0[0].xyzw
-mov o4.xyzw, cb0[0].xyzw
-mov oDepth, cb0[1].x
-ret 
-// Approximately 7 instruction slots used
-#endif
-
-const BYTE g_PS_ClearFloat5[] = {
-    68,  88,  66,  67,  110, 251, 0,   120, 207, 72,  250, 15,  78,  51,  222, 23,  61,  180, 247,
-    36,  1,   0,   0,   0,   160, 3,   0,   0,   5,   0,   0,   0,   52,  0,   0,   0,   72,  1,
-    0,   0,   124, 1,   0,   0,   48,  2,   0,   0,   36,  3,   0,   0,   82,  68,  69,  70,  12,
-    1,   0,   0,   1,   0,   0,   0,   84,  0,   0,   0,   1,   0,   0,   0,   28,  0,   0,   0,
-    0,   4,   255, 255, 0,   1,   0,   0,   216, 0,   0,   0,   60,  0,   0,   0,   0,   0,   0,
-    0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   1,   0,
-    0,   0,   1,   0,   0,   0,   67,  111, 108, 111, 114, 65,  110, 100, 68,  101, 112, 116, 104,
-    68,  97,  116, 97,  70,  108, 111, 97,  116, 0,   171, 60,  0,   0,   0,   2,   0,   0,   0,
-    108, 0,   0,   0,   32,  0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   156, 0,   0,
-    0,   0,   0,   0,   0,   16,  0,   0,   0,   2,   0,   0,   0,   168, 0,   0,   0,   0,   0,
-    0,   0,   184, 0,   0,   0,   16,  0,   0,   0,   4,   0,   0,   0,   2,   0,   0,   0,   200,
-    0,   0,   0,   0,   0,   0,   0,   99,  111, 108, 111, 114, 95,  70,  108, 111, 97,  116, 0,
-    1,   0,   3,   0,   1,   0,   4,   0,   0,   0,   0,   0,   0,   0,   0,   0,   122, 86,  97,
-    108, 117, 101, 70,  95,  70,  108, 111, 97,  116, 0,   171, 171, 0,   0,   3,   0,   1,   0,
-    1,   0,   0,   0,   0,   0,   0,   0,   0,   0,   77,  105, 99,  114, 111, 115, 111, 102, 116,
-    32,  40,  82,  41,  32,  72,  76,  83,  76,  32,  83,  104, 97,  100, 101, 114, 32,  67,  111,
-    109, 112, 105, 108, 101, 114, 32,  54,  46,  51,  46,  57,  54,  48,  48,  46,  49,  54,  51,
-    56,  52,  0,   171, 171, 73,  83,  71,  78,  44,  0,   0,   0,   1,   0,   0,   0,   8,   0,
-    0,   0,   32,  0,   0,   0,   0,   0,   0,   0,   1,   0,   0,   0,   3,   0,   0,   0,   0,
-    0,   0,   0,   15,  0,   0,   0,   83,  86,  95,  80,  79,  83,  73,  84,  73,  79,  78,  0,
-    79,  83,  71,  78,  172, 0,   0,   0,   6,   0,   0,   0,   8,   0,   0,   0,   152, 0,   0,
-    0,   0,   0,   0,   0,   0,   0,   0,   0,   3,   0,   0,   0,   0,   0,   0,   0,   15,  0,
-    0,   0,   152, 0,   0,   0,   1,   0,   0,   0,   0,   0,   0,   0,   3,   0,   0,   0,   1,
-    0,   0,   0,   15,  0,   0,   0,   152, 0,   0,   0,   2,   0,   0,   0,   0,   0,   0,   0,
-    3,   0,   0,   0,   2,   0,   0,   0,   15,  0,   0,   0,   152, 0,   0,   0,   3,   0,   0,
-    0,   0,   0,   0,   0,   3,   0,   0,   0,   3,   0,   0,   0,   15,  0,   0,   0,   152, 0,
-    0,   0,   4,   0,   0,   0,   0,   0,   0,   0,   3,   0,   0,   0,   4,   0,   0,   0,   15,
-    0,   0,   0,   162, 0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   3,   0,   0,   0,
-    255, 255, 255, 255, 1,   14,  0,   0,   83,  86,  95,  84,  65,  82,  71,  69,  84,  0,   83,
-    86,  95,  68,  69,  80,  84,  72,  0,   171, 83,  72,  68,  82,  236, 0,   0,   0,   64,  0,
-    0,   0,   59,  0,   0,   0,   89,  0,   0,   4,   70,  142, 32,  0,   0,   0,   0,   0,   2,
-    0,   0,   0,   101, 0,   0,   3,   242, 32,  16,  0,   0,   0,   0,   0,   101, 0,   0,   3,
-    242, 32,  16,  0,   1,   0,   0,   0,   101, 0,   0,   3,   242, 32,  16,  0,   2,   0,   0,
-    0,   101, 0,   0,   3,   242, 32,  16,  0,   3,   0,   0,   0,   101, 0,   0,   3,   242, 32,
-    16,  0,   4,   0,   0,   0,   101, 0,   0,   2,   1,   192, 0,   0,   54,  0,   0,   6,   242,
-    32,  16,  0,   0,   0,   0,   0,   70,  142, 32,  0,   0,   0,   0,   0,   0,   0,   0,   0,
-    54,  0,   0,   6,   242, 32,  16,  0,   1,   0,   0,   0,   70,  142, 32,  0,   0,   0,   0,
-    0,   0,   0,   0,   0,   54,  0,   0,   6,   242, 32,  16,  0,   2,   0,   0,   0,   70,  142,
-    32,  0,   0,   0,   0,   0,   0,   0,   0,   0,   54,  0,   0,   6,   242, 32,  16,  0,   3,
-    0,   0,   0,   70,  142, 32,  0,   0,   0,   0,   0,   0,   0,   0,   0,   54,  0,   0,   6,
-    242, 32,  16,  0,   4,   0,   0,   0,   70,  142, 32,  0,   0,   0,   0,   0,   0,   0,   0,
-    0,   54,  0,   0,   5,   1,   192, 0,   0,   10,  128, 32,  0,   0,   0,   0,   0,   1,   0,
-    0,   0,   62,  0,   0,   1,   83,  84,  65,  84,  116, 0,   0,   0,   7,   0,   0,   0,   0,
-    0,   0,   0,   0,   0,   0,   0,   6,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
-    0,   0,   0,   0,   1,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
-    0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
-    0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   6,   0,   0,   0,   0,
-    0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
-    0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0};
+#if 0
+//
+// Generated by Microsoft (R) HLSL Shader Compiler 6.3.9600.16384
+//
+//
+// Buffer Definitions: 
+//
+// cbuffer ColorAndDepthDataFloat
+// {
+//
+//   float4 color_Float;                // Offset:    0 Size:    16
+//   float zValueF_Float;               // Offset:   16 Size:     4
+//
+// }
+//
+//
+// Resource Bindings:
+//
+// Name                                 Type  Format         Dim Slot Elements
+// ------------------------------ ---------- ------- ----------- ---- --------
+// ColorAndDepthDataFloat            cbuffer      NA          NA    0        1
+//
+//
+//
+// Input signature:
+//
+// Name                 Index   Mask Register SysValue  Format   Used
+// -------------------- ----- ------ -------- -------- ------- ------
+// SV_POSITION              0   xyzw        0      POS   float       
+//
+//
+// Output signature:
+//
+// Name                 Index   Mask Register SysValue  Format   Used
+// -------------------- ----- ------ -------- -------- ------- ------
+// SV_TARGET                0   xyzw        0   TARGET   float   xyzw
+// SV_TARGET                1   xyzw        1   TARGET   float   xyzw
+// SV_TARGET                2   xyzw        2   TARGET   float   xyzw
+// SV_TARGET                3   xyzw        3   TARGET   float   xyzw
+// SV_TARGET                4   xyzw        4   TARGET   float   xyzw
+// SV_DEPTH                 0    N/A   oDepth    DEPTH   float    YES
+//
+ps_4_0
+dcl_constantbuffer cb0[2], immediateIndexed
+dcl_output o0.xyzw
+dcl_output o1.xyzw
+dcl_output o2.xyzw
+dcl_output o3.xyzw
+dcl_output o4.xyzw
+dcl_output oDepth
+mov o0.xyzw, cb0[0].xyzw
+mov o1.xyzw, cb0[0].xyzw
+mov o2.xyzw, cb0[0].xyzw
+mov o3.xyzw, cb0[0].xyzw
+mov o4.xyzw, cb0[0].xyzw
+mov oDepth, cb0[1].x
+ret 
+// Approximately 7 instruction slots used
+#endif
+
+const BYTE g_PS_ClearFloat5[] = {
+    68,  88,  66,  67,  110, 251, 0,   120, 207, 72,  250, 15,  78,  51,  222, 23,  61,  180, 247,
+    36,  1,   0,   0,   0,   160, 3,   0,   0,   5,   0,   0,   0,   52,  0,   0,   0,   72,  1,
+    0,   0,   124, 1,   0,   0,   48,  2,   0,   0,   36,  3,   0,   0,   82,  68,  69,  70,  12,
+    1,   0,   0,   1,   0,   0,   0,   84,  0,   0,   0,   1,   0,   0,   0,   28,  0,   0,   0,
+    0,   4,   255, 255, 0,   1,   0,   0,   216, 0,   0,   0,   60,  0,   0,   0,   0,   0,   0,
+    0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   1,   0,
+    0,   0,   1,   0,   0,   0,   67,  111, 108, 111, 114, 65,  110, 100, 68,  101, 112, 116, 104,
+    68,  97,  116, 97,  70,  108, 111, 97,  116, 0,   171, 60,  0,   0,   0,   2,   0,   0,   0,
+    108, 0,   0,   0,   32,  0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   156, 0,   0,
+    0,   0,   0,   0,   0,   16,  0,   0,   0,   2,   0,   0,   0,   168, 0,   0,   0,   0,   0,
+    0,   0,   184, 0,   0,   0,   16,  0,   0,   0,   4,   0,   0,   0,   2,   0,   0,   0,   200,
+    0,   0,   0,   0,   0,   0,   0,   99,  111, 108, 111, 114, 95,  70,  108, 111, 97,  116, 0,
+    1,   0,   3,   0,   1,   0,   4,   0,   0,   0,   0,   0,   0,   0,   0,   0,   122, 86,  97,
+    108, 117, 101, 70,  95,  70,  108, 111, 97,  116, 0,   171, 171, 0,   0,   3,   0,   1,   0,
+    1,   0,   0,   0,   0,   0,   0,   0,   0,   0,   77,  105, 99,  114, 111, 115, 111, 102, 116,
+    32,  40,  82,  41,  32,  72,  76,  83,  76,  32,  83,  104, 97,  100, 101, 114, 32,  67,  111,
+    109, 112, 105, 108, 101, 114, 32,  54,  46,  51,  46,  57,  54,  48,  48,  46,  49,  54,  51,
+    56,  52,  0,   171, 171, 73,  83,  71,  78,  44,  0,   0,   0,   1,   0,   0,   0,   8,   0,
+    0,   0,   32,  0,   0,   0,   0,   0,   0,   0,   1,   0,   0,   0,   3,   0,   0,   0,   0,
+    0,   0,   0,   15,  0,   0,   0,   83,  86,  95,  80,  79,  83,  73,  84,  73,  79,  78,  0,
+    79,  83,  71,  78,  172, 0,   0,   0,   6,   0,   0,   0,   8,   0,   0,   0,   152, 0,   0,
+    0,   0,   0,   0,   0,   0,   0,   0,   0,   3,   0,   0,   0,   0,   0,   0,   0,   15,  0,
+    0,   0,   152, 0,   0,   0,   1,   0,   0,   0,   0,   0,   0,   0,   3,   0,   0,   0,   1,
+    0,   0,   0,   15,  0,   0,   0,   152, 0,   0,   0,   2,   0,   0,   0,   0,   0,   0,   0,
+    3,   0,   0,   0,   2,   0,   0,   0,   15,  0,   0,   0,   152, 0,   0,   0,   3,   0,   0,
+    0,   0,   0,   0,   0,   3,   0,   0,   0,   3,   0,   0,   0,   15,  0,   0,   0,   152, 0,
+    0,   0,   4,   0,   0,   0,   0,   0,   0,   0,   3,   0,   0,   0,   4,   0,   0,   0,   15,
+    0,   0,   0,   162, 0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   3,   0,   0,   0,
+    255, 255, 255, 255, 1,   14,  0,   0,   83,  86,  95,  84,  65,  82,  71,  69,  84,  0,   83,
+    86,  95,  68,  69,  80,  84,  72,  0,   171, 83,  72,  68,  82,  236, 0,   0,   0,   64,  0,
+    0,   0,   59,  0,   0,   0,   89,  0,   0,   4,   70,  142, 32,  0,   0,   0,   0,   0,   2,
+    0,   0,   0,   101, 0,   0,   3,   242, 32,  16,  0,   0,   0,   0,   0,   101, 0,   0,   3,
+    242, 32,  16,  0,   1,   0,   0,   0,   101, 0,   0,   3,   242, 32,  16,  0,   2,   0,   0,
+    0,   101, 0,   0,   3,   242, 32,  16,  0,   3,   0,   0,   0,   101, 0,   0,   3,   242, 32,
+    16,  0,   4,   0,   0,   0,   101, 0,   0,   2,   1,   192, 0,   0,   54,  0,   0,   6,   242,
+    32,  16,  0,   0,   0,   0,   0,   70,  142, 32,  0,   0,   0,   0,   0,   0,   0,   0,   0,
+    54,  0,   0,   6,   242, 32,  16,  0,   1,   0,   0,   0,   70,  142, 32,  0,   0,   0,   0,
+    0,   0,   0,   0,   0,   54,  0,   0,   6,   242, 32,  16,  0,   2,   0,   0,   0,   70,  142,
+    32,  0,   0,   0,   0,   0,   0,   0,   0,   0,   54,  0,   0,   6,   242, 32,  16,  0,   3,
+    0,   0,   0,   70,  142, 32,  0,   0,   0,   0,   0,   0,   0,   0,   0,   54,  0,   0,   6,
+    242, 32,  16,  0,   4,   0,   0,   0,   70,  142, 32,  0,   0,   0,   0,   0,   0,   0,   0,
+    0,   54,  0,   0,   5,   1,   192, 0,   0,   10,  128, 32,  0,   0,   0,   0,   0,   1,   0,
+    0,   0,   62,  0,   0,   1,   83,  84,  65,  84,  116, 0,   0,   0,   7,   0,   0,   0,   0,
+    0,   0,   0,   0,   0,   0,   0,   6,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+    0,   0,   0,   0,   1,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+    0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+    0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   6,   0,   0,   0,   0,
+    0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+    0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0};
--- a/gfx/angle/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/clearfloat11ps6.h
+++ b/gfx/angle/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/clearfloat11ps6.h
@@ -1,116 +1,116 @@
-#if 0
-//
-// Generated by Microsoft (R) HLSL Shader Compiler 6.3.9600.16384
-//
-//
-// Buffer Definitions: 
-//
-// cbuffer ColorAndDepthDataFloat
-// {
-//
-//   float4 color_Float;                // Offset:    0 Size:    16
-//   float zValueF_Float;               // Offset:   16 Size:     4
-//
-// }
-//
-//
-// Resource Bindings:
-//
-// Name                                 Type  Format         Dim Slot Elements
-// ------------------------------ ---------- ------- ----------- ---- --------
-// ColorAndDepthDataFloat            cbuffer      NA          NA    0        1
-//
-//
-//
-// Input signature:
-//
-// Name                 Index   Mask Register SysValue  Format   Used
-// -------------------- ----- ------ -------- -------- ------- ------
-// SV_POSITION              0   xyzw        0      POS   float       
-//
-//
-// Output signature:
-//
-// Name                 Index   Mask Register SysValue  Format   Used
-// -------------------- ----- ------ -------- -------- ------- ------
-// SV_TARGET                0   xyzw        0   TARGET   float   xyzw
-// SV_TARGET                1   xyzw        1   TARGET   float   xyzw
-// SV_TARGET                2   xyzw        2   TARGET   float   xyzw
-// SV_TARGET                3   xyzw        3   TARGET   float   xyzw
-// SV_TARGET                4   xyzw        4   TARGET   float   xyzw
-// SV_TARGET                5   xyzw        5   TARGET   float   xyzw
-// SV_DEPTH                 0    N/A   oDepth    DEPTH   float    YES
-//
-ps_4_0
-dcl_constantbuffer cb0[2], immediateIndexed
-dcl_output o0.xyzw
-dcl_output o1.xyzw
-dcl_output o2.xyzw
-dcl_output o3.xyzw
-dcl_output o4.xyzw
-dcl_output o5.xyzw
-dcl_output oDepth
-mov o0.xyzw, cb0[0].xyzw
-mov o1.xyzw, cb0[0].xyzw
-mov o2.xyzw, cb0[0].xyzw
-mov o3.xyzw, cb0[0].xyzw
-mov o4.xyzw, cb0[0].xyzw
-mov o5.xyzw, cb0[0].xyzw
-mov oDepth, cb0[1].x
-ret 
-// Approximately 8 instruction slots used
-#endif
-
-const BYTE g_PS_ClearFloat6[] = {
-    68,  88,  66,  67,  89,  150, 245, 198, 63,  119, 94,  62,  185, 247, 214, 162, 19,  194, 96,
-    152, 1,   0,   0,   0,   220, 3,   0,   0,   5,   0,   0,   0,   52,  0,   0,   0,   72,  1,
-    0,   0,   124, 1,   0,   0,   72,  2,   0,   0,   96,  3,   0,   0,   82,  68,  69,  70,  12,
-    1,   0,   0,   1,   0,   0,   0,   84,  0,   0,   0,   1,   0,   0,   0,   28,  0,   0,   0,
-    0,   4,   255, 255, 0,   1,   0,   0,   216, 0,   0,   0,   60,  0,   0,   0,   0,   0,   0,
-    0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   1,   0,
-    0,   0,   1,   0,   0,   0,   67,  111, 108, 111, 114, 65,  110, 100, 68,  101, 112, 116, 104,
-    68,  97,  116, 97,  70,  108, 111, 97,  116, 0,   171, 60,  0,   0,   0,   2,   0,   0,   0,
-    108, 0,   0,   0,   32,  0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   156, 0,   0,
-    0,   0,   0,   0,   0,   16,  0,   0,   0,   2,   0,   0,   0,   168, 0,   0,   0,   0,   0,
-    0,   0,   184, 0,   0,   0,   16,  0,   0,   0,   4,   0,   0,   0,   2,   0,   0,   0,   200,
-    0,   0,   0,   0,   0,   0,   0,   99,  111, 108, 111, 114, 95,  70,  108, 111, 97,  116, 0,
-    1,   0,   3,   0,   1,   0,   4,   0,   0,   0,   0,   0,   0,   0,   0,   0,   122, 86,  97,
-    108, 117, 101, 70,  95,  70,  108, 111, 97,  116, 0,   171, 171, 0,   0,   3,   0,   1,   0,
-    1,   0,   0,   0,   0,   0,   0,   0,   0,   0,   77,  105, 99,  114, 111, 115, 111, 102, 116,
-    32,  40,  82,  41,  32,  72,  76,  83,  76,  32,  83,  104, 97,  100, 101, 114, 32,  67,  111,
-    109, 112, 105, 108, 101, 114, 32,  54,  46,  51,  46,  57,  54,  48,  48,  46,  49,  54,  51,
-    56,  52,  0,   171, 171, 73,  83,  71,  78,  44,  0,   0,   0,   1,   0,   0,   0,   8,   0,
-    0,   0,   32,  0,   0,   0,   0,   0,   0,   0,   1,   0,   0,   0,   3,   0,   0,   0,   0,
-    0,   0,   0,   15,  0,   0,   0,   83,  86,  95,  80,  79,  83,  73,  84,  73,  79,  78,  0,
-    79,  83,  71,  78,  196, 0,   0,   0,   7,   0,   0,   0,   8,   0,   0,   0,   176, 0,   0,
-    0,   0,   0,   0,   0,   0,   0,   0,   0,   3,   0,   0,   0,   0,   0,   0,   0,   15,  0,
-    0,   0,   176, 0,   0,   0,   1,   0,   0,   0,   0,   0,   0,   0,   3,   0,   0,   0,   1,
-    0,   0,   0,   15,  0,   0,   0,   176, 0,   0,   0,   2,   0,   0,   0,   0,   0,   0,   0,
-    3,   0,   0,   0,   2,   0,   0,   0,   15,  0,   0,   0,   176, 0,   0,   0,   3,   0,   0,
-    0,   0,   0,   0,   0,   3,   0,   0,   0,   3,   0,   0,   0,   15,  0,   0,   0,   176, 0,
-    0,   0,   4,   0,   0,   0,   0,   0,   0,   0,   3,   0,   0,   0,   4,   0,   0,   0,   15,
-    0,   0,   0,   176, 0,   0,   0,   5,   0,   0,   0,   0,   0,   0,   0,   3,   0,   0,   0,
-    5,   0,   0,   0,   15,  0,   0,   0,   186, 0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
-    0,   3,   0,   0,   0,   255, 255, 255, 255, 1,   14,  0,   0,   83,  86,  95,  84,  65,  82,
-    71,  69,  84,  0,   83,  86,  95,  68,  69,  80,  84,  72,  0,   171, 83,  72,  68,  82,  16,
-    1,   0,   0,   64,  0,   0,   0,   68,  0,   0,   0,   89,  0,   0,   4,   70,  142, 32,  0,
-    0,   0,   0,   0,   2,   0,   0,   0,   101, 0,   0,   3,   242, 32,  16,  0,   0,   0,   0,
-    0,   101, 0,   0,   3,   242, 32,  16,  0,   1,   0,   0,   0,   101, 0,   0,   3,   242, 32,
-    16,  0,   2,   0,   0,   0,   101, 0,   0,   3,   242, 32,  16,  0,   3,   0,   0,   0,   101,
-    0,   0,   3,   242, 32,  16,  0,   4,   0,   0,   0,   101, 0,   0,   3,   242, 32,  16,  0,
-    5,   0,   0,   0,   101, 0,   0,   2,   1,   192, 0,   0,   54,  0,   0,   6,   242, 32,  16,
-    0,   0,   0,   0,   0,   70,  142, 32,  0,   0,   0,   0,   0,   0,   0,   0,   0,   54,  0,
-    0,   6,   242, 32,  16,  0,   1,   0,   0,   0,   70,  142, 32,  0,   0,   0,   0,   0,   0,
-    0,   0,   0,   54,  0,   0,   6,   242, 32,  16,  0,   2,   0,   0,   0,   70,  142, 32,  0,
-    0,   0,   0,   0,   0,   0,   0,   0,   54,  0,   0,   6,   242, 32,  16,  0,   3,   0,   0,
-    0,   70,  142, 32,  0,   0,   0,   0,   0,   0,   0,   0,   0,   54,  0,   0,   6,   242, 32,
-    16,  0,   4,   0,   0,   0,   70,  142, 32,  0,   0,   0,   0,   0,   0,   0,   0,   0,   54,
-    0,   0,   6,   242, 32,  16,  0,   5,   0,   0,   0,   70,  142, 32,  0,   0,   0,   0,   0,
-    0,   0,   0,   0,   54,  0,   0,   5,   1,   192, 0,   0,   10,  128, 32,  0,   0,   0,   0,
-    0,   1,   0,   0,   0,   62,  0,   0,   1,   83,  84,  65,  84,  116, 0,   0,   0,   8,   0,
-    0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   7,   0,   0,   0,   0,   0,   0,   0,   0,
-    0,   0,   0,   0,   0,   0,   0,   1,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
-    0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
-    0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   7,   0,
-    0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
-    0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0};
+#if 0
+//
+// Generated by Microsoft (R) HLSL Shader Compiler 6.3.9600.16384
+//
+//
+// Buffer Definitions: 
+//
+// cbuffer ColorAndDepthDataFloat
+// {
+//
+//   float4 color_Float;                // Offset:    0 Size:    16
+//   float zValueF_Float;               // Offset:   16 Size:     4
+//
+// }
+//
+//
+// Resource Bindings:
+//
+// Name                                 Type  Format         Dim Slot Elements
+// ------------------------------ ---------- ------- ----------- ---- --------
+// ColorAndDepthDataFloat            cbuffer      NA          NA    0        1
+//
+//
+//
+// Input signature:
+//
+// Name                 Index   Mask Register SysValue  Format   Used
+// -------------------- ----- ------ -------- -------- ------- ------
+// SV_POSITION              0   xyzw        0      POS   float       
+//
+//
+// Output signature:
+//
+// Name                 Index   Mask Register SysValue  Format   Used
+// -------------------- ----- ------ -------- -------- ------- ------
+// SV_TARGET                0   xyzw        0   TARGET   float   xyzw
+// SV_TARGET                1   xyzw        1   TARGET   float   xyzw
+// SV_TARGET                2   xyzw        2   TARGET   float   xyzw
+// SV_TARGET                3   xyzw        3   TARGET   float   xyzw
+// SV_TARGET                4   xyzw        4   TARGET   float   xyzw
+// SV_TARGET                5   xyzw        5   TARGET   float   xyzw
+// SV_DEPTH                 0    N/A   oDepth    DEPTH   float    YES
+//
+ps_4_0
+dcl_constantbuffer cb0[2], immediateIndexed
+dcl_output o0.xyzw
+dcl_output o1.xyzw
+dcl_output o2.xyzw
+dcl_output o3.xyzw
+dcl_output o4.xyzw
+dcl_output o5.xyzw
+dcl_output oDepth
+mov o0.xyzw, cb0[0].xyzw
+mov o1.xyzw, cb0[0].xyzw
+mov o2.xyzw, cb0[0].xyzw
+mov o3.xyzw, cb0[0].xyzw
+mov o4.xyzw, cb0[0].xyzw
+mov o5.xyzw, cb0[0].xyzw
+mov oDepth, cb0[1].x
+ret 
+// Approximately 8 instruction slots used
+#endif
+
+const BYTE g_PS_ClearFloat6[] = {
+    68,  88,  66,  67,  89,  150, 245, 198, 63,  119, 94,  62,  185, 247, 214, 162, 19,  194, 96,
+    152, 1,   0,   0,   0,   220, 3,   0,   0,   5,   0,   0,   0,   52,  0,   0,   0,   72,  1,
+    0,   0,   124, 1,   0,   0,   72,  2,   0,   0,   96,  3,   0,   0,   82,  68,  69,  70,  12,
+    1,   0,   0,   1,   0,   0,   0,   84,  0,   0,   0,   1,   0,   0,   0,   28,  0,   0,   0,
+    0,   4,   255, 255, 0,   1,   0,   0,   216, 0,   0,   0,   60,  0,   0,   0,   0,   0,   0,
+    0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   1,   0,
+    0,   0,   1,   0,   0,   0,   67,  111, 108, 111, 114, 65,  110, 100, 68,  101, 112, 116, 104,
+    68,  97,  116, 97,  70,  108, 111, 97,  116, 0,   171, 60,  0,   0,   0,   2,   0,   0,   0,
+    108, 0,   0,   0,   32,  0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   156, 0,   0,
+    0,   0,   0,   0,   0,   16,  0,   0,   0,   2,   0,   0,   0,   168, 0,   0,   0,   0,   0,
+    0,   0,   184, 0,   0,   0,   16,  0,   0,   0,   4,   0,   0,   0,   2,   0,   0,   0,   200,
+    0,   0,   0,   0,   0,   0,   0,   99,  111, 108, 111, 114, 95,  70,  108, 111, 97,  116, 0,
+    1,   0,   3,   0,   1,   0,   4,   0,   0,   0,   0,   0,   0,   0,   0,   0,   122, 86,  97,
+    108, 117, 101, 70,  95,  70,  108, 111, 97,  116, 0,   171, 171, 0,   0,   3,   0,   1,   0,
+    1,   0,   0,   0,   0,   0,   0,   0,   0,   0,   77,  105, 99,  114, 111, 115, 111, 102, 116,
+    32,  40,  82,  41,  32,  72,  76,  83,  76,  32,  83,  104, 97,  100, 101, 114, 32,  67,  111,
+    109, 112, 105, 108, 101, 114, 32,  54,  46,  51,  46,  57,  54,  48,  48,  46,  49,  54,  51,
+    56,  52,  0,   171, 171, 73,  83,  71,  78,  44,  0,   0,   0,   1,   0,   0,   0,   8,   0,
+    0,   0,   32,  0,   0,   0,   0,   0,   0,   0,   1,   0,   0,   0,   3,   0,   0,   0,   0,
+    0,   0,   0,   15,  0,   0,   0,   83,  86,  95,  80,  79,  83,  73,  84,  73,  79,  78,  0,
+    79,  83,  71,  78,  196, 0,   0,   0,   7,   0,   0,   0,   8,   0,   0,   0,   176, 0,   0,
+    0,   0,   0,   0,   0,   0,   0,   0,   0,   3,   0,   0,   0,   0,   0,   0,   0,   15,  0,
+    0,   0,   176, 0,   0,   0,   1,   0,   0,   0,   0,   0,   0,   0,   3,   0,   0,   0,   1,
+    0,   0,   0,   15,  0,   0,   0,   176, 0,   0,   0,   2,   0,   0,   0,   0,   0,   0,   0,
+    3,   0,   0,   0,   2,   0,   0,   0,   15,  0,   0,   0,   176, 0,   0,   0,   3,   0,   0,
+    0,   0,   0,   0,   0,   3,   0,   0,   0,   3,   0,   0,   0,   15,  0,   0,   0,   176, 0,
+    0,   0,   4,   0,   0,   0,   0,   0,   0,   0,   3,   0,   0,   0,   4,   0,   0,   0,   15,
+    0,   0,   0,   176, 0,   0,   0,   5,   0,   0,   0,   0,   0,   0,   0,   3,   0,   0,   0,
+    5,   0,   0,   0,   15,  0,   0,   0,   186, 0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+    0,   3,   0,   0,   0,   255, 255, 255, 255, 1,   14,  0,   0,   83,  86,  95,  84,  65,  82,
+    71,  69,  84,  0,   83,  86,  95,  68,  69,  80,  84,  72,  0,   171, 83,  72,  68,  82,  16,
+    1,   0,   0,   64,  0,   0,   0,   68,  0,   0,   0,   89,  0,   0,   4,   70,  142, 32,  0,
+    0,   0,   0,   0,   2,   0,   0,   0,   101, 0,   0,   3,   242, 32,  16,  0,   0,   0,   0,
+    0,   101, 0,   0,   3,   242, 32,  16,  0,   1,   0,   0,   0,   101, 0,   0,   3,   242, 32,
+    16,  0,   2,   0,   0,   0,   101, 0,   0,   3,   242, 32,  16,  0,   3,   0,   0,   0,   101,
+    0,   0,   3,   242, 32,  16,  0,   4,   0,   0,   0,   101, 0,   0,   3,   242, 32,  16,  0,
+    5,   0,   0,   0,   101, 0,   0,   2,   1,   192, 0,   0,   54,  0,   0,   6,   242, 32,  16,
+    0,   0,   0,   0,   0,   70,  142, 32,  0,   0,   0,   0,   0,   0,   0,   0,   0,   54,  0,
+    0,   6,   242, 32,  16,  0,   1,   0,   0,   0,   70,  142, 32,  0,   0,   0,   0,   0,   0,
+    0,   0,   0,   54,  0,   0,   6,   242, 32,  16,  0,   2,   0,   0,   0,   70,  142, 32,  0,
+    0,   0,   0,   0,   0,   0,   0,   0,   54,  0,   0,   6,   242, 32,  16,  0,   3,   0,   0,
+    0,   70,  142, 32,  0,   0,   0,   0,   0,   0,   0,   0,   0,   54,  0,   0,   6,   242, 32,
+    16,  0,   4,   0,   0,   0,   70,  142, 32,  0,   0,   0,   0,   0,   0,   0,   0,   0,   54,
+    0,   0,   6,   242, 32,  16,  0,   5,   0,   0,   0,   70,  142, 32,  0,   0,   0,   0,   0,
+    0,   0,   0,   0,   54,  0,   0,   5,   1,   192, 0,   0,   10,  128, 32,  0,   0,   0,   0,
+    0,   1,   0,   0,   0,   62,  0,   0,   1,   83,  84,  65,  84,  116, 0,   0,   0,   8,   0,
+    0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   7,   0,   0,   0,   0,   0,   0,   0,   0,
+    0,   0,   0,   0,   0,   0,   0,   1,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+    0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+    0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   7,   0,
+    0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+    0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0};
--- a/gfx/angle/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/clearfloat11ps7.h
+++ b/gfx/angle/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/clearfloat11ps7.h
@@ -1,123 +1,123 @@
-#if 0
-//
-// Generated by Microsoft (R) HLSL Shader Compiler 6.3.9600.16384
-//
-//
-// Buffer Definitions: 
-//
-// cbuffer ColorAndDepthDataFloat
-// {
-//
-//   float4 color_Float;                // Offset:    0 Size:    16
-//   float zValueF_Float;               // Offset:   16 Size:     4
-//
-// }
-//
-//
-// Resource Bindings:
-//
-// Name                                 Type  Format         Dim Slot Elements
-// ------------------------------ ---------- ------- ----------- ---- --------
-// ColorAndDepthDataFloat            cbuffer      NA          NA    0        1
-//
-//
-//
-// Input signature:
-//
-// Name                 Index   Mask Register SysValue  Format   Used
-// -------------------- ----- ------ -------- -------- ------- ------
-// SV_POSITION              0   xyzw        0      POS   float       
-//
-//
-// Output signature:
-//
-// Name                 Index   Mask Register SysValue  Format   Used
-// -------------------- ----- ------ -------- -------- ------- ------
-// SV_TARGET                0   xyzw        0   TARGET   float   xyzw
-// SV_TARGET                1   xyzw        1   TARGET   float   xyzw
-// SV_TARGET                2   xyzw        2   TARGET   float   xyzw
-// SV_TARGET                3   xyzw        3   TARGET   float   xyzw
-// SV_TARGET                4   xyzw        4   TARGET   float   xyzw
-// SV_TARGET                5   xyzw        5   TARGET   float   xyzw
-// SV_TARGET                6   xyzw        6   TARGET   float   xyzw
-// SV_DEPTH                 0    N/A   oDepth    DEPTH   float    YES
-//
-ps_4_0
-dcl_constantbuffer cb0[2], immediateIndexed
-dcl_output o0.xyzw
-dcl_output o1.xyzw
-dcl_output o2.xyzw
-dcl_output o3.xyzw
-dcl_output o4.xyzw
-dcl_output o5.xyzw
-dcl_output o6.xyzw
-dcl_output oDepth
-mov o0.xyzw, cb0[0].xyzw
-mov o1.xyzw, cb0[0].xyzw
-mov o2.xyzw, cb0[0].xyzw
-mov o3.xyzw, cb0[0].xyzw
-mov o4.xyzw, cb0[0].xyzw
-mov o5.xyzw, cb0[0].xyzw
-mov o6.xyzw, cb0[0].xyzw
-mov oDepth, cb0[1].x
-ret 
-// Approximately 9 instruction slots used
-#endif
-
-const BYTE g_PS_ClearFloat7[] = {
-    68,  88,  66,  67,  148, 239, 191, 126, 102, 53,  77,  186, 61,  158, 28,  92,  123, 95,  81,
-    17,  1,   0,   0,   0,   24,  4,   0,   0,   5,   0,   0,   0,   52,  0,   0,   0,   72,  1,
-    0,   0,   124, 1,   0,   0,   96,  2,   0,   0,   156, 3,   0,   0,   82,  68,  69,  70,  12,
-    1,   0,   0,   1,   0,   0,   0,   84,  0,   0,   0,   1,   0,   0,   0,   28,  0,   0,   0,
-    0,   4,   255, 255, 0,   1,   0,   0,   216, 0,   0,   0,   60,  0,   0,   0,   0,   0,   0,
-    0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   1,   0,
-    0,   0,   1,   0,   0,   0,   67,  111, 108, 111, 114, 65,  110, 100, 68,  101, 112, 116, 104,
-    68,  97,  116, 97,  70,  108, 111, 97,  116, 0,   171, 60,  0,   0,   0,   2,   0,   0,   0,
-    108, 0,   0,   0,   32,  0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   156, 0,   0,
-    0,   0,   0,   0,   0,   16,  0,   0,   0,   2,   0,   0,   0,   168, 0,   0,   0,   0,   0,
-    0,   0,   184, 0,   0,   0,   16,  0,   0,   0,   4,   0,   0,   0,   2,   0,   0,   0,   200,
-    0,   0,   0,   0,   0,   0,   0,   99,  111, 108, 111, 114, 95,  70,  108, 111, 97,  116, 0,
-    1,   0,   3,   0,   1,   0,   4,   0,   0,   0,   0,   0,   0,   0,   0,   0,   122, 86,  97,
-    108, 117, 101, 70,  95,  70,  108, 111, 97,  116, 0,   171, 171, 0,   0,   3,   0,   1,   0,
-    1,   0,   0,   0,   0,   0,   0,   0,   0,   0,   77,  105, 99,  114, 111, 115, 111, 102, 116,
-    32,  40,  82,  41,  32,  72,  76,  83,  76,  32,  83,  104, 97,  100, 101, 114, 32,  67,  111,
-    109, 112, 105, 108, 101, 114, 32,  54,  46,  51,  46,  57,  54,  48,  48,  46,  49,  54,  51,
-    56,  52,  0,   171, 171, 73,  83,  71,  78,  44,  0,   0,   0,   1,   0,   0,   0,   8,   0,
-    0,   0,   32,  0,   0,   0,   0,   0,   0,   0,   1,   0,   0,   0,   3,   0,   0,   0,   0,
-    0,   0,   0,   15,  0,   0,   0,   83,  86,  95,  80,  79,  83,  73,  84,  73,  79,  78,  0,
-    79,  83,  71,  78,  220, 0,   0,   0,   8,   0,   0,   0,   8,   0,   0,   0,   200, 0,   0,
-    0,   0,   0,   0,   0,   0,   0,   0,   0,   3,   0,   0,   0,   0,   0,   0,   0,   15,  0,
-    0,   0,   200, 0,   0,   0,   1,   0,   0,   0,   0,   0,   0,   0,   3,   0,   0,   0,   1,
-    0,   0,   0,   15,  0,   0,   0,   200, 0,   0,   0,   2,   0,   0,   0,   0,   0,   0,   0,
-    3,   0,   0,   0,   2,   0,   0,   0,   15,  0,   0,   0,   200, 0,   0,   0,   3,   0,   0,
-    0,   0,   0,   0,   0,   3,   0,   0,   0,   3,   0,   0,   0,   15,  0,   0,   0,   200, 0,
-    0,   0,   4,   0,   0,   0,   0,   0,   0,   0,   3,   0,   0,   0,   4,   0,   0,   0,   15,
-    0,   0,   0,   200, 0,   0,   0,   5,   0,   0,   0,   0,   0,   0,   0,   3,   0,   0,   0,
-    5,   0,   0,   0,   15,  0,   0,   0,   200, 0,   0,   0,   6,   0,   0,   0,   0,   0,   0,
-    0,   3,   0,   0,   0,   6,   0,   0,   0,   15,  0,   0,   0,   210, 0,   0,   0,   0,   0,
-    0,   0,   0,   0,   0,   0,   3,   0,   0,   0,   255, 255, 255, 255, 1,   14,  0,   0,   83,
-    86,  95,  84,  65,  82,  71,  69,  84,  0,   83,  86,  95,  68,  69,  80,  84,  72,  0,   171,
-    83,  72,  68,  82,  52,  1,   0,   0,   64,  0,   0,   0,   77,  0,   0,   0,   89,  0,   0,
-    4,   70,  142, 32,  0,   0,   0,   0,   0,   2,   0,   0,   0,   101, 0,   0,   3,   242, 32,
-    16,  0,   0,   0,   0,   0,   101, 0,   0,   3,   242, 32,  16,  0,   1,   0,   0,   0,   101,
-    0,   0,   3,   242, 32,  16,  0,   2,   0,   0,   0,   101, 0,   0,   3,   242, 32,  16,  0,
-    3,   0,   0,   0,   101, 0,   0,   3,   242, 32,  16,  0,   4,   0,   0,   0,   101, 0,   0,
-    3,   242, 32,  16,  0,   5,   0,   0,   0,   101, 0,   0,   3,   242, 32,  16,  0,   6,   0,
-    0,   0,   101, 0,   0,   2,   1,   192, 0,   0,   54,  0,   0,   6,   242, 32,  16,  0,   0,
-    0,   0,   0,   70,  142, 32,  0,   0,   0,   0,   0,   0,   0,   0,   0,   54,  0,   0,   6,
-    242, 32,  16,  0,   1,   0,   0,   0,   70,  142, 32,  0,   0,   0,   0,   0,   0,   0,   0,
-    0,   54,  0,   0,   6,   242, 32,  16,  0,   2,   0,   0,   0,   70,  142, 32,  0,   0,   0,
-    0,   0,   0,   0,   0,   0,   54,  0,   0,   6,   242, 32,  16,  0,   3,   0,   0,   0,   70,
-    142, 32,  0,   0,   0,   0,   0,   0,   0,   0,   0,   54,  0,   0,   6,   242, 32,  16,  0,
-    4,   0,   0,   0,   70,  142, 32,  0,   0,   0,   0,   0,   0,   0,   0,   0,   54,  0,   0,
-    6,   242, 32,  16,  0,   5,   0,   0,   0,   70,  142, 32,  0,   0,   0,   0,   0,   0,   0,
-    0,   0,   54,  0,   0,   6,   242, 32,  16,  0,   6,   0,   0,   0,   70,  142, 32,  0,   0,
-    0,   0,   0,   0,   0,   0,   0,   54,  0,   0,   5,   1,   192, 0,   0,   10,  128, 32,  0,
-    0,   0,   0,   0,   1,   0,   0,   0,   62,  0,   0,   1,   83,  84,  65,  84,  116, 0,   0,
-    0,   9,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   8,   0,   0,   0,   0,   0,
-    0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   1,   0,   0,   0,   0,   0,   0,   0,   0,
-    0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
-    0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
-    0,   8,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
-    0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
-    0,   0,   0};
+#if 0
+//
+// Generated by Microsoft (R) HLSL Shader Compiler 6.3.9600.16384
+//
+//
+// Buffer Definitions: 
+//
+// cbuffer ColorAndDepthDataFloat
+// {
+//
+//   float4 color_Float;                // Offset:    0 Size:    16
+//   float zValueF_Float;               // Offset:   16 Size:     4
+//
+// }
+//
+//
+// Resource Bindings:
+//
+// Name                                 Type  Format         Dim Slot Elements
+// ------------------------------ ---------- ------- ----------- ---- --------
+// ColorAndDepthDataFloat            cbuffer      NA          NA    0        1
+//
+//
+//
+// Input signature:
+//
+// Name                 Index   Mask Register SysValue  Format   Used
+// -------------------- ----- ------ -------- -------- ------- ------
+// SV_POSITION              0   xyzw        0      POS   float       
+//
+//
+// Output signature:
+//
+// Name                 Index   Mask Register SysValue  Format   Used
+// -------------------- ----- ------ -------- -------- ------- ------
+// SV_TARGET                0   xyzw        0   TARGET   float   xyzw
+// SV_TARGET                1   xyzw        1   TARGET   float   xyzw
+// SV_TARGET                2   xyzw        2   TARGET   float   xyzw
+// SV_TARGET                3   xyzw        3   TARGET   float   xyzw
+// SV_TARGET                4   xyzw        4   TARGET   float   xyzw
+// SV_TARGET                5   xyzw        5   TARGET   float   xyzw
+// SV_TARGET                6   xyzw        6   TARGET   float   xyzw
+// SV_DEPTH                 0    N/A   oDepth    DEPTH   float    YES
+//
+ps_4_0
+dcl_constantbuffer cb0[2], immediateIndexed
+dcl_output o0.xyzw
+dcl_output o1.xyzw
+dcl_output o2.xyzw
+dcl_output o3.xyzw
+dcl_output o4.xyzw
+dcl_output o5.xyzw
+dcl_output o6.xyzw
+dcl_output oDepth
+mov o0.xyzw, cb0[0].xyzw
+mov o1.xyzw, cb0[0].xyzw
+mov o2.xyzw, cb0[0].xyzw
+mov o3.xyzw, cb0[0].xyzw
+mov o4.xyzw, cb0[0].xyzw
+mov o5.xyzw, cb0[0].xyzw
+mov o6.xyzw, cb0[0].xyzw
+mov oDepth, cb0[1].x
+ret 
+// Approximately 9 instruction slots used
+#endif
+
+const BYTE g_PS_ClearFloat7[] = {
+    68,  88,  66,  67,  148, 239, 191, 126, 102, 53,  77,  186, 61,  158, 28,  92,  123, 95,  81,
+    17,  1,   0,   0,   0,   24,  4,   0,   0,   5,   0,   0,   0,   52,  0,   0,   0,   72,  1,
+    0,   0,   124, 1,   0,   0,   96,  2,   0,   0,   156, 3,   0,   0,   82,  68,  69,  70,  12,
+    1,   0,   0,   1,   0,   0,   0,   84,  0,   0,   0,   1,   0,   0,   0,   28,  0,   0,   0,
+    0,   4,   255, 255, 0,   1,   0,   0,   216, 0,   0,   0,   60,  0,   0,   0,   0,   0,   0,
+    0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   1,   0,
+    0,   0,   1,   0,   0,   0,   67,  111, 108, 111, 114, 65,  110, 100, 68,  101, 112, 116, 104,
+    68,  97,  116, 97,  70,  108, 111, 97,  116, 0,   171, 60,  0,   0,   0,   2,   0,   0,   0,
+    108, 0,   0,   0,   32,  0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   156, 0,   0,
+    0,   0,   0,   0,   0,   16,  0,   0,   0,   2,   0,   0,   0,   168, 0,   0,   0,   0,   0,
+    0,   0,   184, 0,   0,   0,   16,  0,   0,   0,   4,   0,   0,   0,   2,   0,   0,   0,   200,
+    0,   0,   0,   0,   0,   0,   0,   99,  111, 108, 111, 114, 95,  70,  108, 111, 97,  116, 0,
+    1,   0,   3,   0,   1,   0,   4,   0,   0,   0,   0,   0,   0,   0,   0,   0,   122, 86,  97,
+    108, 117, 101, 70,  95,  70,  108, 111, 97,  116, 0,   171, 171, 0,   0,   3,   0,   1,   0,
+    1,   0,   0,   0,   0,   0,   0,   0,   0,   0,   77,  105, 99,  114, 111, 115, 111, 102, 116,
+    32,  40,  82,  41,  32,  72,  76,  83,  76,  32,  83,  104, 97,  100, 101, 114, 32,  67,  111,
+    109, 112, 105, 108, 101, 114, 32,  54,  46,  51,  46,  57,  54,  48,  48,  46,  49,  54,  51,
+    56,  52,  0,   171, 171, 73,  83,  71,  78,  44,  0,   0,   0,   1,   0,   0,   0,   8,   0,
+    0,   0,   32,  0,   0,   0,   0,   0,   0,   0,   1,   0,   0,   0,   3,   0,   0,   0,   0,
+    0,   0,   0,   15,  0,   0,   0,   83,  86,  95,  80,  79,  83,  73,  84,  73,  79,  78,  0,
+    79,  83,  71,  78,  220, 0,   0,   0,   8,   0,   0,   0,   8,   0,   0,   0,   200, 0,   0,
+    0,   0,   0,   0,   0,   0,   0,   0,   0,   3,   0,   0,   0,   0,   0,   0,   0,   15,  0,
+    0,   0,   200, 0,   0,   0,   1,   0,   0,   0,   0,   0,   0,   0,   3,   0,   0,   0,   1,
+    0,   0,   0,   15,  0,   0,   0,   200, 0,   0,   0,   2,   0,   0,   0,   0,   0,   0,   0,
+    3,   0,   0,   0,   2,   0,   0,   0,   15,  0,   0,   0,   200, 0,   0,   0,   3,   0,   0,
+    0,   0,   0,   0,   0,   3,   0,   0,   0,   3,   0,   0,   0,   15,  0,   0,   0,   200, 0,
+    0,   0,   4,   0,   0,   0,   0,   0,   0,   0,   3,   0,   0,   0,   4,   0,   0,   0,   15,
+    0,   0,   0,   200, 0,   0,   0,   5,   0,   0,   0,   0,   0,   0,   0,   3,   0,   0,   0,
+    5,   0,   0,   0,   15,  0,   0,   0,   200, 0,   0,   0,   6,   0,   0,   0,   0,   0,   0,
+    0,   3,   0,   0,   0,   6,   0,   0,   0,   15,  0,   0,   0,   210, 0,   0,   0,   0,   0,
+    0,   0,   0,   0,   0,   0,   3,   0,   0,   0,   255, 255, 255, 255, 1,   14,  0,   0,   83,
+    86,  95,  84,  65,  82,  71,  69,  84,  0,   83,  86,  95,  68,  69,  80,  84,  72,  0,   171,
+    83,  72,  68,  82,  52,  1,   0,   0,   64,  0,   0,   0,   77,  0,   0,   0,   89,  0,   0,
+    4,   70,  142, 32,  0,   0,   0,   0,   0,   2,   0,   0,   0,   101, 0,   0,   3,   242, 32,
+    16,  0,   0,   0,   0,   0,   101, 0,   0,   3,   242, 32,  16,  0,   1,   0,   0,   0,   101,
+    0,   0,   3,   242, 32,  16,  0,   2,   0,   0,   0,   101, 0,   0,   3,   242, 32,  16,  0,
+    3,   0,   0,   0,   101, 0,   0,   3,   242, 32,  16,  0,   4,   0,   0,   0,   101, 0,   0,
+    3,   242, 32,  16,  0,   5,   0,   0,   0,   101, 0,   0,   3,   242, 32,  16,  0,   6,   0,
+    0,   0,   101, 0,   0,   2,   1,   192, 0,   0,   54,  0,   0,   6,   242, 32,  16,  0,   0,
+    0,   0,   0,   70,  142, 32,  0,   0,   0,   0,   0,   0,   0,   0,   0,   54,  0,   0,   6,
+    242, 32,  16,  0,   1,   0,   0,   0,   70,  142, 32,  0,   0,   0,   0,   0,   0,   0,   0,
+    0,   54,  0,   0,   6,   242, 32,  16,  0,   2,   0,   0,   0,   70,  142, 32,  0,   0,   0,
+    0,   0,   0,   0,   0,   0,   54,  0,   0,   6,   242, 32,  16,  0,   3,   0,   0,   0,   70,
+    142, 32,  0,   0,   0,   0,   0,   0,   0,   0,   0,   54,  0,   0,   6,   242, 32,  16,  0,
+    4,   0,   0,   0,   70,  142, 32,  0,   0,   0,   0,   0,   0,   0,   0,   0,   54,  0,   0,
+    6,   242, 32,  16,  0,   5,   0,   0,   0,   70,  142, 32,  0,   0,   0,   0,   0,   0,   0,
+    0,   0,   54,  0,   0,   6,   242, 32,  16,  0,   6,   0,   0,   0,   70,  142, 32,  0,   0,
+    0,   0,   0,   0,   0,   0,   0,   54,  0,   0,   5,   1,   192, 0,   0,   10,  128, 32,  0,
+    0,   0,   0,   0,   1,   0,   0,   0,   62,  0,   0,   1,   83,  84,  65,  84,  116, 0,   0,
+    0,   9,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   8,   0,   0,   0,   0,   0,
+    0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   1,   0,   0,   0,   0,   0,   0,   0,   0,
+    0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+    0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+    0,   8,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+    0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+    0,   0,   0};
--- a/gfx/angle/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/clearfloat11ps8.h
+++ b/gfx/angle/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/clearfloat11ps8.h
@@ -1,129 +1,129 @@
-#if 0
-//
-// Generated by Microsoft (R) HLSL Shader Compiler 6.3.9600.16384
-//
-//
-// Buffer Definitions: 
-//
-// cbuffer ColorAndDepthDataFloat
-// {
-//
-//   float4 color_Float;                // Offset:    0 Size:    16
-//   float zValueF_Float;               // Offset:   16 Size:     4
-//
-// }
-//
-//
-// Resource Bindings:
-//
-// Name                                 Type  Format         Dim Slot Elements
-// ------------------------------ ---------- ------- ----------- ---- --------
-// ColorAndDepthDataFloat            cbuffer      NA          NA    0        1
-//
-//
-//
-// Input signature:
-//
-// Name                 Index   Mask Register SysValue  Format   Used
-// -------------------- ----- ------ -------- -------- ------- ------
-// SV_POSITION              0   xyzw        0      POS   float       
-//
-//
-// Output signature:
-//
-// Name                 Index   Mask Register SysValue  Format   Used
-// -------------------- ----- ------ -------- -------- ------- ------
-// SV_TARGET                0   xyzw        0   TARGET   float   xyzw
-// SV_TARGET                1   xyzw        1   TARGET   float   xyzw
-// SV_TARGET                2   xyzw        2   TARGET   float   xyzw
-// SV_TARGET                3   xyzw        3   TARGET   float   xyzw
-// SV_TARGET                4   xyzw        4   TARGET   float   xyzw
-// SV_TARGET                5   xyzw        5   TARGET   float   xyzw
-// SV_TARGET                6   xyzw        6   TARGET   float   xyzw
-// SV_TARGET                7   xyzw        7   TARGET   float   xyzw
-// SV_DEPTH                 0    N/A   oDepth    DEPTH   float    YES
-//
-ps_4_0
-dcl_constantbuffer cb0[2], immediateIndexed
-dcl_output o0.xyzw
-dcl_output o1.xyzw
-dcl_output o2.xyzw
-dcl_output o3.xyzw
-dcl_output o4.xyzw
-dcl_output o5.xyzw
-dcl_output o6.xyzw
-dcl_output o7.xyzw
-dcl_output oDepth
-mov o0.xyzw, cb0[0].xyzw
-mov o1.xyzw, cb0[0].xyzw
-mov o2.xyzw, cb0[0].xyzw
-mov o3.xyzw, cb0[0].xyzw
-mov o4.xyzw, cb0[0].xyzw
-mov o5.xyzw, cb0[0].xyzw
-mov o6.xyzw, cb0[0].xyzw
-mov o7.xyzw, cb0[0].xyzw
-mov oDepth, cb0[1].x
-ret 
-// Approximately 10 instruction slots used
-#endif
-
-const BYTE g_PS_ClearFloat8[] = {
-    68,  88,  66,  67,  0,   45,  15,  86,  227, 217, 47,  173, 72,  182, 197, 224, 178, 165, 77,
-    73,  1,   0,   0,   0,   84,  4,   0,   0,   5,   0,   0,   0,   52,  0,   0,   0,   72,  1,
-    0,   0,   124, 1,   0,   0,   120, 2,   0,   0,   216, 3,   0,   0,   82,  68,  69,  70,  12,
-    1,   0,   0,   1,   0,   0,   0,   84,  0,   0,   0,   1,   0,   0,   0,   28,  0,   0,   0,
-    0,   4,   255, 255, 0,   1,   0,   0,   216, 0,   0,   0,   60,  0,   0,   0,   0,   0,   0,
-    0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   1,   0,
-    0,   0,   1,   0,   0,   0,   67,  111, 108, 111, 114, 65,  110, 100, 68,  101, 112, 116, 104,
-    68,  97,  116, 97,  70,  108, 111, 97,  116, 0,   171, 60,  0,   0,   0,   2,   0,   0,   0,
-    108, 0,   0,   0,   32,  0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   156, 0,   0,
-    0,   0,   0,   0,   0,   16,  0,   0,   0,   2,   0,   0,   0,   168, 0,   0,   0,   0,   0,
-    0,   0,   184, 0,   0,   0,   16,  0,   0,   0,   4,   0,   0,   0,   2,   0,   0,   0,   200,
-    0,   0,   0,   0,   0,   0,   0,   99,  111, 108, 111, 114, 95,  70,  108, 111, 97,  116, 0,
-    1,   0,   3,   0,   1,   0,   4,   0,   0,   0,   0,   0,   0,   0,   0,   0,   122, 86,  97,
-    108, 117, 101, 70,  95,  70,  108, 111, 97,  116, 0,   171, 171, 0,   0,   3,   0,   1,   0,
-    1,   0,   0,   0,   0,   0,   0,   0,   0,   0,   77,  105, 99,  114, 111, 115, 111, 102, 116,
-    32,  40,  82,  41,  32,  72,  76,  83,  76,  32,  83,  104, 97,  100, 101, 114, 32,  67,  111,
-    109, 112, 105, 108, 101, 114, 32,  54,  46,  51,  46,  57,  54,  48,  48,  46,  49,  54,  51,
-    56,  52,  0,   171, 171, 73,  83,  71,  78,  44,  0,   0,   0,   1,   0,   0,   0,   8,   0,
-    0,   0,   32,  0,   0,   0,   0,   0,   0,   0,   1,   0,   0,   0,   3,   0,   0,   0,   0,
-    0,   0,   0,   15,  0,   0,   0,   83,  86,  95,  80,  79,  83,  73,  84,  73,  79,  78,  0,
-    79,  83,  71,  78,  244, 0,   0,   0,   9,   0,   0,   0,   8,   0,   0,   0,   224, 0,   0,
-    0,   0,   0,   0,   0,   0,   0,   0,   0,   3,   0,   0,   0,   0,   0,   0,   0,   15,  0,
-    0,   0,   224, 0,   0,   0,   1,   0,   0,   0,   0,   0,   0,   0,   3,   0,   0,   0,   1,
-    0,   0,   0,   15,  0,   0,   0,   224, 0,   0,   0,   2,   0,   0,   0,   0,   0,   0,   0,
-    3,   0,   0,   0,   2,   0,   0,   0,   15,  0,   0,   0,   224, 0,   0,   0,   3,   0,   0,
-    0,   0,   0,   0,   0,   3,   0,   0,   0,   3,   0,   0,   0,   15,  0,   0,   0,   224, 0,
-    0,   0,   4,   0,   0,   0,   0,   0,   0,   0,   3,   0,   0,   0,   4,   0,   0,   0,   15,
-    0,   0,   0,   224, 0,   0,   0,   5,   0,   0,   0,   0,   0,   0,   0,   3,   0,   0,   0,
-    5,   0,   0,   0,   15,  0,   0,   0,   224, 0,   0,   0,   6,   0,   0,   0,   0,   0,   0,
-    0,   3,   0,   0,   0,   6,   0,   0,   0,   15,  0,   0,   0,   224, 0,   0,   0,   7,   0,
-    0,   0,   0,   0,   0,   0,   3,   0,   0,   0,   7,   0,   0,   0,   15,  0,   0,   0,   234,
-    0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   3,   0,   0,   0,   255, 255, 255, 255,
-    1,   14,  0,   0,   83,  86,  95,  84,  65,  82,  71,  69,  84,  0,   83,  86,  95,  68,  69,
-    80,  84,  72,  0,   171, 83,  72,  68,  82,  88,  1,   0,   0,   64,  0,   0,   0,   86,  0,
-    0,   0,   89,  0,   0,   4,   70,  142, 32,  0,   0,   0,   0,   0,   2,   0,   0,   0,   101,
-    0,   0,   3,   242, 32,  16,  0,   0,   0,   0,   0,   101, 0,   0,   3,   242, 32,  16,  0,
-    1,   0,   0,   0,   101, 0,   0,   3,   242, 32,  16,  0,   2,   0,   0,   0,   101, 0,   0,
-    3,   242, 32,  16,  0,   3,   0,   0,   0,   101, 0,   0,   3,   242, 32,  16,  0,   4,   0,
-    0,   0,   101, 0,   0,   3,   242, 32,  16,  0,   5,   0,   0,   0,   101, 0,   0,   3,   242,
-    32,  16,  0,   6,   0,   0,   0,   101, 0,   0,   3,   242, 32,  16,  0,   7,   0,   0,   0,
-    101, 0,   0,   2,   1,   192, 0,   0,   54,  0,   0,   6,   242, 32,  16,  0,   0,   0,   0,
-    0,   70,  142, 32,  0,   0,   0,   0,   0,   0,   0,   0,   0,   54,  0,   0,   6,   242, 32,
-    16,  0,   1,   0,   0,   0,   70,  142, 32,  0,   0,   0,   0,   0,   0,   0,   0,   0,   54,
-    0,   0,   6,   242, 32,  16,  0,   2,   0,   0,   0,   70,  142, 32,  0,   0,   0,   0,   0,
-    0,   0,   0,   0,   54,  0,   0,   6,   242, 32,  16,  0,   3,   0,   0,   0,   70,  142, 32,
-    0,   0,   0,   0,   0,   0,   0,   0,   0,   54,  0,   0,   6,   242, 32,  16,  0,   4,   0,
-    0,   0,   70,  142, 32,  0,   0,   0,   0,   0,   0,   0,   0,   0,   54,  0,   0,   6,   242,
-    32,  16,  0,   5,   0,   0,   0,   70,  142, 32,  0,   0,   0,   0,   0,   0,   0,   0,   0,
-    54,  0,   0,   6,   242, 32,  16,  0,   6,   0,   0,   0,   70,  142, 32,  0,   0,   0,   0,
-    0,   0,   0,   0,   0,   54,  0,   0,   6,   242, 32,  16,  0,   7,   0,   0,   0,   70,  142,
-    32,  0,   0,   0,   0,   0,   0,   0,   0,   0,   54,  0,   0,   5,   1,   192, 0,   0,   10,
-    128, 32,  0,   0,   0,   0,   0,   1,   0,   0,   0,   62,  0,   0,   1,   83,  84,  65,  84,
-    116, 0,   0,   0,   10,  0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   9,   0,   0,
-    0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   1,   0,   0,   0,   0,   0,
-    0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
-    0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
-    0,   0,   0,   0,   9,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
-    0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
-    0,   0,   0,   0,   0,   0};
+#if 0
+//
+// Generated by Microsoft (R) HLSL Shader Compiler 6.3.9600.16384
+//
+//
+// Buffer Definitions: 
+//
+// cbuffer ColorAndDepthDataFloat
+// {
+//
+//   float4 color_Float;                // Offset:    0 Size:    16
+//   float zValueF_Float;               // Offset:   16 Size:     4
+//
+// }
+//
+//
+// Resource Bindings:
+//
+// Name                                 Type  Format         Dim Slot Elements
+// ------------------------------ ---------- ------- ----------- ---- --------
+// ColorAndDepthDataFloat            cbuffer      NA          NA    0        1
+//
+//
+//
+// Input signature:
+//
+// Name                 Index   Mask Register SysValue  Format   Used
+// -------------------- ----- ------ -------- -------- ------- ------
+// SV_POSITION              0   xyzw        0      POS   float       
+//
+//
+// Output signature:
+//
+// Name                 Index   Mask Register SysValue  Format   Used
+// -------------------- ----- ------ -------- -------- ------- ------
+// SV_TARGET                0   xyzw        0   TARGET   float   xyzw
+// SV_TARGET                1   xyzw        1   TARGET   float   xyzw
+// SV_TARGET                2   xyzw        2   TARGET   float   xyzw
+// SV_TARGET                3   xyzw        3   TARGET   float   xyzw
+// SV_TARGET                4   xyzw        4   TARGET   float   xyzw
+// SV_TARGET                5   xyzw        5   TARGET   float   xyzw
+// SV_TARGET                6   xyzw        6   TARGET   float   xyzw
+// SV_TARGET                7   xyzw        7   TARGET   float   xyzw
+// SV_DEPTH                 0    N/A   oDepth    DEPTH   float    YES
+//
+ps_4_0
+dcl_constantbuffer cb0[2], immediateIndexed
+dcl_output o0.xyzw
+dcl_output o1.xyzw
+dcl_output o2.xyzw
+dcl_output o3.xyzw
+dcl_output o4.xyzw
+dcl_output o5.xyzw
+dcl_output o6.xyzw
+dcl_output o7.xyzw
+dcl_output oDepth
+mov o0.xyzw, cb0[0].xyzw
+mov o1.xyzw, cb0[0].xyzw
+mov o2.xyzw, cb0[0].xyzw
+mov o3.xyzw, cb0[0].xyzw
+mov o4.xyzw, cb0[0].xyzw
+mov o5.xyzw, cb0[0].xyzw
+mov o6.xyzw, cb0[0].xyzw
+mov o7.xyzw, cb0[0].xyzw
+mov oDepth, cb0[1].x
+ret 
+// Approximately 10 instruction slots used
+#endif
+
+const BYTE g_PS_ClearFloat8[] = {
+    68,  88,  66,  67,  0,   45,  15,  86,  227, 217, 47,  173, 72,  182, 197, 224, 178, 165, 77,
+    73,  1,   0,   0,   0,   84,  4,   0,   0,   5,   0,   0,   0,   52,  0,   0,   0,   72,  1,
+    0,   0,   124, 1,   0,   0,   120, 2,   0,   0,   216, 3,   0,   0,   82,  68,  69,  70,  12,
+    1,   0,   0,   1,   0,   0,   0,   84,  0,   0,   0,   1,   0,   0,   0,   28,  0,   0,   0,
+    0,   4,   255, 255, 0,   1,   0,   0,   216, 0,   0,   0,   60,  0,   0,   0,   0,   0,   0,
+    0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   1,   0,
+    0,   0,   1,   0,   0,   0,   67,  111, 108, 111, 114, 65,  110, 100, 68,  101, 112, 116, 104,
+    68,  97,  116, 97,  70,  108, 111, 97,  116, 0,   171, 60,  0,   0,   0,   2,   0,   0,   0,
+    108, 0,   0,   0,   32,  0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   156, 0,   0,
+    0,   0,   0,   0,   0,   16,  0,   0,   0,   2,   0,   0,   0,   168, 0,   0,   0,   0,   0,
+    0,   0,   184, 0,   0,   0,   16,  0,   0,   0,   4,   0,   0,   0,   2,   0,   0,   0,   200,
+    0,   0,   0,   0,   0,   0,   0,   99,  111, 108, 111, 114, 95,  70,  108, 111, 97,  116, 0,
+    1,   0,   3,   0,   1,   0,   4,   0,   0,   0,   0,   0,   0,   0,   0,   0,   122, 86,  97,
+    108, 117, 101, 70,  95,  70,  108, 111, 97,  116, 0,   171, 171, 0,   0,   3,   0,   1,   0,
+    1,   0,   0,   0,   0,   0,   0,   0,   0,   0,   77,  105, 99,  114, 111, 115, 111, 102, 116,
+    32,  40,  82,  41,  32,  72,  76,  83,  76,  32,  83,  104, 97,  100, 101, 114, 32,  67,  111,
+    109, 112, 105, 108, 101, 114, 32,  54,  46,  51,  46,  57,  54,  48,  48,  46,  49,  54,  51,
+    56,  52,  0,   171, 171, 73,  83,  71,  78,  44,  0,   0,   0,   1,   0,   0,   0,   8,   0,
+    0,   0,   32,  0,   0,   0,   0,   0,   0,   0,   1,   0,   0,   0,   3,   0,   0,   0,   0,
+    0,   0,   0,   15,  0,   0,   0,   83,  86,  95,  80,  79,  83,  73,  84,  73,  79,  78,  0,
+    79,  83,  71,  78,  244, 0,   0,   0,   9,   0,   0,   0,   8,   0,   0,   0,   224, 0,   0,
+    0,   0,   0,   0,   0,   0,   0,   0,   0,   3,   0,   0,   0,   0,   0,   0,   0,   15,  0,
+    0,   0,   224, 0,   0,   0,   1,   0,   0,   0,   0,   0,   0,   0,   3,   0,   0,   0,   1,
+    0,   0,   0,   15,  0,   0,   0,   224, 0,   0,   0,   2,   0,   0,   0,   0,   0,   0,   0,
+    3,   0,   0,   0,   2,   0,   0,   0,   15,  0,   0,   0,   224, 0,   0,   0,   3,   0,   0,
+    0,   0,   0,   0,   0,   3,   0,   0,   0,   3,   0,   0,   0,   15,  0,   0,   0,   224, 0,
+    0,   0,   4,   0,   0,   0,   0,   0,   0,   0,   3,   0,   0,   0,   4,   0,   0,   0,   15,
+    0,   0,   0,   224, 0,   0,   0,   5,   0,   0,   0,   0,   0,   0,   0,   3,   0,   0,   0,
+    5,   0,   0,   0,   15,  0,   0,   0,   224, 0,   0,   0,   6,   0,   0,   0,   0,   0,   0,
+    0,   3,   0,   0,   0,   6,   0,   0,   0,   15,  0,   0,   0,   224, 0,   0,   0,   7,   0,
+    0,   0,   0,   0,   0,   0,   3,   0,   0,   0,   7,   0,   0,   0,   15,  0,   0,   0,   234,
+    0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   3,   0,   0,   0,   255, 255, 255, 255,
+    1,   14,  0,   0,   83,  86,  95,  84,  65,  82,  71,  69,  84,  0,   83,  86,  95,  68,  69,
+    80,  84,  72,  0,   171, 83,  72,  68,  82,  88,  1,   0,   0,   64,  0,   0,   0,   86,  0,
+    0,   0,   89,  0,   0,   4,   70,  142, 32,  0,   0,   0,   0,   0,   2,   0,   0,   0,   101,
+    0,   0,   3,   242, 32,  16,  0,   0,   0,   0,   0,   101, 0,   0,   3,   242, 32,  16,  0,
+    1,   0,   0,   0,   101, 0,   0,   3,   242, 32,  16,  0,   2,   0,   0,   0,   101, 0,   0,
+    3,   242, 32,  16,  0,   3,   0,   0,   0,   101, 0,   0,   3,   242, 32,  16,  0,   4,   0,
+    0,   0,   101, 0,   0,   3,   242, 32,  16,  0,   5,   0,   0,   0,   101, 0,   0,   3,   242,
+    32,  16,  0,   6,   0,   0,   0,   101, 0,   0,   3,   242, 32,  16,  0,   7,   0,   0,   0,
+    101, 0,   0,   2,   1,   192, 0,   0,   54,  0,   0,   6,   242, 32,  16,  0,   0,   0,   0,
+    0,   70,  142, 32,  0,   0,   0,   0,   0,   0,   0,   0,   0,   54,  0,   0,   6,   242, 32,
+    16,  0,   1,   0,   0,   0,   70,  142, 32,  0,   0,   0,   0,   0,   0,   0,   0,   0,   54,
+    0,   0,   6,   242, 32,  16,  0,   2,   0,   0,   0,   70,  142, 32,  0,   0,   0,   0,   0,
+    0,   0,   0,   0,   54,  0,   0,   6,   242, 32,  16,  0,   3,   0,   0,   0,   70,  142, 32,
+    0,   0,   0,   0,   0,   0,   0,   0,   0,   54,  0,   0,   6,   242, 32,  16,  0,   4,   0,
+    0,   0,   70,  142, 32,  0,   0,   0,   0,   0,   0,   0,   0,   0,   54,  0,   0,   6,   242,
+    32,  16,  0,   5,   0,   0,   0,   70,  142, 32,  0,   0,   0,   0,   0,   0,   0,   0,   0,
+    54,  0,   0,   6,   242, 32,  16,  0,   6,   0,   0,   0,   70,  142, 32,  0,   0,   0,   0,
+    0,   0,   0,   0,   0,   54,  0,   0,   6,   242, 32,  16,  0,   7,   0,   0,   0,   70,  142,
+    32,  0,   0,   0,   0,   0,   0,   0,   0,   0,   54,  0,   0,   5,   1,   192, 0,   0,   10,
+    128, 32,  0,   0,   0,   0,   0,   1,   0,   0,   0,   62,  0,   0,   1,   83,  84,  65,  84,
+    116, 0,   0,   0,   10,  0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   9,   0,   0,
+    0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   1,   0,   0,   0,   0,   0,
+    0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+    0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+    0,   0,   0,   0,   9,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+    0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+    0,   0,   0,   0,   0,   0};
--- a/gfx/angle/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/clearsint11ps1.h
+++ b/gfx/angle/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/clearsint11ps1.h
@@ -1,86 +1,86 @@
-#if 0
-//
-// Generated by Microsoft (R) HLSL Shader Compiler 6.3.9600.16384
-//
-//
-// Buffer Definitions: 
-//
-// cbuffer ColorAndDepthDataSint
-// {
-//
-//   int4 color_Sint;                   // Offset:    0 Size:    16
-//   float zValueF_Sint;                // Offset:   16 Size:     4
-//
-// }
-//
-//
-// Resource Bindings:
-//
-// Name                                 Type  Format         Dim Slot Elements
-// ------------------------------ ---------- ------- ----------- ---- --------
-// ColorAndDepthDataSint             cbuffer      NA          NA    0        1
-//
-//
-//
-// Input signature:
-//
-// Name                 Index   Mask Register SysValue  Format   Used
-// -------------------- ----- ------ -------- -------- ------- ------
-// SV_POSITION              0   xyzw        0      POS   float       
-//
-//
-// Output signature:
-//
-// Name                 Index   Mask Register SysValue  Format   Used
-// -------------------- ----- ------ -------- -------- ------- ------
-// SV_TARGET                0   xyzw        0   TARGET     int   xyzw
-// SV_DEPTH                 0    N/A   oDepth    DEPTH   float    YES
-//
-ps_4_0
-dcl_constantbuffer cb0[2], immediateIndexed
-dcl_output o0.xyzw
-dcl_output oDepth
-mov o0.xyzw, cb0[0].xyzw
-mov oDepth, cb0[1].x
-ret 
-// Approximately 3 instruction slots used
-#endif
-
-const BYTE g_PS_ClearSint1[] = {
-    68,  88,  66,  67,  234, 238, 101, 91,  76,  164, 85,  240, 165, 134, 177, 247, 216, 133, 221,
-    129, 1,   0,   0,   0,   176, 2,   0,   0,   5,   0,   0,   0,   52,  0,   0,   0,   72,  1,
-    0,   0,   124, 1,   0,   0,   208, 1,   0,   0,   52,  2,   0,   0,   82,  68,  69,  70,  12,
-    1,   0,   0,   1,   0,   0,   0,   84,  0,   0,   0,   1,   0,   0,   0,   28,  0,   0,   0,
-    0,   4,   255, 255, 0,   1,   0,   0,   216, 0,   0,   0,   60,  0,   0,   0,   0,   0,   0,
-    0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   1,   0,
-    0,   0,   1,   0,   0,   0,   67,  111, 108, 111, 114, 65,  110, 100, 68,  101, 112, 116, 104,
-    68,  97,  116, 97,  83,  105, 110, 116, 0,   171, 171, 60,  0,   0,   0,   2,   0,   0,   0,
-    108, 0,   0,   0,   32,  0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   156, 0,   0,
-    0,   0,   0,   0,   0,   16,  0,   0,   0,   2,   0,   0,   0,   168, 0,   0,   0,   0,   0,
-    0,   0,   184, 0,   0,   0,   16,  0,   0,   0,   4,   0,   0,   0,   2,   0,   0,   0,   200,
-    0,   0,   0,   0,   0,   0,   0,   99,  111, 108, 111, 114, 95,  83,  105, 110, 116, 0,   171,
-    1,   0,   2,   0,   1,   0,   4,   0,   0,   0,   0,   0,   0,   0,   0,   0,   122, 86,  97,
-    108, 117, 101, 70,  95,  83,  105, 110, 116, 0,   171, 171, 171, 0,   0,   3,   0,   1,   0,
-    1,   0,   0,   0,   0,   0,   0,   0,   0,   0,   77,  105, 99,  114, 111, 115, 111, 102, 116,
-    32,  40,  82,  41,  32,  72,  76,  83,  76,  32,  83,  104, 97,  100, 101, 114, 32,  67,  111,
-    109, 112, 105, 108, 101, 114, 32,  54,  46,  51,  46,  57,  54,  48,  48,  46,  49,  54,  51,
-    56,  52,  0,   171, 171, 73,  83,  71,  78,  44,  0,   0,   0,   1,   0,   0,   0,   8,   0,
-    0,   0,   32,  0,   0,   0,   0,   0,   0,   0,   1,   0,   0,   0,   3,   0,   0,   0,   0,
-    0,   0,   0,   15,  0,   0,   0,   83,  86,  95,  80,  79,  83,  73,  84,  73,  79,  78,  0,
-    79,  83,  71,  78,  76,  0,   0,   0,   2,   0,   0,   0,   8,   0,   0,   0,   56,  0,   0,
-    0,   0,   0,   0,   0,   0,   0,   0,   0,   2,   0,   0,   0,   0,   0,   0,   0,   15,  0,
-    0,   0,   66,  0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   3,   0,   0,   0,   255,
-    255, 255, 255, 1,   14,  0,   0,   83,  86,  95,  84,  65,  82,  71,  69,  84,  0,   83,  86,
-    95,  68,  69,  80,  84,  72,  0,   171, 83,  72,  68,  82,  92,  0,   0,   0,   64,  0,   0,
-    0,   23,  0,   0,   0,   89,  0,   0,   4,   70,  142, 32,  0,   0,   0,   0,   0,   2,   0,
-    0,   0,   101, 0,   0,   3,   242, 32,  16,  0,   0,   0,   0,   0,   101, 0,   0,   2,   1,
-    192, 0,   0,   54,  0,   0,   6,   242, 32,  16,  0,   0,   0,   0,   0,   70,  142, 32,  0,
-    0,   0,   0,   0,   0,   0,   0,   0,   54,  0,   0,   5,   1,   192, 0,   0,   10,  128, 32,
-    0,   0,   0,   0,   0,   1,   0,   0,   0,   62,  0,   0,   1,   83,  84,  65,  84,  116, 0,
-    0,   0,   3,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   2,   0,   0,   0,   0,
-    0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   1,   0,   0,   0,   0,   0,   0,   0,
-    0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
-    0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
-    0,   0,   2,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
-    0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
-    0,   0,   0,   0};
+#if 0
+//
+// Generated by Microsoft (R) HLSL Shader Compiler 6.3.9600.16384
+//
+//
+// Buffer Definitions: 
+//
+// cbuffer ColorAndDepthDataSint
+// {
+//
+//   int4 color_Sint;                   // Offset:    0 Size:    16
+//   float zValueF_Sint;                // Offset:   16 Size:     4
+//
+// }
+//
+//
+// Resource Bindings:
+//
+// Name                                 Type  Format         Dim Slot Elements
+// ------------------------------ ---------- ------- ----------- ---- --------
+// ColorAndDepthDataSint             cbuffer      NA          NA    0        1
+//
+//
+//
+// Input signature:
+//
+// Name                 Index   Mask Register SysValue  Format   Used
+// -------------------- ----- ------ -------- -------- ------- ------
+// SV_POSITION              0   xyzw        0      POS   float       
+//
+//
+// Output signature:
+//
+// Name                 Index   Mask Register SysValue  Format   Used
+// -------------------- ----- ------ -------- -------- ------- ------
+// SV_TARGET                0   xyzw        0   TARGET     int   xyzw
+// SV_DEPTH                 0    N/A   oDepth    DEPTH   float    YES
+//
+ps_4_0
+dcl_constantbuffer cb0[2], immediateIndexed
+dcl_output o0.xyzw
+dcl_output oDepth
+mov o0.xyzw, cb0[0].xyzw
+mov oDepth, cb0[1].x
+ret 
+// Approximately 3 instruction slots used
+#endif
+
+const BYTE g_PS_ClearSint1[] = {
+    68,  88,  66,  67,  234, 238, 101, 91,  76,  164, 85,  240, 165, 134, 177, 247, 216, 133, 221,
+    129, 1,   0,   0,   0,   176, 2,   0,   0,   5,   0,   0,   0,   52,  0,   0,   0,   72,  1,
+    0,   0,   124, 1,   0,   0,   208, 1,   0,   0,   52,  2,   0,   0,   82,  68,  69,  70,  12,
+    1,   0,   0,   1,   0,   0,   0,   84,  0,   0,   0,   1,   0,   0,   0,   28,  0,   0,   0,
+    0,   4,   255, 255, 0,   1,   0,   0,   216, 0,   0,   0,   60,  0,   0,   0,   0,   0,   0,
+    0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   1,   0,
+    0,   0,   1,   0,   0,   0,   67,  111, 108, 111, 114, 65,  110, 100, 68,  101, 112, 116, 104,
+    68,  97,  116, 97,  83,  105, 110, 116, 0,   171, 171, 60,  0,   0,   0,   2,   0,   0,   0,
+    108, 0,   0,   0,   32,  0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   156, 0,   0,
+    0,   0,   0,   0,   0,   16,  0,   0,   0,   2,   0,   0,   0,   168, 0,   0,   0,   0,   0,
+    0,   0,   184, 0,   0,   0,   16,  0,   0,   0,   4,   0,   0,   0,   2,   0,   0,   0,   200,
+    0,   0,   0,   0,   0,   0,   0,   99,  111, 108, 111, 114, 95,  83,  105, 110, 116, 0,   171,
+    1,   0,   2,   0,   1,   0,   4,   0,   0,   0,   0,   0,   0,   0,   0,   0,   122, 86,  97,
+    108, 117, 101, 70,  95,  83,  105, 110, 116, 0,   171, 171, 171, 0,   0,   3,   0,   1,   0,
+    1,   0,   0,   0,   0,   0,   0,   0,   0,   0,   77,  105, 99,  114, 111, 115, 111, 102, 116,
+    32,  40,  82,  41,  32,  72,  76,  83,  76,  32,  83,  104, 97,  100, 101, 114, 32,  67,  111,
+    109, 112, 105, 108, 101, 114, 32,  54,  46,  51,  46,  57,  54,  48,  48,  46,  49,  54,  51,
+    56,  52,  0,   171, 171, 73,  83,  71,  78,  44,  0,   0,   0,   1,   0,   0,   0,   8,   0,
+    0,   0,   32,  0,   0,   0,   0,   0,   0,   0,   1,   0,   0,   0,   3,   0,   0,   0,   0,
+    0,   0,   0,   15,  0,   0,   0,   83,  86,  95,  80,  79,  83,  73,  84,  73,  79,  78,  0,
+    79,  83,  71,  78,  76,  0,   0,   0,   2,   0,   0,   0,   8,   0,   0,   0,   56,  0,   0,
+    0,   0,   0,   0,   0,   0,   0,   0,   0,   2,   0,   0,   0,   0,   0,   0,   0,   15,  0,
+    0,   0,   66,  0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   3,   0,   0,   0,   255,
+    255, 255, 255, 1,   14,  0,   0,   83,  86,  95,  84,  65,  82,  71,  69,  84,  0,   83,  86,
+    95,  68,  69,  80,  84,  72,  0,   171, 83,  72,  68,  82,  92,  0,   0,   0,   64,  0,   0,
+    0,   23,  0,   0,   0,   89,  0,   0,   4,   70,  142, 32,  0,   0,   0,   0,   0,   2,   0,
+    0,   0,   101, 0,   0,   3,   242, 32,  16,  0,   0,   0,   0,   0,   101, 0,   0,   2,   1,
+    192, 0,   0,   54,  0,   0,   6,   242, 32,  16,  0,   0,   0,   0,   0,   70,  142, 32,  0,
+    0,   0,   0,   0,   0,   0,   0,   0,   54,  0,   0,   5,   1,   192, 0,   0,   10,  128, 32,
+    0,   0,   0,   0,   0,   1,   0,   0,   0,   62,  0,   0,   1,   83,  84,  65,  84,  116, 0,
+    0,   0,   3,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   2,   0,   0,   0,   0,
+    0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   1,   0,   0,   0,   0,   0,   0,   0,
+    0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+    0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+    0,   0,   2,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+    0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+    0,   0,   0,   0};
--- a/gfx/angle/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/clearsint11ps2.h
+++ b/gfx/angle/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/clearsint11ps2.h
@@ -1,92 +1,92 @@
-#if 0
-//
-// Generated by Microsoft (R) HLSL Shader Compiler 6.3.9600.16384
-//
-//
-// Buffer Definitions: 
-//
-// cbuffer ColorAndDepthDataSint
-// {
-//
-//   int4 color_Sint;                   // Offset:    0 Size:    16
-//   float zValueF_Sint;                // Offset:   16 Size:     4
-//
-// }
-//
-//
-// Resource Bindings:
-//
-// Name                                 Type  Format         Dim Slot Elements
-// ------------------------------ ---------- ------- ----------- ---- --------
-// ColorAndDepthDataSint             cbuffer      NA          NA    0        1
-//
-//
-//
-// Input signature:
-//
-// Name                 Index   Mask Register SysValue  Format   Used
-// -------------------- ----- ------ -------- -------- ------- ------
-// SV_POSITION              0   xyzw        0      POS   float       
-//
-//
-// Output signature:
-//
-// Name                 Index   Mask Register SysValue  Format   Used
-// -------------------- ----- ------ -------- -------- ------- ------
-// SV_TARGET                0   xyzw        0   TARGET     int   xyzw
-// SV_TARGET                1   xyzw        1   TARGET     int   xyzw
-// SV_DEPTH                 0    N/A   oDepth    DEPTH   float    YES
-//
-ps_4_0
-dcl_constantbuffer cb0[2], immediateIndexed
-dcl_output o0.xyzw
-dcl_output o1.xyzw
-dcl_output oDepth
-mov o0.xyzw, cb0[0].xyzw
-mov o1.xyzw, cb0[0].xyzw
-mov oDepth, cb0[1].x
-ret 
-// Approximately 4 instruction slots used
-#endif
-
-const BYTE g_PS_ClearSint2[] = {
-    68,  88,  66,  67,  222, 216, 239, 82,  222, 254, 123, 203, 132, 152, 125, 4,   154, 18,  65,
-    65,  1,   0,   0,   0,   236, 2,   0,   0,   5,   0,   0,   0,   52,  0,   0,   0,   72,  1,
-    0,   0,   124, 1,   0,   0,   232, 1,   0,   0,   112, 2,   0,   0,   82,  68,  69,  70,  12,
-    1,   0,   0,   1,   0,   0,   0,   84,  0,   0,   0,   1,   0,   0,   0,   28,  0,   0,   0,
-    0,   4,   255, 255, 0,   1,   0,   0,   216, 0,   0,   0,   60,  0,   0,   0,   0,   0,   0,
-    0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   1,   0,
-    0,   0,   1,   0,   0,   0,   67,  111, 108, 111, 114, 65,  110, 100, 68,  101, 112, 116, 104,
-    68,  97,  116, 97,  83,  105, 110, 116, 0,   171, 171, 60,  0,   0,   0,   2,   0,   0,   0,
-    108, 0,   0,   0,   32,  0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   156, 0,   0,
-    0,   0,   0,   0,   0,   16,  0,   0,   0,   2,   0,   0,   0,   168, 0,   0,   0,   0,   0,
-    0,   0,   184, 0,   0,   0,   16,  0,   0,   0,   4,   0,   0,   0,   2,   0,   0,   0,   200,
-    0,   0,   0,   0,   0,   0,   0,   99,  111, 108, 111, 114, 95,  83,  105, 110, 116, 0,   171,
-    1,   0,   2,   0,   1,   0,   4,   0,   0,   0,   0,   0,   0,   0,   0,   0,   122, 86,  97,
-    108, 117, 101, 70,  95,  83,  105, 110, 116, 0,   171, 171, 171, 0,   0,   3,   0,   1,   0,
-    1,   0,   0,   0,   0,   0,   0,   0,   0,   0,   77,  105, 99,  114, 111, 115, 111, 102, 116,
-    32,  40,  82,  41,  32,  72,  76,  83,  76,  32,  83,  104, 97,  100, 101, 114, 32,  67,  111,
-    109, 112, 105, 108, 101, 114, 32,  54,  46,  51,  46,  57,  54,  48,  48,  46,  49,  54,  51,
-    56,  52,  0,   171, 171, 73,  83,  71,  78,  44,  0,   0,   0,   1,   0,   0,   0,   8,   0,
-    0,   0,   32,  0,   0,   0,   0,   0,   0,   0,   1,   0,   0,   0,   3,   0,   0,   0,   0,
-    0,   0,   0,   15,  0,   0,   0,   83,  86,  95,  80,  79,  83,  73,  84,  73,  79,  78,  0,
-    79,  83,  71,  78,  100, 0,   0,   0,   3,   0,   0,   0,   8,   0,   0,   0,   80,  0,   0,
-    0,   0,   0,   0,   0,   0,   0,   0,   0,   2,   0,   0,   0,   0,   0,   0,   0,   15,  0,
-    0,   0,   80,  0,   0,   0,   1,   0,   0,   0,   0,   0,   0,   0,   2,   0,   0,   0,   1,
-    0,   0,   0,   15,  0,   0,   0,   90,  0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
-    3,   0,   0,   0,   255, 255, 255, 255, 1,   14,  0,   0,   83,  86,  95,  84,  65,  82,  71,
-    69,  84,  0,   83,  86,  95,  68,  69,  80,  84,  72,  0,   171, 83,  72,  68,  82,  128, 0,
-    0,   0,   64,  0,   0,   0,   32,  0,   0,   0,   89,  0,   0,   4,   70,  142, 32,  0,   0,
-    0,   0,   0,   2,   0,   0,   0,   101, 0,   0,   3,   242, 32,  16,  0,   0,   0,   0,   0,
-    101, 0,   0,   3,   242, 32,  16,  0,   1,   0,   0,   0,   101, 0,   0,   2,   1,   192, 0,
-    0,   54,  0,   0,   6,   242, 32,  16,  0,   0,   0,   0,   0,   70,  142, 32,  0,   0,   0,
-    0,   0,   0,   0,   0,   0,   54,  0,   0,   6,   242, 32,  16,  0,   1,   0,   0,   0,   70,
-    142, 32,  0,   0,   0,   0,   0,   0,   0,   0,   0,   54,  0,   0,   5,   1,   192, 0,   0,
-    10,  128, 32,  0,   0,   0,   0,   0,   1,   0,   0,   0,   62,  0,   0,   1,   83,  84,  65,
-    84,  116, 0,   0,   0,   4,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   3,   0,
-    0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   1,   0,   0,   0,   0,
-    0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
-    0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
-    0,   0,   0,   0,   0,   3,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
-    0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
-    0,   0,   0,   0,   0,   0,   0};
+#if 0
+//
+// Generated by Microsoft (R) HLSL Shader Compiler 6.3.9600.16384
+//
+//
+// Buffer Definitions: 
+//
+// cbuffer ColorAndDepthDataSint
+// {
+//
+//   int4 color_Sint;                   // Offset:    0 Size:    16
+//   float zValueF_Sint;                // Offset:   16 Size:     4
+//
+// }
+//
+//
+// Resource Bindings:
+//
+// Name                                 Type  Format         Dim Slot Elements
+// ------------------------------ ---------- ------- ----------- ---- --------
+// ColorAndDepthDataSint             cbuffer      NA          NA    0        1
+//
+//
+//
+// Input signature:
+//
+// Name                 Index   Mask Register SysValue  Format   Used
+// -------------------- ----- ------ -------- -------- ------- ------
+// SV_POSITION              0   xyzw        0      POS   float       
+//
+//
+// Output signature:
+//
+// Name                 Index   Mask Register SysValue  Format   Used
+// -------------------- ----- ------ -------- -------- ------- ------
+// SV_TARGET                0   xyzw        0   TARGET     int   xyzw
+// SV_TARGET                1   xyzw        1   TARGET     int   xyzw
+// SV_DEPTH                 0    N/A   oDepth    DEPTH   float    YES
+//
+ps_4_0
+dcl_constantbuffer cb0[2], immediateIndexed
+dcl_output o0.xyzw
+dcl_output o1.xyzw
+dcl_output oDepth
+mov o0.xyzw, cb0[0].xyzw
+mov o1.xyzw, cb0[0].xyzw
+mov oDepth, cb0[1].x
+ret 
+// Approximately 4 instruction slots used
+#endif
+
+const BYTE g_PS_ClearSint2[] = {
+    68,  88,  66,  67,  222, 216, 239, 82,  222, 254, 123, 203, 132, 152, 125, 4,   154, 18,  65,
+    65,  1,   0,   0,   0,   236, 2,   0,   0,   5,   0,   0,   0,   52,  0,   0,   0,   72,  1,
+    0,   0,   124, 1,   0,   0,   232, 1,   0,   0,   112, 2,   0,   0,   82,  68,  69,  70,  12,
+    1,   0,   0,   1,   0,   0,   0,   84,  0,   0,   0,   1,   0,   0,   0,   28,  0,   0,   0,
+    0,   4,   255, 255, 0,   1,   0,   0,   216, 0,   0,   0,   60,  0,   0,   0,   0,   0,   0,
+    0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   1,   0,
+    0,   0,   1,   0,   0,   0,   67,  111, 108, 111, 114, 65,  110, 100, 68,  101, 112, 116, 104,
+    68,  97,  116, 97,  83,  105, 110, 116, 0,   171, 171, 60,  0,   0,   0,   2,   0,   0,   0,
+    108, 0,   0,   0,   32,  0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   156, 0,   0,
+    0,   0,   0,   0,   0,   16,  0,   0,   0,   2,   0,   0,   0,   168, 0,   0,   0,   0,   0,
+    0,   0,   184, 0,   0,   0,   16,  0,   0,   0,   4,   0,   0,   0,   2,   0,   0,   0,   200,
+    0,   0,   0,   0,   0,   0,   0,   99,  111, 108, 111, 114, 95,  83,  105, 110, 116, 0,   171,
+    1,   0,   2,   0,   1,   0,   4,   0,   0,   0,   0,   0,   0,   0,   0,   0,   122, 86,  97,
+    108, 117, 101, 70,  95,  83,  105, 110, 116, 0,   171, 171, 171, 0,   0,   3,   0,   1,   0,
+    1,   0,   0,   0,   0,   0,   0,   0,   0,   0,   77,  105, 99,  114, 111, 115, 111, 102, 116,
+    32,  40,  82,  41,  32,  72,  76,  83,  76,  32,  83,  104, 97,  100, 101, 114, 32,  67,  111,
+    109, 112, 105, 108, 101, 114, 32,  54,  46,  51,  46,  57,  54,  48,  48,  46,  49,  54,  51,
+    56,  52,  0,   171, 171, 73,  83,  71,  78,  44,  0,   0,   0,   1,   0,   0,   0,   8,   0,
+    0,   0,   32,  0,   0,   0,   0,   0,   0,   0,   1,   0,   0,   0,   3,   0,   0,   0,   0,
+    0,   0,   0,   15,  0,   0,   0,   83,  86,  95,  80,  79,  83,  73,  84,  73,  79,  78,  0,
+    79,  83,  71,  78,  100, 0,   0,   0,   3,   0,   0,   0,   8,   0,   0,   0,   80,  0,   0,
+    0,   0,   0,   0,   0,   0,   0,   0,   0,   2,   0,   0,   0,   0,   0,   0,   0,   15,  0,
+    0,   0,   80,  0,   0,   0,   1,   0,   0,   0,   0,   0,   0,   0,   2,   0,   0,   0,   1,
+    0,   0,   0,   15,  0,   0,   0,   90,  0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+    3,   0,   0,   0,   255, 255, 255, 255, 1,   14,  0,   0,   83,  86,  95,  84,  65,  82,  71,
+    69,  84,  0,   83,  86,  95,  68,  69,  80,  84,  72,  0,   171, 83,  72,  68,  82,  128, 0,
+    0,   0,   64,  0,   0,   0,   32,  0,   0,   0,   89,  0,   0,   4,   70,  142, 32,  0,   0,
+    0,   0,   0,   2,   0,   0,   0,   101, 0,   0,   3,   242, 32,  16,  0,   0,   0,   0,   0,
+    101, 0,   0,   3,   242, 32,  16,  0,   1,   0,   0,   0,   101, 0,   0,   2,   1,   192, 0,
+    0,   54,  0,   0,   6,   242, 32,  16,  0,   0,   0,   0,   0,   70,  142, 32,  0,   0,   0,
+    0,   0,   0,   0,   0,   0,   54,  0,   0,   6,   242, 32,  16,  0,   1,   0,   0,   0,   70,
+    142, 32,  0,   0,   0,   0,   0,   0,   0,   0,   0,   54,  0,   0,   5,   1,   192, 0,   0,
+    10,  128, 32,  0,   0,   0,   0,   0,   1,   0,   0,   0,   62,  0,   0,   1,   83,  84,  65,
+    84,  116, 0,   0,   0,   4,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   3,   0,
+    0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   1,   0,   0,   0,   0,
+    0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+    0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+    0,   0,   0,   0,   0,   3,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+    0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+    0,   0,   0,   0,   0,   0,   0};
--- a/gfx/angle/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/clearsint11ps3.h
+++ b/gfx/angle/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/clearsint11ps3.h
@@ -1,98 +1,98 @@
-#if 0
-//
-// Generated by Microsoft (R) HLSL Shader Compiler 6.3.9600.16384
-//
-//
-// Buffer Definitions: 
-//
-// cbuffer ColorAndDepthDataSint
-// {
-//
-//   int4 color_Sint;                   // Offset:    0 Size:    16
-//   float zValueF_Sint;                // Offset:   16 Size:     4
-//
-// }
-//
-//
-// Resource Bindings:
-//
-// Name                                 Type  Format         Dim Slot Elements
-// ------------------------------ ---------- ------- ----------- ---- --------
-// ColorAndDepthDataSint             cbuffer      NA          NA    0        1
-//
-//
-//
-// Input signature:
-//
-// Name                 Index   Mask Register SysValue  Format   Used
-// -------------------- ----- ------ -------- -------- ------- ------
-// SV_POSITION              0   xyzw        0      POS   float       
-//
-//
-// Output signature:
-//
-// Name                 Index   Mask Register SysValue  Format   Used
-// -------------------- ----- ------ -------- -------- ------- ------
-// SV_TARGET                0   xyzw        0   TARGET     int   xyzw
-// SV_TARGET                1   xyzw        1   TARGET     int   xyzw
-// SV_TARGET                2   xyzw        2   TARGET     int   xyzw
-// SV_DEPTH                 0    N/A   oDepth    DEPTH   float    YES
-//
-ps_4_0
-dcl_constantbuffer cb0[2], immediateIndexed
-dcl_output o0.xyzw
-dcl_output o1.xyzw
-dcl_output o2.xyzw
-dcl_output oDepth
-mov o0.xyzw, cb0[0].xyzw
-mov o1.xyzw, cb0[0].xyzw
-mov o2.xyzw, cb0[0].xyzw
-mov oDepth, cb0[1].x
-ret 
-// Approximately 5 instruction slots used
-#endif
-
-const BYTE g_PS_ClearSint3[] = {
-    68,  88,  66,  67,  251, 25,  49,  126, 247, 6,   239, 75,  31,  240, 87,  139, 35,  246, 130,
-    22,  1,   0,   0,   0,   40,  3,   0,   0,   5,   0,   0,   0,   52,  0,   0,   0,   72,  1,
-    0,   0,   124, 1,   0,   0,   0,   2,   0,   0,   172, 2,   0,   0,   82,  68,  69,  70,  12,
-    1,   0,   0,   1,   0,   0,   0,   84,  0,   0,   0,   1,   0,   0,   0,   28,  0,   0,   0,
-    0,   4,   255, 255, 0,   1,   0,   0,   216, 0,   0,   0,   60,  0,   0,   0,   0,   0,   0,
-    0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   1,   0,
-    0,   0,   1,   0,   0,   0,   67,  111, 108, 111, 114, 65,  110, 100, 68,  101, 112, 116, 104,
-    68,  97,  116, 97,  83,  105, 110, 116, 0,   171, 171, 60,  0,   0,   0,   2,   0,   0,   0,
-    108, 0,   0,   0,   32,  0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   156, 0,   0,
-    0,   0,   0,   0,   0,   16,  0,   0,   0,   2,   0,   0,   0,   168, 0,   0,   0,   0,   0,
-    0,   0,   184, 0,   0,   0,   16,  0,   0,   0,   4,   0,   0,   0,   2,   0,   0,   0,   200,
-    0,   0,   0,   0,   0,   0,   0,   99,  111, 108, 111, 114, 95,  83,  105, 110, 116, 0,   171,
-    1,   0,   2,   0,   1,   0,   4,   0,   0,   0,   0,   0,   0,   0,   0,   0,   122, 86,  97,
-    108, 117, 101, 70,  95,  83,  105, 110, 116, 0,   171, 171, 171, 0,   0,   3,   0,   1,   0,
-    1,   0,   0,   0,   0,   0,   0,   0,   0,   0,   77,  105, 99,  114, 111, 115, 111, 102, 116,
-    32,  40,  82,  41,  32,  72,  76,  83,  76,  32,  83,  104, 97,  100, 101, 114, 32,  67,  111,
-    109, 112, 105, 108, 101, 114, 32,  54,  46,  51,  46,  57,  54,  48,  48,  46,  49,  54,  51,
-    56,  52,  0,   171, 171, 73,  83,  71,  78,  44,  0,   0,   0,   1,   0,   0,   0,   8,   0,
-    0,   0,   32,  0,   0,   0,   0,   0,   0,   0,   1,   0,   0,   0,   3,   0,   0,   0,   0,
-    0,   0,   0,   15,  0,   0,   0,   83,  86,  95,  80,  79,  83,  73,  84,  73,  79,  78,  0,
-    79,  83,  71,  78,  124, 0,   0,   0,   4,   0,   0,   0,   8,   0,   0,   0,   104, 0,   0,
-    0,   0,   0,   0,   0,   0,   0,   0,   0,   2,   0,   0,   0,   0,   0,   0,   0,   15,  0,
-    0,   0,   104, 0,   0,   0,   1,   0,   0,   0,   0,   0,   0,   0,   2,   0,   0,   0,   1,
-    0,   0,   0,   15,  0,   0,   0,   104, 0,   0,   0,   2,   0,   0,   0,   0,   0,   0,   0,
-    2,   0,   0,   0,   2,   0,   0,   0,   15,  0,   0,   0,   114, 0,   0,   0,   0,   0,   0,
-    0,   0,   0,   0,   0,   3,   0,   0,   0,   255, 255, 255, 255, 1,   14,  0,   0,   83,  86,
-    95,  84,  65,  82,  71,  69,  84,  0,   83,  86,  95,  68,  69,  80,  84,  72,  0,   171, 83,
-    72,  68,  82,  164, 0,   0,   0,   64,  0,   0,   0,   41,  0,   0,   0,   89,  0,   0,   4,
-    70,  142, 32,  0,   0,   0,   0,   0,   2,   0,   0,   0,   101, 0,   0,   3,   242, 32,  16,
-    0,   0,   0,   0,   0,   101, 0,   0,   3,   242, 32,  16,  0,   1,   0,   0,   0,   101, 0,
-    0,   3,   242, 32,  16,  0,   2,   0,   0,   0,   101, 0,   0,   2,   1,   192, 0,   0,   54,
-    0,   0,   6,   242, 32,  16,  0,   0,   0,   0,   0,   70,  142, 32,  0,   0,   0,   0,   0,
-    0,   0,   0,   0,   54,  0,   0,   6,   242, 32,  16,  0,   1,   0,   0,   0,   70,  142, 32,
-    0,   0,   0,   0,   0,   0,   0,   0,   0,   54,  0,   0,   6,   242, 32,  16,  0,   2,   0,
-    0,   0,   70,  142, 32,  0,   0,   0,   0,   0,   0,   0,   0,   0,   54,  0,   0,   5,   1,
-    192, 0,   0,   10,  128, 32,  0,   0,   0,   0,   0,   1,   0,   0,   0,   62,  0,   0,   1,
-    83,  84,  65,  84,  116, 0,   0,   0,   5,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
-    0,   4,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   1,   0,
-    0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
-    0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
-    0,   0,   0,   0,   0,   0,   0,   0,   4,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
-    0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
-    0,   0,   0,   0,   0,   0,   0,   0,   0,   0};
+#if 0
+//
+// Generated by Microsoft (R) HLSL Shader Compiler 6.3.9600.16384
+//
+//
+// Buffer Definitions: 
+//
+// cbuffer ColorAndDepthDataSint
+// {
+//
+//   int4 color_Sint;                   // Offset:    0 Size:    16
+//   float zValueF_Sint;                // Offset:   16 Size:     4
+//
+// }
+//
+//
+// Resource Bindings:
+//
+// Name                                 Type  Format         Dim Slot Elements
+// ------------------------------ ---------- ------- ----------- ---- --------
+// ColorAndDepthDataSint             cbuffer      NA          NA    0        1
+//
+//
+//
+// Input signature:
+//
+// Name                 Index   Mask Register SysValue  Format   Used
+// -------------------- ----- ------ -------- -------- ------- ------
+// SV_POSITION              0   xyzw        0      POS   float       
+//
+//
+// Output signature:
+//
+// Name                 Index   Mask Register SysValue  Format   Used
+// -------------------- ----- ------ -------- -------- ------- ------
+// SV_TARGET                0   xyzw        0   TARGET     int   xyzw
+// SV_TARGET                1   xyzw        1   TARGET     int   xyzw
+// SV_TARGET                2   xyzw        2   TARGET     int   xyzw
+// SV_DEPTH                 0    N/A   oDepth    DEPTH   float    YES
+//
+ps_4_0
+dcl_constantbuffer cb0[2], immediateIndexed
+dcl_output o0.xyzw
+dcl_output o1.xyzw
+dcl_output o2.xyzw
+dcl_output oDepth
+mov o0.xyzw, cb0[0].xyzw
+mov o1.xyzw, cb0[0].xyzw
+mov o2.xyzw, cb0[0].xyzw
+mov oDepth, cb0[1].x
+ret 
+// Approximately 5 instruction slots used
+#endif
+
+const BYTE g_PS_ClearSint3[] = {
+    68,  88,  66,  67,  251, 25,  49,  126, 247, 6,   239, 75,  31,  240, 87,  139, 35,  246, 130,
+    22,  1,   0,   0,   0,   40,  3,   0,   0,   5,   0,   0,   0,   52,  0,   0,   0,   72,  1,
+    0,   0,   124, 1,   0,   0,   0,   2,   0,   0,   172, 2,   0,   0,   82,  68,  69,  70,  12,
+    1,   0,   0,   1,   0,   0,   0,   84,  0,   0,   0,   1,   0,   0,   0,   28,  0,   0,   0,
+    0,   4,   255, 255, 0,   1,   0,   0,   216, 0,   0,   0,   60,  0,   0,   0,   0,   0,   0,
+    0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   1,   0,
+    0,   0,   1,   0,   0,   0,   67,  111, 108, 111, 114, 65,  110, 100, 68,  101, 112, 116, 104,
+    68,  97,  116, 97,  83,  105, 110, 116, 0,   171, 171, 60,  0,   0,   0,   2,   0,   0,   0,
+    108, 0,   0,   0,   32,  0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   156, 0,   0,
+    0,   0,   0,   0,   0,   16,  0,   0,   0,   2,   0,   0,   0,   168, 0,   0,   0,   0,   0,
+    0,   0,   184, 0,   0,   0,   16,  0,   0,   0,   4,   0,   0,   0,   2,   0,   0,   0,   200,
+    0,   0,   0,   0,   0,   0,   0,   99,  111, 108, 111, 114, 95,  83,  105, 110, 116, 0,   171,
+    1,   0,   2,   0,   1,   0,   4,   0,   0,   0,   0,   0,   0,   0,   0,   0,   122, 86,  97,
+    108, 117, 101, 70,  95,  83,  105, 110, 116, 0,   171, 171, 171, 0,   0,   3,   0,   1,   0,
+    1,   0,   0,   0,   0,   0,   0,   0,   0,   0,   77,  105, 99,  114, 111, 115, 111, 102, 116,
+    32,  40,  82,  41,  32,  72,  76,  83,  76,  32,  83,  104, 97,  100, 101, 114, 32,  67,  111,
+    109, 112, 105, 108, 101, 114, 32,  54,  46,  51,  46,  57,  54,  48,  48,  46,  49,  54,  51,
+    56,  52,  0,   171, 171, 73,  83,  71,  78,  44,  0,   0,   0,   1,   0,   0,   0,   8,   0,
+    0,   0,   32,  0,   0,   0,   0,   0,   0,   0,   1,   0,   0,   0,   3,   0,   0,   0,   0,
+    0,   0,   0,   15,  0,   0,   0,   83,  86,  95,  80,  79,  83,  73,  84,  73,  79,  78,  0,
+    79,  83,  71,  78,  124, 0,   0,   0,   4,   0,   0,   0,   8,   0,   0,   0,   104, 0,   0,
+    0,   0,   0,   0,   0,   0,   0,   0,   0,   2,   0,   0,   0,   0,   0,   0,   0,   15,  0,
+    0,   0,   104, 0,   0,   0,   1,   0,   0,   0,   0,   0,   0,   0,   2,   0,   0,   0,   1,
+    0,   0,   0,   15,  0,   0,   0,   104, 0,   0,   0,   2,   0,   0,   0,   0,   0,   0,   0,
+    2,   0,   0,   0,   2,   0,   0,   0,   15,  0,   0,   0,   114, 0,   0,   0,   0,   0,   0,
+    0,   0,   0,   0,   0,   3,   0,   0,   0,   255, 255, 255, 255, 1,   14,  0,   0,   83,  86,
+    95,  84,  65,  82,  71,  69,  84,  0,   83,  86,  95,  68,  69,  80,  84,  72,  0,   171, 83,
+    72,  68,  82,  164, 0,   0,   0,   64,  0,   0,   0,   41,  0,   0,   0,   89,  0,   0,   4,
+    70,  142, 32,  0,   0,   0,   0,   0,   2,   0,   0,   0,   101, 0,   0,   3,   242, 32,  16,
+    0,   0,   0,   0,   0,   101, 0,   0,   3,   242, 32,  16,  0,   1,   0,   0,   0,   101, 0,
+    0,   3,   242, 32,  16,  0,   2,   0,   0,   0,   101, 0,   0,   2,   1,   192, 0,   0,   54,
+    0,   0,   6,   242, 32,  16,  0,   0,   0,   0,   0,   70,  142, 32,  0,   0,   0,   0,   0,
+    0,   0,   0,   0,   54,  0,   0,   6,   242, 32,  16,  0,   1,   0,   0,   0,   70,  142, 32,
+    0,   0,   0,   0,   0,   0,   0,   0,   0,   54,  0,   0,   6,   242, 32,  16,  0,   2,   0,
+    0,   0,   70,  142, 32,  0,   0,   0,   0,   0,   0,   0,   0,   0,   54,  0,   0,   5,   1,
+    192, 0,   0,   10,  128, 32,  0,   0,   0,   0,   0,   1,   0,   0,   0,   62,  0,   0,   1,
+    83,  84,  65,  84,  116, 0,   0,   0,   5,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+    0,   4,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   1,   0,
+    0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+    0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+    0,   0,   0,   0,   0,   0,   0,   0,   4,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+    0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+    0,   0,   0,   0,   0,   0,   0,   0,   0,   0};
--- a/gfx/angle/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/clearsint11ps4.h
+++ b/gfx/angle/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/clearsint11ps4.h
@@ -1,104 +1,104 @@
-#if 0
-//
-// Generated by Microsoft (R) HLSL Shader Compiler 6.3.9600.16384
-//
-//
-// Buffer Definitions: 
-//
-// cbuffer ColorAndDepthDataSint
-// {
-//
-//   int4 color_Sint;                   // Offset:    0 Size:    16
-//   float zValueF_Sint;                // Offset:   16 Size:     4
-//
-// }
-//
-//
-// Resource Bindings:
-//
-// Name                                 Type  Format         Dim Slot Elements
-// ------------------------------ ---------- ------- ----------- ---- --------
-// ColorAndDepthDataSint             cbuffer      NA          NA    0        1
-//
-//
-//
-// Input signature:
-//
-// Name                 Index   Mask Register SysValue  Format   Used
-// -------------------- ----- ------ -------- -------- ------- ------
-// SV_POSITION              0   xyzw        0      POS   float       
-//
-//
-// Output signature:
-//
-// Name                 Index   Mask Register SysValue  Format   Used
-// -------------------- ----- ------ -------- -------- ------- ------
-// SV_TARGET                0   xyzw        0   TARGET     int   xyzw
-// SV_TARGET                1   xyzw        1   TARGET     int   xyzw
-// SV_TARGET                2   xyzw        2   TARGET     int   xyzw
-// SV_TARGET                3   xyzw        3   TARGET     int   xyzw
-// SV_DEPTH                 0    N/A   oDepth    DEPTH   float    YES
-//
-ps_4_0
-dcl_constantbuffer cb0[2], immediateIndexed
-dcl_output o0.xyzw
-dcl_output o1.xyzw
-dcl_output o2.xyzw
-dcl_output o3.xyzw
-dcl_output oDepth
-mov o0.xyzw, cb0[0].xyzw
-mov o1.xyzw, cb0[0].xyzw
-mov o2.xyzw, cb0[0].xyzw
-mov o3.xyzw, cb0[0].xyzw
-mov oDepth, cb0[1].x
-ret 
-// Approximately 6 instruction slots used
-#endif
-
-const BYTE g_PS_ClearSint4[] = {
-    68,  88,  66,  67,  86,  121, 157, 133, 160, 178, 28,  19,  207, 77,  229, 165, 39,  10,  12,
-    177, 1,   0,   0,   0,   100, 3,   0,   0,   5,   0,   0,   0,   52,  0,   0,   0,   72,  1,
-    0,   0,   124, 1,   0,   0,   24,  2,   0,   0,   232, 2,   0,   0,   82,  68,  69,  70,  12,
-    1,   0,   0,   1,   0,   0,   0,   84,  0,   0,   0,   1,   0,   0,   0,   28,  0,   0,   0,
-    0,   4,   255, 255, 0,   1,   0,   0,   216, 0,   0,   0,   60,  0,   0,   0,   0,   0,   0,
-    0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   1,   0,
-    0,   0,   1,   0,   0,   0,   67,  111, 108, 111, 114, 65,  110, 100, 68,  101, 112, 116, 104,
-    68,  97,  116, 97,  83,  105, 110, 116, 0,   171, 171, 60,  0,   0,   0,   2,   0,   0,   0,
-    108, 0,   0,   0,   32,  0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   156, 0,   0,
-    0,   0,   0,   0,   0,   16,  0,   0,   0,   2,   0,   0,   0,   168, 0,   0,   0,   0,   0,
-    0,   0,   184, 0,   0,   0,   16,  0,   0,   0,   4,   0,   0,   0,   2,   0,   0,   0,   200,
-    0,   0,   0,   0,   0,   0,   0,   99,  111, 108, 111, 114, 95,  83,  105, 110, 116, 0,   171,
-    1,   0,   2,   0,   1,   0,   4,   0,   0,   0,   0,   0,   0,   0,   0,   0,   122, 86,  97,
-    108, 117, 101, 70,  95,  83,  105, 110, 116, 0,   171, 171, 171, 0,   0,   3,   0,   1,   0,
-    1,   0,   0,   0,   0,   0,   0,   0,   0,   0,   77,  105, 99,  114, 111, 115, 111, 102, 116,
-    32,  40,  82,  41,  32,  72,  76,  83,  76,  32,  83,  104, 97,  100, 101, 114, 32,  67,  111,
-    109, 112, 105, 108, 101, 114, 32,  54,  46,  51,  46,  57,  54,  48,  48,  46,  49,  54,  51,
-    56,  52,  0,   171, 171, 73,  83,  71,  78,  44,  0,   0,   0,   1,   0,   0,   0,   8,   0,
-    0,   0,   32,  0,   0,   0,   0,   0,   0,   0,   1,   0,   0,   0,   3,   0,   0,   0,   0,
-    0,   0,   0,   15,  0,   0,   0,   83,  86,  95,  80,  79,  83,  73,  84,  73,  79,  78,  0,
-    79,  83,  71,  78,  148, 0,   0,   0,   5,   0,   0,   0,   8,   0,   0,   0,   128, 0,   0,
-    0,   0,   0,   0,   0,   0,   0,   0,   0,   2,   0,   0,   0,   0,   0,   0,   0,   15,  0,
-    0,   0,   128, 0,   0,   0,   1,   0,   0,   0,   0,   0,   0,   0,   2,   0,   0,   0,   1,
-    0,   0,   0,   15,  0,   0,   0,   128, 0,   0,   0,   2,   0,   0,   0,   0,   0,   0,   0,
-    2,   0,   0,   0,   2,   0,   0,   0,   15,  0,   0,   0,   128, 0,   0,   0,   3,   0,   0,
-    0,   0,   0,   0,   0,   2,   0,   0,   0,   3,   0,   0,   0,   15,  0,   0,   0,   138, 0,
-    0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   3,   0,   0,   0,   255, 255, 255, 255, 1,
-    14,  0,   0,   83,  86,  95,  84,  65,  82,  71,  69,  84,  0,   83,  86,  95,  68,  69,  80,
-    84,  72,  0,   171, 83,  72,  68,  82,  200, 0,   0,   0,   64,  0,   0,   0,   50,  0,   0,
-    0,   89,  0,   0,   4,   70,  142, 32,  0,   0,   0,   0,   0,   2,   0,   0,   0,   101, 0,
-    0,   3,   242, 32,  16,  0,   0,   0,   0,   0,   101, 0,   0,   3,   242, 32,  16,  0,   1,
-    0,   0,   0,   101, 0,   0,   3,   242, 32,  16,  0,   2,   0,   0,   0,   101, 0,   0,   3,
-    242, 32,  16,  0,   3,   0,   0,   0,   101, 0,   0,   2,   1,   192, 0,   0,   54,  0,   0,
-    6,   242, 32,  16,  0,   0,   0,   0,   0,   70,  142, 32,  0,   0,   0,   0,   0,   0,   0,
-    0,   0,   54,  0,   0,   6,   242, 32,  16,  0,   1,   0,   0,   0,   70,  142, 32,  0,   0,
-    0,   0,   0,   0,   0,   0,   0,   54,  0,   0,   6,   242, 32,  16,  0,   2,   0,   0,   0,
-    70,  142, 32,  0,   0,   0,   0,   0,   0,   0,   0,   0,   54,  0,   0,   6,   242, 32,  16,
-    0,   3,   0,   0,   0,   70,  142, 32,  0,   0,   0,   0,   0,   0,   0,   0,   0,   54,  0,
-    0,   5,   1,   192, 0,   0,   10,  128, 32,  0,   0,   0,   0,   0,   1,   0,   0,   0,   62,
-    0,   0,   1,   83,  84,  65,  84,  116, 0,   0,   0,   6,   0,   0,   0,   0,   0,   0,   0,
-    0,   0,   0,   0,   5,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
-    0,   1,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
-    0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
-    0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   5,   0,   0,   0,   0,   0,   0,   0,
-    0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
-    0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0};
+#if 0
+//
+// Generated by Microsoft (R) HLSL Shader Compiler 6.3.9600.16384
+//
+//
+// Buffer Definitions: 
+//
+// cbuffer ColorAndDepthDataSint
+// {
+//
+//   int4 color_Sint;                   // Offset:    0 Size:    16
+//   float zValueF_Sint;                // Offset:   16 Size:     4
+//
+// }
+//
+//
+// Resource Bindings:
+//
+// Name                                 Type  Format         Dim Slot Elements
+// ------------------------------ ---------- ------- ----------- ---- --------
+// ColorAndDepthDataSint             cbuffer      NA          NA    0        1
+//
+//
+//
+// Input signature:
+//
+// Name                 Index   Mask Register SysValue  Format   Used
+// -------------------- ----- ------ -------- -------- ------- ------
+// SV_POSITION              0   xyzw        0      POS   float       
+//
+//
+// Output signature:
+//
+// Name                 Index   Mask Register SysValue  Format   Used
+// -------------------- ----- ------ -------- -------- ------- ------
+// SV_TARGET                0   xyzw        0   TARGET     int   xyzw
+// SV_TARGET                1   xyzw        1   TARGET     int   xyzw
+// SV_TARGET                2   xyzw        2   TARGET     int   xyzw
+// SV_TARGET                3   xyzw        3   TARGET     int   xyzw
+// SV_DEPTH                 0    N/A   oDepth    DEPTH   float    YES
+//
+ps_4_0
+dcl_constantbuffer cb0[2], immediateIndexed
+dcl_output o0.xyzw
+dcl_output o1.xyzw
+dcl_output o2.xyzw
+dcl_output o3.xyzw
+dcl_output oDepth
+mov o0.xyzw, cb0[0].xyzw
+mov o1.xyzw, cb0[0].xyzw
+mov o2.xyzw, cb0[0].xyzw
+mov o3.xyzw, cb0[0].xyzw
+mov oDepth, cb0[1].x
+ret 
+// Approximately 6 instruction slots used
+#endif
+
+const BYTE g_PS_ClearSint4[] = {
+    68,  88,  66,  67,  86,  121, 157, 133, 160, 178, 28,  19,  207, 77,  229, 165, 39,  10,  12,
+    177, 1,   0,   0,   0,   100, 3,   0,   0,   5,   0,   0,   0,   52,  0,   0,   0,   72,  1,
+    0,   0,   124, 1,   0,   0,   24,  2,   0,   0,   232, 2,   0,   0,   82,  68,  69,  70,  12,
+    1,   0,   0,   1,   0,   0,   0,   84,  0,   0,   0,   1,   0,   0,   0,   28,  0,   0,   0,
+    0,   4,   255, 255, 0,   1,   0,   0,   216, 0,   0,   0,   60,  0,   0,   0,   0,   0,   0,
+    0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   1,   0,
+    0,   0,   1,   0,   0,   0,   67,  111, 108, 111, 114, 65,  110, 100, 68,  101, 112, 116, 104,
+    68,  97,  116, 97,  83,  105, 110, 116, 0,   171, 171, 60,  0,   0,   0,   2,   0,   0,   0,
+    108, 0,   0,   0,   32,  0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   156, 0,   0,
+    0,   0,   0,   0,   0,   16,  0,   0,   0,   2,   0,   0,   0,   168, 0,   0,   0,   0,   0,
+    0,   0,   184, 0,   0,   0,   16,  0,   0,   0,   4,   0,   0,   0,   2,   0,   0,   0,   200,
+    0,   0,   0,   0,   0,   0,   0,   99,  111, 108, 111, 114, 95,  83,  105, 110, 116, 0,   171,
+    1,   0,   2,   0,   1,   0,   4,   0,   0,   0,   0,   0,   0,   0,   0,   0,   122, 86,  97,
+    108, 117, 101, 70,  95,  83,  105, 110, 116, 0,   171, 171, 171, 0,   0,   3,   0,   1,   0,
+    1,   0,   0,   0,   0,   0,   0,   0,   0,   0,   77,  105, 99,  114, 111, 115, 111, 102, 116,
+    32,  40,  82,  41,  32,  72,  76,  83,  76,  32,  83,  104, 97,  100, 101, 114, 32,  67,  111,
+    109, 112, 105, 108, 101, 114, 32,  54,  46,  51,  46,  57,  54,  48,  48,  46,  49,  54,  51,
+    56,  52,  0,   171, 171, 73,  83,  71,  78,  44,  0,   0,   0,   1,   0,   0,   0,   8,   0,
+    0,   0,   32,  0,   0,   0,   0,   0,   0,   0,   1,   0,   0,   0,   3,   0,   0,   0,   0,
+    0,   0,   0,   15,  0,   0,   0,   83,  86,  95,  80,  79,  83,  73,  84,  73,  79,  78,  0,
+    79,  83,  71,  78,  148, 0,   0,   0,   5,   0,   0,   0,   8,   0,   0,   0,   128, 0,   0,
+    0,   0,   0,   0,   0,   0,   0,   0,   0,   2,   0,   0,   0,   0,   0,   0,   0,   15,  0,
+    0,   0,   128, 0,   0,   0,   1,   0,   0,   0,   0,   0,   0,   0,   2,   0,   0,   0,   1,
+    0,   0,   0,   15,  0,   0,   0,   128, 0,   0,   0,   2,   0,   0,   0,   0,   0,   0,   0,
+    2,   0,   0,   0,   2,   0,   0,   0,   15,  0,   0,   0,   128, 0,   0,   0,   3,   0,   0,
+    0,   0,   0,   0,   0,   2,   0,   0,   0,   3,   0,   0,   0,   15,  0,   0,   0,   138, 0,
+    0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   3,   0,   0,   0,   255, 255, 255, 255, 1,
+    14,  0,   0,   83,  86,  95,  84,  65,  82,  71,  69,  84,  0,   83,  86,  95,  68,  69,  80,
+    84,  72,  0,   171, 83,  72,  68,  82,  200, 0,   0,   0,   64,  0,   0,   0,   50,  0,   0,
+    0,   89,  0,   0,   4,   70,  142, 32,  0,   0,   0,   0,   0,   2,   0,   0,   0,   101, 0,
+    0,   3,   242, 32,  16,  0,   0,   0,   0,   0,   101, 0,   0,   3,   242, 32,  16,  0,   1,
+    0,   0,   0,   101, 0,   0,   3,   242, 32,  16,  0,   2,   0,   0,   0,   101, 0,   0,   3,
+    242, 32,  16,  0,   3,   0,   0,   0,   101, 0,   0,   2,   1,   192, 0,   0,   54,  0,   0,
+    6,   242, 32,  16,  0,   0,   0,   0,   0,   70,  142, 32,  0,   0,   0,   0,   0,   0,   0,
+    0,   0,   54,  0,   0,   6,   242, 32,  16,  0,   1,   0,   0,   0,   70,  142, 32,  0,   0,
+    0,   0,   0,   0,   0,   0,   0,   54,  0,   0,   6,   242, 32,  16,  0,   2,   0,   0,   0,
+    70,  142, 32,  0,   0,   0,   0,   0,   0,   0,   0,   0,   54,  0,   0,   6,   242, 32,  16,
+    0,   3,   0,   0,   0,   70,  142, 32,  0,   0,   0,   0,   0,   0,   0,   0,   0,   54,  0,
+    0,   5,   1,   192, 0,   0,   10,  128, 32,  0,   0,   0,   0,   0,   1,   0,   0,   0,   62,
+    0,   0,   1,   83,  84,  65,  84,  116, 0,   0,   0,   6,   0,   0,   0,   0,   0,   0,   0,
+    0,   0,   0,   0,   5,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+    0,   1,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+    0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+    0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   5,   0,   0,   0,   0,   0,   0,   0,
+    0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+    0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0};
--- a/gfx/angle/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/clearsint11ps5.h
+++ b/gfx/angle/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/clearsint11ps5.h
@@ -1,110 +1,110 @@
-#if 0
-//
-// Generated by Microsoft (R) HLSL Shader Compiler 6.3.9600.16384
-//
-//
-// Buffer Definitions: 
-//
-// cbuffer ColorAndDepthDataSint
-// {
-//
-//   int4 color_Sint;                   // Offset:    0 Size:    16
-//   float zValueF_Sint;                // Offset:   16 Size:     4
-//
-// }
-//
-//
-// Resource Bindings:
-//
-// Name                                 Type  Format         Dim Slot Elements
-// ------------------------------ ---------- ------- ----------- ---- --------
-// ColorAndDepthDataSint             cbuffer      NA          NA    0        1
-//
-//
-//
-// Input signature:
-//
-// Name                 Index   Mask Register SysValue  Format   Used
-// -------------------- ----- ------ -------- -------- ------- ------
-// SV_POSITION              0   xyzw        0      POS   float       
-//
-//
-// Output signature:
-//
-// Name                 Index   Mask Register SysValue  Format   Used
-// -------------------- ----- ------ -------- -------- ------- ------
-// SV_TARGET                0   xyzw        0   TARGET     int   xyzw
-// SV_TARGET                1   xyzw        1   TARGET     int   xyzw
-// SV_TARGET                2   xyzw        2   TARGET     int   xyzw
-// SV_TARGET                3   xyzw        3   TARGET     int   xyzw
-// SV_TARGET                4   xyzw        4   TARGET     int   xyzw
-// SV_DEPTH                 0    N/A   oDepth    DEPTH   float    YES
-//
-ps_4_0
-dcl_constantbuffer cb0[2], immediateIndexed
-dcl_output o0.xyzw
-dcl_output o1.xyzw
-dcl_output o2.xyzw
-dcl_output o3.xyzw
-dcl_output o4.xyzw
-dcl_output oDepth
-mov o0.xyzw, cb0[0].xyzw
-mov o1.xyzw, cb0[0].xyzw
-mov o2.xyzw, cb0[0].xyzw
-mov o3.xyzw, cb0[0].xyzw
-mov o4.xyzw, cb0[0].xyzw
-mov oDepth, cb0[1].x
-ret 
-// Approximately 7 instruction slots used
-#endif
-
-const BYTE g_PS_ClearSint5[] = {
-    68,  88,  66,  67,  107, 129, 105, 65,  196, 155, 48,  132, 184, 42,  88,  150, 96,  246, 10,
-    243, 1,   0,   0,   0,   160, 3,   0,   0,   5,   0,   0,   0,   52,  0,   0,   0,   72,  1,
-    0,   0,   124, 1,   0,   0,   48,  2,   0,   0,   36,  3,   0,   0,   82,  68,  69,  70,  12,
-    1,   0,   0,   1,   0,   0,   0,   84,  0,   0,   0,   1,   0,   0,   0,   28,  0,   0,   0,
-    0,   4,   255, 255, 0,   1,   0,   0,   216, 0,   0,   0,   60,  0,   0,   0,   0,   0,   0,
-    0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   1,   0,
-    0,   0,   1,   0,   0,   0,   67,  111, 108, 111, 114, 65,  110, 100, 68,  101, 112, 116, 104,
-    68,  97,  116, 97,  83,  105, 110, 116, 0,   171, 171, 60,  0,   0,   0,   2,   0,   0,   0,
-    108, 0,   0,   0,   32,  0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   156, 0,   0,
-    0,   0,   0,   0,   0,   16,  0,   0,   0,   2,   0,   0,   0,   168, 0,   0,   0,   0,   0,
-    0,   0,   184, 0,   0,   0,   16,  0,   0,   0,   4,   0,   0,   0,   2,   0,   0,   0,   200,
-    0,   0,   0,   0,   0,   0,   0,   99,  111, 108, 111, 114, 95,  83,  105, 110, 116, 0,   171,
-    1,   0,   2,   0,   1,   0,   4,   0,   0,   0,   0,   0,   0,   0,   0,   0,   122, 86,  97,
-    108, 117, 101, 70,  95,  83,  105, 110, 116, 0,   171, 171, 171, 0,   0,   3,   0,   1,   0,
-    1,   0,   0,   0,   0,   0,   0,   0,   0,   0,   77,  105, 99,  114, 111, 115, 111, 102, 116,
-    32,  40,  82,  41,  32,  72,  76,  83,  76,  32,  83,  104, 97,  100, 101, 114, 32,  67,  111,
-    109, 112, 105, 108, 101, 114, 32,  54,  46,  51,  46,  57,  54,  48,  48,  46,  49,  54,  51,
-    56,  52,  0,   171, 171, 73,  83,  71,  78,  44,  0,   0,   0,   1,   0,   0,   0,   8,   0,
-    0,   0,   32,  0,   0,   0,   0,   0,   0,   0,   1,   0,   0,   0,   3,   0,   0,   0,   0,
-    0,   0,   0,   15,  0,   0,   0,   83,  86,  95,  80,  79,  83,  73,  84,  73,  79,  78,  0,
-    79,  83,  71,  78,  172, 0,   0,   0,   6,   0,   0,   0,   8,   0,   0,   0,   152, 0,   0,
-    0,   0,   0,   0,   0,   0,   0,   0,   0,   2,   0,   0,   0,   0,   0,   0,   0,   15,  0,
-    0,   0,   152, 0,   0,   0,   1,   0,   0,   0,   0,   0,   0,   0,   2,   0,   0,   0,   1,
-    0,   0,   0,   15,  0,   0,   0,   152, 0,   0,   0,   2,   0,   0,   0,   0,   0,   0,   0,
-    2,   0,   0,   0,   2,   0,   0,   0,   15,  0,   0,   0,   152, 0,   0,   0,   3,   0,   0,
-    0,   0,   0,   0,   0,   2,   0,   0,   0,   3,   0,   0,   0,   15,  0,   0,   0,   152, 0,
-    0,   0,   4,   0,   0,   0,   0,   0,   0,   0,   2,   0,   0,   0,   4,   0,   0,   0,   15,
-    0,   0,   0,   162, 0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   3,   0,   0,   0,
-    255, 255, 255, 255, 1,   14,  0,   0,   83,  86,  95,  84,  65,  82,  71,  69,  84,  0,   83,
-    86,  95,  68,  69,  80,  84,  72,  0,   171, 83,  72,  68,  82,  236, 0,   0,   0,   64,  0,
-    0,   0,   59,  0,   0,   0,   89,  0,   0,   4,   70,  142, 32,  0,   0,   0,   0,   0,   2,
-    0,   0,   0,   101, 0,   0,   3,   242, 32,  16,  0,   0,   0,   0,   0,   101, 0,   0,   3,
-    242, 32,  16,  0,   1,   0,   0,   0,   101, 0,   0,   3,   242, 32,  16,  0,   2,   0,   0,
-    0,   101, 0,   0,   3,   242, 32,  16,  0,   3,   0,   0,   0,   101, 0,   0,   3,   242, 32,
-    16,  0,   4,   0,   0,   0,   101, 0,   0,   2,   1,   192, 0,   0,   54,  0,   0,   6,   242,
-    32,  16,  0,   0,   0,   0,   0,   70,  142, 32,  0,   0,   0,   0,   0,   0,   0,   0,   0,
-    54,  0,   0,   6,   242, 32,  16,  0,   1,   0,   0,   0,   70,  142, 32,  0,   0,   0,   0,
-    0,   0,   0,   0,   0,   54,  0,   0,   6,   242, 32,  16,  0,   2,   0,   0,   0,   70,  142,
-    32,  0,   0,   0,   0,   0,   0,   0,   0,   0,   54,  0,   0,   6,   242, 32,  16,  0,   3,
-    0,   0,   0,   70,  142, 32,  0,   0,   0,   0,   0,   0,   0,   0,   0,   54,  0,   0,   6,
-    242, 32,  16,  0,   4,   0,   0,   0,   70,  142, 32,  0,   0,   0,   0,   0,   0,   0,   0,
-    0,   54,  0,   0,   5,   1,   192, 0,   0,   10,  128, 32,  0,   0,   0,   0,   0,   1,   0,
-    0,   0,   62,  0,   0,   1,   83,  84,  65,  84,  116, 0,   0,   0,   7,   0,   0,   0,   0,
-    0,   0,   0,   0,   0,   0,   0,   6,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
-    0,   0,   0,   0,   1,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
-    0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
-    0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   6,   0,   0,   0,   0,
-    0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
-    0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0};
+#if 0
+//
+// Generated by Microsoft (R) HLSL Shader Compiler 6.3.9600.16384
+//
+//
+// Buffer Definitions: 
+//
+// cbuffer ColorAndDepthDataSint
+// {
+//
+//   int4 color_Sint;                   // Offset:    0 Size:    16
+//   float zValueF_Sint;                // Offset:   16 Size:     4
+//
+// }
+//
+//
+// Resource Bindings:
+//
+// Name                                 Type  Format         Dim Slot Elements
+// ------------------------------ ---------- ------- ----------- ---- --------
+// ColorAndDepthDataSint             cbuffer      NA          NA    0        1
+//
+//
+//
+// Input signature:
+//
+// Name                 Index   Mask Register SysValue  Format   Used
+// -------------------- ----- ------ -------- -------- ------- ------
+// SV_POSITION              0   xyzw        0      POS   float       
+//
+//
+// Output signature:
+//
+// Name                 Index   Mask Register SysValue  Format   Used
+// -------------------- ----- ------ -------- -------- ------- ------
+// SV_TARGET                0   xyzw        0   TARGET     int   xyzw
+// SV_TARGET                1   xyzw        1   TARGET     int   xyzw
+// SV_TARGET                2   xyzw        2   TARGET     int   xyzw
+// SV_TARGET                3   xyzw        3   TARGET     int   xyzw
+// SV_TARGET                4   xyzw        4   TARGET     int   xyzw
+// SV_DEPTH                 0    N/A   oDepth    DEPTH   float    YES
+//
+ps_4_0
+dcl_constantbuffer cb0[2], immediateIndexed
+dcl_output o0.xyzw
+dcl_output o1.xyzw
+dcl_output o2.xyzw
+dcl_output o3.xyzw
+dcl_output o4.xyzw
+dcl_output oDepth
+mov o0.xyzw, cb0[0].xyzw
+mov o1.xyzw, cb0[0].xyzw
+mov o2.xyzw, cb0[0].xyzw
+mov o3.xyzw, cb0[0].xyzw
+mov o4.xyzw, cb0[0].xyzw
+mov oDepth, cb0[1].x
+ret 
+// Approximately 7 instruction slots used
+#endif
+
+const BYTE g_PS_ClearSint5[] = {
+    68,  88,  66,  67,  107, 129, 105, 65,  196, 155, 48,  132, 184, 42,  88,  150, 96,  246, 10,
+    243, 1,   0,   0,   0,   160, 3,   0,   0,   5,   0,   0,   0,   52,  0,   0,   0,   72,  1,
+    0,   0,   124, 1,   0,   0,   48,  2,   0,   0,   36,  3,   0,   0,   82,  68,  69,  70,  12,
+    1,   0,   0,   1,   0,   0,   0,   84,  0,   0,   0,   1,   0,   0,   0,   28,  0,   0,   0,
+    0,   4,   255, 255, 0,   1,   0,   0,   216, 0,   0,   0,   60,  0,   0,   0,   0,   0,   0,
+    0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   1,   0,
+    0,   0,   1,   0,   0,   0,   67,  111, 108, 111, 114, 65,  110, 100, 68,  101, 112, 116, 104,
+    68,  97,  116, 97,  83,  105, 110, 116, 0,   171, 171, 60,  0,   0,   0,   2,   0,   0,   0,
+    108, 0,   0,   0,   32,  0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   156, 0,   0,
+    0,   0,   0,   0,   0,   16,  0,   0,   0,   2,   0,   0,   0,   168, 0,   0,   0,   0,   0,
+    0,   0,   184, 0,   0,   0,   16,  0,   0,   0,   4,   0,   0,   0,   2,   0,   0,   0,   200,
+    0,   0,   0,   0,   0,   0,   0,   99,  111, 108, 111, 114, 95,  83,  105, 110, 116, 0,   171,
+    1,   0,   2,   0,   1,   0,   4,   0,   0,   0,   0,   0,   0,   0,   0,   0,   122, 86,  97,
+    108, 117, 101, 70,  95,  83,  105, 110, 116, 0,   171, 171, 171, 0,   0,   3,   0,   1,   0,
+    1,   0,   0,   0,   0,   0,   0,   0,   0,   0,   77,  105, 99,  114, 111, 115, 111, 102, 116,
+    32,  40,  82,  41,  32,  72,  76,  83,  76,  32,  83,  104, 97,  100, 101, 114, 32,  67,  111,
+    109, 112, 105, 108, 101, 114, 32,  54,  46,  51,  46,  57,  54,  48,  48,  46,  49,  54,  51,
+    56,  52,  0,   171, 171, 73,  83,  71,  78,  44,  0,   0,   0,   1,   0,   0,   0,   8,   0,
+    0,   0,   32,  0,   0,   0,   0,   0,   0,   0,   1,   0,   0,   0,   3,   0,   0,   0,   0,
+    0,   0,   0,   15,  0,   0,   0,   83,  86,  95,  80,  79,  83,  73,  84,  73,  79,  78,  0,
+    79,  83,  71,  78,  172, 0,   0,   0,   6,   0,   0,   0,   8,   0,   0,   0,   152, 0,   0,
+    0,   0,   0,   0,   0,   0,   0,   0,   0,   2,   0,   0,   0,   0,   0,   0,   0,   15,  0,
+    0,   0,   152, 0,   0,   0,   1,   0,   0,   0,   0,   0,   0,   0,   2,   0,   0,   0,   1,
+    0,   0,   0,   15,  0,   0,   0,   152, 0,   0,   0,   2,   0,   0,   0,   0,   0,   0,   0,
+    2,   0,   0,   0,   2,   0,   0,   0,   15,  0,   0,   0,   152, 0,   0,   0,   3,   0,   0,
+    0,   0,   0,   0,   0,   2,   0,   0,   0,   3,   0,   0,   0,   15,  0,   0,   0,   152, 0,
+    0,   0,   4,   0,   0,   0,   0,   0,   0,   0,   2,   0,   0,   0,   4,   0,   0,   0,   15,
+    0,   0,   0,   162, 0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   3,   0,   0,   0,
+    255, 255, 255, 255, 1,   14,  0,   0,   83,  86,  95,  84,  65,  82,  71,  69,  84,  0,   83,
+    86,  95,  68,  69,  80,  84,  72,  0,   171, 83,  72,  68,  82,  236, 0,   0,   0,   64,  0,
+    0,   0,   59,  0,   0,   0,   89,  0,   0,   4,   70,  142, 32,  0,   0,   0,   0,   0,   2,
+    0,   0,   0,   101, 0,   0,   3,   242, 32,  16,  0,   0,   0,   0,   0,   101, 0,   0,   3,
+    242, 32,  16,  0,   1,   0,   0,   0,   101, 0,   0,   3,   242, 32,  16,  0,   2,   0,   0,
+    0,   101, 0,   0,   3,   242, 32,  16,  0,   3,   0,   0,   0,   101, 0,   0,   3,   242, 32,
+    16,  0,   4,   0,   0,   0,   101, 0,   0,   2,   1,   192, 0,   0,   54,  0,   0,   6,   242,
+    32,  16,  0,   0,   0,   0,   0,   70,  142, 32,  0,   0,   0,   0,   0,   0,   0,   0,   0,
+    54,  0,   0,   6,   242, 32,  16,  0,   1,   0,   0,   0,   70,  142, 32,  0,   0,   0,   0,
+    0,   0,   0,   0,   0,   54,  0,   0,   6,   242, 32,  16,  0,   2,   0,   0,   0,   70,  142,
+    32,  0,   0,   0,   0,   0,   0,   0,   0,   0,   54,  0,   0,   6,   242, 32,  16,  0,   3,
+    0,   0,   0,   70,  142, 32,  0,   0,   0,   0,   0,   0,   0,   0,   0,   54,  0,   0,   6,
+    242, 32,  16,  0,   4,   0,   0,   0,   70,  142, 32,  0,   0,   0,   0,   0,   0,   0,   0,
+    0,   54,  0,   0,   5,   1,   192, 0,   0,   10,  128, 32,  0,   0,   0,   0,   0,   1,   0,
+    0,   0,   62,  0,   0,   1,   83,  84,  65,  84,  116, 0,   0,   0,   7,   0,   0,   0,   0,
+    0,   0,   0,   0,   0,   0,   0,   6,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+    0,   0,   0,   0,   1,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+    0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+    0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   6,   0,   0,   0,   0,
+    0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+    0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0};
--- a/gfx/angle/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/clearsint11ps6.h
+++ b/gfx/angle/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/clearsint11ps6.h
@@ -1,116 +1,116 @@
-#if 0
-//
-// Generated by Microsoft (R) HLSL Shader Compiler 6.3.9600.16384
-//
-//
-// Buffer Definitions: 
-//
-// cbuffer ColorAndDepthDataSint
-// {
-//
-//   int4 color_Sint;                   // Offset:    0 Size:    16
-//   float zValueF_Sint;                // Offset:   16 Size:     4
-//
-// }
-//
-//
-// Resource Bindings:
-//
-// Name                                 Type  Format         Dim Slot Elements
-// ------------------------------ ---------- ------- ----------- ---- --------
-// ColorAndDepthDataSint             cbuffer      NA          NA    0        1
-//
-//
-//
-// Input signature:
-//
-// Name                 Index   Mask Register SysValue  Format   Used
-// -------------------- ----- ------ -------- -------- ------- ------
-// SV_POSITION              0   xyzw        0      POS   float       
-//
-//
-// Output signature:
-//
-// Name                 Index   Mask Register SysValue  Format   Used
-// -------------------- ----- ------ -------- -------- ------- ------
-// SV_TARGET                0   xyzw        0   TARGET     int   xyzw
-// SV_TARGET                1   xyzw        1   TARGET     int   xyzw
-// SV_TARGET                2   xyzw        2   TARGET     int   xyzw
-// SV_TARGET                3   xyzw        3   TARGET     int   xyzw
-// SV_TARGET                4   xyzw        4   TARGET     int   xyzw
-// SV_TARGET                5   xyzw        5   TARGET     int   xyzw
-// SV_DEPTH                 0    N/A   oDepth    DEPTH   float    YES
-//
-ps_4_0
-dcl_constantbuffer cb0[2], immediateIndexed
-dcl_output o0.xyzw
-dcl_output o1.xyzw
-dcl_output o2.xyzw
-dcl_output o3.xyzw
-dcl_output o4.xyzw
-dcl_output o5.xyzw
-dcl_output oDepth
-mov o0.xyzw, cb0[0].xyzw
-mov o1.xyzw, cb0[0].xyzw
-mov o2.xyzw, cb0[0].xyzw
-mov o3.xyzw, cb0[0].xyzw
-mov o4.xyzw, cb0[0].xyzw
-mov o5.xyzw, cb0[0].xyzw
-mov oDepth, cb0[1].x
-ret 
-// Approximately 8 instruction slots used
-#endif
-
-const BYTE g_PS_ClearSint6[] = {
-    68,  88,  66,  67,  224, 172, 158, 172, 195, 197, 14,  59,  216, 200, 243, 209, 33,  202, 68,
-    50,  1,   0,   0,   0,   220, 3,   0,   0,   5,   0,   0,   0,   52,  0,   0,   0,   72,  1,
-    0,   0,   124, 1,   0,   0,   72,  2,   0,   0,   96,  3,   0,   0,   82,  68,  69,  70,  12,
-    1,   0,   0,   1,   0,   0,   0,   84,  0,   0,   0,   1,   0,   0,   0,   28,  0,   0,   0,
-    0,   4,   255, 255, 0,   1,   0,   0,   216, 0,   0,   0,   60,  0,   0,   0,   0,   0,   0,
-    0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   1,   0,
-    0,   0,   1,   0,   0,   0,   67,  111, 108, 111, 114, 65,  110, 100, 68,  101, 112, 116, 104,
-    68,  97,  116, 97,  83,  105, 110, 116, 0,   171, 171, 60,  0,   0,   0,   2,   0,   0,   0,
-    108, 0,   0,   0,   32,  0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   156, 0,   0,
-    0,   0,   0,   0,   0,   16,  0,   0,   0,   2,   0,   0,   0,   168, 0,   0,   0,   0,   0,
-    0,   0,   184, 0,   0,   0,   16,  0,   0,   0,   4,   0,   0,   0,   2,   0,   0,   0,   200,
-    0,   0,   0,   0,   0,   0,   0,   99,  111, 108, 111, 114, 95,  83,  105, 110, 116, 0,   171,
-    1,   0,   2,   0,   1,   0,   4,   0,   0,   0,   0,   0,   0,   0,   0,   0,   122, 86,  97,
-    108, 117, 101, 70,  95,  83,  105, 110, 116, 0,   171, 171, 171, 0,   0,   3,   0,   1,   0,
-    1,   0,   0,   0,   0,   0,   0,   0,   0,   0,   77,  105, 99,  114, 111, 115, 111, 102, 116,
-    32,  40,  82,  41,  32,  72,  76,  83,  76,  32,  83,  104, 97,  100, 101, 114, 32,  67,  111,
-    109, 112, 105, 108, 101, 114, 32,  54,  46,  51,  46,  57,  54,  48,  48,  46,  49,  54,  51,
-    56,  52,  0,   171, 171, 73,  83,  71,  78,  44,  0,   0,   0,   1,   0,   0,   0,   8,   0,
-    0,   0,   32,  0,   0,   0,   0,   0,   0,   0,   1,   0,   0,   0,   3,   0,   0,   0,   0,
-    0,   0,   0,   15,  0,   0,   0,   83,  86,  95,  80,  79,  83,  73,  84,  73,  79,  78,  0,
-    79,  83,  71,  78,  196, 0,   0,   0,   7,   0,   0,   0,   8,   0,   0,   0,   176, 0,   0,
-    0,   0,   0,   0,   0,   0,   0,   0,   0,   2,   0,   0,   0,   0,   0,   0,   0,   15,  0,
-    0,   0,   176, 0,   0,   0,   1,   0,   0,   0,   0,   0,   0,   0,   2,   0,   0,   0,   1,
-    0,   0,   0,   15,  0,   0,   0,   176, 0,   0,   0,   2,   0,   0,   0,   0,   0,   0,   0,
-    2,   0,   0,   0,   2,   0,   0,   0,   15,  0,   0,   0,   176, 0,   0,   0,   3,   0,   0,
-    0,   0,   0,   0,   0,   2,   0,   0,   0,   3,   0,   0,   0,   15,  0,   0,   0,   176, 0,
-    0,   0,   4,   0,   0,   0,   0,   0,   0,   0,   2,   0,   0,   0,   4,   0,   0,   0,   15,
-    0,   0,   0,   176, 0,   0,   0,   5,   0,   0,   0,   0,   0,   0,   0,   2,   0,   0,   0,
-    5,   0,   0,   0,   15,  0,   0,   0,   186, 0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
-    0,   3,   0,   0,   0,   255, 255, 255, 255, 1,   14,  0,   0,   83,  86,  95,  84,  65,  82,
-    71,  69,  84,  0,   83,  86,  95,  68,  69,  80,  84,  72,  0,   171, 83,  72,  68,  82,  16,
-    1,   0,   0,   64,  0,   0,   0,   68,  0,   0,   0,   89,  0,   0,   4,   70,  142, 32,  0,
-    0,   0,   0,   0,   2,   0,   0,   0,   101, 0,   0,   3,   242, 32,  16,  0,   0,   0,   0,
-    0,   101, 0,   0,   3,   242, 32,  16,  0,   1,   0,   0,   0,   101, 0,   0,   3,   242, 32,
-    16,  0,   2,   0,   0,   0,   101, 0,   0,   3,   242, 32,  16,  0,   3,   0,   0,   0,   101,
-    0,   0,   3,   242, 32,  16,  0,   4,   0,   0,   0,   101, 0,   0,   3,   242, 32,  16,  0,
-    5,   0,   0,   0,   101, 0,   0,   2,   1,   192, 0,   0,   54,  0,   0,   6,   242, 32,  16,
-    0,   0,   0,   0,   0,   70,  142, 32,  0,   0,   0,   0,   0,   0,   0,   0,   0,   54,  0,
-    0,   6,   242, 32,  16,  0,   1,   0,   0,   0,   70,  142, 32,  0,   0,   0,   0,   0,   0,
-    0,   0,   0,   54,  0,   0,   6,   242, 32,  16,  0,   2,   0,   0,   0,   70,  142, 32,  0,
-    0,   0,   0,   0,   0,   0,   0,   0,   54,  0,   0,   6,   242, 32,  16,  0,   3,   0,   0,
-    0,   70,  142, 32,  0,   0,   0,   0,   0,   0,   0,   0,   0,   54,  0,   0,   6,   242, 32,
-    16,  0,   4,   0,   0,   0,   70,  142, 32,  0,   0,   0,   0,   0,   0,   0,   0,   0,   54,
-    0,   0,   6,   242, 32,  16,  0,   5,   0,   0,   0,   70,  142, 32,  0,   0,   0,   0,   0,
-    0,   0,   0,   0,   54,  0,   0,   5,   1,   192, 0,   0,   10,  128, 32,  0,   0,   0,   0,
-    0,   1,   0,   0,   0,   62,  0,   0,   1,   83,  84,  65,  84,  116, 0,   0,   0,   8,   0,
-    0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   7,   0,   0,   0,   0,   0,   0,   0,   0,
-    0,   0,   0,   0,   0,   0,   0,   1,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
-    0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
-    0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   7,   0,
-    0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
-    0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0};
+#if 0
+//
+// Generated by Microsoft (R) HLSL Shader Compiler 6.3.9600.16384
+//
+//
+// Buffer Definitions: 
+//
+// cbuffer ColorAndDepthDataSint
+// {
+//
+//   int4 color_Sint;                   // Offset:    0 Size:    16
+//   float zValueF_Sint;                // Offset:   16 Size:     4
+//
+// }
+//
+//
+// Resource Bindings:
+//
+// Name                                 Type  Format         Dim Slot Elements
+// ------------------------------ ---------- ------- ----------- ---- --------
+// ColorAndDepthDataSint             cbuffer      NA          NA    0        1
+//
+//
+//
+// Input signature:
+//
+// Name                 Index   Mask Register SysValue  Format   Used
+// -------------------- ----- ------ -------- -------- ------- ------
+// SV_POSITION              0   xyzw        0      POS   float       
+//
+//
+// Output signature:
+//
+// Name                 Index   Mask Register SysValue  Format   Used
+// -------------------- ----- ------ -------- -------- ------- ------
+// SV_TARGET                0   xyzw        0   TARGET     int   xyzw
+// SV_TARGET                1   xyzw        1   TARGET     int   xyzw
+// SV_TARGET                2   xyzw        2   TARGET     int   xyzw
+// SV_TARGET                3   xyzw        3   TARGET     int   xyzw
+// SV_TARGET                4   xyzw        4   TARGET     int   xyzw
+// SV_TARGET                5   xyzw        5   TARGET     int   xyzw
+// SV_DEPTH                 0    N/A   oDepth    DEPTH   float    YES
+//
+ps_4_0
+dcl_constantbuffer cb0[2], immediateIndexed
+dcl_output o0.xyzw
+dcl_output o1.xyzw
+dcl_output o2.xyzw
+dcl_output o3.xyzw
+dcl_output o4.xyzw
+dcl_output o5.xyzw
+dcl_output oDepth
+mov o0.xyzw, cb0[0].xyzw
+mov o1.xyzw, cb0[0].xyzw
+mov o2.xyzw, cb0[0].xyzw
+mov o3.xyzw, cb0[0].xyzw
+mov o4.xyzw, cb0[0].xyzw
+mov o5.xyzw, cb0[0].xyzw
+mov oDepth, cb0[1].x
+ret 
+// Approximately 8 instruction slots used
+#endif
+
+const BYTE g_PS_ClearSint6[] = {
+    68,  88,  66,  67,  224, 172, 158, 172, 195, 197, 14,  59,  216, 200, 243, 209, 33,  202, 68,
+    50,  1,   0,   0,   0,   220, 3,   0,   0,   5,   0,   0,   0,   52,  0,   0,   0,   72,  1,
+    0,   0,   124, 1,   0,   0,   72,  2,   0,   0,   96,  3,   0,   0,   82,  68,  69,  70,  12,
+    1,   0,   0,   1,   0,   0,   0,   84,  0,   0,   0,   1,   0,   0,   0,   28,  0,   0,   0,
+    0,   4,   255, 255, 0,   1,   0,   0,   216, 0,   0,   0,   60,  0,   0,   0,   0,   0,   0,
+    0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   1,   0,
+    0,   0,   1,   0,   0,   0,   67,  111, 108, 111, 114, 65,  110, 100, 68,  101, 112, 116, 104,
+    68,  97,  116, 97,  83,  105, 110, 116, 0,   171, 171, 60,  0,   0,   0,   2,   0,   0,   0,
+    108, 0,   0,   0,   32,  0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   156, 0,   0,
+    0,   0,   0,   0,   0,   16,  0,   0,   0,   2,   0,   0,   0,   168, 0,   0,   0,   0,   0,
+    0,   0,   184, 0,   0,   0,   16,  0,   0,   0,   4,   0,   0,   0,   2,   0,   0,   0,   200,
+    0,   0,   0,   0,   0,   0,   0,   99,  111, 108, 111, 114, 95,  83,  105, 110, 116, 0,   171,
+    1,   0,   2,   0,   1,   0,   4,   0,   0,   0,   0,   0,   0,   0,   0,   0,   122, 86,  97,
+    108, 117, 101, 70,  95,  83,  105, 110, 116, 0,   171, 171, 171, 0,   0,   3,   0,   1,   0,
+    1,   0,   0,   0,   0,   0,   0,   0,   0,   0,   77,  105, 99,  114, 111, 115, 111, 102, 116,
+    32,  40,  82,  41,  32,  72,  76,  83,  76,  32,  83,  104, 97,  100, 101, 114, 32,  67,  111,
+    109, 112, 105, 108, 101, 114, 32,  54,  46,  51,  46,  57,  54,  48,  48,  46,  49,  54,  51,
+    56,  52,  0,   171, 171, 73,  83,  71,  78,  44,  0,   0,   0,   1,   0,   0,   0,   8,   0,
+    0,   0,   32,  0,   0,   0,   0,   0,   0,   0,   1,   0,   0,   0,   3,   0,   0,   0,   0,
+    0,   0,   0,   15,  0,   0,   0,   83,  86,  95,  80,  79,  83,  73,  84,  73,  79,  78,  0,
+    79,  83,  71,  78,  196, 0,   0,   0,   7,   0,   0,   0,   8,   0,   0,   0,   176, 0,   0,
+    0,   0,   0,   0,   0,   0,   0,   0,   0,   2,   0,   0,   0,   0,   0,   0,   0,   15,  0,
+    0,   0,   176, 0,   0,   0,   1,   0,   0,   0,   0,   0,   0,   0,   2,   0,   0,   0,   1,
+    0,   0,   0,   15,  0,   0,   0,   176, 0,   0,   0,   2,   0,   0,   0,   0,   0,   0,   0,
+    2,   0,   0,   0,   2,   0,   0,   0,   15,  0,   0,   0,   176, 0,   0,   0,   3,   0,   0,
+    0,   0,   0,   0,   0,   2,   0,   0,   0,   3,   0,   0,   0,   15,  0,   0,   0,   176, 0,
+    0,   0,   4,   0,   0,   0,   0,   0,   0,   0,   2,   0,   0,   0,   4,   0,   0,   0,   15,
+    0,   0,   0,   176, 0,   0,   0,   5,   0,   0,   0,   0,   0,   0,   0,   2,   0,   0,   0,
+    5,   0,   0,   0,   15,  0,   0,   0,   186, 0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+    0,   3,   0,   0,   0,   255, 255, 255, 255, 1,   14,  0,   0,   83,  86,  95,  84,  65,  82,
+    71,  69,  84,  0,   83,  86,  95,  68,  69,  80,  84,  72,  0,   171, 83,  72,  68,  82,  16,
+    1,   0,   0,   64,  0,   0,   0,   68,  0,   0,   0,   89,  0,   0,   4,   70,  142, 32,  0,
+    0,   0,   0,   0,   2,   0,   0,   0,   101, 0,   0,   3,   242, 32,  16,  0,   0,   0,   0,
+    0,   101, 0,   0,   3,   242, 32,  16,  0,   1,   0,   0,   0,   101, 0,   0,   3,   242, 32,
+    16,  0,   2,   0,   0,   0,   101, 0,   0,   3,   242, 32,  16,  0,   3,   0,   0,   0,   101,
+    0,   0,   3,   242, 32,  16,  0,   4,   0,   0,   0,   101, 0,   0,   3,   242, 32,  16,  0,
+    5,   0,   0,   0,   101, 0,   0,   2,   1,   192, 0,   0,   54,  0,   0,   6,   242, 32,  16,
+    0,   0,   0,   0,   0,   70,  142, 32,  0,   0,   0,   0,   0,   0,   0,   0,   0,   54,  0,
+    0,   6,   242, 32,  16,  0,   1,   0,   0,   0,   70,  142, 32,  0,   0,   0,   0,   0,   0,
+    0,   0,   0,   54,  0,   0,   6,   242, 32,  16,  0,   2,   0,   0,   0,   70,  142, 32,  0,
+    0,   0,   0,   0,   0,   0,   0,   0,   54,  0,   0,   6,   242, 32,  16,  0,   3,   0,   0,
+    0,   70,  142, 32,  0,   0,   0,   0,   0,   0,   0,   0,   0,   54,  0,   0,   6,   242, 32,
+    16,  0,   4,   0,   0,   0,   70,  142, 32,  0,   0,   0,   0,   0,   0,   0,   0,   0,   54,
+    0,   0,   6,   242, 32,  16,  0,   5,   0,   0,   0,   70,  142, 32,  0,   0,   0,   0,   0,
+    0,   0,   0,   0,   54,  0,   0,   5,   1,   192, 0,   0,   10,  128, 32,  0,   0,   0,   0,
+    0,   1,   0,   0,   0,   62,  0,   0,   1,   83,  84,  65,  84,  116, 0,   0,   0,   8,   0,
+    0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   7,   0,   0,   0,   0,   0,   0,   0,   0,
+    0,   0,   0,   0,   0,   0,   0,   1,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+    0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+    0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   7,   0,
+    0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+    0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0};
--- a/gfx/angle/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/clearsint11ps7.h
+++ b/gfx/angle/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/clearsint11ps7.h
@@ -1,123 +1,123 @@
-#if 0
-//
-// Generated by Microsoft (R) HLSL Shader Compiler 6.3.9600.16384
-//
-//
-// Buffer Definitions: 
-//
-// cbuffer ColorAndDepthDataSint
-// {
-//
-//   int4 color_Sint;                   // Offset:    0 Size:    16
-//   float zValueF_Sint;                // Offset:   16 Size:     4
-//
-// }
-//
-//
-// Resource Bindings:
-//
-// Name                                 Type  Format         Dim Slot Elements
-// ------------------------------ ---------- ------- ----------- ---- --------
-// ColorAndDepthDataSint             cbuffer      NA          NA    0        1
-//
-//
-//
-// Input signature:
-//
-// Name                 Index   Mask Register SysValue  Format   Used
-// -------------------- ----- ------ -------- -------- ------- ------
-// SV_POSITION              0   xyzw        0      POS   float       
-//
-//
-// Output signature:
-//
-// Name                 Index   Mask Register SysValue  Format   Used
-// -------------------- ----- ------ -------- -------- ------- ------
-// SV_TARGET                0   xyzw        0   TARGET     int   xyzw
-// SV_TARGET                1   xyzw        1   TARGET     int   xyzw
-// SV_TARGET                2   xyzw        2   TARGET     int   xyzw
-// SV_TARGET                3   xyzw        3   TARGET     int   xyzw
-// SV_TARGET                4   xyzw        4   TARGET     int   xyzw
-// SV_TARGET                5   xyzw        5   TARGET     int   xyzw
-// SV_TARGET                6   xyzw        6   TARGET     int   xyzw
-// SV_DEPTH                 0    N/A   oDepth    DEPTH   float    YES
-//
-ps_4_0
-dcl_constantbuffer cb0[2], immediateIndexed
-dcl_output o0.xyzw
-dcl_output o1.xyzw
-dcl_output o2.xyzw
-dcl_output o3.xyzw
-dcl_output o4.xyzw
-dcl_output o5.xyzw
-dcl_output o6.xyzw
-dcl_output oDepth
-mov o0.xyzw, cb0[0].xyzw
-mov o1.xyzw, cb0[0].xyzw
-mov o2.xyzw, cb0[0].xyzw
-mov o3.xyzw, cb0[0].xyzw
-mov o4.xyzw, cb0[0].xyzw
-mov o5.xyzw, cb0[0].xyzw
-mov o6.xyzw, cb0[0].xyzw
-mov oDepth, cb0[1].x
-ret 
-// Approximately 9 instruction slots used
-#endif
-
-const BYTE g_PS_ClearSint7[] = {
-    68,  88,  66,  67,  7,   138, 112, 174, 240, 99,  49,  26,  154, 27,  225, 30,  199, 218, 197,
-    44,  1,   0,   0,   0,   24,  4,   0,   0,   5,   0,   0,   0,   52,  0,   0,   0,   72,  1,
-    0,   0,   124, 1,   0,   0,   96,  2,   0,   0,   156, 3,   0,   0,   82,  68,  69,  70,  12,
-    1,   0,   0,   1,   0,   0,   0,   84,  0,   0,   0,   1,   0,   0,   0,   28,  0,   0,   0,
-    0,   4,   255, 255, 0,   1,   0,   0,   216, 0,   0,   0,   60,  0,   0,   0,   0,   0,   0,
-    0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   1,   0,
-    0,   0,   1,   0,   0,   0,   67,  111, 108, 111, 114, 65,  110, 100, 68,  101, 112, 116, 104,
-    68,  97,  116, 97,  83,  105, 110, 116, 0,   171, 171, 60,  0,   0,   0,   2,   0,   0,   0,
-    108, 0,   0,   0,   32,  0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   156, 0,   0,
-    0,   0,   0,   0,   0,   16,  0,   0,   0,   2,   0,   0,   0,   168, 0,   0,   0,   0,   0,
-    0,   0,   184, 0,   0,   0,   16,  0,   0,   0,   4,   0,   0,   0,   2,   0,   0,   0,   200,
-    0,   0,   0,   0,   0,   0,   0,   99,  111, 108, 111, 114, 95,  83,  105, 110, 116, 0,   171,
-    1,   0,   2,   0,   1,   0,   4,   0,   0,   0,   0,   0,   0,   0,   0,   0,   122, 86,  97,
-    108, 117, 101, 70,  95,  83,  105, 110, 116, 0,   171, 171, 171, 0,   0,   3,   0,   1,   0,
-    1,   0,   0,   0,   0,   0,   0,   0,   0,   0,   77,  105, 99,  114, 111, 115, 111, 102, 116,
-    32,  40,  82,  41,  32,  72,  76,  83,  76,  32,  83,  104, 97,  100, 101, 114, 32,  67,  111,
-    109, 112, 105, 108, 101, 114, 32,  54,  46,  51,  46,  57,  54,  48,  48,  46,  49,  54,  51,
-    56,  52,  0,   171, 171, 73,  83,  71,  78,  44,  0,   0,   0,   1,   0,   0,   0,   8,   0,
-    0,   0,   32,  0,   0,   0,   0,   0,   0,   0,   1,   0,   0,   0,   3,   0,   0,   0,   0,
-    0,   0,   0,   15,  0,   0,   0,   83,  86,  95,  80,  79,  83,  73,  84,  73,  79,  78,  0,
-    79,  83,  71,  78,  220, 0,   0,   0,   8,   0,   0,   0,   8,   0,   0,   0,   200, 0,   0,
-    0,   0,   0,   0,   0,   0,   0,   0,   0,   2,   0,   0,   0,   0,   0,   0,   0,   15,  0,
-    0,   0,   200, 0,   0,   0,   1,   0,   0,   0,   0,   0,   0,   0,   2,   0,   0,   0,   1,
-    0,   0,   0,   15,  0,   0,   0,   200, 0,   0,   0,   2,   0,   0,   0,   0,   0,   0,   0,
-    2,   0,   0,   0,   2,   0,   0,   0,   15,  0,   0,   0,   200, 0,   0,   0,   3,   0,   0,
-    0,   0,   0,   0,   0,   2,   0,   0,   0,   3,   0,   0,   0,   15,  0,   0,   0,   200, 0,
-    0,   0,   4,   0,   0,   0,   0,   0,   0,   0,   2,   0,   0,   0,   4,   0,   0,   0,   15,
-    0,   0,   0,   200, 0,   0,   0,   5,   0,   0,   0,   0,   0,   0,   0,   2,   0,   0,   0,
-    5,   0,   0,   0,   15,  0,   0,   0,   200, 0,   0,   0,   6,   0,   0,   0,   0,   0,   0,
-    0,   2,   0,   0,   0,   6,   0,   0,   0,   15,  0,   0,   0,   210, 0,   0,   0,   0,   0,
-    0,   0,   0,   0,   0,   0,   3,   0,   0,   0,   255, 255, 255, 255, 1,   14,  0,   0,   83,
-    86,  95,  84,  65,  82,  71,  69,  84,  0,   83,  86,  95,  68,  69,  80,  84,  72,  0,   171,
-    83,  72,  68,  82,  52,  1,   0,   0,   64,  0,   0,   0,   77,  0,   0,   0,   89,  0,   0,
-    4,   70,  142, 32,  0,   0,   0,   0,   0,   2,   0,   0,   0,   101, 0,   0,   3,   242, 32,
-    16,  0,   0,   0,   0,   0,   101, 0,   0,   3,   242, 32,  16,  0,   1,   0,   0,   0,   101,
-    0,   0,   3,   242, 32,  16,  0,   2,   0,   0,   0,   101, 0,   0,   3,   242, 32,  16,  0,
-    3,   0,   0,   0,   101, 0,   0,   3,   242, 32,  16,  0,   4,   0,   0,   0,   101, 0,   0,
-    3,   242, 32,  16,  0,   5,   0,   0,   0,   101, 0,   0,   3,   242, 32,  16,  0,   6,   0,
-    0,   0,   101, 0,   0,   2,   1,   192, 0,   0,   54,  0,   0,   6,   242, 32,  16,  0,   0,
-    0,   0,   0,   70,  142, 32,  0,   0,   0,   0,   0,   0,   0,   0,   0,   54,  0,   0,   6,
-    242, 32,  16,  0,   1,   0,   0,   0,   70,  142, 32,  0,   0,   0,   0,   0,   0,   0,   0,
-    0,   54,  0,   0,   6,   242, 32,  16,  0,   2,   0,   0,   0,   70,  142, 32,  0,   0,   0,
-    0,   0,   0,   0,   0,   0,   54,  0,   0,   6,   242, 32,  16,  0,   3,   0,   0,   0,   70,
-    142, 32,  0,   0,   0,   0,   0,   0,   0,   0,   0,   54,  0,   0,   6,   242, 32,  16,  0,
-    4,   0,   0,   0,   70,  142, 32,  0,   0,   0,   0,   0,   0,   0,   0,   0,   54,  0,   0,
-    6,   242, 32,  16,  0,   5,   0,   0,   0,   70,  142, 32,  0,   0,   0,   0,   0,   0,   0,
-    0,   0,   54,  0,   0,   6,   242, 32,  16,  0,   6,   0,   0,   0,   70,  142, 32,  0,   0,
-    0,   0,   0,   0,   0,   0,   0,   54,  0,   0,   5,   1,   192, 0,   0,   10,  128, 32,  0,
-    0,   0,   0,   0,   1,   0,   0,   0,   62,  0,   0,   1,   83,  84,  65,  84,  116, 0,   0,
-    0,   9,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   8,   0,   0,   0,   0,   0,
-    0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   1,   0,   0,   0,   0,   0,   0,   0,   0,
-    0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
-    0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
-    0,   8,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
-    0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
-    0,   0,   0};
+#if 0
+//
+// Generated by Microsoft (R) HLSL Shader Compiler 6.3.9600.16384
+//
+//
+// Buffer Definitions: 
+//
+// cbuffer ColorAndDepthDataSint
+// {
+//
+//   int4 color_Sint;                   // Offset:    0 Size:    16
+//   float zValueF_Sint;                // Offset:   16 Size:     4
+//
+// }
+//
+//
+// Resource Bindings:
+//
+// Name                                 Type  Format         Dim Slot Elements
+// ------------------------------ ---------- ------- ----------- ---- --------
+// ColorAndDepthDataSint             cbuffer      NA          NA    0        1
+//
+//
+//
+// Input signature:
+//
+// Name                 Index   Mask Register SysValue  Format   Used
+// -------------------- ----- ------ -------- -------- ------- ------
+// SV_POSITION              0   xyzw        0      POS   float       
+//
+//
+// Output signature:
+//
+// Name                 Index   Mask Register SysValue  Format   Used
+// -------------------- ----- ------ -------- -------- ------- ------
+// SV_TARGET                0   xyzw        0   TARGET     int   xyzw
+// SV_TARGET                1   xyzw        1   TARGET     int   xyzw
+// SV_TARGET                2   xyzw        2   TARGET     int   xyzw
+// SV_TARGET                3   xyzw        3   TARGET     int   xyzw
+// SV_TARGET                4   xyzw        4   TARGET     int   xyzw
+// SV_TARGET                5   xyzw        5   TARGET     int   xyzw
+// SV_TARGET                6   xyzw        6   TARGET     int   xyzw
+// SV_DEPTH                 0    N/A   oDepth    DEPTH   float    YES
+//
+ps_4_0
+dcl_constantbuffer cb0[2], immediateIndexed
+dcl_output o0.xyzw
+dcl_output o1.xyzw
+dcl_output o2.xyzw
+dcl_output o3.xyzw
+dcl_output o4.xyzw
+dcl_output o5.xyzw
+dcl_output o6.xyzw
+dcl_output oDepth
+mov o0.xyzw, cb0[0].xyzw
+mov o1.xyzw, cb0[0].xyzw
+mov o2.xyzw, cb0[0].xyzw
+mov o3.xyzw, cb0[0].xyzw
+mov o4.xyzw, cb0[0].xyzw
+mov o5.xyzw, cb0[0].xyzw
+mov o6.xyzw, cb0[0].xyzw
+mov oDepth, cb0[1].x
+ret 
+// Approximately 9 instruction slots used
+#endif
+
+const BYTE g_PS_ClearSint7[] = {
+    68,  88,  66,  67,  7,   138, 112, 174, 240, 99,  49,  26,  154, 27,  225, 30,  199, 218, 197,
+    44,  1,   0,   0,   0,   24,  4,   0,   0,   5,   0,   0,   0,   52,  0,   0,   0,   72,  1,
+    0,   0,   124, 1,   0,   0,   96,  2,   0,   0,   156, 3,   0,   0,   82,  68,  69,  70,  12,
+    1,   0,   0,   1,   0,   0,   0,   84,  0,   0,   0,   1,   0,   0,   0,   28,  0,   0,   0,
+    0,   4,   255, 255, 0,   1,   0,   0,   216, 0,   0,   0,   60,  0,   0,   0,   0,   0,   0,
+    0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   1,   0,
+    0,   0,   1,   0,   0,   0,   67,  111, 108, 111, 114, 65,  110, 100, 68,  101, 112, 116, 104,
+    68,  97,  116, 97,  83,  105, 110, 116, 0,   171, 171, 60,  0,   0,   0,   2,   0,   0,   0,
+    108, 0,   0,   0,   32,  0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   156, 0,   0,
+    0,   0,   0,   0,   0,   16,  0,   0,   0,   2,   0,   0,   0,   168, 0,   0,   0,   0,   0,
+    0,   0,   184, 0,   0,   0,   16,  0,   0,   0,   4,   0,   0,   0,   2,   0,   0,   0,   200,
+    0,   0,   0,   0,   0,   0,   0,   99,  111, 108, 111, 114, 95,  83,  105, 110, 116, 0,   171,
+    1,   0,   2,   0,   1,   0,   4,   0,   0,   0,   0,   0,   0,   0,   0,   0,   122, 86,  97,
+    108, 117, 101, 70,  95,  83,  105, 110, 116, 0,   171, 171, 171, 0,   0,   3,   0,   1,   0,
+    1,   0,   0,   0,   0,   0,   0,   0,   0,   0,   77,  105, 99,  114, 111, 115, 111, 102, 116,
+    32,  40,  82,  41,  32,  72,  76,  83,  76,  32,  83,  104, 97,  100, 101, 114, 32,  67,  111,
+    109, 112, 105, 108, 101, 114, 32,  54,  46,  51,  46,  57,  54,  48,  48,  46,  49,  54,  51,
+    56,  52,  0,   171, 171, 73,  83,  71,  78,  44,  0,   0,   0,   1,   0,   0,   0,   8,   0,
+    0,   0,   32,  0,   0,   0,   0,   0,   0,   0,   1,   0,   0,   0,   3,   0,   0,   0,   0,
+    0,   0,   0,   15,  0,   0,   0,   83,  86,  95,  80,  79,  83,  73,  84,  73,  79,  78,  0,
+    79,  83,  71,  78,  220, 0,   0,   0,   8,   0,   0,   0,   8,   0,   0,   0,   200, 0,   0,
+    0,   0,   0,   0,   0,   0,   0,   0,   0,   2,   0,   0,   0,   0,   0,   0,   0,   15,  0,
+    0,   0,   200, 0,   0,   0,   1,   0,   0,   0,   0,   0,   0,   0,   2,   0,   0,   0,   1,
+    0,   0,   0,   15,  0,   0,   0,   200, 0,   0,   0,   2,   0,   0,   0,   0,   0,   0,   0,
+    2,   0,   0,   0,   2,   0,   0,   0,   15,  0,   0,   0,   200, 0,   0,   0,   3,   0,   0,
+    0,   0,   0,   0,   0,   2,   0,   0,   0,   3,   0,   0,   0,   15,  0,   0,   0,   200, 0,
+    0,   0,   4,   0,   0,   0,   0,   0,   0,   0,   2,   0,   0,   0,   4,   0,   0,   0,   15,
+    0,   0,   0,   200, 0,   0,   0,   5,   0,   0,   0,   0,   0,   0,   0,   2,   0,   0,   0,
+    5,   0,   0,   0,   15,  0,   0,   0,   200, 0,   0,   0,   6,   0,   0,   0,   0,   0,   0,
+    0,   2,   0,   0,   0,   6,   0,   0,   0,   15,  0,   0,   0,   210, 0,   0,   0,   0,   0,
+    0,   0,   0,   0,   0,   0,   3,   0,   0,   0,   255, 255, 255, 255, 1,   14,  0,   0,   83,
+    86,  95,  84,  65,  82,  71,  69,  84,  0,   83,  86,  95,  68,  69,  80,  84,  72,  0,   171,
+    83,  72,  68,  82,  52,  1,   0,   0,   64,  0,   0,   0,   77,  0,   0,   0,   89,  0,   0,
+    4,   70,  142, 32,  0,   0,   0,   0,   0,   2,   0,   0,   0,   101, 0,   0,   3,   242, 32,
+    16,  0,   0,   0,   0,   0,   101, 0,   0,   3,   242, 32,  16,  0,   1,   0,   0,   0,   101,
+    0,   0,   3,   242, 32,  16,  0,   2,   0,   0,   0,   101, 0,   0,   3,   242, 32,  16,  0,
+    3,   0,   0,   0,   101, 0,   0,   3,   242, 32,  16,  0,   4,   0,   0,   0,   101, 0,   0,
+    3,   242, 32,  16,  0,   5,   0,   0,   0,   101, 0,   0,   3,   242, 32,  16,  0,   6,   0,
+    0,   0,   101, 0,   0,   2,   1,   192, 0,   0,   54,  0,   0,   6,   242, 32,  16,  0,   0,
+    0,   0,   0,   70,  142, 32,  0,   0,   0,   0,   0,   0,   0,   0,   0,   54,  0,   0,   6,
+    242, 32,  16,  0,   1,   0,   0,   0,   70,  142, 32,  0,   0,   0,   0,   0,   0,   0,   0,
+    0,   54,  0,   0,   6,   242, 32,  16,  0,   2,   0,   0,   0,   70,  142, 32,  0,   0,   0,
+    0,   0,   0,   0,   0,   0,   54,  0,   0,   6,   242, 32,  16,  0,   3,   0,   0,   0,   70,
+    142, 32,  0,   0,   0,   0,   0,   0,   0,   0,   0,   54,  0,   0,   6,   242, 32,  16,  0,
+    4,   0,   0,   0,   70,  142, 32,  0,   0,   0,   0,   0,   0,   0,   0,   0,   54,  0,   0,
+    6,   242, 32,  16,  0,   5,   0,   0,   0,   70,  142, 32,  0,   0,   0,   0,   0,   0,   0,
+    0,   0,   54,  0,   0,   6,   242, 32,  16,  0,   6,   0,   0,   0,   70,  142, 32,  0,   0,
+    0,   0,   0,   0,   0,   0,   0,   54,  0,   0,   5,   1,   192, 0,   0,   10,  128, 32,  0,
+    0,   0,   0,   0,   1,   0,   0,   0,   62,  0,   0,   1,   83,  84,  65,  84,  116, 0,   0,
+    0,   9,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   8,   0,   0,   0,   0,   0,
+    0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   1,   0,   0,   0,   0,   0,   0,   0,   0,
+    0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+    0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+    0,   8,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+    0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+    0,   0,   0};
--- a/gfx/angle/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/clearsint11ps8.h
+++ b/gfx/angle/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/clearsint11ps8.h
@@ -1,129 +1,129 @@
-#if 0
-//
-// Generated by Microsoft (R) HLSL Shader Compiler 6.3.9600.16384
-//
-//
-// Buffer Definitions: 
-//
-// cbuffer ColorAndDepthDataSint
-// {
-//
-//   int4 color_Sint;                   // Offset:    0 Size:    16
-//   float zValueF_Sint;                // Offset:   16 Size:     4
-//
-// }
-//
-//
-// Resource Bindings:
-//
-// Name                                 Type  Format         Dim Slot Elements
-// ------------------------------ ---------- ------- ----------- ---- --------
-// ColorAndDepthDataSint             cbuffer      NA          NA    0        1
-//
-//
-//
-// Input signature:
-//
-// Name                 Index   Mask Register SysValue  Format   Used
-// -------------------- ----- ------ -------- -------- ------- ------
-// SV_POSITION              0   xyzw        0      POS   float       
-//
-//
-// Output signature:
-//
-// Name                 Index   Mask Register SysValue  Format   Used
-// -------------------- ----- ------ -------- -------- ------- ------
-// SV_TARGET                0   xyzw        0   TARGET     int   xyzw
-// SV_TARGET                1   xyzw        1   TARGET     int   xyzw
-// SV_TARGET                2   xyzw        2   TARGET     int   xyzw
-// SV_TARGET                3   xyzw        3   TARGET     int   xyzw
-// SV_TARGET                4   xyzw        4   TARGET     int   xyzw
-// SV_TARGET                5   xyzw        5   TARGET     int   xyzw
-// SV_TARGET                6   xyzw        6   TARGET     int   xyzw
-// SV_TARGET                7   xyzw        7   TARGET     int   xyzw
-// SV_DEPTH                 0    N/A   oDepth    DEPTH   float    YES
-//
-ps_4_0
-dcl_constantbuffer cb0[2], immediateIndexed
-dcl_output o0.xyzw
-dcl_output o1.xyzw
-dcl_output o2.xyzw
-dcl_output o3.xyzw
-dcl_output o4.xyzw
-dcl_output o5.xyzw
-dcl_output o6.xyzw
-dcl_output o7.xyzw
-dcl_output oDepth
-mov o0.xyzw, cb0[0].xyzw
-mov o1.xyzw, cb0[0].xyzw
-mov o2.xyzw, cb0[0].xyzw
-mov o3.xyzw, cb0[0].xyzw
-mov o4.xyzw, cb0[0].xyzw
-mov o5.xyzw, cb0[0].xyzw
-mov o6.xyzw, cb0[0].xyzw
-mov o7.xyzw, cb0[0].xyzw
-mov oDepth, cb0[1].x
-ret 
-// Approximately 10 instruction slots used
-#endif
-
-const BYTE g_PS_ClearSint8[] = {
-    68,  88,  66,  67,  40,  80,  87,  20,  166, 137, 87,  18,  79,  10,  71,  118, 4,   27,  31,
-    113, 1,   0,   0,   0,   84,  4,   0,   0,   5,   0,   0,   0,   52,  0,   0,   0,   72,  1,
-    0,   0,   124, 1,   0,   0,   120, 2,   0,   0,   216, 3,   0,   0,   82,  68,  69,  70,  12,
-    1,   0,   0,   1,   0,   0,   0,   84,  0,   0,   0,   1,   0,   0,   0,   28,  0,   0,   0,
-    0,   4,   255, 255, 0,   1,   0,   0,   216, 0,   0,   0,   60,  0,   0,   0,   0,   0,   0,
-    0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   1,   0,
-    0,   0,   1,   0,   0,   0,   67,  111, 108, 111, 114, 65,  110, 100, 68,  101, 112, 116, 104,
-    68,  97,  116, 97,  83,  105, 110, 116, 0,   171, 171, 60,  0,   0,   0,   2,   0,   0,   0,
-    108, 0,   0,   0,   32,  0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   156, 0,   0,
-    0,   0,   0,   0,   0,   16,  0,   0,   0,   2,   0,   0,   0,   168, 0,   0,   0,   0,   0,
-    0,   0,   184, 0,   0,   0,   16,  0,   0,   0,   4,   0,   0,   0,   2,   0,   0,   0,   200,
-    0,   0,   0,   0,   0,   0,   0,   99,  111, 108, 111, 114, 95,  83,  105, 110, 116, 0,   171,
-    1,   0,   2,   0,   1,   0,   4,   0,   0,   0,   0,   0,   0,   0,   0,   0,   122, 86,  97,
-    108, 117, 101, 70,  95,  83,  105, 110, 116, 0,   171, 171, 171, 0,   0,   3,   0,   1,   0,
-    1,   0,   0,   0,   0,   0,   0,   0,   0,   0,   77,  105, 99,  114, 111, 115, 111, 102, 116,
-    32,  40,  82,  41,  32,  72,  76,  83,  76,  32,  83,  104, 97,  100, 101, 114, 32,  67,  111,
-    109, 112, 105, 108, 101, 114, 32,  54,  46,  51,  46,  57,  54,  48,  48,  46,  49,  54,  51,
-    56,  52,  0,   171, 171, 73,  83,  71,  78,  44,  0,   0,   0,   1,   0,   0,   0,   8,   0,
-    0,   0,   32,  0,   0,   0,   0,   0,   0,   0,   1,   0,   0,   0,   3,   0,   0,   0,   0,
-    0,   0,   0,   15,  0,   0,   0,   83,  86,  95,  80,  79,  83,  73,  84,  73,  79,  78,  0,
-    79,  83,  71,  78,  244, 0,   0,   0,   9,   0,   0,   0,   8,   0,   0,   0,   224, 0,   0,
-    0,   0,   0,   0,   0,   0,   0,   0,   0,   2,   0,   0,   0,   0,   0,   0,   0,   15,  0,
-    0,   0,   224, 0,   0,   0,   1,   0,   0,   0,   0,   0,   0,   0,   2,   0,   0,   0,   1,
-    0,   0,   0,   15,  0,   0,   0,   224, 0,   0,   0,   2,   0,   0,   0,   0,   0,   0,   0,
-    2,   0,   0,   0,   2,   0,   0,   0,   15,  0,   0,   0,   224, 0,   0,   0,   3,   0,   0,
-    0,   0,   0,   0,   0,   2,   0,   0,   0,   3,   0,   0,   0,   15,  0,   0,   0,   224, 0,
-    0,   0,   4,   0,   0,   0,   0,   0,   0,   0,   2,   0,   0,   0,   4,   0,   0,   0,   15,
-    0,   0,   0,   224, 0,   0,   0,   5,   0,   0,   0,   0,   0,   0,   0,   2,   0,   0,   0,
-    5,   0,   0,   0,   15,  0,   0,   0,   224, 0,   0,   0,   6,   0,   0,   0,   0,   0,   0,
-    0,   2,   0,   0,   0,   6,   0,   0,   0,   15,  0,   0,   0,   224, 0,   0,   0,   7,   0,
-    0,   0,   0,   0,   0,   0,   2,   0,   0,   0,   7,   0,   0,   0,   15,  0,   0,   0,   234,
-    0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   3,   0,   0,   0,   255, 255, 255, 255,
-    1,   14,  0,   0,   83,  86,  95,  84,  65,  82,  71,  69,  84,  0,   83,  86,  95,  68,  69,
-    80,  84,  72,  0,   171, 83,  72,  68,  82,  88,  1,   0,   0,   64,  0,   0,   0,   86,  0,
-    0,   0,   89,  0,   0,   4,   70,  142, 32,  0,   0,   0,   0,   0,   2,   0,   0,   0,   101,
-    0,   0,   3,   242, 32,  16,  0,   0,   0,   0,   0,   101, 0,   0,   3,   242, 32,  16,  0,
-    1,   0,   0,   0,   101, 0,   0,   3,   242, 32,  16,  0,   2,   0,   0,   0,   101, 0,   0,
-    3,   242, 32,  16,  0,   3,   0,   0,   0,   101, 0,   0,   3,   242, 32,  16,  0,   4,   0,
-    0,   0,   101, 0,   0,   3,   242, 32,  16,  0,   5,   0,   0,   0,   101, 0,   0,   3,   242,
-    32,  16,  0,   6,   0,   0,   0,   101, 0,   0,   3,   242, 32,  16,  0,   7,   0,   0,   0,
-    101, 0,   0,   2,   1,   192, 0,   0,   54,  0,   0,   6,   242, 32,  16,  0,   0,   0,   0,
-    0,   70,  142, 32,  0,   0,   0,   0,   0,   0,   0,   0,   0,   54,  0,   0,   6,   242, 32,
-    16,  0,   1,   0,   0,   0,   70,  142, 32,  0,   0,   0,   0,   0,   0,   0,   0,   0,   54,
-    0,   0,   6,   242, 32,  16,  0,   2,   0,   0,   0,   70,  142, 32,  0,   0,   0,   0,   0,
-    0,   0,   0,   0,   54,  0,   0,   6,   242, 32,  16,  0,   3,   0,   0,   0,   70,  142, 32,
-    0,   0,   0,   0,   0,   0,   0,   0,   0,   54,  0,   0,   6,   242, 32,  16,  0,   4,   0,
-    0,   0,   70,  142, 32,  0,   0,   0,   0,   0,   0,   0,   0,   0,   54,  0,   0,   6,   242,
-    32,  16,  0,   5,   0,   0,   0,   70,  142, 32,  0,   0,   0,   0,   0,   0,   0,   0,   0,
-    54,  0,   0,   6,   242, 32,  16,  0,   6,   0,   0,   0,   70,  142, 32,  0,   0,   0,   0,
-    0,   0,   0,   0,   0,   54,  0,   0,   6,   242, 32,  16,  0,   7,   0,   0,   0,   70,  142,
-    32,  0,   0,   0,   0,   0,   0,   0,   0,   0,   54,  0,   0,   5,   1,   192, 0,   0,   10,
-    128, 32,  0,   0,   0,   0,   0,   1,   0,   0,   0,   62,  0,   0,   1,   83,  84,  65,  84,
-    116, 0,   0,   0,   10,  0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   9,   0,   0,
-    0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   1,   0,   0,   0,   0,   0,
-    0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
-    0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
-    0,   0,   0,   0,   9,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
-    0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
-    0,   0,   0,   0,   0,   0};
+#if 0
+//
+// Generated by Microsoft (R) HLSL Shader Compiler 6.3.9600.16384
+//
+//
+// Buffer Definitions: 
+//
+// cbuffer ColorAndDepthDataSint
+// {
+//
+//   int4 color_Sint;                   // Offset:    0 Size:    16
+//   float zValueF_Sint;                // Offset:   16 Size:     4
+//
+// }
+//
+//
+// Resource Bindings:
+//
+// Name                                 Type  Format         Dim Slot Elements
+// ------------------------------ ---------- ------- ----------- ---- --------
+// ColorAndDepthDataSint             cbuffer      NA          NA    0        1
+//
+//
+//
+// Input signature:
+//
+// Name                 Index   Mask Register SysValue  Format   Used
+// -------------------- ----- ------ -------- -------- ------- ------
+// SV_POSITION              0   xyzw        0      POS   float       
+//
+//
+// Output signature:
+//
+// Name                 Index   Mask Register SysValue  Format   Used
+// -------------------- ----- ------ -------- -------- ------- ------
+// SV_TARGET                0   xyzw        0   TARGET     int   xyzw
+// SV_TARGET                1   xyzw        1   TARGET     int   xyzw
+// SV_TARGET                2   xyzw        2   TARGET     int   xyzw
+// SV_TARGET                3   xyzw        3   TARGET     int   xyzw
+// SV_TARGET                4   xyzw        4   TARGET     int   xyzw
+// SV_TARGET                5   xyzw        5   TARGET     int   xyzw
+// SV_TARGET                6   xyzw        6   TARGET     int   xyzw
+// SV_TARGET                7   xyzw        7   TARGET     int   xyzw
+// SV_DEPTH                 0    N/A   oDepth    DEPTH   float    YES
+//
+ps_4_0
+dcl_constantbuffer cb0[2], immediateIndexed
+dcl_output o0.xyzw
+dcl_output o1.xyzw
+dcl_output o2.xyzw
+dcl_output o3.xyzw
+dcl_output o4.xyzw
+dcl_output o5.xyzw
+dcl_output o6.xyzw
+dcl_output o7.xyzw
+dcl_output oDepth
+mov o0.xyzw, cb0[0].xyzw
+mov o1.xyzw, cb0[0].xyzw
+mov o2.xyzw, cb0[0].xyzw
+mov o3.xyzw, cb0[0].xyzw
+mov o4.xyzw, cb0[0].xyzw
+mov o5.xyzw, cb0[0].xyzw
+mov o6.xyzw, cb0[0].xyzw
+mov o7.xyzw, cb0[0].xyzw
+mov oDepth, cb0[1].x
+ret 
+// Approximately 10 instruction slots used
+#endif
+
+const BYTE g_PS_ClearSint8[] = {
+    68,  88,  66,  67,  40,  80,  87,  20,  166, 137, 87,  18,  79,  10,  71,  118, 4,   27,  31,
+    113, 1,   0,   0,   0,   84,  4,   0,   0,   5,   0,   0,   0,   52,  0,   0,   0,   72,  1,
+    0,   0,   124, 1,   0,   0,   120, 2,   0,   0,   216, 3,   0,   0,   82,  68,  69,  70,  12,
+    1,   0,   0,   1,   0,   0,   0,   84,  0,   0,   0,   1,   0,   0,   0,   28,  0,   0,   0,
+    0,   4,   255, 255, 0,   1,   0,   0,   216, 0,   0,   0,   60,  0,   0,   0,   0,   0,   0,
+    0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   1,   0,
+    0,   0,   1,   0,   0,   0,   67,  111, 108, 111, 114, 65,  110, 100, 68,  101, 112, 116, 104,
+    68,  97,  116, 97,  83,  105, 110, 116, 0,   171, 171, 60,  0,   0,   0,   2,   0,   0,   0,
+    108, 0,   0,   0,   32,  0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   156, 0,   0,
+    0,   0,   0,   0,   0,   16,  0,   0,   0,   2,   0,   0,   0,   168, 0,   0,   0,   0,   0,
+    0,   0,   184, 0,   0,   0,   16,  0,   0,   0,   4,   0,   0,   0,   2,   0,   0,   0,   200,
+    0,   0,   0,   0,   0,   0,   0,   99,  111, 108, 111, 114, 95,  83,  105, 110, 116, 0,   171,
+    1,   0,   2,   0,   1,   0,   4,   0,   0,   0,   0,   0,   0,   0,   0,   0,   122, 86,  97,
+    108, 117, 101, 70,  95,  83,  105, 110, 116, 0,   171, 171, 171, 0,   0,   3,   0,   1,   0,
+    1,   0,   0,   0,   0,   0,   0,   0,   0,   0,   77,  105, 99,  114, 111, 115, 111, 102, 116,
+    32,  40,  82,  41,  32,  72,  76,  83,  76,  32,  83,  104, 97,  100, 101, 114, 32,  67,  111,
+    109, 112, 105, 108, 101, 114, 32,  54,  46,  51,  46,  57,  54,  48,  48,  46,  49,  54,  51,
+    56,  52,  0,   171, 171, 73,  83,  71,  78,  44,  0,   0,   0,   1,   0,   0,   0,   8,   0,
+    0,   0,   32,  0,   0,   0,   0,   0,   0,   0,   1,   0,   0,   0,   3,   0,   0,   0,   0,
+    0,   0,   0,   15,  0,   0,   0,   83,  86,  95,  80,  79,  83,  73,  84,  73,  79,  78,  0,
+    79,  83,  71,  78,  244, 0,   0,   0,   9,   0,   0,   0,   8,   0,   0,   0,   224, 0,   0,
+    0,   0,   0,   0,   0,   0,   0,   0,   0,   2,   0,   0,   0,   0,   0,   0,   0,   15,  0,
+    0,   0,   224, 0,   0,   0,   1,   0,   0,   0,   0,   0,   0,   0,   2,   0,   0,   0,   1,
+    0,   0,   0,   15,  0,   0,   0,   224, 0,   0,   0,   2,   0,   0,   0,   0,   0,   0,   0,
+    2,   0,   0,   0,   2,   0,   0,   0,   15,  0,   0,   0,   224, 0,   0,   0,   3,   0,   0,
+    0,   0,   0,   0,   0,   2,   0,   0,   0,   3,   0,   0,   0,   15,  0,   0,   0,   224, 0,
+    0,   0,   4,   0,   0,   0,   0,   0,   0,   0,   2,   0,   0,   0,   4,   0,   0,   0,   15,
+    0,   0,   0,   224, 0,   0,   0,   5,   0,   0,   0,   0,   0,   0,   0,   2,   0,   0,   0,
+    5,   0,   0,   0,   15,  0,   0,   0,   224, 0,   0,   0,   6,   0,   0,   0,   0,   0,   0,
+    0,   2,   0,   0,   0,   6,   0,   0,   0,   15,  0,   0,   0,   224, 0,   0,   0,   7,   0,
+    0,   0,   0,   0,   0,   0,   2,   0,   0,   0,   7,   0,   0,   0,   15,  0,   0,   0,   234,
+    0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   3,   0,   0,   0,   255, 255, 255, 255,
+    1,   14,  0,   0,   83,  86,  95,  84,  65,  82,  71,  69,  84,  0,   83,  86,  95,  68,  69,
+    80,  84,  72,  0,   171, 83,  72,  68,  82,  88,  1,   0,   0,   64,  0,   0,   0,   86,  0,
+    0,   0,   89,  0,   0,   4,   70,  142, 32,  0,   0,   0,   0,   0,   2,   0,   0,   0,   101,
+    0,   0,   3,   242, 32,  16,  0,   0,   0,   0,   0,   101, 0,   0,   3,   242, 32,  16,  0,
+    1,   0,   0,   0,   101, 0,   0,   3,   242, 32,  16,  0,   2,   0,   0,   0,   101, 0,   0,
+    3,   242, 32,  16,  0,   3,   0,   0,   0,   101, 0,   0,   3,   242, 32,  16,  0,   4,   0,
+    0,   0,   101, 0,   0,   3,   242, 32,  16,  0,   5,   0,   0,   0,   101, 0,   0,   3,   242,
+    32,  16,  0,   6,   0,   0,   0,   101, 0,   0,   3,   242, 32,  16,  0,   7,   0,   0,   0,
+    101, 0,   0,   2,   1,   192, 0,   0,   54,  0,   0,   6,   242, 32,  16,  0,   0,   0,   0,
+    0,   70,  142, 32,  0,   0,   0,   0,   0,   0,   0,   0,   0,   54,  0,   0,   6,   242, 32,
+    16,  0,   1,   0,   0,   0,   70,  142, 32,  0,   0,   0,   0,   0,   0,   0,   0,   0,   54,
+    0,   0,   6,   242, 32,  16,  0,   2,   0,   0,   0,   70,  142, 32,  0,   0,   0,   0,   0,
+    0,   0,   0,   0,   54,  0,   0,   6,   242, 32,  16,  0,   3,   0,   0,   0,   70,  142, 32,
+    0,   0,   0,   0,   0,   0,   0,   0,   0,   54,  0,   0,   6,   242, 32,  16,  0,   4,   0,
+    0,   0,   70,  142, 32,  0,   0,   0,   0,   0,   0,   0,   0,   0,   54,  0,   0,   6,   242,
+    32,  16,  0,   5,   0,   0,   0,   70,  142, 32,  0,   0,   0,   0,   0,   0,   0,   0,   0,
+    54,  0,   0,   6,   242, 32,  16,  0,   6,   0,   0,   0,   70,  142, 32,  0,   0,   0,   0,
+    0,   0,   0,   0,   0,   54,  0,   0,   6,   242, 32,  16,  0,   7,   0,   0,   0,   70,  142,
+    32,  0,   0,   0,   0,   0,   0,   0,   0,   0,   54,  0,   0,   5,   1,   192, 0,   0,   10,
+    128, 32,  0,   0,   0,   0,   0,   1,   0,   0,   0,   62,  0,   0,   1,   83,  84,  65,  84,
+    116, 0,   0,   0,   10,  0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   9,   0,   0,
+    0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   1,   0,   0,   0,   0,   0,
+    0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+    0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+    0,   0,   0,   0,   9,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+    0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+    0,   0,   0,   0,   0,   0};
--- a/gfx/angle/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/clearuint11ps1.h
+++ b/gfx/angle/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/clearuint11ps1.h
@@ -1,86 +1,86 @@
-#if 0
-//
-// Generated by Microsoft (R) HLSL Shader Compiler 6.3.9600.16384
-//
-//
-// Buffer Definitions: 
-//
-// cbuffer ColorAndDepthDataUint
-// {
-//
-//   uint4 color_Uint;                  // Offset:    0 Size:    16
-//   float zValueF_Uint;                // Offset:   16 Size:     4
-//
-// }
-//
-//
-// Resource Bindings:
-//
-// Name                                 Type  Format         Dim Slot Elements
-// ------------------------------ ---------- ------- ----------- ---- --------
-// ColorAndDepthDataUint             cbuffer      NA          NA    0        1
-//
-//
-//
-// Input signature:
-//
-// Name                 Index   Mask Register SysValue  Format   Used
-// -------------------- ----- ------ -------- -------- ------- ------
-// SV_POSITION              0   xyzw        0      POS   float       
-//
-//
-// Output signature:
-//
-// Name                 Index   Mask Register SysValue  Format   Used
-// -------------------- ----- ------ -------- -------- ------- ------
-// SV_TARGET                0   xyzw        0   TARGET    uint   xyzw
-// SV_DEPTH                 0    N/A   oDepth    DEPTH   float    YES
-//
-ps_4_0
-dcl_constantbuffer cb0[2], immediateIndexed
-dcl_output o0.xyzw
-dcl_output oDepth
-mov o0.xyzw, cb0[0].xyzw
-mov oDepth, cb0[1].x
-ret 
-// Approximately 3 instruction slots used
-#endif
-
-const BYTE g_PS_ClearUint1[] = {
-    68,  88,  66,  67,  165, 251, 33,  78,  86,  103, 162, 162, 213, 224, 91,  62,  153, 83,  9,
-    114, 1,   0,   0,   0,   176, 2,   0,   0,   5,   0,   0,   0,   52,  0,   0,   0,   72,  1,
-    0,   0,   124, 1,   0,   0,   208, 1,   0,   0,   52,  2,   0,   0,   82,  68,  69,  70,  12,
-    1,   0,   0,   1,   0,   0,   0,   84,  0,   0,   0,   1,   0,   0,   0,   28,  0,   0,   0,
-    0,   4,   255, 255, 0,   1,   0,   0,   216, 0,   0,   0,   60,  0,   0,   0,   0,   0,   0,
-    0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   1,   0,
-    0,   0,   1,   0,   0,   0,   67,  111, 108, 111, 114, 65,  110, 100, 68,  101, 112, 116, 104,
-    68,  97,  116, 97,  85,  105, 110, 116, 0,   171, 171, 60,  0,   0,   0,   2,   0,   0,   0,
-    108, 0,   0,   0,   32,  0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   156, 0,   0,
-    0,   0,   0,   0,   0,   16,  0,   0,   0,   2,   0,   0,   0,   168, 0,   0,   0,   0,   0,
-    0,   0,   184, 0,   0,   0,   16,  0,   0,   0,   4,   0,   0,   0,   2,   0,   0,   0,   200,
-    0,   0,   0,   0,   0,   0,   0,   99,  111, 108, 111, 114, 95,  85,  105, 110, 116, 0,   171,
-    1,   0,   19,  0,   1,   0,   4,   0,   0,   0,   0,   0,   0,   0,   0,   0,   122, 86,  97,
-    108, 117, 101, 70,  95,  85,  105, 110, 116, 0,   171, 171, 171, 0,   0,   3,   0,   1,   0,
-    1,   0,   0,   0,   0,   0,   0,   0,   0,   0,   77,  105, 99,  114, 111, 115, 111, 102, 116,
-    32,  40,  82,  41,  32,  72,  76,  83,  76,  32,  83,  104, 97,  100, 101, 114, 32,  67,  111,
-    109, 112, 105, 108, 101, 114, 32,  54,  46,  51,  46,  57,  54,  48,  48,  46,  49,  54,  51,
-    56,  52,  0,   171, 171, 73,  83,  71,  78,  44,  0,   0,   0,   1,   0,   0,   0,   8,   0,
-    0,   0,   32,  0,   0,   0,   0,   0,   0,   0,   1,   0,   0,   0,   3,   0,   0,   0,   0,
-    0,   0,   0,   15,  0,   0,   0,   83,  86,  95,  80,  79,  83,  73,  84,  73,  79,  78,  0,
-    79,  83,  71,  78,  76,  0,   0,   0,   2,   0,   0,   0,   8,   0,   0,   0,   56,  0,   0,
-    0,   0,   0,   0,   0,   0,   0,   0,   0,   1,   0,   0,   0,   0,   0,   0,   0,   15,  0,
-    0,   0,   66,  0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   3,   0,   0,   0,   255,
-    255, 255, 255, 1,   14,  0,   0,   83,  86,  95,  84,  65,  82,  71,  69,  84,  0,   83,  86,
-    95,  68,  69,  80,  84,  72,  0,   171, 83,  72,  68,  82,  92,  0,   0,   0,   64,  0,   0,
-    0,   23,  0,   0,   0,   89,  0,   0,   4,   70,  142, 32,  0,   0,   0,   0,   0,   2,   0,
-    0,   0,   101, 0,   0,   3,   242, 32,  16,  0,   0,   0,   0,   0,   101, 0,   0,   2,   1,
-    192, 0,   0,   54,  0,   0,   6,   242, 32,  16,  0,   0,   0,   0,   0,   70,  142, 32,  0,
-    0,   0,   0,   0,   0,   0,   0,   0,   54,  0,   0,   5,   1,   192, 0,   0,   10,  128, 32,
-    0,   0,   0,   0,   0,   1,   0,   0,   0,   62,  0,   0,   1,   83,  84,  65,  84,  116, 0,
-    0,   0,   3,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   2,   0,   0,   0,   0,
-    0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   1,   0,   0,   0,   0,   0,   0,   0,
-    0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
-    0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
-    0,   0,   2,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
-    0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
-    0,   0,   0,   0};
+#if 0
+//
+// Generated by Microsoft (R) HLSL Shader Compiler 6.3.9600.16384
+//
+//
+// Buffer Definitions: 
+//
+// cbuffer ColorAndDepthDataUint
+// {
+//
+//   uint4 color_Uint;                  // Offset:    0 Size:    16
+//   float zValueF_Uint;                // Offset:   16 Size:     4
+//
+// }
+//
+//
+// Resource Bindings:
+//
+// Name                                 Type  Format         Dim Slot Elements
+// ------------------------------ ---------- ------- ----------- ---- --------
+// ColorAndDepthDataUint             cbuffer      NA          NA    0        1
+//
+//
+//
+// Input signature:
+//
+// Name                 Index   Mask Register SysValue  Format   Used
+// -------------------- ----- ------ -------- -------- ------- ------
+// SV_POSITION              0   xyzw        0      POS   float       
+//
+//
+// Output signature:
+//
+// Name                 Index   Mask Register SysValue  Format   Used
+// -------------------- ----- ------ -------- -------- ------- ------
+// SV_TARGET                0   xyzw        0   TARGET    uint   xyzw
+// SV_DEPTH                 0    N/A   oDepth    DEPTH   float    YES
+//
+ps_4_0
+dcl_constantbuffer cb0[2], immediateIndexed
+dcl_output o0.xyzw
+dcl_output oDepth
+mov o0.xyzw, cb0[0].xyzw
+mov oDepth, cb0[1].x
+ret 
+// Approximately 3 instruction slots used
+#endif
+
+const BYTE g_PS_ClearUint1[] = {
+    68,  88,  66,  67,  165, 251, 33,  78,  86,  103, 162, 162, 213, 224, 91,  62,  153, 83,  9,
+    114, 1,   0,   0,   0,   176, 2,   0,   0,   5,   0,   0,   0,   52,  0,   0,   0,   72,  1,
+    0,   0,   124, 1,   0,   0,   208, 1,   0,   0,   52,  2,   0,   0,   82,  68,  69,  70,  12,
+    1,   0,   0,   1,   0,   0,   0,   84,  0,   0,   0,   1,   0,   0,   0,   28,  0,   0,   0,
+    0,   4,   255, 255, 0,   1,   0,   0,   216, 0,   0,   0,   60,  0,   0,   0,   0,   0,   0,
+    0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   1,   0,
+    0,   0,   1,   0,   0,   0,   67,  111, 108, 111, 114, 65,  110, 100, 68,  101, 112, 116, 104,
+    68,  97,  116, 97,  85,  105, 110, 116, 0,   171, 171, 60,  0,   0,   0,   2,   0,   0,   0,
+    108, 0,   0,   0,   32,  0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   156, 0,   0,
+    0,   0,   0,   0,   0,   16,  0,   0,   0,   2,   0,   0,   0,   168, 0,   0,   0,   0,   0,
+    0,   0,   184, 0,   0,   0,   16,  0,   0,   0,   4,   0,   0,   0,   2,   0,   0,   0,   200,
+    0,   0,   0,   0,   0,   0,   0,   99,  111, 108, 111, 114, 95,  85,  105, 110, 116, 0,   171,
+    1,   0,   19,  0,   1,   0,   4,   0,   0,   0,   0,   0,   0,   0,   0,   0,   122, 86,  97,
+    108, 117, 101, 70,  95,  85,  105, 110, 116, 0,   171, 171, 171, 0,   0,   3,   0,   1,   0,
+    1,   0,   0,   0,   0,   0,   0,   0,   0,   0,   77,  105, 99,  114, 111, 115, 111, 102, 116,
+    32,  40,  82,  41,  32,  72,  76,  83,  76,  32,  83,  104, 97,  100, 101, 114, 32,  67,  111,
+    109, 112, 105, 108, 101, 114, 32,  54,  46,  51,  46,  57,  54,  48,  48,  46,  49,  54,  51,
+    56,  52,  0,   171, 171, 73,  83,  71,  78,  44,  0,   0,   0,   1,   0,   0,   0,   8,   0,
+    0,   0,   32,  0,   0,   0,   0,   0,   0,   0,   1,   0,   0,   0,   3,   0,   0,   0,   0,
+    0,   0,   0,   15,  0,   0,   0,   83,  86,  95,  80,  79,  83,  73,  84,  73,  79,  78,  0,
+    79,  83,  71,  78,  76,  0,   0,   0,   2,   0,   0,   0,   8,   0,   0,   0,   56,  0,   0,
+    0,   0,   0,   0,   0,   0,   0,   0,   0,   1,   0,   0,   0,   0,   0,   0,   0,   15,  0,
+    0,   0,   66,  0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   3,   0,   0,   0,   255,
+    255, 255, 255, 1,   14,  0,   0,   83,  86,  95,  84,  65,  82,  71,  69,  84,  0,   83,  86,
+    95,  68,  69,  80,  84,  72,  0,   171, 83,  72,  68,  82,  92,  0,   0,   0,   64,  0,   0,
+    0,   23,  0,   0,   0,   89,  0,   0,   4,   70,  142, 32,  0,   0,   0,   0,   0,   2,   0,
+    0,   0,   101, 0,   0,   3,   242, 32,  16,  0,   0,   0,   0,   0,   101, 0,   0,   2,   1,
+    192, 0,   0,   54,  0,   0,   6,   242, 32,  16,  0,   0,   0,   0,   0,   70,  142, 32,  0,
+    0,   0,   0,   0,   0,   0,   0,   0,   54,  0,   0,   5,   1,   192, 0,   0,   10,  128, 32,
+    0,   0,   0,   0,   0,   1,   0,   0,   0,   62,  0,   0,   1,   83,  84,  65,  84,  116, 0,
+    0,   0,   3,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   2,   0,   0,   0,   0,
+    0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   1,   0,   0,   0,   0,   0,   0,   0,
+    0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+    0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+    0,   0,   2,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+    0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+    0,   0,   0,   0};
--- a/gfx/angle/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/clearuint11ps2.h
+++ b/gfx/angle/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/clearuint11ps2.h
@@ -1,92 +1,92 @@
-#if 0
-//
-// Generated by Microsoft (R) HLSL Shader Compiler 6.3.9600.16384
-//
-//
-// Buffer Definitions: 
-//
-// cbuffer ColorAndDepthDataUint
-// {
-//
-//   uint4 color_Uint;                  // Offset:    0 Size:    16
-//   float zValueF_Uint;                // Offset:   16 Size:     4
-//
-// }
-//
-//
-// Resource Bindings:
-//
-// Name                                 Type  Format         Dim Slot Elements
-// ------------------------------ ---------- ------- ----------- ---- --------
-// ColorAndDepthDataUint             cbuffer      NA          NA    0        1
-//
-//
-//
-// Input signature:
-//
-// Name                 Index   Mask Register SysValue  Format   Used
-// -------------------- ----- ------ -------- -------- ------- ------
-// SV_POSITION              0   xyzw        0      POS   float       
-//
-//
-// Output signature:
-//
-// Name                 Index   Mask Register SysValue  Format   Used
-// -------------------- ----- ------ -------- -------- ------- ------
-// SV_TARGET                0   xyzw        0   TARGET    uint   xyzw
-// SV_TARGET                1   xyzw        1   TARGET    uint   xyzw
-// SV_DEPTH                 0    N/A   oDepth    DEPTH   float    YES
-//
-ps_4_0
-dcl_constantbuffer cb0[2], immediateIndexed
-dcl_output o0.xyzw
-dcl_output o1.xyzw
-dcl_output oDepth
-mov o0.xyzw, cb0[0].xyzw
-mov o1.xyzw, cb0[0].xyzw
-mov oDepth, cb0[1].x
-ret 
-// Approximately 4 instruction slots used
-#endif
-
-const BYTE g_PS_ClearUint2[] = {
-    68,  88,  66,  67,  64,  241, 9,   8,   108, 162, 163, 180, 109, 195, 189, 181, 110, 171, 114,
-    118, 1,   0,   0,   0,   236, 2,   0,   0,   5,   0,   0,   0,   52,  0,   0,   0,   72,  1,
-    0,   0,   124, 1,   0,   0,   232, 1,   0,   0,   112, 2,   0,   0,   82,  68,  69,  70,  12,
-    1,   0,   0,   1,   0,   0,   0,   84,  0,   0,   0,   1,   0,   0,   0,   28,  0,   0,   0,
-    0,   4,   255, 255, 0,   1,   0,   0,   216, 0,   0,   0,   60,  0,   0,   0,   0,   0,   0,
-    0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   1,   0,
-    0,   0,   1,   0,   0,   0,   67,  111, 108, 111, 114, 65,  110, 100, 68,  101, 112, 116, 104,
-    68,  97,  116, 97,  85,  105, 110, 116, 0,   171, 171, 60,  0,   0,   0,   2,   0,   0,   0,
-    108, 0,   0,   0,   32,  0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   156, 0,   0,
-    0,   0,   0,   0,   0,   16,  0,   0,   0,   2,   0,   0,   0,   168, 0,   0,   0,   0,   0,
-    0,   0,   184, 0,   0,   0,   16,  0,   0,   0,   4,   0,   0,   0,   2,   0,   0,   0,   200,
-    0,   0,   0,   0,   0,   0,   0,   99,  111, 108, 111, 114, 95,  85,  105, 110, 116, 0,   171,
-    1,   0,   19,  0,   1,   0,   4,   0,   0,   0,   0,   0,   0,   0,   0,   0,   122, 86,  97,
-    108, 117, 101, 70,  95,  85,  105, 110, 116, 0,   171, 171, 171, 0,   0,   3,   0,   1,   0,
-    1,   0,   0,   0,   0,   0,   0,   0,   0,   0,   77,  105, 99,  114, 111, 115, 111, 102, 116,
-    32,  40,  82,  41,  32,  72,  76,  83,  76,  32,  83,  104, 97,  100, 101, 114, 32,  67,  111,
-    109, 112, 105, 108, 101, 114, 32,  54,  46,  51,  46,  57,  54,  48,  48,  46,  49,  54,  51,
-    56,  52,  0,   171, 171, 73,  83,  71,  78,  44,  0,   0,   0,   1,   0,   0,   0,   8,   0,
-    0,   0,   32,  0,   0,   0,   0,   0,   0,   0,   1,   0,   0,   0,   3,   0,   0,   0,   0,
-    0,   0,   0,   15,  0,   0,   0,   83,  86,  95,  80,  79,  83,  73,  84,  73,  79,  78,  0,
-    79,  83,  71,  78,  100, 0,   0,   0,   3,   0,   0,   0,   8,   0,   0,   0,   80,  0,   0,
-    0,   0,   0,   0,   0,   0,   0,   0,   0,   1,   0,   0,   0,   0,   0,   0,   0,   15,  0,
-    0,   0,   80,  0,   0,   0,   1,   0,   0,   0,   0,   0,   0,   0,   1,   0,   0,   0,   1,
-    0,   0,   0,   15,  0,   0,   0,   90,  0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
-    3,   0,   0,   0,   255, 255, 255, 255, 1,   14,  0,   0,   83,  86,  95,  84,  65,  82,  71,
-    69,  84,  0,   83,  86,  95,  68,  69,  80,  84,  72,  0,   171, 83,  72,  68,  82,  128, 0,
-    0,   0,   64,  0,   0,   0,   32,  0,   0,   0,   89,  0,   0,   4,   70,  142, 32,  0,   0,
-    0,   0,   0,   2,   0,   0,   0,   101, 0,   0,   3,   242, 32,  16,  0,   0,   0,   0,   0,
-    101, 0,   0,   3,   242, 32,  16,  0,   1,   0,   0,   0,   101, 0,   0,   2,   1,   192, 0,
-    0,   54,  0,   0,   6,   242, 32,  16,  0,   0,   0,   0,   0,   70,  142, 32,  0,   0,   0,
-    0,   0,   0,   0,   0,   0,   54,  0,   0,   6,   242, 32,  16,  0,   1,   0,   0,   0,   70,
-    142, 32,  0,   0,   0,   0,   0,   0,   0,   0,   0,   54,  0,   0,   5,   1,   192, 0,   0,
-    10,  128, 32,  0,   0,   0,   0,   0,   1,   0,   0,   0,   62,  0,   0,   1,   83,  84,  65,
-    84,  116, 0,   0,   0,   4,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   3,   0,
-    0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   1,   0,   0,   0,   0,
-    0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
-    0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
-    0,   0,   0,   0,   0,   3,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
-    0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
-    0,   0,   0,   0,   0,   0,   0};
+#if 0
+//
+// Generated by Microsoft (R) HLSL Shader Compiler 6.3.9600.16384
+//
+//
+// Buffer Definitions: 
+//
+// cbuffer ColorAndDepthDataUint
+// {
+//
+//   uint4 color_Uint;                  // Offset:    0 Size:    16
+//   float zValueF_Uint;                // Offset:   16 Size:     4
+//
+// }
+//
+//
+// Resource Bindings:
+//
+// Name                                 Type  Format         Dim Slot Elements
+// ------------------------------ ---------- ------- ----------- ---- --------
+// ColorAndDepthDataUint             cbuffer      NA          NA    0        1
+//
+//
+//
+// Input signature:
+//
+// Name                 Index   Mask Register SysValue  Format   Used
+// -------------------- ----- ------ -------- -------- ------- ------
+// SV_POSITION              0   xyzw        0      POS   float       
+//
+//
+// Output signature:
+//
+// Name                 Index   Mask Register SysValue  Format   Used
+// -------------------- ----- ------ -------- -------- ------- ------
+// SV_TARGET                0   xyzw        0   TARGET    uint   xyzw
+// SV_TARGET                1   xyzw        1   TARGET    uint   xyzw
+// SV_DEPTH                 0    N/A   oDepth    DEPTH   float    YES
+//
+ps_4_0
+dcl_constantbuffer cb0[2], immediateIndexed
+dcl_output o0.xyzw
+dcl_output o1.xyzw
+dcl_output oDepth
+mov o0.xyzw, cb0[0].xyzw
+mov o1.xyzw, cb0[0].xyzw
+mov oDepth, cb0[1].x
+ret 
+// Approximately 4 instruction slots used
+#endif
+
+const BYTE g_PS_ClearUint2[] = {
+    68,  88,  66,  67,  64,  241, 9,   8,   108, 162, 163, 180, 109, 195, 189, 181, 110, 171, 114,
+    118, 1,   0,   0,   0,   236, 2,   0,   0,   5,   0,   0,   0,   52,  0,   0,   0,   72,  1,
+    0,   0,   124, 1,   0,   0,   232, 1,   0,   0,   112, 2,   0,   0,   82,  68,  69,  70,  12,
+    1,   0,   0,   1,   0,   0,   0,   84,  0,   0,   0,   1,   0,   0,   0,   28,  0,   0,   0,
+    0,   4,   255, 255, 0,   1,   0,   0,   216, 0,   0,   0,   60,  0,   0,   0,   0,   0,   0,
+    0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   1,   0,
+    0,   0,   1,   0,   0,   0,   67,  111, 108, 111, 114, 65,  110, 100, 68,  101, 112, 116, 104,
+    68,  97,  116, 97,  85,  105, 110, 116, 0,   171, 171, 60,  0,   0,   0,   2,   0,   0,   0,
+    108, 0,   0,   0,   32,  0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   156, 0,   0,
+    0,   0,   0,   0,   0,   16,  0,   0,   0,   2,   0,   0,   0,   168, 0,   0,   0,   0,   0,
+    0,   0,   184, 0,   0,   0,   16,  0,   0,   0,   4,   0,   0,   0,   2,   0,   0,   0,   200,
+    0,   0,   0,   0,   0,   0,   0,   99,  111, 108, 111, 114, 95,  85,  105, 110, 116, 0,   171,
+    1,   0,   19,  0,   1,   0,   4,   0,   0,   0,   0,   0,   0,   0,   0,   0,   122, 86,  97,
+    108, 117, 101, 70,  95,  85,  105, 110, 116, 0,   171, 171, 171, 0,   0,   3,   0,   1,   0,
+    1,   0,   0,   0,   0,   0,   0,   0,   0,   0,   77,  105, 99,  114, 111, 115, 111, 102, 116,
+    32,  40,  82,  41,  32,  72,  76,  83,  76,  32,  83,  104, 97,  100, 101, 114, 32,  67,  111,
+    109, 112, 105, 108, 101, 114, 32,  54,  46,  51,  46,  57,  54,  48,  48,  46,  49,  54,  51,
+    56,  52,  0,   171, 171, 73,  83,  71,  78,  44,  0,   0,   0,   1,   0,   0,   0,   8,   0,
+    0,   0,   32,  0,   0,   0,   0,   0,   0,   0,   1,   0,   0,   0,   3,   0,   0,   0,   0,
+    0,   0,   0,   15,  0,   0,   0,   83,  86,  95,  80,  79,  83,  73,  84,  73,  79,  78,  0,
+    79,  83,  71,  78,  100, 0,   0,   0,   3,   0,   0,   0,   8,   0,   0,   0,   80,  0,   0,
+    0,   0,   0,   0,   0,   0,   0,   0,   0,   1,   0,   0,   0,   0,   0,   0,   0,   15,  0,
+    0,   0,   80,  0,   0,   0,   1,   0,   0,   0,   0,   0,   0,   0,   1,   0,   0,   0,   1,
+    0,   0,   0,   15,  0,   0,   0,   90,  0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+    3,   0,   0,   0,   255, 255, 255, 255, 1,   14,  0,   0,   83,  86,  95,  84,  65,  82,  71,
+    69,  84,  0,   83,  86,  95,  68,  69,  80,  84,  72,  0,   171, 83,  72,  68,  82,  128, 0,
+    0,   0,   64,  0,   0,   0,   32,  0,   0,   0,   89,  0,   0,   4,   70,  142, 32,  0,   0,
+    0,   0,   0,   2,   0,   0,   0,   101, 0,   0,   3,   242, 32,  16,  0,   0,   0,   0,   0,
+    101, 0,   0,   3,   242, 32,  16,  0,   1,   0,   0,   0,   101, 0,   0,   2,   1,   192, 0,
+    0,   54,  0,   0,   6,   242, 32,  16,  0,   0,   0,   0,   0,   70,  142, 32,  0,   0,   0,
+    0,   0,   0,   0,   0,   0,   54,  0,   0,   6,   242, 32,  16,  0,   1,   0,   0,   0,   70,
+    142, 32,  0,   0,   0,   0,   0,   0,   0,   0,   0,   54,  0,   0,   5,   1,   192, 0,   0,
+    10,  128, 32,  0,   0,   0,   0,   0,   1,   0,   0,   0,   62,  0,   0,   1,   83,  84,  65,
+    84,  116, 0,   0,   0,   4,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   3,   0,
+    0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   1,   0,   0,   0,   0,
+    0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+    0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+    0,   0,   0,   0,   0,   3,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+    0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+    0,   0,   0,   0,   0,   0,   0};
--- a/gfx/angle/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/clearuint11ps3.h
+++ b/gfx/angle/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/clearuint11ps3.h
@@ -1,98 +1,98 @@
-#if 0
-//
-// Generated by Microsoft (R) HLSL Shader Compiler 6.3.9600.16384
-//
-//
-// Buffer Definitions: 
-//
-// cbuffer ColorAndDepthDataUint
-// {
-//
-//   uint4 color_Uint;                  // Offset:    0 Size:    16
-//   float zValueF_Uint;                // Offset:   16 Size:     4
-//
-// }
-//
-//
-// Resource Bindings:
-//
-// Name                                 Type  Format         Dim Slot Elements
-// ------------------------------ ---------- ------- ----------- ---- --------
-// ColorAndDepthDataUint             cbuffer      NA          NA    0        1
-//
-//
-//
-// Input signature:
-//
-// Name                 Index   Mask Register SysValue  Format   Used
-// -------------------- ----- ------ -------- -------- ------- ------
-// SV_POSITION              0   xyzw        0      POS   float       
-//
-//
-// Output signature:
-//
-// Name                 Index   Mask Register SysValue  Format   Used
-// -------------------- ----- ------ -------- -------- ------- ------
-// SV_TARGET                0   xyzw        0   TARGET    uint   xyzw
-// SV_TARGET                1   xyzw        1   TARGET    uint   xyzw
-// SV_TARGET                2   xyzw        2   TARGET    uint   xyzw
-// SV_DEPTH                 0    N/A   oDepth    DEPTH   float    YES
-//
-ps_4_0
-dcl_constantbuffer cb0[2], immediateIndexed
-dcl_output o0.xyzw
-dcl_output o1.xyzw
-dcl_output o2.xyzw
-dcl_output oDepth
-mov o0.xyzw, cb0[0].xyzw
-mov o1.xyzw, cb0[0].xyzw
-mov o2.xyzw, cb0[0].xyzw
-mov oDepth, cb0[1].x
-ret 
-// Approximately 5 instruction slots used
-#endif
-
-const BYTE g_PS_ClearUint3[] = {
-    68,  88,  66,  67,  207, 249, 236, 218, 42,  28,  216, 245, 185, 80,  143, 139, 56,  108, 199,
-    11,  1,   0,   0,   0,   40,  3,   0,   0,   5,   0,   0,   0,   52,  0,   0,   0,   72,  1,
-    0,   0,   124, 1,   0,   0,   0,   2,   0,   0,   172, 2,   0,   0,   82,  68,  69,  70,  12,
-    1,   0,   0,   1,   0,   0,   0,   84,  0,   0,   0,   1,   0,   0,   0,   28,  0,   0,   0,
-    0,   4,   255, 255, 0,   1,   0,   0,   216, 0,   0,   0,   60,  0,   0,   0,   0,   0,   0,
-    0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   1,   0,
-    0,   0,   1,   0,   0,   0,   67,  111, 108, 111, 114, 65,  110, 100, 68,  101, 112, 116, 104,
-    68,  97,  116, 97,  85,  105, 110, 116, 0,   171, 171, 60,  0,   0,   0,   2,   0,   0,   0,
-    108, 0,   0,   0,   32,  0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   156, 0,   0,
-    0,   0,   0,   0,   0,   16,  0,   0,   0,   2,   0,   0,   0,   168, 0,   0,   0,   0,   0,
-    0,   0,   184, 0,   0,   0,   16,  0,   0,   0,   4,   0,   0,   0,   2,   0,   0,   0,   200,
-    0,   0,   0,   0,   0,   0,   0,   99,  111, 108, 111, 114, 95,  85,  105, 110, 116, 0,   171,
-    1,   0,   19,  0,   1,   0,   4,   0,   0,   0,   0,   0,   0,   0,   0,   0,   122, 86,  97,
-    108, 117, 101, 70,  95,  85,  105, 110, 116, 0,   171, 171, 171, 0,   0,   3,   0,   1,   0,
-    1,   0,   0,   0,   0,   0,   0,   0,   0,   0,   77,  105, 99,  114, 111, 115, 111, 102, 116,
-    32,  40,  82,  41,  32,  72,  76,  83,  76,  32,  83,  104, 97,  100, 101, 114, 32,  67,  111,
-    109, 112, 105, 108, 101, 114, 32,  54,  46,  51,  46,  57,  54,  48,  48,  46,  49,  54,  51,
-    56,  52,  0,   171, 171, 73,  83,  71,  78,  44,  0,   0,   0,   1,   0,   0,   0,   8,   0,
-    0,   0,   32,  0,   0,   0,   0,   0,   0,   0,   1,   0,   0,   0,   3,   0,   0,   0,   0,
-    0,   0,   0,   15,  0,   0,   0,   83,  86,  95,  80,  79,  83,  73,  84,  73,  79,  78,  0,
-    79,  83,  71,  78,  124, 0,   0,   0,   4,   0,   0,   0,   8,   0,   0,   0,   104, 0,   0,
-    0,   0,   0,   0,   0,   0,   0,   0,   0,   1,   0,   0,   0,   0,   0,   0,   0,   15,  0,
-    0,   0,   104, 0,   0,   0,   1,   0,   0,   0,   0,   0,   0,   0,   1,   0,   0,   0,   1,
-    0,   0,   0,   15,  0,   0,   0,   104, 0,   0,   0,   2,   0,   0,   0,   0,   0,   0,   0,
-    1,   0,   0,   0,   2,   0,   0,   0,   15,  0,   0,   0,   114, 0,   0,   0,   0,   0,   0,
-    0,   0,   0,   0,   0,   3,   0,   0,   0,   255, 255, 255, 255, 1,   14,  0,   0,   83,  86,
-    95,  84,  65,  82,  71,  69,  84,  0,   83,  86,  95,  68,  69,  80,  84,  72,  0,   171, 83,
-    72,  68,  82,  164, 0,   0,   0,   64,  0,   0,   0,   41,  0,   0,   0,   89,  0,   0,   4,
-    70,  142, 32,  0,   0,   0,   0,   0,   2,   0,   0,   0,   101, 0,   0,   3,   242, 32,  16,
-    0,   0,   0,   0,   0,   101, 0,   0,   3,   242, 32,  16,  0,   1,   0,   0,   0,   101, 0,
-    0,   3,   242, 32,  16,  0,   2,   0,   0,   0,   101, 0,   0,   2,   1,   192, 0,   0,   54,
-    0,   0,   6,   242, 32,  16,  0,   0,   0,   0,   0,   70,  142, 32,  0,   0,   0,   0,   0,
-    0,   0,   0,   0,   54,  0,   0,   6,   242, 32,  16,  0,   1,   0,   0,   0,   70,  142, 32,
-    0,   0,   0,   0,   0,   0,   0,   0,   0,   54,  0,   0,   6,   242, 32,  16,  0,   2,   0,
-    0,   0,   70,  142, 32,  0,   0,   0,   0,   0,   0,   0,   0,   0,   54,  0,   0,   5,   1,
-    192, 0,   0,   10,  128, 32,  0,   0,   0,   0,   0,   1,   0,   0,   0,   62,  0,   0,   1,
-    83,  84,  65,  84,  116, 0,   0,   0,   5,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
-    0,   4,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   1,   0,
-    0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
-    0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
-    0,   0,   0,   0,   0,   0,   0,   0,   4,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
-    0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
-    0,   0,   0,   0,   0,   0,   0,   0,   0,   0};
+#if 0
+//
+// Generated by Microsoft (R) HLSL Shader Compiler 6.3.9600.16384
+//
+//
+// Buffer Definitions: 
+//
+// cbuffer ColorAndDepthDataUint
+// {
+//
+//   uint4 color_Uint;                  // Offset:    0 Size:    16
+//   float zValueF_Uint;                // Offset:   16 Size:     4
+//
+// }
+//
+//
+// Resource Bindings:
+//
+// Name                                 Type  Format         Dim Slot Elements
+// ------------------------------ ---------- ------- ----------- ---- --------
+// ColorAndDepthDataUint             cbuffer      NA          NA    0        1
+//
+//
+//
+// Input signature:
+//
+// Name                 Index   Mask Register SysValue  Format   Used
+// -------------------- ----- ------ -------- -------- ------- ------
+// SV_POSITION              0   xyzw        0      POS   float       
+//
+//
+// Output signature:
+//
+// Name                 Index   Mask Register SysValue  Format   Used
+// -------------------- ----- ------ -------- -------- ------- ------
+// SV_TARGET                0   xyzw        0   TARGET    uint   xyzw
+// SV_TARGET                1   xyzw        1   TARGET    uint   xyzw
+// SV_TARGET                2   xyzw        2   TARGET    uint   xyzw
+// SV_DEPTH                 0    N/A   oDepth    DEPTH   float    YES
+//
+ps_4_0
+dcl_constantbuffer cb0[2], immediateIndexed
+dcl_output o0.xyzw
+dcl_output o1.xyzw
+dcl_output o2.xyzw
+dcl_output oDepth
+mov o0.xyzw, cb0[0].xyzw
+mov o1.xyzw, cb0[0].xyzw
+mov o2.xyzw, cb0[0].xyzw
+mov oDepth, cb0[1].x
+ret 
+// Approximately 5 instruction slots used
+#endif
+
+const BYTE g_PS_ClearUint3[] = {
+    68,  88,  66,  67,  207, 249, 236, 218, 42,  28,  216, 245, 185, 80,  143, 139, 56,  108, 199,
+    11,  1,   0,   0,   0,   40,  3,   0,   0,   5,   0,   0,   0,   52,  0,   0,   0,   72,  1,
+    0,   0,   124, 1,   0,   0,   0,   2,   0,   0,   172, 2,   0,   0,   82,  68,  69,  70,  12,
+    1,   0,   0,   1,   0,   0,   0,   84,  0,   0,   0,   1,   0,   0,   0,   28,  0,   0,   0,
+    0,   4,   255, 255, 0,   1,   0,   0,   216, 0,   0,   0,   60,  0,   0,   0,   0,   0,   0,
+    0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   1,   0,
+    0,   0,   1,   0,   0,   0,   67,  111, 108, 111, 114, 65,  110, 100, 68,  101, 112, 116, 104,
+    68,  97,  116, 97,  85,  105, 110, 116, 0,   171, 171, 60,  0,   0,   0,   2,   0,   0,   0,
+    108, 0,   0,   0,   32,  0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   156, 0,   0,
+    0,   0,   0,   0,   0,   16,  0,   0,   0,   2,   0,   0,   0,   168, 0,   0,   0,   0,   0,
+    0,   0,   184, 0,   0,   0,   16,  0,   0,   0,   4,   0,   0,   0,   2,   0,   0,   0,   200,
+    0,   0,   0,   0,   0,   0,   0,   99,  111, 108, 111, 114, 95,  85,  105, 110, 116, 0,   171,
+    1,   0,   19,  0,   1,   0,   4,   0,   0,   0,   0,   0,   0,   0,   0,   0,   122, 86,  97,
+    108, 117, 101, 70,  95,  85,  105, 110, 116, 0,   171, 171, 171, 0,   0,   3,   0,   1,   0,
+    1,   0,   0,   0,   0,   0,   0,   0,   0,   0,   77,  105, 99,  114, 111, 115, 111, 102, 116,
+    32,  40,  82,  41,  32,  72,  76,  83,  76,  32,  83,  104, 97,  100, 101, 114, 32,  67,  111,
+    109, 112, 105, 108, 101, 114, 32,  54,  46,  51,  46,  57,  54,  48,  48,  46,  49,  54,  51,
+    56,  52,  0,   171, 171, 73,  83,  71,  78,  44,  0,   0,   0,   1,   0,   0,   0,   8,   0,
+    0,   0,   32,  0,   0,   0,   0,   0,   0,   0,   1,   0,   0,   0,   3,   0,   0,   0,   0,
+    0,   0,   0,   15,  0,   0,   0,   83,  86,  95,  80,  79,  83,  73,  84,  73,  79,  78,  0,
+    79,  83,  71,  78,  124, 0,   0,   0,   4,   0,   0,   0,   8,   0,   0,   0,   104, 0,   0,
+    0,   0,   0,   0,   0,   0,   0,   0,   0,   1,   0,   0,   0,   0,   0,   0,   0,   15,  0,
+    0,   0,   104, 0,   0,   0,   1,   0,   0,   0,   0,   0,   0,   0,   1,   0,   0,   0,   1,
+    0,   0,   0,   15,  0,   0,   0,   104, 0,   0,   0,   2,   0,   0,   0,   0,   0,   0,   0,
+    1,   0,   0,   0,   2,   0,   0,   0,   15,  0,   0,   0,   114, 0,   0,   0,   0,   0,   0,
+    0,   0,   0,   0,   0,   3,   0,   0,   0,   255, 255, 255, 255, 1,   14,  0,   0,   83,  86,
+    95,  84,  65,  82,  71,  69,  84,  0,   83,  86,  95,  68,  69,  80,  84,  72,  0,   171, 83,
+    72,  68,  82,  164, 0,   0,   0,   64,  0,   0,   0,   41,  0,   0,   0,   89,  0,   0,   4,
+    70,  142, 32,  0,   0,   0,   0,   0,   2,   0,   0,   0,   101, 0,   0,   3,   242, 32,  16,
+    0,   0,   0,   0,   0,   101, 0,   0,   3,   242, 32,  16,  0,   1,   0,   0,   0,   101, 0,
+    0,   3,   242, 32,  16,  0,   2,   0,   0,   0,   101, 0,   0,   2,   1,   192, 0,   0,   54,
+    0,   0,   6,   242, 32,  16,  0,   0,   0,   0,   0,   70,  142, 32,  0,   0,   0,   0,   0,
+    0,   0,   0,   0,   54,  0,   0,   6,   242, 32,  16,  0,   1,   0,   0,   0,   70,  142, 32,
+    0,   0,   0,   0,   0,   0,   0,   0,   0,   54,  0,   0,   6,   242, 32,  16,  0,   2,   0,
+    0,   0,   70,  142, 32,  0,   0,   0,   0,   0,   0,   0,   0,   0,   54,  0,   0,   5,   1,
+    192, 0,   0,   10,  128, 32,  0,   0,   0,   0,   0,   1,   0,   0,   0,   62,  0,   0,   1,
+    83,  84,  65,  84,  116, 0,   0,   0,   5,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+    0,   4,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   1,   0,
+    0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+    0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+    0,   0,   0,   0,   0,   0,   0,   0,   4,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+    0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+    0,   0,   0,   0,   0,   0,   0,   0,   0,   0};
--- a/gfx/angle/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/clearuint11ps4.h
+++ b/gfx/angle/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/clearuint11ps4.h
@@ -1,104 +1,104 @@
-#if 0
-//
-// Generated by Microsoft (R) HLSL Shader Compiler 6.3.9600.16384
-//
-//
-// Buffer Definitions: 
-//
-// cbuffer ColorAndDepthDataUint
-// {
-//
-//   uint4 color_Uint;                  // Offset:    0 Size:    16
-//   float zValueF_Uint;                // Offset:   16 Size:     4
-//
-// }
-//
-//
-// Resource Bindings:
-//
-// Name                                 Type  Format         Dim Slot Elements
-// ------------------------------ ---------- ------- ----------- ---- --------
-// ColorAndDepthDataUint             cbuffer      NA          NA    0        1
-//
-//
-//
-// Input signature:
-//
-// Name                 Index   Mask Register SysValue  Format   Used
-// -------------------- ----- ------ -------- -------- ------- ------
-// SV_POSITION              0   xyzw        0      POS   float       
-//
-//
-// Output signature:
-//
-// Name                 Index   Mask Register SysValue  Format   Used
-// -------------------- ----- ------ -------- -------- ------- ------
-// SV_TARGET                0   xyzw        0   TARGET    uint   xyzw
-// SV_TARGET                1   xyzw        1   TARGET    uint   xyzw
-// SV_TARGET                2   xyzw        2   TARGET    uint   xyzw
-// SV_TARGET                3   xyzw        3   TARGET    uint   xyzw
-// SV_DEPTH                 0    N/A   oDepth    DEPTH   float    YES
-//
-ps_4_0
-dcl_constantbuffer cb0[2], immediateIndexed
-dcl_output o0.xyzw
-dcl_output o1.xyzw
-dcl_output o2.xyzw
-dcl_output o3.xyzw
-dcl_output oDepth
-mov o0.xyzw, cb0[0].xyzw
-mov o1.xyzw, cb0[0].xyzw
-mov o2.xyzw, cb0[0].xyzw
-mov o3.xyzw, cb0[0].xyzw
-mov oDepth, cb0[1].x
-ret 
-// Approximately 6 instruction slots used
-#endif
-
-const BYTE g_PS_ClearUint4[] = {
-    68,  88,  66,  67,  199, 123, 16,  1,   215, 108, 177, 8,   10,  177, 4,   33,  216, 58,  53,
-    78,  1,   0,   0,   0,   100, 3,   0,   0,   5,   0,   0,   0,   52,  0,   0,   0,   72,  1,
-    0,   0,   124, 1,   0,   0,   24,  2,   0,   0,   232, 2,   0,   0,   82,  68,  69,  70,  12,
-    1,   0,   0,   1,   0,   0,   0,   84,  0,   0,   0,   1,   0,   0,   0,   28,  0,   0,   0,
-    0,   4,   255, 255, 0,   1,   0,   0,   216, 0,   0,   0,   60,  0,   0,   0,   0,   0,   0,
-    0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   1,   0,
-    0,   0,   1,   0,   0,   0,   67,  111, 108, 111, 114, 65,  110, 100, 68,  101, 112, 116, 104,
-    68,  97,  116, 97,  85,  105, 110, 116, 0,   171, 171, 60,  0,   0,   0,   2,   0,   0,   0,
-    108, 0,   0,   0,   32,  0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   156, 0,   0,
-    0,   0,   0,   0,   0,   16,  0,   0,   0,   2,   0,   0,   0,   168, 0,   0,   0,   0,   0,
-    0,   0,   184, 0,   0,   0,   16,  0,   0,   0,   4,   0,   0,   0,   2,   0,   0,   0,   200,
-    0,   0,   0,   0,   0,   0,   0,   99,  111, 108, 111, 114, 95,  85,  105, 110, 116, 0,   171,
-    1,   0,   19,  0,   1,   0,   4,   0,   0,   0,   0,   0,   0,   0,   0,   0,   122, 86,  97,
-    108, 117, 101, 70,  95,  85,  105, 110, 116, 0,   171, 171, 171, 0,   0,   3,   0,   1,   0,
-    1,   0,   0,   0,   0,   0,   0,   0,   0,   0,   77,  105, 99,  114, 111, 115, 111, 102, 116,
-    32,  40,  82,  41,  32,  72,  76,  83,  76,  32,  83,  104, 97,  100, 101, 114, 32,  67,  111,
-    109, 112, 105, 108, 101, 114, 32,  54,  46,  51,  46,  57,  54,  48,  48,  46,  49,  54,  51,
-    56,  52,  0,   171, 171, 73,  83,  71,  78,  44,  0,   0,   0,   1,   0,   0,   0,   8,   0,
-    0,   0,   32,  0,   0,   0,   0,   0,   0,   0,   1,   0,   0,   0,   3,   0,   0,   0,   0,
-    0,   0,   0,   15,  0,   0,   0,   83,  86,  95,  80,  79,  83,  73,  84,  73,  79,  78,  0,
-    79,  83,  71,  78,  148, 0,   0,   0,   5,   0,   0,   0,   8,   0,   0,   0,   128, 0,   0,
-    0,   0,   0,   0,   0,   0,   0,   0,   0,   1,   0,   0,   0,   0,   0,   0,   0,   15,  0,
-    0,   0,   128, 0,   0,   0,   1,   0,   0,   0,   0,   0,   0,   0,   1,   0,   0,   0,   1,
-    0,   0,   0,   15,  0,   0,   0,   128, 0,   0,   0,   2,   0,   0,   0,   0,   0,   0,   0,
-    1,   0,   0,   0,   2,   0,   0,   0,   15,  0,   0,   0,   128, 0,   0,   0,   3,   0,   0,
-    0,   0,   0,   0,   0,   1,   0,   0,   0,   3,   0,   0,   0,   15,  0,   0,   0,   138, 0,
-    0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   3,   0,   0,   0,   255, 255, 255, 255, 1,
-    14,  0,   0,   83,  86,  95,  84,  65,  82,  71,  69,  84,  0,   83,  86,  95,  68,  69,  80,
-    84,  72,  0,   171, 83,  72,  68,  82,  200, 0,   0,   0,   64,  0,   0,   0,   50,  0,   0,
-    0,   89,  0,   0,   4,   70,  142, 32,  0,   0,   0,   0,   0,   2,   0,   0,   0,   101, 0,
-    0,   3,   242, 32,  16,  0,   0,   0,   0,   0,   101, 0,   0,   3,   242, 32,  16,  0,   1,
-    0,   0,   0,   101, 0,   0,   3,   242, 32,  16,  0,   2,   0,   0,   0,   101, 0,   0,   3,
-    242, 32,  16,  0,   3,   0,   0,   0,   101, 0,   0,   2,   1,   192, 0,   0,   54,  0,   0,
-    6,   242, 32,  16,  0,   0,   0,   0,   0,   70,  142, 32,  0,   0,   0,   0,   0,   0,   0,
-    0,   0,   54,  0,   0,   6,   242, 32,  16,  0,   1,   0,   0,   0,   70,  142, 32,  0,   0,
-    0,   0,   0,   0,   0,   0,   0,   54,  0,   0,   6,   242, 32,  16,  0,   2,   0,   0,   0,
-    70,  142, 32,  0,   0,   0,   0,   0,   0,   0,   0,   0,   54,  0,   0,   6,   242, 32,  16,
-    0,   3,   0,   0,   0,   70,  142, 32,  0,   0,   0,   0,   0,   0,   0,   0,   0,   54,  0,
-    0,   5,   1,   192, 0,   0,   10,  128, 32,  0,   0,   0,   0,   0,   1,   0,   0,   0,   62,
-    0,   0,   1,   83,  84,  65,  84,  116, 0,   0,   0,   6,   0,   0,   0,   0,   0,   0,   0,
-    0,   0,   0,   0,   5,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
-    0,   1,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
-    0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
-    0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   5,   0,   0,   0,   0,   0,   0,   0,
-    0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
-    0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0};
+#if 0
+//
+// Generated by Microsoft (R) HLSL Shader Compiler 6.3.9600.16384
+//
+//
+// Buffer Definitions: 
+//
+// cbuffer ColorAndDepthDataUint
+// {
+//
+//   uint4 color_Uint;                  // Offset:    0 Size:    16
+//   float zValueF_Uint;                // Offset:   16 Size:     4
+//
+// }
+//
+//
+// Resource Bindings:
+//
+// Name                                 Type  Format         Dim Slot Elements
+// ------------------------------ ---------- ------- ----------- ---- --------
+// ColorAndDepthDataUint             cbuffer      NA          NA    0        1
+//
+//
+//
+// Input signature:
+//
+// Name                 Index   Mask Register SysValue  Format   Used
+// -------------------- ----- ------ -------- -------- ------- ------
+// SV_POSITION              0   xyzw        0      POS   float       
+//
+//
+// Output signature:
+//
+// Name                 Index   Mask Register SysValue  Format   Used
+// -------------------- ----- ------ -------- -------- ------- ------
+// SV_TARGET                0   xyzw        0   TARGET    uint   xyzw
+// SV_TARGET                1   xyzw        1   TARGET    uint   xyzw
+// SV_TARGET                2   xyzw        2   TARGET    uint   xyzw
+// SV_TARGET                3   xyzw        3   TARGET    uint   xyzw
+// SV_DEPTH                 0    N/A   oDepth    DEPTH   float    YES
+//
+ps_4_0
+dcl_constantbuffer cb0[2], immediateIndexed
+dcl_output o0.xyzw
+dcl_output o1.xyzw
+dcl_output o2.xyzw
+dcl_output o3.xyzw
+dcl_output oDepth
+mov o0.xyzw, cb0[0].xyzw
+mov o1.xyzw, cb0[0].xyzw
+mov o2.xyzw, cb0[0].xyzw
+mov o3.xyzw, cb0[0].xyzw
+mov oDepth, cb0[1].x
+ret 
+// Approximately 6 instruction slots used
+#endif
+
+const BYTE g_PS_ClearUint4[] = {
+    68,  88,  66,  67,  199, 123, 16,  1,   215, 108, 177, 8,   10,  177, 4,   33,  216, 58,  53,
+    78,  1,   0,   0,   0,   100, 3,   0,   0,   5,   0,   0,   0,   52,  0,   0,   0,   72,  1,
+    0,   0,   124, 1,   0,   0,   24,  2,   0,   0,   232, 2,   0,   0,   82,  68,  69,  70,  12,
+    1,   0,   0,   1,   0,   0,   0,   84,  0,   0,   0,   1,   0,   0,   0,   28,  0,   0,   0,
+    0,   4,   255, 255, 0,   1,   0,   0,   216, 0,   0,   0,   60,  0,   0,   0,   0,   0,   0,
+    0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   1,   0,
+    0,   0,   1,   0,   0,   0,   67,  111, 108, 111, 114, 65,  110, 100, 68,  101, 112, 116, 104,
+    68,  97,  116, 97,  85,  105, 110, 116, 0,   171, 171, 60,  0,   0,   0,   2,   0,   0,   0,
+    108, 0,   0,   0,   32,  0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   156, 0,   0,
+    0,   0,   0,   0,   0,   16,  0,   0,   0,   2,   0,   0,   0,   168, 0,   0,   0,   0,   0,
+    0,   0,   184, 0,   0,   0,   16,  0,   0,   0,   4,   0,   0,   0,   2,   0,   0,   0,   200,
+    0,   0,   0,   0,   0,   0,   0,   99,  111, 108, 111, 114, 95,  85,  105, 110, 116, 0,   171,
+    1,   0,   19,  0,   1,   0,   4,   0,   0,   0,   0,   0,   0,   0,   0,   0,   122, 86,  97,
+    108, 117, 101, 70,  95,  85,  105, 110, 116, 0,   171, 171, 171, 0,   0,   3,   0,   1,   0,
+    1,   0,   0,   0,   0,   0,   0,   0,   0,   0,   77,  105, 99,  114, 111, 115, 111, 102, 116,
+    32,  40,  82,  41,  32,  72,  76,  83,  76,  32,  83,  104, 97,  100, 101, 114, 32,  67,  111,
+    109, 112, 105, 108, 101, 114, 32,  54,  46,  51,  46,  57,  54,  48,  48,  46,  49,  54,  51,
+    56,  52,  0,   171, 171, 73,  83,  71,  78,  44,  0,   0,   0,   1,   0,   0,   0,   8,   0,
+    0,   0,   32,  0,   0,   0,   0,   0,   0,   0,   1,   0,   0,   0,   3,   0,   0,   0,   0,
+    0,   0,   0,   15,  0,   0,   0,   83,  86,  95,  80,  79,  83,  73,  84,  73,  79,  78,  0,
+    79,  83,  71,  78,  148, 0,   0,   0,   5,   0,   0,   0,   8,   0,   0,   0,   128, 0,   0,
+    0,   0,   0,   0,   0,   0,   0,   0,   0,   1,   0,   0,   0,   0,   0,   0,   0,   15,  0,
+    0,   0,   128, 0,   0,   0,   1,   0,   0,   0,   0,   0,   0,   0,   1,   0,   0,   0,   1,
+    0,   0,   0,   15,  0,   0,   0,   128, 0,   0,   0,   2,   0,   0,   0,   0,   0,   0,   0,
+    1,   0,   0,   0,   2,   0,   0,   0,   15,  0,   0,   0,   128, 0,   0,   0,   3,   0,   0,
+    0,   0,   0,   0,   0,   1,   0,   0,   0,   3,   0,   0,   0,   15,  0,   0,   0,   138, 0,
+    0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   3,   0,   0,   0,   255, 255, 255, 255, 1,
+    14,  0,   0,   83,  86,  95,  84,  65,  82,  71,  69,  84,  0,   83,  86,  95,  68,  69,  80,
+    84,  72,  0,   171, 83,  72,  68,  82,  200, 0,   0,   0,   64,  0,   0,   0,   50,  0,   0,
+    0,   89,  0,   0,   4,   70,  142, 32,  0,   0,   0,   0,   0,   2,   0,   0,   0,   101, 0,
+    0,   3,   242, 32,  16,  0,   0,   0,   0,   0,   101, 0,   0,   3,   242, 32,  16,  0,   1,
+    0,   0,   0,   101, 0,   0,   3,   242, 32,  16,  0,   2,   0,   0,   0,   101, 0,   0,   3,
+    242, 32,  16,  0,   3,   0,   0,   0,   101, 0,   0,   2,   1,   192, 0,   0,   54,  0,   0,
+    6,   242, 32,  16,  0,   0,   0,   0,   0,   70,  142, 32,  0,   0,   0,   0,   0,   0,   0,
+    0,   0,   54,  0,   0,   6,   242, 32,  16,  0,   1,   0,   0,   0,   70,  142, 32,  0,   0,
+    0,   0,   0,   0,   0,   0,   0,   54,  0,   0,   6,   242, 32,  16,  0,   2,   0,   0,   0,
+    70,  142, 32,  0,   0,   0,   0,   0,   0,   0,   0,   0,   54,  0,   0,   6,   242, 32,  16,
+    0,   3,   0,   0,   0,   70,  142, 32,  0,   0,   0,   0,   0,   0,   0,   0,   0,   54,  0,
+    0,   5,   1,   192, 0,   0,   10,  128, 32,  0,   0,   0,   0,   0,   1,   0,   0,   0,   62,
+    0,   0,   1,   83,  84,  65,  84,  116, 0,   0,   0,   6,   0,   0,   0,   0,   0,   0,   0,
+    0,   0,   0,   0,   5,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+    0,   1,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+    0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+    0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   5,   0,   0,   0,   0,   0,   0,   0,
+    0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+    0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0};
--- a/gfx/angle/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/clearuint11ps5.h
+++ b/gfx/angle/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/clearuint11ps5.h
@@ -1,110 +1,110 @@
-#if 0
-//
-// Generated by Microsoft (R) HLSL Shader Compiler 6.3.9600.16384
-//
-//
-// Buffer Definitions: 
-//
-// cbuffer ColorAndDepthDataUint
-// {
-//
-//   uint4 color_Uint;                  // Offset:    0 Size:    16
-//   float zValueF_Uint;                // Offset:   16 Size:     4
-//
-// }
-//
-//
-// Resource Bindings:
-//
-// Name                                 Type  Format         Dim Slot Elements
-// ------------------------------ ---------- ------- ----------- ---- --------
-// ColorAndDepthDataUint             cbuffer      NA          NA    0        1
-//
-//
-//
-// Input signature:
-//
-// Name                 Index   Mask Register SysValue  Format   Used
-// -------------------- ----- ------ -------- -------- ------- ------
-// SV_POSITION              0   xyzw        0      POS   float       
-//
-//
-// Output signature:
-//
-// Name                 Index   Mask Register SysValue  Format   Used
-// -------------------- ----- ------ -------- -------- ------- ------
-// SV_TARGET                0   xyzw        0   TARGET    uint   xyzw
-// SV_TARGET                1   xyzw        1   TARGET    uint   xyzw
-// SV_TARGET                2   xyzw        2   TARGET    uint   xyzw
-// SV_TARGET                3   xyzw        3   TARGET    uint   xyzw
-// SV_TARGET                4   xyzw        4   TARGET    uint   xyzw
-// SV_DEPTH                 0    N/A   oDepth    DEPTH   float    YES
-//
-ps_4_0
-dcl_constantbuffer cb0[2], immediateIndexed
-dcl_output o0.xyzw
-dcl_output o1.xyzw
-dcl_output o2.xyzw
-dcl_output o3.xyzw
-dcl_output o4.xyzw
-dcl_output oDepth
-mov o0.xyzw, cb0[0].xyzw
-mov o1.xyzw, cb0[0].xyzw
-mov o2.xyzw, cb0[0].xyzw
-mov o3.xyzw, cb0[0].xyzw
-mov o4.xyzw, cb0[0].xyzw
-mov oDepth, cb0[1].x
-ret 
-// Approximately 7 instruction slots used
-#endif
-
-const BYTE g_PS_ClearUint5[] = {
-    68,  88,  66,  67,  200, 229, 167, 131, 228, 54,  139, 228, 159, 151, 189, 241, 206, 62,  101,
-    65,  1,   0,   0,   0,   160, 3,   0,   0,   5,   0,   0,   0,   52,  0,   0,   0,   72,  1,
-    0,   0,   124, 1,   0,   0,   48,  2,   0,   0,   36,  3,   0,   0,   82,  68,  69,  70,  12,
-    1,   0,   0,   1,   0,   0,   0,   84,  0,   0,   0,   1,   0,   0,   0,   28,  0,   0,   0,
-    0,   4,   255, 255, 0,   1,   0,   0,   216, 0,   0,   0,   60,  0,   0,   0,   0,   0,   0,
-    0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   1,   0,
-    0,   0,   1,   0,   0,   0,   67,  111, 108, 111, 114, 65,  110, 100, 68,  101, 112, 116, 104,
-    68,  97,  116, 97,  85,  105, 110, 116, 0,   171, 171, 60,  0,   0,   0,   2,   0,   0,   0,
-    108, 0,   0,   0,   32,  0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   156, 0,   0,
-    0,   0,   0,   0,   0,   16,  0,   0,   0,   2,   0,   0,   0,   168, 0,   0,   0,   0,   0,
-    0,   0,   184, 0,   0,   0,   16,  0,   0,   0,   4,   0,   0,   0,   2,   0,   0,   0,   200,
-    0,   0,   0,   0,   0,   0,   0,   99,  111, 108, 111, 114, 95,  85,  105, 110, 116, 0,   171,
-    1,   0,   19,  0,   1,   0,   4,   0,   0,   0,   0,   0,   0,   0,   0,   0,   122, 86,  97,
-    108, 117, 101, 70,  95,  85,  105, 110, 116, 0,   171, 171, 171, 0,   0,   3,   0,   1,   0,
-    1,   0,   0,   0,   0,   0,   0,   0,   0,   0,   77,  105, 99,  114, 111, 115, 111, 102, 116,
-    32,  40,  82,  41,  32,  72,  76,  83,  76,  32,  83,  104, 97,  100, 101, 114, 32,  67,  111,
-    109, 112, 105, 108, 101, 114, 32,  54,  46,  51,  46,  57,  54,  48,  48,  46,  49,  54,  51,
-    56,  52,  0,   171, 171, 73,  83,  71,  78,  44,  0,   0,   0,   1,   0,   0,   0,   8,   0,
-    0,   0,   32,  0,   0,   0,   0,   0,   0,   0,   1,   0,   0,   0,   3,   0,   0,   0,   0,
-    0,   0,   0,   15,  0,   0,   0,   83,  86,  95,  80,  79,  83,  73,  84,  73,  79,  78,  0,
-    79,  83,  71,  78,  172, 0,   0,   0,   6,   0,   0,   0,   8,   0,   0,   0,   152, 0,   0,
-    0,   0,   0,   0,   0,   0,   0,   0,   0,   1,   0,   0,   0,   0,   0,   0,   0,   15,  0,
-    0,   0,   152, 0,   0,   0,   1,   0,   0,   0,   0,   0,   0,   0,   1,   0,   0,   0,   1,
-    0,   0,   0,   15,  0,   0,   0,   152, 0,   0,   0,   2,   0,   0,   0,   0,   0,   0,   0,
-    1,   0,   0,   0,   2,   0,   0,   0,   15,  0,   0,   0,   152, 0,   0,   0,   3,   0,   0,
-    0,   0,   0,   0,   0,   1,   0,   0,   0,   3,   0,   0,   0,   15,  0,   0,   0,   152, 0,
-    0,   0,   4,   0,   0,   0,   0,   0,   0,   0,   1,   0,   0,   0,   4,   0,   0,   0,   15,
-    0,   0,   0,   162, 0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   3,   0,   0,   0,
-    255, 255, 255, 255, 1,   14,  0,   0,   83,  86,  95,  84,  65,  82,  71,  69,  84,  0,   83,
-    86,  95,  68,  69,  80,  84,  72,  0,   171, 83,  72,  68,  82,  236, 0,   0,   0,   64,  0,
-    0,   0,   59,  0,   0,   0,   89,  0,   0,   4,   70,  142, 32,  0,   0,   0,   0,   0,   2,
-    0,   0,   0,   101, 0,   0,   3,   242, 32,  16,  0,   0,   0,   0,   0,   101, 0,   0,   3,
-    242, 32,  16,  0,   1,   0,   0,   0,   101, 0,   0,   3,   242, 32,  16,  0,   2,   0,   0,
-    0,   101, 0,   0,   3,   242, 32,  16,  0,   3,   0,   0,   0,   101, 0,   0,   3,   242, 32,
-    16,  0,   4,   0,   0,   0,   101, 0,   0,   2,   1,   192, 0,   0,   54,  0,   0,   6,   242,
-    32,  16,  0,   0,   0,   0,   0,   70,  142, 32,  0,   0,   0,   0,   0,   0,   0,   0,   0,
-    54,  0,   0,   6,   242, 32,  16,  0,   1,   0,   0,   0,   70,  142, 32,  0,   0,   0,   0,
-    0,   0,   0,   0,   0,   54,  0,   0,   6,   242, 32,  16,  0,   2,   0,   0,   0,   70,  142,
-    32,  0,   0,   0,   0,   0,   0,   0,   0,   0,   54,  0,   0,   6,   242, 32,  16,  0,   3,
-    0,   0,   0,   70,  142, 32,  0,   0,   0,   0,   0,   0,   0,   0,   0,   54,  0,   0,   6,
-    242, 32,  16,  0,   4,   0,   0,   0,   70,  142, 32,  0,   0,   0,   0,   0,   0,   0,   0,
-    0,   54,  0,   0,   5,   1,   192, 0,   0,   10,  128, 32,  0,   0,   0,   0,   0,   1,   0,
-    0,   0,   62,  0,   0,   1,   83,  84,  65,  84,  116, 0,   0,   0,   7,   0,   0,   0,   0,
-    0,   0,   0,   0,   0,   0,   0,   6,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
-    0,   0,   0,   0,   1,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
-    0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
-    0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   6,   0,   0,   0,   0,
-    0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
-    0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0};
+#if 0
+//
+// Generated by Microsoft (R) HLSL Shader Compiler 6.3.9600.16384
+//
+//
+// Buffer Definitions: 
+//
+// cbuffer ColorAndDepthDataUint
+// {
+//
+//   uint4 color_Uint;                  // Offset:    0 Size:    16
+//   float zValueF_Uint;                // Offset:   16 Size:     4
+//
+// }
+//
+//
+// Resource Bindings:
+//
+// Name                                 Type  Format         Dim Slot Elements
+// ------------------------------ ---------- ------- ----------- ---- --------
+// ColorAndDepthDataUint             cbuffer      NA          NA    0        1
+//
+//
+//
+// Input signature:
+//
+// Name                 Index   Mask Register SysValue  Format   Used
+// -------------------- ----- ------ -------- -------- ------- ------
+// SV_POSITION              0   xyzw        0      POS   float       
+//
+//
+// Output signature:
+//
+// Name                 Index   Mask Register SysValue  Format   Used
+// -------------------- ----- ------ -------- -------- ------- ------
+// SV_TARGET                0   xyzw        0   TARGET    uint   xyzw
+// SV_TARGET                1   xyzw        1   TARGET    uint   xyzw
+// SV_TARGET                2   xyzw        2   TARGET    uint   xyzw
+// SV_TARGET                3   xyzw        3   TARGET    uint   xyzw
+// SV_TARGET                4   xyzw        4   TARGET    uint   xyzw
+// SV_DEPTH                 0    N/A   oDepth    DEPTH   float    YES
+//
+ps_4_0
+dcl_constantbuffer cb0[2], immediateIndexed
+dcl_output o0.xyzw
+dcl_output o1.xyzw
+dcl_output o2.xyzw
+dcl_output o3.xyzw
+dcl_output o4.xyzw
+dcl_output oDepth
+mov o0.xyzw, cb0[0].xyzw
+mov o1.xyzw, cb0[0].xyzw
+mov o2.xyzw, cb0[0].xyzw
+mov o3.xyzw, cb0[0].xyzw
+mov o4.xyzw, cb0[0].xyzw
+mov oDepth, cb0[1].x
+ret 
+// Approximately 7 instruction slots used
+#endif
+
+const BYTE g_PS_ClearUint5[] = {
+    68,  88,  66,  67,  200, 229, 167, 131, 228, 54,  139, 228, 159, 151, 189, 241, 206, 62,  101,
+    65,  1,   0,   0,   0,   160, 3,   0,   0,   5,   0,   0,   0,   52,  0,   0,   0,   72,  1,
+    0,   0,   124, 1,   0,   0,   48,  2,   0,   0,   36,  3,   0,   0,   82,  68,  69,  70,  12,
+    1,   0,   0,   1,   0,   0,   0,   84,  0,   0,   0,   1,   0,   0,   0,   28,  0,   0,   0,
+    0,   4,   255, 255, 0,   1,   0,   0,   216, 0,   0,   0,   60,  0,   0,   0,   0,   0,   0,
+    0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   1,   0,
+    0,   0,   1,   0,   0,   0,   67,  111, 108, 111, 114, 65,  110, 100, 68,  101, 112, 116, 104,
+    68,  97,  116, 97,  85,  105, 110, 116, 0,   171, 171, 60,  0,   0,   0,   2,   0,   0,   0,
+    108, 0,   0,   0,   32,  0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   156, 0,   0,
+    0,   0,   0,   0,   0,   16,  0,   0,   0,   2,   0,   0,   0,   168, 0,   0,   0,   0,   0,
+    0,   0,   184, 0,   0,   0,   16,  0,   0,   0,   4,   0,   0,   0,   2,   0,   0,   0,   200,
+    0,   0,   0,   0,   0,   0,   0,   99,  111, 108, 111, 114, 95,  85,  105, 110, 116, 0,   171,
+    1,   0,   19,  0,   1,   0,   4,   0,   0,   0,   0,   0,   0,   0,   0,   0,   122, 86,  97,
+    108, 117, 101, 70,  95,  85,  105, 110, 116, 0,   171, 171, 171, 0,   0,   3,   0,   1,   0,
+    1,   0,   0,   0,   0,   0,   0,   0,   0,   0,   77,  105, 99,  114, 111, 115, 111, 102, 116,
+    32,  40,  82,  41,  32,  72,  76,  83,  76,  32,  83,  104, 97,  100, 101, 114, 32,  67,  111,
+    109, 112, 105, 108, 101, 114, 32,  54,  46,  51,  46,  57,  54,  48,  48,  46,  49,  54,  51,
+    56,  52,  0,   171, 171, 73,  83,  71,  78,  44,  0,   0,   0,   1,   0,   0,   0,   8,   0,
+    0,   0,   32,  0,   0,   0,   0,   0,   0,   0,   1,   0,   0,   0,   3,   0,   0,   0,   0,
+    0,   0,   0,   15,  0,   0,   0,   83,  86,  95,  80,  79,  83,  73,  84,  73,  79,  78,  0,
+    79,  83,  71,  78,  172, 0,   0,   0,   6,   0,   0,   0,   8,   0,   0,   0,   152, 0,   0,
+    0,   0,   0,   0,   0,   0,   0,   0,   0,   1,   0,   0,   0,   0,   0,   0,   0,   15,  0,
+    0,   0,   152, 0,   0,   0,   1,   0,   0,   0,   0,   0,   0,   0,   1,   0,   0,   0,   1,
+    0,   0,   0,   15,  0,   0,   0,   152, 0,   0,   0,   2,   0,   0,   0,   0,   0,   0,   0,
+    1,   0,   0,   0,   2,   0,   0,   0,   15,  0,   0,   0,   152, 0,   0,   0,   3,   0,   0,
+    0,   0,   0,   0,   0,   1,   0,   0,   0,   3,   0,   0,   0,   15,  0,   0,   0,   152, 0,
+    0,   0,   4,   0,   0,   0,   0,   0,   0,   0,   1,   0,   0,   0,   4,   0,   0,   0,   15,
+    0,   0,   0,   162, 0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   3,   0,   0,   0,
+    255, 255, 255, 255, 1,   14,  0,   0,   83,  86,  95,  84,  65,  82,  71,  69,  84,  0,   83,
+    86,  95,  68,  69,  80,  84,  72,  0,   171, 83,  72,  68,  82,  236, 0,   0,   0,   64,  0,
+    0,   0,   59,  0,   0,   0,   89,  0,   0,   4,   70,  142, 32,  0,   0,   0,   0,   0,   2,
+    0,   0,   0,   101, 0,   0,   3,   242, 32,  16,  0,   0,   0,   0,   0,   101, 0,   0,   3,
+    242, 32,  16,  0,   1,   0,   0,   0,   101, 0,   0,   3,   242, 32,  16,  0,   2,   0,   0,
+    0,   101, 0,   0,   3,   242, 32,  16,  0,   3,   0,   0,   0,   101, 0,   0,   3,   242, 32,
+    16,  0,   4,   0,   0,   0,   101, 0,   0,   2,   1,   192, 0,   0,   54,  0,   0,   6,   242,
+    32,  16,  0,   0,   0,   0,   0,   70,  142, 32,  0,   0,   0,   0,   0,   0,   0,   0,   0,
+    54,  0,   0,   6,   242, 32,  16,  0,   1,   0,   0,   0,   70,  142, 32,  0,   0,   0,   0,
+    0,   0,   0,   0,   0,   54,  0,   0,   6,   242, 32,  16,  0,   2,   0,   0,   0,   70,  142,
+    32,  0,   0,   0,   0,   0,   0,   0,   0,   0,   54,  0,   0,   6,   242, 32,  16,  0,   3,
+    0,   0,   0,   70,  142, 32,  0,   0,   0,   0,   0,   0,   0,   0,   0,   54,  0,   0,   6,
+    242, 32,  16,  0,   4,   0,   0,   0,   70,  142, 32,  0,   0,   0,   0,   0,   0,   0,   0,
+    0,   54,  0,   0,   5,   1,   192, 0,   0,   10,  128, 32,  0,   0,   0,   0,   0,   1,   0,
+    0,   0,   62,  0,   0,   1,   83,  84,  65,  84,  116, 0,   0,   0,   7,   0,   0,   0,   0,
+    0,   0,   0,   0,   0,   0,   0,   6,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+    0,   0,   0,   0,   1,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+    0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+    0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   6,   0,   0,   0,   0,
+    0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+    0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0};
--- a/gfx/angle/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/clearuint11ps6.h
+++ b/gfx/angle/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/clearuint11ps6.h
@@ -1,116 +1,116 @@
-#if 0
-//
-// Generated by Microsoft (R) HLSL Shader Compiler 6.3.9600.16384
-//
-//
-// Buffer Definitions: 
-//
-// cbuffer ColorAndDepthDataUint
-// {
-//
-//   uint4 color_Uint;                  // Offset:    0 Size:    16
-//   float zValueF_Uint;                // Offset:   16 Size:     4
-//
-// }
-//
-//
-// Resource Bindings:
-//
-// Name                                 Type  Format         Dim Slot Elements
-// ------------------------------ ---------- ------- ----------- ---- --------
-// ColorAndDepthDataUint             cbuffer      NA          NA    0        1
-//
-//
-//
-// Input signature:
-//
-// Name                 Index   Mask Register SysValue  Format   Used
-// -------------------- ----- ------ -------- -------- ------- ------
-// SV_POSITION              0   xyzw        0      POS   float       
-//
-//
-// Output signature:
-//
-// Name                 Index   Mask Register SysValue  Format   Used
-// -------------------- ----- ------ -------- -------- ------- ------
-// SV_TARGET                0   xyzw        0   TARGET    uint   xyzw
-// SV_TARGET                1   xyzw        1   TARGET    uint   xyzw
-// SV_TARGET                2   xyzw        2   TARGET    uint   xyzw
-// SV_TARGET                3   xyzw        3   TARGET    uint   xyzw
-// SV_TARGET                4   xyzw        4   TARGET    uint   xyzw
-// SV_TARGET                5   xyzw        5   TARGET    uint   xyzw
-// SV_DEPTH                 0    N/A   oDepth    DEPTH   float    YES
-//
-ps_4_0
-dcl_constantbuffer cb0[2], immediateIndexed
-dcl_output o0.xyzw
-dcl_output o1.xyzw
-dcl_output o2.xyzw
-dcl_output o3.xyzw
-dcl_output o4.xyzw
-dcl_output o5.xyzw
-dcl_output oDepth
-mov o0.xyzw, cb0[0].xyzw
-mov o1.xyzw, cb0[0].xyzw
-mov o2.xyzw, cb0[0].xyzw
-mov o3.xyzw, cb0[0].xyzw
-mov o4.xyzw, cb0[0].xyzw
-mov o5.xyzw, cb0[0].xyzw
-mov oDepth, cb0[1].x
-ret 
-// Approximately 8 instruction slots used
-#endif
-
-const BYTE g_PS_ClearUint6[] = {
-    68,  88,  66,  67,  92,  35,  11,  26,  168, 95,  96,  195, 79,  231, 8,   0,   53,  204, 222,
-    121, 1,   0,   0,   0,   220, 3,   0,   0,   5,   0,   0,   0,   52,  0,   0,   0,   72,  1,
-    0,   0,   124, 1,   0,   0,   72,  2,   0,   0,   96,  3,   0,   0,   82,  68,  69,  70,  12,
-    1,   0,   0,   1,   0,   0,   0,   84,  0,   0,   0,   1,   0,   0,   0,   28,  0,   0,   0,
-    0,   4,   255, 255, 0,   1,   0,   0,   216, 0,   0,   0,   60,  0,   0,   0,   0,   0,   0,
-    0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   1,   0,
-    0,   0,   1,   0,   0,   0,   67,  111, 108, 111, 114, 65,  110, 100, 68,  101, 112, 116, 104,
-    68,  97,  116, 97,  85,  105, 110, 116, 0,   171, 171, 60,  0,   0,   0,   2,   0,   0,   0,
-    108, 0,   0,   0,   32,  0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   156, 0,   0,
-    0,   0,   0,   0,   0,   16,  0,   0,   0,   2,   0,   0,   0,   168, 0,   0,   0,   0,   0,
-    0,   0,   184, 0,   0,   0,   16,  0,   0,   0,   4,   0,   0,   0,   2,   0,   0,   0,   200,
-    0,   0,   0,   0,   0,   0,   0,   99,  111, 108, 111, 114, 95,  85,  105, 110, 116, 0,   171,
-    1,   0,   19,  0,   1,   0,   4,   0,   0,   0,   0,   0,   0,   0,   0,   0,   122, 86,  97,
-    108, 117, 101, 70,  95,  85,  105, 110, 116, 0,   171, 171, 171, 0,   0,   3,   0,   1,   0,
-    1,   0,   0,   0,   0,   0,   0,   0,   0,   0,   77,  105, 99,  114, 111, 115, 111, 102, 116,
-    32,  40,  82,  41,  32,  72,  76,  83,  76,  32,  83,  104, 97,  100, 101, 114, 32,  67,  111,
-    109, 112, 105, 108, 101, 114, 32,  54,  46,  51,  46,  57,  54,  48,  48,  46,  49,  54,  51,
-    56,  52,  0,   171, 171, 73,  83,  71,  78,  44,  0,   0,   0,   1,   0,   0,   0,   8,   0,
-    0,   0,   32,  0,   0,   0,   0,   0,   0,   0,   1,   0,   0,   0,   3,   0,   0,   0,   0,
-    0,   0,   0,   15,  0,   0,   0,   83,  86,  95,  80,  79,  83,  73,  84,  73,  79,  78,  0,
-    79,  83,  71,  78,  196, 0,   0,   0,   7,   0,   0,   0,   8,   0,   0,   0,   176, 0,   0,
-    0,   0,   0,   0,   0,   0,   0,   0,   0,   1,   0,   0,   0,   0,   0,   0,   0,   15,  0,
-    0,   0,   176, 0,   0,   0,   1,   0,   0,   0,   0,   0,   0,   0,   1,   0,   0,   0,   1,
-    0,   0,   0,   15,  0,   0,   0,   176, 0,   0,   0,   2,   0,   0,   0,   0,   0,   0,   0,
-    1,   0,   0,   0,   2,   0,   0,   0,   15,  0,   0,   0,   176, 0,   0,   0,   3,   0,   0,
-    0,   0,   0,   0,   0,   1,   0,   0,   0,   3,   0,   0,   0,   15,  0,   0,   0,   176, 0,
-    0,   0,   4,   0,   0,   0,   0,   0,   0,   0,   1,   0,   0,   0,   4,   0,   0,   0,   15,
-    0,   0,   0,   176, 0,   0,   0,   5,   0,   0,   0,   0,   0,   0,   0,   1,   0,   0,   0,
-    5,   0,   0,   0,   15,  0,   0,   0,   186, 0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
-    0,   3,   0,   0,   0,   255, 255, 255, 255, 1,   14,  0,   0,   83,  86,  95,  84,  65,  82,
-    71,  69,  84,  0,   83,  86,  95,  68,  69,  80,  84,  72,  0,   171, 83,  72,  68,  82,  16,
-    1,   0,   0,   64,  0,   0,   0,   68,  0,   0,   0,   89,  0,   0,   4,   70,  142, 32,  0,
-    0,   0,   0,   0,   2,   0,   0,   0,   101, 0,   0,   3,   242, 32,  16,  0,   0,   0,   0,
-    0,   101, 0,   0,   3,   242, 32,  16,  0,   1,   0,   0,   0,   101, 0,   0,   3,   242, 32,
-    16,  0,   2,   0,   0,   0,   101, 0,   0,   3,   242, 32,  16,  0,   3,   0,   0,   0,   101,
-    0,   0,   3,   242, 32,  16,  0,   4,   0,   0,   0,   101, 0,   0,   3,   242, 32,  16,  0,
-    5,   0,   0,   0,   101, 0,   0,   2,   1,   192, 0,   0,   54,  0,   0,   6,   242, 32,  16,
-    0,   0,   0,   0,   0,   70,  142, 32,  0,   0,   0,   0,   0,   0,   0,   0,   0,   54,  0,
-    0,   6,   242, 32,  16,  0,   1,   0,   0,   0,   70,  142, 32,  0,   0,   0,   0,   0,   0,
-    0,   0,   0,   54,  0,   0,   6,   242, 32,  16,  0,   2,   0,   0,   0,   70,  142, 32,  0,
-    0,   0,   0,   0,   0,   0,   0,   0,   54,  0,   0,   6,   242, 32,  16,  0,   3,   0,   0,
-    0,   70,  142, 32,  0,   0,   0,   0,   0,   0,   0,   0,   0,   54,  0,   0,   6,   242, 32,
-    16,  0,   4,   0,   0,   0,   70,  142, 32,  0,   0,   0,   0,   0,   0,   0,   0,   0,   54,
-    0,   0,   6,   242, 32,  16,  0,   5,   0,   0,   0,   70,  142, 32,  0,   0,   0,   0,   0,
-    0,   0,   0,   0,   54,  0,   0,   5,   1,   192, 0,   0,   10,  128, 32,  0,   0,   0,   0,
-    0,   1,   0,   0,   0,   62,  0,   0,   1,   83,  84,  65,  84,  116, 0,   0,   0,   8,   0,
-    0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   7,   0,   0,   0,   0,   0,   0,   0,   0,
-    0,   0,   0,   0,   0,   0,   0,   1,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
-    0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
-    0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   7,   0,
-    0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
-    0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0};
+#if 0
+//
+// Generated by Microsoft (R) HLSL Shader Compiler 6.3.9600.16384
+//
+//
+// Buffer Definitions: 
+//
+// cbuffer ColorAndDepthDataUint
+// {
+//
+//   uint4 color_Uint;                  // Offset:    0 Size:    16
+//   float zValueF_Uint;                // Offset:   16 Size:     4
+//
+// }
+//
+//
+// Resource Bindings:
+//
+// Name                                 Type  Format         Dim Slot Elements
+// ------------------------------ ---------- ------- ----------- ---- --------
+// ColorAndDepthDataUint             cbuffer      NA          NA    0        1
+//
+//
+//
+// Input signature:
+//
+// Name                 Index   Mask Register SysValue  Format   Used
+// -------------------- ----- ------ -------- -------- ------- ------
+// SV_POSITION              0   xyzw        0      POS   float       
+//
+//
+// Output signature:
+//
+// Name                 Index   Mask Register SysValue  Format   Used
+// -------------------- ----- ------ -------- -------- ------- ------
+// SV_TARGET                0   xyzw        0   TARGET    uint   xyzw
+// SV_TARGET                1   xyzw        1   TARGET    uint   xyzw
+// SV_TARGET                2   xyzw        2   TARGET    uint   xyzw
+// SV_TARGET                3   xyzw        3   TARGET    uint   xyzw
+// SV_TARGET                4   xyzw        4   TARGET    uint   xyzw
+// SV_TARGET                5   xyzw        5   TARGET    uint   xyzw
+// SV_DEPTH                 0    N/A   oDepth    DEPTH   float    YES
+//
+ps_4_0
+dcl_constantbuffer cb0[2], immediateIndexed
+dcl_output o0.xyzw
+dcl_output o1.xyzw
+dcl_output o2.xyzw
+dcl_output o3.xyzw
+dcl_output o4.xyzw
+dcl_output o5.xyzw
+dcl_output oDepth
+mov o0.xyzw, cb0[0].xyzw
+mov o1.xyzw, cb0[0].xyzw
+mov o2.xyzw, cb0[0].xyzw
+mov o3.xyzw, cb0[0].xyzw
+mov o4.xyzw, cb0[0].xyzw
+mov o5.xyzw, cb0[0].xyzw
+mov oDepth, cb0[1].x
+ret 
+// Approximately 8 instruction slots used
+#endif
+
+const BYTE g_PS_ClearUint6[] = {
+    68,  88,  66,  67,  92,  35,  11,  26,  168, 95,  96,  195, 79,  231, 8,   0,   53,  204, 222,
+    121, 1,   0,   0,   0,   220, 3,   0,   0,   5,   0,   0,   0,   52,  0,   0,   0,   72,  1,
+    0,   0,   124, 1,   0,   0,   72,  2,   0,   0,   96,  3,   0,   0,   82,  68,  69,  70,  12,
+    1,   0,   0,   1,   0,   0,   0,   84,  0,   0,   0,   1,   0,   0,   0,   28,  0,   0,   0,
+    0,   4,   255, 255, 0,   1,   0,   0,   216, 0,   0,   0,   60,  0,   0,   0,   0,   0,   0,
+    0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   1,   0,
+    0,   0,   1,   0,   0,   0,   67,  111, 108, 111, 114, 65,  110, 100, 68,  101, 112, 116, 104,
+    68,  97,  116, 97,  85,  105, 110, 116, 0,   171, 171, 60,  0,   0,   0,   2,   0,   0,   0,
+    108, 0,   0,   0,   32,  0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   156, 0,   0,
+    0,   0,   0,   0,   0,   16,  0,   0,   0,   2,   0,   0,   0,   168, 0,   0,   0,   0,   0,
+    0,   0,   184, 0,   0,   0,   16,  0,   0,   0,   4,   0,   0,   0,   2,   0,   0,   0,   200,
+    0,   0,   0,   0,   0,   0,   0,   99,  111, 108, 111, 114, 95,  85,  105, 110, 116, 0,   171,
+    1,   0,   19,  0,   1,   0,   4,   0,   0,   0,   0,   0,   0,   0,   0,   0,   122, 86,  97,
+    108, 117, 101, 70,  95,  85,  105, 110, 116, 0,   171, 171, 171, 0,   0,   3,   0,   1,   0,
+    1,   0,   0,   0,   0,   0,   0,   0,   0,   0,   77,  105, 99,  114, 111, 115, 111, 102, 116,
+    32,  40,  82,  41,  32,  72,  76,  83,  76,  32,  83,  104, 97,  100, 101, 114, 32,  67,  111,
+    109, 112, 105, 108, 101, 114, 32,  54,  46,  51,  46,  57,  54,  48,  48,  46,  49,  54,  51,
+    56,  52,  0,   171, 171, 73,  83,  71,  78,  44,  0,   0,   0,   1,   0,   0,   0,   8,   0,
+    0,   0,   32,  0,   0,   0,   0,   0,   0,   0,   1,   0,   0,   0,   3,   0,   0,   0,   0,
+    0,   0,   0,   15,  0,   0,   0,   83,  86,  95,  80,  79,  83,  73,  84,  73,  79,  78,  0,
+    79,  83,  71,  78,  196, 0,   0,   0,   7,   0,   0,   0,   8,   0,   0,   0,   176, 0,   0,
+    0,   0,   0,   0,   0,   0,   0,   0,   0,   1,   0,   0,   0,   0,   0,   0,   0,   15,  0,
+    0,   0,   176, 0,   0,   0,   1,   0,   0,   0,   0,   0,   0,   0,   1,   0,   0,   0,   1,
+    0,   0,   0,   15,  0,   0,   0,   176, 0,   0,   0,   2,   0,   0,   0,   0,   0,   0,   0,
+    1,   0,   0,   0,   2,   0,   0,   0,   15,  0,   0,   0,   176, 0,   0,   0,   3,   0,   0,
+    0,   0,   0,   0,   0,   1,   0,   0,   0,   3,   0,   0,   0,   15,  0,   0,   0,   176, 0,
+    0,   0,   4,   0,   0,   0,   0,   0,   0,   0,   1,   0,   0,   0,   4,   0,   0,   0,   15,
+    0,   0,   0,   176, 0,   0,   0,   5,   0,   0,   0,   0,   0,   0,   0,   1,   0,   0,   0,
+    5,   0,   0,   0,   15,  0,   0,   0,   186, 0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+    0,   3,   0,   0,   0,   255, 255, 255, 255, 1,   14,  0,   0,   83,  86,  95,  84,  65,  82,
+    71,  69,  84,  0,   83,  86,  95,  68,  69,  80,  84,  72,  0,   171, 83,  72,  68,  82,  16,
+    1,   0,   0,   64,  0,   0,   0,   68,  0,   0,   0,   89,  0,   0,   4,   70,  142, 32,  0,
+    0,   0,   0,   0,   2,   0,   0,   0,   101, 0,   0,   3,   242, 32,  16,  0,   0,   0,   0,
+    0,   101, 0,   0,   3,   242, 32,  16,  0,   1,   0,   0,   0,   101, 0,   0,   3,   242, 32,
+    16,  0,   2,   0,   0,   0,   101, 0,   0,   3,   242, 32,  16,  0,   3,   0,   0,   0,   101,
+    0,   0,   3,   242, 32,  16,  0,   4,   0,   0,   0,   101, 0,   0,   3,   242, 32,  16,  0,
+    5,   0,   0,   0,   101, 0,   0,   2,   1,   192, 0,   0,   54,  0,   0,   6,   242, 32,  16,
+    0,   0,   0,   0,   0,   70,  142, 32,  0,   0,   0,   0,   0,   0,   0,   0,   0,   54,  0,
+    0,   6,   242, 32,  16,  0,   1,   0,   0,   0,   70,  142, 32,  0,   0,   0,   0,   0,   0,
+    0,   0,   0,   54,  0,   0,   6,   242, 32,  16,  0,   2,   0,   0,   0,   70,  142, 32,  0,
+    0,   0,   0,   0,   0,   0,   0,   0,   54,  0,   0,   6,   242, 32,  16,  0,   3,   0,   0,
+    0,   70,  142, 32,  0,   0,   0,   0,   0,   0,   0,   0,   0,   54,  0,   0,   6,   242, 32,
+    16,  0,   4,   0,   0,   0,   70,  142, 32,  0,   0,   0,   0,   0,   0,   0,   0,   0,   54,
+    0,   0,   6,   242, 32,  16,  0,   5,   0,   0,   0,   70,  142, 32,  0,   0,   0,   0,   0,
+    0,   0,   0,   0,   54,  0,   0,   5,   1,   192, 0,   0,   10,  128, 32,  0,   0,   0,   0,
+    0,   1,   0,   0,   0,   62,  0,   0,   1,   83,  84,  65,  84,  116, 0,   0,   0,   8,   0,
+    0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   7,   0,   0,   0,   0,   0,   0,   0,   0,
+    0,   0,   0,   0,   0,   0,   0,   1,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+    0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+    0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   7,   0,
+    0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+    0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0};
--- a/gfx/angle/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/clearuint11ps7.h
+++ b/gfx/angle/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/clearuint11ps7.h
@@ -1,123 +1,123 @@
-#if 0
-//
-// Generated by Microsoft (R) HLSL Shader Compiler 6.3.9600.16384
-//
-//
-// Buffer Definitions: 
-//
-// cbuffer ColorAndDepthDataUint
-// {
-//
-//   uint4 color_Uint;                  // Offset:    0 Size:    16
-//   float zValueF_Uint;                // Offset:   16 Size:     4
-//
-// }
-//
-//
-// Resource Bindings:
-//
-// Name                                 Type  Format         Dim Slot Elements
-// ------------------------------ ---------- ------- ----------- ---- --------
-// ColorAndDepthDataUint             cbuffer      NA          NA    0        1
-//
-//
-//
-// Input signature:
-//
-// Name                 Index   Mask Register SysValue  Format   Used
-// -------------------- ----- ------ -------- -------- ------- ------
-// SV_POSITION              0   xyzw        0      POS   float       
-//
-//
-// Output signature:
-//
-// Name                 Index   Mask Register SysValue  Format   Used
-// -------------------- ----- ------ -------- -------- ------- ------
-// SV_TARGET                0   xyzw        0   TARGET    uint   xyzw
-// SV_TARGET                1   xyzw        1   TARGET    uint   xyzw
-// SV_TARGET                2   xyzw        2   TARGET    uint   xyzw
-// SV_TARGET                3   xyzw        3   TARGET    uint   xyzw
-// SV_TARGET                4   xyzw        4   TARGET    uint   xyzw
-// SV_TARGET                5   xyzw        5   TARGET    uint   xyzw
-// SV_TARGET                6   xyzw        6   TARGET    uint   xyzw
-// SV_DEPTH                 0    N/A   oDepth    DEPTH   float    YES
-//
-ps_4_0
-dcl_constantbuffer cb0[2], immediateIndexed
-dcl_output o0.xyzw
-dcl_output o1.xyzw
-dcl_output o2.xyzw
-dcl_output o3.xyzw
-dcl_output o4.xyzw
-dcl_output o5.xyzw
-dcl_output o6.xyzw
-dcl_output oDepth
-mov o0.xyzw, cb0[0].xyzw
-mov o1.xyzw, cb0[0].xyzw
-mov o2.xyzw, cb0[0].xyzw
-mov o3.xyzw, cb0[0].xyzw
-mov o4.xyzw, cb0[0].xyzw
-mov o5.xyzw, cb0[0].xyzw
-mov o6.xyzw, cb0[0].xyzw
-mov oDepth, cb0[1].x
-ret 
-// Approximately 9 instruction slots used
-#endif
-
-const BYTE g_PS_ClearUint7[] = {
-    68,  88,  66,  67,  222, 54,  153, 233, 23,  19,  230, 114, 59,  92,  55,  31,  123, 0,   252,
-    103, 1,   0,   0,   0,   24,  4,   0,   0,   5,   0,   0,   0,   52,  0,   0,   0,   72,  1,
-    0,   0,   124, 1,   0,   0,   96,  2,   0,   0,   156, 3,   0,   0,   82,  68,  69,  70,  12,
-    1,   0,   0,   1,   0,   0,   0,   84,  0,   0,   0,   1,   0,   0,   0,   28,  0,   0,   0,
-    0,   4,   255, 255, 0,   1,   0,   0,   216, 0,   0,   0,   60,  0,   0,   0,   0,   0,   0,
-    0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   1,   0,
-    0,   0,   1,   0,   0,   0,   67,  111, 108, 111, 114, 65,  110, 100, 68,  101, 112, 116, 104,
-    68,  97,  116, 97,  85,  105, 110, 116, 0,   171, 171, 60,  0,   0,   0,   2,   0,   0,   0,
-    108, 0,   0,   0,   32,  0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   156, 0,   0,
-    0,   0,   0,   0,   0,   16,  0,   0,   0,   2,   0,   0,   0,   168, 0,   0,   0,   0,   0,
-    0,   0,   184, 0,   0,   0,   16,  0,   0,   0,   4,   0,   0,   0,   2,   0,   0,   0,   200,
-    0,   0,   0,   0,   0,   0,   0,   99,  111, 108, 111, 114, 95,  85,  105, 110, 116, 0,   171,
-    1,   0,   19,  0,   1,   0,   4,   0,   0,   0,   0,   0,   0,   0,   0,   0,   122, 86,  97,
-    108, 117, 101, 70,  95,  85,  105, 110, 116, 0,   171, 171, 171, 0,   0,   3,   0,   1,   0,
-    1,   0,   0,   0,   0,   0,   0,   0,   0,   0,   77,  105, 99,  114, 111, 115, 111, 102, 116,
-    32,  40,  82,  41,  32,  72,  76,  83,  76,  32,  83,  104, 97,  100, 101, 114, 32,  67,  111,
-    109, 112, 105, 108, 101, 114, 32,  54,  46,  51,  46,  57,  54,  48,  48,  46,  49,  54,  51,
-    56,  52,  0,   171, 171, 73,  83,  71,  78,  44,  0,   0,   0,   1,   0,   0,   0,   8,   0,
-    0,   0,   32,  0,   0,   0,   0,   0,   0,   0,   1,   0,   0,   0,   3,   0,   0,   0,   0,
-    0,   0,   0,   15,  0,   0,   0,   83,  86,  95,  80,  79,  83,  73,  84,  73,  79,  78,  0,
-    79,  83,  71,  78,  220, 0,   0,   0,   8,   0,   0,   0,   8,   0,   0,   0,   200, 0,   0,
-    0,   0,   0,   0,   0,   0,   0,   0,   0,   1,   0,   0,   0,   0,   0,   0,   0,   15,  0,
-    0,   0,   200, 0,   0,   0,   1,   0,   0,   0,   0,   0,   0,   0,   1,   0,   0,   0,   1,
-    0,   0,   0,   15,  0,   0,   0,   200, 0,   0,   0,   2,   0,   0,   0,   0,   0,   0,   0,
-    1,   0,   0,   0,   2,   0,   0,   0,   15,  0,   0,   0,   200, 0,   0,   0,   3,   0,   0,
-    0,   0,   0,   0,   0,   1,   0,   0,   0,   3,   0,   0,   0,   15,  0,   0,   0,   200, 0,
-    0,   0,   4,   0,   0,   0,   0,   0,   0,   0,   1,   0,   0,   0,   4,   0,   0,   0,   15,
-    0,   0,   0,   200, 0,   0,   0,   5,   0,   0,   0,   0,   0,   0,   0,   1,   0,   0,   0,
-    5,   0,   0,   0,   15,  0,   0,   0,   200, 0,   0,   0,   6,   0,   0,   0,   0,   0,   0,
-    0,   1,   0,   0,   0,   6,   0,   0,   0,   15,  0,   0,   0,   210, 0,   0,   0,   0,   0,
-    0,   0,   0,   0,   0,   0,   3,   0,   0,   0,   255, 255, 255, 255, 1,   14,  0,   0,   83,
-    86,  95,  84,  65,  82,  71,  69,  84,  0,   83,  86,  95,  68,  69,  80,  84,  72,  0,   171,
-    83,  72,  68,  82,  52,  1,   0,   0,   64,  0,   0,   0,   77,  0,   0,   0,   89,  0,   0,
-    4,   70,  142, 32,  0,   0,   0,   0,   0,   2,   0,   0,   0,   101, 0,   0,   3,   242, 32,
-    16,  0,   0,   0,   0,   0,   101, 0,   0,   3,   242, 32,  16,  0,   1,   0,   0,   0,   101,
-    0,   0,   3,   242, 32,  16,  0,   2,   0,   0,   0,   101, 0,   0,   3,   242, 32,  16,  0,
-    3,   0,   0,   0,   101, 0,   0,   3,   242, 32,  16,  0,   4,   0,   0,   0,   101, 0,   0,
-    3,   242, 32,  16,  0,   5,   0,   0,   0,   101, 0,   0,   3,   242, 32,  16,  0,   6,   0,
-    0,   0,   101, 0,   0,   2,   1,   192, 0,   0,   54,  0,   0,   6,   242, 32,  16,  0,   0,
-    0,   0,   0,   70,  142, 32,  0,   0,   0,   0,   0,   0,   0,   0,   0,   54,  0,   0,   6,
-    242, 32,  16,  0,   1,   0,   0,   0,   70,  142, 32,  0,   0,   0,   0,   0,   0,   0,   0,
-    0,   54,  0,   0,   6,   242, 32,  16,  0,   2,   0,   0,   0,   70,  142, 32,  0,   0,   0,
-    0,   0,   0,   0,   0,   0,   54,  0,   0,   6,   242, 32,  16,  0,   3,   0,   0,   0,   70,
-    142, 32,  0,   0,   0,   0,   0,   0,   0,   0,   0,   54,  0,   0,   6,   242, 32,  16,  0,
-    4,   0,   0,   0,   70,  142, 32,  0,   0,   0,   0,   0,   0,   0,   0,   0,   54,  0,   0,
-    6,   242, 32,  16,  0,   5,   0,   0,   0,   70,  142, 32,  0,   0,   0,   0,   0,   0,   0,
-    0,   0,   54,  0,   0,   6,   242, 32,  16,  0,   6,   0,   0,   0,   70,  142, 32,  0,   0,
-    0,   0,   0,   0,   0,   0,   0,   54,  0,   0,   5,   1,   192, 0,   0,   10,  128, 32,  0,
-    0,   0,   0,   0,   1,   0,   0,   0,   62,  0,   0,   1,   83,  84,  65,  84,  116, 0,   0,
-    0,   9,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   8,   0,   0,   0,   0,   0,
-    0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   1,   0,   0,   0,   0,   0,   0,   0,   0,
-    0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
-    0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
-    0,   8,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
-    0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
-    0,   0,   0};
+#if 0
+//
+// Generated by Microsoft (R) HLSL Shader Compiler 6.3.9600.16384
+//
+//
+// Buffer Definitions: 
+//
+// cbuffer ColorAndDepthDataUint
+// {
+//
+//   uint4 color_Uint;                  // Offset:    0 Size:    16
+//   float zValueF_Uint;                // Offset:   16 Size:     4
+//
+// }
+//
+//
+// Resource Bindings:
+//
+// Name                                 Type  Format         Dim Slot Elements
+// ------------------------------ ---------- ------- ----------- ---- --------
+// ColorAndDepthDataUint             cbuffer      NA          NA    0        1
+//
+//
+//
+// Input signature:
+//
+// Name                 Index   Mask Register SysValue  Format   Used
+// -------------------- ----- ------ -------- -------- ------- ------
+// SV_POSITION              0   xyzw        0      POS   float       
+//
+//
+// Output signature:
+//
+// Name                 Index   Mask Register SysValue  Format   Used
+// -------------------- ----- ------ -------- -------- ------- ------
+// SV_TARGET                0   xyzw        0   TARGET    uint   xyzw
+// SV_TARGET                1   xyzw        1   TARGET    uint   xyzw
+// SV_TARGET                2   xyzw        2   TARGET    uint   xyzw
+// SV_TARGET                3   xyzw        3   TARGET    uint   xyzw
+// SV_TARGET                4   xyzw        4   TARGET    uint   xyzw
+// SV_TARGET                5   xyzw        5   TARGET    uint   xyzw
+// SV_TARGET                6   xyzw        6   TARGET    uint   xyzw
+// SV_DEPTH                 0    N/A   oDepth    DEPTH   float    YES
+//
+ps_4_0
+dcl_constantbuffer cb0[2], immediateIndexed
+dcl_output o0.xyzw
+dcl_output o1.xyzw
+dcl_output o2.xyzw
+dcl_output o3.xyzw
+dcl_output o4.xyzw
+dcl_output o5.xyzw
+dcl_output o6.xyzw
+dcl_output oDepth
+mov o0.xyzw, cb0[0].xyzw
+mov o1.xyzw, cb0[0].xyzw
+mov o2.xyzw, cb0[0].xyzw
+mov o3.xyzw, cb0[0].xyzw
+mov o4.xyzw, cb0[0].xyzw
+mov o5.xyzw, cb0[0].xyzw
+mov o6.xyzw, cb0[0].xyzw
+mov oDepth, cb0[1].x
+ret 
+// Approximately 9 instruction slots used
+#endif
+
+const BYTE g_PS_ClearUint7[] = {
+    68,  88,  66,  67,  222, 54,  153, 233, 23,  19,  230, 114, 59,  92,  55,  31,  123, 0,   252,
+    103, 1,   0,   0,   0,   24,  4,   0,   0,   5,   0,   0,   0,   52,  0,   0,   0,   72,  1,
+    0,   0,   124, 1,   0,   0,   96,  2,   0,   0,   156, 3,   0,   0,   82,  68,  69,  70,  12,
+    1,   0,   0,   1,   0,   0,   0,   84,  0,   0,   0,   1,   0,   0,   0,   28,  0,   0,   0,
+    0,   4,   255, 255, 0,   1,   0,   0,   216, 0,   0,   0,   60,  0,   0,   0,   0,   0,   0,
+    0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   1,   0,
+    0,   0,   1,   0,   0,   0,   67,  111, 108, 111, 114, 65,  110, 100, 68,  101, 112, 116, 104,
+    68,  97,  116, 97,  85,  105, 110, 116, 0,   171, 171, 60,  0,   0,   0,   2,   0,   0,   0,
+    108, 0,   0,   0,   32,  0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   156, 0,   0,
+    0,   0,   0,   0,   0,   16,  0,   0,   0,   2,   0,   0,   0,   168, 0,   0,   0,   0,   0,
+    0,   0,   184, 0,   0,   0,   16,  0,   0,   0,   4,   0,   0,   0,   2,   0,   0,   0,   200,
+    0,   0,   0,   0,   0,   0,   0,   99,  111, 108, 111, 114, 95,  85,  105, 110, 116, 0,   171,
+    1,   0,   19,  0,   1,   0,   4,   0,   0,   0,   0,   0,   0,   0,   0,   0,   122, 86,  97,
+    108, 117, 101, 70,  95,  85,  105, 110, 116, 0,   171, 171, 171, 0,   0,   3,   0,   1,   0,
+    1,   0,   0,   0,   0,   0,   0,   0,   0,   0,   77,  105, 99,  114, 111, 115, 111, 102, 116,
+    32,  40,  82,  41,  32,  72,  76,  83,  76,  32,  83,  104, 97,  100, 101, 114, 32,  67,  111,
+    109, 112, 105, 108, 101, 114, 32,  54,  46,  51,  46,  57,  54,  48,  48,  46,  49,  54,  51,
+    56,  52,  0,   171, 171, 73,  83,  71,  78,  44,  0,   0,   0,   1,   0,   0,   0,   8,   0,
+    0,   0,   32,  0,   0,   0,   0,   0,   0,   0,   1,   0,   0,   0,   3,   0,   0,   0,   0,
+    0,   0,   0,   15,  0,   0,   0,   83,  86,  95,  80,  79,  83,  73,  84,  73,  79,  78,  0,
+    79,  83,  71,  78,  220, 0,   0,   0,   8,   0,   0,   0,   8,   0,   0,   0,   200, 0,   0,
+    0,   0,   0,   0,   0,   0,   0,   0,   0,   1,   0,   0,   0,   0,   0,   0,   0,   15,  0,
+    0,   0,   200, 0,   0,   0,   1,   0,   0,   0,   0,   0,   0,   0,   1,   0,   0,   0,   1,
+    0,   0,   0,   15,  0,   0,   0,   200, 0,   0,   0,   2,   0,   0,   0,   0,   0,   0,   0,
+    1,   0,   0,   0,   2,   0,   0,   0,   15,  0,   0,   0,   200, 0,   0,   0,   3,   0,   0,
+    0,   0,   0,   0,   0,   1,   0,   0,   0,   3,   0,   0,   0,   15,  0,   0,   0,   200, 0,
+    0,   0,   4,   0,   0,   0,   0,   0,   0,   0,   1,   0,   0,   0,   4,   0,   0,   0,   15,
+    0,   0,   0,   200, 0,   0,   0,   5,   0,   0,   0,   0,   0,   0,   0,   1,   0,   0,   0,
+    5,   0,   0,   0,   15,  0,   0,   0,   200, 0,   0,   0,   6,   0,   0,   0,   0,   0,   0,
+    0,   1,   0,   0,   0,   6,   0,   0,   0,   15,  0,   0,   0,   210, 0,   0,   0,   0,   0,
+    0,   0,   0,   0,   0,   0,   3,   0,   0,   0,   255, 255, 255, 255, 1,   14,  0,   0,   83,
+    86,  95,  84,  65,  82,  71,  69,  84,  0,   83,  86,  95,  68,  69,  80,  84,  72,  0,   171,
+    83,  72,  68,  82,  52,  1,   0,   0,   64,  0,   0,   0,   77,  0,   0,   0,   89,  0,   0,
+    4,   70,  142, 32,  0,   0,   0,   0,   0,   2,   0,   0,   0,   101, 0,   0,   3,   242, 32,
+    16,  0,   0,   0,   0,   0,   101, 0,   0,   3,   242, 32,  16,  0,   1,   0,   0,   0,   101,
+    0,   0,   3,   242, 32,  16,  0,   2,   0,   0,   0,   101, 0,   0,   3,   242, 32,  16,  0,
+    3,   0,   0,   0,   101, 0,   0,   3,   242, 32,  16,  0,   4,   0,   0,   0,   101, 0,   0,
+    3,   242, 32,  16,  0,   5,   0,   0,   0,   101, 0,   0,   3,   242, 32,  16,  0,   6,   0,
+    0,   0,   101, 0,   0,   2,   1,   192, 0,   0,   54,  0,   0,   6,   242, 32,  16,  0,   0,
+    0,   0,   0,   70,  142, 32,  0,   0,   0,   0,   0,   0,   0,   0,   0,   54,  0,   0,   6,
+    242, 32,  16,  0,   1,   0,   0,   0,   70,  142, 32,  0,   0,   0,   0,   0,   0,   0,   0,
+    0,   54,  0,   0,   6,   242, 32,  16,  0,   2,   0,   0,   0,   70,  142, 32,  0,   0,   0,
+    0,   0,   0,   0,   0,   0,   54,  0,   0,   6,   242, 32,  16,  0,   3,   0,   0,   0,   70,
+    142, 32,  0,   0,   0,   0,   0,   0,   0,   0,   0,   54,  0,   0,   6,   242, 32,  16,  0,
+    4,   0,   0,   0,   70,  142, 32,  0,   0,   0,   0,   0,   0,   0,   0,   0,   54,  0,   0,
+    6,   242, 32,  16,  0,   5,   0,   0,   0,   70,  142, 32,  0,   0,   0,   0,   0,   0,   0,
+    0,   0,   54,  0,   0,   6,   242, 32,  16,  0,   6,   0,   0,   0,   70,  142, 32,  0,   0,
+    0,   0,   0,   0,   0,   0,   0,   54,  0,   0,   5,   1,   192, 0,   0,   10,  128, 32,  0,
+    0,   0,   0,   0,   1,   0,   0,   0,   62,  0,   0,   1,   83,  84,  65,  84,  116, 0,   0,
+    0,   9,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   8,   0,   0,   0,   0,   0,
+    0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   1,   0,   0,   0,   0,   0,   0,   0,   0,
+    0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+    0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+    0,   8,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+    0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+    0,   0,   0};
--- a/gfx/angle/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/clearuint11ps8.h
+++ b/gfx/angle/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/clearuint11ps8.h
@@ -1,129 +1,129 @@
-#if 0
-//
-// Generated by Microsoft (R) HLSL Shader Compiler 6.3.9600.16384
-//
-//
-// Buffer Definitions: 
-//
-// cbuffer ColorAndDepthDataUint
-// {
-//
-//   uint4 color_Uint;                  // Offset:    0 Size:    16
-//   float zValueF_Uint;                // Offset:   16 Size:     4
-//
-// }
-//
-//
-// Resource Bindings:
-//
-// Name                                 Type  Format         Dim Slot Elements
-// ------------------------------ ---------- ------- ----------- ---- --------
-// ColorAndDepthDataUint             cbuffer      NA          NA    0        1
-//
-//
-//
-// Input signature:
-//
-// Name                 Index   Mask Register SysValue  Format   Used
-// -------------------- ----- ------ -------- -------- ------- ------
-// SV_POSITION              0   xyzw        0      POS   float       
-//
-//
-// Output signature:
-//
-// Name                 Index   Mask Register SysValue  Format   Used
-// -------------------- ----- ------ -------- -------- ------- ------
-// SV_TARGET                0   xyzw        0   TARGET    uint   xyzw
-// SV_TARGET                1   xyzw        1   TARGET    uint   xyzw
-// SV_TARGET                2   xyzw        2   TARGET    uint   xyzw
-// SV_TARGET                3   xyzw        3   TARGET    uint   xyzw
-// SV_TARGET                4   xyzw        4   TARGET    uint   xyzw
-// SV_TARGET                5   xyzw        5   TARGET    uint   xyzw
-// SV_TARGET                6   xyzw        6   TARGET    uint   xyzw
-// SV_TARGET                7   xyzw        7   TARGET    uint   xyzw
-// SV_DEPTH                 0    N/A   oDepth    DEPTH   float    YES
-//
-ps_4_0
-dcl_constantbuffer cb0[2], immediateIndexed
-dcl_output o0.xyzw
-dcl_output o1.xyzw
-dcl_output o2.xyzw
-dcl_output o3.xyzw
-dcl_output o4.xyzw
-dcl_output o5.xyzw
-dcl_output o6.xyzw
-dcl_output o7.xyzw
-dcl_output oDepth
-mov o0.xyzw, cb0[0].xyzw
-mov o1.xyzw, cb0[0].xyzw
-mov o2.xyzw, cb0[0].xyzw
-mov o3.xyzw, cb0[0].xyzw
-mov o4.xyzw, cb0[0].xyzw
-mov o5.xyzw, cb0[0].xyzw
-mov o6.xyzw, cb0[0].xyzw
-mov o7.xyzw, cb0[0].xyzw
-mov oDepth, cb0[1].x
-ret 
-// Approximately 10 instruction slots used
-#endif
-
-const BYTE g_PS_ClearUint8[] = {
-    68,  88,  66,  67,  31,  50,  232, 254, 182, 197, 174, 161, 39,  175, 44,  65,  71,  251, 37,
-    230, 1,   0,   0,   0,   84,  4,   0,   0,   5,   0,   0,   0,   52,  0,   0,   0,   72,  1,
-    0,   0,   124, 1,   0,   0,   120, 2,   0,   0,   216, 3,   0,   0,   82,  68,  69,  70,  12,
-    1,   0,   0,   1,   0,   0,   0,   84,  0,   0,   0,   1,   0,   0,   0,   28,  0,   0,   0,
-    0,   4,   255, 255, 0,   1,   0,   0,   216, 0,   0,   0,   60,  0,   0,   0,   0,   0,   0,
-    0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   1,   0,
-    0,   0,   1,   0,   0,   0,   67,  111, 108, 111, 114, 65,  110, 100, 68,  101, 112, 116, 104,
-    68,  97,  116, 97,  85,  105, 110, 116, 0,   171, 171, 60,  0,   0,   0,   2,   0,   0,   0,
-    108, 0,   0,   0,   32,  0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   156, 0,   0,
-    0,   0,   0,   0,   0,   16,  0,   0,   0,   2,   0,   0,   0,   168, 0,   0,   0,   0,   0,
-    0,   0,   184, 0,   0,   0,   16,  0,   0,   0,   4,   0,   0,   0,   2,   0,   0,   0,   200,
-    0,   0,   0,   0,   0,   0,   0,   99,  111, 108, 111, 114, 95,  85,  105, 110, 116, 0,   171,
-    1,   0,   19,  0,   1,   0,   4,   0,   0,   0,   0,   0,   0,   0,   0,   0,   122, 86,  97,
-    108, 117, 101, 70,  95,  85,  105, 110, 116, 0,   171, 171, 171, 0,   0,   3,   0,   1,   0,
-    1,   0,   0,   0,   0,   0,   0,   0,   0,   0,   77,  105, 99,  114, 111, 115, 111, 102, 116,
-    32,  40,  82,  41,  32,  72,  76,  83,  76,  32,  83,  104, 97,  100, 101, 114, 32,  67,  111,
-    109, 112, 105, 108, 101, 114, 32,  54,  46,  51,  46,  57,  54,  48,  48,  46,  49,  54,  51,
-    56,  52,  0,   171, 171, 73,  83,  71,  78,  44,  0,   0,   0,   1,   0,   0,   0,   8,   0,
-    0,   0,   32,  0,   0,   0,   0,   0,   0,   0,   1,   0,   0,   0,   3,   0,   0,   0,   0,
-    0,   0,   0,   15,  0,   0,   0,   83,  86,  95,  80,  79,  83,  73,  84,  73,  79,  78,  0,
-    79,  83,  71,  78,  244, 0,   0,   0,   9,   0,   0,   0,   8,   0,   0,   0,   224, 0,   0,
-    0,   0,   0,   0,   0,   0,   0,   0,   0,   1,   0,   0,   0,   0,   0,   0,   0,   15,  0,
-    0,   0,   224, 0,   0,   0,   1,   0,   0,   0,   0,   0,   0,   0,   1,   0,   0,   0,   1,
-    0,   0,   0,   15,  0,   0,   0,   224, 0,   0,   0,   2,   0,   0,   0,   0,   0,   0,   0,
-    1,   0,   0,   0,   2,   0,   0,   0,   15,  0,   0,   0,   224, 0,   0,   0,   3,   0,   0,
-    0,   0,   0,   0,   0,   1,   0,   0,   0,   3,   0,   0,   0,   15,  0,   0,   0,   224, 0,
-    0,   0,   4,   0,   0,   0,   0,   0,   0,   0,   1,   0,   0,   0,   4,   0,   0,   0,   15,
-    0,   0,   0,   224, 0,   0,   0,   5,   0,   0,   0,   0,   0,   0,   0,   1,   0,   0,   0,
-    5,   0,   0,   0,   15,  0,   0,   0,   224, 0,   0,   0,   6,   0,   0,   0,   0,   0,   0,
-    0,   1,   0,   0,   0,   6,   0,   0,   0,   15,  0,   0,   0,   224, 0,   0,   0,   7,   0,
-    0,   0,   0,   0,   0,   0,   1,   0,   0,   0,   7,   0,   0,   0,   15,  0,   0,   0,   234,
-    0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   3,   0,   0,   0,   255, 255, 255, 255,
-    1,   14,  0,   0,   83,  86,  95,  84,  65,  82,  71,  69,  84,  0,   83,  86,  95,  68,  69,
-    80,  84,  72,  0,   171, 83,  72,  68,  82,  88,  1,   0,   0,   64,  0,   0,   0,   86,  0,
-    0,   0,   89,  0,   0,   4,   70,  142, 32,  0,   0,   0,   0,   0,   2,   0,   0,   0,   101,
-    0,   0,   3,   242, 32,  16,  0,   0,   0,   0,   0,   101, 0,   0,   3,   242, 32,  16,  0,
-    1,   0,   0,   0,   101, 0,   0,   3,   242, 32,  16,  0,   2,   0,   0,   0,   101, 0,   0,
-    3,   242, 32,  16,  0,   3,   0,   0,   0,   101, 0,   0,   3,   242, 32,  16,  0,   4,   0,
-    0,   0,   101, 0,   0,   3,   242, 32,  16,  0,   5,   0,   0,   0,   101, 0,   0,   3,   242,
-    32,  16,  0,   6,   0,   0,   0,   101, 0,   0,   3,   242, 32,  16,  0,   7,   0,   0,   0,
-    101, 0,   0,   2,   1,   192, 0,   0,   54,  0,   0,   6,   242, 32,  16,  0,   0,   0,   0,
-    0,   70,  142, 32,  0,   0,   0,   0,   0,   0,   0,   0,   0,   54,  0,   0,   6,   242, 32,
-    16,  0,   1,   0,   0,   0,   70,  142, 32,  0,   0,   0,   0,   0,   0,   0,   0,   0,   54,
-    0,   0,   6,   242, 32,  16,  0,   2,   0,   0,   0,   70,  142, 32,  0,   0,   0,   0,   0,
-    0,   0,   0,   0,   54,  0,   0,   6,   242, 32,  16,  0,   3,   0,   0,   0,   70,  142, 32,
-    0,   0,   0,   0,   0,   0,   0,   0,   0,   54,  0,   0,   6,   242, 32,  16,  0,   4,   0,
-    0,   0,   70,  142, 32,  0,   0,   0,   0,   0,   0,   0,   0,   0,   54,  0,   0,   6,   242,
-    32,  16,  0,   5,   0,   0,   0,   70,  142, 32,  0,   0,   0,   0,   0,   0,   0,   0,   0,
-    54,  0,   0,   6,   242, 32,  16,  0,   6,   0,   0,   0,   70,  142, 32,  0,   0,   0,   0,
-    0,   0,   0,   0,   0,   54,  0,   0,   6,   242, 32,  16,  0,   7,   0,   0,   0,   70,  142,
-    32,  0,   0,   0,   0,   0,   0,   0,   0,   0,   54,  0,   0,   5,   1,   192, 0,   0,   10,
-    128, 32,  0,   0,   0,   0,   0,   1,   0,   0,   0,   62,  0,   0,   1,   83,  84,  65,  84,
-    116, 0,   0,   0,   10,  0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   9,   0,   0,
-    0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   1,   0,   0,   0,   0,   0,
-    0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
-    0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
-    0,   0,   0,   0,   9,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
-    0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
-    0,   0,   0,   0,   0,   0};
+#if 0
+//
+// Generated by Microsoft (R) HLSL Shader Compiler 6.3.9600.16384
+//
+//
+// Buffer Definitions: 
+//
+// cbuffer ColorAndDepthDataUint
+// {
+//
+//   uint4 color_Uint;                  // Offset:    0 Size:    16
+//   float zValueF_Uint;                // Offset:   16 Size:     4
+//
+// }
+//
+//
+// Resource Bindings:
+//
+// Name                                 Type  Format         Dim Slot Elements
+// ------------------------------ ---------- ------- ----------- ---- --------
+// ColorAndDepthDataUint             cbuffer      NA          NA    0        1
+//
+//
+//
+// Input signature:
+//
+// Name                 Index   Mask Register SysValue  Format   Used
+// -------------------- ----- ------ -------- -------- ------- ------
+// SV_POSITION              0   xyzw        0      POS   float       
+//
+//
+// Output signature:
+//
+// Name                 Index   Mask Register SysValue  Format   Used
+// -------------------- ----- ------ -------- -------- ------- ------
+// SV_TARGET                0   xyzw        0   TARGET    uint   xyzw
+// SV_TARGET                1   xyzw        1   TARGET    uint   xyzw
+// SV_TARGET                2   xyzw        2   TARGET    uint   xyzw
+// SV_TARGET                3   xyzw        3   TARGET    uint   xyzw
+// SV_TARGET                4   xyzw        4   TARGET    uint   xyzw
+// SV_TARGET                5   xyzw        5   TARGET    uint   xyzw
+// SV_TARGET                6   xyzw        6   TARGET    uint   xyzw
+// SV_TARGET                7   xyzw        7   TARGET    uint   xyzw
+// SV_DEPTH                 0    N/A   oDepth    DEPTH   float    YES
+//
+ps_4_0
+dcl_constantbuffer cb0[2], immediateIndexed
+dcl_output o0.xyzw
+dcl_output o1.xyzw
+dcl_output o2.xyzw
+dcl_output o3.xyzw
+dcl_output o4.xyzw
+dcl_output o5.xyzw
+dcl_output o6.xyzw
+dcl_output o7.xyzw
+dcl_output oDepth
+mov o0.xyzw, cb0[0].xyzw
+mov o1.xyzw, cb0[0].xyzw
+mov o2.xyzw, cb0[0].xyzw
+mov o3.xyzw, cb0[0].xyzw
+mov o4.xyzw, cb0[0].xyzw
+mov o5.xyzw, cb0[0].xyzw
+mov o6.xyzw, cb0[0].xyzw
+mov o7.xyzw, cb0[0].xyzw
+mov oDepth, cb0[1].x
+ret 
+// Approximately 10 instruction slots used
+#endif
+
+const BYTE g_PS_ClearUint8[] = {
+    68,  88,  66,  67,  31,  50,  232, 254, 182, 197, 174, 161, 39,  175, 44,  65,  71,  251, 37,
+    230, 1,   0,   0,   0,   84,  4,   0,   0,   5,   0,   0,   0,   52,  0,   0,   0,   72,  1,
+    0,   0,   124, 1,   0,   0,   120, 2,   0,   0,   216, 3,   0,   0,   82,  68,  69,  70,  12,
+    1,   0,   0,   1,   0,   0,   0,   84,  0,   0,   0,   1,   0,   0,   0,   28,  0,   0,   0,
+    0,   4,   255, 255, 0,   1,   0,   0,   216, 0,   0,   0,   60,  0,   0,   0,   0,   0,   0,
+    0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   1,   0,
+    0,   0,   1,   0,   0,   0,   67,  111, 108, 111, 114, 65,  110, 100, 68,  101, 112, 116, 104,
+    68,  97,  116, 97,  85,  105, 110, 116, 0,   171, 171, 60,  0,   0,   0,   2,   0,   0,   0,
+    108, 0,   0,   0,   32,  0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   156, 0,   0,
+    0,   0,   0,   0,   0,   16,  0,   0,   0,   2,   0,   0,   0,   168, 0,   0,   0,   0,   0,
+    0,   0,   184, 0,   0,   0,   16,  0,   0,   0,   4,   0,   0,   0,   2,   0,   0,   0,   200,
+    0,   0,   0,   0,   0,   0,   0,   99,  111, 108, 111, 114, 95,  85,  105, 110, 116, 0,   171,
+    1,   0,   19,  0,   1,   0,   4,   0,   0,   0,   0,   0,   0,   0,   0,   0,   122, 86,  97,
+    108, 117, 101, 70,  95,  85,  105, 110, 116, 0,   171, 171, 171, 0,   0,   3,   0,   1,   0,
+    1,   0,   0,   0,   0,   0,   0,   0,   0,   0,   77,  105, 99,  114, 111, 115, 111, 102, 116,
+    32,  40,  82,  41,  32,  72,  76,  83,  76,  32,  83,  104, 97,  100, 101, 114, 32,  67,  111,
+    109, 112, 105, 108, 101, 114, 32,  54,  46,  51,  46,  57,  54,  48,  48,  46,  49,  54,  51,
+    56,  52,  0,   171, 171, 73,  83,  71,  78,  44,  0,   0,   0,   1,   0,   0,   0,   8,   0,
+    0,   0,   32,  0,   0,   0,   0,   0,   0,   0,   1,   0,   0,   0,   3,   0,   0,   0,   0,
+    0,   0,   0,   15,  0,   0,   0,   83,  86,  95,  80,  79,  83,  73,  84,  73,  79,  78,  0,
+    79,  83,  71,  78,  244, 0,   0,   0,   9,   0,   0,   0,   8,   0,   0,   0,   224, 0,   0,
+    0,   0,   0,   0,   0,   0,   0,   0,   0,   1,   0,   0,   0,   0,   0,   0,   0,   15,  0,
+    0,   0,   224, 0,   0,   0,   1,   0,   0,   0,   0,   0,   0,   0,   1,   0,   0,   0,   1,
+    0,   0,   0,   15,  0,   0,   0,   224, 0,   0,   0,   2,   0,   0,   0,   0,   0,   0,   0,
+    1,   0,   0,   0,   2,   0,   0,   0,   15,  0,   0,   0,   224, 0,   0,   0,   3,   0,   0,
+    0,   0,   0,   0,   0,   1,   0,   0,   0,   3,   0,   0,   0,   15,  0,   0,   0,   224, 0,
+    0,   0,   4,   0,   0,   0,   0,   0,   0,   0,   1,   0,   0,   0,   4,   0,   0,   0,   15,
+    0,   0,   0,   224, 0,   0,   0,   5,   0,   0,   0,   0,   0,   0,   0,   1,   0,   0,   0,
+    5,   0,   0,   0,   15,  0,   0,   0,   224, 0,   0,   0,   6,   0,   0,   0,   0,   0,   0,
+    0,   1,   0,   0,   0,   6,   0,   0,   0,   15,  0,   0,   0,   224, 0,   0,   0,   7,   0,
+    0,   0,   0,   0,   0,   0,   1,   0,   0,   0,   7,   0,   0,   0,   15,  0,   0,   0,   234,
+    0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   3,   0,   0,   0,   255, 255, 255, 255,
+    1,   14,  0,   0,   83,  86,  95,  84,  65,  82,  71,  69,  84,  0,   83,  86,  95,  68,  69,
+    80,  84,  72,  0,   171, 83,  72,  68,  82,  88,  1,   0,   0,   64,  0,   0,   0,   86,  0,
+    0,   0,   89,  0,   0,   4,   70,  142, 32,  0,   0,   0,   0,   0,   2,   0,   0,   0,   101,
+    0,   0,   3,   242, 32,  16,  0,   0,   0,   0,   0,   101, 0,   0,   3,   242, 32,  16,  0,
+    1,   0,   0,   0,   101, 0,   0,   3,   242, 32,  16,  0,   2,   0,   0,   0,   101, 0,   0,
+    3,   242, 32,  16,  0,   3,   0,   0,   0,   101, 0,   0,   3,   242, 32,  16,  0,   4,   0,
+    0,   0,   101, 0,   0,   3,   242, 32,  16,  0,   5,   0,   0,   0,   101, 0,   0,   3,   242,
+    32,  16,  0,   6,   0,   0,   0,   101, 0,   0,   3,   242, 32,  16,  0,   7,   0,   0,   0,
+    101, 0,   0,   2,   1,   192, 0,   0,   54,  0,   0,   6,   242, 32,  16,  0,   0,   0,   0,
+    0,   70,  142, 32,  0,   0,   0,   0,   0,   0,   0,   0,   0,   54,  0,   0,   6,   242, 32,
+    16,  0,   1,   0,   0,   0,   70,  142, 32,  0,   0,   0,   0,   0,   0,   0,   0,   0,   54,
+    0,   0,   6,   242, 32,  16,  0,   2,   0,   0,   0,   70,  142, 32,  0,   0,   0,   0,   0,
+    0,   0,   0,   0,   54,  0,   0,   6,   242, 32,  16,  0,   3,   0,   0,   0,   70,  142, 32,
+    0,   0,   0,   0,   0,   0,   0,   0,   0,   54,  0,   0,   6,   242, 32,  16,  0,   4,   0,
+    0,   0,   70,  142, 32,  0,   0,   0,   0,   0,   0,   0,   0,   0,   54,  0,   0,   6,   242,
+    32,  16,  0,   5,   0,   0,   0,   70,  142, 32,  0,   0,   0,   0,   0,   0,   0,   0,   0,
+    54,  0,   0,   6,   242, 32,  16,  0,   6,   0,   0,   0,   70,  142, 32,  0,   0,   0,   0,
+    0,   0,   0,   0,   0,   54,  0,   0,   6,   242, 32,  16,  0,   7,   0,   0,   0,   70,  142,
+    32,  0,   0,   0,   0,   0,   0,   0,   0,   0,   54,  0,   0,   5,   1,   192, 0,   0,   10,
+    128, 32,  0,   0,   0,   0,   0,   1,   0,   0,   0,   62,  0,   0,   1,   83,  84,  65,  84,
+    116, 0,   0,   0,   10,  0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   9,   0,   0,
+    0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   1,   0,   0,   0,   0,   0,
+    0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+    0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+    0,   0,   0,   0,   9,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+    0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+    0,   0,   0,   0,   0,   0};
--- a/gfx/angle/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftof_pm_luma_ps.h
+++ b/gfx/angle/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftof_pm_luma_ps.h
@@ -1,77 +1,77 @@
-#if 0
-//
-// Generated by Microsoft (R) HLSL Shader Compiler 6.3.9600.16384
-//
-//
-// Resource Bindings:
-//
-// Name                                 Type  Format         Dim Slot Elements
-// ------------------------------ ---------- ------- ----------- ---- --------
-// Sampler                           sampler      NA          NA    0        1
-// TextureF                          texture  float4          2d    0        1
-//
-//
-//
-// Input signature:
-//
-// Name                 Index   Mask Register SysValue  Format   Used
-// -------------------- ----- ------ -------- -------- ------- ------
-// SV_POSITION              0   xyzw        0      POS   float       
-// TEXCOORD                 0   xy          1     NONE   float   xy  
-//
-//
-// Output signature:
-//
-// Name                 Index   Mask Register SysValue  Format   Used
-// -------------------- ----- ------ -------- -------- ------- ------
-// SV_TARGET                0   xyzw        0   TARGET   float   xyzw
-//
-ps_4_0
-dcl_sampler s0, mode_default
-dcl_resource_texture2d (float,float,float,float) t0
-dcl_input_ps linear v1.xy
-dcl_output o0.xyzw
-dcl_temps 1
-sample r0.xyzw, v1.xyxx, t0.xyzw, s0
-mul o0.xyz, r0.wwww, r0.xxxx
-mov o0.w, l(1.000000)
-ret 
-// Approximately 4 instruction slots used
-#endif
-
-const BYTE g_PS_FtoF_PM_LUMA[] = {
-    68, 88,  66,  67,  61,  193, 4,   85,  218, 250, 183, 199, 231, 187, 141, 93,  80,  186, 200,
-    74, 1,   0,   0,   0,   136, 2,   0,   0,   5,   0,   0,   0,   52,  0,   0,   0,   220, 0,
-    0,  0,   52,  1,   0,   0,   104, 1,   0,   0,   12,  2,   0,   0,   82,  68,  69,  70,  160,
-    0,  0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   2,   0,   0,   0,   28,  0,   0,   0,
-    0,  4,   255, 255, 0,   1,   0,   0,   109, 0,   0,   0,   92,  0,   0,   0,   3,   0,   0,
-    0,  0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   1,   0,
-    0,  0,   1,   0,   0,   0,   100, 0,   0,   0,   2,   0,   0,   0,   5,   0,   0,   0,   4,
-    0,  0,   0,   255, 255, 255, 255, 0,   0,   0,   0,   1,   0,   0,   0,   13,  0,   0,   0,
-    83, 97,  109, 112, 108, 101, 114, 0,   84,  101, 120, 116, 117, 114, 101, 70,  0,   77,  105,
-    99, 114, 111, 115, 111, 102, 116, 32,  40,  82,  41,  32,  72,  76,  83,  76,  32,  83,  104,
-    97, 100, 101, 114, 32,  67,  111, 109, 112, 105, 108, 101, 114, 32,  54,  46,  51,  46,  57,
-    54, 48,  48,  46,  49,  54,  51,  56,  52,  0,   171, 73,  83,  71,  78,  80,  0,   0,   0,
-    2,  0,   0,   0,   8,   0,   0,   0,   56,  0,   0,   0,   0,   0,   0,   0,   1,   0,   0,
-    0,  3,   0,   0,   0,   0,   0,   0,   0,   15,  0,   0,   0,   68,  0,   0,   0,   0,   0,
-    0,  0,   0,   0,   0,   0,   3,   0,   0,   0,   1,   0,   0,   0,   3,   3,   0,   0,   83,
-    86, 95,  80,  79,  83,  73,  84,  73,  79,  78,  0,   84,  69,  88,  67,  79,  79,  82,  68,
-    0,  171, 171, 171, 79,  83,  71,  78,  44,  0,   0,   0,   1,   0,   0,   0,   8,   0,   0,
-    0,  32,  0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   3,   0,   0,   0,   0,   0,
-    0,  0,   15,  0,   0,   0,   83,  86,  95,  84,  65,  82,  71,  69,  84,  0,   171, 171, 83,
-    72, 68,  82,  156, 0,   0,   0,   64,  0,   0,   0,   39,  0,   0,   0,   90,  0,   0,   3,
-    0,  96,  16,  0,   0,   0,   0,   0,   88,  24,  0,   4,   0,   112, 16,  0,   0,   0,   0,
-    0,  85,  85,  0,   0,   98,  16,  0,   3,   50,  16,  16,  0,   1,   0,   0,   0,   101, 0,
-    0,  3,   242, 32,  16,  0,   0,   0,   0,   0,   104, 0,   0,   2,   1,   0,   0,   0,   69,
-    0,  0,   9,   242, 0,   16,  0,   0,   0,   0,   0,   70,  16,  16,  0,   1,   0,   0,   0,
-    70, 126, 16,  0,   0,   0,   0,   0,   0,   96,  16,  0,   0,   0,   0,   0,   56,  0,   0,
-    7,  114, 32,  16,  0,   0,   0,   0,   0,   246, 15,  16,  0,   0,   0,   0,   0,   6,   0,
-    16, 0,   0,   0,   0,   0,   54,  0,   0,   5,   130, 32,  16,  0,   0,   0,   0,   0,   1,
-    64, 0,   0,   0,   0,   128, 63,  62,  0,   0,   1,   83,  84,  65,  84,  116, 0,   0,   0,
-    4,  0,   0,   0,   1,   0,   0,   0,   0,   0,   0,   0,   2,   0,   0,   0,   1,   0,   0,
-    0,  0,   0,   0,   0,   0,   0,   0,   0,   1,   0,   0,   0,   0,   0,   0,   0,   0,   0,
-    0,  0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   1,
-    0,  0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
-    1,  0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
-    0,  0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
-    0,  0};
+#if 0
+//
+// Generated by Microsoft (R) HLSL Shader Compiler 6.3.9600.16384
+//
+//
+// Resource Bindings:
+//
+// Name                                 Type  Format         Dim Slot Elements
+// ------------------------------ ---------- ------- ----------- ---- --------
+// Sampler                           sampler      NA          NA    0        1
+// TextureF                          texture  float4          2d    0        1
+//
+//
+//
+// Input signature:
+//
+// Name                 Index   Mask Register SysValue  Format   Used
+// -------------------- ----- ------ -------- -------- ------- ------
+// SV_POSITION              0   xyzw        0      POS   float       
+// TEXCOORD                 0   xy          1     NONE   float   xy  
+//
+//
+// Output signature:
+//
+// Name                 Index   Mask Register SysValue  Format   Used
+// -------------------- ----- ------ -------- -------- ------- ------
+// SV_TARGET                0   xyzw        0   TARGET   float   xyzw
+//
+ps_4_0
+dcl_sampler s0, mode_default
+dcl_resource_texture2d (float,float,float,float) t0
+dcl_input_ps linear v1.xy
+dcl_output o0.xyzw
+dcl_temps 1
+sample r0.xyzw, v1.xyxx, t0.xyzw, s0
+mul o0.xyz, r0.wwww, r0.xxxx
+mov o0.w, l(1.000000)
+ret 
+// Approximately 4 instruction slots used
+#endif
+
+const BYTE g_PS_FtoF_PM_LUMA[] = {
+    68, 88,  66,  67,  61,  193, 4,   85,  218, 250, 183, 199, 231, 187, 141, 93,  80,  186, 200,
+    74, 1,   0,   0,   0,   136, 2,   0,   0,   5,   0,   0,   0,   52,  0,   0,   0,   220, 0,
+    0,  0,   52,  1,   0,   0,   104, 1,   0,   0,   12,  2,   0,   0,   82,  68,  69,  70,  160,
+    0,  0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   2,   0,   0,   0,   28,  0,   0,   0,
+    0,  4,   255, 255, 0,   1,   0,   0,   109, 0,   0,   0,   92,  0,   0,   0,   3,   0,   0,
+    0,  0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   1,   0,
+    0,  0,   1,   0,   0,   0,   100, 0,   0,   0,   2,   0,   0,   0,   5,   0,   0,   0,   4,
+    0,  0,   0,   255, 255, 255, 255, 0,   0,   0,   0,   1,   0,   0,   0,   13,  0,   0,   0,
+    83, 97,  109, 112, 108, 101, 114, 0,   84,  101, 120, 116, 117, 114, 101, 70,  0,   77,  105,
+    99, 114, 111, 115, 111, 102, 116, 32,  40,  82,  41,  32,  72,  76,  83,  76,  32,  83,  104,
+    97, 100, 101, 114, 32,  67,  111, 109, 112, 105, 108, 101, 114, 32,  54,  46,  51,  46,  57,
+    54, 48,  48,  46,  49,  54,  51,  56,  52,  0,   171, 73,  83,  71,  78,  80,  0,   0,   0,
+    2,  0,   0,   0,   8,   0,   0,   0,   56,  0,   0,   0,   0,   0,   0,   0,   1,   0,   0,
+    0,  3,   0,   0,   0,   0,   0,   0,   0,   15,  0,   0,   0,   68,  0,   0,   0,   0,   0,
+    0,  0,   0,   0,   0,   0,   3,   0,   0,   0,   1,   0,   0,   0,   3,   3,   0,   0,   83,
+    86, 95,  80,  79,  83,  73,  84,  73,  79,  78,  0,   84,  69,  88,  67,  79,  79,  82,  68,
+    0,  171, 171, 171, 79,  83,  71,  78,  44,  0,   0,   0,   1,   0,   0,   0,   8,   0,   0,
+    0,  32,  0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   3,   0,   0,   0,   0,   0,
+    0,  0,   15,  0,   0,   0,   83,  86,  95,  84,  65,  82,  71,  69,  84,  0,   171, 171, 83,
+    72, 68,  82,  156, 0,   0,   0,   64,  0,   0,   0,   39,  0,   0,   0,   90,  0,   0,   3,
+    0,  96,  16,  0,   0,   0,   0,   0,   88,  24,  0,   4,   0,   112, 16,  0,   0,   0,   0,
+    0,  85,  85,  0,   0,   98,  16,  0,   3,   50,  16,  16,  0,   1,   0,   0,   0,   101, 0,
+    0,  3,   242, 32,  16,  0,   0,   0,   0,   0,   104, 0,   0,   2,   1,   0,   0,   0,   69,
+    0,  0,   9,   242, 0,   16,  0,   0,   0,   0,   0,   70,  16,  16,  0,   1,   0,   0,   0,
+    70, 126, 16,  0,   0,   0,   0,   0,   0,   96,  16,  0,   0,   0,   0,   0,   56,  0,   0,
+    7,  114, 32,  16,  0,   0,   0,   0,   0,   246, 15,  16,  0,   0,   0,   0,   0,   6,   0,
+    16, 0,   0,   0,   0,   0,   54,  0,   0,   5,   130, 32,  16,  0,   0,   0,   0,   0,   1,
+    64, 0,   0,   0,   0,   128, 63,  62,  0,   0,   1,   83,  84,  65,  84,  116, 0,   0,   0,
+    4,  0,   0,   0,   1,   0,   0,   0,   0,   0,   0,   0,   2,   0,   0,   0,   1,   0,   0,
+    0,  0,   0,   0,   0,   0,   0,   0,   0,   1,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+    0,  0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   1,
+    0,  0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+    1,  0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+    0,  0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+    0,  0};
--- a/gfx/angle/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftof_pm_lumaalpha_ps.h
+++ b/gfx/angle/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftof_pm_lumaalpha_ps.h
@@ -1,77 +1,77 @@
-#if 0
-//
-// Generated by Microsoft (R) HLSL Shader Compiler 6.3.9600.16384
-//
-//
-// Resource Bindings:
-//
-// Name                                 Type  Format         Dim Slot Elements
-// ------------------------------ ---------- ------- ----------- ---- --------
-// Sampler                           sampler      NA          NA    0        1
-// TextureF                          texture  float4          2d    0        1
-//
-//
-//
-// Input signature:
-//
-// Name                 Index   Mask Register SysValue  Format   Used
-// -------------------- ----- ------ -------- -------- ------- ------
-// SV_POSITION              0   xyzw        0      POS   float       
-// TEXCOORD                 0   xy          1     NONE   float   xy  
-//
-//
-// Output signature:
-//
-// Name                 Index   Mask Register SysValue  Format   Used
-// -------------------- ----- ------ -------- -------- ------- ------
-// SV_TARGET                0   xyzw        0   TARGET   float   xyzw
-//
-ps_4_0
-dcl_sampler s0, mode_default
-dcl_resource_texture2d (float,float,float,float) t0
-dcl_input_ps linear v1.xy
-dcl_output o0.xyzw
-dcl_temps 1
-sample r0.xyzw, v1.xyxx, t0.xyzw, s0
-mul o0.xyz, r0.wwww, r0.xxxx
-mov o0.w, r0.w
-ret 
-// Approximately 4 instruction slots used
-#endif
-
-const BYTE g_PS_FtoF_PM_LUMAALPHA[] = {
-    68, 88,  66,  67,  16,  240, 62,  171, 253, 134, 187, 96,  66,  174, 101, 13,  101, 43,  164,
-    23, 1,   0,   0,   0,   136, 2,   0,   0,   5,   0,   0,   0,   52,  0,   0,   0,   220, 0,
-    0,  0,   52,  1,   0,   0,   104, 1,   0,   0,   12,  2,   0,   0,   82,  68,  69,  70,  160,
-    0,  0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   2,   0,   0,   0,   28,  0,   0,   0,
-    0,  4,   255, 255, 0,   1,   0,   0,   109, 0,   0,   0,   92,  0,   0,   0,   3,   0,   0,
-    0,  0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   1,   0,
-    0,  0,   1,   0,   0,   0,   100, 0,   0,   0,   2,   0,   0,   0,   5,   0,   0,   0,   4,
-    0,  0,   0,   255, 255, 255, 255, 0,   0,   0,   0,   1,   0,   0,   0,   13,  0,   0,   0,
-    83, 97,  109, 112, 108, 101, 114, 0,   84,  101, 120, 116, 117, 114, 101, 70,  0,   77,  105,
-    99, 114, 111, 115, 111, 102, 116, 32,  40,  82,  41,  32,  72,  76,  83,  76,  32,  83,  104,
-    97, 100, 101, 114, 32,  67,  111, 109, 112, 105, 108, 101, 114, 32,  54,  46,  51,  46,  57,
-    54, 48,  48,  46,  49,  54,  51,  56,  52,  0,   171, 73,  83,  71,  78,  80,  0,   0,   0,
-    2,  0,   0,   0,   8,   0,   0,   0,   56,  0,   0,   0,   0,   0,   0,   0,   1,   0,   0,
-    0,  3,   0,   0,   0,   0,   0,   0,   0,   15,  0,   0,   0,   68,  0,   0,   0,   0,   0,
-    0,  0,   0,   0,   0,   0,   3,   0,   0,   0,   1,   0,   0,   0,   3,   3,   0,   0,   83,
-    86, 95,  80,  79,  83,  73,  84,  73,  79,  78,  0,   84,  69,  88,  67,  79,  79,  82,  68,
-    0,  171, 171, 171, 79,  83,  71,  78,  44,  0,   0,   0,   1,   0,   0,   0,   8,   0,   0,
-    0,  32,  0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   3,   0,   0,   0,   0,   0,
-    0,  0,   15,  0,   0,   0,   83,  86,  95,  84,  65,  82,  71,  69,  84,  0,   171, 171, 83,
-    72, 68,  82,  156, 0,   0,   0,   64,  0,   0,   0,   39,  0,   0,   0,   90,  0,   0,   3,
-    0,  96,  16,  0,   0,   0,   0,   0,   88,  24,  0,   4,   0,   112, 16,  0,   0,   0,   0,
-    0,  85,  85,  0,   0,   98,  16,  0,   3,   50,  16,  16,  0,   1,   0,   0,   0,   101, 0,
-    0,  3,   242, 32,  16,  0,   0,   0,   0,   0,   104, 0,   0,   2,   1,   0,   0,   0,   69,
-    0,  0,   9,   242, 0,   16,  0,   0,   0,   0,   0,   70,  16,  16,  0,   1,   0,   0,   0,
-    70, 126, 16,  0,   0,   0,   0,   0,   0,   96,  16,  0,   0,   0,   0,   0,   56,  0,   0,
-    7,  114, 32,  16,  0,   0,   0,   0,   0,   246, 15,  16,  0,   0,   0,   0,   0,   6,   0,
-    16, 0,   0,   0,   0,   0,   54,  0,   0,   5,   130, 32,  16,  0,   0,   0,   0,   0,   58,
-    0,  16,  0,   0,   0,   0,   0,   62,  0,   0,   1,   83,  84,  65,  84,  116, 0,   0,   0,
-    4,  0,   0,   0,   1,   0,   0,   0,   0,   0,   0,   0,   2,   0,   0,   0,   1,   0,   0,
-    0,  0,   0,   0,   0,   0,   0,   0,   0,   1,   0,   0,   0,   0,   0,   0,   0,   0,   0,
-    0,  0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   1,
-    0,  0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
-    1,  0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
-    0,  0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
-    0,  0};
+#if 0
+//
+// Generated by Microsoft (R) HLSL Shader Compiler 6.3.9600.16384
+//
+//
+// Resource Bindings:
+//
+// Name                                 Type  Format         Dim Slot Elements
+// ------------------------------ ---------- ------- ----------- ---- --------
+// Sampler                           sampler      NA          NA    0        1
+// TextureF                          texture  float4          2d    0        1
+//
+//
+//
+// Input signature:
+//
+// Name                 Index   Mask Register SysValue  Format   Used
+// -------------------- ----- ------ -------- -------- ------- ------
+// SV_POSITION              0   xyzw        0      POS   float       
+// TEXCOORD                 0   xy          1     NONE   float   xy  
+//
+//
+// Output signature:
+//
+// Name                 Index   Mask Register SysValue  Format   Used
+// -------------------- ----- ------ -------- -------- ------- ------
+// SV_TARGET                0   xyzw        0   TARGET   float   xyzw
+//
+ps_4_0
+dcl_sampler s0, mode_default
+dcl_resource_texture2d (float,float,float,float) t0
+dcl_input_ps linear v1.xy
+dcl_output o0.xyzw
+dcl_temps 1
+sample r0.xyzw, v1.xyxx, t0.xyzw, s0
+mul o0.xyz, r0.wwww, r0.xxxx
+mov o0.w, r0.w
+ret 
+// Approximately 4 instruction slots used
+#endif
+
+const BYTE g_PS_FtoF_PM_LUMAALPHA[] = {
+    68, 88,  66,  67,  16,  240, 62,  171, 253, 134, 187, 96,  66,  174, 101, 13,  101, 43,  164,
+    23, 1,   0,   0,   0,   136, 2,   0,   0,   5,   0,   0,   0,   52,  0,   0,   0,   220, 0,
+    0,  0,   52,  1,   0,   0,   104, 1,   0,   0,   12,  2,   0,   0,   82,  68,  69,  70,  160,
+    0,  0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   2,   0,   0,   0,   28,  0,   0,   0,
+    0,  4,   255, 255, 0,   1,   0,   0,   109, 0,   0,   0,   92,  0,   0,   0,   3,   0,   0,
+    0,  0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   1,   0,
+    0,  0,   1,   0,   0,   0,   100, 0,   0,   0,   2,   0,   0,   0,   5,   0,   0,   0,   4,
+    0,  0,   0,   255, 255, 255, 255, 0,   0,   0,   0,   1,   0,   0,   0,   13,  0,   0,   0,
+    83, 97,  109, 112, 108, 101, 114, 0,   84,  101, 120, 116, 117, 114, 101, 70,  0,   77,  105,
+    99, 114, 111, 115, 111, 102, 116, 32,  40,  82,  41,  32,  72,  76,  83,  76,  32,  83,  104,
+    97, 100, 101, 114, 32,  67,  111, 109, 112, 105, 108, 101, 114, 32,  54,  46,  51,  46,  57,
+    54, 48,  48,  46,  49,  54,  51,  56,  52,  0,   171, 73,  83,  71,  78,  80,  0,   0,   0,
+    2,  0,   0,   0,   8,   0,   0,   0,   56,  0,   0,   0,   0,   0,   0,   0,   1,   0,   0,
+    0,  3,   0,   0,   0,   0,   0,   0,   0,   15,  0,   0,   0,   68,  0,   0,   0,   0,   0,
+    0,  0,   0,   0,   0,   0,   3,   0,   0,   0,   1,   0,   0,   0,   3,   3,   0,   0,   83,
+    86, 95,  80,  79,  83,  73,  84,  73,  79,  78,  0,   84,  69,  88,  67,  79,  79,  82,  68,
+    0,  171, 171, 171, 79,  83,  71,  78,  44,  0,   0,   0,   1,   0,   0,   0,   8,   0,   0,
+    0,  32,  0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   3,   0,   0,   0,   0,   0,
+    0,  0,   15,  0,   0,   0,   83,  86,  95,  84,  65,  82,  71,  69,  84,  0,   171, 171, 83,
+    72, 68,  82,  156, 0,   0,   0,   64,  0,   0,   0,   39,  0,   0,   0,   90,  0,   0,   3,
+    0,  96,  16,  0,   0,   0,   0,   0,   88,  24,  0,   4,   0,   112, 16,  0,   0,   0,   0,
+    0,  85,  85,  0,   0,   98,  16,  0,   3,   50,  16,  16,  0,   1,   0,   0,   0,   101, 0,
+    0,  3,   242, 32,  16,  0,   0,   0,   0,   0,   104, 0,   0,   2,   1,   0,   0,   0,   69,
+    0,  0,   9,   242, 0,   16,  0,   0,   0,   0,   0,   70,  16,  16,  0,   1,   0,   0,   0,
+    70, 126, 16,  0,   0,   0,   0,   0,   0,   96,  16,  0,   0,   0,   0,   0,   56,  0,   0,
+    7,  114, 32,  16,  0,   0,   0,   0,   0,   246, 15,  16,  0,   0,   0,   0,   0,   6,   0,
+    16, 0,   0,   0,   0,   0,   54,  0,   0,   5,   130, 32,  16,  0,   0,   0,   0,   0,   58,
+    0,  16,  0,   0,   0,   0,   0,   62,  0,   0,   1,   83,  84,  65,  84,  116, 0,   0,   0,
+    4,  0,   0,   0,   1,   0,   0,   0,   0,   0,   0,   0,   2,   0,   0,   0,   1,   0,   0,
+    0,  0,   0,   0,   0,   0,   0,   0,   0,   1,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+    0,  0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   1,
+    0,  0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+    1,  0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+    0,  0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+    0,  0};
--- a/gfx/angle/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftof_pm_rgb_ps.h
+++ b/gfx/angle/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftof_pm_rgb_ps.h
@@ -1,77 +1,77 @@
-#if 0
-//
-// Generated by Microsoft (R) HLSL Shader Compiler 6.3.9600.16384
-//
-//
-// Resource Bindings:
-//
-// Name                                 Type  Format         Dim Slot Elements
-// ------------------------------ ---------- ------- ----------- ---- --------
-// Sampler                           sampler      NA          NA    0        1
-// TextureF                          texture  float4          2d    0        1
-//
-//
-//
-// Input signature:
-//
-// Name                 Index   Mask Register SysValue  Format   Used
-// -------------------- ----- ------ -------- -------- ------- ------
-// SV_POSITION              0   xyzw        0      POS   float       
-// TEXCOORD                 0   xy          1     NONE   float   xy  
-//
-//
-// Output signature:
-//
-// Name                 Index   Mask Register SysValue  Format   Used
-// -------------------- ----- ------ -------- -------- ------- ------
-// SV_TARGET                0   xyzw        0   TARGET   float   xyzw
-//
-ps_4_0
-dcl_sampler s0, mode_default
-dcl_resource_texture2d (float,float,float,float) t0
-dcl_input_ps linear v1.xy
-dcl_output o0.xyzw
-dcl_temps 1
-sample r0.xyzw, v1.xyxx, t0.xyzw, s0
-mul o0.xyz, r0.wwww, r0.xyzx
-mov o0.w, l(1.000000)
-ret 
-// Approximately 4 instruction slots used
-#endif
-
-const BYTE g_PS_FtoF_PM_RGB[] = {
-    68, 88,  66,  67,  184, 252, 76,  134, 209, 229, 230, 149, 167, 232, 172, 33,  50,  152, 142,
-    84, 1,   0,   0,   0,   136, 2,   0,   0,   5,   0,   0,   0,   52,  0,   0,   0,   220, 0,
-    0,  0,   52,  1,   0,   0,   104, 1,   0,   0,   12,  2,   0,   0,   82,  68,  69,  70,  160,
-    0,  0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   2,   0,   0,   0,   28,  0,   0,   0,
-    0,  4,   255, 255, 0,   1,   0,   0,   109, 0,   0,   0,   92,  0,   0,   0,   3,   0,   0,
-    0,  0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   1,   0,
-    0,  0,   1,   0,   0,   0,   100, 0,   0,   0,   2,   0,   0,   0,   5,   0,   0,   0,   4,
-    0,  0,   0,   255, 255, 255, 255, 0,   0,   0,   0,   1,   0,   0,   0,   13,  0,   0,   0,
-    83, 97,  109, 112, 108, 101, 114, 0,   84,  101, 120, 116, 117, 114, 101, 70,  0,   77,  105,
-    99, 114, 111, 115, 111, 102, 116, 32,  40,  82,  41,  32,  72,  76,  83,  76,  32,  83,  104,
-    97, 100, 101, 114, 32,  67,  111, 109, 112, 105, 108, 101, 114, 32,  54,  46,  51,  46,  57,
-    54, 48,  48,  46,  49,  54,  51,  56,  52,  0,   171, 73,  83,  71,  78,  80,  0,   0,   0,
-    2,  0,   0,   0,   8,   0,   0,   0,   56,  0,   0,   0,   0,   0,   0,   0,   1,   0,   0,
-    0,  3,   0,   0,   0,   0,   0,   0,   0,   15,  0,   0,   0,   68,  0,   0,   0,   0,   0,
-    0,  0,   0,   0,   0,   0,   3,   0,   0,   0,   1,   0,   0,   0,   3,   3,   0,   0,   83,
-    86, 95,  80,  79,  83,  73,  84,  73,  79,  78,  0,   84,  69,  88,  67,  79,  79,  82,  68,
-    0,  171, 171, 171, 79,  83,  71,  78,  44,  0,   0,   0,   1,   0,   0,   0,   8,   0,   0,
-    0,  32,  0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   3,   0,   0,   0,   0,   0,
-    0,  0,   15,  0,   0,   0,   83,  86,  95,  84,  65,  82,  71,  69,  84,  0,   171, 171, 83,
-    72, 68,  82,  156, 0,   0,   0,   64,  0,   0,   0,   39,  0,   0,   0,   90,  0,   0,   3,
-    0,  96,  16,  0,   0,   0,   0,   0,   88,  24,  0,   4,   0,   112, 16,  0,   0,   0,   0,
-    0,  85,  85,  0,   0,   98,  16,  0,   3,   50,  16,  16,  0,   1,   0,   0,   0,   101, 0,
-    0,  3,   242, 32,  16,  0,   0,   0,   0,   0,   104, 0,   0,   2,   1,   0,   0,   0,   69,
-    0,  0,   9,   242, 0,   16,  0,   0,   0,   0,   0,   70,  16,  16,  0,   1,   0,   0,   0,
-    70, 126, 16,  0,   0,   0,   0,   0,   0,   96,  16,  0,   0,   0,   0,   0,   56,  0,   0,
-    7,  114, 32,  16,  0,   0,   0,   0,   0,   246, 15,  16,  0,   0,   0,   0,   0,   70,  2,
-    16, 0,   0,   0,   0,   0,   54,  0,   0,   5,   130, 32,  16,  0,   0,   0,   0,   0,   1,
-    64, 0,   0,   0,   0,   128, 63,  62,  0,   0,   1,   83,  84,  65,  84,  116, 0,   0,   0,
-    4,  0,   0,   0,   1,   0,   0,   0,   0,   0,   0,   0,   2,   0,   0,   0,   1,   0,   0,
-    0,  0,   0,   0,   0,   0,   0,   0,   0,   1,   0,   0,   0,   0,   0,   0,   0,   0,   0,
-    0,  0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   1,
-    0,  0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
-    1,  0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
-    0,  0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
-    0,  0};
+#if 0
+//
+// Generated by Microsoft (R) HLSL Shader Compiler 6.3.9600.16384
+//
+//
+// Resource Bindings:
+//
+// Name                                 Type  Format         Dim Slot Elements
+// ------------------------------ ---------- ------- ----------- ---- --------
+// Sampler                           sampler      NA          NA    0        1
+// TextureF                          texture  float4          2d    0        1
+//
+//
+//
+// Input signature:
+//
+// Name                 Index   Mask Register SysValue  Format   Used
+// -------------------- ----- ------ -------- -------- ------- ------
+// SV_POSITION              0   xyzw        0      POS   float       
+// TEXCOORD                 0   xy          1     NONE   float   xy  
+//
+//
+// Output signature:
+//
+// Name                 Index   Mask Register SysValue  Format   Used
+// -------------------- ----- ------ -------- -------- ------- ------
+// SV_TARGET                0   xyzw        0   TARGET   float   xyzw
+//
+ps_4_0
+dcl_sampler s0, mode_default
+dcl_resource_texture2d (float,float,float,float) t0
+dcl_input_ps linear v1.xy
+dcl_output o0.xyzw
+dcl_temps 1
+sample r0.xyzw, v1.xyxx, t0.xyzw, s0
+mul o0.xyz, r0.wwww, r0.xyzx
+mov o0.w, l(1.000000)
+ret 
+// Approximately 4 instruction slots used
+#endif
+
+const BYTE g_PS_FtoF_PM_RGB[] = {
+    68, 88,  66,  67,  184, 252, 76,  134, 209, 229, 230, 149, 167, 232, 172, 33,  50,  152, 142,
+    84, 1,   0,   0,   0,   136, 2,   0,   0,   5,   0,   0,   0,   52,  0,   0,   0,   220, 0,
+    0,  0,   52,  1,   0,   0,   104, 1,   0,   0,   12,  2,   0,   0,   82,  68,  69,  70,  160,
+    0,  0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   2,   0,   0,   0,   28,  0,   0,   0,
+    0,  4,   255, 255, 0,   1,   0,   0,   109, 0,   0,   0,   92,  0,   0,   0,   3,   0,   0,
+    0,  0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   1,   0,
+    0,  0,   1,   0,   0,   0,   100, 0,   0,   0,   2,   0,   0,   0,   5,   0,   0,   0,   4,
+    0,  0,   0,   255, 255, 255, 255, 0,   0,   0,   0,   1,   0,   0,   0,   13,  0,   0,   0,
+    83, 97,  109, 112, 108, 101, 114, 0,   84,  101, 120, 116, 117, 114, 101, 70,  0,   77,  105,
+    99, 114, 111, 115, 111, 102, 116, 32,  40,  82,  41,  32,  72,  76,  83,  76,  32,  83,  104,
+    97, 100, 101, 114, 32,  67,  111, 109, 112, 105, 108, 101, 114, 32,  54,  46,  51,  46,  57,
+    54, 48,  48,  46,  49,  54,  51,  56,  52,  0,   171, 73,  83,  71,  78,  80,  0,   0,   0,
+    2,  0,   0,   0,   8,   0,   0,   0,   56,  0,   0,   0,   0,   0,   0,   0,   1,   0,   0,
+    0,  3,   0,   0,   0,   0,   0,   0,   0,   15,  0,   0,   0,   68,  0,   0,   0,   0,   0,
+    0,  0,   0,   0,   0,   0,   3,   0,   0,   0,   1,   0,   0,   0,   3,   3,   0,   0,   83,
+    86, 95,  80,  79,  83,  73,  84,  73,  79,  78,  0,   84,  69,  88,  67,  79,  79,  82,  68,
+    0,  171, 171, 171, 79,  83,  71,  78,  44,  0,   0,   0,   1,   0,   0,   0,   8,   0,   0,
+    0,  32,  0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   3,   0,   0,   0,   0,   0,
+    0,  0,   15,  0,   0,   0,   83,  86,  95,  84,  65,  82,  71,  69,  84,  0,   171, 171, 83,
+    72, 68,  82,  156, 0,   0,   0,   64,  0,   0,   0,   39,  0,   0,   0,   90,  0,   0,   3,
+    0,  96,  16,  0,   0,   0,   0,   0,   88,  24,  0,   4,   0,   112, 16,  0,   0,   0,   0,
+    0,  85,  85,  0,   0,   98,  16,  0,   3,   50,  16,  16,  0,   1,   0,   0,   0,   101, 0,
+    0,  3,   242, 32,  16,  0,   0,   0,   0,   0,   104, 0,   0,   2,   1,   0,   0,   0,   69,
+    0,  0,   9,   242, 0,   16,  0,   0,   0,   0,   0,   70,  16,  16,  0,   1,   0,   0,   0,
+    70, 126, 16,  0,   0,   0,   0,   0,   0,   96,  16,  0,   0,   0,   0,   0,   56,  0,   0,
+    7,  114, 32,  16,  0,   0,   0,   0,   0,   246, 15,  16,  0,   0,   0,   0,   0,   70,  2,
+    16, 0,   0,   0,   0,   0,   54,  0,   0,   5,   130, 32,  16,  0,   0,   0,   0,   0,   1,
+    64, 0,   0,   0,   0,   128, 63,  62,  0,   0,   1,   83,  84,  65,  84,  116, 0,   0,   0,
+    4,  0,   0,   0,   1,   0,   0,   0,   0,   0,   0,   0,   2,   0,   0,   0,   1,   0,   0,
+    0,  0,   0,   0,   0,   0,   0,   0,   0,   1,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+    0,  0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   1,
+    0,  0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+    1,  0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+    0,  0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+    0,  0};
--- a/gfx/angle/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftof_pm_rgba_ps.h
+++ b/gfx/angle/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftof_pm_rgba_ps.h
@@ -1,77 +1,77 @@
-#if 0
-//
-// Generated by Microsoft (R) HLSL Shader Compiler 6.3.9600.16384
-//
-//
-// Resource Bindings:
-//
-// Name                                 Type  Format         Dim Slot Elements
-// ------------------------------ ---------- ------- ----------- ---- --------
-// Sampler                           sampler      NA          NA    0        1
-// TextureF                          texture  float4          2d    0        1
-//
-//
-//
-// Input signature:
-//
-// Name                 Index   Mask Register SysValue  Format   Used
-// -------------------- ----- ------ -------- -------- ------- ------
-// SV_POSITION              0   xyzw        0      POS   float       
-// TEXCOORD                 0   xy          1     NONE   float   xy  
-//
-//
-// Output signature:
-//
-// Name                 Index   Mask Register SysValue  Format   Used
-// -------------------- ----- ------ -------- -------- ------- ------
-// SV_TARGET                0   xyzw        0   TARGET   float   xyzw
-//
-ps_4_0
-dcl_sampler s0, mode_default
-dcl_resource_texture2d (float,float,float,float) t0
-dcl_input_ps linear v1.xy
-dcl_output o0.xyzw
-dcl_temps 1
-sample r0.xyzw, v1.xyxx, t0.xyzw, s0
-mul o0.xyz, r0.wwww, r0.xyzx
-mov o0.w, r0.w
-ret 
-// Approximately 4 instruction slots used
-#endif
-
-const BYTE g_PS_FtoF_PM_RGBA[] = {
-    68, 88,  66,  67,  40,  72,  131, 157, 129, 101, 255, 110, 126, 134, 111, 68,  143, 142, 219,
-    64, 1,   0,   0,   0,   136, 2,   0,   0,   5,   0,   0,   0,   52,  0,   0,   0,   220, 0,
-    0,  0,   52,  1,   0,   0,   104, 1,   0,   0,   12,  2,   0,   0,   82,  68,  69,  70,  160,
-    0,  0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   2,   0,   0,   0,   28,  0,   0,   0,
-    0,  4,   255, 255, 0,   1,   0,   0,   109, 0,   0,   0,   92,  0,   0,   0,   3,   0,   0,
-    0,  0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   1,   0,
-    0,  0,   1,   0,   0,   0,   100, 0,   0,   0,   2,   0,   0,   0,   5,   0,   0,   0,   4,
-    0,  0,   0,   255, 255, 255, 255, 0,   0,   0,   0,   1,   0,   0,   0,   13,  0,   0,   0,
-    83, 97,  109, 112, 108, 101, 114, 0,   84,  101, 120, 116, 117, 114, 101, 70,  0,   77,  105,
-    99, 114, 111, 115, 111, 102, 116, 32,  40,  82,  41,  32,  72,  76,  83,  76,  32,  83,  104,
-    97, 100, 101, 114, 32,  67,  111, 109, 112, 105, 108, 101, 114, 32,  54,  46,  51,  46,  57,
-    54, 48,  48,  46,  49,  54,  51,  56,  52,  0,   171, 73,  83,  71,  78,  80,  0,   0,   0,
-    2,  0,   0,   0,   8,   0,   0,   0,   56,  0,   0,   0,   0,   0,   0,   0,   1,   0,   0,
-    0,  3,   0,   0,   0,   0,   0,   0,   0,   15,  0,   0,   0,   68,  0,   0,   0,   0,   0,
-    0,  0,   0,   0,   0,   0,   3,   0,   0,   0,   1,   0,   0,   0,   3,   3,   0,   0,   83,
-    86, 95,  80,  79,  83,  73,  84,  73,  79,  78,  0,   84,  69,  88,  67,  79,  79,  82,  68,
-    0,  171, 171, 171, 79,  83,  71,  78,  44,  0,   0,   0,   1,   0,   0,   0,   8,   0,   0,
-    0,  32,  0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   3,   0,   0,   0,   0,   0,
-    0,  0,   15,  0,   0,   0,   83,  86,  95,  84,  65,  82,  71,  69,  84,  0,   171, 171, 83,
-    72, 68,  82,  156, 0,   0,   0,   64,  0,   0,   0,   39,  0,   0,   0,   90,  0,   0,   3,
-    0,  96,  16,  0,   0,   0,   0,   0,   88,  24,  0,   4,   0,   112, 16,  0,   0,   0,   0,
-    0,  85,  85,  0,   0,   98,  16,  0,   3,   50,  16,  16,  0,   1,   0,   0,   0,   101, 0,
-    0,  3,   242, 32,  16,  0,   0,   0,   0,   0,   104, 0,   0,   2,   1,   0,   0,   0,   69,
-    0,  0,   9,   242, 0,   16,  0,   0,   0,   0,   0,   70,  16,  16,  0,   1,   0,   0,   0,
-    70, 126, 16,  0,   0,   0,   0,   0,   0,   96,  16,  0,   0,   0,   0,   0,   56,  0,   0,
-    7,  114, 32,  16,  0,   0,   0,   0,   0,   246, 15,  16,  0,   0,   0,   0,   0,   70,  2,
-    16, 0,   0,   0,   0,   0,   54,  0,   0,   5,   130, 32,  16,  0,   0,   0,   0,   0,   58,
-    0,  16,  0,   0,   0,   0,   0,   62,  0,   0,   1,   83,  84,  65,  84,  116, 0,   0,   0,
-    4,  0,   0,   0,   1,   0,   0,   0,   0,   0,   0,   0,   2,   0,   0,   0,   1,   0,   0,
-    0,  0,   0,   0,   0,   0,   0,   0,   0,   1,   0,   0,   0,   0,   0,   0,   0,   0,   0,
-    0,  0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   1,
-    0,  0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
-    1,  0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
-    0,  0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
-    0,  0};
+#if 0
+//
+// Generated by Microsoft (R) HLSL Shader Compiler 6.3.9600.16384
+//
+//
+// Resource Bindings:
+//
+// Name                                 Type  Format         Dim Slot Elements
+// ------------------------------ ---------- ------- ----------- ---- --------
+// Sampler                           sampler      NA          NA    0        1
+// TextureF                          texture  float4          2d    0        1
+//
+//
+//
+// Input signature:
+//
+// Name                 Index   Mask Register SysValue  Format   Used
+// -------------------- ----- ------ -------- -------- ------- ------
+// SV_POSITION              0   xyzw        0      POS   float       
+// TEXCOORD                 0   xy          1     NONE   float   xy  
+//
+//
+// Output signature:
+//
+// Name                 Index   Mask Register SysValue  Format   Used
+// -------------------- ----- ------ -------- -------- ------- ------
+// SV_TARGET                0   xyzw        0   TARGET   float   xyzw
+//
+ps_4_0
+dcl_sampler s0, mode_default
+dcl_resource_texture2d (float,float,float,float) t0
+dcl_input_ps linear v1.xy
+dcl_output o0.xyzw
+dcl_temps 1
+sample r0.xyzw, v1.xyxx, t0.xyzw, s0
+mul o0.xyz, r0.wwww, r0.xyzx
+mov o0.w, r0.w
+ret 
+// Approximately 4 instruction slots used
+#endif
+
+const BYTE g_PS_FtoF_PM_RGBA[] = {
+    68, 88,  66,  67,  40,  72,  131, 157, 129, 101, 255, 110, 126, 134, 111, 68,  143, 142, 219,
+    64, 1,   0,   0,   0,   136, 2,   0,   0,   5,   0,   0,   0,   52,  0,   0,   0,   220, 0,
+    0,  0,   52,  1,   0,   0,   104, 1,   0,   0,   12,  2,   0,   0,   82,  68,  69,  70,  160,
+    0,  0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   2,   0,   0,   0,   28,  0,   0,   0,
+    0,  4,   255, 255, 0,   1,   0,   0,   109, 0,   0,   0,   92,  0,   0,   0,   3,   0,   0,
+    0,  0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   1,   0,
+    0,  0,   1,   0,   0,   0,   100, 0,   0,   0,   2,   0,   0,   0,   5,   0,   0,   0,   4,
+    0,  0,   0,   255, 255, 255, 255, 0,   0,   0,   0,   1,   0,   0,   0,   13,  0,   0,   0,
+    83, 97,  109, 112, 108, 101, 114, 0,   84,  101, 120, 116, 117, 114, 101, 70,  0,   77,  105,
+    99, 114, 111, 115, 111, 102, 116, 32,  40,  82,  41,  32,  72,  76,  83,  76,  32,  83,  104,
+    97, 100, 101, 114, 32,  67,  111, 109, 112, 105, 108, 101, 114, 32,  54,  46,  51,  46,  57,
+    54, 48,  48,  46,  49,  54,  51,  56,  52,  0,   171, 73,  83,  71,  78,  80,  0,   0,   0,
+    2,  0,   0,   0,   8,   0,   0,   0,   56,  0,   0,   0,   0,   0,   0,   0,   1,   0,   0,
+    0,  3,   0,   0,   0,   0,   0,   0,   0,   15,  0,   0,   0,   68,  0,   0,   0,   0,   0,
+    0,  0,   0,   0,   0,   0,   3,   0,   0,   0,   1,   0,   0,   0,   3,   3,   0,   0,   83,
+    86, 95,  80,  79,  83,  73,  84,  73,  79,  78,  0,   84,  69,  88,  67,  79,  79,  82,  68,
+    0,  171, 171, 171, 79,  83,  71,  78,  44,  0,   0,   0,   1,   0,   0,   0,   8,   0,   0,
+    0,  32,  0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   3,   0,   0,   0,   0,   0,
+    0,  0,   15,  0,   0,   0,   83,  86,  95,  84,  65,  82,  71,  69,  84,  0,   171, 171, 83,
+    72, 68,  82,  156, 0,   0,   0,   64,  0,   0,   0,   39,  0,   0,   0,   90,  0,   0,   3,
+    0,  96,  16,  0,   0,   0,   0,   0,   88,  24,  0,   4,   0,   112, 16,  0,   0,   0,   0,
+    0,  85,  85,  0,   0,   98,  16,  0,   3,   50,  16,  16,  0,   1,   0,   0,   0,   101, 0,
+    0,  3,   242, 32,  16,  0,   0,   0,   0,   0,   104, 0,   0,   2,   1,   0,   0,   0,   69,
+    0,  0,   9,   242, 0,   16,  0,   0,   0,   0,   0,   70,  16,  16,  0,   1,   0,   0,   0,
+    70, 126, 16,  0,   0,   0,   0,   0,   0,   96,  16,  0,   0,   0,   0,   0,   56,  0,   0,
+    7,  114, 32,  16,  0,   0,   0,   0,   0,   246, 15,  16,  0,   0,   0,   0,   0,   70,  2,
+    16, 0,   0,   0,   0,   0,   54,  0,   0,   5,   130, 32,  16,  0,   0,   0,   0,   0,   58,
+    0,  16,  0,   0,   0,   0,   0,   62,  0,   0,   1,   83,  84,  65,  84,  116, 0,   0,   0,
+    4,  0,   0,   0,   1,   0,   0,   0,   0,   0,   0,   0,   2,   0,   0,   0,   1,   0,   0,
+    0,  0,   0,   0,   0,   0,   0,   0,   0,   1,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+    0,  0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   1,
+    0,  0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+    1,  0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+    0,  0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+    0,  0};
--- a/gfx/angle/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftof_um_luma_ps.h
+++ b/gfx/angle/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftof_um_luma_ps.h
@@ -1,82 +1,82 @@
-#if 0
-//
-// Generated by Microsoft (R) HLSL Shader Compiler 6.3.9600.16384
-//
-//
-// Resource Bindings:
-//
-// Name                                 Type  Format         Dim Slot Elements
-// ------------------------------ ---------- ------- ----------- ---- --------
-// Sampler                           sampler      NA          NA    0        1
-// TextureF                          texture  float4          2d    0        1
-//
-//
-//
-// Input signature:
-//
-// Name                 Index   Mask Register SysValue  Format   Used
-// -------------------- ----- ------ -------- -------- ------- ------
-// SV_POSITION              0   xyzw        0      POS   float       
-// TEXCOORD                 0   xy          1     NONE   float   xy  
-//
-//
-// Output signature:
-//
-// Name                 Index   Mask Register SysValue  Format   Used
-// -------------------- ----- ------ -------- -------- ------- ------
-// SV_TARGET                0   xyzw        0   TARGET   float   xyzw
-//
-ps_4_0
-dcl_sampler s0, mode_default
-dcl_resource_texture2d (float,float,float,float) t0
-dcl_input_ps linear v1.xy
-dcl_output o0.xyzw
-dcl_temps 2
-sample r0.xyzw, v1.xyxx, t0.xyzw, s0
-lt r1.x, l(0.000000), r0.w
-div r0.w, r0.x, r0.w
-movc o0.xyz, r1.xxxx, r0.wwww, r0.xyzx
-mov o0.w, l(1.000000)
-ret 
-// Approximately 6 instruction slots used
-#endif
-
-const BYTE g_PS_FtoF_UM_LUMA[] = {
-    68,  88,  66,  67,  64,  125, 110, 227, 139, 187, 78,  166, 27,  154, 215, 226, 168, 30,  14,
-    98,  1,   0,   0,   0,   200, 2,   0,   0,   5,   0,   0,   0,   52,  0,   0,   0,   220, 0,
-    0,   0,   52,  1,   0,   0,   104, 1,   0,   0,   76,  2,   0,   0,   82,  68,  69,  70,  160,
-    0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   2,   0,   0,   0,   28,  0,   0,   0,
-    0,   4,   255, 255, 0,   1,   0,   0,   109, 0,   0,   0,   92,  0,   0,   0,   3,   0,   0,
-    0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   1,   0,
-    0,   0,   1,   0,   0,   0,   100, 0,   0,   0,   2,   0,   0,   0,   5,   0,   0,   0,   4,
-    0,   0,   0,   255, 255, 255, 255, 0,   0,   0,   0,   1,   0,   0,   0,   13,  0,   0,   0,
-    83,  97,  109, 112, 108, 101, 114, 0,   84,  101, 120, 116, 117, 114, 101, 70,  0,   77,  105,
-    99,  114, 111, 115, 111, 102, 116, 32,  40,  82,  41,  32,  72,  76,  83,  76,  32,  83,  104,
-    97,  100, 101, 114, 32,  67,  111, 109, 112, 105, 108, 101, 114, 32,  54,  46,  51,  46,  57,
-    54,  48,  48,  46,  49,  54,  51,  56,  52,  0,   171, 73,  83,  71,  78,  80,  0,   0,   0,
-    2,   0,   0,   0,   8,   0,   0,   0,   56,  0,   0,   0,   0,   0,   0,   0,   1,   0,   0,
-    0,   3,   0,   0,   0,   0,   0,   0,   0,   15,  0,   0,   0,   68,  0,   0,   0,   0,   0,
-    0,   0,   0,   0,   0,   0,   3,   0,   0,   0,   1,   0,   0,   0,   3,   3,   0,   0,   83,
-    86,  95,  80,  79,  83,  73,  84,  73,  79,  78,  0,   84,  69,  88,  67,  79,  79,  82,  68,
-    0,   171, 171, 171, 79,  83,  71,  78,  44,  0,   0,   0,   1,   0,   0,   0,   8,   0,   0,
-    0,   32,  0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   3,   0,   0,   0,   0,   0,
-    0,   0,   15,  0,   0,   0,   83,  86,  95,  84,  65,  82,  71,  69,  84,  0,   171, 171, 83,
-    72,  68,  82,  220, 0,   0,   0,   64,  0,   0,   0,   55,  0,   0,   0,   90,  0,   0,   3,
-    0,   96,  16,  0,   0,   0,   0,   0,   88,  24,  0,   4,   0,   112, 16,  0,   0,   0,   0,
-    0,   85,  85,  0,   0,   98,  16,  0,   3,   50,  16,  16,  0,   1,   0,   0,   0,   101, 0,
-    0,   3,   242, 32,  16,  0,   0,   0,   0,   0,   104, 0,   0,   2,   2,   0,   0,   0,   69,
-    0,   0,   9,   242, 0,   16,  0,   0,   0,   0,   0,   70,  16,  16,  0,   1,   0,   0,   0,
-    70,  126, 16,  0,   0,   0,   0,   0,   0,   96,  16,  0,   0,   0,   0,   0,   49,  0,   0,
-    7,   18,  0,   16,  0,   1,   0,   0,   0,   1,   64,  0,   0,   0,   0,   0,   0,   58,  0,
-    16,  0,   0,   0,   0,   0,   14,  0,   0,   7,   130, 0,   16,  0,   0,   0,   0,   0,   10,
-    0,   16,  0,   0,   0,   0,   0,   58,  0,   16,  0,   0,   0,   0,   0,   55,  0,   0,   9,
-    114, 32,  16,  0,   0,   0,   0,   0,   6,   0,   16,  0,   1,   0,   0,   0,   246, 15,  16,
-    0,   0,   0,   0,   0,   70,  2,   16,  0,   0,   0,   0,   0,   54,  0,   0,   5,   130, 32,
-    16,  0,   0,   0,   0,   0,   1,   64,  0,   0,   0,   0,   128, 63,  62,  0,   0,   1,   83,
-    84,  65,  84,  116, 0,   0,   0,   6,   0,   0,   0,   2,   0,   0,   0,   0,   0,   0,   0,
-    2,   0,   0,   0,   2,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   1,   0,   0,
-    0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
-    0,   0,   0,   0,   0,   0,   1,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
-    0,   0,   0,   0,   0,   0,   0,   1,   0,   0,   0,   1,   0,   0,   0,   0,   0,   0,   0,
-    0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
-    0,   0,   0,   0,   0,   0,   0,   0,   0};
+#if 0
+//
+// Generated by Microsoft (R) HLSL Shader Compiler 6.3.9600.16384
+//
+//
+// Resource Bindings:
+//
+// Name                                 Type  Format         Dim Slot Elements
+// ------------------------------ ---------- ------- ----------- ---- --------
+// Sampler                           sampler      NA          NA    0        1
+// TextureF                          texture  float4          2d    0        1
+//
+//
+//
+// Input signature:
+//
+// Name                 Index   Mask Register SysValue  Format   Used
+// -------------------- ----- ------ -------- -------- ------- ------
+// SV_POSITION              0   xyzw        0      POS   float       
+// TEXCOORD                 0   xy          1     NONE   float   xy  
+//
+//
+// Output signature:
+//
+// Name                 Index   Mask Register SysValue  Format   Used
+// -------------------- ----- ------ -------- -------- ------- ------
+// SV_TARGET                0   xyzw        0   TARGET   float   xyzw
+//
+ps_4_0
+dcl_sampler s0, mode_default
+dcl_resource_texture2d (float,float,float,float) t0
+dcl_input_ps linear v1.xy
+dcl_output o0.xyzw
+dcl_temps 2
+sample r0.xyzw, v1.xyxx, t0.xyzw, s0
+lt r1.x, l(0.000000), r0.w
+div r0.w, r0.x, r0.w
+movc o0.xyz, r1.xxxx, r0.wwww, r0.xyzx
+mov o0.w, l(1.000000)
+ret 
+// Approximately 6 instruction slots used
+#endif
+
+const BYTE g_PS_FtoF_UM_LUMA[] = {
+    68,  88,  66,  67,  64,  125, 110, 227, 139, 187, 78,  166, 27,  154, 215, 226, 168, 30,  14,
+    98,  1,   0,   0,   0,   200, 2,   0,   0,   5,   0,   0,   0,   52,  0,   0,   0,   220, 0,
+    0,   0,   52,  1,   0,   0,   104, 1,   0,   0,   76,  2,   0,   0,   82,  68,  69,  70,  160,
+    0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   2,   0,   0,   0,   28,  0,   0,   0,
+    0,   4,   255, 255, 0,   1,   0,   0,   109, 0,   0,   0,   92,  0,   0,   0,   3,   0,   0,
+    0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   1,   0,
+    0,   0,   1,   0,   0,   0,   100, 0,   0,   0,   2,   0,   0,   0,   5,   0,   0,   0,   4,
+    0,   0,   0,   255, 255, 255, 255, 0,   0,   0,   0,   1,   0,   0,   0,   13,  0,   0,   0,
+    83,  97,  109, 112, 108, 101, 114, 0,   84,  101, 120, 116, 117, 114, 101, 70,  0,   77,  105,
+    99,  114, 111, 115, 111, 102, 116, 32,  40,  82,  41,  32,  72,  76,  83,  76,  32,  83,  104,
+    97,  100, 101, 114, 32,  67,  111, 109, 112, 105, 108, 101, 114, 32,  54,  46,  51,  46,  57,
+    54,  48,  48,  46,  49,  54,  51,  56,  52,  0,   171, 73,  83,  71,  78,  80,  0,   0,   0,
+    2,   0,   0,   0,   8,   0,   0,   0,   56,  0,   0,   0,   0,   0,   0,   0,   1,   0,   0,
+    0,   3,   0,   0,   0,   0,   0,   0,   0,   15,  0,   0,   0,   68,  0,   0,   0,   0,   0,
+    0,   0,   0,   0,   0,   0,   3,   0,   0,   0,   1,   0,   0,   0,   3,   3,   0,   0,   83,
+    86,  95,  80,  79,  83,  73,  84,  73,  79,  78,  0,   84,  69,  88,  67,  79,  79,  82,  68,
+    0,   171, 171, 171, 79,  83,  71,  78,  44,  0,   0,   0,   1,   0,   0,   0,   8,   0,   0,
+    0,   32,  0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   3,   0,   0,   0,   0,   0,
+    0,   0,   15,  0,   0,   0,   83,  86,  95,  84,  65,  82,  71,  69,  84,  0,   171, 171, 83,
+    72,  68,  82,  220, 0,   0,   0,   64,  0,   0,   0,   55,  0,   0,   0,   90,  0,   0,   3,
+    0,   96,  16,  0,   0,   0,   0,   0,   88,  24,  0,   4,   0,   112, 16,  0,   0,   0,   0,
+    0,   85,  85,  0,   0,   98,  16,  0,   3,   50,  16,  16,  0,   1,   0,   0,   0,   101, 0,
+    0,   3,   242, 32,  16,  0,   0,   0,   0,   0,   104, 0,   0,   2,   2,   0,   0,   0,   69,
+    0,   0,   9,   242, 0,   16,  0,   0,   0,   0,   0,   70,  16,  16,  0,   1,   0,   0,   0,
+    70,  126, 16,  0,   0,   0,   0,   0,   0,   96,  16,  0,   0,   0,   0,   0,   49,  0,   0,
+    7,   18,  0,   16,  0,   1,   0,   0,   0,   1,   64,  0,   0,   0,   0,   0,   0,   58,  0,
+    16,  0,   0,   0,   0,   0,   14,  0,   0,   7,   130, 0,   16,  0,   0,   0,   0,   0,   10,
+    0,   16,  0,   0,   0,   0,   0,   58,  0,   16,  0,   0,   0,   0,   0,   55,  0,   0,   9,
+    114, 32,  16,  0,   0,   0,   0,   0,   6,   0,   16,  0,   1,   0,   0,   0,   246, 15,  16,
+    0,   0,   0,   0,   0,   70,  2,   16,  0,   0,   0,   0,   0,   54,  0,   0,   5,   130, 32,
+    16,  0,   0,   0,   0,   0,   1,   64,  0,   0,   0,   0,   128, 63,  62,  0,   0,   1,   83,
+    84,  65,  84,  116, 0,   0,   0,   6,   0,   0,   0,   2,   0,   0,   0,   0,   0,   0,   0,
+    2,   0,   0,   0,   2,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   1,   0,   0,
+    0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+    0,   0,   0,   0,   0,   0,   1,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+    0,   0,   0,   0,   0,   0,   0,   1,   0,   0,   0,   1,   0,   0,   0,   0,   0,   0,   0,
+    0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+    0,   0,   0,   0,   0,   0,   0,   0,   0};
--- a/gfx/angle/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftof_um_lumaalpha_ps.h
+++ b/gfx/angle/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftof_um_lumaalpha_ps.h
@@ -1,82 +1,82 @@
-#if 0
-//
-// Generated by Microsoft (R) HLSL Shader Compiler 6.3.9600.16384
-//
-//
-// Resource Bindings:
-//
-// Name                                 Type  Format         Dim Slot Elements
-// ------------------------------ ---------- ------- ----------- ---- --------
-// Sampler                           sampler      NA          NA    0        1
-// TextureF                          texture  float4          2d    0        1
-//
-//
-//
-// Input signature:
-//
-// Name                 Index   Mask Register SysValue  Format   Used
-// -------------------- ----- ------ -------- -------- ------- ------
-// SV_POSITION              0   xyzw        0      POS   float       
-// TEXCOORD                 0   xy          1     NONE   float   xy  
-//
-//
-// Output signature:
-//
-// Name                 Index   Mask Register SysValue  Format   Used
-// -------------------- ----- ------ -------- -------- ------- ------
-// SV_TARGET                0   xyzw        0   TARGET   float   xyzw
-//
-ps_4_0
-dcl_sampler s0, mode_default
-dcl_resource_texture2d (float,float,float,float) t0
-dcl_input_ps linear v1.xy
-dcl_output o0.xyzw
-dcl_temps 2
-sample r0.xyzw, v1.xyxx, t0.xyzw, s0
-lt r1.x, l(0.000000), r0.w
-div r1.y, r0.x, r0.w
-movc o0.xyz, r1.xxxx, r1.yyyy, r0.xyzx
-mov o0.w, r0.w
-ret 
-// Approximately 6 instruction slots used
-#endif
-
-const BYTE g_PS_FtoF_UM_LUMAALPHA[] = {
-    68,  88,  66,  67,  108, 4,   157, 10,  254, 47,  42,  8,   219, 0,   94,  160, 25,  199, 73,
-    60,  1,   0,   0,   0,   200, 2,   0,   0,   5,   0,   0,   0,   52,  0,   0,   0,   220, 0,
-    0,   0,   52,  1,   0,   0,   104, 1,   0,   0,   76,  2,   0,   0,   82,  68,  69,  70,  160,
-    0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   2,   0,   0,   0,   28,  0,   0,   0,
-    0,   4,   255, 255, 0,   1,   0,   0,   109, 0,   0,   0,   92,  0,   0,   0,   3,   0,   0,
-    0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   1,   0,
-    0,   0,   1,   0,   0,   0,   100, 0,   0,   0,   2,   0,   0,   0,   5,   0,   0,   0,   4,
-    0,   0,   0,   255, 255, 255, 255, 0,   0,   0,   0,   1,   0,   0,   0,   13,  0,   0,   0,
-    83,  97,  109, 112, 108, 101, 114, 0,   84,  101, 120, 116, 117, 114, 101, 70,  0,   77,  105,
-    99,  114, 111, 115, 111, 102, 116, 32,  40,  82,  41,  32,  72,  76,  83,  76,  32,  83,  104,
-    97,  100, 101, 114, 32,  67,  111, 109, 112, 105, 108, 101, 114, 32,  54,  46,  51,  46,  57,
-    54,  48,  48,  46,  49,  54,  51,  56,  52,  0,   171, 73,  83,  71,  78,  80,  0,   0,   0,
-    2,   0,   0,   0,   8,   0,   0,   0,   56,  0,   0,   0,   0,   0,   0,   0,   1,   0,   0,
-    0,   3,   0,   0,   0,   0,   0,   0,   0,   15,  0,   0,   0,   68,  0,   0,   0,   0,   0,
-    0,   0,   0,   0,   0,   0,   3,   0,   0,   0,   1,   0,   0,   0,   3,   3,   0,   0,   83,
-    86,  95,  80,  79,  83,  73,  84,  73,  79,  78,  0,   84,  69,  88,  67,  79,  79,  82,  68,
-    0,   171, 171, 171, 79,  83,  71,  78,  44,  0,   0,   0,   1,   0,   0,   0,   8,   0,   0,
-    0,   32,  0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   3,   0,   0,   0,   0,   0,
-    0,   0,   15,  0,   0,   0,   83,  86,  95,  84,  65,  82,  71,  69,  84,  0,   171, 171, 83,
-    72,  68,  82,  220, 0,   0,   0,   64,  0,   0,   0,   55,  0,   0,   0,   90,  0,   0,   3,
-    0,   96,  16,  0,   0,   0,   0,   0,   88,  24,  0,   4,   0,   112, 16,  0,   0,   0,   0,
-    0,   85,  85,  0,   0,   98,  16,  0,   3,   50,  16,  16,  0,   1,   0,   0,   0,   101, 0,
-    0,   3,   242, 32,  16,  0,   0,   0,   0,   0,   104, 0,   0,   2,   2,   0,   0,   0,   69,
-    0,   0,   9,   242, 0,   16,  0,   0,   0,   0,   0,   70,  16,  16,  0,   1,   0,   0,   0,
-    70,  126, 16,  0,   0,   0,   0,   0,   0,   96,  16,  0,   0,   0,   0,   0,   49,  0,   0,
-    7,   18,  0,   16,  0,   1,   0,   0,   0,   1,   64,  0,   0,   0,   0,   0,   0,   58,  0,
-    16,  0,   0,   0,   0,   0,   14,  0,   0,   7,   34,  0,   16,  0,   1,   0,   0,   0,   10,
-    0,   16,  0,   0,   0,   0,   0,   58,  0,   16,  0,   0,   0,   0,   0,   55,  0,   0,   9,
-    114, 32,  16,  0,   0,   0,   0,   0,   6,   0,   16,  0,   1,   0,   0,   0,   86,  5,   16,
-    0,   1,   0,   0,   0,   70,  2,   16,  0,   0,   0,   0,   0,   54,  0,   0,   5,   130, 32,
-    16,  0,   0,   0,   0,   0,   58,  0,   16,  0,   0,   0,   0,   0,   62,  0,   0,   1,   83,
-    84,  65,  84,  116, 0,   0,   0,   6,   0,   0,   0,   2,   0,   0,   0,   0,   0,   0,   0,
-    2,   0,   0,   0,   2,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   1,   0,   0,
-    0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
-    0,   0,   0,   0,   0,   0,   1,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
-    0,   0,   0,   0,   0,   0,   0,   1,   0,   0,   0,   1,   0,   0,   0,   0,   0,   0,   0,
-    0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
-    0,   0,   0,   0,   0,   0,   0,   0,   0};
+#if 0
+//
+// Generated by Microsoft (R) HLSL Shader Compiler 6.3.9600.16384
+//
+//
+// Resource Bindings:
+//
+// Name                                 Type  Format         Dim Slot Elements
+// ------------------------------ ---------- ------- ----------- ---- --------
+// Sampler                           sampler      NA          NA    0        1
+// TextureF                          texture  float4          2d    0        1
+//
+//
+//
+// Input signature:
+//
+// Name                 Index   Mask Register SysValue  Format   Used
+// -------------------- ----- ------ -------- -------- ------- ------
+// SV_POSITION              0   xyzw        0      POS   float       
+// TEXCOORD                 0   xy          1     NONE   float   xy  
+//
+//
+// Output signature:
+//
+// Name                 Index   Mask Register SysValue  Format   Used
+// -------------------- ----- ------ -------- -------- ------- ------
+// SV_TARGET                0   xyzw        0   TARGET   float   xyzw
+//
+ps_4_0
+dcl_sampler s0, mode_default
+dcl_resource_texture2d (float,float,float,float) t0
+dcl_input_ps linear v1.xy
+dcl_output o0.xyzw
+dcl_temps 2
+sample r0.xyzw, v1.xyxx, t0.xyzw, s0
+lt r1.x, l(0.000000), r0.w
+div r1.y, r0.x, r0.w
+movc o0.xyz, r1.xxxx, r1.yyyy, r0.xyzx
+mov o0.w, r0.w
+ret 
+// Approximately 6 instruction slots used
+#endif
+
+const BYTE g_PS_FtoF_UM_LUMAALPHA[] = {
+    68,  88,  66,  67,  108, 4,   157, 10,  254, 47,  42,  8,   219, 0,   94,  160, 25,  199, 73,
+    60,  1,   0,   0,   0,   200, 2,   0,   0,   5,   0,   0,   0,   52,  0,   0,   0,   220, 0,
+    0,   0,   52,  1,   0,   0,   104, 1,   0,   0,   76,  2,   0,   0,   82,  68,  69,  70,  160,
+    0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   2,   0,   0,   0,   28,  0,   0,   0,
+    0,   4,   255, 255, 0,   1,   0,   0,   109, 0,   0,   0,   92,  0,   0,   0,   3,   0,   0,
+    0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   1,   0,
+    0,   0,   1,   0,   0,   0,   100, 0,   0,   0,   2,   0,   0,   0,   5,   0,   0,   0,   4,
+    0,   0,   0,   255, 255, 255, 255, 0,   0,   0,   0,   1,   0,   0,   0,   13,  0,   0,   0,
+    83,  97,  109, 112, 108, 101, 114, 0,   84,  101, 120, 116, 117, 114, 101, 70,  0,   77,  105,
+    99,  114, 111, 115, 111, 102, 116, 32,  40,  82,  41,  32,  72,  76,  83,  76,  32,  83,  104,
+    97,  100, 101, 114, 32,  67,  111, 109, 112, 105, 108, 101, 114, 32,  54,  46,  51,  46,  57,
+    54,  48,  48,  46,  49,  54,  51,  56,  52,  0,   171, 73,  83,  71,  78,  80,  0,   0,   0,
+    2,   0,   0,   0,   8,   0,   0,   0,   56,  0,   0,   0,   0,   0,   0,   0,   1,   0,   0,
+    0,   3,   0,   0,   0,   0,   0,   0,   0,   15,  0,   0,   0,   68,  0,   0,   0,   0,   0,
+    0,   0,   0,   0,   0,   0,   3,   0,   0,   0,   1,   0,   0,   0,   3,   3,   0,   0,   83,
+    86,  95,  80,  79,  83,  73,  84,  73,  79,  78,  0,   84,  69,  88,  67,  79,  79,  82,  68,
+    0,   171, 171, 171, 79,  83,  71,  78,  44,  0,   0,   0,   1,   0,   0,   0,   8,   0,   0,
+    0,   32,  0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   3,   0,   0,   0,   0,   0,
+    0,   0,   15,  0,   0,   0,   83,  86,  95,  84,  65,  82,  71,  69,  84,  0,   171, 171, 83,
+    72,  68,  82,  220, 0,   0,   0,   64,  0,   0,   0,   55,  0,   0,   0,   90,  0,   0,   3,
+    0,   96,  16,  0,   0,   0,   0,   0,   88,  24,  0,   4,   0,   112, 16,  0,   0,   0,   0,
+    0,   85,  85,  0,   0,   98,  16,  0,   3,   50,  16,  16,  0,   1,   0,   0,   0,   101, 0,
+    0,   3,   242, 32,  16,  0,   0,   0,   0,   0,   104, 0,   0,   2,   2,   0,   0,   0,   69,
+    0,   0,   9,   242, 0,   16,  0,   0,   0,   0,   0,   70,  16,  16,  0,   1,   0,   0,   0,
+    70,  126, 16,  0,   0,   0,   0,   0,   0,   96,  16,  0,   0,   0,   0,   0,   49,  0,   0,
+    7,   18,  0,   16,  0,   1,   0,   0,   0,   1,   64,  0,   0,   0,   0,   0,   0,   58,  0,
+    16,  0,   0,   0,   0,   0,   14,  0,   0,   7,   34,  0,   16,  0,   1,   0,   0,   0,   10,
+    0,   16,  0,   0,   0,   0,   0,   58,  0,   16,  0,   0,   0,   0,   0,   55,  0,   0,   9,
+    114, 32,  16,  0,   0,   0,   0,   0,   6,   0,   16,  0,   1,   0,   0,   0,   86,  5,   16,
+    0,   1,   0,   0,   0,   70,  2,   16,  0,   0,   0,   0,   0,   54,  0,   0,   5,   130, 32,
+    16,  0,   0,   0,   0,   0,   58,  0,   16,  0,   0,   0,   0,   0,   62,  0,   0,   1,   83,
+    84,  65,  84,  116, 0,   0,   0,   6,   0,   0,   0,   2,   0,   0,   0,   0,   0,   0,   0,
+    2,   0,   0,   0,   2,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   1,   0,   0,
+    0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+    0,   0,   0,   0,   0,   0,   1,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+    0,   0,   0,   0,   0,   0,   0,   1,   0,   0,   0,   1,   0,   0,   0,   0,   0,   0,   0,
+    0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+    0,   0,   0,   0,   0,   0,   0,   0,   0};
--- a/gfx/angle/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftof_um_rgb_ps.h
+++ b/gfx/angle/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftof_um_rgb_ps.h
@@ -1,82 +1,82 @@
-#if 0
-//
-// Generated by Microsoft (R) HLSL Shader Compiler 6.3.9600.16384
-//
-//
-// Resource Bindings:
-//
-// Name                                 Type  Format         Dim Slot Elements
-// ------------------------------ ---------- ------- ----------- ---- --------
-// Sampler                           sampler      NA          NA    0        1
-// TextureF                          texture  float4          2d    0        1
-//
-//
-//
-// Input signature:
-//
-// Name                 Index   Mask Register SysValue  Format   Used
-// -------------------- ----- ------ -------- -------- ------- ------
-// SV_POSITION              0   xyzw        0      POS   float       
-// TEXCOORD                 0   xy          1     NONE   float   xy  
-//
-//
-// Output signature:
-//
-// Name                 Index   Mask Register SysValue  Format   Used
-// -------------------- ----- ------ -------- -------- ------- ------
-// SV_TARGET                0   xyzw        0   TARGET   float   xyzw
-//
-ps_4_0
-dcl_sampler s0, mode_default
-dcl_resource_texture2d (float,float,float,float) t0
-dcl_input_ps linear v1.xy
-dcl_output o0.xyzw
-dcl_temps 2
-sample r0.xyzw, v1.xyxx, t0.xyzw, s0
-lt r1.x, l(0.000000), r0.w
-div r1.yzw, r0.xxyz, r0.wwww
-movc o0.xyz, r1.xxxx, r1.yzwy, r0.xyzx
-mov o0.w, l(1.000000)
-ret 
-// Approximately 6 instruction slots used
-#endif
-
-const BYTE g_PS_FtoF_UM_RGB[] = {
-    68,  88,  66,  67,  14,  170, 220, 126, 255, 181, 163, 175, 235, 22,  242, 166, 140, 110, 63,
-    74,  1,   0,   0,   0,   200, 2,   0,   0,   5,   0,   0,   0,   52,  0,   0,   0,   220, 0,
-    0,   0,   52,  1,   0,   0,   104, 1,   0,   0,   76,  2,   0,   0,   82,  68,  69,  70,  160,
-    0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   2,   0,   0,   0,   28,  0,   0,   0,
-    0,   4,   255, 255, 0,   1,   0,   0,   109, 0,   0,   0,   92,  0,   0,   0,   3,   0,   0,
-    0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   1,   0,
-    0,   0,   1,   0,   0,   0,   100, 0,   0,   0,   2,   0,   0,   0,   5,   0,   0,   0,   4,
-    0,   0,   0,   255, 255, 255, 255, 0,   0,   0,   0,   1,   0,   0,   0,   13,  0,   0,   0,
-    83,  97,  109, 112, 108, 101, 114, 0,   84,  101, 120, 116, 117, 114, 101, 70,  0,   77,  105,
-    99,  114, 111, 115, 111, 102, 116, 32,  40,  82,  41,  32,  72,  76,  83,  76,  32,  83,  104,
-    97,  100, 101, 114, 32,  67,  111, 109, 112, 105, 108, 101, 114, 32,  54,  46,  51,  46,  57,
-    54,  48,  48,  46,  49,  54,  51,  56,  52,  0,   171, 73,  83,  71,  78,  80,  0,   0,   0,
-    2,   0,   0,   0,   8,   0,   0,   0,   56,  0,   0,   0,   0,   0,   0,   0,   1,   0,   0,
-    0,   3,   0,   0,   0,   0,   0,   0,   0,   15,  0,   0,   0,   68,  0,   0,   0,   0,   0,
-    0,   0,   0,   0,   0,   0,   3,   0,   0,   0,   1,   0,   0,   0,   3,   3,   0,   0,   83,
-    86,  95,  80,  79,  83,  73,  84,  73,  79,  78,  0,   84,  69,  88,  67,  79,  79,  82,  68,
-    0,   171, 171, 171, 79,  83,  71,  78,  44,  0,   0,   0,   1,   0,   0,   0,   8,   0,   0,
-    0,   32,  0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   3,   0,   0,   0,   0,   0,
-    0,   0,   15,  0,   0,   0,   83,  86,  95,  84,  65,  82,  71,  69,  84,  0,   171, 171, 83,
-    72,  68,  82,  220, 0,   0,   0,   64,  0,   0,   0,   55,  0,   0,   0,   90,  0,   0,   3,
-    0,   96,  16,  0,   0,   0,   0,   0,   88,  24,  0,   4,   0,   112, 16,  0,   0,   0,   0,
-    0,   85,  85,  0,   0,   98,  16,  0,   3,   50,  16,  16,  0,   1,   0,   0,   0,   101, 0,
-    0,   3,   242, 32,  16,  0,   0,   0,   0,   0,   104, 0,   0,   2,   2,   0,   0,   0,   69,
-    0,   0,   9,   242, 0,   16,  0,   0,   0,   0,   0,   70,  16,  16,  0,   1,   0,   0,   0,
-    70,  126, 16,  0,   0,   0,   0,   0,   0,   96,  16,  0,   0,   0,   0,   0,   49,  0,   0,
-    7,   18,  0,   16,  0,   1,   0,   0,   0,   1,   64,  0,   0,   0,   0,   0,   0,   58,  0,
-    16,  0,   0,   0,   0,   0,   14,  0,   0,   7,   226, 0,   16,  0,   1,   0,   0,   0,   6,
-    9,   16,  0,   0,   0,   0,   0,   246, 15,  16,  0,   0,   0,   0,   0,   55,  0,   0,   9,
-    114, 32,  16,  0,   0,   0,   0,   0,   6,   0,   16,  0,   1,   0,   0,   0,   150, 7,   16,
-    0,   1,   0,   0,   0,   70,  2,   16,  0,   0,   0,   0,   0,   54,  0,   0,   5,   130, 32,
-    16,  0,   0,   0,   0,   0,   1,   64,  0,   0,   0,   0,   128, 63,  62,  0,   0,   1,   83,
-    84,  65,  84,  116, 0,   0,   0,   6,   0,   0,   0,   2,   0,   0,   0,   0,   0,   0,   0,
-    2,   0,   0,   0,   2,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   1,   0,   0,
-    0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
-    0,   0,   0,   0,   0,   0,   1,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
-    0,   0,   0,   0,   0,   0,   0,   1,   0,   0,   0,   1,   0,   0,   0,   0,   0,   0,   0,
-    0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
-    0,   0,   0,   0,   0,   0,   0,   0,   0};
+#if 0
+//
+// Generated by Microsoft (R) HLSL Shader Compiler 6.3.9600.16384
+//
+//
+// Resource Bindings:
+//
+// Name                                 Type  Format         Dim Slot Elements
+// ------------------------------ ---------- ------- ----------- ---- --------
+// Sampler                           sampler      NA          NA    0        1
+// TextureF                          texture  float4          2d    0        1
+//
+//
+//
+// Input signature:
+//
+// Name                 Index   Mask Register SysValue  Format   Used
+// -------------------- ----- ------ -------- -------- ------- ------
+// SV_POSITION              0   xyzw        0      POS   float       
+// TEXCOORD                 0   xy          1     NONE   float   xy  
+//
+//
+// Output signature:
+//
+// Name                 Index   Mask Register SysValue  Format   Used
+// -------------------- ----- ------ -------- -------- ------- ------
+// SV_TARGET                0   xyzw        0   TARGET   float   xyzw
+//
+ps_4_0
+dcl_sampler s0, mode_default
+dcl_resource_texture2d (float,float,float,float) t0
+dcl_input_ps linear v1.xy
+dcl_output o0.xyzw
+dcl_temps 2
+sample r0.xyzw, v1.xyxx, t0.xyzw, s0
+lt r1.x, l(0.000000), r0.w
+div r1.yzw, r0.xxyz, r0.wwww
+movc o0.xyz, r1.xxxx, r1.yzwy, r0.xyzx
+mov o0.w, l(1.000000)
+ret 
+// Approximately 6 instruction slots used
+#endif
+
+const BYTE g_PS_FtoF_UM_RGB[] = {
+    68,  88,  66,  67,  14,  170, 220, 126, 255, 181, 163, 175, 235, 22,  242, 166, 140, 110, 63,
+    74,  1,   0,   0,   0,   200, 2,   0,   0,   5,   0,   0,   0,   52,  0,   0,   0,   220, 0,
+    0,   0,   52,  1,   0,   0,   104, 1,   0,   0,   76,  2,   0,   0,   82,  68,  69,  70,  160,
+    0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   2,   0,   0,   0,   28,  0,   0,   0,
+    0,   4,   255, 255, 0,   1,   0,   0,   109, 0,   0,   0,   92,  0,   0,   0,   3,   0,   0,
+    0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   1,   0,
+    0,   0,   1,   0,   0,   0,   100, 0,   0,   0,   2,   0,   0,   0,   5,   0,   0,   0,   4,
+    0,   0,   0,   255, 255, 255, 255, 0,   0,   0,   0,   1,   0,   0,   0,   13,  0,   0,   0,
+    83,  97,  109, 112, 108, 101, 114, 0,   84,  101, 120, 116, 117, 114, 101, 70,  0,   77,  105,
+    99,  114, 111, 115, 111, 102, 116, 32,  40,  82,  41,  32,  72,  76,  83,  76,  32,  83,  104,
+    97,  100, 101, 114, 32,  67,  111, 109, 112, 105, 108, 101, 114, 32,  54,  46,  51,  46,  57,
+    54,  48,  48,  46,  49,  54,  51,  56,  52,  0,   171, 73,  83,  71,  78,  80,  0,   0,   0,
+    2,   0,   0,   0,   8,   0,   0,   0,   56,  0,   0,   0,   0,   0,   0,   0,   1,   0,   0,
+    0,   3,   0,   0,   0,   0,   0,   0,   0,   15,  0,   0,   0,   68,  0,   0,   0,   0,   0,
+    0,   0,   0,   0,   0,   0,   3,   0,   0,   0,   1,   0,   0,   0,   3,   3,   0,   0,   83,
+    86,  95,  80,  79,  83,  73,  84,  73,  79,  78,  0,   84,  69,  88,  67,  79,  79,  82,  68,
+    0,   171, 171, 171, 79,  83,  71,  78,  44,  0,   0,   0,   1,   0,   0,   0,   8,   0,   0,
+    0,   32,  0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   3,   0,   0,   0,   0,   0,
+    0,   0,   15,  0,   0,   0,   83,  86,  95,  84,  65,  82,  71,  69,  84,  0,   171, 171, 83,
+    72,  68,  82,  220, 0,   0,   0,   64,  0,   0,   0,   55,  0,   0,   0,   90,  0,   0,   3,
+    0,   96,  16,  0,   0,   0,   0,   0,   88,  24,  0,   4,   0,   112, 16,  0,   0,   0,   0,
+    0,   85,  85,  0,   0,   98,  16,  0,   3,   50,  16,  16,  0,   1,   0,   0,   0,   101, 0,
+    0,   3,   242, 32,  16,  0,   0,   0,   0,   0,   104, 0,   0,   2,   2,   0,   0,   0,   69,
+    0,   0,   9,   242, 0,   16,  0,   0,   0,   0,   0,   70,  16,  16,  0,   1,   0,   0,   0,
+    70,  126, 16,  0,   0,   0,   0,   0,   0,   96,  16,  0,   0,   0,   0,   0,   49,  0,   0,
+    7,   18,  0,   16,  0,   1,   0,   0,   0,   1,   64,  0,   0,   0,   0,   0,   0,   58,  0,
+    16,  0,   0,   0,   0,   0,   14,  0,   0,   7,   226, 0,   16,  0,   1,   0,   0,   0,   6,
+    9,   16,  0,   0,   0,   0,   0,   246, 15,  16,  0,   0,   0,   0,   0,   55,  0,   0,   9,
+    114, 32,  16,  0,   0,   0,   0,   0,   6,   0,   16,  0,   1,   0,   0,   0,   150, 7,   16,
+    0,   1,   0,   0,   0,   70,  2,   16,  0,   0,   0,   0,   0,   54,  0,   0,   5,   130, 32,
+    16,  0,   0,   0,   0,   0,   1,   64,  0,   0,   0,   0,   128, 63,  62,  0,   0,   1,   83,
+    84,  65,  84,  116, 0,   0,   0,   6,   0,   0,   0,   2,   0,   0,   0,   0,   0,   0,   0,
+    2,   0,   0,   0,   2,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   1,   0,   0,
+    0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+    0,   0,   0,   0,   0,   0,   1,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+    0,   0,   0,   0,   0,   0,   0,   1,   0,   0,   0,   1,   0,   0,   0,   0,   0,   0,   0,
+    0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+    0,   0,   0,   0,   0,   0,   0,   0,   0};
--- a/gfx/angle/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftof_um_rgba_ps.h
+++ b/gfx/angle/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftof_um_rgba_ps.h
@@ -1,82 +1,82 @@
-#if 0
-//
-// Generated by Microsoft (R) HLSL Shader Compiler 6.3.9600.16384
-//
-//
-// Resource Bindings:
-//
-// Name                                 Type  Format         Dim Slot Elements
-// ------------------------------ ---------- ------- ----------- ---- --------
-// Sampler                           sampler      NA          NA    0        1
-// TextureF                          texture  float4          2d    0        1
-//
-//
-//
-// Input signature:
-//
-// Name                 Index   Mask Register SysValue  Format   Used
-// -------------------- ----- ------ -------- -------- ------- ------
-// SV_POSITION              0   xyzw        0      POS   float       
-// TEXCOORD                 0   xy          1     NONE   float   xy  
-//
-//
-// Output signature:
-//
-// Name                 Index   Mask Register SysValue  Format   Used
-// -------------------- ----- ------ -------- -------- ------- ------
-// SV_TARGET                0   xyzw        0   TARGET   float   xyzw
-//
-ps_4_0
-dcl_sampler s0, mode_default
-dcl_resource_texture2d (float,float,float,float) t0
-dcl_input_ps linear v1.xy
-dcl_output o0.xyzw
-dcl_temps 2
-sample r0.xyzw, v1.xyxx, t0.xyzw, s0
-lt r1.x, l(0.000000), r0.w
-div r1.yzw, r0.xxyz, r0.wwww
-movc o0.xyz, r1.xxxx, r1.yzwy, r0.xyzx
-mov o0.w, r0.w
-ret 
-// Approximately 6 instruction slots used
-#endif
-
-const BYTE g_PS_FtoF_UM_RGBA[] = {
-    68,  88,  66,  67,  186, 41,  193, 245, 39,  138, 185, 101, 12,  196, 111, 158, 103, 199, 2,
-    40,  1,   0,   0,   0,   200, 2,   0,   0,   5,   0,   0,   0,   52,  0,   0,   0,   220, 0,
-    0,   0,   52,  1,   0,   0,   104, 1,   0,   0,   76,  2,   0,   0,   82,  68,  69,  70,  160,
-    0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   2,   0,   0,   0,   28,  0,   0,   0,
-    0,   4,   255, 255, 0,   1,   0,   0,   109, 0,   0,   0,   92,  0,   0,   0,   3,   0,   0,
-    0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   1,   0,
-    0,   0,   1,   0,   0,   0,   100, 0,   0,   0,   2,   0,   0,   0,   5,   0,   0,   0,   4,
-    0,   0,   0,   255, 255, 255, 255, 0,   0,   0,   0,   1,   0,   0,   0,   13,  0,   0,   0,
-    83,  97,  109, 112, 108, 101, 114, 0,   84,  101, 120, 116, 117, 114, 101, 70,  0,   77,  105,
-    99,  114, 111, 115, 111, 102, 116, 32,  40,  82,  41,  32,  72,  76,  83,  76,  32,  83,  104,
-    97,  100, 101, 114, 32,  67,  111, 109, 112, 105, 108, 101, 114, 32,  54,  46,  51,  46,  57,
-    54,  48,  48,  46,  49,  54,  51,  56,  52,  0,   171, 73,  83,  71,  78,  80,  0,   0,   0,
-    2,   0,   0,   0,   8,   0,   0,   0,   56,  0,   0,   0,   0,   0,   0,   0,   1,   0,   0,
-    0,   3,   0,   0,   0,   0,   0,   0,   0,   15,  0,   0,   0,   68,  0,   0,   0,   0,   0,
-    0,   0,   0,   0,   0,   0,   3,   0,   0,   0,   1,   0,   0,   0,   3,   3,   0,   0,   83,
-    86,  95,  80,  79,  83,  73,  84,  73,  79,  78,  0,   84,  69,  88,  67,  79,  79,  82,  68,
-    0,   171, 171, 171, 79,  83,  71,  78,  44,  0,   0,   0,   1,   0,   0,   0,   8,   0,   0,
-    0,   32,  0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   3,   0,   0,   0,   0,   0,
-    0,   0,   15,  0,   0,   0,   83,  86,  95,  84,  65,  82,  71,  69,  84,  0,   171, 171, 83,
-    72,  68,  82,  220, 0,   0,   0,   64,  0,   0,   0,   55,  0,   0,   0,   90,  0,   0,   3,
-    0,   96,  16,  0,   0,   0,   0,   0,   88,  24,  0,   4,   0,   112, 16,  0,   0,   0,   0,
-    0,   85,  85,  0,   0,   98,  16,  0,   3,   50,  16,  16,  0,   1,   0,   0,   0,   101, 0,
-    0,   3,   242, 32,  16,  0,   0,   0,   0,   0,   104, 0,   0,   2,   2,   0,   0,   0,   69,
-    0,   0,   9,   242, 0,   16,  0,   0,   0,   0,   0,   70,  16,  16,  0,   1,   0,   0,   0,
-    70,  126, 16,  0,   0,   0,   0,   0,   0,   96,  16,  0,   0,   0,   0,   0,   49,  0,   0,
-    7,   18,  0,   16,  0,   1,   0,   0,   0,   1,   64,  0,   0,   0,   0,   0,   0,   58,  0,
-    16,  0,   0,   0,   0,   0,   14,  0,   0,   7,   226, 0,   16,  0,   1,   0,   0,   0,   6,
-    9,   16,  0,   0,   0,   0,   0,   246, 15,  16,  0,   0,   0,   0,   0,   55,  0,   0,   9,
-    114, 32,  16,  0,   0,   0,   0,   0,   6,   0,   16,  0,   1,   0,   0,   0,   150, 7,   16,
-    0,   1,   0,   0,   0,   70,  2,   16,  0,   0,   0,   0,   0,   54,  0,   0,   5,   130, 32,
-    16,  0,   0,   0,   0,   0,   58,  0,   16,  0,   0,   0,   0,   0,   62,  0,   0,   1,   83,
-    84,  65,  84,  116, 0,   0,   0,   6,   0,   0,   0,   2,   0,   0,   0,   0,   0,   0,   0,
-    2,   0,   0,   0,   2,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   1,   0,   0,
-    0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
-    0,   0,   0,   0,   0,   0,   1,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
-    0,   0,   0,   0,   0,   0,   0,   1,   0,   0,   0,   1,   0,   0,   0,   0,   0,   0,   0,
-    0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
-    0,   0,   0,   0,   0,   0,   0,   0,   0};
+#if 0
+//
+// Generated by Microsoft (R) HLSL Shader Compiler 6.3.9600.16384
+//
+//
+// Resource Bindings:
+//
+// Name                                 Type  Format         Dim Slot Elements
+// ------------------------------ ---------- ------- ----------- ---- --------
+// Sampler                           sampler      NA          NA    0        1
+// TextureF                          texture  float4          2d    0        1
+//
+//
+//
+// Input signature:
+//
+// Name                 Index   Mask Register SysValue  Format   Used
+// -------------------- ----- ------ -------- -------- ------- ------
+// SV_POSITION              0   xyzw        0      POS   float       
+// TEXCOORD                 0   xy          1     NONE   float   xy  
+//
+//
+// Output signature:
+//
+// Name                 Index   Mask Register SysValue  Format   Used
+// -------------------- ----- ------ -------- -------- ------- ------
+// SV_TARGET                0   xyzw        0   TARGET   float   xyzw
+//
+ps_4_0
+dcl_sampler s0, mode_default
+dcl_resource_texture2d (float,float,float,float) t0
+dcl_input_ps linear v1.xy
+dcl_output o0.xyzw
+dcl_temps 2
+sample r0.xyzw, v1.xyxx, t0.xyzw, s0
+lt r1.x, l(0.000000), r0.w
+div r1.yzw, r0.xxyz, r0.wwww
+movc o0.xyz, r1.xxxx, r1.yzwy, r0.xyzx
+mov o0.w, r0.w
+ret 
+// Approximately 6 instruction slots used
+#endif
+
+const BYTE g_PS_FtoF_UM_RGBA[] = {
+    68,  88,  66,  67,  186, 41,  193, 245, 39,  138, 185, 101, 12,  196, 111, 158, 103, 199, 2,
+    40,  1,   0,   0,   0,   200, 2,   0,   0,   5,   0,   0,   0,   52,  0,   0,   0,   220, 0,
+    0,   0,   52,  1,   0,   0,   104, 1,   0,   0,   76,  2,   0,   0,   82,  68,  69,  70,  160,
+    0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   2,   0,   0,   0,   28,  0,   0,   0,
+    0,   4,   255, 255, 0,   1,   0,   0,   109, 0,   0,   0,   92,  0,   0,   0,   3,   0,   0,
+    0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   1,   0,
+    0,   0,   1,   0,   0,   0,   100, 0,   0,   0,   2,   0,   0,   0,   5,   0,   0,   0,   4,
+    0,   0,   0,   255, 255, 255, 255, 0,   0,   0,   0,   1,   0,   0,   0,   13,  0,   0,   0,
+    83,  97,  109, 112, 108, 101, 114, 0,   84,  101, 120, 116, 117, 114, 101, 70,  0,   77,  105,
+    99,  114, 111, 115, 111, 102, 116, 32,  40,  82,  41,  32,  72,  76,  83,  76,  32,  83,  104,
+    97,  100, 101, 114, 32,  67,  111, 109, 112, 105, 108, 101, 114, 32,  54,  46,  51,  46,  57,
+    54,  48,  48,  46,  49,  54,  51,  56,  52,  0,   171, 73,  83,  71,  78,  80,  0,   0,   0,
+    2,   0,   0,   0,   8,   0,   0,   0,   56,  0,   0,   0,   0,   0,   0,   0,   1,   0,   0,
+    0,   3,   0,   0,   0,   0,   0,   0,   0,   15,  0,   0,   0,   68,  0,   0,   0,   0,   0,
+    0,   0,   0,   0,   0,   0,   3,   0,   0,   0,   1,   0,   0,   0,   3,   3,   0,   0,   83,
+    86,  95,  80,  79,  83,  73,  84,  73,  79,  78,  0,   84,  69,  88,  67,  79,  79,  82,  68,
+    0,   171, 171, 171, 79,  83,  71,  78,  44,  0,   0,   0,   1,   0,   0,   0,   8,   0,   0,
+    0,   32,  0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   3,   0,   0,   0,   0,   0,
+    0,   0,   15,  0,   0,   0,   83,  86,  95,  84,  65,  82,  71,  69,  84,  0,   171, 171, 83,
+    72,  68,  82,  220, 0,   0,   0,   64,  0,   0,   0,   55,  0,   0,   0,   90,  0,   0,   3,
+    0,   96,  16,  0,   0,   0,   0,   0,   88,  24,  0,   4,   0,   112, 16,  0,   0,   0,   0,
+    0,   85,  85,  0,   0,   98,  16,  0,   3,   50,  16,  16,  0,   1,   0,   0,   0,   101, 0,
+    0,   3,   242, 32,  16,  0,   0,   0,   0,   0,   104, 0,   0,   2,   2,   0,   0,   0,   69,
+    0,   0,   9,   242, 0,   16,  0,   0,   0,   0,   0,   70,  16,  16,  0,   1,   0,   0,   0,
+    70,  126, 16,  0,   0,   0,   0,   0,   0,   96,  16,  0,   0,   0,   0,   0,   49,  0,   0,
+    7,   18,  0,   16,  0,   1,   0,   0,   0,   1,   64,  0,   0,   0,   0,   0,   0,   58,  0,
+    16,  0,   0,   0,   0,   0,   14,  0,   0,   7,   226, 0,   16,  0,   1,   0,   0,   0,   6,
+    9,   16,  0,   0,   0,   0,   0,   246, 15,  16,  0,   0,   0,   0,   0,   55,  0,   0,   9,
+    114, 32,  16,  0,   0,   0,   0,   0,   6,   0,   16,  0,   1,   0,   0,   0,   150, 7,   16,
+    0,   1,   0,   0,   0,   70,  2,   16,  0,   0,   0,   0,   0,   54,  0,   0,   5,   130, 32,
+    16,  0,   0,   0,   0,   0,   58,  0,   16,  0,   0,   0,   0,   0,   62,  0,   0,   1,   83,
+    84,  65,  84,  116, 0,   0,   0,   6,   0,   0,   0,   2,   0,   0,   0,   0,   0,   0,   0,
+    2,   0,   0,   0,   2,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   1,   0,   0,
+    0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+    0,   0,   0,   0,   0,   0,   1,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+    0,   0,   0,   0,   0,   0,   0,   1,   0,   0,   0,   1,   0,   0,   0,   0,   0,   0,   0,
+    0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+    0,   0,   0,   0,   0,   0,   0,   0,   0};
--- a/gfx/angle/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftou_pm_rgb_ps.h
+++ b/gfx/angle/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftou_pm_rgb_ps.h
@@ -1,82 +1,82 @@
-#if 0
-//
-// Generated by Microsoft (R) HLSL Shader Compiler 6.3.9600.16384
-//
-//
-// Resource Bindings:
-//
-// Name                                 Type  Format         Dim Slot Elements
-// ------------------------------ ---------- ------- ----------- ---- --------
-// Sampler                           sampler      NA          NA    0        1
-// TextureF                          texture  float4          2d    0        1
-//
-//
-//
-// Input signature:
-//
-// Name                 Index   Mask Register SysValue  Format   Used
-// -------------------- ----- ------ -------- -------- ------- ------
-// SV_POSITION              0   xyzw        0      POS   float       
-// TEXCOORD                 0   xy          1     NONE   float   xy  
-//
-//
-// Output signature:
-//
-// Name                 Index   Mask Register SysValue  Format   Used
-// -------------------- ----- ------ -------- -------- ------- ------
-// SV_TARGET                0   xyzw        0   TARGET    uint   xyzw
-//
-ps_4_0
-dcl_sampler s0, mode_default
-dcl_resource_texture2d (float,float,float,float) t0
-dcl_input_ps linear v1.xy
-dcl_output o0.xyzw
-dcl_temps 1
-sample r0.xyzw, v1.xyxx, t0.xyzw, s0
-mul r0.xyz, r0.wwww, r0.xyzx
-mul r0.xyz, r0.xyzx, l(255.000000, 255.000000, 255.000000, 0.000000)
-ftou o0.xyz, r0.xyzx
-mov o0.w, l(1)
-ret 
-// Approximately 6 instruction slots used
-#endif
-
-const BYTE g_PS_FtoU_PM_RGB[] = {
-    68, 88,  66,  67,  155, 36,  56,  175, 46,  138, 216, 232, 30,  0,   183, 157, 15,  83,  210,
-    88, 1,   0,   0,   0,   196, 2,   0,   0,   5,   0,   0,   0,   52,  0,   0,   0,   220, 0,
-    0,  0,   52,  1,   0,   0,   104, 1,   0,   0,   72,  2,   0,   0,   82,  68,  69,  70,  160,
-    0,  0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   2,   0,   0,   0,   28,  0,   0,   0,
-    0,  4,   255, 255, 0,   1,   0,   0,   109, 0,   0,   0,   92,  0,   0,   0,   3,   0,   0,
-    0,  0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   1,   0,
-    0,  0,   1,   0,   0,   0,   100, 0,   0,   0,   2,   0,   0,   0,   5,   0,   0,   0,   4,
-    0,  0,   0,   255, 255, 255, 255, 0,   0,   0,   0,   1,   0,   0,   0,   13,  0,   0,   0,
-    83, 97,  109, 112, 108, 101, 114, 0,   84,  101, 120, 116, 117, 114, 101, 70,  0,   77,  105,
-    99, 114, 111, 115, 111, 102, 116, 32,  40,  82,  41,  32,  72,  76,  83,  76,  32,  83,  104,
-    97, 100, 101, 114, 32,  67,  111, 109, 112, 105, 108, 101, 114, 32,  54,  46,  51,  46,  57,
-    54, 48,  48,  46,  49,  54,  51,  56,  52,  0,   171, 73,  83,  71,  78,  80,  0,   0,   0,
-    2,  0,   0,   0,   8,   0,   0,   0,   56,  0,   0,   0,   0,   0,   0,   0,   1,   0,   0,
-    0,  3,   0,   0,   0,   0,   0,   0,   0,   15,  0,   0,   0,   68,  0,   0,   0,   0,   0,
-    0,  0,   0,   0,   0,   0,   3,   0,   0,   0,   1,   0,   0,   0,   3,   3,   0,   0,   83,
-    86, 95,  80,  79,  83,  73,  84,  73,  79,  78,  0,   84,  69,  88,  67,  79,  79,  82,  68,
-    0,  171, 171, 171, 79,  83,  71,  78,  44,  0,   0,   0,   1,   0,   0,   0,   8,   0,   0,
-    0,  32,  0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   1,   0,   0,   0,   0,   0,
-    0,  0,   15,  0,   0,   0,   83,  86,  95,  84,  65,  82,  71,  69,  84,  0,   171, 171, 83,
-    72, 68,  82,  216, 0,   0,   0,   64,  0,   0,   0,   54,  0,   0,   0,   90,  0,   0,   3,
-    0,  96,  16,  0,   0,   0,   0,   0,   88,  24,  0,   4,   0,   112, 16,  0,   0,   0,   0,
-    0,  85,  85,  0,   0,   98,  16,  0,   3,   50,  16,  16,  0,   1,   0,   0,   0,   101, 0,
-    0,  3,   242, 32,  16,  0,   0,   0,   0,   0,   104, 0,   0,   2,   1,   0,   0,   0,   69,
-    0,  0,   9,   242, 0,   16,  0,   0,   0,   0,   0,   70,  16,  16,  0,   1,   0,   0,   0,
-    70, 126, 16,  0,   0,   0,   0,   0,   0,   96,  16,  0,   0,   0,   0,   0,   56,  0,   0,
-    7,  114, 0,   16,  0,   0,   0,   0,   0,   246, 15,  16,  0,   0,   0,   0,   0,   70,  2,
-    16, 0,   0,   0,   0,   0,   56,  0,   0,   10,  114, 0,   16,  0,   0,   0,   0,   0,   70,
-    2,  16,  0,   0,   0,   0,   0,   2,   64,  0,   0,   0,   0,   127, 67,  0,   0,   127, 67,
-    0,  0,   127, 67,  0,   0,   0,   0,   28,  0,   0,   5,   114, 32,  16,  0,   0,   0,   0,
-    0,  70,  2,   16,  0,   0,   0,   0,   0,   54,  0,   0,   5,   130, 32,  16,  0,   0,   0,
-    0,  0,   1,   64,  0,   0,   1,   0,   0,   0,   62,  0,   0,   1,   83,  84,  65,  84,  116,
-    0,  0,   0,   6,   0,   0,   0,   1,   0,   0,   0,   0,   0,   0,   0,   2,   0,   0,   0,
-    2,  0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   1,   0,   0,   0,   0,   0,   0,
-    0,  0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
-    0,  0,   1,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
-    0,  0,   0,   1,   0,   0,   0,   0,   0,   0,   0,   1,   0,   0,   0,   0,   0,   0,   0,
-    0,  0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
-    0,  0,   0,   0,   0};
+#if 0
+//
+// Generated by Microsoft (R) HLSL Shader Compiler 6.3.9600.16384
+//
+//
+// Resource Bindings:
+//
+// Name                                 Type  Format         Dim Slot Elements
+// ------------------------------ ---------- ------- ----------- ---- --------
+// Sampler                           sampler      NA          NA    0        1
+// TextureF                          texture  float4          2d    0        1
+//
+//
+//
+// Input signature:
+//
+// Name                 Index   Mask Register SysValue  Format   Used
+// -------------------- ----- ------ -------- -------- ------- ------
+// SV_POSITION              0   xyzw        0      POS   float       
+// TEXCOORD                 0   xy          1     NONE   float   xy  
+//
+//
+// Output signature:
+//
+// Name                 Index   Mask Register SysValue  Format   Used
+// -------------------- ----- ------ -------- -------- ------- ------
+// SV_TARGET                0   xyzw        0   TARGET    uint   xyzw
+//
+ps_4_0
+dcl_sampler s0, mode_default
+dcl_resource_texture2d (float,float,float,float) t0
+dcl_input_ps linear v1.xy
+dcl_output o0.xyzw
+dcl_temps 1
+sample r0.xyzw, v1.xyxx, t0.xyzw, s0
+mul r0.xyz, r0.wwww, r0.xyzx
+mul r0.xyz, r0.xyzx, l(255.000000, 255.000000, 255.000000, 0.000000)
+ftou o0.xyz, r0.xyzx
+mov o0.w, l(1)
+ret 
+// Approximately 6 instruction slots used
+#endif
+
+const BYTE g_PS_FtoU_PM_RGB[] = {
+    68, 88,  66,  67,  155, 36,  56,  175, 46,  138, 216, 232, 30,  0,   183, 157, 15,  83,  210,
+    88, 1,   0,   0,   0,   196, 2,   0,   0,   5,   0,   0,   0,   52,  0,   0,   0,   220, 0,
+    0,  0,   52,  1,   0,   0,   104, 1,   0,   0,   72,  2,   0,   0,   82,  68,  69,  70,  160,
+    0,  0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   2,   0,   0,   0,   28,  0,   0,   0,
+    0,  4,   255, 255, 0,   1,   0,   0,   109, 0,   0,   0,   92,  0,   0,   0,   3,   0,   0,
+    0,  0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   1,   0,
+    0,  0,   1,   0,   0,   0,   100, 0,   0,   0,   2,   0,   0,   0,   5,   0,   0,   0,   4,
+    0,  0,   0,   255, 255, 255, 255, 0,   0,   0,   0,   1,   0,   0,   0,   13,  0,   0,   0,
+    83, 97,  109, 112, 108, 101, 114, 0,   84,  101, 120, 116, 117, 114, 101, 70,  0,   77,  105,
+    99, 114, 111, 115, 111, 102, 116, 32,  40,  82,  41,  32,  72,  76,  83,  76,  32,  83,  104,
+    97, 100, 101, 114, 32,  67,  111, 109, 112, 105, 108, 101, 114, 32,  54,  46,  51,  46,  57,
+    54, 48,  48,  46,  49,  54,  51,  56,  52,  0,   171, 73,  83,  71,  78,  80,  0,   0,   0,
+    2,  0,   0,   0,   8,   0,   0,   0,   56,  0,   0,   0,   0,   0,   0,   0,   1,   0,   0,
+    0,  3,   0,   0,   0,   0,   0,   0,   0,   15,  0,   0,   0,   68,  0,   0,   0,   0,   0,
+    0,  0,   0,   0,   0,   0,   3,   0,   0,   0,   1,   0,   0,   0,   3,   3,   0,   0,   83,
+    86, 95,  80,  79,  83,  73,  84,  73,  79,  78,  0,   84,  69,  88,  67,  79,  79,  82,  68,
+    0,  171, 171, 171, 79,  83,  71,  78,  44,  0,   0,   0,   1,   0,   0,   0,   8,   0,   0,
+    0,  32,  0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   1,   0,   0,   0,   0,   0,
+    0,  0,   15,  0,   0,   0,   83,  86,  95,  84,  65,  82,  71,  69,  84,  0,   171, 171, 83,
+    72, 68,  82,  216, 0,   0,   0,   64,  0,   0,   0,   54,  0,   0,   0,   90,  0,   0,   3,
+    0,  96,  16,  0,   0,   0,   0,   0,   88,  24,  0,   4,   0,   112, 16,  0,   0,   0,   0,
+    0,  85,  85,  0,   0,   98,  16,  0,   3,   50,  16,  16,  0,   1,   0,   0,   0,   101, 0,
+    0,  3,   242, 32,  16,  0,   0,   0,   0,   0,   104, 0,   0,   2,   1,   0,   0,   0,   69,
+    0,  0,   9,   242, 0,   16,  0,   0,   0,   0,   0,   70,  16,  16,  0,   1,   0,   0,   0,
+    70, 126, 16,  0,   0,   0,   0,   0,   0,   96,  16,  0,   0,   0,   0,   0,   56,  0,   0,
+    7,  114, 0,   16,  0,   0,   0,   0,   0,   246, 15,  16,  0,   0,   0,   0,   0,   70,  2,
+    16, 0,   0,   0,   0,   0,   56,  0,   0,   10,  114, 0,   16,  0,   0,   0,   0,   0,   70,
+    2,  16,  0,   0,   0,   0,   0,   2,   64,  0,   0,   0,   0,   127, 67,  0,   0,   127, 67,
+    0,  0,   127, 67,  0,   0,   0,   0,   28,  0,   0,   5,   114, 32,  16,  0,   0,   0,   0,
+    0,  70,  2,   16,  0,   0,   0,   0,   0,   54,  0,   0,   5,   130, 32,  16,  0,   0,   0,
+    0,  0,   1,   64,  0,   0,   1,   0,   0,   0,   62,  0,   0,   1,   83,  84,  65,  84,  116,
+    0,  0,   0,   6,   0,   0,   0,   1,   0,   0,   0,   0,   0,   0,   0,   2,   0,   0,   0,
+    2,  0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   1,   0,   0,   0,   0,   0,   0,
+    0,  0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+    0,  0,   1,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+    0,  0,   0,   1,   0,   0,   0,   0,   0,   0,   0,   1,   0,   0,   0,   0,   0,   0,   0,
+    0,  0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+    0,  0,   0,   0,   0};
--- a/gfx/angle/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftou_pm_rgba_ps.h
+++ b/gfx/angle/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftou_pm_rgba_ps.h
@@ -1,80 +1,80 @@
-#if 0
-//
-// Generated by Microsoft (R) HLSL Shader Compiler 6.3.9600.16384
-//
-//
-// Resource Bindings:
-//
-// Name                                 Type  Format         Dim Slot Elements
-// ------------------------------ ---------- ------- ----------- ---- --------
-// Sampler                           sampler      NA          NA    0        1
-// TextureF                          texture  float4          2d    0        1
-//
-//
-//
-// Input signature:
-//
-// Name                 Index   Mask Register SysValue  Format   Used
-// -------------------- ----- ------ -------- -------- ------- ------
-// SV_POSITION              0   xyzw        0      POS   float       
-// TEXCOORD                 0   xy          1     NONE   float   xy  
-//
-//
-// Output signature:
-//
-// Name                 Index   Mask Register SysValue  Format   Used
-// -------------------- ----- ------ -------- -------- ------- ------
-// SV_TARGET                0   xyzw        0   TARGET    uint   xyzw
-//
-ps_4_0
-dcl_sampler s0, mode_default
-dcl_resource_texture2d (float,float,float,float) t0
-dcl_input_ps linear v1.xy
-dcl_output o0.xyzw
-dcl_temps 1
-sample r0.xyzw, v1.xyxx, t0.xyzw, s0
-mul r0.xyz, r0.wwww, r0.xyzx
-mul r0.xyzw, r0.xyzw, l(255.000000, 255.000000, 255.000000, 255.000000)
-ftou o0.xyzw, r0.xyzw
-ret 
-// Approximately 5 instruction slots used
-#endif
-
-const BYTE g_PS_FtoU_PM_RGBA[] = {
-    68,  88,  66,  67,  145, 185, 8,   222, 150, 161, 126, 192, 3,   250, 167, 200, 187, 74,  70,
-    211, 1,   0,   0,   0,   176, 2,   0,   0,   5,   0,   0,   0,   52,  0,   0,   0,   220, 0,
-    0,   0,   52,  1,   0,   0,   104, 1,   0,   0,   52,  2,   0,   0,   82,  68,  69,  70,  160,
-    0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   2,   0,   0,   0,   28,  0,   0,   0,
-    0,   4,   255, 255, 0,   1,   0,   0,   109, 0,   0,   0,   92,  0,   0,   0,   3,   0,   0,
-    0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   1,   0,
-    0,   0,   1,   0,   0,   0,   100, 0,   0,   0,   2,   0,   0,   0,   5,   0,   0,   0,   4,
-    0,   0,   0,   255, 255, 255, 255, 0,   0,   0,   0,   1,   0,   0,   0,   13,  0,   0,   0,
-    83,  97,  109, 112, 108, 101, 114, 0,   84,  101, 120, 116, 117, 114, 101, 70,  0,   77,  105,
-    99,  114, 111, 115, 111, 102, 116, 32,  40,  82,  41,  32,  72,  76,  83,  76,  32,  83,  104,
-    97,  100, 101, 114, 32,  67,  111, 109, 112, 105, 108, 101, 114, 32,  54,  46,  51,  46,  57,
-    54,  48,  48,  46,  49,  54,  51,  56,  52,  0,   171, 73,  83,  71,  78,  80,  0,   0,   0,
-    2,   0,   0,   0,   8,   0,   0,   0,   56,  0,   0,   0,   0,   0,   0,   0,   1,   0,   0,
-    0,   3,   0,   0,   0,   0,   0,   0,   0,   15,  0,   0,   0,   68,  0,   0,   0,   0,   0,
-    0,   0,   0,   0,   0,   0,   3,   0,   0,   0,   1,   0,   0,   0,   3,   3,   0,   0,   83,
-    86,  95,  80,  79,  83,  73,  84,  73,  79,  78,  0,   84,  69,  88,  67,  79,  79,  82,  68,
-    0,   171, 171, 171, 79,  83,  71,  78,  44,  0,   0,   0,   1,   0,   0,   0,   8,   0,   0,
-    0,   32,  0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   1,   0,   0,   0,   0,   0,
-    0,   0,   15,  0,   0,   0,   83,  86,  95,  84,  65,  82,  71,  69,  84,  0,   171, 171, 83,
-    72,  68,  82,  196, 0,   0,   0,   64,  0,   0,   0,   49,  0,   0,   0,   90,  0,   0,   3,
-    0,   96,  16,  0,   0,   0,   0,   0,   88,  24,  0,   4,   0,   112, 16,  0,   0,   0,   0,
-    0,   85,  85,  0,   0,   98,  16,  0,   3,   50,  16,  16,  0,   1,   0,   0,   0,   101, 0,
-    0,   3,   242, 32,  16,  0,   0,   0,   0,   0,   104, 0,   0,   2,   1,   0,   0,   0,   69,
-    0,   0,   9,   242, 0,   16,  0,   0,   0,   0,   0,   70,  16,  16,  0,   1,   0,   0,   0,
-    70,  126, 16,  0,   0,   0,   0,   0,   0,   96,  16,  0,   0,   0,   0,   0,   56,  0,   0,
-    7,   114, 0,   16,  0,   0,   0,   0,   0,   246, 15,  16,  0,   0,   0,   0,   0,   70,  2,
-    16,  0,   0,   0,   0,   0,   56,  0,   0,   10,  242, 0,   16,  0,   0,   0,   0,   0,   70,
-    14,  16,  0,   0,   0,   0,   0,   2,   64,  0,   0,   0,   0,   127, 67,  0,   0,   127, 67,
-    0,   0,   127, 67,  0,   0,   127, 67,  28,  0,   0,   5,   242, 32,  16,  0,   0,   0,   0,
-    0,   70,  14,  16,  0,   0,   0,   0,   0,   62,  0,   0,   1,   83,  84,  65,  84,  116, 0,
-    0,   0,   5,   0,   0,   0,   1,   0,   0,   0,   0,   0,   0,   0,   2,   0,   0,   0,   2,
-    0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   1,   0,   0,   0,   0,   0,   0,   0,
-    0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
-    0,   1,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
-    0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   1,   0,   0,   0,   0,   0,   0,   0,   0,
-    0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
-    0,   0,   0,   0};
+#if 0
+//
+// Generated by Microsoft (R) HLSL Shader Compiler 6.3.9600.16384
+//
+//
+// Resource Bindings:
+//
+// Name                                 Type  Format         Dim Slot Elements
+// ------------------------------ ---------- ------- ----------- ---- --------
+// Sampler                           sampler      NA          NA    0        1
+// TextureF                          texture  float4          2d    0        1
+//
+//
+//
+// Input signature:
+//
+// Name                 Index   Mask Register SysValue  Format   Used
+// -------------------- ----- ------ -------- -------- ------- ------
+// SV_POSITION              0   xyzw        0      POS   float       
+// TEXCOORD                 0   xy          1     NONE   float   xy  
+//
+//
+// Output signature:
+//
+// Name                 Index   Mask Register SysValue  Format   Used
+// -------------------- ----- ------ -------- -------- ------- ------
+// SV_TARGET                0   xyzw        0   TARGET    uint   xyzw
+//
+ps_4_0
+dcl_sampler s0, mode_default
+dcl_resource_texture2d (float,float,float,float) t0
+dcl_input_ps linear v1.xy
+dcl_output o0.xyzw
+dcl_temps 1
+sample r0.xyzw, v1.xyxx, t0.xyzw, s0
+mul r0.xyz, r0.wwww, r0.xyzx
+mul r0.xyzw, r0.xyzw, l(255.000000, 255.000000, 255.000000, 255.000000)
+ftou o0.xyzw, r0.xyzw
+ret 
+// Approximately 5 instruction slots used
+#endif
+
+const BYTE g_PS_FtoU_PM_RGBA[] = {
+    68,  88,  66,  67,  145, 185, 8,   222, 150, 161, 126, 192, 3,   250, 167, 200, 187, 74,  70,
+    211, 1,   0,   0,   0,   176, 2,   0,   0,   5,   0,   0,   0,   52,  0,   0,   0,   220, 0,
+    0,   0,   52,  1,   0,   0,   104, 1,   0,   0,   52,  2,   0,   0,   82,  68,  69,  70,  160,
+    0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   2,   0,   0,   0,   28,  0,   0,   0,
+    0,   4,   255, 255, 0,   1,   0,   0,   109, 0,   0,   0,   92,  0,   0,   0,   3,   0,   0,
+    0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   1,   0,
+    0,   0,   1,   0,   0,   0,   100, 0,   0,   0,   2,   0,   0,   0,   5,   0,   0,   0,   4,
+    0,   0,   0,   255, 255, 255, 255, 0,   0,   0,   0,   1,   0,   0,   0,   13,  0,   0,   0,
+    83,  97,  109, 112, 108, 101, 114, 0,   84,  101, 120, 116, 117, 114, 101, 70,  0,   77,  105,
+    99,  114, 111, 115, 111, 102, 116, 32,  40,  82,  41,  32,  72,  76,  83,  76,  32,  83,  104,
+    97,  100, 101, 114, 32,  67,  111, 109, 112, 105, 108, 101, 114, 32,  54,  46,  51,  46,  57,
+    54,  48,  48,  46,  49,  54,  51,  56,  52,  0,   171, 73,  83,  71,  78,  80,  0,   0,   0,
+    2,   0,   0,   0,   8,   0,   0,   0,   56,  0,   0,   0,   0,   0,   0,   0,   1,   0,   0,
+    0,   3,   0,   0,   0,   0,   0,   0,   0,   15,  0,   0,   0,   68,  0,   0,   0,   0,   0,
+    0,   0,   0,   0,   0,   0,   3,   0,   0,   0,   1,   0,   0,   0,   3,   3,   0,   0,   83,
+    86,  95,  80,  79,  83,  73,  84,  73,  79,  78,  0,   84,  69,  88,  67,  79,  79,  82,  68,
+    0,   171, 171, 171, 79,  83,  71,  78,  44,  0,   0,   0,   1,   0,   0,   0,   8,   0,   0,
+    0,   32,  0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   1,   0,   0,   0,   0,   0,
+    0,   0,   15,  0,   0,   0,   83,  86,  95,  84,  65,  82,  71,  69,  84,  0,   171, 171, 83,
+    72,  68,  82,  196, 0,   0,   0,   64,  0,   0,   0,   49,  0,   0,   0,   90,  0,   0,   3,
+    0,   96,  16,  0,   0,   0,   0,   0,   88,  24,  0,   4,   0,   112, 16,  0,   0,   0,   0,
+    0,   85,  85,  0,   0,   98,  16,  0,   3,   50,  16,  16,  0,   1,   0,   0,   0,   101, 0,
+    0,   3,   242, 32,  16,  0,   0,   0,   0,   0,   104, 0,   0,   2,   1,   0,   0,   0,   69,
+    0,   0,   9,   242, 0,   16,  0,   0,   0,   0,   0,   70,  16,  16,  0,   1,   0,   0,   0,
+    70,  126, 16,  0,   0,   0,   0,   0,   0,   96,  16,  0,   0,   0,   0,   0,   56,  0,   0,
+    7,   114, 0,   16,  0,   0,   0,   0,   0,   246, 15,  16,  0,   0,   0,   0,   0,   70,  2,
+    16,  0,   0,   0,   0,   0,   56,  0,   0,   10,  242, 0,   16,  0,   0,   0,   0,   0,   70,
+    14,  16,  0,   0,   0,   0,   0,   2,   64,  0,   0,   0,   0,   127, 67,  0,   0,   127, 67,
+    0,   0,   127, 67,  0,   0,   127, 67,  28,  0,   0,   5,   242, 32,  16,  0,   0,   0,   0,
+    0,   70,  14,  16,  0,   0,   0,   0,   0,   62,  0,   0,   1,   83,  84,  65,  84,  116, 0,
+    0,   0,   5,   0,   0,   0,   1,   0,   0,   0,   0,   0,   0,   0,   2,   0,   0,   0,   2,
+    0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   1,   0,   0,   0,   0,   0,   0,   0,
+    0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+    0,   1,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+    0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   1,   0,   0,   0,   0,   0,   0,   0,   0,
+    0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+    0,   0,   0,   0};
--- a/gfx/angle/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftou_pt_rgb_ps.h
+++ b/gfx/angle/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftou_pt_rgb_ps.h
@@ -1,79 +1,79 @@
-#if 0
-//
-// Generated by Microsoft (R) HLSL Shader Compiler 6.3.9600.16384
-//
-//
-// Resource Bindings:
-//
-// Name                                 Type  Format         Dim Slot Elements
-// ------------------------------ ---------- ------- ----------- ---- --------
-// Sampler                           sampler      NA          NA    0        1
-// TextureF                          texture  float4          2d    0        1
-//
-//
-//
-// Input signature:
-//
-// Name                 Index   Mask Register SysValue  Format   Used
-// -------------------- ----- ------ -------- -------- ------- ------
-// SV_POSITION              0   xyzw        0      POS   float       
-// TEXCOORD                 0   xy          1     NONE   float   xy  
-//
-//
-// Output signature:
-//
-// Name                 Index   Mask Register SysValue  Format   Used
-// -------------------- ----- ------ -------- -------- ------- ------
-// SV_TARGET                0   xyzw        0   TARGET    uint   xyzw
-//
-ps_4_0
-dcl_sampler s0, mode_default
-dcl_resource_texture2d (float,float,float,float) t0
-dcl_input_ps linear v1.xy
-dcl_output o0.xyzw
-dcl_temps 1
-sample r0.xyzw, v1.xyxx, t0.xyzw, s0
-mul r0.xyz, r0.xyzx, l(255.000000, 255.000000, 255.000000, 0.000000)
-ftou o0.xyz, r0.xyzx
-mov o0.w, l(1)
-ret 
-// Approximately 5 instruction slots used
-#endif
-
-const BYTE g_PS_FtoU_PT_RGB[] = {
-    68, 88,  66,  67,  199, 233, 92,  114, 12,  127, 254, 75,  103, 144, 201, 199, 115, 189, 178,
-    64, 1,   0,   0,   0,   168, 2,   0,   0,   5,   0,   0,   0,   52,  0,   0,   0,   220, 0,
-    0,  0,   52,  1,   0,   0,   104, 1,   0,   0,   44,  2,   0,   0,   82,  68,  69,  70,  160,
-    0,  0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   2,   0,   0,   0,   28,  0,   0,   0,
-    0,  4,   255, 255, 0,   1,   0,   0,   109, 0,   0,   0,   92,  0,   0,   0,   3,   0,   0,
-    0,  0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   1,   0,
-    0,  0,   1,   0,   0,   0,   100, 0,   0,   0,   2,   0,   0,   0,   5,   0,   0,   0,   4,
-    0,  0,   0,   255, 255, 255, 255, 0,   0,   0,   0,   1,   0,   0,   0,   13,  0,   0,   0,
-    83, 97,  109, 112, 108, 101, 114, 0,   84,  101, 120, 116, 117, 114, 101, 70,  0,   77,  105,
-    99, 114, 111, 115, 111, 102, 116, 32,  40,  82,  41,  32,  72,  76,  83,  76,  32,  83,  104,
-    97, 100, 101, 114, 32,  67,  111, 109, 112, 105, 108, 101, 114, 32,  54,  46,  51,  46,  57,
-    54, 48,  48,  46,  49,  54,  51,  56,  52,  0,   171, 73,  83,  71,  78,  80,  0,   0,   0,
-    2,  0,   0,   0,   8,   0,   0,   0,   56,  0,   0,   0,   0,   0,   0,   0,   1,   0,   0,
-    0,  3,   0,   0,   0,   0,   0,   0,   0,   15,  0,   0,   0,   68,  0,   0,   0,   0,   0,
-    0,  0,   0,   0,   0,   0,   3,   0,   0,   0,   1,   0,   0,   0,   3,   3,   0,   0,   83,
-    86, 95,  80,  79,  83,  73,  84,  73,  79,  78,  0,   84,  69,  88,  67,  79,  79,  82,  68,
-    0,  171, 171, 171, 79,  83,  71,  78,  44,  0,   0,   0,   1,   0,   0,   0,   8,   0,   0,
-    0,  32,  0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   1,   0,   0,   0,   0,   0,
-    0,  0,   15,  0,   0,   0,   83,  86,  95,  84,  65,  82,  71,  69,  84,  0,   171, 171, 83,
-    72, 68,  82,  188, 0,   0,   0,   64,  0,   0,   0,   47,  0,   0,   0,   90,  0,   0,   3,
-    0,  96,  16,  0,   0,   0,   0,   0,   88,  24,  0,   4,   0,   112, 16,  0,   0,   0,   0,
-    0,  85,  85,  0,   0,   98,  16,  0,   3,   50,  16,  16,  0,   1,   0,   0,   0,   101, 0,
-    0,  3,   242, 32,  16,  0,   0,   0,   0,   0,   104, 0,   0,   2,   1,   0,   0,   0,   69,
-    0,  0,   9,   242, 0,   16,  0,   0,   0,   0,   0,   70,  16,  16,  0,   1,   0,   0,   0,
-    70, 126, 16,  0,   0,   0,   0,   0,   0,   96,  16,  0,   0,   0,   0,   0,   56,  0,   0,
-    10, 114, 0,   16,  0,   0,   0,   0,   0,   70,  2,   16,  0,   0,   0,   0,   0,   2,   64,
-    0,  0,   0,   0,   127, 67,  0,   0,   127, 67,  0,   0,   127, 67,  0,   0,   0,   0,   28,
-    0,  0,   5,   114, 32,  16,  0,   0,   0,   0,   0,   70,  2,   16,  0,   0,   0,   0,   0,
-    54, 0,   0,   5,   130, 32,  16,  0,   0,   0,   0,   0,   1,   64,  0,   0,   1,   0,   0,
-    0,  62,  0,   0,   1,   83,  84,  65,  84,  116, 0,   0,   0,   5,   0,   0,   0,   1,   0,
-    0,  0,   0,   0,   0,   0,   2,   0,   0,   0,   1,   0,   0,   0,   0,   0,   0,   0,   0,
-    0,  0,   0,   1,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
-    0,  0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   1,   0,   0,   0,   0,   0,   0,
-    0,  0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   1,   0,   0,   0,   0,   0,
-    0,  0,   1,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
-    0,  0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0};
+#if 0
+//
+// Generated by Microsoft (R) HLSL Shader Compiler 6.3.9600.16384
+//
+//
+// Resource Bindings:
+//
+// Name                                 Type  Format         Dim Slot Elements
+// ------------------------------ ---------- ------- ----------- ---- --------
+// Sampler                           sampler      NA          NA    0        1
+// TextureF                          texture  float4          2d    0        1
+//
+//
+//
+// Input signature:
+//
+// Name                 Index   Mask Register SysValue  Format   Used
+// -------------------- ----- ------ -------- -------- ------- ------
+// SV_POSITION              0   xyzw        0      POS   float       
+// TEXCOORD                 0   xy          1     NONE   float   xy  
+//
+//
+// Output signature:
+//
+// Name                 Index   Mask Register SysValue  Format   Used
+// -------------------- ----- ------ -------- -------- ------- ------
+// SV_TARGET                0   xyzw        0   TARGET    uint   xyzw
+//
+ps_4_0
+dcl_sampler s0, mode_default
+dcl_resource_texture2d (float,float,float,float) t0
+dcl_input_ps linear v1.xy
+dcl_output o0.xyzw
+dcl_temps 1
+sample r0.xyzw, v1.xyxx, t0.xyzw, s0
+mul r0.xyz, r0.xyzx, l(255.000000, 255.000000, 255.000000, 0.000000)
+ftou o0.xyz, r0.xyzx
+mov o0.w, l(1)
+ret 
+// Approximately 5 instruction slots used
+#endif
+
+const BYTE g_PS_FtoU_PT_RGB[] = {
+    68, 88,  66,  67,  199, 233, 92,  114, 12,  127, 254, 75,  103, 144, 201, 199, 115, 189, 178,
+    64, 1,   0,   0,   0,   168, 2,   0,   0,   5,   0,   0,   0,   52,  0,   0,   0,   220, 0,
+    0,  0,   52,  1,   0,   0,   104, 1,   0,   0,   44,  2,   0,   0,   82,  68,  69,  70,  160,
+    0,  0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   2,   0,   0,   0,   28,  0,   0,   0,
+    0,  4,   255, 255, 0,   1,   0,   0,   109, 0,   0,   0,   92,  0,   0,   0,   3,   0,   0,
+    0,  0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   1,   0,
+    0,  0,   1,   0,   0,   0,   100, 0,   0,   0,   2,   0,   0,   0,   5,   0,   0,   0,   4,
+    0,  0,   0,   255, 255, 255, 255, 0,   0,   0,   0,   1,   0,   0,   0,   13,  0,   0,   0,
+    83, 97,  109, 112, 108, 101, 114, 0,   84,  101, 120, 116, 117, 114, 101, 70,  0,   77,  105,
+    99, 114, 111, 115, 111, 102, 116, 32,  40,  82,  41,  32,  72,  76,  83,  76,  32,  83,  104,
+    97, 100, 101, 114, 32,  67,  111, 109, 112, 105, 108, 101, 114, 32,  54,  46,  51,  46,  57,
+    54, 48,  48,  46,  49,  54,  51,  56,  52,  0,   171, 73,  83,  71,  78,  80,  0,   0,   0,
+    2,  0,   0,   0,   8,   0,   0,   0,   56,  0,   0,   0,   0,   0,   0,   0,   1,   0,   0,
+    0,  3,   0,   0,   0,   0,   0,   0,   0,   15,  0,   0,   0,   68,  0,   0,   0,   0,   0,
+    0,  0,   0,   0,   0,   0,   3,   0,   0,   0,   1,   0,   0,   0,   3,   3,   0,   0,   83,
+    86, 95,  80,  79,  83,  73,  84,  73,  79,  78,  0,   84,  69,  88,  67,  79,  79,  82,  68,
+    0,  171, 171, 171, 79,  83,  71,  78,  44,  0,   0,   0,   1,   0,   0,   0,   8,   0,   0,
+    0,  32,  0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   1,   0,   0,   0,   0,   0,
+    0,  0,   15,  0,   0,   0,   83,  86,  95,  84,  65,  82,  71,  69,  84,  0,   171, 171, 83,
+    72, 68,  82,  188, 0,   0,   0,   64,  0,   0,   0,   47,  0,   0,   0,   90,  0,   0,   3,
+    0,  96,  16,  0,   0,   0,   0,   0,   88,  24,  0,   4,   0,   112, 16,  0,   0,   0,   0,
+    0,  85,  85,  0,   0,   98,  16,  0,   3,   50,  16,  16,  0,   1,   0,   0,   0,   101, 0,
+    0,  3,   242, 32,  16,  0,   0,   0,   0,   0,   104, 0,   0,   2,   1,   0,   0,   0,   69,
+    0,  0,   9,   242, 0,   16,  0,   0,   0,   0,   0,   70,  16,  16,  0,   1,   0,   0,   0,
+    70, 126, 16,  0,   0,   0,   0,   0,   0,   96,  16,  0,   0,   0,   0,   0,   56,  0,   0,
+    10, 114, 0,   16,  0,   0,   0,   0,   0,   70,  2,   16,  0,   0,   0,   0,   0,   2,   64,
+    0,  0,   0,   0,   127, 67,  0,   0,   127, 67,  0,   0,   127, 67,  0,   0,   0,   0,   28,
+    0,  0,   5,   114, 32,  16,  0,   0,   0,   0,   0,   70,  2,   16,  0,   0,   0,   0,   0,
+    54, 0,   0,   5,   130, 32,  16,  0,   0,   0,   0,   0,   1,   64,  0,   0,   1,   0,   0,
+    0,  62,  0,   0,   1,   83,  84,  65,  84,  116, 0,   0,   0,   5,   0,   0,   0,   1,   0,
+    0,  0,   0,   0,   0,   0,   2,   0,   0,   0,   1,   0,   0,   0,   0,   0,   0,   0,   0,
+    0,  0,   0,   1,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+    0,  0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   1,   0,   0,   0,   0,   0,   0,
+    0,  0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   1,   0,   0,   0,   0,   0,
+    0,  0,   1,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+    0,  0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0};
--- a/gfx/angle/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftou_pt_rgba_ps.h
+++ b/gfx/angle/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftou_pt_rgba_ps.h
@@ -1,77 +1,77 @@
-#if 0
-//
-// Generated by Microsoft (R) HLSL Shader Compiler 6.3.9600.16384
-//
-//
-// Resource Bindings:
-//
-// Name                                 Type  Format         Dim Slot Elements
-// ------------------------------ ---------- ------- ----------- ---- --------
-// Sampler                           sampler      NA          NA    0        1
-// TextureF                          texture  float4          2d    0        1
-//
-//
-//
-// Input signature:
-//
-// Name                 Index   Mask Register SysValue  Format   Used
-// -------------------- ----- ------ -------- -------- ------- ------
-// SV_POSITION              0   xyzw        0      POS   float       
-// TEXCOORD                 0   xy          1     NONE   float   xy  
-//
-//
-// Output signature:
-//
-// Name                 Index   Mask Register SysValue  Format   Used
-// -------------------- ----- ------ -------- -------- ------- ------
-// SV_TARGET                0   xyzw        0   TARGET    uint   xyzw
-//
-ps_4_0
-dcl_sampler s0, mode_default
-dcl_resource_texture2d (float,float,float,float) t0
-dcl_input_ps linear v1.xy
-dcl_output o0.xyzw
-dcl_temps 1
-sample r0.xyzw, v1.xyxx, t0.xyzw, s0
-mul r0.xyzw, r0.xyzw, l(255.000000, 255.000000, 255.000000, 255.000000)
-ftou o0.xyzw, r0.xyzw
-ret 
-// Approximately 4 instruction slots used
-#endif
-
-const BYTE g_PS_FtoU_PT_RGBA[] = {
-    68,  88,  66,  67,  209, 83,  172, 72,  82,  105, 159, 134, 14,  29,  227, 217, 205, 178, 97,
-    208, 1,   0,   0,   0,   148, 2,   0,   0,   5,   0,   0,   0,   52,  0,   0,   0,   220, 0,
-    0,   0,   52,  1,   0,   0,   104, 1,   0,   0,   24,  2,   0,   0,   82,  68,  69,  70,  160,
-    0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   2,   0,   0,   0,   28,  0,   0,   0,
-    0,   4,   255, 255, 0,   1,   0,   0,   109, 0,   0,   0,   92,  0,   0,   0,   3,   0,   0,
-    0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   1,   0,
-    0,   0,   1,   0,   0,   0,   100, 0,   0,   0,   2,   0,   0,   0,   5,   0,   0,   0,   4,
-    0,   0,   0,   255, 255, 255, 255, 0,   0,   0,   0,   1,   0,   0,   0,   13,  0,   0,   0,
-    83,  97,  109, 112, 108, 101, 114, 0,   84,  101, 120, 116, 117, 114, 101, 70,  0,   77,  105,
-    99,  114, 111, 115, 111, 102, 116, 32,  40,  82,  41,  32,  72,  76,  83,  76,  32,  83,  104,
-    97,  100, 101, 114, 32,  67,  111, 109, 112, 105, 108, 101, 114, 32,  54,  46,  51,  46,  57,
-    54,  48,  48,  46,  49,  54,  51,  56,  52,  0,   171, 73,  83,  71,  78,  80,  0,   0,   0,
-    2,   0,   0,   0,   8,   0,   0,   0,   56,  0,   0,   0,   0,   0,   0,   0,   1,   0,   0,
-    0,   3,   0,   0,   0,   0,   0,   0,   0,   15,  0,   0,   0,   68,  0,   0,   0,   0,   0,
-    0,   0,   0,   0,   0,   0,   3,   0,   0,   0,   1,   0,   0,   0,   3,   3,   0,   0,   83,
-    86,  95,  80,  79,  83,  73,  84,  73,  79,  78,  0,   84,  69,  88,  67,  79,  79,  82,  68,
-    0,   171, 171, 171, 79,  83,  71,  78,  44,  0,   0,   0,   1,   0,   0,   0,   8,   0,   0,
-    0,   32,  0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   1,   0,   0,   0,   0,   0,
-    0,   0,   15,  0,   0,   0,   83,  86,  95,  84,  65,  82,  71,  69,  84,  0,   171, 171, 83,
-    72,  68,  82,  168, 0,   0,   0,   64,  0,   0,   0,   42,  0,   0,   0,   90,  0,   0,   3,
-    0,   96,  16,  0,   0,   0,   0,   0,   88,  24,  0,   4,   0,   112, 16,  0,   0,   0,   0,
-    0,   85,  85,  0,   0,   98,  16,  0,   3,   50,  16,  16,  0,   1,   0,   0,   0,   101, 0,
-    0,   3,   242, 32,  16,  0,   0,   0,   0,   0,   104, 0,   0,   2,   1,   0,   0,   0,   69,
-    0,   0,   9,   242, 0,   16,  0,   0,   0,   0,   0,   70,  16,  16,  0,   1,   0,   0,   0,
-    70,  126, 16,  0,   0,   0,   0,   0,   0,   96,  16,  0,   0,   0,   0,   0,   56,  0,   0,
-    10,  242, 0,   16,  0,   0,   0,   0,   0,   70,  14,  16,  0,   0,   0,   0,   0,   2,   64,
-    0,   0,   0,   0,   127, 67,  0,   0,   127, 67,  0,   0,   127, 67,  0,   0,   127, 67,  28,
-    0,   0,   5,   242, 32,  16,  0,   0,   0,   0,   0,   70,  14,  16,  0,   0,   0,   0,   0,
-    62,  0,   0,   1,   83,  84,  65,  84,  116, 0,   0,   0,   4,   0,   0,   0,   1,   0,   0,
-    0,   0,   0,   0,   0,   2,   0,   0,   0,   1,   0,   0,   0,   0,   0,   0,   0,   0,   0,
-    0,   0,   1,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
-    0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   1,   0,   0,   0,   0,   0,   0,   0,
-    0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
-    0,   1,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
-    0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0};
+#if 0
+//
+// Generated by Microsoft (R) HLSL Shader Compiler 6.3.9600.16384
+//
+//
+// Resource Bindings:
+//
+// Name                                 Type  Format         Dim Slot Elements
+// ------------------------------ ---------- ------- ----------- ---- --------
+// Sampler                           sampler      NA          NA    0        1
+// TextureF                          texture  float4          2d    0        1
+//
+//
+//
+// Input signature:
+//
+// Name                 Index   Mask Register SysValue  Format   Used
+// -------------------- ----- ------ -------- -------- ------- ------
+// SV_POSITION              0   xyzw        0      POS   float       
+// TEXCOORD                 0   xy          1     NONE   float   xy  
+//
+//
+// Output signature:
+//
+// Name                 Index   Mask Register SysValue  Format   Used
+// -------------------- ----- ------ -------- -------- ------- ------
+// SV_TARGET                0   xyzw        0   TARGET    uint   xyzw
+//
+ps_4_0
+dcl_sampler s0, mode_default
+dcl_resource_texture2d (float,float,float,float) t0
+dcl_input_ps linear v1.xy
+dcl_output o0.xyzw
+dcl_temps 1
+sample r0.xyzw, v1.xyxx, t0.xyzw, s0
+mul r0.xyzw, r0.xyzw, l(255.000000, 255.000000, 255.000000, 255.000000)
+ftou o0.xyzw, r0.xyzw
+ret 
+// Approximately 4 instruction slots used
+#endif
+
+const BYTE g_PS_FtoU_PT_RGBA[] = {
+    68,  88,  66,  67,  209, 83,  172, 72,  82,  105, 159, 134, 14,  29,  227, 217, 205, 178, 97,
+    208, 1,   0,   0,   0,   148, 2,   0,   0,   5,   0,   0,   0,   52,  0,   0,   0,   220, 0,
+    0,   0,   52,  1,   0,   0,   104, 1,   0,   0,   24,  2,   0,   0,   82,  68,  69,  70,  160,
+    0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   2,   0,   0,   0,   28,  0,   0,   0,
+    0,   4,   255, 255, 0,   1,   0,   0,   109, 0,   0,   0,   92,  0,   0,   0,   3,   0,   0,
+    0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   1,   0,
+    0,   0,   1,   0,   0,   0,   100, 0,   0,   0,   2,   0,   0,   0,   5,   0,   0,   0,   4,
+    0,   0,   0,   255, 255, 255, 255, 0,   0,   0,   0,   1,   0,   0,   0,   13,  0,   0,   0,
+    83,  97,  109, 112, 108, 101, 114, 0,   84,  101, 120, 116, 117, 114, 101, 70,  0,   77,  105,
+    99,  114, 111, 115, 111, 102, 116, 32,  40,  82,  41,  32,  72,  76,  83,  76,  32,  83,  104,
+    97,  100, 101, 114, 32,  67,  111, 109, 112, 105, 108, 101, 114, 32,  54,  46,  51,  46,  57,
+    54,  48,  48,  46,  49,  54,  51,  56,  52,  0,   171, 73,  83,  71,  78,  80,  0,   0,   0,
+    2,   0,   0,   0,   8,   0,   0,   0,   56,  0,   0,   0,   0,   0,   0,   0,   1,   0,   0,
+    0,   3,   0,   0,   0,   0,   0,   0,   0,   15,  0,   0,   0,   68,  0,   0,   0,   0,   0,
+    0,   0,   0,   0,   0,   0,   3,   0,   0,   0,   1,   0,   0,   0,   3,   3,   0,   0,   83,
+    86,  95,  80,  79,  83,  73,  84,  73,  79,  78,  0,   84,  69,  88,  67,  79,  79,  82,  68,
+    0,   171, 171, 171, 79,  83,  71,  78,  44,  0,   0,   0,   1,   0,   0,   0,   8,   0,   0,
+    0,   32,  0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   1,   0,   0,   0,   0,   0,
+    0,   0,   15,  0,   0,   0,   83,  86,  95,  84,  65,  82,  71,  69,  84,  0,   171, 171, 83,
+    72,  68,  82,  168, 0,   0,   0,   64,  0,   0,   0,   42,  0,   0,   0,   90,  0,   0,   3,
+    0,   96,  16,  0,   0,   0,   0,   0,   88,  24,  0,   4,   0,   112, 16,  0,   0,   0,   0,
+    0,   85,  85,  0,   0,   98,  16,  0,   3,   50,  16,  16,  0,   1,   0,   0,   0,   101, 0,
+    0,   3,   242, 32,  16,  0,   0,   0,   0,   0,   104, 0,   0,   2,   1,   0,   0,   0,   69,
+    0,   0,   9,   242, 0,   16,  0,   0,   0,   0,   0,   70,  16,  16,  0,   1,   0,   0,   0,
+    70,  126, 16,  0,   0,   0,   0,   0,   0,   96,  16,  0,   0,   0,   0,   0,   56,  0,   0,
+    10,  242, 0,   16,  0,   0,   0,   0,   0,   70,  14,  16,  0,   0,   0,   0,   0,   2,   64,
+    0,   0,   0,   0,   127, 67,  0,   0,   127, 67,  0,   0,   127, 67,  0,   0,   127, 67,  28,
+    0,   0,   5,   242, 32,  16,  0,   0,   0,   0,   0,   70,  14,  16,  0,   0,   0,   0,   0,
+    62,  0,   0,   1,   83,  84,  65,  84,  116, 0,   0,   0,   4,   0,   0,   0,   1,   0,   0,
+    0,   0,   0,   0,   0,   2,   0,   0,   0,   1,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+    0,   0,   1,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+    0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   1,   0,   0,   0,   0,   0,   0,   0,
+    0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+    0,   1,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+    0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0};
--- a/gfx/angle/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftou_um_rgb_ps.h
+++ b/gfx/angle/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftou_um_rgb_ps.h
@@ -1,87 +1,87 @@
-#if 0
-//
-// Generated by Microsoft (R) HLSL Shader Compiler 6.3.9600.16384
-//
-//
-// Resource Bindings:
-//
-// Name                                 Type  Format         Dim Slot Elements
-// ------------------------------ ---------- ------- ----------- ---- --------
-// Sampler                           sampler      NA          NA    0        1
-// TextureF                          texture  float4          2d    0        1
-//
-//
-//
-// Input signature:
-//
-// Name                 Index   Mask Register SysValue  Format   Used
-// -------------------- ----- ------ -------- -------- ------- ------
-// SV_POSITION              0   xyzw        0      POS   float       
-// TEXCOORD                 0   xy          1     NONE   float   xy  
-//
-//
-// Output signature:
-//
-// Name                 Index   Mask Register SysValue  Format   Used
-// -------------------- ----- ------ -------- -------- ------- ------
-// SV_TARGET                0   xyzw        0   TARGET    uint   xyzw
-//
-ps_4_0
-dcl_sampler s0, mode_default
-dcl_resource_texture2d (float,float,float,float) t0
-dcl_input_ps linear v1.xy
-dcl_output o0.xyzw
-dcl_temps 2
-sample r0.xyzw, v1.xyxx, t0.xyzw, s0
-lt r1.x, l(0.000000), r0.w
-div r1.yzw, r0.xxyz, r0.wwww
-movc r0.xyz, r1.xxxx, r1.yzwy, r0.xyzx
-mul r0.xyz, r0.xyzx, l(255.000000, 255.000000, 255.000000, 0.000000)
-ftou o0.xyz, r0.xyzx
-mov o0.w, l(1)
-ret 
-// Approximately 8 instruction slots used
-#endif
-
-const BYTE g_PS_FtoU_UM_RGB[] = {
-    68,  88,  66,  67,  82,  251, 238, 157, 164, 167, 205, 115, 177, 233, 1,   41, 133, 200, 183,
-    107, 1,   0,   0,   0,   4,   3,   0,   0,   5,   0,   0,   0,   52,  0,   0,  0,   220, 0,
-    0,   0,   52,  1,   0,   0,   104, 1,   0,   0,   136, 2,   0,   0,   82,  68, 69,  70,  160,
-    0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   2,   0,   0,   0,   28, 0,   0,   0,
-    0,   4,   255, 255, 0,   1,   0,   0,   109, 0,   0,   0,   92,  0,   0,   0,  3,   0,   0,
-    0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,  0,   1,   0,
-    0,   0,   1,   0,   0,   0,   100, 0,   0,   0,   2,   0,   0,   0,   5,   0,  0,   0,   4,
-    0,   0,   0,   255, 255, 255, 255, 0,   0,   0,   0,   1,   0,   0,   0,   13, 0,   0,   0,
-    83,  97,  109, 112, 108, 101, 114, 0,   84,  101, 120, 116, 117, 114, 101, 70, 0,   77,  105,
-    99,  114, 111, 115, 111, 102, 116, 32,  40,  82,  41,  32,  72,  76,  83,  76, 32,  83,  104,
-    97,  100, 101, 114, 32,  67,  111, 109, 112, 105, 108, 101, 114, 32,  54,  46, 51,  46,  57,
-    54,  48,  48,  46,  49,  54,  51,  56,  52,  0,   171, 73,  83,  71,  78,  80, 0,   0,   0,
-    2,   0,   0,   0,   8,   0,   0,   0,   56,  0,   0,   0,   0,   0,   0,   0,  1,   0,   0,
-    0,   3,   0,   0,   0,   0,   0,   0,   0,   15,  0,   0,   0,   68,  0,   0,  0,   0,   0,
-    0,   0,   0,   0,   0,   0,   3,   0,   0,   0,   1,   0,   0,   0,   3,   3,  0,   0,   83,
-    86,  95,  80,  79,  83,  73,  84,  73,  79,  78,  0,   84,  69,  88,  67,  79, 79,  82,  68,
-    0,   171, 171, 171, 79,  83,  71,  78,  44,  0,   0,   0,   1,   0,   0,   0,  8,   0,   0,
-    0,   32,  0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   1,   0,   0,  0,   0,   0,
-    0,   0,   15,  0,   0,   0,   83,  86,  95,  84,  65,  82,  71,  69,  84,  0,  171, 171, 83,
-    72,  68,  82,  24,  1,   0,   0,   64,  0,   0,   0,   70,  0,   0,   0,   90, 0,   0,   3,
-    0,   96,  16,  0,   0,   0,   0,   0,   88,  24,  0,   4,   0,   112, 16,  0,  0,   0,   0,
-    0,   85,  85,  0,   0,   98,  16,  0,   3,   50,  16,  16,  0,   1,   0,   0,  0,   101, 0,
-    0,   3,   242, 32,  16,  0,   0,   0,   0,   0,   104, 0,   0,   2,   2,   0,  0,   0,   69,
-    0,   0,   9,   242, 0,   16,  0,   0,   0,   0,   0,   70,  16,  16,  0,   1,  0,   0,   0,
-    70,  126, 16,  0,   0,   0,   0,   0,   0,   96,  16,  0,   0,   0,   0,   0,  49,  0,   0,
-    7,   18,  0,   16,  0,   1,   0,   0,   0,   1,   64,  0,   0,   0,   0,   0,  0,   58,  0,
-    16,  0,   0,   0,   0,   0,   14,  0,   0,   7,   226, 0,   16,  0,   1,   0,  0,   0,   6,
-    9,   16,  0,   0,   0,   0,   0,   246, 15,  16,  0,   0,   0,   0,   0,   55, 0,   0,   9,
-    114, 0,   16,  0,   0,   0,   0,   0,   6,   0,   16,  0,   1,   0,   0,   0,  150, 7,   16,
-    0,   1,   0,   0,   0,   70,  2,   16,  0,   0,   0,   0,   0,   56,  0,   0,  10,  114, 0,
-    16,  0,   0,   0,   0,   0,   70,  2,   16,  0,   0,   0,   0,   0,   2,   64, 0,   0,   0,
-    0,   127, 67,  0,   0,   127, 67,  0,   0,   127, 67,  0,   0,   0,   0,   28, 0,   0,   5,
-    114, 32,  16,  0,   0,   0,   0,   0,   70,  2,   16,  0,   0,   0,   0,   0,  54,  0,   0,
-    5,   130, 32,  16,  0,   0,   0,   0,   0,   1,   64,  0,   0,   1,   0,   0,  0,   62,  0,
-    0,   1,   83,  84,  65,  84,  116, 0,   0,   0,   8,   0,   0,   0,   2,   0,  0,   0,   0,
-    0,   0,   0,   2,   0,   0,   0,   3,   0,   0,   0,   0,   0,   0,   0,   0,  0,   0,   0,
-    1,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,  0,   0,   0,
-    0,   0,   0,   0,   0,   0,   0,   0,   0,   1,   0,   0,   0,   0,   0,   0,  0,   0,   0,
-    0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   1,   0,   0,   0,   1,   0,  0,   0,   1,
-    0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,  0,   0,   0,
-    0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0};
+#if 0
+//
+// Generated by Microsoft (R) HLSL Shader Compiler 6.3.9600.16384
+//
+//
+// Resource Bindings:
+//
+// Name                                 Type  Format         Dim Slot Elements
+// ------------------------------ ---------- ------- ----------- ---- --------
+// Sampler                           sampler      NA          NA    0        1
+// TextureF                          texture  float4          2d    0        1
+//
+//
+//
+// Input signature:
+//
+// Name                 Index   Mask Register SysValue  Format   Used
+// -------------------- ----- ------ -------- -------- ------- ------
+// SV_POSITION              0   xyzw        0      POS   float       
+// TEXCOORD                 0   xy          1     NONE   float   xy  
+//
+//
+// Output signature:
+//
+// Name                 Index   Mask Register SysValue  Format   Used
+// -------------------- ----- ------ -------- -------- ------- ------
+// SV_TARGET                0   xyzw        0   TARGET    uint   xyzw
+//
+ps_4_0
+dcl_sampler s0, mode_default
+dcl_resource_texture2d (float,float,float,float) t0
+dcl_input_ps linear v1.xy
+dcl_output o0.xyzw
+dcl_temps 2
+sample r0.xyzw, v1.xyxx, t0.xyzw, s0
+lt r1.x, l(0.000000), r0.w
+div r1.yzw, r0.xxyz, r0.wwww
+movc r0.xyz, r1.xxxx, r1.yzwy, r0.xyzx
+mul r0.xyz, r0.xyzx, l(255.000000, 255.000000, 255.000000, 0.000000)
+ftou o0.xyz, r0.xyzx
+mov o0.w, l(1)
+ret 
+// Approximately 8 instruction slots used
+#endif
+
+const BYTE g_PS_FtoU_UM_RGB[] = {
+    68,  88,  66,  67,  82,  251, 238, 157, 164, 167, 205, 115, 177, 233, 1,   41, 133, 200, 183,
+    107, 1,   0,   0,   0,   4,   3,   0,   0,   5,   0,   0,   0,   52,  0,   0,  0,   220, 0,
+    0,   0,   52,  1,   0,   0,   104, 1,   0,   0,   136, 2,   0,   0,   82,  68, 69,  70,  160,
+    0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   2,   0,   0,   0,   28, 0,   0,   0,
+    0,   4,   255, 255, 0,   1,   0,   0,   109, 0,   0,   0,   92,  0,   0,   0,  3,   0,   0,
+    0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,  0,   1,   0,
+    0,   0,   1,   0,   0,   0,   100, 0,   0,   0,   2,   0,   0,   0,   5,   0,  0,   0,   4,
+    0,   0,   0,   255, 255, 255, 255, 0,   0,   0,   0,   1,   0,   0,   0,   13, 0,   0,   0,
+    83,  97,  109, 112, 108, 101, 114, 0,   84,  101, 120, 116, 117, 114, 101, 70, 0,   77,  105,
+    99,  114, 111, 115, 111, 102, 116, 32,  40,  82,  41,  32,  72,  76,  83,  76, 32,  83,  104,
+    97,  100, 101, 114, 32,  67,  111, 109, 112, 105, 108, 101, 114, 32,  54,  46, 51,  46,  57,
+    54,  48,  48,  46,  49,  54,  51,  56,  52,  0,   171, 73,  83,  71,  78,  80, 0,   0,   0,
+    2,   0,   0,   0,   8,   0,   0,   0,   56,  0,   0,   0,   0,   0,   0,   0,  1,   0,   0,
+    0,   3,   0,   0,   0,   0,   0,   0,   0,   15,  0,   0,   0,   68,  0,   0,  0,   0,   0,
+    0,   0,   0,   0,   0,   0,   3,   0,   0,   0,   1,   0,   0,   0,   3,   3,  0,   0,   83,
+    86,  95,  80,  79,  83,  73,  84,  73,  79,  78,  0,   84,  69,  88,  67,  79, 79,  82,  68,
+    0,   171, 171, 171, 79,  83,  71,  78,  44,  0,   0,   0,   1,   0,   0,   0,  8,   0,   0,
+    0,   32,  0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   1,   0,   0,  0,   0,   0,
+    0,   0,   15,  0,   0,   0,   83,  86,  95,  84,  65,  82,  71,  69,  84,  0,  171, 171, 83,
+    72,  68,  82,  24,  1,   0,   0,   64,  0,   0,   0,   70,  0,   0,   0,   90, 0,   0,   3,
+    0,   96,  16,  0,   0,   0,   0,   0,   88,  24,  0,   4,   0,   112, 16,  0,  0,   0,   0,
+    0,   85,  85,  0,   0,   98,  16,  0,   3,   50,  16,  16,  0,   1,   0,   0,  0,   101, 0,
+    0,   3,   242, 32,  16,  0,   0,   0,   0,   0,   104, 0,   0,   2,   2,   0,  0,   0,   69,
+    0,   0,   9,   242, 0,   16,  0,   0,   0,   0,   0,   70,  16,  16,  0,   1,  0,   0,   0,
+    70,  126, 16,  0,   0,   0,   0,   0,   0,   96,  16,  0,   0,   0,   0,   0,  49,  0,   0,
+    7,   18,  0,   16,  0,   1,   0,   0,   0,   1,   64,  0,   0,   0,   0,   0,  0,   58,  0,
+    16,  0,   0,   0,   0,   0,   14,  0,   0,   7,   226, 0,   16,  0,   1,   0,  0,   0,   6,
+    9,   16,  0,   0,   0,   0,   0,   246, 15,  16,  0,   0,   0,   0,   0,   55, 0,   0,   9,
+    114, 0,   16,  0,   0,   0,   0,   0,   6,   0,   16,  0,   1,   0,   0,   0,  150, 7,   16,
+    0,   1,   0,   0,   0,   70,  2,   16,  0,   0,   0,   0,   0,   56,  0,   0,  10,  114, 0,
+    16,  0,   0,   0,   0,   0,   70,  2,   16,  0,   0,   0,   0,   0,   2,   64, 0,   0,   0,
+    0,   127, 67,  0,   0,   127, 67,  0,   0,   127, 67,  0,   0,   0,   0,   28, 0,   0,   5,
+    114, 32,  16,  0,   0,   0,   0,   0,   70,  2,   16,  0,   0,   0,   0,   0,  54,  0,   0,
+    5,   130, 32,  16,  0,   0,   0,   0,   0,   1,   64,  0,   0,   1,   0,   0,  0,   62,  0,
+    0,   1,   83,  84,  65,  84,  116, 0,   0,   0,   8,   0,   0,   0,   2,   0,  0,   0,   0,
+    0,   0,   0,   2,   0,   0,   0,   3,   0,   0,   0,   0,   0,   0,   0,   0,  0,   0,   0,
+    1,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,  0,   0,   0,
+    0,   0,   0,   0,   0,   0,   0,   0,   0,   1,   0,   0,   0,   0,   0,   0,  0,   0,   0,
+    0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   1,   0,   0,   0,   1,   0,  0,   0,   1,
+    0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,  0,   0,   0,
+    0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0};
--- a/gfx/angle/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftou_um_rgba_ps.h
+++ b/gfx/angle/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftou_um_rgba_ps.h
@@ -1,85 +1,85 @@
-#if 0
-//
-// Generated by Microsoft (R) HLSL Shader Compiler 6.3.9600.16384
-//
-//
-// Resource Bindings:
-//
-// Name                                 Type  Format         Dim Slot Elements
-// ------------------------------ ---------- ------- ----------- ---- --------
-// Sampler                           sampler      NA          NA    0        1
-// TextureF                          texture  float4          2d    0        1
-//
-//
-//
-// Input signature:
-//
-// Name                 Index   Mask Register SysValue  Format   Used
-// -------------------- ----- ------ -------- -------- ------- ------
-// SV_POSITION              0   xyzw        0      POS   float       
-// TEXCOORD                 0   xy          1     NONE   float   xy  
-//
-//
-// Output signature:
-//
-// Name                 Index   Mask Register SysValue  Format   Used
-// -------------------- ----- ------ -------- -------- ------- ------
-// SV_TARGET                0   xyzw        0   TARGET    uint   xyzw
-//
-ps_4_0
-dcl_sampler s0, mode_default
-dcl_resource_texture2d (float,float,float,float) t0
-dcl_input_ps linear v1.xy
-dcl_output o0.xyzw
-dcl_temps 2
-sample r0.xyzw, v1.xyxx, t0.xyzw, s0
-lt r1.x, l(0.000000), r0.w
-div r1.yzw, r0.xxyz, r0.wwww
-movc r0.xyz, r1.xxxx, r1.yzwy, r0.xyzx
-mul r0.xyzw, r0.xyzw, l(255.000000, 255.000000, 255.000000, 255.000000)
-ftou o0.xyzw, r0.xyzw
-ret 
-// Approximately 7 instruction slots used
-#endif
-
-const BYTE g_PS_FtoU_UM_RGBA[] = {
-    68,  88,  66,  67,  43,  223, 220, 54,  150, 139, 210, 139, 116, 210, 25,  161, 205, 213, 104,
-    156, 1,   0,   0,   0,   240, 2,   0,   0,   5,   0,   0,   0,   52,  0,   0,   0,   220, 0,
-    0,   0,   52,  1,   0,   0,   104, 1,   0,   0,   116, 2,   0,   0,   82,  68,  69,  70,  160,
-    0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   2,   0,   0,   0,   28,  0,   0,   0,
-    0,   4,   255, 255, 0,   1,   0,   0,   109, 0,   0,   0,   92,  0,   0,   0,   3,   0,   0,
-    0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   1,   0,
-    0,   0,   1,   0,   0,   0,   100, 0,   0,   0,   2,   0,   0,   0,   5,   0,   0,   0,   4,
-    0,   0,   0,   255, 255, 255, 255, 0,   0,   0,   0,   1,   0,   0,   0,   13,  0,   0,   0,
-    83,  97,  109, 112, 108, 101, 114, 0,   84,  101, 120, 116, 117, 114, 101, 70,  0,   77,  105,
-    99,  114, 111, 115, 111, 102, 116, 32,  40,  82,  41,  32,  72,  76,  83,  76,  32,  83,  104,
-    97,  100, 101, 114, 32,  67,  111, 109, 112, 105, 108, 101, 114, 32,  54,  46,  51,  46,  57,
-    54,  48,  48,  46,  49,  54,  51,  56,  52,  0,   171, 73,  83,  71,  78,  80,  0,   0,   0,
-    2,   0,   0,   0,   8,   0,   0,   0,   56,  0,   0,   0,   0,   0,   0,   0,   1,   0,   0,
-    0,   3,   0,   0,   0,   0,   0,   0,   0,   15,  0,   0,   0,   68,  0,   0,   0,   0,   0,
-    0,   0,   0,   0,   0,   0,   3,   0,   0,   0,   1,   0,   0,   0,   3,   3,   0,   0,   83,
-    86,  95,  80,  79,  83,  73,  84,  73,  79,  78,  0,   84,  69,  88,  67,  79,  79,  82,  68,
-    0,   171, 171, 171, 79,  83,  71,  78,  44,  0,   0,   0,   1,   0,   0,   0,   8,   0,   0,
-    0,   32,  0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   1,   0,   0,   0,   0,   0,
-    0,   0,   15,  0,   0,   0,   83,  86,  95,  84,  65,  82,  71,  69,  84,  0,   171, 171, 83,
-    72,  68,  82,  4,   1,   0,   0,   64,  0,   0,   0,   65,  0,   0,   0,   90,  0,   0,   3,
-    0,   96,  16,  0,   0,   0,   0,   0,   88,  24,  0,   4,   0,   112, 16,  0,   0,   0,   0,
-    0,   85,  85,  0,   0,   98,  16,  0,   3,   50,  16,  16,  0,   1,   0,   0,   0,   101, 0,
-    0,   3,   242, 32,  16,  0,   0,   0,   0,   0,   104, 0,   0,   2,   2,   0,   0,   0,   69,
-    0,   0,   9,   242, 0,   16,  0,   0,   0,   0,   0,   70,  16,  16,  0,   1,   0,   0,   0,
-    70,  126, 16,  0,   0,   0,   0,   0,   0,   96,  16,  0,   0,   0,   0,   0,   49,  0,   0,
-    7,   18,  0,   16,  0,   1,   0,   0,   0,   1,   64,  0,   0,   0,   0,   0,   0,   58,  0,
-    16,  0,   0,   0,   0,   0,   14,  0,   0,   7,   226, 0,   16,  0,   1,   0,   0,   0,   6,
-    9,   16,  0,   0,   0,   0,   0,   246, 15,  16,  0,   0,   0,   0,   0,   55,  0,   0,   9,
-    114, 0,   16,  0,   0,   0,   0,   0,   6,   0,   16,  0,   1,   0,   0,   0,   150, 7,   16,
-    0,   1,   0,   0,   0,   70,  2,   16,  0,   0,   0,   0,   0,   56,  0,   0,   10,  242, 0,
-    16,  0,   0,   0,   0,   0,   70,  14,  16,  0,   0,   0,   0,   0,   2,   64,  0,   0,   0,
-    0,   127, 67,  0,   0,   127, 67,  0,   0,   127, 67,  0,   0,   127, 67,  28,  0,   0,   5,
-    242, 32,  16,  0,   0,   0,   0,   0,   70,  14,  16,  0,   0,   0,   0,   0,   62,  0,   0,
-    1,   83,  84,  65,  84,  116, 0,   0,   0,   7,   0,   0,   0,   2,   0,   0,   0,   0,   0,
-    0,   0,   2,   0,   0,   0,   3,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   1,
-    0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
-    0,   0,   0,   0,   0,   0,   0,   0,   1,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
-    0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   1,   0,   0,   0,   1,   0,
-    0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
-    0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0};
+#if 0
+//
+// Generated by Microsoft (R) HLSL Shader Compiler 6.3.9600.16384
+//
+//
+// Resource Bindings:
+//
+// Name                                 Type  Format         Dim Slot Elements
+// ------------------------------ ---------- ------- ----------- ---- --------
+// Sampler                           sampler      NA          NA    0        1
+// TextureF                          texture  float4          2d    0        1
+//
+//
+//
+// Input signature:
+//
+// Name                 Index   Mask Register SysValue  Format   Used
+// -------------------- ----- ------ -------- -------- ------- ------
+// SV_POSITION              0   xyzw        0      POS   float       
+// TEXCOORD                 0   xy          1     NONE   float   xy  
+//
+//
+// Output signature:
+//
+// Name                 Index   Mask Register SysValue  Format   Used
+// -------------------- ----- ------ -------- -------- ------- ------
+// SV_TARGET                0   xyzw        0   TARGET    uint   xyzw
+//
+ps_4_0
+dcl_sampler s0, mode_default
+dcl_resource_texture2d (float,float,float,float) t0
+dcl_input_ps linear v1.xy
+dcl_output o0.xyzw
+dcl_temps 2
+sample r0.xyzw, v1.xyxx, t0.xyzw, s0
+lt r1.x, l(0.000000), r0.w
+div r1.yzw, r0.xxyz, r0.wwww
+movc r0.xyz, r1.xxxx, r1.yzwy, r0.xyzx
+mul r0.xyzw, r0.xyzw, l(255.000000, 255.000000, 255.000000, 255.000000)
+ftou o0.xyzw, r0.xyzw
+ret 
+// Approximately 7 instruction slots used
+#endif
+
+const BYTE g_PS_FtoU_UM_RGBA[] = {
+    68,  88,  66,  67,  43,  223, 220, 54,  150, 139, 210, 139, 116, 210, 25,  161, 205, 213, 104,
+    156, 1,   0,   0,   0,   240, 2,   0,   0,   5,   0,   0,   0,   52,  0,   0,   0,   220, 0,
+    0,   0,   52,  1,   0,   0,   104, 1,   0,   0,   116, 2,   0,   0,   82,  68,  69,  70,  160,
+    0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   2,   0,   0,   0,   28,  0,   0,   0,
+    0,   4,   255, 255, 0,   1,   0,   0,   109, 0,   0,   0,   92,  0,   0,   0,   3,   0,   0,
+    0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   1,   0,
+    0,   0,   1,   0,   0,   0,   100, 0,   0,   0,   2,   0,   0,   0,   5,   0,   0,   0,   4,
+    0,   0,   0,   255, 255, 255, 255, 0,   0,   0,   0,   1,   0,   0,   0,   13,  0,   0,   0,
+    83,  97,  109, 112, 108, 101, 114, 0,   84,  101, 120, 116, 117, 114, 101, 70,  0,   77,  105,
+    99,  114, 111, 115, 111, 102, 116, 32,  40,  82,  41,  32,  72,  76,  83,  76,  32,  83,  104,
+    97,  100, 101, 114, 32,  67,  111, 109, 112, 105, 108, 101, 114, 32,  54,  46,  51,  46,  57,
+    54,  48,  48,  46,  49,  54,  51,  56,  52,  0,   171, 73,  83,  71,  78,  80,  0,   0,   0,
+    2,   0,   0,   0,   8,   0,   0,   0,   56,  0,   0,   0,   0,   0,   0,   0,   1,   0,   0,
+    0,   3,   0,   0,   0,   0,   0,   0,   0,   15,  0,   0,   0,   68,  0,   0,   0,   0,   0,
+    0,   0,   0,   0,   0,   0,   3,   0,   0,   0,   1,   0,   0,   0,   3,   3,   0,   0,   83,
+    86,  95,  80,  79,  83,  73,  84,  73,  79,  78,  0,   84,  69,  88,  67,  79,  79,  82,  68,
+    0,   171, 171, 171, 79,  83,  71,  78,  44,  0,   0,   0,   1,   0,   0,   0,   8,   0,   0,
+    0,   32,  0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   1,   0,   0,   0,   0,   0,
+    0,   0,   15,  0,   0,   0,   83,  86,  95,  84,  65,  82,  71,  69,  84,  0,   171, 171, 83,
+    72,  68,  82,  4,   1,   0,   0,   64,  0,   0,   0,   65,  0,   0,   0,   90,  0,   0,   3,
+    0,   96,  16,  0,   0,   0,   0,   0,   88,  24,  0,   4,   0,   112, 16,  0,   0,   0,   0,
+    0,   85,  85,  0,   0,   98,  16,  0,   3,   50,  16,  16,  0,   1,   0,   0,   0,   101, 0,
+    0,   3,   242, 32,  16,  0,   0,   0,   0,   0,   104, 0,   0,   2,   2,   0,   0,   0,   69,
+    0,   0,   9,   242, 0,   16,  0,   0,   0,   0,   0,   70,  16,  16,  0,   1,   0,   0,   0,
+    70,  126, 16,  0,   0,   0,   0,   0,   0,   96,  16,  0,   0,   0,   0,   0,   49,  0,   0,
+    7,   18,  0,   16,  0,   1,   0,   0,   0,   1,   64,  0,   0,   0,   0,   0,   0,   58,  0,
+    16,  0,   0,   0,   0,   0,   14,  0,   0,   7,   226, 0,   16,  0,   1,   0,   0,   0,   6,
+    9,   16,  0,   0,   0,   0,   0,   246, 15,  16,  0,   0,   0,   0,   0,   55,  0,   0,   9,
+    114, 0,   16,  0,   0,   0,   0,   0,   6,   0,   16,  0,   1,   0,   0,   0,   150, 7,   16,
+    0,   1,   0,   0,   0,   70,  2,   16,  0,   0,   0,   0,   0,   56,  0,   0,   10,  242, 0,
+    16,  0,   0,   0,   0,   0,   70,  14,  16,  0,   0,   0,   0,   0,   2,   64,  0,   0,   0,
+    0,   127, 67,  0,   0,   127, 67,  0,   0,   127, 67,  0,   0,   127, 67,  28,  0,   0,   5,
+    242, 32,  16,  0,   0,   0,   0,   0,   70,  14,  16,  0,   0,   0,   0,   0,   62,  0,   0,
+    1,   83,  84,  65,  84,  116, 0,   0,   0,   7,   0,   0,   0,   2,   0,   0,   0,   0,   0,
+    0,   0,   2,   0,   0,   0,   3,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   1,
+    0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+    0,   0,   0,   0,   0,   0,   0,   0,   1,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+    0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   1,   0,   0,   0,   1,   0,
+    0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+    0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0};
--- a/gfx/angle/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthrough2d11vs.h
+++ b/gfx/angle/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthrough2d11vs.h
@@ -1,177 +1,177 @@
-#if 0
-//
-// Generated by Microsoft (R) HLSL Shader Compiler 6.3.9600.16384
-//
-//
-//
-// Input signature:
-//
-// Name                 Index   Mask Register SysValue  Format   Used
-// -------------------- ----- ------ -------- -------- ------- ------
-// POSITION                 0   xy          0     NONE   float   xy  
-// TEXCOORD                 0   xy          1     NONE   float   xy  
-//
-//
-// Output signature:
-//
-// Name                 Index   Mask Register SysValue  Format   Used
-// -------------------- ----- ------ -------- -------- ------- ------
-// SV_POSITION              0   xyzw        0      POS   float   xyzw
-// TEXCOORD                 0   xy          1     NONE   float   xy  
-//
-//
-// Runtime generated constant mappings:
-//
-// Target Reg                               Constant Description
-// ---------- --------------------------------------------------
-// c0                              Vertex Shader position offset
-//
-//
-// Level9 shader bytecode:
-//
-    vs_2_x
-    def c1, 0, 1, 0, 0
-    dcl_texcoord v0
-    dcl_texcoord1 v1
-    add oPos.xy, v0, c0
-    mov oPos.zw, c1.xyxy
-    mov oT0.xy, v1
-
-// approximately 3 instruction slots used
-vs_4_0
-dcl_input v0.xy
-dcl_input v1.xy
-dcl_output_siv o0.xyzw, position
-dcl_output o1.xy
-mov o0.xy, v0.xyxx
-mov o0.zw, l(0,0,0,1.000000)
-mov o1.xy, v1.xyxx
-ret 
-// Approximately 4 instruction slots used
-#endif
-
-const BYTE g_VS_Passthrough2D[] =
-{
-     68,  88,  66,  67, 230,  95, 
-    115, 230,  65, 211,  74,  82, 
-    143, 170, 109, 175,  63, 210, 
-     14, 229,   1,   0,   0,   0, 
-    216,   2,   0,   0,   6,   0, 
-      0,   0,  56,   0,   0,   0, 
-    200,   0,   0,   0,  88,   1, 
-      0,   0, 212,   1,   0,   0, 
-     44,   2,   0,   0, 128,   2, 
-      0,   0,  65, 111, 110,  57, 
-    136,   0,   0,   0, 136,   0, 
-      0,   0,   0,   2, 254, 255, 
-     96,   0,   0,   0,  40,   0, 
-      0,   0,   0,   0,  36,   0, 
-      0,   0,  36,   0,   0,   0, 
-     36,   0,   0,   0,  36,   0, 
-      1,   0,  36,   0,   0,   0, 
-      0,   0,   1,   2, 254, 255, 
-     81,   0,   0,   5,   1,   0, 
-     15, 160,   0,   0,   0,   0, 
-      0,   0, 128,  63,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-     31,   0,   0,   2,   5,   0, 
-      0, 128,   0,   0,  15, 144, 
-     31,   0,   0,   2,   5,   0, 
-      1, 128,   1,   0,  15, 144, 
-      2,   0,   0,   3,   0,   0, 
-      3, 192,   0,   0, 228, 144, 
-      0,   0, 228, 160,   1,   0, 
-      0,   2,   0,   0,  12, 192, 
-      1,   0,  68, 160,   1,   0, 
-      0,   2,   0,   0,   3, 224, 
-      1,   0, 228, 144, 255, 255, 
-      0,   0,  83,  72,  68,  82, 
-    136,   0,   0,   0,  64,   0, 
-      1,   0,  34,   0,   0,   0, 
-     95,   0,   0,   3,  50,  16, 
-     16,   0,   0,   0,   0,   0, 
-     95,   0,   0,   3,  50,  16, 
-     16,   0,   1,   0,   0,   0, 
-    103,   0,   0,   4, 242,  32, 
-     16,   0,   0,   0,   0,   0, 
-      1,   0,   0,   0, 101,   0, 
-      0,   3,  50,  32,  16,   0, 
-      1,   0,   0,   0,  54,   0, 
-      0,   5,  50,  32,  16,   0, 
-      0,   0,   0,   0,  70,  16, 
-     16,   0,   0,   0,   0,   0, 
-     54,   0,   0,   8, 194,  32, 
-     16,   0,   0,   0,   0,   0, 
-      2,  64,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-    128,  63,  54,   0,   0,   5, 
-     50,  32,  16,   0,   1,   0, 
-      0,   0,  70,  16,  16,   0, 
-      1,   0,   0,   0,  62,   0, 
-      0,   1,  83,  84,  65,  84, 
-    116,   0,   0,   0,   4,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   4,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   1,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   3,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-     82,  68,  69,  70,  80,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,  28,   0,   0,   0, 
-      0,   4, 254, 255,   0,   1, 
-      0,   0,  28,   0,   0,   0, 
-     77, 105,  99, 114, 111, 115, 
-    111, 102, 116,  32,  40,  82, 
-     41,  32,  72,  76,  83,  76, 
-     32,  83, 104,  97, 100, 101, 
-    114,  32,  67, 111, 109, 112, 
-    105, 108, 101, 114,  32,  54, 
-     46,  51,  46,  57,  54,  48, 
-     48,  46,  49,  54,  51,  56, 
-     52,   0, 171, 171,  73,  83, 
-     71,  78,  76,   0,   0,   0, 
-      2,   0,   0,   0,   8,   0, 
-      0,   0,  56,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   3,   0,   0,   0, 
-      0,   0,   0,   0,   3,   3, 
-      0,   0,  65,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   3,   0,   0,   0, 
-      1,   0,   0,   0,   3,   3, 
-      0,   0,  80,  79,  83,  73, 
-     84,  73,  79,  78,   0,  84, 
-     69,  88,  67,  79,  79,  82, 
-     68,   0, 171, 171,  79,  83, 
-     71,  78,  80,   0,   0,   0, 
-      2,   0,   0,   0,   8,   0, 
-      0,   0,  56,   0,   0,   0, 
-      0,   0,   0,   0,   1,   0, 
-      0,   0,   3,   0,   0,   0, 
-      0,   0,   0,   0,  15,   0, 
-      0,   0,  68,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   3,   0,   0,   0, 
-      1,   0,   0,   0,   3,  12, 
-      0,   0,  83,  86,  95,  80, 
-     79,  83,  73,  84,  73,  79, 
-     78,   0,  84,  69,  88,  67, 
-     79,  79,  82,  68,   0, 171, 
-    171, 171
-};
+#if 0
+//
+// Generated by Microsoft (R) HLSL Shader Compiler 6.3.9600.16384
+//
+//
+//
+// Input signature:
+//
+// Name                 Index   Mask Register SysValue  Format   Used
+// -------------------- ----- ------ -------- -------- ------- ------
+// POSITION                 0   xy          0     NONE   float   xy  
+// TEXCOORD                 0   xy          1     NONE   float   xy  
+//
+//
+// Output signature:
+//
+// Name                 Index   Mask Register SysValue  Format   Used
+// -------------------- ----- ------ -------- -------- ------- ------
+// SV_POSITION              0   xyzw        0      POS   float   xyzw
+// TEXCOORD                 0   xy          1     NONE   float   xy  
+//
+//
+// Runtime generated constant mappings:
+//
+// Target Reg                               Constant Description
+// ---------- --------------------------------------------------
+// c0                              Vertex Shader position offset
+//
+//
+// Level9 shader bytecode:
+//
+    vs_2_x
+    def c1, 0, 1, 0, 0
+    dcl_texcoord v0
+    dcl_texcoord1 v1
+    add oPos.xy, v0, c0
+    mov oPos.zw, c1.xyxy
+    mov oT0.xy, v1
+
+// approximately 3 instruction slots used
+vs_4_0
+dcl_input v0.xy
+dcl_input v1.xy
+dcl_output_siv o0.xyzw, position
+dcl_output o1.xy
+mov o0.xy, v0.xyxx
+mov o0.zw, l(0,0,0,1.000000)
+mov o1.xy, v1.xyxx
+ret 
+// Approximately 4 instruction slots used
+#endif
+
+const BYTE g_VS_Passthrough2D[] =
+{
+     68,  88,  66,  67, 230,  95, 
+    115, 230,  65, 211,  74,  82, 
+    143, 170, 109, 175,  63, 210, 
+     14, 229,   1,   0,   0,   0, 
+    216,   2,   0,   0,   6,   0, 
+      0,   0,  56,   0,   0,   0, 
+    200,   0,   0,   0,  88,   1, 
+      0,   0, 212,   1,   0,   0, 
+     44,   2,   0,   0, 128,   2, 
+      0,   0,  65, 111, 110,  57, 
+    136,   0,   0,   0, 136,   0, 
+      0,   0,   0,   2, 254, 255, 
+     96,   0,   0,   0,  40,   0, 
+      0,   0,   0,   0,  36,   0, 
+      0,   0,  36,   0,   0,   0, 
+     36,   0,   0,   0,  36,   0, 
+      1,   0,  36,   0,   0,   0, 
+      0,   0,   1,   2, 254, 255, 
+     81,   0,   0,   5,   1,   0, 
+     15, 160,   0,   0,   0,   0, 
+      0,   0, 128,  63,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+     31,   0,   0,   2,   5,   0, 
+      0, 128,   0,   0,  15, 144, 
+     31,   0,   0,   2,   5,   0, 
+      1, 128,   1,   0,  15, 144, 
+      2,   0,   0,   3,   0,   0, 
+      3, 192,   0,   0, 228, 144, 
+      0,   0, 228, 160,   1,   0, 
+      0,   2,   0,   0,  12, 192, 
+      1,   0,  68, 160,   1,   0, 
+      0,   2,   0,   0,   3, 224, 
+      1,   0, 228, 144, 255, 255, 
+      0,   0,  83,  72,  68,  82, 
+    136,   0,   0,   0,  64,   0, 
+      1,   0,  34,   0,   0,   0, 
+     95,   0,   0,   3,  50,  16, 
+     16,   0,   0,   0,   0,   0, 
+     95,   0,   0,   3,  50,  16, 
+     16,   0,   1,   0,   0,   0, 
+    103,   0,   0,   4, 242,  32, 
+     16,   0,   0,   0,   0,   0, 
+      1,   0,   0,   0, 101,   0, 
+      0,   3,  50,  32,  16,   0, 
+      1,   0,   0,   0,  54,   0, 
+      0,   5,  50,  32,  16,   0, 
+      0,   0,   0,   0,  70,  16, 
+     16,   0,   0,   0,   0,   0, 
+     54,   0,   0,   8, 194,  32, 
+     16,   0,   0,   0,   0,   0, 
+      2,  64,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+    128,  63,  54,   0,   0,   5, 
+     50,  32,  16,   0,   1,   0, 
+      0,   0,  70,  16,  16,   0, 
+      1,   0,   0,   0,  62,   0, 
+      0,   1,  83,  84,  65,  84, 
+    116,   0,   0,   0,   4,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   4,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   1,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   3,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+     82,  68,  69,  70,  80,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,  28,   0,   0,   0, 
+      0,   4, 254, 255,   0,   1, 
+      0,   0,  28,   0,   0,   0, 
+     77, 105,  99, 114, 111, 115, 
+    111, 102, 116,  32,  40,  82, 
+     41,  32,  72,  76,  83,  76, 
+     32,  83, 104,  97, 100, 101, 
+    114,  32,  67, 111, 109, 112, 
+    105, 108, 101, 114,  32,  54, 
+     46,  51,  46,  57,  54,  48, 
+     48,  46,  49,  54,  51,  56, 
+     52,   0, 171, 171,  73,  83, 
+     71,  78,  76,   0,   0,   0, 
+      2,   0,   0,   0,   8,   0, 
+      0,   0,  56,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   3,   0,   0,   0, 
+      0,   0,   0,   0,   3,   3, 
+      0,   0,  65,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   3,   0,   0,   0, 
+      1,   0,   0,   0,   3,   3, 
+      0,   0,  80,  79,  83,  73, 
+     84,  73,  79,  78,   0,  84, 
+     69,  88,  67,  79,  79,  82, 
+     68,   0, 171, 171,  79,  83, 
+     71,  78,  80,   0,   0,   0, 
+      2,   0,   0,   0,   8,   0, 
+      0,   0,  56,   0,   0,   0, 
+      0,   0,   0,   0,   1,   0, 
+      0,   0,   3,   0,   0,   0, 
+      0,   0,   0,   0,  15,   0, 
+      0,   0,  68,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   3,   0,   0,   0, 
+      1,   0,   0,   0,   3,  12, 
+      0,   0,  83,  86,  95,  80, 
+     79,  83,  73,  84,  73,  79, 
+     78,   0,  84,  69,  88,  67, 
+     79,  79,  82,  68,   0, 171, 
+    171, 171
+};
--- a/gfx/angle/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthrough3d11gs.h
+++ b/gfx/angle/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthrough3d11gs.h
@@ -1,191 +1,191 @@
-#if 0
-//
-// Generated by Microsoft (R) HLSL Shader Compiler 6.3.9600.16384
-//
-//
-//
-// Input signature:
-//
-// Name                 Index   Mask Register SysValue  Format   Used
-// -------------------- ----- ------ -------- -------- ------- ------
-// SV_POSITION              0   xyzw        0      POS   float   xyzw
-// LAYER                    0   x           1     NONE    uint   x   
-// TEXCOORD                 0   xyz         2     NONE   float   xyz 
-//
-//
-// Output signature:
-//
-// Name                 Index   Mask Register SysValue  Format   Used
-// -------------------- ----- ------ -------- -------- ------- ------
-// SV_POSITION              0   xyzw        0      POS   float   xyzw
-// SV_RENDERTARGETARRAYINDEX     0   x           1  RTINDEX    uint   x   
-// TEXCOORD                 0   xyz         2     NONE   float   xyz 
-//
-gs_4_0
-dcl_input_siv v[3][0].xyzw, position
-dcl_input v[3][1].x
-dcl_input v[3][2].xyz
-dcl_temps 1
-dcl_inputprimitive triangle 
-dcl_outputtopology trianglestrip 
-dcl_output_siv o0.xyzw, position
-dcl_output_siv o1.x, rendertarget_array_index
-dcl_output o2.xyz
-dcl_maxout 3
-mov r0.x, l(0)
-loop 
-  ige r0.y, r0.x, l(3)
-  breakc_nz r0.y
-  mov o0.xyzw, v[r0.x + 0][0].xyzw
-  mov o1.x, v[r0.x + 0][1].x
-  mov o2.xyz, v[r0.x + 0][2].xyzx
-  emit 
-  iadd r0.x, r0.x, l(1)
-endloop 
-ret 
-// Approximately 11 instruction slots used
-#endif
-
-const BYTE g_GS_Passthrough3D[] =
-{
-     68,  88,  66,  67,  92, 129, 
-     41, 170, 114,  75, 160, 250, 
-     95, 161, 230, 161,  11,  78, 
-    252,  65,   1,   0,   0,   0, 
-     72,   3,   0,   0,   5,   0, 
-      0,   0,  52,   0,   0,   0, 
-    140,   0,   0,   0,   0,   1, 
-      0,   0, 136,   1,   0,   0, 
-    204,   2,   0,   0,  82,  68, 
-     69,  70,  80,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-     28,   0,   0,   0,   0,   4, 
-     83,  71,   0,   1,   0,   0, 
-     28,   0,   0,   0,  77, 105, 
-     99, 114, 111, 115, 111, 102, 
-    116,  32,  40,  82,  41,  32, 
-     72,  76,  83,  76,  32,  83, 
-    104,  97, 100, 101, 114,  32, 
-     67, 111, 109, 112, 105, 108, 
-    101, 114,  32,  54,  46,  51, 
-     46,  57,  54,  48,  48,  46, 
-     49,  54,  51,  56,  52,   0, 
-    171, 171,  73,  83,  71,  78, 
-    108,   0,   0,   0,   3,   0, 
-      0,   0,   8,   0,   0,   0, 
-     80,   0,   0,   0,   0,   0, 
-      0,   0,   1,   0,   0,   0, 
-      3,   0,   0,   0,   0,   0, 
-      0,   0,  15,  15,   0,   0, 
-     92,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      1,   0,   0,   0,   1,   0, 
-      0,   0,   1,   1,   0,   0, 
-     98,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      3,   0,   0,   0,   2,   0, 
-      0,   0,   7,   7,   0,   0, 
-     83,  86,  95,  80,  79,  83, 
-     73,  84,  73,  79,  78,   0, 
-     76,  65,  89,  69,  82,   0, 
-     84,  69,  88,  67,  79,  79, 
-     82,  68,   0, 171,  79,  83, 
-     71,  78, 128,   0,   0,   0, 
-      3,   0,   0,   0,   8,   0, 
-      0,   0,  80,   0,   0,   0, 
-      0,   0,   0,   0,   1,   0, 
-      0,   0,   3,   0,   0,   0, 
-      0,   0,   0,   0,  15,   0, 
-      0,   0,  92,   0,   0,   0, 
-      0,   0,   0,   0,   4,   0, 
-      0,   0,   1,   0,   0,   0, 
-      1,   0,   0,   0,   1,  14, 
-      0,   0, 118,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   3,   0,   0,   0, 
-      2,   0,   0,   0,   7,   8, 
-      0,   0,  83,  86,  95,  80, 
-     79,  83,  73,  84,  73,  79, 
-     78,   0,  83,  86,  95,  82, 
-     69,  78,  68,  69,  82,  84, 
-     65,  82,  71,  69,  84,  65, 
-     82,  82,  65,  89,  73,  78, 
-     68,  69,  88,   0,  84,  69, 
-     88,  67,  79,  79,  82,  68, 
-      0, 171,  83,  72,  68,  82, 
-     60,   1,   0,   0,  64,   0, 
-      2,   0,  79,   0,   0,   0, 
-     97,   0,   0,   5, 242,  16, 
-     32,   0,   3,   0,   0,   0, 
-      0,   0,   0,   0,   1,   0, 
-      0,   0,  95,   0,   0,   4, 
-     18,  16,  32,   0,   3,   0, 
-      0,   0,   1,   0,   0,   0, 
-     95,   0,   0,   4, 114,  16, 
-     32,   0,   3,   0,   0,   0, 
-      2,   0,   0,   0, 104,   0, 
-      0,   2,   1,   0,   0,   0, 
-     93,  24,   0,   1,  92,  40, 
-      0,   1, 103,   0,   0,   4, 
-    242,  32,  16,   0,   0,   0, 
-      0,   0,   1,   0,   0,   0, 
-    103,   0,   0,   4,  18,  32, 
-     16,   0,   1,   0,   0,   0, 
-      4,   0,   0,   0, 101,   0, 
-      0,   3, 114,  32,  16,   0, 
-      2,   0,   0,   0,  94,   0, 
-      0,   2,   3,   0,   0,   0, 
-     54,   0,   0,   5,  18,   0, 
-     16,   0,   0,   0,   0,   0, 
-      1,  64,   0,   0,   0,   0, 
-      0,   0,  48,   0,   0,   1, 
-     33,   0,   0,   7,  34,   0, 
-     16,   0,   0,   0,   0,   0, 
-     10,   0,  16,   0,   0,   0, 
-      0,   0,   1,  64,   0,   0, 
-      3,   0,   0,   0,   3,   0, 
-      4,   3,  26,   0,  16,   0, 
-      0,   0,   0,   0,  54,   0, 
-      0,   7, 242,  32,  16,   0, 
-      0,   0,   0,   0,  70,  30, 
-    160,   0,  10,   0,  16,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,  54,   0,   0,   7, 
-     18,  32,  16,   0,   1,   0, 
-      0,   0,  10,  16, 160,   0, 
-     10,   0,  16,   0,   0,   0, 
-      0,   0,   1,   0,   0,   0, 
-     54,   0,   0,   7, 114,  32, 
-     16,   0,   2,   0,   0,   0, 
-     70,  18, 160,   0,  10,   0, 
-     16,   0,   0,   0,   0,   0, 
-      2,   0,   0,   0,  19,   0, 
-      0,   1,  30,   0,   0,   7, 
-     18,   0,  16,   0,   0,   0, 
-      0,   0,  10,   0,  16,   0, 
-      0,   0,   0,   0,   1,  64, 
-      0,   0,   1,   0,   0,   0, 
-     22,   0,   0,   1,  62,   0, 
-      0,   1,  83,  84,  65,  84, 
-    116,   0,   0,   0,  11,   0, 
-      0,   0,   1,   0,   0,   0, 
-      0,   0,   0,   0,   6,   0, 
-      0,   0,   0,   0,   0,   0, 
-      2,   0,   0,   0,   0,   0, 
-      0,   0,   1,   0,   0,   0, 
-      1,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   1,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   1,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      3,   0,   0,   0,   5,   0, 
-      0,   0,   3,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0
-};
+#if 0
+//
+// Generated by Microsoft (R) HLSL Shader Compiler 6.3.9600.16384
+//
+//
+//
+// Input signature:
+//
+// Name                 Index   Mask Register SysValue  Format   Used
+// -------------------- ----- ------ -------- -------- ------- ------
+// SV_POSITION              0   xyzw        0      POS   float   xyzw
+// LAYER                    0   x           1     NONE    uint   x   
+// TEXCOORD                 0   xyz         2     NONE   float   xyz 
+//
+//
+// Output signature:
+//
+// Name                 Index   Mask Register SysValue  Format   Used
+// -------------------- ----- ------ -------- -------- ------- ------
+// SV_POSITION              0   xyzw        0      POS   float   xyzw
+// SV_RENDERTARGETARRAYINDEX     0   x           1  RTINDEX    uint   x   
+// TEXCOORD                 0   xyz         2     NONE   float   xyz 
+//
+gs_4_0
+dcl_input_siv v[3][0].xyzw, position
+dcl_input v[3][1].x
+dcl_input v[3][2].xyz
+dcl_temps 1
+dcl_inputprimitive triangle 
+dcl_outputtopology trianglestrip 
+dcl_output_siv o0.xyzw, position
+dcl_output_siv o1.x, rendertarget_array_index
+dcl_output o2.xyz
+dcl_maxout 3
+mov r0.x, l(0)
+loop 
+  ige r0.y, r0.x, l(3)
+  breakc_nz r0.y
+  mov o0.xyzw, v[r0.x + 0][0].xyzw
+  mov o1.x, v[r0.x + 0][1].x
+  mov o2.xyz, v[r0.x + 0][2].xyzx
+  emit 
+  iadd r0.x, r0.x, l(1)
+endloop 
+ret 
+// Approximately 11 instruction slots used
+#endif
+
+const BYTE g_GS_Passthrough3D[] =
+{
+     68,  88,  66,  67,  92, 129, 
+     41, 170, 114,  75, 160, 250, 
+     95, 161, 230, 161,  11,  78, 
+    252,  65,   1,   0,   0,   0, 
+     72,   3,   0,   0,   5,   0, 
+      0,   0,  52,   0,   0,   0, 
+    140,   0,   0,   0,   0,   1, 
+      0,   0, 136,   1,   0,   0, 
+    204,   2,   0,   0,  82,  68, 
+     69,  70,  80,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+     28,   0,   0,   0,   0,   4, 
+     83,  71,   0,   1,   0,   0, 
+     28,   0,   0,   0,  77, 105, 
+     99, 114, 111, 115, 111, 102, 
+    116,  32,  40,  82,  41,  32, 
+     72,  76,  83,  76,  32,  83, 
+    104,  97, 100, 101, 114,  32, 
+     67, 111, 109, 112, 105, 108, 
+    101, 114,  32,  54,  46,  51, 
+     46,  57,  54,  48,  48,  46, 
+     49,  54,  51,  56,  52,   0, 
+    171, 171,  73,  83,  71,  78, 
+    108,   0,   0,   0,   3,   0, 
+      0,   0,   8,   0,   0,   0, 
+     80,   0,   0,   0,   0,   0, 
+      0,   0,   1,   0,   0,   0, 
+      3,   0,   0,   0,   0,   0, 
+      0,   0,  15,  15,   0,   0, 
+     92,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      1,   0,   0,   0,   1,   0, 
+      0,   0,   1,   1,   0,   0, 
+     98,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      3,   0,   0,   0,   2,   0, 
+      0,   0,   7,   7,   0,   0, 
+     83,  86,  95,  80,  79,  83, 
+     73,  84,  73,  79,  78,   0, 
+     76,  65,  89,  69,  82,   0, 
+     84,  69,  88,  67,  79,  79, 
+     82,  68,   0, 171,  79,  83, 
+     71,  78, 128,   0,   0,   0, 
+      3,   0,   0,   0,   8,   0, 
+      0,   0,  80,   0,   0,   0, 
+      0,   0,   0,   0,   1,   0, 
+      0,   0,   3,   0,   0,   0, 
+      0,   0,   0,   0,  15,   0, 
+      0,   0,  92,   0,   0,   0, 
+      0,   0,   0,   0,   4,   0, 
+      0,   0,   1,   0,   0,   0, 
+      1,   0,   0,   0,   1,  14, 
+      0,   0, 118,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   3,   0,   0,   0, 
+      2,   0,   0,   0,   7,   8, 
+      0,   0,  83,  86,  95,  80, 
+     79,  83,  73,  84,  73,  79, 
+     78,   0,  83,  86,  95,  82, 
+     69,  78,  68,  69,  82,  84, 
+     65,  82,  71,  69,  84,  65, 
+     82,  82,  65,  89,  73,  78, 
+     68,  69,  88,   0,  84,  69, 
+     88,  67,  79,  79,  82,  68, 
+      0, 171,  83,  72,  68,  82, 
+     60,   1,   0,   0,  64,   0, 
+      2,   0,  79,   0,   0,   0, 
+     97,   0,   0,   5, 242,  16, 
+     32,   0,   3,   0,   0,   0, 
+      0,   0,   0,   0,   1,   0, 
+      0,   0,  95,   0,   0,   4, 
+     18,  16,  32,   0,   3,   0, 
+      0,   0,   1,   0,   0,   0, 
+     95,   0,   0,   4, 114,  16, 
+     32,   0,   3,   0,   0,   0, 
+      2,   0,   0,   0, 104,   0, 
+      0,   2,   1,   0,   0,   0, 
+     93,  24,   0,   1,  92,  40, 
+      0,   1, 103,   0,   0,   4, 
+    242,  32,  16,   0,   0,   0, 
+      0,   0,   1,   0,   0,   0, 
+    103,   0,   0,   4,  18,  32, 
+     16,   0,   1,   0,   0,   0, 
+      4,   0,   0,   0, 101,   0, 
+      0,   3, 114,  32,  16,   0, 
+      2,   0,   0,   0,  94,   0, 
+      0,   2,   3,   0,   0,   0, 
+     54,   0,   0,   5,  18,   0, 
+     16,   0,   0,   0,   0,   0, 
+      1,  64,   0,   0,   0,   0, 
+      0,   0,  48,   0,   0,   1, 
+     33,   0,   0,   7,  34,   0, 
+     16,   0,   0,   0,   0,   0, 
+     10,   0,  16,   0,   0,   0, 
+      0,   0,   1,  64,   0,   0, 
+      3,   0,   0,   0,   3,   0, 
+      4,   3,  26,   0,  16,   0, 
+      0,   0,   0,   0,  54,   0, 
+      0,   7, 242,  32,  16,   0, 
+      0,   0,   0,   0,  70,  30, 
+    160,   0,  10,   0,  16,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,  54,   0,   0,   7, 
+     18,  32,  16,   0,   1,   0, 
+      0,   0,  10,  16, 160,   0, 
+     10,   0,  16,   0,   0,   0, 
+      0,   0,   1,   0,   0,   0, 
+     54,   0,   0,   7, 114,  32, 
+     16,   0,   2,   0,   0,   0, 
+     70,  18, 160,   0,  10,   0, 
+     16,   0,   0,   0,   0,   0, 
+      2,   0,   0,   0,  19,   0, 
+      0,   1,  30,   0,   0,   7, 
+     18,   0,  16,   0,   0,   0, 
+      0,   0,  10,   0,  16,   0, 
+      0,   0,   0,   0,   1,  64, 
+      0,   0,   1,   0,   0,   0, 
+     22,   0,   0,   1,  62,   0, 
+      0,   1,  83,  84,  65,  84, 
+    116,   0,   0,   0,  11,   0, 
+      0,   0,   1,   0,   0,   0, 
+      0,   0,   0,   0,   6,   0, 
+      0,   0,   0,   0,   0,   0, 
+      2,   0,   0,   0,   0,   0, 
+      0,   0,   1,   0,   0,   0, 
+      1,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   1,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   1,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      3,   0,   0,   0,   5,   0, 
+      0,   0,   3,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0
+};
--- a/gfx/angle/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthrough3d11vs.h
+++ b/gfx/angle/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthrough3d11vs.h
@@ -1,155 +1,155 @@
-#if 0
-//
-// Generated by Microsoft (R) HLSL Shader Compiler 6.3.9600.16384
-//
-//
-//
-// Input signature:
-//
-// Name                 Index   Mask Register SysValue  Format   Used
-// -------------------- ----- ------ -------- -------- ------- ------
-// POSITION                 0   xy          0     NONE   float   xy  
-// LAYER                    0   x           1     NONE    uint   x   
-// TEXCOORD                 0   xyz         2     NONE   float   xyz 
-//
-//
-// Output signature:
-//
-// Name                 Index   Mask Register SysValue  Format   Used
-// -------------------- ----- ------ -------- -------- ------- ------
-// SV_POSITION              0   xyzw        0      POS   float   xyzw
-// LAYER                    0   x           1     NONE    uint   x   
-// TEXCOORD                 0   xyz         2     NONE   float   xyz 
-//
-vs_4_0
-dcl_input v0.xy
-dcl_input v1.x
-dcl_input v2.xyz
-dcl_output_siv o0.xyzw, position
-dcl_output o1.x
-dcl_output o2.xyz
-mov o0.xy, v0.xyxx
-mov o0.zw, l(0,0,0,1.000000)
-mov o1.x, v1.x
-mov o2.xyz, v2.xyzx
-ret 
-// Approximately 5 instruction slots used
-#endif
-
-const BYTE g_VS_Passthrough3D[] =
-{
-     68,  88,  66,  67, 229,  65, 
-    217, 172, 143, 180, 152,  72, 
-     16,  12, 254,  66,   0, 215, 
-     50, 173,   1,   0,   0,   0, 
-    168,   2,   0,   0,   5,   0, 
-      0,   0,  52,   0,   0,   0, 
-    140,   0,   0,   0, 252,   0, 
-      0,   0, 112,   1,   0,   0, 
-     44,   2,   0,   0,  82,  68, 
-     69,  70,  80,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-     28,   0,   0,   0,   0,   4, 
-    254, 255,   0,   1,   0,   0, 
-     28,   0,   0,   0,  77, 105, 
-     99, 114, 111, 115, 111, 102, 
-    116,  32,  40,  82,  41,  32, 
-     72,  76,  83,  76,  32,  83, 
-    104,  97, 100, 101, 114,  32, 
-     67, 111, 109, 112, 105, 108, 
-    101, 114,  32,  54,  46,  51, 
-     46,  57,  54,  48,  48,  46, 
-     49,  54,  51,  56,  52,   0, 
-    171, 171,  73,  83,  71,  78, 
-    104,   0,   0,   0,   3,   0, 
-      0,   0,   8,   0,   0,   0, 
-     80,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      3,   0,   0,   0,   0,   0, 
-      0,   0,   3,   3,   0,   0, 
-     89,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      1,   0,   0,   0,   1,   0, 
-      0,   0,   1,   1,   0,   0, 
-     95,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      3,   0,   0,   0,   2,   0, 
-      0,   0,   7,   7,   0,   0, 
-     80,  79,  83,  73,  84,  73, 
-     79,  78,   0,  76,  65,  89, 
-     69,  82,   0,  84,  69,  88, 
-     67,  79,  79,  82,  68,   0, 
-     79,  83,  71,  78, 108,   0, 
-      0,   0,   3,   0,   0,   0, 
-      8,   0,   0,   0,  80,   0, 
-      0,   0,   0,   0,   0,   0, 
-      1,   0,   0,   0,   3,   0, 
-      0,   0,   0,   0,   0,   0, 
-     15,   0,   0,   0,  92,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   1,   0, 
-      0,   0,   1,   0,   0,   0, 
-      1,  14,   0,   0,  98,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   3,   0, 
-      0,   0,   2,   0,   0,   0, 
-      7,   8,   0,   0,  83,  86, 
-     95,  80,  79,  83,  73,  84, 
-     73,  79,  78,   0,  76,  65, 
-     89,  69,  82,   0,  84,  69, 
-     88,  67,  79,  79,  82,  68, 
-      0, 171,  83,  72,  68,  82, 
-    180,   0,   0,   0,  64,   0, 
-      1,   0,  45,   0,   0,   0, 
-     95,   0,   0,   3,  50,  16, 
-     16,   0,   0,   0,   0,   0, 
-     95,   0,   0,   3,  18,  16, 
-     16,   0,   1,   0,   0,   0, 
-     95,   0,   0,   3, 114,  16, 
-     16,   0,   2,   0,   0,   0, 
-    103,   0,   0,   4, 242,  32, 
-     16,   0,   0,   0,   0,   0, 
-      1,   0,   0,   0, 101,   0, 
-      0,   3,  18,  32,  16,   0, 
-      1,   0,   0,   0, 101,   0, 
-      0,   3, 114,  32,  16,   0, 
-      2,   0,   0,   0,  54,   0, 
-      0,   5,  50,  32,  16,   0, 
-      0,   0,   0,   0,  70,  16, 
-     16,   0,   0,   0,   0,   0, 
-     54,   0,   0,   8, 194,  32, 
-     16,   0,   0,   0,   0,   0, 
-      2,  64,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-    128,  63,  54,   0,   0,   5, 
-     18,  32,  16,   0,   1,   0, 
-      0,   0,  10,  16,  16,   0, 
-      1,   0,   0,   0,  54,   0, 
-      0,   5, 114,  32,  16,   0, 
-      2,   0,   0,   0,  70,  18, 
-     16,   0,   2,   0,   0,   0, 
-     62,   0,   0,   1,  83,  84, 
-     65,  84, 116,   0,   0,   0, 
-      5,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      6,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   1,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   4,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0
-};
+#if 0
+//
+// Generated by Microsoft (R) HLSL Shader Compiler 6.3.9600.16384
+//
+//
+//
+// Input signature:
+//
+// Name                 Index   Mask Register SysValue  Format   Used
+// -------------------- ----- ------ -------- -------- ------- ------
+// POSITION                 0   xy          0     NONE   float   xy  
+// LAYER                    0   x           1     NONE    uint   x   
+// TEXCOORD                 0   xyz         2     NONE   float   xyz 
+//
+//
+// Output signature:
+//
+// Name                 Index   Mask Register SysValue  Format   Used
+// -------------------- ----- ------ -------- -------- ------- ------
+// SV_POSITION              0   xyzw        0      POS   float   xyzw
+// LAYER                    0   x           1     NONE    uint   x   
+// TEXCOORD                 0   xyz         2     NONE   float   xyz 
+//
+vs_4_0
+dcl_input v0.xy
+dcl_input v1.x
+dcl_input v2.xyz
+dcl_output_siv o0.xyzw, position
+dcl_output o1.x
+dcl_output o2.xyz
+mov o0.xy, v0.xyxx
+mov o0.zw, l(0,0,0,1.000000)
+mov o1.x, v1.x
+mov o2.xyz, v2.xyzx
+ret 
+// Approximately 5 instruction slots used
+#endif
+
+const BYTE g_VS_Passthrough3D[] =
+{
+     68,  88,  66,  67, 229,  65, 
+    217, 172, 143, 180, 152,  72, 
+     16,  12, 254,  66,   0, 215, 
+     50, 173,   1,   0,   0,   0, 
+    168,   2,   0,   0,   5,   0, 
+      0,   0,  52,   0,   0,   0, 
+    140,   0,   0,   0, 252,   0, 
+      0,   0, 112,   1,   0,   0, 
+     44,   2,   0,   0,  82,  68, 
+     69,  70,  80,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+     28,   0,   0,   0,   0,   4, 
+    254, 255,   0,   1,   0,   0, 
+     28,   0,   0,   0,  77, 105, 
+     99, 114, 111, 115, 111, 102, 
+    116,  32,  40,  82,  41,  32, 
+     72,  76,  83,  76,  32,  83, 
+    104,  97, 100, 101, 114,  32, 
+     67, 111, 109, 112, 105, 108, 
+    101, 114,  32,  54,  46,  51, 
+     46,  57,  54,  48,  48,  46, 
+     49,  54,  51,  56,  52,   0, 
+    171, 171,  73,  83,  71,  78, 
+    104,   0,   0,   0,   3,   0, 
+      0,   0,   8,   0,   0,   0, 
+     80,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      3,   0,   0,   0,   0,   0, 
+      0,   0,   3,   3,   0,   0, 
+     89,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      1,   0,   0,   0,   1,   0, 
+      0,   0,   1,   1,   0,   0, 
+     95,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      3,   0,   0,   0,   2,   0, 
+      0,   0,   7,   7,   0,   0, 
+     80,  79,  83,  73,  84,  73, 
+     79,  78,   0,  76,  65,  89, 
+     69,  82,   0,  84,  69,  88, 
+     67,  79,  79,  82,  68,   0, 
+     79,  83,  71,  78, 108,   0, 
+      0,   0,   3,   0,   0,   0, 
+      8,   0,   0,   0,  80,   0, 
+      0,   0,   0,   0,   0,   0, 
+      1,   0,   0,   0,   3,   0, 
+      0,   0,   0,   0,   0,   0, 
+     15,   0,   0,   0,  92,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   1,   0, 
+      0,   0,   1,   0,   0,   0, 
+      1,  14,   0,   0,  98,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   3,   0, 
+      0,   0,   2,   0,   0,   0, 
+      7,   8,   0,   0,  83,  86, 
+     95,  80,  79,  83,  73,  84, 
+     73,  79,  78,   0,  76,  65, 
+     89,  69,  82,   0,  84,  69, 
+     88,  67,  79,  79,  82,  68, 
+      0, 171,  83,  72,  68,  82, 
+    180,   0,   0,   0,  64,   0, 
+      1,   0,  45,   0,   0,   0, 
+     95,   0,   0,   3,  50,  16, 
+     16,   0,   0,   0,   0,   0, 
+     95,   0,   0,   3,  18,  16, 
+     16,   0,   1,   0,   0,   0, 
+     95,   0,   0,   3, 114,  16, 
+     16,   0,   2,   0,   0,   0, 
+    103,   0,   0,   4, 242,  32, 
+     16,   0,   0,   0,   0,   0, 
+      1,   0,   0,   0, 101,   0, 
+      0,   3,  18,  32,  16,   0, 
+      1,   0,   0,   0, 101,   0, 
+      0,   3, 114,  32,  16,   0, 
+      2,   0,   0,   0,  54,   0, 
+      0,   5,  50,  32,  16,   0, 
+      0,   0,   0,   0,  70,  16, 
+     16,   0,   0,   0,   0,   0, 
+     54,   0,   0,   8, 194,  32, 
+     16,   0,   0,   0,   0,   0, 
+      2,  64,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+    128,  63,  54,   0,   0,   5, 
+     18,  32,  16,   0,   1,   0, 
+      0,   0,  10,  16,  16,   0, 
+      1,   0,   0,   0,  54,   0, 
+      0,   5, 114,  32,  16,   0, 
+      2,   0,   0,   0,  70,  18, 
+     16,   0,   2,   0,   0,   0, 
+     62,   0,   0,   1,  83,  84, 
+     65,  84, 116,   0,   0,   0, 
+      5,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      6,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   1,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   4,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0
+};
new file mode 100644
--- /dev/null
+++ b/gfx/angle/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthrougha2d11ps.h
@@ -0,0 +1,104 @@
+#if 0
+//
+// Generated by Microsoft (R) HLSL Shader Compiler 6.3.9600.16384
+//
+//
+// Resource Bindings:
+//
+// Name                                 Type  Format         Dim Slot Elements
+// ------------------------------ ---------- ------- ----------- ---- --------
+// Sampler                           sampler      NA          NA    0        1
+// TextureF                          texture  float4          2d    0        1
+//
+//
+//
+// Input signature:
+//
+// Name                 Index   Mask Register SysValue  Format   Used
+// -------------------- ----- ------ -------- -------- ------- ------
+// SV_POSITION              0   xyzw        0      POS   float
+// TEXCOORD                 0   xy          1     NONE   float   xy
+//
+//
+// Output signature:
+//
+// Name                 Index   Mask Register SysValue  Format   Used
+// -------------------- ----- ------ -------- -------- ------- ------
+// SV_TARGET                0   xyzw        0   TARGET   float   xyzw
+//
+//
+// Sampler/Resource to DX9 shader sampler mappings:
+//
+// Target Sampler Source Sampler  Source Resource
+// -------------- --------------- ----------------
+// s0             s0              t0
+//
+//
+// Level9 shader bytecode:
+//
+    ps_2_x
+    def c0, 0, 1, 0, 0
+    dcl t0.xy
+    dcl_2d s0
+    texld r0, t0, s0
+    mul r0, r0.w, c0.xxxy
+    mov oC0, r0
+
+// approximately 3 instruction slots used (1 texture, 2 arithmetic)
+ps_4_0
+dcl_sampler s0, mode_default
+dcl_resource_texture2d (float,float,float,float) t0
+dcl_input_ps linear v1.xy
+dcl_output o0.xyzw
+dcl_temps 1
+sample r0.xyzw, v1.xyxx, t0.xyzw, s0
+mov o0.w, r0.w
+mov o0.xyz, l(0,0,0,0)
+ret
+// Approximately 4 instruction slots used
+#endif
+
+const BYTE g_PS_PassthroughA2D[] = {
+    68,  88,  66,  67,  187, 163, 203, 246, 197, 116, 209, 102, 237, 185, 161, 94,  217, 199, 47,
+    200, 1,   0,   0,   0,   36,  3,   0,   0,   6,   0,   0,   0,   56,  0,   0,   0,   204, 0,
+    0,   0,   116, 1,   0,   0,   240, 1,   0,   0,   152, 2,   0,   0,   240, 2,   0,   0,   65,
+    111, 110, 57,  140, 0,   0,   0,   140, 0,   0,   0,   0,   2,   255, 255, 100, 0,   0,   0,
+    40,  0,   0,   0,   0,   0,   40,  0,   0,   0,   40,  0,   0,   0,   40,  0,   1,   0,   36,
+    0,   0,   0,   40,  0,   0,   0,   0,   0,   1,   2,   255, 255, 81,  0,   0,   5,   0,   0,
+    15,  160, 0,   0,   0,   0,   0,   0,   128, 63,  0,   0,   0,   0,   0,   0,   0,   0,   31,
+    0,   0,   2,   0,   0,   0,   128, 0,   0,   3,   176, 31,  0,   0,   2,   0,   0,   0,   144,
+    0,   8,   15,  160, 66,  0,   0,   3,   0,   0,   15,  128, 0,   0,   228, 176, 0,   8,   228,
+    160, 5,   0,   0,   3,   0,   0,   15,  128, 0,   0,   255, 128, 0,   0,   64,  160, 1,   0,
+    0,   2,   0,   8,   15,  128, 0,   0,   228, 128, 255, 255, 0,   0,   83,  72,  68,  82,  160,
+    0,   0,   0,   64,  0,   0,   0,   40,  0,   0,   0,   90,  0,   0,   3,   0,   96,  16,  0,
+    0,   0,   0,   0,   88,  24,  0,   4,   0,   112, 16,  0,   0,   0,   0,   0,   85,  85,  0,
+    0,   98,  16,  0,   3,   50,  16,  16,  0,   1,   0,   0,   0,   101, 0,   0,   3,   242, 32,
+    16,  0,   0,   0,   0,   0,   104, 0,   0,   2,   1,   0,   0,   0,   69,  0,   0,   9,   242,
+    0,   16,  0,   0,   0,   0,   0,   70,  16,  16,  0,   1,   0,   0,   0,   70,  126, 16,  0,
+    0,   0,   0,   0,   0,   96,  16,  0,   0,   0,   0,   0,   54,  0,   0,   5,   130, 32,  16,
+    0,   0,   0,   0,   0,   58,  0,   16,  0,   0,   0,   0,   0,   54,  0,   0,   8,   114, 32,
+    16,  0,   0,   0,   0,   0,   2,   64,  0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+    0,   0,   0,   0,   0,   0,   0,   62,  0,   0,   1,   83,  84,  65,  84,  116, 0,   0,   0,
+    4,   0,   0,   0,   1,   0,   0,   0,   0,   0,   0,   0,   2,   0,   0,   0,   0,   0,   0,
+    0,   0,   0,   0,   0,   0,   0,   0,   0,   1,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+    0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   1,
+    0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+    2,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+    0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+    0,   0,   82,  68,  69,  70,  160, 0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   2,
+    0,   0,   0,   28,  0,   0,   0,   0,   4,   255, 255, 0,   1,   0,   0,   109, 0,   0,   0,
+    92,  0,   0,   0,   3,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+    0,   0,   0,   0,   0,   1,   0,   0,   0,   1,   0,   0,   0,   100, 0,   0,   0,   2,   0,
+    0,   0,   5,   0,   0,   0,   4,   0,   0,   0,   255, 255, 255, 255, 0,   0,   0,   0,   1,
+    0,   0,   0,   13,  0,   0,   0,   83,  97,  109, 112, 108, 101, 114, 0,   84,  101, 120, 116,
+    117, 114, 101, 70,  0,   77,  105, 99,  114, 111, 115, 111, 102, 116, 32,  40,  82,  41,  32,
+    72,  76,  83,  76,  32,  83,  104, 97,  100, 101, 114, 32,  67,  111, 109, 112, 105, 108, 101,
+    114, 32,  54,  46,  51,  46,  57,  54,  48,  48,  46,  49,  54,  51,  56,  52,  0,   171, 73,
+    83,  71,  78,  80,  0,   0,   0,   2,   0,   0,   0,   8,   0,   0,   0,   56,  0,   0,   0,
+    0,   0,   0,   0,   1,   0,   0,   0,   3,   0,   0,   0,   0,   0,   0,   0,   15,  0,   0,
+    0,   68,  0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   3,   0,   0,   0,   1,   0,
+    0,   0,   3,   3,   0,   0,   83,  86,  95,  80,  79,  83,  73,  84,  73,  79,  78,  0,   84,
+    69,  88,  67,  79,  79,  82,  68,  0,   171, 171, 171, 79,  83,  71,  78,  44,  0,   0,   0,
+    1,   0,   0,   0,   8,   0,   0,   0,   32,  0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+    0,   3,   0,   0,   0,   0,   0,   0,   0,   15,  0,   0,   0,   83,  86,  95,  84,  65,  82,
+    71,  69,  84,  0,   171, 171};
--- a/gfx/angle/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughdepth2d11ps.h
+++ b/gfx/angle/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughdepth2d11ps.h
@@ -1,145 +1,145 @@
-#if 0
-//
-// Generated by Microsoft (R) HLSL Shader Compiler 6.3.9600.16384
-//
-//
-// Resource Bindings:
-//
-// Name                                 Type  Format         Dim Slot Elements
-// ------------------------------ ---------- ------- ----------- ---- --------
-// Sampler                           sampler      NA          NA    0        1
-// TextureF                          texture  float4          2d    0        1
-//
-//
-//
-// Input signature:
-//
-// Name                 Index   Mask Register SysValue  Format   Used
-// -------------------- ----- ------ -------- -------- ------- ------
-// SV_POSITION              0   xyzw        0      POS   float       
-// TEXCOORD                 0   xy          1     NONE   float   xy  
-//
-//
-// Output signature:
-//
-// Name                 Index   Mask Register SysValue  Format   Used
-// -------------------- ----- ------ -------- -------- ------- ------
-// SV_DEPTH                 0    N/A   oDepth    DEPTH   float    YES
-//
-ps_4_0
-dcl_sampler s0, mode_default
-dcl_resource_texture2d (float,float,float,float) t0
-dcl_input_ps linear v1.xy
-dcl_output oDepth
-dcl_temps 1
-sample r0.xyzw, v1.xyxx, t0.xyzw, s0
-mov oDepth, r0.x
-ret 
-// Approximately 3 instruction slots used
-#endif
-
-const BYTE g_PS_PassthroughDepth2D[] =
-{
-     68,  88,  66,  67,   8,  33, 
-    154,  92, 164,  28, 139, 205, 
-      1, 168,  30, 229,  51, 127, 
-    173, 221,   1,   0,   0,   0, 
-    100,   2,   0,   0,   5,   0, 
-      0,   0,  52,   0,   0,   0, 
-    220,   0,   0,   0,  52,   1, 
-      0,   0, 104,   1,   0,   0, 
-    232,   1,   0,   0,  82,  68, 
-     69,  70, 160,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   2,   0,   0,   0, 
-     28,   0,   0,   0,   0,   4, 
-    255, 255,   0,   1,   0,   0, 
-    109,   0,   0,   0,  92,   0, 
-      0,   0,   3,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   1,   0, 
-      0,   0,   1,   0,   0,   0, 
-    100,   0,   0,   0,   2,   0, 
-      0,   0,   5,   0,   0,   0, 
-      4,   0,   0,   0, 255, 255, 
-    255, 255,   0,   0,   0,   0, 
-      1,   0,   0,   0,  13,   0, 
-      0,   0,  83,  97, 109, 112, 
-    108, 101, 114,   0,  84, 101, 
-    120, 116, 117, 114, 101,  70, 
-      0,  77, 105,  99, 114, 111, 
-    115, 111, 102, 116,  32,  40, 
-     82,  41,  32,  72,  76,  83, 
-     76,  32,  83, 104,  97, 100, 
-    101, 114,  32,  67, 111, 109, 
-    112, 105, 108, 101, 114,  32, 
-     54,  46,  51,  46,  57,  54, 
-     48,  48,  46,  49,  54,  51, 
-     56,  52,   0, 171,  73,  83, 
-     71,  78,  80,   0,   0,   0, 
-      2,   0,   0,   0,   8,   0, 
-      0,   0,  56,   0,   0,   0, 
-      0,   0,   0,   0,   1,   0, 
-      0,   0,   3,   0,   0,   0, 
-      0,   0,   0,   0,  15,   0, 
-      0,   0,  68,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   3,   0,   0,   0, 
-      1,   0,   0,   0,   3,   3, 
-      0,   0,  83,  86,  95,  80, 
-     79,  83,  73,  84,  73,  79, 
-     78,   0,  84,  69,  88,  67, 
-     79,  79,  82,  68,   0, 171, 
-    171, 171,  79,  83,  71,  78, 
-     44,   0,   0,   0,   1,   0, 
-      0,   0,   8,   0,   0,   0, 
-     32,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      3,   0,   0,   0, 255, 255, 
-    255, 255,   1,  14,   0,   0, 
-     83,  86,  95,  68,  69,  80, 
-     84,  72,   0, 171, 171, 171, 
-     83,  72,  68,  82, 120,   0, 
-      0,   0,  64,   0,   0,   0, 
-     30,   0,   0,   0,  90,   0, 
-      0,   3,   0,  96,  16,   0, 
-      0,   0,   0,   0,  88,  24, 
-      0,   4,   0, 112,  16,   0, 
-      0,   0,   0,   0,  85,  85, 
-      0,   0,  98,  16,   0,   3, 
-     50,  16,  16,   0,   1,   0, 
-      0,   0, 101,   0,   0,   2, 
-      1, 192,   0,   0, 104,   0, 
-      0,   2,   1,   0,   0,   0, 
-     69,   0,   0,   9, 242,   0, 
-     16,   0,   0,   0,   0,   0, 
-     70,  16,  16,   0,   1,   0, 
-      0,   0,  70, 126,  16,   0, 
-      0,   0,   0,   0,   0,  96, 
-     16,   0,   0,   0,   0,   0, 
-     54,   0,   0,   4,   1, 192, 
-      0,   0,  10,   0,  16,   0, 
-      0,   0,   0,   0,  62,   0, 
-      0,   1,  83,  84,  65,  84, 
-    116,   0,   0,   0,   3,   0, 
-      0,   0,   1,   0,   0,   0, 
-      0,   0,   0,   0,   2,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   1,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      1,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   1,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0
-};
+#if 0
+//
+// Generated by Microsoft (R) HLSL Shader Compiler 6.3.9600.16384
+//
+//
+// Resource Bindings:
+//
+// Name                                 Type  Format         Dim Slot Elements
+// ------------------------------ ---------- ------- ----------- ---- --------
+// Sampler                           sampler      NA          NA    0        1
+// TextureF                          texture  float4          2d    0        1
+//
+//
+//
+// Input signature:
+//
+// Name                 Index   Mask Register SysValue  Format   Used
+// -------------------- ----- ------ -------- -------- ------- ------
+// SV_POSITION              0   xyzw        0      POS   float       
+// TEXCOORD                 0   xy          1     NONE   float   xy  
+//
+//
+// Output signature:
+//
+// Name                 Index   Mask Register SysValue  Format   Used
+// -------------------- ----- ------ -------- -------- ------- ------
+// SV_DEPTH                 0    N/A   oDepth    DEPTH   float    YES
+//
+ps_4_0
+dcl_sampler s0, mode_default
+dcl_resource_texture2d (float,float,float,float) t0
+dcl_input_ps linear v1.xy
+dcl_output oDepth
+dcl_temps 1
+sample r0.xyzw, v1.xyxx, t0.xyzw, s0
+mov oDepth, r0.x
+ret 
+// Approximately 3 instruction slots used
+#endif
+
+const BYTE g_PS_PassthroughDepth2D[] =
+{
+     68,  88,  66,  67,   8,  33, 
+    154,  92, 164,  28, 139, 205, 
+      1, 168,  30, 229,  51, 127, 
+    173, 221,   1,   0,   0,   0, 
+    100,   2,   0,   0,   5,   0, 
+      0,   0,  52,   0,   0,   0, 
+    220,   0,   0,   0,  52,   1, 
+      0,   0, 104,   1,   0,   0, 
+    232,   1,   0,   0,  82,  68, 
+     69,  70, 160,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   2,   0,   0,   0, 
+     28,   0,   0,   0,   0,   4, 
+    255, 255,   0,   1,   0,   0, 
+    109,   0,   0,   0,  92,   0, 
+      0,   0,   3,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   1,   0, 
+      0,   0,   1,   0,   0,   0, 
+    100,   0,   0,   0,   2,   0, 
+      0,   0,   5,   0,   0,   0, 
+      4,   0,   0,   0, 255, 255, 
+    255, 255,   0,   0,   0,   0, 
+      1,   0,   0,   0,  13,   0, 
+      0,   0,  83,  97, 109, 112, 
+    108, 101, 114,   0,  84, 101, 
+    120, 116, 117, 114, 101,  70, 
+      0,  77, 105,  99, 114, 111, 
+    115, 111, 102, 116,  32,  40, 
+     82,  41,  32,  72,  76,  83, 
+     76,  32,  83, 104,  97, 100, 
+    101, 114,  32,  67, 111, 109, 
+    112, 105, 108, 101, 114,  32, 
+     54,  46,  51,  46,  57,  54, 
+     48,  48,  46,  49,  54,  51, 
+     56,  52,   0, 171,  73,  83, 
+     71,  78,  80,   0,   0,   0, 
+      2,   0,   0,   0,   8,   0, 
+      0,   0,  56,   0,   0,   0, 
+      0,   0,   0,   0,   1,   0, 
+      0,   0,   3,   0,   0,   0, 
+      0,   0,   0,   0,  15,   0, 
+      0,   0,  68,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   3,   0,   0,   0, 
+      1,   0,   0,   0,   3,   3, 
+      0,   0,  83,  86,  95,  80, 
+     79,  83,  73,  84,  73,  79, 
+     78,   0,  84,  69,  88,  67, 
+     79,  79,  82,  68,   0, 171, 
+    171, 171,  79,  83,  71,  78, 
+     44,   0,   0,   0,   1,   0, 
+      0,   0,   8,   0,   0,   0, 
+     32,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      3,   0,   0,   0, 255, 255, 
+    255, 255,   1,  14,   0,   0, 
+     83,  86,  95,  68,  69,  80, 
+     84,  72,   0, 171, 171, 171, 
+     83,  72,  68,  82, 120,   0, 
+      0,   0,  64,   0,   0,   0, 
+     30,   0,   0,   0,  90,   0, 
+      0,   3,   0,  96,  16,   0, 
+      0,   0,   0,   0,  88,  24, 
+      0,   4,   0, 112,  16,   0, 
+      0,   0,   0,   0,  85,  85, 
+      0,   0,  98,  16,   0,   3, 
+     50,  16,  16,   0,   1,   0, 
+      0,   0, 101,   0,   0,   2, 
+      1, 192,   0,   0, 104,   0, 
+      0,   2,   1,   0,   0,   0, 
+     69,   0,   0,   9, 242,   0, 
+     16,   0,   0,   0,   0,   0, 
+     70,  16,  16,   0,   1,   0, 
+      0,   0,  70, 126,  16,   0, 
+      0,   0,   0,   0,   0,  96, 
+     16,   0,   0,   0,   0,   0, 
+     54,   0,   0,   4,   1, 192, 
+      0,   0,  10,   0,  16,   0, 
+      0,   0,   0,   0,  62,   0, 
+      0,   1,  83,  84,  65,  84, 
+    116,   0,   0,   0,   3,   0, 
+      0,   0,   1,   0,   0,   0, 
+      0,   0,   0,   0,   2,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   1,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      1,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   1,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0
+};
--- a/gfx/angle/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughlum2d11ps.h
+++ b/gfx/angle/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughlum2d11ps.h
@@ -1,196 +1,196 @@
-#if 0
-//
-// Generated by Microsoft (R) HLSL Shader Compiler 6.3.9600.16384
-//
-//
-// Resource Bindings:
-//
-// Name                                 Type  Format         Dim Slot Elements
-// ------------------------------ ---------- ------- ----------- ---- --------
-// Sampler                           sampler      NA          NA    0        1
-// TextureF                          texture  float4          2d    0        1
-//
-//
-//
-// Input signature:
-//
-// Name                 Index   Mask Register SysValue  Format   Used
-// -------------------- ----- ------ -------- -------- ------- ------
-// SV_POSITION              0   xyzw        0      POS   float       
-// TEXCOORD                 0   xy          1     NONE   float   xy  
-//
-//
-// Output signature:
-//
-// Name                 Index   Mask Register SysValue  Format   Used
-// -------------------- ----- ------ -------- -------- ------- ------
-// SV_TARGET                0   xyzw        0   TARGET   float   xyzw
-//
-//
-// Sampler/Resource to DX9 shader sampler mappings:
-//
-// Target Sampler Source Sampler  Source Resource
-// -------------- --------------- ----------------
-// s0             s0              t0               
-//
-//
-// Level9 shader bytecode:
-//
-    ps_2_x
-    def c0, 1, 0, 0, 0
-    dcl t0.xy
-    dcl_2d s0
-    texld r0, t0, s0
-    mad r0, r0.x, c0.xxxy, c0.yyyx
-    mov oC0, r0
-
-// approximately 3 instruction slots used (1 texture, 2 arithmetic)
-ps_4_0
-dcl_sampler s0, mode_default
-dcl_resource_texture2d (float,float,float,float) t0
-dcl_input_ps linear v1.xy
-dcl_output o0.xyzw
-dcl_temps 1
-sample r0.xyzw, v1.xyxx, t0.xyzw, s0
-mov o0.xyz, r0.xxxx
-mov o0.w, l(1.000000)
-ret 
-// Approximately 4 instruction slots used
-#endif
-
-const BYTE g_PS_PassthroughLum2D[] =
-{
-     68,  88,  66,  67, 144,  18, 
-    242,  89, 150, 125,  18, 219, 
-    193, 196, 127, 207,  14, 165, 
-    198, 119,   1,   0,   0,   0, 
-     28,   3,   0,   0,   6,   0, 
-      0,   0,  56,   0,   0,   0, 
-    208,   0,   0,   0, 108,   1, 
-      0,   0, 232,   1,   0,   0, 
-    144,   2,   0,   0, 232,   2, 
-      0,   0,  65, 111, 110,  57, 
-    144,   0,   0,   0, 144,   0, 
-      0,   0,   0,   2, 255, 255, 
-    104,   0,   0,   0,  40,   0, 
-      0,   0,   0,   0,  40,   0, 
-      0,   0,  40,   0,   0,   0, 
-     40,   0,   1,   0,  36,   0, 
-      0,   0,  40,   0,   0,   0, 
-      0,   0,   1,   2, 255, 255, 
-     81,   0,   0,   5,   0,   0, 
-     15, 160,   0,   0, 128,  63, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-     31,   0,   0,   2,   0,   0, 
-      0, 128,   0,   0,   3, 176, 
-     31,   0,   0,   2,   0,   0, 
-      0, 144,   0,   8,  15, 160, 
-     66,   0,   0,   3,   0,   0, 
-     15, 128,   0,   0, 228, 176, 
-      0,   8, 228, 160,   4,   0, 
-      0,   4,   0,   0,  15, 128, 
-      0,   0,   0, 128,   0,   0, 
-     64, 160,   0,   0,  21, 160, 
-      1,   0,   0,   2,   0,   8, 
-     15, 128,   0,   0, 228, 128, 
-    255, 255,   0,   0,  83,  72, 
-     68,  82, 148,   0,   0,   0, 
-     64,   0,   0,   0,  37,   0, 
-      0,   0,  90,   0,   0,   3, 
-      0,  96,  16,   0,   0,   0, 
-      0,   0,  88,  24,   0,   4, 
-      0, 112,  16,   0,   0,   0, 
-      0,   0,  85,  85,   0,   0, 
-     98,  16,   0,   3,  50,  16, 
-     16,   0,   1,   0,   0,   0, 
-    101,   0,   0,   3, 242,  32, 
-     16,   0,   0,   0,   0,   0, 
-    104,   0,   0,   2,   1,   0, 
-      0,   0,  69,   0,   0,   9, 
-    242,   0,  16,   0,   0,   0, 
-      0,   0,  70,  16,  16,   0, 
-      1,   0,   0,   0,  70, 126, 
-     16,   0,   0,   0,   0,   0, 
-      0,  96,  16,   0,   0,   0, 
-      0,   0,  54,   0,   0,   5, 
-    114,  32,  16,   0,   0,   0, 
-      0,   0,   6,   0,  16,   0, 
-      0,   0,   0,   0,  54,   0, 
-      0,   5, 130,  32,  16,   0, 
-      0,   0,   0,   0,   1,  64, 
-      0,   0,   0,   0, 128,  63, 
-     62,   0,   0,   1,  83,  84, 
-     65,  84, 116,   0,   0,   0, 
-      4,   0,   0,   0,   1,   0, 
-      0,   0,   0,   0,   0,   0, 
-      2,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   1,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   1,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   2,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,  82,  68,  69,  70, 
-    160,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      2,   0,   0,   0,  28,   0, 
-      0,   0,   0,   4, 255, 255, 
-      0,   1,   0,   0, 109,   0, 
-      0,   0,  92,   0,   0,   0, 
-      3,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   1,   0,   0,   0, 
-      1,   0,   0,   0, 100,   0, 
-      0,   0,   2,   0,   0,   0, 
-      5,   0,   0,   0,   4,   0, 
-      0,   0, 255, 255, 255, 255, 
-      0,   0,   0,   0,   1,   0, 
-      0,   0,  13,   0,   0,   0, 
-     83,  97, 109, 112, 108, 101, 
-    114,   0,  84, 101, 120, 116, 
-    117, 114, 101,  70,   0,  77, 
-    105,  99, 114, 111, 115, 111, 
-    102, 116,  32,  40,  82,  41, 
-     32,  72,  76,  83,  76,  32, 
-     83, 104,  97, 100, 101, 114, 
-     32,  67, 111, 109, 112, 105, 
-    108, 101, 114,  32,  54,  46, 
-     51,  46,  57,  54,  48,  48, 
-     46,  49,  54,  51,  56,  52, 
-      0, 171,  73,  83,  71,  78, 
-     80,   0,   0,   0,   2,   0, 
-      0,   0,   8,   0,   0,   0, 
-     56,   0,   0,   0,   0,   0, 
-      0,   0,   1,   0,   0,   0, 
-      3,   0,   0,   0,   0,   0, 
-      0,   0,  15,   0,   0,   0, 
-     68,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      3,   0,   0,   0,   1,   0, 
-      0,   0,   3,   3,   0,   0, 
-     83,  86,  95,  80,  79,  83, 
-     73,  84,  73,  79,  78,   0, 
-     84,  69,  88,  67,  79,  79, 
-     82,  68,   0, 171, 171, 171, 
-     79,  83,  71,  78,  44,   0, 
-      0,   0,   1,   0,   0,   0, 
-      8,   0,   0,   0,  32,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   3,   0, 
-      0,   0,   0,   0,   0,   0, 
-     15,   0,   0,   0,  83,  86, 
-     95,  84,  65,  82,  71,  69, 
-     84,   0, 171, 171
-};
+#if 0
+//
+// Generated by Microsoft (R) HLSL Shader Compiler 6.3.9600.16384
+//
+//
+// Resource Bindings:
+//
+// Name                                 Type  Format         Dim Slot Elements
+// ------------------------------ ---------- ------- ----------- ---- --------
+// Sampler                           sampler      NA          NA    0        1
+// TextureF                          texture  float4          2d    0        1
+//
+//
+//
+// Input signature:
+//
+// Name                 Index   Mask Register SysValue  Format   Used
+// -------------------- ----- ------ -------- -------- ------- ------
+// SV_POSITION              0   xyzw        0      POS   float       
+// TEXCOORD                 0   xy          1     NONE   float   xy  
+//
+//
+// Output signature:
+//
+// Name                 Index   Mask Register SysValue  Format   Used
+// -------------------- ----- ------ -------- -------- ------- ------
+// SV_TARGET                0   xyzw        0   TARGET   float   xyzw
+//
+//
+// Sampler/Resource to DX9 shader sampler mappings:
+//
+// Target Sampler Source Sampler  Source Resource
+// -------------- --------------- ----------------
+// s0             s0              t0               
+//
+//
+// Level9 shader bytecode:
+//
+    ps_2_x
+    def c0, 1, 0, 0, 0
+    dcl t0.xy
+    dcl_2d s0
+    texld r0, t0, s0
+    mad r0, r0.x, c0.xxxy, c0.yyyx
+    mov oC0, r0
+
+// approximately 3 instruction slots used (1 texture, 2 arithmetic)
+ps_4_0
+dcl_sampler s0, mode_default
+dcl_resource_texture2d (float,float,float,float) t0
+dcl_input_ps linear v1.xy
+dcl_output o0.xyzw
+dcl_temps 1
+sample r0.xyzw, v1.xyxx, t0.xyzw, s0
+mov o0.xyz, r0.xxxx
+mov o0.w, l(1.000000)
+ret 
+// Approximately 4 instruction slots used
+#endif
+
+const BYTE g_PS_PassthroughLum2D[] =
+{
+     68,  88,  66,  67, 144,  18, 
+    242,  89, 150, 125,  18, 219, 
+    193, 196, 127, 207,  14, 165, 
+    198, 119,   1,   0,   0,   0, 
+     28,   3,   0,   0,   6,   0, 
+      0,   0,  56,   0,   0,   0, 
+    208,   0,   0,   0, 108,   1, 
+      0,   0, 232,   1,   0,   0, 
+    144,   2,   0,   0, 232,   2, 
+      0,   0,  65, 111, 110,  57, 
+    144,   0,   0,   0, 144,   0, 
+      0,   0,   0,   2, 255, 255, 
+    104,   0,   0,   0,  40,   0, 
+      0,   0,   0,   0,  40,   0, 
+      0,   0,  40,   0,   0,   0, 
+     40,   0,   1,   0,  36,   0, 
+      0,   0,  40,   0,   0,   0, 
+      0,   0,   1,   2, 255, 255, 
+     81,   0,   0,   5,   0,   0, 
+     15, 160,   0,   0, 128,  63, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+     31,   0,   0,   2,   0,   0, 
+      0, 128,   0,   0,   3, 176, 
+     31,   0,   0,   2,   0,   0, 
+      0, 144,   0,   8,  15, 160, 
+     66,   0,   0,   3,   0,   0, 
+     15, 128,   0,   0, 228, 176, 
+      0,   8, 228, 160,   4,   0, 
+      0,   4,   0,   0,  15, 128, 
+      0,   0,   0, 128,   0,   0, 
+     64, 160,   0,   0,  21, 160, 
+      1,   0,   0,   2,   0,   8, 
+     15, 128,   0,   0, 228, 128, 
+    255, 255,   0,   0,  83,  72, 
+     68,  82, 148,   0,   0,   0, 
+     64,   0,   0,   0,  37,   0, 
+      0,   0,  90,   0,   0,   3, 
+      0,  96,  16,   0,   0,   0, 
+      0,   0,  88,  24,   0,   4, 
+      0, 112,  16,   0,   0,   0, 
+      0,   0,  85,  85,   0,   0, 
+     98,  16,   0,   3,  50,  16, 
+     16,   0,   1,   0,   0,   0, 
+    101,   0,   0,   3, 242,  32, 
+     16,   0,   0,   0,   0,   0, 
+    104,   0,   0,   2,   1,   0, 
+      0,   0,  69,   0,   0,   9, 
+    242,   0,  16,   0,   0,   0, 
+      0,   0,  70,  16,  16,   0, 
+      1,   0,   0,   0,  70, 126, 
+     16,   0,   0,   0,   0,   0, 
+      0,  96,  16,   0,   0,   0, 
+      0,   0,  54,   0,   0,   5, 
+    114,  32,  16,   0,   0,   0, 
+      0,   0,   6,   0,  16,   0, 
+      0,   0,   0,   0,  54,   0, 
+      0,   5, 130,  32,  16,   0, 
+      0,   0,   0,   0,   1,  64, 
+      0,   0,   0,   0, 128,  63, 
+     62,   0,   0,   1,  83,  84, 
+     65,  84, 116,   0,   0,   0, 
+      4,   0,   0,   0,   1,   0, 
+      0,   0,   0,   0,   0,   0, 
+      2,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   1,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   1,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   2,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,  82,  68,  69,  70, 
+    160,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      2,   0,   0,   0,  28,   0, 
+      0,   0,   0,   4, 255, 255, 
+      0,   1,   0,   0, 109,   0, 
+      0,   0,  92,   0,   0,   0, 
+      3,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   1,   0,   0,   0, 
+      1,   0,   0,   0, 100,   0, 
+      0,   0,   2,   0,   0,   0, 
+      5,   0,   0,   0,   4,   0, 
+      0,   0, 255, 255, 255, 255, 
+      0,   0,   0,   0,   1,   0, 
+      0,   0,  13,   0,   0,   0, 
+     83,  97, 109, 112, 108, 101, 
+    114,   0,  84, 101, 120, 116, 
+    117, 114, 101,  70,   0,  77, 
+    105,  99, 114, 111, 115, 111, 
+    102, 116,  32,  40,  82,  41, 
+     32,  72,  76,  83,  76,  32, 
+     83, 104,  97, 100, 101, 114, 
+     32,  67, 111, 109, 112, 105, 
+    108, 101, 114,  32,  54,  46, 
+     51,  46,  57,  54,  48,  48, 
+     46,  49,  54,  51,  56,  52, 
+      0, 171,  73,  83,  71,  78, 
+     80,   0,   0,   0,   2,   0, 
+      0,   0,   8,   0,   0,   0, 
+     56,   0,   0,   0,   0,   0, 
+      0,   0,   1,   0,   0,   0, 
+      3,   0,   0,   0,   0,   0, 
+      0,   0,  15,   0,   0,   0, 
+     68,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      3,   0,   0,   0,   1,   0, 
+      0,   0,   3,   3,   0,   0, 
+     83,  86,  95,  80,  79,  83, 
+     73,  84,  73,  79,  78,   0, 
+     84,  69,  88,  67,  79,  79, 
+     82,  68,   0, 171, 171, 171, 
+     79,  83,  71,  78,  44,   0, 
+      0,   0,   1,   0,   0,   0, 
+      8,   0,   0,   0,  32,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   3,   0, 
+      0,   0,   0,   0,   0,   0, 
+     15,   0,   0,   0,  83,  86, 
+     95,  84,  65,  82,  71,  69, 
+     84,   0, 171, 171
+};
--- a/gfx/angle/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughlum3d11ps.h
+++ b/gfx/angle/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughlum3d11ps.h
@@ -1,160 +1,160 @@
-#if 0
-//
-// Generated by Microsoft (R) HLSL Shader Compiler 6.3.9600.16384
-//
-//
-// Resource Bindings:
-//
-// Name                                 Type  Format         Dim Slot Elements
-// ------------------------------ ---------- ------- ----------- ---- --------
-// Sampler                           sampler      NA          NA    0        1
-// TextureF                          texture  float4          3d    0        1
-//
-//
-//
-// Input signature:
-//
-// Name                 Index   Mask Register SysValue  Format   Used
-// -------------------- ----- ------ -------- -------- ------- ------
-// SV_POSITION              0   xyzw        0      POS   float       
-// SV_RENDERTARGETARRAYINDEX     0   x           1  RTINDEX    uint       
-// TEXCOORD                 0   xyz         2     NONE   float   xyz 
-//
-//
-// Output signature:
-//
-// Name                 Index   Mask Register SysValue  Format   Used
-// -------------------- ----- ------ -------- -------- ------- ------
-// SV_TARGET                0   xyzw        0   TARGET   float   xyzw
-//
-ps_4_0
-dcl_sampler s0, mode_default
-dcl_resource_texture3d (float,float,float,float) t0
-dcl_input_ps linear v2.xyz
-dcl_output o0.xyzw
-dcl_temps 1
-sample r0.xyzw, v2.xyzx, t0.xyzw, s0
-mov o0.xyz, r0.xxxx
-mov o0.w, l(1.000000)
-ret 
-// Approximately 4 instruction slots used
-#endif
-
-const BYTE g_PS_PassthroughLum3D[] =
-{
-     68,  88,  66,  67, 173, 177, 
-    219,  35, 149, 130,  33, 215, 
-    183, 219, 250, 244, 100,  17, 
-     62, 106,   1,   0,   0,   0, 
-    176,   2,   0,   0,   5,   0, 
-      0,   0,  52,   0,   0,   0, 
-    220,   0,   0,   0, 100,   1, 
-      0,   0, 152,   1,   0,   0, 
-     52,   2,   0,   0,  82,  68, 
-     69,  70, 160,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   2,   0,   0,   0, 
-     28,   0,   0,   0,   0,   4, 
-    255, 255,   0,   1,   0,   0, 
-    109,   0,   0,   0,  92,   0, 
-      0,   0,   3,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   1,   0, 
-      0,   0,   1,   0,   0,   0, 
-    100,   0,   0,   0,   2,   0, 
-      0,   0,   5,   0,   0,   0, 
-      8,   0,   0,   0, 255, 255, 
-    255, 255,   0,   0,   0,   0, 
-      1,   0,   0,   0,  13,   0, 
-      0,   0,  83,  97, 109, 112, 
-    108, 101, 114,   0,  84, 101, 
-    120, 116, 117, 114, 101,  70, 
-      0,  77, 105,  99, 114, 111, 
-    115, 111, 102, 116,  32,  40, 
-     82,  41,  32,  72,  76,  83, 
-     76,  32,  83, 104,  97, 100, 
-    101, 114,  32,  67, 111, 109, 
-    112, 105, 108, 101, 114,  32, 
-     54,  46,  51,  46,  57,  54, 
-     48,  48,  46,  49,  54,  51, 
-     56,  52,   0, 171,  73,  83, 
-     71,  78, 128,   0,   0,   0, 
-      3,   0,   0,   0,   8,   0, 
-      0,   0,  80,   0,   0,   0, 
-      0,   0,   0,   0,   1,   0, 
-      0,   0,   3,   0,   0,   0, 
-      0,   0,   0,   0,  15,   0, 
-      0,   0,  92,   0,   0,   0, 
-      0,   0,   0,   0,   4,   0, 
-      0,   0,   1,   0,   0,   0, 
-      1,   0,   0,   0,   1,   0, 
-      0,   0, 118,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   3,   0,   0,   0, 
-      2,   0,   0,   0,   7,   7, 
-      0,   0,  83,  86,  95,  80, 
-     79,  83,  73,  84,  73,  79, 
-     78,   0,  83,  86,  95,  82, 
-     69,  78,  68,  69,  82,  84, 
-     65,  82,  71,  69,  84,  65, 
-     82,  82,  65,  89,  73,  78, 
-     68,  69,  88,   0,  84,  69, 
-     88,  67,  79,  79,  82,  68, 
-      0, 171,  79,  83,  71,  78, 
-     44,   0,   0,   0,   1,   0, 
-      0,   0,   8,   0,   0,   0, 
-     32,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      3,   0,   0,   0,   0,   0, 
-      0,   0,  15,   0,   0,   0, 
-     83,  86,  95,  84,  65,  82, 
-     71,  69,  84,   0, 171, 171, 
-     83,  72,  68,  82, 148,   0, 
-      0,   0,  64,   0,   0,   0, 
-     37,   0,   0,   0,  90,   0, 
-      0,   3,   0,  96,  16,   0, 
-      0,   0,   0,   0,  88,  40, 
-      0,   4,   0, 112,  16,   0, 
-      0,   0,   0,   0,  85,  85, 
-      0,   0,  98,  16,   0,   3, 
-    114,  16,  16,   0,   2,   0, 
-      0,   0, 101,   0,   0,   3, 
-    242,  32,  16,   0,   0,   0, 
-      0,   0, 104,   0,   0,   2, 
-      1,   0,   0,   0,  69,   0, 
-      0,   9, 242,   0,  16,   0, 
-      0,   0,   0,   0,  70,  18, 
-     16,   0,   2,   0,   0,   0, 
-     70, 126,  16,   0,   0,   0, 
-      0,   0,   0,  96,  16,   0, 
-      0,   0,   0,   0,  54,   0, 
-      0,   5, 114,  32,  16,   0, 
-      0,   0,   0,   0,   6,   0, 
-     16,   0,   0,   0,   0,   0, 
-     54,   0,   0,   5, 130,  32, 
-     16,   0,   0,   0,   0,   0, 
-      1,  64,   0,   0,   0,   0, 
-    128,  63,  62,   0,   0,   1, 
-     83,  84,  65,  84, 116,   0, 
-      0,   0,   4,   0,   0,   0, 
-      1,   0,   0,   0,   0,   0, 
-      0,   0,   2,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      1,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   1,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      2,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0
-};
+#if 0
+//
+// Generated by Microsoft (R) HLSL Shader Compiler 6.3.9600.16384
+//
+//
+// Resource Bindings:
+//
+// Name                                 Type  Format         Dim Slot Elements
+// ------------------------------ ---------- ------- ----------- ---- --------
+// Sampler                           sampler      NA          NA    0        1
+// TextureF                          texture  float4          3d    0        1
+//
+//
+//
+// Input signature:
+//
+// Name                 Index   Mask Register SysValue  Format   Used
+// -------------------- ----- ------ -------- -------- ------- ------
+// SV_POSITION              0   xyzw        0      POS   float       
+// SV_RENDERTARGETARRAYINDEX     0   x           1  RTINDEX    uint       
+// TEXCOORD                 0   xyz         2     NONE   float   xyz 
+//
+//
+// Output signature:
+//
+// Name                 Index   Mask Register SysValue  Format   Used
+// -------------------- ----- ------ -------- -------- ------- ------
+// SV_TARGET                0   xyzw        0   TARGET   float   xyzw
+//
+ps_4_0
+dcl_sampler s0, mode_default
+dcl_resource_texture3d (float,float,float,float) t0
+dcl_input_ps linear v2.xyz
+dcl_output o0.xyzw
+dcl_temps 1
+sample r0.xyzw, v2.xyzx, t0.xyzw, s0
+mov o0.xyz, r0.xxxx
+mov o0.w, l(1.000000)
+ret 
+// Approximately 4 instruction slots used
+#endif
+
+const BYTE g_PS_PassthroughLum3D[] =
+{
+     68,  88,  66,  67, 173, 177, 
+    219,  35, 149, 130,  33, 215, 
+    183, 219, 250, 244, 100,  17, 
+     62, 106,   1,   0,   0,   0, 
+    176,   2,   0,   0,   5,   0, 
+      0,   0,  52,   0,   0,   0, 
+    220,   0,   0,   0, 100,   1, 
+      0,   0, 152,   1,   0,   0, 
+     52,   2,   0,   0,  82,  68, 
+     69,  70, 160,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   2,   0,   0,   0, 
+     28,   0,   0,   0,   0,   4, 
+    255, 255,   0,   1,   0,   0, 
+    109,   0,   0,   0,  92,   0, 
+      0,   0,   3,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   1,   0, 
+      0,   0,   1,   0,   0,   0, 
+    100,   0,   0,   0,   2,   0, 
+      0,   0,   5,   0,   0,   0, 
+      8,   0,   0,   0, 255, 255, 
+    255, 255,   0,   0,   0,   0, 
+      1,   0,   0,   0,  13,   0, 
+      0,   0,  83,  97, 109, 112, 
+    108, 101, 114,   0,  84, 101, 
+    120, 116, 117, 114, 101,  70, 
+      0,  77, 105,  99, 114, 111, 
+    115, 111, 102, 116,  32,  40, 
+     82,  41,  32,  72,  76,  83, 
+     76,  32,  83, 104,  97, 100, 
+    101, 114,  32,  67, 111, 109, 
+    112, 105, 108, 101, 114,  32, 
+     54,  46,  51,  46,  57,  54, 
+     48,  48,  46,  49,  54,  51, 
+     56,  52,   0, 171,  73,  83, 
+     71,  78, 128,   0,   0,   0, 
+      3,   0,   0,   0,   8,   0, 
+      0,   0,  80,   0,   0,   0, 
+      0,   0,   0,   0,   1,   0, 
+      0,   0,   3,   0,   0,   0, 
+      0,   0,   0,   0,  15,   0, 
+      0,   0,  92,   0,   0,   0, 
+      0,   0,   0,   0,   4,   0, 
+      0,   0,   1,   0,   0,   0, 
+      1,   0,   0,   0,   1,   0, 
+      0,   0, 118,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   3,   0,   0,   0, 
+      2,   0,   0,   0,   7,   7, 
+      0,   0,  83,  86,  95,  80, 
+     79,  83,  73,  84,  73,  79, 
+     78,   0,  83,  86,  95,  82, 
+     69,  78,  68,  69,  82,  84, 
+     65,  82,  71,  69,  84,  65, 
+     82,  82,  65,  89,  73,  78, 
+     68,  69,  88,   0,  84,  69, 
+     88,  67,  79,  79,  82,  68, 
+      0, 171,  79,  83,  71,  78, 
+     44,   0,   0,   0,   1,   0, 
+      0,   0,   8,   0,   0,   0, 
+     32,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      3,   0,   0,   0,   0,   0, 
+      0,   0,  15,   0,   0,   0, 
+     83,  86,  95,  84,  65,  82, 
+     71,  69,  84,   0, 171, 171, 
+     83,  72,  68,  82, 148,   0, 
+      0,   0,  64,   0,   0,   0, 
+     37,   0,   0,   0,  90,   0, 
+      0,   3,   0,  96,  16,   0, 
+      0,   0,   0,   0,  88,  40, 
+      0,   4,   0, 112,  16,   0, 
+      0,   0,   0,   0,  85,  85, 
+      0,   0,  98,  16,   0,   3, 
+    114,  16,  16,   0,   2,   0, 
+      0,   0, 101,   0,   0,   3, 
+    242,  32,  16,   0,   0,   0, 
+      0,   0, 104,   0,   0,   2, 
+      1,   0,   0,   0,  69,   0, 
+      0,   9, 242,   0,  16,   0, 
+      0,   0,   0,   0,  70,  18, 
+     16,   0,   2,   0,   0,   0, 
+     70, 126,  16,   0,   0,   0, 
+      0,   0,   0,  96,  16,   0, 
+      0,   0,   0,   0,  54,   0, 
+      0,   5, 114,  32,  16,   0, 
+      0,   0,   0,   0,   6,   0, 
+     16,   0,   0,   0,   0,   0, 
+     54,   0,   0,   5, 130,  32, 
+     16,   0,   0,   0,   0,   0, 
+      1,  64,   0,   0,   0,   0, 
+    128,  63,  62,   0,   0,   1, 
+     83,  84,  65,  84, 116,   0, 
+      0,   0,   4,   0,   0,   0, 
+      1,   0,   0,   0,   0,   0, 
+      0,   0,   2,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      1,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   1,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      2,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0
+};
--- a/gfx/angle/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughlumalpha2d11ps.h
+++ b/gfx/angle/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughlumalpha2d11ps.h
@@ -1,185 +1,185 @@
-#if 0
-//
-// Generated by Microsoft (R) HLSL Shader Compiler 6.3.9600.16384
-//
-//
-// Resource Bindings:
-//
-// Name                                 Type  Format         Dim Slot Elements
-// ------------------------------ ---------- ------- ----------- ---- --------
-// Sampler                           sampler      NA          NA    0        1
-// TextureF                          texture  float4          2d    0        1
-//
-//
-//
-// Input signature:
-//
-// Name                 Index   Mask Register SysValue  Format   Used
-// -------------------- ----- ------ -------- -------- ------- ------
-// SV_POSITION              0   xyzw        0      POS   float       
-// TEXCOORD                 0   xy          1     NONE   float   xy  
-//
-//
-// Output signature:
-//
-// Name                 Index   Mask Register SysValue  Format   Used
-// -------------------- ----- ------ -------- -------- ------- ------
-// SV_TARGET                0   xyzw        0   TARGET   float   xyzw
-//
-//
-// Sampler/Resource to DX9 shader sampler mappings:
-//
-// Target Sampler Source Sampler  Source Resource
-// -------------- --------------- ----------------
-// s0             s0              t0               
-//
-//
-// Level9 shader bytecode:
-//
-    ps_2_x
-    dcl t0.xy
-    dcl_2d s0
-    texld r0, t0, s0
-    mov r0, r0.xxxw
-    mov oC0, r0
-
-// approximately 3 instruction slots used (1 texture, 2 arithmetic)
-ps_4_0
-dcl_sampler s0, mode_default
-dcl_resource_texture2d (float,float,float,float) t0
-dcl_input_ps linear v1.xy
-dcl_output o0.xyzw
-dcl_temps 1
-sample r0.xyzw, v1.xyxx, t0.xyzw, s0
-mov o0.xyzw, r0.xxxw
-ret 
-// Approximately 3 instruction slots used
-#endif
-
-const BYTE g_PS_PassthroughLumAlpha2D[] =
-{
-     68,  88,  66,  67, 246, 240, 
-    158, 208, 214, 197, 166, 221, 
-     45,  58, 235, 164,  12, 157, 
-     62,  31,   1,   0,   0,   0, 
-    232,   2,   0,   0,   6,   0, 
-      0,   0,  56,   0,   0,   0, 
-    176,   0,   0,   0,  56,   1, 
-      0,   0, 180,   1,   0,   0, 
-     92,   2,   0,   0, 180,   2, 
-      0,   0,  65, 111, 110,  57, 
-    112,   0,   0,   0, 112,   0, 
-      0,   0,   0,   2, 255, 255, 
-     72,   0,   0,   0,  40,   0, 
-      0,   0,   0,   0,  40,   0, 
-      0,   0,  40,   0,   0,   0, 
-     40,   0,   1,   0,  36,   0, 
-      0,   0,  40,   0,   0,   0, 
-      0,   0,   1,   2, 255, 255, 
-     31,   0,   0,   2,   0,   0, 
-      0, 128,   0,   0,   3, 176, 
-     31,   0,   0,   2,   0,   0, 
-      0, 144,   0,   8,  15, 160, 
-     66,   0,   0,   3,   0,   0, 
-     15, 128,   0,   0, 228, 176, 
-      0,   8, 228, 160,   1,   0, 
-      0,   2,   0,   0,  15, 128, 
-      0,   0, 192, 128,   1,   0, 
-      0,   2,   0,   8,  15, 128, 
-      0,   0, 228, 128, 255, 255, 
-      0,   0,  83,  72,  68,  82, 
-    128,   0,   0,   0,  64,   0, 
-      0,   0,  32,   0,   0,   0, 
-     90,   0,   0,   3,   0,  96, 
-     16,   0,   0,   0,   0,   0, 
-     88,  24,   0,   4,   0, 112, 
-     16,   0,   0,   0,   0,   0, 
-     85,  85,   0,   0,  98,  16, 
-      0,   3,  50,  16,  16,   0, 
-      1,   0,   0,   0, 101,   0, 
-      0,   3, 242,  32,  16,   0, 
-      0,   0,   0,   0, 104,   0, 
-      0,   2,   1,   0,   0,   0, 
-     69,   0,   0,   9, 242,   0, 
-     16,   0,   0,   0,   0,   0, 
-     70,  16,  16,   0,   1,   0, 
-      0,   0,  70, 126,  16,   0, 
-      0,   0,   0,   0,   0,  96, 
-     16,   0,   0,   0,   0,   0, 
-     54,   0,   0,   5, 242,  32, 
-     16,   0,   0,   0,   0,   0, 
-      6,  12,  16,   0,   0,   0, 
-      0,   0,  62,   0,   0,   1, 
-     83,  84,  65,  84, 116,   0, 
-      0,   0,   3,   0,   0,   0, 
-      1,   0,   0,   0,   0,   0, 
-      0,   0,   2,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      1,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   1,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      1,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,  82,  68, 
-     69,  70, 160,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   2,   0,   0,   0, 
-     28,   0,   0,   0,   0,   4, 
-    255, 255,   0,   1,   0,   0, 
-    109,   0,   0,   0,  92,   0, 
-      0,   0,   3,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   1,   0, 
-      0,   0,   1,   0,   0,   0, 
-    100,   0,   0,   0,   2,   0, 
-      0,   0,   5,   0,   0,   0, 
-      4,   0,   0,   0, 255, 255, 
-    255, 255,   0,   0,   0,   0, 
-      1,   0,   0,   0,  13,   0, 
-      0,   0,  83,  97, 109, 112, 
-    108, 101, 114,   0,  84, 101, 
-    120, 116, 117, 114, 101,  70, 
-      0,  77, 105,  99, 114, 111, 
-    115, 111, 102, 116,  32,  40, 
-     82,  41,  32,  72,  76,  83, 
-     76,  32,  83, 104,  97, 100, 
-    101, 114,  32,  67, 111, 109, 
-    112, 105, 108, 101, 114,  32, 
-     54,  46,  51,  46,  57,  54, 
-     48,  48,  46,  49,  54,  51, 
-     56,  52,   0, 171,  73,  83, 
-     71,  78,  80,   0,   0,   0, 
-      2,   0,   0,   0,   8,   0, 
-      0,   0,  56,   0,   0,   0, 
-      0,   0,   0,   0,   1,   0, 
-      0,   0,   3,   0,   0,   0, 
-      0,   0,   0,   0,  15,   0, 
-      0,   0,  68,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   3,   0,   0,   0, 
-      1,   0,   0,   0,   3,   3, 
-      0,   0,  83,  86,  95,  80, 
-     79,  83,  73,  84,  73,  79, 
-     78,   0,  84,  69,  88,  67, 
-     79,  79,  82,  68,   0, 171, 
-    171, 171,  79,  83,  71,  78, 
-     44,   0,   0,   0,   1,   0, 
-      0,   0,   8,   0,   0,   0, 
-     32,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      3,   0,   0,   0,   0,   0, 
-      0,   0,  15,   0,   0,   0, 
-     83,  86,  95,  84,  65,  82, 
-     71,  69,  84,   0, 171, 171
-};
+#if 0
+//
+// Generated by Microsoft (R) HLSL Shader Compiler 6.3.9600.16384
+//
+//
+// Resource Bindings:
+//
+// Name                                 Type  Format         Dim Slot Elements
+// ------------------------------ ---------- ------- ----------- ---- --------
+// Sampler                           sampler      NA          NA    0        1
+// TextureF                          texture  float4          2d    0        1
+//
+//
+//
+// Input signature:
+//
+// Name                 Index   Mask Register SysValue  Format   Used
+// -------------------- ----- ------ -------- -------- ------- ------
+// SV_POSITION              0   xyzw        0      POS   float       
+// TEXCOORD                 0   xy          1     NONE   float   xy  
+//
+//
+// Output signature:
+//
+// Name                 Index   Mask Register SysValue  Format   Used
+// -------------------- ----- ------ -------- -------- ------- ------
+// SV_TARGET                0   xyzw        0   TARGET   float   xyzw
+//
+//
+// Sampler/Resource to DX9 shader sampler mappings:
+//
+// Target Sampler Source Sampler  Source Resource
+// -------------- --------------- ----------------
+// s0             s0              t0               
+//
+//
+// Level9 shader bytecode:
+//
+    ps_2_x
+    dcl t0.xy
+    dcl_2d s0
+    texld r0, t0, s0
+    mov r0, r0.xxxw
+    mov oC0, r0
+
+// approximately 3 instruction slots used (1 texture, 2 arithmetic)
+ps_4_0
+dcl_sampler s0, mode_default
+dcl_resource_texture2d (float,float,float,float) t0
+dcl_input_ps linear v1.xy
+dcl_output o0.xyzw
+dcl_temps 1
+sample r0.xyzw, v1.xyxx, t0.xyzw, s0
+mov o0.xyzw, r0.xxxw
+ret 
+// Approximately 3 instruction slots used
+#endif
+
+const BYTE g_PS_PassthroughLumAlpha2D[] =
+{
+     68,  88,  66,  67, 246, 240, 
+    158, 208, 214, 197, 166, 221, 
+     45,  58, 235, 164,  12, 157, 
+     62,  31,   1,   0,   0,   0, 
+    232,   2,   0,   0,   6,   0, 
+      0,   0,  56,   0,   0,   0, 
+    176,   0,   0,   0,  56,   1, 
+      0,   0, 180,   1,   0,   0, 
+     92,   2,   0,   0, 180,   2, 
+      0,   0,  65, 111, 110,  57, 
+    112,   0,   0,   0, 112,   0, 
+      0,   0,   0,   2, 255, 255, 
+     72,   0,   0,   0,  40,   0, 
+      0,   0,   0,   0,  40,   0, 
+      0,   0,  40,   0,   0,   0, 
+     40,   0,   1,   0,  36,   0, 
+      0,   0,  40,   0,   0,   0, 
+      0,   0,   1,   2, 255, 255, 
+     31,   0,   0,   2,   0,   0, 
+      0, 128,   0,   0,   3, 176, 
+     31,   0,   0,   2,   0,   0, 
+      0, 144,   0,   8,  15, 160, 
+     66,   0,   0,   3,   0,   0, 
+     15, 128,   0,   0, 228, 176, 
+      0,   8, 228, 160,   1,   0, 
+      0,   2,   0,   0,  15, 128, 
+      0,   0, 192, 128,   1,   0, 
+      0,   2,   0,   8,  15, 128, 
+      0,   0, 228, 128, 255, 255, 
+      0,   0,  83,  72,  68,  82, 
+    128,   0,   0,   0,  64,   0, 
+      0,   0,  32,   0,   0,   0, 
+     90,   0,   0,   3,   0,  96, 
+     16,   0,   0,   0,   0,   0, 
+     88,  24,   0,   4,   0, 112, 
+     16,   0,   0,   0,   0,   0, 
+     85,  85,   0,   0,  98,  16, 
+      0,   3,  50,  16,  16,   0, 
+      1,   0,   0,   0, 101,   0, 
+      0,   3, 242,  32,  16,   0, 
+      0,   0,   0,   0, 104,   0, 
+      0,   2,   1,   0,   0,   0, 
+     69,   0,   0,   9, 242,   0, 
+     16,   0,   0,   0,   0,   0, 
+     70,  16,  16,   0,   1,   0, 
+      0,   0,  70, 126,  16,   0, 
+      0,   0,   0,   0,   0,  96, 
+     16,   0,   0,   0,   0,   0, 
+     54,   0,   0,   5, 242,  32, 
+     16,   0,   0,   0,   0,   0, 
+      6,  12,  16,   0,   0,   0, 
+      0,   0,  62,   0,   0,   1, 
+     83,  84,  65,  84, 116,   0, 
+      0,   0,   3,   0,   0,   0, 
+      1,   0,   0,   0,   0,   0, 
+      0,   0,   2,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      1,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   1,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      1,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,  82,  68, 
+     69,  70, 160,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   2,   0,   0,   0, 
+     28,   0,   0,   0,   0,   4, 
+    255, 255,   0,   1,   0,   0, 
+    109,   0,   0,   0,  92,   0, 
+      0,   0,   3,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   1,   0, 
+      0,   0,   1,   0,   0,   0, 
+    100,   0,   0,   0,   2,   0, 
+      0,   0,   5,   0,   0,   0, 
+      4,   0,   0,   0, 255, 255, 
+    255, 255,   0,   0,   0,   0, 
+      1,   0,   0,   0,  13,   0, 
+      0,   0,  83,  97, 109, 112, 
+    108, 101, 114,   0,  84, 101, 
+    120, 116, 117, 114, 101,  70, 
+      0,  77, 105,  99, 114, 111, 
+    115, 111, 102, 116,  32,  40, 
+     82,  41,  32,  72,  76,  83, 
+     76,  32,  83, 104,  97, 100, 
+    101, 114,  32,  67, 111, 109, 
+    112, 105, 108, 101, 114,  32, 
+     54,  46,  51,  46,  57,  54, 
+     48,  48,  46,  49,  54,  51, 
+     56,  52,   0, 171,  73,  83, 
+     71,  78,  80,   0,   0,   0, 
+      2,   0,   0,   0,   8,   0, 
+      0,   0,  56,   0,   0,   0, 
+      0,   0,   0,   0,   1,   0, 
+      0,   0,   3,   0,   0,   0, 
+      0,   0,   0,   0,  15,   0, 
+      0,   0,  68,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   3,   0,   0,   0, 
+      1,   0,   0,   0,   3,   3, 
+      0,   0,  83,  86,  95,  80, 
+     79,  83,  73,  84,  73,  79, 
+     78,   0,  84,  69,  88,  67, 
+     79,  79,  82,  68,   0, 171, 
+    171, 171,  79,  83,  71,  78, 
+     44,   0,   0,   0,   1,   0, 
+      0,   0,   8,   0,   0,   0, 
+     32,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      3,   0,   0,   0,   0,   0, 
+      0,   0,  15,   0,   0,   0, 
+     83,  86,  95,  84,  65,  82, 
+     71,  69,  84,   0, 171, 171
+};
--- a/gfx/angle/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughlumalpha3d11ps.h
+++ b/gfx/angle/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughlumalpha3d11ps.h
@@ -1,156 +1,156 @@
-#if 0
-//
-// Generated by Microsoft (R) HLSL Shader Compiler 6.3.9600.16384
-//
-//
-// Resource Bindings:
-//
-// Name                                 Type  Format         Dim Slot Elements
-// ------------------------------ ---------- ------- ----------- ---- --------
-// Sampler                           sampler      NA          NA    0        1
-// TextureF                          texture  float4          3d    0        1
-//
-//
-//
-// Input signature:
-//
-// Name                 Index   Mask Register SysValue  Format   Used
-// -------------------- ----- ------ -------- -------- ------- ------
-// SV_POSITION              0   xyzw        0      POS   float       
-// SV_RENDERTARGETARRAYINDEX     0   x           1  RTINDEX    uint       
-// TEXCOORD                 0   xyz         2     NONE   float   xyz 
-//
-//
-// Output signature:
-//
-// Name                 Index   Mask Register SysValue  Format   Used
-// -------------------- ----- ------ -------- -------- ------- ------
-// SV_TARGET                0   xyzw        0   TARGET   float   xyzw
-//
-ps_4_0
-dcl_sampler s0, mode_default
-dcl_resource_texture3d (float,float,float,float) t0
-dcl_input_ps linear v2.xyz
-dcl_output o0.xyzw
-dcl_temps 1
-sample r0.xyzw, v2.xyzx, t0.xyzw, s0
-mov o0.xyzw, r0.xxxw
-ret 
-// Approximately 3 instruction slots used
-#endif
-
-const BYTE g_PS_PassthroughLumAlpha3D[] =
-{
-     68,  88,  66,  67, 224, 152, 
-    208, 227,  44, 106,  62, 235, 
-    129,  97, 207, 213,  29, 232, 
-    163,   6,   1,   0,   0,   0, 
-    156,   2,   0,   0,   5,   0, 
-      0,   0,  52,   0,   0,   0, 
-    220,   0,   0,   0, 100,   1, 
-      0,   0, 152,   1,   0,   0, 
-     32,   2,   0,   0,  82,  68, 
-     69,  70, 160,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   2,   0,   0,   0, 
-     28,   0,   0,   0,   0,   4, 
-    255, 255,   0,   1,   0,   0, 
-    109,   0,   0,   0,  92,   0, 
-      0,   0,   3,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   1,   0, 
-      0,   0,   1,   0,   0,   0, 
-    100,   0,   0,   0,   2,   0, 
-      0,   0,   5,   0,   0,   0, 
-      8,   0,   0,   0, 255, 255, 
-    255, 255,   0,   0,   0,   0, 
-      1,   0,   0,   0,  13,   0, 
-      0,   0,  83,  97, 109, 112, 
-    108, 101, 114,   0,  84, 101, 
-    120, 116, 117, 114, 101,  70, 
-      0,  77, 105,  99, 114, 111, 
-    115, 111, 102, 116,  32,  40, 
-     82,  41,  32,  72,  76,  83, 
-     76,  32,  83, 104,  97, 100, 
-    101, 114,  32,  67, 111, 109, 
-    112, 105, 108, 101, 114,  32, 
-     54,  46,  51,  46,  57,  54, 
-     48,  48,  46,  49,  54,  51, 
-     56,  52,   0, 171,  73,  83, 
-     71,  78, 128,   0,   0,   0, 
-      3,   0,   0,   0,   8,   0, 
-      0,   0,  80,   0,   0,   0, 
-      0,   0,   0,   0,   1,   0, 
-      0,   0,   3,   0,   0,   0, 
-      0,   0,   0,   0,  15,   0, 
-      0,   0,  92,   0,   0,   0, 
-      0,   0,   0,   0,   4,   0, 
-      0,   0,   1,   0,   0,   0, 
-      1,   0,   0,   0,   1,   0, 
-      0,   0, 118,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   3,   0,   0,   0, 
-      2,   0,   0,   0,   7,   7, 
-      0,   0,  83,  86,  95,  80, 
-     79,  83,  73,  84,  73,  79, 
-     78,   0,  83,  86,  95,  82, 
-     69,  78,  68,  69,  82,  84, 
-     65,  82,  71,  69,  84,  65, 
-     82,  82,  65,  89,  73,  78, 
-     68,  69,  88,   0,  84,  69, 
-     88,  67,  79,  79,  82,  68, 
-      0, 171,  79,  83,  71,  78, 
-     44,   0,   0,   0,   1,   0, 
-      0,   0,   8,   0,   0,   0, 
-     32,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      3,   0,   0,   0,   0,   0, 
-      0,   0,  15,   0,   0,   0, 
-     83,  86,  95,  84,  65,  82, 
-     71,  69,  84,   0, 171, 171, 
-     83,  72,  68,  82, 128,   0, 
-      0,   0,  64,   0,   0,   0, 
-     32,   0,   0,   0,  90,   0, 
-      0,   3,   0,  96,  16,   0, 
-      0,   0,   0,   0,  88,  40, 
-      0,   4,   0, 112,  16,   0, 
-      0,   0,   0,   0,  85,  85, 
-      0,   0,  98,  16,   0,   3, 
-    114,  16,  16,   0,   2,   0, 
-      0,   0, 101,   0,   0,   3, 
-    242,  32,  16,   0,   0,   0, 
-      0,   0, 104,   0,   0,   2, 
-      1,   0,   0,   0,  69,   0, 
-      0,   9, 242,   0,  16,   0, 
-      0,   0,   0,   0,  70,  18, 
-     16,   0,   2,   0,   0,   0, 
-     70, 126,  16,   0,   0,   0, 
-      0,   0,   0,  96,  16,   0, 
-      0,   0,   0,   0,  54,   0, 
-      0,   5, 242,  32,  16,   0, 
-      0,   0,   0,   0,   6,  12, 
-     16,   0,   0,   0,   0,   0, 
-     62,   0,   0,   1,  83,  84, 
-     65,  84, 116,   0,   0,   0, 
-      3,   0,   0,   0,   1,   0, 
-      0,   0,   0,   0,   0,   0, 
-      2,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   1,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   1,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   1,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0
-};
+#if 0
+//
+// Generated by Microsoft (R) HLSL Shader Compiler 6.3.9600.16384
+//
+//
+// Resource Bindings:
+//
+// Name                                 Type  Format         Dim Slot Elements
+// ------------------------------ ---------- ------- ----------- ---- --------
+// Sampler                           sampler      NA          NA    0        1
+// TextureF                          texture  float4          3d    0        1
+//
+//
+//
+// Input signature:
+//
+// Name                 Index   Mask Register SysValue  Format   Used
+// -------------------- ----- ------ -------- -------- ------- ------
+// SV_POSITION              0   xyzw        0      POS   float       
+// SV_RENDERTARGETARRAYINDEX     0   x           1  RTINDEX    uint       
+// TEXCOORD                 0   xyz         2     NONE   float   xyz 
+//
+//
+// Output signature:
+//
+// Name                 Index   Mask Register SysValue  Format   Used
+// -------------------- ----- ------ -------- -------- ------- ------
+// SV_TARGET                0   xyzw        0   TARGET   float   xyzw
+//
+ps_4_0
+dcl_sampler s0, mode_default
+dcl_resource_texture3d (float,float,float,float) t0
+dcl_input_ps linear v2.xyz
+dcl_output o0.xyzw
+dcl_temps 1
+sample r0.xyzw, v2.xyzx, t0.xyzw, s0
+mov o0.xyzw, r0.xxxw
+ret 
+// Approximately 3 instruction slots used
+#endif
+
+const BYTE g_PS_PassthroughLumAlpha3D[] =
+{
+     68,  88,  66,  67, 224, 152, 
+    208, 227,  44, 106,  62, 235, 
+    129,  97, 207, 213,  29, 232, 
+    163,   6,   1,   0,   0,   0, 
+    156,   2,   0,   0,   5,   0, 
+      0,   0,  52,   0,   0,   0, 
+    220,   0,   0,   0, 100,   1, 
+      0,   0, 152,   1,   0,   0, 
+     32,   2,   0,   0,  82,  68, 
+     69,  70, 160,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   2,   0,   0,   0, 
+     28,   0,   0,   0,   0,   4, 
+    255, 255,   0,   1,   0,   0, 
+    109,   0,   0,   0,  92,   0, 
+      0,   0,   3,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   1,   0, 
+      0,   0,   1,   0,   0,   0, 
+    100,   0,   0,   0,   2,   0, 
+      0,   0,   5,   0,   0,   0, 
+      8,   0,   0,   0, 255, 255, 
+    255, 255,   0,   0,   0,   0, 
+      1,   0,   0,   0,  13,   0, 
+      0,   0,  83,  97, 109, 112, 
+    108, 101, 114,   0,  84, 101, 
+    120, 116, 117, 114, 101,  70, 
+      0,  77, 105,  99, 114, 111, 
+    115, 111, 102, 116,  32,  40, 
+     82,  41,  32,  72,  76,  83, 
+     76,  32,  83, 104,  97, 100, 
+    101, 114,  32,  67, 111, 109, 
+    112, 105, 108, 101, 114,  32, 
+     54,  46,  51,  46,  57,  54, 
+     48,  48,  46,  49,  54,  51, 
+     56,  52,   0, 171,  73,  83, 
+     71,  78, 128,   0,   0,   0, 
+      3,   0,   0,   0,   8,   0, 
+      0,   0,  80,   0,   0,   0, 
+      0,   0,   0,   0,   1,   0, 
+      0,   0,   3,   0,   0,   0, 
+      0,   0,   0,   0,  15,   0, 
+      0,   0,  92,   0,   0,   0, 
+      0,   0,   0,   0,   4,   0, 
+      0,   0,   1,   0,   0,   0, 
+      1,   0,   0,   0,   1,   0, 
+      0,   0, 118,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   3,   0,   0,   0, 
+      2,   0,   0,   0,   7,   7, 
+      0,   0,  83,  86,  95,  80, 
+     79,  83,  73,  84,  73,  79, 
+     78,   0,  83,  86,  95,  82, 
+     69,  78,  68,  69,  82,  84, 
+     65,  82,  71,  69,  84,  65, 
+     82,  82,  65,  89,  73,  78, 
+     68,  69,  88,   0,  84,  69, 
+     88,  67,  79,  79,  82,  68, 
+      0, 171,  79,  83,  71,  78, 
+     44,   0,   0,   0,   1,   0, 
+      0,   0,   8,   0,   0,   0, 
+     32,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      3,   0,   0,   0,   0,   0, 
+      0,   0,  15,   0,   0,   0, 
+     83,  86,  95,  84,  65,  82, 
+     71,  69,  84,   0, 171, 171, 
+     83,  72,  68,  82, 128,   0, 
+      0,   0,  64,   0,   0,   0, 
+     32,   0,   0,   0,  90,   0, 
+      0,   3,   0,  96,  16,   0, 
+      0,   0,   0,   0,  88,  40, 
+      0,   4,   0, 112,  16,   0, 
+      0,   0,   0,   0,  85,  85, 
+      0,   0,  98,  16,   0,   3, 
+    114,  16,  16,   0,   2,   0, 
+      0,   0, 101,   0,   0,   3, 
+    242,  32,  16,   0,   0,   0, 
+      0,   0, 104,   0,   0,   2, 
+      1,   0,   0,   0,  69,   0, 
+      0,   9, 242,   0,  16,   0, 
+      0,   0,   0,   0,  70,  18, 
+     16,   0,   2,   0,   0,   0, 
+     70, 126,  16,   0,   0,   0, 
+      0,   0,   0,  96,  16,   0, 
+      0,   0,   0,   0,  54,   0, 
+      0,   5, 242,  32,  16,   0, 
+      0,   0,   0,   0,   6,  12, 
+     16,   0,   0,   0,   0,   0, 
+     62,   0,   0,   1,  83,  84, 
+     65,  84, 116,   0,   0,   0, 
+      3,   0,   0,   0,   1,   0, 
+      0,   0,   0,   0,   0,   0, 
+      2,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   1,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   1,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   1,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0
+};
--- a/gfx/angle/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughr2d11ps.h
+++ b/gfx/angle/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughr2d11ps.h
@@ -1,198 +1,198 @@
-#if 0
-//
-// Generated by Microsoft (R) HLSL Shader Compiler 6.3.9600.16384
-//
-//
-// Resource Bindings:
-//
-// Name                                 Type  Format         Dim Slot Elements
-// ------------------------------ ---------- ------- ----------- ---- --------
-// Sampler                           sampler      NA          NA    0        1
-// TextureF                          texture  float4          2d    0        1
-//
-//
-//
-// Input signature:
-//
-// Name                 Index   Mask Register SysValue  Format   Used
-// -------------------- ----- ------ -------- -------- ------- ------
-// SV_POSITION              0   xyzw        0      POS   float       
-// TEXCOORD                 0   xy          1     NONE   float   xy  
-//
-//
-// Output signature:
-//
-// Name                 Index   Mask Register SysValue  Format   Used
-// -------------------- ----- ------ -------- -------- ------- ------
-// SV_TARGET                0   xyzw        0   TARGET   float   xyzw
-//
-//
-// Sampler/Resource to DX9 shader sampler mappings:
-//
-// Target Sampler Source Sampler  Source Resource
-// -------------- --------------- ----------------
-// s0             s0              t0               
-//
-//
-// Level9 shader bytecode:
-//
-    ps_2_x
-    def c0, 1, 0, 0, 0
-    dcl t0.xy
-    dcl_2d s0
-    texld r0, t0, s0
-    mad r0, r0.x, c0.xyyy, c0.yyyx
-    mov oC0, r0
-
-// approximately 3 instruction slots used (1 texture, 2 arithmetic)
-ps_4_0
-dcl_sampler s0, mode_default
-dcl_resource_texture2d (float,float,float,float) t0
-dcl_input_ps linear v1.xy
-dcl_output o0.xyzw
-dcl_temps 1
-sample r0.xyzw, v1.xyxx, t0.xyzw, s0
-mov o0.x, r0.x
-mov o0.yzw, l(0,0,0,1.000000)
-ret 
-// Approximately 4 instruction slots used
-#endif
-
-const BYTE g_PS_PassthroughR2D[] =
-{
-     68,  88,  66,  67, 212, 251, 
-    117, 250,  99, 185,  28,  44, 
-    178,  14,  83, 133, 173,   0, 
-    182, 196,   1,   0,   0,   0, 
-     40,   3,   0,   0,   6,   0, 
-      0,   0,  56,   0,   0,   0, 
-    208,   0,   0,   0, 120,   1, 
-      0,   0, 244,   1,   0,   0, 
-    156,   2,   0,   0, 244,   2, 
-      0,   0,  65, 111, 110,  57, 
-    144,   0,   0,   0, 144,   0, 
-      0,   0,   0,   2, 255, 255, 
-    104,   0,   0,   0,  40,   0, 
-      0,   0,   0,   0,  40,   0, 
-      0,   0,  40,   0,   0,   0, 
-     40,   0,   1,   0,  36,   0, 
-      0,   0,  40,   0,   0,   0, 
-      0,   0,   1,   2, 255, 255, 
-     81,   0,   0,   5,   0,   0, 
-     15, 160,   0,   0, 128,  63, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-     31,   0,   0,   2,   0,   0, 
-      0, 128,   0,   0,   3, 176, 
-     31,   0,   0,   2,   0,   0, 
-      0, 144,   0,   8,  15, 160, 
-     66,   0,   0,   3,   0,   0, 
-     15, 128,   0,   0, 228, 176, 
-      0,   8, 228, 160,   4,   0, 
-      0,   4,   0,   0,  15, 128, 
-      0,   0,   0, 128,   0,   0, 
-     84, 160,   0,   0,  21, 160, 
-      1,   0,   0,   2,   0,   8, 
-     15, 128,   0,   0, 228, 128, 
-    255, 255,   0,   0,  83,  72, 
-     68,  82, 160,   0,   0,   0, 
-     64,   0,   0,   0,  40,   0, 
-      0,   0,  90,   0,   0,   3, 
-      0,  96,  16,   0,   0,   0, 
-      0,   0,  88,  24,   0,   4, 
-      0, 112,  16,   0,   0,   0, 
-      0,   0,  85,  85,   0,   0, 
-     98,  16,   0,   3,  50,  16, 
-     16,   0,   1,   0,   0,   0, 
-    101,   0,   0,   3, 242,  32, 
-     16,   0,   0,   0,   0,   0, 
-    104,   0,   0,   2,   1,   0, 
-      0,   0,  69,   0,   0,   9, 
-    242,   0,  16,   0,   0,   0, 
-      0,   0,  70,  16,  16,   0, 
-      1,   0,   0,   0,  70, 126, 
-     16,   0,   0,   0,   0,   0, 
-      0,  96,  16,   0,   0,   0, 
-      0,   0,  54,   0,   0,   5, 
-     18,  32,  16,   0,   0,   0, 
-      0,   0,  10,   0,  16,   0, 
-      0,   0,   0,   0,  54,   0, 
-      0,   8, 226,  32,  16,   0, 
-      0,   0,   0,   0,   2,  64, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0, 128,  63, 
-     62,   0,   0,   1,  83,  84, 
-     65,  84, 116,   0,   0,   0, 
-      4,   0,   0,   0,   1,   0, 
-      0,   0,   0,   0,   0,   0, 
-      2,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   1,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   1,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   2,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,  82,  68,  69,  70, 
-    160,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      2,   0,   0,   0,  28,   0, 
-      0,   0,   0,   4, 255, 255, 
-      0,   1,   0,   0, 109,   0, 
-      0,   0,  92,   0,   0,   0, 
-      3,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   1,   0,   0,   0, 
-      1,   0,   0,   0, 100,   0, 
-      0,   0,   2,   0,   0,   0, 
-      5,   0,   0,   0,   4,   0, 
-      0,   0, 255, 255, 255, 255, 
-      0,   0,   0,   0,   1,   0, 
-      0,   0,  13,   0,   0,   0, 
-     83,  97, 109, 112, 108, 101, 
-    114,   0,  84, 101, 120, 116, 
-    117, 114, 101,  70,   0,  77, 
-    105,  99, 114, 111, 115, 111, 
-    102, 116,  32,  40,  82,  41, 
-     32,  72,  76,  83,  76,  32, 
-     83, 104,  97, 100, 101, 114, 
-     32,  67, 111, 109, 112, 105, 
-    108, 101, 114,  32,  54,  46, 
-     51,  46,  57,  54,  48,  48, 
-     46,  49,  54,  51,  56,  52, 
-      0, 171,  73,  83,  71,  78, 
-     80,   0,   0,   0,   2,   0, 
-      0,   0,   8,   0,   0,   0, 
-     56,   0,   0,   0,   0,   0, 
-      0,   0,   1,   0,   0,   0, 
-      3,   0,   0,   0,   0,   0, 
-      0,   0,  15,   0,   0,   0, 
-     68,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      3,   0,   0,   0,   1,   0, 
-      0,   0,   3,   3,   0,   0, 
-     83,  86,  95,  80,  79,  83, 
-     73,  84,  73,  79,  78,   0, 
-     84,  69,  88,  67,  79,  79, 
-     82,  68,   0, 171, 171, 171, 
-     79,  83,  71,  78,  44,   0, 
-      0,   0,   1,   0,   0,   0, 
-      8,   0,   0,   0,  32,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   3,   0, 
-      0,   0,   0,   0,   0,   0, 
-     15,   0,   0,   0,  83,  86, 
-     95,  84,  65,  82,  71,  69, 
-     84,   0, 171, 171
-};
+#if 0
+//
+// Generated by Microsoft (R) HLSL Shader Compiler 6.3.9600.16384
+//
+//
+// Resource Bindings:
+//
+// Name                                 Type  Format         Dim Slot Elements
+// ------------------------------ ---------- ------- ----------- ---- --------
+// Sampler                           sampler      NA          NA    0        1
+// TextureF                          texture  float4          2d    0        1
+//
+//
+//
+// Input signature:
+//
+// Name                 Index   Mask Register SysValue  Format   Used
+// -------------------- ----- ------ -------- -------- ------- ------
+// SV_POSITION              0   xyzw        0      POS   float       
+// TEXCOORD                 0   xy          1     NONE   float   xy  
+//
+//
+// Output signature:
+//
+// Name                 Index   Mask Register SysValue  Format   Used
+// -------------------- ----- ------ -------- -------- ------- ------
+// SV_TARGET                0   xyzw        0   TARGET   float   xyzw
+//
+//
+// Sampler/Resource to DX9 shader sampler mappings:
+//
+// Target Sampler Source Sampler  Source Resource
+// -------------- --------------- ----------------
+// s0             s0              t0               
+//
+//
+// Level9 shader bytecode:
+//
+    ps_2_x
+    def c0, 1, 0, 0, 0
+    dcl t0.xy
+    dcl_2d s0
+    texld r0, t0, s0
+    mad r0, r0.x, c0.xyyy, c0.yyyx
+    mov oC0, r0
+
+// approximately 3 instruction slots used (1 texture, 2 arithmetic)
+ps_4_0
+dcl_sampler s0, mode_default
+dcl_resource_texture2d (float,float,float,float) t0
+dcl_input_ps linear v1.xy
+dcl_output o0.xyzw
+dcl_temps 1
+sample r0.xyzw, v1.xyxx, t0.xyzw, s0
+mov o0.x, r0.x
+mov o0.yzw, l(0,0,0,1.000000)
+ret 
+// Approximately 4 instruction slots used
+#endif
+
+const BYTE g_PS_PassthroughR2D[] =
+{
+     68,  88,  66,  67, 212, 251, 
+    117, 250,  99, 185,  28,  44, 
+    178,  14,  83, 133, 173,   0, 
+    182, 196,   1,   0,   0,   0, 
+     40,   3,   0,   0,   6,   0, 
+      0,   0,  56,   0,   0,   0, 
+    208,   0,   0,   0, 120,   1, 
+      0,   0, 244,   1,   0,   0, 
+    156,   2,   0,   0, 244,   2, 
+      0,   0,  65, 111, 110,  57, 
+    144,   0,   0,   0, 144,   0, 
+      0,   0,   0,   2, 255, 255, 
+    104,   0,   0,   0,  40,   0, 
+      0,   0,   0,   0,  40,   0, 
+      0,   0,  40,   0,   0,   0, 
+     40,   0,   1,   0,  36,   0, 
+      0,   0,  40,   0,   0,   0, 
+      0,   0,   1,   2, 255, 255, 
+     81,   0,   0,   5,   0,   0, 
+     15, 160,   0,   0, 128,  63, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+     31,   0,   0,   2,   0,   0, 
+      0, 128,   0,   0,   3, 176, 
+     31,   0,   0,   2,   0,   0, 
+      0, 144,   0,   8,  15, 160, 
+     66,   0,   0,   3,   0,   0, 
+     15, 128,   0,   0, 228, 176, 
+      0,   8, 228, 160,   4,   0, 
+      0,   4,   0,   0,  15, 128, 
+      0,   0,   0, 128,   0,   0, 
+     84, 160,   0,   0,  21, 160, 
+      1,   0,   0,   2,   0,   8, 
+     15, 128,   0,   0, 228, 128, 
+    255, 255,   0,   0,  83,  72, 
+     68,  82, 160,   0,   0,   0, 
+     64,   0,   0,   0,  40,   0, 
+      0,   0,  90,   0,   0,   3, 
+      0,  96,  16,   0,   0,   0, 
+      0,   0,  88,  24,   0,   4, 
+      0, 112,  16,   0,   0,   0, 
+      0,   0,  85,  85,   0,   0, 
+     98,  16,   0,   3,  50,  16, 
+     16,   0,   1,   0,   0,   0, 
+    101,   0,   0,   3, 242,  32, 
+     16,   0,   0,   0,   0,   0, 
+    104,   0,   0,   2,   1,   0, 
+      0,   0,  69,   0,   0,   9, 
+    242,   0,  16,   0,   0,   0, 
+      0,   0,  70,  16,  16,   0, 
+      1,   0,   0,   0,  70, 126, 
+     16,   0,   0,   0,   0,   0, 
+      0,  96,  16,   0,   0,   0, 
+      0,   0,  54,   0,   0,   5, 
+     18,  32,  16,   0,   0,   0, 
+      0,   0,  10,   0,  16,   0, 
+      0,   0,   0,   0,  54,   0, 
+      0,   8, 226,  32,  16,   0, 
+      0,   0,   0,   0,   2,  64, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0, 128,  63, 
+     62,   0,   0,   1,  83,  84, 
+     65,  84, 116,   0,   0,   0, 
+      4,   0,   0,   0,   1,   0, 
+      0,   0,   0,   0,   0,   0, 
+      2,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   1,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   1,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   2,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,  82,  68,  69,  70, 
+    160,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      2,   0,   0,   0,  28,   0, 
+      0,   0,   0,   4, 255, 255, 
+      0,   1,   0,   0, 109,   0, 
+      0,   0,  92,   0,   0,   0, 
+      3,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   1,   0,   0,   0, 
+      1,   0,   0,   0, 100,   0, 
+      0,   0,   2,   0,   0,   0, 
+      5,   0,   0,   0,   4,   0, 
+      0,   0, 255, 255, 255, 255, 
+      0,   0,   0,   0,   1,   0, 
+      0,   0,  13,   0,   0,   0, 
+     83,  97, 109, 112, 108, 101, 
+    114,   0,  84, 101, 120, 116, 
+    117, 114, 101,  70,   0,  77, 
+    105,  99, 114, 111, 115, 111, 
+    102, 116,  32,  40,  82,  41, 
+     32,  72,  76,  83,  76,  32, 
+     83, 104,  97, 100, 101, 114, 
+     32,  67, 111, 109, 112, 105, 
+    108, 101, 114,  32,  54,  46, 
+     51,  46,  57,  54,  48,  48, 
+     46,  49,  54,  51,  56,  52, 
+      0, 171,  73,  83,  71,  78, 
+     80,   0,   0,   0,   2,   0, 
+      0,   0,   8,   0,   0,   0, 
+     56,   0,   0,   0,   0,   0, 
+      0,   0,   1,   0,   0,   0, 
+      3,   0,   0,   0,   0,   0, 
+      0,   0,  15,   0,   0,   0, 
+     68,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      3,   0,   0,   0,   1,   0, 
+      0,   0,   3,   3,   0,   0, 
+     83,  86,  95,  80,  79,  83, 
+     73,  84,  73,  79,  78,   0, 
+     84,  69,  88,  67,  79,  79, 
+     82,  68,   0, 171, 171, 171, 
+     79,  83,  71,  78,  44,   0, 
+      0,   0,   1,   0,   0,   0, 
+      8,   0,   0,   0,  32,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   3,   0, 
+      0,   0,   0,   0,   0,   0, 
+     15,   0,   0,   0,  83,  86, 
+     95,  84,  65,  82,  71,  69, 
+     84,   0, 171, 171
+};
--- a/gfx/angle/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughr2di11ps.h
+++ b/gfx/angle/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughr2di11ps.h
@@ -1,167 +1,167 @@
-#if 0
-//
-// Generated by Microsoft (R) HLSL Shader Compiler 6.3.9600.16384
-//
-//
-// Resource Bindings:
-//
-// Name                                 Type  Format         Dim Slot Elements
-// ------------------------------ ---------- ------- ----------- ---- --------
-// TextureI                          texture   sint4          2d    0        1
-//
-//
-//
-// Input signature:
-//
-// Name                 Index   Mask Register SysValue  Format   Used
-// -------------------- ----- ------ -------- -------- ------- ------
-// SV_POSITION              0   xyzw        0      POS   float       
-// TEXCOORD                 0   xy          1     NONE   float   xy  
-//
-//
-// Output signature:
-//
-// Name                 Index   Mask Register SysValue  Format   Used
-// -------------------- ----- ------ -------- -------- ------- ------
-// SV_TARGET                0   xyzw        0   TARGET     int   xyzw
-//
-ps_4_0
-dcl_resource_texture2d (sint,sint,sint,sint) t0
-dcl_input_ps linear v1.xy
-dcl_output o0.xyzw
-dcl_temps 1
-resinfo_uint r0.xyzw, l(0), t0.xyzw
-utof r0.xy, r0.xyxx
-mul r0.xy, r0.xyxx, v1.xyxx
-ftoi r0.xy, r0.xyxx
-mov r0.zw, l(0,0,0,0)
-ld r0.xyzw, r0.xyzw, t0.xyzw
-mov o0.x, r0.x
-mov o0.yzw, l(0,0,0,0)
-ret 
-// Approximately 9 instruction slots used
-#endif
-
-const BYTE g_PS_PassthroughR2DI[] =
-{
-     68,  88,  66,  67, 123, 230, 
-     45,  18,  63, 217,  12, 210, 
-    151, 254,  16,  78, 107, 211, 
-     57, 255,   1,   0,   0,   0, 
-    208,   2,   0,   0,   5,   0, 
-      0,   0,  52,   0,   0,   0, 
-    180,   0,   0,   0,  12,   1, 
-      0,   0,  64,   1,   0,   0, 
-     84,   2,   0,   0,  82,  68, 
-     69,  70, 120,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   1,   0,   0,   0, 
-     28,   0,   0,   0,   0,   4, 
-    255, 255,   0,   1,   0,   0, 
-     69,   0,   0,   0,  60,   0, 
-      0,   0,   2,   0,   0,   0, 
-      3,   0,   0,   0,   4,   0, 
-      0,   0, 255, 255, 255, 255, 
-      0,   0,   0,   0,   1,   0, 
-      0,   0,  13,   0,   0,   0, 
-     84, 101, 120, 116, 117, 114, 
-    101,  73,   0,  77, 105,  99, 
-    114, 111, 115, 111, 102, 116, 
-     32,  40,  82,  41,  32,  72, 
-     76,  83,  76,  32,  83, 104, 
-     97, 100, 101, 114,  32,  67, 
-    111, 109, 112, 105, 108, 101, 
-    114,  32,  54,  46,  51,  46, 
-     57,  54,  48,  48,  46,  49, 
-     54,  51,  56,  52,   0, 171, 
-     73,  83,  71,  78,  80,   0, 
-      0,   0,   2,   0,   0,   0, 
-      8,   0,   0,   0,  56,   0, 
-      0,   0,   0,   0,   0,   0, 
-      1,   0,   0,   0,   3,   0, 
-      0,   0,   0,   0,   0,   0, 
-     15,   0,   0,   0,  68,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   3,   0, 
-      0,   0,   1,   0,   0,   0, 
-      3,   3,   0,   0,  83,  86, 
-     95,  80,  79,  83,  73,  84, 
-     73,  79,  78,   0,  84,  69, 
-     88,  67,  79,  79,  82,  68, 
-      0, 171, 171, 171,  79,  83, 
-     71,  78,  44,   0,   0,   0, 
-      1,   0,   0,   0,   8,   0, 
-      0,   0,  32,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   2,   0,   0,   0, 
-      0,   0,   0,   0,  15,   0, 
-      0,   0,  83,  86,  95,  84, 
-     65,  82,  71,  69,  84,   0, 
-    171, 171,  83,  72,  68,  82, 
-     12,   1,   0,   0,  64,   0, 
-      0,   0,  67,   0,   0,   0, 
-     88,  24,   0,   4,   0, 112, 
-     16,   0,   0,   0,   0,   0, 
-     51,  51,   0,   0,  98,  16, 
-      0,   3,  50,  16,  16,   0, 
-      1,   0,   0,   0, 101,   0, 
-      0,   3, 242,  32,  16,   0, 
-      0,   0,   0,   0, 104,   0, 
-      0,   2,   1,   0,   0,   0, 
-     61,  16,   0,   7, 242,   0, 
-     16,   0,   0,   0,   0,   0, 
-      1,  64,   0,   0,   0,   0, 
-      0,   0,  70, 126,  16,   0, 
-      0,   0,   0,   0,  86,   0, 
-      0,   5,  50,   0,  16,   0, 
-      0,   0,   0,   0,  70,   0, 
-     16,   0,   0,   0,   0,   0, 
-     56,   0,   0,   7,  50,   0, 
-     16,   0,   0,   0,   0,   0, 
-     70,   0,  16,   0,   0,   0, 
-      0,   0,  70,  16,  16,   0, 
-      1,   0,   0,   0,  27,   0, 
-      0,   5,  50,   0,  16,   0, 
-      0,   0,   0,   0,  70,   0, 
-     16,   0,   0,   0,   0,   0, 
-     54,   0,   0,   8, 194,   0, 
-     16,   0,   0,   0,   0,   0, 
-      2,  64,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,  45,   0,   0,   7, 
-    242,   0,  16,   0,   0,   0, 
-      0,   0,  70,  14,  16,   0, 
-      0,   0,   0,   0,  70, 126, 
-     16,   0,   0,   0,   0,   0, 
-     54,   0,   0,   5,  18,  32, 
-     16,   0,   0,   0,   0,   0, 
-     10,   0,  16,   0,   0,   0, 
-      0,   0,  54,   0,   0,   8, 
-    226,  32,  16,   0,   0,   0, 
-      0,   0,   2,  64,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,  62,   0, 
-      0,   1,  83,  84,  65,  84, 
-    116,   0,   0,   0,   9,   0, 
-      0,   0,   1,   0,   0,   0, 
-      0,   0,   0,   0,   2,   0, 
-      0,   0,   1,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   1,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   1,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   3,   0,   0,   0, 
-      0,   0,   0,   0,   2,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0
-};
+#if 0
+//
+// Generated by Microsoft (R) HLSL Shader Compiler 6.3.9600.16384
+//
+//
+// Resource Bindings:
+//
+// Name                                 Type  Format         Dim Slot Elements
+// ------------------------------ ---------- ------- ----------- ---- --------
+// TextureI                          texture   sint4          2d    0        1
+//
+//
+//
+// Input signature:
+//
+// Name                 Index   Mask Register SysValue  Format   Used
+// -------------------- ----- ------ -------- -------- ------- ------
+// SV_POSITION              0   xyzw        0      POS   float       
+// TEXCOORD                 0   xy          1     NONE   float   xy  
+//
+//
+// Output signature:
+//
+// Name                 Index   Mask Register SysValue  Format   Used
+// -------------------- ----- ------ -------- -------- ------- ------
+// SV_TARGET                0   xyzw        0   TARGET     int   xyzw
+//
+ps_4_0
+dcl_resource_texture2d (sint,sint,sint,sint) t0
+dcl_input_ps linear v1.xy
+dcl_output o0.xyzw
+dcl_temps 1
+resinfo_uint r0.xyzw, l(0), t0.xyzw
+utof r0.xy, r0.xyxx
+mul r0.xy, r0.xyxx, v1.xyxx
+ftoi r0.xy, r0.xyxx
+mov r0.zw, l(0,0,0,0)
+ld r0.xyzw, r0.xyzw, t0.xyzw
+mov o0.x, r0.x
+mov o0.yzw, l(0,0,0,0)
+ret 
+// Approximately 9 instruction slots used
+#endif
+
+const BYTE g_PS_PassthroughR2DI[] =
+{
+     68,  88,  66,  67, 123, 230, 
+     45,  18,  63, 217,  12, 210, 
+    151, 254,  16,  78, 107, 211, 
+     57, 255,   1,   0,   0,   0, 
+    208,   2,   0,   0,   5,   0, 
+      0,   0,  52,   0,   0,   0, 
+    180,   0,   0,   0,  12,   1, 
+      0,   0,  64,   1,   0,   0, 
+     84,   2,   0,   0,  82,  68, 
+     69,  70, 120,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   1,   0,   0,   0, 
+     28,   0,   0,   0,   0,   4, 
+    255, 255,   0,   1,   0,   0, 
+     69,   0,   0,   0,  60,   0, 
+      0,   0,   2,   0,   0,   0, 
+      3,   0,   0,   0,   4,   0, 
+      0,   0, 255, 255, 255, 255, 
+      0,   0,   0,   0,   1,   0, 
+      0,   0,  13,   0,   0,   0, 
+     84, 101, 120, 116, 117, 114, 
+    101,  73,   0,  77, 105,  99, 
+    114, 111, 115, 111, 102, 116, 
+     32,  40,  82,  41,  32,  72, 
+     76,  83,  76,  32,  83, 104, 
+     97, 100, 101, 114,  32,  67, 
+    111, 109, 112, 105, 108, 101, 
+    114,  32,  54,  46,  51,  46, 
+     57,  54,  48,  48,  46,  49, 
+     54,  51,  56,  52,   0, 171, 
+     73,  83,  71,  78,  80,   0, 
+      0,   0,   2,   0,   0,   0, 
+      8,   0,   0,   0,  56,   0, 
+      0,   0,   0,   0,   0,   0, 
+      1,   0,   0,   0,   3,   0, 
+      0,   0,   0,   0,   0,   0, 
+     15,   0,   0,   0,  68,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   3,   0, 
+      0,   0,   1,   0,   0,   0, 
+      3,   3,   0,   0,  83,  86, 
+     95,  80,  79,  83,  73,  84, 
+     73,  79,  78,   0,  84,  69, 
+     88,  67,  79,  79,  82,  68, 
+      0, 171, 171, 171,  79,  83, 
+     71,  78,  44,   0,   0,   0, 
+      1,   0,   0,   0,   8,   0, 
+      0,   0,  32,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   2,   0,   0,   0, 
+      0,   0,   0,   0,  15,   0, 
+      0,   0,  83,  86,  95,  84, 
+     65,  82,  71,  69,  84,   0, 
+    171, 171,  83,  72,  68,  82, 
+     12,   1,   0,   0,  64,   0, 
+      0,   0,  67,   0,   0,   0, 
+     88,  24,   0,   4,   0, 112, 
+     16,   0,   0,   0,   0,   0, 
+     51,  51,   0,   0,  98,  16, 
+      0,   3,  50,  16,  16,   0, 
+      1,   0,   0,   0, 101,   0, 
+      0,   3, 242,  32,  16,   0, 
+      0,   0,   0,   0, 104,   0, 
+      0,   2,   1,   0,   0,   0, 
+     61,  16,   0,   7, 242,   0, 
+     16,   0,   0,   0,   0,   0, 
+      1,  64,   0,   0,   0,   0, 
+      0,   0,  70, 126,  16,   0, 
+      0,   0,   0,   0,  86,   0, 
+      0,   5,  50,   0,  16,   0, 
+      0,   0,   0,   0,  70,   0, 
+     16,   0,   0,   0,   0,   0, 
+     56,   0,   0,   7,  50,   0, 
+     16,   0,   0,   0,   0,   0, 
+     70,   0,  16,   0,   0,   0, 
+      0,   0,  70,  16,  16,   0, 
+      1,   0,   0,   0,  27,   0, 
+      0,   5,  50,   0,  16,   0, 
+      0,   0,   0,   0,  70,   0, 
+     16,   0,   0,   0,   0,   0, 
+     54,   0,   0,   8, 194,   0, 
+     16,   0,   0,   0,   0,   0, 
+      2,  64,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,  45,   0,   0,   7, 
+    242,   0,  16,   0,   0,   0, 
+      0,   0,  70,  14,  16,   0, 
+      0,   0,   0,   0,  70, 126, 
+     16,   0,   0,   0,   0,   0, 
+     54,   0,   0,   5,  18,  32, 
+     16,   0,   0,   0,   0,   0, 
+     10,   0,  16,   0,   0,   0, 
+      0,   0,  54,   0,   0,   8, 
+    226,  32,  16,   0,   0,   0, 
+      0,   0,   2,  64,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,  62,   0, 
+      0,   1,  83,  84,  65,  84, 
+    116,   0,   0,   0,   9,   0, 
+      0,   0,   1,   0,   0,   0, 
+      0,   0,   0,   0,   2,   0, 
+      0,   0,   1,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   1,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   1,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   3,   0,   0,   0, 
+      0,   0,   0,   0,   2,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0
+};
--- a/gfx/angle/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughr2dui11ps.h
+++ b/gfx/angle/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughr2dui11ps.h
@@ -1,167 +1,167 @@
-#if 0
-//
-// Generated by Microsoft (R) HLSL Shader Compiler 6.3.9600.16384
-//
-//
-// Resource Bindings:
-//
-// Name                                 Type  Format         Dim Slot Elements
-// ------------------------------ ---------- ------- ----------- ---- --------
-// TextureUI                         texture   uint4          2d    0        1
-//
-//
-//
-// Input signature:
-//
-// Name                 Index   Mask Register SysValue  Format   Used
-// -------------------- ----- ------ -------- -------- ------- ------
-// SV_POSITION              0   xyzw        0      POS   float       
-// TEXCOORD                 0   xy          1     NONE   float   xy  
-//
-//
-// Output signature:
-//
-// Name                 Index   Mask Register SysValue  Format   Used
-// -------------------- ----- ------ -------- -------- ------- ------
-// SV_TARGET                0   xyzw        0   TARGET    uint   xyzw
-//
-ps_4_0
-dcl_resource_texture2d (uint,uint,uint,uint) t0
-dcl_input_ps linear v1.xy
-dcl_output o0.xyzw
-dcl_temps 1
-resinfo_uint r0.xyzw, l(0), t0.xyzw
-utof r0.xy, r0.xyxx
-mul r0.xy, r0.xyxx, v1.xyxx
-ftoi r0.xy, r0.xyxx
-mov r0.zw, l(0,0,0,0)
-ld r0.xyzw, r0.xyzw, t0.xyzw
-mov o0.x, r0.x
-mov o0.yzw, l(0,0,0,0)
-ret 
-// Approximately 9 instruction slots used
-#endif
-
-const BYTE g_PS_PassthroughR2DUI[] =
-{
-     68,  88,  66,  67,   4,  26, 
-     62, 109,  94,  45, 124, 238, 
-    150, 245,  85, 155, 185,  37, 
-    234, 152,   1,   0,   0,   0, 
-    208,   2,   0,   0,   5,   0, 
-      0,   0,  52,   0,   0,   0, 
-    180,   0,   0,   0,  12,   1, 
-      0,   0,  64,   1,   0,   0, 
-     84,   2,   0,   0,  82,  68, 
-     69,  70, 120,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   1,   0,   0,   0, 
-     28,   0,   0,   0,   0,   4, 
-    255, 255,   0,   1,   0,   0, 
-     70,   0,   0,   0,  60,   0, 
-      0,   0,   2,   0,   0,   0, 
-      4,   0,   0,   0,   4,   0, 
-      0,   0, 255, 255, 255, 255, 
-      0,   0,   0,   0,   1,   0, 
-      0,   0,  13,   0,   0,   0, 
-     84, 101, 120, 116, 117, 114, 
-    101,  85,  73,   0,  77, 105, 
-     99, 114, 111, 115, 111, 102, 
-    116,  32,  40,  82,  41,  32, 
-     72,  76,  83,  76,  32,  83, 
-    104,  97, 100, 101, 114,  32, 
-     67, 111, 109, 112, 105, 108, 
-    101, 114,  32,  54,  46,  51, 
-     46,  57,  54,  48,  48,  46, 
-     49,  54,  51,  56,  52,   0, 
-     73,  83,  71,  78,  80,   0, 
-      0,   0,   2,   0,   0,   0, 
-      8,   0,   0,   0,  56,   0, 
-      0,   0,   0,   0,   0,   0, 
-      1,   0,   0,   0,   3,   0, 
-      0,   0,   0,   0,   0,   0, 
-     15,   0,   0,   0,  68,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   3,   0, 
-      0,   0,   1,   0,   0,   0, 
-      3,   3,   0,   0,  83,  86, 
-     95,  80,  79,  83,  73,  84, 
-     73,  79,  78,   0,  84,  69, 
-     88,  67,  79,  79,  82,  68, 
-      0, 171, 171, 171,  79,  83, 
-     71,  78,  44,   0,   0,   0, 
-      1,   0,   0,   0,   8,   0, 
-      0,   0,  32,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   1,   0,   0,   0, 
-      0,   0,   0,   0,  15,   0, 
-      0,   0,  83,  86,  95,  84, 
-     65,  82,  71,  69,  84,   0, 
-    171, 171,  83,  72,  68,  82, 
-     12,   1,   0,   0,  64,   0, 
-      0,   0,  67,   0,   0,   0, 
-     88,  24,   0,   4,   0, 112, 
-     16,   0,   0,   0,   0,   0, 
-     68,  68,   0,   0,  98,  16, 
-      0,   3,  50,  16,  16,   0, 
-      1,   0,   0,   0, 101,   0, 
-      0,   3, 242,  32,  16,   0, 
-      0,   0,   0,   0, 104,   0, 
-      0,   2,   1,   0,   0,   0, 
-     61,  16,   0,   7, 242,   0, 
-     16,   0,   0,   0,   0,   0, 
-      1,  64,   0,   0,   0,   0, 
-      0,   0,  70, 126,  16,   0, 
-      0,   0,   0,   0,  86,   0, 
-      0,   5,  50,   0,  16,   0, 
-      0,   0,   0,   0,  70,   0, 
-     16,   0,   0,   0,   0,   0, 
-     56,   0,   0,   7,  50,   0, 
-     16,   0,   0,   0,   0,   0, 
-     70,   0,  16,   0,   0,   0, 
-      0,   0,  70,  16,  16,   0, 
-      1,   0,   0,   0,  27,   0, 
-      0,   5,  50,   0,  16,   0, 
-      0,   0,   0,   0,  70,   0, 
-     16,   0,   0,   0,   0,   0, 
-     54,   0,   0,   8, 194,   0, 
-     16,   0,   0,   0,   0,   0, 
-      2,  64,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,  45,   0,   0,   7, 
-    242,   0,  16,   0,   0,   0, 
-      0,   0,  70,  14,  16,   0, 
-      0,   0,   0,   0,  70, 126, 
-     16,   0,   0,   0,   0,   0, 
-     54,   0,   0,   5,  18,  32, 
-     16,   0,   0,   0,   0,   0, 
-     10,   0,  16,   0,   0,   0, 
-      0,   0,  54,   0,   0,   8, 
-    226,  32,  16,   0,   0,   0, 
-      0,   0,   2,  64,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,  62,   0, 
-      0,   1,  83,  84,  65,  84, 
-    116,   0,   0,   0,   9,   0, 
-      0,   0,   1,   0,   0,   0, 
-      0,   0,   0,   0,   2,   0, 
-      0,   0,   1,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   1,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   1,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   3,   0,   0,   0, 
-      0,   0,   0,   0,   2,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0
-};
+#if 0
+//
+// Generated by Microsoft (R) HLSL Shader Compiler 6.3.9600.16384
+//
+//
+// Resource Bindings:
+//
+// Name                                 Type  Format         Dim Slot Elements
+// ------------------------------ ---------- ------- ----------- ---- --------
+// TextureUI                         texture   uint4          2d    0        1
+//
+//
+//
+// Input signature:
+//
+// Name                 Index   Mask Register SysValue  Format   Used
+// -------------------- ----- ------ -------- -------- ------- ------
+// SV_POSITION              0   xyzw        0      POS   float       
+// TEXCOORD                 0   xy          1     NONE   float   xy  
+//
+//
+// Output signature:
+//
+// Name                 Index   Mask Register SysValue  Format   Used
+// -------------------- ----- ------ -------- -------- ------- ------
+// SV_TARGET                0   xyzw        0   TARGET    uint   xyzw
+//
+ps_4_0
+dcl_resource_texture2d (uint,uint,uint,uint) t0
+dcl_input_ps linear v1.xy
+dcl_output o0.xyzw
+dcl_temps 1
+resinfo_uint r0.xyzw, l(0), t0.xyzw
+utof r0.xy, r0.xyxx
+mul r0.xy, r0.xyxx, v1.xyxx
+ftoi r0.xy, r0.xyxx
+mov r0.zw, l(0,0,0,0)
+ld r0.xyzw, r0.xyzw, t0.xyzw
+mov o0.x, r0.x
+mov o0.yzw, l(0,0,0,0)
+ret 
+// Approximately 9 instruction slots used
+#endif
+
+const BYTE g_PS_PassthroughR2DUI[] =
+{
+     68,  88,  66,  67,   4,  26, 
+     62, 109,  94,  45, 124, 238, 
+    150, 245,  85, 155, 185,  37, 
+    234, 152,   1,   0,   0,   0, 
+    208,   2,   0,   0,   5,   0, 
+      0,   0,  52,   0,   0,   0, 
+    180,   0,   0,   0,  12,   1, 
+      0,   0,  64,   1,   0,   0, 
+     84,   2,   0,   0,  82,  68, 
+     69,  70, 120,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   1,   0,   0,   0, 
+     28,   0,   0,   0,   0,   4, 
+    255, 255,   0,   1,   0,   0, 
+     70,   0,   0,   0,  60,   0, 
+      0,   0,   2,   0,   0,   0, 
+      4,   0,   0,   0,   4,   0, 
+      0,   0, 255, 255, 255, 255, 
+      0,   0,   0,   0,   1,   0, 
+      0,   0,  13,   0,   0,   0, 
+     84, 101, 120, 116, 117, 114, 
+    101,  85,  73,   0,  77, 105, 
+     99, 114, 111, 115, 111, 102, 
+    116,  32,  40,  82,  41,  32, 
+     72,  76,  83,  76,  32,  83, 
+    104,  97, 100, 101, 114,  32, 
+     67, 111, 109, 112, 105, 108, 
+    101, 114,  32,  54,  46,  51, 
+     46,  57,  54,  48,  48,  46, 
+     49,  54,  51,  56,  52,   0, 
+     73,  83,  71,  78,  80,   0, 
+      0,   0,   2,   0,   0,   0, 
+      8,   0,   0,   0,  56,   0, 
+      0,   0,   0,   0,   0,   0, 
+      1,   0,   0,   0,   3,   0, 
+      0,   0,   0,   0,   0,   0, 
+     15,   0,   0,   0,  68,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   3,   0, 
+      0,   0,   1,   0,   0,   0, 
+      3,   3,   0,   0,  83,  86, 
+     95,  80,  79,  83,  73,  84, 
+     73,  79,  78,   0,  84,  69, 
+     88,  67,  79,  79,  82,  68, 
+      0, 171, 171, 171,  79,  83, 
+     71,  78,  44,   0,   0,   0, 
+      1,   0,   0,   0,   8,   0, 
+      0,   0,  32,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   1,   0,   0,   0, 
+      0,   0,   0,   0,  15,   0, 
+      0,   0,  83,  86,  95,  84, 
+     65,  82,  71,  69,  84,   0, 
+    171, 171,  83,  72,  68,  82, 
+     12,   1,   0,   0,  64,   0, 
+      0,   0,  67,   0,   0,   0, 
+     88,  24,   0,   4,   0, 112, 
+     16,   0,   0,   0,   0,   0, 
+     68,  68,   0,   0,  98,  16, 
+      0,   3,  50,  16,  16,   0, 
+      1,   0,   0,   0, 101,   0, 
+      0,   3, 242,  32,  16,   0, 
+      0,   0,   0,   0, 104,   0, 
+      0,   2,   1,   0,   0,   0, 
+     61,  16,   0,   7, 242,   0, 
+     16,   0,   0,   0,   0,   0, 
+      1,  64,   0,   0,   0,   0, 
+      0,   0,  70, 126,  16,   0, 
+      0,   0,   0,   0,  86,   0, 
+      0,   5,  50,   0,  16,   0, 
+      0,   0,   0,   0,  70,   0, 
+     16,   0,   0,   0,   0,   0, 
+     56,   0,   0,   7,  50,   0, 
+     16,   0,   0,   0,   0,   0, 
+     70,   0,  16,   0,   0,   0, 
+      0,   0,  70,  16,  16,   0, 
+      1,   0,   0,   0,  27,   0, 
+      0,   5,  50,   0,  16,   0, 
+      0,   0,   0,   0,  70,   0, 
+     16,   0,   0,   0,   0,   0, 
+     54,   0,   0,   8, 194,   0, 
+     16,   0,   0,   0,   0,   0, 
+      2,  64,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,  45,   0,   0,   7, 
+    242,   0,  16,   0,   0,   0, 
+      0,   0,  70,  14,  16,   0, 
+      0,   0,   0,   0,  70, 126, 
+     16,   0,   0,   0,   0,   0, 
+     54,   0,   0,   5,  18,  32, 
+     16,   0,   0,   0,   0,   0, 
+     10,   0,  16,   0,   0,   0, 
+      0,   0,  54,   0,   0,   8, 
+    226,  32,  16,   0,   0,   0, 
+      0,   0,   2,  64,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,  62,   0, 
+      0,   1,  83,  84,  65,  84, 
+    116,   0,   0,   0,   9,   0, 
+      0,   0,   1,   0,   0,   0, 
+      0,   0,   0,   0,   2,   0, 
+      0,   0,   1,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   1,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   1,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   3,   0,   0,   0, 
+      0,   0,   0,   0,   2,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0
+};
--- a/gfx/angle/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughr3d11ps.h
+++ b/gfx/angle/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughr3d11ps.h
@@ -1,162 +1,162 @@
-#if 0
-//
-// Generated by Microsoft (R) HLSL Shader Compiler 6.3.9600.16384
-//
-//
-// Resource Bindings:
-//
-// Name                                 Type  Format         Dim Slot Elements
-// ------------------------------ ---------- ------- ----------- ---- --------
-// Sampler                           sampler      NA          NA    0        1
-// TextureF                          texture  float4          3d    0        1
-//
-//
-//
-// Input signature:
-//
-// Name                 Index   Mask Register SysValue  Format   Used
-// -------------------- ----- ------ -------- -------- ------- ------
-// SV_POSITION              0   xyzw        0      POS   float       
-// SV_RENDERTARGETARRAYINDEX     0   x           1  RTINDEX    uint       
-// TEXCOORD                 0   xyz         2     NONE   float   xyz 
-//
-//
-// Output signature:
-//
-// Name                 Index   Mask Register SysValue  Format   Used
-// -------------------- ----- ------ -------- -------- ------- ------
-// SV_TARGET                0   xyzw        0   TARGET   float   xyzw
-//
-ps_4_0
-dcl_sampler s0, mode_default
-dcl_resource_texture3d (float,float,float,float) t0
-dcl_input_ps linear v2.xyz
-dcl_output o0.xyzw
-dcl_temps 1
-sample r0.xyzw, v2.xyzx, t0.xyzw, s0
-mov o0.x, r0.x
-mov o0.yzw, l(0,0,0,1.000000)
-ret 
-// Approximately 4 instruction slots used
-#endif
-
-const BYTE g_PS_PassthroughR3D[] =
-{
-     68,  88,  66,  67,  11, 235, 
-    208, 143, 219, 183, 141,  78, 
-    136, 182,  62, 182, 243,  12, 
-    239, 125,   1,   0,   0,   0, 
-    188,   2,   0,   0,   5,   0, 
-      0,   0,  52,   0,   0,   0, 
-    220,   0,   0,   0, 100,   1, 
-      0,   0, 152,   1,   0,   0, 
-     64,   2,   0,   0,  82,  68, 
-     69,  70, 160,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   2,   0,   0,   0, 
-     28,   0,   0,   0,   0,   4, 
-    255, 255,   0,   1,   0,   0, 
-    109,   0,   0,   0,  92,   0, 
-      0,   0,   3,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   1,   0, 
-      0,   0,   1,   0,   0,   0, 
-    100,   0,   0,   0,   2,   0, 
-      0,   0,   5,   0,   0,   0, 
-      8,   0,   0,   0, 255, 255, 
-    255, 255,   0,   0,   0,   0, 
-      1,   0,   0,   0,  13,   0, 
-      0,   0,  83,  97, 109, 112, 
-    108, 101, 114,   0,  84, 101, 
-    120, 116, 117, 114, 101,  70, 
-      0,  77, 105,  99, 114, 111, 
-    115, 111, 102, 116,  32,  40, 
-     82,  41,  32,  72,  76,  83, 
-     76,  32,  83, 104,  97, 100, 
-    101, 114,  32,  67, 111, 109, 
-    112, 105, 108, 101, 114,  32, 
-     54,  46,  51,  46,  57,  54, 
-     48,  48,  46,  49,  54,  51, 
-     56,  52,   0, 171,  73,  83, 
-     71,  78, 128,   0,   0,   0, 
-      3,   0,   0,   0,   8,   0, 
-      0,   0,  80,   0,   0,   0, 
-      0,   0,   0,   0,   1,   0, 
-      0,   0,   3,   0,   0,   0, 
-      0,   0,   0,   0,  15,   0, 
-      0,   0,  92,   0,   0,   0, 
-      0,   0,   0,   0,   4,   0, 
-      0,   0,   1,   0,   0,   0, 
-      1,   0,   0,   0,   1,   0, 
-      0,   0, 118,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   3,   0,   0,   0, 
-      2,   0,   0,   0,   7,   7, 
-      0,   0,  83,  86,  95,  80, 
-     79,  83,  73,  84,  73,  79, 
-     78,   0,  83,  86,  95,  82, 
-     69,  78,  68,  69,  82,  84, 
-     65,  82,  71,  69,  84,  65, 
-     82,  82,  65,  89,  73,  78, 
-     68,  69,  88,   0,  84,  69, 
-     88,  67,  79,  79,  82,  68, 
-      0, 171,  79,  83,  71,  78, 
-     44,   0,   0,   0,   1,   0, 
-      0,   0,   8,   0,   0,   0, 
-     32,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      3,   0,   0,   0,   0,   0, 
-      0,   0,  15,   0,   0,   0, 
-     83,  86,  95,  84,  65,  82, 
-     71,  69,  84,   0, 171, 171, 
-     83,  72,  68,  82, 160,   0, 
-      0,   0,  64,   0,   0,   0, 
-     40,   0,   0,   0,  90,   0, 
-      0,   3,   0,  96,  16,   0, 
-      0,   0,   0,   0,  88,  40, 
-      0,   4,   0, 112,  16,   0, 
-      0,   0,   0,   0,  85,  85, 
-      0,   0,  98,  16,   0,   3, 
-    114,  16,  16,   0,   2,   0, 
-      0,   0, 101,   0,   0,   3, 
-    242,  32,  16,   0,   0,   0, 
-      0,   0, 104,   0,   0,   2, 
-      1,   0,   0,   0,  69,   0, 
-      0,   9, 242,   0,  16,   0, 
-      0,   0,   0,   0,  70,  18, 
-     16,   0,   2,   0,   0,   0, 
-     70, 126,  16,   0,   0,   0, 
-      0,   0,   0,  96,  16,   0, 
-      0,   0,   0,   0,  54,   0, 
-      0,   5,  18,  32,  16,   0, 
-      0,   0,   0,   0,  10,   0, 
-     16,   0,   0,   0,   0,   0, 
-     54,   0,   0,   8, 226,  32, 
-     16,   0,   0,   0,   0,   0, 
-      2,  64,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-    128,  63,  62,   0,   0,   1, 
-     83,  84,  65,  84, 116,   0, 
-      0,   0,   4,   0,   0,   0, 
-      1,   0,   0,   0,   0,   0, 
-      0,   0,   2,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      1,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   1,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      2,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0
-};
+#if 0
+//
+// Generated by Microsoft (R) HLSL Shader Compiler 6.3.9600.16384
+//
+//
+// Resource Bindings:
+//
+// Name                                 Type  Format         Dim Slot Elements
+// ------------------------------ ---------- ------- ----------- ---- --------
+// Sampler                           sampler      NA          NA    0        1
+// TextureF                          texture  float4          3d    0        1
+//
+//
+//
+// Input signature:
+//
+// Name                 Index   Mask Register SysValue  Format   Used
+// -------------------- ----- ------ -------- -------- ------- ------
+// SV_POSITION              0   xyzw        0      POS   float       
+// SV_RENDERTARGETARRAYINDEX     0   x           1  RTINDEX    uint       
+// TEXCOORD                 0   xyz         2     NONE   float   xyz 
+//
+//
+// Output signature:
+//
+// Name                 Index   Mask Register SysValue  Format   Used
+// -------------------- ----- ------ -------- -------- ------- ------
+// SV_TARGET                0   xyzw        0   TARGET   float   xyzw
+//
+ps_4_0
+dcl_sampler s0, mode_default
+dcl_resource_texture3d (float,float,float,float) t0
+dcl_input_ps linear v2.xyz
+dcl_output o0.xyzw
+dcl_temps 1
+sample r0.xyzw, v2.xyzx, t0.xyzw, s0
+mov o0.x, r0.x
+mov o0.yzw, l(0,0,0,1.000000)
+ret 
+// Approximately 4 instruction slots used
+#endif
+
+const BYTE g_PS_PassthroughR3D[] =
+{
+     68,  88,  66,  67,  11, 235, 
+    208, 143, 219, 183, 141,  78, 
+    136, 182,  62, 182, 243,  12, 
+    239, 125,   1,   0,   0,   0, 
+    188,   2,   0,   0,   5,   0, 
+      0,   0,  52,   0,   0,   0, 
+    220,   0,   0,   0, 100,   1, 
+      0,   0, 152,   1,   0,   0, 
+     64,   2,   0,   0,  82,  68, 
+     69,  70, 160,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   2,   0,   0,   0, 
+     28,   0,   0,   0,   0,   4, 
+    255, 255,   0,   1,   0,   0, 
+    109,   0,   0,   0,  92,   0, 
+      0,   0,   3,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   1,   0, 
+      0,   0,   1,   0,   0,   0, 
+    100,   0,   0,   0,   2,   0, 
+      0,   0,   5,   0,   0,   0, 
+      8,   0,   0,   0, 255, 255, 
+    255, 255,   0,   0,   0,   0, 
+      1,   0,   0,   0,  13,   0, 
+      0,   0,  83,  97, 109, 112, 
+    108, 101, 114,   0,  84, 101, 
+    120, 116, 117, 114, 101,  70, 
+      0,  77, 105,  99, 114, 111, 
+    115, 111, 102, 116,  32,  40, 
+     82,  41,  32,  72,  76,  83, 
+     76,  32,  83, 104,  97, 100, 
+    101, 114,  32,  67, 111, 109, 
+    112, 105, 108, 101, 114,  32, 
+     54,  46,  51,  46,  57,  54, 
+     48,  48,  46,  49,  54,  51, 
+     56,  52,   0, 171,  73,  83, 
+     71,  78, 128,   0,   0,   0, 
+      3,   0,   0,   0,   8,   0, 
+      0,   0,  80,   0,   0,   0, 
+      0,   0,   0,   0,   1,   0, 
+      0,   0,   3,   0,   0,   0, 
+      0,   0,   0,   0,  15,   0, 
+      0,   0,  92,   0,   0,   0, 
+      0,   0,   0,   0,   4,   0, 
+      0,   0,   1,   0,   0,   0, 
+      1,   0,   0,   0,   1,   0, 
+      0,   0, 118,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   3,   0,   0,   0, 
+      2,   0,   0,   0,   7,   7, 
+      0,   0,  83,  86,  95,  80, 
+     79,  83,  73,  84,  73,  79, 
+     78,   0,  83,  86,  95,  82, 
+     69,  78,  68,  69,  82,  84, 
+     65,  82,  71,  69,  84,  65, 
+     82,  82,  65,  89,  73,  78, 
+     68,  69,  88,   0,  84,  69, 
+     88,  67,  79,  79,  82,  68, 
+      0, 171,  79,  83,  71,  78, 
+     44,   0,   0,   0,   1,   0, 
+      0,   0,   8,   0,   0,   0, 
+     32,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      3,   0,   0,   0,   0,   0, 
+      0,   0,  15,   0,   0,   0, 
+     83,  86,  95,  84,  65,  82, 
+     71,  69,  84,   0, 171, 171, 
+     83,  72,  68,  82, 160,   0, 
+      0,   0,  64,   0,   0,   0, 
+     40,   0,   0,   0,  90,   0, 
+      0,   3,   0,  96,  16,   0, 
+      0,   0,   0,   0,  88,  40, 
+      0,   4,   0, 112,  16,   0, 
+      0,   0,   0,   0,  85,  85, 
+      0,   0,  98,  16,   0,   3, 
+    114,  16,  16,   0,   2,   0, 
+      0,   0, 101,   0,   0,   3, 
+    242,  32,  16,   0,   0,   0, 
+      0,   0, 104,   0,   0,   2, 
+      1,   0,   0,   0,  69,   0, 
+      0,   9, 242,   0,  16,   0, 
+      0,   0,   0,   0,  70,  18, 
+     16,   0,   2,   0,   0,   0, 
+     70, 126,  16,   0,   0,   0, 
+      0,   0,   0,  96,  16,   0, 
+      0,   0,   0,   0,  54,   0, 
+      0,   5,  18,  32,  16,   0, 
+      0,   0,   0,   0,  10,   0, 
+     16,   0,   0,   0,   0,   0, 
+     54,   0,   0,   8, 226,  32, 
+     16,   0,   0,   0,   0,   0, 
+      2,  64,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+    128,  63,  62,   0,   0,   1, 
+     83,  84,  65,  84, 116,   0, 
+      0,   0,   4,   0,   0,   0, 
+      1,   0,   0,   0,   0,   0, 
+      0,   0,   2,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      1,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   1,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      2,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0
+};
--- a/gfx/angle/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughr3di11ps.h
+++ b/gfx/angle/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughr3di11ps.h
@@ -1,174 +1,174 @@
-#if 0
-//
-// Generated by Microsoft (R) HLSL Shader Compiler 6.3.9600.16384
-//
-//
-// Resource Bindings:
-//
-// Name                                 Type  Format         Dim Slot Elements
-// ------------------------------ ---------- ------- ----------- ---- --------
-// TextureI                          texture   sint4          3d    0        1
-//
-//
-//
-// Input signature:
-//
-// Name                 Index   Mask Register SysValue  Format   Used
-// -------------------- ----- ------ -------- -------- ------- ------
-// SV_POSITION              0   xyzw        0      POS   float       
-// SV_RENDERTARGETARRAYINDEX     0   x           1  RTINDEX    uint       
-// TEXCOORD                 0   xyz         2     NONE   float   xyz 
-//
-//
-// Output signature:
-//
-// Name                 Index   Mask Register SysValue  Format   Used
-// -------------------- ----- ------ -------- -------- ------- ------
-// SV_TARGET                0   xyzw        0   TARGET     int   xyzw
-//
-ps_4_0
-dcl_resource_texture3d (sint,sint,sint,sint) t0
-dcl_input_ps linear v2.xyz
-dcl_output o0.xyzw
-dcl_temps 1
-resinfo_uint r0.xyzw, l(0), t0.xyzw
-utof r0.xyz, r0.xyzx
-mul r0.xyz, r0.xyzx, v2.xyzx
-ftoi r0.xyz, r0.xyzx
-mov r0.w, l(0)
-ld r0.xyzw, r0.xyzw, t0.xyzw
-mov o0.x, r0.x
-mov o0.yzw, l(0,0,0,0)
-ret 
-// Approximately 9 instruction slots used
-#endif
-
-const BYTE g_PS_PassthroughR3DI[] =
-{
-     68,  88,  66,  67, 222, 251, 
-     30,  61,  15,  80,  81, 247, 
-    175, 137,  44,  19,  23,  84, 
-    149, 211,   1,   0,   0,   0, 
-    244,   2,   0,   0,   5,   0, 
-      0,   0,  52,   0,   0,   0, 
-    180,   0,   0,   0,  60,   1, 
-      0,   0, 112,   1,   0,   0, 
-    120,   2,   0,   0,  82,  68, 
-     69,  70, 120,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   1,   0,   0,   0, 
-     28,   0,   0,   0,   0,   4, 
-    255, 255,   0,   1,   0,   0, 
-     69,   0,   0,   0,  60,   0, 
-      0,   0,   2,   0,   0,   0, 
-      3,   0,   0,   0,   8,   0, 
-      0,   0, 255, 255, 255, 255, 
-      0,   0,   0,   0,   1,   0, 
-      0,   0,  13,   0,   0,   0, 
-     84, 101, 120, 116, 117, 114, 
-    101,  73,   0,  77, 105,  99, 
-    114, 111, 115, 111, 102, 116, 
-     32,  40,  82,  41,  32,  72, 
-     76,  83,  76,  32,  83, 104, 
-     97, 100, 101, 114,  32,  67, 
-    111, 109, 112, 105, 108, 101, 
-    114,  32,  54,  46,  51,  46, 
-     57,  54,  48,  48,  46,  49, 
-     54,  51,  56,  52,   0, 171, 
-     73,  83,  71,  78, 128,   0, 
-      0,   0,   3,   0,   0,   0, 
-      8,   0,   0,   0,  80,   0, 
-      0,   0,   0,   0,   0,   0, 
-      1,   0,   0,   0,   3,   0, 
-      0,   0,   0,   0,   0,   0, 
-     15,   0,   0,   0,  92,   0, 
-      0,   0,   0,   0,   0,   0, 
-      4,   0,   0,   0,   1,   0, 
-      0,   0,   1,   0,   0,   0, 
-      1,   0,   0,   0, 118,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   3,   0, 
-      0,   0,   2,   0,   0,   0, 
-      7,   7,   0,   0,  83,  86, 
-     95,  80,  79,  83,  73,  84, 
-     73,  79,  78,   0,  83,  86, 
-     95,  82,  69,  78,  68,  69, 
-     82,  84,  65,  82,  71,  69, 
-     84,  65,  82,  82,  65,  89, 
-     73,  78,  68,  69,  88,   0, 
-     84,  69,  88,  67,  79,  79, 
-     82,  68,   0, 171,  79,  83, 
-     71,  78,  44,   0,   0,   0, 
-      1,   0,   0,   0,   8,   0, 
-      0,   0,  32,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   2,   0,   0,   0, 
-      0,   0,   0,   0,  15,   0, 
-      0,   0,  83,  86,  95,  84, 
-     65,  82,  71,  69,  84,   0, 
-    171, 171,  83,  72,  68,  82, 
-      0,   1,   0,   0,  64,   0, 
-      0,   0,  64,   0,   0,   0, 
-     88,  40,   0,   4,   0, 112, 
-     16,   0,   0,   0,   0,   0, 
-     51,  51,   0,   0,  98,  16, 
-      0,   3, 114,  16,  16,   0, 
-      2,   0,   0,   0, 101,   0, 
-      0,   3, 242,  32,  16,   0, 
-      0,   0,   0,   0, 104,   0, 
-      0,   2,   1,   0,   0,   0, 
-     61,  16,   0,   7, 242,   0, 
-     16,   0,   0,   0,   0,   0, 
-      1,  64,   0,   0,   0,   0, 
-      0,   0,  70, 126,  16,   0, 
-      0,   0,   0,   0,  86,   0, 
-      0,   5, 114,   0,  16,   0, 
-      0,   0,   0,   0,  70,   2, 
-     16,   0,   0,   0,   0,   0, 
-     56,   0,   0,   7, 114,   0, 
-     16,   0,   0,   0,   0,   0, 
-     70,   2,  16,   0,   0,   0, 
-      0,   0,  70,  18,  16,   0, 
-      2,   0,   0,   0,  27,   0, 
-      0,   5, 114,   0,  16,   0, 
-      0,   0,   0,   0,  70,   2, 
-     16,   0,   0,   0,   0,   0, 
-     54,   0,   0,   5, 130,   0, 
-     16,   0,   0,   0,   0,   0, 
-      1,  64,   0,   0,   0,   0, 
-      0,   0,  45,   0,   0,   7, 
-    242,   0,  16,   0,   0,   0, 
-      0,   0,  70,  14,  16,   0, 
-      0,   0,   0,   0,  70, 126, 
-     16,   0,   0,   0,   0,   0, 
-     54,   0,   0,   5,  18,  32, 
-     16,   0,   0,   0,   0,   0, 
-     10,   0,  16,   0,   0,   0, 
-      0,   0,  54,   0,   0,   8, 
-    226,  32,  16,   0,   0,   0, 
-      0,   0,   2,  64,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,  62,   0, 
-      0,   1,  83,  84,  65,  84, 
-    116,   0,   0,   0,   9,   0, 
-      0,   0,   1,   0,   0,   0, 
-      0,   0,   0,   0,   2,   0, 
-      0,   0,   1,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   1,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   1,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   3,   0,   0,   0, 
-      0,   0,   0,   0,   2,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0
-};
+#if 0
+//
+// Generated by Microsoft (R) HLSL Shader Compiler 6.3.9600.16384
+//
+//
+// Resource Bindings:
+//
+// Name                                 Type  Format         Dim Slot Elements
+// ------------------------------ ---------- ------- ----------- ---- --------
+// TextureI                          texture   sint4          3d    0        1
+//
+//
+//
+// Input signature:
+//
+// Name                 Index   Mask Register SysValue  Format   Used
+// -------------------- ----- ------ -------- -------- ------- ------
+// SV_POSITION              0   xyzw        0      POS   float       
+// SV_RENDERTARGETARRAYINDEX     0   x           1  RTINDEX    uint       
+// TEXCOORD                 0   xyz         2     NONE   float   xyz 
+//
+//
+// Output signature:
+//
+// Name                 Index   Mask Register SysValue  Format   Used
+// -------------------- ----- ------ -------- -------- ------- ------
+// SV_TARGET                0   xyzw        0   TARGET     int   xyzw
+//
+ps_4_0
+dcl_resource_texture3d (sint,sint,sint,sint) t0
+dcl_input_ps linear v2.xyz
+dcl_output o0.xyzw
+dcl_temps 1
+resinfo_uint r0.xyzw, l(0), t0.xyzw
+utof r0.xyz, r0.xyzx
+mul r0.xyz, r0.xyzx, v2.xyzx
+ftoi r0.xyz, r0.xyzx
+mov r0.w, l(0)
+ld r0.xyzw, r0.xyzw, t0.xyzw
+mov o0.x, r0.x
+mov o0.yzw, l(0,0,0,0)
+ret 
+// Approximately 9 instruction slots used
+#endif
+
+const BYTE g_PS_PassthroughR3DI[] =
+{
+     68,  88,  66,  67, 222, 251, 
+     30,  61,  15,  80,  81, 247, 
+    175, 137,  44,  19,  23,  84, 
+    149, 211,   1,   0,   0,   0, 
+    244,   2,   0,   0,   5,   0, 
+      0,   0,  52,   0,   0,   0, 
+    180,   0,   0,   0,  60,   1, 
+      0,   0, 112,   1,   0,   0, 
+    120,   2,   0,   0,  82,  68, 
+     69,  70, 120,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   1,   0,   0,   0, 
+     28,   0,   0,   0,   0,   4, 
+    255, 255,   0,   1,   0,   0, 
+     69,   0,   0,   0,  60,   0, 
+      0,   0,   2,   0,   0,   0, 
+      3,   0,   0,   0,   8,   0, 
+      0,   0, 255, 255, 255, 255, 
+      0,   0,   0,   0,   1,   0, 
+      0,   0,  13,   0,   0,   0, 
+     84, 101, 120, 116, 117, 114, 
+    101,  73,   0,  77, 105,  99, 
+    114, 111, 115, 111, 102, 116, 
+     32,  40,  82,  41,  32,  72, 
+     76,  83,  76,  32,  83, 104, 
+     97, 100, 101, 114,  32,  67, 
+    111, 109, 112, 105, 108, 101, 
+    114,  32,  54,  46,  51,  46, 
+     57,  54,  48,  48,  46,  49, 
+     54,  51,  56,  52,   0, 171, 
+     73,  83,  71,  78, 128,   0, 
+      0,   0,   3,   0,   0,   0, 
+      8,   0,   0,   0,  80,   0, 
+      0,   0,   0,   0,   0,   0, 
+      1,   0,   0,   0,   3,   0, 
+      0,   0,   0,   0,   0,   0, 
+     15,   0,   0,   0,  92,   0, 
+      0,   0,   0,   0,   0,   0, 
+      4,   0,   0,   0,   1,   0, 
+      0,   0,   1,   0,   0,   0, 
+      1,   0,   0,   0, 118,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   3,   0, 
+      0,   0,   2,   0,   0,   0, 
+      7,   7,   0,   0,  83,  86, 
+     95,  80,  79,  83,  73,  84, 
+     73,  79,  78,   0,  83,  86, 
+     95,  82,  69,  78,  68,  69, 
+     82,  84,  65,  82,  71,  69, 
+     84,  65,  82,  82,  65,  89, 
+     73,  78,  68,  69,  88,   0, 
+     84,  69,  88,  67,  79,  79, 
+     82,  68,   0, 171,  79,  83, 
+     71,  78,  44,   0,   0,   0, 
+      1,   0,   0,   0,   8,   0, 
+      0,   0,  32,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   2,   0,   0,   0, 
+      0,   0,   0,   0,  15,   0, 
+      0,   0,  83,  86,  95,  84, 
+     65,  82,  71,  69,  84,   0, 
+    171, 171,  83,  72,  68,  82, 
+      0,   1,   0,   0,  64,   0, 
+      0,   0,  64,   0,   0,   0, 
+     88,  40,   0,   4,   0, 112, 
+     16,   0,   0,   0,   0,   0, 
+     51,  51,   0,   0,  98,  16, 
+      0,   3, 114,  16,  16,   0, 
+      2,   0,   0,   0, 101,   0, 
+      0,   3, 242,  32,  16,   0, 
+      0,   0,   0,   0, 104,   0, 
+      0,   2,   1,   0,   0,   0, 
+     61,  16,   0,   7, 242,   0, 
+     16,   0,   0,   0,   0,   0, 
+      1,  64,   0,   0,   0,   0, 
+      0,   0,  70, 126,  16,   0, 
+      0,   0,   0,   0,  86,   0, 
+      0,   5, 114,   0,  16,   0, 
+      0,   0,   0,   0,  70,   2, 
+     16,   0,   0,   0,   0,   0, 
+     56,   0,   0,   7, 114,   0, 
+     16,   0,   0,   0,   0,   0, 
+     70,   2,  16,   0,   0,   0, 
+      0,   0,  70,  18,  16,   0, 
+      2,   0,   0,   0,  27,   0, 
+      0,   5, 114,   0,  16,   0, 
+      0,   0,   0,   0,  70,   2, 
+     16,   0,   0,   0,   0,   0, 
+     54,   0,   0,   5, 130,   0, 
+     16,   0,   0,   0,   0,   0, 
+      1,  64,   0,   0,   0,   0, 
+      0,   0,  45,   0,   0,   7, 
+    242,   0,  16,   0,   0,   0, 
+      0,   0,  70,  14,  16,   0, 
+      0,   0,   0,   0,  70, 126, 
+     16,   0,   0,   0,   0,   0, 
+     54,   0,   0,   5,  18,  32, 
+     16,   0,   0,   0,   0,   0, 
+     10,   0,  16,   0,   0,   0, 
+      0,   0,  54,   0,   0,   8, 
+    226,  32,  16,   0,   0,   0, 
+      0,   0,   2,  64,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,  62,   0, 
+      0,   1,  83,  84,  65,  84, 
+    116,   0,   0,   0,   9,   0, 
+      0,   0,   1,   0,   0,   0, 
+      0,   0,   0,   0,   2,   0, 
+      0,   0,   1,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   1,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   1,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   3,   0,   0,   0, 
+      0,   0,   0,   0,   2,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0
+};
--- a/gfx/angle/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughr3dui11ps.h
+++ b/gfx/angle/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughr3dui11ps.h
@@ -1,174 +1,174 @@
-#if 0
-//
-// Generated by Microsoft (R) HLSL Shader Compiler 6.3.9600.16384
-//
-//
-// Resource Bindings:
-//
-// Name                                 Type  Format         Dim Slot Elements
-// ------------------------------ ---------- ------- ----------- ---- --------
-// TextureUI                         texture   uint4          3d    0        1
-//
-//
-//
-// Input signature:
-//
-// Name                 Index   Mask Register SysValue  Format   Used
-// -------------------- ----- ------ -------- -------- ------- ------
-// SV_POSITION              0   xyzw        0      POS   float       
-// SV_RENDERTARGETARRAYINDEX     0   x           1  RTINDEX    uint       
-// TEXCOORD                 0   xyz         2     NONE   float   xyz 
-//
-//
-// Output signature:
-//
-// Name                 Index   Mask Register SysValue  Format   Used
-// -------------------- ----- ------ -------- -------- ------- ------
-// SV_TARGET                0   xyzw        0   TARGET    uint   xyzw
-//
-ps_4_0
-dcl_resource_texture3d (uint,uint,uint,uint) t0
-dcl_input_ps linear v2.xyz
-dcl_output o0.xyzw
-dcl_temps 1
-resinfo_uint r0.xyzw, l(0), t0.xyzw
-utof r0.xyz, r0.xyzx
-mul r0.xyz, r0.xyzx, v2.xyzx
-ftoi r0.xyz, r0.xyzx
-mov r0.w, l(0)
-ld r0.xyzw, r0.xyzw, t0.xyzw
-mov o0.x, r0.x
-mov o0.yzw, l(0,0,0,0)
-ret 
-// Approximately 9 instruction slots used
-#endif
-
-const BYTE g_PS_PassthroughR3DUI[] =
-{
-     68,  88,  66,  67,  69,   5, 
-     86, 212, 201,  54,  97, 205, 
-     89, 161, 100,  72, 246, 114, 
-     40, 214,   1,   0,   0,   0, 
-    244,   2,   0,   0,   5,   0, 
-      0,   0,  52,   0,   0,   0, 
-    180,   0,   0,   0,  60,   1, 
-      0,   0, 112,   1,   0,   0, 
-    120,   2,   0,   0,  82,  68, 
-     69,  70, 120,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   1,   0,   0,   0, 
-     28,   0,   0,   0,   0,   4, 
-    255, 255,   0,   1,   0,   0, 
-     70,   0,   0,   0,  60,   0, 
-      0,   0,   2,   0,   0,   0, 
-      4,   0,   0,   0,   8,   0, 
-      0,   0, 255, 255, 255, 255, 
-      0,   0,   0,   0,   1,   0, 
-      0,   0,  13,   0,   0,   0, 
-     84, 101, 120, 116, 117, 114, 
-    101,  85,  73,   0,  77, 105, 
-     99, 114, 111, 115, 111, 102, 
-    116,  32,  40,  82,  41,  32, 
-     72,  76,  83,  76,  32,  83, 
-    104,  97, 100, 101, 114,  32, 
-     67, 111, 109, 112, 105, 108, 
-    101, 114,  32,  54,  46,  51, 
-     46,  57,  54,  48,  48,  46, 
-     49,  54,  51,  56,  52,   0, 
-     73,  83,  71,  78, 128,   0, 
-      0,   0,   3,   0,   0,   0, 
-      8,   0,   0,   0,  80,   0, 
-      0,   0,   0,   0,   0,   0, 
-      1,   0,   0,   0,   3,   0, 
-      0,   0,   0,   0,   0,   0, 
-     15,   0,   0,   0,  92,   0, 
-      0,   0,   0,   0,   0,   0, 
-      4,   0,   0,   0,   1,   0, 
-      0,   0,   1,   0,   0,   0, 
-      1,   0,   0,   0, 118,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   3,   0, 
-      0,   0,   2,   0,   0,   0, 
-      7,   7,   0,   0,  83,  86, 
-     95,  80,  79,  83,  73,  84, 
-     73,  79,  78,   0,  83,  86, 
-     95,  82,  69,  78,  68,  69, 
-     82,  84,  65,  82,  71,  69, 
-     84,  65,  82,  82,  65,  89, 
-     73,  78,  68,  69,  88,   0, 
-     84,  69,  88,  67,  79,  79, 
-     82,  68,   0, 171,  79,  83, 
-     71,  78,  44,   0,   0,   0, 
-      1,   0,   0,   0,   8,   0, 
-      0,   0,  32,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   1,   0,   0,   0, 
-      0,   0,   0,   0,  15,   0, 
-      0,   0,  83,  86,  95,  84, 
-     65,  82,  71,  69,  84,   0, 
-    171, 171,  83,  72,  68,  82, 
-      0,   1,   0,   0,  64,   0, 
-      0,   0,  64,   0,   0,   0, 
-     88,  40,   0,   4,   0, 112, 
-     16,   0,   0,   0,   0,   0, 
-     68,  68,   0,   0,  98,  16, 
-      0,   3, 114,  16,  16,   0, 
-      2,   0,   0,   0, 101,   0, 
-      0,   3, 242,  32,  16,   0, 
-      0,   0,   0,   0, 104,   0, 
-      0,   2,   1,   0,   0,   0, 
-     61,  16,   0,   7, 242,   0, 
-     16,   0,   0,   0,   0,   0, 
-      1,  64,   0,   0,   0,   0, 
-      0,   0,  70, 126,  16,   0, 
-      0,   0,   0,   0,  86,   0, 
-      0,   5, 114,   0,  16,   0, 
-      0,   0,   0,   0,  70,   2, 
-     16,   0,   0,   0,   0,   0, 
-     56,   0,   0,   7, 114,   0, 
-     16,   0,   0,   0,   0,   0, 
-     70,   2,  16,   0,   0,   0, 
-      0,   0,  70,  18,  16,   0, 
-      2,   0,   0,   0,  27,   0, 
-      0,   5, 114,   0,  16,   0, 
-      0,   0,   0,   0,  70,   2, 
-     16,   0,   0,   0,   0,   0, 
-     54,   0,   0,   5, 130,   0, 
-     16,   0,   0,   0,   0,   0, 
-      1,  64,   0,   0,   0,   0, 
-      0,   0,  45,   0,   0,   7, 
-    242,   0,  16,   0,   0,   0, 
-      0,   0,  70,  14,  16,   0, 
-      0,   0,   0,   0,  70, 126, 
-     16,   0,   0,   0,   0,   0, 
-     54,   0,   0,   5,  18,  32, 
-     16,   0,   0,   0,   0,   0, 
-     10,   0,  16,   0,   0,   0, 
-      0,   0,  54,   0,   0,   8, 
-    226,  32,  16,   0,   0,   0, 
-      0,   0,   2,  64,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,  62,   0, 
-      0,   1,  83,  84,  65,  84, 
-    116,   0,   0,   0,   9,   0, 
-      0,   0,   1,   0,   0,   0, 
-      0,   0,   0,   0,   2,   0, 
-      0,   0,   1,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   1,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   1,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   3,   0,   0,   0, 
-      0,   0,   0,   0,   2,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0
-};
+#if 0
+//
+// Generated by Microsoft (R) HLSL Shader Compiler 6.3.9600.16384
+//
+//
+// Resource Bindings:
+//
+// Name                                 Type  Format         Dim Slot Elements
+// ------------------------------ ---------- ------- ----------- ---- --------
+// TextureUI                         texture   uint4          3d    0        1
+//
+//
+//
+// Input signature:
+//
+// Name                 Index   Mask Register SysValue  Format   Used
+// -------------------- ----- ------ -------- -------- ------- ------
+// SV_POSITION              0   xyzw        0      POS   float       
+// SV_RENDERTARGETARRAYINDEX     0   x           1  RTINDEX    uint       
+// TEXCOORD                 0   xyz         2     NONE   float   xyz 
+//
+//
+// Output signature:
+//
+// Name                 Index   Mask Register SysValue  Format   Used
+// -------------------- ----- ------ -------- -------- ------- ------
+// SV_TARGET                0   xyzw        0   TARGET    uint   xyzw
+//
+ps_4_0
+dcl_resource_texture3d (uint,uint,uint,uint) t0
+dcl_input_ps linear v2.xyz
+dcl_output o0.xyzw
+dcl_temps 1
+resinfo_uint r0.xyzw, l(0), t0.xyzw
+utof r0.xyz, r0.xyzx
+mul r0.xyz, r0.xyzx, v2.xyzx
+ftoi r0.xyz, r0.xyzx
+mov r0.w, l(0)
+ld r0.xyzw, r0.xyzw, t0.xyzw
+mov o0.x, r0.x
+mov o0.yzw, l(0,0,0,0)
+ret 
+// Approximately 9 instruction slots used
+#endif
+
+const BYTE g_PS_PassthroughR3DUI[] =
+{
+     68,  88,  66,  67,  69,   5, 
+     86, 212, 201,  54,  97, 205, 
+     89, 161, 100,  72, 246, 114, 
+     40, 214,   1,   0,   0,   0, 
+    244,   2,   0,   0,   5,   0, 
+      0,   0,  52,   0,   0,   0, 
+    180,   0,   0,   0,  60,   1, 
+      0,   0, 112,   1,   0,   0, 
+    120,   2,   0,   0,  82,  68, 
+     69,  70, 120,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   1,   0,   0,   0, 
+     28,   0,   0,   0,   0,   4, 
+    255, 255,   0,   1,   0,   0, 
+     70,   0,   0,   0,  60,   0, 
+      0,   0,   2,   0,   0,   0, 
+      4,   0,   0,   0,   8,   0, 
+      0,   0, 255, 255, 255, 255, 
+      0,   0,   0,   0,   1,   0, 
+      0,   0,  13,   0,   0,   0, 
+     84, 101, 120, 116, 117, 114, 
+    101,  85,  73,   0,  77, 105, 
+     99, 114, 111, 115, 111, 102, 
+    116,  32,  40,  82,  41,  32, 
+     72,  76,  83,  76,  32,  83, 
+    104,  97, 100, 101, 114,  32, 
+     67, 111, 109, 112, 105, 108, 
+    101, 114,  32,  54,  46,  51, 
+     46,  57,  54,  48,  48,  46, 
+     49,  54,  51,  56,  52,   0, 
+     73,  83,  71,  78, 128,   0, 
+      0,   0,   3,   0,   0,   0, 
+      8,   0,   0,   0,  80,   0, 
+      0,   0,   0,   0,   0,   0, 
+      1,   0,   0,   0,   3,   0, 
+      0,   0,   0,   0,   0,   0, 
+     15,   0,   0,   0,  92,   0, 
+      0,   0,   0,   0,   0,   0, 
+      4,   0,   0,   0,   1,   0, 
+      0,   0,   1,   0,   0,   0, 
+      1,   0,   0,   0, 118,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   3,   0, 
+      0,   0,   2,   0,   0,   0, 
+      7,   7,   0,   0,  83,  86, 
+     95,  80,  79,  83,  73,  84, 
+     73,  79,  78,   0,  83,  86, 
+     95,  82,  69,  78,  68,  69, 
+     82,  84,  65,  82,  71,  69, 
+     84,  65,  82,  82,  65,  89, 
+     73,  78,  68,  69,  88,   0, 
+     84,  69,  88,  67,  79,  79, 
+     82,  68,   0, 171,  79,  83, 
+     71,  78,  44,   0,   0,   0, 
+      1,   0,   0,   0,   8,   0, 
+      0,   0,  32,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   1,   0,   0,   0, 
+      0,   0,   0,   0,  15,   0, 
+      0,   0,  83,  86,  95,  84, 
+     65,  82,  71,  69,  84,   0, 
+    171, 171,  83,  72,  68,  82, 
+      0,   1,   0,   0,  64,   0, 
+      0,   0,  64,   0,   0,   0, 
+     88,  40,   0,   4,   0, 112, 
+     16,   0,   0,   0,   0,   0, 
+     68,  68,   0,   0,  98,  16, 
+      0,   3, 114,  16,  16,   0, 
+      2,   0,   0,   0, 101,   0, 
+      0,   3, 242,  32,  16,   0, 
+      0,   0,   0,   0, 104,   0, 
+      0,   2,   1,   0,   0,   0, 
+     61,  16,   0,   7, 242,   0, 
+     16,   0,   0,   0,   0,   0, 
+      1,  64,   0,   0,   0,   0, 
+      0,   0,  70, 126,  16,   0, 
+      0,   0,   0,   0,  86,   0, 
+      0,   5, 114,   0,  16,   0, 
+      0,   0,   0,   0,  70,   2, 
+     16,   0,   0,   0,   0,   0, 
+     56,   0,   0,   7, 114,   0, 
+     16,   0,   0,   0,   0,   0, 
+     70,   2,  16,   0,   0,   0, 
+      0,   0,  70,  18,  16,   0, 
+      2,   0,   0,   0,  27,   0, 
+      0,   5, 114,   0,  16,   0, 
+      0,   0,   0,   0,  70,   2, 
+     16,   0,   0,   0,   0,   0, 
+     54,   0,   0,   5, 130,   0, 
+     16,   0,   0,   0,   0,   0, 
+      1,  64,   0,   0,   0,   0, 
+      0,   0,  45,   0,   0,   7, 
+    242,   0,  16,   0,   0,   0, 
+      0,   0,  70,  14,  16,   0, 
+      0,   0,   0,   0,  70, 126, 
+     16,   0,   0,   0,   0,   0, 
+     54,   0,   0,   5,  18,  32, 
+     16,   0,   0,   0,   0,   0, 
+     10,   0,  16,   0,   0,   0, 
+      0,   0,  54,   0,   0,   8, 
+    226,  32,  16,   0,   0,   0, 
+      0,   0,   2,  64,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,  62,   0, 
+      0,   1,  83,  84,  65,  84, 
+    116,   0,   0,   0,   9,   0, 
+      0,   0,   1,   0,   0,   0, 
+      0,   0,   0,   0,   2,   0, 
+      0,   0,   1,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   1,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   1,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   3,   0,   0,   0, 
+      0,   0,   0,   0,   2,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0
+};
--- a/gfx/angle/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrg2d11ps.h
+++ b/gfx/angle/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrg2d11ps.h
@@ -1,198 +1,198 @@
-#if 0
-//
-// Generated by Microsoft (R) HLSL Shader Compiler 6.3.9600.16384
-//
-//
-// Resource Bindings:
-//
-// Name                                 Type  Format         Dim Slot Elements
-// ------------------------------ ---------- ------- ----------- ---- --------
-// Sampler                           sampler      NA          NA    0        1
-// TextureF                          texture  float4          2d    0        1
-//
-//
-//
-// Input signature:
-//
-// Name                 Index   Mask Register SysValue  Format   Used
-// -------------------- ----- ------ -------- -------- ------- ------
-// SV_POSITION              0   xyzw        0      POS   float       
-// TEXCOORD                 0   xy          1     NONE   float   xy  
-//
-//
-// Output signature:
-//
-// Name                 Index   Mask Register SysValue  Format   Used
-// -------------------- ----- ------ -------- -------- ------- ------
-// SV_TARGET                0   xyzw        0   TARGET   float   xyzw
-//
-//
-// Sampler/Resource to DX9 shader sampler mappings:
-//
-// Target Sampler Source Sampler  Source Resource
-// -------------- --------------- ----------------
-// s0             s0              t0               
-//
-//
-// Level9 shader bytecode:
-//
-    ps_2_x
-    def c0, 1, 0, 0, 0
-    dcl t0.xy
-    dcl_2d s0
-    texld r0, t0, s0
-    mad r0, r0.xyxx, c0.xxyy, c0.yyyx
-    mov oC0, r0
-
-// approximately 3 instruction slots used (1 texture, 2 arithmetic)
-ps_4_0
-dcl_sampler s0, mode_default
-dcl_resource_texture2d (float,float,float,float) t0
-dcl_input_ps linear v1.xy
-dcl_output o0.xyzw
-dcl_temps 1
-sample r0.xyzw, v1.xyxx, t0.xyzw, s0
-mov o0.xy, r0.xyxx
-mov o0.zw, l(0,0,0,1.000000)
-ret 
-// Approximately 4 instruction slots used
-#endif
-
-const BYTE g_PS_PassthroughRG2D[] =
-{
-     68,  88,  66,  67, 217, 171, 
-    153, 248,  26,  15, 102, 119, 
-     86, 174, 121, 245, 223,  83, 
-      2, 181,   1,   0,   0,   0, 
-     40,   3,   0,   0,   6,   0, 
-      0,   0,  56,   0,   0,   0, 
-    208,   0,   0,   0, 120,   1, 
-      0,   0, 244,   1,   0,   0, 
-    156,   2,   0,   0, 244,   2, 
-      0,   0,  65, 111, 110,  57, 
-    144,   0,   0,   0, 144,   0, 
-      0,   0,   0,   2, 255, 255, 
-    104,   0,   0,   0,  40,   0, 
-      0,   0,   0,   0,  40,   0, 
-      0,   0,  40,   0,   0,   0, 
-     40,   0,   1,   0,  36,   0, 
-      0,   0,  40,   0,   0,   0, 
-      0,   0,   1,   2, 255, 255, 
-     81,   0,   0,   5,   0,   0, 
-     15, 160,   0,   0, 128,  63, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-     31,   0,   0,   2,   0,   0, 
-      0, 128,   0,   0,   3, 176, 
-     31,   0,   0,   2,   0,   0, 
-      0, 144,   0,   8,  15, 160, 
-     66,   0,   0,   3,   0,   0, 
-     15, 128,   0,   0, 228, 176, 
-      0,   8, 228, 160,   4,   0, 
-      0,   4,   0,   0,  15, 128, 
-      0,   0,   4, 128,   0,   0, 
-     80, 160,   0,   0,  21, 160, 
-      1,   0,   0,   2,   0,   8, 
-     15, 128,   0,   0, 228, 128, 
-    255, 255,   0,   0,  83,  72, 
-     68,  82, 160,   0,   0,   0, 
-     64,   0,   0,   0,  40,   0, 
-      0,   0,  90,   0,   0,   3, 
-      0,  96,  16,   0,   0,   0, 
-      0,   0,  88,  24,   0,   4, 
-      0, 112,  16,   0,   0,   0, 
-      0,   0,  85,  85,   0,   0, 
-     98,  16,   0,   3,  50,  16, 
-     16,   0,   1,   0,   0,   0, 
-    101,   0,   0,   3, 242,  32, 
-     16,   0,   0,   0,   0,   0, 
-    104,   0,   0,   2,   1,   0, 
-      0,   0,  69,   0,   0,   9, 
-    242,   0,  16,   0,   0,   0, 
-      0,   0,  70,  16,  16,   0, 
-      1,   0,   0,   0,  70, 126, 
-     16,   0,   0,   0,   0,   0, 
-      0,  96,  16,   0,   0,   0, 
-      0,   0,  54,   0,   0,   5, 
-     50,  32,  16,   0,   0,   0, 
-      0,   0,  70,   0,  16,   0, 
-      0,   0,   0,   0,  54,   0, 
-      0,   8, 194,  32,  16,   0, 
-      0,   0,   0,   0,   2,  64, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0, 128,  63, 
-     62,   0,   0,   1,  83,  84, 
-     65,  84, 116,   0,   0,   0, 
-      4,   0,   0,   0,   1,   0, 
-      0,   0,   0,   0,   0,   0, 
-      2,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   1,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   1,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   2,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,  82,  68,  69,  70, 
-    160,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      2,   0,   0,   0,  28,   0, 
-      0,   0,   0,   4, 255, 255, 
-      0,   1,   0,   0, 109,   0, 
-      0,   0,  92,   0,   0,   0, 
-      3,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   1,   0,   0,   0, 
-      1,   0,   0,   0, 100,   0, 
-      0,   0,   2,   0,   0,   0, 
-      5,   0,   0,   0,   4,   0, 
-      0,   0, 255, 255, 255, 255, 
-      0,   0,   0,   0,   1,   0, 
-      0,   0,  13,   0,   0,   0, 
-     83,  97, 109, 112, 108, 101, 
-    114,   0,  84, 101, 120, 116, 
-    117, 114, 101,  70,   0,  77, 
-    105,  99, 114, 111, 115, 111, 
-    102, 116,  32,  40,  82,  41, 
-     32,  72,  76,  83,  76,  32, 
-     83, 104,  97, 100, 101, 114, 
-     32,  67, 111, 109, 112, 105, 
-    108, 101, 114,  32,  54,  46, 
-     51,  46,  57,  54,  48,  48, 
-     46,  49,  54,  51,  56,  52, 
-      0, 171,  73,  83,  71,  78, 
-     80,   0,   0,   0,   2,   0, 
-      0,   0,   8,   0,   0,   0, 
-     56,   0,   0,   0,   0,   0, 
-      0,   0,   1,   0,   0,   0, 
-      3,   0,   0,   0,   0,   0, 
-      0,   0,  15,   0,   0,   0, 
-     68,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      3,   0,   0,   0,   1,   0, 
-      0,   0,   3,   3,   0,   0, 
-     83,  86,  95,  80,  79,  83, 
-     73,  84,  73,  79,  78,   0, 
-     84,  69,  88,  67,  79,  79, 
-     82,  68,   0, 171, 171, 171, 
-     79,  83,  71,  78,  44,   0, 
-      0,   0,   1,   0,   0,   0, 
-      8,   0,   0,   0,  32,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   3,   0, 
-      0,   0,   0,   0,   0,   0, 
-     15,   0,   0,   0,  83,  86, 
-     95,  84,  65,  82,  71,  69, 
-     84,   0, 171, 171
-};
+#if 0
+//
+// Generated by Microsoft (R) HLSL Shader Compiler 6.3.9600.16384
+//
+//
+// Resource Bindings:
+//
+// Name                                 Type  Format         Dim Slot Elements
+// ------------------------------ ---------- ------- ----------- ---- --------
+// Sampler                           sampler      NA          NA    0        1
+// TextureF                          texture  float4          2d    0        1
+//
+//
+//
+// Input signature:
+//
+// Name                 Index   Mask Register SysValue  Format   Used
+// -------------------- ----- ------ -------- -------- ------- ------
+// SV_POSITION              0   xyzw        0      POS   float       
+// TEXCOORD                 0   xy          1     NONE   float   xy  
+//
+//
+// Output signature:
+//
+// Name                 Index   Mask Register SysValue  Format   Used
+// -------------------- ----- ------ -------- -------- ------- ------
+// SV_TARGET                0   xyzw        0   TARGET   float   xyzw
+//
+//
+// Sampler/Resource to DX9 shader sampler mappings:
+//
+// Target Sampler Source Sampler  Source Resource
+// -------------- --------------- ----------------
+// s0             s0              t0               
+//
+//
+// Level9 shader bytecode:
+//
+    ps_2_x
+    def c0, 1, 0, 0, 0
+    dcl t0.xy
+    dcl_2d s0
+    texld r0, t0, s0
+    mad r0, r0.xyxx, c0.xxyy, c0.yyyx
+    mov oC0, r0
+
+// approximately 3 instruction slots used (1 texture, 2 arithmetic)
+ps_4_0
+dcl_sampler s0, mode_default
+dcl_resource_texture2d (float,float,float,float) t0
+dcl_input_ps linear v1.xy
+dcl_output o0.xyzw
+dcl_temps 1
+sample r0.xyzw, v1.xyxx, t0.xyzw, s0
+mov o0.xy, r0.xyxx
+mov o0.zw, l(0,0,0,1.000000)
+ret 
+// Approximately 4 instruction slots used
+#endif
+
+const BYTE g_PS_PassthroughRG2D[] =
+{
+     68,  88,  66,  67, 217, 171, 
+    153, 248,  26,  15, 102, 119, 
+     86, 174, 121, 245, 223,  83, 
+      2, 181,   1,   0,   0,   0, 
+     40,   3,   0,   0,   6,   0, 
+      0,   0,  56,   0,   0,   0, 
+    208,   0,   0,   0, 120,   1, 
+      0,   0, 244,   1,   0,   0, 
+    156,   2,   0,   0, 244,   2, 
+      0,   0,  65, 111, 110,  57, 
+    144,   0,   0,   0, 144,   0, 
+      0,   0,   0,   2, 255, 255, 
+    104,   0,   0,   0,  40,   0, 
+      0,   0,   0,   0,  40,   0, 
+      0,   0,  40,   0,   0,   0, 
+     40,   0,   1,   0,  36,   0, 
+      0,   0,  40,   0,   0,   0, 
+      0,   0,   1,   2, 255, 255, 
+     81,   0,   0,   5,   0,   0, 
+     15, 160,   0,   0, 128,  63, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+     31,   0,   0,   2,   0,   0, 
+      0, 128,   0,   0,   3, 176, 
+     31,   0,   0,   2,   0,   0, 
+      0, 144,   0,   8,  15, 160, 
+     66,   0,   0,   3,   0,   0, 
+     15, 128,   0,   0, 228, 176, 
+      0,   8, 228, 160,   4,   0, 
+      0,   4,   0,   0,  15, 128, 
+      0,   0,   4, 128,   0,   0, 
+     80, 160,   0,   0,  21, 160, 
+      1,   0,   0,   2,   0,   8, 
+     15, 128,   0,   0, 228, 128, 
+    255, 255,   0,   0,  83,  72, 
+     68,  82, 160,   0,   0,   0, 
+     64,   0,   0,   0,  40,   0, 
+      0,   0,  90,   0,   0,   3, 
+      0,  96,  16,   0,   0,   0, 
+      0,   0,  88,  24,   0,   4, 
+      0, 112,  16,   0,   0,   0, 
+      0,   0,  85,  85,   0,   0, 
+     98,  16,   0,   3,  50,  16, 
+     16,   0,   1,   0,   0,   0, 
+    101,   0,   0,   3, 242,  32, 
+     16,   0,   0,   0,   0,   0, 
+    104,   0,   0,   2,   1,   0, 
+      0,   0,  69,   0,   0,   9, 
+    242,   0,  16,   0,   0,   0, 
+      0,   0,  70,  16,  16,   0, 
+      1,   0,   0,   0,  70, 126, 
+     16,   0,   0,   0,   0,   0, 
+      0,  96,  16,   0,   0,   0, 
+      0,   0,  54,   0,   0,   5, 
+     50,  32,  16,   0,   0,   0, 
+      0,   0,  70,   0,  16,   0, 
+      0,   0,   0,   0,  54,   0, 
+      0,   8, 194,  32,  16,   0, 
+      0,   0,   0,   0,   2,  64, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0, 128,  63, 
+     62,   0,   0,   1,  83,  84, 
+     65,  84, 116,   0,   0,   0, 
+      4,   0,   0,   0,   1,   0, 
+      0,   0,   0,   0,   0,   0, 
+      2,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   1,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   1,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   2,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,  82,  68,  69,  70, 
+    160,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      2,   0,   0,   0,  28,   0, 
+      0,   0,   0,   4, 255, 255, 
+      0,   1,   0,   0, 109,   0, 
+      0,   0,  92,   0,   0,   0, 
+      3,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   1,   0,   0,   0, 
+      1,   0,   0,   0, 100,   0, 
+      0,   0,   2,   0,   0,   0, 
+      5,   0,   0,   0,   4,   0, 
+      0,   0, 255, 255, 255, 255, 
+      0,   0,   0,   0,   1,   0, 
+      0,   0,  13,   0,   0,   0, 
+     83,  97, 109, 112, 108, 101, 
+    114,   0,  84, 101, 120, 116, 
+    117, 114, 101,  70,   0,  77, 
+    105,  99, 114, 111, 115, 111, 
+    102, 116,  32,  40,  82,  41, 
+     32,  72,  76,  83,  76,  32, 
+     83, 104,  97, 100, 101, 114, 
+     32,  67, 111, 109, 112, 105, 
+    108, 101, 114,  32,  54,  46, 
+     51,  46,  57,  54,  48,  48, 
+     46,  49,  54,  51,  56,  52, 
+      0, 171,  73,  83,  71,  78, 
+     80,   0,   0,   0,   2,   0, 
+      0,   0,   8,   0,   0,   0, 
+     56,   0,   0,   0,   0,   0, 
+      0,   0,   1,   0,   0,   0, 
+      3,   0,   0,   0,   0,   0, 
+      0,   0,  15,   0,   0,   0, 
+     68,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      3,   0,   0,   0,   1,   0, 
+      0,   0,   3,   3,   0,   0, 
+     83,  86,  95,  80,  79,  83, 
+     73,  84,  73,  79,  78,   0, 
+     84,  69,  88,  67,  79,  79, 
+     82,  68,   0, 171, 171, 171, 
+     79,  83,  71,  78,  44,   0, 
+      0,   0,   1,   0,   0,   0, 
+      8,   0,   0,   0,  32,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   3,   0, 
+      0,   0,   0,   0,   0,   0, 
+     15,   0,   0,   0,  83,  86, 
+     95,  84,  65,  82,  71,  69, 
+     84,   0, 171, 171
+};
--- a/gfx/angle/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrg2di11ps.h
+++ b/gfx/angle/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrg2di11ps.h
@@ -1,167 +1,167 @@
-#if 0
-//
-// Generated by Microsoft (R) HLSL Shader Compiler 6.3.9600.16384
-//
-//
-// Resource Bindings:
-//
-// Name                                 Type  Format         Dim Slot Elements
-// ------------------------------ ---------- ------- ----------- ---- --------
-// TextureI                          texture   sint4          2d    0        1
-//
-//
-//
-// Input signature:
-//
-// Name                 Index   Mask Register SysValue  Format   Used
-// -------------------- ----- ------ -------- -------- ------- ------
-// SV_POSITION              0   xyzw        0      POS   float       
-// TEXCOORD                 0   xy          1     NONE   float   xy  
-//
-//
-// Output signature:
-//
-// Name                 Index   Mask Register SysValue  Format   Used
-// -------------------- ----- ------ -------- -------- ------- ------
-// SV_TARGET                0   xyzw        0   TARGET     int   xyzw
-//
-ps_4_0
-dcl_resource_texture2d (sint,sint,sint,sint) t0
-dcl_input_ps linear v1.xy
-dcl_output o0.xyzw
-dcl_temps 1
-resinfo_uint r0.xyzw, l(0), t0.xyzw
-utof r0.xy, r0.xyxx
-mul r0.xy, r0.xyxx, v1.xyxx
-ftoi r0.xy, r0.xyxx
-mov r0.zw, l(0,0,0,0)
-ld r0.xyzw, r0.xyzw, t0.xyzw
-mov o0.xy, r0.xyxx
-mov o0.zw, l(0,0,0,0)
-ret 
-// Approximately 9 instruction slots used
-#endif
-
-const BYTE g_PS_PassthroughRG2DI[] =
-{
-     68,  88,  66,  67,  89, 123, 
-    129, 251, 206, 105, 221, 141, 
-      5, 160, 186, 187, 168, 157, 
-    145, 246,   1,   0,   0,   0, 
-    208,   2,   0,   0,   5,   0, 
-      0,   0,  52,   0,   0,   0, 
-    180,   0,   0,   0,  12,   1, 
-      0,   0,  64,   1,   0,   0, 
-     84,   2,   0,   0,  82,  68, 
-     69,  70, 120,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   1,   0,   0,   0, 
-     28,   0,   0,   0,   0,   4, 
-    255, 255,   0,   1,   0,   0, 
-     69,   0,   0,   0,  60,   0, 
-      0,   0,   2,   0,   0,   0, 
-      3,   0,   0,   0,   4,   0, 
-      0,   0, 255, 255, 255, 255, 
-      0,   0,   0,   0,   1,   0, 
-      0,   0,  13,   0,   0,   0, 
-     84, 101, 120, 116, 117, 114, 
-    101,  73,   0,  77, 105,  99, 
-    114, 111, 115, 111, 102, 116, 
-     32,  40,  82,  41,  32,  72, 
-     76,  83,  76,  32,  83, 104, 
-     97, 100, 101, 114,  32,  67, 
-    111, 109, 112, 105, 108, 101, 
-    114,  32,  54,  46,  51,  46, 
-     57,  54,  48,  48,  46,  49, 
-     54,  51,  56,  52,   0, 171, 
-     73,  83,  71,  78,  80,   0, 
-      0,   0,   2,   0,   0,   0, 
-      8,   0,   0,   0,  56,   0, 
-      0,   0,   0,   0,   0,   0, 
-      1,   0,   0,   0,   3,   0, 
-      0,   0,   0,   0,   0,   0, 
-     15,   0,   0,   0,  68,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   3,   0, 
-      0,   0,   1,   0,   0,   0, 
-      3,   3,   0,   0,  83,  86, 
-     95,  80,  79,  83,  73,  84, 
-     73,  79,  78,   0,  84,  69, 
-     88,  67,  79,  79,  82,  68, 
-      0, 171, 171, 171,  79,  83, 
-     71,  78,  44,   0,   0,   0, 
-      1,   0,   0,   0,   8,   0, 
-      0,   0,  32,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   2,   0,   0,   0, 
-      0,   0,   0,   0,  15,   0, 
-      0,   0,  83,  86,  95,  84, 
-     65,  82,  71,  69,  84,   0, 
-    171, 171,  83,  72,  68,  82, 
-     12,   1,   0,   0,  64,   0, 
-      0,   0,  67,   0,   0,   0, 
-     88,  24,   0,   4,   0, 112, 
-     16,   0,   0,   0,   0,   0, 
-     51,  51,   0,   0,  98,  16, 
-      0,   3,  50,  16,  16,   0, 
-      1,   0,   0,   0, 101,   0, 
-      0,   3, 242,  32,  16,   0, 
-      0,   0,   0,   0, 104,   0, 
-      0,   2,   1,   0,   0,   0, 
-     61,  16,   0,   7, 242,   0, 
-     16,   0,   0,   0,   0,   0, 
-      1,  64,   0,   0,   0,   0, 
-      0,   0,  70, 126,  16,   0, 
-      0,   0,   0,   0,  86,   0, 
-      0,   5,  50,   0,  16,   0, 
-      0,   0,   0,   0,  70,   0, 
-     16,   0,   0,   0,   0,   0, 
-     56,   0,   0,   7,  50,   0, 
-     16,   0,   0,   0,   0,   0, 
-     70,   0,  16,   0,   0,   0, 
-      0,   0,  70,  16,  16,   0, 
-      1,   0,   0,   0,  27,   0, 
-      0,   5,  50,   0,  16,   0, 
-      0,   0,   0,   0,  70,   0, 
-     16,   0,   0,   0,   0,   0, 
-     54,   0,   0,   8, 194,   0, 
-     16,   0,   0,   0,   0,   0, 
-      2,  64,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,  45,   0,   0,   7, 
-    242,   0,  16,   0,   0,   0, 
-      0,   0,  70,  14,  16,   0, 
-      0,   0,   0,   0,  70, 126, 
-     16,   0,   0,   0,   0,   0, 
-     54,   0,   0,   5,  50,  32, 
-     16,   0,   0,   0,   0,   0, 
-     70,   0,  16,   0,   0,   0, 
-      0,   0,  54,   0,   0,   8, 
-    194,  32,  16,   0,   0,   0, 
-      0,   0,   2,  64,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,  62,   0, 
-      0,   1,  83,  84,  65,  84, 
-    116,   0,   0,   0,   9,   0, 
-      0,   0,   1,   0,   0,   0, 
-      0,   0,   0,   0,   2,   0, 
-      0,   0,   1,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   1,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   1,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   3,   0,   0,   0, 
-      0,   0,   0,   0,   2,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0
-};
+#if 0
+//
+// Generated by Microsoft (R) HLSL Shader Compiler 6.3.9600.16384
+//
+//
+// Resource Bindings:
+//
+// Name                                 Type  Format         Dim Slot Elements
+// ------------------------------ ---------- ------- ----------- ---- --------
+// TextureI                          texture   sint4          2d    0        1
+//
+//
+//
+// Input signature:
+//
+// Name                 Index   Mask Register SysValue  Format   Used
+// -------------------- ----- ------ -------- -------- ------- ------
+// SV_POSITION              0   xyzw        0      POS   float       
+// TEXCOORD                 0   xy          1     NONE   float   xy  
+//
+//
+// Output signature:
+//
+// Name                 Index   Mask Register SysValue  Format   Used
+// -------------------- ----- ------ -------- -------- ------- ------
+// SV_TARGET                0   xyzw        0   TARGET     int   xyzw
+//
+ps_4_0
+dcl_resource_texture2d (sint,sint,sint,sint) t0
+dcl_input_ps linear v1.xy
+dcl_output o0.xyzw
+dcl_temps 1
+resinfo_uint r0.xyzw, l(0), t0.xyzw
+utof r0.xy, r0.xyxx
+mul r0.xy, r0.xyxx, v1.xyxx
+ftoi r0.xy, r0.xyxx
+mov r0.zw, l(0,0,0,0)
+ld r0.xyzw, r0.xyzw, t0.xyzw
+mov o0.xy, r0.xyxx
+mov o0.zw, l(0,0,0,0)
+ret 
+// Approximately 9 instruction slots used
+#endif
+
+const BYTE g_PS_PassthroughRG2DI[] =
+{
+     68,  88,  66,  67,  89, 123, 
+    129, 251, 206, 105, 221, 141, 
+      5, 160, 186, 187, 168, 157, 
+    145, 246,   1,   0,   0,   0, 
+    208,   2,   0,   0,   5,   0, 
+      0,   0,  52,   0,   0,   0, 
+    180,   0,   0,   0,  12,   1, 
+      0,   0,  64,   1,   0,   0, 
+     84,   2,   0,   0,  82,  68, 
+     69,  70, 120,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   1,   0,   0,   0, 
+     28,   0,   0,   0,   0,   4, 
+    255, 255,   0,   1,   0,   0, 
+     69,   0,   0,   0,  60,   0, 
+      0,   0,   2,   0,   0,   0, 
+      3,   0,   0,   0,   4,   0, 
+      0,   0, 255, 255, 255, 255, 
+      0,   0,   0,   0,   1,   0, 
+      0,   0,  13,   0,   0,   0, 
+     84, 101, 120, 116, 117, 114, 
+    101,  73,   0,  77, 105,  99, 
+    114, 111, 115, 111, 102, 116, 
+     32,  40,  82,  41,  32,  72, 
+     76,  83,  76,  32,  83, 104, 
+     97, 100, 101, 114,  32,  67, 
+    111, 109, 112, 105, 108, 101, 
+    114,  32,  54,  46,  51,  46, 
+     57,  54,  48,  48,  46,  49, 
+     54,  51,  56,  52,   0, 171, 
+     73,  83,  71,  78,  80,   0, 
+      0,   0,   2,   0,   0,   0, 
+      8,   0,   0,   0,  56,   0, 
+      0,   0,   0,   0,   0,   0, 
+      1,   0,   0,   0,   3,   0, 
+      0,   0,   0,   0,   0,   0, 
+     15,   0,   0,   0,  68,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   3,   0, 
+      0,   0,   1,   0,   0,   0, 
+      3,   3,   0,   0,  83,  86, 
+     95,  80,  79,  83,  73,  84, 
+     73,  79,  78,   0,  84,  69, 
+     88,  67,  79,  79,  82,  68, 
+      0, 171, 171, 171,  79,  83, 
+     71,  78,  44,   0,   0,   0, 
+      1,   0,   0,   0,   8,   0, 
+      0,   0,  32,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   2,   0,   0,   0, 
+      0,   0,   0,   0,  15,   0, 
+      0,   0,  83,  86,  95,  84, 
+     65,  82,  71,  69,  84,   0, 
+    171, 171,  83,  72,  68,  82, 
+     12,   1,   0,   0,  64,   0, 
+      0,   0,  67,   0,   0,   0, 
+     88,  24,   0,   4,   0, 112, 
+     16,   0,   0,   0,   0,   0, 
+     51,  51,   0,   0,  98,  16, 
+      0,   3,  50,  16,  16,   0, 
+      1,   0,   0,   0, 101,   0, 
+      0,   3, 242,  32,  16,   0, 
+      0,   0,   0,   0, 104,   0, 
+      0,   2,   1,   0,   0,   0, 
+     61,  16,   0,   7, 242,   0, 
+     16,   0,   0,   0,   0,   0, 
+      1,  64,   0,   0,   0,   0, 
+      0,   0,  70, 126,  16,   0, 
+      0,   0,   0,   0,  86,   0, 
+      0,   5,  50,   0,  16,   0, 
+      0,   0,   0,   0,  70,   0, 
+     16,   0,   0,   0,   0,   0, 
+     56,   0,   0,   7,  50,   0, 
+     16,   0,   0,   0,   0,   0, 
+     70,   0,  16,   0,   0,   0, 
+      0,   0,  70,  16,  16,   0, 
+      1,   0,   0,   0,  27,   0, 
+      0,   5,  50,   0,  16,   0, 
+      0,   0,   0,   0,  70,   0, 
+     16,   0,   0,   0,   0,   0, 
+     54,   0,   0,   8, 194,   0, 
+     16,   0,   0,   0,   0,   0, 
+      2,  64,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,  45,   0,   0,   7, 
+    242,   0,  16,   0,   0,   0, 
+      0,   0,  70,  14,  16,   0, 
+      0,   0,   0,   0,  70, 126, 
+     16,   0,   0,   0,   0,   0, 
+     54,   0,   0,   5,  50,  32, 
+     16,   0,   0,   0,   0,   0, 
+     70,   0,  16,   0,   0,   0, 
+      0,   0,  54,   0,   0,   8, 
+    194,  32,  16,   0,   0,   0, 
+      0,   0,   2,  64,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,  62,   0, 
+      0,   1,  83,  84,  65,  84, 
+    116,   0,   0,   0,   9,   0, 
+      0,   0,   1,   0,   0,   0, 
+      0,   0,   0,   0,   2,   0, 
+      0,   0,   1,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   1,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   1,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   3,   0,   0,   0, 
+      0,   0,   0,   0,   2,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0
+};
--- a/gfx/angle/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrg2dui11ps.h
+++ b/gfx/angle/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrg2dui11ps.h
@@ -1,167 +1,167 @@
-#if 0
-//
-// Generated by Microsoft (R) HLSL Shader Compiler 6.3.9600.16384
-//
-//
-// Resource Bindings:
-//
-// Name                                 Type  Format         Dim Slot Elements
-// ------------------------------ ---------- ------- ----------- ---- --------
-// TextureUI                         texture   uint4          2d    0        1
-//
-//
-//
-// Input signature:
-//
-// Name                 Index   Mask Register SysValue  Format   Used
-// -------------------- ----- ------ -------- -------- ------- ------
-// SV_POSITION              0   xyzw        0      POS   float       
-// TEXCOORD                 0   xy          1     NONE   float   xy  
-//
-//
-// Output signature:
-//
-// Name                 Index   Mask Register SysValue  Format   Used
-// -------------------- ----- ------ -------- -------- ------- ------
-// SV_TARGET                0   xyzw        0   TARGET    uint   xyzw
-//
-ps_4_0
-dcl_resource_texture2d (uint,uint,uint,uint) t0
-dcl_input_ps linear v1.xy
-dcl_output o0.xyzw
-dcl_temps 1
-resinfo_uint r0.xyzw, l(0), t0.xyzw
-utof r0.xy, r0.xyxx
-mul r0.xy, r0.xyxx, v1.xyxx
-ftoi r0.xy, r0.xyxx
-mov r0.zw, l(0,0,0,0)
-ld r0.xyzw, r0.xyzw, t0.xyzw
-mov o0.xy, r0.xyxx
-mov o0.zw, l(0,0,0,0)
-ret 
-// Approximately 9 instruction slots used
-#endif
-
-const BYTE g_PS_PassthroughRG2DUI[] =
-{
-     68,  88,  66,  67, 253, 188, 
-    138, 153, 226, 194, 182, 197, 
-    184,  36, 111,  24, 198, 171, 
-    241, 145,   1,   0,   0,   0, 
-    208,   2,   0,   0,   5,   0, 
-      0,   0,  52,   0,   0,   0, 
-    180,   0,   0,   0,  12,   1, 
-      0,   0,  64,   1,   0,   0, 
-     84,   2,   0,   0,  82,  68, 
-     69,  70, 120,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   1,   0,   0,   0, 
-     28,   0,   0,   0,   0,   4, 
-    255, 255,   0,   1,   0,   0, 
-     70,   0,   0,   0,  60,   0, 
-      0,   0,   2,   0,   0,   0, 
-      4,   0,   0,   0,   4,   0, 
-      0,   0, 255, 255, 255, 255, 
-      0,   0,   0,   0,   1,   0, 
-      0,   0,  13,   0,   0,   0, 
-     84, 101, 120, 116, 117, 114, 
-    101,  85,  73,   0,  77, 105, 
-     99, 114, 111, 115, 111, 102, 
-    116,  32,  40,  82,  41,  32, 
-     72,  76,  83,  76,  32,  83, 
-    104,  97, 100, 101, 114,  32, 
-     67, 111, 109, 112, 105, 108, 
-    101, 114,  32,  54,  46,  51, 
-     46,  57,  54,  48,  48,  46, 
-     49,  54,  51,  56,  52,   0, 
-     73,  83,  71,  78,  80,   0, 
-      0,   0,   2,   0,   0,   0, 
-      8,   0,   0,   0,  56,   0, 
-      0,   0,   0,   0,   0,   0, 
-      1,   0,   0,   0,   3,   0, 
-      0,   0,   0,   0,   0,   0, 
-     15,   0,   0,   0,  68,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   3,   0, 
-      0,   0,   1,   0,   0,   0, 
-      3,   3,   0,   0,  83,  86, 
-     95,  80,  79,  83,  73,  84, 
-     73,  79,  78,   0,  84,  69, 
-     88,  67,  79,  79,  82,  68, 
-      0, 171, 171, 171,  79,  83, 
-     71,  78,  44,   0,   0,   0, 
-      1,   0,   0,   0,   8,   0, 
-      0,   0,  32,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   1,   0,   0,   0, 
-      0,   0,   0,   0,  15,   0, 
-      0,   0,  83,  86,  95,  84, 
-     65,  82,  71,  69,  84,   0, 
-    171, 171,  83,  72,  68,  82, 
-     12,   1,   0,   0,  64,   0, 
-      0,   0,  67,   0,   0,   0, 
-     88,  24,   0,   4,   0, 112, 
-     16,   0,   0,   0,   0,   0, 
-     68,  68,   0,   0,  98,  16, 
-      0,   3,  50,  16,  16,   0, 
-      1,   0,   0,   0, 101,   0, 
-      0,   3, 242,  32,  16,   0, 
-      0,   0,   0,   0, 104,   0, 
-      0,   2,   1,   0,   0,   0, 
-     61,  16,   0,   7, 242,   0, 
-     16,   0,   0,   0,   0,   0, 
-      1,  64,   0,   0,   0,   0, 
-      0,   0,  70, 126,  16,   0, 
-      0,   0,   0,   0,  86,   0, 
-      0,   5,  50,   0,  16,   0, 
-      0,   0,   0,   0,  70,   0, 
-     16,   0,   0,   0,   0,   0, 
-     56,   0,   0,   7,  50,   0, 
-     16,   0,   0,   0,   0,   0, 
-     70,   0,  16,   0,   0,   0, 
-      0,   0,  70,  16,  16,   0, 
-      1,   0,   0,   0,  27,   0, 
-      0,   5,  50,   0,  16,   0, 
-      0,   0,   0,   0,  70,   0, 
-     16,   0,   0,   0,   0,   0, 
-     54,   0,   0,   8, 194,   0, 
-     16,   0,   0,   0,   0,   0, 
-      2,  64,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,  45,   0,   0,   7, 
-    242,   0,  16,   0,   0,   0, 
-      0,   0,  70,  14,  16,   0, 
-      0,   0,   0,   0,  70, 126, 
-     16,   0,   0,   0,   0,   0, 
-     54,   0,   0,   5,  50,  32, 
-     16,   0,   0,   0,   0,   0, 
-     70,   0,  16,   0,   0,   0, 
-      0,   0,  54,   0,   0,   8, 
-    194,  32,  16,   0,   0,   0, 
-      0,   0,   2,  64,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,  62,   0, 
-      0,   1,  83,  84,  65,  84, 
-    116,   0,   0,   0,   9,   0, 
-      0,   0,   1,   0,   0,   0, 
-      0,   0,   0,   0,   2,   0, 
-      0,   0,   1,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   1,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   1,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   3,   0,   0,   0, 
-      0,   0,   0,   0,   2,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0
-};
+#if 0
+//
+// Generated by Microsoft (R) HLSL Shader Compiler 6.3.9600.16384
+//
+//
+// Resource Bindings:
+//
+// Name                                 Type  Format         Dim Slot Elements
+// ------------------------------ ---------- ------- ----------- ---- --------
+// TextureUI                         texture   uint4          2d    0        1
+//
+//
+//
+// Input signature:
+//
+// Name                 Index   Mask Register SysValue  Format   Used
+// -------------------- ----- ------ -------- -------- ------- ------
+// SV_POSITION              0   xyzw        0      POS   float       
+// TEXCOORD                 0   xy          1     NONE   float   xy  
+//
+//
+// Output signature:
+//
+// Name                 Index   Mask Register SysValue  Format   Used
+// -------------------- ----- ------ -------- -------- ------- ------
+// SV_TARGET                0   xyzw        0   TARGET    uint   xyzw
+//
+ps_4_0
+dcl_resource_texture2d (uint,uint,uint,uint) t0
+dcl_input_ps linear v1.xy
+dcl_output o0.xyzw
+dcl_temps 1
+resinfo_uint r0.xyzw, l(0), t0.xyzw
+utof r0.xy, r0.xyxx
+mul r0.xy, r0.xyxx, v1.xyxx
+ftoi r0.xy, r0.xyxx
+mov r0.zw, l(0,0,0,0)
+ld r0.xyzw, r0.xyzw, t0.xyzw
+mov o0.xy, r0.xyxx
+mov o0.zw, l(0,0,0,0)
+ret 
+// Approximately 9 instruction slots used
+#endif
+
+const BYTE g_PS_PassthroughRG2DUI[] =
+{
+     68,  88,  66,  67, 253, 188, 
+    138, 153, 226, 194, 182, 197, 
+    184,  36, 111,  24, 198, 171, 
+    241, 145,   1,   0,   0,   0, 
+    208,   2,   0,   0,   5,   0, 
+      0,   0,  52,   0,   0,   0, 
+    180,   0,   0,   0,  12,   1, 
+      0,   0,  64,   1,   0,   0, 
+     84,   2,   0,   0,  82,  68, 
+     69,  70, 120,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   1,   0,   0,   0, 
+     28,   0,   0,   0,   0,   4, 
+    255, 255,   0,   1,   0,   0, 
+     70,   0,   0,   0,  60,   0, 
+      0,   0,   2,   0,   0,   0, 
+      4,   0,   0,   0,   4,   0, 
+      0,   0, 255, 255, 255, 255, 
+      0,   0,   0,   0,   1,   0, 
+      0,   0,  13,   0,   0,   0, 
+     84, 101, 120, 116, 117, 114, 
+    101,  85,  73,   0,  77, 105, 
+     99, 114, 111, 115, 111, 102, 
+    116,  32,  40,  82,  41,  32, 
+     72,  76,  83,  76,  32,  83, 
+    104,  97, 100, 101, 114,  32, 
+     67, 111, 109, 112, 105, 108, 
+    101, 114,  32,  54,  46,  51, 
+     46,  57,  54,  48,  48,  46, 
+     49,  54,  51,  56,  52,   0, 
+     73,  83,  71,  78,  80,   0, 
+      0,   0,   2,   0,   0,   0, 
+      8,   0,   0,   0,  56,   0, 
+      0,   0,   0,   0,   0,   0, 
+      1,   0,   0,   0,   3,   0, 
+      0,   0,   0,   0,   0,   0, 
+     15,   0,   0,   0,  68,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   3,   0, 
+      0,   0,   1,   0,   0,   0, 
+      3,   3,   0,   0,  83,  86, 
+     95,  80,  79,  83,  73,  84, 
+     73,  79,  78,   0,  84,  69, 
+     88,  67,  79,  79,  82,  68, 
+      0, 171, 171, 171,  79,  83, 
+     71,  78,  44,   0,   0,   0, 
+      1,   0,   0,   0,   8,   0, 
+      0,   0,  32,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   1,   0,   0,   0, 
+      0,   0,   0,   0,  15,   0, 
+      0,   0,  83,  86,  95,  84, 
+     65,  82,  71,  69,  84,   0, 
+    171, 171,  83,  72,  68,  82, 
+     12,   1,   0,   0,  64,   0, 
+      0,   0,  67,   0,   0,   0, 
+     88,  24,   0,   4,   0, 112, 
+     16,   0,   0,   0,   0,   0, 
+     68,  68,   0,   0,  98,  16, 
+      0,   3,  50,  16,  16,   0, 
+      1,   0,   0,   0, 101,   0, 
+      0,   3, 242,  32,  16,   0, 
+      0,   0,   0,   0, 104,   0, 
+      0,   2,   1,   0,   0,   0, 
+     61,  16,   0,   7, 242,   0, 
+     16,   0,   0,   0,   0,   0, 
+      1,  64,   0,   0,   0,   0, 
+      0,   0,  70, 126,  16,   0, 
+      0,   0,   0,   0,  86,   0, 
+      0,   5,  50,   0,  16,   0, 
+      0,   0,   0,   0,  70,   0, 
+     16,   0,   0,   0,   0,   0, 
+     56,   0,   0,   7,  50,   0, 
+     16,   0,   0,   0,   0,   0, 
+     70,   0,  16,   0,   0,   0, 
+      0,   0,  70,  16,  16,   0, 
+      1,   0,   0,   0,  27,   0, 
+      0,   5,  50,   0,  16,   0, 
+      0,   0,   0,   0,  70,   0, 
+     16,   0,   0,   0,   0,   0, 
+     54,   0,   0,   8, 194,   0, 
+     16,   0,   0,   0,   0,   0, 
+      2,  64,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,  45,   0,   0,   7, 
+    242,   0,  16,   0,   0,   0, 
+      0,   0,  70,  14,  16,   0, 
+      0,   0,   0,   0,  70, 126, 
+     16,   0,   0,   0,   0,   0, 
+     54,   0,   0,   5,  50,  32, 
+     16,   0,   0,   0,   0,   0, 
+     70,   0,  16,   0,   0,   0, 
+      0,   0,  54,   0,   0,   8, 
+    194,  32,  16,   0,   0,   0, 
+      0,   0,   2,  64,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,  62,   0, 
+      0,   1,  83,  84,  65,  84, 
+    116,   0,   0,   0,   9,   0, 
+      0,   0,   1,   0,   0,   0, 
+      0,   0,   0,   0,   2,   0, 
+      0,   0,   1,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   1,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   1,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   3,   0,   0,   0, 
+      0,   0,   0,   0,   2,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0
+};
--- a/gfx/angle/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrg3d11ps.h
+++ b/gfx/angle/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrg3d11ps.h
@@ -1,162 +1,162 @@
-#if 0
-//
-// Generated by Microsoft (R) HLSL Shader Compiler 6.3.9600.16384
-//
-//
-// Resource Bindings:
-//
-// Name                                 Type  Format         Dim Slot Elements
-// ------------------------------ ---------- ------- ----------- ---- --------
-// Sampler                           sampler      NA          NA    0        1
-// TextureF                          texture  float4          3d    0        1
-//
-//
-//
-// Input signature:
-//
-// Name                 Index   Mask Register SysValue  Format   Used
-// -------------------- ----- ------ -------- -------- ------- ------
-// SV_POSITION              0   xyzw        0      POS   float       
-// SV_RENDERTARGETARRAYINDEX     0   x           1  RTINDEX    uint       
-// TEXCOORD                 0   xyz         2     NONE   float   xyz 
-//
-//
-// Output signature:
-//
-// Name                 Index   Mask Register SysValue  Format   Used
-// -------------------- ----- ------ -------- -------- ------- ------
-// SV_TARGET                0   xyzw        0   TARGET   float   xyzw
-//
-ps_4_0
-dcl_sampler s0, mode_default
-dcl_resource_texture3d (float,float,float,float) t0
-dcl_input_ps linear v2.xyz
-dcl_output o0.xyzw
-dcl_temps 1
-sample r0.xyzw, v2.xyzx, t0.xyzw, s0
-mov o0.xy, r0.xyxx
-mov o0.zw, l(0,0,0,1.000000)
-ret 
-// Approximately 4 instruction slots used
-#endif
-
-const BYTE g_PS_PassthroughRG3D[] =
-{
-     68,  88,  66,  67, 117, 159, 
-    238,  81,  51, 223, 126,  31, 
-    223, 171, 227,   2, 248,   7, 
-     72,  91,   1,   0,   0,   0, 
-    188,   2,   0,   0,   5,   0, 
-      0,   0,  52,   0,   0,   0, 
-    220,   0,   0,   0, 100,   1, 
-      0,   0, 152,   1,   0,   0, 
-     64,   2,   0,   0,  82,  68, 
-     69,  70, 160,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   2,   0,   0,   0, 
-     28,   0,   0,   0,   0,   4, 
-    255, 255,   0,   1,   0,   0, 
-    109,   0,   0,   0,  92,   0, 
-      0,   0,   3,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   1,   0, 
-      0,   0,   1,   0,   0,   0, 
-    100,   0,   0,   0,   2,   0, 
-      0,   0,   5,   0,   0,   0, 
-      8,   0,   0,   0, 255, 255, 
-    255, 255,   0,   0,   0,   0, 
-      1,   0,   0,   0,  13,   0, 
-      0,   0,  83,  97, 109, 112, 
-    108, 101, 114,   0,  84, 101, 
-    120, 116, 117, 114, 101,  70, 
-      0,  77, 105,  99, 114, 111, 
-    115, 111, 102, 116,  32,  40, 
-     82,  41,  32,  72,  76,  83, 
-     76,  32,  83, 104,  97, 100, 
-    101, 114,  32,  67, 111, 109, 
-    112, 105, 108, 101, 114,  32, 
-     54,  46,  51,  46,  57,  54, 
-     48,  48,  46,  49,  54,  51, 
-     56,  52,   0, 171,  73,  83, 
-     71,  78, 128,   0,   0,   0, 
-      3,   0,   0,   0,   8,   0, 
-      0,   0,  80,   0,   0,   0, 
-      0,   0,   0,   0,   1,   0, 
-      0,   0,   3,   0,   0,   0, 
-      0,   0,   0,   0,  15,   0, 
-      0,   0,  92,   0,   0,   0, 
-      0,   0,   0,   0,   4,   0, 
-      0,   0,   1,   0,   0,   0, 
-      1,   0,   0,   0,   1,   0, 
-      0,   0, 118,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   3,   0,   0,   0, 
-      2,   0,   0,   0,   7,   7, 
-      0,   0,  83,  86,  95,  80, 
-     79,  83,  73,  84,  73,  79, 
-     78,   0,  83,  86,  95,  82, 
-     69,  78,  68,  69,  82,  84, 
-     65,  82,  71,  69,  84,  65, 
-     82,  82,  65,  89,  73,  78, 
-     68,  69,  88,   0,  84,  69, 
-     88,  67,  79,  79,  82,  68, 
-      0, 171,  79,  83,  71,  78, 
-     44,   0,   0,   0,   1,   0, 
-      0,   0,   8,   0,   0,   0, 
-     32,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      3,   0,   0,   0,   0,   0, 
-      0,   0,  15,   0,   0,   0, 
-     83,  86,  95,  84,  65,  82, 
-     71,  69,  84,   0, 171, 171, 
-     83,  72,  68,  82, 160,   0, 
-      0,   0,  64,   0,   0,   0, 
-     40,   0,   0,   0,  90,   0, 
-      0,   3,   0,  96,  16,   0, 
-      0,   0,   0,   0,  88,  40, 
-      0,   4,   0, 112,  16,   0, 
-      0,   0,   0,   0,  85,  85, 
-      0,   0,  98,  16,   0,   3, 
-    114,  16,  16,   0,   2,   0, 
-      0,   0, 101,   0,   0,   3, 
-    242,  32,  16,   0,   0,   0, 
-      0,   0, 104,   0,   0,   2, 
-      1,   0,   0,   0,  69,   0, 
-      0,   9, 242,   0,  16,   0, 
-      0,   0,   0,   0,  70,  18, 
-     16,   0,   2,   0,   0,   0, 
-     70, 126,  16,   0,   0,   0, 
-      0,   0,   0,  96,  16,   0, 
-      0,   0,   0,   0,  54,   0, 
-      0,   5,  50,  32,  16,   0, 
-      0,   0,   0,   0,  70,   0, 
-     16,   0,   0,   0,   0,   0, 
-     54,   0,   0,   8, 194,  32, 
-     16,   0,   0,   0,   0,   0, 
-      2,  64,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-    128,  63,  62,   0,   0,   1, 
-     83,  84,  65,  84, 116,   0, 
-      0,   0,   4,   0,   0,   0, 
-      1,   0,   0,   0,   0,   0, 
-      0,   0,   2,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      1,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   1,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      2,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0
-};
+#if 0
+//
+// Generated by Microsoft (R) HLSL Shader Compiler 6.3.9600.16384
+//
+//
+// Resource Bindings:
+//
+// Name                                 Type  Format         Dim Slot Elements
+// ------------------------------ ---------- ------- ----------- ---- --------
+// Sampler                           sampler      NA          NA    0        1
+// TextureF                          texture  float4          3d    0        1
+//
+//
+//
+// Input signature:
+//
+// Name                 Index   Mask Register SysValue  Format   Used
+// -------------------- ----- ------ -------- -------- ------- ------
+// SV_POSITION              0   xyzw        0      POS   float       
+// SV_RENDERTARGETARRAYINDEX     0   x           1  RTINDEX    uint       
+// TEXCOORD                 0   xyz         2     NONE   float   xyz 
+//
+//
+// Output signature:
+//
+// Name                 Index   Mask Register SysValue  Format   Used
+// -------------------- ----- ------ -------- -------- ------- ------
+// SV_TARGET                0   xyzw        0   TARGET   float   xyzw
+//
+ps_4_0
+dcl_sampler s0, mode_default
+dcl_resource_texture3d (float,float,float,float) t0
+dcl_input_ps linear v2.xyz
+dcl_output o0.xyzw
+dcl_temps 1
+sample r0.xyzw, v2.xyzx, t0.xyzw, s0
+mov o0.xy, r0.xyxx
+mov o0.zw, l(0,0,0,1.000000)
+ret 
+// Approximately 4 instruction slots used
+#endif
+
+const BYTE g_PS_PassthroughRG3D[] =
+{
+     68,  88,  66,  67, 117, 159, 
+    238,  81,  51, 223, 126,  31, 
+    223, 171, 227,   2, 248,   7, 
+     72,  91,   1,   0,   0,   0, 
+    188,   2,   0,   0,   5,   0, 
+      0,   0,  52,   0,   0,   0, 
+    220,   0,   0,   0, 100,   1, 
+      0,   0, 152,   1,   0,   0, 
+     64,   2,   0,   0,  82,  68, 
+     69,  70, 160,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   2,   0,   0,   0, 
+     28,   0,   0,   0,   0,   4, 
+    255, 255,   0,   1,   0,   0, 
+    109,   0,   0,   0,  92,   0, 
+      0,   0,   3,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   1,   0, 
+      0,   0,   1,   0,   0,   0, 
+    100,   0,   0,   0,   2,   0, 
+      0,   0,   5,   0,   0,   0, 
+      8,   0,   0,   0, 255, 255, 
+    255, 255,   0,   0,   0,   0, 
+      1,   0,   0,   0,  13,   0, 
+      0,   0,  83,  97, 109, 112, 
+    108, 101, 114,   0,  84, 101, 
+    120, 116, 117, 114, 101,  70, 
+      0,  77, 105,  99, 114, 111, 
+    115, 111, 102, 116,  32,  40, 
+     82,  41,  32,  72,  76,  83, 
+     76,  32,  83, 104,  97, 100, 
+    101, 114,  32,  67, 111, 109, 
+    112, 105, 108, 101, 114,  32, 
+     54,  46,  51,  46,  57,  54, 
+     48,  48,  46,  49,  54,  51, 
+     56,  52,   0, 171,  73,  83, 
+     71,  78, 128,   0,   0,   0, 
+      3,   0,   0,   0,   8,   0, 
+      0,   0,  80,   0,   0,   0, 
+      0,   0,   0,   0,   1,   0, 
+      0,   0,   3,   0,   0,   0, 
+      0,   0,   0,   0,  15,   0, 
+      0,   0,  92,   0,   0,   0, 
+      0,   0,   0,   0,   4,   0, 
+      0,   0,   1,   0,   0,   0, 
+      1,   0,   0,   0,   1,   0, 
+      0,   0, 118,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   3,   0,   0,   0, 
+      2,   0,   0,   0,   7,   7, 
+      0,   0,  83,  86,  95,  80, 
+     79,  83,  73,  84,  73,  79, 
+     78,   0,  83,  86,  95,  82, 
+     69,  78,  68,  69,  82,  84, 
+     65,  82,  71,  69,  84,  65, 
+     82,  82,  65,  89,  73,  78, 
+     68,  69,  88,   0,  84,  69, 
+     88,  67,  79,  79,  82,  68, 
+      0, 171,  79,  83,  71,  78, 
+     44,   0,   0,   0,   1,   0, 
+      0,   0,   8,   0,   0,   0, 
+     32,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      3,   0,   0,   0,   0,   0, 
+      0,   0,  15,   0,   0,   0, 
+     83,  86,  95,  84,  65,  82, 
+     71,  69,  84,   0, 171, 171, 
+     83,  72,  68,  82, 160,   0, 
+      0,   0,  64,   0,   0,   0, 
+     40,   0,   0,   0,  90,   0, 
+      0,   3,   0,  96,  16,   0, 
+      0,   0,   0,   0,  88,  40, 
+      0,   4,   0, 112,  16,   0, 
+      0,   0,   0,   0,  85,  85, 
+      0,   0,  98,  16,   0,   3, 
+    114,  16,  16,   0,   2,   0, 
+      0,   0, 101,   0,   0,   3, 
+    242,  32,  16,   0,   0,   0, 
+      0,   0, 104,   0,   0,   2, 
+      1,   0,   0,   0,  69,   0, 
+      0,   9, 242,   0,  16,   0, 
+      0,   0,   0,   0,  70,  18, 
+     16,   0,   2,   0,   0,   0, 
+     70, 126,  16,   0,   0,   0, 
+      0,   0,   0,  96,  16,   0, 
+      0,   0,   0,   0,  54,   0, 
+      0,   5,  50,  32,  16,   0, 
+      0,   0,   0,   0,  70,   0, 
+     16,   0,   0,   0,   0,   0, 
+     54,   0,   0,   8, 194,  32, 
+     16,   0,   0,   0,   0,   0, 
+      2,  64,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+    128,  63,  62,   0,   0,   1, 
+     83,  84,  65,  84, 116,   0, 
+      0,   0,   4,   0,   0,   0, 
+      1,   0,   0,   0,   0,   0, 
+      0,   0,   2,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      1,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   1,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      2,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0
+};
--- a/gfx/angle/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrg3di11ps.h
+++ b/gfx/angle/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrg3di11ps.h
@@ -1,174 +1,174 @@
-#if 0
-//
-// Generated by Microsoft (R) HLSL Shader Compiler 6.3.9600.16384
-//
-//
-// Resource Bindings:
-//
-// Name                                 Type  Format         Dim Slot Elements
-// ------------------------------ ---------- ------- ----------- ---- --------
-// TextureI                          texture   sint4          3d    0        1
-//
-//
-//
-// Input signature:
-//
-// Name                 Index   Mask Register SysValue  Format   Used
-// -------------------- ----- ------ -------- -------- ------- ------
-// SV_POSITION              0   xyzw        0      POS   float       
-// SV_RENDERTARGETARRAYINDEX     0   x           1  RTINDEX    uint       
-// TEXCOORD                 0   xyz         2     NONE   float   xyz 
-//
-//
-// Output signature:
-//
-// Name                 Index   Mask Register SysValue  Format   Used
-// -------------------- ----- ------ -------- -------- ------- ------
-// SV_TARGET                0   xyzw        0   TARGET     int   xyzw
-//
-ps_4_0
-dcl_resource_texture3d (sint,sint,sint,sint) t0
-dcl_input_ps linear v2.xyz
-dcl_output o0.xyzw
-dcl_temps 1
-resinfo_uint r0.xyzw, l(0), t0.xyzw
-utof r0.xyz, r0.xyzx
-mul r0.xyz, r0.xyzx, v2.xyzx
-ftoi r0.xyz, r0.xyzx
-mov r0.w, l(0)
-ld r0.xyzw, r0.xyzw, t0.xyzw
-mov o0.xy, r0.xyxx
-mov o0.zw, l(0,0,0,0)
-ret 
-// Approximately 9 instruction slots used
-#endif
-
-const BYTE g_PS_PassthroughRG3DI[] =
-{
-     68,  88,  66,  67,  62, 119, 
-     61,  21,  83,  42,  80, 125, 
-    121, 208, 247,  10, 223,  62, 
-     33,  18,   1,   0,   0,   0, 
-    244,   2,   0,   0,   5,   0, 
-      0,   0,  52,   0,   0,   0, 
-    180,   0,   0,   0,  60,   1, 
-      0,   0, 112,   1,   0,   0, 
-    120,   2,   0,   0,  82,  68, 
-     69,  70, 120,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   1,   0,   0,   0, 
-     28,   0,   0,   0,   0,   4, 
-    255, 255,   0,   1,   0,   0, 
-     69,   0,   0,   0,  60,   0, 
-      0,   0,   2,   0,   0,   0, 
-      3,   0,   0,   0,   8,   0, 
-      0,   0, 255, 255, 255, 255, 
-      0,   0,   0,   0,   1,   0, 
-      0,   0,  13,   0,   0,   0, 
-     84, 101, 120, 116, 117, 114, 
-    101,  73,   0,  77, 105,  99, 
-    114, 111, 115, 111, 102, 116, 
-     32,  40,  82,  41,  32,  72, 
-     76,  83,  76,  32,  83, 104, 
-     97, 100, 101, 114,  32,  67, 
-    111, 109, 112, 105, 108, 101, 
-    114,  32,  54,  46,  51,  46, 
-     57,  54,  48,  48,  46,  49, 
-     54,  51,  56,  52,   0, 171, 
-     73,  83,  71,  78, 128,   0, 
-      0,   0,   3,   0,   0,   0, 
-      8,   0,   0,   0,  80,   0, 
-      0,   0,   0,   0,   0,   0, 
-      1,   0,   0,   0,   3,   0, 
-      0,   0,   0,   0,   0,   0, 
-     15,   0,   0,   0,  92,   0, 
-      0,   0,   0,   0,   0,   0, 
-      4,   0,   0,   0,   1,   0, 
-      0,   0,   1,   0,   0,   0, 
-      1,   0,   0,   0, 118,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   3,   0, 
-      0,   0,   2,   0,   0,   0, 
-      7,   7,   0,   0,  83,  86, 
-     95,  80,  79,  83,  73,  84, 
-     73,  79,  78,   0,  83,  86, 
-     95,  82,  69,  78,  68,  69, 
-     82,  84,  65,  82,  71,  69, 
-     84,  65,  82,  82,  65,  89, 
-     73,  78,  68,  69,  88,   0, 
-     84,  69,  88,  67,  79,  79, 
-     82,  68,   0, 171,  79,  83, 
-     71,  78,  44,   0,   0,   0, 
-      1,   0,   0,   0,   8,   0, 
-      0,   0,  32,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   2,   0,   0,   0, 
-      0,   0,   0,   0,  15,   0, 
-      0,   0,  83,  86,  95,  84, 
-     65,  82,  71,  69,  84,   0, 
-    171, 171,  83,  72,  68,  82, 
-      0,   1,   0,   0,  64,   0, 
-      0,   0,  64,   0,   0,   0, 
-     88,  40,   0,   4,   0, 112, 
-     16,   0,   0,   0,   0,   0, 
-     51,  51,   0,   0,  98,  16, 
-      0,   3, 114,  16,  16,   0, 
-      2,   0,   0,   0, 101,   0, 
-      0,   3, 242,  32,  16,   0, 
-      0,   0,   0,   0, 104,   0, 
-      0,   2,   1,   0,   0,   0, 
-     61,  16,   0,   7, 242,   0, 
-     16,   0,   0,   0,   0,   0, 
-      1,  64,   0,   0,   0,   0, 
-      0,   0,  70, 126,  16,   0, 
-      0,   0,   0,   0,  86,   0, 
-      0,   5, 114,   0,  16,   0, 
-      0,   0,   0,   0,  70,   2, 
-     16,   0,   0,   0,   0,   0, 
-     56,   0,   0,   7, 114,   0, 
-     16,   0,   0,   0,   0,   0, 
-     70,   2,  16,   0,   0,   0, 
-      0,   0,  70,  18,  16,   0, 
-      2,   0,   0,   0,  27,   0, 
-      0,   5, 114,   0,  16,   0, 
-      0,   0,   0,   0,  70,   2, 
-     16,   0,   0,   0,   0,   0, 
-     54,   0,   0,   5, 130,   0, 
-     16,   0,   0,   0,   0,   0, 
-      1,  64,   0,   0,   0,   0, 
-      0,   0,  45,   0,   0,   7, 
-    242,   0,  16,   0,   0,   0, 
-      0,   0,  70,  14,  16,   0, 
-      0,   0,   0,   0,  70, 126, 
-     16,   0,   0,   0,   0,   0, 
-     54,   0,   0,   5,  50,  32, 
-     16,   0,   0,   0,   0,   0, 
-     70,   0,  16,   0,   0,   0, 
-      0,   0,  54,   0,   0,   8, 
-    194,  32,  16,   0,   0,   0, 
-      0,   0,   2,  64,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,  62,   0, 
-      0,   1,  83,  84,  65,  84, 
-    116,   0,   0,   0,   9,   0, 
-      0,   0,   1,   0,   0,   0, 
-      0,   0,   0,   0,   2,   0, 
-      0,   0,   1,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   1,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   1,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   3,   0,   0,   0, 
-      0,   0,   0,   0,   2,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0
-};
+#if 0
+//
+// Generated by Microsoft (R) HLSL Shader Compiler 6.3.9600.16384
+//
+//
+// Resource Bindings:
+//
+// Name                                 Type  Format         Dim Slot Elements
+// ------------------------------ ---------- ------- ----------- ---- --------
+// TextureI                          texture   sint4          3d    0        1
+//
+//
+//
+// Input signature:
+//
+// Name                 Index   Mask Register SysValue  Format   Used
+// -------------------- ----- ------ -------- -------- ------- ------
+// SV_POSITION              0   xyzw        0      POS   float       
+// SV_RENDERTARGETARRAYINDEX     0   x           1  RTINDEX    uint       
+// TEXCOORD                 0   xyz         2     NONE   float   xyz 
+//
+//
+// Output signature:
+//
+// Name                 Index   Mask Register SysValue  Format   Used
+// -------------------- ----- ------ -------- -------- ------- ------
+// SV_TARGET                0   xyzw        0   TARGET     int   xyzw
+//
+ps_4_0
+dcl_resource_texture3d (sint,sint,sint,sint) t0
+dcl_input_ps linear v2.xyz
+dcl_output o0.xyzw
+dcl_temps 1
+resinfo_uint r0.xyzw, l(0), t0.xyzw
+utof r0.xyz, r0.xyzx
+mul r0.xyz, r0.xyzx, v2.xyzx
+ftoi r0.xyz, r0.xyzx
+mov r0.w, l(0)
+ld r0.xyzw, r0.xyzw, t0.xyzw
+mov o0.xy, r0.xyxx
+mov o0.zw, l(0,0,0,0)
+ret 
+// Approximately 9 instruction slots used
+#endif
+
+const BYTE g_PS_PassthroughRG3DI[] =
+{
+     68,  88,  66,  67,  62, 119, 
+     61,  21,  83,  42,  80, 125, 
+    121, 208, 247,  10, 223,  62, 
+     33,  18,   1,   0,   0,   0, 
+    244,   2,   0,   0,   5,   0, 
+      0,   0,  52,   0,   0,   0, 
+    180,   0,   0,   0,  60,   1, 
+      0,   0, 112,   1,   0,   0, 
+    120,   2,   0,   0,  82,  68, 
+     69,  70, 120,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   1,   0,   0,   0, 
+     28,   0,   0,   0,   0,   4, 
+    255, 255,   0,   1,   0,   0, 
+     69,   0,   0,   0,  60,   0, 
+      0,   0,   2,   0,   0,   0, 
+      3,   0,   0,   0,   8,   0, 
+      0,   0, 255, 255, 255, 255, 
+      0,   0,   0,   0,   1,   0, 
+      0,   0,  13,   0,   0,   0, 
+     84, 101, 120, 116, 117, 114, 
+    101,  73,   0,  77, 105,  99, 
+    114, 111, 115, 111, 102, 116, 
+     32,  40,  82,  41,  32,  72, 
+     76,  83,  76,  32,  83, 104, 
+     97, 100, 101, 114,  32,  67, 
+    111, 109, 112, 105, 108, 101, 
+    114,  32,  54,  46,  51,  46, 
+     57,  54,  48,  48,  46,  49, 
+     54,  51,  56,  52,   0, 171, 
+     73,  83,  71,  78, 128,   0, 
+      0,   0,   3,   0,   0,   0, 
+      8,   0,   0,   0,  80,   0, 
+      0,   0,   0,   0,   0,   0, 
+      1,   0,   0,   0,   3,   0, 
+      0,   0,   0,   0,   0,   0, 
+     15,   0,   0,   0,  92,   0, 
+      0,   0,   0,   0,   0,   0, 
+      4,   0,   0,   0,   1,   0, 
+      0,   0,   1,   0,   0,   0, 
+      1,   0,   0,   0, 118,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   3,   0, 
+      0,   0,   2,   0,   0,   0, 
+      7,   7,   0,   0,  83,  86, 
+     95,  80,  79,  83,  73,  84, 
+     73,  79,  78,   0,  83,  86, 
+     95,  82,  69,  78,  68,  69, 
+     82,  84,  65,  82,  71,  69, 
+     84,  65,  82,  82,  65,  89, 
+     73,  78,  68,  69,  88,   0, 
+     84,  69,  88,  67,  79,  79, 
+     82,  68,   0, 171,  79,  83, 
+     71,  78,  44,   0,   0,   0, 
+      1,   0,   0,   0,   8,   0, 
+      0,   0,  32,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   2,   0,   0,   0, 
+      0,   0,   0,   0,  15,   0, 
+      0,   0,  83,  86,  95,  84, 
+     65,  82,  71,  69,  84,   0, 
+    171, 171,  83,  72,  68,  82, 
+      0,   1,   0,   0,  64,   0, 
+      0,   0,  64,   0,   0,   0, 
+     88,  40,   0,   4,   0, 112, 
+     16,   0,   0,   0,   0,   0, 
+     51,  51,   0,   0,  98,  16, 
+      0,   3, 114,  16,  16,   0, 
+      2,   0,   0,   0, 101,   0, 
+      0,   3, 242,  32,  16,   0, 
+      0,   0,   0,   0, 104,   0, 
+      0,   2,   1,   0,   0,   0, 
+     61,  16,   0,   7, 242,   0, 
+     16,   0,   0,   0,   0,   0, 
+      1,  64,   0,   0,   0,   0, 
+      0,   0,  70, 126,  16,   0, 
+      0,   0,   0,   0,  86,   0, 
+      0,   5, 114,   0,  16,   0, 
+      0,   0,   0,   0,  70,   2, 
+     16,   0,   0,   0,   0,   0, 
+     56,   0,   0,   7, 114,   0, 
+     16,   0,   0,   0,   0,   0, 
+     70,   2,  16,   0,   0,   0, 
+      0,   0,  70,  18,  16,   0, 
+      2,   0,   0,   0,  27,   0, 
+      0,   5, 114,   0,  16,   0, 
+      0,   0,   0,   0,  70,   2, 
+     16,   0,   0,   0,   0,   0, 
+     54,   0,   0,   5, 130,   0, 
+     16,   0,   0,   0,   0,   0, 
+      1,  64,   0,   0,   0,   0, 
+      0,   0,  45,   0,   0,   7, 
+    242,   0,  16,   0,   0,   0, 
+      0,   0,  70,  14,  16,   0, 
+      0,   0,   0,   0,  70, 126, 
+     16,   0,   0,   0,   0,   0, 
+     54,   0,   0,   5,  50,  32, 
+     16,   0,   0,   0,   0,   0, 
+     70,   0,  16,   0,   0,   0, 
+      0,   0,  54,   0,   0,   8, 
+    194,  32,  16,   0,   0,   0, 
+      0,   0,   2,  64,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,  62,   0, 
+      0,   1,  83,  84,  65,  84, 
+    116,   0,   0,   0,   9,   0, 
+      0,   0,   1,   0,   0,   0, 
+      0,   0,   0,   0,   2,   0, 
+      0,   0,   1,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   1,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   1,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   3,   0,   0,   0, 
+      0,   0,   0,   0,   2,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0
+};
--- a/gfx/angle/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrg3dui11ps.h
+++ b/gfx/angle/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrg3dui11ps.h
@@ -1,174 +1,174 @@
-#if 0
-//
-// Generated by Microsoft (R) HLSL Shader Compiler 6.3.9600.16384
-//
-//
-// Resource Bindings:
-//
-// Name                                 Type  Format         Dim Slot Elements
-// ------------------------------ ---------- ------- ----------- ---- --------
-// TextureUI                         texture   uint4          3d    0        1
-//
-//
-//
-// Input signature:
-//
-// Name                 Index   Mask Register SysValue  Format   Used
-// -------------------- ----- ------ -------- -------- ------- ------
-// SV_POSITION              0   xyzw        0      POS   float       
-// SV_RENDERTARGETARRAYINDEX     0   x           1  RTINDEX    uint       
-// TEXCOORD                 0   xyz         2     NONE   float   xyz 
-//
-//
-// Output signature:
-//
-// Name                 Index   Mask Register SysValue  Format   Used
-// -------------------- ----- ------ -------- -------- ------- ------
-// SV_TARGET                0   xyzw        0   TARGET    uint   xyzw
-//
-ps_4_0
-dcl_resource_texture3d (uint,uint,uint,uint) t0
-dcl_input_ps linear v2.xyz
-dcl_output o0.xyzw
-dcl_temps 1
-resinfo_uint r0.xyzw, l(0), t0.xyzw
-utof r0.xyz, r0.xyzx
-mul r0.xyz, r0.xyzx, v2.xyzx
-ftoi r0.xyz, r0.xyzx
-mov r0.w, l(0)
-ld r0.xyzw, r0.xyzw, t0.xyzw
-mov o0.xy, r0.xyxx
-mov o0.zw, l(0,0,0,0)
-ret 
-// Approximately 9 instruction slots used
-#endif
-
-const BYTE g_PS_PassthroughRG3DUI[] =
-{
-     68,  88,  66,  67,  37,  56, 
-     43, 206,  81, 137, 125, 191, 
-    216,  50,  86,  76,  61,  78, 
-     25, 246,   1,   0,   0,   0, 
-    244,   2,   0,   0,   5,   0, 
-      0,   0,  52,   0,   0,   0, 
-    180,   0,   0,   0,  60,   1, 
-      0,   0, 112,   1,   0,   0, 
-    120,   2,   0,   0,  82,  68, 
-     69,  70, 120,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   1,   0,   0,   0, 
-     28,   0,   0,   0,   0,   4, 
-    255, 255,   0,   1,   0,   0, 
-     70,   0,   0,   0,  60,   0, 
-      0,   0,   2,   0,   0,   0, 
-      4,   0,   0,   0,   8,   0, 
-      0,   0, 255, 255, 255, 255, 
-      0,   0,   0,   0,   1,   0, 
-      0,   0,  13,   0,   0,   0, 
-     84, 101, 120, 116, 117, 114, 
-    101,  85,  73,   0,  77, 105, 
-     99, 114, 111, 115, 111, 102, 
-    116,  32,  40,  82,  41,  32, 
-     72,  76,  83,  76,  32,  83, 
-    104,  97, 100, 101, 114,  32, 
-     67, 111, 109, 112, 105, 108, 
-    101, 114,  32,  54,  46,  51, 
-     46,  57,  54,  48,  48,  46, 
-     49,  54,  51,  56,  52,   0, 
-     73,  83,  71,  78, 128,   0, 
-      0,   0,   3,   0,   0,   0, 
-      8,   0,   0,   0,  80,   0, 
-      0,   0,   0,   0,   0,   0, 
-      1,   0,   0,   0,   3,   0, 
-      0,   0,   0,   0,   0,   0, 
-     15,   0,   0,   0,  92,   0, 
-      0,   0,   0,   0,   0,   0, 
-      4,   0,   0,   0,   1,   0, 
-      0,   0,   1,   0,   0,   0, 
-      1,   0,   0,   0, 118,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   3,   0, 
-      0,   0,   2,   0,   0,   0, 
-      7,   7,   0,   0,  83,  86, 
-     95,  80,  79,  83,  73,  84, 
-     73,  79,  78,   0,  83,  86, 
-     95,  82,  69,  78,  68,  69, 
-     82,  84,  65,  82,  71,  69, 
-     84,  65,  82,  82,  65,  89, 
-     73,  78,  68,  69,  88,   0, 
-     84,  69,  88,  67,  79,  79, 
-     82,  68,   0, 171,  79,  83, 
-     71,  78,  44,   0,   0,   0, 
-      1,   0,   0,   0,   8,   0, 
-      0,   0,  32,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   1,   0,   0,   0, 
-      0,   0,   0,   0,  15,   0, 
-      0,   0,  83,  86,  95,  84, 
-     65,  82,  71,  69,  84,   0, 
-    171, 171,  83,  72,  68,  82, 
-      0,   1,   0,   0,  64,   0, 
-      0,   0,  64,   0,   0,   0, 
-     88,  40,   0,   4,   0, 112, 
-     16,   0,   0,   0,   0,   0, 
-     68,  68,   0,   0,  98,  16, 
-      0,   3, 114,  16,  16,   0, 
-      2,   0,   0,   0, 101,   0, 
-      0,   3, 242,  32,  16,   0, 
-      0,   0,   0,   0, 104,   0, 
-      0,   2,   1,   0,   0,   0, 
-     61,  16,   0,   7, 242,   0, 
-     16,   0,   0,   0,   0,   0, 
-      1,  64,   0,   0,   0,   0, 
-      0,   0,  70, 126,  16,   0, 
-      0,   0,   0,   0,  86,   0, 
-      0,   5, 114,   0,  16,   0, 
-      0,   0,   0,   0,  70,   2, 
-     16,   0,   0,   0,   0,   0, 
-     56,   0,   0,   7, 114,   0, 
-     16,   0,   0,   0,   0,   0, 
-     70,   2,  16,   0,   0,   0, 
-      0,   0,  70,  18,  16,   0, 
-      2,   0,   0,   0,  27,   0, 
-      0,   5, 114,   0,  16,   0, 
-      0,   0,   0,   0,  70,   2, 
-     16,   0,   0,   0,   0,   0, 
-     54,   0,   0,   5, 130,   0, 
-     16,   0,   0,   0,   0,   0, 
-      1,  64,   0,   0,   0,   0, 
-      0,   0,  45,   0,   0,   7, 
-    242,   0,  16,   0,   0,   0, 
-      0,   0,  70,  14,  16,   0, 
-      0,   0,   0,   0,  70, 126, 
-     16,   0,   0,   0,   0,   0, 
-     54,   0,   0,   5,  50,  32, 
-     16,   0,   0,   0,   0,   0, 
-     70,   0,  16,   0,   0,   0, 
-      0,   0,  54,   0,   0,   8, 
-    194,  32,  16,   0,   0,   0, 
-      0,   0,   2,  64,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,  62,   0, 
-      0,   1,  83,  84,  65,  84, 
-    116,   0,   0,   0,   9,   0, 
-      0,   0,   1,   0,   0,   0, 
-      0,   0,   0,   0,   2,   0, 
-      0,   0,   1,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   1,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   1,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   3,   0,   0,   0, 
-      0,   0,   0,   0,   2,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0
-};
+#if 0
+//
+// Generated by Microsoft (R) HLSL Shader Compiler 6.3.9600.16384
+//
+//
+// Resource Bindings:
+//
+// Name                                 Type  Format         Dim Slot Elements
+// ------------------------------ ---------- ------- ----------- ---- --------
+// TextureUI                         texture   uint4          3d    0        1
+//
+//
+//
+// Input signature:
+//
+// Name                 Index   Mask Register SysValue  Format   Used
+// -------------------- ----- ------ -------- -------- ------- ------
+// SV_POSITION              0   xyzw        0      POS   float       
+// SV_RENDERTARGETARRAYINDEX     0   x           1  RTINDEX    uint       
+// TEXCOORD                 0   xyz         2     NONE   float   xyz 
+//
+//
+// Output signature:
+//
+// Name                 Index   Mask Register SysValue  Format   Used
+// -------------------- ----- ------ -------- -------- ------- ------
+// SV_TARGET                0   xyzw        0   TARGET    uint   xyzw
+//
+ps_4_0
+dcl_resource_texture3d (uint,uint,uint,uint) t0
+dcl_input_ps linear v2.xyz
+dcl_output o0.xyzw
+dcl_temps 1
+resinfo_uint r0.xyzw, l(0), t0.xyzw
+utof r0.xyz, r0.xyzx
+mul r0.xyz, r0.xyzx, v2.xyzx
+ftoi r0.xyz, r0.xyzx
+mov r0.w, l(0)
+ld r0.xyzw, r0.xyzw, t0.xyzw
+mov o0.xy, r0.xyxx
+mov o0.zw, l(0,0,0,0)
+ret 
+// Approximately 9 instruction slots used
+#endif
+
+const BYTE g_PS_PassthroughRG3DUI[] =
+{
+     68,  88,  66,  67,  37,  56, 
+     43, 206,  81, 137, 125, 191, 
+    216,  50,  86,  76,  61,  78, 
+     25, 246,   1,   0,   0,   0, 
+    244,   2,   0,   0,   5,   0, 
+      0,   0,  52,   0,   0,   0, 
+    180,   0,   0,   0,  60,   1, 
+      0,   0, 112,   1,   0,   0, 
+    120,   2,   0,   0,  82,  68, 
+     69,  70, 120,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   1,   0,   0,   0, 
+     28,   0,   0,   0,   0,   4, 
+    255, 255,   0,   1,   0,   0, 
+     70,   0,   0,   0,  60,   0, 
+      0,   0,   2,   0,   0,   0, 
+      4,   0,   0,   0,   8,   0, 
+      0,   0, 255, 255, 255, 255, 
+      0,   0,   0,   0,   1,   0, 
+      0,   0,  13,   0,   0,   0, 
+     84, 101, 120, 116, 117, 114, 
+    101,  85,  73,   0,  77, 105, 
+     99, 114, 111, 115, 111, 102, 
+    116,  32,  40,  82,  41,  32, 
+     72,  76,  83,  76,  32,  83, 
+    104,  97, 100, 101, 114,  32, 
+     67, 111, 109, 112, 105, 108, 
+    101, 114,  32,  54,  46,  51, 
+     46,  57,  54,  48,  48,  46, 
+     49,  54,  51,  56,  52,   0, 
+     73,  83,  71,  78, 128,   0, 
+      0,   0,   3,   0,   0,   0, 
+      8,   0,   0,   0,  80,   0, 
+      0,   0,   0,   0,   0,   0, 
+      1,   0,   0,   0,   3,   0, 
+      0,   0,   0,   0,   0,   0, 
+     15,   0,   0,   0,  92,   0, 
+      0,   0,   0,   0,   0,   0, 
+      4,   0,   0,   0,   1,   0, 
+      0,   0,   1,   0,   0,   0, 
+      1,   0,   0,   0, 118,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   3,   0, 
+      0,   0,   2,   0,   0,   0, 
+      7,   7,   0,   0,  83,  86, 
+     95,  80,  79,  83,  73,  84, 
+     73,  79,  78,   0,  83,  86, 
+     95,  82,  69,  78,  68,  69, 
+     82,  84,  65,  82,  71,  69, 
+     84,  65,  82,  82,  65,  89, 
+     73,  78,  68,  69,  88,   0, 
+     84,  69,  88,  67,  79,  79, 
+     82,  68,   0, 171,  79,  83, 
+     71,  78,  44,   0,   0,   0, 
+      1,   0,   0,   0,   8,   0, 
+      0,   0,  32,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   1,   0,   0,   0, 
+      0,   0,   0,   0,  15,   0, 
+      0,   0,  83,  86,  95,  84, 
+     65,  82,  71,  69,  84,   0, 
+    171, 171,  83,  72,  68,  82, 
+      0,   1,   0,   0,  64,   0, 
+      0,   0,  64,   0,   0,   0, 
+     88,  40,   0,   4,   0, 112, 
+     16,   0,   0,   0,   0,   0, 
+     68,  68,   0,   0,  98,  16, 
+      0,   3, 114,  16,  16,   0, 
+      2,   0,   0,   0, 101,   0, 
+      0,   3, 242,  32,  16,   0, 
+      0,   0,   0,   0, 104,   0, 
+      0,   2,   1,   0,   0,   0, 
+     61,  16,   0,   7, 242,   0, 
+     16,   0,   0,   0,   0,   0, 
+      1,  64,   0,   0,   0,   0, 
+      0,   0,  70, 126,  16,   0, 
+      0,   0,   0,   0,  86,   0, 
+      0,   5, 114,   0,  16,   0, 
+      0,   0,   0,   0,  70,   2, 
+     16,   0,   0,   0,   0,   0, 
+     56,   0,   0,   7, 114,   0, 
+     16,   0,   0,   0,   0,   0, 
+     70,   2,  16,   0,   0,   0, 
+      0,   0,  70,  18,  16,   0, 
+      2,   0,   0,   0,  27,   0, 
+      0,   5, 114,   0,  16,   0, 
+      0,   0,   0,   0,  70,   2, 
+     16,   0,   0,   0,   0,   0, 
+     54,   0,   0,   5, 130,   0, 
+     16,   0,   0,   0,   0,   0, 
+      1,  64,   0,   0,   0,   0, 
+      0,   0,  45,   0,   0,   7, 
+    242,   0,  16,   0,   0,   0, 
+      0,   0,  70,  14,  16,   0, 
+      0,   0,   0,   0,  70, 126, 
+     16,   0,   0,   0,   0,   0, 
+     54,   0,   0,   5,  50,  32, 
+     16,   0,   0,   0,   0,   0, 
+     70,   0,  16,   0,   0,   0, 
+      0,   0,  54,   0,   0,   8, 
+    194,  32,  16,   0,   0,   0, 
+      0,   0,   2,  64,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,  62,   0, 
+      0,   1,  83,  84,  65,  84, 
+    116,   0,   0,   0,   9,   0, 
+      0,   0,   1,   0,   0,   0, 
+      0,   0,   0,   0,   2,   0, 
+      0,   0,   1,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   1,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   1,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   3,   0,   0,   0, 
+      0,   0,   0,   0,   2,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0
+};
--- a/gfx/angle/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrgb2d11ps.h
+++ b/gfx/angle/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrgb2d11ps.h
@@ -1,196 +1,196 @@
-#if 0
-//
-// Generated by Microsoft (R) HLSL Shader Compiler 6.3.9600.16384
-//
-//
-// Resource Bindings:
-//
-// Name                                 Type  Format         Dim Slot Elements
-// ------------------------------ ---------- ------- ----------- ---- --------
-// Sampler                           sampler      NA          NA    0        1
-// TextureF                          texture  float4          2d    0        1
-//
-//
-//
-// Input signature:
-//
-// Name                 Index   Mask Register SysValue  Format   Used
-// -------------------- ----- ------ -------- -------- ------- ------
-// SV_POSITION              0   xyzw        0      POS   float       
-// TEXCOORD                 0   xy          1     NONE   float   xy  
-//
-//
-// Output signature:
-//
-// Name                 Index   Mask Register SysValue  Format   Used
-// -------------------- ----- ------ -------- -------- ------- ------
-// SV_TARGET                0   xyzw        0   TARGET   float   xyzw
-//
-//
-// Sampler/Resource to DX9 shader sampler mappings:
-//
-// Target Sampler Source Sampler  Source Resource
-// -------------- --------------- ----------------
-// s0             s0              t0               
-//
-//
-// Level9 shader bytecode:
-//
-    ps_2_x
-    def c0, 1, 0, 0, 0
-    dcl t0.xy
-    dcl_2d s0
-    texld r0, t0, s0
-    mad r0, r0.xyzx, c0.xxxy, c0.yyyx
-    mov oC0, r0
-
-// approximately 3 instruction slots used (1 texture, 2 arithmetic)
-ps_4_0
-dcl_sampler s0, mode_default
-dcl_resource_texture2d (float,float,float,float) t0
-dcl_input_ps linear v1.xy
-dcl_output o0.xyzw
-dcl_temps 1
-sample r0.xyzw, v1.xyxx, t0.xyzw, s0
-mov o0.xyz, r0.xyzx
-mov o0.w, l(1.000000)
-ret 
-// Approximately 4 instruction slots used
-#endif
-
-const BYTE g_PS_PassthroughRGB2D[] =
-{
-     68,  88,  66,  67,  51,  90, 
-     49, 167, 211,  79,  20, 215, 
-     57, 227,  70,  56, 132, 117, 
-     66, 156,   1,   0,   0,   0, 
-     28,   3,   0,   0,   6,   0, 
-      0,   0,  56,   0,   0,   0, 
-    208,   0,   0,   0, 108,   1, 
-      0,   0, 232,   1,   0,   0, 
-    144,   2,   0,   0, 232,   2, 
-      0,   0,  65, 111, 110,  57, 
-    144,   0,   0,   0, 144,   0, 
-      0,   0,   0,   2, 255, 255, 
-    104,   0,   0,   0,  40,   0, 
-      0,   0,   0,   0,  40,   0, 
-      0,   0,  40,   0,   0,   0, 
-     40,   0,   1,   0,  36,   0, 
-      0,   0,  40,   0,   0,   0, 
-      0,   0,   1,   2, 255, 255, 
-     81,   0,   0,   5,   0,   0, 
-     15, 160,   0,   0, 128,  63, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-     31,   0,   0,   2,   0,   0, 
-      0, 128,   0,   0,   3, 176, 
-     31,   0,   0,   2,   0,   0, 
-      0, 144,   0,   8,  15, 160, 
-     66,   0,   0,   3,   0,   0, 
-     15, 128,   0,   0, 228, 176, 
-      0,   8, 228, 160,   4,   0, 
-      0,   4,   0,   0,  15, 128, 
-      0,   0,  36, 128,   0,   0, 
-     64, 160,   0,   0,  21, 160, 
-      1,   0,   0,   2,   0,   8, 
-     15, 128,   0,   0, 228, 128, 
-    255, 255,   0,   0,  83,  72, 
-     68,  82, 148,   0,   0,   0, 
-     64,   0,   0,   0,  37,   0, 
-      0,   0,  90,   0,   0,   3, 
-      0,  96,  16,   0,   0,   0, 
-      0,   0,  88,  24,   0,   4, 
-      0, 112,  16,   0,   0,   0, 
-      0,   0,  85,  85,   0,   0, 
-     98,  16,   0,   3,  50,  16, 
-     16,   0,   1,   0,   0,   0, 
-    101,   0,   0,   3, 242,  32, 
-     16,   0,   0,   0,   0,   0, 
-    104,   0,   0,   2,   1,   0, 
-      0,   0,  69,   0,   0,   9, 
-    242,   0,  16,   0,   0,   0, 
-      0,   0,  70,  16,  16,   0, 
-      1,   0,   0,   0,  70, 126, 
-     16,   0,   0,   0,   0,   0, 
-      0,  96,  16,   0,   0,   0, 
-      0,   0,  54,   0,   0,   5, 
-    114,  32,  16,   0,   0,   0, 
-      0,   0,  70,   2,  16,   0, 
-      0,   0,   0,   0,  54,   0, 
-      0,   5, 130,  32,  16,   0, 
-      0,   0,   0,   0,   1,  64, 
-      0,   0,   0,   0, 128,  63, 
-     62,   0,   0,   1,  83,  84, 
-     65,  84, 116,   0,   0,   0, 
-      4,   0,   0,   0,   1,   0, 
-      0,   0,   0,   0,   0,   0, 
-      2,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   1,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   1,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   2,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,  82,  68,  69,  70, 
-    160,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      2,   0,   0,   0,  28,   0, 
-      0,   0,   0,   4, 255, 255, 
-      0,   1,   0,   0, 109,   0, 
-      0,   0,  92,   0,   0,   0, 
-      3,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   1,   0,   0,   0, 
-      1,   0,   0,   0, 100,   0, 
-      0,   0,   2,   0,   0,   0, 
-      5,   0,   0,   0,   4,   0, 
-      0,   0, 255, 255, 255, 255, 
-      0,   0,   0,   0,   1,   0, 
-      0,   0,  13,   0,   0,   0, 
-     83,  97, 109, 112, 108, 101, 
-    114,   0,  84, 101, 120, 116, 
-    117, 114, 101,  70,   0,  77, 
-    105,  99, 114, 111, 115, 111, 
-    102, 116,  32,  40,  82,  41, 
-     32,  72,  76,  83,  76,  32, 
-     83, 104,  97, 100, 101, 114, 
-     32,  67, 111, 109, 112, 105, 
-    108, 101, 114,  32,  54,  46, 
-     51,  46,  57,  54,  48,  48, 
-     46,  49,  54,  51,  56,  52, 
-      0, 171,  73,  83,  71,  78, 
-     80,   0,   0,   0,   2,   0, 
-      0,   0,   8,   0,   0,   0, 
-     56,   0,   0,   0,   0,   0, 
-      0,   0,   1,   0,   0,   0, 
-      3,   0,   0,   0,   0,   0, 
-      0,   0,  15,   0,   0,   0, 
-     68,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      3,   0,   0,   0,   1,   0, 
-      0,   0,   3,   3,   0,   0, 
-     83,  86,  95,  80,  79,  83, 
-     73,  84,  73,  79,  78,   0, 
-     84,  69,  88,  67,  79,  79, 
-     82,  68,   0, 171, 171, 171, 
-     79,  83,  71,  78,  44,   0, 
-      0,   0,   1,   0,   0,   0, 
-      8,   0,   0,   0,  32,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   3,   0, 
-      0,   0,   0,   0,   0,   0, 
-     15,   0,   0,   0,  83,  86, 
-     95,  84,  65,  82,  71,  69, 
-     84,   0, 171, 171
-};
+#if 0
+//
+// Generated by Microsoft (R) HLSL Shader Compiler 6.3.9600.16384
+//
+//
+// Resource Bindings:
+//
+// Name                                 Type  Format         Dim Slot Elements
+// ------------------------------ ---------- ------- ----------- ---- --------
+// Sampler                           sampler      NA          NA    0        1
+// TextureF                          texture  float4          2d    0        1
+//
+//
+//
+// Input signature:
+//
+// Name                 Index   Mask Register SysValue  Format   Used
+// -------------------- ----- ------ -------- -------- ------- ------
+// SV_POSITION              0   xyzw        0      POS   float       
+// TEXCOORD                 0   xy          1     NONE   float   xy  
+//
+//
+// Output signature:
+//
+// Name                 Index   Mask Register SysValue  Format   Used
+// -------------------- ----- ------ -------- -------- ------- ------
+// SV_TARGET                0   xyzw        0   TARGET   float   xyzw
+//
+//
+// Sampler/Resource to DX9 shader sampler mappings:
+//
+// Target Sampler Source Sampler  Source Resource
+// -------------- --------------- ----------------
+// s0             s0              t0               
+//
+//
+// Level9 shader bytecode:
+//
+    ps_2_x
+    def c0, 1, 0, 0, 0
+    dcl t0.xy
+    dcl_2d s0
+    texld r0, t0, s0
+    mad r0, r0.xyzx, c0.xxxy, c0.yyyx
+    mov oC0, r0
+
+// approximately 3 instruction slots used (1 texture, 2 arithmetic)
+ps_4_0
+dcl_sampler s0, mode_default
+dcl_resource_texture2d (float,float,float,float) t0
+dcl_input_ps linear v1.xy
+dcl_output o0.xyzw
+dcl_temps 1
+sample r0.xyzw, v1.xyxx, t0.xyzw, s0
+mov o0.xyz, r0.xyzx
+mov o0.w, l(1.000000)
+ret 
+// Approximately 4 instruction slots used
+#endif
+
+const BYTE g_PS_PassthroughRGB2D[] =
+{
+     68,  88,  66,  67,  51,  90, 
+     49, 167, 211,  79,  20, 215, 
+     57, 227,  70,  56, 132, 117, 
+     66, 156,   1,   0,   0,   0, 
+     28,   3,   0,   0,   6,   0, 
+      0,   0,  56,   0,   0,   0, 
+    208,   0,   0,   0, 108,   1, 
+      0,   0, 232,   1,   0,   0, 
+    144,   2,   0,   0, 232,   2, 
+      0,   0,  65, 111, 110,  57, 
+    144,   0,   0,   0, 144,   0, 
+      0,   0,   0,   2, 255, 255, 
+    104,   0,   0,   0,  40,   0, 
+      0,   0,   0,   0,  40,   0, 
+      0,   0,  40,   0,   0,   0, 
+     40,   0,   1,   0,  36,   0, 
+      0,   0,  40,   0,   0,   0, 
+      0,   0,   1,   2, 255, 255, 
+     81,   0,   0,   5,   0,   0, 
+     15, 160,   0,   0, 128,  63, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+     31,   0,   0,   2,   0,   0, 
+      0, 128,   0,   0,   3, 176, 
+     31,   0,   0,   2,   0,   0, 
+      0, 144,   0,   8,  15, 160, 
+     66,   0,   0,   3,   0,   0, 
+     15, 128,   0,   0, 228, 176, 
+      0,   8, 228, 160,   4,   0, 
+      0,   4,   0,   0,  15, 128, 
+      0,   0,  36, 128,   0,   0, 
+     64, 160,   0,   0,  21, 160, 
+      1,   0,   0,   2,   0,   8, 
+     15, 128,   0,   0, 228, 128, 
+    255, 255,   0,   0,  83,  72, 
+     68,  82, 148,   0,   0,   0, 
+     64,   0,   0,   0,  37,   0, 
+      0,   0,  90,   0,   0,   3, 
+      0,  96,  16,   0,   0,   0, 
+      0,   0,  88,  24,   0,   4, 
+      0, 112,  16,   0,   0,   0, 
+      0,   0,  85,  85,   0,   0, 
+     98,  16,   0,   3,  50,  16, 
+     16,   0,   1,   0,   0,   0, 
+    101,   0,   0,   3, 242,  32, 
+     16,   0,   0,   0,   0,   0, 
+    104,   0,   0,   2,   1,   0, 
+      0,   0,  69,   0,   0,   9, 
+    242,   0,  16,   0,   0,   0, 
+      0,   0,  70,  16,  16,   0, 
+      1,   0,   0,   0,  70, 126, 
+     16,   0,   0,   0,   0,   0, 
+      0,  96,  16,   0,   0,   0, 
+      0,   0,  54,   0,   0,   5, 
+    114,  32,  16,   0,   0,   0, 
+      0,   0,  70,   2,  16,   0, 
+      0,   0,   0,   0,  54,   0, 
+      0,   5, 130,  32,  16,   0, 
+      0,   0,   0,   0,   1,  64, 
+      0,   0,   0,   0, 128,  63, 
+     62,   0,   0,   1,  83,  84, 
+     65,  84, 116,   0,   0,   0, 
+      4,   0,   0,   0,   1,   0, 
+      0,   0,   0,   0,   0,   0, 
+      2,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   1,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   1,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   2,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,  82,  68,  69,  70, 
+    160,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      2,   0,   0,   0,  28,   0, 
+      0,   0,   0,   4, 255, 255, 
+      0,   1,   0,   0, 109,   0, 
+      0,   0,  92,   0,   0,   0, 
+      3,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   1,   0,   0,   0, 
+      1,   0,   0,   0, 100,   0, 
+      0,   0,   2,   0,   0,   0, 
+      5,   0,   0,   0,   4,   0, 
+      0,   0, 255, 255, 255, 255, 
+      0,   0,   0,   0,   1,   0, 
+      0,   0,  13,   0,   0,   0, 
+     83,  97, 109, 112, 108, 101, 
+    114,   0,  84, 101, 120, 116, 
+    117, 114, 101,  70,   0,  77, 
+    105,  99, 114, 111, 115, 111, 
+    102, 116,  32,  40,  82,  41, 
+     32,  72,  76,  83,  76,  32, 
+     83, 104,  97, 100, 101, 114, 
+     32,  67, 111, 109, 112, 105, 
+    108, 101, 114,  32,  54,  46, 
+     51,  46,  57,  54,  48,  48, 
+     46,  49,  54,  51,  56,  52, 
+      0, 171,  73,  83,  71,  78, 
+     80,   0,   0,   0,   2,   0, 
+      0,   0,   8,   0,   0,   0, 
+     56,   0,   0,   0,   0,   0, 
+      0,   0,   1,   0,   0,   0, 
+      3,   0,   0,   0,   0,   0, 
+      0,   0,  15,   0,   0,   0, 
+     68,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      3,   0,   0,   0,   1,   0, 
+      0,   0,   3,   3,   0,   0, 
+     83,  86,  95,  80,  79,  83, 
+     73,  84,  73,  79,  78,   0, 
+     84,  69,  88,  67,  79,  79, 
+     82,  68,   0, 171, 171, 171, 
+     79,  83,  71,  78,  44,   0, 
+      0,   0,   1,   0,   0,   0, 
+      8,   0,   0,   0,  32,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   3,   0, 
+      0,   0,   0,   0,   0,   0, 
+     15,   0,   0,   0,  83,  86, 
+     95,  84,  65,  82,  71,  69, 
+     84,   0, 171, 171
+};
--- a/gfx/angle/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrgb2di11ps.h
+++ b/gfx/angle/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrgb2di11ps.h
@@ -1,165 +1,165 @@
-#if 0
-//
-// Generated by Microsoft (R) HLSL Shader Compiler 6.3.9600.16384
-//
-//
-// Resource Bindings:
-//
-// Name                                 Type  Format         Dim Slot Elements
-// ------------------------------ ---------- ------- ----------- ---- --------
-// TextureI                          texture   sint4          2d    0        1
-//
-//
-//
-// Input signature:
-//
-// Name                 Index   Mask Register SysValue  Format   Used
-// -------------------- ----- ------ -------- -------- ------- ------
-// SV_POSITION              0   xyzw        0      POS   float       
-// TEXCOORD                 0   xy          1     NONE   float   xy  
-//
-//
-// Output signature:
-//
-// Name                 Index   Mask Register SysValue  Format   Used
-// -------------------- ----- ------ -------- -------- ------- ------
-// SV_TARGET                0   xyzw        0   TARGET     int   xyzw
-//
-ps_4_0
-dcl_resource_texture2d (sint,sint,sint,sint) t0
-dcl_input_ps linear v1.xy
-dcl_output o0.xyzw
-dcl_temps 1
-resinfo_uint r0.xyzw, l(0), t0.xyzw
-utof r0.xy, r0.xyxx
-mul r0.xy, r0.xyxx, v1.xyxx
-ftoi r0.xy, r0.xyxx
-mov r0.zw, l(0,0,0,0)
-ld r0.xyzw, r0.xyzw, t0.xyzw
-mov o0.xyz, r0.xyzx
-mov o0.w, l(0)
-ret 
-// Approximately 9 instruction slots used
-#endif
-
-const BYTE g_PS_PassthroughRGB2DI[] =
-{
-     68,  88,  66,  67,  16, 227, 
-    172, 190, 246, 118, 223, 239, 
-    176,  78,  90,  11, 135, 138, 
-    109, 174,   1,   0,   0,   0, 
-    196,   2,   0,   0,   5,   0, 
-      0,   0,  52,   0,   0,   0, 
-    180,   0,   0,   0,  12,   1, 
-      0,   0,  64,   1,   0,   0, 
-     72,   2,   0,   0,  82,  68, 
-     69,  70, 120,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   1,   0,   0,   0, 
-     28,   0,   0,   0,   0,   4, 
-    255, 255,   0,   1,   0,   0, 
-     69,   0,   0,   0,  60,   0, 
-      0,   0,   2,   0,   0,   0, 
-      3,   0,   0,   0,   4,   0, 
-      0,   0, 255, 255, 255, 255, 
-      0,   0,   0,   0,   1,   0, 
-      0,   0,  13,   0,   0,   0, 
-     84, 101, 120, 116, 117, 114, 
-    101,  73,   0,  77, 105,  99, 
-    114, 111, 115, 111, 102, 116, 
-     32,  40,  82,  41,  32,  72, 
-     76,  83,  76,  32,  83, 104, 
-     97, 100, 101, 114,  32,  67, 
-    111, 109, 112, 105, 108, 101, 
-    114,  32,  54,  46,  51,  46, 
-     57,  54,  48,  48,  46,  49, 
-     54,  51,  56,  52,   0, 171, 
-     73,  83,  71,  78,  80,   0, 
-      0,   0,   2,   0,   0,   0, 
-      8,   0,   0,   0,  56,   0, 
-      0,   0,   0,   0,   0,   0, 
-      1,   0,   0,   0,   3,   0, 
-      0,   0,   0,   0,   0,   0, 
-     15,   0,   0,   0,  68,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   3,   0, 
-      0,   0,   1,   0,   0,   0, 
-      3,   3,   0,   0,  83,  86, 
-     95,  80,  79,  83,  73,  84, 
-     73,  79,  78,   0,  84,  69, 
-     88,  67,  79,  79,  82,  68, 
-      0, 171, 171, 171,  79,  83, 
-     71,  78,  44,   0,   0,   0, 
-      1,   0,   0,   0,   8,   0, 
-      0,   0,  32,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   2,   0,   0,   0, 
-      0,   0,   0,   0,  15,   0, 
-      0,   0,  83,  86,  95,  84, 
-     65,  82,  71,  69,  84,   0, 
-    171, 171,  83,  72,  68,  82, 
-      0,   1,   0,   0,  64,   0, 
-      0,   0,  64,   0,   0,   0, 
-     88,  24,   0,   4,   0, 112, 
-     16,   0,   0,   0,   0,   0, 
-     51,  51,   0,   0,  98,  16, 
-      0,   3,  50,  16,  16,   0, 
-      1,   0,   0,   0, 101,   0, 
-      0,   3, 242,  32,  16,   0, 
-      0,   0,   0,   0, 104,   0, 
-      0,   2,   1,   0,   0,   0, 
-     61,  16,   0,   7, 242,   0, 
-     16,   0,   0,   0,   0,   0, 
-      1,  64,   0,   0,   0,   0, 
-      0,   0,  70, 126,  16,   0, 
-      0,   0,   0,   0,  86,   0, 
-      0,   5,  50,   0,  16,   0, 
-      0,   0,   0,   0,  70,   0, 
-     16,   0,   0,   0,   0,   0, 
-     56,   0,   0,   7,  50,   0, 
-     16,   0,   0,   0,   0,   0, 
-     70,   0,  16,   0,   0,   0, 
-      0,   0,  70,  16,  16,   0, 
-      1,   0,   0,   0,  27,   0, 
-      0,   5,  50,   0,  16,   0, 
-      0,   0,   0,   0,  70,   0, 
-     16,   0,   0,   0,   0,   0, 
-     54,   0,   0,   8, 194,   0, 
-     16,   0,   0,   0,   0,   0, 
-      2,  64,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,  45,   0,   0,   7, 
-    242,   0,  16,   0,   0,   0, 
-      0,   0,  70,  14,  16,   0, 
-      0,   0,   0,   0,  70, 126, 
-     16,   0,   0,   0,   0,   0, 
-     54,   0,   0,   5, 114,  32, 
-     16,   0,   0,   0,   0,   0, 
-     70,   2,  16,   0,   0,   0, 
-      0,   0,  54,   0,   0,   5, 
-    130,  32,  16,   0,   0,   0, 
-      0,   0,   1,  64,   0,   0, 
-      0,   0,   0,   0,  62,   0, 
-      0,   1,  83,  84,  65,  84, 
-    116,   0,   0,   0,   9,   0, 
-      0,   0,   1,   0,   0,   0, 
-      0,   0,   0,   0,   2,   0, 
-      0,   0,   1,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   1,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   1,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   3,   0,   0,   0, 
-      0,   0,   0,   0,   2,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0
-};
+#if 0
+//
+// Generated by Microsoft (R) HLSL Shader Compiler 6.3.9600.16384
+//
+//
+// Resource Bindings:
+//
+// Name                                 Type  Format         Dim Slot Elements
+// ------------------------------ ---------- ------- ----------- ---- --------
+// TextureI                          texture   sint4          2d    0        1
+//
+//
+//
+// Input signature:
+//
+// Name                 Index   Mask Register SysValue  Format   Used
+// -------------------- ----- ------ -------- -------- ------- ------
+// SV_POSITION              0   xyzw        0      POS   float       
+// TEXCOORD                 0   xy          1     NONE   float   xy  
+//
+//
+// Output signature:
+//
+// Name                 Index   Mask Register SysValue  Format   Used
+// -------------------- ----- ------ -------- -------- ------- ------
+// SV_TARGET                0   xyzw        0   TARGET     int   xyzw
+//
+ps_4_0
+dcl_resource_texture2d (sint,sint,sint,sint) t0
+dcl_input_ps linear v1.xy
+dcl_output o0.xyzw
+dcl_temps 1
+resinfo_uint r0.xyzw, l(0), t0.xyzw
+utof r0.xy, r0.xyxx
+mul r0.xy, r0.xyxx, v1.xyxx
+ftoi r0.xy, r0.xyxx
+mov r0.zw, l(0,0,0,0)
+ld r0.xyzw, r0.xyzw, t0.xyzw
+mov o0.xyz, r0.xyzx
+mov o0.w, l(0)
+ret 
+// Approximately 9 instruction slots used
+#endif
+
+const BYTE g_PS_PassthroughRGB2DI[] =
+{
+     68,  88,  66,  67,  16, 227, 
+    172, 190, 246, 118, 223, 239, 
+    176,  78,  90,  11, 135, 138, 
+    109, 174,   1,   0,   0,   0, 
+    196,   2,   0,   0,   5,   0, 
+      0,   0,  52,   0,   0,   0, 
+    180,   0,   0,   0,  12,   1, 
+      0,   0,  64,   1,   0,   0, 
+     72,   2,   0,   0,  82,  68, 
+     69,  70, 120,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   1,   0,   0,   0, 
+     28,   0,   0,   0,   0,   4, 
+    255, 255,   0,   1,   0,   0, 
+     69,   0,   0,   0,  60,   0, 
+      0,   0,   2,   0,   0,   0, 
+      3,   0,   0,   0,   4,   0, 
+      0,   0, 255, 255, 255, 255, 
+      0,   0,   0,   0,   1,   0, 
+      0,   0,  13,   0,   0,   0, 
+     84, 101, 120, 116, 117, 114, 
+    101,  73,   0,  77, 105,  99, 
+    114, 111, 115, 111, 102, 116, 
+     32,  40,  82,  41,  32,  72, 
+     76,  83,  76,  32,  83, 104, 
+     97, 100, 101, 114,  32,  67, 
+    111, 109, 112, 105, 108, 101, 
+    114,  32,  54,  46,  51,  46, 
+     57,  54,  48,  48,  46,  49, 
+     54,  51,  56,  52,   0, 171, 
+     73,  83,  71,  78,  80,   0, 
+      0,   0,   2,   0,   0,   0, 
+      8,   0,   0,   0,  56,   0, 
+      0,   0,   0,   0,   0,   0, 
+      1,   0,   0,   0,   3,   0, 
+      0,   0,   0,   0,   0,   0, 
+     15,   0,   0,   0,  68,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   3,   0, 
+      0,   0,   1,   0,   0,   0, 
+      3,   3,   0,   0,  83,  86, 
+     95,  80,  79,  83,  73,  84, 
+     73,  79,  78,   0,  84,  69, 
+     88,  67,  79,  79,  82,  68, 
+      0, 171, 171, 171,  79,  83, 
+     71,  78,  44,   0,   0,   0, 
+      1,   0,   0,   0,   8,   0, 
+      0,   0,  32,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   2,   0,   0,   0, 
+      0,   0,   0,   0,  15,   0, 
+      0,   0,  83,  86,  95,  84, 
+     65,  82,  71,  69,  84,   0, 
+    171, 171,  83,  72,  68,  82, 
+      0,   1,   0,   0,  64,   0, 
+      0,   0,  64,   0,   0,   0, 
+     88,  24,   0,   4,   0, 112, 
+     16,   0,   0,   0,   0,   0, 
+     51,  51,   0,   0,  98,  16, 
+      0,   3,  50,  16,  16,   0, 
+      1,   0,   0,   0, 101,   0, 
+      0,   3, 242,  32,  16,   0, 
+      0,   0,   0,   0, 104,   0, 
+      0,   2,   1,   0,   0,   0, 
+     61,  16,   0,   7, 242,   0, 
+     16,   0,   0,   0,   0,   0, 
+      1,  64,   0,   0,   0,   0, 
+      0,   0,  70, 126,  16,   0, 
+      0,   0,   0,   0,  86,   0, 
+      0,   5,  50,   0,  16,   0, 
+      0,   0,   0,   0,  70,   0, 
+     16,   0,   0,   0,   0,   0, 
+     56,   0,   0,   7,  50,   0, 
+     16,   0,   0,   0,   0,   0, 
+     70,   0,  16,   0,   0,   0, 
+      0,   0,  70,  16,  16,   0, 
+      1,   0,   0,   0,  27,   0, 
+      0,   5,  50,   0,  16,   0, 
+      0,   0,   0,   0,  70,   0, 
+     16,   0,   0,   0,   0,   0, 
+     54,   0,   0,   8, 194,   0, 
+     16,   0,   0,   0,   0,   0, 
+      2,  64,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,  45,   0,   0,   7, 
+    242,   0,  16,   0,   0,   0, 
+      0,   0,  70,  14,  16,   0, 
+      0,   0,   0,   0,  70, 126, 
+     16,   0,   0,   0,   0,   0, 
+     54,   0,   0,   5, 114,  32, 
+     16,   0,   0,   0,   0,   0, 
+     70,   2,  16,   0,   0,   0, 
+      0,   0,  54,   0,   0,   5, 
+    130,  32,  16,   0,   0,   0, 
+      0,   0,   1,  64,   0,   0, 
+      0,   0,   0,   0,  62,   0, 
+      0,   1,  83,  84,  65,  84, 
+    116,   0,   0,   0,   9,   0, 
+      0,   0,   1,   0,   0,   0, 
+      0,   0,   0,   0,   2,   0, 
+      0,   0,   1,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   1,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   1,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   3,   0,   0,   0, 
+      0,   0,   0,   0,   2,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0
+};
--- a/gfx/angle/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrgb2dui11ps.h
+++ b/gfx/angle/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrgb2dui11ps.h
@@ -1,165 +1,165 @@
-#if 0
-//
-// Generated by Microsoft (R) HLSL Shader Compiler 6.3.9600.16384
-//
-//
-// Resource Bindings:
-//
-// Name                                 Type  Format         Dim Slot Elements
-// ------------------------------ ---------- ------- ----------- ---- --------
-// TextureUI                         texture   uint4          2d    0        1
-//
-//
-//
-// Input signature:
-//
-// Name                 Index   Mask Register SysValue  Format   Used
-// -------------------- ----- ------ -------- -------- ------- ------
-// SV_POSITION              0   xyzw        0      POS   float       
-// TEXCOORD                 0   xy          1     NONE   float   xy  
-//
-//
-// Output signature:
-//
-// Name                 Index   Mask Register SysValue  Format   Used
-// -------------------- ----- ------ -------- -------- ------- ------
-// SV_TARGET                0   xyzw        0   TARGET    uint   xyzw
-//
-ps_4_0
-dcl_resource_texture2d (uint,uint,uint,uint) t0
-dcl_input_ps linear v1.xy
-dcl_output o0.xyzw
-dcl_temps 1
-resinfo_uint r0.xyzw, l(0), t0.xyzw
-utof r0.xy, r0.xyxx
-mul r0.xy, r0.xyxx, v1.xyxx
-ftoi r0.xy, r0.xyxx
-mov r0.zw, l(0,0,0,0)
-ld r0.xyzw, r0.xyzw, t0.xyzw
-mov o0.xyz, r0.xyzx
-mov o0.w, l(0)
-ret 
-// Approximately 9 instruction slots used
-#endif
-
-const BYTE g_PS_PassthroughRGB2DUI[] =
-{
-     68,  88,  66,  67, 245, 219, 
-     46,  32,  34,  74,   2,  47, 
-    124,  96, 216,  40, 253, 243, 
-    104, 178,   1,   0,   0,   0, 
-    196,   2,   0,   0,   5,   0, 
-      0,   0,  52,   0,   0,   0, 
-    180,   0,   0,   0,  12,   1, 
-      0,   0,  64,   1,   0,   0, 
-     72,   2,   0,   0,  82,  68, 
-     69,  70, 120,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   1,   0,   0,   0, 
-     28,   0,   0,   0,   0,   4, 
-    255, 255,   0,   1,   0,   0, 
-     70,   0,   0,   0,  60,   0, 
-      0,   0,   2,   0,   0,   0, 
-      4,   0,   0,   0,   4,   0, 
-      0,   0, 255, 255, 255, 255, 
-      0,   0,   0,   0,   1,   0, 
-      0,   0,  13,   0,   0,   0, 
-     84, 101, 120, 116, 117, 114, 
-    101,  85,  73,   0,  77, 105, 
-     99, 114, 111, 115, 111, 102, 
-    116,  32,  40,  82,  41,  32, 
-     72,  76,  83,  76,  32,  83, 
-    104,  97, 100, 101, 114,  32, 
-     67, 111, 109, 112, 105, 108, 
-    101, 114,  32,  54,  46,  51, 
-     46,  57,  54,  48,  48,  46, 
-     49,  54,  51,  56,  52,   0, 
-     73,  83,  71,  78,  80,   0, 
-      0,   0,   2,   0,   0,   0, 
-      8,   0,   0,   0,  56,   0, 
-      0,   0,   0,   0,   0,   0, 
-      1,   0,   0,   0,   3,   0, 
-      0,   0,   0,   0,   0,   0, 
-     15,   0,   0,   0,  68,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   3,   0, 
-      0,   0,   1,   0,   0,   0, 
-      3,   3,   0,   0,  83,  86, 
-     95,  80,  79,  83,  73,  84, 
-     73,  79,  78,   0,  84,  69, 
-     88,  67,  79,  79,  82,  68, 
-      0, 171, 171, 171,  79,  83, 
-     71,  78,  44,   0,   0,   0, 
-      1,   0,   0,   0,   8,   0, 
-      0,   0,  32,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   1,   0,   0,   0, 
-      0,   0,   0,   0,  15,   0, 
-      0,   0,  83,  86,  95,  84, 
-     65,  82,  71,  69,  84,   0, 
-    171, 171,  83,  72,  68,  82, 
-      0,   1,   0,   0,  64,   0, 
-      0,   0,  64,   0,   0,   0, 
-     88,  24,   0,   4,   0, 112, 
-     16,   0,   0,   0,   0,   0, 
-     68,  68,   0,   0,  98,  16, 
-      0,   3,  50,  16,  16,   0, 
-      1,   0,   0,   0, 101,   0, 
-      0,   3, 242,  32,  16,   0, 
-      0,   0,   0,   0, 104,   0, 
-      0,   2,   1,   0,   0,   0, 
-     61,  16,   0,   7, 242,   0, 
-     16,   0,   0,   0,   0,   0, 
-      1,  64,   0,   0,   0,   0, 
-      0,   0,  70, 126,  16,   0, 
-      0,   0,   0,   0,  86,   0, 
-      0,   5,  50,   0,  16,   0, 
-      0,   0,   0,   0,  70,   0, 
-     16,   0,   0,   0,   0,   0, 
-     56,   0,   0,   7,  50,   0, 
-     16,   0,   0,   0,   0,   0, 
-     70,   0,  16,   0,   0,   0, 
-      0,   0,  70,  16,  16,   0, 
-      1,   0,   0,   0,  27,   0, 
-      0,   5,  50,   0,  16,   0, 
-      0,   0,   0,   0,  70,   0, 
-     16,   0,   0,   0,   0,   0, 
-     54,   0,   0,   8, 194,   0, 
-     16,   0,   0,   0,   0,   0, 
-      2,  64,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,  45,   0,   0,   7, 
-    242,   0,  16,   0,   0,   0, 
-      0,   0,  70,  14,  16,   0, 
-      0,   0,   0,   0,  70, 126, 
-     16,   0,   0,   0,   0,   0, 
-     54,   0,   0,   5, 114,  32, 
-     16,   0,   0,   0,   0,   0, 
-     70,   2,  16,   0,   0,   0, 
-      0,   0,  54,   0,   0,   5, 
-    130,  32,  16,   0,   0,   0, 
-      0,   0,   1,  64,   0,   0, 
-      0,   0,   0,   0,  62,   0, 
-      0,   1,  83,  84,  65,  84, 
-    116,   0,   0,   0,   9,   0, 
-      0,   0,   1,   0,   0,   0, 
-      0,   0,   0,   0,   2,   0, 
-      0,   0,   1,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   1,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   1,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   3,   0,   0,   0, 
-      0,   0,   0,   0,   2,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0
-};
+#if 0
+//
+// Generated by Microsoft (R) HLSL Shader Compiler 6.3.9600.16384
+//
+//
+// Resource Bindings:
+//
+// Name                                 Type  Format         Dim Slot Elements
+// ------------------------------ ---------- ------- ----------- ---- --------
+// TextureUI                         texture   uint4          2d    0        1
+//
+//
+//
+// Input signature:
+//
+// Name                 Index   Mask Register SysValue  Format   Used
+// -------------------- ----- ------ -------- -------- ------- ------
+// SV_POSITION              0   xyzw        0      POS   float       
+// TEXCOORD                 0   xy          1     NONE   float   xy  
+//
+//
+// Output signature:
+//
+// Name                 Index   Mask Register SysValue  Format   Used
+// -------------------- ----- ------ -------- -------- ------- ------
+// SV_TARGET                0   xyzw        0   TARGET    uint   xyzw
+//
+ps_4_0
+dcl_resource_texture2d (uint,uint,uint,uint) t0
+dcl_input_ps linear v1.xy
+dcl_output o0.xyzw
+dcl_temps 1
+resinfo_uint r0.xyzw, l(0), t0.xyzw
+utof r0.xy, r0.xyxx
+mul r0.xy, r0.xyxx, v1.xyxx
+ftoi r0.xy, r0.xyxx
+mov r0.zw, l(0,0,0,0)
+ld r0.xyzw, r0.xyzw, t0.xyzw
+mov o0.xyz, r0.xyzx
+mov o0.w, l(0)
+ret 
+// Approximately 9 instruction slots used
+#endif
+
+const BYTE g_PS_PassthroughRGB2DUI[] =
+{
+     68,  88,  66,  67, 245, 219, 
+     46,  32,  34,  74,   2,  47, 
+    124,  96, 216,  40, 253, 243, 
+    104, 178,   1,   0,   0,   0, 
+    196,   2,   0,   0,   5,   0, 
+      0,   0,  52,   0,   0,   0, 
+    180,   0,   0,   0,  12,   1, 
+      0,   0,  64,   1,   0,   0, 
+     72,   2,   0,   0,  82,  68, 
+     69,  70, 120,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   1,   0,   0,   0, 
+     28,   0,   0,   0,   0,   4, 
+    255, 255,   0,   1,   0,   0, 
+     70,   0,   0,   0,  60,   0, 
+      0,   0,   2,   0,   0,   0, 
+      4,   0,   0,   0,   4,   0, 
+      0,   0, 255, 255, 255, 255, 
+      0,   0,   0,   0,   1,   0, 
+      0,   0,  13,   0,   0,   0, 
+     84, 101, 120, 116, 117, 114, 
+    101,  85,  73,   0,  77, 105, 
+     99, 114, 111, 115, 111, 102, 
+    116,  32,  40,  82,  41,  32, 
+     72,  76,  83,  76,  32,  83, 
+    104,  97, 100, 101, 114,  32, 
+     67, 111, 109, 112, 105, 108, 
+    101, 114,  32,  54,  46,  51, 
+     46,  57,  54,  48,  48,  46, 
+     49,  54,  51,  56,  52,   0, 
+     73,  83,  71,  78,  80,   0, 
+      0,   0,   2,   0,   0,   0, 
+      8,   0,   0,   0,  56,   0, 
+      0,   0,   0,   0,   0,   0, 
+      1,   0,   0,   0,   3,   0, 
+      0,   0,   0,   0,   0,   0, 
+     15,   0,   0,   0,  68,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   3,   0, 
+      0,   0,   1,   0,   0,   0, 
+      3,   3,   0,   0,  83,  86, 
+     95,  80,  79,  83,  73,  84, 
+     73,  79,  78,   0,  84,  69, 
+     88,  67,  79,  79,  82,  68, 
+      0, 171, 171, 171,  79,  83, 
+     71,  78,  44,   0,   0,   0, 
+      1,   0,   0,   0,   8,   0, 
+      0,   0,  32,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   1,   0,   0,   0, 
+      0,   0,   0,   0,  15,   0, 
+      0,   0,  83,  86,  95,  84, 
+     65,  82,  71,  69,  84,   0, 
+    171, 171,  83,  72,  68,  82, 
+      0,   1,   0,   0,  64,   0, 
+      0,   0,  64,   0,   0,   0, 
+     88,  24,   0,   4,   0, 112, 
+     16,   0,   0,   0,   0,   0, 
+     68,  68,   0,   0,  98,  16, 
+      0,   3,  50,  16,  16,   0, 
+      1,   0,   0,   0, 101,   0, 
+      0,   3, 242,  32,  16,   0, 
+      0,   0,   0,   0, 104,   0, 
+      0,   2,   1,   0,   0,   0, 
+     61,  16,   0,   7, 242,   0, 
+     16,   0,   0,   0,   0,   0, 
+      1,  64,   0,   0,   0,   0, 
+      0,   0,  70, 126,  16,   0, 
+      0,   0,   0,   0,  86,   0, 
+      0,   5,  50,   0,  16,   0, 
+      0,   0,   0,   0,  70,   0, 
+     16,   0,   0,   0,   0,   0, 
+     56,   0,   0,   7,  50,   0, 
+     16,   0,   0,   0,   0,   0, 
+     70,   0,  16,   0,   0,   0, 
+      0,   0,  70,  16,  16,   0, 
+      1,   0,   0,   0,  27,   0, 
+      0,   5,  50,   0,  16,   0, 
+      0,   0,   0,   0,  70,   0, 
+     16,   0,   0,   0,   0,   0, 
+     54,   0,   0,   8, 194,   0, 
+     16,   0,   0,   0,   0,   0, 
+      2,  64,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,  45,   0,   0,   7, 
+    242,   0,  16,   0,   0,   0, 
+      0,   0,  70,  14,  16,   0, 
+      0,   0,   0,   0,  70, 126, 
+     16,   0,   0,   0,   0,   0, 
+     54,   0,   0,   5, 114,  32, 
+     16,   0,   0,   0,   0,   0, 
+     70,   2,  16,   0,   0,   0, 
+      0,   0,  54,   0,   0,   5, 
+    130,  32,  16,   0,   0,   0, 
+      0,   0,   1,  64,   0,   0, 
+      0,   0,   0,   0,  62,   0, 
+      0,   1,  83,  84,  65,  84, 
+    116,   0,   0,   0,   9,   0, 
+      0,   0,   1,   0,   0,   0, 
+      0,   0,   0,   0,   2,   0, 
+      0,   0,   1,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   1,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   1,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   3,   0,   0,   0, 
+      0,   0,   0,   0,   2,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0
+};
--- a/gfx/angle/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrgb3d11ps.h
+++ b/gfx/angle/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrgb3d11ps.h
@@ -1,160 +1,160 @@
-#if 0
-//
-// Generated by Microsoft (R) HLSL Shader Compiler 6.3.9600.16384
-//
-//
-// Resource Bindings:
-//
-// Name                                 Type  Format         Dim Slot Elements
-// ------------------------------ ---------- ------- ----------- ---- --------
-// Sampler                           sampler      NA          NA    0        1
-// TextureF                          texture  float4          3d    0        1
-//
-//
-//
-// Input signature:
-//
-// Name                 Index   Mask Register SysValue  Format   Used
-// -------------------- ----- ------ -------- -------- ------- ------
-// SV_POSITION              0   xyzw        0      POS   float       
-// SV_RENDERTARGETARRAYINDEX     0   x           1  RTINDEX    uint       
-// TEXCOORD                 0   xyz         2     NONE   float   xyz 
-//
-//
-// Output signature:
-//
-// Name                 Index   Mask Register SysValue  Format   Used
-// -------------------- ----- ------ -------- -------- ------- ------
-// SV_TARGET                0   xyzw        0   TARGET   float   xyzw
-//
-ps_4_0
-dcl_sampler s0, mode_default
-dcl_resource_texture3d (float,float,float,float) t0
-dcl_input_ps linear v2.xyz
-dcl_output o0.xyzw
-dcl_temps 1
-sample r0.xyzw, v2.xyzx, t0.xyzw, s0
-mov o0.xyz, r0.xyzx
-mov o0.w, l(1.000000)
-ret 
-// Approximately 4 instruction slots used
-#endif
-
-const BYTE g_PS_PassthroughRGB3D[] =
-{
-     68,  88,  66,  67,   3, 213, 
-    227, 200, 132, 255,   7,  95, 
-      0, 252,  77,  33, 254, 184, 
-     83, 110,   1,   0,   0,   0, 
-    176,   2,   0,   0,   5,   0, 
-      0,   0,  52,   0,   0,   0, 
-    220,   0,   0,   0, 100,   1, 
-      0,   0, 152,   1,   0,   0, 
-     52,   2,   0,   0,  82,  68, 
-     69,  70, 160,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   2,   0,   0,   0, 
-     28,   0,   0,   0,   0,   4, 
-    255, 255,   0,   1,   0,   0, 
-    109,   0,   0,   0,  92,   0, 
-      0,   0,   3,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   1,   0, 
-      0,   0,   1,   0,   0,   0, 
-    100,   0,   0,   0,   2,   0, 
-      0,   0,   5,   0,   0,   0, 
-      8,   0,   0,   0, 255, 255, 
-    255, 255,   0,   0,   0,   0, 
-      1,   0,   0,   0,  13,   0, 
-      0,   0,  83,  97, 109, 112, 
-    108, 101, 114,   0,  84, 101, 
-    120, 116, 117, 114, 101,  70, 
-      0,  77, 105,  99, 114, 111, 
-    115, 111, 102, 116,  32,  40, 
-     82,  41,  32,  72,  76,  83, 
-     76,  32,  83, 104,  97, 100, 
-    101, 114,  32,  67, 111, 109, 
-    112, 105, 108, 101, 114,  32, 
-     54,  46,  51,  46,  57,  54, 
-     48,  48,  46,  49,  54,  51, 
-     56,  52,   0, 171,  73,  83, 
-     71,  78, 128,   0,   0,   0, 
-      3,   0,   0,   0,   8,   0, 
-      0,   0,  80,   0,   0,   0, 
-      0,   0,   0,   0,   1,   0, 
-      0,   0,   3,   0,   0,   0, 
-      0,   0,   0,   0,  15,   0, 
-      0,   0,  92,   0,   0,   0, 
-      0,   0,   0,   0,   4,   0, 
-      0,   0,   1,   0,   0,   0, 
-      1,   0,   0,   0,   1,   0, 
-      0,   0, 118,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   3,   0,   0,   0, 
-      2,   0,   0,   0,   7,   7, 
-      0,   0,  83,  86,  95,  80, 
-     79,  83,  73,  84,  73,  79, 
-     78,   0,  83,  86,  95,  82, 
-     69,  78,  68,  69,  82,  84, 
-     65,  82,  71,  69,  84,  65, 
-     82,  82,  65,  89,  73,  78, 
-     68,  69,  88,   0,  84,  69, 
-     88,  67,  79,  79,  82,  68, 
-      0, 171,  79,  83,  71,  78, 
-     44,   0,   0,   0,   1,   0, 
-      0,   0,   8,   0,   0,   0, 
-     32,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      3,   0,   0,   0,   0,   0, 
-      0,   0,  15,   0,   0,   0, 
-     83,  86,  95,  84,  65,  82, 
-     71,  69,  84,   0, 171, 171, 
-     83,  72,  68,  82, 148,   0, 
-      0,   0,  64,   0,   0,   0, 
-     37,   0,   0,   0,  90,   0, 
-      0,   3,   0,  96,  16,   0, 
-      0,   0,   0,   0,  88,  40, 
-      0,   4,   0, 112,  16,   0, 
-      0,   0,   0,   0,  85,  85, 
-      0,   0,  98,  16,   0,   3, 
-    114,  16,  16,   0,   2,   0, 
-      0,   0, 101,   0,   0,   3, 
-    242,  32,  16,   0,   0,   0, 
-      0,   0, 104,   0,   0,   2, 
-      1,   0,   0,   0,  69,   0, 
-      0,   9, 242,   0,  16,   0, 
-      0,   0,   0,   0,  70,  18, 
-     16,   0,   2,   0,   0,   0, 
-     70, 126,  16,   0,   0,   0, 
-      0,   0,   0,  96,  16,   0, 
-      0,   0,   0,   0,  54,   0, 
-      0,   5, 114,  32,  16,   0, 
-      0,   0,   0,   0,  70,   2, 
-     16,   0,   0,   0,   0,   0, 
-     54,   0,   0,   5, 130,  32, 
-     16,   0,   0,   0,   0,   0, 
-      1,  64,   0,   0,   0,   0, 
-    128,  63,  62,   0,   0,   1, 
-     83,  84,  65,  84, 116,   0, 
-      0,   0,   4,   0,   0,   0, 
-      1,   0,   0,   0,   0,   0, 
-      0,   0,   2,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      1,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   1,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      2,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0
-};
+#if 0
+//
+// Generated by Microsoft (R) HLSL Shader Compiler 6.3.9600.16384
+//
+//
+// Resource Bindings:
+//
+// Name                                 Type  Format         Dim Slot Elements
+// ------------------------------ ---------- ------- ----------- ---- --------
+// Sampler                           sampler      NA          NA    0        1
+// TextureF                          texture  float4          3d    0        1
+//
+//
+//
+// Input signature:
+//
+// Name                 Index   Mask Register SysValue  Format   Used
+// -------------------- ----- ------ -------- -------- ------- ------
+// SV_POSITION              0   xyzw        0      POS   float       
+// SV_RENDERTARGETARRAYINDEX     0   x           1  RTINDEX    uint       
+// TEXCOORD                 0   xyz         2     NONE   float   xyz 
+//
+//
+// Output signature:
+//
+// Name                 Index   Mask Register SysValue  Format   Used
+// -------------------- ----- ------ -------- -------- ------- ------
+// SV_TARGET                0   xyzw        0   TARGET   float   xyzw
+//
+ps_4_0
+dcl_sampler s0, mode_default
+dcl_resource_texture3d (float,float,float,float) t0
+dcl_input_ps linear v2.xyz
+dcl_output o0.xyzw
+dcl_temps 1
+sample r0.xyzw, v2.xyzx, t0.xyzw, s0
+mov o0.xyz, r0.xyzx
+mov o0.w, l(1.000000)
+ret 
+// Approximately 4 instruction slots used
+#endif
+
+const BYTE g_PS_PassthroughRGB3D[] =
+{
+     68,  88,  66,  67,   3, 213, 
+    227, 200, 132, 255,   7,  95, 
+      0, 252,  77,  33, 254, 184, 
+     83, 110,   1,   0,   0,   0, 
+    176,   2,   0,   0,   5,   0, 
+      0,   0,  52,   0,   0,   0, 
+    220,   0,   0,   0, 100,   1, 
+      0,   0, 152,   1,   0,   0, 
+     52,   2,   0,   0,  82,  68, 
+     69,  70, 160,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   2,   0,   0,   0, 
+     28,   0,   0,   0,   0,   4, 
+    255, 255,   0,   1,   0,   0, 
+    109,   0,   0,   0,  92,   0, 
+      0,   0,   3,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   1,   0, 
+      0,   0,   1,   0,   0,   0, 
+    100,   0,   0,   0,   2,   0, 
+      0,   0,   5,   0,   0,   0, 
+      8,   0,   0,   0, 255, 255, 
+    255, 255,   0,   0,   0,   0, 
+      1,   0,   0,   0,  13,   0, 
+      0,   0,  83,  97, 109, 112, 
+    108, 101, 114,   0,  84, 101, 
+    120, 116, 117, 114, 101,  70, 
+      0,  77, 105,  99, 114, 111, 
+    115, 111, 102, 116,  32,  40, 
+     82,  41,  32,  72,  76,  83, 
+     76,  32,  83, 104,  97, 100, 
+    101, 114,  32,  67, 111, 109, 
+    112, 105, 108, 101, 114,  32, 
+     54,  46,  51,  46,  57,  54, 
+     48,  48,  46,  49,  54,  51, 
+     56,  52,   0, 171,  73,  83, 
+     71,  78, 128,   0,   0,   0, 
+      3,   0,   0,   0,   8,   0, 
+      0,   0,  80,   0,   0,   0, 
+      0,   0,   0,   0,   1,   0, 
+      0,   0,   3,   0,   0,   0, 
+      0,   0,   0,   0,  15,   0, 
+      0,   0,  92,   0,   0,   0, 
+      0,   0,   0,   0,   4,   0, 
+      0,   0,   1,   0,   0,   0, 
+      1,   0,   0,   0,   1,   0, 
+      0,   0, 118,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   3,   0,   0,   0, 
+      2,   0,   0,   0,   7,   7, 
+      0,   0,  83,  86,  95,  80, 
+     79,  83,  73,  84,  73,  79, 
+     78,   0,  83,  86,  95,  82, 
+     69,  78,  68,  69,  82,  84, 
+     65,  82,  71,  69,  84,  65, 
+     82,  82,  65,  89,  73,  78, 
+     68,  69,  88,   0,  84,  69, 
+     88,  67,  79,  79,  82,  68, 
+      0, 171,  79,  83,  71,  78, 
+     44,   0,   0,   0,   1,   0, 
+      0,   0,   8,   0,   0,   0, 
+     32,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      3,   0,   0,   0,   0,   0, 
+      0,   0,  15,   0,   0,   0, 
+     83,  86,  95,  84,  65,  82, 
+     71,  69,  84,   0, 171, 171, 
+     83,  72,  68,  82, 148,   0, 
+      0,   0,  64,   0,   0,   0, 
+     37,   0,   0,   0,  90,   0, 
+      0,   3,   0,  96,  16,   0, 
+      0,   0,   0,   0,  88,  40, 
+      0,   4,   0, 112,  16,   0, 
+      0,   0,   0,   0,  85,  85, 
+      0,   0,  98,  16,   0,   3, 
+    114,  16,  16,   0,   2,   0, 
+      0,   0, 101,   0,   0,   3, 
+    242,  32,  16,   0,   0,   0, 
+      0,   0, 104,   0,   0,   2, 
+      1,   0,   0,   0,  69,   0, 
+      0,   9, 242,   0,  16,   0, 
+      0,   0,   0,   0,  70,  18, 
+     16,   0,   2,   0,   0,   0, 
+     70, 126,  16,   0,   0,   0, 
+      0,   0,   0,  96,  16,   0, 
+      0,   0,   0,   0,  54,   0, 
+      0,   5, 114,  32,  16,   0, 
+      0,   0,   0,   0,  70,   2, 
+     16,   0,   0,   0,   0,   0, 
+     54,   0,   0,   5, 130,  32, 
+     16,   0,   0,   0,   0,   0, 
+      1,  64,   0,   0,   0,   0, 
+    128,  63,  62,   0,   0,   1, 
+     83,  84,  65,  84, 116,   0, 
+      0,   0,   4,   0,   0,   0, 
+      1,   0,   0,   0,   0,   0, 
+      0,   0,   2,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      1,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   1,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      2,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0
+};
--- a/gfx/angle/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrgb3di11ps.h
+++ b/gfx/angle/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrgb3di11ps.h
@@ -1,172 +1,172 @@
-#if 0
-//
-// Generated by Microsoft (R) HLSL Shader Compiler 6.3.9600.16384
-//
-//
-// Resource Bindings:
-//
-// Name                                 Type  Format         Dim Slot Elements
-// ------------------------------ ---------- ------- ----------- ---- --------
-// TextureI                          texture   sint4          3d    0        1
-//
-//
-//
-// Input signature:
-//
-// Name                 Index   Mask Register SysValue  Format   Used
-// -------------------- ----- ------ -------- -------- ------- ------
-// SV_POSITION              0   xyzw        0      POS   float       
-// SV_RENDERTARGETARRAYINDEX     0   x           1  RTINDEX    uint       
-// TEXCOORD                 0   xyz         2     NONE   float   xyz 
-//
-//
-// Output signature:
-//
-// Name                 Index   Mask Register SysValue  Format   Used
-// -------------------- ----- ------ -------- -------- ------- ------
-// SV_TARGET                0   xyzw        0   TARGET     int   xyzw
-//
-ps_4_0
-dcl_resource_texture3d (sint,sint,sint,sint) t0
-dcl_input_ps linear v2.xyz
-dcl_output o0.xyzw
-dcl_temps 1
-resinfo_uint r0.xyzw, l(0), t0.xyzw
-utof r0.xyz, r0.xyzx
-mul r0.xyz, r0.xyzx, v2.xyzx
-ftoi r0.xyz, r0.xyzx
-mov r0.w, l(0)
-ld r0.xyzw, r0.xyzw, t0.xyzw
-mov o0.xyz, r0.xyzx
-mov o0.w, l(0)
-ret 
-// Approximately 9 instruction slots used
-#endif
-
-const BYTE g_PS_PassthroughRGB3DI[] =
-{
-     68,  88,  66,  67, 194, 157, 
-      8, 194, 167, 235,  14, 127, 
-     69, 198,  32,  35, 167,  35, 
-    213, 248,   1,   0,   0,   0, 
-    232,   2,   0,   0,   5,   0, 
-      0,   0,  52,   0,   0,   0, 
-    180,   0,   0,   0,  60,   1, 
-      0,   0, 112,   1,   0,   0, 
-    108,   2,   0,   0,  82,  68, 
-     69,  70, 120,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   1,   0,   0,   0, 
-     28,   0,   0,   0,   0,   4, 
-    255, 255,   0,   1,   0,   0, 
-     69,   0,   0,   0,  60,   0, 
-      0,   0,   2,   0,   0,   0, 
-      3,   0,   0,   0,   8,   0, 
-      0,   0, 255, 255, 255, 255, 
-      0,   0,   0,   0,   1,   0, 
-      0,   0,  13,   0,   0,   0, 
-     84, 101, 120, 116, 117, 114, 
-    101,  73,   0,  77, 105,  99, 
-    114, 111, 115, 111, 102, 116, 
-     32,  40,  82,  41,  32,  72, 
-     76,  83,  76,  32,  83, 104, 
-     97, 100, 101, 114,  32,  67, 
-    111, 109, 112, 105, 108, 101, 
-    114,  32,  54,  46,  51,  46, 
-     57,  54,  48,  48,  46,  49, 
-     54,  51,  56,  52,   0, 171, 
-     73,  83,  71,  78, 128,   0, 
-      0,   0,   3,   0,   0,   0, 
-      8,   0,   0,   0,  80,   0, 
-      0,   0,   0,   0,   0,   0, 
-      1,   0,   0,   0,   3,   0, 
-      0,   0,   0,   0,   0,   0, 
-     15,   0,   0,   0,  92,   0, 
-      0,   0,   0,   0,   0,   0, 
-      4,   0,   0,   0,   1,   0, 
-      0,   0,   1,   0,   0,   0, 
-      1,   0,   0,   0, 118,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   3,   0, 
-      0,   0,   2,   0,   0,   0, 
-      7,   7,   0,   0,  83,  86, 
-     95,  80,  79,  83,  73,  84, 
-     73,  79,  78,   0,  83,  86, 
-     95,  82,  69,  78,  68,  69, 
-     82,  84,  65,  82,  71,  69, 
-     84,  65,  82,  82,  65,  89, 
-     73,  78,  68,  69,  88,   0, 
-     84,  69,  88,  67,  79,  79, 
-     82,  68,   0, 171,  79,  83, 
-     71,  78,  44,   0,   0,   0, 
-      1,   0,   0,   0,   8,   0, 
-      0,   0,  32,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   2,   0,   0,   0, 
-      0,   0,   0,   0,  15,   0, 
-      0,   0,  83,  86,  95,  84, 
-     65,  82,  71,  69,  84,   0, 
-    171, 171,  83,  72,  68,  82, 
-    244,   0,   0,   0,  64,   0, 
-      0,   0,  61,   0,   0,   0, 
-     88,  40,   0,   4,   0, 112, 
-     16,   0,   0,   0,   0,   0, 
-     51,  51,   0,   0,  98,  16, 
-      0,   3, 114,  16,  16,   0, 
-      2,   0,   0,   0, 101,   0, 
-      0,   3, 242,  32,  16,   0, 
-      0,   0,   0,   0, 104,   0, 
-      0,   2,   1,   0,   0,   0, 
-     61,  16,   0,   7, 242,   0, 
-     16,   0,   0,   0,   0,   0, 
-      1,  64,   0,   0,   0,   0, 
-      0,   0,  70, 126,  16,   0, 
-      0,   0,   0,   0,  86,   0, 
-      0,   5, 114,   0,  16,   0, 
-      0,   0,   0,   0,  70,   2, 
-     16,   0,   0,   0,   0,   0, 
-     56,   0,   0,   7, 114,   0, 
-     16,   0,   0,   0,   0,   0, 
-     70,   2,  16,   0,   0,   0, 
-      0,   0,  70,  18,  16,   0, 
-      2,   0,   0,   0,  27,   0, 
-      0,   5, 114,   0,  16,   0, 
-      0,   0,   0,   0,  70,   2, 
-     16,   0,   0,   0,   0,   0, 
-     54,   0,   0,   5, 130,   0, 
-     16,   0,   0,   0,   0,   0, 
-      1,  64,   0,   0,   0,   0, 
-      0,   0,  45,   0,   0,   7, 
-    242,   0,  16,   0,   0,   0, 
-      0,   0,  70,  14,  16,   0, 
-      0,   0,   0,   0,  70, 126, 
-     16,   0,   0,   0,   0,   0, 
-     54,   0,   0,   5, 114,  32, 
-     16,   0,   0,   0,   0,   0, 
-     70,   2,  16,   0,   0,   0, 
-      0,   0,  54,   0,   0,   5, 
-    130,  32,  16,   0,   0,   0, 
-      0,   0,   1,  64,   0,   0, 
-      0,   0,   0,   0,  62,   0, 
-      0,   1,  83,  84,  65,  84, 
-    116,   0,   0,   0,   9,   0, 
-      0,   0,   1,   0,   0,   0, 
-      0,   0,   0,   0,   2,   0, 
-      0,   0,   1,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   1,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   1,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   3,   0,   0,   0, 
-      0,   0,   0,   0,   2,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0
-};
+#if 0
+//
+// Generated by Microsoft (R) HLSL Shader Compiler 6.3.9600.16384
+//
+//
+// Resource Bindings:
+//
+// Name                                 Type  Format         Dim Slot Elements
+// ------------------------------ ---------- ------- ----------- ---- --------
+// TextureI                          texture   sint4          3d    0        1
+//
+//
+//
+// Input signature:
+//
+// Name                 Index   Mask Register SysValue  Format   Used
+// -------------------- ----- ------ -------- -------- ------- ------
+// SV_POSITION              0   xyzw        0      POS   float       
+// SV_RENDERTARGETARRAYINDEX     0   x           1  RTINDEX    uint       
+// TEXCOORD                 0   xyz         2     NONE   float   xyz 
+//
+//
+// Output signature:
+//
+// Name                 Index   Mask Register SysValue  Format   Used
+// -------------------- ----- ------ -------- -------- ------- ------
+// SV_TARGET                0   xyzw        0   TARGET     int   xyzw
+//
+ps_4_0
+dcl_resource_texture3d (sint,sint,sint,sint) t0
+dcl_input_ps linear v2.xyz
+dcl_output o0.xyzw
+dcl_temps 1
+resinfo_uint r0.xyzw, l(0), t0.xyzw
+utof r0.xyz, r0.xyzx
+mul r0.xyz, r0.xyzx, v2.xyzx
+ftoi r0.xyz, r0.xyzx
+mov r0.w, l(0)
+ld r0.xyzw, r0.xyzw, t0.xyzw
+mov o0.xyz, r0.xyzx
+mov o0.w, l(0)
+ret 
+// Approximately 9 instruction slots used
+#endif
+
+const BYTE g_PS_PassthroughRGB3DI[] =
+{
+     68,  88,  66,  67, 194, 157, 
+      8, 194, 167, 235,  14, 127, 
+     69, 198,  32,  35, 167,  35, 
+    213, 248,   1,   0,   0,   0, 
+    232,   2,   0,   0,   5,   0, 
+      0,   0,  52,   0,   0,   0, 
+    180,   0,   0,   0,  60,   1, 
+      0,   0, 112,   1,   0,   0, 
+    108,   2,   0,   0,  82,  68, 
+     69,  70, 120,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   1,   0,   0,   0, 
+     28,   0,   0,   0,   0,   4, 
+    255, 255,   0,   1,   0,   0, 
+     69,   0,   0,   0,  60,   0, 
+      0,   0,   2,   0,   0,   0, 
+      3,   0,   0,   0,   8,   0, 
+      0,   0, 255, 255, 255, 255, 
+      0,   0,   0,   0,   1,   0, 
+      0,   0,  13,   0,   0,   0, 
+     84, 101, 120, 116, 117, 114, 
+    101,  73,   0,  77, 105,  99, 
+    114, 111, 115, 111, 102, 116, 
+     32,  40,  82,  41,  32,  72, 
+     76,  83,  76,  32,  83, 104, 
+     97, 100, 101, 114,  32,  67, 
+    111, 109, 112, 105, 108, 101, 
+    114,  32,  54,  46,  51,  46, 
+     57,  54,  48,  48,  46,  49, 
+     54,  51,  56,  52,   0, 171, 
+     73,  83,  71,  78, 128,   0, 
+      0,   0,   3,   0,   0,   0, 
+      8,   0,   0,   0,  80,   0, 
+      0,   0,   0,   0,   0,   0, 
+      1,   0,   0,   0,   3,   0, 
+      0,   0,   0,   0,   0,   0, 
+     15,   0,   0,   0,  92,   0, 
+      0,   0,   0,   0,   0,   0, 
+      4,   0,   0,   0,   1,   0, 
+      0,   0,   1,   0,   0,   0, 
+      1,   0,   0,   0, 118,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   3,   0, 
+      0,   0,   2,   0,   0,   0, 
+      7,   7,   0,   0,  83,  86, 
+     95,  80,  79,  83,  73,  84, 
+     73,  79,  78,   0,  83,  86, 
+     95,  82,  69,  78,  68,  69, 
+     82,  84,  65,  82,  71,  69, 
+     84,  65,  82,  82,  65,  89, 
+     73,  78,  68,  69,  88,   0, 
+     84,  69,  88,  67,  79,  79, 
+     82,  68,   0, 171,  79,  83, 
+     71,  78,  44,   0,   0,   0, 
+      1,   0,   0,   0,   8,   0, 
+      0,   0,  32,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   2,   0,   0,   0, 
+      0,   0,   0,   0,  15,   0, 
+      0,   0,  83,  86,  95,  84, 
+     65,  82,  71,  69,  84,   0, 
+    171, 171,  83,  72,  68,  82, 
+    244,   0,   0,   0,  64,   0, 
+      0,   0,  61,   0,   0,   0, 
+     88,  40,   0,   4,   0, 112, 
+     16,   0,   0,   0,   0,   0, 
+     51,  51,   0,   0,  98,  16, 
+      0,   3, 114,  16,  16,   0, 
+      2,   0,   0,   0, 101,   0, 
+      0,   3, 242,  32,  16,   0, 
+      0,   0,   0,   0, 104,   0, 
+      0,   2,   1,   0,   0,   0, 
+     61,  16,   0,   7, 242,   0, 
+     16,   0,   0,   0,   0,   0, 
+      1,  64,   0,   0,   0,   0, 
+      0,   0,  70, 126,  16,   0, 
+      0,   0,   0,   0,  86,   0, 
+      0,   5, 114,   0,  16,   0, 
+      0,   0,   0,   0,  70,   2, 
+     16,   0,   0,   0,   0,   0, 
+     56,   0,   0,   7, 114,   0, 
+     16,   0,   0,   0,   0,   0, 
+     70,   2,  16,   0,   0,   0, 
+      0,   0,  70,  18,  16,   0, 
+      2,   0,   0,   0,  27,   0, 
+      0,   5, 114,   0,  16,   0, 
+      0,   0,   0,   0,  70,   2, 
+     16,   0,   0,   0,   0,   0, 
+     54,   0,   0,   5, 130,   0, 
+     16,   0,   0,   0,   0,   0, 
+      1,  64,   0,   0,   0,   0, 
+      0,   0,  45,   0,   0,   7, 
+    242,   0,  16,   0,   0,   0, 
+      0,   0,  70,  14,  16,   0, 
+      0,   0,   0,   0,  70, 126, 
+     16,   0,   0,   0,   0,   0, 
+     54,   0,   0,   5, 114,  32, 
+     16,   0,   0,   0,   0,   0, 
+     70,   2,  16,   0,   0,   0, 
+      0,   0,  54,   0,   0,   5, 
+    130,  32,  16,   0,   0,   0, 
+      0,   0,   1,  64,   0,   0, 
+      0,   0,   0,   0,  62,   0, 
+      0,   1,  83,  84,  65,  84, 
+    116,   0,   0,   0,   9,   0, 
+      0,   0,   1,   0,   0,   0, 
+      0,   0,   0,   0,   2,   0, 
+      0,   0,   1,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   1,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   1,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   3,   0,   0,   0, 
+      0,   0,   0,   0,   2,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0
+};
--- a/gfx/angle/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrgb3dui11ps.h
+++ b/gfx/angle/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrgb3dui11ps.h
@@ -1,172 +1,172 @@
-#if 0
-//
-// Generated by Microsoft (R) HLSL Shader Compiler 6.3.9600.16384
-//
-//
-// Resource Bindings:
-//
-// Name                                 Type  Format         Dim Slot Elements
-// ------------------------------ ---------- ------- ----------- ---- --------
-// TextureUI                         texture   uint4          3d    0        1
-//
-//
-//
-// Input signature:
-//
-// Name                 Index   Mask Register SysValue  Format   Used
-// -------------------- ----- ------ -------- -------- ------- ------
-// SV_POSITION              0   xyzw        0      POS   float       
-// SV_RENDERTARGETARRAYINDEX     0   x           1  RTINDEX    uint       
-// TEXCOORD                 0   xyz         2     NONE   float   xyz 
-//
-//
-// Output signature:
-//
-// Name                 Index   Mask Register SysValue  Format   Used
-// -------------------- ----- ------ -------- -------- ------- ------
-// SV_TARGET                0   xyzw        0   TARGET    uint   xyzw
-//
-ps_4_0
-dcl_resource_texture3d (uint,uint,uint,uint) t0
-dcl_input_ps linear v2.xyz
-dcl_output o0.xyzw
-dcl_temps 1
-resinfo_uint r0.xyzw, l(0), t0.xyzw
-utof r0.xyz, r0.xyzx
-mul r0.xyz, r0.xyzx, v2.xyzx
-ftoi r0.xyz, r0.xyzx
-mov r0.w, l(0)
-ld r0.xyzw, r0.xyzw, t0.xyzw
-mov o0.xyz, r0.xyzx
-mov o0.w, l(0)
-ret 
-// Approximately 9 instruction slots used
-#endif
-
-const BYTE g_PS_PassthroughRGB3DUI[] =
-{
-     68,  88,  66,  67, 253, 147, 
-      1, 158,  41,  31, 253, 138, 
-     52, 213, 103,  41, 188, 192, 
-     79, 199,   1,   0,   0,   0, 
-    232,   2,   0,   0,   5,   0, 
-      0,   0,  52,   0,   0,   0, 
-    180,   0,   0,   0,  60,   1, 
-      0,   0, 112,   1,   0,   0, 
-    108,   2,   0,   0,  82,  68, 
-     69,  70, 120,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   1,   0,   0,   0, 
-     28,   0,   0,   0,   0,   4, 
-    255, 255,   0,   1,   0,   0, 
-     70,   0,   0,   0,  60,   0, 
-      0,   0,   2,   0,   0,   0, 
-      4,   0,   0,   0,   8,   0, 
-      0,   0, 255, 255, 255, 255, 
-      0,   0,   0,   0,   1,   0, 
-      0,   0,  13,   0,   0,   0, 
-     84, 101, 120, 116, 117, 114, 
-    101,  85,  73,   0,  77, 105, 
-     99, 114, 111, 115, 111, 102, 
-    116,  32,  40,  82,  41,  32, 
-     72,  76,  83,  76,  32,  83, 
-    104,  97, 100, 101, 114,  32, 
-     67, 111, 109, 112, 105, 108, 
-    101, 114,  32,  54,  46,  51, 
-     46,  57,  54,  48,  48,  46, 
-     49,  54,  51,  56,  52,   0, 
-     73,  83,  71,  78, 128,   0, 
-      0,   0,   3,   0,   0,   0, 
-      8,   0,   0,   0,  80,   0, 
-      0,   0,   0,   0,   0,   0, 
-      1,   0,   0,   0,   3,   0, 
-      0,   0,   0,   0,   0,   0, 
-     15,   0,   0,   0,  92,   0, 
-      0,   0,   0,   0,   0,   0, 
-      4,   0,   0,   0,   1,   0, 
-      0,   0,   1,   0,   0,   0, 
-      1,   0,   0,   0, 118,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   3,   0, 
-      0,   0,   2,   0,   0,   0, 
-      7,   7,   0,   0,  83,  86, 
-     95,  80,  79,  83,  73,  84, 
-     73,  79,  78,   0,  83,  86, 
-     95,  82,  69,  78,  68,  69, 
-     82,  84,  65,  82,  71,  69, 
-     84,  65,  82,  82,  65,  89, 
-     73,  78,  68,  69,  88,   0, 
-     84,  69,  88,  67,  79,  79, 
-     82,  68,   0, 171,  79,  83, 
-     71,  78,  44,   0,   0,   0, 
-      1,   0,   0,   0,   8,   0, 
-      0,   0,  32,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   1,   0,   0,   0, 
-      0,   0,   0,   0,  15,   0, 
-      0,   0,  83,  86,  95,  84, 
-     65,  82,  71,  69,  84,   0, 
-    171, 171,  83,  72,  68,  82, 
-    244,   0,   0,   0,  64,   0, 
-      0,   0,  61,   0,   0,   0, 
-     88,  40,   0,   4,   0, 112, 
-     16,   0,   0,   0,   0,   0, 
-     68,  68,   0,   0,  98,  16, 
-      0,   3, 114,  16,  16,   0, 
-      2,   0,   0,   0, 101,   0, 
-      0,   3, 242,  32,  16,   0, 
-      0,   0,   0,   0, 104,   0, 
-      0,   2,   1,   0,   0,   0, 
-     61,  16,   0,   7, 242,   0, 
-     16,   0,   0,   0,   0,   0, 
-      1,  64,   0,   0,   0,   0, 
-      0,   0,  70, 126,  16,   0, 
-      0,   0,   0,   0,  86,   0, 
-      0,   5, 114,   0,  16,   0, 
-      0,   0,   0,   0,  70,   2, 
-     16,   0,   0,   0,   0,   0, 
-     56,   0,   0,   7, 114,   0, 
-     16,   0,   0,   0,   0,   0, 
-     70,   2,  16,   0,   0,   0, 
-      0,   0,  70,  18,  16,   0, 
-      2,   0,   0,   0,  27,   0, 
-      0,   5, 114,   0,  16,   0, 
-      0,   0,   0,   0,  70,   2, 
-     16,   0,   0,   0,   0,   0, 
-     54,   0,   0,   5, 130,   0, 
-     16,   0,   0,   0,   0,   0, 
-      1,  64,   0,   0,   0,   0, 
-      0,   0,  45,   0,   0,   7, 
-    242,   0,  16,   0,   0,   0, 
-      0,   0,  70,  14,  16,   0, 
-      0,   0,   0,   0,  70, 126, 
-     16,   0,   0,   0,   0,   0, 
-     54,   0,   0,   5, 114,  32, 
-     16,   0,   0,   0,   0,   0, 
-     70,   2,  16,   0,   0,   0, 
-      0,   0,  54,   0,   0,   5, 
-    130,  32,  16,   0,   0,   0, 
-      0,   0,   1,  64,   0,   0, 
-      0,   0,   0,   0,  62,   0, 
-      0,   1,  83,  84,  65,  84, 
-    116,   0,   0,   0,   9,   0, 
-      0,   0,   1,   0,   0,   0, 
-      0,   0,   0,   0,   2,   0, 
-      0,   0,   1,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   1,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   1,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   3,   0,   0,   0, 
-      0,   0,   0,   0,   2,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0
-};
+#if 0
+//
+// Generated by Microsoft (R) HLSL Shader Compiler 6.3.9600.16384
+//
+//
+// Resource Bindings:
+//
+// Name                                 Type  Format         Dim Slot Elements
+// ------------------------------ ---------- ------- ----------- ---- --------
+// TextureUI                         texture   uint4          3d    0        1
+//
+//
+//
+// Input signature:
+//
+// Name                 Index   Mask Register SysValue  Format   Used
+// -------------------- ----- ------ -------- -------- ------- ------
+// SV_POSITION              0   xyzw        0      POS   float       
+// SV_RENDERTARGETARRAYINDEX     0   x           1  RTINDEX    uint       
+// TEXCOORD                 0   xyz         2     NONE   float   xyz 
+//
+//
+// Output signature:
+//
+// Name                 Index   Mask Register SysValue  Format   Used
+// -------------------- ----- ------ -------- -------- ------- ------
+// SV_TARGET                0   xyzw        0   TARGET    uint   xyzw
+//
+ps_4_0
+dcl_resource_texture3d (uint,uint,uint,uint) t0
+dcl_input_ps linear v2.xyz
+dcl_output o0.xyzw
+dcl_temps 1
+resinfo_uint r0.xyzw, l(0), t0.xyzw
+utof r0.xyz, r0.xyzx
+mul r0.xyz, r0.xyzx, v2.xyzx
+ftoi r0.xyz, r0.xyzx
+mov r0.w, l(0)
+ld r0.xyzw, r0.xyzw, t0.xyzw
+mov o0.xyz, r0.xyzx
+mov o0.w, l(0)
+ret 
+// Approximately 9 instruction slots used
+#endif
+
+const BYTE g_PS_PassthroughRGB3DUI[] =
+{
+     68,  88,  66,  67, 253, 147, 
+      1, 158,  41,  31, 253, 138, 
+     52, 213, 103,  41, 188, 192, 
+     79, 199,   1,   0,   0,   0, 
+    232,   2,   0,   0,   5,   0, 
+      0,   0,  52,   0,   0,   0, 
+    180,   0,   0,   0,  60,   1, 
+      0,   0, 112,   1,   0,   0, 
+    108,   2,   0,   0,  82,  68, 
+     69,  70, 120,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   1,   0,   0,   0, 
+     28,   0,   0,   0,   0,   4, 
+    255, 255,   0,   1,   0,   0, 
+     70,   0,   0,   0,  60,   0, 
+      0,   0,   2,   0,   0,   0, 
+      4,   0,   0,   0,   8,   0, 
+      0,   0, 255, 255, 255, 255, 
+      0,   0,   0,   0,   1,   0, 
+      0,   0,  13,   0,   0,   0, 
+     84, 101, 120, 116, 117, 114, 
+    101,  85,  73,   0,  77, 105, 
+     99, 114, 111, 115, 111, 102, 
+    116,  32,  40,  82,  41,  32, 
+     72,  76,  83,  76,  32,  83, 
+    104,  97, 100, 101, 114,  32, 
+     67, 111, 109, 112, 105, 108, 
+    101, 114,  32,  54,  46,  51, 
+     46,  57,  54,  48,  48,  46, 
+     49,  54,  51,  56,  52,   0, 
+     73,  83,  71,  78, 128,   0, 
+      0,   0,   3,   0,   0,   0, 
+      8,   0,   0,   0,  80,   0, 
+      0,   0,   0,   0,   0,   0, 
+      1,   0,   0,   0,   3,   0, 
+      0,   0,   0,   0,   0,   0, 
+     15,   0,   0,   0,  92,   0, 
+      0,   0,   0,   0,   0,   0, 
+      4,   0,   0,   0,   1,   0, 
+      0,   0,   1,   0,   0,   0, 
+      1,   0,   0,   0, 118,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   3,   0, 
+      0,   0,   2,   0,   0,   0, 
+      7,   7,   0,   0,  83,  86, 
+     95,  80,  79,  83,  73,  84, 
+     73,  79,  78,   0,  83,  86, 
+     95,  82,  69,  78,  68,  69, 
+     82,  84,  65,  82,  71,  69, 
+     84,  65,  82,  82,  65,  89, 
+     73,  78,  68,  69,  88,   0, 
+     84,  69,  88,  67,  79,  79, 
+     82,  68,   0, 171,  79,  83, 
+     71,  78,  44,   0,   0,   0, 
+      1,   0,   0,   0,   8,   0, 
+      0,   0,  32,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   1,   0,   0,   0, 
+      0,   0,   0,   0,  15,   0, 
+      0,   0,  83,  86,  95,  84, 
+     65,  82,  71,  69,  84,   0, 
+    171, 171,  83,  72,  68,  82, 
+    244,   0,   0,   0,  64,   0, 
+      0,   0,  61,   0,   0,   0, 
+     88,  40,   0,   4,   0, 112, 
+     16,   0,   0,   0,   0,   0, 
+     68,  68,   0,   0,  98,  16, 
+      0,   3, 114,  16,  16,   0, 
+      2,   0,   0,   0, 101,   0, 
+      0,   3, 242,  32,  16,   0, 
+      0,   0,   0,   0, 104,   0, 
+      0,   2,   1,   0,   0,   0, 
+     61,  16,   0,   7, 242,   0, 
+     16,   0,   0,   0,   0,   0, 
+      1,  64,   0,   0,   0,   0, 
+      0,   0,  70, 126,  16,   0, 
+      0,   0,   0,   0,  86,   0, 
+      0,   5, 114,   0,  16,   0, 
+      0,   0,   0,   0,  70,   2, 
+     16,   0,   0,   0,   0,   0, 
+     56,   0,   0,   7, 114,   0, 
+     16,   0,   0,   0,   0,   0, 
+     70,   2,  16,   0,   0,   0, 
+      0,   0,  70,  18,  16,   0, 
+      2,   0,   0,   0,  27,   0, 
+      0,   5, 114,   0,  16,   0, 
+      0,   0,   0,   0,  70,   2, 
+     16,   0,   0,   0,   0,   0, 
+     54,   0,   0,   5, 130,   0, 
+     16,   0,   0,   0,   0,   0, 
+      1,  64,   0,   0,   0,   0, 
+      0,   0,  45,   0,   0,   7, 
+    242,   0,  16,   0,   0,   0, 
+      0,   0,  70,  14,  16,   0, 
+      0,   0,   0,   0,  70, 126, 
+     16,   0,   0,   0,   0,   0, 
+     54,   0,   0,   5, 114,  32, 
+     16,   0,   0,   0,   0,   0, 
+     70,   2,  16,   0,   0,   0, 
+      0,   0,  54,   0,   0,   5, 
+    130,  32,  16,   0,   0,   0, 
+      0,   0,   1,  64,   0,   0, 
+      0,   0,   0,   0,  62,   0, 
+      0,   1,  83,  84,  65,  84, 
+    116,   0,   0,   0,   9,   0, 
+      0,   0,   1,   0,   0,   0, 
+      0,   0,   0,   0,   2,   0, 
+      0,   0,   1,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   1,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   1,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   3,   0,   0,   0, 
+      0,   0,   0,   0,   2,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0
+};
--- a/gfx/angle/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrgba2d11ps.h
+++ b/gfx/angle/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrgba2d11ps.h
@@ -1,176 +1,176 @@
-#if 0
-//
-// Generated by Microsoft (R) HLSL Shader Compiler 6.3.9600.16384
-//
-//
-// Resource Bindings:
-//
-// Name                                 Type  Format         Dim Slot Elements
-// ------------------------------ ---------- ------- ----------- ---- --------
-// Sampler                           sampler      NA          NA    0        1
-// TextureF                          texture  float4          2d    0        1
-//
-//
-//
-// Input signature:
-//
-// Name                 Index   Mask Register SysValue  Format   Used
-// -------------------- ----- ------ -------- -------- ------- ------
-// SV_POSITION              0   xyzw        0      POS   float       
-// TEXCOORD                 0   xy          1     NONE   float   xy  
-//
-//
-// Output signature:
-//
-// Name                 Index   Mask Register SysValue  Format   Used
-// -------------------- ----- ------ -------- -------- ------- ------
-// SV_TARGET                0   xyzw        0   TARGET   float   xyzw
-//
-//
-// Sampler/Resource to DX9 shader sampler mappings:
-//
-// Target Sampler Source Sampler  Source Resource
-// -------------- --------------- ----------------
-// s0             s0              t0               
-//
-//
-// Level9 shader bytecode:
-//
-    ps_2_x
-    dcl t0.xy
-    dcl_2d s0
-    texld r0, t0, s0
-    mov oC0, r0
-
-// approximately 2 instruction slots used (1 texture, 1 arithmetic)
-ps_4_0
-dcl_sampler s0, mode_default
-dcl_resource_texture2d (float,float,float,float) t0
-dcl_input_ps linear v1.xy
-dcl_output o0.xyzw
-sample o0.xyzw, v1.xyxx, t0.xyzw, s0
-ret 
-// Approximately 2 instruction slots used
-#endif
-
-const BYTE g_PS_PassthroughRGBA2D[] =
-{
-     68,  88,  66,  67, 240, 186, 
-    163, 221, 151,  45, 139,  68, 
-    172, 121,  30, 230, 203, 102, 
-     92,  33,   1,   0,   0,   0, 
-    192,   2,   0,   0,   6,   0, 
-      0,   0,  56,   0,   0,   0, 
-    164,   0,   0,   0,  16,   1, 
-      0,   0, 140,   1,   0,   0, 
-     52,   2,   0,   0, 140,   2, 
-      0,   0,  65, 111, 110,  57, 
-    100,   0,   0,   0, 100,   0, 
-      0,   0,   0,   2, 255, 255, 
-     60,   0,   0,   0,  40,   0, 
-      0,   0,   0,   0,  40,   0, 
-      0,   0,  40,   0,   0,   0, 
-     40,   0,   1,   0,  36,   0, 
-      0,   0,  40,   0,   0,   0, 
-      0,   0,   1,   2, 255, 255, 
-     31,   0,   0,   2,   0,   0, 
-      0, 128,   0,   0,   3, 176, 
-     31,   0,   0,   2,   0,   0, 
-      0, 144,   0,   8,  15, 160, 
-     66,   0,   0,   3,   0,   0, 
-     15, 128,   0,   0, 228, 176, 
-      0,   8, 228, 160,   1,   0, 
-      0,   2,   0,   8,  15, 128, 
-      0,   0, 228, 128, 255, 255, 
-      0,   0,  83,  72,  68,  82, 
-    100,   0,   0,   0,  64,   0, 
-      0,   0,  25,   0,   0,   0, 
-     90,   0,   0,   3,   0,  96, 
-     16,   0,   0,   0,   0,   0, 
-     88,  24,   0,   4,   0, 112, 
-     16,   0,   0,   0,   0,   0, 
-     85,  85,   0,   0,  98,  16, 
-      0,   3,  50,  16,  16,   0, 
-      1,   0,   0,   0, 101,   0, 
-      0,   3, 242,  32,  16,   0, 
-      0,   0,   0,   0,  69,   0, 
-      0,   9, 242,  32,  16,   0, 
-      0,   0,   0,   0,  70,  16, 
-     16,   0,   1,   0,   0,   0, 
-     70, 126,  16,   0,   0,   0, 
-      0,   0,   0,  96,  16,   0, 
-      0,   0,   0,   0,  62,   0, 
-      0,   1,  83,  84,  65,  84, 
-    116,   0,   0,   0,   2,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   2,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   1,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      1,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-     82,  68,  69,  70, 160,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   2,   0, 
-      0,   0,  28,   0,   0,   0, 
-      0,   4, 255, 255,   0,   1, 
-      0,   0, 109,   0,   0,   0, 
-     92,   0,   0,   0,   3,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      1,   0,   0,   0,   1,   0, 
-      0,   0, 100,   0,   0,   0, 
-      2,   0,   0,   0,   5,   0, 
-      0,   0,   4,   0,   0,   0, 
-    255, 255, 255, 255,   0,   0, 
-      0,   0,   1,   0,   0,   0, 
-     13,   0,   0,   0,  83,  97, 
-    109, 112, 108, 101, 114,   0, 
-     84, 101, 120, 116, 117, 114, 
-    101,  70,   0,  77, 105,  99, 
-    114, 111, 115, 111, 102, 116, 
-     32,  40,  82,  41,  32,  72, 
-     76,  83,  76,  32,  83, 104, 
-     97, 100, 101, 114,  32,  67, 
-    111, 109, 112, 105, 108, 101, 
-    114,  32,  54,  46,  51,  46, 
-     57,  54,  48,  48,  46,  49, 
-     54,  51,  56,  52,   0, 171, 
-     73,  83,  71,  78,  80,   0, 
-      0,   0,   2,   0,   0,   0, 
-      8,   0,   0,   0,  56,   0, 
-      0,   0,   0,   0,   0,   0, 
-      1,   0,   0,   0,   3,   0, 
-      0,   0,   0,   0,   0,   0, 
-     15,   0,   0,   0,  68,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   3,   0, 
-      0,   0,   1,   0,   0,   0, 
-      3,   3,   0,   0,  83,  86, 
-     95,  80,  79,  83,  73,  84, 
-     73,  79,  78,   0,  84,  69, 
-     88,  67,  79,  79,  82,  68, 
-      0, 171, 171, 171,  79,  83, 
-     71,  78,  44,   0,   0,   0, 
-      1,   0,   0,   0,   8,   0, 
-      0,   0,  32,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   3,   0,   0,   0, 
-      0,   0,   0,   0,  15,   0, 
-      0,   0,  83,  86,  95,  84, 
-     65,  82,  71,  69,  84,   0, 
-    171, 171
-};
+#if 0
+//
+// Generated by Microsoft (R) HLSL Shader Compiler 6.3.9600.16384
+//
+//
+// Resource Bindings:
+//
+// Name                                 Type  Format         Dim Slot Elements
+// ------------------------------ ---------- ------- ----------- ---- --------
+// Sampler                           sampler      NA          NA    0        1
+// TextureF                          texture  float4          2d    0        1
+//
+//
+//
+// Input signature:
+//
+// Name                 Index   Mask Register SysValue  Format   Used
+// -------------------- ----- ------ -------- -------- ------- ------
+// SV_POSITION              0   xyzw        0      POS   float       
+// TEXCOORD                 0   xy          1     NONE   float   xy  
+//
+//
+// Output signature:
+//
+// Name                 Index   Mask Register SysValue  Format   Used
+// -------------------- ----- ------ -------- -------- ------- ------
+// SV_TARGET                0   xyzw        0   TARGET   float   xyzw
+//
+//
+// Sampler/Resource to DX9 shader sampler mappings:
+//
+// Target Sampler Source Sampler  Source Resource
+// -------------- --------------- ----------------
+// s0             s0              t0               
+//
+//
+// Level9 shader bytecode:
+//
+    ps_2_x
+    dcl t0.xy
+    dcl_2d s0
+    texld r0, t0, s0
+    mov oC0, r0
+
+// approximately 2 instruction slots used (1 texture, 1 arithmetic)
+ps_4_0
+dcl_sampler s0, mode_default
+dcl_resource_texture2d (float,float,float,float) t0
+dcl_input_ps linear v1.xy
+dcl_output o0.xyzw
+sample o0.xyzw, v1.xyxx, t0.xyzw, s0
+ret 
+// Approximately 2 instruction slots used
+#endif
+
+const BYTE g_PS_PassthroughRGBA2D[] =
+{
+     68,  88,  66,  67, 240, 186, 
+    163, 221, 151,  45, 139,  68, 
+    172, 121,  30, 230, 203, 102, 
+     92,  33,   1,   0,   0,   0, 
+    192,   2,   0,   0,   6,   0, 
+      0,   0,  56,   0,   0,   0, 
+    164,   0,   0,   0,  16,   1, 
+      0,   0, 140,   1,   0,   0, 
+     52,   2,   0,   0, 140,   2, 
+      0,   0,  65, 111, 110,  57, 
+    100,   0,   0,   0, 100,   0, 
+      0,   0,   0,   2, 255, 255, 
+     60,   0,   0,   0,  40,   0, 
+      0,   0,   0,   0,  40,   0, 
+      0,   0,  40,   0,   0,   0, 
+     40,   0,   1,   0,  36,   0, 
+      0,   0,  40,   0,   0,   0, 
+      0,   0,   1,   2, 255, 255, 
+     31,   0,   0,   2,   0,   0, 
+      0, 128,   0,   0,   3, 176, 
+     31,   0,   0,   2,   0,   0, 
+      0, 144,   0,   8,  15, 160, 
+     66,   0,   0,   3,   0,   0, 
+     15, 128,   0,   0, 228, 176, 
+      0,   8, 228, 160,   1,   0, 
+      0,   2,   0,   8,  15, 128, 
+      0,   0, 228, 128, 255, 255, 
+      0,   0,  83,  72,  68,  82, 
+    100,   0,   0,   0,  64,   0, 
+      0,   0,  25,   0,   0,   0, 
+     90,   0,   0,   3,   0,  96, 
+     16,   0,   0,   0,   0,   0, 
+     88,  24,   0,   4,   0, 112, 
+     16,   0,   0,   0,   0,   0, 
+     85,  85,   0,   0,  98,  16, 
+      0,   3,  50,  16,  16,   0, 
+      1,   0,   0,   0, 101,   0, 
+      0,   3, 242,  32,  16,   0, 
+      0,   0,   0,   0,  69,   0, 
+      0,   9, 242,  32,  16,   0, 
+      0,   0,   0,   0,  70,  16, 
+     16,   0,   1,   0,   0,   0, 
+     70, 126,  16,   0,   0,   0, 
+      0,   0,   0,  96,  16,   0, 
+      0,   0,   0,   0,  62,   0, 
+      0,   1,  83,  84,  65,  84, 
+    116,   0,   0,   0,   2,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   2,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   1,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      1,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+     82,  68,  69,  70, 160,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   2,   0, 
+      0,   0,  28,   0,   0,   0, 
+      0,   4, 255, 255,   0,   1, 
+      0,   0, 109,   0,   0,   0, 
+     92,   0,   0,   0,   3,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      1,   0,   0,   0,   1,   0, 
+      0,   0, 100,   0,   0,   0, 
+      2,   0,   0,   0,   5,   0, 
+      0,   0,   4,   0,   0,   0, 
+    255, 255, 255, 255,   0,   0, 
+      0,   0,   1,   0,   0,   0, 
+     13,   0,   0,   0,  83,  97, 
+    109, 112, 108, 101, 114,   0, 
+     84, 101, 120, 116, 117, 114, 
+    101,  70,   0,  77, 105,  99, 
+    114, 111, 115, 111, 102, 116, 
+     32,  40,  82,  41,  32,  72, 
+     76,  83,  76,  32,  83, 104, 
+     97, 100, 101, 114,  32,  67, 
+    111, 109, 112, 105, 108, 101, 
+    114,  32,  54,  46,  51,  46, 
+     57,  54,  48,  48,  46,  49, 
+     54,  51,  56,  52,   0, 171, 
+     73,  83,  71,  78,  80,   0, 
+      0,   0,   2,   0,   0,   0, 
+      8,   0,   0,   0,  56,   0, 
+      0,   0,   0,   0,   0,   0, 
+      1,   0,   0,   0,   3,   0, 
+      0,   0,   0,   0,   0,   0, 
+     15,   0,   0,   0,  68,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   3,   0, 
+      0,   0,   1,   0,   0,   0, 
+      3,   3,   0,   0,  83,  86, 
+     95,  80,  79,  83,  73,  84, 
+     73,  79,  78,   0,  84,  69, 
+     88,  67,  79,  79,  82,  68, 
+      0, 171, 171, 171,  79,  83, 
+     71,  78,  44,   0,   0,   0, 
+      1,   0,   0,   0,   8,   0, 
+      0,   0,  32,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   3,   0,   0,   0, 
+      0,   0,   0,   0,  15,   0, 
+      0,   0,  83,  86,  95,  84, 
+     65,  82,  71,  69,  84,   0, 
+    171, 171
+};
--- a/gfx/angle/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrgba2di11ps.h
+++ b/gfx/angle/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrgba2di11ps.h
@@ -1,157 +1,157 @@
-#if 0
-//
-// Generated by Microsoft (R) HLSL Shader Compiler 6.3.9600.16384
-//
-//
-// Resource Bindings:
-//
-// Name                                 Type  Format         Dim Slot Elements
-// ------------------------------ ---------- ------- ----------- ---- --------
-// TextureI                          texture   sint4          2d    0        1
-//
-//
-//
-// Input signature:
-//
-// Name                 Index   Mask Register SysValue  Format   Used
-// -------------------- ----- ------ -------- -------- ------- ------
-// SV_POSITION              0   xyzw        0      POS   float       
-// TEXCOORD                 0   xy          1     NONE   float   xy  
-//
-//
-// Output signature:
-//
-// Name                 Index   Mask Register SysValue  Format   Used
-// -------------------- ----- ------ -------- -------- ------- ------
-// SV_TARGET                0   xyzw        0   TARGET     int   xyzw
-//
-ps_4_0
-dcl_resource_texture2d (sint,sint,sint,sint) t0
-dcl_input_ps linear v1.xy
-dcl_output o0.xyzw
-dcl_temps 1
-resinfo_uint r0.xyzw, l(0), t0.xyzw
-utof r0.xy, r0.xyxx
-mul r0.xy, r0.xyxx, v1.xyxx
-ftoi r0.xy, r0.xyxx
-mov r0.zw, l(0,0,0,0)
-ld o0.xyzw, r0.xyzw, t0.xyzw
-ret 
-// Approximately 7 instruction slots used
-#endif
-
-const BYTE g_PS_PassthroughRGBA2DI[] =
-{
-     68,  88,  66,  67,  81, 147, 
-    194, 141,  92, 236, 184, 192, 
-     11, 249,  14, 215, 122, 110, 
-     35, 111,   1,   0,   0,   0, 
-    156,   2,   0,   0,   5,   0, 
-      0,   0,  52,   0,   0,   0, 
-    180,   0,   0,   0,  12,   1, 
-      0,   0,  64,   1,   0,   0, 
-     32,   2,   0,   0,  82,  68, 
-     69,  70, 120,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   1,   0,   0,   0, 
-     28,   0,   0,   0,   0,   4, 
-    255, 255,   0,   1,   0,   0, 
-     69,   0,   0,   0,  60,   0, 
-      0,   0,   2,   0,   0,   0, 
-      3,   0,   0,   0,   4,   0, 
-      0,   0, 255, 255, 255, 255, 
-      0,   0,   0,   0,   1,   0, 
-      0,   0,  13,   0,   0,   0, 
-     84, 101, 120, 116, 117, 114, 
-    101,  73,   0,  77, 105,  99, 
-    114, 111, 115, 111, 102, 116, 
-     32,  40,  82,  41,  32,  72, 
-     76,  83,  76,  32,  83, 104, 
-     97, 100, 101, 114,  32,  67, 
-    111, 109, 112, 105, 108, 101, 
-    114,  32,  54,  46,  51,  46, 
-     57,  54,  48,  48,  46,  49, 
-     54,  51,  56,  52,   0, 171, 
-     73,  83,  71,  78,  80,   0, 
-      0,   0,   2,   0,   0,   0, 
-      8,   0,   0,   0,  56,   0, 
-      0,   0,   0,   0,   0,   0, 
-      1,   0,   0,   0,   3,   0, 
-      0,   0,   0,   0,   0,   0, 
-     15,   0,   0,   0,  68,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   3,   0, 
-      0,   0,   1,   0,   0,   0, 
-      3,   3,   0,   0,  83,  86, 
-     95,  80,  79,  83,  73,  84, 
-     73,  79,  78,   0,  84,  69, 
-     88,  67,  79,  79,  82,  68, 
-      0, 171, 171, 171,  79,  83, 
-     71,  78,  44,   0,   0,   0, 
-      1,   0,   0,   0,   8,   0, 
-      0,   0,  32,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   2,   0,   0,   0, 
-      0,   0,   0,   0,  15,   0, 
-      0,   0,  83,  86,  95,  84, 
-     65,  82,  71,  69,  84,   0, 
-    171, 171,  83,  72,  68,  82, 
-    216,   0,   0,   0,  64,   0, 
-      0,   0,  54,   0,   0,   0, 
-     88,  24,   0,   4,   0, 112, 
-     16,   0,   0,   0,   0,   0, 
-     51,  51,   0,   0,  98,  16, 
-      0,   3,  50,  16,  16,   0, 
-      1,   0,   0,   0, 101,   0, 
-      0,   3, 242,  32,  16,   0, 
-      0,   0,   0,   0, 104,   0, 
-      0,   2,   1,   0,   0,   0, 
-     61,  16,   0,   7, 242,   0, 
-     16,   0,   0,   0,   0,   0, 
-      1,  64,   0,   0,   0,   0, 
-      0,   0,  70, 126,  16,   0, 
-      0,   0,   0,   0,  86,   0, 
-      0,   5,  50,   0,  16,   0, 
-      0,   0,   0,   0,  70,   0, 
-     16,   0,   0,   0,   0,   0, 
-     56,   0,   0,   7,  50,   0, 
-     16,   0,   0,   0,   0,   0, 
-     70,   0,  16,   0,   0,   0, 
-      0,   0,  70,  16,  16,   0, 
-      1,   0,   0,   0,  27,   0, 
-      0,   5,  50,   0,  16,   0, 
-      0,   0,   0,   0,  70,   0, 
-     16,   0,   0,   0,   0,   0, 
-     54,   0,   0,   8, 194,   0, 
-     16,   0,   0,   0,   0,   0, 
-      2,  64,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,  45,   0,   0,   7, 
-    242,  32,  16,   0,   0,   0, 
-      0,   0,  70,  14,  16,   0, 
-      0,   0,   0,   0,  70, 126, 
-     16,   0,   0,   0,   0,   0, 
-     62,   0,   0,   1,  83,  84, 
-     65,  84, 116,   0,   0,   0, 
-      7,   0,   0,   0,   1,   0, 
-      0,   0,   0,   0,   0,   0, 
-      2,   0,   0,   0,   1,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   1,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      1,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   1,   0, 
-      0,   0,   0,   0,   0,   0, 
-      2,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0
-};
+#if 0
+//
+// Generated by Microsoft (R) HLSL Shader Compiler 6.3.9600.16384
+//
+//
+// Resource Bindings:
+//
+// Name                                 Type  Format         Dim Slot Elements
+// ------------------------------ ---------- ------- ----------- ---- --------
+// TextureI                          texture   sint4          2d    0        1
+//
+//
+//
+// Input signature:
+//
+// Name                 Index   Mask Register SysValue  Format   Used
+// -------------------- ----- ------ -------- -------- ------- ------
+// SV_POSITION              0   xyzw        0      POS   float       
+// TEXCOORD                 0   xy          1     NONE   float   xy  
+//
+//
+// Output signature:
+//
+// Name                 Index   Mask Register SysValue  Format   Used
+// -------------------- ----- ------ -------- -------- ------- ------
+// SV_TARGET                0   xyzw        0   TARGET     int   xyzw
+//
+ps_4_0
+dcl_resource_texture2d (sint,sint,sint,sint) t0
+dcl_input_ps linear v1.xy
+dcl_output o0.xyzw
+dcl_temps 1
+resinfo_uint r0.xyzw, l(0), t0.xyzw
+utof r0.xy, r0.xyxx
+mul r0.xy, r0.xyxx, v1.xyxx
+ftoi r0.xy, r0.xyxx
+mov r0.zw, l(0,0,0,0)
+ld o0.xyzw, r0.xyzw, t0.xyzw
+ret 
+// Approximately 7 instruction slots used
+#endif
+
+const BYTE g_PS_PassthroughRGBA2DI[] =
+{
+     68,  88,  66,  67,  81, 147, 
+    194, 141,  92, 236, 184, 192, 
+     11, 249,  14, 215, 122, 110, 
+     35, 111,   1,   0,   0,   0, 
+    156,   2,   0,   0,   5,   0, 
+      0,   0,  52,   0,   0,   0, 
+    180,   0,   0,   0,  12,   1, 
+      0,   0,  64,   1,   0,   0, 
+     32,   2,   0,   0,  82,  68, 
+     69,  70, 120,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   1,   0,   0,   0, 
+     28,   0,   0,   0,   0,   4, 
+    255, 255,   0,   1,   0,   0, 
+     69,   0,   0,   0,  60,   0, 
+      0,   0,   2,   0,   0,   0, 
+      3,   0,   0,   0,   4,   0, 
+      0,   0, 255, 255, 255, 255, 
+      0,   0,   0,   0,   1,   0, 
+      0,   0,  13,   0,   0,   0, 
+     84, 101, 120, 116, 117, 114, 
+    101,  73,   0,  77, 105,  99, 
+    114, 111, 115, 111, 102, 116, 
+     32,  40,  82,  41,  32,  72, 
+     76,  83,  76,  32,  83, 104, 
+     97, 100, 101, 114,  32,  67, 
+    111, 109, 112, 105, 108, 101, 
+    114,  32,  54,  46,  51,  46, 
+     57,  54,  48,  48,  46,  49, 
+     54,  51,  56,  52,   0, 171, 
+     73,  83,  71,  78,  80,   0, 
+      0,   0,   2,   0,   0,   0, 
+      8,   0,   0,   0,  56,   0, 
+      0,   0,   0,   0,   0,   0, 
+      1,   0,   0,   0,   3,   0, 
+      0,   0,   0,   0,   0,   0, 
+     15,   0,   0,   0,  68,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   3,   0, 
+      0,   0,   1,   0,   0,   0, 
+      3,   3,   0,   0,  83,  86, 
+     95,  80,  79,  83,  73,  84, 
+     73,  79,  78,   0,  84,  69, 
+     88,  67,  79,  79,  82,  68, 
+      0, 171, 171, 171,  79,  83, 
+     71,  78,  44,   0,   0,   0, 
+      1,   0,   0,   0,   8,   0, 
+      0,   0,  32,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   2,   0,   0,   0, 
+      0,   0,   0,   0,  15,   0, 
+      0,   0,  83,  86,  95,  84, 
+     65,  82,  71,  69,  84,   0, 
+    171, 171,  83,  72,  68,  82, 
+    216,   0,   0,   0,  64,   0, 
+      0,   0,  54,   0,   0,   0, 
+     88,  24,   0,   4,   0, 112, 
+     16,   0,   0,   0,   0,   0, 
+     51,  51,   0,   0,  98,  16, 
+      0,   3,  50,  16,  16,   0, 
+      1,   0,   0,   0, 101,   0, 
+      0,   3, 242,  32,  16,   0, 
+      0,   0,   0,   0, 104,   0, 
+      0,   2,   1,   0,   0,   0, 
+     61,  16,   0,   7, 242,   0, 
+     16,   0,   0,   0,   0,   0, 
+      1,  64,   0,   0,   0,   0, 
+      0,   0,  70, 126,  16,   0, 
+      0,   0,   0,   0,  86,   0, 
+      0,   5,  50,   0,  16,   0, 
+      0,   0,   0,   0,  70,   0, 
+     16,   0,   0,   0,   0,   0, 
+     56,   0,   0,   7,  50,   0, 
+     16,   0,   0,   0,   0,   0, 
+     70,   0,  16,   0,   0,   0, 
+      0,   0,  70,  16,  16,   0, 
+      1,   0,   0,   0,  27,   0, 
+      0,   5,  50,   0,  16,   0, 
+      0,   0,   0,   0,  70,   0, 
+     16,   0,   0,   0,   0,   0, 
+     54,   0,   0,   8, 194,   0, 
+     16,   0,   0,   0,   0,   0, 
+      2,  64,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,  45,   0,   0,   7, 
+    242,  32,  16,   0,   0,   0, 
+      0,   0,  70,  14,  16,   0, 
+      0,   0,   0,   0,  70, 126, 
+     16,   0,   0,   0,   0,   0, 
+     62,   0,   0,   1,  83,  84, 
+     65,  84, 116,   0,   0,   0, 
+      7,   0,   0,   0,   1,   0, 
+      0,   0,   0,   0,   0,   0, 
+      2,   0,   0,   0,   1,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   1,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      1,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   1,   0, 
+      0,   0,   0,   0,   0,   0, 
+      2,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0
+};
--- a/gfx/angle/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrgba2dms11ps.h
+++ b/gfx/angle/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrgba2dms11ps.h
@@ -1,80 +1,80 @@
-#if 0
-//
-// Generated by Microsoft (R) HLSL Shader Compiler 6.3.9600.16384
-//
-//
-// Resource Bindings:
-//
-// Name                                 Type  Format         Dim Slot Elements
-// ------------------------------ ---------- ------- ----------- ---- --------
-// TextureF_MS                       texture  float4        2dMS    0        1
-//
-//
-//
-// Input signature:
-//
-// Name                 Index   Mask Register SysValue  Format   Used
-// -------------------- ----- ------ -------- -------- ------- ------
-// SV_POSITION              0   xyzw        0      POS   float       
-// TEXCORD                  0   xy          1     NONE   float   xy  
-// SV_SAMPLEINDEX           0   x           2   SAMPLE    uint   x   
-//
-//
-// Output signature:
-//
-// Name                 Index   Mask Register SysValue  Format   Used
-// -------------------- ----- ------ -------- -------- ------- ------
-// SV_TARGET                0   xyzw        0   TARGET   float   xyzw
-//
-// Pixel Shader runs at sample frequency
-//
-ps_4_1
-dcl_globalFlags refactoringAllowed
-dcl_resource_texture2dms(0) (float,float,float,float) t0
-dcl_input_ps linear v1.xy
-dcl_input_ps_sgv v2.x, sampleIndex
-dcl_output o0.xyzw
-dcl_temps 1
-ftou r0.xy, v1.xyxx
-mov r0.zw, l(0,0,0,0)
-ldms o0.xyzw, r0.xyzw, t0.xyzw, v2.x
-ret 
-// Approximately 4 instruction slots used
-#endif
-
-const BYTE g_PS_PassthroughRGBA2DMS[] = {
-    68,  88,  66,  67,  24,  185, 64,  224, 216, 192, 107, 84,  140, 208, 46, 210, 75,  20,  1,
-    202, 1,   0,   0,   0,   148, 2,   0,   0,   5,   0,   0,   0,   52,  0,  0,   0,   184, 0,
-    0,   0,   52,  1,   0,   0,   104, 1,   0,   0,   24,  2,   0,   0,   82, 68,  69,  70,  124,
-    0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   1,   0,   0,   0,  28,  0,   0,   0,
-    1,   4,   255, 255, 0,   1,   0,   0,   72,  0,   0,   0,   60,  0,   0,  0,   2,   0,   0,
-    0,   5,   0,   0,   0,   6,   0,   0,   0,   0,   0,   0,   0,   0,   0,  0,   0,   1,   0,
-    0,   0,   13,  0,   0,   0,   84,  101, 120, 116, 117, 114, 101, 70,  95, 77,  83,  0,   77,
-    105, 99,  114, 111, 115, 111, 102, 116, 32,  40,  82,  41,  32,  72,  76, 83,  76,  32,  83,
-    104, 97,  100, 101, 114, 32,  67,  111, 109, 112, 105, 108, 101, 114, 32, 54,  46,  51,  46,
-    57,  54,  48,  48,  46,  49,  54,  51,  56,  52,  0,   171, 171, 73,  83, 71,  78,  116, 0,
-    0,   0,   3,   0,   0,   0,   8,   0,   0,   0,   80,  0,   0,   0,   0,  0,   0,   0,   1,
-    0,   0,   0,   3,   0,   0,   0,   0,   0,   0,   0,   15,  0,   0,   0,  92,  0,   0,   0,
-    0,   0,   0,   0,   0,   0,   0,   0,   3,   0,   0,   0,   1,   0,   0,  0,   3,   3,   0,
-    0,   100, 0,   0,   0,   0,   0,   0,   0,   10,  0,   0,   0,   1,   0,  0,   0,   2,   0,
-    0,   0,   1,   1,   0,   0,   83,  86,  95,  80,  79,  83,  73,  84,  73, 79,  78,  0,   84,
-    69,  88,  67,  79,  82,  68,  0,   83,  86,  95,  83,  65,  77,  80,  76, 69,  73,  78,  68,
-    69,  88,  0,   171, 79,  83,  71,  78,  44,  0,   0,   0,   1,   0,   0,  0,   8,   0,   0,
-    0,   32,  0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   3,   0,  0,   0,   0,   0,
-    0,   0,   15,  0,   0,   0,   83,  86,  95,  84,  65,  82,  71,  69,  84, 0,   171, 171, 83,
-    72,  68,  82,  168, 0,   0,   0,   65,  0,   0,   0,   42,  0,   0,   0,  106, 8,   0,   1,
-    88,  32,  0,   4,   0,   112, 16,  0,   0,   0,   0,   0,   85,  85,  0,  0,   98,  16,  0,
-    3,   50,  16,  16,  0,   1,   0,   0,   0,   99,  8,   0,   4,   18,  16, 16,  0,   2,   0,
-    0,   0,   10,  0,   0,   0,   101, 0,   0,   3,   242, 32,  16,  0,   0,  0,   0,   0,   104,
-    0,   0,   2,   1,   0,   0,   0,   28,  0,   0,   5,   50,  0,   16,  0,  0,   0,   0,   0,
-    70,  16,  16,  0,   1,   0,   0,   0,   54,  0,   0,   8,   194, 0,   16, 0,   0,   0,   0,
-    0,   2,   64,  0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,  0,   0,   0,   0,
-    0,   0,   46,  0,   0,   9,   242, 32,  16,  0,   0,   0,   0,   0,   70, 14,  16,  0,   0,
-    0,   0,   0,   70,  126, 16,  0,   0,   0,   0,   0,   10,  16,  16,  0,  2,   0,   0,   0,
-    62,  0,   0,   1,   83,  84,  65,  84,  116, 0,   0,   0,   4,   0,   0,  0,   1,   0,   0,
-    0,   0,   0,   0,   0,   3,   0,   0,   0,   0,   0,   0,   0,   0,   0,  0,   0,   0,   0,
-    0,   0,   1,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,  0,   0,   0,   0,
-    0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,  1,   0,   0,   0,
-    0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   1,   0,   0,  0,   0,   0,   0,
-    0,   1,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,  0,   0,   0,   0,
-    0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   1,   0,   0,   0};
+#if 0
+//
+// Generated by Microsoft (R) HLSL Shader Compiler 6.3.9600.16384
+//
+//
+// Resource Bindings:
+//
+// Name                                 Type  Format         Dim Slot Elements
+// ------------------------------ ---------- ------- ----------- ---- --------
+// TextureF_MS                       texture  float4        2dMS    0        1
+//
+//
+//
+// Input signature:
+//
+// Name                 Index   Mask Register SysValue  Format   Used
+// -------------------- ----- ------ -------- -------- ------- ------
+// SV_POSITION              0   xyzw        0      POS   float       
+// TEXCORD                  0   xy          1     NONE   float   xy  
+// SV_SAMPLEINDEX           0   x           2   SAMPLE    uint   x   
+//
+//
+// Output signature:
+//
+// Name                 Index   Mask Register SysValue  Format   Used
+// -------------------- ----- ------ -------- -------- ------- ------
+// SV_TARGET                0   xyzw        0   TARGET   float   xyzw
+//
+// Pixel Shader runs at sample frequency
+//
+ps_4_1
+dcl_globalFlags refactoringAllowed
+dcl_resource_texture2dms(0) (float,float,float,float) t0
+dcl_input_ps linear v1.xy
+dcl_input_ps_sgv v2.x, sampleIndex
+dcl_output o0.xyzw
+dcl_temps 1
+ftou r0.xy, v1.xyxx
+mov r0.zw, l(0,0,0,0)
+ldms o0.xyzw, r0.xyzw, t0.xyzw, v2.x
+ret 
+// Approximately 4 instruction slots used
+#endif
+
+const BYTE g_PS_PassthroughRGBA2DMS[] = {
+    68,  88,  66,  67,  24,  185, 64,  224, 216, 192, 107, 84,  140, 208, 46, 210, 75,  20,  1,
+    202, 1,   0,   0,   0,   148, 2,   0,   0,   5,   0,   0,   0,   52,  0,  0,   0,   184, 0,
+    0,   0,   52,  1,   0,   0,   104, 1,   0,   0,   24,  2,   0,   0,   82, 68,  69,  70,  124,
+    0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   1,   0,   0,   0,  28,  0,   0,   0,
+    1,   4,   255, 255, 0,   1,   0,   0,   72,  0,   0,   0,   60,  0,   0,  0,   2,   0,   0,
+    0,   5,   0,   0,   0,   6,   0,   0,   0,   0,   0,   0,   0,   0,   0,  0,   0,   1,   0,
+    0,   0,   13,  0,   0,   0,   84,  101, 120, 116, 117, 114, 101, 70,  95, 77,  83,  0,   77,
+    105, 99,  114, 111, 115, 111, 102, 116, 32,  40,  82,  41,  32,  72,  76, 83,  76,  32,  83,
+    104, 97,  100, 101, 114, 32,  67,  111, 109, 112, 105, 108, 101, 114, 32, 54,  46,  51,  46,
+    57,  54,  48,  48,  46,  49,  54,  51,  56,  52,  0,   171, 171, 73,  83, 71,  78,  116, 0,
+    0,   0,   3,   0,   0,   0,   8,   0,   0,   0,   80,  0,   0,   0,   0,  0,   0,   0,   1,
+    0,   0,   0,   3,   0,   0,   0,   0,   0,   0,   0,   15,  0,   0,   0,  92,  0,   0,   0,
+    0,   0,   0,   0,   0,   0,   0,   0,   3,   0,   0,   0,   1,   0,   0,  0,   3,   3,   0,
+    0,   100, 0,   0,   0,   0,   0,   0,   0,   10,  0,   0,   0,   1,   0,  0,   0,   2,   0,
+    0,   0,   1,   1,   0,   0,   83,  86,  95,  80,  79,  83,  73,  84,  73, 79,  78,  0,   84,
+    69,  88,  67,  79,  82,  68,  0,   83,  86,  95,  83,  65,  77,  80,  76, 69,  73,  78,  68,
+    69,  88,  0,   171, 79,  83,  71,  78,  44,  0,   0,   0,   1,   0,   0,  0,   8,   0,   0,
+    0,   32,  0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   3,   0,  0,   0,   0,   0,
+    0,   0,   15,  0,   0,   0,   83,  86,  95,  84,  65,  82,  71,  69,  84, 0,   171, 171, 83,
+    72,  68,  82,  168, 0,   0,   0,   65,  0,   0,   0,   42,  0,   0,   0,  106, 8,   0,   1,
+    88,  32,  0,   4,   0,   112, 16,  0,   0,   0,   0,   0,   85,  85,  0,  0,   98,  16,  0,
+    3,   50,  16,  16,  0,   1,   0,   0,   0,   99,  8,   0,   4,   18,  16, 16,  0,   2,   0,
+    0,   0,   10,  0,   0,   0,   101, 0,   0,   3,   242, 32,  16,  0,   0,  0,   0,   0,   104,
+    0,   0,   2,   1,   0,   0,   0,   28,  0,   0,   5,   50,  0,   16,  0,  0,   0,   0,   0,
+    70,  16,  16,  0,   1,   0,   0,   0,   54,  0,   0,   8,   194, 0,   16, 0,   0,   0,   0,
+    0,   2,   64,  0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,  0,   0,   0,   0,
+    0,   0,   46,  0,   0,   9,   242, 32,  16,  0,   0,   0,   0,   0,   70, 14,  16,  0,   0,
+    0,   0,   0,   70,  126, 16,  0,   0,   0,   0,   0,   10,  16,  16,  0,  2,   0,   0,   0,
+    62,  0,   0,   1,   83,  84,  65,  84,  116, 0,   0,   0,   4,   0,   0,  0,   1,   0,   0,
+    0,   0,   0,   0,   0,   3,   0,   0,   0,   0,   0,   0,   0,   0,   0,  0,   0,   0,   0,
+    0,   0,   1,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,  0,   0,   0,   0,
+    0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,  1,   0,   0,   0,
+    0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   1,   0,   0,  0,   0,   0,   0,
+    0,   1,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,  0,   0,   0,   0,
+    0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   1,   0,   0,   0};
--- a/gfx/angle/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrgba2dui11ps.h
+++ b/gfx/angle/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrgba2dui11ps.h
@@ -1,157 +1,157 @@
-#if 0
-//
-// Generated by Microsoft (R) HLSL Shader Compiler 6.3.9600.16384
-//
-//
-// Resource Bindings:
-//
-// Name                                 Type  Format         Dim Slot Elements
-// ------------------------------ ---------- ------- ----------- ---- --------
-// TextureUI                         texture   uint4          2d    0        1
-//
-//
-//
-// Input signature:
-//
-// Name                 Index   Mask Register SysValue  Format   Used
-// -------------------- ----- ------ -------- -------- ------- ------
-// SV_POSITION              0   xyzw        0      POS   float       
-// TEXCOORD                 0   xy          1     NONE   float   xy  
-//
-//
-// Output signature:
-//
-// Name                 Index   Mask Register SysValue  Format   Used
-// -------------------- ----- ------ -------- -------- ------- ------
-// SV_TARGET                0   xyzw        0   TARGET    uint   xyzw
-//
-ps_4_0
-dcl_resource_texture2d (uint,uint,uint,uint) t0
-dcl_input_ps linear v1.xy
-dcl_output o0.xyzw
-dcl_temps 1
-resinfo_uint r0.xyzw, l(0), t0.xyzw
-utof r0.xy, r0.xyxx
-mul r0.xy, r0.xyxx, v1.xyxx
-ftoi r0.xy, r0.xyxx
-mov r0.zw, l(0,0,0,0)
-ld o0.xyzw, r0.xyzw, t0.xyzw
-ret 
-// Approximately 7 instruction slots used
-#endif
-
-const BYTE g_PS_PassthroughRGBA2DUI[] =
-{
-     68,  88,  66,  67, 128, 252, 
-    255, 238,  68, 109,  10, 133, 
-    175, 163, 216, 152, 219, 103, 
-    163, 223,   1,   0,   0,   0, 
-    156,   2,   0,   0,   5,   0, 
-      0,   0,  52,   0,   0,   0, 
-    180,   0,   0,   0,  12,   1, 
-      0,   0,  64,   1,   0,   0, 
-     32,   2,   0,   0,  82,  68, 
-     69,  70, 120,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   1,   0,   0,   0, 
-     28,   0,   0,   0,   0,   4, 
-    255, 255,   0,   1,   0,   0, 
-     70,   0,   0,   0,  60,   0, 
-      0,   0,   2,   0,   0,   0, 
-      4,   0,   0,   0,   4,   0, 
-      0,   0, 255, 255, 255, 255, 
-      0,   0,   0,   0,   1,   0, 
-      0,   0,  13,   0,   0,   0, 
-     84, 101, 120, 116, 117, 114, 
-    101,  85,  73,   0,  77, 105, 
-     99, 114, 111, 115, 111, 102, 
-    116,  32,  40,  82,  41,  32, 
-     72,  76,  83,  76,  32,  83, 
-    104,  97, 100, 101, 114,  32, 
-     67, 111, 109, 112, 105, 108, 
-    101, 114,  32,  54,  46,  51, 
-     46,  57,  54,  48,  48,  46, 
-     49,  54,  51,  56,  52,   0, 
-     73,  83,  71,  78,  80,   0, 
-      0,   0,   2,   0,   0,   0, 
-      8,   0,   0,   0,  56,   0, 
-      0,   0,   0,   0,   0,   0, 
-      1,   0,   0,   0,   3,   0, 
-      0,   0,   0,   0,   0,   0, 
-     15,   0,   0,   0,  68,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   3,   0, 
-      0,   0,   1,   0,   0,   0, 
-      3,   3,   0,   0,  83,  86, 
-     95,  80,  79,  83,  73,  84, 
-     73,  79,  78,   0,  84,  69, 
-     88,  67,  79,  79,  82,  68, 
-      0, 171, 171, 171,  79,  83, 
-     71,  78,  44,   0,   0,   0, 
-      1,   0,   0,   0,   8,   0, 
-      0,   0,  32,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   1,   0,   0,   0, 
-      0,   0,   0,   0,  15,   0, 
-      0,   0,  83,  86,  95,  84, 
-     65,  82,  71,  69,  84,   0, 
-    171, 171,  83,  72,  68,  82, 
-    216,   0,   0,   0,  64,   0, 
-      0,   0,  54,   0,   0,   0, 
-     88,  24,   0,   4,   0, 112, 
-     16,   0,   0,   0,   0,   0, 
-     68,  68,   0,   0,  98,  16, 
-      0,   3,  50,  16,  16,   0, 
-      1,   0,   0,   0, 101,   0, 
-      0,   3, 242,  32,  16,   0, 
-      0,   0,   0,   0, 104,   0, 
-      0,   2,   1,   0,   0,   0, 
-     61,  16,   0,   7, 242,   0, 
-     16,   0,   0,   0,   0,   0, 
-      1,  64,   0,   0,   0,   0, 
-      0,   0,  70, 126,  16,   0, 
-      0,   0,   0,   0,  86,   0, 
-      0,   5,  50,   0,  16,   0, 
-      0,   0,   0,   0,  70,   0, 
-     16,   0,   0,   0,   0,   0, 
-     56,   0,   0,   7,  50,   0, 
-     16,   0,   0,   0,   0,   0, 
-     70,   0,  16,   0,   0,   0, 
-      0,   0,  70,  16,  16,   0, 
-      1,   0,   0,   0,  27,   0, 
-      0,   5,  50,   0,  16,   0, 
-      0,   0,   0,   0,  70,   0, 
-     16,   0,   0,   0,   0,   0, 
-     54,   0,   0,   8, 194,   0, 
-     16,   0,   0,   0,   0,   0, 
-      2,  64,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,  45,   0,   0,   7, 
-    242,  32,  16,   0,   0,   0, 
-      0,   0,  70,  14,  16,   0, 
-      0,   0,   0,   0,  70, 126, 
-     16,   0,   0,   0,   0,   0, 
-     62,   0,   0,   1,  83,  84, 
-     65,  84, 116,   0,   0,   0, 
-      7,   0,   0,   0,   1,   0, 
-      0,   0,   0,   0,   0,   0, 
-      2,   0,   0,   0,   1,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   1,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      1,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   1,   0, 
-      0,   0,   0,   0,   0,   0, 
-      2,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0
-};
+#if 0
+//
+// Generated by Microsoft (R) HLSL Shader Compiler 6.3.9600.16384
+//
+//
+// Resource Bindings:
+//
+// Name                                 Type  Format         Dim Slot Elements
+// ------------------------------ ---------- ------- ----------- ---- --------
+// TextureUI                         texture   uint4          2d    0        1
+//
+//
+//
+// Input signature:
+//
+// Name                 Index   Mask Register SysValue  Format   Used
+// -------------------- ----- ------ -------- -------- ------- ------
+// SV_POSITION              0   xyzw        0      POS   float       
+// TEXCOORD                 0   xy          1     NONE   float   xy  
+//
+//
+// Output signature:
+//
+// Name                 Index   Mask Register SysValue  Format   Used
+// -------------------- ----- ------ -------- -------- ------- ------
+// SV_TARGET                0   xyzw        0   TARGET    uint   xyzw
+//
+ps_4_0
+dcl_resource_texture2d (uint,uint,uint,uint) t0
+dcl_input_ps linear v1.xy
+dcl_output o0.xyzw
+dcl_temps 1
+resinfo_uint r0.xyzw, l(0), t0.xyzw
+utof r0.xy, r0.xyxx
+mul r0.xy, r0.xyxx, v1.xyxx
+ftoi r0.xy, r0.xyxx
+mov r0.zw, l(0,0,0,0)
+ld o0.xyzw, r0.xyzw, t0.xyzw
+ret 
+// Approximately 7 instruction slots used
+#endif
+
+const BYTE g_PS_PassthroughRGBA2DUI[] =
+{
+     68,  88,  66,  67, 128, 252, 
+    255, 238,  68, 109,  10, 133, 
+    175, 163, 216, 152, 219, 103, 
+    163, 223,   1,   0,   0,   0, 
+    156,   2,   0,   0,   5,   0, 
+      0,   0,  52,   0,   0,   0, 
+    180,   0,   0,   0,  12,   1, 
+      0,   0,  64,   1,   0,   0, 
+     32,   2,   0,   0,  82,  68, 
+     69,  70, 120,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   1,   0,   0,   0, 
+     28,   0,   0,   0,   0,   4, 
+    255, 255,   0,   1,   0,   0, 
+     70,   0,   0,   0,  60,   0, 
+      0,   0,   2,   0,   0,   0, 
+      4,   0,   0,   0,   4,   0, 
+      0,   0, 255, 255, 255, 255, 
+      0,   0,   0,   0,   1,   0, 
+      0,   0,  13,   0,   0,   0, 
+     84, 101, 120, 116, 117, 114, 
+    101,  85,  73,   0,  77, 105, 
+     99, 114, 111, 115, 111, 102, 
+    116,  32,  40,  82,  41,  32, 
+     72,  76,  83,  76,  32,  83, 
+    104,  97, 100, 101, 114,  32, 
+     67, 111, 109, 112, 105, 108, 
+    101, 114,  32,  54,  46,  51, 
+     46,  57,  54,  48,  48,  46, 
+     49,  54,  51,  56,  52,   0, 
+     73,  83,  71,  78,  80,   0, 
+      0,   0,   2,   0,   0,   0, 
+      8,   0,   0,   0,  56,   0, 
+      0,   0,   0,   0,   0,   0, 
+      1,   0,   0,   0,   3,   0, 
+      0,   0,   0,   0,   0,   0, 
+     15,   0,   0,   0,  68,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   3,   0, 
+      0,   0,   1,   0,   0,   0, 
+      3,   3,   0,   0,  83,  86, 
+     95,  80,  79,  83,  73,  84, 
+     73,  79,  78,   0,  84,  69, 
+     88,  67,  79,  79,  82,  68, 
+      0, 171, 171, 171,  79,  83, 
+     71,  78,  44,   0,   0,   0, 
+      1,   0,   0,   0,   8,   0, 
+      0,   0,  32,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   1,   0,   0,   0, 
+      0,   0,   0,   0,  15,   0, 
+      0,   0,  83,  86,  95,  84, 
+     65,  82,  71,  69,  84,   0, 
+    171, 171,  83,  72,  68,  82, 
+    216,   0,   0,   0,  64,   0, 
+      0,   0,  54,   0,   0,   0, 
+     88,  24,   0,   4,   0, 112, 
+     16,   0,   0,   0,   0,   0, 
+     68,  68,   0,   0,  98,  16, 
+      0,   3,  50,  16,  16,   0, 
+      1,   0,   0,   0, 101,   0, 
+      0,   3, 242,  32,  16,   0, 
+      0,   0,   0,   0, 104,   0, 
+      0,   2,   1,   0,   0,   0, 
+     61,  16,   0,   7, 242,   0, 
+     16,   0,   0,   0,   0,   0, 
+      1,  64,   0,   0,   0,   0, 
+      0,   0,  70, 126,  16,   0, 
+      0,   0,   0,   0,  86,   0, 
+      0,   5,  50,   0,  16,   0, 
+      0,   0,   0,   0,  70,   0, 
+     16,   0,   0,   0,   0,   0, 
+     56,   0,   0,   7,  50,   0, 
+     16,   0,   0,   0,   0,   0, 
+     70,   0,  16,   0,   0,   0, 
+      0,   0,  70,  16,  16,   0, 
+      1,   0,   0,   0,  27,   0, 
+      0,   5,  50,   0,  16,   0, 
+      0,   0,   0,   0,  70,   0, 
+     16,   0,   0,   0,   0,   0, 
+     54,   0,   0,   8, 194,   0, 
+     16,   0,   0,   0,   0,   0, 
+      2,  64,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,  45,   0,   0,   7, 
+    242,  32,  16,   0,   0,   0, 
+      0,   0,  70,  14,  16,   0, 
+      0,   0,   0,   0,  70, 126, 
+     16,   0,   0,   0,   0,   0, 
+     62,   0,   0,   1,  83,  84, 
+     65,  84, 116,   0,   0,   0, 
+      7,   0,   0,   0,   1,   0, 
+      0,   0,   0,   0,   0,   0, 
+      2,   0,   0,   0,   1,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   1,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      1,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   1,   0, 
+      0,   0,   0,   0,   0,   0, 
+      2,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0
+};
--- a/gfx/angle/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrgba3d11ps.h
+++ b/gfx/angle/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrgba3d11ps.h
@@ -1,149 +1,149 @@
-#if 0
-//
-// Generated by Microsoft (R) HLSL Shader Compiler 6.3.9600.16384
-//
-//
-// Resource Bindings:
-//
-// Name                                 Type  Format         Dim Slot Elements
-// ------------------------------ ---------- ------- ----------- ---- --------
-// Sampler                           sampler      NA          NA    0        1
-// TextureF                          texture  float4          3d    0        1
-//
-//
-//
-// Input signature:
-//
-// Name                 Index   Mask Register SysValue  Format   Used
-// -------------------- ----- ------ -------- -------- ------- ------
-// SV_POSITION              0   xyzw        0      POS   float       
-// SV_RENDERTARGETARRAYINDEX     0   x           1  RTINDEX    uint       
-// TEXCOORD                 0   xyz         2     NONE   float   xyz 
-//
-//
-// Output signature:
-//
-// Name                 Index   Mask Register SysValue  Format   Used
-// -------------------- ----- ------ -------- -------- ------- ------
-// SV_TARGET                0   xyzw        0   TARGET   float   xyzw
-//
-ps_4_0
-dcl_sampler s0, mode_default
-dcl_resource_texture3d (float,float,float,float) t0
-dcl_input_ps linear v2.xyz
-dcl_output o0.xyzw
-sample o0.xyzw, v2.xyzx, t0.xyzw, s0
-ret 
-// Approximately 2 instruction slots used
-#endif
-
-const BYTE g_PS_PassthroughRGBA3D[] =
-{
-     68,  88,  66,  67, 246,  41, 
-     15, 240, 168, 172,  91, 145, 
-    236, 221, 187,  89,  12,   0, 
-     93, 149,   1,   0,   0,   0, 
-    128,   2,   0,   0,   5,   0, 
-      0,   0,  52,   0,   0,   0, 
-    220,   0,   0,   0, 100,   1, 
-      0,   0, 152,   1,   0,   0, 
-      4,   2,   0,   0,  82,  68, 
-     69,  70, 160,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   2,   0,   0,   0, 
-     28,   0,   0,   0,   0,   4, 
-    255, 255,   0,   1,   0,   0, 
-    109,   0,   0,   0,  92,   0, 
-      0,   0,   3,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   1,   0, 
-      0,   0,   1,   0,   0,   0, 
-    100,   0,   0,   0,   2,   0, 
-      0,   0,   5,   0,   0,   0, 
-      8,   0,   0,   0, 255, 255, 
-    255, 255,   0,   0,   0,   0, 
-      1,   0,   0,   0,  13,   0, 
-      0,   0,  83,  97, 109, 112, 
-    108, 101, 114,   0,  84, 101, 
-    120, 116, 117, 114, 101,  70, 
-      0,  77, 105,  99, 114, 111, 
-    115, 111, 102, 116,  32,  40, 
-     82,  41,  32,  72,  76,  83, 
-     76,  32,  83, 104,  97, 100, 
-    101, 114,  32,  67, 111, 109, 
-    112, 105, 108, 101, 114,  32, 
-     54,  46,  51,  46,  57,  54, 
-     48,  48,  46,  49,  54,  51, 
-     56,  52,   0, 171,  73,  83, 
-     71,  78, 128,   0,   0,   0, 
-      3,   0,   0,   0,   8,   0, 
-      0,   0,  80,   0,   0,   0, 
-      0,   0,   0,   0,   1,   0, 
-      0,   0,   3,   0,   0,   0, 
-      0,   0,   0,   0,  15,   0, 
-      0,   0,  92,   0,   0,   0, 
-      0,   0,   0,   0,   4,   0, 
-      0,   0,   1,   0,   0,   0, 
-      1,   0,   0,   0,   1,   0, 
-      0,   0, 118,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   3,   0,   0,   0, 
-      2,   0,   0,   0,   7,   7, 
-      0,   0,  83,  86,  95,  80, 
-     79,  83,  73,  84,  73,  79, 
-     78,   0,  83,  86,  95,  82, 
-     69,  78,  68,  69,  82,  84, 
-     65,  82,  71,  69,  84,  65, 
-     82,  82,  65,  89,  73,  78, 
-     68,  69,  88,   0,  84,  69, 
-     88,  67,  79,  79,  82,  68, 
-      0, 171,  79,  83,  71,  78, 
-     44,   0,   0,   0,   1,   0, 
-      0,   0,   8,   0,   0,   0, 
-     32,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      3,   0,   0,   0,   0,   0, 
-      0,   0,  15,   0,   0,   0, 
-     83,  86,  95,  84,  65,  82, 
-     71,  69,  84,   0, 171, 171, 
-     83,  72,  68,  82, 100,   0, 
-      0,   0,  64,   0,   0,   0, 
-     25,   0,   0,   0,  90,   0, 
-      0,   3,   0,  96,  16,   0, 
-      0,   0,   0,   0,  88,  40, 
-      0,   4,   0, 112,  16,   0, 
-      0,   0,   0,   0,  85,  85, 
-      0,   0,  98,  16,   0,   3, 
-    114,  16,  16,   0,   2,   0, 
-      0,   0, 101,   0,   0,   3, 
-    242,  32,  16,   0,   0,   0, 
-      0,   0,  69,   0,   0,   9, 
-    242,  32,  16,   0,   0,   0, 
-      0,   0,  70,  18,  16,   0, 
-      2,   0,   0,   0,  70, 126, 
-     16,   0,   0,   0,   0,   0, 
-      0,  96,  16,   0,   0,   0, 
-      0,   0,  62,   0,   0,   1, 
-     83,  84,  65,  84, 116,   0, 
-      0,   0,   2,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   2,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      1,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   1,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0
-};
+#if 0
+//
+// Generated by Microsoft (R) HLSL Shader Compiler 6.3.9600.16384
+//
+//
+// Resource Bindings:
+//
+// Name                                 Type  Format         Dim Slot Elements
+// ------------------------------ ---------- ------- ----------- ---- --------
+// Sampler                           sampler      NA          NA    0        1
+// TextureF                          texture  float4          3d    0        1
+//
+//
+//
+// Input signature:
+//
+// Name                 Index   Mask Register SysValue  Format   Used
+// -------------------- ----- ------ -------- -------- ------- ------
+// SV_POSITION              0   xyzw        0      POS   float       
+// SV_RENDERTARGETARRAYINDEX     0   x           1  RTINDEX    uint       
+// TEXCOORD                 0   xyz         2     NONE   float   xyz 
+//
+//
+// Output signature:
+//
+// Name                 Index   Mask Register SysValue  Format   Used
+// -------------------- ----- ------ -------- -------- ------- ------
+// SV_TARGET                0   xyzw        0   TARGET   float   xyzw
+//
+ps_4_0
+dcl_sampler s0, mode_default
+dcl_resource_texture3d (float,float,float,float) t0
+dcl_input_ps linear v2.xyz
+dcl_output o0.xyzw
+sample o0.xyzw, v2.xyzx, t0.xyzw, s0
+ret 
+// Approximately 2 instruction slots used
+#endif
+
+const BYTE g_PS_PassthroughRGBA3D[] =
+{
+     68,  88,  66,  67, 246,  41, 
+     15, 240, 168, 172,  91, 145, 
+    236, 221, 187,  89,  12,   0, 
+     93, 149,   1,   0,   0,   0, 
+    128,   2,   0,   0,   5,   0, 
+      0,   0,  52,   0,   0,   0, 
+    220,   0,   0,   0, 100,   1, 
+      0,   0, 152,   1,   0,   0, 
+      4,   2,   0,   0,  82,  68, 
+     69,  70, 160,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   2,   0,   0,   0, 
+     28,   0,   0,   0,   0,   4, 
+    255, 255,   0,   1,   0,   0, 
+    109,   0,   0,   0,  92,   0, 
+      0,   0,   3,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   1,   0, 
+      0,   0,   1,   0,   0,   0, 
+    100,   0,   0,   0,   2,   0, 
+      0,   0,   5,   0,   0,   0, 
+      8,   0,   0,   0, 255, 255, 
+    255, 255,   0,   0,   0,   0, 
+      1,   0,   0,   0,  13,   0, 
+      0,   0,  83,  97, 109, 112, 
+    108, 101, 114,   0,  84, 101, 
+    120, 116, 117, 114, 101,  70, 
+      0,  77, 105,  99, 114, 111, 
+    115, 111, 102, 116,  32,  40, 
+     82,  41,  32,  72,  76,  83, 
+     76,  32,  83, 104,  97, 100, 
+    101, 114,  32,  67, 111, 109, 
+    112, 105, 108, 101, 114,  32, 
+     54,  46,  51,  46,  57,  54, 
+     48,  48,  46,  49,  54,  51, 
+     56,  52,   0, 171,  73,  83, 
+     71,  78, 128,   0,   0,   0, 
+      3,   0,   0,   0,   8,   0, 
+      0,   0,  80,   0,   0,   0, 
+      0,   0,   0,   0,   1,   0, 
+      0,   0,   3,   0,   0,   0, 
+      0,   0,   0,   0,  15,   0, 
+      0,   0,  92,   0,   0,   0, 
+      0,   0,   0,   0,   4,   0, 
+      0,   0,   1,   0,   0,   0, 
+      1,   0,   0,   0,   1,   0, 
+      0,   0, 118,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   3,   0,   0,   0, 
+      2,   0,   0,   0,   7,   7, 
+      0,   0,  83,  86,  95,  80, 
+     79,  83,  73,  84,  73,  79, 
+     78,   0,  83,  86,  95,  82, 
+     69,  78,  68,  69,  82,  84, 
+     65,  82,  71,  69,  84,  65, 
+     82,  82,  65,  89,  73,  78, 
+     68,  69,  88,   0,  84,  69, 
+     88,  67,  79,  79,  82,  68, 
+      0, 171,  79,  83,  71,  78, 
+     44,   0,   0,   0,   1,   0, 
+      0,   0,   8,   0,   0,   0, 
+     32,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      3,   0,   0,   0,   0,   0, 
+      0,   0,  15,   0,   0,   0, 
+     83,  86,  95,  84,  65,  82, 
+     71,  69,  84,   0, 171, 171, 
+     83,  72,  68,  82, 100,   0, 
+      0,   0,  64,   0,   0,   0, 
+     25,   0,   0,   0,  90,   0, 
+      0,   3,   0,  96,  16,   0, 
+      0,   0,   0,   0,  88,  40, 
+      0,   4,   0, 112,  16,   0, 
+      0,   0,   0,   0,  85,  85, 
+      0,   0,  98,  16,   0,   3, 
+    114,  16,  16,   0,   2,   0, 
+      0,   0, 101,   0,   0,   3, 
+    242,  32,  16,   0,   0,   0, 
+      0,   0,  69,   0,   0,   9, 
+    242,  32,  16,   0,   0,   0, 
+      0,   0,  70,  18,  16,   0, 
+      2,   0,   0,   0,  70, 126, 
+     16,   0,   0,   0,   0,   0, 
+      0,  96,  16,   0,   0,   0, 
+      0,   0,  62,   0,   0,   1, 
+     83,  84,  65,  84, 116,   0, 
+      0,   0,   2,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   2,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      1,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   1,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0
+};
--- a/gfx/angle/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrgba3di11ps.h
+++ b/gfx/angle/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrgba3di11ps.h
@@ -1,164 +1,164 @@
-#if 0
-//
-// Generated by Microsoft (R) HLSL Shader Compiler 6.3.9600.16384
-//
-//
-// Resource Bindings:
-//
-// Name                                 Type  Format         Dim Slot Elements
-// ------------------------------ ---------- ------- ----------- ---- --------
-// TextureI                          texture   sint4          3d    0        1
-//
-//
-//
-// Input signature:
-//
-// Name                 Index   Mask Register SysValue  Format   Used
-// -------------------- ----- ------ -------- -------- ------- ------
-// SV_POSITION              0   xyzw        0      POS   float       
-// SV_RENDERTARGETARRAYINDEX     0   x           1  RTINDEX    uint       
-// TEXCOORD                 0   xyz         2     NONE   float   xyz 
-//
-//
-// Output signature:
-//
-// Name                 Index   Mask Register SysValue  Format   Used
-// -------------------- ----- ------ -------- -------- ------- ------
-// SV_TARGET                0   xyzw        0   TARGET     int   xyzw
-//
-ps_4_0
-dcl_resource_texture3d (sint,sint,sint,sint) t0
-dcl_input_ps linear v2.xyz
-dcl_output o0.xyzw
-dcl_temps 1
-resinfo_uint r0.xyzw, l(0), t0.xyzw
-utof r0.xyz, r0.xyzx
-mul r0.xyz, r0.xyzx, v2.xyzx
-ftoi r0.xyz, r0.xyzx
-mov r0.w, l(0)
-ld o0.xyzw, r0.xyzw, t0.xyzw
-ret 
-// Approximately 7 instruction slots used
-#endif
-
-const BYTE g_PS_PassthroughRGBA3DI[] =
-{
-     68,  88,  66,  67, 139, 158, 
-      6, 251, 163, 134,   3, 183, 
-      5, 227, 185, 108,  35,  91, 
-     67, 191,   1,   0,   0,   0, 
-    192,   2,   0,   0,   5,   0, 
-      0,   0,  52,   0,   0,   0, 
-    180,   0,   0,   0,  60,   1, 
-      0,   0, 112,   1,   0,   0, 
-     68,   2,   0,   0,  82,  68, 
-     69,  70, 120,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   1,   0,   0,   0, 
-     28,   0,   0,   0,   0,   4, 
-    255, 255,   0,   1,   0,   0, 
-     69,   0,   0,   0,  60,   0, 
-      0,   0,   2,   0,   0,   0, 
-      3,   0,   0,   0,   8,   0, 
-      0,   0, 255, 255, 255, 255, 
-      0,   0,   0,   0,   1,   0, 
-      0,   0,  13,   0,   0,   0, 
-     84, 101, 120, 116, 117, 114, 
-    101,  73,   0,  77, 105,  99, 
-    114, 111, 115, 111, 102, 116, 
-     32,  40,  82,  41,  32,  72, 
-     76,  83,  76,  32,  83, 104, 
-     97, 100, 101, 114,  32,  67, 
-    111, 109, 112, 105, 108, 101, 
-    114,  32,  54,  46,  51,  46, 
-     57,  54,  48,  48,  46,  49, 
-     54,  51,  56,  52,   0, 171, 
-     73,  83,  71,  78, 128,   0, 
-      0,   0,   3,   0,   0,   0, 
-      8,   0,   0,   0,  80,   0, 
-      0,   0,   0,   0,   0,   0, 
-      1,   0,   0,   0,   3,   0, 
-      0,   0,   0,   0,   0,   0, 
-     15,   0,   0,   0,  92,   0, 
-      0,   0,   0,   0,   0,   0, 
-      4,   0,   0,   0,   1,   0, 
-      0,   0,   1,   0,   0,   0, 
-      1,   0,   0,   0, 118,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   3,   0, 
-      0,   0,   2,   0,   0,   0, 
-      7,   7,   0,   0,  83,  86, 
-     95,  80,  79,  83,  73,  84, 
-     73,  79,  78,   0,  83,  86, 
-     95,  82,  69,  78,  68,  69, 
-     82,  84,  65,  82,  71,  69, 
-     84,  65,  82,  82,  65,  89, 
-     73,  78,  68,  69,  88,   0, 
-     84,  69,  88,  67,  79,  79, 
-     82,  68,   0, 171,  79,  83, 
-     71,  78,  44,   0,   0,   0, 
-      1,   0,   0,   0,   8,   0, 
-      0,   0,  32,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   2,   0,   0,   0, 
-      0,   0,   0,   0,  15,   0, 
-      0,   0,  83,  86,  95,  84, 
-     65,  82,  71,  69,  84,   0, 
-    171, 171,  83,  72,  68,  82, 
-    204,   0,   0,   0,  64,   0, 
-      0,   0,  51,   0,   0,   0, 
-     88,  40,   0,   4,   0, 112, 
-     16,   0,   0,   0,   0,   0, 
-     51,  51,   0,   0,  98,  16, 
-      0,   3, 114,  16,  16,   0, 
-      2,   0,   0,   0, 101,   0, 
-      0,   3, 242,  32,  16,   0, 
-      0,   0,   0,   0, 104,   0, 
-      0,   2,   1,   0,   0,   0, 
-     61,  16,   0,   7, 242,   0, 
-     16,   0,   0,   0,   0,   0, 
-      1,  64,   0,   0,   0,   0, 
-      0,   0,  70, 126,  16,   0, 
-      0,   0,   0,   0,  86,   0, 
-      0,   5, 114,   0,  16,   0, 
-      0,   0,   0,   0,  70,   2, 
-     16,   0,   0,   0,   0,   0, 
-     56,   0,   0,   7, 114,   0, 
-     16,   0,   0,   0,   0,   0, 
-     70,   2,  16,   0,   0,   0, 
-      0,   0,  70,  18,  16,   0, 
-      2,   0,   0,   0,  27,   0, 
-      0,   5, 114,   0,  16,   0, 
-      0,   0,   0,   0,  70,   2, 
-     16,   0,   0,   0,   0,   0, 
-     54,   0,   0,   5, 130,   0, 
-     16,   0,   0,   0,   0,   0, 
-      1,  64,   0,   0,   0,   0, 
-      0,   0,  45,   0,   0,   7, 
-    242,  32,  16,   0,   0,   0, 
-      0,   0,  70,  14,  16,   0, 
-      0,   0,   0,   0,  70, 126, 
-     16,   0,   0,   0,   0,   0, 
-     62,   0,   0,   1,  83,  84, 
-     65,  84, 116,   0,   0,   0, 
-      7,   0,   0,   0,   1,   0, 
-      0,   0,   0,   0,   0,   0, 
-      2,   0,   0,   0,   1,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   1,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      1,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   1,   0, 
-      0,   0,   0,   0,   0,   0, 
-      2,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0
-};
+#if 0
+//
+// Generated by Microsoft (R) HLSL Shader Compiler 6.3.9600.16384
+//
+//
+// Resource Bindings:
+//
+// Name                                 Type  Format         Dim Slot Elements
+// ------------------------------ ---------- ------- ----------- ---- --------
+// TextureI                          texture   sint4          3d    0        1
+//
+//
+//
+// Input signature:
+//
+// Name                 Index   Mask Register SysValue  Format   Used
+// -------------------- ----- ------ -------- -------- ------- ------
+// SV_POSITION              0   xyzw        0      POS   float       
+// SV_RENDERTARGETARRAYINDEX     0   x           1  RTINDEX    uint       
+// TEXCOORD                 0   xyz         2     NONE   float   xyz 
+//
+//
+// Output signature:
+//
+// Name                 Index   Mask Register SysValue  Format   Used
+// -------------------- ----- ------ -------- -------- ------- ------
+// SV_TARGET                0   xyzw        0   TARGET     int   xyzw
+//
+ps_4_0
+dcl_resource_texture3d (sint,sint,sint,sint) t0
+dcl_input_ps linear v2.xyz
+dcl_output o0.xyzw
+dcl_temps 1
+resinfo_uint r0.xyzw, l(0), t0.xyzw
+utof r0.xyz, r0.xyzx
+mul r0.xyz, r0.xyzx, v2.xyzx
+ftoi r0.xyz, r0.xyzx
+mov r0.w, l(0)
+ld o0.xyzw, r0.xyzw, t0.xyzw
+ret 
+// Approximately 7 instruction slots used
+#endif
+
+const BYTE g_PS_PassthroughRGBA3DI[] =
+{
+     68,  88,  66,  67, 139, 158, 
+      6, 251, 163, 134,   3, 183, 
+      5, 227, 185, 108,  35,  91, 
+     67, 191,   1,   0,   0,   0, 
+    192,   2,   0,   0,   5,   0, 
+      0,   0,  52,   0,   0,   0, 
+    180,   0,   0,   0,  60,   1, 
+      0,   0, 112,   1,   0,   0, 
+     68,   2,   0,   0,  82,  68, 
+     69,  70, 120,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   1,   0,   0,   0, 
+     28,   0,   0,   0,   0,   4, 
+    255, 255,   0,   1,   0,   0, 
+     69,   0,   0,   0,  60,   0, 
+      0,   0,   2,   0,   0,   0, 
+      3,   0,   0,   0,   8,   0, 
+      0,   0, 255, 255, 255, 255, 
+      0,   0,   0,   0,   1,   0, 
+      0,   0,  13,   0,   0,   0, 
+     84, 101, 120, 116, 117, 114, 
+    101,  73,   0,  77, 105,  99, 
+    114, 111, 115, 111, 102, 116, 
+     32,  40,  82,  41,  32,  72, 
+     76,  83,  76,  32,  83, 104, 
+     97, 100, 101, 114,  32,  67, 
+    111, 109, 112, 105, 108, 101, 
+    114,  32,  54,  46,  51,  46, 
+     57,  54,  48,  48,  46,  49, 
+     54,  51,  56,  52,   0, 171, 
+     73,  83,  71,  78, 128,   0, 
+      0,   0,   3,   0,   0,   0, 
+      8,   0,   0,   0,  80,   0, 
+      0,   0,   0,   0,   0,   0, 
+      1,   0,   0,   0,   3,   0, 
+      0,   0,   0,   0,   0,   0, 
+     15,   0,   0,   0,  92,   0, 
+      0,   0,   0,   0,   0,   0, 
+      4,   0,   0,   0,   1,   0, 
+      0,   0,   1,   0,   0,   0, 
+      1,   0,   0,   0, 118,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   3,   0, 
+      0,   0,   2,   0,   0,   0, 
+      7,   7,   0,   0,  83,  86, 
+     95,  80,  79,  83,  73,  84, 
+     73,  79,  78,   0,  83,  86, 
+     95,  82,  69,  78,  68,  69, 
+     82,  84,  65,  82,  71,  69, 
+     84,  65,  82,  82,  65,  89, 
+     73,  78,  68,  69,  88,   0, 
+     84,  69,  88,  67,  79,  79, 
+     82,  68,   0, 171,  79,  83, 
+     71,  78,  44,   0,   0,   0, 
+      1,   0,   0,   0,   8,   0, 
+      0,   0,  32,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   2,   0,   0,   0, 
+      0,   0,   0,   0,  15,   0, 
+      0,   0,  83,  86,  95,  84, 
+     65,  82,  71,  69,  84,   0, 
+    171, 171,  83,  72,  68,  82, 
+    204,   0,   0,   0,  64,   0, 
+      0,   0,  51,   0,   0,   0, 
+     88,  40,   0,   4,   0, 112, 
+     16,   0,   0,   0,   0,   0, 
+     51,  51,   0,   0,  98,  16, 
+      0,   3, 114,  16,  16,   0, 
+      2,   0,   0,   0, 101,   0, 
+      0,   3, 242,  32,  16,   0, 
+      0,   0,   0,   0, 104,   0, 
+      0,   2,   1,   0,   0,   0, 
+     61,  16,   0,   7, 242,   0, 
+     16,   0,   0,   0,   0,   0, 
+      1,  64,   0,   0,   0,   0, 
+      0,   0,  70, 126,  16,   0, 
+      0,   0,   0,   0,  86,   0, 
+      0,   5, 114,   0,  16,   0, 
+      0,   0,   0,   0,  70,   2, 
+     16,   0,   0,   0,   0,   0, 
+     56,   0,   0,   7, 114,   0, 
+     16,   0,   0,   0,   0,   0, 
+     70,   2,  16,   0,   0,   0, 
+      0,   0,  70,  18,  16,   0, 
+      2,   0,   0,   0,  27,   0, 
+      0,   5, 114,   0,  16,   0, 
+      0,   0,   0,   0,  70,   2, 
+     16,   0,   0,   0,   0,   0, 
+     54,   0,   0,   5, 130,   0, 
+     16,   0,   0,   0,   0,   0, 
+      1,  64,   0,   0,   0,   0, 
+      0,   0,  45,   0,   0,   7, 
+    242,  32,  16,   0,   0,   0, 
+      0,   0,  70,  14,  16,   0, 
+      0,   0,   0,   0,  70, 126, 
+     16,   0,   0,   0,   0,   0, 
+     62,   0,   0,   1,  83,  84, 
+     65,  84, 116,   0,   0,   0, 
+      7,   0,   0,   0,   1,   0, 
+      0,   0,   0,   0,   0,   0, 
+      2,   0,   0,   0,   1,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   1,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      1,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   1,   0, 
+      0,   0,   0,   0,   0,   0, 
+      2,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0
+};
--- a/gfx/angle/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrgba3dui11ps.h
+++ b/gfx/angle/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrgba3dui11ps.h
@@ -1,164 +1,164 @@
-#if 0
-//
-// Generated by Microsoft (R) HLSL Shader Compiler 6.3.9600.16384
-//
-//
-// Resource Bindings:
-//
-// Name                                 Type  Format         Dim Slot Elements
-// ------------------------------ ---------- ------- ----------- ---- --------
-// TextureUI                         texture   uint4          3d    0        1
-//
-//
-//
-// Input signature:
-//
-// Name                 Index   Mask Register SysValue  Format   Used
-// -------------------- ----- ------ -------- -------- ------- ------
-// SV_POSITION              0   xyzw        0      POS   float       
-// SV_RENDERTARGETARRAYINDEX     0   x           1  RTINDEX    uint       
-// TEXCOORD                 0   xyz         2     NONE   float   xyz 
-//
-//
-// Output signature:
-//
-// Name                 Index   Mask Register SysValue  Format   Used
-// -------------------- ----- ------ -------- -------- ------- ------
-// SV_TARGET                0   xyzw        0   TARGET    uint   xyzw
-//
-ps_4_0
-dcl_resource_texture3d (uint,uint,uint,uint) t0
-dcl_input_ps linear v2.xyz
-dcl_output o0.xyzw
-dcl_temps 1
-resinfo_uint r0.xyzw, l(0), t0.xyzw
-utof r0.xyz, r0.xyzx
-mul r0.xyz, r0.xyzx, v2.xyzx
-ftoi r0.xyz, r0.xyzx
-mov r0.w, l(0)
-ld o0.xyzw, r0.xyzw, t0.xyzw
-ret 
-// Approximately 7 instruction slots used
-#endif
-
-const BYTE g_PS_PassthroughRGBA3DUI[] =
-{
-     68,  88,  66,  67,  16, 111, 
-     56, 218, 148, 233, 100, 164, 
-      0, 199,  73, 155, 213, 171, 
-     78,  18,   1,   0,   0,   0, 
-    192,   2,   0,   0,   5,   0, 
-      0,   0,  52,   0,   0,   0, 
-    180,   0,   0,   0,  60,   1, 
-      0,   0, 112,   1,   0,   0, 
-     68,   2,   0,   0,  82,  68, 
-     69,  70, 120,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   1,   0,   0,   0, 
-     28,   0,   0,   0,   0,   4, 
-    255, 255,   0,   1,   0,   0, 
-     70,   0,   0,   0,  60,   0, 
-      0,   0,   2,   0,   0,   0, 
-      4,   0,   0,   0,   8,   0, 
-      0,   0, 255, 255, 255, 255, 
-      0,   0,   0,   0,   1,   0, 
-      0,   0,  13,   0,   0,   0, 
-     84, 101, 120, 116, 117, 114, 
-    101,  85,  73,   0,  77, 105, 
-     99, 114, 111, 115, 111, 102, 
-    116,  32,  40,  82,  41,  32, 
-     72,  76,  83,  76,  32,  83, 
-    104,  97, 100, 101, 114,  32, 
-     67, 111, 109, 112, 105, 108, 
-    101, 114,  32,  54,  46,  51, 
-     46,  57,  54,  48,  48,  46, 
-     49,  54,  51,  56,  52,   0, 
-     73,  83,  71,  78, 128,   0, 
-      0,   0,   3,   0,   0,   0, 
-      8,   0,   0,   0,  80,   0, 
-      0,   0,   0,   0,   0,   0, 
-      1,   0,   0,   0,   3,   0, 
-      0,   0,   0,   0,   0,   0, 
-     15,   0,   0,   0,  92,   0, 
-      0,   0,   0,   0,   0,   0, 
-      4,   0,   0,   0,   1,   0, 
-      0,   0,   1,   0,   0,   0, 
-      1,   0,   0,   0, 118,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   3,   0, 
-      0,   0,   2,   0,   0,   0, 
-      7,   7,   0,   0,  83,  86, 
-     95,  80,  79,  83,  73,  84, 
-     73,  79,  78,   0,  83,  86, 
-     95,  82,  69,  78,  68,  69, 
-     82,  84,  65,  82,  71,  69, 
-     84,  65,  82,  82,  65,  89, 
-     73,  78,  68,  69,  88,   0, 
-     84,  69,  88,  67,  79,  79, 
-     82,  68,   0, 171,  79,  83, 
-     71,  78,  44,   0,   0,   0, 
-      1,   0,   0,   0,   8,   0, 
-      0,   0,  32,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   1,   0,   0,   0, 
-      0,   0,   0,   0,  15,   0, 
-      0,   0,  83,  86,  95,  84, 
-     65,  82,  71,  69,  84,   0, 
-    171, 171,  83,  72,  68,  82, 
-    204,   0,   0,   0,  64,   0, 
-      0,   0,  51,   0,   0,   0, 
-     88,  40,   0,   4,   0, 112, 
-     16,   0,   0,   0,   0,   0, 
-     68,  68,   0,   0,  98,  16, 
-      0,   3, 114,  16,  16,   0, 
-      2,   0,   0,   0, 101,   0, 
-      0,   3, 242,  32,  16,   0, 
-      0,   0,   0,   0, 104,   0, 
-      0,   2,   1,   0,   0,   0, 
-     61,  16,   0,   7, 242,   0, 
-     16,   0,   0,   0,   0,   0, 
-      1,  64,   0,   0,   0,   0, 
-      0,   0,  70, 126,  16,   0, 
-      0,   0,   0,   0,  86,   0, 
-      0,   5, 114,   0,  16,   0, 
-      0,   0,   0,   0,  70,   2, 
-     16,   0,   0,   0,   0,   0, 
-     56,   0,   0,   7, 114,   0, 
-     16,   0,   0,   0,   0,   0, 
-     70,   2,  16,   0,   0,   0, 
-      0,   0,  70,  18,  16,   0, 
-      2,   0,   0,   0,  27,   0, 
-      0,   5, 114,   0,  16,   0, 
-      0,   0,   0,   0,  70,   2, 
-     16,   0,   0,   0,   0,   0, 
-     54,   0,   0,   5, 130,   0, 
-     16,   0,   0,   0,   0,   0, 
-      1,  64,   0,   0,   0,   0, 
-      0,   0,  45,   0,   0,   7, 
-    242,  32,  16,   0,   0,   0, 
-      0,   0,  70,  14,  16,   0, 
-      0,   0,   0,   0,  70, 126, 
-     16,   0,   0,   0,   0,   0, 
-     62,   0,   0,   1,  83,  84, 
-     65,  84, 116,   0,   0,   0, 
-      7,   0,   0,   0,   1,   0, 
-      0,   0,   0,   0,   0,   0, 
-      2,   0,   0,   0,   1,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   1,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      1,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   1,   0, 
-      0,   0,   0,   0,   0,   0, 
-      2,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0
-};
+#if 0
+//
+// Generated by Microsoft (R) HLSL Shader Compiler 6.3.9600.16384
+//
+//
+// Resource Bindings:
+//
+// Name                                 Type  Format         Dim Slot Elements
+// ------------------------------ ---------- ------- ----------- ---- --------
+// TextureUI                         texture   uint4          3d    0        1
+//
+//
+//
+// Input signature:
+//
+// Name                 Index   Mask Register SysValue  Format   Used
+// -------------------- ----- ------ -------- -------- ------- ------
+// SV_POSITION              0   xyzw        0      POS   float       
+// SV_RENDERTARGETARRAYINDEX     0   x           1  RTINDEX    uint       
+// TEXCOORD                 0   xyz         2     NONE   float   xyz 
+//
+//
+// Output signature:
+//
+// Name                 Index   Mask Register SysValue  Format   Used
+// -------------------- ----- ------ -------- -------- ------- ------
+// SV_TARGET                0   xyzw        0   TARGET    uint   xyzw
+//
+ps_4_0
+dcl_resource_texture3d (uint,uint,uint,uint) t0
+dcl_input_ps linear v2.xyz
+dcl_output o0.xyzw
+dcl_temps 1
+resinfo_uint r0.xyzw, l(0), t0.xyzw
+utof r0.xyz, r0.xyzx
+mul r0.xyz, r0.xyzx, v2.xyzx
+ftoi r0.xyz, r0.xyzx
+mov r0.w, l(0)
+ld o0.xyzw, r0.xyzw, t0.xyzw
+ret 
+// Approximately 7 instruction slots used
+#endif
+
+const BYTE g_PS_PassthroughRGBA3DUI[] =
+{
+     68,  88,  66,  67,  16, 111, 
+     56, 218, 148, 233, 100, 164, 
+      0, 199,  73, 155, 213, 171, 
+     78,  18,   1,   0,   0,   0, 
+    192,   2,   0,   0,   5,   0, 
+      0,   0,  52,   0,   0,   0, 
+    180,   0,   0,   0,  60,   1, 
+      0,   0, 112,   1,   0,   0, 
+     68,   2,   0,   0,  82,  68, 
+     69,  70, 120,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   1,   0,   0,   0, 
+     28,   0,   0,   0,   0,   4, 
+    255, 255,   0,   1,   0,   0, 
+     70,   0,   0,   0,  60,   0, 
+      0,   0,   2,   0,   0,   0, 
+      4,   0,   0,   0,   8,   0, 
+      0,   0, 255, 255, 255, 255, 
+      0,   0,   0,   0,   1,   0, 
+      0,   0,  13,   0,   0,   0, 
+     84, 101, 120, 116, 117, 114, 
+    101,  85,  73,   0,  77, 105, 
+     99, 114, 111, 115, 111, 102, 
+    116,  32,  40,  82,  41,  32, 
+     72,  76,  83,  76,  32,  83, 
+    104,  97, 100, 101, 114,  32, 
+     67, 111, 109, 112, 105, 108, 
+    101, 114,  32,  54,  46,  51, 
+     46,  57,  54,  48,  48,  46, 
+     49,  54,  51,  56,  52,   0, 
+     73,  83,  71,  78, 128,   0, 
+      0,   0,   3,   0,   0,   0, 
+      8,   0,   0,   0,  80,   0, 
+      0,   0,   0,   0,   0,   0, 
+      1,   0,   0,   0,   3,   0, 
+      0,   0,   0,   0,   0,   0, 
+     15,   0,   0,   0,  92,   0, 
+      0,   0,   0,   0,   0,   0, 
+      4,   0,   0,   0,   1,   0, 
+      0,   0,   1,   0,   0,   0, 
+      1,   0,   0,   0, 118,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   3,   0, 
+      0,   0,   2,   0,   0,   0, 
+      7,   7,   0,   0,  83,  86, 
+     95,  80,  79,  83,  73,  84, 
+     73,  79,  78,   0,  83,  86, 
+     95,  82,  69,  78,  68,  69, 
+     82,  84,  65,  82,  71,  69, 
+     84,  65,  82,  82,  65,  89, 
+     73,  78,  68,  69,  88,   0, 
+     84,  69,  88,  67,  79,  79, 
+     82,  68,   0, 171,  79,  83, 
+     71,  78,  44,   0,   0,   0, 
+      1,   0,   0,   0,   8,   0, 
+      0,   0,  32,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   1,   0,   0,   0, 
+      0,   0,   0,   0,  15,   0, 
+      0,   0,  83,  86,  95,  84, 
+     65,  82,  71,  69,  84,   0, 
+    171, 171,  83,  72,  68,  82, 
+    204,   0,   0,   0,  64,   0, 
+      0,   0,  51,   0,   0,   0, 
+     88,  40,   0,   4,   0, 112, 
+     16,   0,   0,   0,   0,   0, 
+     68,  68,   0,   0,  98,  16, 
+      0,   3, 114,  16,  16,   0, 
+      2,   0,   0,   0, 101,   0, 
+      0,   3, 242,  32,  16,   0, 
+      0,   0,   0,   0, 104,   0, 
+      0,   2,   1,   0,   0,   0, 
+     61,  16,   0,   7, 242,   0, 
+     16,   0,   0,   0,   0,   0, 
+      1,  64,   0,   0,   0,   0, 
+      0,   0,  70, 126,  16,   0, 
+      0,   0,   0,   0,  86,   0, 
+      0,   5, 114,   0,  16,   0, 
+      0,   0,   0,   0,  70,   2, 
+     16,   0,   0,   0,   0,   0, 
+     56,   0,   0,   7, 114,   0, 
+     16,   0,   0,   0,   0,   0, 
+     70,   2,  16,   0,   0,   0, 
+      0,   0,  70,  18,  16,   0, 
+      2,   0,   0,   0,  27,   0, 
+      0,   5, 114,   0,  16,   0, 
+      0,   0,   0,   0,  70,   2, 
+     16,   0,   0,   0,   0,   0, 
+     54,   0,   0,   5, 130,   0, 
+     16,   0,   0,   0,   0,   0, 
+      1,  64,   0,   0,   0,   0, 
+      0,   0,  45,   0,   0,   7, 
+    242,  32,  16,   0,   0,   0, 
+      0,   0,  70,  14,  16,   0, 
+      0,   0,   0,   0,  70, 126, 
+     16,   0,   0,   0,   0,   0, 
+     62,   0,   0,   1,  83,  84, 
+     65,  84, 116,   0,   0,   0, 
+      7,   0,   0,   0,   1,   0, 
+      0,   0,   0,   0,   0,   0, 
+      2,   0,   0,   0,   1,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   1,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      1,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   1,   0, 
+      0,   0,   0,   0,   0,   0, 
+      2,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0
+};
--- a/gfx/angle/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/resolvedepth11_ps.h
+++ b/gfx/angle/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/resolvedepth11_ps.h
@@ -1,82 +1,82 @@
-#if 0
-//
-// Generated by Microsoft (R) HLSL Shader Compiler 6.3.9600.16384
-//
-//
-// Resource Bindings:
-//
-// Name                                 Type  Format         Dim Slot Elements
-// ------------------------------ ---------- ------- ----------- ---- --------
-// Depth                             texture   float        2dMS    0        1
-//
-//
-//
-// Input signature:
-//
-// Name                 Index   Mask Register SysValue  Format   Used
-// -------------------- ----- ------ -------- -------- ------- ------
-// SV_Position              0   xyzw        0      POS   float       
-// TEXCOORD                 0   xy          1     NONE   float   xy  
-//
-//
-// Output signature:
-//
-// Name                 Index   Mask Register SysValue  Format   Used
-// -------------------- ----- ------ -------- -------- ------- ------
-// SV_Depth                 0    N/A   oDepth    DEPTH   float    YES
-//
-ps_4_1
-dcl_globalFlags refactoringAllowed
-dcl_resource_texture2dms(0) (float,float,float,float) t0
-dcl_input_ps linear v1.xy
-dcl_output oDepth
-dcl_temps 1
-resinfo_uint r0.xy, l(0), t0.xyzw
-utof r0.xy, r0.xyxx
-mul r0.xy, r0.xyxx, v1.xyxx
-ftou r0.xy, r0.xyxx
-mov r0.zw, l(0,0,0,0)
-ldms r0.x, r0.xyzw, t0.xyzw, l(0)
-mov oDepth, r0.x
-ret 
-// Approximately 8 instruction slots used
-#endif
-
-const BYTE g_PS_ResolveDepth[] = {
-    68,  88,  66,  67,  106, 43,  8,   187, 21,  3,   136, 11,  227, 249, 190, 191, 97,  127, 18,
-    212, 1,   0,   0,   0,   176, 2,   0,   0,   5,   0,   0,   0,   52,  0,   0,   0,   176, 0,
-    0,   0,   8,   1,   0,   0,   60,  1,   0,   0,   52,  2,   0,   0,   82,  68,  69,  70,  116,
-    0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   1,   0,   0,   0,   28,  0,   0,   0,
-    1,   4,   255, 255, 0,   1,   0,   0,   66,  0,   0,   0,   60,  0,   0,   0,   2,   0,   0,
-    0,   5,   0,   0,   0,   6,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   1,   0,
-    0,   0,   1,   0,   0,   0,   68,  101, 112, 116, 104, 0,   77,  105, 99,  114, 111, 115, 111,
-    102, 116, 32,  40,  82,  41,  32,  72,  76,  83,  76,  32,  83,  104, 97,  100, 101, 114, 32,
-    67,  111, 109, 112, 105, 108, 101, 114, 32,  54,  46,  51,  46,  57,  54,  48,  48,  46,  49,
-    54,  51,  56,  52,  0,   73,  83,  71,  78,  80,  0,   0,   0,   2,   0,   0,   0,   8,   0,
-    0,   0,   56,  0,   0,   0,   0,   0,   0,   0,   1,   0,   0,   0,   3,   0,   0,   0,   0,
-    0,   0,   0,   15,  0,   0,   0,   68,  0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
-    3,   0,   0,   0,   1,   0,   0,   0,   3,   3,   0,   0,   83,  86,  95,  80,  111, 115, 105,
-    116, 105, 111, 110, 0,   84,  69,  88,  67,  79,  79,  82,  68,  0,   171, 171, 171, 79,  83,
-    71,  78,  44,  0,   0,   0,   1,   0,   0,   0,   8,   0,   0,   0,   32,  0,   0,   0,   0,
-    0,   0,   0,   0,   0,   0,   0,   3,   0,   0,   0,   255, 255, 255, 255, 1,   14,  0,   0,
-    83,  86,  95,  68,  101, 112, 116, 104, 0,   171, 171, 171, 83,  72,  68,  82,  240, 0,   0,
-    0,   65,  0,   0,   0,   60,  0,   0,   0,   106, 8,   0,   1,   88,  32,  0,   4,   0,   112,
-    16,  0,   0,   0,   0,   0,   85,  85,  0,   0,   98,  16,  0,   3,   50,  16,  16,  0,   1,
-    0,   0,   0,   101, 0,   0,   2,   1,   192, 0,   0,   104, 0,   0,   2,   1,   0,   0,   0,
-    61,  16,  0,   7,   50,  0,   16,  0,   0,   0,   0,   0,   1,   64,  0,   0,   0,   0,   0,
-    0,   70,  126, 16,  0,   0,   0,   0,   0,   86,  0,   0,   5,   50,  0,   16,  0,   0,   0,
-    0,   0,   70,  0,   16,  0,   0,   0,   0,   0,   56,  0,   0,   7,   50,  0,   16,  0,   0,
-    0,   0,   0,   70,  0,   16,  0,   0,   0,   0,   0,   70,  16,  16,  0,   1,   0,   0,   0,
-    28,  0,   0,   5,   50,  0,   16,  0,   0,   0,   0,   0,   70,  0,   16,  0,   0,   0,   0,
-    0,   54,  0,   0,   8,   194, 0,   16,  0,   0,   0,   0,   0,   2,   64,  0,   0,   0,   0,
-    0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   46,  0,   0,   9,   18,
-    0,   16,  0,   0,   0,   0,   0,   70,  14,  16,  0,   0,   0,   0,   0,   70,  126, 16,  0,
-    0,   0,   0,   0,   1,   64,  0,   0,   0,   0,   0,   0,   54,  0,   0,   4,   1,   192, 0,
-    0,   10,  0,   16,  0,   0,   0,   0,   0,   62,  0,   0,   1,   83,  84,  65,  84,  116, 0,
-    0,   0,   8,   0,   0,   0,   1,   0,   0,   0,   0,   0,   0,   0,   2,   0,   0,   0,   1,
-    0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   1,   0,   0,   0,   0,   0,   0,   0,
-    0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
-    0,   0,   0,   0,   0,   1,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
-    0,   0,   2,   0,   0,   0,   0,   0,   0,   0,   2,   0,   0,   0,   0,   0,   0,   0,   0,
-    0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
-    0,   0,   0,   0};
+#if 0
+//
+// Generated by Microsoft (R) HLSL Shader Compiler 6.3.9600.16384
+//
+//
+// Resource Bindings:
+//
+// Name                                 Type  Format         Dim Slot Elements
+// ------------------------------ ---------- ------- ----------- ---- --------
+// Depth                             texture   float        2dMS    0        1
+//
+//
+//
+// Input signature:
+//
+// Name                 Index   Mask Register SysValue  Format   Used
+// -------------------- ----- ------ -------- -------- ------- ------
+// SV_Position              0   xyzw        0      POS   float       
+// TEXCOORD                 0   xy          1     NONE   float   xy  
+//
+//
+// Output signature:
+//
+// Name                 Index   Mask Register SysValue  Format   Used
+// -------------------- ----- ------ -------- -------- ------- ------
+// SV_Depth                 0    N/A   oDepth    DEPTH   float    YES
+//
+ps_4_1
+dcl_globalFlags refactoringAllowed
+dcl_resource_texture2dms(0) (float,float,float,float) t0
+dcl_input_ps linear v1.xy
+dcl_output oDepth
+dcl_temps 1
+resinfo_uint r0.xy, l(0), t0.xyzw
+utof r0.xy, r0.xyxx
+mul r0.xy, r0.xyxx, v1.xyxx
+ftou r0.xy, r0.xyxx
+mov r0.zw, l(0,0,0,0)
+ldms r0.x, r0.xyzw, t0.xyzw, l(0)
+mov oDepth, r0.x
+ret 
+// Approximately 8 instruction slots used
+#endif
+
+const BYTE g_PS_ResolveDepth[] = {
+    68,  88,  66,  67,  106, 43,  8,   187, 21,  3,   136, 11,  227, 249, 190, 191, 97,  127, 18,
+    212, 1,   0,   0,   0,   176, 2,   0,   0,   5,   0,   0,   0,   52,  0,   0,   0,   176, 0,
+    0,   0,   8,   1,   0,   0,   60,  1,   0,   0,   52,  2,   0,   0,   82,  68,  69,  70,  116,
+    0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   1,   0,   0,   0,   28,  0,   0,   0,
+    1,   4,   255, 255, 0,   1,   0,   0,   66,  0,   0,   0,   60,  0,   0,   0,   2,   0,   0,
+    0,   5,   0,   0,   0,   6,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   1,   0,
+    0,   0,   1,   0,   0,   0,   68,  101, 112, 116, 104, 0,   77,  105, 99,  114, 111, 115, 111,
+    102, 116, 32,  40,  82,  41,  32,  72,  76,  83,  76,  32,  83,  104, 97,  100, 101, 114, 32,
+    67,  111, 109, 112, 105, 108, 101, 114, 32,  54,  46,  51,  46,  57,  54,  48,  48,  46,  49,
+    54,  51,  56,  52,  0,   73,  83,  71,  78,  80,  0,   0,   0,   2,   0,   0,   0,   8,   0,
+    0,   0,   56,  0,   0,   0,   0,   0,   0,   0,   1,   0,   0,   0,   3,   0,   0,   0,   0,
+    0,   0,   0,   15,  0,   0,   0,   68,  0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+    3,   0,   0,   0,   1,   0,   0,   0,   3,   3,   0,   0,   83,  86,  95,  80,  111, 115, 105,
+    116, 105, 111, 110, 0,   84,  69,  88,  67,  79,  79,  82,  68,  0,   171, 171, 171, 79,  83,
+    71,  78,  44,  0,   0,   0,   1,   0,   0,   0,   8,   0,   0,   0,   32,  0,   0,   0,   0,
+    0,   0,   0,   0,   0,   0,   0,   3,   0,   0,   0,   255, 255, 255, 255, 1,   14,  0,   0,
+    83,  86,  95,  68,  101, 112, 116, 104, 0,   171, 171, 171, 83,  72,  68,  82,  240, 0,   0,
+    0,   65,  0,   0,   0,   60,  0,   0,   0,   106, 8,   0,   1,   88,  32,  0,   4,   0,   112,
+    16,  0,   0,   0,   0,   0,   85,  85,  0,   0,   98,  16,  0,   3,   50,  16,  16,  0,   1,
+    0,   0,   0,   101, 0,   0,   2,   1,   192, 0,   0,   104, 0,   0,   2,   1,   0,   0,   0,
+    61,  16,  0,   7,   50,  0,   16,  0,   0,   0,   0,   0,   1,   64,  0,   0,   0,   0,   0,
+    0,   70,  126, 16,  0,   0,   0,   0,   0,   86,  0,   0,   5,   50,  0,   16,  0,   0,   0,
+    0,   0,   70,  0,   16,  0,   0,   0,   0,   0,   56,  0,   0,   7,   50,  0,   16,  0,   0,
+    0,   0,   0,   70,  0,   16,  0,   0,   0,   0,   0,   70,  16,  16,  0,   1,   0,   0,   0,
+    28,  0,   0,   5,   50,  0,   16,  0,   0,   0,   0,   0,   70,  0,   16,  0,   0,   0,   0,
+    0,   54,  0,   0,   8,   194, 0,   16,  0,   0,   0,   0,   0,   2,   64,  0,   0,   0,   0,
+    0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   46,  0,   0,   9,   18,
+    0,   16,  0,   0,   0,   0,   0,   70,  14,  16,  0,   0,   0,   0,   0,   70,  126, 16,  0,
+    0,   0,   0,   0,   1,   64,  0,   0,   0,   0,   0,   0,   54,  0,   0,   4,   1,   192, 0,
+    0,   10,  0,   16,  0,   0,   0,   0,   0,   62,  0,   0,   1,   83,  84,  65,  84,  116, 0,
+    0,   0,   8,   0,   0,   0,   1,   0,   0,   0,   0,   0,   0,   0,   2,   0,   0,   0,   1,
+    0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   1,   0,   0,   0,   0,   0,   0,   0,
+    0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+    0,   0,   0,   0,   0,   1,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+    0,   0,   2,   0,   0,   0,   0,   0,   0,   0,   2,   0,   0,   0,   0,   0,   0,   0,   0,
+    0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+    0,   0,   0,   0};
--- a/gfx/angle/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/resolvedepthstencil11_ps.h
+++ b/gfx/angle/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/resolvedepthstencil11_ps.h
@@ -1,92 +1,92 @@
-#if 0
-//
-// Generated by Microsoft (R) HLSL Shader Compiler 6.3.9600.16384
-//
-//
-// Resource Bindings:
-//
-// Name                                 Type  Format         Dim Slot Elements
-// ------------------------------ ---------- ------- ----------- ---- --------
-// Depth                             texture   float        2dMS    0        1
-// Stencil                           texture   uint2        2dMS    1        1
-//
-//
-//
-// Input signature:
-//
-// Name                 Index   Mask Register SysValue  Format   Used
-// -------------------- ----- ------ -------- -------- ------- ------
-// SV_Position              0   xyzw        0      POS   float       
-// TEXCOORD                 0   xy          1     NONE   float   xy  
-//
-//
-// Output signature:
-//
-// Name                 Index   Mask Register SysValue  Format   Used
-// -------------------- ----- ------ -------- -------- ------- ------
-// SV_Target                0   xy          0   TARGET   float   xy  
-//
-ps_4_1
-dcl_globalFlags refactoringAllowed
-dcl_resource_texture2dms(0) (float,float,float,float) t0
-dcl_resource_texture2dms(0) (uint,uint,uint,uint) t1
-dcl_input_ps linear v1.xy
-dcl_output o0.xy
-dcl_temps 1
-resinfo_uint r0.xy, l(0), t0.xyzw
-utof r0.xy, r0.xyxx
-mul r0.xy, r0.xyxx, v1.xyxx
-ftou r0.xy, r0.xyxx
-mov r0.zw, l(0,0,0,0)
-ldms r0.z, r0.xyzw, t1.xzyw, l(0)
-ldms r0.x, r0.xyww, t0.xyzw, l(0)
-mov o0.x, r0.x
-utof o0.y, r0.z
-ret 
-// Approximately 10 instruction slots used
-#endif
-
-const BYTE g_PS_ResolveDepthStencil[] = {
-    68,  88,  66,  67,  229, 191, 254, 12,  10,  19,  181, 162, 222, 203, 244, 146, 104, 226, 195,
-    177, 1,   0,   0,   0,   40,  3,   0,   0,   5,   0,   0,   0,   52,  0,   0,   0,   216, 0,
-    0,   0,   48,  1,   0,   0,   100, 1,   0,   0,   172, 2,   0,   0,   82,  68,  69,  70,  156,
-    0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   2,   0,   0,   0,   28,  0,   0,   0,
-    1,   4,   255, 255, 0,   1,   0,   0,   106, 0,   0,   0,   92,  0,   0,   0,   2,   0,   0,
-    0,   5,   0,   0,   0,   6,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   1,   0,
-    0,   0,   1,   0,   0,   0,   98,  0,   0,   0,   2,   0,   0,   0,   4,   0,   0,   0,   6,
-    0,   0,   0,   0,   0,   0,   0,   1,   0,   0,   0,   1,   0,   0,   0,   5,   0,   0,   0,
-    68,  101, 112, 116, 104, 0,   83,  116, 101, 110, 99,  105, 108, 0,   77,  105, 99,  114, 111,
-    115, 111, 102, 116, 32,  40,  82,  41,  32,  72,  76,  83,  76,  32,  83,  104, 97,  100, 101,
-    114, 32,  67,  111, 109, 112, 105, 108, 101, 114, 32,  54,  46,  51,  46,  57,  54,  48,  48,
-    46,  49,  54,  51,  56,  52,  0,   73,  83,  71,  78,  80,  0,   0,   0,   2,   0,   0,   0,
-    8,   0,   0,   0,   56,  0,   0,   0,   0,   0,   0,   0,   1,   0,   0,   0,   3,   0,   0,
-    0,   0,   0,   0,   0,   15,  0,   0,   0,   68,  0,   0,   0,   0,   0,   0,   0,   0,   0,
-    0,   0,   3,   0,   0,   0,   1,   0,   0,   0,   3,   3,   0,   0,   83,  86,  95,  80,  111,
-    115, 105, 116, 105, 111, 110, 0,   84,  69,  88,  67,  79,  79,  82,  68,  0,   171, 171, 171,
-    79,  83,  71,  78,  44,  0,   0,   0,   1,   0,   0,   0,   8,   0,   0,   0,   32,  0,   0,
-    0,   0,   0,   0,   0,   0,   0,   0,   0,   3,   0,   0,   0,   0,   0,   0,   0,   3,   12,
-    0,   0,   83,  86,  95,  84,  97,  114, 103, 101, 116, 0,   171, 171, 83,  72,  68,  82,  64,
-    1,   0,   0,   65,  0,   0,   0,   80,  0,   0,   0,   106, 8,   0,   1,   88,  32,  0,   4,
-    0,   112, 16,  0,   0,   0,   0,   0,   85,  85,  0,   0,   88,  32,  0,   4,   0,   112, 16,
-    0,   1,   0,   0,   0,   68,  68,  0,   0,   98,  16,  0,   3,   50,  16,  16,  0,   1,   0,
-    0,   0,   101, 0,   0,   3,   50,  32,  16,  0,   0,   0,   0,   0,   104, 0,   0,   2,   1,
-    0,   0,   0,   61,  16,  0,   7,   50,  0,   16,  0,   0,   0,   0,   0,   1,   64,  0,   0,
-    0,   0,   0,   0,   70,  126, 16,  0,   0,   0,   0,   0,   86,  0,   0,   5,   50,  0,   16,
-    0,   0,   0,   0,   0,   70,  0,   16,  0,   0,   0,   0,   0,   56,  0,   0,   7,   50,  0,
-    16,  0,   0,   0,   0,   0,   70,  0,   16,  0,   0,   0,   0,   0,   70,  16,  16,  0,   1,
-    0,   0,   0,   28,  0,   0,   5,   50,  0,   16,  0,   0,   0,   0,   0,   70,  0,   16,  0,
-    0,   0,   0,   0,   54,  0,   0,   8,   194, 0,   16,  0,   0,   0,   0,   0,   2,   64,  0,
-    0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   46,  0,
-    0,   9,   66,  0,   16,  0,   0,   0,   0,   0,   70,  14,  16,  0,   0,   0,   0,   0,   134,
-    125, 16,  0,   1,   0,   0,   0,   1,   64,  0,   0,   0,   0,   0,   0,   46,  0,   0,   9,
-    18,  0,   16,  0,   0,   0,   0,   0,   70,  15,  16,  0,   0,   0,   0,   0,   70,  126, 16,
-    0,   0,   0,   0,   0,   1,   64,  0,   0,   0,   0,   0,   0,   54,  0,   0,   5,   18,  32,
-    16,  0,   0,   0,   0,   0,   10,  0,   16,  0,   0,   0,   0,   0,   86,  0,   0,   5,   34,
-    32,  16,  0,   0,   0,   0,   0,   42,  0,   16,  0,   0,   0,   0,   0,   62,  0,   0,   1,
-    83,  84,  65,  84,  116, 0,   0,   0,   10,  0,   0,   0,   1,   0,   0,   0,   0,   0,   0,
-    0,   2,   0,   0,   0,   1,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   1,   0,
-    0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
-    0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   2,   0,   0,   0,   0,   0,   0,   0,
-    0,   0,   0,   0,   0,   0,   0,   0,   2,   0,   0,   0,   0,   0,   0,   0,   3,   0,   0,
-    0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
-    0,   0,   0,   0,   0,   0,   0,   0,   0,   0};
+#if 0
+//
+// Generated by Microsoft (R) HLSL Shader Compiler 6.3.9600.16384
+//
+//
+// Resource Bindings:
+//
+// Name                                 Type  Format         Dim Slot Elements
+// ------------------------------ ---------- ------- ----------- ---- --------
+// Depth                             texture   float        2dMS    0        1
+// Stencil                           texture   uint2        2dMS    1        1
+//
+//
+//
+// Input signature:
+//
+// Name                 Index   Mask Register SysValue  Format   Used
+// -------------------- ----- ------ -------- -------- ------- ------
+// SV_Position              0   xyzw        0      POS   float       
+// TEXCOORD                 0   xy          1     NONE   float   xy  
+//
+//
+// Output signature:
+//
+// Name                 Index   Mask Register SysValue  Format   Used
+// -------------------- ----- ------ -------- -------- ------- ------
+// SV_Target                0   xy          0   TARGET   float   xy  
+//
+ps_4_1
+dcl_globalFlags refactoringAllowed
+dcl_resource_texture2dms(0) (float,float,float,float) t0
+dcl_resource_texture2dms(0) (uint,uint,uint,uint) t1
+dcl_input_ps linear v1.xy
+dcl_output o0.xy
+dcl_temps 1
+resinfo_uint r0.xy, l(0), t0.xyzw
+utof r0.xy, r0.xyxx
+mul r0.xy, r0.xyxx, v1.xyxx
+ftou r0.xy, r0.xyxx
+mov r0.zw, l(0,0,0,0)
+ldms r0.z, r0.xyzw, t1.xzyw, l(0)
+ldms r0.x, r0.xyww, t0.xyzw, l(0)
+mov o0.x, r0.x
+utof o0.y, r0.z
+ret 
+// Approximately 10 instruction slots used
+#endif
+
+const BYTE g_PS_ResolveDepthStencil[] = {
+    68,  88,  66,  67,  229, 191, 254, 12,  10,  19,  181, 162, 222, 203, 244, 146, 104, 226, 195,
+    177, 1,   0,   0,   0,   40,  3,   0,   0,   5,   0,   0,   0,   52,  0,   0,   0,   216, 0,
+    0,   0,   48,  1,   0,   0,   100, 1,   0,   0,   172, 2,   0,   0,   82,  68,  69,  70,  156,
+    0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   2,   0,   0,   0,   28,  0,   0,   0,
+    1,   4,   255, 255, 0,   1,   0,   0,   106, 0,   0,   0,   92,  0,   0,   0,   2,   0,   0,
+    0,   5,   0,   0,   0,   6,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   1,   0,
+    0,   0,   1,   0,   0,   0,   98,  0,   0,   0,   2,   0,   0,   0,   4,   0,   0,   0,   6,
+    0,   0,   0,   0,   0,   0,   0,   1,   0,   0,   0,   1,   0,   0,   0,   5,   0,   0,   0,
+    68,  101, 112, 116, 104, 0,   83,  116, 101, 110, 99,  105, 108, 0,   77,  105, 99,  114, 111,
+    115, 111, 102, 116, 32,  40,  82,  41,  32,  72,  76,  83,  76,  32,  83,  104, 97,  100, 101,
+    114, 32,  67,  111, 109, 112, 105, 108, 101, 114, 32,  54,  46,  51,  46,  57,  54,  48,  48,
+    46,  49,  54,  51,  56,  52,  0,   73,  83,  71,  78,  80,  0,   0,   0,   2,   0,   0,   0,
+    8,   0,   0,   0,   56,  0,   0,   0,   0,   0,   0,   0,   1,   0,   0,   0,   3,   0,   0,
+    0,   0,   0,   0,   0,   15,  0,   0,   0,   68,  0,   0,   0,   0,   0,   0,   0,   0,   0,
+    0,   0,   3,   0,   0,   0,   1,   0,   0,   0,   3,   3,   0,   0,   83,  86,  95,  80,  111,
+    115, 105, 116, 105, 111, 110, 0,   84,  69,  88,  67,  79,  79,  82,  68,  0,   171, 171, 171,
+    79,  83,  71,  78,  44,  0,   0,   0,   1,   0,   0,   0,   8,   0,   0,   0,   32,  0,   0,
+    0,   0,   0,   0,   0,   0,   0,   0,   0,   3,   0,   0,   0,   0,   0,   0,   0,   3,   12,
+    0,   0,   83,  86,  95,  84,  97,  114, 103, 101, 116, 0,   171, 171, 83,  72,  68,  82,  64,
+    1,   0,   0,   65,  0,   0,   0,   80,  0,   0,   0,   106, 8,   0,   1,   88,  32,  0,   4,
+    0,   112, 16,  0,   0,   0,   0,   0,   85,  85,  0,   0,   88,  32,  0,   4,   0,   112, 16,
+    0,   1,   0,   0,   0,   68,  68,  0,   0,   98,  16,  0,   3,   50,  16,  16,  0,   1,   0,
+    0,   0,   101, 0,   0,   3,   50,  32,  16,  0,   0,   0,   0,   0,   104, 0,   0,   2,   1,
+    0,   0,   0,   61,  16,  0,   7,   50,  0,   16,  0,   0,   0,   0,   0,   1,   64,  0,   0,
+    0,   0,   0,   0,   70,  126, 16,  0,   0,   0,   0,   0,   86,  0,   0,   5,   50,  0,   16,
+    0,   0,   0,   0,   0,   70,  0,   16,  0,   0,   0,   0,   0,   56,  0,   0,   7,   50,  0,
+    16,  0,   0,   0,   0,   0,   70,  0,   16,  0,   0,   0,   0,   0,   70,  16,  16,  0,   1,
+    0,   0,   0,   28,  0,   0,   5,   50,  0,   16,  0,   0,   0,   0,   0,   70,  0,   16,  0,
+    0,   0,   0,   0,   54,  0,   0,   8,   194, 0,   16,  0,   0,   0,   0,   0,   2,   64,  0,
+    0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   46,  0,
+    0,   9,   66,  0,   16,  0,   0,   0,   0,   0,   70,  14,  16,  0,   0,   0,   0,   0,   134,
+    125, 16,  0,   1,   0,   0,   0,   1,   64,  0,   0,   0,   0,   0,   0,   46,  0,   0,   9,
+    18,  0,   16,  0,   0,   0,   0,   0,   70,  15,  16,  0,   0,   0,   0,   0,   70,  126, 16,
+    0,   0,   0,   0,   0,   1,   64,  0,   0,   0,   0,   0,   0,   54,  0,   0,   5,   18,  32,
+    16,  0,   0,   0,   0,   0,   10,  0,   16,  0,   0,   0,   0,   0,   86,  0,   0,   5,   34,
+    32,  16,  0,   0,   0,   0,   0,   42,  0,   16,  0,   0,   0,   0,   0,   62,  0,   0,   1,
+    83,  84,  65,  84,  116, 0,   0,   0,   10,  0,   0,   0,   1,   0,   0,   0,   0,   0,   0,
+    0,   2,   0,   0,   0,   1,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   1,   0,
+    0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+    0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   2,   0,   0,   0,   0,   0,   0,   0,
+    0,   0,   0,   0,   0,   0,   0,   0,   2,   0,   0,   0,   0,   0,   0,   0,   3,   0,   0,
+    0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+    0,   0,   0,   0,   0,   0,   0,   0,   0,   0};
--- a/gfx/angle/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/resolvedepthstencil11_vs.h
+++ b/gfx/angle/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/resolvedepthstencil11_vs.h
@@ -1,84 +1,84 @@
-#if 0
-//
-// Generated by Microsoft (R) HLSL Shader Compiler 6.3.9600.16384
-//
-//
-//
-// Input signature:
-//
-// Name                 Index   Mask Register SysValue  Format   Used
-// -------------------- ----- ------ -------- -------- ------- ------
-// SV_VertexID              0   x           0   VERTID    uint   x   
-//
-//
-// Output signature:
-//
-// Name                 Index   Mask Register SysValue  Format   Used
-// -------------------- ----- ------ -------- -------- ------- ------
-// SV_Position              0   xyzw        0      POS   float   xyzw
-// TEXCOORD                 0   xy          1     NONE   float   xy  
-//
-vs_4_1
-dcl_globalFlags refactoringAllowed
-dcl_immediateConstantBuffer { { -1.000000, 1.000000, 0, 0},
-                              { 1.000000, -1.000000, 0, 0},
-                              { -1.000000, -1.000000, 0, 0},
-                              { -1.000000, 1.000000, 0, 0},
-                              { 1.000000, 1.000000, 0, 0},
-                              { 1.000000, -1.000000, 0, 0} }
-dcl_input_sgv v0.x, vertex_id
-dcl_output_siv o0.xyzw, position
-dcl_output o1.xy
-dcl_temps 1
-mov o0.zw, l(0,0,0,1.000000)
-mov r0.x, v0.x
-mov o0.xy, icb[r0.x + 0].xyxx
-add r0.y, l(1.000000), icb[r0.x + 0].x
-add r0.x, l(1.000000), -icb[r0.x + 0].y
-mul o1.xy, r0.yxyy, l(0.500000, 0.500000, 0.000000, 0.000000)
-ret 
-// Approximately 7 instruction slots used
-#endif
-
-const BYTE g_VS_ResolveDepthStencil[] = {
-    68,  88,  66,  67,  205, 15,  103, 70,  202, 235, 195, 98,  255, 82,  84,  239, 130, 6,   12,
-    104, 1,   0,   0,   0,   0,   3,   0,   0,   5,   0,   0,   0,   52,  0,   0,   0,   140, 0,
-    0,   0,   192, 0,   0,   0,   24,  1,   0,   0,   132, 2,   0,   0,   82,  68,  69,  70,  80,
-    0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   28,  0,   0,   0,
-    1,   4,   254, 255, 0,   1,   0,   0,   28,  0,   0,   0,   77,  105, 99,  114, 111, 115, 111,
-    102, 116, 32,  40,  82,  41,  32,  72,  76,  83,  76,  32,  83,  104, 97,  100, 101, 114, 32,
-    67,  111, 109, 112, 105, 108, 101, 114, 32,  54,  46,  51,  46,  57,  54,  48,  48,  46,  49,
-    54,  51,  56,  52,  0,   171, 171, 73,  83,  71,  78,  44,  0,   0,   0,   1,   0,   0,   0,
-    8,   0,   0,   0,   32,  0,   0,   0,   0,   0,   0,   0,   6,   0,   0,   0,   1,   0,   0,
-    0,   0,   0,   0,   0,   1,   1,   0,   0,   83,  86,  95,  86,  101, 114, 116, 101, 120, 73,
-    68,  0,   79,  83,  71,  78,  80,  0,   0,   0,   2,   0,   0,   0,   8,   0,   0,   0,   56,
-    0,   0,   0,   0,   0,   0,   0,   1,   0,   0,   0,   3,   0,   0,   0,   0,   0,   0,   0,
-    15,  0,   0,   0,   68,  0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   3,   0,   0,
-    0,   1,   0,   0,   0,   3,   12,  0,   0,   83,  86,  95,  80,  111, 115, 105, 116, 105, 111,
-    110, 0,   84,  69,  88,  67,  79,  79,  82,  68,  0,   171, 171, 171, 83,  72,  68,  82,  100,
-    1,   0,   0,   65,  0,   1,   0,   89,  0,   0,   0,   106, 8,   0,   1,   53,  24,  0,   0,
-    26,  0,   0,   0,   0,   0,   128, 191, 0,   0,   128, 63,  0,   0,   0,   0,   0,   0,   0,
-    0,   0,   0,   128, 63,  0,   0,   128, 191, 0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
-    128, 191, 0,   0,   128, 191, 0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   128, 191, 0,
-    0,   128, 63,  0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   128, 63,  0,   0,   128, 63,
-    0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   128, 63,  0,   0,   128, 191, 0,   0,   0,
-    0,   0,   0,   0,   0,   96,  0,   0,   4,   18,  16,  16,  0,   0,   0,   0,   0,   6,   0,
-    0,   0,   103, 0,   0,   4,   242, 32,  16,  0,   0,   0,   0,   0,   1,   0,   0,   0,   101,
-    0,   0,   3,   50,  32,  16,  0,   1,   0,   0,   0,   104, 0,   0,   2,   1,   0,   0,   0,
-    54,  0,   0,   8,   194, 32,  16,  0,   0,   0,   0,   0,   2,   64,  0,   0,   0,   0,   0,
-    0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   128, 63,  54,  0,   0,   5,   18,  0,
-    16,  0,   0,   0,   0,   0,   10,  16,  16,  0,   0,   0,   0,   0,   54,  0,   0,   6,   50,
-    32,  16,  0,   0,   0,   0,   0,   70,  144, 144, 0,   10,  0,   16,  0,   0,   0,   0,   0,
-    0,   0,   0,   8,   34,  0,   16,  0,   0,   0,   0,   0,   1,   64,  0,   0,   0,   0,   128,
-    63,  10,  144, 144, 0,   10,  0,   16,  0,   0,   0,   0,   0,   0,   0,   0,   9,   18,  0,
-    16,  0,   0,   0,   0,   0,   1,   64,  0,   0,   0,   0,   128, 63,  26,  144, 144, 128, 65,
-    0,   0,   0,   10,  0,   16,  0,   0,   0,   0,   0,   56,  0,   0,   10,  50,  32,  16,  0,
-    1,   0,   0,   0,   22,  5,   16,  0,   0,   0,   0,   0,   2,   64,  0,   0,   0,   0,   0,
-    63,  0,   0,   0,   63,  0,   0,   0,   0,   0,   0,   0,   0,   62,  0,   0,   1,   83,  84,
-    65,  84,  116, 0,   0,   0,   7,   0,   0,   0,   1,   0,   0,   0,   6,   0,   0,   0,   3,
-    0,   0,   0,   3,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   1,   0,   0,   0,
-    0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
-    0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
-    0,   0,   0,   0,   0,   0,   3,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
-    0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
-    0,   0,   0,   0,   0,   0,   0,   0};
+#if 0
+//
+// Generated by Microsoft (R) HLSL Shader Compiler 6.3.9600.16384
+//
+//
+//
+// Input signature:
+//
+// Name                 Index   Mask Register SysValue  Format   Used
+// -------------------- ----- ------ -------- -------- ------- ------
+// SV_VertexID              0   x           0   VERTID    uint   x   
+//
+//
+// Output signature:
+//
+// Name                 Index   Mask Register SysValue  Format   Used
+// -------------------- ----- ------ -------- -------- ------- ------
+// SV_Position              0   xyzw        0      POS   float   xyzw
+// TEXCOORD                 0   xy          1     NONE   float   xy  
+//
+vs_4_1
+dcl_globalFlags refactoringAllowed
+dcl_immediateConstantBuffer { { -1.000000, 1.000000, 0, 0},
+                              { 1.000000, -1.000000, 0, 0},
+                              { -1.000000, -1.000000, 0, 0},
+                              { -1.000000, 1.000000, 0, 0},
+                              { 1.000000, 1.000000, 0, 0},
+                              { 1.000000, -1.000000, 0, 0} }
+dcl_input_sgv v0.x, vertex_id
+dcl_output_siv o0.xyzw, position
+dcl_output o1.xy
+dcl_temps 1
+mov o0.zw, l(0,0,0,1.000000)
+mov r0.x, v0.x
+mov o0.xy, icb[r0.x + 0].xyxx
+add r0.y, l(1.000000), icb[r0.x + 0].x
+add r0.x, l(1.000000), -icb[r0.x + 0].y
+mul o1.xy, r0.yxyy, l(0.500000, 0.500000, 0.000000, 0.000000)
+ret 
+// Approximately 7 instruction slots used
+#endif
+
+const BYTE g_VS_ResolveDepthStencil[] = {
+    68,  88,  66,  67,  205, 15,  103, 70,  202, 235, 195, 98,  255, 82,  84,  239, 130, 6,   12,
+    104, 1,   0,   0,   0,   0,   3,   0,   0,   5,   0,   0,   0,   52,  0,   0,   0,   140, 0,
+    0,   0,   192, 0,   0,   0,   24,  1,   0,   0,   132, 2,   0,   0,   82,  68,  69,  70,  80,
+    0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   28,  0,   0,   0,
+    1,   4,   254, 255, 0,   1,   0,   0,   28,  0,   0,   0,   77,  105, 99,  114, 111, 115, 111,
+    102, 116, 32,  40,  82,  41,  32,  72,  76,  83,  76,  32,  83,  104, 97,  100, 101, 114, 32,
+    67,  111, 109, 112, 105, 108, 101, 114, 32,  54,  46,  51,  46,  57,  54,  48,  48,  46,  49,
+    54,  51,  56,  52,  0,   171, 171, 73,  83,  71,  78,  44,  0,   0,   0,   1,   0,   0,   0,
+    8,   0,   0,   0,   32,  0,   0,   0,   0,   0,   0,   0,   6,   0,   0,   0,   1,   0,   0,
+    0,   0,   0,   0,   0,   1,   1,   0,   0,   83,  86,  95,  86,  101, 114, 116, 101, 120, 73,
+    68,  0,   79,  83,  71,  78,  80,  0,   0,   0,   2,   0,   0,   0,   8,   0,   0,   0,   56,
+    0,   0,   0,   0,   0,   0,   0,   1,   0,   0,   0,   3,   0,   0,   0,   0,   0,   0,   0,
+    15,  0,   0,   0,   68,  0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   3,   0,   0,
+    0,   1,   0,   0,   0,   3,   12,  0,   0,   83,  86,  95,  80,  111, 115, 105, 116, 105, 111,
+    110, 0,   84,  69,  88,  67,  79,  79,  82,  68,  0,   171, 171, 171, 83,  72,  68,  82,  100,
+    1,   0,   0,   65,  0,   1,   0,   89,  0,   0,   0,   106, 8,   0,   1,   53,  24,  0,   0,
+    26,  0,   0,   0,   0,   0,   128, 191, 0,   0,   128, 63,  0,   0,   0,   0,   0,   0,   0,
+    0,   0,   0,   128, 63,  0,   0,   128, 191, 0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+    128, 191, 0,   0,   128, 191, 0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   128, 191, 0,
+    0,   128, 63,  0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   128, 63,  0,   0,   128, 63,
+    0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   128, 63,  0,   0,   128, 191, 0,   0,   0,
+    0,   0,   0,   0,   0,   96,  0,   0,   4,   18,  16,  16,  0,   0,   0,   0,   0,   6,   0,
+    0,   0,   103, 0,   0,   4,   242, 32,  16,  0,   0,   0,   0,   0,   1,   0,   0,   0,   101,
+    0,   0,   3,   50,  32,  16,  0,   1,   0,   0,   0,   104, 0,   0,   2,   1,   0,   0,   0,
+    54,  0,   0,   8,   194, 32,  16,  0,   0,   0,   0,   0,   2,   64,  0,   0,   0,   0,   0,
+    0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   128, 63,  54,  0,   0,   5,   18,  0,
+    16,  0,   0,   0,   0,   0,   10,  16,  16,  0,   0,   0,   0,   0,   54,  0,   0,   6,   50,
+    32,  16,  0,   0,   0,   0,   0,   70,  144, 144, 0,   10,  0,   16,  0,   0,   0,   0,   0,
+    0,   0,   0,   8,   34,  0,   16,  0,   0,   0,   0,   0,   1,   64,  0,   0,   0,   0,   128,
+    63,  10,  144, 144, 0,   10,  0,   16,  0,   0,   0,   0,   0,   0,   0,   0,   9,   18,  0,
+    16,  0,   0,   0,   0,   0,   1,   64,  0,   0,   0,   0,   128, 63,  26,  144, 144, 128, 65,
+    0,   0,   0,   10,  0,   16,  0,   0,   0,   0,   0,   56,  0,   0,   10,  50,  32,  16,  0,
+    1,   0,   0,   0,   22,  5,   16,  0,   0,   0,   0,   0,   2,   64,  0,   0,   0,   0,   0,
+    63,  0,   0,   0,   63,  0,   0,   0,   0,   0,   0,   0,   0,   62,  0,   0,   1,   83,  84,
+    65,  84,  116, 0,   0,   0,   7,   0,   0,   0,   1,   0,   0,   0,   6,   0,   0,   0,   3,
+    0,   0,   0,   3,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   1,   0,   0,   0,
+    0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+    0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+    0,   0,   0,   0,   0,   0,   3,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+    0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+    0,   0,   0,   0,   0,   0,   0,   0};
--- a/gfx/angle/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/resolvestencil11_ps.h
+++ b/gfx/angle/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/resolvestencil11_ps.h
@@ -1,84 +1,84 @@
-#if 0
-//
-// Generated by Microsoft (R) HLSL Shader Compiler 6.3.9600.16384
-//
-//
-// Resource Bindings:
-//
-// Name                                 Type  Format         Dim Slot Elements
-// ------------------------------ ---------- ------- ----------- ---- --------
-// Stencil                           texture   uint2        2dMS    1        1
-//
-//
-//
-// Input signature:
-//
-// Name                 Index   Mask Register SysValue  Format   Used
-// -------------------- ----- ------ -------- -------- ------- ------
-// SV_Position              0   xyzw        0      POS   float       
-// TEXCOORD                 0   xy          1     NONE   float   xy  
-//
-//
-// Output signature:
-//
-// Name                 Index   Mask Register SysValue  Format   Used
-// -------------------- ----- ------ -------- -------- ------- ------
-// SV_Target                0   xy          0   TARGET   float   xy  
-//
-ps_4_1
-dcl_globalFlags refactoringAllowed
-dcl_resource_texture2dms(0) (uint,uint,uint,uint) t1
-dcl_input_ps linear v1.xy
-dcl_output o0.xy
-dcl_temps 1
-resinfo_uint r0.xy, l(0), t1.xyzw
-utof r0.xy, r0.xyxx
-mul r0.xy, r0.xyxx, v1.xyxx
-ftou r0.xy, r0.xyxx
-mov r0.zw, l(0,0,0,0)
-ldms r0.x, r0.xyzw, t1.yxzw, l(0)
-utof o0.y, r0.x
-mov o0.x, l(0)
-ret 
-// Approximately 9 instruction slots used
-#endif
-
-const BYTE g_PS_ResolveStencil[] = {
-    68,  88,  66,  67,  122, 29,  34,  146, 254, 203, 175, 97,  151, 254, 255, 190, 91, 40,  55,
-    118, 1,   0,   0,   0,   208, 2,   0,   0,   5,   0,   0,   0,   52,  0,   0,   0,  180, 0,
-    0,   0,   12,  1,   0,   0,   64,  1,   0,   0,   84,  2,   0,   0,   82,  68,  69, 70,  120,
-    0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   1,   0,   0,   0,   28,  0,  0,   0,
-    1,   4,   255, 255, 0,   1,   0,   0,   68,  0,   0,   0,   60,  0,   0,   0,   2,  0,   0,
-    0,   4,   0,   0,   0,   6,   0,   0,   0,   0,   0,   0,   0,   1,   0,   0,   0,  1,   0,
-    0,   0,   5,   0,   0,   0,   83,  116, 101, 110, 99,  105, 108, 0,   77,  105, 99, 114, 111,
-    115, 111, 102, 116, 32,  40,  82,  41,  32,  72,  76,  83,  76,  32,  83,  104, 97, 100, 101,
-    114, 32,  67,  111, 109, 112, 105, 108, 101, 114, 32,  54,  46,  51,  46,  57,  54, 48,  48,
-    46,  49,  54,  51,  56,  52,  0,   171, 171, 73,  83,  71,  78,  80,  0,   0,   0,  2,   0,
-    0,   0,   8,   0,   0,   0,   56,  0,   0,   0,   0,   0,   0,   0,   1,   0,   0,  0,   3,
-    0,   0,   0,   0,   0,   0,   0,   15,  0,   0,   0,   68,  0,   0,   0,   0,   0,  0,   0,
-    0,   0,   0,   0,   3,   0,   0,   0,   1,   0,   0,   0,   3,   3,   0,   0,   83, 86,  95,
-    80,  111, 115, 105, 116, 105, 111, 110, 0,   84,  69,  88,  67,  79,  79,  82,  68, 0,   171,
-    171, 171, 79,  83,  71,  78,  44,  0,   0,   0,   1,   0,   0,   0,   8,   0,   0,  0,   32,
-    0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   3,   0,   0,   0,   0,   0,  0,   0,
-    3,   12,  0,   0,   83,  86,  95,  84,  97,  114, 103, 101, 116, 0,   171, 171, 83, 72,  68,
-    82,  12,  1,   0,   0,   65,  0,   0,   0,   67,  0,   0,   0,   106, 8,   0,   1,  88,  32,
-    0,   4,   0,   112, 16,  0,   1,   0,   0,   0,   68,  68,  0,   0,   98,  16,  0,  3,   50,
-    16,  16,  0,   1,   0,   0,   0,   101, 0,   0,   3,   50,  32,  16,  0,   0,   0,  0,   0,
-    104, 0,   0,   2,   1,   0,   0,   0,   61,  16,  0,   7,   50,  0,   16,  0,   0,  0,   0,
-    0,   1,   64,  0,   0,   0,   0,   0,   0,   70,  126, 16,  0,   1,   0,   0,   0,  86,  0,
-    0,   5,   50,  0,   16,  0,   0,   0,   0,   0,   70,  0,   16,  0,   0,   0,   0,  0,   56,
-    0,   0,   7,   50,  0,   16,  0,   0,   0,   0,   0,   70,  0,   16,  0,   0,   0,  0,   0,
-    70,  16,  16,  0,   1,   0,   0,   0,   28,  0,   0,   5,   50,  0,   16,  0,   0,  0,   0,
-    0,   70,  0,   16,  0,   0,   0,   0,   0,   54,  0,   0,   8,   194, 0,   16,  0,  0,   0,
-    0,   0,   2,   64,  0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,  0,   0,
-    0,   0,   0,   46,  0,   0,   9,   18,  0,   16,  0,   0,   0,   0,   0,   70,  14, 16,  0,
-    0,   0,   0,   0,   22,  126, 16,  0,   1,   0,   0,   0,   1,   64,  0,   0,   0,  0,   0,
-    0,   86,  0,   0,   5,   34,  32,  16,  0,   0,   0,   0,   0,   10,  0,   16,  0,  0,   0,
-    0,   0,   54,  0,   0,   5,   18,  32,  16,  0,   0,   0,   0,   0,   1,   64,  0,  0,   0,
-    0,   0,   0,   62,  0,   0,   1,   83,  84,  65,  84,  116, 0,   0,   0,   9,   0,  0,   0,
-    1,   0,   0,   0,   0,   0,   0,   0,   2,   0,   0,   0,   1,   0,   0,   0,   0,  0,   0,
-    0,   0,   0,   0,   0,   1,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,  0,   0,
-    0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,  0,   1,
-    0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   2,   0,  0,   0,
-    0,   0,   0,   0,   3,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,  0,   0,
-    0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0};
+#if 0
+//
+// Generated by Microsoft (R) HLSL Shader Compiler 6.3.9600.16384
+//
+//
+// Resource Bindings:
+//
+// Name                                 Type  Format         Dim Slot Elements
+// ------------------------------ ---------- ------- ----------- ---- --------
+// Stencil                           texture   uint2        2dMS    1        1
+//
+//
+//
+// Input signature:
+//
+// Name                 Index   Mask Register SysValue  Format   Used
+// -------------------- ----- ------ -------- -------- ------- ------
+// SV_Position              0   xyzw        0      POS   float       
+// TEXCOORD                 0   xy          1     NONE   float   xy  
+//
+//
+// Output signature:
+//
+// Name                 Index   Mask Register SysValue  Format   Used
+// -------------------- ----- ------ -------- -------- ------- ------
+// SV_Target                0   xy          0   TARGET   float   xy  
+//
+ps_4_1
+dcl_globalFlags refactoringAllowed
+dcl_resource_texture2dms(0) (uint,uint,uint,uint) t1
+dcl_input_ps linear v1.xy
+dcl_output o0.xy
+dcl_temps 1
+resinfo_uint r0.xy, l(0), t1.xyzw
+utof r0.xy, r0.xyxx
+mul r0.xy, r0.xyxx, v1.xyxx
+ftou r0.xy, r0.xyxx
+mov r0.zw, l(0,0,0,0)
+ldms r0.x, r0.xyzw, t1.yxzw, l(0)
+utof o0.y, r0.x
+mov o0.x, l(0)
+ret 
+// Approximately 9 instruction slots used
+#endif
+
+const BYTE g_PS_ResolveStencil[] = {
+    68,  88,  66,  67,  122, 29,  34,  146, 254, 203, 175, 97,  151, 254, 255, 190, 91, 40,  55,
+    118, 1,   0,   0,   0,   208, 2,   0,   0,   5,   0,   0,   0,   52,  0,   0,   0,  180, 0,
+    0,   0,   12,  1,   0,   0,   64,  1,   0,   0,   84,  2,   0,   0,   82,  68,  69, 70,  120,
+    0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   1,   0,   0,   0,   28,  0,  0,   0,
+    1,   4,   255, 255, 0,   1,   0,   0,   68,  0,   0,   0,   60,  0,   0,   0,   2,  0,   0,
+    0,   4,   0,   0,   0,   6,   0,   0,   0,   0,   0,   0,   0,   1,   0,   0,   0,  1,   0,
+    0,   0,   5,   0,   0,   0,   83,  116, 101, 110, 99,  105, 108, 0,   77,  105, 99, 114, 111,
+    115, 111, 102, 116, 32,  40,  82,  41,  32,  72,  76,  83,  76,  32,  83,  104, 97, 100, 101,
+    114, 32,  67,  111, 109, 112, 105, 108, 101, 114, 32,  54,  46,  51,  46,  57,  54, 48,  48,
+    46,  49,  54,  51,  56,  52,  0,   171, 171, 73,  83,  71,  78,  80,  0,   0,   0,  2,   0,
+    0,   0,   8,   0,   0,   0,   56,  0,   0,   0,   0,   0,   0,   0,   1,   0,   0,  0,   3,
+    0,   0,   0,   0,   0,   0,   0,   15,  0,   0,   0,   68,  0,   0,   0,   0,   0,  0,   0,
+    0,   0,   0,   0,   3,   0,   0,   0,   1,   0,   0,   0,   3,   3,   0,   0,   83, 86,  95,
+    80,  111, 115, 105, 116, 105, 111, 110, 0,   84,  69,  88,  67,  79,  79,  82,  68, 0,   171,
+    171, 171, 79,  83,  71,  78,  44,  0,   0,   0,   1,   0,   0,   0,   8,   0,   0,  0,   32,
+    0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   3,   0,   0,   0,   0,   0,  0,   0,
+    3,   12,  0,   0,   83,  86,  95,  84,  97,  114, 103, 101, 116, 0,   171, 171, 83, 72,  68,
+    82,  12,  1,   0,   0,   65,  0,   0,   0,   67,  0,   0,   0,   106, 8,   0,   1,  88,  32,
+    0,   4,   0,   112, 16,  0,   1,   0,   0,   0,   68,  68,  0,   0,   98,  16,  0,  3,   50,
+    16,  16,  0,   1,   0,   0,   0,   101, 0,   0,   3,   50,  32,  16,  0,   0,   0,  0,   0,
+    104, 0,   0,   2,   1,   0,   0,   0,   61,  16,  0,   7,   50,  0,   16,  0,   0,  0,   0,
+    0,   1,   64,  0,   0,   0,   0,   0,   0,   70,  126, 16,  0,   1,   0,   0,   0,  86,  0,
+    0,   5,   50,  0,   16,  0,   0,   0,   0,   0,   70,  0,   16,  0,   0,   0,   0,  0,   56,
+    0,   0,   7,   50,  0,   16,  0,   0,   0,   0,   0,   70,  0,   16,  0,   0,   0,  0,   0,
+    70,  16,  16,  0,   1,   0,   0,   0,   28,  0,   0,   5,   50,  0,   16,  0,   0,  0,   0,
+    0,   70,  0,   16,  0,   0,   0,   0,   0,   54,  0,   0,   8,   194, 0,   16,  0,  0,   0,
+    0,   0,   2,   64,  0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,  0,   0,
+    0,   0,   0,   46,  0,   0,   9,   18,  0,   16,  0,   0,   0,   0,   0,   70,  14, 16,  0,
+    0,   0,   0,   0,   22,  126, 16,  0,   1,   0,   0,   0,   1,   64,  0,   0,   0,  0,   0,
+    0,   86,  0,   0,   5,   34,  32,  16,  0,   0,   0,   0,   0,   10,  0,   16,  0,  0,   0,
+    0,   0,   54,  0,   0,   5,   18,  32,  16,  0,   0,   0,   0,   0,   1,   64,  0,  0,   0,
+    0,   0,   0,   62,  0,   0,   1,   83,  84,  65,  84,  116, 0,   0,   0,   9,   0,  0,   0,
+    1,   0,   0,   0,   0,   0,   0,   0,   2,   0,   0,   0,   1,   0,   0,   0,   0,  0,   0,
+    0,   0,   0,   0,   0,   1,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,  0,   0,
+    0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,  0,   1,
+    0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   2,   0,  0,   0,
+    0,   0,   0,   0,   3,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,  0,   0,
+    0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0};
--- a/gfx/angle/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/swizzlef2darrayps.h
+++ b/gfx/angle/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/swizzlef2darrayps.h
@@ -1,278 +1,278 @@
-#if 0
-//
-// Generated by Microsoft (R) HLSL Shader Compiler 6.3.9600.16384
-//
-//
-// Buffer Definitions: 
-//
-// cbuffer SwizzleProperties
-// {
-//
-//   uint4 SwizzleIndices;              // Offset:    0 Size:    16
-//
-// }
-//
-//
-// Resource Bindings:
-//
-// Name                                 Type  Format         Dim Slot Elements
-// ------------------------------ ---------- ------- ----------- ---- --------
-// Sampler                           sampler      NA          NA    0        1
-// TextureF2DArray                   texture  float4     2darray    0        1
-// SwizzleProperties                 cbuffer      NA          NA    0        1
-//
-//
-//
-// Input signature:
-//
-// Name                 Index   Mask Register SysValue  Format   Used
-// -------------------- ----- ------ -------- -------- ------- ------
-// SV_POSITION              0   xyzw        0      POS   float       
-// SV_RENDERTARGETARRAYINDEX     0   x           1  RTINDEX    uint   x   
-// TEXCOORD                 0   xyz         2     NONE   float   xy  
-//
-//
-// Output signature:
-//
-// Name                 Index   Mask Register SysValue  Format   Used
-// -------------------- ----- ------ -------- -------- ------- ------
-// SV_TARGET                0   xyzw        0   TARGET   float   xyzw
-//
-ps_4_0
-dcl_constantbuffer cb0[1], immediateIndexed
-dcl_sampler s0, mode_default
-dcl_resource_texture2darray (float,float,float,float) t0
-dcl_input_ps_siv constant v1.x, rendertarget_array_index
-dcl_input_ps linear v2.xy
-dcl_output o0.xyzw
-dcl_temps 1
-dcl_indexableTemp x0[6], 4
-utof r0.z, v1.x
-mov r0.xy, v2.xyxx
-sample r0.xyzw, r0.xyzx, t0.xyzw, s0
-mov x0[0].x, r0.x
-mov x0[1].x, r0.y
-mov x0[2].x, r0.z
-mov x0[3].x, r0.w
-mov x0[4].x, l(0)
-mov x0[5].x, l(1.000000)
-mov r0.x, cb0[0].x
-mov o0.x, x0[r0.x + 0].x
-mov r0.x, cb0[0].y
-mov o0.y, x0[r0.x + 0].x
-mov r0.x, cb0[0].z
-mov o0.z, x0[r0.x + 0].x
-mov r0.x, cb0[0].w
-mov o0.w, x0[r0.x + 0].x
-ret 
-// Approximately 18 instruction slots used
-#endif
-
-const BYTE g_PS_SwizzleF2DArray[] =
-{
-     68,  88,  66,  67,  39, 232, 
-     91, 166, 165, 217,  22,  39, 
-    183, 202, 191,  64, 238, 104, 
-    217, 199,   1,   0,   0,   0, 
-    204,   4,   0,   0,   5,   0, 
-      0,   0,  52,   0,   0,   0, 
-    104,   1,   0,   0, 240,   1, 
-      0,   0,  36,   2,   0,   0, 
-     80,   4,   0,   0,  82,  68, 
-     69,  70,  44,   1,   0,   0, 
-      1,   0,   0,   0, 168,   0, 
-      0,   0,   3,   0,   0,   0, 
-     28,   0,   0,   0,   0,   4, 
-    255, 255,   0,   1,   0,   0, 
-    248,   0,   0,   0, 124,   0, 
-      0,   0,   3,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   1,   0, 
-      0,   0,   1,   0,   0,   0, 
-    132,   0,   0,   0,   2,   0, 
-      0,   0,   5,   0,   0,   0, 
-      5,   0,   0,   0, 255, 255, 
-    255, 255,   0,   0,   0,   0, 
-      1,   0,   0,   0,  13,   0, 
-      0,   0, 148,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   1,   0,   0,   0, 
-      1,   0,   0,   0,  83,  97, 
-    109, 112, 108, 101, 114,   0, 
-     84, 101, 120, 116, 117, 114, 
-    101,  70,  50,  68,  65, 114, 
-    114,  97, 121,   0,  83, 119, 
-    105, 122, 122, 108, 101,  80, 
-    114, 111, 112, 101, 114, 116, 
-    105, 101, 115,   0, 171, 171, 
-    148,   0,   0,   0,   1,   0, 
-      0,   0, 192,   0,   0,   0, 
-     16,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-    216,   0,   0,   0,   0,   0, 
-      0,   0,  16,   0,   0,   0, 
-      2,   0,   0,   0, 232,   0, 
-      0,   0,   0,   0,   0,   0, 
-     83, 119, 105, 122, 122, 108, 
-    101,  73, 110, 100, 105,  99, 
-    101, 115,   0, 171,   1,   0, 
-     19,   0,   1,   0,   4,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,  77, 105,  99, 114, 
-    111, 115, 111, 102, 116,  32, 
-     40,  82,  41,  32,  72,  76, 
-     83,  76,  32,  83, 104,  97, 
-    100, 101, 114,  32,  67, 111, 
-    109, 112, 105, 108, 101, 114, 
-     32,  54,  46,  51,  46,  57, 
-     54,  48,  48,  46,  49,  54, 
-     51,  56,  52,   0, 171, 171, 
-     73,  83,  71,  78, 128,   0, 
-      0,   0,   3,   0,   0,   0, 
-      8,   0,   0,   0,  80,   0, 
-      0,   0,   0,   0,   0,   0, 
-      1,   0,   0,   0,   3,   0, 
-      0,   0,   0,   0,   0,   0, 
-     15,   0,   0,   0,  92,   0, 
-      0,   0,   0,   0,   0,   0, 
-      4,   0,   0,   0,   1,   0, 
-      0,   0,   1,   0,   0,   0, 
-      1,   1,   0,   0, 118,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   3,   0, 
-      0,   0,   2,   0,   0,   0, 
-      7,   3,   0,   0,  83,  86, 
-     95,  80,  79,  83,  73,  84, 
-     73,  79,  78,   0,  83,  86, 
-     95,  82,  69,  78,  68,  69, 
-     82,  84,  65,  82,  71,  69, 
-     84,  65,  82,  82,  65,  89, 
-     73,  78,  68,  69,  88,   0, 
-     84,  69,  88,  67,  79,  79, 
-     82,  68,   0, 171,  79,  83, 
-     71,  78,  44,   0,   0,   0, 
-      1,   0,   0,   0,   8,   0, 
-      0,   0,  32,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   3,   0,   0,   0, 
-      0,   0,   0,   0,  15,   0, 
-      0,   0,  83,  86,  95,  84, 
-     65,  82,  71,  69,  84,   0, 
-    171, 171,  83,  72,  68,  82, 
-     36,   2,   0,   0,  64,   0, 
-      0,   0, 137,   0,   0,   0, 
-     89,   0,   0,   4,  70, 142, 
-     32,   0,   0,   0,   0,   0, 
-      1,   0,   0,   0,  90,   0, 
-      0,   3,   0,  96,  16,   0, 
-      0,   0,   0,   0,  88,  64, 
-      0,   4,   0, 112,  16,   0, 
-      0,   0,   0,   0,  85,  85, 
-      0,   0, 100,   8,   0,   4, 
-     18,  16,  16,   0,   1,   0, 
-      0,   0,   4,   0,   0,   0, 
-     98,  16,   0,   3,  50,  16, 
-     16,   0,   2,   0,   0,   0, 
-    101,   0,   0,   3, 242,  32, 
-     16,   0,   0,   0,   0,   0, 
-    104,   0,   0,   2,   1,   0, 
-      0,   0, 105,   0,   0,   4, 
-      0,   0,   0,   0,   6,   0, 
-      0,   0,   4,   0,   0,   0, 
-     86,   0,   0,   5,  66,   0, 
-     16,   0,   0,   0,   0,   0, 
-     10,  16,  16,   0,   1,   0, 
-      0,   0,  54,   0,   0,   5, 
-     50,   0,  16,   0,   0,   0, 
-      0,   0,  70,  16,  16,   0, 
-      2,   0,   0,   0,  69,   0, 
-      0,   9, 242,   0,  16,   0, 
-      0,   0,   0,   0,  70,   2, 
-     16,   0,   0,   0,   0,   0, 
-     70, 126,  16,   0,   0,   0, 
-      0,   0,   0,  96,  16,   0, 
-      0,   0,   0,   0,  54,   0, 
-      0,   6,  18,  48,  32,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,  10,   0,  16,   0, 
-      0,   0,   0,   0,  54,   0, 
-      0,   6,  18,  48,  32,   0, 
-      0,   0,   0,   0,   1,   0, 
-      0,   0,  26,   0,  16,   0, 
-      0,   0,   0,   0,  54,   0, 
-      0,   6,  18,  48,  32,   0, 
-      0,   0,   0,   0,   2,   0, 
-      0,   0,  42,   0,  16,   0, 
-      0,   0,   0,   0,  54,   0, 
-      0,   6,  18,  48,  32,   0, 
-      0,   0,   0,   0,   3,   0, 
-      0,   0,  58,   0,  16,   0, 
-      0,   0,   0,   0,  54,   0, 
-      0,   6,  18,  48,  32,   0, 
-      0,   0,   0,   0,   4,   0, 
-      0,   0,   1,  64,   0,   0, 
-      0,   0,   0,   0,  54,   0, 
-      0,   6,  18,  48,  32,   0, 
-      0,   0,   0,   0,   5,   0, 
-      0,   0,   1,  64,   0,   0, 
-      0,   0, 128,  63,  54,   0, 
-      0,   6,  18,   0,  16,   0, 
-      0,   0,   0,   0,  10, 128, 
-     32,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,  54,   0, 
-      0,   7,  18,  32,  16,   0, 
-      0,   0,   0,   0,  10,  48, 
-     32,   4,   0,   0,   0,   0, 
-     10,   0,  16,   0,   0,   0, 
-      0,   0,  54,   0,   0,   6, 
-     18,   0,  16,   0,   0,   0, 
-      0,   0,  26, 128,  32,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,  54,   0,   0,   7, 
-     34,  32,  16,   0,   0,   0, 
-      0,   0,  10,  48,  32,   4, 
-      0,   0,   0,   0,  10,   0, 
-     16,   0,   0,   0,   0,   0, 
-     54,   0,   0,   6,  18,   0, 
-     16,   0,   0,   0,   0,   0, 
-     42, 128,  32,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-     54,   0,   0,   7,  66,  32, 
-     16,   0,   0,   0,   0,   0, 
-     10,  48,  32,   4,   0,   0, 
-      0,   0,  10,   0,  16,   0, 
-      0,   0,   0,   0,  54,   0, 
-      0,   6,  18,   0,  16,   0, 
-      0,   0,   0,   0,  58, 128, 
-     32,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,  54,   0, 
-      0,   7, 130,  32,  16,   0, 
-      0,   0,   0,   0,  10,  48, 
-     32,   4,   0,   0,   0,   0, 
-     10,   0,  16,   0,   0,   0, 
-      0,   0,  62,   0,   0,   1, 
-     83,  84,  65,  84, 116,   0, 
-      0,   0,  18,   0,   0,   0, 
-      1,   0,   0,   0,   0,   0, 
-      0,   0,   3,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      1,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      6,   0,   0,   0,  10,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   1,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      5,   0,   0,   0,   0,   0, 
-      0,   0,   1,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0
-};
+#if 0
+//
+// Generated by Microsoft (R) HLSL Shader Compiler 6.3.9600.16384
+//
+//
+// Buffer Definitions: 
+//
+// cbuffer SwizzleProperties
+// {
+//
+//   uint4 SwizzleIndices;              // Offset:    0 Size:    16
+//
+// }
+//
+//
+// Resource Bindings:
+//
+// Name                                 Type  Format         Dim Slot Elements
+// ------------------------------ ---------- ------- ----------- ---- --------
+// Sampler                           sampler      NA          NA    0        1
+// TextureF2DArray                   texture  float4     2darray    0        1
+// SwizzleProperties                 cbuffer      NA          NA    0        1
+//
+//
+//
+// Input signature:
+//
+// Name                 Index   Mask Register SysValue  Format   Used
+// -------------------- ----- ------ -------- -------- ------- ------
+// SV_POSITION              0   xyzw        0      POS   float       
+// SV_RENDERTARGETARRAYINDEX     0   x           1  RTINDEX    uint   x   
+// TEXCOORD                 0   xyz         2     NONE   float   xy  
+//
+//
+// Output signature:
+//
+// Name                 Index   Mask Register SysValue  Format   Used
+// -------------------- ----- ------ -------- -------- ------- ------
+// SV_TARGET                0   xyzw        0   TARGET   float   xyzw
+//
+ps_4_0
+dcl_constantbuffer cb0[1], immediateIndexed
+dcl_sampler s0, mode_default
+dcl_resource_texture2darray (float,float,float,float) t0
+dcl_input_ps_siv constant v1.x, rendertarget_array_index
+dcl_input_ps linear v2.xy
+dcl_output o0.xyzw
+dcl_temps 1
+dcl_indexableTemp x0[6], 4
+utof r0.z, v1.x
+mov r0.xy, v2.xyxx
+sample r0.xyzw, r0.xyzx, t0.xyzw, s0
+mov x0[0].x, r0.x
+mov x0[1].x, r0.y
+mov x0[2].x, r0.z
+mov x0[3].x, r0.w
+mov x0[4].x, l(0)
+mov x0[5].x, l(1.000000)
+mov r0.x, cb0[0].x
+mov o0.x, x0[r0.x + 0].x
+mov r0.x, cb0[0].y
+mov o0.y, x0[r0.x + 0].x
+mov r0.x, cb0[0].z
+mov o0.z, x0[r0.x + 0].x
+mov r0.x, cb0[0].w
+mov o0.w, x0[r0.x + 0].x
+ret 
+// Approximately 18 instruction slots used
+#endif
+
+const BYTE g_PS_SwizzleF2DArray[] =
+{
+     68,  88,  66,  67,  39, 232, 
+     91, 166, 165, 217,  22,  39, 
+    183, 202, 191,  64, 238, 104, 
+    217, 199,   1,   0,   0,   0, 
+    204,   4,   0,   0,   5,   0, 
+      0,   0,  52,   0,   0,   0, 
+    104,   1,   0,   0, 240,   1, 
+      0,   0,  36,   2,   0,   0, 
+     80,   4,   0,   0,  82,  68, 
+     69,  70,  44,   1,   0,   0, 
+      1,   0,   0,   0, 168,   0, 
+      0,   0,   3,   0,   0,   0, 
+     28,   0,   0,   0,   0,   4, 
+    255, 255,   0,   1,   0,   0, 
+    248,   0,   0,   0, 124,   0, 
+      0,   0,   3,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   1,   0, 
+      0,   0,   1,   0,   0,   0, 
+    132,   0,   0,   0,   2,   0, 
+      0,   0,   5,   0,   0,   0, 
+      5,   0,   0,   0, 255, 255, 
+    255, 255,   0,   0,   0,   0, 
+      1,   0,   0,   0,  13,   0, 
+      0,   0, 148,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   1,   0,   0,   0, 
+      1,   0,   0,   0,  83,  97, 
+    109, 112, 108, 101, 114,   0, 
+     84, 101, 120, 116, 117, 114, 
+    101,  70,  50,  68,  65, 114, 
+    114,  97, 121,   0,  83, 119, 
+    105, 122, 122, 108, 101,  80, 
+    114, 111, 112, 101, 114, 116, 
+    105, 101, 115,   0, 171, 171, 
+    148,   0,   0,   0,   1,   0, 
+      0,   0, 192,   0,   0,   0, 
+     16,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+    216,   0,   0,   0,   0,   0, 
+      0,   0,  16,   0,   0,   0, 
+      2,   0,   0,   0, 232,   0, 
+      0,   0,   0,   0,   0,   0, 
+     83, 119, 105, 122, 122, 108, 
+    101,  73, 110, 100, 105,  99, 
+    101, 115,   0, 171,   1,   0, 
+     19,   0,   1,   0,   4,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,  77, 105,  99, 114, 
+    111, 115, 111, 102, 116,  32, 
+     40,  82,  41,  32,  72,  76, 
+     83,  76,  32,  83, 104,  97, 
+    100, 101, 114,  32,  67, 111, 
+    109, 112, 105, 108, 101, 114, 
+     32,  54,  46,  51,  46,  57, 
+     54,  48,  48,  46,  49,  54, 
+     51,  56,  52,   0, 171, 171, 
+     73,  83,  71,  78, 128,   0, 
+      0,   0,   3,   0,   0,   0, 
+      8,   0,   0,   0,  80,   0, 
+      0,   0,   0,   0,   0,   0, 
+      1,   0,   0,   0,   3,   0, 
+      0,   0,   0,   0,   0,   0, 
+     15,   0,   0,   0,  92,   0, 
+      0,   0,   0,   0,   0,   0, 
+      4,   0,   0,   0,   1,   0, 
+      0,   0,   1,   0,   0,   0, 
+      1,   1,   0,   0, 118,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   3,   0, 
+      0,   0,   2,   0,   0,   0, 
+      7,   3,   0,   0,  83,  86, 
+     95,  80,  79,  83,  73,  84, 
+     73,  79,  78,   0,  83,  86, 
+     95,  82,  69,  78,  68,  69, 
+     82,  84,  65,  82,  71,  69, 
+     84,  65,  82,  82,  65,  89, 
+     73,  78,  68,  69,  88,   0, 
+     84,  69,  88,  67,  79,  79, 
+     82,  68,   0, 171,  79,  83, 
+     71,  78,  44,   0,   0,   0, 
+      1,   0,   0,   0,   8,   0, 
+      0,   0,  32,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   3,   0,   0,   0, 
+      0,   0,   0,   0,  15,   0, 
+      0,   0,  83,  86,  95,  84, 
+     65,  82,  71,  69,  84,   0, 
+    171, 171,  83,  72,  68,  82, 
+     36,   2,   0,   0,  64,   0, 
+      0,   0, 137,   0,   0,   0, 
+     89,   0,   0,   4,  70, 142, 
+     32,   0,   0,   0,   0,   0, 
+      1,   0,   0,   0,  90,   0, 
+      0,   3,   0,  96,  16,   0, 
+      0,   0,   0,   0,  88,  64, 
+      0,   4,   0, 112,  16,   0, 
+      0,   0,   0,   0,  85,  85, 
+      0,   0, 100,   8,   0,   4, 
+     18,  16,  16,   0,   1,   0, 
+      0,   0,   4,   0,   0,   0, 
+     98,  16,   0,   3,  50,  16, 
+     16,   0,   2,   0,   0,   0, 
+    101,   0,   0,   3, 242,  32, 
+     16,   0,   0,   0,   0,   0, 
+    104,   0,   0,   2,   1,   0, 
+      0,   0, 105,   0,   0,   4, 
+      0,   0,   0,   0,   6,   0, 
+      0,   0,   4,   0,   0,   0, 
+     86,   0,   0,   5,  66,   0, 
+     16,   0,   0,   0,   0,   0, 
+     10,  16,  16,   0,   1,   0, 
+      0,   0,  54,   0,   0,   5, 
+     50,   0,  16,   0,   0,   0, 
+      0,   0,  70,  16,  16,   0, 
+      2,   0,   0,   0,  69,   0, 
+      0,   9, 242,   0,  16,   0, 
+      0,   0,   0,   0,  70,   2, 
+     16,   0,   0,   0,   0,   0, 
+     70, 126,  16,   0,   0,   0, 
+      0,   0,   0,  96,  16,   0, 
+      0,   0,   0,   0,  54,   0, 
+      0,   6,  18,  48,  32,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,  10,   0,  16,   0, 
+      0,   0,   0,   0,  54,   0, 
+      0,   6,  18,  48,  32,   0, 
+      0,   0,   0,   0,   1,   0, 
+      0,   0,  26,   0,  16,   0, 
+      0,   0,   0,   0,  54,   0, 
+      0,   6,  18,  48,  32,   0, 
+      0,   0,   0,   0,   2,   0, 
+      0,   0,  42,   0,  16,   0, 
+      0,   0,   0,   0,  54,   0, 
+      0,   6,  18,  48,  32,   0, 
+      0,   0,   0,   0,   3,   0, 
+      0,   0,  58,   0,  16,   0, 
+      0,   0,   0,   0,  54,   0, 
+      0,   6,  18,  48,  32,   0, 
+      0,   0,   0,   0,   4,   0, 
+      0,   0,   1,  64,   0,   0, 
+      0,   0,   0,   0,  54,   0, 
+      0,   6,  18,  48,  32,   0, 
+      0,   0,   0,   0,   5,   0, 
+      0,   0,   1,  64,   0,   0, 
+      0,   0, 128,  63,  54,   0, 
+      0,   6,  18,   0,  16,   0, 
+      0,   0,   0,   0,  10, 128, 
+     32,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,  54,   0, 
+      0,   7,  18,  32,  16,   0, 
+      0,   0,   0,   0,  10,  48, 
+     32,   4,   0,   0,   0,   0, 
+     10,   0,  16,   0,   0,   0, 
+      0,   0,  54,   0,   0,   6, 
+     18,   0,  16,   0,   0,   0, 
+      0,   0,  26, 128,  32,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,  54,   0,   0,   7, 
+     34,  32,  16,   0,   0,   0, 
+      0,   0,  10,  48,  32,   4, 
+      0,   0,   0,   0,  10,   0, 
+     16,   0,   0,   0,   0,   0, 
+     54,   0,   0,   6,  18,   0, 
+     16,   0,   0,   0,   0,   0, 
+     42, 128,  32,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+     54,   0,   0,   7,  66,  32, 
+     16,   0,   0,   0,   0,   0, 
+     10,  48,  32,   4,   0,   0, 
+      0,   0,  10,   0,  16,   0, 
+      0,   0,   0,   0,  54,   0, 
+      0,   6,  18,   0,  16,   0, 
+      0,   0,   0,   0,  58, 128, 
+     32,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,  54,   0, 
+      0,   7, 130,  32,  16,   0, 
+      0,   0,   0,   0,  10,  48, 
+     32,   4,   0,   0,   0,   0, 
+     10,   0,  16,   0,   0,   0, 
+      0,   0,  62,   0,   0,   1, 
+     83,  84,  65,  84, 116,   0, 
+      0,   0,  18,   0,   0,   0, 
+      1,   0,   0,   0,   0,   0, 
+      0,   0,   3,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      1,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      6,   0,   0,   0,  10,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   1,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      5,   0,   0,   0,   0,   0, 
+      0,   0,   1,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0
+};
--- a/gfx/angle/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/swizzlef2dps.h
+++ b/gfx/angle/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/swizzlef2dps.h
@@ -1,256 +1,256 @@
-#if 0
-//
-// Generated by Microsoft (R) HLSL Shader Compiler 6.3.9600.16384
-//
-//
-// Buffer Definitions: 
-//
-// cbuffer SwizzleProperties
-// {
-//
-//   uint4 SwizzleIndices;              // Offset:    0 Size:    16
-//
-// }
-//
-//
-// Resource Bindings:
-//
-// Name                                 Type  Format         Dim Slot Elements
-// ------------------------------ ---------- ------- ----------- ---- --------
-// Sampler                           sampler      NA          NA    0        1
-// TextureF2D                        texture  float4          2d    0        1
-// SwizzleProperties                 cbuffer      NA          NA    0        1
-//
-//
-//
-// Input signature:
-//
-// Name                 Index   Mask Register SysValue  Format   Used
-// -------------------- ----- ------ -------- -------- ------- ------
-// SV_POSITION              0   xyzw        0      POS   float       
-// TEXCOORD                 0   xy          1     NONE   float   xy  
-//
-//
-// Output signature:
-//
-// Name                 Index   Mask Register SysValue  Format   Used
-// -------------------- ----- ------ -------- -------- ------- ------
-// SV_TARGET                0   xyzw        0   TARGET   float   xyzw
-//
-ps_4_0
-dcl_constantbuffer cb0[1], immediateIndexed
-dcl_sampler s0, mode_default
-dcl_resource_texture2d (float,float,float,float) t0
-dcl_input_ps linear v1.xy
-dcl_output o0.xyzw
-dcl_temps 1
-dcl_indexableTemp x0[6], 4
-sample r0.xyzw, v1.xyxx, t0.xyzw, s0
-mov x0[0].x, r0.x
-mov x0[1].x, r0.y
-mov x0[2].x, r0.z
-mov x0[3].x, r0.w
-mov x0[4].x, l(0)
-mov x0[5].x, l(1.000000)
-mov r0.x, cb0[0].x
-mov o0.x, x0[r0.x + 0].x
-mov r0.x, cb0[0].y
-mov o0.y, x0[r0.x + 0].x
-mov r0.x, cb0[0].z
-mov o0.z, x0[r0.x + 0].x
-mov r0.x, cb0[0].w
-mov o0.w, x0[r0.x + 0].x
-ret 
-// Approximately 16 instruction slots used
-#endif
-
-const BYTE g_PS_SwizzleF2D[] =
-{
-     68,  88,  66,  67, 187, 204, 
-    160,  39, 195, 158, 245,  72, 
-    125, 249,  70, 140, 158, 199, 
-    246, 220,   1,   0,   0,   0, 
-     96,   4,   0,   0,   5,   0, 
-      0,   0,  52,   0,   0,   0, 
-    100,   1,   0,   0, 188,   1, 
-      0,   0, 240,   1,   0,   0, 
-    228,   3,   0,   0,  82,  68, 
-     69,  70,  40,   1,   0,   0, 
-      1,   0,   0,   0, 164,   0, 
-      0,   0,   3,   0,   0,   0, 
-     28,   0,   0,   0,   0,   4, 
-    255, 255,   0,   1,   0,   0, 
-    244,   0,   0,   0, 124,   0, 
-      0,   0,   3,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   1,   0, 
-      0,   0,   1,   0,   0,   0, 
-    132,   0,   0,   0,   2,   0, 
-      0,   0,   5,   0,   0,   0, 
-      4,   0,   0,   0, 255, 255, 
-    255, 255,   0,   0,   0,   0, 
-      1,   0,   0,   0,  13,   0, 
-      0,   0, 143,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   1,   0,   0,   0, 
-      1,   0,   0,   0,  83,  97, 
-    109, 112, 108, 101, 114,   0, 
-     84, 101, 120, 116, 117, 114, 
-    101,  70,  50,  68,   0,  83, 
-    119, 105, 122, 122, 108, 101, 
-     80, 114, 111, 112, 101, 114, 
-    116, 105, 101, 115,   0, 171, 
-    171, 171, 143,   0,   0,   0, 
-      1,   0,   0,   0, 188,   0, 
-      0,   0,  16,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0, 212,   0,   0,   0, 
-      0,   0,   0,   0,  16,   0, 
-      0,   0,   2,   0,   0,   0, 
-    228,   0,   0,   0,   0,   0, 
-      0,   0,  83, 119, 105, 122, 
-    122, 108, 101,  73, 110, 100, 
-    105,  99, 101, 115,   0, 171, 
-      1,   0,  19,   0,   1,   0, 
-      4,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,  77, 105, 
-     99, 114, 111, 115, 111, 102, 
-    116,  32,  40,  82,  41,  32, 
-     72,  76,  83,  76,  32,  83, 
-    104,  97, 100, 101, 114,  32, 
-     67, 111, 109, 112, 105, 108, 
-    101, 114,  32,  54,  46,  51, 
-     46,  57,  54,  48,  48,  46, 
-     49,  54,  51,  56,  52,   0, 
-    171, 171,  73,  83,  71,  78, 
-     80,   0,   0,   0,   2,   0, 
-      0,   0,   8,   0,   0,   0, 
-     56,   0,   0,   0,   0,   0, 
-      0,   0,   1,   0,   0,   0, 
-      3,   0,   0,   0,   0,   0, 
-      0,   0,  15,   0,   0,   0, 
-     68,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      3,   0,   0,   0,   1,   0, 
-      0,   0,   3,   3,   0,   0, 
-     83,  86,  95,  80,  79,  83, 
-     73,  84,  73,  79,  78,   0, 
-     84,  69,  88,  67,  79,  79, 
-     82,  68,   0, 171, 171, 171, 
-     79,  83,  71,  78,  44,   0, 
-      0,   0,   1,   0,   0,   0, 
-      8,   0,   0,   0,  32,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   3,   0, 
-      0,   0,   0,   0,   0,   0, 
-     15,   0,   0,   0,  83,  86, 
-     95,  84,  65,  82,  71,  69, 
-     84,   0, 171, 171,  83,  72, 
-     68,  82, 236,   1,   0,   0, 
-     64,   0,   0,   0, 123,   0, 
-      0,   0,  89,   0,   0,   4, 
-     70, 142,  32,   0,   0,   0, 
-      0,   0,   1,   0,   0,   0, 
-     90,   0,   0,   3,   0,  96, 
-     16,   0,   0,   0,   0,   0, 
-     88,  24,   0,   4,   0, 112, 
-     16,   0,   0,   0,   0,   0, 
-     85,  85,   0,   0,  98,  16, 
-      0,   3,  50,  16,  16,   0, 
-      1,   0,   0,   0, 101,   0, 
-      0,   3, 242,  32,  16,   0, 
-      0,   0,   0,   0, 104,   0, 
-      0,   2,   1,   0,   0,   0, 
-    105,   0,   0,   4,   0,   0, 
-      0,   0,   6,   0,   0,   0, 
-      4,   0,   0,   0,  69,   0, 
-      0,   9, 242,   0,  16,   0, 
-      0,   0,   0,   0,  70,  16, 
-     16,   0,   1,   0,   0,   0, 
-     70, 126,  16,   0,   0,   0, 
-      0,   0,   0,  96,  16,   0, 
-      0,   0,   0,   0,  54,   0, 
-      0,   6,  18,  48,  32,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,  10,   0,  16,   0, 
-      0,   0,   0,   0,  54,   0, 
-      0,   6,  18,  48,  32,   0, 
-      0,   0,   0,   0,   1,   0, 
-      0,   0,  26,   0,  16,   0, 
-      0,   0,   0,   0,  54,   0, 
-      0,   6,  18,  48,  32,   0, 
-      0,   0,   0,   0,   2,   0, 
-      0,   0,  42,   0,  16,   0, 
-      0,   0,   0,   0,  54,   0, 
-      0,   6,  18,  48,  32,   0, 
-      0,   0,   0,   0,   3,   0, 
-      0,   0,  58,   0,  16,   0, 
-      0,   0,   0,   0,  54,   0, 
-      0,   6,  18,  48,  32,   0, 
-      0,   0,   0,   0,   4,   0, 
-      0,   0,   1,  64,   0,   0, 
-      0,   0,   0,   0,  54,   0, 
-      0,   6,  18,  48,  32,   0, 
-      0,   0,   0,   0,   5,   0, 
-      0,   0,   1,  64,   0,   0, 
-      0,   0, 128,  63,  54,   0, 
-      0,   6,  18,   0,  16,   0, 
-      0,   0,   0,   0,  10, 128, 
-     32,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,  54,   0, 
-      0,   7,  18,  32,  16,   0, 
-      0,   0,   0,   0,  10,  48, 
-     32,   4,   0,   0,   0,   0, 
-     10,   0,  16,   0,   0,   0, 
-      0,   0,  54,   0,   0,   6, 
-     18,   0,  16,   0,   0,   0, 
-      0,   0,  26, 128,  32,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,  54,   0,   0,   7, 
-     34,  32,  16,   0,   0,   0, 
-      0,   0,  10,  48,  32,   4, 
-      0,   0,   0,   0,  10,   0, 
-     16,   0,   0,   0,   0,   0, 
-     54,   0,   0,   6,  18,   0, 
-     16,   0,   0,   0,   0,   0, 
-     42, 128,  32,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-     54,   0,   0,   7,  66,  32, 
-     16,   0,   0,   0,   0,   0, 
-     10,  48,  32,   4,   0,   0, 
-      0,   0,  10,   0,  16,   0, 
-      0,   0,   0,   0,  54,   0, 
-      0,   6,  18,   0,  16,   0, 
-      0,   0,   0,   0,  58, 128, 
-     32,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,  54,   0, 
-      0,   7, 130,  32,  16,   0, 
-      0,   0,   0,   0,  10,  48, 
-     32,   4,   0,   0,   0,   0, 
-     10,   0,  16,   0,   0,   0, 
-      0,   0,  62,   0,   0,   1, 
-     83,  84,  65,  84, 116,   0, 
-      0,   0,  16,   0,   0,   0, 
-      1,   0,   0,   0,   0,   0, 
-      0,   0,   2,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      1,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      6,   0,   0,   0,  10,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   1,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      4,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0
-};
+#if 0
+//
+// Generated by Microsoft (R) HLSL Shader Compiler 6.3.9600.16384
+//
+//
+// Buffer Definitions: 
+//
+// cbuffer SwizzleProperties
+// {
+//
+//   uint4 SwizzleIndices;              // Offset:    0 Size:    16
+//
+// }
+//
+//
+// Resource Bindings:
+//
+// Name                                 Type  Format         Dim Slot Elements
+// ------------------------------ ---------- ------- ----------- ---- --------
+// Sampler                           sampler      NA          NA    0        1
+// TextureF2D                        texture  float4          2d    0        1
+// SwizzleProperties                 cbuffer      NA          NA    0        1
+//
+//
+//
+// Input signature:
+//
+// Name                 Index   Mask Register SysValue  Format   Used
+// -------------------- ----- ------ -------- -------- ------- ------
+// SV_POSITION              0   xyzw        0      POS   float       
+// TEXCOORD                 0   xy          1     NONE   float   xy  
+//
+//
+// Output signature:
+//
+// Name                 Index   Mask Register SysValue  Format   Used
+// -------------------- ----- ------ -------- -------- ------- ------
+// SV_TARGET                0   xyzw        0   TARGET   float   xyzw
+//
+ps_4_0
+dcl_constantbuffer cb0[1], immediateIndexed
+dcl_sampler s0, mode_default
+dcl_resource_texture2d (float,float,float,float) t0
+dcl_input_ps linear v1.xy
+dcl_output o0.xyzw
+dcl_temps 1
+dcl_indexableTemp x0[6], 4
+sample r0.xyzw, v1.xyxx, t0.xyzw, s0
+mov x0[0].x, r0.x
+mov x0[1].x, r0.y
+mov x0[2].x, r0.z
+mov x0[3].x, r0.w
+mov x0[4].x, l(0)
+mov x0[5].x, l(1.000000)
+mov r0.x, cb0[0].x
+mov o0.x, x0[r0.x + 0].x
+mov r0.x, cb0[0].y
+mov o0.y, x0[r0.x + 0].x
+mov r0.x, cb0[0].z
+mov o0.z, x0[r0.x + 0].x
+mov r0.x, cb0[0].w
+mov o0.w, x0[r0.x + 0].x
+ret 
+// Approximately 16 instruction slots used
+#endif
+
+const BYTE g_PS_SwizzleF2D[] =
+{
+     68,  88,  66,  67, 187, 204, 
+    160,  39, 195, 158, 245,  72, 
+    125, 249,  70, 140, 158, 199, 
+    246, 220,   1,   0,   0,   0, 
+     96,   4,   0,   0,   5,   0, 
+      0,   0,  52,   0,   0,   0, 
+    100,   1,   0,   0, 188,   1, 
+      0,   0, 240,   1,   0,   0, 
+    228,   3,   0,   0,  82,  68, 
+     69,  70,  40,   1,   0,   0, 
+      1,   0,   0,   0, 164,   0, 
+      0,   0,   3,   0,   0,   0, 
+     28,   0,   0,   0,   0,   4, 
+    255, 255,   0,   1,   0,   0, 
+    244,   0,   0,   0, 124,   0, 
+      0,   0,   3,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   1,   0, 
+      0,   0,   1,   0,   0,   0, 
+    132,   0,   0,   0,   2,   0, 
+      0,   0,   5,   0,   0,   0, 
+      4,   0,   0,   0, 255, 255, 
+    255, 255,   0,   0,   0,   0, 
+      1,   0,   0,   0,  13,   0, 
+      0,   0, 143,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   1,   0,   0,   0, 
+      1,   0,   0,   0,  83,  97, 
+    109, 112, 108, 101, 114,   0, 
+     84, 101, 120, 116, 117, 114, 
+    101,  70,  50,  68,   0,  83, 
+    119, 105, 122, 122, 108, 101, 
+     80, 114, 111, 112, 101, 114, 
+    116, 105, 101, 115,   0, 171, 
+    171, 171, 143,   0,   0,   0, 
+      1,   0,   0,   0, 188,   0, 
+      0,   0,  16,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0, 212,   0,   0,   0, 
+      0,   0,   0,   0,  16,   0, 
+      0,   0,   2,   0,   0,   0, 
+    228,   0,   0,   0,   0,   0, 
+      0,   0,  83, 119, 105, 122, 
+    122, 108, 101,  73, 110, 100, 
+    105,  99, 101, 115,   0, 171, 
+      1,   0,  19,   0,   1,   0, 
+      4,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,  77, 105, 
+     99, 114, 111, 115, 111, 102, 
+    116,  32,  40,  82,  41,  32, 
+     72,  76,  83,  76,  32,  83, 
+    104,  97, 100, 101, 114,  32, 
+     67, 111, 109, 112, 105, 108, 
+    101, 114,  32,  54,  46,  51, 
+     46,  57,  54,  48,  48,  46, 
+     49,  54,  51,  56,  52,   0, 
+    171, 171,  73,  83,  71,  78, 
+     80,   0,   0,   0,   2,   0, 
+      0,   0,   8,   0,   0,   0, 
+     56,   0,   0,   0,   0,   0, 
+      0,   0,   1,   0,   0,   0, 
+      3,   0,   0,   0,   0,   0, 
+      0,   0,  15,   0,   0,   0, 
+     68,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      3,   0,   0,   0,   1,   0, 
+      0,   0,   3,   3,   0,   0, 
+     83,  86,  95,  80,  79,  83, 
+     73,  84,  73,  79,  78,   0, 
+     84,  69,  88,  67,  79,  79, 
+     82,  68,   0, 171, 171, 171, 
+     79,  83,  71,  78,  44,   0, 
+      0,   0,   1,   0,   0,   0, 
+      8,   0,   0,   0,  32,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   3,   0, 
+      0,   0,   0,   0,   0,   0, 
+     15,   0,   0,   0,  83,  86, 
+     95,  84,  65,  82,  71,  69, 
+     84,   0, 171, 171,  83,  72, 
+     68,  82, 236,   1,   0,   0, 
+     64,   0,   0,   0, 123,   0, 
+      0,   0,  89,   0,   0,   4, 
+     70, 142,  32,   0,   0,   0, 
+      0,   0,   1,   0,   0,   0, 
+     90,   0,   0,   3,   0,  96, 
+     16,   0,   0,   0,   0,   0, 
+     88,  24,   0,   4,   0, 112, 
+     16,   0,   0,   0,   0,   0, 
+     85,  85,   0,   0,  98,  16, 
+      0,   3,  50,  16,  16,   0, 
+      1,   0,   0,   0, 101,   0, 
+      0,   3, 242,  32,  16,   0, 
+      0,   0,   0,   0, 104,   0, 
+      0,   2,   1,   0,   0,   0, 
+    105,   0,   0,   4,   0,   0, 
+      0,   0,   6,   0,   0,   0, 
+      4,   0,   0,   0,  69,   0, 
+      0,   9, 242,   0,  16,   0, 
+      0,   0,   0,   0,  70,  16, 
+     16,   0,   1,   0,   0,   0, 
+     70, 126,  16,   0,   0,   0, 
+      0,   0,   0,  96,  16,   0, 
+      0,   0,   0,   0,  54,   0, 
+      0,   6,  18,  48,  32,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,  10,   0,  16,   0, 
+      0,   0,   0,   0,  54,   0, 
+      0,   6,  18,  48,  32,   0, 
+      0,   0,   0,   0,   1,   0, 
+      0,   0,  26,   0,  16,   0, 
+      0,   0,   0,   0,  54,   0, 
+      0,   6,  18,  48,  32,   0, 
+      0,   0,   0,   0,   2,   0, 
+      0,   0,  42,   0,  16,   0, 
+      0,   0,   0,   0,  54,   0, 
+      0,   6,  18,  48,  32,   0, 
+      0,   0,   0,   0,   3,   0, 
+      0,   0,  58,   0,  16,   0, 
+      0,   0,   0,   0,  54,   0, 
+      0,   6,  18,  48,  32,   0, 
+      0,   0,   0,   0,   4,   0, 
+      0,   0,   1,  64,   0,   0, 
+      0,   0,   0,   0,  54,   0, 
+      0,   6,  18,  48,  32,   0, 
+      0,   0,   0,   0,   5,   0, 
+      0,   0,   1,  64,   0,   0, 
+      0,   0, 128,  63,  54,   0, 
+      0,   6,  18,   0,  16,   0, 
+      0,   0,   0,   0,  10, 128, 
+     32,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,  54,   0, 
+      0,   7,  18,  32,  16,   0, 
+      0,   0,   0,   0,  10,  48, 
+     32,   4,   0,   0,   0,   0, 
+     10,   0,  16,   0,   0,   0, 
+      0,   0,  54,   0,   0,   6, 
+     18,   0,  16,   0,   0,   0, 
+      0,   0,  26, 128,  32,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,  54,   0,   0,   7, 
+     34,  32,  16,   0,   0,   0, 
+      0,   0,  10,  48,  32,   4, 
+      0,   0,   0,   0,  10,   0, 
+     16,   0,   0,   0,   0,   0, 
+     54,   0,   0,   6,  18,   0, 
+     16,   0,   0,   0,   0,   0, 
+     42, 128,  32,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+     54,   0,   0,   7,  66,  32, 
+     16,   0,   0,   0,   0,   0, 
+     10,  48,  32,   4,   0,   0, 
+      0,   0,  10,   0,  16,   0, 
+      0,   0,   0,   0,  54,   0, 
+      0,   6,  18,   0,  16,   0, 
+      0,   0,   0,   0,  58, 128, 
+     32,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,  54,   0, 
+      0,   7, 130,  32,  16,   0, 
+      0,   0,   0,   0,  10,  48, 
+     32,   4,   0,   0,   0,   0, 
+     10,   0,  16,   0,   0,   0, 
+      0,   0,  62,   0,   0,   1, 
+     83,  84,  65,  84, 116,   0, 
+      0,   0,  16,   0,   0,   0, 
+      1,   0,   0,   0,   0,   0, 
+      0,   0,   2,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      1,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      6,   0,   0,   0,  10,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   1,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      4,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0
+};
--- a/gfx/angle/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/swizzlef3dps.h
+++ b/gfx/angle/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/swizzlef3dps.h
@@ -1,265 +1,265 @@
-#if 0
-//
-// Generated by Microsoft (R) HLSL Shader Compiler 6.3.9600.16384
-//
-//
-// Buffer Definitions: 
-//
-// cbuffer SwizzleProperties
-// {
-//
-//   uint4 SwizzleIndices;              // Offset:    0 Size:    16
-//
-// }
-//
-//
-// Resource Bindings:
-//
-// Name                                 Type  Format         Dim Slot Elements
-// ------------------------------ ---------- ------- ----------- ---- --------
-// Sampler                           sampler      NA          NA    0        1
-// TextureF3D                        texture  float4          3d    0        1
-// SwizzleProperties                 cbuffer      NA          NA    0        1
-//
-//
-//
-// Input signature:
-//
-// Name                 Index   Mask Register SysValue  Format   Used
-// -------------------- ----- ------ -------- -------- ------- ------
-// SV_POSITION              0   xyzw        0      POS   float       
-// SV_RENDERTARGETARRAYINDEX     0   x           1  RTINDEX    uint       
-// TEXCOORD                 0   xyz         2     NONE   float   xyz 
-//
-//
-// Output signature:
-//
-// Name                 Index   Mask Register SysValue  Format   Used
-// -------------------- ----- ------ -------- -------- ------- ------
-// SV_TARGET                0   xyzw        0   TARGET   float   xyzw
-//
-ps_4_0
-dcl_constantbuffer cb0[1], immediateIndexed
-dcl_sampler s0, mode_default
-dcl_resource_texture3d (float,float,float,float) t0
-dcl_input_ps linear v2.xyz
-dcl_output o0.xyzw
-dcl_temps 1
-dcl_indexableTemp x0[6], 4
-sample r0.xyzw, v2.xyzx, t0.xyzw, s0
-mov x0[0].x, r0.x
-mov x0[1].x, r0.y
-mov x0[2].x, r0.z
-mov x0[3].x, r0.w
-mov x0[4].x, l(0)
-mov x0[5].x, l(1.000000)
-mov r0.x, cb0[0].x
-mov o0.x, x0[r0.x + 0].x
-mov r0.x, cb0[0].y
-mov o0.y, x0[r0.x + 0].x
-mov r0.x, cb0[0].z
-mov o0.z, x0[r0.x + 0].x
-mov r0.x, cb0[0].w
-mov o0.w, x0[r0.x + 0].x
-ret 
-// Approximately 16 instruction slots used
-#endif
-
-const BYTE g_PS_SwizzleF3D[] =
-{
-     68,  88,  66,  67, 238,  60, 
-     80,  74,  42,  65, 120, 165, 
-    177,  91, 253, 216,  89, 102, 
-      2, 228,   1,   0,   0,   0, 
-    144,   4,   0,   0,   5,   0, 
-      0,   0,  52,   0,   0,   0, 
-    100,   1,   0,   0, 236,   1, 
-      0,   0,  32,   2,   0,   0, 
-     20,   4,   0,   0,  82,  68, 
-     69,  70,  40,   1,   0,   0, 
-      1,   0,   0,   0, 164,   0, 
-      0,   0,   3,   0,   0,   0, 
-     28,   0,   0,   0,   0,   4, 
-    255, 255,   0,   1,   0,   0, 
-    244,   0,   0,   0, 124,   0, 
-      0,   0,   3,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   1,   0, 
-      0,   0,   1,   0,   0,   0, 
-    132,   0,   0,   0,   2,   0, 
-      0,   0,   5,   0,   0,   0, 
-      8,   0,   0,   0, 255, 255, 
-    255, 255,   0,   0,   0,   0, 
-      1,   0,   0,   0,  13,   0, 
-      0,   0, 143,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   1,   0,   0,   0, 
-      1,   0,   0,   0,  83,  97, 
-    109, 112, 108, 101, 114,   0, 
-     84, 101, 120, 116, 117, 114, 
-    101,  70,  51,  68,   0,  83, 
-    119, 105, 122, 122, 108, 101, 
-     80, 114, 111, 112, 101, 114, 
-    116, 105, 101, 115,   0, 171, 
-    171, 171, 143,   0,   0,   0, 
-      1,   0,   0,   0, 188,   0, 
-      0,   0,  16,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0, 212,   0,   0,   0, 
-      0,   0,   0,   0,  16,   0, 
-      0,   0,   2,   0,   0,   0, 
-    228,   0,   0,   0,   0,   0, 
-      0,   0,  83, 119, 105, 122, 
-    122, 108, 101,  73, 110, 100, 
-    105,  99, 101, 115,   0, 171, 
-      1,   0,  19,   0,   1,   0, 
-      4,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,  77, 105, 
-     99, 114, 111, 115, 111, 102, 
-    116,  32,  40,  82,  41,  32, 
-     72,  76,  83,  76,  32,  83, 
-    104,  97, 100, 101, 114,  32, 
-     67, 111, 109, 112, 105, 108, 
-    101, 114,  32,  54,  46,  51, 
-     46,  57,  54,  48,  48,  46, 
-     49,  54,  51,  56,  52,   0, 
-    171, 171,  73,  83,  71,  78, 
-    128,   0,   0,   0,   3,   0, 
-      0,   0,   8,   0,   0,   0, 
-     80,   0,   0,   0,   0,   0, 
-      0,   0,   1,   0,   0,   0, 
-      3,   0,   0,   0,   0,   0, 
-      0,   0,  15,   0,   0,   0, 
-     92,   0,   0,   0,   0,   0, 
-      0,   0,   4,   0,   0,   0, 
-      1,   0,   0,   0,   1,   0, 
-      0,   0,   1,   0,   0,   0, 
-    118,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      3,   0,   0,   0,   2,   0, 
-      0,   0,   7,   7,   0,   0, 
-     83,  86,  95,  80,  79,  83, 
-     73,  84,  73,  79,  78,   0, 
-     83,  86,  95,  82,  69,  78, 
-     68,  69,  82,  84,  65,  82, 
-     71,  69,  84,  65,  82,  82, 
-     65,  89,  73,  78,  68,  69, 
-     88,   0,  84,  69,  88,  67, 
-     79,  79,  82,  68,   0, 171, 
-     79,  83,  71,  78,  44,   0, 
-      0,   0,   1,   0,   0,   0, 
-      8,   0,   0,   0,  32,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   3,   0, 
-      0,   0,   0,   0,   0,   0, 
-     15,   0,   0,   0,  83,  86, 
-     95,  84,  65,  82,  71,  69, 
-     84,   0, 171, 171,  83,  72, 
-     68,  82, 236,   1,   0,   0, 
-     64,   0,   0,   0, 123,   0, 
-      0,   0,  89,   0,   0,   4, 
-     70, 142,  32,   0,   0,   0, 
-      0,   0,   1,   0,   0,   0, 
-     90,   0,   0,   3,   0,  96, 
-     16,   0,   0,   0,   0,   0, 
-     88,  40,   0,   4,   0, 112, 
-     16,   0,   0,   0,   0,   0, 
-     85,  85,   0,   0,  98,  16, 
-      0,   3, 114,  16,  16,   0, 
-      2,   0,   0,   0, 101,   0, 
-      0,   3, 242,  32,  16,   0, 
-      0,   0,   0,   0, 104,   0, 
-      0,   2,   1,   0,   0,   0, 
-    105,   0,   0,   4,   0,   0, 
-      0,   0,   6,   0,   0,   0, 
-      4,   0,   0,   0,  69,   0, 
-      0,   9, 242,   0,  16,   0, 
-      0,   0,   0,   0,  70,  18, 
-     16,   0,   2,   0,   0,   0, 
-     70, 126,  16,   0,   0,   0, 
-      0,   0,   0,  96,  16,   0, 
-      0,   0,   0,   0,  54,   0, 
-      0,   6,  18,  48,  32,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,  10,   0,  16,   0, 
-      0,   0,   0,   0,  54,   0, 
-      0,   6,  18,  48,  32,   0, 
-      0,   0,   0,   0,   1,   0, 
-      0,   0,  26,   0,  16,   0, 
-      0,   0,   0,   0,  54,   0, 
-      0,   6,  18,  48,  32,   0, 
-      0,   0,   0,   0,   2,   0, 
-      0,   0,  42,   0,  16,   0, 
-      0,   0,   0,   0,  54,   0, 
-      0,   6,  18,  48,  32,   0, 
-      0,   0,   0,   0,   3,   0, 
-      0,   0,  58,   0,  16,   0, 
-      0,   0,   0,   0,  54,   0, 
-      0,   6,  18,  48,  32,   0, 
-      0,   0,   0,   0,   4,   0, 
-      0,   0,   1,  64,   0,   0, 
-      0,   0,   0,   0,  54,   0, 
-      0,   6,  18,  48,  32,   0, 
-      0,   0,   0,   0,   5,   0, 
-      0,   0,   1,  64,   0,   0, 
-      0,   0, 128,  63,  54,   0, 
-      0,   6,  18,   0,  16,   0, 
-      0,   0,   0,   0,  10, 128, 
-     32,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,  54,   0, 
-      0,   7,  18,  32,  16,   0, 
-      0,   0,   0,   0,  10,  48, 
-     32,   4,   0,   0,   0,   0, 
-     10,   0,  16,   0,   0,   0, 
-      0,   0,  54,   0,   0,   6, 
-     18,   0,  16,   0,   0,   0, 
-      0,   0,  26, 128,  32,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,  54,   0,   0,   7, 
-     34,  32,  16,   0,   0,   0, 
-      0,   0,  10,  48,  32,   4, 
-      0,   0,   0,   0,  10,   0, 
-     16,   0,   0,   0,   0,   0, 
-     54,   0,   0,   6,  18,   0, 
-     16,   0,   0,   0,   0,   0, 
-     42, 128,  32,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-     54,   0,   0,   7,  66,  32, 
-     16,   0,   0,   0,   0,   0, 
-     10,  48,  32,   4,   0,   0, 
-      0,   0,  10,   0,  16,   0, 
-      0,   0,   0,   0,  54,   0, 
-      0,   6,  18,   0,  16,   0, 
-      0,   0,   0,   0,  58, 128, 
-     32,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,  54,   0, 
-      0,   7, 130,  32,  16,   0, 
-      0,   0,   0,   0,  10,  48, 
-     32,   4,   0,   0,   0,   0, 
-     10,   0,  16,   0,   0,   0, 
-      0,   0,  62,   0,   0,   1, 
-     83,  84,  65,  84, 116,   0, 
-      0,   0,  16,   0,   0,   0, 
-      1,   0,   0,   0,   0,   0, 
-      0,   0,   2,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      1,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      6,   0,   0,   0,  10,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   1,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      4,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0
-};
+#if 0
+//
+// Generated by Microsoft (R) HLSL Shader Compiler 6.3.9600.16384
+//
+//
+// Buffer Definitions: 
+//
+// cbuffer SwizzleProperties
+// {
+//
+//   uint4 SwizzleIndices;              // Offset:    0 Size:    16
+//
+// }
+//
+//
+// Resource Bindings:
+//
+// Name                                 Type  Format         Dim Slot Elements
+// ------------------------------ ---------- ------- ----------- ---- --------
+// Sampler                           sampler      NA          NA    0        1
+// TextureF3D                        texture  float4          3d    0        1
+// SwizzleProperties                 cbuffer      NA          NA    0        1
+//
+//
+//
+// Input signature:
+//
+// Name                 Index   Mask Register SysValue  Format   Used
+// -------------------- ----- ------ -------- -------- ------- ------
+// SV_POSITION              0   xyzw        0      POS   float       
+// SV_RENDERTARGETARRAYINDEX     0   x           1  RTINDEX    uint       
+// TEXCOORD                 0   xyz         2     NONE   float   xyz 
+//
+//
+// Output signature:
+//
+// Name                 Index   Mask Register SysValue  Format   Used
+// -------------------- ----- ------ -------- -------- ------- ------
+// SV_TARGET                0   xyzw        0   TARGET   float   xyzw
+//
+ps_4_0
+dcl_constantbuffer cb0[1], immediateIndexed
+dcl_sampler s0, mode_default
+dcl_resource_texture3d (float,float,float,float) t0
+dcl_input_ps linear v2.xyz
+dcl_output o0.xyzw
+dcl_temps 1
+dcl_indexableTemp x0[6], 4
+sample r0.xyzw, v2.xyzx, t0.xyzw, s0
+mov x0[0].x, r0.x
+mov x0[1].x, r0.y
+mov x0[2].x, r0.z
+mov x0[3].x, r0.w
+mov x0[4].x, l(0)
+mov x0[5].x, l(1.000000)
+mov r0.x, cb0[0].x
+mov o0.x, x0[r0.x + 0].x
+mov r0.x, cb0[0].y
+mov o0.y, x0[r0.x + 0].x
+mov r0.x, cb0[0].z
+mov o0.z, x0[r0.x + 0].x
+mov r0.x, cb0[0].w
+mov o0.w, x0[r0.x + 0].x
+ret 
+// Approximately 16 instruction slots used
+#endif
+
+const BYTE g_PS_SwizzleF3D[] =
+{
+     68,  88,  66,  67, 238,  60, 
+     80,  74,  42,  65, 120, 165, 
+    177,  91, 253, 216,  89, 102, 
+      2, 228,   1,   0,   0,   0, 
+    144,   4,   0,   0,   5,   0, 
+      0,   0,  52,   0,   0,   0, 
+    100,   1,   0,   0, 236,   1, 
+      0,   0,  32,   2,   0,   0, 
+     20,   4,   0,   0,  82,  68, 
+     69,  70,  40,   1,   0,   0, 
+      1,   0,   0,   0, 164,   0, 
+      0,   0,   3,   0,   0,   0, 
+     28,   0,   0,   0,   0,   4, 
+    255, 255,   0,   1,   0,   0, 
+    244,   0,   0,   0, 124,   0, 
+      0,   0,   3,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   1,   0, 
+      0,   0,   1,   0,   0,   0, 
+    132,   0,   0,   0,   2,   0, 
+      0,   0,   5,   0,   0,   0, 
+      8,   0,   0,   0, 255, 255, 
+    255, 255,   0,   0,   0,   0, 
+      1,   0,   0,   0,  13,   0, 
+      0,   0, 143,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   1,   0,   0,   0, 
+      1,   0,   0,   0,  83,  97, 
+    109, 112, 108, 101, 114,   0, 
+     84, 101, 120, 116, 117, 114, 
+    101,  70,  51,  68,   0,  83, 
+    119, 105, 122, 122, 108, 101, 
+     80, 114, 111, 112, 101, 114, 
+    116, 105, 101, 115,   0, 171, 
+    171, 171, 143,   0,   0,   0, 
+      1,   0,   0,   0, 188,   0, 
+      0,   0,  16,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0, 212,   0,   0,   0, 
+      0,   0,   0,   0,  16,   0, 
+      0,   0,   2,   0,   0,   0, 
+    228,   0,   0,   0,   0,   0, 
+      0,   0,  83, 119, 105, 122, 
+    122, 108, 101,  73, 110, 100, 
+    105,  99, 101, 115,   0, 171, 
+      1,   0,  19,   0,   1,   0, 
+      4,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,  77, 105, 
+     99, 114, 111, 115, 111, 102, 
+    116,  32,  40,  82,  41,  32, 
+     72,  76,  83,  76,  32,  83, 
+    104,  97, 100, 101, 114,  32, 
+     67, 111, 109, 112, 105, 108, 
+    101, 114,  32,  54,  46,  51, 
+     46,  57,  54,  48,  48,  46, 
+     49,  54,  51,  56,  52,   0, 
+    171, 171,  73,  83,  71,  78, 
+    128,   0,   0,   0,   3,   0, 
+      0,   0,   8,   0,   0,   0, 
+     80,   0,   0,   0,   0,   0, 
+      0,   0,   1,   0,   0,   0, 
+      3,   0,   0,   0,   0,   0, 
+      0,   0,  15,   0,   0,   0, 
+     92,   0,   0,   0,   0,   0, 
+      0,   0,   4,   0,   0,   0, 
+      1,   0,   0,   0,   1,   0, 
+      0,   0,   1,   0,   0,   0, 
+    118,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      3,   0,   0,   0,   2,   0, 
+      0,   0,   7,   7,   0,   0, 
+     83,  86,  95,  80,  79,  83, 
+     73,  84,  73,  79,  78,   0, 
+     83,  86,  95,  82,  69,  78, 
+     68,  69,  82,  84,  65,  82, 
+     71,  69,  84,  65,  82,  82, 
+     65,  89,  73,  78,  68,  69, 
+     88,   0,  84,  69,  88,  67, 
+     79,  79,  82,  68,   0, 171, 
+     79,  83,  71,  78,  44,   0, 
+      0,   0,   1,   0,   0,   0, 
+      8,   0,   0,   0,  32,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   3,   0, 
+      0,   0,   0,   0,   0,   0, 
+     15,   0,   0,   0,  83,  86, 
+     95,  84,  65,  82,  71,  69, 
+     84,   0, 171, 171,  83,  72, 
+     68,  82, 236,   1,   0,   0, 
+     64,   0,   0,   0, 123,   0, 
+      0,   0,  89,   0,   0,   4, 
+     70, 142,  32,   0,   0,   0, 
+      0,   0,   1,   0,   0,   0, 
+     90,   0,   0,   3,   0,  96, 
+     16,   0,   0,   0,   0,   0, 
+     88,  40,   0,   4,   0, 112, 
+     16,   0,   0,   0,   0,   0, 
+     85,  85,   0,   0,  98,  16, 
+      0,   3, 114,  16,  16,   0, 
+      2,   0,   0,   0, 101,   0, 
+      0,   3, 242,  32,  16,   0, 
+      0,   0,   0,   0, 104,   0, 
+      0,   2,   1,   0,   0,   0, 
+    105,   0,   0,   4,   0,   0, 
+      0,   0,   6,   0,   0,   0, 
+      4,   0,   0,   0,  69,   0, 
+      0,   9, 242,   0,  16,   0, 
+      0,   0,   0,   0,  70,  18, 
+     16,   0,   2,   0,   0,   0, 
+     70, 126,  16,   0,   0,   0, 
+      0,   0,   0,  96,  16,   0, 
+      0,   0,   0,   0,  54,   0, 
+      0,   6,  18,  48,  32,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,  10,   0,  16,   0, 
+      0,   0,   0,   0,  54,   0, 
+      0,   6,  18,  48,  32,   0, 
+      0,   0,   0,   0,   1,   0, 
+      0,   0,  26,   0,  16,   0, 
+      0,   0,   0,   0,  54,   0, 
+      0,   6,  18,  48,  32,   0, 
+      0,   0,   0,   0,   2,   0, 
+      0,   0,  42,   0,  16,   0, 
+      0,   0,   0,   0,  54,   0, 
+      0,   6,  18,  48,  32,   0, 
+      0,   0,   0,   0,   3,   0, 
+      0,   0,  58,   0,  16,   0, 
+      0,   0,   0,   0,  54,   0, 
+      0,   6,  18,  48,  32,   0, 
+      0,   0,   0,   0,   4,   0, 
+      0,   0,   1,  64,   0,   0, 
+      0,   0,   0,   0,  54,   0, 
+      0,   6,  18,  48,  32,   0, 
+      0,   0,   0,   0,   5,   0, 
+      0,   0,   1,  64,   0,   0, 
+      0,   0, 128,  63,  54,   0, 
+      0,   6,  18,   0,  16,   0, 
+      0,   0,   0,   0,  10, 128, 
+     32,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,  54,   0, 
+      0,   7,  18,  32,  16,   0, 
+      0,   0,   0,   0,  10,  48, 
+     32,   4,   0,   0,   0,   0, 
+     10,   0,  16,   0,   0,   0, 
+      0,   0,  54,   0,   0,   6, 
+     18,   0,  16,   0,   0,   0, 
+      0,   0,  26, 128,  32,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,  54,   0,   0,   7, 
+     34,  32,  16,   0,   0,   0, 
+      0,   0,  10,  48,  32,   4, 
+      0,   0,   0,   0,  10,   0, 
+     16,   0,   0,   0,   0,   0, 
+     54,   0,   0,   6,  18,   0, 
+     16,   0,   0,   0,   0,   0, 
+     42, 128,  32,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+     54,   0,   0,   7,  66,  32, 
+     16,   0,   0,   0,   0,   0, 
+     10,  48,  32,   4,   0,   0, 
+      0,   0,  10,   0,  16,   0, 
+      0,   0,   0,   0,  54,   0, 
+      0,   6,  18,   0,  16,   0, 
+      0,   0,   0,   0,  58, 128, 
+     32,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,  54,   0, 
+      0,   7, 130,  32,  16,   0, 
+      0,   0,   0,   0,  10,  48, 
+     32,   4,   0,   0,   0,   0, 
+     10,   0,  16,   0,   0,   0, 
+      0,   0,  62,   0,   0,   1, 
+     83,  84,  65,  84, 116,   0, 
+      0,   0,  16,   0,   0,   0, 
+      1,   0,   0,   0,   0,   0, 
+      0,   0,   2,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      1,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      6,   0,   0,   0,  10,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   1,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      4,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0
+};
--- a/gfx/angle/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/swizzlei2darrayps.h
+++ b/gfx/angle/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/swizzlei2darrayps.h
@@ -1,286 +1,286 @@
-#if 0
-//
-// Generated by Microsoft (R) HLSL Shader Compiler 6.3.9600.16384
-//
-//
-// Buffer Definitions: 
-//
-// cbuffer SwizzleProperties
-// {
-//
-//   uint4 SwizzleIndices;              // Offset:    0 Size:    16
-//
-// }
-//
-//
-// Resource Bindings:
-//
-// Name                                 Type  Format         Dim Slot Elements
-// ------------------------------ ---------- ------- ----------- ---- --------
-// TextureI2DArray                   texture   sint4     2darray    0        1
-// SwizzleProperties                 cbuffer      NA          NA    0        1
-//
-//
-//
-// Input signature:
-//
-// Name                 Index   Mask Register SysValue  Format   Used
-// -------------------- ----- ------ -------- -------- ------- ------
-// SV_POSITION              0   xyzw        0      POS   float       
-// SV_RENDERTARGETARRAYINDEX     0   x           1  RTINDEX    uint   x   
-// TEXCOORD                 0   xyz         2     NONE   float   xy  
-//
-//
-// Output signature:
-//
-// Name                 Index   Mask Register SysValue  Format   Used
-// -------------------- ----- ------ -------- -------- ------- ------
-// SV_TARGET                0   xyzw        0   TARGET     int   xyzw
-//
-ps_4_0
-dcl_constantbuffer cb0[1], immediateIndexed
-dcl_resource_texture2darray (sint,sint,sint,sint) t0
-dcl_input_ps_siv constant v1.x, rendertarget_array_index
-dcl_input_ps linear v2.xy
-dcl_output o0.xyzw
-dcl_temps 1
-dcl_indexableTemp x0[6], 4
-resinfo_uint r0.xyzw, l(0), t0.xyzw
-utof r0.xy, r0.xyxx
-mul r0.xy, r0.xyxx, v2.xyxx
-ftoi r0.xy, r0.xyxx
-mov r0.z, v1.x
-mov r0.w, l(0)
-ld r0.xyzw, r0.xyzw, t0.xyzw
-mov x0[0].x, r0.x
-mov x0[1].x, r0.y
-mov x0[2].x, r0.z
-mov x0[3].x, r0.w
-mov x0[4].x, l(0)
-mov x0[5].x, l(1)
-mov r0.x, cb0[0].x
-mov o0.x, x0[r0.x + 0].x
-mov r0.x, cb0[0].y
-mov o0.y, x0[r0.x + 0].x
-mov r0.x, cb0[0].z
-mov o0.z, x0[r0.x + 0].x
-mov r0.x, cb0[0].w
-mov o0.w, x0[r0.x + 0].x
-ret 
-// Approximately 22 instruction slots used
-#endif
-
-const BYTE g_PS_SwizzleI2DArray[] =
-{
-     68,  88,  66,  67,  85,  61, 
-     60,  36,  33, 245,  58, 113, 
-    238, 227, 230, 200, 136, 227, 
-     36, 193,   1,   0,   0,   0, 
-    240,   4,   0,   0,   5,   0, 
-      0,   0,  52,   0,   0,   0, 
-     64,   1,   0,   0, 200,   1, 
-      0,   0, 252,   1,   0,   0, 
-    116,   4,   0,   0,  82,  68, 
-     69,  70,   4,   1,   0,   0, 
-      1,   0,   0,   0, 128,   0, 
-      0,   0,   2,   0,   0,   0, 
-     28,   0,   0,   0,   0,   4, 
-    255, 255,   0,   1,   0,   0, 
-    208,   0,   0,   0,  92,   0, 
-      0,   0,   2,   0,   0,   0, 
-      3,   0,   0,   0,   5,   0, 
-      0,   0, 255, 255, 255, 255, 
-      0,   0,   0,   0,   1,   0, 
-      0,   0,  13,   0,   0,   0, 
-    108,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      1,   0,   0,   0,   1,   0, 
-      0,   0,  84, 101, 120, 116, 
-    117, 114, 101,  73,  50,  68, 
-     65, 114, 114,  97, 121,   0, 
-     83, 119, 105, 122, 122, 108, 
-    101,  80, 114, 111, 112, 101, 
-    114, 116, 105, 101, 115,   0, 
-    171, 171, 108,   0,   0,   0, 
-      1,   0,   0,   0, 152,   0, 
-      0,   0,  16,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0, 176,   0,   0,   0, 
-      0,   0,   0,   0,  16,   0, 
-      0,   0,   2,   0,   0,   0, 
-    192,   0,   0,   0,   0,   0, 
-      0,   0,  83, 119, 105, 122, 
-    122, 108, 101,  73, 110, 100, 
-    105,  99, 101, 115,   0, 171, 
-      1,   0,  19,   0,   1,   0, 
-      4,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,  77, 105, 
-     99, 114, 111, 115, 111, 102, 
-    116,  32,  40,  82,  41,  32, 
-     72,  76,  83,  76,  32,  83, 
-    104,  97, 100, 101, 114,  32, 
-     67, 111, 109, 112, 105, 108, 
-    101, 114,  32,  54,  46,  51, 
-     46,  57,  54,  48,  48,  46, 
-     49,  54,  51,  56,  52,   0, 
-    171, 171,  73,  83,  71,  78, 
-    128,   0,   0,   0,   3,   0, 
-      0,   0,   8,   0,   0,   0, 
-     80,   0,   0,   0,   0,   0, 
-      0,   0,   1,   0,   0,   0, 
-      3,   0,   0,   0,   0,   0, 
-      0,   0,  15,   0,   0,   0, 
-     92,   0,   0,   0,   0,   0, 
-      0,   0,   4,   0,   0,   0, 
-      1,   0,   0,   0,   1,   0, 
-      0,   0,   1,   1,   0,   0, 
-    118,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      3,   0,   0,   0,   2,   0, 
-      0,   0,   7,   3,   0,   0, 
-     83,  86,  95,  80,  79,  83, 
-     73,  84,  73,  79,  78,   0, 
-     83,  86,  95,  82,  69,  78, 
-     68,  69,  82,  84,  65,  82, 
-     71,  69,  84,  65,  82,  82, 
-     65,  89,  73,  78,  68,  69, 
-     88,   0,  84,  69,  88,  67, 
-     79,  79,  82,  68,   0, 171, 
-     79,  83,  71,  78,  44,   0, 
-      0,   0,   1,   0,   0,   0, 
-      8,   0,   0,   0,  32,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   2,   0, 
-      0,   0,   0,   0,   0,   0, 
-     15,   0,   0,   0,  83,  86, 
-     95,  84,  65,  82,  71,  69, 
-     84,   0, 171, 171,  83,  72, 
-     68,  82, 112,   2,   0,   0, 
-     64,   0,   0,   0, 156,   0, 
-      0,   0,  89,   0,   0,   4, 
-     70, 142,  32,   0,   0,   0, 
-      0,   0,   1,   0,   0,   0, 
-     88,  64,   0,   4,   0, 112, 
-     16,   0,   0,   0,   0,   0, 
-     51,  51,   0,   0, 100,   8, 
-      0,   4,  18,  16,  16,   0, 
-      1,   0,   0,   0,   4,   0, 
-      0,   0,  98,  16,   0,   3, 
-     50,  16,  16,   0,   2,   0, 
-      0,   0, 101,   0,   0,   3, 
-    242,  32,  16,   0,   0,   0, 
-      0,   0, 104,   0,   0,   2, 
-      1,   0,   0,   0, 105,   0, 
-      0,   4,   0,   0,   0,   0, 
-      6,   0,   0,   0,   4,   0, 
-      0,   0,  61,  16,   0,   7, 
-    242,   0,  16,   0,   0,   0, 
-      0,   0,   1,  64,   0,   0, 
-      0,   0,   0,   0,  70, 126, 
-     16,   0,   0,   0,   0,   0, 
-     86,   0,   0,   5,  50,   0, 
-     16,   0,   0,   0,   0,   0, 
-     70,   0,  16,   0,   0,   0, 
-      0,   0,  56,   0,   0,   7, 
-     50,   0,  16,   0,   0,   0, 
-      0,   0,  70,   0,  16,   0, 
-      0,   0,   0,   0,  70,  16, 
-     16,   0,   2,   0,   0,   0, 
-     27,   0,   0,   5,  50,   0, 
-     16,   0,   0,   0,   0,   0, 
-     70,   0,  16,   0,   0,   0, 
-      0,   0,  54,   0,   0,   5, 
-     66,   0,  16,   0,   0,   0, 
-      0,   0,  10,  16,  16,   0, 
-      1,   0,   0,   0,  54,   0, 
-      0,   5, 130,   0,  16,   0, 
-      0,   0,   0,   0,   1,  64, 
-      0,   0,   0,   0,   0,   0, 
-     45,   0,   0,   7, 242,   0, 
-     16,   0,   0,   0,   0,   0, 
-     70,  14,  16,   0,   0,   0, 
-      0,   0,  70, 126,  16,   0, 
-      0,   0,   0,   0,  54,   0, 
-      0,   6,  18,  48,  32,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,  10,   0,  16,   0, 
-      0,   0,   0,   0,  54,   0, 
-      0,   6,  18,  48,  32,   0, 
-      0,   0,   0,   0,   1,   0, 
-      0,   0,  26,   0,  16,   0, 
-      0,   0,   0,   0,  54,   0, 
-      0,   6,  18,  48,  32,   0, 
-      0,   0,   0,   0,   2,   0, 
-      0,   0,  42,   0,  16,   0, 
-      0,   0,   0,   0,  54,   0, 
-      0,   6,  18,  48,  32,   0, 
-      0,   0,   0,   0,   3,   0, 
-      0,   0,  58,   0,  16,   0, 
-      0,   0,   0,   0,  54,   0, 
-      0,   6,  18,  48,  32,   0, 
-      0,   0,   0,   0,   4,   0, 
-      0,   0,   1,  64,   0,   0, 
-      0,   0,   0,   0,  54,   0, 
-      0,   6,  18,  48,  32,   0, 
-      0,   0,   0,   0,   5,   0, 
-      0,   0,   1,  64,   0,   0, 
-      1,   0,   0,   0,  54,   0, 
-      0,   6,  18,   0,  16,   0, 
-      0,   0,   0,   0,  10, 128, 
-     32,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,  54,   0, 
-      0,   7,  18,  32,  16,   0, 
-      0,   0,   0,   0,  10,  48, 
-     32,   4,   0,   0,   0,   0, 
-     10,   0,  16,   0,   0,   0, 
-      0,   0,  54,   0,   0,   6, 
-     18,   0,  16,   0,   0,   0, 
-      0,   0,  26, 128,  32,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,  54,   0,   0,   7, 
-     34,  32,  16,   0,   0,   0, 
-      0,   0,  10,  48,  32,   4, 
-      0,   0,   0,   0,  10,   0, 
-     16,   0,   0,   0,   0,   0, 
-     54,   0,   0,   6,  18,   0, 
-     16,   0,   0,   0,   0,   0, 
-     42, 128,  32,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-     54,   0,   0,   7,  66,  32, 
-     16,   0,   0,   0,   0,   0, 
-     10,  48,  32,   4,   0,   0, 
-      0,   0,  10,   0,  16,   0, 
-      0,   0,   0,   0,  54,   0, 
-      0,   6,  18,   0,  16,   0, 
-      0,   0,   0,   0,  58, 128, 
-     32,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,  54,   0, 
-      0,   7, 130,  32,  16,   0, 
-      0,   0,   0,   0,  10,  48, 
-     32,   4,   0,   0,   0,   0, 
-     10,   0,  16,   0,   0,   0, 
-      0,   0,  62,   0,   0,   1, 
-     83,  84,  65,  84, 116,   0, 
-      0,   0,  22,   0,   0,   0, 
-      1,   0,   0,   0,   0,   0, 
-      0,   0,   3,   0,   0,   0, 
-      1,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      1,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      6,   0,   0,   0,  10,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   1,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      6,   0,   0,   0,   0,   0, 
-      0,   0,   2,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0
-};
+#if 0
+//
+// Generated by Microsoft (R) HLSL Shader Compiler 6.3.9600.16384
+//
+//
+// Buffer Definitions: 
+//
+// cbuffer SwizzleProperties
+// {
+//
+//   uint4 SwizzleIndices;              // Offset:    0 Size:    16
+//
+// }
+//
+//
+// Resource Bindings:
+//
+// Name                                 Type  Format         Dim Slot Elements
+// ------------------------------ ---------- ------- ----------- ---- --------
+// TextureI2DArray                   texture   sint4     2darray    0        1
+// SwizzleProperties                 cbuffer      NA          NA    0        1
+//
+//
+//
+// Input signature:
+//
+// Name                 Index   Mask Register SysValue  Format   Used
+// -------------------- ----- ------ -------- -------- ------- ------
+// SV_POSITION              0   xyzw        0      POS   float       
+// SV_RENDERTARGETARRAYINDEX     0   x           1  RTINDEX    uint   x   
+// TEXCOORD                 0   xyz         2     NONE   float   xy  
+//
+//
+// Output signature:
+//
+// Name                 Index   Mask Register SysValue  Format   Used
+// -------------------- ----- ------ -------- -------- ------- ------
+// SV_TARGET                0   xyzw        0   TARGET     int   xyzw
+//
+ps_4_0
+dcl_constantbuffer cb0[1], immediateIndexed
+dcl_resource_texture2darray (sint,sint,sint,sint) t0
+dcl_input_ps_siv constant v1.x, rendertarget_array_index
+dcl_input_ps linear v2.xy
+dcl_output o0.xyzw
+dcl_temps 1
+dcl_indexableTemp x0[6], 4
+resinfo_uint r0.xyzw, l(0), t0.xyzw
+utof r0.xy, r0.xyxx
+mul r0.xy, r0.xyxx, v2.xyxx
+ftoi r0.xy, r0.xyxx
+mov r0.z, v1.x
+mov r0.w, l(0)
+ld r0.xyzw, r0.xyzw, t0.xyzw
+mov x0[0].x, r0.x
+mov x0[1].x, r0.y
+mov x0[2].x, r0.z
+mov x0[3].x, r0.w
+mov x0[4].x, l(0)
+mov x0[5].x, l(1)
+mov r0.x, cb0[0].x
+mov o0.x, x0[r0.x + 0].x
+mov r0.x, cb0[0].y
+mov o0.y, x0[r0.x + 0].x
+mov r0.x, cb0[0].z
+mov o0.z, x0[r0.x + 0].x
+mov r0.x, cb0[0].w
+mov o0.w, x0[r0.x + 0].x
+ret 
+// Approximately 22 instruction slots used
+#endif
+
+const BYTE g_PS_SwizzleI2DArray[] =
+{
+     68,  88,  66,  67,  85,  61, 
+     60,  36,  33, 245,  58, 113, 
+    238, 227, 230, 200, 136, 227, 
+     36, 193,   1,   0,   0,   0, 
+    240,   4,   0,   0,   5,   0, 
+      0,   0,  52,   0,   0,   0, 
+     64,   1,   0,   0, 200,   1, 
+      0,   0, 252,   1,   0,   0, 
+    116,   4,   0,   0,  82,  68, 
+     69,  70,   4,   1,   0,   0, 
+      1,   0,   0,   0, 128,   0, 
+      0,   0,   2,   0,   0,   0, 
+     28,   0,   0,   0,   0,   4, 
+    255, 255,   0,   1,   0,   0, 
+    208,   0,   0,   0,  92,   0, 
+      0,   0,   2,   0,   0,   0, 
+      3,   0,   0,   0,   5,   0, 
+      0,   0, 255, 255, 255, 255, 
+      0,   0,   0,   0,   1,   0, 
+      0,   0,  13,   0,   0,   0, 
+    108,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      1,   0,   0,   0,   1,   0, 
+      0,   0,  84, 101, 120, 116, 
+    117, 114, 101,  73,  50,  68, 
+     65, 114, 114,  97, 121,   0, 
+     83, 119, 105, 122, 122, 108, 
+    101,  80, 114, 111, 112, 101, 
+    114, 116, 105, 101, 115,   0, 
+    171, 171, 108,   0,   0,   0, 
+      1,   0,   0,   0, 152,   0, 
+      0,   0,  16,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0, 176,   0,   0,   0, 
+      0,   0,   0,   0,  16,   0, 
+      0,   0,   2,   0,   0,   0, 
+    192,   0,   0,   0,   0,   0, 
+      0,   0,  83, 119, 105, 122, 
+    122, 108, 101,  73, 110, 100, 
+    105,  99, 101, 115,   0, 171, 
+      1,   0,  19,   0,   1,   0, 
+      4,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,  77, 105, 
+     99, 114, 111, 115, 111, 102, 
+    116,  32,  40,  82,  41,  32, 
+     72,  76,  83,  76,  32,  83, 
+    104,  97, 100, 101, 114,  32, 
+     67, 111, 109, 112, 105, 108, 
+    101, 114,  32,  54,  46,  51, 
+     46,  57,  54,  48,  48,  46, 
+     49,  54,  51,  56,  52,   0, 
+    171, 171,  73,  83,  71,  78, 
+    128,   0,   0,   0,   3,   0, 
+      0,   0,   8,   0,   0,   0, 
+     80,   0,   0,   0,   0,   0, 
+      0,   0,   1,   0,   0,   0, 
+      3,   0,   0,   0,   0,   0, 
+      0,   0,  15,   0,   0,   0, 
+     92,   0,   0,   0,   0,   0, 
+      0,   0,   4,   0,   0,   0, 
+      1,   0,   0,   0,   1,   0, 
+      0,   0,   1,   1,   0,   0, 
+    118,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      3,   0,   0,   0,   2,   0, 
+      0,   0,   7,   3,   0,   0, 
+     83,  86,  95,  80,  79,  83, 
+     73,  84,  73,  79,  78,   0, 
+     83,  86,  95,  82,  69,  78, 
+     68,  69,  82,  84,  65,  82, 
+     71,  69,  84,  65,  82,  82, 
+     65,  89,  73,  78,  68,  69, 
+     88,   0,  84,  69,  88,  67, 
+     79,  79,  82,  68,   0, 171, 
+     79,  83,  71,  78,  44,   0, 
+      0,   0,   1,   0,   0,   0, 
+      8,   0,   0,   0,  32,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   2,   0, 
+      0,   0,   0,   0,   0,   0, 
+     15,   0,   0,   0,  83,  86, 
+     95,  84,  65,  82,  71,  69, 
+     84,   0, 171, 171,  83,  72, 
+     68,  82, 112,   2,   0,   0, 
+     64,   0,   0,   0, 156,   0, 
+      0,   0,  89,   0,   0,   4, 
+     70, 142,  32,   0,   0,   0, 
+      0,   0,   1,   0,   0,   0, 
+     88,  64,   0,   4,   0, 112, 
+     16,   0,   0,   0,   0,   0, 
+     51,  51,   0,   0, 100,   8, 
+      0,   4,  18,  16,  16,   0, 
+      1,   0,   0,   0,   4,   0, 
+      0,   0,  98,  16,   0,   3, 
+     50,  16,  16,   0,   2,   0, 
+      0,   0, 101,   0,   0,   3, 
+    242,  32,  16,   0,   0,   0, 
+      0,   0, 104,   0,   0,   2, 
+      1,   0,   0,   0, 105,   0, 
+      0,   4,   0,   0,   0,   0, 
+      6,   0,   0,   0,   4,   0, 
+      0,   0,  61,  16,   0,   7, 
+    242,   0,  16,   0,   0,   0, 
+      0,   0,   1,  64,   0,   0, 
+      0,   0,   0,   0,  70, 126, 
+     16,   0,   0,   0,   0,   0, 
+     86,   0,   0,   5,  50,   0, 
+     16,   0,   0,   0,   0,   0, 
+     70,   0,  16,   0,   0,   0, 
+      0,   0,  56,   0,   0,   7, 
+     50,   0,  16,   0,   0,   0, 
+      0,   0,  70,   0,  16,   0, 
+      0,   0,   0,   0,  70,  16, 
+     16,   0,   2,   0,   0,   0, 
+     27,   0,   0,   5,  50,   0, 
+     16,   0,   0,   0,   0,   0, 
+     70,   0,  16,   0,   0,   0, 
+      0,   0,  54,   0,   0,   5, 
+     66,   0,  16,   0,   0,   0, 
+      0,   0,  10,  16,  16,   0, 
+      1,   0,   0,   0,  54,   0, 
+      0,   5, 130,   0,  16,   0, 
+      0,   0,   0,   0,   1,  64, 
+      0,   0,   0,   0,   0,   0, 
+     45,   0,   0,   7, 242,   0, 
+     16,   0,   0,   0,   0,   0, 
+     70,  14,  16,   0,   0,   0, 
+      0,   0,  70, 126,  16,   0, 
+      0,   0,   0,   0,  54,   0, 
+      0,   6,  18,  48,  32,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,  10,   0,  16,   0, 
+      0,   0,   0,   0,  54,   0, 
+      0,   6,  18,  48,  32,   0, 
+      0,   0,   0,   0,   1,   0, 
+      0,   0,  26,   0,  16,   0, 
+      0,   0,   0,   0,  54,   0, 
+      0,   6,  18,  48,  32,   0, 
+      0,   0,   0,   0,   2,   0, 
+      0,   0,  42,   0,  16,   0, 
+      0,   0,   0,   0,  54,   0, 
+      0,   6,  18,  48,  32,   0, 
+      0,   0,   0,   0,   3,   0, 
+      0,   0,  58,   0,  16,   0, 
+      0,   0,   0,   0,  54,   0, 
+      0,   6,  18,  48,  32,   0, 
+      0,   0,   0,   0,   4,   0, 
+      0,   0,   1,  64,   0,   0, 
+      0,   0,   0,   0,  54,   0, 
+      0,   6,  18,  48,  32,   0, 
+      0,   0,   0,   0,   5,   0, 
+      0,   0,   1,  64,   0,   0, 
+      1,   0,   0,   0,  54,   0, 
+      0,   6,  18,   0,  16,   0, 
+      0,   0,   0,   0,  10, 128, 
+     32,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,  54,   0, 
+      0,   7,  18,  32,  16,   0, 
+      0,   0,   0,   0,  10,  48, 
+     32,   4,   0,   0,   0,   0, 
+     10,   0,  16,   0,   0,   0, 
+      0,   0,  54,   0,   0,   6, 
+     18,   0,  16,   0,   0,   0, 
+      0,   0,  26, 128,  32,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,  54,   0,   0,   7, 
+     34,  32,  16,   0,   0,   0, 
+      0,   0,  10,  48,  32,   4, 
+      0,   0,   0,   0,  10,   0, 
+     16,   0,   0,   0,   0,   0, 
+     54,   0,   0,   6,  18,   0, 
+     16,   0,   0,   0,   0,   0, 
+     42, 128,  32,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+     54,   0,   0,   7,  66,  32, 
+     16,   0,   0,   0,   0,   0, 
+     10,  48,  32,   4,   0,   0, 
+      0,   0,  10,   0,  16,   0, 
+      0,   0,   0,   0,  54,   0, 
+      0,   6,  18,   0,  16,   0, 
+      0,   0,   0,   0,  58, 128, 
+     32,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,  54,   0, 
+      0,   7, 130,  32,  16,   0, 
+      0,   0,   0,   0,  10,  48, 
+     32,   4,   0,   0,   0,   0, 
+     10,   0,  16,   0,   0,   0, 
+      0,   0,  62,   0,   0,   1, 
+     83,  84,  65,  84, 116,   0, 
+      0,   0,  22,   0,   0,   0, 
+      1,   0,   0,   0,   0,   0, 
+      0,   0,   3,   0,   0,   0, 
+      1,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      1,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      6,   0,   0,   0,  10,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   1,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      6,   0,   0,   0,   0,   0, 
+      0,   0,   2,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0
+};
--- a/gfx/angle/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/swizzlei2dps.h
+++ b/gfx/angle/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/swizzlei2dps.h
@@ -1,270 +1,270 @@
-#if 0
-//
-// Generated by Microsoft (R) HLSL Shader Compiler 6.3.9600.16384
-//
-//
-// Buffer Definitions: 
-//
-// cbuffer SwizzleProperties
-// {
-//
-//   uint4 SwizzleIndices;              // Offset:    0 Size:    16
-//
-// }
-//
-//
-// Resource Bindings:
-//
-// Name                                 Type  Format         Dim Slot Elements
-// ------------------------------ ---------- ------- ----------- ---- --------
-// TextureI2D                        texture   sint4          2d    0        1
-// SwizzleProperties                 cbuffer      NA          NA    0        1
-//
-//
-//
-// Input signature:
-//
-// Name                 Index   Mask Register SysValue  Format   Used
-// -------------------- ----- ------ -------- -------- ------- ------
-// SV_POSITION              0   xyzw        0      POS   float       
-// TEXCOORD                 0   xy          1     NONE   float   xy  
-//
-//
-// Output signature:
-//
-// Name                 Index   Mask Register SysValue  Format   Used
-// -------------------- ----- ------ -------- -------- ------- ------
-// SV_TARGET                0   xyzw        0   TARGET     int   xyzw
-//
-ps_4_0
-dcl_constantbuffer cb0[1], immediateIndexed
-dcl_resource_texture2d (sint,sint,sint,sint) t0
-dcl_input_ps linear v1.xy
-dcl_output o0.xyzw
-dcl_temps 1
-dcl_indexableTemp x0[6], 4
-resinfo_uint r0.xyzw, l(0), t0.xyzw
-utof r0.xy, r0.xyxx
-mul r0.xy, r0.xyxx, v1.xyxx
-ftoi r0.xy, r0.xyxx
-mov r0.zw, l(0,0,0,0)
-ld r0.xyzw, r0.xyzw, t0.xyzw
-mov x0[0].x, r0.x
-mov x0[1].x, r0.y
-mov x0[2].x, r0.z
-mov x0[3].x, r0.w
-mov x0[4].x, l(0)
-mov x0[5].x, l(1)
-mov r0.x, cb0[0].x
-mov o0.x, x0[r0.x + 0].x
-mov r0.x, cb0[0].y
-mov o0.y, x0[r0.x + 0].x
-mov r0.x, cb0[0].z
-mov o0.z, x0[r0.x + 0].x
-mov r0.x, cb0[0].w
-mov o0.w, x0[r0.x + 0].x
-ret 
-// Approximately 21 instruction slots used
-#endif
-
-const BYTE g_PS_SwizzleI2D[] =
-{
-     68,  88,  66,  67, 180,  37, 
-     54,  19,  39, 134, 185, 230, 
-    234,  82, 113, 129,  69, 135, 
-    140,  27,   1,   0,   0,   0, 
-    164,   4,   0,   0,   5,   0, 
-      0,   0,  52,   0,   0,   0, 
-     60,   1,   0,   0, 148,   1, 
-      0,   0, 200,   1,   0,   0, 
-     40,   4,   0,   0,  82,  68, 
-     69,  70,   0,   1,   0,   0, 
-      1,   0,   0,   0, 124,   0, 
-      0,   0,   2,   0,   0,   0, 
-     28,   0,   0,   0,   0,   4, 
-    255, 255,   0,   1,   0,   0, 
-    204,   0,   0,   0,  92,   0, 
-      0,   0,   2,   0,   0,   0, 
-      3,   0,   0,   0,   4,   0, 
-      0,   0, 255, 255, 255, 255, 
-      0,   0,   0,   0,   1,   0, 
-      0,   0,  13,   0,   0,   0, 
-    103,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      1,   0,   0,   0,   1,   0, 
-      0,   0,  84, 101, 120, 116, 
-    117, 114, 101,  73,  50,  68, 
-      0,  83, 119, 105, 122, 122, 
-    108, 101,  80, 114, 111, 112, 
-    101, 114, 116, 105, 101, 115, 
-      0, 171, 171, 171, 103,   0, 
-      0,   0,   1,   0,   0,   0, 
-    148,   0,   0,   0,  16,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0, 172,   0, 
-      0,   0,   0,   0,   0,   0, 
-     16,   0,   0,   0,   2,   0, 
-      0,   0, 188,   0,   0,   0, 
-      0,   0,   0,   0,  83, 119, 
-    105, 122, 122, 108, 101,  73, 
-    110, 100, 105,  99, 101, 115, 
-      0, 171,   1,   0,  19,   0, 
-      1,   0,   4,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-     77, 105,  99, 114, 111, 115, 
-    111, 102, 116,  32,  40,  82, 
-     41,  32,  72,  76,  83,  76, 
-     32,  83, 104,  97, 100, 101, 
-    114,  32,  67, 111, 109, 112, 
-    105, 108, 101, 114,  32,  54, 
-     46,  51,  46,  57,  54,  48, 
-     48,  46,  49,  54,  51,  56, 
-     52,   0, 171, 171,  73,  83, 
-     71,  78,  80,   0,   0,   0, 
-      2,   0,   0,   0,   8,   0, 
-      0,   0,  56,   0,   0,   0, 
-      0,   0,   0,   0,   1,   0, 
-      0,   0,   3,   0,   0,   0, 
-      0,   0,   0,   0,  15,   0, 
-      0,   0,  68,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   3,   0,   0,   0, 
-      1,   0,   0,   0,   3,   3, 
-      0,   0,  83,  86,  95,  80, 
-     79,  83,  73,  84,  73,  79, 
-     78,   0,  84,  69,  88,  67, 
-     79,  79,  82,  68,   0, 171, 
-    171, 171,  79,  83,  71,  78, 
-     44,   0,   0,   0,   1,   0, 
-      0,   0,   8,   0,   0,   0, 
-     32,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      2,   0,   0,   0,   0,   0, 
-      0,   0,  15,   0,   0,   0, 
-     83,  86,  95,  84,  65,  82, 
-     71,  69,  84,   0, 171, 171, 
-     83,  72,  68,  82,  88,   2, 
-      0,   0,  64,   0,   0,   0, 
-    150,   0,   0,   0,  89,   0, 
-      0,   4,  70, 142,  32,   0, 
-      0,   0,   0,   0,   1,   0, 
-      0,   0,  88,  24,   0,   4, 
-      0, 112,  16,   0,   0,   0, 
-      0,   0,  51,  51,   0,   0, 
-     98,  16,   0,   3,  50,  16, 
-     16,   0,   1,   0,   0,   0, 
-    101,   0,   0,   3, 242,  32, 
-     16,   0,   0,   0,   0,   0, 
-    104,   0,   0,   2,   1,   0, 
-      0,   0, 105,   0,   0,   4, 
-      0,   0,   0,   0,   6,   0, 
-      0,   0,   4,   0,   0,   0, 
-     61,  16,   0,   7, 242,   0, 
-     16,   0,   0,   0,   0,   0, 
-      1,  64,   0,   0,   0,   0, 
-      0,   0,  70, 126,  16,   0, 
-      0,   0,   0,   0,  86,   0, 
-      0,   5,  50,   0,  16,   0, 
-      0,   0,   0,   0,  70,   0, 
-     16,   0,   0,   0,   0,   0, 
-     56,   0,   0,   7,  50,   0, 
-     16,   0,   0,   0,   0,   0, 
-     70,   0,  16,   0,   0,   0, 
-      0,   0,  70,  16,  16,   0, 
-      1,   0,   0,   0,  27,   0, 
-      0,   5,  50,   0,  16,   0, 
-      0,   0,   0,   0,  70,   0, 
-     16,   0,   0,   0,   0,   0, 
-     54,   0,   0,   8, 194,   0, 
-     16,   0,   0,   0,   0,   0, 
-      2,  64,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,  45,   0,   0,   7, 
-    242,   0,  16,   0,   0,   0, 
-      0,   0,  70,  14,  16,   0, 
-      0,   0,   0,   0,  70, 126, 
-     16,   0,   0,   0,   0,   0, 
-     54,   0,   0,   6,  18,  48, 
-     32,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,  10,   0, 
-     16,   0,   0,   0,   0,   0, 
-     54,   0,   0,   6,  18,  48, 
-     32,   0,   0,   0,   0,   0, 
-      1,   0,   0,   0,  26,   0, 
-     16,   0,   0,   0,   0,   0, 
-     54,   0,   0,   6,  18,  48, 
-     32,   0,   0,   0,   0,   0, 
-      2,   0,   0,   0,  42,   0, 
-     16,   0,   0,   0,   0,   0, 
-     54,   0,   0,   6,  18,  48, 
-     32,   0,   0,   0,   0,   0, 
-      3,   0,   0,   0,  58,   0, 
-     16,   0,   0,   0,   0,   0, 
-     54,   0,   0,   6,  18,  48, 
-     32,   0,   0,   0,   0,   0, 
-      4,   0,   0,   0,   1,  64, 
-      0,   0,   0,   0,   0,   0, 
-     54,   0,   0,   6,  18,  48, 
-     32,   0,   0,   0,   0,   0, 
-      5,   0,   0,   0,   1,  64, 
-      0,   0,   1,   0,   0,   0, 
-     54,   0,   0,   6,  18,   0, 
-     16,   0,   0,   0,   0,   0, 
-     10, 128,  32,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-     54,   0,   0,   7,  18,  32, 
-     16,   0,   0,   0,   0,   0, 
-     10,  48,  32,   4,   0,   0, 
-      0,   0,  10,   0,  16,   0, 
-      0,   0,   0,   0,  54,   0, 
-      0,   6,  18,   0,  16,   0, 
-      0,   0,   0,   0,  26, 128, 
-     32,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,  54,   0, 
-      0,   7,  34,  32,  16,   0, 
-      0,   0,   0,   0,  10,  48, 
-     32,   4,   0,   0,   0,   0, 
-     10,   0,  16,   0,   0,   0, 
-      0,   0,  54,   0,   0,   6, 
-     18,   0,  16,   0,   0,   0, 
-      0,   0,  42, 128,  32,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,  54,   0,   0,   7, 
-     66,  32,  16,   0,   0,   0, 
-      0,   0,  10,  48,  32,   4, 
-      0,   0,   0,   0,  10,   0, 
-     16,   0,   0,   0,   0,   0, 
-     54,   0,   0,   6,  18,   0, 
-     16,   0,   0,   0,   0,   0, 
-     58, 128,  32,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-     54,   0,   0,   7, 130,  32, 
-     16,   0,   0,   0,   0,   0, 
-     10,  48,  32,   4,   0,   0, 
-      0,   0,  10,   0,  16,   0, 
-      0,   0,   0,   0,  62,   0, 
-      0,   1,  83,  84,  65,  84, 
-    116,   0,   0,   0,  21,   0, 
-      0,   0,   1,   0,   0,   0, 
-      0,   0,   0,   0,   2,   0, 
-      0,   0,   1,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   1,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   6,   0,   0,   0, 
-     10,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   1,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   5,   0,   0,   0, 
-      0,   0,   0,   0,   2,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0
-};
+#if 0
+//
+// Generated by Microsoft (R) HLSL Shader Compiler 6.3.9600.16384
+//
+//
+// Buffer Definitions: 
+//
+// cbuffer SwizzleProperties
+// {
+//
+//   uint4 SwizzleIndices;              // Offset:    0 Size:    16
+//
+// }
+//
+//
+// Resource Bindings:
+//
+// Name                                 Type  Format         Dim Slot Elements
+// ------------------------------ ---------- ------- ----------- ---- --------
+// TextureI2D                        texture   sint4          2d    0        1
+// SwizzleProperties                 cbuffer      NA          NA    0        1
+//
+//
+//
+// Input signature:
+//
+// Name                 Index   Mask Register SysValue  Format   Used
+// -------------------- ----- ------ -------- -------- ------- ------
+// SV_POSITION              0   xyzw        0      POS   float       
+// TEXCOORD                 0   xy          1     NONE   float   xy  
+//
+//
+// Output signature:
+//
+// Name                 Index   Mask Register SysValue  Format   Used
+// -------------------- ----- ------ -------- -------- ------- ------
+// SV_TARGET                0   xyzw        0   TARGET     int   xyzw
+//
+ps_4_0
+dcl_constantbuffer cb0[1], immediateIndexed
+dcl_resource_texture2d (sint,sint,sint,sint) t0
+dcl_input_ps linear v1.xy
+dcl_output o0.xyzw
+dcl_temps 1
+dcl_indexableTemp x0[6], 4
+resinfo_uint r0.xyzw, l(0), t0.xyzw
+utof r0.xy, r0.xyxx
+mul r0.xy, r0.xyxx, v1.xyxx
+ftoi r0.xy, r0.xyxx
+mov r0.zw, l(0,0,0,0)
+ld r0.xyzw, r0.xyzw, t0.xyzw
+mov x0[0].x, r0.x
+mov x0[1].x, r0.y
+mov x0[2].x, r0.z
+mov x0[3].x, r0.w
+mov x0[4].x, l(0)
+mov x0[5].x, l(1)
+mov r0.x, cb0[0].x
+mov o0.x, x0[r0.x + 0].x
+mov r0.x, cb0[0].y
+mov o0.y, x0[r0.x + 0].x
+mov r0.x, cb0[0].z
+mov o0.z, x0[r0.x + 0].x
+mov r0.x, cb0[0].w
+mov o0.w, x0[r0.x + 0].x
+ret 
+// Approximately 21 instruction slots used
+#endif
+
+const BYTE g_PS_SwizzleI2D[] =
+{
+     68,  88,  66,  67, 180,  37, 
+     54,  19,  39, 134, 185, 230, 
+    234,  82, 113, 129,  69, 135, 
+    140,  27,   1,   0,   0,   0, 
+    164,   4,   0,   0,   5,   0, 
+      0,   0,  52,   0,   0,   0, 
+     60,   1,   0,   0, 148,   1, 
+      0,   0, 200,   1,   0,   0, 
+     40,   4,   0,   0,  82,  68, 
+     69,  70,   0,   1,   0,   0, 
+      1,   0,   0,   0, 124,   0, 
+      0,   0,   2,   0,   0,   0, 
+     28,   0,   0,   0,   0,   4, 
+    255, 255,   0,   1,   0,   0, 
+    204,   0,   0,   0,  92,   0, 
+      0,   0,   2,   0,   0,   0, 
+      3,   0,   0,   0,   4,   0, 
+      0,   0, 255, 255, 255, 255, 
+      0,   0,   0,   0,   1,   0, 
+      0,   0,  13,   0,   0,   0, 
+    103,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      1,   0,   0,   0,   1,   0, 
+      0,   0,  84, 101, 120, 116, 
+    117, 114, 101,  73,  50,  68, 
+      0,  83, 119, 105, 122, 122, 
+    108, 101,  80, 114, 111, 112, 
+    101, 114, 116, 105, 101, 115, 
+      0, 171, 171, 171, 103,   0, 
+      0,   0,   1,   0,   0,   0, 
+    148,   0,   0,   0,  16,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0, 172,   0, 
+      0,   0,   0,   0,   0,   0, 
+     16,   0,   0,   0,   2,   0, 
+      0,   0, 188,   0,   0,   0, 
+      0,   0,   0,   0,  83, 119, 
+    105, 122, 122, 108, 101,  73, 
+    110, 100, 105,  99, 101, 115, 
+      0, 171,   1,   0,  19,   0, 
+      1,   0,   4,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+     77, 105,  99, 114, 111, 115, 
+    111, 102, 116,  32,  40,  82, 
+     41,  32,  72,  76,  83,  76, 
+     32,  83, 104,  97, 100, 101, 
+    114,  32,  67, 111, 109, 112, 
+    105, 108, 101, 114,  32,  54, 
+     46,  51,  46,  57,  54,  48, 
+     48,  46,  49,  54,  51,  56, 
+     52,   0, 171, 171,  73,  83, 
+     71,  78,  80,   0,   0,   0, 
+      2,   0,   0,   0,   8,   0, 
+      0,   0,  56,   0,   0,   0, 
+      0,   0,   0,   0,   1,   0, 
+      0,   0,   3,   0,   0,   0, 
+      0,   0,   0,   0,  15,   0, 
+      0,   0,  68,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   3,   0,   0,   0, 
+      1,   0,   0,   0,   3,   3, 
+      0,   0,  83,  86,  95,  80, 
+     79,  83,  73,  84,  73,  79, 
+     78,   0,  84,  69,  88,  67, 
+     79,  79,  82,  68,   0, 171, 
+    171, 171,  79,  83,  71,  78, 
+     44,   0,   0,   0,   1,   0, 
+      0,   0,   8,   0,   0,   0, 
+     32,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      2,   0,   0,   0,   0,   0, 
+      0,   0,  15,   0,   0,   0, 
+     83,  86,  95,  84,  65,  82, 
+     71,  69,  84,   0, 171, 171, 
+     83,  72,  68,  82,  88,   2, 
+      0,   0,  64,   0,   0,   0, 
+    150,   0,   0,   0,  89,   0, 
+      0,   4,  70, 142,  32,   0, 
+      0,   0,   0,   0,   1,   0, 
+      0,   0,  88,  24,   0,   4, 
+      0, 112,  16,   0,   0,   0, 
+      0,   0,  51,  51,   0,   0, 
+     98,  16,   0,   3,  50,  16, 
+     16,   0,   1,   0,   0,   0, 
+    101,   0,   0,   3, 242,  32, 
+     16,   0,   0,   0,   0,   0, 
+    104,   0,   0,   2,   1,   0, 
+      0,   0, 105,   0,   0,   4, 
+      0,   0,   0,   0,   6,   0, 
+      0,   0,   4,   0,   0,   0, 
+     61,  16,   0,   7, 242,   0, 
+     16,   0,   0,   0,   0,   0, 
+      1,  64,   0,   0,   0,   0, 
+      0,   0,  70, 126,  16,   0, 
+      0,   0,   0,   0,  86,   0, 
+      0,   5,  50,   0,  16,   0, 
+      0,   0,   0,   0,  70,   0, 
+     16,   0,   0,   0,   0,   0, 
+     56,   0,   0,   7,  50,   0, 
+     16,   0,   0,   0,   0,   0, 
+     70,   0,  16,   0,   0,   0, 
+      0,   0,  70,  16,  16,   0, 
+      1,   0,   0,   0,  27,   0, 
+      0,   5,  50,   0,  16,   0, 
+      0,   0,   0,   0,  70,   0, 
+     16,   0,   0,   0,   0,   0, 
+     54,   0,   0,   8, 194,   0, 
+     16,   0,   0,   0,   0,   0, 
+      2,  64,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,  45,   0,   0,   7, 
+    242,   0,  16,   0,   0,   0, 
+      0,   0,  70,  14,  16,   0, 
+      0,   0,   0,   0,  70, 126, 
+     16,   0,   0,   0,   0,   0, 
+     54,   0,   0,   6,  18,  48, 
+     32,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,  10,   0, 
+     16,   0,   0,   0,   0,   0, 
+     54,   0,   0,   6,  18,  48, 
+     32,   0,   0,   0,   0,   0, 
+      1,   0,   0,   0,  26,   0, 
+     16,   0,   0,   0,   0,   0, 
+     54,   0,   0,   6,  18,  48, 
+     32,   0,   0,   0,   0,   0, 
+      2,   0,   0,   0,  42,   0, 
+     16,   0,   0,   0,   0,   0, 
+     54,   0,   0,   6,  18,  48, 
+     32,   0,   0,   0,   0,   0, 
+      3,   0,   0,   0,  58,   0, 
+     16,   0,   0,   0,   0,   0, 
+     54,   0,   0,   6,  18,  48, 
+     32,   0,   0,   0,   0,   0, 
+      4,   0,   0,   0,   1,  64, 
+      0,   0,   0,   0,   0,   0, 
+     54,   0,   0,   6,  18,  48, 
+     32,   0,   0,   0,   0,   0, 
+      5,   0,   0,   0,   1,  64, 
+      0,   0,   1,   0,   0,   0, 
+     54,   0,   0,   6,  18,   0, 
+     16,   0,   0,   0,   0,   0, 
+     10, 128,  32,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+     54,   0,   0,   7,  18,  32, 
+     16,   0,   0,   0,   0,   0, 
+     10,  48,  32,   4,   0,   0, 
+      0,   0,  10,   0,  16,   0, 
+      0,   0,   0,   0,  54,   0, 
+      0,   6,  18,   0,  16,   0, 
+      0,   0,   0,   0,  26, 128, 
+     32,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,  54,   0, 
+      0,   7,  34,  32,  16,   0, 
+      0,   0,   0,   0,  10,  48, 
+     32,   4,   0,   0,   0,   0, 
+     10,   0,  16,   0,   0,   0, 
+      0,   0,  54,   0,   0,   6, 
+     18,   0,  16,   0,   0,   0, 
+      0,   0,  42, 128,  32,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,  54,   0,   0,   7, 
+     66,  32,  16,   0,   0,   0, 
+      0,   0,  10,  48,  32,   4, 
+      0,   0,   0,   0,  10,   0, 
+     16,   0,   0,   0,   0,   0, 
+     54,   0,   0,   6,  18,   0, 
+     16,   0,   0,   0,   0,   0, 
+     58, 128,  32,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+     54,   0,   0,   7, 130,  32, 
+     16,   0,   0,   0,   0,   0, 
+     10,  48,  32,   4,   0,   0, 
+      0,   0,  10,   0,  16,   0, 
+      0,   0,   0,   0,  62,   0, 
+      0,   1,  83,  84,  65,  84, 
+    116,   0,   0,   0,  21,   0, 
+      0,   0,   1,   0,   0,   0, 
+      0,   0,   0,   0,   2,   0, 
+      0,   0,   1,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   1,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   6,   0,   0,   0, 
+     10,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   1,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   5,   0,   0,   0, 
+      0,   0,   0,   0,   2,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0
+};
--- a/gfx/angle/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/swizzlei3dps.h
+++ b/gfx/angle/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/swizzlei3dps.h
@@ -1,277 +1,277 @@
-#if 0
-//
-// Generated by Microsoft (R) HLSL Shader Compiler 6.3.9600.16384
-//
-//
-// Buffer Definitions: 
-//
-// cbuffer SwizzleProperties
-// {
-//
-//   uint4 SwizzleIndices;              // Offset:    0 Size:    16
-//
-// }
-//
-//
-// Resource Bindings:
-//
-// Name                                 Type  Format         Dim Slot Elements
-// ------------------------------ ---------- ------- ----------- ---- --------
-// TextureI3D                        texture   sint4          3d    0        1
-// SwizzleProperties                 cbuffer      NA          NA    0        1
-//
-//
-//
-// Input signature:
-//
-// Name                 Index   Mask Register SysValue  Format   Used
-// -------------------- ----- ------ -------- -------- ------- ------
-// SV_POSITION              0   xyzw        0      POS   float       
-// SV_RENDERTARGETARRAYINDEX     0   x           1  RTINDEX    uint       
-// TEXCOORD                 0   xyz         2     NONE   float   xyz 
-//
-//
-// Output signature:
-//
-// Name                 Index   Mask Register SysValue  Format   Used
-// -------------------- ----- ------ -------- -------- ------- ------
-// SV_TARGET                0   xyzw        0   TARGET     int   xyzw
-//
-ps_4_0
-dcl_constantbuffer cb0[1], immediateIndexed
-dcl_resource_texture3d (sint,sint,sint,sint) t0
-dcl_input_ps linear v2.xyz
-dcl_output o0.xyzw
-dcl_temps 1
-dcl_indexableTemp x0[6], 4
-resinfo_uint r0.xyzw, l(0), t0.xyzw
-utof r0.xyz, r0.xyzx
-mul r0.xyz, r0.xyzx, v2.xyzx
-ftoi r0.xyz, r0.xyzx
-mov r0.w, l(0)
-ld r0.xyzw, r0.xyzw, t0.xyzw
-mov x0[0].x, r0.x
-mov x0[1].x, r0.y
-mov x0[2].x, r0.z
-mov x0[3].x, r0.w
-mov x0[4].x, l(0)
-mov x0[5].x, l(1)
-mov r0.x, cb0[0].x
-mov o0.x, x0[r0.x + 0].x
-mov r0.x, cb0[0].y
-mov o0.y, x0[r0.x + 0].x
-mov r0.x, cb0[0].z
-mov o0.z, x0[r0.x + 0].x
-mov r0.x, cb0[0].w
-mov o0.w, x0[r0.x + 0].x
-ret 
-// Approximately 21 instruction slots used
-#endif
-
-const BYTE g_PS_SwizzleI3D[] =
-{
-     68,  88,  66,  67,  48,  84, 
-     97, 193, 216, 245, 101, 196, 
-    167,  81, 215, 168,  25, 164, 
-    144,  38,   1,   0,   0,   0, 
-    200,   4,   0,   0,   5,   0, 
-      0,   0,  52,   0,   0,   0, 
-     60,   1,   0,   0, 196,   1, 
-      0,   0, 248,   1,   0,   0, 
-     76,   4,   0,   0,  82,  68, 
-     69,  70,   0,   1,   0,   0, 
-      1,   0,   0,   0, 124,   0, 
-      0,   0,   2,   0,   0,   0, 
-     28,   0,   0,   0,   0,   4, 
-    255, 255,   0,   1,   0,   0, 
-    204,   0,   0,   0,  92,   0, 
-      0,   0,   2,   0,   0,   0, 
-      3,   0,   0,   0,   8,   0, 
-      0,   0, 255, 255, 255, 255, 
-      0,   0,   0,   0,   1,   0, 
-      0,   0,  13,   0,   0,   0, 
-    103,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      1,   0,   0,   0,   1,   0, 
-      0,   0,  84, 101, 120, 116, 
-    117, 114, 101,  73,  51,  68, 
-      0,  83, 119, 105, 122, 122, 
-    108, 101,  80, 114, 111, 112, 
-    101, 114, 116, 105, 101, 115, 
-      0, 171, 171, 171, 103,   0, 
-      0,   0,   1,   0,   0,   0, 
-    148,   0,   0,   0,  16,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0, 172,   0, 
-      0,   0,   0,   0,   0,   0, 
-     16,   0,   0,   0,   2,   0, 
-      0,   0, 188,   0,   0,   0, 
-      0,   0,   0,   0,  83, 119, 
-    105, 122, 122, 108, 101,  73, 
-    110, 100, 105,  99, 101, 115, 
-      0, 171,   1,   0,  19,   0, 
-      1,   0,   4,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-     77, 105,  99, 114, 111, 115, 
-    111, 102, 116,  32,  40,  82, 
-     41,  32,  72,  76,  83,  76, 
-     32,  83, 104,  97, 100, 101, 
-    114,  32,  67, 111, 109, 112, 
-    105, 108, 101, 114,  32,  54, 
-     46,  51,  46,  57,  54,  48, 
-     48,  46,  49,  54,  51,  56, 
-     52,   0, 171, 171,  73,  83, 
-     71,  78, 128,   0,   0,   0, 
-      3,   0,   0,   0,   8,   0, 
-      0,   0,  80,   0,   0,   0, 
-      0,   0,   0,   0,   1,   0, 
-      0,   0,   3,   0,   0,   0, 
-      0,   0,   0,   0,  15,   0, 
-      0,   0,  92,   0,   0,   0, 
-      0,   0,   0,   0,   4,   0, 
-      0,   0,   1,   0,   0,   0, 
-      1,   0,   0,   0,   1,   0, 
-      0,   0, 118,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   3,   0,   0,   0, 
-      2,   0,   0,   0,   7,   7, 
-      0,   0,  83,  86,  95,  80, 
-     79,  83,  73,  84,  73,  79, 
-     78,   0,  83,  86,  95,  82, 
-     69,  78,  68,  69,  82,  84, 
-     65,  82,  71,  69,  84,  65, 
-     82,  82,  65,  89,  73,  78, 
-     68,  69,  88,   0,  84,  69, 
-     88,  67,  79,  79,  82,  68, 
-      0, 171,  79,  83,  71,  78, 
-     44,   0,   0,   0,   1,   0, 
-      0,   0,   8,   0,   0,   0, 
-     32,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      2,   0,   0,   0,   0,   0, 
-      0,   0,  15,   0,   0,   0, 
-     83,  86,  95,  84,  65,  82, 
-     71,  69,  84,   0, 171, 171, 
-     83,  72,  68,  82,  76,   2, 
-      0,   0,  64,   0,   0,   0, 
-    147,   0,   0,   0,  89,   0, 
-      0,   4,  70, 142,  32,   0, 
-      0,   0,   0,   0,   1,   0, 
-      0,   0,  88,  40,   0,   4, 
-      0, 112,  16,   0,   0,   0, 
-      0,   0,  51,  51,   0,   0, 
-     98,  16,   0,   3, 114,  16, 
-     16,   0,   2,   0,   0,   0, 
-    101,   0,   0,   3, 242,  32, 
-     16,   0,   0,   0,   0,   0, 
-    104,   0,   0,   2,   1,   0, 
-      0,   0, 105,   0,   0,   4, 
-      0,   0,   0,   0,   6,   0, 
-      0,   0,   4,   0,   0,   0, 
-     61,  16,   0,   7, 242,   0, 
-     16,   0,   0,   0,   0,   0, 
-      1,  64,   0,   0,   0,   0, 
-      0,   0,  70, 126,  16,   0, 
-      0,   0,   0,   0,  86,   0, 
-      0,   5, 114,   0,  16,   0, 
-      0,   0,   0,   0,  70,   2, 
-     16,   0,   0,   0,   0,   0, 
-     56,   0,   0,   7, 114,   0, 
-     16,   0,   0,   0,   0,   0, 
-     70,   2,  16,   0,   0,   0, 
-      0,   0,  70,  18,  16,   0, 
-      2,   0,   0,   0,  27,   0, 
-      0,   5, 114,   0,  16,   0, 
-      0,   0,   0,   0,  70,   2, 
-     16,   0,   0,   0,   0,   0, 
-     54,   0,   0,   5, 130,   0, 
-     16,   0,   0,   0,   0,   0, 
-      1,  64,   0,   0,   0,   0, 
-      0,   0,  45,   0,   0,   7, 
-    242,   0,  16,   0,   0,   0, 
-      0,   0,  70,  14,  16,   0, 
-      0,   0,   0,   0,  70, 126, 
-     16,   0,   0,   0,   0,   0, 
-     54,   0,   0,   6,  18,  48, 
-     32,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,  10,   0, 
-     16,   0,   0,   0,   0,   0, 
-     54,   0,   0,   6,  18,  48, 
-     32,   0,   0,   0,   0,   0, 
-      1,   0,   0,   0,  26,   0, 
-     16,   0,   0,   0,   0,   0, 
-     54,   0,   0,   6,  18,  48, 
-     32,   0,   0,   0,   0,   0, 
-      2,   0,   0,   0,  42,   0, 
-     16,   0,   0,   0,   0,   0, 
-     54,   0,   0,   6,  18,  48, 
-     32,   0,   0,   0,   0,   0, 
-      3,   0,   0,   0,  58,   0, 
-     16,   0,   0,   0,   0,   0, 
-     54,   0,   0,   6,  18,  48, 
-     32,   0,   0,   0,   0,   0, 
-      4,   0,   0,   0,   1,  64, 
-      0,   0,   0,   0,   0,   0, 
-     54,   0,   0,   6,  18,  48, 
-     32,   0,   0,   0,   0,   0, 
-      5,   0,   0,   0,   1,  64, 
-      0,   0,   1,   0,   0,   0, 
-     54,   0,   0,   6,  18,   0, 
-     16,   0,   0,   0,   0,   0, 
-     10, 128,  32,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-     54,   0,   0,   7,  18,  32, 
-     16,   0,   0,   0,   0,   0, 
-     10,  48,  32,   4,   0,   0, 
-      0,   0,  10,   0,  16,   0, 
-      0,   0,   0,   0,  54,   0, 
-      0,   6,  18,   0,  16,   0, 
-      0,   0,   0,   0,  26, 128, 
-     32,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,  54,   0, 
-      0,   7,  34,  32,  16,   0, 
-      0,   0,   0,   0,  10,  48, 
-     32,   4,   0,   0,   0,   0, 
-     10,   0,  16,   0,   0,   0, 
-      0,   0,  54,   0,   0,   6, 
-     18,   0,  16,   0,   0,   0, 
-      0,   0,  42, 128,  32,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,  54,   0,   0,   7, 
-     66,  32,  16,   0,   0,   0, 
-      0,   0,  10,  48,  32,   4, 
-      0,   0,   0,   0,  10,   0, 
-     16,   0,   0,   0,   0,   0, 
-     54,   0,   0,   6,  18,   0, 
-     16,   0,   0,   0,   0,   0, 
-     58, 128,  32,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-     54,   0,   0,   7, 130,  32, 
-     16,   0,   0,   0,   0,   0, 
-     10,  48,  32,   4,   0,   0, 
-      0,   0,  10,   0,  16,   0, 
-      0,   0,   0,   0,  62,   0, 
-      0,   1,  83,  84,  65,  84, 
-    116,   0,   0,   0,  21,   0, 
-      0,   0,   1,   0,   0,   0, 
-      0,   0,   0,   0,   2,   0, 
-      0,   0,   1,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   1,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   6,   0,   0,   0, 
-     10,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   1,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   5,   0,   0,   0, 
-      0,   0,   0,   0,   2,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0
-};
+#if 0
+//
+// Generated by Microsoft (R) HLSL Shader Compiler 6.3.9600.16384
+//
+//
+// Buffer Definitions: 
+//
+// cbuffer SwizzleProperties
+// {
+//
+//   uint4 SwizzleIndices;              // Offset:    0 Size:    16
+//
+// }
+//
+//
+// Resource Bindings:
+//
+// Name                                 Type  Format         Dim Slot Elements
+// ------------------------------ ---------- ------- ----------- ---- --------
+// TextureI3D                        texture   sint4          3d    0        1
+// SwizzleProperties                 cbuffer      NA          NA    0        1
+//
+//
+//
+// Input signature:
+//
+// Name                 Index   Mask Register SysValue  Format   Used
+// -------------------- ----- ------ -------- -------- ------- ------
+// SV_POSITION              0   xyzw        0      POS   float       
+// SV_RENDERTARGETARRAYINDEX     0   x           1  RTINDEX    uint       
+// TEXCOORD                 0   xyz         2     NONE   float   xyz 
+//
+//
+// Output signature:
+//
+// Name                 Index   Mask Register SysValue  Format   Used
+// -------------------- ----- ------ -------- -------- ------- ------
+// SV_TARGET                0   xyzw        0   TARGET     int   xyzw
+//
+ps_4_0
+dcl_constantbuffer cb0[1], immediateIndexed
+dcl_resource_texture3d (sint,sint,sint,sint) t0
+dcl_input_ps linear v2.xyz
+dcl_output o0.xyzw
+dcl_temps 1
+dcl_indexableTemp x0[6], 4
+resinfo_uint r0.xyzw, l(0), t0.xyzw
+utof r0.xyz, r0.xyzx
+mul r0.xyz, r0.xyzx, v2.xyzx
+ftoi r0.xyz, r0.xyzx
+mov r0.w, l(0)
+ld r0.xyzw, r0.xyzw, t0.xyzw
+mov x0[0].x, r0.x
+mov x0[1].x, r0.y
+mov x0[2].x, r0.z
+mov x0[3].x, r0.w
+mov x0[4].x, l(0)
+mov x0[5].x, l(1)
+mov r0.x, cb0[0].x
+mov o0.x, x0[r0.x + 0].x
+mov r0.x, cb0[0].y
+mov o0.y, x0[r0.x + 0].x
+mov r0.x, cb0[0].z
+mov o0.z, x0[r0.x + 0].x
+mov r0.x, cb0[0].w
+mov o0.w, x0[r0.x + 0].x
+ret 
+// Approximately 21 instruction slots used
+#endif
+
+const BYTE g_PS_SwizzleI3D[] =
+{
+     68,  88,  66,  67,  48,  84, 
+     97, 193, 216, 245, 101, 196, 
+    167,  81, 215, 168,  25, 164, 
+    144,  38,   1,   0,   0,   0, 
+    200,   4,   0,   0,   5,   0, 
+      0,   0,  52,   0,   0,   0, 
+     60,   1,   0,   0, 196,   1, 
+      0,   0, 248,   1,   0,   0, 
+     76,   4,   0,   0,  82,  68, 
+     69,  70,   0,   1,   0,   0, 
+      1,   0,   0,   0, 124,   0, 
+      0,   0,   2,   0,   0,   0, 
+     28,   0,   0,   0,   0,   4, 
+    255, 255,   0,   1,   0,   0, 
+    204,   0,   0,   0,  92,   0, 
+      0,   0,   2,   0,   0,   0, 
+      3,   0,   0,   0,   8,   0, 
+      0,   0, 255, 255, 255, 255, 
+      0,   0,   0,   0,   1,   0, 
+      0,   0,  13,   0,   0,   0, 
+    103,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      1,   0,   0,   0,   1,   0, 
+      0,   0,  84, 101, 120, 116, 
+    117, 114, 101,  73,  51,  68, 
+      0,  83, 119, 105, 122, 122, 
+    108, 101,  80, 114, 111, 112, 
+    101, 114, 116, 105, 101, 115, 
+      0, 171, 171, 171, 103,   0, 
+      0,   0,   1,   0,   0,   0, 
+    148,   0,   0,   0,  16,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0, 172,   0, 
+      0,   0,   0,   0,   0,   0, 
+     16,   0,   0,   0,   2,   0, 
+      0,   0, 188,   0,   0,   0, 
+      0,   0,   0,   0,  83, 119, 
+    105, 122, 122, 108, 101,  73, 
+    110, 100, 105,  99, 101, 115, 
+      0, 171,   1,   0,  19,   0, 
+      1,   0,   4,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+     77, 105,  99, 114, 111, 115, 
+    111, 102, 116,  32,  40,  82, 
+     41,  32,  72,  76,  83,  76, 
+     32,  83, 104,  97, 100, 101, 
+    114,  32,  67, 111, 109, 112, 
+    105, 108, 101, 114,  32,  54, 
+     46,  51,  46,  57,  54,  48, 
+     48,  46,  49,  54,  51,  56, 
+     52,   0, 171, 171,  73,  83, 
+     71,  78, 128,   0,   0,   0, 
+      3,   0,   0,   0,   8,   0, 
+      0,   0,  80,   0,   0,   0, 
+      0,   0,   0,   0,   1,   0, 
+      0,   0,   3,   0,   0,   0, 
+      0,   0,   0,   0,  15,   0, 
+      0,   0,  92,   0,   0,   0, 
+      0,   0,   0,   0,   4,   0, 
+      0,   0,   1,   0,   0,   0, 
+      1,   0,   0,   0,   1,   0, 
+      0,   0, 118,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   3,   0,   0,   0, 
+      2,   0,   0,   0,   7,   7, 
+      0,   0,  83,  86,  95,  80, 
+     79,  83,  73,  84,  73,  79, 
+     78,   0,  83,  86,  95,  82, 
+     69,  78,  68,  69,  82,  84, 
+     65,  82,  71,  69,  84,  65, 
+     82,  82,  65,  89,  73,  78, 
+     68,  69,  88,   0,  84,  69, 
+     88,  67,  79,  79,  82,  68, 
+      0, 171,  79,  83,  71,  78, 
+     44,   0,   0,   0,   1,   0, 
+      0,   0,   8,   0,   0,   0, 
+     32,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      2,   0,   0,   0,   0,   0, 
+      0,   0,  15,   0,   0,   0, 
+     83,  86,  95,  84,  65,  82, 
+     71,  69,  84,   0, 171, 171, 
+     83,  72,  68,  82,  76,   2, 
+      0,   0,  64,   0,   0,   0, 
+    147,   0,   0,   0,  89,   0, 
+      0,   4,  70, 142,  32,   0, 
+      0,   0,   0,   0,   1,   0, 
+      0,   0,  88,  40,   0,   4, 
+      0, 112,  16,   0,   0,   0, 
+      0,   0,  51,  51,   0,   0, 
+     98,  16,   0,   3, 114,  16, 
+     16,   0,   2,   0,   0,   0, 
+    101,   0,   0,   3, 242,  32, 
+     16,   0,   0,   0,   0,   0, 
+    104,   0,   0,   2,   1,   0, 
+      0,   0, 105,   0,   0,   4, 
+      0,   0,   0,   0,   6,   0, 
+      0,   0,   4,   0,   0,   0, 
+     61,  16,   0,   7, 242,   0, 
+     16,   0,   0,   0,   0,   0, 
+      1,  64,   0,   0,   0,   0, 
+      0,   0,  70, 126,  16,   0, 
+      0,   0,   0,   0,  86,   0, 
+      0,   5, 114,   0,  16,   0, 
+      0,   0,   0,   0,  70,   2, 
+     16,   0,   0,   0,   0,   0, 
+     56,   0,   0,   7, 114,   0, 
+     16,   0,   0,   0,   0,   0, 
+     70,   2,  16,   0,   0,   0, 
+      0,   0,  70,  18,  16,   0, 
+      2,   0,   0,   0,  27,   0, 
+      0,   5, 114,   0,  16,   0, 
+      0,   0,   0,   0,  70,   2, 
+     16,   0,   0,   0,   0,   0, 
+     54,   0,   0,   5, 130,   0, 
+     16,   0,   0,   0,   0,   0, 
+      1,  64,   0,   0,   0,   0, 
+      0,   0,  45,   0,   0,   7, 
+    242,   0,  16,   0,   0,   0, 
+      0,   0,  70,  14,  16,   0, 
+      0,   0,   0,   0,  70, 126, 
+     16,   0,   0,   0,   0,   0, 
+     54,   0,   0,   6,  18,  48, 
+     32,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,  10,   0, 
+     16,   0,   0,   0,   0,   0, 
+     54,   0,   0,   6,  18,  48, 
+     32,   0,   0,   0,   0,   0, 
+      1,   0,   0,   0,  26,   0, 
+     16,   0,   0,   0,   0,   0, 
+     54,   0,   0,   6,  18,  48, 
+     32,   0,   0,   0,   0,   0, 
+      2,   0,   0,   0,  42,   0, 
+     16,   0,   0,   0,   0,   0, 
+     54,   0,   0,   6,  18,  48, 
+     32,   0,   0,   0,   0,   0, 
+      3,   0,   0,   0,  58,   0, 
+     16,   0,   0,   0,   0,   0, 
+     54,   0,   0,   6,  18,  48, 
+     32,   0,   0,   0,   0,   0, 
+      4,   0,   0,   0,   1,  64, 
+      0,   0,   0,   0,   0,   0, 
+     54,   0,   0,   6,  18,  48, 
+     32,   0,   0,   0,   0,   0, 
+      5,   0,   0,   0,   1,  64, 
+      0,   0,   1,   0,   0,   0, 
+     54,   0,   0,   6,  18,   0, 
+     16,   0,   0,   0,   0,   0, 
+     10, 128,  32,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+     54,   0,   0,   7,  18,  32, 
+     16,   0,   0,   0,   0,   0, 
+     10,  48,  32,   4,   0,   0, 
+      0,   0,  10,   0,  16,   0, 
+      0,   0,   0,   0,  54,   0, 
+      0,   6,  18,   0,  16,   0, 
+      0,   0,   0,   0,  26, 128, 
+     32,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,  54,   0, 
+      0,   7,  34,  32,  16,   0, 
+      0,   0,   0,   0,  10,  48, 
+     32,   4,   0,   0,   0,   0, 
+     10,   0,  16,   0,   0,   0, 
+      0,   0,  54,   0,   0,   6, 
+     18,   0,  16,   0,   0,   0, 
+      0,   0,  42, 128,  32,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,  54,   0,   0,   7, 
+     66,  32,  16,   0,   0,   0, 
+      0,   0,  10,  48,  32,   4, 
+      0,   0,   0,   0,  10,   0, 
+     16,   0,   0,   0,   0,   0, 
+     54,   0,   0,   6,  18,   0, 
+     16,   0,   0,   0,   0,   0, 
+     58, 128,  32,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+     54,   0,   0,   7, 130,  32, 
+     16,   0,   0,   0,   0,   0, 
+     10,  48,  32,   4,   0,   0, 
+      0,   0,  10,   0,  16,   0, 
+      0,   0,   0,   0,  62,   0, 
+      0,   1,  83,  84,  65,  84, 
+    116,   0,   0,   0,  21,   0, 
+      0,   0,   1,   0,   0,   0, 
+      0,   0,   0,   0,   2,   0, 
+      0,   0,   1,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   1,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   6,   0,   0,   0, 
+     10,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   1,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   5,   0,   0,   0, 
+      0,   0,   0,   0,   2,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0
+};
--- a/gfx/angle/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/swizzleui2darrayps.h
+++ b/gfx/angle/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/swizzleui2darrayps.h
@@ -1,286 +1,286 @@
-#if 0
-//
-// Generated by Microsoft (R) HLSL Shader Compiler 6.3.9600.16384
-//
-//
-// Buffer Definitions: 
-//
-// cbuffer SwizzleProperties
-// {
-//
-//   uint4 SwizzleIndices;              // Offset:    0 Size:    16
-//
-// }
-//
-//
-// Resource Bindings:
-//
-// Name                                 Type  Format         Dim Slot Elements
-// ------------------------------ ---------- ------- ----------- ---- --------
-// TextureUI2DArray                  texture   uint4     2darray    0        1
-// SwizzleProperties                 cbuffer      NA          NA    0        1
-//
-//
-//
-// Input signature:
-//
-// Name                 Index   Mask Register SysValue  Format   Used
-// -------------------- ----- ------ -------- -------- ------- ------
-// SV_POSITION              0   xyzw        0      POS   float       
-// SV_RENDERTARGETARRAYINDEX     0   x           1  RTINDEX    uint   x   
-// TEXCOORD                 0   xyz         2     NONE   float   xy  
-//
-//
-// Output signature:
-//
-// Name                 Index   Mask Register SysValue  Format   Used
-// -------------------- ----- ------ -------- -------- ------- ------
-// SV_TARGET                0   xyzw        0   TARGET    uint   xyzw
-//
-ps_4_0
-dcl_constantbuffer cb0[1], immediateIndexed
-dcl_resource_texture2darray (uint,uint,uint,uint) t0
-dcl_input_ps_siv constant v1.x, rendertarget_array_index
-dcl_input_ps linear v2.xy
-dcl_output o0.xyzw
-dcl_temps 1
-dcl_indexableTemp x0[6], 4
-resinfo_uint r0.xyzw, l(0), t0.xyzw
-utof r0.xy, r0.xyxx
-mul r0.xy, r0.xyxx, v2.xyxx
-ftoi r0.xy, r0.xyxx
-mov r0.z, v1.x
-mov r0.w, l(0)
-ld r0.xyzw, r0.xyzw, t0.xyzw
-mov x0[0].x, r0.x
-mov x0[1].x, r0.y
-mov x0[2].x, r0.z
-mov x0[3].x, r0.w
-mov x0[4].x, l(0)
-mov x0[5].x, l(1)
-mov r0.x, cb0[0].x
-mov o0.x, x0[r0.x + 0].x
-mov r0.x, cb0[0].y
-mov o0.y, x0[r0.x + 0].x
-mov r0.x, cb0[0].z
-mov o0.z, x0[r0.x + 0].x
-mov r0.x, cb0[0].w
-mov o0.w, x0[r0.x + 0].x
-ret 
-// Approximately 22 instruction slots used
-#endif
-
-const BYTE g_PS_SwizzleUI2DArray[] =
-{
-     68,  88,  66,  67,  15, 124, 
-    179,  49,  45,  69,  64, 249, 
-    216, 189, 135, 190,  71, 234, 
-     72,  20,   1,   0,   0,   0, 
-    240,   4,   0,   0,   5,   0, 
-      0,   0,  52,   0,   0,   0, 
-     64,   1,   0,   0, 200,   1, 
-      0,   0, 252,   1,   0,   0, 
-    116,   4,   0,   0,  82,  68, 
-     69,  70,   4,   1,   0,   0, 
-      1,   0,   0,   0, 128,   0, 
-      0,   0,   2,   0,   0,   0, 
-     28,   0,   0,   0,   0,   4, 
-    255, 255,   0,   1,   0,   0, 
-    208,   0,   0,   0,  92,   0, 
-      0,   0,   2,   0,   0,   0, 
-      4,   0,   0,   0,   5,   0, 
-      0,   0, 255, 255, 255, 255, 
-      0,   0,   0,   0,   1,   0, 
-      0,   0,  13,   0,   0,   0, 
-    109,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      1,   0,   0,   0,   1,   0, 
-      0,   0,  84, 101, 120, 116, 
-    117, 114, 101,  85,  73,  50, 
-     68,  65, 114, 114,  97, 121, 
-      0,  83, 119, 105, 122, 122, 
-    108, 101,  80, 114, 111, 112, 
-    101, 114, 116, 105, 101, 115, 
-      0, 171, 109,   0,   0,   0, 
-      1,   0,   0,   0, 152,   0, 
-      0,   0,  16,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0, 176,   0,   0,   0, 
-      0,   0,   0,   0,  16,   0, 
-      0,   0,   2,   0,   0,   0, 
-    192,   0,   0,   0,   0,   0, 
-      0,   0,  83, 119, 105, 122, 
-    122, 108, 101,  73, 110, 100, 
-    105,  99, 101, 115,   0, 171, 
-      1,   0,  19,   0,   1,   0, 
-      4,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,  77, 105, 
-     99, 114, 111, 115, 111, 102, 
-    116,  32,  40,  82,  41,  32, 
-     72,  76,  83,  76,  32,  83, 
-    104,  97, 100, 101, 114,  32, 
-     67, 111, 109, 112, 105, 108, 
-    101, 114,  32,  54,  46,  51, 
-     46,  57,  54,  48,  48,  46, 
-     49,  54,  51,  56,  52,   0, 
-    171, 171,  73,  83,  71,  78, 
-    128,   0,   0,   0,   3,   0, 
-      0,   0,   8,   0,   0,   0, 
-     80,   0,   0,   0,   0,   0, 
-      0,   0,   1,   0,   0,   0, 
-      3,   0,   0,   0,   0,   0, 
-      0,   0,  15,   0,   0,   0, 
-     92,   0,   0,   0,   0,   0, 
-      0,   0,   4,   0,   0,   0, 
-      1,   0,   0,   0,   1,   0, 
-      0,   0,   1,   1,   0,   0, 
-    118,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      3,   0,   0,   0,   2,   0, 
-      0,   0,   7,   3,   0,   0, 
-     83,  86,  95,  80,  79,  83, 
-     73,  84,  73,  79,  78,   0, 
-     83,  86,  95,  82,  69,  78, 
-     68,  69,  82,  84,  65,  82, 
-     71,  69,  84,  65,  82,  82, 
-     65,  89,  73,  78,  68,  69, 
-     88,   0,  84,  69,  88,  67, 
-     79,  79,  82,  68,   0, 171, 
-     79,  83,  71,  78,  44,   0, 
-      0,   0,   1,   0,   0,   0, 
-      8,   0,   0,   0,  32,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   1,   0, 
-      0,   0,   0,   0,   0,   0, 
-     15,   0,   0,   0,  83,  86, 
-     95,  84,  65,  82,  71,  69, 
-     84,   0, 171, 171,  83,  72, 
-     68,  82, 112,   2,   0,   0, 
-     64,   0,   0,   0, 156,   0, 
-      0,   0,  89,   0,   0,   4, 
-     70, 142,  32,   0,   0,   0, 
-      0,   0,   1,   0,   0,   0, 
-     88,  64,   0,   4,   0, 112, 
-     16,   0,   0,   0,   0,   0, 
-     68,  68,   0,   0, 100,   8, 
-      0,   4,  18,  16,  16,   0, 
-      1,   0,   0,   0,   4,   0, 
-      0,   0,  98,  16,   0,   3, 
-     50,  16,  16,   0,   2,   0, 
-      0,   0, 101,   0,   0,   3, 
-    242,  32,  16,   0,   0,   0, 
-      0,   0, 104,   0,   0,   2, 
-      1,   0,   0,   0, 105,   0, 
-      0,   4,   0,   0,   0,   0, 
-      6,   0,   0,   0,   4,   0, 
-      0,   0,  61,  16,   0,   7, 
-    242,   0,  16,   0,   0,   0, 
-      0,   0,   1,  64,   0,   0, 
-      0,   0,   0,   0,  70, 126, 
-     16,   0,   0,   0,   0,   0, 
-     86,   0,   0,   5,  50,   0, 
-     16,   0,   0,   0,   0,   0, 
-     70,   0,  16,   0,   0,   0, 
-      0,   0,  56,   0,   0,   7, 
-     50,   0,  16,   0,   0,   0, 
-      0,   0,  70,   0,  16,   0, 
-      0,   0,   0,   0,  70,  16, 
-     16,   0,   2,   0,   0,   0, 
-     27,   0,   0,   5,  50,   0, 
-     16,   0,   0,   0,   0,   0, 
-     70,   0,  16,   0,   0,   0, 
-      0,   0,  54,   0,   0,   5, 
-     66,   0,  16,   0,   0,   0, 
-      0,   0,  10,  16,  16,   0, 
-      1,   0,   0,   0,  54,   0, 
-      0,   5, 130,   0,  16,   0, 
-      0,   0,   0,   0,   1,  64, 
-      0,   0,   0,   0,   0,   0, 
-     45,   0,   0,   7, 242,   0, 
-     16,   0,   0,   0,   0,   0, 
-     70,  14,  16,   0,   0,   0, 
-      0,   0,  70, 126,  16,   0, 
-      0,   0,   0,   0,  54,   0, 
-      0,   6,  18,  48,  32,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,  10,   0,  16,   0, 
-      0,   0,   0,   0,  54,   0, 
-      0,   6,  18,  48,  32,   0, 
-      0,   0,   0,   0,   1,   0, 
-      0,   0,  26,   0,  16,   0, 
-      0,   0,   0,   0,  54,   0, 
-      0,   6,  18,  48,  32,   0, 
-      0,   0,   0,   0,   2,   0, 
-      0,   0,  42,   0,  16,   0, 
-      0,   0,   0,   0,  54,   0, 
-      0,   6,  18,  48,  32,   0, 
-      0,   0,   0,   0,   3,   0, 
-      0,   0,  58,   0,  16,   0, 
-      0,   0,   0,   0,  54,   0, 
-      0,   6,  18,  48,  32,   0, 
-      0,   0,   0,   0,   4,   0, 
-      0,   0,   1,  64,   0,   0, 
-      0,   0,   0,   0,  54,   0, 
-      0,   6,  18,  48,  32,   0, 
-      0,   0,   0,   0,   5,   0, 
-      0,   0,   1,  64,   0,   0, 
-      1,   0,   0,   0,  54,   0, 
-      0,   6,  18,   0,  16,   0, 
-      0,   0,   0,   0,  10, 128, 
-     32,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,  54,   0, 
-      0,   7,  18,  32,  16,   0, 
-      0,   0,   0,   0,  10,  48, 
-     32,   4,   0,   0,   0,   0, 
-     10,   0,  16,   0,   0,   0, 
-      0,   0,  54,   0,   0,   6, 
-     18,   0,  16,   0,   0,   0, 
-      0,   0,  26, 128,  32,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,  54,   0,   0,   7, 
-     34,  32,  16,   0,   0,   0, 
-      0,   0,  10,  48,  32,   4, 
-      0,   0,   0,   0,  10,   0, 
-     16,   0,   0,   0,   0,   0, 
-     54,   0,   0,   6,  18,   0, 
-     16,   0,   0,   0,   0,   0, 
-     42, 128,  32,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-     54,   0,   0,   7,  66,  32, 
-     16,   0,   0,   0,   0,   0, 
-     10,  48,  32,   4,   0,   0, 
-      0,   0,  10,   0,  16,   0, 
-      0,   0,   0,   0,  54,   0, 
-      0,   6,  18,   0,  16,   0, 
-      0,   0,   0,   0,  58, 128, 
-     32,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,  54,   0, 
-      0,   7, 130,  32,  16,   0, 
-      0,   0,   0,   0,  10,  48, 
-     32,   4,   0,   0,   0,   0, 
-     10,   0,  16,   0,   0,   0, 
-      0,   0,  62,   0,   0,   1, 
-     83,  84,  65,  84, 116,   0, 
-      0,   0,  22,   0,   0,   0, 
-      1,   0,   0,   0,   0,   0, 
-      0,   0,   3,   0,   0,   0, 
-      1,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      1,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      6,   0,   0,   0,  10,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   1,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      6,   0,   0,   0,   0,   0, 
-      0,   0,   2,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0
-};
+#if 0
+//
+// Generated by Microsoft (R) HLSL Shader Compiler 6.3.9600.16384
+//
+//
+// Buffer Definitions: 
+//
+// cbuffer SwizzleProperties
+// {
+//
+//   uint4 SwizzleIndices;              // Offset:    0 Size:    16
+//
+// }
+//
+//
+// Resource Bindings:
+//
+// Name                                 Type  Format         Dim Slot Elements
+// ------------------------------ ---------- ------- ----------- ---- --------
+// TextureUI2DArray                  texture   uint4     2darray    0        1
+// SwizzleProperties                 cbuffer      NA          NA    0        1
+//
+//
+//
+// Input signature:
+//
+// Name                 Index   Mask Register SysValue  Format   Used
+// -------------------- ----- ------ -------- -------- ------- ------
+// SV_POSITION              0   xyzw        0      POS   float       
+// SV_RENDERTARGETARRAYINDEX     0   x           1  RTINDEX    uint   x   
+// TEXCOORD                 0   xyz         2     NONE   float   xy  
+//
+//
+// Output signature:
+//
+// Name                 Index   Mask Register SysValue  Format   Used
+// -------------------- ----- ------ -------- -------- ------- ------
+// SV_TARGET                0   xyzw        0   TARGET    uint   xyzw
+//
+ps_4_0
+dcl_constantbuffer cb0[1], immediateIndexed
+dcl_resource_texture2darray (uint,uint,uint,uint) t0
+dcl_input_ps_siv constant v1.x, rendertarget_array_index
+dcl_input_ps linear v2.xy
+dcl_output o0.xyzw
+dcl_temps 1
+dcl_indexableTemp x0[6], 4
+resinfo_uint r0.xyzw, l(0), t0.xyzw
+utof r0.xy, r0.xyxx
+mul r0.xy, r0.xyxx, v2.xyxx
+ftoi r0.xy, r0.xyxx
+mov r0.z, v1.x
+mov r0.w, l(0)
+ld r0.xyzw, r0.xyzw, t0.xyzw
+mov x0[0].x, r0.x
+mov x0[1].x, r0.y
+mov x0[2].x, r0.z
+mov x0[3].x, r0.w
+mov x0[4].x, l(0)
+mov x0[5].x, l(1)
+mov r0.x, cb0[0].x
+mov o0.x, x0[r0.x + 0].x
+mov r0.x, cb0[0].y
+mov o0.y, x0[r0.x + 0].x
+mov r0.x, cb0[0].z
+mov o0.z, x0[r0.x + 0].x
+mov r0.x, cb0[0].w
+mov o0.w, x0[r0.x + 0].x
+ret 
+// Approximately 22 instruction slots used
+#endif
+
+const BYTE g_PS_SwizzleUI2DArray[] =
+{
+     68,  88,  66,  67,  15, 124, 
+    179,  49,  45,  69,  64, 249, 
+    216, 189, 135, 190,  71, 234, 
+     72,  20,   1,   0,   0,   0, 
+    240,   4,   0,   0,   5,   0, 
+      0,   0,  52,   0,   0,   0, 
+     64,   1,   0,   0, 200,   1, 
+      0,   0, 252,   1,   0,   0, 
+    116,   4,   0,   0,  82,  68, 
+     69,  70,   4,   1,   0,   0, 
+      1,   0,   0,   0, 128,   0, 
+      0,   0,   2,   0,   0,   0, 
+     28,   0,   0,   0,   0,   4, 
+    255, 255,   0,   1,   0,   0, 
+    208,   0,   0,   0,  92,   0, 
+      0,   0,   2,   0,   0,   0, 
+      4,   0,   0,   0,   5,   0, 
+      0,   0, 255, 255, 255, 255, 
+      0,   0,   0,   0,   1,   0, 
+      0,   0,  13,   0,   0,   0, 
+    109,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      1,   0,   0,   0,   1,   0, 
+      0,   0,  84, 101, 120, 116, 
+    117, 114, 101,  85,  73,  50, 
+     68,  65, 114, 114,  97, 121, 
+      0,  83, 119, 105, 122, 122, 
+    108, 101,  80, 114, 111, 112, 
+    101, 114, 116, 105, 101, 115, 
+      0, 171, 109,   0,   0,   0, 
+      1,   0,   0,   0, 152,   0, 
+      0,   0,  16,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0, 176,   0,   0,   0, 
+      0,   0,   0,   0,  16,   0, 
+      0,   0,   2,   0,   0,   0, 
+    192,   0,   0,   0,   0,   0, 
+      0,   0,  83, 119, 105, 122, 
+    122, 108, 101,  73, 110, 100, 
+    105,  99, 101, 115,   0, 171, 
+      1,   0,  19,   0,   1,   0, 
+      4,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,  77, 105, 
+     99, 114, 111, 115, 111, 102, 
+    116,  32,  40,  82,  41,  32, 
+     72,  76,  83,  76,  32,  83, 
+    104,  97, 100, 101, 114,  32, 
+     67, 111, 109, 112, 105, 108, 
+    101, 114,  32,  54,  46,  51, 
+     46,  57,  54,  48,  48,  46, 
+     49,  54,  51,  56,  52,   0, 
+    171, 171,  73,  83,  71,  78, 
+    128,   0,   0,   0,   3,   0, 
+      0,   0,   8,   0,   0,   0, 
+     80,   0,   0,   0,   0,   0, 
+      0,   0,   1,   0,   0,   0, 
+      3,   0,   0,   0,   0,   0, 
+      0,   0,  15,   0,   0,   0, 
+     92,   0,   0,   0,   0,   0, 
+      0,   0,   4,   0,   0,   0, 
+      1,   0,   0,   0,   1,   0, 
+      0,   0,   1,   1,   0,   0, 
+    118,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      3,   0,   0,   0,   2,   0, 
+      0,   0,   7,   3,   0,   0, 
+     83,  86,  95,  80,  79,  83, 
+     73,  84,  73,  79,  78,   0, 
+     83,  86,  95,  82,  69,  78, 
+     68,  69,  82,  84,  65,  82, 
+     71,  69,  84,  65,  82,  82, 
+     65,  89,  73,  78,  68,  69, 
+     88,   0,  84,  69,  88,  67, 
+     79,  79,  82,  68,   0, 171, 
+     79,  83,  71,  78,  44,   0, 
+      0,   0,   1,   0,   0,   0, 
+      8,   0,   0,   0,  32,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   1,   0, 
+      0,   0,   0,   0,   0,   0, 
+     15,   0,   0,   0,  83,  86, 
+     95,  84,  65,  82,  71,  69, 
+     84,   0, 171, 171,  83,  72, 
+     68,  82, 112,   2,   0,   0, 
+     64,   0,   0,   0, 156,   0, 
+      0,   0,  89,   0,   0,   4, 
+     70, 142,  32,   0,   0,   0, 
+      0,   0,   1,   0,   0,   0, 
+     88,  64,   0,   4,   0, 112, 
+     16,   0,   0,   0,   0,   0, 
+     68,  68,   0,   0, 100,   8, 
+      0,   4,  18,  16,  16,   0, 
+      1,   0,   0,   0,   4,   0, 
+      0,   0,  98,  16,   0,   3, 
+     50,  16,  16,   0,   2,   0, 
+      0,   0, 101,   0,   0,   3, 
+    242,  32,  16,   0,   0,   0, 
+      0,   0, 104,   0,   0,   2, 
+      1,   0,   0,   0, 105,   0, 
+      0,   4,   0,   0,   0,   0, 
+      6,   0,   0,   0,   4,   0, 
+      0,   0,  61,  16,   0,   7, 
+    242,   0,  16,   0,   0,   0, 
+      0,   0,   1,  64,   0,   0, 
+      0,   0,   0,   0,  70, 126, 
+     16,   0,   0,   0,   0,   0, 
+     86,   0,   0,   5,  50,   0, 
+     16,   0,   0,   0,   0,   0, 
+     70,   0,  16,   0,   0,   0, 
+      0,   0,  56,   0,   0,   7, 
+     50,   0,  16,   0,   0,   0, 
+      0,   0,  70,   0,  16,   0, 
+      0,   0,   0,   0,  70,  16, 
+     16,   0,   2,   0,   0,   0, 
+     27,   0,   0,   5,  50,   0, 
+     16,   0,   0,   0,   0,   0, 
+     70,   0,  16,   0,   0,   0, 
+      0,   0,  54,   0,   0,   5, 
+     66,   0,  16,   0,   0,   0, 
+      0,   0,  10,  16,  16,   0, 
+      1,   0,   0,   0,  54,   0, 
+      0,   5, 130,   0,  16,   0, 
+      0,   0,   0,   0,   1,  64, 
+      0,   0,   0,   0,   0,   0, 
+     45,   0,   0,   7, 242,   0, 
+     16,   0,   0,   0,   0,   0, 
+     70,  14,  16,   0,   0,   0, 
+      0,   0,  70, 126,  16,   0, 
+      0,   0,   0,   0,  54,   0, 
+      0,   6,  18,  48,  32,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,  10,   0,  16,   0, 
+      0,   0,   0,   0,  54,   0, 
+      0,   6,  18,  48,  32,   0, 
+      0,   0,   0,   0,   1,   0, 
+      0,   0,  26,   0,  16,   0, 
+      0,   0,   0,   0,  54,   0, 
+      0,   6,  18,  48,  32,   0, 
+      0,   0,   0,   0,   2,   0, 
+      0,   0,  42,   0,  16,   0, 
+      0,   0,   0,   0,  54,   0, 
+      0,   6,  18,  48,  32,   0, 
+      0,   0,   0,   0,   3,   0, 
+      0,   0,  58,   0,  16,   0, 
+      0,   0,   0,   0,  54,   0, 
+      0,   6,  18,  48,  32,   0, 
+      0,   0,   0,   0,   4,   0, 
+      0,   0,   1,  64,   0,   0, 
+      0,   0,   0,   0,  54,   0, 
+      0,   6,  18,  48,  32,   0, 
+      0,   0,   0,   0,   5,   0, 
+      0,   0,   1,  64,   0,   0, 
+      1,   0,   0,   0,  54,   0, 
+      0,   6,  18,   0,  16,   0, 
+      0,   0,   0,   0,  10, 128, 
+     32,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,  54,   0, 
+      0,   7,  18,  32,  16,   0, 
+      0,   0,   0,   0,  10,  48, 
+     32,   4,   0,   0,   0,   0, 
+     10,   0,  16,   0,   0,   0, 
+      0,   0,  54,   0,   0,   6, 
+     18,   0,  16,   0,   0,   0, 
+      0,   0,  26, 128,  32,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,  54,   0,   0,   7, 
+     34,  32,  16,   0,   0,   0, 
+      0,   0,  10,  48,  32,   4, 
+      0,   0,   0,   0,  10,   0, 
+     16,   0,   0,   0,   0,   0, 
+     54,   0,   0,   6,  18,   0, 
+     16,   0,   0,   0,   0,   0, 
+     42, 128,  32,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+     54,   0,   0,   7,  66,  32, 
+     16,   0,   0,   0,   0,   0, 
+     10,  48,  32,   4,   0,   0, 
+      0,   0,  10,   0,  16,   0, 
+      0,   0,   0,   0,  54,   0, 
+      0,   6,  18,   0,  16,   0, 
+      0,   0,   0,   0,  58, 128, 
+     32,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,  54,   0, 
+      0,   7, 130,  32,  16,   0, 
+      0,   0,   0,   0,  10,  48, 
+     32,   4,   0,   0,   0,   0, 
+     10,   0,  16,   0,   0,   0, 
+      0,   0,  62,   0,   0,   1, 
+     83,  84,  65,  84, 116,   0, 
+      0,   0,  22,   0,   0,   0, 
+      1,   0,   0,   0,   0,   0, 
+      0,   0,   3,   0,   0,   0, 
+      1,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      1,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      6,   0,   0,   0,  10,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   1,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      6,   0,   0,   0,   0,   0, 
+      0,   0,   2,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0
+};
--- a/gfx/angle/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/swizzleui2dps.h
+++ b/gfx/angle/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/swizzleui2dps.h
@@ -1,270 +1,270 @@
-#if 0
-//
-// Generated by Microsoft (R) HLSL Shader Compiler 6.3.9600.16384
-//
-//
-// Buffer Definitions: 
-//
-// cbuffer SwizzleProperties
-// {
-//
-//   uint4 SwizzleIndices;              // Offset:    0 Size:    16
-//
-// }
-//
-//
-// Resource Bindings:
-//
-// Name                                 Type  Format         Dim Slot Elements
-// ------------------------------ ---------- ------- ----------- ---- --------
-// TextureUI2D                       texture   uint4          2d    0        1
-// SwizzleProperties                 cbuffer      NA          NA    0        1
-//
-//
-//
-// Input signature:
-//
-// Name                 Index   Mask Register SysValue  Format   Used
-// -------------------- ----- ------ -------- -------- ------- ------
-// SV_POSITION              0   xyzw        0      POS   float       
-// TEXCOORD                 0   xy          1     NONE   float   xy  
-//
-//
-// Output signature:
-//
-// Name                 Index   Mask Register SysValue  Format   Used
-// -------------------- ----- ------ -------- -------- ------- ------
-// SV_TARGET                0   xyzw        0   TARGET    uint   xyzw
-//
-ps_4_0
-dcl_constantbuffer cb0[1], immediateIndexed
-dcl_resource_texture2d (uint,uint,uint,uint) t0
-dcl_input_ps linear v1.xy
-dcl_output o0.xyzw
-dcl_temps 1
-dcl_indexableTemp x0[6], 4
-resinfo_uint r0.xyzw, l(0), t0.xyzw
-utof r0.xy, r0.xyxx
-mul r0.xy, r0.xyxx, v1.xyxx
-ftoi r0.xy, r0.xyxx
-mov r0.zw, l(0,0,0,0)
-ld r0.xyzw, r0.xyzw, t0.xyzw
-mov x0[0].x, r0.x
-mov x0[1].x, r0.y
-mov x0[2].x, r0.z
-mov x0[3].x, r0.w
-mov x0[4].x, l(0)
-mov x0[5].x, l(1)
-mov r0.x, cb0[0].x
-mov o0.x, x0[r0.x + 0].x
-mov r0.x, cb0[0].y
-mov o0.y, x0[r0.x + 0].x
-mov r0.x, cb0[0].z
-mov o0.z, x0[r0.x + 0].x
-mov r0.x, cb0[0].w
-mov o0.w, x0[r0.x + 0].x
-ret 
-// Approximately 21 instruction slots used
-#endif
-
-const BYTE g_PS_SwizzleUI2D[] =
-{
-     68,  88,  66,  67, 165, 190, 
-     35, 188, 235, 202, 154, 237, 
-    226,  86, 223, 212,  34,  38, 
-     81, 252,   1,   0,   0,   0, 
-    164,   4,   0,   0,   5,   0, 
-      0,   0,  52,   0,   0,   0, 
-     60,   1,   0,   0, 148,   1, 
-      0,   0, 200,   1,   0,   0, 
-     40,   4,   0,   0,  82,  68, 
-     69,  70,   0,   1,   0,   0, 
-      1,   0,   0,   0, 124,   0, 
-      0,   0,   2,   0,   0,   0, 
-     28,   0,   0,   0,   0,   4, 
-    255, 255,   0,   1,   0,   0, 
-    204,   0,   0,   0,  92,   0, 
-      0,   0,   2,   0,   0,   0, 
-      4,   0,   0,   0,   4,   0, 
-      0,   0, 255, 255, 255, 255, 
-      0,   0,   0,   0,   1,   0, 
-      0,   0,  13,   0,   0,   0, 
-    104,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      1,   0,   0,   0,   1,   0, 
-      0,   0,  84, 101, 120, 116, 
-    117, 114, 101,  85,  73,  50, 
-     68,   0,  83, 119, 105, 122, 
-    122, 108, 101,  80, 114, 111, 
-    112, 101, 114, 116, 105, 101, 
-    115,   0, 171, 171, 104,   0, 
-      0,   0,   1,   0,   0,   0, 
-    148,   0,   0,   0,  16,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0, 172,   0, 
-      0,   0,   0,   0,   0,   0, 
-     16,   0,   0,   0,   2,   0, 
-      0,   0, 188,   0,   0,   0, 
-      0,   0,   0,   0,  83, 119, 
-    105, 122, 122, 108, 101,  73, 
-    110, 100, 105,  99, 101, 115, 
-      0, 171,   1,   0,  19,   0, 
-      1,   0,   4,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-     77, 105,  99, 114, 111, 115, 
-    111, 102, 116,  32,  40,  82, 
-     41,  32,  72,  76,  83,  76, 
-     32,  83, 104,  97, 100, 101, 
-    114,  32,  67, 111, 109, 112, 
-    105, 108, 101, 114,  32,  54, 
-     46,  51,  46,  57,  54,  48, 
-     48,  46,  49,  54,  51,  56, 
-     52,   0, 171, 171,  73,  83, 
-     71,  78,  80,   0,   0,   0, 
-      2,   0,   0,   0,   8,   0, 
-      0,   0,  56,   0,   0,   0, 
-      0,   0,   0,   0,   1,   0, 
-      0,   0,   3,   0,   0,   0, 
-      0,   0,   0,   0,  15,   0, 
-      0,   0,  68,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   3,   0,   0,   0, 
-      1,   0,   0,   0,   3,   3, 
-      0,   0,  83,  86,  95,  80, 
-     79,  83,  73,  84,  73,  79, 
-     78,   0,  84,  69,  88,  67, 
-     79,  79,  82,  68,   0, 171, 
-    171, 171,  79,  83,  71,  78, 
-     44,   0,   0,   0,   1,   0, 
-      0,   0,   8,   0,   0,   0, 
-     32,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      1,   0,   0,   0,   0,   0, 
-      0,   0,  15,   0,   0,   0, 
-     83,  86,  95,  84,  65,  82, 
-     71,  69,  84,   0, 171, 171, 
-     83,  72,  68,  82,  88,   2, 
-      0,   0,  64,   0,   0,   0, 
-    150,   0,   0,   0,  89,   0, 
-      0,   4,  70, 142,  32,   0, 
-      0,   0,   0,   0,   1,   0, 
-      0,   0,  88,  24,   0,   4, 
-      0, 112,  16,   0,   0,   0, 
-      0,   0,  68,  68,   0,   0, 
-     98,  16,   0,   3,  50,  16, 
-     16,   0,   1,   0,   0,   0, 
-    101,   0,   0,   3, 242,  32, 
-     16,   0,   0,   0,   0,   0, 
-    104,   0,   0,   2,   1,   0, 
-      0,   0, 105,   0,   0,   4, 
-      0,   0,   0,   0,   6,   0, 
-      0,   0,   4,   0,   0,   0, 
-     61,  16,   0,   7, 242,   0, 
-     16,   0,   0,   0,   0,   0, 
-      1,  64,   0,   0,   0,   0, 
-      0,   0,  70, 126,  16,   0, 
-      0,   0,   0,   0,  86,   0, 
-      0,   5,  50,   0,  16,   0, 
-      0,   0,   0,   0,  70,   0, 
-     16,   0,   0,   0,   0,   0, 
-     56,   0,   0,   7,  50,   0, 
-     16,   0,   0,   0,   0,   0, 
-     70,   0,  16,   0,   0,   0, 
-      0,   0,  70,  16,  16,   0, 
-      1,   0,   0,   0,  27,   0, 
-      0,   5,  50,   0,  16,   0, 
-      0,   0,   0,   0,  70,   0, 
-     16,   0,   0,   0,   0,   0, 
-     54,   0,   0,   8, 194,   0, 
-     16,   0,   0,   0,   0,   0, 
-      2,  64,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,  45,   0,   0,   7, 
-    242,   0,  16,   0,   0,   0, 
-      0,   0,  70,  14,  16,   0, 
-      0,   0,   0,   0,  70, 126, 
-     16,   0,   0,   0,   0,   0, 
-     54,   0,   0,   6,  18,  48, 
-     32,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,  10,   0, 
-     16,   0,   0,   0,   0,   0, 
-     54,   0,   0,   6,  18,  48, 
-     32,   0,   0,   0,   0,   0, 
-      1,   0,   0,   0,  26,   0, 
-     16,   0,   0,   0,   0,   0, 
-     54,   0,   0,   6,  18,  48, 
-     32,   0,   0,   0,   0,   0, 
-      2,   0,   0,   0,  42,   0, 
-     16,   0,   0,   0,   0,   0, 
-     54,   0,   0,   6,  18,  48, 
-     32,   0,   0,   0,   0,   0, 
-      3,   0,   0,   0,  58,   0, 
-     16,   0,   0,   0,   0,   0, 
-     54,   0,   0,   6,  18,  48, 
-     32,   0,   0,   0,   0,   0, 
-      4,   0,   0,   0,   1,  64, 
-      0,   0,   0,   0,   0,   0, 
-     54,   0,   0,   6,  18,  48, 
-     32,   0,   0,   0,   0,   0, 
-      5,   0,   0,   0,   1,  64, 
-      0,   0,   1,   0,   0,   0, 
-     54,   0,   0,   6,  18,   0, 
-     16,   0,   0,   0,   0,   0, 
-     10, 128,  32,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-     54,   0,   0,   7,  18,  32, 
-     16,   0,   0,   0,   0,   0, 
-     10,  48,  32,   4,   0,   0, 
-      0,   0,  10,   0,  16,   0, 
-      0,   0,   0,   0,  54,   0, 
-      0,   6,  18,   0,  16,   0, 
-      0,   0,   0,   0,  26, 128, 
-     32,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,  54,   0, 
-      0,   7,  34,  32,  16,   0, 
-      0,   0,   0,   0,  10,  48, 
-     32,   4,   0,   0,   0,   0, 
-     10,   0,  16,   0,   0,   0, 
-      0,   0,  54,   0,   0,   6, 
-     18,   0,  16,   0,   0,   0, 
-      0,   0,  42, 128,  32,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,  54,   0,   0,   7, 
-     66,  32,  16,   0,   0,   0, 
-      0,   0,  10,  48,  32,   4, 
-      0,   0,   0,   0,  10,   0, 
-     16,   0,   0,   0,   0,   0, 
-     54,   0,   0,   6,  18,   0, 
-     16,   0,   0,   0,   0,   0, 
-     58, 128,  32,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-     54,   0,   0,   7, 130,  32, 
-     16,   0,   0,   0,   0,   0, 
-     10,  48,  32,   4,   0,   0, 
-      0,   0,  10,   0,  16,   0, 
-      0,   0,   0,   0,  62,   0, 
-      0,   1,  83,  84,  65,  84, 
-    116,   0,   0,   0,  21,   0, 
-      0,   0,   1,   0,   0,   0, 
-      0,   0,   0,   0,   2,   0, 
-      0,   0,   1,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   1,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   6,   0,   0,   0, 
-     10,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   1,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   5,   0,   0,   0, 
-      0,   0,   0,   0,   2,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0
-};
+#if 0
+//
+// Generated by Microsoft (R) HLSL Shader Compiler 6.3.9600.16384
+//
+//
+// Buffer Definitions: 
+//
+// cbuffer SwizzleProperties
+// {
+//
+//   uint4 SwizzleIndices;              // Offset:    0 Size:    16
+//
+// }
+//
+//
+// Resource Bindings:
+//
+// Name                                 Type  Format         Dim Slot Elements
+// ------------------------------ ---------- ------- ----------- ---- --------
+// TextureUI2D                       texture   uint4          2d    0        1
+// SwizzleProperties                 cbuffer      NA          NA    0        1
+//
+//
+//
+// Input signature:
+//
+// Name                 Index   Mask Register SysValue  Format   Used
+// -------------------- ----- ------ -------- -------- ------- ------
+// SV_POSITION              0   xyzw        0      POS   float       
+// TEXCOORD                 0   xy          1     NONE   float   xy  
+//
+//
+// Output signature:
+//
+// Name                 Index   Mask Register SysValue  Format   Used
+// -------------------- ----- ------ -------- -------- ------- ------
+// SV_TARGET                0   xyzw        0   TARGET    uint   xyzw
+//
+ps_4_0
+dcl_constantbuffer cb0[1], immediateIndexed
+dcl_resource_texture2d (uint,uint,uint,uint) t0
+dcl_input_ps linear v1.xy
+dcl_output o0.xyzw
+dcl_temps 1
+dcl_indexableTemp x0[6], 4
+resinfo_uint r0.xyzw, l(0), t0.xyzw
+utof r0.xy, r0.xyxx
+mul r0.xy, r0.xyxx, v1.xyxx
+ftoi r0.xy, r0.xyxx
+mov r0.zw, l(0,0,0,0)
+ld r0.xyzw, r0.xyzw, t0.xyzw
+mov x0[0].x, r0.x
+mov x0[1].x, r0.y
+mov x0[2].x, r0.z
+mov x0[3].x, r0.w
+mov x0[4].x, l(0)
+mov x0[5].x, l(1)
+mov r0.x, cb0[0].x
+mov o0.x, x0[r0.x + 0].x
+mov r0.x, cb0[0].y
+mov o0.y, x0[r0.x + 0].x
+mov r0.x, cb0[0].z
+mov o0.z, x0[r0.x + 0].x
+mov r0.x, cb0[0].w
+mov o0.w, x0[r0.x + 0].x
+ret 
+// Approximately 21 instruction slots used
+#endif
+
+const BYTE g_PS_SwizzleUI2D[] =
+{
+     68,  88,  66,  67, 165, 190, 
+     35, 188, 235, 202, 154, 237, 
+    226,  86, 223, 212,  34,  38, 
+     81, 252,   1,   0,   0,   0, 
+    164,   4,   0,   0,   5,   0, 
+      0,   0,  52,   0,   0,   0, 
+     60,   1,   0,   0, 148,   1, 
+      0,   0, 200,   1,   0,   0, 
+     40,   4,   0,   0,  82,  68, 
+     69,  70,   0,   1,   0,   0, 
+      1,   0,   0,   0, 124,   0, 
+      0,   0,   2,   0,   0,   0, 
+     28,   0,   0,   0,   0,   4, 
+    255, 255,   0,   1,   0,   0, 
+    204,   0,   0,   0,  92,   0, 
+      0,   0,   2,   0,   0,   0, 
+      4,   0,   0,   0,   4,   0, 
+      0,   0, 255, 255, 255, 255, 
+      0,   0,   0,   0,   1,   0, 
+      0,   0,  13,   0,   0,   0, 
+    104,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      1,   0,   0,   0,   1,   0, 
+      0,   0,  84, 101, 120, 116, 
+    117, 114, 101,  85,  73,  50, 
+     68,   0,  83, 119, 105, 122, 
+    122, 108, 101,  80, 114, 111, 
+    112, 101, 114, 116, 105, 101, 
+    115,   0, 171, 171, 104,   0, 
+      0,   0,   1,   0,   0,   0, 
+    148,   0,   0,   0,  16,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0, 172,   0, 
+      0,   0,   0,   0,   0,   0, 
+     16,   0,   0,   0,   2,   0, 
+      0,   0, 188,   0,   0,   0, 
+      0,   0,   0,   0,  83, 119, 
+    105, 122, 122, 108, 101,  73, 
+    110, 100, 105,  99, 101, 115, 
+      0, 171,   1,   0,  19,   0, 
+      1,   0,   4,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+     77, 105,  99, 114, 111, 115, 
+    111, 102, 116,  32,  40,  82, 
+     41,  32,  72,  76,  83,  76, 
+     32,  83, 104,  97, 100, 101, 
+    114,  32,  67, 111, 109, 112, 
+    105, 108, 101, 114,  32,  54, 
+     46,  51,  46,  57,  54,  48, 
+     48,  46,  49,  54,  51,  56, 
+     52,   0, 171, 171,  73,  83, 
+     71,  78,  80,   0,   0,   0, 
+      2,   0,   0,   0,   8,   0, 
+      0,   0,  56,   0,   0,   0, 
+      0,   0,   0,   0,   1,   0, 
+      0,   0,   3,   0,   0,   0, 
+      0,   0,   0,   0,  15,   0, 
+      0,   0,  68,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   3,   0,   0,   0, 
+      1,   0,   0,   0,   3,   3, 
+      0,   0,  83,  86,  95,  80, 
+     79,  83,  73,  84,  73,  79, 
+     78,   0,  84,  69,  88,  67, 
+     79,  79,  82,  68,   0, 171, 
+    171, 171,  79,  83,  71,  78, 
+     44,   0,   0,   0,   1,   0, 
+      0,   0,   8,   0,   0,   0, 
+     32,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      1,   0,   0,   0,   0,   0, 
+      0,   0,  15,   0,   0,   0, 
+     83,  86,  95,  84,  65,  82, 
+     71,  69,  84,   0, 171, 171, 
+     83,  72,  68,  82,  88,   2, 
+      0,   0,  64,   0,   0,   0, 
+    150,   0,   0,   0,  89,   0, 
+      0,   4,  70, 142,  32,   0, 
+      0,   0,   0,   0,   1,   0, 
+      0,   0,  88,  24,   0,   4, 
+      0, 112,  16,   0,   0,   0, 
+      0,   0,  68,  68,   0,   0, 
+     98,  16,   0,   3,  50,  16, 
+     16,   0,   1,   0,   0,   0, 
+    101,   0,   0,   3, 242,  32, 
+     16,   0,   0,   0,   0,   0, 
+    104,   0,   0,   2,   1,   0, 
+      0,   0, 105,   0,   0,   4, 
+      0,   0,   0,   0,   6,   0, 
+      0,   0,   4,   0,   0,   0, 
+     61,  16,   0,   7, 242,   0, 
+     16,   0,   0,   0,   0,   0, 
+      1,  64,   0,   0,   0,   0, 
+      0,   0,  70, 126,  16,   0, 
+      0,   0,   0,   0,  86,   0, 
+      0,   5,  50,   0,  16,   0, 
+      0,   0,   0,   0,  70,   0, 
+     16,   0,   0,   0,   0,   0, 
+     56,   0,   0,   7,  50,   0, 
+     16,   0,   0,   0,   0,   0, 
+     70,   0,  16,   0,   0,   0, 
+      0,   0,  70,  16,  16,   0, 
+      1,   0,   0,   0,  27,   0, 
+      0,   5,  50,   0,  16,   0, 
+      0,   0,   0,   0,  70,   0, 
+     16,   0,   0,   0,   0,   0, 
+     54,   0,   0,   8, 194,   0, 
+     16,   0,   0,   0,   0,   0, 
+      2,  64,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,  45,   0,   0,   7, 
+    242,   0,  16,   0,   0,   0, 
+      0,   0,  70,  14,  16,   0, 
+      0,   0,   0,   0,  70, 126, 
+     16,   0,   0,   0,   0,   0, 
+     54,   0,   0,   6,  18,  48, 
+     32,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,  10,   0, 
+     16,   0,   0,   0,   0,   0, 
+     54,   0,   0,   6,  18,  48, 
+     32,   0,   0,   0,   0,   0, 
+      1,   0,   0,   0,  26,   0, 
+     16,   0,   0,   0,   0,   0, 
+     54,   0,   0,   6,  18,  48, 
+     32,   0,   0,   0,   0,   0, 
+      2,   0,   0,   0,  42,   0, 
+     16,   0,   0,   0,   0,   0, 
+     54,   0,   0,   6,  18,  48, 
+     32,   0,   0,   0,   0,   0, 
+      3,   0,   0,   0,  58,   0, 
+     16,   0,   0,   0,   0,   0, 
+     54,   0,   0,   6,  18,  48, 
+     32,   0,   0,   0,   0,   0, 
+      4,   0,   0,   0,   1,  64, 
+      0,   0,   0,   0,   0,   0, 
+     54,   0,   0,   6,  18,  48, 
+     32,   0,   0,   0,   0,   0, 
+      5,   0,   0,   0,   1,  64, 
+      0,   0,   1,   0,   0,   0, 
+     54,   0,   0,   6,  18,   0, 
+     16,   0,   0,   0,   0,   0, 
+     10, 128,  32,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+     54,   0,   0,   7,  18,  32, 
+     16,   0,   0,   0,   0,   0, 
+     10,  48,  32,   4,   0,   0, 
+      0,   0,  10,   0,  16,   0, 
+      0,   0,   0,   0,  54,   0, 
+      0,   6,  18,   0,  16,   0, 
+      0,   0,   0,   0,  26, 128, 
+     32,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,  54,   0, 
+      0,   7,  34,  32,  16,   0, 
+      0,   0,   0,   0,  10,  48, 
+     32,   4,   0,   0,   0,   0, 
+     10,   0,  16,   0,   0,   0, 
+      0,   0,  54,   0,   0,   6, 
+     18,   0,  16,   0,   0,   0, 
+      0,   0,  42, 128,  32,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,  54,   0,   0,   7, 
+     66,  32,  16,   0,   0,   0, 
+      0,   0,  10,  48,  32,   4, 
+      0,   0,   0,   0,  10,   0, 
+     16,   0,   0,   0,   0,   0, 
+     54,   0,   0,   6,  18,   0, 
+     16,   0,   0,   0,   0,   0, 
+     58, 128,  32,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+     54,   0,   0,   7, 130,  32, 
+     16,   0,   0,   0,   0,   0, 
+     10,  48,  32,   4,   0,   0, 
+      0,   0,  10,   0,  16,   0, 
+      0,   0,   0,   0,  62,   0, 
+      0,   1,  83,  84,  65,  84, 
+    116,   0,   0,   0,  21,   0, 
+      0,   0,   1,   0,   0,   0, 
+      0,   0,   0,   0,   2,   0, 
+      0,   0,   1,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   1,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   6,   0,   0,   0, 
+     10,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   1,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   5,   0,   0,   0, 
+      0,   0,   0,   0,   2,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0
+};
--- a/gfx/angle/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/swizzleui3dps.h
+++ b/gfx/angle/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/swizzleui3dps.h
@@ -1,277 +1,277 @@
-#if 0
-//
-// Generated by Microsoft (R) HLSL Shader Compiler 6.3.9600.16384
-//
-//
-// Buffer Definitions: 
-//
-// cbuffer SwizzleProperties
-// {
-//
-//   uint4 SwizzleIndices;              // Offset:    0 Size:    16
-//
-// }
-//
-//
-// Resource Bindings:
-//
-// Name                                 Type  Format         Dim Slot Elements
-// ------------------------------ ---------- ------- ----------- ---- --------
-// TextureUI3D                       texture   uint4          3d    0        1
-// SwizzleProperties                 cbuffer      NA          NA    0        1
-//
-//
-//
-// Input signature:
-//
-// Name                 Index   Mask Register SysValue  Format   Used
-// -------------------- ----- ------ -------- -------- ------- ------
-// SV_POSITION              0   xyzw        0      POS   float       
-// SV_RENDERTARGETARRAYINDEX     0   x           1  RTINDEX    uint       
-// TEXCOORD                 0   xyz         2     NONE   float   xyz 
-//
-//
-// Output signature:
-//
-// Name                 Index   Mask Register SysValue  Format   Used
-// -------------------- ----- ------ -------- -------- ------- ------
-// SV_TARGET                0   xyzw        0   TARGET    uint   xyzw
-//
-ps_4_0
-dcl_constantbuffer cb0[1], immediateIndexed
-dcl_resource_texture3d (uint,uint,uint,uint) t0
-dcl_input_ps linear v2.xyz
-dcl_output o0.xyzw
-dcl_temps 1
-dcl_indexableTemp x0[6], 4
-resinfo_uint r0.xyzw, l(0), t0.xyzw
-utof r0.xyz, r0.xyzx
-mul r0.xyz, r0.xyzx, v2.xyzx
-ftoi r0.xyz, r0.xyzx
-mov r0.w, l(0)
-ld r0.xyzw, r0.xyzw, t0.xyzw
-mov x0[0].x, r0.x
-mov x0[1].x, r0.y
-mov x0[2].x, r0.z
-mov x0[3].x, r0.w
-mov x0[4].x, l(0)
-mov x0[5].x, l(1)
-mov r0.x, cb0[0].x
-mov o0.x, x0[r0.x + 0].x
-mov r0.x, cb0[0].y
-mov o0.y, x0[r0.x + 0].x
-mov r0.x, cb0[0].z
-mov o0.z, x0[r0.x + 0].x
-mov r0.x, cb0[0].w
-mov o0.w, x0[r0.x + 0].x
-ret 
-// Approximately 21 instruction slots used
-#endif
-
-const BYTE g_PS_SwizzleUI3D[] =
-{
-     68,  88,  66,  67, 186, 124, 
-    222, 110, 186, 145, 165,  56, 
-    152,  97, 247, 114, 115, 197, 
-    159, 190,   1,   0,   0,   0, 
-    200,   4,   0,   0,   5,   0, 
-      0,   0,  52,   0,   0,   0, 
-     60,   1,   0,   0, 196,   1, 
-      0,   0, 248,   1,   0,   0, 
-     76,   4,   0,   0,  82,  68, 
-     69,  70,   0,   1,   0,   0, 
-      1,   0,   0,   0, 124,   0, 
-      0,   0,   2,   0,   0,   0, 
-     28,   0,   0,   0,   0,   4, 
-    255, 255,   0,   1,   0,   0, 
-    204,   0,   0,   0,  92,   0, 
-      0,   0,   2,   0,   0,   0, 
-      4,   0,   0,   0,   8,   0, 
-      0,   0, 255, 255, 255, 255, 
-      0,   0,   0,   0,   1,   0, 
-      0,   0,  13,   0,   0,   0, 
-    104,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      1,   0,   0,   0,   1,   0, 
-      0,   0,  84, 101, 120, 116, 
-    117, 114, 101,  85,  73,  51, 
-     68,   0,  83, 119, 105, 122, 
-    122, 108, 101,  80, 114, 111, 
-    112, 101, 114, 116, 105, 101, 
-    115,   0, 171, 171, 104,   0, 
-      0,   0,   1,   0,   0,   0, 
-    148,   0,   0,   0,  16,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0, 172,   0, 
-      0,   0,   0,   0,   0,   0, 
-     16,   0,   0,   0,   2,   0, 
-      0,   0, 188,   0,   0,   0, 
-      0,   0,   0,   0,  83, 119, 
-    105, 122, 122, 108, 101,  73, 
-    110, 100, 105,  99, 101, 115, 
-      0, 171,   1,   0,  19,   0, 
-      1,   0,   4,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-     77, 105,  99, 114, 111, 115, 
-    111, 102, 116,  32,  40,  82, 
-     41,  32,  72,  76,  83,  76, 
-     32,  83, 104,  97, 100, 101, 
-    114,  32,  67, 111, 109, 112, 
-    105, 108, 101, 114,  32,  54, 
-     46,  51,  46,  57,  54,  48, 
-     48,  46,  49,  54,  51,  56, 
-     52,   0, 171, 171,  73,  83, 
-     71,  78, 128,   0,   0,   0, 
-      3,   0,   0,   0,   8,   0, 
-      0,   0,  80,   0,   0,   0, 
-      0,   0,   0,   0,   1,   0, 
-      0,   0,   3,   0,   0,   0, 
-      0,   0,   0,   0,  15,   0, 
-      0,   0,  92,   0,   0,   0, 
-      0,   0,   0,   0,   4,   0, 
-      0,   0,   1,   0,   0,   0, 
-      1,   0,   0,   0,   1,   0, 
-      0,   0, 118,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   3,   0,   0,   0, 
-      2,   0,   0,   0,   7,   7, 
-      0,   0,  83,  86,  95,  80, 
-     79,  83,  73,  84,  73,  79, 
-     78,   0,  83,  86,  95,  82, 
-     69,  78,  68,  69,  82,  84, 
-     65,  82,  71,  69,  84,  65, 
-     82,  82,  65,  89,  73,  78, 
-     68,  69,  88,   0,  84,  69, 
-     88,  67,  79,  79,  82,  68, 
-      0, 171,  79,  83,  71,  78, 
-     44,   0,   0,   0,   1,   0, 
-      0,   0,   8,   0,   0,   0, 
-     32,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      1,   0,   0,   0,   0,   0, 
-      0,   0,  15,   0,   0,   0, 
-     83,  86,  95,  84,  65,  82, 
-     71,  69,  84,   0, 171, 171, 
-     83,  72,  68,  82,  76,   2, 
-      0,   0,  64,   0,   0,   0, 
-    147,   0,   0,   0,  89,   0, 
-      0,   4,  70, 142,  32,   0, 
-      0,   0,   0,   0,   1,   0, 
-      0,   0,  88,  40,   0,   4, 
-      0, 112,  16,   0,   0,   0, 
-      0,   0,  68,  68,   0,   0, 
-     98,  16,   0,   3, 114,  16, 
-     16,   0,   2,   0,   0,   0, 
-    101,   0,   0,   3, 242,  32, 
-     16,   0,   0,   0,   0,   0, 
-    104,   0,   0,   2,   1,   0, 
-      0,   0, 105,   0,   0,   4, 
-      0,   0,   0,   0,   6,   0, 
-      0,   0,   4,   0,   0,   0, 
-     61,  16,   0,   7, 242,   0, 
-     16,   0,   0,   0,   0,   0, 
-      1,  64,   0,   0,   0,   0, 
-      0,   0,  70, 126,  16,   0, 
-      0,   0,   0,   0,  86,   0, 
-      0,   5, 114,   0,  16,   0, 
-      0,   0,   0,   0,  70,   2, 
-     16,   0,   0,   0,   0,   0, 
-     56,   0,   0,   7, 114,   0, 
-     16,   0,   0,   0,   0,   0, 
-     70,   2,  16,   0,   0,   0, 
-      0,   0,  70,  18,  16,   0, 
-      2,   0,   0,   0,  27,   0, 
-      0,   5, 114,   0,  16,   0, 
-      0,   0,   0,   0,  70,   2, 
-     16,   0,   0,   0,   0,   0, 
-     54,   0,   0,   5, 130,   0, 
-     16,   0,   0,   0,   0,   0, 
-      1,  64,   0,   0,   0,   0, 
-      0,   0,  45,   0,   0,   7, 
-    242,   0,  16,   0,   0,   0, 
-      0,   0,  70,  14,  16,   0, 
-      0,   0,   0,   0,  70, 126, 
-     16,   0,   0,   0,   0,   0, 
-     54,   0,   0,   6,  18,  48, 
-     32,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,  10,   0, 
-     16,   0,   0,   0,   0,   0, 
-     54,   0,   0,   6,  18,  48, 
-     32,   0,   0,   0,   0,   0, 
-      1,   0,   0,   0,  26,   0, 
-     16,   0,   0,   0,   0,   0, 
-     54,   0,   0,   6,  18,  48, 
-     32,   0,   0,   0,   0,   0, 
-      2,   0,   0,   0,  42,   0, 
-     16,   0,   0,   0,   0,   0, 
-     54,   0,   0,   6,  18,  48, 
-     32,   0,   0,   0,   0,   0, 
-      3,   0,   0,   0,  58,   0, 
-     16,   0,   0,   0,   0,   0, 
-     54,   0,   0,   6,  18,  48, 
-     32,   0,   0,   0,   0,   0, 
-      4,   0,   0,   0,   1,  64, 
-      0,   0,   0,   0,   0,   0, 
-     54,   0,   0,   6,  18,  48, 
-     32,   0,   0,   0,   0,   0, 
-      5,   0,   0,   0,   1,  64, 
-      0,   0,   1,   0,   0,   0, 
-     54,   0,   0,   6,  18,   0, 
-     16,   0,   0,   0,   0,   0, 
-     10, 128,  32,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-     54,   0,   0,   7,  18,  32, 
-     16,   0,   0,   0,   0,   0, 
-     10,  48,  32,   4,   0,   0, 
-      0,   0,  10,   0,  16,   0, 
-      0,   0,   0,   0,  54,   0, 
-      0,   6,  18,   0,  16,   0, 
-      0,   0,   0,   0,  26, 128, 
-     32,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,  54,   0, 
-      0,   7,  34,  32,  16,   0, 
-      0,   0,   0,   0,  10,  48, 
-     32,   4,   0,   0,   0,   0, 
-     10,   0,  16,   0,   0,   0, 
-      0,   0,  54,   0,   0,   6, 
-     18,   0,  16,   0,   0,   0, 
-      0,   0,  42, 128,  32,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,  54,   0,   0,   7, 
-     66,  32,  16,   0,   0,   0, 
-      0,   0,  10,  48,  32,   4, 
-      0,   0,   0,   0,  10,   0, 
-     16,   0,   0,   0,   0,   0, 
-     54,   0,   0,   6,  18,   0, 
-     16,   0,   0,   0,   0,   0, 
-     58, 128,  32,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-     54,   0,   0,   7, 130,  32, 
-     16,   0,   0,   0,   0,   0, 
-     10,  48,  32,   4,   0,   0, 
-      0,   0,  10,   0,  16,   0, 
-      0,   0,   0,   0,  62,   0, 
-      0,   1,  83,  84,  65,  84, 
-    116,   0,   0,   0,  21,   0, 
-      0,   0,   1,   0,   0,   0, 
-      0,   0,   0,   0,   2,   0, 
-      0,   0,   1,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   1,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   6,   0,   0,   0, 
-     10,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   1,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   5,   0,   0,   0, 
-      0,   0,   0,   0,   2,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0
-};
+#if 0
+//
+// Generated by Microsoft (R) HLSL Shader Compiler 6.3.9600.16384
+//
+//
+// Buffer Definitions: 
+//
+// cbuffer SwizzleProperties
+// {
+//
+//   uint4 SwizzleIndices;              // Offset:    0 Size:    16
+//
+// }
+//
+//
+// Resource Bindings:
+//
+// Name                                 Type  Format         Dim Slot Elements
+// ------------------------------ ---------- ------- ----------- ---- --------
+// TextureUI3D                       texture   uint4          3d    0        1
+// SwizzleProperties                 cbuffer      NA          NA    0        1
+//
+//
+//
+// Input signature:
+//
+// Name                 Index   Mask Register SysValue  Format   Used
+// -------------------- ----- ------ -------- -------- ------- ------
+// SV_POSITION              0   xyzw        0      POS   float       
+// SV_RENDERTARGETARRAYINDEX     0   x           1  RTINDEX    uint       
+// TEXCOORD                 0   xyz         2     NONE   float   xyz 
+//
+//
+// Output signature:
+//
+// Name                 Index   Mask Register SysValue  Format   Used
+// -------------------- ----- ------ -------- -------- ------- ------
+// SV_TARGET                0   xyzw        0   TARGET    uint   xyzw
+//
+ps_4_0
+dcl_constantbuffer cb0[1], immediateIndexed
+dcl_resource_texture3d (uint,uint,uint,uint) t0
+dcl_input_ps linear v2.xyz
+dcl_output o0.xyzw
+dcl_temps 1
+dcl_indexableTemp x0[6], 4
+resinfo_uint r0.xyzw, l(0), t0.xyzw
+utof r0.xyz, r0.xyzx
+mul r0.xyz, r0.xyzx, v2.xyzx
+ftoi r0.xyz, r0.xyzx
+mov r0.w, l(0)
+ld r0.xyzw, r0.xyzw, t0.xyzw
+mov x0[0].x, r0.x
+mov x0[1].x, r0.y
+mov x0[2].x, r0.z
+mov x0[3].x, r0.w
+mov x0[4].x, l(0)
+mov x0[5].x, l(1)
+mov r0.x, cb0[0].x
+mov o0.x, x0[r0.x + 0].x
+mov r0.x, cb0[0].y
+mov o0.y, x0[r0.x + 0].x
+mov r0.x, cb0[0].z
+mov o0.z, x0[r0.x + 0].x
+mov r0.x, cb0[0].w
+mov o0.w, x0[r0.x + 0].x
+ret 
+// Approximately 21 instruction slots used
+#endif
+
+const BYTE g_PS_SwizzleUI3D[] =
+{
+     68,  88,  66,  67, 186, 124, 
+    222, 110, 186, 145, 165,  56, 
+    152,  97, 247, 114, 115, 197, 
+    159, 190,   1,   0,   0,   0, 
+    200,   4,   0,   0,   5,   0, 
+      0,   0,  52,   0,   0,   0, 
+     60,   1,   0,   0, 196,   1, 
+      0,   0, 248,   1,   0,   0, 
+     76,   4,   0,   0,  82,  68, 
+     69,  70,   0,   1,   0,   0, 
+      1,   0,   0,   0, 124,   0, 
+      0,   0,   2,   0,   0,   0, 
+     28,   0,   0,   0,   0,   4, 
+    255, 255,   0,   1,   0,   0, 
+    204,   0,   0,   0,  92,   0, 
+      0,   0,   2,   0,   0,   0, 
+      4,   0,   0,   0,   8,   0, 
+      0,   0, 255, 255, 255, 255, 
+      0,   0,   0,   0,   1,   0, 
+      0,   0,  13,   0,   0,   0, 
+    104,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      1,   0,   0,   0,   1,   0, 
+      0,   0,  84, 101, 120, 116, 
+    117, 114, 101,  85,  73,  51, 
+     68,   0,  83, 119, 105, 122, 
+    122, 108, 101,  80, 114, 111, 
+    112, 101, 114, 116, 105, 101, 
+    115,   0, 171, 171, 104,   0, 
+      0,   0,   1,   0,   0,   0, 
+    148,   0,   0,   0,  16,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0, 172,   0, 
+      0,   0,   0,   0,   0,   0, 
+     16,   0,   0,   0,   2,   0, 
+      0,   0, 188,   0,   0,   0, 
+      0,   0,   0,   0,  83, 119, 
+    105, 122, 122, 108, 101,  73, 
+    110, 100, 105,  99, 101, 115, 
+      0, 171,   1,   0,  19,   0, 
+      1,   0,   4,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+     77, 105,  99, 114, 111, 115, 
+    111, 102, 116,  32,  40,  82, 
+     41,  32,  72,  76,  83,  76, 
+     32,  83, 104,  97, 100, 101, 
+    114,  32,  67, 111, 109, 112, 
+    105, 108, 101, 114,  32,  54, 
+     46,  51,  46,  57,  54,  48, 
+     48,  46,  49,  54,  51,  56, 
+     52,   0, 171, 171,  73,  83, 
+     71,  78, 128,   0,   0,   0, 
+      3,   0,   0,   0,   8,   0, 
+      0,   0,  80,   0,   0,   0, 
+      0,   0,   0,   0,   1,   0, 
+      0,   0,   3,   0,   0,   0, 
+      0,   0,   0,   0,  15,   0, 
+      0,   0,  92,   0,   0,   0, 
+      0,   0,   0,   0,   4,   0, 
+      0,   0,   1,   0,   0,   0, 
+      1,   0,   0,   0,   1,   0, 
+      0,   0, 118,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   3,   0,   0,   0, 
+      2,   0,   0,   0,   7,   7, 
+      0,   0,  83,  86,  95,  80, 
+     79,  83,  73,  84,  73,  79, 
+     78,   0,  83,  86,  95,  82, 
+     69,  78,  68,  69,  82,  84, 
+     65,  82,  71,  69,  84,  65, 
+     82,  82,  65,  89,  73,  78, 
+     68,  69,  88,   0,  84,  69, 
+     88,  67,  79,  79,  82,  68, 
+      0, 171,  79,  83,  71,  78, 
+     44,   0,   0,   0,   1,   0, 
+      0,   0,   8,   0,   0,   0, 
+     32,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      1,   0,   0,   0,   0,   0, 
+      0,   0,  15,   0,   0,   0, 
+     83,  86,  95,  84,  65,  82, 
+     71,  69,  84,   0, 171, 171, 
+     83,  72,  68,  82,  76,   2, 
+      0,   0,  64,   0,   0,   0, 
+    147,   0,   0,   0,  89,   0, 
+      0,   4,  70, 142,  32,   0, 
+      0,   0,   0,   0,   1,   0, 
+      0,   0,  88,  40,   0,   4, 
+      0, 112,  16,   0,   0,   0, 
+      0,   0,  68,  68,   0,   0, 
+     98,  16,   0,   3, 114,  16, 
+     16,   0,   2,   0,   0,   0, 
+    101,   0,   0,   3, 242,  32, 
+     16,   0,   0,   0,   0,   0, 
+    104,   0,   0,   2,   1,   0, 
+      0,   0, 105,   0,   0,   4, 
+      0,   0,   0,   0,   6,   0, 
+      0,   0,   4,   0,   0,   0, 
+     61,  16,   0,   7, 242,   0, 
+     16,   0,   0,   0,   0,   0, 
+      1,  64,   0,   0,   0,   0, 
+      0,   0,  70, 126,  16,   0, 
+      0,   0,   0,   0,  86,   0, 
+      0,   5, 114,   0,  16,   0, 
+      0,   0,   0,   0,  70,   2, 
+     16,   0,   0,   0,   0,   0, 
+     56,   0,   0,   7, 114,   0, 
+     16,   0,   0,   0,   0,   0, 
+     70,   2,  16,   0,   0,   0, 
+      0,   0,  70,  18,  16,   0, 
+      2,   0,   0,   0,  27,   0, 
+      0,   5, 114,   0,  16,   0, 
+      0,   0,   0,   0,  70,   2, 
+     16,   0,   0,   0,   0,   0, 
+     54,   0,   0,   5, 130,   0, 
+     16,   0,   0,   0,   0,   0, 
+      1,  64,   0,   0,   0,   0, 
+      0,   0,  45,   0,   0,   7, 
+    242,   0,  16,   0,   0,   0, 
+      0,   0,  70,  14,  16,   0, 
+      0,   0,   0,   0,  70, 126, 
+     16,   0,   0,   0,   0,   0, 
+     54,   0,   0,   6,  18,  48, 
+     32,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,  10,   0, 
+     16,   0,   0,   0,   0,   0, 
+     54,   0,   0,   6,  18,  48, 
+     32,   0,   0,   0,   0,   0, 
+      1,   0,   0,   0,  26,   0, 
+     16,   0,   0,   0,   0,   0, 
+     54,   0,   0,   6,  18,  48, 
+     32,   0,   0,   0,   0,   0, 
+      2,   0,   0,   0,  42,   0, 
+     16,   0,   0,   0,   0,   0, 
+     54,   0,   0,   6,  18,  48, 
+     32,   0,   0,   0,   0,   0, 
+      3,   0,   0,   0,  58,   0, 
+     16,   0,   0,   0,   0,   0, 
+     54,   0,   0,   6,  18,  48, 
+     32,   0,   0,   0,   0,   0, 
+      4,   0,   0,   0,   1,  64, 
+      0,   0,   0,   0,   0,   0, 
+     54,   0,   0,   6,  18,  48, 
+     32,   0,   0,   0,   0,   0, 
+      5,   0,   0,   0,   1,  64, 
+      0,   0,   1,   0,   0,   0, 
+     54,   0,   0,   6,  18,   0, 
+     16,   0,   0,   0,   0,   0, 
+     10, 128,  32,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+     54,   0,   0,   7,  18,  32, 
+     16,   0,   0,   0,   0,   0, 
+     10,  48,  32,   4,   0,   0, 
+      0,   0,  10,   0,  16,   0, 
+      0,   0,   0,   0,  54,   0, 
+      0,   6,  18,   0,  16,   0, 
+      0,   0,   0,   0,  26, 128, 
+     32,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,  54,   0, 
+      0,   7,  34,  32,  16,   0, 
+      0,   0,   0,   0,  10,  48, 
+     32,   4,   0,   0,   0,   0, 
+     10,   0,  16,   0,   0,   0, 
+      0,   0,  54,   0,   0,   6, 
+     18,   0,  16,   0,   0,   0, 
+      0,   0,  42, 128,  32,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,  54,   0,   0,   7, 
+     66,  32,  16,   0,   0,   0, 
+      0,   0,  10,  48,  32,   4, 
+      0,   0,   0,   0,  10,   0, 
+     16,   0,   0,   0,   0,   0, 
+     54,   0,   0,   6,  18,   0, 
+     16,   0,   0,   0,   0,   0, 
+     58, 128,  32,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+     54,   0,   0,   7, 130,  32, 
+     16,   0,   0,   0,   0,   0, 
+     10,  48,  32,   4,   0,   0, 
+      0,   0,  10,   0,  16,   0, 
+      0,   0,   0,   0,  62,   0, 
+      0,   1,  83,  84,  65,  84, 
+    116,   0,   0,   0,  21,   0, 
+      0,   0,   1,   0,   0,   0, 
+      0,   0,   0,   0,   2,   0, 
+      0,   0,   1,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   1,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   6,   0,   0,   0, 
+     10,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   1,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   5,   0,   0,   0, 
+      0,   0,   0,   0,   2,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0
+};
--- a/gfx/angle/src/libANGLE/renderer/d3d/d3d11/shaders/generate_shaders.bat
+++ b/gfx/angle/src/libANGLE/renderer/d3d/d3d11/shaders/generate_shaders.bat
@@ -1,167 +1,168 @@
-@ECHO OFF
-REM
-REM Copyright (c) 2013 The ANGLE Project Authors. All rights reserved.
-REM Use of this source code is governed by a BSD-style license that can be
-REM found in the LICENSE file.
-REM
-
-PATH %ProgramFiles(x86)%\Windows Kits\8.1\bin\x86;%DXSDK_DIR%\Utilities\bin\x86;%PATH%
-
-setlocal
-set errorCount=0
-set successCount=0
-set debug=0
-
-if "%1" == "debug" (
-    set debug=1
-)
-if "%1" == "release" (
-    set debug=0
-)
-
-:: Shaders for OpenGL ES 2.0 and OpenGL ES 3.0+
-::              | Input file         | Entry point            | Type            | Output file                        | Debug |
-call:BuildShader Passthrough2D11.hlsl VS_Passthrough2D         vs_4_0_level_9_3  compiled\passthrough2d11vs.h         %debug%
-call:BuildShader Passthrough2D11.hlsl PS_PassthroughRGBA2D     ps_4_0_level_9_3  compiled\passthroughrgba2d11ps.h     %debug%
-call:BuildShader Passthrough2D11.hlsl PS_PassthroughRGBA2DMS   ps_4_1            compiled\passthroughrgba2dms11ps.h   %debug%
-call:BuildShader Passthrough2D11.hlsl PS_PassthroughRGB2D      ps_4_0_level_9_3  compiled\passthroughrgb2d11ps.h      %debug%
-call:BuildShader Passthrough2D11.hlsl PS_PassthroughRG2D       ps_4_0_level_9_3  compiled\passthroughrg2d11ps.h       %debug%
-call:BuildShader Passthrough2D11.hlsl PS_PassthroughR2D        ps_4_0_level_9_3  compiled\passthroughr2d11ps.h        %debug%
-call:BuildShader Passthrough2D11.hlsl PS_PassthroughLum2D      ps_4_0_level_9_3  compiled\passthroughlum2d11ps.h      %debug%
-call:BuildShader Passthrough2D11.hlsl PS_PassthroughLumAlpha2D ps_4_0_level_9_3  compiled\passthroughlumalpha2d11ps.h %debug%
-
-call:BuildShader MultiplyAlpha.hlsl PS_FtoF_PM_RGBA ps_4_0 compiled\multiplyalpha_ftof_pm_rgba_ps.h %debug%
-call:BuildShader MultiplyAlpha.hlsl PS_FtoF_UM_RGBA ps_4_0 compiled\multiplyalpha_ftof_um_rgba_ps.h %debug%
-call:BuildShader MultiplyAlpha.hlsl PS_FtoF_PM_RGB  ps_4_0 compiled\multiplyalpha_ftof_pm_rgb_ps.h  %debug%
-call:BuildShader MultiplyAlpha.hlsl PS_FtoF_UM_RGB  ps_4_0 compiled\multiplyalpha_ftof_um_rgb_ps.h  %debug%
-call:BuildShader MultiplyAlpha.hlsl PS_FtoU_PT_RGBA ps_4_0 compiled\multiplyalpha_ftou_pt_rgba_ps.h %debug%
-call:BuildShader MultiplyAlpha.hlsl PS_FtoU_PM_RGBA ps_4_0 compiled\multiplyalpha_ftou_pm_rgba_ps.h %debug%
-call:BuildShader MultiplyAlpha.hlsl PS_FtoU_UM_RGBA ps_4_0 compiled\multiplyalpha_ftou_um_rgba_ps.h %debug%
-call:BuildShader MultiplyAlpha.hlsl PS_FtoU_PT_RGB  ps_4_0 compiled\multiplyalpha_ftou_pt_rgb_ps.h  %debug%
-call:BuildShader MultiplyAlpha.hlsl PS_FtoU_PM_RGB  ps_4_0 compiled\multiplyalpha_ftou_pm_rgb_ps.h  %debug%
-call:BuildShader MultiplyAlpha.hlsl PS_FtoU_UM_RGB  ps_4_0 compiled\multiplyalpha_ftou_um_rgb_ps.h  %debug%
-call:BuildShader MultiplyAlpha.hlsl PS_FtoF_PM_LUMA ps_4_0 compiled\multiplyalpha_ftof_pm_luma_ps.h  %debug%
-call:BuildShader MultiplyAlpha.hlsl PS_FtoF_UM_LUMA ps_4_0 compiled\multiplyalpha_ftof_um_luma_ps.h  %debug%
-call:BuildShader MultiplyAlpha.hlsl PS_FtoF_PM_LUMAALPHA   ps_4_0 compiled\multiplyalpha_ftof_pm_lumaalpha_ps.h  %debug%
-call:BuildShader MultiplyAlpha.hlsl PS_FtoF_UM_LUMAALPHA   ps_4_0 compiled\multiplyalpha_ftof_um_lumaalpha_ps.h  %debug%
-
-call:BuildShader Clear11.hlsl           VS_Clear_FL9             vs_4_0_level_9_3  compiled\clear11_fl9vs.h             %debug%
-call:BuildShader Clear11.hlsl           PS_ClearFloat_FL9        ps_4_0_level_9_3  compiled\clearfloat11_fl9ps.h        %debug%
-
-call:BuildShader Clear11.hlsl           VS_Clear                 vs_4_0            compiled\clear11vs.h                 %debug%
-call:BuildShader Clear11.hlsl           VS_Multiview_Clear                 vs_4_0            compiled\clear11multiviewvs.h                 %debug%
-call:BuildShader Clear11.hlsl           GS_Multiview_Clear                 gs_4_0            compiled\clear11multiviewgs.h                 %debug%
-call:BuildShader Clear11.hlsl           PS_ClearDepth            ps_4_0            compiled\cleardepth11ps.h            %debug%
-call:BuildShader Clear11.hlsl           PS_ClearFloat1           ps_4_0            compiled\clearfloat11ps1.h           %debug%
-call:BuildShader Clear11.hlsl           PS_ClearFloat2           ps_4_0            compiled\clearfloat11ps2.h           %debug%
-call:BuildShader Clear11.hlsl           PS_ClearFloat3           ps_4_0            compiled\clearfloat11ps3.h           %debug%
-call:BuildShader Clear11.hlsl           PS_ClearFloat4           ps_4_0            compiled\clearfloat11ps4.h           %debug%
-call:BuildShader Clear11.hlsl           PS_ClearFloat5           ps_4_0            compiled\clearfloat11ps5.h           %debug%
-call:BuildShader Clear11.hlsl           PS_ClearFloat6           ps_4_0            compiled\clearfloat11ps6.h           %debug%
-call:BuildShader Clear11.hlsl           PS_ClearFloat7           ps_4_0            compiled\clearfloat11ps7.h           %debug%
-call:BuildShader Clear11.hlsl           PS_ClearFloat8           ps_4_0            compiled\clearfloat11ps8.h           %debug%
-
-:: Shaders for OpenGL ES 3.0+ only
-::              | Input file               | Entry point            | Type   | Output file                        | Debug |
-call:BuildShader Passthrough2D11.hlsl       PS_PassthroughDepth2D    ps_4_0   compiled\passthroughdepth2d11ps.h    %debug%
-call:BuildShader Passthrough2D11.hlsl       PS_PassthroughRGBA2DUI   ps_4_0   compiled\passthroughrgba2dui11ps.h   %debug%
-call:BuildShader Passthrough2D11.hlsl       PS_PassthroughRGBA2DI    ps_4_0   compiled\passthroughrgba2di11ps.h    %debug%
-call:BuildShader Passthrough2D11.hlsl       PS_PassthroughRGB2DUI    ps_4_0   compiled\passthroughrgb2dui11ps.h    %debug%
-call:BuildShader Passthrough2D11.hlsl       PS_PassthroughRGB2DI     ps_4_0   compiled\passthroughrgb2di11ps.h     %debug%
-call:BuildShader Passthrough2D11.hlsl       PS_PassthroughRG2DUI     ps_4_0   compiled\passthroughrg2dui11ps.h     %debug%
-call:BuildShader Passthrough2D11.hlsl       PS_PassthroughRG2DI      ps_4_0   compiled\passthroughrg2di11ps.h      %debug%
-call:BuildShader Passthrough2D11.hlsl       PS_PassthroughR2DUI      ps_4_0   compiled\passthroughr2dui11ps.h      %debug%
-call:BuildShader Passthrough2D11.hlsl       PS_PassthroughR2DI       ps_4_0   compiled\passthroughr2di11ps.h       %debug%
-
-call:BuildShader Passthrough3D11.hlsl       VS_Passthrough3D         vs_4_0   compiled\passthrough3d11vs.h         %debug%
-call:BuildShader Passthrough3D11.hlsl       GS_Passthrough3D         gs_4_0   compiled\passthrough3d11gs.h         %debug%
-call:BuildShader Passthrough3D11.hlsl       PS_PassthroughRGBA3D     ps_4_0   compiled\passthroughrgba3d11ps.h     %debug%
-call:BuildShader Passthrough3D11.hlsl       PS_PassthroughRGBA3DUI   ps_4_0   compiled\passthroughrgba3dui11ps.h   %debug%
-call:BuildShader Passthrough3D11.hlsl       PS_PassthroughRGBA3DI    ps_4_0   compiled\passthroughrgba3di11ps.h    %debug%
-call:BuildShader Passthrough3D11.hlsl       PS_PassthroughRGB3D      ps_4_0   compiled\passthroughrgb3d11ps.h      %debug%
-call:BuildShader Passthrough3D11.hlsl       PS_PassthroughRGB3DUI    ps_4_0   compiled\passthroughrgb3dui11ps.h    %debug%
-call:BuildShader Passthrough3D11.hlsl       PS_PassthroughRGB3DI     ps_4_0   compiled\passthroughrgb3di11ps.h     %debug%
-call:BuildShader Passthrough3D11.hlsl       PS_PassthroughRG3D       ps_4_0   compiled\passthroughrg3d11ps.h       %debug%
-call:BuildShader Passthrough3D11.hlsl       PS_PassthroughRG3DUI     ps_4_0   compiled\passthroughrg3dui11ps.h     %debug%
-call:BuildShader Passthrough3D11.hlsl       PS_PassthroughRG3DI      ps_4_0   compiled\passthroughrg3di11ps.h      %debug%
-call:BuildShader Passthrough3D11.hlsl       PS_PassthroughR3D        ps_4_0   compiled\passthroughr3d11ps.h        %debug%
-call:BuildShader Passthrough3D11.hlsl       PS_PassthroughR3DUI      ps_4_0   compiled\passthroughr3dui11ps.h      %debug%
-call:BuildShader Passthrough3D11.hlsl       PS_PassthroughR3DI       ps_4_0   compiled\passthroughr3di11ps.h       %debug%
-call:BuildShader Passthrough3D11.hlsl       PS_PassthroughLum3D      ps_4_0   compiled\passthroughlum3d11ps.h      %debug%
-call:BuildShader Passthrough3D11.hlsl       PS_PassthroughLumAlpha3D ps_4_0   compiled\passthroughlumalpha3d11ps.h %debug%
-
-call:BuildShader Swizzle11.hlsl             PS_SwizzleF2D            ps_4_0   compiled\swizzlef2dps.h              %debug%
-call:BuildShader Swizzle11.hlsl             PS_SwizzleI2D            ps_4_0   compiled\swizzlei2dps.h              %debug%
-call:BuildShader Swizzle11.hlsl             PS_SwizzleUI2D           ps_4_0   compiled\swizzleui2dps.h             %debug%
-
-call:BuildShader Swizzle11.hlsl             PS_SwizzleF3D            ps_4_0   compiled\swizzlef3dps.h              %debug%
-call:BuildShader Swizzle11.hlsl             PS_SwizzleI3D            ps_4_0   compiled\swizzlei3dps.h              %debug%
-call:BuildShader Swizzle11.hlsl             PS_SwizzleUI3D           ps_4_0   compiled\swizzleui3dps.h             %debug%
-
-call:BuildShader Swizzle11.hlsl             PS_SwizzleF2DArray       ps_4_0   compiled\swizzlef2darrayps.h         %debug%
-call:BuildShader Swizzle11.hlsl             PS_SwizzleI2DArray       ps_4_0   compiled\swizzlei2darrayps.h         %debug%
-call:BuildShader Swizzle11.hlsl             PS_SwizzleUI2DArray      ps_4_0   compiled\swizzleui2darrayps.h        %debug%
-
-call:BuildShader Clear11.hlsl               PS_ClearUint1            ps_4_0   compiled\clearuint11ps1.h            %debug%
-call:BuildShader Clear11.hlsl               PS_ClearUint2            ps_4_0   compiled\clearuint11ps2.h            %debug%
-call:BuildShader Clear11.hlsl               PS_ClearUint3            ps_4_0   compiled\clearuint11ps3.h            %debug%
-call:BuildShader Clear11.hlsl               PS_ClearUint4            ps_4_0   compiled\clearuint11ps4.h            %debug%
-call:BuildShader Clear11.hlsl               PS_ClearUint5            ps_4_0   compiled\clearuint11ps5.h            %debug%
-call:BuildShader Clear11.hlsl               PS_ClearUint6            ps_4_0   compiled\clearuint11ps6.h            %debug%
-call:BuildShader Clear11.hlsl               PS_ClearUint7            ps_4_0   compiled\clearuint11ps7.h            %debug%
-call:BuildShader Clear11.hlsl               PS_ClearUint8            ps_4_0   compiled\clearuint11ps8.h            %debug%
-call:BuildShader Clear11.hlsl               PS_ClearSint1            ps_4_0   compiled\clearsint11ps1.h            %debug%
-call:BuildShader Clear11.hlsl               PS_ClearSint2            ps_4_0   compiled\clearsint11ps2.h            %debug%
-call:BuildShader Clear11.hlsl               PS_ClearSint3            ps_4_0   compiled\clearsint11ps3.h            %debug%
-call:BuildShader Clear11.hlsl               PS_ClearSint4            ps_4_0   compiled\clearsint11ps4.h            %debug%
-call:BuildShader Clear11.hlsl               PS_ClearSint5            ps_4_0   compiled\clearsint11ps5.h            %debug%
-call:BuildShader Clear11.hlsl               PS_ClearSint6            ps_4_0   compiled\clearsint11ps6.h            %debug%
-call:BuildShader Clear11.hlsl               PS_ClearSint7            ps_4_0   compiled\clearsint11ps7.h            %debug%
-call:BuildShader Clear11.hlsl               PS_ClearSint8            ps_4_0   compiled\clearsint11ps8.h            %debug%
-
-call:BuildShader BufferToTexture11.hlsl     VS_BufferToTexture       vs_4_0   compiled/buffertotexture11_vs.h      %debug%
-call:BuildShader BufferToTexture11.hlsl     GS_BufferToTexture       gs_4_0   compiled/buffertotexture11_gs.h      %debug%
-call:BuildShader BufferToTexture11.hlsl     PS_BufferToTexture_4F    ps_4_0   compiled/buffertotexture11_ps_4f.h   %debug%
-call:BuildShader BufferToTexture11.hlsl     PS_BufferToTexture_4I    ps_4_0   compiled/buffertotexture11_ps_4i.h   %debug%
-call:BuildShader BufferToTexture11.hlsl     PS_BufferToTexture_4UI   ps_4_0   compiled/buffertotexture11_ps_4ui.h  %debug%
-
-call:BuildShader ResolveDepthStencil.hlsl   VS_ResolveDepthStencil   vs_4_1   compiled/resolvedepthstencil11_vs.h  %debug%
-call:BuildShader ResolveDepthStencil.hlsl   PS_ResolveDepth          ps_4_1   compiled/resolvedepth11_ps.h         %debug%
-call:BuildShader ResolveDepthStencil.hlsl   PS_ResolveDepthStencil   ps_4_1   compiled/resolvedepthstencil11_ps.h  %debug%
-call:BuildShader ResolveDepthStencil.hlsl   PS_ResolveStencil        ps_4_1   compiled/resolvestencil11_ps.h       %debug%
-
-echo.
-
-if %successCount% GTR 0 (
-   echo %successCount% shaders compiled successfully.
-)
-if %errorCount% GTR 0 (
-   echo There were %errorCount% shader compilation errors.
-)
-
-endlocal
-exit /b
-
-:BuildShader
-set input=%~1
-set entry=%~2
-set type=%~3
-set output=%~4
-set debug=%~5
-
-if %debug% == 0 (
-    set "buildCMD=fxc /nologo /E %entry% /T %type% /Fh %output% %input%"
-) else (
-    set "buildCMD=fxc /nologo /Zi /Od /E %entry% /T %type% /Fh %output% %input%"
-)
-
-set error=0
-%buildCMD% || set error=1
-
-if %error% == 0 (
-    set /a successCount=%successCount%+1
-) else (
-    set /a errorCount=%errorCount%+1
-)
-
-exit /b
+@ECHO OFF
+REM
+REM Copyright (c) 2013 The ANGLE Project Authors. All rights reserved.
+REM Use of this source code is governed by a BSD-style license that can be
+REM found in the LICENSE file.
+REM
+
+PATH %ProgramFiles(x86)%\Windows Kits\8.1\bin\x86;%DXSDK_DIR%\Utilities\bin\x86;%PATH%
+
+setlocal
+set errorCount=0
+set successCount=0
+set debug=0
+
+if "%1" == "debug" (
+    set debug=1
+)
+if "%1" == "release" (
+    set debug=0
+)
+
+:: Shaders for OpenGL ES 2.0 and OpenGL ES 3.0+
+::              | Input file         | Entry point            | Type            | Output file                        | Debug |
+call:BuildShader Passthrough2D11.hlsl VS_Passthrough2D         vs_4_0_level_9_3  compiled\passthrough2d11vs.h         %debug%
+call:BuildShader Passthrough2D11.hlsl PS_PassthroughRGBA2D     ps_4_0_level_9_3  compiled\passthroughrgba2d11ps.h     %debug%
+call:BuildShader Passthrough2D11.hlsl PS_PassthroughA2D        ps_4_0_level_9_3  compiled\passthrougha2d11ps.h        %debug%
+call:BuildShader Passthrough2D11.hlsl PS_PassthroughRGBA2DMS   ps_4_1            compiled\passthroughrgba2dms11ps.h   %debug%
+call:BuildShader Passthrough2D11.hlsl PS_PassthroughRGB2D      ps_4_0_level_9_3  compiled\passthroughrgb2d11ps.h      %debug%
+call:BuildShader Passthrough2D11.hlsl PS_PassthroughRG2D       ps_4_0_level_9_3  compiled\passthroughrg2d11ps.h       %debug%
+call:BuildShader Passthrough2D11.hlsl PS_PassthroughR2D        ps_4_0_level_9_3  compiled\passthroughr2d11ps.h        %debug%
+call:BuildShader Passthrough2D11.hlsl PS_PassthroughLum2D      ps_4_0_level_9_3  compiled\passthroughlum2d11ps.h      %debug%
+call:BuildShader Passthrough2D11.hlsl PS_PassthroughLumAlpha2D ps_4_0_level_9_3  compiled\passthroughlumalpha2d11ps.h %debug%
+
+call:BuildShader MultiplyAlpha.hlsl PS_FtoF_PM_RGBA ps_4_0 compiled\multiplyalpha_ftof_pm_rgba_ps.h %debug%
+call:BuildShader MultiplyAlpha.hlsl PS_FtoF_UM_RGBA ps_4_0 compiled\multiplyalpha_ftof_um_rgba_ps.h %debug%
+call:BuildShader MultiplyAlpha.hlsl PS_FtoF_PM_RGB  ps_4_0 compiled\multiplyalpha_ftof_pm_rgb_ps.h  %debug%
+call:BuildShader MultiplyAlpha.hlsl PS_FtoF_UM_RGB  ps_4_0 compiled\multiplyalpha_ftof_um_rgb_ps.h  %debug%
+call:BuildShader MultiplyAlpha.hlsl PS_FtoU_PT_RGBA ps_4_0 compiled\multiplyalpha_ftou_pt_rgba_ps.h %debug%
+call:BuildShader MultiplyAlpha.hlsl PS_FtoU_PM_RGBA ps_4_0 compiled\multiplyalpha_ftou_pm_rgba_ps.h %debug%
+call:BuildShader MultiplyAlpha.hlsl PS_FtoU_UM_RGBA ps_4_0 compiled\multiplyalpha_ftou_um_rgba_ps.h %debug%
+call:BuildShader MultiplyAlpha.hlsl PS_FtoU_PT_RGB  ps_4_0 compiled\multiplyalpha_ftou_pt_rgb_ps.h  %debug%
+call:BuildShader MultiplyAlpha.hlsl PS_FtoU_PM_RGB  ps_4_0 compiled\multiplyalpha_ftou_pm_rgb_ps.h  %debug%
+call:BuildShader MultiplyAlpha.hlsl PS_FtoU_UM_RGB  ps_4_0 compiled\multiplyalpha_ftou_um_rgb_ps.h  %debug%
+call:BuildShader MultiplyAlpha.hlsl PS_FtoF_PM_LUMA ps_4_0 compiled\multiplyalpha_ftof_pm_luma_ps.h  %debug%
+call:BuildShader MultiplyAlpha.hlsl PS_FtoF_UM_LUMA ps_4_0 compiled\multiplyalpha_ftof_um_luma_ps.h  %debug%
+call:BuildShader MultiplyAlpha.hlsl PS_FtoF_PM_LUMAALPHA   ps_4_0 compiled\multiplyalpha_ftof_pm_lumaalpha_ps.h  %debug%
+call:BuildShader MultiplyAlpha.hlsl PS_FtoF_UM_LUMAALPHA   ps_4_0 compiled\multiplyalpha_ftof_um_lumaalpha_ps.h  %debug%
+
+call:BuildShader Clear11.hlsl           VS_Clear_FL9             vs_4_0_level_9_3  compiled\clear11_fl9vs.h             %debug%
+call:BuildShader Clear11.hlsl           PS_ClearFloat_FL9        ps_4_0_level_9_3  compiled\clearfloat11_fl9ps.h        %debug%
+
+call:BuildShader Clear11.hlsl           VS_Clear                 vs_4_0            compiled\clear11vs.h                 %debug%
+call:BuildShader Clear11.hlsl           VS_Multiview_Clear                 vs_4_0            compiled\clear11multiviewvs.h                 %debug%
+call:BuildShader Clear11.hlsl           GS_Multiview_Clear                 gs_4_0            compiled\clear11multiviewgs.h                 %debug%
+call:BuildShader Clear11.hlsl           PS_ClearDepth            ps_4_0            compiled\cleardepth11ps.h            %debug%
+call:BuildShader Clear11.hlsl           PS_ClearFloat1           ps_4_0            compiled\clearfloat11ps1.h           %debug%
+call:BuildShader Clear11.hlsl           PS_ClearFloat2           ps_4_0            compiled\clearfloat11ps2.h           %debug%
+call:BuildShader Clear11.hlsl           PS_ClearFloat3           ps_4_0            compiled\clearfloat11ps3.h           %debug%
+call:BuildShader Clear11.hlsl           PS_ClearFloat4           ps_4_0            compiled\clearfloat11ps4.h           %debug%
+call:BuildShader Clear11.hlsl           PS_ClearFloat5           ps_4_0            compiled\clearfloat11ps5.h           %debug%
+call:BuildShader Clear11.hlsl           PS_ClearFloat6           ps_4_0            compiled\clearfloat11ps6.h           %debug%
+call:BuildShader Clear11.hlsl           PS_ClearFloat7           ps_4_0            compiled\clearfloat11ps7.h           %debug%
+call:BuildShader Clear11.hlsl           PS_ClearFloat8           ps_4_0            compiled\clearfloat11ps8.h           %debug%
+
+:: Shaders for OpenGL ES 3.0+ only
+::              | Input file               | Entry point            | Type   | Output file                        | Debug |
+call:BuildShader Passthrough2D11.hlsl       PS_PassthroughDepth2D    ps_4_0   compiled\passthroughdepth2d11ps.h    %debug%
+call:BuildShader Passthrough2D11.hlsl       PS_PassthroughRGBA2DUI   ps_4_0   compiled\passthroughrgba2dui11ps.h   %debug%
+call:BuildShader Passthrough2D11.hlsl       PS_PassthroughRGBA2DI    ps_4_0   compiled\passthroughrgba2di11ps.h    %debug%
+call:BuildShader Passthrough2D11.hlsl       PS_PassthroughRGB2DUI    ps_4_0   compiled\passthroughrgb2dui11ps.h    %debug%
+call:BuildShader Passthrough2D11.hlsl       PS_PassthroughRGB2DI     ps_4_0   compiled\passthroughrgb2di11ps.h     %debug%
+call:BuildShader Passthrough2D11.hlsl       PS_PassthroughRG2DUI     ps_4_0   compiled\passthroughrg2dui11ps.h     %debug%
+call:BuildShader Passthrough2D11.hlsl       PS_PassthroughRG2DI      ps_4_0   compiled\passthroughrg2di11ps.h      %debug%
+call:BuildShader Passthrough2D11.hlsl       PS_PassthroughR2DUI      ps_4_0   compiled\passthroughr2dui11ps.h      %debug%
+call:BuildShader Passthrough2D11.hlsl       PS_PassthroughR2DI       ps_4_0   compiled\passthroughr2di11ps.h       %debug%
+
+call:BuildShader Passthrough3D11.hlsl       VS_Passthrough3D         vs_4_0   compiled\passthrough3d11vs.h         %debug%
+call:BuildShader Passthrough3D11.hlsl       GS_Passthrough3D         gs_4_0   compiled\passthrough3d11gs.h         %debug%
+call:BuildShader Passthrough3D11.hlsl       PS_PassthroughRGBA3D     ps_4_0   compiled\passthroughrgba3d11ps.h     %debug%
+call:BuildShader Passthrough3D11.hlsl       PS_PassthroughRGBA3DUI   ps_4_0   compiled\passthroughrgba3dui11ps.h   %debug%
+call:BuildShader Passthrough3D11.hlsl       PS_PassthroughRGBA3DI    ps_4_0   compiled\passthroughrgba3di11ps.h    %debug%
+call:BuildShader Passthrough3D11.hlsl       PS_PassthroughRGB3D      ps_4_0   compiled\passthroughrgb3d11ps.h      %debug%
+call:BuildShader Passthrough3D11.hlsl       PS_PassthroughRGB3DUI    ps_4_0   compiled\passthroughrgb3dui11ps.h    %debug%
+call:BuildShader Passthrough3D11.hlsl       PS_PassthroughRGB3DI     ps_4_0   compiled\passthroughrgb3di11ps.h     %debug%
+call:BuildShader Passthrough3D11.hlsl       PS_PassthroughRG3D       ps_4_0   compiled\passthroughrg3d11ps.h       %debug%
+call:BuildShader Passthrough3D11.hlsl       PS_PassthroughRG3DUI     ps_4_0   compiled\passthroughrg3dui11ps.h     %debug%
+call:BuildShader Passthrough3D11.hlsl       PS_PassthroughRG3DI      ps_4_0   compiled\passthroughrg3di11ps.h      %debug%
+call:BuildShader Passthrough3D11.hlsl       PS_PassthroughR3D        ps_4_0   compiled\passthroughr3d11ps.h        %debug%
+call:BuildShader Passthrough3D11.hlsl       PS_PassthroughR3DUI      ps_4_0   compiled\passthroughr3dui11ps.h      %debug%
+call:BuildShader Passthrough3D11.hlsl       PS_PassthroughR3DI       ps_4_0   compiled\passthroughr3di11ps.h       %debug%
+call:BuildShader Passthrough3D11.hlsl       PS_PassthroughLum3D      ps_4_0   compiled\passthroughlum3d11ps.h      %debug%
+call:BuildShader Passthrough3D11.hlsl       PS_PassthroughLumAlpha3D ps_4_0   compiled\passthroughlumalpha3d11ps.h %debug%
+
+call:BuildShader Swizzle11.hlsl             PS_SwizzleF2D            ps_4_0   compiled\swizzlef2dps.h              %debug%
+call:BuildShader Swizzle11.hlsl             PS_SwizzleI2D            ps_4_0   compiled\swizzlei2dps.h              %debug%
+call:BuildShader Swizzle11.hlsl             PS_SwizzleUI2D           ps_4_0   compiled\swizzleui2dps.h             %debug%
+
+call:BuildShader Swizzle11.hlsl             PS_SwizzleF3D            ps_4_0   compiled\swizzlef3dps.h              %debug%
+call:BuildShader Swizzle11.hlsl             PS_SwizzleI3D            ps_4_0   compiled\swizzlei3dps.h              %debug%
+call:BuildShader Swizzle11.hlsl             PS_SwizzleUI3D           ps_4_0   compiled\swizzleui3dps.h             %debug%
+
+call:BuildShader Swizzle11.hlsl             PS_SwizzleF2DArray       ps_4_0   compiled\swizzlef2darrayps.h         %debug%
+call:BuildShader Swizzle11.hlsl             PS_SwizzleI2DArray       ps_4_0   compiled\swizzlei2darrayps.h         %debug%
+call:BuildShader Swizzle11.hlsl             PS_SwizzleUI2DArray      ps_4_0   compiled\swizzleui2darrayps.h        %debug%
+
+call:BuildShader Clear11.hlsl               PS_ClearUint1            ps_4_0   compiled\clearuint11ps1.h            %debug%
+call:BuildShader Clear11.hlsl               PS_ClearUint2            ps_4_0   compiled\clearuint11ps2.h            %debug%
+call:BuildShader Clear11.hlsl               PS_ClearUint3            ps_4_0   compiled\clearuint11ps3.h            %debug%
+call:BuildShader Clear11.hlsl               PS_ClearUint4            ps_4_0   compiled\clearuint11ps4.h            %debug%
+call:BuildShader Clear11.hlsl               PS_ClearUint5            ps_4_0   compiled\clearuint11ps5.h            %debug%
+call:BuildShader Clear11.hlsl               PS_ClearUint6            ps_4_0   compiled\clearuint11ps6.h            %debug%
+call:BuildShader Clear11.hlsl               PS_ClearUint7            ps_4_0   compiled\clearuint11ps7.h            %debug%
+call:BuildShader Clear11.hlsl               PS_ClearUint8            ps_4_0   compiled\clearuint11ps8.h            %debug%
+call:BuildShader Clear11.hlsl               PS_ClearSint1            ps_4_0   compiled\clearsint11ps1.h            %debug%
+call:BuildShader Clear11.hlsl               PS_ClearSint2            ps_4_0   compiled\clearsint11ps2.h            %debug%
+call:BuildShader Clear11.hlsl               PS_ClearSint3            ps_4_0   compiled\clearsint11ps3.h            %debug%
+call:BuildShader Clear11.hlsl               PS_ClearSint4            ps_4_0   compiled\clearsint11ps4.h            %debug%
+call:BuildShader Clear11.hlsl               PS_ClearSint5            ps_4_0   compiled\clearsint11ps5.h            %debug%
+call:BuildShader Clear11.hlsl               PS_ClearSint6            ps_4_0   compiled\clearsint11ps6.h            %debug%
+call:BuildShader Clear11.hlsl               PS_ClearSint7            ps_4_0   compiled\clearsint11ps7.h            %debug%
+call:BuildShader Clear11.hlsl               PS_ClearSint8            ps_4_0   compiled\clearsint11ps8.h            %debug%
+
+call:BuildShader BufferToTexture11.hlsl     VS_BufferToTexture       vs_4_0   compiled/buffertotexture11_vs.h      %debug%
+call:BuildShader BufferToTexture11.hlsl     GS_BufferToTexture       gs_4_0   compiled/buffertotexture11_gs.h      %debug%
+call:BuildShader BufferToTexture11.hlsl     PS_BufferToTexture_4F    ps_4_0   compiled/buffertotexture11_ps_4f.h   %debug%
+call:BuildShader BufferToTexture11.hlsl     PS_BufferToTexture_4I    ps_4_0   compiled/buffertotexture11_ps_4i.h   %debug%
+call:BuildShader BufferToTexture11.hlsl     PS_BufferToTexture_4UI   ps_4_0   compiled/buffertotexture11_ps_4ui.h  %debug%
+
+call:BuildShader ResolveDepthStencil.hlsl   VS_ResolveDepthStencil   vs_4_1   compiled/resolvedepthstencil11_vs.h  %debug%
+call:BuildShader ResolveDepthStencil.hlsl   PS_ResolveDepth          ps_4_1   compiled/resolvedepth11_ps.h         %debug%
+call:BuildShader ResolveDepthStencil.hlsl   PS_ResolveDepthStencil   ps_4_1   compiled/resolvedepthstencil11_ps.h  %debug%
+call:BuildShader ResolveDepthStencil.hlsl   PS_ResolveStencil        ps_4_1   compiled/resolvestencil11_ps.h       %debug%
+
+echo.
+
+if %successCount% GTR 0 (
+   echo %successCount% shaders compiled successfully.
+)
+if %errorCount% GTR 0 (
+   echo There were %errorCount% shader compilation errors.
+)
+
+endlocal
+exit /b
+
+:BuildShader
+set input=%~1
+set entry=%~2
+set type=%~3
+set output=%~4
+set debug=%~5
+
+if %debug% == 0 (
+    set "buildCMD=fxc /nologo /E %entry% /T %type% /Fh %output% %input%"
+) else (
+    set "buildCMD=fxc /nologo /Zi /Od /E %entry% /T %type% /Fh %output% %input%"
+)
+
+set error=0
+%buildCMD% || set error=1
+
+if %error% == 0 (
+    set /a successCount=%successCount%+1
+) else (
+    set /a errorCount=%errorCount%+1
+)
+
+exit /b
--- a/gfx/angle/src/libANGLE/renderer/d3d/d3d11/texture_format_data.json
+++ b/gfx/angle/src/libANGLE/renderer/d3d/d3d11/texture_format_data.json
@@ -9,16 +9,17 @@
     "componentType": "unorm",
     "bits": { "alpha": 8 },
     "supportTest": "OnlyFL10Plus(deviceCaps)",
     "fallbackFormat": "R8G8B8A8_UNORM"
   },
   "R8G8B8A8_UNORM": {
     "texFormat": "DXGI_FORMAT_R8G8B8A8_UNORM",
     "srvFormat": "DXGI_FORMAT_R8G8B8A8_UNORM",
+    "uavFormat": "DXGI_FORMAT_R8G8B8A8_UNORM",
     "rtvFormat": "DXGI_FORMAT_R8G8B8A8_UNORM",
     "channels": "rgba",
     "componentType": "unorm",
     "bits": { "red": 8, "green": 8, "blue": 8, "alpha": 8 },
     "glInternalFormat": "GL_RGBA8"
   },
   "R16G16B16A16_UNORM": {
     "texFormat": "DXGI_FORMAT_R16G16B16A16_UNORM",
@@ -27,40 +28,51 @@
     "channels": "rgba",
     "componentType": "unorm",
     "bits": { "red": 16, "green": 16, "blue": 16, "alpha": 16 },
     "glInternalFormat": "GL_RGBA16_EXT"
   },
   "R16G16B16A16_FLOAT": {
     "texFormat": "DXGI_FORMAT_R16G16B16A16_FLOAT",
     "srvFormat": "DXGI_FORMAT_R16G16B16A16_FLOAT",
+    "uavFormat": "DXGI_FORMAT_R16G16B16A16_FLOAT",
     "rtvFormat": "DXGI_FORMAT_R16G16B16A16_FLOAT",
     "channels": "rgba",
     "componentType": "float",
     "bits": { "red": 16, "green": 16, "blue": 16, "alpha": 16 },
     "glInternalFormat": "GL_RGBA16F"
   },
   "R32G32B32A32_FLOAT": {
     "texFormat": "DXGI_FORMAT_R32G32B32A32_FLOAT",
     "srvFormat": "DXGI_FORMAT_R32G32B32A32_FLOAT",
+    "uavFormat": "DXGI_FORMAT_R32G32B32A32_FLOAT",
     "rtvFormat": "DXGI_FORMAT_R32G32B32A32_FLOAT",
     "channels": "rgba",
     "componentType": "float",
     "bits": { "red": 32, "green": 32, "blue": 32, "alpha": 32 },
     "glInternalFormat": "GL_RGBA32F"
   },
   "B8G8R8A8_UNORM": {
     "texFormat": "DXGI_FORMAT_B8G8R8A8_UNORM",
     "srvFormat": "DXGI_FORMAT_B8G8R8A8_UNORM",
     "rtvFormat": "DXGI_FORMAT_B8G8R8A8_UNORM",
     "channels": "bgra",
     "componentType": "unorm",
     "bits": { "red": 8, "green": 8, "blue": 8, "alpha": 8 },
     "glInternalFormat": "GL_BGRA8_EXT"
   },
+  "B8G8R8A8_UNORM_SRGB": {
+    "texFormat": "DXGI_FORMAT_B8G8R8A8_UNORM_SRGB",
+    "srvFormat": "DXGI_FORMAT_B8G8R8A8_UNORM_SRGB",
+    "rtvFormat": "DXGI_FORMAT_B8G8R8A8_UNORM_SRGB",
+    "channels": "bgra",
+    "componentType": "unorm",
+    "bits": {"red": 8, "green": 8, "blue": 8,"alpha": 8},
+    "siwzzleFormat": "GL_RGBA8"
+  },
   "BC1_RGBA_UNORM_BLOCK": {
     "texFormat": "DXGI_FORMAT_BC1_UNORM",
     "srvFormat": "DXGI_FORMAT_BC1_UNORM",
     "channels": "rgba",
     "componentType": "unorm",
     "swizzleFormat": "GL_RGBA8"
   },
   "BC1_RGB_UNORM_BLOCK": {
@@ -190,34 +202,37 @@
     "channels": "r",
     "componentType": "uint",
     "bits": { "red": 16 },
     "glInternalFormat": "GL_R16UI"
   },
   "R32_FLOAT": {
     "texFormat": "DXGI_FORMAT_R32_FLOAT",
     "srvFormat": "DXGI_FORMAT_R32_FLOAT",
+    "uavFormat": "DXGI_FORMAT_R32_FLOAT",
     "rtvFormat": "DXGI_FORMAT_R32_FLOAT",
     "channels": "r",
     "componentType": "float",
     "bits": { "red": 32 },
     "glInternalFormat": "GL_R32F"
   },
   "R32_SINT": {
     "texFormat": "DXGI_FORMAT_R32_SINT",
     "srvFormat": "DXGI_FORMAT_R32_SINT",
+    "uavFormat": "DXGI_FORMAT_R32_SINT",
     "rtvFormat": "DXGI_FORMAT_R32_SINT",
     "channels": "r",
     "componentType": "int",
     "bits": { "red": 32 },
     "glInternalFormat": "GL_R32I"
   },
   "R32_UINT": {
     "texFormat": "DXGI_FORMAT_R32_UINT",
     "srvFormat": "DXGI_FORMAT_R32_UINT",
+    "uavFormat": "DXGI_FORMAT_R32_UINT",
     "rtvFormat": "DXGI_FORMAT_R32_UINT",
     "channels": "r",
     "componentType": "uint",
     "bits": { "red": 32 },
     "glInternalFormat": "GL_R32UI"
   },
   "R8_UNORM": {
     "texFormat": "DXGI_FORMAT_R8_UNORM",
@@ -359,43 +374,47 @@
     "channels": "rgba",
     "componentType": "uint",
     "bits": { "red": 10, "green": 10, "blue": 10, "alpha": 2 },
     "glInternalFormat": "GL_RGB10_A2UI"
   },
   "R16G16B16A16_SINT": {
     "texFormat": "DXGI_FORMAT_R16G16B16A16_SINT",
     "srvFormat": "DXGI_FORMAT_R16G16B16A16_SINT",
+    "uavFormat": "DXGI_FORMAT_R16G16B16A16_SINT",
     "rtvFormat": "DXGI_FORMAT_R16G16B16A16_SINT",
     "channels": "rgba",
     "componentType": "int",
     "bits": { "red": 16, "green": 16, "blue": 16, "alpha": 16 },
     "glInternalFormat": "GL_RGBA16I"
   },
   "R16G16B16A16_UINT": {
     "texFormat": "DXGI_FORMAT_R16G16B16A16_UINT",
     "srvFormat": "DXGI_FORMAT_R16G16B16A16_UINT",
+    "uavFormat": "DXGI_FORMAT_R16G16B16A16_UINT",
     "rtvFormat": "DXGI_FORMAT_R16G16B16A16_UINT",
     "channels": "rgba",
     "componentType": "uint",
     "bits": { "red": 16, "green": 16, "blue": 16, "alpha": 16 },
     "glInternalFormat": "GL_RGBA16UI"
   },
   "R32G32B32A32_SINT": {
     "texFormat": "DXGI_FORMAT_R32G32B32A32_SINT",
     "srvFormat": "DXGI_FORMAT_R32G32B32A32_SINT",
+    "uavFormat": "DXGI_FORMAT_R32G32B32A32_SINT",
     "rtvFormat": "DXGI_FORMAT_R32G32B32A32_SINT",
     "channels": "rgba",
     "componentType": "int",
     "bits": { "red": 32, "green": 32, "blue": 32, "alpha": 32 },
     "glInternalFormat": "GL_RGBA32I"
   },
   "R32G32B32A32_UINT": {
     "texFormat": "DXGI_FORMAT_R32G32B32A32_UINT",
     "srvFormat": "DXGI_FORMAT_R32G32B32A32_UINT",
+    "uavFormat": "DXGI_FORMAT_R32G32B32A32_UINT",
     "rtvFormat": "DXGI_FORMAT_R32G32B32A32_UINT",
     "channels": "rgba",
     "componentType": "uint",
     "bits": { "red": 32, "green": 32, "blue": 32, "alpha": 32 },
     "glInternalFormat": "GL_RGBA32UI"
   },
   "B5G6R5_UNORM": {
     "texFormat": "DXGI_FORMAT_B5G6R5_UNORM",
@@ -424,25 +443,27 @@
     "channels": "rgba",
     "componentType": "int",
     "bits": { "red": 8, "green": 8, "blue": 8, "alpha": 8 },
     "glInternalFormat": "GL_RGBA8I"
   },
   "R8G8B8A8_UINT": {
     "texFormat": "DXGI_FORMAT_R8G8B8A8_UINT",
     "srvFormat": "DXGI_FORMAT_R8G8B8A8_UINT",
+    "uavFormat": "DXGI_FORMAT_R8G8B8A8_UINT",
     "rtvFormat": "DXGI_FORMAT_R8G8B8A8_UINT",
     "channels": "rgba",
     "componentType": "uint",
     "bits": { "red": 8, "green": 8, "blue": 8, "alpha": 8 },
     "glInternalFormat": "GL_RGBA8UI"
   },
   "R8G8B8A8_SNORM": {
     "texFormat": "DXGI_FORMAT_R8G8B8A8_SNORM",
     "srvFormat": "DXGI_FORMAT_R8G8B8A8_SNORM",
+    "uavFormat": "DXGI_FORMAT_R8G8B8A8_SNORM",
     "channels": "rgba",
     "componentType": "snorm",
     "bits": { "red": 8, "green": 8, "blue": 8, "alpha": 8 },
     "glInternalFormat": "GL_RGBA8_SNORM"
   },
   "R9G9B9E5_SHAREDEXP": {
     "texFormat": "DXGI_FORMAT_R9G9B9E5_SHAREDEXP",
     "srvFormat": "DXGI_FORMAT_R9G9B9E5_SHAREDEXP",
--- a/gfx/angle/src/libANGLE/renderer/d3d/d3d11/texture_format_map.json
+++ b/gfx/angle/src/libANGLE/renderer/d3d/d3d11/texture_format_map.json
@@ -1,13 +1,14 @@
 {
   "GL_ALPHA16F_EXT": "R16G16B16A16_FLOAT",
   "GL_ALPHA32F_EXT": "R32G32B32A32_FLOAT",
   "GL_BGR5_A1_ANGLEX": "B8G8R8A8_UNORM",
   "GL_BGRA4_ANGLEX": "B8G8R8A8_UNORM",
+  "GL_BGRA8_SRGB_ANGLEX": "B8G8R8A8_UNORM_SRGB",
   "GL_COMPRESSED_R11_EAC": "R8_UNORM",
   "GL_COMPRESSED_RG11_EAC": "R8G8_UNORM",
   "GL_COMPRESSED_RGB8_ETC2": "R8G8B8A8_UNORM",
   "GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2": "R8G8B8A8_UNORM",
   "GL_COMPRESSED_RGBA8_ETC2_EAC": "R8G8B8A8_UNORM",
   "GL_COMPRESSED_RGBA_ASTC_4x4_KHR": "NONE",
   "GL_COMPRESSED_RGBA_ASTC_5x4_KHR": "NONE",
   "GL_COMPRESSED_RGBA_ASTC_5x5_KHR": "NONE",
--- a/gfx/angle/src/libANGLE/renderer/d3d/d3d11/texture_format_table.h
+++ b/gfx/angle/src/libANGLE/renderer/d3d/d3d11/texture_format_table.h
@@ -32,16 +32,17 @@ namespace d3d11
 // DSVs given a GL internal format.
 struct Format final : private angle::NonCopyable
 {
     constexpr Format();
     constexpr Format(GLenum internalFormat,
                      angle::Format::ID formatID,
                      DXGI_FORMAT texFormat,
                      DXGI_FORMAT srvFormat,
+                     DXGI_FORMAT uavFormat,
                      DXGI_FORMAT rtvFormat,
                      DXGI_FORMAT dsvFormat,
                      DXGI_FORMAT blitSRVFormat,
                      GLenum swizzleFormat,
                      InitializeTextureDataFunction internalFormatInitializer);
 
     static const Format &Get(GLenum internalFormat, const Renderer11DeviceCaps &deviceCaps);
 
@@ -49,52 +50,56 @@ struct Format final : private angle::Non
     LoadFunctionMap getLoadFunctions() const;
     const angle::Format &format() const;
 
     GLenum internalFormat;
     angle::Format::ID formatID;
 
     DXGI_FORMAT texFormat;
     DXGI_FORMAT srvFormat;
+    DXGI_FORMAT uavFormat;
     DXGI_FORMAT rtvFormat;
     DXGI_FORMAT dsvFormat;
 
     DXGI_FORMAT blitSRVFormat;
 
     GLenum swizzleFormat;
 
     InitializeTextureDataFunction dataInitializerFunction;
 };
 
 constexpr Format::Format()
     : internalFormat(GL_NONE),
       formatID(angle::Format::ID::NONE),
       texFormat(DXGI_FORMAT_UNKNOWN),
       srvFormat(DXGI_FORMAT_UNKNOWN),
+      uavFormat(DXGI_FORMAT_UNKNOWN),
       rtvFormat(DXGI_FORMAT_UNKNOWN),
       dsvFormat(DXGI_FORMAT_UNKNOWN),
       blitSRVFormat(DXGI_FORMAT_UNKNOWN),
       swizzleFormat(GL_NONE),
       dataInitializerFunction(nullptr)
 {
 }
 
 constexpr Format::Format(GLenum internalFormat,
                          angle::Format::ID formatID,
                          DXGI_FORMAT texFormat,
                          DXGI_FORMAT srvFormat,
+                         DXGI_FORMAT uavFormat,
                          DXGI_FORMAT rtvFormat,
                          DXGI_FORMAT dsvFormat,
                          DXGI_FORMAT blitSRVFormat,
                          GLenum swizzleFormat,
                          InitializeTextureDataFunction internalFormatInitializer)
     : internalFormat(internalFormat),
       formatID(formatID),
       texFormat(texFormat),
       srvFormat(srvFormat),
+      uavFormat(uavFormat),
       rtvFormat(rtvFormat),
       dsvFormat(dsvFormat),
       blitSRVFormat(blitSRVFormat),
       swizzleFormat(swizzleFormat),
       dataInitializerFunction(internalFormatInitializer)
 {
 }
 
--- a/gfx/angle/src/libANGLE/renderer/d3d/d3d11/texture_format_table_autogen.cpp
+++ b/gfx/angle/src/libANGLE/renderer/d3d/d3d11/texture_format_table_autogen.cpp
@@ -1,12 +1,12 @@
 // GENERATED FILE - DO NOT EDIT.
 // Generated by gen_texture_format_table.py using data from texture_format_data.json
 //
-// Copyright 2016 The ANGLE Project Authors. All rights reserved.
+// 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.
 //
 // texture_format_table:
 //   Queries for full textureFormat information based in internalFormat
 //
 
 #include "libANGLE/renderer/d3d/d3d11/texture_format_table.h"
@@ -35,1878 +35,2034 @@ const Format &Format::Get(GLenum interna
     {
         case GL_ALPHA16F_EXT:
         {
             static constexpr Format info(GL_ALPHA16F_EXT,
                                          angle::Format::ID::R16G16B16A16_FLOAT,
                                          DXGI_FORMAT_R16G16B16A16_FLOAT,
                                          DXGI_FORMAT_R16G16B16A16_FLOAT,
                                          DXGI_FORMAT_R16G16B16A16_FLOAT,
+                                         DXGI_FORMAT_R16G16B16A16_FLOAT,
                                          DXGI_FORMAT_UNKNOWN,
                                          DXGI_FORMAT_R16G16B16A16_FLOAT,
                                          GL_RGBA16F,
                                          nullptr);
             return info;
         }
         case GL_ALPHA32F_EXT:
         {
             static constexpr Format info(GL_ALPHA32F_EXT,
                                          angle::Format::ID::R32G32B32A32_FLOAT,
                                          DXGI_FORMAT_R32G32B32A32_FLOAT,
                                          DXGI_FORMAT_R32G32B32A32_FLOAT,
                                          DXGI_FORMAT_R32G32B32A32_FLOAT,
+                                         DXGI_FORMAT_R32G32B32A32_FLOAT,
                                          DXGI_FORMAT_UNKNOWN,
                                          DXGI_FORMAT_R32G32B32A32_FLOAT,
                                          GL_RGBA32F,
                                          nullptr);
             return info;
         }
         case GL_ALPHA8_EXT:
         {
             if (OnlyFL10Plus(deviceCaps))
             {
                 static constexpr Format info(GL_ALPHA8_EXT,
                                              angle::Format::ID::A8_UNORM,
                                              DXGI_FORMAT_A8_UNORM,
                                              DXGI_FORMAT_A8_UNORM,
+                                             DXGI_FORMAT_UNKNOWN,
                                              DXGI_FORMAT_A8_UNORM,
                                              DXGI_FORMAT_UNKNOWN,
                                              DXGI_FORMAT_A8_UNORM,
                                              GL_RGBA8,
                                              nullptr);
                 return info;
             }
             else
             {
                 static constexpr Format info(GL_ALPHA8_EXT,
                                              angle::Format::ID::R8G8B8A8_UNORM,
                                              DXGI_FORMAT_R8G8B8A8_UNORM,
                                              DXGI_FORMAT_R8G8B8A8_UNORM,
                                              DXGI_FORMAT_R8G8B8A8_UNORM,
+                                             DXGI_FORMAT_R8G8B8A8_UNORM,
                                              DXGI_FORMAT_UNKNOWN,
                                              DXGI_FORMAT_R8G8B8A8_UNORM,
                                              GL_RGBA8,
                                              nullptr);
                 return info;
             }
         }
         case GL_BGR565_ANGLEX:
         {
             if (SupportsFormat(DXGI_FORMAT_B5G6R5_UNORM, deviceCaps))
             {
                 static constexpr Format info(GL_BGR565_ANGLEX,
                                              angle::Format::ID::B5G6R5_UNORM,
                                              DXGI_FORMAT_B5G6R5_UNORM,
                                              DXGI_FORMAT_B5G6R5_UNORM,
+                                             DXGI_FORMAT_UNKNOWN,
                                              DXGI_FORMAT_B5G6R5_UNORM,
                                              DXGI_FORMAT_UNKNOWN,
                                              DXGI_FORMAT_B5G6R5_UNORM,
                                              GL_RGBA8,
                                              nullptr);
                 return info;
             }
             else
             {
                 static constexpr Format info(GL_BGR565_ANGLEX,
                                              angle::Format::ID::R8G8B8A8_UNORM,
                                              DXGI_FORMAT_R8G8B8A8_UNORM,
                                              DXGI_FORMAT_R8G8B8A8_UNORM,
                                              DXGI_FORMAT_R8G8B8A8_UNORM,
+                                             DXGI_FORMAT_R8G8B8A8_UNORM,
                                              DXGI_FORMAT_UNKNOWN,
                                              DXGI_FORMAT_R8G8B8A8_UNORM,
                                              GL_RGBA8,
                                              nullptr);
                 return info;
             }
         }
         case GL_BGR5_A1_ANGLEX:
         {
             static constexpr Format info(GL_BGR5_A1_ANGLEX,
                                          angle::Format::ID::B8G8R8A8_UNORM,
                                          DXGI_FORMAT_B8G8R8A8_UNORM,
                                          DXGI_FORMAT_B8G8R8A8_UNORM,
+                                         DXGI_FORMAT_UNKNOWN,
                                          DXGI_FORMAT_B8G8R8A8_UNORM,
                                          DXGI_FORMAT_UNKNOWN,
                                          DXGI_FORMAT_B8G8R8A8_UNORM,
                                          GL_BGRA8_EXT,
                                          nullptr);
             return info;
         }
         case GL_BGRA4_ANGLEX:
         {
             static constexpr Format info(GL_BGRA4_ANGLEX,
                                          angle::Format::ID::B8G8R8A8_UNORM,
                                          DXGI_FORMAT_B8G8R8A8_UNORM,
                                          DXGI_FORMAT_B8G8R8A8_UNORM,
+                                         DXGI_FORMAT_UNKNOWN,
                                          DXGI_FORMAT_B8G8R8A8_UNORM,
                                          DXGI_FORMAT_UNKNOWN,
                                          DXGI_FORMAT_B8G8R8A8_UNORM,
                                          GL_BGRA8_EXT,
                                          nullptr);
             return info;
         }
         case GL_BGRA8_EXT:
         {
             static constexpr Format info(GL_BGRA8_EXT,
                                          angle::Format::ID::B8G8R8A8_UNORM,
                                          DXGI_FORMAT_B8G8R8A8_UNORM,
                                          DXGI_FORMAT_B8G8R8A8_UNORM,
+                                         DXGI_FORMAT_UNKNOWN,
                                          DXGI_FORMAT_B8G8R8A8_UNORM,
                                          DXGI_FORMAT_UNKNOWN,
                                          DXGI_FORMAT_B8G8R8A8_UNORM,
                                          GL_BGRA8_EXT,
                                          nullptr);
             return info;
         }
+        case GL_BGRA8_SRGB_ANGLEX:
+        {
+            static constexpr Format info(GL_BGRA8_SRGB_ANGLEX,
+                                         angle::Format::ID::B8G8R8A8_UNORM_SRGB,
+                                         DXGI_FORMAT_B8G8R8A8_UNORM_SRGB,
+                                         DXGI_FORMAT_B8G8R8A8_UNORM_SRGB,
+                                         DXGI_FORMAT_UNKNOWN,
+                                         DXGI_FORMAT_B8G8R8A8_UNORM_SRGB,
+                                         DXGI_FORMAT_UNKNOWN,
+                                         DXGI_FORMAT_B8G8R8A8_UNORM_SRGB,
+                                         GL_BGRA8_SRGB_ANGLEX,
+                                         nullptr);
+            return info;
+        }
         case GL_COMPRESSED_R11_EAC:
         {
             static constexpr Format info(GL_COMPRESSED_R11_EAC,
                                          angle::Format::ID::R8_UNORM,
                                          DXGI_FORMAT_R8_UNORM,
                                          DXGI_FORMAT_R8_UNORM,
+                                         DXGI_FORMAT_UNKNOWN,
                                          DXGI_FORMAT_R8_UNORM,
                                          DXGI_FORMAT_UNKNOWN,
                                          DXGI_FORMAT_R8_UNORM,
                                          GL_RGBA8,
                                          nullptr);
             return info;
         }
         case GL_COMPRESSED_RG11_EAC:
         {
             static constexpr Format info(GL_COMPRESSED_RG11_EAC,
                                          angle::Format::ID::R8G8_UNORM,
                                          DXGI_FORMAT_R8G8_UNORM,
                                          DXGI_FORMAT_R8G8_UNORM,
+                                         DXGI_FORMAT_UNKNOWN,
                                          DXGI_FORMAT_R8G8_UNORM,
                                          DXGI_FORMAT_UNKNOWN,
                                          DXGI_FORMAT_R8G8_UNORM,
                                          GL_RGBA8,
                                          nullptr);
             return info;
         }
         case GL_COMPRESSED_RGB8_ETC2:
         {
             static constexpr Format info(GL_COMPRESSED_RGB8_ETC2,
                                          angle::Format::ID::R8G8B8A8_UNORM,
                                          DXGI_FORMAT_R8G8B8A8_UNORM,
                                          DXGI_FORMAT_R8G8B8A8_UNORM,
                                          DXGI_FORMAT_R8G8B8A8_UNORM,
+                                         DXGI_FORMAT_R8G8B8A8_UNORM,
                                          DXGI_FORMAT_UNKNOWN,
                                          DXGI_FORMAT_R8G8B8A8_UNORM,
                                          GL_RGBA8,
                                          Initialize4ComponentData<GLubyte, 0x00, 0x00, 0x00, 0xFF>);
             return info;
         }
         case GL_COMPRESSED_RGB8_LOSSY_DECODE_ETC2_ANGLE:
         {
             static constexpr Format info(GL_COMPRESSED_RGB8_LOSSY_DECODE_ETC2_ANGLE,
                                          angle::Format::ID::BC1_RGB_UNORM_BLOCK,
                                          DXGI_FORMAT_BC1_UNORM,
                                          DXGI_FORMAT_BC1_UNORM,
                                          DXGI_FORMAT_UNKNOWN,
                                          DXGI_FORMAT_UNKNOWN,
+                                         DXGI_FORMAT_UNKNOWN,
                                          DXGI_FORMAT_BC1_UNORM,
                                          GL_RGBA8,
                                          nullptr);
             return info;
         }
         case GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2:
         {
             static constexpr Format info(GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2,
                                          angle::Format::ID::R8G8B8A8_UNORM,
                                          DXGI_FORMAT_R8G8B8A8_UNORM,
                                          DXGI_FORMAT_R8G8B8A8_UNORM,
                                          DXGI_FORMAT_R8G8B8A8_UNORM,
+                                         DXGI_FORMAT_R8G8B8A8_UNORM,
                                          DXGI_FORMAT_UNKNOWN,
                                          DXGI_FORMAT_R8G8B8A8_UNORM,
                                          GL_RGBA8,
                                          Initialize4ComponentData<GLubyte, 0x00, 0x00, 0x00, 0xFF>);
             return info;
         }
         case GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_LOSSY_DECODE_ETC2_ANGLE:
         {
             static constexpr Format info(GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_LOSSY_DECODE_ETC2_ANGLE,
                                          angle::Format::ID::BC1_RGBA_UNORM_BLOCK,
                                          DXGI_FORMAT_BC1_UNORM,
                                          DXGI_FORMAT_BC1_UNORM,
                                          DXGI_FORMAT_UNKNOWN,
                                          DXGI_FORMAT_UNKNOWN,
+                                         DXGI_FORMAT_UNKNOWN,
                                          DXGI_FORMAT_BC1_UNORM,
                                          GL_RGBA8,
                                          nullptr);
             return info;
         }
         case GL_COMPRESSED_RGBA8_ETC2_EAC:
         {
             static constexpr Format info(GL_COMPRESSED_RGBA8_ETC2_EAC,
                                          angle::Format::ID::R8G8B8A8_UNORM,
                                          DXGI_FORMAT_R8G8B8A8_UNORM,
                                          DXGI_FORMAT_R8G8B8A8_UNORM,
                                          DXGI_FORMAT_R8G8B8A8_UNORM,
+                                         DXGI_FORMAT_R8G8B8A8_UNORM,
                                          DXGI_FORMAT_UNKNOWN,
                                          DXGI_FORMAT_R8G8B8A8_UNORM,
                                          GL_RGBA8,
                                          nullptr);
             return info;
         }
         case GL_COMPRESSED_RGBA_ASTC_10x10_KHR:
         {
             static constexpr Format info(GL_COMPRESSED_RGBA_ASTC_10x10_KHR,
                                          angle::Format::ID::NONE,
                                          DXGI_FORMAT_UNKNOWN,
                                          DXGI_FORMAT_UNKNOWN,
                                          DXGI_FORMAT_UNKNOWN,
                                          DXGI_FORMAT_UNKNOWN,
                                          DXGI_FORMAT_UNKNOWN,
+                                         DXGI_FORMAT_UNKNOWN,
                                          GL_NONE,
                                          nullptr);
             return info;
         }
         case GL_COMPRESSED_RGBA_ASTC_10x5_KHR:
         {
             static constexpr Format info(GL_COMPRESSED_RGBA_ASTC_10x5_KHR,
                                          angle::Format::ID::NONE,
                                          DXGI_FORMAT_UNKNOWN,
                                          DXGI_FORMAT_UNKNOWN,
                                          DXGI_FORMAT_UNKNOWN,
                                          DXGI_FORMAT_UNKNOWN,
                                          DXGI_FORMAT_UNKNOWN,
+                                         DXGI_FORMAT_UNKNOWN,
                                          GL_NONE,
                                          nullptr);
             return info;
         }
         case GL_COMPRESSED_RGBA_ASTC_10x6_KHR:
         {
             static constexpr Format info(GL_COMPRESSED_RGBA_ASTC_10x6_KHR,
                                          angle::Format::ID::NONE,
                                          DXGI_FORMAT_UNKNOWN,
                                          DXGI_FORMAT_UNKNOWN,
                                          DXGI_FORMAT_UNKNOWN,
                                          DXGI_FORMAT_UNKNOWN,
                                          DXGI_FORMAT_UNKNOWN,
+                                         DXGI_FORMAT_UNKNOWN,
                                          GL_NONE,
                                          nullptr);
             return info;
         }
         case GL_COMPRESSED_RGBA_ASTC_10x8_KHR:
         {
             static constexpr Format info(GL_COMPRESSED_RGBA_ASTC_10x8_KHR,
                                          angle::Format::ID::NONE,
                                          DXGI_FORMAT_UNKNOWN,
                                          DXGI_FORMAT_UNKNOWN,
                                          DXGI_FORMAT_UNKNOWN,
                                          DXGI_FORMAT_UNKNOWN,
                                          DXGI_FORMAT_UNKNOWN,
+                                         DXGI_FORMAT_UNKNOWN,
                                          GL_NONE,
                                          nullptr);
             return info;
         }
         case GL_COMPRESSED_RGBA_ASTC_12x10_KHR:
         {
             static constexpr Format info(GL_COMPRESSED_RGBA_ASTC_12x10_KHR,
                                          angle::Format::ID::NONE,
                                          DXGI_FORMAT_UNKNOWN,
                                          DXGI_FORMAT_UNKNOWN,
                                          DXGI_FORMAT_UNKNOWN,
                                          DXGI_FORMAT_UNKNOWN,
                                          DXGI_FORMAT_UNKNOWN,
+                                         DXGI_FORMAT_UNKNOWN,
                                          GL_NONE,
                                          nullptr);
             return info;
         }
         case GL_COMPRESSED_RGBA_ASTC_12x12_KHR:
         {
             static constexpr Format info(GL_COMPRESSED_RGBA_ASTC_12x12_KHR,
                                          angle::Format::ID::NONE,
                                          DXGI_FORMAT_UNKNOWN,
                                          DXGI_FORMAT_UNKNOWN,
                                          DXGI_FORMAT_UNKNOWN,
                                          DXGI_FORMAT_UNKNOWN,
                                          DXGI_FORMAT_UNKNOWN,
+                                         DXGI_FORMAT_UNKNOWN,
                                          GL_NONE,
                                          nullptr);
             return info;
         }
         case GL_COMPRESSED_RGBA_ASTC_4x4_KHR:
         {
             static constexpr Format info(GL_COMPRESSED_RGBA_ASTC_4x4_KHR,
                                          angle::Format::ID::NONE,
                                          DXGI_FORMAT_UNKNOWN,
                                          DXGI_FORMAT_UNKNOWN,
                                          DXGI_FORMAT_UNKNOWN,
                                          DXGI_FORMAT_UNKNOWN,
                                          DXGI_FORMAT_UNKNOWN,
+                                         DXGI_FORMAT_UNKNOWN,
                                          GL_NONE,
                                          nullptr);
             return info;
         }
         case GL_COMPRESSED_RGBA_ASTC_5x4_KHR:
         {
             static constexpr Format info(GL_COMPRESSED_RGBA_ASTC_5x4_KHR,
                                          angle::Format::ID::NONE,
                                          DXGI_FORMAT_UNKNOWN,
                                          DXGI_FORMAT_UNKNOWN,
                                          DXGI_FORMAT_UNKNOWN,
                                          DXGI_FORMAT_UNKNOWN,
                                          DXGI_FORMAT_UNKNOWN,
+                                         DXGI_FORMAT_UNKNOWN,
                                          GL_NONE,
                                          nullptr);
             return info;
         }
         case GL_COMPRESSED_RGBA_ASTC_5x5_KHR:
         {
             static constexpr Format info(GL_COMPRESSED_RGBA_ASTC_5x5_KHR,
                                          angle::Format::ID::NONE,
                                          DXGI_FORMAT_UNKNOWN,
                                          DXGI_FORMAT_UNKNOWN,
                                          DXGI_FORMAT_UNKNOWN,
                                          DXGI_FORMAT_UNKNOWN,
                                          DXGI_FORMAT_UNKNOWN,
+                                         DXGI_FORMAT_UNKNOWN,
                                          GL_NONE,
                                          nullptr);
             return info;
         }
         case GL_COMPRESSED_RGBA_ASTC_6x5_KHR:
         {
             static constexpr Format info(GL_COMPRESSED_RGBA_ASTC_6x5_KHR,
                                          angle::Format::ID::NONE,
                                          DXGI_FORMAT_UNKNOWN,
                                          DXGI_FORMAT_UNKNOWN,
                                          DXGI_FORMAT_UNKNOWN,
                                          DXGI_FORMAT_UNKNOWN,
                                          DXGI_FORMAT_UNKNOWN,
+                                         DXGI_FORMAT_UNKNOWN,
                                          GL_NONE,
                                          nullptr);
             return info;
         }
         case GL_COMPRESSED_RGBA_ASTC_6x6_KHR:
         {
             static constexpr Format info(GL_COMPRESSED_RGBA_ASTC_6x6_KHR,
                                          angle::Format::ID::NONE,
                                          DXGI_FORMAT_UNKNOWN,
                                          DXGI_FORMAT_UNKNOWN,
                                          DXGI_FORMAT_UNKNOWN,
                                          DXGI_FORMAT_UNKNOWN,
                                          DXGI_FORMAT_UNKNOWN,
+                                         DXGI_FORMAT_UNKNOWN,
                                          GL_NONE,
                                          nullptr);
             return info;
         }
         case GL_COMPRESSED_RGBA_ASTC_8x5_KHR:
         {
             static constexpr Format info(GL_COMPRESSED_RGBA_ASTC_8x5_KHR,
                                          angle::Format::ID::NONE,
                                          DXGI_FORMAT_UNKNOWN,
                                          DXGI_FORMAT_UNKNOWN,
                                          DXGI_FORMAT_UNKNOWN,
                                          DXGI_FORMAT_UNKNOWN,
                                          DXGI_FORMAT_UNKNOWN,
+                                         DXGI_FORMAT_UNKNOWN,
                                          GL_NONE,
                                          nullptr);
             return info;
         }
         case GL_COMPRESSED_RGBA_ASTC_8x6_KHR:
         {
             static constexpr Format info(GL_COMPRESSED_RGBA_ASTC_8x6_KHR,
                                          angle::Format::ID::NONE,
                                          DXGI_FORMAT_UNKNOWN,
                                          DXGI_FORMAT_UNKNOWN,
                                          DXGI_FORMAT_UNKNOWN,
                                          DXGI_FORMAT_UNKNOWN,
                                          DXGI_FORMAT_UNKNOWN,
+                                         DXGI_FORMAT_UNKNOWN,
                                          GL_NONE,
                                          nullptr);
             return info;
         }
         case GL_COMPRESSED_RGBA_ASTC_8x8_KHR:
         {
             static constexpr Format info(GL_COMPRESSED_RGBA_ASTC_8x8_KHR,
                                          angle::Format::ID::NONE,
                                          DXGI_FORMAT_UNKNOWN,
                                          DXGI_FORMAT_UNKNOWN,
                                          DXGI_FORMAT_UNKNOWN,
                                          DXGI_FORMAT_UNKNOWN,
                                          DXGI_FORMAT_UNKNOWN,
+                                         DXGI_FORMAT_UNKNOWN,
                                          GL_NONE,
                                          nullptr);
             return info;
         }
         case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
         {
             static constexpr Format info(GL_COMPRESSED_RGBA_S3TC_DXT1_EXT,
                                          angle::Format::ID::BC1_RGBA_UNORM_BLOCK,
                                          DXGI_FORMAT_BC1_UNORM,
                                          DXGI_FORMAT_BC1_UNORM,
                                          DXGI_FORMAT_UNKNOWN,
                                          DXGI_FORMAT_UNKNOWN,
+                                         DXGI_FORMAT_UNKNOWN,
                                          DXGI_FORMAT_BC1_UNORM,
                                          GL_RGBA8,
                                          nullptr);
             return info;
         }
         case GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE:
         {
             static constexpr Format info(GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE,
                                          angle::Format::ID::BC2_RGBA_UNORM_BLOCK,
                                          DXGI_FORMAT_BC2_UNORM,
                                          DXGI_FORMAT_BC2_UNORM,
                                          DXGI_FORMAT_UNKNOWN,
                                          DXGI_FORMAT_UNKNOWN,
+                                         DXGI_FORMAT_UNKNOWN,
                                          DXGI_FORMAT_BC2_UNORM,
                                          GL_RGBA8,
                                          nullptr);
             return info;
         }
         case GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE:
         {
             static constexpr Format info(GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE,
                                          angle::Format::ID::BC3_RGBA_UNORM_BLOCK,
                                          DXGI_FORMAT_BC3_UNORM,
                                          DXGI_FORMAT_BC3_UNORM,
                                          DXGI_FORMAT_UNKNOWN,
                                          DXGI_FORMAT_UNKNOWN,
+                                         DXGI_FORMAT_UNKNOWN,
                                          DXGI_FORMAT_BC3_UNORM,
                                          GL_RGBA8,
                                          nullptr);
             return info;
         }
         case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
         {
             static constexpr Format info(GL_COMPRESSED_RGB_S3TC_DXT1_EXT,
                                          angle::Format::ID::BC1_RGB_UNORM_BLOCK,
                                          DXGI_FORMAT_BC1_UNORM,
                                          DXGI_FORMAT_BC1_UNORM,
                                          DXGI_FORMAT_UNKNOWN,
                                          DXGI_FORMAT_UNKNOWN,
+                                         DXGI_FORMAT_UNKNOWN,
                                          DXGI_FORMAT_BC1_UNORM,
                                          GL_RGBA8,
                                          nullptr);
             return info;
         }
         case GL_COMPRESSED_SIGNED_R11_EAC:
         {
             static constexpr Format info(GL_COMPRESSED_SIGNED_R11_EAC,
                                          angle::Format::ID::R8_SNORM,
                                          DXGI_FORMAT_R8_SNORM,
                                          DXGI_FORMAT_R8_SNORM,
                                          DXGI_FORMAT_UNKNOWN,
                                          DXGI_FORMAT_UNKNOWN,
+                                         DXGI_FORMAT_UNKNOWN,
                                          DXGI_FORMAT_R8_SNORM,
                                          GL_RGBA8_SNORM,
                                          nullptr);
             return info;
         }
         case GL_COMPRESSED_SIGNED_RG11_EAC:
         {
             static constexpr Format info(GL_COMPRESSED_SIGNED_RG11_EAC,
                                          angle::Format::ID::R8G8_SNORM,
                                          DXGI_FORMAT_R8G8_SNORM,
                                          DXGI_FORMAT_R8G8_SNORM,
                                          DXGI_FORMAT_UNKNOWN,
                                          DXGI_FORMAT_UNKNOWN,
+                                         DXGI_FORMAT_UNKNOWN,
                                          DXGI_FORMAT_R8G8_SNORM,
                                          GL_RGBA8_SNORM,
                                          nullptr);
             return info;
         }
         case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x10_KHR:
         {
             static constexpr Format info(GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x10_KHR,
                                          angle::Format::ID::NONE,
                                          DXGI_FORMAT_UNKNOWN,
                                          DXGI_FORMAT_UNKNOWN,
                                          DXGI_FORMAT_UNKNOWN,
                                          DXGI_FORMAT_UNKNOWN,
                                          DXGI_FORMAT_UNKNOWN,
+                                         DXGI_FORMAT_UNKNOWN,
                                          GL_NONE,
                                          nullptr);
             return info;
         }
         case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x5_KHR:
         {
             static constexpr Format info(GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x5_KHR,
                                          angle::Format::ID::NONE,
                                          DXGI_FORMAT_UNKNOWN,
                                          DXGI_FORMAT_UNKNOWN,
                                          DXGI_FORMAT_UNKNOWN,
                                          DXGI_FORMAT_UNKNOWN,
                                          DXGI_FORMAT_UNKNOWN,
+                                         DXGI_FORMAT_UNKNOWN,
                                          GL_NONE,
                                          nullptr);
             return info;
         }
         case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x6_KHR:
         {
             static constexpr Format info(GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x6_KHR,
                                          angle::Format::ID::NONE,
                                          DXGI_FORMAT_UNKNOWN,
                                          DXGI_FORMAT_UNKNOWN,
                                          DXGI_FORMAT_UNKNOWN,
                                          DXGI_FORMAT_UNKNOWN,
                                          DXGI_FORMAT_UNKNOWN,
+                                         DXGI_FORMAT_UNKNOWN,
                                          GL_NONE,
                                          nullptr);
             return info;
         }
         case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x8_KHR:
         {
             static constexpr Format info(GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x8_KHR,
                                          angle::Format::ID::NONE,
                                          DXGI_FORMAT_UNKNOWN,
                                          DXGI_FORMAT_UNKNOWN,
                                          DXGI_FORMAT_UNKNOWN,
                                          DXGI_FORMAT_UNKNOWN,
                                          DXGI_FORMAT_UNKNOWN,
+                                         DXGI_FORMAT_UNKNOWN,
                                          GL_NONE,
                                          nullptr);
             return info;
         }
         case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_12x10_KHR:
         {
             static constexpr Format info(GL_COMPRESSED_SRGB8_ALPHA8_ASTC_12x10_KHR,
                                          angle::Format::ID::NONE,
                                          DXGI_FORMAT_UNKNOWN,
                                          DXGI_FORMAT_UNKNOWN,
                                          DXGI_FORMAT_UNKNOWN,
                                          DXGI_FORMAT_UNKNOWN,
                                          DXGI_FORMAT_UNKNOWN,
+                                         DXGI_FORMAT_UNKNOWN,
                                          GL_NONE,
                                          nullptr);
             return info;
         }
         case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_12x12_KHR:
         {
             static constexpr Format info(GL_COMPRESSED_SRGB8_ALPHA8_ASTC_12x12_KHR,
                                          angle::Format::ID::NONE,
                                          DXGI_FORMAT_UNKNOWN,
                                          DXGI_FORMAT_UNKNOWN,
                                          DXGI_FORMAT_UNKNOWN,
                                          DXGI_FORMAT_UNKNOWN,
                                          DXGI_FORMAT_UNKNOWN,
+                                         DXGI_FORMAT_UNKNOWN,
                                          GL_NONE,
                                          nullptr);
             return info;
         }
         case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_4x4_KHR:
         {
             static constexpr Format info(GL_COMPRESSED_SRGB8_ALPHA8_ASTC_4x4_KHR,
                                          angle::Format::ID::NONE,
                                          DXGI_FORMAT_UNKNOWN,
                                          DXGI_FORMAT_UNKNOWN,
                                          DXGI_FORMAT_UNKNOWN,
                                          DXGI_FORMAT_UNKNOWN,
                                          DXGI_FORMAT_UNKNOWN,
+                                         DXGI_FORMAT_UNKNOWN,
                                          GL_NONE,
                                          nullptr);
             return info;
         }
         case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x4_KHR:
         {
             static constexpr Format info(GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x4_KHR,
                                          angle::Format::ID::NONE,
                                          DXGI_FORMAT_UNKNOWN,
                                          DXGI_FORMAT_UNKNOWN,
                                          DXGI_FORMAT_UNKNOWN,
                                          DXGI_FORMAT_UNKNOWN,
                                          DXGI_FORMAT_UNKNOWN,
+                                         DXGI_FORMAT_UNKNOWN,
                                          GL_NONE,
                                          nullptr);
             return info;
         }
         case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x5_KHR:
         {
             static constexpr Format info(GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x5_KHR,
                                          angle::Format::ID::NONE,
                                          DXGI_FORMAT_UNKNOWN,
                                          DXGI_FORMAT_UNKNOWN,
                                          DXGI_FORMAT_UNKNOWN,
                                          DXGI_FORMAT_UNKNOWN,
                                          DXGI_FORMAT_UNKNOWN,
+                                         DXGI_FORMAT_UNKNOWN,
                                          GL_NONE,
                                          nullptr);
             return info;
         }
         case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x5_KHR:
         {
             static constexpr Format info(GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x5_KHR,
                                          angle::Format::ID::NONE,
                                          DXGI_FORMAT_UNKNOWN,
                                          DXGI_FORMAT_UNKNOWN,
                                          DXGI_FORMAT_UNKNOWN,
                                          DXGI_FORMAT_UNKNOWN,
                                          DXGI_FORMAT_UNKNOWN,
+                                         DXGI_FORMAT_UNKNOWN,
                                          GL_NONE,
                                          nullptr);
             return info;
         }
         case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x6_KHR:
         {
             static constexpr Format info(GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x6_KHR,
                                          angle::Format::ID::NONE,
                                          DXGI_FORMAT_UNKNOWN,
                                          DXGI_FORMAT_UNKNOWN,
                                          DXGI_FORMAT_UNKNOWN,
                                          DXGI_FORMAT_UNKNOWN,
                                          DXGI_FORMAT_UNKNOWN,
+                                         DXGI_FORMAT_UNKNOWN,
                                          GL_NONE,
                                          nullptr);
             return info;
         }
         case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x5_KHR:
         {
             static constexpr Format info(GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x5_KHR,
                                          angle::Format::ID::NONE,
                                          DXGI_FORMAT_UNKNOWN,
                                          DXGI_FORMAT_UNKNOWN,
                                          DXGI_FORMAT_UNKNOWN,
                                          DXGI_FORMAT_UNKNOWN,
                                          DXGI_FORMAT_UNKNOWN,
+                                         DXGI_FORMAT_UNKNOWN,
                                          GL_NONE,
                                          nullptr);
             return info;
         }
         case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x6_KHR:
         {
             static constexpr Format info(GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x6_KHR,
                                          angle::Format::ID::NONE,
                                          DXGI_FORMAT_UNKNOWN,
                                          DXGI_FORMAT_UNKNOWN,
                                          DXGI_FORMAT_UNKNOWN,
                                          DXGI_FORMAT_UNKNOWN,
                                          DXGI_FORMAT_UNKNOWN,
+                                         DXGI_FORMAT_UNKNOWN,
                                          GL_NONE,
                                          nullptr);
             return info;
         }
         case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x8_KHR:
         {
             static constexpr Format info(GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x8_KHR,
                                          angle::Format::ID::NONE,
                                          DXGI_FORMAT_UNKNOWN,
                                          DXGI_FORMAT_UNKNOWN,
                                          DXGI_FORMAT_UNKNOWN,
                                          DXGI_FORMAT_UNKNOWN,
                                          DXGI_FORMAT_UNKNOWN,
+                                         DXGI_FORMAT_UNKNOWN,
                                          GL_NONE,
                                          nullptr);
             return info;
         }
         case GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC:
         {
             static constexpr Format info(GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC,
                                          angle::Format::ID::R8G8B8A8_UNORM_SRGB,
                                          DXGI_FORMAT_R8G8B8A8_UNORM_SRGB,
                                          DXGI_FORMAT_R8G8B8A8_UNORM_SRGB,
+                                         DXGI_FORMAT_UNKNOWN,
                                          DXGI_FORMAT_R8G8B8A8_UNORM_SRGB,
                                          DXGI_FORMAT_UNKNOWN,
                                          DXGI_FORMAT_R8G8B8A8_UNORM_SRGB,
                                          GL_SRGB8_ALPHA8,
                                          nullptr);
             return info;
         }
         case GL_COMPRESSED_SRGB8_ETC2:
         {
             static constexpr Format info(GL_COMPRESSED_SRGB8_ETC2,
                                          angle::Format::ID::R8G8B8A8_UNORM_SRGB,
                                          DXGI_FORMAT_R8G8B8A8_UNORM_SRGB,
                                          DXGI_FORMAT_R8G8B8A8_UNORM_SRGB,
+                                         DXGI_FORMAT_UNKNOWN,
                                          DXGI_FORMAT_R8G8B8A8_UNORM_SRGB,
                                          DXGI_FORMAT_UNKNOWN,
                                          DXGI_FORMAT_R8G8B8A8_UNORM_SRGB,
                                          GL_SRGB8_ALPHA8,
                                          Initialize4ComponentData<GLubyte, 0x00, 0x00, 0x00, 0xFF>);
             return info;
         }
         case GL_COMPRESSED_SRGB8_LOSSY_DECODE_ETC2_ANGLE:
         {
             static constexpr Format info(GL_COMPRESSED_SRGB8_LOSSY_DECODE_ETC2_ANGLE,
                                          angle::Format::ID::BC1_RGB_UNORM_SRGB_BLOCK,
                                          DXGI_FORMAT_BC1_UNORM_SRGB,
                                          DXGI_FORMAT_BC1_UNORM_SRGB,
                                          DXGI_FORMAT_UNKNOWN,
                                          DXGI_FORMAT_UNKNOWN,
+                                         DXGI_FORMAT_UNKNOWN,
                                          DXGI_FORMAT_BC1_UNORM_SRGB,
                                          GL_RGBA8,
                                          nullptr);
             return info;
         }
         case GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2:
         {
             static constexpr Format info(GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2,
                                          angle::Format::ID::R8G8B8A8_UNORM_SRGB,
                                          DXGI_FORMAT_R8G8B8A8_UNORM_SRGB,
                                          DXGI_FORMAT_R8G8B8A8_UNORM_SRGB,
+                                         DXGI_FORMAT_UNKNOWN,
                                          DXGI_FORMAT_R8G8B8A8_UNORM_SRGB,
                                          DXGI_FORMAT_UNKNOWN,
                                          DXGI_FORMAT_R8G8B8A8_UNORM_SRGB,
                                          GL_SRGB8_ALPHA8,
                                          nullptr);
             return info;
         }
         case GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_LOSSY_DECODE_ETC2_ANGLE:
         {
             static constexpr Format info(GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_LOSSY_DECODE_ETC2_ANGLE,
                                          angle::Format::ID::BC1_RGBA_UNORM_SRGB_BLOCK,
                                          DXGI_FORMAT_BC1_UNORM_SRGB,
                                          DXGI_FORMAT_BC1_UNORM_SRGB,
                                          DXGI_FORMAT_UNKNOWN,
                                          DXGI_FORMAT_UNKNOWN,
+                                         DXGI_FORMAT_UNKNOWN,
                                          DXGI_FORMAT_BC1_UNORM_SRGB,
                                          GL_RGBA8,
                                          nullptr);
             return info;
         }
         case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT:
         {
             static constexpr Format info(GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT,
                                          angle::Format::ID::BC1_RGBA_UNORM_SRGB_BLOCK,
                                          DXGI_FORMAT_BC1_UNORM_SRGB,
                                          DXGI_FORMAT_BC1_UNORM_SRGB,
                                          DXGI_FORMAT_UNKNOWN,
                                          DXGI_FORMAT_UNKNOWN,
+                                         DXGI_FORMAT_UNKNOWN,
                                          DXGI_FORMAT_BC1_UNORM_SRGB,
                                          GL_RGBA8,
                                          nullptr);
             return info;
         }
         case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT:
         {
             static constexpr Format info(GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT,
                                          angle::Format::ID::BC2_RGBA_UNORM_SRGB_BLOCK,
                                          DXGI_FORMAT_BC2_UNORM_SRGB,
                                          DXGI_FORMAT_BC2_UNORM_SRGB,
                                          DXGI_FORMAT_UNKNOWN,
                                          DXGI_FORMAT_UNKNOWN,
+                                         DXGI_FORMAT_UNKNOWN,
                                          DXGI_FORMAT_BC2_UNORM_SRGB,
                                          GL_RGBA8,
                                          nullptr);
             return info;
         }
         case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT:
         {
             static constexpr Format info(GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT,
                                          angle::Format::ID::BC3_RGBA_UNORM_SRGB_BLOCK,
                                          DXGI_FORMAT_BC3_UNORM_SRGB,
                                          DXGI_FORMAT_BC3_UNORM_SRGB,
                                          DXGI_FORMAT_UNKNOWN,
                                          DXGI_FORMAT_UNKNOWN,
+                                         DXGI_FORMAT_UNKNOWN,
                                          DXGI_FORMAT_BC3_UNORM_SRGB,
                                          GL_RGBA8,
                                          nullptr);
             return info;
         }
         case GL_COMPRESSED_SRGB_S3TC_DXT1_EXT:
         {
             static constexpr Format info(GL_COMPRESSED_SRGB_S3TC_DXT1_EXT,
                                          angle::Format::ID::BC1_RGB_UNORM_SRGB_BLOCK,
                                          DXGI_FORMAT_BC1_UNORM_SRGB,
                                          DXGI_FORMAT_BC1_UNORM_SRGB,
                                          DXGI_FORMAT_UNKNOWN,
                                          DXGI_FORMAT_UNKNOWN,
+                                         DXGI_FORMAT_UNKNOWN,
                                          DXGI_FORMAT_BC1_UNORM_SRGB,
                                          GL_RGBA8,
                                          nullptr);
             return info;
         }
         case GL_DEPTH24_STENCIL8:
         {
             if (OnlyFL10Plus(deviceCaps))
             {
                 static constexpr Format info(GL_DEPTH24_STENCIL8,
                                              angle::Format::ID::D24_UNORM_S8_UINT,
                                              DXGI_FORMAT_R24G8_TYPELESS,
                                              DXGI_FORMAT_R24_UNORM_X8_TYPELESS,
                                              DXGI_FORMAT_UNKNOWN,
+                                             DXGI_FORMAT_UNKNOWN,
                                              DXGI_FORMAT_D24_UNORM_S8_UINT,
                                              DXGI_FORMAT_R24_UNORM_X8_TYPELESS,
                                              GL_RGBA32F,
                                              nullptr);
                 return info;
             }
             else
             {
                 static constexpr Format info(GL_DEPTH24_STENCIL8,
                                              angle::Format::ID::D24_UNORM_S8_UINT,
                                              DXGI_FORMAT_D24_UNORM_S8_UINT,
                                              DXGI_FORMAT_UNKNOWN,
                                              DXGI_FORMAT_UNKNOWN,
+                                             DXGI_FORMAT_UNKNOWN,
                                              DXGI_FORMAT_D24_UNORM_S8_UINT,
                                              DXGI_FORMAT_UNKNOWN,
                                              GL_RGBA32F,
                                              nullptr);
                 return info;
             }
         }
         case GL_DEPTH32F_STENCIL8:
         {
             static constexpr Format info(GL_DEPTH32F_STENCIL8,
                                          angle::Format::ID::D32_FLOAT_S8X24_UINT,
                                          DXGI_FORMAT_R32G8X24_TYPELESS,
                                          DXGI_FORMAT_R32_FLOAT_X8X24_TYPELESS,
                                          DXGI_FORMAT_UNKNOWN,
+                                         DXGI_FORMAT_UNKNOWN,
                                          DXGI_FORMAT_D32_FLOAT_S8X24_UINT,
                                          DXGI_FORMAT_R32_FLOAT_X8X24_TYPELESS,
                                          GL_RGBA32F,
                                          nullptr);
             return info;
         }
         case GL_DEPTH_COMPONENT16:
         {
             if (OnlyFL10Plus(deviceCaps))
             {
                 static constexpr Format info(GL_DEPTH_COMPONENT16,
                                              angle::Format::ID::D16_UNORM,
                                              DXGI_FORMAT_R16_TYPELESS,
                                              DXGI_FORMAT_R16_UNORM,
                                              DXGI_FORMAT_UNKNOWN,
+                                             DXGI_FORMAT_UNKNOWN,
                                              DXGI_FORMAT_D16_UNORM,
                                              DXGI_FORMAT_R16_UNORM,
                                              GL_RGBA16_EXT,
                                              nullptr);
                 return info;
             }
             else
             {
                 static constexpr Format info(GL_DEPTH_COMPONENT16,
                                              angle::Format::ID::D16_UNORM,
                                              DXGI_FORMAT_D16_UNORM,
                                              DXGI_FORMAT_UNKNOWN,
                                              DXGI_FORMAT_UNKNOWN,
+                                             DXGI_FORMAT_UNKNOWN,
                                              DXGI_FORMAT_D16_UNORM,
                                              DXGI_FORMAT_UNKNOWN,
                                              GL_RGBA16_EXT,
                                              nullptr);
                 return info;
             }
         }
         case GL_DEPTH_COMPONENT24:
         {
             if (OnlyFL10Plus(deviceCaps))
             {
                 static constexpr Format info(GL_DEPTH_COMPONENT24,
                                              angle::Format::ID::D24_UNORM_S8_UINT,
                                              DXGI_FORMAT_R24G8_TYPELESS,
                                              DXGI_FORMAT_R24_UNORM_X8_TYPELESS,
                                              DXGI_FORMAT_UNKNOWN,
+                                             DXGI_FORMAT_UNKNOWN,
                                              DXGI_FORMAT_D24_UNORM_S8_UINT,
                                              DXGI_FORMAT_R24_UNORM_X8_TYPELESS,
                                              GL_RGBA32F,
                                              nullptr);
                 return info;
             }
             else
             {
                 static constexpr Format info(GL_DEPTH_COMPONENT24,
                                              angle::Format::ID::D24_UNORM_S8_UINT,
                                              DXGI_FORMAT_D24_UNORM_S8_UINT,
                                              DXGI_FORMAT_UNKNOWN,
                                              DXGI_FORMAT_UNKNOWN,
+                                             DXGI_FORMAT_UNKNOWN,
                                              DXGI_FORMAT_D24_UNORM_S8_UINT,
                                              DXGI_FORMAT_UNKNOWN,
                                              GL_RGBA32F,
                                              nullptr);
                 return info;
             }
         }
         case GL_DEPTH_COMPONENT32F:
         {
             static constexpr Format info(GL_DEPTH_COMPONENT32F,
                                          angle::Format::ID::D32_FLOAT,
                                          DXGI_FORMAT_R32_TYPELESS,
                                          DXGI_FORMAT_R32_FLOAT,
                                          DXGI_FORMAT_UNKNOWN,
+                                         DXGI_FORMAT_UNKNOWN,
                                          DXGI_FORMAT_D32_FLOAT,
                                          DXGI_FORMAT_R32_FLOAT,
                                          GL_RGBA32F,
                                          nullptr);
             return info;
         }
         case GL_DEPTH_COMPONENT32_OES:
         {
             if (OnlyFL10Plus(deviceCaps))
             {
                 static constexpr Format info(GL_DEPTH_COMPONENT32_OES,
                                              angle::Format::ID::D24_UNORM_S8_UINT,
                                              DXGI_FORMAT_R24G8_TYPELESS,
                                              DXGI_FORMAT_R24_UNORM_X8_TYPELESS,
                                              DXGI_FORMAT_UNKNOWN,
+                                             DXGI_FORMAT_UNKNOWN,
                                              DXGI_FORMAT_D24_UNORM_S8_UINT,
                                              DXGI_FORMAT_R24_UNORM_X8_TYPELESS,
                                              GL_RGBA32F,
                                              nullptr);
                 return info;
             }
             else
             {
                 static constexpr Format info(GL_DEPTH_COMPONENT32_OES,
                                              angle::Format::ID::D24_UNORM_S8_UINT,
                                              DXGI_FORMAT_D24_UNORM_S8_UINT,
                                              DXGI_FORMAT_UNKNOWN,
                                              DXGI_FORMAT_UNKNOWN,
+                                             DXGI_FORMAT_UNKNOWN,
                                              DXGI_FORMAT_D24_UNORM_S8_UINT,
                                              DXGI_FORMAT_UNKNOWN,
                                              GL_RGBA32F,
                                              nullptr);
                 return info;
             }
         }
         case GL_ETC1_RGB8_LOSSY_DECODE_ANGLE:
         {
             static constexpr Format info(GL_ETC1_RGB8_LOSSY_DECODE_ANGLE,
                                          angle::Format::ID::BC1_RGB_UNORM_BLOCK,
                                          DXGI_FORMAT_BC1_UNORM,
                                          DXGI_FORMAT_BC1_UNORM,
                                          DXGI_FORMAT_UNKNOWN,
                                          DXGI_FORMAT_UNKNOWN,
+                                         DXGI_FORMAT_UNKNOWN,
                                          DXGI_FORMAT_BC1_UNORM,
                                          GL_RGBA8,
                                          nullptr);
             return info;
         }
         case GL_ETC1_RGB8_OES:
         {
             static constexpr Format info(GL_ETC1_RGB8_OES,
                                          angle::Format::ID::R8G8B8A8_UNORM,
                                          DXGI_FORMAT_R8G8B8A8_UNORM,
                                          DXGI_FORMAT_R8G8B8A8_UNORM,
                                          DXGI_FORMAT_R8G8B8A8_UNORM,
+                                         DXGI_FORMAT_R8G8B8A8_UNORM,
                                          DXGI_FORMAT_UNKNOWN,
                                          DXGI_FORMAT_R8G8B8A8_UNORM,
                                          GL_RGBA8,
                                          Initialize4ComponentData<GLubyte, 0x00, 0x00, 0x00, 0xFF>);
             return info;
         }
         case GL_LUMINANCE16F_EXT:
         {
             static constexpr Format info(GL_LUMINANCE16F_EXT,
                                          angle::Format::ID::R16G16B16A16_FLOAT,
                                          DXGI_FORMAT_R16G16B16A16_FLOAT,
                                          DXGI_FORMAT_R16G16B16A16_FLOAT,
                                          DXGI_FORMAT_R16G16B16A16_FLOAT,
+                                         DXGI_FORMAT_R16G16B16A16_FLOAT,
                                          DXGI_FORMAT_UNKNOWN,
                                          DXGI_FORMAT_R16G16B16A16_FLOAT,
                                          GL_RGBA16F,
                                          Initialize4ComponentData<GLhalf, 0x0000, 0x0000, 0x0000, gl::Float16One>);
             return info;
         }
         case GL_LUMINANCE32F_EXT:
         {
             static constexpr Format info(GL_LUMINANCE32F_EXT,
                                          angle::Format::ID::R32G32B32A32_FLOAT,
                                          DXGI_FORMAT_R32G32B32A32_FLOAT,
                                          DXGI_FORMAT_R32G32B32A32_FLOAT,
                                          DXGI_FORMAT_R32G32B32A32_FLOAT,
+                                         DXGI_FORMAT_R32G32B32A32_FLOAT,
                                          DXGI_FORMAT_UNKNOWN,
                                          DXGI_FORMAT_R32G32B32A32_FLOAT,
                                          GL_RGBA32F,
                                          Initialize4ComponentData<GLfloat, 0x00000000, 0x00000000, 0x00000000, gl::Float32One>);
             return info;
         }
         case GL_LUMINANCE8_ALPHA8_EXT:
         {
             static constexpr Format info(GL_LUMINANCE8_ALPHA8_EXT,
                                          angle::Format::ID::R8G8B8A8_UNORM,
                                          DXGI_FORMAT_R8G8B8A8_UNORM,
                                          DXGI_FORMAT_R8G8B8A8_UNORM,
                                          DXGI_FORMAT_R8G8B8A8_UNORM,
+                                         DXGI_FORMAT_R8G8B8A8_UNORM,
                                          DXGI_FORMAT_UNKNOWN,
                                          DXGI_FORMAT_R8G8B8A8_UNORM,
                                          GL_RGBA8,
                                          nullptr);
             return info;
         }
         case GL_LUMINANCE8_EXT:
         {
             static constexpr Format info(GL_LUMINANCE8_EXT,
                                          angle::Format::ID::R8G8B8A8_UNORM,
                                          DXGI_FORMAT_R8G8B8A8_UNORM,
                                          DXGI_FORMAT_R8G8B8A8_UNORM,
                                          DXGI_FORMAT_R8G8B8A8_UNORM,
+                                         DXGI_FORMAT_R8G8B8A8_UNORM,
                                          DXGI_FORMAT_UNKNOWN,
                                          DXGI_FORMAT_R8G8B8A8_UNORM,
                                          GL_RGBA8,
                                          Initialize4ComponentData<GLubyte, 0x00, 0x00, 0x00, 0xFF>);
             return info;
         }
         case GL_LUMINANCE_ALPHA16F_EXT:
         {
             static constexpr Format info(GL_LUMINANCE_ALPHA16F_EXT,
                                          angle::Format::ID::R16G16B16A16_FLOAT,
                                          DXGI_FORMAT_R16G16B16A16_FLOAT,
                                          DXGI_FORMAT_R16G16B16A16_FLOAT,
                                          DXGI_FORMAT_R16G16B16A16_FLOAT,
+                                         DXGI_FORMAT_R16G16B16A16_FLOAT,
                                          DXGI_FORMAT_UNKNOWN,
                                          DXGI_FORMAT_R16G16B16A16_FLOAT,
                                          GL_RGBA16F,
                                          nullptr);
             return info;
         }
         case GL_LUMINANCE_ALPHA32F_EXT:
         {
             static constexpr Format info(GL_LUMINANCE_ALPHA32F_EXT,
                                          angle::Format::ID::R32G32B32A32_FLOAT,
                                          DXGI_FORMAT_R32G32B32A32_FLOAT,
                                          DXGI_FORMAT_R32G32B32A32_FLOAT,
                                          DXGI_FORMAT_R32G32B32A32_FLOAT,
+                                         DXGI_FORMAT_R32G32B32A32_FLOAT,
                                          DXGI_FORMAT_UNKNOWN,
                                          DXGI_FORMAT_R32G32B32A32_FLOAT,
                                          GL_RGBA32F,
                                          nullptr);
             return info;
         }
         case GL_NONE:
         {
             static constexpr Format info(GL_NONE,
                                          angle::Format::ID::NONE,
                                          DXGI_FORMAT_UNKNOWN,
                                          DXGI_FORMAT_UNKNOWN,
                                          DXGI_FORMAT_UNKNOWN,
                                          DXGI_FORMAT_UNKNOWN,
                                          DXGI_FORMAT_UNKNOWN,
+                                         DXGI_FORMAT_UNKNOWN,
                                          GL_NONE,
                                          nullptr);
             return info;
         }
         case GL_R11F_G11F_B10F:
         {
             static constexpr Format info(GL_R11F_G11F_B10F,
                                          angle::Format::ID::R11G11B10_FLOAT,
                                          DXGI_FORMAT_R11G11B10_FLOAT,
                                          DXGI_FORMAT_R11G11B10_FLOAT,
+                                         DXGI_FORMAT_UNKNOWN,
                                          DXGI_FORMAT_R11G11B10_FLOAT,
                                          DXGI_FORMAT_UNKNOWN,
                                          DXGI_FORMAT_R11G11B10_FLOAT,
                                          GL_RGBA16F_EXT,
                                          nullptr);
             return info;
         }
         case GL_R16F:
         {
             static constexpr Format info(GL_R16F,
                                          angle::Format::ID::R16_FLOAT,
                                          DXGI_FORMAT_R16_FLOAT,
                                          DXGI_FORMAT_R16_FLOAT,
+                                         DXGI_FORMAT_UNKNOWN,
                                          DXGI_FORMAT_R16_FLOAT,
                                          DXGI_FORMAT_UNKNOWN,
                                          DXGI_FORMAT_R16_FLOAT,
                                          GL_RGBA16F_EXT,
                                          nullptr);
             return info;
         }
         case GL_R16I:
         {
             static constexpr Format info(GL_R16I,
                                          angle::Format::ID::R16_SINT,
                                          DXGI_FORMAT_R16_SINT,
                                          DXGI_FORMAT_R16_SINT,
+                                         DXGI_FORMAT_UNKNOWN,
                                          DXGI_FORMAT_R16_SINT,
                                          DXGI_FORMAT_UNKNOWN,
                                          DXGI_FORMAT_R16_SINT,
                                          GL_RGBA16I,
                                          nullptr);
             return info;
         }
         case GL_R16UI:
         {
             static constexpr Format info(GL_R16UI,
                                          angle::Format::ID::R16_UINT,
                                          DXGI_FORMAT_R16_UINT,
                                          DXGI_FORMAT_R16_UINT,
+                                         DXGI_FORMAT_UNKNOWN,
                                          DXGI_FORMAT_R16_UINT,
                                          DXGI_FORMAT_UNKNOWN,
                                          DXGI_FORMAT_R16_UINT,
                                          GL_RGBA16I,
                                          nullptr);
             return info;
         }
         case GL_R16_EXT:
         {
             static constexpr Format info(GL_R16_EXT,
                                          angle::Format::ID::R16_UNORM,
                                          DXGI_FORMAT_R16_UNORM,
                                          DXGI_FORMAT_R16_UNORM,
+                                         DXGI_FORMAT_UNKNOWN,
                                          DXGI_FORMAT_R16_UNORM,
                                          DXGI_FORMAT_UNKNOWN,
                                          DXGI_FORMAT_R16_UNORM,
                                          GL_RGBA16_EXT,
                                          nullptr);
             return info;
         }
         case GL_R16_SNORM_EXT:
         {
             static constexpr Format info(GL_R16_SNORM_EXT,
                                          angle::Format::ID::R16_SNORM,
                                          DXGI_FORMAT_R16_SNORM,
                                          DXGI_FORMAT_R16_SNORM,
                                          DXGI_FORMAT_UNKNOWN,
                                          DXGI_FORMAT_UNKNOWN,
+                                         DXGI_FORMAT_UNKNOWN,
                                          DXGI_FORMAT_R16_SNORM,
                                          GL_RGBA16_SNORM_EXT,
                                          nullptr);
             return info;
         }
         case GL_R32F:
         {
             static constexpr Format info(GL_R32F,
                                          angle::Format::ID::R32_FLOAT,
                                          DXGI_FORMAT_R32_FLOAT,
                                          DXGI_FORMAT_R32_FLOAT,
                                          DXGI_FORMAT_R32_FLOAT,
+                                         DXGI_FORMAT_R32_FLOAT,
                                          DXGI_FORMAT_UNKNOWN,
                                          DXGI_FORMAT_R32_FLOAT,
                                          GL_RGBA32F,
                                          nullptr);
             return info;
         }
         case GL_R32I:
         {
             static constexpr Format info(GL_R32I,
                                          angle::Format::ID::R32_SINT,
                                          DXGI_FORMAT_R32_SINT,
                                          DXGI_FORMAT_R32_SINT,
                                          DXGI_FORMAT_R32_SINT,
+                                         DXGI_FORMAT_R32_SINT,
                                          DXGI_FORMAT_UNKNOWN,
                                          DXGI_FORMAT_R32_SINT,
                                          GL_RGBA32I,
                                          nullptr);
             return info;
         }
         case GL_R32UI:
         {
             static constexpr Format info(GL_R32UI,
                                          angle::Format::ID::R32_UINT,
                                          DXGI_FORMAT_R32_UINT,
                                          DXGI_FORMAT_R32_UINT,
                                          DXGI_FORMAT_R32_UINT,
+                                         DXGI_FORMAT_R32_UINT,
                                          DXGI_FORMAT_UNKNOWN,
                                          DXGI_FORMAT_R32_UINT,
                                          GL_RGBA32I,
                                          nullptr);
             return info;
         }
         case GL_R8:
         {
             static constexpr Format info(GL_R8,
                                          angle::Format::ID::R8_UNORM,
                                          DXGI_FORMAT_R8_UNORM,
                                          DXGI_FORMAT_R8_UNORM,
+                                         DXGI_FORMAT_UNKNOWN,
                                          DXGI_FORMAT_R8_UNORM,
                                          DXGI_FORMAT_UNKNOWN,
                                          DXGI_FORMAT_R8_UNORM,
                                          GL_RGBA8,
                                          nullptr);
             return info;
         }
         case GL_R8I:
         {
             static constexpr Format info(GL_R8I,
                                          angle::Format::ID::R8_SINT,
                                          DXGI_FORMAT_R8_SINT,
                                          DXGI_FORMAT_R8_SINT,
+                                         DXGI_FORMAT_UNKNOWN,
                                          DXGI_FORMAT_R8_SINT,
                                          DXGI_FORMAT_UNKNOWN,
                                          DXGI_FORMAT_R8_SINT,
                                          GL_RGBA8I,
                                          nullptr);
             return info;
         }
         case GL_R8UI:
         {
             static constexpr Format info(GL_R8UI,
                                          angle::Format::ID::R8_UINT,
                                          DXGI_FORMAT_R8_UINT,
                                          DXGI_FORMAT_R8_UINT,
+                                         DXGI_FORMAT_UNKNOWN,
                                          DXGI_FORMAT_R8_UINT,
                                          DXGI_FORMAT_UNKNOWN,
                                          DXGI_FORMAT_R8_UINT,
                                          GL_RGBA8I,
                                          nullptr);
             return info;
         }
         case GL_R8_SNORM:
         {
             static constexpr Format info(GL_R8_SNORM,
                                          angle::Format::ID::R8_SNORM,
                                          DXGI_FORMAT_R8_SNORM,
                                          DXGI_FORMAT_R8_SNORM,
                                          DXGI_FORMAT_UNKNOWN,
                                          DXGI_FORMAT_UNKNOWN,
+                                         DXGI_FORMAT_UNKNOWN,
                                          DXGI_FORMAT_R8_SNORM,
                                          GL_RGBA8_SNORM,
                                          nullptr);
             return info;
         }
         case GL_RG16F:
         {
             static constexpr Format info(GL_RG16F,
                                          angle::Format::ID::R16G16_FLOAT,
                                          DXGI_FORMAT_R16G16_FLOAT,
                                          DXGI_FORMAT_R16G16_FLOAT,
+                                         DXGI_FORMAT_UNKNOWN,
                                          DXGI_FORMAT_R16G16_FLOAT,
                                          DXGI_FORMAT_UNKNOWN,
                                          DXGI_FORMAT_R16G16_FLOAT,
                                          GL_RGBA16F_EXT,
                                          nullptr);
             return info;
         }
         case GL_RG16I:
         {
             static constexpr Format info(GL_RG16I,
                                          angle::Format::ID::R16G16_SINT,
                                          DXGI_FORMAT_R16G16_SINT,
                                          DXGI_FORMAT_R16G16_SINT,
+                                         DXGI_FORMAT_UNKNOWN,
                                          DXGI_FORMAT_R16G16_SINT,
                                          DXGI_FORMAT_UNKNOWN,
                                          DXGI_FORMAT_R16G16_SINT,
                                          GL_RGBA16I,
                                          nullptr);
             return info;
         }
         case GL_RG16UI:
         {
             static constexpr Format info(GL_RG16UI,
                                          angle::Format::ID::R16G16_UINT,
                                          DXGI_FORMAT_R16G16_UINT,
                                          DXGI_FORMAT_R16G16_UINT,
+                                         DXGI_FORMAT_UNKNOWN,
                                          DXGI_FORMAT_R16G16_UINT,
                                          DXGI_FORMAT_UNKNOWN,
                                          DXGI_FORMAT_R16G16_UINT,
                                          GL_RGBA16I,
                                          nullptr);
             return info;
         }
         case GL_RG16_EXT:
         {
             static constexpr Format info(GL_RG16_EXT,
                                          angle::Format::ID::R16G16_UNORM,
                                          DXGI_FORMAT_R16G16_UNORM,
                                          DXGI_FORMAT_R16G16_UNORM,
+                                         DXGI_FORMAT_UNKNOWN,
                                          DXGI_FORMAT_R16G16_UNORM,
                                          DXGI_FORMAT_UNKNOWN,
                                          DXGI_FORMAT_R16G16_UNORM,
                                          GL_RGBA16_EXT,
                                          nullptr);
             return info;
         }
         case GL_RG16_SNORM_EXT:
         {
             static constexpr Format info(GL_RG16_SNORM_EXT,
                                          angle::Format::ID::R16G16_SNORM,
                                          DXGI_FORMAT_R16G16_SNORM,
                                          DXGI_FORMAT_R16G16_SNORM,
                                          DXGI_FORMAT_UNKNOWN,
                                          DXGI_FORMAT_UNKNOWN,
+                                         DXGI_FORMAT_UNKNOWN,
                                          DXGI_FORMAT_R16G16_SNORM,
                                          GL_RGBA16_SNORM_EXT,
                                          nullptr);
             return info;
         }
         case GL_RG32F:
         {
             static constexpr Format info(GL_RG32F,
                                          angle::Format::ID::R32G32_FLOAT,
                                          DXGI_FORMAT_R32G32_FLOAT,
                                          DXGI_FORMAT_R32G32_FLOAT,
+                                         DXGI_FORMAT_UNKNOWN,
                                          DXGI_FORMAT_R32G32_FLOAT,
                                          DXGI_FORMAT_UNKNOWN,
                                          DXGI_FORMAT_R32G32_FLOAT,
                                          GL_RGBA32F,
                                          nullptr);
             return info;
         }
         case GL_RG32I:
         {
             static constexpr Format info(GL_RG32I,
                                          angle::Format::ID::R32G32_SINT,
                                          DXGI_FORMAT_R32G32_SINT,
                                          DXGI_FORMAT_R32G32_SINT,
+                                         DXGI_FORMAT_UNKNOWN,
                                          DXGI_FORMAT_R32G32_SINT,
                                          DXGI_FORMAT_UNKNOWN,
                                          DXGI_FORMAT_R32G32_SINT,
                                          GL_RGBA32I,
                                          nullptr);
             return info;
         }
         case GL_RG32UI:
         {
             static constexpr Format info(GL_RG32UI,
                                          angle::Format::ID::R32G32_UINT,
                                          DXGI_FORMAT_R32G32_UINT,
                                          DXGI_FORMAT_R32G32_UINT,
+                                         DXGI_FORMAT_UNKNOWN,
                                          DXGI_FORMAT_R32G32_UINT,
                                          DXGI_FORMAT_UNKNOWN,
                                          DXGI_FORMAT_R32G32_UINT,
                                          GL_RGBA32I,
                                          nullptr);
             return info;
         }
         case GL_RG8:
         {
             static constexpr Format info(GL_RG8,
                                          angle::Format::ID::R8G8_UNORM,
                                          DXGI_FORMAT_R8G8_UNORM,
                                          DXGI_FORMAT_R8G8_UNORM,
+                                         DXGI_FORMAT_UNKNOWN,
                                          DXGI_FORMAT_R8G8_UNORM,
                                          DXGI_FORMAT_UNKNOWN,
                                          DXGI_FORMAT_R8G8_UNORM,
                                          GL_RGBA8,
                                          nullptr);
             return info;
         }
         case GL_RG8I:
         {
             static constexpr Format info(GL_RG8I,
                                          angle::Format::ID::R8G8_SINT,
                                          DXGI_FORMAT_R8G8_SINT,
                                          DXGI_FORMAT_R8G8_SINT,
+                                         DXGI_FORMAT_UNKNOWN,
                                          DXGI_FORMAT_R8G8_SINT,
                                          DXGI_FORMAT_UNKNOWN,
                                          DXGI_FORMAT_R8G8_SINT,
                                          GL_RGBA8I,
                                          nullptr);
             return info;
         }
         case GL_RG8UI:
         {
             static constexpr Format info(GL_RG8UI,
                                          angle::Format::ID::R8G8_UINT,
                                          DXGI_FORMAT_R8G8_UINT,
                                          DXGI_FORMAT_R8G8_UINT,
+                                         DXGI_FORMAT_UNKNOWN,
                                          DXGI_FORMAT_R8G8_UINT,
                                          DXGI_FORMAT_UNKNOWN,
                                          DXGI_FORMAT_R8G8_UINT,
                                          GL_RGBA8I,
                                          nullptr);
             return info;
         }
         case GL_RG8_SNORM:
         {
             static constexpr Format info(GL_RG8_SNORM,
                                          angle::Format::ID::R8G8_SNORM,
                                          DXGI_FORMAT_R8G8_SNORM,
                                          DXGI_FORMAT_R8G8_SNORM,
                                          DXGI_FORMAT_UNKNOWN,
                                          DXGI_FORMAT_UNKNOWN,
+                                         DXGI_FORMAT_UNKNOWN,
                                          DXGI_FORMAT_R8G8_SNORM,
                                          GL_RGBA8_SNORM,
                                          nullptr);
             return info;
         }
         case GL_RGB:
         {
             static constexpr Format info(GL_RGB,
                                          angle::Format::ID::R8G8B8A8_UNORM,
                                          DXGI_FORMAT_R8G8B8A8_UNORM,
                                          DXGI_FORMAT_R8G8B8A8_UNORM,
                                          DXGI_FORMAT_R8G8B8A8_UNORM,
+                                         DXGI_FORMAT_R8G8B8A8_UNORM,
                                          DXGI_FORMAT_UNKNOWN,
                                          DXGI_FORMAT_R8G8B8A8_UNORM,
                                          GL_RGBA8,
                                          Initialize4ComponentData<GLubyte, 0x00, 0x00, 0x00, 0xFF>);
             return info;
         }
         case GL_RGB10_A2:
         {
             static constexpr Format info(GL_RGB10_A2,
                                          angle::Format::ID::R10G10B10A2_UNORM,
                                          DXGI_FORMAT_R10G10B10A2_UNORM,
                                          DXGI_FORMAT_R10G10B10A2_UNORM,
+                                         DXGI_FORMAT_UNKNOWN,
                                          DXGI_FORMAT_R10G10B10A2_UNORM,
                                          DXGI_FORMAT_UNKNOWN,
                                          DXGI_FORMAT_R10G10B10A2_UNORM,
                                          GL_RGBA16_EXT,
                                          nullptr);
             return info;
         }
         case GL_RGB10_A2UI:
         {
             static constexpr Format info(GL_RGB10_A2UI,
                                          angle::Format::ID::R10G10B10A2_UINT,
                                          DXGI_FORMAT_R10G10B10A2_UINT,
                                          DXGI_FORMAT_R10G10B10A2_UINT,
+                                         DXGI_FORMAT_UNKNOWN,
                                          DXGI_FORMAT_R10G10B10A2_UINT,
                                          DXGI_FORMAT_UNKNOWN,
                                          DXGI_FORMAT_R10G10B10A2_UINT,
                                          GL_RGBA16I,
                                          nullptr);
             return info;
         }
         case GL_RGB16F:
         {
             static constexpr Format info(GL_RGB16F,
                                          angle::Format::ID::R16G16B16A16_FLOAT,
                                          DXGI_FORMAT_R16G16B16A16_FLOAT,
                                          DXGI_FORMAT_R16G16B16A16_FLOAT,
                                          DXGI_FORMAT_R16G16B16A16_FLOAT,
+                                         DXGI_FORMAT_R16G16B16A16_FLOAT,
                                          DXGI_FORMAT_UNKNOWN,
                                          DXGI_FORMAT_R16G16B16A16_FLOAT,
                                          GL_RGBA16F,
                                          Initialize4ComponentData<GLhalf, 0x0000, 0x0000, 0x0000, gl::Float16One>);
             return info;
         }
         case GL_RGB16I:
         {
             static constexpr Format info(GL_RGB16I,
                                          angle::Format::ID::R16G16B16A16_SINT,
                                          DXGI_FORMAT_R16G16B16A16_SINT,
                                          DXGI_FORMAT_R16G16B16A16_SINT,
                                          DXGI_FORMAT_R16G16B16A16_SINT,
+                                         DXGI_FORMAT_R16G16B16A16_SINT,
                                          DXGI_FORMAT_UNKNOWN,
                                          DXGI_FORMAT_R16G16B16A16_SINT,
                                          GL_RGBA16I,
                                          Initialize4ComponentData<GLshort, 0x0000, 0x0000, 0x0000, 0x0001>);
             return info;
         }
         case GL_RGB16UI:
         {
             static constexpr Format info(GL_RGB16UI,
                                          angle::Format::ID::R16G16B16A16_UINT,
                                          DXGI_FORMAT_R16G16B16A16_UINT,
                                          DXGI_FORMAT_R16G16B16A16_UINT,
                                          DXGI_FORMAT_R16G16B16A16_UINT,
+                                         DXGI_FORMAT_R16G16B16A16_UINT,
                                          DXGI_FORMAT_UNKNOWN,
                                          DXGI_FORMAT_R16G16B16A16_UINT,
                                          GL_RGBA16UI,
                                          Initialize4ComponentData<GLushort, 0x0000, 0x0000, 0x0000, 0x0001>);
             return info;
         }
         case GL_RGB16_EXT:
         {
             static constexpr Format info(GL_RGB16_EXT,
                                          angle::Format::ID::R16G16B16A16_UNORM,
                                          DXGI_FORMAT_R16G16B16A16_UNORM,
                                          DXGI_FORMAT_R16G16B16A16_UNORM,
+                                         DXGI_FORMAT_UNKNOWN,
                                          DXGI_FORMAT_R16G16B16A16_UNORM,
                                          DXGI_FORMAT_UNKNOWN,
                                          DXGI_FORMAT_R16G16B16A16_UNORM,
                                          GL_RGBA16_EXT,
                                          Initialize4ComponentData<GLubyte, 0x0000, 0x0000, 0x0000, 0xFFFF>);
             return info;
         }
         case GL_RGB16_SNORM_EXT:
         {
             static constexpr Format info(GL_RGB16_SNORM_EXT,
                                          angle::Format::ID::R16G16B16A16_SNORM,
                                          DXGI_FORMAT_R16G16B16A16_SNORM,
                                          DXGI_FORMAT_R16G16B16A16_SNORM,
                                          DXGI_FORMAT_UNKNOWN,
                                          DXGI_FORMAT_UNKNOWN,
+                                         DXGI_FORMAT_UNKNOWN,
                                          DXGI_FORMAT_R16G16B16A16_SNORM,
                                          GL_RGBA16_SNORM_EXT,
                                          Initialize4ComponentData<GLushort, 0x0000, 0x0000, 0x0000, 0x7FFF>);
             return info;
         }
         case GL_RGB32F:
         {
             static constexpr Format info(GL_RGB32F,
                                          angle::Format::ID::R32G32B32A32_FLOAT,
                                          DXGI_FORMAT_R32G32B32A32_FLOAT,
                                          DXGI_FORMAT_R32G32B32A32_FLOAT,
                                          DXGI_FORMAT_R32G32B32A32_FLOAT,
+                                         DXGI_FORMAT_R32G32B32A32_FLOAT,
                                          DXGI_FORMAT_UNKNOWN,
                                          DXGI_FORMAT_R32G32B32A32_FLOAT,
                                          GL_RGBA32F,
                                          Initialize4ComponentData<GLfloat, 0x00000000, 0x00000000, 0x00000000, gl::Float32One>);
             return info;
         }
         case GL_RGB32I:
         {
             static constexpr Format info(GL_RGB32I,
                                          angle::Format::ID::R32G32B32A32_SINT,
                                          DXGI_FORMAT_R32G32B32A32_SINT,
                                          DXGI_FORMAT_R32G32B32A32_SINT,
                                          DXGI_FORMAT_R32G32B32A32_SINT,
+                                         DXGI_FORMAT_R32G32B32A32_SINT,
                                          DXGI_FORMAT_UNKNOWN,
                                          DXGI_FORMAT_R32G32B32A32_SINT,
                                          GL_RGBA32I,
                                          Initialize4ComponentData<GLint, 0x00000000, 0x00000000, 0x00000000, 0x00000001>);
             return info;
         }
         case GL_RGB32UI:
         {
             static constexpr Format info(GL_RGB32UI,
                                          angle::Format::ID::R32G32B32A32_UINT,
                                          DXGI_FORMAT_R32G32B32A32_UINT,
                                          DXGI_FORMAT_R32G32B32A32_UINT,
                                          DXGI_FORMAT_R32G32B32A32_UINT,
+                                         DXGI_FORMAT_R32G32B32A32_UINT,
                                          DXGI_FORMAT_UNKNOWN,
                                          DXGI_FORMAT_R32G32B32A32_UINT,
                                          GL_RGBA32UI,
                                          Initialize4ComponentData<GLuint, 0x00000000, 0x00000000, 0x00000000, 0x00000001>);
             return info;
         }
         case GL_RGB565:
         {
             if (SupportsFormat(DXGI_FORMAT_B5G6R5_UNORM, deviceCaps))
             {
                 static constexpr Format info(GL_RGB565,
                                              angle::Format::ID::B5G6R5_UNORM,
                                              DXGI_FORMAT_B5G6R5_UNORM,
                                              DXGI_FORMAT_B5G6R5_UNORM,
+                                             DXGI_FORMAT_UNKNOWN,
                                              DXGI_FORMAT_B5G6R5_UNORM,
                                              DXGI_FORMAT_UNKNOWN,
                                              DXGI_FORMAT_B5G6R5_UNORM,
                                              GL_RGBA8,
                                              nullptr);
                 return info;
             }
             else
             {
                 static constexpr Format info(GL_RGB565,
                                              angle::Format::ID::R8G8B8A8_UNORM,
                                              DXGI_FORMAT_R8G8B8A8_UNORM,
                                              DXGI_FORMAT_R8G8B8A8_UNORM,
                                              DXGI_FORMAT_R8G8B8A8_UNORM,
+                                             DXGI_FORMAT_R8G8B8A8_UNORM,
                                              DXGI_FORMAT_UNKNOWN,
                                              DXGI_FORMAT_R8G8B8A8_UNORM,
                                              GL_RGBA8,
                                              Initialize4ComponentData<GLubyte, 0x00, 0x00, 0x00, 0xFF>);
                 return info;
             }
         }
         case GL_RGB5_A1:
         {
             if (SupportsFormat(DXGI_FORMAT_B5G5R5A1_UNORM, deviceCaps))
             {
                 static constexpr Format info(GL_RGB5_A1,
                                              angle::Format::ID::B5G5R5A1_UNORM,
                                              DXGI_FORMAT_B5G5R5A1_UNORM,
                                              DXGI_FORMAT_B5G5R5A1_UNORM,
+                                             DXGI_FORMAT_UNKNOWN,
                                              DXGI_FORMAT_B5G5R5A1_UNORM,
                                              DXGI_FORMAT_UNKNOWN,
                                              DXGI_FORMAT_B5G5R5A1_UNORM,
                                              GL_RGBA8,
                                              nullptr);
                 return info;
             }
             else
             {
                 static constexpr Format info(GL_RGB5_A1,
                                              angle::Format::ID::R8G8B8A8_UNORM,
                                              DXGI_FORMAT_R8G8B8A8_UNORM,
                                              DXGI_FORMAT_R8G8B8A8_UNORM,
                                              DXGI_FORMAT_R8G8B8A8_UNORM,
+                                             DXGI_FORMAT_R8G8B8A8_UNORM,
                                              DXGI_FORMAT_UNKNOWN,
                                              DXGI_FORMAT_R8G8B8A8_UNORM,
                                              GL_RGBA8,
                                              nullptr);
                 return info;
             }
         }
         case GL_RGB8:
         {
             static constexpr Format info(GL_RGB8,
                                          angle::Format::ID::R8G8B8A8_UNORM,
                                          DXGI_FORMAT_R8G8B8A8_UNORM,
                                          DXGI_FORMAT_R8G8B8A8_UNORM,
                                          DXGI_FORMAT_R8G8B8A8_UNORM,
+                                         DXGI_FORMAT_R8G8B8A8_UNORM,
                                          DXGI_FORMAT_UNKNOWN,
                                          DXGI_FORMAT_R8G8B8A8_UNORM,
                                          GL_RGBA8,
                                          Initialize4ComponentData<GLubyte, 0x00, 0x00, 0x00, 0xFF>);
             return info;
         }
         case GL_RGB8I:
         {
             static constexpr Format info(GL_RGB8I,
                                          angle::Format::ID::R8G8B8A8_SINT,
                                          DXGI_FORMAT_R8G8B8A8_SINT,
                                          DXGI_FORMAT_R8G8B8A8_SINT,
+                                         DXGI_FORMAT_UNKNOWN,
                                          DXGI_FORMAT_R8G8B8A8_SINT,
                                          DXGI_FORMAT_UNKNOWN,
                                          DXGI_FORMAT_R8G8B8A8_SINT,
                                          GL_RGBA8I,
                                          Initialize4ComponentData<GLbyte, 0x00, 0x00, 0x00, 0x01>);
             return info;
         }
         case GL_RGB8UI:
         {
             static constexpr Format info(GL_RGB8UI,
                                          angle::Format::ID::R8G8B8A8_UINT,
                                          DXGI_FORMAT_R8G8B8A8_UINT,
                                          DXGI_FORMAT_R8G8B8A8_UINT,
                                          DXGI_FORMAT_R8G8B8A8_UINT,
+                                         DXGI_FORMAT_R8G8B8A8_UINT,
                                          DXGI_FORMAT_UNKNOWN,
                                          DXGI_FORMAT_R8G8B8A8_UINT,
                                          GL_RGBA8UI,
                                          Initialize4ComponentData<GLubyte, 0x00, 0x00, 0x00, 0x01>);
             return info;
         }
         case GL_RGB8_SNORM:
         {
             static constexpr Format info(GL_RGB8_SNORM,
                                          angle::Format::ID::R8G8B8A8_SNORM,
                                          DXGI_FORMAT_R8G8B8A8_SNORM,
                                          DXGI_FORMAT_R8G8B8A8_SNORM,
+                                         DXGI_FORMAT_R8G8B8A8_SNORM,
                                          DXGI_FORMAT_UNKNOWN,
                                          DXGI_FORMAT_UNKNOWN,
                                          DXGI_FORMAT_R8G8B8A8_SNORM,
                                          GL_RGBA8_SNORM,
                                          Initialize4ComponentData<GLbyte, 0x00, 0x00, 0x00, 0x7F>);
             return info;
         }
         case GL_RGB9_E5:
         {
             static constexpr Format info(GL_RGB9_E5,
                                          angle::Format::ID::R9G9B9E5_SHAREDEXP,
                                          DXGI_FORMAT_R9G9B9E5_SHAREDEXP,
                                          DXGI_FORMAT_R9G9B9E5_SHAREDEXP,
                                          DXGI_FORMAT_UNKNOWN,
                                          DXGI_FORMAT_UNKNOWN,
+                                         DXGI_FORMAT_UNKNOWN,
                                          DXGI_FORMAT_R9G9B9E5_SHAREDEXP,
                                          GL_RGBA16F_EXT,
                                          nullptr);
             return info;
         }
         case GL_RGBA:
         {
             static constexpr Format info(GL_RGBA,
                                          angle::Format::ID::R8G8B8A8_UNORM,
                                          DXGI_FORMAT_R8G8B8A8_UNORM,
                                          DXGI_FORMAT_R8G8B8A8_UNORM,
                                          DXGI_FORMAT_R8G8B8A8_UNORM,
+                                         DXGI_FORMAT_R8G8B8A8_UNORM,
                                          DXGI_FORMAT_UNKNOWN,
                                          DXGI_FORMAT_R8G8B8A8_UNORM,
                                          GL_RGBA8,
                                          nullptr);
             return info;
         }
         case GL_RGBA16F:
         {
             static constexpr Format info(GL_RGBA16F,
                                          angle::Format::ID::R16G16B16A16_FLOAT,
                                          DXGI_FORMAT_R16G16B16A16_FLOAT,
                                          DXGI_FORMAT_R16G16B16A16_FLOAT,
                                          DXGI_FORMAT_R16G16B16A16_FLOAT,
+                                         DXGI_FORMAT_R16G16B16A16_FLOAT,
                                          DXGI_FORMAT_UNKNOWN,
                                          DXGI_FORMAT_R16G16B16A16_FLOAT,
                                          GL_RGBA16F,
                                          nullptr);
             return info;
         }
         case GL_RGBA16I:
         {
             static constexpr Format info(GL_RGBA16I,
                                          angle::Format::ID::R16G16B16A16_SINT,
                                          DXGI_FORMAT_R16G16B16A16_SINT,
                                          DXGI_FORMAT_R16G16B16A16_SINT,
                                          DXGI_FORMAT_R16G16B16A16_SINT,
+                                         DXGI_FORMAT_R16G16B16A16_SINT,
                                          DXGI_FORMAT_UNKNOWN,
                                          DXGI_FORMAT_R16G16B16A16_SINT,
                                          GL_RGBA16I,
                                          nullptr);
             return info;
         }
         case GL_RGBA16UI:
         {
             static constexpr Format info(GL_RGBA16UI,
                                          angle::Format::ID::R16G16B16A16_UINT,
                                          DXGI_FORMAT_R16G16B16A16_UINT,
                                          DXGI_FORMAT_R16G16B16A16_UINT,
                                          DXGI_FORMAT_R16G16B16A16_UINT,
+                                         DXGI_FORMAT_R16G16B16A16_UINT,
                                          DXGI_FORMAT_UNKNOWN,
                                          DXGI_FORMAT_R16G16B16A16_UINT,
                                          GL_RGBA16UI,
                                          nullptr);
             return info;
         }
         case GL_RGBA16_EXT:
         {
             static constexpr Format info(GL_RGBA16_EXT,
                                          angle::Format::ID::R16G16B16A16_UNORM,
                                          DXGI_FORMAT_R16G16B16A16_UNORM,
                                          DXGI_FORMAT_R16G16B16A16_UNORM,
+                                         DXGI_FORMAT_UNKNOWN,
                                          DXGI_FORMAT_R16G16B16A16_UNORM,
                                          DXGI_FORMAT_UNKNOWN,
                                          DXGI_FORMAT_R16G16B16A16_UNORM,
                                          GL_RGBA16_EXT,
                                          nullptr);
             return info;
         }
         case GL_RGBA16_SNORM_EXT:
         {
             static constexpr Format info(GL_RGBA16_SNORM_EXT,
                                          angle::Format::ID::R16G16B16A16_SNORM,
                                          DXGI_FORMAT_R16G16B16A16_SNORM,
                                          DXGI_FORMAT_R16G16B16A16_SNORM,
                                          DXGI_FORMAT_UNKNOWN,
                                          DXGI_FORMAT_UNKNOWN,
+                                         DXGI_FORMAT_UNKNOWN,
                                          DXGI_FORMAT_R16G16B16A16_SNORM,
                                          GL_RGBA16_SNORM_EXT,
                                          nullptr);
             return info;
         }
         case GL_RGBA32F:
         {
             static constexpr Format info(GL_RGBA32F,
                                          angle::Format::ID::R32G32B32A32_FLOAT,
                                          DXGI_FORMAT_R32G32B32A32_FLOAT,
                                          DXGI_FORMAT_R32G32B32A32_FLOAT,
                                          DXGI_FORMAT_R32G32B32A32_FLOAT,
+                                         DXGI_FORMAT_R32G32B32A32_FLOAT,
                                          DXGI_FORMAT_UNKNOWN,
                                          DXGI_FORMAT_R32G32B32A32_FLOAT,
                                          GL_RGBA32F,
                                          nullptr);
             return info;
         }
         case GL_RGBA32I:
         {
             static constexpr Format info(GL_RGBA32I,
                                          angle::Format::ID::R32G32B32A32_SINT,
                                          DXGI_FORMAT_R32G32B32A32_SINT,
                                          DXGI_FORMAT_R32G32B32A32_SINT,
                                          DXGI_FORMAT_R32G32B32A32_SINT,
+                                         DXGI_FORMAT_R32G32B32A32_SINT,
                                          DXGI_FORMAT_UNKNOWN,
                                          DXGI_FORMAT_R32G32B32A32_SINT,
                                          GL_RGBA32I,
                                          nullptr);
             return info;
         }
         case GL_RGBA32UI:
         {
             static constexpr Format info(GL_RGBA32UI,
                                          angle::Format::ID::R32G32B32A32_UINT,
                                          DXGI_FORMAT_R32G32B32A32_UINT,
                                          DXGI_FORMAT_R32G32B32A32_UINT,
                                          DXGI_FORMAT_R32G32B32A32_UINT,
+                                         DXGI_FORMAT_R32G32B32A32_UINT,
                                          DXGI_FORMAT_UNKNOWN,
                                          DXGI_FORMAT_R32G32B32A32_UINT,
                                          GL_RGBA32UI,
                                          nullptr);
             return info;
         }
         case GL_RGBA4:
         {
             if (SupportsFormat(DXGI_FORMAT_B4G4R4A4_UNORM, deviceCaps))
             {
                 static constexpr Format info(GL_RGBA4,
                                              angle::Format::ID::B4G4R4A4_UNORM,
                                              DXGI_FORMAT_B4G4R4A4_UNORM,
                                              DXGI_FORMAT_B4G4R4A4_UNORM,
+                                             DXGI_FORMAT_UNKNOWN,
                                              DXGI_FORMAT_B4G4R4A4_UNORM,
                                              DXGI_FORMAT_UNKNOWN,
                                              DXGI_FORMAT_B4G4R4A4_UNORM,
                                              GL_RGBA4,
                                              nullptr);
                 return info;
             }
             else
             {
                 static constexpr Format info(GL_RGBA4,
                                              angle::Format::ID::R8G8B8A8_UNORM,
                                              DXGI_FORMAT_R8G8B8A8_UNORM,
                                              DXGI_FORMAT_R8G8B8A8_UNORM,
                                              DXGI_FORMAT_R8G8B8A8_UNORM,
+                                             DXGI_FORMAT_R8G8B8A8_UNORM,
                                              DXGI_FORMAT_UNKNOWN,
                                              DXGI_FORMAT_R8G8B8A8_UNORM,
                                              GL_RGBA8,
                                              nullptr);
                 return info;
             }
         }
         case GL_RGBA8:
         {
             static constexpr Format info(GL_RGBA8,
                                          angle::Format::ID::R8G8B8A8_UNORM,
                                          DXGI_FORMAT_R8G8B8A8_UNORM,
                                          DXGI_FORMAT_R8G8B8A8_UNORM,
                                          DXGI_FORMAT_R8G8B8A8_UNORM,
+                                         DXGI_FORMAT_R8G8B8A8_UNORM,
                                          DXGI_FORMAT_UNKNOWN,
                                          DXGI_FORMAT_R8G8B8A8_UNORM,
                                          GL_RGBA8,
                                          nullptr);
             return info;
         }
         case GL_RGBA8I:
         {
             static constexpr Format info(GL_RGBA8I,
                                          angle::Format::ID::R8G8B8A8_SINT,
                                          DXGI_FORMAT_R8G8B8A8_SINT,
                                          DXGI_FORMAT_R8G8B8A8_SINT,
+                                         DXGI_FORMAT_UNKNOWN,
                                          DXGI_FORMAT_R8G8B8A8_SINT,
                                          DXGI_FORMAT_UNKNOWN,
                                          DXGI_FORMAT_R8G8B8A8_SINT,
                                          GL_RGBA8I,
                                          nullptr);
             return info;
         }
         case GL_RGBA8UI:
         {
             static constexpr Format info(GL_RGBA8UI,
                                          angle::Format::ID::R8G8B8A8_UINT,
                                          DXGI_FORMAT_R8G8B8A8_UINT,
                                          DXGI_FORMAT_R8G8B8A8_UINT,
                                          DXGI_FORMAT_R8G8B8A8_UINT,
+                                         DXGI_FORMAT_R8G8B8A8_UINT,
                                          DXGI_FORMAT_UNKNOWN,
                                          DXGI_FORMAT_R8G8B8A8_UINT,
                                          GL_RGBA8UI,
                                          nullptr);
             return info;
         }
         case GL_RGBA8_SNORM:
         {
             static constexpr Format info(GL_RGBA8_SNORM,
                                          angle::Format::ID::R8G8B8A8_SNORM,
                                          DXGI_FORMAT_R8G8B8A8_SNORM,
                                          DXGI_FORMAT_R8G8B8A8_SNORM,
+                                         DXGI_FORMAT_R8G8B8A8_SNORM,
                                          DXGI_FORMAT_UNKNOWN,
                                          DXGI_FORMAT_UNKNOWN,
                                          DXGI_FORMAT_R8G8B8A8_SNORM,
                                          GL_RGBA8_SNORM,
                                          nullptr);
             return info;
         }
         case GL_SRGB8:
         {
             static constexpr Format info(GL_SRGB8,
                                          angle::Format::ID::R8G8B8A8_UNORM_SRGB,
                                          DXGI_FORMAT_R8G8B8A8_UNORM_SRGB,
                                          DXGI_FORMAT_R8G8B8A8_UNORM_SRGB,
+                                         DXGI_FORMAT_UNKNOWN,
                                          DXGI_FORMAT_R8G8B8A8_UNORM_SRGB,
                                          DXGI_FORMAT_UNKNOWN,
                                          DXGI_FORMAT_R8G8B8A8_UNORM_SRGB,
                                          GL_SRGB8_ALPHA8,
                                          Initialize4ComponentData<GLubyte, 0x00, 0x00, 0x00, 0xFF>);
             return info;
         }
         case GL_SRGB8_ALPHA8:
         {
             static constexpr Format info(GL_SRGB8_ALPHA8,
                                          angle::Format::ID::R8G8B8A8_UNORM_SRGB,
                                          DXGI_FORMAT_R8G8B8A8_UNORM_SRGB,
                                          DXGI_FORMAT_R8G8B8A8_UNORM_SRGB,
+                                         DXGI_FORMAT_UNKNOWN,
                                          DXGI_FORMAT_R8G8B8A8_UNORM_SRGB,
                                          DXGI_FORMAT_UNKNOWN,
                                          DXGI_FORMAT_R8G8B8A8_UNORM_SRGB,
                                          GL_SRGB8_ALPHA8,
                                          nullptr);
             return info;
         }
         case GL_STENCIL_INDEX8:
         {
             if (OnlyFL10Plus(deviceCaps))
             {
                 static constexpr Format info(GL_STENCIL_INDEX8,
                                              angle::Format::ID::D24_UNORM_S8_UINT,
                                              DXGI_FORMAT_R24G8_TYPELESS,
                                              DXGI_FORMAT_R24_UNORM_X8_TYPELESS,
                                              DXGI_FORMAT_UNKNOWN,
+                                             DXGI_FORMAT_UNKNOWN,
                                              DXGI_FORMAT_D24_UNORM_S8_UINT,
                                              DXGI_FORMAT_R24_UNORM_X8_TYPELESS,
                                              GL_RGBA32F,
                                              nullptr);
                 return info;
             }
             else
             {
                 static constexpr Format info(GL_STENCIL_INDEX8,
                                              angle::Format::ID::D24_UNORM_S8_UINT,
                                              DXGI_FORMAT_D24_UNORM_S8_UINT,
                                              DXGI_FORMAT_UNKNOWN,
                                              DXGI_FORMAT_UNKNOWN,
+                                             DXGI_FORMAT_UNKNOWN,
                                              DXGI_FORMAT_D24_UNORM_S8_UINT,
                                              DXGI_FORMAT_UNKNOWN,
                                              GL_RGBA32F,
                                              nullptr);
                 return info;
             }
         }
 
--- a/gfx/angle/src/libANGLE/renderer/d3d/d3d9/Buffer9.cpp
+++ b/gfx/angle/src/libANGLE/renderer/d3d/d3d9/Buffer9.cpp
@@ -17,21 +17,31 @@ Buffer9::Buffer9(const gl::BufferState &
 {
 }
 
 Buffer9::~Buffer9()
 {
     mSize = 0;
 }
 
+size_t Buffer9::getSize() const
+{
+    return mSize;
+}
+
+bool Buffer9::supportsDirectBinding() const
+{
+    return false;
+}
+
 gl::Error Buffer9::setData(const gl::Context *context,
-                           GLenum /*target*/,
+                           gl::BufferBinding /*target*/,
                            const void *data,
                            size_t size,
-                           GLenum usage)
+                           gl::BufferUsage usage)
 {
     if (size > mMemory.size())
     {
         if (!mMemory.resize(size))
         {
             return gl::OutOfMemory() << "Failed to resize internal buffer.";
         }
     }
@@ -51,17 +61,17 @@ gl::Error Buffer9::setData(const gl::Con
 
 gl::Error Buffer9::getData(const gl::Context *context, const uint8_t **outData)
 {
     *outData = mMemory.data();
     return gl::NoError();
 }
 
 gl::Error Buffer9::setSubData(const gl::Context *context,
-                              GLenum /*target*/,
+                              gl::BufferBinding /*target*/,
                               const void *data,
                               size_t size,
                               size_t offset)
 {
     if (offset + size > mMemory.size())
     {
         if (!mMemory.resize(offset + size))
         {
--- a/gfx/angle/src/libANGLE/renderer/d3d/d3d9/Buffer9.h
+++ b/gfx/angle/src/libANGLE/renderer/d3d/d3d9/Buffer9.h
@@ -16,31 +16,31 @@
 namespace rx
 {
 class Renderer9;
 
 class Buffer9 : public BufferD3D
 {
   public:
     Buffer9(const gl::BufferState &state, Renderer9 *renderer);
-    virtual ~Buffer9();
+    ~Buffer9() override;
 
     // BufferD3D implementation
-    virtual size_t getSize() const { return mSize; }
-    virtual bool supportsDirectBinding() const { return false; }
+    size_t getSize() const override;
+    bool supportsDirectBinding() const override;
     gl::Error getData(const gl::Context *context, const uint8_t **outData) override;
 
     // BufferImpl implementation
     gl::Error setData(const gl::Context *context,
-                      GLenum target,
+                      gl::BufferBinding target,
                       const void *data,
                       size_t size,
-                      GLenum usage) override;
+                      gl::BufferUsage usage) override;
     gl::Error setSubData(const gl::Context *context,
-                         GLenum target,
+                         gl::BufferBinding target,
                          const void *data,
                          size_t size,
                          size_t offset) override;
     gl::Error copySubData(const gl::Context *context,
                           BufferImpl *source,
                           GLintptr sourceOffset,
                           GLintptr destOffset,
                           GLsizeiptr size) override;
--- a/gfx/angle/src/libANGLE/renderer/d3d/d3d9/Context9.cpp
+++ b/gfx/angle/src/libANGLE/renderer/d3d/d3d9/Context9.cpp
@@ -126,22 +126,22 @@ ProgramPipelineImpl *Context9::createPro
     return nullptr;
 }
 
 std::vector<PathImpl *> Context9::createPaths(GLsizei)
 {
     return std::vector<PathImpl *>();
 }
 
-gl::Error Context9::flush()
+gl::Error Context9::flush(const gl::Context *context)
 {
     return mRenderer->flush();
 }
 
-gl::Error Context9::finish()
+gl::Error Context9::finish(const gl::Context *context)
 {
     return mRenderer->finish();
 }
 
 gl::Error Context9::drawArrays(const gl::Context *context, GLenum mode, GLint first, GLsizei count)
 {
     return mRenderer->genericDrawArrays(context, mode, first, count, 0);
 }
@@ -235,16 +235,28 @@ void Context9::pushGroupMarker(GLsizei l
     }
 }
 
 void Context9::popGroupMarker()
 {
     mRenderer->getAnnotator()->endEvent();
 }
 
+void Context9::pushDebugGroup(GLenum source, GLuint id, GLsizei length, const char *message)
+{
+    // Fall through to the EXT_debug_marker functions
+    pushGroupMarker(length, message);
+}
+
+void Context9::popDebugGroup()
+{
+    // Fall through to the EXT_debug_marker functions
+    popGroupMarker();
+}
+
 void Context9::syncState(const gl::Context *context, const gl::State::DirtyBits &dirtyBits)
 {
     mRenderer->getStateManager()->syncState(mState.getState(), dirtyBits);
 }
 
 GLint Context9::getGPUDisjoint()
 {
     return mRenderer->getGPUDisjoint();
@@ -283,9 +295,27 @@ gl::Error Context9::dispatchCompute(cons
                                     GLuint numGroupsX,
                                     GLuint numGroupsY,
                                     GLuint numGroupsZ)
 {
     UNREACHABLE();
     return gl::InternalError() << "D3D9 doesn't support ES 3.1 DispatchCompute API";
 }
 
+gl::Error Context9::dispatchComputeIndirect(const gl::Context *context, GLintptr indirect)
+{
+    UNREACHABLE();
+    return gl::InternalError() << "D3D9 doesn't support ES 3.1 dispatchComputeIndirect API";
+}
+
+gl::Error Context9::memoryBarrier(const gl::Context *context, GLbitfield barriers)
+{
+    UNREACHABLE();
+    return gl::InternalError() << "D3D9 doesn't support ES 3.1 memoryBarrier API";
+}
+
+gl::Error Context9::memoryBarrierByRegion(const gl::Context *context, GLbitfield barriers)
+{
+    UNREACHABLE();
+    return gl::InternalError() << "D3D9 doesn't support ES 3.1 memoryBarrierByRegion API";
+}
+
 }  // namespace rx
--- a/gfx/angle/src/libANGLE/renderer/d3d/d3d9/Context9.h
+++ b/gfx/angle/src/libANGLE/renderer/d3d/d3d9/Context9.h
@@ -58,18 +58,18 @@ class Context9 : public ContextImpl
 
     // Program Pipeline object creation
     ProgramPipelineImpl *createProgramPipeline(const gl::ProgramPipelineState &data) override;
 
     // Path object creation
     std::vector<PathImpl *> createPaths(GLsizei) override;
 
     // Flush and finish.
-    gl::Error flush() override;
-    gl::Error finish() override;
+    gl::Error flush(const gl::Context *context) override;
+    gl::Error finish(const gl::Context *context) override;
 
     // Drawing methods.
     gl::Error drawArrays(const gl::Context *context,
                          GLenum mode,
                          GLint first,
                          GLsizei count) override;
     gl::Error drawArraysInstanced(const gl::Context *context,
                                   GLenum mode,
@@ -105,21 +105,25 @@ class Context9 : public ContextImpl
 
     // Device loss
     GLenum getResetStatus() override;
 
     // Vendor and description strings.
     std::string getVendorString() const override;
     std::string getRendererDescription() const override;
 
-    // Debug markers.
+    // EXT_debug_marker
     void insertEventMarker(GLsizei length, const char *marker) override;
     void pushGroupMarker(GLsizei length, const char *marker) override;
     void popGroupMarker() override;
 
+    // KHR_debug
+    void pushDebugGroup(GLenum source, GLuint id, GLsizei length, const char *message) override;
+    void popDebugGroup() override;
+
     // State sync with dirty bits.
     void syncState(const gl::Context *context, const gl::State::DirtyBits &dirtyBits) override;
 
     // Disjoint timer queries
     GLint getGPUDisjoint() override;
     GLint64 getTimestamp() override;
 
     // Context switching
@@ -130,16 +134,20 @@ class Context9 : public ContextImpl
     const gl::TextureCapsMap &getNativeTextureCaps() const override;
     const gl::Extensions &getNativeExtensions() const override;
     const gl::Limitations &getNativeLimitations() const override;
 
     gl::Error dispatchCompute(const gl::Context *context,
                               GLuint numGroupsX,
                               GLuint numGroupsY,
                               GLuint numGroupsZ) override;
+    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;
 
     Renderer9 *getRenderer() const { return mRenderer; }
 
   private:
     Renderer9 *mRenderer;
 };
 
 }  // namespace rx
--- a/gfx/angle/src/libANGLE/renderer/d3d/d3d9/Framebuffer9.cpp
+++ b/gfx/angle/src/libANGLE/renderer/d3d/d3d9/Framebuffer9.cpp
@@ -80,18 +80,16 @@ gl::Error Framebuffer9::clearImpl(const 
 gl::Error Framebuffer9::readPixelsImpl(const gl::Context *context,
                                        const gl::Rectangle &area,
                                        GLenum format,
                                        GLenum type,
                                        size_t outputPitch,
                                        const gl::PixelPackState &pack,
                                        uint8_t *pixels)
 {
-    ASSERT(pack.pixelBuffer.get() == nullptr);
-
     const gl::FramebufferAttachment *colorbuffer = mState.getColorAttachment(0);
     ASSERT(colorbuffer);
 
     RenderTarget9 *renderTarget = nullptr;
     ANGLE_TRY(colorbuffer->getRenderTarget(context, &renderTarget));
     ASSERT(renderTarget);
 
     IDirect3DSurface9 *surface = renderTarget->getSurface();
@@ -186,26 +184,25 @@ gl::Error Framebuffer9::readPixelsImpl(c
     }
 
     uint8_t *source = reinterpret_cast<uint8_t *>(lock.pBits);
     int inputPitch  = lock.Pitch;
 
     const d3d9::D3DFormat &d3dFormatInfo = d3d9::GetD3DFormatInfo(desc.Format);
     gl::FormatType formatType(format, type);
 
-    // TODO(jmadill): Maybe we can avoid a copy of pack parameters here?
     PackPixelsParams packParams;
     packParams.area.x      = rect.left;
     packParams.area.y      = rect.top;
     packParams.area.width  = rect.right - rect.left;
     packParams.area.height = rect.bottom - rect.top;
     packParams.format      = format;
     packParams.type        = type;
     packParams.outputPitch = static_cast<GLuint>(outputPitch);
-    packParams.pack.copyFrom(context, pack);
+    packParams.pack        = pack;
 
     PackPixels(packParams, d3dFormatInfo.info(), inputPitch, source, pixels);
 
     systemSurface->UnlockRect();
     SafeRelease(systemSurface);
 
     return gl::NoError();
 }
--- a/gfx/angle/src/libANGLE/renderer/d3d/d3d9/Framebuffer9.h
+++ b/gfx/angle/src/libANGLE/renderer/d3d/d3d9/Framebuffer9.h
@@ -14,17 +14,17 @@
 namespace rx
 {
 class Renderer9;
 
 class Framebuffer9 : public FramebufferD3D
 {
   public:
     Framebuffer9(const gl::FramebufferState &data, Renderer9 *renderer);
-    virtual ~Framebuffer9();
+    ~Framebuffer9() 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,
                          const GLenum *attachments) override;
     gl::Error invalidateSub(const gl::Context *context,
                             size_t count,
                             const GLenum *attachments,
--- a/gfx/angle/src/libANGLE/renderer/d3d/d3d9/Image9.cpp
+++ b/gfx/angle/src/libANGLE/renderer/d3d/d3d9/Image9.cpp
@@ -99,34 +99,22 @@ gl::Error Image9::generateMip(IDirect3DS
     sourceSurface->UnlockRect();
 
     return gl::NoError();
 }
 
 gl::Error Image9::generateMipmap(Image9 *dest, Image9 *source)
 {
     IDirect3DSurface9 *sourceSurface = nullptr;
-    gl::Error error = source->getSurface(&sourceSurface);
-    if (error.isError())
-    {
-        return error;
-    }
+    ANGLE_TRY(source->getSurface(&sourceSurface));
 
     IDirect3DSurface9 *destSurface = nullptr;
-    error = dest->getSurface(&destSurface);
-    if (error.isError())
-    {
-        return error;
-    }
+    ANGLE_TRY(dest->getSurface(&destSurface));
 
-    error = generateMip(destSurface, sourceSurface);
-    if (error.isError())
-    {
-        return error;
-    }
+    ANGLE_TRY(generateMip(destSurface, sourceSurface));
 
     dest->markDirty();
 
     return gl::NoError();
 }
 
 gl::Error Image9::copyLockableSurfaces(IDirect3DSurface9 *dest, IDirect3DSurface9 *source)
 {
@@ -166,16 +154,94 @@ gl::Error Image9::copyLockableSurfaces(I
     }
 
     source->UnlockRect();
     dest->UnlockRect();
 
     return gl::NoError();
 }
 
+// static
+gl::Error Image9::CopyImage(const gl::Context *context,
+                            Image9 *dest,
+                            Image9 *source,
+                            const gl::Rectangle &sourceRect,
+                            const gl::Offset &destOffset,
+                            bool unpackFlipY,
+                            bool unpackPremultiplyAlpha,
+                            bool unpackUnmultiplyAlpha)
+{
+    IDirect3DSurface9 *sourceSurface = nullptr;
+    ANGLE_TRY(source->getSurface(&sourceSurface));
+
+    IDirect3DSurface9 *destSurface = nullptr;
+    ANGLE_TRY(dest->getSurface(&destSurface));
+
+    D3DSURFACE_DESC destDesc;
+    HRESULT result = destSurface->GetDesc(&destDesc);
+    ASSERT(SUCCEEDED(result));
+    if (FAILED(result))
+    {
+        return gl::OutOfMemory()
+               << "Failed to query the source surface description for mipmap generation, "
+               << gl::FmtHR(result);
+    }
+    const d3d9::D3DFormat &destD3DFormatInfo = d3d9::GetD3DFormatInfo(destDesc.Format);
+
+    D3DSURFACE_DESC sourceDesc;
+    result = sourceSurface->GetDesc(&sourceDesc);
+    ASSERT(SUCCEEDED(result));
+    if (FAILED(result))
+    {
+        return gl::OutOfMemory()
+               << "Failed to query the destination surface description for mipmap generation, "
+               << gl::FmtHR(result);
+    }
+    const d3d9::D3DFormat &sourceD3DFormatInfo = d3d9::GetD3DFormatInfo(sourceDesc.Format);
+
+    D3DLOCKED_RECT sourceLocked = {0};
+    result                      = sourceSurface->LockRect(&sourceLocked, nullptr, D3DLOCK_READONLY);
+    ASSERT(SUCCEEDED(result));
+    if (FAILED(result))
+    {
+        return gl::OutOfMemory() << "Failed to lock the source surface for CopyImage, "
+                                 << gl::FmtHR(result);
+    }
+
+    D3DLOCKED_RECT destLocked = {0};
+    result                    = destSurface->LockRect(&destLocked, nullptr, 0);
+    ASSERT(SUCCEEDED(result));
+    if (FAILED(result))
+    {
+        sourceSurface->UnlockRect();
+        return gl::OutOfMemory() << "Failed to lock the destination surface for CopyImage, "
+                                 << gl::FmtHR(result);
+    }
+
+    const uint8_t *sourceData = reinterpret_cast<const uint8_t *>(sourceLocked.pBits) +
+                                sourceRect.x * sourceD3DFormatInfo.pixelBytes +
+                                sourceRect.y * sourceLocked.Pitch;
+    uint8_t *destData = reinterpret_cast<uint8_t *>(destLocked.pBits) +
+                        destOffset.x * destD3DFormatInfo.pixelBytes +
+                        destOffset.y * destLocked.Pitch;
+    ASSERT(sourceData && destData);
+
+    CopyImageCHROMIUM(sourceData, sourceLocked.Pitch, sourceD3DFormatInfo.pixelBytes,
+                      sourceD3DFormatInfo.info().colorReadFunction, destData, destLocked.Pitch,
+                      destD3DFormatInfo.pixelBytes, destD3DFormatInfo.info().colorWriteFunction,
+                      gl::GetUnsizedFormat(dest->getInternalFormat()),
+                      destD3DFormatInfo.info().componentType, sourceRect.width, sourceRect.height,
+                      unpackFlipY, unpackPremultiplyAlpha, unpackUnmultiplyAlpha);
+
+    destSurface->UnlockRect();
+    sourceSurface->UnlockRect();
+
+    return gl::NoError();
+}
+
 bool Image9::redefine(GLenum target, 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);
 
@@ -491,26 +557,27 @@ gl::Error Image9::copyToSurface(IDirect3
     return gl::NoError();
 }
 
 // Store the pixel rectangle designated by xoffset,yoffset,width,height with pixels stored as format/type at input
 // into the target pixel rectangle.
 gl::Error Image9::loadData(const gl::Context *context,
                            const gl::Box &area,
                            const gl::PixelUnpackState &unpack,
-                           GLenum inputType,
+                           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 &formatInfo = gl::GetSizedInternalFormatInfo(mInternalFormat);
     GLuint inputRowPitch                 = 0;
     ANGLE_TRY_RESULT(
-        formatInfo.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);
 
@@ -540,17 +607,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/src/libANGLE/renderer/d3d/d3d9/Image9.h
+++ b/gfx/angle/src/libANGLE/renderer/d3d/d3d9/Image9.h
@@ -21,27 +21,35 @@ class Framebuffer;
 namespace rx
 {
 class Renderer9;
 
 class Image9 : public ImageD3D
 {
   public:
     Image9(Renderer9 *renderer);
-    ~Image9();
+    ~Image9() override;
 
     static gl::Error generateMipmap(Image9 *dest, Image9 *source);
     static gl::Error generateMip(IDirect3DSurface9 *destSurface, IDirect3DSurface9 *sourceSurface);
     static gl::Error copyLockableSurfaces(IDirect3DSurface9 *dest, IDirect3DSurface9 *source);
+    static gl::Error CopyImage(const gl::Context *context,
+                               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;
 
     D3DFORMAT getD3DFormat() const;
 
-    virtual bool isDirty() const;
+    bool isDirty() const override;
 
     gl::Error setManagedSurface2D(const gl::Context *context,
                                   TextureStorage *storage,
                                   int level) override;
     gl::Error setManagedSurfaceCube(const gl::Context *context,
                                     TextureStorage *storage,
                                     int face,
                                     int level) override;
--- a/gfx/angle/src/libANGLE/renderer/d3d/d3d9/IndexBuffer9.h
+++ b/gfx/angle/src/libANGLE/renderer/d3d/d3d9/IndexBuffer9.h
@@ -14,28 +14,28 @@
 namespace rx
 {
 class Renderer9;
 
 class IndexBuffer9 : public IndexBuffer
 {
   public:
     explicit IndexBuffer9(Renderer9 *const renderer);
-    virtual ~IndexBuffer9();
+    ~IndexBuffer9() override;
 
-    virtual gl::Error initialize(unsigned int bufferSize, GLenum indexType, bool dynamic);
+    gl::Error initialize(unsigned int bufferSize, GLenum indexType, bool dynamic) override;
 
-    virtual gl::Error mapBuffer(unsigned int offset, unsigned int size, void** outMappedMemory);
-    virtual gl::Error unmapBuffer();
+    gl::Error mapBuffer(unsigned int offset, unsigned int size, void **outMappedMemory) override;
+    gl::Error unmapBuffer() override;
 
-    virtual GLenum getIndexType() const;
-    virtual unsigned int getBufferSize() const;
-    virtual gl::Error setSize(unsigned int bufferSize, GLenum indexType);
+    GLenum getIndexType() const override;
+    unsigned int getBufferSize() const override;
+    gl::Error setSize(unsigned int bufferSize, GLenum indexType) override;
 
-    virtual gl::Error discard();
+    gl::Error discard() override;
 
     D3DFORMAT getIndexFormat() const;
     IDirect3DIndexBuffer9 *getBuffer() const;
 
   private:
     Renderer9 *const mRenderer;
 
     IDirect3DIndexBuffer9 *mIndexBuffer;
--- a/gfx/angle/src/libANGLE/renderer/d3d/d3d9/Query9.h
+++ b/gfx/angle/src/libANGLE/renderer/d3d/d3d9/Query9.h
@@ -14,26 +14,26 @@
 namespace rx
 {
 class Renderer9;
 
 class Query9 : public QueryImpl
 {
   public:
     Query9(Renderer9 *renderer, GLenum type);
-    virtual ~Query9();
+    ~Query9() override;
 
-    virtual gl::Error begin();
-    virtual gl::Error end();
-    virtual gl::Error queryCounter();
-    virtual gl::Error getResult(GLint *params);
-    virtual gl::Error getResult(GLuint *params);
-    virtual gl::Error getResult(GLint64 *params);
-    virtual gl::Error getResult(GLuint64 *params);
-    virtual gl::Error isResultAvailable(bool *available);
+    gl::Error begin() override;
+    gl::Error end() override;
+    gl::Error queryCounter() override;
+    gl::Error getResult(GLint *params) override;
+    gl::Error getResult(GLuint *params) override;
+    gl::Error getResult(GLint64 *params) override;
+    gl::Error getResult(GLuint64 *params) override;
+    gl::Error isResultAvailable(bool *available) override;
 
   private:
     gl::Error testQuery();
 
     template <typename T>
     gl::Error getResultBase(T *params);
 
     GLuint64 mResult;
--- a/gfx/angle/src/libANGLE/renderer/d3d/d3d9/RenderTarget9.h
+++ b/gfx/angle/src/libANGLE/renderer/d3d/d3d9/RenderTarget9.h
@@ -16,17 +16,17 @@ namespace rx
 {
 class Renderer9;
 class SwapChain9;
 
 class RenderTarget9 : public RenderTargetD3D
 {
   public:
     RenderTarget9() { }
-    virtual ~RenderTarget9() { }
+    ~RenderTarget9() override {}
     // Retrieve the texture that backs this render target, may be null for swap chain render
     // targets.
     virtual IDirect3DBaseTexture9 *getTexture() const = 0;
     virtual size_t getTextureLevel() const = 0;
 
     virtual IDirect3DSurface9 *getSurface() const = 0;
 
     virtual D3DFORMAT getD3DFormat() const = 0;
@@ -38,17 +38,17 @@ class TextureRenderTarget9 : public Rend
     TextureRenderTarget9(IDirect3DBaseTexture9 *texture,
                          size_t textureLevel,
                          IDirect3DSurface9 *surface,
                          GLenum internalFormat,
                          GLsizei width,
                          GLsizei height,
                          GLsizei depth,
                          GLsizei samples);
-    virtual ~TextureRenderTarget9();
+    ~TextureRenderTarget9() override;
 
     GLsizei getWidth() const override;
     GLsizei getHeight() const override;
     GLsizei getDepth() const override;
     GLenum getInternalFormat() const override;
     GLsizei getSamples() const override;
 
     IDirect3DBaseTexture9 *getTexture() const override;
@@ -69,17 +69,17 @@ class TextureRenderTarget9 : public Rend
     size_t mTextureLevel;
     IDirect3DSurface9 *mRenderTarget;
 };
 
 class SurfaceRenderTarget9 : public RenderTarget9
 {
   public:
     SurfaceRenderTarget9(SwapChain9 *swapChain, bool depth);
-    virtual ~SurfaceRenderTarget9();
+    ~SurfaceRenderTarget9() override;
 
     GLsizei getWidth() const override;
     GLsizei getHeight() const override;
     GLsizei getDepth() const override;
     GLenum getInternalFormat() const override;
     GLsizei getSamples() const override;
 
     IDirect3DBaseTexture9 *getTexture() const override;
--- a/gfx/angle/src/libANGLE/renderer/d3d/d3d9/Renderer9.cpp
+++ b/gfx/angle/src/libANGLE/renderer/d3d/d3d9/Renderer9.cpp
@@ -94,17 +94,17 @@ Renderer9::Renderer9(egl::Display *displ
     EGLint requestedDeviceType          = static_cast<EGLint>(attributes.get(
         EGL_PLATFORM_ANGLE_DEVICE_TYPE_ANGLE, EGL_PLATFORM_ANGLE_DEVICE_TYPE_HARDWARE_ANGLE));
     switch (requestedDeviceType)
     {
         case EGL_PLATFORM_ANGLE_DEVICE_TYPE_HARDWARE_ANGLE:
             mDeviceType = D3DDEVTYPE_HAL;
             break;
 
-        case EGL_PLATFORM_ANGLE_DEVICE_TYPE_REFERENCE_ANGLE:
+        case EGL_PLATFORM_ANGLE_DEVICE_TYPE_D3D_REFERENCE_ANGLE:
             mDeviceType = D3DDEVTYPE_REF;
             break;
 
         case EGL_PLATFORM_ANGLE_DEVICE_TYPE_NULL_ANGLE:
             mDeviceType = D3DDEVTYPE_NULLREF;
             break;
 
         default:
@@ -375,17 +375,17 @@ egl::Error Renderer9::initializeDevice()
     mSceneStarted = false;
 
     ASSERT(!mBlit);
     mBlit = new Blit9(this);
     ANGLE_TRY(mBlit->initialize());
 
     ASSERT(!mVertexDataManager && !mIndexDataManager);
     mVertexDataManager = new VertexDataManager(this);
-    mIndexDataManager  = new IndexDataManager(this, getRendererClass());
+    mIndexDataManager  = new IndexDataManager(this);
 
     if (mVertexDataManager->initialize().isError())
     {
         return egl::EglBadAlloc() << "Error initializing VertexDataManager";
     }
 
     mTranslatedAttribCache.resize(getNativeCaps().maxVertexAttributes);
 
@@ -572,16 +572,18 @@ void Renderer9::generateDisplayExtension
 
     outExtensions->flexibleSurfaceCompatibility = true;
 
     // Contexts are virtualized so textures can be shared globally
     outExtensions->displayTextureShareGroup = true;
 
     // D3D9 can be used without an output surface
     outExtensions->surfacelessContext = true;
+
+    outExtensions->robustResourceInitialization = true;
 }
 
 void Renderer9::startScene()
 {
     if (!mSceneStarted)
     {
         long result = mDevice->BeginScene();
         if (SUCCEEDED(result))
@@ -899,17 +901,17 @@ HRESULT Renderer9::createIndexBuffer(UIN
     return mDevice->CreateIndexBuffer(Length, Usage, Format, Pool, ppIndexBuffer, nullptr);
 }
 
 IndexBuffer *Renderer9::createIndexBuffer()
 {
     return new IndexBuffer9(this);
 }
 
-StreamProducerImpl *Renderer9::createStreamProducerD3DTextureNV12(
+StreamProducerImpl *Renderer9::createStreamProducerD3DTexture(
     egl::Stream::ConsumerType consumerType,
     const egl::AttributeMap &attribs)
 {
     // Streams are not supported under D3D9
     UNREACHABLE();
     return nullptr;
 }
 
@@ -928,39 +930,40 @@ gl::Error Renderer9::fastCopyBufferToTex
                                              const gl::Box &destArea)
 {
     // Pixel buffer objects are not supported in D3D9, since D3D9 is ES2-only and PBOs are ES3.
     UNREACHABLE();
     return gl::InternalError();
 }
 
 gl::Error Renderer9::setSamplerState(const gl::Context *context,
-                                     gl::SamplerType type,
+                                     gl::ShaderType type,
                                      int index,
                                      gl::Texture *texture,
                                      const gl::SamplerState &samplerState)
 {
-    CurSamplerState &appliedSampler = (type == gl::SAMPLER_PIXEL) ? mCurPixelSamplerStates[index]
-                                                                  : mCurVertexSamplerStates[index];
+    CurSamplerState &appliedSampler = (type == gl::SHADER_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));
 
     // 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::SAMPLER_PIXEL) ? 0 : D3DVERTEXTEXTURESAMPLER0;
+        int d3dSamplerOffset = (type == gl::SHADER_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(
@@ -986,27 +989,27 @@ gl::Error Renderer9::setSamplerState(con
     appliedSampler.forceSet     = false;
     appliedSampler.samplerState = samplerState;
     appliedSampler.baseLevel    = baseLevel;
 
     return gl::NoError();
 }
 
 gl::Error Renderer9::setTexture(const gl::Context *context,
-                                gl::SamplerType type,
+                                gl::ShaderType type,
                                 int index,
                                 gl::Texture *texture)
 {
-    int d3dSamplerOffset              = (type == gl::SAMPLER_PIXEL) ? 0 : D3DVERTEXTEXTURESAMPLER0;
+    int d3dSamplerOffset = (type == gl::SHADER_FRAGMENT) ? 0 : D3DVERTEXTEXTURESAMPLER0;
     int d3dSampler                    = index + d3dSamplerOffset;
     IDirect3DBaseTexture9 *d3dTexture = nullptr;
     bool forceSetTexture              = false;
 
     std::vector<uintptr_t> &appliedTextures =
-        (type == gl::SAMPLER_PIXEL) ? mCurPixelTextures : mCurVertexTextures;
+        (type == gl::SHADER_FRAGMENT) ? mCurPixelTextures : mCurVertexTextures;
 
     if (texture)
     {
         TextureD3D *textureImpl = GetImplAs<TextureD3D>(texture);
 
         TextureStorage *texStorage = nullptr;
         ANGLE_TRY(textureImpl->getNativeTexture(context, &texStorage));
 
@@ -1052,17 +1055,17 @@ gl::Error Renderer9::updateState(const g
     // Setting scissors state
     setScissorRectangle(glState.getScissor(), glState.isScissorTestEnabled());
 
     // Setting blend, depth stencil, and rasterizer states
     // Since framebuffer->getSamples will return the original samples which may be different with
     // the sample counts that we set in render target view, here we use renderTarget->getSamples to
     // get the actual samples.
     GLsizei samples           = 0;
-    auto firstColorAttachment = framebuffer->getFirstColorbuffer();
+    const gl::FramebufferAttachment *firstColorAttachment = framebuffer->getFirstColorbuffer();
     if (firstColorAttachment)
     {
         ASSERT(firstColorAttachment->isAttached());
         RenderTarget9 *renderTarget = nullptr;
         ANGLE_TRY(firstColorAttachment->getRenderTarget(context, &renderTarget));
         samples = renderTarget->getSamples();
     }
     gl::RasterizerState rasterizer = glState.getRasterizerState();
@@ -1080,23 +1083,23 @@ gl::Error Renderer9::updateState(const g
 void Renderer9::setScissorRectangle(const gl::Rectangle &scissor, bool enabled)
 {
     mStateManager.setScissorState(scissor, enabled);
 }
 
 gl::Error Renderer9::setBlendDepthRasterStates(const gl::Context *context, GLenum drawMode)
 {
     const auto &glState  = context->getGLState();
-    auto drawFramebuffer = glState.getDrawFramebuffer();
+    gl::Framebuffer *drawFramebuffer = glState.getDrawFramebuffer();
     ASSERT(!drawFramebuffer->hasAnyDirtyBit());
     // Since framebuffer->getSamples will return the original samples which may be different with
     // the sample counts that we set in render target view, here we use renderTarget->getSamples to
     // get the actual samples.
     GLsizei samples           = 0;
-    auto firstColorAttachment = drawFramebuffer->getFirstColorbuffer();
+    const gl::FramebufferAttachment *firstColorAttachment = drawFramebuffer->getFirstColorbuffer();
     if (firstColorAttachment)
     {
         ASSERT(firstColorAttachment->isAttached());
         RenderTarget9 *renderTarget = nullptr;
         ANGLE_TRY(firstColorAttachment->getRenderTarget(context, &renderTarget));
         samples = renderTarget->getSamples();
     }
     gl::RasterizerState rasterizer = glState.getRasterizerState();
@@ -1335,22 +1338,22 @@ gl::Error Renderer9::applyIndexBuffer(co
                                       const void *indices,
                                       GLsizei count,
                                       GLenum mode,
                                       GLenum type,
                                       TranslatedIndexData *indexInfo)
 {
     gl::VertexArray *vao           = context->getGLState().getVertexArray();
     gl::Buffer *elementArrayBuffer = vao->getElementArrayBuffer().get();
-    gl::Error error = mIndexDataManager->prepareIndexData(context, type, count, elementArrayBuffer,
-                                                          indices, indexInfo, false);
-    if (error.isError())
-    {
-        return error;
-    }
+    const auto &lazyIndexRange     = context->getParams<gl::HasIndexRange>();
+
+    GLenum dstType = GetIndexTranslationDestType(type, lazyIndexRange, false);
+
+    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)
     {
         IndexBuffer9 *indexBuffer = GetAs<IndexBuffer9>(indexInfo->indexBuffer);
 
@@ -1409,27 +1412,28 @@ gl::Error Renderer9::drawArraysImpl(cons
 gl::Error Renderer9::drawElementsImpl(const gl::Context *context,
                                       GLenum mode,
                                       GLsizei count,
                                       GLenum type,
                                       const void *indices,
                                       GLsizei instances)
 {
     TranslatedIndexData indexInfo;
-    const gl::IndexRange &indexRange =
-        context->getParams<gl::HasIndexRange>().getIndexRange().value();
-    indexInfo.indexRange = indexRange;
+
     ANGLE_TRY(applyIndexBuffer(context, indices, count, mode, type, &indexInfo));
-    size_t vertexCount = indexInfo.indexRange.vertexCount();
-    ANGLE_TRY(applyVertexBuffer(context, mode, static_cast<GLsizei>(indexInfo.indexRange.start),
+
+    const auto &lazyIndexRange       = context->getParams<gl::HasIndexRange>();
+    const gl::IndexRange &indexRange = lazyIndexRange.getIndexRange().value();
+    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>(indexInfo.indexRange.start);
+    int minIndex = static_cast<int>(indexRange.start);
 
     gl::VertexArray *vao           = context->getGLState().getVertexArray();
     gl::Buffer *elementArrayBuffer = vao->getElementArrayBuffer().get();
 
     if (mode == GL_POINTS)
     {
         return drawIndexedPoints(context, count, type, indices, minIndex, elementArrayBuffer);
     }
@@ -2677,38 +2681,38 @@ gl::Error Renderer9::createRenderTargetC
     }
 
     *outRT = newRT;
     return gl::NoError();
 }
 
 gl::Error Renderer9::loadExecutable(const uint8_t *function,
                                     size_t length,
-                                    ShaderType type,
+                                    gl::ShaderType type,
                                     const std::vector<D3DVarying> &streamOutVaryings,
                                     bool separatedOutputBuffers,
                                     ShaderExecutableD3D **outExecutable)
 {
     // Transform feedback is not supported in ES2 or D3D9
     ASSERT(streamOutVaryings.empty());
 
     switch (type)
     {
-        case SHADER_VERTEX:
+        case gl::SHADER_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 SHADER_PIXEL:
+        case gl::SHADER_FRAGMENT:
         {
             IDirect3DPixelShader9 *pshader = nullptr;
             gl::Error error                = createPixelShader((DWORD *)function, length, &pshader);
             if (error.isError())
             {
                 return error;
             }
             *outExecutable = new ShaderExecutable9(function, length, pshader);
@@ -2719,33 +2723,33 @@ gl::Error Renderer9::loadExecutable(cons
             return gl::InternalError();
     }
 
     return gl::NoError();
 }
 
 gl::Error Renderer9::compileToExecutable(gl::InfoLog &infoLog,
                                          const std::string &shaderHLSL,
-                                         ShaderType type,
+                                         gl::ShaderType type,
                                          const std::vector<D3DVarying> &streamOutVaryings,
                                          bool separatedOutputBuffers,
                                          const angle::CompilerWorkaroundsD3D &workarounds,
                                          ShaderExecutableD3D **outExectuable)
 {
     // Transform feedback is not supported in ES2 or D3D9
     ASSERT(streamOutVaryings.empty());
 
     std::stringstream profileStream;
 
     switch (type)
     {
-        case SHADER_VERTEX:
+        case gl::SHADER_VERTEX:
             profileStream << "vs";
             break;
-        case SHADER_PIXEL:
+        case gl::SHADER_FRAGMENT:
             profileStream << "ps";
             break;
         default:
             UNREACHABLE();
             return gl::InternalError();
     }
 
     profileStream << "_" << ((getMajorShaderModel() >= 3) ? 3 : 2);
@@ -2884,16 +2888,21 @@ gl::Error Renderer9::copyToRenderTarget(
     {
         ASSERT(result == D3DERR_OUTOFVIDEOMEMORY || result == E_OUTOFMEMORY);
         return gl::OutOfMemory() << "Failed to blit internal texture, " << gl::FmtHR(result);
     }
 
     return gl::NoError();
 }
 
+RendererClass Renderer9::getRendererClass() const
+{
+    return RENDERER_D3D9;
+}
+
 ImageD3D *Renderer9::createImage()
 {
     return new Image9(this);
 }
 
 gl::Error Renderer9::generateMipmap(const gl::Context *context, ImageD3D *dest, ImageD3D *src)
 {
     Image9 *src9 = GetAs<Image9>(src);
@@ -2913,18 +2922,20 @@ gl::Error Renderer9::copyImage(const gl:
                                ImageD3D *dest,
                                ImageD3D *source,
                                const gl::Rectangle &sourceRect,
                                const gl::Offset &destOffset,
                                bool unpackFlipY,
                                bool unpackPremultiplyAlpha,
                                bool unpackUnmultiplyAlpha)
 {
-    UNREACHABLE();
-    return gl::NoError();
+    Image9 *dest9 = GetAs<Image9>(dest);
+    Image9 *src9  = GetAs<Image9>(source);
+    return Image9::CopyImage(context, dest9, src9, sourceRect, destOffset, unpackFlipY,
+                             unpackPremultiplyAlpha, unpackUnmultiplyAlpha);
 }
 
 TextureStorage *Renderer9::createTextureStorage2D(SwapChainD3D *swapChain)
 {
     SwapChain9 *swapChain9 = GetAs<SwapChain9>(swapChain);
     return new TextureStorage9_2D(this, swapChain9);
 }
 
@@ -2988,17 +2999,17 @@ TextureStorage *Renderer9::createTexture
     return nullptr;
 }
 
 TextureStorage *Renderer9::createTextureStorage2DMultisample(GLenum internalformat,
                                                              GLsizei width,
                                                              GLsizei height,
                                                              int levels,
                                                              int samples,
-                                                             GLboolean fixedSampleLocations)
+                                                             bool fixedSampleLocations)
 {
     // 2D multisampled textures are not supported by the D3D9 backend.
     UNREACHABLE();
 
     return NULL;
 }
 
 bool Renderer9::getLUID(LUID *adapterLuid) const
@@ -3171,101 +3182,130 @@ gl::Version Renderer9::getMaxSupportedES
     return gl::Version(2, 0);
 }
 
 gl::Error Renderer9::clearRenderTarget(RenderTargetD3D *renderTarget,
                                        const gl::ColorF &clearColorValue,
                                        const float clearDepthValue,
                                        const unsigned int clearStencilValue)
 {
-    UNIMPLEMENTED();
-    return gl::InternalError() << "clearRenderTarget is not implemented on D3D9";
+    D3DCOLOR color =
+        D3DCOLOR_ARGB(gl::unorm<8>(clearColorValue.alpha), gl::unorm<8>(clearColorValue.red),
+                      gl::unorm<8>(clearColorValue.green), gl::unorm<8>(clearColorValue.blue));
+    float depth   = clearDepthValue;
+    DWORD stencil = clearStencilValue & 0x000000FF;
+
+    unsigned int renderTargetSerial        = renderTarget->getSerial();
+    RenderTarget9 *renderTarget9           = GetAs<RenderTarget9>(renderTarget);
+    IDirect3DSurface9 *renderTargetSurface = renderTarget9->getSurface();
+    ASSERT(renderTargetSurface);
+
+    DWORD dxClearFlags = 0;
+
+    const gl::InternalFormat &internalFormatInfo =
+        gl::GetSizedInternalFormatInfo(renderTarget->getInternalFormat());
+    if (internalFormatInfo.depthBits > 0 || internalFormatInfo.stencilBits > 0)
+    {
+        dxClearFlags = D3DCLEAR_ZBUFFER | D3DCLEAR_STENCIL;
+        if (mAppliedDepthStencilSerial != renderTargetSerial)
+        {
+            mDevice->SetDepthStencilSurface(renderTargetSurface);
+        }
+    }
+    else
+    {
+        dxClearFlags = D3DCLEAR_TARGET;
+        if (mAppliedRenderTargetSerial != renderTargetSerial)
+        {
+            mDevice->SetRenderTarget(0, renderTargetSurface);
+        }
+    }
+    SafeRelease(renderTargetSurface);
+
+    D3DVIEWPORT9 viewport;
+    viewport.X      = 0;
+    viewport.Y      = 0;
+    viewport.Width  = renderTarget->getWidth();
+    viewport.Height = renderTarget->getHeight();
+    mDevice->SetViewport(&viewport);
+
+    mDevice->SetRenderState(D3DRS_SCISSORTESTENABLE, FALSE);
+
+    mDevice->Clear(0, nullptr, dxClearFlags, color, depth, stencil);
+
+    markAllStateDirty();
+
+    return gl::NoError();
+}
+
+bool Renderer9::canSelectViewInVertexShader() const
+{
+    return false;
 }
 
 // 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 Renderer9::applyTextures(const gl::Context *context,
-                                   gl::SamplerType shaderType,
-                                   const FramebufferTextureArray &framebufferTextures,
-                                   size_t framebufferTextureCount)
+gl::Error Renderer9::applyTextures(const gl::Context *context, gl::ShaderType shaderType)
 {
     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();
 
     unsigned int samplerRange = programD3D->getUsedSamplerRange(shaderType);
     for (unsigned int samplerIndex = 0; samplerIndex < samplerRange; samplerIndex++)
     {
-        GLenum textureType = programD3D->getSamplerTextureType(shaderType, samplerIndex);
-        GLint textureUnit  = programD3D->getSamplerMapping(shaderType, samplerIndex, caps);
-        if (textureUnit != -1)
+        GLint textureUnit = programD3D->getSamplerMapping(shaderType, samplerIndex, caps);
+        ASSERT(textureUnit != -1);
+        gl::Texture *texture = completeTextures[textureUnit];
+
+        // A nullptr texture indicates incomplete.
+        if (texture)
         {
-            gl::Texture *texture = completeTextures[textureUnit];
-
-            // A nullptr texture indicates incomplete.
-            if (texture &&
-                !std::binary_search(framebufferTextures.begin(),
-                                    framebufferTextures.begin() + framebufferTextureCount, texture))
-            {
-                gl::Sampler *samplerObject = glState.getSampler(textureUnit);
-
-                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
-            {
-                // 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));
-            }
+            gl::Sampler *samplerObject = glState.getSampler(textureUnit);
+
+            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
         {
-            // No texture bound to this slot even though it is used by the shader, bind a NULL
-            // texture
-            ANGLE_TRY(setTexture(context, shaderType, samplerIndex, nullptr));
+            GLenum 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::SAMPLER_PIXEL) ? caps.maxTextureImageUnits
-                                                            : caps.maxVertexTextureImageUnits;
+    size_t samplerCount = (shaderType == gl::SHADER_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)
 {
-    FramebufferTextureArray framebufferTextures;
-    size_t framebufferSerialCount =
-        getBoundFramebufferTextures(context->getContextState(), &framebufferTextures);
-
-    ANGLE_TRY(
-        applyTextures(context, gl::SAMPLER_VERTEX, framebufferTextures, framebufferSerialCount));
-    ANGLE_TRY(
-        applyTextures(context, gl::SAMPLER_PIXEL, framebufferTextures, framebufferSerialCount));
+    ANGLE_TRY(applyTextures(context, gl::SHADER_VERTEX));
+    ANGLE_TRY(applyTextures(context, gl::SHADER_FRAGMENT));
     return gl::NoError();
 }
 
 }  // namespace rx
--- a/gfx/angle/src/libANGLE/renderer/d3d/d3d9/Renderer9.h
+++ b/gfx/angle/src/libANGLE/renderer/d3d/d3d9/Renderer9.h
@@ -62,17 +62,17 @@ enum D3D9InitError
     D3D9_INIT_OTHER_ERROR,
     NUM_D3D9_INIT_ERRORS
 };
 
 class Renderer9 : public RendererD3D
 {
   public:
     explicit Renderer9(egl::Display *display);
-    virtual ~Renderer9();
+    ~Renderer9() override;
 
     egl::Error initialize() override;
     bool resetDevice() override;
 
     egl::ConfigSet generateConfigs() override;
     void generateDisplayExtensions(egl::DisplayExtensions *outExtensions) const override;
 
     void startScene();
@@ -115,22 +115,22 @@ class Renderer9 : public RendererD3D
                                 size_t length,
                                 IDirect3DPixelShader9 **outShader);
     HRESULT createVertexBuffer(UINT Length, DWORD Usage, IDirect3DVertexBuffer9 **ppVertexBuffer);
     HRESULT createIndexBuffer(UINT Length,
                               DWORD Usage,
                               D3DFORMAT Format,
                               IDirect3DIndexBuffer9 **ppIndexBuffer);
     gl::Error setSamplerState(const gl::Context *context,
-                              gl::SamplerType type,
+                              gl::ShaderType type,
                               int index,
                               gl::Texture *texture,
                               const gl::SamplerState &sampler);
     gl::Error setTexture(const gl::Context *context,
-                         gl::SamplerType type,
+                         gl::ShaderType type,
                          int index,
                          gl::Texture *texture);
 
     gl::Error updateState(const gl::Context *context, GLenum drawMode);
 
     void setScissorRectangle(const gl::Rectangle &scissor, bool enabled);
     void setViewport(const gl::Rectangle &viewport,
                      float zNear,
@@ -162,17 +162,17 @@ class Renderer9 : public RendererD3D
                     const ClearParameters &clearParams,
                     const gl::FramebufferAttachment *colorBuffer,
                     const gl::FramebufferAttachment *depthStencilBuffer);
 
     void markAllStateDirty();
 
     // lost device
     bool testDeviceLost() override;
-    bool testDeviceResettable();
+    bool testDeviceResettable() override;
 
     VendorID getVendorId() const;
     std::string getRendererDescription() const;
     DeviceIdentifier getAdapterIdentifier() const override;
 
     IDirect3DDevice9 *getDevice() { return mDevice; }
     void *getD3DDevice() override;
 
@@ -242,23 +242,23 @@ class Renderer9 : public RendererD3D
                                  GLenum format,
                                  GLsizei samples,
                                  RenderTargetD3D **outRT) override;
     gl::Error createRenderTargetCopy(RenderTargetD3D *source, RenderTargetD3D **outRT) override;
 
     // Shader operations
     gl::Error loadExecutable(const uint8_t *function,
                              size_t length,
-                             ShaderType type,
+                             gl::ShaderType type,
                              const std::vector<D3DVarying> &streamOutVaryings,
                              bool separatedOutputBuffers,
                              ShaderExecutableD3D **outExecutable) override;
     gl::Error compileToExecutable(gl::InfoLog &infoLog,
                                   const std::string &shaderHLSL,
-                                  ShaderType type,
+                                  gl::ShaderType type,
                                   const std::vector<D3DVarying> &streamOutVaryings,
                                   bool separatedOutputBuffers,
                                   const angle::CompilerWorkaroundsD3D &workarounds,
                                   ShaderExecutableD3D **outExectuable) override;
     gl::Error ensureHLSLCompilerInitialized() override;
 
     UniformStorageD3D *createUniformStorage(size_t storageSize) override;
 
@@ -306,26 +306,25 @@ class Renderer9 : public RendererD3D
                                                 GLsizei depth,
                                                 int levels) override;
 
     TextureStorage *createTextureStorage2DMultisample(GLenum internalformat,
                                                       GLsizei width,
                                                       GLsizei height,
                                                       int levels,
                                                       int samples,
-                                                      GLboolean fixedSampleLocations) override;
+                                                      bool fixedSampleLocations) override;
 
     // Buffer creation
     VertexBuffer *createVertexBuffer() override;
     IndexBuffer *createIndexBuffer() override;
 
     // Stream Creation
-    StreamProducerImpl *createStreamProducerD3DTextureNV12(
-        egl::Stream::ConsumerType consumerType,
-        const egl::AttributeMap &attribs) override;
+    StreamProducerImpl *createStreamProducerD3DTexture(egl::Stream::ConsumerType consumerType,
+                                                       const egl::AttributeMap &attribs) override;
 
     // Buffer-to-texture and Texture-to-buffer copies
     bool supportsFastCopyBufferToTexture(GLenum internalFormat) const override;
     gl::Error fastCopyBufferToTexture(const gl::Context *context,
                                       const gl::PixelUnpackState &unpack,
                                       unsigned int offset,
                                       RenderTargetD3D *destRenderTarget,
                                       GLenum destinationFormat,
@@ -348,17 +347,17 @@ class Renderer9 : public RendererD3D
                                                            const gl::VertexBinding &binding,
                                                            GLsizei count,
                                                            GLsizei instances) const override;
 
     gl::Error copyToRenderTarget(IDirect3DSurface9 *dest,
                                  IDirect3DSurface9 *source,
                                  bool fromManaged);
 
-    RendererClass getRendererClass() const override { return RENDERER_D3D9; }
+    RendererClass getRendererClass() const override;
 
     D3DDEVTYPE getD3D9DeviceType() const { return mDeviceType; }
 
     egl::Error getEGLDevice(DeviceImpl **device) override;
 
     StateManager9 *getStateManager() { return &mStateManager; }
 
     gl::Error genericDrawArrays(const gl::Context *context,
@@ -381,17 +380,17 @@ class Renderer9 : public RendererD3D
 
     gl::Version getMaxSupportedESVersion() const override;
 
     gl::Error clearRenderTarget(RenderTargetD3D *renderTarget,
                                 const gl::ColorF &clearColorValue,
                                 const float clearDepthValue,
                                 const unsigned int clearStencilValue) override;
 
-    bool canSelectViewInVertexShader() const override { return false; }
+    bool canSelectViewInVertexShader() const override;
 
   private:
     gl::Error drawArraysImpl(const gl::Context *context,
                              GLenum mode,
                              GLint startVertex,
                              GLsizei count,
                              GLsizei instances);
     gl::Error drawElementsImpl(const gl::Context *context,
@@ -399,20 +398,17 @@ class Renderer9 : public RendererD3D
                                GLsizei count,
                                GLenum type,
                                const void *indices,
                                GLsizei instances);
 
     gl::Error applyShaders(const gl::Context *context, GLenum drawMode);
 
     gl::Error applyTextures(const gl::Context *context);
-    gl::Error applyTextures(const gl::Context *context,
-                            gl::SamplerType shaderType,
-                            const FramebufferTextureArray &framebufferTextures,
-                            size_t framebufferTextureCount);
+    gl::Error applyTextures(const gl::Context *context, gl::ShaderType shaderType);
 
     void generateCaps(gl::Caps *outCaps,
                       gl::TextureCapsMap *outTextureCaps,
                       gl::Extensions *outExtensions,
                       gl::Limitations *outLimitations) const override;
 
     angle::WorkaroundsD3D generateWorkarounds() const override;
 
--- a/gfx/angle/src/libANGLE/renderer/d3d/d3d9/ShaderExecutable9.h
+++ b/gfx/angle/src/libANGLE/renderer/d3d/d3d9/ShaderExecutable9.h
@@ -15,17 +15,17 @@
 namespace rx
 {
 
 class ShaderExecutable9 : public ShaderExecutableD3D
 {
   public:
     ShaderExecutable9(const void *function, size_t length, IDirect3DPixelShader9 *executable);
     ShaderExecutable9(const void *function, size_t length, IDirect3DVertexShader9 *executable);
-    virtual ~ShaderExecutable9();
+    ~ShaderExecutable9() override;
 
     IDirect3DPixelShader9 *getPixelShader() const;
     IDirect3DVertexShader9 *getVertexShader() const;
 
   private:
     IDirect3DPixelShader9 *mPixelExecutable;
     IDirect3DVertexShader9 *mVertexExecutable;
 };
--- a/gfx/angle/src/libANGLE/renderer/d3d/d3d9/StateManager9.cpp
+++ b/gfx/angle/src/libANGLE/renderer/d3d/d3d9/StateManager9.cpp
@@ -885,17 +885,17 @@ void StateManager9::setSampleMask(unsign
     IDirect3DDevice9 *device = mRenderer9->getDevice();
     // Set the multisample mask
     device->SetRenderState(D3DRS_MULTISAMPLEANTIALIAS, TRUE);
     device->SetRenderState(D3DRS_MULTISAMPLEMASK, static_cast<DWORD>(sampleMask));
 
     mCurSampleMask = sampleMask;
 }
 
-void StateManager9::setCullMode(bool cullFace, GLenum cullMode, GLenum frontFace)
+void StateManager9::setCullMode(bool cullFace, gl::CullFaceMode cullMode, GLenum frontFace)
 {
     if (cullFace)
     {
         mRenderer9->getDevice()->SetRenderState(D3DRS_CULLMODE,
                                                 gl_d3d9::ConvertCullMode(cullMode, frontFace));
     }
     else
     {
--- a/gfx/angle/src/libANGLE/renderer/d3d/d3d9/StateManager9.h
+++ b/gfx/angle/src/libANGLE/renderer/d3d/d3d9/StateManager9.h
@@ -81,17 +81,17 @@ class StateManager9 final : angle::NonCo
                       bool blue,
                       bool green,
                       bool alpha);
     void setSampleAlphaToCoverage(bool enabled);
     void setDither(bool dither);
     void setSampleMask(unsigned int sampleMask);
 
     // Current raster state functions
-    void setCullMode(bool cullFace, GLenum cullMode, GLenum frontFace);
+    void setCullMode(bool cullFace, gl::CullFaceMode cullMode, GLenum frontFace);
     void setDepthBias(bool polygonOffsetFill,
                       GLfloat polygonOffsetFactor,
                       GLfloat polygonOffsetUnits);
 
     // Depth stencil state functions
     void setStencilOpsFront(GLenum stencilFail,
                             GLenum stencilPassDepthFail,
                             GLenum stencilPassDepthPass,
--- a/gfx/angle/src/libANGLE/renderer/d3d/d3d9/SwapChain9.cpp
+++ b/gfx/angle/src/libANGLE/renderer/d3d/d3d9/SwapChain9.cpp
@@ -450,9 +450,18 @@ void SwapChain9::recreate()
     SafeRelease(mSwapChain);
     mSwapChain = newSwapChain;
 
     SafeRelease(mBackBuffer);
     result = mSwapChain->GetBackBuffer(0, D3DBACKBUFFER_TYPE_MONO, &mBackBuffer);
     ASSERT(SUCCEEDED(result));
 }
 
+RenderTargetD3D *SwapChain9::getColorRenderTarget()
+{
+    return &mColorRenderTarget;
 }
+
+RenderTargetD3D *SwapChain9::getDepthStencilRenderTarget()
+{
+    return &mDepthStencilRenderTarget;
+}
+}
--- a/gfx/angle/src/libANGLE/renderer/d3d/d3d9/SwapChain9.h
+++ b/gfx/angle/src/libANGLE/renderer/d3d/d3d9/SwapChain9.h
@@ -23,32 +23,33 @@ class SwapChain9 : public SwapChainD3D
   public:
     SwapChain9(Renderer9 *renderer,
                NativeWindow9 *nativeWindow,
                HANDLE shareHandle,
                IUnknown *d3dTexture,
                GLenum backBufferFormat,
                GLenum depthBufferFormat,
                EGLint orientation);
-    virtual ~SwapChain9();
+    ~SwapChain9() override;
 
-    EGLint resize(const gl::Context *context, EGLint backbufferWidth, EGLint backbufferHeight);
-    virtual EGLint reset(const gl::Context *context,
-                         EGLint backbufferWidth,
-                         EGLint backbufferHeight,
-                         EGLint swapInterval);
-    virtual EGLint swapRect(const gl::Context *context,
-                            EGLint x,
-                            EGLint y,
-                            EGLint width,
-                            EGLint height);
-    virtual void recreate();
+    EGLint resize(const gl::Context *context, EGLint backbufferWidth, EGLint backbufferHeight)
+        override;
+    EGLint reset(const gl::Context *context,
+                 EGLint backbufferWidth,
+                 EGLint backbufferHeight,
+                 EGLint swapInterval) override;
+    EGLint swapRect(const gl::Context *context,
+                    EGLint x,
+                    EGLint y,
+                    EGLint width,
+                    EGLint height) override;
+    void recreate() override;
 
-    RenderTargetD3D *getColorRenderTarget() override { return &mColorRenderTarget; }
-    RenderTargetD3D *getDepthStencilRenderTarget() override { return &mDepthStencilRenderTarget; }
+    RenderTargetD3D *getColorRenderTarget() override;
+    RenderTargetD3D *getDepthStencilRenderTarget() override;
 
     virtual IDirect3DSurface9 *getRenderTarget();
     virtual IDirect3DSurface9 *getDepthStencil();
     virtual IDirect3DTexture9 *getOffscreenTexture();
 
     EGLint getWidth() const { return mWidth; }
     EGLint getHeight() const { return mHeight; }
 
--- a/gfx/angle/src/libANGLE/renderer/d3d/d3d9/TextureStorage9.cpp
+++ b/gfx/angle/src/libANGLE/renderer/d3d/d3d9/TextureStorage9.cpp
@@ -139,17 +139,17 @@ TextureStorage9_2D::TextureStorage9_2D(R
     mMipLevels = mTopLevel + levels;
 
     mRenderTargets.resize(levels, nullptr);
 }
 
 TextureStorage9_2D::~TextureStorage9_2D()
 {
     SafeRelease(mTexture);
-    for (auto &renderTarget : mRenderTargets)
+    for (RenderTargetD3D *renderTarget : mRenderTargets)
     {
         SafeDelete(renderTarget);
     }
 }
 
 // Increments refcount on surface.
 // caller must Release() the returned surface
 gl::Error TextureStorage9_2D::getSurfaceLevel(const gl::Context *context,
--- a/gfx/angle/src/libANGLE/renderer/d3d/d3d9/TextureStorage9.h
+++ b/gfx/angle/src/libANGLE/renderer/d3d/d3d9/TextureStorage9.h
@@ -20,39 +20,36 @@ class EGLImageD3D;
 class Renderer9;
 class SwapChain9;
 class RenderTargetD3D;
 class RenderTarget9;
 
 class TextureStorage9 : public TextureStorage
 {
   public:
-    virtual ~TextureStorage9();
+    ~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,
                                       int level,
                                       bool dirty,
                                       IDirect3DSurface9 **outSurface) = 0;
     virtual gl::Error getBaseTexture(const gl::Context *context,
                                      IDirect3DBaseTexture9 **outTexture) = 0;
-    virtual gl::Error getRenderTarget(const gl::Context *context,
-                                      const gl::ImageIndex &index,
-                                      RenderTargetD3D **outRT) = 0;
 
-    virtual int getTopLevel() const;
-    virtual bool isRenderTarget() const;
-    virtual bool isManaged() const;
+    int getTopLevel() const override;
+    bool isRenderTarget() const override;
+    bool isManaged() const override;
     bool supportsNativeMipmapFunction() const override;
-    virtual int getLevelCount() const;
+    int getLevelCount() const override;
 
     gl::Error setData(const gl::Context *context,
                       const gl::ImageIndex &index,
                       ImageD3D *image,
                       const gl::Box *destBox,
                       GLenum type,
                       const gl::PixelUnpackState &unpack,
                       const uint8_t *pixelData) override;
@@ -125,17 +122,17 @@ class TextureStorage9_EGLImage final : p
   private:
     EGLImageD3D *mImage;
 };
 
 class TextureStorage9_Cube : public TextureStorage9
 {
   public:
     TextureStorage9_Cube(Renderer9 *renderer, GLenum internalformat, bool renderTarget, int size, int levels, bool hintLevelZeroOnly);
-    virtual ~TextureStorage9_Cube();
+    ~TextureStorage9_Cube() override;
 
     gl::Error getSurfaceLevel(const gl::Context *context,
                               GLenum target,
                               int level,
                               bool dirty,
                               IDirect3DSurface9 **outSurface) override;
     gl::Error getRenderTarget(const gl::Context *context,
                               const gl::ImageIndex &index,
@@ -150,9 +147,8 @@ class TextureStorage9_Cube : public Text
   private:
     IDirect3DCubeTexture9 *mTexture;
     RenderTarget9 *mRenderTarget[gl::CUBE_FACE_COUNT];
 };
 
 }
 
 #endif // LIBANGLE_RENDERER_D3D_D3D9_TEXTURESTORAGE9_H_
-
--- a/gfx/angle/src/libANGLE/renderer/d3d/d3d9/VertexArray9.h
+++ b/gfx/angle/src/libANGLE/renderer/d3d/d3d9/VertexArray9.h
@@ -18,26 +18,29 @@ 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
-    {
-        ASSERT(dirtyBits.any());
-        Renderer9 *renderer = GetImplAs<Context9>(context)->getRenderer();
-        mCurrentStateSerial = renderer->generateSerial();
-    }
+    void syncState(const gl::Context *context,
+                   const gl::VertexArray::DirtyBits &dirtyBits) override;
 
     ~VertexArray9() override {}
 
     Serial getCurrentStateSerial() const { return mCurrentStateSerial; }
 
   private:
     Serial mCurrentStateSerial;
 };
 
+inline void VertexArray9::syncState(const gl::Context *context,
+                                    const gl::VertexArray::DirtyBits &dirtyBits)
+{
+    ASSERT(dirtyBits.any());
+    Renderer9 *renderer = GetImplAs<Context9>(context)->getRenderer();
+    mCurrentStateSerial = renderer->generateSerial();
+}
 }
 
 #endif // LIBANGLE_RENDERER_D3D_D3D9_VERTEXARRAY9_H_
--- a/gfx/angle/src/libANGLE/renderer/d3d/d3d9/formatutils9.cpp
+++ b/gfx/angle/src/libANGLE/renderer/d3d/d3d9/formatutils9.cpp
@@ -25,42 +25,42 @@ namespace d3d9
 {
 
 constexpr D3DFORMAT D3DFMT_INTZ = ((D3DFORMAT)(MAKEFOURCC('I', 'N', 'T', 'Z')));
 constexpr D3DFORMAT D3DFMT_NULL = ((D3DFORMAT)(MAKEFOURCC('N', 'U', 'L', 'L')));
 
 // A map to determine the pixel size and mip generation function of a given D3D format
 typedef std::map<D3DFORMAT, D3DFormat> D3D9FormatInfoMap;
 
-constexpr D3DFormat::D3DFormat()
+D3DFormat::D3DFormat()
     : pixelBytes(0),
       blockWidth(0),
       blockHeight(0),
       redBits(0),
       greenBits(0),
       blueBits(0),
       alphaBits(0),
       luminanceBits(0),
       depthBits(0),
       stencilBits(0),
       formatID(angle::Format::ID::NONE)
 {
 }
 
-constexpr D3DFormat::D3DFormat(GLuint bits,
-                               GLuint blockWidth,
-                               GLuint blockHeight,
-                               GLuint redBits,
-                               GLuint greenBits,
-                               GLuint blueBits,
-                               GLuint alphaBits,
-                               GLuint lumBits,
-                               GLuint depthBits,
-                               GLuint stencilBits,
-                               Format::ID formatID)
+D3DFormat::D3DFormat(GLuint bits,
+                     GLuint blockWidth,
+                     GLuint blockHeight,
+                     GLuint redBits,
+                     GLuint greenBits,
+                     GLuint blueBits,
+                     GLuint alphaBits,
+                     GLuint lumBits,
+                     GLuint depthBits,
+                     GLuint stencilBits,
+                     Format::ID formatID)
     : pixelBytes(bits / 8),
       blockWidth(blockWidth),
       blockHeight(blockHeight),
       redBits(redBits),
       greenBits(greenBits),
       blueBits(blueBits),
       alphaBits(alphaBits),
       luminanceBits(lumBits),
@@ -69,161 +69,153 @@ constexpr D3DFormat::D3DFormat(GLuint bi
       formatID(formatID)
 {
 }
 
 const D3DFormat &GetD3DFormatInfo(D3DFORMAT format)
 {
     if (format == D3DFMT_NULL)
     {
-        static constexpr D3DFormat info(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, Format::ID::NONE);
+        static const D3DFormat info(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, Format::ID::NONE);
         return info;
     }
 
     if (format == D3DFMT_INTZ)
     {
-        static constexpr D3DFormat info(32, 1, 1, 0, 0, 0, 0, 0, 24, 8,
-                                        Format::ID::D24_UNORM_S8_UINT);
+        static const D3DFormat info(32, 1, 1, 0, 0, 0, 0, 0, 24, 8, Format::ID::D24_UNORM_S8_UINT);
         return info;
     }
 
     switch (format)
     {
         case D3DFMT_UNKNOWN:
         {
-            static constexpr D3DFormat info(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, Format::ID::NONE);
+            static const D3DFormat info(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, Format::ID::NONE);
             return info;
         }
 
         case D3DFMT_L8:
         {
-            static constexpr D3DFormat info(8, 1, 1, 0, 0, 0, 0, 8, 0, 0, Format::ID::L8_UNORM);
+            static const D3DFormat info(8, 1, 1, 0, 0, 0, 0, 8, 0, 0, Format::ID::L8_UNORM);
             return info;
         }
         case D3DFMT_A8:
         {
-            static constexpr D3DFormat info(8, 1, 1, 0, 0, 0, 8, 0, 0, 0, Format::ID::A8_UNORM);
+            static const D3DFormat info(8, 1, 1, 0, 0, 0, 8, 0, 0, 0, Format::ID::A8_UNORM);
             return info;
         }
         case D3DFMT_A8L8:
         {
-            static constexpr D3DFormat info(16, 1, 1, 0, 0, 0, 8, 8, 0, 0, Format::ID::L8A8_UNORM);
+            static const D3DFormat info(16, 1, 1, 0, 0, 0, 8, 8, 0, 0, Format::ID::L8A8_UNORM);
             return info;
         }
 
         case D3DFMT_A4R4G4B4:
         {
-            static constexpr D3DFormat info(16, 1, 1, 4, 4, 4, 4, 0, 0, 0,
-                                            Format::ID::B4G4R4A4_UNORM);
+            static const D3DFormat info(16, 1, 1, 4, 4, 4, 4, 0, 0, 0, Format::ID::B4G4R4A4_UNORM);
             return info;
         }
         case D3DFMT_A1R5G5B5:
         {
-            static constexpr D3DFormat info(16, 1, 1, 5, 5, 5, 1, 0, 0, 0,
-                                            Format::ID::B5G5R5A1_UNORM);
+            static const D3DFormat info(16, 1, 1, 5, 5, 5, 1, 0, 0, 0, Format::ID::B5G5R5A1_UNORM);
             return info;
         }
         case D3DFMT_R5G6B5:
         {
-            static constexpr D3DFormat info(16, 1, 1, 5, 6, 5, 0, 0, 0, 0,
-                                            Format::ID::R5G6B5_UNORM);
+            static const D3DFormat info(16, 1, 1, 5, 6, 5, 0, 0, 0, 0, Format::ID::R5G6B5_UNORM);
             return info;
         }
         case D3DFMT_X8R8G8B8:
         {
-            static constexpr D3DFormat info(32, 1, 1, 8, 8, 8, 0, 0, 0, 0,
-                                            Format::ID::B8G8R8X8_UNORM);
+            static const D3DFormat info(32, 1, 1, 8, 8, 8, 0, 0, 0, 0, Format::ID::B8G8R8X8_UNORM);
             return info;
         }
         case D3DFMT_A8R8G8B8:
         {
-            static constexpr D3DFormat info(32, 1, 1, 8, 8, 8, 8, 0, 0, 0,
-                                            Format::ID::B8G8R8A8_UNORM);
+            static const D3DFormat info(32, 1, 1, 8, 8, 8, 8, 0, 0, 0, Format::ID::B8G8R8A8_UNORM);
             return info;
         }
 
         case D3DFMT_R16F:
         {
-            static constexpr D3DFormat info(16, 1, 1, 16, 0, 0, 0, 0, 0, 0, Format::ID::R16_FLOAT);
+            static const D3DFormat info(16, 1, 1, 16, 0, 0, 0, 0, 0, 0, Format::ID::R16_FLOAT);
             return info;
         }
         case D3DFMT_G16R16F:
         {
-            static constexpr D3DFormat info(32, 1, 1, 16, 16, 0, 0, 0, 0, 0,
-                                            Format::ID::R16G16_FLOAT);
+            static const D3DFormat info(32, 1, 1, 16, 16, 0, 0, 0, 0, 0, Format::ID::R16G16_FLOAT);
             return info;
         }
         case D3DFMT_A16B16G16R16F:
         {
-            static constexpr D3DFormat info(64, 1, 1, 16, 16, 16, 16, 0, 0, 0,
-                                            Format::ID::R16G16B16A16_FLOAT);
+            static const D3DFormat info(64, 1, 1, 16, 16, 16, 16, 0, 0, 0,
+                                        Format::ID::R16G16B16A16_FLOAT);
             return info;
         }
         case D3DFMT_R32F:
         {
-            static constexpr D3DFormat info(32, 1, 1, 32, 0, 0, 0, 0, 0, 0, Format::ID::R32_FLOAT);
+            static const D3DFormat info(32, 1, 1, 32, 0, 0, 0, 0, 0, 0, Format::ID::R32_FLOAT);
             return info;
         }
         case D3DFMT_G32R32F:
         {
-            static constexpr D3DFormat info(64, 1, 1, 32, 32, 0, 0, 0, 0, 0,
-                                            Format::ID::R32G32_FLOAT);
+            static const D3DFormat info(64, 1, 1, 32, 32, 0, 0, 0, 0, 0, Format::ID::R32G32_FLOAT);
             return info;
         }
         case D3DFMT_A32B32G32R32F:
         {
-            static constexpr D3DFormat info(128, 1, 1, 32, 32, 32, 32, 0, 0, 0,
-                                            Format::ID::R32G32B32A32_FLOAT);
+            static const D3DFormat info(128, 1, 1, 32, 32, 32, 32, 0, 0, 0,
+                                        Format::ID::R32G32B32A32_FLOAT);
             return info;
         }
 
         case D3DFMT_D16:
         {
-            static constexpr D3DFormat info(16, 1, 1, 0, 0, 0, 0, 0, 16, 0, Format::ID::D16_UNORM);
+            static const D3DFormat info(16, 1, 1, 0, 0, 0, 0, 0, 16, 0, Format::ID::D16_UNORM);
             return info;
         }
         case D3DFMT_D24S8:
         {
-            static constexpr D3DFormat info(32, 1, 1, 0, 0, 0, 0, 0, 24, 8,
-                                            Format::ID::D24_UNORM_S8_UINT);
+            static const D3DFormat info(32, 1, 1, 0, 0, 0, 0, 0, 24, 8,
+                                        Format::ID::D24_UNORM_S8_UINT);
             return info;
         }
         case D3DFMT_D24X8:
         {
-            static constexpr D3DFormat info(32, 1, 1, 0, 0, 0, 0, 0, 24, 0, Format::ID::D16_UNORM);
+            static const D3DFormat info(32, 1, 1, 0, 0, 0, 0, 0, 24, 0, Format::ID::D16_UNORM);
             return info;
         }
         case D3DFMT_D32:
         {
-            static constexpr D3DFormat info(32, 1, 1, 0, 0, 0, 0, 0, 32, 0, Format::ID::D32_UNORM);
+            static const D3DFormat info(32, 1, 1, 0, 0, 0, 0, 0, 32, 0, Format::ID::D32_UNORM);
             return info;
         }
 
         case D3DFMT_DXT1:
         {
-            static constexpr D3DFormat info(64, 4, 4, 0, 0, 0, 0, 0, 0, 0,
-                                            Format::ID::BC1_RGBA_UNORM_BLOCK);
+            static const D3DFormat info(64, 4, 4, 0, 0, 0, 0, 0, 0, 0,
+                                        Format::ID::BC1_RGBA_UNORM_BLOCK);
             return info;
         }
         case D3DFMT_DXT3:
         {
-            static constexpr D3DFormat info(128, 4, 4, 0, 0, 0, 0, 0, 0, 0,
-                                            Format::ID::BC2_RGBA_UNORM_BLOCK);
+            static const D3DFormat info(128, 4, 4, 0, 0, 0, 0, 0, 0, 0,
+                                        Format::ID::BC2_RGBA_UNORM_BLOCK);
             return info;
         }
         case D3DFMT_DXT5:
         {
-            static constexpr D3DFormat info(128, 4, 4, 0, 0, 0, 0, 0, 0, 0,
-                                            Format::ID::BC3_RGBA_UNORM_BLOCK);
+            static const D3DFormat info(128, 4, 4, 0, 0, 0, 0, 0, 0, 0,
+                                        Format::ID::BC3_RGBA_UNORM_BLOCK);
             return info;
         }
 
         default:
         {
-            static constexpr D3DFormat defaultInfo;
+            static const D3DFormat defaultInfo;
             return defaultInfo;
         }
     }
 }
 
 typedef std::pair<GLint, InitializeTextureDataFunction> InternalFormatInitialzerPair;
 typedef std::map<GLint, InitializeTextureDataFunction> InternalFormatInitialzerMap;
 
--- a/gfx/angle/src/libANGLE/renderer/d3d/d3d9/formatutils9.h
+++ b/gfx/angle/src/libANGLE/renderer/d3d/d3d9/formatutils9.h
@@ -24,28 +24,28 @@ namespace rx
 
 class Renderer9;
 
 namespace d3d9
 {
 
 struct D3DFormat
 {
-    constexpr D3DFormat();
-    constexpr D3DFormat(GLuint pixelBytes,
-                        GLuint blockWidth,
-                        GLuint blockHeight,
-                        GLuint redBits,
-                        GLuint greenBits,
-                        GLuint blueBits,
-                        GLuint alphaBits,
-                        GLuint luminanceBits,
-                        GLuint depthBits,
-                        GLuint stencilBits,
-                        angle::Format::ID formatID);
+    D3DFormat();
+    D3DFormat(GLuint pixelBytes,
+              GLuint blockWidth,
+              GLuint blockHeight,
+              GLuint redBits,
+              GLuint greenBits,
+              GLuint blueBits,
+              GLuint alphaBits,
+              GLuint luminanceBits,
+              GLuint depthBits,
+              GLuint stencilBits,
+              angle::Format::ID formatID);
 
     const angle::Format &info() const { return angle::Format::Get(formatID); }
 
     GLuint pixelBytes;
     GLuint blockWidth;
     GLuint blockHeight;
 
     GLuint redBits;
--- a/gfx/angle/src/libANGLE/renderer/d3d/d3d9/renderer9_utils.cpp
+++ b/gfx/angle/src/libANGLE/renderer/d3d/d3d9/renderer9_utils.cpp
@@ -130,31 +130,32 @@ D3DTEXTUREADDRESS ConvertTextureWrap(GLe
       case GL_CLAMP_TO_EDGE:     d3dWrap = D3DTADDRESS_CLAMP;  break;
       case GL_MIRRORED_REPEAT:   d3dWrap = D3DTADDRESS_MIRROR; break;
       default: UNREACHABLE();
     }
 
     return d3dWrap;
 }
 
-D3DCULL ConvertCullMode(GLenum cullFace, GLenum frontFace)
+D3DCULL ConvertCullMode(gl::CullFaceMode cullFace, GLenum frontFace)
 {
     D3DCULL cull = D3DCULL_CCW;
     switch (cullFace)
     {
-      case GL_FRONT:
-        cull = (frontFace == GL_CCW ? D3DCULL_CW : D3DCULL_CCW);
-        break;
-      case GL_BACK:
-        cull = (frontFace == GL_CCW ? D3DCULL_CCW : D3DCULL_CW);
-        break;
-      case GL_FRONT_AND_BACK:
-        cull = D3DCULL_NONE; // culling will be handled during draw
-        break;
-      default: UNREACHABLE();
+        case gl::CullFaceMode::Front:
+            cull = (frontFace == GL_CCW ? D3DCULL_CW : D3DCULL_CCW);
+            break;
+        case gl::CullFaceMode::Back:
+            cull = (frontFace == GL_CCW ? D3DCULL_CCW : D3DCULL_CW);
+            break;
+        case gl::CullFaceMode::FrontAndBack:
+            cull = D3DCULL_NONE;  // culling will be handled during draw
+            break;
+        default:
+            UNREACHABLE();
     }
 
     return cull;
 }
 
 D3DCUBEMAP_FACES ConvertCubeFace(GLenum cubeFace)
 {
     D3DCUBEMAP_FACES face = D3DCUBEMAP_FACE_POSITIVE_X;
@@ -571,17 +572,16 @@ void GenerateCaps(IDirect3D9 *d3d9,
     extensions->occlusionQueryBoolean = SUCCEEDED(device->CreateQuery(D3DQUERYTYPE_OCCLUSION, &occlusionQuery)) && occlusionQuery;
     SafeRelease(occlusionQuery);
 
     // Check event query support by trying to create one
     IDirect3DQuery9 *eventQuery = nullptr;
     extensions->fence = SUCCEEDED(device->CreateQuery(D3DQUERYTYPE_EVENT, &eventQuery)) && eventQuery;
     SafeRelease(eventQuery);
 
-    extensions->timerQuery = false; // Unimplemented
     extensions->disjointTimerQuery     = false;
     extensions->robustness = true;
     // It seems that only DirectX 10 and higher enforce the well-defined behavior of always
     // returning zero values when out-of-bounds reads. See
     // https://www.khronos.org/registry/OpenGL/extensions/ARB/ARB_robustness.txt
     extensions->robustBufferAccessBehavior = false;
     extensions->blendMinMax = true;
     extensions->framebufferBlit = true;
--- a/gfx/angle/src/libANGLE/renderer/d3d/d3d9/renderer9_utils.h
+++ b/gfx/angle/src/libANGLE/renderer/d3d/d3d9/renderer9_utils.h
@@ -28,17 +28,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(GLenum cullFace, GLenum frontFace);
+D3DCULL ConvertCullMode(gl::CullFaceMode cullFace, GLenum frontFace);
 D3DCUBEMAP_FACES ConvertCubeFace(GLenum 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/src/libANGLE/renderer/d3d/d3d9/shaders/Blit.ps
+++ b/gfx/angle/src/libANGLE/renderer/d3d/d3d9/shaders/Blit.ps
@@ -21,47 +21,47 @@ float4 passthroughps(float4 texcoord : T
 // Returns data in the form of llla
 float4 luminanceps(float4 texcoord : TEXCOORD0) : COLOR
 {
     return (tex2D(tex, texcoord.xy).xw * mult.xw + add.xw).xxxy;
 };
 
 float4 luminancepremultps(float4 texcoord : TEXCOORD0) : COLOR
 {
-    float4 luma = (tex2D(tex, texcoord.xy).xw * mult.xw + add.xw).xxxy;
+    float4 luma = tex2D(tex, texcoord.xy).xxxw;
     luma.rgb *= luma.a;
-    return luma;
+    return luma * mult + add;
 };
 
 float4 luminanceunmultps(float4 texcoord : TEXCOORD0) : COLOR
 {
-    float4 luma = (tex2D(tex, texcoord.xy).xw * mult.xw + add.xw).xxxy;
+    float4 luma = tex2D(tex, texcoord.xy).xxxw;
     if (luma.a > 0.0f)
     {
         luma.rgb /= luma.a;
     }
-    return luma;
+    return luma * mult + add;
 };
 
 // RGB/A Component Mask Pixel Shader
 // Performs a mad operation using the texture's RGBA data with mult.xyzw and add.xyzw.
 // Returns data in the form of rgba
 float4 componentmaskps(float4 texcoord : TEXCOORD0) : COLOR
 {
     return tex2D(tex, texcoord.xy) * mult + add;
 };
 
 float4 componentmaskpremultps(float4 texcoord : TEXCOORD0) : COLOR
 {
-    float4 color = tex2D(tex, texcoord.xy) * mult + add;
+    float4 color = tex2D(tex, texcoord.xy);
     color.rgb *= color.a;
-    return color;
+    return color * mult + add;
 };
 
 float4 componentmaskunmultps(float4 texcoord : TEXCOORD0) : COLOR
 {
-    float4 color =  tex2D(tex, texcoord.xy) * mult + add;
+    float4 color =  tex2D(tex, texcoord.xy);
     if (color.a > 0.0f)
     {
         color.rgb /= color.a;
     }
-    return color;
+    return color * mult + add;
 };
--- a/gfx/angle/src/libANGLE/renderer/d3d/d3d9/shaders/compiled/componentmaskpremultps.h
+++ b/gfx/angle/src/libANGLE/renderer/d3d/d3d9/shaders/compiled/componentmaskpremultps.h
@@ -1,50 +1,50 @@
-#if 0
-//
-// Generated by Microsoft (R) HLSL Shader Compiler 6.3.9600.16384
-//
-// Parameters:
-//
-//   float4 add;
-//   float4 mult;
-//   sampler2D tex;
-//
-//
-// Registers:
-//
-//   Name         Reg   Size
-//   ------------ ----- ----
-//   mult         c0       1
-//   add          c1       1
-//   tex          s0       1
-//
-
-    ps_2_0
-    dcl t0.xy
-    dcl_2d s0
-    texld r0, t0, s0
-    mov r1, c0
-    mad r0, r0, r1, c1
-    mul r0.xyz, r0.w, r0
-    mov oC0, r0
-
-// approximately 5 instruction slots used (1 texture, 4 arithmetic)
-#endif
-
-const BYTE g_ps20_componentmaskpremultps[] = {
-    0,   2,   255, 255, 254, 255, 50,  0,   67,  84,  65,  66,  28,  0,   0,   0,   143, 0,   0,
-    0,   0,   2,   255, 255, 3,   0,   0,   0,   28,  0,   0,   0,   0,   1,   0,   0,   136, 0,
-    0,   0,   88,  0,   0,   0,   2,   0,   1,   0,   1,   0,   0,   0,   92,  0,   0,   0,   0,
-    0,   0,   0,   108, 0,   0,   0,   2,   0,   0,   0,   1,   0,   0,   0,   92,  0,   0,   0,
-    0,   0,   0,   0,   113, 0,   0,   0,   3,   0,   0,   0,   1,   0,   0,   0,   120, 0,   0,
-    0,   0,   0,   0,   0,   97,  100, 100, 0,   1,   0,   3,   0,   1,   0,   4,   0,   1,   0,
-    0,   0,   0,   0,   0,   0,   109, 117, 108, 116, 0,   116, 101, 120, 0,   171, 171, 171, 4,
-    0,   12,  0,   1,   0,   1,   0,   1,   0,   0,   0,   0,   0,   0,   0,   112, 115, 95,  50,
-    95,  48,  0,   77,  105, 99,  114, 111, 115, 111, 102, 116, 32,  40,  82,  41,  32,  72,  76,
-    83,  76,  32,  83,  104, 97,  100, 101, 114, 32,  67,  111, 109, 112, 105, 108, 101, 114, 32,
-    54,  46,  51,  46,  57,  54,  48,  48,  46,  49,  54,  51,  56,  52,  0,   171, 171, 171, 31,
-    0,   0,   2,   0,   0,   0,   128, 0,   0,   3,   176, 31,  0,   0,   2,   0,   0,   0,   144,
-    0,   8,   15,  160, 66,  0,   0,   3,   0,   0,   15,  128, 0,   0,   228, 176, 0,   8,   228,
-    160, 1,   0,   0,   2,   1,   0,   15,  128, 0,   0,   228, 160, 4,   0,   0,   4,   0,   0,
-    15,  128, 0,   0,   228, 128, 1,   0,   228, 128, 1,   0,   228, 160, 5,   0,   0,   3,   0,
-    0,   7,   128, 0,   0,   255, 128, 0,   0,   228, 128, 1,   0,   0,   2,   0,   8,   15,  128,
-    0,   0,   228, 128, 255, 255, 0,   0};
+#if 0
+//
+// Generated by Microsoft (R) HLSL Shader Compiler 6.3.9600.16384
+//
+// Parameters:
+//
+//   float4 add;
+//   float4 mult;
+//   sampler2D tex;
+//
+//
+// Registers:
+//
+//   Name         Reg   Size
+//   ------------ ----- ----
+//   mult         c0       1
+//   add          c1       1
+//   tex          s0       1
+//
+
+    ps_2_0
+    dcl t0.xy
+    dcl_2d s0
+    texld r0, t0, s0
+    mul r0.xyz, r0.w, r0
+    mov r1, c0
+    mad r0, r0, r1, c1
+    mov oC0, r0
+
+// approximately 5 instruction slots used (1 texture, 4 arithmetic)
+#endif
+
+const BYTE g_ps20_componentmaskpremultps[] = {
+    0,   2,   255, 255, 254, 255, 50,  0,   67,  84,  65,  66,  28,  0,   0,   0,   143, 0,   0,
+    0,   0,   2,   255, 255, 3,   0,   0,   0,   28,  0,   0,   0,   0,   1,   0,   0,   136, 0,
+    0,   0,   88,  0,   0,   0,   2,   0,   1,   0,   1,   0,   0,   0,   92,  0,   0,   0,   0,
+    0,   0,   0,   108, 0,   0,   0,   2,   0,   0,   0,   1,   0,   0,   0,   92,  0,   0,   0,
+    0,   0,   0,   0,   113, 0,   0,   0,   3,   0,   0,   0,   1,   0,   0,   0,   120, 0,   0,
+    0,   0,   0,   0,   0,   97,  100, 100, 0,   1,   0,   3,   0,   1,   0,   4,   0,   1,   0,
+    0,   0,   0,   0,   0,   0,   109, 117, 108, 116, 0,   116, 101, 120, 0,   171, 171, 171, 4,
+    0,   12,  0,   1,   0,   1,   0,   1,   0,   0,   0,   0,   0,   0,   0,   112, 115, 95,  50,
+    95,  48,  0,   77,  105, 99,  114, 111, 115, 111, 102, 116, 32,  40,  82,  41,  32,  72,  76,
+    83,  76,  32,  83,  104, 97,  100, 101, 114, 32,  67,  111, 109, 112, 105, 108, 101, 114, 32,
+    54,  46,  51,  46,  57,  54,  48,  48,  46,  49,  54,  51,  56,  52,  0,   171, 171, 171, 31,
+    0,   0,   2,   0,   0,   0,   128, 0,   0,   3,   176, 31,  0,   0,   2,   0,   0,   0,   144,
+    0,   8,   15,  160, 66,  0,   0,   3,   0,   0,   15,  128, 0,   0,   228, 176, 0,   8,   228,
+    160, 5,   0,   0,   3,   0,   0,   7,   128, 0,   0,   255, 128, 0,   0,   228, 128, 1,   0,
+    0,   2,   1,   0,   15,  128, 0,   0,   228, 160, 4,   0,   0,   4,   0,   0,   15,  128, 0,
+    0,   228, 128, 1,   0,   228, 128, 1,   0,   228, 160, 1,   0,   0,   2,   0,   8,   15,  128,
+    0,   0,   228, 128, 255, 255, 0,   0};
--- a/gfx/angle/src/libANGLE/renderer/d3d/d3d9/shaders/compiled/componentmaskps.h
+++ b/gfx/angle/src/libANGLE/renderer/d3d/d3d9/shaders/compiled/componentmaskps.h
@@ -1,84 +1,84 @@
-#if 0
-//
-// Generated by Microsoft (R) HLSL Shader Compiler 6.3.9600.16384
-//
-// Parameters:
-//
-//   float4 add;
-//   float4 mult;
-//   sampler2D tex;
-//
-//
-// Registers:
-//
-//   Name         Reg   Size
-//   ------------ ----- ----
-//   mult         c0       1
-//   add          c1       1
-//   tex          s0       1
-//
-
-    ps_2_0
-    dcl t0.xy
-    dcl_2d s0
-    texld r0, t0, s0
-    mov r1, c0
-    mad r0, r0, r1, c1
-    mov oC0, r0
-
-// approximately 4 instruction slots used (1 texture, 3 arithmetic)
-#endif
-
-const BYTE g_ps20_componentmaskps[] =
-{
-      0,   2, 255, 255, 254, 255, 
-     50,   0,  67,  84,  65,  66, 
-     28,   0,   0,   0, 143,   0, 
-      0,   0,   0,   2, 255, 255, 
-      3,   0,   0,   0,  28,   0, 
-      0,   0,   0,   1,   0,   0, 
-    136,   0,   0,   0,  88,   0, 
-      0,   0,   2,   0,   1,   0, 
-      1,   0,   0,   0,  92,   0, 
-      0,   0,   0,   0,   0,   0, 
-    108,   0,   0,   0,   2,   0, 
-      0,   0,   1,   0,   0,   0, 
-     92,   0,   0,   0,   0,   0, 
-      0,   0, 113,   0,   0,   0, 
-      3,   0,   0,   0,   1,   0, 
-      0,   0, 120,   0,   0,   0, 
-      0,   0,   0,   0,  97, 100, 
-    100,   0,   1,   0,   3,   0, 
-      1,   0,   4,   0,   1,   0, 
-      0,   0,   0,   0,   0,   0, 
-    109, 117, 108, 116,   0, 116, 
-    101, 120,   0, 171, 171, 171, 
-      4,   0,  12,   0,   1,   0, 
-      1,   0,   1,   0,   0,   0, 
-      0,   0,   0,   0, 112, 115, 
-     95,  50,  95,  48,   0,  77, 
-    105,  99, 114, 111, 115, 111, 
-    102, 116,  32,  40,  82,  41, 
-     32,  72,  76,  83,  76,  32, 
-     83, 104,  97, 100, 101, 114, 
-     32,  67, 111, 109, 112, 105, 
-    108, 101, 114,  32,  54,  46, 
-     51,  46,  57,  54,  48,  48, 
-     46,  49,  54,  51,  56,  52, 
-      0, 171, 171, 171,  31,   0, 
-      0,   2,   0,   0,   0, 128, 
-      0,   0,   3, 176,  31,   0, 
-      0,   2,   0,   0,   0, 144, 
-      0,   8,  15, 160,  66,   0, 
-      0,   3,   0,   0,  15, 128, 
-      0,   0, 228, 176,   0,   8, 
-    228, 160,   1,   0,   0,   2, 
-      1,   0,  15, 128,   0,   0, 
-    228, 160,   4,   0,   0,   4, 
-      0,   0,  15, 128,   0,   0, 
-    228, 128,   1,   0, 228, 128, 
-      1,   0, 228, 160,   1,   0, 
-      0,   2,   0,   8,  15, 128, 
-      0,   0, 228, 128, 255, 255, 
-      0,   0
-};
+#if 0
+//
+// Generated by Microsoft (R) HLSL Shader Compiler 6.3.9600.16384
+//
+// Parameters:
+//
+//   float4 add;
+//   float4 mult;
+//   sampler2D tex;
+//
+//
+// Registers:
+//
+//   Name         Reg   Size
+//   ------------ ----- ----
+//   mult         c0       1
+//   add          c1       1
+//   tex          s0       1
+//
+
+    ps_2_0
+    dcl t0.xy
+    dcl_2d s0
+    texld r0, t0, s0
+    mov r1, c0
+    mad r0, r0, r1, c1
+    mov oC0, r0
+
+// approximately 4 instruction slots used (1 texture, 3 arithmetic)
+#endif
+
+const BYTE g_ps20_componentmaskps[] =
+{
+      0,   2, 255, 255, 254, 255, 
+     50,   0,  67,  84,  65,  66, 
+     28,   0,   0,   0, 143,   0, 
+      0,   0,   0,   2, 255, 255, 
+      3,   0,   0,   0,  28,   0, 
+      0,   0,   0,   1,   0,   0, 
+    136,   0,   0,   0,  88,   0, 
+      0,   0,   2,   0,   1,   0, 
+      1,   0,   0,   0,  92,   0, 
+      0,   0,   0,   0,   0,   0, 
+    108,   0,   0,   0,   2,   0, 
+      0,   0,   1,   0,   0,   0, 
+     92,   0,   0,   0,   0,   0, 
+      0,   0, 113,   0,   0,   0, 
+      3,   0,   0,   0,   1,   0, 
+      0,   0, 120,   0,   0,   0, 
+      0,   0,   0,   0,  97, 100, 
+    100,   0,   1,   0,   3,   0, 
+      1,   0,   4,   0,   1,   0, 
+      0,   0,   0,   0,   0,   0, 
+    109, 117, 108, 116,   0, 116, 
+    101, 120,   0, 171, 171, 171, 
+      4,   0,  12,   0,   1,   0, 
+      1,   0,   1,   0,   0,   0, 
+      0,   0,   0,   0, 112, 115, 
+     95,  50,  95,  48,   0,  77, 
+    105,  99, 114, 111, 115, 111, 
+    102, 116,  32,  40,  82,  41, 
+     32,  72,  76,  83,  76,  32, 
+     83, 104,  97, 100, 101, 114, 
+     32,  67, 111, 109, 112, 105, 
+    108, 101, 114,  32,  54,  46, 
+     51,  46,  57,  54,  48,  48, 
+     46,  49,  54,  51,  56,  52, 
+      0, 171, 171, 171,  31,   0, 
+      0,   2,   0,   0,   0, 128, 
+      0,   0,   3, 176,  31,   0, 
+      0,   2,   0,   0,   0, 144, 
+      0,   8,  15, 160,  66,   0, 
+      0,   3,   0,   0,  15, 128, 
+      0,   0, 228, 176,   0,   8, 
+    228, 160,   1,   0,   0,   2, 
+      1,   0,  15, 128,   0,   0, 
+    228, 160,   4,   0,   0,   4, 
+      0,   0,  15, 128,   0,   0, 
+    228, 128,   1,   0, 228, 128, 
+      1,   0, 228, 160,   1,   0, 
+      0,   2,   0,   8,  15, 128, 
+      0,   0, 228, 128, 255, 255, 
+      0,   0
+};
--- a/gfx/angle/src/libANGLE/renderer/d3d/d3d9/shaders/compiled/componentmaskunmultps.h
+++ b/gfx/angle/src/libANGLE/renderer/d3d/d3d9/shaders/compiled/componentmaskunmultps.h
@@ -1,54 +1,54 @@
-#if 0
-//
-// Generated by Microsoft (R) HLSL Shader Compiler 6.3.9600.16384
-//
-// Parameters:
-//
-//   float4 add;
-//   float4 mult;
-//   sampler2D tex;
-//
-//
-// Registers:
-//
-//   Name         Reg   Size
-//   ------------ ----- ----
-//   mult         c0       1
-//   add          c1       1
-//   tex          s0       1
-//
-
-    ps_2_0
-    dcl t0.xy
-    dcl_2d s0
-    texld r0, t0, s0
-    mov r1, c0
-    mad r0, r0, r1, c1
-    rcp r1.x, r0.w
-    mul r1.xyz, r0, r1.x
-    cmp r0.xyz, -r0.w, r0, r1
-    mov oC0, r0
-
-// approximately 7 instruction slots used (1 texture, 6 arithmetic)
-#endif
-
-const BYTE g_ps20_componentmaskunmultps[] = {
-    0,   2,   255, 255, 254, 255, 50,  0,   67,  84,  65,  66,  28,  0,   0,   0,   143, 0,   0,
-    0,   0,   2,   255, 255, 3,   0,   0,   0,   28,  0,   0,   0,   0,   1,   0,   0,   136, 0,
-    0,   0,   88,  0,   0,   0,   2,   0,   1,   0,   1,   0,   0,   0,   92,  0,   0,   0,   0,
-    0,   0,   0,   108, 0,   0,   0,   2,   0,   0,   0,   1,   0,   0,   0,   92,  0,   0,   0,
-    0,   0,   0,   0,   113, 0,   0,   0,   3,   0,   0,   0,   1,   0,   0,   0,   120, 0,   0,
-    0,   0,   0,   0,   0,   97,  100, 100, 0,   1,   0,   3,   0,   1,   0,   4,   0,   1,   0,
-    0,   0,   0,   0,   0,   0,   109, 117, 108, 116, 0,   116, 101, 120, 0,   171, 171, 171, 4,
-    0,   12,  0,   1,   0,   1,   0,   1,   0,   0,   0,   0,   0,   0,   0,   112, 115, 95,  50,
-    95,  48,  0,   77,  105, 99,  114, 111, 115, 111, 102, 116, 32,  40,  82,  41,  32,  72,  76,
-    83,  76,  32,  83,  104, 97,  100, 101, 114, 32,  67,  111, 109, 112, 105, 108, 101, 114, 32,
-    54,  46,  51,  46,  57,  54,  48,  48,  46,  49,  54,  51,  56,  52,  0,   171, 171, 171, 31,
-    0,   0,   2,   0,   0,   0,   128, 0,   0,   3,   176, 31,  0,   0,   2,   0,   0,   0,   144,
-    0,   8,   15,  160, 66,  0,   0,   3,   0,   0,   15,  128, 0,   0,   228, 176, 0,   8,   228,
-    160, 1,   0,   0,   2,   1,   0,   15,  128, 0,   0,   228, 160, 4,   0,   0,   4,   0,   0,
-    15,  128, 0,   0,   228, 128, 1,   0,   228, 128, 1,   0,   228, 160, 6,   0,   0,   2,   1,
-    0,   1,   128, 0,   0,   255, 128, 5,   0,   0,   3,   1,   0,   7,   128, 0,   0,   228, 128,
-    1,   0,   0,   128, 88,  0,   0,   4,   0,   0,   7,   128, 0,   0,   255, 129, 0,   0,   228,
-    128, 1,   0,   228, 128, 1,   0,   0,   2,   0,   8,   15,  128, 0,   0,   228, 128, 255, 255,
-    0,   0};
+#if 0
+//
+// Generated by Microsoft (R) HLSL Shader Compiler 6.3.9600.16384
+//
+// Parameters:
+//
+//   float4 add;
+//   float4 mult;
+//   sampler2D tex;
+//
+//
+// Registers:
+//
+//   Name         Reg   Size
+//   ------------ ----- ----
+//   mult         c0       1
+//   add          c1       1
+//   tex          s0       1
+//
+
+    ps_2_0
+    dcl t0.xy
+    dcl_2d s0
+    texld r0, t0, s0
+    rcp r1.w, r0.w
+    mul r1.xyz, r0, r1.w
+    cmp r0.xyz, -r0.w, r0, r1
+    mov r1, c0
+    mad r0, r0, r1, c1
+    mov oC0, r0
+
+// approximately 7 instruction slots used (1 texture, 6 arithmetic)
+#endif
+
+const BYTE g_ps20_componentmaskunmultps[] = {
+    0,   2,   255, 255, 254, 255, 50,  0,   67,  84,  65,  66,  28,  0,   0,   0,   143, 0,   0,
+    0,   0,   2,   255, 255, 3,   0,   0,   0,   28,  0,   0,   0,   0,   1,   0,   0,   136, 0,
+    0,   0,   88,  0,   0,   0,   2,   0,   1,   0,   1,   0,   0,   0,   92,  0,   0,   0,   0,
+    0,   0,   0,   108, 0,   0,   0,   2,   0,   0,   0,   1,   0,   0,   0,   92,  0,   0,   0,
+    0,   0,   0,   0,   113, 0,   0,   0,   3,   0,   0,   0,   1,   0,   0,   0,   120, 0,   0,
+    0,   0,   0,   0,   0,   97,  100, 100, 0,   1,   0,   3,   0,   1,   0,   4,   0,   1,   0,
+    0,   0,   0,   0,   0,   0,   109, 117, 108, 116, 0,   116, 101, 120, 0,   171, 171, 171, 4,
+    0,   12,  0,   1,   0,   1,   0,   1,   0,   0,   0,   0,   0,   0,   0,   112, 115, 95,  50,
+    95,  48,  0,   77,  105, 99,  114, 111, 115, 111, 102, 116, 32,  40,  82,  41,  32,  72,  76,
+    83,  76,  32,  83,  104, 97,  100, 101, 114, 32,  67,  111, 109, 112, 105, 108, 101, 114, 32,
+    54,  46,  51,  46,  57,  54,  48,  48,  46,  49,  54,  51,  56,  52,  0,   171, 171, 171, 31,
+    0,   0,   2,   0,   0,   0,   128, 0,   0,   3,   176, 31,  0,   0,   2,   0,   0,   0,   144,
+    0,   8,   15,  160, 66,  0,   0,   3,   0,   0,   15,  128, 0,   0,   228, 176, 0,   8,   228,
+    160, 6,   0,   0,   2,   1,   0,   8,   128, 0,   0,   255, 128, 5,   0,   0,   3,   1,   0,
+    7,   128, 0,   0,   228, 128, 1,   0,   255, 128, 88,  0,   0,   4,   0,   0,   7,   128, 0,
+    0,   255, 129, 0,   0,   228, 128, 1,   0,   228, 128, 1,   0,   0,   2,   1,   0,   15,  128,
+    0,   0,   228, 160, 4,   0,   0,   4,   0,   0,   15,  128, 0,   0,   228, 128, 1,   0,   228,
+    128, 1,   0,   228, 160, 1,   0,   0,   2,   0,   8,   15,  128, 0,   0,   228, 128, 255, 255,
+    0,   0};
--- a/gfx/angle/src/libANGLE/renderer/d3d/d3d9/shaders/compiled/luminancepremultps.h
+++ b/gfx/angle/src/libANGLE/renderer/d3d/d3d9/shaders/compiled/luminancepremultps.h
@@ -1,54 +1,50 @@
-#if 0
-//
-// Generated by Microsoft (R) HLSL Shader Compiler 6.3.9600.16384
-//
-// Parameters:
-//
-//   float4 add;
-//   float4 mult;
-//   sampler2D tex;
-//
-//
-// Registers:
-//
-//   Name         Reg   Size
-//   ------------ ----- ----
-//   mult         c0       1
-//   add          c1       1
-//   tex          s0       1
-//
-
-    ps_2_0
-    dcl t0.xy
-    dcl_2d s0
-    texld r0, t0, s0
-    mov r1.xw, c0
-    mad r0.x, r0.x, r1.x, c1.x
-    mad r0.y, r0.w, r1.w, c1.w
-    mul r1.xyz, r0.y, r0.x
-    mov r1.w, r0.y
-    mov oC0, r1
-
-// approximately 7 instruction slots used (1 texture, 6 arithmetic)
-#endif
-
-const BYTE g_ps20_luminancepremultps[] = {
-    0,   2,   255, 255, 254, 255, 50,  0,   67,  84,  65,  66,  28,  0,   0,   0,   143, 0,   0,
-    0,   0,   2,   255, 255, 3,   0,   0,   0,   28,  0,   0,   0,   0,   1,   0,   0,   136, 0,
-    0,   0,   88,  0,   0,   0,   2,   0,   1,   0,   1,   0,   0,   0,   92,  0,   0,   0,   0,
-    0,   0,   0,   108, 0,   0,   0,   2,   0,   0,   0,   1,   0,   0,   0,   92,  0,   0,   0,
-    0,   0,   0,   0,   113, 0,   0,   0,   3,   0,   0,   0,   1,   0,   0,   0,   120, 0,   0,
-    0,   0,   0,   0,   0,   97,  100, 100, 0,   1,   0,   3,   0,   1,   0,   4,   0,   1,   0,
-    0,   0,   0,   0,   0,   0,   109, 117, 108, 116, 0,   116, 101, 120, 0,   171, 171, 171, 4,
-    0,   12,  0,   1,   0,   1,   0,   1,   0,   0,   0,   0,   0,   0,   0,   112, 115, 95,  50,
-    95,  48,  0,   77,  105, 99,  114, 111, 115, 111, 102, 116, 32,  40,  82,  41,  32,  72,  76,
-    83,  76,  32,  83,  104, 97,  100, 101, 114, 32,  67,  111, 109, 112, 105, 108, 101, 114, 32,
-    54,  46,  51,  46,  57,  54,  48,  48,  46,  49,  54,  51,  56,  52,  0,   171, 171, 171, 31,
-    0,   0,   2,   0,   0,   0,   128, 0,   0,   3,   176, 31,  0,   0,   2,   0,   0,   0,   144,
-    0,   8,   15,  160, 66,  0,   0,   3,   0,   0,   15,  128, 0,   0,   228, 176, 0,   8,   228,
-    160, 1,   0,   0,   2,   1,   0,   9,   128, 0,   0,   228, 160, 4,   0,   0,   4,   0,   0,
-    1,   128, 0,   0,   0,   128, 1,   0,   0,   128, 1,   0,   0,   160, 4,   0,   0,   4,   0,
-    0,   2,   128, 0,   0,   255, 128, 1,   0,   255, 128, 1,   0,   255, 160, 5,   0,   0,   3,
-    1,   0,   7,   128, 0,   0,   85,  128, 0,   0,   0,   128, 1,   0,   0,   2,   1,   0,   8,
-    128, 0,   0,   85,  128, 1,   0,   0,   2,   0,   8,   15,  128, 1,   0,   228, 128, 255, 255,
-    0,   0};
+#if 0
+//
+// Generated by Microsoft (R) HLSL Shader Compiler 6.3.9600.16384
+//
+// Parameters:
+//
+//   float4 add;
+//   float4 mult;
+//   sampler2D tex;
+//
+//
+// Registers:
+//
+//   Name         Reg   Size
+//   ------------ ----- ----
+//   mult         c0       1
+//   add          c1       1
+//   tex          s0       1
+//
+
+    ps_2_0
+    dcl t0.xy
+    dcl_2d s0
+    texld r0, t0, s0
+    mul r0.xyz, r0.w, r0.x
+    mov r1, c0
+    mad r0, r0, r1, c1
+    mov oC0, r0
+
+// approximately 5 instruction slots used (1 texture, 4 arithmetic)
+#endif
+
+const BYTE g_ps20_luminancepremultps[] = {
+    0,   2,   255, 255, 254, 255, 50,  0,   67,  84,  65,  66,  28,  0,   0,   0,   143, 0,   0,
+    0,   0,   2,   255, 255, 3,   0,   0,   0,   28,  0,   0,   0,   0,   1,   0,   0,   136, 0,
+    0,   0,   88,  0,   0,   0,   2,   0,   1,   0,   1,   0,   0,   0,   92,  0,   0,   0,   0,
+    0,   0,   0,   108, 0,   0,   0,   2,   0,   0,   0,   1,   0,   0,   0,   92,  0,   0,   0,
+    0,   0,   0,   0,   113, 0,   0,   0,   3,   0,   0,   0,   1,   0,   0,   0,   120, 0,   0,
+    0,   0,   0,   0,   0,   97,  100, 100, 0,   1,   0,   3,   0,   1,   0,   4,   0,   1,   0,
+    0,   0,   0,   0,   0,   0,   109, 117, 108, 116, 0,   116, 101, 120, 0,   171, 171, 171, 4,
+    0,   12,  0,   1,   0,   1,   0,   1,   0,   0,   0,   0,   0,   0,   0,   112, 115, 95,  50,
+    95,  48,  0,   77,  105, 99,  114, 111, 115, 111, 102, 116, 32,  40,  82,  41,  32,  72,  76,
+    83,  76,  32,  83,  104, 97,  100, 101, 114, 32,  67,  111, 109, 112, 105, 108, 101, 114, 32,
+    54,  46,  51,  46,  57,  54,  48,  48,  46,  49,  54,  51,  56,  52,  0,   171, 171, 171, 31,
+    0,   0,   2,   0,   0,   0,   128, 0,   0,   3,   176, 31,  0,   0,   2,   0,   0,   0,   144,
+    0,   8,   15,  160, 66,  0,   0,   3,   0,   0,   15,  128, 0,   0,   228, 176, 0,   8,   228,
+    160, 5,   0,   0,   3,   0,   0,   7,   128, 0,   0,   255, 128, 0,   0,   0,   128, 1,   0,
+    0,   2,   1,   0,   15,  128, 0,   0,   228, 160, 4,   0,   0,   4,   0,   0,   15,  128, 0,
+    0,   228, 128, 1,   0,   228, 128, 1,   0,   228, 160, 1,   0,   0,   2,   0,   8,   15,  128,
+    0,   0,   228, 128, 255, 255, 0,   0};
--- a/gfx/angle/src/libANGLE/renderer/d3d/d3d9/shaders/compiled/luminanceps.h
+++ b/gfx/angle/src/libANGLE/renderer/d3d/d3d9/shaders/compiled/luminanceps.h
@@ -1,94 +1,94 @@
-#if 0
-//
-// Generated by Microsoft (R) HLSL Shader Compiler 6.3.9600.16384
-//
-// Parameters:
-//
-//   float4 add;
-//   float4 mult;
-//   sampler2D tex;
-//
-//
-// Registers:
-//
-//   Name         Reg   Size
-//   ------------ ----- ----
-//   mult         c0       1
-//   add          c1       1
-//   tex          s0       1
-//
-
-    ps_2_0
-    dcl t0.xy
-    dcl_2d s0
-    texld r0, t0, s0
-    mov r1.xw, c0
-    mad r0.x, r0.x, r1.x, c1.x
-    mad r0.y, r0.w, r1.w, c1.w
-    mov r1.xyz, r0.x
-    mov r1.w, r0.y
-    mov oC0, r1
-
-// approximately 7 instruction slots used (1 texture, 6 arithmetic)
-#endif
-
-const BYTE g_ps20_luminanceps[] =
-{
-      0,   2, 255, 255, 254, 255, 
-     50,   0,  67,  84,  65,  66, 
-     28,   0,   0,   0, 143,   0, 
-      0,   0,   0,   2, 255, 255, 
-      3,   0,   0,   0,  28,   0, 
-      0,   0,   0,   1,   0,   0, 
-    136,   0,   0,   0,  88,   0, 
-      0,   0,   2,   0,   1,   0, 
-      1,   0,   0,   0,  92,   0, 
-      0,   0,   0,   0,   0,   0, 
-    108,   0,   0,   0,   2,   0, 
-      0,   0,   1,   0,   0,   0, 
-     92,   0,   0,   0,   0,   0, 
-      0,   0, 113,   0,   0,   0, 
-      3,   0,   0,   0,   1,   0, 
-      0,   0, 120,   0,   0,   0, 
-      0,   0,   0,   0,  97, 100, 
-    100,   0,   1,   0,   3,   0, 
-      1,   0,   4,   0,   1,   0, 
-      0,   0,   0,   0,   0,   0, 
-    109, 117, 108, 116,   0, 116, 
-    101, 120,   0, 171, 171, 171, 
-      4,   0,  12,   0,   1,   0, 
-      1,   0,   1,   0,   0,   0, 
-      0,   0,   0,   0, 112, 115, 
-     95,  50,  95,  48,   0,  77, 
-    105,  99, 114, 111, 115, 111, 
-    102, 116,  32,  40,  82,  41, 
-     32,  72,  76,  83,  76,  32, 
-     83, 104,  97, 100, 101, 114, 
-     32,  67, 111, 109, 112, 105, 
-    108, 101, 114,  32,  54,  46, 
-     51,  46,  57,  54,  48,  48, 
-     46,  49,  54,  51,  56,  52, 
-      0, 171, 171, 171,  31,   0, 
-      0,   2,   0,   0,   0, 128, 
-      0,   0,   3, 176,  31,   0, 
-      0,   2,   0,   0,   0, 144, 
-      0,   8,  15, 160,  66,   0, 
-      0,   3,   0,   0,  15, 128, 
-      0,   0, 228, 176,   0,   8, 
-    228, 160,   1,   0,   0,   2, 
-      1,   0,   9, 128,   0,   0, 
-    228, 160,   4,   0,   0,   4, 
-      0,   0,   1, 128,   0,   0, 
-      0, 128,   1,   0,   0, 128, 
-      1,   0,   0, 160,   4,   0, 
-      0,   4,   0,   0,   2, 128, 
-      0,   0, 255, 128,   1,   0, 
-    255, 128,   1,   0, 255, 160, 
-      1,   0,   0,   2,   1,   0, 
-      7, 128,   0,   0,   0, 128, 
-      1,   0,   0,   2,   1,   0, 
-      8, 128,   0,   0,  85, 128, 
-      1,   0,   0,   2,   0,   8, 
-     15, 128,   1,   0, 228, 128, 
-    255, 255,   0,   0
-};
+#if 0
+//
+// Generated by Microsoft (R) HLSL Shader Compiler 6.3.9600.16384
+//
+// Parameters:
+//
+//   float4 add;
+//   float4 mult;
+//   sampler2D tex;
+//
+//
+// Registers:
+//
+//   Name         Reg   Size
+//   ------------ ----- ----
+//   mult         c0       1
+//   add          c1       1
+//   tex          s0       1
+//
+
+    ps_2_0
+    dcl t0.xy
+    dcl_2d s0
+    texld r0, t0, s0
+    mov r1.xw, c0
+    mad r0.x, r0.x, r1.x, c1.x
+    mad r0.y, r0.w, r1.w, c1.w
+    mov r1.xyz, r0.x
+    mov r1.w, r0.y
+    mov oC0, r1
+
+// approximately 7 instruction slots used (1 texture, 6 arithmetic)
+#endif
+
+const BYTE g_ps20_luminanceps[] =
+{
+      0,   2, 255, 255, 254, 255, 
+     50,   0,  67,  84,  65,  66, 
+     28,   0,   0,   0, 143,   0, 
+      0,   0,   0,   2, 255, 255, 
+      3,   0,   0,   0,  28,   0, 
+      0,   0,   0,   1,   0,   0, 
+    136,   0,   0,   0,  88,   0, 
+      0,   0,   2,   0,   1,   0, 
+      1,   0,   0,   0,  92,   0, 
+      0,   0,   0,   0,   0,   0, 
+    108,   0,   0,   0,   2,   0, 
+      0,   0,   1,   0,   0,   0, 
+     92,   0,   0,   0,   0,   0, 
+      0,   0, 113,   0,   0,   0, 
+      3,   0,   0,   0,   1,   0, 
+      0,   0, 120,   0,   0,   0, 
+      0,   0,   0,   0,  97, 100, 
+    100,   0,   1,   0,   3,   0, 
+      1,   0,   4,   0,   1,   0, 
+      0,   0,   0,   0,   0,   0, 
+    109, 117, 108, 116,   0, 116, 
+    101, 120,   0, 171, 171, 171, 
+      4,   0,  12,   0,   1,   0, 
+      1,   0,   1,   0,   0,   0, 
+      0,   0,   0,   0, 112, 115, 
+     95,  50,  95,  48,   0,  77, 
+    105,  99, 114, 111, 115, 111, 
+    102, 116,  32,  40,  82,  41, 
+     32,  72,  76,  83,  76,  32, 
+     83, 104,  97, 100, 101, 114, 
+     32,  67, 111, 109, 112, 105, 
+    108, 101, 114,  32,  54,  46, 
+     51,  46,  57,  54,  48,  48, 
+     46,  49,  54,  51,  56,  52, 
+      0, 171, 171, 171,  31,   0, 
+      0,   2,   0,   0,   0, 128, 
+      0,   0,   3, 176,  31,   0, 
+      0,   2,   0,   0,   0, 144, 
+      0,   8,  15, 160,  66,   0, 
+      0,   3,   0,   0,  15, 128, 
+      0,   0, 228, 176,   0,   8, 
+    228, 160,   1,   0,   0,   2, 
+      1,   0,   9, 128,   0,   0, 
+    228, 160,   4,   0,   0,   4, 
+      0,   0,   1, 128,   0,   0, 
+      0, 128,   1,   0,   0, 128, 
+      1,   0,   0, 160,   4,   0, 
+      0,   4,   0,   0,   2, 128, 
+      0,   0, 255, 128,   1,   0, 
+    255, 128,   1,   0, 255, 160, 
+      1,   0,   0,   2,   1,   0, 
+      7, 128,   0,   0,   0, 128, 
+      1,   0,   0,   2,   1,   0, 
+      8, 128,   0,   0,  85, 128, 
+      1,   0,   0,   2,   0,   8, 
+     15, 128,   1,   0, 228, 128, 
+    255, 255,   0,   0
+};
--- a/gfx/angle/src/libANGLE/renderer/d3d/d3d9/shaders/compiled/luminanceunmultps.h
+++ b/gfx/angle/src/libANGLE/renderer/d3d/d3d9/shaders/compiled/luminanceunmultps.h
@@ -1,57 +1,54 @@
-#if 0
-//
-// Generated by Microsoft (R) HLSL Shader Compiler 6.3.9600.16384
-//
-// Parameters:
-//
-//   float4 add;
-//   float4 mult;
-//   sampler2D tex;
-//
-//
-// Registers:
-//
-//   Name         Reg   Size
-//   ------------ ----- ----
-//   mult         c0       1
-//   add          c1       1
-//   tex          s0       1
-//
-
-    ps_2_0
-    dcl t0.xy
-    dcl_2d s0
-    texld r0, t0, s0
-    mov r1.xw, c0
-    mad r0.x, r0.x, r1.x, c1.x
-    mad r0.y, r0.w, r1.w, c1.w
-    rcp r0.z, r0.y
-    mul r0.z, r0.z, r0.x
-    cmp r1.xyz, -r0.y, r0.x, r0.z
-    mov r1.w, r0.y
-    mov oC0, r1
-
-// approximately 9 instruction slots used (1 texture, 8 arithmetic)
-#endif
-
-const BYTE g_ps20_luminanceunmultps[] = {
-    0,   2,   255, 255, 254, 255, 50,  0,   67,  84,  65,  66,  28,  0,   0,   0,   143, 0,   0,
-    0,   0,   2,   255, 255, 3,   0,   0,   0,   28,  0,   0,   0,   0,   1,   0,   0,   136, 0,
-    0,   0,   88,  0,   0,   0,   2,   0,   1,   0,   1,   0,   0,   0,   92,  0,   0,   0,   0,
-    0,   0,   0,   108, 0,   0,   0,   2,   0,   0,   0,   1,   0,   0,   0,   92,  0,   0,   0,
-    0,   0,   0,   0,   113, 0,   0,   0,   3,   0,   0,   0,   1,   0,   0,   0,   120, 0,   0,
-    0,   0,   0,   0,   0,   97,  100, 100, 0,   1,   0,   3,   0,   1,   0,   4,   0,   1,   0,
-    0,   0,   0,   0,   0,   0,   109, 117, 108, 116, 0,   116, 101, 120, 0,   171, 171, 171, 4,
-    0,   12,  0,   1,   0,   1,   0,   1,   0,   0,   0,   0,   0,   0,   0,   112, 115, 95,  50,
-    95,  48,  0,   77,  105, 99,  114, 111, 115, 111, 102, 116, 32,  40,  82,  41,  32,  72,  76,
-    83,  76,  32,  83,  104, 97,  100, 101, 114, 32,  67,  111, 109, 112, 105, 108, 101, 114, 32,
-    54,  46,  51,  46,  57,  54,  48,  48,  46,  49,  54,  51,  56,  52,  0,   171, 171, 171, 31,
-    0,   0,   2,   0,   0,   0,   128, 0,   0,   3,   176, 31,  0,   0,   2,   0,   0,   0,   144,
-    0,   8,   15,  160, 66,  0,   0,   3,   0,   0,   15,  128, 0,   0,   228, 176, 0,   8,   228,
-    160, 1,   0,   0,   2,   1,   0,   9,   128, 0,   0,   228, 160, 4,   0,   0,   4,   0,   0,
-    1,   128, 0,   0,   0,   128, 1,   0,   0,   128, 1,   0,   0,   160, 4,   0,   0,   4,   0,
-    0,   2,   128, 0,   0,   255, 128, 1,   0,   255, 128, 1,   0,   255, 160, 6,   0,   0,   2,
-    0,   0,   4,   128, 0,   0,   85,  128, 5,   0,   0,   3,   0,   0,   4,   128, 0,   0,   170,
-    128, 0,   0,   0,   128, 88,  0,   0,   4,   1,   0,   7,   128, 0,   0,   85,  129, 0,   0,
-    0,   128, 0,   0,   170, 128, 1,   0,   0,   2,   1,   0,   8,   128, 0,   0,   85,  128, 1,
-    0,   0,   2,   0,   8,   15,  128, 1,   0,   228, 128, 255, 255, 0,   0};
+#if 0
+//
+// Generated by Microsoft (R) HLSL Shader Compiler 6.3.9600.16384
+//
+// Parameters:
+//
+//   float4 add;
+//   float4 mult;
+//   sampler2D tex;
+//
+//
+// Registers:
+//
+//   Name         Reg   Size
+//   ------------ ----- ----
+//   mult         c0       1
+//   add          c1       1
+//   tex          s0       1
+//
+
+    ps_2_0
+    dcl t0.xy
+    dcl_2d s0
+    texld r0, t0, s0
+    rcp r1.w, r0.w
+    mul r1.x, r0.x, r1.w
+    cmp r0.xyz, -r0.w, r0.x, r1.x
+    mov r1, c0
+    mad r0, r0, r1, c1
+    mov oC0, r0
+
+// approximately 7 instruction slots used (1 texture, 6 arithmetic)
+#endif
+
+const BYTE g_ps20_luminanceunmultps[] = {
+    0,   2,   255, 255, 254, 255, 50,  0,   67,  84,  65,  66,  28,  0,   0,   0,   143, 0,   0,
+    0,   0,   2,   255, 255, 3,   0,   0,   0,   28,  0,   0,   0,   0,   1,   0,   0,   136, 0,
+    0,   0,   88,  0,   0,   0,   2,   0,   1,   0,   1,   0,   0,   0,   92,  0,   0,   0,   0,
+    0,   0,   0,   108, 0,   0,   0,   2,   0,   0,   0,   1,   0,   0,   0,   92,  0,   0,   0,
+    0,   0,   0,   0,   113, 0,   0,   0,   3,   0,   0,   0,   1,   0,   0,   0,   120, 0,   0,
+    0,   0,   0,   0,   0,   97,  100, 100, 0,   1,   0,   3,   0,   1,   0,   4,   0,   1,   0,
+    0,   0,   0,   0,   0,   0,   109, 117, 108, 116, 0,   116, 101, 120, 0,   171, 171, 171, 4,
+    0,   12,  0,   1,   0,   1,   0,   1,   0,   0,   0,   0,   0,   0,   0,   112, 115, 95,  50,
+    95,  48,  0,   77,  105, 99,  114, 111, 115, 111, 102, 116, 32,  40,  82,  41,  32,  72,  76,
+    83,  76,  32,  83,  104, 97,  100, 101, 114, 32,  67,  111, 109, 112, 105, 108, 101, 114, 32,
+    54,  46,  51,  46,  57,  54,  48,  48,  46,  49,  54,  51,  56,  52,  0,   171, 171, 171, 31,
+    0,   0,   2,   0,   0,   0,   128, 0,   0,   3,   176, 31,  0,   0,   2,   0,   0,   0,   144,
+    0,   8,   15,  160, 66,  0,   0,   3,   0,   0,   15,  128, 0,   0,   228, 176, 0,   8,   228,
+    160, 6,   0,   0,   2,   1,   0,   8,   128, 0,   0,   255, 128, 5,   0,   0,   3,   1,   0,
+    1,   128, 0,   0,   0,   128, 1,   0,   255, 128, 88,  0,   0,   4,   0,   0,   7,   128, 0,
+    0,   255, 129, 0,   0,   0,   128, 1,   0,   0,   128, 1,   0,   0,   2,   1,   0,   15,  128,
+    0,   0,   228, 160, 4,   0,   0,   4,   0,   0,   15,  128, 0,   0,   228, 128, 1,   0,   228,
+    128, 1,   0,   228, 160, 1,   0,   0,   2,   0,   8,   15,  128, 0,   0,   228, 128, 255, 255,
+    0,   0};
--- a/gfx/angle/src/libANGLE/renderer/d3d/d3d9/shaders/compiled/passthroughps.h
+++ b/gfx/angle/src/libANGLE/renderer/d3d/d3d9/shaders/compiled/passthroughps.h
@@ -1,61 +1,61 @@
-#if 0
-//
-// Generated by Microsoft (R) HLSL Shader Compiler 6.3.9600.16384
-//
-// Parameters:
-//
-//   sampler2D tex;
-//
-//
-// Registers:
-//
-//   Name         Reg   Size
-//   ------------ ----- ----
-//   tex          s0       1
-//
-
-    ps_2_0
-    dcl t0.xy
-    dcl_2d s0
-    texld r0, t0, s0
-    mov oC0, r0
-
-// approximately 2 instruction slots used (1 texture, 1 arithmetic)
-#endif
-
-const BYTE g_ps20_passthroughps[] =
-{
-      0,   2, 255, 255, 254, 255, 
-     33,   0,  67,  84,  65,  66, 
-     28,   0,   0,   0,  75,   0, 
-      0,   0,   0,   2, 255, 255, 
-      1,   0,   0,   0,  28,   0, 
-      0,   0,   0,   1,   0,   0, 
-     68,   0,   0,   0,  48,   0, 
-      0,   0,   3,   0,   0,   0, 
-      1,   0,   0,   0,  52,   0, 
-      0,   0,   0,   0,   0,   0, 
-    116, 101, 120,   0,   4,   0, 
-     12,   0,   1,   0,   1,   0, 
-      1,   0,   0,   0,   0,   0, 
-      0,   0, 112, 115,  95,  50, 
-     95,  48,   0,  77, 105,  99, 
-    114, 111, 115, 111, 102, 116, 
-     32,  40,  82,  41,  32,  72, 
-     76,  83,  76,  32,  83, 104, 
-     97, 100, 101, 114,  32,  67, 
-    111, 109, 112, 105, 108, 101, 
-    114,  32,  54,  46,  51,  46, 
-     57,  54,  48,  48,  46,  49, 
-     54,  51,  56,  52,   0, 171, 
-    171, 171,  31,   0,   0,   2, 
-      0,   0,   0, 128,   0,   0, 
-      3, 176,  31,   0,   0,   2, 
-      0,   0,   0, 144,   0,   8, 
-     15, 160,  66,   0,   0,   3, 
-      0,   0,  15, 128,   0,   0, 
-    228, 176,   0,   8, 228, 160, 
-      1,   0,   0,   2,   0,   8, 
-     15, 128,   0,   0, 228, 128, 
-    255, 255,   0,   0
-};
+#if 0
+//
+// Generated by Microsoft (R) HLSL Shader Compiler 6.3.9600.16384
+//
+// Parameters:
+//
+//   sampler2D tex;
+//
+//
+// Registers:
+//
+//   Name         Reg   Size
+//   ------------ ----- ----
+//   tex          s0       1
+//
+
+    ps_2_0
+    dcl t0.xy
+    dcl_2d s0
+    texld r0, t0, s0
+    mov oC0, r0
+
+// approximately 2 instruction slots used (1 texture, 1 arithmetic)
+#endif
+
+const BYTE g_ps20_passthroughps[] =
+{
+      0,   2, 255, 255, 254, 255, 
+     33,   0,  67,  84,  65,  66, 
+     28,   0,   0,   0,  75,   0, 
+      0,   0,   0,   2, 255, 255, 
+      1,   0,   0,   0,  28,   0, 
+      0,   0,   0,   1,   0,   0, 
+     68,   0,   0,   0,  48,   0, 
+      0,   0,   3,   0,   0,   0, 
+      1,   0,   0,   0,  52,   0, 
+      0,   0,   0,   0,   0,   0, 
+    116, 101, 120,   0,   4,   0, 
+     12,   0,   1,   0,   1,   0, 
+      1,   0,   0,   0,   0,   0, 
+      0,   0, 112, 115,  95,  50, 
+     95,  48,   0,  77, 105,  99, 
+    114, 111, 115, 111, 102, 116, 
+     32,  40,  82,  41,  32,  72, 
+     76,  83,  76,  32,  83, 104, 
+     97, 100, 101, 114,  32,  67, 
+    111, 109, 112, 105, 108, 101, 
+    114,  32,  54,  46,  51,  46, 
+     57,  54,  48,  48,  46,  49, 
+     54,  51,  56,  52,   0, 171, 
+    171, 171,  31,   0,   0,   2, 
+      0,   0,   0, 128,   0,   0, 
+      3, 176,  31,   0,   0,   2, 
+      0,   0,   0, 144,   0,   8, 
+     15, 160,  66,   0,   0,   3, 
+      0,   0,  15, 128,   0,   0, 
+    228, 176,   0,   8, 228, 160, 
+      1,   0,   0,   2,   0,   8, 
+     15, 128,   0,   0, 228, 128, 
+    255, 255,   0,   0
+};
--- a/gfx/angle/src/libANGLE/renderer/d3d/d3d9/shaders/compiled/standardvs.h
+++ b/gfx/angle/src/libANGLE/renderer/d3d/d3d9/shaders/compiled/standardvs.h
@@ -1,46 +1,46 @@
-#if 0
-//
-// Generated by Microsoft (R) HLSL Shader Compiler 6.3.9600.16384
-//
-// Parameters:
-//
-//   float4 halfPixelSize;
-//   float4 texcoordOffset;
-//
-//
-// Registers:
-//
-//   Name           Reg   Size
-//   -------------- ----- ----
-//   halfPixelSize  c0       1
-//   texcoordOffset c1       1
-//
-
-    vs_2_0
-    def c2, 0.5, -0.5, 1, 0
-    dcl_position v0
-    add oPos, v0, c0
-    mad r0, v0, c2.xyzz, c2.xxww
-    mov oT0.zw, r0
-    mad oT0.xy, r0, c1.zwzw, c1
-
-// approximately 4 instruction slots used
-#endif
-
-const BYTE g_vs20_standardvs[] = {
-    0,   2,   254, 255, 254, 255, 44,  0,   67,  84,  65,  66,  28,  0,   0,   0,   122, 0,   0,
-    0,   0,   2,   254, 255, 2,   0,   0,   0,   28,  0,   0,   0,   0,   1,   0,   0,   115, 0,
-    0,   0,   68,  0,   0,   0,   2,   0,   0,   0,   1,   0,   0,   0,   84,  0,   0,   0,   0,
-    0,   0,   0,   100, 0,   0,   0,   2,   0,   1,   0,   1,   0,   0,   0,   84,  0,   0,   0,
-    0,   0,   0,   0,   104, 97,  108, 102, 80,  105, 120, 101, 108, 83,  105, 122, 101, 0,   171,
-    171, 1,   0,   3,   0,   1,   0,   4,   0,   1,   0,   0,   0,   0,   0,   0,   0,   116, 101,
-    120, 99,  111, 111, 114, 100, 79,  102, 102, 115, 101, 116, 0,   118, 115, 95,  50,  95,  48,
-    0,   77,  105, 99,  114, 111, 115, 111, 102, 116, 32,  40,  82,  41,  32,  72,  76,  83,  76,
-    32,  83,  104, 97,  100, 101, 114, 32,  67,  111, 109, 112, 105, 108, 101, 114, 32,  54,  46,
-    51,  46,  57,  54,  48,  48,  46,  49,  54,  51,  56,  52,  0,   81,  0,   0,   5,   2,   0,
-    15,  160, 0,   0,   0,   63,  0,   0,   0,   191, 0,   0,   128, 63,  0,   0,   0,   0,   31,
-    0,   0,   2,   0,   0,   0,   128, 0,   0,   15,  144, 2,   0,   0,   3,   0,   0,   15,  192,
-    0,   0,   228, 144, 0,   0,   228, 160, 4,   0,   0,   4,   0,   0,   15,  128, 0,   0,   228,
-    144, 2,   0,   164, 160, 2,   0,   240, 160, 1,   0,   0,   2,   0,   0,   12,  224, 0,   0,
-    228, 128, 4,   0,   0,   4,   0,   0,   3,   224, 0,   0,   228, 128, 1,   0,   238, 160, 1,
-    0,   228, 160, 255, 255, 0,   0};
+#if 0
+//
+// Generated by Microsoft (R) HLSL Shader Compiler 6.3.9600.16384
+//
+// Parameters:
+//
+//   float4 halfPixelSize;
+//   float4 texcoordOffset;
+//
+//
+// Registers:
+//
+//   Name           Reg   Size
+//   -------------- ----- ----
+//   halfPixelSize  c0       1
+//   texcoordOffset c1       1
+//
+
+    vs_2_0
+    def c2, 0.5, -0.5, 1, 0
+    dcl_position v0
+    add oPos, v0, c0
+    mad r0, v0, c2.xyzz, c2.xxww
+    mov oT0.zw, r0
+    mad oT0.xy, r0, c1.zwzw, c1
+
+// approximately 4 instruction slots used
+#endif
+
+const BYTE g_vs20_standardvs[] = {
+    0,   2,   254, 255, 254, 255, 44,  0,   67,  84,  65,  66,  28,  0,   0,   0,   122, 0,   0,
+    0,   0,   2,   254, 255, 2,   0,   0,   0,   28,  0,   0,   0,   0,   1,   0,   0,   115, 0,
+    0,   0,   68,  0,   0,   0,   2,   0,   0,   0,   1,   0,   0,   0,   84,  0,   0,   0,   0,
+    0,   0,   0,   100, 0,   0,   0,   2,   0,   1,   0,   1,   0,   0,   0,   84,  0,   0,   0,
+    0,   0,   0,   0,   104, 97,  108, 102, 80,  105, 120, 101, 108, 83,  105, 122, 101, 0,   171,
+    171, 1,   0,   3,   0,   1,   0,   4,   0,   1,   0,   0,   0,   0,   0,   0,   0,   116, 101,
+    120, 99,  111, 111, 114, 100, 79,  102, 102, 115, 101, 116, 0,   118, 115, 95,  50,  95,  48,
+    0,   77,  105, 99,  114, 111, 115, 111, 102, 116, 32,  40,  82,  41,  32,  72,  76,  83,  76,
+    32,  83,  104, 97,  100, 101, 114, 32,  67,  111, 109, 112, 105, 108, 101, 114, 32,  54,  46,
+    51,  46,  57,  54,  48,  48,  46,  49,  54,  51,  56,  52,  0,   81,  0,   0,   5,   2,   0,
+    15,  160, 0,   0,   0,   63,  0,   0,   0,   191, 0,   0,   128, 63,  0,   0,   0,   0,   31,
+    0,   0,   2,   0,   0,   0,   128, 0,   0,   15,  144, 2,   0,   0,   3,   0,   0,   15,  192,
+    0,   0,   228, 144, 0,   0,   228, 160, 4,   0,   0,   4,   0,   0,   15,  128, 0,   0,   228,
+    144, 2,   0,   164, 160, 2,   0,   240, 160, 1,   0,   0,   2,   0,   0,   12,  224, 0,   0,
+    228, 128, 4,   0,   0,   4,   0,   0,   3,   224, 0,   0,   228, 128, 1,   0,   238, 160, 1,
+    0,   228, 160, 255, 255, 0,   0};
--- a/gfx/angle/src/libANGLE/renderer/d3d/d3d9/shaders/generate_shaders.bat
+++ b/gfx/angle/src/libANGLE/renderer/d3d/d3d9/shaders/generate_shaders.bat
@@ -1,66 +1,66 @@
-@ECHO OFF
-REM
-REM Copyright (c) 2013 The ANGLE Project Authors. All rights reserved.
-REM Use of this source code is governed by a BSD-style license that can be
-REM found in the LICENSE file.
-REM
-
-PATH %PATH%;%ProgramFiles(x86)%\Windows Kits\8.1\bin\x86;%DXSDK_DIR%\Utilities\bin\x86
-
-setlocal
-set errorCount=0
-set successCount=0
-set debug=0
-
-if "%1" == "debug" (
-    set debug=1
-)
-if "%1" == "release" (
-    set debug=0
-)
-
-::              | Input file          | Entry point           | Type | Output file                        | Debug |
-call:BuildShader Blit.vs               standardvs              vs_2_0 compiled\standardvs.h                %debug%
-call:BuildShader Blit.ps               passthroughps           ps_2_0 compiled\passthroughps.h             %debug%
-call:BuildShader Blit.ps               luminanceps             ps_2_0 compiled\luminanceps.h               %debug%
-call:BuildShader Blit.ps               luminancepremultps      ps_2_0 compiled\luminancepremultps.h        %debug%
-call:BuildShader Blit.ps               luminanceunmultps       ps_2_0 compiled\luminanceunmultps.h         %debug%
-call:BuildShader Blit.ps               componentmaskps         ps_2_0 compiled\componentmaskps.h           %debug%
-call:BuildShader Blit.ps               componentmaskpremultps  ps_2_0 compiled\componentmaskpremultps.h    %debug%
-call:BuildShader Blit.ps               componentmaskunmultps   ps_2_0 compiled\componentmaskunmultps.h     %debug%
-
-echo.
-
-if %successCount% GTR 0 (
-   echo %successCount% shaders compiled successfully.
-)
-if %errorCount% GTR 0 (
-   echo There were %errorCount% shader compilation errors.
-)
-
-endlocal
-exit /b
-
-:BuildShader
-set input=%~1
-set entry=%~2
-set type=%~3
-set output=%~4
-set debug=%~5
-
-if %debug% == 0 (
-    set "buildCMD=fxc /nologo /E %entry% /T %type% /Fh %output% %input%"
-) else (
-    set "buildCMD=fxc /nologo /Zi /Od /E %entry% /T %type% /Fh %output% %input%"
-)
-
-set error=0
-%buildCMD% || set error=1
-
-if %error% == 0 (
-    set /a successCount=%successCount%+1
-) else (
-    set /a errorCount=%errorCount%+1
-)
-
-exit /b
+@ECHO OFF
+REM
+REM Copyright (c) 2013 The ANGLE Project Authors. All rights reserved.
+REM Use of this source code is governed by a BSD-style license that can be
+REM found in the LICENSE file.
+REM
+
+PATH %PATH%;%ProgramFiles(x86)%\Windows Kits\8.1\bin\x86;%DXSDK_DIR%\Utilities\bin\x86
+
+setlocal
+set errorCount=0
+set successCount=0
+set debug=0
+
+if "%1" == "debug" (
+    set debug=1
+)
+if "%1" == "release" (
+    set debug=0
+)
+
+::              | Input file          | Entry point           | Type | Output file                        | Debug |
+call:BuildShader Blit.vs               standardvs              vs_2_0 compiled\standardvs.h                %debug%
+call:BuildShader Blit.ps               passthroughps           ps_2_0 compiled\passthroughps.h             %debug%
+call:BuildShader Blit.ps               luminanceps             ps_2_0 compiled\luminanceps.h               %debug%
+call:BuildShader Blit.ps               luminancepremultps      ps_2_0 compiled\luminancepremultps.h        %debug%
+call:BuildShader Blit.ps               luminanceunmultps       ps_2_0 compiled\luminanceunmultps.h         %debug%
+call:BuildShader Blit.ps               componentmaskps         ps_2_0 compiled\componentmaskps.h           %debug%
+call:BuildShader Blit.ps               componentmaskpremultps  ps_2_0 compiled\componentmaskpremultps.h    %debug%
+call:BuildShader Blit.ps               componentmaskunmultps   ps_2_0 compiled\componentmaskunmultps.h     %debug%
+
+echo.
+
+if %successCount% GTR 0 (
+   echo %successCount% shaders compiled successfully.
+)
+if %errorCount% GTR 0 (
+   echo There were %errorCount% shader compilation errors.
+)
+
+endlocal
+exit /b
+
+:BuildShader
+set input=%~1
+set entry=%~2
+set type=%~3
+set output=%~4
+set debug=%~5
+
+if %debug% == 0 (
+    set "buildCMD=fxc /nologo /E %entry% /T %type% /Fh %output% %input%"
+) else (
+    set "buildCMD=fxc /nologo /Zi /Od /E %entry% /T %type% /Fh %output% %input%"
+)
+
+set error=0
+%buildCMD% || set error=1
+
+if %error% == 0 (
+    set /a successCount=%successCount%+1
+) else (
+    set /a errorCount=%errorCount%+1
+)
+
+exit /b
--- a/gfx/angle/src/libANGLE/renderer/gen_angle_format_table.py
+++ b/gfx/angle/src/libANGLE/renderer/gen_angle_format_table.py
@@ -27,16 +27,18 @@ template_autogen_h = """// GENERATED FIL
 namespace angle
 {{
 
 enum class Format::ID
 {{
 {angle_format_enum}
 }};
 
+constexpr uint32_t kNumANGLEFormats = {num_angle_formats};
+
 }}  // namespace angle
 """
 
 template_autogen_inl = """// GENERATED FILE - DO NOT EDIT.
 // Generated by {script_name} using data from {data_source_name}
 //
 // Copyright {copyright_year} The ANGLE Project Authors. All rights reserved.
 // Use of this source code is governed by a BSD-style license that can be
@@ -65,19 +67,17 @@ constexpr Format g_formatInfoTable[] = {
 {angle_format_info_cases}    // clang-format on
 }};
 
 // static
 Format::ID Format::InternalFormatToID(GLenum internalFormat)
 {{
     switch (internalFormat)
     {{
-        // clang-format off
 {angle_format_switch}
-        // clang-format on
     }}
 }}
 
 // static
 const Format &Format::Get(ID id)
 {{
     return g_formatInfoTable[static_cast<size_t>(id)];
 }}
@@ -226,18 +226,19 @@ def gen_enum_string(all_angle):
             continue
         enum_data += ',\n    ' + format_id
     return enum_data
 
 def gen_map_switch_string(gl_to_angle):
     switch_data = '';
     for gl_format in gl_to_angle:
         angle_format = gl_to_angle[gl_format]
-        switch_data += "        case " + gl_format + ": return Format::ID::" + angle_format + ";\n"
-    switch_data += "        default: return Format::ID::NONE;"
+        switch_data += "        case " + gl_format + ":\nreturn Format::ID::" + angle_format + ";\n"
+    switch_data += "        default:\n"
+    switch_data += "            return Format::ID::NONE;"
     return switch_data;
 
 gl_to_angle = angle_format.load_forward_table('angle_format_map.json')
 angle_to_gl = angle_format.load_inverse_table('angle_format_map.json')
 data_source_name = 'angle_format_data.json'
 json_data = angle_format.load_json(data_source_name)
 all_angle = angle_to_gl.keys()
 
@@ -250,16 +251,18 @@ output_cpp = template_autogen_inl.format
     angle_format_info_cases = angle_format_cases,
     angle_format_switch = switch_data,
     data_source_name = data_source_name)
 with open('Format_table_autogen.cpp', 'wt') as out_file:
     out_file.write(output_cpp)
     out_file.close()
 
 enum_data = gen_enum_string(all_angle)
+num_angle_formats = len(all_angle)
 output_h = template_autogen_h.format(
     script_name = sys.argv[0],
     copyright_year = date.today().year,
     angle_format_enum = enum_data,
-    data_source_name = data_source_name)
+    data_source_name = data_source_name,
+    num_angle_formats = num_angle_formats)
 with open('Format_ID_autogen.inl', 'wt') as out_file:
     out_file.write(output_h)
     out_file.close()
--- a/gfx/angle/src/libANGLE/renderer/gl/BlitGL.cpp
+++ b/gfx/angle/src/libANGLE/renderer/gl/BlitGL.cpp
@@ -173,16 +173,18 @@ gl::Error BlitGL::copyImageToLUMAWorkaro
 {
     mStateManager->bindTexture(textureType, texture);
 
     // Allocate the texture memory
     GLenum format = gl::GetUnsizedFormat(internalFormat);
 
     gl::PixelUnpackState unpack;
     mStateManager->setPixelUnpackState(unpack);
+    mStateManager->setPixelUnpackBuffer(
+        context->getGLState().getTargetBuffer(gl::BufferBinding::PixelUnpack));
     mFunctions->texImage2D(target, static_cast<GLint>(level), internalFormat, sourceArea.width,
                            sourceArea.height, 0, format,
                            source->getImplementationColorReadType(context), nullptr);
 
     return copySubImageToLUMAWorkaroundTexture(context, texture, textureType, target, lumaFormat,
                                                level, gl::Offset(0, 0, 0), sourceArea, source);
 }
 
@@ -566,31 +568,37 @@ gl::Error BlitGL::copySubTextureCPUReadb
     }
     else
     {
         ASSERT(sourceComponentType != GL_INT);
         readPixelsFormat = GL_RGBA;
         readFunction     = angle::ReadColor<angle::R8G8B8A8, GLfloat>;
     }
 
-    mStateManager->setPixelUnpackState(gl::PixelUnpackState(1, 0));
+    gl::PixelUnpackState unpack;
+    unpack.alignment = 1;
+    mStateManager->setPixelUnpackState(unpack);
+    mStateManager->setPixelUnpackBuffer(nullptr);
     mFunctions->readPixels(sourceArea.x, sourceArea.y, sourceArea.width, sourceArea.height,
                            readPixelsFormat, GL_UNSIGNED_BYTE, sourceMemory);
 
     angle::Format::ID destFormatID =
         angle::Format::InternalFormatToID(destInternalFormatInfo.sizedInternalFormat);
     const auto &destFormatInfo = angle::Format::Get(destFormatID);
     CopyImageCHROMIUM(
         sourceMemory, sourceArea.width * sourcePixelSize, sourcePixelSize, readFunction, destMemory,
         sourceArea.width * destInternalFormatInfo.pixelBytes, destInternalFormatInfo.pixelBytes,
         destFormatInfo.colorWriteFunction, destInternalFormatInfo.format,
         destInternalFormatInfo.componentType, sourceArea.width, sourceArea.height, unpackFlipY,
         unpackPremultiplyAlpha, unpackUnmultiplyAlpha);
 
-    mStateManager->setPixelPackState(gl::PixelPackState(1, false));
+    gl::PixelPackState pack;
+    pack.alignment = 1;
+    mStateManager->setPixelPackState(pack);
+    mStateManager->setPixelPackBuffer(nullptr);
 
     nativegl::TexSubImageFormat texSubImageFormat =
         nativegl::GetTexSubImageFormat(mFunctions, mWorkarounds, destFormat, destType);
 
     mFunctions->texSubImage2D(destTarget, static_cast<GLint>(destLevel), destOffset.x, destOffset.y,
                               sourceArea.width, sourceArea.height, texSubImageFormat.format,
                               texSubImageFormat.type, destMemory);
 
@@ -633,33 +641,33 @@ gl::Error BlitGL::initializeResources()
     if (mScratchFBO == 0)
     {
         mFunctions->genFramebuffers(1, &mScratchFBO);
     }
 
     if (mVertexBuffer == 0)
     {
         mFunctions->genBuffers(1, &mVertexBuffer);
-        mStateManager->bindBuffer(GL_ARRAY_BUFFER, mVertexBuffer);
+        mStateManager->bindBuffer(gl::BufferBinding::Array, mVertexBuffer);
 
         // Use a single, large triangle, to avoid arithmetic precision issues where fragments
         // with the same Y coordinate don't get exactly the same interpolated texcoord Y.
         float vertexData[] = {
             -0.5f, 0.0f, 1.5f, 0.0f, 0.5f, 2.0f,
         };
 
         mFunctions->bufferData(GL_ARRAY_BUFFER, sizeof(float) * 6, vertexData, GL_STATIC_DRAW);
     }
 
     if (mVAO == 0)
     {
         mFunctions->genVertexArrays(1, &mVAO);
 
         mStateManager->bindVertexArray(mVAO, 0);
-        mStateManager->bindBuffer(GL_ARRAY_BUFFER, mVertexBuffer);
+        mStateManager->bindBuffer(gl::BufferBinding::Array, mVertexBuffer);
 
         // Enable all attributes with the same buffer so that it doesn't matter what location the
         // texcoord attribute is assigned
         GLint maxAttributes = 0;
         mFunctions->getIntegerv(GL_MAX_VERTEX_ATTRIBS, &maxAttributes);
 
         for (GLint i = 0; i < maxAttributes; i++)
         {
@@ -673,16 +681,17 @@ gl::Error BlitGL::initializeResources()
 
 void BlitGL::orphanScratchTextures()
 {
     for (auto texture : mScratchTextures)
     {
         mStateManager->bindTexture(GL_TEXTURE_2D, texture);
         gl::PixelUnpackState unpack;
         mStateManager->setPixelUnpackState(unpack);
+        mStateManager->setPixelUnpackBuffer(nullptr);
         mFunctions->texImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 0, 0, 0, GL_RGBA, GL_UNSIGNED_BYTE,
                                nullptr);
     }
 }
 
 void BlitGL::setScratchTextureParameter(GLenum param, GLenum value)
 {
     for (auto texture : mScratchTextures)
--- a/gfx/angle/src/libANGLE/renderer/gl/BufferGL.cpp
+++ b/gfx/angle/src/libANGLE/renderer/gl/BufferGL.cpp
@@ -18,21 +18,21 @@
 
 namespace rx
 {
 
 // Use the GL_COPY_READ_BUFFER binding when two buffers need to be bound simultaneously.
 // GL_ELEMENT_ARRAY_BUFFER is supported on more versions but can modify the state of the currently
 // bound VAO.  Two simultaneous buffer bindings are only needed for glCopyBufferSubData which also
 // adds the GL_COPY_READ_BUFFER binding.
-static const GLenum SourceBufferOperationTarget = GL_COPY_READ_BUFFER;
+static constexpr gl::BufferBinding SourceBufferOperationTarget = gl::BufferBinding::CopyRead;
 
 // Use the GL_ELEMENT_ARRAY_BUFFER binding for most operations since it's available on all
 // supported GL versions and doesn't affect any current state when it changes.
-static const GLenum DestBufferOperationTarget = GL_ARRAY_BUFFER;
+static constexpr gl::BufferBinding DestBufferOperationTarget = gl::BufferBinding::Array;
 
 BufferGL::BufferGL(const gl::BufferState &state,
                    const FunctionsGL *functions,
                    StateManagerGL *stateManager)
     : BufferImpl(state),
       mIsMapped(false),
       mMapOffset(0),
       mMapSize(0),
@@ -51,23 +51,23 @@ BufferGL::BufferGL(const gl::BufferState
 
 BufferGL::~BufferGL()
 {
     mStateManager->deleteBuffer(mBufferID);
     mBufferID = 0;
 }
 
 gl::Error BufferGL::setData(const gl::Context * /*context*/,
-                            GLenum /*target*/,
+                            gl::BufferBinding /*target*/,
                             const void *data,
                             size_t size,
-                            GLenum usage)
+                            gl::BufferUsage usage)
 {
     mStateManager->bindBuffer(DestBufferOperationTarget, mBufferID);
-    mFunctions->bufferData(DestBufferOperationTarget, size, data, usage);
+    mFunctions->bufferData(gl::ToGLenum(DestBufferOperationTarget), size, data, ToGLenum(usage));
 
     if (mShadowBufferData)
     {
         if (!mShadowCopy.resize(size))
         {
             return gl::OutOfMemory() << "Failed to resize buffer data shadow copy.";
         }
 
@@ -78,23 +78,23 @@ gl::Error BufferGL::setData(const gl::Co
     }
 
     mBufferSize = size;
 
     return gl::NoError();
 }
 
 gl::Error BufferGL::setSubData(const gl::Context * /*context*/,
-                               GLenum /*target*/,
+                               gl::BufferBinding /*target*/,
                                const void *data,
                                size_t size,
                                size_t offset)
 {
     mStateManager->bindBuffer(DestBufferOperationTarget, mBufferID);
-    mFunctions->bufferSubData(DestBufferOperationTarget, offset, size, data);
+    mFunctions->bufferSubData(gl::ToGLenum(DestBufferOperationTarget), offset, size, data);
 
     if (mShadowBufferData && size > 0)
     {
         memcpy(mShadowCopy.data() + offset, data, size);
     }
 
     return gl::NoError();
 }
@@ -105,18 +105,19 @@ gl::Error BufferGL::copySubData(const gl
                                 GLintptr destOffset,
                                 GLsizeiptr size)
 {
     BufferGL *sourceGL = GetAs<BufferGL>(source);
 
     mStateManager->bindBuffer(DestBufferOperationTarget, mBufferID);
     mStateManager->bindBuffer(SourceBufferOperationTarget, sourceGL->getBufferID());
 
-    mFunctions->copyBufferSubData(SourceBufferOperationTarget, DestBufferOperationTarget,
-                                  sourceOffset, destOffset, size);
+    mFunctions->copyBufferSubData(gl::ToGLenum(SourceBufferOperationTarget),
+                                  gl::ToGLenum(DestBufferOperationTarget), sourceOffset, destOffset,
+                                  size);
 
     if (mShadowBufferData && size > 0)
     {
         ASSERT(sourceGL->mShadowBufferData);
         memcpy(mShadowCopy.data() + destOffset, sourceGL->mShadowCopy.data() + sourceOffset, size);
     }
 
     return gl::NoError();
@@ -126,24 +127,24 @@ gl::Error BufferGL::map(const gl::Contex
 {
     if (mShadowBufferData)
     {
         *mapPtr = mShadowCopy.data();
     }
     else if (mFunctions->mapBuffer)
     {
         mStateManager->bindBuffer(DestBufferOperationTarget, mBufferID);
-        *mapPtr = mFunctions->mapBuffer(DestBufferOperationTarget, access);
+        *mapPtr = mFunctions->mapBuffer(gl::ToGLenum(DestBufferOperationTarget), access);
     }
     else
     {
         ASSERT(mFunctions->mapBufferRange && access == GL_WRITE_ONLY_OES);
         mStateManager->bindBuffer(DestBufferOperationTarget, mBufferID);
-        *mapPtr =
-            mFunctions->mapBufferRange(DestBufferOperationTarget, 0, mBufferSize, GL_MAP_WRITE_BIT);
+        *mapPtr = mFunctions->mapBufferRange(gl::ToGLenum(DestBufferOperationTarget), 0,
+                                             mBufferSize, GL_MAP_WRITE_BIT);
     }
 
     mIsMapped  = true;
     mMapOffset = 0;
     mMapSize   = mBufferSize;
 
     return gl::NoError();
 }
@@ -156,17 +157,18 @@ gl::Error BufferGL::mapRange(const gl::C
 {
     if (mShadowBufferData)
     {
         *mapPtr = mShadowCopy.data() + offset;
     }
     else
     {
         mStateManager->bindBuffer(DestBufferOperationTarget, mBufferID);
-        *mapPtr = mFunctions->mapBufferRange(DestBufferOperationTarget, offset, length, access);
+        *mapPtr = mFunctions->mapBufferRange(gl::ToGLenum(DestBufferOperationTarget), offset,
+                                             length, access);
     }
 
     mIsMapped  = true;
     mMapOffset = offset;
     mMapSize   = length;
 
     return gl::NoError();
 }
@@ -174,24 +176,24 @@ gl::Error BufferGL::mapRange(const gl::C
 gl::Error BufferGL::unmap(const gl::Context *context, GLboolean *result)
 {
     ASSERT(result);
     ASSERT(mIsMapped);
 
     if (mShadowBufferData)
     {
         mStateManager->bindBuffer(DestBufferOperationTarget, mBufferID);
-        mFunctions->bufferSubData(DestBufferOperationTarget, mMapOffset, mMapSize,
+        mFunctions->bufferSubData(gl::ToGLenum(DestBufferOperationTarget), mMapOffset, mMapSize,
                                   mShadowCopy.data() + mMapOffset);
         *result = GL_TRUE;
     }
     else
     {
         mStateManager->bindBuffer(DestBufferOperationTarget, mBufferID);
-        *result = mFunctions->unmapBuffer(DestBufferOperationTarget);
+        *result = mFunctions->unmapBuffer(gl::ToGLenum(DestBufferOperationTarget));
     }
 
     mIsMapped = false;
     return gl::NoError();
 }
 
 gl::Error BufferGL::getIndexRange(const gl::Context *context,
                                   GLenum type,
@@ -207,20 +209,21 @@ gl::Error BufferGL::getIndexRange(const 
         *outRange = gl::ComputeIndexRange(type, mShadowCopy.data() + offset, count,
                                           primitiveRestartEnabled);
     }
     else
     {
         mStateManager->bindBuffer(DestBufferOperationTarget, mBufferID);
 
         const gl::Type &typeInfo  = gl::GetTypeInfo(type);
-        const uint8_t *bufferData = MapBufferRangeWithFallback(
-            mFunctions, DestBufferOperationTarget, offset, count * typeInfo.bytes, GL_MAP_READ_BIT);
+        const uint8_t *bufferData =
+            MapBufferRangeWithFallback(mFunctions, gl::ToGLenum(DestBufferOperationTarget), offset,
+                                       count * typeInfo.bytes, GL_MAP_READ_BIT);
         *outRange = gl::ComputeIndexRange(type, bufferData, count, primitiveRestartEnabled);
-        mFunctions->unmapBuffer(DestBufferOperationTarget);
+        mFunctions->unmapBuffer(gl::ToGLenum(DestBufferOperationTarget));
     }
 
     return gl::NoError();
 }
 
 GLuint BufferGL::getBufferID() const
 {
     return mBufferID;
--- a/gfx/angle/src/libANGLE/renderer/gl/BufferGL.h
+++ b/gfx/angle/src/libANGLE/renderer/gl/BufferGL.h
@@ -22,22 +22,22 @@ class BufferGL : public BufferImpl
 {
   public:
     BufferGL(const gl::BufferState &state,
              const FunctionsGL *functions,
              StateManagerGL *stateManager);
     ~BufferGL() override;
 
     gl::Error setData(const gl::Context *context,
-                      GLenum target,
+                      gl::BufferBinding target,
                       const void *data,
                       size_t size,
-                      GLenum usage) override;
+                      gl::BufferUsage usage) override;
     gl::Error setSubData(const gl::Context *context,
-                         GLenum target,
+                         gl::BufferBinding target,
                          const void *data,
                          size_t size,
                          size_t offset) override;
     gl::Error copySubData(const gl::Context *context,
                           BufferImpl *source,
                           GLintptr sourceOffset,
                           GLintptr destOffset,
                           GLsizeiptr size) override;
--- a/gfx/angle/src/libANGLE/renderer/gl/ClearMultiviewGL.cpp
+++ b/gfx/angle/src/libANGLE/renderer/gl/ClearMultiviewGL.cpp
@@ -35,17 +35,17 @@ void ClearMultiviewGL::clearMultiviewFBO
                                          ClearCommandType clearCommandType,
                                          GLbitfield mask,
                                          GLenum buffer,
                                          GLint drawbuffer,
                                          const uint8_t *values,
                                          GLfloat depth,
                                          GLint stencil)
 {
-    const auto &firstAttachment = state.getFirstNonNullAttachment();
+    const gl::FramebufferAttachment *firstAttachment = state.getFirstNonNullAttachment();
     switch (firstAttachment->getMultiviewLayout())
     {
         case GL_FRAMEBUFFER_MULTIVIEW_LAYERED_ANGLE:
             clearLayeredFBO(state, clearCommandType, mask, buffer, drawbuffer, values, depth,
                             stencil);
             break;
         case GL_FRAMEBUFFER_MULTIVIEW_SIDE_BY_SIDE_ANGLE:
             clearSideBySideFBO(state, scissorBase, clearCommandType, mask, buffer, drawbuffer,
@@ -64,17 +64,17 @@ void ClearMultiviewGL::clearLayeredFBO(c
                                        const uint8_t *values,
                                        GLfloat depth,
                                        GLint stencil)
 {
     initializeResources();
 
     mStateManager->bindFramebuffer(GL_DRAW_FRAMEBUFFER, mFramebuffer);
 
-    const auto &firstAttachment = state.getFirstNonNullAttachment();
+    const gl::FramebufferAttachment *firstAttachment = state.getFirstNonNullAttachment();
     ASSERT(firstAttachment->getMultiviewLayout() == GL_FRAMEBUFFER_MULTIVIEW_LAYERED_ANGLE);
 
     const auto &drawBuffers = state.getDrawBufferStates();
     mFunctions->drawBuffers(static_cast<GLsizei>(drawBuffers.size()), drawBuffers.data());
 
     // Attach the new attachments and clear.
     int numViews      = firstAttachment->getNumViews();
     int baseViewIndex = firstAttachment->getBaseViewIndex();
@@ -92,17 +92,17 @@ void ClearMultiviewGL::clearSideBySideFB
                                           ClearCommandType clearCommandType,
                                           GLbitfield mask,
                                           GLenum buffer,
                                           GLint drawbuffer,
                                           const uint8_t *values,
                                           GLfloat depth,
                                           GLint stencil)
 {
-    const auto &firstAttachment = state.getFirstNonNullAttachment();
+    const gl::FramebufferAttachment *firstAttachment = state.getFirstNonNullAttachment();
     ASSERT(firstAttachment->getMultiviewLayout() == GL_FRAMEBUFFER_MULTIVIEW_SIDE_BY_SIDE_ANGLE);
 
     const auto &viewportOffsets = firstAttachment->getMultiviewViewportOffsets();
     for (size_t i = 0u; i < viewportOffsets.size(); ++i)
     {
         gl::Rectangle scissor(scissorBase.x + viewportOffsets[i].x,
                               scissorBase.y + viewportOffsets[i].y, scissorBase.width,
                               scissorBase.height);
@@ -142,35 +142,35 @@ void ClearMultiviewGL::genericClear(Clea
             UNREACHABLE();
     }
 }
 
 void ClearMultiviewGL::attachTextures(const gl::FramebufferState &state, int layer)
 {
     for (auto drawBufferId : state.getEnabledDrawBuffers())
     {
-        const auto &attachment = state.getColorAttachment(drawBufferId);
+        const gl::FramebufferAttachment *attachment = state.getColorAttachment(drawBufferId);
         if (attachment == nullptr)
         {
             continue;
         }
 
         const auto &imageIndex = attachment->getTextureImageIndex();
         ASSERT(imageIndex.type == GL_TEXTURE_2D_ARRAY);
 
         GLenum colorAttachment =
             static_cast<GLenum>(GL_COLOR_ATTACHMENT0 + static_cast<int>(drawBufferId));
         const TextureGL *textureGL = GetImplAs<TextureGL>(attachment->getTexture());
         mFunctions->framebufferTextureLayer(GL_DRAW_FRAMEBUFFER, colorAttachment,
                                             textureGL->getTextureID(), imageIndex.mipIndex, layer);
     }
 
-    const auto &depthStencilAttachment = state.getDepthStencilAttachment();
-    const auto &depthAttachment        = state.getDepthAttachment();
-    const auto &stencilAttachment      = state.getStencilAttachment();
+    const gl::FramebufferAttachment *depthStencilAttachment = state.getDepthStencilAttachment();
+    const gl::FramebufferAttachment *depthAttachment        = state.getDepthAttachment();
+    const gl::FramebufferAttachment *stencilAttachment      = state.getStencilAttachment();
     if (depthStencilAttachment != nullptr)
     {
         const auto &imageIndex = depthStencilAttachment->getTextureImageIndex();
         ASSERT(imageIndex.type == GL_TEXTURE_2D_ARRAY);
 
         const TextureGL *textureGL = GetImplAs<TextureGL>(depthStencilAttachment->getTexture());
         mFunctions->framebufferTextureLayer(GL_DRAW_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT,
                                             textureGL->getTextureID(), imageIndex.mipIndex, layer);
@@ -194,30 +194,30 @@ void ClearMultiviewGL::attachTextures(co
                                             textureGL->getTextureID(), imageIndex.mipIndex, layer);
     }
 }
 
 void ClearMultiviewGL::detachTextures(const gl::FramebufferState &state)
 {
     for (auto drawBufferId : state.getEnabledDrawBuffers())
     {
-        const auto &attachment = state.getColorAttachment(drawBufferId);
+        const gl::FramebufferAttachment *attachment = state.getColorAttachment(drawBufferId);
         if (attachment == nullptr)
         {
             continue;
         }
 
         GLenum colorAttachment =
             static_cast<GLenum>(GL_COLOR_ATTACHMENT0 + static_cast<int>(drawBufferId));
         mFunctions->framebufferTextureLayer(GL_DRAW_FRAMEBUFFER, colorAttachment, 0, 0, 0);
     }
 
-    const auto &depthStencilAttachment = state.getDepthStencilAttachment();
-    const auto &depthAttachment        = state.getDepthAttachment();
-    const auto &stencilAttachment      = state.getStencilAttachment();
+    const gl::FramebufferAttachment *depthStencilAttachment = state.getDepthStencilAttachment();
+    const gl::FramebufferAttachment *depthAttachment        = state.getDepthAttachment();
+    const gl::FramebufferAttachment *stencilAttachment      = state.getStencilAttachment();
     if (depthStencilAttachment != nullptr)
     {
         mFunctions->framebufferTextureLayer(GL_DRAW_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, 0, 0,
                                             0);
     }
     else if (depthAttachment != nullptr)
     {
         mFunctions->framebufferTextureLayer(GL_DRAW_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, 0, 0, 0);
--- a/gfx/angle/src/libANGLE/renderer/gl/CompilerGL.cpp
+++ b/gfx/angle/src/libANGLE/renderer/gl/CompilerGL.cpp
@@ -83,9 +83,19 @@ ShShaderOutput GetShaderOutputType(const
 
 }  // anonymous namespace
 
 CompilerGL::CompilerGL(const FunctionsGL *functions)
     : mTranslatorOutputType(GetShaderOutputType(functions))
 {
 }
 
+gl::Error CompilerGL::release()
+{
+    return gl::NoError();
+}
+
+ShShaderOutput CompilerGL::getTranslatorOutputType() const
+{
+    return mTranslatorOutputType;
+}
+
 }  // namespace rx
--- a/gfx/angle/src/libANGLE/renderer/gl/CompilerGL.h
+++ b/gfx/angle/src/libANGLE/renderer/gl/CompilerGL.h
@@ -16,18 +16,18 @@ namespace rx
 class FunctionsGL;
 
 class CompilerGL : public CompilerImpl
 {
   public:
     CompilerGL(const FunctionsGL *functions);
     ~CompilerGL() override {}
 
-    gl::Error release() override { return gl::NoError(); }
-    ShShaderOutput getTranslatorOutputType() const override { return mTranslatorOutputType; }
+    gl::Error release() override;
+    ShShaderOutput getTranslatorOutputType() const override;
 
   private:
     ShShaderOutput mTranslatorOutputType;
 };
 
 }
 
 #endif // LIBANGLE_RENDERER_GL_COMPILERGL_H_
--- a/gfx/angle/src/libANGLE/renderer/gl/ContextGL.cpp
+++ b/gfx/angle/src/libANGLE/renderer/gl/ContextGL.cpp
@@ -143,22 +143,22 @@ std::vector<PathImpl *> ContextGL::creat
     {
         const auto id = first + i;
         ret.push_back(new PathGL(funcs, id));
     }
 
     return ret;
 }
 
-gl::Error ContextGL::flush()
+gl::Error ContextGL::flush(const gl::Context *context)
 {
     return mRenderer->flush();
 }
 
-gl::Error ContextGL::finish()
+gl::Error ContextGL::finish(const gl::Context *context)
 {
     return mRenderer->finish();
 }
 
 gl::Error ContextGL::drawArrays(const gl::Context *context, GLenum mode, GLint first, GLsizei count)
 {
     return mRenderer->drawArrays(context, mode, first, count);
 }
@@ -336,16 +336,26 @@ void ContextGL::pushGroupMarker(GLsizei 
     mRenderer->pushGroupMarker(length, marker);
 }
 
 void ContextGL::popGroupMarker()
 {
     mRenderer->popGroupMarker();
 }
 
+void ContextGL::pushDebugGroup(GLenum source, GLuint id, GLsizei length, const char *message)
+{
+    mRenderer->pushDebugGroup(source, id, length, message);
+}
+
+void ContextGL::popDebugGroup()
+{
+    mRenderer->popDebugGroup();
+}
+
 void ContextGL::syncState(const gl::Context *context, const gl::State::DirtyBits &dirtyBits)
 {
     mRenderer->getStateManager()->syncState(context, dirtyBits);
 }
 
 GLint ContextGL::getGPUDisjoint()
 {
     return mRenderer->getGPUDisjoint();
@@ -405,9 +415,23 @@ const WorkaroundsGL &ContextGL::getWorka
 gl::Error ContextGL::dispatchCompute(const gl::Context *context,
                                      GLuint numGroupsX,
                                      GLuint numGroupsY,
                                      GLuint numGroupsZ)
 {
     return mRenderer->dispatchCompute(context, numGroupsX, numGroupsY, numGroupsZ);
 }
 
+gl::Error ContextGL::dispatchComputeIndirect(const gl::Context *context, GLintptr indirect)
+{
+    return mRenderer->dispatchComputeIndirect(context, indirect);
+}
+
+gl::Error ContextGL::memoryBarrier(const gl::Context *context, GLbitfield barriers)
+{
+    return mRenderer->memoryBarrier(barriers);
+}
+gl::Error ContextGL::memoryBarrierByRegion(const gl::Context *context, GLbitfield barriers)
+{
+    return mRenderer->memoryBarrierByRegion(barriers);
+}
+
 }  // namespace rx
--- a/gfx/angle/src/libANGLE/renderer/gl/ContextGL.h
+++ b/gfx/angle/src/libANGLE/renderer/gl/ContextGL.h
@@ -66,18 +66,18 @@ class ContextGL : public ContextImpl
 
     // Program Pipeline object creation
     ProgramPipelineImpl *createProgramPipeline(const gl::ProgramPipelineState &data) override;
 
     // Path object creation
     std::vector<PathImpl *> createPaths(GLsizei range) override;
 
     // Flush and finish.
-    gl::Error flush() override;
-    gl::Error finish() override;
+    gl::Error flush(const gl::Context *context) override;
+    gl::Error finish(const gl::Context *context) override;
 
     // Drawing methods.
     gl::Error drawArrays(const gl::Context *context,
                          GLenum mode,
                          GLint first,
                          GLsizei count) override;
     gl::Error drawArraysInstanced(const gl::Context *context,
                                   GLenum mode,
@@ -157,21 +157,25 @@ class ContextGL : public ContextImpl
 
     // Device loss
     GLenum getResetStatus() override;
 
     // Vendor and description strings.
     std::string getVendorString() const override;
     std::string getRendererDescription() const override;
 
-    // Debug markers.
+    // EXT_debug_marker
     void insertEventMarker(GLsizei length, const char *marker) override;
     void pushGroupMarker(GLsizei length, const char *marker) override;
     void popGroupMarker() override;
 
+    // KHR_debug
+    void pushDebugGroup(GLenum source, GLuint id, GLsizei length, const char *message) override;
+    void popDebugGroup() override;
+
     // State sync with dirty bits.
     void syncState(const gl::Context *context, const gl::State::DirtyBits &dirtyBits) override;
 
     // Disjoint timer queries
     GLint getGPUDisjoint() override;
     GLint64 getTimestamp() override;
 
     // Context switching
@@ -189,16 +193,20 @@ class ContextGL : public ContextImpl
     const FunctionsGL *getFunctions() const;
     StateManagerGL *getStateManager();
     const WorkaroundsGL &getWorkaroundsGL() const;
 
     gl::Error dispatchCompute(const gl::Context *context,
                               GLuint numGroupsX,
                               GLuint numGroupsY,
                               GLuint numGroupsZ) override;
+    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;
 
   private:
     RendererGL *mRenderer;
 };
 
 }  // namespace rx
 
 #endif  // LIBANGLE_RENDERER_GL_CONTEXTGL_H_
new file mode 100644
--- /dev/null
+++ b/gfx/angle/src/libANGLE/renderer/gl/DispatchTableGL_autogen.cpp
@@ -0,0 +1,5459 @@
+// GENERATED FILE - DO NOT EDIT.
+// Generated by generate_gl_dispatch_table.py using data from gl_bindings_data.json and gl.xml.
+//
+// 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.
+//
+// DispatchTableGL_autogen.cpp:
+//   Initialize the native bindings for ANGLE's OpenGL back-end.
+
+#include "libANGLE/renderer/gl/DispatchTableGL_autogen.h"
+
+#include "libANGLE/Version.h"
+#include "libANGLE/renderer/gl/FunctionsGL.h"
+
+#if defined(ANGLE_ENABLE_OPENGL_NULL)
+#include "libANGLE/renderer/gl/null_functions.h"
+#endif  // defined(ANGLE_ENABLE_OPENGL_NULL)
+
+// Check for nullptr so extensions do not overwrite core imports.
+#define ASSIGN(NAME, FP) \
+    if (!FP)             \
+    *reinterpret_cast<void **>(&FP) = loadProcAddress(NAME)
+
+namespace rx
+{
+
+void DispatchTableGL::initProcsDesktopGL(const gl::Version &version,
+                                         const std::set<std::string> &extensions)
+{
+    if (version >= gl::Version(1, 0))
+    {
+        ASSIGN("glBlendFunc", blendFunc);
+        ASSIGN("glClear", clear);
+        ASSIGN("glClearColor", clearColor);
+        ASSIGN("glClearDepth", clearDepth);
+        ASSIGN("glClearStencil", clearStencil);
+        ASSIGN("glColorMask", colorMask);
+        ASSIGN("glCullFace", cullFace);
+        ASSIGN("glDepthFunc", depthFunc);
+        ASSIGN("glDepthMask", depthMask);
+        ASSIGN("glDepthRange", depthRange);
+        ASSIGN("glDisable", disable);
+        ASSIGN("glDrawBuffer", drawBuffer);
+        ASSIGN("glEnable", enable);
+        ASSIGN("glFinish", finish);
+        ASSIGN("glFlush", flush);
+        ASSIGN("glFrontFace", frontFace);
+        ASSIGN("glGetBooleanv", getBooleanv);
+        ASSIGN("glGetDoublev", getDoublev);
+        ASSIGN("glGetError", getError);
+        ASSIGN("glGetFloatv", getFloatv);
+        ASSIGN("glGetIntegerv", getIntegerv);
+        ASSIGN("glGetString", getString);
+        ASSIGN("glGetTexImage", getTexImage);
+        ASSIGN("glGetTexLevelParameterfv", getTexLevelParameterfv);
+        ASSIGN("glGetTexLevelParameteriv", getTexLevelParameteriv);
+        ASSIGN("glGetTexParameterfv", getTexParameterfv);
+        ASSIGN("glGetTexParameteriv", getTexParameteriv);
+        ASSIGN("glHint", hint);
+        ASSIGN("glIsEnabled", isEnabled);
+        ASSIGN("glLineWidth", lineWidth);
+        ASSIGN("glLogicOp", logicOp);
+        ASSIGN("glPixelStoref", pixelStoref);
+        ASSIGN("glPixelStorei", pixelStorei);
+        ASSIGN("glPointSize", pointSize);
+        ASSIGN("glPolygonMode", polygonMode);
+        ASSIGN("glReadBuffer", readBuffer);
+        ASSIGN("glReadPixels", readPixels);
+        ASSIGN("glScissor", scissor);
+        ASSIGN("glStencilFunc", stencilFunc);
+        ASSIGN("glStencilMask", stencilMask);
+        ASSIGN("glStencilOp", stencilOp);
+        ASSIGN("glTexImage1D", texImage1D);
+        ASSIGN("glTexImage2D", texImage2D);
+        ASSIGN("glTexParameterf", texParameterf);
+        ASSIGN("glTexParameterfv", texParameterfv);
+        ASSIGN("glTexParameteri", texParameteri);
+        ASSIGN("glTexParameteriv", texParameteriv);
+        ASSIGN("glViewport", viewport);
+    }
+
+    if (version >= gl::Version(1, 1))
+    {
+        ASSIGN("glBindTexture", bindTexture);
+        ASSIGN("glCopyTexImage1D", copyTexImage1D);
+        ASSIGN("glCopyTexImage2D", copyTexImage2D);
+        ASSIGN("glCopyTexSubImage1D", copyTexSubImage1D);
+        ASSIGN("glCopyTexSubImage2D", copyTexSubImage2D);
+        ASSIGN("glDeleteTextures", deleteTextures);
+        ASSIGN("glDrawArrays", drawArrays);
+        ASSIGN("glDrawElements", drawElements);
+        ASSIGN("glGenTextures", genTextures);
+        ASSIGN("glIsTexture", isTexture);
+        ASSIGN("glPolygonOffset", polygonOffset);
+        ASSIGN("glTexSubImage1D", texSubImage1D);
+        ASSIGN("glTexSubImage2D", texSubImage2D);
+    }
+
+    if (version >= gl::Version(1, 2))
+    {
+        ASSIGN("glCopyTexSubImage3D", copyTexSubImage3D);
+        ASSIGN("glDrawRangeElements", drawRangeElements);
+        ASSIGN("glTexImage3D", texImage3D);
+        ASSIGN("glTexSubImage3D", texSubImage3D);
+    }
+
+    if (version >= gl::Version(1, 3))
+    {
+        ASSIGN("glActiveTexture", activeTexture);
+        ASSIGN("glCompressedTexImage1D", compressedTexImage1D);
+        ASSIGN("glCompressedTexImage2D", compressedTexImage2D);
+        ASSIGN("glCompressedTexImage3D", compressedTexImage3D);
+        ASSIGN("glCompressedTexSubImage1D", compressedTexSubImage1D);
+        ASSIGN("glCompressedTexSubImage2D", compressedTexSubImage2D);
+        ASSIGN("glCompressedTexSubImage3D", compressedTexSubImage3D);
+        ASSIGN("glGetCompressedTexImage", getCompressedTexImage);
+        ASSIGN("glSampleCoverage", sampleCoverage);
+    }
+
+    if (version >= gl::Version(1, 4))
+    {
+        ASSIGN("glBlendColor", blendColor);
+        ASSIGN("glBlendEquation", blendEquation);
+        ASSIGN("glBlendFuncSeparate", blendFuncSeparate);
+        ASSIGN("glMultiDrawArrays", multiDrawArrays);
+        ASSIGN("glMultiDrawElements", multiDrawElements);
+        ASSIGN("glPointParameterf", pointParameterf);
+        ASSIGN("glPointParameterfv", pointParameterfv);
+        ASSIGN("glPointParameteri", pointParameteri);
+        ASSIGN("glPointParameteriv", pointParameteriv);
+    }
+
+    if (version >= gl::Version(1, 5))
+    {
+        ASSIGN("glBeginQuery", beginQuery);
+        ASSIGN("glBindBuffer", bindBuffer);
+        ASSIGN("glBufferData", bufferData);
+        ASSIGN("glBufferSubData", bufferSubData);
+        ASSIGN("glDeleteBuffers", deleteBuffers);
+        ASSIGN("glDeleteQueries", deleteQueries);
+        ASSIGN("glEndQuery", endQuery);
+        ASSIGN("glGenBuffers", genBuffers);
+        ASSIGN("glGenQueries", genQueries);
+        ASSIGN("glGetBufferParameteriv", getBufferParameteriv);
+        ASSIGN("glGetBufferPointerv", getBufferPointerv);
+        ASSIGN("glGetBufferSubData", getBufferSubData);
+        ASSIGN("glGetQueryObjectiv", getQueryObjectiv);
+        ASSIGN("glGetQueryObjectuiv", getQueryObjectuiv);
+        ASSIGN("glGetQueryiv", getQueryiv);
+        ASSIGN("glIsBuffer", isBuffer);
+        ASSIGN("glIsQuery", isQuery);
+        ASSIGN("glMapBuffer", mapBuffer);
+        ASSIGN("glUnmapBuffer", unmapBuffer);
+    }
+
+    if (version >= gl::Version(2, 0))
+    {
+        ASSIGN("glAttachShader", attachShader);
+        ASSIGN("glBindAttribLocation", bindAttribLocation);
+        ASSIGN("glBlendEquationSeparate", blendEquationSeparate);
+        ASSIGN("glCompileShader", compileShader);
+        ASSIGN("glCreateProgram", createProgram);
+        ASSIGN("glCreateShader", createShader);
+        ASSIGN("glDeleteProgram", deleteProgram);
+        ASSIGN("glDeleteShader", deleteShader);
+        ASSIGN("glDetachShader", detachShader);
+        ASSIGN("glDisableVertexAttribArray", disableVertexAttribArray);
+        ASSIGN("glDrawBuffers", drawBuffers);
+        ASSIGN("glEnableVertexAttribArray", enableVertexAttribArray);
+        ASSIGN("glGetActiveAttrib", getActiveAttrib);
+        ASSIGN("glGetActiveUniform", getActiveUniform);
+        ASSIGN("glGetAttachedShaders", getAttachedShaders);
+        ASSIGN("glGetAttribLocation", getAttribLocation);
+        ASSIGN("glGetProgramInfoLog", getProgramInfoLog);
+        ASSIGN("glGetProgramiv", getProgramiv);
+        ASSIGN("glGetShaderInfoLog", getShaderInfoLog);
+        ASSIGN("glGetShaderSource", getShaderSource);
+        ASSIGN("glGetShaderiv", getShaderiv);
+        ASSIGN("glGetUniformLocation", getUniformLocation);
+        ASSIGN("glGetUniformfv", getUniformfv);
+        ASSIGN("glGetUniformiv", getUniformiv);
+        ASSIGN("glGetVertexAttribPointerv", getVertexAttribPointerv);
+        ASSIGN("glGetVertexAttribdv", getVertexAttribdv);
+        ASSIGN("glGetVertexAttribfv", getVertexAttribfv);
+        ASSIGN("glGetVertexAttribiv", getVertexAttribiv);
+        ASSIGN("glIsProgram", isProgram);
+        ASSIGN("glIsShader", isShader);
+        ASSIGN("glLinkProgram", linkProgram);
+        ASSIGN("glShaderSource", shaderSource);
+        ASSIGN("glStencilFuncSeparate", stencilFuncSeparate);
+        ASSIGN("glStencilMaskSeparate", stencilMaskSeparate);
+        ASSIGN("glStencilOpSeparate", stencilOpSeparate);
+        ASSIGN("glUniform1f", uniform1f);
+        ASSIGN("glUniform1fv", uniform1fv);
+        ASSIGN("glUniform1i", uniform1i);
+        ASSIGN("glUniform1iv", uniform1iv);
+        ASSIGN("glUniform2f", uniform2f);
+        ASSIGN("glUniform2fv", uniform2fv);
+        ASSIGN("glUniform2i", uniform2i);
+        ASSIGN("glUniform2iv", uniform2iv);
+        ASSIGN("glUniform3f", uniform3f);
+        ASSIGN("glUniform3fv", uniform3fv);
+        ASSIGN("glUniform3i", uniform3i);
+        ASSIGN("glUniform3iv", uniform3iv);
+        ASSIGN("glUniform4f", uniform4f);
+        ASSIGN("glUniform4fv", uniform4fv);
+        ASSIGN("glUniform4i", uniform4i);
+        ASSIGN("glUniform4iv", uniform4iv);
+        ASSIGN("glUniformMatrix2fv", uniformMatrix2fv);
+        ASSIGN("glUniformMatrix3fv", uniformMatrix3fv);
+        ASSIGN("glUniformMatrix4fv", uniformMatrix4fv);
+        ASSIGN("glUseProgram", useProgram);
+        ASSIGN("glValidateProgram", validateProgram);
+        ASSIGN("glVertexAttrib1d", vertexAttrib1d);
+        ASSIGN("glVertexAttrib1dv", vertexAttrib1dv);
+        ASSIGN("glVertexAttrib1f", vertexAttrib1f);
+        ASSIGN("glVertexAttrib1fv", vertexAttrib1fv);
+        ASSIGN("glVertexAttrib1s", vertexAttrib1s);
+        ASSIGN("glVertexAttrib1sv", vertexAttrib1sv);
+        ASSIGN("glVertexAttrib2d", vertexAttrib2d);
+        ASSIGN("glVertexAttrib2dv", vertexAttrib2dv);
+        ASSIGN("glVertexAttrib2f", vertexAttrib2f);
+        ASSIGN("glVertexAttrib2fv", vertexAttrib2fv);
+        ASSIGN("glVertexAttrib2s", vertexAttrib2s);
+        ASSIGN("glVertexAttrib2sv", vertexAttrib2sv);
+        ASSIGN("glVertexAttrib3d", vertexAttrib3d);
+        ASSIGN("glVertexAttrib3dv", vertexAttrib3dv);
+        ASSIGN("glVertexAttrib3f", vertexAttrib3f);
+        ASSIGN("glVertexAttrib3fv", vertexAttrib3fv);
+        ASSIGN("glVertexAttrib3s", vertexAttrib3s);
+        ASSIGN("glVertexAttrib3sv", vertexAttrib3sv);
+        ASSIGN("glVertexAttrib4Nbv", vertexAttrib4Nbv);
+        ASSIGN("glVertexAttrib4Niv", vertexAttrib4Niv);
+        ASSIGN("glVertexAttrib4Nsv", vertexAttrib4Nsv);
+        ASSIGN("glVertexAttrib4Nub", vertexAttrib4Nub);
+        ASSIGN("glVertexAttrib4Nubv", vertexAttrib4Nubv);
+        ASSIGN("glVertexAttrib4Nuiv", vertexAttrib4Nuiv);
+        ASSIGN("glVertexAttrib4Nusv", vertexAttrib4Nusv);
+        ASSIGN("glVertexAttrib4bv", vertexAttrib4bv);
+        ASSIGN("glVertexAttrib4d", vertexAttrib4d);
+        ASSIGN("glVertexAttrib4dv", vertexAttrib4dv);
+        ASSIGN("glVertexAttrib4f", vertexAttrib4f);
+        ASSIGN("glVertexAttrib4fv", vertexAttrib4fv);
+        ASSIGN("glVertexAttrib4iv", vertexAttrib4iv);
+        ASSIGN("glVertexAttrib4s", vertexAttrib4s);
+        ASSIGN("glVertexAttrib4sv", vertexAttrib4sv);
+        ASSIGN("glVertexAttrib4ubv", vertexAttrib4ubv);
+        ASSIGN("glVertexAttrib4uiv", vertexAttrib4uiv);
+        ASSIGN("glVertexAttrib4usv", vertexAttrib4usv);
+        ASSIGN("glVertexAttribPointer", vertexAttribPointer);
+    }
+
+    if (version >= gl::Version(2, 1))
+    {
+        ASSIGN("glUniformMatrix2x3fv", uniformMatrix2x3fv);
+        ASSIGN("glUniformMatrix2x4fv", uniformMatrix2x4fv);
+        ASSIGN("glUniformMatrix3x2fv", uniformMatrix3x2fv);
+        ASSIGN("glUniformMatrix3x4fv", uniformMatrix3x4fv);
+        ASSIGN("glUniformMatrix4x2fv", uniformMatrix4x2fv);
+        ASSIGN("glUniformMatrix4x3fv", uniformMatrix4x3fv);
+    }
+
+    if (version >= gl::Version(3, 0))
+    {
+        ASSIGN("glBeginConditionalRender", beginConditionalRender);
+        ASSIGN("glBeginTransformFeedback", beginTransformFeedback);
+        ASSIGN("glBindBufferBase", bindBufferBase);
+        ASSIGN("glBindBufferRange", bindBufferRange);
+        ASSIGN("glBindFragDataLocation", bindFragDataLocation);
+        ASSIGN("glBindFramebuffer", bindFramebuffer);
+        ASSIGN("glBindRenderbuffer", bindRenderbuffer);
+        ASSIGN("glBindVertexArray", bindVertexArray);
+        ASSIGN("glBlitFramebuffer", blitFramebuffer);
+        ASSIGN("glCheckFramebufferStatus", checkFramebufferStatus);
+        ASSIGN("glClampColor", clampColor);
+        ASSIGN("glClearBufferfi", clearBufferfi);
+        ASSIGN("glClearBufferfv", clearBufferfv);
+        ASSIGN("glClearBufferiv", clearBufferiv);
+        ASSIGN("glClearBufferuiv", clearBufferuiv);
+        ASSIGN("glColorMaski", colorMaski);
+        ASSIGN("glDeleteFramebuffers", deleteFramebuffers);
+        ASSIGN("glDeleteRenderbuffers", deleteRenderbuffers);
+        ASSIGN("glDeleteVertexArrays", deleteVertexArrays);
+        ASSIGN("glDisablei", disablei);
+        ASSIGN("glEnablei", enablei);
+        ASSIGN("glEndConditionalRender", endConditionalRender);
+        ASSIGN("glEndTransformFeedback", endTransformFeedback);
+        ASSIGN("glFlushMappedBufferRange", flushMappedBufferRange);
+        ASSIGN("glFramebufferRenderbuffer", framebufferRenderbuffer);
+        ASSIGN("glFramebufferTexture1D", framebufferTexture1D);
+        ASSIGN("glFramebufferTexture2D", framebufferTexture2D);
+        ASSIGN("glFramebufferTexture3D", framebufferTexture3D);
+        ASSIGN("glFramebufferTextureLayer", framebufferTextureLayer);
+        ASSIGN("glGenFramebuffers", genFramebuffers);
+        ASSIGN("glGenRenderbuffers", genRenderbuffers);
+        ASSIGN("glGenVertexArrays", genVertexArrays);
+        ASSIGN("glGenerateMipmap", generateMipmap);
+        ASSIGN("glGetBooleani_v", getBooleani_v);
+        ASSIGN("glGetFragDataLocation", getFragDataLocation);
+        ASSIGN("glGetFramebufferAttachmentParameteriv", getFramebufferAttachmentParameteriv);
+        ASSIGN("glGetIntegeri_v", getIntegeri_v);
+        ASSIGN("glGetRenderbufferParameteriv", getRenderbufferParameteriv);
+        ASSIGN("glGetStringi", getStringi);
+        ASSIGN("glGetTexParameterIiv", getTexParameterIiv);
+        ASSIGN("glGetTexParameterIuiv", getTexParameterIuiv);
+        ASSIGN("glGetTransformFeedbackVarying", getTransformFeedbackVarying);
+        ASSIGN("glGetUniformuiv", getUniformuiv);
+        ASSIGN("glGetVertexAttribIiv", getVertexAttribIiv);
+        ASSIGN("glGetVertexAttribIuiv", getVertexAttribIuiv);
+        ASSIGN("glIsEnabledi", isEnabledi);
+        ASSIGN("glIsFramebuffer", isFramebuffer);
+        ASSIGN("glIsRenderbuffer", isRenderbuffer);
+        ASSIGN("glIsVertexArray", isVertexArray);
+        ASSIGN("glMapBufferRange", mapBufferRange);
+        ASSIGN("glRenderbufferStorage", renderbufferStorage);
+        ASSIGN("glRenderbufferStorageMultisample", renderbufferStorageMultisample);
+        ASSIGN("glTexParameterIiv", texParameterIiv);
+        ASSIGN("glTexParameterIuiv", texParameterIuiv);
+        ASSIGN("glTransformFeedbackVaryings", transformFeedbackVaryings);
+        ASSIGN("glUniform1ui", uniform1ui);
+        ASSIGN("glUniform1uiv", uniform1uiv);
+        ASSIGN("glUniform2ui", uniform2ui);
+        ASSIGN("glUniform2uiv", uniform2uiv);
+        ASSIGN("glUniform3ui", uniform3ui);
+        ASSIGN("glUniform3uiv", uniform3uiv);
+        ASSIGN("glUniform4ui", uniform4ui);
+        ASSIGN("glUniform4uiv", uniform4uiv);
+        ASSIGN("glVertexAttribI1i", vertexAttribI1i);
+        ASSIGN("glVertexAttribI1iv", vertexAttribI1iv);
+        ASSIGN("glVertexAttribI1ui", vertexAttribI1ui);
+        ASSIGN("glVertexAttribI1uiv", vertexAttribI1uiv);
+        ASSIGN("glVertexAttribI2i", vertexAttribI2i);
+        ASSIGN("glVertexAttribI2iv", vertexAttribI2iv);
+        ASSIGN("glVertexAttribI2ui", vertexAttribI2ui);
+        ASSIGN("glVertexAttribI2uiv", vertexAttribI2uiv);
+        ASSIGN("glVertexAttribI3i", vertexAttribI3i);
+        ASSIGN("glVertexAttribI3iv", vertexAttribI3iv);
+        ASSIGN("glVertexAttribI3ui", vertexAttribI3ui);
+        ASSIGN("glVertexAttribI3uiv", vertexAttribI3uiv);
+        ASSIGN("glVertexAttribI4bv", vertexAttribI4bv);
+        ASSIGN("glVertexAttribI4i", vertexAttribI4i);
+        ASSIGN("glVertexAttribI4iv", vertexAttribI4iv);
+        ASSIGN("glVertexAttribI4sv", vertexAttribI4sv);
+        ASSIGN("glVertexAttribI4ubv", vertexAttribI4ubv);
+        ASSIGN("glVertexAttribI4ui", vertexAttribI4ui);
+        ASSIGN("glVertexAttribI4uiv", vertexAttribI4uiv);
+        ASSIGN("glVertexAttribI4usv", vertexAttribI4usv);
+        ASSIGN("glVertexAttribIPointer", vertexAttribIPointer);
+    }
+
+    if (version >= gl::Version(3, 1))
+    {
+        ASSIGN("glCopyBufferSubData", copyBufferSubData);
+        ASSIGN("glDrawArraysInstanced", drawArraysInstanced);
+        ASSIGN("glDrawElementsInstanced", drawElementsInstanced);
+        ASSIGN("glGetActiveUniformBlockName", getActiveUniformBlockName);
+        ASSIGN("glGetActiveUniformBlockiv", getActiveUniformBlockiv);
+        ASSIGN("glGetActiveUniformName", getActiveUniformName);
+        ASSIGN("glGetActiveUniformsiv", getActiveUniformsiv);
+        ASSIGN("glGetUniformBlockIndex", getUniformBlockIndex);
+        ASSIGN("glGetUniformIndices", getUniformIndices);
+        ASSIGN("glPrimitiveRestartIndex", primitiveRestartIndex);
+        ASSIGN("glTexBuffer", texBuffer);
+        ASSIGN("glUniformBlockBinding", uniformBlockBinding);
+    }
+
+    if (version >= gl::Version(3, 2))
+    {
+        ASSIGN("glClientWaitSync", clientWaitSync);
+        ASSIGN("glDeleteSync", deleteSync);
+        ASSIGN("glDrawElementsBaseVertex", drawElementsBaseVertex);
+        ASSIGN("glDrawElementsInstancedBaseVertex", drawElementsInstancedBaseVertex);
+        ASSIGN("glDrawRangeElementsBaseVertex", drawRangeElementsBaseVertex);
+        ASSIGN("glFenceSync", fenceSync);
+        ASSIGN("glFramebufferTexture", framebufferTexture);
+        ASSIGN("glGetBufferParameteri64v", getBufferParameteri64v);
+        ASSIGN("glGetInteger64i_v", getInteger64i_v);
+        ASSIGN("glGetInteger64v", getInteger64v);
+        ASSIGN("glGetMultisamplefv", getMultisamplefv);
+        ASSIGN("glGetSynciv", getSynciv);
+        ASSIGN("glIsSync", isSync);
+        ASSIGN("glMultiDrawElementsBaseVertex", multiDrawElementsBaseVertex);
+        ASSIGN("glProvokingVertex", provokingVertex);
+        ASSIGN("glSampleMaski", sampleMaski);
+        ASSIGN("glTexImage2DMultisample", texImage2DMultisample);
+        ASSIGN("glTexImage3DMultisample", texImage3DMultisample);
+        ASSIGN("glWaitSync", waitSync);
+    }
+
+    if (version >= gl::Version(3, 3))
+    {
+        ASSIGN("glBindFragDataLocationIndexed", bindFragDataLocationIndexed);
+        ASSIGN("glBindSampler", bindSampler);
+        ASSIGN("glDeleteSamplers", deleteSamplers);
+        ASSIGN("glGenSamplers", genSamplers);
+        ASSIGN("glGetFragDataIndex", getFragDataIndex);
+        ASSIGN("glGetQueryObjecti64v", getQueryObjecti64v);
+        ASSIGN("glGetQueryObjectui64v", getQueryObjectui64v);
+        ASSIGN("glGetSamplerParameterIiv", getSamplerParameterIiv);
+        ASSIGN("glGetSamplerParameterIuiv", getSamplerParameterIuiv);
+        ASSIGN("glGetSamplerParameterfv", getSamplerParameterfv);
+        ASSIGN("glGetSamplerParameteriv", getSamplerParameteriv);
+        ASSIGN("glIsSampler", isSampler);
+        ASSIGN("glQueryCounter", queryCounter);
+        ASSIGN("glSamplerParameterIiv", samplerParameterIiv);
+        ASSIGN("glSamplerParameterIuiv", samplerParameterIuiv);
+        ASSIGN("glSamplerParameterf", samplerParameterf);
+        ASSIGN("glSamplerParameterfv", samplerParameterfv);
+        ASSIGN("glSamplerParameteri", samplerParameteri);
+        ASSIGN("glSamplerParameteriv", samplerParameteriv);
+        ASSIGN("glVertexAttribDivisor", vertexAttribDivisor);
+        ASSIGN("glVertexAttribP1ui", vertexAttribP1ui);
+        ASSIGN("glVertexAttribP1uiv", vertexAttribP1uiv);
+        ASSIGN("glVertexAttribP2ui", vertexAttribP2ui);
+        ASSIGN("glVertexAttribP2uiv", vertexAttribP2uiv);
+        ASSIGN("glVertexAttribP3ui", vertexAttribP3ui);
+        ASSIGN("glVertexAttribP3uiv", vertexAttribP3uiv);
+        ASSIGN("glVertexAttribP4ui", vertexAttribP4ui);
+        ASSIGN("glVertexAttribP4uiv", vertexAttribP4uiv);
+    }
+
+    if (version >= gl::Version(4, 0))
+    {
+        ASSIGN("glBeginQueryIndexed", beginQueryIndexed);
+        ASSIGN("glBindTransformFeedback", bindTransformFeedback);
+        ASSIGN("glBlendEquationSeparatei", blendEquationSeparatei);
+        ASSIGN("glBlendEquationi", blendEquationi);
+        ASSIGN("glBlendFuncSeparatei", blendFuncSeparatei);
+        ASSIGN("glBlendFunci", blendFunci);
+        ASSIGN("glDeleteTransformFeedbacks", deleteTransformFeedbacks);
+        ASSIGN("glDrawArraysIndirect", drawArraysIndirect);
+        ASSIGN("glDrawElementsIndirect", drawElementsIndirect);
+        ASSIGN("glDrawTransformFeedback", drawTransformFeedback);
+        ASSIGN("glDrawTransformFeedbackStream", drawTransformFeedbackStream);
+        ASSIGN("glEndQueryIndexed", endQueryIndexed);
+        ASSIGN("glGenTransformFeedbacks", genTransformFeedbacks);
+        ASSIGN("glGetActiveSubroutineName", getActiveSubroutineName);
+        ASSIGN("glGetActiveSubroutineUniformName", getActiveSubroutineUniformName);
+        ASSIGN("glGetActiveSubroutineUniformiv", getActiveSubroutineUniformiv);
+        ASSIGN("glGetProgramStageiv", getProgramStageiv);
+        ASSIGN("glGetQueryIndexediv", getQueryIndexediv);
+        ASSIGN("glGetSubroutineIndex", getSubroutineIndex);
+        ASSIGN("glGetSubroutineUniformLocation", getSubroutineUniformLocation);
+        ASSIGN("glGetUniformSubroutineuiv", getUniformSubroutineuiv);
+        ASSIGN("glGetUniformdv", getUniformdv);
+        ASSIGN("glIsTransformFeedback", isTransformFeedback);
+        ASSIGN("glMinSampleShading", minSampleShading);
+        ASSIGN("glPatchParameterfv", patchParameterfv);
+        ASSIGN("glPatchParameteri", patchParameteri);
+        ASSIGN("glPauseTransformFeedback", pauseTransformFeedback);
+        ASSIGN("glResumeTransformFeedback", resumeTransformFeedback);
+        ASSIGN("glUniform1d", uniform1d);
+        ASSIGN("glUniform1dv", uniform1dv);
+        ASSIGN("glUniform2d", uniform2d);
+        ASSIGN("glUniform2dv", uniform2dv);
+        ASSIGN("glUniform3d", uniform3d);
+        ASSIGN("glUniform3dv", uniform3dv);
+        ASSIGN("glUniform4d", uniform4d);
+        ASSIGN("glUniform4dv", uniform4dv);
+        ASSIGN("glUniformMatrix2dv", uniformMatrix2dv);
+        ASSIGN("glUniformMatrix2x3dv", uniformMatrix2x3dv);
+        ASSIGN("glUniformMatrix2x4dv", uniformMatrix2x4dv);
+        ASSIGN("glUniformMatrix3dv", uniformMatrix3dv);
+        ASSIGN("glUniformMatrix3x2dv", uniformMatrix3x2dv);
+        ASSIGN("glUniformMatrix3x4dv", uniformMatrix3x4dv);
+        ASSIGN("glUniformMatrix4dv", uniformMatrix4dv);
+        ASSIGN("glUniformMatrix4x2dv", uniformMatrix4x2dv);
+        ASSIGN("glUniformMatrix4x3dv", uniformMatrix4x3dv);
+        ASSIGN("glUniformSubroutinesuiv", uniformSubroutinesuiv);
+    }
+
+    if (version >= gl::Version(4, 1))
+    {
+        ASSIGN("glActiveShaderProgram", activeShaderProgram);
+        ASSIGN("glBindProgramPipeline", bindProgramPipeline);
+        ASSIGN("glClearDepthf", clearDepthf);
+        ASSIGN("glCreateShaderProgramv", createShaderProgramv);
+        ASSIGN("glDeleteProgramPipelines", deleteProgramPipelines);
+        ASSIGN("glDepthRangeArrayv", depthRangeArrayv);
+        ASSIGN("glDepthRangeIndexed", depthRangeIndexed);
+        ASSIGN("glDepthRangef", depthRangef);
+        ASSIGN("glGenProgramPipelines", genProgramPipelines);
+        ASSIGN("glGetDoublei_v", getDoublei_v);
+        ASSIGN("glGetFloati_v", getFloati_v);
+        ASSIGN("glGetProgramBinary", getProgramBinary);
+        ASSIGN("glGetProgramPipelineInfoLog", getProgramPipelineInfoLog);
+        ASSIGN("glGetProgramPipelineiv", getProgramPipelineiv);
+        ASSIGN("glGetShaderPrecisionFormat", getShaderPrecisionFormat);
+        ASSIGN("glGetVertexAttribLdv", getVertexAttribLdv);
+        ASSIGN("glIsProgramPipeline", isProgramPipeline);
+        ASSIGN("glProgramBinary", programBinary);
+        ASSIGN("glProgramParameteri", programParameteri);
+        ASSIGN("glProgramUniform1d", programUniform1d);
+        ASSIGN("glProgramUniform1dv", programUniform1dv);
+        ASSIGN("glProgramUniform1f", programUniform1f);
+        ASSIGN("glProgramUniform1fv", programUniform1fv);
+        ASSIGN("glProgramUniform1i", programUniform1i);
+        ASSIGN("glProgramUniform1iv", programUniform1iv);
+        ASSIGN("glProgramUniform1ui", programUniform1ui);
+        ASSIGN("glProgramUniform1uiv", programUniform1uiv);
+        ASSIGN("glProgramUniform2d", programUniform2d);
+        ASSIGN("glProgramUniform2dv", programUniform2dv);
+        ASSIGN("glProgramUniform2f", programUniform2f);
+        ASSIGN("glProgramUniform2fv", programUniform2fv);
+        ASSIGN("glProgramUniform2i", programUniform2i);
+        ASSIGN("glProgramUniform2iv", programUniform2iv);
+        ASSIGN("glProgramUniform2ui", programUniform2ui);
+        ASSIGN("glProgramUniform2uiv", programUniform2uiv);
+        ASSIGN("glProgramUniform3d", programUniform3d);
+        ASSIGN("glProgramUniform3dv", programUniform3dv);
+        ASSIGN("glProgramUniform3f", programUniform3f);
+        ASSIGN("glProgramUniform3fv", programUniform3fv);
+        ASSIGN("glProgramUniform3i", programUniform3i);
+        ASSIGN("glProgramUniform3iv", programUniform3iv);
+        ASSIGN("glProgramUniform3ui", programUniform3ui);
+        ASSIGN("glProgramUniform3uiv", programUniform3uiv);
+        ASSIGN("glProgramUniform4d", programUniform4d);
+        ASSIGN("glProgramUniform4dv", programUniform4dv);
+        ASSIGN("glProgramUniform4f", programUniform4f);
+        ASSIGN("glProgramUniform4fv", programUniform4fv);
+        ASSIGN("glProgramUniform4i", programUniform4i);
+        ASSIGN("glProgramUniform4iv", programUniform4iv);
+        ASSIGN("glProgramUniform4ui", programUniform4ui);
+        ASSIGN("glProgramUniform4uiv", programUniform4uiv);
+        ASSIGN("glProgramUniformMatrix2dv", programUniformMatrix2dv);
+        ASSIGN("glProgramUniformMatrix2fv", programUniformMatrix2fv);
+        ASSIGN("glProgramUniformMatrix2x3dv", programUniformMatrix2x3dv);
+        ASSIGN("glProgramUniformMatrix2x3fv", programUniformMatrix2x3fv);
+        ASSIGN("glProgramUniformMatrix2x4dv", programUniformMatrix2x4dv);
+        ASSIGN("glProgramUniformMatrix2x4fv", programUniformMatrix2x4fv);
+        ASSIGN("glProgramUniformMatrix3dv", programUniformMatrix3dv);
+        ASSIGN("glProgramUniformMatrix3fv", programUniformMatrix3fv);
+        ASSIGN("glProgramUniformMatrix3x2dv", programUniformMatrix3x2dv);
+        ASSIGN("glProgramUniformMatrix3x2fv", programUniformMatrix3x2fv);
+        ASSIGN("glProgramUniformMatrix3x4dv", programUniformMatrix3x4dv);
+        ASSIGN("glProgramUniformMatrix3x4fv", programUniformMatrix3x4fv);
+        ASSIGN("glProgramUniformMatrix4dv", programUniformMatrix4dv);
+        ASSIGN("glProgramUniformMatrix4fv", programUniformMatrix4fv);
+        ASSIGN("glProgramUniformMatrix4x2dv", programUniformMatrix4x2dv);
+        ASSIGN("glProgramUniformMatrix4x2fv", programUniformMatrix4x2fv);
+        ASSIGN("glProgramUniformMatrix4x3dv", programUniformMatrix4x3dv);
+        ASSIGN("glProgramUniformMatrix4x3fv", programUniformMatrix4x3fv);
+        ASSIGN("glReleaseShaderCompiler", releaseShaderCompiler);
+        ASSIGN("glScissorArrayv", scissorArrayv);
+        ASSIGN("glScissorIndexed", scissorIndexed);
+        ASSIGN("glScissorIndexedv", scissorIndexedv);
+        ASSIGN("glShaderBinary", shaderBinary);
+        ASSIGN("glUseProgramStages", useProgramStages);
+        ASSIGN("glValidateProgramPipeline", validateProgramPipeline);
+        ASSIGN("glVertexAttribL1d", vertexAttribL1d);
+        ASSIGN("glVertexAttribL1dv", vertexAttribL1dv);
+        ASSIGN("glVertexAttribL2d", vertexAttribL2d);
+        ASSIGN("glVertexAttribL2dv", vertexAttribL2dv);
+        ASSIGN("glVertexAttribL3d", vertexAttribL3d);
+        ASSIGN("glVertexAttribL3dv", vertexAttribL3dv);
+        ASSIGN("glVertexAttribL4d", vertexAttribL4d);
+        ASSIGN("glVertexAttribL4dv", vertexAttribL4dv);
+        ASSIGN("glVertexAttribLPointer", vertexAttribLPointer);
+        ASSIGN("glViewportArrayv", viewportArrayv);
+        ASSIGN("glViewportIndexedf", viewportIndexedf);
+        ASSIGN("glViewportIndexedfv", viewportIndexedfv);
+    }
+
+    if (version >= gl::Version(4, 2))
+    {
+        ASSIGN("glBindImageTexture", bindImageTexture);
+        ASSIGN("glDrawArraysInstancedBaseInstance", drawArraysInstancedBaseInstance);
+        ASSIGN("glDrawElementsInstancedBaseInstance", drawElementsInstancedBaseInstance);
+        ASSIGN("glDrawElementsInstancedBaseVertexBaseInstance",
+               drawElementsInstancedBaseVertexBaseInstance);
+        ASSIGN("glDrawTransformFeedbackInstanced", drawTransformFeedbackInstanced);
+        ASSIGN("glDrawTransformFeedbackStreamInstanced", drawTransformFeedbackStreamInstanced);
+        ASSIGN("glGetActiveAtomicCounterBufferiv", getActiveAtomicCounterBufferiv);
+        ASSIGN("glGetInternalformativ", getInternalformativ);
+        ASSIGN("glMemoryBarrier", memoryBarrier);
+        ASSIGN("glTexStorage1D", texStorage1D);
+        ASSIGN("glTexStorage2D", texStorage2D);
+        ASSIGN("glTexStorage3D", texStorage3D);
+    }
+
+    if (version >= gl::Version(4, 3))
+    {
+        ASSIGN("glBindVertexBuffer", bindVertexBuffer);
+        ASSIGN("glClearBufferData", clearBufferData);
+        ASSIGN("glClearBufferSubData", clearBufferSubData);
+        ASSIGN("glCopyImageSubData", copyImageSubData);
+        ASSIGN("glDebugMessageCallback", debugMessageCallback);
+        ASSIGN("glDebugMessageControl", debugMessageControl);
+        ASSIGN("glDebugMessageInsert", debugMessageInsert);
+        ASSIGN("glDispatchCompute", dispatchCompute);
+        ASSIGN("glDispatchComputeIndirect", dispatchComputeIndirect);
+        ASSIGN("glFramebufferParameteri", framebufferParameteri);
+        ASSIGN("glGetDebugMessageLog", getDebugMessageLog);
+        ASSIGN("glGetFramebufferParameteriv", getFramebufferParameteriv);
+        ASSIGN("glGetInternalformati64v", getInternalformati64v);
+        ASSIGN("glGetObjectLabel", getObjectLabel);
+        ASSIGN("glGetObjectPtrLabel", getObjectPtrLabel);
+        ASSIGN("glGetPointerv", getPointerv);
+        ASSIGN("glGetProgramInterfaceiv", getProgramInterfaceiv);
+        ASSIGN("glGetProgramResourceIndex", getProgramResourceIndex);
+        ASSIGN("glGetProgramResourceLocation", getProgramResourceLocation);
+        ASSIGN("glGetProgramResourceLocationIndex", getProgramResourceLocationIndex);
+        ASSIGN("glGetProgramResourceName", getProgramResourceName);
+        ASSIGN("glGetProgramResourceiv", getProgramResourceiv);
+        ASSIGN("glInvalidateBufferData", invalidateBufferData);
+        ASSIGN("glInvalidateBufferSubData", invalidateBufferSubData);
+        ASSIGN("glInvalidateFramebuffer", invalidateFramebuffer);
+        ASSIGN("glInvalidateSubFramebuffer", invalidateSubFramebuffer);
+        ASSIGN("glInvalidateTexImage", invalidateTexImage);
+        ASSIGN("glInvalidateTexSubImage", invalidateTexSubImage);
+        ASSIGN("glMultiDrawArraysIndirect", multiDrawArraysIndirect);
+        ASSIGN("glMultiDrawElementsIndirect", multiDrawElementsIndirect);
+        ASSIGN("glObjectLabel", objectLabel);
+        ASSIGN("glObjectPtrLabel", objectPtrLabel);
+        ASSIGN("glPopDebugGroup", popDebugGroup);
+        ASSIGN("glPushDebugGroup", pushDebugGroup);
+        ASSIGN("glShaderStorageBlockBinding", shaderStorageBlockBinding);
+        ASSIGN("glTexBufferRange", texBufferRange);
+        ASSIGN("glTexStorage2DMultisample", texStorage2DMultisample);
+        ASSIGN("glTexStorage3DMultisample", texStorage3DMultisample);
+        ASSIGN("glTextureView", textureView);
+        ASSIGN("glVertexAttribBinding", vertexAttribBinding);
+        ASSIGN("glVertexAttribFormat", vertexAttribFormat);
+        ASSIGN("glVertexAttribIFormat", vertexAttribIFormat);
+        ASSIGN("glVertexAttribLFormat", vertexAttribLFormat);
+        ASSIGN("glVertexBindingDivisor", vertexBindingDivisor);
+    }
+
+    if (version >= gl::Version(4, 4))
+    {
+        ASSIGN("glBindBuffersBase", bindBuffersBase);
+        ASSIGN("glBindBuffersRange", bindBuffersRange);
+        ASSIGN("glBindImageTextures", bindImageTextures);
+        ASSIGN("glBindSamplers", bindSamplers);
+        ASSIGN("glBindTextures", bindTextures);
+        ASSIGN("glBindVertexBuffers", bindVertexBuffers);
+        ASSIGN("glBufferStorage", bufferStorage);
+        ASSIGN("glClearTexImage", clearTexImage);
+        ASSIGN("glClearTexSubImage", clearTexSubImage);
+    }
+
+    if (version >= gl::Version(4, 5))
+    {
+        ASSIGN("glBindTextureUnit", bindTextureUnit);
+        ASSIGN("glBlitNamedFramebuffer", blitNamedFramebuffer);
+        ASSIGN("glCheckNamedFramebufferStatus", checkNamedFramebufferStatus);
+        ASSIGN("glClearNamedBufferData", clearNamedBufferData);
+        ASSIGN("glClearNamedBufferSubData", clearNamedBufferSubData);
+        ASSIGN("glClearNamedFramebufferfi", clearNamedFramebufferfi);
+        ASSIGN("glClearNamedFramebufferfv", clearNamedFramebufferfv);
+        ASSIGN("glClearNamedFramebufferiv", clearNamedFramebufferiv);
+        ASSIGN("glClearNamedFramebufferuiv", clearNamedFramebufferuiv);
+        ASSIGN("glClipControl", clipControl);
+        ASSIGN("glCompressedTextureSubImage1D", compressedTextureSubImage1D);
+        ASSIGN("glCompressedTextureSubImage2D", compressedTextureSubImage2D);
+        ASSIGN("glCompressedTextureSubImage3D", compressedTextureSubImage3D);
+        ASSIGN("glCopyNamedBufferSubData", copyNamedBufferSubData);
+        ASSIGN("glCopyTextureSubImage1D", copyTextureSubImage1D);
+        ASSIGN("glCopyTextureSubImage2D", copyTextureSubImage2D);
+        ASSIGN("glCopyTextureSubImage3D", copyTextureSubImage3D);
+        ASSIGN("glCreateBuffers", createBuffers);
+        ASSIGN("glCreateFramebuffers", createFramebuffers);
+        ASSIGN("glCreateProgramPipelines", createProgramPipelines);
+        ASSIGN("glCreateQueries", createQueries);
+        ASSIGN("glCreateRenderbuffers", createRenderbuffers);
+        ASSIGN("glCreateSamplers", createSamplers);
+        ASSIGN("glCreateTextures", createTextures);
+        ASSIGN("glCreateTransformFeedbacks", createTransformFeedbacks);
+        ASSIGN("glCreateVertexArrays", createVertexArrays);
+        ASSIGN("glDisableVertexArrayAttrib", disableVertexArrayAttrib);
+        ASSIGN("glEnableVertexArrayAttrib", enableVertexArrayAttrib);
+        ASSIGN("glFlushMappedNamedBufferRange", flushMappedNamedBufferRange);
+        ASSIGN("glGenerateTextureMipmap", generateTextureMipmap);
+        ASSIGN("glGetCompressedTextureImage", getCompressedTextureImage);
+        ASSIGN("glGetCompressedTextureSubImage", getCompressedTextureSubImage);
+        ASSIGN("glGetGraphicsResetStatus", getGraphicsResetStatus);
+        ASSIGN("glGetNamedBufferParameteri64v", getNamedBufferParameteri64v);
+        ASSIGN("glGetNamedBufferParameteriv", getNamedBufferParameteriv);
+        ASSIGN("glGetNamedBufferPointerv", getNamedBufferPointerv);
+        ASSIGN("glGetNamedBufferSubData", getNamedBufferSubData);
+        ASSIGN("glGetNamedFramebufferAttachmentParameteriv",
+               getNamedFramebufferAttachmentParameteriv);
+        ASSIGN("glGetNamedFramebufferParameteriv", getNamedFramebufferParameteriv);
+        ASSIGN("glGetNamedRenderbufferParameteriv", getNamedRenderbufferParameteriv);
+        ASSIGN("glGetQueryBufferObjecti64v", getQueryBufferObjecti64v);
+        ASSIGN("glGetQueryBufferObjectiv", getQueryBufferObjectiv);
+        ASSIGN("glGetQueryBufferObjectui64v", getQueryBufferObjectui64v);
+        ASSIGN("glGetQueryBufferObjectuiv", getQueryBufferObjectuiv);
+        ASSIGN("glGetTextureImage", getTextureImage);
+        ASSIGN("glGetTextureLevelParameterfv", getTextureLevelParameterfv);
+        ASSIGN("glGetTextureLevelParameteriv", getTextureLevelParameteriv);
+        ASSIGN("glGetTextureParameterIiv", getTextureParameterIiv);
+        ASSIGN("glGetTextureParameterIuiv", getTextureParameterIuiv);
+        ASSIGN("glGetTextureParameterfv", getTextureParameterfv);
+        ASSIGN("glGetTextureParameteriv", getTextureParameteriv);
+        ASSIGN("glGetTextureSubImage", getTextureSubImage);
+        ASSIGN("glGetTransformFeedbacki64_v", getTransformFeedbacki64_v);
+        ASSIGN("glGetTransformFeedbacki_v", getTransformFeedbacki_v);
+        ASSIGN("glGetTransformFeedbackiv", getTransformFeedbackiv);
+        ASSIGN("glGetVertexArrayIndexed64iv", getVertexArrayIndexed64iv);
+        ASSIGN("glGetVertexArrayIndexediv", getVertexArrayIndexediv);
+        ASSIGN("glGetVertexArrayiv", getVertexArrayiv);
+        ASSIGN("glGetnCompressedTexImage", getnCompressedTexImage);
+        ASSIGN("glGetnTexImage", getnTexImage);
+        ASSIGN("glGetnUniformdv", getnUniformdv);
+        ASSIGN("glGetnUniformfv", getnUniformfv);
+        ASSIGN("glGetnUniformiv", getnUniformiv);
+        ASSIGN("glGetnUniformuiv", getnUniformuiv);
+        ASSIGN("glInvalidateNamedFramebufferData", invalidateNamedFramebufferData);
+        ASSIGN("glInvalidateNamedFramebufferSubData", invalidateNamedFramebufferSubData);
+        ASSIGN("glMapNamedBuffer", mapNamedBuffer);
+        ASSIGN("glMapNamedBufferRange", mapNamedBufferRange);
+        ASSIGN("glMemoryBarrierByRegion", memoryBarrierByRegion);
+        ASSIGN("glNamedBufferData", namedBufferData);
+        ASSIGN("glNamedBufferStorage", namedBufferStorage);
+        ASSIGN("glNamedBufferSubData", namedBufferSubData);
+        ASSIGN("glNamedFramebufferDrawBuffer", namedFramebufferDrawBuffer);
+        ASSIGN("glNamedFramebufferDrawBuffers", namedFramebufferDrawBuffers);
+        ASSIGN("glNamedFramebufferParameteri", namedFramebufferParameteri);
+        ASSIGN("glNamedFramebufferReadBuffer", namedFramebufferReadBuffer);
+        ASSIGN("glNamedFramebufferRenderbuffer", namedFramebufferRenderbuffer);
+        ASSIGN("glNamedFramebufferTexture", namedFramebufferTexture);
+        ASSIGN("glNamedFramebufferTextureLayer", namedFramebufferTextureLayer);
+        ASSIGN("glNamedRenderbufferStorage", namedRenderbufferStorage);
+        ASSIGN("glNamedRenderbufferStorageMultisample", namedRenderbufferStorageMultisample);
+        ASSIGN("glReadnPixels", readnPixels);
+        ASSIGN("glTextureBarrier", textureBarrier);
+        ASSIGN("glTextureBuffer", textureBuffer);
+        ASSIGN("glTextureBufferRange", textureBufferRange);
+        ASSIGN("glTextureParameterIiv", textureParameterIiv);
+        ASSIGN("glTextureParameterIuiv", textureParameterIuiv);
+        ASSIGN("glTextureParameterf", textureParameterf);
+        ASSIGN("glTextureParameterfv", textureParameterfv);
+        ASSIGN("glTextureParameteri", textureParameteri);
+        ASSIGN("glTextureParameteriv", textureParameteriv);
+        ASSIGN("glTextureStorage1D", textureStorage1D);
+        ASSIGN("glTextureStorage2D", textureStorage2D);
+        ASSIGN("glTextureStorage2DMultisample", textureStorage2DMultisample);
+        ASSIGN("glTextureStorage3D", textureStorage3D);
+        ASSIGN("glTextureStorage3DMultisample", textureStorage3DMultisample);
+        ASSIGN("glTextureSubImage1D", textureSubImage1D);
+        ASSIGN("glTextureSubImage2D", textureSubImage2D);
+        ASSIGN("glTextureSubImage3D", textureSubImage3D);
+        ASSIGN("glTransformFeedbackBufferBase", transformFeedbackBufferBase);
+        ASSIGN("glTransformFeedbackBufferRange", transformFeedbackBufferRange);
+        ASSIGN("glUnmapNamedBuffer", unmapNamedBuffer);
+        ASSIGN("glVertexArrayAttribBinding", vertexArrayAttribBinding);
+        ASSIGN("glVertexArrayAttribFormat", vertexArrayAttribFormat);
+        ASSIGN("glVertexArrayAttribIFormat", vertexArrayAttribIFormat);
+        ASSIGN("glVertexArrayAttribLFormat", vertexArrayAttribLFormat);
+        ASSIGN("glVertexArrayBindingDivisor", vertexArrayBindingDivisor);
+        ASSIGN("glVertexArrayElementBuffer", vertexArrayElementBuffer);
+        ASSIGN("glVertexArrayVertexBuffer", vertexArrayVertexBuffer);
+        ASSIGN("glVertexArrayVertexBuffers", vertexArrayVertexBuffers);
+    }
+
+    if (extensions.count("GL_ARB_ES2_compatibility") != 0)
+    {
+        ASSIGN("glClearDepthf", clearDepthf);
+        ASSIGN("glDepthRangef", depthRangef);
+        ASSIGN("glGetShaderPrecisionFormat", getShaderPrecisionFormat);
+        ASSIGN("glReleaseShaderCompiler", releaseShaderCompiler);
+        ASSIGN("glShaderBinary", shaderBinary);
+    }
+
+    if (extensions.count("GL_ARB_ES3_1_compatibility") != 0)
+    {
+        ASSIGN("glMemoryBarrierByRegion", memoryBarrierByRegion);
+    }
+
+    if (extensions.count("GL_ARB_ES3_2_compatibility") != 0)
+    {
+        ASSIGN("glPrimitiveBoundingBoxARB", primitiveBoundingBox);
+    }
+
+    if (extensions.count("GL_ARB_base_instance") != 0)
+    {
+        ASSIGN("glDrawArraysInstancedBaseInstance", drawArraysInstancedBaseInstance);
+        ASSIGN("glDrawElementsInstancedBaseInstance", drawElementsInstancedBaseInstance);
+        ASSIGN("glDrawElementsInstancedBaseVertexBaseInstance",
+               drawElementsInstancedBaseVertexBaseInstance);
+    }
+
+    if (extensions.count("GL_ARB_blend_func_extended") != 0)
+    {
+        ASSIGN("glBindFragDataLocationIndexed", bindFragDataLocationIndexed);
+        ASSIGN("glGetFragDataIndex", getFragDataIndex);
+    }
+
+    if (extensions.count("GL_ARB_buffer_storage") != 0)
+    {
+        ASSIGN("glBufferStorage", bufferStorage);
+    }
+
+    if (extensions.count("GL_ARB_clear_buffer_object") != 0)
+    {
+        ASSIGN("glClearBufferData", clearBufferData);
+        ASSIGN("glClearBufferSubData", clearBufferSubData);
+    }
+
+    if (extensions.count("GL_ARB_clear_texture") != 0)
+    {
+        ASSIGN("glClearTexImage", clearTexImage);
+        ASSIGN("glClearTexSubImage", clearTexSubImage);
+    }
+
+    if (extensions.count("GL_ARB_clip_control") != 0)
+    {
+        ASSIGN("glClipControl", clipControl);
+    }
+
+    if (extensions.count("GL_ARB_color_buffer_float") != 0)
+    {
+        ASSIGN("glClampColorARB", clampColor);
+    }
+
+    if (extensions.count("GL_ARB_compute_shader") != 0)
+    {
+        ASSIGN("glDispatchCompute", dispatchCompute);
+        ASSIGN("glDispatchComputeIndirect", dispatchComputeIndirect);
+    }
+
+    if (extensions.count("GL_ARB_copy_buffer") != 0)
+    {
+        ASSIGN("glCopyBufferSubData", copyBufferSubData);
+    }
+
+    if (extensions.count("GL_ARB_copy_image") != 0)
+    {
+        ASSIGN("glCopyImageSubData", copyImageSubData);
+    }
+
+    if (extensions.count("GL_ARB_debug_output") != 0)
+    {
+        ASSIGN("glDebugMessageCallbackARB", debugMessageCallback);
+        ASSIGN("glDebugMessageControlARB", debugMessageControl);
+        ASSIGN("glDebugMessageInsertARB", debugMessageInsert);
+        ASSIGN("glGetDebugMessageLogARB", getDebugMessageLog);
+    }
+
+    if (extensions.count("GL_ARB_direct_state_access") != 0)
+    {
+        ASSIGN("glBindTextureUnit", bindTextureUnit);
+        ASSIGN("glBlitNamedFramebuffer", blitNamedFramebuffer);
+        ASSIGN("glCheckNamedFramebufferStatus", checkNamedFramebufferStatus);
+        ASSIGN("glClearNamedBufferData", clearNamedBufferData);
+        ASSIGN("glClearNamedBufferSubData", clearNamedBufferSubData);
+        ASSIGN("glClearNamedFramebufferfi", clearNamedFramebufferfi);
+        ASSIGN("glClearNamedFramebufferfv", clearNamedFramebufferfv);
+        ASSIGN("glClearNamedFramebufferiv", clearNamedFramebufferiv);
+        ASSIGN("glClearNamedFramebufferuiv", clearNamedFramebufferuiv);
+        ASSIGN("glCompressedTextureSubImage1D", compressedTextureSubImage1D);
+        ASSIGN("glCompressedTextureSubImage2D", compressedTextureSubImage2D);
+        ASSIGN("glCompressedTextureSubImage3D", compressedTextureSubImage3D);
+        ASSIGN("glCopyNamedBufferSubData", copyNamedBufferSubData);
+        ASSIGN("glCopyTextureSubImage1D", copyTextureSubImage1D);
+        ASSIGN("glCopyTextureSubImage2D", copyTextureSubImage2D);
+        ASSIGN("glCopyTextureSubImage3D", copyTextureSubImage3D);
+        ASSIGN("glCreateBuffers", createBuffers);
+        ASSIGN("glCreateFramebuffers", createFramebuffers);
+        ASSIGN("glCreateProgramPipelines", createProgramPipelines);
+        ASSIGN("glCreateQueries", createQueries);
+        ASSIGN("glCreateRenderbuffers", createRenderbuffers);
+        ASSIGN("glCreateSamplers", createSamplers);
+        ASSIGN("glCreateTextures", createTextures);
+        ASSIGN("glCreateTransformFeedbacks", createTransformFeedbacks);
+        ASSIGN("glCreateVertexArrays", createVertexArrays);
+        ASSIGN("glDisableVertexArrayAttrib", disableVertexArrayAttrib);
+        ASSIGN("glEnableVertexArrayAttrib", enableVertexArrayAttrib);
+        ASSIGN("glFlushMappedNamedBufferRange", flushMappedNamedBufferRange);
+        ASSIGN("glGenerateTextureMipmap", generateTextureMipmap);
+        ASSIGN("glGetCompressedTextureImage", getCompressedTextureImage);
+        ASSIGN("glGetNamedBufferParameteri64v", getNamedBufferParameteri64v);
+        ASSIGN("glGetNamedBufferParameteriv", getNamedBufferParameteriv);
+        ASSIGN("glGetNamedBufferPointerv", getNamedBufferPointerv);
+        ASSIGN("glGetNamedBufferSubData", getNamedBufferSubData);
+        ASSIGN("glGetNamedFramebufferAttachmentParameteriv",
+               getNamedFramebufferAttachmentParameteriv);
+        ASSIGN("glGetNamedFramebufferParameteriv", getNamedFramebufferParameteriv);
+        ASSIGN("glGetNamedRenderbufferParameteriv", getNamedRenderbufferParameteriv);
+        ASSIGN("glGetQueryBufferObjecti64v", getQueryBufferObjecti64v);
+        ASSIGN("glGetQueryBufferObjectiv", getQueryBufferObjectiv);
+        ASSIGN("glGetQueryBufferObjectui64v", getQueryBufferObjectui64v);
+        ASSIGN("glGetQueryBufferObjectuiv", getQueryBufferObjectuiv);
+        ASSIGN("glGetTextureImage", getTextureImage);
+        ASSIGN("glGetTextureLevelParameterfv", getTextureLevelParameterfv);
+        ASSIGN("glGetTextureLevelParameteriv", getTextureLevelParameteriv);
+        ASSIGN("glGetTextureParameterIiv", getTextureParameterIiv);
+        ASSIGN("glGetTextureParameterIuiv", getTextureParameterIuiv);
+        ASSIGN("glGetTextureParameterfv", getTextureParameterfv);
+        ASSIGN("glGetTextureParameteriv", getTextureParameteriv);
+        ASSIGN("glGetTransformFeedbacki64_v", getTransformFeedbacki64_v);
+        ASSIGN("glGetTransformFeedbacki_v", getTransformFeedbacki_v);
+        ASSIGN("glGetTransformFeedbackiv", getTransformFeedbackiv);
+        ASSIGN("glGetVertexArrayIndexed64iv", getVertexArrayIndexed64iv);
+        ASSIGN("glGetVertexArrayIndexediv", getVertexArrayIndexediv);
+        ASSIGN("glGetVertexArrayiv", getVertexArrayiv);
+        ASSIGN("glInvalidateNamedFramebufferData", invalidateNamedFramebufferData);
+        ASSIGN("glInvalidateNamedFramebufferSubData", invalidateNamedFramebufferSubData);
+        ASSIGN("glMapNamedBuffer", mapNamedBuffer);
+        ASSIGN("glMapNamedBufferRange", mapNamedBufferRange);
+        ASSIGN("glNamedBufferData", namedBufferData);
+        ASSIGN("glNamedBufferStorage", namedBufferStorage);
+        ASSIGN("glNamedBufferSubData", namedBufferSubData);
+        ASSIGN("glNamedFramebufferDrawBuffer", namedFramebufferDrawBuffer);
+        ASSIGN("glNamedFramebufferDrawBuffers", namedFramebufferDrawBuffers);
+        ASSIGN("glNamedFramebufferParameteri", namedFramebufferParameteri);
+        ASSIGN("glNamedFramebufferReadBuffer", namedFramebufferReadBuffer);
+        ASSIGN("glNamedFramebufferRenderbuffer", namedFramebufferRenderbuffer);
+        ASSIGN("glNamedFramebufferTexture", namedFramebufferTexture);
+        ASSIGN("glNamedFramebufferTextureLayer", namedFramebufferTextureLayer);
+        ASSIGN("glNamedRenderbufferStorage", namedRenderbufferStorage);
+        ASSIGN("glNamedRenderbufferStorageMultisample", namedRenderbufferStorageMultisample);
+        ASSIGN("glTextureBuffer", textureBuffer);
+        ASSIGN("glTextureBufferRange", textureBufferRange);
+        ASSIGN("glTextureParameterIiv", textureParameterIiv);
+        ASSIGN("glTextureParameterIuiv", textureParameterIuiv);
+        ASSIGN("glTextureParameterf", textureParameterf);
+        ASSIGN("glTextureParameterfv", textureParameterfv);
+        ASSIGN("glTextureParameteri", textureParameteri);
+        ASSIGN("glTextureParameteriv", textureParameteriv);
+        ASSIGN("glTextureStorage1D", textureStorage1D);
+        ASSIGN("glTextureStorage2D", textureStorage2D);
+        ASSIGN("glTextureStorage2DMultisample", textureStorage2DMultisample);
+        ASSIGN("glTextureStorage3D", textureStorage3D);
+        ASSIGN("glTextureStorage3DMultisample", textureStorage3DMultisample);
+        ASSIGN("glTextureSubImage1D", textureSubImage1D);
+        ASSIGN("glTextureSubImage2D", textureSubImage2D);
+        ASSIGN("glTextureSubImage3D", textureSubImage3D);
+        ASSIGN("glTransformFeedbackBufferBase", transformFeedbackBufferBase);
+        ASSIGN("glTransformFeedbackBufferRange", transformFeedbackBufferRange);
+        ASSIGN("glUnmapNamedBuffer", unmapNamedBuffer);
+        ASSIGN("glVertexArrayAttribBinding", vertexArrayAttribBinding);
+        ASSIGN("glVertexArrayAttribFormat", vertexArrayAttribFormat);
+        ASSIGN("glVertexArrayAttribIFormat", vertexArrayAttribIFormat);
+        ASSIGN("glVertexArrayAttribLFormat", vertexArrayAttribLFormat);
+        ASSIGN("glVertexArrayBindingDivisor", vertexArrayBindingDivisor);
+        ASSIGN("glVertexArrayElementBuffer", vertexArrayElementBuffer);
+        ASSIGN("glVertexArrayVertexBuffer", vertexArrayVertexBuffer);
+        ASSIGN("glVertexArrayVertexBuffers", vertexArrayVertexBuffers);
+    }
+
+    if (extensions.count("GL_ARB_draw_buffers") != 0)
+    {
+        ASSIGN("glDrawBuffersARB", drawBuffers);
+    }
+
+    if (extensions.count("GL_ARB_draw_buffers_blend") != 0)
+    {
+        ASSIGN("glBlendEquationSeparateiARB", blendEquationSeparatei);
+        ASSIGN("glBlendEquationiARB", blendEquationi);
+        ASSIGN("glBlendFuncSeparateiARB", blendFuncSeparatei);
+        ASSIGN("glBlendFunciARB", blendFunci);
+    }
+
+    if (extensions.count("GL_ARB_draw_elements_base_vertex") != 0)
+    {
+        ASSIGN("glDrawElementsBaseVertex", drawElementsBaseVertex);
+        ASSIGN("glDrawElementsInstancedBaseVertex", drawElementsInstancedBaseVertex);
+        ASSIGN("glDrawRangeElementsBaseVertex", drawRangeElementsBaseVertex);
+        ASSIGN("glMultiDrawElementsBaseVertex", multiDrawElementsBaseVertex);
+    }
+
+    if (extensions.count("GL_ARB_draw_indirect") != 0)
+    {
+        ASSIGN("glDrawArraysIndirect", drawArraysIndirect);
+        ASSIGN("glDrawElementsIndirect", drawElementsIndirect);
+    }
+
+    if (extensions.count("GL_ARB_draw_instanced") != 0)
+    {
+        ASSIGN("glDrawArraysInstancedARB", drawArraysInstanced);
+        ASSIGN("glDrawElementsInstancedARB", drawElementsInstanced);
+    }
+
+    if (extensions.count("GL_ARB_fragment_program") != 0)
+    {
+        ASSIGN("glGetProgramivARB", getProgramiv);
+        ASSIGN("glIsProgramARB", isProgram);
+    }
+
+    if (extensions.count("GL_ARB_framebuffer_no_attachments") != 0)
+    {
+        ASSIGN("glFramebufferParameteri", framebufferParameteri);
+        ASSIGN("glGetFramebufferParameteriv", getFramebufferParameteriv);
+    }
+
+    if (extensions.count("GL_ARB_framebuffer_object") != 0)
+    {
+        ASSIGN("glBindFramebuffer", bindFramebuffer);
+        ASSIGN("glBindRenderbuffer", bindRenderbuffer);
+        ASSIGN("glBlitFramebuffer", blitFramebuffer);
+        ASSIGN("glCheckFramebufferStatus", checkFramebufferStatus);
+        ASSIGN("glDeleteFramebuffers", deleteFramebuffers);
+        ASSIGN("glDeleteRenderbuffers", deleteRenderbuffers);
+        ASSIGN("glFramebufferRenderbuffer", framebufferRenderbuffer);
+        ASSIGN("glFramebufferTexture1D", framebufferTexture1D);
+        ASSIGN("glFramebufferTexture2D", framebufferTexture2D);
+        ASSIGN("glFramebufferTexture3D", framebufferTexture3D);
+        ASSIGN("glFramebufferTextureLayer", framebufferTextureLayer);
+        ASSIGN("glGenFramebuffers", genFramebuffers);
+        ASSIGN("glGenRenderbuffers", genRenderbuffers);
+        ASSIGN("glGenerateMipmap", generateMipmap);
+        ASSIGN("glGetFramebufferAttachmentParameteriv", getFramebufferAttachmentParameteriv);
+        ASSIGN("glGetRenderbufferParameteriv", getRenderbufferParameteriv);
+        ASSIGN("glIsFramebuffer", isFramebuffer);
+        ASSIGN("glIsRenderbuffer", isRenderbuffer);
+        ASSIGN("glRenderbufferStorage", renderbufferStorage);
+        ASSIGN("glRenderbufferStorageMultisample", renderbufferStorageMultisample);
+    }
+
+    if (extensions.count("GL_ARB_geometry_shader4") != 0)
+    {
+        ASSIGN("glFramebufferTextureARB", framebufferTexture);
+        ASSIGN("glFramebufferTextureLayerARB", framebufferTextureLayer);
+        ASSIGN("glProgramParameteriARB", programParameteri);
+    }
+
+    if (extensions.count("GL_ARB_get_program_binary") != 0)
+    {
+        ASSIGN("glGetProgramBinary", getProgramBinary);
+        ASSIGN("glProgramBinary", programBinary);
+        ASSIGN("glProgramParameteri", programParameteri);
+    }
+
+    if (extensions.count("GL_ARB_get_texture_sub_image") != 0)
+    {
+        ASSIGN("glGetCompressedTextureSubImage", getCompressedTextureSubImage);
+        ASSIGN("glGetTextureSubImage", getTextureSubImage);
+    }
+
+    if (extensions.count("GL_ARB_gpu_shader_fp64") != 0)
+    {
+        ASSIGN("glGetUniformdv", getUniformdv);
+        ASSIGN("glUniform1d", uniform1d);
+        ASSIGN("glUniform1dv", uniform1dv);
+        ASSIGN("glUniform2d", uniform2d);
+        ASSIGN("glUniform2dv", uniform2dv);
+        ASSIGN("glUniform3d", uniform3d);
+        ASSIGN("glUniform3dv", uniform3dv);
+        ASSIGN("glUniform4d", uniform4d);
+        ASSIGN("glUniform4dv", uniform4dv);
+        ASSIGN("glUniformMatrix2dv", uniformMatrix2dv);
+        ASSIGN("glUniformMatrix2x3dv", uniformMatrix2x3dv);
+        ASSIGN("glUniformMatrix2x4dv", uniformMatrix2x4dv);
+        ASSIGN("glUniformMatrix3dv", uniformMatrix3dv);
+        ASSIGN("glUniformMatrix3x2dv", uniformMatrix3x2dv);
+        ASSIGN("glUniformMatrix3x4dv", uniformMatrix3x4dv);
+        ASSIGN("glUniformMatrix4dv", uniformMatrix4dv);
+        ASSIGN("glUniformMatrix4x2dv", uniformMatrix4x2dv);
+        ASSIGN("glUniformMatrix4x3dv", uniformMatrix4x3dv);
+    }
+
+    if (extensions.count("GL_ARB_imaging") != 0)
+    {
+        ASSIGN("glBlendColor", blendColor);
+        ASSIGN("glBlendEquation", blendEquation);
+    }
+
+    if (extensions.count("GL_ARB_instanced_arrays") != 0)
+    {
+        ASSIGN("glVertexAttribDivisorARB", vertexAttribDivisor);
+    }
+
+    if (extensions.count("GL_ARB_internalformat_query") != 0)
+    {
+        ASSIGN("glGetInternalformativ", getInternalformativ);
+    }
+
+    if (extensions.count("GL_ARB_internalformat_query2") != 0)
+    {
+        ASSIGN("glGetInternalformati64v", getInternalformati64v);
+    }
+
+    if (extensions.count("GL_ARB_invalidate_subdata") != 0)
+    {
+        ASSIGN("glInvalidateBufferData", invalidateBufferData);
+        ASSIGN("glInvalidateBufferSubData", invalidateBufferSubData);
+        ASSIGN("glInvalidateFramebuffer", invalidateFramebuffer);
+        ASSIGN("glInvalidateSubFramebuffer", invalidateSubFramebuffer);
+        ASSIGN("glInvalidateTexImage", invalidateTexImage);
+        ASSIGN("glInvalidateTexSubImage", invalidateTexSubImage);
+    }
+
+    if (extensions.count("GL_ARB_map_buffer_range") != 0)
+    {
+        ASSIGN("glFlushMappedBufferRange", flushMappedBufferRange);
+        ASSIGN("glMapBufferRange", mapBufferRange);
+    }
+
+    if (extensions.count("GL_ARB_multi_bind") != 0)
+    {
+        ASSIGN("glBindBuffersBase", bindBuffersBase);
+        ASSIGN("glBindBuffersRange", bindBuffersRange);
+        ASSIGN("glBindImageTextures", bindImageTextures);
+        ASSIGN("glBindSamplers", bindSamplers);
+        ASSIGN("glBindTextures", bindTextures);
+        ASSIGN("glBindVertexBuffers", bindVertexBuffers);
+    }
+
+    if (extensions.count("GL_ARB_multi_draw_indirect") != 0)
+    {
+        ASSIGN("glMultiDrawArraysIndirect", multiDrawArraysIndirect);
+        ASSIGN("glMultiDrawElementsIndirect", multiDrawElementsIndirect);
+    }
+
+    if (extensions.count("GL_ARB_multisample") != 0)
+    {
+        ASSIGN("glSampleCoverageARB", sampleCoverage);
+    }
+
+    if (extensions.count("GL_ARB_multitexture") != 0)
+    {
+        ASSIGN("glActiveTextureARB", activeTexture);
+    }
+
+    if (extensions.count("GL_ARB_occlusion_query") != 0)
+    {
+        ASSIGN("glBeginQueryARB", beginQuery);
+        ASSIGN("glDeleteQueriesARB", deleteQueries);
+        ASSIGN("glEndQueryARB", endQuery);
+        ASSIGN("glGenQueriesARB", genQueries);
+        ASSIGN("glGetQueryObjectivARB", getQueryObjectiv);
+        ASSIGN("glGetQueryObjectuivARB", getQueryObjectuiv);
+        ASSIGN("glGetQueryivARB", getQueryiv);
+        ASSIGN("glIsQueryARB", isQuery);
+    }
+
+    if (extensions.count("GL_ARB_point_parameters") != 0)
+    {
+        ASSIGN("glPointParameterfARB", pointParameterf);
+        ASSIGN("glPointParameterfvARB", pointParameterfv);
+    }
+
+    if (extensions.count("GL_ARB_program_interface_query") != 0)
+    {
+        ASSIGN("glGetProgramInterfaceiv", getProgramInterfaceiv);
+        ASSIGN("glGetProgramResourceIndex", getProgramResourceIndex);
+        ASSIGN("glGetProgramResourceLocation", getProgramResourceLocation);
+        ASSIGN("glGetProgramResourceLocationIndex", getProgramResourceLocationIndex);
+        ASSIGN("glGetProgramResourceName", getProgramResourceName);
+        ASSIGN("glGetProgramResourceiv", getProgramResourceiv);
+    }
+
+    if (extensions.count("GL_ARB_provoking_vertex") != 0)
+    {
+        ASSIGN("glProvokingVertex", provokingVertex);
+    }
+
+    if (extensions.count("GL_ARB_robustness") != 0)
+    {
+        ASSIGN("glGetGraphicsResetStatusARB", getGraphicsResetStatus);
+        ASSIGN("glGetnCompressedTexImageARB", getnCompressedTexImage);
+        ASSIGN("glGetnTexImageARB", getnTexImage);
+        ASSIGN("glGetnUniformdvARB", getnUniformdv);
+        ASSIGN("glGetnUniformfvARB", getnUniformfv);
+        ASSIGN("glGetnUniformivARB", getnUniformiv);
+        ASSIGN("glGetnUniformuivARB", getnUniformuiv);
+        ASSIGN("glReadnPixelsARB", readnPixels);
+    }
+
+    if (extensions.count("GL_ARB_sample_shading") != 0)
+    {
+        ASSIGN("glMinSampleShadingARB", minSampleShading);
+    }
+
+    if (extensions.count("GL_ARB_sampler_objects") != 0)
+    {
+        ASSIGN("glBindSampler", bindSampler);
+        ASSIGN("glDeleteSamplers", deleteSamplers);
+        ASSIGN("glGenSamplers", genSamplers);
+        ASSIGN("glGetSamplerParameterIiv", getSamplerParameterIiv);
+        ASSIGN("glGetSamplerParameterIuiv", getSamplerParameterIuiv);
+        ASSIGN("glGetSamplerParameterfv", getSamplerParameterfv);
+        ASSIGN("glGetSamplerParameteriv", getSamplerParameteriv);
+        ASSIGN("glIsSampler", isSampler);
+        ASSIGN("glSamplerParameterIiv", samplerParameterIiv);
+        ASSIGN("glSamplerParameterIuiv", samplerParameterIuiv);
+        ASSIGN("glSamplerParameterf", samplerParameterf);
+        ASSIGN("glSamplerParameterfv", samplerParameterfv);
+        ASSIGN("glSamplerParameteri", samplerParameteri);
+        ASSIGN("glSamplerParameteriv", samplerParameteriv);
+    }
+
+    if (extensions.count("GL_ARB_separate_shader_objects") != 0)
+    {
+        ASSIGN("glActiveShaderProgram", activeShaderProgram);
+        ASSIGN("glBindProgramPipeline", bindProgramPipeline);
+        ASSIGN("glCreateShaderProgramv", createShaderProgramv);
+        ASSIGN("glDeleteProgramPipelines", deleteProgramPipelines);
+        ASSIGN("glGenProgramPipelines", genProgramPipelines);
+        ASSIGN("glGetProgramPipelineInfoLog", getProgramPipelineInfoLog);
+        ASSIGN("glGetProgramPipelineiv", getProgramPipelineiv);
+        ASSIGN("glIsProgramPipeline", isProgramPipeline);
+        ASSIGN("glProgramUniform1d", programUniform1d);
+        ASSIGN("glProgramUniform1dv", programUniform1dv);
+        ASSIGN("glProgramUniform1f", programUniform1f);
+        ASSIGN("glProgramUniform1fv", programUniform1fv);
+        ASSIGN("glProgramUniform1i", programUniform1i);
+        ASSIGN("glProgramUniform1iv", programUniform1iv);
+        ASSIGN("glProgramUniform1ui", programUniform1ui);
+        ASSIGN("glProgramUniform1uiv", programUniform1uiv);
+        ASSIGN("glProgramUniform2d", programUniform2d);
+        ASSIGN("glProgramUniform2dv", programUniform2dv);
+        ASSIGN("glProgramUniform2f", programUniform2f);
+        ASSIGN("glProgramUniform2fv", programUniform2fv);
+        ASSIGN("glProgramUniform2i", programUniform2i);
+        ASSIGN("glProgramUniform2iv", programUniform2iv);
+        ASSIGN("glProgramUniform2ui", programUniform2ui);
+        ASSIGN("glProgramUniform2uiv", programUniform2uiv);
+        ASSIGN("glProgramUniform3d", programUniform3d);
+        ASSIGN("glProgramUniform3dv", programUniform3dv);
+        ASSIGN("glProgramUniform3f", programUniform3f);
+        ASSIGN("glProgramUniform3fv", programUniform3fv);
+        ASSIGN("glProgramUniform3i", programUniform3i);
+        ASSIGN("glProgramUniform3iv", programUniform3iv);
+        ASSIGN("glProgramUniform3ui", programUniform3ui);
+        ASSIGN("glProgramUniform3uiv", programUniform3uiv);
+        ASSIGN("glProgramUniform4d", programUniform4d);
+        ASSIGN("glProgramUniform4dv", programUniform4dv);
+        ASSIGN("glProgramUniform4f", programUniform4f);
+        ASSIGN("glProgramUniform4fv", programUniform4fv);
+        ASSIGN("glProgramUniform4i", programUniform4i);
+        ASSIGN("glProgramUniform4iv", programUniform4iv);
+        ASSIGN("glProgramUniform4ui", programUniform4ui);
+        ASSIGN("glProgramUniform4uiv", programUniform4uiv);
+        ASSIGN("glProgramUniformMatrix2dv", programUniformMatrix2dv);
+        ASSIGN("glProgramUniformMatrix2fv", programUniformMatrix2fv);
+        ASSIGN("glProgramUniformMatrix2x3dv", programUniformMatrix2x3dv);
+        ASSIGN("glProgramUniformMatrix2x3fv", programUniformMatrix2x3fv);
+        ASSIGN("glProgramUniformMatrix2x4dv", programUniformMatrix2x4dv);
+        ASSIGN("glProgramUniformMatrix2x4fv", programUniformMatrix2x4fv);
+        ASSIGN("glProgramUniformMatrix3dv", programUniformMatrix3dv);
+        ASSIGN("glProgramUniformMatrix3fv", programUniformMatrix3fv);
+        ASSIGN("glProgramUniformMatrix3x2dv", programUniformMatrix3x2dv);
+        ASSIGN("glProgramUniformMatrix3x2fv", programUniformMatrix3x2fv);
+        ASSIGN("glProgramUniformMatrix3x4dv", programUniformMatrix3x4dv);
+        ASSIGN("glProgramUniformMatrix3x4fv", programUniformMatrix3x4fv);
+        ASSIGN("glProgramUniformMatrix4dv", programUniformMatrix4dv);
+        ASSIGN("glProgramUniformMatrix4fv", programUniformMatrix4fv);
+        ASSIGN("glProgramUniformMatrix4x2dv", programUniformMatrix4x2dv);
+        ASSIGN("glProgramUniformMatrix4x2fv", programUniformMatrix4x2fv);
+        ASSIGN("glProgramUniformMatrix4x3dv", programUniformMatrix4x3dv);
+        ASSIGN("glProgramUniformMatrix4x3fv", programUniformMatrix4x3fv);
+        ASSIGN("glUseProgramStages", useProgramStages);
+        ASSIGN("glValidateProgramPipeline", validateProgramPipeline);
+    }
+
+    if (extensions.count("GL_ARB_shader_atomic_counters") != 0)
+    {
+        ASSIGN("glGetActiveAtomicCounterBufferiv", getActiveAtomicCounterBufferiv);
+    }
+
+    if (extensions.count("GL_ARB_shader_image_load_store") != 0)
+    {
+        ASSIGN("glBindImageTexture", bindImageTexture);
+        ASSIGN("glMemoryBarrier", memoryBarrier);
+    }
+
+    if (extensions.count("GL_ARB_shader_objects") != 0)
+    {
+        ASSIGN("glCompileShaderARB", compileShader);
+        ASSIGN("glGetActiveUniformARB", getActiveUniform);
+        ASSIGN("glGetShaderSourceARB", getShaderSource);
+        ASSIGN("glGetUniformLocationARB", getUniformLocation);
+        ASSIGN("glGetUniformfvARB", getUniformfv);
+        ASSIGN("glGetUniformivARB", getUniformiv);
+        ASSIGN("glLinkProgramARB", linkProgram);
+        ASSIGN("glShaderSourceARB", shaderSource);
+        ASSIGN("glUniform1fARB", uniform1f);
+        ASSIGN("glUniform1fvARB", uniform1fv);
+        ASSIGN("glUniform1iARB", uniform1i);
+        ASSIGN("glUniform1ivARB", uniform1iv);
+        ASSIGN("glUniform2fARB", uniform2f);
+        ASSIGN("glUniform2fvARB", uniform2fv);
+        ASSIGN("glUniform2iARB", uniform2i);
+        ASSIGN("glUniform2ivARB", uniform2iv);
+        ASSIGN("glUniform3fARB", uniform3f);
+        ASSIGN("glUniform3fvARB", uniform3fv);
+        ASSIGN("glUniform3iARB", uniform3i);
+        ASSIGN("glUniform3ivARB", uniform3iv);
+        ASSIGN("glUniform4fARB", uniform4f);
+        ASSIGN("glUniform4fvARB", uniform4fv);
+        ASSIGN("glUniform4iARB", uniform4i);
+        ASSIGN("glUniform4ivARB", uniform4iv);
+        ASSIGN("glUniformMatrix2fvARB", uniformMatrix2fv);
+        ASSIGN("glUniformMatrix3fvARB", uniformMatrix3fv);
+        ASSIGN("glUniformMatrix4fvARB", uniformMatrix4fv);
+        ASSIGN("glValidateProgramARB", validateProgram);
+    }
+
+    if (extensions.count("GL_ARB_shader_storage_buffer_object") != 0)
+    {
+        ASSIGN("glShaderStorageBlockBinding", shaderStorageBlockBinding);
+    }
+
+    if (extensions.count("GL_ARB_shader_subroutine") != 0)
+    {
+        ASSIGN("glGetActiveSubroutineName", getActiveSubroutineName);
+        ASSIGN("glGetActiveSubroutineUniformName", getActiveSubroutineUniformName);
+        ASSIGN("glGetActiveSubroutineUniformiv", getActiveSubroutineUniformiv);
+        ASSIGN("glGetProgramStageiv", getProgramStageiv);
+        ASSIGN("glGetSubroutineIndex", getSubroutineIndex);
+        ASSIGN("glGetSubroutineUniformLocation", getSubroutineUniformLocation);
+        ASSIGN("glGetUniformSubroutineuiv", getUniformSubroutineuiv);
+        ASSIGN("glUniformSubroutinesuiv", uniformSubroutinesuiv);
+    }
+
+    if (extensions.count("GL_ARB_sync") != 0)
+    {
+        ASSIGN("glClientWaitSync", clientWaitSync);
+        ASSIGN("glDeleteSync", deleteSync);
+        ASSIGN("glFenceSync", fenceSync);
+        ASSIGN("glGetInteger64v", getInteger64v);
+        ASSIGN("glGetSynciv", getSynciv);
+        ASSIGN("glIsSync", isSync);
+        ASSIGN("glWaitSync", waitSync);
+    }
+
+    if (extensions.count("GL_ARB_tessellation_shader") != 0)
+    {
+        ASSIGN("glPatchParameterfv", patchParameterfv);
+        ASSIGN("glPatchParameteri", patchParameteri);
+    }
+
+    if (extensions.count("GL_ARB_texture_barrier") != 0)
+    {
+        ASSIGN("glTextureBarrier", textureBarrier);
+    }
+
+    if (extensions.count("GL_ARB_texture_buffer_object") != 0)
+    {
+        ASSIGN("glTexBufferARB", texBuffer);
+    }
+
+    if (extensions.count("GL_ARB_texture_buffer_range") != 0)
+    {
+        ASSIGN("glTexBufferRange", texBufferRange);
+    }
+
+    if (extensions.count("GL_ARB_texture_compression") != 0)
+    {
+        ASSIGN("glCompressedTexImage1DARB", compressedTexImage1D);
+        ASSIGN("glCompressedTexImage2DARB", compressedTexImage2D);
+        ASSIGN("glCompressedTexImage3DARB", compressedTexImage3D);
+        ASSIGN("glCompressedTexSubImage1DARB", compressedTexSubImage1D);
+        ASSIGN("glCompressedTexSubImage2DARB", compressedTexSubImage2D);
+        ASSIGN("glCompressedTexSubImage3DARB", compressedTexSubImage3D);
+        ASSIGN("glGetCompressedTexImageARB", getCompressedTexImage);
+    }
+
+    if (extensions.count("GL_ARB_texture_multisample") != 0)
+    {
+        ASSIGN("glGetMultisamplefv", getMultisamplefv);
+        ASSIGN("glSampleMaski", sampleMaski);
+        ASSIGN("glTexImage2DMultisample", texImage2DMultisample);
+        ASSIGN("glTexImage3DMultisample", texImage3DMultisample);
+    }
+
+    if (extensions.count("GL_ARB_texture_storage") != 0)
+    {
+        ASSIGN("glTexStorage1D", texStorage1D);
+        ASSIGN("glTexStorage2D", texStorage2D);
+        ASSIGN("glTexStorage3D", texStorage3D);
+    }
+
+    if (extensions.count("GL_ARB_texture_storage_multisample") != 0)
+    {
+        ASSIGN("glTexStorage2DMultisample", texStorage2DMultisample);
+        ASSIGN("glTexStorage3DMultisample", texStorage3DMultisample);
+    }
+
+    if (extensions.count("GL_ARB_texture_view") != 0)
+    {
+        ASSIGN("glTextureView", textureView);
+    }
+
+    if (extensions.count("GL_ARB_timer_query") != 0)
+    {
+        ASSIGN("glGetQueryObjecti64v", getQueryObjecti64v);
+        ASSIGN("glGetQueryObjectui64v", getQueryObjectui64v);
+        ASSIGN("glQueryCounter", queryCounter);
+    }
+
+    if (extensions.count("GL_ARB_transform_feedback2") != 0)
+    {
+        ASSIGN("glBindTransformFeedback", bindTransformFeedback);
+        ASSIGN("glDeleteTransformFeedbacks", deleteTransformFeedbacks);
+        ASSIGN("glDrawTransformFeedback", drawTransformFeedback);
+        ASSIGN("glGenTransformFeedbacks", genTransformFeedbacks);
+        ASSIGN("glIsTransformFeedback", isTransformFeedback);
+        ASSIGN("glPauseTransformFeedback", pauseTransformFeedback);
+        ASSIGN("glResumeTransformFeedback", resumeTransformFeedback);
+    }
+
+    if (extensions.count("GL_ARB_transform_feedback3") != 0)
+    {
+        ASSIGN("glBeginQueryIndexed", beginQueryIndexed);
+        ASSIGN("glDrawTransformFeedbackStream", drawTransformFeedbackStream);
+        ASSIGN("glEndQueryIndexed", endQueryIndexed);
+        ASSIGN("glGetQueryIndexediv", getQueryIndexediv);
+    }
+
+    if (extensions.count("GL_ARB_transform_feedback_instanced") != 0)
+    {
+        ASSIGN("glDrawTransformFeedbackInstanced", drawTransformFeedbackInstanced);
+        ASSIGN("glDrawTransformFeedbackStreamInstanced", drawTransformFeedbackStreamInstanced);
+    }
+
+    if (extensions.count("GL_ARB_uniform_buffer_object") != 0)
+    {
+        ASSIGN("glBindBufferBase", bindBufferBase);
+        ASSIGN("glBindBufferRange", bindBufferRange);
+        ASSIGN("glGetActiveUniformBlockName", getActiveUniformBlockName);
+        ASSIGN("glGetActiveUniformBlockiv", getActiveUniformBlockiv);
+        ASSIGN("glGetActiveUniformName", getActiveUniformName);
+        ASSIGN("glGetActiveUniformsiv", getActiveUniformsiv);
+        ASSIGN("glGetIntegeri_v", getIntegeri_v);
+        ASSIGN("glGetUniformBlockIndex", getUniformBlockIndex);
+        ASSIGN("glGetUniformIndices", getUniformIndices);
+        ASSIGN("glUniformBlockBinding", uniformBlockBinding);
+    }
+
+    if (extensions.count("GL_ARB_vertex_array_object") != 0)
+    {
+        ASSIGN("glBindVertexArray", bindVertexArray);
+        ASSIGN("glDeleteVertexArrays", deleteVertexArrays);
+        ASSIGN("glGenVertexArrays", genVertexArrays);
+        ASSIGN("glIsVertexArray", isVertexArray);
+    }
+
+    if (extensions.count("GL_ARB_vertex_attrib_64bit") != 0)
+    {
+        ASSIGN("glGetVertexAttribLdv", getVertexAttribLdv);
+        ASSIGN("glVertexAttribL1d", vertexAttribL1d);
+        ASSIGN("glVertexAttribL1dv", vertexAttribL1dv);
+        ASSIGN("glVertexAttribL2d", vertexAttribL2d);
+        ASSIGN("glVertexAttribL2dv", vertexAttribL2dv);
+        ASSIGN("glVertexAttribL3d", vertexAttribL3d);
+        ASSIGN("glVertexAttribL3dv", vertexAttribL3dv);
+        ASSIGN("glVertexAttribL4d", vertexAttribL4d);
+        ASSIGN("glVertexAttribL4dv", vertexAttribL4dv);
+        ASSIGN("glVertexAttribLPointer", vertexAttribLPointer);
+    }
+
+    if (extensions.count("GL_ARB_vertex_attrib_binding") != 0)
+    {
+        ASSIGN("glBindVertexBuffer", bindVertexBuffer);
+        ASSIGN("glVertexAttribBinding", vertexAttribBinding);
+        ASSIGN("glVertexAttribFormat", vertexAttribFormat);
+        ASSIGN("glVertexAttribIFormat", vertexAttribIFormat);
+        ASSIGN("glVertexAttribLFormat", vertexAttribLFormat);
+        ASSIGN("glVertexBindingDivisor", vertexBindingDivisor);
+    }
+
+    if (extensions.count("GL_ARB_vertex_buffer_object") != 0)
+    {
+        ASSIGN("glBindBufferARB", bindBuffer);
+        ASSIGN("glBufferDataARB", bufferData);
+        ASSIGN("glBufferSubDataARB", bufferSubData);
+        ASSIGN("glDeleteBuffersARB", deleteBuffers);
+        ASSIGN("glGenBuffersARB", genBuffers);
+        ASSIGN("glGetBufferParameterivARB", getBufferParameteriv);
+        ASSIGN("glGetBufferPointervARB", getBufferPointerv);
+        ASSIGN("glGetBufferSubDataARB", getBufferSubData);
+        ASSIGN("glIsBufferARB", isBuffer);
+        ASSIGN("glMapBufferARB", mapBuffer);
+        ASSIGN("glUnmapBufferARB", unmapBuffer);
+    }
+
+    if (extensions.count("GL_ARB_vertex_program") != 0)
+    {
+        ASSIGN("glDisableVertexAttribArrayARB", disableVertexAttribArray);
+        ASSIGN("glEnableVertexAttribArrayARB", enableVertexAttribArray);
+        ASSIGN("glGetProgramivARB", getProgramiv);
+        ASSIGN("glGetVertexAttribPointervARB", getVertexAttribPointerv);
+        ASSIGN("glGetVertexAttribdvARB", getVertexAttribdv);
+        ASSIGN("glGetVertexAttribfvARB", getVertexAttribfv);
+        ASSIGN("glGetVertexAttribivARB", getVertexAttribiv);
+        ASSIGN("glIsProgramARB", isProgram);
+        ASSIGN("glVertexAttrib1dARB", vertexAttrib1d);
+        ASSIGN("glVertexAttrib1dvARB", vertexAttrib1dv);
+        ASSIGN("glVertexAttrib1fARB", vertexAttrib1f);
+        ASSIGN("glVertexAttrib1fvARB", vertexAttrib1fv);
+        ASSIGN("glVertexAttrib1sARB", vertexAttrib1s);
+        ASSIGN("glVertexAttrib1svARB", vertexAttrib1sv);
+        ASSIGN("glVertexAttrib2dARB", vertexAttrib2d);
+        ASSIGN("glVertexAttrib2dvARB", vertexAttrib2dv);
+        ASSIGN("glVertexAttrib2fARB", vertexAttrib2f);
+        ASSIGN("glVertexAttrib2fvARB", vertexAttrib2fv);
+        ASSIGN("glVertexAttrib2sARB", vertexAttrib2s);
+        ASSIGN("glVertexAttrib2svARB", vertexAttrib2sv);
+        ASSIGN("glVertexAttrib3dARB", vertexAttrib3d);
+        ASSIGN("glVertexAttrib3dvARB", vertexAttrib3dv);
+        ASSIGN("glVertexAttrib3fARB", vertexAttrib3f);
+        ASSIGN("glVertexAttrib3fvARB", vertexAttrib3fv);
+        ASSIGN("glVertexAttrib3sARB", vertexAttrib3s);
+        ASSIGN("glVertexAttrib3svARB", vertexAttrib3sv);
+        ASSIGN("glVertexAttrib4NbvARB", vertexAttrib4Nbv);
+        ASSIGN("glVertexAttrib4NivARB", vertexAttrib4Niv);
+        ASSIGN("glVertexAttrib4NsvARB", vertexAttrib4Nsv);
+        ASSIGN("glVertexAttrib4NubARB", vertexAttrib4Nub);
+        ASSIGN("glVertexAttrib4NubvARB", vertexAttrib4Nubv);
+        ASSIGN("glVertexAttrib4NuivARB", vertexAttrib4Nuiv);
+        ASSIGN("glVertexAttrib4NusvARB", vertexAttrib4Nusv);
+        ASSIGN("glVertexAttrib4bvARB", vertexAttrib4bv);
+        ASSIGN("glVertexAttrib4dARB", vertexAttrib4d);
+        ASSIGN("glVertexAttrib4dvARB", vertexAttrib4dv);
+        ASSIGN("glVertexAttrib4fARB", vertexAttrib4f);
+        ASSIGN("glVertexAttrib4fvARB", vertexAttrib4fv);
+        ASSIGN("glVertexAttrib4ivARB", vertexAttrib4iv);
+        ASSIGN("glVertexAttrib4sARB", vertexAttrib4s);
+        ASSIGN("glVertexAttrib4svARB", vertexAttrib4sv);
+        ASSIGN("glVertexAttrib4ubvARB", vertexAttrib4ubv);
+        ASSIGN("glVertexAttrib4uivARB", vertexAttrib4uiv);
+        ASSIGN("glVertexAttrib4usvARB", vertexAttrib4usv);
+        ASSIGN("glVertexAttribPointerARB", vertexAttribPointer);
+    }
+
+    if (extensions.count("GL_ARB_vertex_shader") != 0)
+    {
+        ASSIGN("glBindAttribLocationARB", bindAttribLocation);
+        ASSIGN("glDisableVertexAttribArrayARB", disableVertexAttribArray);
+        ASSIGN("glEnableVertexAttribArrayARB", enableVertexAttribArray);
+        ASSIGN("glGetActiveAttribARB", getActiveAttrib);
+        ASSIGN("glGetAttribLocationARB", getAttribLocation);
+        ASSIGN("glGetVertexAttribPointervARB", getVertexAttribPointerv);
+        ASSIGN("glGetVertexAttribdvARB", getVertexAttribdv);
+        ASSIGN("glGetVertexAttribfvARB", getVertexAttribfv);
+        ASSIGN("glGetVertexAttribivARB", getVertexAttribiv);
+        ASSIGN("glVertexAttrib1dARB", vertexAttrib1d);
+        ASSIGN("glVertexAttrib1dvARB", vertexAttrib1dv);
+        ASSIGN("glVertexAttrib1fARB", vertexAttrib1f);
+        ASSIGN("glVertexAttrib1fvARB", vertexAttrib1fv);
+        ASSIGN("glVertexAttrib1sARB", vertexAttrib1s);
+        ASSIGN("glVertexAttrib1svARB", vertexAttrib1sv);
+        ASSIGN("glVertexAttrib2dARB", vertexAttrib2d);
+        ASSIGN("glVertexAttrib2dvARB", vertexAttrib2dv);
+        ASSIGN("glVertexAttrib2fARB", vertexAttrib2f);
+        ASSIGN("glVertexAttrib2fvARB", vertexAttrib2fv);
+        ASSIGN("glVertexAttrib2sARB", vertexAttrib2s);
+        ASSIGN("glVertexAttrib2svARB", vertexAttrib2sv);
+        ASSIGN("glVertexAttrib3dARB", vertexAttrib3d);
+        ASSIGN("glVertexAttrib3dvARB", vertexAttrib3dv);
+        ASSIGN("glVertexAttrib3fARB", vertexAttrib3f);
+        ASSIGN("glVertexAttrib3fvARB", vertexAttrib3fv);
+        ASSIGN("glVertexAttrib3sARB", vertexAttrib3s);
+        ASSIGN("glVertexAttrib3svARB", vertexAttrib3sv);
+        ASSIGN("glVertexAttrib4NbvARB", vertexAttrib4Nbv);
+        ASSIGN("glVertexAttrib4NivARB", vertexAttrib4Niv);
+        ASSIGN("glVertexAttrib4NsvARB", vertexAttrib4Nsv);
+        ASSIGN("glVertexAttrib4NubARB", vertexAttrib4Nub);
+        ASSIGN("glVertexAttrib4NubvARB", vertexAttrib4Nubv);
+        ASSIGN("glVertexAttrib4NuivARB", vertexAttrib4Nuiv);
+        ASSIGN("glVertexAttrib4NusvARB", vertexAttrib4Nusv);
+        ASSIGN("glVertexAttrib4bvARB", vertexAttrib4bv);
+        ASSIGN("glVertexAttrib4dARB", vertexAttrib4d);
+        ASSIGN("glVertexAttrib4dvARB", vertexAttrib4dv);
+        ASSIGN("glVertexAttrib4fARB", vertexAttrib4f);
+        ASSIGN("glVertexAttrib4fvARB", vertexAttrib4fv);
+        ASSIGN("glVertexAttrib4ivARB", vertexAttrib4iv);
+        ASSIGN("glVertexAttrib4sARB", vertexAttrib4s);
+        ASSIGN("glVertexAttrib4svARB", vertexAttrib4sv);
+        ASSIGN("glVertexAttrib4ubvARB", vertexAttrib4ubv);
+        ASSIGN("glVertexAttrib4uivARB", vertexAttrib4uiv);
+        ASSIGN("glVertexAttrib4usvARB", vertexAttrib4usv);
+        ASSIGN("glVertexAttribPointerARB", vertexAttribPointer);
+    }
+
+    if (extensions.count("GL_ARB_vertex_type_2_10_10_10_rev") != 0)
+    {
+        ASSIGN("glVertexAttribP1ui", vertexAttribP1ui);
+        ASSIGN("glVertexAttribP1uiv", vertexAttribP1uiv);
+        ASSIGN("glVertexAttribP2ui", vertexAttribP2ui);
+        ASSIGN("glVertexAttribP2uiv", vertexAttribP2uiv);
+        ASSIGN("glVertexAttribP3ui", vertexAttribP3ui);
+        ASSIGN("glVertexAttribP3uiv", vertexAttribP3uiv);
+        ASSIGN("glVertexAttribP4ui", vertexAttribP4ui);
+        ASSIGN("glVertexAttribP4uiv", vertexAttribP4uiv);
+    }
+
+    if (extensions.count("GL_ARB_viewport_array") != 0)
+    {
+        ASSIGN("glDepthRangeArrayv", depthRangeArrayv);
+        ASSIGN("glDepthRangeIndexed", depthRangeIndexed);
+        ASSIGN("glGetDoublei_v", getDoublei_v);
+        ASSIGN("glGetFloati_v", getFloati_v);
+        ASSIGN("glScissorArrayv", scissorArrayv);
+        ASSIGN("glScissorIndexed", scissorIndexed);
+        ASSIGN("glScissorIndexedv", scissorIndexedv);
+        ASSIGN("glViewportArrayv", viewportArrayv);
+        ASSIGN("glViewportIndexedf", viewportIndexedf);
+        ASSIGN("glViewportIndexedfv", viewportIndexedfv);
+    }
+
+    if (extensions.count("GL_EXT_blend_color") != 0)
+    {
+        ASSIGN("glBlendColorEXT", blendColor);
+    }
+
+    if (extensions.count("GL_EXT_blend_equation_separate") != 0)
+    {
+        ASSIGN("glBlendEquationSeparateEXT", blendEquationSeparate);
+    }
+
+    if (extensions.count("GL_EXT_blend_func_separate") != 0)
+    {
+        ASSIGN("glBlendFuncSeparateEXT", blendFuncSeparate);
+    }
+
+    if (extensions.count("GL_EXT_copy_texture") != 0)
+    {
+        ASSIGN("glCopyTexImage1DEXT", copyTexImage1D);
+        ASSIGN("glCopyTexImage2DEXT", copyTexImage2D);
+        ASSIGN("glCopyTexSubImage1DEXT", copyTexSubImage1D);
+        ASSIGN("glCopyTexSubImage2DEXT", copyTexSubImage2D);
+        ASSIGN("glCopyTexSubImage3DEXT", copyTexSubImage3D);
+    }
+
+    if (extensions.count("GL_EXT_direct_state_access") != 0)
+    {
+        ASSIGN("glCheckNamedFramebufferStatusEXT", checkNamedFramebufferStatus);
+        ASSIGN("glClearNamedBufferDataEXT", clearNamedBufferData);
+        ASSIGN("glClearNamedBufferSubDataEXT", clearNamedBufferSubData);
+        ASSIGN("glCompressedTextureSubImage1DEXT", compressedTextureSubImage1D);
+        ASSIGN("glCompressedTextureSubImage2DEXT", compressedTextureSubImage2D);
+        ASSIGN("glCompressedTextureSubImage3DEXT", compressedTextureSubImage3D);
+        ASSIGN("glCopyTextureSubImage1DEXT", copyTextureSubImage1D);
+        ASSIGN("glCopyTextureSubImage2DEXT", copyTextureSubImage2D);
+        ASSIGN("glCopyTextureSubImage3DEXT", copyTextureSubImage3D);
+        ASSIGN("glDisableVertexArrayAttribEXT", disableVertexArrayAttrib);
+        ASSIGN("glEnableVertexArrayAttribEXT", enableVertexArrayAttrib);
+        ASSIGN("glFlushMappedNamedBufferRangeEXT", flushMappedNamedBufferRange);
+        ASSIGN("glGenerateTextureMipmapEXT", generateTextureMipmap);
+        ASSIGN("glGetCompressedTextureImageEXT", getCompressedTextureImage);
+        ASSIGN("glGetDoublei_vEXT", getDoublei_v);
+        ASSIGN("glGetFloati_vEXT", getFloati_v);
+        ASSIGN("glGetFramebufferParameterivEXT", getFramebufferParameteriv);
+        ASSIGN("glGetNamedBufferParameterivEXT", getNamedBufferParameteriv);
+        ASSIGN("glGetNamedBufferPointervEXT", getNamedBufferPointerv);
+        ASSIGN("glGetNamedBufferSubDataEXT", getNamedBufferSubData);
+        ASSIGN("glGetNamedFramebufferAttachmentParameterivEXT",
+               getNamedFramebufferAttachmentParameteriv);
+        ASSIGN("glGetNamedFramebufferParameterivEXT", getNamedFramebufferParameteriv);
+        ASSIGN("glGetNamedRenderbufferParameterivEXT", getNamedRenderbufferParameteriv);
+        ASSIGN("glGetTextureImageEXT", getTextureImage);
+        ASSIGN("glGetTextureLevelParameterfvEXT", getTextureLevelParameterfv);
+        ASSIGN("glGetTextureLevelParameterivEXT", getTextureLevelParameteriv);
+        ASSIGN("glGetTextureParameterIivEXT", getTextureParameterIiv);
+        ASSIGN("glGetTextureParameterIuivEXT", getTextureParameterIuiv);
+        ASSIGN("glGetTextureParameterfvEXT", getTextureParameterfv);
+        ASSIGN("glGetTextureParameterivEXT", getTextureParameteriv);
+        ASSIGN("glMapNamedBufferEXT", mapNamedBuffer);
+        ASSIGN("glMapNamedBufferRangeEXT", mapNamedBufferRange);
+        ASSIGN("glNamedBufferDataEXT", namedBufferData);
+        ASSIGN("glNamedBufferStorageEXT", namedBufferStorage);
+        ASSIGN("glNamedBufferSubDataEXT", namedBufferSubData);
+        ASSIGN("glNamedFramebufferParameteriEXT", namedFramebufferParameteri);
+        ASSIGN("glNamedFramebufferRenderbufferEXT", namedFramebufferRenderbuffer);
+        ASSIGN("glNamedFramebufferTextureEXT", namedFramebufferTexture);
+        ASSIGN("glNamedFramebufferTextureLayerEXT", namedFramebufferTextureLayer);
+        ASSIGN("glNamedRenderbufferStorageEXT", namedRenderbufferStorage);
+        ASSIGN("glNamedRenderbufferStorageMultisampleEXT", namedRenderbufferStorageMultisample);
+        ASSIGN("glProgramUniform1dEXT", programUniform1d);
+        ASSIGN("glProgramUniform1dvEXT", programUniform1dv);
+        ASSIGN("glProgramUniform2dEXT", programUniform2d);
+        ASSIGN("glProgramUniform2dvEXT", programUniform2dv);
+        ASSIGN("glProgramUniform3dEXT", programUniform3d);
+        ASSIGN("glProgramUniform3dvEXT", programUniform3dv);
+        ASSIGN("glProgramUniform4dEXT", programUniform4d);
+        ASSIGN("glProgramUniform4dvEXT", programUniform4dv);
+        ASSIGN("glProgramUniformMatrix2dvEXT", programUniformMatrix2dv);
+        ASSIGN("glProgramUniformMatrix2x3dvEXT", programUniformMatrix2x3dv);
+        ASSIGN("glProgramUniformMatrix2x4dvEXT", programUniformMatrix2x4dv);
+        ASSIGN("glProgramUniformMatrix3dvEXT", programUniformMatrix3dv);
+        ASSIGN("glProgramUniformMatrix3x2dvEXT", programUniformMatrix3x2dv);
+        ASSIGN("glProgramUniformMatrix3x4dvEXT", programUniformMatrix3x4dv);
+        ASSIGN("glProgramUniformMatrix4dvEXT", programUniformMatrix4dv);
+        ASSIGN("glProgramUniformMatrix4x2dvEXT", programUniformMatrix4x2dv);
+        ASSIGN("glProgramUniformMatrix4x3dvEXT", programUniformMatrix4x3dv);
+        ASSIGN("glTextureBufferEXT", textureBuffer);
+        ASSIGN("glTextureBufferRangeEXT", textureBufferRange);
+        ASSIGN("glTextureParameterIivEXT", textureParameterIiv);
+        ASSIGN("glTextureParameterIuivEXT", textureParameterIuiv);
+        ASSIGN("glTextureParameterfEXT", textureParameterf);
+        ASSIGN("glTextureParameterfvEXT", textureParameterfv);
+        ASSIGN("glTextureParameteriEXT", textureParameteri);
+        ASSIGN("glTextureParameterivEXT", textureParameteriv);
+        ASSIGN("glTextureStorage1DEXT", textureStorage1D);
+        ASSIGN("glTextureStorage2DEXT", textureStorage2D);
+        ASSIGN("glTextureStorage2DMultisampleEXT", textureStorage2DMultisample);
+        ASSIGN("glTextureStorage3DEXT", textureStorage3D);
+        ASSIGN("glTextureStorage3DMultisampleEXT", textureStorage3DMultisample);
+        ASSIGN("glTextureSubImage1DEXT", textureSubImage1D);
+        ASSIGN("glTextureSubImage2DEXT", textureSubImage2D);
+        ASSIGN("glTextureSubImage3DEXT", textureSubImage3D);
+        ASSIGN("glUnmapNamedBufferEXT", unmapNamedBuffer);
+    }
+
+    if (extensions.count("GL_EXT_draw_range_elements") != 0)
+    {
+        ASSIGN("glDrawRangeElementsEXT", drawRangeElements);
+    }
+
+    if (extensions.count("GL_EXT_framebuffer_blit") != 0)
+    {
+        ASSIGN("glBlitFramebufferEXT", blitFramebuffer);
+    }
+
+    if (extensions.count("GL_EXT_framebuffer_multisample") != 0)
+    {
+        ASSIGN("glRenderbufferStorageMultisampleEXT", renderbufferStorageMultisample);
+    }
+
+    if (extensions.count("GL_EXT_framebuffer_object") != 0)
+    {
+        ASSIGN("glBindFramebufferEXT", bindFramebuffer);
+        ASSIGN("glBindRenderbufferEXT", bindRenderbuffer);
+        ASSIGN("glCheckFramebufferStatusEXT", checkFramebufferStatus);
+        ASSIGN("glDeleteFramebuffersEXT", deleteFramebuffers);
+        ASSIGN("glDeleteRenderbuffersEXT", deleteRenderbuffers);
+        ASSIGN("glFramebufferRenderbufferEXT", framebufferRenderbuffer);
+        ASSIGN("glFramebufferTexture1DEXT", framebufferTexture1D);
+        ASSIGN("glFramebufferTexture2DEXT", framebufferTexture2D);
+        ASSIGN("glFramebufferTexture3DEXT", framebufferTexture3D);
+        ASSIGN("glGenFramebuffersEXT", genFramebuffers);
+        ASSIGN("glGenRenderbuffersEXT", genRenderbuffers);
+        ASSIGN("glGenerateMipmapEXT", generateMipmap);
+        ASSIGN("glGetFramebufferAttachmentParameterivEXT", getFramebufferAttachmentParameteriv);
+        ASSIGN("glGetRenderbufferParameterivEXT", getRenderbufferParameteriv);
+        ASSIGN("glIsFramebufferEXT", isFramebuffer);
+        ASSIGN("glIsRenderbufferEXT", isRenderbuffer);
+        ASSIGN("glRenderbufferStorageEXT", renderbufferStorage);
+    }
+
+    if (extensions.count("GL_EXT_gpu_shader4") != 0)
+    {
+        ASSIGN("glBindFragDataLocationEXT", bindFragDataLocation);
+        ASSIGN("glGetFragDataLocationEXT", getFragDataLocation);
+        ASSIGN("glGetUniformuivEXT", getUniformuiv);
+        ASSIGN("glUniform1uiEXT", uniform1ui);
+        ASSIGN("glUniform1uivEXT", uniform1uiv);
+        ASSIGN("glUniform2uiEXT", uniform2ui);
+        ASSIGN("glUniform2uivEXT", uniform2uiv);
+        ASSIGN("glUniform3uiEXT", uniform3ui);
+        ASSIGN("glUniform3uivEXT", uniform3uiv);
+        ASSIGN("glUniform4uiEXT", uniform4ui);
+        ASSIGN("glUniform4uivEXT", uniform4uiv);
+    }
+
+    if (extensions.count("GL_EXT_point_parameters") != 0)
+    {
+        ASSIGN("glPointParameterfEXT", pointParameterf);
+        ASSIGN("glPointParameterfvEXT", pointParameterfv);
+    }
+
+    if (extensions.count("GL_EXT_polygon_offset") != 0)
+    {
+        ASSIGN("glPolygonOffsetEXT", polygonOffset);
+    }
+
+    if (extensions.count("GL_EXT_provoking_vertex") != 0)
+    {
+        ASSIGN("glProvokingVertexEXT", provokingVertex);
+    }
+
+    if (extensions.count("GL_EXT_shader_image_load_store") != 0)
+    {
+        ASSIGN("glBindImageTextureEXT", bindImageTexture);
+        ASSIGN("glMemoryBarrierEXT", memoryBarrier);
+    }
+
+    if (extensions.count("GL_EXT_subtexture") != 0)
+    {
+        ASSIGN("glTexSubImage1DEXT", texSubImage1D);
+        ASSIGN("glTexSubImage2DEXT", texSubImage2D);
+    }
+
+    if (extensions.count("GL_EXT_texture3D") != 0)
+    {
+        ASSIGN("glTexImage3DEXT", texImage3D);
+        ASSIGN("glTexSubImage3DEXT", texSubImage3D);
+    }
+
+    if (extensions.count("GL_EXT_texture_array") != 0)
+    {
+        ASSIGN("glFramebufferTextureLayerEXT", framebufferTextureLayer);
+    }
+
+    if (extensions.count("GL_EXT_texture_buffer_object") != 0)
+    {
+        ASSIGN("glTexBufferEXT", texBuffer);
+    }
+
+    if (extensions.count("GL_EXT_texture_integer") != 0)
+    {
+        ASSIGN("glGetTexParameterIivEXT", getTexParameterIiv);
+        ASSIGN("glGetTexParameterIuivEXT", getTexParameterIuiv);
+        ASSIGN("glTexParameterIivEXT", texParameterIiv);
+        ASSIGN("glTexParameterIuivEXT", texParameterIuiv);
+    }
+
+    if (extensions.count("GL_EXT_texture_object") != 0)
+    {
+        ASSIGN("glBindTextureEXT", bindTexture);
+        ASSIGN("glDeleteTexturesEXT", deleteTextures);
+        ASSIGN("glGenTexturesEXT", genTextures);
+        ASSIGN("glIsTextureEXT", isTexture);
+    }
+
+    if (extensions.count("GL_EXT_timer_query") != 0)
+    {
+        ASSIGN("glGetQueryObjecti64vEXT", getQueryObjecti64v);
+        ASSIGN("glGetQueryObjectui64vEXT", getQueryObjectui64v);
+    }
+
+    if (extensions.count("GL_EXT_transform_feedback") != 0)
+    {
+        ASSIGN("glBeginTransformFeedbackEXT", beginTransformFeedback);
+        ASSIGN("glBindBufferBaseEXT", bindBufferBase);
+        ASSIGN("glBindBufferRangeEXT", bindBufferRange);
+        ASSIGN("glEndTransformFeedbackEXT", endTransformFeedback);
+        ASSIGN("glGetTransformFeedbackVaryingEXT", getTransformFeedbackVarying);
+        ASSIGN("glTransformFeedbackVaryingsEXT", transformFeedbackVaryings);
+    }
+
+    if (extensions.count("GL_EXT_vertex_array") != 0)
+    {
+        ASSIGN("glDrawArraysEXT", drawArrays);
+        ASSIGN("glGetPointervEXT", getPointerv);
+    }
+
+    if (extensions.count("GL_EXT_vertex_attrib_64bit") != 0)
+    {
+        ASSIGN("glGetVertexAttribLdvEXT", getVertexAttribLdv);
+        ASSIGN("glVertexAttribL1dEXT", vertexAttribL1d);
+        ASSIGN("glVertexAttribL1dvEXT", vertexAttribL1dv);
+        ASSIGN("glVertexAttribL2dEXT", vertexAttribL2d);
+        ASSIGN("glVertexAttribL2dvEXT", vertexAttribL2dv);
+        ASSIGN("glVertexAttribL3dEXT", vertexAttribL3d);
+        ASSIGN("glVertexAttribL3dvEXT", vertexAttribL3dv);
+        ASSIGN("glVertexAttribL4dEXT", vertexAttribL4d);
+        ASSIGN("glVertexAttribL4dvEXT", vertexAttribL4dv);
+        ASSIGN("glVertexAttribLPointerEXT", vertexAttribLPointer);
+    }
+
+    if (extensions.count("GL_KHR_debug") != 0)
+    {
+        ASSIGN("glDebugMessageCallback", debugMessageCallback);
+        ASSIGN("glDebugMessageControl", debugMessageControl);
+        ASSIGN("glDebugMessageInsert", debugMessageInsert);
+        ASSIGN("glGetDebugMessageLog", getDebugMessageLog);
+        ASSIGN("glGetObjectLabel", getObjectLabel);
+        ASSIGN("glGetObjectPtrLabel", getObjectPtrLabel);
+        ASSIGN("glGetPointerv", getPointerv);
+        ASSIGN("glObjectLabel", objectLabel);
+        ASSIGN("glObjectPtrLabel", objectPtrLabel);
+        ASSIGN("glPopDebugGroup", popDebugGroup);
+        ASSIGN("glPushDebugGroup", pushDebugGroup);
+    }
+
+    if (extensions.count("GL_KHR_robustness") != 0)
+    {
+        ASSIGN("glGetGraphicsResetStatus", getGraphicsResetStatus);
+        ASSIGN("glGetnUniformfv", getnUniformfv);
+        ASSIGN("glGetnUniformiv", getnUniformiv);
+        ASSIGN("glGetnUniformuiv", getnUniformuiv);
+        ASSIGN("glReadnPixels", readnPixels);
+    }
+
+    if (extensions.count("GL_NV_geometry_program4") != 0)
+    {
+        ASSIGN("glFramebufferTextureEXT", framebufferTexture);
+        ASSIGN("glFramebufferTextureLayerEXT", framebufferTextureLayer);
+    }
+
+    if (extensions.count("GL_NV_vertex_program4") != 0)
+    {
+        ASSIGN("glGetVertexAttribIivEXT", getVertexAttribIiv);
+        ASSIGN("glGetVertexAttribIuivEXT", getVertexAttribIuiv);
+        ASSIGN("glVertexAttribI1iEXT", vertexAttribI1i);
+        ASSIGN("glVertexAttribI1ivEXT", vertexAttribI1iv);
+        ASSIGN("glVertexAttribI1uiEXT", vertexAttribI1ui);
+        ASSIGN("glVertexAttribI1uivEXT", vertexAttribI1uiv);
+        ASSIGN("glVertexAttribI2iEXT", vertexAttribI2i);
+        ASSIGN("glVertexAttribI2ivEXT", vertexAttribI2iv);
+        ASSIGN("glVertexAttribI2uiEXT", vertexAttribI2ui);
+        ASSIGN("glVertexAttribI2uivEXT", vertexAttribI2uiv);
+        ASSIGN("glVertexAttribI3iEXT", vertexAttribI3i);
+        ASSIGN("glVertexAttribI3ivEXT", vertexAttribI3iv);
+        ASSIGN("glVertexAttribI3uiEXT", vertexAttribI3ui);
+        ASSIGN("glVertexAttribI3uivEXT", vertexAttribI3uiv);
+        ASSIGN("glVertexAttribI4bvEXT", vertexAttribI4bv);
+        ASSIGN("glVertexAttribI4iEXT", vertexAttribI4i);
+        ASSIGN("glVertexAttribI4ivEXT", vertexAttribI4iv);
+        ASSIGN("glVertexAttribI4svEXT", vertexAttribI4sv);
+        ASSIGN("glVertexAttribI4ubvEXT", vertexAttribI4ubv);
+        ASSIGN("glVertexAttribI4uiEXT", vertexAttribI4ui);
+        ASSIGN("glVertexAttribI4uivEXT", vertexAttribI4uiv);
+        ASSIGN("glVertexAttribI4usvEXT", vertexAttribI4usv);
+        ASSIGN("glVertexAttribIPointerEXT", vertexAttribIPointer);
+    }
+
+    if (extensions.count("GL_OES_single_precision") != 0)
+    {
+        ASSIGN("glClearDepthfOES", clearDepthf);
+        ASSIGN("glDepthRangefOES", depthRangef);
+    }
+}
+
+void DispatchTableGL::initProcsGLES(const gl::Version &version,
+                                    const std::set<std::string> &extensions)
+{
+    if (version >= gl::Version(2, 0))
+    {
+        ASSIGN("glActiveTexture", activeTexture);
+        ASSIGN("glAttachShader", attachShader);
+        ASSIGN("glBindAttribLocation", bindAttribLocation);
+        ASSIGN("glBindBuffer", bindBuffer);
+        ASSIGN("glBindFramebuffer", bindFramebuffer);
+        ASSIGN("glBindRenderbuffer", bindRenderbuffer);
+        ASSIGN("glBindTexture", bindTexture);
+        ASSIGN("glBlendColor", blendColor);
+        ASSIGN("glBlendEquation", blendEquation);
+        ASSIGN("glBlendEquationSeparate", blendEquationSeparate);
+        ASSIGN("glBlendFunc", blendFunc);
+        ASSIGN("glBlendFuncSeparate", blendFuncSeparate);
+        ASSIGN("glBufferData", bufferData);
+        ASSIGN("glBufferSubData", bufferSubData);
+        ASSIGN("glCheckFramebufferStatus", checkFramebufferStatus);
+        ASSIGN("glClear", clear);
+        ASSIGN("glClearColor", clearColor);
+        ASSIGN("glClearDepthf", clearDepthf);
+        ASSIGN("glClearStencil", clearStencil);
+        ASSIGN("glColorMask", colorMask);
+        ASSIGN("glCompileShader", compileShader);
+        ASSIGN("glCompressedTexImage2D", compressedTexImage2D);
+        ASSIGN("glCompressedTexSubImage2D", compressedTexSubImage2D);
+        ASSIGN("glCopyTexImage2D", copyTexImage2D);
+        ASSIGN("glCopyTexSubImage2D", copyTexSubImage2D);
+        ASSIGN("glCreateProgram", createProgram);
+        ASSIGN("glCreateShader", createShader);
+        ASSIGN("glCullFace", cullFace);
+        ASSIGN("glDeleteBuffers", deleteBuffers);
+        ASSIGN("glDeleteFramebuffers", deleteFramebuffers);
+        ASSIGN("glDeleteProgram", deleteProgram);
+        ASSIGN("glDeleteRenderbuffers", deleteRenderbuffers);
+        ASSIGN("glDeleteShader", deleteShader);
+        ASSIGN("glDeleteTextures", deleteTextures);
+        ASSIGN("glDepthFunc", depthFunc);
+        ASSIGN("glDepthMask", depthMask);
+        ASSIGN("glDepthRangef", depthRangef);
+        ASSIGN("glDetachShader", detachShader);
+        ASSIGN("glDisable", disable);
+        ASSIGN("glDisableVertexAttribArray", disableVertexAttribArray);
+        ASSIGN("glDrawArrays", drawArrays);
+        ASSIGN("glDrawElements", drawElements);
+        ASSIGN("glEnable", enable);
+        ASSIGN("glEnableVertexAttribArray", enableVertexAttribArray);
+        ASSIGN("glFinish", finish);
+        ASSIGN("glFlush", flush);
+        ASSIGN("glFramebufferRenderbuffer", framebufferRenderbuffer);
+        ASSIGN("glFramebufferTexture2D", framebufferTexture2D);
+        ASSIGN("glFrontFace", frontFace);
+        ASSIGN("glGenBuffers", genBuffers);
+        ASSIGN("glGenFramebuffers", genFramebuffers);
+        ASSIGN("glGenRenderbuffers", genRenderbuffers);
+        ASSIGN("glGenTextures", genTextures);
+        ASSIGN("glGenerateMipmap", generateMipmap);
+        ASSIGN("glGetActiveAttrib", getActiveAttrib);
+        ASSIGN("glGetActiveUniform", getActiveUniform);
+        ASSIGN("glGetAttachedShaders", getAttachedShaders);
+        ASSIGN("glGetAttribLocation", getAttribLocation);
+        ASSIGN("glGetBooleanv", getBooleanv);
+        ASSIGN("glGetBufferParameteriv", getBufferParameteriv);
+        ASSIGN("glGetError", getError);
+        ASSIGN("glGetFloatv", getFloatv);
+        ASSIGN("glGetFramebufferAttachmentParameteriv", getFramebufferAttachmentParameteriv);
+        ASSIGN("glGetIntegerv", getIntegerv);
+        ASSIGN("glGetProgramInfoLog", getProgramInfoLog);
+        ASSIGN("glGetProgramiv", getProgramiv);
+        ASSIGN("glGetRenderbufferParameteriv", getRenderbufferParameteriv);
+        ASSIGN("glGetShaderInfoLog", getShaderInfoLog);
+        ASSIGN("glGetShaderPrecisionFormat", getShaderPrecisionFormat);
+        ASSIGN("glGetShaderSource", getShaderSource);
+        ASSIGN("glGetShaderiv", getShaderiv);
+        ASSIGN("glGetString", getString);
+        ASSIGN("glGetTexParameterfv", getTexParameterfv);
+        ASSIGN("glGetTexParameteriv", getTexParameteriv);
+        ASSIGN("glGetUniformLocation", getUniformLocation);
+        ASSIGN("glGetUniformfv", getUniformfv);
+        ASSIGN("glGetUniformiv", getUniformiv);
+        ASSIGN("glGetVertexAttribPointerv", getVertexAttribPointerv);
+        ASSIGN("glGetVertexAttribfv", getVertexAttribfv);
+        ASSIGN("glGetVertexAttribiv", getVertexAttribiv);
+        ASSIGN("glHint", hint);
+        ASSIGN("glIsBuffer", isBuffer);
+        ASSIGN("glIsEnabled", isEnabled);
+        ASSIGN("glIsFramebuffer", isFramebuffer);
+        ASSIGN("glIsProgram", isProgram);
+        ASSIGN("glIsRenderbuffer", isRenderbuffer);
+        ASSIGN("glIsShader", isShader);
+        ASSIGN("glIsTexture", isTexture);
+        ASSIGN("glLineWidth", lineWidth);
+        ASSIGN("glLinkProgram", linkProgram);
+        ASSIGN("glPixelStorei", pixelStorei);
+        ASSIGN("glPolygonOffset", polygonOffset);
+        ASSIGN("glReadPixels", readPixels);
+        ASSIGN("glReleaseShaderCompiler", releaseShaderCompiler);
+        ASSIGN("glRenderbufferStorage", renderbufferStorage);
+        ASSIGN("glSampleCoverage", sampleCoverage);
+        ASSIGN("glScissor", scissor);
+        ASSIGN("glShaderBinary", shaderBinary);
+        ASSIGN("glShaderSource", shaderSource);
+        ASSIGN("glStencilFunc", stencilFunc);
+        ASSIGN("glStencilFuncSeparate", stencilFuncSeparate);
+        ASSIGN("glStencilMask", stencilMask);
+        ASSIGN("glStencilMaskSeparate", stencilMaskSeparate);
+        ASSIGN("glStencilOp", stencilOp);
+        ASSIGN("glStencilOpSeparate", stencilOpSeparate);
+        ASSIGN("glTexImage2D", texImage2D);
+        ASSIGN("glTexParameterf", texParameterf);
+        ASSIGN("glTexParameterfv", texParameterfv);
+        ASSIGN("glTexParameteri", texParameteri);
+        ASSIGN("glTexParameteriv", texParameteriv);
+        ASSIGN("glTexSubImage2D", texSubImage2D);
+        ASSIGN("glUniform1f", uniform1f);
+        ASSIGN("glUniform1fv", uniform1fv);
+        ASSIGN("glUniform1i", uniform1i);
+        ASSIGN("glUniform1iv", uniform1iv);
+        ASSIGN("glUniform2f", uniform2f);
+        ASSIGN("glUniform2fv", uniform2fv);
+        ASSIGN("glUniform2i", uniform2i);
+        ASSIGN("glUniform2iv", uniform2iv);
+        ASSIGN("glUniform3f", uniform3f);
+        ASSIGN("glUniform3fv", uniform3fv);
+        ASSIGN("glUniform3i", uniform3i);
+        ASSIGN("glUniform3iv", uniform3iv);
+        ASSIGN("glUniform4f", uniform4f);
+        ASSIGN("glUniform4fv", uniform4fv);
+        ASSIGN("glUniform4i", uniform4i);
+        ASSIGN("glUniform4iv", uniform4iv);
+        ASSIGN("glUniformMatrix2fv", uniformMatrix2fv);
+        ASSIGN("glUniformMatrix3fv", uniformMatrix3fv);
+        ASSIGN("glUniformMatrix4fv", uniformMatrix4fv);
+        ASSIGN("glUseProgram", useProgram);
+        ASSIGN("glValidateProgram", validateProgram);
+        ASSIGN("glVertexAttrib1f", vertexAttrib1f);
+        ASSIGN("glVertexAttrib1fv", vertexAttrib1fv);
+        ASSIGN("glVertexAttrib2f", vertexAttrib2f);
+        ASSIGN("glVertexAttrib2fv", vertexAttrib2fv);
+        ASSIGN("glVertexAttrib3f", vertexAttrib3f);
+        ASSIGN("glVertexAttrib3fv", vertexAttrib3fv);
+        ASSIGN("glVertexAttrib4f", vertexAttrib4f);
+        ASSIGN("glVertexAttrib4fv", vertexAttrib4fv);
+        ASSIGN("glVertexAttribPointer", vertexAttribPointer);
+        ASSIGN("glViewport", viewport);
+    }
+
+    if (version >= gl::Version(3, 0))
+    {
+        ASSIGN("glBeginQuery", beginQuery);
+        ASSIGN("glBeginTransformFeedback", beginTransformFeedback);
+        ASSIGN("glBindBufferBase", bindBufferBase);
+        ASSIGN("glBindBufferRange", bindBufferRange);
+        ASSIGN("glBindSampler", bindSampler);
+        ASSIGN("glBindTransformFeedback", bindTransformFeedback);
+        ASSIGN("glBindVertexArray", bindVertexArray);
+        ASSIGN("glBlitFramebuffer", blitFramebuffer);
+        ASSIGN("glClearBufferfi", clearBufferfi);
+        ASSIGN("glClearBufferfv", clearBufferfv);
+        ASSIGN("glClearBufferiv", clearBufferiv);
+        ASSIGN("glClearBufferuiv", clearBufferuiv);
+        ASSIGN("glClientWaitSync", clientWaitSync);
+        ASSIGN("glCompressedTexImage3D", compressedTexImage3D);
+        ASSIGN("glCompressedTexSubImage3D", compressedTexSubImage3D);
+        ASSIGN("glCopyBufferSubData", copyBufferSubData);
+        ASSIGN("glCopyTexSubImage3D", copyTexSubImage3D);
+        ASSIGN("glDeleteQueries", deleteQueries);
+        ASSIGN("glDeleteSamplers", deleteSamplers);
+        ASSIGN("glDeleteSync", deleteSync);
+        ASSIGN("glDeleteTransformFeedbacks", deleteTransformFeedbacks);
+        ASSIGN("glDeleteVertexArrays", deleteVertexArrays);
+        ASSIGN("glDrawArraysInstanced", drawArraysInstanced);
+        ASSIGN("glDrawBuffers", drawBuffers);
+        ASSIGN("glDrawElementsInstanced", drawElementsInstanced);
+        ASSIGN("glDrawRangeElements", drawRangeElements);
+        ASSIGN("glEndQuery", endQuery);
+        ASSIGN("glEndTransformFeedback", endTransformFeedback);
+        ASSIGN("glFenceSync", fenceSync);
+        ASSIGN("glFlushMappedBufferRange", flushMappedBufferRange);
+        ASSIGN("glFramebufferTextureLayer", framebufferTextureLayer);
+        ASSIGN("glGenQueries", genQueries);
+        ASSIGN("glGenSamplers", genSamplers);
+        ASSIGN("glGenTransformFeedbacks", genTransformFeedbacks);
+        ASSIGN("glGenVertexArrays", genVertexArrays);
+        ASSIGN("glGetActiveUniformBlockName", getActiveUniformBlockName);
+        ASSIGN("glGetActiveUniformBlockiv", getActiveUniformBlockiv);
+        ASSIGN("glGetActiveUniformsiv", getActiveUniformsiv);
+        ASSIGN("glGetBufferParameteri64v", getBufferParameteri64v);
+        ASSIGN("glGetBufferPointerv", getBufferPointerv);
+        ASSIGN("glGetFragDataLocation", getFragDataLocation);
+        ASSIGN("glGetInteger64i_v", getInteger64i_v);
+        ASSIGN("glGetInteger64v", getInteger64v);
+        ASSIGN("glGetIntegeri_v", getIntegeri_v);
+        ASSIGN("glGetInternalformativ", getInternalformativ);
+        ASSIGN("glGetProgramBinary", getProgramBinary);
+        ASSIGN("glGetQueryObjectuiv", getQueryObjectuiv);
+        ASSIGN("glGetQueryiv", getQueryiv);
+        ASSIGN("glGetSamplerParameterfv", getSamplerParameterfv);
+        ASSIGN("glGetSamplerParameteriv", getSamplerParameteriv);
+        ASSIGN("glGetStringi", getStringi);
+        ASSIGN("glGetSynciv", getSynciv);
+        ASSIGN("glGetTransformFeedbackVarying", getTransformFeedbackVarying);
+        ASSIGN("glGetUniformBlockIndex", getUniformBlockIndex);
+        ASSIGN("glGetUniformIndices", getUniformIndices);
+        ASSIGN("glGetUniformuiv", getUniformuiv);
+        ASSIGN("glGetVertexAttribIiv", getVertexAttribIiv);
+        ASSIGN("glGetVertexAttribIuiv", getVertexAttribIuiv);
+        ASSIGN("glInvalidateFramebuffer", invalidateFramebuffer);
+        ASSIGN("glInvalidateSubFramebuffer", invalidateSubFramebuffer);
+        ASSIGN("glIsQuery", isQuery);
+        ASSIGN("glIsSampler", isSampler);
+        ASSIGN("glIsSync", isSync);
+        ASSIGN("glIsTransformFeedback", isTransformFeedback);
+        ASSIGN("glIsVertexArray", isVertexArray);
+        ASSIGN("glMapBufferRange", mapBufferRange);
+        ASSIGN("glPauseTransformFeedback", pauseTransformFeedback);
+        ASSIGN("glProgramBinary", programBinary);
+        ASSIGN("glProgramParameteri", programParameteri);
+        ASSIGN("glReadBuffer", readBuffer);
+        ASSIGN("glRenderbufferStorageMultisample", renderbufferStorageMultisample);
+        ASSIGN("glResumeTransformFeedback", resumeTransformFeedback);
+        ASSIGN("glSamplerParameterf", samplerParameterf);
+        ASSIGN("glSamplerParameterfv", samplerParameterfv);
+        ASSIGN("glSamplerParameteri", samplerParameteri);
+        ASSIGN("glSamplerParameteriv", samplerParameteriv);
+        ASSIGN("glTexImage3D", texImage3D);
+        ASSIGN("glTexStorage2D", texStorage2D);
+        ASSIGN("glTexStorage3D", texStorage3D);
+        ASSIGN("glTexSubImage3D", texSubImage3D);
+        ASSIGN("glTransformFeedbackVaryings", transformFeedbackVaryings);
+        ASSIGN("glUniform1ui", uniform1ui);
+        ASSIGN("glUniform1uiv", uniform1uiv);
+        ASSIGN("glUniform2ui", uniform2ui);
+        ASSIGN("glUniform2uiv", uniform2uiv);
+        ASSIGN("glUniform3ui", uniform3ui);
+        ASSIGN("glUniform3uiv", uniform3uiv);
+        ASSIGN("glUniform4ui", uniform4ui);
+        ASSIGN("glUniform4uiv", uniform4uiv);
+        ASSIGN("glUniformBlockBinding", uniformBlockBinding);
+        ASSIGN("glUniformMatrix2x3fv", uniformMatrix2x3fv);
+        ASSIGN("glUniformMatrix2x4fv", uniformMatrix2x4fv);
+        ASSIGN("glUniformMatrix3x2fv", uniformMatrix3x2fv);
+        ASSIGN("glUniformMatrix3x4fv", uniformMatrix3x4fv);
+        ASSIGN("glUniformMatrix4x2fv", uniformMatrix4x2fv);
+        ASSIGN("glUniformMatrix4x3fv", uniformMatrix4x3fv);
+        ASSIGN("glUnmapBuffer", unmapBuffer);
+        ASSIGN("glVertexAttribDivisor", vertexAttribDivisor);
+        ASSIGN("glVertexAttribI4i", vertexAttribI4i);
+        ASSIGN("glVertexAttribI4iv", vertexAttribI4iv);
+        ASSIGN("glVertexAttribI4ui", vertexAttribI4ui);
+        ASSIGN("glVertexAttribI4uiv", vertexAttribI4uiv);
+        ASSIGN("glVertexAttribIPointer", vertexAttribIPointer);
+        ASSIGN("glWaitSync", waitSync);
+    }
+
+    if (version >= gl::Version(3, 1))
+    {
+        ASSIGN("glActiveShaderProgram", activeShaderProgram);
+        ASSIGN("glBindImageTexture", bindImageTexture);
+        ASSIGN("glBindProgramPipeline", bindProgramPipeline);
+        ASSIGN("glBindVertexBuffer", bindVertexBuffer);
+        ASSIGN("glCreateShaderProgramv", createShaderProgramv);
+        ASSIGN("glDeleteProgramPipelines", deleteProgramPipelines);
+        ASSIGN("glDispatchCompute", dispatchCompute);
+        ASSIGN("glDispatchComputeIndirect", dispatchComputeIndirect);
+        ASSIGN("glDrawArraysIndirect", drawArraysIndirect);
+        ASSIGN("glDrawElementsIndirect", drawElementsIndirect);
+        ASSIGN("glFramebufferParameteri", framebufferParameteri);
+        ASSIGN("glGenProgramPipelines", genProgramPipelines);
+        ASSIGN("glGetBooleani_v", getBooleani_v);
+        ASSIGN("glGetFramebufferParameteriv", getFramebufferParameteriv);
+        ASSIGN("glGetMultisamplefv", getMultisamplefv);
+        ASSIGN("glGetProgramInterfaceiv", getProgramInterfaceiv);
+        ASSIGN("glGetProgramPipelineInfoLog", getProgramPipelineInfoLog);
+        ASSIGN("glGetProgramPipelineiv", getProgramPipelineiv);
+        ASSIGN("glGetProgramResourceIndex", getProgramResourceIndex);
+        ASSIGN("glGetProgramResourceLocation", getProgramResourceLocation);
+        ASSIGN("glGetProgramResourceName", getProgramResourceName);
+        ASSIGN("glGetProgramResourceiv", getProgramResourceiv);
+        ASSIGN("glGetTexLevelParameterfv", getTexLevelParameterfv);
+        ASSIGN("glGetTexLevelParameteriv", getTexLevelParameteriv);
+        ASSIGN("glIsProgramPipeline", isProgramPipeline);
+        ASSIGN("glMemoryBarrier", memoryBarrier);
+        ASSIGN("glMemoryBarrierByRegion", memoryBarrierByRegion);
+        ASSIGN("glProgramUniform1f", programUniform1f);
+        ASSIGN("glProgramUniform1fv", programUniform1fv);
+        ASSIGN("glProgramUniform1i", programUniform1i);
+        ASSIGN("glProgramUniform1iv", programUniform1iv);
+        ASSIGN("glProgramUniform1ui", programUniform1ui);
+        ASSIGN("glProgramUniform1uiv", programUniform1uiv);
+        ASSIGN("glProgramUniform2f", programUniform2f);
+        ASSIGN("glProgramUniform2fv", programUniform2fv);
+        ASSIGN("glProgramUniform2i", programUniform2i);
+        ASSIGN("glProgramUniform2iv", programUniform2iv);
+        ASSIGN("glProgramUniform2ui", programUniform2ui);
+        ASSIGN("glProgramUniform2uiv", programUniform2uiv);
+        ASSIGN("glProgramUniform3f", programUniform3f);
+        ASSIGN("glProgramUniform3fv", programUniform3fv);
+        ASSIGN("glProgramUniform3i", programUniform3i);
+        ASSIGN("glProgramUniform3iv", programUniform3iv);
+        ASSIGN("glProgramUniform3ui", programUniform3ui);
+        ASSIGN("glProgramUniform3uiv", programUniform3uiv);
+        ASSIGN("glProgramUniform4f", programUniform4f);
+        ASSIGN("glProgramUniform4fv", programUniform4fv);
+        ASSIGN("glProgramUniform4i", programUniform4i);
+        ASSIGN("glProgramUniform4iv", programUniform4iv);
+        ASSIGN("glProgramUniform4ui", programUniform4ui);
+        ASSIGN("glProgramUniform4uiv", programUniform4uiv);
+        ASSIGN("glProgramUniformMatrix2fv", programUniformMatrix2fv);
+        ASSIGN("glProgramUniformMatrix2x3fv", programUniformMatrix2x3fv);
+        ASSIGN("glProgramUniformMatrix2x4fv", programUniformMatrix2x4fv);
+        ASSIGN("glProgramUniformMatrix3fv", programUniformMatrix3fv);
+        ASSIGN("glProgramUniformMatrix3x2fv", programUniformMatrix3x2fv);
+        ASSIGN("glProgramUniformMatrix3x4fv", programUniformMatrix3x4fv);
+        ASSIGN("glProgramUniformMatrix4fv", programUniformMatrix4fv);
+        ASSIGN("glProgramUniformMatrix4x2fv", programUniformMatrix4x2fv);
+        ASSIGN("glProgramUniformMatrix4x3fv", programUniformMatrix4x3fv);
+        ASSIGN("glSampleMaski", sampleMaski);
+        ASSIGN("glTexStorage2DMultisample", texStorage2DMultisample);
+        ASSIGN("glUseProgramStages", useProgramStages);
+        ASSIGN("glValidateProgramPipeline", validateProgramPipeline);
+        ASSIGN("glVertexAttribBinding", vertexAttribBinding);
+        ASSIGN("glVertexAttribFormat", vertexAttribFormat);
+        ASSIGN("glVertexAttribIFormat", vertexAttribIFormat);
+        ASSIGN("glVertexBindingDivisor", vertexBindingDivisor);
+    }
+
+    if (version >= gl::Version(3, 2))
+    {
+        ASSIGN("glBlendBarrier", blendBarrier);
+        ASSIGN("glBlendEquationSeparatei", blendEquationSeparatei);
+        ASSIGN("glBlendEquationi", blendEquationi);
+        ASSIGN("glBlendFuncSeparatei", blendFuncSeparatei);
+        ASSIGN("glBlendFunci", blendFunci);
+        ASSIGN("glColorMaski", colorMaski);
+        ASSIGN("glCopyImageSubData", copyImageSubData);
+        ASSIGN("glDebugMessageCallback", debugMessageCallback);
+        ASSIGN("glDebugMessageControl", debugMessageControl);
+        ASSIGN("glDebugMessageInsert", debugMessageInsert);
+        ASSIGN("glDisablei", disablei);
+        ASSIGN("glDrawElementsBaseVertex", drawElementsBaseVertex);
+        ASSIGN("glDrawElementsInstancedBaseVertex", drawElementsInstancedBaseVertex);
+        ASSIGN("glDrawRangeElementsBaseVertex", drawRangeElementsBaseVertex);
+        ASSIGN("glEnablei", enablei);
+        ASSIGN("glFramebufferTexture", framebufferTexture);
+        ASSIGN("glGetDebugMessageLog", getDebugMessageLog);
+        ASSIGN("glGetGraphicsResetStatus", getGraphicsResetStatus);
+        ASSIGN("glGetObjectLabel", getObjectLabel);
+        ASSIGN("glGetObjectPtrLabel", getObjectPtrLabel);
+        ASSIGN("glGetPointerv", getPointerv);
+        ASSIGN("glGetSamplerParameterIiv", getSamplerParameterIiv);
+        ASSIGN("glGetSamplerParameterIuiv", getSamplerParameterIuiv);
+        ASSIGN("glGetTexParameterIiv", getTexParameterIiv);
+        ASSIGN("glGetTexParameterIuiv", getTexParameterIuiv);
+        ASSIGN("glGetnUniformfv", getnUniformfv);
+        ASSIGN("glGetnUniformiv", getnUniformiv);
+        ASSIGN("glGetnUniformuiv", getnUniformuiv);
+        ASSIGN("glIsEnabledi", isEnabledi);
+        ASSIGN("glMinSampleShading", minSampleShading);
+        ASSIGN("glObjectLabel", objectLabel);
+        ASSIGN("glObjectPtrLabel", objectPtrLabel);
+        ASSIGN("glPatchParameteri", patchParameteri);
+        ASSIGN("glPopDebugGroup", popDebugGroup);
+        ASSIGN("glPrimitiveBoundingBox", primitiveBoundingBox);
+        ASSIGN("glPushDebugGroup", pushDebugGroup);
+        ASSIGN("glReadnPixels", readnPixels);
+        ASSIGN("glSamplerParameterIiv", samplerParameterIiv);
+        ASSIGN("glSamplerParameterIuiv", samplerParameterIuiv);
+        ASSIGN("glTexBuffer", texBuffer);
+        ASSIGN("glTexBufferRange", texBufferRange);
+        ASSIGN("glTexParameterIiv", texParameterIiv);
+        ASSIGN("glTexParameterIuiv", texParameterIuiv);
+        ASSIGN("glTexStorage3DMultisample", texStorage3DMultisample);
+    }
+
+    if (extensions.count("GL_EXT_base_instance") != 0)
+    {
+        ASSIGN("glDrawArraysInstancedBaseInstanceEXT", drawArraysInstancedBaseInstance);
+        ASSIGN("glDrawElementsInstancedBaseInstanceEXT", drawElementsInstancedBaseInstance);
+        ASSIGN("glDrawElementsInstancedBaseVertexBaseInstanceEXT",
+               drawElementsInstancedBaseVertexBaseInstance);
+    }
+
+    if (extensions.count("GL_EXT_blend_func_extended") != 0)
+    {
+        ASSIGN("glBindFragDataLocationEXT", bindFragDataLocation);
+        ASSIGN("glBindFragDataLocationIndexedEXT", bindFragDataLocationIndexed);
+        ASSIGN("glGetFragDataIndexEXT", getFragDataIndex);
+        ASSIGN("glGetProgramResourceLocationIndexEXT", getProgramResourceLocationIndex);
+    }
+
+    if (extensions.count("GL_EXT_buffer_storage") != 0)
+    {
+        ASSIGN("glBufferStorageEXT", bufferStorage);
+    }
+
+    if (extensions.count("GL_EXT_clear_texture") != 0)
+    {
+        ASSIGN("glClearTexImageEXT", clearTexImage);
+        ASSIGN("glClearTexSubImageEXT", clearTexSubImage);
+    }
+
+    if (extensions.count("GL_EXT_copy_image") != 0)
+    {
+        ASSIGN("glCopyImageSubDataEXT", copyImageSubData);
+    }
+
+    if (extensions.count("GL_EXT_discard_framebuffer") != 0)
+    {
+        ASSIGN("glDiscardFramebufferEXT", discardFramebufferEXT);
+    }
+
+    if (extensions.count("GL_EXT_disjoint_timer_query") != 0)
+    {
+        ASSIGN("glBeginQueryEXT", beginQuery);
+        ASSIGN("glDeleteQueriesEXT", deleteQueries);
+        ASSIGN("glEndQueryEXT", endQuery);
+        ASSIGN("glGenQueriesEXT", genQueries);
+        ASSIGN("glGetQueryObjecti64vEXT", getQueryObjecti64v);
+        ASSIGN("glGetQueryObjectivEXT", getQueryObjectiv);
+        ASSIGN("glGetQueryObjectui64vEXT", getQueryObjectui64v);
+        ASSIGN("glGetQueryObjectuivEXT", getQueryObjectuiv);
+        ASSIGN("glGetQueryivEXT", getQueryiv);
+        ASSIGN("glIsQueryEXT", isQuery);
+        ASSIGN("glQueryCounterEXT", queryCounter);
+    }
+
+    if (extensions.count("GL_EXT_draw_buffers") != 0)
+    {
+        ASSIGN("glDrawBuffersEXT", drawBuffers);
+    }
+
+    if (extensions.count("GL_EXT_draw_buffers_indexed") != 0)
+    {
+        ASSIGN("glBlendEquationSeparateiEXT", blendEquationSeparatei);
+        ASSIGN("glBlendEquationiEXT", blendEquationi);
+        ASSIGN("glBlendFuncSeparateiEXT", blendFuncSeparatei);
+        ASSIGN("glBlendFunciEXT", blendFunci);
+        ASSIGN("glColorMaskiEXT", colorMaski);
+        ASSIGN("glDisableiEXT", disablei);
+        ASSIGN("glEnableiEXT", enablei);
+        ASSIGN("glIsEnablediEXT", isEnabledi);
+    }
+
+    if (extensions.count("GL_EXT_draw_elements_base_vertex") != 0)
+    {
+        ASSIGN("glDrawElementsBaseVertexEXT", drawElementsBaseVertex);
+        ASSIGN("glDrawElementsInstancedBaseVertexEXT", drawElementsInstancedBaseVertex);
+        ASSIGN("glDrawRangeElementsBaseVertexEXT", drawRangeElementsBaseVertex);
+        ASSIGN("glMultiDrawElementsBaseVertexEXT", multiDrawElementsBaseVertex);
+    }
+
+    if (extensions.count("GL_EXT_draw_transform_feedback") != 0)
+    {
+        ASSIGN("glDrawTransformFeedbackEXT", drawTransformFeedback);
+        ASSIGN("glDrawTransformFeedbackInstancedEXT", drawTransformFeedbackInstanced);
+    }
+
+    if (extensions.count("GL_EXT_geometry_shader") != 0)
+    {
+        ASSIGN("glFramebufferTextureEXT", framebufferTexture);
+    }
+
+    if (extensions.count("GL_EXT_instanced_arrays") != 0)
+    {
+        ASSIGN("glVertexAttribDivisorEXT", vertexAttribDivisor);
+    }
+
+    if (extensions.count("GL_EXT_map_buffer_range") != 0)
+    {
+        ASSIGN("glFlushMappedBufferRangeEXT", flushMappedBufferRange);
+        ASSIGN("glMapBufferRangeEXT", mapBufferRange);
+    }
+
+    if (extensions.count("GL_EXT_multi_draw_indirect") != 0)
+    {
+        ASSIGN("glMultiDrawArraysIndirectEXT", multiDrawArraysIndirect);
+        ASSIGN("glMultiDrawElementsIndirectEXT", multiDrawElementsIndirect);
+    }
+
+    if (extensions.count("GL_EXT_multisampled_render_to_texture") != 0)
+    {
+        ASSIGN("glRenderbufferStorageMultisampleEXT", renderbufferStorageMultisample);
+    }
+
+    if (extensions.count("GL_EXT_multiview_draw_buffers") != 0)
+    {
+        ASSIGN("glGetIntegeri_vEXT", getIntegeri_v);
+    }
+
+    if (extensions.count("GL_EXT_occlusion_query_boolean") != 0)
+    {
+        ASSIGN("glBeginQueryEXT", beginQuery);
+        ASSIGN("glDeleteQueriesEXT", deleteQueries);
+        ASSIGN("glEndQueryEXT", endQuery);
+        ASSIGN("glGenQueriesEXT", genQueries);
+        ASSIGN("glGetQueryObjectuivEXT", getQueryObjectuiv);
+        ASSIGN("glGetQueryivEXT", getQueryiv);
+        ASSIGN("glIsQueryEXT", isQuery);
+    }
+
+    if (extensions.count("GL_EXT_primitive_bounding_box") != 0)
+    {
+        ASSIGN("glPrimitiveBoundingBoxEXT", primitiveBoundingBox);
+    }
+
+    if (extensions.count("GL_EXT_robustness") != 0)
+    {
+        ASSIGN("glGetGraphicsResetStatusEXT", getGraphicsResetStatus);
+        ASSIGN("glGetnUniformfvEXT", getnUniformfv);
+        ASSIGN("glGetnUniformivEXT", getnUniformiv);
+        ASSIGN("glReadnPixelsEXT", readnPixels);
+    }
+
+    if (extensions.count("GL_EXT_tessellation_shader") != 0)
+    {
+        ASSIGN("glPatchParameteriEXT", patchParameteri);
+    }
+
+    if (extensions.count("GL_EXT_texture_border_clamp") != 0)
+    {
+        ASSIGN("glGetSamplerParameterIivEXT", getSamplerParameterIiv);
+        ASSIGN("glGetSamplerParameterIuivEXT", getSamplerParameterIuiv);
+        ASSIGN("glGetTexParameterIivEXT", getTexParameterIiv);
+        ASSIGN("glGetTexParameterIuivEXT", getTexParameterIuiv);
+        ASSIGN("glSamplerParameterIivEXT", samplerParameterIiv);
+        ASSIGN("glSamplerParameterIuivEXT", samplerParameterIuiv);
+        ASSIGN("glTexParameterIivEXT", texParameterIiv);
+        ASSIGN("glTexParameterIuivEXT", texParameterIuiv);
+    }
+
+    if (extensions.count("GL_EXT_texture_buffer") != 0)
+    {
+        ASSIGN("glTexBufferEXT", texBuffer);
+        ASSIGN("glTexBufferRangeEXT", texBufferRange);
+    }
+
+    if (extensions.count("GL_EXT_texture_storage") != 0)
+    {
+        ASSIGN("glTexStorage1DEXT", texStorage1D);
+        ASSIGN("glTexStorage2DEXT", texStorage2D);
+        ASSIGN("glTexStorage3DEXT", texStorage3D);
+        ASSIGN("glTextureStorage1DEXT", textureStorage1D);
+        ASSIGN("glTextureStorage2DEXT", textureStorage2D);
+        ASSIGN("glTextureStorage3DEXT", textureStorage3D);
+    }
+
+    if (extensions.count("GL_EXT_texture_view") != 0)
+    {
+        ASSIGN("glTextureViewEXT", textureView);
+    }
+
+    if (extensions.count("GL_KHR_debug") != 0)
+    {
+        ASSIGN("glDebugMessageCallbackKHR", debugMessageCallback);
+        ASSIGN("glDebugMessageControlKHR", debugMessageControl);
+        ASSIGN("glDebugMessageInsertKHR", debugMessageInsert);
+        ASSIGN("glGetDebugMessageLogKHR", getDebugMessageLog);
+        ASSIGN("glGetObjectLabelKHR", getObjectLabel);
+        ASSIGN("glGetObjectPtrLabelKHR", getObjectPtrLabel);
+        ASSIGN("glGetPointervKHR", getPointerv);
+        ASSIGN("glObjectLabelKHR", objectLabel);
+        ASSIGN("glObjectPtrLabelKHR", objectPtrLabel);
+        ASSIGN("glPopDebugGroupKHR", popDebugGroup);
+        ASSIGN("glPushDebugGroupKHR", pushDebugGroup);
+    }
+
+    if (extensions.count("GL_KHR_robustness") != 0)
+    {
+        ASSIGN("glGetGraphicsResetStatusKHR", getGraphicsResetStatus);
+        ASSIGN("glGetnUniformfvKHR", getnUniformfv);
+        ASSIGN("glGetnUniformivKHR", getnUniformiv);
+        ASSIGN("glGetnUniformuivKHR", getnUniformuiv);
+        ASSIGN("glReadnPixelsKHR", readnPixels);
+    }
+
+    if (extensions.count("GL_OES_EGL_image") != 0)
+    {
+        ASSIGN("glEGLImageTargetRenderbufferStorageOES", eGLImageTargetRenderbufferStorageOES);
+        ASSIGN("glEGLImageTargetTexture2DOES", eGLImageTargetTexture2DOES);
+    }
+
+    if (extensions.count("GL_OES_copy_image") != 0)
+    {
+        ASSIGN("glCopyImageSubDataOES", copyImageSubData);
+    }
+
+    if (extensions.count("GL_OES_draw_buffers_indexed") != 0)
+    {
+        ASSIGN("glBlendEquationSeparateiOES", blendEquationSeparatei);
+        ASSIGN("glBlendEquationiOES", blendEquationi);
+        ASSIGN("glBlendFuncSeparateiOES", blendFuncSeparatei);
+        ASSIGN("glBlendFunciOES", blendFunci);
+        ASSIGN("glColorMaskiOES", colorMaski);
+        ASSIGN("glDisableiOES", disablei);
+        ASSIGN("glEnableiOES", enablei);
+        ASSIGN("glIsEnablediOES", isEnabledi);
+    }
+
+    if (extensions.count("GL_OES_draw_elements_base_vertex") != 0)
+    {
+        ASSIGN("glDrawElementsBaseVertexOES", drawElementsBaseVertex);
+        ASSIGN("glDrawElementsInstancedBaseVertexOES", drawElementsInstancedBaseVertex);
+        ASSIGN("glDrawRangeElementsBaseVertexOES", drawRangeElementsBaseVertex);
+        ASSIGN("glMultiDrawElementsBaseVertexOES", multiDrawElementsBaseVertex);
+    }
+
+    if (extensions.count("GL_OES_geometry_shader") != 0)
+    {
+        ASSIGN("glFramebufferTextureOES", framebufferTexture);
+    }
+
+    if (extensions.count("GL_OES_get_program_binary") != 0)
+    {
+        ASSIGN("glGetProgramBinaryOES", getProgramBinary);
+        ASSIGN("glProgramBinaryOES", programBinary);
+    }
+
+    if (extensions.count("GL_OES_mapbuffer") != 0)
+    {
+        ASSIGN("glGetBufferPointervOES", getBufferPointerv);
+        ASSIGN("glMapBufferOES", mapBuffer);
+        ASSIGN("glUnmapBufferOES", unmapBuffer);
+    }
+
+    if (extensions.count("GL_OES_primitive_bounding_box") != 0)
+    {
+        ASSIGN("glPrimitiveBoundingBoxOES", primitiveBoundingBox);
+    }
+
+    if (extensions.count("GL_OES_sample_shading") != 0)
+    {
+        ASSIGN("glMinSampleShadingOES", minSampleShading);
+    }
+
+    if (extensions.count("GL_OES_tessellation_shader") != 0)
+    {
+        ASSIGN("glPatchParameteriOES", patchParameteri);
+    }
+
+    if (extensions.count("GL_OES_texture_3D") != 0)
+    {
+        ASSIGN("glCompressedTexImage3DOES", compressedTexImage3D);
+        ASSIGN("glCompressedTexSubImage3DOES", compressedTexSubImage3D);
+        ASSIGN("glCopyTexSubImage3DOES", copyTexSubImage3D);
+        ASSIGN("glFramebufferTexture3DOES", framebufferTexture3D);
+        ASSIGN("glTexImage3DOES", texImage3D);
+        ASSIGN("glTexSubImage3DOES", texSubImage3D);
+    }
+
+    if (extensions.count("GL_OES_texture_border_clamp") != 0)
+    {
+        ASSIGN("glGetSamplerParameterIivOES", getSamplerParameterIiv);
+        ASSIGN("glGetSamplerParameterIuivOES", getSamplerParameterIuiv);
+        ASSIGN("glGetTexParameterIivOES", getTexParameterIiv);
+        ASSIGN("glGetTexParameterIuivOES", getTexParameterIuiv);
+        ASSIGN("glSamplerParameterIivOES", samplerParameterIiv);
+        ASSIGN("glSamplerParameterIuivOES", samplerParameterIuiv);
+        ASSIGN("glTexParameterIivOES", texParameterIiv);
+        ASSIGN("glTexParameterIuivOES", texParameterIuiv);
+    }
+
+    if (extensions.count("GL_OES_texture_buffer") != 0)
+    {
+        ASSIGN("glTexBufferOES", texBuffer);
+        ASSIGN("glTexBufferRangeOES", texBufferRange);
+    }
+
+    if (extensions.count("GL_OES_texture_storage_multisample_2d_array") != 0)
+    {
+        ASSIGN("glTexStorage3DMultisampleOES", texStorage3DMultisample);
+    }
+
+    if (extensions.count("GL_OES_texture_view") != 0)
+    {
+        ASSIGN("glTextureViewOES", textureView);
+    }
+
+    if (extensions.count("GL_OES_vertex_array_object") != 0)
+    {
+        ASSIGN("glBindVertexArrayOES", bindVertexArray);
+        ASSIGN("glDeleteVertexArraysOES", deleteVertexArrays);
+        ASSIGN("glGenVertexArraysOES", genVertexArrays);
+        ASSIGN("glIsVertexArrayOES", isVertexArray);
+    }
+
+    if (extensions.count("GL_OES_viewport_array") != 0)
+    {
+        ASSIGN("glDisableiOES", disablei);
+        ASSIGN("glEnableiOES", enablei);
+        ASSIGN("glGetFloati_vOES", getFloati_v);
+        ASSIGN("glIsEnablediOES", isEnabledi);
+        ASSIGN("glScissorArrayvOES", scissorArrayv);
+        ASSIGN("glScissorIndexedOES", scissorIndexed);
+        ASSIGN("glScissorIndexedvOES", scissorIndexedv);
+        ASSIGN("glViewportArrayvOES", viewportArrayv);
+        ASSIGN("glViewportIndexedfOES", viewportIndexedf);
+        ASSIGN("glViewportIndexedfvOES", viewportIndexedfv);
+    }
+}
+
+void DispatchTableGL::initProcsSharedExtensions(const std::set<std::string> &extensions)
+{
+    if (extensions.count("GL_EXT_blend_minmax") != 0)
+    {
+        ASSIGN("glBlendEquationEXT", blendEquation);
+    }
+
+    if (extensions.count("GL_EXT_debug_label") != 0)
+    {
+        ASSIGN("glGetObjectLabelEXT", getObjectLabel);
+    }
+
+    if (extensions.count("GL_EXT_debug_marker") != 0)
+    {
+        ASSIGN("glInsertEventMarkerEXT", insertEventMarkerEXT);
+        ASSIGN("glPopGroupMarkerEXT", popGroupMarkerEXT);
+        ASSIGN("glPushGroupMarkerEXT", pushGroupMarkerEXT);
+    }
+
+    if (extensions.count("GL_EXT_draw_instanced") != 0)
+    {
+        ASSIGN("glDrawArraysInstancedEXT", drawArraysInstanced);
+        ASSIGN("glDrawElementsInstancedEXT", drawElementsInstanced);
+    }
+
+    if (extensions.count("GL_EXT_multi_draw_arrays") != 0)
+    {
+        ASSIGN("glMultiDrawArraysEXT", multiDrawArrays);
+        ASSIGN("glMultiDrawElementsEXT", multiDrawElements);
+    }
+
+    if (extensions.count("GL_EXT_separate_shader_objects") != 0)
+    {
+        ASSIGN("glActiveShaderProgramEXT", activeShaderProgram);
+        ASSIGN("glBindProgramPipelineEXT", bindProgramPipeline);
+        ASSIGN("glCreateShaderProgramvEXT", createShaderProgramv);
+        ASSIGN("glDeleteProgramPipelinesEXT", deleteProgramPipelines);
+        ASSIGN("glGenProgramPipelinesEXT", genProgramPipelines);
+        ASSIGN("glGetProgramPipelineInfoLogEXT", getProgramPipelineInfoLog);
+        ASSIGN("glGetProgramPipelineivEXT", getProgramPipelineiv);
+        ASSIGN("glIsProgramPipelineEXT", isProgramPipeline);
+        ASSIGN("glProgramParameteriEXT", programParameteri);
+        ASSIGN("glProgramUniform1fEXT", programUniform1f);
+        ASSIGN("glProgramUniform1fvEXT", programUniform1fv);
+        ASSIGN("glProgramUniform1iEXT", programUniform1i);
+        ASSIGN("glProgramUniform1ivEXT", programUniform1iv);
+        ASSIGN("glProgramUniform1uiEXT", programUniform1ui);
+        ASSIGN("glProgramUniform1uivEXT", programUniform1uiv);
+        ASSIGN("glProgramUniform2fEXT", programUniform2f);
+        ASSIGN("glProgramUniform2fvEXT", programUniform2fv);
+        ASSIGN("glProgramUniform2iEXT", programUniform2i);
+        ASSIGN("glProgramUniform2ivEXT", programUniform2iv);
+        ASSIGN("glProgramUniform2uiEXT", programUniform2ui);
+        ASSIGN("glProgramUniform2uivEXT", programUniform2uiv);
+        ASSIGN("glProgramUniform3fEXT", programUniform3f);
+        ASSIGN("glProgramUniform3fvEXT", programUniform3fv);
+        ASSIGN("glProgramUniform3iEXT", programUniform3i);
+        ASSIGN("glProgramUniform3ivEXT", programUniform3iv);
+        ASSIGN("glProgramUniform3uiEXT", programUniform3ui);
+        ASSIGN("glProgramUniform3uivEXT", programUniform3uiv);
+        ASSIGN("glProgramUniform4fEXT", programUniform4f);
+        ASSIGN("glProgramUniform4fvEXT", programUniform4fv);
+        ASSIGN("glProgramUniform4iEXT", programUniform4i);
+        ASSIGN("glProgramUniform4ivEXT", programUniform4iv);
+        ASSIGN("glProgramUniform4uiEXT", programUniform4ui);
+        ASSIGN("glProgramUniform4uivEXT", programUniform4uiv);
+        ASSIGN("glProgramUniformMatrix2fvEXT", programUniformMatrix2fv);
+        ASSIGN("glProgramUniformMatrix2x3fvEXT", programUniformMatrix2x3fv);
+        ASSIGN("glProgramUniformMatrix2x4fvEXT", programUniformMatrix2x4fv);
+        ASSIGN("glProgramUniformMatrix3fvEXT", programUniformMatrix3fv);
+        ASSIGN("glProgramUniformMatrix3x2fvEXT", programUniformMatrix3x2fv);
+        ASSIGN("glProgramUniformMatrix3x4fvEXT", programUniformMatrix3x4fv);
+        ASSIGN("glProgramUniformMatrix4fvEXT", programUniformMatrix4fv);
+        ASSIGN("glProgramUniformMatrix4fvEXT", programUniformMatrix4fv);
+        ASSIGN("glProgramUniformMatrix4x2fvEXT", programUniformMatrix4x2fv);
+        ASSIGN("glProgramUniformMatrix4x3fvEXT", programUniformMatrix4x3fv);
+        ASSIGN("glUseProgramStagesEXT", useProgramStages);
+        ASSIGN("glValidateProgramPipelineEXT", validateProgramPipeline);
+    }
+
+    if (extensions.count("GL_NV_fence") != 0)
+    {
+        ASSIGN("glDeleteFencesNV", deleteFencesNV);
+        ASSIGN("glFinishFenceNV", finishFenceNV);
+        ASSIGN("glGenFencesNV", genFencesNV);
+        ASSIGN("glGetFenceivNV", getFenceivNV);
+        ASSIGN("glIsFenceNV", isFenceNV);
+        ASSIGN("glSetFenceNV", setFenceNV);
+        ASSIGN("glTestFenceNV", testFenceNV);
+    }
+
+    if (extensions.count("GL_NV_framebuffer_mixed_samples") != 0)
+    {
+        ASSIGN("glCoverageModulationNV", coverageModulationNV);
+    }
+
+    if (extensions.count("GL_NV_internalformat_sample_query") != 0)
+    {
+        ASSIGN("glGetInternalformatSampleivNV", getInternalformatSampleivNV);
+    }
+
+    if (extensions.count("GL_NV_path_rendering") != 0)
+    {
+        ASSIGN("glCoverFillPathInstancedNV", coverFillPathInstancedNV);
+        ASSIGN("glCoverFillPathNV", coverFillPathNV);
+        ASSIGN("glCoverStrokePathInstancedNV", coverStrokePathInstancedNV);
+        ASSIGN("glCoverStrokePathNV", coverStrokePathNV);
+        ASSIGN("glDeletePathsNV", deletePathsNV);
+        ASSIGN("glGenPathsNV", genPathsNV);
+        ASSIGN("glGetPathParameterfvNV", getPathParameterfvNV);
+        ASSIGN("glGetPathParameterivNV", getPathParameterivNV);
+        ASSIGN("glIsPathNV", isPathNV);
+        ASSIGN("glMatrixLoadfEXT", matrixLoadfEXT);
+        ASSIGN("glPathCommandsNV", pathCommandsNV);
+        ASSIGN("glPathParameterfNV", pathParameterfNV);
+        ASSIGN("glPathParameteriNV", pathParameteriNV);
+        ASSIGN("glPathStencilFuncNV", pathStencilFuncNV);
+        ASSIGN("glProgramPathFragmentInputGenNV", programPathFragmentInputGenNV);
+        ASSIGN("glStencilFillPathInstancedNV", stencilFillPathInstancedNV);
+        ASSIGN("glStencilFillPathNV", stencilFillPathNV);
+        ASSIGN("glStencilStrokePathInstancedNV", stencilStrokePathInstancedNV);
+        ASSIGN("glStencilStrokePathNV", stencilStrokePathNV);
+        ASSIGN("glStencilThenCoverFillPathInstancedNV", stencilThenCoverFillPathInstancedNV);
+        ASSIGN("glStencilThenCoverFillPathNV", stencilThenCoverFillPathNV);
+        ASSIGN("glStencilThenCoverStrokePathInstancedNV", stencilThenCoverStrokePathInstancedNV);
+        ASSIGN("glStencilThenCoverStrokePathNV", stencilThenCoverStrokePathNV);
+    }
+}
+
+#if defined(ANGLE_ENABLE_OPENGL_NULL)
+void DispatchTableGL::initProcsDesktopGLNULL(const gl::Version &version,
+                                             const std::set<std::string> &extensions)
+{
+    if (version >= gl::Version(1, 0))
+    {
+        blendFunc              = &glBlendFuncNULL;
+        clear                  = &glClearNULL;
+        clearColor             = &glClearColorNULL;
+        clearDepth             = &glClearDepthNULL;
+        clearStencil           = &glClearStencilNULL;
+        colorMask              = &glColorMaskNULL;
+        cullFace               = &glCullFaceNULL;
+        depthFunc              = &glDepthFuncNULL;
+        depthMask              = &glDepthMaskNULL;
+        depthRange             = &glDepthRangeNULL;
+        disable                = &glDisableNULL;
+        drawBuffer             = &glDrawBufferNULL;
+        enable                 = &glEnableNULL;
+        finish                 = &glFinishNULL;
+        flush                  = &glFlushNULL;
+        frontFace              = &glFrontFaceNULL;
+        getBooleanv            = &glGetBooleanvNULL;
+        getDoublev             = &glGetDoublevNULL;
+        getError               = &glGetErrorNULL;
+        getFloatv              = &glGetFloatvNULL;
+        getIntegerv            = &glGetIntegervNULL;
+        getString              = &glGetStringNULL;
+        getTexImage            = &glGetTexImageNULL;
+        getTexLevelParameterfv = &glGetTexLevelParameterfvNULL;
+        getTexLevelParameteriv = &glGetTexLevelParameterivNULL;
+        getTexParameterfv      = &glGetTexParameterfvNULL;
+        getTexParameteriv      = &glGetTexParameterivNULL;
+        hint                   = &glHintNULL;
+        isEnabled              = &glIsEnabledNULL;
+        lineWidth              = &glLineWidthNULL;
+        logicOp                = &glLogicOpNULL;
+        pixelStoref            = &glPixelStorefNULL;
+        pixelStorei            = &glPixelStoreiNULL;
+        pointSize              = &glPointSizeNULL;
+        polygonMode            = &glPolygonModeNULL;
+        readBuffer             = &glReadBufferNULL;
+        readPixels             = &glReadPixelsNULL;
+        scissor                = &glScissorNULL;
+        stencilFunc            = &glStencilFuncNULL;
+        stencilMask            = &glStencilMaskNULL;
+        stencilOp              = &glStencilOpNULL;
+        texImage1D             = &glTexImage1DNULL;
+        texImage2D             = &glTexImage2DNULL;
+        texParameterf          = &glTexParameterfNULL;
+        texParameterfv         = &glTexParameterfvNULL;
+        texParameteri          = &glTexParameteriNULL;
+        texParameteriv         = &glTexParameterivNULL;
+        viewport               = &glViewportNULL;
+    }
+
+    if (version >= gl::Version(1, 1))
+    {
+        bindTexture       = &glBindTextureNULL;
+        copyTexImage1D    = &glCopyTexImage1DNULL;
+        copyTexImage2D    = &glCopyTexImage2DNULL;
+        copyTexSubImage1D = &glCopyTexSubImage1DNULL;
+        copyTexSubImage2D = &glCopyTexSubImage2DNULL;
+        deleteTextures    = &glDeleteTexturesNULL;
+        drawArrays        = &glDrawArraysNULL;
+        drawElements      = &glDrawElementsNULL;
+        genTextures       = &glGenTexturesNULL;
+        isTexture         = &glIsTextureNULL;
+        polygonOffset     = &glPolygonOffsetNULL;
+        texSubImage1D     = &glTexSubImage1DNULL;
+        texSubImage2D     = &glTexSubImage2DNULL;
+    }
+
+    if (version >= gl::Version(1, 2))
+    {
+        copyTexSubImage3D = &glCopyTexSubImage3DNULL;
+        drawRangeElements = &glDrawRangeElementsNULL;
+        texImage3D        = &glTexImage3DNULL;
+        texSubImage3D     = &glTexSubImage3DNULL;
+    }
+
+    if (version >= gl::Version(1, 3))
+    {
+        activeTexture           = &glActiveTextureNULL;
+        compressedTexImage1D    = &glCompressedTexImage1DNULL;
+        compressedTexImage2D    = &glCompressedTexImage2DNULL;
+        compressedTexImage3D    = &glCompressedTexImage3DNULL;
+        compressedTexSubImage1D = &glCompressedTexSubImage1DNULL;
+        compressedTexSubImage2D = &glCompressedTexSubImage2DNULL;
+        compressedTexSubImage3D = &glCompressedTexSubImage3DNULL;
+        getCompressedTexImage   = &glGetCompressedTexImageNULL;
+        sampleCoverage          = &glSampleCoverageNULL;
+    }
+
+    if (version >= gl::Version(1, 4))
+    {
+        blendColor        = &glBlendColorNULL;
+        blendEquation     = &glBlendEquationNULL;
+        blendFuncSeparate = &glBlendFuncSeparateNULL;
+        multiDrawArrays   = &glMultiDrawArraysNULL;
+        multiDrawElements = &glMultiDrawElementsNULL;
+        pointParameterf   = &glPointParameterfNULL;
+        pointParameterfv  = &glPointParameterfvNULL;
+        pointParameteri   = &glPointParameteriNULL;
+        pointParameteriv  = &glPointParameterivNULL;
+    }
+
+    if (version >= gl::Version(1, 5))
+    {
+        beginQuery           = &glBeginQueryNULL;
+        bindBuffer           = &glBindBufferNULL;
+        bufferData           = &glBufferDataNULL;
+        bufferSubData        = &glBufferSubDataNULL;
+        deleteBuffers        = &glDeleteBuffersNULL;
+        deleteQueries        = &glDeleteQueriesNULL;
+        endQuery             = &glEndQueryNULL;
+        genBuffers           = &glGenBuffersNULL;
+        genQueries           = &glGenQueriesNULL;
+        getBufferParameteriv = &glGetBufferParameterivNULL;
+        getBufferPointerv    = &glGetBufferPointervNULL;
+        getBufferSubData     = &glGetBufferSubDataNULL;
+        getQueryObjectiv     = &glGetQueryObjectivNULL;
+        getQueryObjectuiv    = &glGetQueryObjectuivNULL;
+        getQueryiv           = &glGetQueryivNULL;
+        isBuffer             = &glIsBufferNULL;
+        isQuery              = &glIsQueryNULL;
+        mapBuffer            = &glMapBufferNULL;
+        unmapBuffer          = &glUnmapBufferNULL;
+    }
+
+    if (version >= gl::Version(2, 0))
+    {
+        attachShader             = &glAttachShaderNULL;
+        bindAttribLocation       = &glBindAttribLocationNULL;
+        blendEquationSeparate    = &glBlendEquationSeparateNULL;
+        compileShader            = &glCompileShaderNULL;
+        createProgram            = &glCreateProgramNULL;
+        createShader             = &glCreateShaderNULL;
+        deleteProgram            = &glDeleteProgramNULL;
+        deleteShader             = &glDeleteShaderNULL;
+        detachShader             = &glDetachShaderNULL;
+        disableVertexAttribArray = &glDisableVertexAttribArrayNULL;
+        drawBuffers              = &glDrawBuffersNULL;
+        enableVertexAttribArray  = &glEnableVertexAttribArrayNULL;
+        getActiveAttrib          = &glGetActiveAttribNULL;
+        getActiveUniform         = &glGetActiveUniformNULL;
+        getAttachedShaders       = &glGetAttachedShadersNULL;
+        getAttribLocation        = &glGetAttribLocationNULL;
+        getProgramInfoLog        = &glGetProgramInfoLogNULL;
+        getProgramiv             = &glGetProgramivNULL;
+        getShaderInfoLog         = &glGetShaderInfoLogNULL;
+        getShaderSource          = &glGetShaderSourceNULL;
+        getShaderiv              = &glGetShaderivNULL;
+        getUniformLocation       = &glGetUniformLocationNULL;
+        getUniformfv             = &glGetUniformfvNULL;
+        getUniformiv             = &glGetUniformivNULL;
+        getVertexAttribPointerv  = &glGetVertexAttribPointervNULL;
+        getVertexAttribdv        = &glGetVertexAttribdvNULL;
+        getVertexAttribfv        = &glGetVertexAttribfvNULL;
+        getVertexAttribiv        = &glGetVertexAttribivNULL;
+        isProgram                = &glIsProgramNULL;
+        isShader                 = &glIsShaderNULL;
+        linkProgram              = &glLinkProgramNULL;
+        shaderSource             = &glShaderSourceNULL;
+        stencilFuncSeparate      = &glStencilFuncSeparateNULL;
+        stencilMaskSeparate      = &glStencilMaskSeparateNULL;
+        stencilOpSeparate        = &glStencilOpSeparateNULL;
+        uniform1f                = &glUniform1fNULL;
+        uniform1fv               = &glUniform1fvNULL;
+        uniform1i                = &glUniform1iNULL;
+        uniform1iv               = &glUniform1ivNULL;
+        uniform2f                = &glUniform2fNULL;
+        uniform2fv               = &glUniform2fvNULL;
+        uniform2i                = &glUniform2iNULL;
+        uniform2iv               = &glUniform2ivNULL;
+        uniform3f                = &glUniform3fNULL;
+        uniform3fv               = &glUniform3fvNULL;
+        uniform3i                = &glUniform3iNULL;
+        uniform3iv               = &glUniform3ivNULL;
+        uniform4f                = &glUniform4fNULL;
+        uniform4fv               = &glUniform4fvNULL;
+        uniform4i                = &glUniform4iNULL;
+        uniform4iv               = &glUniform4ivNULL;
+        uniformMatrix2fv         = &glUniformMatrix2fvNULL;
+        uniformMatrix3fv         = &glUniformMatrix3fvNULL;
+        uniformMatrix4fv         = &glUniformMatrix4fvNULL;
+        useProgram               = &glUseProgramNULL;
+        validateProgram          = &glValidateProgramNULL;
+        vertexAttrib1d           = &glVertexAttrib1dNULL;
+        vertexAttrib1dv          = &glVertexAttrib1dvNULL;
+        vertexAttrib1f           = &glVertexAttrib1fNULL;
+        vertexAttrib1fv          = &glVertexAttrib1fvNULL;
+        vertexAttrib1s           = &glVertexAttrib1sNULL;
+        vertexAttrib1sv          = &glVertexAttrib1svNULL;
+        vertexAttrib2d           = &glVertexAttrib2dNULL;
+        vertexAttrib2dv          = &glVertexAttrib2dvNULL;
+        vertexAttrib2f           = &glVertexAttrib2fNULL;
+        vertexAttrib2fv          = &glVertexAttrib2fvNULL;
+        vertexAttrib2s           = &glVertexAttrib2sNULL;
+        vertexAttrib2sv          = &glVertexAttrib2svNULL;
+        vertexAttrib3d           = &glVertexAttrib3dNULL;
+        vertexAttrib3dv          = &glVertexAttrib3dvNULL;
+        vertexAttrib3f           = &glVertexAttrib3fNULL;
+        vertexAttrib3fv          = &glVertexAttrib3fvNULL;
+        vertexAttrib3s           = &glVertexAttrib3sNULL;
+        vertexAttrib3sv          = &glVertexAttrib3svNULL;
+        vertexAttrib4Nbv         = &glVertexAttrib4NbvNULL;
+        vertexAttrib4Niv         = &glVertexAttrib4NivNULL;
+        vertexAttrib4Nsv         = &glVertexAttrib4NsvNULL;
+        vertexAttrib4Nub         = &glVertexAttrib4NubNULL;
+        vertexAttrib4Nubv        = &glVertexAttrib4NubvNULL;
+        vertexAttrib4Nuiv        = &glVertexAttrib4NuivNULL;
+        vertexAttrib4Nusv        = &glVertexAttrib4NusvNULL;
+        vertexAttrib4bv          = &glVertexAttrib4bvNULL;
+        vertexAttrib4d           = &glVertexAttrib4dNULL;
+        vertexAttrib4dv          = &glVertexAttrib4dvNULL;
+        vertexAttrib4f           = &glVertexAttrib4fNULL;
+        vertexAttrib4fv          = &glVertexAttrib4fvNULL;
+        vertexAttrib4iv          = &glVertexAttrib4ivNULL;
+        vertexAttrib4s           = &glVertexAttrib4sNULL;
+        vertexAttrib4sv          = &glVertexAttrib4svNULL;
+        vertexAttrib4ubv         = &glVertexAttrib4ubvNULL;
+        vertexAttrib4uiv         = &glVertexAttrib4uivNULL;
+        vertexAttrib4usv         = &glVertexAttrib4usvNULL;
+        vertexAttribPointer      = &glVertexAttribPointerNULL;
+    }
+
+    if (version >= gl::Version(2, 1))
+    {
+        uniformMatrix2x3fv = &glUniformMatrix2x3fvNULL;
+        uniformMatrix2x4fv = &glUniformMatrix2x4fvNULL;
+        uniformMatrix3x2fv = &glUniformMatrix3x2fvNULL;
+        uniformMatrix3x4fv = &glUniformMatrix3x4fvNULL;
+        uniformMatrix4x2fv = &glUniformMatrix4x2fvNULL;
+        uniformMatrix4x3fv = &glUniformMatrix4x3fvNULL;
+    }
+
+    if (version >= gl::Version(3, 0))
+    {
+        beginConditionalRender              = &glBeginConditionalRenderNULL;
+        beginTransformFeedback              = &glBeginTransformFeedbackNULL;
+        bindBufferBase                      = &glBindBufferBaseNULL;
+        bindBufferRange                     = &glBindBufferRangeNULL;
+        bindFragDataLocation                = &glBindFragDataLocationNULL;
+        bindFramebuffer                     = &glBindFramebufferNULL;
+        bindRenderbuffer                    = &glBindRenderbufferNULL;
+        bindVertexArray                     = &glBindVertexArrayNULL;
+        blitFramebuffer                     = &glBlitFramebufferNULL;
+        checkFramebufferStatus              = &glCheckFramebufferStatusNULL;
+        clampColor                          = &glClampColorNULL;
+        clearBufferfi                       = &glClearBufferfiNULL;
+        clearBufferfv                       = &glClearBufferfvNULL;
+        clearBufferiv                       = &glClearBufferivNULL;
+        clearBufferuiv                      = &glClearBufferuivNULL;
+        colorMaski                          = &glColorMaskiNULL;
+        deleteFramebuffers                  = &glDeleteFramebuffersNULL;
+        deleteRenderbuffers                 = &glDeleteRenderbuffersNULL;
+        deleteVertexArrays                  = &glDeleteVertexArraysNULL;
+        disablei                            = &glDisableiNULL;
+        enablei                             = &glEnableiNULL;
+        endConditionalRender                = &glEndConditionalRenderNULL;
+        endTransformFeedback                = &glEndTransformFeedbackNULL;
+        flushMappedBufferRange              = &glFlushMappedBufferRangeNULL;
+        framebufferRenderbuffer             = &glFramebufferRenderbufferNULL;
+        framebufferTexture1D                = &glFramebufferTexture1DNULL;
+        framebufferTexture2D                = &glFramebufferTexture2DNULL;
+        framebufferTexture3D                = &glFramebufferTexture3DNULL;
+        framebufferTextureLayer             = &glFramebufferTextureLayerNULL;
+        genFramebuffers                     = &glGenFramebuffersNULL;
+        genRenderbuffers                    = &glGenRenderbuffersNULL;
+        genVertexArrays                     = &glGenVertexArraysNULL;
+        generateMipmap                      = &glGenerateMipmapNULL;
+        getBooleani_v                       = &glGetBooleani_vNULL;
+        getFragDataLocation                 = &glGetFragDataLocationNULL;
+        getFramebufferAttachmentParameteriv = &glGetFramebufferAttachmentParameterivNULL;
+        getIntegeri_v                       = &glGetIntegeri_vNULL;
+        getRenderbufferParameteriv          = &glGetRenderbufferParameterivNULL;
+        getStringi                          = &glGetStringiNULL;
+        getTexParameterIiv                  = &glGetTexParameterIivNULL;
+        getTexParameterIuiv                 = &glGetTexParameterIuivNULL;
+        getTransformFeedbackVarying         = &glGetTransformFeedbackVaryingNULL;
+        getUniformuiv                       = &glGetUniformuivNULL;
+        getVertexAttribIiv                  = &glGetVertexAttribIivNULL;
+        getVertexAttribIuiv                 = &glGetVertexAttribIuivNULL;
+        isEnabledi                          = &glIsEnablediNULL;
+        isFramebuffer                       = &glIsFramebufferNULL;
+        isRenderbuffer                      = &glIsRenderbufferNULL;
+        isVertexArray                       = &glIsVertexArrayNULL;
+        mapBufferRange                      = &glMapBufferRangeNULL;
+        renderbufferStorage                 = &glRenderbufferStorageNULL;
+        renderbufferStorageMultisample      = &glRenderbufferStorageMultisampleNULL;
+        texParameterIiv                     = &glTexParameterIivNULL;
+        texParameterIuiv                    = &glTexParameterIuivNULL;
+        transformFeedbackVaryings           = &glTransformFeedbackVaryingsNULL;
+        uniform1ui                          = &glUniform1uiNULL;
+        uniform1uiv                         = &glUniform1uivNULL;
+        uniform2ui                          = &glUniform2uiNULL;
+        uniform2uiv                         = &glUniform2uivNULL;
+        uniform3ui                          = &glUniform3uiNULL;
+        uniform3uiv                         = &glUniform3uivNULL;
+        uniform4ui                          = &glUniform4uiNULL;
+        uniform4uiv                         = &glUniform4uivNULL;
+        vertexAttribI1i                     = &glVertexAttribI1iNULL;
+        vertexAttribI1iv                    = &glVertexAttribI1ivNULL;
+        vertexAttribI1ui                    = &glVertexAttribI1uiNULL;
+        vertexAttribI1uiv                   = &glVertexAttribI1uivNULL;
+        vertexAttribI2i                     = &glVertexAttribI2iNULL;
+        vertexAttribI2iv                    = &glVertexAttribI2ivNULL;
+        vertexAttribI2ui                    = &glVertexAttribI2uiNULL;
+        vertexAttribI2uiv                   = &glVertexAttribI2uivNULL;
+        vertexAttribI3i                     = &glVertexAttribI3iNULL;
+        vertexAttribI3iv                    = &glVertexAttribI3ivNULL;
+        vertexAttribI3ui                    = &glVertexAttribI3uiNULL;
+        vertexAttribI3uiv                   = &glVertexAttribI3uivNULL;
+        vertexAttribI4bv                    = &glVertexAttribI4bvNULL;
+        vertexAttribI4i                     = &glVertexAttribI4iNULL;
+        vertexAttribI4iv                    = &glVertexAttribI4ivNULL;
+        vertexAttribI4sv                    = &glVertexAttribI4svNULL;
+        vertexAttribI4ubv                   = &glVertexAttribI4ubvNULL;
+        vertexAttribI4ui                    = &glVertexAttribI4uiNULL;
+        vertexAttribI4uiv                   = &glVertexAttribI4uivNULL;
+        vertexAttribI4usv                   = &glVertexAttribI4usvNULL;
+        vertexAttribIPointer                = &glVertexAttribIPointerNULL;
+    }
+
+    if (version >= gl::Version(3, 1))
+    {
+        copyBufferSubData         = &glCopyBufferSubDataNULL;
+        drawArraysInstanced       = &glDrawArraysInstancedNULL;
+        drawElementsInstanced     = &glDrawElementsInstancedNULL;
+        getActiveUniformBlockName = &glGetActiveUniformBlockNameNULL;
+        getActiveUniformBlockiv   = &glGetActiveUniformBlockivNULL;
+        getActiveUniformName      = &glGetActiveUniformNameNULL;
+        getActiveUniformsiv       = &glGetActiveUniformsivNULL;
+        getUniformBlockIndex      = &glGetUniformBlockIndexNULL;
+        getUniformIndices         = &glGetUniformIndicesNULL;
+        primitiveRestartIndex     = &glPrimitiveRestartIndexNULL;
+        texBuffer                 = &glTexBufferNULL;
+        uniformBlockBinding       = &glUniformBlockBindingNULL;
+    }
+
+    if (version >= gl::Version(3, 2))
+    {
+        clientWaitSync                  = &glClientWaitSyncNULL;
+        deleteSync                      = &glDeleteSyncNULL;
+        drawElementsBaseVertex          = &glDrawElementsBaseVertexNULL;
+        drawElementsInstancedBaseVertex = &glDrawElementsInstancedBaseVertexNULL;
+        drawRangeElementsBaseVertex     = &glDrawRangeElementsBaseVertexNULL;
+        fenceSync                       = &glFenceSyncNULL;
+        framebufferTexture              = &glFramebufferTextureNULL;
+        getBufferParameteri64v          = &glGetBufferParameteri64vNULL;
+        getInteger64i_v                 = &glGetInteger64i_vNULL;
+        getInteger64v                   = &glGetInteger64vNULL;
+        getMultisamplefv                = &glGetMultisamplefvNULL;
+        getSynciv                       = &glGetSyncivNULL;
+        isSync                          = &glIsSyncNULL;
+        multiDrawElementsBaseVertex     = &glMultiDrawElementsBaseVertexNULL;
+        provokingVertex                 = &glProvokingVertexNULL;
+        sampleMaski                     = &glSampleMaskiNULL;
+        texImage2DMultisample           = &glTexImage2DMultisampleNULL;
+        texImage3DMultisample           = &glTexImage3DMultisampleNULL;
+        waitSync                        = &glWaitSyncNULL;
+    }
+
+    if (version >= gl::Version(3, 3))
+    {
+        bindFragDataLocationIndexed = &glBindFragDataLocationIndexedNULL;
+        bindSampler                 = &glBindSamplerNULL;
+        deleteSamplers              = &glDeleteSamplersNULL;
+        genSamplers                 = &glGenSamplersNULL;
+        getFragDataIndex            = &glGetFragDataIndexNULL;
+        getQueryObjecti64v          = &glGetQueryObjecti64vNULL;
+        getQueryObjectui64v         = &glGetQueryObjectui64vNULL;
+        getSamplerParameterIiv      = &glGetSamplerParameterIivNULL;
+        getSamplerParameterIuiv     = &glGetSamplerParameterIuivNULL;
+        getSamplerParameterfv       = &glGetSamplerParameterfvNULL;
+        getSamplerParameteriv       = &glGetSamplerParameterivNULL;
+        isSampler                   = &glIsSamplerNULL;
+        queryCounter                = &glQueryCounterNULL;
+        samplerParameterIiv         = &glSamplerParameterIivNULL;
+        samplerParameterIuiv        = &glSamplerParameterIuivNULL;
+        samplerParameterf           = &glSamplerParameterfNULL;
+        samplerParameterfv          = &glSamplerParameterfvNULL;
+        samplerParameteri           = &glSamplerParameteriNULL;
+        samplerParameteriv          = &glSamplerParameterivNULL;
+        vertexAttribDivisor         = &glVertexAttribDivisorNULL;
+        vertexAttribP1ui            = &glVertexAttribP1uiNULL;
+        vertexAttribP1uiv           = &glVertexAttribP1uivNULL;
+        vertexAttribP2ui            = &glVertexAttribP2uiNULL;
+        vertexAttribP2uiv           = &glVertexAttribP2uivNULL;
+        vertexAttribP3ui            = &glVertexAttribP3uiNULL;
+        vertexAttribP3uiv           = &glVertexAttribP3uivNULL;
+        vertexAttribP4ui            = &glVertexAttribP4uiNULL;
+        vertexAttribP4uiv           = &glVertexAttribP4uivNULL;
+    }
+
+    if (version >= gl::Version(4, 0))
+    {
+        beginQueryIndexed              = &glBeginQueryIndexedNULL;
+        bindTransformFeedback          = &glBindTransformFeedbackNULL;
+        blendEquationSeparatei         = &glBlendEquationSeparateiNULL;
+        blendEquationi                 = &glBlendEquationiNULL;
+        blendFuncSeparatei             = &glBlendFuncSeparateiNULL;
+        blendFunci                     = &glBlendFunciNULL;
+        deleteTransformFeedbacks       = &glDeleteTransformFeedbacksNULL;
+        drawArraysIndirect             = &glDrawArraysIndirectNULL;
+        drawElementsIndirect           = &glDrawElementsIndirectNULL;
+        drawTransformFeedback          = &glDrawTransformFeedbackNULL;
+        drawTransformFeedbackStream    = &glDrawTransformFeedbackStreamNULL;
+        endQueryIndexed                = &glEndQueryIndexedNULL;
+        genTransformFeedbacks          = &glGenTransformFeedbacksNULL;
+        getActiveSubroutineName        = &glGetActiveSubroutineNameNULL;
+        getActiveSubroutineUniformName = &glGetActiveSubroutineUniformNameNULL;
+        getActiveSubroutineUniformiv   = &glGetActiveSubroutineUniformivNULL;
+        getProgramStageiv              = &glGetProgramStageivNULL;
+        getQueryIndexediv              = &glGetQueryIndexedivNULL;
+        getSubroutineIndex             = &glGetSubroutineIndexNULL;
+        getSubroutineUniformLocation   = &glGetSubroutineUniformLocationNULL;
+        getUniformSubroutineuiv        = &glGetUniformSubroutineuivNULL;
+        getUniformdv                   = &glGetUniformdvNULL;
+        isTransformFeedback            = &glIsTransformFeedbackNULL;
+        minSampleShading               = &glMinSampleShadingNULL;
+        patchParameterfv               = &glPatchParameterfvNULL;
+        patchParameteri                = &glPatchParameteriNULL;
+        pauseTransformFeedback         = &glPauseTransformFeedbackNULL;
+        resumeTransformFeedback        = &glResumeTransformFeedbackNULL;
+        uniform1d                      = &glUniform1dNULL;
+        uniform1dv                     = &glUniform1dvNULL;
+        uniform2d                      = &glUniform2dNULL;
+        uniform2dv                     = &glUniform2dvNULL;
+        uniform3d                      = &glUniform3dNULL;
+        uniform3dv                     = &glUniform3dvNULL;
+        uniform4d                      = &glUniform4dNULL;
+        uniform4dv                     = &glUniform4dvNULL;
+        uniformMatrix2dv               = &glUniformMatrix2dvNULL;
+        uniformMatrix2x3dv             = &glUniformMatrix2x3dvNULL;
+        uniformMatrix2x4dv             = &glUniformMatrix2x4dvNULL;
+        uniformMatrix3dv               = &glUniformMatrix3dvNULL;
+        uniformMatrix3x2dv             = &glUniformMatrix3x2dvNULL;
+        uniformMatrix3x4dv             = &glUniformMatrix3x4dvNULL;
+        uniformMatrix4dv               = &glUniformMatrix4dvNULL;
+        uniformMatrix4x2dv             = &glUniformMatrix4x2dvNULL;
+        uniformMatrix4x3dv             = &glUniformMatrix4x3dvNULL;
+        uniformSubroutinesuiv          = &glUniformSubroutinesuivNULL;
+    }
+
+    if (version >= gl::Version(4, 1))
+    {
+        activeShaderProgram       = &glActiveShaderProgramNULL;
+        bindProgramPipeline       = &glBindProgramPipelineNULL;
+        clearDepthf               = &glClearDepthfNULL;
+        createShaderProgramv      = &glCreateShaderProgramvNULL;
+        deleteProgramPipelines    = &glDeleteProgramPipelinesNULL;
+        depthRangeArrayv          = &glDepthRangeArrayvNULL;
+        depthRangeIndexed         = &glDepthRangeIndexedNULL;
+        depthRangef               = &glDepthRangefNULL;
+        genProgramPipelines       = &glGenProgramPipelinesNULL;
+        getDoublei_v              = &glGetDoublei_vNULL;
+        getFloati_v               = &glGetFloati_vNULL;
+        getProgramBinary          = &glGetProgramBinaryNULL;
+        getProgramPipelineInfoLog = &glGetProgramPipelineInfoLogNULL;
+        getProgramPipelineiv      = &glGetProgramPipelineivNULL;
+        getShaderPrecisionFormat  = &glGetShaderPrecisionFormatNULL;
+        getVertexAttribLdv        = &glGetVertexAttribLdvNULL;
+        isProgramPipeline         = &glIsProgramPipelineNULL;
+        programBinary             = &glProgramBinaryNULL;
+        programParameteri         = &glProgramParameteriNULL;
+        programUniform1d          = &glProgramUniform1dNULL;
+        programUniform1dv         = &glProgramUniform1dvNULL;
+        programUniform1f          = &glProgramUniform1fNULL;
+        programUniform1fv         = &glProgramUniform1fvNULL;
+        programUniform1i          = &glProgramUniform1iNULL;
+        programUniform1iv         = &glProgramUniform1ivNULL;
+        programUniform1ui         = &glProgramUniform1uiNULL;
+        programUniform1uiv        = &glProgramUniform1uivNULL;
+        programUniform2d          = &glProgramUniform2dNULL;
+        programUniform2dv         = &glProgramUniform2dvNULL;
+        programUniform2f          = &glProgramUniform2fNULL;
+        programUniform2fv         = &glProgramUniform2fvNULL;
+        programUniform2i          = &glProgramUniform2iNULL;
+        programUniform2iv         = &glProgramUniform2ivNULL;
+        programUniform2ui         = &glProgramUniform2uiNULL;
+        programUniform2uiv        = &glProgramUniform2uivNULL;
+        programUniform3d          = &glProgramUniform3dNULL;
+        programUniform3dv         = &glProgramUniform3dvNULL;
+        programUniform3f          = &glProgramUniform3fNULL;
+        programUniform3fv         = &glProgramUniform3fvNULL;
+        programUniform3i          = &glProgramUniform3iNULL;
+        programUniform3iv         = &glProgramUniform3ivNULL;
+        programUniform3ui         = &glProgramUniform3uiNULL;
+        programUniform3uiv        = &glProgramUniform3uivNULL;
+        programUniform4d          = &glProgramUniform4dNULL;
+        programUniform4dv         = &glProgramUniform4dvNULL;
+        programUniform4f          = &glProgramUniform4fNULL;
+        programUniform4fv         = &glProgramUniform4fvNULL;
+        programUniform4i          = &glProgramUniform4iNULL;
+        programUniform4iv         = &glProgramUniform4ivNULL;
+        programUniform4ui         = &glProgramUniform4uiNULL;
+        programUniform4uiv        = &glProgramUniform4uivNULL;
+        programUniformMatrix2dv   = &glProgramUniformMatrix2dvNULL;
+        programUniformMatrix2fv   = &glProgramUniformMatrix2fvNULL;
+        programUniformMatrix2x3dv = &glProgramUniformMatrix2x3dvNULL;
+        programUniformMatrix2x3fv = &glProgramUniformMatrix2x3fvNULL;
+        programUniformMatrix2x4dv = &glProgramUniformMatrix2x4dvNULL;
+        programUniformMatrix2x4fv = &glProgramUniformMatrix2x4fvNULL;
+        programUniformMatrix3dv   = &glProgramUniformMatrix3dvNULL;
+        programUniformMatrix3fv   = &glProgramUniformMatrix3fvNULL;
+        programUniformMatrix3x2dv = &glProgramUniformMatrix3x2dvNULL;
+        programUniformMatrix3x2fv = &glProgramUniformMatrix3x2fvNULL;
+        programUniformMatrix3x4dv = &glProgramUniformMatrix3x4dvNULL;
+        programUniformMatrix3x4fv = &glProgramUniformMatrix3x4fvNULL;
+        programUniformMatrix4dv   = &glProgramUniformMatrix4dvNULL;
+        programUniformMatrix4fv   = &glProgramUniformMatrix4fvNULL;
+        programUniformMatrix4x2dv = &glProgramUniformMatrix4x2dvNULL;
+        programUniformMatrix4x2fv = &glProgramUniformMatrix4x2fvNULL;
+        programUniformMatrix4x3dv = &glProgramUniformMatrix4x3dvNULL;
+        programUniformMatrix4x3fv = &glProgramUniformMatrix4x3fvNULL;
+        releaseShaderCompiler     = &glReleaseShaderCompilerNULL;
+        scissorArrayv             = &glScissorArrayvNULL;
+        scissorIndexed            = &glScissorIndexedNULL;
+        scissorIndexedv           = &glScissorIndexedvNULL;
+        shaderBinary              = &glShaderBinaryNULL;
+        useProgramStages          = &glUseProgramStagesNULL;
+        validateProgramPipeline   = &glValidateProgramPipelineNULL;
+        vertexAttribL1d           = &glVertexAttribL1dNULL;
+        vertexAttribL1dv          = &glVertexAttribL1dvNULL;
+        vertexAttribL2d           = &glVertexAttribL2dNULL;
+        vertexAttribL2dv          = &glVertexAttribL2dvNULL;
+        vertexAttribL3d           = &glVertexAttribL3dNULL;
+        vertexAttribL3dv          = &glVertexAttribL3dvNULL;
+        vertexAttribL4d           = &glVertexAttribL4dNULL;
+        vertexAttribL4dv          = &glVertexAttribL4dvNULL;
+        vertexAttribLPointer      = &glVertexAttribLPointerNULL;
+        viewportArrayv            = &glViewportArrayvNULL;
+        viewportIndexedf          = &glViewportIndexedfNULL;
+        viewportIndexedfv         = &glViewportIndexedfvNULL;
+    }
+
+    if (version >= gl::Version(4, 2))
+    {
+        bindImageTexture                  = &glBindImageTextureNULL;
+        drawArraysInstancedBaseInstance   = &glDrawArraysInstancedBaseInstanceNULL;
+        drawElementsInstancedBaseInstance = &glDrawElementsInstancedBaseInstanceNULL;
+        drawElementsInstancedBaseVertexBaseInstance =
+            &glDrawElementsInstancedBaseVertexBaseInstanceNULL;
+        drawTransformFeedbackInstanced       = &glDrawTransformFeedbackInstancedNULL;
+        drawTransformFeedbackStreamInstanced = &glDrawTransformFeedbackStreamInstancedNULL;
+        getActiveAtomicCounterBufferiv       = &glGetActiveAtomicCounterBufferivNULL;
+        getInternalformativ                  = &glGetInternalformativNULL;
+        memoryBarrier                        = &glMemoryBarrierNULL;
+        texStorage1D                         = &glTexStorage1DNULL;
+        texStorage2D                         = &glTexStorage2DNULL;
+        texStorage3D                         = &glTexStorage3DNULL;
+    }
+
+    if (version >= gl::Version(4, 3))
+    {
+        bindVertexBuffer                = &glBindVertexBufferNULL;
+        clearBufferData                 = &glClearBufferDataNULL;
+        clearBufferSubData              = &glClearBufferSubDataNULL;
+        copyImageSubData                = &glCopyImageSubDataNULL;
+        debugMessageCallback            = &glDebugMessageCallbackNULL;
+        debugMessageControl             = &glDebugMessageControlNULL;
+        debugMessageInsert              = &glDebugMessageInsertNULL;
+        dispatchCompute                 = &glDispatchComputeNULL;
+        dispatchComputeIndirect         = &glDispatchComputeIndirectNULL;
+        framebufferParameteri           = &glFramebufferParameteriNULL;
+        getDebugMessageLog              = &glGetDebugMessageLogNULL;
+        getFramebufferParameteriv       = &glGetFramebufferParameterivNULL;
+        getInternalformati64v           = &glGetInternalformati64vNULL;
+        getObjectLabel                  = &glGetObjectLabelNULL;
+        getObjectPtrLabel               = &glGetObjectPtrLabelNULL;
+        getPointerv                     = &glGetPointervNULL;
+        getProgramInterfaceiv           = &glGetProgramInterfaceivNULL;
+        getProgramResourceIndex         = &glGetProgramResourceIndexNULL;
+        getProgramResourceLocation      = &glGetProgramResourceLocationNULL;
+        getProgramResourceLocationIndex = &glGetProgramResourceLocationIndexNULL;
+        getProgramResourceName          = &glGetProgramResourceNameNULL;
+        getProgramResourceiv            = &glGetProgramResourceivNULL;
+        invalidateBufferData            = &glInvalidateBufferDataNULL;
+        invalidateBufferSubData         = &glInvalidateBufferSubDataNULL;
+        invalidateFramebuffer           = &glInvalidateFramebufferNULL;
+        invalidateSubFramebuffer        = &glInvalidateSubFramebufferNULL;
+        invalidateTexImage              = &glInvalidateTexImageNULL;
+        invalidateTexSubImage           = &glInvalidateTexSubImageNULL;
+        multiDrawArraysIndirect         = &glMultiDrawArraysIndirectNULL;
+        multiDrawElementsIndirect       = &glMultiDrawElementsIndirectNULL;
+        objectLabel                     = &glObjectLabelNULL;
+        objectPtrLabel                  = &glObjectPtrLabelNULL;
+        popDebugGroup                   = &glPopDebugGroupNULL;
+        pushDebugGroup                  = &glPushDebugGroupNULL;
+        shaderStorageBlockBinding       = &glShaderStorageBlockBindingNULL;
+        texBufferRange                  = &glTexBufferRangeNULL;
+        texStorage2DMultisample         = &glTexStorage2DMultisampleNULL;
+        texStorage3DMultisample         = &glTexStorage3DMultisampleNULL;
+        textureView                     = &glTextureViewNULL;
+        vertexAttribBinding             = &glVertexAttribBindingNULL;
+        vertexAttribFormat              = &glVertexAttribFormatNULL;
+        vertexAttribIFormat             = &glVertexAttribIFormatNULL;
+        vertexAttribLFormat             = &glVertexAttribLFormatNULL;
+        vertexBindingDivisor            = &glVertexBindingDivisorNULL;
+    }
+
+    if (version >= gl::Version(4, 4))
+    {
+        bindBuffersBase   = &glBindBuffersBaseNULL;
+        bindBuffersRange  = &glBindBuffersRangeNULL;
+        bindImageTextures = &glBindImageTexturesNULL;
+        bindSamplers      = &glBindSamplersNULL;
+        bindTextures      = &glBindTexturesNULL;
+        bindVertexBuffers = &glBindVertexBuffersNULL;
+        bufferStorage     = &glBufferStorageNULL;
+        clearTexImage     = &glClearTexImageNULL;
+        clearTexSubImage  = &glClearTexSubImageNULL;
+    }
+
+    if (version >= gl::Version(4, 5))
+    {
+        bindTextureUnit                          = &glBindTextureUnitNULL;
+        blitNamedFramebuffer                     = &glBlitNamedFramebufferNULL;
+        checkNamedFramebufferStatus              = &glCheckNamedFramebufferStatusNULL;
+        clearNamedBufferData                     = &glClearNamedBufferDataNULL;
+        clearNamedBufferSubData                  = &glClearNamedBufferSubDataNULL;
+        clearNamedFramebufferfi                  = &glClearNamedFramebufferfiNULL;
+        clearNamedFramebufferfv                  = &glClearNamedFramebufferfvNULL;
+        clearNamedFramebufferiv                  = &glClearNamedFramebufferivNULL;
+        clearNamedFramebufferuiv                 = &glClearNamedFramebufferuivNULL;
+        clipControl                              = &glClipControlNULL;
+        compressedTextureSubImage1D              = &glCompressedTextureSubImage1DNULL;
+        compressedTextureSubImage2D              = &glCompressedTextureSubImage2DNULL;
+        compressedTextureSubImage3D              = &glCompressedTextureSubImage3DNULL;
+        copyNamedBufferSubData                   = &glCopyNamedBufferSubDataNULL;
+        copyTextureSubImage1D                    = &glCopyTextureSubImage1DNULL;
+        copyTextureSubImage2D                    = &glCopyTextureSubImage2DNULL;
+        copyTextureSubImage3D                    = &glCopyTextureSubImage3DNULL;
+        createBuffers                            = &glCreateBuffersNULL;
+        createFramebuffers                       = &glCreateFramebuffersNULL;
+        createProgramPipelines                   = &glCreateProgramPipelinesNULL;
+        createQueries                            = &glCreateQueriesNULL;
+        createRenderbuffers                      = &glCreateRenderbuffersNULL;
+        createSamplers                           = &glCreateSamplersNULL;
+        createTextures                           = &glCreateTexturesNULL;
+        createTransformFeedbacks                 = &glCreateTransformFeedbacksNULL;
+        createVertexArrays                       = &glCreateVertexArraysNULL;
+        disableVertexArrayAttrib                 = &glDisableVertexArrayAttribNULL;
+        enableVertexArrayAttrib                  = &glEnableVertexArrayAttribNULL;
+        flushMappedNamedBufferRange              = &glFlushMappedNamedBufferRangeNULL;
+        generateTextureMipmap                    = &glGenerateTextureMipmapNULL;
+        getCompressedTextureImage                = &glGetCompressedTextureImageNULL;
+        getCompressedTextureSubImage             = &glGetCompressedTextureSubImageNULL;
+        getGraphicsResetStatus                   = &glGetGraphicsResetStatusNULL;
+        getNamedBufferParameteri64v              = &glGetNamedBufferParameteri64vNULL;
+        getNamedBufferParameteriv                = &glGetNamedBufferParameterivNULL;
+        getNamedBufferPointerv                   = &glGetNamedBufferPointervNULL;
+        getNamedBufferSubData                    = &glGetNamedBufferSubDataNULL;
+        getNamedFramebufferAttachmentParameteriv = &glGetNamedFramebufferAttachmentParameterivNULL;
+        getNamedFramebufferParameteriv           = &glGetNamedFramebufferParameterivNULL;
+        getNamedRenderbufferParameteriv          = &glGetNamedRenderbufferParameterivNULL;
+        getQueryBufferObjecti64v                 = &glGetQueryBufferObjecti64vNULL;
+        getQueryBufferObjectiv                   = &glGetQueryBufferObjectivNULL;
+        getQueryBufferObjectui64v                = &glGetQueryBufferObjectui64vNULL;
+        getQueryBufferObjectuiv                  = &glGetQueryBufferObjectuivNULL;
+        getTextureImage                          = &glGetTextureImageNULL;
+        getTextureLevelParameterfv               = &glGetTextureLevelParameterfvNULL;
+        getTextureLevelParameteriv               = &glGetTextureLevelParameterivNULL;
+        getTextureParameterIiv                   = &glGetTextureParameterIivNULL;
+        getTextureParameterIuiv                  = &glGetTextureParameterIuivNULL;
+        getTextureParameterfv                    = &glGetTextureParameterfvNULL;
+        getTextureParameteriv                    = &glGetTextureParameterivNULL;
+        getTextureSubImage                       = &glGetTextureSubImageNULL;
+        getTransformFeedbacki64_v                = &glGetTransformFeedbacki64_vNULL;
+        getTransformFeedbacki_v                  = &glGetTransformFeedbacki_vNULL;
+        getTransformFeedbackiv                   = &glGetTransformFeedbackivNULL;
+        getVertexArrayIndexed64iv                = &glGetVertexArrayIndexed64ivNULL;
+        getVertexArrayIndexediv                  = &glGetVertexArrayIndexedivNULL;
+        getVertexArrayiv                         = &glGetVertexArrayivNULL;
+        getnCompressedTexImage                   = &glGetnCompressedTexImageNULL;
+        getnTexImage                             = &glGetnTexImageNULL;
+        getnUniformdv                            = &glGetnUniformdvNULL;
+        getnUniformfv                            = &glGetnUniformfvNULL;
+        getnUniformiv                            = &glGetnUniformivNULL;
+        getnUniformuiv                           = &glGetnUniformuivNULL;
+        invalidateNamedFramebufferData           = &glInvalidateNamedFramebufferDataNULL;
+        invalidateNamedFramebufferSubData        = &glInvalidateNamedFramebufferSubDataNULL;
+        mapNamedBuffer                           = &glMapNamedBufferNULL;
+        mapNamedBufferRange                      = &glMapNamedBufferRangeNULL;
+        memoryBarrierByRegion                    = &glMemoryBarrierByRegionNULL;
+        namedBufferData                          = &glNamedBufferDataNULL;
+        namedBufferStorage                       = &glNamedBufferStorageNULL;
+        namedBufferSubData                       = &glNamedBufferSubDataNULL;
+        namedFramebufferDrawBuffer               = &glNamedFramebufferDrawBufferNULL;
+        namedFramebufferDrawBuffers              = &glNamedFramebufferDrawBuffersNULL;
+        namedFramebufferParameteri               = &glNamedFramebufferParameteriNULL;
+        namedFramebufferReadBuffer               = &glNamedFramebufferReadBufferNULL;
+        namedFramebufferRenderbuffer             = &glNamedFramebufferRenderbufferNULL;
+        namedFramebufferTexture                  = &glNamedFramebufferTextureNULL;
+        namedFramebufferTextureLayer             = &glNamedFramebufferTextureLayerNULL;
+        namedRenderbufferStorage                 = &glNamedRenderbufferStorageNULL;
+        namedRenderbufferStorageMultisample      = &glNamedRenderbufferStorageMultisampleNULL;
+        readnPixels                              = &glReadnPixelsNULL;
+        textureBarrier                           = &glTextureBarrierNULL;
+        textureBuffer                            = &glTextureBufferNULL;
+        textureBufferRange                       = &glTextureBufferRangeNULL;
+        textureParameterIiv                      = &glTextureParameterIivNULL;
+        textureParameterIuiv                     = &glTextureParameterIuivNULL;
+        textureParameterf                        = &glTextureParameterfNULL;
+        textureParameterfv                       = &glTextureParameterfvNULL;
+        textureParameteri                        = &glTextureParameteriNULL;
+        textureParameteriv                       = &glTextureParameterivNULL;
+        textureStorage1D                         = &glTextureStorage1DNULL;
+        textureStorage2D                         = &glTextureStorage2DNULL;
+        textureStorage2DMultisample              = &glTextureStorage2DMultisampleNULL;
+        textureStorage3D                         = &glTextureStorage3DNULL;
+        textureStorage3DMultisample              = &glTextureStorage3DMultisampleNULL;
+        textureSubImage1D                        = &glTextureSubImage1DNULL;
+        textureSubImage2D                        = &glTextureSubImage2DNULL;
+        textureSubImage3D                        = &glTextureSubImage3DNULL;
+        transformFeedbackBufferBase              = &glTransformFeedbackBufferBaseNULL;
+        transformFeedbackBufferRange             = &glTransformFeedbackBufferRangeNULL;
+        unmapNamedBuffer                         = &glUnmapNamedBufferNULL;
+        vertexArrayAttribBinding                 = &glVertexArrayAttribBindingNULL;
+        vertexArrayAttribFormat                  = &glVertexArrayAttribFormatNULL;
+        vertexArrayAttribIFormat                 = &glVertexArrayAttribIFormatNULL;
+        vertexArrayAttribLFormat                 = &glVertexArrayAttribLFormatNULL;
+        vertexArrayBindingDivisor                = &glVertexArrayBindingDivisorNULL;
+        vertexArrayElementBuffer                 = &glVertexArrayElementBufferNULL;
+        vertexArrayVertexBuffer                  = &glVertexArrayVertexBufferNULL;
+        vertexArrayVertexBuffers                 = &glVertexArrayVertexBuffersNULL;
+    }
+
+    if (extensions.count("GL_ARB_ES2_compatibility") != 0)
+    {
+        clearDepthf              = &glClearDepthfNULL;
+        depthRangef              = &glDepthRangefNULL;
+        getShaderPrecisionFormat = &glGetShaderPrecisionFormatNULL;
+        releaseShaderCompiler    = &glReleaseShaderCompilerNULL;
+        shaderBinary             = &glShaderBinaryNULL;
+    }
+
+    if (extensions.count("GL_ARB_ES3_1_compatibility") != 0)
+    {
+        memoryBarrierByRegion = &glMemoryBarrierByRegionNULL;
+    }
+
+    if (extensions.count("GL_ARB_ES3_2_compatibility") != 0)
+    {
+        primitiveBoundingBox = &glPrimitiveBoundingBoxNULL;
+    }
+
+    if (extensions.count("GL_ARB_base_instance") != 0)
+    {
+        drawArraysInstancedBaseInstance   = &glDrawArraysInstancedBaseInstanceNULL;
+        drawElementsInstancedBaseInstance = &glDrawElementsInstancedBaseInstanceNULL;
+        drawElementsInstancedBaseVertexBaseInstance =
+            &glDrawElementsInstancedBaseVertexBaseInstanceNULL;
+    }
+
+    if (extensions.count("GL_ARB_blend_func_extended") != 0)
+    {
+        bindFragDataLocationIndexed = &glBindFragDataLocationIndexedNULL;
+        getFragDataIndex            = &glGetFragDataIndexNULL;
+    }
+
+    if (extensions.count("GL_ARB_buffer_storage") != 0)
+    {
+        bufferStorage = &glBufferStorageNULL;
+    }
+
+    if (extensions.count("GL_ARB_clear_buffer_object") != 0)
+    {
+        clearBufferData    = &glClearBufferDataNULL;
+        clearBufferSubData = &glClearBufferSubDataNULL;
+    }
+
+    if (extensions.count("GL_ARB_clear_texture") != 0)
+    {
+        clearTexImage    = &glClearTexImageNULL;
+        clearTexSubImage = &glClearTexSubImageNULL;
+    }
+
+    if (extensions.count("GL_ARB_clip_control") != 0)
+    {
+        clipControl = &glClipControlNULL;
+    }
+
+    if (extensions.count("GL_ARB_color_buffer_float") != 0)
+    {
+        clampColor = &glClampColorNULL;
+    }
+
+    if (extensions.count("GL_ARB_compute_shader") != 0)
+    {
+        dispatchCompute         = &glDispatchComputeNULL;
+        dispatchComputeIndirect = &glDispatchComputeIndirectNULL;
+    }
+
+    if (extensions.count("GL_ARB_copy_buffer") != 0)
+    {
+        copyBufferSubData = &glCopyBufferSubDataNULL;
+    }
+
+    if (extensions.count("GL_ARB_copy_image") != 0)
+    {
+        copyImageSubData = &glCopyImageSubDataNULL;
+    }
+
+    if (extensions.count("GL_ARB_debug_output") != 0)
+    {
+        debugMessageCallback = &glDebugMessageCallbackNULL;
+        debugMessageControl  = &glDebugMessageControlNULL;
+        debugMessageInsert   = &glDebugMessageInsertNULL;
+        getDebugMessageLog   = &glGetDebugMessageLogNULL;
+    }
+
+    if (extensions.count("GL_ARB_direct_state_access") != 0)
+    {
+        bindTextureUnit                          = &glBindTextureUnitNULL;
+        blitNamedFramebuffer                     = &glBlitNamedFramebufferNULL;
+        checkNamedFramebufferStatus              = &glCheckNamedFramebufferStatusNULL;
+        clearNamedBufferData                     = &glClearNamedBufferDataNULL;
+        clearNamedBufferSubData                  = &glClearNamedBufferSubDataNULL;
+        clearNamedFramebufferfi                  = &glClearNamedFramebufferfiNULL;
+        clearNamedFramebufferfv                  = &glClearNamedFramebufferfvNULL;
+        clearNamedFramebufferiv                  = &glClearNamedFramebufferivNULL;
+        clearNamedFramebufferuiv                 = &glClearNamedFramebufferuivNULL;
+        compressedTextureSubImage1D              = &glCompressedTextureSubImage1DNULL;
+        compressedTextureSubImage2D              = &glCompressedTextureSubImage2DNULL;
+        compressedTextureSubImage3D              = &glCompressedTextureSubImage3DNULL;
+        copyNamedBufferSubData                   = &glCopyNamedBufferSubDataNULL;
+        copyTextureSubImage1D                    = &glCopyTextureSubImage1DNULL;
+        copyTextureSubImage2D                    = &glCopyTextureSubImage2DNULL;
+        copyTextureSubImage3D                    = &glCopyTextureSubImage3DNULL;
+        createBuffers                            = &glCreateBuffersNULL;
+        createFramebuffers                       = &glCreateFramebuffersNULL;
+        createProgramPipelines                   = &glCreateProgramPipelinesNULL;
+        createQueries                            = &glCreateQueriesNULL;
+        createRenderbuffers                      = &glCreateRenderbuffersNULL;
+        createSamplers                           = &glCreateSamplersNULL;
+        createTextures                           = &glCreateTexturesNULL;
+        createTransformFeedbacks                 = &glCreateTransformFeedbacksNULL;
+        createVertexArrays                       = &glCreateVertexArraysNULL;
+        disableVertexArrayAttrib                 = &glDisableVertexArrayAttribNULL;
+        enableVertexArrayAttrib                  = &glEnableVertexArrayAttribNULL;
+        flushMappedNamedBufferRange              = &glFlushMappedNamedBufferRangeNULL;
+        generateTextureMipmap                    = &glGenerateTextureMipmapNULL;
+        getCompressedTextureImage                = &glGetCompressedTextureImageNULL;
+        getNamedBufferParameteri64v              = &glGetNamedBufferParameteri64vNULL;
+        getNamedBufferParameteriv                = &glGetNamedBufferParameterivNULL;
+        getNamedBufferPointerv                   = &glGetNamedBufferPointervNULL;
+        getNamedBufferSubData                    = &glGetNamedBufferSubDataNULL;
+        getNamedFramebufferAttachmentParameteriv = &glGetNamedFramebufferAttachmentParameterivNULL;
+        getNamedFramebufferParameteriv           = &glGetNamedFramebufferParameterivNULL;
+        getNamedRenderbufferParameteriv          = &glGetNamedRenderbufferParameterivNULL;
+        getQueryBufferObjecti64v                 = &glGetQueryBufferObjecti64vNULL;
+        getQueryBufferObjectiv                   = &glGetQueryBufferObjectivNULL;
+        getQueryBufferObjectui64v                = &glGetQueryBufferObjectui64vNULL;
+        getQueryBufferObjectuiv                  = &glGetQueryBufferObjectuivNULL;
+        getTextureImage                          = &glGetTextureImageNULL;
+        getTextureLevelParameterfv               = &glGetTextureLevelParameterfvNULL;
+        getTextureLevelParameteriv               = &glGetTextureLevelParameterivNULL;
+        getTextureParameterIiv                   = &glGetTextureParameterIivNULL;
+        getTextureParameterIuiv                  = &glGetTextureParameterIuivNULL;
+        getTextureParameterfv                    = &glGetTextureParameterfvNULL;
+        getTextureParameteriv                    = &glGetTextureParameterivNULL;
+        getTransformFeedbacki64_v                = &glGetTransformFeedbacki64_vNULL;
+        getTransformFeedbacki_v                  = &glGetTransformFeedbacki_vNULL;
+        getTransformFeedbackiv                   = &glGetTransformFeedbackivNULL;
+        getVertexArrayIndexed64iv                = &glGetVertexArrayIndexed64ivNULL;
+        getVertexArrayIndexediv                  = &glGetVertexArrayIndexedivNULL;
+        getVertexArrayiv                         = &glGetVertexArrayivNULL;
+        invalidateNamedFramebufferData           = &glInvalidateNamedFramebufferDataNULL;
+        invalidateNamedFramebufferSubData        = &glInvalidateNamedFramebufferSubDataNULL;
+        mapNamedBuffer                           = &glMapNamedBufferNULL;
+        mapNamedBufferRange                      = &glMapNamedBufferRangeNULL;
+        namedBufferData                          = &glNamedBufferDataNULL;
+        namedBufferStorage                       = &glNamedBufferStorageNULL;
+        namedBufferSubData                       = &glNamedBufferSubDataNULL;
+        namedFramebufferDrawBuffer               = &glNamedFramebufferDrawBufferNULL;
+        namedFramebufferDrawBuffers              = &glNamedFramebufferDrawBuffersNULL;
+        namedFramebufferParameteri               = &glNamedFramebufferParameteriNULL;
+        namedFramebufferReadBuffer               = &glNamedFramebufferReadBufferNULL;
+        namedFramebufferRenderbuffer             = &glNamedFramebufferRenderbufferNULL;
+        namedFramebufferTexture                  = &glNamedFramebufferTextureNULL;
+        namedFramebufferTextureLayer             = &glNamedFramebufferTextureLayerNULL;
+        namedRenderbufferStorage                 = &glNamedRenderbufferStorageNULL;
+        namedRenderbufferStorageMultisample      = &glNamedRenderbufferStorageMultisampleNULL;
+        textureBuffer                            = &glTextureBufferNULL;
+        textureBufferRange                       = &glTextureBufferRangeNULL;
+        textureParameterIiv                      = &glTextureParameterIivNULL;
+        textureParameterIuiv                     = &glTextureParameterIuivNULL;
+        textureParameterf                        = &glTextureParameterfNULL;
+        textureParameterfv                       = &glTextureParameterfvNULL;
+        textureParameteri                        = &glTextureParameteriNULL;
+        textureParameteriv                       = &glTextureParameterivNULL;
+        textureStorage1D                         = &glTextureStorage1DNULL;
+        textureStorage2D                         = &glTextureStorage2DNULL;
+        textureStorage2DMultisample              = &glTextureStorage2DMultisampleNULL;
+        textureStorage3D                         = &glTextureStorage3DNULL;
+        textureStorage3DMultisample              = &glTextureStorage3DMultisampleNULL;
+        textureSubImage1D                        = &glTextureSubImage1DNULL;
+        textureSubImage2D                        = &glTextureSubImage2DNULL;
+        textureSubImage3D                        = &glTextureSubImage3DNULL;
+        transformFeedbackBufferBase              = &glTransformFeedbackBufferBaseNULL;
+        transformFeedbackBufferRange             = &glTransformFeedbackBufferRangeNULL;
+        unmapNamedBuffer                         = &glUnmapNamedBufferNULL;
+        vertexArrayAttribBinding                 = &glVertexArrayAttribBindingNULL;
+        vertexArrayAttribFormat                  = &glVertexArrayAttribFormatNULL;
+        vertexArrayAttribIFormat                 = &glVertexArrayAttribIFormatNULL;
+        vertexArrayAttribLFormat                 = &glVertexArrayAttribLFormatNULL;
+        vertexArrayBindingDivisor                = &glVertexArrayBindingDivisorNULL;
+        vertexArrayElementBuffer                 = &glVertexArrayElementBufferNULL;
+        vertexArrayVertexBuffer                  = &glVertexArrayVertexBufferNULL;
+        vertexArrayVertexBuffers                 = &glVertexArrayVertexBuffersNULL;
+    }
+
+    if (extensions.count("GL_ARB_draw_buffers") != 0)
+    {
+        drawBuffers = &glDrawBuffersNULL;
+    }
+
+    if (extensions.count("GL_ARB_draw_buffers_blend") != 0)
+    {
+        blendEquationSeparatei = &glBlendEquationSeparateiNULL;
+        blendEquationi         = &glBlendEquationiNULL;
+        blendFuncSeparatei     = &glBlendFuncSeparateiNULL;
+        blendFunci             = &glBlendFunciNULL;
+    }
+
+    if (extensions.count("GL_ARB_draw_elements_base_vertex") != 0)
+    {
+        drawElementsBaseVertex          = &glDrawElementsBaseVertexNULL;
+        drawElementsInstancedBaseVertex = &glDrawElementsInstancedBaseVertexNULL;
+        drawRangeElementsBaseVertex     = &glDrawRangeElementsBaseVertexNULL;
+        multiDrawElementsBaseVertex     = &glMultiDrawElementsBaseVertexNULL;
+    }
+
+    if (extensions.count("GL_ARB_draw_indirect") != 0)
+    {
+        drawArraysIndirect   = &glDrawArraysIndirectNULL;
+        drawElementsIndirect = &glDrawElementsIndirectNULL;
+    }
+
+    if (extensions.count("GL_ARB_draw_instanced") != 0)
+    {
+        drawArraysInstanced   = &glDrawArraysInstancedNULL;
+        drawElementsInstanced = &glDrawElementsInstancedNULL;
+    }
+
+    if (extensions.count("GL_ARB_fragment_program") != 0)
+    {
+        getProgramiv = &glGetProgramivNULL;
+        isProgram    = &glIsProgramNULL;
+    }
+
+    if (extensions.count("GL_ARB_framebuffer_no_attachments") != 0)
+    {
+        framebufferParameteri     = &glFramebufferParameteriNULL;
+        getFramebufferParameteriv = &glGetFramebufferParameterivNULL;
+    }
+
+    if (extensions.count("GL_ARB_framebuffer_object") != 0)
+    {
+        bindFramebuffer                     = &glBindFramebufferNULL;
+        bindRenderbuffer                    = &glBindRenderbufferNULL;
+        blitFramebuffer                     = &glBlitFramebufferNULL;
+        checkFramebufferStatus              = &glCheckFramebufferStatusNULL;
+        deleteFramebuffers                  = &glDeleteFramebuffersNULL;
+        deleteRenderbuffers                 = &glDeleteRenderbuffersNULL;
+        framebufferRenderbuffer             = &glFramebufferRenderbufferNULL;
+        framebufferTexture1D                = &glFramebufferTexture1DNULL;
+        framebufferTexture2D                = &glFramebufferTexture2DNULL;
+        framebufferTexture3D                = &glFramebufferTexture3DNULL;
+        framebufferTextureLayer             = &glFramebufferTextureLayerNULL;
+        genFramebuffers                     = &glGenFramebuffersNULL;
+        genRenderbuffers                    = &glGenRenderbuffersNULL;
+        generateMipmap                      = &glGenerateMipmapNULL;
+        getFramebufferAttachmentParameteriv = &glGetFramebufferAttachmentParameterivNULL;
+        getRenderbufferParameteriv          = &glGetRenderbufferParameterivNULL;
+        isFramebuffer                       = &glIsFramebufferNULL;
+        isRenderbuffer                      = &glIsRenderbufferNULL;
+        renderbufferStorage                 = &glRenderbufferStorageNULL;
+        renderbufferStorageMultisample      = &glRenderbufferStorageMultisampleNULL;
+    }
+
+    if (extensions.count("GL_ARB_geometry_shader4") != 0)
+    {
+        framebufferTexture      = &glFramebufferTextureNULL;
+        framebufferTextureLayer = &glFramebufferTextureLayerNULL;
+        programParameteri       = &glProgramParameteriNULL;
+    }
+
+    if (extensions.count("GL_ARB_get_program_binary") != 0)
+    {
+        getProgramBinary  = &glGetProgramBinaryNULL;
+        programBinary     = &glProgramBinaryNULL;
+        programParameteri = &glProgramParameteriNULL;
+    }
+
+    if (extensions.count("GL_ARB_get_texture_sub_image") != 0)
+    {
+        getCompressedTextureSubImage = &glGetCompressedTextureSubImageNULL;
+        getTextureSubImage           = &glGetTextureSubImageNULL;
+    }
+
+    if (extensions.count("GL_ARB_gpu_shader_fp64") != 0)
+    {
+        getUniformdv       = &glGetUniformdvNULL;
+        uniform1d          = &glUniform1dNULL;
+        uniform1dv         = &glUniform1dvNULL;
+        uniform2d          = &glUniform2dNULL;
+        uniform2dv         = &glUniform2dvNULL;
+        uniform3d          = &glUniform3dNULL;
+        uniform3dv         = &glUniform3dvNULL;
+        uniform4d          = &glUniform4dNULL;
+        uniform4dv         = &glUniform4dvNULL;
+        uniformMatrix2dv   = &glUniformMatrix2dvNULL;
+        uniformMatrix2x3dv = &glUniformMatrix2x3dvNULL;
+        uniformMatrix2x4dv = &glUniformMatrix2x4dvNULL;
+        uniformMatrix3dv   = &glUniformMatrix3dvNULL;
+        uniformMatrix3x2dv = &glUniformMatrix3x2dvNULL;
+        uniformMatrix3x4dv = &glUniformMatrix3x4dvNULL;
+        uniformMatrix4dv   = &glUniformMatrix4dvNULL;
+        uniformMatrix4x2dv = &glUniformMatrix4x2dvNULL;
+        uniformMatrix4x3dv = &glUniformMatrix4x3dvNULL;
+    }
+
+    if (extensions.count("GL_ARB_imaging") != 0)
+    {
+        blendColor    = &glBlendColorNULL;
+        blendEquation = &glBlendEquationNULL;
+    }
+
+    if (extensions.count("GL_ARB_instanced_arrays") != 0)
+    {
+        vertexAttribDivisor = &glVertexAttribDivisorNULL;
+    }
+
+    if (extensions.count("GL_ARB_internalformat_query") != 0)
+    {
+        getInternalformativ = &glGetInternalformativNULL;
+    }
+
+    if (extensions.count("GL_ARB_internalformat_query2") != 0)
+    {
+        getInternalformati64v = &glGetInternalformati64vNULL;
+    }
+
+    if (extensions.count("GL_ARB_invalidate_subdata") != 0)
+    {
+        invalidateBufferData     = &glInvalidateBufferDataNULL;
+        invalidateBufferSubData  = &glInvalidateBufferSubDataNULL;
+        invalidateFramebuffer    = &glInvalidateFramebufferNULL;
+        invalidateSubFramebuffer = &glInvalidateSubFramebufferNULL;
+        invalidateTexImage       = &glInvalidateTexImageNULL;
+        invalidateTexSubImage    = &glInvalidateTexSubImageNULL;
+    }
+
+    if (extensions.count("GL_ARB_map_buffer_range") != 0)
+    {
+        flushMappedBufferRange = &glFlushMappedBufferRangeNULL;
+        mapBufferRange         = &glMapBufferRangeNULL;
+    }
+
+    if (extensions.count("GL_ARB_multi_bind") != 0)
+    {
+        bindBuffersBase   = &glBindBuffersBaseNULL;
+        bindBuffersRange  = &glBindBuffersRangeNULL;
+        bindImageTextures = &glBindImageTexturesNULL;
+        bindSamplers      = &glBindSamplersNULL;
+        bindTextures      = &glBindTexturesNULL;
+        bindVertexBuffers = &glBindVertexBuffersNULL;
+    }
+
+    if (extensions.count("GL_ARB_multi_draw_indirect") != 0)
+    {
+        multiDrawArraysIndirect   = &glMultiDrawArraysIndirectNULL;
+        multiDrawElementsIndirect = &glMultiDrawElementsIndirectNULL;
+    }
+
+    if (extensions.count("GL_ARB_multisample") != 0)
+    {
+        sampleCoverage = &glSampleCoverageNULL;
+    }
+
+    if (extensions.count("GL_ARB_multitexture") != 0)
+    {
+        activeTexture = &glActiveTextureNULL;
+    }
+
+    if (extensions.count("GL_ARB_occlusion_query") != 0)
+    {
+        beginQuery        = &glBeginQueryNULL;
+        deleteQueries     = &glDeleteQueriesNULL;
+        endQuery          = &glEndQueryNULL;
+        genQueries        = &glGenQueriesNULL;
+        getQueryObjectiv  = &glGetQueryObjectivNULL;
+        getQueryObjectuiv = &glGetQueryObjectuivNULL;
+        getQueryiv        = &glGetQueryivNULL;
+        isQuery           = &glIsQueryNULL;
+    }
+
+    if (extensions.count("GL_ARB_point_parameters") != 0)
+    {
+        pointParameterf  = &glPointParameterfNULL;
+        pointParameterfv = &glPointParameterfvNULL;
+    }
+
+    if (extensions.count("GL_ARB_program_interface_query") != 0)
+    {
+        getProgramInterfaceiv           = &glGetProgramInterfaceivNULL;
+        getProgramResourceIndex         = &glGetProgramResourceIndexNULL;
+        getProgramResourceLocation      = &glGetProgramResourceLocationNULL;
+        getProgramResourceLocationIndex = &glGetProgramResourceLocationIndexNULL;
+        getProgramResourceName          = &glGetProgramResourceNameNULL;
+        getProgramResourceiv            = &glGetProgramResourceivNULL;
+    }
+
+    if (extensions.count("GL_ARB_provoking_vertex") != 0)
+    {
+        provokingVertex = &glProvokingVertexNULL;
+    }
+
+    if (extensions.count("GL_ARB_robustness") != 0)
+    {
+        getGraphicsResetStatus = &glGetGraphicsResetStatusNULL;
+        getnCompressedTexImage = &glGetnCompressedTexImageNULL;
+        getnTexImage           = &glGetnTexImageNULL;
+        getnUniformdv          = &glGetnUniformdvNULL;
+        getnUniformfv          = &glGetnUniformfvNULL;
+        getnUniformiv          = &glGetnUniformivNULL;
+        getnUniformuiv         = &glGetnUniformuivNULL;
+        readnPixels            = &glReadnPixelsNULL;
+    }
+
+    if (extensions.count("GL_ARB_sample_shading") != 0)
+    {
+        minSampleShading = &glMinSampleShadingNULL;
+    }
+
+    if (extensions.count("GL_ARB_sampler_objects") != 0)
+    {
+        bindSampler             = &glBindSamplerNULL;
+        deleteSamplers          = &glDeleteSamplersNULL;
+        genSamplers             = &glGenSamplersNULL;
+        getSamplerParameterIiv  = &glGetSamplerParameterIivNULL;
+        getSamplerParameterIuiv = &glGetSamplerParameterIuivNULL;
+        getSamplerParameterfv   = &glGetSamplerParameterfvNULL;
+        getSamplerParameteriv   = &glGetSamplerParameterivNULL;
+        isSampler               = &glIsSamplerNULL;
+        samplerParameterIiv     = &glSamplerParameterIivNULL;
+        samplerParameterIuiv    = &glSamplerParameterIuivNULL;
+        samplerParameterf       = &glSamplerParameterfNULL;
+        samplerParameterfv      = &glSamplerParameterfvNULL;
+        samplerParameteri       = &glSamplerParameteriNULL;
+        samplerParameteriv      = &glSamplerParameterivNULL;
+    }
+
+    if (extensions.count("GL_ARB_separate_shader_objects") != 0)
+    {
+        activeShaderProgram       = &glActiveShaderProgramNULL;
+        bindProgramPipeline       = &glBindProgramPipelineNULL;
+        createShaderProgramv      = &glCreateShaderProgramvNULL;
+        deleteProgramPipelines    = &glDeleteProgramPipelinesNULL;
+        genProgramPipelines       = &glGenProgramPipelinesNULL;
+        getProgramPipelineInfoLog = &glGetProgramPipelineInfoLogNULL;
+        getProgramPipelineiv      = &glGetProgramPipelineivNULL;
+        isProgramPipeline         = &glIsProgramPipelineNULL;
+        programUniform1d          = &glProgramUniform1dNULL;
+        programUniform1dv         = &glProgramUniform1dvNULL;
+        programUniform1f          = &glProgramUniform1fNULL;
+        programUniform1fv         = &glProgramUniform1fvNULL;
+        programUniform1i          = &glProgramUniform1iNULL;
+        programUniform1iv         = &glProgramUniform1ivNULL;
+        programUniform1ui         = &glProgramUniform1uiNULL;
+        programUniform1uiv        = &glProgramUniform1uivNULL;
+        programUniform2d          = &glProgramUniform2dNULL;
+        programUniform2dv         = &glProgramUniform2dvNULL;
+        programUniform2f          = &glProgramUniform2fNULL;
+        programUniform2fv         = &glProgramUniform2fvNULL;
+        programUniform2i          = &glProgramUniform2iNULL;
+        programUniform2iv         = &glProgramUniform2ivNULL;
+        programUniform2ui         = &glProgramUniform2uiNULL;
+        programUniform2uiv        = &glProgramUniform2uivNULL;
+        programUniform3d          = &glProgramUniform3dNULL;
+        programUniform3dv         = &glProgramUniform3dvNULL;
+        programUniform3f          = &glProgramUniform3fNULL;
+        programUniform3fv         = &glProgramUniform3fvNULL;
+        programUniform3i          = &glProgramUniform3iNULL;
+        programUniform3iv         = &glProgramUniform3ivNULL;
+        programUniform3ui         = &glProgramUniform3uiNULL;
+        programUniform3uiv        = &glProgramUniform3uivNULL;
+        programUniform4d          = &glProgramUniform4dNULL;
+        programUniform4dv         = &glProgramUniform4dvNULL;
+        programUniform4f          = &glProgramUniform4fNULL;
+        programUniform4fv         = &glProgramUniform4fvNULL;
+        programUniform4i          = &glProgramUniform4iNULL;
+        programUniform4iv         = &glProgramUniform4ivNULL;
+        programUniform4ui         = &glProgramUniform4uiNULL;
+        programUniform4uiv        = &glProgramUniform4uivNULL;
+        programUniformMatrix2dv   = &glProgramUniformMatrix2dvNULL;
+        programUniformMatrix2fv   = &glProgramUniformMatrix2fvNULL;
+        programUniformMatrix2x3dv = &glProgramUniformMatrix2x3dvNULL;
+        programUniformMatrix2x3fv = &glProgramUniformMatrix2x3fvNULL;
+        programUniformMatrix2x4dv = &glProgramUniformMatrix2x4dvNULL;
+        programUniformMatrix2x4fv = &glProgramUniformMatrix2x4fvNULL;
+        programUniformMatrix3dv   = &glProgramUniformMatrix3dvNULL;
+        programUniformMatrix3fv   = &glProgramUniformMatrix3fvNULL;
+        programUniformMatrix3x2dv = &glProgramUniformMatrix3x2dvNULL;
+        programUniformMatrix3x2fv = &glProgramUniformMatrix3x2fvNULL;
+        programUniformMatrix3x4dv = &glProgramUniformMatrix3x4dvNULL;
+        programUniformMatrix3x4fv = &glProgramUniformMatrix3x4fvNULL;
+        programUniformMatrix4dv   = &glProgramUniformMatrix4dvNULL;
+        programUniformMatrix4fv   = &glProgramUniformMatrix4fvNULL;
+        programUniformMatrix4x2dv = &glProgramUniformMatrix4x2dvNULL;
+        programUniformMatrix4x2fv = &glProgramUniformMatrix4x2fvNULL;
+        programUniformMatrix4x3dv = &glProgramUniformMatrix4x3dvNULL;
+        programUniformMatrix4x3fv = &glProgramUniformMatrix4x3fvNULL;
+        useProgramStages          = &glUseProgramStagesNULL;
+        validateProgramPipeline   = &glValidateProgramPipelineNULL;
+    }
+
+    if (extensions.count("GL_ARB_shader_atomic_counters") != 0)
+    {
+        getActiveAtomicCounterBufferiv = &glGetActiveAtomicCounterBufferivNULL;
+    }
+
+    if (extensions.count("GL_ARB_shader_image_load_store") != 0)
+    {
+        bindImageTexture = &glBindImageTextureNULL;
+        memoryBarrier    = &glMemoryBarrierNULL;
+    }
+
+    if (extensions.count("GL_ARB_shader_objects") != 0)
+    {
+        compileShader      = &glCompileShaderNULL;
+        getActiveUniform   = &glGetActiveUniformNULL;
+        getShaderSource    = &glGetShaderSourceNULL;
+        getUniformLocation = &glGetUniformLocationNULL;
+        getUniformfv       = &glGetUniformfvNULL;
+        getUniformiv       = &glGetUniformivNULL;
+        linkProgram        = &glLinkProgramNULL;
+        shaderSource       = &glShaderSourceNULL;
+        uniform1f          = &glUniform1fNULL;
+        uniform1fv         = &glUniform1fvNULL;
+        uniform1i          = &glUniform1iNULL;
+        uniform1iv         = &glUniform1ivNULL;
+        uniform2f          = &glUniform2fNULL;
+        uniform2fv         = &glUniform2fvNULL;
+        uniform2i          = &glUniform2iNULL;
+        uniform2iv         = &glUniform2ivNULL;
+        uniform3f          = &glUniform3fNULL;
+        uniform3fv         = &glUniform3fvNULL;
+        uniform3i          = &glUniform3iNULL;
+        uniform3iv         = &glUniform3ivNULL;
+        uniform4f          = &glUniform4fNULL;
+        uniform4fv         = &glUniform4fvNULL;
+        uniform4i          = &glUniform4iNULL;
+        uniform4iv         = &glUniform4ivNULL;
+        uniformMatrix2fv   = &glUniformMatrix2fvNULL;
+        uniformMatrix3fv   = &glUniformMatrix3fvNULL;
+        uniformMatrix4fv   = &glUniformMatrix4fvNULL;
+        validateProgram    = &glValidateProgramNULL;
+    }
+
+    if (extensions.count("GL_ARB_shader_storage_buffer_object") != 0)
+    {
+        shaderStorageBlockBinding = &glShaderStorageBlockBindingNULL;
+    }
+
+    if (extensions.count("GL_ARB_shader_subroutine") != 0)
+    {
+        getActiveSubroutineName        = &glGetActiveSubroutineNameNULL;
+        getActiveSubroutineUniformName = &glGetActiveSubroutineUniformNameNULL;
+        getActiveSubroutineUniformiv   = &glGetActiveSubroutineUniformivNULL;
+        getProgramStageiv              = &glGetProgramStageivNULL;
+        getSubroutineIndex             = &glGetSubroutineIndexNULL;
+        getSubroutineUniformLocation   = &glGetSubroutineUniformLocationNULL;
+        getUniformSubroutineuiv        = &glGetUniformSubroutineuivNULL;
+        uniformSubroutinesuiv          = &glUniformSubroutinesuivNULL;
+    }
+
+    if (extensions.count("GL_ARB_sync") != 0)
+    {
+        clientWaitSync = &glClientWaitSyncNULL;
+        deleteSync     = &glDeleteSyncNULL;
+        fenceSync      = &glFenceSyncNULL;
+        getInteger64v  = &glGetInteger64vNULL;
+        getSynciv      = &glGetSyncivNULL;
+        isSync         = &glIsSyncNULL;
+        waitSync       = &glWaitSyncNULL;
+    }
+
+    if (extensions.count("GL_ARB_tessellation_shader") != 0)
+    {
+        patchParameterfv = &glPatchParameterfvNULL;
+        patchParameteri  = &glPatchParameteriNULL;
+    }
+
+    if (extensions.count("GL_ARB_texture_barrier") != 0)
+    {
+        textureBarrier = &glTextureBarrierNULL;
+    }
+
+    if (extensions.count("GL_ARB_texture_buffer_object") != 0)
+    {
+        texBuffer = &glTexBufferNULL;
+    }
+
+    if (extensions.count("GL_ARB_texture_buffer_range") != 0)
+    {
+        texBufferRange = &glTexBufferRangeNULL;
+    }
+
+    if (extensions.count("GL_ARB_texture_compression") != 0)
+    {
+        compressedTexImage1D    = &glCompressedTexImage1DNULL;
+        compressedTexImage2D    = &glCompressedTexImage2DNULL;
+        compressedTexImage3D    = &glCompressedTexImage3DNULL;
+        compressedTexSubImage1D = &glCompressedTexSubImage1DNULL;
+        compressedTexSubImage2D = &glCompressedTexSubImage2DNULL;
+        compressedTexSubImage3D = &glCompressedTexSubImage3DNULL;
+        getCompressedTexImage   = &glGetCompressedTexImageNULL;
+    }
+
+    if (extensions.count("GL_ARB_texture_multisample") != 0)
+    {
+        getMultisamplefv      = &glGetMultisamplefvNULL;
+        sampleMaski           = &glSampleMaskiNULL;
+        texImage2DMultisample = &glTexImage2DMultisampleNULL;
+        texImage3DMultisample = &glTexImage3DMultisampleNULL;
+    }
+
+    if (extensions.count("GL_ARB_texture_storage") != 0)
+    {
+        texStorage1D = &glTexStorage1DNULL;
+        texStorage2D = &glTexStorage2DNULL;
+        texStorage3D = &glTexStorage3DNULL;
+    }
+
+    if (extensions.count("GL_ARB_texture_storage_multisample") != 0)
+    {
+        texStorage2DMultisample = &glTexStorage2DMultisampleNULL;
+        texStorage3DMultisample = &glTexStorage3DMultisampleNULL;
+    }
+
+    if (extensions.count("GL_ARB_texture_view") != 0)
+    {
+        textureView = &glTextureViewNULL;
+    }
+
+    if (extensions.count("GL_ARB_timer_query") != 0)
+    {
+        getQueryObjecti64v  = &glGetQueryObjecti64vNULL;
+        getQueryObjectui64v = &glGetQueryObjectui64vNULL;
+        queryCounter        = &glQueryCounterNULL;
+    }
+
+    if (extensions.count("GL_ARB_transform_feedback2") != 0)
+    {
+        bindTransformFeedback    = &glBindTransformFeedbackNULL;
+        deleteTransformFeedbacks = &glDeleteTransformFeedbacksNULL;
+        drawTransformFeedback    = &glDrawTransformFeedbackNULL;
+        genTransformFeedbacks    = &glGenTransformFeedbacksNULL;
+        isTransformFeedback      = &glIsTransformFeedbackNULL;
+        pauseTransformFeedback   = &glPauseTransformFeedbackNULL;
+        resumeTransformFeedback  = &glResumeTransformFeedbackNULL;
+    }
+
+    if (extensions.count("GL_ARB_transform_feedback3") != 0)
+    {
+        beginQueryIndexed           = &glBeginQueryIndexedNULL;
+        drawTransformFeedbackStream = &glDrawTransformFeedbackStreamNULL;
+        endQueryIndexed             = &glEndQueryIndexedNULL;
+        getQueryIndexediv           = &glGetQueryIndexedivNULL;
+    }
+
+    if (extensions.count("GL_ARB_transform_feedback_instanced") != 0)
+    {
+        drawTransformFeedbackInstanced       = &glDrawTransformFeedbackInstancedNULL;
+        drawTransformFeedbackStreamInstanced = &glDrawTransformFeedbackStreamInstancedNULL;
+    }
+
+    if (extensions.count("GL_ARB_uniform_buffer_object") != 0)
+    {
+        bindBufferBase            = &glBindBufferBaseNULL;
+        bindBufferRange           = &glBindBufferRangeNULL;
+        getActiveUniformBlockName = &glGetActiveUniformBlockNameNULL;
+        getActiveUniformBlockiv   = &glGetActiveUniformBlockivNULL;
+        getActiveUniformName      = &glGetActiveUniformNameNULL;
+        getActiveUniformsiv       = &glGetActiveUniformsivNULL;
+        getIntegeri_v             = &glGetIntegeri_vNULL;
+        getUniformBlockIndex      = &glGetUniformBlockIndexNULL;
+        getUniformIndices         = &glGetUniformIndicesNULL;
+        uniformBlockBinding       = &glUniformBlockBindingNULL;
+    }
+
+    if (extensions.count("GL_ARB_vertex_array_object") != 0)
+    {
+        bindVertexArray    = &glBindVertexArrayNULL;
+        deleteVertexArrays = &glDeleteVertexArraysNULL;
+        genVertexArrays    = &glGenVertexArraysNULL;
+        isVertexArray      = &glIsVertexArrayNULL;
+    }
+
+    if (extensions.count("GL_ARB_vertex_attrib_64bit") != 0)
+    {
+        getVertexAttribLdv   = &glGetVertexAttribLdvNULL;
+        vertexAttribL1d      = &glVertexAttribL1dNULL;
+        vertexAttribL1dv     = &glVertexAttribL1dvNULL;
+        vertexAttribL2d      = &glVertexAttribL2dNULL;
+        vertexAttribL2dv     = &glVertexAttribL2dvNULL;
+        vertexAttribL3d      = &glVertexAttribL3dNULL;
+        vertexAttribL3dv     = &glVertexAttribL3dvNULL;
+        vertexAttribL4d      = &glVertexAttribL4dNULL;
+        vertexAttribL4dv     = &glVertexAttribL4dvNULL;
+        vertexAttribLPointer = &glVertexAttribLPointerNULL;
+    }
+
+    if (extensions.count("GL_ARB_vertex_attrib_binding") != 0)
+    {
+        bindVertexBuffer     = &glBindVertexBufferNULL;
+        vertexAttribBinding  = &glVertexAttribBindingNULL;
+        vertexAttribFormat   = &glVertexAttribFormatNULL;
+        vertexAttribIFormat  = &glVertexAttribIFormatNULL;
+        vertexAttribLFormat  = &glVertexAttribLFormatNULL;
+        vertexBindingDivisor = &glVertexBindingDivisorNULL;
+    }
+
+    if (extensions.count("GL_ARB_vertex_buffer_object") != 0)
+    {
+        bindBuffer           = &glBindBufferNULL;
+        bufferData           = &glBufferDataNULL;
+        bufferSubData        = &glBufferSubDataNULL;
+        deleteBuffers        = &glDeleteBuffersNULL;
+        genBuffers           = &glGenBuffersNULL;
+        getBufferParameteriv = &glGetBufferParameterivNULL;
+        getBufferPointerv    = &glGetBufferPointervNULL;
+        getBufferSubData     = &glGetBufferSubDataNULL;
+        isBuffer             = &glIsBufferNULL;
+        mapBuffer            = &glMapBufferNULL;
+        unmapBuffer          = &glUnmapBufferNULL;
+    }
+
+    if (extensions.count("GL_ARB_vertex_program") != 0)
+    {
+        disableVertexAttribArray = &glDisableVertexAttribArrayNULL;
+        enableVertexAttribArray  = &glEnableVertexAttribArrayNULL;
+        getProgramiv             = &glGetProgramivNULL;
+        getVertexAttribPointerv  = &glGetVertexAttribPointervNULL;
+        getVertexAttribdv        = &glGetVertexAttribdvNULL;
+        getVertexAttribfv        = &glGetVertexAttribfvNULL;
+        getVertexAttribiv        = &glGetVertexAttribivNULL;
+        isProgram                = &glIsProgramNULL;
+        vertexAttrib1d           = &glVertexAttrib1dNULL;
+        vertexAttrib1dv          = &glVertexAttrib1dvNULL;
+        vertexAttrib1f           = &glVertexAttrib1fNULL;
+        vertexAttrib1fv          = &glVertexAttrib1fvNULL;
+        vertexAttrib1s           = &glVertexAttrib1sNULL;
+        vertexAttrib1sv          = &glVertexAttrib1svNULL;
+        vertexAttrib2d           = &glVertexAttrib2dNULL;
+        vertexAttrib2dv          = &glVertexAttrib2dvNULL;
+        vertexAttrib2f           = &glVertexAttrib2fNULL;
+        vertexAttrib2fv          = &glVertexAttrib2fvNULL;
+        vertexAttrib2s           = &glVertexAttrib2sNULL;
+        vertexAttrib2sv          = &glVertexAttrib2svNULL;
+        vertexAttrib3d           = &glVertexAttrib3dNULL;
+        vertexAttrib3dv          = &glVertexAttrib3dvNULL;
+        vertexAttrib3f           = &glVertexAttrib3fNULL;
+        vertexAttrib3fv          = &glVertexAttrib3fvNULL;
+        vertexAttrib3s           = &glVertexAttrib3sNULL;
+        vertexAttrib3sv          = &glVertexAttrib3svNULL;
+        vertexAttrib4Nbv         = &glVertexAttrib4NbvNULL;
+        vertexAttrib4Niv         = &glVertexAttrib4NivNULL;
+        vertexAttrib4Nsv         = &glVertexAttrib4NsvNULL;
+        vertexAttrib4Nub         = &glVertexAttrib4NubNULL;
+        vertexAttrib4Nubv        = &glVertexAttrib4NubvNULL;
+        vertexAttrib4Nuiv        = &glVertexAttrib4NuivNULL;
+        vertexAttrib4Nusv        = &glVertexAttrib4NusvNULL;
+        vertexAttrib4bv          = &glVertexAttrib4bvNULL;
+        vertexAttrib4d           = &glVertexAttrib4dNULL;
+        vertexAttrib4dv          = &glVertexAttrib4dvNULL;
+        vertexAttrib4f           = &glVertexAttrib4fNULL;
+        vertexAttrib4fv          = &glVertexAttrib4fvNULL;
+        vertexAttrib4iv          = &glVertexAttrib4ivNULL;
+        vertexAttrib4s           = &glVertexAttrib4sNULL;
+        vertexAttrib4sv          = &glVertexAttrib4svNULL;
+        vertexAttrib4ubv         = &glVertexAttrib4ubvNULL;
+        vertexAttrib4uiv         = &glVertexAttrib4uivNULL;
+        vertexAttrib4usv         = &glVertexAttrib4usvNULL;
+        vertexAttribPointer      = &glVertexAttribPointerNULL;
+    }
+
+    if (extensions.count("GL_ARB_vertex_shader") != 0)
+    {
+        bindAttribLocation       = &glBindAttribLocationNULL;
+        disableVertexAttribArray = &glDisableVertexAttribArrayNULL;
+        enableVertexAttribArray  = &glEnableVertexAttribArrayNULL;
+        getActiveAttrib          = &glGetActiveAttribNULL;
+        getAttribLocation        = &glGetAttribLocationNULL;
+        getVertexAttribPointerv  = &glGetVertexAttribPointervNULL;
+        getVertexAttribdv        = &glGetVertexAttribdvNULL;
+        getVertexAttribfv        = &glGetVertexAttribfvNULL;
+        getVertexAttribiv        = &glGetVertexAttribivNULL;
+        vertexAttrib1d           = &glVertexAttrib1dNULL;
+        vertexAttrib1dv          = &glVertexAttrib1dvNULL;
+        vertexAttrib1f           = &glVertexAttrib1fNULL;
+        vertexAttrib1fv          = &glVertexAttrib1fvNULL;
+        vertexAttrib1s           = &glVertexAttrib1sNULL;
+        vertexAttrib1sv          = &glVertexAttrib1svNULL;
+        vertexAttrib2d           = &glVertexAttrib2dNULL;
+        vertexAttrib2dv          = &glVertexAttrib2dvNULL;
+        vertexAttrib2f           = &glVertexAttrib2fNULL;
+        vertexAttrib2fv          = &glVertexAttrib2fvNULL;
+        vertexAttrib2s           = &glVertexAttrib2sNULL;
+        vertexAttrib2sv          = &glVertexAttrib2svNULL;
+        vertexAttrib3d           = &glVertexAttrib3dNULL;
+        vertexAttrib3dv          = &glVertexAttrib3dvNULL;
+        vertexAttrib3f           = &glVertexAttrib3fNULL;
+        vertexAttrib3fv          = &glVertexAttrib3fvNULL;
+        vertexAttrib3s           = &glVertexAttrib3sNULL;
+        vertexAttrib3sv          = &glVertexAttrib3svNULL;
+        vertexAttrib4Nbv         = &glVertexAttrib4NbvNULL;
+        vertexAttrib4Niv         = &glVertexAttrib4NivNULL;
+        vertexAttrib4Nsv         = &glVertexAttrib4NsvNULL;
+        vertexAttrib4Nub         = &glVertexAttrib4NubNULL;
+        vertexAttrib4Nubv        = &glVertexAttrib4NubvNULL;
+        vertexAttrib4Nuiv        = &glVertexAttrib4NuivNULL;
+        vertexAttrib4Nusv        = &glVertexAttrib4NusvNULL;
+        vertexAttrib4bv          = &glVertexAttrib4bvNULL;
+        vertexAttrib4d           = &glVertexAttrib4dNULL;
+        vertexAttrib4dv          = &glVertexAttrib4dvNULL;
+        vertexAttrib4f           = &glVertexAttrib4fNULL;
+        vertexAttrib4fv          = &glVertexAttrib4fvNULL;
+        vertexAttrib4iv          = &glVertexAttrib4ivNULL;
+        vertexAttrib4s           = &glVertexAttrib4sNULL;
+        vertexAttrib4sv          = &glVertexAttrib4svNULL;
+        vertexAttrib4ubv         = &glVertexAttrib4ubvNULL;
+        vertexAttrib4uiv         = &glVertexAttrib4uivNULL;
+        vertexAttrib4usv         = &glVertexAttrib4usvNULL;
+        vertexAttribPointer      = &glVertexAttribPointerNULL;
+    }
+
+    if (extensions.count("GL_ARB_vertex_type_2_10_10_10_rev") != 0)
+    {
+        vertexAttribP1ui  = &glVertexAttribP1uiNULL;
+        vertexAttribP1uiv = &glVertexAttribP1uivNULL;
+        vertexAttribP2ui  = &glVertexAttribP2uiNULL;
+        vertexAttribP2uiv = &glVertexAttribP2uivNULL;
+        vertexAttribP3ui  = &glVertexAttribP3uiNULL;
+        vertexAttribP3uiv = &glVertexAttribP3uivNULL;
+        vertexAttribP4ui  = &glVertexAttribP4uiNULL;
+        vertexAttribP4uiv = &glVertexAttribP4uivNULL;
+    }
+
+    if (extensions.count("GL_ARB_viewport_array") != 0)
+    {
+        depthRangeArrayv  = &glDepthRangeArrayvNULL;
+        depthRangeIndexed = &glDepthRangeIndexedNULL;
+        getDoublei_v      = &glGetDoublei_vNULL;
+        getFloati_v       = &glGetFloati_vNULL;
+        scissorArrayv     = &glScissorArrayvNULL;
+        scissorIndexed    = &glScissorIndexedNULL;
+        scissorIndexedv   = &glScissorIndexedvNULL;
+        viewportArrayv    = &glViewportArrayvNULL;
+        viewportIndexedf  = &glViewportIndexedfNULL;
+        viewportIndexedfv = &glViewportIndexedfvNULL;
+    }
+
+    if (extensions.count("GL_EXT_blend_color") != 0)
+    {
+        blendColor = &glBlendColorNULL;
+    }
+
+    if (extensions.count("GL_EXT_blend_equation_separate") != 0)
+    {
+        blendEquationSeparate = &glBlendEquationSeparateNULL;
+    }
+
+    if (extensions.count("GL_EXT_blend_func_separate") != 0)
+    {
+        blendFuncSeparate = &glBlendFuncSeparateNULL;
+    }
+
+    if (extensions.count("GL_EXT_copy_texture") != 0)
+    {
+        copyTexImage1D    = &glCopyTexImage1DNULL;
+        copyTexImage2D    = &glCopyTexImage2DNULL;
+        copyTexSubImage1D = &glCopyTexSubImage1DNULL;
+        copyTexSubImage2D = &glCopyTexSubImage2DNULL;
+        copyTexSubImage3D = &glCopyTexSubImage3DNULL;
+    }
+
+    if (extensions.count("GL_EXT_direct_state_access") != 0)
+    {
+        checkNamedFramebufferStatus              = &glCheckNamedFramebufferStatusNULL;
+        clearNamedBufferData                     = &glClearNamedBufferDataNULL;
+        clearNamedBufferSubData                  = &glClearNamedBufferSubDataNULL;
+        compressedTextureSubImage1D              = &glCompressedTextureSubImage1DNULL;
+        compressedTextureSubImage2D              = &glCompressedTextureSubImage2DNULL;
+        compressedTextureSubImage3D              = &glCompressedTextureSubImage3DNULL;
+        copyTextureSubImage1D                    = &glCopyTextureSubImage1DNULL;
+        copyTextureSubImage2D                    = &glCopyTextureSubImage2DNULL;
+        copyTextureSubImage3D                    = &glCopyTextureSubImage3DNULL;
+        disableVertexArrayAttrib                 = &glDisableVertexArrayAttribNULL;
+        enableVertexArrayAttrib                  = &glEnableVertexArrayAttribNULL;
+        flushMappedNamedBufferRange              = &glFlushMappedNamedBufferRangeNULL;
+        generateTextureMipmap                    = &glGenerateTextureMipmapNULL;
+        getCompressedTextureImage                = &glGetCompressedTextureImageNULL;
+        getDoublei_v                             = &glGetDoublei_vNULL;
+        getFloati_v                              = &glGetFloati_vNULL;
+        getFramebufferParameteriv                = &glGetFramebufferParameterivNULL;
+        getNamedBufferParameteriv                = &glGetNamedBufferParameterivNULL;
+        getNamedBufferPointerv                   = &glGetNamedBufferPointervNULL;
+        getNamedBufferSubData                    = &glGetNamedBufferSubDataNULL;
+        getNamedFramebufferAttachmentParameteriv = &glGetNamedFramebufferAttachmentParameterivNULL;
+        getNamedFramebufferParameteriv           = &glGetNamedFramebufferParameterivNULL;
+        getNamedRenderbufferParameteriv          = &glGetNamedRenderbufferParameterivNULL;
+        getTextureImage                          = &glGetTextureImageNULL;
+        getTextureLevelParameterfv               = &glGetTextureLevelParameterfvNULL;
+        getTextureLevelParameteriv               = &glGetTextureLevelParameterivNULL;
+        getTextureParameterIiv                   = &glGetTextureParameterIivNULL;
+        getTextureParameterIuiv                  = &glGetTextureParameterIuivNULL;
+        getTextureParameterfv                    = &glGetTextureParameterfvNULL;
+        getTextureParameteriv                    = &glGetTextureParameterivNULL;
+        mapNamedBuffer                           = &glMapNamedBufferNULL;
+        mapNamedBufferRange                      = &glMapNamedBufferRangeNULL;
+        namedBufferData                          = &glNamedBufferDataNULL;
+        namedBufferStorage                       = &glNamedBufferStorageNULL;
+        namedBufferSubData                       = &glNamedBufferSubDataNULL;
+        namedFramebufferParameteri               = &glNamedFramebufferParameteriNULL;
+        namedFramebufferRenderbuffer             = &glNamedFramebufferRenderbufferNULL;
+        namedFramebufferTexture                  = &glNamedFramebufferTextureNULL;
+        namedFramebufferTextureLayer             = &glNamedFramebufferTextureLayerNULL;
+        namedRenderbufferStorage                 = &glNamedRenderbufferStorageNULL;
+        namedRenderbufferStorageMultisample      = &glNamedRenderbufferStorageMultisampleNULL;
+        programUniform1d                         = &glProgramUniform1dNULL;
+        programUniform1dv                        = &glProgramUniform1dvNULL;
+        programUniform2d                         = &glProgramUniform2dNULL;
+        programUniform2dv                        = &glProgramUniform2dvNULL;
+        programUniform3d                         = &glProgramUniform3dNULL;
+        programUniform3dv                        = &glProgramUniform3dvNULL;
+        programUniform4d                         = &glProgramUniform4dNULL;
+        programUniform4dv                        = &glProgramUniform4dvNULL;
+        programUniformMatrix2dv                  = &glProgramUniformMatrix2dvNULL;
+        programUniformMatrix2x3dv                = &glProgramUniformMatrix2x3dvNULL;
+        programUniformMatrix2x4dv                = &glProgramUniformMatrix2x4dvNULL;
+        programUniformMatrix3dv                  = &glProgramUniformMatrix3dvNULL;
+        programUniformMatrix3x2dv                = &glProgramUniformMatrix3x2dvNULL;
+        programUniformMatrix3x4dv                = &glProgramUniformMatrix3x4dvNULL;
+        programUniformMatrix4dv                  = &glProgramUniformMatrix4dvNULL;
+        programUniformMatrix4x2dv                = &glProgramUniformMatrix4x2dvNULL;
+        programUniformMatrix4x3dv                = &glProgramUniformMatrix4x3dvNULL;
+        textureBuffer                            = &glTextureBufferNULL;
+        textureBufferRange                       = &glTextureBufferRangeNULL;
+        textureParameterIiv                      = &glTextureParameterIivNULL;
+        textureParameterIuiv                     = &glTextureParameterIuivNULL;
+        textureParameterf                        = &glTextureParameterfNULL;
+        textureParameterfv                       = &glTextureParameterfvNULL;
+        textureParameteri                        = &glTextureParameteriNULL;
+        textureParameteriv                       = &glTextureParameterivNULL;
+        textureStorage1D                         = &glTextureStorage1DNULL;
+        textureStorage2D                         = &glTextureStorage2DNULL;
+        textureStorage2DMultisample              = &glTextureStorage2DMultisampleNULL;
+        textureStorage3D                         = &glTextureStorage3DNULL;
+        textureStorage3DMultisample              = &glTextureStorage3DMultisampleNULL;
+        textureSubImage1D                        = &glTextureSubImage1DNULL;
+        textureSubImage2D                        = &glTextureSubImage2DNULL;
+        textureSubImage3D                        = &glTextureSubImage3DNULL;
+        unmapNamedBuffer                         = &glUnmapNamedBufferNULL;
+    }
+
+    if (extensions.count("GL_EXT_draw_range_elements") != 0)
+    {
+        drawRangeElements = &glDrawRangeElementsNULL;
+    }
+
+    if (extensions.count("GL_EXT_framebuffer_blit") != 0)
+    {
+        blitFramebuffer = &glBlitFramebufferNULL;
+    }
+
+    if (extensions.count("GL_EXT_framebuffer_multisample") != 0)
+    {
+        renderbufferStorageMultisample = &glRenderbufferStorageMultisampleNULL;
+    }
+
+    if (extensions.count("GL_EXT_framebuffer_object") != 0)
+    {
+        bindFramebuffer                     = &glBindFramebufferNULL;
+        bindRenderbuffer                    = &glBindRenderbufferNULL;
+        checkFramebufferStatus              = &glCheckFramebufferStatusNULL;
+        deleteFramebuffers                  = &glDeleteFramebuffersNULL;
+        deleteRenderbuffers                 = &glDeleteRenderbuffersNULL;
+        framebufferRenderbuffer             = &glFramebufferRenderbufferNULL;
+        framebufferTexture1D                = &glFramebufferTexture1DNULL;
+        framebufferTexture2D                = &glFramebufferTexture2DNULL;
+        framebufferTexture3D                = &glFramebufferTexture3DNULL;
+        genFramebuffers                     = &glGenFramebuffersNULL;
+        genRenderbuffers                    = &glGenRenderbuffersNULL;
+        generateMipmap                      = &glGenerateMipmapNULL;
+        getFramebufferAttachmentParameteriv = &glGetFramebufferAttachmentParameterivNULL;
+        getRenderbufferParameteriv          = &glGetRenderbufferParameterivNULL;
+        isFramebuffer                       = &glIsFramebufferNULL;
+        isRenderbuffer                      = &glIsRenderbufferNULL;
+        renderbufferStorage                 = &glRenderbufferStorageNULL;
+    }
+
+    if (extensions.count("GL_EXT_gpu_shader4") != 0)
+    {
+        bindFragDataLocation = &glBindFragDataLocationNULL;
+        getFragDataLocation  = &glGetFragDataLocationNULL;
+        getUniformuiv        = &glGetUniformuivNULL;
+        uniform1ui           = &glUniform1uiNULL;
+        uniform1uiv          = &glUniform1uivNULL;
+        uniform2ui           = &glUniform2uiNULL;
+        uniform2uiv          = &glUniform2uivNULL;
+        uniform3ui           = &glUniform3uiNULL;
+        uniform3uiv          = &glUniform3uivNULL;
+        uniform4ui           = &glUniform4uiNULL;
+        uniform4uiv          = &glUniform4uivNULL;
+    }
+
+    if (extensions.count("GL_EXT_point_parameters") != 0)
+    {
+        pointParameterf  = &glPointParameterfNULL;
+        pointParameterfv = &glPointParameterfvNULL;
+    }
+
+    if (extensions.count("GL_EXT_polygon_offset") != 0)
+    {
+        polygonOffset = &glPolygonOffsetNULL;
+    }
+
+    if (extensions.count("GL_EXT_provoking_vertex") != 0)
+    {
+        provokingVertex = &glProvokingVertexNULL;
+    }
+
+    if (extensions.count("GL_EXT_shader_image_load_store") != 0)
+    {
+        bindImageTexture = &glBindImageTextureNULL;
+        memoryBarrier    = &glMemoryBarrierNULL;
+    }
+
+    if (extensions.count("GL_EXT_subtexture") != 0)
+    {
+        texSubImage1D = &glTexSubImage1DNULL;
+        texSubImage2D = &glTexSubImage2DNULL;
+    }
+
+    if (extensions.count("GL_EXT_texture3D") != 0)
+    {
+        texImage3D    = &glTexImage3DNULL;
+        texSubImage3D = &glTexSubImage3DNULL;
+    }
+
+    if (extensions.count("GL_EXT_texture_array") != 0)
+    {
+        framebufferTextureLayer = &glFramebufferTextureLayerNULL;
+    }
+
+    if (extensions.count("GL_EXT_texture_buffer_object") != 0)
+    {
+        texBuffer = &glTexBufferNULL;
+    }
+
+    if (extensions.count("GL_EXT_texture_integer") != 0)
+    {
+        getTexParameterIiv  = &glGetTexParameterIivNULL;
+        getTexParameterIuiv = &glGetTexParameterIuivNULL;
+        texParameterIiv     = &glTexParameterIivNULL;
+        texParameterIuiv    = &glTexParameterIuivNULL;
+    }
+
+    if (extensions.count("GL_EXT_texture_object") != 0)
+    {
+        bindTexture    = &glBindTextureNULL;
+        deleteTextures = &glDeleteTexturesNULL;
+        genTextures    = &glGenTexturesNULL;
+        isTexture      = &glIsTextureNULL;
+    }
+
+    if (extensions.count("GL_EXT_timer_query") != 0)
+    {
+        getQueryObjecti64v  = &glGetQueryObjecti64vNULL;
+        getQueryObjectui64v = &glGetQueryObjectui64vNULL;
+    }
+
+    if (extensions.count("GL_EXT_transform_feedback") != 0)
+    {
+        beginTransformFeedback      = &glBeginTransformFeedbackNULL;
+        bindBufferBase              = &glBindBufferBaseNULL;
+        bindBufferRange             = &glBindBufferRangeNULL;
+        endTransformFeedback        = &glEndTransformFeedbackNULL;
+        getTransformFeedbackVarying = &glGetTransformFeedbackVaryingNULL;
+        transformFeedbackVaryings   = &glTransformFeedbackVaryingsNULL;
+    }
+
+    if (extensions.count("GL_EXT_vertex_array") != 0)
+    {
+        drawArrays  = &glDrawArraysNULL;
+        getPointerv = &glGetPointervNULL;
+    }
+
+    if (extensions.count("GL_EXT_vertex_attrib_64bit") != 0)
+    {
+        getVertexAttribLdv   = &glGetVertexAttribLdvNULL;
+        vertexAttribL1d      = &glVertexAttribL1dNULL;
+        vertexAttribL1dv     = &glVertexAttribL1dvNULL;
+        vertexAttribL2d      = &glVertexAttribL2dNULL;
+        vertexAttribL2dv     = &glVertexAttribL2dvNULL;
+        vertexAttribL3d      = &glVertexAttribL3dNULL;
+        vertexAttribL3dv     = &glVertexAttribL3dvNULL;
+        vertexAttribL4d      = &glVertexAttribL4dNULL;
+        vertexAttribL4dv     = &glVertexAttribL4dvNULL;
+        vertexAttribLPointer = &glVertexAttribLPointerNULL;
+    }
+
+    if (extensions.count("GL_KHR_debug") != 0)
+    {
+        debugMessageCallback = &glDebugMessageCallbackNULL;
+        debugMessageControl  = &glDebugMessageControlNULL;
+        debugMessageInsert   = &glDebugMessageInsertNULL;
+        getDebugMessageLog   = &glGetDebugMessageLogNULL;
+        getObjectLabel       = &glGetObjectLabelNULL;
+        getObjectPtrLabel    = &glGetObjectPtrLabelNULL;
+        getPointerv          = &glGetPointervNULL;
+        objectLabel          = &glObjectLabelNULL;
+        objectPtrLabel       = &glObjectPtrLabelNULL;
+        popDebugGroup        = &glPopDebugGroupNULL;
+        pushDebugGroup       = &glPushDebugGroupNULL;
+    }
+
+    if (extensions.count("GL_KHR_robustness") != 0)
+    {
+        getGraphicsResetStatus = &glGetGraphicsResetStatusNULL;
+        getnUniformfv          = &glGetnUniformfvNULL;
+        getnUniformiv          = &glGetnUniformivNULL;
+        getnUniformuiv         = &glGetnUniformuivNULL;
+        readnPixels            = &glReadnPixelsNULL;
+    }
+
+    if (extensions.count("GL_NV_geometry_program4") != 0)
+    {
+        framebufferTexture      = &glFramebufferTextureNULL;
+        framebufferTextureLayer = &glFramebufferTextureLayerNULL;
+    }
+
+    if (extensions.count("GL_NV_vertex_program4") != 0)
+    {
+        getVertexAttribIiv   = &glGetVertexAttribIivNULL;
+        getVertexAttribIuiv  = &glGetVertexAttribIuivNULL;
+        vertexAttribI1i      = &glVertexAttribI1iNULL;
+        vertexAttribI1iv     = &glVertexAttribI1ivNULL;
+        vertexAttribI1ui     = &glVertexAttribI1uiNULL;
+        vertexAttribI1uiv    = &glVertexAttribI1uivNULL;
+        vertexAttribI2i      = &glVertexAttribI2iNULL;
+        vertexAttribI2iv     = &glVertexAttribI2ivNULL;
+        vertexAttribI2ui     = &glVertexAttribI2uiNULL;
+        vertexAttribI2uiv    = &glVertexAttribI2uivNULL;
+        vertexAttribI3i      = &glVertexAttribI3iNULL;
+        vertexAttribI3iv     = &glVertexAttribI3ivNULL;
+        vertexAttribI3ui     = &glVertexAttribI3uiNULL;
+        vertexAttribI3uiv    = &glVertexAttribI3uivNULL;
+        vertexAttribI4bv     = &glVertexAttribI4bvNULL;
+        vertexAttribI4i      = &glVertexAttribI4iNULL;
+        vertexAttribI4iv     = &glVertexAttribI4ivNULL;
+        vertexAttribI4sv     = &glVertexAttribI4svNULL;
+        vertexAttribI4ubv    = &glVertexAttribI4ubvNULL;
+        vertexAttribI4ui     = &glVertexAttribI4uiNULL;
+        vertexAttribI4uiv    = &glVertexAttribI4uivNULL;
+        vertexAttribI4usv    = &glVertexAttribI4usvNULL;
+        vertexAttribIPointer = &glVertexAttribIPointerNULL;
+    }
+
+    if (extensions.count("GL_OES_single_precision") != 0)
+    {
+        clearDepthf = &glClearDepthfNULL;
+        depthRangef = &glDepthRangefNULL;
+    }
+}
+
+void DispatchTableGL::initProcsGLESNULL(const gl::Version &version,
+                                        const std::set<std::string> &extensions)
+{
+    if (version >= gl::Version(2, 0))
+    {
+        activeTexture                       = &glActiveTextureNULL;
+        attachShader                        = &glAttachShaderNULL;
+        bindAttribLocation                  = &glBindAttribLocationNULL;
+        bindBuffer                          = &glBindBufferNULL;
+        bindFramebuffer                     = &glBindFramebufferNULL;
+        bindRenderbuffer                    = &glBindRenderbufferNULL;
+        bindTexture                         = &glBindTextureNULL;
+        blendColor                          = &glBlendColorNULL;
+        blendEquation                       = &glBlendEquationNULL;
+        blendEquationSeparate               = &glBlendEquationSeparateNULL;
+        blendFunc                           = &glBlendFuncNULL;
+        blendFuncSeparate                   = &glBlendFuncSeparateNULL;
+        bufferData                          = &glBufferDataNULL;
+        bufferSubData                       = &glBufferSubDataNULL;
+        checkFramebufferStatus              = &glCheckFramebufferStatusNULL;
+        clear                               = &glClearNULL;
+        clearColor                          = &glClearColorNULL;
+        clearDepthf                         = &glClearDepthfNULL;
+        clearStencil                        = &glClearStencilNULL;
+        colorMask                           = &glColorMaskNULL;
+        compileShader                       = &glCompileShaderNULL;
+        compressedTexImage2D                = &glCompressedTexImage2DNULL;
+        compressedTexSubImage2D             = &glCompressedTexSubImage2DNULL;
+        copyTexImage2D                      = &glCopyTexImage2DNULL;
+        copyTexSubImage2D                   = &glCopyTexSubImage2DNULL;
+        createProgram                       = &glCreateProgramNULL;
+        createShader                        = &glCreateShaderNULL;
+        cullFace                            = &glCullFaceNULL;
+        deleteBuffers                       = &glDeleteBuffersNULL;
+        deleteFramebuffers                  = &glDeleteFramebuffersNULL;
+        deleteProgram                       = &glDeleteProgramNULL;
+        deleteRenderbuffers                 = &glDeleteRenderbuffersNULL;
+        deleteShader                        = &glDeleteShaderNULL;
+        deleteTextures                      = &glDeleteTexturesNULL;
+        depthFunc                           = &glDepthFuncNULL;
+        depthMask                           = &glDepthMaskNULL;
+        depthRangef                         = &glDepthRangefNULL;
+        detachShader                        = &glDetachShaderNULL;
+        disable                             = &glDisableNULL;
+        disableVertexAttribArray            = &glDisableVertexAttribArrayNULL;
+        drawArrays                          = &glDrawArraysNULL;
+        drawElements                        = &glDrawElementsNULL;
+        enable                              = &glEnableNULL;
+        enableVertexAttribArray             = &glEnableVertexAttribArrayNULL;
+        finish                              = &glFinishNULL;
+        flush                               = &glFlushNULL;
+        framebufferRenderbuffer             = &glFramebufferRenderbufferNULL;
+        framebufferTexture2D                = &glFramebufferTexture2DNULL;
+        frontFace                           = &glFrontFaceNULL;
+        genBuffers                          = &glGenBuffersNULL;
+        genFramebuffers                     = &glGenFramebuffersNULL;
+        genRenderbuffers                    = &glGenRenderbuffersNULL;
+        genTextures                         = &glGenTexturesNULL;
+        generateMipmap                      = &glGenerateMipmapNULL;
+        getActiveAttrib                     = &glGetActiveAttribNULL;
+        getActiveUniform                    = &glGetActiveUniformNULL;
+        getAttachedShaders                  = &glGetAttachedShadersNULL;
+        getAttribLocation                   = &glGetAttribLocationNULL;
+        getBooleanv                         = &glGetBooleanvNULL;
+        getBufferParameteriv                = &glGetBufferParameterivNULL;
+        getError                            = &glGetErrorNULL;
+        getFloatv                           = &glGetFloatvNULL;
+        getFramebufferAttachmentParameteriv = &glGetFramebufferAttachmentParameterivNULL;
+        getIntegerv                         = &glGetIntegervNULL;
+        getProgramInfoLog                   = &glGetProgramInfoLogNULL;
+        getProgramiv                        = &glGetProgramivNULL;
+        getRenderbufferParameteriv          = &glGetRenderbufferParameterivNULL;
+        getShaderInfoLog                    = &glGetShaderInfoLogNULL;
+        getShaderPrecisionFormat            = &glGetShaderPrecisionFormatNULL;
+        getShaderSource                     = &glGetShaderSourceNULL;
+        getShaderiv                         = &glGetShaderivNULL;
+        getString                           = &glGetStringNULL;
+        getTexParameterfv                   = &glGetTexParameterfvNULL;
+        getTexParameteriv                   = &glGetTexParameterivNULL;
+        getUniformLocation                  = &glGetUniformLocationNULL;
+        getUniformfv                        = &glGetUniformfvNULL;
+        getUniformiv                        = &glGetUniformivNULL;
+        getVertexAttribPointerv             = &glGetVertexAttribPointervNULL;
+        getVertexAttribfv                   = &glGetVertexAttribfvNULL;
+        getVertexAttribiv                   = &glGetVertexAttribivNULL;
+        hint                                = &glHintNULL;
+        isBuffer                            = &glIsBufferNULL;
+        isEnabled                           = &glIsEnabledNULL;
+        isFramebuffer                       = &glIsFramebufferNULL;
+        isProgram                           = &glIsProgramNULL;
+        isRenderbuffer                      = &glIsRenderbufferNULL;
+        isShader                            = &glIsShaderNULL;
+        isTexture                           = &glIsTextureNULL;
+        lineWidth                           = &glLineWidthNULL;
+        linkProgram                         = &glLinkProgramNULL;
+        pixelStorei                         = &glPixelStoreiNULL;
+        polygonOffset                       = &glPolygonOffsetNULL;
+        readPixels                          = &glReadPixelsNULL;
+        releaseShaderCompiler               = &glReleaseShaderCompilerNULL;
+        renderbufferStorage                 = &glRenderbufferStorageNULL;
+        sampleCoverage                      = &glSampleCoverageNULL;
+        scissor                             = &glScissorNULL;
+        shaderBinary                        = &glShaderBinaryNULL;
+        shaderSource                        = &glShaderSourceNULL;
+        stencilFunc                         = &glStencilFuncNULL;
+        stencilFuncSeparate                 = &glStencilFuncSeparateNULL;
+        stencilMask                         = &glStencilMaskNULL;
+        stencilMaskSeparate                 = &glStencilMaskSeparateNULL;
+        stencilOp                           = &glStencilOpNULL;
+        stencilOpSeparate                   = &glStencilOpSeparateNULL;
+        texImage2D                          = &glTexImage2DNULL;
+        texParameterf                       = &glTexParameterfNULL;
+        texParameterfv                      = &glTexParameterfvNULL;
+        texParameteri                       = &glTexParameteriNULL;
+        texParameteriv                      = &glTexParameterivNULL;
+        texSubImage2D                       = &glTexSubImage2DNULL;
+        uniform1f                           = &glUniform1fNULL;
+        uniform1fv                          = &glUniform1fvNULL;
+        uniform1i                           = &glUniform1iNULL;
+        uniform1iv                          = &glUniform1ivNULL;
+        uniform2f                           = &glUniform2fNULL;
+        uniform2fv                          = &glUniform2fvNULL;
+        uniform2i                           = &glUniform2iNULL;
+        uniform2iv                          = &glUniform2ivNULL;
+        uniform3f                           = &glUniform3fNULL;
+        uniform3fv                          = &glUniform3fvNULL;
+        uniform3i                           = &glUniform3iNULL;
+        uniform3iv                          = &glUniform3ivNULL;
+        uniform4f                           = &glUniform4fNULL;
+        uniform4fv                          = &glUniform4fvNULL;
+        uniform4i                           = &glUniform4iNULL;
+        uniform4iv                          = &glUniform4ivNULL;
+        uniformMatrix2fv                    = &glUniformMatrix2fvNULL;
+        uniformMatrix3fv                    = &glUniformMatrix3fvNULL;
+        uniformMatrix4fv                    = &glUniformMatrix4fvNULL;
+        useProgram                          = &glUseProgramNULL;
+        validateProgram                     = &glValidateProgramNULL;
+        vertexAttrib1f                      = &glVertexAttrib1fNULL;
+        vertexAttrib1fv                     = &glVertexAttrib1fvNULL;
+        vertexAttrib2f                      = &glVertexAttrib2fNULL;
+        vertexAttrib2fv                     = &glVertexAttrib2fvNULL;
+        vertexAttrib3f                      = &glVertexAttrib3fNULL;
+        vertexAttrib3fv                     = &glVertexAttrib3fvNULL;
+        vertexAttrib4f                      = &glVertexAttrib4fNULL;
+        vertexAttrib4fv                     = &glVertexAttrib4fvNULL;
+        vertexAttribPointer                 = &glVertexAttribPointerNULL;
+        viewport                            = &glViewportNULL;
+    }
+
+    if (version >= gl::Version(3, 0))
+    {
+        beginQuery                     = &glBeginQueryNULL;
+        beginTransformFeedback         = &glBeginTransformFeedbackNULL;
+        bindBufferBase                 = &glBindBufferBaseNULL;
+        bindBufferRange                = &glBindBufferRangeNULL;
+        bindSampler                    = &glBindSamplerNULL;
+        bindTransformFeedback          = &glBindTransformFeedbackNULL;
+        bindVertexArray                = &glBindVertexArrayNULL;
+        blitFramebuffer                = &glBlitFramebufferNULL;
+        clearBufferfi                  = &glClearBufferfiNULL;
+        clearBufferfv                  = &glClearBufferfvNULL;
+        clearBufferiv                  = &glClearBufferivNULL;
+        clearBufferuiv                 = &glClearBufferuivNULL;
+        clientWaitSync                 = &glClientWaitSyncNULL;
+        compressedTexImage3D           = &glCompressedTexImage3DNULL;
+        compressedTexSubImage3D        = &glCompressedTexSubImage3DNULL;
+        copyBufferSubData              = &glCopyBufferSubDataNULL;
+        copyTexSubImage3D              = &glCopyTexSubImage3DNULL;
+        deleteQueries                  = &glDeleteQueriesNULL;
+        deleteSamplers                 = &glDeleteSamplersNULL;
+        deleteSync                     = &glDeleteSyncNULL;
+        deleteTransformFeedbacks       = &glDeleteTransformFeedbacksNULL;
+        deleteVertexArrays             = &glDeleteVertexArraysNULL;
+        drawArraysInstanced            = &glDrawArraysInstancedNULL;
+        drawBuffers                    = &glDrawBuffersNULL;
+        drawElementsInstanced          = &glDrawElementsInstancedNULL;
+        drawRangeElements              = &glDrawRangeElementsNULL;
+        endQuery                       = &glEndQueryNULL;
+        endTransformFeedback           = &glEndTransformFeedbackNULL;
+        fenceSync                      = &glFenceSyncNULL;
+        flushMappedBufferRange         = &glFlushMappedBufferRangeNULL;
+        framebufferTextureLayer        = &glFramebufferTextureLayerNULL;
+        genQueries                     = &glGenQueriesNULL;
+        genSamplers                    = &glGenSamplersNULL;
+        genTransformFeedbacks          = &glGenTransformFeedbacksNULL;
+        genVertexArrays                = &glGenVertexArraysNULL;
+        getActiveUniformBlockName      = &glGetActiveUniformBlockNameNULL;
+        getActiveUniformBlockiv        = &glGetActiveUniformBlockivNULL;
+        getActiveUniformsiv            = &glGetActiveUniformsivNULL;
+        getBufferParameteri64v         = &glGetBufferParameteri64vNULL;
+        getBufferPointerv              = &glGetBufferPointervNULL;
+        getFragDataLocation            = &glGetFragDataLocationNULL;
+        getInteger64i_v                = &glGetInteger64i_vNULL;
+        getInteger64v                  = &glGetInteger64vNULL;
+        getIntegeri_v                  = &glGetIntegeri_vNULL;
+        getInternalformativ            = &glGetInternalformativNULL;
+        getProgramBinary               = &glGetProgramBinaryNULL;
+        getQueryObjectuiv              = &glGetQueryObjectuivNULL;
+        getQueryiv                     = &glGetQueryivNULL;
+        getSamplerParameterfv          = &glGetSamplerParameterfvNULL;
+        getSamplerParameteriv          = &glGetSamplerParameterivNULL;
+        getStringi                     = &glGetStringiNULL;
+        getSynciv                      = &glGetSyncivNULL;
+        getTransformFeedbackVarying    = &glGetTransformFeedbackVaryingNULL;
+        getUniformBlockIndex           = &glGetUniformBlockIndexNULL;
+        getUniformIndices              = &glGetUniformIndicesNULL;
+        getUniformuiv                  = &glGetUniformuivNULL;
+        getVertexAttribIiv             = &glGetVertexAttribIivNULL;
+        getVertexAttribIuiv            = &glGetVertexAttribIuivNULL;
+        invalidateFramebuffer          = &glInvalidateFramebufferNULL;
+        invalidateSubFramebuffer       = &glInvalidateSubFramebufferNULL;
+        isQuery                        = &glIsQueryNULL;
+        isSampler                      = &glIsSamplerNULL;
+        isSync                         = &glIsSyncNULL;
+        isTransformFeedback            = &glIsTransformFeedbackNULL;
+        isVertexArray                  = &glIsVertexArrayNULL;
+        mapBufferRange                 = &glMapBufferRangeNULL;
+        pauseTransformFeedback         = &glPauseTransformFeedbackNULL;
+        programBinary                  = &glProgramBinaryNULL;
+        programParameteri              = &glProgramParameteriNULL;
+        readBuffer                     = &glReadBufferNULL;
+        renderbufferStorageMultisample = &glRenderbufferStorageMultisampleNULL;
+        resumeTransformFeedback        = &glResumeTransformFeedbackNULL;
+        samplerParameterf              = &glSamplerParameterfNULL;
+        samplerParameterfv             = &glSamplerParameterfvNULL;
+        samplerParameteri              = &glSamplerParameteriNULL;
+        samplerParameteriv             = &glSamplerParameterivNULL;
+        texImage3D                     = &glTexImage3DNULL;
+        texStorage2D                   = &glTexStorage2DNULL;
+        texStorage3D                   = &glTexStorage3DNULL;
+        texSubImage3D                  = &glTexSubImage3DNULL;
+        transformFeedbackVaryings      = &glTransformFeedbackVaryingsNULL;
+        uniform1ui                     = &glUniform1uiNULL;
+        uniform1uiv                    = &glUniform1uivNULL;
+        uniform2ui                     = &glUniform2uiNULL;
+        uniform2uiv                    = &glUniform2uivNULL;
+        uniform3ui                     = &glUniform3uiNULL;
+        uniform3uiv                    = &glUniform3uivNULL;
+        uniform4ui                     = &glUniform4uiNULL;
+        uniform4uiv                    = &glUniform4uivNULL;
+        uniformBlockBinding            = &glUniformBlockBindingNULL;
+        uniformMatrix2x3fv             = &glUniformMatrix2x3fvNULL;
+        uniformMatrix2x4fv             = &glUniformMatrix2x4fvNULL;
+        uniformMatrix3x2fv             = &glUniformMatrix3x2fvNULL;
+        uniformMatrix3x4fv             = &glUniformMatrix3x4fvNULL;
+        uniformMatrix4x2fv             = &glUniformMatrix4x2fvNULL;
+        uniformMatrix4x3fv             = &glUniformMatrix4x3fvNULL;
+        unmapBuffer                    = &glUnmapBufferNULL;
+        vertexAttribDivisor            = &glVertexAttribDivisorNULL;
+        vertexAttribI4i                = &glVertexAttribI4iNULL;
+        vertexAttribI4iv               = &glVertexAttribI4ivNULL;
+        vertexAttribI4ui               = &glVertexAttribI4uiNULL;
+        vertexAttribI4uiv              = &glVertexAttribI4uivNULL;
+        vertexAttribIPointer           = &glVertexAttribIPointerNULL;
+        waitSync                       = &glWaitSyncNULL;
+    }
+
+    if (version >= gl::Version(3, 1))
+    {
+        activeShaderProgram        = &glActiveShaderProgramNULL;
+        bindImageTexture           = &glBindImageTextureNULL;
+        bindProgramPipeline        = &glBindProgramPipelineNULL;
+        bindVertexBuffer           = &glBindVertexBufferNULL;
+        createShaderProgramv       = &glCreateShaderProgramvNULL;
+        deleteProgramPipelines     = &glDeleteProgramPipelinesNULL;
+        dispatchCompute            = &glDispatchComputeNULL;
+        dispatchComputeIndirect    = &glDispatchComputeIndirectNULL;
+        drawArraysIndirect         = &glDrawArraysIndirectNULL;
+        drawElementsIndirect       = &glDrawElementsIndirectNULL;
+        framebufferParameteri      = &glFramebufferParameteriNULL;
+        genProgramPipelines        = &glGenProgramPipelinesNULL;
+        getBooleani_v              = &glGetBooleani_vNULL;
+        getFramebufferParameteriv  = &glGetFramebufferParameterivNULL;
+        getMultisamplefv           = &glGetMultisamplefvNULL;
+        getProgramInterfaceiv      = &glGetProgramInterfaceivNULL;
+        getProgramPipelineInfoLog  = &glGetProgramPipelineInfoLogNULL;
+        getProgramPipelineiv       = &glGetProgramPipelineivNULL;
+        getProgramResourceIndex    = &glGetProgramResourceIndexNULL;
+        getProgramResourceLocation = &glGetProgramResourceLocationNULL;
+        getProgramResourceName     = &glGetProgramResourceNameNULL;
+        getProgramResourceiv       = &glGetProgramResourceivNULL;
+        getTexLevelParameterfv     = &glGetTexLevelParameterfvNULL;
+        getTexLevelParameteriv     = &glGetTexLevelParameterivNULL;
+        isProgramPipeline          = &glIsProgramPipelineNULL;
+        memoryBarrier              = &glMemoryBarrierNULL;
+        memoryBarrierByRegion      = &glMemoryBarrierByRegionNULL;
+        programUniform1f           = &glProgramUniform1fNULL;
+        programUniform1fv          = &glProgramUniform1fvNULL;
+        programUniform1i           = &glProgramUniform1iNULL;
+        programUniform1iv          = &glProgramUniform1ivNULL;
+        programUniform1ui          = &glProgramUniform1uiNULL;
+        programUniform1uiv         = &glProgramUniform1uivNULL;
+        programUniform2f           = &glProgramUniform2fNULL;
+        programUniform2fv          = &glProgramUniform2fvNULL;
+        programUniform2i           = &glProgramUniform2iNULL;
+        programUniform2iv          = &glProgramUniform2ivNULL;
+        programUniform2ui          = &glProgramUniform2uiNULL;
+        programUniform2uiv         = &glProgramUniform2uivNULL;
+        programUniform3f           = &glProgramUniform3fNULL;
+        programUniform3fv          = &glProgramUniform3fvNULL;
+        programUniform3i           = &glProgramUniform3iNULL;
+        programUniform3iv          = &glProgramUniform3ivNULL;
+        programUniform3ui          = &glProgramUniform3uiNULL;
+        programUniform3uiv         = &glProgramUniform3uivNULL;
+        programUniform4f           = &glProgramUniform4fNULL;
+        programUniform4fv          = &glProgramUniform4fvNULL;
+        programUniform4i           = &glProgramUniform4iNULL;
+        programUniform4iv          = &glProgramUniform4ivNULL;
+        programUniform4ui          = &glProgramUniform4uiNULL;
+        programUniform4uiv         = &glProgramUniform4uivNULL;
+        programUniformMatrix2fv    = &glProgramUniformMatrix2fvNULL;
+        programUniformMatrix2x3fv  = &glProgramUniformMatrix2x3fvNULL;
+        programUniformMatrix2x4fv  = &glProgramUniformMatrix2x4fvNULL;
+        programUniformMatrix3fv    = &glProgramUniformMatrix3fvNULL;
+        programUniformMatrix3x2fv  = &glProgramUniformMatrix3x2fvNULL;
+        programUniformMatrix3x4fv  = &glProgramUniformMatrix3x4fvNULL;
+        programUniformMatrix4fv    = &glProgramUniformMatrix4fvNULL;
+        programUniformMatrix4x2fv  = &glProgramUniformMatrix4x2fvNULL;
+        programUniformMatrix4x3fv  = &glProgramUniformMatrix4x3fvNULL;
+        sampleMaski                = &glSampleMaskiNULL;
+        texStorage2DMultisample    = &glTexStorage2DMultisampleNULL;
+        useProgramStages           = &glUseProgramStagesNULL;
+        validateProgramPipeline    = &glValidateProgramPipelineNULL;
+        vertexAttribBinding        = &glVertexAttribBindingNULL;
+        vertexAttribFormat         = &glVertexAttribFormatNULL;
+        vertexAttribIFormat        = &glVertexAttribIFormatNULL;
+        vertexBindingDivisor       = &glVertexBindingDivisorNULL;
+    }
+
+    if (version >= gl::Version(3, 2))
+    {
+        blendBarrier                    = &glBlendBarrierNULL;
+        blendEquationSeparatei          = &glBlendEquationSeparateiNULL;
+        blendEquationi                  = &glBlendEquationiNULL;
+        blendFuncSeparatei              = &glBlendFuncSeparateiNULL;
+        blendFunci                      = &glBlendFunciNULL;
+        colorMaski                      = &glColorMaskiNULL;
+        copyImageSubData                = &glCopyImageSubDataNULL;
+        debugMessageCallback            = &glDebugMessageCallbackNULL;
+        debugMessageControl             = &glDebugMessageControlNULL;
+        debugMessageInsert              = &glDebugMessageInsertNULL;
+        disablei                        = &glDisableiNULL;
+        drawElementsBaseVertex          = &glDrawElementsBaseVertexNULL;
+        drawElementsInstancedBaseVertex = &glDrawElementsInstancedBaseVertexNULL;
+        drawRangeElementsBaseVertex     = &glDrawRangeElementsBaseVertexNULL;
+        enablei                         = &glEnableiNULL;
+        framebufferTexture              = &glFramebufferTextureNULL;
+        getDebugMessageLog              = &glGetDebugMessageLogNULL;
+        getGraphicsResetStatus          = &glGetGraphicsResetStatusNULL;
+        getObjectLabel                  = &glGetObjectLabelNULL;
+        getObjectPtrLabel               = &glGetObjectPtrLabelNULL;
+        getPointerv                     = &glGetPointervNULL;
+        getSamplerParameterIiv          = &glGetSamplerParameterIivNULL;
+        getSamplerParameterIuiv         = &glGetSamplerParameterIuivNULL;
+        getTexParameterIiv              = &glGetTexParameterIivNULL;
+        getTexParameterIuiv             = &glGetTexParameterIuivNULL;
+        getnUniformfv                   = &glGetnUniformfvNULL;
+        getnUniformiv                   = &glGetnUniformivNULL;
+        getnUniformuiv                  = &glGetnUniformuivNULL;
+        isEnabledi                      = &glIsEnablediNULL;
+        minSampleShading                = &glMinSampleShadingNULL;
+        objectLabel                     = &glObjectLabelNULL;
+        objectPtrLabel                  = &glObjectPtrLabelNULL;
+        patchParameteri                 = &glPatchParameteriNULL;
+        popDebugGroup                   = &glPopDebugGroupNULL;
+        primitiveBoundingBox            = &glPrimitiveBoundingBoxNULL;
+        pushDebugGroup                  = &glPushDebugGroupNULL;
+        readnPixels                     = &glReadnPixelsNULL;
+        samplerParameterIiv             = &glSamplerParameterIivNULL;
+        samplerParameterIuiv            = &glSamplerParameterIuivNULL;
+        texBuffer                       = &glTexBufferNULL;
+        texBufferRange                  = &glTexBufferRangeNULL;
+        texParameterIiv                 = &glTexParameterIivNULL;
+        texParameterIuiv                = &glTexParameterIuivNULL;
+        texStorage3DMultisample         = &glTexStorage3DMultisampleNULL;
+    }
+
+    if (extensions.count("GL_EXT_base_instance") != 0)
+    {
+        drawArraysInstancedBaseInstance   = &glDrawArraysInstancedBaseInstanceNULL;
+        drawElementsInstancedBaseInstance = &glDrawElementsInstancedBaseInstanceNULL;
+        drawElementsInstancedBaseVertexBaseInstance =
+            &glDrawElementsInstancedBaseVertexBaseInstanceNULL;
+    }
+
+    if (extensions.count("GL_EXT_blend_func_extended") != 0)
+    {
+        bindFragDataLocation            = &glBindFragDataLocationNULL;
+        bindFragDataLocationIndexed     = &glBindFragDataLocationIndexedNULL;
+        getFragDataIndex                = &glGetFragDataIndexNULL;
+        getProgramResourceLocationIndex = &glGetProgramResourceLocationIndexNULL;
+    }
+
+    if (extensions.count("GL_EXT_buffer_storage") != 0)
+    {
+        bufferStorage = &glBufferStorageNULL;
+    }
+
+    if (extensions.count("GL_EXT_clear_texture") != 0)
+    {
+        clearTexImage    = &glClearTexImageNULL;
+        clearTexSubImage = &glClearTexSubImageNULL;
+    }
+
+    if (extensions.count("GL_EXT_copy_image") != 0)
+    {
+        copyImageSubData = &glCopyImageSubDataNULL;
+    }
+
+    if (extensions.count("GL_EXT_discard_framebuffer") != 0)
+    {
+        discardFramebufferEXT = &glDiscardFramebufferEXTNULL;
+    }
+
+    if (extensions.count("GL_EXT_disjoint_timer_query") != 0)
+    {
+        beginQuery          = &glBeginQueryNULL;
+        deleteQueries       = &glDeleteQueriesNULL;
+        endQuery            = &glEndQueryNULL;
+        genQueries          = &glGenQueriesNULL;
+        getQueryObjecti64v  = &glGetQueryObjecti64vNULL;
+        getQueryObjectiv    = &glGetQueryObjectivNULL;
+        getQueryObjectui64v = &glGetQueryObjectui64vNULL;
+        getQueryObjectuiv   = &glGetQueryObjectuivNULL;
+        getQueryiv          = &glGetQueryivNULL;
+        isQuery             = &glIsQueryNULL;
+        queryCounter        = &glQueryCounterNULL;
+    }
+
+    if (extensions.count("GL_EXT_draw_buffers") != 0)
+    {
+        drawBuffers = &glDrawBuffersNULL;
+    }
+
+    if (extensions.count("GL_EXT_draw_buffers_indexed") != 0)
+    {
+        blendEquationSeparatei = &glBlendEquationSeparateiNULL;
+        blendEquationi         = &glBlendEquationiNULL;
+        blendFuncSeparatei     = &glBlendFuncSeparateiNULL;
+        blendFunci             = &glBlendFunciNULL;
+        colorMaski             = &glColorMaskiNULL;
+        disablei               = &glDisableiNULL;
+        enablei                = &glEnableiNULL;
+        isEnabledi             = &glIsEnablediNULL;
+    }
+
+    if (extensions.count("GL_EXT_draw_elements_base_vertex") != 0)
+    {
+        drawElementsBaseVertex          = &glDrawElementsBaseVertexNULL;
+        drawElementsInstancedBaseVertex = &glDrawElementsInstancedBaseVertexNULL;
+        drawRangeElementsBaseVertex     = &glDrawRangeElementsBaseVertexNULL;
+        multiDrawElementsBaseVertex     = &glMultiDrawElementsBaseVertexNULL;
+    }
+
+    if (extensions.count("GL_EXT_draw_transform_feedback") != 0)
+    {
+        drawTransformFeedback          = &glDrawTransformFeedbackNULL;
+        drawTransformFeedbackInstanced = &glDrawTransformFeedbackInstancedNULL;
+    }
+
+    if (extensions.count("GL_EXT_geometry_shader") != 0)
+    {
+        framebufferTexture = &glFramebufferTextureNULL;
+    }
+
+    if (extensions.count("GL_EXT_instanced_arrays") != 0)
+    {
+        vertexAttribDivisor = &glVertexAttribDivisorNULL;
+    }
+
+    if (extensions.count("GL_EXT_map_buffer_range") != 0)
+    {
+        flushMappedBufferRange = &glFlushMappedBufferRangeNULL;
+        mapBufferRange         = &glMapBufferRangeNULL;
+    }
+
+    if (extensions.count("GL_EXT_multi_draw_indirect") != 0)
+    {
+        multiDrawArraysIndirect   = &glMultiDrawArraysIndirectNULL;
+        multiDrawElementsIndirect = &glMultiDrawElementsIndirectNULL;
+    }
+
+    if (extensions.count("GL_EXT_multisampled_render_to_texture") != 0)
+    {
+        renderbufferStorageMultisample = &glRenderbufferStorageMultisampleNULL;
+    }
+
+    if (extensions.count("GL_EXT_multiview_draw_buffers") != 0)
+    {
+        getIntegeri_v = &glGetIntegeri_vNULL;
+    }
+
+    if (extensions.count("GL_EXT_occlusion_query_boolean") != 0)
+    {
+        beginQuery        = &glBeginQueryNULL;
+        deleteQueries     = &glDeleteQueriesNULL;
+        endQuery          = &glEndQueryNULL;
+        genQueries        = &glGenQueriesNULL;
+        getQueryObjectuiv = &glGetQueryObjectuivNULL;
+        getQueryiv        = &glGetQueryivNULL;
+        isQuery           = &glIsQueryNULL;
+    }
+
+    if (extensions.count("GL_EXT_primitive_bounding_box") != 0)
+    {
+        primitiveBoundingBox = &glPrimitiveBoundingBoxNULL;
+    }
+
+    if (extensions.count("GL_EXT_robustness") != 0)
+    {
+        getGraphicsResetStatus = &glGetGraphicsResetStatusNULL;
+        getnUniformfv          = &glGetnUniformfvNULL;
+        getnUniformiv          = &glGetnUniformivNULL;
+        readnPixels            = &glReadnPixelsNULL;
+    }
+
+    if (extensions.count("GL_EXT_tessellation_shader") != 0)
+    {
+        patchParameteri = &glPatchParameteriNULL;
+    }
+
+    if (extensions.count("GL_EXT_texture_border_clamp") != 0)
+    {
+        getSamplerParameterIiv  = &glGetSamplerParameterIivNULL;
+        getSamplerParameterIuiv = &glGetSamplerParameterIuivNULL;
+        getTexParameterIiv      = &glGetTexParameterIivNULL;
+        getTexParameterIuiv     = &glGetTexParameterIuivNULL;
+        samplerParameterIiv     = &glSamplerParameterIivNULL;
+        samplerParameterIuiv    = &glSamplerParameterIuivNULL;
+        texParameterIiv         = &glTexParameterIivNULL;
+        texParameterIuiv        = &glTexParameterIuivNULL;
+    }
+
+    if (extensions.count("GL_EXT_texture_buffer") != 0)
+    {
+        texBuffer      = &glTexBufferNULL;
+        texBufferRange = &glTexBufferRangeNULL;
+    }
+
+    if (extensions.count("GL_EXT_texture_storage") != 0)
+    {
+        texStorage1D     = &glTexStorage1DNULL;
+        texStorage2D     = &glTexStorage2DNULL;
+        texStorage3D     = &glTexStorage3DNULL;
+        textureStorage1D = &glTextureStorage1DNULL;
+        textureStorage2D = &glTextureStorage2DNULL;
+        textureStorage3D = &glTextureStorage3DNULL;
+    }
+
+    if (extensions.count("GL_EXT_texture_view") != 0)
+    {
+        textureView = &glTextureViewNULL;
+    }
+
+    if (extensions.count("GL_KHR_debug") != 0)
+    {
+        debugMessageCallback = &glDebugMessageCallbackNULL;
+        debugMessageControl  = &glDebugMessageControlNULL;
+        debugMessageInsert   = &glDebugMessageInsertNULL;
+        getDebugMessageLog   = &glGetDebugMessageLogNULL;
+        getObjectLabel       = &glGetObjectLabelNULL;
+        getObjectPtrLabel    = &glGetObjectPtrLabelNULL;
+        getPointerv          = &glGetPointervNULL;
+        objectLabel          = &glObjectLabelNULL;
+        objectPtrLabel       = &glObjectPtrLabelNULL;
+        popDebugGroup        = &glPopDebugGroupNULL;
+        pushDebugGroup       = &glPushDebugGroupNULL;
+    }
+
+    if (extensions.count("GL_KHR_robustness") != 0)
+    {
+        getGraphicsResetStatus = &glGetGraphicsResetStatusNULL;
+        getnUniformfv          = &glGetnUniformfvNULL;
+        getnUniformiv          = &glGetnUniformivNULL;
+        getnUniformuiv         = &glGetnUniformuivNULL;
+        readnPixels            = &glReadnPixelsNULL;
+    }
+
+    if (extensions.count("GL_OES_EGL_image") != 0)
+    {
+        eGLImageTargetRenderbufferStorageOES = &glEGLImageTargetRenderbufferStorageOESNULL;
+        eGLImageTargetTexture2DOES           = &glEGLImageTargetTexture2DOESNULL;
+    }
+
+    if (extensions.count("GL_OES_copy_image") != 0)
+    {
+        copyImageSubData = &glCopyImageSubDataNULL;
+    }
+
+    if (extensions.count("GL_OES_draw_buffers_indexed") != 0)
+    {
+        blendEquationSeparatei = &glBlendEquationSeparateiNULL;
+        blendEquationi         = &glBlendEquationiNULL;
+        blendFuncSeparatei     = &glBlendFuncSeparateiNULL;
+        blendFunci             = &glBlendFunciNULL;
+        colorMaski             = &glColorMaskiNULL;
+        disablei               = &glDisableiNULL;
+        enablei                = &glEnableiNULL;
+        isEnabledi             = &glIsEnablediNULL;
+    }
+
+    if (extensions.count("GL_OES_draw_elements_base_vertex") != 0)
+    {
+        drawElementsBaseVertex          = &glDrawElementsBaseVertexNULL;
+        drawElementsInstancedBaseVertex = &glDrawElementsInstancedBaseVertexNULL;
+        drawRangeElementsBaseVertex     = &glDrawRangeElementsBaseVertexNULL;
+        multiDrawElementsBaseVertex     = &glMultiDrawElementsBaseVertexNULL;
+    }
+
+    if (extensions.count("GL_OES_geometry_shader") != 0)
+    {
+        framebufferTexture = &glFramebufferTextureNULL;
+    }
+
+    if (extensions.count("GL_OES_get_program_binary") != 0)
+    {
+        getProgramBinary = &glGetProgramBinaryNULL;
+        programBinary    = &glProgramBinaryNULL;
+    }
+
+    if (extensions.count("GL_OES_mapbuffer") != 0)
+    {
+        getBufferPointerv = &glGetBufferPointervNULL;
+        mapBuffer         = &glMapBufferNULL;
+        unmapBuffer       = &glUnmapBufferNULL;
+    }
+
+    if (extensions.count("GL_OES_primitive_bounding_box") != 0)
+    {
+        primitiveBoundingBox = &glPrimitiveBoundingBoxNULL;
+    }
+
+    if (extensions.count("GL_OES_sample_shading") != 0)
+    {
+        minSampleShading = &glMinSampleShadingNULL;
+    }
+
+    if (extensions.count("GL_OES_tessellation_shader") != 0)
+    {
+        patchParameteri = &glPatchParameteriNULL;
+    }
+
+    if (extensions.count("GL_OES_texture_3D") != 0)
+    {
+        compressedTexImage3D    = &glCompressedTexImage3DNULL;
+        compressedTexSubImage3D = &glCompressedTexSubImage3DNULL;
+        copyTexSubImage3D       = &glCopyTexSubImage3DNULL;
+        framebufferTexture3D    = &glFramebufferTexture3DNULL;
+        texImage3D              = &glTexImage3DNULL;
+        texSubImage3D           = &glTexSubImage3DNULL;
+    }
+
+    if (extensions.count("GL_OES_texture_border_clamp") != 0)
+    {
+        getSamplerParameterIiv  = &glGetSamplerParameterIivNULL;
+        getSamplerParameterIuiv = &glGetSamplerParameterIuivNULL;
+        getTexParameterIiv      = &glGetTexParameterIivNULL;
+        getTexParameterIuiv     = &glGetTexParameterIuivNULL;
+        samplerParameterIiv     = &glSamplerParameterIivNULL;
+        samplerParameterIuiv    = &glSamplerParameterIuivNULL;
+        texParameterIiv         = &glTexParameterIivNULL;
+        texParameterIuiv        = &glTexParameterIuivNULL;
+    }
+
+    if (extensions.count("GL_OES_texture_buffer") != 0)
+    {
+        texBuffer      = &glTexBufferNULL;
+        texBufferRange = &glTexBufferRangeNULL;
+    }
+
+    if (extensions.count("GL_OES_texture_storage_multisample_2d_array") != 0)
+    {
+        texStorage3DMultisample = &glTexStorage3DMultisampleNULL;
+    }
+
+    if (extensions.count("GL_OES_texture_view") != 0)
+    {
+        textureView = &glTextureViewNULL;
+    }
+
+    if (extensions.count("GL_OES_vertex_array_object") != 0)
+    {
+        bindVertexArray    = &glBindVertexArrayNULL;
+        deleteVertexArrays = &glDeleteVertexArraysNULL;
+        genVertexArrays    = &glGenVertexArraysNULL;
+        isVertexArray      = &glIsVertexArrayNULL;
+    }
+
+    if (extensions.count("GL_OES_viewport_array") != 0)
+    {
+        disablei          = &glDisableiNULL;
+        enablei           = &glEnableiNULL;
+        getFloati_v       = &glGetFloati_vNULL;
+        isEnabledi        = &glIsEnablediNULL;
+        scissorArrayv     = &glScissorArrayvNULL;
+        scissorIndexed    = &glScissorIndexedNULL;
+        scissorIndexedv   = &glScissorIndexedvNULL;
+        viewportArrayv    = &glViewportArrayvNULL;
+        viewportIndexedf  = &glViewportIndexedfNULL;
+        viewportIndexedfv = &glViewportIndexedfvNULL;
+    }
+}
+
+void DispatchTableGL::initProcsSharedExtensionsNULL(const std::set<std::string> &extensions)
+{
+    if (extensions.count("GL_EXT_blend_minmax") != 0)
+    {
+        blendEquation = &glBlendEquationNULL;
+    }
+
+    if (extensions.count("GL_EXT_debug_label") != 0)
+    {
+        getObjectLabel = &glGetObjectLabelNULL;
+    }
+
+    if (extensions.count("GL_EXT_debug_marker") != 0)
+    {
+        insertEventMarkerEXT = &glInsertEventMarkerEXTNULL;
+        popGroupMarkerEXT    = &glPopGroupMarkerEXTNULL;
+        pushGroupMarkerEXT   = &glPushGroupMarkerEXTNULL;
+    }
+
+    if (extensions.count("GL_EXT_draw_instanced") != 0)
+    {
+        drawArraysInstanced   = &glDrawArraysInstancedNULL;
+        drawElementsInstanced = &glDrawElementsInstancedNULL;
+    }
+
+    if (extensions.count("GL_EXT_multi_draw_arrays") != 0)
+    {
+        multiDrawArrays   = &glMultiDrawArraysNULL;
+        multiDrawElements = &glMultiDrawElementsNULL;
+    }
+
+    if (extensions.count("GL_EXT_separate_shader_objects") != 0)
+    {
+        activeShaderProgram       = &glActiveShaderProgramNULL;
+        bindProgramPipeline       = &glBindProgramPipelineNULL;
+        createShaderProgramv      = &glCreateShaderProgramvNULL;
+        deleteProgramPipelines    = &glDeleteProgramPipelinesNULL;
+        genProgramPipelines       = &glGenProgramPipelinesNULL;
+        getProgramPipelineInfoLog = &glGetProgramPipelineInfoLogNULL;
+        getProgramPipelineiv      = &glGetProgramPipelineivNULL;
+        isProgramPipeline         = &glIsProgramPipelineNULL;
+        programParameteri         = &glProgramParameteriNULL;
+        programUniform1f          = &glProgramUniform1fNULL;
+        programUniform1fv         = &glProgramUniform1fvNULL;
+        programUniform1i          = &glProgramUniform1iNULL;
+        programUniform1iv         = &glProgramUniform1ivNULL;
+        programUniform1ui         = &glProgramUniform1uiNULL;
+        programUniform1uiv        = &glProgramUniform1uivNULL;
+        programUniform2f          = &glProgramUniform2fNULL;
+        programUniform2fv         = &glProgramUniform2fvNULL;
+        programUniform2i          = &glProgramUniform2iNULL;
+        programUniform2iv         = &glProgramUniform2ivNULL;
+        programUniform2ui         = &glProgramUniform2uiNULL;
+        programUniform2uiv        = &glProgramUniform2uivNULL;
+        programUniform3f          = &glProgramUniform3fNULL;
+        programUniform3fv         = &glProgramUniform3fvNULL;
+        programUniform3i          = &glProgramUniform3iNULL;
+        programUniform3iv         = &glProgramUniform3ivNULL;
+        programUniform3ui         = &glProgramUniform3uiNULL;
+        programUniform3uiv        = &glProgramUniform3uivNULL;
+        programUniform4f          = &glProgramUniform4fNULL;
+        programUniform4fv         = &glProgramUniform4fvNULL;
+        programUniform4i          = &glProgramUniform4iNULL;
+        programUniform4iv         = &glProgramUniform4ivNULL;
+        programUniform4ui         = &glProgramUniform4uiNULL;
+        programUniform4uiv        = &glProgramUniform4uivNULL;
+        programUniformMatrix2fv   = &glProgramUniformMatrix2fvNULL;
+        programUniformMatrix2x3fv = &glProgramUniformMatrix2x3fvNULL;
+        programUniformMatrix2x4fv = &glProgramUniformMatrix2x4fvNULL;
+        programUniformMatrix3fv   = &glProgramUniformMatrix3fvNULL;
+        programUniformMatrix3x2fv = &glProgramUniformMatrix3x2fvNULL;
+        programUniformMatrix3x4fv = &glProgramUniformMatrix3x4fvNULL;
+        programUniformMatrix4fv   = &glProgramUniformMatrix4fvNULL;
+        programUniformMatrix4fv   = &glProgramUniformMatrix4fvNULL;
+        programUniformMatrix4x2fv = &glProgramUniformMatrix4x2fvNULL;
+        programUniformMatrix4x3fv = &glProgramUniformMatrix4x3fvNULL;
+        useProgramStages          = &glUseProgramStagesNULL;
+        validateProgramPipeline   = &glValidateProgramPipelineNULL;
+    }
+
+    if (extensions.count("GL_NV_fence") != 0)
+    {
+        deleteFencesNV = &glDeleteFencesNVNULL;
+        finishFenceNV  = &glFinishFenceNVNULL;
+        genFencesNV    = &glGenFencesNVNULL;
+        getFenceivNV   = &glGetFenceivNVNULL;
+        isFenceNV      = &glIsFenceNVNULL;
+        setFenceNV     = &glSetFenceNVNULL;
+        testFenceNV    = &glTestFenceNVNULL;
+    }
+
+    if (extensions.count("GL_NV_framebuffer_mixed_samples") != 0)
+    {
+        coverageModulationNV = &glCoverageModulationNVNULL;
+    }
+
+    if (extensions.count("GL_NV_internalformat_sample_query") != 0)
+    {
+        getInternalformatSampleivNV = &glGetInternalformatSampleivNVNULL;
+    }
+
+    if (extensions.count("GL_NV_path_rendering") != 0)
+    {
+        coverFillPathInstancedNV              = &glCoverFillPathInstancedNVNULL;
+        coverFillPathNV                       = &glCoverFillPathNVNULL;
+        coverStrokePathInstancedNV            = &glCoverStrokePathInstancedNVNULL;
+        coverStrokePathNV                     = &glCoverStrokePathNVNULL;
+        deletePathsNV                         = &glDeletePathsNVNULL;
+        genPathsNV                            = &glGenPathsNVNULL;
+        getPathParameterfvNV                  = &glGetPathParameterfvNVNULL;
+        getPathParameterivNV                  = &glGetPathParameterivNVNULL;
+        isPathNV                              = &glIsPathNVNULL;
+        matrixLoadfEXT                        = &glMatrixLoadfEXTNULL;
+        pathCommandsNV                        = &glPathCommandsNVNULL;
+        pathParameterfNV                      = &glPathParameterfNVNULL;
+        pathParameteriNV                      = &glPathParameteriNVNULL;
+        pathStencilFuncNV                     = &glPathStencilFuncNVNULL;
+        programPathFragmentInputGenNV         = &glProgramPathFragmentInputGenNVNULL;
+        stencilFillPathInstancedNV            = &glStencilFillPathInstancedNVNULL;
+        stencilFillPathNV                     = &glStencilFillPathNVNULL;
+        stencilStrokePathInstancedNV          = &glStencilStrokePathInstancedNVNULL;
+        stencilStrokePathNV                   = &glStencilStrokePathNVNULL;
+        stencilThenCoverFillPathInstancedNV   = &glStencilThenCoverFillPathInstancedNVNULL;
+        stencilThenCoverFillPathNV            = &glStencilThenCoverFillPathNVNULL;
+        stencilThenCoverStrokePathInstancedNV = &glStencilThenCoverStrokePathInstancedNVNULL;
+        stencilThenCoverStrokePathNV          = &glStencilThenCoverStrokePathNVNULL;
+    }
+}
+#endif  // defined(ANGLE_ENABLE_OPENGL_NULL)
+
+}  // namespace rx
new file mode 100644
--- /dev/null
+++ b/gfx/angle/src/libANGLE/renderer/gl/DispatchTableGL_autogen.h
@@ -0,0 +1,793 @@
+// GENERATED FILE - DO NOT EDIT.
+// Generated by generate_gl_dispatch_table.py using data from gl_bindings_data.json and gl.xml.
+//
+// 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.
+//
+// DispatchTableGL_autogen.h:
+//   Defines the native binding interface for ANGLE's OpenGL back-end.
+
+#ifndef LIBGLESV2_RENDERER_GL_DISPATCH_TABLE_GL_AUTOGEN_H_
+#define LIBGLESV2_RENDERER_GL_DISPATCH_TABLE_GL_AUTOGEN_H_
+
+#include "common/angleutils.h"
+#include "libANGLE/renderer/gl/functionsgl_typedefs.h"
+
+#include <set>
+
+namespace gl
+{
+struct Version;
+}  // namespace gl
+
+namespace rx
+{
+class DispatchTableGL : angle::NonCopyable
+{
+  public:
+    // 1.0
+    PFNGLBLENDFUNCPROC blendFunc                           = nullptr;
+    PFNGLCLEARPROC clear                                   = nullptr;
+    PFNGLCLEARCOLORPROC clearColor                         = nullptr;
+    PFNGLCLEARDEPTHPROC clearDepth                         = nullptr;
+    PFNGLCLEARSTENCILPROC clearStencil                     = nullptr;
+    PFNGLCOLORMASKPROC colorMask                           = nullptr;
+    PFNGLCULLFACEPROC cullFace                             = nullptr;
+    PFNGLDEPTHFUNCPROC depthFunc                           = nullptr;
+    PFNGLDEPTHMASKPROC depthMask                           = nullptr;
+    PFNGLDEPTHRANGEPROC depthRange                         = nullptr;
+    PFNGLDISABLEPROC disable                               = nullptr;
+    PFNGLDRAWBUFFERPROC drawBuffer                         = nullptr;
+    PFNGLENABLEPROC enable                                 = nullptr;
+    PFNGLFINISHPROC finish                                 = nullptr;
+    PFNGLFLUSHPROC flush                                   = nullptr;
+    PFNGLFRONTFACEPROC frontFace                           = nullptr;
+    PFNGLGETBOOLEANVPROC getBooleanv                       = nullptr;
+    PFNGLGETDOUBLEVPROC getDoublev                         = nullptr;
+    PFNGLGETERRORPROC getError                             = nullptr;
+    PFNGLGETFLOATVPROC getFloatv                           = nullptr;
+    PFNGLGETINTEGERVPROC getIntegerv                       = nullptr;
+    PFNGLGETSTRINGPROC getString                           = nullptr;
+    PFNGLGETTEXIMAGEPROC getTexImage                       = nullptr;
+    PFNGLGETTEXLEVELPARAMETERFVPROC getTexLevelParameterfv = nullptr;
+    PFNGLGETTEXLEVELPARAMETERIVPROC getTexLevelParameteriv = nullptr;
+    PFNGLGETTEXPARAMETERFVPROC getTexParameterfv           = nullptr;
+    PFNGLGETTEXPARAMETERIVPROC getTexParameteriv           = nullptr;
+    PFNGLHINTPROC hint                                     = nullptr;
+    PFNGLISENABLEDPROC isEnabled                           = nullptr;
+    PFNGLLINEWIDTHPROC lineWidth                           = nullptr;
+    PFNGLLOGICOPPROC logicOp                               = nullptr;
+    PFNGLPIXELSTOREFPROC pixelStoref                       = nullptr;
+    PFNGLPIXELSTOREIPROC pixelStorei                       = nullptr;
+    PFNGLPOINTSIZEPROC pointSize                           = nullptr;
+    PFNGLPOLYGONMODEPROC polygonMode                       = nullptr;
+    PFNGLREADBUFFERPROC readBuffer                         = nullptr;
+    PFNGLREADPIXELSPROC readPixels                         = nullptr;
+    PFNGLSCISSORPROC scissor                               = nullptr;
+    PFNGLSTENCILFUNCPROC stencilFunc                       = nullptr;
+    PFNGLSTENCILMASKPROC stencilMask                       = nullptr;
+    PFNGLSTENCILOPPROC stencilOp                           = nullptr;
+    PFNGLTEXIMAGE1DPROC texImage1D                         = nullptr;
+    PFNGLTEXIMAGE2DPROC texImage2D                         = nullptr;
+    PFNGLTEXPARAMETERFPROC texParameterf                   = nullptr;
+    PFNGLTEXPARAMETERFVPROC texParameterfv                 = nullptr;
+    PFNGLTEXPARAMETERIPROC texParameteri                   = nullptr;
+    PFNGLTEXPARAMETERIVPROC texParameteriv                 = nullptr;
+    PFNGLVIEWPORTPROC viewport                             = nullptr;
+
+    // 1.1
+    PFNGLBINDTEXTUREPROC bindTexture             = nullptr;
+    PFNGLCOPYTEXIMAGE1DPROC copyTexImage1D       = nullptr;
+    PFNGLCOPYTEXIMAGE2DPROC copyTexImage2D       = nullptr;
+    PFNGLCOPYTEXSUBIMAGE1DPROC copyTexSubImage1D = nullptr;
+    PFNGLCOPYTEXSUBIMAGE2DPROC copyTexSubImage2D = nullptr;
+    PFNGLDELETETEXTURESPROC deleteTextures       = nullptr;
+    PFNGLDRAWARRAYSPROC drawArrays               = nullptr;
+    PFNGLDRAWELEMENTSPROC drawElements           = nullptr;
+    PFNGLGENTEXTURESPROC genTextures             = nullptr;
+    PFNGLISTEXTUREPROC isTexture                 = nullptr;
+    PFNGLPOLYGONOFFSETPROC polygonOffset         = nullptr;
+    PFNGLTEXSUBIMAGE1DPROC texSubImage1D         = nullptr;
+    PFNGLTEXSUBIMAGE2DPROC texSubImage2D         = nullptr;
+
+    // 1.2
+    PFNGLBLENDCOLORPROC blendColor               = nullptr;
+    PFNGLBLENDEQUATIONPROC blendEquation         = nullptr;
+    PFNGLCOPYTEXSUBIMAGE3DPROC copyTexSubImage3D = nullptr;
+    PFNGLDRAWRANGEELEMENTSPROC drawRangeElements = nullptr;
+    PFNGLTEXIMAGE3DPROC texImage3D               = nullptr;
+    PFNGLTEXSUBIMAGE3DPROC texSubImage3D         = nullptr;
+
+    // 1.2 Extensions
+    PFNGLDELETEFENCESNVPROC deleteFencesNV = nullptr;
+    PFNGLFINISHFENCENVPROC finishFenceNV   = nullptr;
+    PFNGLGENFENCESNVPROC genFencesNV       = nullptr;
+    PFNGLGETFENCEIVNVPROC getFenceivNV     = nullptr;
+    PFNGLISFENCENVPROC isFenceNV           = nullptr;
+    PFNGLSETFENCENVPROC setFenceNV         = nullptr;
+    PFNGLTESTFENCENVPROC testFenceNV       = nullptr;
+
+    // 1.3
+    PFNGLACTIVETEXTUREPROC activeTexture                     = nullptr;
+    PFNGLCOMPRESSEDTEXIMAGE1DPROC compressedTexImage1D       = nullptr;
+    PFNGLCOMPRESSEDTEXIMAGE2DPROC compressedTexImage2D       = nullptr;
+    PFNGLCOMPRESSEDTEXIMAGE3DPROC compressedTexImage3D       = nullptr;
+    PFNGLCOMPRESSEDTEXSUBIMAGE1DPROC compressedTexSubImage1D = nullptr;
+    PFNGLCOMPRESSEDTEXSUBIMAGE2DPROC compressedTexSubImage2D = nullptr;
+    PFNGLCOMPRESSEDTEXSUBIMAGE3DPROC compressedTexSubImage3D = nullptr;
+    PFNGLGETCOMPRESSEDTEXIMAGEPROC getCompressedTexImage     = nullptr;
+    PFNGLSAMPLECOVERAGEPROC sampleCoverage                   = nullptr;
+
+    // 1.4
+    PFNGLBLENDFUNCSEPARATEPROC blendFuncSeparate = nullptr;
+    PFNGLMULTIDRAWARRAYSPROC multiDrawArrays     = nullptr;
+    PFNGLMULTIDRAWELEMENTSPROC multiDrawElements = nullptr;
+    PFNGLPOINTPARAMETERFPROC pointParameterf     = nullptr;
+    PFNGLPOINTPARAMETERFVPROC pointParameterfv   = nullptr;
+    PFNGLPOINTPARAMETERIPROC pointParameteri     = nullptr;
+    PFNGLPOINTPARAMETERIVPROC pointParameteriv   = nullptr;
+
+    // 1.5
+    PFNGLBEGINQUERYPROC beginQuery                     = nullptr;
+    PFNGLBINDBUFFERPROC bindBuffer                     = nullptr;
+    PFNGLBUFFERDATAPROC bufferData                     = nullptr;
+    PFNGLBUFFERSUBDATAPROC bufferSubData               = nullptr;
+    PFNGLDELETEBUFFERSPROC deleteBuffers               = nullptr;
+    PFNGLDELETEQUERIESPROC deleteQueries               = nullptr;
+    PFNGLENDQUERYPROC endQuery                         = nullptr;
+    PFNGLGENBUFFERSPROC genBuffers                     = nullptr;
+    PFNGLGENQUERIESPROC genQueries                     = nullptr;
+    PFNGLGETBUFFERPARAMETERIVPROC getBufferParameteriv = nullptr;
+    PFNGLGETBUFFERPOINTERVPROC getBufferPointerv       = nullptr;
+    PFNGLGETBUFFERSUBDATAPROC getBufferSubData         = nullptr;
+    PFNGLGETQUERYOBJECTIVPROC getQueryObjectiv         = nullptr;
+    PFNGLGETQUERYOBJECTUIVPROC getQueryObjectuiv       = nullptr;
+    PFNGLGETQUERYIVPROC getQueryiv                     = nullptr;
+    PFNGLISBUFFERPROC isBuffer                         = nullptr;
+    PFNGLISQUERYPROC isQuery                           = nullptr;
+    PFNGLMAPBUFFERPROC mapBuffer                       = nullptr;
+    PFNGLUNMAPBUFFERPROC unmapBuffer                   = nullptr;
+
+    // 2.0
+    PFNGLATTACHSHADERPROC attachShader                         = nullptr;
+    PFNGLBINDATTRIBLOCATIONPROC bindAttribLocation             = nullptr;
+    PFNGLBLENDEQUATIONSEPARATEPROC blendEquationSeparate       = nullptr;
+    PFNGLCOMPILESHADERPROC compileShader                       = nullptr;
+    PFNGLCREATEPROGRAMPROC createProgram                       = nullptr;
+    PFNGLCREATESHADERPROC createShader                         = nullptr;
+    PFNGLDELETEPROGRAMPROC deleteProgram                       = nullptr;
+    PFNGLDELETESHADERPROC deleteShader                         = nullptr;
+    PFNGLDETACHSHADERPROC detachShader                         = nullptr;
+    PFNGLDISABLEVERTEXATTRIBARRAYPROC disableVertexAttribArray = nullptr;
+    PFNGLDRAWBUFFERSPROC drawBuffers                           = nullptr;
+    PFNGLENABLEVERTEXATTRIBARRAYPROC enableVertexAttribArray   = nullptr;
+    PFNGLGETACTIVEATTRIBPROC getActiveAttrib                   = nullptr;
+    PFNGLGETACTIVEUNIFORMPROC getActiveUniform                 = nullptr;
+    PFNGLGETATTACHEDSHADERSPROC getAttachedShaders             = nullptr;
+    PFNGLGETATTRIBLOCATIONPROC getAttribLocation               = nullptr;
+    PFNGLGETPROGRAMINFOLOGPROC getProgramInfoLog               = nullptr;
+    PFNGLGETPROGRAMIVPROC getProgramiv                         = nullptr;
+    PFNGLGETSHADERINFOLOGPROC getShaderInfoLog                 = nullptr;
+    PFNGLGETSHADERSOURCEPROC getShaderSource                   = nullptr;
+    PFNGLGETSHADERIVPROC getShaderiv                           = nullptr;
+    PFNGLGETUNIFORMLOCATIONPROC getUniformLocation             = nullptr;
+    PFNGLGETUNIFORMFVPROC getUniformfv                         = nullptr;
+    PFNGLGETUNIFORMIVPROC getUniformiv                         = nullptr;
+    PFNGLGETVERTEXATTRIBPOINTERVPROC getVertexAttribPointerv   = nullptr;
+    PFNGLGETVERTEXATTRIBDVPROC getVertexAttribdv               = nullptr;
+    PFNGLGETVERTEXATTRIBFVPROC getVertexAttribfv               = nullptr;
+    PFNGLGETVERTEXATTRIBIVPROC getVertexAttribiv               = nullptr;
+    PFNGLISPROGRAMPROC isProgram                               = nullptr;
+    PFNGLISSHADERPROC isShader                                 = nullptr;
+    PFNGLLINKPROGRAMPROC linkProgram                           = nullptr;
+    PFNGLSHADERSOURCEPROC shaderSource                         = nullptr;
+    PFNGLSTENCILFUNCSEPARATEPROC stencilFuncSeparate           = nullptr;
+    PFNGLSTENCILMASKSEPARATEPROC stencilMaskSeparate           = nullptr;
+    PFNGLSTENCILOPSEPARATEPROC stencilOpSeparate               = nullptr;
+    PFNGLUNIFORM1FPROC uniform1f                               = nullptr;
+    PFNGLUNIFORM1FVPROC uniform1fv                             = nullptr;
+    PFNGLUNIFORM1IPROC uniform1i                               = nullptr;
+    PFNGLUNIFORM1IVPROC uniform1iv                             = nullptr;
+    PFNGLUNIFORM2FPROC uniform2f                               = nullptr;
+    PFNGLUNIFORM2FVPROC uniform2fv                             = nullptr;
+    PFNGLUNIFORM2IPROC uniform2i                               = nullptr;
+    PFNGLUNIFORM2IVPROC uniform2iv                             = nullptr;
+    PFNGLUNIFORM3FPROC uniform3f                               = nullptr;
+    PFNGLUNIFORM3FVPROC uniform3fv                             = nullptr;
+    PFNGLUNIFORM3IPROC uniform3i                               = nullptr;
+    PFNGLUNIFORM3IVPROC uniform3iv                             = nullptr;
+    PFNGLUNIFORM4FPROC uniform4f                               = nullptr;
+    PFNGLUNIFORM4FVPROC uniform4fv                             = nullptr;
+    PFNGLUNIFORM4IPROC uniform4i                               = nullptr;
+    PFNGLUNIFORM4IVPROC uniform4iv                             = nullptr;
+    PFNGLUNIFORMMATRIX2FVPROC uniformMatrix2fv                 = nullptr;
+    PFNGLUNIFORMMATRIX3FVPROC uniformMatrix3fv                 = nullptr;
+    PFNGLUNIFORMMATRIX4FVPROC uniformMatrix4fv                 = nullptr;
+    PFNGLUSEPROGRAMPROC useProgram                             = nullptr;
+    PFNGLVALIDATEPROGRAMPROC validateProgram                   = nullptr;
+    PFNGLVERTEXATTRIB1DPROC vertexAttrib1d                     = nullptr;
+    PFNGLVERTEXATTRIB1DVPROC vertexAttrib1dv                   = nullptr;
+    PFNGLVERTEXATTRIB1FPROC vertexAttrib1f                     = nullptr;
+    PFNGLVERTEXATTRIB1FVPROC vertexAttrib1fv                   = nullptr;
+    PFNGLVERTEXATTRIB1SPROC vertexAttrib1s                     = nullptr;
+    PFNGLVERTEXATTRIB1SVPROC vertexAttrib1sv                   = nullptr;
+    PFNGLVERTEXATTRIB2DPROC vertexAttrib2d                     = nullptr;
+    PFNGLVERTEXATTRIB2DVPROC vertexAttrib2dv                   = nullptr;
+    PFNGLVERTEXATTRIB2FPROC vertexAttrib2f                     = nullptr;
+    PFNGLVERTEXATTRIB2FVPROC vertexAttrib2fv                   = nullptr;
+    PFNGLVERTEXATTRIB2SPROC vertexAttrib2s                     = nullptr;
+    PFNGLVERTEXATTRIB2SVPROC vertexAttrib2sv                   = nullptr;
+    PFNGLVERTEXATTRIB3DPROC vertexAttrib3d                     = nullptr;
+    PFNGLVERTEXATTRIB3DVPROC vertexAttrib3dv                   = nullptr;
+    PFNGLVERTEXATTRIB3FPROC vertexAttrib3f                     = nullptr;
+    PFNGLVERTEXATTRIB3FVPROC vertexAttrib3fv                   = nullptr;
+    PFNGLVERTEXATTRIB3SPROC vertexAttrib3s                     = nullptr;
+    PFNGLVERTEXATTRIB3SVPROC vertexAttrib3sv                   = nullptr;
+    PFNGLVERTEXATTRIB4NBVPROC vertexAttrib4Nbv                 = nullptr;
+    PFNGLVERTEXATTRIB4NIVPROC vertexAttrib4Niv                 = nullptr;
+    PFNGLVERTEXATTRIB4NSVPROC vertexAttrib4Nsv                 = nullptr;
+    PFNGLVERTEXATTRIB4NUBPROC vertexAttrib4Nub                 = nullptr;
+    PFNGLVERTEXATTRIB4NUBVPROC vertexAttrib4Nubv               = nullptr;
+    PFNGLVERTEXATTRIB4NUIVPROC vertexAttrib4Nuiv               = nullptr;
+    PFNGLVERTEXATTRIB4NUSVPROC vertexAttrib4Nusv               = nullptr;
+    PFNGLVERTEXATTRIB4BVPROC vertexAttrib4bv                   = nullptr;
+    PFNGLVERTEXATTRIB4DPROC vertexAttrib4d                     = nullptr;
+    PFNGLVERTEXATTRIB4DVPROC vertexAttrib4dv                   = nullptr;
+    PFNGLVERTEXATTRIB4FPROC vertexAttrib4f                     = nullptr;
+    PFNGLVERTEXATTRIB4FVPROC vertexAttrib4fv                   = nullptr;
+    PFNGLVERTEXATTRIB4IVPROC vertexAttrib4iv                   = nullptr;
+    PFNGLVERTEXATTRIB4SPROC vertexAttrib4s                     = nullptr;
+    PFNGLVERTEXATTRIB4SVPROC vertexAttrib4sv                   = nullptr;
+    PFNGLVERTEXATTRIB4UBVPROC vertexAttrib4ubv                 = nullptr;
+    PFNGLVERTEXATTRIB4UIVPROC vertexAttrib4uiv                 = nullptr;
+    PFNGLVERTEXATTRIB4USVPROC vertexAttrib4usv                 = nullptr;
+    PFNGLVERTEXATTRIBPOINTERPROC vertexAttribPointer           = nullptr;
+
+    // 2.1
+    PFNGLUNIFORMMATRIX2X3FVPROC uniformMatrix2x3fv = nullptr;
+    PFNGLUNIFORMMATRIX2X4FVPROC uniformMatrix2x4fv = nullptr;
+    PFNGLUNIFORMMATRIX3X2FVPROC uniformMatrix3x2fv = nullptr;
+    PFNGLUNIFORMMATRIX3X4FVPROC uniformMatrix3x4fv = nullptr;
+    PFNGLUNIFORMMATRIX4X2FVPROC uniformMatrix4x2fv = nullptr;
+    PFNGLUNIFORMMATRIX4X3FVPROC uniformMatrix4x3fv = nullptr;
+
+    // 3.0
+    PFNGLBEGINCONDITIONALRENDERPROC beginConditionalRender                           = nullptr;
+    PFNGLBEGINTRANSFORMFEEDBACKPROC beginTransformFeedback                           = nullptr;
+    PFNGLBINDBUFFERBASEPROC bindBufferBase                                           = nullptr;
+    PFNGLBINDBUFFERRANGEPROC bindBufferRange                                         = nullptr;
+    PFNGLBINDFRAGDATALOCATIONPROC bindFragDataLocation                               = nullptr;
+    PFNGLBINDFRAMEBUFFERPROC bindFramebuffer                                         = nullptr;
+    PFNGLBINDRENDERBUFFERPROC bindRenderbuffer                                       = nullptr;
+    PFNGLBINDVERTEXARRAYPROC bindVertexArray                                         = nullptr;
+    PFNGLBLITFRAMEBUFFERPROC blitFramebuffer                                         = nullptr;
+    PFNGLCHECKFRAMEBUFFERSTATUSPROC checkFramebufferStatus                           = nullptr;
+    PFNGLCLAMPCOLORPROC clampColor                                                   = nullptr;
+    PFNGLCLEARBUFFERFIPROC clearBufferfi                                             = nullptr;
+    PFNGLCLEARBUFFERFVPROC clearBufferfv                                             = nullptr;
+    PFNGLCLEARBUFFERIVPROC clearBufferiv                                             = nullptr;
+    PFNGLCLEARBUFFERUIVPROC clearBufferuiv                                           = nullptr;
+    PFNGLCOLORMASKIPROC colorMaski                                                   = nullptr;
+    PFNGLDELETEFRAMEBUFFERSPROC deleteFramebuffers                                   = nullptr;
+    PFNGLDELETERENDERBUFFERSPROC deleteRenderbuffers                                 = nullptr;
+    PFNGLDELETEVERTEXARRAYSPROC deleteVertexArrays                                   = nullptr;
+    PFNGLDISABLEIPROC disablei                                                       = nullptr;
+    PFNGLENABLEIPROC enablei                                                         = nullptr;
+    PFNGLENDCONDITIONALRENDERPROC endConditionalRender                               = nullptr;
+    PFNGLENDTRANSFORMFEEDBACKPROC endTransformFeedback                               = nullptr;
+    PFNGLFLUSHMAPPEDBUFFERRANGEPROC flushMappedBufferRange                           = nullptr;
+    PFNGLFRAMEBUFFERRENDERBUFFERPROC framebufferRenderbuffer                         = nullptr;
+    PFNGLFRAMEBUFFERTEXTURE1DPROC framebufferTexture1D                               = nullptr;
+    PFNGLFRAMEBUFFERTEXTURE2DPROC framebufferTexture2D                               = nullptr;
+    PFNGLFRAMEBUFFERTEXTURE3DPROC framebufferTexture3D                               = nullptr;
+    PFNGLFRAMEBUFFERTEXTURELAYERPROC framebufferTextureLayer                         = nullptr;
+    PFNGLGENFRAMEBUFFERSPROC genFramebuffers                                         = nullptr;
+    PFNGLGENRENDERBUFFERSPROC genRenderbuffers                                       = nullptr;
+    PFNGLGENVERTEXARRAYSPROC genVertexArrays                                         = nullptr;
+    PFNGLGENERATEMIPMAPPROC generateMipmap                                           = nullptr;
+    PFNGLGETBOOLEANI_VPROC getBooleani_v                                             = nullptr;
+    PFNGLGETFRAGDATALOCATIONPROC getFragDataLocation                                 = nullptr;
+    PFNGLGETFRAMEBUFFERATTACHMENTPARAMETERIVPROC getFramebufferAttachmentParameteriv = nullptr;
+    PFNGLGETINTEGERI_VPROC getIntegeri_v                                             = nullptr;
+    PFNGLGETRENDERBUFFERPARAMETERIVPROC getRenderbufferParameteriv                   = nullptr;
+    PFNGLGETSTRINGIPROC getStringi                                                   = nullptr;
+    PFNGLGETTEXPARAMETERIIVPROC getTexParameterIiv                                   = nullptr;
+    PFNGLGETTEXPARAMETERIUIVPROC getTexParameterIuiv                                 = nullptr;
+    PFNGLGETTRANSFORMFEEDBACKVARYINGPROC getTransformFeedbackVarying                 = nullptr;
+    PFNGLGETUNIFORMUIVPROC getUniformuiv                                             = nullptr;
+    PFNGLGETVERTEXATTRIBIIVPROC getVertexAttribIiv                                   = nullptr;
+    PFNGLGETVERTEXATTRIBIUIVPROC getVertexAttribIuiv                                 = nullptr;
+    PFNGLISENABLEDIPROC isEnabledi                                                   = nullptr;
+    PFNGLISFRAMEBUFFERPROC isFramebuffer                                             = nullptr;
+    PFNGLISRENDERBUFFERPROC isRenderbuffer                                           = nullptr;
+    PFNGLISVERTEXARRAYPROC isVertexArray                                             = nullptr;
+    PFNGLMAPBUFFERRANGEPROC mapBufferRange                                           = nullptr;
+    PFNGLRENDERBUFFERSTORAGEPROC renderbufferStorage                                 = nullptr;
+    PFNGLRENDERBUFFERSTORAGEMULTISAMPLEPROC renderbufferStorageMultisample           = nullptr;
+    PFNGLTEXPARAMETERIIVPROC texParameterIiv                                         = nullptr;
+    PFNGLTEXPARAMETERIUIVPROC texParameterIuiv                                       = nullptr;
+    PFNGLTRANSFORMFEEDBACKVARYINGSPROC transformFeedbackVaryings                     = nullptr;
+    PFNGLUNIFORM1UIPROC uniform1ui                                                   = nullptr;
+    PFNGLUNIFORM1UIVPROC uniform1uiv                                                 = nullptr;
+    PFNGLUNIFORM2UIPROC uniform2ui                                                   = nullptr;
+    PFNGLUNIFORM2UIVPROC uniform2uiv                                                 = nullptr;
+    PFNGLUNIFORM3UIPROC uniform3ui                                                   = nullptr;
+    PFNGLUNIFORM3UIVPROC uniform3uiv                                                 = nullptr;
+    PFNGLUNIFORM4UIPROC uniform4ui                                                   = nullptr;
+    PFNGLUNIFORM4UIVPROC uniform4uiv                                                 = nullptr;
+    PFNGLVERTEXATTRIBI1IPROC vertexAttribI1i                                         = nullptr;
+    PFNGLVERTEXATTRIBI1IVPROC vertexAttribI1iv                                       = nullptr;
+    PFNGLVERTEXATTRIBI1UIPROC vertexAttribI1ui                                       = nullptr;
+    PFNGLVERTEXATTRIBI1UIVPROC vertexAttribI1uiv                                     = nullptr;
+    PFNGLVERTEXATTRIBI2IPROC vertexAttribI2i                                         = nullptr;
+    PFNGLVERTEXATTRIBI2IVPROC vertexAttribI2iv                                       = nullptr;
+    PFNGLVERTEXATTRIBI2UIPROC vertexAttribI2ui                                       = nullptr;
+    PFNGLVERTEXATTRIBI2UIVPROC vertexAttribI2uiv                                     = nullptr;
+    PFNGLVERTEXATTRIBI3IPROC vertexAttribI3i                                         = nullptr;
+    PFNGLVERTEXATTRIBI3IVPROC vertexAttribI3iv                                       = nullptr;
+    PFNGLVERTEXATTRIBI3UIPROC vertexAttribI3ui                                       = nullptr;
+    PFNGLVERTEXATTRIBI3UIVPROC vertexAttribI3uiv                                     = nullptr;
+    PFNGLVERTEXATTRIBI4BVPROC vertexAttribI4bv                                       = nullptr;
+    PFNGLVERTEXATTRIBI4IPROC vertexAttribI4i                                         = nullptr;
+    PFNGLVERTEXATTRIBI4IVPROC vertexAttribI4iv                                       = nullptr;
+    PFNGLVERTEXATTRIBI4SVPROC vertexAttribI4sv                                       = nullptr;
+    PFNGLVERTEXATTRIBI4UBVPROC vertexAttribI4ubv                                     = nullptr;
+    PFNGLVERTEXATTRIBI4UIPROC vertexAttribI4ui                                       = nullptr;
+    PFNGLVERTEXATTRIBI4UIVPROC vertexAttribI4uiv                                     = nullptr;
+    PFNGLVERTEXATTRIBI4USVPROC vertexAttribI4usv                                     = nullptr;
+    PFNGLVERTEXATTRIBIPOINTERPROC vertexAttribIPointer                               = nullptr;
+
+    // 3.1
+    PFNGLCOPYBUFFERSUBDATAPROC copyBufferSubData                 = nullptr;
+    PFNGLDRAWARRAYSINSTANCEDPROC drawArraysInstanced             = nullptr;
+    PFNGLDRAWELEMENTSINSTANCEDPROC drawElementsInstanced         = nullptr;
+    PFNGLGETACTIVEUNIFORMBLOCKNAMEPROC getActiveUniformBlockName = nullptr;
+    PFNGLGETACTIVEUNIFORMBLOCKIVPROC getActiveUniformBlockiv     = nullptr;
+    PFNGLGETACTIVEUNIFORMNAMEPROC getActiveUniformName           = nullptr;
+    PFNGLGETACTIVEUNIFORMSIVPROC getActiveUniformsiv             = nullptr;
+    PFNGLGETUNIFORMBLOCKINDEXPROC getUniformBlockIndex           = nullptr;
+    PFNGLGETUNIFORMINDICESPROC getUniformIndices                 = nullptr;
+    PFNGLPRIMITIVERESTARTINDEXPROC primitiveRestartIndex         = nullptr;
+    PFNGLTEXBUFFERPROC texBuffer                                 = nullptr;
+    PFNGLUNIFORMBLOCKBINDINGPROC uniformBlockBinding             = nullptr;
+
+    // 3.2
+    PFNGLCLIENTWAITSYNCPROC clientWaitSync                                   = nullptr;
+    PFNGLDELETESYNCPROC deleteSync                                           = nullptr;
+    PFNGLDRAWELEMENTSBASEVERTEXPROC drawElementsBaseVertex                   = nullptr;
+    PFNGLDRAWELEMENTSINSTANCEDBASEVERTEXPROC drawElementsInstancedBaseVertex = nullptr;
+    PFNGLDRAWRANGEELEMENTSBASEVERTEXPROC drawRangeElementsBaseVertex         = nullptr;
+    PFNGLFENCESYNCPROC fenceSync                                             = nullptr;
+    PFNGLFRAMEBUFFERTEXTUREPROC framebufferTexture                           = nullptr;
+    PFNGLGETBUFFERPARAMETERI64VPROC getBufferParameteri64v                   = nullptr;
+    PFNGLGETINTEGER64I_VPROC getInteger64i_v                                 = nullptr;
+    PFNGLGETINTEGER64VPROC getInteger64v                                     = nullptr;
+    PFNGLGETMULTISAMPLEFVPROC getMultisamplefv                               = nullptr;
+    PFNGLGETSYNCIVPROC getSynciv                                             = nullptr;
+    PFNGLISSYNCPROC isSync                                                   = nullptr;
+    PFNGLMULTIDRAWELEMENTSBASEVERTEXPROC multiDrawElementsBaseVertex         = nullptr;
+    PFNGLPROVOKINGVERTEXPROC provokingVertex                                 = nullptr;
+    PFNGLSAMPLEMASKIPROC sampleMaski                                         = nullptr;
+    PFNGLTEXIMAGE2DMULTISAMPLEPROC texImage2DMultisample                     = nullptr;
+    PFNGLTEXIMAGE3DMULTISAMPLEPROC texImage3DMultisample                     = nullptr;
+    PFNGLWAITSYNCPROC waitSync                                               = nullptr;
+
+    // 3.3
+    PFNGLBINDFRAGDATALOCATIONINDEXEDPROC bindFragDataLocationIndexed = nullptr;
+    PFNGLBINDSAMPLERPROC bindSampler                                 = nullptr;
+    PFNGLDELETESAMPLERSPROC deleteSamplers                           = nullptr;
+    PFNGLGENSAMPLERSPROC genSamplers                                 = nullptr;
+    PFNGLGETFRAGDATAINDEXPROC getFragDataIndex                       = nullptr;
+    PFNGLGETQUERYOBJECTI64VPROC getQueryObjecti64v                   = nullptr;
+    PFNGLGETQUERYOBJECTUI64VPROC getQueryObjectui64v                 = nullptr;
+    PFNGLGETSAMPLERPARAMETERIIVPROC getSamplerParameterIiv           = nullptr;
+    PFNGLGETSAMPLERPARAMETERIUIVPROC getSamplerParameterIuiv         = nullptr;
+    PFNGLGETSAMPLERPARAMETERFVPROC getSamplerParameterfv             = nullptr;
+    PFNGLGETSAMPLERPARAMETERIVPROC getSamplerParameteriv             = nullptr;
+    PFNGLISSAMPLERPROC isSampler                                     = nullptr;
+    PFNGLQUERYCOUNTERPROC queryCounter                               = nullptr;
+    PFNGLSAMPLERPARAMETERIIVPROC samplerParameterIiv                 = nullptr;
+    PFNGLSAMPLERPARAMETERIUIVPROC samplerParameterIuiv               = nullptr;
+    PFNGLSAMPLERPARAMETERFPROC samplerParameterf                     = nullptr;
+    PFNGLSAMPLERPARAMETERFVPROC samplerParameterfv                   = nullptr;
+    PFNGLSAMPLERPARAMETERIPROC samplerParameteri                     = nullptr;
+    PFNGLSAMPLERPARAMETERIVPROC samplerParameteriv                   = nullptr;
+    PFNGLVERTEXATTRIBDIVISORPROC vertexAttribDivisor                 = nullptr;
+    PFNGLVERTEXATTRIBP1UIPROC vertexAttribP1ui                       = nullptr;
+    PFNGLVERTEXATTRIBP1UIVPROC vertexAttribP1uiv                     = nullptr;
+    PFNGLVERTEXATTRIBP2UIPROC vertexAttribP2ui                       = nullptr;
+    PFNGLVERTEXATTRIBP2UIVPROC vertexAttribP2uiv                     = nullptr;
+    PFNGLVERTEXATTRIBP3UIPROC vertexAttribP3ui                       = nullptr;
+    PFNGLVERTEXATTRIBP3UIVPROC vertexAttribP3uiv                     = nullptr;
+    PFNGLVERTEXATTRIBP4UIPROC vertexAttribP4ui                       = nullptr;
+    PFNGLVERTEXATTRIBP4UIVPROC vertexAttribP4uiv                     = nullptr;
+
+    // 4.0
+    PFNGLBEGINQUERYINDEXEDPROC beginQueryIndexed                           = nullptr;
+    PFNGLBINDTRANSFORMFEEDBACKPROC bindTransformFeedback                   = nullptr;
+    PFNGLBLENDEQUATIONSEPARATEIPROC blendEquationSeparatei                 = nullptr;
+    PFNGLBLENDEQUATIONIPROC blendEquationi                                 = nullptr;
+    PFNGLBLENDFUNCSEPARATEIPROC blendFuncSeparatei                         = nullptr;
+    PFNGLBLENDFUNCIPROC blendFunci                                         = nullptr;
+    PFNGLDELETETRANSFORMFEEDBACKSPROC deleteTransformFeedbacks             = nullptr;
+    PFNGLDRAWARRAYSINDIRECTPROC drawArraysIndirect                         = nullptr;
+    PFNGLDRAWELEMENTSINDIRECTPROC drawElementsIndirect                     = nullptr;
+    PFNGLDRAWTRANSFORMFEEDBACKPROC drawTransformFeedback                   = nullptr;
+    PFNGLDRAWTRANSFORMFEEDBACKSTREAMPROC drawTransformFeedbackStream       = nullptr;
+    PFNGLENDQUERYINDEXEDPROC endQueryIndexed                               = nullptr;
+    PFNGLGENTRANSFORMFEEDBACKSPROC genTransformFeedbacks                   = nullptr;
+    PFNGLGETACTIVESUBROUTINENAMEPROC getActiveSubroutineName               = nullptr;
+    PFNGLGETACTIVESUBROUTINEUNIFORMNAMEPROC getActiveSubroutineUniformName = nullptr;
+    PFNGLGETACTIVESUBROUTINEUNIFORMIVPROC getActiveSubroutineUniformiv     = nullptr;
+    PFNGLGETPROGRAMSTAGEIVPROC getProgramStageiv                           = nullptr;
+    PFNGLGETQUERYINDEXEDIVPROC getQueryIndexediv                           = nullptr;
+    PFNGLGETSUBROUTINEINDEXPROC getSubroutineIndex                         = nullptr;
+    PFNGLGETSUBROUTINEUNIFORMLOCATIONPROC getSubroutineUniformLocation     = nullptr;
+    PFNGLGETUNIFORMSUBROUTINEUIVPROC getUniformSubroutineuiv               = nullptr;
+    PFNGLGETUNIFORMDVPROC getUniformdv                                     = nullptr;
+    PFNGLISTRANSFORMFEEDBACKPROC isTransformFeedback                       = nullptr;
+    PFNGLMINSAMPLESHADINGPROC minSampleShading                             = nullptr;
+    PFNGLPATCHPARAMETERFVPROC patchParameterfv                             = nullptr;
+    PFNGLPATCHPARAMETERIPROC patchParameteri                               = nullptr;
+    PFNGLPAUSETRANSFORMFEEDBACKPROC pauseTransformFeedback                 = nullptr;
+    PFNGLRESUMETRANSFORMFEEDBACKPROC resumeTransformFeedback               = nullptr;
+    PFNGLUNIFORM1DPROC uniform1d                                           = nullptr;
+    PFNGLUNIFORM1DVPROC uniform1dv                                         = nullptr;
+    PFNGLUNIFORM2DPROC uniform2d                                           = nullptr;
+    PFNGLUNIFORM2DVPROC uniform2dv                                         = nullptr;
+    PFNGLUNIFORM3DPROC uniform3d                                           = nullptr;
+    PFNGLUNIFORM3DVPROC uniform3dv                                         = nullptr;
+    PFNGLUNIFORM4DPROC uniform4d                                           = nullptr;
+    PFNGLUNIFORM4DVPROC uniform4dv                                         = nullptr;
+    PFNGLUNIFORMMATRIX2DVPROC uniformMatrix2dv                             = nullptr;
+    PFNGLUNIFORMMATRIX2X3DVPROC uniformMatrix2x3dv                         = nullptr;
+    PFNGLUNIFORMMATRIX2X4DVPROC uniformMatrix2x4dv                         = nullptr;
+    PFNGLUNIFORMMATRIX3DVPROC uniformMatrix3dv                             = nullptr;
+    PFNGLUNIFORMMATRIX3X2DVPROC uniformMatrix3x2dv                         = nullptr;
+    PFNGLUNIFORMMATRIX3X4DVPROC uniformMatrix3x4dv                         = nullptr;
+    PFNGLUNIFORMMATRIX4DVPROC uniformMatrix4dv                             = nullptr;
+    PFNGLUNIFORMMATRIX4X2DVPROC uniformMatrix4x2dv                         = nullptr;
+    PFNGLUNIFORMMATRIX4X3DVPROC uniformMatrix4x3dv                         = nullptr;
+    PFNGLUNIFORMSUBROUTINESUIVPROC uniformSubroutinesuiv                   = nullptr;
+
+    // 4.1
+    PFNGLACTIVESHADERPROGRAMPROC activeShaderProgram             = nullptr;
+    PFNGLBINDPROGRAMPIPELINEPROC bindProgramPipeline             = nullptr;
+    PFNGLCLEARDEPTHFPROC clearDepthf                             = nullptr;
+    PFNGLCREATESHADERPROGRAMVPROC createShaderProgramv           = nullptr;
+    PFNGLDELETEPROGRAMPIPELINESPROC deleteProgramPipelines       = nullptr;
+    PFNGLDEPTHRANGEARRAYVPROC depthRangeArrayv                   = nullptr;
+    PFNGLDEPTHRANGEINDEXEDPROC depthRangeIndexed                 = nullptr;
+    PFNGLDEPTHRANGEFPROC depthRangef                             = nullptr;
+    PFNGLGENPROGRAMPIPELINESPROC genProgramPipelines             = nullptr;
+    PFNGLGETDOUBLEI_VPROC getDoublei_v                           = nullptr;
+    PFNGLGETFLOATI_VPROC getFloati_v                             = nullptr;
+    PFNGLGETPROGRAMBINARYPROC getProgramBinary                   = nullptr;
+    PFNGLGETPROGRAMPIPELINEINFOLOGPROC getProgramPipelineInfoLog = nullptr;
+    PFNGLGETPROGRAMPIPELINEIVPROC getProgramPipelineiv           = nullptr;
+    PFNGLGETSHADERPRECISIONFORMATPROC getShaderPrecisionFormat   = nullptr;
+    PFNGLGETVERTEXATTRIBLDVPROC getVertexAttribLdv               = nullptr;
+    PFNGLISPROGRAMPIPELINEPROC isProgramPipeline                 = nullptr;
+    PFNGLPROGRAMBINARYPROC programBinary                         = nullptr;
+    PFNGLPROGRAMPARAMETERIPROC programParameteri                 = nullptr;
+    PFNGLPROGRAMUNIFORM1DPROC programUniform1d                   = nullptr;
+    PFNGLPROGRAMUNIFORM1DVPROC programUniform1dv                 = nullptr;
+    PFNGLPROGRAMUNIFORM1FPROC programUniform1f                   = nullptr;
+    PFNGLPROGRAMUNIFORM1FVPROC programUniform1fv                 = nullptr;
+    PFNGLPROGRAMUNIFORM1IPROC programUniform1i                   = nullptr;
+    PFNGLPROGRAMUNIFORM1IVPROC programUniform1iv                 = nullptr;
+    PFNGLPROGRAMUNIFORM1UIPROC programUniform1ui                 = nullptr;
+    PFNGLPROGRAMUNIFORM1UIVPROC programUniform1uiv               = nullptr;
+    PFNGLPROGRAMUNIFORM2DPROC programUniform2d                   = nullptr;
+    PFNGLPROGRAMUNIFORM2DVPROC programUniform2dv                 = nullptr;
+    PFNGLPROGRAMUNIFORM2FPROC programUniform2f                   = nullptr;
+    PFNGLPROGRAMUNIFORM2FVPROC programUniform2fv                 = nullptr;
+    PFNGLPROGRAMUNIFORM2IPROC programUniform2i                   = nullptr;
+    PFNGLPROGRAMUNIFORM2IVPROC programUniform2iv                 = nullptr;
+    PFNGLPROGRAMUNIFORM2UIPROC programUniform2ui                 = nullptr;
+    PFNGLPROGRAMUNIFORM2UIVPROC programUniform2uiv               = nullptr;
+    PFNGLPROGRAMUNIFORM3DPROC programUniform3d                   = nullptr;
+    PFNGLPROGRAMUNIFORM3DVPROC programUniform3dv                 = nullptr;
+    PFNGLPROGRAMUNIFORM3FPROC programUniform3f                   = nullptr;
+    PFNGLPROGRAMUNIFORM3FVPROC programUniform3fv                 = nullptr;
+    PFNGLPROGRAMUNIFORM3IPROC programUniform3i                   = nullptr;
+    PFNGLPROGRAMUNIFORM3IVPROC programUniform3iv                 = nullptr;
+    PFNGLPROGRAMUNIFORM3UIPROC programUniform3ui                 = nullptr;
+    PFNGLPROGRAMUNIFORM3UIVPROC programUniform3uiv               = nullptr;
+    PFNGLPROGRAMUNIFORM4DPROC programUniform4d                   = nullptr;
+    PFNGLPROGRAMUNIFORM4DVPROC programUniform4dv                 = nullptr;
+    PFNGLPROGRAMUNIFORM4FPROC programUniform4f                   = nullptr;
+    PFNGLPROGRAMUNIFORM4FVPROC programUniform4fv                 = nullptr;
+    PFNGLPROGRAMUNIFORM4IPROC programUniform4i                   = nullptr;
+    PFNGLPROGRAMUNIFORM4IVPROC programUniform4iv                 = nullptr;
+    PFNGLPROGRAMUNIFORM4UIPROC programUniform4ui                 = nullptr;
+    PFNGLPROGRAMUNIFORM4UIVPROC programUniform4uiv               = nullptr;
+    PFNGLPROGRAMUNIFORMMATRIX2DVPROC programUniformMatrix2dv     = nullptr;
+    PFNGLPROGRAMUNIFORMMATRIX2FVPROC programUniformMatrix2fv     = nullptr;
+    PFNGLPROGRAMUNIFORMMATRIX2X3DVPROC programUniformMatrix2x3dv = nullptr;
+    PFNGLPROGRAMUNIFORMMATRIX2X3FVPROC programUniformMatrix2x3fv = nullptr;
+    PFNGLPROGRAMUNIFORMMATRIX2X4DVPROC programUniformMatrix2x4dv = nullptr;
+    PFNGLPROGRAMUNIFORMMATRIX2X4FVPROC programUniformMatrix2x4fv = nullptr;
+    PFNGLPROGRAMUNIFORMMATRIX3DVPROC programUniformMatrix3dv     = nullptr;
+    PFNGLPROGRAMUNIFORMMATRIX3FVPROC programUniformMatrix3fv     = nullptr;
+    PFNGLPROGRAMUNIFORMMATRIX3X2DVPROC programUniformMatrix3x2dv = nullptr;
+    PFNGLPROGRAMUNIFORMMATRIX3X2FVPROC programUniformMatrix3x2fv = nullptr;
+    PFNGLPROGRAMUNIFORMMATRIX3X4DVPROC programUniformMatrix3x4dv = nullptr;
+    PFNGLPROGRAMUNIFORMMATRIX3X4FVPROC programUniformMatrix3x4fv = nullptr;
+    PFNGLPROGRAMUNIFORMMATRIX4DVPROC programUniformMatrix4dv     = nullptr;
+    PFNGLPROGRAMUNIFORMMATRIX4FVPROC programUniformMatrix4fv     = nullptr;
+    PFNGLPROGRAMUNIFORMMATRIX4X2DVPROC programUniformMatrix4x2dv = nullptr;
+    PFNGLPROGRAMUNIFORMMATRIX4X2FVPROC programUniformMatrix4x2fv = nullptr;
+    PFNGLPROGRAMUNIFORMMATRIX4X3DVPROC programUniformMatrix4x3dv = nullptr;
+    PFNGLPROGRAMUNIFORMMATRIX4X3FVPROC programUniformMatrix4x3fv = nullptr;
+    PFNGLRELEASESHADERCOMPILERPROC releaseShaderCompiler         = nullptr;
+    PFNGLSCISSORARRAYVPROC scissorArrayv                         = nullptr;
+    PFNGLSCISSORINDEXEDPROC scissorIndexed                       = nullptr;
+    PFNGLSCISSORINDEXEDVPROC scissorIndexedv                     = nullptr;
+    PFNGLSHADERBINARYPROC shaderBinary                           = nullptr;
+    PFNGLUSEPROGRAMSTAGESPROC useProgramStages                   = nullptr;
+    PFNGLVALIDATEPROGRAMPIPELINEPROC validateProgramPipeline     = nullptr;
+    PFNGLVERTEXATTRIBL1DPROC vertexAttribL1d                     = nullptr;
+    PFNGLVERTEXATTRIBL1DVPROC vertexAttribL1dv                   = nullptr;
+    PFNGLVERTEXATTRIBL2DPROC vertexAttribL2d                     = nullptr;
+    PFNGLVERTEXATTRIBL2DVPROC vertexAttribL2dv                   = nullptr;
+    PFNGLVERTEXATTRIBL3DPROC vertexAttribL3d                     = nullptr;
+    PFNGLVERTEXATTRIBL3DVPROC vertexAttribL3dv                   = nullptr;
+    PFNGLVERTEXATTRIBL4DPROC vertexAttribL4d                     = nullptr;
+    PFNGLVERTEXATTRIBL4DVPROC vertexAttribL4dv                   = nullptr;
+    PFNGLVERTEXATTRIBLPOINTERPROC vertexAttribLPointer           = nullptr;
+    PFNGLVIEWPORTARRAYVPROC viewportArrayv                       = nullptr;
+    PFNGLVIEWPORTINDEXEDFPROC viewportIndexedf                   = nullptr;
+    PFNGLVIEWPORTINDEXEDFVPROC viewportIndexedfv                 = nullptr;
+
+    // 4.2
+    PFNGLBINDIMAGETEXTUREPROC bindImageTexture                                   = nullptr;
+    PFNGLDRAWARRAYSINSTANCEDBASEINSTANCEPROC drawArraysInstancedBaseInstance     = nullptr;
+    PFNGLDRAWELEMENTSINSTANCEDBASEINSTANCEPROC drawElementsInstancedBaseInstance = nullptr;
+    PFNGLDRAWELEMENTSINSTANCEDBASEVERTEXBASEINSTANCEPROC
+        drawElementsInstancedBaseVertexBaseInstance                                    = nullptr;
+    PFNGLDRAWTRANSFORMFEEDBACKINSTANCEDPROC drawTransformFeedbackInstanced             = nullptr;
+    PFNGLDRAWTRANSFORMFEEDBACKSTREAMINSTANCEDPROC drawTransformFeedbackStreamInstanced = nullptr;
+    PFNGLGETACTIVEATOMICCOUNTERBUFFERIVPROC getActiveAtomicCounterBufferiv             = nullptr;
+    PFNGLGETINTERNALFORMATIVPROC getInternalformativ                                   = nullptr;
+    PFNGLMEMORYBARRIERPROC memoryBarrier                                               = nullptr;
+    PFNGLTEXSTORAGE1DPROC texStorage1D                                                 = nullptr;
+    PFNGLTEXSTORAGE2DPROC texStorage2D                                                 = nullptr;
+    PFNGLTEXSTORAGE3DPROC texStorage3D                                                 = nullptr;
+
+    // 4.3
+    PFNGLBINDVERTEXBUFFERPROC bindVertexBuffer                               = nullptr;
+    PFNGLCLEARBUFFERDATAPROC clearBufferData                                 = nullptr;
+    PFNGLCLEARBUFFERSUBDATAPROC clearBufferSubData                           = nullptr;
+    PFNGLCOPYIMAGESUBDATAPROC copyImageSubData                               = nullptr;
+    PFNGLCOVERAGEMODULATIONNVPROC coverageModulationNV                       = nullptr;
+    PFNGLDEBUGMESSAGECALLBACKPROC debugMessageCallback                       = nullptr;
+    PFNGLDEBUGMESSAGECONTROLPROC debugMessageControl                         = nullptr;
+    PFNGLDEBUGMESSAGEINSERTPROC debugMessageInsert                           = nullptr;
+    PFNGLDISPATCHCOMPUTEPROC dispatchCompute                                 = nullptr;
+    PFNGLDISPATCHCOMPUTEINDIRECTPROC dispatchComputeIndirect                 = nullptr;
+    PFNGLFRAMEBUFFERPARAMETERIPROC framebufferParameteri                     = nullptr;
+    PFNGLGETDEBUGMESSAGELOGPROC getDebugMessageLog                           = nullptr;
+    PFNGLGETFRAMEBUFFERPARAMETERIVPROC getFramebufferParameteriv             = nullptr;
+    PFNGLGETINTERNALFORMATI64VPROC getInternalformati64v                     = nullptr;
+    PFNGLGETOBJECTLABELPROC getObjectLabel                                   = nullptr;
+    PFNGLGETOBJECTPTRLABELPROC getObjectPtrLabel                             = nullptr;
+    PFNGLGETPOINTERVPROC getPointerv                                         = nullptr;
+    PFNGLGETPROGRAMINTERFACEIVPROC getProgramInterfaceiv                     = nullptr;
+    PFNGLGETPROGRAMRESOURCEINDEXPROC getProgramResourceIndex                 = nullptr;
+    PFNGLGETPROGRAMRESOURCELOCATIONPROC getProgramResourceLocation           = nullptr;
+    PFNGLGETPROGRAMRESOURCELOCATIONINDEXPROC getProgramResourceLocationIndex = nullptr;
+    PFNGLGETPROGRAMRESOURCENAMEPROC getProgramResourceName                   = nullptr;
+    PFNGLGETPROGRAMRESOURCEIVPROC getProgramResourceiv                       = nullptr;
+    PFNGLINVALIDATEBUFFERDATAPROC invalidateBufferData                       = nullptr;
+    PFNGLINVALIDATEBUFFERSUBDATAPROC invalidateBufferSubData                 = nullptr;
+    PFNGLINVALIDATEFRAMEBUFFERPROC invalidateFramebuffer                     = nullptr;
+    PFNGLINVALIDATESUBFRAMEBUFFERPROC invalidateSubFramebuffer               = nullptr;
+    PFNGLINVALIDATETEXIMAGEPROC invalidateTexImage                           = nullptr;
+    PFNGLINVALIDATETEXSUBIMAGEPROC invalidateTexSubImage                     = nullptr;
+    PFNGLMULTIDRAWARRAYSINDIRECTPROC multiDrawArraysIndirect                 = nullptr;
+    PFNGLMULTIDRAWELEMENTSINDIRECTPROC multiDrawElementsIndirect             = nullptr;
+    PFNGLOBJECTLABELPROC objectLabel                                         = nullptr;
+    PFNGLOBJECTPTRLABELPROC objectPtrLabel                                   = nullptr;
+    PFNGLPOPDEBUGGROUPPROC popDebugGroup                                     = nullptr;
+    PFNGLPUSHDEBUGGROUPPROC pushDebugGroup                                   = nullptr;
+    PFNGLSHADERSTORAGEBLOCKBINDINGPROC shaderStorageBlockBinding             = nullptr;
+    PFNGLTEXBUFFERRANGEPROC texBufferRange                                   = nullptr;
+    PFNGLTEXSTORAGE2DMULTISAMPLEPROC texStorage2DMultisample                 = nullptr;
+    PFNGLTEXSTORAGE3DMULTISAMPLEPROC texStorage3DMultisample                 = nullptr;
+    PFNGLTEXTUREVIEWPROC textureView                                         = nullptr;
+    PFNGLVERTEXATTRIBBINDINGPROC vertexAttribBinding                         = nullptr;
+    PFNGLVERTEXATTRIBFORMATPROC vertexAttribFormat                           = nullptr;
+    PFNGLVERTEXATTRIBIFORMATPROC vertexAttribIFormat                         = nullptr;
+    PFNGLVERTEXATTRIBLFORMATPROC vertexAttribLFormat                         = nullptr;
+    PFNGLVERTEXBINDINGDIVISORPROC vertexBindingDivisor                       = nullptr;
+
+    // 4.4
+    PFNGLBINDBUFFERSBASEPROC bindBuffersBase     = nullptr;
+    PFNGLBINDBUFFERSRANGEPROC bindBuffersRange   = nullptr;
+    PFNGLBINDIMAGETEXTURESPROC bindImageTextures = nullptr;
+    PFNGLBINDSAMPLERSPROC bindSamplers           = nullptr;
+    PFNGLBINDTEXTURESPROC bindTextures           = nullptr;
+    PFNGLBINDVERTEXBUFFERSPROC bindVertexBuffers = nullptr;
+    PFNGLBUFFERSTORAGEPROC bufferStorage         = nullptr;
+    PFNGLCLEARTEXIMAGEPROC clearTexImage         = nullptr;
+    PFNGLCLEARTEXSUBIMAGEPROC clearTexSubImage   = nullptr;
+
+    // 4.5
+    PFNGLBINDTEXTUREUNITPROC bindTextureUnit                           = nullptr;
+    PFNGLBLITNAMEDFRAMEBUFFERPROC blitNamedFramebuffer                 = nullptr;
+    PFNGLCHECKNAMEDFRAMEBUFFERSTATUSPROC checkNamedFramebufferStatus   = nullptr;
+    PFNGLCLEARNAMEDBUFFERDATAPROC clearNamedBufferData                 = nullptr;
+    PFNGLCLEARNAMEDBUFFERSUBDATAPROC clearNamedBufferSubData           = nullptr;
+    PFNGLCLEARNAMEDFRAMEBUFFERFIPROC clearNamedFramebufferfi           = nullptr;
+    PFNGLCLEARNAMEDFRAMEBUFFERFVPROC clearNamedFramebufferfv           = nullptr;
+    PFNGLCLEARNAMEDFRAMEBUFFERIVPROC clearNamedFramebufferiv           = nullptr;
+    PFNGLCLEARNAMEDFRAMEBUFFERUIVPROC clearNamedFramebufferuiv         = nullptr;
+    PFNGLCLIPCONTROLPROC clipControl                                   = nullptr;
+    PFNGLCOMPRESSEDTEXTURESUBIMAGE1DPROC compressedTextureSubImage1D   = nullptr;
+    PFNGLCOMPRESSEDTEXTURESUBIMAGE2DPROC compressedTextureSubImage2D   = nullptr;
+    PFNGLCOMPRESSEDTEXTURESUBIMAGE3DPROC compressedTextureSubImage3D   = nullptr;
+    PFNGLCOPYNAMEDBUFFERSUBDATAPROC copyNamedBufferSubData             = nullptr;
+    PFNGLCOPYTEXTURESUBIMAGE1DPROC copyTextureSubImage1D               = nullptr;
+    PFNGLCOPYTEXTURESUBIMAGE2DPROC copyTextureSubImage2D               = nullptr;
+    PFNGLCOPYTEXTURESUBIMAGE3DPROC copyTextureSubImage3D               = nullptr;
+    PFNGLCREATEBUFFERSPROC createBuffers                               = nullptr;
+    PFNGLCREATEFRAMEBUFFERSPROC createFramebuffers                     = nullptr;
+    PFNGLCREATEPROGRAMPIPELINESPROC createProgramPipelines             = nullptr;
+    PFNGLCREATEQUERIESPROC createQueries                               = nullptr;
+    PFNGLCREATERENDERBUFFERSPROC createRenderbuffers                   = nullptr;
+    PFNGLCREATESAMPLERSPROC createSamplers                             = nullptr;
+    PFNGLCREATETEXTURESPROC createTextures                             = nullptr;
+    PFNGLCREATETRANSFORMFEEDBACKSPROC createTransformFeedbacks         = nullptr;
+    PFNGLCREATEVERTEXARRAYSPROC createVertexArrays                     = nullptr;
+    PFNGLDISABLEVERTEXARRAYATTRIBPROC disableVertexArrayAttrib         = nullptr;
+    PFNGLENABLEVERTEXARRAYATTRIBPROC enableVertexArrayAttrib           = nullptr;
+    PFNGLFLUSHMAPPEDNAMEDBUFFERRANGEPROC flushMappedNamedBufferRange   = nullptr;
+    PFNGLGENERATETEXTUREMIPMAPPROC generateTextureMipmap               = nullptr;
+    PFNGLGETCOMPRESSEDTEXTUREIMAGEPROC getCompressedTextureImage       = nullptr;
+    PFNGLGETCOMPRESSEDTEXTURESUBIMAGEPROC getCompressedTextureSubImage = nullptr;
+    PFNGLGETGRAPHICSRESETSTATUSPROC getGraphicsResetStatus             = nullptr;
+    PFNGLGETNAMEDBUFFERPARAMETERI64VPROC getNamedBufferParameteri64v   = nullptr;
+    PFNGLGETNAMEDBUFFERPARAMETERIVPROC getNamedBufferParameteriv       = nullptr;
+    PFNGLGETNAMEDBUFFERPOINTERVPROC getNamedBufferPointerv             = nullptr;
+    PFNGLGETNAMEDBUFFERSUBDATAPROC getNamedBufferSubData               = nullptr;
+    PFNGLGETNAMEDFRAMEBUFFERATTACHMENTPARAMETERIVPROC getNamedFramebufferAttachmentParameteriv =
+        nullptr;
+    PFNGLGETNAMEDFRAMEBUFFERPARAMETERIVPROC getNamedFramebufferParameteriv           = nullptr;
+    PFNGLGETNAMEDRENDERBUFFERPARAMETERIVPROC getNamedRenderbufferParameteriv         = nullptr;
+    PFNGLGETQUERYBUFFEROBJECTI64VPROC getQueryBufferObjecti64v                       = nullptr;
+    PFNGLGETQUERYBUFFEROBJECTIVPROC getQueryBufferObjectiv                           = nullptr;
+    PFNGLGETQUERYBUFFEROBJECTUI64VPROC getQueryBufferObjectui64v                     = nullptr;
+    PFNGLGETQUERYBUFFEROBJECTUIVPROC getQueryBufferObjectuiv                         = nullptr;
+    PFNGLGETTEXTUREIMAGEPROC getTextureImage                                         = nullptr;
+    PFNGLGETTEXTURELEVELPARAMETERFVPROC getTextureLevelParameterfv                   = nullptr;
+    PFNGLGETTEXTURELEVELPARAMETERIVPROC getTextureLevelParameteriv                   = nullptr;
+    PFNGLGETTEXTUREPARAMETERIIVPROC getTextureParameterIiv                           = nullptr;
+    PFNGLGETTEXTUREPARAMETERIUIVPROC getTextureParameterIuiv                         = nullptr;
+    PFNGLGETTEXTUREPARAMETERFVPROC getTextureParameterfv                             = nullptr;
+    PFNGLGETTEXTUREPARAMETERIVPROC getTextureParameteriv                             = nullptr;
+    PFNGLGETTEXTURESUBIMAGEPROC getTextureSubImage                                   = nullptr;
+    PFNGLGETTRANSFORMFEEDBACKI64_VPROC getTransformFeedbacki64_v                     = nullptr;
+    PFNGLGETTRANSFORMFEEDBACKI_VPROC getTransformFeedbacki_v                         = nullptr;
+    PFNGLGETTRANSFORMFEEDBACKIVPROC getTransformFeedbackiv                           = nullptr;
+    PFNGLGETVERTEXARRAYINDEXED64IVPROC getVertexArrayIndexed64iv                     = nullptr;
+    PFNGLGETVERTEXARRAYINDEXEDIVPROC getVertexArrayIndexediv                         = nullptr;
+    PFNGLGETVERTEXARRAYIVPROC getVertexArrayiv                                       = nullptr;
+    PFNGLGETNCOMPRESSEDTEXIMAGEPROC getnCompressedTexImage                           = nullptr;
+    PFNGLGETNTEXIMAGEPROC getnTexImage                                               = nullptr;
+    PFNGLGETNUNIFORMDVPROC getnUniformdv                                             = nullptr;
+    PFNGLGETNUNIFORMFVPROC getnUniformfv                                             = nullptr;
+    PFNGLGETNUNIFORMIVPROC getnUniformiv                                             = nullptr;
+    PFNGLGETNUNIFORMUIVPROC getnUniformuiv                                           = nullptr;
+    PFNGLINVALIDATENAMEDFRAMEBUFFERDATAPROC invalidateNamedFramebufferData           = nullptr;
+    PFNGLINVALIDATENAMEDFRAMEBUFFERSUBDATAPROC invalidateNamedFramebufferSubData     = nullptr;
+    PFNGLMAPNAMEDBUFFERPROC mapNamedBuffer                                           = nullptr;
+    PFNGLMAPNAMEDBUFFERRANGEPROC mapNamedBufferRange                                 = nullptr;
+    PFNGLMEMORYBARRIERBYREGIONPROC memoryBarrierByRegion                             = nullptr;
+    PFNGLNAMEDBUFFERDATAPROC namedBufferData                                         = nullptr;
+    PFNGLNAMEDBUFFERSTORAGEPROC namedBufferStorage                                   = nullptr;
+    PFNGLNAMEDBUFFERSUBDATAPROC namedBufferSubData                                   = nullptr;
+    PFNGLNAMEDFRAMEBUFFERDRAWBUFFERPROC namedFramebufferDrawBuffer                   = nullptr;
+    PFNGLNAMEDFRAMEBUFFERDRAWBUFFERSPROC namedFramebufferDrawBuffers                 = nullptr;
+    PFNGLNAMEDFRAMEBUFFERPARAMETERIPROC namedFramebufferParameteri                   = nullptr;
+    PFNGLNAMEDFRAMEBUFFERREADBUFFERPROC namedFramebufferReadBuffer                   = nullptr;
+    PFNGLNAMEDFRAMEBUFFERRENDERBUFFERPROC namedFramebufferRenderbuffer               = nullptr;
+    PFNGLNAMEDFRAMEBUFFERTEXTUREPROC namedFramebufferTexture                         = nullptr;
+    PFNGLNAMEDFRAMEBUFFERTEXTURELAYERPROC namedFramebufferTextureLayer               = nullptr;
+    PFNGLNAMEDRENDERBUFFERSTORAGEPROC namedRenderbufferStorage                       = nullptr;
+    PFNGLNAMEDRENDERBUFFERSTORAGEMULTISAMPLEPROC namedRenderbufferStorageMultisample = nullptr;
+    PFNGLREADNPIXELSPROC readnPixels                                                 = nullptr;
+    PFNGLTEXTUREBARRIERPROC textureBarrier                                           = nullptr;
+    PFNGLTEXTUREBUFFERPROC textureBuffer                                             = nullptr;
+    PFNGLTEXTUREBUFFERRANGEPROC textureBufferRange                                   = nullptr;
+    PFNGLTEXTUREPARAMETERIIVPROC textureParameterIiv                                 = nullptr;
+    PFNGLTEXTUREPARAMETERIUIVPROC textureParameterIuiv                               = nullptr;
+    PFNGLTEXTUREPARAMETERFPROC textureParameterf                                     = nullptr;
+    PFNGLTEXTUREPARAMETERFVPROC textureParameterfv                                   = nullptr;
+    PFNGLTEXTUREPARAMETERIPROC textureParameteri                                     = nullptr;
+    PFNGLTEXTUREPARAMETERIVPROC textureParameteriv                                   = nullptr;
+    PFNGLTEXTURESTORAGE1DPROC textureStorage1D                                       = nullptr;
+    PFNGLTEXTURESTORAGE2DPROC textureStorage2D                                       = nullptr;
+    PFNGLTEXTURESTORAGE2DMULTISAMPLEPROC textureStorage2DMultisample                 = nullptr;
+    PFNGLTEXTURESTORAGE3DPROC textureStorage3D                                       = nullptr;
+    PFNGLTEXTURESTORAGE3DMULTISAMPLEPROC textureStorage3DMultisample                 = nullptr;
+    PFNGLTEXTURESUBIMAGE1DPROC textureSubImage1D                                     = nullptr;
+    PFNGLTEXTURESUBIMAGE2DPROC textureSubImage2D                                     = nullptr;
+    PFNGLTEXTURESUBIMAGE3DPROC textureSubImage3D                                     = nullptr;
+    PFNGLTRANSFORMFEEDBACKBUFFERBASEPROC transformFeedbackBufferBase                 = nullptr;
+    PFNGLTRANSFORMFEEDBACKBUFFERRANGEPROC transformFeedbackBufferRange               = nullptr;
+    PFNGLUNMAPNAMEDBUFFERPROC unmapNamedBuffer                                       = nullptr;
+    PFNGLVERTEXARRAYATTRIBBINDINGPROC vertexArrayAttribBinding                       = nullptr;
+    PFNGLVERTEXARRAYATTRIBFORMATPROC vertexArrayAttribFormat                         = nullptr;
+    PFNGLVERTEXARRAYATTRIBIFORMATPROC vertexArrayAttribIFormat                       = nullptr;
+    PFNGLVERTEXARRAYATTRIBLFORMATPROC vertexArrayAttribLFormat                       = nullptr;
+    PFNGLVERTEXARRAYBINDINGDIVISORPROC vertexArrayBindingDivisor                     = nullptr;
+    PFNGLVERTEXARRAYELEMENTBUFFERPROC vertexArrayElementBuffer                       = nullptr;
+    PFNGLVERTEXARRAYVERTEXBUFFERPROC vertexArrayVertexBuffer                         = nullptr;
+    PFNGLVERTEXARRAYVERTEXBUFFERSPROC vertexArrayVertexBuffers                       = nullptr;
+
+    // ES 3.2
+    PFNGLBLENDBARRIERPROC blendBarrier                 = nullptr;
+    PFNGLPRIMITIVEBOUNDINGBOXPROC primitiveBoundingBox = nullptr;
+
+    // GL_EXT_debug_marker
+    PFNGLINSERTEVENTMARKEREXTPROC insertEventMarkerEXT = nullptr;
+    PFNGLPOPGROUPMARKEREXTPROC popGroupMarkerEXT       = nullptr;
+    PFNGLPUSHGROUPMARKEREXTPROC pushGroupMarkerEXT     = nullptr;
+
+    // GL_EXT_discard_framebuffer
+    PFNGLDISCARDFRAMEBUFFEREXTPROC discardFramebufferEXT = nullptr;
+
+    // GL_NV_internalformat_sample_query
+    PFNGLGETINTERNALFORMATSAMPLEIVNVPROC getInternalformatSampleivNV = nullptr;
+
+    // GL_OES_EGL_image
+    PFNGLEGLIMAGETARGETRENDERBUFFERSTORAGEOESPROC eGLImageTargetRenderbufferStorageOES = nullptr;
+    PFNGLEGLIMAGETARGETTEXTURE2DOESPROC eGLImageTargetTexture2DOES                     = nullptr;
+
+    // NV_path_rendering (originally written against 3.2 compatibility profile)
+    PFNGLCOVERFILLPATHINSTANCEDNVPROC coverFillPathInstancedNV                           = nullptr;
+    PFNGLCOVERFILLPATHNVPROC coverFillPathNV                                             = nullptr;
+    PFNGLCOVERSTROKEPATHINSTANCEDNVPROC coverStrokePathInstancedNV                       = nullptr;
+    PFNGLCOVERSTROKEPATHNVPROC coverStrokePathNV                                         = nullptr;
+    PFNGLDELETEPATHSNVPROC deletePathsNV                                                 = nullptr;
+    PFNGLGENPATHSNVPROC genPathsNV                                                       = nullptr;
+    PFNGLGETPATHPARAMETERFVNVPROC getPathParameterfvNV                                   = nullptr;
+    PFNGLGETPATHPARAMETERIVNVPROC getPathParameterivNV                                   = nullptr;
+    PFNGLISPATHNVPROC isPathNV                                                           = nullptr;
+    PFNGLMATRIXLOADFEXTPROC matrixLoadfEXT                                               = nullptr;
+    PFNGLPATHCOMMANDSNVPROC pathCommandsNV                                               = nullptr;
+    PFNGLPATHPARAMETERFNVPROC pathParameterfNV                                           = nullptr;
+    PFNGLPATHPARAMETERINVPROC pathParameteriNV                                           = nullptr;
+    PFNGLPATHSTENCILFUNCNVPROC pathStencilFuncNV                                         = nullptr;
+    PFNGLPROGRAMPATHFRAGMENTINPUTGENNVPROC programPathFragmentInputGenNV                 = nullptr;
+    PFNGLSTENCILFILLPATHINSTANCEDNVPROC stencilFillPathInstancedNV                       = nullptr;
+    PFNGLSTENCILFILLPATHNVPROC stencilFillPathNV                                         = nullptr;
+    PFNGLSTENCILSTROKEPATHINSTANCEDNVPROC stencilStrokePathInstancedNV                   = nullptr;
+    PFNGLSTENCILSTROKEPATHNVPROC stencilStrokePathNV                                     = nullptr;
+    PFNGLSTENCILTHENCOVERFILLPATHINSTANCEDNVPROC stencilThenCoverFillPathInstancedNV     = nullptr;
+    PFNGLSTENCILTHENCOVERFILLPATHNVPROC stencilThenCoverFillPathNV                       = nullptr;
+    PFNGLSTENCILTHENCOVERSTROKEPATHINSTANCEDNVPROC stencilThenCoverStrokePathInstancedNV = nullptr;
+    PFNGLSTENCILTHENCOVERSTROKEPATHNVPROC stencilThenCoverStrokePathNV                   = nullptr;
+
+    virtual ~DispatchTableGL() = default;
+
+  protected:
+    virtual void *loadProcAddress(const std::string &function) const = 0;
+
+    void initProcsDesktopGL(const gl::Version &version, const std::set<std::string> &extensions);
+    void initProcsGLES(const gl::Version &version, const std::set<std::string> &extensions);
+    void initProcsSharedExtensions(const std::set<std::string> &extensions);
+
+#if defined(ANGLE_ENABLE_OPENGL_NULL)
+    void initProcsDesktopGLNULL(const gl::Version &version,
+                                const std::set<std::string> &extensions);
+    void initProcsGLESNULL(const gl::Version &version, const std::set<std::string> &extensions);
+    void initProcsSharedExtensionsNULL(const std::set<std::string> &extensions);
+#endif  // defined(ANGLE_ENABLE_OPENGL_NULL)
+};
+
+}  // namespace rx
+
+#endif  // LIBGLESV2_RENDERER_GL_DISPATCH_TABLE_GL_AUTOGEN_H_
--- a/gfx/angle/src/libANGLE/renderer/gl/DisplayGL.cpp
+++ b/gfx/angle/src/libANGLE/renderer/gl/DisplayGL.cpp
@@ -58,17 +58,17 @@ ImageImpl *DisplayGL::createImage(const 
 }
 
 ContextImpl *DisplayGL::createContext(const gl::ContextState &state)
 {
     ASSERT(mRenderer != nullptr);
     return new ContextGL(state, mRenderer);
 }
 
-StreamProducerImpl *DisplayGL::createStreamProducerD3DTextureNV12(
+StreamProducerImpl *DisplayGL::createStreamProducerD3DTexture(
     egl::Stream::ConsumerType consumerType,
     const egl::AttributeMap &attribs)
 {
     UNIMPLEMENTED();
     return nullptr;
 }
 
 egl::Error DisplayGL::makeCurrent(egl::Surface *drawSurface, egl::Surface *readSurface, gl::Context *context)
@@ -104,14 +104,21 @@ egl::Error DisplayGL::makeCurrent(egl::S
 }
 
 gl::Version DisplayGL::getMaxSupportedESVersion() const
 {
     ASSERT(mRenderer != nullptr);
     return mRenderer->getMaxSupportedESVersion();
 }
 
+void DisplayGL::generateExtensions(egl::DisplayExtensions *outExtensions) const
+{
+    // Advertise robust resource initialization on all OpenGL backends for testing even though it is
+    // not fully implemented.
+    outExtensions->robustResourceInitialization = true;
+}
+
 egl::Error DisplayGL::makeCurrentSurfaceless(gl::Context *context)
 {
     UNIMPLEMENTED();
     return egl::NoError();
 }
 }
--- a/gfx/angle/src/libANGLE/renderer/gl/DisplayGL.h
+++ b/gfx/angle/src/libANGLE/renderer/gl/DisplayGL.h
@@ -32,27 +32,28 @@ class DisplayGL : public DisplayImpl
     void terminate() override;
 
     ImageImpl *createImage(const egl::ImageState &state,
                            EGLenum target,
                            const egl::AttributeMap &attribs) override;
 
     ContextImpl *createContext(const gl::ContextState &state) override;
 
-    StreamProducerImpl *createStreamProducerD3DTextureNV12(
-        egl::Stream::ConsumerType consumerType,
-        const egl::AttributeMap &attribs) override;
+    StreamProducerImpl *createStreamProducerD3DTexture(egl::Stream::ConsumerType consumerType,
+                                                       const egl::AttributeMap &attribs) override;
 
     egl::Error makeCurrent(egl::Surface *drawSurface, egl::Surface *readSurface, gl::Context *context) override;
 
     gl::Version getMaxSupportedESVersion() const override;
 
   protected:
     RendererGL *getRenderer() const { return mRenderer; };
 
+    void generateExtensions(egl::DisplayExtensions *outExtensions) const override;
+
   private:
     virtual const FunctionsGL *getFunctionsGL() const = 0;
     virtual egl::Error makeCurrentSurfaceless(gl::Context *context);
 
     RendererGL *mRenderer;
 
     egl::Surface *mCurrentDrawSurface;
 };
--- a/gfx/angle/src/libANGLE/renderer/gl/FramebufferGL.cpp
+++ b/gfx/angle/src/libANGLE/renderer/gl/FramebufferGL.cpp
@@ -10,16 +10,17 @@
 
 #include "common/bitset_utils.h"
 #include "common/debug.h"
 #include "libANGLE/Context.h"
 #include "libANGLE/FramebufferAttachment.h"
 #include "libANGLE/State.h"
 #include "libANGLE/angletypes.h"
 #include "libANGLE/formatutils.h"
+#include "libANGLE/queryconversions.h"
 #include "libANGLE/renderer/ContextImpl.h"
 #include "libANGLE/renderer/gl/BlitGL.h"
 #include "libANGLE/renderer/gl/ClearMultiviewGL.h"
 #include "libANGLE/renderer/gl/ContextGL.h"
 #include "libANGLE/renderer/gl/FunctionsGL.h"
 #include "libANGLE/renderer/gl/RenderbufferGL.h"
 #include "libANGLE/renderer/gl/StateManagerGL.h"
 #include "libANGLE/renderer/gl/TextureGL.h"
@@ -245,21 +246,21 @@ Error FramebufferGL::invalidate(const gl
 
     // Since this function is just a hint, only call a native function if it exists.
     if (mFunctions->invalidateFramebuffer)
     {
         mStateManager->bindFramebuffer(GL_FRAMEBUFFER, mFramebufferID);
         mFunctions->invalidateFramebuffer(GL_FRAMEBUFFER, static_cast<GLsizei>(count),
                                           finalAttachmentsPtr);
     }
-    else if (mFunctions->discardFramebuffer)
+    else if (mFunctions->discardFramebufferEXT)
     {
         mStateManager->bindFramebuffer(GL_FRAMEBUFFER, mFramebufferID);
-        mFunctions->discardFramebuffer(GL_FRAMEBUFFER, static_cast<GLsizei>(count),
-                                       finalAttachmentsPtr);
+        mFunctions->discardFramebufferEXT(GL_FRAMEBUFFER, static_cast<GLsizei>(count),
+                                          finalAttachmentsPtr);
     }
 
     return gl::NoError();
 }
 
 Error FramebufferGL::invalidateSub(const gl::Context *context,
                                    size_t count,
                                    const GLenum *attachments,
@@ -424,40 +425,41 @@ Error FramebufferGL::readPixels(const gl
     const gl::Rectangle fbRect(0, 0, fbSize.width, fbSize.height);
     gl::Rectangle area;
     if (!ClipRectangle(origArea, fbRect, &area))
     {
         // nothing to read
         return gl::NoError();
     }
 
-    PixelPackState packState;
-    packState.copyFrom(context, context->getGLState().getPackState());
+    PixelPackState packState     = context->getGLState().getPackState();
+    const gl::Buffer *packBuffer =
+        context->getGLState().getTargetBuffer(gl::BufferBinding::PixelPack);
 
     nativegl::ReadPixelsFormat readPixelsFormat =
         nativegl::GetReadPixelsFormat(mFunctions, mWorkarounds, format, type);
     GLenum readFormat = readPixelsFormat.format;
     GLenum readType   = readPixelsFormat.type;
 
     mStateManager->bindFramebuffer(GL_READ_FRAMEBUFFER, mFramebufferID);
 
     bool useOverlappingRowsWorkaround = mWorkarounds.packOverlappingRowsSeparatelyPackBuffer &&
-                                        packState.pixelBuffer.get() && packState.rowLength != 0 &&
+                                        packBuffer && packState.rowLength != 0 &&
                                         packState.rowLength < area.width;
 
     GLubyte *pixels = reinterpret_cast<GLubyte *>(ptrOrOffset);
     int leftClip    = area.x - origArea.x;
     int topClip     = area.y - origArea.y;
     if (leftClip || topClip)
     {
         // Adjust destination to match portion clipped off left and/or top.
         const gl::InternalFormat &glFormat = gl::GetInternalFormatInfo(readFormat, readType);
 
         GLuint rowBytes = 0;
-        ANGLE_TRY_RESULT(glFormat.computeRowPitch(origArea.width, packState.alignment,
+        ANGLE_TRY_RESULT(glFormat.computeRowPitch(readType, origArea.width, packState.alignment,
                                                   packState.rowLength),
                          rowBytes);
         pixels += leftClip * glFormat.pixelBytes + topClip * rowBytes;
     }
 
     if (packState.rowLength == 0 && area.width != origArea.width)
     {
         // No rowLength was specified so it will derive from read width, but clipping changed the
@@ -474,33 +476,32 @@ Error FramebufferGL::readPixels(const gl
     {
         retVal = readPixelsRowByRow(context, area, readFormat, readType, packState, pixels);
     }
     else
     {
         gl::ErrorOrResult<bool> useLastRowPaddingWorkaround = false;
         if (mWorkarounds.packLastRowSeparatelyForPaddingInclusion)
         {
-            useLastRowPaddingWorkaround =
-                ShouldApplyLastRowPaddingWorkaround(gl::Extents(area.width, area.height, 1),
-                                                    packState, readFormat, readType, false, pixels);
+            useLastRowPaddingWorkaround = ShouldApplyLastRowPaddingWorkaround(
+                gl::Extents(area.width, area.height, 1), packState, packBuffer, readFormat,
+                readType, false, pixels);
         }
 
         if (useLastRowPaddingWorkaround.isError())
         {
             retVal = useLastRowPaddingWorkaround.getError();
         }
         else
         {
             retVal = readPixelsAllAtOnce(context, area, readFormat, readType, packState, pixels,
                                          useLastRowPaddingWorkaround.getResult());
         }
     }
 
-    packState.pixelBuffer.set(context, nullptr);
     return retVal;
 }
 
 Error FramebufferGL::blit(const gl::Context *context,
                           const gl::Rectangle &sourceArea,
                           const gl::Rectangle &destArea,
                           GLbitfield mask,
                           GLenum filter)
@@ -589,17 +590,17 @@ Error FramebufferGL::blit(const gl::Cont
 
 gl::Error FramebufferGL::getSamplePosition(size_t index, GLfloat *xy) const
 {
     mStateManager->bindFramebuffer(GL_FRAMEBUFFER, mFramebufferID);
     mFunctions->getMultisamplefv(GL_SAMPLE_POSITION, static_cast<GLuint>(index), xy);
     return gl::NoError();
 }
 
-bool FramebufferGL::checkStatus() const
+bool FramebufferGL::checkStatus(const gl::Context *context) const
 {
     mStateManager->bindFramebuffer(GL_FRAMEBUFFER, mFramebufferID);
     GLenum status = mFunctions->checkFramebufferStatus(GL_FRAMEBUFFER);
     if (status != GL_FRAMEBUFFER_COMPLETE)
     {
         WARN() << "GL framebuffer returned incomplete.";
     }
     return (status == GL_FRAMEBUFFER_COMPLETE);
@@ -661,19 +662,19 @@ void FramebufferGL::syncState(const gl::
                 mFunctions->framebufferParameteri(GL_FRAMEBUFFER, GL_FRAMEBUFFER_DEFAULT_HEIGHT,
                                                   mState.getDefaultHeight());
                 break;
             case Framebuffer::DIRTY_BIT_DEFAULT_SAMPLES:
                 mFunctions->framebufferParameteri(GL_FRAMEBUFFER, GL_FRAMEBUFFER_DEFAULT_SAMPLES,
                                                   mState.getDefaultSamples());
                 break;
             case Framebuffer::DIRTY_BIT_DEFAULT_FIXED_SAMPLE_LOCATIONS:
-                mFunctions->framebufferParameteri(GL_FRAMEBUFFER,
-                                                  GL_FRAMEBUFFER_DEFAULT_FIXED_SAMPLE_LOCATIONS,
-                                                  mState.getDefaultFixedSampleLocations());
+                mFunctions->framebufferParameteri(
+                    GL_FRAMEBUFFER, GL_FRAMEBUFFER_DEFAULT_FIXED_SAMPLE_LOCATIONS,
+                    gl::ConvertToGLBoolean(mState.getDefaultFixedSampleLocations()));
                 break;
             default:
             {
                 ASSERT(Framebuffer::DIRTY_BIT_COLOR_ATTACHMENT_0 == 0 &&
                        dirtyBit < Framebuffer::DIRTY_BIT_COLOR_ATTACHMENT_MAX);
                 size_t index =
                     static_cast<size_t>(dirtyBit - Framebuffer::DIRTY_BIT_COLOR_ATTACHMENT_0);
                 const FramebufferAttachment *newAttachment = mState.getColorAttachment(index);
@@ -832,29 +833,27 @@ bool FramebufferGL::modifyInvalidateAtta
 
 gl::Error FramebufferGL::readPixelsRowByRow(const gl::Context *context,
                                             const gl::Rectangle &area,
                                             GLenum format,
                                             GLenum type,
                                             const gl::PixelPackState &pack,
                                             GLubyte *pixels) const
 {
+    const gl::InternalFormat &glFormat = gl::GetInternalFormatInfo(format, type);
 
-    const gl::InternalFormat &glFormat = gl::GetInternalFormatInfo(format, type);
     GLuint rowBytes = 0;
-    ANGLE_TRY_RESULT(glFormat.computeRowPitch(area.width, pack.alignment, pack.rowLength),
+    ANGLE_TRY_RESULT(glFormat.computeRowPitch(type, area.width, pack.alignment, pack.rowLength),
                      rowBytes);
     GLuint skipBytes = 0;
     ANGLE_TRY_RESULT(glFormat.computeSkipBytes(rowBytes, 0, pack, false), skipBytes);
 
     gl::PixelPackState directPack;
-    directPack.pixelBuffer.set(context, pack.pixelBuffer.get());
     directPack.alignment   = 1;
     mStateManager->setPixelPackState(directPack);
-    directPack.pixelBuffer.set(context, nullptr);
 
     pixels += skipBytes;
     for (GLint y = area.y; y < area.y + area.height; ++y)
     {
         mFunctions->readPixels(area.x, y, area.width, 1, format, type, pixels);
         pixels += rowBytes;
     }
 
@@ -876,26 +875,24 @@ gl::Error FramebufferGL::readPixelsAllAt
         mFunctions->readPixels(area.x, area.y, area.width, height, format, type, pixels);
     }
 
     if (readLastRowSeparately)
     {
         const gl::InternalFormat &glFormat = gl::GetInternalFormatInfo(format, type);
 
         GLuint rowBytes = 0;
-        ANGLE_TRY_RESULT(glFormat.computeRowPitch(area.width, pack.alignment, pack.rowLength),
+        ANGLE_TRY_RESULT(glFormat.computeRowPitch(type, area.width, pack.alignment, pack.rowLength),
                          rowBytes);
         GLuint skipBytes = 0;
         ANGLE_TRY_RESULT(glFormat.computeSkipBytes(rowBytes, 0, pack, false), skipBytes);
 
         gl::PixelPackState directPack;
-        directPack.pixelBuffer.set(context, pack.pixelBuffer.get());
         directPack.alignment = 1;
         mStateManager->setPixelPackState(directPack);
-        directPack.pixelBuffer.set(context, nullptr);
 
         pixels += skipBytes + (area.height - 1) * rowBytes;
         mFunctions->readPixels(area.x, area.y + area.height - 1, area.width, 1, format, type,
                                pixels);
     }
 
     return gl::NoError();
 }
--- a/gfx/angle/src/libANGLE/renderer/gl/FramebufferGL.h
+++ b/gfx/angle/src/libANGLE/renderer/gl/FramebufferGL.h
@@ -82,17 +82,17 @@ class FramebufferGL : public Framebuffer
     gl::Error blit(const gl::Context *context,
                    const gl::Rectangle &sourceArea,
                    const gl::Rectangle &destArea,
                    GLbitfield mask,
                    GLenum filter) override;
 
     gl::Error getSamplePosition(size_t index, GLfloat *xy) const override;
 
-    bool checkStatus() const override;
+    bool checkStatus(const gl::Context *context) const override;
 
     void syncState(const gl::Context *context,
                    const gl::Framebuffer::DirtyBits &dirtyBits) override;
 
     GLuint getFramebufferID() const;
     bool isDefault() const;
 
     void maskOutInactiveOutputDrawBuffers(gl::DrawBufferMask maxSet);
--- a/gfx/angle/src/libANGLE/renderer/gl/FunctionsGL.cpp
+++ b/gfx/angle/src/libANGLE/renderer/gl/FunctionsGL.cpp
@@ -6,16 +6,17 @@
 
 // FunctionsGL.cpp: Implements the FuntionsGL class to contain loaded GL functions
 
 #include "libANGLE/renderer/gl/FunctionsGL.h"
 
 #include <algorithm>
 
 #include "common/string_utils.h"
+#include "libANGLE/AttributeMap.h"
 #include "libANGLE/renderer/gl/renderergl_utils.h"
 
 namespace rx
 {
 
 static void GetGLVersion(PFNGLGETSTRINGPROC getStringFunction, gl::Version *outVersion, StandardGL *outStandard)
 {
     const std::string version = reinterpret_cast<const char*>(getStringFunction(GL_VERSION));
@@ -50,2264 +51,155 @@ static std::vector<std::string> GetIndex
     for (GLint i = 0; i < numExtensions; i++)
     {
         result.push_back(reinterpret_cast<const char*>(getStringIFunction(GL_EXTENSIONS, i)));
     }
 
     return result;
 }
 
-static void AssignGLExtensionEntryPoint(const std::vector<std::string> &extensions,
-                                        const char *requiredExtensionString,
-                                        void *function,
-                                        void **outFunction)
+#if defined(ANGLE_ENABLE_OPENGL_NULL)
+static GLenum INTERNAL_GL_APIENTRY DummyCheckFramebufferStatus(GLenum)
 {
-    std::vector<std::string> requiredExtensions;
-    angle::SplitStringAlongWhitespace(requiredExtensionString, &requiredExtensions);
-    for (const std::string& requiredExtension : requiredExtensions)
-    {
-        if (std::find(extensions.begin(), extensions.end(), requiredExtension) == extensions.end())
-        {
-            return;
-        }
-    }
-
-    *outFunction = function;
+    return GL_FRAMEBUFFER_COMPLETE;
 }
 
-#define ASSIGN_WITH_EXT(EXT, NAME, FP)                                  \
-    AssignGLExtensionEntryPoint(extensions, EXT, loadProcAddress(NAME), \
-                                reinterpret_cast<void **>(&FP))
+static void INTERNAL_GL_APIENTRY DummyGetProgramiv(GLuint program, GLenum pname, GLint *params)
+{
+    switch (pname)
+    {
+        case GL_LINK_STATUS:
+            *params = GL_TRUE;
+            break;
+        case GL_VALIDATE_STATUS:
+            *params = GL_TRUE;
+            break;
+        default:
+            break;
+    }
+}
+
+static void INTERNAL_GL_APIENTRY DummyGetShaderiv(GLuint program, GLenum pname, GLint *params)
+{
+    switch (pname)
+    {
+        case GL_COMPILE_STATUS:
+            *params = GL_TRUE;
+            break;
+        default:
+            break;
+    }
+}
+#endif  // defined(ANGLE_ENABLE_OPENGL_NULL)
+
 #define ASSIGN(NAME, FP) *reinterpret_cast<void **>(&FP) = loadProcAddress(NAME)
 
-FunctionsGL::FunctionsGL()
-    : version(),
-      standard(),
-      extensions(),
-
-      blendFunc(nullptr),
-      clear(nullptr),
-      clearColor(nullptr),
-      clearDepth(nullptr),
-      clearStencil(nullptr),
-      colorMask(nullptr),
-      cullFace(nullptr),
-      depthFunc(nullptr),
-      depthMask(nullptr),
-      depthRange(nullptr),
-      disable(nullptr),
-      drawBuffer(nullptr),
-      enable(nullptr),
-      finish(nullptr),
-      flush(nullptr),
-      frontFace(nullptr),
-      getBooleanv(nullptr),
-      getDoublev(nullptr),
-      getError(nullptr),
-      getFloatv(nullptr),
-      getIntegerv(nullptr),
-      getString(nullptr),
-      getTexImage(nullptr),
-      getTexLevelParameterfv(nullptr),
-      getTexLevelParameteriv(nullptr),
-      getTexParameterfv(nullptr),
-      getTexParameteriv(nullptr),
-      hint(nullptr),
-      isEnabled(nullptr),
-      lineWidth(nullptr),
-      logicOp(nullptr),
-      pixelStoref(nullptr),
-      pixelStorei(nullptr),
-      pointSize(nullptr),
-      polygonMode(nullptr),
-      readBuffer(nullptr),
-      readPixels(nullptr),
-      scissor(nullptr),
-      stencilFunc(nullptr),
-      stencilMask(nullptr),
-      stencilOp(nullptr),
-      texImage1D(nullptr),
-      texImage2D(nullptr),
-      texParameterf(nullptr),
-      texParameterfv(nullptr),
-      texParameteri(nullptr),
-      texParameteriv(nullptr),
-      viewport(nullptr),
-
-      bindTexture(nullptr),
-      copyTexImage1D(nullptr),
-      copyTexImage2D(nullptr),
-      copyTexSubImage1D(nullptr),
-      copyTexSubImage2D(nullptr),
-      deleteTextures(nullptr),
-      drawArrays(nullptr),
-      drawElements(nullptr),
-      genTextures(nullptr),
-      isTexture(nullptr),
-      polygonOffset(nullptr),
-      texSubImage1D(nullptr),
-      texSubImage2D(nullptr),
-
-      blendColor(nullptr),
-      blendEquation(nullptr),
-      copyTexSubImage3D(nullptr),
-      drawRangeElements(nullptr),
-      texImage3D(nullptr),
-      texSubImage3D(nullptr),
-
-      deleteFencesNV(nullptr),
-      genFencesNV(nullptr),
-      isFenceNV(nullptr),
-      testFenceNV(nullptr),
-      getFenceivNV(nullptr),
-      finishFenceNV(nullptr),
-      setFenceNV(nullptr),
-
-      activeTexture(nullptr),
-      compressedTexImage1D(nullptr),
-      compressedTexImage2D(nullptr),
-      compressedTexImage3D(nullptr),
-      compressedTexSubImage1D(nullptr),
-      compressedTexSubImage2D(nullptr),
-      compressedTexSubImage3D(nullptr),
-      getCompressedTexImage(nullptr),
-      sampleCoverage(nullptr),
-
-      blendFuncSeparate(nullptr),
-      multiDrawArrays(nullptr),
-      multiDrawElements(nullptr),
-      pointParameterf(nullptr),
-      pointParameterfv(nullptr),
-      pointParameteri(nullptr),
-      pointParameteriv(nullptr),
-
-      beginQuery(nullptr),
-      bindBuffer(nullptr),
-      bufferData(nullptr),
-      bufferSubData(nullptr),
-      deleteBuffers(nullptr),
-      deleteQueries(nullptr),
-      endQuery(nullptr),
-      genBuffers(nullptr),
-      genQueries(nullptr),
-      getBufferParameteriv(nullptr),
-      getBufferPointerv(nullptr),
-      getBufferSubData(nullptr),
-      getQueryObjectiv(nullptr),
-      getQueryObjectuiv(nullptr),
-      getQueryiv(nullptr),
-      isBuffer(nullptr),
-      isQuery(nullptr),
-      mapBuffer(nullptr),
-      unmapBuffer(nullptr),
-
-      attachShader(nullptr),
-      bindAttribLocation(nullptr),
-      blendEquationSeparate(nullptr),
-      compileShader(nullptr),
-      createProgram(nullptr),
-      createShader(nullptr),
-      deleteProgram(nullptr),
-      deleteShader(nullptr),
-      detachShader(nullptr),
-      disableVertexAttribArray(nullptr),
-      drawBuffers(nullptr),
-      enableVertexAttribArray(nullptr),
-      getActiveAttrib(nullptr),
-      getActiveUniform(nullptr),
-      getAttachedShaders(nullptr),
-      getAttribLocation(nullptr),
-      getProgramInfoLog(nullptr),
-      getProgramiv(nullptr),
-      getShaderInfoLog(nullptr),
-      getShaderSource(nullptr),
-      getShaderiv(nullptr),
-      getUniformLocation(nullptr),
-      getUniformfv(nullptr),
-      getUniformiv(nullptr),
-      getVertexAttribPointerv(nullptr),
-      getVertexAttribdv(nullptr),
-      getVertexAttribfv(nullptr),
-      getVertexAttribiv(nullptr),
-      isProgram(nullptr),
-      isShader(nullptr),
-      linkProgram(nullptr),
-      shaderSource(nullptr),
-      stencilFuncSeparate(nullptr),
-      stencilMaskSeparate(nullptr),
-      stencilOpSeparate(nullptr),
-      uniform1f(nullptr),
-      uniform1fv(nullptr),
-      uniform1i(nullptr),
-      uniform1iv(nullptr),
-      uniform2f(nullptr),
-      uniform2fv(nullptr),
-      uniform2i(nullptr),
-      uniform2iv(nullptr),
-      uniform3f(nullptr),
-      uniform3fv(nullptr),
-      uniform3i(nullptr),
-      uniform3iv(nullptr),
-      uniform4f(nullptr),
-      uniform4fv(nullptr),
-      uniform4i(nullptr),
-      uniform4iv(nullptr),
-      uniformMatrix2fv(nullptr),
-      uniformMatrix3fv(nullptr),
-      uniformMatrix4fv(nullptr),
-      useProgram(nullptr),
-      validateProgram(nullptr),
-      vertexAttrib1d(nullptr),
-      vertexAttrib1dv(nullptr),
-      vertexAttrib1f(nullptr),
-      vertexAttrib1fv(nullptr),
-      vertexAttrib1s(nullptr),
-      vertexAttrib1sv(nullptr),
-      vertexAttrib2d(nullptr),
-      vertexAttrib2dv(nullptr),
-      vertexAttrib2f(nullptr),
-      vertexAttrib2fv(nullptr),
-      vertexAttrib2s(nullptr),
-      vertexAttrib2sv(nullptr),
-      vertexAttrib3d(nullptr),
-      vertexAttrib3dv(nullptr),
-      vertexAttrib3f(nullptr),
-      vertexAttrib3fv(nullptr),
-      vertexAttrib3s(nullptr),
-      vertexAttrib3sv(nullptr),
-      vertexAttrib4Nbv(nullptr),
-      vertexAttrib4Niv(nullptr),
-      vertexAttrib4Nsv(nullptr),
-      vertexAttrib4Nub(nullptr),
-      vertexAttrib4Nubv(nullptr),
-      vertexAttrib4Nuiv(nullptr),
-      vertexAttrib4Nusv(nullptr),
-      vertexAttrib4bv(nullptr),
-      vertexAttrib4d(nullptr),
-      vertexAttrib4dv(nullptr),
-      vertexAttrib4f(nullptr),
-      vertexAttrib4fv(nullptr),
-      vertexAttrib4iv(nullptr),
-      vertexAttrib4s(nullptr),
-      vertexAttrib4sv(nullptr),
-      vertexAttrib4ubv(nullptr),
-      vertexAttrib4uiv(nullptr),
-      vertexAttrib4usv(nullptr),
-      vertexAttribPointer(nullptr),
-
-      uniformMatrix2x3fv(nullptr),
-      uniformMatrix2x4fv(nullptr),
-      uniformMatrix3x2fv(nullptr),
-      uniformMatrix3x4fv(nullptr),
-      uniformMatrix4x2fv(nullptr),
-      uniformMatrix4x3fv(nullptr),
-
-      beginConditionalRender(nullptr),
-      beginTransformFeedback(nullptr),
-      bindBufferBase(nullptr),
-      bindBufferRange(nullptr),
-      bindFragDataLocation(nullptr),
-      bindFramebuffer(nullptr),
-      bindRenderbuffer(nullptr),
-      bindVertexArray(nullptr),
-      blitFramebuffer(nullptr),
-      checkFramebufferStatus(nullptr),
-      clampColor(nullptr),
-      clearBufferfi(nullptr),
-      clearBufferfv(nullptr),
-      clearBufferiv(nullptr),
-      clearBufferuiv(nullptr),
-      colorMaski(nullptr),
-      deleteFramebuffers(nullptr),
-      deleteRenderbuffers(nullptr),
-      deleteVertexArrays(nullptr),
-      disablei(nullptr),
-      enablei(nullptr),
-      endConditionalRender(nullptr),
-      endTransformFeedback(nullptr),
-      flushMappedBufferRange(nullptr),
-      framebufferRenderbuffer(nullptr),
-      framebufferTexture1D(nullptr),
-      framebufferTexture2D(nullptr),
-      framebufferTexture3D(nullptr),
-      framebufferTextureLayer(nullptr),
-      genFramebuffers(nullptr),
-      genRenderbuffers(nullptr),
-      genVertexArrays(nullptr),
-      generateMipmap(nullptr),
-      getBooleani_v(nullptr),
-      getFragDataLocation(nullptr),
-      getFramebufferAttachmentParameteriv(nullptr),
-      getIntegeri_v(nullptr),
-      getRenderbufferParameteriv(nullptr),
-      getStringi(nullptr),
-      getTexParameterIiv(nullptr),
-      getTexParameterIuiv(nullptr),
-      getTransformFeedbackVarying(nullptr),
-      getUniformuiv(nullptr),
-      getVertexAttribIiv(nullptr),
-      getVertexAttribIuiv(nullptr),
-      isEnabledi(nullptr),
-      isFramebuffer(nullptr),
-      isRenderbuffer(nullptr),
-      isVertexArray(nullptr),
-      mapBufferRange(nullptr),
-      renderbufferStorage(nullptr),
-      renderbufferStorageMultisample(nullptr),
-      texParameterIiv(nullptr),
-      texParameterIuiv(nullptr),
-      transformFeedbackVaryings(nullptr),
-      uniform1ui(nullptr),
-      uniform1uiv(nullptr),
-      uniform2ui(nullptr),
-      uniform2uiv(nullptr),
-      uniform3ui(nullptr),
-      uniform3uiv(nullptr),
-      uniform4ui(nullptr),
-      uniform4uiv(nullptr),
-      vertexAttribI1i(nullptr),
-      vertexAttribI1iv(nullptr),
-      vertexAttribI1ui(nullptr),
-      vertexAttribI1uiv(nullptr),
-      vertexAttribI2i(nullptr),
-      vertexAttribI2iv(nullptr),
-      vertexAttribI2ui(nullptr),
-      vertexAttribI2uiv(nullptr),
-      vertexAttribI3i(nullptr),
-      vertexAttribI3iv(nullptr),
-      vertexAttribI3ui(nullptr),
-      vertexAttribI3uiv(nullptr),
-      vertexAttribI4bv(nullptr),
-      vertexAttribI4i(nullptr),
-      vertexAttribI4iv(nullptr),
-      vertexAttribI4sv(nullptr),
-      vertexAttribI4ubv(nullptr),
-      vertexAttribI4ui(nullptr),
-      vertexAttribI4uiv(nullptr),
-      vertexAttribI4usv(nullptr),
-      vertexAttribIPointer(nullptr),
-
-      copyBufferSubData(nullptr),
-      drawArraysInstanced(nullptr),
-      drawElementsInstanced(nullptr),
-      getActiveUniformBlockName(nullptr),
-      getActiveUniformBlockiv(nullptr),
-      getActiveUniformName(nullptr),
-      getActiveUniformsiv(nullptr),
-      getUniformBlockIndex(nullptr),
-      getUniformIndices(nullptr),
-      primitiveRestartIndex(nullptr),
-      texBuffer(nullptr),
-      uniformBlockBinding(nullptr),
-
-      clientWaitSync(nullptr),
-      deleteSync(nullptr),
-      drawElementsBaseVertex(nullptr),
-      drawElementsInstancedBaseVertex(nullptr),
-      drawRangeElementsBaseVertex(nullptr),
-      fenceSync(nullptr),
-      framebufferTexture(nullptr),
-      getBufferParameteri64v(nullptr),
-      getInteger64i_v(nullptr),
-      getInteger64v(nullptr),
-      getMultisamplefv(nullptr),
-      getSynciv(nullptr),
-      isSync(nullptr),
-      multiDrawElementsBaseVertex(nullptr),
-      provokingVertex(nullptr),
-      sampleMaski(nullptr),
-      texImage2DMultisample(nullptr),
-      texImage3DMultisample(nullptr),
-      waitSync(nullptr),
-
-      matrixLoadEXT(nullptr),
-      genPathsNV(nullptr),
-      delPathsNV(nullptr),
-      pathCommandsNV(nullptr),
-      setPathParameterfNV(nullptr),
-      setPathParameteriNV(nullptr),
-      getPathParameterfNV(nullptr),
-      getPathParameteriNV(nullptr),
-      pathStencilFuncNV(nullptr),
-      stencilFillPathNV(nullptr),
-      stencilStrokePathNV(nullptr),
-      coverFillPathNV(nullptr),
-      coverStrokePathNV(nullptr),
-      stencilThenCoverFillPathNV(nullptr),
-      stencilThenCoverStrokePathNV(nullptr),
-      coverFillPathInstancedNV(nullptr),
-      coverStrokePathInstancedNV(nullptr),
-      stencilFillPathInstancedNV(nullptr),
-      stencilStrokePathInstancedNV(nullptr),
-      stencilThenCoverFillPathInstancedNV(nullptr),
-      stencilThenCoverStrokePathInstancedNV(nullptr),
-      programPathFragmentInputGenNV(nullptr),
-
-      bindFragDataLocationIndexed(nullptr),
-      bindSampler(nullptr),
-      deleteSamplers(nullptr),
-      genSamplers(nullptr),
-      getFragDataIndex(nullptr),
-      getQueryObjecti64v(nullptr),
-      getQueryObjectui64v(nullptr),
-      getSamplerParameterIiv(nullptr),
-      getSamplerParameterIuiv(nullptr),
-      getSamplerParameterfv(nullptr),
-      getSamplerParameteriv(nullptr),
-      isSampler(nullptr),
-      queryCounter(nullptr),
-      samplerParameterIiv(nullptr),
-      samplerParameterIuiv(nullptr),
-      samplerParameterf(nullptr),
-      samplerParameterfv(nullptr),
-      samplerParameteri(nullptr),
-      samplerParameteriv(nullptr),
-      vertexAttribDivisor(nullptr),
-      vertexAttribP1ui(nullptr),
-      vertexAttribP1uiv(nullptr),
-      vertexAttribP2ui(nullptr),
-      vertexAttribP2uiv(nullptr),
-      vertexAttribP3ui(nullptr),
-      vertexAttribP3uiv(nullptr),
-      vertexAttribP4ui(nullptr),
-      vertexAttribP4uiv(nullptr),
-
-      beginQueryIndexed(nullptr),
-      bindTransformFeedback(nullptr),
-      blendEquationSeparatei(nullptr),
-      blendEquationi(nullptr),
-      blendFuncSeparatei(nullptr),
-      blendFunci(nullptr),
-      deleteTransformFeedbacks(nullptr),
-      drawArraysIndirect(nullptr),
-      drawElementsIndirect(nullptr),
-      drawTransformFeedback(nullptr),
-      drawTransformFeedbackStream(nullptr),
-      endQueryIndexed(nullptr),
-      genTransformFeedbacks(nullptr),
-      getActiveSubroutineName(nullptr),
-      getActiveSubroutineUniformName(nullptr),
-      getActiveSubroutineUniformiv(nullptr),
-      getProgramStageiv(nullptr),
-      getQueryIndexediv(nullptr),
-      getSubroutineIndex(nullptr),
-      getSubroutineUniformLocation(nullptr),
-      getUniformSubroutineuiv(nullptr),
-      getUniformdv(nullptr),
-      isTransformFeedback(nullptr),
-      minSampleShading(nullptr),
-      patchParameterfv(nullptr),
-      patchParameteri(nullptr),
-      pauseTransformFeedback(nullptr),
-      resumeTransformFeedback(nullptr),
-      uniform1d(nullptr),
-      uniform1dv(nullptr),
-      uniform2d(nullptr),
-      uniform2dv(nullptr),
-      uniform3d(nullptr),
-      uniform3dv(nullptr),
-      uniform4d(nullptr),
-      uniform4dv(nullptr),
-      uniformMatrix2dv(nullptr),
-      uniformMatrix2x3dv(nullptr),
-      uniformMatrix2x4dv(nullptr),
-      uniformMatrix3dv(nullptr),
-      uniformMatrix3x2dv(nullptr),
-      uniformMatrix3x4dv(nullptr),
-      uniformMatrix4dv(nullptr),
-      uniformMatrix4x2dv(nullptr),
-      uniformMatrix4x3dv(nullptr),
-      uniformSubroutinesuiv(nullptr),
-
-      activeShaderProgram(nullptr),
-      bindProgramPipeline(nullptr),
-      clearDepthf(nullptr),
-      createShaderProgramv(nullptr),
-      deleteProgramPipelines(nullptr),
-      depthRangeArrayv(nullptr),
-      depthRangeIndexed(nullptr),
-      depthRangef(nullptr),
-      genProgramPipelines(nullptr),
-      getDoublei_v(nullptr),
-      getFloati_v(nullptr),
-      getProgramBinary(nullptr),
-      getProgramPipelineInfoLog(nullptr),
-      getProgramPipelineiv(nullptr),
-      getShaderPrecisionFormat(nullptr),
-      getVertexAttribLdv(nullptr),
-      isProgramPipeline(nullptr),
-      programBinary(nullptr),
-      programParameteri(nullptr),
-      programUniform1d(nullptr),
-      programUniform1dv(nullptr),
-      programUniform1f(nullptr),
-      programUniform1fv(nullptr),
-      programUniform1i(nullptr),
-      programUniform1iv(nullptr),
-      programUniform1ui(nullptr),
-      programUniform1uiv(nullptr),
-      programUniform2d(nullptr),
-      programUniform2dv(nullptr),
-      programUniform2f(nullptr),
-      programUniform2fv(nullptr),
-      programUniform2i(nullptr),
-      programUniform2iv(nullptr),
-      programUniform2ui(nullptr),
-      programUniform2uiv(nullptr),
-      programUniform3d(nullptr),
-      programUniform3dv(nullptr),
-      programUniform3f(nullptr),
-      programUniform3fv(nullptr),
-      programUniform3i(nullptr),
-      programUniform3iv(nullptr),
-      programUniform3ui(nullptr),
-      programUniform3uiv(nullptr),
-      programUniform4d(nullptr),
-      programUniform4dv(nullptr),
-      programUniform4f(nullptr),
-      programUniform4fv(nullptr),
-      programUniform4i(nullptr),
-      programUniform4iv(nullptr),
-      programUniform4ui(nullptr),
-      programUniform4uiv(nullptr),
-      programUniformMatrix2dv(nullptr),
-      programUniformMatrix2fv(nullptr),
-      programUniformMatrix2x3dv(nullptr),
-      programUniformMatrix2x3fv(nullptr),
-      programUniformMatrix2x4dv(nullptr),
-      programUniformMatrix2x4fv(nullptr),
-      programUniformMatrix3dv(nullptr),
-      programUniformMatrix3fv(nullptr),
-      programUniformMatrix3x2dv(nullptr),
-      programUniformMatrix3x2fv(nullptr),
-      programUniformMatrix3x4dv(nullptr),
-      programUniformMatrix3x4fv(nullptr),
-      programUniformMatrix4dv(nullptr),
-      programUniformMatrix4fv(nullptr),
-      programUniformMatrix4x2dv(nullptr),
-      programUniformMatrix4x2fv(nullptr),
-      programUniformMatrix4x3dv(nullptr),
-      programUniformMatrix4x3fv(nullptr),
-      releaseShaderCompiler(nullptr),
-      scissorArrayv(nullptr),
-      scissorIndexed(nullptr),
-      scissorIndexedv(nullptr),
-      shaderBinary(nullptr),
-      useProgramStages(nullptr),
-      validateProgramPipeline(nullptr),
-      vertexAttribL1d(nullptr),
-      vertexAttribL1dv(nullptr),
-      vertexAttribL2d(nullptr),
-      vertexAttribL2dv(nullptr),
-      vertexAttribL3d(nullptr),
-      vertexAttribL3dv(nullptr),
-      vertexAttribL4d(nullptr),
-      vertexAttribL4dv(nullptr),
-      vertexAttribLPointer(nullptr),
-      viewportArrayv(nullptr),
-      viewportIndexedf(nullptr),
-      viewportIndexedfv(nullptr),
-
-      bindImageTexture(nullptr),
-      drawArraysInstancedBaseInstance(nullptr),
-      drawElementsInstancedBaseInstance(nullptr),
-      drawElementsInstancedBaseVertexBaseInstance(nullptr),
-      drawTransformFeedbackInstanced(nullptr),
-      drawTransformFeedbackStreamInstanced(nullptr),
-      getActiveAtomicCounterBufferiv(nullptr),
-      getInternalformativ(nullptr),
-      memoryBarrier(nullptr),
-      texStorage1D(nullptr),
-      texStorage2D(nullptr),
-      texStorage3D(nullptr),
-
-      bindVertexBuffer(nullptr),
-      clearBufferData(nullptr),
-      clearBufferSubData(nullptr),
-      copyImageSubData(nullptr),
-      debugMessageCallback(nullptr),
-      debugMessageControl(nullptr),
-      debugMessageInsert(nullptr),
-      dispatchCompute(nullptr),
-      dispatchComputeIndirect(nullptr),
-      framebufferParameteri(nullptr),
-      getDebugMessageLog(nullptr),
-      getFramebufferParameteriv(nullptr),
-      getInternalformati64v(nullptr),
-      getPointerv(nullptr),
-      getObjectLabel(nullptr),
-      getObjectPtrLabel(nullptr),
-      getProgramInterfaceiv(nullptr),
-      getProgramResourceIndex(nullptr),
-      getProgramResourceLocation(nullptr),
-      getProgramResourceLocationIndex(nullptr),
-      getProgramResourceName(nullptr),
-      getProgramResourceiv(nullptr),
-      invalidateBufferData(nullptr),
-      invalidateBufferSubData(nullptr),
-      invalidateFramebuffer(nullptr),
-      invalidateSubFramebuffer(nullptr),
-      invalidateTexImage(nullptr),
-      invalidateTexSubImage(nullptr),
-      multiDrawArraysIndirect(nullptr),
-      multiDrawElementsIndirect(nullptr),
-      objectLabel(nullptr),
-      objectPtrLabel(nullptr),
-      popDebugGroup(nullptr),
-      pushDebugGroup(nullptr),
-      shaderStorageBlockBinding(nullptr),
-      texBufferRange(nullptr),
-      texStorage2DMultisample(nullptr),
-      texStorage3DMultisample(nullptr),
-      textureView(nullptr),
-      vertexAttribBinding(nullptr),
-      vertexAttribFormat(nullptr),
-      vertexAttribIFormat(nullptr),
-      vertexAttribLFormat(nullptr),
-      vertexBindingDivisor(nullptr),
-      coverageModulationNV(nullptr),
-
-      bindBuffersBase(nullptr),
-      bindBuffersRange(nullptr),
-      bindImageTextures(nullptr),
-      bindSamplers(nullptr),
-      bindTextures(nullptr),
-      bindVertexBuffers(nullptr),
-      bufferStorage(nullptr),
-      clearTexImage(nullptr),
-      clearTexSubImage(nullptr),
-
-      bindTextureUnit(nullptr),
-      blitNamedFramebuffer(nullptr),
-      checkNamedFramebufferStatus(nullptr),
-      clearNamedBufferData(nullptr),
-      clearNamedBufferSubData(nullptr),
-      clearNamedFramebufferfi(nullptr),
-      clearNamedFramebufferfv(nullptr),
-      clearNamedFramebufferiv(nullptr),
-      clearNamedFramebufferuiv(nullptr),
-      clipControl(nullptr),
-      compressedTextureSubImage1D(nullptr),
-      compressedTextureSubImage2D(nullptr),
-      compressedTextureSubImage3D(nullptr),
-      copyNamedBufferSubData(nullptr),
-      copyTextureSubImage1D(nullptr),
-      copyTextureSubImage2D(nullptr),
-      copyTextureSubImage3D(nullptr),
-      createBuffers(nullptr),
-      createFramebuffers(nullptr),
-      createProgramPipelines(nullptr),
-      createQueries(nullptr),
-      createRenderbuffers(nullptr),
-      createSamplers(nullptr),
-      createTextures(nullptr),
-      createTransformFeedbacks(nullptr),
-      createVertexArrays(nullptr),
-      disableVertexArrayAttrib(nullptr),
-      enableVertexArrayAttrib(nullptr),
-      flushMappedNamedBufferRange(nullptr),
-      generateTextureMipmap(nullptr),
-      getCompressedTextureImage(nullptr),
-      getCompressedTextureSubImage(nullptr),
-      getGraphicsResetStatus(nullptr),
-      getNamedBufferParameteri64v(nullptr),
-      getNamedBufferParameteriv(nullptr),
-      getNamedBufferPointerv(nullptr),
-      getNamedBufferSubData(nullptr),
-      getNamedFramebufferAttachmentParameteriv(nullptr),
-      getNamedFramebufferParameteriv(nullptr),
-      getNamedRenderbufferParameteriv(nullptr),
-      getQueryBufferObjecti64v(nullptr),
-      getQueryBufferObjectiv(nullptr),
-      getQueryBufferObjectui64v(nullptr),
-      getQueryBufferObjectuiv(nullptr),
-      getTextureImage(nullptr),
-      getTextureLevelParameterfv(nullptr),
-      getTextureLevelParameteriv(nullptr),
-      getTextureParameterIiv(nullptr),
-      getTextureParameterIuiv(nullptr),
-      getTextureParameterfv(nullptr),
-      getTextureParameteriv(nullptr),
-      getTextureSubImage(nullptr),
-      getTransformFeedbacki64_v(nullptr),
-      getTransformFeedbacki_v(nullptr),
-      getTransformFeedbackiv(nullptr),
-      getVertexArrayIndexed64iv(nullptr),
-      getVertexArrayIndexediv(nullptr),
-      getVertexArrayiv(nullptr),
-      getnCompressedTexImage(nullptr),
-      getnTexImage(nullptr),
-      getnUniformdv(nullptr),
-      getnUniformfv(nullptr),
-      getnUniformiv(nullptr),
-      getnUniformuiv(nullptr),
-      invalidateNamedFramebufferData(nullptr),
-      invalidateNamedFramebufferSubData(nullptr),
-      mapNamedBuffer(nullptr),
-      mapNamedBufferRange(nullptr),
-      memoryBarrierByRegion(nullptr),
-      namedBufferData(nullptr),
-      namedBufferStorage(nullptr),
-      namedBufferSubData(nullptr),
-      namedFramebufferDrawBuffer(nullptr),
-      namedFramebufferDrawBuffers(nullptr),
-      namedFramebufferParameteri(nullptr),
-      namedFramebufferReadBuffer(nullptr),
-      namedFramebufferRenderbuffer(nullptr),
-      namedFramebufferTexture(nullptr),
-      namedFramebufferTextureLayer(nullptr),
-      namedRenderbufferStorage(nullptr),
-      namedRenderbufferStorageMultisample(nullptr),
-      readnPixels(nullptr),
-      textureBarrier(nullptr),
-      textureBuffer(nullptr),
-      textureBufferRange(nullptr),
-      textureParameterIiv(nullptr),
-      textureParameterIuiv(nullptr),
-      textureParameterf(nullptr),
-      textureParameterfv(nullptr),
-      textureParameteri(nullptr),
-      textureParameteriv(nullptr),
-      textureStorage1D(nullptr),
-      textureStorage2D(nullptr),
-      textureStorage2DMultisample(nullptr),
-      textureStorage3D(nullptr),
-      textureStorage3DMultisample(nullptr),
-      textureSubImage1D(nullptr),
-      textureSubImage2D(nullptr),
-      textureSubImage3D(nullptr),
-      transformFeedbackBufferBase(nullptr),
-      transformFeedbackBufferRange(nullptr),
-      unmapNamedBuffer(nullptr),
-      vertexArrayAttribBinding(nullptr),
-      vertexArrayAttribFormat(nullptr),
-      vertexArrayAttribIFormat(nullptr),
-      vertexArrayAttribLFormat(nullptr),
-      vertexArrayBindingDivisor(nullptr),
-      vertexArrayElementBuffer(nullptr),
-      vertexArrayVertexBuffer(nullptr),
-      vertexArrayVertexBuffers(nullptr),
-      blendBarrier(nullptr),
-      primitiveBoundingBox(nullptr),
-      eglImageTargetRenderbufferStorageOES(nullptr),
-      eglImageTargetTexture2DOES(nullptr),
-      discardFramebuffer(nullptr),
-      getInternalformatSampleivNV(nullptr)
+FunctionsGL::FunctionsGL() : version(), standard(), extensions()
 {
 }
 
 FunctionsGL::~FunctionsGL()
 {
 }
 
-void FunctionsGL::initialize()
+void FunctionsGL::initialize(const egl::AttributeMap &displayAttributes)
 {
     // Grab the version number
     ASSIGN("glGetString", getString);
     ASSIGN("glGetIntegerv", getIntegerv);
     GetGLVersion(getString, &version, &standard);
 
     // Grab the GL extensions
     if (isAtLeastGL(gl::Version(3, 0)) || isAtLeastGLES(gl::Version(3, 0)))
     {
         ASSIGN("glGetStringi", getStringi);
         extensions = GetIndexedExtensions(getIntegerv, getStringi);
     }
     else
     {
-        const char *exts = reinterpret_cast<const char*>(getString(GL_EXTENSIONS));
+        const char *exts = reinterpret_cast<const char *>(getString(GL_EXTENSIONS));
         angle::SplitStringAlongWhitespace(std::string(exts), &extensions);
     }
 
-    // Load the entry points
+    std::set<std::string> extensionSet;
+    for (const auto &extension : extensions)
+    {
+        extensionSet.insert(extension);
+    }
+
+// Note:
+// Even though extensions are written against specific versions of GL, many drivers expose the
+// extensions in even older versions.  Always try loading the extensions regardless of GL
+// version.
+
+// Load the entry points
+
+#if defined(ANGLE_ENABLE_OPENGL_NULL)
+    EGLint deviceType =
+        static_cast<EGLint>(displayAttributes.get(EGL_PLATFORM_ANGLE_DEVICE_TYPE_ANGLE, EGL_NONE));
+#endif  // defined(ANGLE_ENABLE_GL_NULL)
+
     switch (standard)
     {
         case STANDARD_GL_DESKTOP:
-            initializeProcsDesktopGL();
+        {
+            // Check the context profile
+            profile = 0;
+            if (isAtLeastGL(gl::Version(3, 2)))
+            {
+                getIntegerv(GL_CONTEXT_PROFILE_MASK, &profile);
+            }
+
+#if defined(ANGLE_ENABLE_OPENGL_NULL)
+            if (deviceType == EGL_PLATFORM_ANGLE_DEVICE_TYPE_NULL_ANGLE)
+            {
+                initProcsDesktopGLNULL(version, extensionSet);
+            }
+            else
+#endif  // defined(ANGLE_ENABLE_GL_NULL)
+            {
+                initProcsDesktopGL(version, extensionSet);
+            }
             break;
+        }
 
         case STANDARD_GL_ES:
-            initializeProcsGLES();
+        {
+            // No profiles in GLES
+            profile = 0;
+
+#if defined(ANGLE_ENABLE_OPENGL_NULL)
+            if (deviceType == EGL_PLATFORM_ANGLE_DEVICE_TYPE_NULL_ANGLE)
+            {
+                initProcsGLESNULL(version, extensionSet);
+            }
+            else
+#endif  // defined(ANGLE_ENABLE_GL_NULL)
+            {
+                initProcsGLES(version, extensionSet);
+            }
             break;
+        }
 
         default:
             UNREACHABLE();
             break;
     }
-}
 
-void FunctionsGL::initializeProcsDesktopGL()
-{
-    // Check the context profile
-    profile = 0;
-    if (isAtLeastGL(gl::Version(3, 2)))
-    {
-        getIntegerv(GL_CONTEXT_PROFILE_MASK, &profile);
-    }
-
-    // clang-format off
-
-    // Load extensions
-    // Even though extensions are written against specific versions of GL, many drivers expose the extensions
-    // in even older versions.  Always try loading the extensions regardless of GL version.
-
-    // GL_NV_internalformat_sample_query
-    ASSIGN_WITH_EXT("GL_NV_internalformat_sample_query", "glGetInternalformatSampleivNV", getInternalformatSampleivNV);
-
-    // GL_ARB_program_interface_query (loading only functions relevant to GL_NV_path_rendering here)
-    ASSIGN_WITH_EXT("GL_ARB_program_interface_query", "glGetProgramInterfaceiv", getProgramInterfaceiv);
-    ASSIGN_WITH_EXT("GL_ARB_program_interface_query", "glGetProgramResourceName", getProgramResourceName);
-    ASSIGN_WITH_EXT("GL_ARB_program_interface_query", "glGetProgramResourceiv", getProgramResourceiv);
-
-    // GL_NV_path_rendering
-    ASSIGN_WITH_EXT("GL_NV_path_rendering", "glMatrixLoadfEXT", matrixLoadEXT);
-    ASSIGN_WITH_EXT("GL_NV_path_rendering", "glGenPathsNV", genPathsNV);
-    ASSIGN_WITH_EXT("GL_NV_path_rendering", "glDeletePathsNV", delPathsNV);
-    ASSIGN_WITH_EXT("GL_NV_path_rendering", "glPathCommandsNV", pathCommandsNV);
-    ASSIGN_WITH_EXT("GL_NV_path_rendering", "glIsPathNV", isPathNV);
-    ASSIGN_WITH_EXT("GL_NV_path_rendering", "glPathParameterfNV", setPathParameterfNV);
-    ASSIGN_WITH_EXT("GL_NV_path_rendering", "glPathParameteriNV", setPathParameteriNV);
-    ASSIGN_WITH_EXT("GL_NV_path_rendering", "glGetPathParameterfvNV", getPathParameterfNV);
-    ASSIGN_WITH_EXT("GL_NV_path_rendering", "glGetPathParameterivNV", getPathParameteriNV);
-    ASSIGN_WITH_EXT("GL_NV_path_rendering", "glPathStencilFuncNV", pathStencilFuncNV);
-    ASSIGN_WITH_EXT("GL_NV_path_rendering", "glStencilFillPathNV", stencilFillPathNV);
-    ASSIGN_WITH_EXT("GL_NV_path_rendering", "glStencilStrokePathNV", stencilStrokePathNV);
-    ASSIGN_WITH_EXT("GL_NV_path_rendering", "glCoverFillPathNV", coverFillPathNV);
-    ASSIGN_WITH_EXT("GL_NV_path_rendering", "glCoverStrokePathNV", coverStrokePathNV);
-    ASSIGN_WITH_EXT("GL_NV_path_rendering", "glStencilThenCoverFillPathNV", stencilThenCoverFillPathNV);
-    ASSIGN_WITH_EXT("GL_NV_path_rendering", "glStencilThenCoverStrokePathNV", stencilThenCoverStrokePathNV);
-    ASSIGN_WITH_EXT("GL_NV_path_rendering", "glCoverFillPathInstancedNV", coverFillPathInstancedNV);
-    ASSIGN_WITH_EXT("GL_NV_path_rendering", "glCoverStrokePathInstancedNV", coverStrokePathInstancedNV);
-    ASSIGN_WITH_EXT("GL_NV_path_rendering", "glStencilFillPathInstancedNV", stencilFillPathInstancedNV);
-    ASSIGN_WITH_EXT("GL_NV_path_rendering", "glStencilStrokePathInstancedNV", stencilStrokePathInstancedNV);
-    ASSIGN_WITH_EXT("GL_NV_path_rendering", "glStencilThenCoverFillPathInstancedNV", stencilThenCoverFillPathInstancedNV);
-    ASSIGN_WITH_EXT("GL_NV_path_rendering", "glStencilThenCoverStrokePathInstancedNV", stencilThenCoverStrokePathInstancedNV);
-    ASSIGN_WITH_EXT("GL_NV_path_rendering", "glProgramPathFragmentInputGenNV", programPathFragmentInputGenNV);
-
-    // GL_NV_framebuffer_mixed_samples
-    ASSIGN_WITH_EXT("GL_NV_framebuffer_mixed_samples", "glCoverageModulationNV", coverageModulationNV);
-
-    // GL_NV_fence
-    ASSIGN_WITH_EXT("GL_NV_fence", "glDeleteFencesNV", deleteFencesNV);
-    ASSIGN_WITH_EXT("GL_NV_fence", "glGenFencesNV", genFencesNV);
-    ASSIGN_WITH_EXT("GL_NV_fence", "glIsFenceNV", isFenceNV);
-    ASSIGN_WITH_EXT("GL_NV_fence", "glTestFenceNV", testFenceNV);
-    ASSIGN_WITH_EXT("GL_NV_fence", "glGetFenceivNV", getFenceivNV);
-    ASSIGN_WITH_EXT("GL_NV_fence", "glFinishFenceNV", finishFenceNV);
-    ASSIGN_WITH_EXT("GL_NV_fence", "glSetFenceNV", setFenceNV);
-
-    // GL_EXT_texture_storage
-    ASSIGN_WITH_EXT("GL_EXT_texture_storage", "glTexStorage1DEXT", texStorage1D);
-    ASSIGN_WITH_EXT("GL_EXT_texture_storage", "glTexStorage2DEXT", texStorage2D);
-    ASSIGN_WITH_EXT("GL_EXT_texture_storage GL_EXT_texture3D", "glTexStorage3DEXT", texStorage3D);
-    ASSIGN_WITH_EXT("GL_EXT_texture_storage GL_EXT_texture3D", "glTextureStorage1DEXT", textureStorage1D);
-    ASSIGN_WITH_EXT("GL_EXT_texture_storage GL_EXT_direct_state_access", "glTextureStorage2DEXT", textureStorage2D);
-    ASSIGN_WITH_EXT("GL_EXT_texture_storage GL_EXT_direct_state_access GL_EXT_texture3D", "glTextureStorage3DEXT", textureStorage3D);
-
-    // GL_ARB_vertex_array_object
-    ASSIGN_WITH_EXT("GL_ARB_vertex_array_object", "glBindVertexArray", bindVertexArray);
-    ASSIGN_WITH_EXT("GL_ARB_vertex_array_object", "glDeleteVertexArrays", deleteVertexArrays);
-    ASSIGN_WITH_EXT("GL_ARB_vertex_array_object", "glGenVertexArrays", genVertexArrays);
-    ASSIGN_WITH_EXT("GL_ARB_vertex_array_object", "glIsVertexArray", isVertexArray);
-
-    // GL_ARB_vertex_attrib_binding
-    ASSIGN_WITH_EXT("GL_ARB_vertex_attrib_binding", "glBindVertexBuffer", bindVertexBuffer);
-    ASSIGN_WITH_EXT("GL_ARB_vertex_attrib_binding", "glVertexAttribFormat", vertexAttribFormat);
-    ASSIGN_WITH_EXT("GL_ARB_vertex_attrib_binding", "glVertexAttribIFormat", vertexAttribIFormat);
-    ASSIGN_WITH_EXT("GL_ARB_vertex_attrib_binding", "glVertexAttribLFormat", vertexAttribLFormat);
-    ASSIGN_WITH_EXT("GL_ARB_vertex_attrib_binding", "glVertexAttribBinding", vertexAttribBinding);
-    ASSIGN_WITH_EXT("GL_ARB_vertex_attrib_binding", "glVertexBindingDivisor", vertexBindingDivisor);
-
-    // GL_ARB_sync
-    ASSIGN_WITH_EXT("GL_ARB_sync", "glClientWaitSync", clientWaitSync);
-    ASSIGN_WITH_EXT("GL_ARB_sync", "glDeleteSync", deleteSync);
-    ASSIGN_WITH_EXT("GL_ARB_sync", "glFenceSync", fenceSync);
-    ASSIGN_WITH_EXT("GL_ARB_sync", "glGetInteger64i_v", getInteger64i_v);
-    ASSIGN_WITH_EXT("GL_ARB_sync", "glGetInteger64v", getInteger64v);
-    ASSIGN_WITH_EXT("GL_ARB_sync", "glGetSynciv", getSynciv);
-    ASSIGN_WITH_EXT("GL_ARB_sync", "glIsSync", isSync);
-    ASSIGN_WITH_EXT("GL_ARB_sync", "glWaitSync", waitSync);
-
-    // GL_EXT_framebuffer_object
-    ASSIGN_WITH_EXT("GL_EXT_framebuffer_object", "glIsRenderbufferEXT", isRenderbuffer);
-    ASSIGN_WITH_EXT("GL_EXT_framebuffer_object", "glBindRenderbufferEXT", bindRenderbuffer);
-    ASSIGN_WITH_EXT("GL_EXT_framebuffer_object", "glDeleteRenderbuffersEXT", deleteRenderbuffers);
-    ASSIGN_WITH_EXT("GL_EXT_framebuffer_object", "glGenRenderbuffersEXT", genRenderbuffers);
-    ASSIGN_WITH_EXT("GL_EXT_framebuffer_object", "glRenderbufferStorageEXT", renderbufferStorage);
-    ASSIGN_WITH_EXT("GL_EXT_framebuffer_object", "glGetRenderbufferParameterivEXT", getRenderbufferParameteriv);
-    ASSIGN_WITH_EXT("GL_EXT_framebuffer_object", "glIsFramebufferEXT", isFramebuffer);
-    ASSIGN_WITH_EXT("GL_EXT_framebuffer_object", "glBindFramebufferEXT", bindFramebuffer);
-    ASSIGN_WITH_EXT("GL_EXT_framebuffer_object", "glDeleteFramebuffersEXT", deleteFramebuffers);
-    ASSIGN_WITH_EXT("GL_EXT_framebuffer_object", "glGenFramebuffersEXT", genFramebuffers);
-    ASSIGN_WITH_EXT("GL_EXT_framebuffer_object", "glCheckFramebufferStatusEXT", checkFramebufferStatus);
-    ASSIGN_WITH_EXT("GL_EXT_framebuffer_object", "glFramebufferTexture1DEXT", framebufferTexture1D);
-    ASSIGN_WITH_EXT("GL_EXT_framebuffer_object", "glFramebufferTexture2DEXT", framebufferTexture2D);
-    ASSIGN_WITH_EXT("GL_EXT_framebuffer_object", "glFramebufferTexture3DEXT", framebufferTexture3D);
-    ASSIGN_WITH_EXT("GL_EXT_framebuffer_object", "glFramebufferRenderbufferEXT", framebufferRenderbuffer);
-    ASSIGN_WITH_EXT("GL_EXT_framebuffer_object", "glGetFramebufferAttachmentParameterivEXT", getFramebufferAttachmentParameteriv);
-    ASSIGN_WITH_EXT("GL_EXT_framebuffer_object", "glGenerateMipmapEXT", generateMipmap);
-
-    // GL_EXT_framebuffer_blit
-    ASSIGN_WITH_EXT("GL_EXT_framebuffer_blit", "glBlitFramebufferEXT", blitFramebuffer);
-
-    // GL_KHR_debug
-    ASSIGN_WITH_EXT("GL_KHR_debug", "glDebugMessageControl", debugMessageControl);
-    ASSIGN_WITH_EXT("GL_KHR_debug", "glDebugMessageInsert", debugMessageInsert);
-    ASSIGN_WITH_EXT("GL_KHR_debug", "glDebugMessageCallback", debugMessageCallback);
-    ASSIGN_WITH_EXT("GL_KHR_debug", "glGetDebugMessageLog", getDebugMessageLog);
-    ASSIGN_WITH_EXT("GL_KHR_debug", "glGetPointerv", getPointerv);
-    ASSIGN_WITH_EXT("GL_KHR_debug", "glPushDebugGroup", pushDebugGroup);
-    ASSIGN_WITH_EXT("GL_KHR_debug", "glPopDebugGroup", popDebugGroup);
-    ASSIGN_WITH_EXT("GL_KHR_debug", "glObjectLabel", objectLabel);
-    ASSIGN_WITH_EXT("GL_KHR_debug", "glGetObjectLabel", getObjectLabel);
-    ASSIGN_WITH_EXT("GL_KHR_debug", "glObjectPtrLabel", objectPtrLabel);
-    ASSIGN_WITH_EXT("GL_KHR_debug", "glGetObjectPtrLabel", getObjectPtrLabel);
-
-    // GL_ARB_internalformat_query
-    ASSIGN_WITH_EXT("GL_ARB_internalformat_query", "glGetInternalformativ", getInternalformativ);
-
-    // GL_ARB_ES2_compatibility
-    ASSIGN_WITH_EXT("GL_ARB_ES2_compatibility", "glReleaseShaderCompiler", releaseShaderCompiler);
-    ASSIGN_WITH_EXT("GL_ARB_ES2_compatibility", "glShaderBinary", shaderBinary);
-    ASSIGN_WITH_EXT("GL_ARB_ES2_compatibility", "glGetShaderPrecisionFormat", getShaderPrecisionFormat);
-    ASSIGN_WITH_EXT("GL_ARB_ES2_compatibility", "glDepthRangef", depthRangef);
-    ASSIGN_WITH_EXT("GL_ARB_ES2_compatibility", "glClearDepthf", clearDepthf);
-
-    // GL_ARB_instanced_arrays
-    ASSIGN_WITH_EXT("GL_ARB_instanced_arrays", "glVertexAttribDivisorARB", vertexAttribDivisor);
-
-    // GL_EXT_draw_instanced
-    ASSIGN_WITH_EXT("GL_EXT_draw_instanced", "glDrawArraysInstancedEXT", drawArraysInstanced);
-    ASSIGN_WITH_EXT("GL_EXT_draw_instanced", "glDrawElementsInstancedEXT", drawElementsInstanced);
-
-    // GL_ARB_draw_instanced
-    ASSIGN_WITH_EXT("GL_ARB_draw_instanced", "glDrawArraysInstancedARB", drawArraysInstanced);
-    ASSIGN_WITH_EXT("GL_ARB_draw_instanced", "glDrawElementsInstancedARB", drawElementsInstanced);
-
-    // GL_ARB_sampler_objects
-    ASSIGN_WITH_EXT("GL_ARB_sampler_objects", "glGenSamplers", genSamplers);
-    ASSIGN_WITH_EXT("GL_ARB_sampler_objects", "glDeleteSamplers", deleteSamplers);
-    ASSIGN_WITH_EXT("GL_ARB_sampler_objects", "glIsSampler", isSampler);
-    ASSIGN_WITH_EXT("GL_ARB_sampler_objects", "glBindSampler", bindSampler);
-    ASSIGN_WITH_EXT("GL_ARB_sampler_objects", "glSamplerParameteri", samplerParameteri);
-    ASSIGN_WITH_EXT("GL_ARB_sampler_objects", "glSamplerParameterf", samplerParameterf);
-    ASSIGN_WITH_EXT("GL_ARB_sampler_objects", "glSamplerParameteriv", samplerParameteriv);
-    ASSIGN_WITH_EXT("GL_ARB_sampler_objects", "glSamplerParameterfv", samplerParameterfv);
-    ASSIGN_WITH_EXT("GL_ARB_sampler_objects", "glSamplerParameterIiv", samplerParameterIiv);
-    ASSIGN_WITH_EXT("GL_ARB_sampler_objects", "glSamplerParameterIuiv", samplerParameterIuiv);
-    ASSIGN_WITH_EXT("GL_ARB_sampler_objects", "glGetSamplerParameteriv", getSamplerParameteriv);
-    ASSIGN_WITH_EXT("GL_ARB_sampler_objects", "glGetSamplerParameterfv", getSamplerParameterfv);
-    ASSIGN_WITH_EXT("GL_ARB_sampler_objects", "glGetSamplerParameterIiv", getSamplerParameterIiv);
-    ASSIGN_WITH_EXT("GL_ARB_sampler_objects", "glGetSamplerParameterIuiv", getSamplerParameterIuiv);
-
-    // GL_ARB_occlusion_query
-    ASSIGN_WITH_EXT("GL_ARB_occlusion_query", "glGenQueriesARB", genQueries);
-    ASSIGN_WITH_EXT("GL_ARB_occlusion_query", "glDeleteQueriesARB", deleteQueries);
-    ASSIGN_WITH_EXT("GL_ARB_occlusion_query", "glIsQueryARB", isQuery);
-    ASSIGN_WITH_EXT("GL_ARB_occlusion_query", "glBeginQueryARB", beginQuery);
-    ASSIGN_WITH_EXT("GL_ARB_occlusion_query", "glEndQueryARB", endQuery);
-    ASSIGN_WITH_EXT("GL_ARB_occlusion_query", "glGetQueryivARB", getQueryiv);
-    ASSIGN_WITH_EXT("GL_ARB_occlusion_query", "glGetQueryObjectivARB", getQueryObjectiv);
-    ASSIGN_WITH_EXT("GL_ARB_occlusion_query", "glGetQueryObjectuivARB", getQueryObjectuiv);
-
-    // EXT_transform_feedback
-    ASSIGN_WITH_EXT("EXT_transform_feedback", "glBindBufferRangeEXT", bindBufferRange);
-    ASSIGN_WITH_EXT("EXT_transform_feedback", "glBindBufferBaseEXT", bindBufferBase);
-    ASSIGN_WITH_EXT("EXT_transform_feedback", "glBeginTransformFeedbackEXT", beginTransformFeedback);
-    ASSIGN_WITH_EXT("EXT_transform_feedback", "glEndTransformFeedbackEXT", endTransformFeedback);
-    ASSIGN_WITH_EXT("EXT_transform_feedback", "glTransformFeedbackVaryingsEXT", transformFeedbackVaryings);
-    ASSIGN_WITH_EXT("EXT_transform_feedback", "glGetTransformFeedbackVaryingEXT", getTransformFeedbackVarying);
-
-    // GL_ARB_transform_feedback2
-    ASSIGN_WITH_EXT("GL_ARB_transform_feedback2", "glBindTransformFeedback", bindTransformFeedback);
-    ASSIGN_WITH_EXT("GL_ARB_transform_feedback2", "glDeleteTransformFeedbacks", deleteTransformFeedbacks);
-    ASSIGN_WITH_EXT("GL_ARB_transform_feedback2", "glGenTransformFeedbacks", genTransformFeedbacks);
-    ASSIGN_WITH_EXT("GL_ARB_transform_feedback2", "glIsTransformFeedback", isTransformFeedback);
-    ASSIGN_WITH_EXT("GL_ARB_transform_feedback2", "glPauseTransformFeedback", pauseTransformFeedback);
-    ASSIGN_WITH_EXT("GL_ARB_transform_feedback2", "glResumeTransformFeedback", resumeTransformFeedback);
-    ASSIGN_WITH_EXT("GL_ARB_transform_feedback2", "glDrawTransformFeedback", drawTransformFeedback);
-
-    // GL_ARB_transform_feedback3
-    ASSIGN_WITH_EXT("GL_ARB_transform_feedback3", "glDrawTransformFeedbackStream", drawTransformFeedbackStream);
-    ASSIGN_WITH_EXT("GL_ARB_transform_feedback3", "glBeginQueryIndexed", beginQueryIndexed);
-    ASSIGN_WITH_EXT("GL_ARB_transform_feedback3", "glEndQueryIndexed", endQueryIndexed);
-    ASSIGN_WITH_EXT("GL_ARB_transform_feedback3", "glGetQueryIndexediv", getQueryIndexediv);
-
-    // GL_ARB_get_program_binary
-    ASSIGN_WITH_EXT("GL_ARB_get_program_binary", "glGetProgramBinary", getProgramBinary);
-    ASSIGN_WITH_EXT("GL_ARB_get_program_binary", "glProgramBinary", programBinary);
-    ASSIGN_WITH_EXT("GL_ARB_get_program_binary", "glProgramParameteri", programParameteri);
-
-    // GL_ARB_robustness
-    ASSIGN_WITH_EXT("GL_ARB_robustness", "glGetGraphicsResetStatusARB", getGraphicsResetStatus);
-
-    // GL_KHR_robustness
-    ASSIGN_WITH_EXT("GL_KHR_robustness", "glGetGraphicsResetStatus", getGraphicsResetStatus);
-
-    // GL_ARB_invalidate_subdata
-    ASSIGN_WITH_EXT("GL_ARB_invalidate_subdata", "glInvalidateTexSubImage", invalidateTexSubImage);
-    ASSIGN_WITH_EXT("GL_ARB_invalidate_subdata", "glInvalidateTexImage", invalidateTexImage);
-    ASSIGN_WITH_EXT("GL_ARB_invalidate_subdata", "glInvalidateBufferSubData", invalidateBufferSubData);
-    ASSIGN_WITH_EXT("GL_ARB_invalidate_subdata", "glInvalidateBufferData", invalidateBufferData);
-    ASSIGN_WITH_EXT("GL_ARB_invalidate_subdata", "glInvalidateFramebuffer", invalidateFramebuffer);
-    ASSIGN_WITH_EXT("GL_ARB_invalidate_subdata", "glInvalidateSubFramebuffer", invalidateSubFramebuffer);
-
-    // 1.0
-    if (isAtLeastGL(gl::Version(1, 0)))
-    {
-        ASSIGN("glBlendFunc", blendFunc);
-        ASSIGN("glClear", clear);
-        ASSIGN("glClearColor", clearColor);
-        ASSIGN("glClearDepth", clearDepth);
-        ASSIGN("glClearStencil", clearStencil);
-        ASSIGN("glColorMask", colorMask);
-        ASSIGN("glCullFace", cullFace);
-        ASSIGN("glDepthFunc", depthFunc);
-        ASSIGN("glDepthMask", depthMask);
-        ASSIGN("glDepthRange", depthRange);
-        ASSIGN("glDisable", disable);
-        ASSIGN("glDrawBuffer", drawBuffer);
-        ASSIGN("glEnable", enable);
-        ASSIGN("glFinish", finish);
-        ASSIGN("glFlush", flush);
-        ASSIGN("glFrontFace", frontFace);
-        ASSIGN("glGetBooleanv", getBooleanv);
-        ASSIGN("glGetDoublev", getDoublev);
-        ASSIGN("glGetError", getError);
-        ASSIGN("glGetFloatv", getFloatv);
-        ASSIGN("glGetIntegerv", getIntegerv);
-        ASSIGN("glGetString", getString);
-        ASSIGN("glGetTexImage", getTexImage);
-        ASSIGN("glGetTexLevelParameterfv", getTexLevelParameterfv);
-        ASSIGN("glGetTexLevelParameteriv", getTexLevelParameteriv);
-        ASSIGN("glGetTexParameterfv", getTexParameterfv);
-        ASSIGN("glGetTexParameteriv", getTexParameteriv);
-        ASSIGN("glHint", hint);
-        ASSIGN("glIsEnabled", isEnabled);
-        ASSIGN("glLineWidth", lineWidth);
-        ASSIGN("glLogicOp", logicOp);
-        ASSIGN("glPixelStoref", pixelStoref);
-        ASSIGN("glPixelStorei", pixelStorei);
-        ASSIGN("glPointSize", pointSize);
-        ASSIGN("glPolygonMode", polygonMode);
-        ASSIGN("glReadBuffer", readBuffer);
-        ASSIGN("glReadPixels", readPixels);
-        ASSIGN("glScissor", scissor);
-        ASSIGN("glStencilFunc", stencilFunc);
-        ASSIGN("glStencilMask", stencilMask);
-        ASSIGN("glStencilOp", stencilOp);
-        ASSIGN("glTexImage1D", texImage1D);
-        ASSIGN("glTexImage2D", texImage2D);
-        ASSIGN("glTexParameterf", texParameterf);
-        ASSIGN("glTexParameterfv", texParameterfv);
-        ASSIGN("glTexParameteri", texParameteri);
-        ASSIGN("glTexParameteriv", texParameteriv);
-        ASSIGN("glViewport", viewport);
-    }
-
-    // 1.1
-    if (isAtLeastGL(gl::Version(1, 1)))
-    {
-        ASSIGN("glBindTexture", bindTexture);
-        ASSIGN("glCopyTexImage1D", copyTexImage1D);
-        ASSIGN("glCopyTexImage2D", copyTexImage2D);
-        ASSIGN("glCopyTexSubImage1D", copyTexSubImage1D);
-        ASSIGN("glCopyTexSubImage2D", copyTexSubImage2D);
-        ASSIGN("glDeleteTextures", deleteTextures);
-        ASSIGN("glDrawArrays", drawArrays);
-        ASSIGN("glDrawElements", drawElements);
-        ASSIGN("glGenTextures", genTextures);
-        ASSIGN("glIsTexture", isTexture);
-        ASSIGN("glPolygonOffset", polygonOffset);
-        ASSIGN("glTexSubImage1D", texSubImage1D);
-        ASSIGN("glTexSubImage2D", texSubImage2D);
-    }
-
-    // 1.2
-    if (isAtLeastGL(gl::Version(1, 2)))
-    {
-        ASSIGN("glBlendColor", blendColor);
-        ASSIGN("glBlendEquation", blendEquation);
-        ASSIGN("glCopyTexSubImage3D", copyTexSubImage3D);
-        ASSIGN("glDrawRangeElements", drawRangeElements);
-        ASSIGN("glTexImage3D", texImage3D);
-        ASSIGN("glTexSubImage3D", texSubImage3D);
-    }
-
-    // 1.3
-    if (isAtLeastGL(gl::Version(1, 3)))
-    {
-        ASSIGN("glActiveTexture", activeTexture);
-        ASSIGN("glCompressedTexImage1D", compressedTexImage1D);
-        ASSIGN("glCompressedTexImage2D", compressedTexImage2D);
-        ASSIGN("glCompressedTexImage3D", compressedTexImage3D);
-        ASSIGN("glCompressedTexSubImage1D", compressedTexSubImage1D);
-        ASSIGN("glCompressedTexSubImage2D", compressedTexSubImage2D);
-        ASSIGN("glCompressedTexSubImage3D", compressedTexSubImage3D);
-        ASSIGN("glGetCompressedTexImage", getCompressedTexImage);
-        ASSIGN("glSampleCoverage", sampleCoverage);
-    }
-
-    // 1.4
-    if (isAtLeastGL(gl::Version(1, 4)))
-    {
-        ASSIGN("glBlendFuncSeparate", blendFuncSeparate);
-        ASSIGN("glMultiDrawArrays", multiDrawArrays);
-        ASSIGN("glMultiDrawElements", multiDrawElements);
-        ASSIGN("glPointParameterf", pointParameterf);
-        ASSIGN("glPointParameterfv", pointParameterfv);
-        ASSIGN("glPointParameteri", pointParameteri);
-        ASSIGN("glPointParameteriv", pointParameteriv);
-    }
-
-    // 1.5
-    if (isAtLeastGL(gl::Version(1, 5)))
-    {
-        ASSIGN("glBeginQuery", beginQuery);
-        ASSIGN("glBindBuffer", bindBuffer);
-        ASSIGN("glBufferData", bufferData);
-        ASSIGN("glBufferSubData", bufferSubData);
-        ASSIGN("glDeleteBuffers", deleteBuffers);
-        ASSIGN("glDeleteQueries", deleteQueries);
-        ASSIGN("glEndQuery", endQuery);
-        ASSIGN("glGenBuffers", genBuffers);
-        ASSIGN("glGenQueries", genQueries);
-        ASSIGN("glGetBufferParameteriv", getBufferParameteriv);
-        ASSIGN("glGetBufferPointerv", getBufferPointerv);
-        ASSIGN("glGetBufferSubData", getBufferSubData);
-        ASSIGN("glGetQueryObjectiv", getQueryObjectiv);
-        ASSIGN("glGetQueryObjectuiv", getQueryObjectuiv);
-        ASSIGN("glGetQueryiv", getQueryiv);
-        ASSIGN("glIsBuffer", isBuffer);
-        ASSIGN("glIsQuery", isQuery);
-        ASSIGN("glMapBuffer", mapBuffer);
-        ASSIGN("glUnmapBuffer", unmapBuffer);
-    }
-
-    // 2.0
-    if (isAtLeastGL(gl::Version(2, 0)))
-    {
-        ASSIGN("glAttachShader", attachShader);
-        ASSIGN("glBindAttribLocation", bindAttribLocation);
-        ASSIGN("glBlendEquationSeparate", blendEquationSeparate);
-        ASSIGN("glCompileShader", compileShader);
-        ASSIGN("glCreateProgram", createProgram);
-        ASSIGN("glCreateShader", createShader);
-        ASSIGN("glDeleteProgram", deleteProgram);
-        ASSIGN("glDeleteShader", deleteShader);
-        ASSIGN("glDetachShader", detachShader);
-        ASSIGN("glDisableVertexAttribArray", disableVertexAttribArray);
-        ASSIGN("glDrawBuffers", drawBuffers);
-        ASSIGN("glEnableVertexAttribArray", enableVertexAttribArray);
-        ASSIGN("glGetActiveAttrib", getActiveAttrib);
-        ASSIGN("glGetActiveUniform", getActiveUniform);
-        ASSIGN("glGetAttachedShaders", getAttachedShaders);
-        ASSIGN("glGetAttribLocation", getAttribLocation);
-        ASSIGN("glGetProgramInfoLog", getProgramInfoLog);
-        ASSIGN("glGetProgramiv", getProgramiv);
-        ASSIGN("glGetShaderInfoLog", getShaderInfoLog);
-        ASSIGN("glGetShaderSource", getShaderSource);
-        ASSIGN("glGetShaderiv", getShaderiv);
-        ASSIGN("glGetUniformLocation", getUniformLocation);
-        ASSIGN("glGetUniformfv", getUniformfv);
-        ASSIGN("glGetUniformiv", getUniformiv);
-        ASSIGN("glGetVertexAttribPointerv", getVertexAttribPointerv);
-        ASSIGN("glGetVertexAttribdv", getVertexAttribdv);
-        ASSIGN("glGetVertexAttribfv", getVertexAttribfv);
-        ASSIGN("glGetVertexAttribiv", getVertexAttribiv);
-        ASSIGN("glIsProgram", isProgram);
-        ASSIGN("glIsShader", isShader);
-        ASSIGN("glLinkProgram", linkProgram);
-        ASSIGN("glShaderSource", shaderSource);
-        ASSIGN("glStencilFuncSeparate", stencilFuncSeparate);
-        ASSIGN("glStencilMaskSeparate", stencilMaskSeparate);
-        ASSIGN("glStencilOpSeparate", stencilOpSeparate);
-        ASSIGN("glUniform1f", uniform1f);
-        ASSIGN("glUniform1fv", uniform1fv);
-        ASSIGN("glUniform1i", uniform1i);
-        ASSIGN("glUniform1iv", uniform1iv);
-        ASSIGN("glUniform2f", uniform2f);
-        ASSIGN("glUniform2fv", uniform2fv);
-        ASSIGN("glUniform2i", uniform2i);
-        ASSIGN("glUniform2iv", uniform2iv);
-        ASSIGN("glUniform3f", uniform3f);
-        ASSIGN("glUniform3fv", uniform3fv);
-        ASSIGN("glUniform3i", uniform3i);
-        ASSIGN("glUniform3iv", uniform3iv);
-        ASSIGN("glUniform4f", uniform4f);
-        ASSIGN("glUniform4fv", uniform4fv);
-        ASSIGN("glUniform4i", uniform4i);
-        ASSIGN("glUniform4iv", uniform4iv);
-        ASSIGN("glUniformMatrix2fv", uniformMatrix2fv);
-        ASSIGN("glUniformMatrix3fv", uniformMatrix3fv);
-        ASSIGN("glUniformMatrix4fv", uniformMatrix4fv);
-        ASSIGN("glUseProgram", useProgram);
-        ASSIGN("glValidateProgram", validateProgram);
-        ASSIGN("glVertexAttrib1d", vertexAttrib1d);
-        ASSIGN("glVertexAttrib1dv", vertexAttrib1dv);
-        ASSIGN("glVertexAttrib1f", vertexAttrib1f);
-        ASSIGN("glVertexAttrib1fv", vertexAttrib1fv);
-        ASSIGN("glVertexAttrib1s", vertexAttrib1s);
-        ASSIGN("glVertexAttrib1sv", vertexAttrib1sv);
-        ASSIGN("glVertexAttrib2d", vertexAttrib2d);
-        ASSIGN("glVertexAttrib2dv", vertexAttrib2dv);
-        ASSIGN("glVertexAttrib2f", vertexAttrib2f);
-        ASSIGN("glVertexAttrib2fv", vertexAttrib2fv);
-        ASSIGN("glVertexAttrib2s", vertexAttrib2s);
-        ASSIGN("glVertexAttrib2sv", vertexAttrib2sv);
-        ASSIGN("glVertexAttrib3d", vertexAttrib3d);
-        ASSIGN("glVertexAttrib3dv", vertexAttrib3dv);
-        ASSIGN("glVertexAttrib3f", vertexAttrib3f);
-        ASSIGN("glVertexAttrib3fv", vertexAttrib3fv);
-        ASSIGN("glVertexAttrib3s", vertexAttrib3s);
-        ASSIGN("glVertexAttrib3sv", vertexAttrib3sv);
-        ASSIGN("glVertexAttrib4Nbv", vertexAttrib4Nbv);
-        ASSIGN("glVertexAttrib4Niv", vertexAttrib4Niv);
-        ASSIGN("glVertexAttrib4Nsv", vertexAttrib4Nsv);
-        ASSIGN("glVertexAttrib4Nub", vertexAttrib4Nub);
-        ASSIGN("glVertexAttrib4Nubv", vertexAttrib4Nubv);
-        ASSIGN("glVertexAttrib4Nuiv", vertexAttrib4Nuiv);
-        ASSIGN("glVertexAttrib4Nusv", vertexAttrib4Nusv);
-        ASSIGN("glVertexAttrib4bv", vertexAttrib4bv);
-        ASSIGN("glVertexAttrib4d", vertexAttrib4d);
-        ASSIGN("glVertexAttrib4dv", vertexAttrib4dv);
-        ASSIGN("glVertexAttrib4f", vertexAttrib4f);
-        ASSIGN("glVertexAttrib4fv", vertexAttrib4fv);
-        ASSIGN("glVertexAttrib4iv", vertexAttrib4iv);
-        ASSIGN("glVertexAttrib4s", vertexAttrib4s);
-        ASSIGN("glVertexAttrib4sv", vertexAttrib4sv);
-        ASSIGN("glVertexAttrib4ubv", vertexAttrib4ubv);
-        ASSIGN("glVertexAttrib4uiv", vertexAttrib4uiv);
-        ASSIGN("glVertexAttrib4usv", vertexAttrib4usv);
-        ASSIGN("glVertexAttribPointer", vertexAttribPointer);
-    }
-
-    // 2.1
-    if (isAtLeastGL(gl::Version(2, 1)))
-    {
-        ASSIGN("glUniformMatrix2x3fv", uniformMatrix2x3fv);
-        ASSIGN("glUniformMatrix2x4fv", uniformMatrix2x4fv);
-        ASSIGN("glUniformMatrix3x2fv", uniformMatrix3x2fv);
-        ASSIGN("glUniformMatrix3x4fv", uniformMatrix3x4fv);
-        ASSIGN("glUniformMatrix4x2fv", uniformMatrix4x2fv);
-        ASSIGN("glUniformMatrix4x3fv", uniformMatrix4x3fv);
-    }
-
-    // 3.0
-    if (isAtLeastGL(gl::Version(3, 0)))
-    {
-        ASSIGN("glBeginConditionalRender", beginConditionalRender);
-        ASSIGN("glBeginTransformFeedback", beginTransformFeedback);
-        ASSIGN("glBindBufferBase", bindBufferBase);
-        ASSIGN("glBindBufferRange", bindBufferRange);
-        ASSIGN("glBindFragDataLocation", bindFragDataLocation);
-        ASSIGN("glBindFramebuffer", bindFramebuffer);
-        ASSIGN("glBindRenderbuffer", bindRenderbuffer);
-        ASSIGN("glBindVertexArray", bindVertexArray);
-        ASSIGN("glBlitFramebuffer", blitFramebuffer);
-        ASSIGN("glCheckFramebufferStatus", checkFramebufferStatus);
-        ASSIGN("glClampColor", clampColor);
-        ASSIGN("glClearBufferfi", clearBufferfi);
-        ASSIGN("glClearBufferfv", clearBufferfv);
-        ASSIGN("glClearBufferiv", clearBufferiv);
-        ASSIGN("glClearBufferuiv", clearBufferuiv);
-        ASSIGN("glColorMaski", colorMaski);
-        ASSIGN("glDeleteFramebuffers", deleteFramebuffers);
-        ASSIGN("glDeleteRenderbuffers", deleteRenderbuffers);
-        ASSIGN("glDeleteVertexArrays", deleteVertexArrays);
-        ASSIGN("glDisablei", disablei);
-        ASSIGN("glEnablei", enablei);
-        ASSIGN("glEndConditionalRender", endConditionalRender);
-        ASSIGN("glEndTransformFeedback", endTransformFeedback);
-        ASSIGN("glFlushMappedBufferRange", flushMappedBufferRange);
-        ASSIGN("glFramebufferRenderbuffer", framebufferRenderbuffer);
-        ASSIGN("glFramebufferTexture1D", framebufferTexture1D);
-        ASSIGN("glFramebufferTexture2D", framebufferTexture2D);
-        ASSIGN("glFramebufferTexture3D", framebufferTexture3D);
-        ASSIGN("glFramebufferTextureLayer", framebufferTextureLayer);
-        ASSIGN("glGenFramebuffers", genFramebuffers);
-        ASSIGN("glGenRenderbuffers", genRenderbuffers);
-        ASSIGN("glGenVertexArrays", genVertexArrays);
-        ASSIGN("glGenerateMipmap", generateMipmap);
-        ASSIGN("glGetBooleani_v", getBooleani_v);
-        ASSIGN("glGetFragDataLocation", getFragDataLocation);
-        ASSIGN("glGetFramebufferAttachmentParameteriv", getFramebufferAttachmentParameteriv);
-        ASSIGN("glGetIntegeri_v", getIntegeri_v);
-        ASSIGN("glGetRenderbufferParameteriv", getRenderbufferParameteriv);
-        ASSIGN("glGetStringi", getStringi);
-        ASSIGN("glGetTexParameterIiv", getTexParameterIiv);
-        ASSIGN("glGetTexParameterIuiv", getTexParameterIuiv);
-        ASSIGN("glGetTransformFeedbackVarying", getTransformFeedbackVarying);
-        ASSIGN("glGetUniformuiv", getUniformuiv);
-        ASSIGN("glGetVertexAttribIiv", getVertexAttribIiv);
-        ASSIGN("glGetVertexAttribIuiv", getVertexAttribIuiv);
-        ASSIGN("glIsEnabledi", isEnabledi);
-        ASSIGN("glIsFramebuffer", isFramebuffer);
-        ASSIGN("glIsRenderbuffer", isRenderbuffer);
-        ASSIGN("glIsVertexArray", isVertexArray);
-        ASSIGN("glMapBufferRange", mapBufferRange);
-        ASSIGN("glRenderbufferStorage", renderbufferStorage);
-        ASSIGN("glRenderbufferStorageMultisample", renderbufferStorageMultisample);
-        ASSIGN("glTexParameterIiv", texParameterIiv);
-        ASSIGN("glTexParameterIuiv", texParameterIuiv);
-        ASSIGN("glTransformFeedbackVaryings", transformFeedbackVaryings);
-        ASSIGN("glUniform1ui", uniform1ui);
-        ASSIGN("glUniform1uiv", uniform1uiv);
-        ASSIGN("glUniform2ui", uniform2ui);
-        ASSIGN("glUniform2uiv", uniform2uiv);
-        ASSIGN("glUniform3ui", uniform3ui);
-        ASSIGN("glUniform3uiv", uniform3uiv);
-        ASSIGN("glUniform4ui", uniform4ui);
-        ASSIGN("glUniform4uiv", uniform4uiv);
-        ASSIGN("glVertexAttribI1i", vertexAttribI1i);
-        ASSIGN("glVertexAttribI1iv", vertexAttribI1iv);
-        ASSIGN("glVertexAttribI1ui", vertexAttribI1ui);
-        ASSIGN("glVertexAttribI1uiv", vertexAttribI1uiv);
-        ASSIGN("glVertexAttribI2i", vertexAttribI2i);
-        ASSIGN("glVertexAttribI2iv", vertexAttribI2iv);
-        ASSIGN("glVertexAttribI2ui", vertexAttribI2ui);
-        ASSIGN("glVertexAttribI2uiv", vertexAttribI2uiv);
-        ASSIGN("glVertexAttribI3i", vertexAttribI3i);
-        ASSIGN("glVertexAttribI3iv", vertexAttribI3iv);
-        ASSIGN("glVertexAttribI3ui", vertexAttribI3ui);
-        ASSIGN("glVertexAttribI3uiv", vertexAttribI3uiv);
-        ASSIGN("glVertexAttribI4bv", vertexAttribI4bv);
-        ASSIGN("glVertexAttribI4i", vertexAttribI4i);
-        ASSIGN("glVertexAttribI4iv", vertexAttribI4iv);
-        ASSIGN("glVertexAttribI4sv", vertexAttribI4sv);
-        ASSIGN("glVertexAttribI4ubv", vertexAttribI4ubv);
-        ASSIGN("glVertexAttribI4ui", vertexAttribI4ui);
-        ASSIGN("glVertexAttribI4uiv", vertexAttribI4uiv);
-        ASSIGN("glVertexAttribI4usv", vertexAttribI4usv);
-        ASSIGN("glVertexAttribIPointer", vertexAttribIPointer);
-    }
-
-    // 3.1
-    if (isAtLeastGL(gl::Version(3, 1)))
-    {
-        ASSIGN("glCopyBufferSubData", copyBufferSubData);
-        ASSIGN("glDrawArraysInstanced", drawArraysInstanced);
-        ASSIGN("glDrawElementsInstanced", drawElementsInstanced);
-        ASSIGN("glGetActiveUniformBlockName", getActiveUniformBlockName);
-        ASSIGN("glGetActiveUniformBlockiv", getActiveUniformBlockiv);
-        ASSIGN("glGetActiveUniformName", getActiveUniformName);
-        ASSIGN("glGetActiveUniformsiv", getActiveUniformsiv);
-        ASSIGN("glGetUniformBlockIndex", getUniformBlockIndex);
-        ASSIGN("glGetUniformIndices", getUniformIndices);
-        ASSIGN("glPrimitiveRestartIndex", primitiveRestartIndex);
-        ASSIGN("glTexBuffer", texBuffer);
-        ASSIGN("glUniformBlockBinding", uniformBlockBinding);
-    }
-
-    // 3.2
-    if (isAtLeastGL(gl::Version(3, 2)))
-    {
-        ASSIGN("glClientWaitSync", clientWaitSync);
-        ASSIGN("glDeleteSync", deleteSync);
-        ASSIGN("glDrawElementsBaseVertex", drawElementsBaseVertex);
-        ASSIGN("glDrawElementsInstancedBaseVertex", drawElementsInstancedBaseVertex);
-        ASSIGN("glDrawRangeElementsBaseVertex", drawRangeElementsBaseVertex);
-        ASSIGN("glFenceSync", fenceSync);
-        ASSIGN("glFramebufferTexture", framebufferTexture);
-        ASSIGN("glGetBufferParameteri64v", getBufferParameteri64v);
-        ASSIGN("glGetInteger64i_v", getInteger64i_v);
-        ASSIGN("glGetInteger64v", getInteger64v);
-        ASSIGN("glGetMultisamplefv", getMultisamplefv);
-        ASSIGN("glGetSynciv", getSynciv);
-        ASSIGN("glIsSync", isSync);
-        ASSIGN("glMultiDrawElementsBaseVertex", multiDrawElementsBaseVertex);
-        ASSIGN("glProvokingVertex", provokingVertex);
-        ASSIGN("glSampleMaski", sampleMaski);
-        ASSIGN("glTexImage2DMultisample", texImage2DMultisample);
-        ASSIGN("glTexImage3DMultisample", texImage3DMultisample);
-        ASSIGN("glWaitSync", waitSync);
-    }
-
-    // 3.3
-    if (isAtLeastGL(gl::Version(3, 3)))
-    {
-        ASSIGN("glBindFragDataLocationIndexed", bindFragDataLocationIndexed);
-        ASSIGN("glBindSampler", bindSampler);
-        ASSIGN("glDeleteSamplers", deleteSamplers);
-        ASSIGN("glGenSamplers", genSamplers);
-        ASSIGN("glGetFragDataIndex", getFragDataIndex);
-        ASSIGN("glGetQueryObjecti64v", getQueryObjecti64v);
-        ASSIGN("glGetQueryObjectui64v", getQueryObjectui64v);
-        ASSIGN("glGetSamplerParameterIiv", getSamplerParameterIiv);
-        ASSIGN("glGetSamplerParameterIuiv", getSamplerParameterIuiv);
-        ASSIGN("glGetSamplerParameterfv", getSamplerParameterfv);
-        ASSIGN("glGetSamplerParameteriv", getSamplerParameteriv);
-        ASSIGN("glIsSampler", isSampler);
-        ASSIGN("glQueryCounter", queryCounter);
-        ASSIGN("glSamplerParameterIiv", samplerParameterIiv);
-        ASSIGN("glSamplerParameterIuiv", samplerParameterIuiv);
-        ASSIGN("glSamplerParameterf", samplerParameterf);
-        ASSIGN("glSamplerParameterfv", samplerParameterfv);
-        ASSIGN("glSamplerParameteri", samplerParameteri);
-        ASSIGN("glSamplerParameteriv", samplerParameteriv);
-        ASSIGN("glVertexAttribDivisor", vertexAttribDivisor);
-        ASSIGN("glVertexAttribP1ui", vertexAttribP1ui);
-        ASSIGN("glVertexAttribP1uiv", vertexAttribP1uiv);
-        ASSIGN("glVertexAttribP2ui", vertexAttribP2ui);
-        ASSIGN("glVertexAttribP2uiv", vertexAttribP2uiv);
-        ASSIGN("glVertexAttribP3ui", vertexAttribP3ui);
-        ASSIGN("glVertexAttribP3uiv", vertexAttribP3uiv);
-        ASSIGN("glVertexAttribP4ui", vertexAttribP4ui);
-        ASSIGN("glVertexAttribP4uiv", vertexAttribP4uiv);
-    }
-
-    // 4.0
-    if (isAtLeastGL(gl::Version(4, 0)))
-    {
-        ASSIGN("glBeginQueryIndexed", beginQueryIndexed);
-        ASSIGN("glBindTransformFeedback", bindTransformFeedback);
-        ASSIGN("glBlendEquationSeparatei", blendEquationSeparatei);
-        ASSIGN("glBlendEquationi", blendEquationi);
-        ASSIGN("glBlendFuncSeparatei", blendFuncSeparatei);
-        ASSIGN("glBlendFunci", blendFunci);
-        ASSIGN("glDeleteTransformFeedbacks", deleteTransformFeedbacks);
-        ASSIGN("glDrawArraysIndirect", drawArraysIndirect);
-        ASSIGN("glDrawElementsIndirect", drawElementsIndirect);
-        ASSIGN("glDrawTransformFeedback", drawTransformFeedback);
-        ASSIGN("glDrawTransformFeedbackStream", drawTransformFeedbackStream);
-        ASSIGN("glEndQueryIndexed", endQueryIndexed);
-        ASSIGN("glGenTransformFeedbacks", genTransformFeedbacks);
-        ASSIGN("glGetActiveSubroutineName", getActiveSubroutineName);
-        ASSIGN("glGetActiveSubroutineUniformName", getActiveSubroutineUniformName);
-        ASSIGN("glGetActiveSubroutineUniformiv", getActiveSubroutineUniformiv);
-        ASSIGN("glGetProgramStageiv", getProgramStageiv);
-        ASSIGN("glGetQueryIndexediv", getQueryIndexediv);
-        ASSIGN("glGetSubroutineIndex", getSubroutineIndex);
-        ASSIGN("glGetSubroutineUniformLocation", getSubroutineUniformLocation);
-        ASSIGN("glGetUniformSubroutineuiv", getUniformSubroutineuiv);
-        ASSIGN("glGetUniformdv", getUniformdv);
-        ASSIGN("glIsTransformFeedback", isTransformFeedback);
-        ASSIGN("glMinSampleShading", minSampleShading);
-        ASSIGN("glPatchParameterfv", patchParameterfv);
-        ASSIGN("glPatchParameteri", patchParameteri);
-        ASSIGN("glPauseTransformFeedback", pauseTransformFeedback);
-        ASSIGN("glResumeTransformFeedback", resumeTransformFeedback);
-        ASSIGN("glUniform1d", uniform1d);
-        ASSIGN("glUniform1dv", uniform1dv);
-        ASSIGN("glUniform2d", uniform2d);
-        ASSIGN("glUniform2dv", uniform2dv);
-        ASSIGN("glUniform3d", uniform3d);
-        ASSIGN("glUniform3dv", uniform3dv);
-        ASSIGN("glUniform4d", uniform4d);
-        ASSIGN("glUniform4dv", uniform4dv);
-        ASSIGN("glUniformMatrix2dv", uniformMatrix2dv);
-        ASSIGN("glUniformMatrix2x3dv", uniformMatrix2x3dv);
-        ASSIGN("glUniformMatrix2x4dv", uniformMatrix2x4dv);
-        ASSIGN("glUniformMatrix3dv", uniformMatrix3dv);
-        ASSIGN("glUniformMatrix3x2dv", uniformMatrix3x2dv);
-        ASSIGN("glUniformMatrix3x4dv", uniformMatrix3x4dv);
-        ASSIGN("glUniformMatrix4dv", uniformMatrix4dv);
-        ASSIGN("glUniformMatrix4x2dv", uniformMatrix4x2dv);
-        ASSIGN("glUniformMatrix4x3dv", uniformMatrix4x3dv);
-        ASSIGN("glUniformSubroutinesuiv", uniformSubroutinesuiv);
-    }
-
-    // 4.1
-    if (isAtLeastGL(gl::Version(4, 1)))
+#if defined(ANGLE_ENABLE_OPENGL_NULL)
+    if (deviceType == EGL_PLATFORM_ANGLE_DEVICE_TYPE_NULL_ANGLE)
     {
-        ASSIGN("glActiveShaderProgram", activeShaderProgram);
-        ASSIGN("glBindProgramPipeline", bindProgramPipeline);
-        ASSIGN("glClearDepthf", clearDepthf);
-        ASSIGN("glCreateShaderProgramv", createShaderProgramv);
-        ASSIGN("glDeleteProgramPipelines", deleteProgramPipelines);
-        ASSIGN("glDepthRangeArrayv", depthRangeArrayv);
-        ASSIGN("glDepthRangeIndexed", depthRangeIndexed);
-        ASSIGN("glDepthRangef", depthRangef);
-        ASSIGN("glGenProgramPipelines", genProgramPipelines);
-        ASSIGN("glGetDoublei_v", getDoublei_v);
-        ASSIGN("glGetFloati_v", getFloati_v);
-        ASSIGN("glGetProgramBinary", getProgramBinary);
-        ASSIGN("glGetProgramPipelineInfoLog", getProgramPipelineInfoLog);
-        ASSIGN("glGetProgramPipelineiv", getProgramPipelineiv);
-        ASSIGN("glGetShaderPrecisionFormat", getShaderPrecisionFormat);
-        ASSIGN("glGetVertexAttribLdv", getVertexAttribLdv);
-        ASSIGN("glIsProgramPipeline", isProgramPipeline);
-        ASSIGN("glProgramBinary", programBinary);
-        ASSIGN("glProgramParameteri", programParameteri);
-        ASSIGN("glProgramUniform1d", programUniform1d);
-        ASSIGN("glProgramUniform1dv", programUniform1dv);
-        ASSIGN("glProgramUniform1f", programUniform1f);
-        ASSIGN("glProgramUniform1fv", programUniform1fv);
-        ASSIGN("glProgramUniform1i", programUniform1i);
-        ASSIGN("glProgramUniform1iv", programUniform1iv);
-        ASSIGN("glProgramUniform1ui", programUniform1ui);
-        ASSIGN("glProgramUniform1uiv", programUniform1uiv);
-        ASSIGN("glProgramUniform2d", programUniform2d);
-        ASSIGN("glProgramUniform2dv", programUniform2dv);
-        ASSIGN("glProgramUniform2f", programUniform2f);
-        ASSIGN("glProgramUniform2fv", programUniform2fv);
-        ASSIGN("glProgramUniform2i", programUniform2i);
-        ASSIGN("glProgramUniform2iv", programUniform2iv);
-        ASSIGN("glProgramUniform2ui", programUniform2ui);
-        ASSIGN("glProgramUniform2uiv", programUniform2uiv);
-        ASSIGN("glProgramUniform3d", programUniform3d);
-        ASSIGN("glProgramUniform3dv", programUniform3dv);
-        ASSIGN("glProgramUniform3f", programUniform3f);
-        ASSIGN("glProgramUniform3fv", programUniform3fv);
-        ASSIGN("glProgramUniform3i", programUniform3i);
-        ASSIGN("glProgramUniform3iv", programUniform3iv);
-        ASSIGN("glProgramUniform3ui", programUniform3ui);
-        ASSIGN("glProgramUniform3uiv", programUniform3uiv);
-        ASSIGN("glProgramUniform4d", programUniform4d);
-        ASSIGN("glProgramUniform4dv", programUniform4dv);
-        ASSIGN("glProgramUniform4f", programUniform4f);
-        ASSIGN("glProgramUniform4fv", programUniform4fv);
-        ASSIGN("glProgramUniform4i", programUniform4i);
-        ASSIGN("glProgramUniform4iv", programUniform4iv);
-        ASSIGN("glProgramUniform4ui", programUniform4ui);
-        ASSIGN("glProgramUniform4uiv", programUniform4uiv);
-        ASSIGN("glProgramUniformMatrix2dv", programUniformMatrix2dv);
-        ASSIGN("glProgramUniformMatrix2fv", programUniformMatrix2fv);
-        ASSIGN("glProgramUniformMatrix2x3dv", programUniformMatrix2x3dv);
-        ASSIGN("glProgramUniformMatrix2x3fv", programUniformMatrix2x3fv);
-        ASSIGN("glProgramUniformMatrix2x4dv", programUniformMatrix2x4dv);
-        ASSIGN("glProgramUniformMatrix2x4fv", programUniformMatrix2x4fv);
-        ASSIGN("glProgramUniformMatrix3dv", programUniformMatrix3dv);
-        ASSIGN("glProgramUniformMatrix3fv", programUniformMatrix3fv);
-        ASSIGN("glProgramUniformMatrix3x2dv", programUniformMatrix3x2dv);
-        ASSIGN("glProgramUniformMatrix3x2fv", programUniformMatrix3x2fv);
-        ASSIGN("glProgramUniformMatrix3x4dv", programUniformMatrix3x4dv);
-        ASSIGN("glProgramUniformMatrix3x4fv", programUniformMatrix3x4fv);
-        ASSIGN("glProgramUniformMatrix4dv", programUniformMatrix4dv);
-        ASSIGN("glProgramUniformMatrix4fv", programUniformMatrix4fv);
-        ASSIGN("glProgramUniformMatrix4x2dv", programUniformMatrix4x2dv);
-        ASSIGN("glProgramUniformMatrix4x2fv", programUniformMatrix4x2fv);
-        ASSIGN("glProgramUniformMatrix4x3dv", programUniformMatrix4x3dv);
-        ASSIGN("glProgramUniformMatrix4x3fv", programUniformMatrix4x3fv);
-        ASSIGN("glReleaseShaderCompiler", releaseShaderCompiler);
-        ASSIGN("glScissorArrayv", scissorArrayv);
-        ASSIGN("glScissorIndexed", scissorIndexed);
-        ASSIGN("glScissorIndexedv", scissorIndexedv);
-        ASSIGN("glShaderBinary", shaderBinary);
-        ASSIGN("glUseProgramStages", useProgramStages);
-        ASSIGN("glValidateProgramPipeline", validateProgramPipeline);
-        ASSIGN("glVertexAttribL1d", vertexAttribL1d);
-        ASSIGN("glVertexAttribL1dv", vertexAttribL1dv);
-        ASSIGN("glVertexAttribL2d", vertexAttribL2d);
-        ASSIGN("glVertexAttribL2dv", vertexAttribL2dv);
-        ASSIGN("glVertexAttribL3d", vertexAttribL3d);
-        ASSIGN("glVertexAttribL3dv", vertexAttribL3dv);
-        ASSIGN("glVertexAttribL4d", vertexAttribL4d);
-        ASSIGN("glVertexAttribL4dv", vertexAttribL4dv);
-        ASSIGN("glVertexAttribLPointer", vertexAttribLPointer);
-        ASSIGN("glViewportArrayv", viewportArrayv);
-        ASSIGN("glViewportIndexedf", viewportIndexedf);
-        ASSIGN("glViewportIndexedfv", viewportIndexedfv);
-    }
-
-    // 4.2
-    if (isAtLeastGL(gl::Version(4, 2)))
-    {
-        ASSIGN("glBindImageTexture", bindImageTexture);
-        ASSIGN("glDrawArraysInstancedBaseInstance", drawArraysInstancedBaseInstance);
-        ASSIGN("glDrawElementsInstancedBaseInstance", drawElementsInstancedBaseInstance);
-        ASSIGN("glDrawElementsInstancedBaseVertexBaseInstance", drawElementsInstancedBaseVertexBaseInstance);
-        ASSIGN("glDrawTransformFeedbackInstanced", drawTransformFeedbackInstanced);
-        ASSIGN("glDrawTransformFeedbackStreamInstanced", drawTransformFeedbackStreamInstanced);
-        ASSIGN("glGetActiveAtomicCounterBufferiv", getActiveAtomicCounterBufferiv);
-        ASSIGN("glGetInternalformativ", getInternalformativ);
-        ASSIGN("glMemoryBarrier", memoryBarrier);
-        ASSIGN("glTexStorage1D", texStorage1D);
-        ASSIGN("glTexStorage2D", texStorage2D);
-        ASSIGN("glTexStorage3D", texStorage3D);
-    }
-
-    // 4.3
-    if (isAtLeastGL(gl::Version(4, 3)))
-    {
-        ASSIGN("glBindVertexBuffer", bindVertexBuffer);
-        ASSIGN("glClearBufferData", clearBufferData);
-        ASSIGN("glClearBufferSubData", clearBufferSubData);
-        ASSIGN("glCopyImageSubData", copyImageSubData);
-        ASSIGN("glDebugMessageCallback", debugMessageCallback);
-        ASSIGN("glDebugMessageControl", debugMessageControl);
-        ASSIGN("glDebugMessageInsert", debugMessageInsert);
-        ASSIGN("glDispatchCompute", dispatchCompute);
-        ASSIGN("glDispatchComputeIndirect", dispatchComputeIndirect);
-        ASSIGN("glFramebufferParameteri", framebufferParameteri);
-        ASSIGN("glGetDebugMessageLog", getDebugMessageLog);
-        ASSIGN("glGetFramebufferParameteriv", getFramebufferParameteriv);
-        ASSIGN("glGetInternalformati64v", getInternalformati64v);
-        ASSIGN("glGetPointerv", getPointerv);
-        ASSIGN("glGetObjectLabel", getObjectLabel);
-        ASSIGN("glGetObjectPtrLabel", getObjectPtrLabel);
-        ASSIGN("glGetProgramInterfaceiv", getProgramInterfaceiv);
-        ASSIGN("glGetProgramResourceIndex", getProgramResourceIndex);
-        ASSIGN("glGetProgramResourceLocation", getProgramResourceLocation);
-        ASSIGN("glGetProgramResourceLocationIndex", getProgramResourceLocationIndex);
-        ASSIGN("glGetProgramResourceName", getProgramResourceName);
-        ASSIGN("glGetProgramResourceiv", getProgramResourceiv);
-        ASSIGN("glInvalidateBufferData", invalidateBufferData);
-        ASSIGN("glInvalidateBufferSubData", invalidateBufferSubData);
-        ASSIGN("glInvalidateFramebuffer", invalidateFramebuffer);
-        ASSIGN("glInvalidateSubFramebuffer", invalidateSubFramebuffer);
-        ASSIGN("glInvalidateTexImage", invalidateTexImage);
-        ASSIGN("glInvalidateTexSubImage", invalidateTexSubImage);
-        ASSIGN("glMultiDrawArraysIndirect", multiDrawArraysIndirect);
-        ASSIGN("glMultiDrawElementsIndirect", multiDrawElementsIndirect);
-        ASSIGN("glObjectLabel", objectLabel);
-        ASSIGN("glObjectPtrLabel", objectPtrLabel);
-        ASSIGN("glPopDebugGroup", popDebugGroup);
-        ASSIGN("glPushDebugGroup", pushDebugGroup);
-        ASSIGN("glShaderStorageBlockBinding", shaderStorageBlockBinding);
-        ASSIGN("glTexBufferRange", texBufferRange);
-        ASSIGN("glTexStorage2DMultisample", texStorage2DMultisample);
-        ASSIGN("glTexStorage3DMultisample", texStorage3DMultisample);
-        ASSIGN("glTextureView", textureView);
-        ASSIGN("glVertexAttribBinding", vertexAttribBinding);
-        ASSIGN("glVertexAttribFormat", vertexAttribFormat);
-        ASSIGN("glVertexAttribIFormat", vertexAttribIFormat);
-        ASSIGN("glVertexAttribLFormat", vertexAttribLFormat);
-        ASSIGN("glVertexBindingDivisor", vertexBindingDivisor);
-    }
-
-    // 4.4
-    if (isAtLeastGL(gl::Version(4, 4)))
-    {
-        ASSIGN("glBindBuffersBase", bindBuffersBase);
-        ASSIGN("glBindBuffersRange", bindBuffersRange);
-        ASSIGN("glBindImageTextures", bindImageTextures);
-        ASSIGN("glBindSamplers", bindSamplers);
-        ASSIGN("glBindTextures", bindTextures);
-        ASSIGN("glBindVertexBuffers", bindVertexBuffers);
-        ASSIGN("glBufferStorage", bufferStorage);
-        ASSIGN("glClearTexImage", clearTexImage);
-        ASSIGN("glClearTexSubImage", clearTexSubImage);
-    }
-
-    // 4.5
-    if (isAtLeastGL(gl::Version(4, 5)))
-    {
-        ASSIGN("glBindTextureUnit", bindTextureUnit);
-        ASSIGN("glBlitNamedFramebuffer", blitNamedFramebuffer);
-        ASSIGN("glCheckNamedFramebufferStatus", checkNamedFramebufferStatus);
-        ASSIGN("glClearNamedBufferData", clearNamedBufferData);
-        ASSIGN("glClearNamedBufferSubData", clearNamedBufferSubData);
-        ASSIGN("glClearNamedFramebufferfi", clearNamedFramebufferfi);
-        ASSIGN("glClearNamedFramebufferfv", clearNamedFramebufferfv);
-        ASSIGN("glClearNamedFramebufferiv", clearNamedFramebufferiv);
-        ASSIGN("glClearNamedFramebufferuiv", clearNamedFramebufferuiv);
-        ASSIGN("glClipControl", clipControl);
-        ASSIGN("glCompressedTextureSubImage1D", compressedTextureSubImage1D);
-        ASSIGN("glCompressedTextureSubImage2D", compressedTextureSubImage2D);
-        ASSIGN("glCompressedTextureSubImage3D", compressedTextureSubImage3D);
-        ASSIGN("glCopyNamedBufferSubData", copyNamedBufferSubData);
-        ASSIGN("glCopyTextureSubImage1D", copyTextureSubImage1D);
-        ASSIGN("glCopyTextureSubImage2D", copyTextureSubImage2D);
-        ASSIGN("glCopyTextureSubImage3D", copyTextureSubImage3D);
-        ASSIGN("glCreateBuffers", createBuffers);
-        ASSIGN("glCreateFramebuffers", createFramebuffers);
-        ASSIGN("glCreateProgramPipelines", createProgramPipelines);
-        ASSIGN("glCreateQueries", createQueries);
-        ASSIGN("glCreateRenderbuffers", createRenderbuffers);
-        ASSIGN("glCreateSamplers", createSamplers);
-        ASSIGN("glCreateTextures", createTextures);
-        ASSIGN("glCreateTransformFeedbacks", createTransformFeedbacks);
-        ASSIGN("glCreateVertexArrays", createVertexArrays);
-        ASSIGN("glDisableVertexArrayAttrib", disableVertexArrayAttrib);
-        ASSIGN("glEnableVertexArrayAttrib", enableVertexArrayAttrib);
-        ASSIGN("glFlushMappedNamedBufferRange", flushMappedNamedBufferRange);
-        ASSIGN("glGenerateTextureMipmap", generateTextureMipmap);
-        ASSIGN("glGetCompressedTextureImage", getCompressedTextureImage);
-        ASSIGN("glGetCompressedTextureSubImage", getCompressedTextureSubImage);
-        ASSIGN("glGetGraphicsResetStatus", getGraphicsResetStatus);
-        ASSIGN("glGetNamedBufferParameteri64v", getNamedBufferParameteri64v);
-        ASSIGN("glGetNamedBufferParameteriv", getNamedBufferParameteriv);
-        ASSIGN("glGetNamedBufferPointerv", getNamedBufferPointerv);
-        ASSIGN("glGetNamedBufferSubData", getNamedBufferSubData);
-        ASSIGN("glGetNamedFramebufferAttachmentParameteriv", getNamedFramebufferAttachmentParameteriv);
-        ASSIGN("glGetNamedFramebufferParameteriv", getNamedFramebufferParameteriv);
-        ASSIGN("glGetNamedRenderbufferParameteriv", getNamedRenderbufferParameteriv);
-        ASSIGN("glGetQueryBufferObjecti64v", getQueryBufferObjecti64v);
-        ASSIGN("glGetQueryBufferObjectiv", getQueryBufferObjectiv);
-        ASSIGN("glGetQueryBufferObjectui64v", getQueryBufferObjectui64v);
-        ASSIGN("glGetQueryBufferObjectuiv", getQueryBufferObjectuiv);
-        ASSIGN("glGetTextureImage", getTextureImage);
-        ASSIGN("glGetTextureLevelParameterfv", getTextureLevelParameterfv);
-        ASSIGN("glGetTextureLevelParameteriv", getTextureLevelParameteriv);
-        ASSIGN("glGetTextureParameterIiv", getTextureParameterIiv);
-        ASSIGN("glGetTextureParameterIuiv", getTextureParameterIuiv);
-        ASSIGN("glGetTextureParameterfv", getTextureParameterfv);
-        ASSIGN("glGetTextureParameteriv", getTextureParameteriv);
-        ASSIGN("glGetTextureSubImage", getTextureSubImage);
-        ASSIGN("glGetTransformFeedbacki64_v", getTransformFeedbacki64_v);
-        ASSIGN("glGetTransformFeedbacki_v", getTransformFeedbacki_v);
-        ASSIGN("glGetTransformFeedbackiv", getTransformFeedbackiv);
-        ASSIGN("glGetVertexArrayIndexed64iv", getVertexArrayIndexed64iv);
-        ASSIGN("glGetVertexArrayIndexediv", getVertexArrayIndexediv);
-        ASSIGN("glGetVertexArrayiv", getVertexArrayiv);
-        ASSIGN("glGetnCompressedTexImage", getnCompressedTexImage);
-        ASSIGN("glGetnTexImage", getnTexImage);
-        ASSIGN("glGetnUniformdv", getnUniformdv);
-        ASSIGN("glGetnUniformfv", getnUniformfv);
-        ASSIGN("glGetnUniformiv", getnUniformiv);
-        ASSIGN("glGetnUniformuiv", getnUniformuiv);
-        ASSIGN("glInvalidateNamedFramebufferData", invalidateNamedFramebufferData);
-        ASSIGN("glInvalidateNamedFramebufferSubData", invalidateNamedFramebufferSubData);
-        ASSIGN("glMapNamedBuffer", mapNamedBuffer);
-        ASSIGN("glMapNamedBufferRange", mapNamedBufferRange);
-        ASSIGN("glMemoryBarrierByRegion", memoryBarrierByRegion);
-        ASSIGN("glNamedBufferData", namedBufferData);
-        ASSIGN("glNamedBufferStorage", namedBufferStorage);
-        ASSIGN("glNamedBufferSubData", namedBufferSubData);
-        ASSIGN("glNamedFramebufferDrawBuffer", namedFramebufferDrawBuffer);
-        ASSIGN("glNamedFramebufferDrawBuffers", namedFramebufferDrawBuffers);
-        ASSIGN("glNamedFramebufferParameteri", namedFramebufferParameteri);
-        ASSIGN("glNamedFramebufferReadBuffer", namedFramebufferReadBuffer);
-        ASSIGN("glNamedFramebufferRenderbuffer", namedFramebufferRenderbuffer);
-        ASSIGN("glNamedFramebufferTexture", namedFramebufferTexture);
-        ASSIGN("glNamedFramebufferTextureLayer", namedFramebufferTextureLayer);
-        ASSIGN("glNamedRenderbufferStorage", namedRenderbufferStorage);
-        ASSIGN("glNamedRenderbufferStorageMultisample", namedRenderbufferStorageMultisample);
-        ASSIGN("glReadnPixels", readnPixels);
-        ASSIGN("glTextureBarrier", textureBarrier);
-        ASSIGN("glTextureBuffer", textureBuffer);
-        ASSIGN("glTextureBufferRange", textureBufferRange);
-        ASSIGN("glTextureParameterIiv", textureParameterIiv);
-        ASSIGN("glTextureParameterIuiv", textureParameterIuiv);
-        ASSIGN("glTextureParameterf", textureParameterf);
-        ASSIGN("glTextureParameterfv", textureParameterfv);
-        ASSIGN("glTextureParameteri", textureParameteri);
-        ASSIGN("glTextureParameteriv", textureParameteriv);
-        ASSIGN("glTextureStorage1D", textureStorage1D);
-        ASSIGN("glTextureStorage2D", textureStorage2D);
-        ASSIGN("glTextureStorage2DMultisample", textureStorage2DMultisample);
-        ASSIGN("glTextureStorage3D", textureStorage3D);
-        ASSIGN("glTextureStorage3DMultisample", textureStorage3DMultisample);
-        ASSIGN("glTextureSubImage1D", textureSubImage1D);
-        ASSIGN("glTextureSubImage2D", textureSubImage2D);
-        ASSIGN("glTextureSubImage3D", textureSubImage3D);
-        ASSIGN("glTransformFeedbackBufferBase", transformFeedbackBufferBase);
-        ASSIGN("glTransformFeedbackBufferRange", transformFeedbackBufferRange);
-        ASSIGN("glUnmapNamedBuffer", unmapNamedBuffer);
-        ASSIGN("glVertexArrayAttribBinding", vertexArrayAttribBinding);
-        ASSIGN("glVertexArrayAttribFormat", vertexArrayAttribFormat);
-        ASSIGN("glVertexArrayAttribIFormat", vertexArrayAttribIFormat);
-        ASSIGN("glVertexArrayAttribLFormat", vertexArrayAttribLFormat);
-        ASSIGN("glVertexArrayBindingDivisor", vertexArrayBindingDivisor);
-        ASSIGN("glVertexArrayElementBuffer", vertexArrayElementBuffer);
-        ASSIGN("glVertexArrayVertexBuffer", vertexArrayVertexBuffer);
-        ASSIGN("glVertexArrayVertexBuffers", vertexArrayVertexBuffers);
+        initProcsSharedExtensionsNULL(extensionSet);
+        initializeDummyFunctionsForNULLDriver(extensionSet);
     }
-
-    // clang-format on
-}
-
-void FunctionsGL::initializeProcsGLES()
-{
-    // No profiles in GLES
-    profile = 0;
-
-    // clang-format off
-
-    // GL_NV_internalformat_sample_query
-    ASSIGN_WITH_EXT("GL_NV_internalformat_sample_query", "glGetInternalformatSampleivNV", getInternalformatSampleivNV);
-
-    // GL_NV_path_rendering
-    ASSIGN_WITH_EXT("GL_NV_path_rendering", "glMatrixLoadfEXT", matrixLoadEXT);
-    ASSIGN_WITH_EXT("GL_NV_path_rendering", "glGenPathsNV", genPathsNV);
-    ASSIGN_WITH_EXT("GL_NV_path_rendering", "glDeletePathsNV", delPathsNV);
-    ASSIGN_WITH_EXT("GL_NV_path_rendering", "glPathCommandsNV", pathCommandsNV);
-    ASSIGN_WITH_EXT("GL_NV_path_rendering", "glIsPathNV", isPathNV);
-    ASSIGN_WITH_EXT("GL_NV_path_rendering", "glPathParameterfNV", setPathParameterfNV);
-    ASSIGN_WITH_EXT("GL_NV_path_rendering", "glPathParameteriNV", setPathParameteriNV);
-    ASSIGN_WITH_EXT("GL_NV_path_rendering", "glGetPathParameterfvNV", getPathParameterfNV);
-    ASSIGN_WITH_EXT("GL_NV_path_rendering", "glGetPathParameterivNV", getPathParameteriNV);
-    ASSIGN_WITH_EXT("GL_NV_path_rendering", "glPathStencilFuncNV", pathStencilFuncNV);
-    ASSIGN_WITH_EXT("GL_NV_path_rendering", "glStencilFillPathNV", stencilFillPathNV);
-    ASSIGN_WITH_EXT("GL_NV_path_rendering", "glStencilStrokePathNV", stencilStrokePathNV);
-    ASSIGN_WITH_EXT("GL_NV_path_rendering", "glCoverFillPathNV", coverFillPathNV);
-    ASSIGN_WITH_EXT("GL_NV_path_rendering", "glCoverStrokePathNV", coverStrokePathNV);
-    ASSIGN_WITH_EXT("GL_NV_path_rendering", "glStencilThenCoverFillPathNV", stencilThenCoverFillPathNV);
-    ASSIGN_WITH_EXT("GL_NV_path_rendering", "glStencilThenCoverStrokePathNV", stencilThenCoverStrokePathNV);
-    ASSIGN_WITH_EXT("GL_NV_path_rendering", "glCoverFillPathInstancedNV", coverFillPathInstancedNV);
-    ASSIGN_WITH_EXT("GL_NV_path_rendering", "glCoverStrokePathInstancedNV", coverStrokePathInstancedNV);
-    ASSIGN_WITH_EXT("GL_NV_path_rendering", "glStencilFillPathInstancedNV", stencilFillPathInstancedNV);
-    ASSIGN_WITH_EXT("GL_NV_path_rendering", "glStencilStrokePathInstancedNV", stencilStrokePathInstancedNV);
-    ASSIGN_WITH_EXT("GL_NV_path_rendering", "glStencilThenCoverFillPathInstancedNV", stencilThenCoverFillPathInstancedNV);
-    ASSIGN_WITH_EXT("GL_NV_path_rendering", "glStencilThenCoverStrokePathInstancedNV", stencilThenCoverStrokePathInstancedNV);
-    ASSIGN_WITH_EXT("GL_NV_path_rendering", "glProgramPathFragmentInputGenNV", programPathFragmentInputGenNV);
-
-    // GL_OES_texture_3D
-    ASSIGN_WITH_EXT("GL_OES_texture_3D", "glTexImage3DOES", texImage3D);
-    ASSIGN_WITH_EXT("GL_OES_texture_3D", "glTexSubImage3DOES", texSubImage3D);
-    ASSIGN_WITH_EXT("GL_OES_texture_3D", "glCopyTexSubImage3DOES", copyTexSubImage3D);
-
-    // GL_NV_framebuffer_mixed_samples
-    ASSIGN_WITH_EXT("GL_NV_framebuffer_mixed_samples", "glCoverageModulationNV", coverageModulationNV);
-
-    // GL_NV_fence
-    ASSIGN_WITH_EXT("GL_NV_fence", "glDeleteFencesNV", deleteFencesNV);
-    ASSIGN_WITH_EXT("GL_NV_fence", "glGenFencesNV", genFencesNV);
-    ASSIGN_WITH_EXT("GL_NV_fence", "glIsFenceNV", isFenceNV);
-    ASSIGN_WITH_EXT("GL_NV_fence", "glTestFenceNV", testFenceNV);
-    ASSIGN_WITH_EXT("GL_NV_fence", "glGetFenceivNV", getFenceivNV);
-    ASSIGN_WITH_EXT("GL_NV_fence", "glFinishFenceNV", finishFenceNV);
-    ASSIGN_WITH_EXT("GL_NV_fence", "glSetFenceNV", setFenceNV);
-
-    // GL_EXT_texture_storage
-    ASSIGN_WITH_EXT("GL_EXT_texture_storage", "glTexStorage2DEXT", texStorage2D);
-    ASSIGN_WITH_EXT("GL_EXT_texture_storage GL_OES_texture3D", "glTexStorage3DEXT", texStorage3D);
-
-    // GL_OES_vertex_array_object
-    ASSIGN_WITH_EXT("GL_OES_vertex_array_object", "glBindVertexArray", bindVertexArray);
-    ASSIGN_WITH_EXT("GL_OES_vertex_array_object", "glDeleteVertexArrays", deleteVertexArrays);
-    ASSIGN_WITH_EXT("GL_OES_vertex_array_object", "glGenVertexArrays", genVertexArrays);
-    ASSIGN_WITH_EXT("GL_OES_vertex_array_object", "glIsVertexArray", isVertexArray);
-
-    // GL_EXT_map_buffer_range
-    ASSIGN_WITH_EXT("GL_EXT_map_buffer_range", "glMapBufferRangeEXT", mapBufferRange);
-    ASSIGN_WITH_EXT("GL_EXT_map_buffer_range", "glFlushMappedBufferRangeEXT", flushMappedBufferRange);
-    ASSIGN_WITH_EXT("GL_EXT_map_buffer_range", "glUnmapBufferOES", unmapBuffer);
-
-    // GL_OES_mapbuffer
-    ASSIGN_WITH_EXT("GL_OES_mapbuffer", "glMapBufferOES", mapBuffer);
-    ASSIGN_WITH_EXT("GL_OES_mapbuffer", "glUnmapBufferOES", unmapBuffer);
-
-    // GL_KHR_debug
-    ASSIGN_WITH_EXT("GL_KHR_debug", "glDebugMessageControlKHR", debugMessageControl);
-    ASSIGN_WITH_EXT("GL_KHR_debug", "glDebugMessageInsertKHR", debugMessageInsert);
-    ASSIGN_WITH_EXT("GL_KHR_debug", "glDebugMessageCallbackKHR", debugMessageCallback);
-    ASSIGN_WITH_EXT("GL_KHR_debug", "glGetDebugMessageLogKHR", getDebugMessageLog);
-    ASSIGN_WITH_EXT("GL_KHR_debug", "glGetPointervKHR", getPointerv);
-    ASSIGN_WITH_EXT("GL_KHR_debug", "glPushDebugGroupKHR", pushDebugGroup);
-    ASSIGN_WITH_EXT("GL_KHR_debug", "glPopDebugGroupKHR", popDebugGroup);
-    ASSIGN_WITH_EXT("GL_KHR_debug", "glObjectLabelKHR", objectLabel);
-    ASSIGN_WITH_EXT("GL_KHR_debug", "glGetObjectLabelKHR", getObjectLabel);
-    ASSIGN_WITH_EXT("GL_KHR_debug", "glObjectPtrLabelKHR", objectPtrLabel);
-    ASSIGN_WITH_EXT("GL_KHR_debug", "glGetObjectPtrLabelKHR", getObjectPtrLabel);
-
-    // GL_EXT_draw_instanced
-    ASSIGN_WITH_EXT("GL_EXT_draw_instanced", "glVertexAttribDivisorEXT", vertexAttribDivisor);
-    ASSIGN_WITH_EXT("GL_EXT_draw_instanced", "glDrawArraysInstancedEXT", drawArraysInstanced);
-    ASSIGN_WITH_EXT("GL_EXT_draw_instanced", "glDrawElementsInstancedEXT", drawElementsInstanced);
-
-    // GL_EXT_occlusion_query_boolean
-    ASSIGN_WITH_EXT("GL_EXT_occlusion_query_boolean", "glGenQueriesEXT", genQueries);
-    ASSIGN_WITH_EXT("GL_EXT_occlusion_query_boolean", "glDeleteQueriesEXT", deleteQueries);
-    ASSIGN_WITH_EXT("GL_EXT_occlusion_query_boolean", "glIsQueryEXT", isQuery);
-    ASSIGN_WITH_EXT("GL_EXT_occlusion_query_boolean", "glBeginQueryEXT", beginQuery);
-    ASSIGN_WITH_EXT("GL_EXT_occlusion_query_boolean", "glEndQueryEXT", endQuery);
-    ASSIGN_WITH_EXT("GL_EXT_occlusion_query_boolean", "glGetQueryivEXT", getQueryiv);
-    ASSIGN_WITH_EXT("GL_EXT_occlusion_query_boolean", "glGetQueryObjectuivEXT", getQueryObjectuiv);
-
-    // GL_EXT_disjoint_timer_query
-    ASSIGN_WITH_EXT("GL_EXT_disjoint_timer_query", "glGenQueriesEXT", genQueries);
-    ASSIGN_WITH_EXT("GL_EXT_disjoint_timer_query", "glDeleteQueriesEXT", deleteQueries);
-    ASSIGN_WITH_EXT("GL_EXT_disjoint_timer_query", "glIsQueryEXT", isQuery);
-    ASSIGN_WITH_EXT("GL_EXT_disjoint_timer_query", "glBeginQueryEXT", beginQuery);
-    ASSIGN_WITH_EXT("GL_EXT_disjoint_timer_query", "glEndQueryEXT", endQuery);
-    ASSIGN_WITH_EXT("GL_EXT_disjoint_timer_query", "glQueryCounterEXT", queryCounter);
-    ASSIGN_WITH_EXT("GL_EXT_disjoint_timer_query", "glGetQueryivEXT", getQueryiv);
-    ASSIGN_WITH_EXT("GL_EXT_disjoint_timer_query", "glGetQueryObjectivEXT", getQueryObjectiv);
-    ASSIGN_WITH_EXT("GL_EXT_disjoint_timer_query", "glGetQueryObjectuivEXT", getQueryObjectuiv);
-    ASSIGN_WITH_EXT("GL_EXT_disjoint_timer_query", "glGetQueryObjecti64vEXT", getQueryObjecti64v);
-    ASSIGN_WITH_EXT("GL_EXT_disjoint_timer_query", "glGetQueryObjectui64vEXT", getQueryObjectui64v);
-
-    // GL_OES_EGL_image
-    ASSIGN_WITH_EXT("GL_OES_EGL_image", "glEGLImageTargetRenderbufferStorageOES", eglImageTargetRenderbufferStorageOES);
-    ASSIGN_WITH_EXT("GL_OES_EGL_image", "glEGLImageTargetTexture2DOES", eglImageTargetTexture2DOES);
-
-    // GL_OES_get_program_binary
-    ASSIGN_WITH_EXT("GL_OES_get_program_binary", "glGetProgramBinaryOES", getProgramBinary);
-    ASSIGN_WITH_EXT("GL_OES_get_program_binary", "glProgramBinaryOES", programBinary);
-
-    // GL_EXT_robustness
-    ASSIGN_WITH_EXT("GL_EXT_robustness", "glGetGraphicsResetStatusEXT", getGraphicsResetStatus);
-
-    // GL_KHR_robustness
-    ASSIGN_WITH_EXT("GL_KHR_robustness", "glGetGraphicsResetStatusKHR", getGraphicsResetStatus);
-
-    // GL_EXT_discard_framebuffer
-    ASSIGN_WITH_EXT("GL_EXT_discard_framebuffer", "glDiscardFramebufferEXT", discardFramebuffer);
-
-    // 2.0
-    if (isAtLeastGLES(gl::Version(2, 0)))
+    else
+#endif  // defined(ANGLE_ENABLE_OPENGL_NULL)
     {
-        ASSIGN("glActiveTexture", activeTexture);
-        ASSIGN("glAttachShader", attachShader);
-        ASSIGN("glBindAttribLocation", bindAttribLocation);
-        ASSIGN("glBindBuffer", bindBuffer);
-        ASSIGN("glBindFramebuffer", bindFramebuffer);
-        ASSIGN("glBindRenderbuffer", bindRenderbuffer);
-        ASSIGN("glBindTexture", bindTexture);
-        ASSIGN("glBlendColor", blendColor);
-        ASSIGN("glBlendEquation", blendEquation);
-        ASSIGN("glBlendEquationSeparate", blendEquationSeparate);
-        ASSIGN("glBlendFunc", blendFunc);
-        ASSIGN("glBlendFuncSeparate", blendFuncSeparate);
-        ASSIGN("glBufferData", bufferData);
-        ASSIGN("glBufferSubData", bufferSubData);
-        ASSIGN("glCheckFramebufferStatus", checkFramebufferStatus);
-        ASSIGN("glClear", clear);
-        ASSIGN("glClearColor", clearColor);
-        ASSIGN("glClearDepthf", clearDepthf);
-        ASSIGN("glClearStencil", clearStencil);
-        ASSIGN("glColorMask", colorMask);
-        ASSIGN("glCompileShader", compileShader);
-        ASSIGN("glCompressedTexImage2D", compressedTexImage2D);
-        ASSIGN("glCompressedTexSubImage2D", compressedTexSubImage2D);
-        ASSIGN("glCopyTexImage2D", copyTexImage2D);
-        ASSIGN("glCopyTexSubImage2D", copyTexSubImage2D);
-        ASSIGN("glCreateProgram", createProgram);
-        ASSIGN("glCreateShader", createShader);
-        ASSIGN("glCullFace", cullFace);
-        ASSIGN("glDeleteBuffers", deleteBuffers);
-        ASSIGN("glDeleteFramebuffers", deleteFramebuffers);
-        ASSIGN("glDeleteProgram", deleteProgram);
-        ASSIGN("glDeleteRenderbuffers", deleteRenderbuffers);
-        ASSIGN("glDeleteShader", deleteShader);
-        ASSIGN("glDeleteTextures", deleteTextures);
-        ASSIGN("glDepthFunc", depthFunc);
-        ASSIGN("glDepthMask", depthMask);
-        ASSIGN("glDepthRangef", depthRangef);
-        ASSIGN("glDetachShader", detachShader);
-        ASSIGN("glDisable", disable);
-        ASSIGN("glDisableVertexAttribArray", disableVertexAttribArray);
-        ASSIGN("glDrawArrays", drawArrays);
-        ASSIGN("glDrawElements", drawElements);
-        ASSIGN("glEnable", enable);
-        ASSIGN("glEnableVertexAttribArray", enableVertexAttribArray);
-        ASSIGN("glFinish", finish);
-        ASSIGN("glFlush", flush);
-        ASSIGN("glFramebufferRenderbuffer", framebufferRenderbuffer);
-        ASSIGN("glFramebufferTexture2D", framebufferTexture2D);
-        ASSIGN("glFrontFace", frontFace);
-        ASSIGN("glGenBuffers", genBuffers);
-        ASSIGN("glGenerateMipmap", generateMipmap);
-        ASSIGN("glGenFramebuffers", genFramebuffers);
-        ASSIGN("glGenRenderbuffers", genRenderbuffers);
-        ASSIGN("glGenTextures", genTextures);
-        ASSIGN("glGetActiveAttrib", getActiveAttrib);
-        ASSIGN("glGetActiveUniform", getActiveUniform);
-        ASSIGN("glGetAttachedShaders", getAttachedShaders);
-        ASSIGN("glGetAttribLocation", getAttribLocation);
-        ASSIGN("glGetBooleanv", getBooleanv);
-        ASSIGN("glGetBufferParameteriv", getBufferParameteriv);
-        ASSIGN("glGetError", getError);
-        ASSIGN("glGetFloatv", getFloatv);
-        ASSIGN("glGetFramebufferAttachmentParameteriv", getFramebufferAttachmentParameteriv);
-        ASSIGN("glGetIntegerv", getIntegerv);
-        ASSIGN("glGetProgramiv", getProgramiv);
-        ASSIGN("glGetProgramInfoLog", getProgramInfoLog);
-        ASSIGN("glGetRenderbufferParameteriv", getRenderbufferParameteriv);
-        ASSIGN("glGetShaderiv", getShaderiv);
-        ASSIGN("glGetShaderInfoLog", getShaderInfoLog);
-        ASSIGN("glGetShaderPrecisionFormat", getShaderPrecisionFormat);
-        ASSIGN("glGetShaderSource", getShaderSource);
-        ASSIGN("glGetString", getString);
-        ASSIGN("glGetTexParameterfv", getTexParameterfv);
-        ASSIGN("glGetTexParameteriv", getTexParameteriv);
-        ASSIGN("glGetUniformfv", getUniformfv);
-        ASSIGN("glGetUniformiv", getUniformiv);
-        ASSIGN("glGetUniformLocation", getUniformLocation);
-        ASSIGN("glGetVertexAttribfv", getVertexAttribfv);
-        ASSIGN("glGetVertexAttribiv", getVertexAttribiv);
-        ASSIGN("glGetVertexAttribPointerv", getVertexAttribPointerv);
-        ASSIGN("glHint", hint);
-        ASSIGN("glIsBuffer", isBuffer);
-        ASSIGN("glIsEnabled", isEnabled);
-        ASSIGN("glIsFramebuffer", isFramebuffer);
-        ASSIGN("glIsProgram", isProgram);
-        ASSIGN("glIsRenderbuffer", isRenderbuffer);
-        ASSIGN("glIsShader", isShader);
-        ASSIGN("glIsTexture", isTexture);
-        ASSIGN("glLineWidth", lineWidth);
-        ASSIGN("glLinkProgram", linkProgram);
-        ASSIGN("glPixelStorei", pixelStorei);
-        ASSIGN("glPolygonOffset", polygonOffset);
-        ASSIGN("glReadPixels", readPixels);
-        ASSIGN("glReleaseShaderCompiler", releaseShaderCompiler);
-        ASSIGN("glRenderbufferStorage", renderbufferStorage);
-        ASSIGN("glSampleCoverage", sampleCoverage);
-        ASSIGN("glScissor", scissor);
-        ASSIGN("glShaderBinary", shaderBinary);
-        ASSIGN("glShaderSource", shaderSource);
-        ASSIGN("glStencilFunc", stencilFunc);
-        ASSIGN("glStencilFuncSeparate", stencilFuncSeparate);
-        ASSIGN("glStencilMask", stencilMask);
-        ASSIGN("glStencilMaskSeparate", stencilMaskSeparate);
-        ASSIGN("glStencilOp", stencilOp);
-        ASSIGN("glStencilOpSeparate", stencilOpSeparate);
-        ASSIGN("glTexImage2D", texImage2D);
-        ASSIGN("glTexParameterf", texParameterf);
-        ASSIGN("glTexParameterfv", texParameterfv);
-        ASSIGN("glTexParameteri", texParameteri);
-        ASSIGN("glTexParameteriv", texParameteriv);
-        ASSIGN("glTexSubImage2D", texSubImage2D);
-        ASSIGN("glUniform1f", uniform1f);
-        ASSIGN("glUniform1fv", uniform1fv);
-        ASSIGN("glUniform1i", uniform1i);
-        ASSIGN("glUniform1iv", uniform1iv);
-        ASSIGN("glUniform2f", uniform2f);
-        ASSIGN("glUniform2fv", uniform2fv);
-        ASSIGN("glUniform2i", uniform2i);
-        ASSIGN("glUniform2iv", uniform2iv);
-        ASSIGN("glUniform3f", uniform3f);
-        ASSIGN("glUniform3fv", uniform3fv);
-        ASSIGN("glUniform3i", uniform3i);
-        ASSIGN("glUniform3iv", uniform3iv);
-        ASSIGN("glUniform4f", uniform4f);
-        ASSIGN("glUniform4fv", uniform4fv);
-        ASSIGN("glUniform4i", uniform4i);
-        ASSIGN("glUniform4iv", uniform4iv);
-        ASSIGN("glUniformMatrix2fv", uniformMatrix2fv);
-        ASSIGN("glUniformMatrix3fv", uniformMatrix3fv);
-        ASSIGN("glUniformMatrix4fv", uniformMatrix4fv);
-        ASSIGN("glUseProgram", useProgram);
-        ASSIGN("glValidateProgram", validateProgram);
-        ASSIGN("glVertexAttrib1f", vertexAttrib1f);
-        ASSIGN("glVertexAttrib1fv", vertexAttrib1fv);
-        ASSIGN("glVertexAttrib2f", vertexAttrib2f);
-        ASSIGN("glVertexAttrib2fv", vertexAttrib2fv);
-        ASSIGN("glVertexAttrib3f", vertexAttrib3f);
-        ASSIGN("glVertexAttrib3fv", vertexAttrib3fv);
-        ASSIGN("glVertexAttrib4f", vertexAttrib4f);
-        ASSIGN("glVertexAttrib4fv", vertexAttrib4fv);
-        ASSIGN("glVertexAttribPointer", vertexAttribPointer);
-        ASSIGN("glViewport", viewport);
+        initProcsSharedExtensions(extensionSet);
     }
-
-    // 3.0
-    if (isAtLeastGLES(gl::Version(3, 0)))
-    {
-        ASSIGN("glReadBuffer", readBuffer);
-        ASSIGN("glDrawRangeElements", drawRangeElements);
-        ASSIGN("glTexImage3D", texImage3D);
-        ASSIGN("glTexSubImage3D", texSubImage3D);
-        ASSIGN("glCopyTexSubImage3D", copyTexSubImage3D);
-        ASSIGN("glCompressedTexImage3D", compressedTexImage3D);
-        ASSIGN("glCompressedTexSubImage3D", compressedTexSubImage3D);
-        ASSIGN("glGenQueries", genQueries);
-        ASSIGN("glDeleteQueries", deleteQueries);
-        ASSIGN("glIsQuery", isQuery);
-        ASSIGN("glBeginQuery", beginQuery);
-        ASSIGN("glEndQuery", endQuery);
-        ASSIGN("glGetQueryiv", getQueryiv);
-        ASSIGN("glGetQueryObjectuiv", getQueryObjectuiv);
-        ASSIGN("glUnmapBuffer", unmapBuffer);
-        ASSIGN("glGetBufferPointerv", getBufferPointerv);
-        ASSIGN("glDrawBuffers", drawBuffers);
-        ASSIGN("glUniformMatrix2x3fv", uniformMatrix2x3fv);
-        ASSIGN("glUniformMatrix3x2fv", uniformMatrix3x2fv);
-        ASSIGN("glUniformMatrix2x4fv", uniformMatrix2x4fv);
-        ASSIGN("glUniformMatrix4x2fv", uniformMatrix4x2fv);
-        ASSIGN("glUniformMatrix3x4fv", uniformMatrix3x4fv);
-        ASSIGN("glUniformMatrix4x3fv", uniformMatrix4x3fv);
-        ASSIGN("glBlitFramebuffer", blitFramebuffer);
-        ASSIGN("glRenderbufferStorageMultisample", renderbufferStorageMultisample);
-        ASSIGN("glFramebufferTextureLayer", framebufferTextureLayer);
-        ASSIGN("glMapBufferRange", mapBufferRange);
-        ASSIGN("glFlushMappedBufferRange", flushMappedBufferRange);
-        ASSIGN("glBindVertexArray", bindVertexArray);
-        ASSIGN("glDeleteVertexArrays", deleteVertexArrays);
-        ASSIGN("glGenVertexArrays", genVertexArrays);
-        ASSIGN("glIsVertexArray", isVertexArray);
-        ASSIGN("glGetIntegeri_v", getIntegeri_v);
-        ASSIGN("glBeginTransformFeedback", beginTransformFeedback);
-        ASSIGN("glEndTransformFeedback", endTransformFeedback);
-        ASSIGN("glBindBufferRange", bindBufferRange);
-        ASSIGN("glBindBufferBase", bindBufferBase);
-        ASSIGN("glTransformFeedbackVaryings", transformFeedbackVaryings);
-        ASSIGN("glGetTransformFeedbackVarying", getTransformFeedbackVarying);
-        ASSIGN("glVertexAttribIPointer", vertexAttribIPointer);
-        ASSIGN("glGetVertexAttribIiv", getVertexAttribIiv);
-        ASSIGN("glGetVertexAttribIuiv", getVertexAttribIuiv);
-        ASSIGN("glVertexAttribI4i", vertexAttribI4i);
-        ASSIGN("glVertexAttribI4ui", vertexAttribI4ui);
-        ASSIGN("glVertexAttribI4iv", vertexAttribI4iv);
-        ASSIGN("glVertexAttribI4uiv", vertexAttribI4uiv);
-        ASSIGN("glGetUniformuiv", getUniformuiv);
-        ASSIGN("glGetFragDataLocation", getFragDataLocation);
-        ASSIGN("glUniform1ui", uniform1ui);
-        ASSIGN("glUniform2ui", uniform2ui);
-        ASSIGN("glUniform3ui", uniform3ui);
-        ASSIGN("glUniform4ui", uniform4ui);
-        ASSIGN("glUniform1uiv", uniform1uiv);
-        ASSIGN("glUniform2uiv", uniform2uiv);
-        ASSIGN("glUniform3uiv", uniform3uiv);
-        ASSIGN("glUniform4uiv", uniform4uiv);
-        ASSIGN("glClearBufferiv", clearBufferiv);
-        ASSIGN("glClearBufferuiv", clearBufferuiv);
-        ASSIGN("glClearBufferfv", clearBufferfv);
-        ASSIGN("glClearBufferfi", clearBufferfi);
-        ASSIGN("glGetStringi", getStringi);
-        ASSIGN("glCopyBufferSubData", copyBufferSubData);
-        ASSIGN("glGetUniformIndices", getUniformIndices);
-        ASSIGN("glGetActiveUniformsiv", getActiveUniformsiv);
-        ASSIGN("glGetUniformBlockIndex", getUniformBlockIndex);
-        ASSIGN("glGetActiveUniformBlockiv", getActiveUniformBlockiv);
-        ASSIGN("glGetActiveUniformBlockName", getActiveUniformBlockName);
-        ASSIGN("glUniformBlockBinding", uniformBlockBinding);
-        ASSIGN("glDrawArraysInstanced", drawArraysInstanced);
-        ASSIGN("glDrawElementsInstanced", drawElementsInstanced);
-        ASSIGN("glFenceSync", fenceSync);
-        ASSIGN("glIsSync", isSync);
-        ASSIGN("glDeleteSync", deleteSync);
-        ASSIGN("glClientWaitSync", clientWaitSync);
-        ASSIGN("glWaitSync", waitSync);
-        ASSIGN("glGetInteger64v", getInteger64v);
-        ASSIGN("glGetSynciv", getSynciv);
-        ASSIGN("glGetInteger64i_v", getInteger64i_v);
-        ASSIGN("glGetBufferParameteri64v", getBufferParameteri64v);
-        ASSIGN("glGenSamplers", genSamplers);
-        ASSIGN("glDeleteSamplers", deleteSamplers);
-        ASSIGN("glIsSampler", isSampler);
-        ASSIGN("glBindSampler", bindSampler);
-        ASSIGN("glSamplerParameteri", samplerParameteri);
-        ASSIGN("glSamplerParameteriv", samplerParameteriv);
-        ASSIGN("glSamplerParameterf", samplerParameterf);
-        ASSIGN("glSamplerParameterfv", samplerParameterfv);
-        ASSIGN("glGetSamplerParameteriv", getSamplerParameteriv);
-        ASSIGN("glGetSamplerParameterfv", getSamplerParameterfv);
-        ASSIGN("glVertexAttribDivisor", vertexAttribDivisor);
-        ASSIGN("glBindTransformFeedback", bindTransformFeedback);
-        ASSIGN("glDeleteTransformFeedbacks", deleteTransformFeedbacks);
-        ASSIGN("glGenTransformFeedbacks", genTransformFeedbacks);
-        ASSIGN("glIsTransformFeedback", isTransformFeedback);
-        ASSIGN("glPauseTransformFeedback", pauseTransformFeedback);
-        ASSIGN("glResumeTransformFeedback", resumeTransformFeedback);
-        ASSIGN("glGetProgramBinary", getProgramBinary);
-        ASSIGN("glProgramBinary", programBinary);
-        ASSIGN("glProgramParameteri", programParameteri);
-        ASSIGN("glInvalidateFramebuffer", invalidateFramebuffer);
-        ASSIGN("glInvalidateSubFramebuffer", invalidateSubFramebuffer);
-        ASSIGN("glTexStorage2D", texStorage2D);
-        ASSIGN("glTexStorage3D", texStorage3D);
-        ASSIGN("glGetInternalformativ", getInternalformativ);
-    }
-
-    // 3.1
-    if (isAtLeastGLES(gl::Version(3, 1)))
-    {
-        ASSIGN("glDispatchCompute", dispatchCompute);
-        ASSIGN("glDispatchComputeIndirect", dispatchComputeIndirect);
-        ASSIGN("glDrawArraysIndirect", drawArraysIndirect);
-        ASSIGN("glDrawElementsIndirect", drawElementsIndirect);
-        ASSIGN("glFramebufferParameteri", framebufferParameteri);
-        ASSIGN("glGetFramebufferParameteriv", getFramebufferParameteriv);
-        ASSIGN("glGetProgramInterfaceiv", getProgramInterfaceiv);
-        ASSIGN("glGetProgramResourceIndex", getProgramResourceIndex);
-        ASSIGN("glGetProgramResourceName", getProgramResourceName);
-        ASSIGN("glGetProgramResourceiv", getProgramResourceiv);
-        ASSIGN("glGetProgramResourceLocation", getProgramResourceLocation);
-        ASSIGN("glUseProgramStages", useProgramStages);
-        ASSIGN("glActiveShaderProgram", activeShaderProgram);
-        ASSIGN("glCreateShaderProgramv", createShaderProgramv);
-        ASSIGN("glBindProgramPipeline", bindProgramPipeline);
-        ASSIGN("glDeleteProgramPipelines", deleteProgramPipelines);
-        ASSIGN("glGenProgramPipelines", genProgramPipelines);
-        ASSIGN("glIsProgramPipeline", isProgramPipeline);
-        ASSIGN("glGetProgramPipelineiv", getProgramPipelineiv);
-        ASSIGN("glProgramUniform1i", programUniform1i);
-        ASSIGN("glProgramUniform2i", programUniform2i);
-        ASSIGN("glProgramUniform3i", programUniform3i);
-        ASSIGN("glProgramUniform4i", programUniform4i);
-        ASSIGN("glProgramUniform1ui", programUniform1ui);
-        ASSIGN("glProgramUniform2ui", programUniform2ui);
-        ASSIGN("glProgramUniform3ui", programUniform3ui);
-        ASSIGN("glProgramUniform4ui", programUniform4ui);
-        ASSIGN("glProgramUniform1f", programUniform1f);
-        ASSIGN("glProgramUniform2f", programUniform2f);
-        ASSIGN("glProgramUniform3f", programUniform3f);
-        ASSIGN("glProgramUniform4f", programUniform4f);
-        ASSIGN("glProgramUniform1iv", programUniform1iv);
-        ASSIGN("glProgramUniform2iv", programUniform2iv);
-        ASSIGN("glProgramUniform3iv", programUniform3iv);
-        ASSIGN("glProgramUniform4iv", programUniform4iv);
-        ASSIGN("glProgramUniform1uiv", programUniform1uiv);
-        ASSIGN("glProgramUniform2uiv", programUniform2uiv);
-        ASSIGN("glProgramUniform3uiv", programUniform3uiv);
-        ASSIGN("glProgramUniform4uiv", programUniform4uiv);
-        ASSIGN("glProgramUniform1fv", programUniform1fv);
-        ASSIGN("glProgramUniform2fv", programUniform2fv);
-        ASSIGN("glProgramUniform3fv", programUniform3fv);
-        ASSIGN("glProgramUniform4fv", programUniform4fv);
-        ASSIGN("glProgramUniformMatrix2fv", programUniformMatrix2fv);
-        ASSIGN("glProgramUniformMatrix3fv", programUniformMatrix3fv);
-        ASSIGN("glProgramUniformMatrix4fv", programUniformMatrix4fv);
-        ASSIGN("glProgramUniformMatrix2x3fv", programUniformMatrix2x3fv);
-        ASSIGN("glProgramUniformMatrix3x2fv", programUniformMatrix3x2fv);
-        ASSIGN("glProgramUniformMatrix2x4fv", programUniformMatrix2x4fv);
-        ASSIGN("glProgramUniformMatrix4x2fv", programUniformMatrix4x2fv);
-        ASSIGN("glProgramUniformMatrix3x4fv", programUniformMatrix3x4fv);
-        ASSIGN("glProgramUniformMatrix4x3fv", programUniformMatrix4x3fv);
-        ASSIGN("glValidateProgramPipeline", validateProgramPipeline);
-        ASSIGN("glGetProgramPipelineInfoLog", getProgramPipelineInfoLog);
-        ASSIGN("glBindImageTexture", bindImageTexture);
-        ASSIGN("glGetBooleani_v", getBooleani_v);
-        ASSIGN("glMemoryBarrier", memoryBarrier);
-        ASSIGN("glMemoryBarrierByRegion", memoryBarrierByRegion);
-        ASSIGN("glTexStorage2DMultisample", texStorage2DMultisample);
-        ASSIGN("glGetMultisamplefv", getMultisamplefv);
-        ASSIGN("glSampleMaski", sampleMaski);
-        ASSIGN("glGetTexLevelParameteriv", getTexLevelParameteriv);
-        ASSIGN("glGetTexLevelParameterfv", getTexLevelParameterfv);
-        ASSIGN("glBindVertexBuffer", bindVertexBuffer);
-        ASSIGN("glVertexAttribFormat", vertexAttribFormat);
-        ASSIGN("glVertexAttribIFormat", vertexAttribIFormat);
-        ASSIGN("glVertexAttribBinding", vertexAttribBinding);
-        ASSIGN("glVertexBindingDivisor", vertexBindingDivisor);
-    }
-
-    // 3.2
-    if (isAtLeastGLES(gl::Version(3, 2)))
-    {
-        ASSIGN("glBlendBarrier", blendBarrier);
-        ASSIGN("glCopyImageSubData", copyImageSubData);
-        ASSIGN("glDebugMessageControl", debugMessageControl);
-        ASSIGN("glDebugMessageInsert", debugMessageInsert);
-        ASSIGN("glDebugMessageCallback", debugMessageCallback);
-        ASSIGN("glGetDebugMessageLog", getDebugMessageLog);
-        ASSIGN("glPushDebugGroup", pushDebugGroup);
-        ASSIGN("glPopDebugGroup", popDebugGroup);
-        ASSIGN("glObjectLabel", objectLabel);
-        ASSIGN("glGetObjectLabel", getObjectLabel);
-        ASSIGN("glObjectPtrLabel", objectPtrLabel);
-        ASSIGN("glGetObjectPtrLabel", getObjectPtrLabel);
-        ASSIGN("glGetPointerv", getPointerv);
-        ASSIGN("glEnablei", enablei);
-        ASSIGN("glDisablei", disablei);
-        ASSIGN("glBlendEquationi", blendEquationi);
-        ASSIGN("glBlendEquationSeparatei", blendEquationSeparatei);
-        ASSIGN("glBlendFunci", blendFunci);
-        ASSIGN("glBlendFuncSeparatei", blendFuncSeparatei);
-        ASSIGN("glColorMaski", colorMaski);
-        ASSIGN("glIsEnabledi", isEnabledi);
-        ASSIGN("glDrawElementsBaseVertex", drawElementsBaseVertex);
-        ASSIGN("glDrawRangeElementsBaseVertex", drawRangeElementsBaseVertex);
-        ASSIGN("glDrawElementsInstancedBaseVertex", drawElementsInstancedBaseVertex);
-        ASSIGN("glFramebufferTexture", framebufferTexture);
-        ASSIGN("glPrimitiveBoundingBox", primitiveBoundingBox);
-        ASSIGN("glGetGraphicsResetStatus", getGraphicsResetStatus);
-        ASSIGN("glReadnPixels", readnPixels);
-        ASSIGN("glGetnUniformfv", getnUniformfv);
-        ASSIGN("glGetnUniformiv", getnUniformiv);
-        ASSIGN("glGetnUniformuiv", getnUniformuiv);
-        ASSIGN("glMinSampleShading", minSampleShading);
-        ASSIGN("glPatchParameteri", patchParameteri);
-        ASSIGN("glTexParameterIiv", texParameterIiv);
-        ASSIGN("glTexParameterIuiv", texParameterIuiv);
-        ASSIGN("glGetTexParameterIiv", getTexParameterIiv);
-        ASSIGN("glGetTexParameterIuiv", getTexParameterIuiv);
-        ASSIGN("glSamplerParameterIiv", samplerParameterIiv);
-        ASSIGN("glSamplerParameterIuiv", samplerParameterIuiv);
-        ASSIGN("glGetSamplerParameterIiv", getSamplerParameterIiv);
-        ASSIGN("glGetSamplerParameterIuiv", getSamplerParameterIuiv);
-        ASSIGN("glTexBuffer", texBuffer);
-        ASSIGN("glTexBufferRange", texBufferRange);
-        ASSIGN("glTexStorage3DMultisample", texStorage3DMultisample);
-    }
-
-    // clang-format on
 }
 
 bool FunctionsGL::isAtLeastGL(const gl::Version &glVersion) const
 {
     return standard == STANDARD_GL_DESKTOP && version >= glVersion;
 }
 
 bool FunctionsGL::isAtMostGL(const gl::Version &glVersion) const
@@ -2335,9 +227,44 @@ bool FunctionsGL::hasGLExtension(const s
     return standard == STANDARD_GL_DESKTOP && hasExtension(ext);
 }
 
 bool FunctionsGL::hasGLESExtension(const std::string &ext) const
 {
     return standard == STANDARD_GL_ES && hasExtension(ext);
 }
 
+#if defined(ANGLE_ENABLE_OPENGL_NULL)
+void FunctionsGL::initializeDummyFunctionsForNULLDriver(const std::set<std::string> &extensionSet)
+{
+    // This is a quick hack to get the NULL driver working, but we might want to implement a true
+    // NULL/stub driver that never calls into the OS. See Chromium's implementation in
+    // ui/gl/gl_stub_api.cc. This might be useful for testing things like perf scaling due to
+    // the caps returned by the drivers (i.e. number of texture units) or a true NULL back-end
+    // that could be used in a VM for things like fuzzing.
+    // TODO(jmadill): Implement true no-op/stub back-end.
+    ASSIGN("glGetString", getString);
+    ASSIGN("glGetStringi", getStringi);
+    ASSIGN("glGetIntegerv", getIntegerv);
+
+    getProgramiv           = &DummyGetProgramiv;
+    getShaderiv            = &DummyGetShaderiv;
+    checkFramebufferStatus = &DummyCheckFramebufferStatus;
+
+    if (isAtLeastGLES(gl::Version(3, 0)) || isAtLeastGL(gl::Version(4, 2)) ||
+        extensionSet.count("GL_ARB_internalformat_query") > 0)
+    {
+        ASSIGN("glGetInternalformativ", getInternalformativ);
+    }
+
+    if (isAtLeastGL(gl::Version(4, 3)))
+    {
+        ASSIGN("glGetInternalformati64v", getInternalformati64v);
+    }
+
+    if (extensionSet.count("GL_NV_internalformat_sample_query") > 0)
+    {
+        ASSIGN("glGetInternalformatSampleivNV", getInternalformatSampleivNV);
+    }
+}
+#endif  // defined(ANGLE_ENABLE_OPENGL_NULL)
+
 }  // namespace gl
--- a/gfx/angle/src/libANGLE/renderer/gl/FunctionsGL.h
+++ b/gfx/angle/src/libANGLE/renderer/gl/FunctionsGL.h
@@ -6,792 +6,57 @@
 
 // FunctionsGL.h: Defines the FuntionsGL class to contain loaded GL functions
 
 #ifndef LIBANGLE_RENDERER_GL_FUNCTIONSGL_H_
 #define LIBANGLE_RENDERER_GL_FUNCTIONSGL_H_
 
 #include "common/debug.h"
 #include "libANGLE/Version.h"
+#include "libANGLE/renderer/gl/DispatchTableGL_autogen.h"
 #include "libANGLE/renderer/gl/functionsgl_enums.h"
 #include "libANGLE/renderer/gl/functionsgl_typedefs.h"
 
+namespace egl
+{
+class AttributeMap;
+}  // namespace egl
+
 namespace rx
 {
 
 enum StandardGL
 {
     STANDARD_GL_DESKTOP,
     STANDARD_GL_ES,
 };
 
-class FunctionsGL
+class FunctionsGL : public DispatchTableGL
 {
   public:
     FunctionsGL();
-    virtual ~FunctionsGL();
+    ~FunctionsGL() override;
 
-    void initialize();
+    void initialize(const egl::AttributeMap &displayAttributes);
 
     // Version information
     gl::Version version;
     StandardGL standard;
     GLint profile;
     bool isAtLeastGL(const gl::Version &glVersion) const;
     bool isAtMostGL(const gl::Version &glVersion) const;
     bool isAtLeastGLES(const gl::Version &glesVersion) const;
     bool isAtMostGLES(const gl::Version &glesVersion) const;
 
     // Extensions
     std::vector<std::string> extensions;
     bool hasExtension(const std::string &ext) const;
     bool hasGLExtension(const std::string &ext) const;
     bool hasGLESExtension(const std::string &ext) const;
 
-    // Entry Points
-    // 1.0
-    PFNGLBLENDFUNCPROC blendFunc;
-    PFNGLCLEARPROC clear;
-    PFNGLCLEARCOLORPROC clearColor;
-    PFNGLCLEARDEPTHPROC clearDepth;
-    PFNGLCLEARSTENCILPROC clearStencil;
-    PFNGLCOLORMASKPROC colorMask;
-    PFNGLCULLFACEPROC cullFace;
-    PFNGLDEPTHFUNCPROC depthFunc;
-    PFNGLDEPTHMASKPROC depthMask;
-    PFNGLDEPTHRANGEPROC depthRange;
-    PFNGLDISABLEPROC disable;
-    PFNGLDRAWBUFFERPROC drawBuffer;
-    PFNGLENABLEPROC enable;
-    PFNGLFINISHPROC finish;
-    PFNGLFLUSHPROC flush;
-    PFNGLFRONTFACEPROC frontFace;
-    PFNGLGETBOOLEANVPROC getBooleanv;
-    PFNGLGETDOUBLEVPROC getDoublev;
-    PFNGLGETERRORPROC getError;
-    PFNGLGETFLOATVPROC getFloatv;
-    PFNGLGETINTEGERVPROC getIntegerv;
-    PFNGLGETSTRINGPROC getString;
-    PFNGLGETTEXIMAGEPROC getTexImage;
-    PFNGLGETTEXLEVELPARAMETERFVPROC getTexLevelParameterfv;
-    PFNGLGETTEXLEVELPARAMETERIVPROC getTexLevelParameteriv;
-    PFNGLGETTEXPARAMETERFVPROC getTexParameterfv;
-    PFNGLGETTEXPARAMETERIVPROC getTexParameteriv;
-    PFNGLHINTPROC hint;
-    PFNGLISENABLEDPROC isEnabled;
-    PFNGLLINEWIDTHPROC lineWidth;
-    PFNGLLOGICOPPROC logicOp;
-    PFNGLPIXELSTOREFPROC pixelStoref;
-    PFNGLPIXELSTOREIPROC pixelStorei;
-    PFNGLPOINTSIZEPROC pointSize;
-    PFNGLPOLYGONMODEPROC polygonMode;
-    PFNGLREADBUFFERPROC readBuffer;
-    PFNGLREADPIXELSPROC readPixels;
-    PFNGLSCISSORPROC scissor;
-    PFNGLSTENCILFUNCPROC stencilFunc;
-    PFNGLSTENCILMASKPROC stencilMask;
-    PFNGLSTENCILOPPROC stencilOp;
-    PFNGLTEXIMAGE1DPROC texImage1D;
-    PFNGLTEXIMAGE2DPROC texImage2D;
-    PFNGLTEXPARAMETERFPROC texParameterf;
-    PFNGLTEXPARAMETERFVPROC texParameterfv;
-    PFNGLTEXPARAMETERIPROC texParameteri;
-    PFNGLTEXPARAMETERIVPROC texParameteriv;
-    PFNGLVIEWPORTPROC viewport;
-
-    // 1.1
-    PFNGLBINDTEXTUREPROC bindTexture;
-    PFNGLCOPYTEXIMAGE1DPROC copyTexImage1D;
-    PFNGLCOPYTEXIMAGE2DPROC copyTexImage2D;
-    PFNGLCOPYTEXSUBIMAGE1DPROC copyTexSubImage1D;
-    PFNGLCOPYTEXSUBIMAGE2DPROC copyTexSubImage2D;
-    PFNGLDELETETEXTURESPROC deleteTextures;
-    PFNGLDRAWARRAYSPROC drawArrays;
-    PFNGLDRAWELEMENTSPROC drawElements;
-    PFNGLGENTEXTURESPROC genTextures;
-    PFNGLISTEXTUREPROC isTexture;
-    PFNGLPOLYGONOFFSETPROC polygonOffset;
-    PFNGLTEXSUBIMAGE1DPROC texSubImage1D;
-    PFNGLTEXSUBIMAGE2DPROC texSubImage2D;
-
-    // 1.2
-    PFNGLBLENDCOLORPROC blendColor;
-    PFNGLBLENDEQUATIONPROC blendEquation;
-    PFNGLCOPYTEXSUBIMAGE3DPROC copyTexSubImage3D;
-    PFNGLDRAWRANGEELEMENTSPROC drawRangeElements;
-    PFNGLTEXIMAGE3DPROC texImage3D;
-    PFNGLTEXSUBIMAGE3DPROC texSubImage3D;
-
-    // 1.2 Extensions
-    PFNGLDELETEFENCESNVPROC deleteFencesNV;
-    PFNGLGENFENCESNVPROC genFencesNV;
-    PFNGLISFENCENVPROC isFenceNV;
-    PFNGLTESTFENCENVPROC testFenceNV;
-    PFNGLGETFENCEIVNVPROC getFenceivNV;
-    PFNGLFINISHFENCENVPROC finishFenceNV;
-    PFNGLSETFENCENVPROC setFenceNV;
-
-    // 1.3
-    PFNGLACTIVETEXTUREPROC activeTexture;
-    PFNGLCOMPRESSEDTEXIMAGE1DPROC compressedTexImage1D;
-    PFNGLCOMPRESSEDTEXIMAGE2DPROC compressedTexImage2D;
-    PFNGLCOMPRESSEDTEXIMAGE3DPROC compressedTexImage3D;
-    PFNGLCOMPRESSEDTEXSUBIMAGE1DPROC compressedTexSubImage1D;
-    PFNGLCOMPRESSEDTEXSUBIMAGE2DPROC compressedTexSubImage2D;
-    PFNGLCOMPRESSEDTEXSUBIMAGE3DPROC compressedTexSubImage3D;
-    PFNGLGETCOMPRESSEDTEXIMAGEPROC getCompressedTexImage;
-    PFNGLSAMPLECOVERAGEPROC sampleCoverage;
-
-    // 1.4
-    PFNGLBLENDFUNCSEPARATEPROC blendFuncSeparate;
-    PFNGLMULTIDRAWARRAYSPROC multiDrawArrays;
-    PFNGLMULTIDRAWELEMENTSPROC multiDrawElements;
-    PFNGLPOINTPARAMETERFPROC pointParameterf;
-    PFNGLPOINTPARAMETERFVPROC pointParameterfv;
-    PFNGLPOINTPARAMETERIPROC pointParameteri;
-    PFNGLPOINTPARAMETERIVPROC pointParameteriv;
-
-    // 1.5
-    PFNGLBEGINQUERYPROC beginQuery;
-    PFNGLBINDBUFFERPROC bindBuffer;
-    PFNGLBUFFERDATAPROC bufferData;
-    PFNGLBUFFERSUBDATAPROC bufferSubData;
-    PFNGLDELETEBUFFERSPROC deleteBuffers;
-    PFNGLDELETEQUERIESPROC deleteQueries;
-    PFNGLENDQUERYPROC endQuery;
-    PFNGLGENBUFFERSPROC genBuffers;
-    PFNGLGENQUERIESPROC genQueries;
-    PFNGLGETBUFFERPARAMETERIVPROC getBufferParameteriv;
-    PFNGLGETBUFFERPOINTERVPROC getBufferPointerv;
-    PFNGLGETBUFFERSUBDATAPROC getBufferSubData;
-    PFNGLGETQUERYOBJECTIVPROC getQueryObjectiv;
-    PFNGLGETQUERYOBJECTUIVPROC getQueryObjectuiv;
-    PFNGLGETQUERYIVPROC getQueryiv;
-    PFNGLISBUFFERPROC isBuffer;
-    PFNGLISQUERYPROC isQuery;
-    PFNGLMAPBUFFERPROC mapBuffer;
-    PFNGLUNMAPBUFFERPROC unmapBuffer;
-
-    // 2.0
-    PFNGLATTACHSHADERPROC attachShader;
-    PFNGLBINDATTRIBLOCATIONPROC bindAttribLocation;
-    PFNGLBLENDEQUATIONSEPARATEPROC blendEquationSeparate;
-    PFNGLCOMPILESHADERPROC compileShader;
-    PFNGLCREATEPROGRAMPROC createProgram;
-    PFNGLCREATESHADERPROC createShader;
-    PFNGLDELETEPROGRAMPROC deleteProgram;
-    PFNGLDELETESHADERPROC deleteShader;
-    PFNGLDETACHSHADERPROC detachShader;
-    PFNGLDISABLEVERTEXATTRIBARRAYPROC disableVertexAttribArray;
-    PFNGLDRAWBUFFERSPROC drawBuffers;
-    PFNGLENABLEVERTEXATTRIBARRAYPROC enableVertexAttribArray;
-    PFNGLGETACTIVEATTRIBPROC getActiveAttrib;
-    PFNGLGETACTIVEUNIFORMPROC getActiveUniform;
-    PFNGLGETATTACHEDSHADERSPROC getAttachedShaders;
-    PFNGLGETATTRIBLOCATIONPROC getAttribLocation;
-    PFNGLGETPROGRAMINFOLOGPROC getProgramInfoLog;
-    PFNGLGETPROGRAMIVPROC getProgramiv;
-    PFNGLGETSHADERINFOLOGPROC getShaderInfoLog;
-    PFNGLGETSHADERSOURCEPROC getShaderSource;
-    PFNGLGETSHADERIVPROC getShaderiv;
-    PFNGLGETUNIFORMLOCATIONPROC getUniformLocation;
-    PFNGLGETUNIFORMFVPROC getUniformfv;
-    PFNGLGETUNIFORMIVPROC getUniformiv;
-    PFNGLGETVERTEXATTRIBPOINTERVPROC getVertexAttribPointerv;
-    PFNGLGETVERTEXATTRIBDVPROC getVertexAttribdv;
-    PFNGLGETVERTEXATTRIBFVPROC getVertexAttribfv;
-    PFNGLGETVERTEXATTRIBIVPROC getVertexAttribiv;
-    PFNGLISPROGRAMPROC isProgram;
-    PFNGLISSHADERPROC isShader;
-    PFNGLLINKPROGRAMPROC linkProgram;
-    PFNGLSHADERSOURCEPROC shaderSource;
-    PFNGLSTENCILFUNCSEPARATEPROC stencilFuncSeparate;
-    PFNGLSTENCILMASKSEPARATEPROC stencilMaskSeparate;
-    PFNGLSTENCILOPSEPARATEPROC stencilOpSeparate;
-    PFNGLUNIFORM1FPROC uniform1f;
-    PFNGLUNIFORM1FVPROC uniform1fv;
-    PFNGLUNIFORM1IPROC uniform1i;
-    PFNGLUNIFORM1IVPROC uniform1iv;
-    PFNGLUNIFORM2FPROC uniform2f;
-    PFNGLUNIFORM2FVPROC uniform2fv;
-    PFNGLUNIFORM2IPROC uniform2i;
-    PFNGLUNIFORM2IVPROC uniform2iv;
-    PFNGLUNIFORM3FPROC uniform3f;
-    PFNGLUNIFORM3FVPROC uniform3fv;
-    PFNGLUNIFORM3IPROC uniform3i;
-    PFNGLUNIFORM3IVPROC uniform3iv;
-    PFNGLUNIFORM4FPROC uniform4f;
-    PFNGLUNIFORM4FVPROC uniform4fv;
-    PFNGLUNIFORM4IPROC uniform4i;
-    PFNGLUNIFORM4IVPROC uniform4iv;
-    PFNGLUNIFORMMATRIX2FVPROC uniformMatrix2fv;
-    PFNGLUNIFORMMATRIX3FVPROC uniformMatrix3fv;
-    PFNGLUNIFORMMATRIX4FVPROC uniformMatrix4fv;
-    PFNGLUSEPROGRAMPROC useProgram;
-    PFNGLVALIDATEPROGRAMPROC validateProgram;
-    PFNGLVERTEXATTRIB1DPROC vertexAttrib1d;
-    PFNGLVERTEXATTRIB1DVPROC vertexAttrib1dv;
-    PFNGLVERTEXATTRIB1FPROC vertexAttrib1f;
-    PFNGLVERTEXATTRIB1FVPROC vertexAttrib1fv;
-    PFNGLVERTEXATTRIB1SPROC vertexAttrib1s;
-    PFNGLVERTEXATTRIB1SVPROC vertexAttrib1sv;
-    PFNGLVERTEXATTRIB2DPROC vertexAttrib2d;
-    PFNGLVERTEXATTRIB2DVPROC vertexAttrib2dv;
-    PFNGLVERTEXATTRIB2FPROC vertexAttrib2f;
-    PFNGLVERTEXATTRIB2FVPROC vertexAttrib2fv;
-    PFNGLVERTEXATTRIB2SPROC vertexAttrib2s;
-    PFNGLVERTEXATTRIB2SVPROC vertexAttrib2sv;
-    PFNGLVERTEXATTRIB3DPROC vertexAttrib3d;
-    PFNGLVERTEXATTRIB3DVPROC vertexAttrib3dv;
-    PFNGLVERTEXATTRIB3FPROC vertexAttrib3f;
-    PFNGLVERTEXATTRIB3FVPROC vertexAttrib3fv;
-    PFNGLVERTEXATTRIB3SPROC vertexAttrib3s;
-    PFNGLVERTEXATTRIB3SVPROC vertexAttrib3sv;
-    PFNGLVERTEXATTRIB4NBVPROC vertexAttrib4Nbv;
-    PFNGLVERTEXATTRIB4NIVPROC vertexAttrib4Niv;
-    PFNGLVERTEXATTRIB4NSVPROC vertexAttrib4Nsv;
-    PFNGLVERTEXATTRIB4NUBPROC vertexAttrib4Nub;
-    PFNGLVERTEXATTRIB4NUBVPROC vertexAttrib4Nubv;
-    PFNGLVERTEXATTRIB4NUIVPROC vertexAttrib4Nuiv;
-    PFNGLVERTEXATTRIB4NUSVPROC vertexAttrib4Nusv;
-    PFNGLVERTEXATTRIB4BVPROC vertexAttrib4bv;
-    PFNGLVERTEXATTRIB4DPROC vertexAttrib4d;
-    PFNGLVERTEXATTRIB4DVPROC vertexAttrib4dv;
-    PFNGLVERTEXATTRIB4FPROC vertexAttrib4f;
-    PFNGLVERTEXATTRIB4FVPROC vertexAttrib4fv;
-    PFNGLVERTEXATTRIB4IVPROC vertexAttrib4iv;
-    PFNGLVERTEXATTRIB4SPROC vertexAttrib4s;
-    PFNGLVERTEXATTRIB4SVPROC vertexAttrib4sv;
-    PFNGLVERTEXATTRIB4UBVPROC vertexAttrib4ubv;
-    PFNGLVERTEXATTRIB4UIVPROC vertexAttrib4uiv;
-    PFNGLVERTEXATTRIB4USVPROC vertexAttrib4usv;
-    PFNGLVERTEXATTRIBPOINTERPROC vertexAttribPointer;
-
-    // 2.1
-    PFNGLUNIFORMMATRIX2X3FVPROC uniformMatrix2x3fv;
-    PFNGLUNIFORMMATRIX2X4FVPROC uniformMatrix2x4fv;
-    PFNGLUNIFORMMATRIX3X2FVPROC uniformMatrix3x2fv;
-    PFNGLUNIFORMMATRIX3X4FVPROC uniformMatrix3x4fv;
-    PFNGLUNIFORMMATRIX4X2FVPROC uniformMatrix4x2fv;
-    PFNGLUNIFORMMATRIX4X3FVPROC uniformMatrix4x3fv;
-
-    // 3.0
-    PFNGLBEGINCONDITIONALRENDERPROC beginConditionalRender;
-    PFNGLBEGINTRANSFORMFEEDBACKPROC beginTransformFeedback;
-    PFNGLBINDBUFFERBASEPROC bindBufferBase;
-    PFNGLBINDBUFFERRANGEPROC bindBufferRange;
-    PFNGLBINDFRAGDATALOCATIONPROC bindFragDataLocation;
-    PFNGLBINDFRAMEBUFFERPROC bindFramebuffer;
-    PFNGLBINDRENDERBUFFERPROC bindRenderbuffer;
-    PFNGLBINDVERTEXARRAYPROC bindVertexArray;
-    PFNGLBLITFRAMEBUFFERPROC blitFramebuffer;
-    PFNGLCHECKFRAMEBUFFERSTATUSPROC checkFramebufferStatus;
-    PFNGLCLAMPCOLORPROC clampColor;
-    PFNGLCLEARBUFFERFIPROC clearBufferfi;
-    PFNGLCLEARBUFFERFVPROC clearBufferfv;
-    PFNGLCLEARBUFFERIVPROC clearBufferiv;
-    PFNGLCLEARBUFFERUIVPROC clearBufferuiv;
-    PFNGLCOLORMASKIPROC colorMaski;
-    PFNGLDELETEFRAMEBUFFERSPROC deleteFramebuffers;
-    PFNGLDELETERENDERBUFFERSPROC deleteRenderbuffers;
-    PFNGLDELETEVERTEXARRAYSPROC deleteVertexArrays;
-    PFNGLDISABLEIPROC disablei;
-    PFNGLENABLEIPROC enablei;
-    PFNGLENDCONDITIONALRENDERPROC endConditionalRender;
-    PFNGLENDTRANSFORMFEEDBACKPROC endTransformFeedback;
-    PFNGLFLUSHMAPPEDBUFFERRANGEPROC flushMappedBufferRange;
-    PFNGLFRAMEBUFFERRENDERBUFFERPROC framebufferRenderbuffer;
-    PFNGLFRAMEBUFFERTEXTURE1DPROC framebufferTexture1D;
-    PFNGLFRAMEBUFFERTEXTURE2DPROC framebufferTexture2D;
-    PFNGLFRAMEBUFFERTEXTURE3DPROC framebufferTexture3D;
-    PFNGLFRAMEBUFFERTEXTURELAYERPROC framebufferTextureLayer;
-    PFNGLGENFRAMEBUFFERSPROC genFramebuffers;
-    PFNGLGENRENDERBUFFERSPROC genRenderbuffers;
-    PFNGLGENVERTEXARRAYSPROC genVertexArrays;
-    PFNGLGENERATEMIPMAPPROC generateMipmap;
-    PFNGLGETBOOLEANI_VPROC getBooleani_v;
-    PFNGLGETFRAGDATALOCATIONPROC getFragDataLocation;
-    PFNGLGETFRAMEBUFFERATTACHMENTPARAMETERIVPROC getFramebufferAttachmentParameteriv;
-    PFNGLGETINTEGERI_VPROC getIntegeri_v;
-    PFNGLGETRENDERBUFFERPARAMETERIVPROC getRenderbufferParameteriv;
-    PFNGLGETSTRINGIPROC getStringi;
-    PFNGLGETTEXPARAMETERIIVPROC getTexParameterIiv;
-    PFNGLGETTEXPARAMETERIUIVPROC getTexParameterIuiv;
-    PFNGLGETTRANSFORMFEEDBACKVARYINGPROC getTransformFeedbackVarying;
-    PFNGLGETUNIFORMUIVPROC getUniformuiv;
-    PFNGLGETVERTEXATTRIBIIVPROC getVertexAttribIiv;
-    PFNGLGETVERTEXATTRIBIUIVPROC getVertexAttribIuiv;
-    PFNGLISENABLEDIPROC isEnabledi;
-    PFNGLISFRAMEBUFFERPROC isFramebuffer;
-    PFNGLISRENDERBUFFERPROC isRenderbuffer;
-    PFNGLISVERTEXARRAYPROC isVertexArray;
-    PFNGLMAPBUFFERRANGEPROC mapBufferRange;
-    PFNGLRENDERBUFFERSTORAGEPROC renderbufferStorage;
-    PFNGLRENDERBUFFERSTORAGEMULTISAMPLEPROC renderbufferStorageMultisample;
-    PFNGLTEXPARAMETERIIVPROC texParameterIiv;
-    PFNGLTEXPARAMETERIUIVPROC texParameterIuiv;
-    PFNGLTRANSFORMFEEDBACKVARYINGSPROC transformFeedbackVaryings;
-    PFNGLUNIFORM1UIPROC uniform1ui;
-    PFNGLUNIFORM1UIVPROC uniform1uiv;
-    PFNGLUNIFORM2UIPROC uniform2ui;
-    PFNGLUNIFORM2UIVPROC uniform2uiv;
-    PFNGLUNIFORM3UIPROC uniform3ui;
-    PFNGLUNIFORM3UIVPROC uniform3uiv;
-    PFNGLUNIFORM4UIPROC uniform4ui;
-    PFNGLUNIFORM4UIVPROC uniform4uiv;
-    PFNGLVERTEXATTRIBI1IPROC vertexAttribI1i;
-    PFNGLVERTEXATTRIBI1IVPROC vertexAttribI1iv;
-    PFNGLVERTEXATTRIBI1UIPROC vertexAttribI1ui;
-    PFNGLVERTEXATTRIBI1UIVPROC vertexAttribI1uiv;
-    PFNGLVERTEXATTRIBI2IPROC vertexAttribI2i;
-    PFNGLVERTEXATTRIBI2IVPROC vertexAttribI2iv;
-    PFNGLVERTEXATTRIBI2UIPROC vertexAttribI2ui;
-    PFNGLVERTEXATTRIBI2UIVPROC vertexAttribI2uiv;
-    PFNGLVERTEXATTRIBI3IPROC vertexAttribI3i;
-    PFNGLVERTEXATTRIBI3IVPROC vertexAttribI3iv;
-    PFNGLVERTEXATTRIBI3UIPROC vertexAttribI3ui;
-    PFNGLVERTEXATTRIBI3UIVPROC vertexAttribI3uiv;
-    PFNGLVERTEXATTRIBI4BVPROC vertexAttribI4bv;
-    PFNGLVERTEXATTRIBI4IPROC vertexAttribI4i;
-    PFNGLVERTEXATTRIBI4IVPROC vertexAttribI4iv;
-    PFNGLVERTEXATTRIBI4SVPROC vertexAttribI4sv;
-    PFNGLVERTEXATTRIBI4UBVPROC vertexAttribI4ubv;
-    PFNGLVERTEXATTRIBI4UIPROC vertexAttribI4ui;
-    PFNGLVERTEXATTRIBI4UIVPROC vertexAttribI4uiv;
-    PFNGLVERTEXATTRIBI4USVPROC vertexAttribI4usv;
-    PFNGLVERTEXATTRIBIPOINTERPROC vertexAttribIPointer;
-
-    // 3.1
-    PFNGLCOPYBUFFERSUBDATAPROC copyBufferSubData;
-    PFNGLDRAWARRAYSINSTANCEDPROC drawArraysInstanced;
-    PFNGLDRAWELEMENTSINSTANCEDPROC drawElementsInstanced;
-    PFNGLGETACTIVEUNIFORMBLOCKNAMEPROC getActiveUniformBlockName;
-    PFNGLGETACTIVEUNIFORMBLOCKIVPROC getActiveUniformBlockiv;
-    PFNGLGETACTIVEUNIFORMNAMEPROC getActiveUniformName;
-    PFNGLGETACTIVEUNIFORMSIVPROC getActiveUniformsiv;
-    PFNGLGETUNIFORMBLOCKINDEXPROC getUniformBlockIndex;
-    PFNGLGETUNIFORMINDICESPROC getUniformIndices;
-    PFNGLPRIMITIVERESTARTINDEXPROC primitiveRestartIndex;
-    PFNGLTEXBUFFERPROC texBuffer;
-    PFNGLUNIFORMBLOCKBINDINGPROC uniformBlockBinding;
-
-    // 3.2
-    PFNGLCLIENTWAITSYNCPROC clientWaitSync;
-    PFNGLDELETESYNCPROC deleteSync;
-    PFNGLDRAWELEMENTSBASEVERTEXPROC drawElementsBaseVertex;
-    PFNGLDRAWELEMENTSINSTANCEDBASEVERTEXPROC drawElementsInstancedBaseVertex;
-    PFNGLDRAWRANGEELEMENTSBASEVERTEXPROC drawRangeElementsBaseVertex;
-    PFNGLFENCESYNCPROC fenceSync;
-    PFNGLFRAMEBUFFERTEXTUREPROC framebufferTexture;
-    PFNGLGETBUFFERPARAMETERI64VPROC getBufferParameteri64v;
-    PFNGLGETINTEGER64I_VPROC getInteger64i_v;
-    PFNGLGETINTEGER64VPROC getInteger64v;
-    PFNGLGETMULTISAMPLEFVPROC getMultisamplefv;
-    PFNGLGETSYNCIVPROC getSynciv;
-    PFNGLISSYNCPROC isSync;
-    PFNGLMULTIDRAWELEMENTSBASEVERTEXPROC multiDrawElementsBaseVertex;
-    PFNGLPROVOKINGVERTEXPROC provokingVertex;
-    PFNGLSAMPLEMASKIPROC sampleMaski;
-    PFNGLTEXIMAGE2DMULTISAMPLEPROC texImage2DMultisample;
-    PFNGLTEXIMAGE3DMULTISAMPLEPROC texImage3DMultisample;
-    PFNGLWAITSYNCPROC waitSync;
-
-    // NV_path_rendering (originally written against 3.2 compatibility profile)
-    PFNGLMATRIXLOADFEXTPROC matrixLoadEXT;
-    PFNGLGENPATHSNVPROC genPathsNV;
-    PFNGLDELETEPATHSNVPROC delPathsNV;
-    PFNGLPATHCOMMANDSNVPROC pathCommandsNV;
-    PFNGLISPATHNVPROC isPathNV;
-    PFNGLPATHPARAMETERFNVPROC setPathParameterfNV;
-    PFNGLPATHPARAMETERINVPROC setPathParameteriNV;
-    PFNGLGETPATHPARAMETERFVNVPROC getPathParameterfNV;
-    PFNGLGETPATHPARAMETERIVNVPROC getPathParameteriNV;
-    PFNGLPATHSTENCILFUNCNVPROC pathStencilFuncNV;
-    PFNGLSTENCILFILLPATHNVPROC stencilFillPathNV;
-    PFNGLSTENCILSTROKEPATHNVPROC stencilStrokePathNV;
-    PFNGLCOVERFILLPATHNVPROC coverFillPathNV;
-    PFNGLCOVERSTROKEPATHNVPROC coverStrokePathNV;
-    PFNGLSTENCILTHENCOVERFILLPATHNVPROC stencilThenCoverFillPathNV;
-    PFNGLSTENCILTHENCOVERSTROKEPATHNVPROC stencilThenCoverStrokePathNV;
-    PFNGLCOVERFILLPATHINSTANCEDNVPROC coverFillPathInstancedNV;
-    PFNGLCOVERSTROKEPATHINSTANCEDNVPROC coverStrokePathInstancedNV;
-    PFNGLSTENCILFILLPATHINSTANCEDNVPROC stencilFillPathInstancedNV;
-    PFNGLSTENCILSTROKEPATHINSTANCEDNVPROC stencilStrokePathInstancedNV;
-    PFNGLSTENCILTHENCOVERFILLPATHINSTANCEDNVPROC stencilThenCoverFillPathInstancedNV;
-    PFNGLSTENCILTHENCOVERSTROKEPATHINSTANCEDNVPROC stencilThenCoverStrokePathInstancedNV;
-    PFNGLPROGRAMPATHFRAGMENTINPUTGENNVPROC programPathFragmentInputGenNV;
-
-    // 3.3
-    PFNGLBINDFRAGDATALOCATIONINDEXEDPROC bindFragDataLocationIndexed;
-    PFNGLBINDSAMPLERPROC bindSampler;
-    PFNGLDELETESAMPLERSPROC deleteSamplers;
-    PFNGLGENSAMPLERSPROC genSamplers;
-    PFNGLGETFRAGDATAINDEXPROC getFragDataIndex;
-    PFNGLGETQUERYOBJECTI64VPROC getQueryObjecti64v;
-    PFNGLGETQUERYOBJECTUI64VPROC getQueryObjectui64v;
-    PFNGLGETSAMPLERPARAMETERIIVPROC getSamplerParameterIiv;
-    PFNGLGETSAMPLERPARAMETERIUIVPROC getSamplerParameterIuiv;
-    PFNGLGETSAMPLERPARAMETERFVPROC getSamplerParameterfv;
-    PFNGLGETSAMPLERPARAMETERIVPROC getSamplerParameteriv;
-    PFNGLISSAMPLERPROC isSampler;
-    PFNGLQUERYCOUNTERPROC queryCounter;
-    PFNGLSAMPLERPARAMETERIIVPROC samplerParameterIiv;
-    PFNGLSAMPLERPARAMETERIUIVPROC samplerParameterIuiv;
-    PFNGLSAMPLERPARAMETERFPROC samplerParameterf;
-    PFNGLSAMPLERPARAMETERFVPROC samplerParameterfv;
-    PFNGLSAMPLERPARAMETERIPROC samplerParameteri;
-    PFNGLSAMPLERPARAMETERIVPROC samplerParameteriv;
-    PFNGLVERTEXATTRIBDIVISORPROC vertexAttribDivisor;
-    PFNGLVERTEXATTRIBP1UIPROC vertexAttribP1ui;
-    PFNGLVERTEXATTRIBP1UIVPROC vertexAttribP1uiv;
-    PFNGLVERTEXATTRIBP2UIPROC vertexAttribP2ui;
-    PFNGLVERTEXATTRIBP2UIVPROC vertexAttribP2uiv;
-    PFNGLVERTEXATTRIBP3UIPROC vertexAttribP3ui;
-    PFNGLVERTEXATTRIBP3UIVPROC vertexAttribP3uiv;
-    PFNGLVERTEXATTRIBP4UIPROC vertexAttribP4ui;
-    PFNGLVERTEXATTRIBP4UIVPROC vertexAttribP4uiv;
-
-    // 4.0
-    PFNGLBEGINQUERYINDEXEDPROC beginQueryIndexed;
-    PFNGLBINDTRANSFORMFEEDBACKPROC bindTransformFeedback;
-    PFNGLBLENDEQUATIONSEPARATEIPROC blendEquationSeparatei;
-    PFNGLBLENDEQUATIONIPROC blendEquationi;
-    PFNGLBLENDFUNCSEPARATEIPROC blendFuncSeparatei;
-    PFNGLBLENDFUNCIPROC blendFunci;
-    PFNGLDELETETRANSFORMFEEDBACKSPROC deleteTransformFeedbacks;
-    PFNGLDRAWARRAYSINDIRECTPROC drawArraysIndirect;
-    PFNGLDRAWELEMENTSINDIRECTPROC drawElementsIndirect;
-    PFNGLDRAWTRANSFORMFEEDBACKPROC drawTransformFeedback;
-    PFNGLDRAWTRANSFORMFEEDBACKSTREAMPROC drawTransformFeedbackStream;
-    PFNGLENDQUERYINDEXEDPROC endQueryIndexed;
-    PFNGLGENTRANSFORMFEEDBACKSPROC genTransformFeedbacks;
-    PFNGLGETACTIVESUBROUTINENAMEPROC getActiveSubroutineName;
-    PFNGLGETACTIVESUBROUTINEUNIFORMNAMEPROC getActiveSubroutineUniformName;
-    PFNGLGETACTIVESUBROUTINEUNIFORMIVPROC getActiveSubroutineUniformiv;
-    PFNGLGETPROGRAMSTAGEIVPROC getProgramStageiv;
-    PFNGLGETQUERYINDEXEDIVPROC getQueryIndexediv;
-    PFNGLGETSUBROUTINEINDEXPROC getSubroutineIndex;
-    PFNGLGETSUBROUTINEUNIFORMLOCATIONPROC getSubroutineUniformLocation;
-    PFNGLGETUNIFORMSUBROUTINEUIVPROC getUniformSubroutineuiv;
-    PFNGLGETUNIFORMDVPROC getUniformdv;
-    PFNGLISTRANSFORMFEEDBACKPROC isTransformFeedback;
-    PFNGLMINSAMPLESHADINGPROC minSampleShading;
-    PFNGLPATCHPARAMETERFVPROC patchParameterfv;
-    PFNGLPATCHPARAMETERIPROC patchParameteri;
-    PFNGLPAUSETRANSFORMFEEDBACKPROC pauseTransformFeedback;
-    PFNGLRESUMETRANSFORMFEEDBACKPROC resumeTransformFeedback;
-    PFNGLUNIFORM1DPROC uniform1d;
-    PFNGLUNIFORM1DVPROC uniform1dv;
-    PFNGLUNIFORM2DPROC uniform2d;
-    PFNGLUNIFORM2DVPROC uniform2dv;
-    PFNGLUNIFORM3DPROC uniform3d;
-    PFNGLUNIFORM3DVPROC uniform3dv;
-    PFNGLUNIFORM4DPROC uniform4d;
-    PFNGLUNIFORM4DVPROC uniform4dv;
-    PFNGLUNIFORMMATRIX2DVPROC uniformMatrix2dv;
-    PFNGLUNIFORMMATRIX2X3DVPROC uniformMatrix2x3dv;
-    PFNGLUNIFORMMATRIX2X4DVPROC uniformMatrix2x4dv;
-    PFNGLUNIFORMMATRIX3DVPROC uniformMatrix3dv;
-    PFNGLUNIFORMMATRIX3X2DVPROC uniformMatrix3x2dv;
-    PFNGLUNIFORMMATRIX3X4DVPROC uniformMatrix3x4dv;
-    PFNGLUNIFORMMATRIX4DVPROC uniformMatrix4dv;
-    PFNGLUNIFORMMATRIX4X2DVPROC uniformMatrix4x2dv;
-    PFNGLUNIFORMMATRIX4X3DVPROC uniformMatrix4x3dv;
-    PFNGLUNIFORMSUBROUTINESUIVPROC uniformSubroutinesuiv;
-
-    // 4.1
-    PFNGLACTIVESHADERPROGRAMPROC activeShaderProgram;
-    PFNGLBINDPROGRAMPIPELINEPROC bindProgramPipeline;
-    PFNGLCLEARDEPTHFPROC clearDepthf;
-    PFNGLCREATESHADERPROGRAMVPROC createShaderProgramv;
-    PFNGLDELETEPROGRAMPIPELINESPROC deleteProgramPipelines;
-    PFNGLDEPTHRANGEARRAYVPROC depthRangeArrayv;
-    PFNGLDEPTHRANGEINDEXEDPROC depthRangeIndexed;
-    PFNGLDEPTHRANGEFPROC depthRangef;
-    PFNGLGENPROGRAMPIPELINESPROC genProgramPipelines;
-    PFNGLGETDOUBLEI_VPROC getDoublei_v;
-    PFNGLGETFLOATI_VPROC getFloati_v;
-    PFNGLGETPROGRAMBINARYPROC getProgramBinary;
-    PFNGLGETPROGRAMPIPELINEINFOLOGPROC getProgramPipelineInfoLog;
-    PFNGLGETPROGRAMPIPELINEIVPROC getProgramPipelineiv;
-    PFNGLGETSHADERPRECISIONFORMATPROC getShaderPrecisionFormat;
-    PFNGLGETVERTEXATTRIBLDVPROC getVertexAttribLdv;
-    PFNGLISPROGRAMPIPELINEPROC isProgramPipeline;
-    PFNGLPROGRAMBINARYPROC programBinary;
-    PFNGLPROGRAMPARAMETERIPROC programParameteri;
-    PFNGLPROGRAMUNIFORM1DPROC programUniform1d;
-    PFNGLPROGRAMUNIFORM1DVPROC programUniform1dv;
-    PFNGLPROGRAMUNIFORM1FPROC programUniform1f;
-    PFNGLPROGRAMUNIFORM1FVPROC programUniform1fv;
-    PFNGLPROGRAMUNIFORM1IPROC programUniform1i;
-    PFNGLPROGRAMUNIFORM1IVPROC programUniform1iv;
-    PFNGLPROGRAMUNIFORM1UIPROC programUniform1ui;
-    PFNGLPROGRAMUNIFORM1UIVPROC programUniform1uiv;
-    PFNGLPROGRAMUNIFORM2DPROC programUniform2d;
-    PFNGLPROGRAMUNIFORM2DVPROC programUniform2dv;
-    PFNGLPROGRAMUNIFORM2FPROC programUniform2f;
-    PFNGLPROGRAMUNIFORM2FVPROC programUniform2fv;
-    PFNGLPROGRAMUNIFORM2IPROC programUniform2i;
-    PFNGLPROGRAMUNIFORM2IVPROC programUniform2iv;
-    PFNGLPROGRAMUNIFORM2UIPROC programUniform2ui;
-    PFNGLPROGRAMUNIFORM2UIVPROC programUniform2uiv;
-    PFNGLPROGRAMUNIFORM3DPROC programUniform3d;
-    PFNGLPROGRAMUNIFORM3DVPROC programUniform3dv;
-    PFNGLPROGRAMUNIFORM3FPROC programUniform3f;
-    PFNGLPROGRAMUNIFORM3FVPROC programUniform3fv;
-    PFNGLPROGRAMUNIFORM3IPROC programUniform3i;
-    PFNGLPROGRAMUNIFORM3IVPROC programUniform3iv;
-    PFNGLPROGRAMUNIFORM3UIPROC programUniform3ui;
-    PFNGLPROGRAMUNIFORM3UIVPROC programUniform3uiv;
-    PFNGLPROGRAMUNIFORM4DPROC programUniform4d;
-    PFNGLPROGRAMUNIFORM4DVPROC programUniform4dv;
-    PFNGLPROGRAMUNIFORM4FPROC programUniform4f;
-    PFNGLPROGRAMUNIFORM4FVPROC programUniform4fv;
-    PFNGLPROGRAMUNIFORM4IPROC programUniform4i;
-    PFNGLPROGRAMUNIFORM4IVPROC programUniform4iv;
-    PFNGLPROGRAMUNIFORM4UIPROC programUniform4ui;
-    PFNGLPROGRAMUNIFORM4UIVPROC programUniform4uiv;
-    PFNGLPROGRAMUNIFORMMATRIX2DVPROC programUniformMatrix2dv;
-    PFNGLPROGRAMUNIFORMMATRIX2FVPROC programUniformMatrix2fv;
-    PFNGLPROGRAMUNIFORMMATRIX2X3DVPROC programUniformMatrix2x3dv;
-    PFNGLPROGRAMUNIFORMMATRIX2X3FVPROC programUniformMatrix2x3fv;
-    PFNGLPROGRAMUNIFORMMATRIX2X4DVPROC programUniformMatrix2x4dv;
-    PFNGLPROGRAMUNIFORMMATRIX2X4FVPROC programUniformMatrix2x4fv;
-    PFNGLPROGRAMUNIFORMMATRIX3DVPROC programUniformMatrix3dv;
-    PFNGLPROGRAMUNIFORMMATRIX3FVPROC programUniformMatrix3fv;
-    PFNGLPROGRAMUNIFORMMATRIX3X2DVPROC programUniformMatrix3x2dv;
-    PFNGLPROGRAMUNIFORMMATRIX3X2FVPROC programUniformMatrix3x2fv;
-    PFNGLPROGRAMUNIFORMMATRIX3X4DVPROC programUniformMatrix3x4dv;
-    PFNGLPROGRAMUNIFORMMATRIX3X4FVPROC programUniformMatrix3x4fv;
-    PFNGLPROGRAMUNIFORMMATRIX4DVPROC programUniformMatrix4dv;
-    PFNGLPROGRAMUNIFORMMATRIX4FVPROC programUniformMatrix4fv;
-    PFNGLPROGRAMUNIFORMMATRIX4X2DVPROC programUniformMatrix4x2dv;
-    PFNGLPROGRAMUNIFORMMATRIX4X2FVPROC programUniformMatrix4x2fv;
-    PFNGLPROGRAMUNIFORMMATRIX4X3DVPROC programUniformMatrix4x3dv;
-    PFNGLPROGRAMUNIFORMMATRIX4X3FVPROC programUniformMatrix4x3fv;
-    PFNGLRELEASESHADERCOMPILERPROC releaseShaderCompiler;
-    PFNGLSCISSORARRAYVPROC scissorArrayv;
-    PFNGLSCISSORINDEXEDPROC scissorIndexed;
-    PFNGLSCISSORINDEXEDVPROC scissorIndexedv;
-    PFNGLSHADERBINARYPROC shaderBinary;
-    PFNGLUSEPROGRAMSTAGESPROC useProgramStages;
-    PFNGLVALIDATEPROGRAMPIPELINEPROC validateProgramPipeline;
-    PFNGLVERTEXATTRIBL1DPROC vertexAttribL1d;
-    PFNGLVERTEXATTRIBL1DVPROC vertexAttribL1dv;
-    PFNGLVERTEXATTRIBL2DPROC vertexAttribL2d;
-    PFNGLVERTEXATTRIBL2DVPROC vertexAttribL2dv;
-    PFNGLVERTEXATTRIBL3DPROC vertexAttribL3d;
-    PFNGLVERTEXATTRIBL3DVPROC vertexAttribL3dv;
-    PFNGLVERTEXATTRIBL4DPROC vertexAttribL4d;
-    PFNGLVERTEXATTRIBL4DVPROC vertexAttribL4dv;
-    PFNGLVERTEXATTRIBLPOINTERPROC vertexAttribLPointer;
-    PFNGLVIEWPORTARRAYVPROC viewportArrayv;
-    PFNGLVIEWPORTINDEXEDFPROC viewportIndexedf;
-    PFNGLVIEWPORTINDEXEDFVPROC viewportIndexedfv;
-
-    // 4.2
-    PFNGLBINDIMAGETEXTUREPROC bindImageTexture;
-    PFNGLDRAWARRAYSINSTANCEDBASEINSTANCEPROC drawArraysInstancedBaseInstance;
-    PFNGLDRAWELEMENTSINSTANCEDBASEINSTANCEPROC drawElementsInstancedBaseInstance;
-    PFNGLDRAWELEMENTSINSTANCEDBASEVERTEXBASEINSTANCEPROC drawElementsInstancedBaseVertexBaseInstance;
-    PFNGLDRAWTRANSFORMFEEDBACKINSTANCEDPROC drawTransformFeedbackInstanced;
-    PFNGLDRAWTRANSFORMFEEDBACKSTREAMINSTANCEDPROC drawTransformFeedbackStreamInstanced;
-    PFNGLGETACTIVEATOMICCOUNTERBUFFERIVPROC getActiveAtomicCounterBufferiv;
-    PFNGLGETINTERNALFORMATIVPROC getInternalformativ;
-    PFNGLMEMORYBARRIERPROC memoryBarrier;
-    PFNGLTEXSTORAGE1DPROC texStorage1D;
-    PFNGLTEXSTORAGE2DPROC texStorage2D;
-    PFNGLTEXSTORAGE3DPROC texStorage3D;
-
-    // 4.3
-    PFNGLBINDVERTEXBUFFERPROC bindVertexBuffer;
-    PFNGLCLEARBUFFERDATAPROC clearBufferData;
-    PFNGLCLEARBUFFERSUBDATAPROC clearBufferSubData;
-    PFNGLCOPYIMAGESUBDATAPROC copyImageSubData;
-    PFNGLDEBUGMESSAGECALLBACKPROC debugMessageCallback;
-    PFNGLDEBUGMESSAGECONTROLPROC debugMessageControl;
-    PFNGLDEBUGMESSAGEINSERTPROC debugMessageInsert;
-    PFNGLDISPATCHCOMPUTEPROC dispatchCompute;
-    PFNGLDISPATCHCOMPUTEINDIRECTPROC dispatchComputeIndirect;
-    PFNGLFRAMEBUFFERPARAMETERIPROC framebufferParameteri;
-    PFNGLGETDEBUGMESSAGELOGPROC getDebugMessageLog;
-    PFNGLGETFRAMEBUFFERPARAMETERIVPROC getFramebufferParameteriv;
-    PFNGLGETINTERNALFORMATI64VPROC getInternalformati64v;
-    PFNGLGETPOINTERVPROC getPointerv;
-    PFNGLGETOBJECTLABELPROC getObjectLabel;
-    PFNGLGETOBJECTPTRLABELPROC getObjectPtrLabel;
-    PFNGLGETPROGRAMINTERFACEIVPROC getProgramInterfaceiv;
-    PFNGLGETPROGRAMRESOURCEINDEXPROC getProgramResourceIndex;
-    PFNGLGETPROGRAMRESOURCELOCATIONPROC getProgramResourceLocation;
-    PFNGLGETPROGRAMRESOURCELOCATIONINDEXPROC getProgramResourceLocationIndex;
-    PFNGLGETPROGRAMRESOURCENAMEPROC getProgramResourceName;
-    PFNGLGETPROGRAMRESOURCEIVPROC getProgramResourceiv;
-    PFNGLINVALIDATEBUFFERDATAPROC invalidateBufferData;
-    PFNGLINVALIDATEBUFFERSUBDATAPROC invalidateBufferSubData;
-    PFNGLINVALIDATEFRAMEBUFFERPROC invalidateFramebuffer;
-    PFNGLINVALIDATESUBFRAMEBUFFERPROC invalidateSubFramebuffer;
-    PFNGLINVALIDATETEXIMAGEPROC invalidateTexImage;
-    PFNGLINVALIDATETEXSUBIMAGEPROC invalidateTexSubImage;
-    PFNGLMULTIDRAWARRAYSINDIRECTPROC multiDrawArraysIndirect;
-    PFNGLMULTIDRAWELEMENTSINDIRECTPROC multiDrawElementsIndirect;
-    PFNGLOBJECTLABELPROC objectLabel;
-    PFNGLOBJECTPTRLABELPROC objectPtrLabel;
-    PFNGLPOPDEBUGGROUPPROC popDebugGroup;
-    PFNGLPUSHDEBUGGROUPPROC pushDebugGroup;
-    PFNGLSHADERSTORAGEBLOCKBINDINGPROC shaderStorageBlockBinding;
-    PFNGLTEXBUFFERRANGEPROC texBufferRange;
-    PFNGLTEXSTORAGE2DMULTISAMPLEPROC texStorage2DMultisample;
-    PFNGLTEXSTORAGE3DMULTISAMPLEPROC texStorage3DMultisample;
-    PFNGLTEXTUREVIEWPROC textureView;
-    PFNGLVERTEXATTRIBBINDINGPROC vertexAttribBinding;
-    PFNGLVERTEXATTRIBFORMATPROC vertexAttribFormat;
-    PFNGLVERTEXATTRIBIFORMATPROC vertexAttribIFormat;
-    PFNGLVERTEXATTRIBLFORMATPROC vertexAttribLFormat;
-    PFNGLVERTEXBINDINGDIVISORPROC vertexBindingDivisor;
-    PFNGLCOVERAGEMODULATIONNVPROC coverageModulationNV;
-
-    // 4.4
-    PFNGLBINDBUFFERSBASEPROC bindBuffersBase;
-    PFNGLBINDBUFFERSRANGEPROC bindBuffersRange;
-    PFNGLBINDIMAGETEXTURESPROC bindImageTextures;
-    PFNGLBINDSAMPLERSPROC bindSamplers;
-    PFNGLBINDTEXTURESPROC bindTextures;
-    PFNGLBINDVERTEXBUFFERSPROC bindVertexBuffers;
-    PFNGLBUFFERSTORAGEPROC bufferStorage;
-    PFNGLCLEARTEXIMAGEPROC clearTexImage;
-    PFNGLCLEARTEXSUBIMAGEPROC clearTexSubImage;
-
-    // 4.5
-    PFNGLBINDTEXTUREUNITPROC bindTextureUnit;
-    PFNGLBLITNAMEDFRAMEBUFFERPROC blitNamedFramebuffer;
-    PFNGLCHECKNAMEDFRAMEBUFFERSTATUSPROC checkNamedFramebufferStatus;
-    PFNGLCLEARNAMEDBUFFERDATAPROC clearNamedBufferData;
-    PFNGLCLEARNAMEDBUFFERSUBDATAPROC clearNamedBufferSubData;
-    PFNGLCLEARNAMEDFRAMEBUFFERFIPROC clearNamedFramebufferfi;
-    PFNGLCLEARNAMEDFRAMEBUFFERFVPROC clearNamedFramebufferfv;
-    PFNGLCLEARNAMEDFRAMEBUFFERIVPROC clearNamedFramebufferiv;
-    PFNGLCLEARNAMEDFRAMEBUFFERUIVPROC clearNamedFramebufferuiv;
-    PFNGLCLIPCONTROLPROC clipControl;
-    PFNGLCOMPRESSEDTEXTURESUBIMAGE1DPROC compressedTextureSubImage1D;
-    PFNGLCOMPRESSEDTEXTURESUBIMAGE2DPROC compressedTextureSubImage2D;
-    PFNGLCOMPRESSEDTEXTURESUBIMAGE3DPROC compressedTextureSubImage3D;
-    PFNGLCOPYNAMEDBUFFERSUBDATAPROC copyNamedBufferSubData;
-    PFNGLCOPYTEXTURESUBIMAGE1DPROC copyTextureSubImage1D;
-    PFNGLCOPYTEXTURESUBIMAGE2DPROC copyTextureSubImage2D;
-    PFNGLCOPYTEXTURESUBIMAGE3DPROC copyTextureSubImage3D;
-    PFNGLCREATEBUFFERSPROC createBuffers;
-    PFNGLCREATEFRAMEBUFFERSPROC createFramebuffers;
-    PFNGLCREATEPROGRAMPIPELINESPROC createProgramPipelines;
-    PFNGLCREATEQUERIESPROC createQueries;
-    PFNGLCREATERENDERBUFFERSPROC createRenderbuffers;
-    PFNGLCREATESAMPLERSPROC createSamplers;
-    PFNGLCREATETEXTURESPROC createTextures;
-    PFNGLCREATETRANSFORMFEEDBACKSPROC createTransformFeedbacks;
-    PFNGLCREATEVERTEXARRAYSPROC createVertexArrays;
-    PFNGLDISABLEVERTEXARRAYATTRIBPROC disableVertexArrayAttrib;
-    PFNGLENABLEVERTEXARRAYATTRIBPROC enableVertexArrayAttrib;
-    PFNGLFLUSHMAPPEDNAMEDBUFFERRANGEPROC flushMappedNamedBufferRange;
-    PFNGLGENERATETEXTUREMIPMAPPROC generateTextureMipmap;
-    PFNGLGETCOMPRESSEDTEXTUREIMAGEPROC getCompressedTextureImage;
-    PFNGLGETCOMPRESSEDTEXTURESUBIMAGEPROC getCompressedTextureSubImage;
-    PFNGLGETGRAPHICSRESETSTATUSPROC getGraphicsResetStatus;
-    PFNGLGETNAMEDBUFFERPARAMETERI64VPROC getNamedBufferParameteri64v;
-    PFNGLGETNAMEDBUFFERPARAMETERIVPROC getNamedBufferParameteriv;
-    PFNGLGETNAMEDBUFFERPOINTERVPROC getNamedBufferPointerv;
-    PFNGLGETNAMEDBUFFERSUBDATAPROC getNamedBufferSubData;
-    PFNGLGETNAMEDFRAMEBUFFERATTACHMENTPARAMETERIVPROC getNamedFramebufferAttachmentParameteriv;
-    PFNGLGETNAMEDFRAMEBUFFERPARAMETERIVPROC getNamedFramebufferParameteriv;
-    PFNGLGETNAMEDRENDERBUFFERPARAMETERIVPROC getNamedRenderbufferParameteriv;
-    PFNGLGETQUERYBUFFEROBJECTI64VPROC getQueryBufferObjecti64v;
-    PFNGLGETQUERYBUFFEROBJECTIVPROC getQueryBufferObjectiv;
-    PFNGLGETQUERYBUFFEROBJECTUI64VPROC getQueryBufferObjectui64v;
-    PFNGLGETQUERYBUFFEROBJECTUIVPROC getQueryBufferObjectuiv;
-    PFNGLGETTEXTUREIMAGEPROC getTextureImage;
-    PFNGLGETTEXTURELEVELPARAMETERFVPROC getTextureLevelParameterfv;
-    PFNGLGETTEXTURELEVELPARAMETERIVPROC getTextureLevelParameteriv;
-    PFNGLGETTEXTUREPARAMETERIIVPROC getTextureParameterIiv;
-    PFNGLGETTEXTUREPARAMETERIUIVPROC getTextureParameterIuiv;
-    PFNGLGETTEXTUREPARAMETERFVPROC getTextureParameterfv;
-    PFNGLGETTEXTUREPARAMETERIVPROC getTextureParameteriv;
-    PFNGLGETTEXTURESUBIMAGEPROC getTextureSubImage;
-    PFNGLGETTRANSFORMFEEDBACKI64_VPROC getTransformFeedbacki64_v;
-    PFNGLGETTRANSFORMFEEDBACKI_VPROC getTransformFeedbacki_v;
-    PFNGLGETTRANSFORMFEEDBACKIVPROC getTransformFeedbackiv;
-    PFNGLGETVERTEXARRAYINDEXED64IVPROC getVertexArrayIndexed64iv;
-    PFNGLGETVERTEXARRAYINDEXEDIVPROC getVertexArrayIndexediv;
-    PFNGLGETVERTEXARRAYIVPROC getVertexArrayiv;
-    PFNGLGETNCOMPRESSEDTEXIMAGEPROC getnCompressedTexImage;
-    PFNGLGETNTEXIMAGEPROC getnTexImage;
-    PFNGLGETNUNIFORMDVPROC getnUniformdv;
-    PFNGLGETNUNIFORMFVPROC getnUniformfv;
-    PFNGLGETNUNIFORMIVPROC getnUniformiv;
-    PFNGLGETNUNIFORMUIVPROC getnUniformuiv;
-    PFNGLINVALIDATENAMEDFRAMEBUFFERDATAPROC invalidateNamedFramebufferData;
-    PFNGLINVALIDATENAMEDFRAMEBUFFERSUBDATAPROC invalidateNamedFramebufferSubData;
-    PFNGLMAPNAMEDBUFFERPROC mapNamedBuffer;
-    PFNGLMAPNAMEDBUFFERRANGEPROC mapNamedBufferRange;
-    PFNGLMEMORYBARRIERBYREGIONPROC memoryBarrierByRegion;
-    PFNGLNAMEDBUFFERDATAPROC namedBufferData;
-    PFNGLNAMEDBUFFERSTORAGEPROC namedBufferStorage;
-    PFNGLNAMEDBUFFERSUBDATAPROC namedBufferSubData;
-    PFNGLNAMEDFRAMEBUFFERDRAWBUFFERPROC namedFramebufferDrawBuffer;
-    PFNGLNAMEDFRAMEBUFFERDRAWBUFFERSPROC namedFramebufferDrawBuffers;
-    PFNGLNAMEDFRAMEBUFFERPARAMETERIPROC namedFramebufferParameteri;
-    PFNGLNAMEDFRAMEBUFFERREADBUFFERPROC namedFramebufferReadBuffer;
-    PFNGLNAMEDFRAMEBUFFERRENDERBUFFERPROC namedFramebufferRenderbuffer;
-    PFNGLNAMEDFRAMEBUFFERTEXTUREPROC namedFramebufferTexture;
-    PFNGLNAMEDFRAMEBUFFERTEXTURELAYERPROC namedFramebufferTextureLayer;
-    PFNGLNAMEDRENDERBUFFERSTORAGEPROC namedRenderbufferStorage;
-    PFNGLNAMEDRENDERBUFFERSTORAGEMULTISAMPLEPROC namedRenderbufferStorageMultisample;
-    PFNGLREADNPIXELSPROC readnPixels;
-    PFNGLTEXTUREBARRIERPROC textureBarrier;
-    PFNGLTEXTUREBUFFERPROC textureBuffer;
-    PFNGLTEXTUREBUFFERRANGEPROC textureBufferRange;
-    PFNGLTEXTUREPARAMETERIIVPROC textureParameterIiv;
-    PFNGLTEXTUREPARAMETERIUIVPROC textureParameterIuiv;
-    PFNGLTEXTUREPARAMETERFPROC textureParameterf;
-    PFNGLTEXTUREPARAMETERFVPROC textureParameterfv;
-    PFNGLTEXTUREPARAMETERIPROC textureParameteri;
-    PFNGLTEXTUREPARAMETERIVPROC textureParameteriv;
-    PFNGLTEXTURESTORAGE1DPROC textureStorage1D;
-    PFNGLTEXTURESTORAGE2DPROC textureStorage2D;
-    PFNGLTEXTURESTORAGE2DMULTISAMPLEPROC textureStorage2DMultisample;
-    PFNGLTEXTURESTORAGE3DPROC textureStorage3D;
-    PFNGLTEXTURESTORAGE3DMULTISAMPLEPROC textureStorage3DMultisample;
-    PFNGLTEXTURESUBIMAGE1DPROC textureSubImage1D;
-    PFNGLTEXTURESUBIMAGE2DPROC textureSubImage2D;
-    PFNGLTEXTURESUBIMAGE3DPROC textureSubImage3D;
-    PFNGLTRANSFORMFEEDBACKBUFFERBASEPROC transformFeedbackBufferBase;
-    PFNGLTRANSFORMFEEDBACKBUFFERRANGEPROC transformFeedbackBufferRange;
-    PFNGLUNMAPNAMEDBUFFERPROC unmapNamedBuffer;
-    PFNGLVERTEXARRAYATTRIBBINDINGPROC vertexArrayAttribBinding;
-    PFNGLVERTEXARRAYATTRIBFORMATPROC vertexArrayAttribFormat;
-    PFNGLVERTEXARRAYATTRIBIFORMATPROC vertexArrayAttribIFormat;
-    PFNGLVERTEXARRAYATTRIBLFORMATPROC vertexArrayAttribLFormat;
-    PFNGLVERTEXARRAYBINDINGDIVISORPROC vertexArrayBindingDivisor;
-    PFNGLVERTEXARRAYELEMENTBUFFERPROC vertexArrayElementBuffer;
-    PFNGLVERTEXARRAYVERTEXBUFFERPROC vertexArrayVertexBuffer;
-    PFNGLVERTEXARRAYVERTEXBUFFERSPROC vertexArrayVertexBuffers;
-
-    // ES 3.2
-    PFNGLBLENDBARRIERPROC blendBarrier;
-    PFNGLPRIMITIVEBOUNDINGBOXPROC primitiveBoundingBox;
-
-    // GL_OES_EGL_image
-    PFNGLEGLIMAGETARGETRENDERBUFFERSTORAGEOESPROC eglImageTargetRenderbufferStorageOES;
-    PFNGLEGLIMAGETARGETTEXTURE2DOESPROC eglImageTargetTexture2DOES;
-
-    // GL_EXT_discard_framebuffer
-    PFNGLDISCARDFRAMEBUFFEREXTPROC discardFramebuffer;
-
-    // GL_NV_internalformat_sample_query
-    PFNGLGETINTERNALFORMATSAMPLEIVNVPROC getInternalformatSampleivNV;
-
   private:
-    void initializeProcsDesktopGL();
-    void initializeProcsGLES();
-
-    virtual void *loadProcAddress(const std::string &function) = 0;
+    void *loadProcAddress(const std::string &function) const override = 0;
+    void initializeDummyFunctionsForNULLDriver(const std::set<std::string> &extensionSet);
 };
 
-}
+}  // namespace rx
 
 #endif // LIBANGLE_RENDERER_GL_FUNCTIONSGL_H_
--- a/gfx/angle/src/libANGLE/renderer/gl/PathGL.cpp
+++ b/gfx/angle/src/libANGLE/renderer/gl/PathGL.cpp
@@ -27,12 +27,12 @@ gl::Error PathGL::setCommands(GLsizei nu
                               const void *coords)
 {
     mFunctions->pathCommandsNV(mPathID, numCommands, commands, numCoords, coordType, coords);
     return gl::NoError();
 }
 
 void PathGL::setPathParameter(GLenum pname, GLfloat value)
 {
-    mFunctions->setPathParameterfNV(mPathID, pname, value);
+    mFunctions->pathParameterfNV(mPathID, pname, value);
 }
 
 }  // rx
--- a/gfx/angle/src/libANGLE/renderer/gl/PathGL.h
+++ b/gfx/angle/src/libANGLE/renderer/gl/PathGL.h
@@ -16,17 +16,17 @@ namespace rx
 {
 
 class FunctionsGL;
 
 class PathGL : public PathImpl
 {
   public:
     PathGL(const FunctionsGL *functions, GLuint path);
-    ~PathGL();
+    ~PathGL() override;
 
     gl::Error setCommands(GLsizei numCommands,
                           const GLubyte *commands,
                           GLsizei numCoords,
                           GLenum coordType,
                           const void *coords) override;
 
     void setPathParameter(GLenum pname, GLfloat value) override;
--- a/gfx/angle/src/libANGLE/renderer/gl/ProgramGL.cpp
+++ b/gfx/angle/src/libANGLE/renderer/gl/ProgramGL.cpp
@@ -9,17 +9,19 @@
 #include "libANGLE/renderer/gl/ProgramGL.h"
 
 #include "common/angleutils.h"
 #include "common/bitset_utils.h"
 #include "common/debug.h"
 #include "common/string_utils.h"
 #include "common/utilities.h"
 #include "libANGLE/Context.h"
+#include "libANGLE/ProgramLinkedResources.h"
 #include "libANGLE/Uniform.h"
+#include "libANGLE/queryconversions.h"
 #include "libANGLE/renderer/gl/ContextGL.h"
 #include "libANGLE/renderer/gl/FunctionsGL.h"
 #include "libANGLE/renderer/gl/ShaderGL.h"
 #include "libANGLE/renderer/gl/StateManagerGL.h"
 #include "libANGLE/renderer/gl/WorkaroundsGL.h"
 #include "platform/Platform.h"
 
 namespace rx
@@ -77,24 +79,24 @@ gl::LinkResult ProgramGL::load(const gl:
     return true;
 }
 
 void ProgramGL::save(const gl::Context *context, gl::BinaryOutputStream *stream)
 {
     GLint binaryLength = 0;
     mFunctions->getProgramiv(mProgramID, GL_PROGRAM_BINARY_LENGTH, &binaryLength);
 
-    std::vector<uint8_t> binary(binaryLength);
+    std::vector<uint8_t> binary(std::max(binaryLength, 1));
     GLenum binaryFormat = GL_NONE;
     mFunctions->getProgramBinary(mProgramID, binaryLength, &binaryLength, &binaryFormat,
-                                 &binary[0]);
+                                 binary.data());
 
     stream->writeInt(binaryFormat);
     stream->writeInt(binaryLength);
-    stream->writeBytes(&binary[0], binaryLength);
+    stream->writeBytes(binary.data(), binaryLength);
 
     reapplyUBOBindingsIfNeeded(context);
 }
 
 void ProgramGL::reapplyUBOBindingsIfNeeded(const gl::Context *context)
 {
     // Re-apply UBO bindings to work around driver bugs.
     const WorkaroundsGL &workaroundsGL = GetImplAs<ContextGL>(context)->getWorkaroundsGL();
@@ -119,17 +121,17 @@ void ProgramGL::setBinaryRetrievableHint
 }
 
 void ProgramGL::setSeparable(bool separable)
 {
     mFunctions->programParameteri(mProgramID, GL_PROGRAM_SEPARABLE, separable ? GL_TRUE : GL_FALSE);
 }
 
 gl::LinkResult ProgramGL::link(const gl::Context *context,
-                               const gl::VaryingPacking &packing,
+                               const gl::ProgramLinkedResources &resources,
                                gl::InfoLog &infoLog)
 {
     preLink();
 
     if (mState.getAttachedComputeShader())
     {
         const ShaderGL *computeShaderGL = GetImplAs<ShaderGL>(mState.getAttachedComputeShader());
 
@@ -207,16 +209,17 @@ gl::LinkResult ProgramGL::link(const gl:
         return false;
     }
 
     if (mWorkarounds.alwaysCallUseProgramAfterLink)
     {
         mStateManager->forceUseProgram(mProgramID);
     }
 
+    linkResources(resources);
     postLink();
 
     return true;
 }
 
 GLboolean ProgramGL::validate(const gl::Caps & /*caps*/, gl::InfoLog * /*infoLog*/)
 {
     // TODO(jmadill): implement validate
@@ -569,20 +572,100 @@ bool ProgramGL::getUniformBlockMemberInf
                                     &memberInfoOut->arrayStride);
     mFunctions->getActiveUniformsiv(mProgramID, 1, &uniformIndex, GL_UNIFORM_MATRIX_STRIDE,
                                     &memberInfoOut->matrixStride);
 
     // TODO(jmadill): possibly determine this at the gl::Program level.
     GLint isRowMajorMatrix = 0;
     mFunctions->getActiveUniformsiv(mProgramID, 1, &uniformIndex, GL_UNIFORM_IS_ROW_MAJOR,
                                     &isRowMajorMatrix);
-    memberInfoOut->isRowMajorMatrix = isRowMajorMatrix != GL_FALSE;
+    memberInfoOut->isRowMajorMatrix = gl::ConvertToBool(isRowMajorMatrix);
+    return true;
+}
+
+bool ProgramGL::getShaderStorageBlockMemberInfo(const std::string & /* memberName */,
+                                                const std::string &memberUniformMappedName,
+                                                sh::BlockMemberInfo *memberInfoOut) const
+{
+    const GLchar *memberNameGLStr = memberUniformMappedName.c_str();
+    GLuint index =
+        mFunctions->getProgramResourceIndex(mProgramID, GL_BUFFER_VARIABLE, memberNameGLStr);
+
+    if (index == GL_INVALID_INDEX)
+    {
+        *memberInfoOut = sh::BlockMemberInfo::getDefaultBlockInfo();
+        return false;
+    }
+
+    constexpr int kPropCount             = 5;
+    std::array<GLenum, kPropCount> props = {
+        {GL_ARRAY_STRIDE, GL_IS_ROW_MAJOR, GL_MATRIX_STRIDE, GL_OFFSET, GL_TOP_LEVEL_ARRAY_STRIDE}};
+    std::array<GLint, kPropCount> params;
+    GLsizei length;
+    mFunctions->getProgramResourceiv(mProgramID, GL_BUFFER_VARIABLE, index, kPropCount,
+                                     props.data(), kPropCount, &length, params.data());
+    ASSERT(kPropCount == length);
+    memberInfoOut->arrayStride         = params[0];
+    memberInfoOut->isRowMajorMatrix    = params[1] != 0;
+    memberInfoOut->matrixStride        = params[2];
+    memberInfoOut->offset              = params[3];
+    memberInfoOut->topLevelArrayStride = params[4];
+
     return true;
 }
 
+bool ProgramGL::getShaderStorageBlockSize(const std::string &name,
+                                          const std::string &mappedName,
+                                          size_t *sizeOut) const
+{
+    const GLchar *nameGLStr = mappedName.c_str();
+    GLuint index =
+        mFunctions->getProgramResourceIndex(mProgramID, GL_SHADER_STORAGE_BLOCK, nameGLStr);
+
+    if (index == GL_INVALID_INDEX)
+    {
+        *sizeOut = 0;
+        return false;
+    }
+
+    GLenum prop    = GL_BUFFER_DATA_SIZE;
+    GLsizei length = 0;
+    GLint dataSize = 0;
+    mFunctions->getProgramResourceiv(mProgramID, GL_SHADER_STORAGE_BLOCK, index, 1, &prop, 1,
+                                     &length, &dataSize);
+    *sizeOut = static_cast<size_t>(dataSize);
+    return true;
+}
+
+void ProgramGL::getAtomicCounterBufferSizeMap(std::map<int, unsigned int> *sizeMapOut) const
+{
+    if (mFunctions->getProgramInterfaceiv == nullptr)
+    {
+        return;
+    }
+
+    int resourceCount = 0;
+    mFunctions->getProgramInterfaceiv(mProgramID, GL_ATOMIC_COUNTER_BUFFER, GL_ACTIVE_RESOURCES,
+                                      &resourceCount);
+
+    for (int index = 0; index < resourceCount; index++)
+    {
+        constexpr int kPropCount             = 2;
+        std::array<GLenum, kPropCount> props = {{GL_BUFFER_BINDING, GL_BUFFER_DATA_SIZE}};
+        std::array<GLint, kPropCount> params;
+        GLsizei length;
+        mFunctions->getProgramResourceiv(mProgramID, GL_ATOMIC_COUNTER_BUFFER, index, kPropCount,
+                                         props.data(), kPropCount, &length, params.data());
+        ASSERT(kPropCount == length);
+        int bufferBinding           = params[0];
+        unsigned int bufferDataSize = params[1];
+        sizeMapOut->insert(std::pair<int, unsigned int>(bufferBinding, bufferDataSize));
+    }
+}
+
 void ProgramGL::setPathFragmentInputGen(const std::string &inputName,
                                         GLenum genMode,
                                         GLint components,
                                         const GLfloat *coeffs)
 {
     ASSERT(mEnablePathRendering);
 
     for (const auto &input : mPathRenderingFragmentInputs)
@@ -654,24 +737,29 @@ void ProgramGL::postLink()
     for (size_t uniformLocation = 0; uniformLocation < uniformLocations.size(); uniformLocation++)
     {
         const auto &entry = uniformLocations[uniformLocation];
         if (!entry.used())
         {
             continue;
         }
 
-        // From the spec:
+        // From the GLES 3.0.5 spec:
         // "Locations for sequential array indices are not required to be sequential."
         const gl::LinkedUniform &uniform = uniforms[entry.index];
         std::stringstream fullNameStr;
-        fullNameStr << uniform.mappedName;
         if (uniform.isArray())
         {
-            fullNameStr << "[" << entry.element << "]";
+            ASSERT(angle::EndsWith(uniform.mappedName, "[0]"));
+            fullNameStr << uniform.mappedName.substr(0, uniform.mappedName.length() - 3);
+            fullNameStr << "[" << entry.arrayIndex << "]";
+        }
+        else
+        {
+            fullNameStr << uniform.mappedName;
         }
         const std::string &fullName = fullNameStr.str();
 
         GLint realLocation = mFunctions->getUniformLocation(mProgramID, fullName.c_str());
         mUniformRealLocationMap[uniformLocation] = realLocation;
     }
 
     if (mState.usesMultiview())
@@ -795,9 +883,43 @@ void ProgramGL::markUnusedUniformLocatio
                 GLuint samplerIndex = mState.getSamplerIndexFromUniformIndex(locationRef.index);
                 (*samplerBindings)[samplerIndex].unreferenced = true;
             }
             locationRef.markUnused();
         }
     }
 }
 
+void ProgramGL::linkResources(const gl::ProgramLinkedResources &resources)
+{
+    // Gather interface block info.
+    auto getUniformBlockSize = [this](const std::string &name, const std::string &mappedName,
+                                      size_t *sizeOut) {
+        return this->getUniformBlockSize(name, mappedName, sizeOut);
+    };
+
+    auto getUniformBlockMemberInfo = [this](const std::string &name, const std::string &mappedName,
+                                            sh::BlockMemberInfo *infoOut) {
+        return this->getUniformBlockMemberInfo(name, mappedName, infoOut);
+    };
+
+    resources.uniformBlockLinker.linkBlocks(getUniformBlockSize, getUniformBlockMemberInfo);
+
+    auto getShaderStorageBlockSize = [this](const std::string &name, const std::string &mappedName,
+                                            size_t *sizeOut) {
+        return this->getShaderStorageBlockSize(name, mappedName, sizeOut);
+    };
+
+    auto getShaderStorageBlockMemberInfo = [this](const std::string &name,
+                                                  const std::string &mappedName,
+                                                  sh::BlockMemberInfo *infoOut) {
+        return this->getShaderStorageBlockMemberInfo(name, mappedName, infoOut);
+    };
+    resources.shaderStorageBlockLinker.linkBlocks(getShaderStorageBlockSize,
+                                                  getShaderStorageBlockMemberInfo);
+
+    // Gather atomic counter buffer info.
+    std::map<int, unsigned int> sizeMap;
+    getAtomicCounterBufferSizeMap(&sizeMap);
+    resources.atomicCounterBufferLinker.link(sizeMap);
+}
+
 }  // namespace rx
--- a/gfx/angle/src/libANGLE/renderer/gl/ProgramGL.h
+++ b/gfx/angle/src/libANGLE/renderer/gl/ProgramGL.h
@@ -34,17 +34,17 @@ class ProgramGL : public ProgramImpl
     gl::LinkResult load(const gl::Context *contextImpl,
                         gl::InfoLog &infoLog,
                         gl::BinaryInputStream *stream) override;
     void save(const gl::Context *context, gl::BinaryOutputStream *stream) override;
     void setBinaryRetrievableHint(bool retrievable) override;
     void setSeparable(bool separable) override;
 
     gl::LinkResult link(const gl::Context *contextImpl,
-                        const gl::VaryingPacking &packing,
+                        const gl::ProgramLinkedResources &resources,
                         gl::InfoLog &infoLog) override;
     GLboolean validate(const gl::Caps &caps, gl::InfoLog *infoLog) override;
 
     void setUniform1fv(GLint location, GLsizei count, const GLfloat *v) override;
     void setUniform2fv(GLint location, GLsizei count, const GLfloat *v) override;
     void setUniform3fv(GLint location, GLsizei count, const GLfloat *v) override;
     void setUniform4fv(GLint location, GLsizei count, const GLfloat *v) override;
     void setUniform1iv(GLint location, GLsizei count, const GLint *v) override;
@@ -66,23 +66,16 @@ class ProgramGL : public ProgramImpl
     void setUniformMatrix4x3fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value) override;
 
     void getUniformfv(const gl::Context *context, GLint location, GLfloat *params) const override;
     void getUniformiv(const gl::Context *context, GLint location, GLint *params) const override;
     void getUniformuiv(const gl::Context *context, GLint location, GLuint *params) const override;
 
     void setUniformBlockBinding(GLuint uniformBlockIndex, GLuint uniformBlockBinding) override;
 
-    bool getUniformBlockSize(const std::string &blockName,
-                             const std::string &blockMappedName,
-                             size_t *sizeOut) const override;
-    bool getUniformBlockMemberInfo(const std::string &memberUniformName,
-                                   const std::string &memberUniformMappedName,
-                                   sh::BlockMemberInfo *memberInfoOut) const override;
-
     void setPathFragmentInputGen(const std::string &inputName,
                                  GLenum genMode,
                                  GLint components,
                                  const GLfloat *coeffs) override;
 
     void markUnusedUniformLocations(std::vector<gl::VariableLocation> *uniformLocations,
                                     std::vector<gl::SamplerBinding> *samplerBindings) override;
 
@@ -92,16 +85,32 @@ class ProgramGL : public ProgramImpl
     void enableLayeredRenderingPath(int baseViewIndex) const;
 
   private:
     void preLink();
     bool checkLinkStatus(gl::InfoLog &infoLog);
     void postLink();
     void reapplyUBOBindingsIfNeeded(const gl::Context *context);
 
+    bool getUniformBlockSize(const std::string &blockName,
+                             const std::string &blockMappedName,
+                             size_t *sizeOut) const;
+    bool getUniformBlockMemberInfo(const std::string &memberUniformName,
+                                   const std::string &memberUniformMappedName,
+                                   sh::BlockMemberInfo *memberInfoOut) const;
+    bool getShaderStorageBlockMemberInfo(const std::string &memberName,
+                                         const std::string &memberMappedName,
+                                         sh::BlockMemberInfo *memberInfoOut) const;
+    bool getShaderStorageBlockSize(const std::string &blockName,
+                                   const std::string &blockMappedName,
+                                   size_t *sizeOut) const;
+    void getAtomicCounterBufferSizeMap(std::map<int, unsigned int> *sizeMapOut) const;
+
+    void linkResources(const gl::ProgramLinkedResources &resources);
+
     // Helper function, makes it simpler to type.
     GLint uniLoc(GLint glLocation) const { return mUniformRealLocationMap[glLocation]; }
 
     const FunctionsGL *mFunctions;
     const WorkaroundsGL &mWorkarounds;
     StateManagerGL *mStateManager;
 
     std::vector<GLint> mUniformRealLocationMap;
--- a/gfx/angle/src/libANGLE/renderer/gl/QueryGL.cpp
+++ b/gfx/angle/src/libANGLE/renderer/gl/QueryGL.cpp
@@ -240,17 +240,17 @@ class SyncProviderGL
 class SyncProviderGLSync : public SyncProviderGL
 {
   public:
     SyncProviderGLSync(const FunctionsGL *functions) : mFunctions(functions), mSync(nullptr)
     {
         mSync = mFunctions->fenceSync(GL_SYNC_GPU_COMMANDS_COMPLETE, 0);
     }
 
-    virtual ~SyncProviderGLSync() { mFunctions->deleteSync(mSync); }
+    ~SyncProviderGLSync() override { mFunctions->deleteSync(mSync); }
 
     gl::Error flush(bool force, bool *finished) override
     {
         if (force)
         {
             mFunctions->clientWaitSync(mSync, 0, 0);
             *finished = true;
         }
@@ -279,17 +279,17 @@ class SyncProviderGLQuery : public SyncP
     {
         mFunctions->genQueries(1, &mQuery);
         ANGLE_SWALLOW_ERR(stateManager->pauseQuery(queryType));
         mFunctions->beginQuery(queryType, mQuery);
         mFunctions->endQuery(queryType);
         ANGLE_SWALLOW_ERR(stateManager->resumeQuery(queryType));
     }
 
-    virtual ~SyncProviderGLQuery() { mFunctions->deleteQueries(1, &mQuery); }
+    ~SyncProviderGLQuery() override { mFunctions->deleteQueries(1, &mQuery); }
 
     gl::Error flush(bool force, bool *finished) override
     {
         if (force)
         {
             GLint result = 0;
             mFunctions->getQueryObjectiv(mQuery, GL_QUERY_RESULT, &result);
             *finished = true;
--- a/gfx/angle/src/libANGLE/renderer/gl/RenderbufferGL.cpp
+++ b/gfx/angle/src/libANGLE/renderer/gl/RenderbufferGL.cpp
@@ -95,9 +95,16 @@ gl::Error RenderbufferGL::setStorageEGLI
     return gl::InternalError();
 }
 
 GLuint RenderbufferGL::getRenderbufferID() const
 {
     return mRenderbufferID;
 }
 
+gl::Error RenderbufferGL::initializeContents(const gl::Context *context,
+                                             const gl::ImageIndex &imageIndex)
+{
+    // TODO(jmadill):
+    return gl::NoError();
 }
+
+}  // namespace rx
--- a/gfx/angle/src/libANGLE/renderer/gl/RenderbufferGL.h
+++ b/gfx/angle/src/libANGLE/renderer/gl/RenderbufferGL.h
@@ -27,27 +27,29 @@ class RenderbufferGL : public Renderbuff
 {
   public:
     RenderbufferGL(const FunctionsGL *functions,
                    const WorkaroundsGL &workarounds,
                    StateManagerGL *stateManager,
                    const gl::TextureCapsMap &textureCaps);
     ~RenderbufferGL() override;
 
-    virtual gl::Error setStorage(const gl::Context *context,
-                                 GLenum internalformat,
-                                 size_t width,
-                                 size_t height) override;
-    virtual gl::Error setStorageMultisample(const gl::Context *context,
-                                            size_t samples,
-                                            GLenum internalformat,
-                                            size_t width,
-                                            size_t height) override;
-    virtual gl::Error setStorageEGLImageTarget(const gl::Context *context,
-                                               egl::Image *image) override;
+    gl::Error setStorage(const gl::Context *context,
+                         GLenum internalformat,
+                         size_t width,
+                         size_t height) override;
+    gl::Error setStorageMultisample(const gl::Context *context,
+                                    size_t samples,
+                                    GLenum internalformat,
+                                    size_t width,
+                                    size_t height) override;
+    gl::Error setStorageEGLImageTarget(const gl::Context *context, egl::Image *image) override;
+
+    gl::Error initializeContents(const gl::Context *context,
+                                 const gl::ImageIndex &imageIndex) override;
 
     GLuint getRenderbufferID() const;
 
   private:
     const FunctionsGL *mFunctions;
     const WorkaroundsGL &mWorkarounds;
     StateManagerGL *mStateManager;
     const gl::TextureCapsMap &mTextureCaps;
--- a/gfx/angle/src/libANGLE/renderer/gl/RendererGL.cpp
+++ b/gfx/angle/src/libANGLE/renderer/gl/RendererGL.cpp
@@ -166,17 +166,16 @@ namespace rx
 
 RendererGL::RendererGL(const FunctionsGL *functions, const egl::AttributeMap &attribMap)
     : mMaxSupportedESVersion(0, 0),
       mFunctions(functions),
       mStateManager(nullptr),
       mBlitter(nullptr),
       mMultiviewClearer(nullptr),
       mUseDebugOutput(false),
-      mSkipDrawCalls(false),
       mCapsInitialized(false),
       mMultiviewImplementationType(MultiviewImplementationTypeGL::UNSPECIFIED)
 {
     ASSERT(mFunctions);
     nativegl_gl::GenerateWorkarounds(mFunctions, &mWorkarounds);
     mStateManager = new StateManagerGL(mFunctions, getNativeCaps(), getNativeExtensions());
     mBlitter      = new BlitGL(functions, mWorkarounds, mStateManager);
     mMultiviewClearer = new ClearMultiviewGL(functions, mStateManager);
@@ -198,23 +197,16 @@ RendererGL::RendererGL(const FunctionsGL
                                         nullptr, GL_TRUE);
         mFunctions->debugMessageControl(GL_DONT_CARE, GL_DONT_CARE, GL_DEBUG_SEVERITY_LOW, 0,
                                         nullptr, GL_FALSE);
         mFunctions->debugMessageControl(GL_DONT_CARE, GL_DONT_CARE, GL_DEBUG_SEVERITY_NOTIFICATION,
                                         0, nullptr, GL_FALSE);
         mFunctions->debugMessageCallback(&LogGLDebugMessage, nullptr);
     }
 
-    EGLint deviceType =
-        static_cast<EGLint>(attribMap.get(EGL_PLATFORM_ANGLE_DEVICE_TYPE_ANGLE, EGL_NONE));
-    if (deviceType == EGL_PLATFORM_ANGLE_DEVICE_TYPE_NULL_ANGLE)
-    {
-        mSkipDrawCalls = true;
-    }
-
     if (mWorkarounds.initializeCurrentVertexAttributes)
     {
         GLint maxVertexAttribs = 0;
         mFunctions->getIntegerv(GL_MAX_VERTEX_ATTRIBS, &maxVertexAttribs);
 
         for (GLint i = 0; i < maxVertexAttribs; ++i)
         {
             mFunctions->vertexAttrib4f(i, 0.0f, 0.0f, 0.0f, 1.0f);
@@ -257,26 +249,23 @@ gl::Error RendererGL::drawArrays(const g
                                  GLint first,
                                  GLsizei count)
 {
     const gl::Program *program  = context->getGLState().getProgram();
     const bool usesMultiview    = program->usesMultiview();
     const GLsizei instanceCount = usesMultiview ? program->getNumViews() : 0;
 
     ANGLE_TRY(mStateManager->setDrawArraysState(context, first, count, instanceCount));
-    if (!mSkipDrawCalls)
+    if (!usesMultiview)
     {
-        if (!usesMultiview)
-        {
-            mFunctions->drawArrays(mode, first, count);
-        }
-        else
-        {
-            mFunctions->drawArraysInstanced(mode, first, count, instanceCount);
-        }
+        mFunctions->drawArrays(mode, first, count);
+    }
+    else
+    {
+        mFunctions->drawArraysInstanced(mode, first, count, instanceCount);
     }
     return gl::NoError();
 }
 
 gl::Error RendererGL::drawArraysInstanced(const gl::Context *context,
                                           GLenum mode,
                                           GLint first,
                                           GLsizei count,
@@ -285,46 +274,40 @@ gl::Error RendererGL::drawArraysInstance
     GLsizei adjustedInstanceCount = instanceCount;
     const gl::Program *program    = context->getGLState().getProgram();
     if (program->usesMultiview())
     {
         adjustedInstanceCount *= program->getNumViews();
     }
 
     ANGLE_TRY(mStateManager->setDrawArraysState(context, first, count, adjustedInstanceCount));
-    if (!mSkipDrawCalls)
-    {
-        mFunctions->drawArraysInstanced(mode, first, count, adjustedInstanceCount);
-    }
+    mFunctions->drawArraysInstanced(mode, first, count, adjustedInstanceCount);
     return gl::NoError();
 }
 
 gl::Error RendererGL::drawElements(const gl::Context *context,
                                    GLenum mode,
                                    GLsizei count,
                                    GLenum type,
                                    const void *indices)
 {
     const gl::Program *program  = context->getGLState().getProgram();
     const bool usesMultiview    = program->usesMultiview();
     const GLsizei instanceCount = usesMultiview ? program->getNumViews() : 0;
     const void *drawIndexPtr = nullptr;
 
     ANGLE_TRY(mStateManager->setDrawElementsState(context, count, type, indices, instanceCount,
                                                   &drawIndexPtr));
-    if (!mSkipDrawCalls)
+    if (!usesMultiview)
     {
-        if (!usesMultiview)
-        {
-            mFunctions->drawElements(mode, count, type, drawIndexPtr);
-        }
-        else
-        {
-            mFunctions->drawElementsInstanced(mode, count, type, drawIndexPtr, instanceCount);
-        }
+        mFunctions->drawElements(mode, count, type, drawIndexPtr);
+    }
+    else
+    {
+        mFunctions->drawElementsInstanced(mode, count, type, drawIndexPtr, instanceCount);
     }
     return gl::NoError();
 }
 
 gl::Error RendererGL::drawElementsInstanced(const gl::Context *context,
                                             GLenum mode,
                                             GLsizei count,
                                             GLenum type,
@@ -336,21 +319,17 @@ gl::Error RendererGL::drawElementsInstan
     if (program->usesMultiview())
     {
         adjustedInstanceCount *= program->getNumViews();
     }
     const void *drawIndexPointer = nullptr;
 
     ANGLE_TRY(mStateManager->setDrawElementsState(context, count, type, indices,
                                                   adjustedInstanceCount, &drawIndexPointer));
-    if (!mSkipDrawCalls)
-    {
-        mFunctions->drawElementsInstanced(mode, count, type, drawIndexPointer,
-                                          adjustedInstanceCount);
-    }
+    mFunctions->drawElementsInstanced(mode, count, type, drawIndexPointer, adjustedInstanceCount);
     return gl::NoError();
 }
 
 gl::Error RendererGL::drawRangeElements(const gl::Context *context,
                                         GLenum mode,
                                         GLuint start,
                                         GLuint end,
                                         GLsizei count,
@@ -359,54 +338,43 @@ gl::Error RendererGL::drawRangeElements(
 {
     const gl::Program *program   = context->getGLState().getProgram();
     const bool usesMultiview     = program->usesMultiview();
     const GLsizei instanceCount  = usesMultiview ? program->getNumViews() : 0;
     const void *drawIndexPointer = nullptr;
 
     ANGLE_TRY(mStateManager->setDrawElementsState(context, count, type, indices, instanceCount,
                                                   &drawIndexPointer));
-    if (!mSkipDrawCalls)
+    if (!usesMultiview)
     {
-        if (!usesMultiview)
-        {
-            mFunctions->drawRangeElements(mode, start, end, count, type, drawIndexPointer);
-        }
-        else
-        {
-            mFunctions->drawElementsInstanced(mode, count, type, drawIndexPointer, instanceCount);
-        }
+        mFunctions->drawRangeElements(mode, start, end, count, type, drawIndexPointer);
+    }
+    else
+    {
+        mFunctions->drawElementsInstanced(mode, count, type, drawIndexPointer, instanceCount);
     }
     return gl::NoError();
 }
 
 gl::Error RendererGL::drawArraysIndirect(const gl::Context *context,
                                          GLenum mode,
                                          const void *indirect)
 {
     ANGLE_TRY(mStateManager->setDrawIndirectState(context, GL_NONE));
-
-    if (!mSkipDrawCalls)
-    {
-        mFunctions->drawArraysIndirect(mode, indirect);
-    }
+    mFunctions->drawArraysIndirect(mode, indirect);
     return gl::NoError();
 }
 
 gl::Error RendererGL::drawElementsIndirect(const gl::Context *context,
                                            GLenum mode,
                                            GLenum type,
                                            const void *indirect)
 {
     ANGLE_TRY(mStateManager->setDrawIndirectState(context, type));
-
-    if (!mSkipDrawCalls)
-    {
-        mFunctions->drawElementsIndirect(mode, type, indirect);
-    }
+    mFunctions->drawElementsIndirect(mode, type, indirect);
     return gl::NoError();
 }
 
 void RendererGL::stencilFillPath(const gl::ContextState &state,
                                  const gl::Path *path,
                                  GLenum fillMode,
                                  GLuint mask)
 {
@@ -575,28 +543,79 @@ GLenum RendererGL::getResetStatus()
 
 ContextImpl *RendererGL::createContext(const gl::ContextState &state)
 {
     return new ContextGL(state, this);
 }
 
 void RendererGL::insertEventMarker(GLsizei length, const char *marker)
 {
-    mFunctions->debugMessageInsert(GL_DEBUG_SOURCE_APPLICATION, GL_DEBUG_TYPE_MARKER, 0,
-                                   GL_DEBUG_SEVERITY_NOTIFICATION, length, marker);
+    if (mFunctions->insertEventMarkerEXT)
+    {
+        mFunctions->insertEventMarkerEXT(length, marker);
+    }
+    else if (mFunctions->debugMessageInsert)
+    {
+        mFunctions->debugMessageInsert(GL_DEBUG_SOURCE_APPLICATION, GL_DEBUG_TYPE_MARKER, 0,
+                                       GL_DEBUG_SEVERITY_NOTIFICATION, length, marker);
+    }
+    else
+    {
+        UNREACHABLE();
+    }
 }
 
 void RendererGL::pushGroupMarker(GLsizei length, const char *marker)
 {
-    mFunctions->pushDebugGroup(GL_DEBUG_SOURCE_APPLICATION, 0, length, marker);
+    if (mFunctions->pushGroupMarkerEXT)
+    {
+        mFunctions->pushGroupMarkerEXT(length, marker);
+    }
+    else if (mFunctions->pushDebugGroup)
+    {
+        // Fall back to KHR_debug to implement EXT_debug_marker
+        mFunctions->pushDebugGroup(GL_DEBUG_SOURCE_APPLICATION, 0, length, marker);
+    }
+    else
+    {
+        UNREACHABLE();
+    }
 }
 
 void RendererGL::popGroupMarker()
 {
-    mFunctions->popDebugGroup();
+    if (mFunctions->popGroupMarkerEXT)
+    {
+        mFunctions->popGroupMarkerEXT();
+    }
+    else if (mFunctions->popDebugGroup)
+    {
+        // Fall back to KHR_debug to implement EXT_debug_marker
+        mFunctions->popDebugGroup();
+    }
+    else
+    {
+        UNREACHABLE();
+    }
+}
+
+void RendererGL::pushDebugGroup(GLenum source, GLuint id, GLsizei length, const char *message)
+{
+    if (mFunctions->pushDebugGroup)
+    {
+        mFunctions->pushDebugGroup(source, id, length, message);
+    }
+}
+
+void RendererGL::popDebugGroup()
+{
+    if (mFunctions->popDebugGroup)
+    {
+        mFunctions->popDebugGroup();
+    }
 }
 
 std::string RendererGL::getVendorString() const
 {
     return std::string(reinterpret_cast<const char *>(mFunctions->getString(GL_VENDOR)));
 }
 
 std::string RendererGL::getRendererDescription() const
@@ -705,14 +724,32 @@ void RendererGL::applyNativeWorkarounds(
     nativegl_gl::ApplyWorkarounds(mFunctions, workarounds);
 }
 
 gl::Error RendererGL::dispatchCompute(const gl::Context *context,
                                       GLuint numGroupsX,
                                       GLuint numGroupsY,
                                       GLuint numGroupsZ)
 {
-    ANGLE_TRY(mStateManager->setDispatchComputeState(context));
+    ANGLE_TRY(mStateManager->setDispatchComputeState(context, false));
     mFunctions->dispatchCompute(numGroupsX, numGroupsY, numGroupsZ);
     return gl::NoError();
 }
 
+gl::Error RendererGL::dispatchComputeIndirect(const gl::Context *context, GLintptr indirect)
+{
+    ANGLE_TRY(mStateManager->setDispatchComputeState(context, true));
+    mFunctions->dispatchComputeIndirect(indirect);
+    return gl::NoError();
+}
+
+gl::Error RendererGL::memoryBarrier(GLbitfield barriers)
+{
+    mFunctions->memoryBarrier(barriers);
+    return gl::NoError();
+}
+gl::Error RendererGL::memoryBarrierByRegion(GLbitfield barriers)
+{
+    mFunctions->memoryBarrierByRegion(barriers);
+    return gl::NoError();
+}
+
 }  // namespace rx
--- a/gfx/angle/src/libANGLE/renderer/gl/RendererGL.h
+++ b/gfx/angle/src/libANGLE/renderer/gl/RendererGL.h
@@ -144,16 +144,20 @@ class RendererGL : angle::NonCopyable
 
     GLenum getResetStatus();
 
     // EXT_debug_marker
     void insertEventMarker(GLsizei length, const char *marker);
     void pushGroupMarker(GLsizei length, const char *marker);
     void popGroupMarker();
 
+    // KHR_debug
+    void pushDebugGroup(GLenum source, GLuint id, GLsizei length, const char *message);
+    void popDebugGroup();
+
     std::string getVendorString() const;
     std::string getRendererDescription() const;
 
     GLint getGPUDisjoint();
     GLint64 getTimestamp();
 
     const gl::Version &getMaxSupportedESVersion() const;
     const FunctionsGL *getFunctions() const { return mFunctions; }
@@ -168,16 +172,20 @@ class RendererGL : angle::NonCopyable
     const gl::Extensions &getNativeExtensions() const;
     const gl::Limitations &getNativeLimitations() const;
     void applyNativeWorkarounds(gl::Workarounds *workarounds) const;
 
     gl::Error dispatchCompute(const gl::Context *context,
                               GLuint numGroupsX,
                               GLuint numGroupsY,
                               GLuint numGroupsZ);
+    gl::Error dispatchComputeIndirect(const gl::Context *context, GLintptr indirect);
+
+    gl::Error memoryBarrier(GLbitfield barriers);
+    gl::Error memoryBarrierByRegion(GLbitfield barriers);
 
   private:
     void ensureCapsInitialized() const;
     void generateCaps(gl::Caps *outCaps,
                       gl::TextureCapsMap *outTextureCaps,
                       gl::Extensions *outExtensions,
                       gl::Limitations *outLimitations) const;
 
@@ -188,19 +196,16 @@ class RendererGL : angle::NonCopyable
 
     BlitGL *mBlitter;
     ClearMultiviewGL *mMultiviewClearer;
 
     WorkaroundsGL mWorkarounds;
 
     bool mUseDebugOutput;
 
-    // For performance debugging
-    bool mSkipDrawCalls;
-
     mutable bool mCapsInitialized;
     mutable gl::Caps mNativeCaps;
     mutable gl::TextureCapsMap mNativeTextureCaps;
     mutable gl::Extensions mNativeExtensions;
     mutable gl::Limitations mNativeLimitations;
     mutable MultiviewImplementationTypeGL mMultiviewImplementationType;
 };
 
--- a/gfx/angle/src/libANGLE/renderer/gl/ShaderGL.cpp
+++ b/gfx/angle/src/libANGLE/renderer/gl/ShaderGL.cpp
@@ -112,16 +112,26 @@ ShCompileOptions ShaderGL::prepareSource
         options |= SH_INITIALIZE_UNINITIALIZED_LOCALS;
     }
 
     if (mWorkarounds.clampPointSize)
     {
         options |= SH_CLAMP_POINT_SIZE;
     }
 
+    if (mWorkarounds.rewriteVectorScalarArithmetic)
+    {
+        options |= SH_REWRITE_VECTOR_SCALAR_ARITHMETIC;
+    }
+
+    if (mWorkarounds.dontUseLoopsToInitializeVariables)
+    {
+        options |= SH_DONT_USE_LOOPS_TO_INITIALIZE_VARIABLES;
+    }
+
     if (mMultiviewImplementationType == MultiviewImplementationTypeGL::NV_VIEWPORT_ARRAY2)
     {
         options |= SH_INITIALIZE_BUILTINS_FOR_INSTANCED_MULTIVIEW;
         options |= SH_SELECT_VIEW_IN_NV_GLSL_VERTEX_SHADER;
     }
 
     return options;
 }
--- a/gfx/angle/src/libANGLE/renderer/gl/StateManagerGL.cpp
+++ b/gfx/angle/src/libANGLE/renderer/gl/StateManagerGL.cpp
@@ -80,18 +80,18 @@ StateManagerGL::StateManagerGL(const Fun
       mVertexAttribCurrentValues(rendererCaps.maxVertexAttributes),
       mBuffers(),
       mIndexedBuffers(),
       mTextureUnitIndex(0),
       mTextures(),
       mSamplers(rendererCaps.maxCombinedTextureImageUnits, 0),
       mImages(rendererCaps.maxImageUnits, ImageUnitBinding()),
       mTransformFeedback(0),
+      mCurrentTransformFeedback(nullptr),
       mQueries(),
-      mPrevDrawTransformFeedback(nullptr),
       mCurrentQueries(),
       mPrevDrawContext(0),
       mUnpackAlignment(4),
       mUnpackRowLength(0),
       mUnpackSkipRows(0),
       mUnpackSkipPixels(0),
       mUnpackImageHeight(0),
       mUnpackSkipImages(0),
@@ -138,17 +138,17 @@ StateManagerGL::StateManagerGL(const Fun
       mStencilBackFunc(GL_ALWAYS),
       mStencilBackRef(0),
       mStencilBackValueMask(static_cast<GLuint>(-1)),
       mStencilBackStencilFailOp(GL_KEEP),
       mStencilBackStencilPassDepthFailOp(GL_KEEP),
       mStencilBackStencilPassDepthPassOp(GL_KEEP),
       mStencilBackWritemask(static_cast<GLuint>(-1)),
       mCullFaceEnabled(false),
-      mCullFace(GL_BACK),
+      mCullFace(gl::CullFaceMode::Back),
       mFrontFace(GL_CCW),
       mPolygonOffsetFillEnabled(false),
       mPolygonOffsetFactor(0.0f),
       mPolygonOffsetUnits(0.0f),
       mRasterizerDiscardEnabled(false),
       mLineWidth(1.0f),
       mPrimitiveRestartEnabled(false),
       mClearColor(0.0f, 0.0f, 0.0f, 0.0f),
@@ -162,31 +162,35 @@ StateManagerGL::StateManagerGL(const Fun
       mCoverageModulation(GL_NONE),
       mPathStencilFunc(GL_ALWAYS),
       mPathStencilRef(0),
       mPathStencilMask(std::numeric_limits<GLuint>::max()),
       mIsSideBySideDrawFramebuffer(false),
       mIsMultiviewEnabled(extensions.multiview),
       mLocalDirtyBits(),
       mMultiviewDirtyBits(),
-      mProgramTexturesAndSamplersDirty(true)
+      mProgramTexturesAndSamplersDirty(true),
+      mProgramStorageBuffersDirty(true),
+      mProgramDispatchIndirectBufferDirty(false)
 {
     ASSERT(mFunctions);
     ASSERT(extensions.maxViews >= 1u);
 
     mTextures[GL_TEXTURE_2D].resize(rendererCaps.maxCombinedTextureImageUnits);
     mTextures[GL_TEXTURE_RECTANGLE_ANGLE].resize(rendererCaps.maxCombinedTextureImageUnits);
     mTextures[GL_TEXTURE_CUBE_MAP].resize(rendererCaps.maxCombinedTextureImageUnits);
     mTextures[GL_TEXTURE_2D_ARRAY].resize(rendererCaps.maxCombinedTextureImageUnits);
     mTextures[GL_TEXTURE_3D].resize(rendererCaps.maxCombinedTextureImageUnits);
     mTextures[GL_TEXTURE_2D_MULTISAMPLE].resize(rendererCaps.maxCombinedTextureImageUnits);
 
-    mIndexedBuffers[GL_UNIFORM_BUFFER].resize(rendererCaps.maxCombinedUniformBlocks);
-    mIndexedBuffers[GL_ATOMIC_COUNTER_BUFFER].resize(rendererCaps.maxCombinedAtomicCounterBuffers);
-    mIndexedBuffers[GL_SHADER_STORAGE_BUFFER].resize(rendererCaps.maxCombinedShaderStorageBlocks);
+    mIndexedBuffers[gl::BufferBinding::Uniform].resize(rendererCaps.maxUniformBufferBindings);
+    mIndexedBuffers[gl::BufferBinding::AtomicCounter].resize(
+        rendererCaps.maxAtomicCounterBufferBindings);
+    mIndexedBuffers[gl::BufferBinding::ShaderStorage].resize(
+        rendererCaps.maxShaderStorageBufferBindings);
 
     mSampleMaskValues.fill(~GLbitfield(0));
 
     for (GLenum queryType : QueryTypes)
     {
         mQueries[queryType] = 0;
     }
 
@@ -203,16 +207,20 @@ StateManagerGL::StateManagerGL(const Fun
             mFunctions->enable(GL_POINT_SPRITE);
         }
     }
 
     angle::Matrix<GLfloat>::setToIdentity(mPathMatrixProj);
     angle::Matrix<GLfloat>::setToIdentity(mPathMatrixMV);
 }
 
+StateManagerGL::~StateManagerGL()
+{
+}
+
 void StateManagerGL::deleteProgram(GLuint program)
 {
     if (program != 0)
     {
         if (mProgram == program)
         {
             useProgram(0);
         }
@@ -278,55 +286,55 @@ void StateManagerGL::deleteSampler(GLuin
         }
 
         mFunctions->deleteSamplers(1, &sampler);
     }
 }
 
 void StateManagerGL::deleteBuffer(GLuint buffer)
 {
-    if (buffer != 0)
+    if (buffer == 0)
     {
-        for (const auto &bufferTypeIter : mBuffers)
+        return;
+    }
+
+    for (auto target : angle::AllEnums<gl::BufferBinding>())
+    {
+        if (mBuffers[target] == buffer)
         {
-            if (bufferTypeIter.second == buffer)
-            {
-                bindBuffer(bufferTypeIter.first, 0);
-            }
+            bindBuffer(target, 0);
         }
 
-        for (const auto &bufferTypeIter : mIndexedBuffers)
+        auto &indexedTarget = mIndexedBuffers[target];
+        for (size_t bindIndex = 0; bindIndex < indexedTarget.size(); ++bindIndex)
         {
-            for (size_t bindIndex = 0; bindIndex < bufferTypeIter.second.size(); bindIndex++)
+            if (indexedTarget[bindIndex].buffer == buffer)
             {
-                if (bufferTypeIter.second[bindIndex].buffer == buffer)
-                {
-                    bindBufferBase(bufferTypeIter.first, bindIndex, 0);
-                }
+                bindBufferBase(target, bindIndex, 0);
             }
         }
+    }
 
-        mFunctions->deleteBuffers(1, &buffer);
-    }
+    mFunctions->deleteBuffers(1, &buffer);
 }
 
 void StateManagerGL::deleteFramebuffer(GLuint fbo)
 {
     if (fbo != 0)
     {
         for (size_t binding = 0; binding < mFramebuffers.size(); ++binding)
         {
             if (mFramebuffers[binding] == fbo)
             {
                 GLenum enumValue = angle::FramebufferBindingToEnum(
                     static_cast<angle::FramebufferBinding>(binding));
                 bindFramebuffer(enumValue, 0);
             }
-            mFunctions->deleteFramebuffers(1, &fbo);
         }
+        mFunctions->deleteFramebuffers(1, &fbo);
     }
 }
 
 void StateManagerGL::deleteRenderbuffer(GLuint rbo)
 {
     if (rbo != 0)
     {
         if (mRenderbuffer == rbo)
@@ -342,20 +350,20 @@ void StateManagerGL::deleteTransformFeed
 {
     if (transformFeedback != 0)
     {
         if (mTransformFeedback == transformFeedback)
         {
             bindTransformFeedback(GL_TRANSFORM_FEEDBACK, 0);
         }
 
-        if (mPrevDrawTransformFeedback != nullptr &&
-            mPrevDrawTransformFeedback->getTransformFeedbackID() == transformFeedback)
+        if (mCurrentTransformFeedback != nullptr &&
+            mCurrentTransformFeedback->getTransformFeedbackID() == transformFeedback)
         {
-            mPrevDrawTransformFeedback = nullptr;
+            mCurrentTransformFeedback = nullptr;
         }
 
         mFunctions->deleteTransformFeedbacks(1, &transformFeedback);
     }
 }
 
 void StateManagerGL::deleteQuery(GLuint query)
 {
@@ -387,59 +395,61 @@ void StateManagerGL::forceUseProgram(GLu
     mFunctions->useProgram(mProgram);
     mLocalDirtyBits.set(gl::State::DIRTY_BIT_PROGRAM_BINDING);
 }
 
 void StateManagerGL::bindVertexArray(GLuint vao, GLuint elementArrayBuffer)
 {
     if (mVAO != vao)
     {
-        mVAO                              = vao;
-        mBuffers[GL_ELEMENT_ARRAY_BUFFER] = elementArrayBuffer;
+        mVAO                                      = vao;
+        mBuffers[gl::BufferBinding::ElementArray] = elementArrayBuffer;
         mFunctions->bindVertexArray(vao);
 
         mLocalDirtyBits.set(gl::State::DIRTY_BIT_VERTEX_ARRAY_BINDING);
     }
 }
 
-void StateManagerGL::bindBuffer(GLenum type, GLuint buffer)
+void StateManagerGL::bindBuffer(gl::BufferBinding target, GLuint buffer)
 {
-    if (mBuffers[type] != buffer)
+    if (mBuffers[target] != buffer)
     {
-        mBuffers[type] = buffer;
-        mFunctions->bindBuffer(type, buffer);
+        mBuffers[target] = buffer;
+        mFunctions->bindBuffer(gl::ToGLenum(target), buffer);
     }
 }
 
-void StateManagerGL::bindBufferBase(GLenum type, size_t index, GLuint buffer)
+void StateManagerGL::bindBufferBase(gl::BufferBinding target, size_t index, GLuint buffer)
 {
-    auto &binding = mIndexedBuffers[type][index];
+    ASSERT(index < mIndexedBuffers[target].size());
+    auto &binding = mIndexedBuffers[target][index];
     if (binding.buffer != buffer || binding.offset != static_cast<size_t>(-1) ||
         binding.size != static_cast<size_t>(-1))
     {
         binding.buffer = buffer;
         binding.offset = static_cast<size_t>(-1);
         binding.size   = static_cast<size_t>(-1);
-        mFunctions->bindBufferBase(type, static_cast<GLuint>(index), buffer);
+        mFunctions->bindBufferBase(gl::ToGLenum(target), static_cast<GLuint>(index), buffer);
     }
 }
 
-void StateManagerGL::bindBufferRange(GLenum type,
+void StateManagerGL::bindBufferRange(gl::BufferBinding target,
                                      size_t index,
                                      GLuint buffer,
                                      size_t offset,
                                      size_t size)
 {
-    auto &binding = mIndexedBuffers[type][index];
+    auto &binding = mIndexedBuffers[target][index];
     if (binding.buffer != buffer || binding.offset != offset || binding.size != size)
     {
         binding.buffer = buffer;
         binding.offset = offset;
         binding.size   = size;
-        mFunctions->bindBufferRange(type, static_cast<GLuint>(index), buffer, offset, size);
+        mFunctions->bindBufferRange(gl::ToGLenum(target), static_cast<GLuint>(index), buffer,
+                                    offset, size);
     }
 }
 
 void StateManagerGL::activeTexture(size_t unit)
 {
     if (mTextureUnitIndex != unit)
     {
         mTextureUnitIndex = unit;
@@ -486,135 +496,118 @@ void StateManagerGL::bindImageTexture(GL
         binding.access  = access;
         binding.format  = format;
         mFunctions->bindImageTexture(unit, texture, level, layered, layer, access, format);
     }
 }
 
 void StateManagerGL::setPixelUnpackState(const gl::PixelUnpackState &unpack)
 {
-    GLuint unpackBufferID          = 0;
-    const gl::Buffer *unpackBuffer = unpack.pixelBuffer.get();
-    if (unpackBuffer != nullptr)
+    if (mUnpackAlignment != unpack.alignment)
     {
-        unpackBufferID = GetImplAs<BufferGL>(unpackBuffer)->getBufferID();
-    }
-    setPixelUnpackState(unpack.alignment, unpack.rowLength, unpack.skipRows, unpack.skipPixels,
-                        unpack.imageHeight, unpack.skipImages, unpackBufferID);
-}
-
-void StateManagerGL::setPixelUnpackState(GLint alignment,
-                                         GLint rowLength,
-                                         GLint skipRows,
-                                         GLint skipPixels,
-                                         GLint imageHeight,
-                                         GLint skipImages,
-                                         GLuint unpackBuffer)
-{
-    if (mUnpackAlignment != alignment)
-    {
-        mUnpackAlignment = alignment;
+        mUnpackAlignment = unpack.alignment;
         mFunctions->pixelStorei(GL_UNPACK_ALIGNMENT, mUnpackAlignment);
 
-        mLocalDirtyBits.set(gl::State::DIRTY_BIT_UNPACK_ALIGNMENT);
+        mLocalDirtyBits.set(gl::State::DIRTY_BIT_UNPACK_STATE);
     }
 
-    if (mUnpackRowLength != rowLength)
+    if (mUnpackRowLength != unpack.rowLength)
     {
-        mUnpackRowLength = rowLength;
+        mUnpackRowLength = unpack.rowLength;
         mFunctions->pixelStorei(GL_UNPACK_ROW_LENGTH, mUnpackRowLength);
 
-        mLocalDirtyBits.set(gl::State::DIRTY_BIT_UNPACK_ROW_LENGTH);
+        mLocalDirtyBits.set(gl::State::DIRTY_BIT_UNPACK_STATE);
+    }
+
+    if (mUnpackSkipRows != unpack.skipRows)
+    {
+        mUnpackSkipRows = unpack.skipRows;
+        mFunctions->pixelStorei(GL_UNPACK_SKIP_ROWS, mUnpackSkipRows);
+
+        mLocalDirtyBits.set(gl::State::DIRTY_BIT_UNPACK_STATE);
     }
 
-    if (mUnpackSkipRows != skipRows)
+    if (mUnpackSkipPixels != unpack.skipPixels)
     {
-        mUnpackSkipRows = skipRows;
-        mFunctions->pixelStorei(GL_UNPACK_SKIP_ROWS, mUnpackSkipRows);
+        mUnpackSkipPixels = unpack.skipPixels;
+        mFunctions->pixelStorei(GL_UNPACK_SKIP_PIXELS, mUnpackSkipPixels);
 
-        mLocalDirtyBits.set(gl::State::DIRTY_BIT_UNPACK_SKIP_ROWS);
+        mLocalDirtyBits.set(gl::State::DIRTY_BIT_UNPACK_STATE);
     }
 
-    if (mUnpackSkipPixels != skipPixels)
+    if (mUnpackImageHeight != unpack.imageHeight)
     {
-        mUnpackSkipPixels = skipPixels;
-        mFunctions->pixelStorei(GL_UNPACK_SKIP_PIXELS, mUnpackSkipPixels);
+        mUnpackImageHeight = unpack.imageHeight;
+        mFunctions->pixelStorei(GL_UNPACK_IMAGE_HEIGHT, mUnpackImageHeight);
 
-        mLocalDirtyBits.set(gl::State::DIRTY_BIT_UNPACK_SKIP_PIXELS);
+        mLocalDirtyBits.set(gl::State::DIRTY_BIT_UNPACK_STATE);
     }
 
-    if (mUnpackImageHeight != imageHeight)
+    if (mUnpackSkipImages != unpack.skipImages)
     {
-        mUnpackImageHeight = imageHeight;
-        mFunctions->pixelStorei(GL_UNPACK_IMAGE_HEIGHT, mUnpackImageHeight);
-
-        mLocalDirtyBits.set(gl::State::DIRTY_BIT_UNPACK_IMAGE_HEIGHT);
-    }
-
-    if (mUnpackSkipImages != skipImages)
-    {
-        mUnpackSkipImages = skipImages;
+        mUnpackSkipImages = unpack.skipImages;
         mFunctions->pixelStorei(GL_UNPACK_SKIP_IMAGES, mUnpackSkipImages);
 
-        mLocalDirtyBits.set(gl::State::DIRTY_BIT_UNPACK_SKIP_IMAGES);
+        mLocalDirtyBits.set(gl::State::DIRTY_BIT_UNPACK_STATE);
     }
+}
 
-    bindBuffer(GL_PIXEL_UNPACK_BUFFER, unpackBuffer);
+void StateManagerGL::setPixelUnpackBuffer(const gl::Buffer *pixelBuffer)
+{
+    GLuint bufferID = 0;
+    if (pixelBuffer != nullptr)
+    {
+        bufferID = GetImplAs<BufferGL>(pixelBuffer)->getBufferID();
+    }
+    bindBuffer(gl::BufferBinding::PixelUnpack, bufferID);
 }
 
 void StateManagerGL::setPixelPackState(const gl::PixelPackState &pack)
 {
-    GLuint packBufferID          = 0;
-    const gl::Buffer *packBuffer = pack.pixelBuffer.get();
-    if (packBuffer != nullptr)
+    if (mPackAlignment != pack.alignment)
     {
-        packBufferID = GetImplAs<BufferGL>(packBuffer)->getBufferID();
-    }
-    setPixelPackState(pack.alignment, pack.rowLength, pack.skipRows, pack.skipPixels, packBufferID);
-}
-
-void StateManagerGL::setPixelPackState(GLint alignment,
-                                       GLint rowLength,
-                                       GLint skipRows,
-                                       GLint skipPixels,
-                                       GLuint packBuffer)
-{
-    if (mPackAlignment != alignment)
-    {
-        mPackAlignment = alignment;
+        mPackAlignment = pack.alignment;
         mFunctions->pixelStorei(GL_PACK_ALIGNMENT, mPackAlignment);
 
-        mLocalDirtyBits.set(gl::State::DIRTY_BIT_PACK_ALIGNMENT);
+        mLocalDirtyBits.set(gl::State::DIRTY_BIT_PACK_STATE);
+    }
+
+    if (mPackRowLength != pack.rowLength)
+    {
+        mPackRowLength = pack.rowLength;
+        mFunctions->pixelStorei(GL_PACK_ROW_LENGTH, mPackRowLength);
+
+        mLocalDirtyBits.set(gl::State::DIRTY_BIT_PACK_STATE);
     }
 
-    if (mPackRowLength != rowLength)
+    if (mPackSkipRows != pack.skipRows)
     {
-        mPackRowLength = rowLength;
-        mFunctions->pixelStorei(GL_PACK_ROW_LENGTH, mPackRowLength);
-
-        mLocalDirtyBits.set(gl::State::DIRTY_BIT_UNPACK_ROW_LENGTH);
-    }
-
-    if (mPackSkipRows != skipRows)
-    {
-        mPackSkipRows = skipRows;
+        mPackSkipRows = pack.skipRows;
         mFunctions->pixelStorei(GL_PACK_SKIP_ROWS, mPackSkipRows);
 
-        // TODO: set dirty bit once one exists
+        mLocalDirtyBits.set(gl::State::DIRTY_BIT_PACK_STATE);
     }
 
-    if (mPackSkipPixels != skipPixels)
+    if (mPackSkipPixels != pack.skipPixels)
     {
-        mPackSkipPixels = skipPixels;
+        mPackSkipPixels = pack.skipPixels;
         mFunctions->pixelStorei(GL_PACK_SKIP_PIXELS, mPackSkipPixels);
 
-        // TODO: set dirty bit once one exists
+        mLocalDirtyBits.set(gl::State::DIRTY_BIT_PACK_STATE);
     }
+}
 
-    bindBuffer(GL_PIXEL_PACK_BUFFER, packBuffer);
+void StateManagerGL::setPixelPackBuffer(const gl::Buffer *pixelBuffer)
+{
+    GLuint bufferID = 0;
+    if (pixelBuffer != nullptr)
+    {
+        bufferID = GetImplAs<BufferGL>(pixelBuffer)->getBufferID();
+    }
+    bindBuffer(gl::BufferBinding::PixelPack, bufferID);
 }
 
 void StateManagerGL::bindFramebuffer(GLenum type, GLuint framebuffer)
 {
     if (type == GL_FRAMEBUFFER)
     {
         if (mFramebuffers[angle::FramebufferBindingRead] != framebuffer ||
             mFramebuffers[angle::FramebufferBindingDraw] != framebuffer)
@@ -649,28 +642,34 @@ void StateManagerGL::bindRenderbuffer(GL
 void StateManagerGL::bindTransformFeedback(GLenum type, GLuint transformFeedback)
 {
     ASSERT(type == GL_TRANSFORM_FEEDBACK);
     if (mTransformFeedback != transformFeedback)
     {
         // Pause the current transform feedback if one is active.
         // To handle virtualized contexts, StateManagerGL needs to be able to bind a new transform
         // feedback at any time, even if there is one active.
-        if (mPrevDrawTransformFeedback != nullptr &&
-            mPrevDrawTransformFeedback->getTransformFeedbackID() != transformFeedback)
+        if (mCurrentTransformFeedback != nullptr &&
+            mCurrentTransformFeedback->getTransformFeedbackID() != transformFeedback)
         {
-            mPrevDrawTransformFeedback->syncPausedState(true);
-            mPrevDrawTransformFeedback = nullptr;
+            mCurrentTransformFeedback->syncPausedState(true);
+            mCurrentTransformFeedback = nullptr;
         }
 
         mTransformFeedback = transformFeedback;
         mFunctions->bindTransformFeedback(type, mTransformFeedback);
+        onTransformFeedbackStateChange();
     }
 }
 
+void StateManagerGL::onTransformFeedbackStateChange()
+{
+    mLocalDirtyBits.set(gl::State::DIRTY_BIT_TRANSFORM_FEEDBACK_BINDING);
+}
+
 void StateManagerGL::beginQuery(GLenum type, GLuint query)
 {
     // Make sure this is a valid query type and there is no current active query of this type
     ASSERT(mQueries.find(type) != mQueries.end());
     ASSERT(mQueries[type] == 0);
     ASSERT(query != 0);
 
     mQueries[type] = query;
@@ -749,35 +748,52 @@ gl::Error StateManagerGL::setDrawIndirec
     const VertexArrayGL *vaoGL = GetImplAs<VertexArrayGL>(vao);
 
     if (type != GL_NONE)
     {
         ANGLE_TRY(vaoGL->syncElementArrayState(context));
     }
     bindVertexArray(vaoGL->getVertexArrayID(), vaoGL->getAppliedElementArrayBufferID());
 
-    gl::Buffer *drawIndirectBuffer = glState.getDrawIndirectBuffer();
+    gl::Buffer *drawIndirectBuffer = glState.getTargetBuffer(gl::BufferBinding::DrawIndirect);
     ASSERT(drawIndirectBuffer);
     const BufferGL *bufferGL = GetImplAs<BufferGL>(drawIndirectBuffer);
-    bindBuffer(GL_DRAW_INDIRECT_BUFFER, bufferGL->getBufferID());
+    bindBuffer(gl::BufferBinding::DrawIndirect, bufferGL->getBufferID());
 
     return setGenericDrawState(context);
 }
 
-gl::Error StateManagerGL::setDispatchComputeState(const gl::Context *context)
+void StateManagerGL::updateProgramDispatchIndirectBufferBinding(const gl::Context *context)
+{
+    gl::Buffer *dispatchIndirectBuffer =
+        context->getGLState().getTargetBuffer(gl::BufferBinding::DispatchIndirect);
+    ASSERT(dispatchIndirectBuffer);
+    const BufferGL *bufferGL = GetImplAs<BufferGL>(dispatchIndirectBuffer);
+    bindBuffer(gl::BufferBinding::DispatchIndirect, bufferGL->getBufferID());
+}
+
+gl::Error StateManagerGL::setDispatchComputeState(const gl::Context *context, bool isIndirect)
 {
     setGenericShaderState(context);
+
+    if (isIndirect && mProgramDispatchIndirectBufferDirty)
+    {
+        updateProgramDispatchIndirectBufferBinding(context);
+        mProgramDispatchIndirectBufferDirty = false;
+    }
+
     return gl::NoError();
 }
 
 void StateManagerGL::pauseTransformFeedback()
 {
-    if (mPrevDrawTransformFeedback != nullptr)
+    if (mCurrentTransformFeedback != nullptr)
     {
-        mPrevDrawTransformFeedback->syncPausedState(true);
+        mCurrentTransformFeedback->syncPausedState(true);
+        onTransformFeedbackStateChange();
     }
 }
 
 gl::Error StateManagerGL::pauseAllQueries()
 {
     for (QueryGL *prevQuery : mCurrentQueries)
     {
         ANGLE_TRY(prevQuery->pause());
@@ -824,17 +840,17 @@ gl::Error StateManagerGL::onMakeCurrent(
 
     // If the context has changed, pause the previous context's queries
     auto contextID = context->getContextState().getContextID();
     if (contextID != mPrevDrawContext)
     {
         ANGLE_TRY(pauseAllQueries());
     }
     mCurrentQueries.clear();
-    mPrevDrawTransformFeedback = nullptr;
+    onTransformFeedbackStateChange();
     mPrevDrawContext           = contextID;
 
     // Set the current query state
     for (GLenum queryType : QueryTypes)
     {
         gl::Query *query = glState.getActiveQuery(queryType);
         if (query != nullptr)
         {
@@ -853,47 +869,50 @@ gl::Error StateManagerGL::onMakeCurrent(
 }
 
 void StateManagerGL::setGenericShaderState(const gl::Context *context)
 {
     const gl::State &glState = context->getGLState();
 
     // Sync the current program state
     const gl::Program *program = glState.getProgram();
-    const ProgramGL *programGL = GetImplAs<ProgramGL>(program);
-    useProgram(programGL->getProgramID());
-
     for (size_t uniformBlockIndex = 0; uniformBlockIndex < program->getActiveUniformBlockCount();
          uniformBlockIndex++)
     {
         GLuint binding = program->getUniformBlockBinding(static_cast<GLuint>(uniformBlockIndex));
         const auto &uniformBuffer = glState.getIndexedUniformBuffer(binding);
 
         if (uniformBuffer.get() != nullptr)
         {
             BufferGL *bufferGL = GetImplAs<BufferGL>(uniformBuffer.get());
 
             if (uniformBuffer.getSize() == 0)
             {
-                bindBufferBase(GL_UNIFORM_BUFFER, binding, bufferGL->getBufferID());
+                bindBufferBase(gl::BufferBinding::Uniform, binding, bufferGL->getBufferID());
             }
             else
             {
-                bindBufferRange(GL_UNIFORM_BUFFER, binding, bufferGL->getBufferID(),
+                bindBufferRange(gl::BufferBinding::Uniform, binding, bufferGL->getBufferID(),
                                 uniformBuffer.getOffset(), uniformBuffer.getSize());
             }
         }
     }
 
     if (mProgramTexturesAndSamplersDirty)
     {
         updateProgramTextureAndSamplerBindings(context);
         mProgramTexturesAndSamplersDirty = false;
     }
 
+    if (mProgramStorageBuffersDirty)
+    {
+        updateProgramStorageBufferBindings(context);
+        mProgramStorageBuffersDirty = false;
+    }
+
     // TODO(xinghua.cao@intel.com): Track image units state with dirty bits to
     // avoid update every draw call.
     ASSERT(context->getClientVersion() >= gl::ES_3_1 || program->getImageBindings().size() == 0);
     for (const gl::ImageBinding &imageUniform : program->getImageBindings())
     {
         for (GLuint imageUnitIndex : imageUniform.boundImageUnits)
         {
             const gl::ImageUnit &imageUnit = glState.getImageUnit(imageUnitIndex);
@@ -918,21 +937,21 @@ void StateManagerGL::setGenericShaderSta
         const auto &buffer = glState.getIndexedAtomicCounterBuffer(binding);
 
         if (buffer.get() != nullptr)
         {
             BufferGL *bufferGL = GetImplAs<BufferGL>(buffer.get());
 
             if (buffer.getSize() == 0)
             {
-                bindBufferBase(GL_ATOMIC_COUNTER_BUFFER, binding, bufferGL->getBufferID());
+                bindBufferBase(gl::BufferBinding::AtomicCounter, binding, bufferGL->getBufferID());
             }
             else
             {
-                bindBufferRange(GL_ATOMIC_COUNTER_BUFFER, binding, bufferGL->getBufferID(),
+                bindBufferRange(gl::BufferBinding::AtomicCounter, binding, bufferGL->getBufferID(),
                                 buffer.getOffset(), buffer.getSize());
             }
         }
     }
 }
 
 void StateManagerGL::updateProgramTextureAndSamplerBindings(const gl::Context *context)
 {
@@ -979,68 +998,56 @@ void StateManagerGL::updateProgramTextur
                 bindSampler(textureUnitIndex, samplerGL->getSamplerID());
             }
             else
             {
                 bindSampler(textureUnitIndex, 0);
             }
         }
     }
+}
+
+void StateManagerGL::updateProgramStorageBufferBindings(const gl::Context *context)
+{
+    const gl::State &glState   = context->getGLState();
+    const gl::Program *program = glState.getProgram();
 
     for (size_t blockIndex = 0; blockIndex < program->getActiveShaderStorageBlockCount();
          blockIndex++)
     {
         GLuint binding = program->getShaderStorageBlockBinding(static_cast<GLuint>(blockIndex));
         const auto &shaderStorageBuffer = glState.getIndexedShaderStorageBuffer(binding);
 
         if (shaderStorageBuffer.get() != nullptr)
         {
             BufferGL *bufferGL = GetImplAs<BufferGL>(shaderStorageBuffer.get());
 
             if (shaderStorageBuffer.getSize() == 0)
             {
-                bindBufferBase(GL_SHADER_STORAGE_BUFFER, binding, bufferGL->getBufferID());
+                bindBufferBase(gl::BufferBinding::ShaderStorage, binding, bufferGL->getBufferID());
             }
             else
             {
-                bindBufferRange(GL_SHADER_STORAGE_BUFFER, binding, bufferGL->getBufferID(),
+                bindBufferRange(gl::BufferBinding::ShaderStorage, binding, bufferGL->getBufferID(),
                                 shaderStorageBuffer.getOffset(), shaderStorageBuffer.getSize());
             }
         }
     }
 }
 
 gl::Error StateManagerGL::setGenericDrawState(const gl::Context *context)
 {
     setGenericShaderState(context);
 
     const gl::State &glState = context->getGLState();
 
     gl::Framebuffer *framebuffer = glState.getDrawFramebuffer();
     FramebufferGL *framebufferGL = GetImplAs<FramebufferGL>(framebuffer);
     bindFramebuffer(GL_DRAW_FRAMEBUFFER, framebufferGL->getFramebufferID());
 
-    // Set the current transform feedback state
-    gl::TransformFeedback *transformFeedback = glState.getCurrentTransformFeedback();
-    if (transformFeedback)
-    {
-        TransformFeedbackGL *transformFeedbackGL =
-            GetImplAs<TransformFeedbackGL>(transformFeedback);
-        bindTransformFeedback(GL_TRANSFORM_FEEDBACK, transformFeedbackGL->getTransformFeedbackID());
-        transformFeedbackGL->syncActiveState(transformFeedback->isActive(),
-                                             transformFeedback->getPrimitiveMode());
-        transformFeedbackGL->syncPausedState(transformFeedback->isPaused());
-        mPrevDrawTransformFeedback = transformFeedbackGL;
-    }
-    else
-    {
-        bindTransformFeedback(GL_TRANSFORM_FEEDBACK, 0);
-        mPrevDrawTransformFeedback = nullptr;
-    }
-
     if (context->getExtensions().webglCompatibility)
     {
         auto activeOutputs = glState.getProgram()->getState().getActiveOutputVariables();
         framebufferGL->maskOutInactiveOutputDrawBuffers(activeOutputs);
     }
 
     return gl::NoError();
 }
@@ -1064,17 +1071,18 @@ void StateManagerGL::setAttributeCurrent
             case GL_UNSIGNED_INT:
                 mFunctions->vertexAttribI4uiv(static_cast<GLuint>(index),
                                               mVertexAttribCurrentValues[index].UnsignedIntValues);
                 break;
             default:
                 UNREACHABLE();
         }
 
-        mLocalDirtyBits.set(gl::State::DIRTY_BIT_CURRENT_VALUE_0 + index);
+        mLocalDirtyBits.set(gl::State::DIRTY_BIT_CURRENT_VALUES);
+        mLocalDirtyCurrentValues.set(index);
     }
 }
 
 void StateManagerGL::setScissorTestEnabled(bool enabled)
 {
     if (mScissorTestEnabled != enabled)
     {
         mScissorTestEnabled = enabled;
@@ -1357,17 +1365,17 @@ void StateManagerGL::setSampleMaskEnable
 void StateManagerGL::setSampleMaski(GLuint maskNumber, GLbitfield mask)
 {
     ASSERT(maskNumber < mSampleMaskValues.size());
     if (mSampleMaskValues[maskNumber] != mask)
     {
         mSampleMaskValues[maskNumber] = mask;
         mFunctions->sampleMaski(maskNumber, mask);
 
-        mLocalDirtyBits.set(gl::State::DIRTY_BIT_SAMPLE_MASK_WORD_0 + maskNumber);
+        mLocalDirtyBits.set(gl::State::DIRTY_BIT_SAMPLE_MASK);
     }
 }
 
 void StateManagerGL::setDepthTestEnabled(bool enabled)
 {
     if (mDepthTestEnabled != enabled)
     {
         mDepthTestEnabled = enabled;
@@ -1519,22 +1527,22 @@ void StateManagerGL::setCullFaceEnabled(
         {
             mFunctions->disable(GL_CULL_FACE);
         }
 
         mLocalDirtyBits.set(gl::State::DIRTY_BIT_CULL_FACE_ENABLED);
     }
 }
 
-void StateManagerGL::setCullFace(GLenum cullFace)
+void StateManagerGL::setCullFace(gl::CullFaceMode cullFace)
 {
     if (mCullFace != cullFace)
     {
         mCullFace = cullFace;
-        mFunctions->cullFace(mCullFace);
+        mFunctions->cullFace(ToGLenum(mCullFace));
 
         mLocalDirtyBits.set(gl::State::DIRTY_BIT_CULL_FACE);
     }
 }
 
 void StateManagerGL::setFrontFace(GLenum frontFace)
 {
     if (mFrontFace != frontFace)
@@ -1668,17 +1676,17 @@ void StateManagerGL::setClearStencil(GLi
         mLocalDirtyBits.set(gl::State::DIRTY_BIT_CLEAR_STENCIL);
     }
 }
 
 void StateManagerGL::syncState(const gl::Context *context, const gl::State::DirtyBits &glDirtyBits)
 {
     const gl::State &state = context->getGLState();
 
-    // The the current framebuffer binding sometimes requires resetting the srgb blending
+    // Changing the draw framebuffer binding sometimes requires resetting srgb blending.
     if (glDirtyBits[gl::State::DIRTY_BIT_DRAW_FRAMEBUFFER_BINDING])
     {
         if (mFunctions->standard == STANDARD_GL_DESKTOP)
         {
             mLocalDirtyBits.set(gl::State::DIRTY_BIT_FRAMEBUFFER_SRGB);
         }
 
         if (mIsMultiviewEnabled)
@@ -1690,44 +1698,48 @@ void StateManagerGL::syncState(const gl:
             mMultiviewDirtyBits.set(MULTIVIEW_DIRTY_BIT_VIEWPORT_OFFSETS);
             mLocalDirtyBits.set(gl::State::DIRTY_BIT_SCISSOR_TEST_ENABLED);
             mLocalDirtyBits.set(gl::State::DIRTY_BIT_SCISSOR);
             mLocalDirtyBits.set(gl::State::DIRTY_BIT_VIEWPORT);
         }
     }
 
     // Iterate over and resolve multi-view dirty bits.
-    for (auto dirtyBit : mMultiviewDirtyBits)
+    if (mMultiviewDirtyBits.any())
     {
-        switch (dirtyBit)
+        for (auto dirtyBit : mMultiviewDirtyBits)
         {
-            case MULTIVIEW_DIRTY_BIT_SIDE_BY_SIDE_LAYOUT:
-            {
-                const gl::Framebuffer *drawFramebuffer = state.getDrawFramebuffer();
-                ASSERT(drawFramebuffer != nullptr);
-                setSideBySide(drawFramebuffer->getMultiviewLayout() ==
-                              GL_FRAMEBUFFER_MULTIVIEW_SIDE_BY_SIDE_ANGLE);
-            }
-            break;
-            case MULTIVIEW_DIRTY_BIT_VIEWPORT_OFFSETS:
+            switch (dirtyBit)
             {
-                const gl::Framebuffer *drawFramebuffer = state.getDrawFramebuffer();
-                ASSERT(drawFramebuffer != nullptr);
-                const std::vector<gl::Offset> *attachmentViewportOffsets =
-                    drawFramebuffer->getViewportOffsets();
-                const std::vector<gl::Offset> &viewportOffsets =
-                    attachmentViewportOffsets != nullptr
-                        ? *attachmentViewportOffsets
-                        : gl::FramebufferAttachment::GetDefaultViewportOffsetVector();
-                setViewportOffsets(viewportOffsets);
+                case MULTIVIEW_DIRTY_BIT_SIDE_BY_SIDE_LAYOUT:
+                {
+                    const gl::Framebuffer *drawFramebuffer = state.getDrawFramebuffer();
+                    ASSERT(drawFramebuffer != nullptr);
+                    setSideBySide(drawFramebuffer->getMultiviewLayout() ==
+                                  GL_FRAMEBUFFER_MULTIVIEW_SIDE_BY_SIDE_ANGLE);
+                }
+                break;
+                case MULTIVIEW_DIRTY_BIT_VIEWPORT_OFFSETS:
+                {
+                    const gl::Framebuffer *drawFramebuffer = state.getDrawFramebuffer();
+                    ASSERT(drawFramebuffer != nullptr);
+                    const std::vector<gl::Offset> *attachmentViewportOffsets =
+                        drawFramebuffer->getViewportOffsets();
+                    const std::vector<gl::Offset> &viewportOffsets =
+                        attachmentViewportOffsets != nullptr
+                            ? *attachmentViewportOffsets
+                            : gl::FramebufferAttachment::GetDefaultViewportOffsetVector();
+                    setViewportOffsets(viewportOffsets);
+                }
+                break;
+                default:
+                    UNREACHABLE();
             }
-            break;
-            default:
-                UNREACHABLE();
         }
+        mMultiviewDirtyBits.reset();
     }
 
     const gl::State::DirtyBits &glAndLocalDirtyBits = (glDirtyBits | mLocalDirtyBits);
 
     if (!glAndLocalDirtyBits.any())
     {
         return;
     }
@@ -1888,67 +1900,27 @@ void StateManagerGL::syncState(const gl:
                 setClearColor(state.getColorClearValue());
                 break;
             case gl::State::DIRTY_BIT_CLEAR_DEPTH:
                 setClearDepth(state.getDepthClearValue());
                 break;
             case gl::State::DIRTY_BIT_CLEAR_STENCIL:
                 setClearStencil(state.getStencilClearValue());
                 break;
-            case gl::State::DIRTY_BIT_UNPACK_ALIGNMENT:
-                // TODO(jmadill): split this
-                setPixelUnpackState(state.getUnpackState());
-                break;
-            case gl::State::DIRTY_BIT_UNPACK_ROW_LENGTH:
-                // TODO(jmadill): split this
-                setPixelUnpackState(state.getUnpackState());
-                break;
-            case gl::State::DIRTY_BIT_UNPACK_IMAGE_HEIGHT:
-                // TODO(jmadill): split this
-                setPixelUnpackState(state.getUnpackState());
-                break;
-            case gl::State::DIRTY_BIT_UNPACK_SKIP_IMAGES:
-                // TODO(jmadill): split this
-                setPixelUnpackState(state.getUnpackState());
-                break;
-            case gl::State::DIRTY_BIT_UNPACK_SKIP_ROWS:
-                // TODO(jmadill): split this
-                setPixelUnpackState(state.getUnpackState());
-                break;
-            case gl::State::DIRTY_BIT_UNPACK_SKIP_PIXELS:
-                // TODO(jmadill): split this
+            case gl::State::DIRTY_BIT_UNPACK_STATE:
                 setPixelUnpackState(state.getUnpackState());
                 break;
             case gl::State::DIRTY_BIT_UNPACK_BUFFER_BINDING:
-                // TODO(jmadill): split this
-                setPixelUnpackState(state.getUnpackState());
-                break;
-            case gl::State::DIRTY_BIT_PACK_ALIGNMENT:
-                // TODO(jmadill): split this
-                setPixelPackState(state.getPackState());
-                break;
-            case gl::State::DIRTY_BIT_PACK_REVERSE_ROW_ORDER:
-                // TODO(jmadill): split this
-                setPixelPackState(state.getPackState());
+                setPixelUnpackBuffer(state.getTargetBuffer(gl::BufferBinding::PixelUnpack));
                 break;
-            case gl::State::DIRTY_BIT_PACK_ROW_LENGTH:
-                // TODO(jmadill): split this
-                setPixelPackState(state.getPackState());
-                break;
-            case gl::State::DIRTY_BIT_PACK_SKIP_ROWS:
-                // TODO(jmadill): split this
-                setPixelPackState(state.getPackState());
-                break;
-            case gl::State::DIRTY_BIT_PACK_SKIP_PIXELS:
-                // TODO(jmadill): split this
+            case gl::State::DIRTY_BIT_PACK_STATE:
                 setPixelPackState(state.getPackState());
                 break;
             case gl::State::DIRTY_BIT_PACK_BUFFER_BINDING:
-                // TODO(jmadill): split this
-                setPixelPackState(state.getPackState());
+                setPixelPackBuffer(state.getTargetBuffer(gl::BufferBinding::PixelPack));
                 break;
             case gl::State::DIRTY_BIT_DITHER_ENABLED:
                 setDitherEnabled(state.isDitherEnabled());
                 break;
             case gl::State::DIRTY_BIT_GENERATE_MIPMAP_HINT:
                 // TODO(jmadill): implement this
                 break;
             case gl::State::DIRTY_BIT_SHADER_DERIVATIVE_HINT:
@@ -1971,38 +1943,60 @@ void StateManagerGL::syncState(const gl:
             case gl::State::DIRTY_BIT_VERTEX_ARRAY_BINDING:
                 // TODO(jmadill): implement this
                 propagateNumViewsToVAO(state.getProgram(),
                                        GetImplAs<VertexArrayGL>(state.getVertexArray()));
                 break;
             case gl::State::DIRTY_BIT_DRAW_INDIRECT_BUFFER_BINDING:
                 // TODO: implement this
                 break;
+            case gl::State::DIRTY_BIT_DISPATCH_INDIRECT_BUFFER_BINDING:
+                mProgramDispatchIndirectBufferDirty = true;
+                break;
             case gl::State::DIRTY_BIT_PROGRAM_BINDING:
+            {
                 mProgramTexturesAndSamplersDirty = true;
+                mProgramStorageBuffersDirty      = true;
+                gl::Program *program = state.getProgram();
+                if (program != nullptr)
+                {
+                    useProgram(GetImplAs<ProgramGL>(program)->getProgramID());
+                }
                 break;
+            }
             case gl::State::DIRTY_BIT_TEXTURE_BINDINGS:
                 mProgramTexturesAndSamplersDirty = true;
                 break;
             case gl::State::DIRTY_BIT_SAMPLER_BINDINGS:
                 mProgramTexturesAndSamplersDirty = true;
                 break;
+            case gl::State::DIRTY_BIT_TRANSFORM_FEEDBACK_BINDING:
+                syncTransformFeedbackState(context);
+                break;
             case gl::State::DIRTY_BIT_PROGRAM_EXECUTABLE:
                 mProgramTexturesAndSamplersDirty = true;
+                mProgramStorageBuffersDirty      = true;
                 propagateNumViewsToVAO(state.getProgram(),
                                        GetImplAs<VertexArrayGL>(state.getVertexArray()));
                 updateMultiviewBaseViewLayerIndexUniform(
                     state.getProgram(),
                     state.getDrawFramebuffer()->getImplementation()->getState());
                 break;
+            case gl::State::DIRTY_BIT_SHADER_STORAGE_BUFFER_BINDING:
+                mProgramStorageBuffersDirty = true;
+                break;
+            case gl::State::DIRTY_BIT_UNIFORM_BUFFER_BINDINGS:
+                // TODO(jmadll): State update.
+                break;
             case gl::State::DIRTY_BIT_MULTISAMPLING:
                 setMultisamplingStateEnabled(state.isMultisamplingEnabled());
                 break;
             case gl::State::DIRTY_BIT_SAMPLE_ALPHA_TO_ONE:
                 setSampleAlphaToOneStateEnabled(state.isSampleAlphaToOneEnabled());
+                break;
             case gl::State::DIRTY_BIT_COVERAGE_MODULATION:
                 setCoverageModulation(state.getCoverageModulation());
                 break;
             case gl::State::DIRTY_BIT_PATH_RENDERING_MATRIX_MV:
                 setPathRenderingModelViewMatrix(
                     state.getPathRenderingMatrix(GL_PATH_MODELVIEW_MATRIX_CHROMIUM));
                 break;
             case gl::State::DIRTY_BIT_PATH_RENDERING_MATRIX_PROJ:
@@ -2016,44 +2010,41 @@ void StateManagerGL::syncState(const gl:
             case gl::State::DIRTY_BIT_FRAMEBUFFER_SRGB:
                 setFramebufferSRGBEnabledForFramebuffer(
                     context, state.getFramebufferSRGB(),
                     GetImplAs<FramebufferGL>(state.getDrawFramebuffer()));
                 break;
             case gl::State::DIRTY_BIT_SAMPLE_MASK_ENABLED:
                 setSampleMaskEnabled(state.isSampleMaskEnabled());
                 break;
-            default:
+            case gl::State::DIRTY_BIT_SAMPLE_MASK:
             {
-                if (dirtyBit >= gl::State::DIRTY_BIT_CURRENT_VALUE_0 &&
-                    dirtyBit < gl::State::DIRTY_BIT_CURRENT_VALUE_MAX)
+                for (GLuint maskNumber = 0; maskNumber < state.getMaxSampleMaskWords();
+                     ++maskNumber)
                 {
-                    size_t attribIndex =
-                        static_cast<size_t>(dirtyBit) - gl::State::DIRTY_BIT_CURRENT_VALUE_0;
+                    setSampleMaski(maskNumber, state.getSampleMaskWord(maskNumber));
+                }
+                break;
+            }
+            case gl::State::DIRTY_BIT_CURRENT_VALUES:
+            {
+                gl::AttributesMask combinedMask =
+                    (state.getAndResetDirtyCurrentValues() | mLocalDirtyCurrentValues);
+                mLocalDirtyCurrentValues.reset();
+
+                for (auto attribIndex : combinedMask)
+                {
                     setAttributeCurrentData(attribIndex,
                                             state.getVertexAttribCurrentValue(attribIndex));
-                    break;
                 }
-                else if (dirtyBit >= gl::State::DIRTY_BIT_SAMPLE_MASK_WORD_0 &&
-                         dirtyBit < gl::State::DIRTY_BIT_SAMPLE_MASK_WORD_MAX)
-                {
-                    GLuint maskNumber =
-                        static_cast<GLuint>(dirtyBit) - gl::State::DIRTY_BIT_SAMPLE_MASK_WORD_0;
-                    // Only set the available sample mask values.
-                    if (maskNumber < state.getMaxSampleMaskWords())
-                    {
-                        setSampleMaski(maskNumber, state.getSampleMaskWord(maskNumber));
-                    }
-                    break;
-                }
-                else
-                {
-                    UNREACHABLE();
-                }
+                break;
             }
+            default:
+                UNREACHABLE();
+                break;
         }
 
         mLocalDirtyBits.reset();
     }
 }
 
 void StateManagerGL::setFramebufferSRGBEnabled(const gl::Context *context, bool enabled)
 {
@@ -2157,28 +2148,28 @@ void StateManagerGL::setCoverageModulati
     }
 }
 
 void StateManagerGL::setPathRenderingModelViewMatrix(const GLfloat *m)
 {
     if (memcmp(mPathMatrixMV, m, sizeof(mPathMatrixMV)) != 0)
     {
         memcpy(mPathMatrixMV, m, sizeof(mPathMatrixMV));
-        mFunctions->matrixLoadEXT(GL_PATH_MODELVIEW_CHROMIUM, m);
+        mFunctions->matrixLoadfEXT(GL_PATH_MODELVIEW_CHROMIUM, m);
 
         mLocalDirtyBits.set(gl::State::DIRTY_BIT_PATH_RENDERING_MATRIX_MV);
     }
 }
 
 void StateManagerGL::setPathRenderingProjectionMatrix(const GLfloat *m)
 {
     if (memcmp(mPathMatrixProj, m, sizeof(mPathMatrixProj)) != 0)
     {
         memcpy(mPathMatrixProj, m, sizeof(mPathMatrixProj));
-        mFunctions->matrixLoadEXT(GL_PATH_PROJECTION_CHROMIUM, m);
+        mFunctions->matrixLoadfEXT(GL_PATH_PROJECTION_CHROMIUM, m);
 
         mLocalDirtyBits.set(gl::State::DIRTY_BIT_PATH_RENDERING_MATRIX_PROJ);
     }
 }
 
 void StateManagerGL::setPathRenderingStencilState(GLenum func, GLint ref, GLuint mask)
 {
     if (func != mPathStencilFunc || ref != mPathStencilRef || mask != mPathStencilMask)
@@ -2271,9 +2262,30 @@ void StateManagerGL::updateMultiviewBase
             case GL_FRAMEBUFFER_MULTIVIEW_LAYERED_ANGLE:
                 programGL->enableLayeredRenderingPath(drawFramebufferState.getBaseViewIndex());
                 break;
             default:
                 break;
         }
     }
 }
+
+void StateManagerGL::syncTransformFeedbackState(const gl::Context *context)
+{
+    // Set the current transform feedback state
+    gl::TransformFeedback *transformFeedback = context->getGLState().getCurrentTransformFeedback();
+    if (transformFeedback)
+    {
+        TransformFeedbackGL *transformFeedbackGL =
+            GetImplAs<TransformFeedbackGL>(transformFeedback);
+        bindTransformFeedback(GL_TRANSFORM_FEEDBACK, transformFeedbackGL->getTransformFeedbackID());
+        transformFeedbackGL->syncActiveState(transformFeedback->isActive(),
+                                             transformFeedback->getPrimitiveMode());
+        transformFeedbackGL->syncPausedState(transformFeedback->isPaused());
+        mCurrentTransformFeedback = transformFeedbackGL;
+    }
+    else
+    {
+        bindTransformFeedback(GL_TRANSFORM_FEEDBACK, 0);
+        mCurrentTransformFeedback = nullptr;
+    }
 }
+}
--- a/gfx/angle/src/libANGLE/renderer/gl/StateManagerGL.h
+++ b/gfx/angle/src/libANGLE/renderer/gl/StateManagerGL.h
@@ -35,46 +35,52 @@ class VertexArrayGL;
 class QueryGL;
 
 class StateManagerGL final : angle::NonCopyable
 {
   public:
     StateManagerGL(const FunctionsGL *functions,
                    const gl::Caps &rendererCaps,
                    const gl::Extensions &extensions);
+    ~StateManagerGL();
 
     void deleteProgram(GLuint program);
     void deleteVertexArray(GLuint vao);
     void deleteTexture(GLuint texture);
     void deleteSampler(GLuint sampler);
     void deleteBuffer(GLuint buffer);
     void deleteFramebuffer(GLuint fbo);
     void deleteRenderbuffer(GLuint rbo);
     void deleteTransformFeedback(GLuint transformFeedback);
     void deleteQuery(GLuint query);
 
     void useProgram(GLuint program);
     void forceUseProgram(GLuint program);
     void bindVertexArray(GLuint vao, GLuint elementArrayBuffer);
-    void bindBuffer(GLenum type, GLuint buffer);
-    void bindBufferBase(GLenum type, size_t index, GLuint buffer);
-    void bindBufferRange(GLenum type, size_t index, GLuint buffer, size_t offset, size_t size);
+    void bindBuffer(gl::BufferBinding target, GLuint buffer);
+    void bindBufferBase(gl::BufferBinding target, size_t index, GLuint buffer);
+    void bindBufferRange(gl::BufferBinding target,
+                         size_t index,
+                         GLuint buffer,
+                         size_t offset,
+                         size_t size);
     void activeTexture(size_t unit);
     void bindTexture(GLenum type, GLuint texture);
     void bindSampler(size_t unit, GLuint sampler);
     void bindImageTexture(GLuint unit,
                           GLuint texture,
                           GLint level,
                           GLboolean layered,
                           GLint layer,
                           GLenum access,
                           GLenum format);
     void bindFramebuffer(GLenum type, GLuint framebuffer);
     void bindRenderbuffer(GLenum type, GLuint renderbuffer);
     void bindTransformFeedback(GLenum type, GLuint transformFeedback);
+    void onTransformFeedbackStateChange();
     void beginQuery(GLenum type, GLuint query);
     void endQuery(GLenum type, GLuint query);
     void onBeginQuery(QueryGL *query);
 
     void setAttributeCurrentData(size_t index, const gl::VertexAttribCurrentValueData &data);
 
     void setScissorTestEnabled(bool enabled);
     void setScissor(const gl::Rectangle &scissor);
@@ -109,43 +115,33 @@ class StateManagerGL final : angle::NonC
     void setStencilFrontWritemask(GLuint mask);
     void setStencilBackWritemask(GLuint mask);
     void setStencilFrontFuncs(GLenum func, GLint ref, GLuint mask);
     void setStencilBackFuncs(GLenum func, GLint ref, GLuint mask);
     void setStencilFrontOps(GLenum sfail, GLenum dpfail, GLenum dppass);
     void setStencilBackOps(GLenum sfail, GLenum dpfail, GLenum dppass);
 
     void setCullFaceEnabled(bool enabled);
-    void setCullFace(GLenum cullFace);
+    void setCullFace(gl::CullFaceMode cullFace);
     void setFrontFace(GLenum frontFace);
     void setPolygonOffsetFillEnabled(bool enabled);
     void setPolygonOffset(float factor, float units);
     void setRasterizerDiscardEnabled(bool enabled);
     void setLineWidth(float width);
 
     void setPrimitiveRestartEnabled(bool enabled);
 
     void setClearColor(const gl::ColorF &clearColor);
     void setClearDepth(float clearDepth);
     void setClearStencil(GLint clearStencil);
 
     void setPixelUnpackState(const gl::PixelUnpackState &unpack);
-    void setPixelUnpackState(GLint alignment,
-                             GLint rowLength,
-                             GLint skipRows,
-                             GLint skipPixels,
-                             GLint imageHeight,
-                             GLint skipImages,
-                             GLuint unpackBuffer);
+    void setPixelUnpackBuffer(const gl::Buffer *pixelBuffer);
     void setPixelPackState(const gl::PixelPackState &pack);
-    void setPixelPackState(GLint alignment,
-                           GLint rowLength,
-                           GLint skipRows,
-                           GLint skipPixels,
-                           GLuint packBuffer);
+    void setPixelPackBuffer(const gl::Buffer *pixelBuffer);
 
     void setFramebufferSRGBEnabled(const gl::Context *context, bool enabled);
     void setFramebufferSRGBEnabledForFramebuffer(const gl::Context *context,
                                                  bool enabled,
                                                  const FramebufferGL *framebuffer);
 
     void setDitherEnabled(bool enabled);
 
@@ -167,17 +163,17 @@ class StateManagerGL final : angle::NonC
     gl::Error setDrawElementsState(const gl::Context *context,
                                    GLsizei count,
                                    GLenum type,
                                    const void *indices,
                                    GLsizei instanceCount,
                                    const void **outIndices);
     gl::Error setDrawIndirectState(const gl::Context *context, GLenum type);
 
-    gl::Error setDispatchComputeState(const gl::Context *context);
+    gl::Error setDispatchComputeState(const gl::Context *context, bool isIndirect);
 
     void pauseTransformFeedback();
     gl::Error pauseAllQueries();
     gl::Error pauseQuery(GLenum type);
     gl::Error resumeAllQueries();
     gl::Error resumeQuery(GLenum type);
     gl::Error onMakeCurrent(const gl::Context *context);
 
@@ -198,42 +194,46 @@ class StateManagerGL final : angle::NonC
 
     void applyViewportOffsetsAndSetScissors(const gl::Rectangle &scissor,
                                             const gl::Framebuffer &drawFramebuffer);
     void applyViewportOffsetsAndSetViewports(const gl::Rectangle &viewport,
                                              const gl::Framebuffer &drawFramebuffer);
     void propagateNumViewsToVAO(const gl::Program *program, VertexArrayGL *vao);
 
     void updateProgramTextureAndSamplerBindings(const gl::Context *context);
+    void updateProgramStorageBufferBindings(const gl::Context *context);
+    void updateProgramDispatchIndirectBufferBinding(const gl::Context *context);
+
+    void syncTransformFeedbackState(const gl::Context *context);
 
     enum MultiviewDirtyBitType
     {
         MULTIVIEW_DIRTY_BIT_SIDE_BY_SIDE_LAYOUT,
         MULTIVIEW_DIRTY_BIT_VIEWPORT_OFFSETS,
         MULTIVIEW_DIRTY_BIT_MAX
     };
 
     const FunctionsGL *mFunctions;
 
     GLuint mProgram;
 
     GLuint mVAO;
     std::vector<gl::VertexAttribCurrentValueData> mVertexAttribCurrentValues;
 
-    std::map<GLenum, GLuint> mBuffers;
+    angle::PackedEnumMap<gl::BufferBinding, GLuint> mBuffers;
 
     struct IndexedBufferBinding
     {
         IndexedBufferBinding();
 
         size_t offset;
         size_t size;
         GLuint buffer;
     };
-    std::map<GLenum, std::vector<IndexedBufferBinding>> mIndexedBuffers;
+    angle::PackedEnumMap<gl::BufferBinding, std::vector<IndexedBufferBinding>> mIndexedBuffers;
 
     size_t mTextureUnitIndex;
     std::map<GLenum, std::vector<GLuint>> mTextures;
     std::vector<GLuint> mSamplers;
 
     struct ImageUnitBinding
     {
         ImageUnitBinding()
@@ -246,20 +246,19 @@ class StateManagerGL final : angle::NonC
         GLboolean layered;
         GLint layer;
         GLenum access;
         GLenum format;
     };
     std::vector<ImageUnitBinding> mImages;
 
     GLuint mTransformFeedback;
+    TransformFeedbackGL *mCurrentTransformFeedback;
 
     std::map<GLenum, GLuint> mQueries;
-
-    TransformFeedbackGL *mPrevDrawTransformFeedback;
     std::set<QueryGL *> mCurrentQueries;
     gl::ContextID mPrevDrawContext;
 
     GLint mUnpackAlignment;
     GLint mUnpackRowLength;
     GLint mUnpackSkipRows;
     GLint mUnpackSkipPixels;
     GLint mUnpackImageHeight;
@@ -315,17 +314,17 @@ class StateManagerGL final : angle::NonC
     GLint mStencilBackRef;
     GLuint mStencilBackValueMask;
     GLenum mStencilBackStencilFailOp;
     GLenum mStencilBackStencilPassDepthFailOp;
     GLenum mStencilBackStencilPassDepthPassOp;
     GLuint mStencilBackWritemask;
 
     bool mCullFaceEnabled;
-    GLenum mCullFace;
+    gl::CullFaceMode mCullFace;
     GLenum mFrontFace;
     bool mPolygonOffsetFillEnabled;
     GLfloat mPolygonOffsetFactor;
     GLfloat mPolygonOffsetUnits;
     bool mRasterizerDiscardEnabled;
     float mLineWidth;
 
     bool mPrimitiveRestartEnabled;
@@ -348,17 +347,20 @@ class StateManagerGL final : angle::NonC
     GLenum mPathStencilFunc;
     GLint mPathStencilRef;
     GLuint mPathStencilMask;
 
     bool mIsSideBySideDrawFramebuffer;
     const bool mIsMultiviewEnabled;
 
     gl::State::DirtyBits mLocalDirtyBits;
+    gl::AttributesMask mLocalDirtyCurrentValues;
 
     // ANGLE_multiview dirty bits.
     angle::BitSet<MULTIVIEW_DIRTY_BIT_MAX> mMultiviewDirtyBits;
 
     bool mProgramTexturesAndSamplersDirty;
+    bool mProgramStorageBuffersDirty;
+    bool mProgramDispatchIndirectBufferDirty;
 };
 }
 
 #endif  // LIBANGLE_RENDERER_GL_STATEMANAGERGL_H_
--- a/gfx/angle/src/libANGLE/renderer/gl/SurfaceGL.cpp
+++ b/gfx/angle/src/libANGLE/renderer/gl/SurfaceGL.cpp
@@ -35,9 +35,17 @@ egl::Error SurfaceGL::getSyncValues(EGLu
     UNREACHABLE();
     return egl::EglBadSurface();
 }
 
 egl::Error SurfaceGL::unMakeCurrent()
 {
     return egl::NoError();
 }
+
+gl::Error SurfaceGL::initializeContents(const gl::Context *context,
+                                        const gl::ImageIndex &imageIndex)
+{
+    // UNIMPLEMENTED();
+    return gl::NoError();
 }
+
+}  // namespace rx
--- a/gfx/angle/src/libANGLE/renderer/gl/SurfaceGL.h
+++ b/gfx/angle/src/libANGLE/renderer/gl/SurfaceGL.h
@@ -20,16 +20,19 @@ class SurfaceGL : public SurfaceImpl
 {
   public:
     SurfaceGL(const egl::SurfaceState &state, RendererGL *renderer);
     ~SurfaceGL() override;
 
     FramebufferImpl *createDefaultFramebuffer(const gl::FramebufferState &data) override;
     egl::Error getSyncValues(EGLuint64KHR *ust, EGLuint64KHR *msc, EGLuint64KHR *sbc) override;
 
+    gl::Error initializeContents(const gl::Context *context,
+                                 const gl::ImageIndex &imageIndex) override;
+
     virtual egl::Error makeCurrent() = 0;
     virtual egl::Error unMakeCurrent();
 
   private:
     RendererGL *mRenderer;
 };
 
 }
--- a/gfx/angle/src/libANGLE/renderer/gl/TextureGL.cpp
+++ b/gfx/angle/src/libANGLE/renderer/gl/TextureGL.cpp
@@ -10,16 +10,17 @@
 
 #include "common/bitset_utils.h"
 #include "common/debug.h"
 #include "common/utilities.h"
 #include "libANGLE/Context.h"
 #include "libANGLE/State.h"
 #include "libANGLE/angletypes.h"
 #include "libANGLE/formatutils.h"
+#include "libANGLE/queryconversions.h"
 #include "libANGLE/renderer/gl/BlitGL.h"
 #include "libANGLE/renderer/gl/BufferGL.h"
 #include "libANGLE/renderer/gl/FramebufferGL.h"
 #include "libANGLE/renderer/gl/FunctionsGL.h"
 #include "libANGLE/renderer/gl/StateManagerGL.h"
 #include "libANGLE/renderer/gl/WorkaroundsGL.h"
 #include "libANGLE/renderer/gl/formatutilsgl.h"
 #include "libANGLE/renderer/gl/renderergl_utils.h"
@@ -167,54 +168,58 @@ gl::Error TextureGL::setImage(const gl::
                               size_t level,
                               GLenum internalFormat,
                               const gl::Extents &size,
                               GLenum format,
                               GLenum type,
                               const gl::PixelUnpackState &unpack,
                               const uint8_t *pixels)
 {
-    if (mWorkarounds.unpackOverlappingRowsSeparatelyUnpackBuffer && unpack.pixelBuffer.get() &&
+    const gl::Buffer *unpackBuffer =
+        context->getGLState().getTargetBuffer(gl::BufferBinding::PixelUnpack);
+
+    if (mWorkarounds.unpackOverlappingRowsSeparatelyUnpackBuffer && unpackBuffer &&
         unpack.rowLength != 0 && unpack.rowLength < size.width)
     {
         // The rows overlap in unpack memory. Upload the texture row by row to work around
         // driver bug.
         reserveTexImageToBeFilled(target, level, internalFormat, size, format, type);
 
         if (size.width == 0 || size.height == 0 || size.depth == 0)
         {
             return gl::NoError();
         }
 
         gl::Box area(0, 0, 0, size.width, size.height, size.depth);
         return setSubImageRowByRowWorkaround(context, target, level, area, format, type, unpack,
-                                             pixels);
+                                             unpackBuffer, pixels);
     }
 
     if (mWorkarounds.unpackLastRowSeparatelyForPaddingInclusion)
     {
         bool apply;
-        ANGLE_TRY_RESULT(ShouldApplyLastRowPaddingWorkaround(size, unpack, format, type,
-                                                             UseTexImage3D(getTarget()), pixels),
-                         apply);
+        ANGLE_TRY_RESULT(
+            ShouldApplyLastRowPaddingWorkaround(size, unpack, unpackBuffer, format, type,
+                                                UseTexImage3D(getTarget()), pixels),
+            apply);
 
         // The driver will think the pixel buffer doesn't have enough data, work around this bug
         // by uploading the last row (and last level if 3D) separately.
         if (apply)
         {
             reserveTexImageToBeFilled(target, level, internalFormat, size, format, type);
 
             if (size.width == 0 || size.height == 0 || size.depth == 0)
             {
                 return gl::NoError();
             }
 
             gl::Box area(0, 0, 0, size.width, size.height, size.depth);
             return setSubImagePaddingWorkaround(context, target, level, area, format, type, unpack,
-                                                pixels);
+                                                unpackBuffer, pixels);
         }
     }
 
     setImageHelper(target, level, internalFormat, size, format, type, pixels);
 
     return gl::NoError();
 }
 
@@ -256,61 +261,63 @@ void TextureGL::setImageHelper(GLenum ta
 
 void TextureGL::reserveTexImageToBeFilled(GLenum target,
                                           size_t level,
                                           GLenum internalFormat,
                                           const gl::Extents &size,
                                           GLenum format,
                                           GLenum type)
 {
-    gl::PixelUnpackState unpack;
-    mStateManager->setPixelUnpackState(unpack);
+    mStateManager->setPixelUnpackBuffer(nullptr);
     setImageHelper(target, level, internalFormat, size, format, type, nullptr);
 }
 
 gl::Error TextureGL::setSubImage(const gl::Context *context,
                                  GLenum target,
                                  size_t level,
                                  const gl::Box &area,
                                  GLenum format,
                                  GLenum type,
                                  const gl::PixelUnpackState &unpack,
                                  const uint8_t *pixels)
 {
     ASSERT(CompatibleTextureTarget(getTarget(), target));
+    const gl::Buffer *unpackBuffer =
+        context->getGLState().getTargetBuffer(gl::BufferBinding::PixelUnpack);
 
     nativegl::TexSubImageFormat texSubImageFormat =
         nativegl::GetTexSubImageFormat(mFunctions, mWorkarounds, format, type);
 
     ASSERT(getLevelInfo(target, level).lumaWorkaround.enabled ==
            GetLevelInfo(format, texSubImageFormat.format).lumaWorkaround.enabled);
 
     mStateManager->bindTexture(getTarget(), mTextureID);
-    if (mWorkarounds.unpackOverlappingRowsSeparatelyUnpackBuffer && unpack.pixelBuffer.get() &&
+    if (mWorkarounds.unpackOverlappingRowsSeparatelyUnpackBuffer && unpackBuffer &&
         unpack.rowLength != 0 && unpack.rowLength < area.width)
     {
         return setSubImageRowByRowWorkaround(context, target, level, area, format, type, unpack,
-                                             pixels);
+                                             unpackBuffer, pixels);
     }
 
     if (mWorkarounds.unpackLastRowSeparatelyForPaddingInclusion)
     {
         gl::Extents size(area.width, area.height, area.depth);
 
         bool apply;
-        ANGLE_TRY_RESULT(ShouldApplyLastRowPaddingWorkaround(size, unpack, format, type,
-                                                             UseTexImage3D(getTarget()), pixels),
-                         apply);
+        ANGLE_TRY_RESULT(
+            ShouldApplyLastRowPaddingWorkaround(size, unpack, unpackBuffer, format, type,
+                                                UseTexImage3D(getTarget()), pixels),
+            apply);
 
         // The driver will think the pixel buffer doesn't have enough data, work around this bug
         // by uploading the last row (and last level if 3D) separately.
         if (apply)
         {
             return setSubImagePaddingWorkaround(context, target, level, area, format, type, unpack,
-                                                pixels);
+                                                unpackBuffer, pixels);
         }
     }
 
     if (UseTexImage2D(getTarget()))
     {
         ASSERT(area.z == 0 && area.depth == 1);
         mFunctions->texSubImage2D(target, static_cast<GLint>(level), area.x, area.y, area.width,
                                   area.height, texSubImageFormat.format, texSubImageFormat.type,
@@ -329,30 +336,30 @@ gl::Error TextureGL::setSubImage(const g
 
 gl::Error TextureGL::setSubImageRowByRowWorkaround(const gl::Context *context,
                                                    GLenum target,
                                                    size_t level,
                                                    const gl::Box &area,
                                                    GLenum format,
                                                    GLenum type,
                                                    const gl::PixelUnpackState &unpack,
+                                                   const gl::Buffer *unpackBuffer,
                                                    const uint8_t *pixels)
 {
     gl::PixelUnpackState directUnpack;
-    directUnpack.pixelBuffer.set(context, unpack.pixelBuffer.get());
     directUnpack.alignment   = 1;
     mStateManager->setPixelUnpackState(directUnpack);
-    directUnpack.pixelBuffer.set(context, nullptr);
+    mStateManager->setPixelUnpackBuffer(unpackBuffer);
 
-    const gl::InternalFormat &glFormat = gl::GetInternalFormatInfo(format, type);
-    GLuint rowBytes = 0;
-    ANGLE_TRY_RESULT(glFormat.computeRowPitch(area.width, unpack.alignment, unpack.rowLength),
+    const gl::InternalFormat &glFormat   = gl::GetInternalFormatInfo(format, type);
+    GLuint rowBytes                      = 0;
+    ANGLE_TRY_RESULT(glFormat.computeRowPitch(type, area.width, unpack.alignment, unpack.rowLength),
                      rowBytes);
     GLuint imageBytes = 0;
-    ANGLE_TRY_RESULT(gl::InternalFormat::computeDepthPitch(area.height, unpack.imageHeight, rowBytes),
+    ANGLE_TRY_RESULT(glFormat.computeDepthPitch(area.height, unpack.imageHeight, rowBytes),
                      imageBytes);
     bool useTexImage3D = UseTexImage3D(getTarget());
     GLuint skipBytes   = 0;
     ANGLE_TRY_RESULT(glFormat.computeSkipBytes(rowBytes, imageBytes, unpack, useTexImage3D),
                      skipBytes);
 
     const uint8_t *pixelsWithSkip = pixels + skipBytes;
     if (useTexImage3D)
@@ -386,34 +393,35 @@ gl::Error TextureGL::setSubImageRowByRow
 
 gl::Error TextureGL::setSubImagePaddingWorkaround(const gl::Context *context,
                                                   GLenum target,
                                                   size_t level,
                                                   const gl::Box &area,
                                                   GLenum format,
                                                   GLenum type,
                                                   const gl::PixelUnpackState &unpack,
+                                                  const gl::Buffer *unpackBuffer,
                                                   const uint8_t *pixels)
 {
     const gl::InternalFormat &glFormat = gl::GetInternalFormatInfo(format, type);
     GLuint rowBytes = 0;
-    ANGLE_TRY_RESULT(glFormat.computeRowPitch(area.width, unpack.alignment, unpack.rowLength),
+    ANGLE_TRY_RESULT(glFormat.computeRowPitch(type, area.width, unpack.alignment, unpack.rowLength),
                      rowBytes);
     GLuint imageBytes = 0;
-    ANGLE_TRY_RESULT(gl::InternalFormat::computeDepthPitch(area.height, unpack.imageHeight, rowBytes),
+    ANGLE_TRY_RESULT(glFormat.computeDepthPitch(area.height, unpack.imageHeight, rowBytes),
                      imageBytes);
     bool useTexImage3D = UseTexImage3D(getTarget());
     GLuint skipBytes   = 0;
     ANGLE_TRY_RESULT(glFormat.computeSkipBytes(rowBytes, imageBytes, unpack, useTexImage3D),
                      skipBytes);
 
     mStateManager->setPixelUnpackState(unpack);
+    mStateManager->setPixelUnpackBuffer(unpackBuffer);
 
     gl::PixelUnpackState directUnpack;
-    directUnpack.pixelBuffer.set(context, unpack.pixelBuffer.get());
     directUnpack.alignment   = 1;
 
     if (useTexImage3D)
     {
         // Upload all but the last slice
         if (area.depth > 1)
         {
             mFunctions->texSubImage3D(target, static_cast<GLint>(level), area.x, area.y, area.z,
@@ -459,18 +467,16 @@ gl::Error TextureGL::setSubImagePaddingW
 
         GLint lastRowOffset          = skipBytes + (area.height - 1) * rowBytes;
         const GLubyte *lastRowPixels = pixels + lastRowOffset;
         mFunctions->texSubImage2D(target, static_cast<GLint>(level), area.x,
                                   area.y + area.height - 1, area.width, 1, format, type,
                                   lastRowPixels);
     }
 
-    directUnpack.pixelBuffer.set(context, nullptr);
-
     return gl::NoError();
 }
 
 gl::Error TextureGL::setCompressedImage(const gl::Context *context,
                                         GLenum target,
                                         size_t level,
                                         GLenum internalFormat,
                                         const gl::Extents &size,
@@ -576,17 +582,22 @@ gl::Error TextureGL::copyImage(const gl:
     {
         // TODO(fjhenigman): When robust resource initialization is implemented, avoid redundant
         // clearing of the texture.
         GLuint pixelBytes =
             gl::GetInternalFormatInfo(copyTexImageFormat.internalFormat, type).pixelBytes;
         angle::MemoryBuffer *zero;
         ANGLE_TRY(context->getZeroFilledBuffer(
             origSourceArea.width * origSourceArea.height * pixelBytes, &zero));
-        mStateManager->setPixelUnpackState(gl::PixelUnpackState(1, 0));
+
+        gl::PixelUnpackState unpack;
+        unpack.alignment = 1;
+        mStateManager->setPixelUnpackState(unpack);
+        mStateManager->setPixelUnpackBuffer(nullptr);
+
         mFunctions->texImage2D(target, static_cast<GLint>(level), copyTexImageFormat.internalFormat,
                                origSourceArea.width, origSourceArea.height, 0,
                                gl::GetUnsizedFormat(copyTexImageFormat.internalFormat), type,
                                zero->data());
     }
 
     // Clip source area to framebuffer and copy if remaining area is not empty.
     gl::Rectangle sourceArea;
@@ -814,17 +825,17 @@ gl::Error TextureGL::setStorage(const gl
         if (mFunctions->texStorage2D)
         {
             mFunctions->texStorage2D(target, static_cast<GLsizei>(levels),
                                      texStorageFormat.internalFormat, size.width, size.height);
         }
         else
         {
             // Make sure no pixel unpack buffer is bound
-            mStateManager->bindBuffer(GL_PIXEL_UNPACK_BUFFER, 0);
+            mStateManager->bindBuffer(gl::BufferBinding::PixelUnpack, 0);
 
             const gl::InternalFormat &internalFormatInfo =
                 gl::GetSizedInternalFormatInfo(internalFormat);
 
             // Internal format must be sized
             ASSERT(internalFormatInfo.sized);
 
             for (size_t level = 0; level < levels; level++)
@@ -867,18 +878,17 @@ gl::Error TextureGL::setStorage(const gl
                     {
                         if (internalFormatInfo.compressed)
                         {
                             nativegl::CompressedTexSubImageFormat compressedTexImageFormat =
                                 nativegl::GetCompressedSubTexImageFormat(mFunctions, mWorkarounds,
                                                                          internalFormat);
 
                             GLuint dataSize = 0;
-                            ANGLE_TRY_RESULT(internalFormatInfo.computeCompressedImageSize(
-                                                 levelSize),
+                            ANGLE_TRY_RESULT(internalFormatInfo.computeCompressedImageSize(levelSize),
                                              dataSize);
                             mFunctions->compressedTexImage2D(
                                 face, static_cast<GLint>(level), compressedTexImageFormat.format,
                                 levelSize.width, levelSize.height, 0,
                                 static_cast<GLsizei>(dataSize), nullptr);
                         }
                         else
                         {
@@ -906,17 +916,17 @@ gl::Error TextureGL::setStorage(const gl
         {
             mFunctions->texStorage3D(target, static_cast<GLsizei>(levels),
                                      texStorageFormat.internalFormat, size.width, size.height,
                                      size.depth);
         }
         else
         {
             // Make sure no pixel unpack buffer is bound
-            mStateManager->bindBuffer(GL_PIXEL_UNPACK_BUFFER, 0);
+            mStateManager->bindBuffer(gl::BufferBinding::PixelUnpack, 0);
 
             const gl::InternalFormat &internalFormatInfo =
                 gl::GetSizedInternalFormatInfo(internalFormat);
 
             // Internal format must be sized
             ASSERT(internalFormatInfo.sized);
 
             for (GLsizei i = 0; i < static_cast<GLsizei>(levels); i++)
@@ -963,27 +973,28 @@ gl::Error TextureGL::setStorage(const gl
     return gl::NoError();
 }
 
 gl::Error TextureGL::setStorageMultisample(const gl::Context *context,
                                            GLenum target,
                                            GLsizei samples,
                                            GLint internalFormat,
                                            const gl::Extents &size,
-                                           GLboolean fixedSampleLocations)
+                                           bool fixedSampleLocations)
 {
     nativegl::TexStorageFormat texStorageFormat =
         nativegl::GetTexStorageFormat(mFunctions, mWorkarounds, internalFormat);
 
     mStateManager->bindTexture(mState.mTarget, mTextureID);
 
     ASSERT(size.depth == 1);
 
     mFunctions->texStorage2DMultisample(target, samples, texStorageFormat.internalFormat,
-                                        size.width, size.height, fixedSampleLocations);
+                                        size.width, size.height,
+                                        gl::ConvertToGLBoolean(fixedSampleLocations));
 
     setLevelInfo(target, 0, 1, GetLevelInfo(internalFormat, texStorageFormat.internalFormat));
 
     return gl::NoError();
 }
 
 gl::Error TextureGL::setImageExternal(const gl::Context *context,
                                       GLenum target,
@@ -1140,16 +1151,18 @@ void TextureGL::syncState(const gl::Text
                 mFunctions->texParameteri(getTarget(), GL_TEXTURE_BASE_LEVEL, mAppliedBaseLevel);
                 break;
             case gl::Texture::DIRTY_BIT_MAX_LEVEL:
                 mAppliedMaxLevel = mState.getEffectiveMaxLevel();
                 mFunctions->texParameteri(getTarget(), GL_TEXTURE_MAX_LEVEL, mAppliedMaxLevel);
                 break;
             case gl::Texture::DIRTY_BIT_USAGE:
                 break;
+            case gl::Texture::DIRTY_BIT_LABEL:
+                break;
 
             default:
                 UNREACHABLE();
         }
     }
 
     mLocalDirtyBits.reset();
 }
@@ -1330,43 +1343,52 @@ void TextureGL::syncTextureStateSwizzle(
 
 void TextureGL::setLevelInfo(GLenum target,
                              size_t level,
                              size_t levelCount,
                              const LevelInfoGL &levelInfo)
 {
     ASSERT(levelCount > 0);
 
-    GLuint baseLevel              = mState.getEffectiveBaseLevel();
-    bool needsResync              = level <= baseLevel && level + levelCount >= baseLevel &&
-                       (levelInfo.depthStencilWorkaround || levelInfo.lumaWorkaround.enabled);
-    if (needsResync)
-    {
-        mLocalDirtyBits |= GetLevelWorkaroundDirtyBits();
-    }
+    bool updateWorkarounds = levelInfo.depthStencilWorkaround || levelInfo.lumaWorkaround.enabled;
 
     for (size_t i = level; i < level + levelCount; i++)
     {
         if (target == GL_TEXTURE_CUBE_MAP)
         {
             for (GLenum face = gl::FirstCubeMapTextureTarget; face <= gl::LastCubeMapTextureTarget;
                  face++)
             {
                 size_t index = GetLevelInfoIndex(face, level);
                 ASSERT(index < mLevelInfo.size());
-                mLevelInfo[index] = levelInfo;
+                auto &curLevelInfo = mLevelInfo[index];
+
+                updateWorkarounds |= curLevelInfo.depthStencilWorkaround;
+                updateWorkarounds |= curLevelInfo.lumaWorkaround.enabled;
+
+                curLevelInfo = levelInfo;
             }
         }
         else
         {
             size_t index = GetLevelInfoIndex(target, level);
             ASSERT(index < mLevelInfo.size());
-            mLevelInfo[index] = levelInfo;
+            auto &curLevelInfo = mLevelInfo[index];
+
+            updateWorkarounds |= curLevelInfo.depthStencilWorkaround;
+            updateWorkarounds |= curLevelInfo.lumaWorkaround.enabled;
+
+            curLevelInfo = levelInfo;
         }
     }
+
+    if (updateWorkarounds)
+    {
+        mLocalDirtyBits |= GetLevelWorkaroundDirtyBits();
+    }
 }
 
 const LevelInfoGL &TextureGL::getLevelInfo(GLenum target, size_t level) const
 {
     ASSERT(target != GL_TEXTURE_CUBE_MAP);
     return mLevelInfo[GetLevelInfoIndex(target, level)];
 }
 
@@ -1382,9 +1404,17 @@ GLuint TextureGL::getTextureID() const
 {
     return mTextureID;
 }
 
 GLenum TextureGL::getTarget() const
 {
     return mState.mTarget;
 }
+
+gl::Error TextureGL::initializeContents(const gl::Context *context,
+                                        const gl::ImageIndex &imageIndex)
+{
+    // UNIMPLEMENTED();
+    return gl::NoError();
 }
+
+}  // namespace rx
--- a/gfx/angle/src/libANGLE/renderer/gl/TextureGL.h
+++ b/gfx/angle/src/libANGLE/renderer/gl/TextureGL.h
@@ -150,17 +150,17 @@ class TextureGL : public TextureImpl
                          GLenum internalFormat,
                          const gl::Extents &size) override;
 
     gl::Error setStorageMultisample(const gl::Context *context,
                                     GLenum target,
                                     GLsizei samples,
                                     GLint internalFormat,
                                     const gl::Extents &size,
-                                    GLboolean fixedSampleLocations) override;
+                                    bool fixedSampleLocations) override;
 
     gl::Error setImageExternal(const gl::Context *context,
                                GLenum target,
                                egl::Stream *stream,
                                const egl::Stream::GLTextureDescription &desc) override;
 
     gl::Error generateMipmap(const gl::Context *context) override;
 
@@ -174,16 +174,19 @@ class TextureGL : public TextureImpl
     GLuint getTextureID() const;
     GLenum getTarget() const;
 
     void syncState(const gl::Texture::DirtyBits &dirtyBits) override;
     bool hasAnyDirtyBit() const;
 
     gl::Error setBaseLevel(const gl::Context *context, GLuint baseLevel) override;
 
+    gl::Error initializeContents(const gl::Context *context,
+                                 const gl::ImageIndex &imageIndex) override;
+
     void setMinFilter(GLenum filter);
     void setMagFilter(GLenum filter);
 
     void setSwizzle(GLint swizzle[4]);
 
   private:
     void setImageHelper(GLenum target,
                         size_t level,
@@ -201,25 +204,27 @@ class TextureGL : public TextureImpl
                                    GLenum type);
     gl::Error setSubImageRowByRowWorkaround(const gl::Context *context,
                                             GLenum target,
                                             size_t level,
                                             const gl::Box &area,
                                             GLenum format,
                                             GLenum type,
                                             const gl::PixelUnpackState &unpack,
+                                            const gl::Buffer *unpackBuffer,
                                             const uint8_t *pixels);
 
     gl::Error setSubImagePaddingWorkaround(const gl::Context *context,
                                            GLenum target,
                                            size_t level,
                                            const gl::Box &area,
                                            GLenum format,
                                            GLenum type,
                                            const gl::PixelUnpackState &unpack,
+                                           const gl::Buffer *unpackBuffer,
                                            const uint8_t *pixels);
 
     void syncTextureStateSwizzle(const FunctionsGL *functions,
                                  GLenum name,
                                  GLenum value,
                                  GLenum *outValue);
 
     void setLevelInfo(GLenum target, size_t level, size_t levelCount, const LevelInfoGL &levelInfo);
--- a/gfx/angle/src/libANGLE/renderer/gl/TransformFeedbackGL.cpp
+++ b/gfx/angle/src/libANGLE/renderer/gl/TransformFeedbackGL.cpp
@@ -33,32 +33,37 @@ TransformFeedbackGL::TransformFeedbackGL
 TransformFeedbackGL::~TransformFeedbackGL()
 {
     mStateManager->deleteTransformFeedback(mTransformFeedbackID);
     mTransformFeedbackID = 0;
 }
 
 void TransformFeedbackGL::begin(GLenum primitiveMode)
 {
-    // Do not begin directly, StateManagerGL will handle beginning and resuming transform feedback.
+    mStateManager->onTransformFeedbackStateChange();
 }
 
 void TransformFeedbackGL::end()
 {
+    mStateManager->onTransformFeedbackStateChange();
+
+    // Immediately end the transform feedback so that the results are visible.
     syncActiveState(false, GL_NONE);
 }
 
 void TransformFeedbackGL::pause()
 {
+    mStateManager->onTransformFeedbackStateChange();
+
     syncPausedState(true);
 }
 
 void TransformFeedbackGL::resume()
 {
-    // Do not resume directly, StateManagerGL will handle beginning and resuming transform feedback.
+    mStateManager->onTransformFeedbackStateChange();
 }
 
 void TransformFeedbackGL::bindGenericBuffer(const gl::BindingPointer<gl::Buffer> &binding)
 {
 }
 
 void TransformFeedbackGL::bindIndexedBuffer(size_t index,
                                             const gl::OffsetBindingPointer<gl::Buffer> &binding)
--- a/gfx/angle/src/libANGLE/renderer/gl/VertexArrayGL.cpp
+++ b/gfx/angle/src/libANGLE/renderer/gl/VertexArrayGL.cpp
@@ -78,16 +78,20 @@ VertexArrayGL::VertexArrayGL(const Verte
     // Set the cached vertex attribute array and vertex attribute binding array size
     GLuint maxVertexAttribs = static_cast<GLuint>(state.getMaxAttribs());
     for (GLuint i = 0; i < maxVertexAttribs; i++)
     {
         mAppliedAttributes.emplace_back(i);
     }
 }
 
+VertexArrayGL::~VertexArrayGL()
+{
+}
+
 void VertexArrayGL::destroy(const gl::Context *context)
 {
     mStateManager->deleteVertexArray(mVertexArrayID);
     mVertexArrayID = 0;
     mAppliedNumViews = 1;
 
     mStateManager->deleteBuffer(mStreamingElementArrayBuffer);
     mStreamingElementArrayBufferSize = 0;
@@ -124,22 +128,22 @@ gl::Error VertexArrayGL::syncDrawElement
                                                const void **outIndices) const
 {
     return syncDrawState(context, activeAttributesMask, 0, count, type, indices, instanceCount,
                          primitiveRestartEnabled, outIndices);
 }
 
 gl::Error VertexArrayGL::syncElementArrayState(const gl::Context *context) const
 {
-    gl::Buffer *elementArrayBuffer = mData.getElementArrayBuffer().get();
+    gl::Buffer *elementArrayBuffer = mState.getElementArrayBuffer().get();
     ASSERT(elementArrayBuffer);
     if (elementArrayBuffer != mAppliedElementArrayBuffer.get())
     {
         const BufferGL *bufferGL = GetImplAs<BufferGL>(elementArrayBuffer);
-        mStateManager->bindBuffer(GL_ELEMENT_ARRAY_BUFFER, bufferGL->getBufferID());
+        mStateManager->bindBuffer(gl::BufferBinding::ElementArray, bufferGL->getBufferID());
         mAppliedElementArrayBuffer.set(context, elementArrayBuffer);
     }
 
     return gl::NoError();
 }
 
 gl::Error VertexArrayGL::syncDrawState(const gl::Context *context,
                                        const gl::AttributesMask &activeAttributesMask,
@@ -186,33 +190,33 @@ gl::Error VertexArrayGL::syncIndexData(c
                                        const void *indices,
                                        bool primitiveRestartEnabled,
                                        bool attributesNeedStreaming,
                                        IndexRange *outIndexRange,
                                        const void **outIndices) const
 {
     ASSERT(outIndices);
 
-    gl::Buffer *elementArrayBuffer = mData.getElementArrayBuffer().get();
+    gl::Buffer *elementArrayBuffer = mState.getElementArrayBuffer().get();
 
     // Need to check the range of indices if attributes need to be streamed
     if (elementArrayBuffer != nullptr)
     {
         if (elementArrayBuffer != mAppliedElementArrayBuffer.get())
         {
             const BufferGL *bufferGL = GetImplAs<BufferGL>(elementArrayBuffer);
-            mStateManager->bindBuffer(GL_ELEMENT_ARRAY_BUFFER, bufferGL->getBufferID());
+            mStateManager->bindBuffer(gl::BufferBinding::ElementArray, bufferGL->getBufferID());
             mAppliedElementArrayBuffer.set(context, elementArrayBuffer);
         }
 
         // Only compute the index range if the attributes also need to be streamed
         if (attributesNeedStreaming)
         {
             ptrdiff_t elementArrayBufferOffset = reinterpret_cast<ptrdiff_t>(indices);
-            Error error                        = mData.getElementArrayBuffer()->getIndexRange(
+            Error error                        = mState.getElementArrayBuffer()->getIndexRange(
                 context, type, elementArrayBufferOffset, count, primitiveRestartEnabled,
                 outIndexRange);
             if (error.isError())
             {
                 return error;
             }
         }
 
@@ -233,17 +237,17 @@ gl::Error VertexArrayGL::syncIndexData(c
 
         // Allocate the streaming element array buffer
         if (mStreamingElementArrayBuffer == 0)
         {
             mFunctions->genBuffers(1, &mStreamingElementArrayBuffer);
             mStreamingElementArrayBufferSize = 0;
         }
 
-        mStateManager->bindBuffer(GL_ELEMENT_ARRAY_BUFFER, mStreamingElementArrayBuffer);
+        mStateManager->bindBuffer(gl::BufferBinding::ElementArray, mStreamingElementArrayBuffer);
         mAppliedElementArrayBuffer.set(context, nullptr);
 
         // Make sure the element array buffer is large enough
         const Type &indexTypeInfo          = GetTypeInfo(type);
         size_t requiredStreamingBufferSize = indexTypeInfo.bytes * count;
         if (requiredStreamingBufferSize > mStreamingElementArrayBufferSize)
         {
             // Copy the indices in while resizing the buffer
@@ -272,18 +276,18 @@ void VertexArrayGL::computeStreamingAttr
                                                    size_t *outStreamingDataSize,
                                                    size_t *outMaxAttributeDataSize) const
 {
     *outStreamingDataSize    = 0;
     *outMaxAttributeDataSize = 0;
 
     ASSERT(mAttributesNeedStreaming.any());
 
-    const auto &attribs  = mData.getVertexAttributes();
-    const auto &bindings = mData.getVertexBindings();
+    const auto &attribs  = mState.getVertexAttributes();
+    const auto &bindings = mState.getVertexBindings();
 
     gl::AttributesMask attribsToStream = (mAttributesNeedStreaming & activeAttributesMask);
 
     for (auto idx : attribsToStream)
     {
         const auto &attrib  = attribs[idx];
         const auto &binding = bindings[attrib.bindingIndex];
         ASSERT(AttributeNeedsStreaming(attrib, binding));
@@ -322,17 +326,17 @@ gl::Error VertexArrayGL::streamAttribute
         mStreamingArrayBufferSize = 0;
     }
 
     // If first is greater than zero, a slack space needs to be left at the beginning of the buffer
     // so that the same 'first' argument can be passed into the draw call.
     const size_t bufferEmptySpace   = maxAttributeDataSize * indexRange.start;
     const size_t requiredBufferSize = streamingDataSize + bufferEmptySpace;
 
-    mStateManager->bindBuffer(GL_ARRAY_BUFFER, mStreamingArrayBuffer);
+    mStateManager->bindBuffer(gl::BufferBinding::Array, mStreamingArrayBuffer);
     if (requiredBufferSize > mStreamingArrayBufferSize)
     {
         mFunctions->bufferData(GL_ARRAY_BUFFER, requiredBufferSize, nullptr, GL_DYNAMIC_DRAW);
         mStreamingArrayBufferSize = requiredBufferSize;
     }
 
     // Unmapping a buffer can return GL_FALSE to indicate that the system has corrupted the data
     // somehow (such as by a screen change), retry writing the data a few times and return
@@ -340,18 +344,18 @@ gl::Error VertexArrayGL::streamAttribute
     GLboolean unmapResult     = GL_FALSE;
     size_t unmapRetryAttempts = 5;
     while (unmapResult != GL_TRUE && --unmapRetryAttempts > 0)
     {
         uint8_t *bufferPointer = MapBufferRangeWithFallback(mFunctions, GL_ARRAY_BUFFER, 0,
                                                             requiredBufferSize, GL_MAP_WRITE_BIT);
         size_t curBufferOffset = bufferEmptySpace;
 
-        const auto &attribs  = mData.getVertexAttributes();
-        const auto &bindings = mData.getVertexBindings();
+        const auto &attribs  = mState.getVertexAttributes();
+        const auto &bindings = mState.getVertexBindings();
 
         gl::AttributesMask attribsToStream = (mAttributesNeedStreaming & activeAttributesMask);
 
         for (auto idx : attribsToStream)
         {
             const auto &attrib  = attribs[idx];
             ASSERT(IsVertexAttribPointerSupported(idx, attrib));
 
@@ -425,24 +429,24 @@ GLuint VertexArrayGL::getAppliedElementA
         return mStreamingElementArrayBuffer;
     }
 
     return GetImplAs<BufferGL>(mAppliedElementArrayBuffer.get())->getBufferID();
 }
 
 void VertexArrayGL::updateNeedsStreaming(size_t attribIndex)
 {
-    const auto &attrib  = mData.getVertexAttribute(attribIndex);
-    const auto &binding = mData.getBindingFromAttribIndex(attribIndex);
+    const auto &attrib  = mState.getVertexAttribute(attribIndex);
+    const auto &binding = mState.getBindingFromAttribIndex(attribIndex);
     mAttributesNeedStreaming.set(attribIndex, AttributeNeedsStreaming(attrib, binding));
 }
 
 void VertexArrayGL::updateAttribEnabled(size_t attribIndex)
 {
-    const bool enabled = mData.getVertexAttribute(attribIndex).enabled;
+    const bool enabled = mState.getVertexAttribute(attribIndex).enabled;
     if (mAppliedAttributes[attribIndex].enabled == enabled)
     {
         return;
     }
 
     updateNeedsStreaming(attribIndex);
 
     if (enabled)
@@ -454,21 +458,21 @@ void VertexArrayGL::updateAttribEnabled(
         mFunctions->disableVertexAttribArray(static_cast<GLuint>(attribIndex));
     }
 
     mAppliedAttributes[attribIndex].enabled = enabled;
 }
 
 void VertexArrayGL::updateAttribPointer(const gl::Context *context, size_t attribIndex)
 {
-    const VertexAttribute &attrib = mData.getVertexAttribute(attribIndex);
+    const VertexAttribute &attrib = mState.getVertexAttribute(attribIndex);
 
     // According to SPEC, VertexAttribPointer should update the binding indexed attribIndex instead
     // of the binding indexed attrib.bindingIndex (unless attribIndex == attrib.bindingIndex).
-    const VertexBinding &binding = mData.getVertexBinding(attribIndex);
+    const VertexBinding &binding = mState.getVertexBinding(attribIndex);
 
     // Since mAttributesNeedStreaming[attribIndex] keeps the value set in the last draw, here we
     // only need to update it when the buffer has been changed. e.g. When we set an attribute to be
     // streamed in the last draw, and only change its format in this draw without calling
     // updateNeedsStreaming, it will still be streamed because the flag is already on.
     const auto &bindingBuffer = binding.getBuffer();
     if (bindingBuffer != mAppliedBindings[attribIndex].getBuffer())
     {
@@ -501,17 +505,17 @@ void VertexArrayGL::updateAttribPointer(
 
     // Since ANGLE always uses a non-zero VAO, we cannot use a client memory pointer on it:
     // [OpenGL ES 3.0.2] Section 2.8 page 24:
     // An INVALID_OPERATION error is generated when a non-zero vertex array object is bound,
     // zero is bound to the ARRAY_BUFFER buffer object binding point, and the pointer argument
     // is not NULL.
 
     const BufferGL *arrayBufferGL = GetImplAs<BufferGL>(arrayBuffer);
-    mStateManager->bindBuffer(GL_ARRAY_BUFFER, arrayBufferGL->getBufferID());
+    mStateManager->bindBuffer(gl::BufferBinding::Array, arrayBufferGL->getBufferID());
     callVertexAttribPointer(static_cast<GLuint>(attribIndex), attrib, binding.getStride(),
                             binding.getOffset());
 
     mAppliedAttributes[attribIndex].size        = attrib.size;
     mAppliedAttributes[attribIndex].type        = attrib.type;
     mAppliedAttributes[attribIndex].normalized  = attrib.normalized;
     mAppliedAttributes[attribIndex].pureInteger = attrib.pureInteger;
 
@@ -550,17 +554,17 @@ bool VertexArrayGL::supportVertexAttribB
     ASSERT(mFunctions);
     return (mFunctions->vertexAttribBinding != nullptr);
 }
 
 void VertexArrayGL::updateAttribFormat(size_t attribIndex)
 {
     ASSERT(supportVertexAttribBinding());
 
-    const VertexAttribute &attrib = mData.getVertexAttribute(attribIndex);
+    const VertexAttribute &attrib = mState.getVertexAttribute(attribIndex);
     if (SameVertexAttribFormat(mAppliedAttributes[attribIndex], attrib))
     {
         return;
     }
 
     if (attrib.pureInteger)
     {
         ASSERT(!attrib.normalized);
@@ -579,32 +583,32 @@ void VertexArrayGL::updateAttribFormat(s
     mAppliedAttributes[attribIndex].pureInteger    = attrib.pureInteger;
     mAppliedAttributes[attribIndex].relativeOffset = attrib.relativeOffset;
 }
 
 void VertexArrayGL::updateAttribBinding(size_t attribIndex)
 {
     ASSERT(supportVertexAttribBinding());
 
-    GLuint bindingIndex = mData.getVertexAttribute(attribIndex).bindingIndex;
+    GLuint bindingIndex = mState.getVertexAttribute(attribIndex).bindingIndex;
     if (mAppliedAttributes[attribIndex].bindingIndex == bindingIndex)
     {
         return;
     }
 
     mFunctions->vertexAttribBinding(static_cast<GLuint>(attribIndex), bindingIndex);
 
     mAppliedAttributes[attribIndex].bindingIndex = bindingIndex;
 }
 
 void VertexArrayGL::updateBindingBuffer(const gl::Context *context, size_t bindingIndex)
 {
     ASSERT(supportVertexAttribBinding());
 
-    const VertexBinding &binding = mData.getVertexBinding(bindingIndex);
+    const VertexBinding &binding = mState.getVertexBinding(bindingIndex);
     if (SameVertexBuffer(mAppliedBindings[bindingIndex], binding))
     {
         return;
     }
 
     const Buffer *arrayBuffer = binding.getBuffer().get();
     GLuint bufferId           = 0;
     if (arrayBuffer != nullptr)
@@ -618,17 +622,17 @@ void VertexArrayGL::updateBindingBuffer(
     mAppliedBindings[bindingIndex].setStride(binding.getStride());
     mAppliedBindings[bindingIndex].setOffset(binding.getOffset());
     mAppliedBindings[bindingIndex].setBuffer(context, binding.getBuffer().get());
 }
 
 void VertexArrayGL::updateBindingDivisor(size_t bindingIndex)
 {
     GLuint adjustedDivisor =
-        GetAdjustedDivisor(mAppliedNumViews, mData.getVertexBinding(bindingIndex).getDivisor());
+        GetAdjustedDivisor(mAppliedNumViews, mState.getVertexBinding(bindingIndex).getDivisor());
     if (mAppliedBindings[bindingIndex].getDivisor() == adjustedDivisor)
     {
         return;
     }
 
     if (supportVertexAttribBinding())
     {
         mFunctions->vertexBindingDivisor(static_cast<GLuint>(bindingIndex), adjustedDivisor);
--- a/gfx/angle/src/libANGLE/renderer/gl/VertexArrayGL.h
+++ b/gfx/angle/src/libANGLE/renderer/gl/VertexArrayGL.h
@@ -18,16 +18,18 @@ class FunctionsGL;
 class StateManagerGL;
 
 class VertexArrayGL : public VertexArrayImpl
 {
   public:
     VertexArrayGL(const gl::VertexArrayState &data,
                   const FunctionsGL *functions,
                   StateManagerGL *stateManager);
+    ~VertexArrayGL() override;
+
     void destroy(const gl::Context *context) override;
 
     gl::Error syncDrawArraysState(const gl::Context *context,
                                   const gl::AttributesMask &activeAttributesMask,
                                   GLint first,
                                   GLsizei count,
                                   GLsizei instanceCount) const;
     gl::Error syncDrawElementsState(const gl::Context *context,
--- a/gfx/angle/src/libANGLE/renderer/gl/WorkaroundsGL.h
+++ b/gfx/angle/src/libANGLE/renderer/gl/WorkaroundsGL.h
@@ -9,16 +9,18 @@
 #ifndef LIBANGLE_RENDERER_GL_WORKAROUNDSGL_H_
 #define LIBANGLE_RENDERER_GL_WORKAROUNDSGL_H_
 
 namespace rx
 {
 
 struct WorkaroundsGL
 {
+    WorkaroundsGL();
+
     // When writing a float to a normalized integer framebuffer, desktop OpenGL is allowed to write
     // one of the two closest normalized integer representations (although round to nearest is
     // preferred) (see section 2.3.5.2 of the GL 4.5 core specification). OpenGL ES requires that
     // round-to-nearest is used (see "Conversion from Floating-Point to Framebuffer Fixed-Point" in
     // section 2.1.2 of the OpenGL ES 2.0.25 spec).  This issue only shows up on Intel and AMD
     // drivers on framebuffer formats that have 1-bit alpha, work around this by using higher
     // precision formats instead.
     bool avoid1BitAlphaTextureFormats = false;
@@ -128,12 +130,23 @@ struct WorkaroundsGL
 
     // Initializing uninitialized locals caused odd behavior on Mac in a few WebGL 2 tests.
     // Tracking bug: http://anglebug/2041
     bool dontInitializeUninitializedLocals = false;
 
     // On some NVIDIA drivers the point size range reported from the API is inconsistent with the
     // actual behavior. Clamp the point size to the value from the API to fix this.
     bool clampPointSize = false;
+
+    // On some NVIDIA drivers certain types of GLSL arithmetic ops mixing vectors and scalars may be
+    // executed incorrectly. Change them in the shader translator. Tracking bug:
+    // http://crbug.com/772651
+    bool rewriteVectorScalarArithmetic = false;
+
+    // On some Android devices for loops used to initialize variables hit native GLSL compiler bugs.
+    bool dontUseLoopsToInitializeVariables = false;
 };
+
+inline WorkaroundsGL::WorkaroundsGL() = default;
+
 }  // namespace rx
 
 #endif  // LIBANGLE_RENDERER_GL_WORKAROUNDSGL_H_
--- a/gfx/angle/src/libANGLE/renderer/gl/cgl/DisplayCGL.h
+++ b/gfx/angle/src/libANGLE/renderer/gl/cgl/DisplayCGL.h
@@ -40,24 +40,30 @@ class DisplayCGL : public DisplayGL
                                      const egl::AttributeMap &attribs) override;
 
     egl::ConfigSet generateConfigs() override;
 
     bool testDeviceLost() override;
     egl::Error restoreLostDevice(const egl::Display *display) override;
 
     bool isValidNativeWindow(EGLNativeWindowType window) const override;
+    egl::Error validateClientBuffer(const egl::Config *configuration,
+                                    EGLenum buftype,
+                                    EGLClientBuffer clientBuffer,
+                                    const egl::AttributeMap &attribs) const override;
 
     egl::Error getDevice(DeviceImpl **device) override;
 
     std::string getVendorString() const override;
 
     egl::Error waitClient(const gl::Context *context) const override;
     egl::Error waitNative(const gl::Context *context, EGLint engine) const override;
 
+    CGLContextObj getCGLContext() const;
+
   private:
     const FunctionsGL *getFunctionsGL() const override;
     egl::Error makeCurrentSurfaceless(gl::Context *context) override;
 
     void generateExtensions(egl::DisplayExtensions *outExtensions) const override;
     void generateCaps(egl::Caps *outCaps) const override;
 
     egl::Display *mEGLDisplay;
--- a/gfx/angle/src/libANGLE/renderer/gl/cgl/DisplayCGL.mm
+++ b/gfx/angle/src/libANGLE/renderer/gl/cgl/DisplayCGL.mm
@@ -8,16 +8,18 @@
 
 #include "libANGLE/renderer/gl/cgl/DisplayCGL.h"
 
 #import <Cocoa/Cocoa.h>
 #include <dlfcn.h>
 #include <EGL/eglext.h>
 
 #include "common/debug.h"
+#include "libANGLE/Display.h"
+#include "libANGLE/renderer/gl/cgl/IOSurfaceSurfaceCGL.h"
 #include "libANGLE/renderer/gl/cgl/PbufferSurfaceCGL.h"
 #include "libANGLE/renderer/gl/cgl/WindowSurfaceCGL.h"
 
 namespace
 {
 
 const char *kDefaultOpenGLDylibName =
     "/System/Library/Frameworks/OpenGL.framework/Libraries/libGL.dylib";
@@ -31,17 +33,17 @@ namespace rx
 class FunctionsGLCGL : public FunctionsGL
 {
   public:
     FunctionsGLCGL(void *dylibHandle) : mDylibHandle(dylibHandle) {}
 
     ~FunctionsGLCGL() override { dlclose(mDylibHandle); }
 
   private:
-    void *loadProcAddress(const std::string &function) override
+    void *loadProcAddress(const std::string &function) const override
     {
         return dlsym(mDylibHandle, function.c_str());
     }
 
     void *mDylibHandle;
 };
 
 DisplayCGL::DisplayCGL(const egl::DisplayState &state)
@@ -86,17 +88,17 @@ egl::Error DisplayCGL::initialize(egl::D
         handle = dlopen(kFallbackOpenGLDylibName, RTLD_NOW);
     }
     if (!handle)
     {
         return egl::EglNotInitialized() << "Could not open the OpenGL Framework.";
     }
 
     mFunctions = new FunctionsGLCGL(handle);
-    mFunctions->initialize();
+    mFunctions->initialize(display->getAttributeMap());
 
     return DisplayGL::initialize(display);
 }
 
 void DisplayCGL::terminate()
 {
     DisplayGL::terminate();
 
@@ -125,18 +127,19 @@ SurfaceImpl *DisplayCGL::createPbufferSu
     return new PbufferSurfaceCGL(state, this->getRenderer(), width, height, mFunctions);
 }
 
 SurfaceImpl *DisplayCGL::createPbufferFromClientBuffer(const egl::SurfaceState &state,
                                                        EGLenum buftype,
                                                        EGLClientBuffer clientBuffer,
                                                        const egl::AttributeMap &attribs)
 {
-    UNIMPLEMENTED();
-    return nullptr;
+    ASSERT(buftype == EGL_IOSURFACE_ANGLE);
+
+    return new IOSurfaceSurfaceCGL(state, this->getRenderer(), this, clientBuffer, attribs);
 }
 
 SurfaceImpl *DisplayCGL::createPixmapSurface(const egl::SurfaceState &state,
                                              NativePixmapType nativePixmap,
                                              const egl::AttributeMap &attribs)
 {
     UNIMPLEMENTED();
     return nullptr;
@@ -227,33 +230,56 @@ egl::Error DisplayCGL::restoreLostDevice
 }
 
 bool DisplayCGL::isValidNativeWindow(EGLNativeWindowType window) const
 {
     NSObject *layer = reinterpret_cast<NSObject *>(window);
     return [layer isKindOfClass:[CALayer class]];
 }
 
+egl::Error DisplayCGL::validateClientBuffer(const egl::Config *configuration,
+                                            EGLenum buftype,
+                                            EGLClientBuffer clientBuffer,
+                                            const egl::AttributeMap &attribs) const
+{
+    ASSERT(buftype == EGL_IOSURFACE_ANGLE);
+
+    if (!IOSurfaceSurfaceCGL::validateAttributes(clientBuffer, attribs))
+    {
+        return egl::EglBadAttribute();
+    }
+
+    return egl::NoError();
+}
+
 std::string DisplayCGL::getVendorString() const
 {
     // TODO(cwallez) find a useful vendor string
     return "";
 }
 
+CGLContextObj DisplayCGL::getCGLContext() const
+{
+    return mContext;
+}
+
 const FunctionsGL *DisplayCGL::getFunctionsGL() const
 {
     return mFunctions;
 }
 
 void DisplayCGL::generateExtensions(egl::DisplayExtensions *outExtensions) const
 {
+    outExtensions->iosurfaceClientBuffer = true;
     outExtensions->surfacelessContext = true;
 
     // Contexts are virtualized so textures can be shared globally
     outExtensions->displayTextureShareGroup = true;
+
+    DisplayGL::generateExtensions(outExtensions);
 }
 
 void DisplayCGL::generateCaps(egl::Caps *outCaps) const
 {
     outCaps->textureNPOT = true;
 }
 
 egl::Error DisplayCGL::waitClient(const gl::Context *context) const
new file mode 100644
--- /dev/null
+++ b/gfx/angle/src/libANGLE/renderer/gl/cgl/IOSurfaceSurfaceCGL.h
@@ -0,0 +1,75 @@
+//
+// 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.
+//
+
+// PBufferSurfaceCGL.h: an implementation of PBuffers created from IOSurfaces using
+//                      EGL_ANGLE_iosurface_client_buffer
+
+#ifndef LIBANGLE_RENDERER_GL_CGL_IOSURFACESURFACECGL_H_
+#define LIBANGLE_RENDERER_GL_CGL_IOSURFACESURFACECGL_H_
+
+#include "libANGLE/renderer/gl/SurfaceGL.h"
+
+struct __IOSurface;
+typedef __IOSurface *IOSurfaceRef;
+
+namespace egl
+{
+class AttributeMap;
+}  // namespace gl
+
+namespace rx
+{
+
+class DisplayCGL;
+class FunctionsGL;
+class StateManagerGL;
+
+class IOSurfaceSurfaceCGL : public SurfaceGL
+{
+  public:
+    IOSurfaceSurfaceCGL(const egl::SurfaceState &state,
+                        RendererGL *renderer,
+                        DisplayCGL *display,
+                        EGLClientBuffer buffer,
+                        const egl::AttributeMap &attribs);
+    ~IOSurfaceSurfaceCGL() override;
+
+    egl::Error initialize(const egl::Display *display) override;
+    egl::Error makeCurrent() override;
+
+    egl::Error swap(const gl::Context *context) override;
+    egl::Error postSubBuffer(const gl::Context *context,
+                             EGLint x,
+                             EGLint y,
+                             EGLint width,
+                             EGLint height) override;
+    egl::Error querySurfacePointerANGLE(EGLint attribute, void **value) override;
+    egl::Error bindTexImage(gl::Texture *texture, EGLint buffer) override;
+    egl::Error releaseTexImage(EGLint buffer) override;
+    void setSwapInterval(EGLint interval) override;
+
+    EGLint getWidth() const override;
+    EGLint getHeight() const override;
+
+    EGLint isPostSubBufferSupported() const override;
+    EGLint getSwapBehavior() const override;
+
+    static bool validateAttributes(EGLClientBuffer buffer, const egl::AttributeMap &attribs);
+
+  private:
+    DisplayCGL *mDisplay;
+    RendererGL *mRenderer;
+    StateManagerGL *mStateManager;
+    IOSurfaceRef mIOSurface;
+    int mWidth;
+    int mHeight;
+    int mPlane;
+    int mFormatIndex;
+};
+
+}  // namespace rx
+
+#endif  // LIBANGLE_RENDERER_GL_CGL_IOSURFACESURFACECGL_H_
new file mode 100644
--- /dev/null
+++ b/gfx/angle/src/libANGLE/renderer/gl/cgl/IOSurfaceSurfaceCGL.mm
@@ -0,0 +1,240 @@
+//
+// 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.
+//
+
+// PBufferSurfaceCGL.cpp: an implementation of PBuffers created from IOSurfaces using
+//                        EGL_ANGLE_iosurface_client_buffer
+
+#include "libANGLE/renderer/gl/cgl/IOSurfaceSurfaceCGL.h"
+
+#include <IOSurface/IOSurface.h>
+#include <OpenGL/CGLIOSurface.h>
+
+#include "common/debug.h"
+#include "libANGLE/AttributeMap.h"
+#include "libANGLE/renderer/gl/FramebufferGL.h"
+#include "libANGLE/renderer/gl/FunctionsGL.h"
+#include "libANGLE/renderer/gl/RendererGL.h"
+#include "libANGLE/renderer/gl/StateManagerGL.h"
+#include "libANGLE/renderer/gl/TextureGL.h"
+#include "libANGLE/renderer/gl/cgl/DisplayCGL.h"
+
+namespace rx
+{
+
+namespace
+{
+
+struct IOSurfaceFormatInfo
+{
+    GLenum internalFormat;
+    GLenum type;
+
+    size_t componentBytes;
+
+    GLenum nativeInternalFormat;
+    GLenum nativeFormat;
+    GLenum nativeType;
+};
+
+// clang-format off
+static const IOSurfaceFormatInfo kIOSurfaceFormats[] = {
+    {GL_RED,      GL_UNSIGNED_BYTE,  1, GL_RED,  GL_RED,  GL_UNSIGNED_BYTE           },
+    {GL_R8UI,     GL_UNSIGNED_SHORT, 2, GL_RED,  GL_RED,  GL_UNSIGNED_SHORT          },
+    {GL_RG,       GL_UNSIGNED_BYTE,  2, GL_RG,   GL_RG,   GL_UNSIGNED_BYTE           },
+    {GL_BGRA_EXT, GL_UNSIGNED_BYTE,  4, GL_BGRA, GL_RGBA, GL_UNSIGNED_INT_8_8_8_8_REV},
+    {GL_RGBA,     GL_HALF_FLOAT,     8, GL_RGBA, GL_RGBA, GL_HALF_FLOAT              },
+};
+// clang-format on
+
+int FindIOSurfaceFormatIndex(GLenum internalFormat, GLenum type)
+{
+    for (int i = 0; i < static_cast<int>(ArraySize(kIOSurfaceFormats)); ++i)
+    {
+        const auto &formatInfo = kIOSurfaceFormats[i];
+        if (formatInfo.internalFormat == internalFormat && formatInfo.type == type)
+        {
+            return i;
+        }
+    }
+    return -1;
+}
+
+}  // anonymous namespace
+
+IOSurfaceSurfaceCGL::IOSurfaceSurfaceCGL(const egl::SurfaceState &state,
+                                         RendererGL *renderer,
+                                         DisplayCGL *display,
+                                         EGLClientBuffer buffer,
+                                         const egl::AttributeMap &attribs)
+    : SurfaceGL(state, renderer),
+      mDisplay(display),
+      mRenderer(renderer),
+      mStateManager(renderer->getStateManager()),
+      mIOSurface(nullptr),
+      mWidth(0),
+      mHeight(0),
+      mPlane(0),
+      mFormatIndex(-1)
+{
+    // Keep reference to the IOSurface so it doesn't get deleted while the pbuffer exists.
+    mIOSurface = reinterpret_cast<IOSurfaceRef>(buffer);
+    CFRetain(mIOSurface);
+
+    // Extract attribs useful for the call to CGLTexImageIOSurface2D
+    mWidth  = attribs.get(EGL_WIDTH);
+    mHeight = attribs.get(EGL_HEIGHT);
+    mPlane  = attribs.get(EGL_IOSURFACE_PLANE_ANGLE);
+
+    EGLAttrib internalFormat = attribs.get(EGL_TEXTURE_INTERNAL_FORMAT_ANGLE);
+    EGLAttrib type           = attribs.get(EGL_TEXTURE_TYPE_ANGLE);
+    mFormatIndex             = FindIOSurfaceFormatIndex(internalFormat, type);
+    ASSERT(mFormatIndex >= 0);
+}
+
+IOSurfaceSurfaceCGL::~IOSurfaceSurfaceCGL()
+{
+    if (mIOSurface != nullptr)
+    {
+        CFRelease(mIOSurface);
+        mIOSurface = nullptr;
+    }
+}
+
+egl::Error IOSurfaceSurfaceCGL::initialize(const egl::Display *display)
+{
+    return egl::NoError();
+}
+
+egl::Error IOSurfaceSurfaceCGL::makeCurrent()
+{
+    // Make current is not supported on IOSurface pbuffers.
+    return egl::EglBadSurface();
+}
+
+egl::Error IOSurfaceSurfaceCGL::swap(const gl::Context *context)
+{
+    UNREACHABLE();
+    return egl::NoError();
+}
+
+egl::Error IOSurfaceSurfaceCGL::postSubBuffer(const gl::Context *context,
+                                              EGLint x,
+                                              EGLint y,
+                                              EGLint width,
+                                              EGLint height)
+{
+    UNREACHABLE();
+    return egl::NoError();
+}
+
+egl::Error IOSurfaceSurfaceCGL::querySurfacePointerANGLE(EGLint attribute, void **value)
+{
+    UNREACHABLE();
+    return egl::NoError();
+}
+
+egl::Error IOSurfaceSurfaceCGL::bindTexImage(gl::Texture *texture, EGLint buffer)
+{
+    const TextureGL *textureGL = GetImplAs<TextureGL>(texture);
+    GLuint textureID           = textureGL->getTextureID();
+    mStateManager->bindTexture(GL_TEXTURE_RECTANGLE, textureID);
+
+    const auto &format = kIOSurfaceFormats[mFormatIndex];
+    auto error         = CGLTexImageIOSurface2D(
+        mDisplay->getCGLContext(), GL_TEXTURE_RECTANGLE, format.nativeFormat, mWidth, mHeight,
+        format.nativeInternalFormat, format.nativeType, mIOSurface, mPlane);
+
+    if (error != kCGLNoError)
+    {
+        return egl::EglContextLost();
+    }
+
+    return egl::NoError();
+}
+
+egl::Error IOSurfaceSurfaceCGL::releaseTexImage(EGLint buffer)
+{
+    gl::Error error = mRenderer->flush();
+    if (error.isError())
+    {
+        return egl::EglContextLost();
+    }
+    return egl::NoError();
+}
+
+void IOSurfaceSurfaceCGL::setSwapInterval(EGLint interval)
+{
+    UNREACHABLE();
+}
+
+EGLint IOSurfaceSurfaceCGL::getWidth() const
+{
+    return mWidth;
+}
+
+EGLint IOSurfaceSurfaceCGL::getHeight() const
+{
+    return mHeight;
+}
+
+EGLint IOSurfaceSurfaceCGL::isPostSubBufferSupported() const
+{
+    UNREACHABLE();
+    return EGL_FALSE;
+}
+
+EGLint IOSurfaceSurfaceCGL::getSwapBehavior() const
+{
+    // N/A because you can't MakeCurrent an IOSurface, return any valid value.
+    return EGL_BUFFER_PRESERVED;
+}
+
+// static
+bool IOSurfaceSurfaceCGL::validateAttributes(EGLClientBuffer buffer,
+                                             const egl::AttributeMap &attribs)
+{
+    IOSurfaceRef ioSurface = reinterpret_cast<IOSurfaceRef>(buffer);
+
+    // The plane must exist for this IOSurface. IOSurfaceGetPlaneCount can return 0 for non-planar
+    // ioSurfaces but we will treat non-planar like it is a single plane.
+    size_t surfacePlaneCount = std::max(size_t(1), IOSurfaceGetPlaneCount(ioSurface));
+    EGLAttrib plane          = attribs.get(EGL_IOSURFACE_PLANE_ANGLE);
+    if (plane < 0 || static_cast<size_t>(plane) >= surfacePlaneCount)
+    {
+        return false;
+    }
+
+    // The width height specified must be at least (1, 1) and at most the plane size
+    EGLAttrib width  = attribs.get(EGL_WIDTH);
+    EGLAttrib height = attribs.get(EGL_HEIGHT);
+    if (width <= 0 || static_cast<size_t>(width) > IOSurfaceGetWidthOfPlane(ioSurface, plane) ||
+        height < 0 || static_cast<size_t>(height) > IOSurfaceGetHeightOfPlane(ioSurface, plane))
+    {
+        return false;
+    }
+
+    // Find this IOSurface format
+    EGLAttrib internalFormat = attribs.get(EGL_TEXTURE_INTERNAL_FORMAT_ANGLE);
+    EGLAttrib type           = attribs.get(EGL_TEXTURE_TYPE_ANGLE);
+
+    int formatIndex = FindIOSurfaceFormatIndex(internalFormat, type);
+
+    if (formatIndex < 0)
+    {
+        return false;
+    }
+
+    // Check that the format matches this IOSurface plane
+    if (IOSurfaceGetBytesPerElementOfPlane(ioSurface, plane) !=
+        kIOSurfaceFormats[formatIndex].componentBytes)
+    {
+        return false;
+    }
+
+    return true;
+}
+
+}  // namespace rx
--- a/gfx/angle/src/libANGLE/renderer/gl/egl/DisplayEGL.cpp
+++ b/gfx/angle/src/libANGLE/renderer/gl/egl/DisplayEGL.cpp
@@ -3,16 +3,18 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 //
 
 // DisplayEGL.cpp: Common across EGL parts of platform specific egl::Display implementations
 
 #include "libANGLE/renderer/gl/egl/DisplayEGL.h"
 
+#include "libANGLE/renderer/gl/egl/egl_utils.h"
+
 namespace rx
 {
 
 #define EGL_NO_CONFIG ((EGLConfig)0)
 
 DisplayEGL::DisplayEGL(const egl::DisplayState &state)
     : DisplayGL(state),
       mEGL(nullptr),
@@ -43,17 +45,17 @@ egl::Error DisplayEGL::initializeContext
         eglAttributes.getAsInt(EGL_PLATFORM_ANGLE_MAX_VERSION_MINOR_ANGLE, EGL_DONT_CARE);
     bool initializeRequested = requestedMajor != EGL_DONT_CARE && requestedMinor != EGL_DONT_CARE;
 
     static_assert(EGL_CONTEXT_MAJOR_VERSION == EGL_CONTEXT_MAJOR_VERSION_KHR,
                   "Major Version define should match");
     static_assert(EGL_CONTEXT_MINOR_VERSION == EGL_CONTEXT_MINOR_VERSION_KHR,
                   "Minor Version define should match");
 
-    std::vector<std::vector<EGLint>> contextAttribLists;
+    std::vector<native_egl::AttributeVector> contextAttribLists;
     if (eglVersion >= gl::Version(1, 5) || mEGL->hasExtension("EGL_KHR_create_context"))
     {
         if (initializeRequested)
         {
             contextAttribLists.push_back({EGL_CONTEXT_MAJOR_VERSION, requestedMajor,
                                           EGL_CONTEXT_MINOR_VERSION, requestedMinor, EGL_NONE});
         }
         else
@@ -79,17 +81,17 @@ egl::Error DisplayEGL::initializeContext
     {
         if (initializeRequested && (requestedMajor != 2 || requestedMinor != 0))
         {
             return egl::EglBadAttribute() << "Unsupported requested context version";
         }
         contextAttribLists.push_back({EGL_CONTEXT_CLIENT_VERSION, 2, EGL_NONE});
     }
 
-    for (auto &attribList : contextAttribLists)
+    for (const auto &attribList : contextAttribLists)
     {
         mContext = mEGL->createContext(mConfig, EGL_NO_CONTEXT, attribList.data());
         if (mContext != EGL_NO_CONTEXT)
         {
             return egl::NoError();
         }
     }
 
@@ -103,16 +105,18 @@ void DisplayEGL::generateExtensions(egl:
 
     outExtensions->postSubBuffer = false;  // Since SurfaceEGL::postSubBuffer is not implemented
 
     // Contexts are virtualized so textures can be shared globally
     outExtensions->displayTextureShareGroup = true;
 
     // Surfaceless contexts are emulated even if there is no native support.
     outExtensions->surfacelessContext = true;
+
+    DisplayGL::generateExtensions(outExtensions);
 }
 
 void DisplayEGL::generateCaps(egl::Caps *outCaps) const
 {
     outCaps->textureNPOT = true;  // Since we request GLES >= 2
 }
 
 const FunctionsGL *DisplayEGL::getFunctionsGL() const
--- a/gfx/angle/src/libANGLE/renderer/gl/egl/FunctionsEGL.cpp
+++ b/gfx/angle/src/libANGLE/renderer/gl/egl/FunctionsEGL.cpp
@@ -195,17 +195,17 @@ egl::Error FunctionsEGL::terminate()
 class FunctionsGLEGL : public FunctionsGL
 {
   public:
     FunctionsGLEGL(const FunctionsEGL &egl) : mEGL(egl) {}
 
     ~FunctionsGLEGL() override {}
 
   private:
-    void *loadProcAddress(const std::string &function) override
+    void *loadProcAddress(const std::string &function) const override
     {
         return mEGL.getProcAddress(function.c_str());
     }
 
     const FunctionsEGL &mEGL;
 };
 
 FunctionsGL *FunctionsEGL::makeFunctionsGL(void) const
--- a/gfx/angle/src/libANGLE/renderer/gl/egl/FunctionsEGLDL.cpp
+++ b/gfx/angle/src/libANGLE/renderer/gl/egl/FunctionsEGLDL.cpp
@@ -7,68 +7,60 @@
 // FunctionsEGLDL.cpp: Implements the FunctionsEGLDL class.
 
 #include "libANGLE/renderer/gl/egl/FunctionsEGLDL.h"
 
 #include <dlfcn.h>
 
 namespace rx
 {
-
-DynamicLib::DynamicLib() : handle(nullptr)
-{
-}
-
-DynamicLib::~DynamicLib()
+namespace
 {
-    if (handle)
-    {
-        dlclose(handle);
-        handle = nullptr;
-    }
-}
-
-// Due to a bug in Mesa (or maybe libdl) it's not possible to close and re-open libEGL.so
-// an arbitrary number of times.  End2end tests would die after a couple hundred tests.
-// So we use a static object with a destructor to close the library when the program exits.
-// TODO(fjhenigman) File a bug and put a link here.
-DynamicLib FunctionsEGLDL::sNativeLib;
+// In ideal world, we would want this to be a member of FunctionsEGLDL,
+// and call dlclose() on it in ~FunctionsEGLDL().
+// However, some GL implementations are broken and don't allow multiple
+// load/unload cycles, but only static linking with them.
+// That's why we dlopen() this handle once and never dlclose() it.
+// This is consistent with Chromium's CleanupNativeLibraries() code,
+// referencing crbug.com/250813 and http://www.xfree86.org/4.3.0/DRI11.html
+void *nativeEGLHandle;
+}  // anonymous namespace
 
 FunctionsEGLDL::FunctionsEGLDL() : mGetProcAddressPtr(nullptr)
 {
 }
 
 FunctionsEGLDL::~FunctionsEGLDL()
 {
 }
 
 egl::Error FunctionsEGLDL::initialize(EGLNativeDisplayType nativeDisplay, const char *libName)
 {
-    if (!sNativeLib.handle)
+    if (!nativeEGLHandle)
     {
-        sNativeLib.handle = dlopen(libName, RTLD_NOW);
-        if (!sNativeLib.handle)
+        nativeEGLHandle = dlopen(libName, RTLD_NOW);
+        if (!nativeEGLHandle)
         {
             return egl::EglNotInitialized() << "Could not dlopen native EGL: " << dlerror();
         }
     }
 
     mGetProcAddressPtr =
-        reinterpret_cast<PFNEGLGETPROCADDRESSPROC>(dlsym(sNativeLib.handle, "eglGetProcAddress"));
+        reinterpret_cast<PFNEGLGETPROCADDRESSPROC>(dlsym(nativeEGLHandle, "eglGetProcAddress"));
     if (!mGetProcAddressPtr)
     {
         return egl::EglNotInitialized() << "Could not find eglGetProcAddress";
     }
 
     return FunctionsEGL::initialize(nativeDisplay);
 }
 
 void *FunctionsEGLDL::getProcAddress(const char *name) const
 {
     void *f = reinterpret_cast<void *>(mGetProcAddressPtr(name));
     if (f)
     {
         return f;
     }
-    return dlsym(sNativeLib.handle, name);
+    return dlsym(nativeEGLHandle, name);
 }
 
 }  // namespace rx
--- a/gfx/angle/src/libANGLE/renderer/gl/egl/FunctionsEGLDL.h
+++ b/gfx/angle/src/libANGLE/renderer/gl/egl/FunctionsEGLDL.h
@@ -9,34 +9,23 @@
 #ifndef LIBANGLE_RENDERER_GL_CROS_FUNCTIONSEGLDL_H_
 #define LIBANGLE_RENDERER_GL_CROS_FUNCTIONSEGLDL_H_
 
 #include "libANGLE/renderer/gl/egl/FunctionsEGL.h"
 #include "libANGLE/renderer/gl/egl/functionsegl_typedefs.h"
 
 namespace rx
 {
-
-class DynamicLib final
-{
-  public:
-    void *handle;
-
-    DynamicLib();
-    ~DynamicLib();
-};
-
 class FunctionsEGLDL : public FunctionsEGL
 {
   public:
     FunctionsEGLDL();
     ~FunctionsEGLDL() override;
 
     egl::Error initialize(EGLNativeDisplayType nativeDisplay, const char *libName);
     void *getProcAddress(const char *name) const override;
 
   private:
     PFNEGLGETPROCADDRESSPROC mGetProcAddressPtr;
-    static DynamicLib sNativeLib;
 };
 }  // namespace rx
 
 #endif  // LIBANGLE_RENDERER_GL_CROS_FUNCTIONSEGLDL_H_
--- a/gfx/angle/src/libANGLE/renderer/gl/egl/PbufferSurfaceEGL.cpp
+++ b/gfx/angle/src/libANGLE/renderer/gl/egl/PbufferSurfaceEGL.cpp
@@ -3,35 +3,46 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 //
 
 // PbufferSurfaceEGL.h: EGL implementation of egl::Surface for pbuffers
 
 #include "libANGLE/renderer/gl/egl/PbufferSurfaceEGL.h"
 
+#include "libANGLE/Surface.h"
+#include "libANGLE/renderer/gl/egl/egl_utils.h"
+
 namespace rx
 {
 
 PbufferSurfaceEGL::PbufferSurfaceEGL(const egl::SurfaceState &state,
                                      const FunctionsEGL *egl,
                                      EGLConfig config,
-                                     const std::vector<EGLint> &attribList,
                                      RendererGL *renderer)
-    : SurfaceEGL(state, egl, config, attribList, renderer)
+    : SurfaceEGL(state, egl, config, renderer)
 {
 }
 
 PbufferSurfaceEGL::~PbufferSurfaceEGL()
 {
 }
 
 egl::Error PbufferSurfaceEGL::initialize(const egl::Display *display)
 {
-    mSurface = mEGL->createPbufferSurface(mConfig, mAttribList.data());
+    constexpr EGLint kForwardedPBufferSurfaceAttributes[] = {
+        EGL_WIDTH,          EGL_HEIGHT,         EGL_LARGEST_PBUFFER, EGL_TEXTURE_FORMAT,
+        EGL_TEXTURE_TARGET, EGL_MIPMAP_TEXTURE, EGL_VG_COLORSPACE,   EGL_VG_ALPHA_FORMAT,
+    };
+
+    native_egl::AttributeVector nativeAttribs =
+        native_egl::TrimAttributeMap(mState.attributes, kForwardedPBufferSurfaceAttributes);
+    native_egl::FinalizeAttributeVector(&nativeAttribs);
+
+    mSurface = mEGL->createPbufferSurface(mConfig, nativeAttribs.data());
     if (mSurface == EGL_NO_SURFACE)
     {
         return egl::Error(mEGL->getError(), "eglCreatePbufferSurface failed");
     }
 
     return egl::NoError();
 }
 
--- a/gfx/angle/src/libANGLE/renderer/gl/egl/PbufferSurfaceEGL.h
+++ b/gfx/angle/src/libANGLE/renderer/gl/egl/PbufferSurfaceEGL.h
@@ -18,17 +18,16 @@ namespace rx
 {
 
 class PbufferSurfaceEGL : public SurfaceEGL
 {
   public:
     PbufferSurfaceEGL(const egl::SurfaceState &state,
                       const FunctionsEGL *egl,
                       EGLConfig config,
-                      const std::vector<EGLint> &attribList,
                       RendererGL *renderer);
     ~PbufferSurfaceEGL() override;
 
     egl::Error initialize(const egl::Display *display) override;
 };
 
 }  // namespace rx
 
--- a/gfx/angle/src/libANGLE/renderer/gl/egl/SurfaceEGL.cpp
+++ b/gfx/angle/src/libANGLE/renderer/gl/egl/SurfaceEGL.cpp
@@ -11,22 +11,20 @@
 #include "common/debug.h"
 
 namespace rx
 {
 
 SurfaceEGL::SurfaceEGL(const egl::SurfaceState &state,
                        const FunctionsEGL *egl,
                        EGLConfig config,
-                       const std::vector<EGLint> &attribList,
                        RendererGL *renderer)
     : SurfaceGL(state, renderer),
       mEGL(egl),
       mConfig(config),
-      mAttribList(attribList),
       mSurface(EGL_NO_SURFACE)
 {
 }
 
 SurfaceEGL::~SurfaceEGL()
 {
     if (mSurface != EGL_NO_SURFACE)
     {
--- a/gfx/angle/src/libANGLE/renderer/gl/egl/SurfaceEGL.h
+++ b/gfx/angle/src/libANGLE/renderer/gl/egl/SurfaceEGL.h
@@ -18,17 +18,16 @@ namespace rx
 {
 
 class SurfaceEGL : public SurfaceGL
 {
   public:
     SurfaceEGL(const egl::SurfaceState &state,
                const FunctionsEGL *egl,
                EGLConfig config,
-               const std::vector<EGLint> &attribList,
                RendererGL *renderer);
     ~SurfaceEGL() override;
 
     egl::Error makeCurrent() override;
     egl::Error swap(const gl::Context *context) override;
     egl::Error postSubBuffer(const gl::Context *context,
                              EGLint x,
                              EGLint y,
@@ -43,15 +42,14 @@ class SurfaceEGL : public SurfaceGL
     EGLint isPostSubBufferSupported() const override;
     EGLint getSwapBehavior() const override;
 
     EGLSurface getSurface() const;
 
   protected:
     const FunctionsEGL *mEGL;
     EGLConfig mConfig;
-    std::vector<EGLint> mAttribList;
     EGLSurface mSurface;
 };
 
 }  // namespace rx
 
 #endif  // LIBANGLE_RENDERER_GL_EGL_SURFACEEGL_H_
--- a/gfx/angle/src/libANGLE/renderer/gl/egl/WindowSurfaceEGL.cpp
+++ b/gfx/angle/src/libANGLE/renderer/gl/egl/WindowSurfaceEGL.cpp
@@ -3,36 +3,46 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 //
 
 // WindowSurfaceEGL.h: EGL implementation of egl::Surface for windows
 
 #include "libANGLE/renderer/gl/egl/WindowSurfaceEGL.h"
 
+#include "libANGLE/Surface.h"
+#include "libANGLE/renderer/gl/egl/egl_utils.h"
+
 namespace rx
 {
 
 WindowSurfaceEGL::WindowSurfaceEGL(const egl::SurfaceState &state,
                                    const FunctionsEGL *egl,
                                    EGLConfig config,
                                    EGLNativeWindowType window,
-                                   const std::vector<EGLint> &attribList,
                                    RendererGL *renderer)
-    : SurfaceEGL(state, egl, config, attribList, renderer), mWindow(window)
+    : SurfaceEGL(state, egl, config, renderer), mWindow(window)
 {
 }
 
 WindowSurfaceEGL::~WindowSurfaceEGL()
 {
 }
 
 egl::Error WindowSurfaceEGL::initialize(const egl::Display *display)
 {
-    mSurface = mEGL->createWindowSurface(mConfig, mWindow, mAttribList.data());
+    constexpr EGLint kForwardedWindowSurfaceAttributes[] = {
+        EGL_RENDER_BUFFER, EGL_POST_SUB_BUFFER_SUPPORTED_NV,
+    };
+
+    native_egl::AttributeVector nativeAttribs =
+        native_egl::TrimAttributeMap(mState.attributes, kForwardedWindowSurfaceAttributes);
+    native_egl::FinalizeAttributeVector(&nativeAttribs);
+
+    mSurface = mEGL->createWindowSurface(mConfig, mWindow, nativeAttribs.data());
     if (mSurface == EGL_NO_SURFACE)
     {
         return egl::Error(mEGL->getError(), "eglCreateWindowSurface failed");
     }
 
     return egl::NoError();
 }
 
--- a/gfx/angle/src/libANGLE/renderer/gl/egl/WindowSurfaceEGL.h
+++ b/gfx/angle/src/libANGLE/renderer/gl/egl/WindowSurfaceEGL.h
@@ -16,17 +16,16 @@ namespace rx
 
 class WindowSurfaceEGL : public SurfaceEGL
 {
   public:
     WindowSurfaceEGL(const egl::SurfaceState &state,
                      const FunctionsEGL *egl,
                      EGLConfig config,
                      EGLNativeWindowType window,
-                     const std::vector<EGLint> &attribList,
                      RendererGL *renderer);
     ~WindowSurfaceEGL() override;
 
     egl::Error initialize(const egl::Display *display) override;
 
   private:
     EGLNativeWindowType mWindow;
 };
--- a/gfx/angle/src/libANGLE/renderer/gl/egl/android/DisplayAndroid.cpp
+++ b/gfx/angle/src/libANGLE/renderer/gl/egl/android/DisplayAndroid.cpp
@@ -112,17 +112,17 @@ egl::Error DisplayAndroid::initialize(eg
     if (success == EGL_FALSE)
     {
         return egl::EglNotInitialized()
                << "eglMakeCurrent failed with " << egl::Error(mEGL->getError());
     }
     mCurrentSurface = mDummyPbuffer;
 
     mFunctionsGL = mEGL->makeFunctionsGL();
-    mFunctionsGL->initialize();
+    mFunctionsGL->initialize(display->getAttributeMap());
 
     return DisplayGL::initialize(display);
 }
 
 void DisplayAndroid::terminate()
 {
     DisplayGL::terminate();
 
@@ -170,31 +170,31 @@ SurfaceImpl *DisplayAndroid::createWindo
     EGLConfig config;
     EGLint numConfig;
     EGLBoolean success;
 
     const EGLint configAttribList[] = {EGL_CONFIG_ID, mConfigIds[state.config->configID], EGL_NONE};
     success = mEGL->chooseConfig(configAttribList, &config, 1, &numConfig);
     ASSERT(success && numConfig == 1);
 
-    return new WindowSurfaceEGL(state, mEGL, config, window, attribs.toIntVector(), getRenderer());
+    return new WindowSurfaceEGL(state, mEGL, config, window, getRenderer());
 }
 
 SurfaceImpl *DisplayAndroid::createPbufferSurface(const egl::SurfaceState &state,
                                                   const egl::AttributeMap &attribs)
 {
     EGLConfig config;
     EGLint numConfig;
     EGLBoolean success;
 
     const EGLint configAttribList[] = {EGL_CONFIG_ID, mConfigIds[state.config->configID], EGL_NONE};
     success = mEGL->chooseConfig(configAttribList, &config, 1, &numConfig);
     ASSERT(success && numConfig == 1);
 
-    return new PbufferSurfaceEGL(state, mEGL, config, attribs.toIntVector(), getRenderer());
+    return new PbufferSurfaceEGL(state, mEGL, config, getRenderer());
 }
 
 SurfaceImpl *DisplayAndroid::createPbufferFromClientBuffer(const egl::SurfaceState &state,
                                                            EGLenum buftype,
                                                            EGLClientBuffer clientBuffer,
                                                            const egl::AttributeMap &attribs)
 {
     UNIMPLEMENTED();
new file mode 100644
--- /dev/null
+++ b/gfx/angle/src/libANGLE/renderer/gl/egl/egl_utils.cpp
@@ -0,0 +1,45 @@
+//
+// 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.
+//
+
+// egl_utils.cpp: Utility routines specific to the EGL->EGL implementation.
+
+#include "libANGLE/renderer/gl/egl/egl_utils.h"
+
+#include "common/debug.h"
+
+namespace rx
+{
+
+namespace native_egl
+{
+
+AttributeVector TrimAttributeMap(const egl::AttributeMap &attributes,
+                                 const EGLint *forwardAttribs,
+                                 size_t forwardAttribsCount)
+{
+    AttributeVector result;
+    for (size_t forwardAttribIndex = 0; forwardAttribIndex < forwardAttribsCount;
+         forwardAttribIndex++)
+    {
+        EGLint forwardAttrib = forwardAttribs[forwardAttribIndex];
+        if (attributes.contains(forwardAttrib))
+        {
+            result.push_back(forwardAttrib);
+            result.push_back(attributes.get(forwardAttrib));
+        }
+    }
+    return result;
+}
+
+void FinalizeAttributeVector(AttributeVector *attributeVector)
+{
+    ASSERT(attributeVector);
+    attributeVector->push_back(EGL_NONE);
+}
+
+}  // namespace egl
+
+}  // namespace rx
new file mode 100644
--- /dev/null
+++ b/gfx/angle/src/libANGLE/renderer/gl/egl/egl_utils.h
@@ -0,0 +1,45 @@
+//
+// 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.
+//
+
+// egl_utils.h: Utility routines specific to the EGL->EGL implementation.
+
+#ifndef LIBANGLE_RENDERER_GL_EGL_EGLUTILS_H_
+#define LIBANGLE_RENDERER_GL_EGL_EGLUTILS_H_
+
+#include <vector>
+
+#include "common/platform.h"
+#include "libANGLE/AttributeMap.h"
+
+namespace rx
+{
+
+namespace native_egl
+{
+
+using AttributeVector = std::vector<EGLint>;
+
+// Filter the attribute map and return a vector of attributes that can be passed to the native
+// driver.  Does NOT append EGL_NONE to the vector.
+AttributeVector TrimAttributeMap(const egl::AttributeMap &attributes,
+                                 const EGLint *forwardAttribs,
+                                 size_t forwardAttribsCount);
+
+template <size_t N>
+AttributeVector TrimAttributeMap(const egl::AttributeMap &attributes,
+                                 const EGLint (&forwardAttribs)[N])
+{
+    return TrimAttributeMap(attributes, forwardAttribs, N);
+}
+
+// Append EGL_NONE to the attribute vector so that it can be passed to a native driver.
+void FinalizeAttributeVector(AttributeVector *attributeVector);
+
+}  // namespace egl
+
+}  // namespace rx
+
+#endif  // LIBANGLE_RENDERER_GL_EGL_EGLUTILS_H_
--- a/gfx/angle/src/libANGLE/renderer/gl/egl/ozone/DisplayOzone.cpp
+++ b/gfx/angle/src/libANGLE/renderer/gl/egl/ozone/DisplayOzone.cpp
@@ -213,17 +213,17 @@ bool DisplayOzone::Buffer::resize(int32_
         return false;
     }
 
     FunctionsGL *gl    = mDisplay->mFunctionsGL;
     StateManagerGL *sm = mDisplay->getRenderer()->getStateManager();
 
     gl->genRenderbuffers(1, &mColorBuffer);
     sm->bindRenderbuffer(GL_RENDERBUFFER, mColorBuffer);
-    gl->eglImageTargetRenderbufferStorageOES(GL_RENDERBUFFER, mImage);
+    gl->eGLImageTargetRenderbufferStorageOES(GL_RENDERBUFFER, mImage);
 
     sm->bindFramebuffer(GL_FRAMEBUFFER, mGLFB);
     gl->framebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0_EXT, GL_RENDERBUFFER,
                                 mColorBuffer);
 
     if (mDepthBits || mStencilBits)
     {
         gl->genRenderbuffers(1, &mDSBuffer);
@@ -258,34 +258,34 @@ bool DisplayOzone::Buffer::initialize(co
 bool DisplayOzone::Buffer::initialize(int width, int height)
 {
     mDisplay->mFunctionsGL->genFramebuffers(1, &mGLFB);
     return resize(width, height);
 }
 
 void DisplayOzone::Buffer::bindTexImage()
 {
-    mDisplay->mFunctionsGL->eglImageTargetTexture2DOES(GL_TEXTURE_2D, mImage);
+    mDisplay->mFunctionsGL->eGLImageTargetTexture2DOES(GL_TEXTURE_2D, mImage);
 }
 
 GLuint DisplayOzone::Buffer::getTexture()
 {
     // TODO(fjhenigman) Try not to create a new texture every time.  That already works on Intel
     // and should work on Mali with proper fences.
     FunctionsGL *gl    = mDisplay->mFunctionsGL;
     StateManagerGL *sm = mDisplay->getRenderer()->getStateManager();
 
     gl->genTextures(1, &mTexture);
     sm->bindTexture(GL_TEXTURE_2D, mTexture);
     gl->texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
     gl->texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
     gl->texParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
     gl->texParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
     ASSERT(mImage != EGL_NO_IMAGE_KHR);
-    gl->eglImageTargetTexture2DOES(GL_TEXTURE_2D, mImage);
+    gl->eGLImageTargetTexture2DOES(GL_TEXTURE_2D, mImage);
     return mTexture;
 }
 
 uint32_t DisplayOzone::Buffer::getDRMFB()
 {
     if (!mHasDRMFB)
     {
         int fd              = gbm_device_get_fd(mDisplay->mGBM);
@@ -506,17 +506,17 @@ egl::Error DisplayOzone::initialize(egl:
     ANGLE_TRY(initializeContext(display->getAttributeMap()));
 
     if (!mEGL->makeCurrent(EGL_NO_SURFACE, mContext))
     {
         return egl::EglNotInitialized() << "Could not make context current.";
     }
 
     mFunctionsGL = mEGL->makeFunctionsGL();
-    mFunctionsGL->initialize();
+    mFunctionsGL->initialize(display->getAttributeMap());
 
     return DisplayGL::initialize(display);
 }
 
 void DisplayOzone::pageFlipHandler(int fd,
                                    unsigned int sequence,
                                    unsigned int tv_sec,
                                    unsigned int tv_usec,
@@ -679,31 +679,31 @@ void DisplayOzone::drawWithTexture(Buffe
              // window border outside corners
              1, -1, 1,
             -1, -1, 1,
              1,  1, 1,
             -1,  1, 1,
         };
         // clang-format on
         gl->genBuffers(1, &mVertexBuffer);
-        sm->bindBuffer(GL_ARRAY_BUFFER, mVertexBuffer);
+        sm->bindBuffer(gl::BufferBinding::Array, mVertexBuffer);
         gl->bufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
 
         // window border triangle strip
         const GLuint borderStrip[] = {5, 0, 4, 2, 6, 3, 7, 1, 5, 0};
 
         gl->genBuffers(1, &mIndexBuffer);
-        sm->bindBuffer(GL_ELEMENT_ARRAY_BUFFER, mIndexBuffer);
+        sm->bindBuffer(gl::BufferBinding::ElementArray, mIndexBuffer);
         gl->bufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(borderStrip), borderStrip, GL_STATIC_DRAW);
     }
     else
     {
         sm->useProgram(mProgram);
-        sm->bindBuffer(GL_ARRAY_BUFFER, mVertexBuffer);
-        sm->bindBuffer(GL_ELEMENT_ARRAY_BUFFER, mIndexBuffer);
+        sm->bindBuffer(gl::BufferBinding::Array, mVertexBuffer);
+        sm->bindBuffer(gl::BufferBinding::ElementArray, mIndexBuffer);
     }
 
     // convert from pixels to "-1 to 1" space
     const NativeWindow *n = buffer->getNative();
     double x              = n->x * 2. / mWidth - 1;
     double y              = n->y * 2. / mHeight - 1;
     double halfw          = n->width * 1. / mWidth;
     double halfh          = n->height * 1. / mHeight;
--- a/gfx/angle/src/libANGLE/renderer/gl/formatutilsgl.cpp
+++ b/gfx/angle/src/libANGLE/renderer/gl/formatutilsgl.cpp
@@ -22,24 +22,36 @@ namespace nativegl
 
 SupportRequirement::SupportRequirement()
     : version(std::numeric_limits<GLuint>::max(), std::numeric_limits<GLuint>::max()),
       versionExtensions(),
       requiredExtensions()
 {
 }
 
+SupportRequirement::SupportRequirement(const SupportRequirement &other) = default;
+
+SupportRequirement::~SupportRequirement()
+{
+}
+
 InternalFormat::InternalFormat()
     : texture(),
       filter(),
       renderbuffer(),
       framebufferAttachment()
 {
 }
 
+InternalFormat::InternalFormat(const InternalFormat &other) = default;
+
+InternalFormat::~InternalFormat()
+{
+}
+
 // supported = version || vertexExt
 static inline SupportRequirement VersionOrExts(GLuint major, GLuint minor, const std::string &versionExt)
 {
     SupportRequirement requirement;
     requirement.version.major = major;
     requirement.version.minor = minor;
     angle::SplitStringAlongWhitespace(versionExt, &requirement.versionExtensions);
     return requirement;
@@ -420,39 +432,60 @@ static GLenum GetNativeCompressedFormat(
         }
     }
 
     return result;
 }
 
 static GLenum GetNativeType(const FunctionsGL *functions,
                             const WorkaroundsGL &workarounds,
+                            GLenum format,
                             GLenum type)
 {
     GLenum result = type;
 
     if (functions->standard == STANDARD_GL_DESKTOP)
     {
         if (type == GL_HALF_FLOAT_OES)
         {
-            // The enums differ for the OES half float extensions and desktop GL spec. Update it.
+            // The enums differ for the OES half float extensions and desktop GL spec.
+            // Update it.
             result = GL_HALF_FLOAT;
         }
     }
+    else if (functions->isAtLeastGLES(gl::Version(3, 0)))
+    {
+        if (type == GL_HALF_FLOAT_OES)
+        {
+            switch (format)
+            {
+                case GL_LUMINANCE_ALPHA:
+                case GL_LUMINANCE:
+                case GL_ALPHA:
+                    // In ES3, these formats come from EXT_texture_storage, which uses
+                    // HALF_FLOAT_OES. Other formats (like RGBA) use HALF_FLOAT (non-OES) in ES3.
+                    break;
+
+                default:
+                    result = GL_HALF_FLOAT;
+                    break;
+            }
+        }
+    }
 
     return result;
 }
 
 static GLenum GetNativeReadType(const FunctionsGL *functions,
                                 const WorkaroundsGL &workarounds,
                                 GLenum type)
 {
     GLenum result = type;
 
-    if (functions->standard == STANDARD_GL_DESKTOP)
+    if (functions->standard == STANDARD_GL_DESKTOP || functions->isAtLeastGLES(gl::Version(3, 0)))
     {
         if (type == GL_HALF_FLOAT_OES)
         {
             // The enums differ for the OES half float extensions and desktop GL spec. Update it.
             result = GL_HALF_FLOAT;
         }
     }
 
@@ -472,28 +505,28 @@ TexImageFormat GetTexImageFormat(const F
                                  GLenum internalFormat,
                                  GLenum format,
                                  GLenum type)
 {
     TexImageFormat result;
     result.internalFormat = GetNativeInternalFormat(
         functions, workarounds, gl::GetInternalFormatInfo(internalFormat, type));
     result.format = GetNativeFormat(functions, workarounds, format);
-    result.type   = GetNativeType(functions, workarounds, type);
+    result.type   = GetNativeType(functions, workarounds, format, type);
     return result;
 }
 
 TexSubImageFormat GetTexSubImageFormat(const FunctionsGL *functions,
                                        const WorkaroundsGL &workarounds,
                                        GLenum format,
                                        GLenum type)
 {
     TexSubImageFormat result;
     result.format = GetNativeFormat(functions, workarounds, format);
-    result.type   = GetNativeType(functions, workarounds, type);
+    result.type   = GetNativeType(functions, workarounds, format, type);
     return result;
 }
 
 CompressedTexImageFormat GetCompressedTexImageFormat(const FunctionsGL *functions,
                                                      const WorkaroundsGL &workarounds,
                                                      GLenum internalFormat)
 {
     CompressedTexImageFormat result;
--- a/gfx/angle/src/libANGLE/renderer/gl/formatutilsgl.h
+++ b/gfx/angle/src/libANGLE/renderer/gl/formatutilsgl.h
@@ -23,30 +23,34 @@ namespace rx
 {
 
 namespace nativegl
 {
 
 struct SupportRequirement
 {
     SupportRequirement();
+    SupportRequirement(const SupportRequirement &other);
+    ~SupportRequirement();
 
     // Version that this format became supported without extensions
     gl::Version version;
 
     // Extensions that are required if the minimum version is not met
     std::vector<std::string> versionExtensions;
 
     // Extensions that are always required to support this format
     std::vector<std::string> requiredExtensions;
 };
 
 struct InternalFormat
 {
     InternalFormat();
+    InternalFormat(const InternalFormat &other);
+    ~InternalFormat();
 
     SupportRequirement texture;
     SupportRequirement filter;
     SupportRequirement renderbuffer;
     SupportRequirement framebufferAttachment;
 };
 const InternalFormat &GetInternalFormatInfo(GLenum internalFormat, StandardGL standard);
 
--- a/gfx/angle/src/libANGLE/renderer/gl/functionsgl_typedefs.h
+++ b/gfx/angle/src/libANGLE/renderer/gl/functionsgl_typedefs.h
@@ -41,16 +41,18 @@ typedef double           GLclampd;
 typedef khronos_int32_t  GLfixed;
 typedef khronos_intptr_t GLintptr;
 typedef khronos_ssize_t  GLsizeiptr;
 typedef unsigned short   GLhalf;
 typedef khronos_int64_t  GLint64;
 typedef khronos_uint64_t GLuint64;
 typedef struct __GLsync *GLsync;
 
+// TODO(jmadill): It's likely we can auto-generate this file from gl.xml.
+
 namespace rx
 {
 typedef void (INTERNAL_GL_APIENTRY *GLDEBUGPROC)(GLenum source, GLenum type, GLuint id, GLenum severity, GLsizei length, const GLchar *message, const void *userParam);
 typedef void (INTERNAL_GL_APIENTRY *GLDEBUGPROCARB)(GLenum source, GLenum type, GLuint id, GLenum severity, GLsizei length, const GLchar *message, const void *userParam);
 typedef void (INTERNAL_GL_APIENTRY *GLDEBUGPROCAMD)(GLuint id, GLenum category, GLenum severity, GLsizei length, const GLchar *message, void *userParam);
 
 // 1.0
 typedef void (INTERNAL_GL_APIENTRY *PFNGLBLENDFUNCPROC)(GLenum, GLenum);
@@ -390,18 +392,29 @@ typedef void (INTERNAL_GL_APIENTRY *PFNG
 typedef void (INTERNAL_GL_APIENTRY *PFNGLGETINTEGER64I_VPROC)(GLenum, GLuint, GLint64 *);
 typedef void (INTERNAL_GL_APIENTRY *PFNGLGETINTEGER64VPROC)(GLenum, GLint64 *);
 typedef void (INTERNAL_GL_APIENTRY *PFNGLGETMULTISAMPLEFVPROC)(GLenum, GLuint, GLfloat *);
 typedef void (INTERNAL_GL_APIENTRY *PFNGLGETSYNCIVPROC)(GLsync, GLenum, GLsizei, GLsizei *, GLint *);
 typedef GLboolean (INTERNAL_GL_APIENTRY *PFNGLISSYNCPROC)(GLsync);
 typedef void (INTERNAL_GL_APIENTRY *PFNGLMULTIDRAWELEMENTSBASEVERTEXPROC)(GLenum, const GLsizei *, GLenum, const GLvoid *const*, GLsizei, const GLint *);
 typedef void (INTERNAL_GL_APIENTRY *PFNGLPROVOKINGVERTEXPROC)(GLenum);
 typedef void (INTERNAL_GL_APIENTRY *PFNGLSAMPLEMASKIPROC)(GLuint, GLbitfield);
-typedef void (INTERNAL_GL_APIENTRY *PFNGLTEXIMAGE2DMULTISAMPLEPROC)(GLenum, GLsizei, GLint, GLsizei, GLsizei, GLboolean);
-typedef void (INTERNAL_GL_APIENTRY *PFNGLTEXIMAGE3DMULTISAMPLEPROC)(GLenum, GLsizei, GLint, GLsizei, GLsizei, GLsizei, GLboolean);
+typedef void(INTERNAL_GL_APIENTRY *PFNGLTEXIMAGE2DMULTISAMPLEPROC)(GLenum,
+                                                                   GLsizei,
+                                                                   GLenum,
+                                                                   GLsizei,
+                                                                   GLsizei,
+                                                                   GLboolean);
+typedef void(INTERNAL_GL_APIENTRY *PFNGLTEXIMAGE3DMULTISAMPLEPROC)(GLenum,
+                                                                   GLsizei,
+                                                                   GLenum,
+                                                                   GLsizei,
+                                                                   GLsizei,
+                                                                   GLsizei,
+                                                                   GLboolean);
 typedef void (INTERNAL_GL_APIENTRY *PFNGLWAITSYNCPROC)(GLsync, GLbitfield, GLuint64);
 
 // 3.3
 typedef void (INTERNAL_GL_APIENTRY *PFNGLBINDFRAGDATALOCATIONINDEXEDPROC)(GLuint, GLuint, GLuint, const GLchar *);
 typedef void (INTERNAL_GL_APIENTRY *PFNGLBINDSAMPLERPROC)(GLuint, GLuint);
 typedef void (INTERNAL_GL_APIENTRY *PFNGLDELETESAMPLERSPROC)(GLsizei, const GLuint *);
 typedef void (INTERNAL_GL_APIENTRY *PFNGLGENSAMPLERSPROC)(GLsizei, GLuint *);
 typedef GLint (INTERNAL_GL_APIENTRY *PFNGLGETFRAGDATAINDEXPROC)(GLuint, const GLchar *);
@@ -642,17 +655,18 @@ typedef void (INTERNAL_GL_APIENTRY *PFNG
 typedef void (INTERNAL_GL_APIENTRY *PFNGLCLEARTEXSUBIMAGEPROC)(GLuint, GLint, GLint, GLint, GLint, GLsizei, GLsizei, GLsizei, GLenum, GLenum, const void *);
 
 // 4.5
 typedef void (INTERNAL_GL_APIENTRY *PFNGLBINDTEXTUREUNITPROC)(GLuint, GLuint);
 typedef void (INTERNAL_GL_APIENTRY *PFNGLBLITNAMEDFRAMEBUFFERPROC)(GLuint, GLuint, GLint, GLint, GLint, GLint, GLint, GLint, GLint, GLint, GLbitfield, GLenum);
 typedef GLenum (INTERNAL_GL_APIENTRY *PFNGLCHECKNAMEDFRAMEBUFFERSTATUSPROC)(GLuint, GLenum);
 typedef void (INTERNAL_GL_APIENTRY *PFNGLCLEARNAMEDBUFFERDATAPROC)(GLuint, GLenum, GLenum, GLenum, const void *);
 typedef void (INTERNAL_GL_APIENTRY *PFNGLCLEARNAMEDBUFFERSUBDATAPROC)(GLuint, GLenum, GLintptr, GLsizeiptr, GLenum, GLenum, const void *);
-typedef void (INTERNAL_GL_APIENTRY *PFNGLCLEARNAMEDFRAMEBUFFERFIPROC)(GLuint, GLenum, const GLfloat, GLint);
+typedef void(
+    INTERNAL_GL_APIENTRY *PFNGLCLEARNAMEDFRAMEBUFFERFIPROC)(GLuint, GLenum, GLint, GLfloat, GLint);
 typedef void (INTERNAL_GL_APIENTRY *PFNGLCLEARNAMEDFRAMEBUFFERFVPROC)(GLuint, GLenum, GLint, const GLfloat *);
 typedef void (INTERNAL_GL_APIENTRY *PFNGLCLEARNAMEDFRAMEBUFFERIVPROC)(GLuint, GLenum, GLint, const GLint *);
 typedef void (INTERNAL_GL_APIENTRY *PFNGLCLEARNAMEDFRAMEBUFFERUIVPROC)(GLuint, GLenum, GLint, const GLuint *);
 typedef void (INTERNAL_GL_APIENTRY *PFNGLCLIPCONTROLPROC)(GLenum, GLenum);
 typedef void (INTERNAL_GL_APIENTRY *PFNGLCOMPRESSEDTEXTURESUBIMAGE1DPROC)(GLuint, GLint, GLint, GLsizei, GLenum, GLsizei, const void *);
 typedef void (INTERNAL_GL_APIENTRY *PFNGLCOMPRESSEDTEXTURESUBIMAGE2DPROC)(GLuint, GLint, GLint, GLint, GLsizei, GLsizei, GLenum, GLsizei, const void *);
 typedef void (INTERNAL_GL_APIENTRY *PFNGLCOMPRESSEDTEXTURESUBIMAGE3DPROC)(GLuint, GLint, GLint, GLint, GLint, GLsizei, GLsizei, GLsizei, GLenum, GLsizei, const void *);
 typedef void (INTERNAL_GL_APIENTRY *PFNGLCOPYNAMEDBUFFERSUBDATAPROC)(GLuint, GLuint, GLintptr, GLintptr, GLsizeiptr);
@@ -748,11 +762,155 @@ typedef void (INTERNAL_GL_APIENTRY *PFNG
 typedef void (INTERNAL_GL_APIENTRY *PFNGLVERTEXARRAYATTRIBFORMATPROC)(GLuint, GLuint, GLint, GLenum, GLboolean, GLuint);
 typedef void (INTERNAL_GL_APIENTRY *PFNGLVERTEXARRAYATTRIBIFORMATPROC)(GLuint, GLuint, GLint, GLenum, GLuint);
 typedef void (INTERNAL_GL_APIENTRY *PFNGLVERTEXARRAYATTRIBLFORMATPROC)(GLuint, GLuint, GLint, GLenum, GLuint);
 typedef void (INTERNAL_GL_APIENTRY *PFNGLVERTEXARRAYBINDINGDIVISORPROC)(GLuint, GLuint, GLuint);
 typedef void (INTERNAL_GL_APIENTRY *PFNGLVERTEXARRAYELEMENTBUFFERPROC)(GLuint, GLuint);
 typedef void (INTERNAL_GL_APIENTRY *PFNGLVERTEXARRAYVERTEXBUFFERPROC)(GLuint, GLuint, GLuint, GLintptr, GLsizei);
 typedef void (INTERNAL_GL_APIENTRY *PFNGLVERTEXARRAYVERTEXBUFFERSPROC)(GLuint, GLuint, GLsizei, const GLuint *, const GLintptr *, const GLsizei *);
 
+// GL_EXT_discard_framebuffer
+typedef void(INTERNAL_GL_APIENTRY *PFNGLDISCARDFRAMEBUFFEREXTPROC)(GLenum target,
+                                                                   GLsizei numAttachments,
+                                                                   const GLenum *attachments);
+
+// GL_OES_EGL_image
+typedef void *GLeglImageOES;
+typedef void(INTERNAL_GL_APIENTRY *PFNGLEGLIMAGETARGETTEXTURE2DOESPROC)(GLenum target,
+                                                                        GLeglImageOES image);
+typedef void(INTERNAL_GL_APIENTRY *PFNGLEGLIMAGETARGETRENDERBUFFERSTORAGEOESPROC)(
+    GLenum target,
+    GLeglImageOES image);
+
+// NV_path_rendering (originally written against 3.2 compatibility profile)
+typedef void(INTERNAL_GL_APIENTRY *PFNGLMATRIXLOADFEXTPROC)(GLenum matrixMode, const GLfloat *m);
+typedef void(INTERNAL_GL_APIENTRY *PFNGLMATRIXLOADFNVPROC)(GLenum matrixMode, const GLfloat *m);
+typedef void(INTERNAL_GL_APIENTRY *PFNGLMATRIXLOADIDENTITYNVPROC)(GLenum matrixMode);
+typedef GLuint(INTERNAL_GL_APIENTRY *PFNGLGENPATHSNVPROC)(GLsizei range);
+typedef void(INTERNAL_GL_APIENTRY *PFNGLDELETEPATHSNVPROC)(GLuint path, GLsizei range);
+typedef GLboolean(INTERNAL_GL_APIENTRY *PFNGLISPATHNVPROC)(GLuint path);
+typedef void(INTERNAL_GL_APIENTRY *PFNGLPATHCOMMANDSNVPROC)(GLuint path,
+                                                            GLsizei numCommands,
+                                                            const GLubyte *commands,
+                                                            GLsizei numCoords,
+                                                            GLenum coordType,
+                                                            const void *coords);
+typedef void(INTERNAL_GL_APIENTRY *PFNGLPATHPARAMETERINVPROC)(GLuint path,
+                                                              GLenum pname,
+                                                              GLint value);
+typedef void(INTERNAL_GL_APIENTRY *PFNGLPATHPARAMETERFNVPROC)(GLuint path,
+                                                              GLenum pname,
+                                                              GLfloat value);
+typedef void(INTERNAL_GL_APIENTRY *PFNGLGETPATHPARAMETERIVNVPROC)(GLuint path,
+                                                                  GLenum pname,
+                                                                  GLint *value);
+typedef void(INTERNAL_GL_APIENTRY *PFNGLGETPATHPARAMETERFVNVPROC)(GLuint path,
+                                                                  GLenum pname,
+                                                                  GLfloat *value);
+typedef void(INTERNAL_GL_APIENTRY *PFNGLPATHSTENCILFUNCNVPROC)(GLenum func, GLint ref, GLuint mask);
+typedef void(INTERNAL_GL_APIENTRY *PFNGLSTENCILFILLPATHNVPROC)(GLuint path,
+                                                               GLenum fillMode,
+                                                               GLuint mask);
+typedef void(INTERNAL_GL_APIENTRY *PFNGLSTENCILSTROKEPATHNVPROC)(GLuint path,
+                                                                 GLint reference,
+                                                                 GLuint mask);
+typedef void(INTERNAL_GL_APIENTRY *PFNGLCOVERFILLPATHNVPROC)(GLuint path, GLenum coverMode);
+typedef void(INTERNAL_GL_APIENTRY *PFNGLCOVERSTROKEPATHNVPROC)(GLuint path, GLenum coverMode);
+typedef void(INTERNAL_GL_APIENTRY *PFNGLSTENCILTHENCOVERFILLPATHNVPROC)(GLuint path,
+                                                                        GLenum fillMode,
+                                                                        GLuint mask,
+                                                                        GLenum coverMode);
+typedef void(INTERNAL_GL_APIENTRY *PFNGLSTENCILTHENCOVERSTROKEPATHNVPROC)(GLuint path,
+                                                                          GLint reference,
+                                                                          GLuint mask,
+                                                                          GLenum coverMode);
+typedef void(INTERNAL_GL_APIENTRY *PFNGLCOVERFILLPATHINSTANCEDNVPROC)(
+    GLsizei numPaths,
+    GLenum pathNameType,
+    const void *paths,
+    GLuint pathBase,
+    GLenum coverMode,
+    GLenum transformType,
+    const GLfloat *transformValues);
+typedef void(INTERNAL_GL_APIENTRY *PFNGLCOVERSTROKEPATHINSTANCEDNVPROC)(
+    GLsizei numPaths,
+    GLenum pathNameType,
+    const void *paths,
+    GLuint pathBase,
+    GLenum coverMode,
+    GLenum transformType,
+    const GLfloat *transformValues);
+typedef void(INTERNAL_GL_APIENTRY *PFNGLSTENCILFILLPATHINSTANCEDNVPROC)(
+    GLsizei numPaths,
+    GLenum pathNameType,
+    const void *paths,
+    GLuint pathBase,
+    GLenum fillMode,
+    GLuint mask,
+    GLenum transformType,
+    const GLfloat *transformValues);
+typedef void(INTERNAL_GL_APIENTRY *PFNGLSTENCILSTROKEPATHINSTANCEDNVPROC)(
+    GLsizei numPaths,
+    GLenum pathNameType,
+    const void *paths,
+    GLuint pathBase,
+    GLint reference,
+    GLuint mask,
+    GLenum transformType,
+    const GLfloat *transformValues);
+typedef void(INTERNAL_GL_APIENTRY *PFNGLSTENCILTHENCOVERFILLPATHINSTANCEDNVPROC)(
+    GLsizei numPaths,
+    GLenum pathNameType,
+    const void *paths,
+    GLuint pathBase,
+    GLenum fillMode,
+    GLuint mask,
+    GLenum coverMode,
+    GLenum transformType,
+    const GLfloat *transformValues);
+typedef void(INTERNAL_GL_APIENTRY *PFNGLSTENCILTHENCOVERSTROKEPATHINSTANCEDNVPROC)(
+    GLsizei numPaths,
+    GLenum pathNameType,
+    const void *paths,
+    GLuint pathBase,
+    GLint reference,
+    GLuint mask,
+    GLenum coverMode,
+    GLenum transformType,
+    const GLfloat *transformValues);
+
+typedef void(INTERNAL_GL_APIENTRY *PFNGLBINDFRAGMENTINPUTLOCATIONNVPROC)(GLuint program,
+                                                                         GLint location,
+                                                                         const GLchar *name);
+typedef void(INTERNAL_GL_APIENTRY *PFNGLPROGRAMPATHFRAGMENTINPUTGENNVPROC)(GLuint program,
+                                                                           GLint location,
+                                                                           GLenum genMode,
+                                                                           GLint components,
+                                                                           const GLfloat *coeffs);
+
+// ES 3.2
+typedef void(INTERNAL_GL_APIENTRY *PFNGLBLENDBARRIERPROC)(void);
+typedef void(INTERNAL_GL_APIENTRY *PFNGLPRIMITIVEBOUNDINGBOXPROC)(GLfloat minX,
+                                                                  GLfloat minY,
+                                                                  GLfloat minZ,
+                                                                  GLfloat minW,
+                                                                  GLfloat maxX,
+                                                                  GLfloat maxY,
+                                                                  GLfloat maxZ,
+                                                                  GLfloat maxW);
+
+// GL_NV_internalformat_sample_query
+typedef void(INTERNAL_GL_APIENTRY *PFNGLGETINTERNALFORMATSAMPLEIVNVPROC)(GLenum target,
+                                                                         GLenum internalformat,
+                                                                         GLsizei samples,
+                                                                         GLenum pname,
+                                                                         GLsizei bufSize,
+                                                                         GLint *params);
+
+// EXT_debug_marker
+typedef void(INTERNAL_GL_APIENTRY *PFNGLINSERTEVENTMARKEREXTPROC)(GLsizei length,
+                                                                  const GLchar *marker);
+typedef void(INTERNAL_GL_APIENTRY *PFNGLPUSHGROUPMARKEREXTPROC)(GLsizei length,
+                                                                const GLchar *marker);
+typedef void(INTERNAL_GL_APIENTRY *PFNGLPOPGROUPMARKEREXTPROC)(void);
 }
 
 #endif // LIBANGLE_RENDERER_GL_FUNCTIONSGLTYPEDEFS_H_
new file mode 100644
--- /dev/null
+++ b/gfx/angle/src/libANGLE/renderer/gl/generate_gl_dispatch_table.py
@@ -0,0 +1,453 @@
+#!/usr/bin/python
+# 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.
+#
+# generate_gl_dispatch_table.py:
+#  Generation script for OpenGL bindings with ANGLE.
+
+import sys
+import os
+import re
+import xml.etree.ElementTree as etree
+from datetime import date
+
+# Set the CWD to the script directory.
+os.chdir(os.path.dirname(os.path.abspath(sys.argv[0])))
+
+sys.path.append('..')
+import angle_format
+
+def safe_append(the_dict, key, element):
+    if key not in the_dict:
+        the_dict[key] = []
+    the_dict[key].append(element)
+
+gl_xml_path = os.path.join('..', '..', '..', '..', 'scripts', 'gl.xml')
+dispatch_header_path = 'DispatchTableGL_autogen.h'
+dispatch_source_path = 'DispatchTableGL_autogen.cpp'
+null_functions_header_path = 'null_functions.h'
+null_functions_source_path = 'null_functions.cpp'
+
+# Load the JSON and XML data.
+data_source_name = 'gl_bindings_data.json'
+json_data = angle_format.load_json(data_source_name)
+xml_root = etree.parse(gl_xml_path).getroot()
+
+api_feature_info = {}
+
+core_removed_eps = []
+for core_removed_ep in xml_root.findall('feature/remove'):
+    assert(core_removed_ep.attrib['profile'] == 'core')
+    for command in core_removed_ep.findall('./command'):
+        core_removed_eps.append(command.attrib['name'])
+
+for feature in xml_root.findall('feature'):
+    api = feature.attrib['api']
+    name = feature.attrib['name']
+    number = feature.attrib['number']
+
+    # OpenGL ES 3.x versions are listed as api 'gles2'
+    if api != 'gl' and api != 'gles2':
+        continue
+
+    for command in feature.findall('./require/command'):
+        command_name = command.attrib['name']
+        safe_append(api_feature_info, command_name, (api, name, number))
+
+gl_extension_commands = {}
+gles2_extension_commands = {}
+both_extension_commands = {}
+
+for extension in xml_root.findall('extensions/extension'):
+    extension_name = extension.attrib['name']
+    support = extension.attrib['supported'].split('|')
+    for command in extension.findall('./require/command'):
+        command_name = command.attrib['name']
+        if 'gl' in support and 'gles2' in support:
+            # Special case for KHR extensions, since in GLES they are suffixed.
+            if '_KHR_' in extension_name:
+                safe_append(gl_extension_commands, command_name, extension_name)
+                safe_append(gles2_extension_commands, command_name, extension_name)
+            else:
+                safe_append(both_extension_commands, command_name, extension_name)
+        elif 'gl' in support:
+            safe_append(gl_extension_commands, command_name, extension_name)
+        elif 'gles2' in support:
+            safe_append(gles2_extension_commands, command_name, extension_name)
+
+gl_requirements = {}
+gles2_requirements = {}
+gl_extension_requirements = {}
+gles2_extension_requirements = {}
+both_extension_requirements = {}
+
+# Used later in the NULL bindings.
+all_entry_points = []
+
+for comment, entry_points in json_data.iteritems():
+    for entry_point_no_prefix in entry_points:
+        entry_point = "gl" + entry_point_no_prefix
+
+        all_entry_points.append(entry_point)
+
+        gl_required = None
+        gles2_required = None
+
+        if entry_point in api_feature_info:
+            for api, name, number in api_feature_info[entry_point]:
+                major, minor = number.split(".")
+                reqs = (major, minor)
+                if api == 'gl':
+                    if not gl_required:
+                        gl_required = reqs
+                    elif entry_point in core_removed_eps:
+                        print('Upgrade ' + entry_point + ' to ' + str(reqs) + ' instead of ' + str(gl_required))
+                        gl_required = reqs
+                    else:
+                        print('Keep ' + entry_point + ' at ' + str(gl_required) + ' instead of ' + str(reqs))
+                elif api == 'gles2':
+                    if not gles2_required:
+                        gles2_required = reqs
+                    else:
+                        print("Duplicate for " + entry_point + ": " + str(reqs) + " and " + str(gles2_required))
+                else:
+                    raise Exception('Bad api type: ' + api)
+
+        if gl_required:
+            safe_append(gl_requirements, gl_required, entry_point)
+
+        if gles2_required:
+            safe_append(gles2_requirements, gles2_required, entry_point)
+
+        # Special case for finding extensions that overlap with core functions.
+
+        extension = False
+
+        for ep in [entry_point, entry_point + "EXT", entry_point + "ARB", entry_point + "OES"]:
+            if ep in both_extension_commands:
+                extension = True
+                for extension in both_extension_commands[ep]:
+                    safe_append(both_extension_requirements, extension, (entry_point, ep))
+
+            else:
+                if ep in gl_extension_commands:
+                    extension = True
+                    for extension in gl_extension_commands[ep]:
+                        safe_append(gl_extension_requirements, extension, (entry_point, ep))
+
+                if ep in gles2_extension_commands:
+                    extension = True
+                    for extension in gles2_extension_commands[ep]:
+                        full_ep = ep
+                        if '_KHR_' in extension:
+                            full_ep += 'KHR'
+                        safe_append(gles2_extension_requirements, extension, (entry_point, full_ep))
+
+        if not (gl_required or gles2_required or extension):
+            raise Exception('Entry point ' + entry_point + ' not found in the xml.')
+
+# Template for the header declaration of the dispatch table.
+dispatch_table_header_template = """// GENERATED FILE - DO NOT EDIT.
+// Generated by {script_name} using data from {data_source_name} and gl.xml.
+//
+// Copyright {year} The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+// {file_name}:
+//   Defines the native binding interface for ANGLE's OpenGL back-end.
+
+#ifndef LIBGLESV2_RENDERER_GL_DISPATCH_TABLE_GL_AUTOGEN_H_
+#define LIBGLESV2_RENDERER_GL_DISPATCH_TABLE_GL_AUTOGEN_H_
+
+#include "common/angleutils.h"
+#include "libANGLE/renderer/gl/functionsgl_typedefs.h"
+
+#include <set>
+
+namespace gl
+{{
+struct Version;
+}}  // namespace gl
+
+namespace rx
+{{
+class DispatchTableGL : angle::NonCopyable
+{{
+  public:
+{table_data}
+
+  virtual ~DispatchTableGL() = default;
+
+  protected:
+    virtual void *loadProcAddress(const std::string &function) const = 0;
+
+    void initProcsDesktopGL(const gl::Version &version, const std::set<std::string> &extensions);
+    void initProcsGLES(const gl::Version &version, const std::set<std::string> &extensions);
+    void initProcsSharedExtensions(const std::set<std::string> &extensions);
+
+#if defined(ANGLE_ENABLE_OPENGL_NULL)
+    void initProcsDesktopGLNULL(const gl::Version &version, const std::set<std::string> &extensions);
+    void initProcsGLESNULL(const gl::Version &version, const std::set<std::string> &extensions);
+    void initProcsSharedExtensionsNULL(const std::set<std::string> &extensions);
+#endif  // defined(ANGLE_ENABLE_OPENGL_NULL)
+}};
+
+}}  // namespace rx
+
+#endif  // LIBGLESV2_RENDERER_GL_DISPATCH_TABLE_GL_AUTOGEN_H_
+"""
+
+def first_lower(str):
+    return str[:1].lower() + str[1:]
+
+def format_ep_decl(entry_point):
+    return "    PFNGL" + entry_point.upper() + "PROC " + first_lower(entry_point) + " = nullptr;"
+
+table_data = []
+for comment, entry_points in sorted(json_data.iteritems()):
+    formatted = ["    // " + comment]
+    formatted += [format_ep_decl(entry_point) for entry_point in sorted(entry_points)]
+
+    table_data.append("\n".join(formatted))
+
+dispatch_table_header = dispatch_table_header_template.format(
+    script_name = os.path.basename(sys.argv[0]),
+    data_source_name = data_source_name,
+    year = date.today().year,
+    file_name = dispatch_header_path,
+    table_data = "\n\n".join(table_data))
+
+with open(dispatch_header_path, "w") as out:
+    out.write(dispatch_table_header)
+
+# Template for the initialization file of the dispatch table.
+dispatch_table_source_template = """// GENERATED FILE - DO NOT EDIT.
+// Generated by {script_name} using data from {data_source_name} and gl.xml.
+//
+// Copyright {year} The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+// {file_name}:
+//   Initialize the native bindings for ANGLE's OpenGL back-end.
+
+#include "libANGLE/renderer/gl/DispatchTableGL_autogen.h"
+
+#include "libANGLE/Version.h"
+#include "libANGLE/renderer/gl/FunctionsGL.h"
+
+#if defined(ANGLE_ENABLE_OPENGL_NULL)
+#include "libANGLE/renderer/gl/null_functions.h"
+#endif  // defined(ANGLE_ENABLE_OPENGL_NULL)
+
+// Check for nullptr so extensions do not overwrite core imports.
+#define ASSIGN(NAME, FP) if (!FP) *reinterpret_cast<void **>(&FP) = loadProcAddress(NAME)
+
+namespace rx
+{{
+
+void DispatchTableGL::initProcsDesktopGL(const gl::Version &version, const std::set<std::string> &extensions)
+{{
+{gl_data}
+
+{gl_extensions_data}
+}}
+
+void DispatchTableGL::initProcsGLES(const gl::Version &version, const std::set<std::string> &extensions)
+{{
+{gles2_data}
+
+{gles2_extensions_data}
+}}
+
+void DispatchTableGL::initProcsSharedExtensions(const std::set<std::string> &extensions)
+{{
+{both_extensions_data}
+}}
+
+#if defined(ANGLE_ENABLE_OPENGL_NULL)
+void DispatchTableGL::initProcsDesktopGLNULL(const gl::Version &version, const std::set<std::string> &extensions)
+{{
+{gl_null_data}
+
+{gl_null_extensions_data}
+}}
+
+void DispatchTableGL::initProcsGLESNULL(const gl::Version &version, const std::set<std::string> &extensions)
+{{
+{gles2_null_data}
+
+{gles2_null_extensions_data}
+}}
+
+void DispatchTableGL::initProcsSharedExtensionsNULL(const std::set<std::string> &extensions)
+{{
+{both_null_extensions_data}
+}}
+#endif  // defined(ANGLE_ENABLE_OPENGL_NULL)
+
+}}  // namespace rx
+"""
+
+def format_assign_ep(entry_point, ep):
+    return '        ASSIGN("' + ep + '", ' + first_lower(entry_point[2:]) + ');'
+
+def format_requirements_lines(required, entry_points):
+    major, minor = required
+    lines = ['    if (version >= gl::Version(' + major + ', ' + minor + '))', '    {']
+    lines += [format_assign_ep(entry_point, entry_point) for entry_point in sorted(entry_points)]
+    lines += ['    }']
+    return '\n'.join(lines)
+
+def format_extension_requirements_lines(extension, entry_points, api):
+    lines = ['    if (extensions.count("' + extension + '") != 0)', '    {']
+    lines += [format_assign_ep(entry_point, ep) for entry_point, ep in sorted(entry_points)]
+    lines += ['    }']
+    return '\n'.join(lines)
+
+gl_data = []
+for gl_required, entry_points in sorted(gl_requirements.iteritems()):
+    gl_data.append(format_requirements_lines(gl_required, entry_points))
+
+gl_extensions_data = []
+for extension, entry_points in sorted(gl_extension_requirements.iteritems()):
+    gl_extensions_data.append(format_extension_requirements_lines(extension, entry_points, "gl"))
+
+gles2_data = []
+for gles2_required, entry_points in sorted(gles2_requirements.iteritems()):
+    gles2_data.append(format_requirements_lines(gles2_required, entry_points))
+
+gles2_extensions_data = []
+for extension, entry_points in sorted(gles2_extension_requirements.iteritems()):
+    gles2_extensions_data.append(format_extension_requirements_lines(extension, entry_points, "gles2"))
+
+both_extensions_data = []
+for extension, entry_points in sorted(both_extension_requirements.iteritems()):
+    both_extensions_data.append(format_extension_requirements_lines(extension, entry_points, "gles2|gl"))
+
+def assign_null_line(line):
+    m = re.match(r'        ASSIGN\("gl.*", (.+)\);', line)
+    if m:
+        name = m.group(1)
+        return '        ' + name + ' = &gl' + name[0].upper() + name[1:] + 'NULL;'
+    else:
+        return line
+
+def assign_null(entry):
+    return '\n'.join([assign_null_line(line) for line in entry.split('\n')])
+
+def nullify(data):
+    return [assign_null(entry) for entry in data]
+
+dispatch_table_source = dispatch_table_source_template.format(
+    script_name = os.path.basename(sys.argv[0]),
+    data_source_name = data_source_name,
+    year = date.today().year,
+    file_name = dispatch_source_path,
+    gl_data = "\n\n".join(gl_data),
+    gl_extensions_data = "\n\n".join(gl_extensions_data),
+    gles2_data = "\n\n".join(gles2_data),
+    gles2_extensions_data = "\n\n".join(gles2_extensions_data),
+    both_extensions_data = "\n\n".join(both_extensions_data),
+    gl_null_data = "\n\n".join(nullify(gl_data)),
+    gl_null_extensions_data = "\n\n".join(nullify(gl_extensions_data)),
+    gles2_null_data = "\n\n".join(nullify(gles2_data)),
+    gles2_null_extensions_data = "\n\n".join(nullify(gles2_extensions_data)),
+    both_null_extensions_data = "\n\n".join(nullify(both_extensions_data)))
+
+with open(dispatch_source_path, "w") as out:
+    out.write(dispatch_table_source)
+
+# Generate the NULL/stub entry points.
+# Process the whole set of commands
+
+def format_param(param):
+    return "".join(param.itertext())
+
+command_defs = {}
+command_decls = {}
+
+for command in xml_root.findall('commands/command'):
+    proto = command.find('proto')
+    command_name = proto.find('name').text
+    entry = ''.join(proto.itertext())
+    return_type = entry[:-len(command_name)]
+    entry = return_type + ' INTERNAL_GL_APIENTRY ' + entry[len(return_type):] + 'NULL('
+
+    param_text = [format_param(param) for param in command.findall('param')]
+    entry += ', '.join(param_text) + ')'
+
+    command_decls[command_name] = entry + ';'
+
+    entry += '\n{\n'
+    if return_type != 'void ':
+        entry += '    return static_cast<' + return_type + '>(0);\n'
+    entry += '}'
+
+    command_defs[command_name] = entry
+
+null_decls = [command_decls[entry_point] for entry_point in sorted(all_entry_points)]
+null_stubs = [command_defs[entry_point] for entry_point in sorted(all_entry_points)]
+
+null_functions_header_template = """// GENERATED FILE - DO NOT EDIT.
+// Generated by {script_name} using data from {data_source_name} and gl.xml.
+//
+// Copyright {year} The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+// {file_name}:
+//   Declares the NULL/Stub bindings for the OpenGL back-end.
+
+#ifndef LIBGLESV2_RENDERER_GL_NULL_GL_FUNCTIONS_AUTOGEN_H_
+#define LIBGLESV2_RENDERER_GL_NULL_GL_FUNCTIONS_AUTOGEN_H_
+
+#include "libANGLE/renderer/gl/functionsgl_typedefs.h"
+
+namespace rx
+{{
+{table_data}
+}}  // namespace rx
+
+#endif  // LIBGLESV2_RENDERER_GL_NULL_GL_FUNCTIONS_AUTOGEN_H_
+"""
+
+null_functions_header = null_functions_header_template.format(
+    script_name = os.path.basename(sys.argv[0]),
+    data_source_name = data_source_name,
+    year = date.today().year,
+    file_name = null_functions_header_path,
+    table_data = "\n".join(null_decls))
+
+with open(null_functions_header_path, "w") as out:
+    out.write(null_functions_header)
+
+null_functions_source_template = """// GENERATED FILE - DO NOT EDIT.
+// Generated by {script_name} using data from {data_source_name} and gl.xml.
+//
+// Copyright {year} The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+// {file_name}:
+//   Defines the NULL/Stub bindings for the OpenGL back-end.
+
+#include "libANGLE/renderer/gl/null_functions.h"
+
+namespace rx
+{{
+{table_data}
+}}  // namespace rx
+"""
+
+null_functions_source = null_functions_source_template.format(
+    script_name = os.path.basename(sys.argv[0]),
+    data_source_name = data_source_name,
+    year = date.today().year,
+    file_name = null_functions_source_path,
+    table_data = "\n\n".join(null_stubs))
+
+with open(null_functions_source_path, "w") as out:
+    out.write(null_functions_source)
new file mode 100644
--- /dev/null
+++ b/gfx/angle/src/libANGLE/renderer/gl/gl_bindings_data.json
@@ -0,0 +1,794 @@
+{
+    "1.0":
+    [
+        "BlendFunc",
+        "Clear",
+        "ClearColor",
+        "ClearDepth",
+        "ClearStencil",
+        "ColorMask",
+        "CullFace",
+        "DepthFunc",
+        "DepthMask",
+        "DepthRange",
+        "Disable",
+        "DrawBuffer",
+        "Enable",
+        "Finish",
+        "Flush",
+        "FrontFace",
+        "GetBooleanv",
+        "GetDoublev",
+        "GetError",
+        "GetFloatv",
+        "GetIntegerv",
+        "GetString",
+        "GetTexImage",
+        "GetTexLevelParameterfv",
+        "GetTexLevelParameteriv",
+        "GetTexParameterfv",
+        "GetTexParameteriv",
+        "Hint",
+        "IsEnabled",
+        "LineWidth",
+        "LogicOp",
+        "PixelStoref",
+        "PixelStorei",
+        "PointSize",
+        "PolygonMode",
+        "ReadBuffer",
+        "ReadPixels",
+        "Scissor",
+        "StencilFunc",
+        "StencilMask",
+        "StencilOp",
+        "TexImage1D",
+        "TexImage2D",
+        "TexParameterf",
+        "TexParameterfv",
+        "TexParameteri",
+        "TexParameteriv",
+        "Viewport"
+    ],
+
+    "1.1":
+    [
+        "BindTexture",
+        "CopyTexImage1D",
+        "CopyTexImage2D",
+        "CopyTexSubImage1D",
+        "CopyTexSubImage2D",
+        "DeleteTextures",
+        "DrawArrays",
+        "DrawElements",
+        "GenTextures",
+        "IsTexture",
+        "PolygonOffset",
+        "TexSubImage1D",
+        "TexSubImage2D"
+    ],
+
+    "1.2":
+    [
+        "BlendColor",
+        "BlendEquation",
+        "CopyTexSubImage3D",
+        "DrawRangeElements",
+        "TexImage3D",
+        "TexSubImage3D"
+    ],
+
+    "1.2 Extensions":
+    [
+        "DeleteFencesNV",
+        "GenFencesNV",
+        "IsFenceNV",
+        "TestFenceNV",
+        "GetFenceivNV",
+        "FinishFenceNV",
+        "SetFenceNV"
+    ],
+
+    "1.3":
+    [
+        "ActiveTexture",
+        "CompressedTexImage1D",
+        "CompressedTexImage2D",
+        "CompressedTexImage3D",
+        "CompressedTexSubImage1D",
+        "CompressedTexSubImage2D",
+        "CompressedTexSubImage3D",
+        "GetCompressedTexImage",
+        "SampleCoverage"
+    ],
+
+    "1.4":
+    [
+        "BlendFuncSeparate",
+        "MultiDrawArrays",
+        "MultiDrawElements",
+        "PointParameterf",
+        "PointParameterfv",
+        "PointParameteri",
+        "PointParameteriv"
+    ],
+
+    "1.5":
+    [
+        "BeginQuery",
+        "BindBuffer",
+        "BufferData",
+        "BufferSubData",
+        "DeleteBuffers",
+        "DeleteQueries",
+        "EndQuery",
+        "GenBuffers",
+        "GenQueries",
+        "GetBufferParameteriv",
+        "GetBufferPointerv",
+        "GetBufferSubData",
+        "GetQueryObjectiv",
+        "GetQueryObjectuiv",
+        "GetQueryiv",
+        "IsBuffer",
+        "IsQuery",
+        "MapBuffer",
+        "UnmapBuffer"
+    ],
+
+    "2.0":
+    [
+        "AttachShader",
+        "BindAttribLocation",
+        "BlendEquationSeparate",
+        "CompileShader",
+        "CreateProgram",
+        "CreateShader",
+        "DeleteProgram",
+        "DeleteShader",
+        "DetachShader",
+        "DisableVertexAttribArray",
+        "DrawBuffers",
+        "EnableVertexAttribArray",
+        "GetActiveAttrib",
+        "GetActiveUniform",
+        "GetAttachedShaders",
+        "GetAttribLocation",
+        "GetProgramInfoLog",
+        "GetProgramiv",
+        "GetShaderInfoLog",
+        "GetShaderSource",
+        "GetShaderiv",
+        "GetUniformLocation",
+        "GetUniformfv",
+        "GetUniformiv",
+        "GetVertexAttribPointerv",
+        "GetVertexAttribdv",
+        "GetVertexAttribfv",
+        "GetVertexAttribiv",
+        "IsProgram",
+        "IsShader",
+        "LinkProgram",
+        "ShaderSource",
+        "StencilFuncSeparate",
+        "StencilMaskSeparate",
+        "StencilOpSeparate",
+        "Uniform1f",
+        "Uniform1fv",
+        "Uniform1i",
+        "Uniform1iv",
+        "Uniform2f",
+        "Uniform2fv",
+        "Uniform2i",
+        "Uniform2iv",
+        "Uniform3f",
+        "Uniform3fv",
+        "Uniform3i",
+        "Uniform3iv",
+        "Uniform4f",
+        "Uniform4fv",
+        "Uniform4i",
+        "Uniform4iv",
+        "UniformMatrix2fv",
+        "UniformMatrix3fv",
+        "UniformMatrix4fv",
+        "UseProgram",
+        "ValidateProgram",
+        "VertexAttrib1d",
+        "VertexAttrib1dv",
+        "VertexAttrib1f",
+        "VertexAttrib1fv",
+        "VertexAttrib1s",
+        "VertexAttrib1sv",
+        "VertexAttrib2d",
+        "VertexAttrib2dv",
+        "VertexAttrib2f",
+        "VertexAttrib2fv",
+        "VertexAttrib2s",
+        "VertexAttrib2sv",
+        "VertexAttrib3d",
+        "VertexAttrib3dv",
+        "VertexAttrib3f",
+        "VertexAttrib3fv",
+        "VertexAttrib3s",
+        "VertexAttrib3sv",
+        "VertexAttrib4Nbv",
+        "VertexAttrib4Niv",
+        "VertexAttrib4Nsv",
+        "VertexAttrib4Nub",
+        "VertexAttrib4Nubv",
+        "VertexAttrib4Nuiv",
+        "VertexAttrib4Nusv",
+        "VertexAttrib4bv",
+        "VertexAttrib4d",
+        "VertexAttrib4dv",
+        "VertexAttrib4f",
+        "VertexAttrib4fv",
+        "VertexAttrib4iv",
+        "VertexAttrib4s",
+        "VertexAttrib4sv",
+        "VertexAttrib4ubv",
+        "VertexAttrib4uiv",
+        "VertexAttrib4usv",
+        "VertexAttribPointer"
+    ],
+
+    "2.1":
+    [
+        "UniformMatrix2x3fv",
+        "UniformMatrix2x4fv",
+        "UniformMatrix3x2fv",
+        "UniformMatrix3x4fv",
+        "UniformMatrix4x2fv",
+        "UniformMatrix4x3fv"
+    ],
+
+    "3.0":
+    [
+        "BeginConditionalRender",
+        "BeginTransformFeedback",
+        "BindBufferBase",
+        "BindBufferRange",
+        "BindFragDataLocation",
+        "BindFramebuffer",
+        "BindRenderbuffer",
+        "BindVertexArray",
+        "BlitFramebuffer",
+        "CheckFramebufferStatus",
+        "ClampColor",
+        "ClearBufferfi",
+        "ClearBufferfv",
+        "ClearBufferiv",
+        "ClearBufferuiv",
+        "ColorMaski",
+        "DeleteFramebuffers",
+        "DeleteRenderbuffers",
+        "DeleteVertexArrays",
+        "Disablei",
+        "Enablei",
+        "EndConditionalRender",
+        "EndTransformFeedback",
+        "FlushMappedBufferRange",
+        "FramebufferRenderbuffer",
+        "FramebufferTexture1D",
+        "FramebufferTexture2D",
+        "FramebufferTexture3D",
+        "FramebufferTextureLayer",
+        "GenFramebuffers",
+        "GenRenderbuffers",
+        "GenVertexArrays",
+        "GenerateMipmap",
+        "GetBooleani_v",
+        "GetFragDataLocation",
+        "GetFramebufferAttachmentParameteriv",
+        "GetIntegeri_v",
+        "GetRenderbufferParameteriv",
+        "GetStringi",
+        "GetTexParameterIiv",
+        "GetTexParameterIuiv",
+        "GetTransformFeedbackVarying",
+        "GetUniformuiv",
+        "GetVertexAttribIiv",
+        "GetVertexAttribIuiv",
+        "IsEnabledi",
+        "IsFramebuffer",
+        "IsRenderbuffer",
+        "IsVertexArray",
+        "MapBufferRange",
+        "RenderbufferStorage",
+        "RenderbufferStorageMultisample",
+        "TexParameterIiv",
+        "TexParameterIuiv",
+        "TransformFeedbackVaryings",
+        "Uniform1ui",
+        "Uniform1uiv",
+        "Uniform2ui",
+        "Uniform2uiv",
+        "Uniform3ui",
+        "Uniform3uiv",
+        "Uniform4ui",
+        "Uniform4uiv",
+        "VertexAttribI1i",
+        "VertexAttribI1iv",
+        "VertexAttribI1ui",
+        "VertexAttribI1uiv",
+        "VertexAttribI2i",
+        "VertexAttribI2iv",
+        "VertexAttribI2ui",
+        "VertexAttribI2uiv",
+        "VertexAttribI3i",
+        "VertexAttribI3iv",
+        "VertexAttribI3ui",
+        "VertexAttribI3uiv",
+        "VertexAttribI4bv",
+        "VertexAttribI4i",
+        "VertexAttribI4iv",
+        "VertexAttribI4sv",
+        "VertexAttribI4ubv",
+        "VertexAttribI4ui",
+        "VertexAttribI4uiv",
+        "VertexAttribI4usv",
+        "VertexAttribIPointer"
+    ],
+
+    "3.1":
+    [
+        "CopyBufferSubData",
+        "DrawArraysInstanced",
+        "DrawElementsInstanced",
+        "GetActiveUniformBlockName",
+        "GetActiveUniformBlockiv",
+        "GetActiveUniformName",
+        "GetActiveUniformsiv",
+        "GetUniformBlockIndex",
+        "GetUniformIndices",
+        "PrimitiveRestartIndex",
+        "TexBuffer",
+        "UniformBlockBinding"
+    ],
+
+    "3.2":
+    [
+        "ClientWaitSync",
+        "DeleteSync",
+        "DrawElementsBaseVertex",
+        "DrawElementsInstancedBaseVertex",
+        "DrawRangeElementsBaseVertex",
+        "FenceSync",
+        "FramebufferTexture",
+        "GetBufferParameteri64v",
+        "GetInteger64i_v",
+        "GetInteger64v",
+        "GetMultisamplefv",
+        "GetSynciv",
+        "IsSync",
+        "MultiDrawElementsBaseVertex",
+        "ProvokingVertex",
+        "SampleMaski",
+        "TexImage2DMultisample",
+        "TexImage3DMultisample",
+        "WaitSync"
+    ],
+
+    "NV_path_rendering (originally written against 3.2 compatibility profile)":
+    [
+        "MatrixLoadfEXT",
+        "GenPathsNV",
+        "DeletePathsNV",
+        "PathCommandsNV",
+        "IsPathNV",
+        "PathParameterfNV",
+        "PathParameteriNV",
+        "GetPathParameterfvNV",
+        "GetPathParameterivNV",
+        "PathStencilFuncNV",
+        "StencilFillPathNV",
+        "StencilStrokePathNV",
+        "CoverFillPathNV",
+        "CoverStrokePathNV",
+        "StencilThenCoverFillPathNV",
+        "StencilThenCoverStrokePathNV",
+        "CoverFillPathInstancedNV",
+        "CoverStrokePathInstancedNV",
+        "StencilFillPathInstancedNV",
+        "StencilStrokePathInstancedNV",
+        "StencilThenCoverFillPathInstancedNV",
+        "StencilThenCoverStrokePathInstancedNV",
+        "ProgramPathFragmentInputGenNV"
+    ],
+
+    "3.3":
+    [
+        "BindFragDataLocationIndexed",
+        "BindSampler",
+        "DeleteSamplers",
+        "GenSamplers",
+        "GetFragDataIndex",
+        "GetQueryObjecti64v",
+        "GetQueryObjectui64v",
+        "GetSamplerParameterIiv",
+        "GetSamplerParameterIuiv",
+        "GetSamplerParameterfv",
+        "GetSamplerParameteriv",
+        "IsSampler",
+        "QueryCounter",
+        "SamplerParameterIiv",
+        "SamplerParameterIuiv",
+        "SamplerParameterf",
+        "SamplerParameterfv",
+        "SamplerParameteri",
+        "SamplerParameteriv",
+        "VertexAttribDivisor",
+        "VertexAttribP1ui",
+        "VertexAttribP1uiv",
+        "VertexAttribP2ui",
+        "VertexAttribP2uiv",
+        "VertexAttribP3ui",
+        "VertexAttribP3uiv",
+        "VertexAttribP4ui",
+        "VertexAttribP4uiv"
+    ],
+
+    "4.0":
+    [
+        "BeginQueryIndexed",
+        "BindTransformFeedback",
+        "BlendEquationSeparatei",
+        "BlendEquationi",
+        "BlendFuncSeparatei",
+        "BlendFunci",
+        "DeleteTransformFeedbacks",
+        "DrawArraysIndirect",
+        "DrawElementsIndirect",
+        "DrawTransformFeedback",
+        "DrawTransformFeedbackStream",
+        "EndQueryIndexed",
+        "GenTransformFeedbacks",
+        "GetActiveSubroutineName",
+        "GetActiveSubroutineUniformName",
+        "GetActiveSubroutineUniformiv",
+        "GetProgramStageiv",
+        "GetQueryIndexediv",
+        "GetSubroutineIndex",
+        "GetSubroutineUniformLocation",
+        "GetUniformSubroutineuiv",
+        "GetUniformdv",
+        "IsTransformFeedback",
+        "MinSampleShading",
+        "PatchParameterfv",
+        "PatchParameteri",
+        "PauseTransformFeedback",
+        "ResumeTransformFeedback",
+        "Uniform1d",
+        "Uniform1dv",
+        "Uniform2d",
+        "Uniform2dv",
+        "Uniform3d",
+        "Uniform3dv",
+        "Uniform4d",
+        "Uniform4dv",
+        "UniformMatrix2dv",
+        "UniformMatrix2x3dv",
+        "UniformMatrix2x4dv",
+        "UniformMatrix3dv",
+        "UniformMatrix3x2dv",
+        "UniformMatrix3x4dv",
+        "UniformMatrix4dv",
+        "UniformMatrix4x2dv",
+        "UniformMatrix4x3dv",
+        "UniformSubroutinesuiv"
+    ],
+
+    "4.1":
+    [
+        "ActiveShaderProgram",
+        "BindProgramPipeline",
+        "ClearDepthf",
+        "CreateShaderProgramv",
+        "DeleteProgramPipelines",
+        "DepthRangeArrayv",
+        "DepthRangeIndexed",
+        "DepthRangef",
+        "GenProgramPipelines",
+        "GetDoublei_v",
+        "GetFloati_v",
+        "GetProgramBinary",
+        "GetProgramPipelineInfoLog",
+        "GetProgramPipelineiv",
+        "GetShaderPrecisionFormat",
+        "GetVertexAttribLdv",
+        "IsProgramPipeline",
+        "ProgramBinary",
+        "ProgramParameteri",
+        "ProgramUniform1d",
+        "ProgramUniform1dv",
+        "ProgramUniform1f",
+        "ProgramUniform1fv",
+        "ProgramUniform1i",
+        "ProgramUniform1iv",
+        "ProgramUniform1ui",
+        "ProgramUniform1uiv",
+        "ProgramUniform2d",
+        "ProgramUniform2dv",
+        "ProgramUniform2f",
+        "ProgramUniform2fv",
+        "ProgramUniform2i",
+        "ProgramUniform2iv",
+        "ProgramUniform2ui",
+        "ProgramUniform2uiv",
+        "ProgramUniform3d",
+        "ProgramUniform3dv",
+        "ProgramUniform3f",
+        "ProgramUniform3fv",
+        "ProgramUniform3i",
+        "ProgramUniform3iv",
+        "ProgramUniform3ui",
+        "ProgramUniform3uiv",
+        "ProgramUniform4d",
+        "ProgramUniform4dv",
+        "ProgramUniform4f",
+        "ProgramUniform4fv",
+        "ProgramUniform4i",
+        "ProgramUniform4iv",
+        "ProgramUniform4ui",
+        "ProgramUniform4uiv",
+        "ProgramUniformMatrix2dv",
+        "ProgramUniformMatrix2fv",
+        "ProgramUniformMatrix2x3dv",
+        "ProgramUniformMatrix2x3fv",
+        "ProgramUniformMatrix2x4dv",
+        "ProgramUniformMatrix2x4fv",
+        "ProgramUniformMatrix3dv",
+        "ProgramUniformMatrix3fv",
+        "ProgramUniformMatrix3x2dv",
+        "ProgramUniformMatrix3x2fv",
+        "ProgramUniformMatrix3x4dv",
+        "ProgramUniformMatrix3x4fv",
+        "ProgramUniformMatrix4dv",
+        "ProgramUniformMatrix4fv",
+        "ProgramUniformMatrix4x2dv",
+        "ProgramUniformMatrix4x2fv",
+        "ProgramUniformMatrix4x3dv",
+        "ProgramUniformMatrix4x3fv",
+        "ReleaseShaderCompiler",
+        "ScissorArrayv",
+        "ScissorIndexed",
+        "ScissorIndexedv",
+        "ShaderBinary",
+        "UseProgramStages",
+        "ValidateProgramPipeline",
+        "VertexAttribL1d",
+        "VertexAttribL1dv",
+        "VertexAttribL2d",
+        "VertexAttribL2dv",
+        "VertexAttribL3d",
+        "VertexAttribL3dv",
+        "VertexAttribL4d",
+        "VertexAttribL4dv",
+        "VertexAttribLPointer",
+        "ViewportArrayv",
+        "ViewportIndexedf",
+        "ViewportIndexedfv"
+    ],
+
+    "4.2":
+    [
+        "BindImageTexture",
+        "DrawArraysInstancedBaseInstance",
+        "DrawElementsInstancedBaseInstance",
+        "DrawElementsInstancedBaseVertexBaseInstance",
+        "DrawTransformFeedbackInstanced",
+        "DrawTransformFeedbackStreamInstanced",
+        "GetActiveAtomicCounterBufferiv",
+        "GetInternalformativ",
+        "MemoryBarrier",
+        "TexStorage1D",
+        "TexStorage2D",
+        "TexStorage3D"
+    ],
+
+    "4.3":
+    [
+        "BindVertexBuffer",
+        "ClearBufferData",
+        "ClearBufferSubData",
+        "CopyImageSubData",
+        "DebugMessageCallback",
+        "DebugMessageControl",
+        "DebugMessageInsert",
+        "DispatchCompute",
+        "DispatchComputeIndirect",
+        "FramebufferParameteri",
+        "GetDebugMessageLog",
+        "GetFramebufferParameteriv",
+        "GetInternalformati64v",
+        "GetPointerv",
+        "GetObjectLabel",
+        "GetObjectPtrLabel",
+        "GetProgramInterfaceiv",
+        "GetProgramResourceIndex",
+        "GetProgramResourceLocation",
+        "GetProgramResourceLocationIndex",
+        "GetProgramResourceName",
+        "GetProgramResourceiv",
+        "InvalidateBufferData",
+        "InvalidateBufferSubData",
+        "InvalidateFramebuffer",
+        "InvalidateSubFramebuffer",
+        "InvalidateTexImage",
+        "InvalidateTexSubImage",
+        "MultiDrawArraysIndirect",
+        "MultiDrawElementsIndirect",
+        "ObjectLabel",
+        "ObjectPtrLabel",
+        "PopDebugGroup",
+        "PushDebugGroup",
+        "ShaderStorageBlockBinding",
+        "TexBufferRange",
+        "TexStorage2DMultisample",
+        "TexStorage3DMultisample",
+        "TextureView",
+        "VertexAttribBinding",
+        "VertexAttribFormat",
+        "VertexAttribIFormat",
+        "VertexAttribLFormat",
+        "VertexBindingDivisor",
+        "CoverageModulationNV"
+    ],
+
+    "4.4":
+    [
+        "BindBuffersBase",
+        "BindBuffersRange",
+        "BindImageTextures",
+        "BindSamplers",
+        "BindTextures",
+        "BindVertexBuffers",
+        "BufferStorage",
+        "ClearTexImage",
+        "ClearTexSubImage"
+    ],
+
+    "4.5":
+    [
+        "BindTextureUnit",
+        "BlitNamedFramebuffer",
+        "CheckNamedFramebufferStatus",
+        "ClearNamedBufferData",
+        "ClearNamedBufferSubData",
+        "ClearNamedFramebufferfi",
+        "ClearNamedFramebufferfv",
+        "ClearNamedFramebufferiv",
+        "ClearNamedFramebufferuiv",
+        "ClipControl",
+        "CompressedTextureSubImage1D",
+        "CompressedTextureSubImage2D",
+        "CompressedTextureSubImage3D",
+        "CopyNamedBufferSubData",
+        "CopyTextureSubImage1D",
+        "CopyTextureSubImage2D",
+        "CopyTextureSubImage3D",
+        "CreateBuffers",
+        "CreateFramebuffers",
+        "CreateProgramPipelines",
+        "CreateQueries",
+        "CreateRenderbuffers",
+        "CreateSamplers",
+        "CreateTextures",
+        "CreateTransformFeedbacks",
+        "CreateVertexArrays",
+        "DisableVertexArrayAttrib",
+        "EnableVertexArrayAttrib",
+        "FlushMappedNamedBufferRange",
+        "GenerateTextureMipmap",
+        "GetCompressedTextureImage",
+        "GetCompressedTextureSubImage",
+        "GetGraphicsResetStatus",
+        "GetNamedBufferParameteri64v",
+        "GetNamedBufferParameteriv",
+        "GetNamedBufferPointerv",
+        "GetNamedBufferSubData",
+        "GetNamedFramebufferAttachmentParameteriv",
+        "GetNamedFramebufferParameteriv",
+        "GetNamedRenderbufferParameteriv",
+        "GetQueryBufferObjecti64v",
+        "GetQueryBufferObjectiv",
+        "GetQueryBufferObjectui64v",
+        "GetQueryBufferObjectuiv",
+        "GetTextureImage",
+        "GetTextureLevelParameterfv",
+        "GetTextureLevelParameteriv",
+        "GetTextureParameterIiv",
+        "GetTextureParameterIuiv",
+        "GetTextureParameterfv",
+        "GetTextureParameteriv",
+        "GetTextureSubImage",
+        "GetTransformFeedbacki64_v",
+        "GetTransformFeedbacki_v",
+        "GetTransformFeedbackiv",
+        "GetVertexArrayIndexed64iv",
+        "GetVertexArrayIndexediv",
+        "GetVertexArrayiv",
+        "GetnCompressedTexImage",
+        "GetnTexImage",
+        "GetnUniformdv",
+        "GetnUniformfv",
+        "GetnUniformiv",
+        "GetnUniformuiv",
+        "InvalidateNamedFramebufferData",
+        "InvalidateNamedFramebufferSubData",
+        "MapNamedBuffer",
+        "MapNamedBufferRange",
+        "MemoryBarrierByRegion",
+        "NamedBufferData",
+        "NamedBufferStorage",
+        "NamedBufferSubData",
+        "NamedFramebufferDrawBuffer",
+        "NamedFramebufferDrawBuffers",
+        "NamedFramebufferParameteri",
+        "NamedFramebufferReadBuffer",
+        "NamedFramebufferRenderbuffer",
+        "NamedFramebufferTexture",
+        "NamedFramebufferTextureLayer",
+        "NamedRenderbufferStorage",
+        "NamedRenderbufferStorageMultisample",
+        "ReadnPixels",
+        "TextureBarrier",
+        "TextureBuffer",
+        "TextureBufferRange",
+        "TextureParameterIiv",
+        "TextureParameterIuiv",
+        "TextureParameterf",
+        "TextureParameterfv",
+        "TextureParameteri",
+        "TextureParameteriv",
+        "TextureStorage1D",
+        "TextureStorage2D",
+        "TextureStorage2DMultisample",
+        "TextureStorage3D",
+        "TextureStorage3DMultisample",
+        "TextureSubImage1D",
+        "TextureSubImage2D",
+        "TextureSubImage3D",
+        "TransformFeedbackBufferBase",
+        "TransformFeedbackBufferRange",
+        "UnmapNamedBuffer",
+        "VertexArrayAttribBinding",
+        "VertexArrayAttribFormat",
+        "VertexArrayAttribIFormat",
+        "VertexArrayAttribLFormat",
+        "VertexArrayBindingDivisor",
+        "VertexArrayElementBuffer",
+        "VertexArrayVertexBuffer",
+        "VertexArrayVertexBuffers"
+    ],
+
+    "ES 3.2":
+    [
+        "BlendBarrier",
+        "PrimitiveBoundingBox"
+    ],
+
+    "GL_OES_EGL_image":
+    [
+        "EGLImageTargetRenderbufferStorageOES",
+        "EGLImageTargetTexture2DOES"
+    ],
+
+    "GL_EXT_discard_framebuffer":
+    [
+        "DiscardFramebufferEXT"
+    ],
+
+    "GL_NV_internalformat_sample_query":
+    [
+        "GetInternalformatSampleivNV"
+    ],
+
+    "GL_EXT_debug_marker":
+    [
+        "InsertEventMarkerEXT",
+        "PushGroupMarkerEXT",
+        "PopGroupMarkerEXT"
+    ]
+}
--- a/gfx/angle/src/libANGLE/renderer/gl/glx/DisplayGLX.cpp
+++ b/gfx/angle/src/libANGLE/renderer/gl/glx/DisplayGLX.cpp
@@ -44,17 +44,17 @@ class FunctionsGLGLX : public FunctionsG
     FunctionsGLGLX(PFNGETPROCPROC getProc)
       : mGetProc(getProc)
     {
     }
 
     ~FunctionsGLGLX() override {}
 
   private:
-    void *loadProcAddress(const std::string &function) override
+    void *loadProcAddress(const std::string &function) const override
     {
         return reinterpret_cast<void*>(mGetProc(function.c_str()));
     }
 
     PFNGETPROCPROC mGetProc;
 };
 
 DisplayGLX::DisplayGLX(const egl::DisplayState &state)
@@ -287,17 +287,17 @@ egl::Error DisplayGLX::initialize(egl::D
     }
 
     if (!mGLX.makeCurrent(mDummyPbuffer, mContext))
     {
         return egl::EglNotInitialized() << "Could not make the dummy pbuffer current.";
     }
 
     mFunctionsGL = new FunctionsGLGLX(mGLX.getProc);
-    mFunctionsGL->initialize();
+    mFunctionsGL->initialize(eglAttributes);
 
     // TODO(cwallez, angleproject:1303) Disable the OpenGL ES backend on Linux NVIDIA and Intel as
     // it has problems on our automated testing. An OpenGL ES backend might not trigger this test if
     // there is no Desktop OpenGL support, but that's not the case in our automated testing.
     VendorID vendor = GetVendorID(mFunctionsGL);
     bool isOpenGLES =
         eglAttributes.get(EGL_PLATFORM_ANGLE_TYPE_ANGLE, EGL_PLATFORM_ANGLE_TYPE_DEFAULT_ANGLE) ==
         EGL_PLATFORM_ANGLE_TYPE_OPENGLES_ANGLE;
@@ -786,16 +786,18 @@ const FunctionsGL *DisplayGLX::getFuncti
 void DisplayGLX::generateExtensions(egl::DisplayExtensions *outExtensions) const
 {
     outExtensions->createContextRobustness = mHasARBCreateContextRobustness;
 
     // Contexts are virtualized so textures can be shared globally
     outExtensions->displayTextureShareGroup = true;
 
     outExtensions->surfacelessContext = true;
+
+    DisplayGL::generateExtensions(outExtensions);
 }
 
 void DisplayGLX::generateCaps(egl::Caps *outCaps) const
 {
     outCaps->textureNPOT = true;
 }
 
 egl::Error DisplayGLX::makeCurrentSurfaceless(gl::Context *context)
new file mode 100644
--- /dev/null
+++ b/gfx/angle/src/libANGLE/renderer/gl/null_functions.cpp
@@ -0,0 +1,4068 @@
+// GENERATED FILE - DO NOT EDIT.
+// Generated by generate_gl_dispatch_table.py using data from gl_bindings_data.json and gl.xml.
+//
+// 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.
+//
+// null_functions.cpp:
+//   Defines the NULL/Stub bindings for the OpenGL back-end.
+
+#include "libANGLE/renderer/gl/null_functions.h"
+
+namespace rx
+{
+void INTERNAL_GL_APIENTRY glActiveShaderProgramNULL(GLuint pipeline, GLuint program)
+{
+}
+
+void INTERNAL_GL_APIENTRY glActiveTextureNULL(GLenum texture)
+{
+}
+
+void INTERNAL_GL_APIENTRY glAttachShaderNULL(GLuint program, GLuint shader)
+{
+}
+
+void INTERNAL_GL_APIENTRY glBeginConditionalRenderNULL(GLuint id, GLenum mode)
+{
+}
+
+void INTERNAL_GL_APIENTRY glBeginQueryNULL(GLenum target, GLuint id)
+{
+}
+
+void INTERNAL_GL_APIENTRY glBeginQueryIndexedNULL(GLenum target, GLuint index, GLuint id)
+{
+}
+
+void INTERNAL_GL_APIENTRY glBeginTransformFeedbackNULL(GLenum primitiveMode)
+{
+}
+
+void INTERNAL_GL_APIENTRY glBindAttribLocationNULL(GLuint program, GLuint index, const GLchar *name)
+{
+}
+
+void INTERNAL_GL_APIENTRY glBindBufferNULL(GLenum target, GLuint buffer)
+{
+}
+
+void INTERNAL_GL_APIENTRY glBindBufferBaseNULL(GLenum target, GLuint index, GLuint buffer)
+{
+}
+
+void INTERNAL_GL_APIENTRY
+glBindBufferRangeNULL(GLenum target, GLuint index, GLuint buffer, GLintptr offset, GLsizeiptr size)
+{
+}
+
+void INTERNAL_GL_APIENTRY glBindBuffersBaseNULL(GLenum target,
+                                                GLuint first,
+                                                GLsizei count,
+                                                const GLuint *buffers)
+{
+}
+
+void INTERNAL_GL_APIENTRY glBindBuffersRangeNULL(GLenum target,
+                                                 GLuint first,
+                                                 GLsizei count,
+                                                 const GLuint *buffers,
+                                                 const GLintptr *offsets,
+                                                 const GLsizeiptr *sizes)
+{
+}
+
+void INTERNAL_GL_APIENTRY glBindFragDataLocationNULL(GLuint program,
+                                                     GLuint color,
+                                                     const GLchar *name)
+{
+}
+
+void INTERNAL_GL_APIENTRY glBindFragDataLocationIndexedNULL(GLuint program,
+                                                            GLuint colorNumber,
+                                                            GLuint index,
+                                                            const GLchar *name)
+{
+}
+
+void INTERNAL_GL_APIENTRY glBindFramebufferNULL(GLenum target, GLuint framebuffer)
+{
+}
+
+void INTERNAL_GL_APIENTRY glBindImageTextureNULL(GLuint unit,
+                                                 GLuint texture,
+                                                 GLint level,
+                                                 GLboolean layered,
+                                                 GLint layer,
+                                                 GLenum access,
+                                                 GLenum format)
+{
+}
+
+void INTERNAL_GL_APIENTRY glBindImageTexturesNULL(GLuint first,
+                                                  GLsizei count,
+                                                  const GLuint *textures)
+{
+}
+
+void INTERNAL_GL_APIENTRY glBindProgramPipelineNULL(GLuint pipeline)
+{
+}
+
+void INTERNAL_GL_APIENTRY glBindRenderbufferNULL(GLenum target, GLuint renderbuffer)
+{
+}
+
+void INTERNAL_GL_APIENTRY glBindSamplerNULL(GLuint unit, GLuint sampler)
+{
+}
+
+void INTERNAL_GL_APIENTRY glBindSamplersNULL(GLuint first, GLsizei count, const GLuint *samplers)
+{
+}
+
+void INTERNAL_GL_APIENTRY glBindTextureNULL(GLenum target, GLuint texture)
+{
+}
+
+void INTERNAL_GL_APIENTRY glBindTextureUnitNULL(GLuint unit, GLuint texture)
+{
+}
+
+void INTERNAL_GL_APIENTRY glBindTexturesNULL(GLuint first, GLsizei count, const GLuint *textures)
+{
+}
+
+void INTERNAL_GL_APIENTRY glBindTransformFeedbackNULL(GLenum target, GLuint id)
+{
+}
+
+void INTERNAL_GL_APIENTRY glBindVertexArrayNULL(GLuint array)
+{
+}
+
+void INTERNAL_GL_APIENTRY glBindVertexBufferNULL(GLuint bindingindex,
+                                                 GLuint buffer,
+                                                 GLintptr offset,
+                                                 GLsizei stride)
+{
+}
+
+void INTERNAL_GL_APIENTRY glBindVertexBuffersNULL(GLuint first,
+                                                  GLsizei count,
+                                                  const GLuint *buffers,
+                                                  const GLintptr *offsets,
+                                                  const GLsizei *strides)
+{
+}
+
+void INTERNAL_GL_APIENTRY glBlendBarrierNULL()
+{
+}
+
+void INTERNAL_GL_APIENTRY glBlendColorNULL(GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha)
+{
+}
+
+void INTERNAL_GL_APIENTRY glBlendEquationNULL(GLenum mode)
+{
+}
+
+void INTERNAL_GL_APIENTRY glBlendEquationSeparateNULL(GLenum modeRGB, GLenum modeAlpha)
+{
+}
+
+void INTERNAL_GL_APIENTRY glBlendEquationSeparateiNULL(GLuint buf, GLenum modeRGB, GLenum modeAlpha)
+{
+}
+
+void INTERNAL_GL_APIENTRY glBlendEquationiNULL(GLuint buf, GLenum mode)
+{
+}
+
+void INTERNAL_GL_APIENTRY glBlendFuncNULL(GLenum sfactor, GLenum dfactor)
+{
+}
+
+void INTERNAL_GL_APIENTRY glBlendFuncSeparateNULL(GLenum sfactorRGB,
+                                                  GLenum dfactorRGB,
+                                                  GLenum sfactorAlpha,
+                                                  GLenum dfactorAlpha)
+{
+}
+
+void INTERNAL_GL_APIENTRY
+glBlendFuncSeparateiNULL(GLuint buf, GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha)
+{
+}
+
+void INTERNAL_GL_APIENTRY glBlendFunciNULL(GLuint buf, GLenum src, GLenum dst)
+{
+}
+
+void INTERNAL_GL_APIENTRY glBlitFramebufferNULL(GLint srcX0,
+                                                GLint srcY0,
+                                                GLint srcX1,
+                                                GLint srcY1,
+                                                GLint dstX0,
+                                                GLint dstY0,
+                                                GLint dstX1,
+                                                GLint dstY1,
+                                                GLbitfield mask,
+                                                GLenum filter)
+{
+}
+
+void INTERNAL_GL_APIENTRY glBlitNamedFramebufferNULL(GLuint readFramebuffer,
+                                                     GLuint drawFramebuffer,
+                                                     GLint srcX0,
+                                                     GLint srcY0,
+                                                     GLint srcX1,
+                                                     GLint srcY1,
+                                                     GLint dstX0,
+                                                     GLint dstY0,
+                                                     GLint dstX1,
+                                                     GLint dstY1,
+                                                     GLbitfield mask,
+                                                     GLenum filter)
+{
+}
+
+void INTERNAL_GL_APIENTRY glBufferDataNULL(GLenum target,
+                                           GLsizeiptr size,
+                                           const void *data,
+                                           GLenum usage)
+{
+}
+
+void INTERNAL_GL_APIENTRY glBufferStorageNULL(GLenum target,
+                                              GLsizeiptr size,
+                                              const void *data,
+                                              GLbitfield flags)
+{
+}
+
+void INTERNAL_GL_APIENTRY glBufferSubDataNULL(GLenum target,
+                                              GLintptr offset,
+                                              GLsizeiptr size,
+                                              const void *data)
+{
+}
+
+GLenum INTERNAL_GL_APIENTRY glCheckFramebufferStatusNULL(GLenum target)
+{
+    return static_cast<GLenum>(0);
+}
+
+GLenum INTERNAL_GL_APIENTRY glCheckNamedFramebufferStatusNULL(GLuint framebuffer, GLenum target)
+{
+    return static_cast<GLenum>(0);
+}
+
+void INTERNAL_GL_APIENTRY glClampColorNULL(GLenum target, GLenum clamp)
+{
+}
+
+void INTERNAL_GL_APIENTRY glClearNULL(GLbitfield mask)
+{
+}
+
+void INTERNAL_GL_APIENTRY glClearBufferDataNULL(GLenum target,
+                                                GLenum internalformat,
+                                                GLenum format,
+                                                GLenum type,
+                                                const void *data)
+{
+}
+
+void INTERNAL_GL_APIENTRY glClearBufferSubDataNULL(GLenum target,
+                                                   GLenum internalformat,
+                                                   GLintptr offset,
+                                                   GLsizeiptr size,
+                                                   GLenum format,
+                                                   GLenum type,
+                                                   const void *data)
+{
+}
+
+void INTERNAL_GL_APIENTRY glClearBufferfiNULL(GLenum buffer,
+                                              GLint drawbuffer,
+                                              GLfloat depth,
+                                              GLint stencil)
+{
+}
+
+void INTERNAL_GL_APIENTRY glClearBufferfvNULL(GLenum buffer, GLint drawbuffer, const GLfloat *value)
+{
+}
+
+void INTERNAL_GL_APIENTRY glClearBufferivNULL(GLenum buffer, GLint drawbuffer, const GLint *value)
+{
+}
+
+void INTERNAL_GL_APIENTRY glClearBufferuivNULL(GLenum buffer, GLint drawbuffer, const GLuint *value)
+{
+}
+
+void INTERNAL_GL_APIENTRY glClearColorNULL(GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha)
+{
+}
+
+void INTERNAL_GL_APIENTRY glClearDepthNULL(GLdouble depth)
+{
+}
+
+void INTERNAL_GL_APIENTRY glClearDepthfNULL(GLfloat d)
+{
+}
+
+void INTERNAL_GL_APIENTRY glClearNamedBufferDataNULL(GLuint buffer,
+                                                     GLenum internalformat,
+                                                     GLenum format,
+                                                     GLenum type,
+                                                     const void *data)
+{
+}
+
+void INTERNAL_GL_APIENTRY glClearNamedBufferSubDataNULL(GLuint buffer,
+                                                        GLenum internalformat,
+                                                        GLintptr offset,
+                                                        GLsizeiptr size,
+                                                        GLenum format,
+                                                        GLenum type,
+                                                        const void *data)
+{
+}
+
+void INTERNAL_GL_APIENTRY glClearNamedFramebufferfiNULL(GLuint framebuffer,
+                                                        GLenum buffer,
+                                                        GLint drawbuffer,
+                                                        GLfloat depth,
+                                                        GLint stencil)
+{
+}
+
+void INTERNAL_GL_APIENTRY glClearNamedFramebufferfvNULL(GLuint framebuffer,
+                                                        GLenum buffer,
+                                                        GLint drawbuffer,
+                                                        const GLfloat *value)
+{
+}
+
+void INTERNAL_GL_APIENTRY glClearNamedFramebufferivNULL(GLuint framebuffer,
+                                                        GLenum buffer,
+                                                        GLint drawbuffer,
+                                                        const GLint *value)
+{
+}
+
+void INTERNAL_GL_APIENTRY glClearNamedFramebufferuivNULL(GLuint framebuffer,
+                                                         GLenum buffer,
+                                                         GLint drawbuffer,
+                                                         const GLuint *value)
+{
+}
+
+void INTERNAL_GL_APIENTRY glClearStencilNULL(GLint s)
+{
+}
+
+void INTERNAL_GL_APIENTRY
+glClearTexImageNULL(GLuint texture, GLint level, GLenum format, GLenum type, const void *data)
+{
+}
+
+void INTERNAL_GL_APIENTRY glClearTexSubImageNULL(GLuint texture,
+                                                 GLint level,
+                                                 GLint xoffset,
+                                                 GLint yoffset,
+                                                 GLint zoffset,
+                                                 GLsizei width,
+                                                 GLsizei height,
+                                                 GLsizei depth,
+                                                 GLenum format,
+                                                 GLenum type,
+                                                 const void *data)
+{
+}
+
+GLenum INTERNAL_GL_APIENTRY glClientWaitSyncNULL(GLsync sync, GLbitfield flags, GLuint64 timeout)
+{
+    return static_cast<GLenum>(0);
+}
+
+void INTERNAL_GL_APIENTRY glClipControlNULL(GLenum origin, GLenum depth)
+{
+}
+
+void INTERNAL_GL_APIENTRY glColorMaskNULL(GLboolean red,
+                                          GLboolean green,
+                                          GLboolean blue,
+                                          GLboolean alpha)
+{
+}
+
+void INTERNAL_GL_APIENTRY
+glColorMaskiNULL(GLuint index, GLboolean r, GLboolean g, GLboolean b, GLboolean a)
+{
+}
+
+void INTERNAL_GL_APIENTRY glCompileShaderNULL(GLuint shader)
+{
+}
+
+void INTERNAL_GL_APIENTRY glCompressedTexImage1DNULL(GLenum target,
+                                                     GLint level,
+                                                     GLenum internalformat,
+                                                     GLsizei width,
+                                                     GLint border,
+                                                     GLsizei imageSize,
+                                                     const void *data)
+{
+}
+
+void INTERNAL_GL_APIENTRY glCompressedTexImage2DNULL(GLenum target,
+                                                     GLint level,
+                                                     GLenum internalformat,
+                                                     GLsizei width,
+                                                     GLsizei height,
+                                                     GLint border,
+                                                     GLsizei imageSize,
+                                                     const void *data)
+{
+}
+
+void INTERNAL_GL_APIENTRY glCompressedTexImage3DNULL(GLenum target,
+                                                     GLint level,
+                                                     GLenum internalformat,
+                                                     GLsizei width,
+                                                     GLsizei height,
+                                                     GLsizei depth,
+                                                     GLint border,
+                                                     GLsizei imageSize,
+                                                     const void *data)
+{
+}
+
+void INTERNAL_GL_APIENTRY glCompressedTexSubImage1DNULL(GLenum target,
+                                                        GLint level,
+                                                        GLint xoffset,
+                                                        GLsizei width,
+                                                        GLenum format,
+                                                        GLsizei imageSize,
+                                                        const void *data)
+{
+}
+
+void INTERNAL_GL_APIENTRY glCompressedTexSubImage2DNULL(GLenum target,
+                                                        GLint level,
+                                                        GLint xoffset,
+                                                        GLint yoffset,
+                                                        GLsizei width,
+                                                        GLsizei height,
+                                                        GLenum format,
+                                                        GLsizei imageSize,
+                                                        const void *data)
+{
+}
+
+void INTERNAL_GL_APIENTRY glCompressedTexSubImage3DNULL(GLenum target,
+                                                        GLint level,
+                                                        GLint xoffset,
+                                                        GLint yoffset,
+                                                        GLint zoffset,
+                                                        GLsizei width,
+                                                        GLsizei height,
+                                                        GLsizei depth,
+                                                        GLenum format,
+                                                        GLsizei imageSize,
+                                                        const void *data)
+{
+}
+
+void INTERNAL_GL_APIENTRY glCompressedTextureSubImage1DNULL(GLuint texture,
+                                                            GLint level,
+                                                            GLint xoffset,
+                                                            GLsizei width,
+                                                            GLenum format,
+                                                            GLsizei imageSize,
+                                                            const void *data)
+{
+}
+
+void INTERNAL_GL_APIENTRY glCompressedTextureSubImage2DNULL(GLuint texture,
+                                                            GLint level,
+                                                            GLint xoffset,
+                                                            GLint yoffset,
+                                                            GLsizei width,
+                                                            GLsizei height,
+                                                            GLenum format,
+                                                            GLsizei imageSize,
+                                                            const void *data)
+{
+}
+
+void INTERNAL_GL_APIENTRY glCompressedTextureSubImage3DNULL(GLuint texture,
+                                                            GLint level,
+                                                            GLint xoffset,
+                                                            GLint yoffset,
+                                                            GLint zoffset,
+                                                            GLsizei width,
+                                                            GLsizei height,
+                                                            GLsizei depth,
+                                                            GLenum format,
+                                                            GLsizei imageSize,
+                                                            const void *data)
+{
+}
+
+void INTERNAL_GL_APIENTRY glCopyBufferSubDataNULL(GLenum readTarget,
+                                                  GLenum writeTarget,
+                                                  GLintptr readOffset,
+                                                  GLintptr writeOffset,
+                                                  GLsizeiptr size)
+{
+}
+
+void INTERNAL_GL_APIENTRY glCopyImageSubDataNULL(GLuint srcName,
+                                                 GLenum srcTarget,
+                                                 GLint srcLevel,
+                                                 GLint srcX,
+                                                 GLint srcY,
+                                                 GLint srcZ,
+                                                 GLuint dstName,
+                                                 GLenum dstTarget,
+                                                 GLint dstLevel,
+                                                 GLint dstX,
+                                                 GLint dstY,
+                                                 GLint dstZ,
+                                                 GLsizei srcWidth,
+                                                 GLsizei srcHeight,
+                                                 GLsizei srcDepth)
+{
+}
+
+void INTERNAL_GL_APIENTRY glCopyNamedBufferSubDataNULL(GLuint readBuffer,
+                                                       GLuint writeBuffer,
+                                                       GLintptr readOffset,
+                                                       GLintptr writeOffset,
+                                                       GLsizeiptr size)
+{
+}
+
+void INTERNAL_GL_APIENTRY glCopyTexImage1DNULL(GLenum target,
+                                               GLint level,
+                                               GLenum internalformat,
+                                               GLint x,
+                                               GLint y,
+                                               GLsizei width,
+                                               GLint border)
+{
+}
+
+void INTERNAL_GL_APIENTRY glCopyTexImage2DNULL(GLenum target,
+                                               GLint level,
+                                               GLenum internalformat,
+                                               GLint x,
+                                               GLint y,
+                                               GLsizei width,
+                                               GLsizei height,
+                                               GLint border)
+{
+}
+
+void INTERNAL_GL_APIENTRY
+glCopyTexSubImage1DNULL(GLenum target, GLint level, GLint xoffset, GLint x, GLint y, GLsizei width)
+{
+}
+
+void INTERNAL_GL_APIENTRY glCopyTexSubImage2DNULL(GLenum target,
+                                                  GLint level,
+                                                  GLint xoffset,
+                                                  GLint yoffset,
+                                                  GLint x,
+                                                  GLint y,
+                                                  GLsizei width,
+                                                  GLsizei height)
+{
+}
+
+void INTERNAL_GL_APIENTRY glCopyTexSubImage3DNULL(GLenum target,
+                                                  GLint level,
+                                                  GLint xoffset,
+                                                  GLint yoffset,
+                                                  GLint zoffset,
+                                                  GLint x,
+                                                  GLint y,
+                                                  GLsizei width,
+                                                  GLsizei height)
+{
+}
+
+void INTERNAL_GL_APIENTRY glCopyTextureSubImage1DNULL(GLuint texture,
+                                                      GLint level,
+                                                      GLint xoffset,
+                                                      GLint x,
+                                                      GLint y,
+                                                      GLsizei width)
+{
+}
+
+void INTERNAL_GL_APIENTRY glCopyTextureSubImage2DNULL(GLuint texture,
+                                                      GLint level,
+                                                      GLint xoffset,
+                                                      GLint yoffset,
+                                                      GLint x,
+                                                      GLint y,
+                                                      GLsizei width,
+                                                      GLsizei height)
+{
+}
+
+void INTERNAL_GL_APIENTRY glCopyTextureSubImage3DNULL(GLuint texture,
+                                                      GLint level,
+                                                      GLint xoffset,
+                                                      GLint yoffset,
+                                                      GLint zoffset,
+                                                      GLint x,
+                                                      GLint y,
+                                                      GLsizei width,
+                                                      GLsizei height)
+{
+}
+
+void INTERNAL_GL_APIENTRY glCoverFillPathInstancedNVNULL(GLsizei numPaths,
+                                                         GLenum pathNameType,
+                                                         const void *paths,
+                                                         GLuint pathBase,
+                                                         GLenum coverMode,
+                                                         GLenum transformType,
+                                                         const GLfloat *transformValues)
+{
+}
+
+void INTERNAL_GL_APIENTRY glCoverFillPathNVNULL(GLuint path, GLenum coverMode)
+{
+}
+
+void INTERNAL_GL_APIENTRY glCoverStrokePathInstancedNVNULL(GLsizei numPaths,
+                                                           GLenum pathNameType,
+                                                           const void *paths,
+                                                           GLuint pathBase,
+                                                           GLenum coverMode,
+                                                           GLenum transformType,
+                                                           const GLfloat *transformValues)
+{
+}
+
+void INTERNAL_GL_APIENTRY glCoverStrokePathNVNULL(GLuint path, GLenum coverMode)
+{
+}
+
+void INTERNAL_GL_APIENTRY glCoverageModulationNVNULL(GLenum components)
+{
+}
+
+void INTERNAL_GL_APIENTRY glCreateBuffersNULL(GLsizei n, GLuint *buffers)
+{
+}
+
+void INTERNAL_GL_APIENTRY glCreateFramebuffersNULL(GLsizei n, GLuint *framebuffers)
+{
+}
+
+GLuint INTERNAL_GL_APIENTRY glCreateProgramNULL()
+{
+    return static_cast<GLuint>(0);
+}
+
+void INTERNAL_GL_APIENTRY glCreateProgramPipelinesNULL(GLsizei n, GLuint *pipelines)
+{
+}
+
+void INTERNAL_GL_APIENTRY glCreateQueriesNULL(GLenum target, GLsizei n, GLuint *ids)
+{
+}
+
+void INTERNAL_GL_APIENTRY glCreateRenderbuffersNULL(GLsizei n, GLuint *renderbuffers)
+{
+}
+
+void INTERNAL_GL_APIENTRY glCreateSamplersNULL(GLsizei n, GLuint *samplers)
+{
+}
+
+GLuint INTERNAL_GL_APIENTRY glCreateShaderNULL(GLenum type)
+{
+    return static_cast<GLuint>(0);
+}
+
+GLuint INTERNAL_GL_APIENTRY glCreateShaderProgramvNULL(GLenum type,
+                                                       GLsizei count,
+                                                       const GLchar *const *strings)
+{
+    return static_cast<GLuint>(0);
+}
+
+void INTERNAL_GL_APIENTRY glCreateTexturesNULL(GLenum target, GLsizei n, GLuint *textures)
+{
+}
+
+void INTERNAL_GL_APIENTRY glCreateTransformFeedbacksNULL(GLsizei n, GLuint *ids)
+{
+}
+
+void INTERNAL_GL_APIENTRY glCreateVertexArraysNULL(GLsizei n, GLuint *arrays)
+{
+}
+
+void INTERNAL_GL_APIENTRY glCullFaceNULL(GLenum mode)
+{
+}
+
+void INTERNAL_GL_APIENTRY glDebugMessageCallbackNULL(GLDEBUGPROC callback, const void *userParam)
+{
+}
+
+void INTERNAL_GL_APIENTRY glDebugMessageControlNULL(GLenum source,
+                                                    GLenum type,
+                                                    GLenum severity,
+                                                    GLsizei count,
+                                                    const GLuint *ids,
+                                                    GLboolean enabled)
+{
+}
+
+void INTERNAL_GL_APIENTRY glDebugMessageInsertNULL(GLenum source,
+                                                   GLenum type,
+                                                   GLuint id,
+                                                   GLenum severity,
+                                                   GLsizei length,
+                                                   const GLchar *buf)
+{
+}
+
+void INTERNAL_GL_APIENTRY glDeleteBuffersNULL(GLsizei n, const GLuint *buffers)
+{
+}
+
+void INTERNAL_GL_APIENTRY glDeleteFencesNVNULL(GLsizei n, const GLuint *fences)
+{
+}
+
+void INTERNAL_GL_APIENTRY glDeleteFramebuffersNULL(GLsizei n, const GLuint *framebuffers)
+{
+}
+
+void INTERNAL_GL_APIENTRY glDeletePathsNVNULL(GLuint path, GLsizei range)
+{
+}
+
+void INTERNAL_GL_APIENTRY glDeleteProgramNULL(GLuint program)
+{
+}
+
+void INTERNAL_GL_APIENTRY glDeleteProgramPipelinesNULL(GLsizei n, const GLuint *pipelines)
+{
+}
+
+void INTERNAL_GL_APIENTRY glDeleteQueriesNULL(GLsizei n, const GLuint *ids)
+{
+}
+
+void INTERNAL_GL_APIENTRY glDeleteRenderbuffersNULL(GLsizei n, const GLuint *renderbuffers)
+{
+}
+
+void INTERNAL_GL_APIENTRY glDeleteSamplersNULL(GLsizei count, const GLuint *samplers)
+{
+}
+
+void INTERNAL_GL_APIENTRY glDeleteShaderNULL(GLuint shader)
+{
+}
+
+void INTERNAL_GL_APIENTRY glDeleteSyncNULL(GLsync sync)
+{
+}
+
+void INTERNAL_GL_APIENTRY glDeleteTexturesNULL(GLsizei n, const GLuint *textures)
+{
+}
+
+void INTERNAL_GL_APIENTRY glDeleteTransformFeedbacksNULL(GLsizei n, const GLuint *ids)
+{
+}
+
+void INTERNAL_GL_APIENTRY glDeleteVertexArraysNULL(GLsizei n, const GLuint *arrays)
+{
+}
+
+void INTERNAL_GL_APIENTRY glDepthFuncNULL(GLenum func)
+{
+}
+
+void INTERNAL_GL_APIENTRY glDepthMaskNULL(GLboolean flag)
+{
+}
+
+void INTERNAL_GL_APIENTRY glDepthRangeNULL(GLdouble near, GLdouble far)
+{
+}
+
+void INTERNAL_GL_APIENTRY glDepthRangeArrayvNULL(GLuint first, GLsizei count, const GLdouble *v)
+{
+}
+
+void INTERNAL_GL_APIENTRY glDepthRangeIndexedNULL(GLuint index, GLdouble n, GLdouble f)
+{
+}
+
+void INTERNAL_GL_APIENTRY glDepthRangefNULL(GLfloat n, GLfloat f)
+{
+}
+
+void INTERNAL_GL_APIENTRY glDetachShaderNULL(GLuint program, GLuint shader)
+{
+}
+
+void INTERNAL_GL_APIENTRY glDisableNULL(GLenum cap)
+{
+}
+
+void INTERNAL_GL_APIENTRY glDisableVertexArrayAttribNULL(GLuint vaobj, GLuint index)
+{
+}
+
+void INTERNAL_GL_APIENTRY glDisableVertexAttribArrayNULL(GLuint index)
+{
+}
+
+void INTERNAL_GL_APIENTRY glDisableiNULL(GLenum target, GLuint index)
+{
+}
+
+void INTERNAL_GL_APIENTRY glDiscardFramebufferEXTNULL(GLenum target,
+                                                      GLsizei numAttachments,
+                                                      const GLenum *attachments)
+{
+}
+
+void INTERNAL_GL_APIENTRY glDispatchComputeNULL(GLuint num_groups_x,
+                                                GLuint num_groups_y,
+                                                GLuint num_groups_z)
+{
+}
+
+void INTERNAL_GL_APIENTRY glDispatchComputeIndirectNULL(GLintptr indirect)
+{
+}
+
+void INTERNAL_GL_APIENTRY glDrawArraysNULL(GLenum mode, GLint first, GLsizei count)
+{
+}
+
+void INTERNAL_GL_APIENTRY glDrawArraysIndirectNULL(GLenum mode, const void *indirect)
+{
+}
+
+void INTERNAL_GL_APIENTRY glDrawArraysInstancedNULL(GLenum mode,
+                                                    GLint first,
+                                                    GLsizei count,
+                                                    GLsizei instancecount)
+{
+}
+
+void INTERNAL_GL_APIENTRY glDrawArraysInstancedBaseInstanceNULL(GLenum mode,
+                                                                GLint first,
+                                                                GLsizei count,
+                                                                GLsizei instancecount,
+                                                                GLuint baseinstance)
+{
+}
+
+void INTERNAL_GL_APIENTRY glDrawBufferNULL(GLenum buf)
+{
+}
+
+void INTERNAL_GL_APIENTRY glDrawBuffersNULL(GLsizei n, const GLenum *bufs)
+{
+}
+
+void INTERNAL_GL_APIENTRY glDrawElementsNULL(GLenum mode,
+                                             GLsizei count,
+                                             GLenum type,
+                                             const void *indices)
+{
+}
+
+void INTERNAL_GL_APIENTRY glDrawElementsBaseVertexNULL(GLenum mode,
+                                                       GLsizei count,
+                                                       GLenum type,
+                                                       const void *indices,
+                                                       GLint basevertex)
+{
+}
+
+void INTERNAL_GL_APIENTRY glDrawElementsIndirectNULL(GLenum mode, GLenum type, const void *indirect)
+{
+}
+
+void INTERNAL_GL_APIENTRY glDrawElementsInstancedNULL(GLenum mode,
+                                                      GLsizei count,
+                                                      GLenum type,
+                                                      const void *indices,
+                                                      GLsizei instancecount)
+{
+}
+
+void INTERNAL_GL_APIENTRY glDrawElementsInstancedBaseInstanceNULL(GLenum mode,
+                                                                  GLsizei count,
+                                                                  GLenum type,
+                                                                  const void *indices,
+                                                                  GLsizei instancecount,
+                                                                  GLuint baseinstance)
+{
+}
+
+void INTERNAL_GL_APIENTRY glDrawElementsInstancedBaseVertexNULL(GLenum mode,
+                                                                GLsizei count,
+                                                                GLenum type,
+                                                                const void *indices,
+                                                                GLsizei instancecount,
+                                                                GLint basevertex)
+{
+}
+
+void INTERNAL_GL_APIENTRY glDrawElementsInstancedBaseVertexBaseInstanceNULL(GLenum mode,
+                                                                            GLsizei count,
+                                                                            GLenum type,
+                                                                            const void *indices,
+                                                                            GLsizei instancecount,
+                                                                            GLint basevertex,
+                                                                            GLuint baseinstance)
+{
+}
+
+void INTERNAL_GL_APIENTRY glDrawRangeElementsNULL(GLenum mode,
+                                                  GLuint start,
+                                                  GLuint end,
+                                                  GLsizei count,
+                                                  GLenum type,
+                                                  const void *indices)
+{
+}
+
+void INTERNAL_GL_APIENTRY glDrawRangeElementsBaseVertexNULL(GLenum mode,
+                                                            GLuint start,
+                                                            GLuint end,
+                                                            GLsizei count,
+                                                            GLenum type,
+                                                            const void *indices,
+                                                            GLint basevertex)
+{
+}
+
+void INTERNAL_GL_APIENTRY glDrawTransformFeedbackNULL(GLenum mode, GLuint id)
+{
+}
+
+void INTERNAL_GL_APIENTRY glDrawTransformFeedbackInstancedNULL(GLenum mode,
+                                                               GLuint id,
+                                                               GLsizei instancecount)
+{
+}
+
+void INTERNAL_GL_APIENTRY glDrawTransformFeedbackStreamNULL(GLenum mode, GLuint id, GLuint stream)
+{
+}
+
+void INTERNAL_GL_APIENTRY glDrawTransformFeedbackStreamInstancedNULL(GLenum mode,
+                                                                     GLuint id,
+                                                                     GLuint stream,
+                                                                     GLsizei instancecount)
+{
+}
+
+void INTERNAL_GL_APIENTRY glEGLImageTargetRenderbufferStorageOESNULL(GLenum target,
+                                                                     GLeglImageOES image)
+{
+}
+
+void INTERNAL_GL_APIENTRY glEGLImageTargetTexture2DOESNULL(GLenum target, GLeglImageOES image)
+{
+}
+
+void INTERNAL_GL_APIENTRY glEnableNULL(GLenum cap)
+{
+}
+
+void INTERNAL_GL_APIENTRY glEnableVertexArrayAttribNULL(GLuint vaobj, GLuint index)
+{
+}
+
+void INTERNAL_GL_APIENTRY glEnableVertexAttribArrayNULL(GLuint index)
+{
+}
+
+void INTERNAL_GL_APIENTRY glEnableiNULL(GLenum target, GLuint index)
+{
+}
+
+void INTERNAL_GL_APIENTRY glEndConditionalRenderNULL()
+{
+}
+
+void INTERNAL_GL_APIENTRY glEndQueryNULL(GLenum target)
+{
+}
+
+void INTERNAL_GL_APIENTRY glEndQueryIndexedNULL(GLenum target, GLuint index)
+{
+}
+
+void INTERNAL_GL_APIENTRY glEndTransformFeedbackNULL()
+{
+}
+
+GLsync INTERNAL_GL_APIENTRY glFenceSyncNULL(GLenum condition, GLbitfield flags)
+{
+    return static_cast<GLsync>(0);
+}
+
+void INTERNAL_GL_APIENTRY glFinishNULL()
+{
+}
+
+void INTERNAL_GL_APIENTRY glFinishFenceNVNULL(GLuint fence)
+{
+}
+
+void INTERNAL_GL_APIENTRY glFlushNULL()
+{
+}
+
+void INTERNAL_GL_APIENTRY glFlushMappedBufferRangeNULL(GLenum target,
+                                                       GLintptr offset,
+                                                       GLsizeiptr length)
+{
+}
+
+void INTERNAL_GL_APIENTRY glFlushMappedNamedBufferRangeNULL(GLuint buffer,
+                                                            GLintptr offset,
+                                                            GLsizeiptr length)
+{
+}
+
+void INTERNAL_GL_APIENTRY glFramebufferParameteriNULL(GLenum target, GLenum pname, GLint param)
+{
+}
+
+void INTERNAL_GL_APIENTRY glFramebufferRenderbufferNULL(GLenum target,
+                                                        GLenum attachment,
+                                                        GLenum renderbuffertarget,
+                                                        GLuint renderbuffer)
+{
+}
+
+void INTERNAL_GL_APIENTRY glFramebufferTextureNULL(GLenum target,
+                                                   GLenum attachment,
+                                                   GLuint texture,
+                                                   GLint level)
+{
+}
+
+void INTERNAL_GL_APIENTRY glFramebufferTexture1DNULL(GLenum target,
+                                                     GLenum attachment,
+                                                     GLenum textarget,
+                                                     GLuint texture,
+                                                     GLint level)
+{
+}
+
+void INTERNAL_GL_APIENTRY glFramebufferTexture2DNULL(GLenum target,
+                                                     GLenum attachment,
+                                                     GLenum textarget,
+                                                     GLuint texture,
+                                                     GLint level)
+{
+}
+
+void INTERNAL_GL_APIENTRY glFramebufferTexture3DNULL(GLenum target,
+                                                     GLenum attachment,
+                                                     GLenum textarget,
+                                                     GLuint texture,
+                                                     GLint level,
+                                                     GLint zoffset)
+{
+}
+
+void INTERNAL_GL_APIENTRY glFramebufferTextureLayerNULL(GLenum target,
+                                                        GLenum attachment,
+                                                        GLuint texture,
+                                                        GLint level,
+                                                        GLint layer)
+{
+}
+
+void INTERNAL_GL_APIENTRY glFrontFaceNULL(GLenum mode)
+{
+}
+
+void INTERNAL_GL_APIENTRY glGenBuffersNULL(GLsizei n, GLuint *buffers)
+{
+}
+
+void INTERNAL_GL_APIENTRY glGenFencesNVNULL(GLsizei n, GLuint *fences)
+{
+}
+
+void INTERNAL_GL_APIENTRY glGenFramebuffersNULL(GLsizei n, GLuint *framebuffers)
+{
+}
+
+GLuint INTERNAL_GL_APIENTRY glGenPathsNVNULL(GLsizei range)
+{
+    return static_cast<GLuint>(0);
+}
+
+void INTERNAL_GL_APIENTRY glGenProgramPipelinesNULL(GLsizei n, GLuint *pipelines)
+{
+}
+
+void INTERNAL_GL_APIENTRY glGenQueriesNULL(GLsizei n, GLuint *ids)
+{
+}
+
+void INTERNAL_GL_APIENTRY glGenRenderbuffersNULL(GLsizei n, GLuint *renderbuffers)
+{
+}
+
+void INTERNAL_GL_APIENTRY glGenSamplersNULL(GLsizei count, GLuint *samplers)
+{
+}
+
+void INTERNAL_GL_APIENTRY glGenTexturesNULL(GLsizei n, GLuint *textures)
+{
+}
+
+void INTERNAL_GL_APIENTRY glGenTransformFeedbacksNULL(GLsizei n, GLuint *ids)
+{
+}
+
+void INTERNAL_GL_APIENTRY glGenVertexArraysNULL(GLsizei n, GLuint *arrays)
+{
+}
+
+void INTERNAL_GL_APIENTRY glGenerateMipmapNULL(GLenum target)
+{
+}
+
+void INTERNAL_GL_APIENTRY glGenerateTextureMipmapNULL(GLuint texture)
+{
+}
+
+void INTERNAL_GL_APIENTRY glGetActiveAtomicCounterBufferivNULL(GLuint program,
+                                                               GLuint bufferIndex,
+                                                               GLenum pname,
+                                                               GLint *params)
+{
+}
+
+void INTERNAL_GL_APIENTRY glGetActiveAttribNULL(GLuint program,
+                                                GLuint index,
+                                                GLsizei bufSize,
+                                                GLsizei *length,
+                                                GLint *size,
+                                                GLenum *type,
+                                                GLchar *name)
+{
+}
+
+void INTERNAL_GL_APIENTRY glGetActiveSubroutineNameNULL(GLuint program,
+                                                        GLenum shadertype,
+                                                        GLuint index,
+                                                        GLsizei bufsize,
+                                                        GLsizei *length,
+                                                        GLchar *name)
+{
+}
+
+void INTERNAL_GL_APIENTRY glGetActiveSubroutineUniformNameNULL(GLuint program,
+                                                               GLenum shadertype,
+                                                               GLuint index,
+                                                               GLsizei bufsize,
+                                                               GLsizei *length,
+                                                               GLchar *name)
+{
+}
+
+void INTERNAL_GL_APIENTRY glGetActiveSubroutineUniformivNULL(GLuint program,
+                                                             GLenum shadertype,
+                                                             GLuint index,
+                                                             GLenum pname,
+                                                             GLint *values)
+{
+}
+
+void INTERNAL_GL_APIENTRY glGetActiveUniformNULL(GLuint program,
+                                                 GLuint index,
+                                                 GLsizei bufSize,
+                                                 GLsizei *length,
+                                                 GLint *size,
+                                                 GLenum *type,
+                                                 GLchar *name)
+{
+}
+
+void INTERNAL_GL_APIENTRY glGetActiveUniformBlockNameNULL(GLuint program,
+                                                          GLuint uniformBlockIndex,
+                                                          GLsizei bufSize,
+                                                          GLsizei *length,
+                                                          GLchar *uniformBlockName)
+{
+}
+
+void INTERNAL_GL_APIENTRY glGetActiveUniformBlockivNULL(GLuint program,
+                                                        GLuint uniformBlockIndex,
+                                                        GLenum pname,
+                                                        GLint *params)
+{
+}
+
+void INTERNAL_GL_APIENTRY glGetActiveUniformNameNULL(GLuint program,
+                                                     GLuint uniformIndex,
+                                                     GLsizei bufSize,
+                                                     GLsizei *length,
+                                                     GLchar *uniformName)
+{
+}
+
+void INTERNAL_GL_APIENTRY glGetActiveUniformsivNULL(GLuint program,
+                                                    GLsizei uniformCount,
+                                                    const GLuint *uniformIndices,
+                                                    GLenum pname,
+                                                    GLint *params)
+{
+}
+
+void INTERNAL_GL_APIENTRY glGetAttachedShadersNULL(GLuint program,
+                                                   GLsizei maxCount,
+                                                   GLsizei *count,
+                                                   GLuint *shaders)
+{
+}
+
+GLint INTERNAL_GL_APIENTRY glGetAttribLocationNULL(GLuint program, const GLchar *name)
+{
+    return static_cast<GLint>(0);
+}
+
+void INTERNAL_GL_APIENTRY glGetBooleani_vNULL(GLenum target, GLuint index, GLboolean *data)
+{
+}
+
+void INTERNAL_GL_APIENTRY glGetBooleanvNULL(GLenum pname, GLboolean *data)
+{
+}
+
+void INTERNAL_GL_APIENTRY glGetBufferParameteri64vNULL(GLenum target, GLenum pname, GLint64 *params)
+{
+}
+
+void INTERNAL_GL_APIENTRY glGetBufferParameterivNULL(GLenum target, GLenum pname, GLint *params)
+{
+}
+
+void INTERNAL_GL_APIENTRY glGetBufferPointervNULL(GLenum target, GLenum pname, void **params)
+{
+}
+
+void INTERNAL_GL_APIENTRY glGetBufferSubDataNULL(GLenum target,
+                                                 GLintptr offset,
+                                                 GLsizeiptr size,
+                                                 void *data)
+{
+}
+
+void INTERNAL_GL_APIENTRY glGetCompressedTexImageNULL(GLenum target, GLint level, void *img)
+{
+}
+
+void INTERNAL_GL_APIENTRY glGetCompressedTextureImageNULL(GLuint texture,
+                                                          GLint level,
+                                                          GLsizei bufSize,
+                                                          void *pixels)
+{
+}
+
+void INTERNAL_GL_APIENTRY glGetCompressedTextureSubImageNULL(GLuint texture,
+                                                             GLint level,
+                                                             GLint xoffset,
+                                                             GLint yoffset,
+                                                             GLint zoffset,
+                                                             GLsizei width,
+                                                             GLsizei height,
+                                                             GLsizei depth,
+                                                             GLsizei bufSize,
+                                                             void *pixels)
+{
+}
+
+GLuint INTERNAL_GL_APIENTRY glGetDebugMessageLogNULL(GLuint count,
+                                                     GLsizei bufSize,
+                                                     GLenum *sources,
+                                                     GLenum *types,
+                                                     GLuint *ids,
+                                                     GLenum *severities,
+                                                     GLsizei *lengths,
+                                                     GLchar *messageLog)
+{
+    return static_cast<GLuint>(0);
+}
+
+void INTERNAL_GL_APIENTRY glGetDoublei_vNULL(GLenum target, GLuint index, GLdouble *data)
+{
+}
+
+void INTERNAL_GL_APIENTRY glGetDoublevNULL(GLenum pname, GLdouble *data)
+{
+}
+
+GLenum INTERNAL_GL_APIENTRY glGetErrorNULL()
+{
+    return static_cast<GLenum>(0);
+}
+
+void INTERNAL_GL_APIENTRY glGetFenceivNVNULL(GLuint fence, GLenum pname, GLint *params)
+{
+}
+
+void INTERNAL_GL_APIENTRY glGetFloati_vNULL(GLenum target, GLuint index, GLfloat *data)
+{
+}
+
+void INTERNAL_GL_APIENTRY glGetFloatvNULL(GLenum pname, GLfloat *data)
+{
+}
+
+GLint INTERNAL_GL_APIENTRY glGetFragDataIndexNULL(GLuint program, const GLchar *name)
+{
+    return static_cast<GLint>(0);
+}
+
+GLint INTERNAL_GL_APIENTRY glGetFragDataLocationNULL(GLuint program, const GLchar *name)
+{
+    return static_cast<GLint>(0);
+}
+
+void INTERNAL_GL_APIENTRY glGetFramebufferAttachmentParameterivNULL(GLenum target,
+                                                                    GLenum attachment,
+                                                                    GLenum pname,
+                                                                    GLint *params)
+{
+}
+
+void INTERNAL_GL_APIENTRY glGetFramebufferParameterivNULL(GLenum target,
+                                                          GLenum pname,
+                                                          GLint *params)
+{
+}
+
+GLenum INTERNAL_GL_APIENTRY glGetGraphicsResetStatusNULL()
+{
+    return static_cast<GLenum>(0);
+}
+
+void INTERNAL_GL_APIENTRY glGetInteger64i_vNULL(GLenum target, GLuint index, GLint64 *data)
+{
+}
+
+void INTERNAL_GL_APIENTRY glGetInteger64vNULL(GLenum pname, GLint64 *data)
+{
+}
+
+void INTERNAL_GL_APIENTRY glGetIntegeri_vNULL(GLenum target, GLuint index, GLint *data)
+{
+}
+
+void INTERNAL_GL_APIENTRY glGetIntegervNULL(GLenum pname, GLint *data)
+{
+}
+
+void INTERNAL_GL_APIENTRY glGetInternalformatSampleivNVNULL(GLenum target,
+                                                            GLenum internalformat,
+                                                            GLsizei samples,
+                                                            GLenum pname,
+                                                            GLsizei bufSize,
+                                                            GLint *params)
+{
+}
+
+void INTERNAL_GL_APIENTRY glGetInternalformati64vNULL(GLenum target,
+                                                      GLenum internalformat,
+                                                      GLenum pname,
+                                                      GLsizei bufSize,
+                                                      GLint64 *params)
+{
+}
+
+void INTERNAL_GL_APIENTRY glGetInternalformativNULL(GLenum target,
+                                                    GLenum internalformat,
+                                                    GLenum pname,
+                                                    GLsizei bufSize,
+                                                    GLint *params)
+{
+}
+
+void INTERNAL_GL_APIENTRY glGetMultisamplefvNULL(GLenum pname, GLuint index, GLfloat *val)
+{
+}
+
+void INTERNAL_GL_APIENTRY glGetNamedBufferParameteri64vNULL(GLuint buffer,
+                                                            GLenum pname,
+                                                            GLint64 *params)
+{
+}
+
+void INTERNAL_GL_APIENTRY glGetNamedBufferParameterivNULL(GLuint buffer,
+                                                          GLenum pname,
+                                                          GLint *params)
+{
+}
+
+void INTERNAL_GL_APIENTRY glGetNamedBufferPointervNULL(GLuint buffer, GLenum pname, void **params)
+{
+}
+
+void INTERNAL_GL_APIENTRY glGetNamedBufferSubDataNULL(GLuint buffer,
+                                                      GLintptr offset,
+                                                      GLsizeiptr size,
+                                                      void *data)
+{
+}
+
+void INTERNAL_GL_APIENTRY glGetNamedFramebufferAttachmentParameterivNULL(GLuint framebuffer,
+                                                                         GLenum attachment,
+                                                                         GLenum pname,
+                                                                         GLint *params)
+{
+}
+
+void INTERNAL_GL_APIENTRY glGetNamedFramebufferParameterivNULL(GLuint framebuffer,
+                                                               GLenum pname,
+                                                               GLint *param)
+{
+}
+
+void INTERNAL_GL_APIENTRY glGetNamedRenderbufferParameterivNULL(GLuint renderbuffer,
+                                                                GLenum pname,
+                                                                GLint *params)
+{
+}
+
+void INTERNAL_GL_APIENTRY glGetObjectLabelNULL(GLenum identifier,
+                                               GLuint name,
+                                               GLsizei bufSize,
+                                               GLsizei *length,
+                                               GLchar *label)
+{
+}
+
+void INTERNAL_GL_APIENTRY glGetObjectPtrLabelNULL(const void *ptr,
+                                                  GLsizei bufSize,
+                                                  GLsizei *length,
+                                                  GLchar *label)
+{
+}
+
+void INTERNAL_GL_APIENTRY glGetPathParameterfvNVNULL(GLuint path, GLenum pname, GLfloat *value)
+{
+}
+
+void INTERNAL_GL_APIENTRY glGetPathParameterivNVNULL(GLuint path, GLenum pname, GLint *value)
+{
+}
+
+void INTERNAL_GL_APIENTRY glGetPointervNULL(GLenum pname, void **params)
+{
+}
+
+void INTERNAL_GL_APIENTRY glGetProgramBinaryNULL(GLuint program,
+                                                 GLsizei bufSize,
+                                                 GLsizei *length,
+                                                 GLenum *binaryFormat,
+                                                 void *binary)
+{
+}
+
+void INTERNAL_GL_APIENTRY glGetProgramInfoLogNULL(GLuint program,
+                                                  GLsizei bufSize,
+                                                  GLsizei *length,
+                                                  GLchar *infoLog)
+{
+}
+
+void INTERNAL_GL_APIENTRY glGetProgramInterfaceivNULL(GLuint program,
+                                                      GLenum programInterface,
+                                                      GLenum pname,
+                                                      GLint *params)
+{
+}
+
+void INTERNAL_GL_APIENTRY glGetProgramPipelineInfoLogNULL(GLuint pipeline,
+                                                          GLsizei bufSize,
+                                                          GLsizei *length,
+                                                          GLchar *infoLog)
+{
+}
+
+void INTERNAL_GL_APIENTRY glGetProgramPipelineivNULL(GLuint pipeline, GLenum pname, GLint *params)
+{
+}
+
+GLuint INTERNAL_GL_APIENTRY glGetProgramResourceIndexNULL(GLuint program,
+                                                          GLenum programInterface,
+                                                          const GLchar *name)
+{
+    return static_cast<GLuint>(0);
+}
+
+GLint INTERNAL_GL_APIENTRY glGetProgramResourceLocationNULL(GLuint program,
+                                                            GLenum programInterface,
+                                                            const GLchar *name)
+{
+    return static_cast<GLint>(0);
+}
+
+GLint INTERNAL_GL_APIENTRY glGetProgramResourceLocationIndexNULL(GLuint program,
+                                                                 GLenum programInterface,
+                                                                 const GLchar *name)
+{
+    return static_cast<GLint>(0);
+}
+
+void INTERNAL_GL_APIENTRY glGetProgramResourceNameNULL(GLuint program,
+                                                       GLenum programInterface,
+                                                       GLuint index,
+                                                       GLsizei bufSize,
+                                                       GLsizei *length,
+                                                       GLchar *name)
+{
+}
+
+void INTERNAL_GL_APIENTRY glGetProgramResourceivNULL(GLuint program,
+                                                     GLenum programInterface,
+                                                     GLuint index,
+                                                     GLsizei propCount,
+                                                     const GLenum *props,
+                                                     GLsizei bufSize,
+                                                     GLsizei *length,
+                                                     GLint *params)
+{
+}
+
+void INTERNAL_GL_APIENTRY glGetProgramStageivNULL(GLuint program,
+                                                  GLenum shadertype,
+                                                  GLenum pname,
+                                                  GLint *values)
+{
+}
+
+void INTERNAL_GL_APIENTRY glGetProgramivNULL(GLuint program, GLenum pname, GLint *params)
+{
+}
+
+void INTERNAL_GL_APIENTRY glGetQueryBufferObjecti64vNULL(GLuint id,
+                                                         GLuint buffer,
+                                                         GLenum pname,
+                                                         GLintptr offset)
+{
+}
+
+void INTERNAL_GL_APIENTRY glGetQueryBufferObjectivNULL(GLuint id,
+                                                       GLuint buffer,
+                                                       GLenum pname,
+                                                       GLintptr offset)
+{
+}
+
+void INTERNAL_GL_APIENTRY glGetQueryBufferObjectui64vNULL(GLuint id,
+                                                          GLuint buffer,
+                                                          GLenum pname,
+                                                          GLintptr offset)
+{
+}
+
+void INTERNAL_GL_APIENTRY glGetQueryBufferObjectuivNULL(GLuint id,
+                                                        GLuint buffer,
+                                                        GLenum pname,
+                                                        GLintptr offset)
+{
+}
+
+void INTERNAL_GL_APIENTRY glGetQueryIndexedivNULL(GLenum target,
+                                                  GLuint index,
+                                                  GLenum pname,
+                                                  GLint *params)
+{
+}
+
+void INTERNAL_GL_APIENTRY glGetQueryObjecti64vNULL(GLuint id, GLenum pname, GLint64 *params)
+{
+}
+
+void INTERNAL_GL_APIENTRY glGetQueryObjectivNULL(GLuint id, GLenum pname, GLint *params)
+{
+}
+
+void INTERNAL_GL_APIENTRY glGetQueryObjectui64vNULL(GLuint id, GLenum pname, GLuint64 *params)
+{
+}
+
+void INTERNAL_GL_APIENTRY glGetQueryObjectuivNULL(GLuint id, GLenum pname, GLuint *params)
+{
+}
+
+void INTERNAL_GL_APIENTRY glGetQueryivNULL(GLenum target, GLenum pname, GLint *params)
+{
+}
+
+void INTERNAL_GL_APIENTRY glGetRenderbufferParameterivNULL(GLenum target,
+                                                           GLenum pname,
+                                                           GLint *params)
+{
+}
+
+void INTERNAL_GL_APIENTRY glGetSamplerParameterIivNULL(GLuint sampler, GLenum pname, GLint *params)
+{
+}
+
+void INTERNAL_GL_APIENTRY glGetSamplerParameterIuivNULL(GLuint sampler,
+                                                        GLenum pname,
+                                                        GLuint *params)
+{
+}
+
+void INTERNAL_GL_APIENTRY glGetSamplerParameterfvNULL(GLuint sampler, GLenum pname, GLfloat *params)
+{
+}
+
+void INTERNAL_GL_APIENTRY glGetSamplerParameterivNULL(GLuint sampler, GLenum pname, GLint *params)
+{
+}
+
+void INTERNAL_GL_APIENTRY glGetShaderInfoLogNULL(GLuint shader,
+                                                 GLsizei bufSize,
+                                                 GLsizei *length,
+                                                 GLchar *infoLog)
+{
+}
+
+void INTERNAL_GL_APIENTRY glGetShaderPrecisionFormatNULL(GLenum shadertype,
+                                                         GLenum precisiontype,
+                                                         GLint *range,
+                                                         GLint *precision)
+{
+}
+
+void INTERNAL_GL_APIENTRY glGetShaderSourceNULL(GLuint shader,
+                                                GLsizei bufSize,
+                                                GLsizei *length,
+                                                GLchar *source)
+{
+}
+
+void INTERNAL_GL_APIENTRY glGetShaderivNULL(GLuint shader, GLenum pname, GLint *params)
+{
+}
+
+const GLubyte *INTERNAL_GL_APIENTRY glGetStringNULL(GLenum name)
+{
+    return static_cast<const GLubyte *>(0);
+}
+
+const GLubyte *INTERNAL_GL_APIENTRY glGetStringiNULL(GLenum name, GLuint index)
+{
+    return static_cast<const GLubyte *>(0);
+}
+
+GLuint INTERNAL_GL_APIENTRY glGetSubroutineIndexNULL(GLuint program,
+                                                     GLenum shadertype,
+                                                     const GLchar *name)
+{
+    return static_cast<GLuint>(0);
+}
+
+GLint INTERNAL_GL_APIENTRY glGetSubroutineUniformLocationNULL(GLuint program,
+                                                              GLenum shadertype,
+                                                              const GLchar *name)
+{
+    return static_cast<GLint>(0);
+}
+
+void INTERNAL_GL_APIENTRY
+glGetSyncivNULL(GLsync sync, GLenum pname, GLsizei bufSize, GLsizei *length, GLint *values)
+{
+}
+
+void INTERNAL_GL_APIENTRY
+glGetTexImageNULL(GLenum target, GLint level, GLenum format, GLenum type, void *pixels)
+{
+}
+
+void INTERNAL_GL_APIENTRY glGetTexLevelParameterfvNULL(GLenum target,
+                                                       GLint level,
+                                                       GLenum pname,
+                                                       GLfloat *params)
+{
+}
+
+void INTERNAL_GL_APIENTRY glGetTexLevelParameterivNULL(GLenum target,
+                                                       GLint level,
+                                                       GLenum pname,
+                                                       GLint *params)
+{
+}
+
+void INTERNAL_GL_APIENTRY glGetTexParameterIivNULL(GLenum target, GLenum pname, GLint *params)
+{
+}
+
+void INTERNAL_GL_APIENTRY glGetTexParameterIuivNULL(GLenum target, GLenum pname, GLuint *params)
+{
+}
+
+void INTERNAL_GL_APIENTRY glGetTexParameterfvNULL(GLenum target, GLenum pname, GLfloat *params)
+{
+}
+
+void INTERNAL_GL_APIENTRY glGetTexParameterivNULL(GLenum target, GLenum pname, GLint *params)
+{
+}
+
+void INTERNAL_GL_APIENTRY glGetTextureImageNULL(GLuint texture,
+                                                GLint level,
+                                                GLenum format,
+                                                GLenum type,
+                                                GLsizei bufSize,
+                                                void *pixels)
+{
+}
+
+void INTERNAL_GL_APIENTRY glGetTextureLevelParameterfvNULL(GLuint texture,
+                                                           GLint level,
+                                                           GLenum pname,
+                                                           GLfloat *params)
+{
+}
+
+void INTERNAL_GL_APIENTRY glGetTextureLevelParameterivNULL(GLuint texture,
+                                                           GLint level,
+                                                           GLenum pname,
+                                                           GLint *params)
+{
+}
+
+void INTERNAL_GL_APIENTRY glGetTextureParameterIivNULL(GLuint texture, GLenum pname, GLint *params)
+{
+}
+
+void INTERNAL_GL_APIENTRY glGetTextureParameterIuivNULL(GLuint texture,
+                                                        GLenum pname,
+                                                        GLuint *params)
+{
+}
+
+void INTERNAL_GL_APIENTRY glGetTextureParameterfvNULL(GLuint texture, GLenum pname, GLfloat *params)
+{
+}
+
+void INTERNAL_GL_APIENTRY glGetTextureParameterivNULL(GLuint texture, GLenum pname, GLint *params)
+{
+}
+
+void INTERNAL_GL_APIENTRY glGetTextureSubImageNULL(GLuint texture,
+                                                   GLint level,
+                                                   GLint xoffset,
+                                                   GLint yoffset,
+                                                   GLint zoffset,
+                                                   GLsizei width,
+                                                   GLsizei height,
+                                                   GLsizei depth,
+                                                   GLenum format,
+                                                   GLenum type,
+                                                   GLsizei bufSize,
+                                                   void *pixels)
+{
+}
+
+void INTERNAL_GL_APIENTRY glGetTransformFeedbackVaryingNULL(GLuint program,
+                                                            GLuint index,
+                                                            GLsizei bufSize,
+                                                            GLsizei *length,
+                                                            GLsizei *size,
+                                                            GLenum *type,
+                                                            GLchar *name)
+{
+}
+
+void INTERNAL_GL_APIENTRY glGetTransformFeedbacki64_vNULL(GLuint xfb,
+                                                          GLenum pname,
+                                                          GLuint index,
+                                                          GLint64 *param)
+{
+}
+
+void INTERNAL_GL_APIENTRY glGetTransformFeedbacki_vNULL(GLuint xfb,
+                                                        GLenum pname,
+                                                        GLuint index,
+                                                        GLint *param)
+{
+}
+
+void INTERNAL_GL_APIENTRY glGetTransformFeedbackivNULL(GLuint xfb, GLenum pname, GLint *param)
+{
+}
+
+GLuint INTERNAL_GL_APIENTRY glGetUniformBlockIndexNULL(GLuint program,
+                                                       const GLchar *uniformBlockName)
+{
+    return static_cast<GLuint>(0);
+}
+
+void INTERNAL_GL_APIENTRY glGetUniformIndicesNULL(GLuint program,
+                                                  GLsizei uniformCount,
+                                                  const GLchar *const *uniformNames,
+                                                  GLuint *uniformIndices)
+{
+}
+
+GLint INTERNAL_GL_APIENTRY glGetUniformLocationNULL(GLuint program, const GLchar *name)
+{
+    return static_cast<GLint>(0);
+}
+
+void INTERNAL_GL_APIENTRY glGetUniformSubroutineuivNULL(GLenum shadertype,
+                                                        GLint location,
+                                                        GLuint *params)
+{
+}
+
+void INTERNAL_GL_APIENTRY glGetUniformdvNULL(GLuint program, GLint location, GLdouble *params)
+{
+}
+
+void INTERNAL_GL_APIENTRY glGetUniformfvNULL(GLuint program, GLint location, GLfloat *params)
+{
+}
+
+void INTERNAL_GL_APIENTRY glGetUniformivNULL(GLuint program, GLint location, GLint *params)
+{
+}
+
+void INTERNAL_GL_APIENTRY glGetUniformuivNULL(GLuint program, GLint location, GLuint *params)
+{
+}
+
+void INTERNAL_GL_APIENTRY glGetVertexArrayIndexed64ivNULL(GLuint vaobj,
+                                                          GLuint index,
+                                                          GLenum pname,
+                                                          GLint64 *param)
+{
+}
+
+void INTERNAL_GL_APIENTRY glGetVertexArrayIndexedivNULL(GLuint vaobj,
+                                                        GLuint index,
+                                                        GLenum pname,
+                                                        GLint *param)
+{
+}
+
+void INTERNAL_GL_APIENTRY glGetVertexArrayivNULL(GLuint vaobj, GLenum pname, GLint *param)
+{
+}
+
+void INTERNAL_GL_APIENTRY glGetVertexAttribIivNULL(GLuint index, GLenum pname, GLint *params)
+{
+}
+
+void INTERNAL_GL_APIENTRY glGetVertexAttribIuivNULL(GLuint index, GLenum pname, GLuint *params)
+{
+}
+
+void INTERNAL_GL_APIENTRY glGetVertexAttribLdvNULL(GLuint index, GLenum pname, GLdouble *params)
+{
+}
+
+void INTERNAL_GL_APIENTRY glGetVertexAttribPointervNULL(GLuint index, GLenum pname, void **pointer)
+{
+}
+
+void INTERNAL_GL_APIENTRY glGetVertexAttribdvNULL(GLuint index, GLenum pname, GLdouble *params)
+{
+}
+
+void INTERNAL_GL_APIENTRY glGetVertexAttribfvNULL(GLuint index, GLenum pname, GLfloat *params)
+{
+}
+
+void INTERNAL_GL_APIENTRY glGetVertexAttribivNULL(GLuint index, GLenum pname, GLint *params)
+{
+}
+
+void INTERNAL_GL_APIENTRY glGetnCompressedTexImageNULL(GLenum target,
+                                                       GLint lod,
+                                                       GLsizei bufSize,
+                                                       void *pixels)
+{
+}
+
+void INTERNAL_GL_APIENTRY glGetnTexImageNULL(GLenum target,
+                                             GLint level,
+                                             GLenum format,
+                                             GLenum type,
+                                             GLsizei bufSize,
+                                             void *pixels)
+{
+}
+
+void INTERNAL_GL_APIENTRY glGetnUniformdvNULL(GLuint program,
+                                              GLint location,
+                                              GLsizei bufSize,
+                                              GLdouble *params)
+{
+}
+
+void INTERNAL_GL_APIENTRY glGetnUniformfvNULL(GLuint program,
+                                              GLint location,
+                                              GLsizei bufSize,
+                                              GLfloat *params)
+{
+}
+
+void INTERNAL_GL_APIENTRY glGetnUniformivNULL(GLuint program,
+                                              GLint location,
+                                              GLsizei bufSize,
+                                              GLint *params)
+{
+}
+
+void INTERNAL_GL_APIENTRY glGetnUniformuivNULL(GLuint program,
+                                               GLint location,
+                                               GLsizei bufSize,
+                                               GLuint *params)
+{
+}
+
+void INTERNAL_GL_APIENTRY glHintNULL(GLenum target, GLenum mode)
+{
+}
+
+void INTERNAL_GL_APIENTRY glInsertEventMarkerEXTNULL(GLsizei length, const GLchar *marker)
+{
+}
+
+void INTERNAL_GL_APIENTRY glInvalidateBufferDataNULL(GLuint buffer)
+{
+}
+
+void INTERNAL_GL_APIENTRY glInvalidateBufferSubDataNULL(GLuint buffer,
+                                                        GLintptr offset,
+                                                        GLsizeiptr length)
+{
+}
+
+void INTERNAL_GL_APIENTRY glInvalidateFramebufferNULL(GLenum target,
+                                                      GLsizei numAttachments,
+                                                      const GLenum *attachments)
+{
+}
+
+void INTERNAL_GL_APIENTRY glInvalidateNamedFramebufferDataNULL(GLuint framebuffer,
+                                                               GLsizei numAttachments,
+                                                               const GLenum *attachments)
+{
+}
+
+void INTERNAL_GL_APIENTRY glInvalidateNamedFramebufferSubDataNULL(GLuint framebuffer,
+                                                                  GLsizei numAttachments,
+                                                                  const GLenum *attachments,
+                                                                  GLint x,
+                                                                  GLint y,
+                                                                  GLsizei width,
+                                                                  GLsizei height)
+{
+}
+
+void INTERNAL_GL_APIENTRY glInvalidateSubFramebufferNULL(GLenum target,
+                                                         GLsizei numAttachments,
+                                                         const GLenum *attachments,
+                                                         GLint x,
+                                                         GLint y,
+                                                         GLsizei width,
+                                                         GLsizei height)
+{
+}
+
+void INTERNAL_GL_APIENTRY glInvalidateTexImageNULL(GLuint texture, GLint level)
+{
+}
+
+void INTERNAL_GL_APIENTRY glInvalidateTexSubImageNULL(GLuint texture,
+                                                      GLint level,
+                                                      GLint xoffset,
+                                                      GLint yoffset,
+                                                      GLint zoffset,
+                                                      GLsizei width,
+                                                      GLsizei height,
+                                                      GLsizei depth)
+{
+}
+
+GLboolean INTERNAL_GL_APIENTRY glIsBufferNULL(GLuint buffer)
+{
+    return static_cast<GLboolean>(0);
+}
+
+GLboolean INTERNAL_GL_APIENTRY glIsEnabledNULL(GLenum cap)
+{
+    return static_cast<GLboolean>(0);
+}
+
+GLboolean INTERNAL_GL_APIENTRY glIsEnablediNULL(GLenum target, GLuint index)
+{
+    return static_cast<GLboolean>(0);
+}
+
+GLboolean INTERNAL_GL_APIENTRY glIsFenceNVNULL(GLuint fence)
+{
+    return static_cast<GLboolean>(0);
+}
+
+GLboolean INTERNAL_GL_APIENTRY glIsFramebufferNULL(GLuint framebuffer)
+{
+    return static_cast<GLboolean>(0);
+}
+
+GLboolean INTERNAL_GL_APIENTRY glIsPathNVNULL(GLuint path)
+{
+    return static_cast<GLboolean>(0);
+}
+
+GLboolean INTERNAL_GL_APIENTRY glIsProgramNULL(GLuint program)
+{
+    return static_cast<GLboolean>(0);
+}
+
+GLboolean INTERNAL_GL_APIENTRY glIsProgramPipelineNULL(GLuint pipeline)
+{
+    return static_cast<GLboolean>(0);
+}
+
+GLboolean INTERNAL_GL_APIENTRY glIsQueryNULL(GLuint id)
+{
+    return static_cast<GLboolean>(0);
+}
+
+GLboolean INTERNAL_GL_APIENTRY glIsRenderbufferNULL(GLuint renderbuffer)
+{
+    return static_cast<GLboolean>(0);
+}
+
+GLboolean INTERNAL_GL_APIENTRY glIsSamplerNULL(GLuint sampler)
+{
+    return static_cast<GLboolean>(0);
+}
+
+GLboolean INTERNAL_GL_APIENTRY glIsShaderNULL(GLuint shader)
+{
+    return static_cast<GLboolean>(0);
+}
+
+GLboolean INTERNAL_GL_APIENTRY glIsSyncNULL(GLsync sync)
+{
+    return static_cast<GLboolean>(0);
+}
+
+GLboolean INTERNAL_GL_APIENTRY glIsTextureNULL(GLuint texture)
+{
+    return static_cast<GLboolean>(0);
+}
+
+GLboolean INTERNAL_GL_APIENTRY glIsTransformFeedbackNULL(GLuint id)
+{
+    return static_cast<GLboolean>(0);
+}
+
+GLboolean INTERNAL_GL_APIENTRY glIsVertexArrayNULL(GLuint array)
+{
+    return static_cast<GLboolean>(0);
+}
+
+void INTERNAL_GL_APIENTRY glLineWidthNULL(GLfloat width)
+{
+}
+
+void INTERNAL_GL_APIENTRY glLinkProgramNULL(GLuint program)
+{
+}
+
+void INTERNAL_GL_APIENTRY glLogicOpNULL(GLenum opcode)
+{
+}
+
+void *INTERNAL_GL_APIENTRY glMapBufferNULL(GLenum target, GLenum access)
+{
+    return static_cast<void *>(0);
+}
+
+void *INTERNAL_GL_APIENTRY glMapBufferRangeNULL(GLenum target,
+                                                GLintptr offset,
+                                                GLsizeiptr length,
+                                                GLbitfield access)
+{
+    return static_cast<void *>(0);
+}
+
+void *INTERNAL_GL_APIENTRY glMapNamedBufferNULL(GLuint buffer, GLenum access)
+{
+    return static_cast<void *>(0);
+}
+
+void *INTERNAL_GL_APIENTRY glMapNamedBufferRangeNULL(GLuint buffer,
+                                                     GLintptr offset,
+                                                     GLsizeiptr length,
+                                                     GLbitfield access)
+{
+    return static_cast<void *>(0);
+}
+
+void INTERNAL_GL_APIENTRY glMatrixLoadfEXTNULL(GLenum mode, const GLfloat *m)
+{
+}
+
+void INTERNAL_GL_APIENTRY glMemoryBarrierNULL(GLbitfield barriers)
+{
+}
+
+void INTERNAL_GL_APIENTRY glMemoryBarrierByRegionNULL(GLbitfield barriers)
+{
+}
+
+void INTERNAL_GL_APIENTRY glMinSampleShadingNULL(GLfloat value)
+{
+}
+
+void INTERNAL_GL_APIENTRY glMultiDrawArraysNULL(GLenum mode,
+                                                const GLint *first,
+                                                const GLsizei *count,
+                                                GLsizei drawcount)
+{
+}
+
+void INTERNAL_GL_APIENTRY glMultiDrawArraysIndirectNULL(GLenum mode,
+                                                        const void *indirect,
+                                                        GLsizei drawcount,
+                                                        GLsizei stride)
+{
+}
+
+void INTERNAL_GL_APIENTRY glMultiDrawElementsNULL(GLenum mode,
+                                                  const GLsizei *count,
+                                                  GLenum type,
+                                                  const void *const *indices,
+                                                  GLsizei drawcount)
+{
+}
+
+void INTERNAL_GL_APIENTRY glMultiDrawElementsBaseVertexNULL(GLenum mode,
+                                                            const GLsizei *count,
+                                                            GLenum type,
+                                                            const void *const *indices,
+                                                            GLsizei drawcount,
+                                                            const GLint *basevertex)
+{
+}
+
+void INTERNAL_GL_APIENTRY glMultiDrawElementsIndirectNULL(GLenum mode,
+                                                          GLenum type,
+                                                          const void *indirect,
+                                                          GLsizei drawcount,
+                                                          GLsizei stride)
+{
+}
+
+void INTERNAL_GL_APIENTRY glNamedBufferDataNULL(GLuint buffer,
+                                                GLsizeiptr size,
+                                                const void *data,
+                                                GLenum usage)
+{
+}
+
+void INTERNAL_GL_APIENTRY glNamedBufferStorageNULL(GLuint buffer,
+                                                   GLsizeiptr size,
+                                                   const void *data,
+                                                   GLbitfield flags)
+{
+}
+
+void INTERNAL_GL_APIENTRY glNamedBufferSubDataNULL(GLuint buffer,
+                                                   GLintptr offset,
+                                                   GLsizeiptr size,
+                                                   const void *data)
+{
+}
+
+void INTERNAL_GL_APIENTRY glNamedFramebufferDrawBufferNULL(GLuint framebuffer, GLenum buf)
+{
+}
+
+void INTERNAL_GL_APIENTRY glNamedFramebufferDrawBuffersNULL(GLuint framebuffer,
+                                                            GLsizei n,
+                                                            const GLenum *bufs)
+{
+}
+
+void INTERNAL_GL_APIENTRY glNamedFramebufferParameteriNULL(GLuint framebuffer,
+                                                           GLenum pname,
+                                                           GLint param)
+{
+}
+
+void INTERNAL_GL_APIENTRY glNamedFramebufferReadBufferNULL(GLuint framebuffer, GLenum src)
+{
+}
+
+void INTERNAL_GL_APIENTRY glNamedFramebufferRenderbufferNULL(GLuint framebuffer,
+                                                             GLenum attachment,
+                                                             GLenum renderbuffertarget,
+                                                             GLuint renderbuffer)
+{
+}
+
+void INTERNAL_GL_APIENTRY glNamedFramebufferTextureNULL(GLuint framebuffer,
+                                                        GLenum attachment,
+                                                        GLuint texture,
+                                                        GLint level)
+{
+}
+
+void INTERNAL_GL_APIENTRY glNamedFramebufferTextureLayerNULL(GLuint framebuffer,
+                                                             GLenum attachment,
+                                                             GLuint texture,
+                                                             GLint level,
+                                                             GLint layer)
+{
+}
+
+void INTERNAL_GL_APIENTRY glNamedRenderbufferStorageNULL(GLuint renderbuffer,
+                                                         GLenum internalformat,
+                                                         GLsizei width,
+                                                         GLsizei height)
+{
+}
+
+void INTERNAL_GL_APIENTRY glNamedRenderbufferStorageMultisampleNULL(GLuint renderbuffer,
+                                                                    GLsizei samples,
+                                                                    GLenum internalformat,
+                                                                    GLsizei width,
+                                                                    GLsizei height)
+{
+}
+
+void INTERNAL_GL_APIENTRY glObjectLabelNULL(GLenum identifier,
+                                            GLuint name,
+                                            GLsizei length,
+                                            const GLchar *label)
+{
+}
+
+void INTERNAL_GL_APIENTRY glObjectPtrLabelNULL(const void *ptr, GLsizei length, const GLchar *label)
+{
+}
+
+void INTERNAL_GL_APIENTRY glPatchParameterfvNULL(GLenum pname, const GLfloat *values)
+{
+}
+
+void INTERNAL_GL_APIENTRY glPatchParameteriNULL(GLenum pname, GLint value)
+{
+}
+
+void INTERNAL_GL_APIENTRY glPathCommandsNVNULL(GLuint path,
+                                               GLsizei numCommands,
+                                               const GLubyte *commands,
+                                               GLsizei numCoords,
+                                               GLenum coordType,
+                                               const void *coords)
+{
+}
+
+void INTERNAL_GL_APIENTRY glPathParameterfNVNULL(GLuint path, GLenum pname, GLfloat value)
+{
+}
+
+void INTERNAL_GL_APIENTRY glPathParameteriNVNULL(GLuint path, GLenum pname, GLint value)
+{
+}
+
+void INTERNAL_GL_APIENTRY glPathStencilFuncNVNULL(GLenum func, GLint ref, GLuint mask)
+{
+}
+
+void INTERNAL_GL_APIENTRY glPauseTransformFeedbackNULL()
+{
+}
+
+void INTERNAL_GL_APIENTRY glPixelStorefNULL(GLenum pname, GLfloat param)
+{
+}
+
+void INTERNAL_GL_APIENTRY glPixelStoreiNULL(GLenum pname, GLint param)
+{
+}
+
+void INTERNAL_GL_APIENTRY glPointParameterfNULL(GLenum pname, GLfloat param)
+{
+}
+
+void INTERNAL_GL_APIENTRY glPointParameterfvNULL(GLenum pname, const GLfloat *params)
+{
+}
+
+void INTERNAL_GL_APIENTRY glPointParameteriNULL(GLenum pname, GLint param)
+{
+}
+
+void INTERNAL_GL_APIENTRY glPointParameterivNULL(GLenum pname, const GLint *params)
+{
+}
+
+void INTERNAL_GL_APIENTRY glPointSizeNULL(GLfloat size)
+{
+}
+
+void INTERNAL_GL_APIENTRY glPolygonModeNULL(GLenum face, GLenum mode)
+{
+}
+
+void INTERNAL_GL_APIENTRY glPolygonOffsetNULL(GLfloat factor, GLfloat units)
+{
+}
+
+void INTERNAL_GL_APIENTRY glPopDebugGroupNULL()
+{
+}
+
+void INTERNAL_GL_APIENTRY glPopGroupMarkerEXTNULL()
+{
+}
+
+void INTERNAL_GL_APIENTRY glPrimitiveBoundingBoxNULL(GLfloat minX,
+                                                     GLfloat minY,
+                                                     GLfloat minZ,
+                                                     GLfloat minW,
+                                                     GLfloat maxX,
+                                                     GLfloat maxY,
+                                                     GLfloat maxZ,
+                                                     GLfloat maxW)
+{
+}
+
+void INTERNAL_GL_APIENTRY glPrimitiveRestartIndexNULL(GLuint index)
+{
+}
+
+void INTERNAL_GL_APIENTRY glProgramBinaryNULL(GLuint program,
+                                              GLenum binaryFormat,
+                                              const void *binary,
+                                              GLsizei length)
+{
+}
+
+void INTERNAL_GL_APIENTRY glProgramParameteriNULL(GLuint program, GLenum pname, GLint value)
+{
+}
+
+void INTERNAL_GL_APIENTRY glProgramPathFragmentInputGenNVNULL(GLuint program,
+                                                              GLint location,
+                                                              GLenum genMode,
+                                                              GLint components,
+                                                              const GLfloat *coeffs)
+{
+}
+
+void INTERNAL_GL_APIENTRY glProgramUniform1dNULL(GLuint program, GLint location, GLdouble v0)
+{
+}
+
+void INTERNAL_GL_APIENTRY glProgramUniform1dvNULL(GLuint program,
+                                                  GLint location,
+                                                  GLsizei count,
+                                                  const GLdouble *value)
+{
+}
+
+void INTERNAL_GL_APIENTRY glProgramUniform1fNULL(GLuint program, GLint location, GLfloat v0)
+{
+}
+
+void INTERNAL_GL_APIENTRY glProgramUniform1fvNULL(GLuint program,
+                                                  GLint location,
+                                                  GLsizei count,
+                                                  const GLfloat *value)
+{
+}
+
+void INTERNAL_GL_APIENTRY glProgramUniform1iNULL(GLuint program, GLint location, GLint v0)
+{
+}
+
+void INTERNAL_GL_APIENTRY glProgramUniform1ivNULL(GLuint program,
+                                                  GLint location,
+                                                  GLsizei count,
+                                                  const GLint *value)
+{
+}
+
+void INTERNAL_GL_APIENTRY glProgramUniform1uiNULL(GLuint program, GLint location, GLuint v0)
+{
+}
+
+void INTERNAL_GL_APIENTRY glProgramUniform1uivNULL(GLuint program,
+                                                   GLint location,
+                                                   GLsizei count,
+                                                   const GLuint *value)
+{
+}
+
+void INTERNAL_GL_APIENTRY glProgramUniform2dNULL(GLuint program,
+                                                 GLint location,
+                                                 GLdouble v0,
+                                                 GLdouble v1)
+{
+}
+
+void INTERNAL_GL_APIENTRY glProgramUniform2dvNULL(GLuint program,
+                                                  GLint location,
+                                                  GLsizei count,
+                                                  const GLdouble *value)
+{
+}
+
+void INTERNAL_GL_APIENTRY glProgramUniform2fNULL(GLuint program,
+                                                 GLint location,
+                                                 GLfloat v0,
+                                                 GLfloat v1)
+{
+}
+
+void INTERNAL_GL_APIENTRY glProgramUniform2fvNULL(GLuint program,
+                                                  GLint location,
+                                                  GLsizei count,
+                                                  const GLfloat *value)
+{
+}
+
+void INTERNAL_GL_APIENTRY glProgramUniform2iNULL(GLuint program, GLint location, GLint v0, GLint v1)
+{
+}
+
+void INTERNAL_GL_APIENTRY glProgramUniform2ivNULL(GLuint program,
+                                                  GLint location,
+                                                  GLsizei count,
+                                                  const GLint *value)
+{
+}
+
+void INTERNAL_GL_APIENTRY glProgramUniform2uiNULL(GLuint program,
+                                                  GLint location,
+                                                  GLuint v0,
+                                                  GLuint v1)
+{
+}
+
+void INTERNAL_GL_APIENTRY glProgramUniform2uivNULL(GLuint program,
+                                                   GLint location,
+                                                   GLsizei count,
+                                                   const GLuint *value)
+{
+}
+
+void INTERNAL_GL_APIENTRY
+glProgramUniform3dNULL(GLuint program, GLint location, GLdouble v0, GLdouble v1, GLdouble v2)
+{
+}
+
+void INTERNAL_GL_APIENTRY glProgramUniform3dvNULL(GLuint program,
+                                                  GLint location,
+                                                  GLsizei count,
+                                                  const GLdouble *value)
+{
+}
+
+void INTERNAL_GL_APIENTRY
+glProgramUniform3fNULL(GLuint program, GLint location, GLfloat v0, GLfloat v1, GLfloat v2)
+{
+}
+
+void INTERNAL_GL_APIENTRY glProgramUniform3fvNULL(GLuint program,
+                                                  GLint location,
+                                                  GLsizei count,
+                                                  const GLfloat *value)
+{
+}
+
+void INTERNAL_GL_APIENTRY
+glProgramUniform3iNULL(GLuint program, GLint location, GLint v0, GLint v1, GLint v2)
+{
+}
+
+void INTERNAL_GL_APIENTRY glProgramUniform3ivNULL(GLuint program,
+                                                  GLint location,
+                                                  GLsizei count,
+                                                  const GLint *value)
+{
+}
+
+void INTERNAL_GL_APIENTRY
+glProgramUniform3uiNULL(GLuint program, GLint location, GLuint v0, GLuint v1, GLuint v2)
+{
+}
+
+void INTERNAL_GL_APIENTRY glProgramUniform3uivNULL(GLuint program,
+                                                   GLint location,
+                                                   GLsizei count,
+                                                   const GLuint *value)
+{
+}
+
+void INTERNAL_GL_APIENTRY glProgramUniform4dNULL(GLuint program,
+                                                 GLint location,
+                                                 GLdouble v0,
+                                                 GLdouble v1,
+                                                 GLdouble v2,
+                                                 GLdouble v3)
+{
+}
+
+void INTERNAL_GL_APIENTRY glProgramUniform4dvNULL(GLuint program,
+                                                  GLint location,
+                                                  GLsizei count,
+                                                  const GLdouble *value)
+{
+}
+
+void INTERNAL_GL_APIENTRY glProgramUniform4fNULL(GLuint program,
+                                                 GLint location,
+                                                 GLfloat v0,
+                                                 GLfloat v1,
+                                                 GLfloat v2,
+                                                 GLfloat v3)
+{
+}
+
+void INTERNAL_GL_APIENTRY glProgramUniform4fvNULL(GLuint program,
+                                                  GLint location,
+                                                  GLsizei count,
+                                                  const GLfloat *value)
+{
+}
+
+void INTERNAL_GL_APIENTRY
+glProgramUniform4iNULL(GLuint program, GLint location, GLint v0, GLint v1, GLint v2, GLint v3)
+{
+}
+
+void INTERNAL_GL_APIENTRY glProgramUniform4ivNULL(GLuint program,
+                                                  GLint location,
+                                                  GLsizei count,
+                                                  const GLint *value)
+{
+}
+
+void INTERNAL_GL_APIENTRY
+glProgramUniform4uiNULL(GLuint program, GLint location, GLuint v0, GLuint v1, GLuint v2, GLuint v3)
+{
+}
+
+void INTERNAL_GL_APIENTRY glProgramUniform4uivNULL(GLuint program,
+                                                   GLint location,
+                                                   GLsizei count,
+                                                   const GLuint *value)
+{
+}
+
+void INTERNAL_GL_APIENTRY glProgramUniformMatrix2dvNULL(GLuint program,
+                                                        GLint location,
+                                                        GLsizei count,
+                                                        GLboolean transpose,
+                                                        const GLdouble *value)
+{
+}
+
+void INTERNAL_GL_APIENTRY glProgramUniformMatrix2fvNULL(GLuint program,
+                                                        GLint location,
+                                                        GLsizei count,
+                                                        GLboolean transpose,
+                                                        const GLfloat *value)
+{
+}
+
+void INTERNAL_GL_APIENTRY glProgramUniformMatrix2x3dvNULL(GLuint program,
+                                                          GLint location,
+                                                          GLsizei count,
+                                                          GLboolean transpose,
+                                                          const GLdouble *value)
+{
+}
+
+void INTERNAL_GL_APIENTRY glProgramUniformMatrix2x3fvNULL(GLuint program,
+                                                          GLint location,
+                                                          GLsizei count,
+                                                          GLboolean transpose,
+                                                          const GLfloat *value)
+{
+}
+
+void INTERNAL_GL_APIENTRY glProgramUniformMatrix2x4dvNULL(GLuint program,
+                                                          GLint location,
+                                                          GLsizei count,
+                                                          GLboolean transpose,
+                                                          const GLdouble *value)
+{
+}
+
+void INTERNAL_GL_APIENTRY glProgramUniformMatrix2x4fvNULL(GLuint program,
+                                                          GLint location,
+                                                          GLsizei count,
+                                                          GLboolean transpose,
+                                                          const GLfloat *value)
+{
+}
+
+void INTERNAL_GL_APIENTRY glProgramUniformMatrix3dvNULL(GLuint program,
+                                                        GLint location,
+                                                        GLsizei count,
+                                                        GLboolean transpose,
+                                                        const GLdouble *value)
+{
+}
+
+void INTERNAL_GL_APIENTRY glProgramUniformMatrix3fvNULL(GLuint program,
+                                                        GLint location,
+                                                        GLsizei count,
+                                                        GLboolean transpose,
+                                                        const GLfloat *value)
+{
+}
+
+void INTERNAL_GL_APIENTRY glProgramUniformMatrix3x2dvNULL(GLuint program,
+                                                          GLint location,
+                                                          GLsizei count,
+                                                          GLboolean transpose,
+                                                          const GLdouble *value)
+{
+}
+
+void INTERNAL_GL_APIENTRY glProgramUniformMatrix3x2fvNULL(GLuint program,
+                                                          GLint location,
+                                                          GLsizei count,
+                                                          GLboolean transpose,
+                                                          const GLfloat *value)
+{
+}
+
+void INTERNAL_GL_APIENTRY glProgramUniformMatrix3x4dvNULL(GLuint program,
+                                                          GLint location,
+                                                          GLsizei count,
+                                                          GLboolean transpose,
+                                                          const GLdouble *value)
+{
+}
+
+void INTERNAL_GL_APIENTRY glProgramUniformMatrix3x4fvNULL(GLuint program,
+                                                          GLint location,
+                                                          GLsizei count,
+                                                          GLboolean transpose,
+                                                          const GLfloat *value)
+{
+}
+
+void INTERNAL_GL_APIENTRY glProgramUniformMatrix4dvNULL(GLuint program,
+                                                        GLint location,
+                                                        GLsizei count,
+                                                        GLboolean transpose,
+                                                        const GLdouble *value)
+{
+}
+
+void INTERNAL_GL_APIENTRY glProgramUniformMatrix4fvNULL(GLuint program,
+                                                        GLint location,
+                                                        GLsizei count,
+                                                        GLboolean transpose,
+                                                        const GLfloat *value)
+{
+}
+
+void INTERNAL_GL_APIENTRY glProgramUniformMatrix4x2dvNULL(GLuint program,
+                                                          GLint location,
+                                                          GLsizei count,
+                                                          GLboolean transpose,
+                                                          const GLdouble *value)
+{
+}
+
+void INTERNAL_GL_APIENTRY glProgramUniformMatrix4x2fvNULL(GLuint program,
+                                                          GLint location,
+                                                          GLsizei count,
+                                                          GLboolean transpose,
+                                                          const GLfloat *value)
+{
+}
+
+void INTERNAL_GL_APIENTRY glProgramUniformMatrix4x3dvNULL(GLuint program,
+                                                          GLint location,
+                                                          GLsizei count,
+                                                          GLboolean transpose,
+                                                          const GLdouble *value)
+{
+}
+
+void INTERNAL_GL_APIENTRY glProgramUniformMatrix4x3fvNULL(GLuint program,
+                                                          GLint location,
+                                                          GLsizei count,
+                                                          GLboolean transpose,
+                                                          const GLfloat *value)
+{
+}
+
+void INTERNAL_GL_APIENTRY glProvokingVertexNULL(GLenum mode)
+{
+}
+
+void INTERNAL_GL_APIENTRY glPushDebugGroupNULL(GLenum source,
+                                               GLuint id,
+                                               GLsizei length,
+                                               const GLchar *message)
+{
+}
+
+void INTERNAL_GL_APIENTRY glPushGroupMarkerEXTNULL(GLsizei length, const GLchar *marker)
+{
+}
+
+void INTERNAL_GL_APIENTRY glQueryCounterNULL(GLuint id, GLenum target)
+{
+}
+
+void INTERNAL_GL_APIENTRY glReadBufferNULL(GLenum src)
+{
+}
+
+void INTERNAL_GL_APIENTRY glReadPixelsNULL(GLint x,
+                                           GLint y,
+                                           GLsizei width,
+                                           GLsizei height,
+                                           GLenum format,
+                                           GLenum type,
+                                           void *pixels)
+{
+}
+
+void INTERNAL_GL_APIENTRY glReadnPixelsNULL(GLint x,
+                                            GLint y,
+                                            GLsizei width,
+                                            GLsizei height,
+                                            GLenum format,
+                                            GLenum type,
+                                            GLsizei bufSize,
+                                            void *data)
+{
+}
+
+void INTERNAL_GL_APIENTRY glReleaseShaderCompilerNULL()
+{
+}
+
+void INTERNAL_GL_APIENTRY glRenderbufferStorageNULL(GLenum target,
+                                                    GLenum internalformat,
+                                                    GLsizei width,
+                                                    GLsizei height)
+{
+}
+
+void INTERNAL_GL_APIENTRY glRenderbufferStorageMultisampleNULL(GLenum target,
+                                                               GLsizei samples,
+                                                               GLenum internalformat,
+                                                               GLsizei width,
+                                                               GLsizei height)
+{
+}
+
+void INTERNAL_GL_APIENTRY glResumeTransformFeedbackNULL()
+{
+}
+
+void INTERNAL_GL_APIENTRY glSampleCoverageNULL(GLfloat value, GLboolean invert)
+{
+}
+
+void INTERNAL_GL_APIENTRY glSampleMaskiNULL(GLuint maskNumber, GLbitfield mask)
+{
+}
+
+void INTERNAL_GL_APIENTRY glSamplerParameterIivNULL(GLuint sampler,
+                                                    GLenum pname,
+                                                    const GLint *param)
+{
+}
+
+void INTERNAL_GL_APIENTRY glSamplerParameterIuivNULL(GLuint sampler,
+                                                     GLenum pname,
+                                                     const GLuint *param)
+{
+}
+
+void INTERNAL_GL_APIENTRY glSamplerParameterfNULL(GLuint sampler, GLenum pname, GLfloat param)
+{
+}
+
+void INTERNAL_GL_APIENTRY glSamplerParameterfvNULL(GLuint sampler,
+                                                   GLenum pname,
+                                                   const GLfloat *param)
+{
+}
+
+void INTERNAL_GL_APIENTRY glSamplerParameteriNULL(GLuint sampler, GLenum pname, GLint param)
+{
+}
+
+void INTERNAL_GL_APIENTRY glSamplerParameterivNULL(GLuint sampler, GLenum pname, const GLint *param)
+{
+}
+
+void INTERNAL_GL_APIENTRY glScissorNULL(GLint x, GLint y, GLsizei width, GLsizei height)
+{
+}
+
+void INTERNAL_GL_APIENTRY glScissorArrayvNULL(GLuint first, GLsizei count, const GLint *v)
+{
+}
+
+void INTERNAL_GL_APIENTRY
+glScissorIndexedNULL(GLuint index, GLint left, GLint bottom, GLsizei width, GLsizei height)
+{
+}
+
+void INTERNAL_GL_APIENTRY glScissorIndexedvNULL(GLuint index, const GLint *v)
+{
+}
+
+void INTERNAL_GL_APIENTRY glSetFenceNVNULL(GLuint fence, GLenum condition)
+{
+}
+
+void INTERNAL_GL_APIENTRY glShaderBinaryNULL(GLsizei count,
+                                             const GLuint *shaders,
+                                             GLenum binaryformat,
+                                             const void *binary,
+                                             GLsizei length)
+{
+}
+
+void INTERNAL_GL_APIENTRY glShaderSourceNULL(GLuint shader,
+                                             GLsizei count,
+                                             const GLchar *const *string,
+                                             const GLint *length)
+{
+}
+
+void INTERNAL_GL_APIENTRY glShaderStorageBlockBindingNULL(GLuint program,
+                                                          GLuint storageBlockIndex,
+                                                          GLuint storageBlockBinding)
+{
+}
+
+void INTERNAL_GL_APIENTRY glStencilFillPathInstancedNVNULL(GLsizei numPaths,
+                                                           GLenum pathNameType,
+                                                           const void *paths,
+                                                           GLuint pathBase,
+                                                           GLenum fillMode,
+                                                           GLuint mask,
+                                                           GLenum transformType,
+                                                           const GLfloat *transformValues)
+{
+}
+
+void INTERNAL_GL_APIENTRY glStencilFillPathNVNULL(GLuint path, GLenum fillMode, GLuint mask)
+{
+}
+
+void INTERNAL_GL_APIENTRY glStencilFuncNULL(GLenum func, GLint ref, GLuint mask)
+{
+}
+
+void INTERNAL_GL_APIENTRY glStencilFuncSeparateNULL(GLenum face,
+                                                    GLenum func,
+                                                    GLint ref,
+                                                    GLuint mask)
+{
+}
+
+void INTERNAL_GL_APIENTRY glStencilMaskNULL(GLuint mask)
+{
+}
+
+void INTERNAL_GL_APIENTRY glStencilMaskSeparateNULL(GLenum face, GLuint mask)
+{
+}
+
+void INTERNAL_GL_APIENTRY glStencilOpNULL(GLenum fail, GLenum zfail, GLenum zpass)
+{
+}
+
+void INTERNAL_GL_APIENTRY glStencilOpSeparateNULL(GLenum face,
+                                                  GLenum sfail,
+                                                  GLenum dpfail,
+                                                  GLenum dppass)
+{
+}
+
+void INTERNAL_GL_APIENTRY glStencilStrokePathInstancedNVNULL(GLsizei numPaths,
+                                                             GLenum pathNameType,
+                                                             const void *paths,
+                                                             GLuint pathBase,
+                                                             GLint reference,
+                                                             GLuint mask,
+                                                             GLenum transformType,
+                                                             const GLfloat *transformValues)
+{
+}
+
+void INTERNAL_GL_APIENTRY glStencilStrokePathNVNULL(GLuint path, GLint reference, GLuint mask)
+{
+}
+
+void INTERNAL_GL_APIENTRY glStencilThenCoverFillPathInstancedNVNULL(GLsizei numPaths,
+                                                                    GLenum pathNameType,
+                                                                    const void *paths,
+                                                                    GLuint pathBase,
+                                                                    GLenum fillMode,
+                                                                    GLuint mask,
+                                                                    GLenum coverMode,
+                                                                    GLenum transformType,
+                                                                    const GLfloat *transformValues)
+{
+}
+
+void INTERNAL_GL_APIENTRY glStencilThenCoverFillPathNVNULL(GLuint path,
+                                                           GLenum fillMode,
+                                                           GLuint mask,
+                                                           GLenum coverMode)
+{
+}
+
+void INTERNAL_GL_APIENTRY
+glStencilThenCoverStrokePathInstancedNVNULL(GLsizei numPaths,
+                                            GLenum pathNameType,
+                                            const void *paths,
+                                            GLuint pathBase,
+                                            GLint reference,
+                                            GLuint mask,
+                                            GLenum coverMode,
+                                            GLenum transformType,
+                                            const GLfloat *transformValues)
+{
+}
+
+void INTERNAL_GL_APIENTRY glStencilThenCoverStrokePathNVNULL(GLuint path,
+                                                             GLint reference,
+                                                             GLuint mask,
+                                                             GLenum coverMode)
+{
+}
+
+GLboolean INTERNAL_GL_APIENTRY glTestFenceNVNULL(GLuint fence)
+{
+    return static_cast<GLboolean>(0);
+}
+
+void INTERNAL_GL_APIENTRY glTexBufferNULL(GLenum target, GLenum internalformat, GLuint buffer)
+{
+}
+
+void INTERNAL_GL_APIENTRY glTexBufferRangeNULL(GLenum target,
+                                               GLenum internalformat,
+                                               GLuint buffer,
+                                               GLintptr offset,
+                                               GLsizeiptr size)
+{
+}
+
+void INTERNAL_GL_APIENTRY glTexImage1DNULL(GLenum target,
+                                           GLint level,
+                                           GLint internalformat,
+                                           GLsizei width,
+                                           GLint border,
+                                           GLenum format,
+                                           GLenum type,
+                                           const void *pixels)
+{
+}
+
+void INTERNAL_GL_APIENTRY glTexImage2DNULL(GLenum target,
+                                           GLint level,
+                                           GLint internalformat,
+                                           GLsizei width,
+                                           GLsizei height,
+                                           GLint border,
+                                           GLenum format,
+                                           GLenum type,
+                                           const void *pixels)
+{
+}
+
+void INTERNAL_GL_APIENTRY glTexImage2DMultisampleNULL(GLenum target,
+                                                      GLsizei samples,
+                                                      GLenum internalformat,
+                                                      GLsizei width,
+                                                      GLsizei height,
+                                                      GLboolean fixedsamplelocations)
+{
+}
+
+void INTERNAL_GL_APIENTRY glTexImage3DNULL(GLenum target,
+                                           GLint level,
+                                           GLint internalformat,
+                                           GLsizei width,
+                                           GLsizei height,
+                                           GLsizei depth,
+                                           GLint border,
+                                           GLenum format,
+                                           GLenum type,
+                                           const void *pixels)
+{
+}
+
+void INTERNAL_GL_APIENTRY glTexImage3DMultisampleNULL(GLenum target,
+                                                      GLsizei samples,
+                                                      GLenum internalformat,
+                                                      GLsizei width,
+                                                      GLsizei height,
+                                                      GLsizei depth,
+                                                      GLboolean fixedsamplelocations)
+{
+}
+
+void INTERNAL_GL_APIENTRY glTexParameterIivNULL(GLenum target, GLenum pname, const GLint *params)
+{
+}
+
+void INTERNAL_GL_APIENTRY glTexParameterIuivNULL(GLenum target, GLenum pname, const GLuint *params)
+{
+}
+
+void INTERNAL_GL_APIENTRY glTexParameterfNULL(GLenum target, GLenum pname, GLfloat param)
+{
+}
+
+void INTERNAL_GL_APIENTRY glTexParameterfvNULL(GLenum target, GLenum pname, const GLfloat *params)
+{
+}
+
+void INTERNAL_GL_APIENTRY glTexParameteriNULL(GLenum target, GLenum pname, GLint param)
+{
+}
+
+void INTERNAL_GL_APIENTRY glTexParameterivNULL(GLenum target, GLenum pname, const GLint *params)
+{
+}
+
+void INTERNAL_GL_APIENTRY glTexStorage1DNULL(GLenum target,
+                                             GLsizei levels,
+                                             GLenum internalformat,
+                                             GLsizei width)
+{
+}
+
+void INTERNAL_GL_APIENTRY glTexStorage2DNULL(GLenum target,
+                                             GLsizei levels,
+                                             GLenum internalformat,
+                                             GLsizei width,
+                                             GLsizei height)
+{
+}
+
+void INTERNAL_GL_APIENTRY glTexStorage2DMultisampleNULL(GLenum target,
+                                                        GLsizei samples,
+                                                        GLenum internalformat,
+                                                        GLsizei width,
+                                                        GLsizei height,
+                                                        GLboolean fixedsamplelocations)
+{
+}
+
+void INTERNAL_GL_APIENTRY glTexStorage3DNULL(GLenum target,
+                                             GLsizei levels,
+                                             GLenum internalformat,
+                                             GLsizei width,
+                                             GLsizei height,
+                                             GLsizei depth)
+{
+}
+
+void INTERNAL_GL_APIENTRY glTexStorage3DMultisampleNULL(GLenum target,
+                                                        GLsizei samples,
+                                                        GLenum internalformat,
+                                                        GLsizei width,
+                                                        GLsizei height,
+                                                        GLsizei depth,
+                                                        GLboolean fixedsamplelocations)
+{
+}
+
+void INTERNAL_GL_APIENTRY glTexSubImage1DNULL(GLenum target,
+                                              GLint level,
+                                              GLint xoffset,
+                                              GLsizei width,
+                                              GLenum format,
+                                              GLenum type,
+                                              const void *pixels)
+{
+}
+
+void INTERNAL_GL_APIENTRY glTexSubImage2DNULL(GLenum target,
+                                              GLint level,
+                                              GLint xoffset,
+                                              GLint yoffset,
+                                              GLsizei width,
+                                              GLsizei height,
+                                              GLenum format,
+                                              GLenum type,
+                                              const void *pixels)
+{
+}
+
+void INTERNAL_GL_APIENTRY glTexSubImage3DNULL(GLenum target,
+                                              GLint level,
+                                              GLint xoffset,
+                                              GLint yoffset,
+                                              GLint zoffset,
+                                              GLsizei width,
+                                              GLsizei height,
+                                              GLsizei depth,
+                                              GLenum format,
+                                              GLenum type,
+                                              const void *pixels)
+{
+}
+
+void INTERNAL_GL_APIENTRY glTextureBarrierNULL()
+{
+}
+
+void INTERNAL_GL_APIENTRY glTextureBufferNULL(GLuint texture, GLenum internalformat, GLuint buffer)
+{
+}
+
+void INTERNAL_GL_APIENTRY glTextureBufferRangeNULL(GLuint texture,
+                                                   GLenum internalformat,
+                                                   GLuint buffer,
+                                                   GLintptr offset,
+                                                   GLsizeiptr size)
+{
+}
+
+void INTERNAL_GL_APIENTRY glTextureParameterIivNULL(GLuint texture,
+                                                    GLenum pname,
+                                                    const GLint *params)
+{
+}
+
+void INTERNAL_GL_APIENTRY glTextureParameterIuivNULL(GLuint texture,
+                                                     GLenum pname,
+                                                     const GLuint *params)
+{
+}
+
+void INTERNAL_GL_APIENTRY glTextureParameterfNULL(GLuint texture, GLenum pname, GLfloat param)
+{
+}
+
+void INTERNAL_GL_APIENTRY glTextureParameterfvNULL(GLuint texture,
+                                                   GLenum pname,
+                                                   const GLfloat *param)
+{
+}
+
+void INTERNAL_GL_APIENTRY glTextureParameteriNULL(GLuint texture, GLenum pname, GLint param)
+{
+}
+
+void INTERNAL_GL_APIENTRY glTextureParameterivNULL(GLuint texture, GLenum pname, const GLint *param)
+{
+}
+
+void INTERNAL_GL_APIENTRY glTextureStorage1DNULL(GLuint texture,
+                                                 GLsizei levels,
+                                                 GLenum internalformat,
+                                                 GLsizei width)
+{
+}
+
+void INTERNAL_GL_APIENTRY glTextureStorage2DNULL(GLuint texture,
+                                                 GLsizei levels,
+                                                 GLenum internalformat,
+                                                 GLsizei width,
+                                                 GLsizei height)
+{
+}
+
+void INTERNAL_GL_APIENTRY glTextureStorage2DMultisampleNULL(GLuint texture,
+                                                            GLsizei samples,
+                                                            GLenum internalformat,
+                                                            GLsizei width,
+                                                            GLsizei height,
+                                                            GLboolean fixedsamplelocations)
+{
+}
+
+void INTERNAL_GL_APIENTRY glTextureStorage3DNULL(GLuint texture,
+                                                 GLsizei levels,
+                                                 GLenum internalformat,
+                                                 GLsizei width,
+                                                 GLsizei height,
+                                                 GLsizei depth)
+{
+}
+
+void INTERNAL_GL_APIENTRY glTextureStorage3DMultisampleNULL(GLuint texture,
+                                                            GLsizei samples,
+                                                            GLenum internalformat,
+                                                            GLsizei width,
+                                                            GLsizei height,
+                                                            GLsizei depth,
+                                                            GLboolean fixedsamplelocations)
+{
+}
+
+void INTERNAL_GL_APIENTRY glTextureSubImage1DNULL(GLuint texture,
+                                                  GLint level,
+                                                  GLint xoffset,
+                                                  GLsizei width,
+                                                  GLenum format,
+                                                  GLenum type,
+                                                  const void *pixels)
+{
+}
+
+void INTERNAL_GL_APIENTRY glTextureSubImage2DNULL(GLuint texture,
+                                                  GLint level,
+                                                  GLint xoffset,
+                                                  GLint yoffset,
+                                                  GLsizei width,
+                                                  GLsizei height,
+                                                  GLenum format,
+                                                  GLenum type,
+                                                  const void *pixels)
+{
+}
+
+void INTERNAL_GL_APIENTRY glTextureSubImage3DNULL(GLuint texture,
+                                                  GLint level,
+                                                  GLint xoffset,
+                                                  GLint yoffset,
+                                                  GLint zoffset,
+                                                  GLsizei width,
+                                                  GLsizei height,
+                                                  GLsizei depth,
+                                                  GLenum format,
+                                                  GLenum type,
+                                                  const void *pixels)
+{
+}
+
+void INTERNAL_GL_APIENTRY glTextureViewNULL(GLuint texture,
+                                            GLenum target,
+                                            GLuint origtexture,
+                                            GLenum internalformat,
+                                            GLuint minlevel,
+                                            GLuint numlevels,
+                                            GLuint minlayer,
+                                            GLuint numlayers)
+{
+}
+
+void INTERNAL_GL_APIENTRY glTransformFeedbackBufferBaseNULL(GLuint xfb, GLuint index, GLuint buffer)
+{
+}
+
+void INTERNAL_GL_APIENTRY glTransformFeedbackBufferRangeNULL(GLuint xfb,
+                                                             GLuint index,
+                                                             GLuint buffer,
+                                                             GLintptr offset,
+                                                             GLsizeiptr size)
+{
+}
+
+void INTERNAL_GL_APIENTRY glTransformFeedbackVaryingsNULL(GLuint program,
+                                                          GLsizei count,
+                                                          const GLchar *const *varyings,
+                                                          GLenum bufferMode)
+{
+}
+
+void INTERNAL_GL_APIENTRY glUniform1dNULL(GLint location, GLdouble x)
+{
+}
+
+void INTERNAL_GL_APIENTRY glUniform1dvNULL(GLint location, GLsizei count, const GLdouble *value)
+{
+}
+
+void INTERNAL_GL_APIENTRY glUniform1fNULL(GLint location, GLfloat v0)
+{
+}
+
+void INTERNAL_GL_APIENTRY glUniform1fvNULL(GLint location, GLsizei count, const GLfloat *value)
+{
+}
+
+void INTERNAL_GL_APIENTRY glUniform1iNULL(GLint location, GLint v0)
+{
+}
+
+void INTERNAL_GL_APIENTRY glUniform1ivNULL(GLint location, GLsizei count, const GLint *value)
+{
+}
+
+void INTERNAL_GL_APIENTRY glUniform1uiNULL(GLint location, GLuint v0)
+{
+}
+
+void INTERNAL_GL_APIENTRY glUniform1uivNULL(GLint location, GLsizei count, const GLuint *value)
+{
+}
+
+void INTERNAL_GL_APIENTRY glUniform2dNULL(GLint location, GLdouble x, GLdouble y)
+{
+}
+
+void INTERNAL_GL_APIENTRY glUniform2dvNULL(GLint location, GLsizei count, const GLdouble *value)
+{
+}
+
+void INTERNAL_GL_APIENTRY glUniform2fNULL(GLint location, GLfloat v0, GLfloat v1)
+{
+}
+
+void INTERNAL_GL_APIENTRY glUniform2fvNULL(GLint location, GLsizei count, const GLfloat *value)
+{
+}
+
+void INTERNAL_GL_APIENTRY glUniform2iNULL(GLint location, GLint v0, GLint v1)
+{
+}
+
+void INTERNAL_GL_APIENTRY glUniform2ivNULL(GLint location, GLsizei count, const GLint *value)
+{
+}
+
+void INTERNAL_GL_APIENTRY glUniform2uiNULL(GLint location, GLuint v0, GLuint v1)
+{
+}
+
+void INTERNAL_GL_APIENTRY glUniform2uivNULL(GLint location, GLsizei count, const GLuint *value)
+{
+}
+
+void INTERNAL_GL_APIENTRY glUniform3dNULL(GLint location, GLdouble x, GLdouble y, GLdouble z)
+{
+}
+
+void INTERNAL_GL_APIENTRY glUniform3dvNULL(GLint location, GLsizei count, const GLdouble *value)
+{
+}
+
+void INTERNAL_GL_APIENTRY glUniform3fNULL(GLint location, GLfloat v0, GLfloat v1, GLfloat v2)
+{
+}
+
+void INTERNAL_GL_APIENTRY glUniform3fvNULL(GLint location, GLsizei count, const GLfloat *value)
+{
+}
+
+void INTERNAL_GL_APIENTRY glUniform3iNULL(GLint location, GLint v0, GLint v1, GLint v2)
+{
+}
+
+void INTERNAL_GL_APIENTRY glUniform3ivNULL(GLint location, GLsizei count, const GLint *value)
+{
+}
+
+void INTERNAL_GL_APIENTRY glUniform3uiNULL(GLint location, GLuint v0, GLuint v1, GLuint v2)
+{
+}
+
+void INTERNAL_GL_APIENTRY glUniform3uivNULL(GLint location, GLsizei count, const GLuint *value)
+{
+}
+
+void INTERNAL_GL_APIENTRY
+glUniform4dNULL(GLint location, GLdouble x, GLdouble y, GLdouble z, GLdouble w)
+{
+}
+
+void INTERNAL_GL_APIENTRY glUniform4dvNULL(GLint location, GLsizei count, const GLdouble *value)
+{
+}
+
+void INTERNAL_GL_APIENTRY
+glUniform4fNULL(GLint location, GLfloat v0, GLfloat v1, GLfloat v2, GLfloat v3)
+{
+}
+
+void INTERNAL_GL_APIENTRY glUniform4fvNULL(GLint location, GLsizei count, const GLfloat *value)
+{
+}
+
+void INTERNAL_GL_APIENTRY glUniform4iNULL(GLint location, GLint v0, GLint v1, GLint v2, GLint v3)
+{
+}
+
+void INTERNAL_GL_APIENTRY glUniform4ivNULL(GLint location, GLsizei count, const GLint *value)
+{
+}
+
+void INTERNAL_GL_APIENTRY
+glUniform4uiNULL(GLint location, GLuint v0, GLuint v1, GLuint v2, GLuint v3)
+{
+}
+
+void INTERNAL_GL_APIENTRY glUniform4uivNULL(GLint location, GLsizei count, const GLuint *value)
+{
+}
+
+void INTERNAL_GL_APIENTRY glUniformBlockBindingNULL(GLuint program,
+                                                    GLuint uniformBlockIndex,
+                                                    GLuint uniformBlockBinding)
+{
+}
+
+void INTERNAL_GL_APIENTRY glUniformMatrix2dvNULL(GLint location,
+                                                 GLsizei count,
+                                                 GLboolean transpose,
+                                                 const GLdouble *value)
+{
+}
+
+void INTERNAL_GL_APIENTRY glUniformMatrix2fvNULL(GLint location,
+                                                 GLsizei count,
+                                                 GLboolean transpose,
+                                                 const GLfloat *value)
+{
+}
+
+void INTERNAL_GL_APIENTRY glUniformMatrix2x3dvNULL(GLint location,
+                                                   GLsizei count,
+                                                   GLboolean transpose,
+                                                   const GLdouble *value)
+{
+}
+
+void INTERNAL_GL_APIENTRY glUniformMatrix2x3fvNULL(GLint location,
+                                                   GLsizei count,
+                                                   GLboolean transpose,
+                                                   const GLfloat *value)
+{
+}
+
+void INTERNAL_GL_APIENTRY glUniformMatrix2x4dvNULL(GLint location,
+                                                   GLsizei count,
+                                                   GLboolean transpose,
+                                                   const GLdouble *value)
+{
+}
+
+void INTERNAL_GL_APIENTRY glUniformMatrix2x4fvNULL(GLint location,
+                                                   GLsizei count,
+                                                   GLboolean transpose,
+                                                   const GLfloat *value)
+{
+}
+
+void INTERNAL_GL_APIENTRY glUniformMatrix3dvNULL(GLint location,
+                                                 GLsizei count,
+                                                 GLboolean transpose,
+                                                 const GLdouble *value)
+{
+}
+
+void INTERNAL_GL_APIENTRY glUniformMatrix3fvNULL(GLint location,
+                                                 GLsizei count,
+                                                 GLboolean transpose,
+                                                 const GLfloat *value)
+{
+}
+
+void INTERNAL_GL_APIENTRY glUniformMatrix3x2dvNULL(GLint location,
+                                                   GLsizei count,
+                                                   GLboolean transpose,
+                                                   const GLdouble *value)
+{
+}
+
+void INTERNAL_GL_APIENTRY glUniformMatrix3x2fvNULL(GLint location,
+                                                   GLsizei count,
+                                                   GLboolean transpose,
+                                                   const GLfloat *value)
+{
+}
+
+void INTERNAL_GL_APIENTRY glUniformMatrix3x4dvNULL(GLint location,
+                                                   GLsizei count,
+                                                   GLboolean transpose,
+                                                   const GLdouble *value)
+{
+}
+
+void INTERNAL_GL_APIENTRY glUniformMatrix3x4fvNULL(GLint location,
+                                                   GLsizei count,
+                                                   GLboolean transpose,
+                                                   const GLfloat *value)
+{
+}
+
+void INTERNAL_GL_APIENTRY glUniformMatrix4dvNULL(GLint location,
+                                                 GLsizei count,
+                                                 GLboolean transpose,
+                                                 const GLdouble *value)
+{
+}
+
+void INTERNAL_GL_APIENTRY glUniformMatrix4fvNULL(GLint location,
+                                                 GLsizei count,
+                                                 GLboolean transpose,
+                                                 const GLfloat *value)
+{
+}
+
+void INTERNAL_GL_APIENTRY glUniformMatrix4x2dvNULL(GLint location,
+                                                   GLsizei count,
+                                                   GLboolean transpose,
+                                                   const GLdouble *value)
+{
+}
+
+void INTERNAL_GL_APIENTRY glUniformMatrix4x2fvNULL(GLint location,
+                                                   GLsizei count,
+                                                   GLboolean transpose,
+                                                   const GLfloat *value)
+{
+}
+
+void INTERNAL_GL_APIENTRY glUniformMatrix4x3dvNULL(GLint location,
+                                                   GLsizei count,
+                                                   GLboolean transpose,
+                                                   const GLdouble *value)
+{
+}
+
+void INTERNAL_GL_APIENTRY glUniformMatrix4x3fvNULL(GLint location,
+                                                   GLsizei count,
+                                                   GLboolean transpose,
+                                                   const GLfloat *value)
+{
+}
+
+void INTERNAL_GL_APIENTRY glUniformSubroutinesuivNULL(GLenum shadertype,
+                                                      GLsizei count,
+                                                      const GLuint *indices)
+{
+}
+
+GLboolean INTERNAL_GL_APIENTRY glUnmapBufferNULL(GLenum target)
+{
+    return static_cast<GLboolean>(0);
+}
+
+GLboolean INTERNAL_GL_APIENTRY glUnmapNamedBufferNULL(GLuint buffer)
+{
+    return static_cast<GLboolean>(0);
+}
+
+void INTERNAL_GL_APIENTRY glUseProgramNULL(GLuint program)
+{
+}
+
+void INTERNAL_GL_APIENTRY glUseProgramStagesNULL(GLuint pipeline, GLbitfield stages, GLuint program)
+{
+}
+
+void INTERNAL_GL_APIENTRY glValidateProgramNULL(GLuint program)
+{
+}
+
+void INTERNAL_GL_APIENTRY glValidateProgramPipelineNULL(GLuint pipeline)
+{
+}
+
+void INTERNAL_GL_APIENTRY glVertexArrayAttribBindingNULL(GLuint vaobj,
+                                                         GLuint attribindex,
+                                                         GLuint bindingindex)
+{
+}
+
+void INTERNAL_GL_APIENTRY glVertexArrayAttribFormatNULL(GLuint vaobj,
+                                                        GLuint attribindex,
+                                                        GLint size,
+                                                        GLenum type,
+                                                        GLboolean normalized,
+                                                        GLuint relativeoffset)
+{
+}
+
+void INTERNAL_GL_APIENTRY glVertexArrayAttribIFormatNULL(GLuint vaobj,
+                                                         GLuint attribindex,
+                                                         GLint size,
+                                                         GLenum type,
+                                                         GLuint relativeoffset)
+{
+}
+
+void INTERNAL_GL_APIENTRY glVertexArrayAttribLFormatNULL(GLuint vaobj,
+                                                         GLuint attribindex,
+                                                         GLint size,
+                                                         GLenum type,
+                                                         GLuint relativeoffset)
+{
+}
+
+void INTERNAL_GL_APIENTRY glVertexArrayBindingDivisorNULL(GLuint vaobj,
+                                                          GLuint bindingindex,
+                                                          GLuint divisor)
+{
+}
+
+void INTERNAL_GL_APIENTRY glVertexArrayElementBufferNULL(GLuint vaobj, GLuint buffer)
+{
+}
+
+void INTERNAL_GL_APIENTRY glVertexArrayVertexBufferNULL(GLuint vaobj,
+                                                        GLuint bindingindex,
+                                                        GLuint buffer,
+                                                        GLintptr offset,
+                                                        GLsizei stride)
+{
+}
+
+void INTERNAL_GL_APIENTRY glVertexArrayVertexBuffersNULL(GLuint vaobj,
+                                                         GLuint first,
+                                                         GLsizei count,
+                                                         const GLuint *buffers,
+                                                         const GLintptr *offsets,
+                                                         const GLsizei *strides)
+{
+}
+
+void INTERNAL_GL_APIENTRY glVertexAttrib1dNULL(GLuint index, GLdouble x)
+{
+}
+
+void INTERNAL_GL_APIENTRY glVertexAttrib1dvNULL(GLuint index, const GLdouble *v)
+{
+}
+
+void INTERNAL_GL_APIENTRY glVertexAttrib1fNULL(GLuint index, GLfloat x)
+{
+}
+
+void INTERNAL_GL_APIENTRY glVertexAttrib1fvNULL(GLuint index, const GLfloat *v)
+{
+}
+
+void INTERNAL_GL_APIENTRY glVertexAttrib1sNULL(GLuint index, GLshort x)
+{
+}
+
+void INTERNAL_GL_APIENTRY glVertexAttrib1svNULL(GLuint index, const GLshort *v)
+{
+}
+
+void INTERNAL_GL_APIENTRY glVertexAttrib2dNULL(GLuint index, GLdouble x, GLdouble y)
+{
+}
+
+void INTERNAL_GL_APIENTRY glVertexAttrib2dvNULL(GLuint index, const GLdouble *v)
+{
+}
+
+void INTERNAL_GL_APIENTRY glVertexAttrib2fNULL(GLuint index, GLfloat x, GLfloat y)
+{
+}
+
+void INTERNAL_GL_APIENTRY glVertexAttrib2fvNULL(GLuint index, const GLfloat *v)
+{
+}
+
+void INTERNAL_GL_APIENTRY glVertexAttrib2sNULL(GLuint index, GLshort x, GLshort y)
+{
+}
+
+void INTERNAL_GL_APIENTRY glVertexAttrib2svNULL(GLuint index, const GLshort *v)
+{
+}
+
+void INTERNAL_GL_APIENTRY glVertexAttrib3dNULL(GLuint index, GLdouble x, GLdouble y, GLdouble z)
+{
+}
+
+void INTERNAL_GL_APIENTRY glVertexAttrib3dvNULL(GLuint index, const GLdouble *v)
+{
+}
+
+void INTERNAL_GL_APIENTRY glVertexAttrib3fNULL(GLuint index, GLfloat x, GLfloat y, GLfloat z)
+{
+}
+
+void INTERNAL_GL_APIENTRY glVertexAttrib3fvNULL(GLuint index, const GLfloat *v)
+{
+}
+
+void INTERNAL_GL_APIENTRY glVertexAttrib3sNULL(GLuint index, GLshort x, GLshort y, GLshort z)
+{
+}
+
+void INTERNAL_GL_APIENTRY glVertexAttrib3svNULL(GLuint index, const GLshort *v)
+{
+}
+
+void INTERNAL_GL_APIENTRY glVertexAttrib4NbvNULL(GLuint index, const GLbyte *v)
+{
+}
+
+void INTERNAL_GL_APIENTRY glVertexAttrib4NivNULL(GLuint index, const GLint *v)
+{
+}
+
+void INTERNAL_GL_APIENTRY glVertexAttrib4NsvNULL(GLuint index, const GLshort *v)
+{
+}
+
+void INTERNAL_GL_APIENTRY
+glVertexAttrib4NubNULL(GLuint index, GLubyte x, GLubyte y, GLubyte z, GLubyte w)
+{
+}
+
+void INTERNAL_GL_APIENTRY glVertexAttrib4NubvNULL(GLuint index, const GLubyte *v)
+{
+}
+
+void INTERNAL_GL_APIENTRY glVertexAttrib4NuivNULL(GLuint index, const GLuint *v)
+{
+}
+
+void INTERNAL_GL_APIENTRY glVertexAttrib4NusvNULL(GLuint index, const GLushort *v)
+{
+}
+
+void INTERNAL_GL_APIENTRY glVertexAttrib4bvNULL(GLuint index, const GLbyte *v)
+{
+}
+
+void INTERNAL_GL_APIENTRY
+glVertexAttrib4dNULL(GLuint index, GLdouble x, GLdouble y, GLdouble z, GLdouble w)
+{
+}
+
+void INTERNAL_GL_APIENTRY glVertexAttrib4dvNULL(GLuint index, const GLdouble *v)
+{
+}
+
+void INTERNAL_GL_APIENTRY
+glVertexAttrib4fNULL(GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w)
+{
+}
+
+void INTERNAL_GL_APIENTRY glVertexAttrib4fvNULL(GLuint index, const GLfloat *v)
+{
+}
+
+void INTERNAL_GL_APIENTRY glVertexAttrib4ivNULL(GLuint index, const GLint *v)
+{
+}
+
+void INTERNAL_GL_APIENTRY
+glVertexAttrib4sNULL(GLuint index, GLshort x, GLshort y, GLshort z, GLshort w)
+{
+}
+
+void INTERNAL_GL_APIENTRY glVertexAttrib4svNULL(GLuint index, const GLshort *v)
+{
+}
+
+void INTERNAL_GL_APIENTRY glVertexAttrib4ubvNULL(GLuint index, const GLubyte *v)
+{
+}
+
+void INTERNAL_GL_APIENTRY glVertexAttrib4uivNULL(GLuint index, const GLuint *v)
+{
+}
+
+void INTERNAL_GL_APIENTRY glVertexAttrib4usvNULL(GLuint index, const GLushort *v)
+{
+}
+
+void INTERNAL_GL_APIENTRY glVertexAttribBindingNULL(GLuint attribindex, GLuint bindingindex)
+{
+}
+
+void INTERNAL_GL_APIENTRY glVertexAttribDivisorNULL(GLuint index, GLuint divisor)
+{
+}
+
+void INTERNAL_GL_APIENTRY glVertexAttribFormatNULL(GLuint attribindex,
+                                                   GLint size,
+                                                   GLenum type,
+                                                   GLboolean normalized,
+                                                   GLuint relativeoffset)
+{
+}
+
+void INTERNAL_GL_APIENTRY glVertexAttribI1iNULL(GLuint index, GLint x)
+{
+}
+
+void INTERNAL_GL_APIENTRY glVertexAttribI1ivNULL(GLuint index, const GLint *v)
+{
+}
+
+void INTERNAL_GL_APIENTRY glVertexAttribI1uiNULL(GLuint index, GLuint x)
+{
+}
+
+void INTERNAL_GL_APIENTRY glVertexAttribI1uivNULL(GLuint index, const GLuint *v)
+{
+}
+
+void INTERNAL_GL_APIENTRY glVertexAttribI2iNULL(GLuint index, GLint x, GLint y)
+{
+}
+
+void INTERNAL_GL_APIENTRY glVertexAttribI2ivNULL(GLuint index, const GLint *v)
+{
+}
+
+void INTERNAL_GL_APIENTRY glVertexAttribI2uiNULL(GLuint index, GLuint x, GLuint y)
+{
+}
+
+void INTERNAL_GL_APIENTRY glVertexAttribI2uivNULL(GLuint index, const GLuint *v)
+{
+}
+
+void INTERNAL_GL_APIENTRY glVertexAttribI3iNULL(GLuint index, GLint x, GLint y, GLint z)
+{
+}
+
+void INTERNAL_GL_APIENTRY glVertexAttribI3ivNULL(GLuint index, const GLint *v)
+{
+}
+
+void INTERNAL_GL_APIENTRY glVertexAttribI3uiNULL(GLuint index, GLuint x, GLuint y, GLuint z)
+{
+}
+
+void INTERNAL_GL_APIENTRY glVertexAttribI3uivNULL(GLuint index, const GLuint *v)
+{
+}
+
+void INTERNAL_GL_APIENTRY glVertexAttribI4bvNULL(GLuint index, const GLbyte *v)
+{
+}
+
+void INTERNAL_GL_APIENTRY glVertexAttribI4iNULL(GLuint index, GLint x, GLint y, GLint z, GLint w)
+{
+}
+
+void INTERNAL_GL_APIENTRY glVertexAttribI4ivNULL(GLuint index, const GLint *v)
+{
+}
+
+void INTERNAL_GL_APIENTRY glVertexAttribI4svNULL(GLuint index, const GLshort *v)
+{
+}
+
+void INTERNAL_GL_APIENTRY glVertexAttribI4ubvNULL(GLuint index, const GLubyte *v)
+{
+}
+
+void INTERNAL_GL_APIENTRY
+glVertexAttribI4uiNULL(GLuint index, GLuint x, GLuint y, GLuint z, GLuint w)
+{
+}
+
+void INTERNAL_GL_APIENTRY glVertexAttribI4uivNULL(GLuint index, const GLuint *v)
+{
+}
+
+void INTERNAL_GL_APIENTRY glVertexAttribI4usvNULL(GLuint index, const GLushort *v)
+{
+}
+
+void INTERNAL_GL_APIENTRY glVertexAttribIFormatNULL(GLuint attribindex,
+                                                    GLint size,
+                                                    GLenum type,
+                                                    GLuint relativeoffset)
+{
+}
+
+void INTERNAL_GL_APIENTRY glVertexAttribIPointerNULL(GLuint index,
+                                                     GLint size,
+                                                     GLenum type,
+                                                     GLsizei stride,
+                                                     const void *pointer)
+{
+}
+
+void INTERNAL_GL_APIENTRY glVertexAttribL1dNULL(GLuint index, GLdouble x)
+{
+}
+
+void INTERNAL_GL_APIENTRY glVertexAttribL1dvNULL(GLuint index, const GLdouble *v)
+{
+}
+
+void INTERNAL_GL_APIENTRY glVertexAttribL2dNULL(GLuint index, GLdouble x, GLdouble y)
+{
+}
+
+void INTERNAL_GL_APIENTRY glVertexAttribL2dvNULL(GLuint index, const GLdouble *v)
+{
+}
+
+void INTERNAL_GL_APIENTRY glVertexAttribL3dNULL(GLuint index, GLdouble x, GLdouble y, GLdouble z)
+{
+}
+
+void INTERNAL_GL_APIENTRY glVertexAttribL3dvNULL(GLuint index, const GLdouble *v)
+{
+}
+
+void INTERNAL_GL_APIENTRY
+glVertexAttribL4dNULL(GLuint index, GLdouble x, GLdouble y, GLdouble z, GLdouble w)
+{
+}
+
+void INTERNAL_GL_APIENTRY glVertexAttribL4dvNULL(GLuint index, const GLdouble *v)
+{
+}
+
+void INTERNAL_GL_APIENTRY glVertexAttribLFormatNULL(GLuint attribindex,
+                                                    GLint size,
+                                                    GLenum type,
+                                                    GLuint relativeoffset)
+{
+}
+
+void INTERNAL_GL_APIENTRY glVertexAttribLPointerNULL(GLuint index,
+                                                     GLint size,
+                                                     GLenum type,
+                                                     GLsizei stride,
+                                                     const void *pointer)
+{
+}
+
+void INTERNAL_GL_APIENTRY glVertexAttribP1uiNULL(GLuint index,
+                                                 GLenum type,
+                                                 GLboolean normalized,
+                                                 GLuint value)
+{
+}
+
+void INTERNAL_GL_APIENTRY glVertexAttribP1uivNULL(GLuint index,
+                                                  GLenum type,
+                                                  GLboolean normalized,
+                                                  const GLuint *value)
+{
+}
+
+void INTERNAL_GL_APIENTRY glVertexAttribP2uiNULL(GLuint index,
+                                                 GLenum type,
+                                                 GLboolean normalized,
+                                                 GLuint value)
+{
+}
+
+void INTERNAL_GL_APIENTRY glVertexAttribP2uivNULL(GLuint index,
+                                                  GLenum type,
+                                                  GLboolean normalized,
+                                                  const GLuint *value)
+{
+}
+
+void INTERNAL_GL_APIENTRY glVertexAttribP3uiNULL(GLuint index,
+                                                 GLenum type,
+                                                 GLboolean normalized,
+                                                 GLuint value)
+{
+}
+
+void INTERNAL_GL_APIENTRY glVertexAttribP3uivNULL(GLuint index,
+                                                  GLenum type,
+                                                  GLboolean normalized,
+                                                  const GLuint *value)
+{
+}
+
+void INTERNAL_GL_APIENTRY glVertexAttribP4uiNULL(GLuint index,
+                                                 GLenum type,
+                                                 GLboolean normalized,
+                                                 GLuint value)
+{
+}
+
+void INTERNAL_GL_APIENTRY glVertexAttribP4uivNULL(GLuint index,
+                                                  GLenum type,
+                                                  GLboolean normalized,
+                                                  const GLuint *value)
+{
+}
+
+void INTERNAL_GL_APIENTRY glVertexAttribPointerNULL(GLuint index,
+                                                    GLint size,
+                                                    GLenum type,
+                                                    GLboolean normalized,
+                                                    GLsizei stride,
+                                                    const void *pointer)
+{
+}
+
+void INTERNAL_GL_APIENTRY glVertexBindingDivisorNULL(GLuint bindingindex, GLuint divisor)
+{
+}
+
+void INTERNAL_GL_APIENTRY glViewportNULL(GLint x, GLint y, GLsizei width, GLsizei height)
+{
+}
+
+void INTERNAL_GL_APIENTRY glViewportArrayvNULL(GLuint first, GLsizei count, const GLfloat *v)
+{
+}
+
+void INTERNAL_GL_APIENTRY
+glViewportIndexedfNULL(GLuint index, GLfloat x, GLfloat y, GLfloat w, GLfloat h)
+{
+}
+
+void INTERNAL_GL_APIENTRY glViewportIndexedfvNULL(GLuint index, const GLfloat *v)
+{
+}
+
+void INTERNAL_GL_APIENTRY glWaitSyncNULL(GLsync sync, GLbitfield flags, GLuint64 timeout)
+{
+}
+}  // namespace rx
new file mode 100644
--- /dev/null
+++ b/gfx/angle/src/libANGLE/renderer/gl/null_functions.h
@@ -0,0 +1,1981 @@
+// GENERATED FILE - DO NOT EDIT.
+// Generated by generate_gl_dispatch_table.py using data from gl_bindings_data.json and gl.xml.
+//
+// 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.
+//
+// null_functions.h:
+//   Declares the NULL/Stub bindings for the OpenGL back-end.
+
+#ifndef LIBGLESV2_RENDERER_GL_NULL_GL_FUNCTIONS_AUTOGEN_H_
+#define LIBGLESV2_RENDERER_GL_NULL_GL_FUNCTIONS_AUTOGEN_H_
+
+#include "libANGLE/renderer/gl/functionsgl_typedefs.h"
+
+namespace rx
+{
+void INTERNAL_GL_APIENTRY glActiveShaderProgramNULL(GLuint pipeline, GLuint program);
+void INTERNAL_GL_APIENTRY glActiveTextureNULL(GLenum texture);
+void INTERNAL_GL_APIENTRY glAttachShaderNULL(GLuint program, GLuint shader);
+void INTERNAL_GL_APIENTRY glBeginConditionalRenderNULL(GLuint id, GLenum mode);
+void INTERNAL_GL_APIENTRY glBeginQueryNULL(GLenum target, GLuint id);
+void INTERNAL_GL_APIENTRY glBeginQueryIndexedNULL(GLenum target, GLuint index, GLuint id);
+void INTERNAL_GL_APIENTRY glBeginTransformFeedbackNULL(GLenum primitiveMode);
+void INTERNAL_GL_APIENTRY glBindAttribLocationNULL(GLuint program,
+                                                   GLuint index,
+                                                   const GLchar *name);
+void INTERNAL_GL_APIENTRY glBindBufferNULL(GLenum target, GLuint buffer);
+void INTERNAL_GL_APIENTRY glBindBufferBaseNULL(GLenum target, GLuint index, GLuint buffer);
+void INTERNAL_GL_APIENTRY
+glBindBufferRangeNULL(GLenum target, GLuint index, GLuint buffer, GLintptr offset, GLsizeiptr size);
+void INTERNAL_GL_APIENTRY glBindBuffersBaseNULL(GLenum target,
+                                                GLuint first,
+                                                GLsizei count,
+                                                const GLuint *buffers);
+void INTERNAL_GL_APIENTRY glBindBuffersRangeNULL(GLenum target,
+                                                 GLuint first,
+                                                 GLsizei count,
+                                                 const GLuint *buffers,
+                                                 const GLintptr *offsets,
+                                                 const GLsizeiptr *sizes);
+void INTERNAL_GL_APIENTRY glBindFragDataLocationNULL(GLuint program,
+                                                     GLuint color,
+                                                     const GLchar *name);
+void INTERNAL_GL_APIENTRY glBindFragDataLocationIndexedNULL(GLuint program,
+                                                            GLuint colorNumber,
+                                                            GLuint index,
+                                                            const GLchar *name);
+void INTERNAL_GL_APIENTRY glBindFramebufferNULL(GLenum target, GLuint framebuffer);
+void INTERNAL_GL_APIENTRY glBindImageTextureNULL(GLuint unit,
+                                                 GLuint texture,
+                                                 GLint level,
+                                                 GLboolean layered,
+                                                 GLint layer,
+                                                 GLenum access,
+                                                 GLenum format);
+void INTERNAL_GL_APIENTRY glBindImageTexturesNULL(GLuint first,
+                                                  GLsizei count,
+                                                  const GLuint *textures);
+void INTERNAL_GL_APIENTRY glBindProgramPipelineNULL(GLuint pipeline);
+void INTERNAL_GL_APIENTRY glBindRenderbufferNULL(GLenum target, GLuint renderbuffer);
+void INTERNAL_GL_APIENTRY glBindSamplerNULL(GLuint unit, GLuint sampler);
+void INTERNAL_GL_APIENTRY glBindSamplersNULL(GLuint first, GLsizei count, const GLuint *samplers);
+void INTERNAL_GL_APIENTRY glBindTextureNULL(GLenum target, GLuint texture);
+void INTERNAL_GL_APIENTRY glBindTextureUnitNULL(GLuint unit, GLuint texture);
+void INTERNAL_GL_APIENTRY glBindTexturesNULL(GLuint first, GLsizei count, const GLuint *textures);
+void INTERNAL_GL_APIENTRY glBindTransformFeedbackNULL(GLenum target, GLuint id);
+void INTERNAL_GL_APIENTRY glBindVertexArrayNULL(GLuint array);
+void INTERNAL_GL_APIENTRY glBindVertexBufferNULL(GLuint bindingindex,
+                                                 GLuint buffer,
+                                                 GLintptr offset,
+                                                 GLsizei stride);
+void INTERNAL_GL_APIENTRY glBindVertexBuffersNULL(GLuint first,
+                                                  GLsizei count,
+                                                  const GLuint *buffers,
+                                                  const GLintptr *offsets,
+                                                  const GLsizei *strides);
+void INTERNAL_GL_APIENTRY glBlendBarrierNULL();
+void INTERNAL_GL_APIENTRY glBlendColorNULL(GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha);
+void INTERNAL_GL_APIENTRY glBlendEquationNULL(GLenum mode);
+void INTERNAL_GL_APIENTRY glBlendEquationSeparateNULL(GLenum modeRGB, GLenum modeAlpha);
+void INTERNAL_GL_APIENTRY glBlendEquationSeparateiNULL(GLuint buf,
+                                                       GLenum modeRGB,
+                                                       GLenum modeAlpha);
+void INTERNAL_GL_APIENTRY glBlendEquationiNULL(GLuint buf, GLenum mode);
+void INTERNAL_GL_APIENTRY glBlendFuncNULL(GLenum sfactor, GLenum dfactor);
+void INTERNAL_GL_APIENTRY glBlendFuncSeparateNULL(GLenum sfactorRGB,
+                                                  GLenum dfactorRGB,
+                                                  GLenum sfactorAlpha,
+                                                  GLenum dfactorAlpha);
+void INTERNAL_GL_APIENTRY glBlendFuncSeparateiNULL(GLuint buf,
+                                                   GLenum srcRGB,
+                                                   GLenum dstRGB,
+                                                   GLenum srcAlpha,
+                                                   GLenum dstAlpha);
+void INTERNAL_GL_APIENTRY glBlendFunciNULL(GLuint buf, GLenum src, GLenum dst);
+void INTERNAL_GL_APIENTRY glBlitFramebufferNULL(GLint srcX0,
+                                                GLint srcY0,
+                                                GLint srcX1,
+                                                GLint srcY1,
+                                                GLint dstX0,
+                                                GLint dstY0,
+                                                GLint dstX1,
+                                                GLint dstY1,
+                                                GLbitfield mask,
+                                                GLenum filter);
+void INTERNAL_GL_APIENTRY glBlitNamedFramebufferNULL(GLuint readFramebuffer,
+                                                     GLuint drawFramebuffer,
+                                                     GLint srcX0,
+                                                     GLint srcY0,
+                                                     GLint srcX1,
+                                                     GLint srcY1,
+                                                     GLint dstX0,
+                                                     GLint dstY0,
+                                                     GLint dstX1,
+                                                     GLint dstY1,
+                                                     GLbitfield mask,
+                                                     GLenum filter);
+void INTERNAL_GL_APIENTRY glBufferDataNULL(GLenum target,
+                                           GLsizeiptr size,
+                                           const void *data,
+                                           GLenum usage);
+void INTERNAL_GL_APIENTRY glBufferStorageNULL(GLenum target,
+                                              GLsizeiptr size,
+                                              const void *data,
+                                              GLbitfield flags);
+void INTERNAL_GL_APIENTRY glBufferSubDataNULL(GLenum target,
+                                              GLintptr offset,
+                                              GLsizeiptr size,
+                                              const void *data);
+GLenum INTERNAL_GL_APIENTRY glCheckFramebufferStatusNULL(GLenum target);
+GLenum INTERNAL_GL_APIENTRY glCheckNamedFramebufferStatusNULL(GLuint framebuffer, GLenum target);
+void INTERNAL_GL_APIENTRY glClampColorNULL(GLenum target, GLenum clamp);
+void INTERNAL_GL_APIENTRY glClearNULL(GLbitfield mask);
+void INTERNAL_GL_APIENTRY glClearBufferDataNULL(GLenum target,
+                                                GLenum internalformat,
+                                                GLenum format,
+                                                GLenum type,
+                                                const void *data);
+void INTERNAL_GL_APIENTRY glClearBufferSubDataNULL(GLenum target,
+                                                   GLenum internalformat,
+                                                   GLintptr offset,
+                                                   GLsizeiptr size,
+                                                   GLenum format,
+                                                   GLenum type,
+                                                   const void *data);
+void INTERNAL_GL_APIENTRY glClearBufferfiNULL(GLenum buffer,
+                                              GLint drawbuffer,
+                                              GLfloat depth,
+                                              GLint stencil);
+void INTERNAL_GL_APIENTRY glClearBufferfvNULL(GLenum buffer,
+                                              GLint drawbuffer,
+                                              const GLfloat *value);
+void INTERNAL_GL_APIENTRY glClearBufferivNULL(GLenum buffer, GLint drawbuffer, const GLint *value);
+void INTERNAL_GL_APIENTRY glClearBufferuivNULL(GLenum buffer,
+                                               GLint drawbuffer,
+                                               const GLuint *value);
+void INTERNAL_GL_APIENTRY glClearColorNULL(GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha);
+void INTERNAL_GL_APIENTRY glClearDepthNULL(GLdouble depth);
+void INTERNAL_GL_APIENTRY glClearDepthfNULL(GLfloat d);
+void INTERNAL_GL_APIENTRY glClearNamedBufferDataNULL(GLuint buffer,
+                                                     GLenum internalformat,
+                                                     GLenum format,
+                                                     GLenum type,
+                                                     const void *data);
+void INTERNAL_GL_APIENTRY glClearNamedBufferSubDataNULL(GLuint buffer,
+                                                        GLenum internalformat,
+                                                        GLintptr offset,
+                                                        GLsizeiptr size,
+                                                        GLenum format,
+                                                        GLenum type,
+                                                        const void *data);
+void INTERNAL_GL_APIENTRY glClearNamedFramebufferfiNULL(GLuint framebuffer,
+                                                        GLenum buffer,
+                                                        GLint drawbuffer,
+                                                        GLfloat depth,
+                                                        GLint stencil);
+void INTERNAL_GL_APIENTRY glClearNamedFramebufferfvNULL(GLuint framebuffer,
+                                                        GLenum buffer,
+                                                        GLint drawbuffer,
+                                                        const GLfloat *value);
+void INTERNAL_GL_APIENTRY glClearNamedFramebufferivNULL(GLuint framebuffer,
+                                                        GLenum buffer,
+                                                        GLint drawbuffer,
+                                                        const GLint *value);
+void INTERNAL_GL_APIENTRY glClearNamedFramebufferuivNULL(GLuint framebuffer,
+                                                         GLenum buffer,
+                                                         GLint drawbuffer,
+                                                         const GLuint *value);
+void INTERNAL_GL_APIENTRY glClearStencilNULL(GLint s);
+void INTERNAL_GL_APIENTRY
+glClearTexImageNULL(GLuint texture, GLint level, GLenum format, GLenum type, const void *data);
+void INTERNAL_GL_APIENTRY glClearTexSubImageNULL(GLuint texture,
+                                                 GLint level,
+                                                 GLint xoffset,
+                                                 GLint yoffset,
+                                                 GLint zoffset,
+                                                 GLsizei width,
+                                                 GLsizei height,
+                                                 GLsizei depth,
+                                                 GLenum format,
+                                                 GLenum type,
+                                                 const void *data);
+GLenum INTERNAL_GL_APIENTRY glClientWaitSyncNULL(GLsync sync, GLbitfield flags, GLuint64 timeout);
+void INTERNAL_GL_APIENTRY glClipControlNULL(GLenum origin, GLenum depth);
+void INTERNAL_GL_APIENTRY glColorMaskNULL(GLboolean red,
+                                          GLboolean green,
+                                          GLboolean blue,
+                                          GLboolean alpha);
+void INTERNAL_GL_APIENTRY
+glColorMaskiNULL(GLuint index, GLboolean r, GLboolean g, GLboolean b, GLboolean a);
+void INTERNAL_GL_APIENTRY glCompileShaderNULL(GLuint shader);
+void INTERNAL_GL_APIENTRY glCompressedTexImage1DNULL(GLenum target,
+                                                     GLint level,
+                                                     GLenum internalformat,
+                                                     GLsizei width,
+                                                     GLint border,
+                                                     GLsizei imageSize,
+                                                     const void *data);
+void INTERNAL_GL_APIENTRY glCompressedTexImage2DNULL(GLenum target,
+                                                     GLint level,
+                                                     GLenum internalformat,
+                                                     GLsizei width,
+                                                     GLsizei height,
+                                                     GLint border,
+                                                     GLsizei imageSize,
+                                                     const void *data);
+void INTERNAL_GL_APIENTRY glCompressedTexImage3DNULL(GLenum target,
+                                                     GLint level,
+                                                     GLenum internalformat,
+                                                     GLsizei width,
+                                                     GLsizei height,
+                                                     GLsizei depth,
+                                                     GLint border,
+                                                     GLsizei imageSize,
+                                                     const void *data);
+void INTERNAL_GL_APIENTRY glCompressedTexSubImage1DNULL(GLenum target,
+                                                        GLint level,
+                                                        GLint xoffset,
+                                                        GLsizei width,
+                                                        GLenum format,
+                                                        GLsizei imageSize,
+                                                        const void *data);
+void INTERNAL_GL_APIENTRY glCompressedTexSubImage2DNULL(GLenum target,
+                                                        GLint level,
+                                                        GLint xoffset,
+                                                        GLint yoffset,
+                                                        GLsizei width,
+                                                        GLsizei height,
+                                                        GLenum format,
+                                                        GLsizei imageSize,
+                                                        const void *data);
+void INTERNAL_GL_APIENTRY glCompressedTexSubImage3DNULL(GLenum target,
+                                                        GLint level,
+                                                        GLint xoffset,
+                                                        GLint yoffset,
+                                                        GLint zoffset,
+                                                        GLsizei width,
+                                                        GLsizei height,
+                                                        GLsizei depth,
+                                                        GLenum format,
+                                                        GLsizei imageSize,
+                                                        const void *data);
+void INTERNAL_GL_APIENTRY glCompressedTextureSubImage1DNULL(GLuint texture,
+                                                            GLint level,
+                                                            GLint xoffset,
+                                                            GLsizei width,
+                                                            GLenum format,
+                                                            GLsizei imageSize,
+                                                            const void *data);
+void INTERNAL_GL_APIENTRY glCompressedTextureSubImage2DNULL(GLuint texture,
+                                                            GLint level,
+                                                            GLint xoffset,
+                                                            GLint yoffset,
+                                                            GLsizei width,
+                                                            GLsizei height,
+                                                            GLenum format,
+                                                            GLsizei imageSize,
+                                                            const void *data);
+void INTERNAL_GL_APIENTRY glCompressedTextureSubImage3DNULL(GLuint texture,
+                                                            GLint level,
+                                                            GLint xoffset,
+                                                            GLint yoffset,
+                                                            GLint zoffset,
+                                                            GLsizei width,
+                                                            GLsizei height,
+                                                            GLsizei depth,
+                                                            GLenum format,
+                                                            GLsizei imageSize,
+                                                            const void *data);
+void INTERNAL_GL_APIENTRY glCopyBufferSubDataNULL(GLenum readTarget,
+                                                  GLenum writeTarget,
+                                                  GLintptr readOffset,
+                                                  GLintptr writeOffset,
+                                                  GLsizeiptr size);
+void INTERNAL_GL_APIENTRY glCopyImageSubDataNULL(GLuint srcName,
+                                                 GLenum srcTarget,
+                                                 GLint srcLevel,
+                                                 GLint srcX,
+                                                 GLint srcY,
+                                                 GLint srcZ,
+                                                 GLuint dstName,
+                                                 GLenum dstTarget,
+                                                 GLint dstLevel,
+                                                 GLint dstX,
+                                                 GLint dstY,
+                                                 GLint dstZ,
+                                                 GLsizei srcWidth,
+                                                 GLsizei srcHeight,
+                                                 GLsizei srcDepth);
+void INTERNAL_GL_APIENTRY glCopyNamedBufferSubDataNULL(GLuint readBuffer,
+                                                       GLuint writeBuffer,
+                                                       GLintptr readOffset,
+                                                       GLintptr writeOffset,
+                                                       GLsizeiptr size);
+void INTERNAL_GL_APIENTRY glCopyTexImage1DNULL(GLenum target,
+                                               GLint level,
+                                               GLenum internalformat,
+                                               GLint x,
+                                               GLint y,
+                                               GLsizei width,
+                                               GLint border);
+void INTERNAL_GL_APIENTRY glCopyTexImage2DNULL(GLenum target,
+                                               GLint level,
+                                               GLenum internalformat,
+                                               GLint x,
+                                               GLint y,
+                                               GLsizei width,
+                                               GLsizei height,
+                                               GLint border);
+void INTERNAL_GL_APIENTRY
+glCopyTexSubImage1DNULL(GLenum target, GLint level, GLint xoffset, GLint x, GLint y, GLsizei width);
+void INTERNAL_GL_APIENTRY glCopyTexSubImage2DNULL(GLenum target,
+                                                  GLint level,
+                                                  GLint xoffset,
+                                                  GLint yoffset,
+                                                  GLint x,
+                                                  GLint y,
+                                                  GLsizei width,
+                                                  GLsizei height);
+void INTERNAL_GL_APIENTRY glCopyTexSubImage3DNULL(GLenum target,
+                                                  GLint level,
+                                                  GLint xoffset,
+                                                  GLint yoffset,
+                                                  GLint zoffset,
+                                                  GLint x,
+                                                  GLint y,
+                                                  GLsizei width,
+                                                  GLsizei height);
+void INTERNAL_GL_APIENTRY glCopyTextureSubImage1DNULL(GLuint texture,
+                                                      GLint level,
+                                                      GLint xoffset,
+                                                      GLint x,
+                                                      GLint y,
+                                                      GLsizei width);
+void INTERNAL_GL_APIENTRY glCopyTextureSubImage2DNULL(GLuint texture,
+                                                      GLint level,
+                                                      GLint xoffset,
+                                                      GLint yoffset,
+                                                      GLint x,
+                                                      GLint y,
+                                                      GLsizei width,
+                                                      GLsizei height);
+void INTERNAL_GL_APIENTRY glCopyTextureSubImage3DNULL(GLuint texture,
+                                                      GLint level,
+                                                      GLint xoffset,
+                                                      GLint yoffset,
+                                                      GLint zoffset,
+                                                      GLint x,
+                                                      GLint y,
+                                                      GLsizei width,
+                                                      GLsizei height);
+void INTERNAL_GL_APIENTRY glCoverFillPathInstancedNVNULL(GLsizei numPaths,
+                                                         GLenum pathNameType,
+                                                         const void *paths,
+                                                         GLuint pathBase,
+                                                         GLenum coverMode,
+                                                         GLenum transformType,
+                                                         const GLfloat *transformValues);
+void INTERNAL_GL_APIENTRY glCoverFillPathNVNULL(GLuint path, GLenum coverMode);
+void INTERNAL_GL_APIENTRY glCoverStrokePathInstancedNVNULL(GLsizei numPaths,
+                                                           GLenum pathNameType,
+                                                           const void *paths,
+                                                           GLuint pathBase,
+                                                           GLenum coverMode,
+                                                           GLenum transformType,
+                                                           const GLfloat *transformValues);
+void INTERNAL_GL_APIENTRY glCoverStrokePathNVNULL(GLuint path, GLenum coverMode);
+void INTERNAL_GL_APIENTRY glCoverageModulationNVNULL(GLenum components);
+void INTERNAL_GL_APIENTRY glCreateBuffersNULL(GLsizei n, GLuint *buffers);
+void INTERNAL_GL_APIENTRY glCreateFramebuffersNULL(GLsizei n, GLuint *framebuffers);
+GLuint INTERNAL_GL_APIENTRY glCreateProgramNULL();
+void INTERNAL_GL_APIENTRY glCreateProgramPipelinesNULL(GLsizei n, GLuint *pipelines);
+void INTERNAL_GL_APIENTRY glCreateQueriesNULL(GLenum target, GLsizei n, GLuint *ids);
+void INTERNAL_GL_APIENTRY glCreateRenderbuffersNULL(GLsizei n, GLuint *renderbuffers);
+void INTERNAL_GL_APIENTRY glCreateSamplersNULL(GLsizei n, GLuint *samplers);
+GLuint INTERNAL_GL_APIENTRY glCreateShaderNULL(GLenum type);
+GLuint INTERNAL_GL_APIENTRY glCreateShaderProgramvNULL(GLenum type,
+                                                       GLsizei count,
+                                                       const GLchar *const *strings);
+void INTERNAL_GL_APIENTRY glCreateTexturesNULL(GLenum target, GLsizei n, GLuint *textures);
+void INTERNAL_GL_APIENTRY glCreateTransformFeedbacksNULL(GLsizei n, GLuint *ids);
+void INTERNAL_GL_APIENTRY glCreateVertexArraysNULL(GLsizei n, GLuint *arrays);
+void INTERNAL_GL_APIENTRY glCullFaceNULL(GLenum mode);
+void INTERNAL_GL_APIENTRY glDebugMessageCallbackNULL(GLDEBUGPROC callback, const void *userParam);
+void INTERNAL_GL_APIENTRY glDebugMessageControlNULL(GLenum source,
+                                                    GLenum type,
+                                                    GLenum severity,
+                                                    GLsizei count,
+                                                    const GLuint *ids,
+                                                    GLboolean enabled);
+void INTERNAL_GL_APIENTRY glDebugMessageInsertNULL(GLenum source,
+                                                   GLenum type,
+                                                   GLuint id,
+                                                   GLenum severity,
+                                                   GLsizei length,
+                                                   const GLchar *buf);
+void INTERNAL_GL_APIENTRY glDeleteBuffersNULL(GLsizei n, const GLuint *buffers);
+void INTERNAL_GL_APIENTRY glDeleteFencesNVNULL(GLsizei n, const GLuint *fences);
+void INTERNAL_GL_APIENTRY glDeleteFramebuffersNULL(GLsizei n, const GLuint *framebuffers);
+void INTERNAL_GL_APIENTRY glDeletePathsNVNULL(GLuint path, GLsizei range);
+void INTERNAL_GL_APIENTRY glDeleteProgramNULL(GLuint program);
+void INTERNAL_GL_APIENTRY glDeleteProgramPipelinesNULL(GLsizei n, const GLuint *pipelines);
+void INTERNAL_GL_APIENTRY glDeleteQueriesNULL(GLsizei n, const GLuint *ids);
+void INTERNAL_GL_APIENTRY glDeleteRenderbuffersNULL(GLsizei n, const GLuint *renderbuffers);
+void INTERNAL_GL_APIENTRY glDeleteSamplersNULL(GLsizei count, const GLuint *samplers);
+void INTERNAL_GL_APIENTRY glDeleteShaderNULL(GLuint shader);
+void INTERNAL_GL_APIENTRY glDeleteSyncNULL(GLsync sync);
+void INTERNAL_GL_APIENTRY glDeleteTexturesNULL(GLsizei n, const GLuint *textures);
+void INTERNAL_GL_APIENTRY glDeleteTransformFeedbacksNULL(GLsizei n, const GLuint *ids);
+void INTERNAL_GL_APIENTRY glDeleteVertexArraysNULL(GLsizei n, const GLuint *arrays);
+void INTERNAL_GL_APIENTRY glDepthFuncNULL(GLenum func);
+void INTERNAL_GL_APIENTRY glDepthMaskNULL(GLboolean flag);
+void INTERNAL_GL_APIENTRY glDepthRangeNULL(GLdouble near, GLdouble far);
+void INTERNAL_GL_APIENTRY glDepthRangeArrayvNULL(GLuint first, GLsizei count, const GLdouble *v);
+void INTERNAL_GL_APIENTRY glDepthRangeIndexedNULL(GLuint index, GLdouble n, GLdouble f);
+void INTERNAL_GL_APIENTRY glDepthRangefNULL(GLfloat n, GLfloat f);
+void INTERNAL_GL_APIENTRY glDetachShaderNULL(GLuint program, GLuint shader);
+void INTERNAL_GL_APIENTRY glDisableNULL(GLenum cap);
+void INTERNAL_GL_APIENTRY glDisableVertexArrayAttribNULL(GLuint vaobj, GLuint index);
+void INTERNAL_GL_APIENTRY glDisableVertexAttribArrayNULL(GLuint index);
+void INTERNAL_GL_APIENTRY glDisableiNULL(GLenum target, GLuint index);
+void INTERNAL_GL_APIENTRY glDiscardFramebufferEXTNULL(GLenum target,
+                                                      GLsizei numAttachments,
+                                                      const GLenum *attachments);
+void INTERNAL_GL_APIENTRY glDispatchComputeNULL(GLuint num_groups_x,
+                                                GLuint num_groups_y,
+                                                GLuint num_groups_z);
+void INTERNAL_GL_APIENTRY glDispatchComputeIndirectNULL(GLintptr indirect);
+void INTERNAL_GL_APIENTRY glDrawArraysNULL(GLenum mode, GLint first, GLsizei count);
+void INTERNAL_GL_APIENTRY glDrawArraysIndirectNULL(GLenum mode, const void *indirect);
+void INTERNAL_GL_APIENTRY glDrawArraysInstancedNULL(GLenum mode,
+                                                    GLint first,
+                                                    GLsizei count,
+                                                    GLsizei instancecount);
+void INTERNAL_GL_APIENTRY glDrawArraysInstancedBaseInstanceNULL(GLenum mode,
+                                                                GLint first,
+                                                                GLsizei count,
+                                                                GLsizei instancecount,
+                                                                GLuint baseinstance);
+void INTERNAL_GL_APIENTRY glDrawBufferNULL(GLenum buf);
+void INTERNAL_GL_APIENTRY glDrawBuffersNULL(GLsizei n, const GLenum *bufs);
+void INTERNAL_GL_APIENTRY glDrawElementsNULL(GLenum mode,
+                                             GLsizei count,
+                                             GLenum type,
+                                             const void *indices);
+void INTERNAL_GL_APIENTRY glDrawElementsBaseVertexNULL(GLenum mode,
+                                                       GLsizei count,
+                                                       GLenum type,
+                                                       const void *indices,
+                                                       GLint basevertex);
+void INTERNAL_GL_APIENTRY glDrawElementsIndirectNULL(GLenum mode,
+                                                     GLenum type,
+                                                     const void *indirect);
+void INTERNAL_GL_APIENTRY glDrawElementsInstancedNULL(GLenum mode,
+                                                      GLsizei count,
+                                                      GLenum type,
+                                                      const void *indices,
+                                                      GLsizei instancecount);
+void INTERNAL_GL_APIENTRY glDrawElementsInstancedBaseInstanceNULL(GLenum mode,
+                                                                  GLsizei count,
+                                                                  GLenum type,
+                                                                  const void *indices,
+                                                                  GLsizei instancecount,
+                                                                  GLuint baseinstance);
+void INTERNAL_GL_APIENTRY glDrawElementsInstancedBaseVertexNULL(GLenum mode,
+                                                                GLsizei count,
+                                                                GLenum type,
+                                                                const void *indices,
+                                                                GLsizei instancecount,
+                                                                GLint basevertex);
+void INTERNAL_GL_APIENTRY glDrawElementsInstancedBaseVertexBaseInstanceNULL(GLenum mode,
+                                                                            GLsizei count,
+                                                                            GLenum type,
+                                                                            const void *indices,
+                                                                            GLsizei instancecount,
+                                                                            GLint basevertex,
+                                                                            GLuint baseinstance);
+void INTERNAL_GL_APIENTRY glDrawRangeElementsNULL(GLenum mode,
+                                                  GLuint start,
+                                                  GLuint end,
+                                                  GLsizei count,
+                                                  GLenum type,
+                                                  const void *indices);
+void INTERNAL_GL_APIENTRY glDrawRangeElementsBaseVertexNULL(GLenum mode,
+                                                            GLuint start,
+                                                            GLuint end,
+                                                            GLsizei count,
+                                                            GLenum type,
+                                                            const void *indices,
+                                                            GLint basevertex);
+void INTERNAL_GL_APIENTRY glDrawTransformFeedbackNULL(GLenum mode, GLuint id);
+void INTERNAL_GL_APIENTRY glDrawTransformFeedbackInstancedNULL(GLenum mode,
+                                                               GLuint id,
+                                                               GLsizei instancecount);
+void INTERNAL_GL_APIENTRY glDrawTransformFeedbackStreamNULL(GLenum mode, GLuint id, GLuint stream);
+void INTERNAL_GL_APIENTRY glDrawTransformFeedbackStreamInstancedNULL(GLenum mode,
+                                                                     GLuint id,
+                                                                     GLuint stream,
+                                                                     GLsizei instancecount);
+void INTERNAL_GL_APIENTRY glEGLImageTargetRenderbufferStorageOESNULL(GLenum target,
+                                                                     GLeglImageOES image);
+void INTERNAL_GL_APIENTRY glEGLImageTargetTexture2DOESNULL(GLenum target, GLeglImageOES image);
+void INTERNAL_GL_APIENTRY glEnableNULL(GLenum cap);
+void INTERNAL_GL_APIENTRY glEnableVertexArrayAttribNULL(GLuint vaobj, GLuint index);
+void INTERNAL_GL_APIENTRY glEnableVertexAttribArrayNULL(GLuint index);
+void INTERNAL_GL_APIENTRY glEnableiNULL(GLenum target, GLuint index);
+void INTERNAL_GL_APIENTRY glEndConditionalRenderNULL();
+void INTERNAL_GL_APIENTRY glEndQueryNULL(GLenum target);
+void INTERNAL_GL_APIENTRY glEndQueryIndexedNULL(GLenum target, GLuint index);
+void INTERNAL_GL_APIENTRY glEndTransformFeedbackNULL();
+GLsync INTERNAL_GL_APIENTRY glFenceSyncNULL(GLenum condition, GLbitfield flags);
+void INTERNAL_GL_APIENTRY glFinishNULL();
+void INTERNAL_GL_APIENTRY glFinishFenceNVNULL(GLuint fence);
+void INTERNAL_GL_APIENTRY glFlushNULL();
+void INTERNAL_GL_APIENTRY glFlushMappedBufferRangeNULL(GLenum target,
+                                                       GLintptr offset,
+                                                       GLsizeiptr length);
+void INTERNAL_GL_APIENTRY glFlushMappedNamedBufferRangeNULL(GLuint buffer,
+                                                            GLintptr offset,
+                                                            GLsizeiptr length);
+void INTERNAL_GL_APIENTRY glFramebufferParameteriNULL(GLenum target, GLenum pname, GLint param);
+void INTERNAL_GL_APIENTRY glFramebufferRenderbufferNULL(GLenum target,
+                                                        GLenum attachment,
+                                                        GLenum renderbuffertarget,
+                                                        GLuint renderbuffer);
+void INTERNAL_GL_APIENTRY glFramebufferTextureNULL(GLenum target,
+                                                   GLenum attachment,
+                                                   GLuint texture,
+                                                   GLint level);
+void INTERNAL_GL_APIENTRY glFramebufferTexture1DNULL(GLenum target,
+                                                     GLenum attachment,
+                                                     GLenum textarget,
+                                                     GLuint texture,
+                                                     GLint level);
+void INTERNAL_GL_APIENTRY glFramebufferTexture2DNULL(GLenum target,
+                                                     GLenum attachment,
+                                                     GLenum textarget,
+                                                     GLuint texture,
+                                                     GLint level);
+void INTERNAL_GL_APIENTRY glFramebufferTexture3DNULL(GLenum target,
+                                                     GLenum attachment,
+                                                     GLenum textarget,
+                                                     GLuint texture,
+                                                     GLint level,
+                                                     GLint zoffset);
+void INTERNAL_GL_APIENTRY glFramebufferTextureLayerNULL(GLenum target,
+                                                        GLenum attachment,
+                                                        GLuint texture,
+                                                        GLint level,
+                                                        GLint layer);
+void INTERNAL_GL_APIENTRY glFrontFaceNULL(GLenum mode);
+void INTERNAL_GL_APIENTRY glGenBuffersNULL(GLsizei n, GLuint *buffers);
+void INTERNAL_GL_APIENTRY glGenFencesNVNULL(GLsizei n, GLuint *fences);
+void INTERNAL_GL_APIENTRY glGenFramebuffersNULL(GLsizei n, GLuint *framebuffers);
+GLuint INTERNAL_GL_APIENTRY glGenPathsNVNULL(GLsizei range);
+void INTERNAL_GL_APIENTRY glGenProgramPipelinesNULL(GLsizei n, GLuint *pipelines);
+void INTERNAL_GL_APIENTRY glGenQueriesNULL(GLsizei n, GLuint *ids);
+void INTERNAL_GL_APIENTRY glGenRenderbuffersNULL(GLsizei n, GLuint *renderbuffers);
+void INTERNAL_GL_APIENTRY glGenSamplersNULL(GLsizei count, GLuint *samplers);
+void INTERNAL_GL_APIENTRY glGenTexturesNULL(GLsizei n, GLuint *textures);
+void INTERNAL_GL_APIENTRY glGenTransformFeedbacksNULL(GLsizei n, GLuint *ids);
+void INTERNAL_GL_APIENTRY glGenVertexArraysNULL(GLsizei n, GLuint *arrays);
+void INTERNAL_GL_APIENTRY glGenerateMipmapNULL(GLenum target);
+void INTERNAL_GL_APIENTRY glGenerateTextureMipmapNULL(GLuint texture);
+void INTERNAL_GL_APIENTRY glGetActiveAtomicCounterBufferivNULL(GLuint program,
+                                                               GLuint bufferIndex,
+                                                               GLenum pname,
+                                                               GLint *params);
+void INTERNAL_GL_APIENTRY glGetActiveAttribNULL(GLuint program,
+                                                GLuint index,
+                                                GLsizei bufSize,
+                                                GLsizei *length,
+                                                GLint *size,
+                                                GLenum *type,
+                                                GLchar *name);
+void INTERNAL_GL_APIENTRY glGetActiveSubroutineNameNULL(GLuint program,
+                                                        GLenum shadertype,
+                                                        GLuint index,
+                                                        GLsizei bufsize,
+                                                        GLsizei *length,
+                                                        GLchar *name);
+void INTERNAL_GL_APIENTRY glGetActiveSubroutineUniformNameNULL(GLuint program,
+                                                               GLenum shadertype,
+                                                               GLuint index,
+                                                               GLsizei bufsize,
+                                                               GLsizei *length,
+                                                               GLchar *name);
+void INTERNAL_GL_APIENTRY glGetActiveSubroutineUniformivNULL(GLuint program,
+                                                             GLenum shadertype,
+                                                             GLuint index,
+                                                             GLenum pname,
+                                                             GLint *values);
+void INTERNAL_GL_APIENTRY glGetActiveUniformNULL(GLuint program,
+                                                 GLuint index,
+                                                 GLsizei bufSize,
+                                                 GLsizei *length,
+                                                 GLint *size,
+                                                 GLenum *type,
+                                                 GLchar *name);
+void INTERNAL_GL_APIENTRY glGetActiveUniformBlockNameNULL(GLuint program,
+                                                          GLuint uniformBlockIndex,
+                                                          GLsizei bufSize,
+                                                          GLsizei *length,
+                                                          GLchar *uniformBlockName);
+void INTERNAL_GL_APIENTRY glGetActiveUniformBlockivNULL(GLuint program,
+                                                        GLuint uniformBlockIndex,
+                                                        GLenum pname,
+                                                        GLint *params);
+void INTERNAL_GL_APIENTRY glGetActiveUniformNameNULL(GLuint program,
+                                                     GLuint uniformIndex,
+                                                     GLsizei bufSize,
+                                                     GLsizei *length,
+                                                     GLchar *uniformName);
+void INTERNAL_GL_APIENTRY glGetActiveUniformsivNULL(GLuint program,
+                                                    GLsizei uniformCount,
+                                                    const GLuint *uniformIndices,
+                                                    GLenum pname,
+                                                    GLint *params);
+void INTERNAL_GL_APIENTRY glGetAttachedShadersNULL(GLuint program,
+                                                   GLsizei maxCount,
+                                                   GLsizei *count,
+                                                   GLuint *shaders);
+GLint INTERNAL_GL_APIENTRY glGetAttribLocationNULL(GLuint program, const GLchar *name);
+void INTERNAL_GL_APIENTRY glGetBooleani_vNULL(GLenum target, GLuint index, GLboolean *data);
+void INTERNAL_GL_APIENTRY glGetBooleanvNULL(GLenum pname, GLboolean *data);
+void INTERNAL_GL_APIENTRY glGetBufferParameteri64vNULL(GLenum target,
+                                                       GLenum pname,
+                                                       GLint64 *params);
+void INTERNAL_GL_APIENTRY glGetBufferParameterivNULL(GLenum target, GLenum pname, GLint *params);
+void INTERNAL_GL_APIENTRY glGetBufferPointervNULL(GLenum target, GLenum pname, void **params);
+void INTERNAL_GL_APIENTRY glGetBufferSubDataNULL(GLenum target,
+                                                 GLintptr offset,
+                                                 GLsizeiptr size,
+                                                 void *data);
+void INTERNAL_GL_APIENTRY glGetCompressedTexImageNULL(GLenum target, GLint level, void *img);
+void INTERNAL_GL_APIENTRY glGetCompressedTextureImageNULL(GLuint texture,
+                                                          GLint level,
+                                                          GLsizei bufSize,
+                                                          void *pixels);
+void INTERNAL_GL_APIENTRY glGetCompressedTextureSubImageNULL(GLuint texture,
+                                                             GLint level,
+                                                             GLint xoffset,
+                                                             GLint yoffset,
+                                                             GLint zoffset,
+                                                             GLsizei width,
+                                                             GLsizei height,
+                                                             GLsizei depth,
+                                                             GLsizei bufSize,
+                                                             void *pixels);
+GLuint INTERNAL_GL_APIENTRY glGetDebugMessageLogNULL(GLuint count,
+                                                     GLsizei bufSize,
+                                                     GLenum *sources,
+                                                     GLenum *types,
+                                                     GLuint *ids,
+                                                     GLenum *severities,
+                                                     GLsizei *lengths,
+                                                     GLchar *messageLog);
+void INTERNAL_GL_APIENTRY glGetDoublei_vNULL(GLenum target, GLuint index, GLdouble *data);
+void INTERNAL_GL_APIENTRY glGetDoublevNULL(GLenum pname, GLdouble *data);
+GLenum INTERNAL_GL_APIENTRY glGetErrorNULL();
+void INTERNAL_GL_APIENTRY glGetFenceivNVNULL(GLuint fence, GLenum pname, GLint *params);
+void INTERNAL_GL_APIENTRY glGetFloati_vNULL(GLenum target, GLuint index, GLfloat *data);
+void INTERNAL_GL_APIENTRY glGetFloatvNULL(GLenum pname, GLfloat *data);
+GLint INTERNAL_GL_APIENTRY glGetFragDataIndexNULL(GLuint program, const GLchar *name);
+GLint INTERNAL_GL_APIENTRY glGetFragDataLocationNULL(GLuint program, const GLchar *name);
+void INTERNAL_GL_APIENTRY glGetFramebufferAttachmentParameterivNULL(GLenum target,
+                                                                    GLenum attachment,
+                                                                    GLenum pname,
+                                                                    GLint *params);
+void INTERNAL_GL_APIENTRY glGetFramebufferParameterivNULL(GLenum target,
+                                                          GLenum pname,
+                                                          GLint *params);
+GLenum INTERNAL_GL_APIENTRY glGetGraphicsResetStatusNULL();
+void INTERNAL_GL_APIENTRY glGetInteger64i_vNULL(GLenum target, GLuint index, GLint64 *data);
+void INTERNAL_GL_APIENTRY glGetInteger64vNULL(GLenum pname, GLint64 *data);
+void INTERNAL_GL_APIENTRY glGetIntegeri_vNULL(GLenum target, GLuint index, GLint *data);
+void INTERNAL_GL_APIENTRY glGetIntegervNULL(GLenum pname, GLint *data);
+void INTERNAL_GL_APIENTRY glGetInternalformatSampleivNVNULL(GLenum target,
+                                                            GLenum internalformat,
+                                                            GLsizei samples,
+                                                            GLenum pname,
+                                                            GLsizei bufSize,
+                                                            GLint *params);
+void INTERNAL_GL_APIENTRY glGetInternalformati64vNULL(GLenum target,
+                                                      GLenum internalformat,
+                                                      GLenum pname,
+                                                      GLsizei bufSize,
+                                                      GLint64 *params);
+void INTERNAL_GL_APIENTRY glGetInternalformativNULL(GLenum target,
+                                                    GLenum internalformat,
+                                                    GLenum pname,
+                                                    GLsizei bufSize,
+                                                    GLint *params);
+void INTERNAL_GL_APIENTRY glGetMultisamplefvNULL(GLenum pname, GLuint index, GLfloat *val);
+void INTERNAL_GL_APIENTRY glGetNamedBufferParameteri64vNULL(GLuint buffer,
+                                                            GLenum pname,
+                                                            GLint64 *params);
+void INTERNAL_GL_APIENTRY glGetNamedBufferParameterivNULL(GLuint buffer,
+                                                          GLenum pname,
+                                                          GLint *params);
+void INTERNAL_GL_APIENTRY glGetNamedBufferPointervNULL(GLuint buffer, GLenum pname, void **params);
+void INTERNAL_GL_APIENTRY glGetNamedBufferSubDataNULL(GLuint buffer,
+                                                      GLintptr offset,
+                                                      GLsizeiptr size,
+                                                      void *data);
+void INTERNAL_GL_APIENTRY glGetNamedFramebufferAttachmentParameterivNULL(GLuint framebuffer,
+                                                                         GLenum attachment,
+                                                                         GLenum pname,
+                                                                         GLint *params);
+void INTERNAL_GL_APIENTRY glGetNamedFramebufferParameterivNULL(GLuint framebuffer,
+                                                               GLenum pname,
+                                                               GLint *param);
+void INTERNAL_GL_APIENTRY glGetNamedRenderbufferParameterivNULL(GLuint renderbuffer,
+                                                                GLenum pname,
+                                                                GLint *params);
+void INTERNAL_GL_APIENTRY glGetObjectLabelNULL(GLenum identifier,
+                                               GLuint name,
+                                               GLsizei bufSize,
+                                               GLsizei *length,
+                                               GLchar *label);
+void INTERNAL_GL_APIENTRY glGetObjectPtrLabelNULL(const void *ptr,
+                                                  GLsizei bufSize,
+                                                  GLsizei *length,
+                                                  GLchar *label);
+void INTERNAL_GL_APIENTRY glGetPathParameterfvNVNULL(GLuint path, GLenum pname, GLfloat *value);
+void INTERNAL_GL_APIENTRY glGetPathParameterivNVNULL(GLuint path, GLenum pname, GLint *value);
+void INTERNAL_GL_APIENTRY glGetPointervNULL(GLenum pname, void **params);
+void INTERNAL_GL_APIENTRY glGetProgramBinaryNULL(GLuint program,
+                                                 GLsizei bufSize,
+                                                 GLsizei *length,
+                                                 GLenum *binaryFormat,
+                                                 void *binary);
+void INTERNAL_GL_APIENTRY glGetProgramInfoLogNULL(GLuint program,
+                                                  GLsizei bufSize,
+                                                  GLsizei *length,
+                                                  GLchar *infoLog);
+void INTERNAL_GL_APIENTRY glGetProgramInterfaceivNULL(GLuint program,
+                                                      GLenum programInterface,
+                                                      GLenum pname,
+                                                      GLint *params);
+void INTERNAL_GL_APIENTRY glGetProgramPipelineInfoLogNULL(GLuint pipeline,
+                                                          GLsizei bufSize,
+                                                          GLsizei *length,
+                                                          GLchar *infoLog);
+void INTERNAL_GL_APIENTRY glGetProgramPipelineivNULL(GLuint pipeline, GLenum pname, GLint *params);
+GLuint INTERNAL_GL_APIENTRY glGetProgramResourceIndexNULL(GLuint program,
+                                                          GLenum programInterface,
+                                                          const GLchar *name);
+GLint INTERNAL_GL_APIENTRY glGetProgramResourceLocationNULL(GLuint program,
+                                                            GLenum programInterface,
+                                                            const GLchar *name);
+GLint INTERNAL_GL_APIENTRY glGetProgramResourceLocationIndexNULL(GLuint program,
+                                                                 GLenum programInterface,
+                                                                 const GLchar *name);
+void INTERNAL_GL_APIENTRY glGetProgramResourceNameNULL(GLuint program,
+                                                       GLenum programInterface,
+                                                       GLuint index,
+                                                       GLsizei bufSize,
+                                                       GLsizei *length,
+                                                       GLchar *name);
+void INTERNAL_GL_APIENTRY glGetProgramResourceivNULL(GLuint program,
+                                                     GLenum programInterface,
+                                                     GLuint index,
+                                                     GLsizei propCount,
+                                                     const GLenum *props,
+                                                     GLsizei bufSize,
+                                                     GLsizei *length,
+                                                     GLint *params);
+void INTERNAL_GL_APIENTRY glGetProgramStageivNULL(GLuint program,
+                                                  GLenum shadertype,
+                                                  GLenum pname,
+                                                  GLint *values);
+void INTERNAL_GL_APIENTRY glGetProgramivNULL(GLuint program, GLenum pname, GLint *params);
+void INTERNAL_GL_APIENTRY glGetQueryBufferObjecti64vNULL(GLuint id,
+                                                         GLuint buffer,
+                                                         GLenum pname,
+                                                         GLintptr offset);
+void INTERNAL_GL_APIENTRY glGetQueryBufferObjectivNULL(GLuint id,
+                                                       GLuint buffer,
+                                                       GLenum pname,
+                                                       GLintptr offset);
+void INTERNAL_GL_APIENTRY glGetQueryBufferObjectui64vNULL(GLuint id,
+                                                          GLuint buffer,
+                                                          GLenum pname,
+                                                          GLintptr offset);
+void INTERNAL_GL_APIENTRY glGetQueryBufferObjectuivNULL(GLuint id,
+                                                        GLuint buffer,
+                                                        GLenum pname,
+                                                        GLintptr offset);
+void INTERNAL_GL_APIENTRY glGetQueryIndexedivNULL(GLenum target,
+                                                  GLuint index,
+                                                  GLenum pname,
+                                                  GLint *params);
+void INTERNAL_GL_APIENTRY glGetQueryObjecti64vNULL(GLuint id, GLenum pname, GLint64 *params);
+void INTERNAL_GL_APIENTRY glGetQueryObjectivNULL(GLuint id, GLenum pname, GLint *params);
+void INTERNAL_GL_APIENTRY glGetQueryObjectui64vNULL(GLuint id, GLenum pname, GLuint64 *params);
+void INTERNAL_GL_APIENTRY glGetQueryObjectuivNULL(GLuint id, GLenum pname, GLuint *params);
+void INTERNAL_GL_APIENTRY glGetQueryivNULL(GLenum target, GLenum pname, GLint *params);
+void INTERNAL_GL_APIENTRY glGetRenderbufferParameterivNULL(GLenum target,
+                                                           GLenum pname,
+                                                           GLint *params);
+void INTERNAL_GL_APIENTRY glGetSamplerParameterIivNULL(GLuint sampler, GLenum pname, GLint *params);
+void INTERNAL_GL_APIENTRY glGetSamplerParameterIuivNULL(GLuint sampler,
+                                                        GLenum pname,
+                                                        GLuint *params);
+void INTERNAL_GL_APIENTRY glGetSamplerParameterfvNULL(GLuint sampler,
+                                                      GLenum pname,
+                                                      GLfloat *params);
+void INTERNAL_GL_APIENTRY glGetSamplerParameterivNULL(GLuint sampler, GLenum pname, GLint *params);
+void INTERNAL_GL_APIENTRY glGetShaderInfoLogNULL(GLuint shader,
+                                                 GLsizei bufSize,
+                                                 GLsizei *length,
+                                                 GLchar *infoLog);
+void INTERNAL_GL_APIENTRY glGetShaderPrecisionFormatNULL(GLenum shadertype,
+                                                         GLenum precisiontype,
+                                                         GLint *range,
+                                                         GLint *precision);
+void INTERNAL_GL_APIENTRY glGetShaderSourceNULL(GLuint shader,
+                                                GLsizei bufSize,
+                                                GLsizei *length,
+                                                GLchar *source);
+void INTERNAL_GL_APIENTRY glGetShaderivNULL(GLuint shader, GLenum pname, GLint *params);
+const GLubyte *INTERNAL_GL_APIENTRY glGetStringNULL(GLenum name);
+const GLubyte *INTERNAL_GL_APIENTRY glGetStringiNULL(GLenum name, GLuint index);
+GLuint INTERNAL_GL_APIENTRY glGetSubroutineIndexNULL(GLuint program,
+                                                     GLenum shadertype,
+                                                     const GLchar *name);
+GLint INTERNAL_GL_APIENTRY glGetSubroutineUniformLocationNULL(GLuint program,
+                                                              GLenum shadertype,
+                                                              const GLchar *name);
+void INTERNAL_GL_APIENTRY
+glGetSyncivNULL(GLsync sync, GLenum pname, GLsizei bufSize, GLsizei *length, GLint *values);
+void INTERNAL_GL_APIENTRY
+glGetTexImageNULL(GLenum target, GLint level, GLenum format, GLenum type, void *pixels);
+void INTERNAL_GL_APIENTRY glGetTexLevelParameterfvNULL(GLenum target,
+                                                       GLint level,
+                                                       GLenum pname,
+                                                       GLfloat *params);
+void INTERNAL_GL_APIENTRY glGetTexLevelParameterivNULL(GLenum target,
+                                                       GLint level,
+                                                       GLenum pname,
+                                                       GLint *params);
+void INTERNAL_GL_APIENTRY glGetTexParameterIivNULL(GLenum target, GLenum pname, GLint *params);
+void INTERNAL_GL_APIENTRY glGetTexParameterIuivNULL(GLenum target, GLenum pname, GLuint *params);
+void INTERNAL_GL_APIENTRY glGetTexParameterfvNULL(GLenum target, GLenum pname, GLfloat *params);
+void INTERNAL_GL_APIENTRY glGetTexParameterivNULL(GLenum target, GLenum pname, GLint *params);
+void INTERNAL_GL_APIENTRY glGetTextureImageNULL(GLuint texture,
+                                                GLint level,
+                                                GLenum format,
+                                                GLenum type,
+                                                GLsizei bufSize,
+                                                void *pixels);
+void INTERNAL_GL_APIENTRY glGetTextureLevelParameterfvNULL(GLuint texture,
+                                                           GLint level,
+                                                           GLenum pname,
+                                                           GLfloat *params);
+void INTERNAL_GL_APIENTRY glGetTextureLevelParameterivNULL(GLuint texture,
+                                                           GLint level,
+                                                           GLenum pname,
+                                                           GLint *params);
+void INTERNAL_GL_APIENTRY glGetTextureParameterIivNULL(GLuint texture, GLenum pname, GLint *params);
+void INTERNAL_GL_APIENTRY glGetTextureParameterIuivNULL(GLuint texture,
+                                                        GLenum pname,
+                                                        GLuint *params);
+void INTERNAL_GL_APIENTRY glGetTextureParameterfvNULL(GLuint texture,
+                                                      GLenum pname,
+                                                      GLfloat *params);
+void INTERNAL_GL_APIENTRY glGetTextureParameterivNULL(GLuint texture, GLenum pname, GLint *params);
+void INTERNAL_GL_APIENTRY glGetTextureSubImageNULL(GLuint texture,
+                                                   GLint level,
+                                                   GLint xoffset,
+                                                   GLint yoffset,
+                                                   GLint zoffset,
+                                                   GLsizei width,
+                                                   GLsizei height,
+                                                   GLsizei depth,
+                                                   GLenum format,
+                                                   GLenum type,
+                                                   GLsizei bufSize,
+                                                   void *pixels);
+void INTERNAL_GL_APIENTRY glGetTransformFeedbackVaryingNULL(GLuint program,
+                                                            GLuint index,
+                                                            GLsizei bufSize,
+                                                            GLsizei *length,
+                                                            GLsizei *size,
+                                                            GLenum *type,
+                                                            GLchar *name);
+void INTERNAL_GL_APIENTRY glGetTransformFeedbacki64_vNULL(GLuint xfb,
+                                                          GLenum pname,
+                                                          GLuint index,
+                                                          GLint64 *param);
+void INTERNAL_GL_APIENTRY glGetTransformFeedbacki_vNULL(GLuint xfb,
+                                                        GLenum pname,
+                                                        GLuint index,
+                                                        GLint *param);
+void INTERNAL_GL_APIENTRY glGetTransformFeedbackivNULL(GLuint xfb, GLenum pname, GLint *param);
+GLuint INTERNAL_GL_APIENTRY glGetUniformBlockIndexNULL(GLuint program,
+                                                       const GLchar *uniformBlockName);
+void INTERNAL_GL_APIENTRY glGetUniformIndicesNULL(GLuint program,
+                                                  GLsizei uniformCount,
+                                                  const GLchar *const *uniformNames,
+                                                  GLuint *uniformIndices);
+GLint INTERNAL_GL_APIENTRY glGetUniformLocationNULL(GLuint program, const GLchar *name);
+void INTERNAL_GL_APIENTRY glGetUniformSubroutineuivNULL(GLenum shadertype,
+                                                        GLint location,
+                                                        GLuint *params);
+void INTERNAL_GL_APIENTRY glGetUniformdvNULL(GLuint program, GLint location, GLdouble *params);
+void INTERNAL_GL_APIENTRY glGetUniformfvNULL(GLuint program, GLint location, GLfloat *params);
+void INTERNAL_GL_APIENTRY glGetUniformivNULL(GLuint program, GLint location, GLint *params);
+void INTERNAL_GL_APIENTRY glGetUniformuivNULL(GLuint program, GLint location, GLuint *params);
+void INTERNAL_GL_APIENTRY glGetVertexArrayIndexed64ivNULL(GLuint vaobj,
+                                                          GLuint index,
+                                                          GLenum pname,
+                                                          GLint64 *param);
+void INTERNAL_GL_APIENTRY glGetVertexArrayIndexedivNULL(GLuint vaobj,
+                                                        GLuint index,
+                                                        GLenum pname,
+                                                        GLint *param);
+void INTERNAL_GL_APIENTRY glGetVertexArrayivNULL(GLuint vaobj, GLenum pname, GLint *param);
+void INTERNAL_GL_APIENTRY glGetVertexAttribIivNULL(GLuint index, GLenum pname, GLint *params);
+void INTERNAL_GL_APIENTRY glGetVertexAttribIuivNULL(GLuint index, GLenum pname, GLuint *params);
+void INTERNAL_GL_APIENTRY glGetVertexAttribLdvNULL(GLuint index, GLenum pname, GLdouble *params);
+void INTERNAL_GL_APIENTRY glGetVertexAttribPointervNULL(GLuint index, GLenum pname, void **pointer);
+void INTERNAL_GL_APIENTRY glGetVertexAttribdvNULL(GLuint index, GLenum pname, GLdouble *params);
+void INTERNAL_GL_APIENTRY glGetVertexAttribfvNULL(GLuint index, GLenum pname, GLfloat *params);
+void INTERNAL_GL_APIENTRY glGetVertexAttribivNULL(GLuint index, GLenum pname, GLint *params);
+void INTERNAL_GL_APIENTRY glGetnCompressedTexImageNULL(GLenum target,
+                                                       GLint lod,
+                                                       GLsizei bufSize,
+                                                       void *pixels);
+void INTERNAL_GL_APIENTRY glGetnTexImageNULL(GLenum target,
+                                             GLint level,
+                                             GLenum format,
+                                             GLenum type,
+                                             GLsizei bufSize,
+                                             void *pixels);
+void INTERNAL_GL_APIENTRY glGetnUniformdvNULL(GLuint program,
+                                              GLint location,
+                                              GLsizei bufSize,
+                                              GLdouble *params);
+void INTERNAL_GL_APIENTRY glGetnUniformfvNULL(GLuint program,
+                                              GLint location,
+                                              GLsizei bufSize,
+                                              GLfloat *params);
+void INTERNAL_GL_APIENTRY glGetnUniformivNULL(GLuint program,
+                                              GLint location,
+                                              GLsizei bufSize,
+                                              GLint *params);
+void INTERNAL_GL_APIENTRY glGetnUniformuivNULL(GLuint program,
+                                               GLint location,
+                                               GLsizei bufSize,
+                                               GLuint *params);
+void INTERNAL_GL_APIENTRY glHintNULL(GLenum target, GLenum mode);
+void INTERNAL_GL_APIENTRY glInsertEventMarkerEXTNULL(GLsizei length, const GLchar *marker);
+void INTERNAL_GL_APIENTRY glInvalidateBufferDataNULL(GLuint buffer);
+void INTERNAL_GL_APIENTRY glInvalidateBufferSubDataNULL(GLuint buffer,
+                                                        GLintptr offset,
+                                                        GLsizeiptr length);
+void INTERNAL_GL_APIENTRY glInvalidateFramebufferNULL(GLenum target,
+                                                      GLsizei numAttachments,
+                                                      const GLenum *attachments);
+void INTERNAL_GL_APIENTRY glInvalidateNamedFramebufferDataNULL(GLuint framebuffer,
+                                                               GLsizei numAttachments,
+                                                               const GLenum *attachments);
+void INTERNAL_GL_APIENTRY glInvalidateNamedFramebufferSubDataNULL(GLuint framebuffer,
+                                                                  GLsizei numAttachments,
+                                                                  const GLenum *attachments,
+                                                                  GLint x,
+                                                                  GLint y,
+                                                                  GLsizei width,
+                                                                  GLsizei height);
+void INTERNAL_GL_APIENTRY glInvalidateSubFramebufferNULL(GLenum target,
+                                                         GLsizei numAttachments,
+                                                         const GLenum *attachments,
+                                                         GLint x,
+                                                         GLint y,
+                                                         GLsizei width,
+                                                         GLsizei height);
+void INTERNAL_GL_APIENTRY glInvalidateTexImageNULL(GLuint texture, GLint level);
+void INTERNAL_GL_APIENTRY glInvalidateTexSubImageNULL(GLuint texture,
+                                                      GLint level,
+                                                      GLint xoffset,
+                                                      GLint yoffset,
+                                                      GLint zoffset,
+                                                      GLsizei width,
+                                                      GLsizei height,
+                                                      GLsizei depth);
+GLboolean INTERNAL_GL_APIENTRY glIsBufferNULL(GLuint buffer);
+GLboolean INTERNAL_GL_APIENTRY glIsEnabledNULL(GLenum cap);
+GLboolean INTERNAL_GL_APIENTRY glIsEnablediNULL(GLenum target, GLuint index);
+GLboolean INTERNAL_GL_APIENTRY glIsFenceNVNULL(GLuint fence);
+GLboolean INTERNAL_GL_APIENTRY glIsFramebufferNULL(GLuint framebuffer);
+GLboolean INTERNAL_GL_APIENTRY glIsPathNVNULL(GLuint path);
+GLboolean INTERNAL_GL_APIENTRY glIsProgramNULL(GLuint program);
+GLboolean INTERNAL_GL_APIENTRY glIsProgramPipelineNULL(GLuint pipeline);
+GLboolean INTERNAL_GL_APIENTRY glIsQueryNULL(GLuint id);
+GLboolean INTERNAL_GL_APIENTRY glIsRenderbufferNULL(GLuint renderbuffer);
+GLboolean INTERNAL_GL_APIENTRY glIsSamplerNULL(GLuint sampler);
+GLboolean INTERNAL_GL_APIENTRY glIsShaderNULL(GLuint shader);
+GLboolean INTERNAL_GL_APIENTRY glIsSyncNULL(GLsync sync);
+GLboolean INTERNAL_GL_APIENTRY glIsTextureNULL(GLuint texture);
+GLboolean INTERNAL_GL_APIENTRY glIsTransformFeedbackNULL(GLuint id);
+GLboolean INTERNAL_GL_APIENTRY glIsVertexArrayNULL(GLuint array);
+void INTERNAL_GL_APIENTRY glLineWidthNULL(GLfloat width);
+void INTERNAL_GL_APIENTRY glLinkProgramNULL(GLuint program);
+void INTERNAL_GL_APIENTRY glLogicOpNULL(GLenum opcode);
+void *INTERNAL_GL_APIENTRY glMapBufferNULL(GLenum target, GLenum access);
+void *INTERNAL_GL_APIENTRY glMapBufferRangeNULL(GLenum target,
+                                                GLintptr offset,
+                                                GLsizeiptr length,
+                                                GLbitfield access);
+void *INTERNAL_GL_APIENTRY glMapNamedBufferNULL(GLuint buffer, GLenum access);
+void *INTERNAL_GL_APIENTRY glMapNamedBufferRangeNULL(GLuint buffer,
+                                                     GLintptr offset,
+                                                     GLsizeiptr length,
+                                                     GLbitfield access);
+void INTERNAL_GL_APIENTRY glMatrixLoadfEXTNULL(GLenum mode, const GLfloat *m);
+void INTERNAL_GL_APIENTRY glMemoryBarrierNULL(GLbitfield barriers);
+void INTERNAL_GL_APIENTRY glMemoryBarrierByRegionNULL(GLbitfield barriers);
+void INTERNAL_GL_APIENTRY glMinSampleShadingNULL(GLfloat value);
+void INTERNAL_GL_APIENTRY glMultiDrawArraysNULL(GLenum mode,
+                                                const GLint *first,
+                                                const GLsizei *count,
+                                                GLsizei drawcount);
+void INTERNAL_GL_APIENTRY glMultiDrawArraysIndirectNULL(GLenum mode,
+                                                        const void *indirect,
+                                                        GLsizei drawcount,
+                                                        GLsizei stride);
+void INTERNAL_GL_APIENTRY glMultiDrawElementsNULL(GLenum mode,
+                                                  const GLsizei *count,
+                                                  GLenum type,
+                                                  const void *const *indices,
+                                                  GLsizei drawcount);
+void INTERNAL_GL_APIENTRY glMultiDrawElementsBaseVertexNULL(GLenum mode,
+                                                            const GLsizei *count,
+                                                            GLenum type,
+                                                            const void *const *indices,
+                                                            GLsizei drawcount,
+                                                            const GLint *basevertex);
+void INTERNAL_GL_APIENTRY glMultiDrawElementsIndirectNULL(GLenum mode,
+                                                          GLenum type,
+                                                          const void *indirect,
+                                                          GLsizei drawcount,
+                                                          GLsizei stride);
+void INTERNAL_GL_APIENTRY glNamedBufferDataNULL(GLuint buffer,
+                                                GLsizeiptr size,
+                                                const void *data,
+                                                GLenum usage);
+void INTERNAL_GL_APIENTRY glNamedBufferStorageNULL(GLuint buffer,
+                                                   GLsizeiptr size,
+                                                   const void *data,
+                                                   GLbitfield flags);
+void INTERNAL_GL_APIENTRY glNamedBufferSubDataNULL(GLuint buffer,
+                                                   GLintptr offset,
+                                                   GLsizeiptr size,
+                                                   const void *data);
+void INTERNAL_GL_APIENTRY glNamedFramebufferDrawBufferNULL(GLuint framebuffer, GLenum buf);
+void INTERNAL_GL_APIENTRY glNamedFramebufferDrawBuffersNULL(GLuint framebuffer,
+                                                            GLsizei n,
+                                                            const GLenum *bufs);
+void INTERNAL_GL_APIENTRY glNamedFramebufferParameteriNULL(GLuint framebuffer,
+                                                           GLenum pname,
+                                                           GLint param);
+void INTERNAL_GL_APIENTRY glNamedFramebufferReadBufferNULL(GLuint framebuffer, GLenum src);
+void INTERNAL_GL_APIENTRY glNamedFramebufferRenderbufferNULL(GLuint framebuffer,
+                                                             GLenum attachment,
+                                                             GLenum renderbuffertarget,
+                                                             GLuint renderbuffer);
+void INTERNAL_GL_APIENTRY glNamedFramebufferTextureNULL(GLuint framebuffer,
+                                                        GLenum attachment,
+                                                        GLuint texture,
+                                                        GLint level);
+void INTERNAL_GL_APIENTRY glNamedFramebufferTextureLayerNULL(GLuint framebuffer,
+                                                             GLenum attachment,
+                                                             GLuint texture,
+                                                             GLint level,
+                                                             GLint layer);
+void INTERNAL_GL_APIENTRY glNamedRenderbufferStorageNULL(GLuint renderbuffer,
+                                                         GLenum internalformat,
+                                                         GLsizei width,
+                                                         GLsizei height);
+void INTERNAL_GL_APIENTRY glNamedRenderbufferStorageMultisampleNULL(GLuint renderbuffer,
+                                                                    GLsizei samples,
+                                                                    GLenum internalformat,
+                                                                    GLsizei width,
+                                                                    GLsizei height);
+void INTERNAL_GL_APIENTRY glObjectLabelNULL(GLenum identifier,
+                                            GLuint name,
+                                            GLsizei length,
+                                            const GLchar *label);
+void INTERNAL_GL_APIENTRY glObjectPtrLabelNULL(const void *ptr,
+                                               GLsizei length,
+                                               const GLchar *label);
+void INTERNAL_GL_APIENTRY glPatchParameterfvNULL(GLenum pname, const GLfloat *values);
+void INTERNAL_GL_APIENTRY glPatchParameteriNULL(GLenum pname, GLint value);
+void INTERNAL_GL_APIENTRY glPathCommandsNVNULL(GLuint path,
+                                               GLsizei numCommands,
+                                               const GLubyte *commands,
+                                               GLsizei numCoords,
+                                               GLenum coordType,
+                                               const void *coords);
+void INTERNAL_GL_APIENTRY glPathParameterfNVNULL(GLuint path, GLenum pname, GLfloat value);
+void INTERNAL_GL_APIENTRY glPathParameteriNVNULL(GLuint path, GLenum pname, GLint value);
+void INTERNAL_GL_APIENTRY glPathStencilFuncNVNULL(GLenum func, GLint ref, GLuint mask);
+void INTERNAL_GL_APIENTRY glPauseTransformFeedbackNULL();
+void INTERNAL_GL_APIENTRY glPixelStorefNULL(GLenum pname, GLfloat param);
+void INTERNAL_GL_APIENTRY glPixelStoreiNULL(GLenum pname, GLint param);
+void INTERNAL_GL_APIENTRY glPointParameterfNULL(GLenum pname, GLfloat param);
+void INTERNAL_GL_APIENTRY glPointParameterfvNULL(GLenum pname, const GLfloat *params);
+void INTERNAL_GL_APIENTRY glPointParameteriNULL(GLenum pname, GLint param);
+void INTERNAL_GL_APIENTRY glPointParameterivNULL(GLenum pname, const GLint *params);
+void INTERNAL_GL_APIENTRY glPointSizeNULL(GLfloat size);
+void INTERNAL_GL_APIENTRY glPolygonModeNULL(GLenum face, GLenum mode);
+void INTERNAL_GL_APIENTRY glPolygonOffsetNULL(GLfloat factor, GLfloat units);
+void INTERNAL_GL_APIENTRY glPopDebugGroupNULL();
+void INTERNAL_GL_APIENTRY glPopGroupMarkerEXTNULL();
+void INTERNAL_GL_APIENTRY glPrimitiveBoundingBoxNULL(GLfloat minX,
+                                                     GLfloat minY,
+                                                     GLfloat minZ,
+                                                     GLfloat minW,
+                                                     GLfloat maxX,
+                                                     GLfloat maxY,
+                                                     GLfloat maxZ,
+                                                     GLfloat maxW);
+void INTERNAL_GL_APIENTRY glPrimitiveRestartIndexNULL(GLuint index);
+void INTERNAL_GL_APIENTRY glProgramBinaryNULL(GLuint program,
+                                              GLenum binaryFormat,
+                                              const void *binary,
+                                              GLsizei length);
+void INTERNAL_GL_APIENTRY glProgramParameteriNULL(GLuint program, GLenum pname, GLint value);
+void INTERNAL_GL_APIENTRY glProgramPathFragmentInputGenNVNULL(GLuint program,
+                                                              GLint location,
+                                                              GLenum genMode,
+                                                              GLint components,
+                                                              const GLfloat *coeffs);
+void INTERNAL_GL_APIENTRY glProgramUniform1dNULL(GLuint program, GLint location, GLdouble v0);
+void INTERNAL_GL_APIENTRY glProgramUniform1dvNULL(GLuint program,
+                                                  GLint location,
+                                                  GLsizei count,
+                                                  const GLdouble *value);
+void INTERNAL_GL_APIENTRY glProgramUniform1fNULL(GLuint program, GLint location, GLfloat v0);
+void INTERNAL_GL_APIENTRY glProgramUniform1fvNULL(GLuint program,
+                                                  GLint location,
+                                                  GLsizei count,
+                                                  const GLfloat *value);
+void INTERNAL_GL_APIENTRY glProgramUniform1iNULL(GLuint program, GLint location, GLint v0);
+void INTERNAL_GL_APIENTRY glProgramUniform1ivNULL(GLuint program,
+                                                  GLint location,
+                                                  GLsizei count,
+                                                  const GLint *value);
+void INTERNAL_GL_APIENTRY glProgramUniform1uiNULL(GLuint program, GLint location, GLuint v0);
+void INTERNAL_GL_APIENTRY glProgramUniform1uivNULL(GLuint program,
+                                                   GLint location,
+                                                   GLsizei count,
+                                                   const GLuint *value);
+void INTERNAL_GL_APIENTRY glProgramUniform2dNULL(GLuint program,
+                                                 GLint location,
+                                                 GLdouble v0,
+                                                 GLdouble v1);
+void INTERNAL_GL_APIENTRY glProgramUniform2dvNULL(GLuint program,
+                                                  GLint location,
+                                                  GLsizei count,
+                                                  const GLdouble *value);
+void INTERNAL_GL_APIENTRY glProgramUniform2fNULL(GLuint program,
+                                                 GLint location,
+                                                 GLfloat v0,
+                                                 GLfloat v1);
+void INTERNAL_GL_APIENTRY glProgramUniform2fvNULL(GLuint program,
+                                                  GLint location,
+                                                  GLsizei count,
+                                                  const GLfloat *value);
+void INTERNAL_GL_APIENTRY glProgramUniform2iNULL(GLuint program,
+                                                 GLint location,
+                                                 GLint v0,
+                                                 GLint v1);
+void INTERNAL_GL_APIENTRY glProgramUniform2ivNULL(GLuint program,
+                                                  GLint location,
+                                                  GLsizei count,
+                                                  const GLint *value);
+void INTERNAL_GL_APIENTRY glProgramUniform2uiNULL(GLuint program,
+                                                  GLint location,
+                                                  GLuint v0,
+                                                  GLuint v1);
+void INTERNAL_GL_APIENTRY glProgramUniform2uivNULL(GLuint program,
+                                                   GLint location,
+                                                   GLsizei count,
+                                                   const GLuint *value);
+void INTERNAL_GL_APIENTRY
+glProgramUniform3dNULL(GLuint program, GLint location, GLdouble v0, GLdouble v1, GLdouble v2);
+void INTERNAL_GL_APIENTRY glProgramUniform3dvNULL(GLuint program,
+                                                  GLint location,
+                                                  GLsizei count,
+                                                  const GLdouble *value);
+void INTERNAL_GL_APIENTRY
+glProgramUniform3fNULL(GLuint program, GLint location, GLfloat v0, GLfloat v1, GLfloat v2);
+void INTERNAL_GL_APIENTRY glProgramUniform3fvNULL(GLuint program,
+                                                  GLint location,
+                                                  GLsizei count,
+                                                  const GLfloat *value);
+void INTERNAL_GL_APIENTRY
+glProgramUniform3iNULL(GLuint program, GLint location, GLint v0, GLint v1, GLint v2);
+void INTERNAL_GL_APIENTRY glProgramUniform3ivNULL(GLuint program,
+                                                  GLint location,
+                                                  GLsizei count,
+                                                  const GLint *value);
+void INTERNAL_GL_APIENTRY
+glProgramUniform3uiNULL(GLuint program, GLint location, GLuint v0, GLuint v1, GLuint v2);
+void INTERNAL_GL_APIENTRY glProgramUniform3uivNULL(GLuint program,
+                                                   GLint location,
+                                                   GLsizei count,
+                                                   const GLuint *value);
+void INTERNAL_GL_APIENTRY glProgramUniform4dNULL(GLuint program,
+                                                 GLint location,
+                                                 GLdouble v0,
+                                                 GLdouble v1,
+                                                 GLdouble v2,
+                                                 GLdouble v3);
+void INTERNAL_GL_APIENTRY glProgramUniform4dvNULL(GLuint program,
+                                                  GLint location,
+                                                  GLsizei count,
+                                                  const GLdouble *value);
+void INTERNAL_GL_APIENTRY glProgramUniform4fNULL(GLuint program,
+                                                 GLint location,
+                                                 GLfloat v0,
+                                                 GLfloat v1,
+                                                 GLfloat v2,
+                                                 GLfloat v3);
+void INTERNAL_GL_APIENTRY glProgramUniform4fvNULL(GLuint program,
+                                                  GLint location,
+                                                  GLsizei count,
+                                                  const GLfloat *value);
+void INTERNAL_GL_APIENTRY
+glProgramUniform4iNULL(GLuint program, GLint location, GLint v0, GLint v1, GLint v2, GLint v3);
+void INTERNAL_GL_APIENTRY glProgramUniform4ivNULL(GLuint program,
+                                                  GLint location,
+                                                  GLsizei count,
+                                                  const GLint *value);
+void INTERNAL_GL_APIENTRY
+glProgramUniform4uiNULL(GLuint program, GLint location, GLuint v0, GLuint v1, GLuint v2, GLuint v3);
+void INTERNAL_GL_APIENTRY glProgramUniform4uivNULL(GLuint program,
+                                                   GLint location,
+                                                   GLsizei count,
+                                                   const GLuint *value);
+void INTERNAL_GL_APIENTRY glProgramUniformMatrix2dvNULL(GLuint program,
+                                                        GLint location,
+                                                        GLsizei count,
+                                                        GLboolean transpose,
+                                                        const GLdouble *value);
+void INTERNAL_GL_APIENTRY glProgramUniformMatrix2fvNULL(GLuint program,
+                                                        GLint location,
+                                                        GLsizei count,
+                                                        GLboolean transpose,
+                                                        const GLfloat *value);
+void INTERNAL_GL_APIENTRY glProgramUniformMatrix2x3dvNULL(GLuint program,
+                                                          GLint location,
+                                                          GLsizei count,
+                                                          GLboolean transpose,
+                                                          const GLdouble *value);
+void INTERNAL_GL_APIENTRY glProgramUniformMatrix2x3fvNULL(GLuint program,
+                                                          GLint location,
+                                                          GLsizei count,
+                                                          GLboolean transpose,
+                                                          const GLfloat *value);
+void INTERNAL_GL_APIENTRY glProgramUniformMatrix2x4dvNULL(GLuint program,
+                                                          GLint location,
+                                                          GLsizei count,
+                                                          GLboolean transpose,
+                                                          const GLdouble *value);
+void INTERNAL_GL_APIENTRY glProgramUniformMatrix2x4fvNULL(GLuint program,
+                                                          GLint location,
+                                                          GLsizei count,
+                                                          GLboolean transpose,
+                                                          const GLfloat *value);
+void INTERNAL_GL_APIENTRY glProgramUniformMatrix3dvNULL(GLuint program,
+                                                        GLint location,
+                                                        GLsizei count,
+                                                        GLboolean transpose,
+                                                        const GLdouble *value);
+void INTERNAL_GL_APIENTRY glProgramUniformMatrix3fvNULL(GLuint program,
+                                                        GLint location,
+                                                        GLsizei count,
+                                                        GLboolean transpose,
+                                                        const GLfloat *value);
+void INTERNAL_GL_APIENTRY glProgramUniformMatrix3x2dvNULL(GLuint program,
+                                                          GLint location,
+                                                          GLsizei count,
+                                                          GLboolean transpose,
+                                                          const GLdouble *value);
+void INTERNAL_GL_APIENTRY glProgramUniformMatrix3x2fvNULL(GLuint program,
+                                                          GLint location,
+                                                          GLsizei count,
+                                                          GLboolean transpose,
+                                                          const GLfloat *value);
+void INTERNAL_GL_APIENTRY glProgramUniformMatrix3x4dvNULL(GLuint program,
+                                                          GLint location,
+                                                          GLsizei count,
+                                                          GLboolean transpose,
+                                                          const GLdouble *value);
+void INTERNAL_GL_APIENTRY glProgramUniformMatrix3x4fvNULL(GLuint program,
+                                                          GLint location,
+                                                          GLsizei count,
+                                                          GLboolean transpose,
+                                                          const GLfloat *value);
+void INTERNAL_GL_APIENTRY glProgramUniformMatrix4dvNULL(GLuint program,
+                                                        GLint location,
+                                                        GLsizei count,
+                                                        GLboolean transpose,
+                                                        const GLdouble *value);
+void INTERNAL_GL_APIENTRY glProgramUniformMatrix4fvNULL(GLuint program,
+                                                        GLint location,
+                                                        GLsizei count,
+                                                        GLboolean transpose,
+                                                        const GLfloat *value);
+void INTERNAL_GL_APIENTRY glProgramUniformMatrix4x2dvNULL(GLuint program,
+                                                          GLint location,
+                                                          GLsizei count,
+                                                          GLboolean transpose,
+                                                          const GLdouble *value);
+void INTERNAL_GL_APIENTRY glProgramUniformMatrix4x2fvNULL(GLuint program,
+                                                          GLint location,
+                                                          GLsizei count,
+                                                          GLboolean transpose,
+                                                          const GLfloat *value);
+void INTERNAL_GL_APIENTRY glProgramUniformMatrix4x3dvNULL(GLuint program,
+                                                          GLint location,
+                                                          GLsizei count,
+                                                          GLboolean transpose,
+                                                          const GLdouble *value);
+void INTERNAL_GL_APIENTRY glProgramUniformMatrix4x3fvNULL(GLuint program,
+                                                          GLint location,
+                                                          GLsizei count,
+                                                          GLboolean transpose,
+                                                          const GLfloat *value);
+void INTERNAL_GL_APIENTRY glProvokingVertexNULL(GLenum mode);
+void INTERNAL_GL_APIENTRY glPushDebugGroupNULL(GLenum source,
+                                               GLuint id,
+                                               GLsizei length,
+                                               const GLchar *message);
+void INTERNAL_GL_APIENTRY glPushGroupMarkerEXTNULL(GLsizei length, const GLchar *marker);
+void INTERNAL_GL_APIENTRY glQueryCounterNULL(GLuint id, GLenum target);
+void INTERNAL_GL_APIENTRY glReadBufferNULL(GLenum src);
+void INTERNAL_GL_APIENTRY glReadPixelsNULL(GLint x,
+                                           GLint y,
+                                           GLsizei width,
+                                           GLsizei height,
+                                           GLenum format,
+                                           GLenum type,
+                                           void *pixels);
+void INTERNAL_GL_APIENTRY glReadnPixelsNULL(GLint x,
+                                            GLint y,
+                                            GLsizei width,
+                                            GLsizei height,
+                                            GLenum format,
+                                            GLenum type,
+                                            GLsizei bufSize,
+                                            void *data);
+void INTERNAL_GL_APIENTRY glReleaseShaderCompilerNULL();
+void INTERNAL_GL_APIENTRY glRenderbufferStorageNULL(GLenum target,
+                                                    GLenum internalformat,
+                                                    GLsizei width,
+                                                    GLsizei height);
+void INTERNAL_GL_APIENTRY glRenderbufferStorageMultisampleNULL(GLenum target,
+                                                               GLsizei samples,
+                                                               GLenum internalformat,
+                                                               GLsizei width,
+                                                               GLsizei height);
+void INTERNAL_GL_APIENTRY glResumeTransformFeedbackNULL();
+void INTERNAL_GL_APIENTRY glSampleCoverageNULL(GLfloat value, GLboolean invert);
+void INTERNAL_GL_APIENTRY glSampleMaskiNULL(GLuint maskNumber, GLbitfield mask);
+void INTERNAL_GL_APIENTRY glSamplerParameterIivNULL(GLuint sampler,
+                                                    GLenum pname,
+                                                    const GLint *param);
+void INTERNAL_GL_APIENTRY glSamplerParameterIuivNULL(GLuint sampler,
+                                                     GLenum pname,
+                                                     const GLuint *param);
+void INTERNAL_GL_APIENTRY glSamplerParameterfNULL(GLuint sampler, GLenum pname, GLfloat param);
+void INTERNAL_GL_APIENTRY glSamplerParameterfvNULL(GLuint sampler,
+                                                   GLenum pname,
+                                                   const GLfloat *param);
+void INTERNAL_GL_APIENTRY glSamplerParameteriNULL(GLuint sampler, GLenum pname, GLint param);
+void INTERNAL_GL_APIENTRY glSamplerParameterivNULL(GLuint sampler,
+                                                   GLenum pname,
+                                                   const GLint *param);
+void INTERNAL_GL_APIENTRY glScissorNULL(GLint x, GLint y, GLsizei width, GLsizei height);
+void INTERNAL_GL_APIENTRY glScissorArrayvNULL(GLuint first, GLsizei count, const GLint *v);
+void INTERNAL_GL_APIENTRY
+glScissorIndexedNULL(GLuint index, GLint left, GLint bottom, GLsizei width, GLsizei height);
+void INTERNAL_GL_APIENTRY glScissorIndexedvNULL(GLuint index, const GLint *v);
+void INTERNAL_GL_APIENTRY glSetFenceNVNULL(GLuint fence, GLenum condition);
+void INTERNAL_GL_APIENTRY glShaderBinaryNULL(GLsizei count,
+                                             const GLuint *shaders,
+                                             GLenum binaryformat,
+                                             const void *binary,
+                                             GLsizei length);
+void INTERNAL_GL_APIENTRY glShaderSourceNULL(GLuint shader,
+                                             GLsizei count,
+                                             const GLchar *const *string,
+                                             const GLint *length);
+void INTERNAL_GL_APIENTRY glShaderStorageBlockBindingNULL(GLuint program,
+                                                          GLuint storageBlockIndex,
+                                                          GLuint storageBlockBinding);
+void INTERNAL_GL_APIENTRY glStencilFillPathInstancedNVNULL(GLsizei numPaths,
+                                                           GLenum pathNameType,
+                                                           const void *paths,
+                                                           GLuint pathBase,
+                                                           GLenum fillMode,
+                                                           GLuint mask,
+                                                           GLenum transformType,
+                                                           const GLfloat *transformValues);
+void INTERNAL_GL_APIENTRY glStencilFillPathNVNULL(GLuint path, GLenum fillMode, GLuint mask);
+void INTERNAL_GL_APIENTRY glStencilFuncNULL(GLenum func, GLint ref, GLuint mask);
+void INTERNAL_GL_APIENTRY glStencilFuncSeparateNULL(GLenum face,
+                                                    GLenum func,
+                                                    GLint ref,
+                                                    GLuint mask);
+void INTERNAL_GL_APIENTRY glStencilMaskNULL(GLuint mask);
+void INTERNAL_GL_APIENTRY glStencilMaskSeparateNULL(GLenum face, GLuint mask);
+void INTERNAL_GL_APIENTRY glStencilOpNULL(GLenum fail, GLenum zfail, GLenum zpass);
+void INTERNAL_GL_APIENTRY glStencilOpSeparateNULL(GLenum face,
+                                                  GLenum sfail,
+                                                  GLenum dpfail,
+                                                  GLenum dppass);
+void INTERNAL_GL_APIENTRY glStencilStrokePathInstancedNVNULL(GLsizei numPaths,
+                                                             GLenum pathNameType,
+                                                             const void *paths,
+                                                             GLuint pathBase,
+                                                             GLint reference,
+                                                             GLuint mask,
+                                                             GLenum transformType,
+                                                             const GLfloat *transformValues);
+void INTERNAL_GL_APIENTRY glStencilStrokePathNVNULL(GLuint path, GLint reference, GLuint mask);
+void INTERNAL_GL_APIENTRY glStencilThenCoverFillPathInstancedNVNULL(GLsizei numPaths,
+                                                                    GLenum pathNameType,
+                                                                    const void *paths,
+                                                                    GLuint pathBase,
+                                                                    GLenum fillMode,
+                                                                    GLuint mask,
+                                                                    GLenum coverMode,
+                                                                    GLenum transformType,
+                                                                    const GLfloat *transformValues);
+void INTERNAL_GL_APIENTRY glStencilThenCoverFillPathNVNULL(GLuint path,
+                                                           GLenum fillMode,
+                                                           GLuint mask,
+                                                           GLenum coverMode);
+void INTERNAL_GL_APIENTRY
+glStencilThenCoverStrokePathInstancedNVNULL(GLsizei numPaths,
+                                            GLenum pathNameType,
+                                            const void *paths,
+                                            GLuint pathBase,
+                                            GLint reference,
+                                            GLuint mask,
+                                            GLenum coverMode,
+                                            GLenum transformType,
+                                            const GLfloat *transformValues);
+void INTERNAL_GL_APIENTRY glStencilThenCoverStrokePathNVNULL(GLuint path,
+                                                             GLint reference,
+                                                             GLuint mask,
+                                                             GLenum coverMode);
+GLboolean INTERNAL_GL_APIENTRY glTestFenceNVNULL(GLuint fence);
+void INTERNAL_GL_APIENTRY glTexBufferNULL(GLenum target, GLenum internalformat, GLuint buffer);
+void INTERNAL_GL_APIENTRY glTexBufferRangeNULL(GLenum target,
+                                               GLenum internalformat,
+                                               GLuint buffer,
+                                               GLintptr offset,
+                                               GLsizeiptr size);
+void INTERNAL_GL_APIENTRY glTexImage1DNULL(GLenum target,
+                                           GLint level,
+                                           GLint internalformat,
+                                           GLsizei width,
+                                           GLint border,
+                                           GLenum format,
+                                           GLenum type,
+                                           const void *pixels);
+void INTERNAL_GL_APIENTRY glTexImage2DNULL(GLenum target,
+                                           GLint level,
+                                           GLint internalformat,
+                                           GLsizei width,
+                                           GLsizei height,
+                                           GLint border,
+                                           GLenum format,
+                                           GLenum type,
+                                           const void *pixels);
+void INTERNAL_GL_APIENTRY glTexImage2DMultisampleNULL(GLenum target,
+                                                      GLsizei samples,
+                                                      GLenum internalformat,
+                                                      GLsizei width,
+                                                      GLsizei height,
+                                                      GLboolean fixedsamplelocations);
+void INTERNAL_GL_APIENTRY glTexImage3DNULL(GLenum target,
+                                           GLint level,
+                                           GLint internalformat,
+                                           GLsizei width,
+                                           GLsizei height,
+                                           GLsizei depth,
+                                           GLint border,
+                                           GLenum format,
+                                           GLenum type,
+                                           const void *pixels);
+void INTERNAL_GL_APIENTRY glTexImage3DMultisampleNULL(GLenum target,
+                                                      GLsizei samples,
+                                                      GLenum internalformat,
+                                                      GLsizei width,
+                                                      GLsizei height,
+                                                      GLsizei depth,
+                                                      GLboolean fixedsamplelocations);
+void INTERNAL_GL_APIENTRY glTexParameterIivNULL(GLenum target, GLenum pname, const GLint *params);
+void INTERNAL_GL_APIENTRY glTexParameterIuivNULL(GLenum target, GLenum pname, const GLuint *params);
+void INTERNAL_GL_APIENTRY glTexParameterfNULL(GLenum target, GLenum pname, GLfloat param);
+void INTERNAL_GL_APIENTRY glTexParameterfvNULL(GLenum target, GLenum pname, const GLfloat *params);
+void INTERNAL_GL_APIENTRY glTexParameteriNULL(GLenum target, GLenum pname, GLint param);
+void INTERNAL_GL_APIENTRY glTexParameterivNULL(GLenum target, GLenum pname, const GLint *params);
+void INTERNAL_GL_APIENTRY glTexStorage1DNULL(GLenum target,
+                                             GLsizei levels,
+                                             GLenum internalformat,
+                                             GLsizei width);
+void INTERNAL_GL_APIENTRY glTexStorage2DNULL(GLenum target,
+                                             GLsizei levels,
+                                             GLenum internalformat,
+                                             GLsizei width,
+                                             GLsizei height);
+void INTERNAL_GL_APIENTRY glTexStorage2DMultisampleNULL(GLenum target,
+                                                        GLsizei samples,
+                                                        GLenum internalformat,
+                                                        GLsizei width,
+                                                        GLsizei height,
+                                                        GLboolean fixedsamplelocations);
+void INTERNAL_GL_APIENTRY glTexStorage3DNULL(GLenum target,
+                                             GLsizei levels,
+                                             GLenum internalformat,
+                                             GLsizei width,
+                                             GLsizei height,
+                                             GLsizei depth);
+void INTERNAL_GL_APIENTRY glTexStorage3DMultisampleNULL(GLenum target,
+                                                        GLsizei samples,
+                                                        GLenum internalformat,
+                                                        GLsizei width,
+                                                        GLsizei height,
+                                                        GLsizei depth,
+                                                        GLboolean fixedsamplelocations);
+void INTERNAL_GL_APIENTRY glTexSubImage1DNULL(GLenum target,
+                                              GLint level,
+                                              GLint xoffset,
+                                              GLsizei width,
+                                              GLenum format,
+                                              GLenum type,
+                                              const void *pixels);
+void INTERNAL_GL_APIENTRY glTexSubImage2DNULL(GLenum target,
+                                              GLint level,
+                                              GLint xoffset,
+                                              GLint yoffset,
+                                              GLsizei width,
+                                              GLsizei height,
+                                              GLenum format,
+                                              GLenum type,
+                                              const void *pixels);
+void INTERNAL_GL_APIENTRY glTexSubImage3DNULL(GLenum target,
+                                              GLint level,
+                                              GLint xoffset,
+                                              GLint yoffset,
+                                              GLint zoffset,
+                                              GLsizei width,
+                                              GLsizei height,
+                                              GLsizei depth,
+                                              GLenum format,
+                                              GLenum type,
+                                              const void *pixels);
+void INTERNAL_GL_APIENTRY glTextureBarrierNULL();
+void INTERNAL_GL_APIENTRY glTextureBufferNULL(GLuint texture, GLenum internalformat, GLuint buffer);
+void INTERNAL_GL_APIENTRY glTextureBufferRangeNULL(GLuint texture,
+                                                   GLenum internalformat,
+                                                   GLuint buffer,
+                                                   GLintptr offset,
+                                                   GLsizeiptr size);
+void INTERNAL_GL_APIENTRY glTextureParameterIivNULL(GLuint texture,
+                                                    GLenum pname,
+                                                    const GLint *params);
+void INTERNAL_GL_APIENTRY glTextureParameterIuivNULL(GLuint texture,
+                                                     GLenum pname,
+                                                     const GLuint *params);
+void INTERNAL_GL_APIENTRY glTextureParameterfNULL(GLuint texture, GLenum pname, GLfloat param);
+void INTERNAL_GL_APIENTRY glTextureParameterfvNULL(GLuint texture,
+                                                   GLenum pname,
+                                                   const GLfloat *param);
+void INTERNAL_GL_APIENTRY glTextureParameteriNULL(GLuint texture, GLenum pname, GLint param);
+void INTERNAL_GL_APIENTRY glTextureParameterivNULL(GLuint texture,
+                                                   GLenum pname,
+                                                   const GLint *param);
+void INTERNAL_GL_APIENTRY glTextureStorage1DNULL(GLuint texture,
+                                                 GLsizei levels,
+                                                 GLenum internalformat,
+                                                 GLsizei width);
+void INTERNAL_GL_APIENTRY glTextureStorage2DNULL(GLuint texture,
+                                                 GLsizei levels,
+                                                 GLenum internalformat,
+                                                 GLsizei width,
+                                                 GLsizei height);
+void INTERNAL_GL_APIENTRY glTextureStorage2DMultisampleNULL(GLuint texture,
+                                                            GLsizei samples,
+                                                            GLenum internalformat,
+                                                            GLsizei width,
+                                                            GLsizei height,
+                                                            GLboolean fixedsamplelocations);
+void INTERNAL_GL_APIENTRY glTextureStorage3DNULL(GLuint texture,
+                                                 GLsizei levels,
+                                                 GLenum internalformat,
+                                                 GLsizei width,
+                                                 GLsizei height,
+                                                 GLsizei depth);
+void INTERNAL_GL_APIENTRY glTextureStorage3DMultisampleNULL(GLuint texture,
+                                                            GLsizei samples,
+                                                            GLenum internalformat,
+                                                            GLsizei width,
+                                                            GLsizei height,
+                                                            GLsizei depth,
+                                                            GLboolean fixedsamplelocations);
+void INTERNAL_GL_APIENTRY glTextureSubImage1DNULL(GLuint texture,
+                                                  GLint level,
+                                                  GLint xoffset,
+                                                  GLsizei width,
+                                                  GLenum format,
+                                                  GLenum type,
+                                                  const void *pixels);
+void INTERNAL_GL_APIENTRY glTextureSubImage2DNULL(GLuint texture,
+                                                  GLint level,
+                                                  GLint xoffset,
+                                                  GLint yoffset,
+                                                  GLsizei width,
+                                                  GLsizei height,
+                                                  GLenum format,
+                                                  GLenum type,
+                                                  const void *pixels);
+void INTERNAL_GL_APIENTRY glTextureSubImage3DNULL(GLuint texture,
+                                                  GLint level,
+                                                  GLint xoffset,
+                                                  GLint yoffset,
+                                                  GLint zoffset,
+                                                  GLsizei width,
+                                                  GLsizei height,
+                                                  GLsizei depth,
+                                                  GLenum format,
+                                                  GLenum type,
+                                                  const void *pixels);
+void INTERNAL_GL_APIENTRY glTextureViewNULL(GLuint texture,
+                                            GLenum target,
+                                            GLuint origtexture,
+                                            GLenum internalformat,
+                                            GLuint minlevel,
+                                            GLuint numlevels,
+                                            GLuint minlayer,
+                                            GLuint numlayers);
+void INTERNAL_GL_APIENTRY glTransformFeedbackBufferBaseNULL(GLuint xfb,
+                                                            GLuint index,
+                                                            GLuint buffer);
+void INTERNAL_GL_APIENTRY glTransformFeedbackBufferRangeNULL(GLuint xfb,
+                                                             GLuint index,
+                                                             GLuint buffer,
+                                                             GLintptr offset,
+                                                             GLsizeiptr size);
+void INTERNAL_GL_APIENTRY glTransformFeedbackVaryingsNULL(GLuint program,
+                                                          GLsizei count,
+                                                          const GLchar *const *varyings,
+                                                          GLenum bufferMode);
+void INTERNAL_GL_APIENTRY glUniform1dNULL(GLint location, GLdouble x);
+void INTERNAL_GL_APIENTRY glUniform1dvNULL(GLint location, GLsizei count, const GLdouble *value);
+void INTERNAL_GL_APIENTRY glUniform1fNULL(GLint location, GLfloat v0);
+void INTERNAL_GL_APIENTRY glUniform1fvNULL(GLint location, GLsizei count, const GLfloat *value);
+void INTERNAL_GL_APIENTRY glUniform1iNULL(GLint location, GLint v0);
+void INTERNAL_GL_APIENTRY glUniform1ivNULL(GLint location, GLsizei count, const GLint *value);
+void INTERNAL_GL_APIENTRY glUniform1uiNULL(GLint location, GLuint v0);
+void INTERNAL_GL_APIENTRY glUniform1uivNULL(GLint location, GLsizei count, const GLuint *value);
+void INTERNAL_GL_APIENTRY glUniform2dNULL(GLint location, GLdouble x, GLdouble y);
+void INTERNAL_GL_APIENTRY glUniform2dvNULL(GLint location, GLsizei count, const GLdouble *value);
+void INTERNAL_GL_APIENTRY glUniform2fNULL(GLint location, GLfloat v0, GLfloat v1);
+void INTERNAL_GL_APIENTRY glUniform2fvNULL(GLint location, GLsizei count, const GLfloat *value);
+void INTERNAL_GL_APIENTRY glUniform2iNULL(GLint location, GLint v0, GLint v1);
+void INTERNAL_GL_APIENTRY glUniform2ivNULL(GLint location, GLsizei count, const GLint *value);
+void INTERNAL_GL_APIENTRY glUniform2uiNULL(GLint location, GLuint v0, GLuint v1);
+void INTERNAL_GL_APIENTRY glUniform2uivNULL(GLint location, GLsizei count, const GLuint *value);
+void INTERNAL_GL_APIENTRY glUniform3dNULL(GLint location, GLdouble x, GLdouble y, GLdouble z);
+void INTERNAL_GL_APIENTRY glUniform3dvNULL(GLint location, GLsizei count, const GLdouble *value);
+void INTERNAL_GL_APIENTRY glUniform3fNULL(GLint location, GLfloat v0, GLfloat v1, GLfloat v2);
+void INTERNAL_GL_APIENTRY glUniform3fvNULL(GLint location, GLsizei count, const GLfloat *value);
+void INTERNAL_GL_APIENTRY glUniform3iNULL(GLint location, GLint v0, GLint v1, GLint v2);
+void INTERNAL_GL_APIENTRY glUniform3ivNULL(GLint location, GLsizei count, const GLint *value);
+void INTERNAL_GL_APIENTRY glUniform3uiNULL(GLint location, GLuint v0, GLuint v1, GLuint v2);
+void INTERNAL_GL_APIENTRY glUniform3uivNULL(GLint location, GLsizei count, const GLuint *value);
+void INTERNAL_GL_APIENTRY
+glUniform4dNULL(GLint location, GLdouble x, GLdouble y, GLdouble z, GLdouble w);
+void INTERNAL_GL_APIENTRY glUniform4dvNULL(GLint location, GLsizei count, const GLdouble *value);
+void INTERNAL_GL_APIENTRY
+glUniform4fNULL(GLint location, GLfloat v0, GLfloat v1, GLfloat v2, GLfloat v3);
+void INTERNAL_GL_APIENTRY glUniform4fvNULL(GLint location, GLsizei count, const GLfloat *value);
+void INTERNAL_GL_APIENTRY glUniform4iNULL(GLint location, GLint v0, GLint v1, GLint v2, GLint v3);
+void INTERNAL_GL_APIENTRY glUniform4ivNULL(GLint location, GLsizei count, const GLint *value);
+void INTERNAL_GL_APIENTRY
+glUniform4uiNULL(GLint location, GLuint v0, GLuint v1, GLuint v2, GLuint v3);
+void INTERNAL_GL_APIENTRY glUniform4uivNULL(GLint location, GLsizei count, const GLuint *value);
+void INTERNAL_GL_APIENTRY glUniformBlockBindingNULL(GLuint program,
+                                                    GLuint uniformBlockIndex,
+                                                    GLuint uniformBlockBinding);
+void INTERNAL_GL_APIENTRY glUniformMatrix2dvNULL(GLint location,
+                                                 GLsizei count,
+                                                 GLboolean transpose,
+                                                 const GLdouble *value);
+void INTERNAL_GL_APIENTRY glUniformMatrix2fvNULL(GLint location,
+                                                 GLsizei count,
+                                                 GLboolean transpose,
+                                                 const GLfloat *value);
+void INTERNAL_GL_APIENTRY glUniformMatrix2x3dvNULL(GLint location,
+                                                   GLsizei count,
+                                                   GLboolean transpose,
+                                                   const GLdouble *value);
+void INTERNAL_GL_APIENTRY glUniformMatrix2x3fvNULL(GLint location,
+                                                   GLsizei count,
+                                                   GLboolean transpose,
+                                                   const GLfloat *value);
+void INTERNAL_GL_APIENTRY glUniformMatrix2x4dvNULL(GLint location,
+                                                   GLsizei count,
+                                                   GLboolean transpose,
+                                                   const GLdouble *value);
+void INTERNAL_GL_APIENTRY glUniformMatrix2x4fvNULL(GLint location,
+                                                   GLsizei count,
+                                                   GLboolean transpose,
+                                                   const GLfloat *value);
+void INTERNAL_GL_APIENTRY glUniformMatrix3dvNULL(GLint location,
+                                                 GLsizei count,
+                                                 GLboolean transpose,
+                                                 const GLdouble *value);
+void INTERNAL_GL_APIENTRY glUniformMatrix3fvNULL(GLint location,
+                                                 GLsizei count,
+                                                 GLboolean transpose,
+                                                 const GLfloat *value);
+void INTERNAL_GL_APIENTRY glUniformMatrix3x2dvNULL(GLint location,
+                                                   GLsizei count,
+                                                   GLboolean transpose,
+                                                   const GLdouble *value);
+void INTERNAL_GL_APIENTRY glUniformMatrix3x2fvNULL(GLint location,
+                                                   GLsizei count,
+                                                   GLboolean transpose,
+                                                   const GLfloat *value);
+void INTERNAL_GL_APIENTRY glUniformMatrix3x4dvNULL(GLint location,
+                                                   GLsizei count,
+                                                   GLboolean transpose,
+                                                   const GLdouble *value);
+void INTERNAL_GL_APIENTRY glUniformMatrix3x4fvNULL(GLint location,
+                                                   GLsizei count,
+                                                   GLboolean transpose,
+                                                   const GLfloat *value);
+void INTERNAL_GL_APIENTRY glUniformMatrix4dvNULL(GLint location,
+                                                 GLsizei count,
+                                                 GLboolean transpose,
+                                                 const GLdouble *value);
+void INTERNAL_GL_APIENTRY glUniformMatrix4fvNULL(GLint location,
+                                                 GLsizei count,
+                                                 GLboolean transpose,
+                                                 const GLfloat *value);
+void INTERNAL_GL_APIENTRY glUniformMatrix4x2dvNULL(GLint location,
+                                                   GLsizei count,
+                                                   GLboolean transpose,
+                                                   const GLdouble *value);
+void INTERNAL_GL_APIENTRY glUniformMatrix4x2fvNULL(GLint location,
+                                                   GLsizei count,
+                                                   GLboolean transpose,
+                                                   const GLfloat *value);
+void INTERNAL_GL_APIENTRY glUniformMatrix4x3dvNULL(GLint location,
+                                                   GLsizei count,
+                                                   GLboolean transpose,
+                                                   const GLdouble *value);
+void INTERNAL_GL_APIENTRY glUniformMatrix4x3fvNULL(GLint location,
+                                                   GLsizei count,
+                                                   GLboolean transpose,
+                                                   const GLfloat *value);
+void INTERNAL_GL_APIENTRY glUniformSubroutinesuivNULL(GLenum shadertype,
+                                                      GLsizei count,
+                                                      const GLuint *indices);
+GLboolean INTERNAL_GL_APIENTRY glUnmapBufferNULL(GLenum target);
+GLboolean INTERNAL_GL_APIENTRY glUnmapNamedBufferNULL(GLuint buffer);
+void INTERNAL_GL_APIENTRY glUseProgramNULL(GLuint program);
+void INTERNAL_GL_APIENTRY glUseProgramStagesNULL(GLuint pipeline,
+                                                 GLbitfield stages,
+                                                 GLuint program);
+void INTERNAL_GL_APIENTRY glValidateProgramNULL(GLuint program);
+void INTERNAL_GL_APIENTRY glValidateProgramPipelineNULL(GLuint pipeline);
+void INTERNAL_GL_APIENTRY glVertexArrayAttribBindingNULL(GLuint vaobj,
+                                                         GLuint attribindex,
+                                                         GLuint bindingindex);
+void INTERNAL_GL_APIENTRY glVertexArrayAttribFormatNULL(GLuint vaobj,
+                                                        GLuint attribindex,
+                                                        GLint size,
+                                                        GLenum type,
+                                                        GLboolean normalized,
+                                                        GLuint relativeoffset);
+void INTERNAL_GL_APIENTRY glVertexArrayAttribIFormatNULL(GLuint vaobj,
+                                                         GLuint attribindex,
+                                                         GLint size,
+                                                         GLenum type,
+                                                         GLuint relativeoffset);
+void INTERNAL_GL_APIENTRY glVertexArrayAttribLFormatNULL(GLuint vaobj,
+                                                         GLuint attribindex,
+                                                         GLint size,
+                                                         GLenum type,
+                                                         GLuint relativeoffset);
+void INTERNAL_GL_APIENTRY glVertexArrayBindingDivisorNULL(GLuint vaobj,
+                                                          GLuint bindingindex,
+                                                          GLuint divisor);
+void INTERNAL_GL_APIENTRY glVertexArrayElementBufferNULL(GLuint vaobj, GLuint buffer);
+void INTERNAL_GL_APIENTRY glVertexArrayVertexBufferNULL(GLuint vaobj,
+                                                        GLuint bindingindex,
+                                                        GLuint buffer,
+                                                        GLintptr offset,
+                                                        GLsizei stride);
+void INTERNAL_GL_APIENTRY glVertexArrayVertexBuffersNULL(GLuint vaobj,
+                                                         GLuint first,
+                                                         GLsizei count,
+                                                         const GLuint *buffers,
+                                                         const GLintptr *offsets,
+                                                         const GLsizei *strides);
+void INTERNAL_GL_APIENTRY glVertexAttrib1dNULL(GLuint index, GLdouble x);
+void INTERNAL_GL_APIENTRY glVertexAttrib1dvNULL(GLuint index, const GLdouble *v);
+void INTERNAL_GL_APIENTRY glVertexAttrib1fNULL(GLuint index, GLfloat x);
+void INTERNAL_GL_APIENTRY glVertexAttrib1fvNULL(GLuint index, const GLfloat *v);
+void INTERNAL_GL_APIENTRY glVertexAttrib1sNULL(GLuint index, GLshort x);
+void INTERNAL_GL_APIENTRY glVertexAttrib1svNULL(GLuint index, const GLshort *v);
+void INTERNAL_GL_APIENTRY glVertexAttrib2dNULL(GLuint index, GLdouble x, GLdouble y);
+void INTERNAL_GL_APIENTRY glVertexAttrib2dvNULL(GLuint index, const GLdouble *v);
+void INTERNAL_GL_APIENTRY glVertexAttrib2fNULL(GLuint index, GLfloat x, GLfloat y);
+void INTERNAL_GL_APIENTRY glVertexAttrib2fvNULL(GLuint index, const GLfloat *v);
+void INTERNAL_GL_APIENTRY glVertexAttrib2sNULL(GLuint index, GLshort x, GLshort y);
+void INTERNAL_GL_APIENTRY glVertexAttrib2svNULL(GLuint index, const GLshort *v);
+void INTERNAL_GL_APIENTRY glVertexAttrib3dNULL(GLuint index, GLdouble x, GLdouble y, GLdouble z);
+void INTERNAL_GL_APIENTRY glVertexAttrib3dvNULL(GLuint index, const GLdouble *v);
+void INTERNAL_GL_APIENTRY glVertexAttrib3fNULL(GLuint index, GLfloat x, GLfloat y, GLfloat z);
+void INTERNAL_GL_APIENTRY glVertexAttrib3fvNULL(GLuint index, const GLfloat *v);
+void INTERNAL_GL_APIENTRY glVertexAttrib3sNULL(GLuint index, GLshort x, GLshort y, GLshort z);
+void INTERNAL_GL_APIENTRY glVertexAttrib3svNULL(GLuint index, const GLshort *v);
+void INTERNAL_GL_APIENTRY glVertexAttrib4NbvNULL(GLuint index, const GLbyte *v);
+void INTERNAL_GL_APIENTRY glVertexAttrib4NivNULL(GLuint index, const GLint *v);
+void INTERNAL_GL_APIENTRY glVertexAttrib4NsvNULL(GLuint index, const GLshort *v);
+void INTERNAL_GL_APIENTRY
+glVertexAttrib4NubNULL(GLuint index, GLubyte x, GLubyte y, GLubyte z, GLubyte w);
+void INTERNAL_GL_APIENTRY glVertexAttrib4NubvNULL(GLuint index, const GLubyte *v);
+void INTERNAL_GL_APIENTRY glVertexAttrib4NuivNULL(GLuint index, const GLuint *v);
+void INTERNAL_GL_APIENTRY glVertexAttrib4NusvNULL(GLuint index, const GLushort *v);
+void INTERNAL_GL_APIENTRY glVertexAttrib4bvNULL(GLuint index, const GLbyte *v);
+void INTERNAL_GL_APIENTRY
+glVertexAttrib4dNULL(GLuint index, GLdouble x, GLdouble y, GLdouble z, GLdouble w);
+void INTERNAL_GL_APIENTRY glVertexAttrib4dvNULL(GLuint index, const GLdouble *v);
+void INTERNAL_GL_APIENTRY
+glVertexAttrib4fNULL(GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w);
+void INTERNAL_GL_APIENTRY glVertexAttrib4fvNULL(GLuint index, const GLfloat *v);
+void INTERNAL_GL_APIENTRY glVertexAttrib4ivNULL(GLuint index, const GLint *v);
+void INTERNAL_GL_APIENTRY
+glVertexAttrib4sNULL(GLuint index, GLshort x, GLshort y, GLshort z, GLshort w);
+void INTERNAL_GL_APIENTRY glVertexAttrib4svNULL(GLuint index, const GLshort *v);
+void INTERNAL_GL_APIENTRY glVertexAttrib4ubvNULL(GLuint index, const GLubyte *v);
+void INTERNAL_GL_APIENTRY glVertexAttrib4uivNULL(GLuint index, const GLuint *v);
+void INTERNAL_GL_APIENTRY glVertexAttrib4usvNULL(GLuint index, const GLushort *v);
+void INTERNAL_GL_APIENTRY glVertexAttribBindingNULL(GLuint attribindex, GLuint bindingindex);
+void INTERNAL_GL_APIENTRY glVertexAttribDivisorNULL(GLuint index, GLuint divisor);
+void INTERNAL_GL_APIENTRY glVertexAttribFormatNULL(GLuint attribindex,
+                                                   GLint size,
+                                                   GLenum type,
+                                                   GLboolean normalized,
+                                                   GLuint relativeoffset);
+void INTERNAL_GL_APIENTRY glVertexAttribI1iNULL(GLuint index, GLint x);
+void INTERNAL_GL_APIENTRY glVertexAttribI1ivNULL(GLuint index, const GLint *v);
+void INTERNAL_GL_APIENTRY glVertexAttribI1uiNULL(GLuint index, GLuint x);
+void INTERNAL_GL_APIENTRY glVertexAttribI1uivNULL(GLuint index, const GLuint *v);
+void INTERNAL_GL_APIENTRY glVertexAttribI2iNULL(GLuint index, GLint x, GLint y);
+void INTERNAL_GL_APIENTRY glVertexAttribI2ivNULL(GLuint index, const GLint *v);
+void INTERNAL_GL_APIENTRY glVertexAttribI2uiNULL(GLuint index, GLuint x, GLuint y);
+void INTERNAL_GL_APIENTRY glVertexAttribI2uivNULL(GLuint index, const GLuint *v);
+void INTERNAL_GL_APIENTRY glVertexAttribI3iNULL(GLuint index, GLint x, GLint y, GLint z);
+void INTERNAL_GL_APIENTRY glVertexAttribI3ivNULL(GLuint index, const GLint *v);
+void INTERNAL_GL_APIENTRY glVertexAttribI3uiNULL(GLuint index, GLuint x, GLuint y, GLuint z);
+void INTERNAL_GL_APIENTRY glVertexAttribI3uivNULL(GLuint index, const GLuint *v);
+void INTERNAL_GL_APIENTRY glVertexAttribI4bvNULL(GLuint index, const GLbyte *v);
+void INTERNAL_GL_APIENTRY glVertexAttribI4iNULL(GLuint index, GLint x, GLint y, GLint z, GLint w);
+void INTERNAL_GL_APIENTRY glVertexAttribI4ivNULL(GLuint index, const GLint *v);
+void INTERNAL_GL_APIENTRY glVertexAttribI4svNULL(GLuint index, const GLshort *v);
+void INTERNAL_GL_APIENTRY glVertexAttribI4ubvNULL(GLuint index, const GLubyte *v);
+void INTERNAL_GL_APIENTRY
+glVertexAttribI4uiNULL(GLuint index, GLuint x, GLuint y, GLuint z, GLuint w);
+void INTERNAL_GL_APIENTRY glVertexAttribI4uivNULL(GLuint index, const GLuint *v);
+void INTERNAL_GL_APIENTRY glVertexAttribI4usvNULL(GLuint index, const GLushort *v);
+void INTERNAL_GL_APIENTRY glVertexAttribIFormatNULL(GLuint attribindex,
+                                                    GLint size,
+                                                    GLenum type,
+                                                    GLuint relativeoffset);
+void INTERNAL_GL_APIENTRY glVertexAttribIPointerNULL(GLuint index,
+                                                     GLint size,
+                                                     GLenum type,
+                                                     GLsizei stride,
+                                                     const void *pointer);
+void INTERNAL_GL_APIENTRY glVertexAttribL1dNULL(GLuint index, GLdouble x);
+void INTERNAL_GL_APIENTRY glVertexAttribL1dvNULL(GLuint index, const GLdouble *v);
+void INTERNAL_GL_APIENTRY glVertexAttribL2dNULL(GLuint index, GLdouble x, GLdouble y);
+void INTERNAL_GL_APIENTRY glVertexAttribL2dvNULL(GLuint index, const GLdouble *v);
+void INTERNAL_GL_APIENTRY glVertexAttribL3dNULL(GLuint index, GLdouble x, GLdouble y, GLdouble z);
+void INTERNAL_GL_APIENTRY glVertexAttribL3dvNULL(GLuint index, const GLdouble *v);
+void INTERNAL_GL_APIENTRY
+glVertexAttribL4dNULL(GLuint index, GLdouble x, GLdouble y, GLdouble z, GLdouble w);
+void INTERNAL_GL_APIENTRY glVertexAttribL4dvNULL(GLuint index, const GLdouble *v);
+void INTERNAL_GL_APIENTRY glVertexAttribLFormatNULL(GLuint attribindex,
+                                                    GLint size,
+                                                    GLenum type,
+                                                    GLuint relativeoffset);
+void INTERNAL_GL_APIENTRY glVertexAttribLPointerNULL(GLuint index,
+                                                     GLint size,
+                                                     GLenum type,
+                                                     GLsizei stride,
+                                                     const void *pointer);
+void INTERNAL_GL_APIENTRY glVertexAttribP1uiNULL(GLuint index,
+                                                 GLenum type,
+                                                 GLboolean normalized,
+                                                 GLuint value);
+void INTERNAL_GL_APIENTRY glVertexAttribP1uivNULL(GLuint index,
+                                                  GLenum type,
+                                                  GLboolean normalized,
+                                                  const GLuint *value);
+void INTERNAL_GL_APIENTRY glVertexAttribP2uiNULL(GLuint index,
+                                                 GLenum type,
+                                                 GLboolean normalized,
+                                                 GLuint value);
+void INTERNAL_GL_APIENTRY glVertexAttribP2uivNULL(GLuint index,
+                                                  GLenum type,
+                                                  GLboolean normalized,
+                                                  const GLuint *value);
+void INTERNAL_GL_APIENTRY glVertexAttribP3uiNULL(GLuint index,
+                                                 GLenum type,
+                                                 GLboolean normalized,
+                                                 GLuint value);
+void INTERNAL_GL_APIENTRY glVertexAttribP3uivNULL(GLuint index,
+                                                  GLenum type,
+                                                  GLboolean normalized,
+                                                  const GLuint *value);
+void INTERNAL_GL_APIENTRY glVertexAttribP4uiNULL(GLuint index,
+                                                 GLenum type,
+                                                 GLboolean normalized,
+                                                 GLuint value);
+void INTERNAL_GL_APIENTRY glVertexAttribP4uivNULL(GLuint index,
+                                                  GLenum type,
+                                                  GLboolean normalized,
+                                                  const GLuint *value);
+void INTERNAL_GL_APIENTRY glVertexAttribPointerNULL(GLuint index,
+                                                    GLint size,
+                                                    GLenum type,
+                                                    GLboolean normalized,
+                                                    GLsizei stride,
+                                                    const void *pointer);
+void INTERNAL_GL_APIENTRY glVertexBindingDivisorNULL(GLuint bindingindex, GLuint divisor);
+void INTERNAL_GL_APIENTRY glViewportNULL(GLint x, GLint y, GLsizei width, GLsizei height);
+void INTERNAL_GL_APIENTRY glViewportArrayvNULL(GLuint first, GLsizei count, const GLfloat *v);
+void INTERNAL_GL_APIENTRY
+glViewportIndexedfNULL(GLuint index, GLfloat x, GLfloat y, GLfloat w, GLfloat h);
+void INTERNAL_GL_APIENTRY glViewportIndexedfvNULL(GLuint index, const GLfloat *v);
+void INTERNAL_GL_APIENTRY glWaitSyncNULL(GLsync sync, GLbitfield flags, GLuint64 timeout);
+}  // namespace rx
+
+#endif  // LIBGLESV2_RENDERER_GL_NULL_GL_FUNCTIONS_AUTOGEN_H_
--- a/gfx/angle/src/libANGLE/renderer/gl/renderergl_utils.cpp
+++ b/gfx/angle/src/libANGLE/renderer/gl/renderergl_utils.cpp
@@ -11,16 +11,17 @@
 
 #include <limits>
 
 #include "common/mathutil.h"
 #include "libANGLE/Buffer.h"
 #include "libANGLE/Caps.h"
 #include "libANGLE/Workarounds.h"
 #include "libANGLE/formatutils.h"
+#include "libANGLE/queryconversions.h"
 #include "libANGLE/renderer/gl/FunctionsGL.h"
 #include "libANGLE/renderer/gl/QueryGL.h"
 #include "libANGLE/renderer/gl/WorkaroundsGL.h"
 #include "libANGLE/renderer/gl/formatutilsgl.h"
 
 #include <algorithm>
 #include <sstream>
 #include <EGL/eglext.h>
@@ -102,17 +103,17 @@ static gl::TextureCaps GenerateTextureFo
     textureCaps.renderable = MeetsRequirements(functions, formatInfo.framebufferAttachment);
 
     // glGetInternalformativ is not available until version 4.2 but may be available through the 3.0
     // extension GL_ARB_internalformat_query
     if (textureCaps.renderable && functions->getInternalformativ)
     {
         GLenum queryInternalFormat = internalFormat;
 
-        if (internalFormat == GL_BGRA8_EXT && functions->standard == STANDARD_GL_DESKTOP)
+        if (internalFormat == GL_BGRA8_EXT)
         {
             // Querying GL_NUM_SAMPLE_COUNTS for GL_BGRA8_EXT generates an INVALID_ENUM on some
             // drivers.  It seems however that allocating a multisampled renderbuffer of this format
             // succeeds. To avoid breaking multisampling for this format, query the supported sample
             // counts for GL_RGBA8 instead.
             queryInternalFormat = GL_RGBA8;
         }
 
@@ -447,32 +448,25 @@ void GenerateCaps(const FunctionsGL *fun
         // Can't support ES2 version without these caps
         LimitVersion(maxSupportedESVersion, gl::Version(0, 0));
     }
 
     if (functions->isAtLeastGL(gl::Version(4, 1)) || functions->hasGLExtension("GL_ARB_ES2_compatibility") ||
         functions->isAtLeastGLES(gl::Version(2, 0)))
     {
         caps->maxVertexUniformVectors = QuerySingleGLInt(functions, GL_MAX_VERTEX_UNIFORM_VECTORS);
+        caps->maxFragmentUniformVectors =
+            QuerySingleGLInt(functions, GL_MAX_FRAGMENT_UNIFORM_VECTORS);
     }
     else
     {
         // Doesn't limit ES version, GL_MAX_VERTEX_UNIFORM_COMPONENTS / 4 is acceptable.
         caps->maxVertexUniformVectors = caps->maxVertexUniformComponents / 4;
-    }
-
-    if (functions->isAtLeastGL(gl::Version(3, 1)) || functions->hasGLExtension("GL_ARB_uniform_buffer_object") ||
-        functions->isAtLeastGLES(gl::Version(3, 0)))
-    {
-        caps->maxVertexUniformBlocks = QuerySingleGLInt(functions, GL_MAX_VERTEX_UNIFORM_BLOCKS);
-    }
-    else
-    {
-        // Can't support ES3 without uniform blocks
-        LimitVersion(maxSupportedESVersion, gl::Version(2, 0));
+        // Doesn't limit ES version, GL_MAX_FRAGMENT_UNIFORM_COMPONENTS / 4 is acceptable.
+        caps->maxFragmentUniformVectors = caps->maxFragmentUniformComponents / 4;
     }
 
     if (functions->isAtLeastGL(gl::Version(3, 2)) ||
         functions->isAtLeastGLES(gl::Version(3, 0)))
     {
         caps->maxVertexOutputComponents = QuerySingleGLInt(functions, GL_MAX_VERTEX_OUTPUT_COMPONENTS);
     }
     else
@@ -490,38 +484,16 @@ void GenerateCaps(const FunctionsGL *fun
         caps->maxTextureImageUnits = QuerySingleGLInt(functions, GL_MAX_TEXTURE_IMAGE_UNITS);
     }
     else
     {
         // Can't support ES2 version without these caps
         LimitVersion(maxSupportedESVersion, gl::Version(0, 0));
     }
 
-    if (functions->isAtLeastGL(gl::Version(4, 1)) || functions->hasGLExtension("GL_ARB_ES2_compatibility") ||
-        functions->isAtLeastGLES(gl::Version(2, 0)))
-    {
-        caps->maxFragmentUniformVectors = QuerySingleGLInt(functions, GL_MAX_FRAGMENT_UNIFORM_VECTORS);
-    }
-    else
-    {
-        // Doesn't limit ES version, GL_MAX_FRAGMENT_UNIFORM_COMPONENTS / 4 is acceptable.
-        caps->maxFragmentUniformVectors = caps->maxFragmentUniformComponents / 4;
-    }
-
-    if (functions->isAtLeastGL(gl::Version(3, 1)) || functions->hasGLExtension("GL_ARB_uniform_buffer_object") ||
-        functions->isAtLeastGLES(gl::Version(3, 0)))
-    {
-        caps->maxFragmentUniformBlocks = QuerySingleGLInt(functions, GL_MAX_FRAGMENT_UNIFORM_BLOCKS);
-    }
-    else
-    {
-        // Can't support ES3 without uniform blocks
-        LimitVersion(maxSupportedESVersion, gl::Version(2, 0));
-    }
-
     if (functions->isAtLeastGL(gl::Version(3, 2)) ||
         functions->isAtLeastGLES(gl::Version(3, 0)))
     {
         caps->maxFragmentInputComponents = QuerySingleGLInt(functions, GL_MAX_FRAGMENT_INPUT_COMPONENTS);
     }
     else
     {
         // There doesn't seem, to be a desktop extension to add this cap, maybe it could be given a safe limit
@@ -540,16 +512,19 @@ void GenerateCaps(const FunctionsGL *fun
         // Can't support ES3 without texel offset, could possibly be emulated in the shader
         LimitVersion(maxSupportedESVersion, gl::Version(2, 0));
     }
 
     // Table 6.33, implementation dependent aggregate shader limits
     if (functions->isAtLeastGL(gl::Version(3, 1)) || functions->hasGLExtension("GL_ARB_uniform_buffer_object") ||
         functions->isAtLeastGLES(gl::Version(3, 0)))
     {
+        caps->maxVertexUniformBlocks = QuerySingleGLInt(functions, GL_MAX_VERTEX_UNIFORM_BLOCKS);
+        caps->maxFragmentUniformBlocks =
+            QuerySingleGLInt(functions, GL_MAX_FRAGMENT_UNIFORM_BLOCKS);
         caps->maxUniformBufferBindings = QuerySingleGLInt(functions, GL_MAX_UNIFORM_BUFFER_BINDINGS);
         caps->maxUniformBlockSize = QuerySingleGLInt64(functions, GL_MAX_UNIFORM_BLOCK_SIZE);
         caps->uniformBufferOffsetAlignment = QuerySingleGLInt(functions, GL_UNIFORM_BUFFER_OFFSET_ALIGNMENT);
 
         GLuint maxCombinedUniformBlocks =
             QuerySingleGLInt(functions, GL_MAX_COMBINED_UNIFORM_BLOCKS);
         // The real cap contains the limits for shader types that are not available to ES, so limit
         // the cap to the sum of vertex+fragment shader caps.
@@ -675,17 +650,17 @@ void GenerateCaps(const FunctionsGL *fun
     if (!functions->isAtLeastGL(gl::Version(3, 3)) &&
         !functions->hasGLExtension("GL_ARB_explicit_attrib_location") &&
         !functions->isAtLeastGLES(gl::Version(3, 0)))
     {
         LimitVersion(maxSupportedESVersion, gl::Version(2, 0));
     }
 
     if (functions->isAtLeastGL(gl::Version(4, 3)) || functions->isAtLeastGLES(gl::Version(3, 1)) ||
-        functions->hasGLExtension("GL_ARB_texture_multisample"))
+        functions->hasGLExtension("GL_ARB_framebuffer_no_attachments"))
     {
         caps->maxFramebufferWidth   = QuerySingleGLInt(functions, GL_MAX_FRAMEBUFFER_WIDTH);
         caps->maxFramebufferHeight  = QuerySingleGLInt(functions, GL_MAX_FRAMEBUFFER_HEIGHT);
         caps->maxFramebufferSamples = QuerySingleGLInt(functions, GL_MAX_FRAMEBUFFER_SAMPLES);
     }
     else
     {
         LimitVersion(maxSupportedESVersion, gl::Version(3, 0));
@@ -723,17 +698,17 @@ void GenerateCaps(const FunctionsGL *fun
             caps->maxVertexAttribStride = QuerySingleGLInt(functions, GL_MAX_VERTEX_ATTRIB_STRIDE);
         }
     }
     else
     {
         LimitVersion(maxSupportedESVersion, gl::Version(3, 0));
     }
 
-    if (functions->isAtLeastGL(gl::Version(4, 2)) || functions->isAtLeastGLES(gl::Version(3, 1)) ||
+    if (functions->isAtLeastGL(gl::Version(4, 3)) || functions->isAtLeastGLES(gl::Version(3, 1)) ||
         functions->hasGLExtension("GL_ARB_shader_storage_buffer_object"))
     {
         caps->maxCombinedShaderOutputResources =
             QuerySingleGLInt(functions, GL_MAX_COMBINED_SHADER_OUTPUT_RESOURCES);
         caps->maxFragmentShaderStorageBlocks =
             QuerySingleGLInt(functions, GL_MAX_FRAGMENT_SHADER_STORAGE_BLOCKS);
         caps->maxVertexShaderStorageBlocks =
             QuerySingleGLInt(functions, GL_MAX_VERTEX_SHADER_STORAGE_BLOCKS);
@@ -751,17 +726,18 @@ void GenerateCaps(const FunctionsGL *fun
         LimitVersion(maxSupportedESVersion, gl::Version(3, 0));
     }
 
     // OpenGL 4.2 is required for GL_ARB_compute_shader, some platform drivers have the extension,
     // but their maximum supported GL versions are less than 4.2. Explicitly limit the minimum
     // GL version to 4.2.
     if (functions->isAtLeastGL(gl::Version(4, 3)) || functions->isAtLeastGLES(gl::Version(3, 1)) ||
         (functions->isAtLeastGL(gl::Version(4, 2)) &&
-         functions->hasGLExtension("GL_ARB_compute_shader")))
+         functions->hasGLExtension("GL_ARB_compute_shader") &&
+         functions->hasGLExtension("GL_ARB_shader_storage_buffer_object")))
     {
         for (GLuint index = 0u; index < 3u; ++index)
         {
             caps->maxComputeWorkGroupCount[index] =
                 QuerySingleIndexGLInt(functions, GL_MAX_COMPUTE_WORK_GROUP_COUNT, index);
 
             caps->maxComputeWorkGroupSize[index] =
                 QuerySingleIndexGLInt(functions, GL_MAX_COMPUTE_WORK_GROUP_SIZE, index);
@@ -929,19 +905,26 @@ void GenerateCaps(const FunctionsGL *fun
                                   functions->isAtLeastGLES(gl::Version(3, 0)) ||
                                   functions->hasGLESExtension("GL_EXT_instanced_arrays");
     extensions->unpackSubimage = functions->standard == STANDARD_GL_DESKTOP ||
                                  functions->isAtLeastGLES(gl::Version(3, 0)) ||
                                  functions->hasGLESExtension("GL_EXT_unpack_subimage");
     extensions->packSubimage = functions->standard == STANDARD_GL_DESKTOP ||
                                functions->isAtLeastGLES(gl::Version(3, 0)) ||
                                functions->hasGLESExtension("GL_NV_pack_subimage");
-    extensions->debugMarker =
-        functions->isAtLeastGL(gl::Version(4, 3)) || functions->hasGLExtension("GL_KHR_debug") ||
-        functions->isAtLeastGLES(gl::Version(3, 2)) || functions->hasGLESExtension("GL_KHR_debug");
+    extensions->vertexArrayObject = functions->isAtLeastGL(gl::Version(3, 0)) ||
+                                    functions->hasGLExtension("GL_ARB_vertex_array_object") ||
+                                    functions->isAtLeastGLES(gl::Version(3, 0)) ||
+                                    functions->hasGLESExtension("GL_OES_vertex_array_object");
+    extensions->debugMarker = functions->isAtLeastGL(gl::Version(4, 3)) ||
+                              functions->hasGLExtension("GL_KHR_debug") ||
+                              functions->hasGLExtension("GL_EXT_debug_marker") ||
+                              functions->isAtLeastGLES(gl::Version(3, 2)) ||
+                              functions->hasGLESExtension("GL_KHR_debug") ||
+                              functions->hasGLESExtension("GL_EXT_debug_marker");
     if (functions->isAtLeastGL(gl::Version(3, 3)) ||
         functions->hasGLExtension("GL_ARB_timer_query") ||
         functions->hasGLESExtension("GL_EXT_disjoint_timer_query"))
     {
         extensions->disjointTimerQuery = true;
         extensions->queryCounterBitsTimeElapsed =
             QueryQueryValue(functions, GL_TIME_ELAPSED, GL_QUERY_COUNTER_BITS);
         extensions->queryCounterBitsTimestamp =
@@ -1005,16 +988,20 @@ void GenerateCaps(const FunctionsGL *fun
                                    functions->hasGLExtension("GL_ARB_framebuffer_sRGB") ||
                                    functions->hasGLESExtension("GL_EXT_sRGB_write_control");
 
 #if defined(ANGLE_PLATFORM_ANDROID)
     // SRGB blending does not appear to work correctly on the Nexus 5. Writing to an SRGB
     // framebuffer with GL_FRAMEBUFFER_SRGB enabled and then reading back returns the same value.
     // Disabling GL_FRAMEBUFFER_SRGB will then convert in the wrong direction.
     extensions->sRGBWriteControl = false;
+
+    // BGRA formats do not appear to be accepted by the Nexus 5X driver dispite the extension being
+    // exposed.
+    extensions->textureFormatBGRA8888 = false;
 #endif
 
     // EXT_discard_framebuffer can be implemented as long as glDiscardFramebufferEXT or
     // glInvalidateFramebuffer is available
     extensions->discardFramebuffer = functions->isAtLeastGL(gl::Version(4, 3)) ||
                                      functions->hasGLExtension("GL_ARB_invalidate_subdata") ||
                                      functions->isAtLeastGLES(gl::Version(3, 0)) ||
                                      functions->hasGLESExtension("GL_EXT_discard_framebuffer") ||
@@ -1024,16 +1011,81 @@ void GenerateCaps(const FunctionsGL *fun
 
     if (functions->isAtLeastGL(gl::Version(3, 1)) ||
         functions->hasGLExtension("GL_ARB_texture_rectangle"))
     {
         extensions->textureRectangle = true;
         caps->maxRectangleTextureSize =
             QuerySingleGLInt(functions, GL_MAX_RECTANGLE_TEXTURE_SIZE_ANGLE);
     }
+
+    // OpenGL 4.3 (and above) can support all features and constants defined in
+    // GL_EXT_geometry_shader.
+    if (functions->isAtLeastGL(gl::Version(4, 3)) || functions->isAtLeastGLES(gl::Version(3, 2)) ||
+        functions->hasGLESExtension("GL_OES_geometry_shader") ||
+        functions->hasGLESExtension("GL_EXT_geometry_shader") ||
+        // OpenGL 4.0 adds the support for instanced geometry shader
+        // GL_ARB_shader_atomic_counters adds atomic counters to geometry shader
+        // GL_ARB_shader_storage_buffer_object adds shader storage buffers to geometry shader
+        // GL_ARB_shader_image_load_store adds images to geometry shader
+        (functions->isAtLeastGL(gl::Version(4, 0)) &&
+         functions->hasGLExtension("GL_ARB_shader_atomic_counters") &&
+         functions->hasGLExtension("GL_ARB_shader_storage_buffer_object") &&
+         functions->hasGLExtension("GL_ARB_shader_image_load_store")))
+    {
+        extensions->geometryShader = true;
+
+        caps->maxFramebufferLayers = QuerySingleGLInt(functions, GL_MAX_FRAMEBUFFER_LAYERS_EXT);
+
+        // GL_PROVOKING_VERTEX isn't a valid return value of GL_LAYER_PROVOKING_VERTEX_EXT in
+        // GL_EXT_geometry_shader SPEC, however it is legal in desktop OpenGL, which means the value
+        // follows the one set by glProvokingVertex.
+        // [OpenGL 4.3] Chapter 11.3.4.6
+        // The vertex conventions followed for gl_Layer and gl_ViewportIndex may be determined by
+        // calling GetIntegerv with the symbolic constants LAYER_PROVOKING_VERTEX and
+        // VIEWPORT_INDEX_PROVOKING_VERTEX, respectively. For either query, if the value returned is
+        // PROVOKING_VERTEX, then vertex selection follows the convention specified by
+        // ProvokingVertex.
+        caps->layerProvokingVertex = QuerySingleGLInt(functions, GL_LAYER_PROVOKING_VERTEX_EXT);
+        if (caps->layerProvokingVertex == GL_PROVOKING_VERTEX)
+        {
+            // We should use GL_LAST_VERTEX_CONVENTION_EXT instead because desktop OpenGL SPEC
+            // requires the initial value of provoking vertex mode is LAST_VERTEX_CONVENTION.
+            // [OpenGL 4.3] Chapter 13.4
+            // The initial value of the provoking vertex mode is LAST_VERTEX_CONVENTION.
+            caps->layerProvokingVertex = GL_LAST_VERTEX_CONVENTION_EXT;
+        }
+
+        caps->maxGeometryUniformComponents =
+            QuerySingleGLInt(functions, GL_MAX_GEOMETRY_UNIFORM_COMPONENTS_EXT);
+        caps->maxGeometryUniformBlocks =
+            QuerySingleGLInt(functions, GL_MAX_GEOMETRY_UNIFORM_BLOCKS_EXT);
+        caps->maxCombinedGeometryUniformComponents =
+            QuerySingleGLInt(functions, GL_MAX_COMBINED_GEOMETRY_UNIFORM_COMPONENTS_EXT);
+        caps->maxGeometryInputComponents =
+            QuerySingleGLInt(functions, GL_MAX_GEOMETRY_INPUT_COMPONENTS_EXT);
+        caps->maxGeometryOutputComponents =
+            QuerySingleGLInt(functions, GL_MAX_GEOMETRY_OUTPUT_COMPONENTS_EXT);
+        caps->maxGeometryOutputVertices =
+            QuerySingleGLInt(functions, GL_MAX_GEOMETRY_OUTPUT_VERTICES_EXT);
+        caps->maxGeometryTotalOutputComponents =
+            QuerySingleGLInt(functions, GL_MAX_GEOMETRY_TOTAL_OUTPUT_COMPONENTS_EXT);
+        caps->maxGeometryShaderInvocations =
+            QuerySingleGLInt(functions, GL_MAX_GEOMETRY_SHADER_INVOCATIONS_EXT);
+        caps->maxGeometryTextureImageUnits =
+            QuerySingleGLInt(functions, GL_MAX_GEOMETRY_TEXTURE_IMAGE_UNITS_EXT);
+        caps->maxGeometryAtomicCounterBuffers =
+            QuerySingleGLInt(functions, GL_MAX_GEOMETRY_ATOMIC_COUNTER_BUFFERS_EXT);
+        caps->maxGeometryAtomicCounters =
+            QuerySingleGLInt(functions, GL_MAX_GEOMETRY_ATOMIC_COUNTERS_EXT);
+        caps->maxGeometryImageUniforms =
+            QuerySingleGLInt(functions, GL_MAX_GEOMETRY_IMAGE_UNIFORMS_EXT);
+        caps->maxGeometryShaderStorageBlocks =
+            QuerySingleGLInt(functions, GL_MAX_GEOMETRY_SHADER_STORAGE_BLOCKS_EXT);
+    }
 }
 
 void GenerateWorkarounds(const FunctionsGL *functions, WorkaroundsGL *workarounds)
 {
     VendorID vendor = GetVendorID(functions);
 
     workarounds->dontRemoveInvariantForFragmentInput =
         functions->standard == STANDARD_GL_DESKTOP && IsAMD(vendor);
@@ -1062,17 +1114,19 @@ void GenerateWorkarounds(const Functions
 
 #if defined(ANGLE_PLATFORM_APPLE)
     workarounds->doWhileGLSLCausesGPUHang = true;
     workarounds->useUnusedBlocksWithStandardOrSharedLayout = true;
     workarounds->rewriteFloatUnaryMinusOperator            = IsIntel(vendor);
 #endif
 
 #if defined(ANGLE_PLATFORM_ANDROID)
-    workarounds->dontInitializeUninitializedLocals = true;
+    // Triggers a bug on Marshmallow Adreno (4xx?) driver.
+    // http://anglebug.com/2046
+    workarounds->dontInitializeUninitializedLocals = IsQualcomm(vendor);
 #endif
 
     workarounds->finishDoesNotCauseQueriesToBeAvailable =
         functions->standard == STANDARD_GL_DESKTOP && IsNvidia(vendor);
 
     // TODO(cwallez): Disable this workaround for MacOSX versions 10.9 or later.
     workarounds->alwaysCallUseProgramAfterLink = true;
 
@@ -1096,21 +1150,25 @@ void GenerateWorkarounds(const Functions
     // TODO(oetuaho): Make this specific to the affected driver versions. Versions that came after
     // 364 are known to be affected, at least up to 375.
     workarounds->emulateAtan2Float = IsNvidia(vendor);
 
     workarounds->reapplyUBOBindingsAfterUsingBinaryProgram = IsAMD(vendor);
 
     workarounds->clampPointSize = IsNvidia(vendor);
 
+    workarounds->rewriteVectorScalarArithmetic = IsNvidia(vendor);
+
 #if defined(ANGLE_PLATFORM_ANDROID)
     // TODO(jmadill): Narrow workaround range for specific devices.
     workarounds->reapplyUBOBindingsAfterUsingBinaryProgram = true;
 
     workarounds->clampPointSize = true;
+
+    workarounds->dontUseLoopsToInitializeVariables = !IsNvidia(vendor);
 #endif
 }
 
 void ApplyWorkarounds(const FunctionsGL *functions, gl::Workarounds *workarounds)
 {
 #if defined(ANGLE_PLATFORM_ANDROID)
     VendorID vendor = GetVendorID(functions);
 
@@ -1144,17 +1202,17 @@ bool SupportsNativeRendering(const Funct
     // Some desktop drivers allow rendering to formats that are not required by the spec, this is
     // exposed through the GL_FRAMEBUFFER_RENDERABLE query.
     if (functions->isAtLeastGL(gl::Version(4, 3)) ||
         functions->hasGLExtension("GL_ARB_internalformat_query2"))
     {
         GLint framebufferRenderable = GL_FALSE;
         functions->getInternalformativ(target, internalFormat, GL_FRAMEBUFFER_RENDERABLE, 1,
                                        &framebufferRenderable);
-        return framebufferRenderable != GL_FALSE;
+        return gl::ConvertToBool(framebufferRenderable);
     }
     else
     {
         const nativegl::InternalFormat &nativeInfo =
             nativegl::GetInternalFormatInfo(internalFormat, functions->standard);
         return nativegl_gl::MeetsRequirements(functions, nativeInfo.framebufferAttachment);
     }
 }
@@ -1209,52 +1267,53 @@ uint8_t *MapBufferRangeWithFallback(cons
         // No options available
         UNREACHABLE();
         return nullptr;
     }
 }
 
 gl::ErrorOrResult<bool> ShouldApplyLastRowPaddingWorkaround(const gl::Extents &size,
                                                             const gl::PixelStoreStateBase &state,
+                                                            const gl::Buffer *pixelBuffer,
                                                             GLenum format,
                                                             GLenum type,
                                                             bool is3D,
                                                             const void *pixels)
 {
-    if (state.pixelBuffer.get() == nullptr)
+    if (pixelBuffer == nullptr)
     {
         return false;
     }
 
     // We are using an pack or unpack buffer, compute what the driver thinks is going to be the
     // last byte read or written. If it is past the end of the buffer, we will need to use the
     // workaround otherwise the driver will generate INVALID_OPERATION and not do the operation.
     CheckedNumeric<size_t> checkedEndByte;
     CheckedNumeric<size_t> pixelBytes;
     size_t rowPitch;
 
     const gl::InternalFormat &glFormat = gl::GetInternalFormatInfo(format, type);
-    ANGLE_TRY_RESULT(glFormat.computePackUnpackEndByte(size, state, is3D), checkedEndByte);
-    ANGLE_TRY_RESULT(glFormat.computeRowPitch(size.width, state.alignment, state.rowLength),
+    ANGLE_TRY_RESULT(glFormat.computePackUnpackEndByte(type, size, state, is3D), checkedEndByte);
+    ANGLE_TRY_RESULT(glFormat.computeRowPitch(type, size.width, state.alignment, state.rowLength),
                      rowPitch);
-    pixelBytes = glFormat.pixelBytes;
+    pixelBytes = glFormat.computePixelBytes(type);
 
     checkedEndByte += reinterpret_cast<intptr_t>(pixels);
 
     // At this point checkedEndByte is the actual last byte read.
     // The driver adds an extra row padding (if any), mimic it.
     ANGLE_TRY_CHECKED_MATH(pixelBytes);
     if (pixelBytes.ValueOrDie() * size.width < rowPitch)
     {
         checkedEndByte += rowPitch - pixelBytes * size.width;
     }
 
     ANGLE_TRY_CHECKED_MATH(checkedEndByte);
 
-    return checkedEndByte.ValueOrDie() > static_cast<size_t>(state.pixelBuffer->getSize());
+    return checkedEndByte.ValueOrDie() > static_cast<size_t>(pixelBuffer->getSize());
 }
 
 std::vector<ContextCreationTry> GenerateContextCreationToTry(EGLint requestedType, bool isMesaGLX)
 {
     using Type                         = ContextCreationTry::Type;
     constexpr EGLint kPlatformOpenGL   = EGL_PLATFORM_ANGLE_TYPE_OPENGL_ANGLE;
     constexpr EGLint kPlatformOpenGLES = EGL_PLATFORM_ANGLE_TYPE_OPENGLES_ANGLE;
 
--- a/gfx/angle/src/libANGLE/renderer/gl/renderergl_utils.h
+++ b/gfx/angle/src/libANGLE/renderer/gl/renderergl_utils.h
@@ -67,16 +67,17 @@ bool CanMapBufferForRead(const Functions
 uint8_t *MapBufferRangeWithFallback(const FunctionsGL *functions,
                                     GLenum target,
                                     size_t offset,
                                     size_t length,
                                     GLbitfield access);
 
 gl::ErrorOrResult<bool> ShouldApplyLastRowPaddingWorkaround(const gl::Extents &size,
                                                             const gl::PixelStoreStateBase &state,
+                                                            const gl::Buffer *pixelBuffer,
                                                             GLenum format,
                                                             GLenum type,
                                                             bool is3D,
                                                             const void *pixels);
 
 struct ContextCreationTry
 {
     enum class Type
--- a/gfx/angle/src/libANGLE/renderer/gl/wgl/DisplayWGL.cpp
+++ b/gfx/angle/src/libANGLE/renderer/gl/wgl/DisplayWGL.cpp
@@ -39,17 +39,17 @@ class FunctionsGLWindows : public Functi
     {
         ASSERT(mOpenGLModule);
         ASSERT(mGetProcAddressWGL);
     }
 
     ~FunctionsGLWindows() override {}
 
   private:
-    void *loadProcAddress(const std::string &function) override
+    void *loadProcAddress(const std::string &function) const override
     {
         void *proc = reinterpret_cast<void*>(mGetProcAddressWGL(function.c_str()));
         if (!proc)
         {
             proc = reinterpret_cast<void*>(GetProcAddress(mOpenGLModule, function.c_str()));
         }
         return proc;
     }
@@ -272,17 +272,17 @@ egl::Error DisplayWGL::initialize(egl::D
 
     if (!mFunctionsWGL->makeCurrent(mDeviceContext, mWGLContext))
     {
         return egl::EglNotInitialized() << "Failed to make the intermediate WGL context current.";
     }
     mCurrentDC = mDeviceContext;
 
     mFunctionsGL = new FunctionsGLWindows(mOpenGLModule, mFunctionsWGL->getProcAddress);
-    mFunctionsGL->initialize();
+    mFunctionsGL->initialize(displayAttributes);
 
     mHasRobustness = mFunctionsGL->getGraphicsResetStatus != nullptr;
     if (mHasWGLCreateContextRobustness != mHasRobustness)
     {
         WARN() << "WGL_ARB_create_context_robustness exists but unable to OpenGL context with "
                   "robustness.";
     }
 
@@ -620,16 +620,18 @@ void DisplayWGL::generateExtensions(egl:
     outExtensions->surfaceD3DTexture2DShareHandle = true;
     outExtensions->querySurfacePointer            = true;
     outExtensions->keyedMutex                     = true;
 
     // Contexts are virtualized so textures can be shared globally
     outExtensions->displayTextureShareGroup = true;
 
     outExtensions->surfacelessContext = true;
+
+    DisplayGL::generateExtensions(outExtensions);
 }
 
 void DisplayWGL::generateCaps(egl::Caps *outCaps) const
 {
     outCaps->textureNPOT = true;
 }
 
 egl::Error DisplayWGL::makeCurrentSurfaceless(gl::Context *context)
--- a/gfx/angle/src/libANGLE/renderer/gl/wgl/FunctionsWGL.cpp
+++ b/gfx/angle/src/libANGLE/renderer/gl/wgl/FunctionsWGL.cpp
@@ -92,16 +92,20 @@ FunctionsWGL::FunctionsWGL()
       dxRegisterObjectNV(nullptr),
       dxUnregisterObjectNV(nullptr),
       dxObjectAccessNV(nullptr),
       dxLockObjectsNV(nullptr),
       dxUnlockObjectsNV(nullptr)
 {
 }
 
+FunctionsWGL::~FunctionsWGL()
+{
+}
+
 void FunctionsWGL::initialize(HMODULE glModule, HDC context)
 {
     // First grab the wglGetProcAddress function from the gl module
     GetWGLProcAddress(glModule, nullptr, "wglGetProcAddress", &getProcAddress);
 
     // Load the core wgl functions
     GetWGLProcAddress(glModule, getProcAddress, "wglCopyContext", &copyContext);
     GetWGLProcAddress(glModule, getProcAddress, "wglCreateContext", &createContext);
--- a/gfx/angle/src/libANGLE/renderer/gl/wgl/FunctionsWGL.h
+++ b/gfx/angle/src/libANGLE/renderer/gl/wgl/FunctionsWGL.h
@@ -14,16 +14,17 @@
 
 namespace rx
 {
 
 class FunctionsWGL : angle::NonCopyable
 {
   public:
     FunctionsWGL();
+    ~FunctionsWGL();
 
     // Loads all available wgl functions, may be called multiple times
     void initialize(HMODULE glModule, HDC context);
 
     // Extension information
     std::vector<std::string> extensions;
     bool hasExtension(const std::string &ext) const;
 
--- a/gfx/angle/src/libANGLE/renderer/null/BufferNULL.cpp
+++ b/gfx/angle/src/libANGLE/renderer/null/BufferNULL.cpp
@@ -25,36 +25,36 @@ BufferNULL::BufferNULL(const gl::BufferS
 
 BufferNULL::~BufferNULL()
 {
     bool memoryReleaseResult = mAllocationTracker->updateMemoryAllocation(mData.size(), 0);
     ASSERT(memoryReleaseResult);
 }
 
 gl::Error BufferNULL::setData(const gl::Context *context,
-                              GLenum target,
+                              gl::BufferBinding target,
                               const void *data,
                               size_t size,
-                              GLenum usage)
+                              gl::BufferUsage usage)
 {
     if (!mAllocationTracker->updateMemoryAllocation(mData.size(), size))
     {
         return gl::OutOfMemory() << "Unable to allocate internal buffer storage.";
     }
 
     mData.resize(size, 0);
     if (size > 0 && data != nullptr)
     {
         memcpy(mData.data(), data, size);
     }
     return gl::NoError();
 }
 
 gl::Error BufferNULL::setSubData(const gl::Context *context,
-                                 GLenum target,
+                                 gl::BufferBinding target,
                                  const void *data,
                                  size_t size,
                                  size_t offset)
 {
     if (size > 0)
     {
         memcpy(mData.data() + offset, data, size);
     }
--- a/gfx/angle/src/libANGLE/renderer/null/BufferNULL.h
+++ b/gfx/angle/src/libANGLE/renderer/null/BufferNULL.h
@@ -19,22 +19,22 @@ class AllocationTrackerNULL;
 
 class BufferNULL : public BufferImpl
 {
   public:
     BufferNULL(const gl::BufferState &state, AllocationTrackerNULL *allocationTracker);
     ~BufferNULL() override;
 
     gl::Error setData(const gl::Context *context,
-                      GLenum target,
+                      gl::BufferBinding target,
                       const void *data,
                       size_t size,
-                      GLenum usage) override;
+                      gl::BufferUsage usage) override;
     gl::Error setSubData(const gl::Context *context,
-                         GLenum target,
+                         gl::BufferBinding target,
                          const void *data,
                          size_t size,
                          size_t offset) override;
     gl::Error copySubData(const gl::Context *context,
                           BufferImpl *source,
                           GLintptr sourceOffset,
                           GLintptr destOffset,
                           GLsizeiptr size) override;
--- a/gfx/angle/src/libANGLE/renderer/null/ContextNULL.cpp
+++ b/gfx/angle/src/libANGLE/renderer/null/ContextNULL.cpp
@@ -59,41 +59,62 @@ bool AllocationTrackerNULL::updateMemory
     return true;
 }
 
 ContextNULL::ContextNULL(const gl::ContextState &state, AllocationTrackerNULL *allocationTracker)
     : ContextImpl(state), mAllocationTracker(allocationTracker)
 {
     ASSERT(mAllocationTracker != nullptr);
 
-    const gl::Version maxClientVersion(3, 1);
-    mCaps = GenerateMinimumCaps(maxClientVersion);
-
     mExtensions                       = gl::Extensions();
+    mExtensions.fence                 = true;
+    mExtensions.instancedArrays       = true;
+    mExtensions.pixelBufferObject     = true;
+    mExtensions.mapBuffer             = true;
+    mExtensions.mapBufferRange        = true;
     mExtensions.copyTexture           = true;
     mExtensions.copyCompressedTexture = true;
+    mExtensions.textureRectangle      = true;
+    mExtensions.textureUsage           = true;
+    mExtensions.vertexArrayObject      = true;
+    mExtensions.debugMarker            = true;
+    mExtensions.translatedShaderSource = true;
 
-    mTextureCaps = GenerateMinimumTextureCapsMap(maxClientVersion, mExtensions);
+    mExtensions.rgb8rgba8 = true;
+    mExtensions.textureCompressionDXT1     = true;
+    mExtensions.textureCompressionDXT3     = true;
+    mExtensions.textureCompressionDXT5     = true;
+    mExtensions.textureCompressionS3TCsRGB = true;
+    mExtensions.textureCompressionASTCHDR  = true;
+    mExtensions.textureCompressionASTCLDR  = true;
+    mExtensions.compressedETC1RGB8Texture  = true;
+    mExtensions.lossyETCDecode             = true;
+    mExtensions.geometryShader             = true;
+
+    const gl::Version maxClientVersion(3, 1);
+    mCaps = GenerateMinimumCaps(maxClientVersion, mExtensions);
+
+    InitMinimumTextureCapsMap(maxClientVersion, mExtensions, &mTextureCaps);
 }
 
 ContextNULL::~ContextNULL()
 {
 }
 
 gl::Error ContextNULL::initialize()
 {
     return gl::NoError();
 }
 
-gl::Error ContextNULL::flush()
+gl::Error ContextNULL::flush(const gl::Context *context)
 {
     return gl::NoError();
 }
 
-gl::Error ContextNULL::finish()
+gl::Error ContextNULL::finish(const gl::Context *context)
 {
     return gl::NoError();
 }
 
 gl::Error ContextNULL::drawArrays(const gl::Context *context,
                                   GLenum mode,
                                   GLint first,
                                   GLsizei count)
@@ -255,16 +276,24 @@ void ContextNULL::insertEventMarker(GLsi
 void ContextNULL::pushGroupMarker(GLsizei length, const char *marker)
 {
 }
 
 void ContextNULL::popGroupMarker()
 {
 }
 
+void ContextNULL::pushDebugGroup(GLenum source, GLuint id, GLsizei length, const char *message)
+{
+}
+
+void ContextNULL::popDebugGroup()
+{
+}
+
 void ContextNULL::syncState(const gl::Context *context, const gl::State::DirtyBits &dirtyBits)
 {
 }
 
 GLint ContextNULL::getGPUDisjoint()
 {
     return 0;
 }
@@ -381,9 +410,24 @@ std::vector<PathImpl *> ContextNULL::cre
 gl::Error ContextNULL::dispatchCompute(const gl::Context *context,
                                        GLuint numGroupsX,
                                        GLuint numGroupsY,
                                        GLuint numGroupsZ)
 {
     return gl::NoError();
 }
 
+gl::Error ContextNULL::dispatchComputeIndirect(const gl::Context *context, GLintptr indirect)
+{
+    return gl::NoError();
+}
+
+gl::Error ContextNULL::memoryBarrier(const gl::Context *context, GLbitfield barriers)
+{
+    return gl::NoError();
+}
+
+gl::Error ContextNULL::memoryBarrierByRegion(const gl::Context *context, GLbitfield barriers)
+{
+    return gl::NoError();
+}
+
 }  // namespace rx
--- a/gfx/angle/src/libANGLE/renderer/null/ContextNULL.h
+++ b/gfx/angle/src/libANGLE/renderer/null/ContextNULL.h
@@ -34,18 +34,18 @@ class ContextNULL : public ContextImpl
 {
   public:
     ContextNULL(const gl::ContextState &state, AllocationTrackerNULL *allocationTracker);
     ~ContextNULL() override;
 
     gl::Error initialize() override;
 
     // Flush and finish.
-    gl::Error flush() override;
-    gl::Error finish() override;
+    gl::Error flush(const gl::Context *context) override;
+    gl::Error finish(const gl::Context *context) override;
 
     // Drawing methods.
     gl::Error drawArrays(const gl::Context *context,
                          GLenum mode,
                          GLint first,
                          GLsizei count) override;
     gl::Error drawArraysInstanced(const gl::Context *context,
                                   GLenum mode,
@@ -127,21 +127,25 @@ class ContextNULL : public ContextImpl
 
     // Device loss
     GLenum getResetStatus() override;
 
     // Vendor and description strings.
     std::string getVendorString() const override;
     std::string getRendererDescription() const override;
 
-    // Debug markers.
+    // EXT_debug_marker
     void insertEventMarker(GLsizei length, const char *marker) override;
     void pushGroupMarker(GLsizei length, const char *marker) override;
     void popGroupMarker() override;
 
+    // KHR_debug
+    void pushDebugGroup(GLenum source, GLuint id, GLsizei length, const char *message) override;
+    void popDebugGroup() override;
+
     // State sync with dirty bits.
     void syncState(const gl::Context *context, const gl::State::DirtyBits &dirtyBits) override;
 
     // Disjoint timer queries
     GLint getGPUDisjoint() override;
     GLint64 getTimestamp() override;
 
     // Context switching
@@ -189,16 +193,20 @@ class ContextNULL : public ContextImpl
     ProgramPipelineImpl *createProgramPipeline(const gl::ProgramPipelineState &data) override;
 
     std::vector<PathImpl *> createPaths(GLsizei range) override;
 
     gl::Error dispatchCompute(const gl::Context *context,
                               GLuint numGroupsX,
                               GLuint numGroupsY,
                               GLuint numGroupsZ) override;
+    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;
 
   private:
     gl::Caps mCaps;
     gl::TextureCapsMap mTextureCaps;
     gl::Extensions mExtensions;
     gl::Limitations mLimitations;
 
     AllocationTrackerNULL *mAllocationTracker;
--- a/gfx/angle/src/libANGLE/renderer/null/DisplayNULL.cpp
+++ b/gfx/angle/src/libANGLE/renderer/null/DisplayNULL.cpp
@@ -169,17 +169,17 @@ ImageImpl *DisplayNULL::createImage(cons
     return new ImageNULL(state);
 }
 
 ContextImpl *DisplayNULL::createContext(const gl::ContextState &state)
 {
     return new ContextNULL(state, mAllocationTracker.get());
 }
 
-StreamProducerImpl *DisplayNULL::createStreamProducerD3DTextureNV12(
+StreamProducerImpl *DisplayNULL::createStreamProducerD3DTexture(
     egl::Stream::ConsumerType consumerType,
     const egl::AttributeMap &attribs)
 {
     UNIMPLEMENTED();
     return nullptr;
 }
 
 void DisplayNULL::generateExtensions(egl::DisplayExtensions *outExtensions) const
@@ -201,16 +201,17 @@ void DisplayNULL::generateExtensions(egl
     outExtensions->createContextWebGLCompatibility    = true;
     outExtensions->createContextBindGeneratesResource = true;
     outExtensions->swapBuffersWithDamage              = true;
     outExtensions->pixelFormatFloat                   = true;
     outExtensions->surfacelessContext                 = true;
     outExtensions->displayTextureShareGroup           = true;
     outExtensions->createContextClientArrays          = true;
     outExtensions->programCacheControl                = true;
+    outExtensions->robustResourceInitialization       = true;
 }
 
 void DisplayNULL::generateCaps(egl::Caps *outCaps) const
 {
     outCaps->textureNPOT = true;
 }
 
 }  // namespace rx
--- a/gfx/angle/src/libANGLE/renderer/null/DisplayNULL.h
+++ b/gfx/angle/src/libANGLE/renderer/null/DisplayNULL.h
@@ -59,19 +59,18 @@ class DisplayNULL : public DisplayImpl
                                      const egl::AttributeMap &attribs) override;
 
     ImageImpl *createImage(const egl::ImageState &state,
                            EGLenum target,
                            const egl::AttributeMap &attribs) override;
 
     ContextImpl *createContext(const gl::ContextState &state) override;
 
-    StreamProducerImpl *createStreamProducerD3DTextureNV12(
-        egl::Stream::ConsumerType consumerType,
-        const egl::AttributeMap &attribs) override;
+    StreamProducerImpl *createStreamProducerD3DTexture(egl::Stream::ConsumerType consumerType,
+                                                       const egl::AttributeMap &attribs) override;
 
   private:
     void generateExtensions(egl::DisplayExtensions *outExtensions) const override;
     void generateCaps(egl::Caps *outCaps) const override;
 
     DeviceImpl *mDevice;
 
     std::unique_ptr<AllocationTrackerNULL> mAllocationTracker;
--- a/gfx/angle/src/libANGLE/renderer/null/FenceNVNULL.cpp
+++ b/gfx/angle/src/libANGLE/renderer/null/FenceNVNULL.cpp
@@ -19,25 +19,23 @@ FenceNVNULL::FenceNVNULL() : FenceNVImpl
 }
 
 FenceNVNULL::~FenceNVNULL()
 {
 }
 
 gl::Error FenceNVNULL::set(GLenum condition)
 {
-    UNIMPLEMENTED();
-    return gl::InternalError();
+    return gl::NoError();
 }
 
 gl::Error FenceNVNULL::test(GLboolean *outFinished)
 {
-    UNIMPLEMENTED();
-    return gl::InternalError();
+    *outFinished = GL_TRUE;
+    return gl::NoError();
 }
 
 gl::Error FenceNVNULL::finish()
 {
-    UNIMPLEMENTED();
-    return gl::InternalError();
+    return gl::NoError();
 }
 
 }  // namespace rx
--- a/gfx/angle/src/libANGLE/renderer/null/FramebufferNULL.cpp
+++ b/gfx/angle/src/libANGLE/renderer/null/FramebufferNULL.cpp
@@ -114,23 +114,24 @@ GLenum FramebufferNULL::getImplementatio
 
 gl::Error FramebufferNULL::readPixels(const gl::Context *context,
                                       const gl::Rectangle &origArea,
                                       GLenum format,
                                       GLenum type,
                                       void *ptrOrOffset)
 {
     const gl::PixelPackState &packState = context->getGLState().getPackState();
+    gl::Buffer *packBuffer = context->getGLState().getTargetBuffer(gl::BufferBinding::PixelPack);
 
     // Get the pointer to write to from the argument or the pack buffer
     GLubyte *pixels = nullptr;
-    if (packState.pixelBuffer.get() != nullptr)
+    if (packBuffer != nullptr)
     {
-        BufferNULL *pixelBuffer = GetImplAs<BufferNULL>(packState.pixelBuffer.get());
-        pixels                  = reinterpret_cast<GLubyte *>(pixelBuffer->getDataPtr());
+        BufferNULL *packBufferGL = GetImplAs<BufferNULL>(packBuffer);
+        pixels                     = reinterpret_cast<GLubyte *>(packBufferGL->getDataPtr());
         pixels += reinterpret_cast<intptr_t>(ptrOrOffset);
     }
     else
     {
         pixels = reinterpret_cast<GLubyte *>(ptrOrOffset);
     }
 
     // Clip read area to framebuffer.
@@ -143,17 +144,17 @@ gl::Error FramebufferNULL::readPixels(co
         return gl::NoError();
     }
 
     // Compute size of unclipped rows and initial skip
     const gl::InternalFormat &glFormat = gl::GetInternalFormatInfo(format, type);
 
     GLuint rowBytes = 0;
     ANGLE_TRY_RESULT(
-        glFormat.computeRowPitch(origArea.width, packState.alignment, packState.rowLength),
+        glFormat.computeRowPitch(type, origArea.width, packState.alignment, packState.rowLength),
         rowBytes);
 
     GLuint skipBytes = 0;
     ANGLE_TRY_RESULT(glFormat.computeSkipBytes(rowBytes, 0, packState, false), skipBytes);
     pixels += skipBytes;
 
     // Skip OOB region up to first in bounds pixel
     int leftClip = area.x - origArea.x;
@@ -174,17 +175,17 @@ gl::Error FramebufferNULL::blit(const gl
                                 const gl::Rectangle &sourceArea,
                                 const gl::Rectangle &destArea,
                                 GLbitfield mask,
                                 GLenum filter)
 {
     return gl::NoError();
 }
 
-bool FramebufferNULL::checkStatus() const
+bool FramebufferNULL::checkStatus(const gl::Context *context) const
 {
     return true;
 }
 
 void FramebufferNULL::syncState(const gl::Context *context,
                                 const gl::Framebuffer::DirtyBits &dirtyBits)
 {
 }
--- a/gfx/angle/src/libANGLE/renderer/null/FramebufferNULL.h
+++ b/gfx/angle/src/libANGLE/renderer/null/FramebufferNULL.h
@@ -58,17 +58,17 @@ class FramebufferNULL : public Framebuff
                          void *pixels) override;
 
     gl::Error blit(const gl::Context *context,
                    const gl::Rectangle &sourceArea,
                    const gl::Rectangle &destArea,
                    GLbitfield mask,
                    GLenum filter) override;
 
-    bool checkStatus() const override;
+    bool checkStatus(const gl::Context *context) const override;
 
     void syncState(const gl::Context *context,
                    const gl::Framebuffer::DirtyBits &dirtyBits) override;
 
     gl::Error getSamplePosition(size_t index, GLfloat *xy) const override;
 };
 
 }  // namespace rx
--- a/gfx/angle/src/libANGLE/renderer/null/ProgramNULL.cpp
+++ b/gfx/angle/src/libANGLE/renderer/null/ProgramNULL.cpp
@@ -37,17 +37,17 @@ void ProgramNULL::setBinaryRetrievableHi
 {
 }
 
 void ProgramNULL::setSeparable(bool separable)
 {
 }
 
 gl::LinkResult ProgramNULL::link(const gl::Context *contextImpl,
-                                 const gl::VaryingPacking &packing,
+                                 const gl::ProgramLinkedResources &resources,
                                  gl::InfoLog &infoLog)
 {
     return true;
 }
 
 GLboolean ProgramNULL::validate(const gl::Caps &caps, gl::InfoLog *infoLog)
 {
     return GL_TRUE;
@@ -178,33 +178,16 @@ void ProgramNULL::getUniformuiv(const gl
 {
     // TODO(jmadill): Write some values.
 }
 
 void ProgramNULL::setUniformBlockBinding(GLuint uniformBlockIndex, GLuint uniformBlockBinding)
 {
 }
 
-bool ProgramNULL::getUniformBlockSize(const std::string &blockName,
-                                      const std::string &blockMappedName,
-                                      size_t *sizeOut) const
-{
-    // TODO(geofflang): Compute reasonable sizes?
-    *sizeOut = 0;
-    return true;
-}
-
-bool ProgramNULL::getUniformBlockMemberInfo(const std::string &memberUniformName,
-                                            const std::string &memberUniformMappedName,
-                                            sh::BlockMemberInfo *memberInfoOut) const
-{
-    // TODO(geofflang): Compute reasonable values?
-    return true;
-}
-
 void ProgramNULL::setPathFragmentInputGen(const std::string &inputName,
                                           GLenum genMode,
                                           GLint components,
                                           const GLfloat *coeffs)
 {
 }
 
 }  // namespace rx
--- a/gfx/angle/src/libANGLE/renderer/null/ProgramNULL.h
+++ b/gfx/angle/src/libANGLE/renderer/null/ProgramNULL.h
@@ -24,17 +24,17 @@ class ProgramNULL : public ProgramImpl
     gl::LinkResult load(const gl::Context *context,
                         gl::InfoLog &infoLog,
                         gl::BinaryInputStream *stream) override;
     void save(const gl::Context *context, gl::BinaryOutputStream *stream) override;
     void setBinaryRetrievableHint(bool retrievable) override;
     void setSeparable(bool separable) override;
 
     gl::LinkResult link(const gl::Context *context,
-                        const gl::VaryingPacking &packing,
+                        const gl::ProgramLinkedResources &resources,
                         gl::InfoLog &infoLog) override;
     GLboolean validate(const gl::Caps &caps, gl::InfoLog *infoLog) override;
 
     void setUniform1fv(GLint location, GLsizei count, const GLfloat *v) override;
     void setUniform2fv(GLint location, GLsizei count, const GLfloat *v) override;
     void setUniform3fv(GLint location, GLsizei count, const GLfloat *v) override;
     void setUniform4fv(GLint location, GLsizei count, const GLfloat *v) override;
     void setUniform1iv(GLint location, GLsizei count, const GLint *v) override;
@@ -84,27 +84,16 @@ class ProgramNULL : public ProgramImpl
 
     void getUniformfv(const gl::Context *context, GLint location, GLfloat *params) const override;
     void getUniformiv(const gl::Context *context, GLint location, GLint *params) const override;
     void getUniformuiv(const gl::Context *context, GLint location, GLuint *params) const override;
 
     // TODO: synchronize in syncState when dirty bits exist.
     void setUniformBlockBinding(GLuint uniformBlockIndex, GLuint uniformBlockBinding) override;
 
-    // May only be called after a successful link operation.
-    // Return false for inactive blocks.
-    bool getUniformBlockSize(const std::string &blockName,
-                             const std::string &blockMappedName,
-                             size_t *sizeOut) const override;
-
-    // May only be called after a successful link operation.
-    // Returns false for inactive members.
-    bool getUniformBlockMemberInfo(const std::string &memberUniformName,
-                                   const std::string &memberUniformMappedName,
-                                   sh::BlockMemberInfo *memberInfoOut) const override;
     // CHROMIUM_path_rendering
     // Set parameters to control fragment shader input variable interpolation
     void setPathFragmentInputGen(const std::string &inputName,
                                  GLenum genMode,
                                  GLint components,
                                  const GLfloat *coeffs) override;
 };
 
--- a/gfx/angle/src/libANGLE/renderer/null/RenderbufferNULL.cpp
+++ b/gfx/angle/src/libANGLE/renderer/null/RenderbufferNULL.cpp
@@ -39,9 +39,15 @@ gl::Error RenderbufferNULL::setStorageMu
     return gl::NoError();
 }
 
 gl::Error RenderbufferNULL::setStorageEGLImageTarget(const gl::Context *context, egl::Image *image)
 {
     return gl::NoError();
 }
 
+gl::Error RenderbufferNULL::initializeContents(const gl::Context *context,
+                                               const gl::ImageIndex &imageIndex)
+{
+    return gl::NoError();
+}
+
 }  // namespace rx
--- a/gfx/angle/src/libANGLE/renderer/null/RenderbufferNULL.h
+++ b/gfx/angle/src/libANGLE/renderer/null/RenderbufferNULL.h
@@ -25,14 +25,18 @@ class RenderbufferNULL : public Renderbu
                          GLenum internalformat,
                          size_t width,
                          size_t height) override;
     gl::Error setStorageMultisample(const gl::Context *context,
                                     size_t samples,
                                     GLenum internalformat,
                                     size_t width,
                                     size_t height) override;
+
     gl::Error setStorageEGLImageTarget(const gl::Context *context, egl::Image *image) override;
+
+    gl::Error initializeContents(const gl::Context *context,
+                                 const gl::ImageIndex &imageIndex) override;
 };
 
 }  // namespace rx
 
 #endif  // LIBANGLE_RENDERER_NULL_RENDERBUFFERNULL_H_
--- a/gfx/angle/src/libANGLE/renderer/null/SurfaceNULL.cpp
+++ b/gfx/angle/src/libANGLE/renderer/null/SurfaceNULL.cpp
@@ -91,9 +91,15 @@ EGLint SurfaceNULL::isPostSubBufferSuppo
     return EGL_TRUE;
 }
 
 EGLint SurfaceNULL::getSwapBehavior() const
 {
     return EGL_BUFFER_PRESERVED;
 }
 
+gl::Error SurfaceNULL::initializeContents(const gl::Context *context,
+                                          const gl::ImageIndex &imageIndex)
+{
+    return gl::NoError();
+}
+
 }  // namespace rx
--- a/gfx/angle/src/libANGLE/renderer/null/SurfaceNULL.h
+++ b/gfx/angle/src/libANGLE/renderer/null/SurfaceNULL.h
@@ -36,13 +36,16 @@ class SurfaceNULL : public SurfaceImpl
     void setSwapInterval(EGLint interval) override;
 
     // width and height can change with client window resizing
     EGLint getWidth() const override;
     EGLint getHeight() const override;
 
     EGLint isPostSubBufferSupported() const override;
     EGLint getSwapBehavior() const override;
+
+    gl::Error initializeContents(const gl::Context *context,
+                                 const gl::ImageIndex &imageIndex) override;
 };
 
 }  // namespace rx
 
 #endif  // LIBANGLE_RENDERER_NULL_SURFACENULL_H_
--- a/gfx/angle/src/libANGLE/renderer/null/TextureNULL.cpp
+++ b/gfx/angle/src/libANGLE/renderer/null/TextureNULL.cpp
@@ -141,14 +141,20 @@ void TextureNULL::syncState(const gl::Te
 {
 }
 
 gl::Error TextureNULL::setStorageMultisample(const gl::Context *context,
                                              GLenum target,
                                              GLsizei samples,
                                              GLint internalformat,
                                              const gl::Extents &size,
-                                             GLboolean fixedSampleLocations)
+                                             bool fixedSampleLocations)
+{
+    return gl::NoError();
+}
+
+gl::Error TextureNULL::initializeContents(const gl::Context *context,
+                                          const gl::ImageIndex &imageIndex)
 {
     return gl::NoError();
 }
 
 }  // namespace rx
--- a/gfx/angle/src/libANGLE/renderer/null/TextureNULL.h
+++ b/gfx/angle/src/libANGLE/renderer/null/TextureNULL.h
@@ -93,14 +93,17 @@ class TextureNULL : public TextureImpl
 
     void syncState(const gl::Texture::DirtyBits &dirtyBits) override;
 
     gl::Error setStorageMultisample(const gl::Context *context,
                                     GLenum target,
                                     GLsizei samples,
                                     GLint internalformat,
                                     const gl::Extents &size,
-                                    GLboolean fixedSampleLocations) override;
+                                    bool fixedSampleLocations) override;
+
+    gl::Error initializeContents(const gl::Context *context,
+                                 const gl::ImageIndex &imageIndex) override;
 };
 
 }  // namespace rx
 
 #endif  // LIBANGLE_RENDERER_NULL_TEXTURENULL_H_
--- a/gfx/angle/src/libANGLE/renderer/renderer_utils.cpp
+++ b/gfx/angle/src/libANGLE/renderer/renderer_utils.cpp
@@ -8,17 +8,19 @@
 //
 
 #include "libANGLE/renderer/renderer_utils.h"
 
 #include "image_util/copyimage.h"
 #include "image_util/imageformats.h"
 
 #include "libANGLE/AttributeMap.h"
+#include "libANGLE/Context.h"
 #include "libANGLE/formatutils.h"
+#include "libANGLE/renderer/ContextImpl.h"
 #include "libANGLE/renderer/Format.h"
 
 #include <string.h>
 
 namespace rx
 {
 
 namespace
@@ -230,37 +232,28 @@ PackPixelsParams::PackPixelsParams()
 {
 }
 
 PackPixelsParams::PackPixelsParams(const gl::Rectangle &areaIn,
                                    GLenum formatIn,
                                    GLenum typeIn,
                                    GLuint outputPitchIn,
                                    const gl::PixelPackState &packIn,
+                                   gl::Buffer *packBufferIn,
                                    ptrdiff_t offsetIn)
     : area(areaIn),
       format(formatIn),
       type(typeIn),
       outputPitch(outputPitchIn),
-      packBuffer(packIn.pixelBuffer.get()),
-      pack(packIn.alignment, packIn.reverseRowOrder),
+      packBuffer(packBufferIn),
+      pack(),
       offset(offsetIn)
 {
-}
-
-PackPixelsParams::PackPixelsParams(const gl::Context *context, const PackPixelsParams &other)
-    : area(other.area),
-      format(other.format),
-      type(other.type),
-      outputPitch(other.outputPitch),
-      packBuffer(other.packBuffer),
-      pack(),
-      offset(other.offset)
-{
-    pack.copyFrom(context, other.pack);
+    pack.alignment       = packIn.alignment;
+    pack.reverseRowOrder = packIn.reverseRowOrder;
 }
 
 void PackPixels(const PackPixelsParams &params,
                 const angle::Format &sourceFormat,
                 int inputPitchIn,
                 const uint8_t *sourceIn,
                 uint8_t *destWithoutOffset)
 {
@@ -377,21 +370,21 @@ ColorCopyFunction FastCopyFunctionMap::g
 }
 
 bool ShouldUseDebugLayers(const egl::AttributeMap &attribs)
 {
     EGLAttrib debugSetting =
         attribs.get(EGL_PLATFORM_ANGLE_DEBUG_LAYERS_ENABLED_ANGLE, EGL_DONT_CARE);
 
 // Prefer to enable debug layers if compiling in Debug, and disabled in Release.
-#if !defined(NDEBUG)
+#if defined(ANGLE_ENABLE_ASSERTS)
     return (debugSetting != EGL_FALSE);
 #else
     return (debugSetting == EGL_TRUE);
-#endif  // !defined(NDEBUG)
+#endif  // defined(ANGLE_ENABLE_ASSERTS)
 }
 
 void CopyImageCHROMIUM(const uint8_t *sourceData,
                        size_t sourceRowPitch,
                        size_t sourcePixelBytes,
                        ColorReadFunction colorReadFunction,
                        uint8_t *destData,
                        size_t destRowPitch,
@@ -465,9 +458,92 @@ void CopyImageCHROMIUM(const uint8_t *so
             }
 
             uint8_t *destPixelData = destData + destY * destRowPitch + x * destPixelBytes;
             writeFunction(sourceColor, colorWriteFunction, destPixelData);
         }
     }
 }
 
+// IncompleteTextureSet implementation.
+IncompleteTextureSet::IncompleteTextureSet()
+{
+}
+
+IncompleteTextureSet::~IncompleteTextureSet()
+{
+}
+
+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);
+    }
+    mIncompleteTextures.clear();
+}
+
+gl::Error IncompleteTextureSet::getIncompleteTexture(
+    const gl::Context *context,
+    GLenum type,
+    MultisampleTextureInitializer *multisampleInitializer,
+    gl::Texture **textureOut)
+{
+    auto iter = mIncompleteTextures.find(type);
+    if (iter != mIncompleteTextures.end())
+    {
+        *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::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)
+    {
+        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)
+    {
+        for (GLenum face = GL_TEXTURE_CUBE_MAP_POSITIVE_X; face <= GL_TEXTURE_CUBE_MAP_NEGATIVE_Z;
+             face++)
+        {
+            ANGLE_TRY(
+                t->setSubImage(context, unpack, face, 0, area, GL_RGBA, GL_UNSIGNED_BYTE, color));
+        }
+    }
+    else if (type == GL_TEXTURE_2D_MULTISAMPLE)
+    {
+        // 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));
+    }
+
+    t->syncState();
+
+    mIncompleteTextures[type].set(context, t.release());
+    *textureOut = mIncompleteTextures[type].get();
+    return gl::NoError();
+}
+
 }  // namespace rx
--- a/gfx/angle/src/libANGLE/renderer/renderer_utils.h
+++ b/gfx/angle/src/libANGLE/renderer/renderer_utils.h
@@ -133,26 +133,26 @@ class FastCopyFunctionMap
     bool has(const gl::FormatType &formatType) const;
     ColorCopyFunction get(const gl::FormatType &formatType) const;
 
   private:
     size_t mSize;
     const Entry *mData;
 };
 
-struct PackPixelsParams : private angle::NonCopyable
+struct PackPixelsParams
 {
     PackPixelsParams();
     PackPixelsParams(const gl::Rectangle &area,
                      GLenum format,
                      GLenum type,
                      GLuint outputPitch,
                      const gl::PixelPackState &pack,
+                     gl::Buffer *packBufferIn,
                      ptrdiff_t offset);
-    PackPixelsParams(const gl::Context *context, const PackPixelsParams &other);
 
     gl::Rectangle area;
     GLenum format;
     GLenum type;
     GLuint outputPitch;
     gl::Buffer *packBuffer;
     gl::PixelPackState pack;
     ptrdiff_t offset;
@@ -212,11 +212,43 @@ void CopyImageCHROMIUM(const uint8_t *so
                        GLenum destUnsizedFormat,
                        GLenum destComponentType,
                        size_t width,
                        size_t height,
                        bool unpackFlipY,
                        bool unpackPremultiplyAlpha,
                        bool unpackUnmultiplyAlpha);
 
+// Incomplete textures are 1x1 textures filled with black, used when samplers are incomplete.
+// This helper class encapsulates handling incomplete textures. Because the GL back-end
+// can take advantage of the driver's incomplete textures, and because clearing multisample
+// textures is so difficult, we can keep an instance of this class in the back-end instead
+// of moving the logic to the Context front-end.
+
+// This interface allows us to call-back to init a multisample texture.
+class MultisampleTextureInitializer
+{
+  public:
+    virtual ~MultisampleTextureInitializer() {}
+    virtual gl::Error initializeMultisampleTextureToBlack(const gl::Context *context,
+                                                          gl::Texture *glTexture) = 0;
+};
+
+class IncompleteTextureSet final : angle::NonCopyable
+{
+  public:
+    IncompleteTextureSet();
+    ~IncompleteTextureSet();
+
+    void onDestroy(const gl::Context *context);
+
+    gl::Error getIncompleteTexture(const gl::Context *context,
+                                   GLenum type,
+                                   MultisampleTextureInitializer *multisampleInitializer,
+                                   gl::Texture **textureOut);
+
+  private:
+    gl::TextureMap mIncompleteTextures;
+};
+
 }  // namespace rx
 
 #endif  // LIBANGLE_RENDERER_RENDERER_UTILS_H_
--- a/gfx/angle/src/libANGLE/renderer/vulkan/BufferVk.cpp
+++ b/gfx/angle/src/libANGLE/renderer/vulkan/BufferVk.cpp
@@ -5,112 +5,97 @@
 //
 // BufferVk.cpp:
 //    Implements the class methods for BufferVk.
 //
 
 #include "libANGLE/renderer/vulkan/BufferVk.h"
 
 #include "common/debug.h"
+#include "common/utilities.h"
 #include "libANGLE/Context.h"
 #include "libANGLE/renderer/vulkan/ContextVk.h"
 #include "libANGLE/renderer/vulkan/RendererVk.h"
 
 namespace rx
 {
 
-BufferVk::BufferVk(const gl::BufferState &state) : BufferImpl(state), mRequiredSize(0)
+BufferVk::BufferVk(const gl::BufferState &state) : BufferImpl(state), mCurrentRequiredSize(0)
 {
 }
 
 BufferVk::~BufferVk()
 {
 }
 
 void BufferVk::destroy(const gl::Context *context)
 {
-    VkDevice device = GetImplAs<ContextVk>(context)->getDevice();
+    ContextVk *contextVk = vk::GetImpl(context);
+    RendererVk *renderer = contextVk->getRenderer();
 
-    mBuffer.destroy(device);
+    release(renderer);
+}
+
+void BufferVk::release(RendererVk *renderer)
+{
+    renderer->releaseResource(*this, &mBuffer);
+    renderer->releaseResource(*this, &mBufferMemory);
 }
 
 gl::Error BufferVk::setData(const gl::Context *context,
-                            GLenum target,
+                            gl::BufferBinding target,
                             const void *data,
                             size_t size,
-                            GLenum usage)
+                            gl::BufferUsage usage)
 {
-    ContextVk *contextVk = GetImplAs<ContextVk>(context);
-    auto device          = contextVk->getDevice();
+    ContextVk *contextVk = vk::GetImpl(context);
+    VkDevice device      = contextVk->getDevice();
 
-    // TODO(jmadill): Proper usage bit implementation. Likely will involve multiple backing buffers
-    // like in D3D11.
-    VkBufferCreateInfo createInfo;
-    createInfo.sType                 = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO;
-    createInfo.pNext                 = nullptr;
-    createInfo.flags                 = 0;
-    createInfo.size                  = size;
-    createInfo.usage                 = VK_BUFFER_USAGE_VERTEX_BUFFER_BIT;
-    createInfo.sharingMode           = VK_SHARING_MODE_EXCLUSIVE;
-    createInfo.queueFamilyIndexCount = 0;
-    createInfo.pQueueFamilyIndices   = nullptr;
-
-    vk::Buffer newBuffer;
-    ANGLE_TRY(newBuffer.init(device, createInfo));
+    if (size > mCurrentRequiredSize)
+    {
+        // Release and re-create the memory and buffer.
+        release(contextVk->getRenderer());
 
-    // Find a compatible memory pool index. If the index doesn't change, we could cache it.
-    // Not finding a valid memory pool means an out-of-spec driver, or internal error.
-    // TODO(jmadill): More efficient memory allocation.
-    VkMemoryRequirements memoryRequirements;
-    vkGetBufferMemoryRequirements(device, newBuffer.getHandle(), &memoryRequirements);
-
-    // The requirements size is not always equal to the specified API size.
-    ASSERT(memoryRequirements.size >= size);
-    mRequiredSize = static_cast<size_t>(memoryRequirements.size);
-
-    VkPhysicalDeviceMemoryProperties memoryProperties;
-    vkGetPhysicalDeviceMemoryProperties(contextVk->getRenderer()->getPhysicalDevice(),
-                                        &memoryProperties);
+        // TODO(jmadill): Proper usage bit implementation. Likely will involve multiple backing
+        // buffers like in D3D11.
+        VkBufferCreateInfo createInfo;
+        createInfo.sType                 = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO;
+        createInfo.pNext                 = nullptr;
+        createInfo.flags                 = 0;
+        createInfo.size                  = size;
+        createInfo.usage = (VK_BUFFER_USAGE_VERTEX_BUFFER_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT |
+                            VK_BUFFER_USAGE_INDEX_BUFFER_BIT);
+        createInfo.sharingMode           = VK_SHARING_MODE_EXCLUSIVE;
+        createInfo.queueFamilyIndexCount = 0;
+        createInfo.pQueueFamilyIndices   = nullptr;
 
-    auto memoryTypeIndex =
-        FindMemoryType(memoryProperties, memoryRequirements,
-                       VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT);
-    ANGLE_VK_CHECK(memoryTypeIndex.valid(), VK_ERROR_INCOMPATIBLE_DRIVER);
-
-    VkMemoryAllocateInfo allocInfo;
-    allocInfo.sType           = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
-    allocInfo.pNext           = nullptr;
-    allocInfo.memoryTypeIndex = memoryTypeIndex.value();
-    allocInfo.allocationSize  = memoryRequirements.size;
-
-    ANGLE_TRY(newBuffer.getMemory().allocate(device, allocInfo));
-    ANGLE_TRY(newBuffer.bindMemory(device));
-
-    mBuffer.retain(device, std::move(newBuffer));
+        ANGLE_TRY(mBuffer.init(device, createInfo));
+        ANGLE_TRY(vk::AllocateBufferMemory(contextVk, size, &mBuffer, &mBufferMemory,
+                                           &mCurrentRequiredSize));
+    }
 
     if (data)
     {
-        ANGLE_TRY(setDataImpl(device, static_cast<const uint8_t *>(data), size, 0));
+        ANGLE_TRY(setDataImpl(contextVk, static_cast<const uint8_t *>(data), size, 0));
     }
 
     return gl::NoError();
 }
 
 gl::Error BufferVk::setSubData(const gl::Context *context,
-                               GLenum target,
+                               gl::BufferBinding target,
                                const void *data,
                                size_t size,
                                size_t offset)
 {
     ASSERT(mBuffer.getHandle() != VK_NULL_HANDLE);
-    ASSERT(mBuffer.getMemory().getHandle() != VK_NULL_HANDLE);
+    ASSERT(mBufferMemory.getHandle() != VK_NULL_HANDLE);
 
-    VkDevice device = GetImplAs<ContextVk>(context)->getDevice();
-
-    ANGLE_TRY(setDataImpl(device, static_cast<const uint8_t *>(data), size, offset));
+    ContextVk *contextVk = vk::GetImpl(context);
+    ANGLE_TRY(setDataImpl(contextVk, static_cast<const uint8_t *>(data), size, offset));
 
     return gl::NoError();
 }
 
 gl::Error BufferVk::copySubData(const gl::Context *context,
                                 BufferImpl *source,
                                 GLintptr sourceOffset,
                                 GLintptr destOffset,
@@ -118,75 +103,135 @@ gl::Error BufferVk::copySubData(const gl
 {
     UNIMPLEMENTED();
     return gl::InternalError();
 }
 
 gl::Error BufferVk::map(const gl::Context *context, GLenum access, void **mapPtr)
 {
     ASSERT(mBuffer.getHandle() != VK_NULL_HANDLE);
-    ASSERT(mBuffer.getMemory().getHandle() != VK_NULL_HANDLE);
+    ASSERT(mBufferMemory.getHandle() != VK_NULL_HANDLE);
 
-    VkDevice device = GetImplAs<ContextVk>(context)->getDevice();
+    VkDevice device = vk::GetImpl(context)->getDevice();
 
-    ANGLE_TRY(mBuffer.getMemory().map(device, 0, mState.getSize(), 0,
-                                      reinterpret_cast<uint8_t **>(mapPtr)));
+    ANGLE_TRY(
+        mBufferMemory.map(device, 0, mState.getSize(), 0, reinterpret_cast<uint8_t **>(mapPtr)));
 
     return gl::NoError();
 }
 
 gl::Error BufferVk::mapRange(const gl::Context *context,
                              size_t offset,
                              size_t length,
                              GLbitfield access,
                              void **mapPtr)
 {
     ASSERT(mBuffer.getHandle() != VK_NULL_HANDLE);
-    ASSERT(mBuffer.getMemory().getHandle() != VK_NULL_HANDLE);
+    ASSERT(mBufferMemory.getHandle() != VK_NULL_HANDLE);
 
-    VkDevice device = GetImplAs<ContextVk>(context)->getDevice();
+    VkDevice device = vk::GetImpl(context)->getDevice();
 
-    ANGLE_TRY(
-        mBuffer.getMemory().map(device, offset, length, 0, reinterpret_cast<uint8_t **>(mapPtr)));
+    ANGLE_TRY(mBufferMemory.map(device, offset, length, 0, reinterpret_cast<uint8_t **>(mapPtr)));
 
     return gl::NoError();
 }
 
 gl::Error BufferVk::unmap(const gl::Context *context, GLboolean *result)
 {
     ASSERT(mBuffer.getHandle() != VK_NULL_HANDLE);
-    ASSERT(mBuffer.getMemory().getHandle() != VK_NULL_HANDLE);
+    ASSERT(mBufferMemory.getHandle() != VK_NULL_HANDLE);
 
-    VkDevice device = GetImplAs<ContextVk>(context)->getDevice();
+    VkDevice device = vk::GetImpl(context)->getDevice();
 
-    mBuffer.getMemory().unmap(device);
+    mBufferMemory.unmap(device);
 
     return gl::NoError();
 }
 
 gl::Error BufferVk::getIndexRange(const gl::Context *context,
                                   GLenum type,
                                   size_t offset,
                                   size_t count,
                                   bool primitiveRestartEnabled,
                                   gl::IndexRange *outRange)
 {
-    UNIMPLEMENTED();
-    return gl::InternalError();
+    VkDevice device = vk::GetImpl(context)->getDevice();
+
+    // TODO(jmadill): Consider keeping a shadow system memory copy in some cases.
+    ASSERT(mBuffer.valid());
+
+    const gl::Type &typeInfo = gl::GetTypeInfo(type);
+
+    uint8_t *mapPointer = nullptr;
+    ANGLE_TRY(mBufferMemory.map(device, offset, typeInfo.bytes * count, 0, &mapPointer));
+
+    *outRange = gl::ComputeIndexRange(type, mapPointer, count, primitiveRestartEnabled);
+
+    return gl::NoError();
 }
 
-vk::Error BufferVk::setDataImpl(VkDevice device, const uint8_t *data, size_t size, size_t offset)
+vk::Error BufferVk::setDataImpl(ContextVk *contextVk,
+                                const uint8_t *data,
+                                size_t size,
+                                size_t offset)
 {
-    uint8_t *mapPointer = nullptr;
-    ANGLE_TRY(mBuffer.getMemory().map(device, offset, size, 0, &mapPointer));
-    ASSERT(mapPointer);
+    RendererVk *renderer = contextVk->getRenderer();
+    VkDevice device      = contextVk->getDevice();
+
+    // Use map when available.
+    if (renderer->isSerialInUse(getQueueSerial()))
+    {
+        vk::StagingBuffer stagingBuffer;
+        ANGLE_TRY(stagingBuffer.init(contextVk, static_cast<VkDeviceSize>(size),
+                                     vk::StagingUsage::Write));
+
+        uint8_t *mapPointer = nullptr;
+        ANGLE_TRY(stagingBuffer.getDeviceMemory().map(device, 0, size, 0, &mapPointer));
+        ASSERT(mapPointer);
+
+        memcpy(mapPointer, data, size);
+        stagingBuffer.getDeviceMemory().unmap(device);
+
+        // Enqueue a copy command on the GPU.
+        vk::CommandBuffer *commandBuffer = nullptr;
+        ANGLE_TRY(recordWriteCommands(renderer, &commandBuffer));
 
-    memcpy(mapPointer, data, size);
+        // Insert a barrier to ensure reads from the buffer are complete.
+        // TODO(jmadill): Insert minimal barriers.
+        VkBufferMemoryBarrier bufferBarrier;
+        bufferBarrier.sType               = VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER;
+        bufferBarrier.pNext               = nullptr;
+        bufferBarrier.srcAccessMask       = VK_ACCESS_MEMORY_READ_BIT;
+        bufferBarrier.dstAccessMask       = VK_ACCESS_TRANSFER_WRITE_BIT;
+        bufferBarrier.srcQueueFamilyIndex = 0;
+        bufferBarrier.dstQueueFamilyIndex = 0;
+        bufferBarrier.buffer              = mBuffer.getHandle();
+        bufferBarrier.offset              = offset;
+        bufferBarrier.size                = static_cast<VkDeviceSize>(size);
+
+        commandBuffer->singleBufferBarrier(VK_PIPELINE_STAGE_ALL_COMMANDS_BIT,
+                                           VK_PIPELINE_STAGE_TRANSFER_BIT, 0, bufferBarrier);
 
-    mBuffer.getMemory().unmap(device);
+        VkBufferCopy copyRegion = {offset, 0, size};
+        commandBuffer->copyBuffer(stagingBuffer.getBuffer(), mBuffer, 1, &copyRegion);
+
+        // Immediately release staging buffer.
+        // TODO(jmadill): Staging buffer re-use.
+        renderer->releaseObject(getQueueSerial(), &stagingBuffer);
+    }
+    else
+    {
+        uint8_t *mapPointer = nullptr;
+        ANGLE_TRY(mBufferMemory.map(device, offset, size, 0, &mapPointer));
+        ASSERT(mapPointer);
+
+        memcpy(mapPointer, data, size);
+
+        mBufferMemory.unmap(device);
+    }
 
     return vk::NoError();
 }
 
 const vk::Buffer &BufferVk::getVkBuffer() const
 {
     return mBuffer;
 }
--- a/gfx/angle/src/libANGLE/renderer/vulkan/BufferVk.h
+++ b/gfx/angle/src/libANGLE/renderer/vulkan/BufferVk.h
@@ -10,31 +10,32 @@
 #ifndef LIBANGLE_RENDERER_VULKAN_BUFFERVK_H_
 #define LIBANGLE_RENDERER_VULKAN_BUFFERVK_H_
 
 #include "libANGLE/renderer/BufferImpl.h"
 #include "libANGLE/renderer/vulkan/renderervk_utils.h"
 
 namespace rx
 {
+class RendererVk;
 
 class BufferVk : public BufferImpl, public ResourceVk
 {
   public:
     BufferVk(const gl::BufferState &state);
     ~BufferVk() override;
     void destroy(const gl::Context *context) override;
 
     gl::Error setData(const gl::Context *context,
-                      GLenum target,
+                      gl::BufferBinding target,
                       const void *data,
                       size_t size,
-                      GLenum usage) override;
+                      gl::BufferUsage usage) override;
     gl::Error setSubData(const gl::Context *context,
-                         GLenum target,
+                         gl::BufferBinding target,
                          const void *data,
                          size_t size,
                          size_t offset) override;
     gl::Error copySubData(const gl::Context *context,
                           BufferImpl *source,
                           GLintptr sourceOffset,
                           GLintptr destOffset,
                           GLsizeiptr size) override;
@@ -51,17 +52,19 @@ class BufferVk : public BufferImpl, publ
                             size_t offset,
                             size_t count,
                             bool primitiveRestartEnabled,
                             gl::IndexRange *outRange) override;
 
     const vk::Buffer &getVkBuffer() const;
 
   private:
-    vk::Error setDataImpl(VkDevice device, const uint8_t *data, size_t size, size_t offset);
+    vk::Error setDataImpl(ContextVk *contextVk, const uint8_t *data, size_t size, size_t offset);
+    void release(RendererVk *renderer);
 
     vk::Buffer mBuffer;
-    size_t mRequiredSize;
+    vk::DeviceMemory mBufferMemory;
+    size_t mCurrentRequiredSize;
 };
 
 }  // namespace rx
 
 #endif  // LIBANGLE_RENDERER_VULKAN_BUFFERVK_H_
new file mode 100644
--- /dev/null
+++ b/gfx/angle/src/libANGLE/renderer/vulkan/CommandBufferNode.cpp
@@ -0,0 +1,275 @@
+//
+// 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.
+//
+// CommandBufferNode:
+//    Deferred work constructed by GL calls, that will later be flushed to Vulkan.
+//
+
+#include "libANGLE/renderer/vulkan/CommandBufferNode.h"
+
+#include "libANGLE/renderer/vulkan/RenderTargetVk.h"
+#include "libANGLE/renderer/vulkan/RendererVk.h"
+#include "libANGLE/renderer/vulkan/formatutilsvk.h"
+
+namespace rx
+{
+
+namespace vk
+{
+
+namespace
+{
+
+Error InitAndBeginCommandBuffer(VkDevice device,
+                                const CommandPool &commandPool,
+                                const VkCommandBufferInheritanceInfo &inheritanceInfo,
+                                VkCommandBufferUsageFlags flags,
+                                CommandBuffer *commandBuffer)
+{
+    ASSERT(!commandBuffer->valid());
+
+    VkCommandBufferAllocateInfo createInfo;
+    createInfo.sType              = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO;
+    createInfo.pNext              = nullptr;
+    createInfo.commandPool        = commandPool.getHandle();
+    createInfo.level              = VK_COMMAND_BUFFER_LEVEL_SECONDARY;
+    createInfo.commandBufferCount = 1;
+
+    ANGLE_TRY(commandBuffer->init(device, createInfo));
+
+    VkCommandBufferBeginInfo beginInfo;
+    beginInfo.sType            = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
+    beginInfo.pNext            = nullptr;
+    beginInfo.flags            = flags | VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT;
+    beginInfo.pInheritanceInfo = &inheritanceInfo;
+
+    ANGLE_TRY(commandBuffer->begin(beginInfo));
+    return NoError();
+}
+
+}  // anonymous namespace
+
+// CommandBufferNode implementation.
+
+CommandBufferNode::CommandBufferNode()
+    : mIsDependency(false), mVisitedState(VisitedState::Unvisited)
+{
+}
+
+CommandBufferNode::~CommandBufferNode()
+{
+    mRenderPassFramebuffer.setHandle(VK_NULL_HANDLE);
+
+    // Command buffers are managed by the command pool, so don't need to be freed.
+    mOutsideRenderPassCommands.releaseHandle();
+    mInsideRenderPassCommands.releaseHandle();
+}
+
+CommandBuffer *CommandBufferNode::getOutsideRenderPassCommands()
+{
+    return &mOutsideRenderPassCommands;
+}
+
+CommandBuffer *CommandBufferNode::getInsideRenderPassCommands()
+{
+    return &mInsideRenderPassCommands;
+}
+
+Error CommandBufferNode::startRecording(VkDevice device,
+                                        const CommandPool &commandPool,
+                                        CommandBuffer **commandsOut)
+{
+    VkCommandBufferInheritanceInfo inheritanceInfo;
+    inheritanceInfo.sType                = VK_STRUCTURE_TYPE_COMMAND_BUFFER_INHERITANCE_INFO;
+    inheritanceInfo.pNext                = nullptr;
+    inheritanceInfo.renderPass           = VK_NULL_HANDLE;
+    inheritanceInfo.subpass              = 0;
+    inheritanceInfo.framebuffer          = VK_NULL_HANDLE;
+    inheritanceInfo.occlusionQueryEnable = VK_FALSE;
+    inheritanceInfo.queryFlags           = 0;
+    inheritanceInfo.pipelineStatistics   = 0;
+
+    ANGLE_TRY(InitAndBeginCommandBuffer(device, commandPool, inheritanceInfo, 0,
+                                        &mOutsideRenderPassCommands));
+
+    *commandsOut = &mOutsideRenderPassCommands;
+    return NoError();
+}
+
+Error CommandBufferNode::startRenderPassRecording(RendererVk *renderer, CommandBuffer **commandsOut)
+{
+    // Get a compatible RenderPass from the cache so we can initialize the inheritance info.
+    // TODO(jmadill): Use different query method for compatible vs conformant render pass.
+    vk::RenderPass *compatibleRenderPass;
+    ANGLE_TRY(renderer->getCompatibleRenderPass(mRenderPassDesc, &compatibleRenderPass));
+
+    VkCommandBufferInheritanceInfo inheritanceInfo;
+    inheritanceInfo.sType                = VK_STRUCTURE_TYPE_COMMAND_BUFFER_INHERITANCE_INFO;
+    inheritanceInfo.pNext                = nullptr;
+    inheritanceInfo.renderPass           = compatibleRenderPass->getHandle();
+    inheritanceInfo.subpass              = 0;
+    inheritanceInfo.framebuffer          = mRenderPassFramebuffer.getHandle();
+    inheritanceInfo.occlusionQueryEnable = VK_FALSE;
+    inheritanceInfo.queryFlags           = 0;
+    inheritanceInfo.pipelineStatistics   = 0;
+
+    ANGLE_TRY(InitAndBeginCommandBuffer(
+        renderer->getDevice(), renderer->getCommandPool(), inheritanceInfo,
+        VK_COMMAND_BUFFER_USAGE_RENDER_PASS_CONTINUE_BIT, &mInsideRenderPassCommands));
+
+    *commandsOut = &mInsideRenderPassCommands;
+    return NoError();
+}
+
+void CommandBufferNode::storeRenderPassInfo(const Framebuffer &framebuffer,
+                                            const gl::Rectangle renderArea,
+                                            const std::vector<VkClearValue> &clearValues)
+{
+    mRenderPassFramebuffer.setHandle(framebuffer.getHandle());
+    mRenderPassRenderArea = renderArea;
+    std::copy(clearValues.begin(), clearValues.end(), mRenderPassClearValues.begin());
+}
+
+void CommandBufferNode::appendColorRenderTarget(Serial serial, RenderTargetVk *colorRenderTarget)
+{
+    // TODO(jmadill): Layout transition?
+    mRenderPassDesc.packColorAttachment(*colorRenderTarget->format, colorRenderTarget->samples);
+    colorRenderTarget->resource->setWriteNode(serial, this);
+}
+
+void CommandBufferNode::appendDepthStencilRenderTarget(Serial serial,
+                                                       RenderTargetVk *depthStencilRenderTarget)
+{
+    // TODO(jmadill): Layout transition?
+    mRenderPassDesc.packDepthStencilAttachment(*depthStencilRenderTarget->format,
+                                               depthStencilRenderTarget->samples);
+    depthStencilRenderTarget->resource->setWriteNode(serial, this);
+}
+
+void CommandBufferNode::initAttachmentDesc(VkAttachmentDescription *desc)
+{
+    desc->flags          = 0;
+    desc->format         = VK_FORMAT_UNDEFINED;
+    desc->samples        = static_cast<VkSampleCountFlagBits>(0);
+    desc->loadOp         = VK_ATTACHMENT_LOAD_OP_CLEAR;
+    desc->storeOp        = VK_ATTACHMENT_STORE_OP_STORE;
+    desc->stencilLoadOp  = VK_ATTACHMENT_LOAD_OP_DONT_CARE;
+    desc->stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE;
+    desc->initialLayout  = VK_IMAGE_LAYOUT_UNDEFINED;
+    desc->finalLayout    = VK_IMAGE_LAYOUT_UNDEFINED;
+}
+
+void CommandBufferNode::addDependency(CommandBufferNode *node)
+{
+    mDependencies.emplace_back(node);
+    node->markAsDependency();
+    ASSERT(node != this && !node->hasDependency(this));
+}
+
+void CommandBufferNode::addDependencies(const std::vector<CommandBufferNode *> &nodes)
+{
+    mDependencies.insert(mDependencies.end(), nodes.begin(), nodes.end());
+
+    // TODO(jmadill): is there a faster way to do this?
+    for (CommandBufferNode *node : nodes)
+    {
+        node->markAsDependency();
+        ASSERT(node != this && !node->hasDependency(this));
+    }
+}
+
+bool CommandBufferNode::hasDependencies() const
+{
+    return !mDependencies.empty();
+}
+
+void CommandBufferNode::markAsDependency()
+{
+    mIsDependency = true;
+}
+
+bool CommandBufferNode::isDependency() const
+{
+    return mIsDependency;
+}
+
+// Do not call this in anything but testing code, since it's slow.
+bool CommandBufferNode::hasDependency(CommandBufferNode *searchNode)
+{
+    std::set<CommandBufferNode *> visitedList;
+    std::vector<CommandBufferNode *> openList;
+    openList.insert(openList.begin(), mDependencies.begin(), mDependencies.end());
+    while (!openList.empty())
+    {
+        CommandBufferNode *node = openList.back();
+        openList.pop_back();
+        if (visitedList.count(node) == 0)
+        {
+            if (node == searchNode)
+            {
+                return true;
+            }
+            visitedList.insert(node);
+            openList.insert(openList.end(), node->mDependencies.begin(), node->mDependencies.end());
+        }
+    }
+
+    return false;
+}
+
+VisitedState CommandBufferNode::visitedState() const
+{
+    return mVisitedState;
+}
+
+void CommandBufferNode::visitDependencies(std::vector<CommandBufferNode *> *stack)
+{
+    ASSERT(mVisitedState == VisitedState::Unvisited);
+    stack->insert(stack->end(), mDependencies.begin(), mDependencies.end());
+    mVisitedState = VisitedState::Ready;
+}
+
+vk::Error CommandBufferNode::visitAndExecute(RendererVk *renderer,
+                                             vk::CommandBuffer *primaryCommandBuffer)
+{
+    if (mOutsideRenderPassCommands.valid())
+    {
+        mOutsideRenderPassCommands.end();
+        primaryCommandBuffer->executeCommands(1, &mOutsideRenderPassCommands);
+    }
+
+    if (mInsideRenderPassCommands.valid())
+    {
+        // Pull a compatible RenderPass from the cache.
+        // TODO(jmadill): Insert real ops and layout transitions.
+        vk::RenderPass *renderPass = nullptr;
+        ANGLE_TRY(renderer->getCompatibleRenderPass(mRenderPassDesc, &renderPass));
+
+        mInsideRenderPassCommands.end();
+
+        VkRenderPassBeginInfo beginInfo;
+        beginInfo.sType                    = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO;
+        beginInfo.pNext                    = nullptr;
+        beginInfo.renderPass               = renderPass->getHandle();
+        beginInfo.framebuffer              = mRenderPassFramebuffer.getHandle();
+        beginInfo.renderArea.offset.x      = static_cast<uint32_t>(mRenderPassRenderArea.x);
+        beginInfo.renderArea.offset.y      = static_cast<uint32_t>(mRenderPassRenderArea.y);
+        beginInfo.renderArea.extent.width  = static_cast<uint32_t>(mRenderPassRenderArea.width);
+        beginInfo.renderArea.extent.height = static_cast<uint32_t>(mRenderPassRenderArea.height);
+        beginInfo.clearValueCount          = mRenderPassDesc.attachmentCount();
+        beginInfo.pClearValues             = mRenderPassClearValues.data();
+
+        primaryCommandBuffer->beginRenderPass(beginInfo,
+                                              VK_SUBPASS_CONTENTS_SECONDARY_COMMAND_BUFFERS);
+        primaryCommandBuffer->executeCommands(1, &mInsideRenderPassCommands);
+        primaryCommandBuffer->endRenderPass();
+    }
+
+    mVisitedState = VisitedState::Visited;
+    return vk::NoError();
+}
+
+}  // namespace vk
+}  // namespace rx
new file mode 100644
--- /dev/null
+++ b/gfx/angle/src/libANGLE/renderer/vulkan/CommandBufferNode.h
@@ -0,0 +1,93 @@
+//
+// 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.
+//
+// CommandBufferNode:
+//    Deferred work constructed by GL calls, that will later be flushed to Vulkan.
+//
+
+#ifndef LIBANGLE_RENDERER_VULKAN_COMMAND_BUFFER_NODE_H_
+#define LIBANGLE_RENDERER_VULKAN_COMMAND_BUFFER_NODE_H_
+
+#include "libANGLE/renderer/vulkan/renderervk_utils.h"
+
+namespace rx
+{
+
+namespace vk
+{
+
+enum class VisitedState
+{
+    Unvisited,
+    Ready,
+    Visited,
+};
+
+class CommandBufferNode final : angle::NonCopyable
+{
+  public:
+    CommandBufferNode();
+    ~CommandBufferNode();
+
+    // Immutable queries for when we're walking the commands tree.
+    CommandBuffer *getOutsideRenderPassCommands();
+    CommandBuffer *getInsideRenderPassCommands();
+
+    // For outside the render pass (copies, transitions, etc).
+    Error startRecording(VkDevice device,
+                         const CommandPool &commandPool,
+                         CommandBuffer **commandsOut);
+
+    // For rendering commands (draws).
+    Error startRenderPassRecording(RendererVk *renderer, CommandBuffer **commandsOut);
+
+    // Commands for storing info relevant to the RenderPass.
+    // RenderTargets must be added in order, with the depth/stencil being added last.
+    void storeRenderPassInfo(const Framebuffer &framebuffer,
+                             const gl::Rectangle renderArea,
+                             const std::vector<VkClearValue> &clearValues);
+    void appendColorRenderTarget(Serial serial, RenderTargetVk *colorRenderTarget);
+    void appendDepthStencilRenderTarget(Serial serial, RenderTargetVk *depthStencilRenderTarget);
+
+    // Commands for linking nodes in the dependency graph.
+    void addDependency(CommandBufferNode *node);
+    void addDependencies(const std::vector<CommandBufferNode *> &nodes);
+    bool hasDependencies() const;
+    bool isDependency() const;
+
+    // Used for testing only.
+    bool hasDependency(CommandBufferNode *searchNode);
+
+    // Commands for traversing the node on a flush operation.
+    VisitedState visitedState() const;
+    void visitDependencies(std::vector<CommandBufferNode *> *stack);
+    Error visitAndExecute(RendererVk *renderer, CommandBuffer *primaryCommandBuffer);
+
+  private:
+    void initAttachmentDesc(VkAttachmentDescription *desc);
+    void markAsDependency();
+
+    // Only used if we need a RenderPass for these commands.
+    RenderPassDesc mRenderPassDesc;
+    Framebuffer mRenderPassFramebuffer;
+    gl::Rectangle mRenderPassRenderArea;
+    gl::AttachmentArray<VkClearValue> mRenderPassClearValues;
+
+    // Keep a separate buffers for commands inside and outside a RenderPass.
+    // TODO(jmadill): We might not need inside and outside RenderPass commands separate.
+    CommandBuffer mOutsideRenderPassCommands;
+    CommandBuffer mInsideRenderPassCommands;
+
+    // Dependency commands must finish before these command can execute.
+    std::vector<CommandBufferNode *> mDependencies;
+    bool mIsDependency;
+
+    // Used when traversing the dependency graph.
+    VisitedState mVisitedState;
+};
+}  // namespace vk
+}  // namespace rx
+
+#endif  // LIBANGLE_RENDERER_VULKAN_COMMAND_BUFFER_NODE_H_
--- a/gfx/angle/src/libANGLE/renderer/vulkan/ContextVk.cpp
+++ b/gfx/angle/src/libANGLE/renderer/vulkan/ContextVk.cpp
@@ -6,18 +6,20 @@
 // ContextVk.cpp:
 //    Implements the class methods for ContextVk.
 //
 
 #include "libANGLE/renderer/vulkan/ContextVk.h"
 
 #include "common/bitset_utils.h"
 #include "common/debug.h"
+#include "libANGLE/Context.h"
 #include "libANGLE/Program.h"
 #include "libANGLE/renderer/vulkan/BufferVk.h"
+#include "libANGLE/renderer/vulkan/CommandBufferNode.h"
 #include "libANGLE/renderer/vulkan/CompilerVk.h"
 #include "libANGLE/renderer/vulkan/ContextVk.h"
 #include "libANGLE/renderer/vulkan/DeviceVk.h"
 #include "libANGLE/renderer/vulkan/FenceNVVk.h"
 #include "libANGLE/renderer/vulkan/FramebufferVk.h"
 #include "libANGLE/renderer/vulkan/ImageVk.h"
 #include "libANGLE/renderer/vulkan/ProgramPipelineVk.h"
 #include "libANGLE/renderer/vulkan/ProgramVk.h"
@@ -30,306 +32,390 @@
 #include "libANGLE/renderer/vulkan/TextureVk.h"
 #include "libANGLE/renderer/vulkan/TransformFeedbackVk.h"
 #include "libANGLE/renderer/vulkan/VertexArrayVk.h"
 #include "libANGLE/renderer/vulkan/formatutilsvk.h"
 
 namespace rx
 {
 
+namespace
+{
+
+VkIndexType GetVkIndexType(GLenum glIndexType)
+{
+    switch (glIndexType)
+    {
+        case GL_UNSIGNED_SHORT:
+            return VK_INDEX_TYPE_UINT16;
+        case GL_UNSIGNED_INT:
+            return VK_INDEX_TYPE_UINT32;
+        default:
+            UNREACHABLE();
+            return VK_INDEX_TYPE_MAX_ENUM;
+    }
+}
+
+enum DescriptorPoolIndex : uint8_t
+{
+    UniformBufferPool = 0,
+    TexturePool       = 1,
+};
+
+}  // anonymous namespace
+
 ContextVk::ContextVk(const gl::ContextState &state, RendererVk *renderer)
-    : ContextImpl(state), mRenderer(renderer), mCurrentDrawMode(GL_NONE)
+    : ContextImpl(state),
+      mRenderer(renderer),
+      mCurrentDrawMode(GL_NONE),
+      mVertexArrayDirty(false),
+      mTexturesDirty(false)
 {
+    // The module handle is filled out at draw time.
+    mCurrentShaderStages[0].sType  = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO;
+    mCurrentShaderStages[0].pNext  = nullptr;
+    mCurrentShaderStages[0].flags  = 0;
+    mCurrentShaderStages[0].stage  = VK_SHADER_STAGE_VERTEX_BIT;
+    mCurrentShaderStages[0].module = VK_NULL_HANDLE;
+    mCurrentShaderStages[0].pName  = "main";
+    mCurrentShaderStages[0].pSpecializationInfo = nullptr;
+
+    mCurrentShaderStages[1].sType  = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO;
+    mCurrentShaderStages[1].pNext  = nullptr;
+    mCurrentShaderStages[1].flags  = 0;
+    mCurrentShaderStages[1].stage  = VK_SHADER_STAGE_FRAGMENT_BIT;
+    mCurrentShaderStages[1].module = VK_NULL_HANDLE;
+    mCurrentShaderStages[1].pName  = "main";
+    mCurrentShaderStages[1].pSpecializationInfo = nullptr;
+
+    // The binding descriptions are filled in at draw time.
+    mCurrentVertexInputState.sType = VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO;
+    mCurrentVertexInputState.pNext = nullptr;
+    mCurrentVertexInputState.flags = 0;
+    mCurrentVertexInputState.vertexBindingDescriptionCount   = 0;
+    mCurrentVertexInputState.pVertexBindingDescriptions      = nullptr;
+    mCurrentVertexInputState.vertexAttributeDescriptionCount = 0;
+    mCurrentVertexInputState.pVertexAttributeDescriptions    = nullptr;
+
+    // Primitive topology is filled in at draw time.
+    mCurrentInputAssemblyState.sType = VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO;
+    mCurrentInputAssemblyState.pNext = nullptr;
+    mCurrentInputAssemblyState.flags = 0;
+    mCurrentInputAssemblyState.topology = gl_vk::GetPrimitiveTopology(mCurrentDrawMode);
+    mCurrentInputAssemblyState.primitiveRestartEnable = VK_FALSE;
+
+    // Set initial viewport and scissor state.
+    mCurrentViewportVk.x        = 0.0f;
+    mCurrentViewportVk.y        = 0.0f;
+    mCurrentViewportVk.width    = 0.0f;
+    mCurrentViewportVk.height   = 0.0f;
+    mCurrentViewportVk.minDepth = 0.0f;
+    mCurrentViewportVk.maxDepth = 1.0f;
+
+    mCurrentScissorVk.offset.x      = 0;
+    mCurrentScissorVk.offset.y      = 0;
+    mCurrentScissorVk.extent.width  = 0u;
+    mCurrentScissorVk.extent.height = 0u;
+
+    mCurrentViewportState.sType         = VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO;
+    mCurrentViewportState.pNext         = nullptr;
+    mCurrentViewportState.flags         = 0;
+    mCurrentViewportState.viewportCount = 1;
+    mCurrentViewportState.pViewports    = &mCurrentViewportVk;
+    mCurrentViewportState.scissorCount  = 1;
+    mCurrentViewportState.pScissors     = &mCurrentScissorVk;
+
+    // Set initial rasterizer state.
+    // TODO(jmadill): Extra rasterizer state features.
+    mCurrentRasterState.sType = VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO;
+    mCurrentRasterState.pNext = nullptr;
+    mCurrentRasterState.flags = 0;
+    mCurrentRasterState.depthClampEnable        = VK_FALSE;
+    mCurrentRasterState.rasterizerDiscardEnable = VK_FALSE;
+    mCurrentRasterState.polygonMode             = VK_POLYGON_MODE_FILL;
+    mCurrentRasterState.cullMode                = VK_CULL_MODE_NONE;
+    mCurrentRasterState.frontFace               = VK_FRONT_FACE_COUNTER_CLOCKWISE;
+    mCurrentRasterState.depthBiasEnable         = VK_FALSE;
+    mCurrentRasterState.depthBiasConstantFactor = 0.0f;
+    mCurrentRasterState.depthBiasClamp          = 0.0f;
+    mCurrentRasterState.depthBiasSlopeFactor    = 0.0f;
+    mCurrentRasterState.lineWidth               = 1.0f;
+
+    // Initialize a dummy multisample state.
+    // TODO(jmadill): Multisample state.
+    mCurrentMultisampleState.sType = VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO;
+    mCurrentMultisampleState.pNext = nullptr;
+    mCurrentMultisampleState.flags = 0;
+    mCurrentMultisampleState.rasterizationSamples  = VK_SAMPLE_COUNT_1_BIT;
+    mCurrentMultisampleState.sampleShadingEnable   = VK_FALSE;
+    mCurrentMultisampleState.minSampleShading      = 0.0f;
+    mCurrentMultisampleState.pSampleMask           = nullptr;
+    mCurrentMultisampleState.alphaToCoverageEnable = VK_FALSE;
+    mCurrentMultisampleState.alphaToOneEnable      = VK_FALSE;
+
+    // TODO(jmadill): Depth/stencil state.
+
+    // Initialize a dummy MRT blend state.
+    // TODO(jmadill): Blend state/MRT.
+    mCurrentBlendAttachmentState.blendEnable         = VK_FALSE;
+    mCurrentBlendAttachmentState.srcColorBlendFactor = VK_BLEND_FACTOR_ONE;
+    mCurrentBlendAttachmentState.dstColorBlendFactor = VK_BLEND_FACTOR_ONE;
+    mCurrentBlendAttachmentState.colorBlendOp        = VK_BLEND_OP_ADD;
+    mCurrentBlendAttachmentState.srcAlphaBlendFactor = VK_BLEND_FACTOR_ONE;
+    mCurrentBlendAttachmentState.dstAlphaBlendFactor = VK_BLEND_FACTOR_ONE;
+    mCurrentBlendAttachmentState.alphaBlendOp        = VK_BLEND_OP_ADD;
+    mCurrentBlendAttachmentState.colorWriteMask =
+        (VK_COLOR_COMPONENT_R_BIT | VK_COLOR_COMPONENT_G_BIT | VK_COLOR_COMPONENT_B_BIT |
+         VK_COLOR_COMPONENT_A_BIT);
+
+    mCurrentBlendState.sType             = VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO;
+    mCurrentBlendState.pNext             = 0;
+    mCurrentBlendState.flags             = 0;
+    mCurrentBlendState.logicOpEnable     = VK_FALSE;
+    mCurrentBlendState.logicOp           = VK_LOGIC_OP_CLEAR;
+    mCurrentBlendState.attachmentCount   = 1;
+    mCurrentBlendState.pAttachments      = &mCurrentBlendAttachmentState;
+    mCurrentBlendState.blendConstants[0] = 0.0f;
+    mCurrentBlendState.blendConstants[1] = 0.0f;
+    mCurrentBlendState.blendConstants[2] = 0.0f;
+    mCurrentBlendState.blendConstants[3] = 0.0f;
+
+    // TODO(jmadill): Dynamic state.
+
+    // The layout and renderpass are filled out at draw time.
+    mCurrentPipelineInfo.sType               = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO;
+    mCurrentPipelineInfo.pNext               = nullptr;
+    mCurrentPipelineInfo.flags               = 0;
+    mCurrentPipelineInfo.stageCount          = 2;
+    mCurrentPipelineInfo.pStages             = mCurrentShaderStages;
+    mCurrentPipelineInfo.pVertexInputState   = &mCurrentVertexInputState;
+    mCurrentPipelineInfo.pInputAssemblyState = &mCurrentInputAssemblyState;
+    mCurrentPipelineInfo.pTessellationState  = nullptr;
+    mCurrentPipelineInfo.pViewportState      = &mCurrentViewportState;
+    mCurrentPipelineInfo.pRasterizationState = &mCurrentRasterState;
+    mCurrentPipelineInfo.pMultisampleState   = &mCurrentMultisampleState;
+    mCurrentPipelineInfo.pDepthStencilState  = nullptr;
+    mCurrentPipelineInfo.pColorBlendState    = &mCurrentBlendState;
+    mCurrentPipelineInfo.pDynamicState       = nullptr;
+    mCurrentPipelineInfo.layout              = VK_NULL_HANDLE;
+    mCurrentPipelineInfo.renderPass          = VK_NULL_HANDLE;
+    mCurrentPipelineInfo.subpass             = 0;
+    mCurrentPipelineInfo.basePipelineHandle  = VK_NULL_HANDLE;
+    mCurrentPipelineInfo.basePipelineIndex   = 0;
 }
 
 ContextVk::~ContextVk()
 {
     invalidateCurrentPipeline();
 }
 
+void ContextVk::onDestroy(const gl::Context *context)
+{
+    VkDevice device = mRenderer->getDevice();
+
+    mDescriptorPool.destroy(device);
+}
+
 gl::Error ContextVk::initialize()
 {
+    VkDevice device = mRenderer->getDevice();
+
+    VkDescriptorPoolSize poolSizes[2];
+    poolSizes[UniformBufferPool].type            = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
+    poolSizes[UniformBufferPool].descriptorCount = 1024;
+    poolSizes[TexturePool].type                  = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER;
+    poolSizes[TexturePool].descriptorCount       = 1024;
+
+    VkDescriptorPoolCreateInfo descriptorPoolInfo;
+    descriptorPoolInfo.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO;
+    descriptorPoolInfo.pNext = nullptr;
+    descriptorPoolInfo.flags = 0;
+
+    // TODO(jmadill): Pick non-arbitrary max.
+    descriptorPoolInfo.maxSets = 2048;
+
+    // Reserve pools for uniform blocks and textures.
+    descriptorPoolInfo.poolSizeCount = 2;
+    descriptorPoolInfo.pPoolSizes    = poolSizes;
+
+    ANGLE_TRY(mDescriptorPool.init(device, descriptorPoolInfo));
+
     return gl::NoError();
 }
 
-gl::Error ContextVk::flush()
+gl::Error ContextVk::flush(const gl::Context *context)
 {
+    // TODO(jmadill): Flush will need to insert a semaphore for the next flush to wait on.
     UNIMPLEMENTED();
     return gl::InternalError();
 }
 
-gl::Error ContextVk::finish()
+gl::Error ContextVk::finish(const gl::Context *context)
 {
-    UNIMPLEMENTED();
-    return gl::InternalError();
+    return mRenderer->finish(context);
 }
 
 gl::Error ContextVk::initPipeline(const gl::Context *context)
 {
     ASSERT(!mCurrentPipeline.valid());
 
     VkDevice device       = mRenderer->getDevice();
     const auto &state     = mState.getState();
-    const auto &programGL = state.getProgram();
-    const auto &vao       = state.getVertexArray();
-    const auto &attribs   = vao->getVertexAttributes();
-    const auto &bindings  = vao->getVertexBindings();
-    const auto &programVk = GetImplAs<ProgramVk>(programGL);
-    const auto *drawFBO   = state.getDrawFramebuffer();
-    FramebufferVk *vkFBO  = GetImplAs<FramebufferVk>(drawFBO);
-
-    // { vertex, fragment }
-    VkPipelineShaderStageCreateInfo shaderStages[2];
-
-    shaderStages[0].sType               = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO;
-    shaderStages[0].pNext               = nullptr;
-    shaderStages[0].flags               = 0;
-    shaderStages[0].stage               = VK_SHADER_STAGE_VERTEX_BIT;
-    shaderStages[0].module              = programVk->getLinkedVertexModule().getHandle();
-    shaderStages[0].pName               = "main";
-    shaderStages[0].pSpecializationInfo = nullptr;
-
-    shaderStages[1].sType               = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO;
-    shaderStages[1].pNext               = nullptr;
-    shaderStages[1].flags               = 0;
-    shaderStages[1].stage               = VK_SHADER_STAGE_FRAGMENT_BIT;
-    shaderStages[1].module              = programVk->getLinkedFragmentModule().getHandle();
-    shaderStages[1].pName               = "main";
-    shaderStages[1].pSpecializationInfo = nullptr;
+    const gl::VertexArray *vao     = state.getVertexArray();
+    const gl::Framebuffer *drawFBO = state.getDrawFramebuffer();
+    FramebufferVk *vkFBO  = vk::GetImpl(drawFBO);
+    VertexArrayVk *vkVAO  = vk::GetImpl(vao);
 
-    // Process vertex attributes
-    // TODO(jmadill): Caching with dirty bits.
-    std::vector<VkVertexInputBindingDescription> vertexBindings;
-    std::vector<VkVertexInputAttributeDescription> vertexAttribs;
-
-    for (auto attribIndex : programGL->getActiveAttribLocationsMask())
-    {
-        const auto &attrib  = attribs[attribIndex];
-        const auto &binding = bindings[attrib.bindingIndex];
-        if (attrib.enabled)
-        {
-            VkVertexInputBindingDescription bindingDesc;
-            bindingDesc.binding = static_cast<uint32_t>(vertexBindings.size());
-            bindingDesc.stride  = static_cast<uint32_t>(gl::ComputeVertexAttributeTypeSize(attrib));
-            bindingDesc.inputRate = (binding.getDivisor() > 0 ? VK_VERTEX_INPUT_RATE_INSTANCE
-                                                              : VK_VERTEX_INPUT_RATE_VERTEX);
+    // Ensure the attribs and bindings are updated.
+    vkVAO->updateVertexDescriptions(context);
 
-            gl::VertexFormatType vertexFormatType = gl::GetVertexFormatType(attrib);
-
-            VkVertexInputAttributeDescription attribDesc;
-            attribDesc.binding  = bindingDesc.binding;
-            attribDesc.format   = vk::GetNativeVertexFormat(vertexFormatType);
-            attribDesc.location = static_cast<uint32_t>(attribIndex);
-            attribDesc.offset =
-                static_cast<uint32_t>(ComputeVertexAttributeOffset(attrib, binding));
-
-            vertexBindings.push_back(bindingDesc);
-            vertexAttribs.push_back(attribDesc);
-        }
-        else
-        {
-            UNIMPLEMENTED();
-        }
-    }
+    const auto &vertexBindings = vkVAO->getVertexBindingDescs();
+    const auto &vertexAttribs  = vkVAO->getVertexAttribDescs();
 
     // TODO(jmadill): Validate with ASSERT against physical device limits/caps?
-    VkPipelineVertexInputStateCreateInfo vertexInputState;
-    vertexInputState.sType = VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO;
-    vertexInputState.pNext = nullptr;
-    vertexInputState.flags = 0;
-    vertexInputState.vertexBindingDescriptionCount   = static_cast<uint32_t>(vertexBindings.size());
-    vertexInputState.pVertexBindingDescriptions      = vertexBindings.data();
-    vertexInputState.vertexAttributeDescriptionCount = static_cast<uint32_t>(vertexAttribs.size());
-    vertexInputState.pVertexAttributeDescriptions    = vertexAttribs.data();
-
-    VkPipelineInputAssemblyStateCreateInfo inputAssemblyState;
-    inputAssemblyState.sType    = VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO;
-    inputAssemblyState.pNext    = nullptr;
-    inputAssemblyState.flags    = 0;
-    inputAssemblyState.topology = gl_vk::GetPrimitiveTopology(mCurrentDrawMode);
-    inputAssemblyState.primitiveRestartEnable = VK_FALSE;
-
-    const gl::Rectangle &viewportGL = state.getViewport();
-    VkViewport viewportVk;
-    viewportVk.x        = static_cast<float>(viewportGL.x);
-    viewportVk.y        = static_cast<float>(viewportGL.y);
-    viewportVk.width    = static_cast<float>(viewportGL.width);
-    viewportVk.height   = static_cast<float>(viewportGL.height);
-    viewportVk.minDepth = state.getNearPlane();
-    viewportVk.maxDepth = state.getFarPlane();
-
-    // TODO(jmadill): Scissor.
-    VkRect2D scissorVk;
-    scissorVk.offset.x      = viewportGL.x;
-    scissorVk.offset.y      = viewportGL.y;
-    scissorVk.extent.width  = viewportGL.width;
-    scissorVk.extent.height = viewportGL.height;
-
-    VkPipelineViewportStateCreateInfo viewportState;
-    viewportState.sType         = VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO;
-    viewportState.pNext         = nullptr;
-    viewportState.flags         = 0;
-    viewportState.viewportCount = 1;
-    viewportState.pViewports    = &viewportVk;
-    viewportState.scissorCount  = 1;
-    viewportState.pScissors     = &scissorVk;
+    mCurrentVertexInputState.vertexBindingDescriptionCount =
+        static_cast<uint32_t>(vertexBindings.size());
+    mCurrentVertexInputState.pVertexBindingDescriptions = vertexBindings.data();
+    mCurrentVertexInputState.vertexAttributeDescriptionCount =
+        static_cast<uint32_t>(vertexAttribs.size());
+    mCurrentVertexInputState.pVertexAttributeDescriptions = vertexAttribs.data();
 
-    // TODO(jmadill): Extra rasterizer state features.
-    VkPipelineRasterizationStateCreateInfo rasterState;
-    rasterState.sType            = VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO;
-    rasterState.pNext            = nullptr;
-    rasterState.flags            = 0;
-    rasterState.depthClampEnable = VK_FALSE;
-    rasterState.rasterizerDiscardEnable = VK_FALSE;
-    rasterState.polygonMode             = VK_POLYGON_MODE_FILL;
-    rasterState.cullMode                = gl_vk::GetCullMode(state.getRasterizerState());
-    rasterState.frontFace               = gl_vk::GetFrontFace(state.getRasterizerState().frontFace);
-    rasterState.depthBiasEnable         = VK_FALSE;
-    rasterState.depthBiasConstantFactor = 0.0f;
-    rasterState.depthBiasClamp          = 0.0f;
-    rasterState.depthBiasSlopeFactor    = 0.0f;
-    rasterState.lineWidth               = state.getLineWidth();
-
-    // TODO(jmadill): Multisample state.
-    VkPipelineMultisampleStateCreateInfo multisampleState;
-    multisampleState.sType = VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO;
-    multisampleState.pNext = nullptr;
-    multisampleState.flags = 0;
-    multisampleState.rasterizationSamples = VK_SAMPLE_COUNT_1_BIT;
-    multisampleState.sampleShadingEnable  = VK_FALSE;
-    multisampleState.minSampleShading     = 0.0f;
-    multisampleState.pSampleMask          = nullptr;
-    multisampleState.alphaToCoverageEnable = VK_FALSE;
-    multisampleState.alphaToOneEnable      = VK_FALSE;
+    mCurrentInputAssemblyState.topology = gl_vk::GetPrimitiveTopology(mCurrentDrawMode);
 
-    // TODO(jmadill): Depth/stencil state.
-
-    // TODO(jmadill): Blend state/MRT.
-    VkPipelineColorBlendAttachmentState blendAttachmentState;
-    blendAttachmentState.blendEnable         = VK_FALSE;
-    blendAttachmentState.srcColorBlendFactor = VK_BLEND_FACTOR_ONE;
-    blendAttachmentState.dstColorBlendFactor = VK_BLEND_FACTOR_ONE;
-    blendAttachmentState.colorBlendOp        = VK_BLEND_OP_ADD;
-    blendAttachmentState.srcAlphaBlendFactor = VK_BLEND_FACTOR_ONE;
-    blendAttachmentState.dstAlphaBlendFactor = VK_BLEND_FACTOR_ONE;
-    blendAttachmentState.alphaBlendOp        = VK_BLEND_OP_ADD;
-    blendAttachmentState.colorWriteMask = (VK_COLOR_COMPONENT_R_BIT | VK_COLOR_COMPONENT_G_BIT |
-                                           VK_COLOR_COMPONENT_B_BIT | VK_COLOR_COMPONENT_A_BIT);
+    const vk::RenderPassDesc &desc = vkFBO->getRenderPassDesc(context);
 
-    VkPipelineColorBlendStateCreateInfo blendState;
-    blendState.sType             = VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO;
-    blendState.pNext             = 0;
-    blendState.flags             = 0;
-    blendState.logicOpEnable     = VK_FALSE;
-    blendState.logicOp           = VK_LOGIC_OP_CLEAR;
-    blendState.attachmentCount   = 1;
-    blendState.pAttachments      = &blendAttachmentState;
-    blendState.blendConstants[0] = 0.0f;
-    blendState.blendConstants[1] = 0.0f;
-    blendState.blendConstants[2] = 0.0f;
-    blendState.blendConstants[3] = 0.0f;
-
-    // TODO(jmadill): Dynamic state.
     vk::RenderPass *renderPass = nullptr;
-    ANGLE_TRY_RESULT(vkFBO->getRenderPass(context, device), renderPass);
+    ANGLE_TRY(mRenderer->getCompatibleRenderPass(desc, &renderPass));
     ASSERT(renderPass && renderPass->valid());
 
-    vk::PipelineLayout *pipelineLayout = nullptr;
-    ANGLE_TRY_RESULT(programVk->getPipelineLayout(device), pipelineLayout);
-    ASSERT(pipelineLayout && pipelineLayout->valid());
+    const vk::PipelineLayout &pipelineLayout = mRenderer->getGraphicsPipelineLayout();
+    ASSERT(pipelineLayout.valid());
 
-    VkGraphicsPipelineCreateInfo pipelineInfo;
-    pipelineInfo.sType               = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO;
-    pipelineInfo.pNext               = nullptr;
-    pipelineInfo.flags               = 0;
-    pipelineInfo.stageCount          = 2;
-    pipelineInfo.pStages             = shaderStages;
-    pipelineInfo.pVertexInputState   = &vertexInputState;
-    pipelineInfo.pInputAssemblyState = &inputAssemblyState;
-    pipelineInfo.pTessellationState  = nullptr;
-    pipelineInfo.pViewportState      = &viewportState;
-    pipelineInfo.pRasterizationState = &rasterState;
-    pipelineInfo.pMultisampleState   = &multisampleState;
-    pipelineInfo.pDepthStencilState  = nullptr;
-    pipelineInfo.pColorBlendState    = &blendState;
-    pipelineInfo.pDynamicState       = nullptr;
-    pipelineInfo.layout              = pipelineLayout->getHandle();
-    pipelineInfo.renderPass          = renderPass->getHandle();
-    pipelineInfo.subpass             = 0;
-    pipelineInfo.basePipelineHandle  = VK_NULL_HANDLE;
-    pipelineInfo.basePipelineIndex   = 0;
+    mCurrentPipelineInfo.layout     = pipelineLayout.getHandle();
+    mCurrentPipelineInfo.renderPass = renderPass->getHandle();
 
-    vk::Pipeline newPipeline;
-    ANGLE_TRY(newPipeline.initGraphics(device, pipelineInfo));
-
-    mCurrentPipeline.retain(device, std::move(newPipeline));
+    ANGLE_TRY(mCurrentPipeline.initGraphics(device, mCurrentPipelineInfo));
 
     return gl::NoError();
 }
 
-gl::Error ContextVk::drawArrays(const gl::Context *context, GLenum mode, GLint first, GLsizei count)
+gl::Error ContextVk::setupDraw(const gl::Context *context,
+                               GLenum mode,
+                               DrawType drawType,
+                               vk::CommandBuffer **commandBuffer)
 {
     if (mode != mCurrentDrawMode)
     {
         invalidateCurrentPipeline();
         mCurrentDrawMode = mode;
     }
 
     if (!mCurrentPipeline.valid())
     {
         ANGLE_TRY(initPipeline(context));
         ASSERT(mCurrentPipeline.valid());
     }
 
-    VkDevice device       = mRenderer->getDevice();
     const auto &state     = mState.getState();
-    const auto &programGL = state.getProgram();
-    const auto &vao       = state.getVertexArray();
-    const auto &attribs   = vao->getVertexAttributes();
-    const auto &bindings  = vao->getVertexBindings();
+    const gl::Program *programGL = state.getProgram();
+    ProgramVk *programVk  = vk::GetImpl(programGL);
+    const gl::VertexArray *vao   = state.getVertexArray();
+    VertexArrayVk *vkVAO  = vk::GetImpl(vao);
     const auto *drawFBO   = state.getDrawFramebuffer();
-    FramebufferVk *vkFBO  = GetImplAs<FramebufferVk>(drawFBO);
+    FramebufferVk *vkFBO  = vk::GetImpl(drawFBO);
     Serial queueSerial    = mRenderer->getCurrentQueueSerial();
+    uint32_t maxAttrib    = programGL->getState().getMaxActiveAttribLocation();
+
+    // Process vertex attributes. Assume zero offsets for now.
+    // TODO(jmadill): Offset handling.
+    const auto &vertexHandles    = vkVAO->getCurrentArrayBufferHandles();
+    angle::MemoryBuffer *zeroBuf = nullptr;
+    ANGLE_TRY(context->getZeroFilledBuffer(maxAttrib * sizeof(VkDeviceSize), &zeroBuf));
 
-    // Process vertex attributes
-    // TODO(jmadill): Caching with dirty bits.
-    std::vector<VkBuffer> vertexHandles;
-    std::vector<VkDeviceSize> vertexOffsets;
+    // TODO(jmadill): Need to link up the TextureVk to the Secondary CB.
+    vk::CommandBufferNode *renderNode = nullptr;
+    ANGLE_TRY(vkFBO->getRenderNode(context, &renderNode));
 
-    for (auto attribIndex : programGL->getActiveAttribLocationsMask())
+    if (!renderNode->getInsideRenderPassCommands()->valid())
+    {
+        mVertexArrayDirty = true;
+        mTexturesDirty    = true;
+        ANGLE_TRY(renderNode->startRenderPassRecording(mRenderer, commandBuffer));
+    }
+    else
     {
-        const auto &attrib  = attribs[attribIndex];
-        const auto &binding = bindings[attrib.bindingIndex];
-        if (attrib.enabled)
+        *commandBuffer = renderNode->getInsideRenderPassCommands();
+    }
+
+    // Ensure any writes to the VAO buffers are flushed before we read from them.
+    if (mVertexArrayDirty)
+    {
+        mVertexArrayDirty = false;
+        vkVAO->updateDrawDependencies(renderNode, programGL->getActiveAttribLocationsMask(),
+                                      queueSerial, drawType);
+    }
+
+    // Ensure any writes to the textures are flushed before we read from them.
+    if (mTexturesDirty)
+    {
+        mTexturesDirty = false;
+        // TODO(jmadill): Should probably merge this for loop with programVk's descriptor update.
+        const auto &completeTextures = state.getCompleteTextureCache();
+        for (const gl::SamplerBinding &samplerBinding : programGL->getSamplerBindings())
         {
-            // TODO(jmadill): Offset handling.
-            gl::Buffer *bufferGL = binding.getBuffer().get();
-            ASSERT(bufferGL);
-            BufferVk *bufferVk = GetImplAs<BufferVk>(bufferGL);
-            vertexHandles.push_back(bufferVk->getVkBuffer().getHandle());
-            vertexOffsets.push_back(0);
+            ASSERT(!samplerBinding.unreferenced);
+
+            // TODO(jmadill): Sampler arrays
+            ASSERT(samplerBinding.boundTextureUnits.size() == 1);
 
-            bufferVk->setQueueSerial(queueSerial);
-        }
-        else
-        {
-            UNIMPLEMENTED();
+            GLuint textureUnit         = samplerBinding.boundTextureUnits[0];
+            const gl::Texture *texture = completeTextures[textureUnit];
+
+            // TODO(jmadill): Incomplete textures handling.
+            ASSERT(texture);
+
+            TextureVk *textureVk = vk::GetImpl(texture);
+            textureVk->updateDependencies(renderNode, mRenderer->getCurrentQueueSerial());
         }
     }
 
-    vk::CommandBuffer *commandBuffer = nullptr;
-    ANGLE_TRY(mRenderer->getStartedCommandBuffer(&commandBuffer));
-    ANGLE_TRY(vkFBO->ensureInRenderPass(context, device, commandBuffer, queueSerial, state));
+    (*commandBuffer)->bindPipeline(VK_PIPELINE_BIND_POINT_GRAPHICS, mCurrentPipeline);
+    (*commandBuffer)
+        ->bindVertexBuffers(0, maxAttrib, vertexHandles.data(),
+                            reinterpret_cast<const VkDeviceSize *>(zeroBuf->data()));
+
+    // Update the queue serial for the pipeline object.
+    // TODO(jmadill): the queue serial should be bound to the pipeline.
+    updateQueueSerial(queueSerial);
+
+    // TODO(jmadill): Can probably use more dirty bits here.
+    ANGLE_TRY(programVk->updateUniforms(this));
+    programVk->updateTexturesDescriptorSet(this);
 
-    commandBuffer->bindPipeline(VK_PIPELINE_BIND_POINT_GRAPHICS, mCurrentPipeline);
-    // TODO(jmadill): the queue serial should be bound to the pipeline.
-    setQueueSerial(queueSerial);
-    commandBuffer->bindVertexBuffers(0, vertexHandles, vertexOffsets);
+    // Bind the graphics descriptor sets.
+    // TODO(jmadill): Handle multiple command buffers.
+    const auto &descriptorSets = programVk->getDescriptorSets();
+    const gl::RangeUI &usedRange = programVk->getUsedDescriptorSetRange();
+    if (!usedRange.empty())
+    {
+        ASSERT(!descriptorSets.empty());
+        const vk::PipelineLayout &pipelineLayout = mRenderer->getGraphicsPipelineLayout();
+        (*commandBuffer)
+            ->bindDescriptorSets(VK_PIPELINE_BIND_POINT_GRAPHICS, pipelineLayout, usedRange.low(),
+                                 usedRange.length(), &descriptorSets[usedRange.low()], 0, nullptr);
+    }
+
+    return gl::NoError();
+}
+
+gl::Error ContextVk::drawArrays(const gl::Context *context, GLenum mode, GLint first, GLsizei count)
+{
+    vk::CommandBuffer *commandBuffer = nullptr;
+    ANGLE_TRY(setupDraw(context, mode, DrawType::Arrays, &commandBuffer));
     commandBuffer->draw(count, 1, first, 0);
-
     return gl::NoError();
 }
 
 gl::Error ContextVk::drawArraysInstanced(const gl::Context *context,
                                          GLenum mode,
                                          GLint first,
                                          GLsizei count,
                                          GLsizei instanceCount)
@@ -339,18 +425,43 @@ gl::Error ContextVk::drawArraysInstanced
 }
 
 gl::Error ContextVk::drawElements(const gl::Context *context,
                                   GLenum mode,
                                   GLsizei count,
                                   GLenum type,
                                   const void *indices)
 {
-    UNIMPLEMENTED();
-    return gl::InternalError();
+    vk::CommandBuffer *commandBuffer;
+    ANGLE_TRY(setupDraw(context, mode, DrawType::Elements, &commandBuffer));
+
+    if (indices)
+    {
+        // TODO(jmadill): Buffer offsets and immediate data.
+        UNIMPLEMENTED();
+        return gl::InternalError() << "Only zero-offset index buffers are currently implemented.";
+    }
+
+    if (type == GL_UNSIGNED_BYTE)
+    {
+        // TODO(jmadill): Index translation.
+        UNIMPLEMENTED();
+        return gl::InternalError() << "Unsigned byte translation is not yet implemented.";
+    }
+
+    const gl::Buffer *elementArrayBuffer =
+        mState.getState().getVertexArray()->getElementArrayBuffer().get();
+    ASSERT(elementArrayBuffer);
+
+    BufferVk *elementArrayBufferVk = vk::GetImpl(elementArrayBuffer);
+
+    commandBuffer->bindIndexBuffer(elementArrayBufferVk->getVkBuffer(), 0, GetVkIndexType(type));
+    commandBuffer->drawIndexed(count, 1, 0, 0, 0);
+
+    return gl::NoError();
 }
 
 gl::Error ContextVk::drawElementsInstanced(const gl::Context *context,
                                            GLenum mode,
                                            GLsizei count,
                                            GLenum type,
                                            const void *indices,
                                            GLsizei instances)
@@ -370,28 +481,16 @@ gl::Error ContextVk::drawRangeElements(c
     return gl::NoError();
 }
 
 VkDevice ContextVk::getDevice() const
 {
     return mRenderer->getDevice();
 }
 
-vk::Error ContextVk::getStartedCommandBuffer(vk::CommandBuffer **commandBufferOut)
-{
-    return mRenderer->getStartedCommandBuffer(commandBufferOut);
-}
-
-vk::Error ContextVk::submitCommands(vk::CommandBuffer *commandBuffer)
-{
-    setQueueSerial(mRenderer->getCurrentQueueSerial());
-    ANGLE_TRY(mRenderer->submitCommandBuffer(commandBuffer));
-    return vk::NoError();
-}
-
 gl::Error ContextVk::drawArraysIndirect(const gl::Context *context,
                                         GLenum mode,
                                         const void *indirect)
 {
     UNIMPLEMENTED();
     return gl::InternalError() << "DrawArraysIndirect hasn't been implemented for vulkan backend.";
 }
 
@@ -432,23 +531,267 @@ void ContextVk::pushGroupMarker(GLsizei 
     UNIMPLEMENTED();
 }
 
 void ContextVk::popGroupMarker()
 {
     UNIMPLEMENTED();
 }
 
+void ContextVk::pushDebugGroup(GLenum source, GLuint id, GLsizei length, const char *message)
+{
+    UNIMPLEMENTED();
+}
+
+void ContextVk::popDebugGroup()
+{
+    UNIMPLEMENTED();
+}
+
 void ContextVk::syncState(const gl::Context *context, const gl::State::DirtyBits &dirtyBits)
 {
-    // TODO(jmadill): Vulkan dirty bits.
     if (dirtyBits.any())
     {
         invalidateCurrentPipeline();
     }
+
+    const auto &glState = context->getGLState();
+
+    // TODO(jmadill): Full dirty bits implementation.
+    bool dirtyTextures = false;
+
+    for (auto dirtyBit : dirtyBits)
+    {
+        switch (dirtyBit)
+        {
+            case gl::State::DIRTY_BIT_SCISSOR_TEST_ENABLED:
+                WARN() << "DIRTY_BIT_SCISSOR_TEST_ENABLED unimplemented";
+                break;
+            case gl::State::DIRTY_BIT_SCISSOR:
+                WARN() << "DIRTY_BIT_SCISSOR unimplemented";
+                break;
+            case gl::State::DIRTY_BIT_VIEWPORT:
+            {
+                const gl::Rectangle &viewportGL = glState.getViewport();
+                mCurrentViewportVk.x            = static_cast<float>(viewportGL.x);
+                mCurrentViewportVk.y            = static_cast<float>(viewportGL.y);
+                mCurrentViewportVk.width        = static_cast<float>(viewportGL.width);
+                mCurrentViewportVk.height       = static_cast<float>(viewportGL.height);
+                mCurrentViewportVk.minDepth     = glState.getNearPlane();
+                mCurrentViewportVk.maxDepth     = glState.getFarPlane();
+
+                // TODO(jmadill): Scissor.
+                mCurrentScissorVk.offset.x      = viewportGL.x;
+                mCurrentScissorVk.offset.y      = viewportGL.y;
+                mCurrentScissorVk.extent.width  = viewportGL.width;
+                mCurrentScissorVk.extent.height = viewportGL.height;
+                break;
+            }
+            case gl::State::DIRTY_BIT_DEPTH_RANGE:
+                WARN() << "DIRTY_BIT_DEPTH_RANGE unimplemented";
+                break;
+            case gl::State::DIRTY_BIT_BLEND_ENABLED:
+                WARN() << "DIRTY_BIT_BLEND_ENABLED unimplemented";
+                break;
+            case gl::State::DIRTY_BIT_BLEND_COLOR:
+                WARN() << "DIRTY_BIT_BLEND_COLOR unimplemented";
+                break;
+            case gl::State::DIRTY_BIT_BLEND_FUNCS:
+                WARN() << "DIRTY_BIT_BLEND_FUNCS unimplemented";
+                break;
+            case gl::State::DIRTY_BIT_BLEND_EQUATIONS:
+                WARN() << "DIRTY_BIT_BLEND_EQUATIONS unimplemented";
+                break;
+            case gl::State::DIRTY_BIT_COLOR_MASK:
+                WARN() << "DIRTY_BIT_COLOR_MASK unimplemented";
+                break;
+            case gl::State::DIRTY_BIT_SAMPLE_ALPHA_TO_COVERAGE_ENABLED:
+                WARN() << "DIRTY_BIT_SAMPLE_ALPHA_TO_COVERAGE_ENABLED unimplemented";
+                break;
+            case gl::State::DIRTY_BIT_SAMPLE_COVERAGE_ENABLED:
+                WARN() << "DIRTY_BIT_SAMPLE_COVERAGE_ENABLED unimplemented";
+                break;
+            case gl::State::DIRTY_BIT_SAMPLE_COVERAGE:
+                WARN() << "DIRTY_BIT_SAMPLE_COVERAGE unimplemented";
+                break;
+            case gl::State::DIRTY_BIT_SAMPLE_MASK_ENABLED:
+                WARN() << "DIRTY_BIT_SAMPLE_MASK_ENABLED unimplemented";
+                break;
+            case gl::State::DIRTY_BIT_SAMPLE_MASK:
+                WARN() << "DIRTY_BIT_SAMPLE_MASK unimplemented";
+                break;
+            case gl::State::DIRTY_BIT_DEPTH_TEST_ENABLED:
+                WARN() << "DIRTY_BIT_DEPTH_TEST_ENABLED unimplemented";
+                break;
+            case gl::State::DIRTY_BIT_DEPTH_FUNC:
+                WARN() << "DIRTY_BIT_DEPTH_FUNC unimplemented";
+                break;
+            case gl::State::DIRTY_BIT_DEPTH_MASK:
+                WARN() << "DIRTY_BIT_DEPTH_MASK unimplemented";
+                break;
+            case gl::State::DIRTY_BIT_STENCIL_TEST_ENABLED:
+                WARN() << "DIRTY_BIT_STENCIL_TEST_ENABLED unimplemented";
+                break;
+            case gl::State::DIRTY_BIT_STENCIL_FUNCS_FRONT:
+                WARN() << "DIRTY_BIT_STENCIL_FUNCS_FRONT unimplemented";
+                break;
+            case gl::State::DIRTY_BIT_STENCIL_FUNCS_BACK:
+                WARN() << "DIRTY_BIT_STENCIL_FUNCS_BACK unimplemented";
+                break;
+            case gl::State::DIRTY_BIT_STENCIL_OPS_FRONT:
+                WARN() << "DIRTY_BIT_STENCIL_OPS_FRONT unimplemented";
+                break;
+            case gl::State::DIRTY_BIT_STENCIL_OPS_BACK:
+                WARN() << "DIRTY_BIT_STENCIL_OPS_BACK unimplemented";
+                break;
+            case gl::State::DIRTY_BIT_STENCIL_WRITEMASK_FRONT:
+                WARN() << "DIRTY_BIT_STENCIL_WRITEMASK_FRONT unimplemented";
+                break;
+            case gl::State::DIRTY_BIT_STENCIL_WRITEMASK_BACK:
+                WARN() << "DIRTY_BIT_STENCIL_WRITEMASK_BACK unimplemented";
+                break;
+            case gl::State::DIRTY_BIT_CULL_FACE_ENABLED:
+            case gl::State::DIRTY_BIT_CULL_FACE:
+                mCurrentRasterState.cullMode = gl_vk::GetCullMode(glState.getRasterizerState());
+                break;
+            case gl::State::DIRTY_BIT_FRONT_FACE:
+                mCurrentRasterState.frontFace =
+                    gl_vk::GetFrontFace(glState.getRasterizerState().frontFace);
+                break;
+            case gl::State::DIRTY_BIT_POLYGON_OFFSET_FILL_ENABLED:
+                WARN() << "DIRTY_BIT_POLYGON_OFFSET_FILL_ENABLED unimplemented";
+                break;
+            case gl::State::DIRTY_BIT_POLYGON_OFFSET:
+                WARN() << "DIRTY_BIT_POLYGON_OFFSET unimplemented";
+                break;
+            case gl::State::DIRTY_BIT_RASTERIZER_DISCARD_ENABLED:
+                WARN() << "DIRTY_BIT_RASTERIZER_DISCARD_ENABLED unimplemented";
+                break;
+            case gl::State::DIRTY_BIT_LINE_WIDTH:
+                mCurrentRasterState.lineWidth = glState.getLineWidth();
+                break;
+            case gl::State::DIRTY_BIT_PRIMITIVE_RESTART_ENABLED:
+                WARN() << "DIRTY_BIT_PRIMITIVE_RESTART_ENABLED unimplemented";
+                break;
+            case gl::State::DIRTY_BIT_CLEAR_COLOR:
+                WARN() << "DIRTY_BIT_CLEAR_COLOR unimplemented";
+                break;
+            case gl::State::DIRTY_BIT_CLEAR_DEPTH:
+                WARN() << "DIRTY_BIT_CLEAR_DEPTH unimplemented";
+                break;
+            case gl::State::DIRTY_BIT_CLEAR_STENCIL:
+                WARN() << "DIRTY_BIT_CLEAR_STENCIL unimplemented";
+                break;
+            case gl::State::DIRTY_BIT_UNPACK_STATE:
+                WARN() << "DIRTY_BIT_UNPACK_STATE unimplemented";
+                break;
+            case gl::State::DIRTY_BIT_UNPACK_BUFFER_BINDING:
+                WARN() << "DIRTY_BIT_UNPACK_BUFFER_BINDING unimplemented";
+                break;
+            case gl::State::DIRTY_BIT_PACK_STATE:
+                WARN() << "DIRTY_BIT_PACK_STATE unimplemented";
+                break;
+            case gl::State::DIRTY_BIT_PACK_BUFFER_BINDING:
+                WARN() << "DIRTY_BIT_PACK_BUFFER_BINDING unimplemented";
+                break;
+            case gl::State::DIRTY_BIT_DITHER_ENABLED:
+                WARN() << "DIRTY_BIT_DITHER_ENABLED unimplemented";
+                break;
+            case gl::State::DIRTY_BIT_GENERATE_MIPMAP_HINT:
+                WARN() << "DIRTY_BIT_GENERATE_MIPMAP_HINT unimplemented";
+                break;
+            case gl::State::DIRTY_BIT_SHADER_DERIVATIVE_HINT:
+                WARN() << "DIRTY_BIT_SHADER_DERIVATIVE_HINT unimplemented";
+                break;
+            case gl::State::DIRTY_BIT_READ_FRAMEBUFFER_BINDING:
+                WARN() << "DIRTY_BIT_READ_FRAMEBUFFER_BINDING unimplemented";
+                break;
+            case gl::State::DIRTY_BIT_DRAW_FRAMEBUFFER_BINDING:
+                WARN() << "DIRTY_BIT_DRAW_FRAMEBUFFER_BINDING unimplemented";
+                break;
+            case gl::State::DIRTY_BIT_RENDERBUFFER_BINDING:
+                WARN() << "DIRTY_BIT_RENDERBUFFER_BINDING unimplemented";
+                break;
+            case gl::State::DIRTY_BIT_VERTEX_ARRAY_BINDING:
+                mVertexArrayDirty = true;
+                break;
+            case gl::State::DIRTY_BIT_DRAW_INDIRECT_BUFFER_BINDING:
+                WARN() << "DIRTY_BIT_DRAW_INDIRECT_BUFFER_BINDING unimplemented";
+                break;
+            case gl::State::DIRTY_BIT_DISPATCH_INDIRECT_BUFFER_BINDING:
+                WARN() << "DIRTY_BIT_DISPATCH_INDIRECT_BUFFER_BINDING unimplemented";
+                break;
+            case gl::State::DIRTY_BIT_PROGRAM_BINDING:
+                WARN() << "DIRTY_BIT_PROGRAM_BINDING unimplemented";
+                break;
+            case gl::State::DIRTY_BIT_PROGRAM_EXECUTABLE:
+            {
+                // { vertex, fragment }
+                ProgramVk *programVk           = vk::GetImpl(glState.getProgram());
+                mCurrentShaderStages[0].module = programVk->getLinkedVertexModule().getHandle();
+                mCurrentShaderStages[1].module = programVk->getLinkedFragmentModule().getHandle();
+
+                // Also invalidate the vertex descriptions cache in the Vertex Array.
+                VertexArrayVk *vaoVk = vk::GetImpl(glState.getVertexArray());
+                vaoVk->invalidateVertexDescriptions();
+
+                dirtyTextures = true;
+                break;
+            }
+            case gl::State::DIRTY_BIT_TEXTURE_BINDINGS:
+                dirtyTextures = true;
+                break;
+            case gl::State::DIRTY_BIT_SAMPLER_BINDINGS:
+                dirtyTextures = true;
+                break;
+            case gl::State::DIRTY_BIT_TRANSFORM_FEEDBACK_BINDING:
+                WARN() << "DIRTY_BIT_TRANSFORM_FEEDBACK_BINDING unimplemented";
+                break;
+            case gl::State::DIRTY_BIT_SHADER_STORAGE_BUFFER_BINDING:
+                WARN() << "DIRTY_BIT_SHADER_STORAGE_BUFFER_BINDING unimplemented";
+                break;
+            case gl::State::DIRTY_BIT_UNIFORM_BUFFER_BINDINGS:
+                WARN() << "DIRTY_BIT_UNIFORM_BUFFER_BINDINGS unimplemented";
+                break;
+            case gl::State::DIRTY_BIT_MULTISAMPLING:
+                WARN() << "DIRTY_BIT_MULTISAMPLING unimplemented";
+                break;
+            case gl::State::DIRTY_BIT_SAMPLE_ALPHA_TO_ONE:
+                WARN() << "DIRTY_BIT_SAMPLE_ALPHA_TO_ONE unimplemented";
+                break;
+            case gl::State::DIRTY_BIT_COVERAGE_MODULATION:
+                WARN() << "DIRTY_BIT_COVERAGE_MODULATION unimplemented";
+                break;
+            case gl::State::DIRTY_BIT_PATH_RENDERING_MATRIX_MV:
+                WARN() << "DIRTY_BIT_PATH_RENDERING_MATRIX_MV unimplemented";
+                break;
+            case gl::State::DIRTY_BIT_PATH_RENDERING_MATRIX_PROJ:
+                WARN() << "DIRTY_BIT_PATH_RENDERING_MATRIX_PROJ unimplemented";
+                break;
+            case gl::State::DIRTY_BIT_PATH_RENDERING_STENCIL_STATE:
+                WARN() << "DIRTY_BIT_PATH_RENDERING_STENCIL_STATE unimplemented";
+                break;
+            case gl::State::DIRTY_BIT_FRAMEBUFFER_SRGB:
+                WARN() << "DIRTY_BIT_FRAMEBUFFER_SRGB unimplemented";
+                break;
+            case gl::State::DIRTY_BIT_CURRENT_VALUES:
+                WARN() << "DIRTY_BIT_CURRENT_VALUES unimplemented";
+                break;
+            default:
+                UNREACHABLE();
+                break;
+        }
+    }
+
+    if (dirtyTextures)
+    {
+        ProgramVk *programVk = vk::GetImpl(glState.getProgram());
+        programVk->invalidateTextures();
+        mTexturesDirty = true;
+    }
 }
 
 GLint ContextVk::getGPUDisjoint()
 {
     UNIMPLEMENTED();
     return GLint();
 }
 
@@ -555,21 +898,51 @@ ProgramPipelineImpl *ContextVk::createPr
 std::vector<PathImpl *> ContextVk::createPaths(GLsizei)
 {
     return std::vector<PathImpl *>();
 }
 
 // TODO(jmadill): Use pipeline cache.
 void ContextVk::invalidateCurrentPipeline()
 {
-    mRenderer->enqueueGarbageOrDeleteNow(*this, mCurrentPipeline);
+    mRenderer->releaseResource(*this, &mCurrentPipeline);
+}
+
+void ContextVk::onVertexArrayChange()
+{
+    // TODO(jmadill): Does not handle dependent state changes.
+    mVertexArrayDirty = true;
+    invalidateCurrentPipeline();
 }
 
 gl::Error ContextVk::dispatchCompute(const gl::Context *context,
                                      GLuint numGroupsX,
                                      GLuint numGroupsY,
                                      GLuint numGroupsZ)
 {
     UNIMPLEMENTED();
     return gl::InternalError();
 }
 
+gl::Error ContextVk::dispatchComputeIndirect(const gl::Context *context, GLintptr indirect)
+{
+    UNIMPLEMENTED();
+    return gl::InternalError();
+}
+
+gl::Error ContextVk::memoryBarrier(const gl::Context *context, GLbitfield barriers)
+{
+    UNIMPLEMENTED();
+    return gl::InternalError();
+}
+
+gl::Error ContextVk::memoryBarrierByRegion(const gl::Context *context, GLbitfield barriers)
+{
+    UNIMPLEMENTED();
+    return gl::InternalError();
+}
+
+vk::DescriptorPool *ContextVk::getDescriptorPool()
+{
+    return &mDescriptorPool;
+}
+
 }  // namespace rx
--- a/gfx/angle/src/libANGLE/renderer/vulkan/ContextVk.h
+++ b/gfx/angle/src/libANGLE/renderer/vulkan/ContextVk.h
@@ -22,19 +22,21 @@ class RendererVk;
 class ContextVk : public ContextImpl, public ResourceVk
 {
   public:
     ContextVk(const gl::ContextState &state, RendererVk *renderer);
     ~ContextVk() override;
 
     gl::Error initialize() override;
 
+    void onDestroy(const gl::Context *context) override;
+
     // Flush and finish.
-    gl::Error flush() override;
-    gl::Error finish() override;
+    gl::Error flush(const gl::Context *context) override;
+    gl::Error finish(const gl::Context *context) override;
 
     // Drawing methods.
     gl::Error drawArrays(const gl::Context *context,
                          GLenum mode,
                          GLint first,
                          GLsizei count) override;
     gl::Error drawArraysInstanced(const gl::Context *context,
                                   GLenum mode,
@@ -70,21 +72,25 @@ class ContextVk : public ContextImpl, pu
 
     // Device loss
     GLenum getResetStatus() override;
 
     // Vendor and description strings.
     std::string getVendorString() const override;
     std::string getRendererDescription() const override;
 
-    // Debug markers.
+    // EXT_debug_marker
     void insertEventMarker(GLsizei length, const char *marker) override;
     void pushGroupMarker(GLsizei length, const char *marker) override;
     void popGroupMarker() override;
 
+    // KHR_debug
+    void pushDebugGroup(GLenum source, GLuint id, GLsizei length, const char *message) override;
+    void popDebugGroup() override;
+
     // State sync with dirty bits.
     void syncState(const gl::Context *context, const gl::State::DirtyBits &dirtyBits) override;
 
     // Disjoint timer queries
     GLint getGPUDisjoint() override;
     GLint64 getTimestamp() override;
 
     // Context switching
@@ -129,33 +135,66 @@ class ContextVk : public ContextImpl, pu
     SamplerImpl *createSampler(const gl::SamplerState &state) override;
 
     // Program Pipeline object creation
     ProgramPipelineImpl *createProgramPipeline(const gl::ProgramPipelineState &data) override;
 
     // Path object creation
     std::vector<PathImpl *> createPaths(GLsizei) override;
 
+    gl::Error dispatchCompute(const gl::Context *context,
+                              GLuint numGroupsX,
+                              GLuint numGroupsY,
+                              GLuint numGroupsZ) override;
+    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;
+
     VkDevice getDevice() const;
-    vk::Error getStartedCommandBuffer(vk::CommandBuffer **commandBufferOut);
-    vk::Error submitCommands(vk::CommandBuffer *commandBuffer);
-
     RendererVk *getRenderer() { return mRenderer; }
 
     // TODO(jmadill): Use pipeline cache.
     void invalidateCurrentPipeline();
 
-    gl::Error dispatchCompute(const gl::Context *context,
-                              GLuint numGroupsX,
-                              GLuint numGroupsY,
-                              GLuint numGroupsZ) override;
+    void onVertexArrayChange();
+
+    vk::DescriptorPool *getDescriptorPool();
 
   private:
     gl::Error initPipeline(const gl::Context *context);
+    gl::Error setupDraw(const gl::Context *context,
+                        GLenum mode,
+                        DrawType drawType,
+                        vk::CommandBuffer **commandBuffer);
 
     RendererVk *mRenderer;
     vk::Pipeline mCurrentPipeline;
     GLenum mCurrentDrawMode;
+
+    // Keep CreateInfo structures cached so that we can quickly update them when creating
+    // updated pipelines. When we move to a pipeline cache, we will want to use a more compact
+    // structure that we can use to query the pipeline cache in the Renderer.
+    // TODO(jmadill): Update this when we move to a pipeline cache.
+    VkPipelineShaderStageCreateInfo mCurrentShaderStages[2];
+    VkPipelineVertexInputStateCreateInfo mCurrentVertexInputState;
+    VkPipelineInputAssemblyStateCreateInfo mCurrentInputAssemblyState;
+    VkViewport mCurrentViewportVk;
+    VkRect2D mCurrentScissorVk;
+    VkPipelineViewportStateCreateInfo mCurrentViewportState;
+    VkPipelineRasterizationStateCreateInfo mCurrentRasterState;
+    VkPipelineMultisampleStateCreateInfo mCurrentMultisampleState;
+    VkPipelineColorBlendAttachmentState mCurrentBlendAttachmentState;
+    VkPipelineColorBlendStateCreateInfo mCurrentBlendState;
+    VkGraphicsPipelineCreateInfo mCurrentPipelineInfo;
+
+    // The descriptor pool is externally sychronized, so cannot be accessed from different threads
+    // simulataneously. Hence, we keep it in the ContextVk instead of the RendererVk.
+    vk::DescriptorPool mDescriptorPool;
+
+    // Triggers adding dependencies to the command graph.
+    bool mVertexArrayDirty;
+    bool mTexturesDirty;
 };
 
 }  // namespace rx
 
 #endif  // LIBANGLE_RENDERER_VULKAN_CONTEXTVK_H_
--- a/gfx/angle/src/libANGLE/renderer/vulkan/DisplayVk.cpp
+++ b/gfx/angle/src/libANGLE/renderer/vulkan/DisplayVk.cpp
@@ -178,17 +178,17 @@ ImageImpl *DisplayVk::createImage(const 
     return static_cast<ImageImpl *>(0);
 }
 
 ContextImpl *DisplayVk::createContext(const gl::ContextState &state)
 {
     return new ContextVk(state, mRenderer.get());
 }
 
-StreamProducerImpl *DisplayVk::createStreamProducerD3DTextureNV12(
+StreamProducerImpl *DisplayVk::createStreamProducerD3DTexture(
     egl::Stream::ConsumerType consumerType,
     const egl::AttributeMap &attribs)
 {
     UNIMPLEMENTED();
     return static_cast<StreamProducerImpl *>(0);
 }
 
 gl::Version DisplayVk::getMaxSupportedESVersion() const
--- a/gfx/angle/src/libANGLE/renderer/vulkan/DisplayVk.h
+++ b/gfx/angle/src/libANGLE/renderer/vulkan/DisplayVk.h
@@ -55,19 +55,18 @@ class DisplayVk : public DisplayImpl
                                      const egl::AttributeMap &attribs) override;
 
     ImageImpl *createImage(const egl::ImageState &state,
                            EGLenum target,
                            const egl::AttributeMap &attribs) override;
 
     ContextImpl *createContext(const gl::ContextState &state) override;
 
-    StreamProducerImpl *createStreamProducerD3DTextureNV12(
-        egl::Stream::ConsumerType consumerType,
-        const egl::AttributeMap &attribs) override;
+    StreamProducerImpl *createStreamProducerD3DTexture(egl::Stream::ConsumerType consumerType,
+                                                       const egl::AttributeMap &attribs) override;
     gl::Version getMaxSupportedESVersion() const override;
 
     RendererVk *getRenderer() const { return mRenderer.get(); }
 
     virtual const char *getWSIName() const = 0;
 
   private:
     virtual SurfaceImpl *createWindowSurfaceVk(const egl::SurfaceState &state,
--- a/gfx/angle/src/libANGLE/renderer/vulkan/FramebufferVk.cpp
+++ b/gfx/angle/src/libANGLE/renderer/vulkan/FramebufferVk.cpp
@@ -13,63 +13,39 @@
 #include <array>
 
 #include "common/debug.h"
 #include "image_util/imageformats.h"
 #include "libANGLE/Context.h"
 #include "libANGLE/Display.h"
 #include "libANGLE/formatutils.h"
 #include "libANGLE/renderer/renderer_utils.h"
+#include "libANGLE/renderer/vulkan/CommandBufferNode.h"
 #include "libANGLE/renderer/vulkan/ContextVk.h"
 #include "libANGLE/renderer/vulkan/DisplayVk.h"
 #include "libANGLE/renderer/vulkan/RenderTargetVk.h"
 #include "libANGLE/renderer/vulkan/RendererVk.h"
 #include "libANGLE/renderer/vulkan/SurfaceVk.h"
 #include "libANGLE/renderer/vulkan/formatutilsvk.h"
 
 namespace rx
 {
 
 namespace
 {
-
 gl::ErrorOrResult<const gl::InternalFormat *> GetReadAttachmentInfo(
     const gl::Context *context,
     const gl::FramebufferAttachment *readAttachment)
 {
     RenderTargetVk *renderTarget = nullptr;
     ANGLE_TRY(readAttachment->getRenderTarget(context, &renderTarget));
 
-    GLenum implFormat = renderTarget->format->format().fboImplementationInternalFormat;
+    GLenum implFormat = renderTarget->format->textureFormat().fboImplementationInternalFormat;
     return &gl::GetSizedInternalFormatInfo(implFormat);
 }
-
-VkSampleCountFlagBits ConvertSamples(GLint sampleCount)
-{
-    switch (sampleCount)
-    {
-        case 0:
-        case 1:
-            return VK_SAMPLE_COUNT_1_BIT;
-        case 2:
-            return VK_SAMPLE_COUNT_2_BIT;
-        case 4:
-            return VK_SAMPLE_COUNT_4_BIT;
-        case 8:
-            return VK_SAMPLE_COUNT_8_BIT;
-        case 16:
-            return VK_SAMPLE_COUNT_16_BIT;
-        case 32:
-            return VK_SAMPLE_COUNT_32_BIT;
-        default:
-            UNREACHABLE();
-            return VK_SAMPLE_COUNT_FLAG_BITS_MAX_ENUM;
-    }
-}
-
 }  // anonymous namespace
 
 // static
 FramebufferVk *FramebufferVk::CreateUserFBO(const gl::FramebufferState &state)
 {
     return new FramebufferVk(state);
 }
 
@@ -78,50 +54,46 @@ FramebufferVk *FramebufferVk::CreateDefa
                                                WindowSurfaceVk *backbuffer)
 {
     return new FramebufferVk(state, backbuffer);
 }
 
 FramebufferVk::FramebufferVk(const gl::FramebufferState &state)
     : FramebufferImpl(state),
       mBackbuffer(nullptr),
-      mRenderPass(),
+      mRenderPassDesc(),
       mFramebuffer(),
-      mInRenderPass(false)
+      mLastRenderNodeSerial()
 {
 }
 
 FramebufferVk::FramebufferVk(const gl::FramebufferState &state, WindowSurfaceVk *backbuffer)
     : FramebufferImpl(state),
       mBackbuffer(backbuffer),
-      mRenderPass(),
+      mRenderPassDesc(),
       mFramebuffer(),
-      mInRenderPass(false)
+      mLastRenderNodeSerial()
 {
 }
 
 FramebufferVk::~FramebufferVk()
 {
 }
 
 void FramebufferVk::destroy(const gl::Context *context)
 {
-    ASSERT(!mInRenderPass);
+    RendererVk *renderer = vk::GetImpl(context)->getRenderer();
 
-    VkDevice device = GetImplAs<ContextVk>(context)->getDevice();
-
-    mRenderPass.destroy(device);
-    mFramebuffer.destroy(device);
+    renderer->releaseResource(*this, &mFramebuffer);
 }
 
 void FramebufferVk::destroyDefault(const egl::Display *display)
 {
-    VkDevice device = GetImplAs<DisplayVk>(display)->getRenderer()->getDevice();
+    VkDevice device = vk::GetImpl(display)->getRenderer()->getDevice();
 
-    mRenderPass.destroy(device);
     mFramebuffer.destroy(device);
 }
 
 gl::Error FramebufferVk::discard(const gl::Context *context,
                                  size_t count,
                                  const GLenum *attachments)
 {
     UNIMPLEMENTED();
@@ -142,18 +114,16 @@ gl::Error FramebufferVk::invalidateSub(c
                                        const gl::Rectangle &area)
 {
     UNIMPLEMENTED();
     return gl::InternalError();
 }
 
 gl::Error FramebufferVk::clear(const gl::Context *context, GLbitfield mask)
 {
-    ContextVk *contextVk = GetImplAs<ContextVk>(context);
-
     if (mState.getDepthAttachment() && (mask & GL_DEPTH_BUFFER_BIT) != 0)
     {
         // TODO(jmadill): Depth clear
         UNIMPLEMENTED();
     }
 
     if (mState.getStencilAttachment() && (mask & GL_STENCIL_BUFFER_BIT) != 0)
     {
@@ -175,27 +145,32 @@ gl::Error FramebufferVk::clear(const gl:
     clearColorValue.float32[3] = clearColor.alpha;
 
     // TODO(jmadill): Scissored clears.
     const auto *attachment = mState.getFirstNonNullAttachment();
     ASSERT(attachment && attachment->isAttached());
     const auto &size = attachment->getSize();
     const gl::Rectangle renderArea(0, 0, size.width, size.height);
 
+    RendererVk *renderer = vk::GetImpl(context)->getRenderer();
+
     vk::CommandBuffer *commandBuffer = nullptr;
-    ANGLE_TRY(contextVk->getStartedCommandBuffer(&commandBuffer));
+    ANGLE_TRY(recordWriteCommands(renderer, &commandBuffer));
 
     for (const auto &colorAttachment : mState.getColorAttachments())
     {
         if (colorAttachment.isAttached())
         {
             RenderTargetVk *renderTarget = nullptr;
             ANGLE_TRY(colorAttachment.getRenderTarget(context, &renderTarget));
-            renderTarget->image->changeLayoutTop(
-                VK_IMAGE_ASPECT_COLOR_BIT, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, commandBuffer);
+
+            renderTarget->image->changeLayoutWithStages(
+                VK_IMAGE_ASPECT_COLOR_BIT, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
+                VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, commandBuffer);
+
             commandBuffer->clearSingleColorImage(*renderTarget->image, clearColorValue);
         }
     }
 
     return gl::NoError();
 }
 
 gl::Error FramebufferVk::clearBufferfv(const gl::Context *context,
@@ -271,369 +246,294 @@ gl::Error FramebufferVk::readPixels(cons
 {
     const auto &glState         = context->getGLState();
     const auto *readFramebuffer = glState.getReadFramebuffer();
     const auto *readAttachment  = readFramebuffer->getReadColorbuffer();
 
     RenderTargetVk *renderTarget = nullptr;
     ANGLE_TRY(readAttachment->getRenderTarget(context, &renderTarget));
 
-    ContextVk *contextVk = GetImplAs<ContextVk>(context);
+    ContextVk *contextVk = vk::GetImpl(context);
     RendererVk *renderer = contextVk->getRenderer();
     VkDevice device      = renderer->getDevice();
 
     vk::Image *readImage = renderTarget->image;
     vk::StagingImage stagingImage;
     ANGLE_TRY(renderer->createStagingImage(TextureDimension::TEX_2D, *renderTarget->format,
-                                           renderTarget->extents, &stagingImage));
+                                           renderTarget->extents, vk::StagingUsage::Read,
+                                           &stagingImage));
 
     vk::CommandBuffer *commandBuffer = nullptr;
-    ANGLE_TRY(contextVk->getStartedCommandBuffer(&commandBuffer));
-
-    // End render pass if we're in one.
-    endRenderPass(commandBuffer);
+    ANGLE_TRY(recordWriteCommands(renderer, &commandBuffer));
 
     stagingImage.getImage().changeLayoutTop(VK_IMAGE_ASPECT_COLOR_BIT, VK_IMAGE_LAYOUT_GENERAL,
                                             commandBuffer);
 
-    gl::Box copyRegion;
-    copyRegion.x      = area.x;
-    copyRegion.y      = area.y;
-    copyRegion.z      = 0;
-    copyRegion.width  = area.width;
-    copyRegion.height = area.height;
-    copyRegion.depth  = 1;
+    readImage->changeLayoutWithStages(
+        VK_IMAGE_ASPECT_COLOR_BIT, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
+        VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, commandBuffer);
 
-    readImage->changeLayoutTop(VK_IMAGE_ASPECT_COLOR_BIT, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
-                               commandBuffer);
-    commandBuffer->copySingleImage(*readImage, stagingImage.getImage(), copyRegion,
-                                   VK_IMAGE_ASPECT_COLOR_BIT);
+    VkImageCopy region;
+    region.srcSubresource.aspectMask     = VK_IMAGE_ASPECT_COLOR_BIT;
+    region.srcSubresource.mipLevel       = 0;
+    region.srcSubresource.baseArrayLayer = 0;
+    region.srcSubresource.layerCount     = 1;
+    region.srcOffset.x                   = area.x;
+    region.srcOffset.y                   = area.y;
+    region.srcOffset.z                   = 0;
+    region.dstSubresource.aspectMask     = VK_IMAGE_ASPECT_COLOR_BIT;
+    region.dstSubresource.mipLevel       = 0;
+    region.dstSubresource.baseArrayLayer = 0;
+    region.dstSubresource.layerCount     = 1;
+    region.dstOffset.x                   = 0;
+    region.dstOffset.y                   = 0;
+    region.dstOffset.z                   = 0;
+    region.extent.width                  = area.width;
+    region.extent.height                 = area.height;
+    region.extent.depth                  = 1;
 
-    ANGLE_TRY(renderer->submitAndFinishCommandBuffer(commandBuffer));
+    commandBuffer->copyImage(*readImage, stagingImage.getImage(), 1, &region);
+
+    // Triggers a full finish.
+    // TODO(jmadill): Don't block on asynchronous readback.
+    ANGLE_TRY(renderer->finish(context));
 
     // TODO(jmadill): parameters
     uint8_t *mapPointer = nullptr;
     ANGLE_TRY(
         stagingImage.getDeviceMemory().map(device, 0, stagingImage.getSize(), 0, &mapPointer));
 
-    const auto &angleFormat = renderTarget->format->format();
+    const auto &angleFormat = renderTarget->format->textureFormat();
 
     // TODO(jmadill): Use pixel bytes from the ANGLE format directly.
     const auto &glFormat = gl::GetSizedInternalFormatInfo(angleFormat.glInternalFormat);
     int inputPitch       = glFormat.pixelBytes * area.width;
 
     PackPixelsParams params;
     params.area        = area;
     params.format      = format;
     params.type        = type;
     params.outputPitch = inputPitch;
-    params.pack.copyFrom(context, glState.getPackState());
+    params.packBuffer  = glState.getTargetBuffer(gl::BufferBinding::PixelPack);
+    params.pack        = glState.getPackState();
 
     PackPixels(params, angleFormat, inputPitch, mapPointer, reinterpret_cast<uint8_t *>(pixels));
 
     stagingImage.getDeviceMemory().unmap(device);
-    renderer->enqueueGarbage(renderer->getCurrentQueueSerial(), std::move(stagingImage));
-
-    stagingImage.getImage().destroy(renderer->getDevice());
-
-    stagingImage.destroy(device);
+    renderer->releaseObject(renderer->getCurrentQueueSerial(), &stagingImage);
 
     return vk::NoError();
 }
 
 gl::Error FramebufferVk::blit(const gl::Context *context,
                               const gl::Rectangle &sourceArea,
                               const gl::Rectangle &destArea,
                               GLbitfield mask,
                               GLenum filter)
 {
     UNIMPLEMENTED();
     return gl::InternalError();
 }
 
-bool FramebufferVk::checkStatus() const
+bool FramebufferVk::checkStatus(const gl::Context *context) const
 {
-    UNIMPLEMENTED();
-    return bool();
+    return true;
 }
 
 void FramebufferVk::syncState(const gl::Context *context,
                               const gl::Framebuffer::DirtyBits &dirtyBits)
 {
-    auto contextVk = GetImplAs<ContextVk>(context);
+    ContextVk *contextVk = vk::GetImpl(context);
+    RendererVk *renderer = contextVk->getRenderer();
 
     ASSERT(dirtyBits.any());
 
     // TODO(jmadill): Smarter update.
-    mRenderPass.destroy(contextVk->getDevice());
-    mFramebuffer.destroy(contextVk->getDevice());
+    mRenderPassDesc.reset();
+    renderer->releaseResource(*this, &mFramebuffer);
+
+    // Trigger a new set of secondary commands next time we render to this FBO,.
+    mLastRenderNodeSerial = Serial();
 
     // TODO(jmadill): Use pipeline cache.
     contextVk->invalidateCurrentPipeline();
 }
 
-gl::ErrorOrResult<vk::RenderPass *> FramebufferVk::getRenderPass(const gl::Context *context,
-                                                                 VkDevice device)
+const vk::RenderPassDesc &FramebufferVk::getRenderPassDesc(const gl::Context *context)
 {
-    if (mRenderPass.valid())
+    if (mRenderPassDesc.valid())
     {
-        return &mRenderPass;
+        return mRenderPassDesc.value();
     }
 
-    // TODO(jmadill): Can we use stack-only memory?
-    std::vector<VkAttachmentDescription> attachmentDescs;
-    std::vector<VkAttachmentReference> colorAttachmentRefs;
+    vk::RenderPassDesc desc;
 
     const auto &colorAttachments = mState.getColorAttachments();
     for (size_t attachmentIndex = 0; attachmentIndex < colorAttachments.size(); ++attachmentIndex)
     {
         const auto &colorAttachment = colorAttachments[attachmentIndex];
         if (colorAttachment.isAttached())
         {
-            VkAttachmentDescription colorDesc;
-            VkAttachmentReference colorRef;
-
             RenderTargetVk *renderTarget = nullptr;
-            ANGLE_TRY(colorAttachment.getRenderTarget(context, &renderTarget));
-
-            // TODO(jmadill): We would only need this flag for duplicated attachments.
-            colorDesc.flags   = VK_ATTACHMENT_DESCRIPTION_MAY_ALIAS_BIT;
-            colorDesc.format  = renderTarget->format->native;
-            colorDesc.samples = ConvertSamples(colorAttachment.getSamples());
-
-            // The load op controls the prior existing depth/color attachment data.
-            // TODO(jmadill): Proper load ops. Should not be hard coded to clear.
-            colorDesc.loadOp         = VK_ATTACHMENT_LOAD_OP_CLEAR;
-            colorDesc.storeOp        = VK_ATTACHMENT_STORE_OP_STORE;
-            colorDesc.stencilLoadOp  = VK_ATTACHMENT_LOAD_OP_DONT_CARE;
-            colorDesc.stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE;
-            colorDesc.initialLayout  = VK_IMAGE_LAYOUT_UNDEFINED;
-
-            // We might want to transition directly to PRESENT_SRC for Surface attachments.
-            colorDesc.finalLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
-
-            colorRef.attachment = static_cast<uint32_t>(colorAttachments.size()) - 1u;
-            colorRef.layout     = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
-
-            attachmentDescs.push_back(colorDesc);
-            colorAttachmentRefs.push_back(colorRef);
+            ANGLE_SWALLOW_ERR(colorAttachment.getRenderTarget(context, &renderTarget));
+            desc.packColorAttachment(*renderTarget->format, colorAttachment.getSamples());
         }
     }
 
     const auto *depthStencilAttachment = mState.getDepthStencilAttachment();
-    VkAttachmentReference depthStencilAttachmentRef;
-    bool useDepth = depthStencilAttachment && depthStencilAttachment->isAttached();
 
-    if (useDepth)
+    if (depthStencilAttachment && depthStencilAttachment->isAttached())
     {
-        VkAttachmentDescription depthStencilDesc;
-
         RenderTargetVk *renderTarget = nullptr;
-        ANGLE_TRY(depthStencilAttachment->getRenderTarget(context, &renderTarget));
-
-        depthStencilDesc.flags          = 0;
-        depthStencilDesc.format         = renderTarget->format->native;
-        depthStencilDesc.samples        = ConvertSamples(depthStencilAttachment->getSamples());
-        depthStencilDesc.loadOp         = VK_ATTACHMENT_LOAD_OP_CLEAR;
-        depthStencilDesc.storeOp        = VK_ATTACHMENT_STORE_OP_STORE;
-        depthStencilDesc.stencilLoadOp  = VK_ATTACHMENT_LOAD_OP_DONT_CARE;
-        depthStencilDesc.stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE;
-        depthStencilDesc.initialLayout  = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL;
-        depthStencilDesc.finalLayout    = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL;
-
-        depthStencilAttachmentRef.attachment = static_cast<uint32_t>(attachmentDescs.size());
-        depthStencilAttachmentRef.layout     = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL;
-
-        attachmentDescs.push_back(depthStencilDesc);
+        ANGLE_SWALLOW_ERR(depthStencilAttachment->getRenderTarget(context, &renderTarget));
+        desc.packDepthStencilAttachment(*renderTarget->format,
+                                        depthStencilAttachment->getSamples());
     }
 
-    ASSERT(!attachmentDescs.empty());
-
-    VkSubpassDescription subpassDesc;
-
-    subpassDesc.flags                   = 0;
-    subpassDesc.pipelineBindPoint       = VK_PIPELINE_BIND_POINT_GRAPHICS;
-    subpassDesc.inputAttachmentCount    = 0;
-    subpassDesc.pInputAttachments       = nullptr;
-    subpassDesc.colorAttachmentCount    = static_cast<uint32_t>(colorAttachmentRefs.size());
-    subpassDesc.pColorAttachments       = colorAttachmentRefs.data();
-    subpassDesc.pResolveAttachments     = nullptr;
-    subpassDesc.pDepthStencilAttachment = (useDepth ? &depthStencilAttachmentRef : nullptr);
-    subpassDesc.preserveAttachmentCount = 0;
-    subpassDesc.pPreserveAttachments    = nullptr;
-
-    VkRenderPassCreateInfo renderPassInfo;
-
-    renderPassInfo.sType           = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO;
-    renderPassInfo.pNext           = nullptr;
-    renderPassInfo.flags           = 0;
-    renderPassInfo.attachmentCount = static_cast<uint32_t>(attachmentDescs.size());
-    renderPassInfo.pAttachments    = attachmentDescs.data();
-    renderPassInfo.subpassCount    = 1;
-    renderPassInfo.pSubpasses      = &subpassDesc;
-    renderPassInfo.dependencyCount = 0;
-    renderPassInfo.pDependencies   = nullptr;
-
-    vk::RenderPass renderPass;
-    ANGLE_TRY(renderPass.init(device, renderPassInfo));
-
-    mRenderPass.retain(device, std::move(renderPass));
-
-    return &mRenderPass;
+    mRenderPassDesc = desc;
+    return mRenderPassDesc.value();
 }
 
 gl::ErrorOrResult<vk::Framebuffer *> FramebufferVk::getFramebuffer(const gl::Context *context,
-                                                                   VkDevice device)
+                                                                   RendererVk *rendererVk)
 {
     // If we've already created our cached Framebuffer, return it.
     if (mFramebuffer.valid())
     {
         return &mFramebuffer;
     }
 
+    const vk::RenderPassDesc &desc = getRenderPassDesc(context);
+
     vk::RenderPass *renderPass = nullptr;
-    ANGLE_TRY_RESULT(getRenderPass(context, device), renderPass);
+    ANGLE_TRY(rendererVk->getCompatibleRenderPass(desc, &renderPass));
 
     // If we've a Framebuffer provided by a Surface (default FBO/backbuffer), query it.
+    VkDevice device = rendererVk->getDevice();
     if (mBackbuffer)
     {
         return mBackbuffer->getCurrentFramebuffer(device, *renderPass);
     }
 
     // Gather VkImageViews over all FBO attachments, also size of attached region.
     std::vector<VkImageView> attachments;
     gl::Extents attachmentsSize;
 
     const auto &colorAttachments = mState.getColorAttachments();
     for (size_t attachmentIndex = 0; attachmentIndex < colorAttachments.size(); ++attachmentIndex)
     {
         const auto &colorAttachment = colorAttachments[attachmentIndex];
         if (colorAttachment.isAttached())
         {
             RenderTargetVk *renderTarget = nullptr;
-            ANGLE_TRY(colorAttachment.getRenderTarget<RenderTargetVk>(context, &renderTarget));
+            ANGLE_TRY(colorAttachment.getRenderTarget(context, &renderTarget));
             attachments.push_back(renderTarget->imageView->getHandle());
 
             ASSERT(attachmentsSize.empty() || attachmentsSize == colorAttachment.getSize());
             attachmentsSize = colorAttachment.getSize();
         }
     }
 
     const auto *depthStencilAttachment = mState.getDepthStencilAttachment();
     if (depthStencilAttachment && depthStencilAttachment->isAttached())
     {
         RenderTargetVk *renderTarget = nullptr;
-        ANGLE_TRY(depthStencilAttachment->getRenderTarget<RenderTargetVk>(context, &renderTarget));
+        ANGLE_TRY(depthStencilAttachment->getRenderTarget(context, &renderTarget));
         attachments.push_back(renderTarget->imageView->getHandle());
 
         ASSERT(attachmentsSize.empty() || attachmentsSize == depthStencilAttachment->getSize());
         attachmentsSize = depthStencilAttachment->getSize();
     }
 
     ASSERT(!attachments.empty());
 
     VkFramebufferCreateInfo framebufferInfo;
 
     framebufferInfo.sType           = VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO;
     framebufferInfo.pNext           = nullptr;
     framebufferInfo.flags           = 0;
-    framebufferInfo.renderPass      = mRenderPass.getHandle();
+    framebufferInfo.renderPass      = renderPass->getHandle();
     framebufferInfo.attachmentCount = static_cast<uint32_t>(attachments.size());
     framebufferInfo.pAttachments    = attachments.data();
     framebufferInfo.width           = static_cast<uint32_t>(attachmentsSize.width);
     framebufferInfo.height          = static_cast<uint32_t>(attachmentsSize.height);
     framebufferInfo.layers          = 1;
 
-    vk::Framebuffer framebuffer;
-    ANGLE_TRY(framebuffer.init(device, framebufferInfo));
-
-    mFramebuffer.retain(device, std::move(framebuffer));
+    ANGLE_TRY(mFramebuffer.init(device, framebufferInfo));
 
     return &mFramebuffer;
 }
 
 gl::Error FramebufferVk::getSamplePosition(size_t index, GLfloat *xy) const
 {
     UNIMPLEMENTED();
     return gl::InternalError() << "getSamplePosition is unimplemented.";
 }
 
-gl::Error FramebufferVk::ensureInRenderPass(const gl::Context *context,
-                                            VkDevice device,
-                                            vk::CommandBuffer *commandBuffer,
-                                            Serial queueSerial,
-                                            const gl::State &glState)
+gl::Error FramebufferVk::getRenderNode(const gl::Context *context, vk::CommandBufferNode **nodeOut)
 {
-    if (mInRenderPass)
+    ContextVk *contextVk = vk::GetImpl(context);
+    RendererVk *renderer = contextVk->getRenderer();
+    Serial currentSerial = renderer->getCurrentQueueSerial();
+
+    if (isCurrentlyRecording(currentSerial) && mLastRenderNodeSerial == currentSerial)
     {
+        *nodeOut = getCurrentWriteNode(currentSerial);
+        ASSERT((*nodeOut)->getInsideRenderPassCommands()->valid());
         return gl::NoError();
     }
 
-    mInRenderPass = true;
-
-    // TODO(jmadill): Cache render targets.
-    for (const auto &colorAttachment : mState.getColorAttachments())
-    {
-        if (colorAttachment.isAttached())
-        {
-            RenderTargetVk *renderTarget = nullptr;
-            ANGLE_TRY(colorAttachment.getRenderTarget<RenderTargetVk>(context, &renderTarget));
-            renderTarget->resource->setQueueSerial(queueSerial);
-        }
-    }
-
-    const auto *depthStencilAttachment = mState.getDepthStencilAttachment();
-    if (depthStencilAttachment && depthStencilAttachment->isAttached())
-    {
-        RenderTargetVk *renderTarget = nullptr;
-        ANGLE_TRY(depthStencilAttachment->getRenderTarget<RenderTargetVk>(context, &renderTarget));
-        renderTarget->resource->setQueueSerial(queueSerial);
-    }
+    vk::CommandBufferNode *node = getNewWriteNode(renderer);
 
     vk::Framebuffer *framebuffer = nullptr;
-    ANGLE_TRY_RESULT(getFramebuffer(context, device), framebuffer);
-    ASSERT(framebuffer && framebuffer->valid());
+    ANGLE_TRY_RESULT(getFramebuffer(context, renderer), framebuffer);
 
-    vk::RenderPass *renderPass = nullptr;
-    ANGLE_TRY_RESULT(getRenderPass(context, device), renderPass);
-    ASSERT(renderPass && renderPass->valid());
+    const gl::State &glState = context->getGLState();
 
+    // Hard-code RenderPass to clear the first render target to the current clear value.
     // TODO(jmadill): Proper clear value implementation.
     VkClearColorValue colorClear;
     memset(&colorClear, 0, sizeof(VkClearColorValue));
     colorClear.float32[0] = glState.getColorClearValue().red;
     colorClear.float32[1] = glState.getColorClearValue().green;
     colorClear.float32[2] = glState.getColorClearValue().blue;
     colorClear.float32[3] = glState.getColorClearValue().alpha;
 
     std::vector<VkClearValue> attachmentClearValues;
     attachmentClearValues.push_back({colorClear});
 
-    // Updated the cached image layout of the attachments in this FBO.
-    // For a default FBO, we need to call through to the WindowSurfaceVk
-    // TODO(jmadill): Iterate over all attachments.
-    ASSERT(mBackbuffer);
-    RenderTargetVk *renderTarget = nullptr;
-    ANGLE_TRY(mState.getFirstColorAttachment()->getRenderTarget(context, &renderTarget));
-    renderTarget->image->updateLayout(VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL);
+    node->storeRenderPassInfo(*framebuffer, glState.getViewport(), attachmentClearValues);
 
-    commandBuffer->beginRenderPass(*renderPass, *framebuffer, glState.getViewport(),
-                                   attachmentClearValues);
+    // Initialize RenderPass info.
+    // TODO(jmadill): Could cache this info, would require dependent state change messaging.
+    const auto &colorAttachments = mState.getColorAttachments();
+    for (size_t attachmentIndex = 0; attachmentIndex < colorAttachments.size(); ++attachmentIndex)
+    {
+        const auto &colorAttachment = colorAttachments[attachmentIndex];
+        if (colorAttachment.isAttached())
+        {
+            RenderTargetVk *renderTarget = nullptr;
+            ANGLE_SWALLOW_ERR(colorAttachment.getRenderTarget(context, &renderTarget));
 
-    setQueueSerial(queueSerial);
-    if (mBackbuffer)
-    {
-        mBackbuffer->setQueueSerial(queueSerial);
+            // TODO(jmadill): May need layout transition.
+            renderTarget->image->updateLayout(VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL);
+            node->appendColorRenderTarget(currentSerial, renderTarget);
+        }
     }
 
+    const gl::FramebufferAttachment *depthStencilAttachment = mState.getDepthOrStencilAttachment();
+    if (depthStencilAttachment && depthStencilAttachment->isAttached())
+    {
+        RenderTargetVk *renderTarget = nullptr;
+        ANGLE_SWALLOW_ERR(depthStencilAttachment->getRenderTarget(context, &renderTarget));
+
+        // TODO(jmadill): May need layout transition.
+        renderTarget->image->updateLayout(VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL);
+        node->appendDepthStencilRenderTarget(currentSerial, renderTarget);
+    }
+
+    mLastRenderNodeSerial = currentSerial;
+
+    *nodeOut = node;
     return gl::NoError();
 }
 
-void FramebufferVk::endRenderPass(vk::CommandBuffer *commandBuffer)
-{
-    if (mInRenderPass)
-    {
-        commandBuffer->endRenderPass();
-        mInRenderPass = false;
-    }
-}
-
 }  // namespace rx
--- a/gfx/angle/src/libANGLE/renderer/vulkan/FramebufferVk.h
+++ b/gfx/angle/src/libANGLE/renderer/vulkan/FramebufferVk.h
@@ -10,16 +10,17 @@
 #ifndef LIBANGLE_RENDERER_VULKAN_FRAMEBUFFERVK_H_
 #define LIBANGLE_RENDERER_VULKAN_FRAMEBUFFERVK_H_
 
 #include "libANGLE/renderer/FramebufferImpl.h"
 #include "libANGLE/renderer/vulkan/renderervk_utils.h"
 
 namespace rx
 {
+class RendererVk;
 class RenderTargetVk;
 class WindowSurfaceVk;
 
 class FramebufferVk : public FramebufferImpl, public ResourceVk
 {
   public:
     // Factory methods so we don't have to use constructors with overloads.
     static FramebufferVk *CreateUserFBO(const gl::FramebufferState &state);
@@ -71,43 +72,35 @@ class FramebufferVk : public Framebuffer
                          void *pixels) override;
 
     gl::Error blit(const gl::Context *context,
                    const gl::Rectangle &sourceArea,
                    const gl::Rectangle &destArea,
                    GLbitfield mask,
                    GLenum filter) override;
 
-    bool checkStatus() const override;
+    bool checkStatus(const gl::Context *context) const override;
 
     void syncState(const gl::Context *context,
                    const gl::Framebuffer::DirtyBits &dirtyBits) override;
 
     gl::Error getSamplePosition(size_t index, GLfloat *xy) const override;
 
-    gl::Error ensureInRenderPass(const gl::Context *context,
-                                 VkDevice device,
-                                 vk::CommandBuffer *commandBuffer,
-                                 Serial queueSerial,
-                                 const gl::State &glState);
-    void endRenderPass(vk::CommandBuffer *commandBuffer);
-
-    bool isInRenderPass() const { return mInRenderPass; }
-
-    gl::ErrorOrResult<vk::RenderPass *> getRenderPass(const gl::Context *context, VkDevice device);
+    const vk::RenderPassDesc &getRenderPassDesc(const gl::Context *context);
+    gl::Error getRenderNode(const gl::Context *context, vk::CommandBufferNode **nodeOut);
 
   private:
     FramebufferVk(const gl::FramebufferState &state);
     FramebufferVk(const gl::FramebufferState &state, WindowSurfaceVk *backbuffer);
 
     gl::ErrorOrResult<vk::Framebuffer *> getFramebuffer(const gl::Context *context,
-                                                        VkDevice device);
+                                                        RendererVk *rendererVk);
 
     WindowSurfaceVk *mBackbuffer;
 
-    vk::RenderPass mRenderPass;
+    Optional<vk::RenderPassDesc> mRenderPassDesc;
     vk::Framebuffer mFramebuffer;
-    bool mInRenderPass;
+    Serial mLastRenderNodeSerial;
 };
 
 }  // namespace rx
 
 #endif  // LIBANGLE_RENDERER_VULKAN_FRAMEBUFFERVK_H_
--- a/gfx/angle/src/libANGLE/renderer/vulkan/GlslangWrapper.cpp
+++ b/gfx/angle/src/libANGLE/renderer/vulkan/GlslangWrapper.cpp
@@ -13,19 +13,39 @@
 #include <ShaderLang.h>
 
 // Other glslang includes.
 #include <StandAlone/ResourceLimits.h>
 #include <SPIRV/GlslangToSpv.h>
 
 #include <array>
 
+#include "common/string_utils.h"
+#include "common/utilities.h"
+#include "libANGLE/ProgramLinkedResources.h"
+
 namespace rx
 {
 
+namespace
+{
+
+void InsertLayoutSpecifierString(std::string *shaderString,
+                                 const std::string &variableName,
+                                 const std::string &layoutString)
+{
+    std::stringstream searchStringBuilder;
+    searchStringBuilder << "@@ LAYOUT-" << variableName << " @@";
+    std::string searchString = searchStringBuilder.str();
+
+    angle::ReplaceSubstring(shaderString, searchString, layoutString);
+}
+
+}  // anonymous namespace
+
 // static
 GlslangWrapper *GlslangWrapper::mInstance = nullptr;
 
 // static
 GlslangWrapper *GlslangWrapper::GetReference()
 {
     if (!mInstance)
     {
@@ -58,21 +78,85 @@ GlslangWrapper::GlslangWrapper()
 }
 
 GlslangWrapper::~GlslangWrapper()
 {
     int result = ShFinalize();
     ASSERT(result != 0);
 }
 
-gl::LinkResult GlslangWrapper::linkProgram(const std::string &vertexSource,
-                                           const std::string &fragmentSource,
+gl::LinkResult GlslangWrapper::linkProgram(const gl::Context *glContext,
+                                           const gl::ProgramState &programState,
+                                           const gl::ProgramLinkedResources &resources,
                                            std::vector<uint32_t> *vertexCodeOut,
                                            std::vector<uint32_t> *fragmentCodeOut)
 {
+    gl::Shader *glVertexShader   = programState.getAttachedVertexShader();
+    gl::Shader *glFragmentShader = programState.getAttachedFragmentShader();
+
+    std::string vertexSource   = glVertexShader->getTranslatedSource(glContext);
+    std::string fragmentSource = glFragmentShader->getTranslatedSource(glContext);
+
+    // Parse attribute locations and replace them in the vertex shader.
+    // See corresponding code in OutputVulkanGLSL.cpp.
+    // TODO(jmadill): Also do the same for ESSL 3 fragment outputs.
+    for (const auto &attribute : programState.getAttributes())
+    {
+        if (!attribute.staticUse)
+            continue;
+
+        std::string locationString = "location = " + Str(attribute.location);
+        InsertLayoutSpecifierString(&vertexSource, attribute.name, locationString);
+    }
+
+    // Assign varying locations.
+    // TODO(jmadill): This might need to be redone.
+    for (const auto &varyingReg : resources.varyingPacking.getRegisterList())
+    {
+        const auto &varying        = *varyingReg.packedVarying;
+        std::string locationString = "location = " + Str(varyingReg.registerRow);
+        InsertLayoutSpecifierString(&vertexSource, varying.varying->name, locationString);
+        InsertLayoutSpecifierString(&fragmentSource, varying.varying->name, locationString);
+    }
+
+    // Bind the default uniforms for vertex and fragment shaders.
+    // See corresponding code in OutputVulkanGLSL.cpp.
+    std::stringstream searchStringBuilder;
+    searchStringBuilder << "@@ DEFAULT-UNIFORMS-SET-BINDING @@";
+    std::string searchString = searchStringBuilder.str();
+
+    std::string vertexDefaultUniformsBinding   = "set = 0, binding = 0";
+    std::string fragmentDefaultUniformsBinding = "set = 0, binding = 1";
+
+    angle::ReplaceSubstring(&vertexSource, searchString, vertexDefaultUniformsBinding);
+    angle::ReplaceSubstring(&fragmentSource, searchString, fragmentDefaultUniformsBinding);
+
+    // Assign textures to a descriptor set and binding.
+    int textureCount     = 0;
+    const auto &uniforms = programState.getUniforms();
+    for (unsigned int uniformIndex : programState.getSamplerUniformRange())
+    {
+        const gl::LinkedUniform &samplerUniform = uniforms[uniformIndex];
+
+        std::string setBindingString = "set = 1, binding = " + Str(textureCount);
+
+        ASSERT(samplerUniform.vertexStaticUse || samplerUniform.fragmentStaticUse);
+        if (samplerUniform.vertexStaticUse)
+        {
+            InsertLayoutSpecifierString(&vertexSource, samplerUniform.name, setBindingString);
+        }
+
+        if (samplerUniform.fragmentStaticUse)
+        {
+            InsertLayoutSpecifierString(&fragmentSource, samplerUniform.name, setBindingString);
+        }
+
+        textureCount += samplerUniform.getBasicTypeElementCount();
+    }
+
     std::array<const char *, 2> strings = {{vertexSource.c_str(), fragmentSource.c_str()}};
 
     std::array<int, 2> lengths = {
         {static_cast<int>(vertexSource.length()), static_cast<int>(fragmentSource.length())}};
 
     // Enable SPIR-V and Vulkan rules when parsing GLSL
     EShMessages messages = static_cast<EShMessages>(EShMsgSpvRules | EShMsgVulkanRules);
 
--- a/gfx/angle/src/libANGLE/renderer/vulkan/GlslangWrapper.h
+++ b/gfx/angle/src/libANGLE/renderer/vulkan/GlslangWrapper.h
@@ -18,18 +18,19 @@ namespace rx
 class GlslangWrapper : public gl::RefCountObjectNoID
 {
   public:
     // Increases the reference count.
     // TODO(jmadill): Determine how to handle this atomically.
     static GlslangWrapper *GetReference();
     static void ReleaseReference();
 
-    gl::LinkResult linkProgram(const std::string &vertexSource,
-                               const std::string &fragmentSource,
+    gl::LinkResult linkProgram(const gl::Context *glContext,
+                               const gl::ProgramState &programState,
+                               const gl::ProgramLinkedResources &resources,
                                std::vector<uint32_t> *vertexCodeOut,
                                std::vector<uint32_t> *fragmentCodeOut);
 
   private:
     GlslangWrapper();
     ~GlslangWrapper() override;
 
     static GlslangWrapper *mInstance;
--- a/gfx/angle/src/libANGLE/renderer/vulkan/ProgramVk.cpp
+++ b/gfx/angle/src/libANGLE/renderer/vulkan/ProgramVk.cpp
@@ -5,39 +5,178 @@
 //
 // ProgramVk.cpp:
 //    Implements the class methods for ProgramVk.
 //
 
 #include "libANGLE/renderer/vulkan/ProgramVk.h"
 
 #include "common/debug.h"
+#include "common/utilities.h"
 #include "libANGLE/Context.h"
 #include "libANGLE/renderer/vulkan/ContextVk.h"
 #include "libANGLE/renderer/vulkan/GlslangWrapper.h"
 #include "libANGLE/renderer/vulkan/RendererVk.h"
+#include "libANGLE/renderer/vulkan/TextureVk.h"
 
 namespace rx
 {
 
-ProgramVk::ProgramVk(const gl::ProgramState &state) : ProgramImpl(state)
+namespace
+{
+
+gl::Error InitDefaultUniformBlock(const gl::Context *context,
+                                  VkDevice device,
+                                  gl::Shader *shader,
+                                  vk::BufferAndMemory *storageOut,
+                                  sh::BlockLayoutMap *blockLayoutMapOut,
+                                  size_t *requiredSizeOut)
+{
+    const auto &uniforms = shader->getUniforms(context);
+
+    if (uniforms.empty())
+    {
+        *requiredSizeOut = 0;
+        return gl::NoError();
+    }
+
+    sh::Std140BlockEncoder blockEncoder;
+    sh::GetUniformBlockInfo(uniforms, "", &blockEncoder, blockLayoutMapOut);
+
+    size_t blockSize = blockEncoder.getBlockSize();
+
+    // TODO(jmadill): I think we still need a valid block for the pipeline even if zero sized.
+    if (blockSize == 0)
+    {
+        *requiredSizeOut = 0;
+        return gl::NoError();
+    }
+
+    VkBufferCreateInfo uniformBufferInfo;
+    uniformBufferInfo.sType                 = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO;
+    uniformBufferInfo.pNext                 = nullptr;
+    uniformBufferInfo.flags                 = 0;
+    uniformBufferInfo.size                  = blockSize;
+    uniformBufferInfo.usage                 = VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT;
+    uniformBufferInfo.sharingMode           = VK_SHARING_MODE_EXCLUSIVE;
+    uniformBufferInfo.queueFamilyIndexCount = 0;
+    uniformBufferInfo.pQueueFamilyIndices   = nullptr;
+
+    ANGLE_TRY(storageOut->buffer.init(device, uniformBufferInfo));
+
+    ANGLE_TRY(AllocateBufferMemory(vk::GetImpl(context), blockSize, &storageOut->buffer,
+                                   &storageOut->memory, requiredSizeOut));
+
+    return gl::NoError();
+}
+
+template <typename T>
+void UpdateDefaultUniformBlock(GLsizei count,
+                               int componentCount,
+                               const T *v,
+                               const sh::BlockMemberInfo &layoutInfo,
+                               angle::MemoryBuffer *uniformData)
 {
+    // Assume an offset of -1 means the block is unused.
+    if (layoutInfo.offset == -1)
+    {
+        return;
+    }
+
+    int elementSize = sizeof(T) * componentCount;
+    if (layoutInfo.arrayStride == 0 || layoutInfo.arrayStride == elementSize)
+    {
+        uint8_t *writePtr = uniformData->data() + layoutInfo.offset;
+        memcpy(writePtr, v, elementSize * count);
+    }
+    else
+    {
+        UNIMPLEMENTED();
+    }
+}
+
+vk::Error SyncDefaultUniformBlock(VkDevice device,
+                                  vk::DeviceMemory *bufferMemory,
+                                  const angle::MemoryBuffer &bufferData)
+{
+    ASSERT(bufferMemory->valid() && !bufferData.empty());
+    uint8_t *mapPointer = nullptr;
+    ANGLE_TRY(bufferMemory->map(device, 0, bufferData.size(), 0, &mapPointer));
+    memcpy(mapPointer, bufferData.data(), bufferData.size());
+    bufferMemory->unmap(device);
+    return vk::NoError();
+}
+
+enum ShaderIndex : uint32_t
+{
+    MinShaderIndex = 0,
+    VertexShader   = MinShaderIndex,
+    FragmentShader = 1,
+    MaxShaderIndex = 2,
+};
+
+gl::Shader *GetShader(const gl::ProgramState &programState, uint32_t shaderIndex)
+{
+    switch (shaderIndex)
+    {
+        case VertexShader:
+            return programState.getAttachedVertexShader();
+        case FragmentShader:
+            return programState.getAttachedFragmentShader();
+        default:
+            UNREACHABLE();
+            return nullptr;
+    }
+}
+
+}  // anonymous namespace
+
+ProgramVk::DefaultUniformBlock::DefaultUniformBlock()
+    : storage(), uniformData(), uniformsDirty(false), uniformLayout()
+{
+}
+
+ProgramVk::DefaultUniformBlock::~DefaultUniformBlock()
+{
+}
+
+ProgramVk::ProgramVk(const gl::ProgramState &state)
+    : ProgramImpl(state), mDefaultUniformBlocks(), mUsedDescriptorSetRange(), mDirtyTextures(true)
+{
+    mUsedDescriptorSetRange.invalidate();
 }
 
 ProgramVk::~ProgramVk()
 {
 }
 
 void ProgramVk::destroy(const gl::Context *contextImpl)
 {
-    VkDevice device = GetImplAs<ContextVk>(contextImpl)->getDevice();
+    VkDevice device = vk::GetImpl(contextImpl)->getDevice();
+    reset(device);
+}
+
+void ProgramVk::reset(VkDevice device)
+{
+    for (auto &uniformBlock : mDefaultUniformBlocks)
+    {
+        uniformBlock.storage.memory.destroy(device);
+        uniformBlock.storage.buffer.destroy(device);
+    }
+
+    mEmptyUniformBlockStorage.memory.destroy(device);
+    mEmptyUniformBlockStorage.buffer.destroy(device);
 
     mLinkedFragmentModule.destroy(device);
     mLinkedVertexModule.destroy(device);
-    mPipelineLayout.destroy(device);
+
+    // Descriptor Sets are pool allocated, so do not need to be explicitly freed.
+    mDescriptorSets.clear();
+    mUsedDescriptorSetRange.invalidate();
+    mDirtyTextures       = false;
 }
 
 gl::LinkResult ProgramVk::load(const gl::Context *contextImpl,
                                gl::InfoLog &infoLog,
                                gl::BinaryInputStream *stream)
 {
     UNIMPLEMENTED();
     return gl::InternalError();
@@ -54,97 +193,231 @@ void ProgramVk::setBinaryRetrievableHint
 }
 
 void ProgramVk::setSeparable(bool separable)
 {
     UNIMPLEMENTED();
 }
 
 gl::LinkResult ProgramVk::link(const gl::Context *glContext,
-                               const gl::VaryingPacking &packing,
+                               const gl::ProgramLinkedResources &resources,
                                gl::InfoLog &infoLog)
 {
-    ContextVk *context             = GetImplAs<ContextVk>(glContext);
-    RendererVk *renderer           = context->getRenderer();
+    ContextVk *contextVk           = vk::GetImpl(glContext);
+    RendererVk *renderer           = contextVk->getRenderer();
     GlslangWrapper *glslangWrapper = renderer->getGlslangWrapper();
+    VkDevice device                = renderer->getDevice();
 
-    const std::string &vertexSource =
-        mState.getAttachedVertexShader()->getTranslatedSource(glContext);
-    const std::string &fragmentSource =
-        mState.getAttachedFragmentShader()->getTranslatedSource(glContext);
+    reset(device);
 
     std::vector<uint32_t> vertexCode;
     std::vector<uint32_t> fragmentCode;
     bool linkSuccess = false;
     ANGLE_TRY_RESULT(
-        glslangWrapper->linkProgram(vertexSource, fragmentSource, &vertexCode, &fragmentCode),
+        glslangWrapper->linkProgram(glContext, mState, resources, &vertexCode, &fragmentCode),
         linkSuccess);
     if (!linkSuccess)
     {
         return false;
     }
 
-    vk::ShaderModule vertexModule;
-    vk::ShaderModule fragmentModule;
-    VkDevice device = renderer->getDevice();
-
     {
         VkShaderModuleCreateInfo vertexShaderInfo;
         vertexShaderInfo.sType    = VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO;
         vertexShaderInfo.pNext    = nullptr;
         vertexShaderInfo.flags    = 0;
         vertexShaderInfo.codeSize = vertexCode.size() * sizeof(uint32_t);
         vertexShaderInfo.pCode    = vertexCode.data();
-        ANGLE_TRY(vertexModule.init(device, vertexShaderInfo));
+
+        ANGLE_TRY(mLinkedVertexModule.init(device, vertexShaderInfo));
     }
 
     {
         VkShaderModuleCreateInfo fragmentShaderInfo;
         fragmentShaderInfo.sType    = VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO;
         fragmentShaderInfo.pNext    = nullptr;
         fragmentShaderInfo.flags    = 0;
         fragmentShaderInfo.codeSize = fragmentCode.size() * sizeof(uint32_t);
         fragmentShaderInfo.pCode    = fragmentCode.data();
 
-        ANGLE_TRY(fragmentModule.init(device, fragmentShaderInfo));
+        ANGLE_TRY(mLinkedFragmentModule.init(device, fragmentShaderInfo));
+    }
+
+    ANGLE_TRY(initDescriptorSets(contextVk));
+    ANGLE_TRY(initDefaultUniformBlocks(glContext));
+
+    if (!mState.getSamplerUniformRange().empty())
+    {
+        // Ensure the descriptor set range includes the textures at position 1.
+        mUsedDescriptorSetRange.extend(1);
+        mDirtyTextures = true;
+    }
+
+    return true;
+}
+
+gl::Error ProgramVk::initDefaultUniformBlocks(const gl::Context *glContext)
+{
+    ContextVk *contextVk = vk::GetImpl(glContext);
+    VkDevice device      = contextVk->getDevice();
+
+    // Process vertex and fragment uniforms into std140 packing.
+    std::array<sh::BlockLayoutMap, 2> layoutMap;
+    std::array<size_t, 2> requiredBufferSize = {{0, 0}};
+
+    for (uint32_t shaderIndex = MinShaderIndex; shaderIndex < MaxShaderIndex; ++shaderIndex)
+    {
+        ANGLE_TRY(InitDefaultUniformBlock(glContext, device, GetShader(mState, shaderIndex),
+                                          &mDefaultUniformBlocks[shaderIndex].storage,
+                                          &layoutMap[shaderIndex],
+                                          &requiredBufferSize[shaderIndex]));
     }
 
-    mLinkedVertexModule.retain(device, std::move(vertexModule));
-    mLinkedFragmentModule.retain(device, std::move(fragmentModule));
+    // Init the default block layout info.
+    const auto &locations = mState.getUniformLocations();
+    const auto &uniforms  = mState.getUniforms();
+    for (size_t locationIndex = 0; locationIndex < locations.size(); ++locationIndex)
+    {
+        std::array<sh::BlockMemberInfo, 2> layoutInfo;
+
+        const auto &location = locations[locationIndex];
+        if (location.used() && !location.ignored)
+        {
+            const auto &uniform = uniforms[location.index];
+
+            if (uniform.isSampler())
+                continue;
+
+            std::string uniformName = uniform.name;
+            if (uniform.isArray())
+            {
+                uniformName += ArrayString(location.arrayIndex);
+            }
+
+            bool found = false;
+
+            for (uint32_t shaderIndex = MinShaderIndex; shaderIndex < MaxShaderIndex; ++shaderIndex)
+            {
+                auto it = layoutMap[shaderIndex].find(uniformName);
+                if (it != layoutMap[shaderIndex].end())
+                {
+                    found                   = true;
+                    layoutInfo[shaderIndex] = it->second;
+                }
+            }
+
+            ASSERT(found);
+        }
+
+        for (uint32_t shaderIndex = MinShaderIndex; shaderIndex < MaxShaderIndex; ++shaderIndex)
+        {
+            mDefaultUniformBlocks[shaderIndex].uniformLayout.push_back(layoutInfo[shaderIndex]);
+        }
+    }
+
+    bool anyDirty = false;
+    bool allDirty = true;
 
-    // TODO(jmadill): Use pipeline cache.
-    context->invalidateCurrentPipeline();
+    for (uint32_t shaderIndex = MinShaderIndex; shaderIndex < MaxShaderIndex; ++shaderIndex)
+    {
+        if (requiredBufferSize[shaderIndex] > 0)
+        {
+            if (!mDefaultUniformBlocks[shaderIndex].uniformData.resize(
+                    requiredBufferSize[shaderIndex]))
+            {
+                return gl::OutOfMemory() << "Memory allocation failure.";
+            }
+            mDefaultUniformBlocks[shaderIndex].uniformData.fill(0);
+            mDefaultUniformBlocks[shaderIndex].uniformsDirty = true;
+
+            anyDirty = true;
+        }
+        else
+        {
+            allDirty = false;
+        }
+    }
 
-    return true;
+    if (anyDirty)
+    {
+        // Initialize the "empty" uniform block if necessary.
+        if (!allDirty)
+        {
+            VkBufferCreateInfo uniformBufferInfo;
+            uniformBufferInfo.sType                 = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO;
+            uniformBufferInfo.pNext                 = nullptr;
+            uniformBufferInfo.flags                 = 0;
+            uniformBufferInfo.size                  = 1;
+            uniformBufferInfo.usage                 = VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT;
+            uniformBufferInfo.sharingMode           = VK_SHARING_MODE_EXCLUSIVE;
+            uniformBufferInfo.queueFamilyIndexCount = 0;
+            uniformBufferInfo.pQueueFamilyIndices   = nullptr;
+
+            ANGLE_TRY(mEmptyUniformBlockStorage.buffer.init(device, uniformBufferInfo));
+
+            size_t requiredSize = 0;
+            ANGLE_TRY(AllocateBufferMemory(contextVk, 1, &mEmptyUniformBlockStorage.buffer,
+                                           &mEmptyUniformBlockStorage.memory, &requiredSize));
+        }
+
+        ANGLE_TRY(updateDefaultUniformsDescriptorSet(contextVk));
+
+        // Ensure the descriptor set range includes the uniform buffers at position 0.
+        mUsedDescriptorSetRange.extend(0);
+    }
+
+    return gl::NoError();
 }
 
 GLboolean ProgramVk::validate(const gl::Caps &caps, gl::InfoLog *infoLog)
 {
     UNIMPLEMENTED();
     return GLboolean();
 }
 
+template <typename T>
+void ProgramVk::setUniformImpl(GLint location, GLsizei count, const T *v, GLenum entryPointType)
+{
+    const gl::VariableLocation &locationInfo = mState.getUniformLocations()[location];
+    const gl::LinkedUniform &linkedUniform   = mState.getUniforms()[locationInfo.index];
+
+    if (linkedUniform.type == entryPointType)
+    {
+        for (auto &uniformBlock : mDefaultUniformBlocks)
+        {
+            const sh::BlockMemberInfo &layoutInfo = uniformBlock.uniformLayout[location];
+            UpdateDefaultUniformBlock(count, linkedUniform.typeInfo->componentCount, v, layoutInfo,
+                                      &uniformBlock.uniformData);
+        }
+    }
+    else
+    {
+        ASSERT(linkedUniform.type == gl::VariableBoolVectorType(entryPointType));
+        UNIMPLEMENTED();
+    }
+}
+
 void ProgramVk::setUniform1fv(GLint location, GLsizei count, const GLfloat *v)
 {
-    UNIMPLEMENTED();
+    setUniformImpl(location, count, v, GL_FLOAT);
 }
 
 void ProgramVk::setUniform2fv(GLint location, GLsizei count, const GLfloat *v)
 {
-    UNIMPLEMENTED();
+    setUniformImpl(location, count, v, GL_FLOAT_VEC2);
 }
 
 void ProgramVk::setUniform3fv(GLint location, GLsizei count, const GLfloat *v)
 {
-    UNIMPLEMENTED();
+    setUniformImpl(location, count, v, GL_FLOAT_VEC3);
 }
 
 void ProgramVk::setUniform4fv(GLint location, GLsizei count, const GLfloat *v)
 {
-    UNIMPLEMENTED();
+    setUniformImpl(location, count, v, GL_FLOAT_VEC4);
 }
 
 void ProgramVk::setUniform1iv(GLint location, GLsizei count, const GLint *v)
 {
     UNIMPLEMENTED();
 }
 
 void ProgramVk::setUniform2iv(GLint location, GLsizei count, const GLint *v)
@@ -254,32 +527,16 @@ void ProgramVk::setUniformMatrix4x3fv(GL
     UNIMPLEMENTED();
 }
 
 void ProgramVk::setUniformBlockBinding(GLuint uniformBlockIndex, GLuint uniformBlockBinding)
 {
     UNIMPLEMENTED();
 }
 
-bool ProgramVk::getUniformBlockSize(const std::string &blockName,
-                                    const std::string &blockMappedName,
-                                    size_t *sizeOut) const
-{
-    UNIMPLEMENTED();
-    return bool();
-}
-
-bool ProgramVk::getUniformBlockMemberInfo(const std::string &memberUniformName,
-                                          const std::string &memberUniformMappedName,
-                                          sh::BlockMemberInfo *memberInfoOut) const
-{
-    UNIMPLEMENTED();
-    return bool();
-}
-
 void ProgramVk::setPathFragmentInputGen(const std::string &inputName,
                                         GLenum genMode,
                                         GLint components,
                                         const GLfloat *coeffs)
 {
     UNIMPLEMENTED();
 }
 
@@ -290,34 +547,41 @@ const vk::ShaderModule &ProgramVk::getLi
 }
 
 const vk::ShaderModule &ProgramVk::getLinkedFragmentModule() const
 {
     ASSERT(mLinkedFragmentModule.getHandle() != VK_NULL_HANDLE);
     return mLinkedFragmentModule;
 }
 
-gl::ErrorOrResult<vk::PipelineLayout *> ProgramVk::getPipelineLayout(VkDevice device)
+vk::Error ProgramVk::initDescriptorSets(ContextVk *contextVk)
 {
-    vk::PipelineLayout newLayout;
+    ASSERT(mDescriptorSets.empty());
+
+    RendererVk *renderer = contextVk->getRenderer();
+    VkDevice device = contextVk->getDevice();
+
+    // Write out to a new a descriptor set.
+    // TODO(jmadill): Handle descriptor set lifetime.
+    vk::DescriptorPool *descriptorPool = contextVk->getDescriptorPool();
+
+    const auto &descriptorSetLayouts = renderer->getGraphicsDescriptorSetLayouts();
 
-    // TODO(jmadill): Descriptor sets.
-    VkPipelineLayoutCreateInfo createInfo;
-    createInfo.sType                  = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO;
-    createInfo.pNext                  = nullptr;
-    createInfo.flags                  = 0;
-    createInfo.setLayoutCount         = 0;
-    createInfo.pSetLayouts            = nullptr;
-    createInfo.pushConstantRangeCount = 0;
-    createInfo.pPushConstantRanges    = nullptr;
+    uint32_t descriptorSetCount = static_cast<uint32_t>(descriptorSetLayouts.size());
 
-    ANGLE_TRY(newLayout.init(device, createInfo));
-    mPipelineLayout.retain(device, std::move(newLayout));
+    VkDescriptorSetAllocateInfo allocInfo;
+    allocInfo.sType              = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO;
+    allocInfo.pNext              = nullptr;
+    allocInfo.descriptorPool     = descriptorPool->getHandle();
+    allocInfo.descriptorSetCount = descriptorSetCount;
+    allocInfo.pSetLayouts        = descriptorSetLayouts[0].ptr();
 
-    return &mPipelineLayout;
+    mDescriptorSets.resize(descriptorSetCount, VK_NULL_HANDLE);
+    ANGLE_TRY(descriptorPool->allocateDescriptorSets(device, allocInfo, &mDescriptorSets[0]));
+    return vk::NoError();
 }
 
 void ProgramVk::getUniformfv(const gl::Context *context, GLint location, GLfloat *params) const
 {
     UNIMPLEMENTED();
 }
 
 void ProgramVk::getUniformiv(const gl::Context *context, GLint location, GLint *params) const
@@ -325,9 +589,160 @@ void ProgramVk::getUniformiv(const gl::C
     UNIMPLEMENTED();
 }
 
 void ProgramVk::getUniformuiv(const gl::Context *context, GLint location, GLuint *params) const
 {
     UNIMPLEMENTED();
 }
 
+vk::Error ProgramVk::updateUniforms(ContextVk *contextVk)
+{
+    if (!mDefaultUniformBlocks[VertexShader].uniformsDirty &&
+        !mDefaultUniformBlocks[FragmentShader].uniformsDirty)
+    {
+        return vk::NoError();
+    }
+
+    ASSERT(mUsedDescriptorSetRange.contains(0));
+
+    VkDevice device = contextVk->getDevice();
+
+    // Update buffer memory by immediate mapping. This immediate update only works once.
+    // TODO(jmadill): Handle inserting updates into the command stream, or use dynamic buffers.
+    for (auto &uniformBlock : mDefaultUniformBlocks)
+    {
+        if (uniformBlock.uniformsDirty)
+        {
+            ANGLE_TRY(SyncDefaultUniformBlock(device, &uniformBlock.storage.memory,
+                                              uniformBlock.uniformData));
+            uniformBlock.uniformsDirty = false;
+        }
+    }
+
+    return vk::NoError();
+}
+
+vk::Error ProgramVk::updateDefaultUniformsDescriptorSet(ContextVk *contextVk)
+{
+    std::array<VkDescriptorBufferInfo, 2> descriptorBufferInfo;
+    std::array<VkWriteDescriptorSet, 2> writeDescriptorInfo;
+    uint32_t bufferCount = 0;
+
+    for (auto &uniformBlock : mDefaultUniformBlocks)
+    {
+        auto &bufferInfo = descriptorBufferInfo[bufferCount];
+
+        if (!uniformBlock.uniformData.empty())
+        {
+            bufferInfo.buffer = uniformBlock.storage.buffer.getHandle();
+        }
+        else
+        {
+            bufferInfo.buffer = mEmptyUniformBlockStorage.buffer.getHandle();
+        }
+
+        bufferInfo.offset = 0;
+        bufferInfo.range  = VK_WHOLE_SIZE;
+
+        auto &writeInfo = writeDescriptorInfo[bufferCount];
+
+        writeInfo.sType            = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
+        writeInfo.pNext            = nullptr;
+        writeInfo.dstSet           = mDescriptorSets[0];
+        writeInfo.dstBinding       = bufferCount;
+        writeInfo.dstArrayElement  = 0;
+        writeInfo.descriptorCount  = 1;
+        writeInfo.descriptorType   = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
+        writeInfo.pImageInfo       = nullptr;
+        writeInfo.pBufferInfo      = &bufferInfo;
+        writeInfo.pTexelBufferView = nullptr;
+
+        bufferCount++;
+    }
+
+    VkDevice device = contextVk->getDevice();
+
+    vkUpdateDescriptorSets(device, bufferCount, writeDescriptorInfo.data(), 0, nullptr);
+
+    return vk::NoError();
+}
+
+const std::vector<VkDescriptorSet> &ProgramVk::getDescriptorSets() const
+{
+    return mDescriptorSets;
+}
+
+const gl::RangeUI &ProgramVk::getUsedDescriptorSetRange() const
+{
+    return mUsedDescriptorSetRange;
+}
+
+void ProgramVk::updateTexturesDescriptorSet(ContextVk *contextVk)
+{
+    if (mState.getSamplerBindings().empty() || !mDirtyTextures)
+    {
+        return;
+    }
+
+    ASSERT(mUsedDescriptorSetRange.contains(1));
+    VkDescriptorSet descriptorSet = mDescriptorSets[1];
+
+    // TODO(jmadill): Don't hard-code the texture limit.
+    ShaderTextureArray<VkDescriptorImageInfo> descriptorImageInfo;
+    ShaderTextureArray<VkWriteDescriptorSet> writeDescriptorInfo;
+    uint32_t imageCount = 0;
+
+    const gl::State &glState     = contextVk->getGLState();
+    const auto &completeTextures = glState.getCompleteTextureCache();
+
+    for (const auto &samplerBinding : mState.getSamplerBindings())
+    {
+        ASSERT(!samplerBinding.unreferenced);
+
+        // TODO(jmadill): Sampler arrays
+        ASSERT(samplerBinding.boundTextureUnits.size() == 1);
+
+        GLuint textureUnit         = samplerBinding.boundTextureUnits[0];
+        const gl::Texture *texture = completeTextures[textureUnit];
+
+        // TODO(jmadill): Incomplete textures handling.
+        ASSERT(texture);
+
+        TextureVk *textureVk   = vk::GetImpl(texture);
+        const vk::Image &image = textureVk->getImage();
+
+        VkDescriptorImageInfo &imageInfo = descriptorImageInfo[imageCount];
+
+        imageInfo.sampler     = textureVk->getSampler().getHandle();
+        imageInfo.imageView   = textureVk->getImageView().getHandle();
+        imageInfo.imageLayout = image.getCurrentLayout();
+
+        auto &writeInfo = writeDescriptorInfo[imageCount];
+
+        writeInfo.sType            = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
+        writeInfo.pNext            = nullptr;
+        writeInfo.dstSet           = descriptorSet;
+        writeInfo.dstBinding       = imageCount;
+        writeInfo.dstArrayElement  = 0;
+        writeInfo.descriptorCount  = 1;
+        writeInfo.descriptorType   = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER;
+        writeInfo.pImageInfo       = &imageInfo;
+        writeInfo.pBufferInfo      = nullptr;
+        writeInfo.pTexelBufferView = nullptr;
+
+        imageCount++;
+    }
+
+    VkDevice device = contextVk->getDevice();
+
+    ASSERT(imageCount > 0);
+    vkUpdateDescriptorSets(device, imageCount, writeDescriptorInfo.data(), 0, nullptr);
+
+    mDirtyTextures = false;
+}
+
+void ProgramVk::invalidateTextures()
+{
+    mDirtyTextures = true;
+}
+
 }  // namespace rx
--- a/gfx/angle/src/libANGLE/renderer/vulkan/ProgramVk.h
+++ b/gfx/angle/src/libANGLE/renderer/vulkan/ProgramVk.h
@@ -5,19 +5,22 @@
 //
 // ProgramVk.h:
 //    Defines the class interface for ProgramVk, implementing ProgramImpl.
 //
 
 #ifndef LIBANGLE_RENDERER_VULKAN_PROGRAMVK_H_
 #define LIBANGLE_RENDERER_VULKAN_PROGRAMVK_H_
 
+#include "libANGLE/Constants.h"
 #include "libANGLE/renderer/ProgramImpl.h"
 #include "libANGLE/renderer/vulkan/renderervk_utils.h"
 
+#include <array>
+
 namespace rx
 {
 
 class ProgramVk : public ProgramImpl
 {
   public:
     ProgramVk(const gl::ProgramState &state);
     ~ProgramVk() override;
@@ -26,17 +29,17 @@ class ProgramVk : public ProgramImpl
     gl::LinkResult load(const gl::Context *context,
                         gl::InfoLog &infoLog,
                         gl::BinaryInputStream *stream) override;
     void save(const gl::Context *context, gl::BinaryOutputStream *stream) override;
     void setBinaryRetrievableHint(bool retrievable) override;
     void setSeparable(bool separable) override;
 
     gl::LinkResult link(const gl::Context *context,
-                        const gl::VaryingPacking &packing,
+                        const gl::ProgramLinkedResources &resources,
                         gl::InfoLog &infoLog) override;
     GLboolean validate(const gl::Caps &caps, gl::InfoLog *infoLog) override;
 
     void setUniform1fv(GLint location, GLsizei count, const GLfloat *v) override;
     void setUniform2fv(GLint location, GLsizei count, const GLfloat *v) override;
     void setUniform3fv(GLint location, GLsizei count, const GLfloat *v) override;
     void setUniform4fv(GLint location, GLsizei count, const GLfloat *v) override;
     void setUniform1iv(GLint location, GLsizei count, const GLint *v) override;
@@ -86,38 +89,79 @@ class ProgramVk : public ProgramImpl
 
     void getUniformfv(const gl::Context *context, GLint location, GLfloat *params) const override;
     void getUniformiv(const gl::Context *context, GLint location, GLint *params) const override;
     void getUniformuiv(const gl::Context *context, GLint location, GLuint *params) const override;
 
     // TODO: synchronize in syncState when dirty bits exist.
     void setUniformBlockBinding(GLuint uniformBlockIndex, GLuint uniformBlockBinding) override;
 
-    // May only be called after a successful link operation.
-    // Return false for inactive blocks.
-    bool getUniformBlockSize(const std::string &blockName,
-                             const std::string &blockMappedName,
-                             size_t *sizeOut) const override;
-
-    // May only be called after a successful link operation.
-    // Returns false for inactive members.
-    bool getUniformBlockMemberInfo(const std::string &memberUniformName,
-                                   const std::string &memberUniformMappedName,
-                                   sh::BlockMemberInfo *memberInfoOut) const override;
-
     void setPathFragmentInputGen(const std::string &inputName,
                                  GLenum genMode,
                                  GLint components,
                                  const GLfloat *coeffs) override;
 
     const vk::ShaderModule &getLinkedVertexModule() const;
     const vk::ShaderModule &getLinkedFragmentModule() const;
-    gl::ErrorOrResult<vk::PipelineLayout *> getPipelineLayout(VkDevice device);
+
+    vk::Error updateUniforms(ContextVk *contextVk);
+
+    const std::vector<VkDescriptorSet> &getDescriptorSets() const;
+
+    // In Vulkan, it is invalid to pass in a NULL descriptor set to vkCmdBindDescriptorSets.
+    // However, it's valid to leave them in an undefined, unbound state, if they are never used.
+    // This means when we want to ignore a descriptor set index, we need to pass in an offset
+    // parameter to BindDescriptorSets, which is an offset into the getDescriptorSets array.
+    // This allows us to skip binding blank descriptor sets when the Program doesn't use Uniforms
+    // or Textures.
+    const gl::RangeUI &getUsedDescriptorSetRange() const;
+
+    void updateTexturesDescriptorSet(ContextVk *contextVk);
+    void invalidateTextures();
 
   private:
+    void reset(VkDevice device);
+    vk::Error initDescriptorSets(ContextVk *contextVk);
+    gl::Error initDefaultUniformBlocks(const gl::Context *glContext);
+    vk::Error updateDefaultUniformsDescriptorSet(ContextVk *contextVk);
+
+    template <typename T>
+    void setUniformImpl(GLint location, GLsizei count, const T *v, GLenum entryPointType);
+
     vk::ShaderModule mLinkedVertexModule;
     vk::ShaderModule mLinkedFragmentModule;
-    vk::PipelineLayout mPipelineLayout;
+
+    // State for the default uniform blocks.
+    struct DefaultUniformBlock final : private angle::NonCopyable
+    {
+        DefaultUniformBlock();
+        ~DefaultUniformBlock();
+
+        vk::BufferAndMemory storage;
+
+        // Shadow copies of the shader uniform data.
+        angle::MemoryBuffer uniformData;
+        bool uniformsDirty;
+
+        // Since the default blocks are laid out in std140, this tells us where to write on a call
+        // to a setUniform method. They are arranged in uniform location order.
+        std::vector<sh::BlockMemberInfo> uniformLayout;
+    };
+
+    std::array<DefaultUniformBlock, 2> mDefaultUniformBlocks;
+
+    // This is a special "empty" placeholder buffer for when a shader has no uniforms.
+    // It is necessary because we want to keep a compatible pipeline layout in all cases,
+    // and Vulkan does not tolerate having null handles in a descriptor set.
+    vk::BufferAndMemory mEmptyUniformBlockStorage;
+
+    // Descriptor sets for uniform blocks and textures for this program.
+    std::vector<VkDescriptorSet> mDescriptorSets;
+    gl::RangeUI mUsedDescriptorSetRange;
+    bool mDirtyTextures;
+
+    template <typename T>
+    using ShaderTextureArray = std::array<T, gl::IMPLEMENTATION_MAX_SHADER_TEXTURES>;
 };
 
 }  // namespace rx
 
 #endif  // LIBANGLE_RENDERER_VULKAN_PROGRAMVK_H_
--- a/gfx/angle/src/libANGLE/renderer/vulkan/RenderbufferVk.cpp
+++ b/gfx/angle/src/libANGLE/renderer/vulkan/RenderbufferVk.cpp
@@ -51,9 +51,16 @@ gl::Error RenderbufferVk::getAttachmentR
                                                     GLenum binding,
                                                     const gl::ImageIndex &imageIndex,
                                                     FramebufferAttachmentRenderTarget **rtOut)
 {
     UNIMPLEMENTED();
     return gl::InternalError();
 }
 
+gl::Error RenderbufferVk::initializeContents(const gl::Context *context,
+                                             const gl::ImageIndex &imageIndex)
+{
+    UNIMPLEMENTED();
+    return gl::NoError();
+}
+
 }  // namespace rx
--- a/gfx/angle/src/libANGLE/renderer/vulkan/RenderbufferVk.h
+++ b/gfx/angle/src/libANGLE/renderer/vulkan/RenderbufferVk.h
@@ -31,13 +31,16 @@ class RenderbufferVk : public Renderbuff
                                     size_t width,
                                     size_t height) override;
     gl::Error setStorageEGLImageTarget(const gl::Context *context, egl::Image *image) override;
 
     gl::Error getAttachmentRenderTarget(const gl::Context *context,
                                         GLenum binding,
                                         const gl::ImageIndex &imageIndex,
                                         FramebufferAttachmentRenderTarget **rtOut) override;
+
+    gl::Error initializeContents(const gl::Context *context,
+                                 const gl::ImageIndex &imageIndex) override;
 };
 
 }  // namespace rx
 
 #endif  // LIBANGLE_RENDERER_VULKAN_RENDERBUFFERVK_H_
--- a/gfx/angle/src/libANGLE/renderer/vulkan/RendererVk.cpp
+++ b/gfx/angle/src/libANGLE/renderer/vulkan/RendererVk.cpp
@@ -12,16 +12,17 @@
 // Placing this first seems to solve an intellisense bug.
 #include "libANGLE/renderer/vulkan/renderervk_utils.h"
 
 #include <EGL/eglext.h>
 
 #include "common/debug.h"
 #include "common/system_utils.h"
 #include "libANGLE/renderer/driver_utils.h"
+#include "libANGLE/renderer/vulkan/CommandBufferNode.h"
 #include "libANGLE/renderer/vulkan/CompilerVk.h"
 #include "libANGLE/renderer/vulkan/FramebufferVk.h"
 #include "libANGLE/renderer/vulkan/GlslangWrapper.h"
 #include "libANGLE/renderer/vulkan/TextureVk.h"
 #include "libANGLE/renderer/vulkan/VertexArrayVk.h"
 #include "libANGLE/renderer/vulkan/formatutilsvk.h"
 #include "platform/Platform.h"
 
@@ -36,17 +37,17 @@ VkResult VerifyExtensionsPresent(const s
 {
     // Compile the extensions names into a set.
     std::set<std::string> extensionNames;
     for (const auto &extensionProp : extensionProps)
     {
         extensionNames.insert(extensionProp.extensionName);
     }
 
-    for (const auto &extensionName : enabledExtensionNames)
+    for (const char *extensionName : enabledExtensionNames)
     {
         if (extensionNames.count(extensionName) == 0)
         {
             return VK_ERROR_EXTENSION_NOT_PRESENT;
         }
     }
 
     return VK_SUCCESS;
@@ -79,55 +80,177 @@ VkBool32 VKAPI_CALL DebugReportCallback(
         // WARN() << message;
     }
 
     return VK_FALSE;
 }
 
 }  // anonymous namespace
 
+// RenderPassCache implementation.
+RenderPassCache::RenderPassCache()
+{
+}
+
+RenderPassCache::~RenderPassCache()
+{
+    ASSERT(mPayload.empty());
+}
+
+void RenderPassCache::destroy(VkDevice device)
+{
+    for (auto &outerIt : mPayload)
+    {
+        for (auto &innerIt : outerIt.second)
+        {
+            innerIt.second.get().destroy(device);
+        }
+    }
+    mPayload.clear();
+}
+
+vk::Error RenderPassCache::getCompatibleRenderPass(VkDevice device,
+                                                   Serial serial,
+                                                   const vk::RenderPassDesc &desc,
+                                                   vk::RenderPass **renderPassOut)
+{
+    auto outerIt = mPayload.find(desc);
+    if (outerIt != mPayload.end())
+    {
+        InnerCache &innerCache = outerIt->second;
+        ASSERT(!innerCache.empty());
+
+        // Find the first element and return it.
+        *renderPassOut = &innerCache.begin()->second.get();
+        return vk::NoError();
+    }
+
+    // Insert some dummy attachment ops.
+    // TODO(jmadill): Pre-populate the cache in the Renderer so we rarely miss here.
+    vk::AttachmentOpsArray ops;
+    for (uint32_t colorIndex = 0; colorIndex < desc.colorAttachmentCount(); ++colorIndex)
+    {
+        ops.initDummyOp(colorIndex, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL);
+    }
+
+    if (desc.depthStencilAttachmentCount() > 0)
+    {
+        ops.initDummyOp(desc.colorAttachmentCount(),
+                        VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL);
+    }
+
+    return getRenderPassWithOps(device, serial, desc, ops, renderPassOut);
+}
+
+vk::Error RenderPassCache::getRenderPassWithOps(VkDevice device,
+                                                Serial serial,
+                                                const vk::RenderPassDesc &desc,
+                                                const vk::AttachmentOpsArray &attachmentOps,
+                                                vk::RenderPass **renderPassOut)
+{
+    auto outerIt = mPayload.find(desc);
+    if (outerIt != mPayload.end())
+    {
+        InnerCache &innerCache = outerIt->second;
+
+        auto innerIt = innerCache.find(attachmentOps);
+        if (innerIt != innerCache.end())
+        {
+            // Update the serial before we return.
+            // TODO(jmadill): Could possibly use an MRU cache here.
+            innerIt->second.updateSerial(serial);
+            *renderPassOut = &innerIt->second.get();
+            return vk::NoError();
+        }
+    }
+    else
+    {
+        auto emplaceResult = mPayload.emplace(desc, InnerCache());
+        outerIt            = emplaceResult.first;
+    }
+
+    vk::RenderPass newRenderPass;
+    ANGLE_TRY(vk::InitializeRenderPassFromDesc(device, desc, attachmentOps, &newRenderPass));
+
+    vk::RenderPassAndSerial withSerial(std::move(newRenderPass), serial);
+
+    InnerCache &innerCache = outerIt->second;
+    auto insertPos         = innerCache.emplace(attachmentOps, std::move(withSerial));
+    *renderPassOut = &insertPos.first->second.get();
+
+    // TODO(jmadill): Trim cache, and pre-populate with the most common RPs on startup.
+    return vk::NoError();
+}
+
+// CommandBatch implementation.
+RendererVk::CommandBatch::CommandBatch()
+{
+}
+
+RendererVk::CommandBatch::~CommandBatch()
+{
+}
+
+RendererVk::CommandBatch::CommandBatch(CommandBatch &&other)
+    : commandPool(std::move(other.commandPool)), fence(std::move(other.fence)), serial(other.serial)
+{
+}
+
+RendererVk::CommandBatch &RendererVk::CommandBatch::operator=(CommandBatch &&other)
+{
+    std::swap(commandPool, other.commandPool);
+    std::swap(fence, other.fence);
+    std::swap(serial, other.serial);
+    return *this;
+}
+
+// RendererVk implementation.
 RendererVk::RendererVk()
     : mCapsInitialized(false),
       mInstance(VK_NULL_HANDLE),
       mEnableValidationLayers(false),
       mDebugReportCallback(VK_NULL_HANDLE),
       mPhysicalDevice(VK_NULL_HANDLE),
       mQueue(VK_NULL_HANDLE),
       mCurrentQueueFamilyIndex(std::numeric_limits<uint32_t>::max()),
       mDevice(VK_NULL_HANDLE),
-      mHostVisibleMemoryIndex(std::numeric_limits<uint32_t>::max()),
       mGlslangWrapper(nullptr),
       mLastCompletedQueueSerial(mQueueSerialFactory.generate()),
       mCurrentQueueSerial(mQueueSerialFactory.generate()),
       mInFlightCommands()
 {
 }
 
 RendererVk::~RendererVk()
 {
-    if (!mInFlightCommands.empty() || !mInFlightFences.empty() || !mGarbage.empty())
+    if (!mInFlightCommands.empty() || !mGarbage.empty())
     {
-        vk::Error error = finish();
+        // TODO(jmadill): Not nice to pass nullptr here, but shouldn't be a problem.
+        vk::Error error = finish(nullptr);
         if (error.isError())
         {
             ERR() << "Error during VK shutdown: " << error;
         }
     }
 
+    for (auto &descriptorSetLayout : mGraphicsDescriptorSetLayouts)
+    {
+        descriptorSetLayout.destroy(mDevice);
+    }
+
+    mGraphicsPipelineLayout.destroy(mDevice);
+
+    mRenderPassCache.destroy(mDevice);
+
     if (mGlslangWrapper)
     {
         GlslangWrapper::ReleaseReference();
         mGlslangWrapper = nullptr;
     }
 
-    if (mCommandBuffer.valid())
-    {
-        mCommandBuffer.destroy(mDevice);
-    }
-
     if (mCommandPool.valid())
     {
         mCommandPool.destroy(mDevice);
     }
 
     if (mDevice)
     {
         vkDestroyDevice(mDevice, nullptr);
@@ -333,34 +456,27 @@ vk::Error RendererVk::initialize(const e
 
     // If only one queue family, go ahead and initialize the device. If there is more than one
     // queue, we'll have to wait until we see a WindowSurface to know which supports present.
     if (graphicsQueueFamilyCount == 1)
     {
         ANGLE_TRY(initializeDevice(firstGraphicsQueueFamily));
     }
 
-    VkPhysicalDeviceMemoryProperties memoryProperties;
-    vkGetPhysicalDeviceMemoryProperties(mPhysicalDevice, &memoryProperties);
-
-    for (uint32_t memoryIndex = 0; memoryIndex < memoryProperties.memoryTypeCount; ++memoryIndex)
-    {
-        if ((memoryProperties.memoryTypes[memoryIndex].propertyFlags &
-             VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT) != 0)
-        {
-            mHostVisibleMemoryIndex = memoryIndex;
-            break;
-        }
-    }
-
-    ANGLE_VK_CHECK(mHostVisibleMemoryIndex < std::numeric_limits<uint32_t>::max(),
-                   VK_ERROR_INITIALIZATION_FAILED);
+    // Store the physical device memory properties so we can find the right memory pools.
+    mMemoryProperties.init(mPhysicalDevice);
 
     mGlslangWrapper = GlslangWrapper::GetReference();
 
+    // Initialize the format table.
+    mFormatTable.initialize(mPhysicalDevice, &mNativeTextureCaps);
+
+    // Initialize the pipeline layout for GL programs.
+    ANGLE_TRY(initGraphicsPipelineLayout());
+
     return vk::NoError();
 }
 
 vk::Error RendererVk::initializeDevice(uint32_t queueFamilyIndex)
 {
     uint32_t deviceLayerCount = 0;
     ANGLE_VK_TRY(vkEnumerateDeviceLayerProperties(mPhysicalDevice, &deviceLayerCount, nullptr));
 
@@ -426,26 +542,23 @@ vk::Error RendererVk::initializeDevice(u
     ANGLE_VK_TRY(vkCreateDevice(mPhysicalDevice, &createInfo, nullptr, &mDevice));
 
     mCurrentQueueFamilyIndex = queueFamilyIndex;
 
     vkGetDeviceQueue(mDevice, mCurrentQueueFamilyIndex, 0, &mQueue);
 
     // Initialize the command pool now that we know the queue family index.
     VkCommandPoolCreateInfo commandPoolInfo;
-    commandPoolInfo.sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO;
-    commandPoolInfo.pNext = nullptr;
-    // TODO(jmadill): Investigate transient command buffers.
-    commandPoolInfo.flags            = VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT;
+    commandPoolInfo.sType            = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO;
+    commandPoolInfo.pNext            = nullptr;
+    commandPoolInfo.flags            = VK_COMMAND_POOL_CREATE_TRANSIENT_BIT;
     commandPoolInfo.queueFamilyIndex = mCurrentQueueFamilyIndex;
 
     ANGLE_TRY(mCommandPool.init(mDevice, commandPoolInfo));
 
-    mCommandBuffer.setCommandPool(&mCommandPool);
-
     return vk::NoError();
 }
 
 vk::ErrorOrResult<uint32_t> RendererVk::selectPresentQueueForSurface(VkSurfaceKHR surface)
 {
     // We've already initialized a device, and can't re-create it unless it's never been used.
     // TODO(jmadill): Handle the re-creation case if necessary.
     if (mDevice != VK_NULL_HANDLE)
@@ -535,16 +648,24 @@ void RendererVk::generateCaps(gl::Caps *
                               gl::TextureCapsMap * /*outTextureCaps*/,
                               gl::Extensions *outExtensions,
                               gl::Limitations * /* outLimitations */) const
 {
     // TODO(jmadill): Caps.
     outCaps->maxDrawBuffers      = 1;
     outCaps->maxVertexAttributes     = gl::MAX_VERTEX_ATTRIBS;
     outCaps->maxVertexAttribBindings = gl::MAX_VERTEX_ATTRIB_BINDINGS;
+    outCaps->maxVaryingVectors            = 16;
+    outCaps->maxTextureImageUnits         = 1;
+    outCaps->maxCombinedTextureImageUnits = 1;
+    outCaps->max2DTextureSize             = 1024;
+    outCaps->maxElementIndex              = std::numeric_limits<GLuint>::max() - 1;
+    outCaps->maxFragmentUniformVectors    = 8;
+    outCaps->maxVertexUniformVectors      = 8;
+    outCaps->maxColorAttachments          = 1;
 
     // Enable this for simple buffer readback testing, but some functionality is missing.
     // TODO(jmadill): Support full mapBufferRange extension.
     outExtensions->mapBuffer      = true;
     outExtensions->mapBufferRange = true;
 }
 
 const gl::Caps &RendererVk::getNativeCaps() const
@@ -566,231 +687,387 @@ const gl::Extensions &RendererVk::getNat
 }
 
 const gl::Limitations &RendererVk::getNativeLimitations() const
 {
     ensureCapsInitialized();
     return mNativeLimitations;
 }
 
-vk::Error RendererVk::getStartedCommandBuffer(vk::CommandBuffer **commandBufferOut)
-{
-    ANGLE_TRY(mCommandBuffer.begin(mDevice));
-    *commandBufferOut = &mCommandBuffer;
-    return vk::NoError();
-}
-
-vk::Error RendererVk::submitCommandBuffer(vk::CommandBuffer *commandBuffer)
+const vk::CommandPool &RendererVk::getCommandPool() const
 {
-    ANGLE_TRY(commandBuffer->end());
-
-    VkFenceCreateInfo fenceInfo;
-    fenceInfo.sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO;
-    fenceInfo.pNext = nullptr;
-    fenceInfo.flags = 0;
-
-    VkSubmitInfo submitInfo;
-    submitInfo.sType                = VK_STRUCTURE_TYPE_SUBMIT_INFO;
-    submitInfo.pNext                = nullptr;
-    submitInfo.waitSemaphoreCount   = 0;
-    submitInfo.pWaitSemaphores      = nullptr;
-    submitInfo.pWaitDstStageMask    = nullptr;
-    submitInfo.commandBufferCount   = 1;
-    submitInfo.pCommandBuffers      = commandBuffer->ptr();
-    submitInfo.signalSemaphoreCount = 0;
-    submitInfo.pSignalSemaphores    = nullptr;
-
-    // TODO(jmadill): Investigate how to properly submit command buffers.
-    ANGLE_TRY(submit(submitInfo));
-
-    return vk::NoError();
+    return mCommandPool;
 }
 
-vk::Error RendererVk::submitAndFinishCommandBuffer(vk::CommandBuffer *commandBuffer)
+vk::Error RendererVk::finish(const gl::Context *context)
 {
-    ANGLE_TRY(submitCommandBuffer(commandBuffer));
-    ANGLE_TRY(finish());
-
-    return vk::NoError();
-}
-
-vk::Error RendererVk::submitCommandsWithSync(vk::CommandBuffer *commandBuffer,
-                                             const vk::Semaphore &waitSemaphore,
-                                             const vk::Semaphore &signalSemaphore)
-{
-    ANGLE_TRY(commandBuffer->end());
-
-    VkPipelineStageFlags waitStageMask  = VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT;
+    if (!mOpenCommandGraph.empty())
+    {
+        vk::CommandBuffer commandBatch;
+        ANGLE_TRY(flushCommandGraph(context, &commandBatch));
 
-    VkSubmitInfo submitInfo;
-    submitInfo.sType                = VK_STRUCTURE_TYPE_SUBMIT_INFO;
-    submitInfo.pNext                = nullptr;
-    submitInfo.waitSemaphoreCount   = 1;
-    submitInfo.pWaitSemaphores      = waitSemaphore.ptr();
-    submitInfo.pWaitDstStageMask    = &waitStageMask;
-    submitInfo.commandBufferCount   = 1;
-    submitInfo.pCommandBuffers      = commandBuffer->ptr();
-    submitInfo.signalSemaphoreCount = 1;
-    submitInfo.pSignalSemaphores    = signalSemaphore.ptr();
+        VkSubmitInfo submitInfo;
+        submitInfo.sType                = VK_STRUCTURE_TYPE_SUBMIT_INFO;
+        submitInfo.pNext                = nullptr;
+        submitInfo.waitSemaphoreCount   = 0;
+        submitInfo.pWaitSemaphores      = nullptr;
+        submitInfo.pWaitDstStageMask    = nullptr;
+        submitInfo.commandBufferCount   = 1;
+        submitInfo.pCommandBuffers      = commandBatch.ptr();
+        submitInfo.signalSemaphoreCount = 0;
+        submitInfo.pSignalSemaphores    = nullptr;
 
-    // TODO(jmadill): Investigate how to properly queue command buffer work.
-    ANGLE_TRY(submitFrame(submitInfo));
+        ANGLE_TRY(submitFrame(submitInfo, std::move(commandBatch)));
+    }
 
-    return vk::NoError();
-}
-
-vk::Error RendererVk::finish()
-{
     ASSERT(mQueue != VK_NULL_HANDLE);
     ANGLE_VK_TRY(vkQueueWaitIdle(mQueue));
     freeAllInFlightResources();
     return vk::NoError();
 }
 
 void RendererVk::freeAllInFlightResources()
 {
-    for (auto &fence : mInFlightFences)
+    for (CommandBatch &batch : mInFlightCommands)
     {
-        fence.destroy(mDevice);
-    }
-    mInFlightFences.clear();
-
-    for (auto &command : mInFlightCommands)
-    {
-        command.destroy(mDevice);
+        batch.fence.destroy(mDevice);
+        batch.commandPool.destroy(mDevice);
     }
     mInFlightCommands.clear();
 
     for (auto &garbage : mGarbage)
     {
-        garbage->destroy(mDevice);
+        garbage.destroy(mDevice);
     }
     mGarbage.clear();
 }
 
 vk::Error RendererVk::checkInFlightCommands()
 {
-    size_t finishedIndex = 0;
+    int finishedCount = 0;
 
-    // Check if any in-flight command buffers are finished.
-    for (size_t index = 0; index < mInFlightFences.size(); index++)
+    for (CommandBatch &batch : mInFlightCommands)
     {
-        auto *inFlightFence = &mInFlightFences[index];
-
-        VkResult result = inFlightFence->get().getStatus(mDevice);
+        VkResult result = batch.fence.getStatus(mDevice);
         if (result == VK_NOT_READY)
             break;
-        ANGLE_VK_TRY(result);
-        finishedIndex = index + 1;
 
-        // Release the fence handle.
-        // TODO(jmadill): Re-use fences.
-        inFlightFence->destroy(mDevice);
+        ANGLE_VK_TRY(result);
+        ASSERT(batch.serial > mLastCompletedQueueSerial);
+        mLastCompletedQueueSerial = batch.serial;
+
+        batch.fence.destroy(mDevice);
+        batch.commandPool.destroy(mDevice);
+        ++finishedCount;
     }
 
-    if (finishedIndex == 0)
-        return vk::NoError();
-
-    Serial finishedSerial = mInFlightFences[finishedIndex - 1].queueSerial();
-    mInFlightFences.erase(mInFlightFences.begin(), mInFlightFences.begin() + finishedIndex);
-
-    size_t completedCBIndex = 0;
-    for (size_t cbIndex = 0; cbIndex < mInFlightCommands.size(); ++cbIndex)
-    {
-        auto *inFlightCB = &mInFlightCommands[cbIndex];
-        if (inFlightCB->queueSerial() > finishedSerial)
-            break;
-
-        completedCBIndex = cbIndex + 1;
-        inFlightCB->destroy(mDevice);
-    }
-
-    if (completedCBIndex == 0)
-        return vk::NoError();
-
-    mInFlightCommands.erase(mInFlightCommands.begin(),
-                            mInFlightCommands.begin() + completedCBIndex);
+    mInFlightCommands.erase(mInFlightCommands.begin(), mInFlightCommands.begin() + finishedCount);
 
     size_t freeIndex = 0;
     for (; freeIndex < mGarbage.size(); ++freeIndex)
     {
-        if (!mGarbage[freeIndex]->destroyIfComplete(mDevice, finishedSerial))
+        if (!mGarbage[freeIndex].destroyIfComplete(mDevice, mLastCompletedQueueSerial))
             break;
     }
 
     // Remove the entries from the garbage list - they should be ready to go.
     if (freeIndex > 0)
     {
         mGarbage.erase(mGarbage.begin(), mGarbage.begin() + freeIndex);
     }
 
     return vk::NoError();
 }
 
-vk::Error RendererVk::submit(const VkSubmitInfo &submitInfo)
+vk::Error RendererVk::submitFrame(const VkSubmitInfo &submitInfo, vk::CommandBuffer &&commandBuffer)
 {
-    ANGLE_VK_TRY(vkQueueSubmit(mQueue, 1, &submitInfo, VK_NULL_HANDLE));
+    VkFenceCreateInfo fenceInfo;
+    fenceInfo.sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO;
+    fenceInfo.pNext = nullptr;
+    fenceInfo.flags = 0;
+
+    CommandBatch batch;
+    ANGLE_TRY(batch.fence.init(mDevice, fenceInfo));
+
+    ANGLE_VK_TRY(vkQueueSubmit(mQueue, 1, &submitInfo, batch.fence.getHandle()));
 
     // Store this command buffer in the in-flight list.
-    mInFlightCommands.emplace_back(std::move(mCommandBuffer), mCurrentQueueSerial);
-
-    // Sanity check.
-    ASSERT(mInFlightCommands.size() < 1000u);
-
-    // Increment the queue serial. If this fails, we should restart ANGLE.
-    // TODO(jmadill): Overflow check.
-    mCurrentQueueSerial = mQueueSerialFactory.generate();
-
-    return vk::NoError();
-}
+    batch.commandPool = std::move(mCommandPool);
+    batch.serial      = mCurrentQueueSerial;
 
-vk::Error RendererVk::submitFrame(const VkSubmitInfo &submitInfo)
-{
-    VkFenceCreateInfo createInfo;
-    createInfo.sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO;
-    createInfo.pNext = nullptr;
-    createInfo.flags = 0;
-
-    vk::Fence fence;
-    ANGLE_TRY(fence.init(mDevice, createInfo));
-
-    ANGLE_VK_TRY(vkQueueSubmit(mQueue, 1, &submitInfo, fence.getHandle()));
-
-    // Store this command buffer in the in-flight list.
-    mInFlightFences.emplace_back(std::move(fence), mCurrentQueueSerial);
-    mInFlightCommands.emplace_back(std::move(mCommandBuffer), mCurrentQueueSerial);
+    mInFlightCommands.emplace_back(std::move(batch));
 
     // Sanity check.
     ASSERT(mInFlightCommands.size() < 1000u);
 
     // Increment the queue serial. If this fails, we should restart ANGLE.
     // TODO(jmadill): Overflow check.
     mCurrentQueueSerial = mQueueSerialFactory.generate();
 
     ANGLE_TRY(checkInFlightCommands());
 
+    // Simply null out the command buffer here - it was allocated using the command pool.
+    commandBuffer.releaseHandle();
+
+    // Reallocate the command pool for next frame.
+    // TODO(jmadill): Consider reusing command pools.
+    VkCommandPoolCreateInfo poolInfo;
+    poolInfo.sType            = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO;
+    poolInfo.pNext            = nullptr;
+    poolInfo.flags            = 0;
+    poolInfo.queueFamilyIndex = mCurrentQueueFamilyIndex;
+
+    mCommandPool.init(mDevice, poolInfo);
+
     return vk::NoError();
 }
 
 vk::Error RendererVk::createStagingImage(TextureDimension dimension,
                                          const vk::Format &format,
                                          const gl::Extents &extent,
+                                         vk::StagingUsage usage,
                                          vk::StagingImage *imageOut)
 {
-    ASSERT(mHostVisibleMemoryIndex != std::numeric_limits<uint32_t>::max());
-
-    ANGLE_TRY(imageOut->init(mDevice, mCurrentQueueFamilyIndex, mHostVisibleMemoryIndex, dimension,
-                             format.native, extent));
-
+    ANGLE_TRY(imageOut->init(mDevice, mCurrentQueueFamilyIndex, mMemoryProperties, dimension,
+                             format.vkTextureFormat, extent, usage));
     return vk::NoError();
 }
 
 GlslangWrapper *RendererVk::getGlslangWrapper()
 {
     return mGlslangWrapper;
 }
 
 Serial RendererVk::getCurrentQueueSerial() const
 {
     return mCurrentQueueSerial;
 }
 
+bool RendererVk::isResourceInUse(const ResourceVk &resource)
+{
+    return isSerialInUse(resource.getQueueSerial());
+}
+
+bool RendererVk::isSerialInUse(Serial serial)
+{
+    return serial > mLastCompletedQueueSerial;
+}
+
+vk::Error RendererVk::getCompatibleRenderPass(const vk::RenderPassDesc &desc,
+                                              vk::RenderPass **renderPassOut)
+{
+    return mRenderPassCache.getCompatibleRenderPass(mDevice, mCurrentQueueSerial, desc,
+                                                    renderPassOut);
+}
+
+vk::Error RendererVk::getRenderPassWithOps(const vk::RenderPassDesc &desc,
+                                           const vk::AttachmentOpsArray &ops,
+                                           vk::RenderPass **renderPassOut)
+{
+    return mRenderPassCache.getRenderPassWithOps(mDevice, mCurrentQueueSerial, desc, ops,
+                                                 renderPassOut);
+}
+
+vk::CommandBufferNode *RendererVk::allocateCommandNode()
+{
+    // TODO(jmadill): Use a pool allocator for the CPU node allocations.
+    vk::CommandBufferNode *newCommands = new vk::CommandBufferNode();
+    mOpenCommandGraph.emplace_back(newCommands);
+    return newCommands;
+}
+
+vk::Error RendererVk::flushCommandGraph(const gl::Context *context, vk::CommandBuffer *commandBatch)
+{
+    VkCommandBufferAllocateInfo primaryInfo;
+    primaryInfo.sType              = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO;
+    primaryInfo.pNext              = nullptr;
+    primaryInfo.commandPool        = mCommandPool.getHandle();
+    primaryInfo.level              = VK_COMMAND_BUFFER_LEVEL_PRIMARY;
+    primaryInfo.commandBufferCount = 1;
+
+    ANGLE_TRY(commandBatch->init(mDevice, primaryInfo));
+
+    if (mOpenCommandGraph.empty())
+    {
+        return vk::NoError();
+    }
+
+    std::vector<vk::CommandBufferNode *> nodeStack;
+
+    VkCommandBufferBeginInfo beginInfo;
+    beginInfo.sType            = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
+    beginInfo.pNext            = nullptr;
+    beginInfo.flags            = 0;
+    beginInfo.pInheritanceInfo = nullptr;
+
+    ANGLE_TRY(commandBatch->begin(beginInfo));
+
+    for (vk::CommandBufferNode *topLevelNode : mOpenCommandGraph)
+    {
+        // Only process commands that don't have child commands. The others will be pulled in
+        // automatically. Also skip commands that have already been visited.
+        if (topLevelNode->isDependency() ||
+            topLevelNode->visitedState() != vk::VisitedState::Unvisited)
+            continue;
+
+        nodeStack.push_back(topLevelNode);
+
+        while (!nodeStack.empty())
+        {
+            vk::CommandBufferNode *node = nodeStack.back();
+
+            switch (node->visitedState())
+            {
+                case vk::VisitedState::Unvisited:
+                    node->visitDependencies(&nodeStack);
+                    break;
+                case vk::VisitedState::Ready:
+                    ANGLE_TRY(node->visitAndExecute(this, commandBatch));
+                    nodeStack.pop_back();
+                    break;
+                case vk::VisitedState::Visited:
+                    nodeStack.pop_back();
+                    break;
+                default:
+                    UNREACHABLE();
+                    break;
+            }
+        }
+    }
+
+    ANGLE_TRY(commandBatch->end());
+    resetCommandGraph();
+    return vk::NoError();
+}
+
+void RendererVk::resetCommandGraph()
+{
+    // TODO(jmadill): Use pool allocation so we don't need to deallocate command graph.
+    for (vk::CommandBufferNode *node : mOpenCommandGraph)
+    {
+        delete node;
+    }
+    mOpenCommandGraph.clear();
+}
+
+vk::Error RendererVk::flush(const gl::Context *context,
+                            const vk::Semaphore &waitSemaphore,
+                            const vk::Semaphore &signalSemaphore)
+{
+    vk::CommandBuffer commandBatch;
+    ANGLE_TRY(flushCommandGraph(context, &commandBatch));
+
+    VkPipelineStageFlags waitStageMask = VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT;
+
+    VkSubmitInfo submitInfo;
+    submitInfo.sType                = VK_STRUCTURE_TYPE_SUBMIT_INFO;
+    submitInfo.pNext                = nullptr;
+    submitInfo.waitSemaphoreCount   = 1;
+    submitInfo.pWaitSemaphores      = waitSemaphore.ptr();
+    submitInfo.pWaitDstStageMask    = &waitStageMask;
+    submitInfo.commandBufferCount   = 1;
+    submitInfo.pCommandBuffers      = commandBatch.ptr();
+    submitInfo.signalSemaphoreCount = 1;
+    submitInfo.pSignalSemaphores    = signalSemaphore.ptr();
+
+    ANGLE_TRY(submitFrame(submitInfo, std::move(commandBatch)));
+    return vk::NoError();
+}
+
+const vk::PipelineLayout &RendererVk::getGraphicsPipelineLayout() const
+{
+    return mGraphicsPipelineLayout;
+}
+
+const std::vector<vk::DescriptorSetLayout> &RendererVk::getGraphicsDescriptorSetLayouts() const
+{
+    return mGraphicsDescriptorSetLayouts;
+}
+
+vk::Error RendererVk::initGraphicsPipelineLayout()
+{
+    ASSERT(!mGraphicsPipelineLayout.valid());
+
+    // Create two descriptor set layouts: one for default uniform info, and one for textures.
+    // Skip one or both if there are no uniforms.
+    VkDescriptorSetLayoutBinding uniformBindings[2];
+    uint32_t blockCount = 0;
+
+    {
+        auto &layoutBinding = uniformBindings[blockCount];
+
+        layoutBinding.binding            = blockCount;
+        layoutBinding.descriptorType     = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
+        layoutBinding.descriptorCount    = 1;
+        layoutBinding.stageFlags         = VK_SHADER_STAGE_VERTEX_BIT;
+        layoutBinding.pImmutableSamplers = nullptr;
+
+        blockCount++;
+    }
+
+    {
+        auto &layoutBinding = uniformBindings[blockCount];
+
+        layoutBinding.binding            = blockCount;
+        layoutBinding.descriptorType     = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
+        layoutBinding.descriptorCount    = 1;
+        layoutBinding.stageFlags         = VK_SHADER_STAGE_FRAGMENT_BIT;
+        layoutBinding.pImmutableSamplers = nullptr;
+
+        blockCount++;
+    }
+
+    {
+        VkDescriptorSetLayoutCreateInfo uniformInfo;
+        uniformInfo.sType        = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO;
+        uniformInfo.pNext        = nullptr;
+        uniformInfo.flags        = 0;
+        uniformInfo.bindingCount = blockCount;
+        uniformInfo.pBindings    = uniformBindings;
+
+        vk::DescriptorSetLayout uniformLayout;
+        ANGLE_TRY(uniformLayout.init(mDevice, uniformInfo));
+        mGraphicsDescriptorSetLayouts.push_back(std::move(uniformLayout));
+    }
+
+    std::array<VkDescriptorSetLayoutBinding, gl::IMPLEMENTATION_MAX_ACTIVE_TEXTURES>
+        textureBindings;
+
+    // TODO(jmadill): This approach might not work well for texture arrays.
+    for (uint32_t textureIndex = 0; textureIndex < gl::IMPLEMENTATION_MAX_ACTIVE_TEXTURES;
+         ++textureIndex)
+    {
+        VkDescriptorSetLayoutBinding &layoutBinding = textureBindings[textureIndex];
+
+        layoutBinding.binding         = textureIndex;
+        layoutBinding.descriptorType  = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER;
+        layoutBinding.descriptorCount = 1;
+        layoutBinding.stageFlags      = (VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_FRAGMENT_BIT);
+        layoutBinding.pImmutableSamplers = nullptr;
+    }
+
+    {
+        VkDescriptorSetLayoutCreateInfo textureInfo;
+        textureInfo.sType        = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO;
+        textureInfo.pNext        = nullptr;
+        textureInfo.flags        = 0;
+        textureInfo.bindingCount = static_cast<uint32_t>(textureBindings.size());
+        textureInfo.pBindings    = textureBindings.data();
+
+        vk::DescriptorSetLayout textureLayout;
+        ANGLE_TRY(textureLayout.init(mDevice, textureInfo));
+        mGraphicsDescriptorSetLayouts.push_back(std::move(textureLayout));
+    }
+
+    VkPipelineLayoutCreateInfo createInfo;
+    createInfo.sType                  = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO;
+    createInfo.pNext                  = nullptr;
+    createInfo.flags                  = 0;
+    createInfo.setLayoutCount         = static_cast<uint32_t>(mGraphicsDescriptorSetLayouts.size());
+    createInfo.pSetLayouts            = mGraphicsDescriptorSetLayouts[0].ptr();
+    createInfo.pushConstantRangeCount = 0;
+    createInfo.pPushConstantRanges    = nullptr;
+
+    ANGLE_TRY(mGraphicsPipelineLayout.init(mDevice, createInfo));
+
+    return vk::NoError();
+}
 }  // namespace rx
--- a/gfx/angle/src/libANGLE/renderer/vulkan/RendererVk.h
+++ b/gfx/angle/src/libANGLE/renderer/vulkan/RendererVk.h
@@ -10,32 +10,62 @@
 #ifndef LIBANGLE_RENDERER_VULKAN_RENDERERVK_H_
 #define LIBANGLE_RENDERER_VULKAN_RENDERERVK_H_
 
 #include <memory>
 #include <vulkan/vulkan.h>
 
 #include "common/angleutils.h"
 #include "libANGLE/Caps.h"
+#include "libANGLE/renderer/vulkan/formatutilsvk.h"
 #include "libANGLE/renderer/vulkan/renderervk_utils.h"
 
 namespace egl
 {
 class AttributeMap;
 }
 
 namespace rx
 {
+class FramebufferVk;
 class GlslangWrapper;
 
 namespace vk
 {
 struct Format;
 }
 
+// TODO(jmadill): Add cache trimming.
+class RenderPassCache
+{
+  public:
+    RenderPassCache();
+    ~RenderPassCache();
+
+    void destroy(VkDevice device);
+
+    vk::Error getCompatibleRenderPass(VkDevice device,
+                                      Serial serial,
+                                      const vk::RenderPassDesc &desc,
+                                      vk::RenderPass **renderPassOut);
+    vk::Error getRenderPassWithOps(VkDevice device,
+                                   Serial serial,
+                                   const vk::RenderPassDesc &desc,
+                                   const vk::AttachmentOpsArray &attachmentOps,
+                                   vk::RenderPass **renderPassOut);
+
+  private:
+    // Use a two-layer caching scheme. The top level matches the "compatible" RenderPass elements.
+    // The second layer caches the attachment load/store ops and initial/final layout.
+    using InnerCache = std::unordered_map<vk::AttachmentOpsArray, vk::RenderPassAndSerial>;
+    using OuterCache = std::unordered_map<vk::RenderPassDesc, InnerCache>;
+
+    OuterCache mPayload;
+};
+
 class RendererVk : angle::NonCopyable
 {
   public:
     RendererVk();
     ~RendererVk();
 
     vk::Error initialize(const egl::AttributeMap &attribs, const char *wsiName);
 
@@ -44,94 +74,140 @@ class RendererVk : angle::NonCopyable
 
     VkInstance getInstance() const { return mInstance; }
     VkPhysicalDevice getPhysicalDevice() const { return mPhysicalDevice; }
     VkQueue getQueue() const { return mQueue; }
     VkDevice getDevice() const { return mDevice; }
 
     vk::ErrorOrResult<uint32_t> selectPresentQueueForSurface(VkSurfaceKHR surface);
 
-    // TODO(jmadill): Use ContextImpl for command buffers to enable threaded contexts.
-    vk::Error getStartedCommandBuffer(vk::CommandBuffer **commandBufferOut);
-    vk::Error submitCommandBuffer(vk::CommandBuffer *commandBuffer);
-    vk::Error submitAndFinishCommandBuffer(vk::CommandBuffer *commandBuffer);
-    vk::Error submitCommandsWithSync(vk::CommandBuffer *commandBuffer,
-                                     const vk::Semaphore &waitSemaphore,
-                                     const vk::Semaphore &signalSemaphore);
-    vk::Error finish();
+    vk::Error finish(const gl::Context *context);
+    vk::Error flush(const gl::Context *context,
+                    const vk::Semaphore &waitSemaphore,
+                    const vk::Semaphore &signalSemaphore);
+
+    const vk::CommandPool &getCommandPool() const;
 
     const gl::Caps &getNativeCaps() const;
     const gl::TextureCapsMap &getNativeTextureCaps() const;
     const gl::Extensions &getNativeExtensions() const;
     const gl::Limitations &getNativeLimitations() const;
 
     vk::Error createStagingImage(TextureDimension dimension,
                                  const vk::Format &format,
                                  const gl::Extents &extent,
+                                 vk::StagingUsage usage,
                                  vk::StagingImage *imageOut);
 
     GlslangWrapper *getGlslangWrapper();
 
     Serial getCurrentQueueSerial() const;
 
+    bool isResourceInUse(const ResourceVk &resource);
+    bool isSerialInUse(Serial serial);
+
     template <typename T>
-    void enqueueGarbage(Serial serial, T &&object)
+    void releaseResource(const ResourceVk &resource, T *object)
     {
-        mGarbage.emplace_back(std::unique_ptr<vk::GarbageObject<T>>(
-            new vk::GarbageObject<T>(serial, std::move(object))));
+        Serial resourceSerial = resource.getQueueSerial();
+        releaseObject(resourceSerial, object);
     }
 
     template <typename T>
-    void enqueueGarbageOrDeleteNow(const ResourceVk &resouce, T &&object)
+    void releaseObject(Serial resourceSerial, T *object)
     {
-        if (resouce.getDeleteSchedule(mLastCompletedQueueSerial) == DeleteSchedule::NOW)
+        if (!isSerialInUse(resourceSerial))
         {
-            object.destroy(mDevice);
+            object->destroy(mDevice);
         }
         else
         {
-            enqueueGarbage(resouce.getStoredQueueSerial(), std::move(object));
+            object->dumpResources(resourceSerial, &mGarbage);
         }
     }
 
+    uint32_t getQueueFamilyIndex() const { return mCurrentQueueFamilyIndex; }
+
+    const vk::MemoryProperties &getMemoryProperties() const { return mMemoryProperties; }
+
+    // TODO(jmadill): We could pass angle::Format::ID here.
+    const vk::Format &getFormat(GLenum internalFormat) const
+    {
+        return mFormatTable[internalFormat];
+    }
+
+    vk::Error getCompatibleRenderPass(const vk::RenderPassDesc &desc,
+                                      vk::RenderPass **renderPassOut);
+    vk::Error getRenderPassWithOps(const vk::RenderPassDesc &desc,
+                                   const vk::AttachmentOpsArray &ops,
+                                   vk::RenderPass **renderPassOut);
+
+    // This should only be called from ResourceVk.
+    // TODO(jmadill): Keep in ContextVk to enable threaded rendering.
+    vk::CommandBufferNode *allocateCommandNode();
+
+    const vk::PipelineLayout &getGraphicsPipelineLayout() const;
+    const std::vector<vk::DescriptorSetLayout> &getGraphicsDescriptorSetLayouts() const;
+
   private:
+    vk::Error initializeDevice(uint32_t queueFamilyIndex);
     void ensureCapsInitialized() const;
     void generateCaps(gl::Caps *outCaps,
                       gl::TextureCapsMap *outTextureCaps,
                       gl::Extensions *outExtensions,
                       gl::Limitations *outLimitations) const;
-    vk::Error submit(const VkSubmitInfo &submitInfo);
-    vk::Error submitFrame(const VkSubmitInfo &submitInfo);
+    vk::Error submitFrame(const VkSubmitInfo &submitInfo, vk::CommandBuffer &&commandBatch);
     vk::Error checkInFlightCommands();
     void freeAllInFlightResources();
+    vk::Error flushCommandGraph(const gl::Context *context, vk::CommandBuffer *commandBatch);
+    void resetCommandGraph();
+    vk::Error initGraphicsPipelineLayout();
 
     mutable bool mCapsInitialized;
     mutable gl::Caps mNativeCaps;
     mutable gl::TextureCapsMap mNativeTextureCaps;
     mutable gl::Extensions mNativeExtensions;
     mutable gl::Limitations mNativeLimitations;
 
-    vk::Error initializeDevice(uint32_t queueFamilyIndex);
-
     VkInstance mInstance;
     bool mEnableValidationLayers;
     VkDebugReportCallbackEXT mDebugReportCallback;
     VkPhysicalDevice mPhysicalDevice;
     VkPhysicalDeviceProperties mPhysicalDeviceProperties;
     std::vector<VkQueueFamilyProperties> mQueueFamilyProperties;
     VkQueue mQueue;
     uint32_t mCurrentQueueFamilyIndex;
     VkDevice mDevice;
     vk::CommandPool mCommandPool;
-    vk::CommandBuffer mCommandBuffer;
-    uint32_t mHostVisibleMemoryIndex;
     GlslangWrapper *mGlslangWrapper;
     SerialFactory mQueueSerialFactory;
     Serial mLastCompletedQueueSerial;
     Serial mCurrentQueueSerial;
-    std::vector<vk::CommandBufferAndSerial> mInFlightCommands;
-    std::vector<vk::FenceAndSerial> mInFlightFences;
-    std::vector<std::unique_ptr<vk::IGarbageObject>> mGarbage;
+
+    struct CommandBatch final : angle::NonCopyable
+    {
+        CommandBatch();
+        ~CommandBatch();
+        CommandBatch(CommandBatch &&other);
+        CommandBatch &operator=(CommandBatch &&other);
+
+        vk::CommandPool commandPool;
+        vk::Fence fence;
+        Serial serial;
+    };
+
+    std::vector<CommandBatch> mInFlightCommands;
+    std::vector<vk::GarbageObject> mGarbage;
+    vk::MemoryProperties mMemoryProperties;
+    vk::FormatTable mFormatTable;
+
+    RenderPassCache mRenderPassCache;
+    std::vector<vk::CommandBufferNode *> mOpenCommandGraph;
+
+    // ANGLE uses a single pipeline layout for all GL programs. It is owned here in the Renderer.
+    // See the design doc for an overview of the pipeline layout structure.
+    vk::PipelineLayout mGraphicsPipelineLayout;
+    std::vector<vk::DescriptorSetLayout> mGraphicsDescriptorSetLayouts;
 };
 
 }  // namespace rx
 
 #endif  // LIBANGLE_RENDERER_VULKAN_RENDERERVK_H_
--- a/gfx/angle/src/libANGLE/renderer/vulkan/SurfaceVk.cpp
+++ b/gfx/angle/src/libANGLE/renderer/vulkan/SurfaceVk.cpp
@@ -19,30 +19,30 @@
 #include "libANGLE/renderer/vulkan/formatutilsvk.h"
 
 namespace rx
 {
 
 namespace
 {
 
-const vk::Format &GetVkFormatFromConfig(const egl::Config &config)
+const vk::Format &GetVkFormatFromConfig(RendererVk *renderer, const egl::Config &config)
 {
     // TODO(jmadill): Properly handle format interpretation.
-    return vk::Format::Get(GL_BGRA8_EXT);
+    return renderer->getFormat(GL_BGRA8_EXT);
 }
 
 VkPresentModeKHR GetDesiredPresentMode(const std::vector<VkPresentModeKHR> &presentModes,
                                        EGLint minSwapInterval,
                                        EGLint maxSwapInterval)
 {
     ASSERT(!presentModes.empty());
 
     // Use FIFO mode for v-sync, since it throttles you to the display rate. Mailbox is more
-    // similar to triple-buffering. For now we hard-code Mailbox for perf tseting.
+    // similar to triple-buffering. For now we hard-code Mailbox for perf testing.
     // TODO(jmadill): Properly select present mode and re-create display if changed.
     VkPresentModeKHR bestChoice = VK_PRESENT_MODE_MAILBOX_KHR;
 
     for (auto presentMode : presentModes)
     {
         if (presentMode == bestChoice)
         {
             return bestChoice;
@@ -145,16 +145,27 @@ gl::Error OffscreenSurfaceVk::getAttachm
     GLenum /*binding*/,
     const gl::ImageIndex & /*imageIndex*/,
     FramebufferAttachmentRenderTarget ** /*rtOut*/)
 {
     UNREACHABLE();
     return gl::InternalError();
 }
 
+gl::Error OffscreenSurfaceVk::initializeContents(const gl::Context *context,
+                                                 const gl::ImageIndex &imageIndex)
+{
+    UNIMPLEMENTED();
+    return gl::NoError();
+}
+
+WindowSurfaceVk::SwapchainImage::SwapchainImage()                                        = default;
+WindowSurfaceVk::SwapchainImage::SwapchainImage(WindowSurfaceVk::SwapchainImage &&other) = default;
+WindowSurfaceVk::SwapchainImage::~SwapchainImage()                                       = default;
+
 WindowSurfaceVk::WindowSurfaceVk(const egl::SurfaceState &surfaceState,
                                  EGLNativeWindowType window,
                                  EGLint width,
                                  EGLint height)
     : SurfaceImpl(surfaceState),
       mNativeWindowType(window),
       mSurface(VK_NULL_HANDLE),
       mInstance(VK_NULL_HANDLE),
@@ -171,40 +182,34 @@ WindowSurfaceVk::WindowSurfaceVk(const e
 WindowSurfaceVk::~WindowSurfaceVk()
 {
     ASSERT(mSurface == VK_NULL_HANDLE);
     ASSERT(mSwapchain == VK_NULL_HANDLE);
 }
 
 void WindowSurfaceVk::destroy(const egl::Display *display)
 {
-    const DisplayVk *displayVk = GetImplAs<DisplayVk>(display);
+    const DisplayVk *displayVk = vk::GetImpl(display);
     RendererVk *rendererVk     = displayVk->getRenderer();
     VkDevice device            = rendererVk->getDevice();
     VkInstance instance        = rendererVk->getInstance();
 
-    rendererVk->finish();
-
-    mImageAvailableSemaphore.destroy(device);
-    mRenderingCompleteSemaphore.destroy(device);
+    rendererVk->finish(display->getProxyContext());
 
-    for (auto &imageView : mSwapchainImageViews)
-    {
-        imageView.destroy(device);
-    }
+    mAcquireNextImageSemaphore.destroy(device);
 
-    // Although we don't own the swapchain image handles, we need to keep our shutdown clean.
-    for (auto &image : mSwapchainImages)
+    for (auto &swapchainImage : mSwapchainImages)
     {
-        image.reset();
-    }
+        // Although we don't own the swapchain image handles, we need to keep our shutdown clean.
+        swapchainImage.image.reset();
 
-    for (auto &framebuffer : mSwapchainFramebuffers)
-    {
-        framebuffer.destroy(device);
+        swapchainImage.imageView.destroy(device);
+        swapchainImage.framebuffer.destroy(device);
+        swapchainImage.imageAcquiredSemaphore.destroy(device);
+        swapchainImage.commandsCompleteSemaphore.destroy(device);
     }
 
     if (mSwapchain)
     {
         vkDestroySwapchainKHR(device, mSwapchain, nullptr);
         mSwapchain = VK_NULL_HANDLE;
     }
 
@@ -212,29 +217,29 @@ void WindowSurfaceVk::destroy(const egl:
     {
         vkDestroySurfaceKHR(instance, mSurface, nullptr);
         mSurface = VK_NULL_HANDLE;
     }
 }
 
 egl::Error WindowSurfaceVk::initialize(const egl::Display *display)
 {
-    const DisplayVk *displayVk = GetImplAs<DisplayVk>(display);
+    const DisplayVk *displayVk = vk::GetImpl(display);
     return initializeImpl(displayVk->getRenderer()).toEGL(EGL_BAD_SURFACE);
 }
 
 vk::Error WindowSurfaceVk::initializeImpl(RendererVk *renderer)
 {
     gl::Extents windowSize;
     ANGLE_TRY_RESULT(createSurfaceVk(renderer), windowSize);
 
     uint32_t presentQueue = 0;
     ANGLE_TRY_RESULT(renderer->selectPresentQueueForSurface(mSurface), presentQueue);
 
-    const auto &physicalDevice = renderer->getPhysicalDevice();
+    const VkPhysicalDevice &physicalDevice = renderer->getPhysicalDevice();
 
     VkSurfaceCapabilitiesKHR surfaceCaps;
     ANGLE_VK_TRY(vkGetPhysicalDeviceSurfaceCapabilitiesKHR(physicalDevice, mSurface, &surfaceCaps));
 
     // Adjust width and height to the swapchain if necessary.
     uint32_t width  = surfaceCaps.currentExtent.width;
     uint32_t height = surfaceCaps.currentExtent.height;
 
@@ -295,18 +300,18 @@ vk::Error WindowSurfaceVk::initializeImp
     uint32_t surfaceFormatCount = 0;
     ANGLE_VK_TRY(vkGetPhysicalDeviceSurfaceFormatsKHR(physicalDevice, mSurface, &surfaceFormatCount,
                                                       nullptr));
 
     std::vector<VkSurfaceFormatKHR> surfaceFormats(surfaceFormatCount);
     ANGLE_VK_TRY(vkGetPhysicalDeviceSurfaceFormatsKHR(physicalDevice, mSurface, &surfaceFormatCount,
                                                       surfaceFormats.data()));
 
-    mRenderTarget.format = &GetVkFormatFromConfig(*mState.config);
-    auto nativeFormat    = mRenderTarget.format->native;
+    mRenderTarget.format  = &GetVkFormatFromConfig(renderer, *mState.config);
+    VkFormat nativeFormat = mRenderTarget.format->vkTextureFormat;
 
     if (surfaceFormatCount == 1u && surfaceFormats[0].format == VK_FORMAT_UNDEFINED)
     {
         // This is fine.
     }
     else
     {
         bool foundFormat = false;
@@ -339,38 +344,39 @@ vk::Error WindowSurfaceVk::initializeImp
     swapchainInfo.queueFamilyIndexCount = 0;
     swapchainInfo.pQueueFamilyIndices   = nullptr;
     swapchainInfo.preTransform          = preTransform;
     swapchainInfo.compositeAlpha        = VK_COMPOSITE_ALPHA_OPAQUE_BIT_KHR;
     swapchainInfo.presentMode           = swapchainPresentMode;
     swapchainInfo.clipped               = VK_TRUE;
     swapchainInfo.oldSwapchain          = VK_NULL_HANDLE;
 
-    const auto &device = renderer->getDevice();
+    VkDevice device = renderer->getDevice();
     ANGLE_VK_TRY(vkCreateSwapchainKHR(device, &swapchainInfo, nullptr, &mSwapchain));
 
     // Intialize the swapchain image views.
     uint32_t imageCount = 0;
     ANGLE_VK_TRY(vkGetSwapchainImagesKHR(device, mSwapchain, &imageCount, nullptr));
 
     std::vector<VkImage> swapchainImages(imageCount);
     ANGLE_VK_TRY(vkGetSwapchainImagesKHR(device, mSwapchain, &imageCount, swapchainImages.data()));
 
-    // CommandBuffer is a singleton in the Renderer.
+    // Allocate a command buffer for clearing our images to black.
     vk::CommandBuffer *commandBuffer = nullptr;
-    ANGLE_TRY(renderer->getStartedCommandBuffer(&commandBuffer));
+    ANGLE_TRY(recordWriteCommands(renderer, &commandBuffer));
 
     VkClearColorValue transparentBlack;
     transparentBlack.float32[0] = 0.0f;
     transparentBlack.float32[1] = 0.0f;
     transparentBlack.float32[2] = 0.0f;
     transparentBlack.float32[3] = 0.0f;
 
     mSwapchainImages.resize(imageCount);
-    mSwapchainImageViews.resize(imageCount);
+
+    ANGLE_TRY(mAcquireNextImageSemaphore.init(device));
 
     for (uint32_t imageIndex = 0; imageIndex < imageCount; ++imageIndex)
     {
         VkImage swapchainImage = swapchainImages[imageIndex];
 
         VkImageViewCreateInfo imageViewInfo;
         imageViewInfo.sType                           = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO;
         imageViewInfo.pNext                           = nullptr;
@@ -383,71 +389,64 @@ vk::Error WindowSurfaceVk::initializeImp
         imageViewInfo.components.b                    = VK_COMPONENT_SWIZZLE_B;
         imageViewInfo.components.a                    = VK_COMPONENT_SWIZZLE_A;
         imageViewInfo.subresourceRange.aspectMask     = VK_IMAGE_ASPECT_COLOR_BIT;
         imageViewInfo.subresourceRange.baseMipLevel   = 0;
         imageViewInfo.subresourceRange.levelCount     = 1;
         imageViewInfo.subresourceRange.baseArrayLayer = 0;
         imageViewInfo.subresourceRange.layerCount     = 1;
 
-        vk::Image image(swapchainImage);
-        vk::ImageView imageView;
-        ANGLE_TRY(imageView.init(device, imageViewInfo));
+        auto &member = mSwapchainImages[imageIndex];
+
+        member.image.setHandle(swapchainImage);
+        ANGLE_TRY(member.imageView.init(device, imageViewInfo));
 
         // Set transfer dest layout, and clear the image to black.
-        image.changeLayoutTop(VK_IMAGE_ASPECT_COLOR_BIT, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
-                              commandBuffer);
-        commandBuffer->clearSingleColorImage(image, transparentBlack);
+        member.image.changeLayoutWithStages(
+            VK_IMAGE_ASPECT_COLOR_BIT, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
+            VK_PIPELINE_STAGE_ALL_GRAPHICS_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, commandBuffer);
+        commandBuffer->clearSingleColorImage(member.image, transparentBlack);
 
-        mSwapchainImages[imageIndex].retain(device, std::move(image));
-        mSwapchainImageViews[imageIndex].retain(device, std::move(imageView));
+        ANGLE_TRY(member.imageAcquiredSemaphore.init(device));
+        ANGLE_TRY(member.commandsCompleteSemaphore.init(device));
     }
 
-    ANGLE_TRY(renderer->submitAndFinishCommandBuffer(commandBuffer));
-
-    ANGLE_TRY(mImageAvailableSemaphore.init(device));
-    ANGLE_TRY(mRenderingCompleteSemaphore.init(device));
-
     // Get the first available swapchain iamge.
     ANGLE_TRY(nextSwapchainImage(renderer));
 
     return vk::NoError();
 }
 
 FramebufferImpl *WindowSurfaceVk::createDefaultFramebuffer(const gl::FramebufferState &state)
 {
     return FramebufferVk::CreateDefaultFBO(state, this);
 }
 
 egl::Error WindowSurfaceVk::swap(const gl::Context *context)
 {
-    const DisplayVk *displayVk = GetImplAs<DisplayVk>(context->getCurrentDisplay());
+    const DisplayVk *displayVk = vk::GetImpl(context->getCurrentDisplay());
     RendererVk *renderer       = displayVk->getRenderer();
 
-    vk::CommandBuffer *currentCB = nullptr;
-    ANGLE_TRY(renderer->getStartedCommandBuffer(&currentCB));
+    vk::CommandBuffer *swapCommands = nullptr;
+    ANGLE_TRY(recordWriteCommands(renderer, &swapCommands));
 
-    // End render pass
-    FramebufferVk *framebufferVk = GetImplAs<FramebufferVk>(mState.defaultFramebuffer);
-    framebufferVk->endRenderPass(currentCB);
+    auto &image = mSwapchainImages[mCurrentSwapchainImageIndex];
 
-    auto *image = &mSwapchainImages[mCurrentSwapchainImageIndex];
+    image.image.changeLayoutWithStages(VK_IMAGE_ASPECT_COLOR_BIT, VK_IMAGE_LAYOUT_PRESENT_SRC_KHR,
+                                       VK_PIPELINE_STAGE_ALL_COMMANDS_BIT,
+                                       VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT, swapCommands);
 
-    image->changeLayoutWithStages(VK_IMAGE_ASPECT_COLOR_BIT, VK_IMAGE_LAYOUT_PRESENT_SRC_KHR,
-                                  VK_PIPELINE_STAGE_ALL_COMMANDS_BIT,
-                                  VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT, currentCB);
-
-    ANGLE_TRY(renderer->submitCommandsWithSync(currentCB, mImageAvailableSemaphore,
-                                               mRenderingCompleteSemaphore));
+    ANGLE_TRY(
+        renderer->flush(context, image.imageAcquiredSemaphore, image.commandsCompleteSemaphore));
 
     VkPresentInfoKHR presentInfo;
     presentInfo.sType              = VK_STRUCTURE_TYPE_PRESENT_INFO_KHR;
     presentInfo.pNext              = nullptr;
     presentInfo.waitSemaphoreCount = 1;
-    presentInfo.pWaitSemaphores    = mRenderingCompleteSemaphore.ptr();
+    presentInfo.pWaitSemaphores    = image.commandsCompleteSemaphore.ptr();
     presentInfo.swapchainCount     = 1;
     presentInfo.pSwapchains        = &mSwapchain;
     presentInfo.pImageIndices      = &mCurrentSwapchainImageIndex;
     presentInfo.pResults           = nullptr;
 
     ANGLE_VK_TRY(vkQueuePresentKHR(renderer->getQueue(), &presentInfo));
 
     // Get the next available swapchain image.
@@ -455,23 +454,30 @@ egl::Error WindowSurfaceVk::swap(const g
 
     return vk::NoError();
 }
 
 vk::Error WindowSurfaceVk::nextSwapchainImage(RendererVk *renderer)
 {
     VkDevice device = renderer->getDevice();
 
-    ANGLE_VK_TRY(vkAcquireNextImageKHR(device, mSwapchain, std::numeric_limits<uint64_t>::max(),
-                                       mImageAvailableSemaphore.getHandle(), VK_NULL_HANDLE,
+    // Use a timeout of zero for AcquireNextImage so we don't actually block.
+    // TODO(jmadill): We should handle VK_NOT_READY and block until we can acquire the image.
+    ANGLE_VK_TRY(vkAcquireNextImageKHR(device, mSwapchain, 0,
+                                       mAcquireNextImageSemaphore.getHandle(), VK_NULL_HANDLE,
                                        &mCurrentSwapchainImageIndex));
 
+    auto &image = mSwapchainImages[mCurrentSwapchainImageIndex];
+
+    // Swap the unused swapchain semaphore and the now active spare semaphore.
+    std::swap(image.imageAcquiredSemaphore, mAcquireNextImageSemaphore);
+
     // Update RenderTarget pointers.
-    mRenderTarget.image     = &mSwapchainImages[mCurrentSwapchainImageIndex];
-    mRenderTarget.imageView = &mSwapchainImageViews[mCurrentSwapchainImageIndex];
+    mRenderTarget.image     = &image.image;
+    mRenderTarget.imageView = &image.imageView;
 
     return vk::NoError();
 }
 
 egl::Error WindowSurfaceVk::postSubBuffer(const gl::Context *context,
                                           EGLint x,
                                           EGLint y,
                                           EGLint width,
@@ -539,46 +545,47 @@ gl::Error WindowSurfaceVk::getAttachment
     *rtOut = &mRenderTarget;
     return gl::NoError();
 }
 
 gl::ErrorOrResult<vk::Framebuffer *> WindowSurfaceVk::getCurrentFramebuffer(
     VkDevice device,
     const vk::RenderPass &compatibleRenderPass)
 {
-    if (!mSwapchainFramebuffers.empty())
+    auto &currentFramebuffer = mSwapchainImages[mCurrentSwapchainImageIndex].framebuffer;
+
+    if (currentFramebuffer.valid())
     {
         // Validation layers should detect if the render pass is really compatible.
-        return &mSwapchainFramebuffers[mCurrentSwapchainImageIndex];
+        return &currentFramebuffer;
     }
 
     VkFramebufferCreateInfo framebufferInfo;
 
     // TODO(jmadill): Depth/Stencil attachments.
     framebufferInfo.sType           = VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO;
     framebufferInfo.pNext           = nullptr;
     framebufferInfo.flags           = 0;
     framebufferInfo.renderPass      = compatibleRenderPass.getHandle();
     framebufferInfo.attachmentCount = 1u;
     framebufferInfo.pAttachments    = nullptr;
     framebufferInfo.width           = static_cast<uint32_t>(mRenderTarget.extents.width);
     framebufferInfo.height          = static_cast<uint32_t>(mRenderTarget.extents.height);
     framebufferInfo.layers          = 1;
 
-    mSwapchainFramebuffers.resize(mSwapchainImageViews.size());
-    for (size_t imageIndex = 0; imageIndex < mSwapchainFramebuffers.size(); ++imageIndex)
+    for (auto &swapchainImage : mSwapchainImages)
     {
-        const auto &imageView        = mSwapchainImageViews[imageIndex];
-        VkImageView imageViewHandle  = imageView.getHandle();
-        framebufferInfo.pAttachments = &imageViewHandle;
-
-        vk::Framebuffer framebuffer;
-        ANGLE_TRY(framebuffer.init(device, framebufferInfo));
-
-        mSwapchainFramebuffers[imageIndex].retain(device, std::move(framebuffer));
+        framebufferInfo.pAttachments = swapchainImage.imageView.ptr();
+        ANGLE_TRY(swapchainImage.framebuffer.init(device, framebufferInfo));
     }
 
-    // We should only initialize framebuffers on the first swap.
-    ASSERT(mCurrentSwapchainImageIndex == 0u);
-    return &mSwapchainFramebuffers[mCurrentSwapchainImageIndex];
+    ASSERT(currentFramebuffer.valid());
+    return &currentFramebuffer;
+}
+
+gl::Error WindowSurfaceVk::initializeContents(const gl::Context *context,
+                                              const gl::ImageIndex &imageIndex)
+{
+    UNIMPLEMENTED();
+    return gl::NoError();
 }
 
 }  // namespace rx
--- a/gfx/angle/src/libANGLE/renderer/vulkan/SurfaceVk.h
+++ b/gfx/angle/src/libANGLE/renderer/vulkan/SurfaceVk.h
@@ -47,16 +47,19 @@ class OffscreenSurfaceVk : public Surfac
     EGLint isPostSubBufferSupported() const override;
     EGLint getSwapBehavior() const override;
 
     gl::Error getAttachmentRenderTarget(const gl::Context *context,
                                         GLenum binding,
                                         const gl::ImageIndex &imageIndex,
                                         FramebufferAttachmentRenderTarget **rtOut) override;
 
+    gl::Error initializeContents(const gl::Context *context,
+                                 const gl::ImageIndex &imageIndex) override;
+
   private:
     EGLint mWidth;
     EGLint mHeight;
 };
 
 class WindowSurfaceVk : public SurfaceImpl, public ResourceVk
 {
   public:
@@ -89,16 +92,19 @@ class WindowSurfaceVk : public SurfaceIm
     EGLint isPostSubBufferSupported() const override;
     EGLint getSwapBehavior() const override;
 
     gl::Error getAttachmentRenderTarget(const gl::Context *context,
                                         GLenum binding,
                                         const gl::ImageIndex &imageIndex,
                                         FramebufferAttachmentRenderTarget **rtOut) override;
 
+    gl::Error initializeContents(const gl::Context *context,
+                                 const gl::ImageIndex &imageIndex) override;
+
     gl::ErrorOrResult<vk::Framebuffer *> getCurrentFramebuffer(
         VkDevice device,
         const vk::RenderPass &compatibleRenderPass);
 
   protected:
     EGLNativeWindowType mNativeWindowType;
     VkSurfaceKHR mSurface;
     VkInstance mInstance;
@@ -106,20 +112,37 @@ class WindowSurfaceVk : public SurfaceIm
   private:
     virtual vk::ErrorOrResult<gl::Extents> createSurfaceVk(RendererVk *renderer) = 0;
     vk::Error initializeImpl(RendererVk *renderer);
     vk::Error nextSwapchainImage(RendererVk *renderer);
 
     VkSwapchainKHR mSwapchain;
 
     RenderTargetVk mRenderTarget;
-    vk::Semaphore mImageAvailableSemaphore;
-    vk::Semaphore mRenderingCompleteSemaphore;
 
     uint32_t mCurrentSwapchainImageIndex;
-    std::vector<vk::Image> mSwapchainImages;
-    std::vector<vk::ImageView> mSwapchainImageViews;
-    std::vector<vk::Framebuffer> mSwapchainFramebuffers;
+
+    // When acquiring a new image for rendering, we keep a 'spare' semaphore. We pass this extra
+    // semaphore to VkAcquireNextImage, then hand it to the next available SwapchainImage when
+    // the command completes. We then make the old semaphore in the new SwapchainImage the spare
+    // semaphore, since we know the image is no longer using it. This avoids the chicken and egg
+    // problem with needing to know the next available image index before we acquire it.
+    vk::Semaphore mAcquireNextImageSemaphore;
+
+    struct SwapchainImage
+    {
+        SwapchainImage();
+        SwapchainImage(SwapchainImage &&other);
+        ~SwapchainImage();
+
+        vk::Image image;
+        vk::ImageView imageView;
+        vk::Framebuffer framebuffer;
+        vk::Semaphore imageAcquiredSemaphore;
+        vk::Semaphore commandsCompleteSemaphore;
+    };
+
+    std::vector<SwapchainImage> mSwapchainImages;
 };
 
 }  // namespace rx
 
 #endif  // LIBANGLE_RENDERER_VULKAN_SURFACEVK_H_
--- a/gfx/angle/src/libANGLE/renderer/vulkan/TextureVk.cpp
+++ b/gfx/angle/src/libANGLE/renderer/vulkan/TextureVk.cpp
@@ -5,53 +5,281 @@
 //
 // TextureVk.cpp:
 //    Implements the class methods for TextureVk.
 //
 
 #include "libANGLE/renderer/vulkan/TextureVk.h"
 
 #include "common/debug.h"
+#include "libANGLE/Context.h"
+#include "libANGLE/renderer/vulkan/ContextVk.h"
+#include "libANGLE/renderer/vulkan/RendererVk.h"
+#include "libANGLE/renderer/vulkan/formatutilsvk.h"
 
 namespace rx
 {
 
 TextureVk::TextureVk(const gl::TextureState &state) : TextureImpl(state)
 {
 }
 
 TextureVk::~TextureVk()
 {
 }
 
+gl::Error TextureVk::onDestroy(const gl::Context *context)
+{
+    ContextVk *contextVk = vk::GetImpl(context);
+    RendererVk *renderer = contextVk->getRenderer();
+
+    renderer->releaseResource(*this, &mImage);
+    renderer->releaseResource(*this, &mDeviceMemory);
+    renderer->releaseResource(*this, &mImageView);
+    renderer->releaseResource(*this, &mSampler);
+
+    return gl::NoError();
+}
+
 gl::Error TextureVk::setImage(const gl::Context *context,
                               GLenum target,
                               size_t level,
                               GLenum internalFormat,
                               const gl::Extents &size,
                               GLenum format,
                               GLenum type,
                               const gl::PixelUnpackState &unpack,
                               const uint8_t *pixels)
 {
-    UNIMPLEMENTED();
-    return gl::InternalError();
+    ContextVk *contextVk = vk::GetImpl(context);
+    RendererVk *renderer = contextVk->getRenderer();
+    VkDevice device      = contextVk->getDevice();
+
+    // TODO(jmadill): support multi-level textures.
+    ASSERT(level == 0);
+
+    if (mImage.valid())
+    {
+        const gl::ImageDesc &desc = mState.getImageDesc(target, level);
+
+        // TODO(jmadill): Consider comparing stored vk::Format.
+        if (desc.size != size ||
+            !gl::Format::SameSized(desc.format, gl::Format(internalFormat, type)))
+        {
+            renderer->releaseResource(*this, &mImage);
+            renderer->releaseResource(*this, &mDeviceMemory);
+            renderer->releaseResource(*this, &mImageView);
+        }
+    }
+
+    // TODO(jmadill): support other types of textures.
+    ASSERT(target == GL_TEXTURE_2D);
+
+    // Convert internalFormat to sized internal format.
+    const gl::InternalFormat &formatInfo = gl::GetInternalFormatInfo(internalFormat, type);
+    const vk::Format &vkFormat           = renderer->getFormat(formatInfo.sizedInternalFormat);
+
+    if (!mImage.valid())
+    {
+        ASSERT(!mDeviceMemory.valid() && !mImageView.valid());
+
+        VkImageCreateInfo imageInfo;
+        imageInfo.sType         = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
+        imageInfo.pNext         = nullptr;
+        imageInfo.flags         = 0;
+        imageInfo.imageType     = VK_IMAGE_TYPE_2D;
+        imageInfo.format        = vkFormat.vkTextureFormat;
+        imageInfo.extent.width  = size.width;
+        imageInfo.extent.height = size.height;
+        imageInfo.extent.depth  = size.depth;
+        imageInfo.mipLevels     = 1;
+        imageInfo.arrayLayers   = 1;
+        imageInfo.samples       = VK_SAMPLE_COUNT_1_BIT;
+        imageInfo.tiling        = VK_IMAGE_TILING_OPTIMAL;
+
+        // TODO(jmadill): Are all these image transfer bits necessary?
+        imageInfo.usage = (VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT |
+                           VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_SAMPLED_BIT);
+        imageInfo.sharingMode           = VK_SHARING_MODE_EXCLUSIVE;
+        imageInfo.queueFamilyIndexCount = 0;
+        imageInfo.pQueueFamilyIndices   = nullptr;
+        imageInfo.initialLayout         = VK_IMAGE_LAYOUT_UNDEFINED;
+
+        ANGLE_TRY(mImage.init(device, imageInfo));
+
+        // Allocate the device memory for the image.
+        // TODO(jmadill): Use more intelligent device memory allocation.
+        VkMemoryRequirements memoryRequirements;
+        mImage.getMemoryRequirements(device, &memoryRequirements);
+
+        uint32_t memoryIndex = renderer->getMemoryProperties().findCompatibleMemoryIndex(
+            memoryRequirements.memoryTypeBits, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT);
+
+        VkMemoryAllocateInfo allocateInfo;
+        allocateInfo.sType           = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
+        allocateInfo.pNext           = nullptr;
+        allocateInfo.allocationSize  = memoryRequirements.size;
+        allocateInfo.memoryTypeIndex = memoryIndex;
+
+        ANGLE_TRY(mDeviceMemory.allocate(device, allocateInfo));
+        ANGLE_TRY(mImage.bindMemory(device, mDeviceMemory));
+
+        VkImageViewCreateInfo viewInfo;
+        viewInfo.sType                           = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO;
+        viewInfo.pNext                           = nullptr;
+        viewInfo.flags                           = 0;
+        viewInfo.image                           = mImage.getHandle();
+        viewInfo.viewType                        = VK_IMAGE_VIEW_TYPE_2D;
+        viewInfo.format                          = vkFormat.vkTextureFormat;
+        viewInfo.components.r                    = VK_COMPONENT_SWIZZLE_R;
+        viewInfo.components.g                    = VK_COMPONENT_SWIZZLE_G;
+        viewInfo.components.b                    = VK_COMPONENT_SWIZZLE_B;
+        viewInfo.components.a                    = VK_COMPONENT_SWIZZLE_A;
+        viewInfo.subresourceRange.aspectMask     = VK_IMAGE_ASPECT_COLOR_BIT;
+        viewInfo.subresourceRange.baseMipLevel   = 0;
+        viewInfo.subresourceRange.levelCount     = 1;
+        viewInfo.subresourceRange.baseArrayLayer = 0;
+        viewInfo.subresourceRange.layerCount     = 1;
+
+        ANGLE_TRY(mImageView.init(device, viewInfo));
+    }
+
+    if (!mSampler.valid())
+    {
+        // Create a simple sampler. Force basic parameter settings.
+        // TODO(jmadill): Sampler parameters.
+        VkSamplerCreateInfo samplerInfo;
+        samplerInfo.sType                   = VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO;
+        samplerInfo.pNext                   = nullptr;
+        samplerInfo.flags                   = 0;
+        samplerInfo.magFilter               = VK_FILTER_NEAREST;
+        samplerInfo.minFilter               = VK_FILTER_NEAREST;
+        samplerInfo.mipmapMode              = VK_SAMPLER_MIPMAP_MODE_NEAREST;
+        samplerInfo.addressModeU            = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE;
+        samplerInfo.addressModeV            = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE;
+        samplerInfo.addressModeW            = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE;
+        samplerInfo.mipLodBias              = 0.0f;
+        samplerInfo.anisotropyEnable        = VK_FALSE;
+        samplerInfo.maxAnisotropy           = 1.0f;
+        samplerInfo.compareEnable           = VK_FALSE;
+        samplerInfo.compareOp               = VK_COMPARE_OP_ALWAYS;
+        samplerInfo.minLod                  = 0.0f;
+        samplerInfo.maxLod                  = 1.0f;
+        samplerInfo.borderColor             = VK_BORDER_COLOR_INT_TRANSPARENT_BLACK;
+        samplerInfo.unnormalizedCoordinates = VK_FALSE;
+
+        ANGLE_TRY(mSampler.init(device, samplerInfo));
+    }
+
+    mRenderTarget.image     = &mImage;
+    mRenderTarget.imageView = &mImageView;
+    mRenderTarget.format    = &vkFormat;
+    mRenderTarget.extents   = size;
+    mRenderTarget.samples   = VK_SAMPLE_COUNT_1_BIT;
+    mRenderTarget.resource  = this;
+
+    // Handle initial data.
+    if (pixels)
+    {
+        ANGLE_TRY(setSubImageImpl(contextVk, formatInfo, unpack, type, pixels));
+    }
+
+    return gl::NoError();
 }
 
 gl::Error TextureVk::setSubImage(const gl::Context *context,
                                  GLenum target,
                                  size_t level,
                                  const gl::Box &area,
                                  GLenum format,
                                  GLenum type,
                                  const gl::PixelUnpackState &unpack,
                                  const uint8_t *pixels)
 {
-    UNIMPLEMENTED();
-    return gl::InternalError();
+    ContextVk *contextVk                 = vk::GetImpl(context);
+    const gl::InternalFormat &formatInfo = gl::GetInternalFormatInfo(format, type);
+    ANGLE_TRY(setSubImageImpl(contextVk, formatInfo, unpack, type, pixels));
+    return gl::NoError();
+}
+
+gl::Error TextureVk::setSubImageImpl(ContextVk *contextVk,
+                                     const gl::InternalFormat &formatInfo,
+                                     const gl::PixelUnpackState &unpack,
+                                     GLenum type,
+                                     const uint8_t *pixels)
+{
+    RendererVk *renderer       = contextVk->getRenderer();
+    VkDevice device            = renderer->getDevice();
+    const gl::Extents &size    = mRenderTarget.extents;
+    const vk::Format &vkFormat = *mRenderTarget.format;
+
+    vk::StagingImage stagingImage;
+    ANGLE_TRY(renderer->createStagingImage(TextureDimension::TEX_2D, vkFormat, size,
+                                           vk::StagingUsage::Write, &stagingImage));
+
+    GLuint inputRowPitch = 0;
+    ANGLE_TRY_RESULT(
+        formatInfo.computeRowPitch(type, size.width, unpack.alignment, unpack.rowLength),
+        inputRowPitch);
+
+    GLuint inputDepthPitch = 0;
+    ANGLE_TRY_RESULT(formatInfo.computeDepthPitch(size.height, unpack.imageHeight, inputRowPitch),
+                     inputDepthPitch);
+
+    // TODO(jmadill): skip images for 3D Textures.
+    bool applySkipImages = false;
+
+    GLuint inputSkipBytes = 0;
+    ANGLE_TRY_RESULT(
+        formatInfo.computeSkipBytes(inputRowPitch, inputDepthPitch, unpack, applySkipImages),
+        inputSkipBytes);
+
+    auto loadFunction = vkFormat.loadFunctions(type);
+
+    uint8_t *mapPointer = nullptr;
+    ANGLE_TRY(stagingImage.getDeviceMemory().map(device, 0, VK_WHOLE_SIZE, 0, &mapPointer));
+
+    const uint8_t *source = pixels + inputSkipBytes;
+
+    // Get the subresource layout. This has important parameters like row pitch.
+    // TODO(jmadill): Fill out this structure based on input parameters.
+    VkImageSubresource subresource;
+    subresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
+    subresource.mipLevel   = 0;
+    subresource.arrayLayer = 0;
+
+    VkSubresourceLayout subresourceLayout;
+    vkGetImageSubresourceLayout(device, stagingImage.getImage().getHandle(), &subresource,
+                                &subresourceLayout);
+
+    loadFunction.loadFunction(size.width, size.height, size.depth, source, inputRowPitch,
+                              inputDepthPitch, mapPointer,
+                              static_cast<size_t>(subresourceLayout.rowPitch),
+                              static_cast<size_t>(subresourceLayout.depthPitch));
+
+    stagingImage.getDeviceMemory().unmap(device);
+
+    vk::CommandBuffer *commandBuffer = nullptr;
+    ANGLE_TRY(recordWriteCommands(renderer, &commandBuffer));
+
+    stagingImage.getImage().changeLayoutWithStages(
+        VK_IMAGE_ASPECT_COLOR_BIT, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
+        VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, commandBuffer);
+    mImage.changeLayoutWithStages(VK_IMAGE_ASPECT_COLOR_BIT, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
+                                  VK_PIPELINE_STAGE_ALL_COMMANDS_BIT,
+                                  VK_PIPELINE_STAGE_TRANSFER_BIT, commandBuffer);
+
+    gl::Box wholeRegion(0, 0, 0, size.width, size.height, size.depth);
+    commandBuffer->copySingleImage(stagingImage.getImage(), mImage, wholeRegion,
+                                   VK_IMAGE_ASPECT_COLOR_BIT);
+
+    // Immediately release staging image.
+    // TODO(jmadill): Staging image re-use.
+    renderer->releaseObject(renderer->getCurrentQueueSerial(), &stagingImage);
+    return gl::NoError();
 }
 
 gl::Error TextureVk::setCompressedImage(const gl::Context *context,
                                         GLenum target,
                                         size_t level,
                                         GLenum internalFormat,
                                         const gl::Extents &size,
                                         const gl::PixelUnpackState &unpack,
@@ -146,29 +374,56 @@ gl::Error TextureVk::releaseTexImage(con
     return gl::InternalError();
 }
 
 gl::Error TextureVk::getAttachmentRenderTarget(const gl::Context *context,
                                                GLenum binding,
                                                const gl::ImageIndex &imageIndex,
                                                FramebufferAttachmentRenderTarget **rtOut)
 {
-    UNIMPLEMENTED();
-    return gl::InternalError();
+    ASSERT(imageIndex.type == GL_TEXTURE_2D);
+    ASSERT(imageIndex.mipIndex == 0 && imageIndex.layerIndex == gl::ImageIndex::ENTIRE_LEVEL);
+    *rtOut = &mRenderTarget;
+    return gl::NoError();
 }
 
 void TextureVk::syncState(const gl::Texture::DirtyBits &dirtyBits)
 {
-    UNIMPLEMENTED();
+    // TODO(jmadill): Texture sync state.
 }
 
 gl::Error TextureVk::setStorageMultisample(const gl::Context *context,
                                            GLenum target,
                                            GLsizei samples,
                                            GLint internalformat,
                                            const gl::Extents &size,
-                                           GLboolean fixedSampleLocations)
+                                           bool fixedSampleLocations)
 {
     UNIMPLEMENTED();
     return gl::InternalError() << "setStorageMultisample is unimplemented.";
 }
 
+gl::Error TextureVk::initializeContents(const gl::Context *context,
+                                        const gl::ImageIndex &imageIndex)
+{
+    UNIMPLEMENTED();
+    return gl::NoError();
+}
+
+const vk::Image &TextureVk::getImage() const
+{
+    ASSERT(mImage.valid());
+    return mImage;
+}
+
+const vk::ImageView &TextureVk::getImageView() const
+{
+    ASSERT(mImageView.valid());
+    return mImageView;
+}
+
+const vk::Sampler &TextureVk::getSampler() const
+{
+    ASSERT(mSampler.valid());
+    return mSampler;
+}
+
 }  // namespace rx
--- a/gfx/angle/src/libANGLE/renderer/vulkan/TextureVk.h
+++ b/gfx/angle/src/libANGLE/renderer/vulkan/TextureVk.h
@@ -6,25 +6,28 @@
 // TextureVk.h:
 //    Defines the class interface for TextureVk, implementing TextureImpl.
 //
 
 #ifndef LIBANGLE_RENDERER_VULKAN_TEXTUREVK_H_
 #define LIBANGLE_RENDERER_VULKAN_TEXTUREVK_H_
 
 #include "libANGLE/renderer/TextureImpl.h"
+#include "libANGLE/renderer/vulkan/RenderTargetVk.h"
+#include "libANGLE/renderer/vulkan/renderervk_utils.h"
 
 namespace rx
 {
 
-class TextureVk : public TextureImpl
+class TextureVk : public TextureImpl, public ResourceVk
 {
   public:
     TextureVk(const gl::TextureState &state);
     ~TextureVk() override;
+    gl::Error onDestroy(const gl::Context *context) override;
 
     gl::Error setImage(const gl::Context *context,
                        GLenum target,
                        size_t level,
                        GLenum internalFormat,
                        const gl::Extents &size,
                        GLenum format,
                        GLenum type,
@@ -98,14 +101,36 @@ class TextureVk : public TextureImpl
 
     void syncState(const gl::Texture::DirtyBits &dirtyBits) override;
 
     gl::Error setStorageMultisample(const gl::Context *context,
                                     GLenum target,
                                     GLsizei samples,
                                     GLint internalformat,
                                     const gl::Extents &size,
-                                    GLboolean fixedSampleLocations) override;
+                                    bool fixedSampleLocations) override;
+
+    gl::Error initializeContents(const gl::Context *context,
+                                 const gl::ImageIndex &imageIndex) override;
+
+    const vk::Image &getImage() const;
+    const vk::ImageView &getImageView() const;
+    const vk::Sampler &getSampler() const;
+
+  private:
+    gl::Error setSubImageImpl(ContextVk *contextVk,
+                              const gl::InternalFormat &formatInfo,
+                              const gl::PixelUnpackState &unpack,
+                              GLenum type,
+                              const uint8_t *pixels);
+
+    // TODO(jmadill): support a more flexible storage back-end.
+    vk::Image mImage;
+    vk::DeviceMemory mDeviceMemory;
+    vk::ImageView mImageView;
+    vk::Sampler mSampler;
+
+    RenderTargetVk mRenderTarget;
 };
 
 }  // namespace rx
 
 #endif  // LIBANGLE_RENDERER_VULKAN_TEXTUREVK_H_
--- a/gfx/angle/src/libANGLE/renderer/vulkan/VertexArrayVk.cpp
+++ b/gfx/angle/src/libANGLE/renderer/vulkan/VertexArrayVk.cpp
@@ -7,32 +7,187 @@
 //    Implements the class methods for VertexArrayVk.
 //
 
 #include "libANGLE/renderer/vulkan/VertexArrayVk.h"
 
 #include "common/debug.h"
 
 #include "libANGLE/Context.h"
+#include "libANGLE/renderer/vulkan/BufferVk.h"
+#include "libANGLE/renderer/vulkan/CommandBufferNode.h"
 #include "libANGLE/renderer/vulkan/ContextVk.h"
+#include "libANGLE/renderer/vulkan/formatutilsvk.h"
 
 namespace rx
 {
 
-VertexArrayVk::VertexArrayVk(const gl::VertexArrayState &data) : VertexArrayImpl(data)
+VertexArrayVk::VertexArrayVk(const gl::VertexArrayState &state)
+    : VertexArrayImpl(state),
+      mCurrentArrayBufferHandles{},
+      mCurrentArrayBufferResources{},
+      mCurrentElementArrayBufferResource(nullptr),
+      mCurrentVertexDescsValid(false)
+{
+    mCurrentArrayBufferHandles.fill(VK_NULL_HANDLE);
+    mCurrentArrayBufferResources.fill(nullptr);
+    mCurrentVertexBindingDescs.reserve(state.getMaxAttribs());
+    mCurrentVertexAttribDescs.reserve(state.getMaxAttribs());
+}
+
+VertexArrayVk::~VertexArrayVk()
 {
 }
 
 void VertexArrayVk::destroy(const gl::Context *context)
 {
 }
 
 void VertexArrayVk::syncState(const gl::Context *context,
                               const gl::VertexArray::DirtyBits &dirtyBits)
 {
     ASSERT(dirtyBits.any());
 
+    // Invalidate current pipeline.
     // TODO(jmadill): Use pipeline cache.
-    auto contextVk = GetImplAs<ContextVk>(context);
-    contextVk->invalidateCurrentPipeline();
+    ContextVk *contextVk = vk::GetImpl(context);
+    contextVk->onVertexArrayChange();
+
+    // Invalidate the vertex descriptions.
+    invalidateVertexDescriptions();
+
+    // Rebuild current attribute buffers cache. This will fail horribly if the buffer changes.
+    // TODO(jmadill): Handle buffer storage changes.
+    const auto &attribs  = mState.getVertexAttributes();
+    const auto &bindings = mState.getVertexBindings();
+
+    for (auto dirtyBit : dirtyBits)
+    {
+        if (dirtyBit == gl::VertexArray::DIRTY_BIT_ELEMENT_ARRAY_BUFFER)
+        {
+            gl::Buffer *bufferGL = mState.getElementArrayBuffer().get();
+            if (bufferGL)
+            {
+                mCurrentElementArrayBufferResource = vk::GetImpl(bufferGL);
+            }
+            else
+            {
+                mCurrentElementArrayBufferResource = nullptr;
+            }
+            continue;
+        }
+
+        size_t attribIndex = gl::VertexArray::GetVertexIndexFromDirtyBit(dirtyBit);
+
+        const auto &attrib  = attribs[attribIndex];
+        const auto &binding = bindings[attrib.bindingIndex];
+
+        if (attrib.enabled)
+        {
+            gl::Buffer *bufferGL = binding.getBuffer().get();
+
+            if (bufferGL)
+            {
+                BufferVk *bufferVk                        = vk::GetImpl(bufferGL);
+                mCurrentArrayBufferResources[attribIndex] = bufferVk;
+                mCurrentArrayBufferHandles[attribIndex]   = bufferVk->getVkBuffer().getHandle();
+            }
+            else
+            {
+                mCurrentArrayBufferResources[attribIndex] = nullptr;
+                mCurrentArrayBufferHandles[attribIndex]   = VK_NULL_HANDLE;
+            }
+        }
+        else
+        {
+            UNIMPLEMENTED();
+        }
+    }
+}
+
+const gl::AttribArray<VkBuffer> &VertexArrayVk::getCurrentArrayBufferHandles() const
+{
+    return mCurrentArrayBufferHandles;
+}
+
+void VertexArrayVk::updateDrawDependencies(vk::CommandBufferNode *readNode,
+                                           const gl::AttributesMask &activeAttribsMask,
+                                           Serial serial,
+                                           DrawType drawType)
+{
+    // Handle the bound array buffers.
+    for (auto attribIndex : activeAttribsMask)
+    {
+        ASSERT(mCurrentArrayBufferResources[attribIndex]);
+        mCurrentArrayBufferResources[attribIndex]->updateDependencies(readNode, serial);
+    }
+
+    // Handle the bound element array buffer.
+    if (drawType == DrawType::Elements)
+    {
+        ASSERT(mCurrentElementArrayBufferResource);
+        mCurrentElementArrayBufferResource->updateDependencies(readNode, serial);
+    }
+}
+
+void VertexArrayVk::invalidateVertexDescriptions()
+{
+    mCurrentVertexDescsValid = false;
+    mCurrentVertexBindingDescs.clear();
+    mCurrentVertexAttribDescs.clear();
+}
+
+void VertexArrayVk::updateVertexDescriptions(const gl::Context *context)
+{
+    if (mCurrentVertexDescsValid)
+    {
+        return;
+    }
+
+    const auto &attribs  = mState.getVertexAttributes();
+    const auto &bindings = mState.getVertexBindings();
+
+    const gl::Program *programGL = context->getGLState().getProgram();
+
+    for (auto attribIndex : programGL->getActiveAttribLocationsMask())
+    {
+        const auto &attrib  = attribs[attribIndex];
+        const auto &binding = bindings[attrib.bindingIndex];
+        if (attrib.enabled)
+        {
+            VkVertexInputBindingDescription bindingDesc;
+            bindingDesc.binding = static_cast<uint32_t>(mCurrentVertexBindingDescs.size());
+            bindingDesc.stride  = static_cast<uint32_t>(gl::ComputeVertexAttributeTypeSize(attrib));
+            bindingDesc.inputRate = (binding.getDivisor() > 0 ? VK_VERTEX_INPUT_RATE_INSTANCE
+                                                              : VK_VERTEX_INPUT_RATE_VERTEX);
+
+            gl::VertexFormatType vertexFormatType = gl::GetVertexFormatType(attrib);
+
+            VkVertexInputAttributeDescription attribDesc;
+            attribDesc.binding  = bindingDesc.binding;
+            attribDesc.format   = vk::GetNativeVertexFormat(vertexFormatType);
+            attribDesc.location = static_cast<uint32_t>(attribIndex);
+            attribDesc.offset =
+                static_cast<uint32_t>(ComputeVertexAttributeOffset(attrib, binding));
+
+            mCurrentVertexBindingDescs.push_back(bindingDesc);
+            mCurrentVertexAttribDescs.push_back(attribDesc);
+        }
+        else
+        {
+            UNIMPLEMENTED();
+        }
+    }
+
+    mCurrentVertexDescsValid = true;
+}
+
+const std::vector<VkVertexInputBindingDescription> &VertexArrayVk::getVertexBindingDescs() const
+{
+    return mCurrentVertexBindingDescs;
+}
+
+const std::vector<VkVertexInputAttributeDescription> &VertexArrayVk::getVertexAttribDescs() const
+{
+    return mCurrentVertexAttribDescs;
 }
 
 }  // namespace rx
--- a/gfx/angle/src/libANGLE/renderer/vulkan/VertexArrayVk.h
+++ b/gfx/angle/src/libANGLE/renderer/vulkan/VertexArrayVk.h
@@ -6,25 +6,53 @@
 // VertexArrayVk.h:
 //    Defines the class interface for VertexArrayVk, implementing VertexArrayImpl.
 //
 
 #ifndef LIBANGLE_RENDERER_VULKAN_VERTEXARRAYVK_H_
 #define LIBANGLE_RENDERER_VULKAN_VERTEXARRAYVK_H_
 
 #include "libANGLE/renderer/VertexArrayImpl.h"
+#include "libANGLE/renderer/vulkan/renderervk_utils.h"
 
 namespace rx
 {
+class BufferVk;
 
 class VertexArrayVk : public VertexArrayImpl
 {
   public:
-    VertexArrayVk(const gl::VertexArrayState &data);
+    VertexArrayVk(const gl::VertexArrayState &state);
+    ~VertexArrayVk() override;
+
     void destroy(const gl::Context *context) override;
 
     void syncState(const gl::Context *context,
                    const gl::VertexArray::DirtyBits &dirtyBits) override;
+
+    const gl::AttribArray<VkBuffer> &getCurrentArrayBufferHandles() const;
+
+    void updateDrawDependencies(vk::CommandBufferNode *readNode,
+                                const gl::AttributesMask &activeAttribsMask,
+                                Serial serial,
+                                DrawType drawType);
+
+    void invalidateVertexDescriptions();
+    void updateVertexDescriptions(const gl::Context *context);
+
+    const std::vector<VkVertexInputBindingDescription> &getVertexBindingDescs() const;
+    const std::vector<VkVertexInputAttributeDescription> &getVertexAttribDescs() const;
+
+  private:
+    gl::AttribArray<VkBuffer> mCurrentArrayBufferHandles;
+    gl::AttribArray<ResourceVk *> mCurrentArrayBufferResources;
+    ResourceVk *mCurrentElementArrayBufferResource;
+
+    // Keep a cache of binding and attribute descriptions for easy pipeline updates.
+    // TODO(jmadill): Update this when we support pipeline caching.
+    bool mCurrentVertexDescsValid;
+    std::vector<VkVertexInputBindingDescription> mCurrentVertexBindingDescs;
+    std::vector<VkVertexInputAttributeDescription> mCurrentVertexAttribDescs;
 };
 
 }  // namespace rx
 
 #endif  // LIBANGLE_RENDERER_VULKAN_VERTEXARRAYVK_H_
--- a/gfx/angle/src/libANGLE/renderer/vulkan/formatutilsvk.cpp
+++ b/gfx/angle/src/libANGLE/renderer/vulkan/formatutilsvk.cpp
@@ -3,90 +3,113 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 //
 // formatutilsvk:
 //   Helper for Vulkan format code.
 
 #include "libANGLE/renderer/vulkan/formatutilsvk.h"
 
+#include "libANGLE/formatutils.h"
 #include "libANGLE/renderer/load_functions_table.h"
 
 namespace rx
 {
 
 namespace vk
 {
 
-const angle::Format &Format::format() const
+Format::Format()
+    : internalFormat(GL_NONE),
+      textureFormatID(angle::Format::ID::NONE),
+      vkTextureFormat(VK_FORMAT_UNDEFINED),
+      bufferFormatID(angle::Format::ID::NONE),
+      vkBufferFormat(VK_FORMAT_UNDEFINED),
+      dataInitializerFunction(nullptr),
+      loadFunctions()
 {
-    return angle::Format::Get(formatID);
+}
+
+const angle::Format &Format::textureFormat() const
+{
+    return angle::Format::Get(textureFormatID);
+}
+
+const angle::Format &Format::bufferFormat() const
+{
+    return angle::Format::Get(bufferFormatID);
 }
 
-LoadFunctionMap Format::getLoadFunctions() const
+FormatTable::FormatTable()
+{
+}
+
+FormatTable::~FormatTable()
+{
+}
+
+void FormatTable::initialize(VkPhysicalDevice physicalDevice, gl::TextureCapsMap *textureCapsMap)
 {
-    return GetLoadFunctionsMap(internalFormat, formatID);
+    for (size_t formatIndex = 0; formatIndex < angle::kNumANGLEFormats; ++formatIndex)
+    {
+        angle::Format::ID formatID       = static_cast<angle::Format::ID>(formatIndex);
+        const angle::Format &angleFormat = angle::Format::Get(formatID);
+        mFormatData[formatIndex].initialize(physicalDevice, angleFormat);
+
+        mFormatData[formatIndex].loadFunctions = GetLoadFunctionsMap(
+            mFormatData[formatIndex].internalFormat, mFormatData[formatIndex].textureFormatID);
+    }
+}
+
+const Format &FormatTable::operator[](GLenum internalFormat) const
+{
+    angle::Format::ID formatID = angle::Format::InternalFormatToID(internalFormat);
+    return mFormatData[static_cast<size_t>(formatID)];
 }
 
 // TODO(jmadill): This is temporary. Figure out how to handle format conversions.
 VkFormat GetNativeVertexFormat(gl::VertexFormatType vertexFormat)
 {
     switch (vertexFormat)
     {
         case gl::VERTEX_FORMAT_INVALID:
             UNREACHABLE();
             return VK_FORMAT_UNDEFINED;
         case gl::VERTEX_FORMAT_SBYTE1:
-            UNIMPLEMENTED();
-            return VK_FORMAT_UNDEFINED;
+            return VK_FORMAT_R8_SINT;
         case gl::VERTEX_FORMAT_SBYTE1_NORM:
-            UNIMPLEMENTED();
-            return VK_FORMAT_UNDEFINED;
+            return VK_FORMAT_R8_SNORM;
         case gl::VERTEX_FORMAT_SBYTE2:
-            UNIMPLEMENTED();
-            return VK_FORMAT_UNDEFINED;
+            return VK_FORMAT_R8G8_SINT;
         case gl::VERTEX_FORMAT_SBYTE2_NORM:
-            UNIMPLEMENTED();
-            return VK_FORMAT_UNDEFINED;
+            return VK_FORMAT_R8G8_SNORM;
         case gl::VERTEX_FORMAT_SBYTE3:
-            UNIMPLEMENTED();
-            return VK_FORMAT_UNDEFINED;
+            return VK_FORMAT_R8G8B8_SINT;
         case gl::VERTEX_FORMAT_SBYTE3_NORM:
-            UNIMPLEMENTED();
-            return VK_FORMAT_UNDEFINED;
+            return VK_FORMAT_R8G8B8_SNORM;
         case gl::VERTEX_FORMAT_SBYTE4:
-            UNIMPLEMENTED();
-            return VK_FORMAT_UNDEFINED;
+            return VK_FORMAT_R8G8B8A8_SINT;
         case gl::VERTEX_FORMAT_SBYTE4_NORM:
-            UNIMPLEMENTED();
-            return VK_FORMAT_UNDEFINED;
+            return VK_FORMAT_R8G8B8A8_SNORM;
         case gl::VERTEX_FORMAT_UBYTE1:
-            UNIMPLEMENTED();
-            return VK_FORMAT_UNDEFINED;
+            return VK_FORMAT_R8_UINT;
         case gl::VERTEX_FORMAT_UBYTE1_NORM:
-            UNIMPLEMENTED();
-            return VK_FORMAT_UNDEFINED;
+            return VK_FORMAT_R8_UNORM;
         case gl::VERTEX_FORMAT_UBYTE2:
-            UNIMPLEMENTED();
-            return VK_FORMAT_UNDEFINED;
+            return VK_FORMAT_R8G8_UINT;
         case gl::VERTEX_FORMAT_UBYTE2_NORM:
-            UNIMPLEMENTED();
-            return VK_FORMAT_UNDEFINED;
+            return VK_FORMAT_R8G8_UNORM;
         case gl::VERTEX_FORMAT_UBYTE3:
-            UNIMPLEMENTED();
-            return VK_FORMAT_UNDEFINED;
+            return VK_FORMAT_R8G8B8_UINT;
         case gl::VERTEX_FORMAT_UBYTE3_NORM:
-            UNIMPLEMENTED();
-            return VK_FORMAT_UNDEFINED;
+            return VK_FORMAT_R8G8B8_UNORM;
         case gl::VERTEX_FORMAT_UBYTE4:
-            UNIMPLEMENTED();
-            return VK_FORMAT_UNDEFINED;
+            return VK_FORMAT_R8G8B8A8_UINT;
         case gl::VERTEX_FORMAT_UBYTE4_NORM:
-            UNIMPLEMENTED();
-            return VK_FORMAT_UNDEFINED;
+            return VK_FORMAT_R8G8B8A8_UNORM;
         case gl::VERTEX_FORMAT_SSHORT1:
             UNIMPLEMENTED();
             return VK_FORMAT_UNDEFINED;
         case gl::VERTEX_FORMAT_SSHORT1_NORM:
             UNIMPLEMENTED();
             return VK_FORMAT_UNDEFINED;
         case gl::VERTEX_FORMAT_SSHORT2:
             UNIMPLEMENTED();
--- a/gfx/angle/src/libANGLE/renderer/vulkan/formatutilsvk.h
+++ b/gfx/angle/src/libANGLE/renderer/vulkan/formatutilsvk.h
@@ -6,53 +6,67 @@
 // Vk::Format:
 //   Vulkan implementation of a storage format.
 
 #ifndef LIBANGLE_RENDERER_VULKAN_FORMAT_H_
 #define LIBANGLE_RENDERER_VULKAN_FORMAT_H_
 
 #include <vulkan/vulkan.h>
 
+#include "libANGLE/formatutils.h"
 #include "libANGLE/renderer/Format.h"
 #include "libANGLE/renderer/renderer_utils.h"
 
+#include <array>
+
+namespace gl
+{
+class TextureCapsMap;
+}  // namespace gl
+
 namespace rx
 {
 
 namespace vk
 {
 
 struct Format final : private angle::NonCopyable
 {
-    constexpr Format(GLenum internalFormat,
-                     angle::Format::ID formatID,
-                     VkFormat native,
-                     InitializeTextureDataFunction initFunction);
+    Format();
 
-    static const Format &Get(GLenum internalFormat);
+    // This is an auto-generated method in vk_format_table_autogen.cpp.
+    void initialize(VkPhysicalDevice physicalDevice, const angle::Format &angleFormat);
 
-    const angle::Format &format() const;
-    LoadFunctionMap getLoadFunctions() const;
+    const angle::Format &textureFormat() const;
+    const angle::Format &bufferFormat() const;
 
     GLenum internalFormat;
-    angle::Format::ID formatID;
-    VkFormat native;
+    angle::Format::ID textureFormatID;
+    VkFormat vkTextureFormat;
+    angle::Format::ID bufferFormatID;
+    VkFormat vkBufferFormat;
     InitializeTextureDataFunction dataInitializerFunction;
+    LoadFunctionMap loadFunctions;
 };
 
-constexpr Format::Format(GLenum internalFormat,
-                         angle::Format::ID formatID,
-                         VkFormat native,
-                         InitializeTextureDataFunction initFunction)
-    : internalFormat(internalFormat),
-      formatID(formatID),
-      native(native),
-      dataInitializerFunction(initFunction)
+class FormatTable final : angle::NonCopyable
 {
-}
+  public:
+    FormatTable();
+    ~FormatTable();
+
+    // Also initializes the TextureCapsMap.
+    void initialize(VkPhysicalDevice physicalDevice, gl::TextureCapsMap *textureCapsMap);
+
+    const Format &operator[](GLenum internalFormat) const;
+
+  private:
+    // The table data is indexed by angle::Format::ID.
+    std::array<Format, angle::kNumANGLEFormats> mFormatData;
+};
 
 // TODO(jmadill): This is temporary. Figure out how to handle format conversions.
 VkFormat GetNativeVertexFormat(gl::VertexFormatType vertexFormat);
 
 }  // namespace vk
 
 }  // namespace rx
 
--- a/gfx/angle/src/libANGLE/renderer/vulkan/gen_vk_format_table.py
+++ b/gfx/angle/src/libANGLE/renderer/vulkan/gen_vk_format_table.py
@@ -36,88 +36,103 @@ template_table_autogen_cpp = """// GENER
 using namespace angle;
 
 namespace rx
 {{
 
 namespace vk
 {{
 
-// static
-const Format &Format::Get(GLenum internalFormat)
+void Format::initialize(VkPhysicalDevice physicalDevice, const angle::Format &angleFormat)
 {{
-    // clang-format off
-    switch (internalFormat)
+    switch (angleFormat.id)
     {{
 {format_case_data}
         default:
+            UNREACHABLE();
             break;
     }}
-    // clang-format on
-
-    UNREACHABLE();
-    static const Format noInfo(GL_NONE, angle::Format::ID::NONE, VK_FORMAT_UNDEFINED, nullptr);
-    return noInfo;
 }}
 
 }}  // namespace vk
 
 }}  // namespace rx
 """
 
-format_entry_template = """{space}{{
-{space}    static constexpr Format info({internalFormat},
-{space}                                 angle::Format::ID::{formatName},
-{space}                                 {vkFormat},
-{space}                                 {initializer});
-{space}    return info;
+empty_format_entry_template = """{space}case angle::Format::ID::{format_id}:
+{space}    // This format is not implemented in Vulkan.
+{space}    break;
+"""
+
+format_entry_template = """{space}case angle::Format::ID::{format_id}:
+{space}{{
+{space}    internalFormat = {internal_format};
+{space}    textureFormatID = angle::Format::ID::{texture_format_id};
+{space}    vkTextureFormat = {vk_texture_format};
+{space}    bufferFormatID = angle::Format::ID::{buffer_format_id};
+{space}    vkBufferFormat = {vk_buffer_format};
+{space}    dataInitializerFunction = {initializer};
+{space}    break;
 {space}}}
 """
 
-def parse_format_case(internal_format, format_name, native_format):
+def gen_format_case(angle, internal_format, vk_map):
 
-    table_data = ""
+    if angle not in vk_map or angle == 'NONE':
+        return empty_format_entry_template.format(
+            space = '        ',
+            format_id = angle)
 
-    parsed = {
-        "space": "        ",
-        "internalFormat": internal_format,
-        "formatName": format_name,
-        "vkFormat": native_format,
-    }
+    texture_format_id = angle
+    buffer_format_id = angle
 
-    # Derived values.
-    parsed["initializer"] = angle_format.get_internal_format_initializer(
-        internal_format, format_name)
+    vk_format_name = vk_map[angle]
+    vk_buffer_format = vk_format_name
+    vk_texture_format = vk_format_name
+
+    if isinstance(vk_format_name, dict):
+        info = vk_format_name
+        vk_format_name = info["native"]
 
-    return format_entry_template.format(**parsed)
-
-def parse_json_into_cases(json_map, vk_map):
-    table_data = ''
-
-    for internal_format, format_name in sorted(json_map.iteritems()):
+        if "buffer" in info:
+            buffer_format_id = info["buffer"]
+            vk_buffer_format = vk_map[buffer_format_id]
+            assert(not isinstance(vk_buffer_format, dict))
+        else:
+            vk_buffer_format = vk_format_name
 
-        if format_name not in vk_map:
-            continue
+        if "texture" in info:
+            texture_format_id = info["texture"]
+            vk_texture_format = vk_map[texture_format_id]
+            assert(not isinstance(vk_texture_format, dict))
+        else:
+            vk_texture_format = vk_format_name
 
-        native_format = vk_map[format_name]
+    initializer = angle_format.get_internal_format_initializer(
+        internal_format, texture_format_id)
 
-        table_data += '        case ' + internal_format + ':\n'
-        table_data += parse_format_case(internal_format, format_name, native_format)
-
-    return table_data
+    return format_entry_template.format(
+        space = '        ',
+        internal_format = internal_format,
+        format_id = angle,
+        texture_format_id = texture_format_id,
+        buffer_format_id = buffer_format_id,
+        vk_buffer_format = vk_buffer_format,
+        vk_texture_format = vk_texture_format,
+        initializer = initializer)
 
 input_file_name = 'vk_format_map.json'
 out_file_name = 'vk_format_table'
 
-json_map = angle_format.load_without_override()
+angle_to_gl = angle_format.load_inverse_table(os.path.join('..', 'angle_format_map.json'))
 vk_map = angle_format.load_json(input_file_name)
+vk_cases = [gen_format_case(angle, gl, vk_map) for angle, gl in sorted(angle_to_gl.iteritems())]
 
-format_case_data = parse_json_into_cases(json_map, vk_map)
 output_cpp = template_table_autogen_cpp.format(
     copyright_year = date.today().year,
-    format_case_data = format_case_data,
+    format_case_data = "\n".join(vk_cases),
     script_name = __file__,
     out_file_name = out_file_name,
     input_file_name = input_file_name)
 
 with open(out_file_name + '_autogen.cpp', 'wt') as out_file:
     out_file.write(output_cpp)
     out_file.close()
--- a/gfx/angle/src/libANGLE/renderer/vulkan/renderervk_utils.cpp
+++ b/gfx/angle/src/libANGLE/renderer/vulkan/renderervk_utils.cpp
@@ -4,16 +4,21 @@
 // found in the LICENSE file.
 //
 // renderervk_utils:
 //    Helper functions for the Vulkan Renderer.
 //
 
 #include "renderervk_utils.h"
 
+#include "libANGLE/Context.h"
+#include "libANGLE/SizedMRUCache.h"
+#include "libANGLE/renderer/vulkan/CommandBufferNode.h"
+#include "libANGLE/renderer/vulkan/ContextVk.h"
+#include "libANGLE/renderer/vulkan/RenderTargetVk.h"
 #include "libANGLE/renderer/vulkan/RendererVk.h"
 
 namespace rx
 {
 
 namespace
 {
 GLenum DefaultGLErrorCode(VkResult result)
@@ -57,23 +62,95 @@ VkAccessFlags GetBasicLayoutAccessFlags(
         case VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL:
             return VK_ACCESS_TRANSFER_WRITE_BIT;
         case VK_IMAGE_LAYOUT_PRESENT_SRC_KHR:
             return VK_ACCESS_MEMORY_READ_BIT;
         case VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL:
             return VK_ACCESS_TRANSFER_READ_BIT;
         case VK_IMAGE_LAYOUT_UNDEFINED:
         case VK_IMAGE_LAYOUT_GENERAL:
+        case VK_IMAGE_LAYOUT_PREINITIALIZED:
             return 0;
         default:
             // TODO(jmadill): Investigate other flags.
             UNREACHABLE();
             return 0;
     }
 }
+
+VkImageUsageFlags GetStagingImageUsageFlags(vk::StagingUsage usage)
+{
+    switch (usage)
+    {
+        case vk::StagingUsage::Read:
+            return VK_IMAGE_USAGE_TRANSFER_DST_BIT;
+        case vk::StagingUsage::Write:
+            return VK_IMAGE_USAGE_TRANSFER_SRC_BIT;
+        case vk::StagingUsage::Both:
+            return (VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT);
+        default:
+            UNREACHABLE();
+            return 0;
+    }
+}
+
+VkImageUsageFlags GetStagingBufferUsageFlags(vk::StagingUsage usage)
+{
+    switch (usage)
+    {
+        case vk::StagingUsage::Read:
+            return VK_BUFFER_USAGE_TRANSFER_DST_BIT;
+        case vk::StagingUsage::Write:
+            return VK_BUFFER_USAGE_TRANSFER_SRC_BIT;
+        case vk::StagingUsage::Both:
+            return (VK_BUFFER_USAGE_TRANSFER_DST_BIT | VK_BUFFER_USAGE_TRANSFER_SRC_BIT);
+        default:
+            UNREACHABLE();
+            return 0;
+    }
+}
+
+VkSampleCountFlagBits ConvertSamples(GLint sampleCount)
+{
+    switch (sampleCount)
+    {
+        case 0:
+        case 1:
+            return VK_SAMPLE_COUNT_1_BIT;
+        case 2:
+            return VK_SAMPLE_COUNT_2_BIT;
+        case 4:
+            return VK_SAMPLE_COUNT_4_BIT;
+        case 8:
+            return VK_SAMPLE_COUNT_8_BIT;
+        case 16:
+            return VK_SAMPLE_COUNT_16_BIT;
+        case 32:
+            return VK_SAMPLE_COUNT_32_BIT;
+        default:
+            UNREACHABLE();
+            return VK_SAMPLE_COUNT_FLAG_BITS_MAX_ENUM;
+    }
+}
+
+void UnpackAttachmentDesc(VkAttachmentDescription *desc,
+                          const vk::PackedAttachmentDesc &packedDesc,
+                          const vk::PackedAttachmentOpsDesc &ops)
+{
+    desc->flags          = static_cast<VkAttachmentDescriptionFlags>(packedDesc.flags);
+    desc->format         = static_cast<VkFormat>(packedDesc.format);
+    desc->samples        = ConvertSamples(packedDesc.samples);
+    desc->loadOp         = static_cast<VkAttachmentLoadOp>(ops.loadOp);
+    desc->storeOp        = static_cast<VkAttachmentStoreOp>(ops.storeOp);
+    desc->stencilLoadOp  = static_cast<VkAttachmentLoadOp>(ops.stencilLoadOp);
+    desc->stencilStoreOp = static_cast<VkAttachmentStoreOp>(ops.stencilStoreOp);
+    desc->initialLayout  = static_cast<VkImageLayout>(ops.initialLayout);
+    desc->finalLayout    = static_cast<VkImageLayout>(ops.finalLayout);
+}
+
 }  // anonymous namespace
 
 // Mirrors std_validation_str in loader.h
 // TODO(jmadill): Possibly wrap the loader into a safe source file. Can't be included trivially.
 const char *g_VkStdValidationLayerName = "VK_LAYER_LUNARG_standard_validation";
 const char *g_VkLoaderLayersPathEnv    = "VK_LAYER_PATH";
 
 const char *VulkanResultString(VkResult result)
@@ -232,101 +309,95 @@ void CommandPool::destroy(VkDevice devic
 Error CommandPool::init(VkDevice device, const VkCommandPoolCreateInfo &createInfo)
 {
     ASSERT(!valid());
     ANGLE_VK_TRY(vkCreateCommandPool(device, &createInfo, nullptr, &mHandle));
     return NoError();
 }
 
 // CommandBuffer implementation.
-CommandBuffer::CommandBuffer() : mStarted(false), mCommandPool(nullptr)
+CommandBuffer::CommandBuffer()
 {
 }
 
-void CommandBuffer::setCommandPool(CommandPool *commandPool)
+VkCommandBuffer CommandBuffer::releaseHandle()
 {
-    ASSERT(!mCommandPool && commandPool->valid());
-    mCommandPool = commandPool;
+    VkCommandBuffer handle = mHandle;
+    mHandle                = nullptr;
+    return handle;
 }
 
-Error CommandBuffer::begin(VkDevice device)
+Error CommandBuffer::init(VkDevice device, const VkCommandBufferAllocateInfo &createInfo)
 {
-    if (mStarted)
-    {
-        return NoError();
-    }
-
-    if (mHandle == VK_NULL_HANDLE)
-    {
-        VkCommandBufferAllocateInfo commandBufferInfo;
-        commandBufferInfo.sType              = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO;
-        commandBufferInfo.pNext              = nullptr;
-        commandBufferInfo.commandPool        = mCommandPool->getHandle();
-        commandBufferInfo.level              = VK_COMMAND_BUFFER_LEVEL_PRIMARY;
-        commandBufferInfo.commandBufferCount = 1;
+    ASSERT(!valid());
+    ANGLE_VK_TRY(vkAllocateCommandBuffers(device, &createInfo, &mHandle));
+    return NoError();
+}
 
-        ANGLE_VK_TRY(vkAllocateCommandBuffers(device, &commandBufferInfo, &mHandle));
-    }
-    else
-    {
-        reset();
-    }
-
-    mStarted = true;
-
-    VkCommandBufferBeginInfo beginInfo;
-    beginInfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
-    beginInfo.pNext = nullptr;
-    // TODO(jmadill): Use other flags?
-    beginInfo.flags            = 0;
-    beginInfo.pInheritanceInfo = nullptr;
-
-    ANGLE_VK_TRY(vkBeginCommandBuffer(mHandle, &beginInfo));
-
+Error CommandBuffer::begin(const VkCommandBufferBeginInfo &info)
+{
+    ASSERT(valid());
+    ANGLE_VK_TRY(vkBeginCommandBuffer(mHandle, &info));
     return NoError();
 }
 
 Error CommandBuffer::end()
 {
-    mStarted = false;
-
     ASSERT(valid());
     ANGLE_VK_TRY(vkEndCommandBuffer(mHandle));
     return NoError();
 }
 
 Error CommandBuffer::reset()
 {
-    mStarted = false;
-
     ASSERT(valid());
     ANGLE_VK_TRY(vkResetCommandBuffer(mHandle, 0));
     return NoError();
 }
 
 void CommandBuffer::singleImageBarrier(VkPipelineStageFlags srcStageMask,
                                        VkPipelineStageFlags dstStageMask,
                                        VkDependencyFlags dependencyFlags,
                                        const VkImageMemoryBarrier &imageMemoryBarrier)
 {
     ASSERT(valid());
     vkCmdPipelineBarrier(mHandle, srcStageMask, dstStageMask, dependencyFlags, 0, nullptr, 0,
                          nullptr, 1, &imageMemoryBarrier);
 }
 
-void CommandBuffer::destroy(VkDevice device)
+void CommandBuffer::singleBufferBarrier(VkPipelineStageFlags srcStageMask,
+                                        VkPipelineStageFlags dstStageMask,
+                                        VkDependencyFlags dependencyFlags,
+                                        const VkBufferMemoryBarrier &bufferBarrier)
+{
+    ASSERT(valid());
+    vkCmdPipelineBarrier(mHandle, srcStageMask, dstStageMask, dependencyFlags, 0, nullptr, 1,
+                         &bufferBarrier, 0, nullptr);
+}
+
+void CommandBuffer::destroy(VkDevice device, const vk::CommandPool &commandPool)
 {
     if (valid())
     {
-        ASSERT(mCommandPool && mCommandPool->valid());
-        vkFreeCommandBuffers(device, mCommandPool->getHandle(), 1, &mHandle);
+        ASSERT(commandPool.valid());
+        vkFreeCommandBuffers(device, commandPool.getHandle(), 1, &mHandle);
         mHandle = VK_NULL_HANDLE;
     }
 }
 
+void CommandBuffer::copyBuffer(const vk::Buffer &srcBuffer,
+                               const vk::Buffer &destBuffer,
+                               uint32_t regionCount,
+                               const VkBufferCopy *regions)
+{
+    ASSERT(valid());
+    ASSERT(srcBuffer.valid() && destBuffer.valid());
+    vkCmdCopyBuffer(mHandle, srcBuffer.getHandle(), destBuffer.getHandle(), regionCount, regions);
+}
+
 void CommandBuffer::clearSingleColorImage(const vk::Image &image, const VkClearColorValue &color)
 {
     ASSERT(valid());
     ASSERT(image.getCurrentLayout() == VK_IMAGE_LAYOUT_GENERAL ||
            image.getCurrentLayout() == VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL);
 
     VkImageSubresourceRange range;
     range.aspectMask     = VK_IMAGE_ASPECT_COLOR_BIT;
@@ -338,22 +409,16 @@ void CommandBuffer::clearSingleColorImag
     vkCmdClearColorImage(mHandle, image.getHandle(), image.getCurrentLayout(), &color, 1, &range);
 }
 
 void CommandBuffer::copySingleImage(const vk::Image &srcImage,
                                     const vk::Image &destImage,
                                     const gl::Box &copyRegion,
                                     VkImageAspectFlags aspectMask)
 {
-    ASSERT(valid());
-    ASSERT(srcImage.getCurrentLayout() == VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL ||
-           srcImage.getCurrentLayout() == VK_IMAGE_LAYOUT_GENERAL);
-    ASSERT(destImage.getCurrentLayout() == VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL ||
-           destImage.getCurrentLayout() == VK_IMAGE_LAYOUT_GENERAL);
-
     VkImageCopy region;
     region.srcSubresource.aspectMask     = aspectMask;
     region.srcSubresource.mipLevel       = 0;
     region.srcSubresource.baseArrayLayer = 0;
     region.srcSubresource.layerCount     = 1;
     region.srcOffset.x                   = copyRegion.x;
     region.srcOffset.y                   = copyRegion.y;
     region.srcOffset.z                   = copyRegion.z;
@@ -363,41 +428,38 @@ void CommandBuffer::copySingleImage(cons
     region.dstSubresource.layerCount     = 1;
     region.dstOffset.x                   = copyRegion.x;
     region.dstOffset.y                   = copyRegion.y;
     region.dstOffset.z                   = copyRegion.z;
     region.extent.width                  = copyRegion.width;
     region.extent.height                 = copyRegion.height;
     region.extent.depth                  = copyRegion.depth;
 
-    vkCmdCopyImage(mHandle, srcImage.getHandle(), srcImage.getCurrentLayout(),
-                   destImage.getHandle(), destImage.getCurrentLayout(), 1, &region);
+    copyImage(srcImage, destImage, 1, &region);
 }
 
-void CommandBuffer::beginRenderPass(const RenderPass &renderPass,
-                                    const Framebuffer &framebuffer,
-                                    const gl::Rectangle &renderArea,
-                                    const std::vector<VkClearValue> &clearValues)
+void CommandBuffer::copyImage(const vk::Image &srcImage,
+                              const vk::Image &dstImage,
+                              uint32_t regionCount,
+                              const VkImageCopy *regions)
 {
-    ASSERT(!clearValues.empty());
-    ASSERT(mHandle != VK_NULL_HANDLE);
+    ASSERT(valid() && srcImage.valid() && dstImage.valid());
+    ASSERT(srcImage.getCurrentLayout() == VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL ||
+           srcImage.getCurrentLayout() == VK_IMAGE_LAYOUT_GENERAL);
+    ASSERT(dstImage.getCurrentLayout() == VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL ||
+           dstImage.getCurrentLayout() == VK_IMAGE_LAYOUT_GENERAL);
+    vkCmdCopyImage(mHandle, srcImage.getHandle(), srcImage.getCurrentLayout(), dstImage.getHandle(),
+                   dstImage.getCurrentLayout(), 1, regions);
+}
 
-    VkRenderPassBeginInfo beginInfo;
-    beginInfo.sType                    = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO;
-    beginInfo.pNext                    = nullptr;
-    beginInfo.renderPass               = renderPass.getHandle();
-    beginInfo.framebuffer              = framebuffer.getHandle();
-    beginInfo.renderArea.offset.x      = static_cast<uint32_t>(renderArea.x);
-    beginInfo.renderArea.offset.y      = static_cast<uint32_t>(renderArea.y);
-    beginInfo.renderArea.extent.width  = static_cast<uint32_t>(renderArea.width);
-    beginInfo.renderArea.extent.height = static_cast<uint32_t>(renderArea.height);
-    beginInfo.clearValueCount          = static_cast<uint32_t>(clearValues.size());
-    beginInfo.pClearValues             = clearValues.data();
-
-    vkCmdBeginRenderPass(mHandle, &beginInfo, VK_SUBPASS_CONTENTS_INLINE);
+void CommandBuffer::beginRenderPass(const VkRenderPassBeginInfo &beginInfo,
+                                    VkSubpassContents subpassContents)
+{
+    ASSERT(valid());
+    vkCmdBeginRenderPass(mHandle, &beginInfo, subpassContents);
 }
 
 void CommandBuffer::endRenderPass()
 {
     ASSERT(mHandle != VK_NULL_HANDLE);
     vkCmdEndRenderPass(mHandle);
 }
 
@@ -405,45 +467,78 @@ void CommandBuffer::draw(uint32_t vertex
                          uint32_t instanceCount,
                          uint32_t firstVertex,
                          uint32_t firstInstance)
 {
     ASSERT(valid());
     vkCmdDraw(mHandle, vertexCount, instanceCount, firstVertex, firstInstance);
 }
 
+void CommandBuffer::drawIndexed(uint32_t indexCount,
+                                uint32_t instanceCount,
+                                uint32_t firstIndex,
+                                int32_t vertexOffset,
+                                uint32_t firstInstance)
+{
+    ASSERT(valid());
+    vkCmdDrawIndexed(mHandle, indexCount, instanceCount, firstIndex, vertexOffset, firstInstance);
+}
+
 void CommandBuffer::bindPipeline(VkPipelineBindPoint pipelineBindPoint,
                                  const vk::Pipeline &pipeline)
 {
     ASSERT(valid() && pipeline.valid());
     vkCmdBindPipeline(mHandle, pipelineBindPoint, pipeline.getHandle());
 }
 
 void CommandBuffer::bindVertexBuffers(uint32_t firstBinding,
-                                      const std::vector<VkBuffer> &buffers,
-                                      const std::vector<VkDeviceSize> &offsets)
+                                      uint32_t bindingCount,
+                                      const VkBuffer *buffers,
+                                      const VkDeviceSize *offsets)
+{
+    ASSERT(valid());
+    vkCmdBindVertexBuffers(mHandle, firstBinding, bindingCount, buffers, offsets);
+}
+
+void CommandBuffer::bindIndexBuffer(const vk::Buffer &buffer,
+                                    VkDeviceSize offset,
+                                    VkIndexType indexType)
 {
-    ASSERT(valid() && buffers.size() == offsets.size());
-    vkCmdBindVertexBuffers(mHandle, firstBinding, static_cast<uint32_t>(buffers.size()),
-                           buffers.data(), offsets.data());
+    ASSERT(valid());
+    vkCmdBindIndexBuffer(mHandle, buffer.getHandle(), offset, indexType);
+}
+
+void CommandBuffer::bindDescriptorSets(VkPipelineBindPoint bindPoint,
+                                       const vk::PipelineLayout &layout,
+                                       uint32_t firstSet,
+                                       uint32_t descriptorSetCount,
+                                       const VkDescriptorSet *descriptorSets,
+                                       uint32_t dynamicOffsetCount,
+                                       const uint32_t *dynamicOffsets)
+{
+    ASSERT(valid());
+    vkCmdBindDescriptorSets(mHandle, bindPoint, layout.getHandle(), firstSet, descriptorSetCount,
+                            descriptorSets, dynamicOffsetCount, dynamicOffsets);
+}
+
+void CommandBuffer::executeCommands(uint32_t commandBufferCount,
+                                    const vk::CommandBuffer *commandBuffers)
+{
+    ASSERT(valid());
+    vkCmdExecuteCommands(mHandle, commandBufferCount, commandBuffers[0].ptr());
 }
 
 // Image implementation.
 Image::Image() : mCurrentLayout(VK_IMAGE_LAYOUT_UNDEFINED)
 {
 }
 
-Image::Image(VkImage image) : WrappedObject(image), mCurrentLayout(VK_IMAGE_LAYOUT_UNDEFINED)
+void Image::setHandle(VkImage handle)
 {
-}
-
-void Image::retain(VkDevice device, Image &&other)
-{
-    WrappedObject::retain(device, std::move(other));
-    std::swap(mCurrentLayout, other.mCurrentLayout);
+    mHandle = handle;
 }
 
 void Image::reset()
 {
     mHandle = VK_NULL_HANDLE;
 }
 
 void Image::destroy(VkDevice device)
@@ -454,16 +549,17 @@ void Image::destroy(VkDevice device)
         mHandle = VK_NULL_HANDLE;
     }
 }
 
 Error Image::init(VkDevice device, const VkImageCreateInfo &createInfo)
 {
     ASSERT(!valid());
     ANGLE_VK_TRY(vkCreateImage(device, &createInfo, nullptr, &mHandle));
+    mCurrentLayout = createInfo.initialLayout;
     return NoError();
 }
 
 void Image::changeLayoutTop(VkImageAspectFlags aspectMask,
                             VkImageLayout newLayout,
                             CommandBuffer *commandBuffer)
 {
     if (newLayout == mCurrentLayout)
@@ -604,16 +700,21 @@ void Framebuffer::destroy(VkDevice devic
 
 Error Framebuffer::init(VkDevice device, const VkFramebufferCreateInfo &createInfo)
 {
     ASSERT(!valid());
     ANGLE_VK_TRY(vkCreateFramebuffer(device, &createInfo, nullptr, &mHandle));
     return NoError();
 }
 
+void Framebuffer::setHandle(VkFramebuffer handle)
+{
+    mHandle = handle;
+}
+
 // DeviceMemory implementation.
 DeviceMemory::DeviceMemory()
 {
 }
 
 void DeviceMemory::destroy(VkDevice device)
 {
     if (valid())
@@ -683,106 +784,102 @@ StagingImage::StagingImage(StagingImage 
 }
 
 void StagingImage::destroy(VkDevice device)
 {
     mImage.destroy(device);
     mDeviceMemory.destroy(device);
 }
 
-void StagingImage::retain(VkDevice device, StagingImage &&other)
-{
-    mImage.retain(device, std::move(other.mImage));
-    mDeviceMemory.retain(device, std::move(other.mDeviceMemory));
-    std::swap(mSize, other.mSize);
-}
-
 Error StagingImage::init(VkDevice device,
                          uint32_t queueFamilyIndex,
-                         uint32_t hostVisibleMemoryIndex,
+                         const vk::MemoryProperties &memoryProperties,
                          TextureDimension dimension,
                          VkFormat format,
-                         const gl::Extents &extent)
+                         const gl::Extents &extent,
+                         StagingUsage usage)
 {
     VkImageCreateInfo createInfo;
 
     createInfo.sType         = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
     createInfo.pNext         = nullptr;
     createInfo.flags         = 0;
     createInfo.imageType     = VK_IMAGE_TYPE_2D;
     createInfo.format        = format;
     createInfo.extent.width  = static_cast<uint32_t>(extent.width);
     createInfo.extent.height = static_cast<uint32_t>(extent.height);
     createInfo.extent.depth  = static_cast<uint32_t>(extent.depth);
     createInfo.mipLevels     = 1;
     createInfo.arrayLayers   = 1;
     createInfo.samples       = VK_SAMPLE_COUNT_1_BIT;
     createInfo.tiling        = VK_IMAGE_TILING_LINEAR;
-    createInfo.usage         = (VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT);
+    createInfo.usage                 = GetStagingImageUsageFlags(usage);
     createInfo.sharingMode   = VK_SHARING_MODE_EXCLUSIVE;
     createInfo.queueFamilyIndexCount = 1;
     createInfo.pQueueFamilyIndices   = &queueFamilyIndex;
-    createInfo.initialLayout         = VK_IMAGE_LAYOUT_UNDEFINED;
+
+    // Use Preinitialized for writable staging images - in these cases we want to map the memory
+    // before we do a copy. For readback images, use an undefined layout.
+    createInfo.initialLayout = usage == vk::StagingUsage::Read ? VK_IMAGE_LAYOUT_UNDEFINED
+                                                               : VK_IMAGE_LAYOUT_PREINITIALIZED;
 
     ANGLE_TRY(mImage.init(device, createInfo));
 
     VkMemoryRequirements memoryRequirements;
     mImage.getMemoryRequirements(device, &memoryRequirements);
 
-    // Ensure we can read this memory.
-    ANGLE_VK_CHECK((memoryRequirements.memoryTypeBits & (1 << hostVisibleMemoryIndex)) != 0,
-                   VK_ERROR_VALIDATION_FAILED_EXT);
+    // Find the right kind of memory index.
+    uint32_t memoryIndex = memoryProperties.findCompatibleMemoryIndex(
+        memoryRequirements.memoryTypeBits, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT);
 
     VkMemoryAllocateInfo allocateInfo;
     allocateInfo.sType           = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
     allocateInfo.pNext           = nullptr;
     allocateInfo.allocationSize  = memoryRequirements.size;
-    allocateInfo.memoryTypeIndex = hostVisibleMemoryIndex;
+    allocateInfo.memoryTypeIndex = memoryIndex;
 
     ANGLE_TRY(mDeviceMemory.allocate(device, allocateInfo));
     ANGLE_TRY(mImage.bindMemory(device, mDeviceMemory));
 
     mSize = memoryRequirements.size;
 
     return NoError();
 }
 
+void StagingImage::dumpResources(Serial serial, std::vector<vk::GarbageObject> *garbageQueue)
+{
+    mImage.dumpResources(serial, garbageQueue);
+    mDeviceMemory.dumpResources(serial, garbageQueue);
+}
+
 // Buffer implementation.
 Buffer::Buffer()
 {
 }
 
 void Buffer::destroy(VkDevice device)
 {
     if (valid())
     {
-        mMemory.destroy(device);
-
         vkDestroyBuffer(device, mHandle, nullptr);
         mHandle = VK_NULL_HANDLE;
     }
 }
 
-void Buffer::retain(VkDevice device, Buffer &&other)
-{
-    WrappedObject::retain(device, std::move(other));
-    mMemory.retain(device, std::move(other.mMemory));
-}
-
 Error Buffer::init(VkDevice device, const VkBufferCreateInfo &createInfo)
 {
     ASSERT(!valid());
     ANGLE_VK_TRY(vkCreateBuffer(device, &createInfo, nullptr, &mHandle));
     return NoError();
 }
 
-Error Buffer::bindMemory(VkDevice device)
+Error Buffer::bindMemory(VkDevice device, const DeviceMemory &deviceMemory)
 {
-    ASSERT(valid() && mMemory.valid());
-    ANGLE_VK_TRY(vkBindBufferMemory(device, mHandle, mMemory.getHandle(), 0));
+    ASSERT(valid() && deviceMemory.valid());
+    ANGLE_VK_TRY(vkBindBufferMemory(device, mHandle, deviceMemory.getHandle(), 0));
     return NoError();
 }
 
 // ShaderModule implementation.
 ShaderModule::ShaderModule()
 {
 }
 
@@ -840,16 +937,88 @@ void PipelineLayout::destroy(VkDevice de
 
 Error PipelineLayout::init(VkDevice device, const VkPipelineLayoutCreateInfo &createInfo)
 {
     ASSERT(!valid());
     ANGLE_VK_TRY(vkCreatePipelineLayout(device, &createInfo, nullptr, &mHandle));
     return NoError();
 }
 
+// DescriptorSetLayout implementation.
+DescriptorSetLayout::DescriptorSetLayout()
+{
+}
+
+void DescriptorSetLayout::destroy(VkDevice device)
+{
+    if (valid())
+    {
+        vkDestroyDescriptorSetLayout(device, mHandle, nullptr);
+        mHandle = VK_NULL_HANDLE;
+    }
+}
+
+Error DescriptorSetLayout::init(VkDevice device, const VkDescriptorSetLayoutCreateInfo &createInfo)
+{
+    ASSERT(!valid());
+    ANGLE_VK_TRY(vkCreateDescriptorSetLayout(device, &createInfo, nullptr, &mHandle));
+    return NoError();
+}
+
+// DescriptorPool implementation.
+DescriptorPool::DescriptorPool()
+{
+}
+
+void DescriptorPool::destroy(VkDevice device)
+{
+    if (valid())
+    {
+        vkDestroyDescriptorPool(device, mHandle, nullptr);
+        mHandle = VK_NULL_HANDLE;
+    }
+}
+
+Error DescriptorPool::init(VkDevice device, const VkDescriptorPoolCreateInfo &createInfo)
+{
+    ASSERT(!valid());
+    ANGLE_VK_TRY(vkCreateDescriptorPool(device, &createInfo, nullptr, &mHandle));
+    return NoError();
+}
+
+Error DescriptorPool::allocateDescriptorSets(VkDevice device,
+                                             const VkDescriptorSetAllocateInfo &allocInfo,
+                                             VkDescriptorSet *descriptorSetsOut)
+{
+    ASSERT(valid());
+    ANGLE_VK_TRY(vkAllocateDescriptorSets(device, &allocInfo, descriptorSetsOut));
+    return NoError();
+}
+
+// Sampler implementation.
+Sampler::Sampler()
+{
+}
+
+void Sampler::destroy(VkDevice device)
+{
+    if (valid())
+    {
+        vkDestroySampler(device, mHandle, nullptr);
+        mHandle = VK_NULL_HANDLE;
+    }
+}
+
+Error Sampler::init(VkDevice device, const VkSamplerCreateInfo &createInfo)
+{
+    ASSERT(!valid());
+    ANGLE_VK_TRY(vkCreateSampler(device, &createInfo, nullptr, &mHandle));
+    return NoError();
+}
+
 // Fence implementation.
 Fence::Fence()
 {
 }
 
 void Fence::destroy(VkDevice device)
 {
     if (valid())
@@ -866,17 +1035,84 @@ Error Fence::init(VkDevice device, const
     return NoError();
 }
 
 VkResult Fence::getStatus(VkDevice device) const
 {
     return vkGetFenceStatus(device, mHandle);
 }
 
-}  // namespace vk
+// MemoryProperties implementation.
+MemoryProperties::MemoryProperties() : mMemoryProperties{0}
+{
+}
+
+void MemoryProperties::init(VkPhysicalDevice physicalDevice)
+{
+    ASSERT(mMemoryProperties.memoryTypeCount == 0);
+    vkGetPhysicalDeviceMemoryProperties(physicalDevice, &mMemoryProperties);
+    ASSERT(mMemoryProperties.memoryTypeCount > 0);
+}
+
+uint32_t MemoryProperties::findCompatibleMemoryIndex(uint32_t bitMask, uint32_t propertyFlags) const
+{
+    ASSERT(mMemoryProperties.memoryTypeCount > 0);
+
+    // TODO(jmadill): Cache compatible memory indexes after finding them once.
+    for (size_t memoryIndex : angle::BitSet32<32>(bitMask))
+    {
+        ASSERT(memoryIndex < mMemoryProperties.memoryTypeCount);
+
+        if ((mMemoryProperties.memoryTypes[memoryIndex].propertyFlags & propertyFlags) ==
+            propertyFlags)
+        {
+            return static_cast<uint32_t>(memoryIndex);
+        }
+    }
+
+    UNREACHABLE();
+    return std::numeric_limits<uint32_t>::max();
+}
+
+// StagingBuffer implementation.
+StagingBuffer::StagingBuffer() : mSize(0)
+{
+}
+
+void StagingBuffer::destroy(VkDevice device)
+{
+    mBuffer.destroy(device);
+    mDeviceMemory.destroy(device);
+    mSize = 0;
+}
+
+vk::Error StagingBuffer::init(ContextVk *contextVk, VkDeviceSize size, StagingUsage usage)
+{
+    VkBufferCreateInfo createInfo;
+    createInfo.sType                 = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO;
+    createInfo.pNext                 = nullptr;
+    createInfo.flags                 = 0;
+    createInfo.size                  = size;
+    createInfo.usage                 = GetStagingBufferUsageFlags(usage);
+    createInfo.sharingMode           = VK_SHARING_MODE_EXCLUSIVE;
+    createInfo.queueFamilyIndexCount = 0;
+    createInfo.pQueueFamilyIndices   = nullptr;
+
+    ANGLE_TRY(mBuffer.init(contextVk->getDevice(), createInfo));
+    ANGLE_TRY(AllocateBufferMemory(contextVk, static_cast<size_t>(size), &mBuffer, &mDeviceMemory,
+                                   &mSize));
+
+    return vk::NoError();
+}
+
+void StagingBuffer::dumpResources(Serial serial, std::vector<vk::GarbageObject> *garbageQueue)
+{
+    mBuffer.dumpResources(serial, garbageQueue);
+    mDeviceMemory.dumpResources(serial, garbageQueue);
+}
 
 Optional<uint32_t> FindMemoryType(const VkPhysicalDeviceMemoryProperties &memoryProps,
                                   const VkMemoryRequirements &requirements,
                                   uint32_t propertyFlagMask)
 {
     for (uint32_t typeIndex = 0; typeIndex < memoryProps.memoryTypeCount; ++typeIndex)
     {
         if ((requirements.memoryTypeBits & (1u << typeIndex)) != 0 &&
@@ -885,16 +1121,336 @@ Optional<uint32_t> FindMemoryType(const 
         {
             return typeIndex;
         }
     }
 
     return Optional<uint32_t>::Invalid();
 }
 
+Error AllocateBufferMemory(ContextVk *contextVk,
+                           size_t size,
+                           Buffer *buffer,
+                           DeviceMemory *deviceMemoryOut,
+                           size_t *requiredSizeOut)
+{
+    VkDevice device = contextVk->getDevice();
+
+    // Find a compatible memory pool index. If the index doesn't change, we could cache it.
+    // Not finding a valid memory pool means an out-of-spec driver, or internal error.
+    // TODO(jmadill): More efficient memory allocation.
+    VkMemoryRequirements memoryRequirements;
+    vkGetBufferMemoryRequirements(device, buffer->getHandle(), &memoryRequirements);
+
+    // The requirements size is not always equal to the specified API size.
+    ASSERT(memoryRequirements.size >= size);
+    *requiredSizeOut = static_cast<size_t>(memoryRequirements.size);
+
+    VkPhysicalDeviceMemoryProperties memoryProperties;
+    vkGetPhysicalDeviceMemoryProperties(contextVk->getRenderer()->getPhysicalDevice(),
+                                        &memoryProperties);
+
+    auto memoryTypeIndex =
+        FindMemoryType(memoryProperties, memoryRequirements,
+                       VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT);
+    ANGLE_VK_CHECK(memoryTypeIndex.valid(), VK_ERROR_INCOMPATIBLE_DRIVER);
+
+    VkMemoryAllocateInfo allocInfo;
+    allocInfo.sType           = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
+    allocInfo.pNext           = nullptr;
+    allocInfo.memoryTypeIndex = memoryTypeIndex.value();
+    allocInfo.allocationSize  = memoryRequirements.size;
+
+    ANGLE_TRY(deviceMemoryOut->allocate(device, allocInfo));
+    ANGLE_TRY(buffer->bindMemory(device, *deviceMemoryOut));
+
+    return NoError();
+}
+
+// GarbageObject implementation.
+GarbageObject::GarbageObject()
+    : mSerial(), mHandleType(HandleType::Invalid), mHandle(VK_NULL_HANDLE)
+{
+}
+
+GarbageObject::GarbageObject(const GarbageObject &other) = default;
+
+GarbageObject &GarbageObject::operator=(const GarbageObject &other) = default;
+
+bool GarbageObject::destroyIfComplete(VkDevice device, Serial completedSerial)
+{
+    if (completedSerial >= mSerial)
+    {
+        destroy(device);
+        return true;
+    }
+
+    return false;
+}
+
+void GarbageObject::destroy(VkDevice device)
+{
+    switch (mHandleType)
+    {
+        case HandleType::Semaphore:
+            vkDestroySemaphore(device, reinterpret_cast<VkSemaphore>(mHandle), nullptr);
+            break;
+        case HandleType::CommandBuffer:
+            // Command buffers are pool allocated.
+            UNREACHABLE();
+            break;
+        case HandleType::Fence:
+            vkDestroyFence(device, reinterpret_cast<VkFence>(mHandle), nullptr);
+            break;
+        case HandleType::DeviceMemory:
+            vkFreeMemory(device, reinterpret_cast<VkDeviceMemory>(mHandle), nullptr);
+            break;
+        case HandleType::Buffer:
+            vkDestroyBuffer(device, reinterpret_cast<VkBuffer>(mHandle), nullptr);
+            break;
+        case HandleType::Image:
+            vkDestroyImage(device, reinterpret_cast<VkImage>(mHandle), nullptr);
+            break;
+        case HandleType::ImageView:
+            vkDestroyImageView(device, reinterpret_cast<VkImageView>(mHandle), nullptr);
+            break;
+        case HandleType::ShaderModule:
+            vkDestroyShaderModule(device, reinterpret_cast<VkShaderModule>(mHandle), nullptr);
+            break;
+        case HandleType::PipelineLayout:
+            vkDestroyPipelineLayout(device, reinterpret_cast<VkPipelineLayout>(mHandle), nullptr);
+            break;
+        case HandleType::RenderPass:
+            vkDestroyRenderPass(device, reinterpret_cast<VkRenderPass>(mHandle), nullptr);
+            break;
+        case HandleType::Pipeline:
+            vkDestroyPipeline(device, reinterpret_cast<VkPipeline>(mHandle), nullptr);
+            break;
+        case HandleType::DescriptorSetLayout:
+            vkDestroyDescriptorSetLayout(device, reinterpret_cast<VkDescriptorSetLayout>(mHandle),
+                                         nullptr);
+            break;
+        case HandleType::Sampler:
+            vkDestroySampler(device, reinterpret_cast<VkSampler>(mHandle), nullptr);
+            break;
+        case HandleType::DescriptorPool:
+            vkDestroyDescriptorPool(device, reinterpret_cast<VkDescriptorPool>(mHandle), nullptr);
+            break;
+        case HandleType::Framebuffer:
+            vkDestroyFramebuffer(device, reinterpret_cast<VkFramebuffer>(mHandle), nullptr);
+            break;
+        case HandleType::CommandPool:
+            vkDestroyCommandPool(device, reinterpret_cast<VkCommandPool>(mHandle), nullptr);
+            break;
+        default:
+            UNREACHABLE();
+            break;
+    }
+}
+
+// RenderPassDesc implementation.
+RenderPassDesc::RenderPassDesc()
+{
+    memset(this, 0, sizeof(RenderPassDesc));
+}
+
+RenderPassDesc::~RenderPassDesc()
+{
+}
+
+RenderPassDesc::RenderPassDesc(const RenderPassDesc &other)
+{
+    memcpy(this, &other, sizeof(RenderPassDesc));
+}
+
+void RenderPassDesc::packAttachment(uint32_t index, const vk::Format &format, GLsizei samples)
+{
+    PackedAttachmentDesc &desc = mAttachmentDescs[index];
+
+    // TODO(jmadill): We would only need this flag for duplicated attachments.
+    desc.flags = VK_ATTACHMENT_DESCRIPTION_MAY_ALIAS_BIT;
+    ASSERT(desc.samples < std::numeric_limits<uint8_t>::max());
+    desc.samples = static_cast<uint8_t>(samples);
+    ASSERT(format.vkTextureFormat < std::numeric_limits<uint16_t>::max());
+    desc.format = static_cast<uint16_t>(format.vkTextureFormat);
+}
+
+void RenderPassDesc::packColorAttachment(const vk::Format &format, GLsizei samples)
+{
+    ASSERT(mDepthStencilAttachmentCount == 0);
+    ASSERT(mColorAttachmentCount < gl::IMPLEMENTATION_MAX_DRAW_BUFFERS);
+    packAttachment(mColorAttachmentCount++, format, samples);
+}
+
+void RenderPassDesc::packDepthStencilAttachment(const vk::Format &format, GLsizei samples)
+{
+    ASSERT(mDepthStencilAttachmentCount == 0);
+    packAttachment(mDepthStencilAttachmentCount++, format, samples);
+}
+
+RenderPassDesc &RenderPassDesc::operator=(const RenderPassDesc &other)
+{
+    memcpy(this, &other, sizeof(RenderPassDesc));
+    return *this;
+}
+
+size_t RenderPassDesc::hash() const
+{
+    return angle::ComputeGenericHash(*this);
+}
+
+uint32_t RenderPassDesc::attachmentCount() const
+{
+    return (mColorAttachmentCount + mDepthStencilAttachmentCount);
+}
+
+uint32_t RenderPassDesc::colorAttachmentCount() const
+{
+    return mColorAttachmentCount;
+}
+
+uint32_t RenderPassDesc::depthStencilAttachmentCount() const
+{
+    return mDepthStencilAttachmentCount;
+}
+
+const PackedAttachmentDesc &RenderPassDesc::operator[](size_t index) const
+{
+    ASSERT(index < mAttachmentDescs.size());
+    return mAttachmentDescs[index];
+}
+
+bool operator==(const RenderPassDesc &lhs, const RenderPassDesc &rhs)
+{
+    return (memcmp(&lhs, &rhs, sizeof(RenderPassDesc)) == 0);
+}
+
+// AttachmentOpsArray implementation.
+AttachmentOpsArray::AttachmentOpsArray()
+{
+    memset(&mOps, 0, sizeof(PackedAttachmentOpsDesc) * mOps.size());
+}
+
+AttachmentOpsArray::~AttachmentOpsArray()
+{
+}
+
+AttachmentOpsArray::AttachmentOpsArray(const AttachmentOpsArray &other)
+{
+    memcpy(&mOps, &other.mOps, sizeof(PackedAttachmentOpsDesc) * mOps.size());
+}
+
+AttachmentOpsArray &AttachmentOpsArray::operator=(const AttachmentOpsArray &other)
+{
+    memcpy(&mOps, &other.mOps, sizeof(PackedAttachmentOpsDesc) * mOps.size());
+    return *this;
+}
+
+const PackedAttachmentOpsDesc &AttachmentOpsArray::operator[](size_t index) const
+{
+    return mOps[index];
+}
+
+PackedAttachmentOpsDesc &AttachmentOpsArray::operator[](size_t index)
+{
+    return mOps[index];
+}
+
+void AttachmentOpsArray::initDummyOp(size_t index, VkImageLayout finalLayout)
+{
+    PackedAttachmentOpsDesc &ops = mOps[index];
+
+    ops.loadOp         = VK_ATTACHMENT_LOAD_OP_CLEAR;
+    ops.storeOp        = VK_ATTACHMENT_STORE_OP_STORE;
+    ops.stencilLoadOp  = VK_ATTACHMENT_LOAD_OP_DONT_CARE;
+    ops.stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE;
+    ops.initialLayout  = static_cast<uint16_t>(VK_IMAGE_LAYOUT_UNDEFINED);
+    ops.finalLayout    = static_cast<uint16_t>(finalLayout);
+}
+
+size_t AttachmentOpsArray::hash() const
+{
+    return angle::ComputeGenericHash(mOps);
+}
+
+bool operator==(const AttachmentOpsArray &lhs, const AttachmentOpsArray &rhs)
+{
+    return (memcmp(&lhs, &rhs, sizeof(AttachmentOpsArray)) == 0);
+}
+
+Error InitializeRenderPassFromDesc(VkDevice device,
+                                   const RenderPassDesc &desc,
+                                   const AttachmentOpsArray &ops,
+                                   RenderPass *renderPass)
+{
+    uint32_t attachmentCount = desc.attachmentCount();
+    ASSERT(attachmentCount > 0);
+
+    gl::DrawBuffersArray<VkAttachmentReference> colorAttachmentRefs;
+
+    for (uint32_t colorIndex = 0; colorIndex < desc.colorAttachmentCount(); ++colorIndex)
+    {
+        VkAttachmentReference &colorRef = colorAttachmentRefs[colorIndex];
+        colorRef.attachment             = colorIndex;
+        colorRef.layout                 = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
+    }
+
+    VkAttachmentReference depthStencilAttachmentRef;
+    if (desc.depthStencilAttachmentCount() > 0)
+    {
+        ASSERT(desc.depthStencilAttachmentCount() == 1);
+        depthStencilAttachmentRef.attachment = desc.colorAttachmentCount();
+        depthStencilAttachmentRef.layout     = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL;
+    }
+
+    VkSubpassDescription subpassDesc;
+
+    subpassDesc.flags                = 0;
+    subpassDesc.pipelineBindPoint    = VK_PIPELINE_BIND_POINT_GRAPHICS;
+    subpassDesc.inputAttachmentCount = 0;
+    subpassDesc.pInputAttachments    = nullptr;
+    subpassDesc.colorAttachmentCount = desc.colorAttachmentCount();
+    subpassDesc.pColorAttachments    = colorAttachmentRefs.data();
+    subpassDesc.pResolveAttachments  = nullptr;
+    subpassDesc.pDepthStencilAttachment =
+        (desc.depthStencilAttachmentCount() > 0 ? &depthStencilAttachmentRef : nullptr);
+    subpassDesc.preserveAttachmentCount = 0;
+    subpassDesc.pPreserveAttachments    = nullptr;
+
+    // Unpack the packed and split representation into the format required by Vulkan.
+    gl::AttachmentArray<VkAttachmentDescription> attachmentDescs;
+    for (uint32_t colorIndex = 0; colorIndex < desc.colorAttachmentCount(); ++colorIndex)
+    {
+        UnpackAttachmentDesc(&attachmentDescs[colorIndex], desc[colorIndex], ops[colorIndex]);
+    }
+
+    if (desc.depthStencilAttachmentCount() > 0)
+    {
+        uint32_t depthStencilIndex = desc.colorAttachmentCount();
+        UnpackAttachmentDesc(&attachmentDescs[depthStencilIndex], desc[depthStencilIndex],
+                             ops[depthStencilIndex]);
+    }
+
+    VkRenderPassCreateInfo createInfo;
+    createInfo.sType           = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO;
+    createInfo.pNext           = nullptr;
+    createInfo.flags           = 0;
+    createInfo.attachmentCount = attachmentCount;
+    createInfo.pAttachments    = attachmentDescs.data();
+    createInfo.subpassCount    = 1;
+    createInfo.pSubpasses      = &subpassDesc;
+    createInfo.dependencyCount = 0;
+    createInfo.pDependencies   = nullptr;
+
+    ANGLE_TRY(renderPass->init(device, createInfo));
+    return vk::NoError();
+}
+
+}  // namespace vk
+
 namespace gl_vk
 {
 VkPrimitiveTopology GetPrimitiveTopology(GLenum mode)
 {
     switch (mode)
     {
         case GL_TRIANGLES:
             return VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST;
@@ -922,21 +1478,21 @@ VkCullModeFlags GetCullMode(const gl::Ra
 {
     if (!rasterState.cullFace)
     {
         return VK_CULL_MODE_NONE;
     }
 
     switch (rasterState.cullMode)
     {
-        case GL_FRONT:
+        case gl::CullFaceMode::Front:
             return VK_CULL_MODE_FRONT_BIT;
-        case GL_BACK:
+        case gl::CullFaceMode::Back:
             return VK_CULL_MODE_BACK_BIT;
-        case GL_FRONT_AND_BACK:
+        case gl::CullFaceMode::FrontAndBack:
             return VK_CULL_MODE_FRONT_AND_BACK;
         default:
             UNREACHABLE();
             return VK_CULL_MODE_NONE;
     }
 }
 
 VkFrontFace GetFrontFace(GLenum frontFace)
@@ -950,15 +1506,104 @@ VkFrontFace GetFrontFace(GLenum frontFac
         default:
             UNREACHABLE();
             return VK_FRONT_FACE_COUNTER_CLOCKWISE;
     }
 }
 
 }  // namespace gl_vk
 
+ResourceVk::ResourceVk() : mCurrentWriteNode(nullptr)
+{
+}
+
+ResourceVk::~ResourceVk()
+{
+}
+
+void ResourceVk::updateQueueSerial(Serial queueSerial)
+{
+    ASSERT(queueSerial >= mStoredQueueSerial);
+
+    if (queueSerial > mStoredQueueSerial)
+    {
+        mCurrentWriteNode = nullptr;
+        mCurrentReadNodes.clear();
+        mStoredQueueSerial = queueSerial;
+    }
+}
+
+Serial ResourceVk::getQueueSerial() const
+{
+    return mStoredQueueSerial;
+}
+
+bool ResourceVk::isCurrentlyRecording(Serial currentSerial) const
+{
+    return (mStoredQueueSerial == currentSerial && mCurrentWriteNode != nullptr);
+}
+
+vk::CommandBufferNode *ResourceVk::getCurrentWriteNode(Serial currentSerial)
+{
+    ASSERT(currentSerial == mStoredQueueSerial);
+    return mCurrentWriteNode;
+}
+
+vk::CommandBufferNode *ResourceVk::getNewWriteNode(RendererVk *renderer)
+{
+    vk::CommandBufferNode *newCommands = renderer->allocateCommandNode();
+    setWriteNode(renderer->getCurrentQueueSerial(), newCommands);
+    return newCommands;
+}
+
+void ResourceVk::setWriteNode(Serial serial, vk::CommandBufferNode *newCommands)
+{
+    updateQueueSerial(serial);
+
+    // Make sure any open reads and writes finish before we execute |newCommands|.
+    if (!mCurrentReadNodes.empty())
+    {
+        newCommands->addDependencies(mCurrentReadNodes);
+        mCurrentReadNodes.clear();
+    }
+
+    if (mCurrentWriteNode)
+    {
+        newCommands->addDependency(mCurrentWriteNode);
+    }
+
+    mCurrentWriteNode = newCommands;
+}
+
+vk::Error ResourceVk::recordWriteCommands(RendererVk *renderer,
+                                          vk::CommandBuffer **commandBufferOut)
+{
+    vk::CommandBufferNode *commands = getNewWriteNode(renderer);
+
+    VkDevice device = renderer->getDevice();
+    ANGLE_TRY(commands->startRecording(device, renderer->getCommandPool(), commandBufferOut));
+    return vk::NoError();
+}
+
+void ResourceVk::updateDependencies(vk::CommandBufferNode *readNode, Serial serial)
+{
+    if (isCurrentlyRecording(serial))
+    {
+        // Link the current write node to "readNode".
+        readNode->addDependency(getCurrentWriteNode(serial));
+        ASSERT(mStoredQueueSerial == serial);
+    }
+    else
+    {
+        updateQueueSerial(serial);
+    }
+
+    // Track "readNode" in this resource.
+    mCurrentReadNodes.push_back(readNode);
+}
+
 }  // namespace rx
 
 std::ostream &operator<<(std::ostream &stream, const rx::vk::Error &error)
 {
     stream << error.toString();
     return stream;
 }
--- a/gfx/angle/src/libANGLE/renderer/vulkan/renderervk_utils.h
+++ b/gfx/angle/src/libANGLE/renderer/vulkan/renderervk_utils.h
@@ -14,86 +14,118 @@
 
 #include <vulkan/vulkan.h>
 
 #include "common/Optional.h"
 #include "common/debug.h"
 #include "libANGLE/Error.h"
 #include "libANGLE/renderer/renderer_utils.h"
 
+#define ANGLE_GL_OBJECTS_X(PROC) \
+    PROC(Buffer)                 \
+    PROC(Context)                \
+    PROC(Framebuffer)            \
+    PROC(Program)                \
+    PROC(Texture)                \
+    PROC(VertexArray)
+
+#define ANGLE_PRE_DECLARE_OBJECT(OBJ) class OBJ;
+
+namespace egl
+{
+class Display;
+}
+
 namespace gl
 {
 struct Box;
 struct Extents;
 struct RasterizerState;
 struct Rectangle;
+
+ANGLE_GL_OBJECTS_X(ANGLE_PRE_DECLARE_OBJECT);
 }
 
+#define ANGLE_PRE_DECLARE_VK_OBJECT(OBJ) class OBJ##Vk;
+
 namespace rx
 {
+class DisplayVk;
+class RenderTargetVk;
+class RendererVk;
+class ResourceVk;
+
+enum class DrawType
+{
+    Arrays,
+    Elements,
+};
+
+ANGLE_GL_OBJECTS_X(ANGLE_PRE_DECLARE_VK_OBJECT);
+
 const char *VulkanResultString(VkResult result);
 bool HasStandardValidationLayer(const std::vector<VkLayerProperties> &layerProps);
 
 extern const char *g_VkStdValidationLayerName;
 extern const char *g_VkLoaderLayersPathEnv;
 
 enum class TextureDimension
 {
     TEX_2D,
     TEX_CUBE,
     TEX_3D,
     TEX_2D_ARRAY,
 };
 
-enum DeleteSchedule
+namespace vk
 {
-    NOW,
-    LATER,
+class CommandBufferNode;
+struct Format;
+
+template <typename T>
+struct ImplTypeHelper;
+
+// clang-format off
+#define ANGLE_IMPL_TYPE_HELPER_GL(OBJ) \
+template<>                             \
+struct ImplTypeHelper<gl::OBJ>         \
+{                                      \
+    using ImplType = OBJ##Vk;          \
+};
+// clang-format on
+
+ANGLE_GL_OBJECTS_X(ANGLE_IMPL_TYPE_HELPER_GL)
+
+template <>
+struct ImplTypeHelper<egl::Display>
+{
+    using ImplType = DisplayVk;
 };
 
-// This is a small helper mixin for any GL object used in Vk command buffers. It records a serial
-// at command submission times indicating it's order in the queue. We will use Fences to detect
-// when commands are finished, and then handle lifetime management for the resources.
-// Note that we use a queue order serial instead of a command buffer id serial since a queue can
-// submit multiple command buffers in one API call.
-class ResourceVk
+template <typename T>
+using GetImplType = typename ImplTypeHelper<T>::ImplType;
+
+template <typename T>
+GetImplType<T> *GetImpl(const T *glObject)
+{
+    return GetImplAs<GetImplType<T>>(glObject);
+}
+
+class MemoryProperties final : angle::NonCopyable
 {
   public:
-    void setQueueSerial(Serial queueSerial)
-    {
-        ASSERT(queueSerial >= mStoredQueueSerial);
-        mStoredQueueSerial = queueSerial;
-    }
+    MemoryProperties();
 
-    DeleteSchedule getDeleteSchedule(Serial lastCompletedQueueSerial) const
-    {
-        if (lastCompletedQueueSerial >= mStoredQueueSerial)
-        {
-            return DeleteSchedule::NOW;
-        }
-        else
-        {
-            return DeleteSchedule::LATER;
-        }
-    }
-
-    Serial getStoredQueueSerial() const { return mStoredQueueSerial; }
+    void init(VkPhysicalDevice physicalDevice);
+    uint32_t findCompatibleMemoryIndex(uint32_t bitMask, uint32_t propertyFlags) const;
 
   private:
-    Serial mStoredQueueSerial;
+    VkPhysicalDeviceMemoryProperties mMemoryProperties;
 };
 
-namespace vk
-{
-class DeviceMemory;
-class Framebuffer;
-class Image;
-class Pipeline;
-class RenderPass;
-
 class Error final
 {
   public:
     Error(VkResult result);
     Error(VkResult result, const char *file, unsigned int line);
     ~Error();
 
     Error(const Error &other);
@@ -125,129 +157,238 @@ template <typename ResultT>
 using ErrorOrResult = angle::ErrorOrResultBase<Error, ResultT, VkResult, VK_SUCCESS>;
 
 // Avoid conflicting with X headers which define "Success".
 inline Error NoError()
 {
     return Error(VK_SUCCESS);
 }
 
+// Unimplemented handle types:
+// Instance
+// PhysicalDevice
+// Device
+// Queue
+// Event
+// QueryPool
+// BufferView
+// DescriptorSet
+// PipelineCache
+
+#define ANGLE_HANDLE_TYPES_X(FUNC) \
+    FUNC(Semaphore)                \
+    FUNC(CommandBuffer)            \
+    FUNC(Fence)                    \
+    FUNC(DeviceMemory)             \
+    FUNC(Buffer)                   \
+    FUNC(Image)                    \
+    FUNC(ImageView)                \
+    FUNC(ShaderModule)             \
+    FUNC(PipelineLayout)           \
+    FUNC(RenderPass)               \
+    FUNC(Pipeline)                 \
+    FUNC(DescriptorSetLayout)      \
+    FUNC(Sampler)                  \
+    FUNC(DescriptorPool)           \
+    FUNC(Framebuffer)              \
+    FUNC(CommandPool)
+
+#define ANGLE_COMMA_SEP_FUNC(TYPE) TYPE,
+
+enum class HandleType
+{
+    Invalid,
+    ANGLE_HANDLE_TYPES_X(ANGLE_COMMA_SEP_FUNC)
+};
+
+#undef ANGLE_COMMA_SEP_FUNC
+
+#define ANGLE_PRE_DECLARE_CLASS_FUNC(TYPE) class TYPE;
+ANGLE_HANDLE_TYPES_X(ANGLE_PRE_DECLARE_CLASS_FUNC)
+#undef ANGLE_PRE_DECLARE_CLASS_FUNC
+
+// Returns the HandleType of a Vk Handle.
+template <typename T>
+struct HandleTypeHelper;
+
+// clang-format off
+#define ANGLE_HANDLE_TYPE_HELPER_FUNC(TYPE)                     \
+template<> struct HandleTypeHelper<TYPE>                        \
+{                                                               \
+    constexpr static HandleType kHandleType = HandleType::TYPE; \
+};
+// clang-format on
+
+ANGLE_HANDLE_TYPES_X(ANGLE_HANDLE_TYPE_HELPER_FUNC)
+
+#undef ANGLE_HANDLE_TYPE_HELPER_FUNC
+
+class GarbageObject final
+{
+  public:
+    template <typename ObjectT>
+    GarbageObject(Serial serial, const ObjectT &object)
+        : mSerial(serial),
+          mHandleType(HandleTypeHelper<ObjectT>::kHandleType),
+          mHandle(reinterpret_cast<VkDevice>(object.getHandle()))
+    {
+    }
+
+    GarbageObject();
+    GarbageObject(const GarbageObject &other);
+    GarbageObject &operator=(const GarbageObject &other);
+
+    bool destroyIfComplete(VkDevice device, Serial completedSerial);
+    void destroy(VkDevice device);
+
+  private:
+    // TODO(jmadill): Since many objects will have the same serial, it might be more efficient to
+    // store the serial outside of the garbage object itself. We could index ranges of garbage
+    // objects in the Renderer, using a circular buffer.
+    Serial mSerial;
+    HandleType mHandleType;
+    VkDevice mHandle;
+};
+
 template <typename DerivedT, typename HandleT>
 class WrappedObject : angle::NonCopyable
 {
   public:
     HandleT getHandle() const { return mHandle; }
     bool valid() const { return (mHandle != VK_NULL_HANDLE); }
 
     const HandleT *ptr() const { return &mHandle; }
 
+    void dumpResources(Serial serial, std::vector<vk::GarbageObject> *garbageQueue)
+    {
+        if (valid())
+        {
+            garbageQueue->emplace_back(serial, *static_cast<DerivedT *>(this));
+            mHandle = VK_NULL_HANDLE;
+        }
+    }
+
   protected:
     WrappedObject() : mHandle(VK_NULL_HANDLE) {}
-    WrappedObject(HandleT handle) : mHandle(handle) {}
     ~WrappedObject() { ASSERT(!valid()); }
 
     WrappedObject(WrappedObject &&other) : mHandle(other.mHandle)
     {
         other.mHandle = VK_NULL_HANDLE;
     }
 
     // Only works to initialize empty objects, since we don't have the device handle.
     WrappedObject &operator=(WrappedObject &&other)
     {
         ASSERT(!valid());
         std::swap(mHandle, other.mHandle);
         return *this;
     }
 
-    void retain(VkDevice device, DerivedT &&other)
-    {
-        if (valid())
-        {
-            static_cast<DerivedT *>(this)->destroy(device);
-        }
-        std::swap(mHandle, other.mHandle);
-    }
-
     HandleT mHandle;
 };
 
 class CommandPool final : public WrappedObject<CommandPool, VkCommandPool>
 {
   public:
     CommandPool();
 
     void destroy(VkDevice device);
 
     Error init(VkDevice device, const VkCommandPoolCreateInfo &createInfo);
 };
 
 // Helper class that wraps a Vulkan command buffer.
-class CommandBuffer final : public WrappedObject<CommandBuffer, VkCommandBuffer>
+class CommandBuffer : public WrappedObject<CommandBuffer, VkCommandBuffer>
 {
   public:
     CommandBuffer();
 
-    bool started() const { return mStarted; }
-
-    void destroy(VkDevice device);
+    VkCommandBuffer releaseHandle();
+    void destroy(VkDevice device, const vk::CommandPool &commandPool);
+    Error init(VkDevice device, const VkCommandBufferAllocateInfo &createInfo);
     using WrappedObject::operator=;
 
-    void setCommandPool(CommandPool *commandPool);
-    Error begin(VkDevice device);
+    Error begin(const VkCommandBufferBeginInfo &info);
+
     Error end();
     Error reset();
 
     void singleImageBarrier(VkPipelineStageFlags srcStageMask,
                             VkPipelineStageFlags dstStageMask,
                             VkDependencyFlags dependencyFlags,
                             const VkImageMemoryBarrier &imageMemoryBarrier);
 
+    void singleBufferBarrier(VkPipelineStageFlags srcStageMask,
+                             VkPipelineStageFlags dstStageMask,
+                             VkDependencyFlags dependencyFlags,
+                             const VkBufferMemoryBarrier &bufferBarrier);
+
     void clearSingleColorImage(const vk::Image &image, const VkClearColorValue &color);
 
+    void copyBuffer(const vk::Buffer &srcBuffer,
+                    const vk::Buffer &destBuffer,
+                    uint32_t regionCount,
+                    const VkBufferCopy *regions);
+
     void copySingleImage(const vk::Image &srcImage,
                          const vk::Image &destImage,
                          const gl::Box &copyRegion,
                          VkImageAspectFlags aspectMask);
 
-    void beginRenderPass(const RenderPass &renderPass,
-                         const Framebuffer &framebuffer,
-                         const gl::Rectangle &renderArea,
-                         const std::vector<VkClearValue> &clearValues);
+    void copyImage(const vk::Image &srcImage,
+                   const vk::Image &dstImage,
+                   uint32_t regionCount,
+                   const VkImageCopy *regions);
+
+    void beginRenderPass(const VkRenderPassBeginInfo &beginInfo, VkSubpassContents subpassContents);
     void endRenderPass();
 
     void draw(uint32_t vertexCount,
               uint32_t instanceCount,
               uint32_t firstVertex,
               uint32_t firstInstance);
 
+    void drawIndexed(uint32_t indexCount,
+                     uint32_t instanceCount,
+                     uint32_t firstIndex,
+                     int32_t vertexOffset,
+                     uint32_t firstInstance);
+
     void bindPipeline(VkPipelineBindPoint pipelineBindPoint, const vk::Pipeline &pipeline);
     void bindVertexBuffers(uint32_t firstBinding,
-                           const std::vector<VkBuffer> &buffers,
-                           const std::vector<VkDeviceSize> &offsets);
+                           uint32_t bindingCount,
+                           const VkBuffer *buffers,
+                           const VkDeviceSize *offsets);
+    void bindIndexBuffer(const vk::Buffer &buffer, VkDeviceSize offset, VkIndexType indexType);
+    void bindDescriptorSets(VkPipelineBindPoint bindPoint,
+                            const vk::PipelineLayout &layout,
+                            uint32_t firstSet,
+                            uint32_t descriptorSetCount,
+                            const VkDescriptorSet *descriptorSets,
+                            uint32_t dynamicOffsetCount,
+                            const uint32_t *dynamicOffsets);
 
-  private:
-    bool mStarted;
-    CommandPool *mCommandPool;
+    void executeCommands(uint32_t commandBufferCount, const vk::CommandBuffer *commandBuffers);
 };
 
 class Image final : public WrappedObject<Image, VkImage>
 {
   public:
-    // Use this constructor if the lifetime of the image is not controlled by ANGLE. (SwapChain)
     Image();
-    explicit Image(VkImage image);
+
+    // Use this method if the lifetime of the image is not controlled by ANGLE. (SwapChain)
+    void setHandle(VkImage handle);
 
     // Called on shutdown when the helper class *doesn't* own the handle to the image resource.
     void reset();
 
     // Called on shutdown when the helper class *does* own the handle to the image resource.
     void destroy(VkDevice device);
 
-    void retain(VkDevice device, Image &&other);
-
     Error init(VkDevice device, const VkImageCreateInfo &createInfo);
 
     void changeLayoutTop(VkImageAspectFlags aspectMask,
                          VkImageLayout newLayout,
                          CommandBuffer *commandBuffer);
 
     void changeLayoutWithStages(VkImageAspectFlags aspectMask,
                                 VkImageLayout newLayout,
@@ -265,153 +406,203 @@ class Image final : public WrappedObject
     VkImageLayout mCurrentLayout;
 };
 
 class ImageView final : public WrappedObject<ImageView, VkImageView>
 {
   public:
     ImageView();
     void destroy(VkDevice device);
-    using WrappedObject::retain;
 
     Error init(VkDevice device, const VkImageViewCreateInfo &createInfo);
 };
 
 class Semaphore final : public WrappedObject<Semaphore, VkSemaphore>
 {
   public:
     Semaphore();
     void destroy(VkDevice device);
-    using WrappedObject::retain;
 
     Error init(VkDevice device);
 };
 
 class Framebuffer final : public WrappedObject<Framebuffer, VkFramebuffer>
 {
   public:
     Framebuffer();
     void destroy(VkDevice device);
-    using WrappedObject::retain;
+
+    // Use this method only in necessary cases. (RenderPass)
+    void setHandle(VkFramebuffer handle);
 
     Error init(VkDevice device, const VkFramebufferCreateInfo &createInfo);
 };
 
 class DeviceMemory final : public WrappedObject<DeviceMemory, VkDeviceMemory>
 {
   public:
     DeviceMemory();
     void destroy(VkDevice device);
-    using WrappedObject::retain;
 
     Error allocate(VkDevice device, const VkMemoryAllocateInfo &allocInfo);
     Error map(VkDevice device,
               VkDeviceSize offset,
               VkDeviceSize size,
               VkMemoryMapFlags flags,
               uint8_t **mapPointer);
     void unmap(VkDevice device);
 };
 
 class RenderPass final : public WrappedObject<RenderPass, VkRenderPass>
 {
   public:
     RenderPass();
     void destroy(VkDevice device);
-    using WrappedObject::retain;
 
     Error init(VkDevice device, const VkRenderPassCreateInfo &createInfo);
 };
 
-class StagingImage final : angle::NonCopyable
+enum class StagingUsage
 {
-  public:
-    StagingImage();
-    StagingImage(StagingImage &&other);
-    void destroy(VkDevice device);
-    void retain(VkDevice device, StagingImage &&other);
-
-    vk::Error init(VkDevice device,
-                   uint32_t queueFamilyIndex,
-                   uint32_t hostVisibleMemoryIndex,
-                   TextureDimension dimension,
-                   VkFormat format,
-                   const gl::Extents &extent);
-
-    Image &getImage() { return mImage; }
-    const Image &getImage() const { return mImage; }
-    DeviceMemory &getDeviceMemory() { return mDeviceMemory; }
-    const DeviceMemory &getDeviceMemory() const { return mDeviceMemory; }
-    VkDeviceSize getSize() const { return mSize; }
-
-  private:
-    Image mImage;
-    DeviceMemory mDeviceMemory;
-    VkDeviceSize mSize;
+    Read,
+    Write,
+    Both,
 };
 
 class Buffer final : public WrappedObject<Buffer, VkBuffer>
 {
   public:
     Buffer();
     void destroy(VkDevice device);
-    void retain(VkDevice device, Buffer &&other);
 
     Error init(VkDevice device, const VkBufferCreateInfo &createInfo);
-    Error bindMemory(VkDevice device);
-
-    DeviceMemory &getMemory() { return mMemory; }
-    const DeviceMemory &getMemory() const { return mMemory; }
-
-  private:
-    DeviceMemory mMemory;
+    Error bindMemory(VkDevice device, const DeviceMemory &deviceMemory);
 };
 
 class ShaderModule final : public WrappedObject<ShaderModule, VkShaderModule>
 {
   public:
     ShaderModule();
     void destroy(VkDevice device);
-    using WrappedObject::retain;
 
     Error init(VkDevice device, const VkShaderModuleCreateInfo &createInfo);
 };
 
 class Pipeline final : public WrappedObject<Pipeline, VkPipeline>
 {
   public:
     Pipeline();
     void destroy(VkDevice device);
-    using WrappedObject::retain;
 
     Error initGraphics(VkDevice device, const VkGraphicsPipelineCreateInfo &createInfo);
 };
 
 class PipelineLayout final : public WrappedObject<PipelineLayout, VkPipelineLayout>
 {
   public:
     PipelineLayout();
     void destroy(VkDevice device);
-    using WrappedObject::retain;
 
     Error init(VkDevice device, const VkPipelineLayoutCreateInfo &createInfo);
 };
 
+class DescriptorSetLayout final : public WrappedObject<DescriptorSetLayout, VkDescriptorSetLayout>
+{
+  public:
+    DescriptorSetLayout();
+    void destroy(VkDevice device);
+
+    Error init(VkDevice device, const VkDescriptorSetLayoutCreateInfo &createInfo);
+};
+
+class DescriptorPool final : public WrappedObject<DescriptorPool, VkDescriptorPool>
+{
+  public:
+    DescriptorPool();
+    void destroy(VkDevice device);
+
+    Error init(VkDevice device, const VkDescriptorPoolCreateInfo &createInfo);
+
+    Error allocateDescriptorSets(VkDevice device,
+                                 const VkDescriptorSetAllocateInfo &allocInfo,
+                                 VkDescriptorSet *descriptorSetsOut);
+};
+
+class Sampler final : public WrappedObject<Sampler, VkSampler>
+{
+  public:
+    Sampler();
+    void destroy(VkDevice device);
+    Error init(VkDevice device, const VkSamplerCreateInfo &createInfo);
+};
+
 class Fence final : public WrappedObject<Fence, VkFence>
 {
   public:
     Fence();
     void destroy(VkDevice fence);
-    using WrappedObject::retain;
     using WrappedObject::operator=;
 
     Error init(VkDevice device, const VkFenceCreateInfo &createInfo);
     VkResult getStatus(VkDevice device) const;
 };
 
+// Helper class for managing a CPU/GPU transfer Image.
+class StagingImage final : angle::NonCopyable
+{
+  public:
+    StagingImage();
+    StagingImage(StagingImage &&other);
+    void destroy(VkDevice device);
+
+    vk::Error init(VkDevice device,
+                   uint32_t queueFamilyIndex,
+                   const MemoryProperties &memoryProperties,
+                   TextureDimension dimension,
+                   VkFormat format,
+                   const gl::Extents &extent,
+                   StagingUsage usage);
+
+    Image &getImage() { return mImage; }
+    const Image &getImage() const { return mImage; }
+    DeviceMemory &getDeviceMemory() { return mDeviceMemory; }
+    const DeviceMemory &getDeviceMemory() const { return mDeviceMemory; }
+    VkDeviceSize getSize() const { return mSize; }
+
+    void dumpResources(Serial serial, std::vector<vk::GarbageObject> *garbageQueue);
+
+  private:
+    Image mImage;
+    DeviceMemory mDeviceMemory;
+    VkDeviceSize mSize;
+};
+
+// Similar to StagingImage, for Buffers.
+class StagingBuffer final : angle::NonCopyable
+{
+  public:
+    StagingBuffer();
+    void destroy(VkDevice device);
+
+    vk::Error init(ContextVk *contextVk, VkDeviceSize size, StagingUsage usage);
+
+    Buffer &getBuffer() { return mBuffer; }
+    const Buffer &getBuffer() const { return mBuffer; }
+    DeviceMemory &getDeviceMemory() { return mDeviceMemory; }
+    const DeviceMemory &getDeviceMemory() const { return mDeviceMemory; }
+    size_t getSize() const { return mSize; }
+
+    void dumpResources(Serial serial, std::vector<vk::GarbageObject> *garbageQueue);
+
+  private:
+    Buffer mBuffer;
+    DeviceMemory mDeviceMemory;
+    size_t mSize;
+};
+
 template <typename ObjT>
 class ObjectAndSerial final : angle::NonCopyable
 {
   public:
     ObjectAndSerial(ObjT &&object, Serial queueSerial)
         : mObject(std::move(object)), mQueueSerial(queueSerial)
     {
     }
@@ -422,84 +613,205 @@ class ObjectAndSerial final : angle::Non
     }
     ObjectAndSerial &operator=(ObjectAndSerial &&other)
     {
         mObject      = std::move(other.mObject);
         mQueueSerial = std::move(other.mQueueSerial);
         return *this;
     }
 
-    void destroy(VkDevice device) { mObject.destroy(device); }
-
     Serial queueSerial() const { return mQueueSerial; }
+    void updateSerial(Serial newSerial)
+    {
+        ASSERT(newSerial >= mQueueSerial);
+        mQueueSerial = newSerial;
+    }
 
     const ObjT &get() const { return mObject; }
+    ObjT &get() { return mObject; }
 
   private:
     ObjT mObject;
     Serial mQueueSerial;
 };
 
-using CommandBufferAndSerial = ObjectAndSerial<CommandBuffer>;
-using FenceAndSerial         = ObjectAndSerial<Fence>;
-
-class IGarbageObject : angle::NonCopyable
-{
-  public:
-    virtual ~IGarbageObject() {}
-    virtual bool destroyIfComplete(VkDevice device, Serial completedSerial) = 0;
-    virtual void destroy(VkDevice device) = 0;
-};
-
-template <typename T>
-class GarbageObject final : public IGarbageObject
-{
-  public:
-    GarbageObject(Serial serial, T &&object) : mSerial(serial), mObject(std::move(object)) {}
-
-    bool destroyIfComplete(VkDevice device, Serial completedSerial) override
-    {
-        if (completedSerial >= mSerial)
-        {
-            mObject.destroy(device);
-            return true;
-        }
-
-        return false;
-    }
-
-    void destroy(VkDevice device) override { mObject.destroy(device); }
-
-  private:
-    Serial mSerial;
-    T mObject;
-};
-
-}  // namespace vk
-
 Optional<uint32_t> FindMemoryType(const VkPhysicalDeviceMemoryProperties &memoryProps,
                                   const VkMemoryRequirements &requirements,
                                   uint32_t propertyFlagMask);
 
+Error AllocateBufferMemory(ContextVk *contextVk,
+                           size_t size,
+                           Buffer *buffer,
+                           DeviceMemory *deviceMemoryOut,
+                           size_t *requiredSizeOut);
+
+struct BufferAndMemory final : private angle::NonCopyable
+{
+    vk::Buffer buffer;
+    vk::DeviceMemory memory;
+};
+
+using CommandBufferAndSerial = ObjectAndSerial<CommandBuffer>;
+using FenceAndSerial         = ObjectAndSerial<Fence>;
+using RenderPassAndSerial    = ObjectAndSerial<RenderPass>;
+
+struct alignas(4) PackedAttachmentDesc
+{
+    uint8_t flags;
+    uint8_t samples;
+    uint16_t format;
+};
+
+struct alignas(8) PackedAttachmentOpsDesc final
+{
+    uint8_t loadOp;
+    uint8_t storeOp;
+    uint8_t stencilLoadOp;
+    uint8_t stencilStoreOp;
+
+    // 16-bits to force pad the structure to exactly 8 bytes.
+    uint16_t initialLayout;
+    uint16_t finalLayout;
+};
+
+class RenderPassDesc final
+{
+  public:
+    RenderPassDesc();
+    ~RenderPassDesc();
+    RenderPassDesc(const RenderPassDesc &other);
+    RenderPassDesc &operator=(const RenderPassDesc &other);
+
+    // Depth stencil attachments must be packed after color attachments.
+    void packColorAttachment(const Format &format, GLsizei samples);
+    void packDepthStencilAttachment(const Format &format, GLsizei samples);
+
+    size_t hash() const;
+
+    uint32_t attachmentCount() const;
+    uint32_t colorAttachmentCount() const;
+    uint32_t depthStencilAttachmentCount() const;
+    const PackedAttachmentDesc &operator[](size_t index) const;
+
+  private:
+    void packAttachment(uint32_t index, const vk::Format &format, GLsizei samples);
+
+    uint32_t mColorAttachmentCount;
+    uint32_t mDepthStencilAttachmentCount;
+    gl::AttachmentArray<PackedAttachmentDesc> mAttachmentDescs;
+};
+
+bool operator==(const RenderPassDesc &lhs, const RenderPassDesc &rhs);
+
+class AttachmentOpsArray final
+{
+  public:
+    AttachmentOpsArray();
+    ~AttachmentOpsArray();
+    AttachmentOpsArray(const AttachmentOpsArray &other);
+    AttachmentOpsArray &operator=(const AttachmentOpsArray &other);
+
+    const PackedAttachmentOpsDesc &operator[](size_t index) const;
+    PackedAttachmentOpsDesc &operator[](size_t index);
+
+    // Initializes an attachment op with whatever values. Used for compatible RenderPass checks.
+    void initDummyOp(size_t index, VkImageLayout finalLayout);
+
+    size_t hash() const;
+
+  private:
+    gl::AttachmentArray<PackedAttachmentOpsDesc> mOps;
+};
+
+bool operator==(const AttachmentOpsArray &lhs, const AttachmentOpsArray &rhs);
+
+static_assert(sizeof(PackedAttachmentDesc) == 4, "Size check failed");
+static_assert(sizeof(PackedAttachmentOpsDesc) == 8, "Size check failed");
+static_assert(sizeof(RenderPassDesc) == 48, "Size check failed");
+static_assert(sizeof(AttachmentOpsArray) == 80, "Size check failed");
+
+Error InitializeRenderPassFromDesc(VkDevice device,
+                                   const RenderPassDesc &desc,
+                                   const AttachmentOpsArray &ops,
+                                   RenderPass *renderPass);
+
+}  // namespace vk
+
 namespace gl_vk
 {
 VkPrimitiveTopology GetPrimitiveTopology(GLenum mode);
 VkCullModeFlags GetCullMode(const gl::RasterizerState &rasterState);
 VkFrontFace GetFrontFace(GLenum frontFace);
 }  // namespace gl_vk
 
+// This is a helper class for back-end objects used in Vk command buffers. It records a serial
+// at command recording times indicating an order in the queue. We use Fences to detect when
+// commands finish, and then release any unreferenced and deleted resources based on the stored
+// queue serial in a special 'garbage' queue. Resources also track current read and write
+// dependencies. Only one command buffer node can be writing to the Resource at a time, but many
+// can be reading from it. Together the dependencies will form a command graph at submission time.
+class ResourceVk
+{
+  public:
+    ResourceVk();
+    virtual ~ResourceVk();
+
+    void updateQueueSerial(Serial queueSerial);
+    Serial getQueueSerial() const;
+
+    // Returns true if any tracked read or write nodes match |currentSerial|.
+    bool isCurrentlyRecording(Serial currentSerial) const;
+
+    // Returns the active write node, and asserts |currentSerial| matches the stored serial.
+    vk::CommandBufferNode *getCurrentWriteNode(Serial currentSerial);
+
+    // Allocates a new write node and calls setWriteNode internally.
+    vk::CommandBufferNode *getNewWriteNode(RendererVk *renderer);
+
+    // Called on an operation that will modify this ResourceVk.
+    void setWriteNode(Serial serial, vk::CommandBufferNode *newCommands);
+
+    // Allocates a write node via getNewWriteNode and returns a started command buffer.
+    // The started command buffer will render outside of a RenderPass.
+    vk::Error recordWriteCommands(RendererVk *renderer, vk::CommandBuffer **commandBufferOut);
+
+    // Sets up the dependency relations. |readNode| has the commands that read from this object.
+    void updateDependencies(vk::CommandBufferNode *readNode, Serial serial);
+
+  private:
+    Serial mStoredQueueSerial;
+    std::vector<vk::CommandBufferNode *> mCurrentReadNodes;
+    vk::CommandBufferNode *mCurrentWriteNode;
+};
+
 }  // namespace rx
 
 #define ANGLE_VK_TRY(command)                                          \
     {                                                                  \
         auto ANGLE_LOCAL_VAR = command;                                \
         if (ANGLE_LOCAL_VAR != VK_SUCCESS)                             \
         {                                                              \
             return rx::vk::Error(ANGLE_LOCAL_VAR, __FILE__, __LINE__); \
         }                                                              \
     }                                                                  \
     ANGLE_EMPTY_STATEMENT
 
 #define ANGLE_VK_CHECK(test, error) ANGLE_VK_TRY(test ? VK_SUCCESS : error)
 
 std::ostream &operator<<(std::ostream &stream, const rx::vk::Error &error);
 
+// Introduce a std::hash for a RenderPassDesc
+namespace std
+{
+template <>
+struct hash<rx::vk::RenderPassDesc>
+{
+    size_t operator()(const rx::vk::RenderPassDesc &key) const { return key.hash(); }
+};
+
+template <>
+struct hash<rx::vk::AttachmentOpsArray>
+{
+    size_t operator()(const rx::vk::AttachmentOpsArray &key) const { return key.hash(); }
+};
+}  // namespace std
+
 #endif  // LIBANGLE_RENDERER_VULKAN_RENDERERVK_UTILS_H_
--- a/gfx/angle/src/libANGLE/renderer/vulkan/vk_format_map.json
+++ b/gfx/angle/src/libANGLE/renderer/vulkan/vk_format_map.json
@@ -12,17 +12,20 @@
     "R8_UINT": "VK_FORMAT_R8_UINT",
     "R8_SINT": "VK_FORMAT_R8_SINT",
     "R8_SRGB": "VK_FORMAT_R8_SRGB",
     "R8G8_UNORM": "VK_FORMAT_R8G8_UNORM",
     "R8G8_SNORM": "VK_FORMAT_R8G8_SNORM",
     "R8G8_UINT": "VK_FORMAT_R8G8_UINT",
     "R8G8_SINT": "VK_FORMAT_R8G8_SINT",
     "R8G8_SRGB": "VK_FORMAT_R8G8_SRGB",
-    "R8G8B8_UNORM": "VK_FORMAT_R8G8B8_UNORM",
+    "R8G8B8_UNORM": {
+        "native": "VK_FORMAT_R8G8B8_UNORM",
+        "texture": "R8G8B8A8_UNORM"
+    },
     "R8G8B8_SNORM": "VK_FORMAT_R8G8B8_SNORM",
     "R8G8B8_UINT": "VK_FORMAT_R8G8B8_UINT",
     "R8G8B8_SINT": "VK_FORMAT_R8G8B8_SINT",
     "R8G8B8_SRGB": "VK_FORMAT_R8G8B8_SRGB",
     "B8G8R8_UNORM": "VK_FORMAT_B8G8R8_UNORM",
     "B8G8R8_SNORM": "VK_FORMAT_B8G8R8_SNORM",
     "B8G8R8_UINT": "VK_FORMAT_B8G8R8_UINT",
     "B8G8R8_SINT": "VK_FORMAT_B8G8R8_SINT",
--- a/gfx/angle/src/libANGLE/renderer/vulkan/vk_format_table_autogen.cpp
+++ b/gfx/angle/src/libANGLE/renderer/vulkan/vk_format_table_autogen.cpp
@@ -1,12 +1,12 @@
 // GENERATED FILE - DO NOT EDIT.
 // Generated by gen_vk_format_table.py using data from vk_format_map.json
 //
-// Copyright 2016 The ANGLE Project Authors. All rights reserved.
+// 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.
 //
 // vk_format_table:
 //   Queries for full Vulkan format information based on GL format.
 
 #include "libANGLE/renderer/vulkan/formatutilsvk.h"
 
@@ -17,852 +17,1219 @@
 using namespace angle;
 
 namespace rx
 {
 
 namespace vk
 {
 
-// static
-const Format &Format::Get(GLenum internalFormat)
+void Format::initialize(VkPhysicalDevice physicalDevice, const angle::Format &angleFormat)
 {
-    // clang-format off
-    switch (internalFormat)
+    switch (angleFormat.id)
     {
-        case GL_BGR565_ANGLEX:
+        case angle::Format::ID::A16_FLOAT:
+            // This format is not implemented in Vulkan.
+            break;
+
+        case angle::Format::ID::A32_FLOAT:
+            // This format is not implemented in Vulkan.
+            break;
+
+        case angle::Format::ID::A8_UNORM:
+            // This format is not implemented in Vulkan.
+            break;
+
+        case angle::Format::ID::ASTC_10x10_SRGB_BLOCK:
         {
-            static constexpr Format info(GL_BGR565_ANGLEX,
-                                         angle::Format::ID::B5G6R5_UNORM,
-                                         VK_FORMAT_B5G6R5_UNORM_PACK16,
-                                         nullptr);
-            return info;
+            internalFormat          = GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x10_KHR;
+            textureFormatID         = angle::Format::ID::ASTC_10x10_SRGB_BLOCK;
+            vkTextureFormat         = VK_FORMAT_ASTC_10x10_SRGB_BLOCK;
+            bufferFormatID          = angle::Format::ID::ASTC_10x10_SRGB_BLOCK;
+            vkBufferFormat          = VK_FORMAT_ASTC_10x10_SRGB_BLOCK;
+            dataInitializerFunction = nullptr;
+            break;
         }
-        case GL_BGR5_A1_ANGLEX:
-        {
-            static constexpr Format info(GL_BGR5_A1_ANGLEX,
-                                         angle::Format::ID::B5G5R5A1_UNORM,
-                                         VK_FORMAT_B5G5R5A1_UNORM_PACK16,
-                                         nullptr);
-            return info;
-        }
-        case GL_BGRA4_ANGLEX:
+
+        case angle::Format::ID::ASTC_10x10_UNORM_BLOCK:
         {
-            static constexpr Format info(GL_BGRA4_ANGLEX,
-                                         angle::Format::ID::B4G4R4A4_UNORM,
-                                         VK_FORMAT_B4G4R4A4_UNORM_PACK16,
-                                         nullptr);
-            return info;
+            internalFormat          = GL_COMPRESSED_RGBA_ASTC_10x10_KHR;
+            textureFormatID         = angle::Format::ID::ASTC_10x10_UNORM_BLOCK;
+            vkTextureFormat         = VK_FORMAT_ASTC_10x10_UNORM_BLOCK;
+            bufferFormatID          = angle::Format::ID::ASTC_10x10_UNORM_BLOCK;
+            vkBufferFormat          = VK_FORMAT_ASTC_10x10_UNORM_BLOCK;
+            dataInitializerFunction = nullptr;
+            break;
         }
-        case GL_BGRA8_EXT:
+
+        case angle::Format::ID::ASTC_10x5_SRGB_BLOCK:
         {
-            static constexpr Format info(GL_BGRA8_EXT,
-                                         angle::Format::ID::B8G8R8A8_UNORM,
-                                         VK_FORMAT_B8G8R8A8_UNORM,
-                                         nullptr);
-            return info;
+            internalFormat          = GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x5_KHR;
+            textureFormatID         = angle::Format::ID::ASTC_10x5_SRGB_BLOCK;
+            vkTextureFormat         = VK_FORMAT_ASTC_10x5_SRGB_BLOCK;
+            bufferFormatID          = angle::Format::ID::ASTC_10x5_SRGB_BLOCK;
+            vkBufferFormat          = VK_FORMAT_ASTC_10x5_SRGB_BLOCK;
+            dataInitializerFunction = nullptr;
+            break;
         }
-        case GL_COMPRESSED_R11_EAC:
+
+        case angle::Format::ID::ASTC_10x5_UNORM_BLOCK:
         {
-            static constexpr Format info(GL_COMPRESSED_R11_EAC,
-                                         angle::Format::ID::EAC_R11_UNORM_BLOCK,
-                                         VK_FORMAT_EAC_R11_UNORM_BLOCK,
-                                         nullptr);
-            return info;
+            internalFormat          = GL_COMPRESSED_RGBA_ASTC_10x5_KHR;
+            textureFormatID         = angle::Format::ID::ASTC_10x5_UNORM_BLOCK;
+            vkTextureFormat         = VK_FORMAT_ASTC_10x5_UNORM_BLOCK;
+            bufferFormatID          = angle::Format::ID::ASTC_10x5_UNORM_BLOCK;
+            vkBufferFormat          = VK_FORMAT_ASTC_10x5_UNORM_BLOCK;
+            dataInitializerFunction = nullptr;
+            break;
         }
-        case GL_COMPRESSED_RG11_EAC:
+
+        case angle::Format::ID::ASTC_10x6_SRGB_BLOCK:
         {
-            static constexpr Format info(GL_COMPRESSED_RG11_EAC,
-                                         angle::Format::ID::EAC_R11G11_UNORM_BLOCK,
-                                         VK_FORMAT_EAC_R11G11_UNORM_BLOCK,
-                                         nullptr);
-            return info;
+            internalFormat          = GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x6_KHR;
+            textureFormatID         = angle::Format::ID::ASTC_10x6_SRGB_BLOCK;
+            vkTextureFormat         = VK_FORMAT_ASTC_10x6_SRGB_BLOCK;
+            bufferFormatID          = angle::Format::ID::ASTC_10x6_SRGB_BLOCK;
+            vkBufferFormat          = VK_FORMAT_ASTC_10x6_SRGB_BLOCK;
+            dataInitializerFunction = nullptr;
+            break;
         }
-        case GL_COMPRESSED_RGB8_ETC2:
+
+        case angle::Format::ID::ASTC_10x6_UNORM_BLOCK:
         {
-            static constexpr Format info(GL_COMPRESSED_RGB8_ETC2,
-                                         angle::Format::ID::ETC2_R8G8B8_UNORM_BLOCK,
-                                         VK_FORMAT_ETC2_R8G8B8_UNORM_BLOCK,
-                                         nullptr);
-            return info;
+            internalFormat          = GL_COMPRESSED_RGBA_ASTC_10x6_KHR;
+            textureFormatID         = angle::Format::ID::ASTC_10x6_UNORM_BLOCK;
+            vkTextureFormat         = VK_FORMAT_ASTC_10x6_UNORM_BLOCK;
+            bufferFormatID          = angle::Format::ID::ASTC_10x6_UNORM_BLOCK;
+            vkBufferFormat          = VK_FORMAT_ASTC_10x6_UNORM_BLOCK;
+            dataInitializerFunction = nullptr;
+            break;
         }
-        case GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2:
+
+        case angle::Format::ID::ASTC_10x8_SRGB_BLOCK:
         {
-            static constexpr Format info(GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2,
-                                         angle::Format::ID::ETC2_R8G8B8A1_UNORM_BLOCK,
-                                         VK_FORMAT_ETC2_R8G8B8A1_UNORM_BLOCK,
-                                         Initialize4ComponentData<GLubyte, 0x00, 0x00, 0x00, 0xFF>);
-            return info;
+            internalFormat          = GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x8_KHR;
+            textureFormatID         = angle::Format::ID::ASTC_10x8_SRGB_BLOCK;
+            vkTextureFormat         = VK_FORMAT_ASTC_10x8_SRGB_BLOCK;
+            bufferFormatID          = angle::Format::ID::ASTC_10x8_SRGB_BLOCK;
+            vkBufferFormat          = VK_FORMAT_ASTC_10x8_SRGB_BLOCK;
+            dataInitializerFunction = nullptr;
+            break;
         }
-        case GL_COMPRESSED_RGBA8_ETC2_EAC:
+
+        case angle::Format::ID::ASTC_10x8_UNORM_BLOCK:
         {
-            static constexpr Format info(GL_COMPRESSED_RGBA8_ETC2_EAC,
-                                         angle::Format::ID::ETC2_R8G8B8A8_UNORM_BLOCK,
-                                         VK_FORMAT_ETC2_R8G8B8A8_UNORM_BLOCK,
-                                         nullptr);
-            return info;
+            internalFormat          = GL_COMPRESSED_RGBA_ASTC_10x8_KHR;
+            textureFormatID         = angle::Format::ID::ASTC_10x8_UNORM_BLOCK;
+            vkTextureFormat         = VK_FORMAT_ASTC_10x8_UNORM_BLOCK;
+            bufferFormatID          = angle::Format::ID::ASTC_10x8_UNORM_BLOCK;
+            vkBufferFormat          = VK_FORMAT_ASTC_10x8_UNORM_BLOCK;
+            dataInitializerFunction = nullptr;
+            break;
         }
-        case GL_COMPRESSED_RGBA_ASTC_10x10_KHR:
+
+        case angle::Format::ID::ASTC_12x10_SRGB_BLOCK:
         {
-            static constexpr Format info(GL_COMPRESSED_RGBA_ASTC_10x10_KHR,
-                                         angle::Format::ID::ASTC_10x10_UNORM_BLOCK,
-                                         VK_FORMAT_ASTC_10x10_UNORM_BLOCK,
-                                         nullptr);
-            return info;
+            internalFormat          = GL_COMPRESSED_SRGB8_ALPHA8_ASTC_12x10_KHR;
+            textureFormatID         = angle::Format::ID::ASTC_12x10_SRGB_BLOCK;
+            vkTextureFormat         = VK_FORMAT_ASTC_12x10_SRGB_BLOCK;
+            bufferFormatID          = angle::Format::ID::ASTC_12x10_SRGB_BLOCK;
+            vkBufferFormat          = VK_FORMAT_ASTC_12x10_SRGB_BLOCK;
+            dataInitializerFunction = nullptr;
+            break;
         }
-        case GL_COMPRESSED_RGBA_ASTC_10x5_KHR:
+
+        case angle::Format::ID::ASTC_12x10_UNORM_BLOCK:
         {
-            static constexpr Format info(GL_COMPRESSED_RGBA_ASTC_10x5_KHR,
-                                         angle::Format::ID::ASTC_10x5_UNORM_BLOCK,
-                                         VK_FORMAT_ASTC_10x5_UNORM_BLOCK,
-                                         nullptr);
-            return info;
+            internalFormat          = GL_COMPRESSED_RGBA_ASTC_12x10_KHR;
+            textureFormatID         = angle::Format::ID::ASTC_12x10_UNORM_BLOCK;
+            vkTextureFormat         = VK_FORMAT_ASTC_12x10_UNORM_BLOCK;
+            bufferFormatID          = angle::Format::ID::ASTC_12x10_UNORM_BLOCK;
+            vkBufferFormat          = VK_FORMAT_ASTC_12x10_UNORM_BLOCK;
+            dataInitializerFunction = nullptr;
+            break;
         }
-        case GL_COMPRESSED_RGBA_ASTC_10x6_KHR:
+
+        case angle::Format::ID::ASTC_12x12_SRGB_BLOCK:
+            // This format is not implemented in Vulkan.
+            break;
+
+        case angle::Format::ID::ASTC_12x12_UNORM_BLOCK:
         {
-            static constexpr Format info(GL_COMPRESSED_RGBA_ASTC_10x6_KHR,
-                                         angle::Format::ID::ASTC_10x6_UNORM_BLOCK,
-                                         VK_FORMAT_ASTC_10x6_UNORM_BLOCK,
-                                         nullptr);
-            return info;
+            internalFormat          = GL_COMPRESSED_RGBA_ASTC_12x12_KHR;
+            textureFormatID         = angle::Format::ID::ASTC_12x12_UNORM_BLOCK;
+            vkTextureFormat         = VK_FORMAT_ASTC_12x12_UNORM_BLOCK;
+            bufferFormatID          = angle::Format::ID::ASTC_12x12_UNORM_BLOCK;
+            vkBufferFormat          = VK_FORMAT_ASTC_12x12_UNORM_BLOCK;
+            dataInitializerFunction = nullptr;
+            break;
         }
-        case GL_COMPRESSED_RGBA_ASTC_10x8_KHR:
+
+        case angle::Format::ID::ASTC_4x4_SRGB_BLOCK:
         {
-            static constexpr Format info(GL_COMPRESSED_RGBA_ASTC_10x8_KHR,
-                                         angle::Format::ID::ASTC_10x8_UNORM_BLOCK,
-                                         VK_FORMAT_ASTC_10x8_UNORM_BLOCK,
-                                         nullptr);
-            return info;
+            internalFormat          = GL_COMPRESSED_SRGB8_ALPHA8_ASTC_4x4_KHR;
+            textureFormatID         = angle::Format::ID::ASTC_4x4_SRGB_BLOCK;
+            vkTextureFormat         = VK_FORMAT_ASTC_4x4_SRGB_BLOCK;
+            bufferFormatID          = angle::Format::ID::ASTC_4x4_SRGB_BLOCK;
+            vkBufferFormat          = VK_FORMAT_ASTC_4x4_SRGB_BLOCK;
+            dataInitializerFunction = nullptr;
+            break;
         }
-        case GL_COMPRESSED_RGBA_ASTC_12x10_KHR:
+
+        case angle::Format::ID::ASTC_4x4_UNORM_BLOCK:
         {
-            static constexpr Format info(GL_COMPRESSED_RGBA_ASTC_12x10_KHR,
-                                         angle::Format::ID::ASTC_12x10_UNORM_BLOCK,
-                                         VK_FORMAT_ASTC_12x10_UNORM_BLOCK,
-                                         nullptr);
-            return info;
+            internalFormat          = GL_COMPRESSED_RGBA_ASTC_4x4_KHR;
+            textureFormatID         = angle::Format::ID::ASTC_4x4_UNORM_BLOCK;
+            vkTextureFormat         = VK_FORMAT_ASTC_4x4_UNORM_BLOCK;
+            bufferFormatID          = angle::Format::ID::ASTC_4x4_UNORM_BLOCK;
+            vkBufferFormat          = VK_FORMAT_ASTC_4x4_UNORM_BLOCK;
+            dataInitializerFunction = nullptr;
+            break;
         }
-        case GL_COMPRESSED_RGBA_ASTC_12x12_KHR:
+
+        case angle::Format::ID::ASTC_5x4_SRGB_BLOCK:
         {
-            static constexpr Format info(GL_COMPRESSED_RGBA_ASTC_12x12_KHR,
-                                         angle::Format::ID::ASTC_12x12_UNORM_BLOCK,
-                                         VK_FORMAT_ASTC_12x12_UNORM_BLOCK,
-                                         nullptr);
-            return info;
+            internalFormat          = GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x4_KHR;
+            textureFormatID         = angle::Format::ID::ASTC_5x4_SRGB_BLOCK;
+            vkTextureFormat         = VK_FORMAT_ASTC_5x4_SRGB_BLOCK;
+            bufferFormatID          = angle::Format::ID::ASTC_5x4_SRGB_BLOCK;
+            vkBufferFormat          = VK_FORMAT_ASTC_5x4_SRGB_BLOCK;
+            dataInitializerFunction = nullptr;
+            break;
         }
-        case GL_COMPRESSED_RGBA_ASTC_4x4_KHR:
+
+        case angle::Format::ID::ASTC_5x4_UNORM_BLOCK:
         {
-            static constexpr Format info(GL_COMPRESSED_RGBA_ASTC_4x4_KHR,
-                                         angle::Format::ID::ASTC_4x4_UNORM_BLOCK,
-                                         VK_FORMAT_ASTC_4x4_UNORM_BLOCK,
-                                         nullptr);
-            return info;
+            internalFormat          = GL_COMPRESSED_RGBA_ASTC_5x4_KHR;
+            textureFormatID         = angle::Format::ID::ASTC_5x4_UNORM_BLOCK;
+            vkTextureFormat         = VK_FORMAT_ASTC_5x4_UNORM_BLOCK;
+            bufferFormatID          = angle::Format::ID::ASTC_5x4_UNORM_BLOCK;
+            vkBufferFormat          = VK_FORMAT_ASTC_5x4_UNORM_BLOCK;
+            dataInitializerFunction = nullptr;
+            break;
         }
-        case GL_COMPRESSED_RGBA_ASTC_5x4_KHR:
+
+        case angle::Format::ID::ASTC_5x5_SRGB_BLOCK:
         {
-            static constexpr Format info(GL_COMPRESSED_RGBA_ASTC_5x4_KHR,
-                                         angle::Format::ID::ASTC_5x4_UNORM_BLOCK,
-                                         VK_FORMAT_ASTC_5x4_UNORM_BLOCK,
-                                         nullptr);
-            return info;
+            internalFormat          = GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x5_KHR;
+            textureFormatID         = angle::Format::ID::ASTC_5x5_SRGB_BLOCK;
+            vkTextureFormat         = VK_FORMAT_ASTC_5x5_SRGB_BLOCK;
+            bufferFormatID          = angle::Format::ID::ASTC_5x5_SRGB_BLOCK;
+            vkBufferFormat          = VK_FORMAT_ASTC_5x5_SRGB_BLOCK;
+            dataInitializerFunction = nullptr;
+            break;
         }
-        case GL_COMPRESSED_RGBA_ASTC_5x5_KHR:
+
+        case angle::Format::ID::ASTC_5x5_UNORM_BLOCK:
         {
-            static constexpr Format info(GL_COMPRESSED_RGBA_ASTC_5x5_KHR,
-                                         angle::Format::ID::ASTC_5x5_UNORM_BLOCK,
-                                         VK_FORMAT_ASTC_5x5_UNORM_BLOCK,
-                                         nullptr);
-            return info;
+            internalFormat          = GL_COMPRESSED_RGBA_ASTC_5x5_KHR;
+            textureFormatID         = angle::Format::ID::ASTC_5x5_UNORM_BLOCK;
+            vkTextureFormat         = VK_FORMAT_ASTC_5x5_UNORM_BLOCK;
+            bufferFormatID          = angle::Format::ID::ASTC_5x5_UNORM_BLOCK;
+            vkBufferFormat          = VK_FORMAT_ASTC_5x5_UNORM_BLOCK;
+            dataInitializerFunction = nullptr;
+            break;
         }
-        case GL_COMPRESSED_RGBA_ASTC_6x5_KHR:
+
+        case angle::Format::ID::ASTC_6x5_SRGB_BLOCK:
         {
-            static constexpr Format info(GL_COMPRESSED_RGBA_ASTC_6x5_KHR,
-                                         angle::Format::ID::ASTC_6x5_UNORM_BLOCK,
-                                         VK_FORMAT_ASTC_6x5_UNORM_BLOCK,
-                                         nullptr);
-            return info;
+            internalFormat          = GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x5_KHR;
+            textureFormatID         = angle::Format::ID::ASTC_6x5_SRGB_BLOCK;
+            vkTextureFormat         = VK_FORMAT_ASTC_6x5_SRGB_BLOCK;
+            bufferFormatID          = angle::Format::ID::ASTC_6x5_SRGB_BLOCK;
+            vkBufferFormat          = VK_FORMAT_ASTC_6x5_SRGB_BLOCK;
+            dataInitializerFunction = nullptr;
+            break;
         }
-        case GL_COMPRESSED_RGBA_ASTC_6x6_KHR:
+
+        case angle::Format::ID::ASTC_6x5_UNORM_BLOCK:
         {
-            static constexpr Format info(GL_COMPRESSED_RGBA_ASTC_6x6_KHR,
-                                         angle::Format::ID::ASTC_6x6_UNORM_BLOCK,
-                                         VK_FORMAT_ASTC_6x6_UNORM_BLOCK,
-                                         nullptr);
-            return info;
+            internalFormat          = GL_COMPRESSED_RGBA_ASTC_6x5_KHR;
+            textureFormatID         = angle::Format::ID::ASTC_6x5_UNORM_BLOCK;
+            vkTextureFormat         = VK_FORMAT_ASTC_6x5_UNORM_BLOCK;
+            bufferFormatID          = angle::Format::ID::ASTC_6x5_UNORM_BLOCK;
+            vkBufferFormat          = VK_FORMAT_ASTC_6x5_UNORM_BLOCK;
+            dataInitializerFunction = nullptr;
+            break;
         }
-        case GL_COMPRESSED_RGBA_ASTC_8x5_KHR:
+
+        case angle::Format::ID::ASTC_6x6_SRGB_BLOCK:
         {
-            static constexpr Format info(GL_COMPRESSED_RGBA_ASTC_8x5_KHR,
-                                         angle::Format::ID::ASTC_8x5_UNORM_BLOCK,
-                                         VK_FORMAT_ASTC_8x5_UNORM_BLOCK,
-                                         nullptr);
-            return info;
+            internalFormat          = GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x6_KHR;
+            textureFormatID         = angle::Format::ID::ASTC_6x6_SRGB_BLOCK;
+            vkTextureFormat         = VK_FORMAT_ASTC_6x6_SRGB_BLOCK;
+            bufferFormatID          = angle::Format::ID::ASTC_6x6_SRGB_BLOCK;
+            vkBufferFormat          = VK_FORMAT_ASTC_6x6_SRGB_BLOCK;
+            dataInitializerFunction = nullptr;
+            break;
         }
-        case GL_COMPRESSED_RGBA_ASTC_8x6_KHR:
+
+        case angle::Format::ID::ASTC_6x6_UNORM_BLOCK:
         {
-            static constexpr Format info(GL_COMPRESSED_RGBA_ASTC_8x6_KHR,
-                                         angle::Format::ID::ASTC_8x6_UNORM_BLOCK,
-                                         VK_FORMAT_ASTC_8x6_UNORM_BLOCK,
-                                         nullptr);
-            return info;
+            internalFormat          = GL_COMPRESSED_RGBA_ASTC_6x6_KHR;
+            textureFormatID         = angle::Format::ID::ASTC_6x6_UNORM_BLOCK;
+            vkTextureFormat         = VK_FORMAT_ASTC_6x6_UNORM_BLOCK;
+            bufferFormatID          = angle::Format::ID::ASTC_6x6_UNORM_BLOCK;
+            vkBufferFormat          = VK_FORMAT_ASTC_6x6_UNORM_BLOCK;
+            dataInitializerFunction = nullptr;
+            break;
         }
-        case GL_COMPRESSED_RGBA_ASTC_8x8_KHR:
+
+        case angle::Format::ID::ASTC_8x5_SRGB_BLOCK:
         {
-            static constexpr Format info(GL_COMPRESSED_RGBA_ASTC_8x8_KHR,
-                                         angle::Format::ID::ASTC_8x8_UNORM_BLOCK,
-                                         VK_FORMAT_ASTC_8x8_UNORM_BLOCK,
-                                         nullptr);
-            return info;
+            internalFormat          = GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x5_KHR;
+            textureFormatID         = angle::Format::ID::ASTC_8x5_SRGB_BLOCK;
+            vkTextureFormat         = VK_FORMAT_ASTC_8x5_SRGB_BLOCK;
+            bufferFormatID          = angle::Format::ID::ASTC_8x5_SRGB_BLOCK;
+            vkBufferFormat          = VK_FORMAT_ASTC_8x5_SRGB_BLOCK;
+            dataInitializerFunction = nullptr;
+            break;
         }
-        case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
+
+        case angle::Format::ID::ASTC_8x5_UNORM_BLOCK:
         {
-            static constexpr Format info(GL_COMPRESSED_RGBA_S3TC_DXT1_EXT,
-                                         angle::Format::ID::BC1_RGBA_UNORM_BLOCK,
-                                         VK_FORMAT_BC1_RGBA_UNORM_BLOCK,
-                                         nullptr);
-            return info;
+            internalFormat          = GL_COMPRESSED_RGBA_ASTC_8x5_KHR;
+            textureFormatID         = angle::Format::ID::ASTC_8x5_UNORM_BLOCK;
+            vkTextureFormat         = VK_FORMAT_ASTC_8x5_UNORM_BLOCK;
+            bufferFormatID          = angle::Format::ID::ASTC_8x5_UNORM_BLOCK;
+            vkBufferFormat          = VK_FORMAT_ASTC_8x5_UNORM_BLOCK;
+            dataInitializerFunction = nullptr;
+            break;
         }
-        case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
+
+        case angle::Format::ID::ASTC_8x6_SRGB_BLOCK:
         {
-            static constexpr Format info(GL_COMPRESSED_RGB_S3TC_DXT1_EXT,
-                                         angle::Format::ID::BC1_RGB_UNORM_BLOCK,
-                                         VK_FORMAT_BC1_RGB_UNORM_BLOCK,
-                                         nullptr);
-            return info;
+            internalFormat          = GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x6_KHR;
+            textureFormatID         = angle::Format::ID::ASTC_8x6_SRGB_BLOCK;
+            vkTextureFormat         = VK_FORMAT_ASTC_8x6_SRGB_BLOCK;
+            bufferFormatID          = angle::Format::ID::ASTC_8x6_SRGB_BLOCK;
+            vkBufferFormat          = VK_FORMAT_ASTC_8x6_SRGB_BLOCK;
+            dataInitializerFunction = nullptr;
+            break;
         }
-        case GL_COMPRESSED_SIGNED_R11_EAC:
+
+        case angle::Format::ID::ASTC_8x6_UNORM_BLOCK:
         {
-            static constexpr Format info(GL_COMPRESSED_SIGNED_R11_EAC,
-                                         angle::Format::ID::EAC_R11_SNORM_BLOCK,
-                                         VK_FORMAT_EAC_R11_SNORM_BLOCK,
-                                         nullptr);
-            return info;
+            internalFormat          = GL_COMPRESSED_RGBA_ASTC_8x6_KHR;
+            textureFormatID         = angle::Format::ID::ASTC_8x6_UNORM_BLOCK;
+            vkTextureFormat         = VK_FORMAT_ASTC_8x6_UNORM_BLOCK;
+            bufferFormatID          = angle::Format::ID::ASTC_8x6_UNORM_BLOCK;
+            vkBufferFormat          = VK_FORMAT_ASTC_8x6_UNORM_BLOCK;
+            dataInitializerFunction = nullptr;
+            break;
         }
-        case GL_COMPRESSED_SIGNED_RG11_EAC:
+
+        case angle::Format::ID::ASTC_8x8_SRGB_BLOCK:
         {
-            static constexpr Format info(GL_COMPRESSED_SIGNED_RG11_EAC,
-                                         angle::Format::ID::EAC_R11G11_SNORM_BLOCK,
-                                         VK_FORMAT_EAC_R11G11_SNORM_BLOCK,
-                                         nullptr);
-            return info;
+            internalFormat          = GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x8_KHR;
+            textureFormatID         = angle::Format::ID::ASTC_8x8_SRGB_BLOCK;
+            vkTextureFormat         = VK_FORMAT_ASTC_8x8_SRGB_BLOCK;
+            bufferFormatID          = angle::Format::ID::ASTC_8x8_SRGB_BLOCK;
+            vkBufferFormat          = VK_FORMAT_ASTC_8x8_SRGB_BLOCK;
+            dataInitializerFunction = nullptr;
+            break;
         }
-        case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x10_KHR:
+
+        case angle::Format::ID::ASTC_8x8_UNORM_BLOCK:
         {
-            static constexpr Format info(GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x10_KHR,
-                                         angle::Format::ID::ASTC_10x10_SRGB_BLOCK,
-                                         VK_FORMAT_ASTC_10x10_SRGB_BLOCK,
-                                         nullptr);
-            return info;
+            internalFormat          = GL_COMPRESSED_RGBA_ASTC_8x8_KHR;
+            textureFormatID         = angle::Format::ID::ASTC_8x8_UNORM_BLOCK;
+            vkTextureFormat         = VK_FORMAT_ASTC_8x8_UNORM_BLOCK;
+            bufferFormatID          = angle::Format::ID::ASTC_8x8_UNORM_BLOCK;
+            vkBufferFormat          = VK_FORMAT_ASTC_8x8_UNORM_BLOCK;
+            dataInitializerFunction = nullptr;
+            break;
         }
-        case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x5_KHR:
+
+        case angle::Format::ID::B4G4R4A4_UNORM:
         {
-            static constexpr Format info(GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x5_KHR,
-                                         angle::Format::ID::ASTC_10x5_SRGB_BLOCK,
-                                         VK_FORMAT_ASTC_10x5_SRGB_BLOCK,
-                                         nullptr);
-            return info;
+            internalFormat          = GL_BGRA4_ANGLEX;
+            textureFormatID         = angle::Format::ID::B4G4R4A4_UNORM;
+            vkTextureFormat         = VK_FORMAT_B4G4R4A4_UNORM_PACK16;
+            bufferFormatID          = angle::Format::ID::B4G4R4A4_UNORM;
+            vkBufferFormat          = VK_FORMAT_B4G4R4A4_UNORM_PACK16;
+            dataInitializerFunction = nullptr;
+            break;
         }
-        case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x6_KHR:
+
+        case angle::Format::ID::B5G5R5A1_UNORM:
         {
-            static constexpr Format info(GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x6_KHR,
-                                         angle::Format::ID::ASTC_10x6_SRGB_BLOCK,
-                                         VK_FORMAT_ASTC_10x6_SRGB_BLOCK,
-                                         nullptr);
-            return info;
+            internalFormat          = GL_BGR5_A1_ANGLEX;
+            textureFormatID         = angle::Format::ID::B5G5R5A1_UNORM;
+            vkTextureFormat         = VK_FORMAT_B5G5R5A1_UNORM_PACK16;
+            bufferFormatID          = angle::Format::ID::B5G5R5A1_UNORM;
+            vkBufferFormat          = VK_FORMAT_B5G5R5A1_UNORM_PACK16;
+            dataInitializerFunction = nullptr;
+            break;
         }
-        case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x8_KHR:
+
+        case angle::Format::ID::B5G6R5_UNORM:
         {
-            static constexpr Format info(GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x8_KHR,
-                                         angle::Format::ID::ASTC_10x8_SRGB_BLOCK,
-                                         VK_FORMAT_ASTC_10x8_SRGB_BLOCK,
-                                         nullptr);
-            return info;
+            internalFormat          = GL_BGR565_ANGLEX;
+            textureFormatID         = angle::Format::ID::B5G6R5_UNORM;
+            vkTextureFormat         = VK_FORMAT_B5G6R5_UNORM_PACK16;
+            bufferFormatID          = angle::Format::ID::B5G6R5_UNORM;
+            vkBufferFormat          = VK_FORMAT_B5G6R5_UNORM_PACK16;
+            dataInitializerFunction = nullptr;
+            break;
         }
-        case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_12x10_KHR:
+
+        case angle::Format::ID::B8G8R8A8_UNORM:
         {
-            static constexpr Format info(GL_COMPRESSED_SRGB8_ALPHA8_ASTC_12x10_KHR,
-                                         angle::Format::ID::ASTC_12x10_SRGB_BLOCK,
-                                         VK_FORMAT_ASTC_12x10_SRGB_BLOCK,
-                                         nullptr);
-            return info;
+            internalFormat          = GL_BGRA8_EXT;
+            textureFormatID         = angle::Format::ID::B8G8R8A8_UNORM;
+            vkTextureFormat         = VK_FORMAT_B8G8R8A8_UNORM;
+            bufferFormatID          = angle::Format::ID::B8G8R8A8_UNORM;
+            vkBufferFormat          = VK_FORMAT_B8G8R8A8_UNORM;
+            dataInitializerFunction = nullptr;
+            break;
         }
-        case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_4x4_KHR:
+
+        case angle::Format::ID::B8G8R8A8_UNORM_SRGB:
+            // This format is not implemented in Vulkan.
+            break;
+
+        case angle::Format::ID::B8G8R8X8_UNORM:
+            // This format is not implemented in Vulkan.
+            break;
+
+        case angle::Format::ID::BC1_RGBA_UNORM_BLOCK:
         {
-            static constexpr Format info(GL_COMPRESSED_SRGB8_ALPHA8_ASTC_4x4_KHR,
-                                         angle::Format::ID::ASTC_4x4_SRGB_BLOCK,
-                                         VK_FORMAT_ASTC_4x4_SRGB_BLOCK,
-                                         nullptr);
-            return info;
+            internalFormat          = GL_COMPRESSED_RGBA_S3TC_DXT1_EXT;
+            textureFormatID         = angle::Format::ID::BC1_RGBA_UNORM_BLOCK;
+            vkTextureFormat         = VK_FORMAT_BC1_RGBA_UNORM_BLOCK;
+            bufferFormatID          = angle::Format::ID::BC1_RGBA_UNORM_BLOCK;
+            vkBufferFormat          = VK_FORMAT_BC1_RGBA_UNORM_BLOCK;
+            dataInitializerFunction = nullptr;
+            break;
         }
-        case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x4_KHR:
-        {
-            static constexpr Format info(GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x4_KHR,
-                                         angle::Format::ID::ASTC_5x4_SRGB_BLOCK,
-                                         VK_FORMAT_ASTC_5x4_SRGB_BLOCK,
-                                         nullptr);
-            return info;
-        }
-        case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x5_KHR:
+
+        case angle::Format::ID::BC1_RGBA_UNORM_SRGB_BLOCK:
+            // This format is not implemented in Vulkan.
+            break;
+
+        case angle::Format::ID::BC1_RGB_UNORM_BLOCK:
         {
-            static constexpr Format info(GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x5_KHR,
-                                         angle::Format::ID::ASTC_5x5_SRGB_BLOCK,
-                                         VK_FORMAT_ASTC_5x5_SRGB_BLOCK,
-                                         nullptr);
-            return info;
-        }
-        case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x5_KHR:
-        {
-            static constexpr Format info(GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x5_KHR,
-                                         angle::Format::ID::ASTC_6x5_SRGB_BLOCK,
-                                         VK_FORMAT_ASTC_6x5_SRGB_BLOCK,
-                                         nullptr);
-            return info;
+            internalFormat          = GL_COMPRESSED_RGB_S3TC_DXT1_EXT;
+            textureFormatID         = angle::Format::ID::BC1_RGB_UNORM_BLOCK;
+            vkTextureFormat         = VK_FORMAT_BC1_RGB_UNORM_BLOCK;
+            bufferFormatID          = angle::Format::ID::BC1_RGB_UNORM_BLOCK;
+            vkBufferFormat          = VK_FORMAT_BC1_RGB_UNORM_BLOCK;
+            dataInitializerFunction = nullptr;
+            break;
         }
-        case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x6_KHR:
+
+        case angle::Format::ID::BC1_RGB_UNORM_SRGB_BLOCK:
+            // This format is not implemented in Vulkan.
+            break;
+
+        case angle::Format::ID::BC2_RGBA_UNORM_BLOCK:
+            // This format is not implemented in Vulkan.
+            break;
+
+        case angle::Format::ID::BC2_RGBA_UNORM_SRGB_BLOCK:
+            // This format is not implemented in Vulkan.
+            break;
+
+        case angle::Format::ID::BC3_RGBA_UNORM_BLOCK:
+            // This format is not implemented in Vulkan.
+            break;
+
+        case angle::Format::ID::BC3_RGBA_UNORM_SRGB_BLOCK:
+            // This format is not implemented in Vulkan.
+            break;
+
+        case angle::Format::ID::D16_UNORM:
         {
-            static constexpr Format info(GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x6_KHR,
-                                         angle::Format::ID::ASTC_6x6_SRGB_BLOCK,
-                                         VK_FORMAT_ASTC_6x6_SRGB_BLOCK,
-                                         nullptr);
-            return info;
-        }
-        case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x5_KHR:
-        {
-            static constexpr Format info(GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x5_KHR,
-                                         angle::Format::ID::ASTC_8x5_SRGB_BLOCK,
-                                         VK_FORMAT_ASTC_8x5_SRGB_BLOCK,
-                                         nullptr);
-            return info;
+            internalFormat          = GL_DEPTH_COMPONENT16;
+            textureFormatID         = angle::Format::ID::D16_UNORM;
+            vkTextureFormat         = VK_FORMAT_D16_UNORM;
+            bufferFormatID          = angle::Format::ID::D16_UNORM;
+            vkBufferFormat          = VK_FORMAT_D16_UNORM;
+            dataInitializerFunction = nullptr;
+            break;
         }
-        case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x6_KHR:
-        {
-            static constexpr Format info(GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x6_KHR,
-                                         angle::Format::ID::ASTC_8x6_SRGB_BLOCK,
-                                         VK_FORMAT_ASTC_8x6_SRGB_BLOCK,
-                                         nullptr);
-            return info;
-        }
-        case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x8_KHR:
+
+        case angle::Format::ID::D24_UNORM:
+            // This format is not implemented in Vulkan.
+            break;
+
+        case angle::Format::ID::D24_UNORM_S8_UINT:
         {
-            static constexpr Format info(GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x8_KHR,
-                                         angle::Format::ID::ASTC_8x8_SRGB_BLOCK,
-                                         VK_FORMAT_ASTC_8x8_SRGB_BLOCK,
-                                         nullptr);
-            return info;
+            internalFormat          = GL_DEPTH24_STENCIL8;
+            textureFormatID         = angle::Format::ID::D24_UNORM_S8_UINT;
+            vkTextureFormat         = VK_FORMAT_D24_UNORM_S8_UINT;
+            bufferFormatID          = angle::Format::ID::D24_UNORM_S8_UINT;
+            vkBufferFormat          = VK_FORMAT_D24_UNORM_S8_UINT;
+            dataInitializerFunction = nullptr;
+            break;
         }
-        case GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC:
+
+        case angle::Format::ID::D32_FLOAT:
         {
-            static constexpr Format info(GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC,
-                                         angle::Format::ID::ETC2_R8G8B8A8_SRGB_BLOCK,
-                                         VK_FORMAT_ETC2_R8G8B8A8_SRGB_BLOCK,
-                                         nullptr);
-            return info;
+            internalFormat          = GL_DEPTH_COMPONENT32F;
+            textureFormatID         = angle::Format::ID::D32_FLOAT;
+            vkTextureFormat         = VK_FORMAT_D32_SFLOAT;
+            bufferFormatID          = angle::Format::ID::D32_FLOAT;
+            vkBufferFormat          = VK_FORMAT_D32_SFLOAT;
+            dataInitializerFunction = nullptr;
+            break;
         }
-        case GL_COMPRESSED_SRGB8_ETC2:
+
+        case angle::Format::ID::D32_FLOAT_S8X24_UINT:
+            // This format is not implemented in Vulkan.
+            break;
+
+        case angle::Format::ID::D32_UNORM:
+            // This format is not implemented in Vulkan.
+            break;
+
+        case angle::Format::ID::EAC_R11G11_SNORM_BLOCK:
         {
-            static constexpr Format info(GL_COMPRESSED_SRGB8_ETC2,
-                                         angle::Format::ID::ETC2_R8G8B8_SRGB_BLOCK,
-                                         VK_FORMAT_ETC2_R8G8B8_SRGB_BLOCK,
-                                         nullptr);
-            return info;
+            internalFormat          = GL_COMPRESSED_SIGNED_RG11_EAC;
+            textureFormatID         = angle::Format::ID::EAC_R11G11_SNORM_BLOCK;
+            vkTextureFormat         = VK_FORMAT_EAC_R11G11_SNORM_BLOCK;
+            bufferFormatID          = angle::Format::ID::EAC_R11G11_SNORM_BLOCK;
+            vkBufferFormat          = VK_FORMAT_EAC_R11G11_SNORM_BLOCK;
+            dataInitializerFunction = nullptr;
+            break;
         }
-        case GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2:
+
+        case angle::Format::ID::EAC_R11G11_UNORM_BLOCK:
         {
-            static constexpr Format info(GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2,
-                                         angle::Format::ID::ETC2_R8G8B8A1_SRGB_BLOCK,
-                                         VK_FORMAT_ETC2_R8G8B8A1_SRGB_BLOCK,
-                                         nullptr);
-            return info;
+            internalFormat          = GL_COMPRESSED_RG11_EAC;
+            textureFormatID         = angle::Format::ID::EAC_R11G11_UNORM_BLOCK;
+            vkTextureFormat         = VK_FORMAT_EAC_R11G11_UNORM_BLOCK;
+            bufferFormatID          = angle::Format::ID::EAC_R11G11_UNORM_BLOCK;
+            vkBufferFormat          = VK_FORMAT_EAC_R11G11_UNORM_BLOCK;
+            dataInitializerFunction = nullptr;
+            break;
         }
-        case GL_DEPTH24_STENCIL8:
+
+        case angle::Format::ID::EAC_R11_SNORM_BLOCK:
         {
-            static constexpr Format info(GL_DEPTH24_STENCIL8,
-                                         angle::Format::ID::D24_UNORM_S8_UINT,
-                                         VK_FORMAT_D24_UNORM_S8_UINT,
-                                         nullptr);
-            return info;
+            internalFormat          = GL_COMPRESSED_SIGNED_R11_EAC;
+            textureFormatID         = angle::Format::ID::EAC_R11_SNORM_BLOCK;
+            vkTextureFormat         = VK_FORMAT_EAC_R11_SNORM_BLOCK;
+            bufferFormatID          = angle::Format::ID::EAC_R11_SNORM_BLOCK;
+            vkBufferFormat          = VK_FORMAT_EAC_R11_SNORM_BLOCK;
+            dataInitializerFunction = nullptr;
+            break;
         }
-        case GL_DEPTH_COMPONENT16:
+
+        case angle::Format::ID::EAC_R11_UNORM_BLOCK:
         {
-            static constexpr Format info(GL_DEPTH_COMPONENT16,
-                                         angle::Format::ID::D16_UNORM,
-                                         VK_FORMAT_D16_UNORM,
-                                         nullptr);
-            return info;
+            internalFormat          = GL_COMPRESSED_R11_EAC;
+            textureFormatID         = angle::Format::ID::EAC_R11_UNORM_BLOCK;
+            vkTextureFormat         = VK_FORMAT_EAC_R11_UNORM_BLOCK;
+            bufferFormatID          = angle::Format::ID::EAC_R11_UNORM_BLOCK;
+            vkBufferFormat          = VK_FORMAT_EAC_R11_UNORM_BLOCK;
+            dataInitializerFunction = nullptr;
+            break;
         }
-        case GL_DEPTH_COMPONENT32F:
+
+        case angle::Format::ID::ETC1_LOSSY_DECODE_R8G8B8_UNORM_BLOCK:
+            // This format is not implemented in Vulkan.
+            break;
+
+        case angle::Format::ID::ETC1_R8G8B8_UNORM_BLOCK:
+            // This format is not implemented in Vulkan.
+            break;
+
+        case angle::Format::ID::ETC2_R8G8B8A1_SRGB_BLOCK:
         {
-            static constexpr Format info(GL_DEPTH_COMPONENT32F,
-                                         angle::Format::ID::D32_FLOAT,
-                                         VK_FORMAT_D32_SFLOAT,
-                                         nullptr);
-            return info;
+            internalFormat          = GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2;
+            textureFormatID         = angle::Format::ID::ETC2_R8G8B8A1_SRGB_BLOCK;
+            vkTextureFormat         = VK_FORMAT_ETC2_R8G8B8A1_SRGB_BLOCK;
+            bufferFormatID          = angle::Format::ID::ETC2_R8G8B8A1_SRGB_BLOCK;
+            vkBufferFormat          = VK_FORMAT_ETC2_R8G8B8A1_SRGB_BLOCK;
+            dataInitializerFunction = nullptr;
+            break;
         }
-        case GL_ETC1_RGB8_LOSSY_DECODE_ANGLE:
+
+        case angle::Format::ID::ETC2_R8G8B8A1_UNORM_BLOCK:
         {
-            static constexpr Format info(GL_ETC1_RGB8_LOSSY_DECODE_ANGLE,
-                                         angle::Format::ID::NONE,
-                                         VK_FORMAT_UNDEFINED,
-                                         nullptr);
-            return info;
+            internalFormat          = GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2;
+            textureFormatID         = angle::Format::ID::ETC2_R8G8B8A1_UNORM_BLOCK;
+            vkTextureFormat         = VK_FORMAT_ETC2_R8G8B8A1_UNORM_BLOCK;
+            bufferFormatID          = angle::Format::ID::ETC2_R8G8B8A1_UNORM_BLOCK;
+            vkBufferFormat          = VK_FORMAT_ETC2_R8G8B8A1_UNORM_BLOCK;
+            dataInitializerFunction = Initialize4ComponentData<GLubyte, 0x00, 0x00, 0x00, 0xFF>;
+            break;
         }
-        case GL_ETC1_RGB8_OES:
+
+        case angle::Format::ID::ETC2_R8G8B8A8_SRGB_BLOCK:
         {
-            static constexpr Format info(GL_ETC1_RGB8_OES,
-                                         angle::Format::ID::NONE,
-                                         VK_FORMAT_UNDEFINED,
-                                         nullptr);
-            return info;
+            internalFormat          = GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC;
+            textureFormatID         = angle::Format::ID::ETC2_R8G8B8A8_SRGB_BLOCK;
+            vkTextureFormat         = VK_FORMAT_ETC2_R8G8B8A8_SRGB_BLOCK;
+            bufferFormatID          = angle::Format::ID::ETC2_R8G8B8A8_SRGB_BLOCK;
+            vkBufferFormat          = VK_FORMAT_ETC2_R8G8B8A8_SRGB_BLOCK;
+            dataInitializerFunction = nullptr;
+            break;
         }
-        case GL_NONE:
+
+        case angle::Format::ID::ETC2_R8G8B8A8_UNORM_BLOCK:
         {
-            static constexpr Format info(GL_NONE,
-                                         angle::Format::ID::NONE,
-                                         VK_FORMAT_UNDEFINED,
-                                         nullptr);
-            return info;
+            internalFormat          = GL_COMPRESSED_RGBA8_ETC2_EAC;
+            textureFormatID         = angle::Format::ID::ETC2_R8G8B8A8_UNORM_BLOCK;
+            vkTextureFormat         = VK_FORMAT_ETC2_R8G8B8A8_UNORM_BLOCK;
+            bufferFormatID          = angle::Format::ID::ETC2_R8G8B8A8_UNORM_BLOCK;
+            vkBufferFormat          = VK_FORMAT_ETC2_R8G8B8A8_UNORM_BLOCK;
+            dataInitializerFunction = nullptr;
+            break;
         }
-        case GL_R16F:
+
+        case angle::Format::ID::ETC2_R8G8B8_SRGB_BLOCK:
         {
-            static constexpr Format info(GL_R16F,
-                                         angle::Format::ID::R16_FLOAT,
-                                         VK_FORMAT_R16_SFLOAT,
-                                         nullptr);
-            return info;
+            internalFormat          = GL_COMPRESSED_SRGB8_ETC2;
+            textureFormatID         = angle::Format::ID::ETC2_R8G8B8_SRGB_BLOCK;
+            vkTextureFormat         = VK_FORMAT_ETC2_R8G8B8_SRGB_BLOCK;
+            bufferFormatID          = angle::Format::ID::ETC2_R8G8B8_SRGB_BLOCK;
+            vkBufferFormat          = VK_FORMAT_ETC2_R8G8B8_SRGB_BLOCK;
+            dataInitializerFunction = nullptr;
+            break;
         }
-        case GL_R16I:
+
+        case angle::Format::ID::ETC2_R8G8B8_UNORM_BLOCK:
         {
-            static constexpr Format info(GL_R16I,
-                                         angle::Format::ID::R16_SINT,
-                                         VK_FORMAT_R16_SINT,
-                                         nullptr);
-            return info;
+            internalFormat          = GL_COMPRESSED_RGB8_ETC2;
+            textureFormatID         = angle::Format::ID::ETC2_R8G8B8_UNORM_BLOCK;
+            vkTextureFormat         = VK_FORMAT_ETC2_R8G8B8_UNORM_BLOCK;
+            bufferFormatID          = angle::Format::ID::ETC2_R8G8B8_UNORM_BLOCK;
+            vkBufferFormat          = VK_FORMAT_ETC2_R8G8B8_UNORM_BLOCK;
+            dataInitializerFunction = nullptr;
+            break;
         }
-        case GL_R16UI:
-        {
-            static constexpr Format info(GL_R16UI,
-                                         angle::Format::ID::R16_UINT,
-                                         VK_FORMAT_R16_UINT,
-                                         nullptr);
-            return info;
-        }
-        case GL_R16_EXT:
+
+        case angle::Format::ID::L16A16_FLOAT:
+            // This format is not implemented in Vulkan.
+            break;
+
+        case angle::Format::ID::L16_FLOAT:
+            // This format is not implemented in Vulkan.
+            break;
+
+        case angle::Format::ID::L32A32_FLOAT:
+            // This format is not implemented in Vulkan.
+            break;
+
+        case angle::Format::ID::L32_FLOAT:
+            // This format is not implemented in Vulkan.
+            break;
+
+        case angle::Format::ID::L8A8_UNORM:
+            // This format is not implemented in Vulkan.
+            break;
+
+        case angle::Format::ID::L8_UNORM:
+            // This format is not implemented in Vulkan.
+            break;
+
+        case angle::Format::ID::NONE:
+            // This format is not implemented in Vulkan.
+            break;
+
+        case angle::Format::ID::R10G10B10A2_UINT:
+            // This format is not implemented in Vulkan.
+            break;
+
+        case angle::Format::ID::R10G10B10A2_UNORM:
+            // This format is not implemented in Vulkan.
+            break;
+
+        case angle::Format::ID::R11G11B10_FLOAT:
+            // This format is not implemented in Vulkan.
+            break;
+
+        case angle::Format::ID::R16G16B16A16_FLOAT:
         {
-            static constexpr Format info(GL_R16_EXT,
-                                         angle::Format::ID::R16_UNORM,
-                                         VK_FORMAT_R16_UNORM,
-                                         nullptr);
-            return info;
-        }
-        case GL_R16_SNORM_EXT:
-        {
-            static constexpr Format info(GL_R16_SNORM_EXT,
-                                         angle::Format::ID::R16_SNORM,
-                                         VK_FORMAT_R16_SNORM,
-                                         nullptr);
-            return info;
+            internalFormat          = GL_RGBA16F;
+            textureFormatID         = angle::Format::ID::R16G16B16A16_FLOAT;
+            vkTextureFormat         = VK_FORMAT_R16G16B16A16_SFLOAT;
+            bufferFormatID          = angle::Format::ID::R16G16B16A16_FLOAT;
+            vkBufferFormat          = VK_FORMAT_R16G16B16A16_SFLOAT;
+            dataInitializerFunction = nullptr;
+            break;
         }
-        case GL_R32F:
-        {
-            static constexpr Format info(GL_R32F,
-                                         angle::Format::ID::R32_FLOAT,
-                                         VK_FORMAT_R32_SFLOAT,
-                                         nullptr);
-            return info;
-        }
-        case GL_R32I:
+
+        case angle::Format::ID::R16G16B16A16_SINT:
         {
-            static constexpr Format info(GL_R32I,
-                                         angle::Format::ID::R32_SINT,
-                                         VK_FORMAT_R32_SINT,
-                                         nullptr);
-            return info;
+            internalFormat          = GL_RGBA16I;
+            textureFormatID         = angle::Format::ID::R16G16B16A16_SINT;
+            vkTextureFormat         = VK_FORMAT_R16G16B16A16_SINT;
+            bufferFormatID          = angle::Format::ID::R16G16B16A16_SINT;
+            vkBufferFormat          = VK_FORMAT_R16G16B16A16_SINT;
+            dataInitializerFunction = nullptr;
+            break;
         }
-        case GL_R32UI:
-        {
-            static constexpr Format info(GL_R32UI,
-                                         angle::Format::ID::R32_UINT,
-                                         VK_FORMAT_R32_UINT,
-                                         nullptr);
-            return info;
-        }
-        case GL_R8:
+
+        case angle::Format::ID::R16G16B16A16_SNORM:
         {
-            static constexpr Format info(GL_R8,
-                                         angle::Format::ID::R8_UNORM,
-                                         VK_FORMAT_R8_UNORM,
-                                         nullptr);
-            return info;
+            internalFormat          = GL_RGBA16_SNORM_EXT;
+            textureFormatID         = angle::Format::ID::R16G16B16A16_SNORM;
+            vkTextureFormat         = VK_FORMAT_R16G16B16A16_SNORM;
+            bufferFormatID          = angle::Format::ID::R16G16B16A16_SNORM;
+            vkBufferFormat          = VK_FORMAT_R16G16B16A16_SNORM;
+            dataInitializerFunction = nullptr;
+            break;
         }
-        case GL_R8I:
+
+        case angle::Format::ID::R16G16B16A16_UINT:
         {
-            static constexpr Format info(GL_R8I,
-                                         angle::Format::ID::R8_SINT,
-                                         VK_FORMAT_R8_SINT,
-                                         nullptr);
-            return info;
+            internalFormat          = GL_RGBA16UI;
+            textureFormatID         = angle::Format::ID::R16G16B16A16_UINT;
+            vkTextureFormat         = VK_FORMAT_R16G16B16A16_UINT;
+            bufferFormatID          = angle::Format::ID::R16G16B16A16_UINT;
+            vkBufferFormat          = VK_FORMAT_R16G16B16A16_UINT;
+            dataInitializerFunction = nullptr;
+            break;
         }
-        case GL_R8UI:
+
+        case angle::Format::ID::R16G16B16A16_UNORM:
         {
-            static constexpr Format info(GL_R8UI,
-                                         angle::Format::ID::R8_UINT,
-                                         VK_FORMAT_R8_UINT,
-                                         nullptr);
-            return info;
+            internalFormat          = GL_RGBA16_EXT;
+            textureFormatID         = angle::Format::ID::R16G16B16A16_UNORM;
+            vkTextureFormat         = VK_FORMAT_R16G16B16A16_UNORM;
+            bufferFormatID          = angle::Format::ID::R16G16B16A16_UNORM;
+            vkBufferFormat          = VK_FORMAT_R16G16B16A16_UNORM;
+            dataInitializerFunction = nullptr;
+            break;
         }
-        case GL_R8_SNORM:
+
+        case angle::Format::ID::R16G16B16_FLOAT:
         {
-            static constexpr Format info(GL_R8_SNORM,
-                                         angle::Format::ID::R8_SNORM,
-                                         VK_FORMAT_R8_SNORM,
-                                         nullptr);
-            return info;
+            internalFormat          = GL_RGB16F;
+            textureFormatID         = angle::Format::ID::R16G16B16_FLOAT;
+            vkTextureFormat         = VK_FORMAT_R16G16B16_SFLOAT;
+            bufferFormatID          = angle::Format::ID::R16G16B16_FLOAT;
+            vkBufferFormat          = VK_FORMAT_R16G16B16_SFLOAT;
+            dataInitializerFunction = nullptr;
+            break;
         }
-        case GL_RG16F:
+
+        case angle::Format::ID::R16G16B16_SINT:
         {
-            static constexpr Format info(GL_RG16F,
-                                         angle::Format::ID::R16G16_FLOAT,
-                                         VK_FORMAT_R16G16_SFLOAT,
-                                         nullptr);
-            return info;
+            internalFormat          = GL_RGB16I;
+            textureFormatID         = angle::Format::ID::R16G16B16_SINT;
+            vkTextureFormat         = VK_FORMAT_R16G16B16_SINT;
+            bufferFormatID          = angle::Format::ID::R16G16B16_SINT;
+            vkBufferFormat          = VK_FORMAT_R16G16B16_SINT;
+            dataInitializerFunction = nullptr;
+            break;
         }
-        case GL_RG16I:
+
+        case angle::Format::ID::R16G16B16_SNORM:
         {
-            static constexpr Format info(GL_RG16I,
-                                         angle::Format::ID::R16G16_SINT,
-                                         VK_FORMAT_R16G16_SINT,
-                                         nullptr);
-            return info;
+            internalFormat          = GL_RGB16_SNORM_EXT;
+            textureFormatID         = angle::Format::ID::R16G16B16_SNORM;
+            vkTextureFormat         = VK_FORMAT_R16G16B16_SNORM;
+            bufferFormatID          = angle::Format::ID::R16G16B16_SNORM;
+            vkBufferFormat          = VK_FORMAT_R16G16B16_SNORM;
+            dataInitializerFunction = nullptr;
+            break;
         }
-        case GL_RG16UI:
+
+        case angle::Format::ID::R16G16B16_UINT:
         {
-            static constexpr Format info(GL_RG16UI,
-                                         angle::Format::ID::R16G16_UINT,
-                                         VK_FORMAT_R16G16_UINT,
-                                         nullptr);
-            return info;
+            internalFormat          = GL_RGB16UI;
+            textureFormatID         = angle::Format::ID::R16G16B16_UINT;
+            vkTextureFormat         = VK_FORMAT_R16G16B16_UINT;
+            bufferFormatID          = angle::Format::ID::R16G16B16_UINT;
+            vkBufferFormat          = VK_FORMAT_R16G16B16_UINT;
+            dataInitializerFunction = nullptr;
+            break;
+        }
+
+        case angle::Format::ID::R16G16B16_UNORM:
+        {
+            internalFormat          = GL_RGB16_EXT;
+            textureFormatID         = angle::Format::ID::R16G16B16_UNORM;
+            vkTextureFormat         = VK_FORMAT_R16G16B16_UNORM;
+            bufferFormatID          = angle::Format::ID::R16G16B16_UNORM;
+            vkBufferFormat          = VK_FORMAT_R16G16B16_UNORM;
+            dataInitializerFunction = nullptr;
+            break;
         }
-        case GL_RG16_EXT:
+
+        case angle::Format::ID::R16G16_FLOAT:
         {
-            static constexpr Format info(GL_RG16_EXT,
-                                         angle::Format::ID::R16G16_UNORM,
-                                         VK_FORMAT_R16G16_UNORM,
-                                         nullptr);
-            return info;
+            internalFormat          = GL_RG16F;
+            textureFormatID         = angle::Format::ID::R16G16_FLOAT;
+            vkTextureFormat         = VK_FORMAT_R16G16_SFLOAT;
+            bufferFormatID          = angle::Format::ID::R16G16_FLOAT;
+            vkBufferFormat          = VK_FORMAT_R16G16_SFLOAT;
+            dataInitializerFunction = nullptr;
+            break;
         }
-        case GL_RG16_SNORM_EXT:
+
+        case angle::Format::ID::R16G16_SINT:
         {
-            static constexpr Format info(GL_RG16_SNORM_EXT,
-                                         angle::Format::ID::R16G16_SNORM,
-                                         VK_FORMAT_R16G16_SNORM,
-                                         nullptr);
-            return info;
+            internalFormat          = GL_RG16I;
+            textureFormatID         = angle::Format::ID::R16G16_SINT;
+            vkTextureFormat         = VK_FORMAT_R16G16_SINT;
+            bufferFormatID          = angle::Format::ID::R16G16_SINT;
+            vkBufferFormat          = VK_FORMAT_R16G16_SINT;
+            dataInitializerFunction = nullptr;
+            break;
         }
-        case GL_RG32F:
+
+        case angle::Format::ID::R16G16_SNORM:
         {
-            static constexpr Format info(GL_RG32F,
-                                         angle::Format::ID::R32G32_FLOAT,
-                                         VK_FORMAT_R32G32_SFLOAT,
-                                         nullptr);
-            return info;
+            internalFormat          = GL_RG16_SNORM_EXT;
+            textureFormatID         = angle::Format::ID::R16G16_SNORM;
+            vkTextureFormat         = VK_FORMAT_R16G16_SNORM;
+            bufferFormatID          = angle::Format::ID::R16G16_SNORM;
+            vkBufferFormat          = VK_FORMAT_R16G16_SNORM;
+            dataInitializerFunction = nullptr;
+            break;
         }
-        case GL_RG32I:
+
+        case angle::Format::ID::R16G16_UINT:
         {
-            static constexpr Format info(GL_RG32I,
-                                         angle::Format::ID::R32G32_SINT,
-                                         VK_FORMAT_R32G32_SINT,
-                                         nullptr);
-            return info;
+            internalFormat          = GL_RG16UI;
+            textureFormatID         = angle::Format::ID::R16G16_UINT;
+            vkTextureFormat         = VK_FORMAT_R16G16_UINT;
+            bufferFormatID          = angle::Format::ID::R16G16_UINT;
+            vkBufferFormat          = VK_FORMAT_R16G16_UINT;
+            dataInitializerFunction = nullptr;
+            break;
         }
-        case GL_RG32UI:
+
+        case angle::Format::ID::R16G16_UNORM:
         {
-            static constexpr Format info(GL_RG32UI,
-                                         angle::Format::ID::R32G32_UINT,
-                                         VK_FORMAT_R32G32_UINT,
-                                         nullptr);
-            return info;
+            internalFormat          = GL_RG16_EXT;
+            textureFormatID         = angle::Format::ID::R16G16_UNORM;
+            vkTextureFormat         = VK_FORMAT_R16G16_UNORM;
+            bufferFormatID          = angle::Format::ID::R16G16_UNORM;
+            vkBufferFormat          = VK_FORMAT_R16G16_UNORM;
+            dataInitializerFunction = nullptr;
+            break;
         }
-        case GL_RG8:
+
+        case angle::Format::ID::R16_FLOAT:
         {
-            static constexpr Format info(GL_RG8,
-                                         angle::Format::ID::R8G8_UNORM,
-                                         VK_FORMAT_R8G8_UNORM,
-                                         nullptr);
-            return info;
+            internalFormat          = GL_R16F;
+            textureFormatID         = angle::Format::ID::R16_FLOAT;
+            vkTextureFormat         = VK_FORMAT_R16_SFLOAT;
+            bufferFormatID          = angle::Format::ID::R16_FLOAT;
+            vkBufferFormat          = VK_FORMAT_R16_SFLOAT;
+            dataInitializerFunction = nullptr;
+            break;
         }
-        case GL_RG8I:
+
+        case angle::Format::ID::R16_SINT:
         {
-            static constexpr Format info(GL_RG8I,
-                                         angle::Format::ID::R8G8_SINT,
-                                         VK_FORMAT_R8G8_SINT,
-                                         nullptr);
-            return info;
+            internalFormat          = GL_R16I;
+            textureFormatID         = angle::Format::ID::R16_SINT;
+            vkTextureFormat         = VK_FORMAT_R16_SINT;
+            bufferFormatID          = angle::Format::ID::R16_SINT;
+            vkBufferFormat          = VK_FORMAT_R16_SINT;
+            dataInitializerFunction = nullptr;
+            break;
         }
-        case GL_RG8UI:
+
+        case angle::Format::ID::R16_SNORM:
         {
-            static constexpr Format info(GL_RG8UI,
-                                         angle::Format::ID::R8G8_UINT,
-                                         VK_FORMAT_R8G8_UINT,
-                                         nullptr);
-            return info;
+            internalFormat          = GL_R16_SNORM_EXT;
+            textureFormatID         = angle::Format::ID::R16_SNORM;
+            vkTextureFormat         = VK_FORMAT_R16_SNORM;
+            bufferFormatID          = angle::Format::ID::R16_SNORM;
+            vkBufferFormat          = VK_FORMAT_R16_SNORM;
+            dataInitializerFunction = nullptr;
+            break;
         }
-        case GL_RG8_SNORM:
+
+        case angle::Format::ID::R16_UINT:
         {
-            static constexpr Format info(GL_RG8_SNORM,
-                                         angle::Format::ID::R8G8_SNORM,
-                                         VK_FORMAT_R8G8_SNORM,
-                                         nullptr);
-            return info;
+            internalFormat          = GL_R16UI;
+            textureFormatID         = angle::Format::ID::R16_UINT;
+            vkTextureFormat         = VK_FORMAT_R16_UINT;
+            bufferFormatID          = angle::Format::ID::R16_UINT;
+            vkBufferFormat          = VK_FORMAT_R16_UINT;
+            dataInitializerFunction = nullptr;
+            break;
         }
-        case GL_RGB:
+
+        case angle::Format::ID::R16_UNORM:
         {
-            static constexpr Format info(GL_RGB,
-                                         angle::Format::ID::R8G8B8_UNORM,
-                                         VK_FORMAT_R8G8B8_UNORM,
-                                         nullptr);
-            return info;
+            internalFormat          = GL_R16_EXT;
+            textureFormatID         = angle::Format::ID::R16_UNORM;
+            vkTextureFormat         = VK_FORMAT_R16_UNORM;
+            bufferFormatID          = angle::Format::ID::R16_UNORM;
+            vkBufferFormat          = VK_FORMAT_R16_UNORM;
+            dataInitializerFunction = nullptr;
+            break;
         }
-        case GL_RGB16F:
+
+        case angle::Format::ID::R32G32B32A32_FLOAT:
         {
-            static constexpr Format info(GL_RGB16F,
-                                         angle::Format::ID::R16G16B16_FLOAT,
-                                         VK_FORMAT_R16G16B16_SFLOAT,
-                                         nullptr);
-            return info;
+            internalFormat          = GL_RGBA32F;
+            textureFormatID         = angle::Format::ID::R32G32B32A32_FLOAT;
+            vkTextureFormat         = VK_FORMAT_R32G32B32A32_SFLOAT;
+            bufferFormatID          = angle::Format::ID::R32G32B32A32_FLOAT;
+            vkBufferFormat          = VK_FORMAT_R32G32B32A32_SFLOAT;
+            dataInitializerFunction = nullptr;
+            break;
         }
-        case GL_RGB16I:
+
+        case angle::Format::ID::R32G32B32A32_SINT:
         {
-            static constexpr Format info(GL_RGB16I,
-                                         angle::Format::ID::R16G16B16_SINT,
-                                         VK_FORMAT_R16G16B16_SINT,
-                                         nullptr);
-            return info;
+            internalFormat          = GL_RGBA32I;
+            textureFormatID         = angle::Format::ID::R32G32B32A32_SINT;
+            vkTextureFormat         = VK_FORMAT_R32G32B32A32_SINT;
+            bufferFormatID          = angle::Format::ID::R32G32B32A32_SINT;
+            vkBufferFormat          = VK_FORMAT_R32G32B32A32_SINT;
+            dataInitializerFunction = nullptr;
+            break;
         }
-        case GL_RGB16UI:
+
+        case angle::Format::ID::R32G32B32A32_UINT:
         {
-            static constexpr Format info(GL_RGB16UI,
-                                         angle::Format::ID::R16G16B16_UINT,
-                                         VK_FORMAT_R16G16B16_UINT,
-                                         nullptr);
-            return info;
+            internalFormat          = GL_RGBA32UI;
+            textureFormatID         = angle::Format::ID::R32G32B32A32_UINT;
+            vkTextureFormat         = VK_FORMAT_R32G32B32A32_UINT;
+            bufferFormatID          = angle::Format::ID::R32G32B32A32_UINT;
+            vkBufferFormat          = VK_FORMAT_R32G32B32A32_UINT;
+            dataInitializerFunction = nullptr;
+            break;
+        }
+
+        case angle::Format::ID::R32G32B32_FLOAT:
+        {
+            internalFormat          = GL_RGB32F;
+            textureFormatID         = angle::Format::ID::R32G32B32_FLOAT;
+            vkTextureFormat         = VK_FORMAT_R32G32B32_SFLOAT;
+            bufferFormatID          = angle::Format::ID::R32G32B32_FLOAT;
+            vkBufferFormat          = VK_FORMAT_R32G32B32_SFLOAT;
+            dataInitializerFunction = nullptr;
+            break;
         }
-        case GL_RGB16_EXT:
+
+        case angle::Format::ID::R32G32B32_SINT:
         {
-            static constexpr Format info(GL_RGB16_EXT,
-                                         angle::Format::ID::R16G16B16_UNORM,
-                                         VK_FORMAT_R16G16B16_UNORM,
-                                         nullptr);
-            return info;
+            internalFormat          = GL_RGB32I;
+            textureFormatID         = angle::Format::ID::R32G32B32_SINT;
+            vkTextureFormat         = VK_FORMAT_R32G32B32_SINT;
+            bufferFormatID          = angle::Format::ID::R32G32B32_SINT;
+            vkBufferFormat          = VK_FORMAT_R32G32B32_SINT;
+            dataInitializerFunction = nullptr;
+            break;
         }
-        case GL_RGB16_SNORM_EXT:
+
+        case angle::Format::ID::R32G32B32_UINT:
         {
-            static constexpr Format info(GL_RGB16_SNORM_EXT,
-                                         angle::Format::ID::R16G16B16_SNORM,
-                                         VK_FORMAT_R16G16B16_SNORM,
-                                         nullptr);
-            return info;
+            internalFormat          = GL_RGB32UI;
+            textureFormatID         = angle::Format::ID::R32G32B32_UINT;
+            vkTextureFormat         = VK_FORMAT_R32G32B32_UINT;
+            bufferFormatID          = angle::Format::ID::R32G32B32_UINT;
+            vkBufferFormat          = VK_FORMAT_R32G32B32_UINT;
+            dataInitializerFunction = nullptr;
+            break;
         }
-        case GL_RGB32F:
+
+        case angle::Format::ID::R32G32_FLOAT:
         {
-            static constexpr Format info(GL_RGB32F,
-                                         angle::Format::ID::R32G32B32_FLOAT,
-                                         VK_FORMAT_R32G32B32_SFLOAT,
-                                         nullptr);
-            return info;
+            internalFormat          = GL_RG32F;
+            textureFormatID         = angle::Format::ID::R32G32_FLOAT;
+            vkTextureFormat         = VK_FORMAT_R32G32_SFLOAT;
+            bufferFormatID          = angle::Format::ID::R32G32_FLOAT;
+            vkBufferFormat          = VK_FORMAT_R32G32_SFLOAT;
+            dataInitializerFunction = nullptr;
+            break;
         }
-        case GL_RGB32I:
+
+        case angle::Format::ID::R32G32_SINT:
         {
-            static constexpr Format info(GL_RGB32I,
-                                         angle::Format::ID::R32G32B32_SINT,
-                                         VK_FORMAT_R32G32B32_SINT,
-                                         nullptr);
-            return info;
+            internalFormat          = GL_RG32I;
+            textureFormatID         = angle::Format::ID::R32G32_SINT;
+            vkTextureFormat         = VK_FORMAT_R32G32_SINT;
+            bufferFormatID          = angle::Format::ID::R32G32_SINT;
+            vkBufferFormat          = VK_FORMAT_R32G32_SINT;
+            dataInitializerFunction = nullptr;
+            break;
         }
-        case GL_RGB32UI:
+
+        case angle::Format::ID::R32G32_UINT:
         {
-            static constexpr Format info(GL_RGB32UI,
-                                         angle::Format::ID::R32G32B32_UINT,
-                                         VK_FORMAT_R32G32B32_UINT,
-                                         nullptr);
-            return info;
+            internalFormat          = GL_RG32UI;
+            textureFormatID         = angle::Format::ID::R32G32_UINT;
+            vkTextureFormat         = VK_FORMAT_R32G32_UINT;
+            bufferFormatID          = angle::Format::ID::R32G32_UINT;
+            vkBufferFormat          = VK_FORMAT_R32G32_UINT;
+            dataInitializerFunction = nullptr;
+            break;
         }
-        case GL_RGB565:
+
+        case angle::Format::ID::R32_FLOAT:
         {
-            static constexpr Format info(GL_RGB565,
-                                         angle::Format::ID::R5G6B5_UNORM,
-                                         VK_FORMAT_R5G6B5_UNORM_PACK16,
-                                         nullptr);
-            return info;
+            internalFormat          = GL_R32F;
+            textureFormatID         = angle::Format::ID::R32_FLOAT;
+            vkTextureFormat         = VK_FORMAT_R32_SFLOAT;
+            bufferFormatID          = angle::Format::ID::R32_FLOAT;
+            vkBufferFormat          = VK_FORMAT_R32_SFLOAT;
+            dataInitializerFunction = nullptr;
+            break;
         }
-        case GL_RGB5_A1:
+
+        case angle::Format::ID::R32_SINT:
         {
-            static constexpr Format info(GL_RGB5_A1,
-                                         angle::Format::ID::R5G5B5A1_UNORM,
-                                         VK_FORMAT_R5G5B5A1_UNORM_PACK16,
-                                         nullptr);
-            return info;
+            internalFormat          = GL_R32I;
+            textureFormatID         = angle::Format::ID::R32_SINT;
+            vkTextureFormat         = VK_FORMAT_R32_SINT;
+            bufferFormatID          = angle::Format::ID::R32_SINT;
+            vkBufferFormat          = VK_FORMAT_R32_SINT;
+            dataInitializerFunction = nullptr;
+            break;
         }
-        case GL_RGB8:
+
+        case angle::Format::ID::R32_UINT:
         {
-            static constexpr Format info(GL_RGB8,
-                                         angle::Format::ID::R8G8B8_UNORM,
-                                         VK_FORMAT_R8G8B8_UNORM,
-                                         nullptr);
-            return info;
+            internalFormat          = GL_R32UI;
+            textureFormatID         = angle::Format::ID::R32_UINT;
+            vkTextureFormat         = VK_FORMAT_R32_UINT;
+            bufferFormatID          = angle::Format::ID::R32_UINT;
+            vkBufferFormat          = VK_FORMAT_R32_UINT;
+            dataInitializerFunction = nullptr;
+            break;
         }
-        case GL_RGB8I:
+
+        case angle::Format::ID::R4G4B4A4_UNORM:
         {
-            static constexpr Format info(GL_RGB8I,
-                                         angle::Format::ID::R8G8B8_SINT,
-                                         VK_FORMAT_R8G8B8_SINT,
-                                         nullptr);
-            return info;
+            internalFormat          = GL_RGBA4;
+            textureFormatID         = angle::Format::ID::R4G4B4A4_UNORM;
+            vkTextureFormat         = VK_FORMAT_R4G4B4A4_UNORM_PACK16;
+            bufferFormatID          = angle::Format::ID::R4G4B4A4_UNORM;
+            vkBufferFormat          = VK_FORMAT_R4G4B4A4_UNORM_PACK16;
+            dataInitializerFunction = nullptr;
+            break;
         }
-        case GL_RGB8UI:
+
+        case angle::Format::ID::R5G5B5A1_UNORM:
         {
-            static constexpr Format info(GL_RGB8UI,
-                                         angle::Format::ID::R8G8B8_UINT,
-                                         VK_FORMAT_R8G8B8_UINT,
-                                         nullptr);
-            return info;
+            internalFormat          = GL_RGB5_A1;
+            textureFormatID         = angle::Format::ID::R5G5B5A1_UNORM;
+            vkTextureFormat         = VK_FORMAT_R5G5B5A1_UNORM_PACK16;
+            bufferFormatID          = angle::Format::ID::R5G5B5A1_UNORM;
+            vkBufferFormat          = VK_FORMAT_R5G5B5A1_UNORM_PACK16;
+            dataInitializerFunction = nullptr;
+            break;
         }
-        case GL_RGB8_SNORM:
+
+        case angle::Format::ID::R5G6B5_UNORM:
         {
-            static constexpr Format info(GL_RGB8_SNORM,
-                                         angle::Format::ID::R8G8B8_SNORM,
-                                         VK_FORMAT_R8G8B8_SNORM,
-                                         nullptr);
-            return info;
+            internalFormat          = GL_RGB565;
+            textureFormatID         = angle::Format::ID::R5G6B5_UNORM;
+            vkTextureFormat         = VK_FORMAT_R5G6B5_UNORM_PACK16;
+            bufferFormatID          = angle::Format::ID::R5G6B5_UNORM;
+            vkBufferFormat          = VK_FORMAT_R5G6B5_UNORM_PACK16;
+            dataInitializerFunction = nullptr;
+            break;
         }
-        case GL_RGBA:
+
+        case angle::Format::ID::R8G8B8A8_SINT:
         {
-            static constexpr Format info(GL_RGBA,
-                                         angle::Format::ID::R8G8B8A8_UNORM,
-                                         VK_FORMAT_R8G8B8A8_UNORM,
-                                         nullptr);
-            return info;
+            internalFormat          = GL_RGBA8I;
+            textureFormatID         = angle::Format::ID::R8G8B8A8_SINT;
+            vkTextureFormat         = VK_FORMAT_R8G8B8A8_SINT;
+            bufferFormatID          = angle::Format::ID::R8G8B8A8_SINT;
+            vkBufferFormat          = VK_FORMAT_R8G8B8A8_SINT;
+            dataInitializerFunction = nullptr;
+            break;
         }
-        case GL_RGBA16F:
+
+        case angle::Format::ID::R8G8B8A8_SNORM:
         {
-            static constexpr Format info(GL_RGBA16F,
-                                         angle::Format::ID::R16G16B16A16_FLOAT,
-                                         VK_FORMAT_R16G16B16A16_SFLOAT,
-                                         nullptr);
-            return info;
+            internalFormat          = GL_RGBA8_SNORM;
+            textureFormatID         = angle::Format::ID::R8G8B8A8_SNORM;
+            vkTextureFormat         = VK_FORMAT_R8G8B8A8_SNORM;
+            bufferFormatID          = angle::Format::ID::R8G8B8A8_SNORM;
+            vkBufferFormat          = VK_FORMAT_R8G8B8A8_SNORM;
+            dataInitializerFunction = nullptr;
+            break;
+        }
+
+        case angle::Format::ID::R8G8B8A8_UINT:
+        {
+            internalFormat          = GL_RGBA8UI;
+            textureFormatID         = angle::Format::ID::R8G8B8A8_UINT;
+            vkTextureFormat         = VK_FORMAT_R8G8B8A8_UINT;
+            bufferFormatID          = angle::Format::ID::R8G8B8A8_UINT;
+            vkBufferFormat          = VK_FORMAT_R8G8B8A8_UINT;
+            dataInitializerFunction = nullptr;
+            break;
         }
-        case GL_RGBA16I:
+
+        case angle::Format::ID::R8G8B8A8_UNORM:
         {
-            static constexpr Format info(GL_RGBA16I,
-                                         angle::Format::ID::R16G16B16A16_SINT,
-                                         VK_FORMAT_R16G16B16A16_SINT,
-                                         nullptr);
-            return info;
+            internalFormat          = GL_RGBA8;
+            textureFormatID         = angle::Format::ID::R8G8B8A8_UNORM;
+            vkTextureFormat         = VK_FORMAT_R8G8B8A8_UNORM;
+            bufferFormatID          = angle::Format::ID::R8G8B8A8_UNORM;
+            vkBufferFormat          = VK_FORMAT_R8G8B8A8_UNORM;
+            dataInitializerFunction = nullptr;
+            break;
         }
-        case GL_RGBA16UI:
+
+        case angle::Format::ID::R8G8B8A8_UNORM_SRGB:
+            // This format is not implemented in Vulkan.
+            break;
+
+        case angle::Format::ID::R8G8B8_SINT:
         {
-            static constexpr Format info(GL_RGBA16UI,
-                                         angle::Format::ID::R16G16B16A16_UINT,
-                                         VK_FORMAT_R16G16B16A16_UINT,
-                                         nullptr);
-            return info;
+            internalFormat          = GL_RGB8I;
+            textureFormatID         = angle::Format::ID::R8G8B8_SINT;
+            vkTextureFormat         = VK_FORMAT_R8G8B8_SINT;
+            bufferFormatID          = angle::Format::ID::R8G8B8_SINT;
+            vkBufferFormat          = VK_FORMAT_R8G8B8_SINT;
+            dataInitializerFunction = nullptr;
+            break;
         }
-        case GL_RGBA16_EXT:
+
+        case angle::Format::ID::R8G8B8_SNORM:
         {
-            static constexpr Format info(GL_RGBA16_EXT,
-                                         angle::Format::ID::R16G16B16A16_UNORM,
-                                         VK_FORMAT_R16G16B16A16_UNORM,
-                                         nullptr);
-            return info;
+            internalFormat          = GL_RGB8_SNORM;
+            textureFormatID         = angle::Format::ID::R8G8B8_SNORM;
+            vkTextureFormat         = VK_FORMAT_R8G8B8_SNORM;
+            bufferFormatID          = angle::Format::ID::R8G8B8_SNORM;
+            vkBufferFormat          = VK_FORMAT_R8G8B8_SNORM;
+            dataInitializerFunction = nullptr;
+            break;
         }
-        case GL_RGBA16_SNORM_EXT:
+
+        case angle::Format::ID::R8G8B8_UINT:
         {
-            static constexpr Format info(GL_RGBA16_SNORM_EXT,
-                                         angle::Format::ID::R16G16B16A16_SNORM,
-                                         VK_FORMAT_R16G16B16A16_SNORM,
-                                         nullptr);
-            return info;
+            internalFormat          = GL_RGB8UI;
+            textureFormatID         = angle::Format::ID::R8G8B8_UINT;
+            vkTextureFormat         = VK_FORMAT_R8G8B8_UINT;
+            bufferFormatID          = angle::Format::ID::R8G8B8_UINT;
+            vkBufferFormat          = VK_FORMAT_R8G8B8_UINT;
+            dataInitializerFunction = nullptr;
+            break;
         }
-        case GL_RGBA32F:
+
+        case angle::Format::ID::R8G8B8_UNORM:
         {
-            static constexpr Format info(GL_RGBA32F,
-                                         angle::Format::ID::R32G32B32A32_FLOAT,
-                                         VK_FORMAT_R32G32B32A32_SFLOAT,
-                                         nullptr);
-            return info;
+            internalFormat          = GL_RGB8;
+            textureFormatID         = angle::Format::ID::R8G8B8A8_UNORM;
+            vkTextureFormat         = VK_FORMAT_R8G8B8A8_UNORM;
+            bufferFormatID          = angle::Format::ID::R8G8B8_UNORM;
+            vkBufferFormat          = VK_FORMAT_R8G8B8_UNORM;
+            dataInitializerFunction = Initialize4ComponentData<GLubyte, 0x00, 0x00, 0x00, 0xFF>;
+            break;
         }
-        case GL_RGBA32I:
+
+        case angle::Format::ID::R8G8B8_UNORM_SRGB:
+            // This format is not implemented in Vulkan.
+            break;
+
+        case angle::Format::ID::R8G8_SINT:
         {
-            static constexpr Format info(GL_RGBA32I,
-                                         angle::Format::ID::R32G32B32A32_SINT,
-                                         VK_FORMAT_R32G32B32A32_SINT,
-                                         nullptr);
-            return info;
+            internalFormat          = GL_RG8I;
+            textureFormatID         = angle::Format::ID::R8G8_SINT;
+            vkTextureFormat         = VK_FORMAT_R8G8_SINT;
+            bufferFormatID          = angle::Format::ID::R8G8_SINT;
+            vkBufferFormat          = VK_FORMAT_R8G8_SINT;
+            dataInitializerFunction = nullptr;
+            break;
         }
-        case GL_RGBA32UI:
+
+        case angle::Format::ID::R8G8_SNORM:
         {
-            static constexpr Format info(GL_RGBA32UI,
-                                         angle::Format::ID::R32G32B32A32_UINT,
-                                         VK_FORMAT_R32G32B32A32_UINT,
-                                         nullptr);
-            return info;
+            internalFormat          = GL_RG8_SNORM;
+            textureFormatID         = angle::Format::ID::R8G8_SNORM;
+            vkTextureFormat         = VK_FORMAT_R8G8_SNORM;
+            bufferFormatID          = angle::Format::ID::R8G8_SNORM;
+            vkBufferFormat          = VK_FORMAT_R8G8_SNORM;
+            dataInitializerFunction = nullptr;
+            break;
         }
-        case GL_RGBA4:
+
+        case angle::Format::ID::R8G8_UINT:
+        {
+            internalFormat          = GL_RG8UI;
+            textureFormatID         = angle::Format::ID::R8G8_UINT;
+            vkTextureFormat         = VK_FORMAT_R8G8_UINT;
+            bufferFormatID          = angle::Format::ID::R8G8_UINT;
+            vkBufferFormat          = VK_FORMAT_R8G8_UINT;
+            dataInitializerFunction = nullptr;
+            break;
+        }
+
+        case angle::Format::ID::R8G8_UNORM:
         {
-            static constexpr Format info(GL_RGBA4,
-                                         angle::Format::ID::R4G4B4A4_UNORM,
-                                         VK_FORMAT_R4G4B4A4_UNORM_PACK16,
-                                         nullptr);
-            return info;
+            internalFormat          = GL_RG8;
+            textureFormatID         = angle::Format::ID::R8G8_UNORM;
+            vkTextureFormat         = VK_FORMAT_R8G8_UNORM;
+            bufferFormatID          = angle::Format::ID::R8G8_UNORM;
+            vkBufferFormat          = VK_FORMAT_R8G8_UNORM;
+            dataInitializerFunction = nullptr;
+            break;
         }
-        case GL_RGBA8:
+
+        case angle::Format::ID::R8_SINT:
         {
-            static constexpr Format info(GL_RGBA8,
-                                         angle::Format::ID::R8G8B8A8_UNORM,
-                                         VK_FORMAT_R8G8B8A8_UNORM,
-                                         nullptr);
-            return info;
+            internalFormat          = GL_R8I;
+            textureFormatID         = angle::Format::ID::R8_SINT;
+            vkTextureFormat         = VK_FORMAT_R8_SINT;
+            bufferFormatID          = angle::Format::ID::R8_SINT;
+            vkBufferFormat          = VK_FORMAT_R8_SINT;
+            dataInitializerFunction = nullptr;
+            break;
         }
-        case GL_RGBA8I:
+
+        case angle::Format::ID::R8_SNORM:
         {
-            static constexpr Format info(GL_RGBA8I,
-                                         angle::Format::ID::R8G8B8A8_SINT,
-                                         VK_FORMAT_R8G8B8A8_SINT,
-                                         nullptr);
-            return info;
+            internalFormat          = GL_R8_SNORM;
+            textureFormatID         = angle::Format::ID::R8_SNORM;
+            vkTextureFormat         = VK_FORMAT_R8_SNORM;
+            bufferFormatID          = angle::Format::ID::R8_SNORM;
+            vkBufferFormat          = VK_FORMAT_R8_SNORM;
+            dataInitializerFunction = nullptr;
+            break;
         }
-        case GL_RGBA8UI:
+
+        case angle::Format::ID::R8_UINT:
         {
-            static constexpr Format info(GL_RGBA8UI,
-                                         angle::Format::ID::R8G8B8A8_UINT,
-                                         VK_FORMAT_R8G8B8A8_UINT,
-                                         nullptr);
-            return info;
+            internalFormat          = GL_R8UI;
+            textureFormatID         = angle::Format::ID::R8_UINT;
+            vkTextureFormat         = VK_FORMAT_R8_UINT;
+            bufferFormatID          = angle::Format::ID::R8_UINT;
+            vkBufferFormat          = VK_FORMAT_R8_UINT;
+            dataInitializerFunction = nullptr;
+            break;
         }
-        case GL_RGBA8_SNORM:
+
+        case angle::Format::ID::R8_UNORM:
         {
-            static constexpr Format info(GL_RGBA8_SNORM,
-                                         angle::Format::ID::R8G8B8A8_SNORM,
-                                         VK_FORMAT_R8G8B8A8_SNORM,
-                                         nullptr);
-            return info;
+            internalFormat          = GL_R8;
+            textureFormatID         = angle::Format::ID::R8_UNORM;
+            vkTextureFormat         = VK_FORMAT_R8_UNORM;
+            bufferFormatID          = angle::Format::ID::R8_UNORM;
+            vkBufferFormat          = VK_FORMAT_R8_UNORM;
+            dataInitializerFunction = nullptr;
+            break;
         }
-        case GL_STENCIL_INDEX8:
+
+        case angle::Format::ID::R9G9B9E5_SHAREDEXP:
+            // This format is not implemented in Vulkan.
+            break;
+
+        case angle::Format::ID::S8_UINT:
         {
-            static constexpr Format info(GL_STENCIL_INDEX8,
-                                         angle::Format::ID::S8_UINT,
-                                         VK_FORMAT_S8_UINT,
-                                         nullptr);
-            return info;
+            internalFormat          = GL_STENCIL_INDEX8;
+            textureFormatID         = angle::Format::ID::S8_UINT;
+            vkTextureFormat         = VK_FORMAT_S8_UINT;
+            bufferFormatID          = angle::Format::ID::S8_UINT;
+            vkBufferFormat          = VK_FORMAT_S8_UINT;
+            dataInitializerFunction = nullptr;
+            break;
         }
 
         default:
+            UNREACHABLE();
             break;
     }
-    // clang-format on
-
-    UNREACHABLE();
-    static const Format noInfo(GL_NONE, angle::Format::ID::NONE, VK_FORMAT_UNDEFINED, nullptr);
-    return noInfo;
 }
 
 }  // namespace vk
 
 }  // namespace rx
--- a/gfx/angle/src/libANGLE/validationEGL.cpp
+++ b/gfx/angle/src/libANGLE/validationEGL.cpp
@@ -293,23 +293,22 @@ Error ValidateGetPlatformDisplayCommon(E
             break;
         default:
             return EglBadConfig() << "Bad platform type.";
     }
 
     if (platform == EGL_PLATFORM_ANGLE_ANGLE)
     {
         EGLAttrib platformType       = EGL_PLATFORM_ANGLE_TYPE_DEFAULT_ANGLE;
-        EGLAttrib deviceType         = EGL_PLATFORM_ANGLE_DEVICE_TYPE_HARDWARE_ANGLE;
         bool enableAutoTrimSpecified = false;
-        bool deviceTypeSpecified     = false;
         bool presentPathSpecified    = false;
 
         Optional<EGLAttrib> majorVersion;
         Optional<EGLAttrib> minorVersion;
+        Optional<EGLAttrib> deviceType;
 
         for (const auto &curAttrib : attribMap)
         {
             const EGLAttrib value = curAttrib.second;
 
             switch (curAttrib.first)
             {
                 case EGL_PLATFORM_ANGLE_TYPE_ANGLE:
@@ -363,23 +362,26 @@ Error ValidateGetPlatformDisplayCommon(E
                     }
                     presentPathSpecified = true;
                     break;
 
                 case EGL_PLATFORM_ANGLE_DEVICE_TYPE_ANGLE:
                     switch (value)
                     {
                         case EGL_PLATFORM_ANGLE_DEVICE_TYPE_HARDWARE_ANGLE:
-                        case EGL_PLATFORM_ANGLE_DEVICE_TYPE_WARP_ANGLE:
-                        case EGL_PLATFORM_ANGLE_DEVICE_TYPE_REFERENCE_ANGLE:
-                            deviceTypeSpecified = true;
+                        case EGL_PLATFORM_ANGLE_DEVICE_TYPE_NULL_ANGLE:
                             break;
 
-                        case EGL_PLATFORM_ANGLE_DEVICE_TYPE_NULL_ANGLE:
-                            // This is a hidden option, accepted by the OpenGL back-end.
+                        case EGL_PLATFORM_ANGLE_DEVICE_TYPE_D3D_WARP_ANGLE:
+                        case EGL_PLATFORM_ANGLE_DEVICE_TYPE_D3D_REFERENCE_ANGLE:
+                            if (!clientExtensions.platformANGLED3D)
+                            {
+                                return EglBadAttribute()
+                                       << "EGL_ANGLE_platform_angle_d3d is not supported";
+                            }
                             break;
 
                         default:
                             return EglBadAttribute() << "Invalid value for "
                                                         "EGL_PLATFORM_ANGLE_DEVICE_TYPE_ANGLE "
                                                         "attrib";
                     }
                     deviceType = value;
@@ -393,43 +395,28 @@ Error ValidateGetPlatformDisplayCommon(E
                     if (value != EGL_TRUE && value != EGL_FALSE && value != EGL_DONT_CARE)
                     {
                         return EglBadAttribute() << "EGL_PLATFORM_ANGLE_DEBUG_LAYERS_ENABLED_ANGLE "
                                                     "must be EGL_TRUE, EGL_FALSE, or "
                                                     "EGL_DONT_CARE.";
                     }
                     break;
 
-                case EGL_DISPLAY_ROBUST_RESOURCE_INITIALIZATION_ANGLE:
-                    if (!clientExtensions.displayRobustResourceInitialization)
-                    {
-                        return EglBadAttribute()
-                               << "Attribute EGL_DISPLAY_ROBUST_RESOURCE_INITIALIZATION_ANGLE "
-                                  "requires EGL_ANGLE_display_robust_resource_initialization.";
-                    }
-                    if (value != EGL_TRUE && value != EGL_FALSE)
-                    {
-                        return EglBadAttribute() << "EGL_DISPLAY_ROBUST_RESOURCE_"
-                                                    "INITIALIZATION_ANGLE must be either "
-                                                    "EGL_TRUE or EGL_FALSE.";
-                    }
-                    break;
-
                 default:
                     break;
             }
         }
 
         if (!majorVersion.valid() && minorVersion.valid())
         {
             return EglBadAttribute()
                    << "Must specify major version if you specify a minor version.";
         }
 
-        if (deviceType == EGL_PLATFORM_ANGLE_DEVICE_TYPE_WARP_ANGLE &&
+        if (deviceType == EGL_PLATFORM_ANGLE_DEVICE_TYPE_D3D_WARP_ANGLE &&
             platformType != EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE)
         {
             return EglBadAttribute() << "EGL_PLATFORM_ANGLE_DEVICE_TYPE_WARP_ANGLE requires a "
                                         "device type of EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE.";
         }
 
         if (enableAutoTrimSpecified && platformType != EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE)
         {
@@ -439,22 +426,33 @@ Error ValidateGetPlatformDisplayCommon(E
         }
 
         if (presentPathSpecified && platformType != EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE)
         {
             return EglBadAttribute() << "EGL_EXPERIMENTAL_PRESENT_PATH_ANGLE requires a "
                                         "device type of EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE.";
         }
 
-        if (deviceTypeSpecified && platformType != EGL_PLATFORM_ANGLE_TYPE_D3D9_ANGLE &&
-            platformType != EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE)
+        if (deviceType.valid())
         {
-            return EglBadAttribute() << "EGL_PLATFORM_ANGLE_DEVICE_TYPE_ANGLE requires a "
-                                        "device type of EGL_PLATFORM_ANGLE_TYPE_D3D9_ANGLE or "
-                                        "EGL_PLATFORM_ANGLE_TYPE_D3D9_ANGLE.";
+            switch (deviceType.value())
+            {
+                case EGL_PLATFORM_ANGLE_DEVICE_TYPE_D3D_REFERENCE_ANGLE:
+                case EGL_PLATFORM_ANGLE_DEVICE_TYPE_D3D_WARP_ANGLE:
+                    if (platformType != EGL_PLATFORM_ANGLE_TYPE_D3D9_ANGLE &&
+                        platformType != EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE)
+                    {
+                        return EglBadAttribute()
+                               << "This device type requires a "
+                                  "platform type of EGL_PLATFORM_ANGLE_TYPE_D3D9_ANGLE or "
+                                  "EGL_PLATFORM_ANGLE_TYPE_D3D9_ANGLE.";
+                    }
+                default:
+                    break;
+            }
         }
 
         if (platformType == EGL_PLATFORM_ANGLE_TYPE_VULKAN_ANGLE)
         {
             if ((majorVersion.valid() && majorVersion.value() != 1) ||
                 (minorVersion.valid() && minorVersion.value() != 0))
             {
                 return EglBadAttribute() << "EGL_PLATFORM_ANGLE_TYPE_VULKAN_ANGLE currently "
@@ -615,19 +613,19 @@ Error ValidateCreateContext(Display *dis
             }
             if (value != EGL_TRUE && value != EGL_FALSE)
             {
                 return EglBadAttribute();
             }
             break;
 
           case EGL_CONTEXT_OPENGL_RESET_NOTIFICATION_STRATEGY_KHR:
-            static_assert(EGL_LOSE_CONTEXT_ON_RESET_EXT == EGL_LOSE_CONTEXT_ON_RESET_KHR, "EGL extension enums not equal.");
-            static_assert(EGL_NO_RESET_NOTIFICATION_EXT == EGL_NO_RESET_NOTIFICATION_KHR, "EGL extension enums not equal.");
-            // same as EGL_CONTEXT_OPENGL_RESET_NOTIFICATION_STRATEGY_EXT, fall through
+            return EglBadAttribute() << "EGL_CONTEXT_OPENGL_RESET_NOTIFICATION_STRATEGY_KHR is not"
+                                     << " valid for GLES with EGL 1.4 and KHR_create_context. Use"
+                                     << " EXT_create_context_robustness.";
           case EGL_CONTEXT_OPENGL_RESET_NOTIFICATION_STRATEGY_EXT:
             if (!display->getExtensions().createContextRobustness)
             {
                 return EglBadAttribute();
             }
             if (value == EGL_LOSE_CONTEXT_ON_RESET_EXT)
             {
                 resetNotification = true;
@@ -721,16 +719,29 @@ Error ValidateCreateContext(Display *dis
               }
               if (value != EGL_TRUE && value != EGL_FALSE)
               {
                   return EglBadAttribute() << "EGL_CONTEXT_PROGRAM_BINARY_CACHE_ENABLED_ANGLE must "
                                               "be EGL_TRUE or EGL_FALSE.";
               }
               break;
 
+          case EGL_ROBUST_RESOURCE_INITIALIZATION_ANGLE:
+              if (!display->getExtensions().robustResourceInitialization)
+              {
+                  return EglBadAttribute() << "Attribute EGL_ROBUST_RESOURCE_INITIALIZATION_ANGLE "
+                                              "requires EGL_ANGLE_robust_resource_initialization.";
+              }
+              if (value != EGL_TRUE && value != EGL_FALSE)
+              {
+                  return EglBadAttribute() << "EGL_ROBUST_RESOURCE_INITIALIZATION_ANGLE must be "
+                                              "either EGL_TRUE or EGL_FALSE.";
+              }
+              break;
+
           default:
               return EglBadAttribute() << "Unknown attribute.";
         }
     }
 
     switch (clientMajorVersion)
     {
         case 2:
@@ -739,17 +750,17 @@ Error ValidateCreateContext(Display *dis
                 return EglBadConfig();
             }
             break;
         case 3:
             if (clientMinorVersion != 0 && clientMinorVersion != 1)
             {
                 return EglBadConfig();
             }
-            if (!(configuration->renderableType & EGL_OPENGL_ES3_BIT_KHR))
+            if (!(configuration->conformant & EGL_OPENGL_ES3_BIT_KHR))
             {
                 return EglBadConfig();
             }
             if (display->getMaxSupportedESVersion() <
                 gl::Version(static_cast<GLuint>(clientMajorVersion),
                             static_cast<GLuint>(clientMinorVersion)))
             {
                 return EglBadConfig() << "Requested GLES version is not supported.";
@@ -870,16 +881,29 @@ Error ValidateCreateWindowSurface(Displa
 
           case EGL_DIRECT_COMPOSITION_ANGLE:
               if (!displayExtensions.directComposition)
               {
                   return EglBadAttribute();
               }
               break;
 
+          case EGL_ROBUST_RESOURCE_INITIALIZATION_ANGLE:
+              if (!display->getExtensions().robustResourceInitialization)
+              {
+                  return EglBadAttribute() << "Attribute EGL_ROBUST_RESOURCE_INITIALIZATION_ANGLE "
+                                              "requires EGL_ANGLE_robust_resource_initialization.";
+              }
+              if (value != EGL_TRUE && value != EGL_FALSE)
+              {
+                  return EglBadAttribute() << "EGL_ROBUST_RESOURCE_INITIALIZATION_ANGLE must be "
+                                              "either EGL_TRUE or EGL_FALSE.";
+              }
+              break;
+
           default:
               return EglBadAttribute();
         }
     }
 
     if (Display::hasExistingWindowSurface(window))
     {
         return EglBadAlloc();
@@ -948,16 +972,29 @@ Error ValidateCreatePbufferSurface(Displ
               if (!displayExtensions.flexibleSurfaceCompatibility)
               {
                   return EglBadAttribute()
                          << "EGL_FLEXIBLE_SURFACE_COMPATIBILITY_SUPPORTED_ANGLE cannot be used "
                             "without EGL_ANGLE_flexible_surface_compatibility support.";
               }
               break;
 
+          case EGL_ROBUST_RESOURCE_INITIALIZATION_ANGLE:
+              if (!display->getExtensions().robustResourceInitialization)
+              {
+                  return EglBadAttribute() << "Attribute EGL_ROBUST_RESOURCE_INITIALIZATION_ANGLE "
+                                              "requires EGL_ANGLE_robust_resource_initialization.";
+              }
+              if (value != EGL_TRUE && value != EGL_FALSE)
+              {
+                  return EglBadAttribute() << "EGL_ROBUST_RESOURCE_INITIALIZATION_ANGLE must be "
+                                              "either EGL_TRUE or EGL_FALSE.";
+              }
+              break;
+
           default:
               return EglBadAttribute();
         }
     }
 
     if (!(config->surfaceType & EGL_PBUFFER_BIT))
     {
         return EglBadMatch();
@@ -1016,96 +1053,149 @@ Error ValidateCreatePbufferFromClientBuf
               return EglBadParameter();
           }
           if (buffer == nullptr)
           {
               return EglBadParameter();
           }
           break;
 
+      case EGL_IOSURFACE_ANGLE:
+          if (!displayExtensions.iosurfaceClientBuffer)
+          {
+              return EglBadParameter() << "<buftype> EGL_IOSURFACE_ANGLE requires the "
+                                          "EGL_ANGLE_iosurface_client_buffer extension.";
+          }
+          if (buffer == nullptr)
+          {
+              return EglBadParameter() << "<buffer> must be non null";
+          }
+          break;
+
       default:
           return EglBadParameter();
     }
 
     for (AttributeMap::const_iterator attributeIter = attributes.begin(); attributeIter != attributes.end(); attributeIter++)
     {
         EGLAttrib attribute = attributeIter->first;
         EGLAttrib value     = attributeIter->second;
 
         switch (attribute)
         {
-          case EGL_WIDTH:
-          case EGL_HEIGHT:
-            if (!displayExtensions.d3dShareHandleClientBuffer)
-            {
-                return EglBadParameter();
-            }
-            if (value < 0)
-            {
-                return EglBadParameter();
-            }
-            break;
+            case EGL_WIDTH:
+            case EGL_HEIGHT:
+                if (buftype != EGL_D3D_TEXTURE_2D_SHARE_HANDLE_ANGLE &&
+                    buftype != EGL_D3D_TEXTURE_ANGLE &&
+                    buftype != EGL_IOSURFACE_ANGLE)
+                {
+                    return EglBadParameter()
+                           << "Width and Height are not supported for thie <buftype>";
+                }
+                if (value < 0)
+                {
+                    return EglBadParameter() << "Width and Height must be positive";
+                }
+                break;
 
-          case EGL_TEXTURE_FORMAT:
-            switch (value)
-            {
-              case EGL_NO_TEXTURE:
-              case EGL_TEXTURE_RGB:
-              case EGL_TEXTURE_RGBA:
+            case EGL_TEXTURE_FORMAT:
+                switch (value)
+                {
+                    case EGL_NO_TEXTURE:
+                    case EGL_TEXTURE_RGB:
+                    case EGL_TEXTURE_RGBA:
+                        break;
+                    default:
+                        return EglBadAttribute() << "Invalid value for EGL_TEXTURE_FORMAT";
+                }
                 break;
-              default:
-                  return EglBadAttribute();
-            }
-            break;
+
+            case EGL_TEXTURE_TARGET:
+                switch (value)
+                {
+                    case EGL_NO_TEXTURE:
+                    case EGL_TEXTURE_2D:
+                        break;
+                    case EGL_TEXTURE_RECTANGLE_ANGLE:
+                        if (buftype != EGL_IOSURFACE_ANGLE)
+                        {
+                            return EglBadParameter()
+                                   << "<buftype> doesn't support rectangle texture targets";
+                        }
+                        break;
 
-          case EGL_TEXTURE_TARGET:
-            switch (value)
-            {
-              case EGL_NO_TEXTURE:
-              case EGL_TEXTURE_2D:
+                    default:
+                        return EglBadAttribute() << "Invalid value for EGL_TEXTURE_TARGET";
+                }
+                break;
+
+            case EGL_MIPMAP_TEXTURE:
                 break;
-              default:
-                  return EglBadAttribute();
-            }
-            break;
+
+            case EGL_FLEXIBLE_SURFACE_COMPATIBILITY_SUPPORTED_ANGLE:
+                if (!displayExtensions.flexibleSurfaceCompatibility)
+                {
+                    return EglBadAttribute()
+                           << "EGL_FLEXIBLE_SURFACE_COMPATIBILITY_SUPPORTED_ANGLE cannot be used "
+                              "without EGL_ANGLE_flexible_surface_compatibility support.";
+                }
+                break;
 
-          case EGL_MIPMAP_TEXTURE:
-            break;
+            case EGL_IOSURFACE_PLANE_ANGLE:
+                if (buftype != EGL_IOSURFACE_ANGLE)
+                {
+                    return EglBadAttribute() << "<buftype> doesn't support iosurface plane";
+                }
+                break;
 
-          case EGL_FLEXIBLE_SURFACE_COMPATIBILITY_SUPPORTED_ANGLE:
-              if (!displayExtensions.flexibleSurfaceCompatibility)
-              {
-                  return EglBadAttribute()
-                         << "EGL_FLEXIBLE_SURFACE_COMPATIBILITY_SUPPORTED_ANGLE cannot be used "
-                            "without EGL_ANGLE_flexible_surface_compatibility support.";
-              }
-              break;
+            case EGL_TEXTURE_TYPE_ANGLE:
+                if (buftype != EGL_IOSURFACE_ANGLE)
+                {
+                    return EglBadAttribute() << "<buftype> doesn't support texture type";
+                }
+                break;
 
-          default:
-              return EglBadAttribute();
+            case EGL_TEXTURE_INTERNAL_FORMAT_ANGLE:
+                if (buftype != EGL_IOSURFACE_ANGLE)
+                {
+                    return EglBadAttribute() << "<buftype> doesn't support texture internal format";
+                }
+                break;
+
+            default:
+                return EglBadAttribute();
         }
     }
 
     if (!(config->surfaceType & EGL_PBUFFER_BIT))
     {
         return EglBadMatch();
     }
 
     EGLAttrib textureFormat = attributes.get(EGL_TEXTURE_FORMAT, EGL_NO_TEXTURE);
     EGLAttrib textureTarget = attributes.get(EGL_TEXTURE_TARGET, EGL_NO_TEXTURE);
     if ((textureFormat != EGL_NO_TEXTURE && textureTarget == EGL_NO_TEXTURE) ||
         (textureFormat == EGL_NO_TEXTURE && textureTarget != EGL_NO_TEXTURE))
     {
         return EglBadMatch();
     }
-
-    if ((textureFormat == EGL_TEXTURE_RGB  && config->bindToTextureRGB  != EGL_TRUE) ||
+    if ((textureFormat == EGL_TEXTURE_RGB && config->bindToTextureRGB != EGL_TRUE) ||
         (textureFormat == EGL_TEXTURE_RGBA && config->bindToTextureRGBA != EGL_TRUE))
     {
-        return EglBadAttribute();
+        // TODO(cwallez@chromium.org): For IOSurface pbuffers we require that EGL_TEXTURE_RGBA is
+        // set so that eglBinTexImage works. Normally this is only allowed if the config exposes the
+        // bindToTextureRGB/RGBA flag. This issue is that enabling this flags means that
+        // eglBindTexImage should also work for regular pbuffers which isn't implemented on macOS.
+        // Instead of adding the flag we special case the check here to be ignored for IOSurfaces.
+        // The TODO is to find a proper solution for this, maybe by implementing eglBindTexImage on
+        // OSX?
+        if (buftype != EGL_IOSURFACE_ANGLE)
+        {
+            return EglBadAttribute();
+        }
     }
 
     if (buftype == EGL_D3D_TEXTURE_2D_SHARE_HANDLE_ANGLE)
     {
         EGLint width  = static_cast<EGLint>(attributes.get(EGL_WIDTH, 0));
         EGLint height = static_cast<EGLint>(attributes.get(EGL_HEIGHT, 0));
 
         if (width == 0 || height == 0)
@@ -1115,16 +1205,38 @@ Error ValidateCreatePbufferFromClientBuf
 
         const Caps &caps = display->getCaps();
         if (textureFormat != EGL_NO_TEXTURE && !caps.textureNPOT && (!gl::isPow2(width) || !gl::isPow2(height)))
         {
             return EglBadMatch();
         }
     }
 
+    if (buftype == EGL_IOSURFACE_ANGLE)
+    {
+        if (textureTarget != EGL_TEXTURE_RECTANGLE_ANGLE)
+        {
+            return EglBadAttribute() << "EGL_IOSURFACE requires the EGL_TEXTURE_RECTANGLE target";
+        }
+
+        if (textureFormat != EGL_TEXTURE_RGBA)
+        {
+            return EglBadAttribute() << "EGL_IOSURFACE requires the EGL_TEXTURE_RGBA format";
+        }
+
+        if (!attributes.contains(EGL_WIDTH) || !attributes.contains(EGL_HEIGHT) ||
+            !attributes.contains(EGL_TEXTURE_FORMAT) ||
+            !attributes.contains(EGL_TEXTURE_TYPE_ANGLE) ||
+            !attributes.contains(EGL_TEXTURE_INTERNAL_FORMAT_ANGLE) ||
+            !attributes.contains(EGL_IOSURFACE_PLANE_ANGLE))
+        {
+            return EglBadParameter() << "Missing required attribute for EGL_IOSURFACE";
+        }
+    }
+
     ANGLE_TRY(display->validateClientBuffer(config, buftype, buffer, attributes));
 
     return NoError();
 }
 
 Error ValidateMakeCurrent(Display *display, EGLSurface draw, EGLSurface read, gl::Context *context)
 {
     if (context == EGL_NO_CONTEXT && (draw != EGL_NO_SURFACE || read != EGL_NO_SURFACE))
@@ -1943,71 +2055,72 @@ Error ValidateStreamConsumerGLTextureExt
                 textureSet.insert(texture);
             }
         }
     }
 
     return NoError();
 }
 
-Error ValidateCreateStreamProducerD3DTextureNV12ANGLE(const Display *display,
-                                                      const Stream *stream,
-                                                      const AttributeMap &attribs)
+Error ValidateCreateStreamProducerD3DTextureANGLE(const Display *display,
+                                                  const Stream *stream,
+                                                  const AttributeMap &attribs)
 {
     ANGLE_TRY(ValidateDisplay(display));
 
     const DisplayExtensions &displayExtensions = display->getExtensions();
-    if (!displayExtensions.streamProducerD3DTextureNV12)
+    if (!displayExtensions.streamProducerD3DTexture)
     {
         return EglBadAccess() << "Stream producer extension not active";
     }
 
     ANGLE_TRY(ValidateStream(display, stream));
 
     if (!attribs.isEmpty())
     {
         return EglBadAttribute() << "Invalid attribute";
     }
 
     if (stream->getState() != EGL_STREAM_STATE_CONNECTING_KHR)
     {
         return EglBadState() << "Stream not in connecting state";
     }
 
-    switch (stream->getConsumerType()) {
-    case Stream::ConsumerType::GLTextureYUV:
-        if (stream->getPlaneCount() != 2)
-        {
-            return Error(EGL_BAD_MATCH, "Incompatible stream consumer type");
-        }
-        break;
+    switch (stream->getConsumerType())
+    {
+        case Stream::ConsumerType::GLTextureYUV:
+            if (stream->getPlaneCount() != 2)
+            {
+                return EglBadMatch() << "Incompatible stream consumer type";
+            }
+            break;
 
-    case Stream::ConsumerType::GLTextureRGB:
-        if (stream->getPlaneCount() != 1)
-        {
-            return Error(EGL_BAD_MATCH, "Incompatible stream consumer type");
-        }
-        break;
+        case Stream::ConsumerType::GLTextureRGB:
+            if (stream->getPlaneCount() != 1)
+            {
+                return EglBadMatch() << "Incompatible stream consumer type";
+            }
+            break;
 
-    default:
-        return Error(EGL_BAD_MATCH, "Incompatible stream consumer type");
+        default:
+            return EglBadMatch() << "Incompatible stream consumer type";
     }
 
     return NoError();
 }
 
-Error ValidateStreamPostD3DTextureNV12ANGLE(const Display *display,
-                                            const Stream *stream,
-                                            void *texture,
-                                            const AttributeMap &attribs)
+Error ValidateStreamPostD3DTextureANGLE(const Display *display,
+                                        const Stream *stream,
+                                        void *texture,
+                                        const AttributeMap &attribs)
 {
     ANGLE_TRY(ValidateDisplay(display));
 
     const DisplayExtensions &displayExtensions = display->getExtensions();
-    if (!displayExtensions.streamProducerD3DTextureNV12)
+    if (!displayExtensions.streamProducerD3DTexture)
     {
         return EglBadAccess() << "Stream producer extension not active";
     }
 
     ANGLE_TRY(ValidateStream(display, stream));
 
     for (auto &attributeIter : attribs)
     {
@@ -2020,42 +2133,42 @@ Error ValidateStreamPostD3DTextureNV12AN
                 if (value < 0)
                 {
                     return EglBadParameter() << "Invalid subresource index";
                 }
                 break;
             case EGL_NATIVE_BUFFER_PLANE_OFFSET_IMG:
                 if (value < 0)
                 {
-                    return Error(EGL_BAD_PARAMETER, "Invalid plane offset");
+                    return EglBadParameter() << "Invalid plane offset";
                 }
                 break;
             default:
                 return EglBadAttribute() << "Invalid attribute";
         }
     }
 
     if (stream->getState() != EGL_STREAM_STATE_EMPTY_KHR &&
         stream->getState() != EGL_STREAM_STATE_NEW_FRAME_AVAILABLE_KHR &&
         stream->getState() != EGL_STREAM_STATE_OLD_FRAME_AVAILABLE_KHR)
     {
         return EglBadState() << "Stream not fully configured";
     }
 
-    if (stream->getProducerType() != Stream::ProducerType::D3D11TextureNV12)
+    if (stream->getProducerType() != Stream::ProducerType::D3D11Texture)
     {
         return EglBadMatch() << "Incompatible stream producer";
     }
 
     if (texture == nullptr)
     {
         return EglBadParameter() << "Texture is null";
     }
 
-    return stream->validateD3D11NV12Texture(texture, attribs);
+    return stream->validateD3D11Texture(texture, attribs);
 }
 
 Error ValidateGetSyncValuesCHROMIUM(const Display *display,
                                     const Surface *surface,
                                     const EGLuint64KHR *ust,
                                     const EGLuint64KHR *msc,
                                     const EGLuint64KHR *sbc)
 {
@@ -2440,16 +2553,57 @@ Error ValidateQuerySurface(const Display
             if (!display->getExtensions().directComposition)
             {
                 return EglBadAttribute() << "EGL_DIRECT_COMPOSITION_ANGLE cannot be "
                                             "used without "
                                             "EGL_ANGLE_direct_composition support.";
             }
             break;
 
+        case EGL_ROBUST_RESOURCE_INITIALIZATION_ANGLE:
+            if (!display->getExtensions().robustResourceInitialization)
+            {
+                return EglBadAttribute() << "EGL_ROBUST_RESOURCE_INITIALIZATION_ANGLE cannot be "
+                                            "used without EGL_ANGLE_robust_resource_initialization "
+                                            "support.";
+            }
+            break;
+
         default:
             return EglBadAttribute() << "Invalid surface attribute.";
     }
 
     return NoError();
 }
 
+Error ValidateQueryContext(const Display *display,
+                           const gl::Context *context,
+                           EGLint attribute,
+                           EGLint *value)
+{
+    ANGLE_TRY(ValidateDisplay(display));
+    ANGLE_TRY(ValidateContext(display, context));
+
+    switch (attribute)
+    {
+        case EGL_CONFIG_ID:
+        case EGL_CONTEXT_CLIENT_TYPE:
+        case EGL_CONTEXT_CLIENT_VERSION:
+        case EGL_RENDER_BUFFER:
+            break;
+
+        case EGL_ROBUST_RESOURCE_INITIALIZATION_ANGLE:
+            if (!display->getExtensions().robustResourceInitialization)
+            {
+                return EglBadAttribute() << "EGL_ROBUST_RESOURCE_INITIALIZATION_ANGLE cannot be "
+                                            "used without EGL_ANGLE_robust_resource_initialization "
+                                            "support.";
+            }
+            break;
+
+        default:
+            return EglBadAttribute() << "Invalid context attribute.";
+    }
+
+    return NoError();
+}
+
 }  // namespace egl
--- a/gfx/angle/src/libANGLE/validationEGL.h
+++ b/gfx/angle/src/libANGLE/validationEGL.h
@@ -85,23 +85,23 @@ Error ValidateStreamConsumerAcquireKHR(c
                                        const Stream *stream);
 Error ValidateStreamConsumerReleaseKHR(const Display *display,
                                        gl::Context *context,
                                        const Stream *stream);
 Error ValidateStreamConsumerGLTextureExternalAttribsNV(const Display *display,
                                                        gl::Context *context,
                                                        const Stream *stream,
                                                        const AttributeMap &attribs);
-Error ValidateCreateStreamProducerD3DTextureNV12ANGLE(const Display *display,
-                                                      const Stream *stream,
-                                                      const AttributeMap &attribs);
-Error ValidateStreamPostD3DTextureNV12ANGLE(const Display *display,
-                                            const Stream *stream,
-                                            void *texture,
-                                            const AttributeMap &attribs);
+Error ValidateCreateStreamProducerD3DTextureANGLE(const Display *display,
+                                                  const Stream *stream,
+                                                  const AttributeMap &attribs);
+Error ValidateStreamPostD3DTextureANGLE(const Display *display,
+                                        const Stream *stream,
+                                        void *texture,
+                                        const AttributeMap &attribs);
 
 Error ValidateGetSyncValuesCHROMIUM(const Display *display,
                                     const Surface *surface,
                                     const EGLuint64KHR *ust,
                                     const EGLuint64KHR *msc,
                                     const EGLuint64KHR *sbc);
 
 Error ValidateSwapBuffersWithDamageEXT(const Display *display,
@@ -150,16 +150,20 @@ Error ValidateProgramCacheResizeANGLE(co
 Error ValidateSurfaceAttrib(const Display *display,
                             const Surface *surface,
                             EGLint attribute,
                             EGLint value);
 Error ValidateQuerySurface(const Display *display,
                            const Surface *surface,
                            EGLint attribute,
                            EGLint *value);
+Error ValidateQueryContext(const Display *display,
+                           const gl::Context *context,
+                           EGLint attribute,
+                           EGLint *value);
 
 }  // namespace egl
 
 #define ANGLE_EGL_TRY(THREAD, EXPR)                   \
     {                                                 \
         auto ANGLE_LOCAL_VAR = (EXPR);                \
         if (ANGLE_LOCAL_VAR.isError())                \
             return THREAD->setError(ANGLE_LOCAL_VAR); \
--- a/gfx/angle/src/libANGLE/validationES.cpp
+++ b/gfx/angle/src/libANGLE/validationES.cpp
@@ -13,46 +13,46 @@
 #include "libANGLE/ErrorStrings.h"
 #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/Uniform.h"
 #include "libANGLE/VertexArray.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"
 
 using namespace angle;
 
 namespace gl
 {
 namespace
 {
+
 bool ValidateDrawAttribs(ValidationContext *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();
     const auto &vertexBindings = vao->getVertexBindings();
-    size_t maxEnabledAttrib    = vao->getMaxEnabledAttribute();
-    for (size_t attributeIndex = 0; attributeIndex < maxEnabledAttrib; ++attributeIndex)
+    for (size_t attributeIndex : vao->getEnabledAttributesMask())
     {
         const VertexAttribute &attrib = vertexAttribs[attributeIndex];
 
         // No need to range check for disabled attribs.
         if (!attrib.enabled)
         {
             continue;
         }
@@ -386,189 +386,53 @@ bool ValidateTextureSRGBDecodeValue(Cont
         default:
             ANGLE_VALIDATION_ERR(context, InvalidEnum(), UnknownParameter);
             return false;
     }
 
     return true;
 }
 
-bool ValidateUniformCommonBase(ValidationContext *context,
-                               gl::Program *program,
-                               GLint location,
-                               GLsizei count,
-                               const LinkedUniform **uniformOut)
-{
-    // TODO(Jiajia): Add image uniform check in future.
-    if (count < 0)
-    {
-        ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeCount);
-        return false;
-    }
-
-    if (!program)
-    {
-        ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidProgramName);
-        return false;
-    }
-
-    if (!program->isLinked())
-    {
-        ANGLE_VALIDATION_ERR(context, InvalidOperation(), ProgramNotLinked);
-        return false;
-    }
-
-    if (location == -1)
-    {
-        // Silently ignore the uniform command
-        return false;
-    }
-
-    const auto &uniformLocations = program->getUniformLocations();
-    size_t castedLocation        = static_cast<size_t>(location);
-    if (castedLocation >= uniformLocations.size())
-    {
-        context->handleError(InvalidOperation() << "Invalid uniform location");
-        return false;
-    }
-
-    const auto &uniformLocation = uniformLocations[castedLocation];
-    if (uniformLocation.ignored)
-    {
-        // Silently ignore the uniform command
-        return false;
-    }
-
-    if (!uniformLocation.used())
-    {
-        context->handleError(InvalidOperation());
-        return false;
-    }
-
-    const auto &uniform = program->getUniformByIndex(uniformLocation.index);
-
-    // attempting to write an array to a non-array uniform is an INVALID_OPERATION
-    if (!uniform.isArray() && count > 1)
-    {
-        context->handleError(InvalidOperation());
-        return false;
-    }
-
-    *uniformOut = &uniform;
-    return true;
-}
-
-bool ValidateUniform1ivValue(ValidationContext *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)
-    {
-        return true;
-    }
-
-    if (IsSamplerType(uniformType))
-    {
-        // Check that the values are in range.
-        const GLint max = context->getCaps().maxCombinedTextureImageUnits;
-        for (GLsizei i = 0; i < count; ++i)
-        {
-            if (value[i] < 0 || value[i] >= max)
-            {
-                context->handleError(InvalidValue() << "sampler uniform value out of range");
-                return false;
-            }
-        }
-        return true;
-    }
-
-    context->handleError(InvalidOperation() << "wrong type of value for uniform");
-    return false;
-}
-
-bool ValidateUniformValue(ValidationContext *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)
-{
-    // 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 ValidateFragmentShaderColorBufferTypeMatch(ValidationContext *context)
 {
     const Program *program         = context->getGLState().getProgram();
     const Framebuffer *framebuffer = context->getGLState().getDrawFramebuffer();
 
-    const auto &programOutputTypes = program->getOutputVariableTypes();
-    for (size_t drawBufferIdx = 0; drawBufferIdx < programOutputTypes.size(); drawBufferIdx++)
-    {
-        GLenum outputType = programOutputTypes[drawBufferIdx];
-        GLenum inputType  = framebuffer->getDrawbufferWriteType(drawBufferIdx);
-        if (outputType != GL_NONE && inputType != GL_NONE && inputType != outputType)
-        {
-            context->handleError(InvalidOperation() << "Fragment shader output type does not "
-                                                       "match the bound framebuffer attachment "
-                                                       "type.");
-            return false;
-        }
+    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();
     const Program *program = context->getGLState().getProgram();
     const VertexArray *vao = context->getGLState().getVertexArray();
 
-    for (const auto &shaderAttribute : program->getAttributes())
-    {
-        // gl_VertexID and gl_InstanceID are active attributes but don't have a bound attribute.
-        if (shaderAttribute.isBuiltIn())
-        {
-            continue;
-        }
-
-        GLenum shaderInputType = VariableComponentType(shaderAttribute.type);
-
-        const auto &attrib = vao->getVertexAttribute(shaderAttribute.location);
-        const auto &currentValue =
-            context->getGLState().getVertexAttribCurrentValue(shaderAttribute.location);
-        GLenum vertexType = attrib.enabled ? GetVertexAttributeBaseType(attrib) : currentValue.Type;
-
-        if (shaderInputType != GL_NONE && vertexType != GL_NONE && shaderInputType != vertexType)
-        {
-            context->handleError(InvalidOperation() << "Vertex shader input type does not "
-                                                       "match the type of the bound vertex "
-                                                       "attribute.");
-            return false;
-        }
-    }
-
+    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;
+    vaoAttribTypeBits = (vaoAttribEnabledMask & vaoAttribTypeBits);
+    vaoAttribTypeBits |= (~vaoAttribEnabledMask & stateCurrentValuesTypeBits);
+
+    if (!ComponentTypeMask::Validate(program->getAttributesTypeMask().to_ulong(), vaoAttribTypeBits,
+                                     program->getAttributesMask().to_ulong(), 0xFFFF))
+    {
+        ANGLE_VALIDATION_ERR(context, InvalidOperation(), VertexShaderTypeMismatch);
+        return false;
+    }
     return true;
 }
 
 }  // anonymous namespace
 
 bool ValidTextureTarget(const ValidationContext *context, GLenum target)
 {
     switch (target)
@@ -748,60 +612,32 @@ bool ValidTexLevelDestinationTarget(cons
             return true;
         case GL_TEXTURE_RECTANGLE_ANGLE:
             return context->getExtensions().textureRectangle;
         default:
             return false;
     }
 }
 
-bool ValidFramebufferTarget(GLenum target)
+bool ValidFramebufferTarget(const ValidationContext *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:
             return true;
+
         case GL_READ_FRAMEBUFFER:
-            return true;
         case GL_DRAW_FRAMEBUFFER:
-            return true;
-        default:
-            return false;
-    }
-}
-
-bool ValidBufferTarget(const ValidationContext *context, GLenum target)
-{
-    switch (target)
-    {
-        case GL_ARRAY_BUFFER:
-        case GL_ELEMENT_ARRAY_BUFFER:
-            return true;
-
-        case GL_PIXEL_PACK_BUFFER:
-        case GL_PIXEL_UNPACK_BUFFER:
-            return (context->getExtensions().pixelBufferObject ||
+            return (context->getExtensions().framebufferBlit ||
                     context->getClientMajorVersion() >= 3);
 
-        case GL_COPY_READ_BUFFER:
-        case GL_COPY_WRITE_BUFFER:
-        case GL_TRANSFORM_FEEDBACK_BUFFER:
-        case GL_UNIFORM_BUFFER:
-            return (context->getClientMajorVersion() >= 3);
-
-        case GL_ATOMIC_COUNTER_BUFFER:
-        case GL_SHADER_STORAGE_BUFFER:
-        case GL_DRAW_INDIRECT_BUFFER:
-        case GL_DISPATCH_INDIRECT_BUFFER:
-            return context->getClientVersion() >= Version(3, 1);
-
         default:
             return false;
     }
 }
 
 bool ValidMipLevel(const ValidationContext *context, GLenum target, GLint level)
 {
     const auto &caps    = context->getCaps();
@@ -990,32 +826,33 @@ bool ValidImageDataSize(ValidationContex
                         GLsizei width,
                         GLsizei height,
                         GLsizei depth,
                         GLenum format,
                         GLenum type,
                         const void *pixels,
                         GLsizei imageSize)
 {
-    gl::Buffer *pixelUnpackBuffer = context->getGLState().getTargetBuffer(GL_PIXEL_UNPACK_BUFFER);
+    gl::Buffer *pixelUnpackBuffer =
+        context->getGLState().getTargetBuffer(BufferBinding::PixelUnpack);
     if (pixelUnpackBuffer == nullptr && imageSize < 0)
     {
         // Checks are not required
         return true;
     }
 
     // ...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);
+    auto endByteOrErr = formatInfo.computePackUnpackEndByte(type, size, unpack, targetIs3D);
     if (endByteOrErr.isError())
     {
         context->handleError(endByteOrErr.getError());
         return false;
     }
 
     GLuint endByte = endByteOrErr.getResult();
 
@@ -1059,17 +896,18 @@ bool ValidQueryType(const Context *conte
                   "GL extension enums not equal.");
     static_assert(GL_ANY_SAMPLES_PASSED_CONSERVATIVE == GL_ANY_SAMPLES_PASSED_CONSERVATIVE_EXT,
                   "GL extension enums not equal.");
 
     switch (queryType)
     {
         case GL_ANY_SAMPLES_PASSED:
         case GL_ANY_SAMPLES_PASSED_CONSERVATIVE:
-            return true;
+            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;
         default:
             return false;
@@ -1162,47 +1000,52 @@ Shader *GetValidShader(ValidationContext
         }
     }
 
     return validShader;
 }
 
 bool ValidateAttachmentTarget(gl::Context *context, GLenum attachment)
 {
-    if (attachment >= GL_COLOR_ATTACHMENT0_EXT && attachment <= GL_COLOR_ATTACHMENT15_EXT)
-    {
+    if (attachment >= GL_COLOR_ATTACHMENT1_EXT && attachment <= GL_COLOR_ATTACHMENT15_EXT)
+    {
+        if (context->getClientMajorVersion() < 3 && !context->getExtensions().drawBuffers)
+        {
+            ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidAttachment);
+            return false;
+        }
+
+        // Color attachment 0 is validated below because it is always valid
         const unsigned int colorAttachment = (attachment - GL_COLOR_ATTACHMENT0_EXT);
-
         if (colorAttachment >= context->getCaps().maxColorAttachments)
         {
-            context->handleError(
-                InvalidOperation()
-                << "attachment index cannot be greater or equal to MAX_COLOR_ATTACHMENTS.");
+            ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidAttachment);
             return false;
         }
     }
     else
     {
         switch (attachment)
         {
+            case GL_COLOR_ATTACHMENT0:
             case GL_DEPTH_ATTACHMENT:
             case GL_STENCIL_ATTACHMENT:
                 break;
 
             case GL_DEPTH_STENCIL_ATTACHMENT:
                 if (!context->getExtensions().webglCompatibility &&
                     context->getClientMajorVersion() < 3)
                 {
-                    ANGLE_VALIDATION_ERR(context, InvalidEnum(), EnumNotSupported);
+                    ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidAttachment);
                     return false;
                 }
                 break;
 
             default:
-                ANGLE_VALIDATION_ERR(context, InvalidEnum(), EnumNotSupported);
+                ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidAttachment);
                 return false;
         }
     }
 
     return true;
 }
 
 bool ValidateRenderbufferStorageParametersBase(ValidationContext *context,
@@ -1264,17 +1107,17 @@ bool ValidateRenderbufferStorageParamete
 }
 
 bool ValidateFramebufferRenderbufferParameters(gl::Context *context,
                                                GLenum target,
                                                GLenum attachment,
                                                GLenum renderbuffertarget,
                                                GLuint renderbuffer)
 {
-    if (!ValidFramebufferTarget(target))
+    if (!ValidFramebufferTarget(context, target))
     {
         context->handleError(InvalidEnum());
         return false;
     }
 
     gl::Framebuffer *framebuffer = context->getGLState().getTargetFramebuffer(target);
 
     ASSERT(framebuffer);
@@ -1300,17 +1143,17 @@ bool ValidateFramebufferRenderbufferPara
             ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidRenderbufferTarget);
             return false;
         }
     }
 
     return true;
 }
 
-bool ValidateBlitFramebufferParameters(ValidationContext *context,
+bool ValidateBlitFramebufferParameters(Context *context,
                                        GLint srcX0,
                                        GLint srcY0,
                                        GLint srcX1,
                                        GLint srcY1,
                                        GLint dstX0,
                                        GLint dstY0,
                                        GLint dstX1,
                                        GLint dstY1,
@@ -1494,19 +1337,19 @@ bool ValidateBlitFramebufferParameters(V
 
     GLenum masks[]       = {GL_DEPTH_BUFFER_BIT, GL_STENCIL_BUFFER_BIT};
     GLenum attachments[] = {GL_DEPTH_ATTACHMENT, GL_STENCIL_ATTACHMENT};
     for (size_t i = 0; i < 2; i++)
     {
         if (mask & masks[i])
         {
             const gl::FramebufferAttachment *readBuffer =
-                readFramebuffer->getAttachment(attachments[i]);
+                readFramebuffer->getAttachment(context, attachments[i]);
             const gl::FramebufferAttachment *drawBuffer =
-                drawFramebuffer->getAttachment(attachments[i]);
+                drawFramebuffer->getAttachment(context, attachments[i]);
 
             if (readBuffer && drawBuffer)
             {
                 if (!Format::EquivalentForBlit(readBuffer->getFormat(), drawBuffer->getFormat()))
                 {
                     context->handleError(InvalidOperation());
                     return false;
                 }
@@ -2085,72 +1928,136 @@ bool ValidateGetQueryObjectui64vRobustAN
     if (!ValidateRobustBufferSize(context, bufSize, *length))
     {
         return false;
     }
 
     return true;
 }
 
-bool ValidateProgramUniform(gl::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);
-    return ValidateUniformCommonBase(context, programObject, location, count, &uniform) &&
-           ValidateUniformValue(context, valueType, uniform->type);
-}
-
-bool ValidateProgramUniform1iv(gl::Context *context,
-                               GLuint program,
+bool ValidateUniformCommonBase(ValidationContext *context,
+                               gl::Program *program,
                                GLint location,
                                GLsizei count,
-                               const GLint *value)
+                               const LinkedUniform **uniformOut)
 {
-    // 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);
-    return ValidateUniformCommonBase(context, programObject, location, count, &uniform) &&
-           ValidateUniform1ivValue(context, uniform->type, count, value);
+    // TODO(Jiajia): Add image uniform check in future.
+    if (count < 0)
+    {
+        ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeCount);
+        return false;
+    }
+
+    if (!program)
+    {
+        ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidProgramName);
+        return false;
+    }
+
+    if (!program->isLinked())
+    {
+        ANGLE_VALIDATION_ERR(context, InvalidOperation(), ProgramNotLinked);
+        return false;
+    }
+
+    if (location == -1)
+    {
+        // Silently ignore the uniform command
+        return false;
+    }
+
+    const auto &uniformLocations = program->getUniformLocations();
+    size_t castedLocation        = static_cast<size_t>(location);
+    if (castedLocation >= uniformLocations.size())
+    {
+        context->handleError(InvalidOperation() << "Invalid uniform location");
+        return false;
+    }
+
+    const auto &uniformLocation = uniformLocations[castedLocation];
+    if (uniformLocation.ignored)
+    {
+        // Silently ignore the uniform command
+        return false;
+    }
+
+    if (!uniformLocation.used())
+    {
+        context->handleError(InvalidOperation());
+        return false;
+    }
+
+    const auto &uniform = program->getUniformByIndex(uniformLocation.index);
+
+    // attempting to write an array to a non-array uniform is an INVALID_OPERATION
+    if (!uniform.isArray() && count > 1)
+    {
+        context->handleError(InvalidOperation());
+        return false;
+    }
+
+    *uniformOut = &uniform;
+    return true;
 }
 
-bool ValidateProgramUniformMatrix(gl::Context *context,
-                                  GLenum valueType,
-                                  GLuint program,
-                                  GLint location,
-                                  GLsizei count,
-                                  GLboolean transpose)
+bool ValidateUniform1ivValue(ValidationContext *context,
+                             GLenum uniformType,
+                             GLsizei count,
+                             const GLint *value)
 {
-    // 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);
-    return ValidateUniformCommonBase(context, programObject, location, count, &uniform) &&
-           ValidateUniformMatrixValue(context, valueType, uniform->type);
+    // 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)
+    {
+        return true;
+    }
+
+    if (IsSamplerType(uniformType))
+    {
+        // Check that the values are in range.
+        const GLint max = context->getCaps().maxCombinedTextureImageUnits;
+        for (GLsizei i = 0; i < count; ++i)
+        {
+            if (value[i] < 0 || value[i] >= max)
+            {
+                context->handleError(InvalidValue() << "sampler uniform value out of range");
+                return false;
+            }
+        }
+        return true;
+    }
+
+    context->handleError(InvalidOperation() << "wrong type of value for uniform");
+    return false;
+}
+
+bool ValidateUniformValue(ValidationContext *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)
+{
+    // 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)
 {
     const LinkedUniform *uniform = nullptr;
     gl::Program *programObject   = context->getGLState().getProgram();
     return ValidateUniformCommonBase(context, programObject, location, count, &uniform) &&
            ValidateUniformValue(context, valueType, uniform->type);
@@ -2168,17 +2075,17 @@ bool ValidateUniform1iv(ValidationContex
 }
 
 bool ValidateUniformMatrix(ValidationContext *context,
                            GLenum valueType,
                            GLint location,
                            GLsizei count,
                            GLboolean transpose)
 {
-    if (transpose != GL_FALSE && context->getClientMajorVersion() < 3)
+    if (ConvertToBool(transpose) && context->getClientMajorVersion() < 3)
     {
         context->handleError(InvalidValue());
         return false;
     }
 
     const LinkedUniform *uniform = nullptr;
     gl::Program *programObject   = context->getGLState().getProgram();
     return ValidateUniformCommonBase(context, programObject, location, count, &uniform) &&
@@ -2343,17 +2250,17 @@ bool ValidateCopyTexImageParametersBase(
 
     if (!ValidMipLevel(context, target, level))
     {
         ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidMipLevel);
         return false;
     }
 
     const auto &state    = context->getGLState();
-    auto readFramebuffer = state.getReadFramebuffer();
+    Framebuffer *readFramebuffer = state.getReadFramebuffer();
     if (readFramebuffer->checkStatus(context) != GL_FRAMEBUFFER_COMPLETE)
     {
         context->handleError(InvalidFramebufferOperation());
         return false;
     }
 
     if (readFramebuffer->id() != 0 && readFramebuffer->getSamples(context) != 0)
     {
@@ -2434,17 +2341,18 @@ bool ValidateCopyTexImageParametersBase(
 
     if (texture->getImmutableFormat() && !isSubImage)
     {
         context->handleError(InvalidOperation());
         return false;
     }
 
     const gl::InternalFormat &formatInfo =
-        gl::GetInternalFormatInfo(internalformat, GL_UNSIGNED_BYTE);
+        isSubImage ? *texture->getFormat(target, level).info
+                   : gl::GetInternalFormatInfo(internalformat, GL_UNSIGNED_BYTE);
 
     if (formatInfo.depthBits > 0 || formatInfo.compressed)
     {
         context->handleError(InvalidOperation());
         return false;
     }
 
     if (isSubImage)
@@ -2518,27 +2426,35 @@ bool ValidateDrawBase(ValidationContext 
     if (count < 0)
     {
         ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeCount);
         return false;
     }
 
     const State &state = context->getGLState();
 
-    // Check for mapped buffers
-    if (state.hasMappedBuffer(GL_ARRAY_BUFFER))
-    {
-        context->handleError(InvalidOperation());
-        return false;
+    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))
+        {
+            context->handleError(InvalidOperation());
+            return false;
+        }
     }
 
     // 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();
-    const Extensions &extensions = context->getExtensions();
     if (context->getLimitations().noSeparateStencilRefsAndMasks || extensions.webglCompatibility)
     {
         const FramebufferAttachment *dsAttachment =
             framebuffer->getStencilOrDepthStencilAttachment();
         GLuint stencilBits                = dsAttachment ? dsAttachment->getStencilSize() : 0;
         GLuint minimumRequiredStencilMask = (1 << stencilBits) - 1;
         const DepthStencilState &depthStencilState = state.getDepthStencilState();
 
@@ -2569,16 +2485,27 @@ bool ValidateDrawBase(ValidationContext 
 
     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())
+    {
+        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()))
     {
         context->handleError(InvalidOperation());
         return false;
     }
 
     if (extensions.multiview)
     {
@@ -2726,16 +2653,22 @@ bool ValidateDrawArraysCommon(Validation
 }
 
 bool ValidateDrawArraysInstancedANGLE(Context *context,
                                       GLenum mode,
                                       GLint first,
                                       GLsizei count,
                                       GLsizei primcount)
 {
+    if (!context->getExtensions().instancedArrays)
+    {
+        ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
+        return false;
+    }
+
     if (!ValidateDrawArraysInstancedBase(context, mode, first, count, primcount))
     {
         return false;
     }
 
     return ValidateDrawInstancedANGLE(context);
 }
 
@@ -2786,21 +2719,28 @@ bool ValidateDrawElementsCommon(Validati
 
     const State &state = context->getGLState();
 
     if (!ValidateDrawBase(context, mode, count))
     {
         return false;
     }
 
-    // Check for mapped buffers
-    if (state.hasMappedBuffer(GL_ELEMENT_ARRAY_BUFFER))
-    {
-        context->handleError(InvalidOperation() << "Index buffer is mapped.");
-        return false;
+    // 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 (!context->getExtensions().webglCompatibility)
+    {
+        // Check for mapped buffers
+        // TODO(jmadill): Optimize this check for non - WebGL contexts.
+        if (state.hasMappedBuffer(gl::BufferBinding::ElementArray))
+        {
+            context->handleError(InvalidOperation() << "Index buffer is mapped.");
+            return false;
+        }
     }
 
     const gl::VertexArray *vao     = state.getVertexArray();
     gl::Buffer *elementArrayBuffer = vao->getElementArrayBuffer().get();
 
     GLuint typeBytes = gl::GetTypeInfo(type).bytes;
 
     if (context->getExtensions().webglCompatibility)
@@ -2942,31 +2882,37 @@ bool ValidateDrawElementsInstancedCommon
 
 bool ValidateDrawElementsInstancedANGLE(Context *context,
                                         GLenum mode,
                                         GLsizei count,
                                         GLenum type,
                                         const void *indices,
                                         GLsizei primcount)
 {
+    if (!context->getExtensions().instancedArrays)
+    {
+        ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
+        return false;
+    }
+
     if (!ValidateDrawElementsInstancedBase(context, mode, count, type, indices, primcount))
     {
         return false;
     }
 
     return ValidateDrawInstancedANGLE(context);
 }
 
 bool ValidateFramebufferTextureBase(Context *context,
                                     GLenum target,
                                     GLenum attachment,
                                     GLuint texture,
                                     GLint level)
 {
-    if (!ValidFramebufferTarget(target))
+    if (!ValidFramebufferTarget(context, target))
     {
         ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidFramebufferTarget);
         return false;
     }
 
     if (!ValidateAttachmentTarget(context, attachment))
     {
         return false;
@@ -3205,51 +3151,63 @@ bool ValidateDiscardFramebufferBase(Cont
         }
     }
 
     return true;
 }
 
 bool ValidateInsertEventMarkerEXT(Context *context, GLsizei length, const char *marker)
 {
+    if (!context->getExtensions().debugMarker)
+    {
+        // The debug marker calls should not set error state
+        // However, it seems reasonable to set an error state if the extension is not enabled
+        ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
+        return false;
+    }
+
     // Note that debug marker calls must not set error state
-
     if (length < 0)
     {
         return false;
     }
 
     if (marker == nullptr)
     {
         return false;
     }
 
     return true;
 }
 
 bool ValidatePushGroupMarkerEXT(Context *context, GLsizei length, const char *marker)
 {
+    if (!context->getExtensions().debugMarker)
+    {
+        // The debug marker calls should not set error state
+        // However, it seems reasonable to set an error state if the extension is not enabled
+        ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
+        return false;
+    }
+
     // Note that debug marker calls must not set error state
-
     if (length < 0)
     {
         return false;
     }
 
     if (length > 0 && marker == nullptr)
     {
         return false;
     }
 
     return true;
 }
 
-bool ValidateEGLImageTargetTexture2DOES(Context *context,
-                                        GLenum target,
-                                        egl::Image *image)
+bool ValidateEGLImageTargetTexture2DOES(Context *context, GLenum target, GLeglImageOES image)
 {
     if (!context->getExtensions().eglImage && !context->getExtensions().eglImageExternal)
     {
         context->handleError(InvalidOperation());
         return false;
     }
 
     switch (target)
@@ -3270,45 +3228,47 @@ bool ValidateEGLImageTargetTexture2DOES(
             }
             break;
 
         default:
             ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidTextureTarget);
             return false;
     }
 
+    egl::Image *imageObject = reinterpret_cast<egl::Image *>(image);
+
     ASSERT(context->getCurrentDisplay());
-    if (!context->getCurrentDisplay()->isValidImage(image))
+    if (!context->getCurrentDisplay()->isValidImage(imageObject))
     {
         context->handleError(InvalidValue() << "EGL image is not valid.");
         return false;
     }
 
-    if (image->getSamples() > 0)
+    if (imageObject->getSamples() > 0)
     {
         context->handleError(InvalidOperation()
                              << "cannot create a 2D texture from a multisampled EGL image.");
         return false;
     }
 
     const TextureCaps &textureCaps =
-        context->getTextureCaps().get(image->getFormat().info->sizedInternalFormat);
+        context->getTextureCaps().get(imageObject->getFormat().info->sizedInternalFormat);
     if (!textureCaps.texturable)
     {
         context->handleError(InvalidOperation()
                              << "EGL image internal format is not supported as a texture.");
         return false;
     }
 
     return true;
 }
 
 bool ValidateEGLImageTargetRenderbufferStorageOES(Context *context,
                                                   GLenum target,
-                                                  egl::Image *image)
+                                                  GLeglImageOES image)
 {
     if (!context->getExtensions().eglImage)
     {
         context->handleError(InvalidOperation());
         return false;
     }
 
     switch (target)
@@ -3316,25 +3276,27 @@ bool ValidateEGLImageTargetRenderbufferS
         case GL_RENDERBUFFER:
             break;
 
         default:
             ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidRenderbufferTarget);
             return false;
     }
 
+    egl::Image *imageObject = reinterpret_cast<egl::Image *>(image);
+
     ASSERT(context->getCurrentDisplay());
-    if (!context->getCurrentDisplay()->isValidImage(image))
+    if (!context->getCurrentDisplay()->isValidImage(imageObject))
     {
         context->handleError(InvalidValue() << "EGL image is not valid.");
         return false;
     }
 
     const TextureCaps &textureCaps =
-        context->getTextureCaps().get(image->getFormat().info->sizedInternalFormat);
+        context->getTextureCaps().get(imageObject->getFormat().info->sizedInternalFormat);
     if (!textureCaps.renderable)
     {
         context->handleError(InvalidOperation()
                              << "EGL image internal format is not supported as a renderbuffer.");
         return false;
     }
 
     return true;
@@ -3486,17 +3448,17 @@ bool ValidateDrawBuffersBase(ValidationC
             return false;
         }
     }
 
     return true;
 }
 
 bool ValidateGetBufferPointervBase(Context *context,
-                                   GLenum target,
+                                   BufferBinding target,
                                    GLenum pname,
                                    GLsizei *length,
                                    void **params)
 {
     if (length)
     {
         *length = 0;
     }
@@ -3504,20 +3466,19 @@ bool ValidateGetBufferPointervBase(Conte
     if (context->getClientMajorVersion() < 3 && !context->getExtensions().mapBuffer)
     {
         context->handleError(
             InvalidOperation()
             << "Context does not support OpenGL ES 3.0 or GL_OES_mapbuffer is not enabled.");
         return false;
     }
 
-    if (!ValidBufferTarget(context, target))
-    {
-        context->handleError(InvalidEnum() << "Buffer target not valid: 0x" << std::hex
-                                           << std::uppercase << target);
+    if (!context->isValidBufferBinding(target))
+    {
+        context->handleError(InvalidEnum() << "Buffer target not valid");
         return false;
     }
 
     switch (pname)
     {
         case GL_BUFFER_MAP_POINTER:
             break;
 
@@ -3539,19 +3500,19 @@ bool ValidateGetBufferPointervBase(Conte
     if (length)
     {
         *length = 1;
     }
 
     return true;
 }
 
-bool ValidateUnmapBufferBase(Context *context, GLenum target)
+bool ValidateUnmapBufferBase(Context *context, BufferBinding target)
 {
-    if (!ValidBufferTarget(context, target))
+    if (!context->isValidBufferBinding(target))
     {
         ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidBufferTypes);
         return false;
     }
 
     Buffer *buffer = context->getGLState().getTargetBuffer(target);
 
     if (buffer == nullptr || !buffer->isMapped())
@@ -3559,22 +3520,22 @@ bool ValidateUnmapBufferBase(Context *co
         context->handleError(InvalidOperation() << "Buffer not mapped.");
         return false;
     }
 
     return true;
 }
 
 bool ValidateMapBufferRangeBase(Context *context,
-                                GLenum target,
+                                BufferBinding target,
                                 GLintptr offset,
                                 GLsizeiptr length,
                                 GLbitfield access)
 {
-    if (!ValidBufferTarget(context, target))
+    if (!context->isValidBufferBinding(target))
     {
         ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidBufferTypes);
         return false;
     }
 
     if (offset < 0)
     {
         ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeOffset);
@@ -3655,33 +3616,33 @@ bool ValidateMapBufferRangeBase(Context 
             << "The explicit flushing bit may only be set if the buffer is mapped for writing.");
         return false;
     }
 
     return ValidateMapBufferBase(context, target);
 }
 
 bool ValidateFlushMappedBufferRangeBase(Context *context,
-                                        GLenum target,
+                                        BufferBinding target,
                                         GLintptr offset,
                                         GLsizeiptr length)
 {
     if (offset < 0)
     {
         ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeOffset);
         return false;
     }
 
     if (length < 0)
     {
         ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeLength);
         return false;
     }
 
-    if (!ValidBufferTarget(context, target))
+    if (!context->isValidBufferBinding(target))
     {
         ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidBufferTypes);
         return false;
     }
 
     Buffer *buffer = context->getGLState().getTargetBuffer(target);
 
     if (buffer == nullptr)
@@ -3747,23 +3708,23 @@ bool ValidateRobustBufferSize(Validation
         context->handleError(InvalidOperation() << numParams << " parameters are required but "
                                                 << bufSize << " were provided.");
         return false;
     }
 
     return true;
 }
 
-bool ValidateGetFramebufferAttachmentParameterivBase(ValidationContext *context,
+bool ValidateGetFramebufferAttachmentParameterivBase(Context *context,
                                                      GLenum target,
                                                      GLenum attachment,
                                                      GLenum pname,
                                                      GLsizei *numParams)
 {
-    if (!ValidFramebufferTarget(target))
+    if (!ValidFramebufferTarget(context, target))
     {
         context->handleError(InvalidEnum());
         return false;
     }
 
     int clientVersion = context->getClientMajorVersion();
 
     switch (pname)
@@ -3812,36 +3773,44 @@ bool ValidateGetFramebufferAttachmentPar
             context->handleError(InvalidEnum());
             return false;
     }
 
     // Determine if the attachment is a valid enum
     switch (attachment)
     {
         case GL_BACK:
-        case GL_FRONT:
         case GL_DEPTH:
         case GL_STENCIL:
-        case GL_DEPTH_STENCIL_ATTACHMENT:
             if (clientVersion < 3)
             {
-                context->handleError(InvalidEnum());
+                ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidAttachment);
                 return false;
             }
             break;
 
+        case GL_DEPTH_STENCIL_ATTACHMENT:
+            if (clientVersion < 3 && !context->isWebGL1())
+            {
+                ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidAttachment);
+                return false;
+            }
+            break;
+
+        case GL_COLOR_ATTACHMENT0:
         case GL_DEPTH_ATTACHMENT:
         case GL_STENCIL_ATTACHMENT:
             break;
 
         default:
-            if (attachment < GL_COLOR_ATTACHMENT0_EXT ||
+            if ((clientVersion < 3 && !context->getExtensions().drawBuffers) ||
+                attachment < GL_COLOR_ATTACHMENT0_EXT ||
                 (attachment - GL_COLOR_ATTACHMENT0_EXT) >= context->getCaps().maxColorAttachments)
             {
-                context->handleError(InvalidEnum());
+                ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidAttachment);
                 return false;
             }
             break;
     }
 
     const Framebuffer *framebuffer = context->getGLState().getTargetFramebuffer(target);
     ASSERT(framebuffer);
 
@@ -3875,31 +3844,31 @@ bool ValidateGetFramebufferAttachmentPar
         {
             switch (attachment)
             {
                 case GL_DEPTH_ATTACHMENT:
                 case GL_STENCIL_ATTACHMENT:
                     break;
 
                 case GL_DEPTH_STENCIL_ATTACHMENT:
-                    if (!framebuffer->hasValidDepthStencil())
+                    if (!framebuffer->hasValidDepthStencil() && !context->isWebGL1())
                     {
                         context->handleError(InvalidOperation());
                         return false;
                     }
                     break;
 
                 default:
                     ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidAttachment);
                     return false;
             }
         }
     }
 
-    const FramebufferAttachment *attachmentObject = framebuffer->getAttachment(attachment);
+    const FramebufferAttachment *attachmentObject = framebuffer->getAttachment(context, attachment);
     if (attachmentObject)
     {
         ASSERT(attachmentObject->type() == GL_RENDERBUFFER ||
                attachmentObject->type() == GL_TEXTURE ||
                attachmentObject->type() == GL_FRAMEBUFFER_DEFAULT);
 
         switch (pname)
         {
@@ -3961,32 +3930,32 @@ bool ValidateGetFramebufferAttachmentPar
         {
             case GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE:
                 break;
 
             case GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME:
                 if (clientVersion < 3)
                 {
                     ANGLE_VALIDATION_ERR(context, InvalidEnum(),
-                                         InvalidFramebufferTextureParameter);
+                                         InvalidFramebufferAttachmentParameter);
                     return false;
                 }
                 break;
 
             default:
                 if (clientVersion < 3)
                 {
                     ANGLE_VALIDATION_ERR(context, InvalidEnum(),
-                                         InvalidFramebufferTextureParameter);
+                                         InvalidFramebufferAttachmentParameter);
                     return false;
                 }
                 else
                 {
                     ANGLE_VALIDATION_ERR(context, InvalidOperation(),
-                                         InvalidFramebufferTextureParameter);
+                                         InvalidFramebufferAttachmentParameter);
                     return false;
                 }
         }
     }
 
     if (numParams)
     {
         if (pname == GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_VIEWPORT_OFFSETS_ANGLE)
@@ -4001,17 +3970,17 @@ bool ValidateGetFramebufferAttachmentPar
             // For all other queries we can have only one output parameter.
             *numParams = 1;
         }
     }
 
     return true;
 }
 
-bool ValidateGetFramebufferAttachmentParameterivRobustANGLE(ValidationContext *context,
+bool ValidateGetFramebufferAttachmentParameterivRobustANGLE(Context *context,
                                                             GLenum target,
                                                             GLenum attachment,
                                                             GLenum pname,
                                                             GLsizei bufSize,
                                                             GLsizei *numParams)
 {
     if (!ValidateRobustEntryPoint(context, bufSize))
     {
@@ -4028,17 +3997,17 @@ bool ValidateGetFramebufferAttachmentPar
     {
         return false;
     }
 
     return true;
 }
 
 bool ValidateGetBufferParameterivRobustANGLE(ValidationContext *context,
-                                             GLenum target,
+                                             BufferBinding target,
                                              GLenum pname,
                                              GLsizei bufSize,
                                              GLsizei *length,
                                              GLint *params)
 {
     if (!ValidateRobustEntryPoint(context, bufSize))
     {
         return false;
@@ -4053,17 +4022,17 @@ bool ValidateGetBufferParameterivRobustA
     {
         return false;
     }
 
     return true;
 }
 
 bool ValidateGetBufferParameteri64vRobustANGLE(ValidationContext *context,
-                                               GLenum target,
+                                               BufferBinding target,
                                                GLenum pname,
                                                GLsizei bufSize,
                                                GLsizei *length,
                                                GLint64 *params)
 {
     if (!ValidateRobustEntryPoint(context, bufSize))
     {
         return false;
@@ -4131,16 +4100,18 @@ bool ValidateGetProgramivBase(Validation
             if (context->getClientMajorVersion() < 3)
             {
                 ANGLE_VALIDATION_ERR(context, InvalidEnum(), ES3Required);
                 return false;
             }
             break;
 
         case GL_PROGRAM_SEPARABLE:
+        case GL_COMPUTE_WORK_GROUP_SIZE:
+        case GL_ACTIVE_ATOMIC_COUNTER_BUFFERS:
             if (context->getClientVersion() < Version(3, 1))
             {
                 ANGLE_VALIDATION_ERR(context, InvalidEnum(), ES31Required);
                 return false;
             }
             break;
 
         default:
@@ -4679,39 +4650,40 @@ bool ValidateRobustCompressedTexImageBas
                                           GLsizei imageSize,
                                           GLsizei dataSize)
 {
     if (!ValidateRobustEntryPoint(context, dataSize))
     {
         return false;
     }
 
-    gl::Buffer *pixelUnpackBuffer = context->getGLState().getTargetBuffer(GL_PIXEL_UNPACK_BUFFER);
+    gl::Buffer *pixelUnpackBuffer =
+        context->getGLState().getTargetBuffer(BufferBinding::PixelUnpack);
     if (pixelUnpackBuffer == nullptr)
     {
         if (dataSize < imageSize)
         {
             context->handleError(InvalidOperation() << "dataSize must be at least " << imageSize);
         }
     }
     return true;
 }
 
 bool ValidateGetBufferParameterBase(ValidationContext *context,
-                                    GLenum target,
+                                    BufferBinding target,
                                     GLenum pname,
                                     bool pointerVersion,
                                     GLsizei *numParams)
 {
     if (numParams)
     {
         *numParams = 0;
     }
 
-    if (!ValidBufferTarget(context, target))
+    if (!context->isValidBufferBinding(target))
     {
         ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidBufferTypes);
         return false;
     }
 
     const Buffer *buffer = context->getGLState().getTargetBuffer(target);
     if (!buffer)
     {
@@ -5098,17 +5070,17 @@ bool ValidateReadPixelsBase(Context *con
     }
 
     if (width < 0 || height < 0)
     {
         ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeSize);
         return false;
     }
 
-    auto readFramebuffer = context->getGLState().getReadFramebuffer();
+    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)
@@ -5178,31 +5150,31 @@ bool ValidateReadPixelsBase(Context *con
 
     if (!(currentFormat == format && currentType == type) && !validFormatTypeCombination)
     {
         ANGLE_VALIDATION_ERR(context, InvalidOperation(), MismatchedTypeAndFormat);
         return false;
     }
 
     // Check for pixel pack buffer related API errors
-    gl::Buffer *pixelPackBuffer = context->getGLState().getTargetBuffer(GL_PIXEL_PACK_BUFFER);
+    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;
     }
 
     // ..  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)
@@ -5382,16 +5354,22 @@ bool ValidateTexParameterBase(Context *c
         case GL_TEXTURE_MAG_FILTER:
             if (!ValidateTextureMagFilterValue(context, params))
             {
                 return false;
             }
             break;
 
         case GL_TEXTURE_USAGE_ANGLE:
+            if (!context->getExtensions().textureUsage)
+            {
+                ANGLE_VALIDATION_ERR(context, InvalidEnum(), EnumNotSupported);
+                return false;
+            }
+
             switch (ConvertToGLenum(params[0]))
             {
                 case GL_NONE:
                 case GL_FRAMEBUFFER_ATTACHMENT_ANGLE:
                     break;
 
                 default:
                     ANGLE_VALIDATION_ERR(context, InvalidEnum(), EnumNotSupported);
@@ -5449,17 +5427,17 @@ bool ValidateTexParameterBase(Context *c
 
                 default:
                     ANGLE_VALIDATION_ERR(context, InvalidEnum(), EnumNotSupported);
                     return false;
             }
             break;
 
         case GL_TEXTURE_BASE_LEVEL:
-            if (params[0] < 0)
+            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)
             {
                 context->handleError(InvalidOperation()
                                      << "Base level must be 0 for external textures.");
@@ -5475,17 +5453,17 @@ bool ValidateTexParameterBase(Context *c
             {
                 context->handleError(InvalidOperation()
                                      << "Base level must be 0 for rectangle textures.");
                 return false;
             }
             break;
 
         case GL_TEXTURE_MAX_LEVEL:
-            if (params[0] < 0)
+            if (ConvertToGLint(params[0]) < 0)
             {
                 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidMipLevel);
                 return false;
             }
             break;
 
         case GL_DEPTH_STENCIL_TEXTURE_MODE:
             if (context->getClientVersion() < Version(3, 1))
--- a/gfx/angle/src/libANGLE/validationES.h
+++ b/gfx/angle/src/libANGLE/validationES.h
@@ -5,45 +5,45 @@
 //
 
 // validationES.h: Validation functions for generic OpenGL ES entry point parameters
 
 #ifndef LIBANGLE_VALIDATION_ES_H_
 #define LIBANGLE_VALIDATION_ES_H_
 
 #include "common/mathutil.h"
+#include "libANGLE/PackedGLEnums.h"
 
 #include <GLES2/gl2.h>
 #include <GLES3/gl3.h>
 #include <GLES3/gl31.h>
 
 namespace egl
 {
 class Display;
 class Image;
 }
 
 namespace gl
 {
 class Context;
 struct Format;
+struct LinkedUniform;
 class Program;
 class Shader;
 class ValidationContext;
 
 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(GLenum target);
-bool ValidBufferTarget(const ValidationContext *context, GLenum target);
-bool ValidBufferParameter(const ValidationContext *context, GLenum pname, GLsizei *numParams);
+bool ValidFramebufferTarget(const ValidationContext *context, GLenum target);
 bool ValidMipLevel(const ValidationContext *context, GLenum target, GLint level);
 bool ValidImageSizeParameters(ValidationContext *context,
                               GLenum target,
                               GLint level,
                               GLsizei width,
                               GLsizei height,
                               GLsizei depth,
                               bool isSubImage);
@@ -97,17 +97,17 @@ bool ValidateRenderbufferStorageParamete
                                                GLsizei width,
                                                GLsizei height);
 bool ValidateFramebufferRenderbufferParameters(Context *context,
                                                GLenum target,
                                                GLenum attachment,
                                                GLenum renderbuffertarget,
                                                GLuint renderbuffer);
 
-bool ValidateBlitFramebufferParameters(ValidationContext *context,
+bool ValidateBlitFramebufferParameters(Context *context,
                                        GLint srcX0,
                                        GLint srcY0,
                                        GLint srcX1,
                                        GLint srcY1,
                                        GLint dstX0,
                                        GLint dstY0,
                                        GLint dstX1,
                                        GLint dstY1,
@@ -204,33 +204,27 @@ 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 ValidateProgramUniform(Context *context,
-                            GLenum uniformType,
-                            GLuint program,
-                            GLint location,
-                            GLsizei count);
-bool ValidateProgramUniform1iv(Context *context,
-                               GLuint program,
+bool ValidateUniformCommonBase(ValidationContext *context,
+                               gl::Program *program,
                                GLint location,
                                GLsizei count,
-                               const GLint *value);
-bool ValidateProgramUniformMatrix(Context *context,
-                                  GLenum matrixType,
-                                  GLuint program,
-                                  GLint location,
-                                  GLsizei count,
-                                  GLboolean transpose);
-
+                               const LinkedUniform **uniformOut);
+bool ValidateUniform1ivValue(ValidationContext *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,
                            GLenum matrixType,
                            GLint location,
                            GLsizei count,
                            GLboolean transpose);
 
 bool ValidateStateQuery(ValidationContext *context,
@@ -337,22 +331,20 @@ 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,
-                                        egl::Image *image);
+bool ValidateEGLImageTargetTexture2DOES(Context *context, GLenum target, GLeglImageOES image);
 bool ValidateEGLImageTargetRenderbufferStorageOES(Context *context,
                                                   GLenum target,
-                                                  egl::Image *image);
+                                                  GLeglImageOES image);
 
 bool ValidateBindVertexArrayBase(Context *context, GLuint array);
 
 bool ValidateProgramBinaryBase(Context *context,
                                GLuint program,
                                GLenum binaryFormat,
                                const void *binary,
                                GLint length);
@@ -361,62 +353,62 @@ bool ValidateGetProgramBinaryBase(Contex
                                   GLsizei bufSize,
                                   GLsizei *length,
                                   GLenum *binaryFormat,
                                   void *binary);
 
 bool ValidateDrawBuffersBase(ValidationContext *context, GLsizei n, const GLenum *bufs);
 
 bool ValidateGetBufferPointervBase(Context *context,
-                                   GLenum target,
+                                   BufferBinding target,
                                    GLenum pname,
                                    GLsizei *length,
                                    void **params);
-bool ValidateUnmapBufferBase(Context *context, GLenum target);
+bool ValidateUnmapBufferBase(Context *context, BufferBinding target);
 bool ValidateMapBufferRangeBase(Context *context,
-                                GLenum target,
+                                BufferBinding target,
                                 GLintptr offset,
                                 GLsizeiptr length,
                                 GLbitfield access);
 bool ValidateFlushMappedBufferRangeBase(Context *context,
-                                        GLenum target,
+                                        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 ValidateGetFramebufferAttachmentParameterivBase(ValidationContext *context,
+bool ValidateGetFramebufferAttachmentParameterivBase(Context *context,
                                                      GLenum target,
                                                      GLenum attachment,
                                                      GLenum pname,
                                                      GLsizei *numParams);
-bool ValidateGetFramebufferAttachmentParameterivRobustANGLE(ValidationContext *context,
+bool ValidateGetFramebufferAttachmentParameterivRobustANGLE(Context *context,
                                                             GLenum target,
                                                             GLenum attachment,
                                                             GLenum pname,
                                                             GLsizei bufSize,
                                                             GLsizei *numParams);
 
 bool ValidateGetBufferParameterBase(ValidationContext *context,
-                                    GLenum target,
+                                    BufferBinding target,
                                     GLenum pname,
                                     bool pointerVersion,
                                     GLsizei *numParams);
 bool ValidateGetBufferParameterivRobustANGLE(ValidationContext *context,
-                                             GLenum target,
+                                             BufferBinding target,
                                              GLenum pname,
                                              GLsizei bufSize,
                                              GLsizei *length,
                                              GLint *params);
 
 bool ValidateGetBufferParameteri64vRobustANGLE(ValidationContext *context,
-                                               GLenum target,
+                                               BufferBinding target,
                                                GLenum pname,
                                                GLsizei bufSize,
                                                GLsizei *length,
                                                GLint64 *params);
 
 bool ValidateGetProgramivBase(ValidationContext *context,
                               GLuint program,
                               GLenum pname,
--- a/gfx/angle/src/libANGLE/validationES2.cpp
+++ b/gfx/angle/src/libANGLE/validationES2.cpp
@@ -10,16 +10,17 @@
 
 #include <cstdint>
 
 #include "common/mathutil.h"
 #include "common/string_utils.h"
 #include "common/utilities.h"
 #include "libANGLE/Context.h"
 #include "libANGLE/ErrorStrings.h"
+#include "libANGLE/Fence.h"
 #include "libANGLE/Framebuffer.h"
 #include "libANGLE/FramebufferAttachment.h"
 #include "libANGLE/Renderbuffer.h"
 #include "libANGLE/Shader.h"
 #include "libANGLE/Texture.h"
 #include "libANGLE/Uniform.h"
 #include "libANGLE/VertexArray.h"
 #include "libANGLE/formatutils.h"
@@ -301,40 +302,49 @@ bool IsValidCopyTextureDestinationFormat
     if (!internalFormatInfo.textureSupport(context->getClientVersion(), context->getExtensions()))
     {
         return false;
     }
 
     return true;
 }
 
-bool IsValidCopyTextureDestinationTarget(Context *context, GLenum textureType, GLenum target)
+bool IsValidCopyTextureDestinationTargetEnum(Context *context, GLenum target)
 {
     switch (target)
     {
         case GL_TEXTURE_2D:
-            return textureType == 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:
-            return textureType == GL_TEXTURE_CUBE_MAP;
+            return true;
 
         case GL_TEXTURE_RECTANGLE_ANGLE:
-            return textureType == GL_TEXTURE_RECTANGLE_ANGLE &&
-                   context->getExtensions().textureRectangle;
+            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:
             return true;
         case GL_TEXTURE_RECTANGLE_ANGLE:
             return context->getExtensions().textureRectangle;
@@ -783,17 +793,17 @@ bool ValidCap(const Context *context, GL
             return queryOnly && context->getExtensions().clientArrays;
 
         case GL_FRAMEBUFFER_SRGB_EXT:
             return context->getExtensions().sRGBWriteControl;
 
         case GL_SAMPLE_MASK:
             return context->getClientVersion() >= Version(3, 1);
 
-        case GL_CONTEXT_ROBUST_RESOURCE_INITIALIZATION_ANGLE:
+        case GL_ROBUST_RESOURCE_INITIALIZATION_ANGLE:
             return queryOnly && context->getExtensions().robustResourceInitialization;
 
         default:
             return false;
     }
 }
 
 // Return true if a character belongs to the ASCII subset as defined in GLSL ES 1.0 spec section
@@ -914,18 +924,22 @@ bool IsValidESSLShaderSourceString(const
                 else if (!IsValidESSLCharacter(c))
                 {
                     return false;
                 }
                 pos++;
                 break;
 
             case ParseState::IN_PREPROCESSOR_DIRECTIVE:
-                // No matter what the character is, just pass it
-                // through. Do not parse comments in this state.
+                // Line-continuation characters may not be permitted.
+                // Otherwise, just pass it through. Do not parse comments in this state.
+                if (!lineContinuationAllowed && c == '\\')
+                {
+                    return false;
+                }
                 pos++;
                 break;
 
             case ParseState::IN_SINGLE_LINE_COMMENT:
                 // Line-continuation characters are processed before comment processing.
                 // Advance string if a new line character is immediately behind
                 // line-continuation character.
                 if (c == '\\' && (next == '\n' || next == '\r'))
@@ -983,16 +997,31 @@ bool ValidateWebGLNameLength(ValidationC
         // uniform and attribute locations.
         ANGLE_VALIDATION_ERR(context, InvalidValue(), Webgl2NameLengthLimitExceeded);
         return false;
     }
 
     return true;
 }
 
+bool ValidateMatrixMode(Context *context, GLenum matrixMode)
+{
+    if (!context->getExtensions().pathRendering)
+    {
+        context->handleError(InvalidOperation() << "GL_CHROMIUM_path_rendering is not available.");
+        return false;
+    }
+
+    if (matrixMode != GL_PATH_MODELVIEW_CHROMIUM && matrixMode != GL_PATH_PROJECTION_CHROMIUM)
+    {
+        ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidMatrixMode);
+        return false;
+    }
+    return true;
+}
 }  // anonymous namespace
 
 bool ValidateES2TexImageParameters(Context *context,
                                    GLenum target,
                                    GLint level,
                                    GLenum internalformat,
                                    bool isCompressed,
                                    bool isSubImage,
@@ -1122,16 +1151,23 @@ 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)
+        {
+            ANGLE_VALIDATION_ERR(context, InvalidValue(), PixelDataNull);
+            return false;
+        }
     }
     else
     {
         if (texture->getImmutableFormat())
         {
             context->handleError(InvalidOperation());
             return false;
         }
@@ -1155,17 +1191,17 @@ bool ValidateES2TexImageParameters(Conte
             case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
                 if (!context->getExtensions().textureCompressionDXT1)
                 {
                     ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidInternalFormat);
                     return false;
                 }
                 break;
             case GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE:
-                if (!context->getExtensions().textureCompressionDXT1)
+                if (!context->getExtensions().textureCompressionDXT3)
                 {
                     ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidInternalFormat);
                     return false;
                 }
                 break;
             case GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE:
                 if (!context->getExtensions().textureCompressionDXT5)
                 {
@@ -1184,26 +1220,30 @@ bool ValidateES2TexImageParameters(Conte
                 }
                 break;
             case GL_ETC1_RGB8_OES:
                 if (!context->getExtensions().compressedETC1RGB8Texture)
                 {
                     ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidInternalFormat);
                     return false;
                 }
+                if (isSubImage)
+                {
+                    ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidInternalFormat);
+                    return false;
+                }
                 break;
             case GL_ETC1_RGB8_LOSSY_DECODE_ANGLE:
             case GL_COMPRESSED_RGB8_LOSSY_DECODE_ETC2_ANGLE:
             case GL_COMPRESSED_SRGB8_LOSSY_DECODE_ETC2_ANGLE:
             case GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_LOSSY_DECODE_ETC2_ANGLE:
             case GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_LOSSY_DECODE_ETC2_ANGLE:
                 if (!context->getExtensions().lossyETCDecode)
                 {
-                    context->handleError(InvalidEnum()
-                                         << "ANGLE_lossy_etc_decode extension is not supported");
+                    ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidInternalFormat);
                     return false;
                 }
                 break;
             default:
                 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidInternalFormat);
                 return false;
         }
 
@@ -1276,18 +1316,24 @@ bool ValidateES2TexImageParameters(Conte
                 if (!context->getExtensions().textureRG)
                 {
                     context->handleError(InvalidEnum());
                     return false;
                 }
                 switch (type)
                 {
                     case GL_UNSIGNED_BYTE:
+                        break;
                     case GL_FLOAT:
                     case GL_HALF_FLOAT_OES:
+                        if (!context->getExtensions().textureFloat)
+                        {
+                            context->handleError(InvalidEnum());
+                            return false;
+                        }
                         break;
                     default:
                         ANGLE_VALIDATION_ERR(context, InvalidOperation(), MismatchedTypeAndFormat);
                         return false;
                 }
                 break;
             case GL_RGB:
                 switch (type)
@@ -1312,16 +1358,21 @@ bool ValidateES2TexImageParameters(Conte
                     case GL_HALF_FLOAT_OES:
                         break;
                     default:
                         ANGLE_VALIDATION_ERR(context, InvalidOperation(), MismatchedTypeAndFormat);
                         return false;
                 }
                 break;
             case GL_BGRA_EXT:
+                if (!context->getExtensions().textureFormatBGRA8888)
+                {
+                    context->handleError(InvalidEnum());
+                    return false;
+                }
                 switch (type)
                 {
                     case GL_UNSIGNED_BYTE:
                         break;
                     default:
                         ANGLE_VALIDATION_ERR(context, InvalidOperation(), MismatchedTypeAndFormat);
                         return false;
                 }
@@ -2462,19 +2513,19 @@ bool ValidateBlitFramebufferANGLE(Contex
 
     GLenum masks[]       = {GL_DEPTH_BUFFER_BIT, GL_STENCIL_BUFFER_BIT};
     GLenum attachments[] = {GL_DEPTH_ATTACHMENT, GL_STENCIL_ATTACHMENT};
     for (size_t i = 0; i < 2; i++)
     {
         if (mask & masks[i])
         {
             const FramebufferAttachment *readBuffer =
-                readFramebuffer->getAttachment(attachments[i]);
+                readFramebuffer->getAttachment(context, attachments[i]);
             const FramebufferAttachment *drawBuffer =
-                drawFramebuffer->getAttachment(attachments[i]);
+                drawFramebuffer->getAttachment(context, attachments[i]);
 
             if (readBuffer && drawBuffer)
             {
                 if (IsPartialBlit(context, readBuffer, drawBuffer, srcX0, srcY0, srcX1, srcY1,
                                   dstX0, dstY0, dstX1, dstY1))
                 {
                     // only whole-buffer copies are permitted
                     context->handleError(InvalidOperation() << "Only whole-buffer depth and "
@@ -2493,17 +2544,17 @@ bool ValidateBlitFramebufferANGLE(Contex
     }
 
     return ValidateBlitFramebufferParameters(context, srcX0, srcY0, srcX1, srcY1, dstX0, dstY0,
                                              dstX1, dstY1, mask, filter);
 }
 
 bool ValidateClear(ValidationContext *context, GLbitfield mask)
 {
-    auto fbo = context->getGLState().getDrawFramebuffer();
+    Framebuffer *fbo = context->getGLState().getDrawFramebuffer();
     if (fbo->checkStatus(context) != GL_FRAMEBUFFER_COMPLETE)
     {
         context->handleError(InvalidFramebufferOperation());
         return false;
     }
 
     if ((mask & ~(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT)) != 0)
     {
@@ -2673,18 +2724,17 @@ bool ValidateCompressedTexImage2D(Contex
                                              0, 0, width, height, 1, border, GL_NONE, GL_NONE, -1,
                                              data))
         {
             return false;
         }
     }
 
     const InternalFormat &formatInfo = GetSizedInternalFormatInfo(internalformat);
-    auto blockSizeOrErr =
-        formatInfo.computeCompressedImageSize(gl::Extents(width, height, 1));
+    auto blockSizeOrErr = formatInfo.computeCompressedImageSize(gl::Extents(width, height, 1));
     if (blockSizeOrErr.isError())
     {
         context->handleError(blockSizeOrErr.getError());
         return false;
     }
 
     if (imageSize < 0 || static_cast<GLuint>(imageSize) != blockSizeOrErr.getResult())
     {
@@ -2767,47 +2817,49 @@ bool ValidateCompressedTexSubImage2D(Con
                                              yoffset, 0, width, height, 1, 0, format, GL_NONE, -1,
                                              data))
         {
             return false;
         }
     }
 
     const InternalFormat &formatInfo = GetSizedInternalFormatInfo(format);
-    auto blockSizeOrErr =
-        formatInfo.computeCompressedImageSize(gl::Extents(width, height, 1));
+    auto blockSizeOrErr = formatInfo.computeCompressedImageSize(gl::Extents(width, height, 1));
     if (blockSizeOrErr.isError())
     {
         context->handleError(blockSizeOrErr.getError());
         return false;
     }
 
     if (imageSize < 0 || static_cast<GLuint>(imageSize) != blockSizeOrErr.getResult())
     {
         context->handleError(InvalidValue());
         return false;
     }
 
     return true;
 }
 
-bool ValidateGetBufferPointervOES(Context *context, GLenum target, GLenum pname, void **params)
+bool ValidateGetBufferPointervOES(Context *context,
+                                  BufferBinding target,
+                                  GLenum pname,
+                                  void **params)
 {
     return ValidateGetBufferPointervBase(context, target, pname, nullptr, params);
 }
 
-bool ValidateMapBufferOES(Context *context, GLenum target, GLenum access)
+bool ValidateMapBufferOES(Context *context, BufferBinding target, GLenum access)
 {
     if (!context->getExtensions().mapBuffer)
     {
         context->handleError(InvalidOperation() << "Map buffer extension not available.");
         return false;
     }
 
-    if (!ValidBufferTarget(context, target))
+    if (!context->isValidBufferBinding(target))
     {
         ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidBufferTypes);
         return false;
     }
 
     Buffer *buffer = context->getGLState().getTargetBuffer(target);
 
     if (buffer == nullptr)
@@ -2826,43 +2878,43 @@ bool ValidateMapBufferOES(Context *conte
     {
         context->handleError(InvalidOperation() << "Buffer is already mapped.");
         return false;
     }
 
     return ValidateMapBufferBase(context, target);
 }
 
-bool ValidateUnmapBufferOES(Context *context, GLenum target)
+bool ValidateUnmapBufferOES(Context *context, BufferBinding target)
 {
     if (!context->getExtensions().mapBuffer)
     {
         context->handleError(InvalidOperation() << "Map buffer extension not available.");
         return false;
     }
 
     return ValidateUnmapBufferBase(context, target);
 }
 
 bool ValidateMapBufferRangeEXT(Context *context,
-                               GLenum target,
+                               BufferBinding target,
                                GLintptr offset,
                                GLsizeiptr length,
                                GLbitfield access)
 {
     if (!context->getExtensions().mapBufferRange)
     {
         context->handleError(InvalidOperation() << "Map buffer range extension not available.");
         return false;
     }
 
     return ValidateMapBufferRangeBase(context, target, offset, length, access);
 }
 
-bool ValidateMapBufferBase(Context *context, GLenum target)
+bool ValidateMapBufferBase(Context *context, BufferBinding target)
 {
     Buffer *buffer = context->getGLState().getTargetBuffer(target);
     ASSERT(buffer != nullptr);
 
     // Check if this buffer is currently being used as a transform feedback output buffer
     TransformFeedback *transformFeedback = context->getGLState().getCurrentTransformFeedback();
     if (transformFeedback != nullptr && transformFeedback->isActive())
     {
@@ -2877,17 +2929,17 @@ bool ValidateMapBufferBase(Context *cont
             }
         }
     }
 
     return true;
 }
 
 bool ValidateFlushMappedBufferRangeEXT(Context *context,
-                                       GLenum target,
+                                       BufferBinding target,
                                        GLintptr offset,
                                        GLsizeiptr length)
 {
     if (!context->getExtensions().mapBufferRange)
     {
         context->handleError(InvalidOperation() << "Map buffer range extension not available.");
         return false;
     }
@@ -3032,52 +3084,38 @@ bool ValidateCoverageModulationCHROMIUM(
             return false;
     }
 
     return true;
 }
 
 // CHROMIUM_path_rendering
 
-bool ValidateMatrix(Context *context, GLenum matrixMode, const GLfloat *matrix)
-{
-    if (!context->getExtensions().pathRendering)
-    {
-        context->handleError(InvalidOperation() << "GL_CHROMIUM_path_rendering is not available.");
-        return false;
-    }
-    if (matrixMode != GL_PATH_MODELVIEW_CHROMIUM && matrixMode != GL_PATH_PROJECTION_CHROMIUM)
-    {
-        ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidMatrixMode);
-        return false;
-    }
+bool ValidateMatrixLoadfCHROMIUM(Context *context, GLenum matrixMode, const GLfloat *matrix)
+{
+    if (!ValidateMatrixMode(context, matrixMode))
+    {
+        return false;
+    }
+
     if (matrix == nullptr)
     {
         context->handleError(InvalidOperation() << "Invalid matrix.");
         return false;
     }
+
     return true;
 }
 
-bool ValidateMatrixMode(Context *context, GLenum matrixMode)
-{
-    if (!context->getExtensions().pathRendering)
-    {
-        context->handleError(InvalidOperation() << "GL_CHROMIUM_path_rendering is not available.");
-        return false;
-    }
-    if (matrixMode != GL_PATH_MODELVIEW_CHROMIUM && matrixMode != GL_PATH_PROJECTION_CHROMIUM)
-    {
-        ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidMatrixMode);
-        return false;
-    }
-    return true;
-}
-
-bool ValidateGenPaths(Context *context, GLsizei range)
+bool ValidateMatrixLoadIdentityCHROMIUM(Context *context, GLenum matrixMode)
+{
+    return ValidateMatrixMode(context, matrixMode);
+}
+
+bool ValidateGenPathsCHROMIUM(Context *context, GLsizei range)
 {
     if (!context->getExtensions().pathRendering)
     {
         context->handleError(InvalidOperation() << "GL_CHROMIUM_path_rendering is not available.");
         return false;
     }
 
     // range = 0 is undefined in NV_path_rendering.
@@ -3092,17 +3130,17 @@ bool ValidateGenPaths(Context *context, 
     {
         ANGLE_VALIDATION_ERR(context, InvalidOperation(), IntegerOverflow);
         return false;
     }
 
     return true;
 }
 
-bool ValidateDeletePaths(Context *context, GLuint path, GLsizei range)
+bool ValidateDeletePathsCHROMIUM(Context *context, GLuint path, GLsizei range)
 {
     if (!context->getExtensions().pathRendering)
     {
         context->handleError(InvalidOperation() << "GL_CHROMIUM_path_rendering is not available.");
         return false;
     }
 
     // range = 0 is undefined in NV_path_rendering.
@@ -3119,23 +3157,23 @@ bool ValidateDeletePaths(Context *contex
     if (!angle::IsValueInRangeForNumericType<std::uint32_t>(range) || !checkedRange.IsValid())
     {
         ANGLE_VALIDATION_ERR(context, InvalidOperation(), IntegerOverflow);
         return false;
     }
     return true;
 }
 
-bool ValidatePathCommands(Context *context,
-                          GLuint path,
-                          GLsizei numCommands,
-                          const GLubyte *commands,
-                          GLsizei numCoords,
-                          GLenum coordType,
-                          const void *coords)
+bool ValidatePathCommandsCHROMIUM(Context *context,
+                                  GLuint path,
+                                  GLsizei numCommands,
+                                  const GLubyte *commands,
+                                  GLsizei numCoords,
+                                  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))
     {
@@ -3240,17 +3278,17 @@ bool ValidatePathCommands(Context *conte
     {
         context->handleError(InvalidValue() << "Invalid number of coordinates.");
         return false;
     }
 
     return true;
 }
 
-bool ValidateSetPathParameter(Context *context, GLuint path, GLenum pname, GLfloat value)
+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))
     {
@@ -3304,17 +3342,23 @@ bool ValidateSetPathParameter(Context *c
 
         default:
             context->handleError(InvalidEnum() << "Invalid path parameter.");
             return false;
     }
     return true;
 }
 
-bool ValidateGetPathParameter(Context *context, GLuint path, GLenum pname, GLfloat *value)
+bool ValidatePathParameteriCHROMIUM(Context *context, GLuint path, GLenum pname, GLint value)
+{
+    // TODO(jmadill): Use proper clamping cast.
+    return ValidatePathParameterfCHROMIUM(context, path, pname, static_cast<GLfloat>(value));
+}
+
+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))
@@ -3340,17 +3384,23 @@ bool ValidateGetPathParameter(Context *c
         default:
             context->handleError(InvalidEnum() << "Invalid path parameter.");
             return false;
     }
 
     return true;
 }
 
-bool ValidatePathStencilFunc(Context *context, GLenum func, GLint ref, GLuint mask)
+bool ValidateGetPathParameterivCHROMIUM(Context *context, GLuint path, GLenum pname, GLint *value)
+{
+    return ValidateGetPathParameterfvCHROMIUM(context, path, pname,
+                                              reinterpret_cast<GLfloat *>(value));
+}
+
+bool ValidatePathStencilFuncCHROMIUM(Context *context, GLenum func, GLint ref, GLuint mask)
 {
     if (!context->getExtensions().pathRendering)
     {
         context->handleError(InvalidOperation() << "GL_CHROMIUM_path_rendering is not available.");
         return false;
     }
 
     switch (func)
@@ -3373,17 +3423,17 @@ bool ValidatePathStencilFunc(Context *co
 }
 
 // Note that the spec specifies that for the path drawing commands
 // if the path object is not an existing path object the command
 // does nothing and no error is generated.
 // However if the path object exists but has not been specified any
 // commands then an error is generated.
 
-bool ValidateStencilFillPath(Context *context, GLuint path, GLenum fillMode, GLuint mask)
+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))
     {
@@ -3405,33 +3455,33 @@ bool ValidateStencilFillPath(Context *co
     {
         ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidStencilBitMask);
         return false;
     }
 
     return true;
 }
 
-bool ValidateStencilStrokePath(Context *context, GLuint path, GLint reference, GLuint mask)
+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))
     {
         context->handleError(InvalidOperation() << "No such path or path has no data.");
         return false;
     }
 
     return true;
 }
 
-bool ValidateCoverPath(Context *context, GLuint path, GLenum 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))
     {
@@ -3446,54 +3496,54 @@ bool ValidateCoverPath(Context *context,
             break;
         default:
             ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidCoverMode);
             return false;
     }
     return true;
 }
 
-bool ValidateStencilThenCoverFillPath(Context *context,
-                                      GLuint path,
-                                      GLenum fillMode,
-                                      GLuint mask,
-                                      GLenum coverMode)
-{
-    return ValidateStencilFillPath(context, path, fillMode, mask) &&
-           ValidateCoverPath(context, path, coverMode);
-}
-
-bool ValidateStencilThenCoverStrokePath(Context *context,
-                                        GLuint path,
-                                        GLint reference,
-                                        GLuint mask,
-                                        GLenum coverMode)
-{
-    return ValidateStencilStrokePath(context, path, reference, mask) &&
-           ValidateCoverPath(context, path, coverMode);
-}
-
-bool ValidateIsPath(Context *context)
+bool ValidateStencilThenCoverFillPathCHROMIUM(Context *context,
+                                              GLuint path,
+                                              GLenum fillMode,
+                                              GLuint mask,
+                                              GLenum coverMode)
+{
+    return ValidateStencilFillPathCHROMIUM(context, path, fillMode, mask) &&
+           ValidateCoverPathCHROMIUM(context, path, coverMode);
+}
+
+bool ValidateStencilThenCoverStrokePathCHROMIUM(Context *context,
+                                                GLuint path,
+                                                GLint reference,
+                                                GLuint mask,
+                                                GLenum coverMode)
+{
+    return ValidateStencilStrokePathCHROMIUM(context, path, reference, mask) &&
+           ValidateCoverPathCHROMIUM(context, path, coverMode);
+}
+
+bool ValidateIsPathCHROMIUM(Context *context)
 {
     if (!context->getExtensions().pathRendering)
     {
         context->handleError(InvalidOperation() << "GL_CHROMIUM_path_rendering is not available.");
         return false;
     }
     return true;
 }
 
-bool ValidateCoverFillPathInstanced(Context *context,
-                                    GLsizei numPaths,
-                                    GLenum pathNameType,
-                                    const void *paths,
-                                    GLuint pathBase,
-                                    GLenum coverMode,
-                                    GLenum transformType,
-                                    const GLfloat *transformValues)
+bool ValidateCoverFillPathInstancedCHROMIUM(Context *context,
+                                            GLsizei numPaths,
+                                            GLenum pathNameType,
+                                            const void *paths,
+                                            GLuint pathBase,
+                                            GLenum coverMode,
+                                            GLenum transformType,
+                                            const GLfloat *transformValues)
 {
     if (!ValidateInstancedPathParameters(context, numPaths, pathNameType, paths, pathBase,
                                          transformType, transformValues))
         return false;
 
     switch (coverMode)
     {
         case GL_CONVEX_HULL_CHROMIUM:
@@ -3503,24 +3553,24 @@ bool ValidateCoverFillPathInstanced(Cont
         default:
             ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidCoverMode);
             return false;
     }
 
     return true;
 }
 
-bool ValidateCoverStrokePathInstanced(Context *context,
-                                      GLsizei numPaths,
-                                      GLenum pathNameType,
-                                      const void *paths,
-                                      GLuint pathBase,
-                                      GLenum coverMode,
-                                      GLenum transformType,
-                                      const GLfloat *transformValues)
+bool ValidateCoverStrokePathInstancedCHROMIUM(Context *context,
+                                              GLsizei numPaths,
+                                              GLenum pathNameType,
+                                              const void *paths,
+                                              GLuint pathBase,
+                                              GLenum coverMode,
+                                              GLenum transformType,
+                                              const GLfloat *transformValues)
 {
     if (!ValidateInstancedPathParameters(context, numPaths, pathNameType, paths, pathBase,
                                          transformType, transformValues))
         return false;
 
     switch (coverMode)
     {
         case GL_CONVEX_HULL_CHROMIUM:
@@ -3530,25 +3580,25 @@ bool ValidateCoverStrokePathInstanced(Co
         default:
             ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidCoverMode);
             return false;
     }
 
     return true;
 }
 
-bool ValidateStencilFillPathInstanced(Context *context,
-                                      GLsizei numPaths,
-                                      GLenum pathNameType,
-                                      const void *paths,
-                                      GLuint pathBase,
-                                      GLenum fillMode,
-                                      GLuint mask,
-                                      GLenum transformType,
-                                      const GLfloat *transformValues)
+bool ValidateStencilFillPathInstancedCHROMIUM(Context *context,
+                                              GLsizei numPaths,
+                                              GLenum pathNameType,
+                                              const void *paths,
+                                              GLuint pathBase,
+                                              GLenum fillMode,
+                                              GLuint mask,
+                                              GLenum transformType,
+                                              const GLfloat *transformValues)
 {
 
     if (!ValidateInstancedPathParameters(context, numPaths, pathNameType, paths, pathBase,
                                          transformType, transformValues))
         return false;
 
     switch (fillMode)
     {
@@ -3562,45 +3612,45 @@ bool ValidateStencilFillPathInstanced(Co
     if (!isPow2(mask + 1))
     {
         ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidStencilBitMask);
         return false;
     }
     return true;
 }
 
-bool ValidateStencilStrokePathInstanced(Context *context,
-                                        GLsizei numPaths,
-                                        GLenum pathNameType,
-                                        const void *paths,
-                                        GLuint pathBase,
-                                        GLint reference,
-                                        GLuint mask,
-                                        GLenum transformType,
-                                        const GLfloat *transformValues)
+bool ValidateStencilStrokePathInstancedCHROMIUM(Context *context,
+                                                GLsizei numPaths,
+                                                GLenum pathNameType,
+                                                const void *paths,
+                                                GLuint pathBase,
+                                                GLint reference,
+                                                GLuint mask,
+                                                GLenum transformType,
+                                                const GLfloat *transformValues)
 {
     if (!ValidateInstancedPathParameters(context, numPaths, pathNameType, paths, pathBase,
                                          transformType, transformValues))
         return false;
 
     // no more validation here.
 
     return true;
 }
 
-bool ValidateStencilThenCoverFillPathInstanced(Context *context,
-                                               GLsizei numPaths,
-                                               GLenum pathNameType,
-                                               const void *paths,
-                                               GLuint pathBase,
-                                               GLenum fillMode,
-                                               GLuint mask,
-                                               GLenum coverMode,
-                                               GLenum transformType,
-                                               const GLfloat *transformValues)
+bool ValidateStencilThenCoverFillPathInstancedCHROMIUM(Context *context,
+                                                       GLsizei numPaths,
+                                                       GLenum pathNameType,
+                                                       const void *paths,
+                                                       GLuint pathBase,
+                                                       GLenum fillMode,
+                                                       GLuint mask,
+                                                       GLenum coverMode,
+                                                       GLenum transformType,
+                                                       const GLfloat *transformValues)
 {
     if (!ValidateInstancedPathParameters(context, numPaths, pathNameType, paths, pathBase,
                                          transformType, transformValues))
         return false;
 
     switch (coverMode)
     {
         case GL_CONVEX_HULL_CHROMIUM:
@@ -3625,26 +3675,26 @@ bool ValidateStencilThenCoverFillPathIns
     {
         ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidStencilBitMask);
         return false;
     }
 
     return true;
 }
 
-bool ValidateStencilThenCoverStrokePathInstanced(Context *context,
-                                                 GLsizei numPaths,
-                                                 GLenum pathNameType,
-                                                 const void *paths,
-                                                 GLuint pathBase,
-                                                 GLint reference,
-                                                 GLuint mask,
-                                                 GLenum coverMode,
-                                                 GLenum transformType,
-                                                 const GLfloat *transformValues)
+bool ValidateStencilThenCoverStrokePathInstancedCHROMIUM(Context *context,
+                                                         GLsizei numPaths,
+                                                         GLenum pathNameType,
+                                                         const void *paths,
+                                                         GLuint pathBase,
+                                                         GLint reference,
+                                                         GLuint mask,
+                                                         GLenum coverMode,
+                                                         GLenum transformType,
+                                                         const GLfloat *transformValues)
 {
     if (!ValidateInstancedPathParameters(context, numPaths, pathNameType, paths, pathBase,
                                          transformType, transformValues))
         return false;
 
     switch (coverMode)
     {
         case GL_CONVEX_HULL_CHROMIUM:
@@ -3654,20 +3704,20 @@ bool ValidateStencilThenCoverStrokePathI
         default:
             ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidCoverMode);
             return false;
     }
 
     return true;
 }
 
-bool ValidateBindFragmentInputLocation(Context *context,
-                                       GLuint program,
-                                       GLint location,
-                                       const GLchar *name)
+bool ValidateBindFragmentInputLocationCHROMIUM(Context *context,
+                                               GLuint program,
+                                               GLint location,
+                                               const GLchar *name)
 {
     if (!context->getExtensions().pathRendering)
     {
         context->handleError(InvalidOperation() << "GL_CHROMIUM_path_rendering is not available.");
         return false;
     }
 
     const GLint MaxLocation = context->getCaps().maxVaryingVectors * 4;
@@ -3694,22 +3744,22 @@ bool ValidateBindFragmentInputLocation(C
     {
         ANGLE_VALIDATION_ERR(context, InvalidOperation(), NameBeginsWithGL);
         return false;
     }
 
     return true;
 }
 
-bool ValidateProgramPathFragmentInputGen(Context *context,
-                                         GLuint program,
-                                         GLint location,
-                                         GLenum genMode,
-                                         GLint components,
-                                         const GLfloat *coeffs)
+bool ValidateProgramPathFragmentInputGenCHROMIUM(Context *context,
+                                                 GLuint program,
+                                                 GLint location,
+                                                 GLenum genMode,
+                                                 GLint components,
+                                                 const GLfloat *coeffs)
 {
     if (!context->getExtensions().pathRendering)
     {
         context->handleError(InvalidOperation() << "GL_CHROMIUM_path_rendering is not available.");
         return false;
     }
 
     const auto *programObject = context->getProgram(program);
@@ -3851,16 +3901,22 @@ bool ValidateCopyTextureCHROMIUM(Context
 
     const InternalFormat &sourceFormat = *source->getFormat(sourceTarget, sourceLevel).info;
     if (!IsValidCopyTextureSourceInternalFormatEnum(sourceFormat.internalFormat))
     {
         context->handleError(InvalidOperation() << "Source texture internal format is invalid.");
         return false;
     }
 
+    if (!IsValidCopyTextureDestinationTargetEnum(context, destTarget))
+    {
+        ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidTextureTarget);
+        return false;
+    }
+
     const Texture *dest = context->getTexture(destId);
     if (dest == nullptr)
     {
         context->handleError(InvalidValue()
                              << "Destination texture is not a valid texture object.");
         return false;
     }
 
@@ -3973,16 +4029,22 @@ bool ValidateCopySubTextureCHROMIUM(Cont
 
     const Format &sourceFormat = source->getFormat(sourceTarget, sourceLevel);
     if (!IsValidCopySubTextureSourceInternalFormat(sourceFormat.info->internalFormat))
     {
         ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidInternalFormat);
         return false;
     }
 
+    if (!IsValidCopyTextureDestinationTargetEnum(context, destTarget))
+    {
+        ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidTextureTarget);
+        return false;
+    }
+
     const Texture *dest = context->getTexture(destId);
     if (dest == nullptr)
     {
         context->handleError(InvalidValue()
                              << "Destination texture is not a valid texture object.");
         return false;
     }
 
@@ -4101,62 +4163,69 @@ bool ValidateCreateShader(Context *conte
         case GL_COMPUTE_SHADER:
             if (context->getClientVersion() < Version(3, 1))
             {
                 ANGLE_VALIDATION_ERR(context, InvalidEnum(), ES31Required);
                 return false;
             }
             break;
 
+        case GL_GEOMETRY_SHADER_EXT:
+            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,
-                        GLenum target,
+                        BufferBinding target,
                         GLsizeiptr size,
                         const void *data,
-                        GLenum usage)
+                        BufferUsage usage)
 {
     if (size < 0)
     {
         ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeSize);
         return false;
     }
 
     switch (usage)
     {
-        case GL_STREAM_DRAW:
-        case GL_STATIC_DRAW:
-        case GL_DYNAMIC_DRAW:
+        case BufferUsage::StreamDraw:
+        case BufferUsage::StaticDraw:
+        case BufferUsage::DynamicDraw:
             break;
 
-        case GL_STREAM_READ:
-        case GL_STREAM_COPY:
-        case GL_STATIC_READ:
-        case GL_STATIC_COPY:
-        case GL_DYNAMIC_READ:
-        case GL_DYNAMIC_COPY:
+        case BufferUsage::StreamRead:
+        case BufferUsage::StaticRead:
+        case BufferUsage::DynamicRead:
+        case BufferUsage::StreamCopy:
+        case BufferUsage::StaticCopy:
+        case BufferUsage::DynamicCopy:
             if (context->getClientMajorVersion() < 3)
             {
                 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidBufferUsage);
                 return false;
             }
             break;
 
         default:
             ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidBufferUsage);
             return false;
     }
 
-    if (!ValidBufferTarget(context, target))
+    if (!context->isValidBufferBinding(target))
     {
         ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidBufferTypes);
         return false;
     }
 
     Buffer *buffer = context->getGLState().getTargetBuffer(target);
 
     if (!buffer)
@@ -4164,34 +4233,34 @@ bool ValidateBufferData(ValidationContex
         ANGLE_VALIDATION_ERR(context, InvalidOperation(), BufferNotBound);
         return false;
     }
 
     return true;
 }
 
 bool ValidateBufferSubData(ValidationContext *context,
-                           GLenum target,
+                           BufferBinding target,
                            GLintptr offset,
                            GLsizeiptr size,
                            const void *data)
 {
     if (size < 0)
     {
         ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeSize);
         return false;
     }
 
     if (offset < 0)
     {
         ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeOffset);
         return false;
     }
 
-    if (!ValidBufferTarget(context, target))
+    if (!context->isValidBufferBinding(target))
     {
         ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidBufferTypes);
         return false;
     }
 
     Buffer *buffer = context->getGLState().getTargetBuffer(target);
 
     if (!buffer)
@@ -4219,27 +4288,25 @@ bool ValidateBufferSubData(ValidationCon
     {
         ANGLE_VALIDATION_ERR(context, InvalidValue(), InsufficientBufferSize);
         return false;
     }
 
     return true;
 }
 
-bool ValidateRequestExtensionANGLE(ValidationContext *context, const GLchar *name)
+bool ValidateRequestExtensionANGLE(Context *context, const GLchar *name)
 {
     if (!context->getExtensions().requestExtension)
     {
         context->handleError(InvalidOperation() << "GL_ANGLE_request_extension is not available.");
         return false;
     }
 
-    const ExtensionInfoMap &extensionInfos = GetExtensionInfoMap();
-    auto extension                         = extensionInfos.find(name);
-    if (extension == extensionInfos.end() || !extension->second.Requestable)
+    if (!context->isExtensionRequestable(name))
     {
         context->handleError(InvalidOperation() << "Extension " << name << " is not requestable.");
         return false;
     }
 
     return true;
 }
 
@@ -4293,16 +4360,25 @@ bool ValidateAttachShader(ValidationCont
         {
             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;
     }
 
     return true;
 }
 
@@ -4339,19 +4415,19 @@ bool ValidateBindAttribLocation(Validati
         {
             return false;
         }
     }
 
     return GetValidProgram(context, program) != nullptr;
 }
 
-bool ValidateBindBuffer(ValidationContext *context, GLenum target, GLuint buffer)
-{
-    if (!ValidBufferTarget(context, target))
+bool ValidateBindBuffer(ValidationContext *context, BufferBinding target, GLuint buffer)
+{
+    if (!context->isValidBufferBinding(target))
     {
         ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidBufferTypes);
         return false;
     }
 
     if (!context->getGLState().isBindGeneratesResourceEnabled() &&
         !context->isBufferGenerated(buffer))
     {
@@ -4359,17 +4435,17 @@ bool ValidateBindBuffer(ValidationContex
         return false;
     }
 
     return true;
 }
 
 bool ValidateBindFramebuffer(ValidationContext *context, GLenum target, GLuint framebuffer)
 {
-    if (!ValidFramebufferTarget(target))
+    if (!ValidFramebufferTarget(context, target))
     {
         ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidFramebufferTarget);
         return false;
     }
 
     if (!context->getGLState().isBindGeneratesResourceEnabled() &&
         !context->isFramebufferGenerated(framebuffer))
     {
@@ -4393,26 +4469,28 @@ bool ValidateBindRenderbuffer(Validation
     {
         ANGLE_VALIDATION_ERR(context, InvalidOperation(), ObjectNotGenerated);
         return false;
     }
 
     return true;
 }
 
-static bool ValidBlendEquationMode(GLenum mode)
+static bool ValidBlendEquationMode(const ValidationContext *context, GLenum mode)
 {
     switch (mode)
     {
         case GL_FUNC_ADD:
         case GL_FUNC_SUBTRACT:
         case GL_FUNC_REVERSE_SUBTRACT:
+            return true;
+
         case GL_MIN:
         case GL_MAX:
-            return true;
+            return context->getClientVersion() >= ES_3_0 || context->getExtensions().blendMinMax;
 
         default:
             return false;
     }
 }
 
 bool ValidateBlendColor(ValidationContext *context,
                         GLfloat red,
@@ -4420,34 +4498,34 @@ bool ValidateBlendColor(ValidationContex
                         GLfloat blue,
                         GLfloat alpha)
 {
     return true;
 }
 
 bool ValidateBlendEquation(ValidationContext *context, GLenum mode)
 {
-    if (!ValidBlendEquationMode(mode))
+    if (!ValidBlendEquationMode(context, mode))
     {
         ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidBlendEquation);
         return false;
     }
 
     return true;
 }
 
 bool ValidateBlendEquationSeparate(ValidationContext *context, GLenum modeRGB, GLenum modeAlpha)
 {
-    if (!ValidBlendEquationMode(modeRGB))
+    if (!ValidBlendEquationMode(context, modeRGB))
     {
         ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidBlendEquation);
         return false;
     }
 
-    if (!ValidBlendEquationMode(modeAlpha))
+    if (!ValidBlendEquationMode(context, modeAlpha))
     {
         ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidBlendEquation);
         return false;
     }
 
     return true;
 }
 
@@ -4650,17 +4728,18 @@ bool ValidateVertexAttribPointer(Validat
     }
 
     // [OpenGL ES 3.0.2] Section 2.8 page 24:
     // An INVALID_OPERATION error is generated when a non-zero vertex array object
     // is bound, zero is bound to the ARRAY_BUFFER buffer object binding point,
     // and the pointer argument is not NULL.
     bool nullBufferAllowed = context->getGLState().areClientArraysEnabled() &&
                              context->getGLState().getVertexArray()->id() == 0;
-    if (!nullBufferAllowed && context->getGLState().getArrayBufferId() == 0 && ptr != nullptr)
+    if (!nullBufferAllowed && context->getGLState().getTargetBuffer(BufferBinding::Array) == 0 &&
+        ptr != nullptr)
     {
         context
             ->handleError(InvalidOperation()
                           << "Client data cannot be used with a non-default vertex array object.");
         return false;
     }
 
     if (context->getExtensions().webglCompatibility)
@@ -4741,17 +4820,17 @@ bool ValidateRenderbufferStorageMultisam
     }
 
     return ValidateRenderbufferStorageParametersBase(context, target, samples, internalformat,
                                                      width, height);
 }
 
 bool ValidateCheckFramebufferStatus(ValidationContext *context, GLenum target)
 {
-    if (!ValidFramebufferTarget(target))
+    if (!ValidFramebufferTarget(context, target))
     {
         ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidFramebufferTarget);
         return false;
     }
 
     return true;
 }
 
@@ -4788,23 +4867,23 @@ bool ValidateCompileShader(ValidationCon
     return true;
 }
 
 bool ValidateCreateProgram(ValidationContext *context)
 {
     return true;
 }
 
-bool ValidateCullFace(ValidationContext *context, GLenum mode)
+bool ValidateCullFace(ValidationContext *context, CullFaceMode mode)
 {
     switch (mode)
     {
-        case GL_FRONT:
-        case GL_BACK:
-        case GL_FRONT_AND_BACK:
+        case CullFaceMode::Front:
+        case CullFaceMode::Back:
+        case CullFaceMode::FrontAndBack:
             break;
 
         default:
             ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidCullMode);
             return false;
     }
 
     return true;
@@ -4913,16 +4992,21 @@ bool ValidateDetachShader(ValidationCont
             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;
     }
 
     if (attachedShader != shaderObject)
     {
         ANGLE_VALIDATION_ERR(context, InvalidOperation(), ShaderToDetachMustBeAttached);
@@ -5367,16 +5451,22 @@ bool ValidatePixelStorei(ValidationConte
             if (param != 1 && param != 2 && param != 4 && param != 8)
             {
                 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidUnpackAlignment);
                 return false;
             }
             break;
 
         case GL_PACK_REVERSE_ROW_ORDER_ANGLE:
+            if (!context->getExtensions().packReverseRowOrder)
+            {
+                ANGLE_VALIDATION_ERR(context, InvalidEnum(), EnumNotSupported);
+            }
+            break;
+
         case GL_UNPACK_ROW_LENGTH:
         case GL_UNPACK_IMAGE_HEIGHT:
         case GL_UNPACK_SKIP_IMAGES:
         case GL_UNPACK_SKIP_ROWS:
         case GL_UNPACK_SKIP_PIXELS:
         case GL_PACK_ROW_LENGTH:
         case GL_PACK_SKIP_ROWS:
         case GL_PACK_SKIP_PIXELS:
@@ -5753,17 +5843,17 @@ bool ValidateDrawElements(ValidationCont
                           GLenum mode,
                           GLsizei count,
                           GLenum type,
                           const void *indices)
 {
     return ValidateDrawElementsCommon(context, mode, count, type, indices, 1);
 }
 
-bool ValidateGetFramebufferAttachmentParameteriv(ValidationContext *context,
+bool ValidateGetFramebufferAttachmentParameteriv(Context *context,
                                                  GLenum target,
                                                  GLenum attachment,
                                                  GLenum pname,
                                                  GLint *params)
 {
     return ValidateGetFramebufferAttachmentParameterivBase(context, target, attachment, pname,
                                                            nullptr);
 }
@@ -5869,17 +5959,17 @@ bool ValidateEnable(Context *context, GL
 }
 
 bool ValidateFramebufferRenderbuffer(Context *context,
                                      GLenum target,
                                      GLenum attachment,
                                      GLenum renderbuffertarget,
                                      GLuint renderbuffer)
 {
-    if (!ValidFramebufferTarget(target))
+    if (!ValidFramebufferTarget(context, target))
     {
         ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidFramebufferTarget);
         return false;
     }
 
     if (renderbuffertarget != GL_RENDERBUFFER && renderbuffer != 0)
     {
         ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidRenderbufferTarget);
@@ -6052,47 +6142,50 @@ bool ValidateGenerateMipmap(Context *con
     // 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;
-    const auto &format = texture->getFormat(baseTarget, effectiveBaseLevel);
-    const TextureCaps &formatCaps = context->getTextureCaps().get(format.info->sizedInternalFormat);
-
-    if (format.info->compressed)
+    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;
+    }
+
+    // GenerateMipmap accepts formats that are unsized or both color renderable and filterable.
+    bool formatUnsized = !format.sized;
+    bool formatColorRenderableAndFilterable =
+        format.filterSupport(context->getClientVersion(), context->getExtensions()) &&
+        format.renderSupport(context->getClientVersion(), context->getExtensions());
+    if (!formatUnsized && !formatColorRenderableAndFilterable)
     {
         ANGLE_VALIDATION_ERR(context, InvalidOperation(), GenerateMipmapNotAllowed);
         return false;
     }
 
-    // GenerateMipmap should not generate an INVALID_OPERATION for textures created with
-    // unsized formats or that are color renderable and filterable. Since we do not track if
-    // the texture was created with sized or unsized format (only sized formats are stored),
-    // it is not possible to make sure the the LUMA formats can generate mipmaps (they should
-    // be able to) because they aren't color renderable.  Simply do a special case for LUMA
-    // textures since they're the only texture format that can be created with unsized formats
-    // that is not color renderable.  New unsized formats are unlikely to be added, since ES2
-    // was the last version to use add them.
-    if (format.info->depthBits > 0 || format.info->stencilBits > 0 || !formatCaps.filterable ||
-        (!formatCaps.renderable && !format.info->isLUMA()))
-    {
-        context->handleError(InvalidOperation());
-        return false;
-    }
-
-    // ES3 and WebGL grant mipmap generation for sRGB textures but GL_EXT_sRGB does not.
+    // GL_EXT_sRGB adds an unsized SRGB (no alpha) format which has explicitly disabled mipmap
+    // generation
+    if (format.colorEncoding == GL_SRGB && format.format == GL_RGB)
+    {
+        ANGLE_VALIDATION_ERR(context, InvalidOperation(), GenerateMipmapNotAllowed);
+        return false;
+    }
+
+    // ES3 and WebGL grant mipmap generation for sRGBA (with alpha) textures but GL_EXT_sRGB does
+    // not.
     bool supportsSRGBMipmapGeneration =
         context->getClientVersion() >= ES_3_0 || context->getExtensions().webglCompatibility;
-    if (!supportsSRGBMipmapGeneration && format.info->colorEncoding == GL_SRGB)
-    {
-        context->handleError(InvalidOperation()
-                             << "Mipmap generation of sRGB textures is not allowed.");
+    if (!supportsSRGBMipmapGeneration && format.colorEncoding == GL_SRGB)
+    {
+        ANGLE_VALIDATION_ERR(context, InvalidOperation(), GenerateMipmapNotAllowed);
         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)))))
     {
@@ -6108,17 +6201,17 @@ bool ValidateGenerateMipmap(Context *con
         ANGLE_VALIDATION_ERR(context, InvalidOperation(), CubemapIncomplete);
         return false;
     }
 
     return true;
 }
 
 bool ValidateGetBufferParameteriv(ValidationContext *context,
-                                  GLenum target,
+                                  BufferBinding target,
                                   GLenum pname,
                                   GLint *params)
 {
     return ValidateGetBufferParameterBase(context, target, pname, false, nullptr);
 }
 
 bool ValidateGetRenderbufferParameteriv(Context *context,
                                         GLenum target,
@@ -6264,9 +6357,328 @@ bool ValidateUseProgram(Context *context
             ->handleError(InvalidOperation()
                           << "Cannot change active program while transform feedback is unpaused.");
         return false;
     }
 
     return true;
 }
 
+bool ValidateDeleteFencesNV(Context *context, GLsizei n, const GLuint *fences)
+{
+    if (!context->getExtensions().fence)
+    {
+        ANGLE_VALIDATION_ERR(context, InvalidOperation(), NVFenceNotSupported);
+        return false;
+    }
+
+    if (n < 0)
+    {
+        ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeCount);
+        return false;
+    }
+
+    return true;
+}
+
+bool ValidateFinishFenceNV(Context *context, GLuint fence)
+{
+    if (!context->getExtensions().fence)
+    {
+        ANGLE_VALIDATION_ERR(context, InvalidOperation(), NVFenceNotSupported);
+        return false;
+    }
+
+    FenceNV *fenceObject = context->getFenceNV(fence);
+
+    if (fenceObject == nullptr)
+    {
+        ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFence);
+        return false;
+    }
+
+    if (!fenceObject->isSet())
+    {
+        ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFenceState);
+        return false;
+    }
+
+    return true;
+}
+
+bool ValidateGenFencesNV(Context *context, GLsizei n, GLuint *fences)
+{
+    if (!context->getExtensions().fence)
+    {
+        ANGLE_VALIDATION_ERR(context, InvalidOperation(), NVFenceNotSupported);
+        return false;
+    }
+
+    if (n < 0)
+    {
+        ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeCount);
+        return false;
+    }
+
+    return true;
+}
+
+bool ValidateGetFenceivNV(Context *context, GLuint fence, GLenum pname, GLint *params)
+{
+    if (!context->getExtensions().fence)
+    {
+        ANGLE_VALIDATION_ERR(context, InvalidOperation(), NVFenceNotSupported);
+        return false;
+    }
+
+    FenceNV *fenceObject = context->getFenceNV(fence);
+
+    if (fenceObject == nullptr)
+    {
+        ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFence);
+        return false;
+    }
+
+    if (!fenceObject->isSet())
+    {
+        ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFenceState);
+        return false;
+    }
+
+    switch (pname)
+    {
+        case GL_FENCE_STATUS_NV:
+        case GL_FENCE_CONDITION_NV:
+            break;
+
+        default:
+            ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidPname);
+            return false;
+    }
+
+    return true;
+}
+
+bool ValidateGetGraphicsResetStatusEXT(Context *context)
+{
+    if (!context->getExtensions().robustness)
+    {
+        ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
+        return false;
+    }
+
+    return true;
+}
+
+bool ValidateGetTranslatedShaderSourceANGLE(Context *context,
+                                            GLuint shader,
+                                            GLsizei bufsize,
+                                            GLsizei *length,
+                                            GLchar *source)
+{
+    if (!context->getExtensions().translatedShaderSource)
+    {
+        ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
+        return false;
+    }
+
+    if (bufsize < 0)
+    {
+        context->handleError(InvalidValue());
+        return false;
+    }
+
+    Shader *shaderObject = context->getShader(shader);
+
+    if (!shaderObject)
+    {
+        context->handleError(InvalidOperation());
+        return false;
+    }
+
+    return true;
+}
+
+bool ValidateIsFenceNV(Context *context, GLuint fence)
+{
+    if (!context->getExtensions().fence)
+    {
+        ANGLE_VALIDATION_ERR(context, InvalidOperation(), NVFenceNotSupported);
+        return false;
+    }
+
+    return true;
+}
+
+bool ValidateSetFenceNV(Context *context, GLuint fence, GLenum condition)
+{
+    if (!context->getExtensions().fence)
+    {
+        ANGLE_VALIDATION_ERR(context, InvalidOperation(), NVFenceNotSupported);
+        return false;
+    }
+
+    if (condition != GL_ALL_COMPLETED_NV)
+    {
+        context->handleError(InvalidEnum());
+        return false;
+    }
+
+    FenceNV *fenceObject = context->getFenceNV(fence);
+
+    if (fenceObject == nullptr)
+    {
+        ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFence);
+        return false;
+    }
+
+    return true;
+}
+
+bool ValidateTestFenceNV(Context *context, GLuint fence)
+{
+    if (!context->getExtensions().fence)
+    {
+        ANGLE_VALIDATION_ERR(context, InvalidOperation(), NVFenceNotSupported);
+        return false;
+    }
+
+    FenceNV *fenceObject = context->getFenceNV(fence);
+
+    if (fenceObject == nullptr)
+    {
+        ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFence);
+        return false;
+    }
+
+    if (fenceObject->isSet() != GL_TRUE)
+    {
+        ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFenceState);
+        return false;
+    }
+
+    return true;
+}
+
+bool ValidateTexStorage2DEXT(Context *context,
+                             GLenum target,
+                             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,
+                                               height);
+    }
+
+    ASSERT(context->getClientMajorVersion() >= 3);
+    return ValidateES3TexStorage2DParameters(context, target, levels, internalformat, width, height,
+                                             1);
+}
+
+bool ValidateVertexAttribDivisorANGLE(Context *context, GLuint index, GLuint divisor)
+{
+    if (!context->getExtensions().instancedArrays)
+    {
+        ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
+        return false;
+    }
+
+    if (index >= MAX_VERTEX_ATTRIBS)
+    {
+        context->handleError(InvalidValue());
+        return false;
+    }
+
+    if (context->getLimitations().attributeZeroRequiresZeroDivisorInEXT)
+    {
+        if (index == 0 && divisor != 0)
+        {
+            const char *errorMessage =
+                "The current context doesn't support setting a non-zero divisor on the "
+                "attribute with index zero. "
+                "Please reorder the attributes in your vertex shader so that attribute zero "
+                "can have a zero divisor.";
+            context->handleError(InvalidOperation() << errorMessage);
+
+            // We also output an error message to the debugger window if tracing is active, so
+            // that developers can see the error message.
+            ERR() << errorMessage;
+            return false;
+        }
+    }
+
+    return true;
+}
+
+bool ValidateTexImage3DOES(Context *context,
+                           GLenum target,
+                           GLint level,
+                           GLenum internalformat,
+                           GLsizei width,
+                           GLsizei height,
+                           GLsizei depth,
+                           GLint border,
+                           GLenum format,
+                           GLenum type,
+                           const void *pixels)
+{
+    UNIMPLEMENTED();  // FIXME
+    return false;
+}
+
+bool ValidatePopGroupMarkerEXT(Context *context)
+{
+    if (!context->getExtensions().debugMarker)
+    {
+        // The debug marker calls should not set error state
+        // However, it seems reasonable to set an error state if the extension is not enabled
+        ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
+        return false;
+    }
+
+    return true;
+}
+
+bool ValidateTexStorage1DEXT(Context *context,
+                             GLenum target,
+                             GLsizei levels,
+                             GLenum internalformat,
+                             GLsizei width)
+{
+    UNIMPLEMENTED();
+    ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
+    return false;
+}
+
+bool ValidateTexStorage3DEXT(Context *context,
+                             GLenum target,
+                             GLsizei levels,
+                             GLenum internalformat,
+                             GLsizei width,
+                             GLsizei height,
+                             GLsizei depth)
+{
+    if (!context->getExtensions().textureStorage)
+    {
+        ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
+        return false;
+    }
+
+    if (context->getClientMajorVersion() < 3)
+    {
+        ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
+        return false;
+    }
+
+    return ValidateES3TexStorage3DParameters(context, target, levels, internalformat, width, height,
+                                             depth);
+}
+
 }  // namespace gl
--- a/gfx/angle/src/libANGLE/validationES2.h
+++ b/gfx/angle/src/libANGLE/validationES2.h
@@ -4,16 +4,18 @@
 // found in the LICENSE file.
 //
 
 // validationES2.h: Validation functions for OpenGL ES 2.0 entry point parameters
 
 #ifndef LIBANGLE_VALIDATION_ES2_H_
 #define LIBANGLE_VALIDATION_ES2_H_
 
+#include "libANGLE/PackedGLEnums.h"
+
 #include <GLES2/gl2.h>
 #include <GLES2/gl2ext.h>
 
 namespace gl
 {
 class Context;
 class ValidationContext;
 
@@ -195,130 +197,138 @@ bool ValidateCompressedTexSubImage2DRobu
                                                 GLsizei height,
                                                 GLenum format,
                                                 GLsizei imageSize,
                                                 GLsizei dataSize,
                                                 const void *data);
 
 bool ValidateBindTexture(Context *context, GLenum target, GLuint texture);
 
-bool ValidateGetBufferPointervOES(Context *context, GLenum target, GLenum pname, void **params);
-bool ValidateMapBufferOES(Context *context, GLenum target, GLenum access);
-bool ValidateUnmapBufferOES(Context *context, GLenum target);
+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,
-                               GLenum target,
+                               BufferBinding target,
                                GLintptr offset,
                                GLsizeiptr length,
                                GLbitfield access);
-bool ValidateMapBufferBase(Context *context, GLenum target);
+bool ValidateMapBufferBase(Context *context, BufferBinding target);
 bool ValidateFlushMappedBufferRangeEXT(Context *context,
-                                       GLenum target,
+                                       BufferBinding target,
                                        GLintptr offset,
                                        GLsizeiptr length);
 
 bool ValidateBindUniformLocationCHROMIUM(Context *context,
                                          GLuint program,
                                          GLint location,
                                          const GLchar *name);
 
 bool ValidateCoverageModulationCHROMIUM(Context *context, GLenum components);
 
 // CHROMIUM_path_rendering
-bool ValidateMatrix(Context *context, GLenum matrixMode, const GLfloat *matrix);
-bool ValidateMatrixMode(Context *context, GLenum matrixMode);
-bool ValidateGenPaths(Context *context, GLsizei range);
-bool ValidateDeletePaths(Context *context, GLuint first, GLsizei range);
-bool ValidatePathCommands(Context *context,
-                          GLuint path,
-                          GLsizei numCommands,
-                          const GLubyte *commands,
-                          GLsizei numCoords,
-                          GLenum coordType,
-                          const void *coords);
-bool ValidateSetPathParameter(Context *context, GLuint path, GLenum pname, GLfloat value);
-bool ValidateGetPathParameter(Context *context, GLuint path, GLenum pname, GLfloat *value);
-bool ValidatePathStencilFunc(Context *context, GLenum func, GLint ref, GLuint mask);
-bool ValidateStencilFillPath(Context *context, GLuint path, GLenum fillMode, GLuint mask);
-bool ValidateStencilStrokePath(Context *context, GLuint path, GLint reference, GLuint mask);
-bool ValidateCoverPath(Context *context, GLuint path, GLenum coverMode);
-bool ValidateStencilThenCoverFillPath(Context *context,
-                                      GLuint path,
-                                      GLenum fillMode,
-                                      GLuint mask,
-                                      GLenum coverMode);
-bool ValidateStencilThenCoverStrokePath(Context *context,
+bool ValidateMatrixLoadfCHROMIUM(Context *context, GLenum matrixMode, const GLfloat *matrix);
+bool ValidateMatrixLoadIdentityCHROMIUM(Context *context, GLenum matrixMode);
+bool ValidateGenPathsCHROMIUM(Context *context, GLsizei range);
+bool ValidateDeletePathsCHROMIUM(Context *context, GLuint first, GLsizei range);
+bool ValidatePathCommandsCHROMIUM(Context *context,
+                                  GLuint path,
+                                  GLsizei numCommands,
+                                  const GLubyte *commands,
+                                  GLsizei numCoords,
+                                  GLenum coordType,
+                                  const void *coords);
+bool ValidatePathParameterfCHROMIUM(Context *context, GLuint path, GLenum pname, GLfloat value);
+bool ValidatePathParameteriCHROMIUM(Context *context, GLuint path, GLenum pname, GLint value);
+bool ValidateGetPathParameterfvCHROMIUM(Context *context,
                                         GLuint path,
-                                        GLint reference,
-                                        GLuint mask,
-                                        GLenum coverMode);
-bool ValidateIsPath(Context *context);
-bool ValidateCoverFillPathInstanced(Context *context,
-                                    GLsizei numPaths,
-                                    GLenum pathNameType,
-                                    const void *paths,
-                                    GLuint pathBase,
-                                    GLenum coverMode,
-                                    GLenum transformType,
-                                    const GLfloat *transformValues);
-bool ValidateCoverStrokePathInstanced(Context *context,
-                                      GLsizei numPaths,
-                                      GLenum pathNameType,
-                                      const void *paths,
-                                      GLuint pathBase,
-                                      GLenum coverMode,
-                                      GLenum transformType,
-                                      const GLfloat *transformValues);
-bool ValidateStencilFillPathInstanced(Context *context,
-                                      GLsizei numPaths,
-                                      GLenum pathNameType,
-                                      const void *paths,
-                                      GLuint pathBAse,
-                                      GLenum fillMode,
-                                      GLuint mask,
-                                      GLenum transformType,
-                                      const GLfloat *transformValues);
-bool ValidateStencilStrokePathInstanced(Context *context,
-                                        GLsizei numPaths,
-                                        GLenum pathNameType,
-                                        const void *paths,
-                                        GLuint pathBase,
-                                        GLint reference,
-                                        GLuint mask,
-                                        GLenum transformType,
-                                        const GLfloat *transformValues);
-bool ValidateStencilThenCoverFillPathInstanced(Context *context,
-                                               GLsizei numPaths,
-                                               GLenum pathNameType,
-                                               const void *paths,
-                                               GLuint pathBase,
-                                               GLenum fillMode,
-                                               GLuint mask,
-                                               GLenum coverMode,
-                                               GLenum transformType,
-                                               const GLfloat *transformValues);
-bool ValidateStencilThenCoverStrokePathInstanced(Context *context,
-                                                 GLsizei numPaths,
-                                                 GLenum pathNameType,
-                                                 const void *paths,
-                                                 GLuint pathBase,
-                                                 GLint reference,
-                                                 GLuint mask,
-                                                 GLenum coverMode,
-                                                 GLenum transformType,
-                                                 const GLfloat *transformValues);
-bool ValidateBindFragmentInputLocation(Context *context,
-                                       GLuint program,
-                                       GLint location,
-                                       const GLchar *name);
-bool ValidateProgramPathFragmentInputGen(Context *context,
-                                         GLuint program,
-                                         GLint location,
-                                         GLenum genMode,
-                                         GLint components,
-                                         const GLfloat *coeffs);
+                                        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 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 ValidateCoverFillPathInstancedCHROMIUM(Context *context,
+                                            GLsizei numPaths,
+                                            GLenum pathNameType,
+                                            const void *paths,
+                                            GLuint pathBase,
+                                            GLenum coverMode,
+                                            GLenum transformType,
+                                            const GLfloat *transformValues);
+bool ValidateCoverStrokePathInstancedCHROMIUM(Context *context,
+                                              GLsizei numPaths,
+                                              GLenum pathNameType,
+                                              const void *paths,
+                                              GLuint pathBase,
+                                              GLenum coverMode,
+                                              GLenum transformType,
+                                              const GLfloat *transformValues);
+bool ValidateStencilFillPathInstancedCHROMIUM(Context *context,
+                                              GLsizei numPaths,
+                                              GLenum pathNameType,
+                                              const void *paths,
+                                              GLuint pathBAse,
+                                              GLenum fillMode,
+                                              GLuint mask,
+                                              GLenum transformType,
+                                              const GLfloat *transformValues);
+bool ValidateStencilStrokePathInstancedCHROMIUM(Context *context,
+                                                GLsizei numPaths,
+                                                GLenum pathNameType,
+                                                const void *paths,
+                                                GLuint pathBase,
+                                                GLint reference,
+                                                GLuint mask,
+                                                GLenum transformType,
+                                                const GLfloat *transformValues);
+bool ValidateStencilThenCoverFillPathInstancedCHROMIUM(Context *context,
+                                                       GLsizei numPaths,
+                                                       GLenum pathNameType,
+                                                       const void *paths,
+                                                       GLuint pathBase,
+                                                       GLenum fillMode,
+                                                       GLuint mask,
+                                                       GLenum coverMode,
+                                                       GLenum transformType,
+                                                       const GLfloat *transformValues);
+bool ValidateStencilThenCoverStrokePathInstancedCHROMIUM(Context *context,
+                                                         GLsizei numPaths,
+                                                         GLenum pathNameType,
+                                                         const void *paths,
+                                                         GLuint pathBase,
+                                                         GLint reference,
+                                                         GLuint mask,
+                                                         GLenum coverMode,
+                                                         GLenum transformType,
+                                                         const GLfloat *transformValues);
+bool ValidateBindFragmentInputLocationCHROMIUM(Context *context,
+                                               GLuint program,
+                                               GLint location,
+                                               const GLchar *name);
+bool ValidateProgramPathFragmentInputGenCHROMIUM(Context *context,
+                                                 GLuint program,
+                                                 GLint location,
+                                                 GLenum genMode,
+                                                 GLint components,
+                                                 const GLfloat *coeffs);
 
 bool ValidateCopyTextureCHROMIUM(Context *context,
                                  GLuint sourceId,
                                  GLint sourceLevel,
                                  GLenum destTarget,
                                  GLuint destId,
                                  GLint destLevel,
                                  GLint internalFormat,
@@ -340,35 +350,35 @@ bool ValidateCopySubTextureCHROMIUM(Cont
                                     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,
-                        GLenum target,
+                        BufferBinding target,
                         GLsizeiptr size,
                         const void *data,
-                        GLenum usage);
+                        BufferUsage usage);
 bool ValidateBufferSubData(ValidationContext *context,
-                           GLenum target,
+                           BufferBinding target,
                            GLintptr offset,
                            GLsizeiptr size,
                            const void *data);
 
-bool ValidateRequestExtensionANGLE(ValidationContext *context, const GLchar *name);
+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, GLenum target, GLuint buffer);
+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,
                         GLclampf red,
                         GLclampf green,
                         GLclampf blue,
                         GLclampf alpha);
 bool ValidateBlendEquation(ValidationContext *context, GLenum mode);
@@ -413,17 +423,17 @@ bool ValidateClearDepthf(ValidationConte
 bool ValidateClearStencil(ValidationContext *context, GLint s);
 bool ValidateColorMask(ValidationContext *context,
                        GLboolean red,
                        GLboolean green,
                        GLboolean blue,
                        GLboolean alpha);
 bool ValidateCompileShader(ValidationContext *context, GLuint shader);
 bool ValidateCreateProgram(ValidationContext *context);
-bool ValidateCullFace(ValidationContext *context, GLenum mode);
+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);
@@ -587,17 +597,17 @@ bool ValidateViewport(ValidationContext 
 bool ValidateDrawElements(ValidationContext *context,
                           GLenum mode,
                           GLsizei count,
                           GLenum type,
                           const void *indices);
 
 bool ValidateDrawArrays(ValidationContext *context, GLenum mode, GLint first, GLsizei count);
 
-bool ValidateGetFramebufferAttachmentParameteriv(ValidationContext *context,
+bool ValidateGetFramebufferAttachmentParameteriv(Context *context,
                                                  GLenum target,
                                                  GLenum attachment,
                                                  GLenum pname,
                                                  GLint *params);
 bool ValidateGetProgramiv(ValidationContext *context, GLuint program, GLenum pname, GLint *params);
 
 bool ValidateCopyTexImage2D(ValidationContext *context,
                             GLenum target,
@@ -637,17 +647,17 @@ bool ValidateFramebufferTexture2D(Contex
                                   GLuint texture,
                                   GLint level);
 bool ValidateGenBuffers(Context *context, GLint n, GLuint *buffers);
 bool ValidateGenerateMipmap(Context *context, GLenum 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,
-                                  GLenum target,
+                                  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);
@@ -672,11 +682,57 @@ bool ValidateTexParameterfv(Context *con
 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 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);
+bool ValidateGetTranslatedShaderSourceANGLE(Context *context,
+                                            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,
+                             GLsizei levels,
+                             GLenum internalformat,
+                             GLsizei width,
+                             GLsizei height);
+bool ValidateVertexAttribDivisorANGLE(Context *context, GLuint index, GLuint divisor);
+bool ValidateTexImage3DOES(Context *context,
+                           GLenum target,
+                           GLint level,
+                           GLenum internalformat,
+                           GLsizei width,
+                           GLsizei height,
+                           GLsizei depth,
+                           GLint border,
+                           GLenum format,
+                           GLenum type,
+                           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,
+                             GLsizei levels,
+                             GLenum internalformat,
+                             GLsizei width,
+                             GLsizei height,
+                             GLsizei depth);
+
 }  // namespace gl
 
 #endif  // LIBANGLE_VALIDATION_ES2_H_
--- a/gfx/angle/src/libANGLE/validationES3.cpp
+++ b/gfx/angle/src/libANGLE/validationES3.cpp
@@ -357,16 +357,22 @@ bool ValidateES3TexImageParametersBase(C
             }
 
             if (format != actualInternalFormat)
             {
                 context->handleError(InvalidOperation()
                                      << "Format must match the internal format of the texture.");
                 return false;
             }
+
+            if (actualInternalFormat == GL_ETC1_RGB8_OES)
+            {
+                ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidInternalFormat);
+                return false;
+            }
         }
         else
         {
             if (!ValidCompressedImageSize(context, actualInternalFormat, level, width, height))
             {
                 context->handleError(InvalidOperation() << "Invalid compressed format dimension.");
                 return false;
             }
@@ -417,27 +423,35 @@ bool ValidateES3TexImageParametersBase(C
 
         if (static_cast<size_t>(xoffset + width) > texture->getWidth(target, level) ||
             static_cast<size_t>(yoffset + height) > texture->getHeight(target, level) ||
             static_cast<size_t>(zoffset + depth) > texture->getDepth(target, level))
         {
             context->handleError(InvalidValue());
             return false;
         }
+
+        if (width > 0 && height > 0 && depth > 0 && pixels == nullptr &&
+            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,
                             imageSize))
     {
         return false;
     }
 
     // Check for pixel unpack buffer related API errors
-    gl::Buffer *pixelUnpackBuffer = context->getGLState().getTargetBuffer(GL_PIXEL_UNPACK_BUFFER);
+    gl::Buffer *pixelUnpackBuffer =
+        context->getGLState().getTargetBuffer(BufferBinding::PixelUnpack);
     if (pixelUnpackBuffer != nullptr)
     {
         // ...data is not evenly divisible into the number of bytes needed to store in memory a
         // datum
         // indicated by type.
         if (!isCompressed)
         {
             size_t offset            = reinterpret_cast<size_t>(pixels);
@@ -1098,30 +1112,30 @@ bool ValidateFramebufferTextureLayer(Con
                                      GLint layer)
 {
     if (context->getClientMajorVersion() < 3)
     {
         ANGLE_VALIDATION_ERR(context, InvalidOperation(), ES3Required);
         return false;
     }
 
-    if (layer < 0)
-    {
-        context->handleError(InvalidValue());
-        return false;
-    }
-
     if (!ValidateFramebufferTextureBase(context, target, attachment, texture, level))
     {
         return false;
     }
 
     const gl::Caps &caps = context->getCaps();
     if (texture != 0)
     {
+        if (layer < 0)
+        {
+            context->handleError(InvalidValue());
+            return false;
+        }
+
         gl::Texture *tex = context->getTexture(texture);
         ASSERT(tex);
 
         switch (tex->getTarget())
         {
             case GL_TEXTURE_2D_ARRAY:
             {
                 if (level > gl::log2(caps.max2DTextureSize))
@@ -1367,18 +1381,17 @@ bool ValidateCompressedTexImage3D(Contex
 
     const InternalFormat &formatInfo = GetSizedInternalFormatInfo(internalformat);
     if (!formatInfo.compressed)
     {
         context->handleError(InvalidEnum() << "Not a valid compressed texture format");
         return false;
     }
 
-    auto blockSizeOrErr =
-        formatInfo.computeCompressedImageSize(gl::Extents(width, height, depth));
+    auto blockSizeOrErr = formatInfo.computeCompressedImageSize(gl::Extents(width, height, depth));
     if (blockSizeOrErr.isError())
     {
         context->handleError(InvalidValue());
         return false;
     }
     if (imageSize < 0 || static_cast<GLuint>(imageSize) != blockSizeOrErr.getResult())
     {
         context->handleError(InvalidValue());
@@ -1442,17 +1455,17 @@ bool ValidateIsVertexArray(Context *cont
         ANGLE_VALIDATION_ERR(context, InvalidOperation(), ES3Required);
         return false;
     }
 
     return true;
 }
 
 static bool ValidateBindBufferCommon(Context *context,
-                                     GLenum target,
+                                     BufferBinding target,
                                      GLuint index,
                                      GLuint buffer,
                                      GLintptr offset,
                                      GLsizeiptr size)
 {
     if (context->getClientMajorVersion() < 3)
     {
         ANGLE_VALIDATION_ERR(context, InvalidOperation(), ES3Required);
@@ -1470,17 +1483,17 @@ static bool ValidateBindBufferCommon(Con
     {
         context->handleError(InvalidOperation() << "Buffer was not generated.");
         return false;
     }
 
     const Caps &caps = context->getCaps();
     switch (target)
     {
-        case GL_TRANSFORM_FEEDBACK_BUFFER:
+        case BufferBinding::TransformFeedback:
         {
             if (index >= caps.maxTransformFeedbackSeparateAttributes)
             {
                 context->handleError(InvalidValue() << "index is greater than or equal to the "
                                                        "number of TRANSFORM_FEEDBACK_BUFFER "
                                                        "indexed binding points.");
                 return false;
             }
@@ -1496,17 +1509,17 @@ static bool ValidateBindBufferCommon(Con
             {
                 context->handleError(InvalidOperation()
                                      << "target is TRANSFORM_FEEDBACK_BUFFER and transform "
                                         "feedback is currently active.");
                 return false;
             }
             break;
         }
-        case GL_UNIFORM_BUFFER:
+        case BufferBinding::Uniform:
         {
             if (index >= caps.maxUniformBufferBindings)
             {
                 context->handleError(InvalidValue() << "index is greater than or equal to the "
                                                        "number of UNIFORM_BUFFER indexed "
                                                        "binding points.");
                 return false;
             }
@@ -1515,17 +1528,17 @@ static bool ValidateBindBufferCommon(Con
             {
                 context->handleError(
                     InvalidValue()
                     << "offset must be multiple of value of UNIFORM_BUFFER_OFFSET_ALIGNMENT.");
                 return false;
             }
             break;
         }
-        case GL_ATOMIC_COUNTER_BUFFER:
+        case BufferBinding::AtomicCounter:
         {
             if (context->getClientVersion() < ES_3_1)
             {
                 context->handleError(InvalidEnum()
                                      << "ATOMIC_COUNTER_BUFFER is not supported before GLES 3.1");
                 return false;
             }
             if (index >= caps.maxAtomicCounterBufferBindings)
@@ -1537,17 +1550,17 @@ static bool ValidateBindBufferCommon(Con
             }
             if (buffer != 0 && (offset % 4) != 0)
             {
                 context->handleError(InvalidValue() << "offset must be a multiple of 4.");
                 return false;
             }
             break;
         }
-        case GL_SHADER_STORAGE_BUFFER:
+        case BufferBinding::ShaderStorage:
         {
             if (context->getClientVersion() < ES_3_1)
             {
                 context->handleError(InvalidEnum()
                                      << "SHADER_STORAGE_BUFFER is not supported in GLES3.");
                 return false;
             }
             if (index >= caps.maxShaderStorageBufferBindings)
@@ -1569,23 +1582,23 @@ static bool ValidateBindBufferCommon(Con
         default:
             context->handleError(InvalidEnum() << "the target is not supported.");
             return false;
     }
 
     return true;
 }
 
-bool ValidateBindBufferBase(Context *context, GLenum target, GLuint index, GLuint buffer)
+bool ValidateBindBufferBase(Context *context, BufferBinding target, GLuint index, GLuint buffer)
 {
     return ValidateBindBufferCommon(context, target, index, buffer, 0, 0);
 }
 
 bool ValidateBindBufferRange(Context *context,
-                             GLenum target,
+                             BufferBinding target,
                              GLuint index,
                              GLuint buffer,
                              GLintptr offset,
                              GLsizeiptr size)
 {
     if (buffer != 0 && size <= 0)
     {
         context->handleError(InvalidValue()
@@ -1996,18 +2009,17 @@ bool ValidateCompressedTexSubImage3D(Con
 
     const InternalFormat &formatInfo = GetSizedInternalFormatInfo(format);
     if (!formatInfo.compressed)
     {
         context->handleError(InvalidEnum() << "Not a valid compressed texture format");
         return false;
     }
 
-    auto blockSizeOrErr =
-        formatInfo.computeCompressedImageSize(gl::Extents(width, height, depth));
+    auto blockSizeOrErr = formatInfo.computeCompressedImageSize(gl::Extents(width, height, depth));
     if (blockSizeOrErr.isError())
     {
         context->handleError(blockSizeOrErr.getError());
         return false;
     }
     if (imageSize < 0 || static_cast<GLuint>(imageSize) != blockSizeOrErr.getResult())
     {
         context->handleError(InvalidValue());
@@ -2015,18 +2027,19 @@ bool ValidateCompressedTexSubImage3D(Con
     }
 
     if (!data)
     {
         context->handleError(InvalidValue());
         return false;
     }
 
-    return ValidateES3TexImage3DParameters(context, target, level, GL_NONE, true, true, 0, 0, 0,
-                                           width, height, depth, 0, format, GL_NONE, -1, data);
+    return ValidateES3TexImage3DParameters(context, target, level, GL_NONE, true, true, xoffset,
+                                           yoffset, zoffset, width, height, depth, 0, format,
+                                           GL_NONE, -1, data);
 }
 bool ValidateCompressedTexSubImage3DRobustANGLE(Context *context,
                                                 GLenum target,
                                                 GLint level,
                                                 GLint xoffset,
                                                 GLint yoffset,
                                                 GLint zoffset,
                                                 GLsizei width,
@@ -2134,26 +2147,40 @@ bool ValidateBeginTransformFeedback(Cont
         const auto &buffer = transformFeedback->getIndexedBuffer(i);
         if (buffer.get() && buffer->isMapped())
         {
             context->handleError(InvalidOperation() << "Transform feedback has a mapped buffer.");
             return false;
         }
     }
 
+    Program *program = context->getGLState().getProgram();
+
+    if (!program)
+    {
+        ANGLE_VALIDATION_ERR(context, InvalidOperation(), ProgramNotBound);
+        return false;
+    }
+
+    if (program->getTransformFeedbackVaryingCount() == 0)
+    {
+        ANGLE_VALIDATION_ERR(context, InvalidOperation(), NoTransformFeedbackOutputVariables);
+        return false;
+    }
+
     return true;
 }
 
-bool ValidateGetBufferPointerv(Context *context, GLenum target, GLenum pname, void **params)
+bool ValidateGetBufferPointerv(Context *context, BufferBinding target, GLenum pname, void **params)
 {
     return ValidateGetBufferPointervBase(context, target, pname, nullptr, params);
 }
 
 bool ValidateGetBufferPointervRobustANGLE(Context *context,
-                                          GLenum target,
+                                          BufferBinding target,
                                           GLenum pname,
                                           GLsizei bufSize,
                                           GLsizei *length,
                                           void **params)
 {
     if (!ValidateRobustEntryPoint(context, bufSize))
     {
         return false;
@@ -2167,44 +2194,44 @@ bool ValidateGetBufferPointervRobustANGL
     if (!ValidateRobustBufferSize(context, bufSize, *length))
     {
         return false;
     }
 
     return true;
 }
 
-bool ValidateUnmapBuffer(Context *context, GLenum target)
+bool ValidateUnmapBuffer(Context *context, BufferBinding target)
 {
     if (context->getClientMajorVersion() < 3)
     {
         ANGLE_VALIDATION_ERR(context, InvalidOperation(), ES3Required);
         return false;
     }
 
     return ValidateUnmapBufferBase(context, target);
 }
 
 bool ValidateMapBufferRange(Context *context,
-                            GLenum target,
+                            BufferBinding target,
                             GLintptr offset,
                             GLsizeiptr length,
                             GLbitfield access)
 {
     if (context->getClientMajorVersion() < 3)
     {
         ANGLE_VALIDATION_ERR(context, InvalidOperation(), ES3Required);
         return false;
     }
 
     return ValidateMapBufferRangeBase(context, target, offset, length, access);
 }
 
 bool ValidateFlushMappedBufferRange(Context *context,
-                                    GLenum target,
+                                    BufferBinding target,
                                     GLintptr offset,
                                     GLsizeiptr length)
 {
     if (context->getClientMajorVersion() < 3)
     {
         ANGLE_VALIDATION_ERR(context, InvalidOperation(), ES3Required);
         return false;
     }
@@ -2326,16 +2353,33 @@ bool ValidateIndexedStateQuery(Validatio
                 return false;
             }
             if (index >= caps.maxSampleMaskWords)
             {
                 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidSampleMaskNumber);
                 return false;
             }
             break;
+        case GL_IMAGE_BINDING_NAME:
+        case GL_IMAGE_BINDING_LEVEL:
+        case GL_IMAGE_BINDING_LAYERED:
+        case GL_IMAGE_BINDING_LAYER:
+        case GL_IMAGE_BINDING_ACCESS:
+        case GL_IMAGE_BINDING_FORMAT:
+            if (context->getClientVersion() < ES_3_1)
+            {
+                ANGLE_VALIDATION_ERR(context, InvalidEnum(), EnumRequiresGLES31);
+                return false;
+            }
+            if (index >= caps.maxImageUnits)
+            {
+                ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidImageUnit);
+                return false;
+            }
+            break;
         default:
             context->handleError(InvalidEnum());
             return false;
     }
 
     if (length)
     {
         *length = 1;
@@ -2422,29 +2466,29 @@ bool ValidateGetInteger64i_vRobustANGLE(
     {
         return false;
     }
 
     return true;
 }
 
 bool ValidateCopyBufferSubData(ValidationContext *context,
-                               GLenum readTarget,
-                               GLenum writeTarget,
+                               BufferBinding readTarget,
+                               BufferBinding writeTarget,
                                GLintptr readOffset,
                                GLintptr writeOffset,
                                GLsizeiptr size)
 {
     if (context->getClientMajorVersion() < 3)
     {
         ANGLE_VALIDATION_ERR(context, InvalidOperation(), ES3Required);
         return false;
     }
 
-    if (!ValidBufferTarget(context, readTarget) || !ValidBufferTarget(context, writeTarget))
+    if (!context->isValidBufferBinding(readTarget) || !context->isValidBufferBinding(writeTarget))
     {
         context->handleError(InvalidEnum() << "Invalid buffer target");
         return false;
     }
 
     Buffer *readBuffer  = context->getGLState().getTargetBuffer(readTarget);
     Buffer *writeBuffer = context->getGLState().getTargetBuffer(writeTarget);
 
@@ -2642,17 +2686,17 @@ bool ValidateVertexAttribIPointer(Valida
         }
     }
 
     // [OpenGL ES 3.0.2] Section 2.8 page 24:
     // An INVALID_OPERATION error is generated when a non-zero vertex array object
     // is bound, zero is bound to the ARRAY_BUFFER buffer object binding point,
     // and the pointer argument is not NULL.
     if (context->getGLState().getVertexArrayId() != 0 &&
-        context->getGLState().getArrayBufferId() == 0 && pointer != nullptr)
+        context->getGLState().getTargetBuffer(BufferBinding::Array) == 0 && pointer != nullptr)
     {
         context
             ->handleError(InvalidOperation()
                           << "Client data cannot be used with a non-default vertex array object.");
         return false;
     }
 
     if (context->getExtensions().webglCompatibility)
@@ -3606,17 +3650,17 @@ bool ValidateTexStorage3D(Context *conte
     {
         return false;
     }
 
     return true;
 }
 
 bool ValidateGetBufferParameteri64v(ValidationContext *context,
-                                    GLenum target,
+                                    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/src/libANGLE/validationES3.h
+++ b/gfx/angle/src/libANGLE/validationES3.h
@@ -4,16 +4,18 @@
 // found in the LICENSE file.
 //
 
 // validationES3.h: Validation functions for OpenGL ES 3.0 entry point parameters
 
 #ifndef LIBANGLE_VALIDATION_ES3_H_
 #define LIBANGLE_VALIDATION_ES3_H_
 
+#include "libANGLE/PackedGLEnums.h"
+
 #include <GLES3/gl3.h>
 
 namespace gl
 {
 class Context;
 struct IndexRange;
 class ValidationContext;
 
@@ -208,19 +210,19 @@ bool ValidateCompressedTexImage3DRobustA
                                              GLint border,
                                              GLsizei imageSize,
                                              GLsizei dataSize,
                                              const void *data);
 
 bool ValidateBindVertexArray(Context *context, GLuint array);
 bool ValidateIsVertexArray(Context *context, GLuint array);
 
-bool ValidateBindBufferBase(Context *context, GLenum target, GLuint index, GLuint buffer);
+bool ValidateBindBufferBase(Context *context, BufferBinding target, GLuint index, GLuint buffer);
 bool ValidateBindBufferRange(Context *context,
-                             GLenum target,
+                             BufferBinding target,
                              GLuint index,
                              GLuint buffer,
                              GLintptr offset,
                              GLsizeiptr size);
 
 bool ValidateProgramBinary(Context *context,
                            GLuint program,
                            GLenum binaryFormat,
@@ -352,31 +354,31 @@ bool ValidateGenSamplers(Context *contex
 bool ValidateDeleteSamplers(Context *context, GLint count, const GLuint *samplers);
 bool ValidateGenTransformFeedbacks(Context *context, GLint n, GLuint *ids);
 bool ValidateDeleteTransformFeedbacks(Context *context, GLint n, const GLuint *ids);
 bool ValidateGenVertexArrays(Context *context, GLint n, GLuint *arrays);
 bool ValidateDeleteVertexArrays(Context *context, GLint n, const GLuint *arrays);
 
 bool ValidateBeginTransformFeedback(Context *context, GLenum primitiveMode);
 
-bool ValidateGetBufferPointerv(Context *context, GLenum target, GLenum pname, void **params);
+bool ValidateGetBufferPointerv(Context *context, BufferBinding target, GLenum pname, void **params);
 bool ValidateGetBufferPointervRobustANGLE(Context *context,
-                                          GLenum target,
+                                          BufferBinding target,
                                           GLenum pname,
                                           GLsizei bufSize,
                                           GLsizei *length,
                                           void **params);
-bool ValidateUnmapBuffer(Context *context, GLenum target);
+bool ValidateUnmapBuffer(Context *context, BufferBinding target);
 bool ValidateMapBufferRange(Context *context,
-                            GLenum target,
+                            BufferBinding target,
                             GLintptr offset,
                             GLsizeiptr length,
                             GLbitfield access);
 bool ValidateFlushMappedBufferRange(Context *context,
-                                    GLenum target,
+                                    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);
@@ -393,18 +395,18 @@ bool ValidateGetInteger64i_v(ValidationC
 bool ValidateGetInteger64i_vRobustANGLE(ValidationContext *context,
                                         GLenum target,
                                         GLuint index,
                                         GLsizei bufSize,
                                         GLsizei *length,
                                         GLint64 *data);
 
 bool ValidateCopyBufferSubData(ValidationContext *context,
-                               GLenum readTarget,
-                               GLenum writeTarget,
+                               BufferBinding readTarget,
+                               BufferBinding writeTarget,
                                GLintptr readOffset,
                                GLintptr writeOffset,
                                GLsizeiptr size);
 
 bool ValidateGetStringi(Context *context, GLenum name, GLuint index);
 bool ValidateRenderbufferStorageMultisample(ValidationContext *context,
                                             GLenum target,
                                             GLsizei samples,
@@ -580,17 +582,17 @@ bool ValidateTexStorage3D(Context *conte
                           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,
-                                    GLenum target,
+                                    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);
 bool ValidateSamplerParameterf(Context *context, GLuint sampler, GLenum pname, GLfloat param);
--- a/gfx/angle/src/libANGLE/validationES31.cpp
+++ b/gfx/angle/src/libANGLE/validationES31.cpp
@@ -252,32 +252,112 @@ bool ValidateProgramResourceIndex(const 
     switch (programInterface)
     {
         case GL_PROGRAM_INPUT:
             return (index < static_cast<GLuint>(programObject->getActiveAttributeCount()));
 
         case GL_PROGRAM_OUTPUT:
             return (index < static_cast<GLuint>(programObject->getOutputResourceCount()));
 
-        // TODO(jie.a.chen@intel.com): more interfaces.
         case GL_UNIFORM:
-        case GL_UNIFORM_BLOCK:
-        case GL_TRANSFORM_FEEDBACK_VARYING:
+            return (index < static_cast<GLuint>(programObject->getActiveUniformCount()));
+
         case GL_BUFFER_VARIABLE:
+            return (index < static_cast<GLuint>(programObject->getActiveBufferVariableCount()));
+
         case GL_SHADER_STORAGE_BLOCK:
+            return (index < static_cast<GLuint>(programObject->getActiveShaderStorageBlockCount()));
+
+        case GL_UNIFORM_BLOCK:
+            return (index < programObject->getActiveUniformBlockCount());
+
         case GL_ATOMIC_COUNTER_BUFFER:
-            UNIMPLEMENTED();
-            return false;
+            return (index < programObject->getActiveAtomicCounterBufferCount());
+
+        case GL_TRANSFORM_FEEDBACK_VARYING:
+            return (index < static_cast<GLuint>(programObject->getTransformFeedbackVaryingCount()));
 
         default:
             UNREACHABLE();
             return false;
     }
 }
 
+bool ValidateProgramUniform(gl::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);
+    return ValidateUniformCommonBase(context, programObject, location, count, &uniform) &&
+           ValidateUniformValue(context, valueType, uniform->type);
+}
+
+bool ValidateProgramUniformMatrix(gl::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);
+    return ValidateUniformCommonBase(context, programObject, location, count, &uniform) &&
+           ValidateUniformMatrixValue(context, valueType, uniform->type);
+}
+
+bool ValidateVertexAttribFormatCommon(ValidationContext *context,
+                                      GLuint attribIndex,
+                                      GLint size,
+                                      GLenum type,
+                                      GLuint relativeOffset,
+                                      GLboolean pureInteger)
+{
+    if (context->getClientVersion() < ES_3_1)
+    {
+        ANGLE_VALIDATION_ERR(context, InvalidOperation(), ES31Required);
+        return false;
+    }
+
+    const Caps &caps = context->getCaps();
+    if (relativeOffset > static_cast<GLuint>(caps.maxVertexAttribRelativeOffset))
+    {
+        context->handleError(
+            InvalidValue()
+            << "relativeOffset cannot be greater than MAX_VERTEX_ATTRIB_RELATIVE_OFFSET.");
+        return false;
+    }
+
+    // [OpenGL ES 3.1] Section 10.3.1 page 243:
+    // An INVALID_OPERATION error is generated if the default vertex array object is bound.
+    if (context->getGLState().getVertexArrayId() == 0)
+    {
+        context->handleError(InvalidOperation() << "Default vertex array object is bound.");
+        return false;
+    }
+
+    return ValidateVertexFormatBase(context, attribIndex, size, type, pureInteger);
+}
+
 }  // anonymous namespace
 
 bool ValidateGetBooleani_v(Context *context, GLenum target, GLuint index, GLboolean *data)
 {
     if (context->getClientVersion() < ES_3_1)
     {
         ANGLE_VALIDATION_ERR(context, InvalidOperation(), ES31Required);
         return false;
@@ -341,17 +421,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.getDrawIndirectBuffer();
+    gl::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.
@@ -390,17 +470,17 @@ bool ValidateDrawArraysIndirect(Context 
         // 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.getDrawIndirectBuffer();
+    gl::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(
@@ -424,33 +504,360 @@ bool ValidateDrawElementsIndirect(Contex
     {
         context->handleError(InvalidOperation() << "zero is bound to ELEMENT_ARRAY_BUFFER");
         return false;
     }
 
     if (!ValidateDrawIndirectBase(context, mode, indirect))
         return false;
 
-    gl::Buffer *drawIndirectBuffer = state.getDrawIndirectBuffer();
+    gl::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(
             InvalidOperation()
             << "the  command  would source data beyond the end of the buffer object.");
         return false;
     }
 
     return true;
 }
 
+bool ValidateProgramUniform1i(Context *context, GLuint program, GLint location, GLint v0)
+{
+    return ValidateProgramUniform1iv(context, program, location, 1, &v0);
+}
+
+bool ValidateProgramUniform2i(Context *context, GLuint program, GLint location, GLint v0, GLint v1)
+{
+    GLint xy[2] = {v0, v1};
+    return ValidateProgramUniform2iv(context, program, location, 1, xy);
+}
+
+bool ValidateProgramUniform3i(Context *context,
+                              GLuint program,
+                              GLint location,
+                              GLint v0,
+                              GLint v1,
+                              GLint v2)
+{
+    GLint xyz[3] = {v0, v1, v2};
+    return ValidateProgramUniform3iv(context, program, location, 1, xyz);
+}
+
+bool ValidateProgramUniform4i(Context *context,
+                              GLuint program,
+                              GLint location,
+                              GLint v0,
+                              GLint v1,
+                              GLint v2,
+                              GLint v3)
+{
+    GLint xyzw[4] = {v0, v1, v2, v3};
+    return ValidateProgramUniform4iv(context, program, location, 1, xyzw);
+}
+
+bool ValidateProgramUniform1ui(Context *context, GLuint program, GLint location, GLuint v0)
+{
+    return ValidateProgramUniform1uiv(context, program, location, 1, &v0);
+}
+
+bool ValidateProgramUniform2ui(Context *context,
+                               GLuint program,
+                               GLint location,
+                               GLuint v0,
+                               GLuint v1)
+{
+    GLuint xy[2] = {v0, v1};
+    return ValidateProgramUniform2uiv(context, program, location, 1, xy);
+}
+
+bool ValidateProgramUniform3ui(Context *context,
+                               GLuint program,
+                               GLint location,
+                               GLuint v0,
+                               GLuint v1,
+                               GLuint v2)
+{
+    GLuint xyz[3] = {v0, v1, v2};
+    return ValidateProgramUniform3uiv(context, program, location, 1, xyz);
+}
+
+bool ValidateProgramUniform4ui(Context *context,
+                               GLuint program,
+                               GLint location,
+                               GLuint v0,
+                               GLuint v1,
+                               GLuint v2,
+                               GLuint v3)
+{
+    GLuint xyzw[4] = {v0, v1, v2, v3};
+    return ValidateProgramUniform4uiv(context, program, location, 1, xyzw);
+}
+
+bool ValidateProgramUniform1f(Context *context, GLuint program, GLint location, GLfloat v0)
+{
+    return ValidateProgramUniform1fv(context, program, location, 1, &v0);
+}
+
+bool ValidateProgramUniform2f(Context *context,
+                              GLuint program,
+                              GLint location,
+                              GLfloat v0,
+                              GLfloat v1)
+{
+    GLfloat xy[2] = {v0, v1};
+    return ValidateProgramUniform2fv(context, program, location, 1, xy);
+}
+
+bool ValidateProgramUniform3f(Context *context,
+                              GLuint program,
+                              GLint location,
+                              GLfloat v0,
+                              GLfloat v1,
+                              GLfloat v2)
+{
+    GLfloat xyz[3] = {v0, v1, v2};
+    return ValidateProgramUniform3fv(context, program, location, 1, xyz);
+}
+
+bool ValidateProgramUniform4f(Context *context,
+                              GLuint program,
+                              GLint location,
+                              GLfloat v0,
+                              GLfloat v1,
+                              GLfloat v2,
+                              GLfloat v3)
+{
+    GLfloat xyzw[4] = {v0, v1, v2, v3};
+    return ValidateProgramUniform4fv(context, program, location, 1, xyzw);
+}
+
+bool ValidateProgramUniform1iv(Context *context,
+                               GLuint program,
+                               GLint location,
+                               GLsizei count,
+                               const GLint *value)
+{
+    // 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);
+    return ValidateUniformCommonBase(context, programObject, location, count, &uniform) &&
+           ValidateUniform1ivValue(context, uniform->type, count, value);
+}
+
+bool ValidateProgramUniform2iv(Context *context,
+                               GLuint program,
+                               GLint location,
+                               GLsizei count,
+                               const GLint *value)
+{
+    return ValidateProgramUniform(context, GL_INT_VEC2, program, location, count);
+}
+
+bool ValidateProgramUniform3iv(Context *context,
+                               GLuint program,
+                               GLint location,
+                               GLsizei count,
+                               const GLint *value)
+{
+    return ValidateProgramUniform(context, GL_INT_VEC3, program, location, count);
+}
+
+bool ValidateProgramUniform4iv(Context *context,
+                               GLuint program,
+                               GLint location,
+                               GLsizei count,
+                               const GLint *value)
+{
+    return ValidateProgramUniform(context, GL_INT_VEC4, program, location, count);
+}
+
+bool ValidateProgramUniform1uiv(Context *context,
+                                GLuint program,
+                                GLint location,
+                                GLsizei count,
+                                const GLuint *value)
+{
+    return ValidateProgramUniform(context, GL_UNSIGNED_INT, program, location, count);
+}
+
+bool ValidateProgramUniform2uiv(Context *context,
+                                GLuint program,
+                                GLint location,
+                                GLsizei count,
+                                const GLuint *value)
+{
+    return ValidateProgramUniform(context, GL_UNSIGNED_INT_VEC2, program, location, count);
+}
+
+bool ValidateProgramUniform3uiv(Context *context,
+                                GLuint program,
+                                GLint location,
+                                GLsizei count,
+                                const GLuint *value)
+{
+    return ValidateProgramUniform(context, GL_UNSIGNED_INT_VEC3, program, location, count);
+}
+
+bool ValidateProgramUniform4uiv(Context *context,
+                                GLuint program,
+                                GLint location,
+                                GLsizei count,
+                                const GLuint *value)
+{
+    return ValidateProgramUniform(context, GL_UNSIGNED_INT_VEC4, program, location, count);
+}
+
+bool ValidateProgramUniform1fv(Context *context,
+                               GLuint program,
+                               GLint location,
+                               GLsizei count,
+                               const GLfloat *value)
+{
+    return ValidateProgramUniform(context, GL_FLOAT, program, location, count);
+}
+
+bool ValidateProgramUniform2fv(Context *context,
+                               GLuint program,
+                               GLint location,
+                               GLsizei count,
+                               const GLfloat *value)
+{
+    return ValidateProgramUniform(context, GL_FLOAT_VEC2, program, location, count);
+}
+
+bool ValidateProgramUniform3fv(Context *context,
+                               GLuint program,
+                               GLint location,
+                               GLsizei count,
+                               const GLfloat *value)
+{
+    return ValidateProgramUniform(context, GL_FLOAT_VEC3, program, location, count);
+}
+
+bool ValidateProgramUniform4fv(Context *context,
+                               GLuint program,
+                               GLint location,
+                               GLsizei count,
+                               const GLfloat *value)
+{
+    return ValidateProgramUniform(context, GL_FLOAT_VEC4, program, location, count);
+}
+
+bool ValidateProgramUniformMatrix2fv(Context *context,
+                                     GLuint program,
+                                     GLint location,
+                                     GLsizei count,
+                                     GLboolean transpose,
+                                     const GLfloat *value)
+{
+    return ValidateProgramUniformMatrix(context, GL_FLOAT_MAT2, program, location, count,
+                                        transpose);
+}
+
+bool ValidateProgramUniformMatrix3fv(Context *context,
+                                     GLuint program,
+                                     GLint location,
+                                     GLsizei count,
+                                     GLboolean transpose,
+                                     const GLfloat *value)
+{
+    return ValidateProgramUniformMatrix(context, GL_FLOAT_MAT3, program, location, count,
+                                        transpose);
+}
+
+bool ValidateProgramUniformMatrix4fv(Context *context,
+                                     GLuint program,
+                                     GLint location,
+                                     GLsizei count,
+                                     GLboolean transpose,
+                                     const GLfloat *value)
+{
+    return ValidateProgramUniformMatrix(context, GL_FLOAT_MAT4, program, location, count,
+                                        transpose);
+}
+
+bool ValidateProgramUniformMatrix2x3fv(Context *context,
+                                       GLuint program,
+                                       GLint location,
+                                       GLsizei count,
+                                       GLboolean transpose,
+                                       const GLfloat *value)
+{
+    return ValidateProgramUniformMatrix(context, GL_FLOAT_MAT2x3, program, location, count,
+                                        transpose);
+}
+
+bool ValidateProgramUniformMatrix3x2fv(Context *context,
+                                       GLuint program,
+                                       GLint location,
+                                       GLsizei count,
+                                       GLboolean transpose,
+                                       const GLfloat *value)
+{
+    return ValidateProgramUniformMatrix(context, GL_FLOAT_MAT3x2, program, location, count,
+                                        transpose);
+}
+
+bool ValidateProgramUniformMatrix2x4fv(Context *context,
+                                       GLuint program,
+                                       GLint location,
+                                       GLsizei count,
+                                       GLboolean transpose,
+                                       const GLfloat *value)
+{
+    return ValidateProgramUniformMatrix(context, GL_FLOAT_MAT2x4, program, location, count,
+                                        transpose);
+}
+
+bool ValidateProgramUniformMatrix4x2fv(Context *context,
+                                       GLuint program,
+                                       GLint location,
+                                       GLsizei count,
+                                       GLboolean transpose,
+                                       const GLfloat *value)
+{
+    return ValidateProgramUniformMatrix(context, GL_FLOAT_MAT4x2, program, location, count,
+                                        transpose);
+}
+
+bool ValidateProgramUniformMatrix3x4fv(Context *context,
+                                       GLuint program,
+                                       GLint location,
+                                       GLsizei count,
+                                       GLboolean transpose,
+                                       const GLfloat *value)
+{
+    return ValidateProgramUniformMatrix(context, GL_FLOAT_MAT3x4, program, location, count,
+                                        transpose);
+}
+
+bool ValidateProgramUniformMatrix4x3fv(Context *context,
+                                       GLuint program,
+                                       GLint location,
+                                       GLsizei count,
+                                       GLboolean transpose,
+                                       const GLfloat *value)
+{
+    return ValidateProgramUniformMatrix(context, GL_FLOAT_MAT4x3, program, location, count,
+                                        transpose);
+}
+
 bool ValidateGetTexLevelParameterBase(Context *context,
                                       GLenum target,
                                       GLint level,
                                       GLenum pname,
                                       GLsizei *length)
 {
     if (context->getClientVersion() < ES_3_1)
     {
@@ -533,17 +940,17 @@ bool ValidateGetTexLevelParameteriv(Cont
                                     GLenum target,
                                     GLint level,
                                     GLenum pname,
                                     GLint *params)
 {
     return ValidateGetTexLevelParameterBase(context, target, level, pname, nullptr);
 }
 
-bool ValidateTexStorage2DMultiSample(Context *context,
+bool ValidateTexStorage2DMultisample(Context *context,
                                      GLenum target,
                                      GLsizei samples,
                                      GLint internalFormat,
                                      GLsizei width,
                                      GLsizei height,
                                      GLboolean fixedSampleLocations)
 {
     if (context->getClientVersion() < ES_3_1)
@@ -645,25 +1052,25 @@ bool ValidateGetMultisamplefv(Context *c
     {
         context->handleError(InvalidValue() << "Index must be less than the value of SAMPLES.");
         return false;
     }
 
     return true;
 }
 
-bool ValidationFramebufferParameteri(Context *context, GLenum target, GLenum pname, GLint param)
+bool ValidateFramebufferParameteri(Context *context, GLenum target, GLenum pname, GLint param)
 {
     if (context->getClientVersion() < ES_3_1)
     {
         ANGLE_VALIDATION_ERR(context, InvalidOperation(), ES31Required);
         return false;
     }
 
-    if (!ValidFramebufferTarget(target))
+    if (!ValidFramebufferTarget(context, target))
     {
         context->handleError(InvalidEnum() << "Invalid framebuffer target.");
         return false;
     }
 
     switch (pname)
     {
         case GL_FRAMEBUFFER_DEFAULT_WIDTH:
@@ -718,28 +1125,25 @@ bool ValidationFramebufferParameteri(Con
     if (framebuffer->id() == 0)
     {
         context->handleError(InvalidOperation() << "Default framebuffer is bound to target.");
         return false;
     }
     return true;
 }
 
-bool ValidationGetFramebufferParameteri(Context *context,
-                                        GLenum target,
-                                        GLenum pname,
-                                        GLint *params)
+bool ValidateGetFramebufferParameteriv(Context *context, GLenum target, GLenum pname, GLint *params)
 {
     if (context->getClientVersion() < ES_3_1)
     {
         ANGLE_VALIDATION_ERR(context, InvalidOperation(), ES31Required);
         return false;
     }
 
-    if (!ValidFramebufferTarget(target))
+    if (!ValidFramebufferTarget(context, target))
     {
         ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidFramebufferTarget);
         return false;
     }
 
     switch (pname)
     {
         case GL_FRAMEBUFFER_DEFAULT_WIDTH:
@@ -863,46 +1267,33 @@ bool ValidateVertexBindingDivisor(Valida
         context->handleError(InvalidOperation() << "Default vertex array object is bound.");
         return false;
     }
 
     return true;
 }
 
 bool ValidateVertexAttribFormat(ValidationContext *context,
-                                GLuint attribIndex,
+                                GLuint attribindex,
                                 GLint size,
                                 GLenum type,
-                                GLuint relativeOffset,
-                                GLboolean pureInteger)
+                                GLboolean normalized,
+                                GLuint relativeoffset)
 {
-    if (context->getClientVersion() < ES_3_1)
-    {
-        ANGLE_VALIDATION_ERR(context, InvalidOperation(), ES31Required);
-        return false;
-    }
+    return ValidateVertexAttribFormatCommon(context, attribindex, size, type, relativeoffset,
+                                            false);
+}
 
-    const Caps &caps = context->getCaps();
-    if (relativeOffset > static_cast<GLuint>(caps.maxVertexAttribRelativeOffset))
-    {
-        context->handleError(
-            InvalidValue()
-            << "relativeOffset cannot be greater than MAX_VERTEX_ATTRIB_RELATIVE_OFFSET.");
-        return false;
-    }
-
-    // [OpenGL ES 3.1] Section 10.3.1 page 243:
-    // An INVALID_OPERATION error is generated if the default vertex array object is bound.
-    if (context->getGLState().getVertexArrayId() == 0)
-    {
-        context->handleError(InvalidOperation() << "Default vertex array object is bound.");
-        return false;
-    }
-
-    return ValidateVertexFormatBase(context, attribIndex, size, type, pureInteger);
+bool ValidateVertexAttribIFormat(ValidationContext *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)
 {
     if (context->getClientVersion() < ES_3_1)
     {
@@ -986,28 +1377,19 @@ bool ValidateDispatchCompute(Context *co
     {
         ANGLE_VALIDATION_ERR(context, InvalidOperation(), ES31Required);
         return false;
     }
 
     const State &state = context->getGLState();
     Program *program   = state.getProgram();
 
-    if (program == nullptr)
+    if (program == nullptr || !program->hasLinkedComputeShader())
     {
-        context->handleError(InvalidOperation()
-                             << "No active program object for the compute shader stage.");
-        return false;
-    }
-
-    if (program->isLinked() == false || program->getAttachedComputeShader() == nullptr)
-    {
-        context->handleError(
-            InvalidOperation()
-            << "Program has not been successfully linked, or program contains no compute shaders.");
+        ANGLE_VALIDATION_ERR(context, InvalidOperation(), NoActiveProgramWithComputeShader);
         return false;
     }
 
     const Caps &caps = context->getCaps();
     if (numGroupsX > caps.maxComputeWorkGroupCount[0])
     {
         context->handleError(
             InvalidValue() << "num_groups_x cannot be greater than MAX_COMPUTE_WORK_GROUP_COUNT[0]="
@@ -1027,16 +1409,64 @@ bool ValidateDispatchCompute(Context *co
             InvalidValue() << "num_groups_z cannot be greater than MAX_COMPUTE_WORK_GROUP_COUNT[2]="
                            << caps.maxComputeWorkGroupCount[2]);
         return false;
     }
 
     return true;
 }
 
+bool ValidateDispatchComputeIndirect(Context *context, GLintptr indirect)
+{
+    if (context->getClientVersion() < ES_3_1)
+    {
+        ANGLE_VALIDATION_ERR(context, InvalidOperation(), ES31Required);
+        return false;
+    }
+
+    const State &state = context->getGLState();
+    Program *program   = state.getProgram();
+
+    if (program == nullptr || !program->hasLinkedComputeShader())
+    {
+        ANGLE_VALIDATION_ERR(context, InvalidOperation(), NoActiveProgramWithComputeShader);
+        return false;
+    }
+
+    gl::Buffer *dispatchIndirectBuffer = state.getTargetBuffer(BufferBinding::DispatchIndirect);
+    if (!dispatchIndirectBuffer)
+    {
+        ANGLE_VALIDATION_ERR(context, InvalidOperation(), DispatchIndirectBufferNotBound);
+        return false;
+    }
+
+    if (indirect < 0)
+    {
+        ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeOffset);
+        return false;
+    }
+
+    if ((indirect & (sizeof(GLuint) - 1)) != 0)
+    {
+        ANGLE_VALIDATION_ERR(context, InvalidOperation(), OffsetMustBeMultipleOfUint);
+        return false;
+    }
+
+    CheckedNumeric<GLuint64> checkedOffset(static_cast<GLuint64>(indirect));
+    auto checkedSum = checkedOffset + static_cast<GLuint64>(3 * sizeof(GLuint));
+    if (!checkedSum.IsValid() ||
+        checkedSum.ValueOrDie() > static_cast<GLuint64>(dispatchIndirectBuffer->getSize()))
+    {
+        ANGLE_VALIDATION_ERR(context, InvalidOperation(), InsufficientBufferSize);
+        return false;
+    }
+
+    return true;
+}
+
 bool ValidateBindImageTexture(Context *context,
                               GLuint unit,
                               GLuint texture,
                               GLint level,
                               GLboolean layered,
                               GLint layer,
                               GLenum access,
                               GLenum format)
@@ -1307,17 +1737,114 @@ bool ValidateIsProgramPipeline(Context *
     {
         ANGLE_VALIDATION_ERR(context, InvalidOperation(), ES31Required);
         return false;
     }
 
     return true;
 }
 
-bool ValidateSampleMaski(Context *context, GLuint maskNumber)
+bool ValidateUseProgramStages(Context *context, GLuint pipeline, GLbitfield stages, GLuint program)
+{
+    UNIMPLEMENTED();
+    return false;
+}
+
+bool ValidateActiveShaderProgram(Context *context, GLuint pipeline, GLuint program)
+{
+    UNIMPLEMENTED();
+    return false;
+}
+
+bool ValidateCreateShaderProgramv(Context *context,
+                                  GLenum type,
+                                  GLsizei count,
+                                  const GLchar *const *strings)
+{
+    UNIMPLEMENTED();
+    return false;
+}
+
+bool ValidateGetProgramPipelineiv(Context *context, GLuint pipeline, GLenum pname, GLint *params)
+{
+    UNIMPLEMENTED();
+    return false;
+}
+
+bool ValidateValidateProgramPipeline(Context *context, GLuint pipeline)
+{
+    UNIMPLEMENTED();
+    return false;
+}
+
+bool ValidateGetProgramPipelineInfoLog(Context *context,
+                                       GLuint pipeline,
+                                       GLsizei bufSize,
+                                       GLsizei *length,
+                                       GLchar *infoLog)
+{
+    UNIMPLEMENTED();
+    return false;
+}
+
+bool ValidateMemoryBarrier(Context *context, GLbitfield barriers)
+{
+    if (context->getClientVersion() < ES_3_1)
+    {
+        ANGLE_VALIDATION_ERR(context, InvalidOperation(), ES31Required);
+        return false;
+    }
+
+    if (barriers == GL_ALL_BARRIER_BITS)
+    {
+        return true;
+    }
+
+    GLbitfield supported_barrier_bits =
+        GL_VERTEX_ATTRIB_ARRAY_BARRIER_BIT | GL_ELEMENT_ARRAY_BARRIER_BIT | GL_UNIFORM_BARRIER_BIT |
+        GL_TEXTURE_FETCH_BARRIER_BIT | GL_SHADER_IMAGE_ACCESS_BARRIER_BIT | GL_COMMAND_BARRIER_BIT |
+        GL_PIXEL_BUFFER_BARRIER_BIT | GL_TEXTURE_UPDATE_BARRIER_BIT | GL_BUFFER_UPDATE_BARRIER_BIT |
+        GL_FRAMEBUFFER_BARRIER_BIT | GL_TRANSFORM_FEEDBACK_BARRIER_BIT |
+        GL_ATOMIC_COUNTER_BARRIER_BIT | GL_SHADER_STORAGE_BARRIER_BIT;
+    if ((barriers & ~supported_barrier_bits) != 0)
+    {
+        ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidMemoryBarrierBit);
+        return false;
+    }
+
+    return true;
+}
+
+bool ValidateMemoryBarrierByRegion(Context *context, GLbitfield barriers)
+{
+    if (context->getClientVersion() < ES_3_1)
+    {
+        ANGLE_VALIDATION_ERR(context, InvalidOperation(), ES31Required);
+        return false;
+    }
+
+    if (barriers == GL_ALL_BARRIER_BITS)
+    {
+        return true;
+    }
+
+    GLbitfield supported_barrier_bits = GL_ATOMIC_COUNTER_BARRIER_BIT | GL_FRAMEBUFFER_BARRIER_BIT |
+                                        GL_SHADER_IMAGE_ACCESS_BARRIER_BIT |
+                                        GL_SHADER_STORAGE_BARRIER_BIT |
+                                        GL_TEXTURE_FETCH_BARRIER_BIT | GL_UNIFORM_BARRIER_BIT;
+    if ((barriers & ~supported_barrier_bits) != 0)
+    {
+        ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidMemoryBarrierBit);
+        return false;
+    }
+
+    return true;
+}
+
+bool ValidateSampleMaski(Context *context, GLuint maskNumber, GLbitfield mask)
 {
     if (context->getClientVersion() < ES_3_1)
     {
         ANGLE_VALIDATION_ERR(context, InvalidOperation(), ES31Required);
         return false;
     }
 
     if (maskNumber >= context->getCaps().maxSampleMaskWords)
--- a/gfx/angle/src/libANGLE/validationES31.h
+++ b/gfx/angle/src/libANGLE/validationES31.h
@@ -30,34 +30,209 @@ bool ValidateGetTexLevelParameterfv(Cont
                                     GLenum pname,
                                     GLfloat *params);
 bool ValidateGetTexLevelParameteriv(Context *context,
                                     GLenum target,
                                     GLint level,
                                     GLenum pname,
                                     GLint *param);
 
-bool ValidateTexStorage2DMultiSample(Context *context,
+bool ValidateTexStorage2DMultisample(Context *context,
                                      GLenum target,
                                      GLsizei samples,
                                      GLint internalFormat,
                                      GLsizei width,
                                      GLsizei height,
                                      GLboolean fixedSampleLocations);
 bool ValidateGetMultisamplefv(Context *context, GLenum pname, GLuint index, 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 ValidationFramebufferParameteri(Context *context, GLenum target, GLenum pname, GLint param);
-bool ValidationGetFramebufferParameteri(Context *context,
-                                        GLenum target,
-                                        GLenum pname,
-                                        GLint *params);
+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,
+                              GLuint program,
+                              GLint location,
+                              GLint v0,
+                              GLint v1,
+                              GLint v2);
+bool ValidateProgramUniform4i(Context *context,
+                              GLuint program,
+                              GLint location,
+                              GLint v0,
+                              GLint v1,
+                              GLint v2,
+                              GLint v3);
+bool ValidateProgramUniform1ui(Context *context, GLuint program, GLint location, GLuint v0);
+bool ValidateProgramUniform2ui(Context *context,
+                               GLuint program,
+                               GLint location,
+                               GLuint v0,
+                               GLuint v1);
+bool ValidateProgramUniform3ui(Context *context,
+                               GLuint program,
+                               GLint location,
+                               GLuint v0,
+                               GLuint v1,
+                               GLuint v2);
+bool ValidateProgramUniform4ui(Context *context,
+                               GLuint program,
+                               GLint location,
+                               GLuint v0,
+                               GLuint v1,
+                               GLuint v2,
+                               GLuint v3);
+bool ValidateProgramUniform1f(Context *context, GLuint program, GLint location, GLfloat v0);
+bool ValidateProgramUniform2f(Context *context,
+                              GLuint program,
+                              GLint location,
+                              GLfloat v0,
+                              GLfloat v1);
+bool ValidateProgramUniform3f(Context *context,
+                              GLuint program,
+                              GLint location,
+                              GLfloat v0,
+                              GLfloat v1,
+                              GLfloat v2);
+bool ValidateProgramUniform4f(Context *context,
+                              GLuint program,
+                              GLint location,
+                              GLfloat v0,
+                              GLfloat v1,
+                              GLfloat v2,
+                              GLfloat v3);
+
+bool ValidateProgramUniform1iv(Context *context,
+                               GLuint program,
+                               GLint location,
+                               GLsizei count,
+                               const GLint *value);
+bool ValidateProgramUniform2iv(Context *context,
+                               GLuint program,
+                               GLint location,
+                               GLsizei count,
+                               const GLint *value);
+bool ValidateProgramUniform3iv(Context *context,
+                               GLuint program,
+                               GLint location,
+                               GLsizei count,
+                               const GLint *value);
+bool ValidateProgramUniform4iv(Context *context,
+                               GLuint program,
+                               GLint location,
+                               GLsizei count,
+                               const GLint *value);
+bool ValidateProgramUniform1uiv(Context *context,
+                                GLuint program,
+                                GLint location,
+                                GLsizei count,
+                                const GLuint *value);
+bool ValidateProgramUniform2uiv(Context *context,
+                                GLuint program,
+                                GLint location,
+                                GLsizei count,
+                                const GLuint *value);
+bool ValidateProgramUniform3uiv(Context *context,
+                                GLuint program,
+                                GLint location,
+                                GLsizei count,
+                                const GLuint *value);
+bool ValidateProgramUniform4uiv(Context *context,
+                                GLuint program,
+                                GLint location,
+                                GLsizei count,
+                                const GLuint *value);
+bool ValidateProgramUniform1fv(Context *context,
+                               GLuint program,
+                               GLint location,
+                               GLsizei count,
+                               const GLfloat *value);
+bool ValidateProgramUniform2fv(Context *context,
+                               GLuint program,
+                               GLint location,
+                               GLsizei count,
+                               const GLfloat *value);
+bool ValidateProgramUniform3fv(Context *context,
+                               GLuint program,
+                               GLint location,
+                               GLsizei count,
+                               const GLfloat *value);
+bool ValidateProgramUniform4fv(Context *context,
+                               GLuint program,
+                               GLint location,
+                               GLsizei count,
+                               const GLfloat *value);
+bool ValidateProgramUniformMatrix2fv(Context *context,
+                                     GLuint program,
+                                     GLint location,
+                                     GLsizei count,
+                                     GLboolean transpose,
+                                     const GLfloat *value);
+bool ValidateProgramUniformMatrix2fv(Context *context,
+                                     GLuint program,
+                                     GLint location,
+                                     GLsizei count,
+                                     GLboolean transpose,
+                                     const GLfloat *value);
+bool ValidateProgramUniformMatrix3fv(Context *context,
+                                     GLuint program,
+                                     GLint location,
+                                     GLsizei count,
+                                     GLboolean transpose,
+                                     const GLfloat *value);
+bool ValidateProgramUniformMatrix4fv(Context *context,
+                                     GLuint program,
+                                     GLint location,
+                                     GLsizei count,
+                                     GLboolean transpose,
+                                     const GLfloat *value);
+bool ValidateProgramUniformMatrix2x3fv(Context *context,
+                                       GLuint program,
+                                       GLint location,
+                                       GLsizei count,
+                                       GLboolean transpose,
+                                       const GLfloat *value);
+bool ValidateProgramUniformMatrix3x2fv(Context *context,
+                                       GLuint program,
+                                       GLint location,
+                                       GLsizei count,
+                                       GLboolean transpose,
+                                       const GLfloat *value);
+bool ValidateProgramUniformMatrix2x4fv(Context *context,
+                                       GLuint program,
+                                       GLint location,
+                                       GLsizei count,
+                                       GLboolean transpose,
+                                       const GLfloat *value);
+bool ValidateProgramUniformMatrix4x2fv(Context *context,
+                                       GLuint program,
+                                       GLint location,
+                                       GLsizei count,
+                                       GLboolean transpose,
+                                       const GLfloat *value);
+bool ValidateProgramUniformMatrix3x4fv(Context *context,
+                                       GLuint program,
+                                       GLint location,
+                                       GLsizei count,
+                                       GLboolean transpose,
+                                       const GLfloat *value);
+bool ValidateProgramUniformMatrix4x3fv(Context *context,
+                                       GLuint program,
+                                       GLint location,
+                                       GLsizei count,
+                                       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 ValidateGetProgramResourceIndex(Context *context,
                                      GLuint program,
                                      GLenum programInterface,
                                      const GLchar *name);
 bool ValidateGetProgramResourceName(Context *context,
                                     GLuint program,
                                     GLenum programInterface,
@@ -87,42 +262,64 @@ bool ValidateGetProgramInterfaceiv(Conte
                                    GLint *params);
 
 bool ValidateBindVertexBuffer(ValidationContext *context,
                               GLuint bindingIndex,
                               GLuint buffer,
                               GLintptr offset,
                               GLsizei stride);
 bool ValidateVertexAttribFormat(ValidationContext *context,
-                                GLuint attribIndex,
+                                GLuint attribindex,
                                 GLint size,
                                 GLenum type,
-                                GLuint relativeOffset,
-                                GLboolean pureInteger);
+                                GLboolean normalized,
+                                GLuint relativeoffset);
+bool ValidateVertexAttribIFormat(ValidationContext *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 ValidateDispatchCompute(Context *context,
                              GLuint numGroupsX,
                              GLuint numGroupsY,
                              GLuint numGroupsZ);
+bool ValidateDispatchComputeIndirect(Context *context, GLintptr indirect);
 
 bool ValidateBindImageTexture(Context *context,
                               GLuint unit,
                               GLuint texture,
                               GLint level,
                               GLboolean layered,
                               GLint layer,
                               GLenum access,
                               GLenum format);
 
 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,
+                                  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,
+                                       GLchar *infoLog);
 
-bool ValidateSampleMaski(Context *context, GLuint maskNumber);
+bool ValidateMemoryBarrier(Context *context, GLbitfield barriers);
+bool ValidateMemoryBarrierByRegion(Context *context, GLbitfield barriers);
+
+bool ValidateSampleMaski(Context *context, GLuint maskNumber, GLbitfield mask);
 
 }  // namespace gl
 
 #endif  // LIBANGLE_VALIDATION_ES31_H_
--- a/gfx/angle/src/libEGL/libEGL.cpp
+++ b/gfx/angle/src/libEGL/libEGL.cpp
@@ -339,29 +339,29 @@ EGLBoolean EGLAPIENTRY eglStreamConsumer
 
 EGLBoolean EGLAPIENTRY eglStreamConsumerGLTextureExternalAttribsNV(EGLDisplay dpy,
                                                                    EGLStreamKHR stream,
                                                                    EGLAttrib *attrib_list)
 {
     return egl::StreamConsumerGLTextureExternalAttribsNV(dpy, stream, attrib_list);
 }
 
-EGLBoolean EGLAPIENTRY eglCreateStreamProducerD3DTextureNV12ANGLE(EGLDisplay dpy,
-                                                                  EGLStreamKHR stream,
-                                                                  const EGLAttrib *attrib_list)
+EGLBoolean EGLAPIENTRY eglCreateStreamProducerD3DTextureANGLE(EGLDisplay dpy,
+                                                              EGLStreamKHR stream,
+                                                              const EGLAttrib *attrib_list)
 {
-    return egl::CreateStreamProducerD3DTextureNV12ANGLE(dpy, stream, attrib_list);
+    return egl::CreateStreamProducerD3DTextureANGLE(dpy, stream, attrib_list);
 }
 
-EGLBoolean EGLAPIENTRY eglStreamPostD3DTextureNV12ANGLE(EGLDisplay dpy,
-                                                        EGLStreamKHR stream,
-                                                        void *texture,
-                                                        const EGLAttrib *attrib_list)
+EGLBoolean EGLAPIENTRY eglStreamPostD3DTextureANGLE(EGLDisplay dpy,
+                                                    EGLStreamKHR stream,
+                                                    void *texture,
+                                                    const EGLAttrib *attrib_list)
 {
-    return egl::StreamPostD3DTextureNV12ANGLE(dpy, stream, texture, attrib_list);
+    return egl::StreamPostD3DTextureANGLE(dpy, stream, texture, attrib_list);
 }
 
 EGLBoolean EGLAPIENTRY eglGetSyncValuesCHROMIUM(EGLDisplay dpy,
                                                 EGLSurface surface,
                                                 EGLuint64KHR *ust,
                                                 EGLuint64KHR *msc,
                                                 EGLuint64KHR *sbc)
 {
--- a/gfx/angle/src/libEGL/libEGL.def
+++ b/gfx/angle/src/libEGL/libEGL.def
@@ -50,18 +50,18 @@ EXPORTS
     eglDestroyStreamKHR                         @56
     eglStreamAttribKHR                          @57
     eglQueryStreamKHR                           @58
     eglQueryStreamu64KHR                        @59
     eglStreamConsumerGLTextureExternalKHR       @60
     eglStreamConsumerAcquireKHR                 @61
     eglStreamConsumerReleaseKHR                 @62
     eglStreamConsumerGLTextureExternalAttribsNV @63
-    eglCreateStreamProducerD3DTextureNV12ANGLE  @64
-    eglStreamPostD3DTextureNV12ANGLE            @65
+    eglCreateStreamProducerD3DTextureANGLE      @64
+    eglStreamPostD3DTextureANGLE                @65
     eglGetSyncValuesCHROMIUM                    @66
     eglSwapBuffersWithDamageEXT                 @67
     eglProgramCacheGetAttribANGLE               @68
     eglProgramCachePopulateANGLE                @69
     eglProgramCacheQueryANGLE                   @70
     eglProgramCacheResizeANGLE                  @71
 
     ; 1.5 entry points
--- a/gfx/angle/src/libEGL/libEGL.rc
+++ b/gfx/angle/src/libEGL/libEGL.rc
@@ -1,103 +1,103 @@
-// Microsoft Visual C++ generated resource script.
-//
-#include "resource.h"
-
-#define APSTUDIO_READONLY_SYMBOLS
-/////////////////////////////////////////////////////////////////////////////
-//
-// Generated from the TEXTINCLUDE 2 resource.
-//
-#include <windows.h>
-#include "../common/version.h"
-
-/////////////////////////////////////////////////////////////////////////////
-#undef APSTUDIO_READONLY_SYMBOLS
-
-/////////////////////////////////////////////////////////////////////////////
-// English (U.S.) resources
-
-#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)
-#ifdef _WIN32
-LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
-#pragma code_page(1252)
-#endif //_WIN32
-
-#ifdef APSTUDIO_INVOKED
-/////////////////////////////////////////////////////////////////////////////
-//
-// TEXTINCLUDE
-//
-
-1 TEXTINCLUDE 
-BEGIN
-    "resource.h\0"
-END
-
-2 TEXTINCLUDE 
-BEGIN
-    "#include ""afxres.h""\r\n"
-    "#include ""../common/version.h""\0"
-END
-
-3 TEXTINCLUDE 
-BEGIN
-    "\r\n"
-    "\0"
-END
-
-#endif    // APSTUDIO_INVOKED
-
-
-/////////////////////////////////////////////////////////////////////////////
-//
-// Version
-//
-
-VS_VERSION_INFO VERSIONINFO
- FILEVERSION ANGLE_MAJOR_VERSION,ANGLE_MINOR_VERSION,ANGLE_REVISION,0
- PRODUCTVERSION ANGLE_MAJOR_VERSION,ANGLE_MINOR_VERSION,ANGLE_REVISION,0
- FILEFLAGSMASK 0x17L
-#ifdef _DEBUG
- FILEFLAGS 0x1L
-#else
- FILEFLAGS 0x0L
-#endif
- FILEOS 0x4L
- FILETYPE 0x2L
- FILESUBTYPE 0x0L
-BEGIN
-    BLOCK "StringFileInfo"
-    BEGIN
-        BLOCK "040904b0"
-        BEGIN
-            VALUE "FileDescription", "ANGLE libEGL Dynamic Link Library"
-            VALUE "FileVersion", ANGLE_VERSION_STRING
-            VALUE "InternalName", "libEGL"
-            VALUE "LegalCopyright", "Copyright (C) 2015 Google Inc."
-            VALUE "OriginalFilename", "libEGL.dll"
-            VALUE "PrivateBuild", ANGLE_VERSION_STRING
-            VALUE "ProductName", "ANGLE libEGL Dynamic Link Library"
-            VALUE "ProductVersion", ANGLE_VERSION_STRING
-            VALUE "Comments", "Build Date: " ANGLE_COMMIT_DATE
-        END
-    END
-    BLOCK "VarFileInfo"
-    BEGIN
-        VALUE "Translation", 0x409, 1200
-    END
-END
-
-#endif    // English (U.S.) resources
-/////////////////////////////////////////////////////////////////////////////
-
-
-
-#ifndef APSTUDIO_INVOKED
-/////////////////////////////////////////////////////////////////////////////
-//
-// Generated from the TEXTINCLUDE 3 resource.
-//
-
-
-/////////////////////////////////////////////////////////////////////////////
-#endif    // not APSTUDIO_INVOKED
+// Microsoft Visual C++ generated resource script.
+//
+#include "resource.h"
+
+#define APSTUDIO_READONLY_SYMBOLS
+/////////////////////////////////////////////////////////////////////////////
+//
+// Generated from the TEXTINCLUDE 2 resource.
+//
+#include <windows.h>
+#include "../common/version.h"
+
+/////////////////////////////////////////////////////////////////////////////
+#undef APSTUDIO_READONLY_SYMBOLS
+
+/////////////////////////////////////////////////////////////////////////////
+// English (U.S.) resources
+
+#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)
+#ifdef _WIN32
+LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
+#pragma code_page(1252)
+#endif //_WIN32
+
+#ifdef APSTUDIO_INVOKED
+/////////////////////////////////////////////////////////////////////////////
+//
+// TEXTINCLUDE
+//
+
+1 TEXTINCLUDE 
+BEGIN
+    "resource.h\0"
+END
+
+2 TEXTINCLUDE 
+BEGIN
+    "#include ""afxres.h""\r\n"
+    "#include ""../common/version.h""\0"
+END
+
+3 TEXTINCLUDE 
+BEGIN
+    "\r\n"
+    "\0"
+END
+
+#endif    // APSTUDIO_INVOKED
+
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// Version
+//
+
+VS_VERSION_INFO VERSIONINFO
+ FILEVERSION ANGLE_MAJOR_VERSION,ANGLE_MINOR_VERSION,ANGLE_REVISION,0
+ PRODUCTVERSION ANGLE_MAJOR_VERSION,ANGLE_MINOR_VERSION,ANGLE_REVISION,0
+ FILEFLAGSMASK 0x17L
+#ifdef _DEBUG
+ FILEFLAGS 0x1L
+#else
+ FILEFLAGS 0x0L
+#endif
+ FILEOS 0x4L
+ FILETYPE 0x2L
+ FILESUBTYPE 0x0L
+BEGIN
+    BLOCK "StringFileInfo"
+    BEGIN
+        BLOCK "040904b0"
+        BEGIN
+            VALUE "FileDescription", "ANGLE libEGL Dynamic Link Library"
+            VALUE "FileVersion", ANGLE_VERSION_STRING
+            VALUE "InternalName", "libEGL"
+            VALUE "LegalCopyright", "Copyright (C) 2015 Google Inc."
+            VALUE "OriginalFilename", "libEGL.dll"
+            VALUE "PrivateBuild", ANGLE_VERSION_STRING
+            VALUE "ProductName", "ANGLE libEGL Dynamic Link Library"
+            VALUE "ProductVersion", ANGLE_VERSION_STRING
+            VALUE "Comments", "Build Date: " ANGLE_COMMIT_DATE
+        END
+    END
+    BLOCK "VarFileInfo"
+    BEGIN
+        VALUE "Translation", 0x409, 1200
+    END
+END
+
+#endif    // English (U.S.) resources
+/////////////////////////////////////////////////////////////////////////////
+
+
+
+#ifndef APSTUDIO_INVOKED
+/////////////////////////////////////////////////////////////////////////////
+//
+// Generated from the TEXTINCLUDE 3 resource.
+//
+
+
+/////////////////////////////////////////////////////////////////////////////
+#endif    // not APSTUDIO_INVOKED
--- a/gfx/angle/src/libEGL/moz.build
+++ b/gfx/angle/src/libEGL/moz.build
@@ -15,28 +15,32 @@ UNIFIED_SOURCES += [
 
 if CONFIG['CC_TYPE'] in ('clang', 'gcc'):
     CXXFLAGS += [
         '-Wno-attributes',
         '-Wno-shadow',
         '-Wno-sign-compare',
         '-Wno-unknown-pragmas',
         '-Wno-unreachable-code',
+        '-Wno-missing-braces',
     ]
     if CONFIG['CC_TYPE'] == 'clang':
         CXXFLAGS += [
             '-Wno-inconsistent-missing-override',
             '-Wno-unused-private-field',
         ]
     else:
         CXXFLAGS += [
             '-Wno-shadow-compatible-local',
             '-Wno-shadow-local',
         ]
 
+if CONFIG['CC_TYPE'] in ('msvc', 'clang-cl'):
+    CXXFLAGS += ['-wd5038'] # C5038: initializer list order warnings
+
 if CONFIG['MOZ_DIRECTX_SDK_PATH'] and not CONFIG['MOZ_HAS_WINSDK_WITH_D3D']:
     LOCAL_INCLUDES += ['%' + '%s/include/' % CONFIG['MOZ_DIRECTX_SDK_PATH']]
 
 DEFINES['_CRT_SECURE_NO_DEPRECATE'] = True
 DEFINES['_HAS_EXCEPTIONS'] = 0
 
 if not CONFIG['MOZ_DEBUG']:
     DEFINES['_SECURE_SCL'] = 0
@@ -51,17 +55,17 @@ DEFINES['ANGLE_NO_EXCEPTIONS'] = True
 
 # We need these defined to nothing so that we don't get bogus dllimport declspecs
 DEFINES['GL_APICALL'] = ""
 DEFINES['GL_GLEXT_PROTOTYPES'] = ""
 DEFINES['EGLAPI'] = ""
 
 
 
-LOCAL_INCLUDES += [ '../../include', '../../src', '../../src/common/third_party/base', '../../src/third_party/khronos' ]
+LOCAL_INCLUDES += [ '../../include', '../../src', '../../src/third_party/khronos' ]
 USE_LIBS += [ 'libGLESv2' ]
 
 DEFINES['LIBANGLE_IMPLEMENTATION'] = "1"
 DEFINES['ANGLE_ENABLE_HLSL'] = "1"
 DEFINES['ANGLE_ENABLE_KEYEDMUTEX'] = "1"
 
 if CONFIG['MOZ_HAS_WINSDK_WITH_D3D']:
   OS_LIBS += [ 'd3d9', 'dxguid' ]
--- a/gfx/angle/src/libGLESv2.gypi
+++ b/gfx/angle/src/libGLESv2.gypi
@@ -31,18 +31,18 @@
             'common/third_party/base/anglebase/macros.h',
             'common/third_party/base/anglebase/numerics/safe_conversions.h',
             'common/third_party/base/anglebase/numerics/safe_conversions_impl.h',
             'common/third_party/base/anglebase/numerics/safe_math.h',
             'common/third_party/base/anglebase/numerics/safe_math_impl.h',
             'common/third_party/base/anglebase/sha1.cc',
             'common/third_party/base/anglebase/sha1.h',
             'common/third_party/base/anglebase/sys_byteorder.h',
-            'common/third_party/murmurhash/MurmurHash3.cpp',
-            'common/third_party/murmurhash/MurmurHash3.h',
+            'common/third_party/smhasher/src/PMurHash.cpp',
+            'common/third_party/smhasher/src/PMurHash.h',
             'common/tls.cpp',
             'common/tls.h',
             'common/uniform_type_info_autogen.cpp',
             'common/utilities.cpp',
             'common/utilities.h',
             'common/vector_utils.h',
             'common/version.h',
         ],
@@ -164,21 +164,26 @@
             'libANGLE/ImageIndex.h',
             'libANGLE/ImageIndex.cpp',
             'libANGLE/IndexRangeCache.cpp',
             'libANGLE/IndexRangeCache.h',
             'libANGLE/LoggingAnnotator.cpp',
             'libANGLE/LoggingAnnotator.h',
             'libANGLE/MemoryProgramCache.cpp',
             'libANGLE/MemoryProgramCache.h',
+            'libANGLE/PackedGLEnums.h',
+            'libANGLE/PackedGLEnums_autogen.cpp',
+            'libANGLE/PackedGLEnums_autogen.h',
             'libANGLE/Path.h',
             'libANGLE/Path.cpp',
             'libANGLE/Platform.cpp',
             'libANGLE/Program.cpp',
             'libANGLE/Program.h',
+            'libANGLE/ProgramLinkedResources.cpp',
+            'libANGLE/ProgramLinkedResources.h',
             'libANGLE/ProgramPipeline.cpp',
             'libANGLE/ProgramPipeline.h',
             'libANGLE/Query.cpp',
             'libANGLE/Query.h',
             'libANGLE/RefCountObject.h',
             'libANGLE/Renderbuffer.cpp',
             'libANGLE/Renderbuffer.h',
             'libANGLE/ResourceManager.cpp',
@@ -198,18 +203,16 @@
             'libANGLE/Texture.cpp',
             'libANGLE/Texture.h',
             'libANGLE/Thread.cpp',
             'libANGLE/Thread.h',
             'libANGLE/TransformFeedback.cpp',
             'libANGLE/TransformFeedback.h',
             'libANGLE/Uniform.cpp',
             'libANGLE/Uniform.h',
-            'libANGLE/UniformLinker.cpp',
-            'libANGLE/UniformLinker.h',
             'libANGLE/VaryingPacking.cpp',
             'libANGLE/VaryingPacking.h',
             'libANGLE/Version.h',
             'libANGLE/Version.inl',
             'libANGLE/VertexArray.cpp',
             'libANGLE/VertexArray.h',
             'libANGLE/VertexAttribute.cpp',
             'libANGLE/VertexAttribute.h',
@@ -517,18 +520,18 @@
             'libANGLE/renderer/d3d/d3d11/shaders/compiled/swizzlei2darrayps.h',
             'libANGLE/renderer/d3d/d3d11/shaders/compiled/swizzlei2dps.h',
             'libANGLE/renderer/d3d/d3d11/shaders/compiled/swizzlei3dps.h',
             'libANGLE/renderer/d3d/d3d11/shaders/compiled/swizzleui2darrayps.h',
             'libANGLE/renderer/d3d/d3d11/shaders/compiled/swizzleui2dps.h',
             'libANGLE/renderer/d3d/d3d11/shaders/compiled/swizzleui3dps.h',
             'libANGLE/renderer/d3d/d3d11/StateManager11.cpp',
             'libANGLE/renderer/d3d/d3d11/StateManager11.h',
-            'libANGLE/renderer/d3d/d3d11/StreamProducerNV12.cpp',
-            'libANGLE/renderer/d3d/d3d11/StreamProducerNV12.h',
+            'libANGLE/renderer/d3d/d3d11/StreamProducerD3DTexture.cpp',
+            'libANGLE/renderer/d3d/d3d11/StreamProducerD3DTexture.h',
             'libANGLE/renderer/d3d/d3d11/SwapChain11.cpp',
             'libANGLE/renderer/d3d/d3d11/SwapChain11.h',
             'libANGLE/renderer/d3d/d3d11/TextureStorage11.cpp',
             'libANGLE/renderer/d3d/d3d11/TextureStorage11.h',
             'libANGLE/renderer/d3d/d3d11/TransformFeedback11.cpp',
             'libANGLE/renderer/d3d/d3d11/TransformFeedback11.h',
             'libANGLE/renderer/d3d/d3d11/Trim11.cpp',
             'libANGLE/renderer/d3d/d3d11/Trim11.h',
@@ -566,16 +569,18 @@
             'libANGLE/renderer/gl/BufferGL.cpp',
             'libANGLE/renderer/gl/BufferGL.h',
             'libANGLE/renderer/gl/ClearMultiviewGL.cpp',
             'libANGLE/renderer/gl/ClearMultiviewGL.h',
             'libANGLE/renderer/gl/CompilerGL.cpp',
             'libANGLE/renderer/gl/CompilerGL.h',
             'libANGLE/renderer/gl/ContextGL.cpp',
             'libANGLE/renderer/gl/ContextGL.h',
+            'libANGLE/renderer/gl/DispatchTableGL_autogen.cpp',
+            'libANGLE/renderer/gl/DispatchTableGL_autogen.h',
             'libANGLE/renderer/gl/DisplayGL.cpp',
             'libANGLE/renderer/gl/DisplayGL.h',
             'libANGLE/renderer/gl/FenceNVGL.cpp',
             'libANGLE/renderer/gl/FenceNVGL.h',
             'libANGLE/renderer/gl/FramebufferGL.cpp',
             'libANGLE/renderer/gl/FramebufferGL.h',
             'libANGLE/renderer/gl/FunctionsGL.cpp',
             'libANGLE/renderer/gl/FunctionsGL.h',
@@ -610,16 +615,21 @@
             'libANGLE/renderer/gl/WorkaroundsGL.h',
             'libANGLE/renderer/gl/formatutilsgl.cpp',
             'libANGLE/renderer/gl/formatutilsgl.h',
             'libANGLE/renderer/gl/functionsgl_enums.h',
             'libANGLE/renderer/gl/functionsgl_typedefs.h',
             'libANGLE/renderer/gl/renderergl_utils.cpp',
             'libANGLE/renderer/gl/renderergl_utils.h',
         ],
+        'libangle_gl_null_sources':
+        [
+            'libANGLE/renderer/gl/null_functions.cpp',
+            'libANGLE/renderer/gl/null_functions.h',
+        ],
         'libangle_gl_wgl_sources':
         [
             'libANGLE/renderer/gl/wgl/D3DTextureSurfaceWGL.cpp',
             'libANGLE/renderer/gl/wgl/D3DTextureSurfaceWGL.h',
             'libANGLE/renderer/gl/wgl/DisplayWGL.cpp',
             'libANGLE/renderer/gl/wgl/DisplayWGL.h',
             'libANGLE/renderer/gl/wgl/DXGISwapChainWindowSurfaceWGL.cpp',
             'libANGLE/renderer/gl/wgl/DXGISwapChainWindowSurfaceWGL.h',
@@ -648,16 +658,18 @@
             'libANGLE/renderer/gl/glx/WindowSurfaceGLX.h',
             'libANGLE/renderer/gl/glx/functionsglx_typedefs.h',
             'libANGLE/renderer/gl/glx/platform_glx.h',
         ],
         'libangle_gl_egl_sources':
         [
             'libANGLE/renderer/gl/egl/DisplayEGL.cpp',
             'libANGLE/renderer/gl/egl/DisplayEGL.h',
+            'libANGLE/renderer/gl/egl/egl_utils.cpp',
+            'libANGLE/renderer/gl/egl/egl_utils.h',
             'libANGLE/renderer/gl/egl/FunctionsEGL.cpp',
             'libANGLE/renderer/gl/egl/FunctionsEGL.h',
             'libANGLE/renderer/gl/egl/functionsegl_typedefs.h',
             'libANGLE/renderer/gl/egl/PbufferSurfaceEGL.cpp',
             'libANGLE/renderer/gl/egl/PbufferSurfaceEGL.h',
             'libANGLE/renderer/gl/egl/SurfaceEGL.cpp',
             'libANGLE/renderer/gl/egl/SurfaceEGL.h',
             'libANGLE/renderer/gl/egl/WindowSurfaceEGL.cpp',
@@ -679,25 +691,29 @@
         [
             'libANGLE/renderer/gl/egl/android/DisplayAndroid.cpp',
             'libANGLE/renderer/gl/egl/android/DisplayAndroid.h',
         ],
         'libangle_gl_cgl_sources':
         [
             'libANGLE/renderer/gl/cgl/DisplayCGL.mm',
             'libANGLE/renderer/gl/cgl/DisplayCGL.h',
+            'libANGLE/renderer/gl/cgl/IOSurfaceSurfaceCGL.mm',
+            'libANGLE/renderer/gl/cgl/IOSurfaceSurfaceCGL.h',
             'libANGLE/renderer/gl/cgl/PbufferSurfaceCGL.mm',
             'libANGLE/renderer/gl/cgl/PbufferSurfaceCGL.h',
             'libANGLE/renderer/gl/cgl/WindowSurfaceCGL.mm',
             'libANGLE/renderer/gl/cgl/WindowSurfaceCGL.h',
         ],
         'libangle_vulkan_sources':
         [
             'libANGLE/renderer/vulkan/BufferVk.cpp',
             'libANGLE/renderer/vulkan/BufferVk.h',
+            'libANGLE/renderer/vulkan/CommandBufferNode.cpp',
+            'libANGLE/renderer/vulkan/CommandBufferNode.h',
             'libANGLE/renderer/vulkan/CompilerVk.cpp',
             'libANGLE/renderer/vulkan/CompilerVk.h',
             'libANGLE/renderer/vulkan/ContextVk.cpp',
             'libANGLE/renderer/vulkan/ContextVk.h',
             'libANGLE/renderer/vulkan/DeviceVk.cpp',
             'libANGLE/renderer/vulkan/DeviceVk.h',
             'libANGLE/renderer/vulkan/DisplayVk.cpp',
             'libANGLE/renderer/vulkan/DisplayVk.h',
@@ -805,25 +821,29 @@
             'libGLESv2/entry_points_egl.cpp',
             'libGLESv2/entry_points_egl.h',
             'libGLESv2/entry_points_egl_ext.cpp',
             'libGLESv2/entry_points_egl_ext.h',
             'libGLESv2/entry_points_gles_2_0_autogen.cpp',
             'libGLESv2/entry_points_gles_2_0_autogen.h',
             'libGLESv2/entry_points_gles_2_0_ext.cpp',
             'libGLESv2/entry_points_gles_2_0_ext.h',
+            'libGLESv2/entry_points_gles_2_0_ext_autogen.cpp',
+            'libGLESv2/entry_points_gles_2_0_ext_autogen.h',
             'libGLESv2/entry_points_gles_3_0_autogen.cpp',
             'libGLESv2/entry_points_gles_3_0_autogen.h',
-            'libGLESv2/entry_points_gles_3_1.cpp',
-            'libGLESv2/entry_points_gles_3_1.h',
+            'libGLESv2/entry_points_gles_3_1_autogen.cpp',
+            'libGLESv2/entry_points_gles_3_1_autogen.h',
             'libGLESv2/global_state.cpp',
             'libGLESv2/global_state.h',
             'libGLESv2/libGLESv2.cpp',
             'libGLESv2/libGLESv2.def',
             'libGLESv2/libGLESv2.rc',
+            'libGLESv2/proc_table.h',
+            'libGLESv2/proc_table_autogen.cpp',
             'libGLESv2/resource.h',
         ],
         'libegl_sources':
         [
             'libEGL/libEGL.cpp',
             'libEGL/libEGL.def',
             'libEGL/libEGL.rc',
             'libEGL/resource.h',
@@ -898,21 +918,21 @@
                     }],
                     ['angle_enable_gl==1',
                     {
                         'defines':
                         [
                             'ANGLE_ENABLE_OPENGL',
                         ],
                     }],
-                    ['angle_enable_vulkan==1',
+                    ['angle_enable_gl_null==1',
                     {
                         'defines':
                         [
-                            'ANGLE_ENABLE_VULKAN',
+                            'ANGLE_ENABLE_OPENGL_NULL',
                         ],
                     }],
                     ['angle_enable_null==1',
                     {
                         'defines':
                         [
                             'ANGLE_ENABLE_NULL',
                         ],
@@ -945,16 +965,20 @@
             [
                 '<@(libangle_sources)',
                 '<@(libangle_includes)',
             ],
             'defines':
             [
                 'LIBANGLE_IMPLEMENTATION',
             ],
+            'msvs_disabled_warnings':
+            [
+                4577, # 'noexcept' used with no exception handling mode specified; termination on exception is not guaranteed.
+            ],
             'export_dependent_settings':
             [
                 'angle_common',
                 'libANGLE_d3d11_config',
                 'libANGLE_renderer_config',
             ],
             'direct_dependent_settings':
             {
@@ -1059,16 +1083,23 @@
                 ['angle_enable_gl==1',
                 {
                     'sources':
                     [
                         '<@(libangle_gl_sources)',
                     ],
                     'conditions':
                     [
+                        ['angle_enable_gl_null==1',
+                        {
+                            'sources':
+                            [
+                                '<@(libangle_gl_null_sources)',
+                            ],
+                        }],
                         ['OS=="win"',
                         {
                             'sources':
                             [
                                 '<@(libangle_gl_wgl_sources)',
                             ],
                         }],
                         ['angle_use_glx==1',
@@ -1149,48 +1180,16 @@
                             {
                                 'xcode_settings': {
                                     'LD_RUNPATH_SEARCH_PATHS': ['@executable_path/.'],
                                 },
                             }
                         }],
                     ],
                 }],
-                ['angle_enable_vulkan==1',
-                {
-                    'sources':
-                    [
-                        '<@(libangle_vulkan_sources)',
-                    ],
-                    'conditions':
-                    [
-                        ['OS=="win"',
-                        {
-                            'sources':
-                            [
-                                '<@(libangle_vulkan_win32_sources)',
-                            ],
-                        }],
-                        ['OS=="linux"',
-                        {
-                            'sources':
-                            [
-                                '<@(libangle_vulkan_xcb_sources)',
-                            ],
-                        }],
-                    ],
-                    'dependencies':
-                    [
-                        'angle_vulkan',
-                    ],
-                    'export_dependent_settings':
-                    [
-                        'angle_vulkan',
-                    ],
-                }],
                 ['angle_enable_null==1',
                 {
                     'sources':
                     [
                         '<@(libangle_null_sources)',
                     ],
                 }],
                 ['angle_build_winrt==0 and OS=="win"',
--- a/gfx/angle/src/libGLESv2/entry_points_egl.cpp
+++ b/gfx/angle/src/libGLESv2/entry_points_egl.cpp
@@ -2,44 +2,43 @@
 // 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.
 //
 
 // entry_points_egl.cpp : Implements the EGL entry points.
 
 #include "libGLESv2/entry_points_egl.h"
-#include "libGLESv2/entry_points_egl_ext.h"
-#include "libGLESv2/entry_points_gles_2_0_autogen.h"
-#include "libGLESv2/entry_points_gles_2_0_ext.h"
-#include "libGLESv2/entry_points_gles_3_0_autogen.h"
-#include "libGLESv2/entry_points_gles_3_1.h"
-#include "libGLESv2/global_state.h"
 
+#include "common/debug.h"
+#include "common/utilities.h"
+#include "common/version.h"
 #include "libANGLE/Context.h"
 #include "libANGLE/Display.h"
 #include "libANGLE/Surface.h"
 #include "libANGLE/Texture.h"
 #include "libANGLE/Thread.h"
 #include "libANGLE/queryutils.h"
 #include "libANGLE/validationEGL.h"
-
-#include "common/debug.h"
-#include "common/version.h"
-
-#include "platform/Platform.h"
+#include "libGLESv2/global_state.h"
+#include "libGLESv2/proc_table.h"
 
 #include <EGL/eglext.h>
 
 namespace egl
 {
 
 namespace
 {
 
+bool CompareProc(const ProcEntry &a, const char *b)
+{
+    return strcmp(a.first, b) < 0;
+}
+
 void ClipConfigs(const std::vector<const Config *> &filteredConfigs,
                  EGLConfig *output_configs,
                  EGLint config_size,
                  EGLint *num_config)
 {
     EGLint result_size = static_cast<EGLint>(filteredConfigs.size());
     if (output_configs)
     {
@@ -569,41 +568,24 @@ EGLBoolean EGLAPIENTRY QueryContext(EGLD
         "(EGLDisplay dpy = 0x%0.8p, EGLContext ctx = 0x%0.8p, EGLint attribute = %d, EGLint *value "
         "= 0x%0.8p)",
         dpy, ctx, attribute, value);
     Thread *thread = GetCurrentThread();
 
     Display *display     = static_cast<Display *>(dpy);
     gl::Context *context = static_cast<gl::Context *>(ctx);
 
-    Error error = ValidateContext(display, context);
+    Error error = ValidateQueryContext(display, context, attribute, value);
     if (error.isError())
     {
         thread->setError(error);
         return EGL_FALSE;
     }
 
-    switch (attribute)
-    {
-        case EGL_CONFIG_ID:
-            *value = context->getConfig()->configID;
-            break;
-        case EGL_CONTEXT_CLIENT_TYPE:
-            *value = context->getClientType();
-            break;
-        case EGL_CONTEXT_CLIENT_VERSION:
-            *value = context->getClientMajorVersion();
-            break;
-        case EGL_RENDER_BUFFER:
-            *value = context->getRenderBuffer();
-            break;
-        default:
-            thread->setError(EglBadAttribute());
-            return EGL_FALSE;
-    }
+    QueryContextAttrib(context, attribute, value);
 
     thread->setError(NoError());
     return EGL_TRUE;
 }
 
 EGLBoolean EGLAPIENTRY WaitGL(void)
 {
     EVENT("()");
@@ -774,17 +756,18 @@ EGLBoolean EGLAPIENTRY BindTexImage(EGLD
     {
         thread->setError(EglBadMatch());
         return EGL_FALSE;
     }
 
     gl::Context *context = thread->getContext();
     if (context)
     {
-        gl::Texture *textureObject = context->getTargetTexture(GL_TEXTURE_2D);
+        GLenum target = egl_gl::EGLTextureTargetToGLTextureTarget(eglSurface->getTextureTarget());
+        gl::Texture *textureObject = context->getTargetTexture(target);
         ASSERT(textureObject != nullptr);
 
         if (textureObject->getImmutableFormat())
         {
             thread->setError(EglBadMatch());
             return EGL_FALSE;
         }
 
@@ -1185,647 +1168,21 @@ EGLBoolean EGLAPIENTRY WaitSync(EGLDispl
     return EGL_FALSE;
 }
 
 __eglMustCastToProperFunctionPointerType EGLAPIENTRY GetProcAddress(const char *procname)
 {
     EVENT("(const char *procname = \"%s\")", procname);
     Thread *thread = GetCurrentThread();
 
-    typedef std::map<std::string, __eglMustCastToProperFunctionPointerType> ProcAddressMap;
-    auto generateProcAddressMap = []() {
-        ProcAddressMap map;
-#define INSERT_PROC_ADDRESS(ns, proc) \
-    map[#ns #proc] = reinterpret_cast<__eglMustCastToProperFunctionPointerType>(ns::proc)
-
-#define INSERT_PROC_ADDRESS_NO_NS(name, proc) \
-    map[name] = reinterpret_cast<__eglMustCastToProperFunctionPointerType>(proc)
-
-        // GLES2 core
-        INSERT_PROC_ADDRESS(gl, ActiveTexture);
-        INSERT_PROC_ADDRESS(gl, AttachShader);
-        INSERT_PROC_ADDRESS(gl, BindAttribLocation);
-        INSERT_PROC_ADDRESS(gl, BindBuffer);
-        INSERT_PROC_ADDRESS(gl, BindFramebuffer);
-        INSERT_PROC_ADDRESS(gl, BindRenderbuffer);
-        INSERT_PROC_ADDRESS(gl, BindTexture);
-        INSERT_PROC_ADDRESS(gl, BlendColor);
-        INSERT_PROC_ADDRESS(gl, BlendEquation);
-        INSERT_PROC_ADDRESS(gl, BlendEquationSeparate);
-        INSERT_PROC_ADDRESS(gl, BlendFunc);
-        INSERT_PROC_ADDRESS(gl, BlendFuncSeparate);
-        INSERT_PROC_ADDRESS(gl, BufferData);
-        INSERT_PROC_ADDRESS(gl, BufferSubData);
-        INSERT_PROC_ADDRESS(gl, CheckFramebufferStatus);
-        INSERT_PROC_ADDRESS(gl, Clear);
-        INSERT_PROC_ADDRESS(gl, ClearColor);
-        INSERT_PROC_ADDRESS(gl, ClearDepthf);
-        INSERT_PROC_ADDRESS(gl, ClearStencil);
-        INSERT_PROC_ADDRESS(gl, ColorMask);
-        INSERT_PROC_ADDRESS(gl, CompileShader);
-        INSERT_PROC_ADDRESS(gl, CompressedTexImage2D);
-        INSERT_PROC_ADDRESS(gl, CompressedTexSubImage2D);
-        INSERT_PROC_ADDRESS(gl, CopyTexImage2D);
-        INSERT_PROC_ADDRESS(gl, CopyTexSubImage2D);
-        INSERT_PROC_ADDRESS(gl, CreateProgram);
-        INSERT_PROC_ADDRESS(gl, CreateShader);
-        INSERT_PROC_ADDRESS(gl, CullFace);
-        INSERT_PROC_ADDRESS(gl, DeleteBuffers);
-        INSERT_PROC_ADDRESS(gl, DeleteFramebuffers);
-        INSERT_PROC_ADDRESS(gl, DeleteProgram);
-        INSERT_PROC_ADDRESS(gl, DeleteRenderbuffers);
-        INSERT_PROC_ADDRESS(gl, DeleteShader);
-        INSERT_PROC_ADDRESS(gl, DeleteTextures);
-        INSERT_PROC_ADDRESS(gl, DepthFunc);
-        INSERT_PROC_ADDRESS(gl, DepthMask);
-        INSERT_PROC_ADDRESS(gl, DepthRangef);
-        INSERT_PROC_ADDRESS(gl, DetachShader);
-        INSERT_PROC_ADDRESS(gl, Disable);
-        INSERT_PROC_ADDRESS(gl, DisableVertexAttribArray);
-        INSERT_PROC_ADDRESS(gl, DrawArrays);
-        INSERT_PROC_ADDRESS(gl, DrawElements);
-        INSERT_PROC_ADDRESS(gl, Enable);
-        INSERT_PROC_ADDRESS(gl, EnableVertexAttribArray);
-        INSERT_PROC_ADDRESS(gl, Finish);
-        INSERT_PROC_ADDRESS(gl, Flush);
-        INSERT_PROC_ADDRESS(gl, FramebufferRenderbuffer);
-        INSERT_PROC_ADDRESS(gl, FramebufferTexture2D);
-        INSERT_PROC_ADDRESS(gl, FrontFace);
-        INSERT_PROC_ADDRESS(gl, GenBuffers);
-        INSERT_PROC_ADDRESS(gl, GenerateMipmap);
-        INSERT_PROC_ADDRESS(gl, GenFramebuffers);
-        INSERT_PROC_ADDRESS(gl, GenRenderbuffers);
-        INSERT_PROC_ADDRESS(gl, GenTextures);
-        INSERT_PROC_ADDRESS(gl, GetActiveAttrib);
-        INSERT_PROC_ADDRESS(gl, GetActiveUniform);
-        INSERT_PROC_ADDRESS(gl, GetAttachedShaders);
-        INSERT_PROC_ADDRESS(gl, GetAttribLocation);
-        INSERT_PROC_ADDRESS(gl, GetBooleanv);
-        INSERT_PROC_ADDRESS(gl, GetBufferParameteriv);
-        INSERT_PROC_ADDRESS(gl, GetError);
-        INSERT_PROC_ADDRESS(gl, GetFloatv);
-        INSERT_PROC_ADDRESS(gl, GetFramebufferAttachmentParameteriv);
-        INSERT_PROC_ADDRESS(gl, GetIntegerv);
-        INSERT_PROC_ADDRESS(gl, GetProgramiv);
-        INSERT_PROC_ADDRESS(gl, GetProgramInfoLog);
-        INSERT_PROC_ADDRESS(gl, GetRenderbufferParameteriv);
-        INSERT_PROC_ADDRESS(gl, GetShaderiv);
-        INSERT_PROC_ADDRESS(gl, GetShaderInfoLog);
-        INSERT_PROC_ADDRESS(gl, GetShaderPrecisionFormat);
-        INSERT_PROC_ADDRESS(gl, GetShaderSource);
-        INSERT_PROC_ADDRESS(gl, GetString);
-        INSERT_PROC_ADDRESS(gl, GetTexParameterfv);
-        INSERT_PROC_ADDRESS(gl, GetTexParameteriv);
-        INSERT_PROC_ADDRESS(gl, GetUniformfv);
-        INSERT_PROC_ADDRESS(gl, GetUniformiv);
-        INSERT_PROC_ADDRESS(gl, GetUniformLocation);
-        INSERT_PROC_ADDRESS(gl, GetVertexAttribfv);
-        INSERT_PROC_ADDRESS(gl, GetVertexAttribiv);
-        INSERT_PROC_ADDRESS(gl, GetVertexAttribPointerv);
-        INSERT_PROC_ADDRESS(gl, Hint);
-        INSERT_PROC_ADDRESS(gl, IsBuffer);
-        INSERT_PROC_ADDRESS(gl, IsEnabled);
-        INSERT_PROC_ADDRESS(gl, IsFramebuffer);
-        INSERT_PROC_ADDRESS(gl, IsProgram);
-        INSERT_PROC_ADDRESS(gl, IsRenderbuffer);
-        INSERT_PROC_ADDRESS(gl, IsShader);
-        INSERT_PROC_ADDRESS(gl, IsTexture);
-        INSERT_PROC_ADDRESS(gl, LineWidth);
-        INSERT_PROC_ADDRESS(gl, LinkProgram);
-        INSERT_PROC_ADDRESS(gl, PixelStorei);
-        INSERT_PROC_ADDRESS(gl, PolygonOffset);
-        INSERT_PROC_ADDRESS(gl, ReadPixels);
-        INSERT_PROC_ADDRESS(gl, ReleaseShaderCompiler);
-        INSERT_PROC_ADDRESS(gl, RenderbufferStorage);
-        INSERT_PROC_ADDRESS(gl, SampleCoverage);
-        INSERT_PROC_ADDRESS(gl, Scissor);
-        INSERT_PROC_ADDRESS(gl, ShaderBinary);
-        INSERT_PROC_ADDRESS(gl, ShaderSource);
-        INSERT_PROC_ADDRESS(gl, StencilFunc);
-        INSERT_PROC_ADDRESS(gl, StencilFuncSeparate);
-        INSERT_PROC_ADDRESS(gl, StencilMask);
-        INSERT_PROC_ADDRESS(gl, StencilMaskSeparate);
-        INSERT_PROC_ADDRESS(gl, StencilOp);
-        INSERT_PROC_ADDRESS(gl, StencilOpSeparate);
-        INSERT_PROC_ADDRESS(gl, TexImage2D);
-        INSERT_PROC_ADDRESS(gl, TexParameterf);
-        INSERT_PROC_ADDRESS(gl, TexParameterfv);
-        INSERT_PROC_ADDRESS(gl, TexParameteri);
-        INSERT_PROC_ADDRESS(gl, TexParameteriv);
-        INSERT_PROC_ADDRESS(gl, TexSubImage2D);
-        INSERT_PROC_ADDRESS(gl, Uniform1f);
-        INSERT_PROC_ADDRESS(gl, Uniform1fv);
-        INSERT_PROC_ADDRESS(gl, Uniform1i);
-        INSERT_PROC_ADDRESS(gl, Uniform1iv);
-        INSERT_PROC_ADDRESS(gl, Uniform2f);
-        INSERT_PROC_ADDRESS(gl, Uniform2fv);
-        INSERT_PROC_ADDRESS(gl, Uniform2i);
-        INSERT_PROC_ADDRESS(gl, Uniform2iv);
-        INSERT_PROC_ADDRESS(gl, Uniform3f);
-        INSERT_PROC_ADDRESS(gl, Uniform3fv);
-        INSERT_PROC_ADDRESS(gl, Uniform3i);
-        INSERT_PROC_ADDRESS(gl, Uniform3iv);
-        INSERT_PROC_ADDRESS(gl, Uniform4f);
-        INSERT_PROC_ADDRESS(gl, Uniform4fv);
-        INSERT_PROC_ADDRESS(gl, Uniform4i);
-        INSERT_PROC_ADDRESS(gl, Uniform4iv);
-        INSERT_PROC_ADDRESS(gl, UniformMatrix2fv);
-        INSERT_PROC_ADDRESS(gl, UniformMatrix3fv);
-        INSERT_PROC_ADDRESS(gl, UniformMatrix4fv);
-        INSERT_PROC_ADDRESS(gl, UseProgram);
-        INSERT_PROC_ADDRESS(gl, ValidateProgram);
-        INSERT_PROC_ADDRESS(gl, VertexAttrib1f);
-        INSERT_PROC_ADDRESS(gl, VertexAttrib1fv);
-        INSERT_PROC_ADDRESS(gl, VertexAttrib2f);
-        INSERT_PROC_ADDRESS(gl, VertexAttrib2fv);
-        INSERT_PROC_ADDRESS(gl, VertexAttrib3f);
-        INSERT_PROC_ADDRESS(gl, VertexAttrib3fv);
-        INSERT_PROC_ADDRESS(gl, VertexAttrib4f);
-        INSERT_PROC_ADDRESS(gl, VertexAttrib4fv);
-        INSERT_PROC_ADDRESS(gl, VertexAttribPointer);
-        INSERT_PROC_ADDRESS(gl, Viewport);
-
-        // GL_ANGLE_framebuffer_blit
-        INSERT_PROC_ADDRESS(gl, BlitFramebufferANGLE);
-
-        // GL_ANGLE_framebuffer_multisample
-        INSERT_PROC_ADDRESS(gl, RenderbufferStorageMultisampleANGLE);
-
-        // GL_EXT_discard_framebuffer
-        INSERT_PROC_ADDRESS(gl, DiscardFramebufferEXT);
-
-        // GL_NV_fence
-        INSERT_PROC_ADDRESS(gl, DeleteFencesNV);
-        INSERT_PROC_ADDRESS(gl, GenFencesNV);
-        INSERT_PROC_ADDRESS(gl, IsFenceNV);
-        INSERT_PROC_ADDRESS(gl, TestFenceNV);
-        INSERT_PROC_ADDRESS(gl, GetFenceivNV);
-        INSERT_PROC_ADDRESS(gl, FinishFenceNV);
-        INSERT_PROC_ADDRESS(gl, SetFenceNV);
-
-        // GL_ANGLE_translated_shader_source
-        INSERT_PROC_ADDRESS(gl, GetTranslatedShaderSourceANGLE);
-
-        // GL_EXT_texture_storage
-        INSERT_PROC_ADDRESS(gl, TexStorage2DEXT);
-
-        // GL_EXT_robustness
-        INSERT_PROC_ADDRESS(gl, GetGraphicsResetStatusEXT);
-        INSERT_PROC_ADDRESS(gl, ReadnPixelsEXT);
-        INSERT_PROC_ADDRESS(gl, GetnUniformfvEXT);
-        INSERT_PROC_ADDRESS(gl, GetnUniformivEXT);
-
-        // GL_EXT_occlusion_query_boolean
-        INSERT_PROC_ADDRESS(gl, GenQueriesEXT);
-        INSERT_PROC_ADDRESS(gl, DeleteQueriesEXT);
-        INSERT_PROC_ADDRESS(gl, IsQueryEXT);
-        INSERT_PROC_ADDRESS(gl, BeginQueryEXT);
-        INSERT_PROC_ADDRESS(gl, EndQueryEXT);
-        INSERT_PROC_ADDRESS(gl, GetQueryivEXT);
-        INSERT_PROC_ADDRESS(gl, GetQueryObjectuivEXT);
-
-        // GL_EXT_disjoint_timer_query
-        // Commented out functions are needed for GL_EXT_disjoint_timer_query
-        // but are pulled in by GL_EXT_occlusion_query_boolean.
-        // INSERT_PROC_ADDRESS(gl, GenQueriesEXT);
-        // INSERT_PROC_ADDRESS(gl, DeleteQueriesEXT);
-        // INSERT_PROC_ADDRESS(gl, IsQueryEXT);
-        // INSERT_PROC_ADDRESS(gl, BeginQueryEXT);
-        // INSERT_PROC_ADDRESS(gl, EndQueryEXT);
-        INSERT_PROC_ADDRESS(gl, QueryCounterEXT);
-        // INSERT_PROC_ADDRESS(gl, GetQueryivEXT);
-        INSERT_PROC_ADDRESS(gl, GetQueryObjectivEXT);
-        // INSERT_PROC_ADDRESS(gl, GetQueryObjectuivEXT);
-        INSERT_PROC_ADDRESS(gl, GetQueryObjecti64vEXT);
-        INSERT_PROC_ADDRESS(gl, GetQueryObjectui64vEXT);
-
-        // GL_EXT_draw_buffers
-        INSERT_PROC_ADDRESS(gl, DrawBuffersEXT);
-
-        // GL_ANGLE_instanced_arrays
-        INSERT_PROC_ADDRESS(gl, DrawArraysInstancedANGLE);
-        INSERT_PROC_ADDRESS(gl, DrawElementsInstancedANGLE);
-        INSERT_PROC_ADDRESS(gl, VertexAttribDivisorANGLE);
-
-        // GL_OES_get_program_binary
-        INSERT_PROC_ADDRESS(gl, GetProgramBinaryOES);
-        INSERT_PROC_ADDRESS(gl, ProgramBinaryOES);
-
-        // GL_OES_mapbuffer
-        INSERT_PROC_ADDRESS(gl, MapBufferOES);
-        INSERT_PROC_ADDRESS(gl, UnmapBufferOES);
-        INSERT_PROC_ADDRESS(gl, GetBufferPointervOES);
-
-        // GL_EXT_map_buffer_range
-        INSERT_PROC_ADDRESS(gl, MapBufferRangeEXT);
-        INSERT_PROC_ADDRESS(gl, FlushMappedBufferRangeEXT);
-
-        // GL_EXT_debug_marker
-        INSERT_PROC_ADDRESS(gl, InsertEventMarkerEXT);
-        INSERT_PROC_ADDRESS(gl, PushGroupMarkerEXT);
-        INSERT_PROC_ADDRESS(gl, PopGroupMarkerEXT);
-
-        // GL_OES_EGL_image
-        INSERT_PROC_ADDRESS(gl, EGLImageTargetTexture2DOES);
-        INSERT_PROC_ADDRESS(gl, EGLImageTargetRenderbufferStorageOES);
-
-        // GL_OES_vertex_array_object
-        INSERT_PROC_ADDRESS(gl, BindVertexArrayOES);
-        INSERT_PROC_ADDRESS(gl, DeleteVertexArraysOES);
-        INSERT_PROC_ADDRESS(gl, GenVertexArraysOES);
-        INSERT_PROC_ADDRESS(gl, IsVertexArrayOES);
-
-        // GL_KHR_debug
-        INSERT_PROC_ADDRESS(gl, DebugMessageControlKHR);
-        INSERT_PROC_ADDRESS(gl, DebugMessageInsertKHR);
-        INSERT_PROC_ADDRESS(gl, DebugMessageCallbackKHR);
-        INSERT_PROC_ADDRESS(gl, GetDebugMessageLogKHR);
-        INSERT_PROC_ADDRESS(gl, PushDebugGroupKHR);
-        INSERT_PROC_ADDRESS(gl, PopDebugGroupKHR);
-        INSERT_PROC_ADDRESS(gl, ObjectLabelKHR);
-        INSERT_PROC_ADDRESS(gl, GetObjectLabelKHR);
-        INSERT_PROC_ADDRESS(gl, ObjectPtrLabelKHR);
-        INSERT_PROC_ADDRESS(gl, GetObjectPtrLabelKHR);
-        INSERT_PROC_ADDRESS(gl, GetPointervKHR);
-
-        // GL_CHROMIUM_bind_uniform_location
-        INSERT_PROC_ADDRESS(gl, BindUniformLocationCHROMIUM);
-
-        // GL_CHROMIUM_copy_texture
-        INSERT_PROC_ADDRESS(gl, CopyTextureCHROMIUM);
-        INSERT_PROC_ADDRESS(gl, CopySubTextureCHROMIUM);
-
-        // GL_CHROMIUM_copy_compressed_texture
-        INSERT_PROC_ADDRESS(gl, CompressedCopyTextureCHROMIUM);
-
-        // GL_ANGLE_request_extension
-        INSERT_PROC_ADDRESS(gl, RequestExtensionANGLE);
-
-        // GL_ANGLE_robust_client_memory
-        INSERT_PROC_ADDRESS(gl, GetBooleanvRobustANGLE);
-        INSERT_PROC_ADDRESS(gl, GetBufferParameterivRobustANGLE);
-        INSERT_PROC_ADDRESS(gl, GetFloatvRobustANGLE);
-        INSERT_PROC_ADDRESS(gl, GetFramebufferAttachmentParameterivRobustANGLE);
-        INSERT_PROC_ADDRESS(gl, GetIntegervRobustANGLE);
-        INSERT_PROC_ADDRESS(gl, GetProgramivRobustANGLE);
-        INSERT_PROC_ADDRESS(gl, GetRenderbufferParameterivRobustANGLE);
-        INSERT_PROC_ADDRESS(gl, GetShaderivRobustANGLE);
-        INSERT_PROC_ADDRESS(gl, GetTexParameterfvRobustANGLE);
-        INSERT_PROC_ADDRESS(gl, GetTexParameterivRobustANGLE);
-        INSERT_PROC_ADDRESS(gl, GetUniformfvRobustANGLE);
-        INSERT_PROC_ADDRESS(gl, GetUniformivRobustANGLE);
-        INSERT_PROC_ADDRESS(gl, GetVertexAttribfvRobustANGLE);
-        INSERT_PROC_ADDRESS(gl, GetVertexAttribivRobustANGLE);
-        INSERT_PROC_ADDRESS(gl, GetVertexAttribPointervRobustANGLE);
-        INSERT_PROC_ADDRESS(gl, ReadPixelsRobustANGLE);
-        INSERT_PROC_ADDRESS(gl, TexImage2DRobustANGLE);
-        INSERT_PROC_ADDRESS(gl, TexParameterfvRobustANGLE);
-        INSERT_PROC_ADDRESS(gl, TexParameterivRobustANGLE);
-        INSERT_PROC_ADDRESS(gl, TexSubImage2DRobustANGLE);
-        INSERT_PROC_ADDRESS(gl, TexImage3DRobustANGLE);
-        INSERT_PROC_ADDRESS(gl, TexSubImage3DRobustANGLE);
-        INSERT_PROC_ADDRESS(gl, CompressedTexImage2DRobustANGLE);
-        INSERT_PROC_ADDRESS(gl, CompressedTexSubImage2DRobustANGLE);
-        INSERT_PROC_ADDRESS(gl, CompressedTexImage3DRobustANGLE);
-        INSERT_PROC_ADDRESS(gl, CompressedTexSubImage3DRobustANGLE);
-        INSERT_PROC_ADDRESS(gl, GetQueryivRobustANGLE);
-        INSERT_PROC_ADDRESS(gl, GetQueryObjectuivRobustANGLE);
-        INSERT_PROC_ADDRESS(gl, GetBufferPointervRobustANGLE);
-        INSERT_PROC_ADDRESS(gl, GetIntegeri_vRobustANGLE);
-        INSERT_PROC_ADDRESS(gl, GetInternalformativRobustANGLE);
-        INSERT_PROC_ADDRESS(gl, GetVertexAttribIivRobustANGLE);
-        INSERT_PROC_ADDRESS(gl, GetVertexAttribIuivRobustANGLE);
-        INSERT_PROC_ADDRESS(gl, GetUniformuivRobustANGLE);
-        INSERT_PROC_ADDRESS(gl, GetActiveUniformBlockivRobustANGLE);
-        INSERT_PROC_ADDRESS(gl, GetInteger64vRobustANGLE);
-        INSERT_PROC_ADDRESS(gl, GetInteger64i_vRobustANGLE);
-        INSERT_PROC_ADDRESS(gl, GetBufferParameteri64vRobustANGLE);
-        INSERT_PROC_ADDRESS(gl, SamplerParameterivRobustANGLE);
-        INSERT_PROC_ADDRESS(gl, SamplerParameterfvRobustANGLE);
-        INSERT_PROC_ADDRESS(gl, GetSamplerParameterivRobustANGLE);
-        INSERT_PROC_ADDRESS(gl, GetSamplerParameterfvRobustANGLE);
-        INSERT_PROC_ADDRESS(gl, GetFramebufferParameterivRobustANGLE);
-        INSERT_PROC_ADDRESS(gl, GetProgramInterfaceivRobustANGLE);
-        INSERT_PROC_ADDRESS(gl, GetBooleani_vRobustANGLE);
-        INSERT_PROC_ADDRESS(gl, GetMultisamplefvRobustANGLE);
-        INSERT_PROC_ADDRESS(gl, GetTexLevelParameterivRobustANGLE);
-        INSERT_PROC_ADDRESS(gl, GetTexLevelParameterfvRobustANGLE);
-        INSERT_PROC_ADDRESS(gl, GetPointervRobustANGLERobustANGLE);
-        INSERT_PROC_ADDRESS(gl, ReadnPixelsRobustANGLE);
-        INSERT_PROC_ADDRESS(gl, GetnUniformfvRobustANGLE);
-        INSERT_PROC_ADDRESS(gl, GetnUniformivRobustANGLE);
-        INSERT_PROC_ADDRESS(gl, GetnUniformuivRobustANGLE);
-        INSERT_PROC_ADDRESS(gl, TexParameterIivRobustANGLE);
-        INSERT_PROC_ADDRESS(gl, TexParameterIuivRobustANGLE);
-        INSERT_PROC_ADDRESS(gl, GetTexParameterIivRobustANGLE);
-        INSERT_PROC_ADDRESS(gl, GetTexParameterIuivRobustANGLE);
-        INSERT_PROC_ADDRESS(gl, SamplerParameterIivRobustANGLE);
-        INSERT_PROC_ADDRESS(gl, SamplerParameterIuivRobustANGLE);
-        INSERT_PROC_ADDRESS(gl, GetSamplerParameterIivRobustANGLE);
-        INSERT_PROC_ADDRESS(gl, GetSamplerParameterIuivRobustANGLE);
-        INSERT_PROC_ADDRESS(gl, GetQueryObjectivRobustANGLE);
-        INSERT_PROC_ADDRESS(gl, GetQueryObjecti64vRobustANGLE);
-        INSERT_PROC_ADDRESS(gl, GetQueryObjectui64vRobustANGLE);
-
-        // GL_ANGLE_multiview
-        INSERT_PROC_ADDRESS(gl, FramebufferTextureMultiviewLayeredANGLE);
-        INSERT_PROC_ADDRESS(gl, FramebufferTextureMultiviewSideBySideANGLE);
-
-        // GLES3 core
-        INSERT_PROC_ADDRESS(gl, ReadBuffer);
-        INSERT_PROC_ADDRESS(gl, DrawRangeElements);
-        INSERT_PROC_ADDRESS(gl, TexImage3D);
-        INSERT_PROC_ADDRESS(gl, TexSubImage3D);
-        INSERT_PROC_ADDRESS(gl, CopyTexSubImage3D);
-        INSERT_PROC_ADDRESS(gl, CompressedTexImage3D);
-        INSERT_PROC_ADDRESS(gl, CompressedTexSubImage3D);
-        INSERT_PROC_ADDRESS(gl, GenQueries);
-        INSERT_PROC_ADDRESS(gl, DeleteQueries);
-        INSERT_PROC_ADDRESS(gl, IsQuery);
-        INSERT_PROC_ADDRESS(gl, BeginQuery);
-        INSERT_PROC_ADDRESS(gl, EndQuery);
-        INSERT_PROC_ADDRESS(gl, GetQueryiv);
-        INSERT_PROC_ADDRESS(gl, GetQueryObjectuiv);
-        INSERT_PROC_ADDRESS(gl, UnmapBuffer);
-        INSERT_PROC_ADDRESS(gl, GetBufferPointerv);
-        INSERT_PROC_ADDRESS(gl, DrawBuffers);
-        INSERT_PROC_ADDRESS(gl, UniformMatrix2x3fv);
-        INSERT_PROC_ADDRESS(gl, UniformMatrix3x2fv);
-        INSERT_PROC_ADDRESS(gl, UniformMatrix2x4fv);
-        INSERT_PROC_ADDRESS(gl, UniformMatrix4x2fv);
-        INSERT_PROC_ADDRESS(gl, UniformMatrix3x4fv);
-        INSERT_PROC_ADDRESS(gl, UniformMatrix4x3fv);
-        INSERT_PROC_ADDRESS(gl, BlitFramebuffer);
-        INSERT_PROC_ADDRESS(gl, RenderbufferStorageMultisample);
-        INSERT_PROC_ADDRESS(gl, FramebufferTextureLayer);
-        INSERT_PROC_ADDRESS(gl, MapBufferRange);
-        INSERT_PROC_ADDRESS(gl, FlushMappedBufferRange);
-        INSERT_PROC_ADDRESS(gl, BindVertexArray);
-        INSERT_PROC_ADDRESS(gl, DeleteVertexArrays);
-        INSERT_PROC_ADDRESS(gl, GenVertexArrays);
-        INSERT_PROC_ADDRESS(gl, IsVertexArray);
-        INSERT_PROC_ADDRESS(gl, GetIntegeri_v);
-        INSERT_PROC_ADDRESS(gl, BeginTransformFeedback);
-        INSERT_PROC_ADDRESS(gl, EndTransformFeedback);
-        INSERT_PROC_ADDRESS(gl, BindBufferRange);
-        INSERT_PROC_ADDRESS(gl, BindBufferBase);
-        INSERT_PROC_ADDRESS(gl, TransformFeedbackVaryings);
-        INSERT_PROC_ADDRESS(gl, GetTransformFeedbackVarying);
-        INSERT_PROC_ADDRESS(gl, VertexAttribIPointer);
-        INSERT_PROC_ADDRESS(gl, GetVertexAttribIiv);
-        INSERT_PROC_ADDRESS(gl, GetVertexAttribIuiv);
-        INSERT_PROC_ADDRESS(gl, VertexAttribI4i);
-        INSERT_PROC_ADDRESS(gl, VertexAttribI4ui);
-        INSERT_PROC_ADDRESS(gl, VertexAttribI4iv);
-        INSERT_PROC_ADDRESS(gl, VertexAttribI4uiv);
-        INSERT_PROC_ADDRESS(gl, GetUniformuiv);
-        INSERT_PROC_ADDRESS(gl, GetFragDataLocation);
-        INSERT_PROC_ADDRESS(gl, Uniform1ui);
-        INSERT_PROC_ADDRESS(gl, Uniform2ui);
-        INSERT_PROC_ADDRESS(gl, Uniform3ui);
-        INSERT_PROC_ADDRESS(gl, Uniform4ui);
-        INSERT_PROC_ADDRESS(gl, Uniform1uiv);
-        INSERT_PROC_ADDRESS(gl, Uniform2uiv);
-        INSERT_PROC_ADDRESS(gl, Uniform3uiv);
-        INSERT_PROC_ADDRESS(gl, Uniform4uiv);
-        INSERT_PROC_ADDRESS(gl, ClearBufferiv);
-        INSERT_PROC_ADDRESS(gl, ClearBufferuiv);
-        INSERT_PROC_ADDRESS(gl, ClearBufferfv);
-        INSERT_PROC_ADDRESS(gl, ClearBufferfi);
-        INSERT_PROC_ADDRESS(gl, GetStringi);
-        INSERT_PROC_ADDRESS(gl, CopyBufferSubData);
-        INSERT_PROC_ADDRESS(gl, GetUniformIndices);
-        INSERT_PROC_ADDRESS(gl, GetActiveUniformsiv);
-        INSERT_PROC_ADDRESS(gl, GetUniformBlockIndex);
-        INSERT_PROC_ADDRESS(gl, GetActiveUniformBlockiv);
-        INSERT_PROC_ADDRESS(gl, GetActiveUniformBlockName);
-        INSERT_PROC_ADDRESS(gl, UniformBlockBinding);
-        INSERT_PROC_ADDRESS(gl, DrawArraysInstanced);
-        INSERT_PROC_ADDRESS(gl, DrawElementsInstanced);
-        INSERT_PROC_ADDRESS(gl, FenceSync);
-        INSERT_PROC_ADDRESS(gl, IsSync);
-        INSERT_PROC_ADDRESS(gl, DeleteSync);
-        INSERT_PROC_ADDRESS(gl, ClientWaitSync);
-        INSERT_PROC_ADDRESS(gl, WaitSync);
-        INSERT_PROC_ADDRESS(gl, GetInteger64v);
-        INSERT_PROC_ADDRESS(gl, GetSynciv);
-        INSERT_PROC_ADDRESS(gl, GetInteger64i_v);
-        INSERT_PROC_ADDRESS(gl, GetBufferParameteri64v);
-        INSERT_PROC_ADDRESS(gl, GenSamplers);
-        INSERT_PROC_ADDRESS(gl, DeleteSamplers);
-        INSERT_PROC_ADDRESS(gl, IsSampler);
-        INSERT_PROC_ADDRESS(gl, BindSampler);
-        INSERT_PROC_ADDRESS(gl, SamplerParameteri);
-        INSERT_PROC_ADDRESS(gl, SamplerParameteriv);
-        INSERT_PROC_ADDRESS(gl, SamplerParameterf);
-        INSERT_PROC_ADDRESS(gl, SamplerParameterfv);
-        INSERT_PROC_ADDRESS(gl, GetSamplerParameteriv);
-        INSERT_PROC_ADDRESS(gl, GetSamplerParameterfv);
-        INSERT_PROC_ADDRESS(gl, VertexAttribDivisor);
-        INSERT_PROC_ADDRESS(gl, BindTransformFeedback);
-        INSERT_PROC_ADDRESS(gl, DeleteTransformFeedbacks);
-        INSERT_PROC_ADDRESS(gl, GenTransformFeedbacks);
-        INSERT_PROC_ADDRESS(gl, IsTransformFeedback);
-        INSERT_PROC_ADDRESS(gl, PauseTransformFeedback);
-        INSERT_PROC_ADDRESS(gl, ResumeTransformFeedback);
-        INSERT_PROC_ADDRESS(gl, GetProgramBinary);
-        INSERT_PROC_ADDRESS(gl, ProgramBinary);
-        INSERT_PROC_ADDRESS(gl, ProgramParameteri);
-        INSERT_PROC_ADDRESS(gl, InvalidateFramebuffer);
-        INSERT_PROC_ADDRESS(gl, InvalidateSubFramebuffer);
-        INSERT_PROC_ADDRESS(gl, TexStorage2D);
-        INSERT_PROC_ADDRESS(gl, TexStorage3D);
-        INSERT_PROC_ADDRESS(gl, GetInternalformativ);
-
-        // GLES31 core
-        INSERT_PROC_ADDRESS(gl, DispatchCompute);
-        INSERT_PROC_ADDRESS(gl, DispatchComputeIndirect);
-        INSERT_PROC_ADDRESS(gl, DrawArraysIndirect);
-        INSERT_PROC_ADDRESS(gl, DrawElementsIndirect);
-        INSERT_PROC_ADDRESS(gl, FramebufferParameteri);
-        INSERT_PROC_ADDRESS(gl, GetFramebufferParameteriv);
-        INSERT_PROC_ADDRESS(gl, GetProgramInterfaceiv);
-        INSERT_PROC_ADDRESS(gl, GetProgramResourceIndex);
-        INSERT_PROC_ADDRESS(gl, GetProgramResourceName);
-        INSERT_PROC_ADDRESS(gl, GetProgramResourceiv);
-        INSERT_PROC_ADDRESS(gl, GetProgramResourceLocation);
-        INSERT_PROC_ADDRESS(gl, UseProgramStages);
-        INSERT_PROC_ADDRESS(gl, ActiveShaderProgram);
-        INSERT_PROC_ADDRESS(gl, CreateShaderProgramv);
-        INSERT_PROC_ADDRESS(gl, BindProgramPipeline);
-        INSERT_PROC_ADDRESS(gl, DeleteProgramPipelines);
-        INSERT_PROC_ADDRESS(gl, GenProgramPipelines);
-        INSERT_PROC_ADDRESS(gl, IsProgramPipeline);
-        INSERT_PROC_ADDRESS(gl, GetProgramPipelineiv);
-        INSERT_PROC_ADDRESS(gl, ProgramUniform1i);
-        INSERT_PROC_ADDRESS(gl, ProgramUniform2i);
-        INSERT_PROC_ADDRESS(gl, ProgramUniform3i);
-        INSERT_PROC_ADDRESS(gl, ProgramUniform4i);
-        INSERT_PROC_ADDRESS(gl, ProgramUniform1ui);
-        INSERT_PROC_ADDRESS(gl, ProgramUniform2ui);
-        INSERT_PROC_ADDRESS(gl, ProgramUniform3ui);
-        INSERT_PROC_ADDRESS(gl, ProgramUniform4ui);
-        INSERT_PROC_ADDRESS(gl, ProgramUniform1f);
-        INSERT_PROC_ADDRESS(gl, ProgramUniform2f);
-        INSERT_PROC_ADDRESS(gl, ProgramUniform3f);
-        INSERT_PROC_ADDRESS(gl, ProgramUniform4f);
-        INSERT_PROC_ADDRESS(gl, ProgramUniform1iv);
-        INSERT_PROC_ADDRESS(gl, ProgramUniform2iv);
-        INSERT_PROC_ADDRESS(gl, ProgramUniform3iv);
-        INSERT_PROC_ADDRESS(gl, ProgramUniform4iv);
-        INSERT_PROC_ADDRESS(gl, ProgramUniform1uiv);
-        INSERT_PROC_ADDRESS(gl, ProgramUniform2uiv);
-        INSERT_PROC_ADDRESS(gl, ProgramUniform3uiv);
-        INSERT_PROC_ADDRESS(gl, ProgramUniform4uiv);
-        INSERT_PROC_ADDRESS(gl, ProgramUniform1fv);
-        INSERT_PROC_ADDRESS(gl, ProgramUniform2fv);
-        INSERT_PROC_ADDRESS(gl, ProgramUniform3fv);
-        INSERT_PROC_ADDRESS(gl, ProgramUniform4fv);
-        INSERT_PROC_ADDRESS(gl, ProgramUniformMatrix2fv);
-        INSERT_PROC_ADDRESS(gl, ProgramUniformMatrix3fv);
-        INSERT_PROC_ADDRESS(gl, ProgramUniformMatrix4fv);
-        INSERT_PROC_ADDRESS(gl, ProgramUniformMatrix2x3fv);
-        INSERT_PROC_ADDRESS(gl, ProgramUniformMatrix3x2fv);
-        INSERT_PROC_ADDRESS(gl, ProgramUniformMatrix2x4fv);
-        INSERT_PROC_ADDRESS(gl, ProgramUniformMatrix4x2fv);
-        INSERT_PROC_ADDRESS(gl, ProgramUniformMatrix3x4fv);
-        INSERT_PROC_ADDRESS(gl, ProgramUniformMatrix4x3fv);
-        INSERT_PROC_ADDRESS(gl, ValidateProgramPipeline);
-        INSERT_PROC_ADDRESS(gl, GetProgramPipelineInfoLog);
-        INSERT_PROC_ADDRESS(gl, BindImageTexture);
-        INSERT_PROC_ADDRESS(gl, GetBooleani_v);
-        INSERT_PROC_ADDRESS(gl, MemoryBarrier);
-        INSERT_PROC_ADDRESS(gl, MemoryBarrierByRegion);
-        INSERT_PROC_ADDRESS(gl, TexStorage2DMultisample);
-        INSERT_PROC_ADDRESS(gl, GetMultisamplefv);
-        INSERT_PROC_ADDRESS(gl, SampleMaski);
-        INSERT_PROC_ADDRESS(gl, GetTexLevelParameteriv);
-        INSERT_PROC_ADDRESS(gl, GetTexLevelParameterfv);
-        INSERT_PROC_ADDRESS(gl, BindVertexBuffer);
-        INSERT_PROC_ADDRESS(gl, VertexAttribFormat);
-        INSERT_PROC_ADDRESS(gl, VertexAttribIFormat);
-        INSERT_PROC_ADDRESS(gl, VertexAttribBinding);
-        INSERT_PROC_ADDRESS(gl, VertexBindingDivisor);
-
-        // EGL 1.0
-        INSERT_PROC_ADDRESS(egl, ChooseConfig);
-        INSERT_PROC_ADDRESS(egl, CopyBuffers);
-        INSERT_PROC_ADDRESS(egl, CreateContext);
-        INSERT_PROC_ADDRESS(egl, CreatePbufferSurface);
-        INSERT_PROC_ADDRESS(egl, CreatePixmapSurface);
-        INSERT_PROC_ADDRESS(egl, CreateWindowSurface);
-        INSERT_PROC_ADDRESS(egl, DestroyContext);
-        INSERT_PROC_ADDRESS(egl, DestroySurface);
-        INSERT_PROC_ADDRESS(egl, GetConfigAttrib);
-        INSERT_PROC_ADDRESS(egl, GetConfigs);
-        INSERT_PROC_ADDRESS(egl, GetCurrentDisplay);
-        INSERT_PROC_ADDRESS(egl, GetCurrentSurface);
-        INSERT_PROC_ADDRESS(egl, GetDisplay);
-        INSERT_PROC_ADDRESS(egl, GetError);
-        INSERT_PROC_ADDRESS(egl, GetProcAddress);
-        INSERT_PROC_ADDRESS(egl, Initialize);
-        INSERT_PROC_ADDRESS(egl, MakeCurrent);
-        INSERT_PROC_ADDRESS(egl, QueryContext);
-        INSERT_PROC_ADDRESS(egl, QueryString);
-        INSERT_PROC_ADDRESS(egl, QuerySurface);
-        INSERT_PROC_ADDRESS(egl, SwapBuffers);
-        INSERT_PROC_ADDRESS(egl, Terminate);
-        INSERT_PROC_ADDRESS(egl, WaitGL);
-        INSERT_PROC_ADDRESS(egl, WaitNative);
-
-        // EGL 1.1
-        INSERT_PROC_ADDRESS(egl, BindTexImage);
-        INSERT_PROC_ADDRESS(egl, ReleaseTexImage);
-        INSERT_PROC_ADDRESS(egl, SurfaceAttrib);
-        INSERT_PROC_ADDRESS(egl, SwapInterval);
-
-        // EGL 1.2
-        INSERT_PROC_ADDRESS(egl, BindAPI);
-        INSERT_PROC_ADDRESS(egl, QueryAPI);
-        INSERT_PROC_ADDRESS(egl, CreatePbufferFromClientBuffer);
-        INSERT_PROC_ADDRESS(egl, ReleaseThread);
-        INSERT_PROC_ADDRESS(egl, WaitClient);
-
-        // EGL 1.4
-        INSERT_PROC_ADDRESS(egl, GetCurrentContext);
-
-        // EGL 1.5
-        INSERT_PROC_ADDRESS(egl, CreateSync);
-        INSERT_PROC_ADDRESS(egl, DestroySync);
-        INSERT_PROC_ADDRESS(egl, ClientWaitSync);
-        INSERT_PROC_ADDRESS(egl, GetSyncAttrib);
-        INSERT_PROC_ADDRESS(egl, CreateImage);
-        INSERT_PROC_ADDRESS(egl, DestroyImage);
-        INSERT_PROC_ADDRESS(egl, GetPlatformDisplay);
-        INSERT_PROC_ADDRESS(egl, CreatePlatformWindowSurface);
-        INSERT_PROC_ADDRESS(egl, CreatePlatformPixmapSurface);
-        INSERT_PROC_ADDRESS(egl, WaitSync);
-
-        // EGL_ANGLE_query_surface_pointer
-        INSERT_PROC_ADDRESS(egl, QuerySurfacePointerANGLE);
-
-        // EGL_NV_post_sub_buffer
-        INSERT_PROC_ADDRESS(egl, PostSubBufferNV);
-
-        // EGL_EXT_platform_base
-        INSERT_PROC_ADDRESS(egl, GetPlatformDisplayEXT);
-
-        // EGL_EXT_device_query
-        INSERT_PROC_ADDRESS(egl, QueryDisplayAttribEXT);
-        INSERT_PROC_ADDRESS(egl, QueryDeviceAttribEXT);
-        INSERT_PROC_ADDRESS(egl, QueryDeviceStringEXT);
-
-        // EGL_KHR_image_base/EGL_KHR_image
-        INSERT_PROC_ADDRESS(egl, CreateImageKHR);
-        INSERT_PROC_ADDRESS(egl, DestroyImageKHR);
-
-        // EGL_EXT_device_creation
-        INSERT_PROC_ADDRESS(egl, CreateDeviceANGLE);
-        INSERT_PROC_ADDRESS(egl, ReleaseDeviceANGLE);
-
-        // EGL_KHR_stream
-        INSERT_PROC_ADDRESS(egl, CreateStreamKHR);
-        INSERT_PROC_ADDRESS(egl, DestroyStreamKHR);
-        INSERT_PROC_ADDRESS(egl, StreamAttribKHR);
-        INSERT_PROC_ADDRESS(egl, QueryStreamKHR);
-        INSERT_PROC_ADDRESS(egl, QueryStreamu64KHR);
-
-        // EGL_KHR_stream_consumer_gltexture
-        INSERT_PROC_ADDRESS(egl, StreamConsumerGLTextureExternalKHR);
-        INSERT_PROC_ADDRESS(egl, StreamConsumerAcquireKHR);
-        INSERT_PROC_ADDRESS(egl, StreamConsumerReleaseKHR);
-
-        // EGL_NV_stream_consumer_gltexture_yuv
-        INSERT_PROC_ADDRESS(egl, StreamConsumerGLTextureExternalAttribsNV);
-
-        // EGL_ANGLE_stream_producer_d3d_texture_nv12
-        INSERT_PROC_ADDRESS(egl, CreateStreamProducerD3DTextureNV12ANGLE);
-        INSERT_PROC_ADDRESS(egl, StreamPostD3DTextureNV12ANGLE);
-
-        // EGL_CHROMIUM_get_sync_values
-        INSERT_PROC_ADDRESS(egl, GetSyncValuesCHROMIUM);
-
-        // EGL_EXT_swap_buffers_with_damage
-        INSERT_PROC_ADDRESS(egl, SwapBuffersWithDamageEXT);
-
-        // EGL_ANGLE_program_cache_control
-        INSERT_PROC_ADDRESS(egl, ProgramCacheGetAttribANGLE);
-        INSERT_PROC_ADDRESS(egl, ProgramCacheQueryANGLE);
-        INSERT_PROC_ADDRESS(egl, ProgramCachePopulateANGLE);
-        INSERT_PROC_ADDRESS(egl, ProgramCacheResizeANGLE);
-
-        // angle::Platform related entry points
-        INSERT_PROC_ADDRESS_NO_NS("ANGLEGetDisplayPlatform", ANGLEGetDisplayPlatform);
-        INSERT_PROC_ADDRESS_NO_NS("ANGLEResetDisplayPlatform", ANGLEResetDisplayPlatform);
-
-#undef INSERT_PROC_ADDRESS
-#undef INSERT_PROC_ADDRESS_NO_NS
-
-        return map;
-    };
-
-    static const ProcAddressMap procAddressMap = generateProcAddressMap();
+    ProcEntry *entry =
+        std::lower_bound(&g_procTable[0], &g_procTable[g_numProcs], procname, CompareProc);
 
     thread->setError(NoError());
-    auto iter = procAddressMap.find(procname);
-    return iter != procAddressMap.end() ? iter->second : nullptr;
+
+    if (entry == &g_procTable[g_numProcs] || strcmp(entry->first, procname) != 0)
+    {
+        return nullptr;
+    }
+
+    return entry->second;
 }
 }
--- a/gfx/angle/src/libGLESv2/entry_points_egl_ext.cpp
+++ b/gfx/angle/src/libGLESv2/entry_points_egl_ext.cpp
@@ -652,71 +652,70 @@ EGLBoolean EGLAPIENTRY StreamConsumerGLT
         thread->setError(error);
         return EGL_FALSE;
     }
 
     thread->setError(error);
     return EGL_TRUE;
 }
 
-EGLBoolean EGLAPIENTRY CreateStreamProducerD3DTextureNV12ANGLE(EGLDisplay dpy,
-                                                               EGLStreamKHR stream,
-                                                               const EGLAttrib *attrib_list)
+EGLBoolean EGLAPIENTRY CreateStreamProducerD3DTextureANGLE(EGLDisplay dpy,
+                                                           EGLStreamKHR stream,
+                                                           const EGLAttrib *attrib_list)
 {
     EVENT(
         "(EGLDisplay dpy = 0x%0.8p, EGLStreamKHR stream = 0x%0.8p, EGLAttrib attrib_list = 0x%0.8p",
         dpy, stream, attrib_list);
     Thread *thread = GetCurrentThread();
 
     Display *display        = static_cast<Display *>(dpy);
     Stream *streamObject    = static_cast<Stream *>(stream);
     AttributeMap attributes = AttributeMap::CreateFromAttribArray(attrib_list);
 
-    Error error =
-        ValidateCreateStreamProducerD3DTextureNV12ANGLE(display, streamObject, attributes);
+    Error error = ValidateCreateStreamProducerD3DTextureANGLE(display, streamObject, attributes);
     if (error.isError())
     {
         thread->setError(error);
         return EGL_FALSE;
     }
 
-    error = streamObject->createProducerD3D11TextureNV12(attributes);
+    error = streamObject->createProducerD3D11Texture(attributes);
     if (error.isError())
     {
         thread->setError(error);
         return EGL_FALSE;
     }
 
     thread->setError(error);
     return EGL_TRUE;
 }
 
-EGLBoolean EGLAPIENTRY StreamPostD3DTextureNV12ANGLE(EGLDisplay dpy,
-                                                     EGLStreamKHR stream,
-                                                     void *texture,
-                                                     const EGLAttrib *attrib_list)
+EGLBoolean EGLAPIENTRY StreamPostD3DTextureANGLE(EGLDisplay dpy,
+                                                 EGLStreamKHR stream,
+                                                 void *texture,
+                                                 const EGLAttrib *attrib_list)
 {
     EVENT(
         "(EGLDisplay dpy = 0x%0.8p, EGLStreamKHR stream = 0x%0.8p, void* texture = 0x%0.8p, "
         "EGLAttrib attrib_list = 0x%0.8p",
         dpy, stream, texture, attrib_list);
     Thread *thread = GetCurrentThread();
 
     Display *display        = static_cast<Display *>(dpy);
     Stream *streamObject    = static_cast<Stream *>(stream);
     AttributeMap attributes = AttributeMap::CreateFromAttribArray(attrib_list);
 
-    Error error = ValidateStreamPostD3DTextureNV12ANGLE(display, streamObject, texture, attributes);
+    Error error = ValidateStreamPostD3DTextureANGLE(display, streamObject, texture, attributes);
     if (error.isError())
     {
         thread->setError(error);
         return EGL_FALSE;
     }
 
-    error = streamObject->postD3D11NV12Texture(texture, attributes);
+    error = streamObject->postD3D11Texture(texture, attributes);
     if (error.isError())
     {
         thread->setError(error);
         return EGL_FALSE;
     }
 
     thread->setError(error);
     return EGL_TRUE;
--- a/gfx/angle/src/libGLESv2/entry_points_egl_ext.h
+++ b/gfx/angle/src/libGLESv2/entry_points_egl_ext.h
@@ -65,25 +65,25 @@ ANGLE_EXPORT EGLBoolean EGLAPIENTRY Stre
                                                                        EGLStreamKHR stream);
 ANGLE_EXPORT EGLBoolean EGLAPIENTRY StreamConsumerAcquireKHR(EGLDisplay dpy, EGLStreamKHR stream);
 ANGLE_EXPORT EGLBoolean EGLAPIENTRY StreamConsumerReleaseKHR(EGLDisplay dpy, EGLStreamKHR stream);
 ANGLE_EXPORT EGLBoolean EGLAPIENTRY
 StreamConsumerGLTextureExternalAttribsNV(EGLDisplay dpy,
                                          EGLStreamKHR stream,
                                          const EGLAttrib *attrib_list);
 
-// EGL_ANGLE_stream_producer_d3d_texture_nv12
+// EGL_ANGLE_stream_producer_d3d_texture
 ANGLE_EXPORT EGLBoolean EGLAPIENTRY
-CreateStreamProducerD3DTextureNV12ANGLE(EGLDisplay dpy,
-                                        EGLStreamKHR stream,
-                                        const EGLAttrib *attrib_list);
-ANGLE_EXPORT EGLBoolean EGLAPIENTRY StreamPostD3DTextureNV12ANGLE(EGLDisplay dpy,
-                                                                  EGLStreamKHR stream,
-                                                                  void *texture,
-                                                                  const EGLAttrib *attrib_list);
+CreateStreamProducerD3DTextureANGLE(EGLDisplay dpy,
+                                    EGLStreamKHR stream,
+                                    const EGLAttrib *attrib_list);
+ANGLE_EXPORT EGLBoolean EGLAPIENTRY StreamPostD3DTextureANGLE(EGLDisplay dpy,
+                                                              EGLStreamKHR stream,
+                                                              void *texture,
+                                                              const EGLAttrib *attrib_list);
 
 // EGL_CHROMIUM_get_sync_values
 ANGLE_EXPORT EGLBoolean EGLAPIENTRY GetSyncValuesCHROMIUM(EGLDisplay dpy,
                                                           EGLSurface surface,
                                                           EGLuint64KHR *ust,
                                                           EGLuint64KHR *msc,
                                                           EGLuint64KHR *sbc);
 
--- a/gfx/angle/src/libGLESv2/entry_points_gles_2_0_autogen.cpp
+++ b/gfx/angle/src/libGLESv2/entry_points_gles_2_0_autogen.cpp
@@ -1,12 +1,12 @@
 // GENERATED FILE - DO NOT EDIT.
 // Generated by generate_entry_points.py using data from gl.xml.
 //
-// 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.
 //
 // entry_points_gles_2_0_autogen.cpp:
 //   Defines the GLES 2.0 entry points.
 
 #include "libANGLE/Context.h"
 #include "libANGLE/validationES2.h"
@@ -65,21 +65,22 @@ void GL_APIENTRY BindAttribLocation(GLui
 
 void GL_APIENTRY BindBuffer(GLenum target, GLuint buffer)
 {
     EVENT("(GLenum target = 0x%X, GLuint buffer = %u)", target, buffer);
 
     Context *context = GetValidGlobalContext();
     if (context)
     {
-        context->gatherParams<EntryPoint::BindBuffer>(target, buffer);
-
-        if (context->skipValidation() || ValidateBindBuffer(context, target, buffer))
+        BufferBinding targetPacked = FromGLenum<BufferBinding>(target);
+        context->gatherParams<EntryPoint::BindBuffer>(targetPacked, buffer);
+
+        if (context->skipValidation() || ValidateBindBuffer(context, targetPacked, buffer))
         {
-            context->bindBuffer(target, buffer);
+            context->bindBuffer(targetPacked, buffer);
         }
     }
 }
 
 void GL_APIENTRY BindFramebuffer(GLenum target, GLuint framebuffer)
 {
     EVENT("(GLenum target = 0x%X, GLuint framebuffer = %u)", target, framebuffer);
 
@@ -221,40 +222,45 @@ void GL_APIENTRY BufferData(GLenum targe
     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)
     {
-        context->gatherParams<EntryPoint::BufferData>(target, size, data, usage);
-
-        if (context->skipValidation() || ValidateBufferData(context, target, size, data, usage))
+        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(target, size, data, usage);
+            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)
     {
-        context->gatherParams<EntryPoint::BufferSubData>(target, offset, size, data);
-
-        if (context->skipValidation() || ValidateBufferSubData(context, target, offset, size, data))
+        BufferBinding targetPacked = FromGLenum<BufferBinding>(target);
+        context->gatherParams<EntryPoint::BufferSubData>(targetPacked, offset, size, data);
+
+        if (context->skipValidation() ||
+            ValidateBufferSubData(context, targetPacked, offset, size, data))
         {
-            context->bufferSubData(target, offset, size, data);
+            context->bufferSubData(targetPacked, offset, size, data);
         }
     }
 }
 
 GLenum GL_APIENTRY CheckFramebufferStatus(GLenum target)
 {
     EVENT("(GLenum target = 0x%X)", target);
 
@@ -528,21 +534,22 @@ GLuint GL_APIENTRY CreateShader(GLenum t
 
 void GL_APIENTRY CullFace(GLenum mode)
 {
     EVENT("(GLenum mode = 0x%X)", mode);
 
     Context *context = GetValidGlobalContext();
     if (context)
     {
-        context->gatherParams<EntryPoint::CullFace>(mode);
-
-        if (context->skipValidation() || ValidateCullFace(context, mode))
+        CullFaceMode modePacked = FromGLenum<CullFaceMode>(mode);
+        context->gatherParams<EntryPoint::CullFace>(modePacked);
+
+        if (context->skipValidation() || ValidateCullFace(context, modePacked))
         {
-            context->cullFace(mode);
+            context->cullFace(modePacked);
         }
     }
 }
 
 void GL_APIENTRY DeleteBuffers(GLsizei n, const GLuint *buffers)
 {
     EVENT("(GLsizei n = %d, const GLuint *buffers = 0x%0.8p)", n, buffers);
 
@@ -910,32 +917,16 @@ void GL_APIENTRY GenBuffers(GLsizei n, G
 
         if (context->skipValidation() || ValidateGenBuffers(context, n, buffers))
         {
             context->genBuffers(n, buffers);
         }
     }
 }
 
-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))
-        {
-            context->generateMipmap(target);
-        }
-    }
-}
-
 void GL_APIENTRY GenFramebuffers(GLsizei n, GLuint *framebuffers)
 {
     EVENT("(GLsizei n = %d, GLuint *framebuffers = 0x%0.8p)", n, framebuffers);
 
     Context *context = GetValidGlobalContext();
     if (context)
     {
         context->gatherParams<EntryPoint::GenFramebuffers>(n, framebuffers);
@@ -974,16 +965,32 @@ void GL_APIENTRY GenTextures(GLsizei n, 
 
         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))
+        {
+            context->generateMipmap(target);
+        }
+    }
+}
+
 void GL_APIENTRY GetActiveAttrib(GLuint program,
                                  GLuint index,
                                  GLsizei bufSize,
                                  GLsizei *length,
                                  GLint *size,
                                  GLenum *type,
                                  GLchar *name)
 {
@@ -1093,22 +1100,23 @@ void GL_APIENTRY GetBooleanv(GLenum pnam
 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)
     {
-        context->gatherParams<EntryPoint::GetBufferParameteriv>(target, pname, params);
+        BufferBinding targetPacked = FromGLenum<BufferBinding>(target);
+        context->gatherParams<EntryPoint::GetBufferParameteriv>(targetPacked, pname, params);
 
         if (context->skipValidation() ||
-            ValidateGetBufferParameteriv(context, target, pname, params))
+            ValidateGetBufferParameteriv(context, targetPacked, pname, params))
         {
-            context->getBufferParameteriv(target, pname, params);
+            context->getBufferParameteriv(targetPacked, pname, params);
         }
     }
 }
 
 GLenum GL_APIENTRY GetError()
 {
     EVENT("()");
 
@@ -1177,33 +1185,16 @@ void GL_APIENTRY GetIntegerv(GLenum pnam
 
         if (context->skipValidation() || ValidateGetIntegerv(context, pname, data))
         {
             context->getIntegerv(pname, data);
         }
     }
 }
 
-void GL_APIENTRY GetProgramiv(GLuint program, GLenum pname, GLint *params)
-{
-    EVENT("(GLuint program = %u, GLenum pname = 0x%X, GLint *params = 0x%0.8p)", program, pname,
-          params);
-
-    Context *context = GetValidGlobalContext();
-    if (context)
-    {
-        context->gatherParams<EntryPoint::GetProgramiv>(program, pname, params);
-
-        if (context->skipValidation() || ValidateGetProgramiv(context, program, pname, params))
-        {
-            context->getProgramiv(program, pname, params);
-        }
-    }
-}
-
 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)",
@@ -1217,16 +1208,33 @@ void GL_APIENTRY GetProgramInfoLog(GLuin
         if (context->skipValidation() ||
             ValidateGetProgramInfoLog(context, program, bufSize, length, infoLog))
         {
             context->getProgramInfoLog(program, bufSize, length, infoLog);
         }
     }
 }
 
+void GL_APIENTRY GetProgramiv(GLuint program, GLenum pname, GLint *params)
+{
+    EVENT("(GLuint program = %u, GLenum pname = 0x%X, GLint *params = 0x%0.8p)", program, pname,
+          params);
+
+    Context *context = GetValidGlobalContext();
+    if (context)
+    {
+        context->gatherParams<EntryPoint::GetProgramiv>(program, pname, params);
+
+        if (context->skipValidation() || ValidateGetProgramiv(context, program, pname, params))
+        {
+            context->getProgramiv(program, pname, params);
+        }
+    }
+}
+
 void GL_APIENTRY GetRenderbufferParameteriv(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)
     {
@@ -1235,33 +1243,16 @@ void GL_APIENTRY GetRenderbufferParamete
         if (context->skipValidation() ||
             ValidateGetRenderbufferParameteriv(context, target, pname, params))
         {
             context->getRenderbufferParameteriv(target, pname, params);
         }
     }
 }
 
-void GL_APIENTRY GetShaderiv(GLuint shader, GLenum pname, GLint *params)
-{
-    EVENT("(GLuint shader = %u, GLenum pname = 0x%X, GLint *params = 0x%0.8p)", shader, pname,
-          params);
-
-    Context *context = GetValidGlobalContext();
-    if (context)
-    {
-        context->gatherParams<EntryPoint::GetShaderiv>(shader, pname, params);
-
-        if (context->skipValidation() || ValidateGetShaderiv(context, shader, pname, params))
-        {
-            context->getShaderiv(shader, pname, params);
-        }
-    }
-}
-
 void GL_APIENTRY GetShaderInfoLog(GLuint shader, GLsizei bufSize, GLsizei *length, GLchar *infoLog)
 {
     EVENT(
         "(GLuint shader = %u, GLsizei bufSize = %d, GLsizei *length = 0x%0.8p, GLchar *infoLog = "
         "0x%0.8p)",
         shader, bufSize, length, infoLog);
 
     Context *context = GetValidGlobalContext();
@@ -1316,16 +1307,33 @@ void GL_APIENTRY GetShaderSource(GLuint 
         if (context->skipValidation() ||
             ValidateGetShaderSource(context, shader, bufSize, length, source))
         {
             context->getShaderSource(shader, bufSize, length, source);
         }
     }
 }
 
+void GL_APIENTRY GetShaderiv(GLuint shader, GLenum pname, GLint *params)
+{
+    EVENT("(GLuint shader = %u, GLenum pname = 0x%X, GLint *params = 0x%0.8p)", shader, pname,
+          params);
+
+    Context *context = GetValidGlobalContext();
+    if (context)
+    {
+        context->gatherParams<EntryPoint::GetShaderiv>(shader, pname, params);
+
+        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);
@@ -1368,16 +1376,34 @@ void GL_APIENTRY GetTexParameteriv(GLenu
 
         if (context->skipValidation() || ValidateGetTexParameteriv(context, target, pname, params))
         {
             context->getTexParameteriv(target, 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);
+
+        if (context->skipValidation() || ValidateGetUniformLocation(context, program, name))
+        {
+            return context->getUniformLocation(program, name);
+        }
+    }
+
+    return GetDefaultReturnValue<EntryPoint::GetUniformLocation, GLint>();
+}
+
 void GL_APIENTRY GetUniformfv(GLuint program, GLint location, GLfloat *params)
 {
     EVENT("(GLuint program = %u, GLint location = %d, GLfloat *params = 0x%0.8p)", program,
           location, params);
 
     Context *context = GetValidGlobalContext();
     if (context)
     {
@@ -1402,32 +1428,32 @@ void GL_APIENTRY GetUniformiv(GLuint pro
 
         if (context->skipValidation() || ValidateGetUniformiv(context, program, location, params))
         {
             context->getUniformiv(program, location, params);
         }
     }
 }
 
-GLint GL_APIENTRY GetUniformLocation(GLuint program, const GLchar *name)
+void GL_APIENTRY GetVertexAttribPointerv(GLuint index, GLenum pname, void **pointer)
 {
-    EVENT("(GLuint program = %u, const GLchar *name = 0x%0.8p)", program, name);
+    EVENT("(GLuint index = %u, GLenum pname = 0x%X, void **pointer = 0x%0.8p)", index, pname,
+          pointer);
 
     Context *context = GetValidGlobalContext();
     if (context)
     {
-        context->gatherParams<EntryPoint::GetUniformLocation>(program, name);
-
-        if (context->skipValidation() || ValidateGetUniformLocation(context, program, name))
+        context->gatherParams<EntryPoint::GetVertexAttribPointerv>(index, pname, pointer);
+
+        if (context->skipValidation() ||
+            ValidateGetVertexAttribPointerv(context, index, pname, pointer))
         {
-            return context->getUniformLocation(program, name);
+            context->getVertexAttribPointerv(index, pname, pointer);
         }
     }
-
-    return GetDefaultReturnValue<EntryPoint::GetUniformLocation, GLint>();
 }
 
 void GL_APIENTRY GetVertexAttribfv(GLuint index, GLenum pname, GLfloat *params)
 {
     EVENT("(GLuint index = %u, GLenum pname = 0x%X, GLfloat *params = 0x%0.8p)", index, pname,
           params);
 
     Context *context = GetValidGlobalContext();
@@ -1454,34 +1480,16 @@ void GL_APIENTRY GetVertexAttribiv(GLuin
 
         if (context->skipValidation() || ValidateGetVertexAttribiv(context, index, pname, params))
         {
             context->getVertexAttribiv(index, pname, params);
         }
     }
 }
 
-void GL_APIENTRY GetVertexAttribPointerv(GLuint index, GLenum pname, void **pointer)
-{
-    EVENT("(GLuint index = %u, GLenum pname = 0x%X, void **pointer = 0x%0.8p)", index, pname,
-          pointer);
-
-    Context *context = GetValidGlobalContext();
-    if (context)
-    {
-        context->gatherParams<EntryPoint::GetVertexAttribPointerv>(index, pname, pointer);
-
-        if (context->skipValidation() ||
-            ValidateGetVertexAttribPointerv(context, index, pname, pointer))
-        {
-            context->getVertexAttribPointerv(index, pname, pointer);
-        }
-    }
-}
-
 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);
--- a/gfx/angle/src/libGLESv2/entry_points_gles_2_0_autogen.h
+++ b/gfx/angle/src/libGLESv2/entry_points_gles_2_0_autogen.h
@@ -1,20 +1,20 @@
 // GENERATED FILE - DO NOT EDIT.
 // Generated by generate_entry_points.py using data from gl.xml.
 //
-// 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.
 //
 // entry_points_gles_2_0_autogen.h:
 //   Defines the GLES 2.0 entry points.
 
-#ifndef LIBGLESV2_ENTRYPOINTSGLES20_AUTOGEN_H_
-#define LIBGLESV2_ENTRYPOINTSGLES20_AUTOGEN_H_
+#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);
@@ -112,20 +112,20 @@ ANGLE_EXPORT void GL_APIENTRY Framebuffe
                                                       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 GenerateMipmap(GLenum target);
 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);
 ANGLE_EXPORT void GL_APIENTRY GetActiveUniform(GLuint program,
@@ -144,46 +144,46 @@ ANGLE_EXPORT void GL_APIENTRY GetBoolean
 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 GetProgramiv(GLuint program, GLenum pname, GLint *params);
 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);
-ANGLE_EXPORT void GL_APIENTRY GetShaderiv(GLuint shader, GLenum pname, GLint *params);
 ANGLE_EXPORT void GL_APIENTRY GetShaderInfoLog(GLuint shader,
                                                GLsizei bufSize,
                                                GLsizei *length,
                                                GLchar *infoLog);
 ANGLE_EXPORT void GL_APIENTRY GetShaderPrecisionFormat(GLenum shadertype,
                                                        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 GLint GL_APIENTRY GetUniformLocation(GLuint program, const GLchar *name);
+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 GetVertexAttribPointerv(GLuint index, GLenum pname, void **pointer);
 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);
@@ -289,9 +289,9 @@ ANGLE_EXPORT void GL_APIENTRY VertexAttr
                                                   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_ENTRYPOINTSGLES20_AUTOGEN_H_
+#endif  // LIBGLESV2_ENTRY_POINTS_GLES_2_0_AUTOGEN_H_
--- a/gfx/angle/src/libGLESv2/entry_points_gles_2_0_ext.cpp
+++ b/gfx/angle/src/libGLESv2/entry_points_gles_2_0_ext.cpp
@@ -7,16 +7,17 @@
 // entry_points_gles_2_0_ext.cpp : Implements the GLES 2.0 extension entry points.
 
 #include "libGLESv2/entry_points_gles_2_0_ext.h"
 #include "libGLESv2/global_state.h"
 
 #include "libANGLE/Buffer.h"
 #include "libANGLE/Context.h"
 #include "libANGLE/Error.h"
+#include "libANGLE/ErrorStrings.h"
 #include "libANGLE/Fence.h"
 #include "libANGLE/Framebuffer.h"
 #include "libANGLE/Query.h"
 #include "libANGLE/Shader.h"
 #include "libANGLE/Thread.h"
 #include "libANGLE/VertexArray.h"
 #include "libANGLE/queryconversions.h"
 #include "libANGLE/queryutils.h"
@@ -40,1417 +41,121 @@ void SetRobustLengthParam(GLsizei *lengt
     if (length)
     {
         *length = value;
     }
 }
 
 }  // anonymous namespace
 
-void GL_APIENTRY GenQueriesEXT(GLsizei n, GLuint *ids)
-{
-    EVENT("(GLsizei n = %d, GLuint* ids = 0x%0.8p)", n, ids);
-
-    Context *context = GetValidGlobalContext();
-    if (context)
-    {
-        if (!context->skipValidation() && !ValidateGenQueriesEXT(context, n, ids))
-        {
-            return;
-        }
-
-        context->genQueries(n, ids);
-    }
-}
-
-void GL_APIENTRY DeleteQueriesEXT(GLsizei n, const GLuint *ids)
-{
-    EVENT("(GLsizei n = %d, const GLuint *ids = 0x%0.8p)", n, ids);
-
-    Context *context = GetValidGlobalContext();
-    if (context)
-    {
-        if (!context->skipValidation() && !ValidateDeleteQueriesEXT(context, n, ids))
-        {
-            return;
-        }
-
-        context->deleteQueries(n, ids);
-    }
-}
-
-GLboolean GL_APIENTRY IsQueryEXT(GLuint id)
-{
-    EVENT("(GLuint id = %d)", id);
-
-    Context *context = GetValidGlobalContext();
-    if (context)
-    {
-        if (!context->skipValidation() && !ValidateIsQueryEXT(context, id))
-        {
-            return GL_FALSE;
-        }
-
-        return context->isQuery(id);
-    }
-
-    return GL_FALSE;
-}
-
-void GL_APIENTRY BeginQueryEXT(GLenum target, GLuint id)
-{
-    EVENT("(GLenum target = 0x%X, GLuint %d)", target, id);
-
-    Context *context = GetValidGlobalContext();
-    if (context)
-    {
-        if (!context->skipValidation() && !ValidateBeginQueryEXT(context, target, id))
-        {
-            return;
-        }
-
-        context->beginQuery(target, id);
-    }
-}
-
-void GL_APIENTRY EndQueryEXT(GLenum target)
-{
-    EVENT("GLenum target = 0x%X)", target);
-
-    Context *context = GetValidGlobalContext();
-    if (context)
-    {
-        if (!context->skipValidation() && !ValidateEndQueryEXT(context, target))
-        {
-            return;
-        }
-
-        context->endQuery(target);
-    }
-}
-
-void GL_APIENTRY QueryCounterEXT(GLuint id, GLenum target)
-{
-    EVENT("GLuint id = %d, GLenum target = 0x%X)", id, target);
-
-    Context *context = GetValidGlobalContext();
-    if (context)
-    {
-        if (!context->skipValidation() && !ValidateQueryCounterEXT(context, id, target))
-        {
-            return;
-        }
-
-        context->queryCounter(id, target);
-    }
-}
-
-void GL_APIENTRY GetQueryivEXT(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)
-    {
-        if (!ValidateGetQueryivEXT(context, target, pname, params))
-        {
-            return;
-        }
-
-        context->getQueryiv(target, pname, params);
-    }
-}
-
-void GL_APIENTRY GetQueryObjectivEXT(GLuint id, GLenum pname, GLint *params)
-{
-    EVENT("(GLuint id = %d, GLenum pname = 0x%X, GLuint *params = 0x%0.8p)", id, pname, params);
-
-    Context *context = GetValidGlobalContext();
-    if (context)
-    {
-        if (!ValidateGetQueryObjectivEXT(context, id, pname, params))
-        {
-            return;
-        }
-
-        context->getQueryObjectiv(id, pname, params);
-    }
-}
-
-void GL_APIENTRY GetQueryObjectuivEXT(GLuint id, GLenum pname, GLuint *params)
-{
-    EVENT("(GLuint id = %d, GLenum pname = 0x%X, GLuint *params = 0x%0.8p)", id, pname, params);
-
-    Context *context = GetValidGlobalContext();
-    if (context)
-    {
-        if (!ValidateGetQueryObjectuivEXT(context, id, pname, params))
-        {
-            return;
-        }
-
-        context->getQueryObjectuiv(id, pname, params);
-    }
-}
-
-void GL_APIENTRY GetQueryObjecti64vEXT(GLuint id, GLenum pname, GLint64 *params)
-{
-    EVENT("(GLuint id = %d, GLenum pname = 0x%X, GLuint *params = 0x%0.16p)", id, pname, params);
-
-    Context *context = GetValidGlobalContext();
-    if (context)
-    {
-        if (!ValidateGetQueryObjecti64vEXT(context, id, pname, params))
-        {
-            return;
-        }
-
-        context->getQueryObjecti64v(id, pname, params);
-    }
-}
-
-void GL_APIENTRY GetQueryObjectui64vEXT(GLuint id, GLenum pname, GLuint64 *params)
-{
-    EVENT("(GLuint id = %d, GLenum pname = 0x%X, GLuint *params = 0x%0.16p)", id, pname, params);
-
-    Context *context = GetValidGlobalContext();
-    if (context)
-    {
-        if (!ValidateGetQueryObjectui64vEXT(context, id, pname, params))
-        {
-            return;
-        }
-
-        context->getQueryObjectui64v(id, pname, params);
-    }
-}
-
-void GL_APIENTRY DeleteFencesNV(GLsizei n, const GLuint *fences)
-{
-    EVENT("(GLsizei n = %d, const GLuint* fences = 0x%0.8p)", n, fences);
-
-    Context *context = GetValidGlobalContext();
-    if (context)
-    {
-        if (n < 0)
-        {
-            context->handleError(InvalidValue());
-            return;
-        }
-
-        for (int i = 0; i < n; i++)
-        {
-            context->deleteFenceNV(fences[i]);
-        }
-    }
-}
-
-void GL_APIENTRY DrawArraysInstancedANGLE(GLenum mode,
-                                          GLint first,
-                                          GLsizei count,
-                                          GLsizei primcount)
-{
-    EVENT("(GLenum mode = 0x%X, GLint first = %d, GLsizei count = %d, GLsizei primcount = %d)",
-          mode, first, count, primcount);
-
-    Context *context = GetValidGlobalContext();
-    if (context)
-    {
-        if (!ValidateDrawArraysInstancedANGLE(context, mode, first, count, primcount))
-        {
-            return;
-        }
-
-        context->drawArraysInstanced(mode, first, count, primcount);
-    }
-}
-
-void GL_APIENTRY DrawElementsInstancedANGLE(GLenum mode,
-                                            GLsizei count,
-                                            GLenum type,
-                                            const void *indices,
-                                            GLsizei primcount)
-{
-    EVENT(
-        "(GLenum mode = 0x%X, GLsizei count = %d, GLenum type = 0x%X, const void* indices = "
-        "0x%0.8p, GLsizei primcount = %d)",
-        mode, count, type, indices, primcount);
-
-    Context *context = GetValidGlobalContext();
-    if (context)
-    {
-        context->gatherParams<EntryPoint::DrawElementsInstancedANGLE>(mode, count, type, indices,
-                                                                      primcount);
-
-        if (!context->skipValidation() &&
-            !ValidateDrawElementsInstancedANGLE(context, mode, count, type, indices, primcount))
-        {
-            return;
-        }
-
-        context->drawElementsInstanced(mode, count, type, indices, primcount);
-    }
-}
-
-void GL_APIENTRY FinishFenceNV(GLuint fence)
-{
-    EVENT("(GLuint fence = %d)", fence);
-
-    Context *context = GetValidGlobalContext();
-    if (context)
-    {
-        FenceNV *fenceObject = context->getFenceNV(fence);
-
-        if (fenceObject == nullptr)
-        {
-            context->handleError(InvalidOperation());
-            return;
-        }
-
-        if (fenceObject->isSet() != GL_TRUE)
-        {
-            context->handleError(InvalidOperation());
-            return;
-        }
-
-        context->handleError(fenceObject->finish());
-    }
-}
-
-void GL_APIENTRY GenFencesNV(GLsizei n, GLuint *fences)
-{
-    EVENT("(GLsizei n = %d, GLuint* fences = 0x%0.8p)", n, fences);
-
-    Context *context = GetValidGlobalContext();
-    if (context)
-    {
-        if (n < 0)
-        {
-            context->handleError(InvalidValue());
-            return;
-        }
-
-        for (int i = 0; i < n; i++)
-        {
-            fences[i] = context->createFenceNV();
-        }
-    }
-}
-
-void GL_APIENTRY GetFenceivNV(GLuint fence, GLenum pname, GLint *params)
-{
-    EVENT("(GLuint fence = %d, GLenum pname = 0x%X, GLint *params = 0x%0.8p)", fence, pname,
-          params);
-
-    Context *context = GetValidGlobalContext();
-    if (context)
-    {
-        FenceNV *fenceObject = context->getFenceNV(fence);
-
-        if (fenceObject == nullptr)
-        {
-            context->handleError(InvalidOperation());
-            return;
-        }
-
-        if (fenceObject->isSet() != GL_TRUE)
-        {
-            context->handleError(InvalidOperation());
-            return;
-        }
-
-        switch (pname)
-        {
-            case GL_FENCE_STATUS_NV:
-            {
-                // GL_NV_fence spec:
-                // Once the status of a fence has been finished (via FinishFenceNV) or tested and
-                // the returned status is TRUE (via either TestFenceNV or GetFenceivNV querying the
-                // FENCE_STATUS_NV), the status remains TRUE until the next SetFenceNV of the fence.
-                GLboolean status = GL_TRUE;
-                if (fenceObject->getStatus() != GL_TRUE)
-                {
-                    Error error = fenceObject->test(&status);
-                    if (error.isError())
-                    {
-                        context->handleError(error);
-                        return;
-                    }
-                }
-                *params = status;
-                break;
-            }
-
-            case GL_FENCE_CONDITION_NV:
-            {
-                *params = static_cast<GLint>(fenceObject->getCondition());
-                break;
-            }
-
-            default:
-            {
-                context->handleError(InvalidEnum());
-                return;
-            }
-        }
-    }
-}
-
-GLenum GL_APIENTRY GetGraphicsResetStatusEXT(void)
-{
-    EVENT("()");
-
-    Context *context = GetGlobalContext();
-
-    if (context)
-    {
-        return context->getResetStatus();
-    }
-
-    return GL_NO_ERROR;
-}
-
-void GL_APIENTRY GetTranslatedShaderSourceANGLE(GLuint shader,
-                                                GLsizei bufsize,
-                                                GLsizei *length,
-                                                GLchar *source)
-{
-    EVENT(
-        "(GLuint shader = %d, GLsizei bufsize = %d, GLsizei* length = 0x%0.8p, GLchar* source = "
-        "0x%0.8p)",
-        shader, bufsize, length, source);
-
-    Context *context = GetValidGlobalContext();
-    if (context)
-    {
-        if (bufsize < 0)
-        {
-            context->handleError(InvalidValue());
-            return;
-        }
-
-        Shader *shaderObject = context->getShader(shader);
-
-        if (!shaderObject)
-        {
-            context->handleError(InvalidOperation());
-            return;
-        }
-
-        shaderObject->getTranslatedSourceWithDebugInfo(context, bufsize, length, source);
-    }
-}
-
-void GL_APIENTRY GetnUniformfvEXT(GLuint program, GLint location, GLsizei bufSize, GLfloat *params)
-{
-    EVENT(
-        "(GLuint program = %d, GLint location = %d, GLsizei bufSize = %d, GLfloat* params = "
-        "0x%0.8p)",
-        program, location, bufSize, params);
-
-    Context *context = GetValidGlobalContext();
-    if (context)
-    {
-        if (!ValidateGetnUniformfvEXT(context, program, location, bufSize, params))
-        {
-            return;
-        }
-
-        Program *programObject = context->getProgram(program);
-        ASSERT(programObject);
-
-        programObject->getUniformfv(context, location, params);
-    }
-}
-
-void GL_APIENTRY GetnUniformivEXT(GLuint program, GLint location, GLsizei bufSize, GLint *params)
-{
-    EVENT(
-        "(GLuint program = %d, GLint location = %d, GLsizei bufSize = %d, GLint* params = 0x%0.8p)",
-        program, location, bufSize, params);
-
-    Context *context = GetValidGlobalContext();
-    if (context)
-    {
-        if (!ValidateGetnUniformivEXT(context, program, location, bufSize, params))
-        {
-            return;
-        }
-
-        Program *programObject = context->getProgram(program);
-        ASSERT(programObject);
-
-        programObject->getUniformiv(context, location, params);
-    }
-}
-
-GLboolean GL_APIENTRY IsFenceNV(GLuint fence)
-{
-    EVENT("(GLuint fence = %d)", fence);
-
-    Context *context = GetValidGlobalContext();
-    if (context)
-    {
-        FenceNV *fenceObject = context->getFenceNV(fence);
-
-        if (fenceObject == nullptr)
-        {
-            return GL_FALSE;
-        }
-
-        // GL_NV_fence spec:
-        // A name returned by GenFencesNV, but not yet set via SetFenceNV, is not the name of an
-        // existing fence.
-        return fenceObject->isSet();
-    }
-
-    return GL_FALSE;
-}
-
-void GL_APIENTRY ReadnPixelsEXT(GLint x,
-                                GLint y,
-                                GLsizei width,
-                                GLsizei height,
-                                GLenum format,
-                                GLenum type,
-                                GLsizei bufSize,
-                                void *data)
-{
-    EVENT(
-        "(GLint x = %d, GLint y = %d, GLsizei width = %d, GLsizei height = %d, "
-        "GLenum format = 0x%X, GLenum type = 0x%X, GLsizei bufSize = 0x%d, void *data = 0x%0.8p)",
-        x, y, width, height, format, type, bufSize, data);
-
-    Context *context = GetValidGlobalContext();
-    if (context)
-    {
-        if (!context->skipValidation() &&
-            !ValidateReadnPixelsEXT(context, x, y, width, height, format, type, bufSize, data))
-        {
-            return;
-        }
-
-        context->readPixels(x, y, width, height, format, type, data);
-    }
-}
-
-void GL_APIENTRY RenderbufferStorageMultisampleANGLE(GLenum target,
-                                                     GLsizei samples,
-                                                     GLenum internalformat,
-                                                     GLsizei width,
-                                                     GLsizei height)
-{
-    EVENT(
-        "(GLenum target = 0x%X, GLsizei samples = %d, GLenum internalformat = 0x%X, GLsizei width "
-        "= %d, GLsizei height = %d)",
-        target, samples, internalformat, width, height);
-
-    Context *context = GetValidGlobalContext();
-    if (context)
-    {
-        if (!context->skipValidation() &&
-            !ValidateRenderbufferStorageMultisampleANGLE(context, target, samples, internalformat,
-                                                         width, height))
-        {
-            return;
-        }
-
-        context->renderbufferStorageMultisample(target, samples, internalformat, width, height);
-    }
-}
-
-void GL_APIENTRY SetFenceNV(GLuint fence, GLenum condition)
-{
-    EVENT("(GLuint fence = %d, GLenum condition = 0x%X)", fence, condition);
-
-    Context *context = GetValidGlobalContext();
-    if (context)
-    {
-        if (condition != GL_ALL_COMPLETED_NV)
-        {
-            context->handleError(InvalidEnum());
-            return;
-        }
-
-        FenceNV *fenceObject = context->getFenceNV(fence);
-
-        if (fenceObject == nullptr)
-        {
-            context->handleError(InvalidOperation());
-            return;
-        }
-
-        Error error = fenceObject->set(condition);
-        if (error.isError())
-        {
-            context->handleError(error);
-            return;
-        }
-    }
-}
-
-GLboolean GL_APIENTRY TestFenceNV(GLuint fence)
-{
-    EVENT("(GLuint fence = %d)", fence);
-
-    Context *context = GetValidGlobalContext();
-    if (context)
-    {
-        FenceNV *fenceObject = context->getFenceNV(fence);
-
-        if (fenceObject == nullptr)
-        {
-            context->handleError(InvalidOperation());
-            return GL_TRUE;
-        }
-
-        if (fenceObject->isSet() != GL_TRUE)
-        {
-            context->handleError(InvalidOperation());
-            return GL_TRUE;
-        }
-
-        GLboolean result;
-        Error error = fenceObject->test(&result);
-        if (error.isError())
-        {
-            context->handleError(error);
-            return GL_TRUE;
-        }
-
-        return result;
-    }
-
-    return GL_TRUE;
-}
-
-void GL_APIENTRY
-TexStorage2DEXT(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)
-    {
-        if (!context->getExtensions().textureStorage)
-        {
-            context->handleError(InvalidOperation());
-            return;
-        }
-
-        if (context->getClientMajorVersion() < 3 &&
-            !ValidateES2TexStorageParameters(context, target, levels, internalformat, width,
-                                             height))
-        {
-            return;
-        }
-
-        if (context->getClientMajorVersion() >= 3 &&
-            !ValidateES3TexStorage2DParameters(context, target, levels, internalformat, width,
-                                               height, 1))
-        {
-            return;
-        }
-
-        context->texStorage2D(target, levels, internalformat, width, height);
-    }
-}
-
-void GL_APIENTRY VertexAttribDivisorANGLE(GLuint index, GLuint divisor)
-{
-    EVENT("(GLuint index = %d, GLuint divisor = %d)", index, divisor);
-
-    Context *context = GetValidGlobalContext();
-    if (context)
-    {
-        if (index >= MAX_VERTEX_ATTRIBS)
-        {
-            context->handleError(InvalidValue());
-            return;
-        }
-
-        if (context->getLimitations().attributeZeroRequiresZeroDivisorInEXT)
-        {
-            if (index == 0 && divisor != 0)
-            {
-                const char *errorMessage =
-                    "The current context doesn't support setting a non-zero divisor on the "
-                    "attribute with index zero. "
-                    "Please reorder the attributes in your vertex shader so that attribute zero "
-                    "can have a zero divisor.";
-                context->handleError(InvalidOperation() << errorMessage);
-
-                // We also output an error message to the debugger window if tracing is active, so
-                // that developers can see the error message.
-                ERR() << errorMessage;
-
-                return;
-            }
-        }
-
-        context->vertexAttribDivisor(index, divisor);
-    }
-}
-
-void GL_APIENTRY BlitFramebufferANGLE(GLint srcX0,
-                                      GLint srcY0,
-                                      GLint srcX1,
-                                      GLint srcY1,
-                                      GLint dstX0,
-                                      GLint dstY0,
-                                      GLint dstX1,
-                                      GLint dstY1,
-                                      GLbitfield mask,
-                                      GLenum filter)
-{
-    EVENT(
-        "(GLint srcX0 = %d, GLint srcY0 = %d, GLint srcX1 = %d, GLint srcY1 = %d, "
-        "GLint dstX0 = %d, GLint dstY0 = %d, GLint dstX1 = %d, GLint dstY1 = %d, "
-        "GLbitfield mask = 0x%X, GLenum filter = 0x%X)",
-        srcX0, srcY0, srcX1, srcX1, dstX0, dstY0, dstX1, dstY1, mask, filter);
-
-    Context *context = GetValidGlobalContext();
-    if (context)
-    {
-        if (!context->skipValidation() &&
-            !ValidateBlitFramebufferANGLE(context, srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1,
-                                          dstY1, mask, filter))
-        {
-            return;
-        }
-
-        context->blitFramebuffer(srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, mask,
-                                 filter);
-    }
-}
-
-void GL_APIENTRY DiscardFramebufferEXT(GLenum target,
-                                       GLsizei numAttachments,
-                                       const GLenum *attachments)
-{
-    EVENT("(GLenum target = 0x%X, GLsizei numAttachments = %d, attachments = 0x%0.8p)", target,
-          numAttachments, attachments);
-
-    Context *context = GetValidGlobalContext();
-    if (context)
-    {
-        if (!context->skipValidation() &&
-            !ValidateDiscardFramebufferEXT(context, target, numAttachments, attachments))
-        {
-            return;
-        }
-
-        context->discardFramebuffer(target, numAttachments, attachments);
-    }
-}
-
-void GL_APIENTRY TexImage3DOES(GLenum target,
-                               GLint level,
-                               GLenum internalformat,
-                               GLsizei width,
-                               GLsizei height,
-                               GLsizei depth,
-                               GLint border,
-                               GLenum format,
-                               GLenum type,
-                               const void *pixels)
-{
-    EVENT(
-        "(GLenum target = 0x%X, GLint level = %d, GLenum internalformat = 0x%X, "
-        "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);
-
-    UNIMPLEMENTED();  // FIXME
-}
-
-void GL_APIENTRY GetProgramBinaryOES(GLuint program,
-                                     GLsizei bufSize,
-                                     GLsizei *length,
-                                     GLenum *binaryFormat,
-                                     void *binary)
-{
-    EVENT(
-        "(GLenum program = 0x%X, bufSize = %d, length = 0x%0.8p, binaryFormat = 0x%0.8p, binary = "
-        "0x%0.8p)",
-        program, bufSize, length, binaryFormat, binary);
-
-    Context *context = GetValidGlobalContext();
-    if (context)
-    {
-        if (!context->skipValidation() &&
-            !ValidateGetProgramBinaryOES(context, program, bufSize, length, binaryFormat, binary))
-        {
-            return;
-        }
-
-        context->getProgramBinary(program, bufSize, length, binaryFormat, binary);
-    }
-}
-
-void GL_APIENTRY ProgramBinaryOES(GLuint program,
-                                  GLenum binaryFormat,
-                                  const void *binary,
-                                  GLint length)
-{
-    EVENT("(GLenum program = 0x%X, binaryFormat = 0x%x, binary = 0x%0.8p, length = %d)", program,
-          binaryFormat, binary, length);
-
-    Context *context = GetValidGlobalContext();
-    if (context)
-    {
-        if (!context->skipValidation() &&
-            !ValidateProgramBinaryOES(context, program, binaryFormat, binary, length))
-        {
-            return;
-        }
-
-        context->programBinary(program, binaryFormat, binary, length);
-    }
-}
-
-void GL_APIENTRY DrawBuffersEXT(GLsizei n, const GLenum *bufs)
-{
-    EVENT("(GLenum n = %d, bufs = 0x%0.8p)", n, bufs);
-
-    Context *context = GetValidGlobalContext();
-    if (context)
-    {
-        if (!context->skipValidation() && !ValidateDrawBuffersEXT(context, n, bufs))
-        {
-            return;
-        }
-
-        context->drawBuffers(n, bufs);
-    }
-}
-
-void GL_APIENTRY GetBufferPointervOES(GLenum target, GLenum pname, void **params)
-{
-    EVENT("(GLenum target = 0x%X, GLenum pname = 0x%X, void** params = 0x%0.8p)", target, pname,
-          params);
-
-    Context *context = GetValidGlobalContext();
-    if (context)
-    {
-        if (!context->skipValidation() &&
-            !ValidateGetBufferPointervOES(context, target, pname, params))
-        {
-            return;
-        }
-
-        context->getBufferPointerv(target, pname, params);
-    }
-}
-
-void *GL_APIENTRY MapBufferOES(GLenum target, GLenum access)
-{
-    EVENT("(GLenum target = 0x%X, GLbitfield access = 0x%X)", target, access);
-
-    Context *context = GetValidGlobalContext();
-    if (context)
-    {
-        if (!context->skipValidation() && !ValidateMapBufferOES(context, target, access))
-        {
-            return nullptr;
-        }
-
-        return context->mapBuffer(target, access);
-    }
-
-    return nullptr;
-}
-
-GLboolean GL_APIENTRY UnmapBufferOES(GLenum target)
-{
-    EVENT("(GLenum target = 0x%X)", target);
-
-    Context *context = GetValidGlobalContext();
-    if (context)
-    {
-        if (!context->skipValidation() && !ValidateUnmapBufferOES(context, target))
-        {
-            return GL_FALSE;
-        }
-
-        return context->unmapBuffer(target);
-    }
-
-    return GL_FALSE;
-}
-
-void *GL_APIENTRY MapBufferRangeEXT(GLenum target,
-                                    GLintptr offset,
-                                    GLsizeiptr length,
-                                    GLbitfield access)
-{
-    EVENT(
-        "(GLenum target = 0x%X, GLintptr offset = %d, GLsizeiptr length = %d, GLbitfield access = "
-        "0x%X)",
-        target, offset, length, access);
-
-    Context *context = GetValidGlobalContext();
-    if (context)
-    {
-        if (!context->skipValidation() &&
-            !ValidateMapBufferRangeEXT(context, target, offset, length, access))
-        {
-            return nullptr;
-        }
-
-        return context->mapBufferRange(target, offset, length, access);
-    }
-
-    return nullptr;
-}
-
-void GL_APIENTRY FlushMappedBufferRangeEXT(GLenum target, GLintptr offset, GLsizeiptr length)
-{
-    EVENT("(GLenum target = 0x%X, GLintptr offset = %d, GLsizeiptr length = %d)", target, offset,
-          length);
-
-    Context *context = GetValidGlobalContext();
-    if (context)
-    {
-        if (!context->skipValidation() &&
-            !ValidateFlushMappedBufferRangeEXT(context, target, offset, length))
-        {
-            return;
-        }
-
-        context->flushMappedBufferRange(target, offset, length);
-    }
-}
-
-void GL_APIENTRY InsertEventMarkerEXT(GLsizei length, const char *marker)
-{
-    // Don't run an EVENT() macro on the EXT_debug_marker entry points.
-    // It can interfere with the debug events being set by the caller.
-
-    Context *context = GetValidGlobalContext();
-    if (context)
-    {
-        if (!context->getExtensions().debugMarker)
-        {
-            // The debug marker calls should not set error state
-            // However, it seems reasonable to set an error state if the extension is not enabled
-            context->handleError(InvalidOperation() << "Extension not enabled");
-            return;
-        }
-
-        if (!ValidateInsertEventMarkerEXT(context, length, marker))
-        {
-            return;
-        }
-
-        context->insertEventMarker(length, marker);
-    }
-}
-
-void GL_APIENTRY PushGroupMarkerEXT(GLsizei length, const char *marker)
-{
-    // Don't run an EVENT() macro on the EXT_debug_marker entry points.
-    // It can interfere with the debug events being set by the caller.
-
-    Context *context = GetValidGlobalContext();
-    if (context)
-    {
-        if (!context->getExtensions().debugMarker)
-        {
-            // The debug marker calls should not set error state
-            // However, it seems reasonable to set an error state if the extension is not enabled
-            context->handleError(InvalidOperation() << "Extension not enabled");
-            return;
-        }
-
-        if (!ValidatePushGroupMarkerEXT(context, length, marker))
-        {
-            return;
-        }
-
-        if (marker == nullptr)
-        {
-            // From the EXT_debug_marker spec,
-            // "If <marker> is null then an empty string is pushed on the stack."
-            context->pushGroupMarker(length, "");
-        }
-        else
-        {
-            context->pushGroupMarker(length, marker);
-        }
-    }
-}
-
-void GL_APIENTRY PopGroupMarkerEXT()
-{
-    // Don't run an EVENT() macro on the EXT_debug_marker entry points.
-    // It can interfere with the debug events being set by the caller.
-
-    Context *context = GetValidGlobalContext();
-    if (context)
-    {
-        if (!context->getExtensions().debugMarker)
-        {
-            // The debug marker calls should not set error state
-            // However, it seems reasonable to set an error state if the extension is not enabled
-            context->handleError(InvalidOperation() << "Extension not enabled");
-            return;
-        }
-
-        context->popGroupMarker();
-    }
-}
-
-ANGLE_EXPORT 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)
-    {
-        egl::Image *imageObject = reinterpret_cast<egl::Image *>(image);
-        if (!ValidateEGLImageTargetTexture2DOES(context, target, imageObject))
-        {
-            return;
-        }
-
-        Texture *texture = context->getTargetTexture(target);
-        Error error      = texture->setEGLImageTarget(context, target, imageObject);
-        if (error.isError())
-        {
-            context->handleError(error);
-            return;
-        }
-    }
-}
-
-ANGLE_EXPORT void GL_APIENTRY EGLImageTargetRenderbufferStorageOES(GLenum target,
-                                                                   GLeglImageOES image)
-{
-    EVENT("(GLenum target = 0x%X, GLeglImageOES image = 0x%0.8p)", target, image);
-
-    Context *context = GetValidGlobalContext();
-    if (context)
-    {
-        egl::Image *imageObject = reinterpret_cast<egl::Image *>(image);
-        if (!ValidateEGLImageTargetRenderbufferStorageOES(context, target, imageObject))
-        {
-            return;
-        }
-
-        Renderbuffer *renderbuffer = context->getGLState().getCurrentRenderbuffer();
-        Error error                = renderbuffer->setStorageEGLImageTarget(context, imageObject);
-        if (error.isError())
-        {
-            context->handleError(error);
-            return;
-        }
-    }
-}
-
-void GL_APIENTRY BindVertexArrayOES(GLuint array)
-{
-    EVENT("(GLuint array = %u)", array);
-
-    Context *context = GetValidGlobalContext();
-    if (context)
-    {
-        if (!context->skipValidation() && !ValidateBindVertexArrayOES(context, array))
-        {
-            return;
-        }
-
-        context->bindVertexArray(array);
-    }
-}
-
-void GL_APIENTRY DeleteVertexArraysOES(GLsizei n, const GLuint *arrays)
-{
-    EVENT("(GLsizei n = %d, const GLuint* arrays = 0x%0.8p)", n, arrays);
-
-    Context *context = GetValidGlobalContext();
-    if (context)
-    {
-        if (!context->skipValidation() && !ValidateDeleteVertexArraysOES(context, n, arrays))
-        {
-            return;
-        }
-
-        context->deleteVertexArrays(n, arrays);
-    }
-}
-
-void GL_APIENTRY GenVertexArraysOES(GLsizei n, GLuint *arrays)
-{
-    EVENT("(GLsizei n = %d, GLuint* arrays = 0x%0.8p)", n, arrays);
-
-    Context *context = GetValidGlobalContext();
-    if (context)
-    {
-        if (!context->skipValidation() && !ValidateGenVertexArraysOES(context, n, arrays))
-        {
-            return;
-        }
-
-        context->genVertexArrays(n, arrays);
-    }
-}
-
-GLboolean GL_APIENTRY IsVertexArrayOES(GLuint array)
-{
-    EVENT("(GLuint array = %u)", array);
-
-    Context *context = GetValidGlobalContext();
-    if (context)
-    {
-        if (!context->skipValidation() && !ValidateIsVertexArrayOES(context, array))
-        {
-            return GL_FALSE;
-        }
-
-        return context->isVertexArray(array);
-    }
-
-    return GL_FALSE;
-}
-
-void GL_APIENTRY DebugMessageControlKHR(GLenum source,
-                                        GLenum type,
-                                        GLenum severity,
-                                        GLsizei count,
-                                        const GLuint *ids,
-                                        GLboolean enabled)
-{
-    EVENT(
-        "(GLenum source = 0x%X, GLenum type = 0x%X, GLenum severity = 0x%X, GLsizei count = %d, "
-        "GLint *ids = 0x%0.8p, GLboolean enabled = %d)",
-        source, type, severity, count, ids, enabled);
-
-    Context *context = GetValidGlobalContext();
-    if (context)
-    {
-        if (!ValidateDebugMessageControlKHR(context, source, type, severity, count, ids, enabled))
-        {
-            return;
-        }
-
-        context->debugMessageControl(source, type, severity, count, ids, enabled);
-    }
-}
-
-void GL_APIENTRY DebugMessageInsertKHR(GLenum source,
-                                       GLenum type,
-                                       GLuint id,
-                                       GLenum severity,
-                                       GLsizei length,
-                                       const GLchar *buf)
-{
-    EVENT(
-        "(GLenum source = 0x%X, GLenum type = 0x%X, GLint id = %d, GLenum severity = 0x%X, GLsizei "
-        "length = %d, const GLchar *buf = 0x%0.8p)",
-        source, type, id, severity, length, buf);
-
-    Context *context = GetValidGlobalContext();
-    if (context)
-    {
-        if (!ValidateDebugMessageInsertKHR(context, source, type, id, severity, length, buf))
-        {
-            return;
-        }
-
-        context->debugMessageInsert(source, type, id, severity, length, buf);
-    }
-}
-
-void GL_APIENTRY DebugMessageCallbackKHR(GLDEBUGPROCKHR callback, const void *userParam)
-{
-    EVENT("(GLDEBUGPROCKHR callback = 0x%0.8p, const void *userParam = 0x%0.8p)", callback,
-          userParam);
-
-    Context *context = GetValidGlobalContext();
-    if (context)
-    {
-        if (!ValidateDebugMessageCallbackKHR(context, callback, userParam))
-        {
-            return;
-        }
-
-        context->debugMessageCallback(callback, userParam);
-    }
-}
-
-GLuint GL_APIENTRY GetDebugMessageLogKHR(GLuint count,
-                                         GLsizei bufSize,
-                                         GLenum *sources,
-                                         GLenum *types,
-                                         GLuint *ids,
-                                         GLenum *severities,
-                                         GLsizei *lengths,
-                                         GLchar *messageLog)
-{
-    EVENT(
-        "(GLsizei count = %d, GLsizei bufSize = %d, GLenum *sources, GLenum *types = 0x%0.8p, "
-        "GLuint *ids = 0x%0.8p, GLenum *severities = 0x%0.8p, GLsizei *lengths = 0x%0.8p, GLchar "
-        "*messageLog = 0x%0.8p)",
-        count, bufSize, sources, types, ids, severities, lengths, messageLog);
-
-    Context *context = GetValidGlobalContext();
-    if (context)
-    {
-        if (!ValidateGetDebugMessageLogKHR(context, count, bufSize, sources, types, ids, severities,
-                                           lengths, messageLog))
-        {
-            return 0;
-        }
-
-        return context->getDebugMessageLog(count, bufSize, sources, types, ids, severities, lengths,
-                                           messageLog);
-    }
-
-    return 0;
-}
-
-void GL_APIENTRY PushDebugGroupKHR(GLenum source, GLuint id, GLsizei length, const GLchar *message)
-{
-    EVENT(
-        "(GLenum source = 0x%X, GLuint id = 0x%X, GLsizei length = %d, const GLchar *message = "
-        "0x%0.8p)",
-        source, id, length, message);
-
-    Context *context = GetValidGlobalContext();
-    if (context)
-    {
-        if (!ValidatePushDebugGroupKHR(context, source, id, length, message))
-        {
-            return;
-        }
-
-        std::string msg(message, (length > 0) ? static_cast<size_t>(length) : strlen(message));
-        context->pushDebugGroup(source, id, length, message);
-    }
-}
-
-void GL_APIENTRY PopDebugGroupKHR(void)
-{
-    EVENT("()");
-
-    Context *context = GetValidGlobalContext();
-    if (context)
-    {
-        if (!ValidatePopDebugGroupKHR(context))
-        {
-            return;
-        }
-
-        context->popDebugGroup();
-    }
-}
-
-void GL_APIENTRY ObjectLabelKHR(GLenum identifier, GLuint name, GLsizei length, const GLchar *label)
-{
-    EVENT(
-        "(GLenum identifier = 0x%X, GLuint name = %u, GLsizei length = %d, const GLchar *label = "
-        "0x%0.8p)",
-        identifier, name, length, label);
-
-    Context *context = GetValidGlobalContext();
-    if (context)
-    {
-        if (!ValidateObjectLabelKHR(context, identifier, name, length, label))
-        {
-            return;
-        }
-
-        context->objectLabel(identifier, name, length, label);
-    }
-}
-
-void GL_APIENTRY
-GetObjectLabelKHR(GLenum identifier, GLuint name, GLsizei bufSize, GLsizei *length, GLchar *label)
-{
-    EVENT(
-        "(GLenum identifier = 0x%X, GLuint name = %u, GLsizei bufSize = %d, GLsizei *length = "
-        "0x%0.8p, GLchar *label = 0x%0.8p)",
-        identifier, name, bufSize, length, label);
-
-    Context *context = GetValidGlobalContext();
-    if (context)
-    {
-        if (!ValidateGetObjectLabelKHR(context, identifier, name, bufSize, length, label))
-        {
-            return;
-        }
-
-        context->getObjectLabel(identifier, name, bufSize, length, label);
-    }
-}
-
-void GL_APIENTRY ObjectPtrLabelKHR(const void *ptr, GLsizei length, const GLchar *label)
-{
-    EVENT("(const void *ptr = 0x%0.8p, GLsizei length = %d, const GLchar *label = 0x%0.8p)", ptr,
-          length, label);
-
-    Context *context = GetValidGlobalContext();
-    if (context)
-    {
-        if (!ValidateObjectPtrLabelKHR(context, ptr, length, label))
-        {
-            return;
-        }
-
-        context->objectPtrLabel(ptr, length, label);
-    }
-}
-
-void GL_APIENTRY GetObjectPtrLabelKHR(const void *ptr,
-                                      GLsizei bufSize,
-                                      GLsizei *length,
-                                      GLchar *label)
-{
-    EVENT(
-        "(const void *ptr = 0x%0.8p, GLsizei bufSize = %d, GLsizei *length = 0x%0.8p, GLchar "
-        "*label = 0x%0.8p)",
-        ptr, bufSize, length, label);
-
-    Context *context = GetValidGlobalContext();
-    if (context)
-    {
-        if (!ValidateGetObjectPtrLabelKHR(context, ptr, bufSize, length, label))
-        {
-            return;
-        }
-
-        context->getObjectPtrLabel(ptr, bufSize, length, label);
-    }
-}
-
-void GL_APIENTRY GetPointervKHR(GLenum pname, void **params)
-{
-    EVENT("(GLenum pname = 0x%X, void **params = 0x%0.8p)", pname, params);
-
-    Context *context = GetValidGlobalContext();
-    if (context)
-    {
-        if (!ValidateGetPointervKHR(context, pname, params))
-        {
-            return;
-        }
-
-        context->getPointerv(pname, params);
-    }
-}
-
 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();
     if (context)
     {
-        if (!ValidateBindUniformLocationCHROMIUM(context, program, location, name))
+        if (!context->skipValidation() &&
+            !ValidateBindUniformLocationCHROMIUM(context, program, location, name))
         {
             return;
         }
 
         context->bindUniformLocation(program, location, name);
     }
 }
 
 ANGLE_EXPORT void GL_APIENTRY CoverageModulationCHROMIUM(GLenum components)
 {
     EVENT("(GLenum components = %u)", components);
 
     Context *context = GetValidGlobalContext();
     if (context)
     {
-        if (!ValidateCoverageModulationCHROMIUM(context, components))
+        if (!context->skipValidation() && !ValidateCoverageModulationCHROMIUM(context, components))
         {
             return;
         }
         context->setCoverageModulation(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() && !ValidateMatrix(context, matrixMode, matrix))
+        if (!context->skipValidation() && !ValidateMatrixLoadfCHROMIUM(context, matrixMode, matrix))
         {
             return;
         }
         context->loadPathRenderingMatrix(matrixMode, matrix);
     }
 }
 
 ANGLE_EXPORT void GL_APIENTRY MatrixLoadIdentityCHROMIUM(GLenum matrixMode)
 {
     EVENT("(GLenum matrixMode = %u)", matrixMode);
 
     Context *context = GetValidGlobalContext();
     if (context)
     {
-        if (!context->skipValidation() && !ValidateMatrixMode(context, matrixMode))
+        if (!context->skipValidation() && !ValidateMatrixLoadIdentityCHROMIUM(context, matrixMode))
         {
             return;
         }
         context->loadPathRenderingIdentityMatrix(matrixMode);
     }
 }
 
 ANGLE_EXPORT GLuint GL_APIENTRY GenPathsCHROMIUM(GLsizei range)
 {
     EVENT("(GLsizei range = %d)", range);
 
     Context *context = GetValidGlobalContext();
     if (context)
     {
-        if (!context->skipValidation() && !ValidateGenPaths(context, range))
+        if (!context->skipValidation() && !ValidateGenPathsCHROMIUM(context, range))
         {
             return 0;
         }
         return context->createPaths(range);
     }
     return 0;
 }
 
 ANGLE_EXPORT void GL_APIENTRY DeletePathsCHROMIUM(GLuint first, GLsizei range)
 {
     EVENT("(GLuint first = %u, GLsizei range = %d)", first, range);
 
     Context *context = GetValidGlobalContext();
     if (context)
     {
-        if (!context->skipValidation() && !ValidateDeletePaths(context, first, range))
+        if (!context->skipValidation() && !ValidateDeletePathsCHROMIUM(context, first, range))
         {
             return;
         }
         context->deletePaths(first, range);
     }
 }
 
 ANGLE_EXPORT GLboolean GL_APIENTRY IsPathCHROMIUM(GLuint path)
 {
     EVENT("(GLuint path = %u)", path);
 
     Context *context = GetValidGlobalContext();
     if (context)
     {
-        if (!context->skipValidation() && !ValidateIsPath(context))
+        if (!context->skipValidation() && !ValidateIsPathCHROMIUM(context))
         {
             return GL_FALSE;
         }
         return context->hasPathData(path);
     }
     return GL_FALSE;
 }
 
@@ -1464,140 +169,163 @@ ANGLE_EXPORT void GL_APIENTRY PathComman
     EVENT(
         "(GLuint path = %u, GLsizei numCommands = %d, commands = %p, "
         "GLsizei numCoords = %d, GLenum coordType = %u, void* coords = %p)",
         path, numCommands, commands, numCoords, coordType, coords);
 
     Context *context = GetValidGlobalContext();
     if (context)
     {
-        if (!context->skipValidation())
+        if (!context->skipValidation() &&
+            !ValidatePathCommandsCHROMIUM(context, path, numCommands, commands, numCoords,
+                                          coordType, coords))
         {
-            if (!ValidatePathCommands(context, path, numCommands, commands, numCoords, coordType,
-                                      coords))
-            {
-                return;
-            }
+            return;
         }
         context->setPathCommands(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();
     if (context)
     {
-        if (!context->skipValidation() && !ValidateSetPathParameter(context, path, pname, value))
+        if (!context->skipValidation() &&
+            !ValidatePathParameterfCHROMIUM(context, path, pname, value))
         {
             return;
         }
-        context->setPathParameterf(path, pname, value);
+
+        context->pathParameterf(path, pname, value);
     }
 }
 
 ANGLE_EXPORT void GL_APIENTRY PathParameteriCHROMIUM(GLuint path, GLenum pname, GLint value)
 {
-    PathParameterfCHROMIUM(path, pname, static_cast<GLfloat>(value));
-}
-
-ANGLE_EXPORT void GL_APIENTRY GetPathParameterfCHROMIUM(GLuint path, GLenum pname, GLfloat *value)
-{
-    EVENT("(GLuint path = %u, GLenum pname = %u)", path, pname);
+    EVENT("(GLuint path = %u, GLenum pname = %u, GLint value = %d)", path, pname, value);
 
     Context *context = GetValidGlobalContext();
     if (context)
     {
-        if (!context->skipValidation() && !ValidateGetPathParameter(context, path, pname, value))
+        if (!context->skipValidation() &&
+            !ValidatePathParameteriCHROMIUM(context, path, pname, value))
+        {
+            return;
+        }
+
+        context->pathParameteri(path, pname, value);
+    }
+}
+
+ANGLE_EXPORT void GL_APIENTRY GetPathParameterfvCHROMIUM(GLuint path, GLenum pname, GLfloat *value)
+{
+    EVENT("(GLuint path = %u, GLenum pname = %u, GLfloat *value = %p)", path, pname, value);
+
+    Context *context = GetValidGlobalContext();
+    if (context)
+    {
+        if (!context->skipValidation() &&
+            !ValidateGetPathParameterfvCHROMIUM(context, path, pname, value))
         {
             return;
         }
         context->getPathParameterfv(path, pname, value);
     }
 }
 
-ANGLE_EXPORT void GL_APIENTRY GetPathParameteriCHROMIUM(GLuint path, GLenum pname, GLint *value)
+ANGLE_EXPORT void GL_APIENTRY GetPathParameterivCHROMIUM(GLuint path, GLenum pname, GLint *value)
 {
-    GLfloat val = 0.0f;
-    GetPathParameterfCHROMIUM(path, pname, value != nullptr ? &val : nullptr);
-    if (value)
-        *value = static_cast<GLint>(val);
+    EVENT("(GLuint path = %u, GLenum pname = %u, GLint *value = %p)", path, pname, value);
+
+    Context *context = GetValidGlobalContext();
+    if (context)
+    {
+        if (!context->skipValidation() &&
+            !ValidateGetPathParameterivCHROMIUM(context, path, pname, value))
+        {
+            return;
+        }
+        context->getPathParameteriv(path, pname, value);
+    }
 }
 
 ANGLE_EXPORT void GL_APIENTRY PathStencilFuncCHROMIUM(GLenum func, GLint ref, GLuint mask)
 {
     EVENT("(GLenum func = %u, GLint ref = %d, GLuint mask = %u)", func, ref, mask);
 
     Context *context = GetValidGlobalContext();
     if (context)
     {
-        if (!context->skipValidation() && !ValidatePathStencilFunc(context, func, ref, mask))
+        if (!context->skipValidation() &&
+            !ValidatePathStencilFuncCHROMIUM(context, func, ref, mask))
         {
             return;
         }
         context->setPathStencilFunc(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();
     if (context)
     {
-        if (!context->skipValidation() && !ValidateStencilFillPath(context, path, fillMode, mask))
+        if (!context->skipValidation() &&
+            !ValidateStencilFillPathCHROMIUM(context, path, fillMode, mask))
         {
             return;
         }
         context->stencilFillPath(path, fillMode, mask);
     }
 }
 
 ANGLE_EXPORT void GL_APIENTRY StencilStrokePathCHROMIUM(GLuint path, GLint reference, GLuint mask)
 {
     EVENT("(GLuint path = %u, GLint ference = %d, GLuint mask = %u)", path, reference, mask);
 
     Context *context = GetValidGlobalContext();
     if (context)
     {
         if (!context->skipValidation() &&
-            !ValidateStencilStrokePath(context, path, reference, mask))
+            !ValidateStencilStrokePathCHROMIUM(context, path, reference, mask))
         {
             return;
         }
         context->stencilStrokePath(path, reference, mask);
     }
 }
 
 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() && !ValidateCoverPath(context, path, coverMode))
+        if (!context->skipValidation() && !ValidateCoverPathCHROMIUM(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() && !ValidateCoverPath(context, path, coverMode))
+        if (!context->skipValidation() && !ValidateCoverPathCHROMIUM(context, path, coverMode))
         {
             return;
         }
         context->coverStrokePath(path, coverMode);
     }
 }
 
 ANGLE_EXPORT void GL_APIENTRY StencilThenCoverFillPathCHROMIUM(GLuint path,
@@ -1607,17 +335,17 @@ ANGLE_EXPORT void GL_APIENTRY StencilThe
 {
     EVENT("(GLuint path = %u, GLenum fillMode = %u, GLuint mask = %u, GLenum coverMode = %u)", path,
           fillMode, mask, coverMode);
 
     Context *context = GetValidGlobalContext();
     if (context)
     {
         if (!context->skipValidation() &&
-            !ValidateStencilThenCoverFillPath(context, path, fillMode, mask, coverMode))
+            !ValidateStencilThenCoverFillPathCHROMIUM(context, path, fillMode, mask, coverMode))
         {
             return;
         }
         context->stencilThenCoverFillPath(path, fillMode, mask, coverMode);
     }
 }
 
 ANGLE_EXPORT void GL_APIENTRY StencilThenCoverStrokePathCHROMIUM(GLuint path,
@@ -1627,17 +355,17 @@ ANGLE_EXPORT void GL_APIENTRY StencilThe
 {
     EVENT("(GLuint path = %u, GLint reference = %d, GLuint mask = %u, GLenum coverMode = %u)", path,
           reference, mask, coverMode);
 
     Context *context = GetValidGlobalContext();
     if (context)
     {
         if (!context->skipValidation() &&
-            !ValidateStencilThenCoverStrokePath(context, path, reference, mask, coverMode))
+            !ValidateStencilThenCoverStrokePathCHROMIUM(context, path, reference, mask, coverMode))
         {
             return;
         }
         context->stencilThenCoverStrokePath(path, reference, mask, coverMode);
     }
 }
 
 ANGLE_EXPORT void GL_APIENTRY CoverFillPathInstancedCHROMIUM(GLsizei numPaths,
@@ -1652,19 +380,19 @@ ANGLE_EXPORT void GL_APIENTRY CoverFillP
         "(GLsizei numPaths = %d, GLenum pathNameType = %u, const void *paths = %p "
         "GLuint pathBase = %u, GLenum coverMode = %u, GLenum transformType = %u "
         "const GLfloat *transformValues = %p)",
         numPaths, pathNameType, paths, pathBase, coverMode, transformType, transformValues);
 
     Context *context = GetValidGlobalContext();
     if (context)
     {
-        if (!context->skipValidation() &&
-            !ValidateCoverFillPathInstanced(context, numPaths, pathNameType, paths, pathBase,
-                                            coverMode, transformType, transformValues))
+        if (!context->skipValidation() && !ValidateCoverFillPathInstancedCHROMIUM(
+                                              context, numPaths, pathNameType, paths, pathBase,
+                                              coverMode, transformType, transformValues))
         {
             return;
         }
         context->coverFillPathInstanced(numPaths, pathNameType, paths, pathBase, coverMode,
                                         transformType, transformValues);
     }
 }
 
@@ -1680,18 +408,18 @@ ANGLE_EXPORT void GL_APIENTRY CoverStrok
         "(GLsizei numPaths = %d, GLenum pathNameType = %u, const void *paths = %p "
         "GLuint pathBase = %u, GLenum coverMode = %u, GLenum transformType = %u "
         "const GLfloat *transformValues = %p)",
         numPaths, pathNameType, paths, pathBase, coverMode, transformType, transformValues);
 
     Context *context = GetValidGlobalContext();
     if (context)
     {
-        if (!context->skipValidation() &&
-            !ValidateCoverStrokePathInstanced(context, numPaths, pathNameType, paths, pathBase,
+        if (!context->skipValidation() && !ValidateCoverStrokePathInstancedCHROMIUM(
+                                              context, numPaths, pathNameType, paths, pathBase,
                                               coverMode, transformType, transformValues))
         {
             return;
         }
         context->coverStrokePathInstanced(numPaths, pathNameType, paths, pathBase, coverMode,
                                           transformType, transformValues);
     }
 }
@@ -1709,19 +437,19 @@ ANGLE_EXPORT void GL_APIENTRY StencilStr
         "(GLsizei numPaths = %u, GLenum pathNameType = %u, const void *paths = %p "
         "GLuint pathBase = %u, GLint reference = %d GLuint mask = %u GLenum transformType = %u "
         "const GLfloat *transformValues = %p)",
         numPaths, pathNameType, paths, pathBase, reference, mask, transformType, transformValues);
 
     Context *context = GetValidGlobalContext();
     if (context)
     {
-        if (!context->skipValidation() &&
-            !ValidateStencilStrokePathInstanced(context, numPaths, pathNameType, paths, pathBase,
-                                                reference, mask, transformType, transformValues))
+        if (!context->skipValidation() && !ValidateStencilStrokePathInstancedCHROMIUM(
+                                              context, numPaths, pathNameType, paths, pathBase,
+                                              reference, mask, transformType, transformValues))
         {
             return;
         }
         context->stencilStrokePathInstanced(numPaths, pathNameType, paths, pathBase, reference,
                                             mask, transformType, transformValues);
     }
 }
 
@@ -1738,18 +466,18 @@ ANGLE_EXPORT void GL_APIENTRY StencilFil
         "(GLsizei numPaths = %u, GLenum pathNameType = %u const void *paths = %p "
         "GLuint pathBase = %u, GLenum fillMode = %u, GLuint mask = %u, GLenum transformType = %u "
         "const GLfloat *transformValues = %p)",
         numPaths, pathNameType, paths, pathBase, fillMode, mask, transformType, transformValues);
 
     Context *context = GetValidGlobalContext();
     if (context)
     {
-        if (!context->skipValidation() &&
-            !ValidateStencilFillPathInstanced(context, numPaths, pathNameType, paths, pathBase,
+        if (!context->skipValidation() && !ValidateStencilFillPathInstancedCHROMIUM(
+                                              context, numPaths, pathNameType, paths, pathBase,
                                               fillMode, mask, transformType, transformValues))
         {
             return;
         }
         context->stencilFillPathInstanced(numPaths, pathNameType, paths, pathBase, fillMode, mask,
                                           transformType, transformValues);
     }
 }
@@ -1770,19 +498,19 @@ StencilThenCoverFillPathInstancedCHROMIU
         "GLuint pathBase = %u, GLenum coverMode = %u, GLuint mask = %u, GLenum transformType = %u "
         "const GLfloat *transformValues = %p)",
         numPaths, pathNameType, paths, pathBase, coverMode, mask, transformType, transformValues);
 
     Context *context = GetValidGlobalContext();
     if (context)
     {
         if (!context->skipValidation() &&
-            !ValidateStencilThenCoverFillPathInstanced(context, numPaths, pathNameType, paths,
-                                                       pathBase, fillMode, mask, coverMode,
-                                                       transformType, transformValues))
+            !ValidateStencilThenCoverFillPathInstancedCHROMIUM(
+                context, numPaths, pathNameType, paths, pathBase, fillMode, mask, coverMode,
+                transformType, transformValues))
         {
             return;
         }
         context->stencilThenCoverFillPathInstanced(numPaths, pathNameType, paths, pathBase,
                                                    fillMode, mask, coverMode, transformType,
                                                    transformValues);
     }
 }
@@ -1805,19 +533,19 @@ StencilThenCoverStrokePathInstancedCHROM
         "const GLfloat *transformValues = %p)",
         numPaths, pathNameType, paths, pathBase, coverMode, reference, mask, transformType,
         transformValues);
 
     Context *context = GetValidGlobalContext();
     if (context)
     {
         if (!context->skipValidation() &&
-            !ValidateStencilThenCoverStrokePathInstanced(context, numPaths, pathNameType, paths,
-                                                         pathBase, reference, mask, coverMode,
-                                                         transformType, transformValues))
+            !ValidateStencilThenCoverStrokePathInstancedCHROMIUM(
+                context, numPaths, pathNameType, paths, pathBase, reference, mask, coverMode,
+                transformType, transformValues))
         {
             return;
         }
         context->stencilThenCoverStrokePathInstanced(numPaths, pathNameType, paths, pathBase,
                                                      reference, mask, coverMode, transformType,
                                                      transformValues);
     }
 }
@@ -1828,17 +556,17 @@ ANGLE_EXPORT void GL_APIENTRY BindFragme
 {
     EVENT("(GLuint program = %u, GLint location = %d, const GLchar *name = %p)", program, location,
           name);
 
     Context *context = GetValidGlobalContext();
     if (context)
     {
         if (!context->skipValidation() &&
-            !ValidateBindFragmentInputLocation(context, program, location, name))
+            !ValidateBindFragmentInputLocationCHROMIUM(context, program, location, name))
         {
             return;
         }
         context->bindFragmentInputLocation(program, location, name);
     }
 }
 
 ANGLE_EXPORT void GL_APIENTRY ProgramPathFragmentInputGenCHROMIUM(GLuint program,
@@ -1851,18 +579,18 @@ ANGLE_EXPORT void GL_APIENTRY ProgramPat
         "(GLuint program = %u, GLint location %d, GLenum genMode = %u, GLint components = %d, "
         "const GLfloat * coeffs = %p)",
         program, location, genMode, components, coeffs);
 
     Context *context = GetValidGlobalContext();
     if (context)
     {
         if (!context->skipValidation() &&
-            !ValidateProgramPathFragmentInputGen(context, program, location, genMode, components,
-                                                 coeffs))
+            !ValidateProgramPathFragmentInputGenCHROMIUM(context, program, location, genMode,
+                                                         components, coeffs))
         {
             return;
         }
         context->programPathFragmentInputGen(program, location, genMode, components, coeffs);
     }
 }
 
 ANGLE_EXPORT void GL_APIENTRY CopyTextureCHROMIUM(GLuint sourceId,
@@ -1890,19 +618,18 @@ ANGLE_EXPORT void GL_APIENTRY CopyTextur
         if (!context->skipValidation() &&
             !ValidateCopyTextureCHROMIUM(context, sourceId, sourceLevel, destTarget, destId,
                                          destLevel, internalFormat, destType, unpackFlipY,
                                          unpackPremultiplyAlpha, unpackUnmultiplyAlpha))
         {
             return;
         }
 
-        context->copyTextureCHROMIUM(sourceId, sourceLevel, destTarget, destId, destLevel,
-                                     internalFormat, destType, unpackFlipY, unpackPremultiplyAlpha,
-                                     unpackUnmultiplyAlpha);
+        context->copyTexture(sourceId, sourceLevel, destTarget, destId, destLevel, internalFormat,
+                             destType, unpackFlipY, unpackPremultiplyAlpha, unpackUnmultiplyAlpha);
     }
 }
 
 ANGLE_EXPORT void GL_APIENTRY CopySubTextureCHROMIUM(GLuint sourceId,
                                                      GLint sourceLevel,
                                                      GLenum destTarget,
                                                      GLuint destId,
                                                      GLint destLevel,
@@ -1930,36 +657,36 @@ ANGLE_EXPORT void GL_APIENTRY CopySubTex
         if (!context->skipValidation() &&
             !ValidateCopySubTextureCHROMIUM(
                 context, sourceId, sourceLevel, destTarget, destId, destLevel, xoffset, yoffset, x,
                 y, width, height, unpackFlipY, unpackPremultiplyAlpha, unpackUnmultiplyAlpha))
         {
             return;
         }
 
-        context->copySubTextureCHROMIUM(sourceId, sourceLevel, destTarget, destId, destLevel,
-                                        xoffset, yoffset, x, y, width, height, unpackFlipY,
-                                        unpackPremultiplyAlpha, unpackUnmultiplyAlpha);
+        context->copySubTexture(sourceId, sourceLevel, destTarget, 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);
 
     Context *context = GetValidGlobalContext();
     if (context)
     {
         if (!context->skipValidation() &&
             !ValidateCompressedCopyTextureCHROMIUM(context, sourceId, destId))
         {
             return;
         }
 
-        context->compressedCopyTextureCHROMIUM(sourceId, destId);
+        context->compressedCopyTexture(sourceId, destId);
     }
 }
 
 ANGLE_EXPORT void GL_APIENTRY RequestExtensionANGLE(const GLchar *name)
 {
     EVENT("(const GLchar *name = %p)", name);
 
     Context *context = GetValidGlobalContext();
@@ -2006,24 +733,26 @@ ANGLE_EXPORT void GL_APIENTRY GetBufferP
                                                               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);
+
         GLsizei numParams = 0;
-        if (!ValidateGetBufferParameterivRobustANGLE(context, target, pname, bufSize, &numParams,
-                                                     params))
+        if (!ValidateGetBufferParameterivRobustANGLE(context, targetPacked, pname, bufSize,
+                                                     &numParams, params))
         {
             return;
         }
 
-        Buffer *buffer = context->getGLState().getTargetBuffer(target);
+        Buffer *buffer = context->getGLState().getTargetBuffer(targetPacked);
         QueryBufferParameteriv(buffer, pname, params);
         SetRobustLengthParam(length, numParams);
     }
 }
 
 ANGLE_EXPORT void GL_APIENTRY GetFloatvRobustANGLE(GLenum pname,
                                                    GLsizei bufSize,
                                                    GLsizei *length,
@@ -2067,17 +796,17 @@ ANGLE_EXPORT void GL_APIENTRY GetFramebu
         GLsizei numParams = 0;
         if (!ValidateGetFramebufferAttachmentParameterivRobustANGLE(context, target, attachment,
                                                                     pname, bufSize, &numParams))
         {
             return;
         }
 
         const Framebuffer *framebuffer = context->getGLState().getTargetFramebuffer(target);
-        QueryFramebufferAttachmentParameteriv(framebuffer, attachment, pname, params);
+        QueryFramebufferAttachmentParameteriv(context, framebuffer, attachment, pname, params);
         SetRobustLengthParam(length, numParams);
     }
 }
 
 ANGLE_EXPORT void GL_APIENTRY GetIntegervRobustANGLE(GLenum pname,
                                                      GLsizei bufSize,
                                                      GLsizei *length,
                                                      GLint *data)
@@ -2771,24 +1500,26 @@ ANGLE_EXPORT void GL_APIENTRY GetBufferP
     EVENT(
         "(GLenum target = 0x%X, GLenum pname = 0x%X,  GLsizei bufsize = %d, GLsizei* length = "
         "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, target, pname, bufSize, &numParams,
+        if (!ValidateGetBufferPointervRobustANGLE(context, targetPacked, pname, bufSize, &numParams,
                                                   params))
         {
             return;
         }
 
-        context->getBufferPointerv(target, pname, params);
+        context->getBufferPointerv(targetPacked, pname, params);
         SetRobustLengthParam(length, numParams);
     }
 }
 
 ANGLE_EXPORT void GL_APIENTRY
 GetIntegeri_vRobustANGLE(GLenum target, GLuint index, GLsizei bufSize, GLsizei *length, GLint *data)
 {
     EVENT(
@@ -3011,24 +1742,26 @@ ANGLE_EXPORT void GL_APIENTRY GetBufferP
                                                                 GLint64 *params)
 {
     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, target, pname, bufSize, &numParams,
-                                                       params))
+        if (!ValidateGetBufferParameteri64vRobustANGLE(context, targetPacked, pname, bufSize,
+                                                       &numParams, params))
         {
             return;
         }
 
-        Buffer *buffer = context->getGLState().getTargetBuffer(target);
+        Buffer *buffer = context->getGLState().getTargetBuffer(targetPacked);
         QueryBufferParameteri64v(buffer, pname, params);
         SetRobustLengthParam(length, numParams);
     }
 }
 
 ANGLE_EXPORT void GL_APIENTRY SamplerParameterivRobustANGLE(GLuint sampler,
                                                             GLenum pname,
                                                             GLsizei bufSize,
--- a/gfx/angle/src/libGLESv2/entry_points_gles_2_0_ext.h
+++ b/gfx/angle/src/libGLESv2/entry_points_gles_2_0_ext.h
@@ -11,195 +11,16 @@
 
 #include <GLES2/gl2.h>
 #include <GLES2/gl2ext.h>
 #include <export.h>
 
 namespace gl
 {
 
-// GL_ANGLE_framebuffer_blit
-ANGLE_EXPORT void GL_APIENTRY BlitFramebufferANGLE(GLint srcX0,
-                                                   GLint srcY0,
-                                                   GLint srcX1,
-                                                   GLint srcY1,
-                                                   GLint dstX0,
-                                                   GLint dstY0,
-                                                   GLint dstX1,
-                                                   GLint dstY1,
-                                                   GLbitfield mask,
-                                                   GLenum filter);
-
-// GL_ANGLE_framebuffer_multisample
-ANGLE_EXPORT void GL_APIENTRY RenderbufferStorageMultisampleANGLE(GLenum target,
-                                                                  GLsizei samples,
-                                                                  GLenum internalformat,
-                                                                  GLsizei width,
-                                                                  GLsizei height);
-
-// GL_EXT_discard_framebuffer
-ANGLE_EXPORT void GL_APIENTRY DiscardFramebufferEXT(GLenum target,
-                                                    GLsizei numAttachments,
-                                                    const GLenum *attachments);
-
-// GL_NV_fence
-ANGLE_EXPORT void GL_APIENTRY DeleteFencesNV(GLsizei n, const GLuint *fences);
-ANGLE_EXPORT void GL_APIENTRY GenFencesNV(GLsizei n, GLuint *fences);
-ANGLE_EXPORT GLboolean GL_APIENTRY IsFenceNV(GLuint fence);
-ANGLE_EXPORT GLboolean GL_APIENTRY TestFenceNV(GLuint fence);
-ANGLE_EXPORT void GL_APIENTRY GetFenceivNV(GLuint fence, GLenum pname, GLint *params);
-ANGLE_EXPORT void GL_APIENTRY FinishFenceNV(GLuint fence);
-ANGLE_EXPORT void GL_APIENTRY SetFenceNV(GLuint fence, GLenum condition);
-
-// GL_ANGLE_translated_shader_source
-ANGLE_EXPORT void GL_APIENTRY GetTranslatedShaderSourceANGLE(GLuint shader,
-                                                             GLsizei bufsize,
-                                                             GLsizei *length,
-                                                             GLchar *source);
-
-// GL_EXT_texture_storage
-ANGLE_EXPORT void GL_APIENTRY TexStorage2DEXT(GLenum target,
-                                              GLsizei levels,
-                                              GLenum internalformat,
-                                              GLsizei width,
-                                              GLsizei height);
-
-// GL_EXT_robustness
-ANGLE_EXPORT GLenum GL_APIENTRY GetGraphicsResetStatusEXT(void);
-ANGLE_EXPORT void GL_APIENTRY ReadnPixelsEXT(GLint x,
-                                             GLint y,
-                                             GLsizei width,
-                                             GLsizei height,
-                                             GLenum format,
-                                             GLenum type,
-                                             GLsizei bufSize,
-                                             void *data);
-ANGLE_EXPORT void GL_APIENTRY GetnUniformfvEXT(GLuint program,
-                                               GLint location,
-                                               GLsizei bufSize,
-                                               float *params);
-ANGLE_EXPORT void GL_APIENTRY GetnUniformivEXT(GLuint program,
-                                               GLint location,
-                                               GLsizei bufSize,
-                                               GLint *params);
-
-// GL_EXT_occlusion_query_boolean
-ANGLE_EXPORT void GL_APIENTRY GenQueriesEXT(GLsizei n, GLuint *ids);
-ANGLE_EXPORT void GL_APIENTRY DeleteQueriesEXT(GLsizei n, const GLuint *ids);
-ANGLE_EXPORT GLboolean GL_APIENTRY IsQueryEXT(GLuint id);
-ANGLE_EXPORT void GL_APIENTRY BeginQueryEXT(GLenum target, GLuint id);
-ANGLE_EXPORT void GL_APIENTRY EndQueryEXT(GLenum target);
-ANGLE_EXPORT void GL_APIENTRY GetQueryivEXT(GLenum target, GLenum pname, GLint *params);
-ANGLE_EXPORT void GL_APIENTRY GetQueryObjectuivEXT(GLuint id, GLenum pname, GLuint *params);
-
-// GL_EXT_disjoint_timer_query
-ANGLE_EXPORT void GL_APIENTRY QueryCounterEXT(GLuint id, GLenum target);
-ANGLE_EXPORT void GL_APIENTRY GetQueryObjectivEXT(GLuint id, GLenum pname, GLint *params);
-ANGLE_EXPORT void GL_APIENTRY GetQueryObjecti64vEXT(GLuint id, GLenum pname, GLint64 *params);
-ANGLE_EXPORT void GL_APIENTRY GetQueryObjectui64vEXT(GLuint id, GLenum pname, GLuint64 *params);
-
-// GL_EXT_draw_buffers
-ANGLE_EXPORT void GL_APIENTRY DrawBuffersEXT(GLsizei n, const GLenum *bufs);
-
-// GL_ANGLE_instanced_arrays
-ANGLE_EXPORT void GL_APIENTRY DrawArraysInstancedANGLE(GLenum mode,
-                                                       GLint first,
-                                                       GLsizei count,
-                                                       GLsizei primcount);
-ANGLE_EXPORT void GL_APIENTRY DrawElementsInstancedANGLE(GLenum mode,
-                                                         GLsizei count,
-                                                         GLenum type,
-                                                         const void *indices,
-                                                         GLsizei primcount);
-ANGLE_EXPORT void GL_APIENTRY VertexAttribDivisorANGLE(GLuint index, GLuint divisor);
-
-// 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,
-                                               const void *binary,
-                                               GLint length);
-
-// GL_OES_mapbuffer
-ANGLE_EXPORT void *GL_APIENTRY MapBufferOES(GLenum target, GLenum access);
-ANGLE_EXPORT GLboolean GL_APIENTRY UnmapBufferOES(GLenum target);
-ANGLE_EXPORT void GL_APIENTRY GetBufferPointervOES(GLenum target, GLenum pname, void **params);
-
-// GL_EXT_map_buffer_range
-ANGLE_EXPORT void *GL_APIENTRY MapBufferRangeEXT(GLenum target,
-                                                 GLintptr offset,
-                                                 GLsizeiptr length,
-                                                 GLbitfield access);
-ANGLE_EXPORT void GL_APIENTRY FlushMappedBufferRangeEXT(GLenum target,
-                                                        GLintptr offset,
-                                                        GLsizeiptr length);
-
-// GL_EXT_debug_marker
-ANGLE_EXPORT void GL_APIENTRY InsertEventMarkerEXT(GLsizei length, const char *marker);
-ANGLE_EXPORT void GL_APIENTRY PushGroupMarkerEXT(GLsizei length, const char *marker);
-ANGLE_EXPORT void GL_APIENTRY PopGroupMarkerEXT();
-
-// GL_OES_EGL_image
-ANGLE_EXPORT void GL_APIENTRY EGLImageTargetTexture2DOES(GLenum target, GLeglImageOES image);
-ANGLE_EXPORT void GL_APIENTRY EGLImageTargetRenderbufferStorageOES(GLenum target,
-                                                                   GLeglImageOES image);
-
-// 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);
-
-// GL_KHR_debug
-ANGLE_EXPORT void GL_APIENTRY DebugMessageControlKHR(GLenum source,
-                                                     GLenum type,
-                                                     GLenum severity,
-                                                     GLsizei count,
-                                                     const GLuint *ids,
-                                                     GLboolean enabled);
-ANGLE_EXPORT void GL_APIENTRY DebugMessageInsertKHR(GLenum source,
-                                                    GLenum type,
-                                                    GLuint id,
-                                                    GLenum severity,
-                                                    GLsizei length,
-                                                    const GLchar *buf);
-ANGLE_EXPORT void GL_APIENTRY DebugMessageCallbackKHR(GLDEBUGPROCKHR callback,
-                                                      const void *userParam);
-ANGLE_EXPORT GLuint GL_APIENTRY GetDebugMessageLogKHR(GLuint count,
-                                                      GLsizei bufSize,
-                                                      GLenum *sources,
-                                                      GLenum *types,
-                                                      GLuint *ids,
-                                                      GLenum *severities,
-                                                      GLsizei *lengths,
-                                                      GLchar *messageLog);
-ANGLE_EXPORT void GL_APIENTRY PushDebugGroupKHR(GLenum source,
-                                                GLuint id,
-                                                GLsizei length,
-                                                const GLchar *message);
-ANGLE_EXPORT void GL_APIENTRY PopDebugGroupKHR(void);
-ANGLE_EXPORT void GL_APIENTRY ObjectLabelKHR(GLenum identifier,
-                                             GLuint name,
-                                             GLsizei length,
-                                             const GLchar *label);
-ANGLE_EXPORT void GL_APIENTRY
-GetObjectLabelKHR(GLenum identifier, GLuint name, GLsizei bufSize, GLsizei *length, GLchar *label);
-ANGLE_EXPORT void GL_APIENTRY ObjectPtrLabelKHR(const void *ptr,
-                                                GLsizei length,
-                                                const GLchar *label);
-ANGLE_EXPORT void GL_APIENTRY GetObjectPtrLabelKHR(const void *ptr,
-                                                   GLsizei bufSize,
-                                                   GLsizei *length,
-                                                   GLchar *label);
-ANGLE_EXPORT void GL_APIENTRY GetPointervKHR(GLenum pname, void **params);
-
 // GL_CHROMIUM_bind_uniform_location
 ANGLE_EXPORT void GL_APIENTRY BindUniformLocationCHROMIUM(GLuint program,
                                                           GLint location,
                                                           const GLchar *name);
 
 // GL_CHROMIUM_framebuffer_mixed_samples
 ANGLE_EXPORT void GL_APIENTRY MatrixLoadfCHROMIUM(GLenum matrixMode, const GLfloat *matrix);
 ANGLE_EXPORT void GL_APIENTRY MatrixLoadIdentityCHROMIUM(GLenum matrixMode);
@@ -213,18 +34,18 @@ ANGLE_EXPORT GLboolean GL_APIENTRY IsPat
 ANGLE_EXPORT void GL_APIENTRY PathCommandsCHROMIUM(GLuint path,
                                                    GLsizei numCommands,
                                                    const GLubyte *commands,
                                                    GLsizei numCoords,
                                                    GLenum coordType,
                                                    const void *coords);
 ANGLE_EXPORT void GL_APIENTRY PathParameterfCHROMIUM(GLuint path, GLenum pname, GLfloat value);
 ANGLE_EXPORT void GL_APIENTRY PathParameteriCHROMIUM(GLuint path, GLenum pname, GLint value);
-ANGLE_EXPORT void GL_APIENTRY GetPathParameterfCHROMIUM(GLuint path, GLenum pname, GLfloat *value);
-ANGLE_EXPORT void GL_APIENTRY GetPathParameteriCHROMIUM(GLuint path, GLenum pname, GLint *value);
+ANGLE_EXPORT void GL_APIENTRY GetPathParameterfvCHROMIUM(GLuint path, GLenum pname, GLfloat *value);
+ANGLE_EXPORT void GL_APIENTRY GetPathParameterivCHROMIUM(GLuint path, GLenum pname, GLint *value);
 ANGLE_EXPORT void GL_APIENTRY PathStencilFuncCHROMIUM(GLenum func, GLint ref, GLuint mask);
 ANGLE_EXPORT void GL_APIENTRY StencilFillPathCHROMIUM(GLuint path, GLenum fillMode, GLuint mask);
 ANGLE_EXPORT void GL_APIENTRY StencilStrokePathCHROMIUM(GLuint path, GLint reference, GLuint mask);
 ANGLE_EXPORT void GL_APIENTRY CoverFillPathCHROMIUM(GLuint path, GLenum coverMode);
 ANGLE_EXPORT void GL_APIENTRY CoverStrokePathCHROMIUM(GLuint path, GLenum coverMode);
 ANGLE_EXPORT void GL_APIENTRY StencilThenCoverFillPathCHROMIUM(GLuint path,
                                                                GLenum fillMode,
                                                                GLuint mask,
new file mode 100644
--- /dev/null
+++ b/gfx/angle/src/libGLESv2/entry_points_gles_2_0_ext_autogen.cpp
@@ -0,0 +1,1227 @@
+// 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.
+//
+// entry_points_gles_2_0_ext_autogen.cpp:
+//   Defines the GLES extension entry points.
+
+#include "libANGLE/Context.h"
+#include "libANGLE/validationES.h"
+#include "libANGLE/validationES2.h"
+#include "libANGLE/validationES3.h"
+#include "libANGLE/validationES31.h"
+#include "libGLESv2/global_state.h"
+
+namespace gl
+{
+
+// GL_ANGLE_framebuffer_blit
+void GL_APIENTRY BlitFramebufferANGLE(GLint srcX0,
+                                      GLint srcY0,
+                                      GLint srcX1,
+                                      GLint srcY1,
+                                      GLint dstX0,
+                                      GLint dstY0,
+                                      GLint dstX1,
+                                      GLint dstY1,
+                                      GLbitfield mask,
+                                      GLenum filter)
+{
+    EVENT(
+        "(GLint srcX0 = %d, GLint srcY0 = %d, GLint srcX1 = %d, GLint srcY1 = %d, GLint dstX0 = "
+        "%d, GLint dstY0 = %d, GLint dstX1 = %d, GLint dstY1 = %d, GLbitfield mask = 0x%X, GLenum "
+        "filter = 0x%X)",
+        srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, mask, filter);
+
+    Context *context = GetValidGlobalContext();
+    if (context)
+    {
+        context->gatherParams<EntryPoint::BlitFramebufferANGLE>(srcX0, srcY0, srcX1, srcY1, dstX0,
+                                                                dstY0, dstX1, dstY1, mask, filter);
+
+        if (context->skipValidation() ||
+            ValidateBlitFramebufferANGLE(context, srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1,
+                                         dstY1, mask, filter))
+        {
+            context->blitFramebuffer(srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, mask,
+                                     filter);
+        }
+    }
+}
+
+// GL_ANGLE_framebuffer_multisample
+void GL_APIENTRY RenderbufferStorageMultisampleANGLE(GLenum target,
+                                                     GLsizei samples,
+                                                     GLenum internalformat,
+                                                     GLsizei width,
+                                                     GLsizei height)
+{
+    EVENT(
+        "(GLenum target = 0x%X, GLsizei samples = %d, GLenum internalformat = 0x%X, GLsizei width "
+        "= %d, GLsizei height = %d)",
+        target, samples, internalformat, width, height);
+
+    Context *context = GetValidGlobalContext();
+    if (context)
+    {
+        context->gatherParams<EntryPoint::RenderbufferStorageMultisampleANGLE>(
+            target, samples, internalformat, width, height);
+
+        if (context->skipValidation() ||
+            ValidateRenderbufferStorageMultisampleANGLE(context, target, samples, internalformat,
+                                                        width, height))
+        {
+            context->renderbufferStorageMultisample(target, samples, internalformat, width, height);
+        }
+    }
+}
+
+// GL_ANGLE_instanced_arrays
+void GL_APIENTRY DrawArraysInstancedANGLE(GLenum mode,
+                                          GLint first,
+                                          GLsizei count,
+                                          GLsizei primcount)
+{
+    EVENT("(GLenum mode = 0x%X, GLint first = %d, GLsizei count = %d, GLsizei primcount = %d)",
+          mode, first, count, primcount);
+
+    Context *context = GetValidGlobalContext();
+    if (context)
+    {
+        context->gatherParams<EntryPoint::DrawArraysInstancedANGLE>(mode, first, count, primcount);
+
+        if (context->skipValidation() ||
+            ValidateDrawArraysInstancedANGLE(context, mode, first, count, primcount))
+        {
+            context->drawArraysInstanced(mode, first, count, primcount);
+        }
+    }
+}
+
+void GL_APIENTRY DrawElementsInstancedANGLE(GLenum mode,
+                                            GLsizei count,
+                                            GLenum type,
+                                            const void *indices,
+                                            GLsizei primcount)
+{
+    EVENT(
+        "(GLenum mode = 0x%X, GLsizei count = %d, GLenum type = 0x%X, const void *indices = "
+        "0x%0.8p, GLsizei primcount = %d)",
+        mode, count, type, indices, primcount);
+
+    Context *context = GetValidGlobalContext();
+    if (context)
+    {
+        context->gatherParams<EntryPoint::DrawElementsInstancedANGLE>(mode, count, type, indices,
+                                                                      primcount);
+
+        if (context->skipValidation() ||
+            ValidateDrawElementsInstancedANGLE(context, mode, count, type, indices, primcount))
+        {
+            context->drawElementsInstanced(mode, count, type, indices, primcount);
+        }
+    }
+}
+
+void GL_APIENTRY VertexAttribDivisorANGLE(GLuint index, GLuint divisor)
+{
+    EVENT("(GLuint index = %u, GLuint divisor = %u)", index, divisor);
+
+    Context *context = GetValidGlobalContext();
+    if (context)
+    {
+        context->gatherParams<EntryPoint::VertexAttribDivisorANGLE>(index, divisor);
+
+        if (context->skipValidation() || ValidateVertexAttribDivisorANGLE(context, index, divisor))
+        {
+            context->vertexAttribDivisor(index, divisor);
+        }
+    }
+}
+
+// GL_ANGLE_translated_shader_source
+void GL_APIENTRY GetTranslatedShaderSourceANGLE(GLuint shader,
+                                                GLsizei bufsize,
+                                                GLsizei *length,
+                                                GLchar *source)
+{
+    EVENT(
+        "(GLuint shader = %u, GLsizei bufsize = %d, GLsizei *length = 0x%0.8p, GLchar *source = "
+        "0x%0.8p)",
+        shader, bufsize, length, source);
+
+    Context *context = GetValidGlobalContext();
+    if (context)
+    {
+        context->gatherParams<EntryPoint::GetTranslatedShaderSourceANGLE>(shader, bufsize, length,
+                                                                          source);
+
+        if (context->skipValidation() ||
+            ValidateGetTranslatedShaderSourceANGLE(context, shader, bufsize, length, source))
+        {
+            context->getTranslatedShaderSource(shader, bufsize, length, source);
+        }
+    }
+}
+
+// GL_EXT_debug_marker
+void GL_APIENTRY InsertEventMarkerEXT(GLsizei length, const GLchar *marker)
+{
+    // Don't run an EVENT() macro on the EXT_debug_marker entry points.
+    // It can interfere with the debug events being set by the caller.
+    // EVENT("(GLsizei length = %d, const GLchar *marker = 0x%0.8p)", length, marker);
+
+    Context *context = GetValidGlobalContext();
+    if (context)
+    {
+        context->gatherParams<EntryPoint::InsertEventMarkerEXT>(length, marker);
+
+        if (context->skipValidation() || ValidateInsertEventMarkerEXT(context, length, marker))
+        {
+            context->insertEventMarker(length, marker);
+        }
+    }
+}
+
+void GL_APIENTRY PopGroupMarkerEXT()
+{
+    // Don't run an EVENT() macro on the EXT_debug_marker entry points.
+    // It can interfere with the debug events being set by the caller.
+    // EVENT("()");
+
+    Context *context = GetValidGlobalContext();
+    if (context)
+    {
+        context->gatherParams<EntryPoint::PopGroupMarkerEXT>();
+
+        if (context->skipValidation() || ValidatePopGroupMarkerEXT(context))
+        {
+            context->popGroupMarker();
+        }
+    }
+}
+
+void GL_APIENTRY PushGroupMarkerEXT(GLsizei length, const GLchar *marker)
+{
+    // Don't run an EVENT() macro on the EXT_debug_marker entry points.
+    // It can interfere with the debug events being set by the caller.
+    // EVENT("(GLsizei length = %d, const GLchar *marker = 0x%0.8p)", length, marker);
+
+    Context *context = GetValidGlobalContext();
+    if (context)
+    {
+        context->gatherParams<EntryPoint::PushGroupMarkerEXT>(length, marker);
+
+        if (context->skipValidation() || ValidatePushGroupMarkerEXT(context, length, marker))
+        {
+            context->pushGroupMarker(length, marker);
+        }
+    }
+}
+
+// GL_EXT_discard_framebuffer
+void GL_APIENTRY DiscardFramebufferEXT(GLenum target,
+                                       GLsizei numAttachments,
+                                       const GLenum *attachments)
+{
+    EVENT(
+        "(GLenum target = 0x%X, GLsizei numAttachments = %d, const GLenum *attachments = 0x%0.8p)",
+        target, numAttachments, attachments);
+
+    Context *context = GetValidGlobalContext();
+    if (context)
+    {
+        context->gatherParams<EntryPoint::DiscardFramebufferEXT>(target, numAttachments,
+                                                                 attachments);
+
+        if (context->skipValidation() ||
+            ValidateDiscardFramebufferEXT(context, target, numAttachments, attachments))
+        {
+            context->discardFramebuffer(target, numAttachments, attachments);
+        }
+    }
+}
+
+// GL_EXT_disjoint_timer_query
+void GL_APIENTRY BeginQueryEXT(GLenum target, GLuint id)
+{
+    EVENT("(GLenum target = 0x%X, GLuint id = %u)", target, id);
+
+    Context *context = GetValidGlobalContext();
+    if (context)
+    {
+        context->gatherParams<EntryPoint::BeginQueryEXT>(target, id);
+
+        if (context->skipValidation() || ValidateBeginQueryEXT(context, target, id))
+        {
+            context->beginQuery(target, id);
+        }
+    }
+}
+
+void GL_APIENTRY DeleteQueriesEXT(GLsizei n, const GLuint *ids)
+{
+    EVENT("(GLsizei n = %d, const GLuint *ids = 0x%0.8p)", n, ids);
+
+    Context *context = GetValidGlobalContext();
+    if (context)
+    {
+        context->gatherParams<EntryPoint::DeleteQueriesEXT>(n, ids);
+
+        if (context->skipValidation() || ValidateDeleteQueriesEXT(context, n, ids))
+        {
+            context->deleteQueries(n, ids);
+        }
+    }
+}
+
+void GL_APIENTRY EndQueryEXT(GLenum target)
+{
+    EVENT("(GLenum target = 0x%X)", target);
+
+    Context *context = GetValidGlobalContext();
+    if (context)
+    {
+        context->gatherParams<EntryPoint::EndQueryEXT>(target);
+
+        if (context->skipValidation() || ValidateEndQueryEXT(context, target))
+        {
+            context->endQuery(target);
+        }
+    }
+}
+
+void GL_APIENTRY GenQueriesEXT(GLsizei n, GLuint *ids)
+{
+    EVENT("(GLsizei n = %d, GLuint *ids = 0x%0.8p)", n, ids);
+
+    Context *context = GetValidGlobalContext();
+    if (context)
+    {
+        context->gatherParams<EntryPoint::GenQueriesEXT>(n, ids);
+
+        if (context->skipValidation() || ValidateGenQueriesEXT(context, n, ids))
+        {
+            context->genQueries(n, ids);
+        }
+    }
+}
+
+void GL_APIENTRY GetQueryObjecti64vEXT(GLuint id, GLenum pname, GLint64 *params)
+{
+    EVENT("(GLuint id = %u, GLenum pname = 0x%X, GLint64 *params = 0x%0.8p)", id, pname, params);
+
+    Context *context = GetValidGlobalContext();
+    if (context)
+    {
+        context->gatherParams<EntryPoint::GetQueryObjecti64vEXT>(id, pname, params);
+
+        if (context->skipValidation() || ValidateGetQueryObjecti64vEXT(context, id, pname, params))
+        {
+            context->getQueryObjecti64v(id, pname, params);
+        }
+    }
+}
+
+void GL_APIENTRY GetQueryObjectivEXT(GLuint id, GLenum pname, GLint *params)
+{
+    EVENT("(GLuint id = %u, GLenum pname = 0x%X, GLint *params = 0x%0.8p)", id, pname, params);
+
+    Context *context = GetValidGlobalContext();
+    if (context)
+    {
+        context->gatherParams<EntryPoint::GetQueryObjectivEXT>(id, pname, params);
+
+        if (context->skipValidation() || ValidateGetQueryObjectivEXT(context, id, pname, params))
+        {
+            context->getQueryObjectiv(id, pname, params);
+        }
+    }
+}
+
+void GL_APIENTRY GetQueryObjectui64vEXT(GLuint id, GLenum pname, GLuint64 *params)
+{
+    EVENT("(GLuint id = %u, GLenum pname = 0x%X, GLuint64 *params = 0x%0.8p)", id, pname, params);
+
+    Context *context = GetValidGlobalContext();
+    if (context)
+    {
+        context->gatherParams<EntryPoint::GetQueryObjectui64vEXT>(id, pname, params);
+
+        if (context->skipValidation() || ValidateGetQueryObjectui64vEXT(context, id, pname, params))
+        {
+            context->getQueryObjectui64v(id, pname, params);
+        }
+    }
+}
+
+void GL_APIENTRY GetQueryObjectuivEXT(GLuint id, GLenum pname, GLuint *params)
+{
+    EVENT("(GLuint id = %u, GLenum pname = 0x%X, GLuint *params = 0x%0.8p)", id, pname, params);
+
+    Context *context = GetValidGlobalContext();
+    if (context)
+    {
+        context->gatherParams<EntryPoint::GetQueryObjectuivEXT>(id, pname, params);
+
+        if (context->skipValidation() || ValidateGetQueryObjectuivEXT(context, id, pname, params))
+        {
+            context->getQueryObjectuiv(id, pname, params);
+        }
+    }
+}
+
+void GL_APIENTRY GetQueryivEXT(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::GetQueryivEXT>(target, pname, params);
+
+        if (context->skipValidation() || ValidateGetQueryivEXT(context, target, pname, params))
+        {
+            context->getQueryiv(target, pname, params);
+        }
+    }
+}
+
+GLboolean GL_APIENTRY IsQueryEXT(GLuint id)
+{
+    EVENT("(GLuint id = %u)", id);
+
+    Context *context = GetValidGlobalContext();
+    if (context)
+    {
+        context->gatherParams<EntryPoint::IsQueryEXT>(id);
+
+        if (context->skipValidation() || ValidateIsQueryEXT(context, id))
+        {
+            return context->isQuery(id);
+        }
+    }
+
+    return GetDefaultReturnValue<EntryPoint::IsQueryEXT, GLboolean>();
+}
+
+void GL_APIENTRY QueryCounterEXT(GLuint id, GLenum target)
+{
+    EVENT("(GLuint id = %u, GLenum target = 0x%X)", id, target);
+
+    Context *context = GetValidGlobalContext();
+    if (context)
+    {
+        context->gatherParams<EntryPoint::QueryCounterEXT>(id, target);
+
+        if (context->skipValidation() || ValidateQueryCounterEXT(context, id, target))
+        {
+            context->queryCounter(id, target);
+        }
+    }
+}
+
+// GL_EXT_draw_buffers
+void GL_APIENTRY DrawBuffersEXT(GLsizei n, const GLenum *bufs)
+{
+    EVENT("(GLsizei n = %d, const GLenum *bufs = 0x%0.8p)", n, bufs);
+
+    Context *context = GetValidGlobalContext();
+    if (context)
+    {
+        context->gatherParams<EntryPoint::DrawBuffersEXT>(n, bufs);
+
+        if (context->skipValidation() || ValidateDrawBuffersEXT(context, n, bufs))
+        {
+            context->drawBuffers(n, bufs);
+        }
+    }
+}
+
+// GL_EXT_map_buffer_range
+void GL_APIENTRY FlushMappedBufferRangeEXT(GLenum target, GLintptr offset, GLsizeiptr length)
+{
+    EVENT("(GLenum target = 0x%X, GLintptr offset = %d, GLsizeiptr length = %d)", target, offset,
+          length);
+
+    Context *context = GetValidGlobalContext();
+    if (context)
+    {
+        BufferBinding targetPacked = FromGLenum<BufferBinding>(target);
+        context->gatherParams<EntryPoint::FlushMappedBufferRangeEXT>(targetPacked, offset, length);
+
+        if (context->skipValidation() ||
+            ValidateFlushMappedBufferRangeEXT(context, targetPacked, offset, length))
+        {
+            context->flushMappedBufferRange(targetPacked, offset, length);
+        }
+    }
+}
+
+void *GL_APIENTRY MapBufferRangeEXT(GLenum target,
+                                    GLintptr offset,
+                                    GLsizeiptr length,
+                                    GLbitfield access)
+{
+    EVENT(
+        "(GLenum target = 0x%X, GLintptr offset = %d, GLsizeiptr length = %d, GLbitfield access = "
+        "0x%X)",
+        target, offset, length, access);
+
+    Context *context = GetValidGlobalContext();
+    if (context)
+    {
+        BufferBinding targetPacked = FromGLenum<BufferBinding>(target);
+        context->gatherParams<EntryPoint::MapBufferRangeEXT>(targetPacked, offset, length, access);
+
+        if (context->skipValidation() ||
+            ValidateMapBufferRangeEXT(context, targetPacked, offset, length, access))
+        {
+            return context->mapBufferRange(targetPacked, offset, length, access);
+        }
+    }
+
+    return GetDefaultReturnValue<EntryPoint::MapBufferRangeEXT, void *>();
+}
+
+// GL_EXT_occlusion_query_boolean
+// BeginQueryEXT is already defined.
+
+// DeleteQueriesEXT is already defined.
+
+// EndQueryEXT is already defined.
+
+// GenQueriesEXT is already defined.
+
+// GetQueryObjectuivEXT is already defined.
+
+// GetQueryivEXT is already defined.
+
+// IsQueryEXT is already defined.
+
+// GL_EXT_robustness
+GLenum GL_APIENTRY GetGraphicsResetStatusEXT()
+{
+    EVENT("()");
+
+    Context *context = GetValidGlobalContext();
+    if (context)
+    {
+        context->gatherParams<EntryPoint::GetGraphicsResetStatusEXT>();
+
+        if (context->skipValidation() || ValidateGetGraphicsResetStatusEXT(context))
+        {
+            return context->getGraphicsResetStatus();
+        }
+    }
+
+    return GetDefaultReturnValue<EntryPoint::GetGraphicsResetStatusEXT, GLenum>();
+}
+
+void GL_APIENTRY GetnUniformfvEXT(GLuint program, GLint location, GLsizei bufSize, GLfloat *params)
+{
+    EVENT(
+        "(GLuint program = %u, GLint location = %d, GLsizei bufSize = %d, GLfloat *params = "
+        "0x%0.8p)",
+        program, location, bufSize, params);
+
+    Context *context = GetValidGlobalContext();
+    if (context)
+    {
+        context->gatherParams<EntryPoint::GetnUniformfvEXT>(program, location, bufSize, params);
+
+        if (context->skipValidation() ||
+            ValidateGetnUniformfvEXT(context, program, location, bufSize, params))
+        {
+            context->getnUniformfv(program, location, bufSize, params);
+        }
+    }
+}
+
+void GL_APIENTRY GetnUniformivEXT(GLuint program, GLint location, GLsizei bufSize, GLint *params)
+{
+    EVENT(
+        "(GLuint program = %u, GLint location = %d, GLsizei bufSize = %d, GLint *params = 0x%0.8p)",
+        program, location, bufSize, params);
+
+    Context *context = GetValidGlobalContext();
+    if (context)
+    {
+        context->gatherParams<EntryPoint::GetnUniformivEXT>(program, location, bufSize, params);
+
+        if (context->skipValidation() ||
+            ValidateGetnUniformivEXT(context, program, location, bufSize, params))
+        {
+            context->getnUniformiv(program, location, bufSize, params);
+        }
+    }
+}
+
+void GL_APIENTRY ReadnPixelsEXT(GLint x,
+                                GLint y,
+                                GLsizei width,
+                                GLsizei height,
+                                GLenum format,
+                                GLenum type,
+                                GLsizei bufSize,
+                                void *data)
+{
+    EVENT(
+        "(GLint x = %d, GLint y = %d, GLsizei width = %d, GLsizei height = %d, GLenum format = "
+        "0x%X, GLenum type = 0x%X, GLsizei bufSize = %d, void *data = 0x%0.8p)",
+        x, y, width, height, format, type, bufSize, data);
+
+    Context *context = GetValidGlobalContext();
+    if (context)
+    {
+        context->gatherParams<EntryPoint::ReadnPixelsEXT>(x, y, width, height, format, type,
+                                                          bufSize, data);
+
+        if (context->skipValidation() ||
+            ValidateReadnPixelsEXT(context, x, y, width, height, format, type, bufSize, data))
+        {
+            context->readnPixels(x, y, width, height, format, type, bufSize, data);
+        }
+    }
+}
+
+// GL_EXT_texture_storage
+void GL_APIENTRY TexStorage1DEXT(GLenum target,
+                                 GLsizei levels,
+                                 GLenum internalformat,
+                                 GLsizei width)
+{
+    EVENT(
+        "(GLenum target = 0x%X, GLsizei levels = %d, GLenum internalformat = 0x%X, GLsizei width = "
+        "%d)",
+        target, levels, internalformat, width);
+
+    Context *context = GetValidGlobalContext();
+    if (context)
+    {
+        context->gatherParams<EntryPoint::TexStorage1DEXT>(target, levels, internalformat, width);
+
+        if (context->skipValidation() ||
+            ValidateTexStorage1DEXT(context, target, levels, internalformat, width))
+        {
+            context->texStorage1D(target, levels, internalformat, width);
+        }
+    }
+}
+
+void GL_APIENTRY
+TexStorage2DEXT(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::TexStorage2DEXT>(target, levels, internalformat, width,
+                                                           height);
+
+        if (context->skipValidation() ||
+            ValidateTexStorage2DEXT(context, target, levels, internalformat, width, height))
+        {
+            context->texStorage2D(target, levels, internalformat, width, height);
+        }
+    }
+}
+
+void GL_APIENTRY TexStorage3DEXT(GLenum target,
+                                 GLsizei levels,
+                                 GLenum internalformat,
+                                 GLsizei width,
+                                 GLsizei height,
+                                 GLsizei depth)
+{
+    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);
+
+        if (context->skipValidation() ||
+            ValidateTexStorage3DEXT(context, target, levels, internalformat, width, height, depth))
+        {
+            context->texStorage3D(target, 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,
+          userParam);
+
+    Context *context = GetValidGlobalContext();
+    if (context)
+    {
+        context->gatherParams<EntryPoint::DebugMessageCallbackKHR>(callback, userParam);
+
+        if (context->skipValidation() ||
+            ValidateDebugMessageCallbackKHR(context, callback, userParam))
+        {
+            context->debugMessageCallback(callback, userParam);
+        }
+    }
+}
+
+void GL_APIENTRY DebugMessageControlKHR(GLenum source,
+                                        GLenum type,
+                                        GLenum severity,
+                                        GLsizei count,
+                                        const GLuint *ids,
+                                        GLboolean enabled)
+{
+    EVENT(
+        "(GLenum source = 0x%X, GLenum type = 0x%X, GLenum severity = 0x%X, GLsizei count = %d, "
+        "const GLuint *ids = 0x%0.8p, GLboolean enabled = %u)",
+        source, type, severity, count, ids, enabled);
+
+    Context *context = GetValidGlobalContext();
+    if (context)
+    {
+        context->gatherParams<EntryPoint::DebugMessageControlKHR>(source, type, severity, count,
+                                                                  ids, enabled);
+
+        if (context->skipValidation() ||
+            ValidateDebugMessageControlKHR(context, source, type, severity, count, ids, enabled))
+        {
+            context->debugMessageControl(source, type, severity, count, ids, enabled);
+        }
+    }
+}
+
+void GL_APIENTRY DebugMessageInsertKHR(GLenum source,
+                                       GLenum type,
+                                       GLuint id,
+                                       GLenum severity,
+                                       GLsizei length,
+                                       const GLchar *buf)
+{
+    EVENT(
+        "(GLenum source = 0x%X, GLenum type = 0x%X, GLuint id = %u, GLenum severity = 0x%X, "
+        "GLsizei length = %d, const GLchar *buf = 0x%0.8p)",
+        source, type, id, severity, length, buf);
+
+    Context *context = GetValidGlobalContext();
+    if (context)
+    {
+        context->gatherParams<EntryPoint::DebugMessageInsertKHR>(source, type, id, severity, length,
+                                                                 buf);
+
+        if (context->skipValidation() ||
+            ValidateDebugMessageInsertKHR(context, source, type, id, severity, length, buf))
+        {
+            context->debugMessageInsert(source, type, id, severity, length, buf);
+        }
+    }
+}
+
+GLuint GL_APIENTRY GetDebugMessageLogKHR(GLuint count,
+                                         GLsizei bufSize,
+                                         GLenum *sources,
+                                         GLenum *types,
+                                         GLuint *ids,
+                                         GLenum *severities,
+                                         GLsizei *lengths,
+                                         GLchar *messageLog)
+{
+    EVENT(
+        "(GLuint count = %u, GLsizei bufSize = %d, GLenum *sources = 0x%0.8p, GLenum *types = "
+        "0x%0.8p, GLuint *ids = 0x%0.8p, GLenum *severities = 0x%0.8p, GLsizei *lengths = 0x%0.8p, "
+        "GLchar *messageLog = 0x%0.8p)",
+        count, bufSize, sources, types, ids, severities, lengths, messageLog);
+
+    Context *context = GetValidGlobalContext();
+    if (context)
+    {
+        context->gatherParams<EntryPoint::GetDebugMessageLogKHR>(
+            count, bufSize, sources, types, ids, severities, lengths, messageLog);
+
+        if (context->skipValidation() ||
+            ValidateGetDebugMessageLogKHR(context, count, bufSize, sources, types, ids, severities,
+                                          lengths, messageLog))
+        {
+            return context->getDebugMessageLog(count, bufSize, sources, types, ids, severities,
+                                               lengths, messageLog);
+        }
+    }
+
+    return GetDefaultReturnValue<EntryPoint::GetDebugMessageLogKHR, GLuint>();
+}
+
+void GL_APIENTRY
+GetObjectLabelKHR(GLenum identifier, GLuint name, GLsizei bufSize, GLsizei *length, GLchar *label)
+{
+    EVENT(
+        "(GLenum identifier = 0x%X, GLuint name = %u, GLsizei bufSize = %d, GLsizei *length = "
+        "0x%0.8p, GLchar *label = 0x%0.8p)",
+        identifier, name, bufSize, length, label);
+
+    Context *context = GetValidGlobalContext();
+    if (context)
+    {
+        context->gatherParams<EntryPoint::GetObjectLabelKHR>(identifier, name, bufSize, length,
+                                                             label);
+
+        if (context->skipValidation() ||
+            ValidateGetObjectLabelKHR(context, identifier, name, bufSize, length, label))
+        {
+            context->getObjectLabel(identifier, name, bufSize, length, label);
+        }
+    }
+}
+
+void GL_APIENTRY GetObjectPtrLabelKHR(const void *ptr,
+                                      GLsizei bufSize,
+                                      GLsizei *length,
+                                      GLchar *label)
+{
+    EVENT(
+        "(const void *ptr = 0x%0.8p, GLsizei bufSize = %d, GLsizei *length = 0x%0.8p, GLchar "
+        "*label = 0x%0.8p)",
+        ptr, bufSize, length, label);
+
+    Context *context = GetValidGlobalContext();
+    if (context)
+    {
+        context->gatherParams<EntryPoint::GetObjectPtrLabelKHR>(ptr, bufSize, length, label);
+
+        if (context->skipValidation() ||
+            ValidateGetObjectPtrLabelKHR(context, ptr, bufSize, length, label))
+        {
+            context->getObjectPtrLabel(ptr, bufSize, length, label);
+        }
+    }
+}
+
+void GL_APIENTRY GetPointervKHR(GLenum pname, void **params)
+{
+    EVENT("(GLenum pname = 0x%X, void **params = 0x%0.8p)", pname, params);
+
+    Context *context = GetValidGlobalContext();
+    if (context)
+    {
+        context->gatherParams<EntryPoint::GetPointervKHR>(pname, params);
+
+        if (context->skipValidation() || ValidateGetPointervKHR(context, pname, params))
+        {
+            context->getPointerv(pname, params);
+        }
+    }
+}
+
+void GL_APIENTRY ObjectLabelKHR(GLenum identifier, GLuint name, GLsizei length, const GLchar *label)
+{
+    EVENT(
+        "(GLenum identifier = 0x%X, GLuint name = %u, GLsizei length = %d, const GLchar *label = "
+        "0x%0.8p)",
+        identifier, name, length, label);
+
+    Context *context = GetValidGlobalContext();
+    if (context)
+    {
+        context->gatherParams<EntryPoint::ObjectLabelKHR>(identifier, name, length, label);
+
+        if (context->skipValidation() ||
+            ValidateObjectLabelKHR(context, identifier, name, length, label))
+        {
+            context->objectLabel(identifier, name, length, label);
+        }
+    }
+}
+
+void GL_APIENTRY ObjectPtrLabelKHR(const void *ptr, GLsizei length, const GLchar *label)
+{
+    EVENT("(const void *ptr = 0x%0.8p, GLsizei length = %d, const GLchar *label = 0x%0.8p)", ptr,
+          length, label);
+
+    Context *context = GetValidGlobalContext();
+    if (context)
+    {
+        context->gatherParams<EntryPoint::ObjectPtrLabelKHR>(ptr, length, label);
+
+        if (context->skipValidation() || ValidateObjectPtrLabelKHR(context, ptr, length, label))
+        {
+            context->objectPtrLabel(ptr, length, label);
+        }
+    }
+}
+
+void GL_APIENTRY PopDebugGroupKHR()
+{
+    EVENT("()");
+
+    Context *context = GetValidGlobalContext();
+    if (context)
+    {
+        context->gatherParams<EntryPoint::PopDebugGroupKHR>();
+
+        if (context->skipValidation() || ValidatePopDebugGroupKHR(context))
+        {
+            context->popDebugGroup();
+        }
+    }
+}
+
+void GL_APIENTRY PushDebugGroupKHR(GLenum source, GLuint id, GLsizei length, const GLchar *message)
+{
+    EVENT(
+        "(GLenum source = 0x%X, GLuint id = %u, GLsizei length = %d, const GLchar *message = "
+        "0x%0.8p)",
+        source, id, length, message);
+
+    Context *context = GetValidGlobalContext();
+    if (context)
+    {
+        context->gatherParams<EntryPoint::PushDebugGroupKHR>(source, id, length, message);
+
+        if (context->skipValidation() ||
+            ValidatePushDebugGroupKHR(context, source, id, length, message))
+        {
+            context->pushDebugGroup(source, id, length, message);
+        }
+    }
+}
+
+// GL_NV_fence
+void GL_APIENTRY DeleteFencesNV(GLsizei n, const GLuint *fences)
+{
+    EVENT("(GLsizei n = %d, const GLuint *fences = 0x%0.8p)", n, fences);
+
+    Context *context = GetValidGlobalContext();
+    if (context)
+    {
+        context->gatherParams<EntryPoint::DeleteFencesNV>(n, fences);
+
+        if (context->skipValidation() || ValidateDeleteFencesNV(context, n, fences))
+        {
+            context->deleteFencesNV(n, fences);
+        }
+    }
+}
+
+void GL_APIENTRY FinishFenceNV(GLuint fence)
+{
+    EVENT("(GLuint fence = %u)", fence);
+
+    Context *context = GetValidGlobalContext();
+    if (context)
+    {
+        context->gatherParams<EntryPoint::FinishFenceNV>(fence);
+
+        if (context->skipValidation() || ValidateFinishFenceNV(context, fence))
+        {
+            context->finishFenceNV(fence);
+        }
+    }
+}
+
+void GL_APIENTRY GenFencesNV(GLsizei n, GLuint *fences)
+{
+    EVENT("(GLsizei n = %d, GLuint *fences = 0x%0.8p)", n, fences);
+
+    Context *context = GetValidGlobalContext();
+    if (context)
+    {
+        context->gatherParams<EntryPoint::GenFencesNV>(n, fences);
+
+        if (context->skipValidation() || ValidateGenFencesNV(context, n, fences))
+        {
+            context->genFencesNV(n, fences);
+        }
+    }
+}
+
+void GL_APIENTRY GetFenceivNV(GLuint fence, GLenum pname, GLint *params)
+{
+    EVENT("(GLuint fence = %u, GLenum pname = 0x%X, GLint *params = 0x%0.8p)", fence, pname,
+          params);
+
+    Context *context = GetValidGlobalContext();
+    if (context)
+    {
+        context->gatherParams<EntryPoint::GetFenceivNV>(fence, pname, params);
+
+        if (context->skipValidation() || ValidateGetFenceivNV(context, fence, pname, params))
+        {
+            context->getFenceivNV(fence, pname, params);
+        }
+    }
+}
+
+GLboolean GL_APIENTRY IsFenceNV(GLuint fence)
+{
+    EVENT("(GLuint fence = %u)", fence);
+
+    Context *context = GetValidGlobalContext();
+    if (context)
+    {
+        context->gatherParams<EntryPoint::IsFenceNV>(fence);
+
+        if (context->skipValidation() || ValidateIsFenceNV(context, fence))
+        {
+            return context->isFenceNV(fence);
+        }
+    }
+
+    return GetDefaultReturnValue<EntryPoint::IsFenceNV, GLboolean>();
+}
+
+void GL_APIENTRY SetFenceNV(GLuint fence, GLenum condition)
+{
+    EVENT("(GLuint fence = %u, GLenum condition = 0x%X)", fence, condition);
+
+    Context *context = GetValidGlobalContext();
+    if (context)
+    {
+        context->gatherParams<EntryPoint::SetFenceNV>(fence, condition);
+
+        if (context->skipValidation() || ValidateSetFenceNV(context, fence, condition))
+        {
+            context->setFenceNV(fence, condition);
+        }
+    }
+}
+
+GLboolean GL_APIENTRY TestFenceNV(GLuint fence)
+{
+    EVENT("(GLuint fence = %u)", fence);
+
+    Context *context = GetValidGlobalContext();
+    if (context)
+    {
+        context->gatherParams<EntryPoint::TestFenceNV>(fence);
+
+        if (context->skipValidation() || ValidateTestFenceNV(context, fence))
+        {
+            return context->testFenceNV(fence);
+        }
+    }
+
+    return GetDefaultReturnValue<EntryPoint::TestFenceNV, GLboolean>();
+}
+
+// GL_OES_EGL_image
+void GL_APIENTRY EGLImageTargetRenderbufferStorageOES(GLenum target, GLeglImageOES image)
+{
+    EVENT("(GLenum target = 0x%X, GLeglImageOES image = 0x%0.8p)", target, image);
+
+    Context *context = GetValidGlobalContext();
+    if (context)
+    {
+        context->gatherParams<EntryPoint::EGLImageTargetRenderbufferStorageOES>(target, image);
+
+        if (context->skipValidation() ||
+            ValidateEGLImageTargetRenderbufferStorageOES(context, target, image))
+        {
+            context->eGLImageTargetRenderbufferStorage(target, image);
+        }
+    }
+}
+
+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);
+
+        if (context->skipValidation() || ValidateEGLImageTargetTexture2DOES(context, target, image))
+        {
+            context->eGLImageTargetTexture2D(target, image);
+        }
+    }
+}
+
+// GL_OES_get_program_binary
+void GL_APIENTRY GetProgramBinaryOES(GLuint program,
+                                     GLsizei bufSize,
+                                     GLsizei *length,
+                                     GLenum *binaryFormat,
+                                     void *binary)
+{
+    EVENT(
+        "(GLuint program = %u, GLsizei bufSize = %d, GLsizei *length = 0x%0.8p, GLenum "
+        "*binaryFormat = 0x%0.8p, void *binary = 0x%0.8p)",
+        program, bufSize, length, binaryFormat, binary);
+
+    Context *context = GetValidGlobalContext();
+    if (context)
+    {
+        context->gatherParams<EntryPoint::GetProgramBinaryOES>(program, bufSize, length,
+                                                               binaryFormat, binary);
+
+        if (context->skipValidation() ||
+            ValidateGetProgramBinaryOES(context, program, bufSize, length, binaryFormat, binary))
+        {
+            context->getProgramBinary(program, bufSize, length, binaryFormat, binary);
+        }
+    }
+}
+
+void GL_APIENTRY ProgramBinaryOES(GLuint program,
+                                  GLenum binaryFormat,
+                                  const void *binary,
+                                  GLint length)
+{
+    EVENT(
+        "(GLuint program = %u, GLenum binaryFormat = 0x%X, const void *binary = 0x%0.8p, GLint "
+        "length = %d)",
+        program, binaryFormat, binary, length);
+
+    Context *context = GetValidGlobalContext();
+    if (context)
+    {
+        context->gatherParams<EntryPoint::ProgramBinaryOES>(program, binaryFormat, binary, length);
+
+        if (context->skipValidation() ||
+            ValidateProgramBinaryOES(context, program, binaryFormat, binary, length))
+        {
+            context->programBinary(program, binaryFormat, binary, length);
+        }
+    }
+}
+
+// GL_OES_mapbuffer
+void GL_APIENTRY GetBufferPointervOES(GLenum target, GLenum pname, void **params)
+{
+    EVENT("(GLenum target = 0x%X, GLenum pname = 0x%X, void **params = 0x%0.8p)", target, pname,
+          params);
+
+    Context *context = GetValidGlobalContext();
+    if (context)
+    {
+        BufferBinding targetPacked = FromGLenum<BufferBinding>(target);
+        context->gatherParams<EntryPoint::GetBufferPointervOES>(targetPacked, pname, params);
+
+        if (context->skipValidation() ||
+            ValidateGetBufferPointervOES(context, targetPacked, pname, params))
+        {
+            context->getBufferPointerv(targetPacked, pname, params);
+        }
+    }
+}
+
+void *GL_APIENTRY MapBufferOES(GLenum target, GLenum access)
+{
+    EVENT("(GLenum target = 0x%X, GLenum access = 0x%X)", target, access);
+
+    Context *context = GetValidGlobalContext();
+    if (context)
+    {
+        BufferBinding targetPacked = FromGLenum<BufferBinding>(target);
+        context->gatherParams<EntryPoint::MapBufferOES>(targetPacked, access);
+
+        if (context->skipValidation() || ValidateMapBufferOES(context, targetPacked, access))
+        {
+            return context->mapBuffer(targetPacked, access);
+        }
+    }
+
+    return GetDefaultReturnValue<EntryPoint::MapBufferOES, void *>();
+}
+
+GLboolean GL_APIENTRY UnmapBufferOES(GLenum target)
+{
+    EVENT("(GLenum target = 0x%X)", target);
+
+    Context *context = GetValidGlobalContext();
+    if (context)
+    {
+        BufferBinding targetPacked = FromGLenum<BufferBinding>(target);
+        context->gatherParams<EntryPoint::UnmapBufferOES>(targetPacked);
+
+        if (context->skipValidation() || ValidateUnmapBufferOES(context, targetPacked))
+        {
+            return context->unmapBuffer(targetPacked);
+        }
+    }
+
+    return GetDefaultReturnValue<EntryPoint::UnmapBufferOES, GLboolean>();
+}
+
+// GL_OES_vertex_array_object
+void GL_APIENTRY BindVertexArrayOES(GLuint array)
+{
+    EVENT("(GLuint array = %u)", array);
+
+    Context *context = GetValidGlobalContext();
+    if (context)
+    {
+        context->gatherParams<EntryPoint::BindVertexArrayOES>(array);
+
+        if (context->skipValidation() || ValidateBindVertexArrayOES(context, array))
+        {
+            context->bindVertexArray(array);
+        }
+    }
+}
+
+void GL_APIENTRY DeleteVertexArraysOES(GLsizei n, const GLuint *arrays)
+{
+    EVENT("(GLsizei n = %d, const GLuint *arrays = 0x%0.8p)", n, arrays);
+
+    Context *context = GetValidGlobalContext();
+    if (context)
+    {
+        context->gatherParams<EntryPoint::DeleteVertexArraysOES>(n, arrays);
+
+        if (context->skipValidation() || ValidateDeleteVertexArraysOES(context, n, arrays))
+        {
+            context->deleteVertexArrays(n, arrays);
+        }
+    }
+}
+
+void GL_APIENTRY GenVertexArraysOES(GLsizei n, GLuint *arrays)
+{
+    EVENT("(GLsizei n = %d, GLuint *arrays = 0x%0.8p)", n, arrays);
+
+    Context *context = GetValidGlobalContext();
+    if (context)
+    {
+        context->gatherParams<EntryPoint::GenVertexArraysOES>(n, arrays);
+
+        if (context->skipValidation() || ValidateGenVertexArraysOES(context, n, arrays))
+        {
+            context->genVertexArrays(n, arrays);
+        }
+    }
+}
+
+GLboolean GL_APIENTRY IsVertexArrayOES(GLuint array)
+{
+    EVENT("(GLuint array = %u)", array);
+
+    Context *context = GetValidGlobalContext();
+    if (context)
+    {
+        context->gatherParams<EntryPoint::IsVertexArrayOES>(array);
+
+        if (context->skipValidation() || ValidateIsVertexArrayOES(context, array))
+        {
+            return context->isVertexArray(array);
+        }
+    }
+
+    return GetDefaultReturnValue<EntryPoint::IsVertexArrayOES, GLboolean>();
+}
+}  // namespace gl
new file mode 100644
--- /dev/null
+++ b/gfx/angle/src/libGLESv2/entry_points_gles_2_0_ext_autogen.h
@@ -0,0 +1,210 @@
+// 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.
+//
+// entry_points_gles_2_0_ext_autogen.h:
+//   Defines the GLES extension entry points.
+
+#ifndef LIBGLESV2_ENTRY_POINTS_GLES_2_0_EXT_AUTOGEN_H_
+#define LIBGLESV2_ENTRY_POINTS_GLES_2_0_EXT_AUTOGEN_H_
+
+#include <GLES2/gl2.h>
+#include <export.h>
+
+namespace gl
+{
+
+// GL_ANGLE_framebuffer_blit
+ANGLE_EXPORT void GL_APIENTRY BlitFramebufferANGLE(GLint srcX0,
+                                                   GLint srcY0,
+                                                   GLint srcX1,
+                                                   GLint srcY1,
+                                                   GLint dstX0,
+                                                   GLint dstY0,
+                                                   GLint dstX1,
+                                                   GLint dstY1,
+                                                   GLbitfield mask,
+                                                   GLenum filter);
+
+// GL_ANGLE_framebuffer_multisample
+ANGLE_EXPORT void GL_APIENTRY RenderbufferStorageMultisampleANGLE(GLenum target,
+                                                                  GLsizei samples,
+                                                                  GLenum internalformat,
+                                                                  GLsizei width,
+                                                                  GLsizei height);
+
+// GL_ANGLE_instanced_arrays
+ANGLE_EXPORT void GL_APIENTRY DrawArraysInstancedANGLE(GLenum mode,
+                                                       GLint first,
+                                                       GLsizei count,
+                                                       GLsizei primcount);
+ANGLE_EXPORT void GL_APIENTRY DrawElementsInstancedANGLE(GLenum mode,
+                                                         GLsizei count,
+                                                         GLenum type,
+                                                         const void *indices,
+                                                         GLsizei primcount);
+ANGLE_EXPORT void GL_APIENTRY VertexAttribDivisorANGLE(GLuint index, GLuint divisor);
+
+// GL_ANGLE_translated_shader_source
+ANGLE_EXPORT void GL_APIENTRY GetTranslatedShaderSourceANGLE(GLuint shader,
+                                                             GLsizei bufsize,
+                                                             GLsizei *length,
+                                                             GLchar *source);
+
+// GL_EXT_debug_marker
+ANGLE_EXPORT void GL_APIENTRY InsertEventMarkerEXT(GLsizei length, const GLchar *marker);
+ANGLE_EXPORT void GL_APIENTRY PopGroupMarkerEXT();
+ANGLE_EXPORT void GL_APIENTRY PushGroupMarkerEXT(GLsizei length, const GLchar *marker);
+
+// GL_EXT_discard_framebuffer
+ANGLE_EXPORT void GL_APIENTRY DiscardFramebufferEXT(GLenum target,
+                                                    GLsizei numAttachments,
+                                                    const GLenum *attachments);
+
+// GL_EXT_disjoint_timer_query
+ANGLE_EXPORT void GL_APIENTRY BeginQueryEXT(GLenum target, GLuint id);
+ANGLE_EXPORT void GL_APIENTRY DeleteQueriesEXT(GLsizei n, const GLuint *ids);
+ANGLE_EXPORT void GL_APIENTRY EndQueryEXT(GLenum target);
+ANGLE_EXPORT void GL_APIENTRY GenQueriesEXT(GLsizei n, GLuint *ids);
+ANGLE_EXPORT void GL_APIENTRY GetQueryObjecti64vEXT(GLuint id, GLenum pname, GLint64 *params);
+ANGLE_EXPORT void GL_APIENTRY GetQueryObjectivEXT(GLuint id, GLenum pname, GLint *params);
+ANGLE_EXPORT void GL_APIENTRY GetQueryObjectui64vEXT(GLuint id, GLenum pname, GLuint64 *params);
+ANGLE_EXPORT void GL_APIENTRY GetQueryObjectuivEXT(GLuint id, GLenum pname, GLuint *params);
+ANGLE_EXPORT void GL_APIENTRY GetQueryivEXT(GLenum target, GLenum pname, GLint *params);
+ANGLE_EXPORT GLboolean GL_APIENTRY IsQueryEXT(GLuint id);
+ANGLE_EXPORT void GL_APIENTRY QueryCounterEXT(GLuint id, GLenum target);
+
+// GL_EXT_draw_buffers
+ANGLE_EXPORT void GL_APIENTRY DrawBuffersEXT(GLsizei n, const GLenum *bufs);
+
+// GL_EXT_map_buffer_range
+ANGLE_EXPORT void GL_APIENTRY FlushMappedBufferRangeEXT(GLenum target,
+                                                        GLintptr offset,
+                                                        GLsizeiptr length);
+ANGLE_EXPORT void *GL_APIENTRY MapBufferRangeEXT(GLenum target,
+                                                 GLintptr offset,
+                                                 GLsizeiptr length,
+                                                 GLbitfield access);
+
+// GL_EXT_occlusion_query_boolean
+
+// GL_EXT_robustness
+ANGLE_EXPORT GLenum GL_APIENTRY GetGraphicsResetStatusEXT();
+ANGLE_EXPORT void GL_APIENTRY GetnUniformfvEXT(GLuint program,
+                                               GLint location,
+                                               GLsizei bufSize,
+                                               GLfloat *params);
+ANGLE_EXPORT void GL_APIENTRY GetnUniformivEXT(GLuint program,
+                                               GLint location,
+                                               GLsizei bufSize,
+                                               GLint *params);
+ANGLE_EXPORT void GL_APIENTRY ReadnPixelsEXT(GLint x,
+                                             GLint y,
+                                             GLsizei width,
+                                             GLsizei height,
+                                             GLenum format,
+                                             GLenum type,
+                                             GLsizei bufSize,
+                                             void *data);
+
+// GL_EXT_texture_storage
+ANGLE_EXPORT void GL_APIENTRY TexStorage1DEXT(GLenum target,
+                                              GLsizei levels,
+                                              GLenum internalformat,
+                                              GLsizei width);
+ANGLE_EXPORT void GL_APIENTRY TexStorage2DEXT(GLenum target,
+                                              GLsizei levels,
+                                              GLenum internalformat,
+                                              GLsizei width,
+                                              GLsizei height);
+ANGLE_EXPORT void GL_APIENTRY TexStorage3DEXT(GLenum target,
+                                              GLsizei levels,
+                                              GLenum internalformat,
+                                              GLsizei width,
+                                              GLsizei height,
+                                              GLsizei depth);
+
+// GL_KHR_debug
+ANGLE_EXPORT void GL_APIENTRY DebugMessageCallbackKHR(GLDEBUGPROCKHR callback,
+                                                      const void *userParam);
+ANGLE_EXPORT void GL_APIENTRY DebugMessageControlKHR(GLenum source,
+                                                     GLenum type,
+                                                     GLenum severity,
+                                                     GLsizei count,
+                                                     const GLuint *ids,
+                                                     GLboolean enabled);
+ANGLE_EXPORT void GL_APIENTRY DebugMessageInsertKHR(GLenum source,
+                                                    GLenum type,
+                                                    GLuint id,
+                                                    GLenum severity,
+                                                    GLsizei length,
+                                                    const GLchar *buf);
+ANGLE_EXPORT GLuint GL_APIENTRY GetDebugMessageLogKHR(GLuint count,
+                                                      GLsizei bufSize,
+                                                      GLenum *sources,
+                                                      GLenum *types,
+                                                      GLuint *ids,
+                                                      GLenum *severities,
+                                                      GLsizei *lengths,
+                                                      GLchar *messageLog);
+ANGLE_EXPORT void GL_APIENTRY
+GetObjectLabelKHR(GLenum identifier, GLuint name, GLsizei bufSize, GLsizei *length, GLchar *label);
+ANGLE_EXPORT void GL_APIENTRY GetObjectPtrLabelKHR(const void *ptr,
+                                                   GLsizei bufSize,
+                                                   GLsizei *length,
+                                                   GLchar *label);
+ANGLE_EXPORT void GL_APIENTRY GetPointervKHR(GLenum pname, void **params);
+ANGLE_EXPORT void GL_APIENTRY ObjectLabelKHR(GLenum identifier,
+                                             GLuint name,
+                                             GLsizei length,
+                                             const GLchar *label);
+ANGLE_EXPORT void GL_APIENTRY ObjectPtrLabelKHR(const void *ptr,
+                                                GLsizei length,
+                                                const GLchar *label);
+ANGLE_EXPORT void GL_APIENTRY PopDebugGroupKHR();
+ANGLE_EXPORT void GL_APIENTRY PushDebugGroupKHR(GLenum source,
+                                                GLuint id,
+                                                GLsizei length,
+                                                const GLchar *message);
+
+// GL_NV_fence
+ANGLE_EXPORT void GL_APIENTRY DeleteFencesNV(GLsizei n, const GLuint *fences);
+ANGLE_EXPORT void GL_APIENTRY FinishFenceNV(GLuint fence);
+ANGLE_EXPORT void GL_APIENTRY GenFencesNV(GLsizei n, GLuint *fences);
+ANGLE_EXPORT void GL_APIENTRY GetFenceivNV(GLuint fence, GLenum pname, GLint *params);
+ANGLE_EXPORT GLboolean GL_APIENTRY IsFenceNV(GLuint fence);
+ANGLE_EXPORT void GL_APIENTRY SetFenceNV(GLuint fence, GLenum condition);
+ANGLE_EXPORT GLboolean GL_APIENTRY TestFenceNV(GLuint fence);
+
+// GL_OES_EGL_image
+ANGLE_EXPORT void GL_APIENTRY EGLImageTargetRenderbufferStorageOES(GLenum target,
+                                                                   GLeglImageOES image);
+ANGLE_EXPORT void GL_APIENTRY EGLImageTargetTexture2DOES(GLenum target, GLeglImageOES image);
+
+// 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,
+                                               const void *binary,
+                                               GLint length);
+
+// GL_OES_mapbuffer
+ANGLE_EXPORT void GL_APIENTRY GetBufferPointervOES(GLenum target, GLenum pname, void **params);
+ANGLE_EXPORT void *GL_APIENTRY MapBufferOES(GLenum target, GLenum access);
+ANGLE_EXPORT GLboolean GL_APIENTRY UnmapBufferOES(GLenum target);
+
+// 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_2_0_EXT_AUTOGEN_H_
--- a/gfx/angle/src/libGLESv2/entry_points_gles_3_0_autogen.cpp
+++ b/gfx/angle/src/libGLESv2/entry_points_gles_3_0_autogen.cpp
@@ -1,164 +1,266 @@
 // GENERATED FILE - DO NOT EDIT.
 // Generated by generate_entry_points.py using data from gl.xml.
 //
-// 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.
 //
 // entry_points_gles_3_0_autogen.cpp:
 //   Defines the GLES 3.0 entry points.
 
 #include "libANGLE/Context.h"
 #include "libANGLE/validationES3.h"
 #include "libGLESv2/global_state.h"
 
 namespace gl
 {
-void GL_APIENTRY ReadBuffer(GLenum src)
+void GL_APIENTRY BeginQuery(GLenum target, GLuint id)
 {
-    EVENT("(GLenum src = 0x%X)", src);
+    EVENT("(GLenum target = 0x%X, GLuint id = %u)", target, id);
+
+    Context *context = GetValidGlobalContext();
+    if (context)
+    {
+        context->gatherParams<EntryPoint::BeginQuery>(target, id);
+
+        if (context->skipValidation() || ValidateBeginQuery(context, target, id))
+        {
+            context->beginQuery(target, id);
+        }
+    }
+}
+
+void GL_APIENTRY BeginTransformFeedback(GLenum primitiveMode)
+{
+    EVENT("(GLenum primitiveMode = 0x%X)", primitiveMode);
 
     Context *context = GetValidGlobalContext();
     if (context)
     {
-        context->gatherParams<EntryPoint::ReadBuffer>(src);
+        context->gatherParams<EntryPoint::BeginTransformFeedback>(primitiveMode);
+
+        if (context->skipValidation() || ValidateBeginTransformFeedback(context, primitiveMode))
+        {
+            context->beginTransformFeedback(primitiveMode);
+        }
+    }
+}
 
-        if (context->skipValidation() || ValidateReadBuffer(context, src))
+void GL_APIENTRY BindBufferBase(GLenum target, GLuint index, GLuint buffer)
+{
+    EVENT("(GLenum target = 0x%X, GLuint index = %u, GLuint buffer = %u)", target, index, buffer);
+
+    Context *context = GetValidGlobalContext();
+    if (context)
+    {
+        BufferBinding targetPacked = FromGLenum<BufferBinding>(target);
+        context->gatherParams<EntryPoint::BindBufferBase>(targetPacked, index, buffer);
+
+        if (context->skipValidation() ||
+            ValidateBindBufferBase(context, targetPacked, index, buffer))
         {
-            context->readBuffer(src);
+            context->bindBufferBase(targetPacked, index, buffer);
         }
     }
 }
 
-void GL_APIENTRY DrawRangeElements(GLenum mode,
-                                   GLuint start,
-                                   GLuint end,
-                                   GLsizei count,
-                                   GLenum type,
-                                   const void *indices)
+void GL_APIENTRY
+BindBufferRange(GLenum target, GLuint index, GLuint buffer, GLintptr offset, GLsizeiptr size)
 {
     EVENT(
-        "(GLenum mode = 0x%X, GLuint start = %u, GLuint end = %u, GLsizei count = %d, GLenum type "
-        "= 0x%X, const void *indices = 0x%0.8p)",
-        mode, start, end, count, type, indices);
+        "(GLenum target = 0x%X, GLuint index = %u, GLuint buffer = %u, GLintptr offset = %d, "
+        "GLsizeiptr size = %d)",
+        target, index, buffer, offset, size);
 
     Context *context = GetValidGlobalContext();
     if (context)
     {
-        context->gatherParams<EntryPoint::DrawRangeElements>(mode, start, end, count, type,
-                                                             indices);
+        BufferBinding targetPacked = FromGLenum<BufferBinding>(target);
+        context->gatherParams<EntryPoint::BindBufferRange>(targetPacked, index, buffer, offset,
+                                                           size);
 
         if (context->skipValidation() ||
-            ValidateDrawRangeElements(context, mode, start, end, count, type, indices))
+            ValidateBindBufferRange(context, targetPacked, index, buffer, offset, size))
         {
-            context->drawRangeElements(mode, start, end, count, type, indices);
+            context->bindBufferRange(targetPacked, index, buffer, offset, size);
         }
     }
 }
 
-void GL_APIENTRY TexImage3D(GLenum target,
-                            GLint level,
-                            GLint internalformat,
-                            GLsizei width,
-                            GLsizei height,
-                            GLsizei depth,
-                            GLint border,
-                            GLenum format,
-                            GLenum type,
-                            const void *pixels)
+void GL_APIENTRY BindSampler(GLuint unit, GLuint sampler)
+{
+    EVENT("(GLuint unit = %u, GLuint sampler = %u)", unit, sampler);
+
+    Context *context = GetValidGlobalContext();
+    if (context)
+    {
+        context->gatherParams<EntryPoint::BindSampler>(unit, sampler);
+
+        if (context->skipValidation() || ValidateBindSampler(context, unit, sampler))
+        {
+            context->bindSampler(unit, sampler);
+        }
+    }
+}
+
+void GL_APIENTRY BindTransformFeedback(GLenum target, GLuint id)
 {
-    EVENT(
-        "(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);
+    EVENT("(GLenum target = 0x%X, GLuint id = %u)", target, id);
+
+    Context *context = GetValidGlobalContext();
+    if (context)
+    {
+        context->gatherParams<EntryPoint::BindTransformFeedback>(target, id);
+
+        if (context->skipValidation() || ValidateBindTransformFeedback(context, target, id))
+        {
+            context->bindTransformFeedback(target, id);
+        }
+    }
+}
+
+void GL_APIENTRY BindVertexArray(GLuint array)
+{
+    EVENT("(GLuint array = %u)", array);
 
     Context *context = GetValidGlobalContext();
     if (context)
     {
-        context->gatherParams<EntryPoint::TexImage3D>(target, level, internalformat, width, height,
-                                                      depth, border, format, type, pixels);
+        context->gatherParams<EntryPoint::BindVertexArray>(array);
 
-        if (context->skipValidation() ||
-            ValidateTexImage3D(context, target, level, internalformat, width, height, depth, border,
-                               format, type, pixels))
+        if (context->skipValidation() || ValidateBindVertexArray(context, array))
         {
-            context->texImage3D(target, level, internalformat, width, height, depth, border, format,
-                                type, pixels);
+            context->bindVertexArray(array);
         }
     }
 }
 
-void GL_APIENTRY TexSubImage3D(GLenum target,
-                               GLint level,
-                               GLint xoffset,
-                               GLint yoffset,
-                               GLint zoffset,
-                               GLsizei width,
-                               GLsizei height,
-                               GLsizei depth,
-                               GLenum format,
-                               GLenum type,
-                               const void *pixels)
+void GL_APIENTRY BlitFramebuffer(GLint srcX0,
+                                 GLint srcY0,
+                                 GLint srcX1,
+                                 GLint srcY1,
+                                 GLint dstX0,
+                                 GLint dstY0,
+                                 GLint dstX1,
+                                 GLint dstY1,
+                                 GLbitfield mask,
+                                 GLenum filter)
 {
     EVENT(
-        "(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);
+        "(GLint srcX0 = %d, GLint srcY0 = %d, GLint srcX1 = %d, GLint srcY1 = %d, GLint dstX0 = "
+        "%d, GLint dstY0 = %d, GLint dstX1 = %d, GLint dstY1 = %d, GLbitfield mask = 0x%X, GLenum "
+        "filter = 0x%X)",
+        srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, mask, filter);
+
+    Context *context = GetValidGlobalContext();
+    if (context)
+    {
+        context->gatherParams<EntryPoint::BlitFramebuffer>(srcX0, srcY0, srcX1, srcY1, dstX0, dstY0,
+                                                           dstX1, dstY1, mask, filter);
+
+        if (context->skipValidation() ||
+            ValidateBlitFramebuffer(context, srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1,
+                                    mask, filter))
+        {
+            context->blitFramebuffer(srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, mask,
+                                     filter);
+        }
+    }
+}
+
+void GL_APIENTRY ClearBufferfi(GLenum buffer, GLint drawbuffer, GLfloat depth, GLint stencil)
+{
+    EVENT("(GLenum buffer = 0x%X, GLint drawbuffer = %d, GLfloat depth = %f, GLint stencil = %d)",
+          buffer, drawbuffer, depth, stencil);
 
     Context *context = GetValidGlobalContext();
     if (context)
     {
-        context->gatherParams<EntryPoint::TexSubImage3D>(
-            target, level, xoffset, yoffset, zoffset, width, height, depth, format, type, pixels);
+        context->gatherParams<EntryPoint::ClearBufferfi>(buffer, drawbuffer, depth, stencil);
 
         if (context->skipValidation() ||
-            ValidateTexSubImage3D(context, target, level, xoffset, yoffset, zoffset, width, height,
-                                  depth, format, type, pixels))
+            ValidateClearBufferfi(context, buffer, drawbuffer, depth, stencil))
         {
-            context->texSubImage3D(target, level, xoffset, yoffset, zoffset, width, height, depth,
-                                   format, type, pixels);
+            context->clearBufferfi(buffer, drawbuffer, depth, stencil);
+        }
+    }
+}
+
+void GL_APIENTRY ClearBufferfv(GLenum buffer, GLint drawbuffer, const GLfloat *value)
+{
+    EVENT("(GLenum buffer = 0x%X, GLint drawbuffer = %d, const GLfloat *value = 0x%0.8p)", buffer,
+          drawbuffer, value);
+
+    Context *context = GetValidGlobalContext();
+    if (context)
+    {
+        context->gatherParams<EntryPoint::ClearBufferfv>(buffer, drawbuffer, value);
+
+        if (context->skipValidation() || ValidateClearBufferfv(context, buffer, drawbuffer, value))
+        {
+            context->clearBufferfv(buffer, drawbuffer, value);
         }
     }
 }
 
-void GL_APIENTRY CopyTexSubImage3D(GLenum target,
-                                   GLint level,
-                                   GLint xoffset,
-                                   GLint yoffset,
-                                   GLint zoffset,
-                                   GLint x,
-                                   GLint y,
-                                   GLsizei width,
-                                   GLsizei height)
+void GL_APIENTRY ClearBufferiv(GLenum buffer, GLint drawbuffer, const GLint *value)
 {
-    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);
+    EVENT("(GLenum buffer = 0x%X, GLint drawbuffer = %d, const GLint *value = 0x%0.8p)", buffer,
+          drawbuffer, value);
+
+    Context *context = GetValidGlobalContext();
+    if (context)
+    {
+        context->gatherParams<EntryPoint::ClearBufferiv>(buffer, drawbuffer, value);
+
+        if (context->skipValidation() || ValidateClearBufferiv(context, buffer, drawbuffer, value))
+        {
+            context->clearBufferiv(buffer, drawbuffer, value);
+        }
+    }
+}
+
+void GL_APIENTRY ClearBufferuiv(GLenum buffer, GLint drawbuffer, const GLuint *value)
+{
+    EVENT("(GLenum buffer = 0x%X, GLint drawbuffer = %d, const GLuint *value = 0x%0.8p)", buffer,
+          drawbuffer, value);
 
     Context *context = GetValidGlobalContext();
     if (context)
     {
-        context->gatherParams<EntryPoint::CopyTexSubImage3D>(target, level, xoffset, yoffset,
-                                                             zoffset, x, y, width, height);
+        context->gatherParams<EntryPoint::ClearBufferuiv>(buffer, drawbuffer, value);
 
-        if (context->skipValidation() ||
-            ValidateCopyTexSubImage3D(context, target, level, xoffset, yoffset, zoffset, x, y,
-                                      width, height))
+        if (context->skipValidation() || ValidateClearBufferuiv(context, buffer, drawbuffer, value))
         {
-            context->copyTexSubImage3D(target, level, xoffset, yoffset, zoffset, x, y, width,
-                                       height);
+            context->clearBufferuiv(buffer, drawbuffer, value);
         }
     }
 }
 
+GLenum GL_APIENTRY ClientWaitSync(GLsync sync, GLbitfield flags, GLuint64 timeout)
+{
+    EVENT("(GLsync sync = 0x%0.8p, GLbitfield flags = 0x%X, GLuint64 timeout = %llu)", sync, flags,
+          timeout);
+
+    Context *context = GetValidGlobalContext();
+    if (context)
+    {
+        context->gatherParams<EntryPoint::ClientWaitSync>(sync, flags, timeout);
+
+        if (context->skipValidation() || ValidateClientWaitSync(context, sync, flags, timeout))
+        {
+            return context->clientWaitSync(sync, flags, timeout);
+        }
+    }
+
+    return GetDefaultReturnValue<EntryPoint::ClientWaitSync, GLenum>();
+}
+
 void GL_APIENTRY CompressedTexImage3D(GLenum target,
                                       GLint level,
                                       GLenum internalformat,
                                       GLsizei width,
                                       GLsizei height,
                                       GLsizei depth,
                                       GLint border,
                                       GLsizei imageSize,
@@ -216,28 +318,72 @@ void GL_APIENTRY CompressedTexSubImage3D
                                             width, height, depth, format, imageSize, data))
         {
             context->compressedTexSubImage3D(target, level, xoffset, yoffset, zoffset, width,
                                              height, depth, format, imageSize, data);
         }
     }
 }
 
-void GL_APIENTRY GenQueries(GLsizei n, GLuint *ids)
+void GL_APIENTRY CopyBufferSubData(GLenum readTarget,
+                                   GLenum writeTarget,
+                                   GLintptr readOffset,
+                                   GLintptr writeOffset,
+                                   GLsizeiptr size)
 {
-    EVENT("(GLsizei n = %d, GLuint *ids = 0x%0.8p)", n, ids);
+    EVENT(
+        "(GLenum readTarget = 0x%X, GLenum writeTarget = 0x%X, GLintptr readOffset = %d, GLintptr "
+        "writeOffset = %d, GLsizeiptr size = %d)",
+        readTarget, writeTarget, readOffset, writeOffset, size);
 
     Context *context = GetValidGlobalContext();
     if (context)
     {
-        context->gatherParams<EntryPoint::GenQueries>(n, ids);
+        BufferBinding readTargetPacked  = FromGLenum<BufferBinding>(readTarget);
+        BufferBinding writeTargetPacked = FromGLenum<BufferBinding>(writeTarget);
+        context->gatherParams<EntryPoint::CopyBufferSubData>(readTargetPacked, writeTargetPacked,
+                                                             readOffset, writeOffset, size);
+
+        if (context->skipValidation() ||
+            ValidateCopyBufferSubData(context, readTargetPacked, writeTargetPacked, readOffset,
+                                      writeOffset, size))
+        {
+            context->copyBufferSubData(readTargetPacked, writeTargetPacked, readOffset, writeOffset,
+                                       size);
+        }
+    }
+}
 
-        if (context->skipValidation() || ValidateGenQueries(context, n, ids))
+void GL_APIENTRY CopyTexSubImage3D(GLenum target,
+                                   GLint level,
+                                   GLint xoffset,
+                                   GLint yoffset,
+                                   GLint zoffset,
+                                   GLint x,
+                                   GLint y,
+                                   GLsizei width,
+                                   GLsizei height)
+{
+    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,
+                                                             zoffset, x, y, width, height);
+
+        if (context->skipValidation() ||
+            ValidateCopyTexSubImage3D(context, target, level, xoffset, yoffset, zoffset, x, y,
+                                      width, height))
         {
-            context->genQueries(n, ids);
+            context->copyTexSubImage3D(target, 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);
 
@@ -248,130 +394,94 @@ void GL_APIENTRY DeleteQueries(GLsizei n
 
         if (context->skipValidation() || ValidateDeleteQueries(context, n, ids))
         {
             context->deleteQueries(n, ids);
         }
     }
 }
 
-GLboolean GL_APIENTRY IsQuery(GLuint id)
+void GL_APIENTRY DeleteSamplers(GLsizei count, const GLuint *samplers)
 {
-    EVENT("(GLuint id = %u)", id);
+    EVENT("(GLsizei count = %d, const GLuint *samplers = 0x%0.8p)", count, samplers);
 
     Context *context = GetValidGlobalContext();
     if (context)
     {
-        context->gatherParams<EntryPoint::IsQuery>(id);
+        context->gatherParams<EntryPoint::DeleteSamplers>(count, samplers);
 
-        if (context->skipValidation() || ValidateIsQuery(context, id))
+        if (context->skipValidation() || ValidateDeleteSamplers(context, count, samplers))
         {
-            return context->isQuery(id);
+            context->deleteSamplers(count, samplers);
         }
     }
-
-    return GetDefaultReturnValue<EntryPoint::IsQuery, GLboolean>();
 }
 
-void GL_APIENTRY BeginQuery(GLenum target, GLuint id)
+void GL_APIENTRY DeleteSync(GLsync sync)
 {
-    EVENT("(GLenum target = 0x%X, GLuint id = %u)", target, id);
+    EVENT("(GLsync sync = 0x%0.8p)", sync);
 
     Context *context = GetValidGlobalContext();
     if (context)
     {
-        context->gatherParams<EntryPoint::BeginQuery>(target, id);
-
-        if (context->skipValidation() || ValidateBeginQuery(context, target, id))
-        {
-            context->beginQuery(target, id);
-        }
-    }
-}
+        context->gatherParams<EntryPoint::DeleteSync>(sync);
 
-void GL_APIENTRY EndQuery(GLenum target)
-{
-    EVENT("(GLenum target = 0x%X)", target);
-
-    Context *context = GetValidGlobalContext();
-    if (context)
-    {
-        context->gatherParams<EntryPoint::EndQuery>(target);
-
-        if (context->skipValidation() || ValidateEndQuery(context, target))
+        if (context->skipValidation() || ValidateDeleteSync(context, sync))
         {
-            context->endQuery(target);
+            context->deleteSync(sync);
         }
     }
 }
 
-void GL_APIENTRY GetQueryiv(GLenum target, GLenum pname, GLint *params)
+void GL_APIENTRY DeleteTransformFeedbacks(GLsizei n, const GLuint *ids)
 {
-    EVENT("(GLenum target = 0x%X, GLenum pname = 0x%X, GLint *params = 0x%0.8p)", target, pname,
-          params);
+    EVENT("(GLsizei n = %d, const GLuint *ids = 0x%0.8p)", n, ids);
 
     Context *context = GetValidGlobalContext();
     if (context)
     {
-        context->gatherParams<EntryPoint::GetQueryiv>(target, pname, params);
+        context->gatherParams<EntryPoint::DeleteTransformFeedbacks>(n, ids);
 
-        if (context->skipValidation() || ValidateGetQueryiv(context, target, pname, params))
+        if (context->skipValidation() || ValidateDeleteTransformFeedbacks(context, n, ids))
         {
-            context->getQueryiv(target, pname, params);
+            context->deleteTransformFeedbacks(n, ids);
         }
     }
 }
 
-void GL_APIENTRY GetQueryObjectuiv(GLuint id, GLenum pname, GLuint *params)
+void GL_APIENTRY DeleteVertexArrays(GLsizei n, const GLuint *arrays)
 {
-    EVENT("(GLuint id = %u, GLenum pname = 0x%X, GLuint *params = 0x%0.8p)", id, pname, params);
+    EVENT("(GLsizei n = %d, const GLuint *arrays = 0x%0.8p)", n, arrays);
 
     Context *context = GetValidGlobalContext();
     if (context)
     {
-        context->gatherParams<EntryPoint::GetQueryObjectuiv>(id, pname, params);
+        context->gatherParams<EntryPoint::DeleteVertexArrays>(n, arrays);
 
-        if (context->skipValidation() || ValidateGetQueryObjectuiv(context, id, pname, params))
+        if (context->skipValidation() || ValidateDeleteVertexArrays(context, n, arrays))
         {
-            context->getQueryObjectuiv(id, pname, params);
+            context->deleteVertexArrays(n, arrays);
         }
     }
 }
 
-GLboolean GL_APIENTRY UnmapBuffer(GLenum target)
+void GL_APIENTRY DrawArraysInstanced(GLenum mode, GLint first, GLsizei count, GLsizei instancecount)
 {
-    EVENT("(GLenum target = 0x%X)", target);
+    EVENT("(GLenum mode = 0x%X, GLint first = %d, GLsizei count = %d, GLsizei instancecount = %d)",
+          mode, first, count, instancecount);
 
     Context *context = GetValidGlobalContext();
     if (context)
     {
-        context->gatherParams<EntryPoint::UnmapBuffer>(target);
-
-        if (context->skipValidation() || ValidateUnmapBuffer(context, target))
-        {
-            return context->unmapBuffer(target);
-        }
-    }
-
-    return GetDefaultReturnValue<EntryPoint::UnmapBuffer, GLboolean>();
-}
+        context->gatherParams<EntryPoint::DrawArraysInstanced>(mode, first, count, instancecount);
 
-void GL_APIENTRY GetBufferPointerv(GLenum target, GLenum pname, void **params)
-{
-    EVENT("(GLenum target = 0x%X, GLenum pname = 0x%X, void **params = 0x%0.8p)", target, pname,
-          params);
-
-    Context *context = GetValidGlobalContext();
-    if (context)
-    {
-        context->gatherParams<EntryPoint::GetBufferPointerv>(target, pname, params);
-
-        if (context->skipValidation() || ValidateGetBufferPointerv(context, target, pname, params))
+        if (context->skipValidation() ||
+            ValidateDrawArraysInstanced(context, mode, first, count, instancecount))
         {
-            context->getBufferPointerv(target, pname, params);
+            context->drawArraysInstanced(mode, first, count, instancecount);
         }
     }
 }
 
 void GL_APIENTRY DrawBuffers(GLsizei n, const GLenum *bufs)
 {
     EVENT("(GLsizei n = %d, const GLenum *bufs = 0x%0.8p)", n, bufs);
 
@@ -382,209 +492,132 @@ void GL_APIENTRY DrawBuffers(GLsizei n, 
 
         if (context->skipValidation() || ValidateDrawBuffers(context, n, bufs))
         {
             context->drawBuffers(n, bufs);
         }
     }
 }
 
-void GL_APIENTRY UniformMatrix2x3fv(GLint location,
-                                    GLsizei count,
-                                    GLboolean transpose,
-                                    const GLfloat *value)
+void GL_APIENTRY DrawElementsInstanced(GLenum mode,
+                                       GLsizei count,
+                                       GLenum type,
+                                       const void *indices,
+                                       GLsizei instancecount)
 {
     EVENT(
-        "(GLint location = %d, GLsizei count = %d, GLboolean transpose = %u, const GLfloat *value "
-        "= 0x%0.8p)",
-        location, count, transpose, value);
-
-    Context *context = GetValidGlobalContext();
-    if (context)
-    {
-        context->gatherParams<EntryPoint::UniformMatrix2x3fv>(location, count, transpose, value);
-
-        if (context->skipValidation() ||
-            ValidateUniformMatrix2x3fv(context, location, count, transpose, value))
-        {
-            context->uniformMatrix2x3fv(location, count, transpose, value);
-        }
-    }
-}
-
-void GL_APIENTRY UniformMatrix3x2fv(GLint location,
-                                    GLsizei count,
-                                    GLboolean transpose,
-                                    const GLfloat *value)
-{
-    EVENT(
-        "(GLint location = %d, GLsizei count = %d, GLboolean transpose = %u, const GLfloat *value "
-        "= 0x%0.8p)",
-        location, count, transpose, value);
+        "(GLenum mode = 0x%X, GLsizei count = %d, GLenum type = 0x%X, const void *indices = "
+        "0x%0.8p, GLsizei instancecount = %d)",
+        mode, count, type, indices, instancecount);
 
     Context *context = GetValidGlobalContext();
     if (context)
     {
-        context->gatherParams<EntryPoint::UniformMatrix3x2fv>(location, count, transpose, value);
+        context->gatherParams<EntryPoint::DrawElementsInstanced>(mode, count, type, indices,
+                                                                 instancecount);
 
         if (context->skipValidation() ||
-            ValidateUniformMatrix3x2fv(context, location, count, transpose, value))
+            ValidateDrawElementsInstanced(context, mode, count, type, indices, instancecount))
         {
-            context->uniformMatrix3x2fv(location, count, transpose, value);
+            context->drawElementsInstanced(mode, count, type, indices, instancecount);
         }
     }
 }
 
-void GL_APIENTRY UniformMatrix2x4fv(GLint location,
-                                    GLsizei count,
-                                    GLboolean transpose,
-                                    const GLfloat *value)
+void GL_APIENTRY DrawRangeElements(GLenum mode,
+                                   GLuint start,
+                                   GLuint end,
+                                   GLsizei count,
+                                   GLenum type,
+                                   const void *indices)
 {
     EVENT(
-        "(GLint location = %d, GLsizei count = %d, GLboolean transpose = %u, const GLfloat *value "
-        "= 0x%0.8p)",
-        location, count, transpose, value);
+        "(GLenum mode = 0x%X, GLuint start = %u, GLuint end = %u, GLsizei count = %d, GLenum type "
+        "= 0x%X, const void *indices = 0x%0.8p)",
+        mode, start, end, count, type, indices);
 
     Context *context = GetValidGlobalContext();
     if (context)
     {
-        context->gatherParams<EntryPoint::UniformMatrix2x4fv>(location, count, transpose, value);
+        context->gatherParams<EntryPoint::DrawRangeElements>(mode, start, end, count, type,
+                                                             indices);
 
         if (context->skipValidation() ||
-            ValidateUniformMatrix2x4fv(context, location, count, transpose, value))
+            ValidateDrawRangeElements(context, mode, start, end, count, type, indices))
         {
-            context->uniformMatrix2x4fv(location, count, transpose, value);
-        }
-    }
-}
-
-void GL_APIENTRY UniformMatrix4x2fv(GLint location,
-                                    GLsizei count,
-                                    GLboolean transpose,
-                                    const GLfloat *value)
-{
-    EVENT(
-        "(GLint location = %d, GLsizei count = %d, GLboolean transpose = %u, const GLfloat *value "
-        "= 0x%0.8p)",
-        location, count, transpose, value);
-
-    Context *context = GetValidGlobalContext();
-    if (context)
-    {
-        context->gatherParams<EntryPoint::UniformMatrix4x2fv>(location, count, transpose, value);
-
-        if (context->skipValidation() ||
-            ValidateUniformMatrix4x2fv(context, location, count, transpose, value))
-        {
-            context->uniformMatrix4x2fv(location, count, transpose, value);
+            context->drawRangeElements(mode, start, end, count, type, indices);
         }
     }
 }
 
-void GL_APIENTRY UniformMatrix3x4fv(GLint location,
-                                    GLsizei count,
-                                    GLboolean transpose,
-                                    const GLfloat *value)
+void GL_APIENTRY EndQuery(GLenum target)
 {
-    EVENT(
-        "(GLint location = %d, GLsizei count = %d, GLboolean transpose = %u, const GLfloat *value "
-        "= 0x%0.8p)",
-        location, count, transpose, value);
+    EVENT("(GLenum target = 0x%X)", target);
 
     Context *context = GetValidGlobalContext();
     if (context)
     {
-        context->gatherParams<EntryPoint::UniformMatrix3x4fv>(location, count, transpose, value);
+        context->gatherParams<EntryPoint::EndQuery>(target);
 
-        if (context->skipValidation() ||
-            ValidateUniformMatrix3x4fv(context, location, count, transpose, value))
+        if (context->skipValidation() || ValidateEndQuery(context, target))
         {
-            context->uniformMatrix3x4fv(location, count, transpose, value);
+            context->endQuery(target);
         }
     }
 }
 
-void GL_APIENTRY UniformMatrix4x3fv(GLint location,
-                                    GLsizei count,
-                                    GLboolean transpose,
-                                    const GLfloat *value)
+void GL_APIENTRY EndTransformFeedback()
 {
-    EVENT(
-        "(GLint location = %d, GLsizei count = %d, GLboolean transpose = %u, const GLfloat *value "
-        "= 0x%0.8p)",
-        location, count, transpose, value);
+    EVENT("()");
 
     Context *context = GetValidGlobalContext();
     if (context)
     {
-        context->gatherParams<EntryPoint::UniformMatrix4x3fv>(location, count, transpose, value);
+        context->gatherParams<EntryPoint::EndTransformFeedback>();
 
-        if (context->skipValidation() ||
-            ValidateUniformMatrix4x3fv(context, location, count, transpose, value))
+        if (context->skipValidation() || ValidateEndTransformFeedback(context))
         {
-            context->uniformMatrix4x3fv(location, count, transpose, value);
+            context->endTransformFeedback();
         }
     }
 }
 
-void GL_APIENTRY BlitFramebuffer(GLint srcX0,
-                                 GLint srcY0,
-                                 GLint srcX1,
-                                 GLint srcY1,
-                                 GLint dstX0,
-                                 GLint dstY0,
-                                 GLint dstX1,
-                                 GLint dstY1,
-                                 GLbitfield mask,
-                                 GLenum filter)
+GLsync GL_APIENTRY FenceSync(GLenum condition, GLbitfield flags)
 {
-    EVENT(
-        "(GLint srcX0 = %d, GLint srcY0 = %d, GLint srcX1 = %d, GLint srcY1 = %d, GLint dstX0 = "
-        "%d, GLint dstY0 = %d, GLint dstX1 = %d, GLint dstY1 = %d, GLbitfield mask = 0x%X, GLenum "
-        "filter = 0x%X)",
-        srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, mask, filter);
+    EVENT("(GLenum condition = 0x%X, GLbitfield flags = 0x%X)", condition, flags);
 
     Context *context = GetValidGlobalContext();
     if (context)
     {
-        context->gatherParams<EntryPoint::BlitFramebuffer>(srcX0, srcY0, srcX1, srcY1, dstX0, dstY0,
-                                                           dstX1, dstY1, mask, filter);
+        context->gatherParams<EntryPoint::FenceSync>(condition, flags);
 
-        if (context->skipValidation() ||
-            ValidateBlitFramebuffer(context, srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1,
-                                    mask, filter))
+        if (context->skipValidation() || ValidateFenceSync(context, condition, flags))
         {
-            context->blitFramebuffer(srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, mask,
-                                     filter);
+            return context->fenceSync(condition, flags);
         }
     }
+
+    return GetDefaultReturnValue<EntryPoint::FenceSync, GLsync>();
 }
 
-void GL_APIENTRY RenderbufferStorageMultisample(GLenum target,
-                                                GLsizei samples,
-                                                GLenum internalformat,
-                                                GLsizei width,
-                                                GLsizei height)
+void GL_APIENTRY FlushMappedBufferRange(GLenum target, GLintptr offset, GLsizeiptr length)
 {
-    EVENT(
-        "(GLenum target = 0x%X, GLsizei samples = %d, GLenum internalformat = 0x%X, GLsizei width "
-        "= %d, GLsizei height = %d)",
-        target, samples, internalformat, width, height);
+    EVENT("(GLenum target = 0x%X, GLintptr offset = %d, GLsizeiptr length = %d)", target, offset,
+          length);
 
     Context *context = GetValidGlobalContext();
     if (context)
     {
-        context->gatherParams<EntryPoint::RenderbufferStorageMultisample>(
-            target, samples, internalformat, width, height);
+        BufferBinding targetPacked = FromGLenum<BufferBinding>(target);
+        context->gatherParams<EntryPoint::FlushMappedBufferRange>(targetPacked, offset, length);
 
         if (context->skipValidation() ||
-            ValidateRenderbufferStorageMultisample(context, target, samples, internalformat, width,
-                                                   height))
+            ValidateFlushMappedBufferRange(context, targetPacked, offset, length))
         {
-            context->renderbufferStorageMultisample(target, samples, internalformat, width, height);
+            context->flushMappedBufferRange(targetPacked, offset, length);
         }
     }
 }
 
 void GL_APIENTRY
 FramebufferTextureLayer(GLenum target, GLenum attachment, GLuint texture, GLint level, GLint layer)
 {
     EVENT(
@@ -601,87 +634,60 @@ FramebufferTextureLayer(GLenum target, G
         if (context->skipValidation() ||
             ValidateFramebufferTextureLayer(context, target, attachment, texture, level, layer))
         {
             context->framebufferTextureLayer(target, attachment, texture, level, layer);
         }
     }
 }
 
-void *GL_APIENTRY MapBufferRange(GLenum target,
-                                 GLintptr offset,
-                                 GLsizeiptr length,
-                                 GLbitfield access)
+void GL_APIENTRY GenQueries(GLsizei n, GLuint *ids)
 {
-    EVENT(
-        "(GLenum target = 0x%X, GLintptr offset = %d, GLsizeiptr length = %d, GLbitfield access = "
-        "0x%X)",
-        target, offset, length, access);
-
-    Context *context = GetValidGlobalContext();
-    if (context)
-    {
-        context->gatherParams<EntryPoint::MapBufferRange>(target, offset, length, access);
-
-        if (context->skipValidation() ||
-            ValidateMapBufferRange(context, target, offset, length, access))
-        {
-            return context->mapBufferRange(target, offset, length, access);
-        }
-    }
-
-    return GetDefaultReturnValue<EntryPoint::MapBufferRange, void *>();
-}
-
-void GL_APIENTRY FlushMappedBufferRange(GLenum target, GLintptr offset, GLsizeiptr length)
-{
-    EVENT("(GLenum target = 0x%X, GLintptr offset = %d, GLsizeiptr length = %d)", target, offset,
-          length);
+    EVENT("(GLsizei n = %d, GLuint *ids = 0x%0.8p)", n, ids);
 
     Context *context = GetValidGlobalContext();
     if (context)
     {
-        context->gatherParams<EntryPoint::FlushMappedBufferRange>(target, offset, length);
+        context->gatherParams<EntryPoint::GenQueries>(n, ids);
 
-        if (context->skipValidation() ||
-            ValidateFlushMappedBufferRange(context, target, offset, length))
+        if (context->skipValidation() || ValidateGenQueries(context, n, ids))
         {
-            context->flushMappedBufferRange(target, offset, length);
+            context->genQueries(n, ids);
         }
     }
 }
 
-void GL_APIENTRY BindVertexArray(GLuint array)
+void GL_APIENTRY GenSamplers(GLsizei count, GLuint *samplers)
 {
-    EVENT("(GLuint array = %u)", array);
+    EVENT("(GLsizei count = %d, GLuint *samplers = 0x%0.8p)", count, samplers);
 
     Context *context = GetValidGlobalContext();
     if (context)
     {
-        context->gatherParams<EntryPoint::BindVertexArray>(array);
+        context->gatherParams<EntryPoint::GenSamplers>(count, samplers);
 
-        if (context->skipValidation() || ValidateBindVertexArray(context, array))
+        if (context->skipValidation() || ValidateGenSamplers(context, count, samplers))
         {
-            context->bindVertexArray(array);
+            context->genSamplers(count, samplers);
         }
     }
 }
 
-void GL_APIENTRY DeleteVertexArrays(GLsizei n, const GLuint *arrays)
+void GL_APIENTRY GenTransformFeedbacks(GLsizei n, GLuint *ids)
 {
-    EVENT("(GLsizei n = %d, const GLuint *arrays = 0x%0.8p)", n, arrays);
+    EVENT("(GLsizei n = %d, GLuint *ids = 0x%0.8p)", n, ids);
 
     Context *context = GetValidGlobalContext();
     if (context)
     {
-        context->gatherParams<EntryPoint::DeleteVertexArrays>(n, arrays);
+        context->gatherParams<EntryPoint::GenTransformFeedbacks>(n, ids);
 
-        if (context->skipValidation() || ValidateDeleteVertexArrays(context, n, arrays))
+        if (context->skipValidation() || ValidateGenTransformFeedbacks(context, n, ids))
         {
-            context->deleteVertexArrays(n, arrays);
+            context->genTransformFeedbacks(n, ids);
         }
     }
 }
 
 void GL_APIENTRY GenVertexArrays(GLsizei n, GLuint *arrays)
 {
     EVENT("(GLsizei n = %d, GLuint *arrays = 0x%0.8p)", n, arrays);
 
@@ -692,32 +698,179 @@ void GL_APIENTRY GenVertexArrays(GLsizei
 
         if (context->skipValidation() || ValidateGenVertexArrays(context, n, arrays))
         {
             context->genVertexArrays(n, arrays);
         }
     }
 }
 
-GLboolean GL_APIENTRY IsVertexArray(GLuint array)
+void GL_APIENTRY GetActiveUniformBlockName(GLuint program,
+                                           GLuint uniformBlockIndex,
+                                           GLsizei bufSize,
+                                           GLsizei *length,
+                                           GLchar *uniformBlockName)
 {
-    EVENT("(GLuint array = %u)", array);
+    EVENT(
+        "(GLuint program = %u, GLuint uniformBlockIndex = %u, GLsizei bufSize = %d, GLsizei "
+        "*length = 0x%0.8p, GLchar *uniformBlockName = 0x%0.8p)",
+        program, uniformBlockIndex, bufSize, length, uniformBlockName);
+
+    Context *context = GetValidGlobalContext();
+    if (context)
+    {
+        context->gatherParams<EntryPoint::GetActiveUniformBlockName>(
+            program, uniformBlockIndex, bufSize, length, uniformBlockName);
+
+        if (context->skipValidation() ||
+            ValidateGetActiveUniformBlockName(context, program, uniformBlockIndex, bufSize, length,
+                                              uniformBlockName))
+        {
+            context->getActiveUniformBlockName(program, uniformBlockIndex, bufSize, length,
+                                               uniformBlockName);
+        }
+    }
+}
+
+void GL_APIENTRY GetActiveUniformBlockiv(GLuint program,
+                                         GLuint uniformBlockIndex,
+                                         GLenum pname,
+                                         GLint *params)
+{
+    EVENT(
+        "(GLuint program = %u, GLuint uniformBlockIndex = %u, GLenum pname = 0x%X, GLint *params = "
+        "0x%0.8p)",
+        program, uniformBlockIndex, pname, params);
+
+    Context *context = GetValidGlobalContext();
+    if (context)
+    {
+        context->gatherParams<EntryPoint::GetActiveUniformBlockiv>(program, uniformBlockIndex,
+                                                                   pname, params);
+
+        if (context->skipValidation() ||
+            ValidateGetActiveUniformBlockiv(context, program, uniformBlockIndex, pname, params))
+        {
+            context->getActiveUniformBlockiv(program, uniformBlockIndex, pname, params);
+        }
+    }
+}
+
+void GL_APIENTRY GetActiveUniformsiv(GLuint program,
+                                     GLsizei uniformCount,
+                                     const GLuint *uniformIndices,
+                                     GLenum pname,
+                                     GLint *params)
+{
+    EVENT(
+        "(GLuint program = %u, GLsizei uniformCount = %d, const GLuint *uniformIndices = 0x%0.8p, "
+        "GLenum pname = 0x%X, GLint *params = 0x%0.8p)",
+        program, uniformCount, uniformIndices, pname, params);
 
     Context *context = GetValidGlobalContext();
     if (context)
     {
-        context->gatherParams<EntryPoint::IsVertexArray>(array);
+        context->gatherParams<EntryPoint::GetActiveUniformsiv>(program, uniformCount,
+                                                               uniformIndices, pname, params);
+
+        if (context->skipValidation() || ValidateGetActiveUniformsiv(context, program, uniformCount,
+                                                                     uniformIndices, pname, params))
+        {
+            context->getActiveUniformsiv(program, uniformCount, uniformIndices, pname, params);
+        }
+    }
+}
+
+void GL_APIENTRY GetBufferParameteri64v(GLenum target, GLenum pname, GLint64 *params)
+{
+    EVENT("(GLenum target = 0x%X, GLenum pname = 0x%X, GLint64 *params = 0x%0.8p)", target, pname,
+          params);
+
+    Context *context = GetValidGlobalContext();
+    if (context)
+    {
+        BufferBinding targetPacked = FromGLenum<BufferBinding>(target);
+        context->gatherParams<EntryPoint::GetBufferParameteri64v>(targetPacked, pname, params);
+
+        if (context->skipValidation() ||
+            ValidateGetBufferParameteri64v(context, targetPacked, pname, params))
+        {
+            context->getBufferParameteri64v(targetPacked, pname, params);
+        }
+    }
+}
 
-        if (context->skipValidation() || ValidateIsVertexArray(context, array))
+void GL_APIENTRY GetBufferPointerv(GLenum target, GLenum pname, void **params)
+{
+    EVENT("(GLenum target = 0x%X, GLenum pname = 0x%X, void **params = 0x%0.8p)", target, pname,
+          params);
+
+    Context *context = GetValidGlobalContext();
+    if (context)
+    {
+        BufferBinding targetPacked = FromGLenum<BufferBinding>(target);
+        context->gatherParams<EntryPoint::GetBufferPointerv>(targetPacked, pname, params);
+
+        if (context->skipValidation() ||
+            ValidateGetBufferPointerv(context, targetPacked, pname, params))
         {
-            return context->isVertexArray(array);
+            context->getBufferPointerv(targetPacked, pname, params);
+        }
+    }
+}
+
+GLint GL_APIENTRY GetFragDataLocation(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::GetFragDataLocation>(program, name);
+
+        if (context->skipValidation() || ValidateGetFragDataLocation(context, program, name))
+        {
+            return context->getFragDataLocation(program, name);
         }
     }
 
-    return GetDefaultReturnValue<EntryPoint::IsVertexArray, GLboolean>();
+    return GetDefaultReturnValue<EntryPoint::GetFragDataLocation, GLint>();
+}
+
+void GL_APIENTRY GetInteger64i_v(GLenum target, GLuint index, GLint64 *data)
+{
+    EVENT("(GLenum target = 0x%X, GLuint index = %u, GLint64 *data = 0x%0.8p)", target, index,
+          data);
+
+    Context *context = GetValidGlobalContext();
+    if (context)
+    {
+        context->gatherParams<EntryPoint::GetInteger64i_v>(target, index, data);
+
+        if (context->skipValidation() || ValidateGetInteger64i_v(context, target, index, data))
+        {
+            context->getInteger64i_v(target, index, data);
+        }
+    }
+}
+
+void GL_APIENTRY GetInteger64v(GLenum pname, GLint64 *data)
+{
+    EVENT("(GLenum pname = 0x%X, GLint64 *data = 0x%0.8p)", pname, data);
+
+    Context *context = GetValidGlobalContext();
+    if (context)
+    {
+        context->gatherParams<EntryPoint::GetInteger64v>(pname, data);
+
+        if (context->skipValidation() || ValidateGetInteger64v(context, pname, data))
+        {
+            context->getInteger64v(pname, data);
+        }
+    }
 }
 
 void GL_APIENTRY GetIntegeri_v(GLenum target, GLuint index, GLint *data)
 {
     EVENT("(GLenum target = 0x%X, GLuint index = %u, GLint *data = 0x%0.8p)", target, index, data);
 
     Context *context = GetValidGlobalContext();
     if (context)
@@ -726,105 +879,170 @@ void GL_APIENTRY GetIntegeri_v(GLenum ta
 
         if (context->skipValidation() || ValidateGetIntegeri_v(context, target, index, data))
         {
             context->getIntegeri_v(target, index, data);
         }
     }
 }
 
-void GL_APIENTRY BeginTransformFeedback(GLenum primitiveMode)
+void GL_APIENTRY GetInternalformativ(GLenum target,
+                                     GLenum internalformat,
+                                     GLenum pname,
+                                     GLsizei bufSize,
+                                     GLint *params)
 {
-    EVENT("(GLenum primitiveMode = 0x%X)", primitiveMode);
+    EVENT(
+        "(GLenum target = 0x%X, GLenum internalformat = 0x%X, GLenum pname = 0x%X, GLsizei bufSize "
+        "= %d, GLint *params = 0x%0.8p)",
+        target, internalformat, pname, bufSize, params);
 
     Context *context = GetValidGlobalContext();
     if (context)
     {
-        context->gatherParams<EntryPoint::BeginTransformFeedback>(primitiveMode);
+        context->gatherParams<EntryPoint::GetInternalformativ>(target, internalformat, pname,
+                                                               bufSize, params);
 
-        if (context->skipValidation() || ValidateBeginTransformFeedback(context, primitiveMode))
+        if (context->skipValidation() ||
+            ValidateGetInternalformativ(context, target, internalformat, pname, bufSize, params))
         {
-            context->beginTransformFeedback(primitiveMode);
+            context->getInternalformativ(target, internalformat, pname, bufSize, params);
         }
     }
 }
 
-void GL_APIENTRY EndTransformFeedback()
+void GL_APIENTRY GetProgramBinary(GLuint program,
+                                  GLsizei bufSize,
+                                  GLsizei *length,
+                                  GLenum *binaryFormat,
+                                  void *binary)
 {
-    EVENT("()");
+    EVENT(
+        "(GLuint program = %u, GLsizei bufSize = %d, GLsizei *length = 0x%0.8p, GLenum "
+        "*binaryFormat = 0x%0.8p, void *binary = 0x%0.8p)",
+        program, bufSize, length, binaryFormat, binary);
 
     Context *context = GetValidGlobalContext();
     if (context)
     {
-        context->gatherParams<EntryPoint::EndTransformFeedback>();
+        context->gatherParams<EntryPoint::GetProgramBinary>(program, bufSize, length, binaryFormat,
+                                                            binary);
 
-        if (context->skipValidation() || ValidateEndTransformFeedback(context))
+        if (context->skipValidation() ||
+            ValidateGetProgramBinary(context, program, bufSize, length, binaryFormat, binary))
         {
-            context->endTransformFeedback();
+            context->getProgramBinary(program, bufSize, length, binaryFormat, binary);
         }
     }
 }
 
-void GL_APIENTRY
-BindBufferRange(GLenum target, GLuint index, GLuint buffer, GLintptr offset, GLsizeiptr size)
+void GL_APIENTRY GetQueryObjectuiv(GLuint id, GLenum pname, GLuint *params)
 {
-    EVENT(
-        "(GLenum target = 0x%X, GLuint index = %u, GLuint buffer = %u, GLintptr offset = %d, "
-        "GLsizeiptr size = %d)",
-        target, index, buffer, offset, size);
+    EVENT("(GLuint id = %u, GLenum pname = 0x%X, GLuint *params = 0x%0.8p)", id, pname, params);
+
+    Context *context = GetValidGlobalContext();
+    if (context)
+    {
+        context->gatherParams<EntryPoint::GetQueryObjectuiv>(id, pname, params);
+
+        if (context->skipValidation() || ValidateGetQueryObjectuiv(context, id, pname, params))
+        {
+            context->getQueryObjectuiv(id, pname, params);
+        }
+    }
+}
+
+void GL_APIENTRY GetQueryiv(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::BindBufferRange>(target, index, buffer, offset, size);
+        context->gatherParams<EntryPoint::GetQueryiv>(target, pname, params);
 
-        if (context->skipValidation() ||
-            ValidateBindBufferRange(context, target, index, buffer, offset, size))
+        if (context->skipValidation() || ValidateGetQueryiv(context, target, pname, params))
         {
-            context->bindBufferRange(target, index, buffer, offset, size);
+            context->getQueryiv(target, pname, params);
         }
     }
 }
 
-void GL_APIENTRY BindBufferBase(GLenum target, GLuint index, GLuint buffer)
+void GL_APIENTRY GetSamplerParameterfv(GLuint sampler, GLenum pname, GLfloat *params)
 {
-    EVENT("(GLenum target = 0x%X, GLuint index = %u, GLuint buffer = %u)", target, index, buffer);
+    EVENT("(GLuint sampler = %u, GLenum pname = 0x%X, GLfloat *params = 0x%0.8p)", sampler, pname,
+          params);
+
+    Context *context = GetValidGlobalContext();
+    if (context)
+    {
+        context->gatherParams<EntryPoint::GetSamplerParameterfv>(sampler, pname, params);
+
+        if (context->skipValidation() ||
+            ValidateGetSamplerParameterfv(context, sampler, pname, params))
+        {
+            context->getSamplerParameterfv(sampler, pname, params);
+        }
+    }
+}
+
+void GL_APIENTRY GetSamplerParameteriv(GLuint sampler, GLenum pname, GLint *params)
+{
+    EVENT("(GLuint sampler = %u, GLenum pname = 0x%X, GLint *params = 0x%0.8p)", sampler, pname,
+          params);
 
     Context *context = GetValidGlobalContext();
     if (context)
     {
-        context->gatherParams<EntryPoint::BindBufferBase>(target, index, buffer);
+        context->gatherParams<EntryPoint::GetSamplerParameteriv>(sampler, pname, params);
 
-        if (context->skipValidation() || ValidateBindBufferBase(context, target, index, buffer))
+        if (context->skipValidation() ||
+            ValidateGetSamplerParameteriv(context, sampler, pname, params))
         {
-            context->bindBufferBase(target, index, buffer);
+            context->getSamplerParameteriv(sampler, pname, params);
         }
     }
 }
 
-void GL_APIENTRY TransformFeedbackVaryings(GLuint program,
-                                           GLsizei count,
-                                           const GLchar *const *varyings,
-                                           GLenum bufferMode)
+const GLubyte *GL_APIENTRY GetStringi(GLenum name, GLuint index)
 {
-    EVENT(
-        "(GLuint program = %u, GLsizei count = %d, const GLchar *const*varyings = 0x%0.8p, GLenum "
-        "bufferMode = 0x%X)",
-        program, count, varyings, bufferMode);
+    EVENT("(GLenum name = 0x%X, GLuint index = %u)", name, index);
 
     Context *context = GetValidGlobalContext();
     if (context)
     {
-        context->gatherParams<EntryPoint::TransformFeedbackVaryings>(program, count, varyings,
-                                                                     bufferMode);
+        context->gatherParams<EntryPoint::GetStringi>(name, index);
+
+        if (context->skipValidation() || ValidateGetStringi(context, name, index))
+        {
+            return context->getStringi(name, index);
+        }
+    }
+
+    return GetDefaultReturnValue<EntryPoint::GetStringi, const GLubyte *>();
+}
+
+void GL_APIENTRY
+GetSynciv(GLsync sync, GLenum pname, GLsizei bufSize, GLsizei *length, GLint *values)
+{
+    EVENT(
+        "(GLsync sync = 0x%0.8p, GLenum pname = 0x%X, GLsizei bufSize = %d, GLsizei *length = "
+        "0x%0.8p, GLint *values = 0x%0.8p)",
+        sync, pname, bufSize, length, values);
+
+    Context *context = GetValidGlobalContext();
+    if (context)
+    {
+        context->gatherParams<EntryPoint::GetSynciv>(sync, pname, bufSize, length, values);
 
         if (context->skipValidation() ||
-            ValidateTransformFeedbackVaryings(context, program, count, varyings, bufferMode))
+            ValidateGetSynciv(context, sync, pname, bufSize, length, values))
         {
-            context->transformFeedbackVaryings(program, count, varyings, bufferMode);
+            context->getSynciv(sync, pname, bufSize, length, values);
         }
     }
 }
 
 void GL_APIENTRY GetTransformFeedbackVarying(GLuint program,
                                              GLuint index,
                                              GLsizei bufSize,
                                              GLsizei *length,
@@ -847,33 +1065,73 @@ void GL_APIENTRY GetTransformFeedbackVar
             ValidateGetTransformFeedbackVarying(context, program, index, bufSize, length, size,
                                                 type, name))
         {
             context->getTransformFeedbackVarying(program, index, bufSize, length, size, type, name);
         }
     }
 }
 
-void GL_APIENTRY
-VertexAttribIPointer(GLuint index, GLint size, GLenum type, GLsizei stride, const void *pointer)
+GLuint GL_APIENTRY GetUniformBlockIndex(GLuint program, const GLchar *uniformBlockName)
 {
-    EVENT(
-        "(GLuint index = %u, GLint size = %d, GLenum type = 0x%X, GLsizei stride = %d, const void "
-        "*pointer = 0x%0.8p)",
-        index, size, type, stride, pointer);
+    EVENT("(GLuint program = %u, const GLchar *uniformBlockName = 0x%0.8p)", program,
+          uniformBlockName);
 
     Context *context = GetValidGlobalContext();
     if (context)
     {
-        context->gatherParams<EntryPoint::VertexAttribIPointer>(index, size, type, stride, pointer);
+        context->gatherParams<EntryPoint::GetUniformBlockIndex>(program, uniformBlockName);
 
         if (context->skipValidation() ||
-            ValidateVertexAttribIPointer(context, index, size, type, stride, pointer))
+            ValidateGetUniformBlockIndex(context, program, uniformBlockName))
         {
-            context->vertexAttribIPointer(index, size, type, stride, pointer);
+            return context->getUniformBlockIndex(program, uniformBlockName);
+        }
+    }
+
+    return GetDefaultReturnValue<EntryPoint::GetUniformBlockIndex, GLuint>();
+}
+
+void GL_APIENTRY GetUniformIndices(GLuint program,
+                                   GLsizei uniformCount,
+                                   const GLchar *const *uniformNames,
+                                   GLuint *uniformIndices)
+{
+    EVENT(
+        "(GLuint program = %u, GLsizei uniformCount = %d, const GLchar *const*uniformNames = "
+        "0x%0.8p, GLuint *uniformIndices = 0x%0.8p)",
+        program, uniformCount, uniformNames, uniformIndices);
+
+    Context *context = GetValidGlobalContext();
+    if (context)
+    {
+        context->gatherParams<EntryPoint::GetUniformIndices>(program, uniformCount, uniformNames,
+                                                             uniformIndices);
+
+        if (context->skipValidation() ||
+            ValidateGetUniformIndices(context, program, uniformCount, uniformNames, uniformIndices))
+        {
+            context->getUniformIndices(program, uniformCount, uniformNames, uniformIndices);
+        }
+    }
+}
+
+void GL_APIENTRY GetUniformuiv(GLuint program, GLint location, GLuint *params)
+{
+    EVENT("(GLuint program = %u, GLint location = %d, GLuint *params = 0x%0.8p)", program, location,
+          params);
+
+    Context *context = GetValidGlobalContext();
+    if (context)
+    {
+        context->gatherParams<EntryPoint::GetUniformuiv>(program, location, params);
+
+        if (context->skipValidation() || ValidateGetUniformuiv(context, program, location, params))
+        {
+            context->getUniformuiv(program, location, params);
         }
     }
 }
 
 void GL_APIENTRY GetVertexAttribIiv(GLuint index, GLenum pname, GLint *params)
 {
     EVENT("(GLuint index = %u, GLenum pname = 0x%X, GLint *params = 0x%0.8p)", index, pname,
           params);
@@ -902,1053 +1160,16 @@ void GL_APIENTRY GetVertexAttribIuiv(GLu
 
         if (context->skipValidation() || ValidateGetVertexAttribIuiv(context, index, pname, params))
         {
             context->getVertexAttribIuiv(index, pname, params);
         }
     }
 }
 
-void GL_APIENTRY VertexAttribI4i(GLuint index, GLint x, GLint y, GLint z, GLint w)
-{
-    EVENT("(GLuint index = %u, GLint x = %d, GLint y = %d, GLint z = %d, GLint w = %d)", index, x,
-          y, z, w);
-
-    Context *context = GetValidGlobalContext();
-    if (context)
-    {
-        context->gatherParams<EntryPoint::VertexAttribI4i>(index, x, y, z, w);
-
-        if (context->skipValidation() || ValidateVertexAttribI4i(context, index, x, y, z, w))
-        {
-            context->vertexAttribI4i(index, x, y, z, w);
-        }
-    }
-}
-
-void GL_APIENTRY VertexAttribI4ui(GLuint index, GLuint x, GLuint y, GLuint z, GLuint w)
-{
-    EVENT("(GLuint index = %u, GLuint x = %u, GLuint y = %u, GLuint z = %u, GLuint w = %u)", index,
-          x, y, z, w);
-
-    Context *context = GetValidGlobalContext();
-    if (context)
-    {
-        context->gatherParams<EntryPoint::VertexAttribI4ui>(index, x, y, z, w);
-
-        if (context->skipValidation() || ValidateVertexAttribI4ui(context, index, x, y, z, w))
-        {
-            context->vertexAttribI4ui(index, x, y, z, w);
-        }
-    }
-}
-
-void GL_APIENTRY VertexAttribI4iv(GLuint index, const GLint *v)
-{
-    EVENT("(GLuint index = %u, const GLint *v = 0x%0.8p)", index, v);
-
-    Context *context = GetValidGlobalContext();
-    if (context)
-    {
-        context->gatherParams<EntryPoint::VertexAttribI4iv>(index, v);
-
-        if (context->skipValidation() || ValidateVertexAttribI4iv(context, index, v))
-        {
-            context->vertexAttribI4iv(index, v);
-        }
-    }
-}
-
-void GL_APIENTRY VertexAttribI4uiv(GLuint index, const GLuint *v)
-{
-    EVENT("(GLuint index = %u, const GLuint *v = 0x%0.8p)", index, v);
-
-    Context *context = GetValidGlobalContext();
-    if (context)
-    {
-        context->gatherParams<EntryPoint::VertexAttribI4uiv>(index, v);
-
-        if (context->skipValidation() || ValidateVertexAttribI4uiv(context, index, v))
-        {
-            context->vertexAttribI4uiv(index, v);
-        }
-    }
-}
-
-void GL_APIENTRY GetUniformuiv(GLuint program, GLint location, GLuint *params)
-{
-    EVENT("(GLuint program = %u, GLint location = %d, GLuint *params = 0x%0.8p)", program, location,
-          params);
-
-    Context *context = GetValidGlobalContext();
-    if (context)
-    {
-        context->gatherParams<EntryPoint::GetUniformuiv>(program, location, params);
-
-        if (context->skipValidation() || ValidateGetUniformuiv(context, program, location, params))
-        {
-            context->getUniformuiv(program, location, params);
-        }
-    }
-}
-
-GLint GL_APIENTRY GetFragDataLocation(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::GetFragDataLocation>(program, name);
-
-        if (context->skipValidation() || ValidateGetFragDataLocation(context, program, name))
-        {
-            return context->getFragDataLocation(program, name);
-        }
-    }
-
-    return GetDefaultReturnValue<EntryPoint::GetFragDataLocation, GLint>();
-}
-
-void GL_APIENTRY Uniform1ui(GLint location, GLuint v0)
-{
-    EVENT("(GLint location = %d, GLuint v0 = %u)", location, v0);
-
-    Context *context = GetValidGlobalContext();
-    if (context)
-    {
-        context->gatherParams<EntryPoint::Uniform1ui>(location, v0);
-
-        if (context->skipValidation() || ValidateUniform1ui(context, location, v0))
-        {
-            context->uniform1ui(location, v0);
-        }
-    }
-}
-
-void GL_APIENTRY Uniform2ui(GLint location, GLuint v0, GLuint v1)
-{
-    EVENT("(GLint location = %d, GLuint v0 = %u, GLuint v1 = %u)", location, v0, v1);
-
-    Context *context = GetValidGlobalContext();
-    if (context)
-    {
-        context->gatherParams<EntryPoint::Uniform2ui>(location, v0, v1);
-
-        if (context->skipValidation() || ValidateUniform2ui(context, location, v0, v1))
-        {
-            context->uniform2ui(location, v0, v1);
-        }
-    }
-}
-
-void GL_APIENTRY Uniform3ui(GLint location, GLuint v0, GLuint v1, GLuint v2)
-{
-    EVENT("(GLint location = %d, GLuint v0 = %u, GLuint v1 = %u, GLuint v2 = %u)", location, v0, v1,
-          v2);
-
-    Context *context = GetValidGlobalContext();
-    if (context)
-    {
-        context->gatherParams<EntryPoint::Uniform3ui>(location, v0, v1, v2);
-
-        if (context->skipValidation() || ValidateUniform3ui(context, location, v0, v1, v2))
-        {
-            context->uniform3ui(location, v0, v1, v2);
-        }
-    }
-}
-
-void GL_APIENTRY Uniform4ui(GLint location, GLuint v0, GLuint v1, GLuint v2, GLuint v3)
-{
-    EVENT("(GLint location = %d, GLuint v0 = %u, GLuint v1 = %u, GLuint v2 = %u, GLuint v3 = %u)",
-          location, v0, v1, v2, v3);
-
-    Context *context = GetValidGlobalContext();
-    if (context)
-    {
-        context->gatherParams<EntryPoint::Uniform4ui>(location, v0, v1, v2, v3);
-
-        if (context->skipValidation() || ValidateUniform4ui(context, location, v0, v1, v2, v3))
-        {
-            context->uniform4ui(location, v0, v1, v2, v3);
-        }
-    }
-}
-
-void GL_APIENTRY Uniform1uiv(GLint location, GLsizei count, const GLuint *value)
-{
-    EVENT("(GLint location = %d, GLsizei count = %d, const GLuint *value = 0x%0.8p)", location,
-          count, value);
-
-    Context *context = GetValidGlobalContext();
-    if (context)
-    {
-        context->gatherParams<EntryPoint::Uniform1uiv>(location, count, value);
-
-        if (context->skipValidation() || ValidateUniform1uiv(context, location, count, value))
-        {
-            context->uniform1uiv(location, count, value);
-        }
-    }
-}
-
-void GL_APIENTRY Uniform2uiv(GLint location, GLsizei count, const GLuint *value)
-{
-    EVENT("(GLint location = %d, GLsizei count = %d, const GLuint *value = 0x%0.8p)", location,
-          count, value);
-
-    Context *context = GetValidGlobalContext();
-    if (context)
-    {
-        context->gatherParams<EntryPoint::Uniform2uiv>(location, count, value);
-
-        if (context->skipValidation() || ValidateUniform2uiv(context, location, count, value))
-        {
-            context->uniform2uiv(location, count, value);
-        }
-    }
-}
-
-void GL_APIENTRY Uniform3uiv(GLint location, GLsizei count, const GLuint *value)
-{
-    EVENT("(GLint location = %d, GLsizei count = %d, const GLuint *value = 0x%0.8p)", location,
-          count, value);
-
-    Context *context = GetValidGlobalContext();
-    if (context)
-    {
-        context->gatherParams<EntryPoint::Uniform3uiv>(location, count, value);
-
-        if (context->skipValidation() || ValidateUniform3uiv(context, location, count, value))
-        {
-            context->uniform3uiv(location, count, value);
-        }
-    }
-}
-
-void GL_APIENTRY Uniform4uiv(GLint location, GLsizei count, const GLuint *value)
-{
-    EVENT("(GLint location = %d, GLsizei count = %d, const GLuint *value = 0x%0.8p)", location,
-          count, value);
-
-    Context *context = GetValidGlobalContext();
-    if (context)
-    {
-        context->gatherParams<EntryPoint::Uniform4uiv>(location, count, value);
-
-        if (context->skipValidation() || ValidateUniform4uiv(context, location, count, value))
-        {
-            context->uniform4uiv(location, count, value);
-        }
-    }
-}
-
-void GL_APIENTRY ClearBufferiv(GLenum buffer, GLint drawbuffer, const GLint *value)
-{
-    EVENT("(GLenum buffer = 0x%X, GLint drawbuffer = %d, const GLint *value = 0x%0.8p)", buffer,
-          drawbuffer, value);
-
-    Context *context = GetValidGlobalContext();
-    if (context)
-    {
-        context->gatherParams<EntryPoint::ClearBufferiv>(buffer, drawbuffer, value);
-
-        if (context->skipValidation() || ValidateClearBufferiv(context, buffer, drawbuffer, value))
-        {
-            context->clearBufferiv(buffer, drawbuffer, value);
-        }
-    }
-}
-
-void GL_APIENTRY ClearBufferuiv(GLenum buffer, GLint drawbuffer, const GLuint *value)
-{
-    EVENT("(GLenum buffer = 0x%X, GLint drawbuffer = %d, const GLuint *value = 0x%0.8p)", buffer,
-          drawbuffer, value);
-
-    Context *context = GetValidGlobalContext();
-    if (context)
-    {
-        context->gatherParams<EntryPoint::ClearBufferuiv>(buffer, drawbuffer, value);
-
-        if (context->skipValidation() || ValidateClearBufferuiv(context, buffer, drawbuffer, value))
-        {
-            context->clearBufferuiv(buffer, drawbuffer, value);
-        }
-    }
-}
-
-void GL_APIENTRY ClearBufferfv(GLenum buffer, GLint drawbuffer, const GLfloat *value)
-{
-    EVENT("(GLenum buffer = 0x%X, GLint drawbuffer = %d, const GLfloat *value = 0x%0.8p)", buffer,
-          drawbuffer, value);
-
-    Context *context = GetValidGlobalContext();
-    if (context)
-    {
-        context->gatherParams<EntryPoint::ClearBufferfv>(buffer, drawbuffer, value);
-
-        if (context->skipValidation() || ValidateClearBufferfv(context, buffer, drawbuffer, value))
-        {
-            context->clearBufferfv(buffer, drawbuffer, value);
-        }
-    }
-}
-
-void GL_APIENTRY ClearBufferfi(GLenum buffer, GLint drawbuffer, GLfloat depth, GLint stencil)
-{
-    EVENT("(GLenum buffer = 0x%X, GLint drawbuffer = %d, GLfloat depth = %f, GLint stencil = %d)",
-          buffer, drawbuffer, depth, stencil);
-
-    Context *context = GetValidGlobalContext();
-    if (context)
-    {
-        context->gatherParams<EntryPoint::ClearBufferfi>(buffer, drawbuffer, depth, stencil);
-
-        if (context->skipValidation() ||
-            ValidateClearBufferfi(context, buffer, drawbuffer, depth, stencil))
-        {
-            context->clearBufferfi(buffer, drawbuffer, depth, stencil);
-        }
-    }
-}
-
-const GLubyte *GL_APIENTRY GetStringi(GLenum name, GLuint index)
-{
-    EVENT("(GLenum name = 0x%X, GLuint index = %u)", name, index);
-
-    Context *context = GetValidGlobalContext();
-    if (context)
-    {
-        context->gatherParams<EntryPoint::GetStringi>(name, index);
-
-        if (context->skipValidation() || ValidateGetStringi(context, name, index))
-        {
-            return context->getStringi(name, index);
-        }
-    }
-
-    return GetDefaultReturnValue<EntryPoint::GetStringi, const GLubyte *>();
-}
-
-void GL_APIENTRY CopyBufferSubData(GLenum readTarget,
-                                   GLenum writeTarget,
-                                   GLintptr readOffset,
-                                   GLintptr writeOffset,
-                                   GLsizeiptr size)
-{
-    EVENT(
-        "(GLenum readTarget = 0x%X, GLenum writeTarget = 0x%X, GLintptr readOffset = %d, GLintptr "
-        "writeOffset = %d, GLsizeiptr size = %d)",
-        readTarget, writeTarget, readOffset, writeOffset, size);
-
-    Context *context = GetValidGlobalContext();
-    if (context)
-    {
-        context->gatherParams<EntryPoint::CopyBufferSubData>(readTarget, writeTarget, readOffset,
-                                                             writeOffset, size);
-
-        if (context->skipValidation() || ValidateCopyBufferSubData(context, readTarget, writeTarget,
-                                                                   readOffset, writeOffset, size))
-        {
-            context->copyBufferSubData(readTarget, writeTarget, readOffset, writeOffset, size);
-        }
-    }
-}
-
-void GL_APIENTRY GetUniformIndices(GLuint program,
-                                   GLsizei uniformCount,
-                                   const GLchar *const *uniformNames,
-                                   GLuint *uniformIndices)
-{
-    EVENT(
-        "(GLuint program = %u, GLsizei uniformCount = %d, const GLchar *const*uniformNames = "
-        "0x%0.8p, GLuint *uniformIndices = 0x%0.8p)",
-        program, uniformCount, uniformNames, uniformIndices);
-
-    Context *context = GetValidGlobalContext();
-    if (context)
-    {
-        context->gatherParams<EntryPoint::GetUniformIndices>(program, uniformCount, uniformNames,
-                                                             uniformIndices);
-
-        if (context->skipValidation() ||
-            ValidateGetUniformIndices(context, program, uniformCount, uniformNames, uniformIndices))
-        {
-            context->getUniformIndices(program, uniformCount, uniformNames, uniformIndices);
-        }
-    }
-}
-
-void GL_APIENTRY GetActiveUniformsiv(GLuint program,
-                                     GLsizei uniformCount,
-                                     const GLuint *uniformIndices,
-                                     GLenum pname,
-                                     GLint *params)
-{
-    EVENT(
-        "(GLuint program = %u, GLsizei uniformCount = %d, const GLuint *uniformIndices = 0x%0.8p, "
-        "GLenum pname = 0x%X, GLint *params = 0x%0.8p)",
-        program, uniformCount, uniformIndices, pname, params);
-
-    Context *context = GetValidGlobalContext();
-    if (context)
-    {
-        context->gatherParams<EntryPoint::GetActiveUniformsiv>(program, uniformCount,
-                                                               uniformIndices, pname, params);
-
-        if (context->skipValidation() || ValidateGetActiveUniformsiv(context, program, uniformCount,
-                                                                     uniformIndices, pname, params))
-        {
-            context->getActiveUniformsiv(program, uniformCount, uniformIndices, pname, params);
-        }
-    }
-}
-
-GLuint GL_APIENTRY GetUniformBlockIndex(GLuint program, const GLchar *uniformBlockName)
-{
-    EVENT("(GLuint program = %u, const GLchar *uniformBlockName = 0x%0.8p)", program,
-          uniformBlockName);
-
-    Context *context = GetValidGlobalContext();
-    if (context)
-    {
-        context->gatherParams<EntryPoint::GetUniformBlockIndex>(program, uniformBlockName);
-
-        if (context->skipValidation() ||
-            ValidateGetUniformBlockIndex(context, program, uniformBlockName))
-        {
-            return context->getUniformBlockIndex(program, uniformBlockName);
-        }
-    }
-
-    return GetDefaultReturnValue<EntryPoint::GetUniformBlockIndex, GLuint>();
-}
-
-void GL_APIENTRY GetActiveUniformBlockiv(GLuint program,
-                                         GLuint uniformBlockIndex,
-                                         GLenum pname,
-                                         GLint *params)
-{
-    EVENT(
-        "(GLuint program = %u, GLuint uniformBlockIndex = %u, GLenum pname = 0x%X, GLint *params = "
-        "0x%0.8p)",
-        program, uniformBlockIndex, pname, params);
-
-    Context *context = GetValidGlobalContext();
-    if (context)
-    {
-        context->gatherParams<EntryPoint::GetActiveUniformBlockiv>(program, uniformBlockIndex,
-                                                                   pname, params);
-
-        if (context->skipValidation() ||
-            ValidateGetActiveUniformBlockiv(context, program, uniformBlockIndex, pname, params))
-        {
-            context->getActiveUniformBlockiv(program, uniformBlockIndex, pname, params);
-        }
-    }
-}
-
-void GL_APIENTRY GetActiveUniformBlockName(GLuint program,
-                                           GLuint uniformBlockIndex,
-                                           GLsizei bufSize,
-                                           GLsizei *length,
-                                           GLchar *uniformBlockName)
-{
-    EVENT(
-        "(GLuint program = %u, GLuint uniformBlockIndex = %u, GLsizei bufSize = %d, GLsizei "
-        "*length = 0x%0.8p, GLchar *uniformBlockName = 0x%0.8p)",
-        program, uniformBlockIndex, bufSize, length, uniformBlockName);
-
-    Context *context = GetValidGlobalContext();
-    if (context)
-    {
-        context->gatherParams<EntryPoint::GetActiveUniformBlockName>(
-            program, uniformBlockIndex, bufSize, length, uniformBlockName);
-
-        if (context->skipValidation() ||
-            ValidateGetActiveUniformBlockName(context, program, uniformBlockIndex, bufSize, length,
-                                              uniformBlockName))
-        {
-            context->getActiveUniformBlockName(program, uniformBlockIndex, bufSize, length,
-                                               uniformBlockName);
-        }
-    }
-}
-
-void GL_APIENTRY UniformBlockBinding(GLuint program,
-                                     GLuint uniformBlockIndex,
-                                     GLuint uniformBlockBinding)
-{
-    EVENT("(GLuint program = %u, GLuint uniformBlockIndex = %u, GLuint uniformBlockBinding = %u)",
-          program, uniformBlockIndex, uniformBlockBinding);
-
-    Context *context = GetValidGlobalContext();
-    if (context)
-    {
-        context->gatherParams<EntryPoint::UniformBlockBinding>(program, uniformBlockIndex,
-                                                               uniformBlockBinding);
-
-        if (context->skipValidation() ||
-            ValidateUniformBlockBinding(context, program, uniformBlockIndex, uniformBlockBinding))
-        {
-            context->uniformBlockBinding(program, uniformBlockIndex, uniformBlockBinding);
-        }
-    }
-}
-
-void GL_APIENTRY DrawArraysInstanced(GLenum mode, GLint first, GLsizei count, GLsizei instancecount)
-{
-    EVENT("(GLenum mode = 0x%X, GLint first = %d, GLsizei count = %d, GLsizei instancecount = %d)",
-          mode, first, count, instancecount);
-
-    Context *context = GetValidGlobalContext();
-    if (context)
-    {
-        context->gatherParams<EntryPoint::DrawArraysInstanced>(mode, first, count, instancecount);
-
-        if (context->skipValidation() ||
-            ValidateDrawArraysInstanced(context, mode, first, count, instancecount))
-        {
-            context->drawArraysInstanced(mode, first, count, instancecount);
-        }
-    }
-}
-
-void GL_APIENTRY DrawElementsInstanced(GLenum mode,
-                                       GLsizei count,
-                                       GLenum type,
-                                       const void *indices,
-                                       GLsizei instancecount)
-{
-    EVENT(
-        "(GLenum mode = 0x%X, GLsizei count = %d, GLenum type = 0x%X, const void *indices = "
-        "0x%0.8p, GLsizei instancecount = %d)",
-        mode, count, type, indices, instancecount);
-
-    Context *context = GetValidGlobalContext();
-    if (context)
-    {
-        context->gatherParams<EntryPoint::DrawElementsInstanced>(mode, count, type, indices,
-                                                                 instancecount);
-
-        if (context->skipValidation() ||
-            ValidateDrawElementsInstanced(context, mode, count, type, indices, instancecount))
-        {
-            context->drawElementsInstanced(mode, count, type, indices, instancecount);
-        }
-    }
-}
-
-GLsync GL_APIENTRY FenceSync(GLenum condition, GLbitfield flags)
-{
-    EVENT("(GLenum condition = 0x%X, GLbitfield flags = 0x%X)", condition, flags);
-
-    Context *context = GetValidGlobalContext();
-    if (context)
-    {
-        context->gatherParams<EntryPoint::FenceSync>(condition, flags);
-
-        if (context->skipValidation() || ValidateFenceSync(context, condition, flags))
-        {
-            return context->fenceSync(condition, flags);
-        }
-    }
-
-    return GetDefaultReturnValue<EntryPoint::FenceSync, GLsync>();
-}
-
-GLboolean GL_APIENTRY IsSync(GLsync sync)
-{
-    EVENT("(GLsync sync = 0x%0.8p)", sync);
-
-    Context *context = GetValidGlobalContext();
-    if (context)
-    {
-        context->gatherParams<EntryPoint::IsSync>(sync);
-
-        if (context->skipValidation() || ValidateIsSync(context, sync))
-        {
-            return context->isSync(sync);
-        }
-    }
-
-    return GetDefaultReturnValue<EntryPoint::IsSync, GLboolean>();
-}
-
-void GL_APIENTRY DeleteSync(GLsync sync)
-{
-    EVENT("(GLsync sync = 0x%0.8p)", sync);
-
-    Context *context = GetValidGlobalContext();
-    if (context)
-    {
-        context->gatherParams<EntryPoint::DeleteSync>(sync);
-
-        if (context->skipValidation() || ValidateDeleteSync(context, sync))
-        {
-            context->deleteSync(sync);
-        }
-    }
-}
-
-GLenum GL_APIENTRY ClientWaitSync(GLsync sync, GLbitfield flags, GLuint64 timeout)
-{
-    EVENT("(GLsync sync = 0x%0.8p, GLbitfield flags = 0x%X, GLuint64 timeout = %llu)", sync, flags,
-          timeout);
-
-    Context *context = GetValidGlobalContext();
-    if (context)
-    {
-        context->gatherParams<EntryPoint::ClientWaitSync>(sync, flags, timeout);
-
-        if (context->skipValidation() || ValidateClientWaitSync(context, sync, flags, timeout))
-        {
-            return context->clientWaitSync(sync, flags, timeout);
-        }
-    }
-
-    return GetDefaultReturnValue<EntryPoint::ClientWaitSync, GLenum>();
-}
-
-void GL_APIENTRY WaitSync(GLsync sync, GLbitfield flags, GLuint64 timeout)
-{
-    EVENT("(GLsync sync = 0x%0.8p, GLbitfield flags = 0x%X, GLuint64 timeout = %llu)", sync, flags,
-          timeout);
-
-    Context *context = GetValidGlobalContext();
-    if (context)
-    {
-        context->gatherParams<EntryPoint::WaitSync>(sync, flags, timeout);
-
-        if (context->skipValidation() || ValidateWaitSync(context, sync, flags, timeout))
-        {
-            context->waitSync(sync, flags, timeout);
-        }
-    }
-}
-
-void GL_APIENTRY GetInteger64v(GLenum pname, GLint64 *data)
-{
-    EVENT("(GLenum pname = 0x%X, GLint64 *data = 0x%0.8p)", pname, data);
-
-    Context *context = GetValidGlobalContext();
-    if (context)
-    {
-        context->gatherParams<EntryPoint::GetInteger64v>(pname, data);
-
-        if (context->skipValidation() || ValidateGetInteger64v(context, pname, data))
-        {
-            context->getInteger64v(pname, data);
-        }
-    }
-}
-
-void GL_APIENTRY
-GetSynciv(GLsync sync, GLenum pname, GLsizei bufSize, GLsizei *length, GLint *values)
-{
-    EVENT(
-        "(GLsync sync = 0x%0.8p, GLenum pname = 0x%X, GLsizei bufSize = %d, GLsizei *length = "
-        "0x%0.8p, GLint *values = 0x%0.8p)",
-        sync, pname, bufSize, length, values);
-
-    Context *context = GetValidGlobalContext();
-    if (context)
-    {
-        context->gatherParams<EntryPoint::GetSynciv>(sync, pname, bufSize, length, values);
-
-        if (context->skipValidation() ||
-            ValidateGetSynciv(context, sync, pname, bufSize, length, values))
-        {
-            context->getSynciv(sync, pname, bufSize, length, values);
-        }
-    }
-}
-
-void GL_APIENTRY GetInteger64i_v(GLenum target, GLuint index, GLint64 *data)
-{
-    EVENT("(GLenum target = 0x%X, GLuint index = %u, GLint64 *data = 0x%0.8p)", target, index,
-          data);
-
-    Context *context = GetValidGlobalContext();
-    if (context)
-    {
-        context->gatherParams<EntryPoint::GetInteger64i_v>(target, index, data);
-
-        if (context->skipValidation() || ValidateGetInteger64i_v(context, target, index, data))
-        {
-            context->getInteger64i_v(target, index, data);
-        }
-    }
-}
-
-void GL_APIENTRY GetBufferParameteri64v(GLenum target, GLenum pname, GLint64 *params)
-{
-    EVENT("(GLenum target = 0x%X, GLenum pname = 0x%X, GLint64 *params = 0x%0.8p)", target, pname,
-          params);
-
-    Context *context = GetValidGlobalContext();
-    if (context)
-    {
-        context->gatherParams<EntryPoint::GetBufferParameteri64v>(target, pname, params);
-
-        if (context->skipValidation() ||
-            ValidateGetBufferParameteri64v(context, target, pname, params))
-        {
-            context->getBufferParameteri64v(target, pname, params);
-        }
-    }
-}
-
-void GL_APIENTRY GenSamplers(GLsizei count, GLuint *samplers)
-{
-    EVENT("(GLsizei count = %d, GLuint *samplers = 0x%0.8p)", count, samplers);
-
-    Context *context = GetValidGlobalContext();
-    if (context)
-    {
-        context->gatherParams<EntryPoint::GenSamplers>(count, samplers);
-
-        if (context->skipValidation() || ValidateGenSamplers(context, count, samplers))
-        {
-            context->genSamplers(count, samplers);
-        }
-    }
-}
-
-void GL_APIENTRY DeleteSamplers(GLsizei count, const GLuint *samplers)
-{
-    EVENT("(GLsizei count = %d, const GLuint *samplers = 0x%0.8p)", count, samplers);
-
-    Context *context = GetValidGlobalContext();
-    if (context)
-    {
-        context->gatherParams<EntryPoint::DeleteSamplers>(count, samplers);
-
-        if (context->skipValidation() || ValidateDeleteSamplers(context, count, samplers))
-        {
-            context->deleteSamplers(count, samplers);
-        }
-    }
-}
-
-GLboolean GL_APIENTRY IsSampler(GLuint sampler)
-{
-    EVENT("(GLuint sampler = %u)", sampler);
-
-    Context *context = GetValidGlobalContext();
-    if (context)
-    {
-        context->gatherParams<EntryPoint::IsSampler>(sampler);
-
-        if (context->skipValidation() || ValidateIsSampler(context, sampler))
-        {
-            return context->isSampler(sampler);
-        }
-    }
-
-    return GetDefaultReturnValue<EntryPoint::IsSampler, GLboolean>();
-}
-
-void GL_APIENTRY BindSampler(GLuint unit, GLuint sampler)
-{
-    EVENT("(GLuint unit = %u, GLuint sampler = %u)", unit, sampler);
-
-    Context *context = GetValidGlobalContext();
-    if (context)
-    {
-        context->gatherParams<EntryPoint::BindSampler>(unit, sampler);
-
-        if (context->skipValidation() || ValidateBindSampler(context, unit, sampler))
-        {
-            context->bindSampler(unit, sampler);
-        }
-    }
-}
-
-void GL_APIENTRY SamplerParameteri(GLuint sampler, GLenum pname, GLint param)
-{
-    EVENT("(GLuint sampler = %u, GLenum pname = 0x%X, GLint param = %d)", sampler, pname, param);
-
-    Context *context = GetValidGlobalContext();
-    if (context)
-    {
-        context->gatherParams<EntryPoint::SamplerParameteri>(sampler, pname, param);
-
-        if (context->skipValidation() || ValidateSamplerParameteri(context, sampler, pname, param))
-        {
-            context->samplerParameteri(sampler, pname, param);
-        }
-    }
-}
-
-void GL_APIENTRY SamplerParameteriv(GLuint sampler, GLenum pname, const GLint *param)
-{
-    EVENT("(GLuint sampler = %u, GLenum pname = 0x%X, const GLint *param = 0x%0.8p)", sampler,
-          pname, param);
-
-    Context *context = GetValidGlobalContext();
-    if (context)
-    {
-        context->gatherParams<EntryPoint::SamplerParameteriv>(sampler, pname, param);
-
-        if (context->skipValidation() || ValidateSamplerParameteriv(context, sampler, pname, param))
-        {
-            context->samplerParameteriv(sampler, pname, param);
-        }
-    }
-}
-
-void GL_APIENTRY SamplerParameterf(GLuint sampler, GLenum pname, GLfloat param)
-{
-    EVENT("(GLuint sampler = %u, GLenum pname = 0x%X, GLfloat param = %f)", sampler, pname, param);
-
-    Context *context = GetValidGlobalContext();
-    if (context)
-    {
-        context->gatherParams<EntryPoint::SamplerParameterf>(sampler, pname, param);
-
-        if (context->skipValidation() || ValidateSamplerParameterf(context, sampler, pname, param))
-        {
-            context->samplerParameterf(sampler, pname, param);
-        }
-    }
-}
-
-void GL_APIENTRY SamplerParameterfv(GLuint sampler, GLenum pname, const GLfloat *param)
-{
-    EVENT("(GLuint sampler = %u, GLenum pname = 0x%X, const GLfloat *param = 0x%0.8p)", sampler,
-          pname, param);
-
-    Context *context = GetValidGlobalContext();
-    if (context)
-    {
-        context->gatherParams<EntryPoint::SamplerParameterfv>(sampler, pname, param);
-
-        if (context->skipValidation() || ValidateSamplerParameterfv(context, sampler, pname, param))
-        {
-            context->samplerParameterfv(sampler, pname, param);
-        }
-    }
-}
-
-void GL_APIENTRY GetSamplerParameteriv(GLuint sampler, GLenum pname, GLint *params)
-{
-    EVENT("(GLuint sampler = %u, GLenum pname = 0x%X, GLint *params = 0x%0.8p)", sampler, pname,
-          params);
-
-    Context *context = GetValidGlobalContext();
-    if (context)
-    {
-        context->gatherParams<EntryPoint::GetSamplerParameteriv>(sampler, pname, params);
-
-        if (context->skipValidation() ||
-            ValidateGetSamplerParameteriv(context, sampler, pname, params))
-        {
-            context->getSamplerParameteriv(sampler, pname, params);
-        }
-    }
-}
-
-void GL_APIENTRY GetSamplerParameterfv(GLuint sampler, GLenum pname, GLfloat *params)
-{
-    EVENT("(GLuint sampler = %u, GLenum pname = 0x%X, GLfloat *params = 0x%0.8p)", sampler, pname,
-          params);
-
-    Context *context = GetValidGlobalContext();
-    if (context)
-    {
-        context->gatherParams<EntryPoint::GetSamplerParameterfv>(sampler, pname, params);
-
-        if (context->skipValidation() ||
-            ValidateGetSamplerParameterfv(context, sampler, pname, params))
-        {
-            context->getSamplerParameterfv(sampler, pname, params);
-        }
-    }
-}
-
-void GL_APIENTRY VertexAttribDivisor(GLuint index, GLuint divisor)
-{
-    EVENT("(GLuint index = %u, GLuint divisor = %u)", index, divisor);
-
-    Context *context = GetValidGlobalContext();
-    if (context)
-    {
-        context->gatherParams<EntryPoint::VertexAttribDivisor>(index, divisor);
-
-        if (context->skipValidation() || ValidateVertexAttribDivisor(context, index, divisor))
-        {
-            context->vertexAttribDivisor(index, divisor);
-        }
-    }
-}
-
-void GL_APIENTRY BindTransformFeedback(GLenum target, GLuint id)
-{
-    EVENT("(GLenum target = 0x%X, GLuint id = %u)", target, id);
-
-    Context *context = GetValidGlobalContext();
-    if (context)
-    {
-        context->gatherParams<EntryPoint::BindTransformFeedback>(target, id);
-
-        if (context->skipValidation() || ValidateBindTransformFeedback(context, target, id))
-        {
-            context->bindTransformFeedback(target, id);
-        }
-    }
-}
-
-void GL_APIENTRY DeleteTransformFeedbacks(GLsizei n, const GLuint *ids)
-{
-    EVENT("(GLsizei n = %d, const GLuint *ids = 0x%0.8p)", n, ids);
-
-    Context *context = GetValidGlobalContext();
-    if (context)
-    {
-        context->gatherParams<EntryPoint::DeleteTransformFeedbacks>(n, ids);
-
-        if (context->skipValidation() || ValidateDeleteTransformFeedbacks(context, n, ids))
-        {
-            context->deleteTransformFeedbacks(n, ids);
-        }
-    }
-}
-
-void GL_APIENTRY GenTransformFeedbacks(GLsizei n, GLuint *ids)
-{
-    EVENT("(GLsizei n = %d, GLuint *ids = 0x%0.8p)", n, ids);
-
-    Context *context = GetValidGlobalContext();
-    if (context)
-    {
-        context->gatherParams<EntryPoint::GenTransformFeedbacks>(n, ids);
-
-        if (context->skipValidation() || ValidateGenTransformFeedbacks(context, n, ids))
-        {
-            context->genTransformFeedbacks(n, ids);
-        }
-    }
-}
-
-GLboolean GL_APIENTRY IsTransformFeedback(GLuint id)
-{
-    EVENT("(GLuint id = %u)", id);
-
-    Context *context = GetValidGlobalContext();
-    if (context)
-    {
-        context->gatherParams<EntryPoint::IsTransformFeedback>(id);
-
-        if (context->skipValidation() || ValidateIsTransformFeedback(context, id))
-        {
-            return context->isTransformFeedback(id);
-        }
-    }
-
-    return GetDefaultReturnValue<EntryPoint::IsTransformFeedback, GLboolean>();
-}
-
-void GL_APIENTRY PauseTransformFeedback()
-{
-    EVENT("()");
-
-    Context *context = GetValidGlobalContext();
-    if (context)
-    {
-        context->gatherParams<EntryPoint::PauseTransformFeedback>();
-
-        if (context->skipValidation() || ValidatePauseTransformFeedback(context))
-        {
-            context->pauseTransformFeedback();
-        }
-    }
-}
-
-void GL_APIENTRY ResumeTransformFeedback()
-{
-    EVENT("()");
-
-    Context *context = GetValidGlobalContext();
-    if (context)
-    {
-        context->gatherParams<EntryPoint::ResumeTransformFeedback>();
-
-        if (context->skipValidation() || ValidateResumeTransformFeedback(context))
-        {
-            context->resumeTransformFeedback();
-        }
-    }
-}
-
-void GL_APIENTRY GetProgramBinary(GLuint program,
-                                  GLsizei bufSize,
-                                  GLsizei *length,
-                                  GLenum *binaryFormat,
-                                  void *binary)
-{
-    EVENT(
-        "(GLuint program = %u, GLsizei bufSize = %d, GLsizei *length = 0x%0.8p, GLenum "
-        "*binaryFormat = 0x%0.8p, void *binary = 0x%0.8p)",
-        program, bufSize, length, binaryFormat, binary);
-
-    Context *context = GetValidGlobalContext();
-    if (context)
-    {
-        context->gatherParams<EntryPoint::GetProgramBinary>(program, bufSize, length, binaryFormat,
-                                                            binary);
-
-        if (context->skipValidation() ||
-            ValidateGetProgramBinary(context, program, bufSize, length, binaryFormat, binary))
-        {
-            context->getProgramBinary(program, bufSize, length, binaryFormat, binary);
-        }
-    }
-}
-
-void GL_APIENTRY ProgramBinary(GLuint program,
-                               GLenum binaryFormat,
-                               const void *binary,
-                               GLsizei length)
-{
-    EVENT(
-        "(GLuint program = %u, GLenum binaryFormat = 0x%X, const void *binary = 0x%0.8p, GLsizei "
-        "length = %d)",
-        program, binaryFormat, binary, length);
-
-    Context *context = GetValidGlobalContext();
-    if (context)
-    {
-        context->gatherParams<EntryPoint::ProgramBinary>(program, binaryFormat, binary, length);
-
-        if (context->skipValidation() ||
-            ValidateProgramBinary(context, program, binaryFormat, binary, length))
-        {
-            context->programBinary(program, binaryFormat, binary, length);
-        }
-    }
-}
-
-void GL_APIENTRY ProgramParameteri(GLuint program, GLenum pname, GLint value)
-{
-    EVENT("(GLuint program = %u, GLenum pname = 0x%X, GLint value = %d)", program, pname, value);
-
-    Context *context = GetValidGlobalContext();
-    if (context)
-    {
-        context->gatherParams<EntryPoint::ProgramParameteri>(program, pname, value);
-
-        if (context->skipValidation() || ValidateProgramParameteri(context, program, pname, value))
-        {
-            context->programParameteri(program, pname, value);
-        }
-    }
-}
-
 void GL_APIENTRY InvalidateFramebuffer(GLenum target,
                                        GLsizei numAttachments,
                                        const GLenum *attachments)
 {
     EVENT(
         "(GLenum target = 0x%X, GLsizei numAttachments = %d, const GLenum *attachments = 0x%0.8p)",
         target, numAttachments, attachments);
 
@@ -1990,16 +1211,344 @@ void GL_APIENTRY InvalidateSubFramebuffe
                                              width, height))
         {
             context->invalidateSubFramebuffer(target, numAttachments, attachments, x, y, width,
                                               height);
         }
     }
 }
 
+GLboolean GL_APIENTRY IsQuery(GLuint id)
+{
+    EVENT("(GLuint id = %u)", id);
+
+    Context *context = GetValidGlobalContext();
+    if (context)
+    {
+        context->gatherParams<EntryPoint::IsQuery>(id);
+
+        if (context->skipValidation() || ValidateIsQuery(context, id))
+        {
+            return context->isQuery(id);
+        }
+    }
+
+    return GetDefaultReturnValue<EntryPoint::IsQuery, GLboolean>();
+}
+
+GLboolean GL_APIENTRY IsSampler(GLuint sampler)
+{
+    EVENT("(GLuint sampler = %u)", sampler);
+
+    Context *context = GetValidGlobalContext();
+    if (context)
+    {
+        context->gatherParams<EntryPoint::IsSampler>(sampler);
+
+        if (context->skipValidation() || ValidateIsSampler(context, sampler))
+        {
+            return context->isSampler(sampler);
+        }
+    }
+
+    return GetDefaultReturnValue<EntryPoint::IsSampler, GLboolean>();
+}
+
+GLboolean GL_APIENTRY IsSync(GLsync sync)
+{
+    EVENT("(GLsync sync = 0x%0.8p)", sync);
+
+    Context *context = GetValidGlobalContext();
+    if (context)
+    {
+        context->gatherParams<EntryPoint::IsSync>(sync);
+
+        if (context->skipValidation() || ValidateIsSync(context, sync))
+        {
+            return context->isSync(sync);
+        }
+    }
+
+    return GetDefaultReturnValue<EntryPoint::IsSync, GLboolean>();
+}
+
+GLboolean GL_APIENTRY IsTransformFeedback(GLuint id)
+{
+    EVENT("(GLuint id = %u)", id);
+
+    Context *context = GetValidGlobalContext();
+    if (context)
+    {
+        context->gatherParams<EntryPoint::IsTransformFeedback>(id);
+
+        if (context->skipValidation() || ValidateIsTransformFeedback(context, id))
+        {
+            return context->isTransformFeedback(id);
+        }
+    }
+
+    return GetDefaultReturnValue<EntryPoint::IsTransformFeedback, GLboolean>();
+}
+
+GLboolean GL_APIENTRY IsVertexArray(GLuint array)
+{
+    EVENT("(GLuint array = %u)", array);
+
+    Context *context = GetValidGlobalContext();
+    if (context)
+    {
+        context->gatherParams<EntryPoint::IsVertexArray>(array);
+
+        if (context->skipValidation() || ValidateIsVertexArray(context, array))
+        {
+            return context->isVertexArray(array);
+        }
+    }
+
+    return GetDefaultReturnValue<EntryPoint::IsVertexArray, GLboolean>();
+}
+
+void *GL_APIENTRY MapBufferRange(GLenum target,
+                                 GLintptr offset,
+                                 GLsizeiptr length,
+                                 GLbitfield access)
+{
+    EVENT(
+        "(GLenum target = 0x%X, GLintptr offset = %d, GLsizeiptr length = %d, GLbitfield access = "
+        "0x%X)",
+        target, offset, length, access);
+
+    Context *context = GetValidGlobalContext();
+    if (context)
+    {
+        BufferBinding targetPacked = FromGLenum<BufferBinding>(target);
+        context->gatherParams<EntryPoint::MapBufferRange>(targetPacked, offset, length, access);
+
+        if (context->skipValidation() ||
+            ValidateMapBufferRange(context, targetPacked, offset, length, access))
+        {
+            return context->mapBufferRange(targetPacked, offset, length, access);
+        }
+    }
+
+    return GetDefaultReturnValue<EntryPoint::MapBufferRange, void *>();
+}
+
+void GL_APIENTRY PauseTransformFeedback()
+{
+    EVENT("()");
+
+    Context *context = GetValidGlobalContext();
+    if (context)
+    {
+        context->gatherParams<EntryPoint::PauseTransformFeedback>();
+
+        if (context->skipValidation() || ValidatePauseTransformFeedback(context))
+        {
+            context->pauseTransformFeedback();
+        }
+    }
+}
+
+void GL_APIENTRY ProgramBinary(GLuint program,
+                               GLenum binaryFormat,
+                               const void *binary,
+                               GLsizei length)
+{
+    EVENT(
+        "(GLuint program = %u, GLenum binaryFormat = 0x%X, const void *binary = 0x%0.8p, GLsizei "
+        "length = %d)",
+        program, binaryFormat, binary, length);
+
+    Context *context = GetValidGlobalContext();
+    if (context)
+    {
+        context->gatherParams<EntryPoint::ProgramBinary>(program, binaryFormat, binary, length);
+
+        if (context->skipValidation() ||
+            ValidateProgramBinary(context, program, binaryFormat, binary, length))
+        {
+            context->programBinary(program, binaryFormat, binary, length);
+        }
+    }
+}
+
+void GL_APIENTRY ProgramParameteri(GLuint program, GLenum pname, GLint value)
+{
+    EVENT("(GLuint program = %u, GLenum pname = 0x%X, GLint value = %d)", program, pname, value);
+
+    Context *context = GetValidGlobalContext();
+    if (context)
+    {
+        context->gatherParams<EntryPoint::ProgramParameteri>(program, pname, value);
+
+        if (context->skipValidation() || ValidateProgramParameteri(context, program, pname, value))
+        {
+            context->programParameteri(program, pname, value);
+        }
+    }
+}
+
+void GL_APIENTRY ReadBuffer(GLenum src)
+{
+    EVENT("(GLenum src = 0x%X)", src);
+
+    Context *context = GetValidGlobalContext();
+    if (context)
+    {
+        context->gatherParams<EntryPoint::ReadBuffer>(src);
+
+        if (context->skipValidation() || ValidateReadBuffer(context, src))
+        {
+            context->readBuffer(src);
+        }
+    }
+}
+
+void GL_APIENTRY RenderbufferStorageMultisample(GLenum target,
+                                                GLsizei samples,
+                                                GLenum internalformat,
+                                                GLsizei width,
+                                                GLsizei height)
+{
+    EVENT(
+        "(GLenum target = 0x%X, GLsizei samples = %d, GLenum internalformat = 0x%X, GLsizei width "
+        "= %d, GLsizei height = %d)",
+        target, samples, internalformat, width, height);
+
+    Context *context = GetValidGlobalContext();
+    if (context)
+    {
+        context->gatherParams<EntryPoint::RenderbufferStorageMultisample>(
+            target, samples, internalformat, width, height);
+
+        if (context->skipValidation() ||
+            ValidateRenderbufferStorageMultisample(context, target, samples, internalformat, width,
+                                                   height))
+        {
+            context->renderbufferStorageMultisample(target, samples, internalformat, width, height);
+        }
+    }
+}
+
+void GL_APIENTRY ResumeTransformFeedback()
+{
+    EVENT("()");
+
+    Context *context = GetValidGlobalContext();
+    if (context)
+    {
+        context->gatherParams<EntryPoint::ResumeTransformFeedback>();
+
+        if (context->skipValidation() || ValidateResumeTransformFeedback(context))
+        {
+            context->resumeTransformFeedback();
+        }
+    }
+}
+
+void GL_APIENTRY SamplerParameterf(GLuint sampler, GLenum pname, GLfloat param)
+{
+    EVENT("(GLuint sampler = %u, GLenum pname = 0x%X, GLfloat param = %f)", sampler, pname, param);
+
+    Context *context = GetValidGlobalContext();
+    if (context)
+    {
+        context->gatherParams<EntryPoint::SamplerParameterf>(sampler, pname, param);
+
+        if (context->skipValidation() || ValidateSamplerParameterf(context, sampler, pname, param))
+        {
+            context->samplerParameterf(sampler, pname, param);
+        }
+    }
+}
+
+void GL_APIENTRY SamplerParameterfv(GLuint sampler, GLenum pname, const GLfloat *param)
+{
+    EVENT("(GLuint sampler = %u, GLenum pname = 0x%X, const GLfloat *param = 0x%0.8p)", sampler,
+          pname, param);
+
+    Context *context = GetValidGlobalContext();
+    if (context)
+    {
+        context->gatherParams<EntryPoint::SamplerParameterfv>(sampler, pname, param);
+
+        if (context->skipValidation() || ValidateSamplerParameterfv(context, sampler, pname, param))
+        {
+            context->samplerParameterfv(sampler, pname, param);
+        }
+    }
+}
+
+void GL_APIENTRY SamplerParameteri(GLuint sampler, GLenum pname, GLint param)
+{
+    EVENT("(GLuint sampler = %u, GLenum pname = 0x%X, GLint param = %d)", sampler, pname, param);
+
+    Context *context = GetValidGlobalContext();
+    if (context)
+    {
+        context->gatherParams<EntryPoint::SamplerParameteri>(sampler, pname, param);
+
+        if (context->skipValidation() || ValidateSamplerParameteri(context, sampler, pname, param))
+        {
+            context->samplerParameteri(sampler, pname, param);
+        }
+    }
+}
+
+void GL_APIENTRY SamplerParameteriv(GLuint sampler, GLenum pname, const GLint *param)
+{
+    EVENT("(GLuint sampler = %u, GLenum pname = 0x%X, const GLint *param = 0x%0.8p)", sampler,
+          pname, param);
+
+    Context *context = GetValidGlobalContext();
+    if (context)
+    {
+        context->gatherParams<EntryPoint::SamplerParameteriv>(sampler, pname, param);
+
+        if (context->skipValidation() || ValidateSamplerParameteriv(context, sampler, pname, param))
+        {
+            context->samplerParameteriv(sampler, pname, param);
+        }
+    }
+}
+
+void GL_APIENTRY TexImage3D(GLenum target,
+                            GLint level,
+                            GLint internalformat,
+                            GLsizei width,
+                            GLsizei height,
+                            GLsizei depth,
+                            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, 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);
+
+        if (context->skipValidation() ||
+            ValidateTexImage3D(context, target, level, internalformat, width, height, depth, border,
+                               format, type, pixels))
+        {
+            context->texImage3D(target, 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);
 
@@ -2038,33 +1587,498 @@ void GL_APIENTRY TexStorage3D(GLenum tar
         if (context->skipValidation() ||
             ValidateTexStorage3D(context, target, levels, internalformat, width, height, depth))
         {
             context->texStorage3D(target, levels, internalformat, width, height, depth);
         }
     }
 }
 
-void GL_APIENTRY GetInternalformativ(GLenum target,
-                                     GLenum internalformat,
-                                     GLenum pname,
-                                     GLsizei bufSize,
-                                     GLint *params)
+void GL_APIENTRY TexSubImage3D(GLenum target,
+                               GLint level,
+                               GLint xoffset,
+                               GLint yoffset,
+                               GLint zoffset,
+                               GLsizei width,
+                               GLsizei height,
+                               GLsizei depth,
+                               GLenum format,
+                               GLenum type,
+                               const void *pixels)
+{
+    EVENT(
+        "(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);
+
+        if (context->skipValidation() ||
+            ValidateTexSubImage3D(context, target, level, xoffset, yoffset, zoffset, width, height,
+                                  depth, format, type, pixels))
+        {
+            context->texSubImage3D(target, level, xoffset, yoffset, zoffset, width, height, depth,
+                                   format, type, pixels);
+        }
+    }
+}
+
+void GL_APIENTRY TransformFeedbackVaryings(GLuint program,
+                                           GLsizei count,
+                                           const GLchar *const *varyings,
+                                           GLenum bufferMode)
 {
     EVENT(
-        "(GLenum target = 0x%X, GLenum internalformat = 0x%X, GLenum pname = 0x%X, GLsizei bufSize "
-        "= %d, GLint *params = 0x%0.8p)",
-        target, internalformat, pname, bufSize, params);
+        "(GLuint program = %u, GLsizei count = %d, const GLchar *const*varyings = 0x%0.8p, GLenum "
+        "bufferMode = 0x%X)",
+        program, count, varyings, bufferMode);
+
+    Context *context = GetValidGlobalContext();
+    if (context)
+    {
+        context->gatherParams<EntryPoint::TransformFeedbackVaryings>(program, count, varyings,
+                                                                     bufferMode);
+
+        if (context->skipValidation() ||
+            ValidateTransformFeedbackVaryings(context, program, count, varyings, bufferMode))
+        {
+            context->transformFeedbackVaryings(program, count, varyings, bufferMode);
+        }
+    }
+}
+
+void GL_APIENTRY Uniform1ui(GLint location, GLuint v0)
+{
+    EVENT("(GLint location = %d, GLuint v0 = %u)", location, v0);
+
+    Context *context = GetValidGlobalContext();
+    if (context)
+    {
+        context->gatherParams<EntryPoint::Uniform1ui>(location, v0);
+
+        if (context->skipValidation() || ValidateUniform1ui(context, location, v0))
+        {
+            context->uniform1ui(location, v0);
+        }
+    }
+}
+
+void GL_APIENTRY Uniform1uiv(GLint location, GLsizei count, const GLuint *value)
+{
+    EVENT("(GLint location = %d, GLsizei count = %d, const GLuint *value = 0x%0.8p)", location,
+          count, value);
+
+    Context *context = GetValidGlobalContext();
+    if (context)
+    {
+        context->gatherParams<EntryPoint::Uniform1uiv>(location, count, value);
+
+        if (context->skipValidation() || ValidateUniform1uiv(context, location, count, value))
+        {
+            context->uniform1uiv(location, count, value);
+        }
+    }
+}
+
+void GL_APIENTRY Uniform2ui(GLint location, GLuint v0, GLuint v1)
+{
+    EVENT("(GLint location = %d, GLuint v0 = %u, GLuint v1 = %u)", location, v0, v1);
+
+    Context *context = GetValidGlobalContext();
+    if (context)
+    {
+        context->gatherParams<EntryPoint::Uniform2ui>(location, v0, v1);
+
+        if (context->skipValidation() || ValidateUniform2ui(context, location, v0, v1))
+        {
+            context->uniform2ui(location, v0, v1);
+        }
+    }
+}
+
+void GL_APIENTRY Uniform2uiv(GLint location, GLsizei count, const GLuint *value)
+{
+    EVENT("(GLint location = %d, GLsizei count = %d, const GLuint *value = 0x%0.8p)", location,
+          count, value);
+
+    Context *context = GetValidGlobalContext();
+    if (context)
+    {
+        context->gatherParams<EntryPoint::Uniform2uiv>(location, count, value);
+
+        if (context->skipValidation() || ValidateUniform2uiv(context, location, count, value))
+        {
+            context->uniform2uiv(location, count, value);
+        }
+    }
+}
+
+void GL_APIENTRY Uniform3ui(GLint location, GLuint v0, GLuint v1, GLuint v2)
+{
+    EVENT("(GLint location = %d, GLuint v0 = %u, GLuint v1 = %u, GLuint v2 = %u)", location, v0, v1,
+          v2);
+
+    Context *context = GetValidGlobalContext();
+    if (context)
+    {
+        context->gatherParams<EntryPoint::Uniform3ui>(location, v0, v1, v2);
+
+        if (context->skipValidation() || ValidateUniform3ui(context, location, v0, v1, v2))
+        {
+            context->uniform3ui(location, v0, v1, v2);
+        }
+    }
+}
+
+void GL_APIENTRY Uniform3uiv(GLint location, GLsizei count, const GLuint *value)
+{
+    EVENT("(GLint location = %d, GLsizei count = %d, const GLuint *value = 0x%0.8p)", location,
+          count, value);
+
+    Context *context = GetValidGlobalContext();
+    if (context)
+    {
+        context->gatherParams<EntryPoint::Uniform3uiv>(location, count, value);
+
+        if (context->skipValidation() || ValidateUniform3uiv(context, location, count, value))
+        {
+            context->uniform3uiv(location, count, value);
+        }
+    }
+}
+
+void GL_APIENTRY Uniform4ui(GLint location, GLuint v0, GLuint v1, GLuint v2, GLuint v3)
+{
+    EVENT("(GLint location = %d, GLuint v0 = %u, GLuint v1 = %u, GLuint v2 = %u, GLuint v3 = %u)",
+          location, v0, v1, v2, v3);
+
+    Context *context = GetValidGlobalContext();
+    if (context)
+    {
+        context->gatherParams<EntryPoint::Uniform4ui>(location, v0, v1, v2, v3);
+
+        if (context->skipValidation() || ValidateUniform4ui(context, location, v0, v1, v2, v3))
+        {
+            context->uniform4ui(location, v0, v1, v2, v3);
+        }
+    }
+}
+
+void GL_APIENTRY Uniform4uiv(GLint location, GLsizei count, const GLuint *value)
+{
+    EVENT("(GLint location = %d, GLsizei count = %d, const GLuint *value = 0x%0.8p)", location,
+          count, value);
+
+    Context *context = GetValidGlobalContext();
+    if (context)
+    {
+        context->gatherParams<EntryPoint::Uniform4uiv>(location, count, value);
+
+        if (context->skipValidation() || ValidateUniform4uiv(context, location, count, value))
+        {
+            context->uniform4uiv(location, count, value);
+        }
+    }
+}
+
+void GL_APIENTRY UniformBlockBinding(GLuint program,
+                                     GLuint uniformBlockIndex,
+                                     GLuint uniformBlockBinding)
+{
+    EVENT("(GLuint program = %u, GLuint uniformBlockIndex = %u, GLuint uniformBlockBinding = %u)",
+          program, uniformBlockIndex, uniformBlockBinding);
+
+    Context *context = GetValidGlobalContext();
+    if (context)
+    {
+        context->gatherParams<EntryPoint::UniformBlockBinding>(program, uniformBlockIndex,
+                                                               uniformBlockBinding);
+
+        if (context->skipValidation() ||
+            ValidateUniformBlockBinding(context, program, uniformBlockIndex, uniformBlockBinding))
+        {
+            context->uniformBlockBinding(program, uniformBlockIndex, uniformBlockBinding);
+        }
+    }
+}
+
+void GL_APIENTRY UniformMatrix2x3fv(GLint location,
+                                    GLsizei count,
+                                    GLboolean transpose,
+                                    const GLfloat *value)
+{
+    EVENT(
+        "(GLint location = %d, GLsizei count = %d, GLboolean transpose = %u, const GLfloat *value "
+        "= 0x%0.8p)",
+        location, count, transpose, value);
 
     Context *context = GetValidGlobalContext();
     if (context)
     {
-        context->gatherParams<EntryPoint::GetInternalformativ>(target, internalformat, pname,
-                                                               bufSize, params);
+        context->gatherParams<EntryPoint::UniformMatrix2x3fv>(location, count, transpose, value);
+
+        if (context->skipValidation() ||
+            ValidateUniformMatrix2x3fv(context, location, count, transpose, value))
+        {
+            context->uniformMatrix2x3fv(location, count, transpose, value);
+        }
+    }
+}
+
+void GL_APIENTRY UniformMatrix2x4fv(GLint location,
+                                    GLsizei count,
+                                    GLboolean transpose,
+                                    const GLfloat *value)
+{
+    EVENT(
+        "(GLint location = %d, GLsizei count = %d, GLboolean transpose = %u, const GLfloat *value "
+        "= 0x%0.8p)",
+        location, count, transpose, value);
+
+    Context *context = GetValidGlobalContext();
+    if (context)
+    {
+        context->gatherParams<EntryPoint::UniformMatrix2x4fv>(location, count, transpose, value);
+
+        if (context->skipValidation() ||
+            ValidateUniformMatrix2x4fv(context, location, count, transpose, value))
+        {
+            context->uniformMatrix2x4fv(location, count, transpose, value);
+        }
+    }
+}
+
+void GL_APIENTRY UniformMatrix3x2fv(GLint location,
+                                    GLsizei count,
+                                    GLboolean transpose,
+                                    const GLfloat *value)
+{
+    EVENT(
+        "(GLint location = %d, GLsizei count = %d, GLboolean transpose = %u, const GLfloat *value "
+        "= 0x%0.8p)",
+        location, count, transpose, value);
+
+    Context *context = GetValidGlobalContext();
+    if (context)
+    {
+        context->gatherParams<EntryPoint::UniformMatrix3x2fv>(location, count, transpose, value);
+
+        if (context->skipValidation() ||
+            ValidateUniformMatrix3x2fv(context, location, count, transpose, value))
+        {
+            context->uniformMatrix3x2fv(location, count, transpose, value);
+        }
+    }
+}
+
+void GL_APIENTRY UniformMatrix3x4fv(GLint location,
+                                    GLsizei count,
+                                    GLboolean transpose,
+                                    const GLfloat *value)
+{
+    EVENT(
+        "(GLint location = %d, GLsizei count = %d, GLboolean transpose = %u, const GLfloat *value "
+        "= 0x%0.8p)",
+        location, count, transpose, value);
+
+    Context *context = GetValidGlobalContext();
+    if (context)
+    {
+        context->gatherParams<EntryPoint::UniformMatrix3x4fv>(location, count, transpose, value);
+
+        if (context->skipValidation() ||
+            ValidateUniformMatrix3x4fv(context, location, count, transpose, value))
+        {
+            context->uniformMatrix3x4fv(location, count, transpose, value);
+        }
+    }
+}
+
+void GL_APIENTRY UniformMatrix4x2fv(GLint location,
+                                    GLsizei count,
+                                    GLboolean transpose,
+                                    const GLfloat *value)
+{
+    EVENT(
+        "(GLint location = %d, GLsizei count = %d, GLboolean transpose = %u, const GLfloat *value "
+        "= 0x%0.8p)",
+        location, count, transpose, value);
+
+    Context *context = GetValidGlobalContext();
+    if (context)
+    {
+        context->gatherParams<EntryPoint::UniformMatrix4x2fv>(location, count, transpose, value);
+
+        if (context->skipValidation() ||
+            ValidateUniformMatrix4x2fv(context, location, count, transpose, value))
+        {
+            context->uniformMatrix4x2fv(location, count, transpose, value);
+        }
+    }
+}
+
+void GL_APIENTRY UniformMatrix4x3fv(GLint location,
+                                    GLsizei count,
+                                    GLboolean transpose,
+                                    const GLfloat *value)
+{
+    EVENT(
+        "(GLint location = %d, GLsizei count = %d, GLboolean transpose = %u, const GLfloat *value "
+        "= 0x%0.8p)",
+        location, count, transpose, value);
+
+    Context *context = GetValidGlobalContext();
+    if (context)
+    {
+        context->gatherParams<EntryPoint::UniformMatrix4x3fv>(location, count, transpose, value);
 
         if (context->skipValidation() ||
-            ValidateGetInternalformativ(context, target, internalformat, pname, bufSize, params))
+            ValidateUniformMatrix4x3fv(context, location, count, transpose, value))
+        {
+            context->uniformMatrix4x3fv(location, count, transpose, value);
+        }
+    }
+}
+
+GLboolean GL_APIENTRY UnmapBuffer(GLenum target)
+{
+    EVENT("(GLenum target = 0x%X)", target);
+
+    Context *context = GetValidGlobalContext();
+    if (context)
+    {
+        BufferBinding targetPacked = FromGLenum<BufferBinding>(target);
+        context->gatherParams<EntryPoint::UnmapBuffer>(targetPacked);
+
+        if (context->skipValidation() || ValidateUnmapBuffer(context, targetPacked))
+        {
+            return context->unmapBuffer(targetPacked);
+        }
+    }
+
+    return GetDefaultReturnValue<EntryPoint::UnmapBuffer, GLboolean>();
+}
+
+void GL_APIENTRY VertexAttribDivisor(GLuint index, GLuint divisor)
+{
+    EVENT("(GLuint index = %u, GLuint divisor = %u)", index, divisor);
+
+    Context *context = GetValidGlobalContext();
+    if (context)
+    {
+        context->gatherParams<EntryPoint::VertexAttribDivisor>(index, divisor);
+
+        if (context->skipValidation() || ValidateVertexAttribDivisor(context, index, divisor))
+        {
+            context->vertexAttribDivisor(index, divisor);
+        }
+    }
+}
+
+void GL_APIENTRY VertexAttribI4i(GLuint index, GLint x, GLint y, GLint z, GLint w)
+{
+    EVENT("(GLuint index = %u, GLint x = %d, GLint y = %d, GLint z = %d, GLint w = %d)", index, x,
+          y, z, w);
+
+    Context *context = GetValidGlobalContext();
+    if (context)
+    {
+        context->gatherParams<EntryPoint::VertexAttribI4i>(index, x, y, z, w);
+
+        if (context->skipValidation() || ValidateVertexAttribI4i(context, index, x, y, z, w))
+        {
+            context->vertexAttribI4i(index, x, y, z, w);
+        }
+    }
+}
+
+void GL_APIENTRY VertexAttribI4iv(GLuint index, const GLint *v)
+{
+    EVENT("(GLuint index = %u, const GLint *v = 0x%0.8p)", index, v);
+
+    Context *context = GetValidGlobalContext();
+    if (context)
+    {
+        context->gatherParams<EntryPoint::VertexAttribI4iv>(index, v);
+
+        if (context->skipValidation() || ValidateVertexAttribI4iv(context, index, v))
         {
-            context->getInternalformativ(target, internalformat, pname, bufSize, params);
+            context->vertexAttribI4iv(index, v);
+        }
+    }
+}
+
+void GL_APIENTRY VertexAttribI4ui(GLuint index, GLuint x, GLuint y, GLuint z, GLuint w)
+{
+    EVENT("(GLuint index = %u, GLuint x = %u, GLuint y = %u, GLuint z = %u, GLuint w = %u)", index,
+          x, y, z, w);
+
+    Context *context = GetValidGlobalContext();
+    if (context)
+    {
+        context->gatherParams<EntryPoint::VertexAttribI4ui>(index, x, y, z, w);
+
+        if (context->skipValidation() || ValidateVertexAttribI4ui(context, index, x, y, z, w))
+        {
+            context->vertexAttribI4ui(index, x, y, z, w);
+        }
+    }
+}
+
+void GL_APIENTRY VertexAttribI4uiv(GLuint index, const GLuint *v)
+{
+    EVENT("(GLuint index = %u, const GLuint *v = 0x%0.8p)", index, v);
+
+    Context *context = GetValidGlobalContext();
+    if (context)
+    {
+        context->gatherParams<EntryPoint::VertexAttribI4uiv>(index, v);
+
+        if (context->skipValidation() || ValidateVertexAttribI4uiv(context, index, v))
+        {
+            context->vertexAttribI4uiv(index, v);
+        }
+    }
+}
+
+void GL_APIENTRY
+VertexAttribIPointer(GLuint index, GLint size, GLenum type, GLsizei stride, const void *pointer)
+{
+    EVENT(
+        "(GLuint index = %u, GLint size = %d, GLenum type = 0x%X, GLsizei stride = %d, const void "
+        "*pointer = 0x%0.8p)",
+        index, size, type, stride, pointer);
+
+    Context *context = GetValidGlobalContext();
+    if (context)
+    {
+        context->gatherParams<EntryPoint::VertexAttribIPointer>(index, size, type, stride, pointer);
+
+        if (context->skipValidation() ||
+            ValidateVertexAttribIPointer(context, index, size, type, stride, pointer))
+        {
+            context->vertexAttribIPointer(index, size, type, stride, pointer);
+        }
+    }
+}
+
+void GL_APIENTRY WaitSync(GLsync sync, GLbitfield flags, GLuint64 timeout)
+{
+    EVENT("(GLsync sync = 0x%0.8p, GLbitfield flags = 0x%X, GLuint64 timeout = %llu)", sync, flags,
+          timeout);
+
+    Context *context = GetValidGlobalContext();
+    if (context)
+    {
+        context->gatherParams<EntryPoint::WaitSync>(sync, flags, timeout);
+
+        if (context->skipValidation() || ValidateWaitSync(context, sync, flags, timeout))
+        {
+            context->waitSync(sync, flags, timeout);
         }
     }
 }
 }  // namespace gl
--- a/gfx/angle/src/libGLESv2/entry_points_gles_3_0_autogen.h
+++ b/gfx/angle/src/libGLESv2/entry_points_gles_3_0_autogen.h
@@ -1,63 +1,52 @@
 // GENERATED FILE - DO NOT EDIT.
 // Generated by generate_entry_points.py using data from gl.xml.
 //
-// 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.
 //
 // entry_points_gles_3_0_autogen.h:
 //   Defines the GLES 3.0 entry points.
 
-#ifndef LIBGLESV2_ENTRYPOINTSGLES30_AUTOGEN_H_
-#define LIBGLESV2_ENTRYPOINTSGLES30_AUTOGEN_H_
+#ifndef LIBGLESV2_ENTRY_POINTS_GLES_3_0_AUTOGEN_H_
+#define LIBGLESV2_ENTRY_POINTS_GLES_3_0_AUTOGEN_H_
 
 #include <GLES3/gl3.h>
 #include <export.h>
 
 namespace gl
 {
-ANGLE_EXPORT void GL_APIENTRY ReadBuffer(GLenum src);
-ANGLE_EXPORT void GL_APIENTRY DrawRangeElements(GLenum mode,
-                                                GLuint start,
-                                                GLuint end,
-                                                GLsizei count,
-                                                GLenum type,
-                                                const void *indices);
-ANGLE_EXPORT void GL_APIENTRY TexImage3D(GLenum target,
-                                         GLint level,
-                                         GLint internalformat,
-                                         GLsizei width,
-                                         GLsizei height,
-                                         GLsizei depth,
-                                         GLint border,
-                                         GLenum format,
-                                         GLenum type,
-                                         const void *pixels);
-ANGLE_EXPORT void GL_APIENTRY TexSubImage3D(GLenum target,
-                                            GLint level,
-                                            GLint xoffset,
-                                            GLint yoffset,
-                                            GLint zoffset,
-                                            GLsizei width,
-                                            GLsizei height,
-                                            GLsizei depth,
-                                            GLenum format,
-                                            GLenum type,
-                                            const void *pixels);
-ANGLE_EXPORT void GL_APIENTRY CopyTexSubImage3D(GLenum target,
-                                                GLint level,
-                                                GLint xoffset,
-                                                GLint yoffset,
-                                                GLint zoffset,
-                                                GLint x,
-                                                GLint y,
-                                                GLsizei width,
-                                                GLsizei height);
+ANGLE_EXPORT void GL_APIENTRY BeginQuery(GLenum target, GLuint id);
+ANGLE_EXPORT void GL_APIENTRY BeginTransformFeedback(GLenum primitiveMode);
+ANGLE_EXPORT void GL_APIENTRY BindBufferBase(GLenum target, GLuint index, GLuint buffer);
+ANGLE_EXPORT void GL_APIENTRY
+BindBufferRange(GLenum target, GLuint index, GLuint buffer, GLintptr offset, GLsizeiptr size);
+ANGLE_EXPORT void GL_APIENTRY BindSampler(GLuint unit, GLuint sampler);
+ANGLE_EXPORT void GL_APIENTRY BindTransformFeedback(GLenum target, GLuint id);
+ANGLE_EXPORT void GL_APIENTRY BindVertexArray(GLuint array);
+ANGLE_EXPORT void GL_APIENTRY BlitFramebuffer(GLint srcX0,
+                                              GLint srcY0,
+                                              GLint srcX1,
+                                              GLint srcY1,
+                                              GLint dstX0,
+                                              GLint dstY0,
+                                              GLint dstX1,
+                                              GLint dstY1,
+                                              GLbitfield mask,
+                                              GLenum filter);
+ANGLE_EXPORT void GL_APIENTRY ClearBufferfi(GLenum buffer,
+                                            GLint drawbuffer,
+                                            GLfloat depth,
+                                            GLint stencil);
+ANGLE_EXPORT void GL_APIENTRY ClearBufferfv(GLenum buffer, GLint drawbuffer, const GLfloat *value);
+ANGLE_EXPORT void GL_APIENTRY ClearBufferiv(GLenum buffer, GLint drawbuffer, const GLint *value);
+ANGLE_EXPORT void GL_APIENTRY ClearBufferuiv(GLenum buffer, GLint drawbuffer, const GLuint *value);
+ANGLE_EXPORT GLenum GL_APIENTRY ClientWaitSync(GLsync sync, GLbitfield flags, GLuint64 timeout);
 ANGLE_EXPORT void GL_APIENTRY CompressedTexImage3D(GLenum target,
                                                    GLint level,
                                                    GLenum internalformat,
                                                    GLsizei width,
                                                    GLsizei height,
                                                    GLsizei depth,
                                                    GLint border,
                                                    GLsizei imageSize,
@@ -68,217 +57,228 @@ ANGLE_EXPORT void GL_APIENTRY Compressed
                                                       GLint yoffset,
                                                       GLint zoffset,
                                                       GLsizei width,
                                                       GLsizei height,
                                                       GLsizei depth,
                                                       GLenum format,
                                                       GLsizei imageSize,
                                                       const void *data);
-ANGLE_EXPORT void GL_APIENTRY GenQueries(GLsizei n, GLuint *ids);
+ANGLE_EXPORT void GL_APIENTRY CopyBufferSubData(GLenum readTarget,
+                                                GLenum writeTarget,
+                                                GLintptr readOffset,
+                                                GLintptr writeOffset,
+                                                GLsizeiptr size);
+ANGLE_EXPORT void GL_APIENTRY CopyTexSubImage3D(GLenum target,
+                                                GLint level,
+                                                GLint xoffset,
+                                                GLint yoffset,
+                                                GLint zoffset,
+                                                GLint x,
+                                                GLint y,
+                                                GLsizei width,
+                                                GLsizei height);
 ANGLE_EXPORT void GL_APIENTRY DeleteQueries(GLsizei n, const GLuint *ids);
-ANGLE_EXPORT GLboolean GL_APIENTRY IsQuery(GLuint id);
-ANGLE_EXPORT void GL_APIENTRY BeginQuery(GLenum target, GLuint id);
-ANGLE_EXPORT void GL_APIENTRY EndQuery(GLenum target);
-ANGLE_EXPORT void GL_APIENTRY GetQueryiv(GLenum target, GLenum pname, GLint *params);
-ANGLE_EXPORT void GL_APIENTRY GetQueryObjectuiv(GLuint id, GLenum pname, GLuint *params);
-ANGLE_EXPORT GLboolean GL_APIENTRY UnmapBuffer(GLenum target);
-ANGLE_EXPORT void GL_APIENTRY GetBufferPointerv(GLenum target, GLenum pname, void **params);
+ANGLE_EXPORT void GL_APIENTRY DeleteSamplers(GLsizei count, const GLuint *samplers);
+ANGLE_EXPORT void GL_APIENTRY DeleteSync(GLsync sync);
+ANGLE_EXPORT void GL_APIENTRY DeleteTransformFeedbacks(GLsizei n, const GLuint *ids);
+ANGLE_EXPORT void GL_APIENTRY DeleteVertexArrays(GLsizei n, const GLuint *arrays);
+ANGLE_EXPORT void GL_APIENTRY DrawArraysInstanced(GLenum mode,
+                                                  GLint first,
+                                                  GLsizei count,
+                                                  GLsizei instancecount);
 ANGLE_EXPORT void GL_APIENTRY DrawBuffers(GLsizei n, const GLenum *bufs);
-ANGLE_EXPORT void GL_APIENTRY UniformMatrix2x3fv(GLint location,
-                                                 GLsizei count,
-                                                 GLboolean transpose,
-                                                 const GLfloat *value);
-ANGLE_EXPORT void GL_APIENTRY UniformMatrix3x2fv(GLint location,
-                                                 GLsizei count,
-                                                 GLboolean transpose,
-                                                 const GLfloat *value);
-ANGLE_EXPORT void GL_APIENTRY UniformMatrix2x4fv(GLint location,
-                                                 GLsizei count,
-                                                 GLboolean transpose,
-                                                 const GLfloat *value);
-ANGLE_EXPORT void GL_APIENTRY UniformMatrix4x2fv(GLint location,
-                                                 GLsizei count,
-                                                 GLboolean transpose,
-                                                 const GLfloat *value);
-ANGLE_EXPORT void GL_APIENTRY UniformMatrix3x4fv(GLint location,
-                                                 GLsizei count,
-                                                 GLboolean transpose,
-                                                 const GLfloat *value);
-ANGLE_EXPORT void GL_APIENTRY UniformMatrix4x3fv(GLint location,
-                                                 GLsizei count,
-                                                 GLboolean transpose,
-                                                 const GLfloat *value);
-ANGLE_EXPORT void GL_APIENTRY BlitFramebuffer(GLint srcX0,
-                                              GLint srcY0,
-                                              GLint srcX1,
-                                              GLint srcY1,
-                                              GLint dstX0,
-                                              GLint dstY0,
-                                              GLint dstX1,
-                                              GLint dstY1,
-                                              GLbitfield mask,
-                                              GLenum filter);
-ANGLE_EXPORT void GL_APIENTRY RenderbufferStorageMultisample(GLenum target,
-                                                             GLsizei samples,
-                                                             GLenum internalformat,
-                                                             GLsizei width,
-                                                             GLsizei height);
-ANGLE_EXPORT void GL_APIENTRY
-FramebufferTextureLayer(GLenum target, GLenum attachment, GLuint texture, GLint level, GLint layer);
-ANGLE_EXPORT void *GL_APIENTRY MapBufferRange(GLenum target,
-                                              GLintptr offset,
-                                              GLsizeiptr length,
-                                              GLbitfield access);
+ANGLE_EXPORT void GL_APIENTRY DrawElementsInstanced(GLenum mode,
+                                                    GLsizei count,
+                                                    GLenum type,
+                                                    const void *indices,
+                                                    GLsizei instancecount);
+ANGLE_EXPORT void GL_APIENTRY DrawRangeElements(GLenum mode,
+                                                GLuint start,
+                                                GLuint end,
+                                                GLsizei count,
+                                                GLenum type,
+                                                const void *indices);
+ANGLE_EXPORT void GL_APIENTRY EndQuery(GLenum target);
+ANGLE_EXPORT void GL_APIENTRY EndTransformFeedback();
+ANGLE_EXPORT GLsync GL_APIENTRY FenceSync(GLenum condition, GLbitfield flags);
 ANGLE_EXPORT void GL_APIENTRY FlushMappedBufferRange(GLenum target,
                                                      GLintptr offset,
                                                      GLsizeiptr length);
-ANGLE_EXPORT void GL_APIENTRY BindVertexArray(GLuint array);
-ANGLE_EXPORT void GL_APIENTRY DeleteVertexArrays(GLsizei n, const GLuint *arrays);
+ANGLE_EXPORT void GL_APIENTRY
+FramebufferTextureLayer(GLenum target, GLenum attachment, GLuint texture, GLint level, GLint layer);
+ANGLE_EXPORT void GL_APIENTRY GenQueries(GLsizei n, GLuint *ids);
+ANGLE_EXPORT void GL_APIENTRY GenSamplers(GLsizei count, GLuint *samplers);
+ANGLE_EXPORT void GL_APIENTRY GenTransformFeedbacks(GLsizei n, GLuint *ids);
 ANGLE_EXPORT void GL_APIENTRY GenVertexArrays(GLsizei n, GLuint *arrays);
-ANGLE_EXPORT GLboolean GL_APIENTRY IsVertexArray(GLuint array);
+ANGLE_EXPORT void GL_APIENTRY GetActiveUniformBlockName(GLuint program,
+                                                        GLuint uniformBlockIndex,
+                                                        GLsizei bufSize,
+                                                        GLsizei *length,
+                                                        GLchar *uniformBlockName);
+ANGLE_EXPORT void GL_APIENTRY GetActiveUniformBlockiv(GLuint program,
+                                                      GLuint uniformBlockIndex,
+                                                      GLenum pname,
+                                                      GLint *params);
+ANGLE_EXPORT void GL_APIENTRY GetActiveUniformsiv(GLuint program,
+                                                  GLsizei uniformCount,
+                                                  const GLuint *uniformIndices,
+                                                  GLenum pname,
+                                                  GLint *params);
+ANGLE_EXPORT void GL_APIENTRY GetBufferParameteri64v(GLenum target, GLenum pname, GLint64 *params);
+ANGLE_EXPORT void GL_APIENTRY GetBufferPointerv(GLenum target, GLenum pname, void **params);
+ANGLE_EXPORT GLint GL_APIENTRY GetFragDataLocation(GLuint program, const GLchar *name);
+ANGLE_EXPORT void GL_APIENTRY GetInteger64i_v(GLenum target, GLuint index, GLint64 *data);
+ANGLE_EXPORT void GL_APIENTRY GetInteger64v(GLenum pname, GLint64 *data);
 ANGLE_EXPORT void GL_APIENTRY GetIntegeri_v(GLenum target, GLuint index, GLint *data);
-ANGLE_EXPORT void GL_APIENTRY BeginTransformFeedback(GLenum primitiveMode);
-ANGLE_EXPORT void GL_APIENTRY EndTransformFeedback();
+ANGLE_EXPORT void GL_APIENTRY GetInternalformativ(GLenum target,
+                                                  GLenum internalformat,
+                                                  GLenum pname,
+                                                  GLsizei bufSize,
+                                                  GLint *params);
+ANGLE_EXPORT void GL_APIENTRY GetProgramBinary(GLuint program,
+                                               GLsizei bufSize,
+                                               GLsizei *length,
+                                               GLenum *binaryFormat,
+                                               void *binary);
+ANGLE_EXPORT void GL_APIENTRY GetQueryObjectuiv(GLuint id, GLenum pname, GLuint *params);
+ANGLE_EXPORT void GL_APIENTRY GetQueryiv(GLenum target, GLenum pname, GLint *params);
+ANGLE_EXPORT void GL_APIENTRY GetSamplerParameterfv(GLuint sampler, GLenum pname, GLfloat *params);
+ANGLE_EXPORT void GL_APIENTRY GetSamplerParameteriv(GLuint sampler, GLenum pname, GLint *params);
+ANGLE_EXPORT const GLubyte *GL_APIENTRY GetStringi(GLenum name, GLuint index);
 ANGLE_EXPORT void GL_APIENTRY
-BindBufferRange(GLenum target, GLuint index, GLuint buffer, GLintptr offset, GLsizeiptr size);
-ANGLE_EXPORT void GL_APIENTRY BindBufferBase(GLenum target, GLuint index, GLuint buffer);
-ANGLE_EXPORT void GL_APIENTRY TransformFeedbackVaryings(GLuint program,
-                                                        GLsizei count,
-                                                        const GLchar *const *varyings,
-                                                        GLenum bufferMode);
+GetSynciv(GLsync sync, GLenum pname, GLsizei bufSize, GLsizei *length, GLint *values);
 ANGLE_EXPORT void GL_APIENTRY GetTransformFeedbackVarying(GLuint program,
                                                           GLuint index,
                                                           GLsizei bufSize,
                                                           GLsizei *length,
                                                           GLsizei *size,
                                                           GLenum *type,
                                                           GLchar *name);
-ANGLE_EXPORT void GL_APIENTRY
-VertexAttribIPointer(GLuint index, GLint size, GLenum type, GLsizei stride, const void *pointer);
-ANGLE_EXPORT void GL_APIENTRY GetVertexAttribIiv(GLuint index, GLenum pname, GLint *params);
-ANGLE_EXPORT void GL_APIENTRY GetVertexAttribIuiv(GLuint index, GLenum pname, GLuint *params);
-ANGLE_EXPORT void GL_APIENTRY VertexAttribI4i(GLuint index, GLint x, GLint y, GLint z, GLint w);
-ANGLE_EXPORT void GL_APIENTRY
-VertexAttribI4ui(GLuint index, GLuint x, GLuint y, GLuint z, GLuint w);
-ANGLE_EXPORT void GL_APIENTRY VertexAttribI4iv(GLuint index, const GLint *v);
-ANGLE_EXPORT void GL_APIENTRY VertexAttribI4uiv(GLuint index, const GLuint *v);
-ANGLE_EXPORT void GL_APIENTRY GetUniformuiv(GLuint program, GLint location, GLuint *params);
-ANGLE_EXPORT GLint GL_APIENTRY GetFragDataLocation(GLuint program, const GLchar *name);
-ANGLE_EXPORT void GL_APIENTRY Uniform1ui(GLint location, GLuint v0);
-ANGLE_EXPORT void GL_APIENTRY Uniform2ui(GLint location, GLuint v0, GLuint v1);
-ANGLE_EXPORT void GL_APIENTRY Uniform3ui(GLint location, GLuint v0, GLuint v1, GLuint v2);
-ANGLE_EXPORT void GL_APIENTRY
-Uniform4ui(GLint location, GLuint v0, GLuint v1, GLuint v2, GLuint v3);
-ANGLE_EXPORT void GL_APIENTRY Uniform1uiv(GLint location, GLsizei count, const GLuint *value);
-ANGLE_EXPORT void GL_APIENTRY Uniform2uiv(GLint location, GLsizei count, const GLuint *value);
-ANGLE_EXPORT void GL_APIENTRY Uniform3uiv(GLint location, GLsizei count, const GLuint *value);
-ANGLE_EXPORT void GL_APIENTRY Uniform4uiv(GLint location, GLsizei count, const GLuint *value);
-ANGLE_EXPORT void GL_APIENTRY ClearBufferiv(GLenum buffer, GLint drawbuffer, const GLint *value);
-ANGLE_EXPORT void GL_APIENTRY ClearBufferuiv(GLenum buffer, GLint drawbuffer, const GLuint *value);
-ANGLE_EXPORT void GL_APIENTRY ClearBufferfv(GLenum buffer, GLint drawbuffer, const GLfloat *value);
-ANGLE_EXPORT void GL_APIENTRY ClearBufferfi(GLenum buffer,
-                                            GLint drawbuffer,
-                                            GLfloat depth,
-                                            GLint stencil);
-ANGLE_EXPORT const GLubyte *GL_APIENTRY GetStringi(GLenum name, GLuint index);
-ANGLE_EXPORT void GL_APIENTRY CopyBufferSubData(GLenum readTarget,
-                                                GLenum writeTarget,
-                                                GLintptr readOffset,
-                                                GLintptr writeOffset,
-                                                GLsizeiptr size);
+ANGLE_EXPORT GLuint GL_APIENTRY GetUniformBlockIndex(GLuint program,
+                                                     const GLchar *uniformBlockName);
 ANGLE_EXPORT void GL_APIENTRY GetUniformIndices(GLuint program,
                                                 GLsizei uniformCount,
                                                 const GLchar *const *uniformNames,
                                                 GLuint *uniformIndices);
-ANGLE_EXPORT void GL_APIENTRY GetActiveUniformsiv(GLuint program,
-                                                  GLsizei uniformCount,
-                                                  const GLuint *uniformIndices,
-                                                  GLenum pname,
-                                                  GLint *params);
-ANGLE_EXPORT GLuint GL_APIENTRY GetUniformBlockIndex(GLuint program,
-                                                     const GLchar *uniformBlockName);
-ANGLE_EXPORT void GL_APIENTRY GetActiveUniformBlockiv(GLuint program,
-                                                      GLuint uniformBlockIndex,
-                                                      GLenum pname,
-                                                      GLint *params);
-ANGLE_EXPORT void GL_APIENTRY GetActiveUniformBlockName(GLuint program,
-                                                        GLuint uniformBlockIndex,
-                                                        GLsizei bufSize,
-                                                        GLsizei *length,
-                                                        GLchar *uniformBlockName);
-ANGLE_EXPORT void GL_APIENTRY UniformBlockBinding(GLuint program,
-                                                  GLuint uniformBlockIndex,
-                                                  GLuint uniformBlockBinding);
-ANGLE_EXPORT void GL_APIENTRY DrawArraysInstanced(GLenum mode,
-                                                  GLint first,
-                                                  GLsizei count,
-                                                  GLsizei instancecount);
-ANGLE_EXPORT void GL_APIENTRY DrawElementsInstanced(GLenum mode,
-                                                    GLsizei count,
-                                                    GLenum type,
-                                                    const void *indices,
-                                                    GLsizei instancecount);
-ANGLE_EXPORT GLsync GL_APIENTRY FenceSync(GLenum condition, GLbitfield flags);
-ANGLE_EXPORT GLboolean GL_APIENTRY IsSync(GLsync sync);
-ANGLE_EXPORT void GL_APIENTRY DeleteSync(GLsync sync);
-ANGLE_EXPORT GLenum GL_APIENTRY ClientWaitSync(GLsync sync, GLbitfield flags, GLuint64 timeout);
-ANGLE_EXPORT void GL_APIENTRY WaitSync(GLsync sync, GLbitfield flags, GLuint64 timeout);
-ANGLE_EXPORT void GL_APIENTRY GetInteger64v(GLenum pname, GLint64 *data);
-ANGLE_EXPORT void GL_APIENTRY
-GetSynciv(GLsync sync, GLenum pname, GLsizei bufSize, GLsizei *length, GLint *values);
-ANGLE_EXPORT void GL_APIENTRY GetInteger64i_v(GLenum target, GLuint index, GLint64 *data);
-ANGLE_EXPORT void GL_APIENTRY GetBufferParameteri64v(GLenum target, GLenum pname, GLint64 *params);
-ANGLE_EXPORT void GL_APIENTRY GenSamplers(GLsizei count, GLuint *samplers);
-ANGLE_EXPORT void GL_APIENTRY DeleteSamplers(GLsizei count, const GLuint *samplers);
-ANGLE_EXPORT GLboolean GL_APIENTRY IsSampler(GLuint sampler);
-ANGLE_EXPORT void GL_APIENTRY BindSampler(GLuint unit, GLuint sampler);
-ANGLE_EXPORT void GL_APIENTRY SamplerParameteri(GLuint sampler, GLenum pname, GLint param);
-ANGLE_EXPORT void GL_APIENTRY SamplerParameteriv(GLuint sampler, GLenum pname, const GLint *param);
-ANGLE_EXPORT void GL_APIENTRY SamplerParameterf(GLuint sampler, GLenum pname, GLfloat param);
-ANGLE_EXPORT void GL_APIENTRY SamplerParameterfv(GLuint sampler,
-                                                 GLenum pname,
-                                                 const GLfloat *param);
-ANGLE_EXPORT void GL_APIENTRY GetSamplerParameteriv(GLuint sampler, GLenum pname, GLint *params);
-ANGLE_EXPORT void GL_APIENTRY GetSamplerParameterfv(GLuint sampler, GLenum pname, GLfloat *params);
-ANGLE_EXPORT void GL_APIENTRY VertexAttribDivisor(GLuint index, GLuint divisor);
-ANGLE_EXPORT void GL_APIENTRY BindTransformFeedback(GLenum target, GLuint id);
-ANGLE_EXPORT void GL_APIENTRY DeleteTransformFeedbacks(GLsizei n, const GLuint *ids);
-ANGLE_EXPORT void GL_APIENTRY GenTransformFeedbacks(GLsizei n, GLuint *ids);
-ANGLE_EXPORT GLboolean GL_APIENTRY IsTransformFeedback(GLuint id);
-ANGLE_EXPORT void GL_APIENTRY PauseTransformFeedback();
-ANGLE_EXPORT void GL_APIENTRY ResumeTransformFeedback();
-ANGLE_EXPORT void GL_APIENTRY GetProgramBinary(GLuint program,
-                                               GLsizei bufSize,
-                                               GLsizei *length,
-                                               GLenum *binaryFormat,
-                                               void *binary);
-ANGLE_EXPORT void GL_APIENTRY ProgramBinary(GLuint program,
-                                            GLenum binaryFormat,
-                                            const void *binary,
-                                            GLsizei length);
-ANGLE_EXPORT void GL_APIENTRY ProgramParameteri(GLuint program, GLenum pname, GLint value);
+ANGLE_EXPORT void GL_APIENTRY GetUniformuiv(GLuint program, GLint location, GLuint *params);
+ANGLE_EXPORT void GL_APIENTRY GetVertexAttribIiv(GLuint index, GLenum pname, GLint *params);
+ANGLE_EXPORT void GL_APIENTRY GetVertexAttribIuiv(GLuint index, GLenum pname, GLuint *params);
 ANGLE_EXPORT void GL_APIENTRY InvalidateFramebuffer(GLenum target,
                                                     GLsizei numAttachments,
                                                     const GLenum *attachments);
 ANGLE_EXPORT void GL_APIENTRY InvalidateSubFramebuffer(GLenum target,
                                                        GLsizei numAttachments,
                                                        const GLenum *attachments,
                                                        GLint x,
                                                        GLint y,
                                                        GLsizei width,
                                                        GLsizei height);
+ANGLE_EXPORT GLboolean GL_APIENTRY IsQuery(GLuint id);
+ANGLE_EXPORT GLboolean GL_APIENTRY IsSampler(GLuint sampler);
+ANGLE_EXPORT GLboolean GL_APIENTRY IsSync(GLsync sync);
+ANGLE_EXPORT GLboolean GL_APIENTRY IsTransformFeedback(GLuint id);
+ANGLE_EXPORT GLboolean GL_APIENTRY IsVertexArray(GLuint array);
+ANGLE_EXPORT void *GL_APIENTRY MapBufferRange(GLenum target,
+                                              GLintptr offset,
+                                              GLsizeiptr length,
+                                              GLbitfield access);
+ANGLE_EXPORT void GL_APIENTRY PauseTransformFeedback();
+ANGLE_EXPORT void GL_APIENTRY ProgramBinary(GLuint program,
+                                            GLenum binaryFormat,
+                                            const void *binary,
+                                            GLsizei length);
+ANGLE_EXPORT void GL_APIENTRY ProgramParameteri(GLuint program, GLenum pname, GLint value);
+ANGLE_EXPORT void GL_APIENTRY ReadBuffer(GLenum src);
+ANGLE_EXPORT void GL_APIENTRY RenderbufferStorageMultisample(GLenum target,
+                                                             GLsizei samples,
+                                                             GLenum internalformat,
+                                                             GLsizei width,
+                                                             GLsizei height);
+ANGLE_EXPORT void GL_APIENTRY ResumeTransformFeedback();
+ANGLE_EXPORT void GL_APIENTRY SamplerParameterf(GLuint sampler, GLenum pname, GLfloat param);
+ANGLE_EXPORT void GL_APIENTRY SamplerParameterfv(GLuint sampler,
+                                                 GLenum pname,
+                                                 const GLfloat *param);
+ANGLE_EXPORT void GL_APIENTRY SamplerParameteri(GLuint sampler, GLenum pname, GLint param);
+ANGLE_EXPORT void GL_APIENTRY SamplerParameteriv(GLuint sampler, GLenum pname, const GLint *param);
+ANGLE_EXPORT void GL_APIENTRY TexImage3D(GLenum target,
+                                         GLint level,
+                                         GLint internalformat,
+                                         GLsizei width,
+                                         GLsizei height,
+                                         GLsizei depth,
+                                         GLint border,
+                                         GLenum format,
+                                         GLenum type,
+                                         const void *pixels);
 ANGLE_EXPORT void GL_APIENTRY
 TexStorage2D(GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height);
 ANGLE_EXPORT void GL_APIENTRY TexStorage3D(GLenum target,
                                            GLsizei levels,
                                            GLenum internalformat,
                                            GLsizei width,
                                            GLsizei height,
                                            GLsizei depth);
-ANGLE_EXPORT void GL_APIENTRY GetInternalformativ(GLenum target,
-                                                  GLenum internalformat,
-                                                  GLenum pname,
-                                                  GLsizei bufSize,
-                                                  GLint *params);
+ANGLE_EXPORT void GL_APIENTRY TexSubImage3D(GLenum target,
+                                            GLint level,
+                                            GLint xoffset,
+                                            GLint yoffset,
+                                            GLint zoffset,
+                                            GLsizei width,
+                                            GLsizei height,
+                                            GLsizei depth,
+                                            GLenum format,
+                                            GLenum type,
+                                            const void *pixels);
+ANGLE_EXPORT void GL_APIENTRY TransformFeedbackVaryings(GLuint program,
+                                                        GLsizei count,
+                                                        const GLchar *const *varyings,
+                                                        GLenum bufferMode);
+ANGLE_EXPORT void GL_APIENTRY Uniform1ui(GLint location, GLuint v0);
+ANGLE_EXPORT void GL_APIENTRY Uniform1uiv(GLint location, GLsizei count, const GLuint *value);
+ANGLE_EXPORT void GL_APIENTRY Uniform2ui(GLint location, GLuint v0, GLuint v1);
+ANGLE_EXPORT void GL_APIENTRY Uniform2uiv(GLint location, GLsizei count, const GLuint *value);
+ANGLE_EXPORT void GL_APIENTRY Uniform3ui(GLint location, GLuint v0, GLuint v1, GLuint v2);
+ANGLE_EXPORT void GL_APIENTRY Uniform3uiv(GLint location, GLsizei count, const GLuint *value);
+ANGLE_EXPORT void GL_APIENTRY
+Uniform4ui(GLint location, GLuint v0, GLuint v1, GLuint v2, GLuint v3);
+ANGLE_EXPORT void GL_APIENTRY Uniform4uiv(GLint location, GLsizei count, const GLuint *value);
+ANGLE_EXPORT void GL_APIENTRY UniformBlockBinding(GLuint program,
+                                                  GLuint uniformBlockIndex,
+                                                  GLuint uniformBlockBinding);
+ANGLE_EXPORT void GL_APIENTRY UniformMatrix2x3fv(GLint location,
+                                                 GLsizei count,
+                                                 GLboolean transpose,
+                                                 const GLfloat *value);
+ANGLE_EXPORT void GL_APIENTRY UniformMatrix2x4fv(GLint location,
+                                                 GLsizei count,
+                                                 GLboolean transpose,
+                                                 const GLfloat *value);
+ANGLE_EXPORT void GL_APIENTRY UniformMatrix3x2fv(GLint location,
+                                                 GLsizei count,
+                                                 GLboolean transpose,
+                                                 const GLfloat *value);
+ANGLE_EXPORT void GL_APIENTRY UniformMatrix3x4fv(GLint location,
+                                                 GLsizei count,
+                                                 GLboolean transpose,
+                                                 const GLfloat *value);
+ANGLE_EXPORT void GL_APIENTRY UniformMatrix4x2fv(GLint location,
+                                                 GLsizei count,
+                                                 GLboolean transpose,
+                                                 const GLfloat *value);
+ANGLE_EXPORT void GL_APIENTRY UniformMatrix4x3fv(GLint location,
+                                                 GLsizei count,
+                                                 GLboolean transpose,
+                                                 const GLfloat *value);
+ANGLE_EXPORT GLboolean GL_APIENTRY UnmapBuffer(GLenum target);
+ANGLE_EXPORT void GL_APIENTRY VertexAttribDivisor(GLuint index, GLuint divisor);
+ANGLE_EXPORT void GL_APIENTRY VertexAttribI4i(GLuint index, GLint x, GLint y, GLint z, GLint w);
+ANGLE_EXPORT void GL_APIENTRY VertexAttribI4iv(GLuint index, const GLint *v);
+ANGLE_EXPORT void GL_APIENTRY
+VertexAttribI4ui(GLuint index, GLuint x, GLuint y, GLuint z, GLuint w);
+ANGLE_EXPORT void GL_APIENTRY VertexAttribI4uiv(GLuint index, const GLuint *v);
+ANGLE_EXPORT void GL_APIENTRY
+VertexAttribIPointer(GLuint index, GLint size, GLenum type, GLsizei stride, const void *pointer);
+ANGLE_EXPORT void GL_APIENTRY WaitSync(GLsync sync, GLbitfield flags, GLuint64 timeout);
 }  // namespace gl
 
-#endif  // LIBGLESV2_ENTRYPOINTSGLES30_AUTOGEN_H_
+#endif  // LIBGLESV2_ENTRY_POINTS_GLES_3_0_AUTOGEN_H_
deleted file mode 100644
--- a/gfx/angle/src/libGLESv2/entry_points_gles_3_1.cpp
+++ /dev/null
@@ -1,1222 +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.
-//
-
-// entry_points_gles_3_1.cpp : Implements the GLES 3.1 Entry point.
-
-#include "libGLESv2/entry_points_gles_3_1.h"
-#include "libGLESv2/global_state.h"
-
-#include "libANGLE/Context.h"
-#include "libANGLE/Error.h"
-
-#include "libANGLE/validationES.h"
-#include "libANGLE/validationES31.h"
-#include "libANGLE/queryconversions.h"
-#include "libANGLE/queryutils.h"
-
-#include "common/debug.h"
-#include "common/utilities.h"
-
-namespace gl
-{
-
-void GL_APIENTRY DispatchCompute(GLuint numGroupsX, GLuint numGroupsY, GLuint numGroupsZ)
-{
-    EVENT("(GLuint numGroupsX = %u, GLuint numGroupsY = %u, numGroupsZ = %u", numGroupsX,
-          numGroupsY, numGroupsZ);
-    Context *context = GetValidGlobalContext();
-    if (context)
-    {
-        if (!context->skipValidation() &&
-            !ValidateDispatchCompute(context, numGroupsX, numGroupsY, numGroupsZ))
-        {
-            return;
-        }
-
-        context->dispatchCompute(numGroupsX, numGroupsY, numGroupsZ);
-    }
-}
-
-void GL_APIENTRY DispatchComputeIndirect(GLintptr indirect)
-{
-    EVENT("(GLintptr indirect = %d)", indirect);
-    Context *context = GetValidGlobalContext();
-    if (context)
-    {
-        if (!context->skipValidation())
-        {
-            context->handleError(InvalidOperation() << "Entry point not implemented");
-        }
-        UNIMPLEMENTED();
-    }
-}
-
-void GL_APIENTRY DrawArraysIndirect(GLenum mode, const void *indirect)
-{
-    EVENT("(GLenum mode = 0x%X, const void* indirect)", mode, indirect);
-    Context *context = GetValidGlobalContext();
-    if (context)
-    {
-        if (!context->skipValidation() && !ValidateDrawArraysIndirect(context, mode, indirect))
-        {
-            return;
-        }
-
-        context->drawArraysIndirect(mode, indirect);
-    }
-}
-
-void GL_APIENTRY DrawElementsIndirect(GLenum mode, GLenum type, const void *indirect)
-{
-    EVENT("(GLenum mode = 0x%X, GLenum type = 0x%X, const void* indirect)", mode, type, indirect);
-    Context *context = GetValidGlobalContext();
-    if (context)
-    {
-        if (!context->skipValidation() &&
-            !ValidateDrawElementsIndirect(context, mode, type, indirect))
-        {
-            return;
-        }
-
-        context->drawElementsIndirect(mode, type, indirect);
-    }
-}
-
-void GL_APIENTRY FramebufferParameteri(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)
-    {
-        if (!context->skipValidation() &&
-            !ValidationFramebufferParameteri(context, target, pname, param))
-        {
-            return;
-        }
-
-        context->setFramebufferParameteri(target, pname, param);
-    }
-}
-
-void GL_APIENTRY GetFramebufferParameteriv(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)
-    {
-        if (!context->skipValidation() &&
-            !ValidationGetFramebufferParameteri(context, target, pname, params))
-        {
-            return;
-        }
-
-        context->getFramebufferParameteriv(target, pname, params);
-    }
-}
-
-void GL_APIENTRY GetProgramInterfaceiv(GLuint program,
-                                       GLenum programInterface,
-                                       GLenum pname,
-                                       GLint *params)
-{
-    EVENT(
-        "(GLuint program = %u, GLenum programInterface = 0x%X, GLenum pname = 0x%X, GLint* params "
-        "= 0x%0.8p)",
-        program, programInterface, pname, params);
-    Context *context = GetValidGlobalContext();
-    if (context)
-    {
-        if (!context->skipValidation() &&
-            !ValidateGetProgramInterfaceiv(context, program, programInterface, pname, params))
-        {
-            return;
-        }
-        context->getProgramInterfaceiv(program, programInterface, pname, params);
-    }
-}
-
-GLuint GL_APIENTRY GetProgramResourceIndex(GLuint program,
-                                           GLenum programInterface,
-                                           const GLchar *name)
-{
-    EVENT("(GLuint program = %u, GLenum programInterface = 0x%X, const GLchar* name = 0x%0.8p)",
-          program, programInterface, name);
-    Context *context = GetValidGlobalContext();
-    if (context)
-    {
-        if (!context->skipValidation() &&
-            !ValidateGetProgramResourceIndex(context, program, programInterface, name))
-        {
-            return GL_INVALID_INDEX;
-        }
-        return context->getProgramResourceIndex(program, programInterface, name);
-    }
-    return GL_INVALID_INDEX;
-}
-
-void GL_APIENTRY GetProgramResourceName(GLuint program,
-                                        GLenum programInterface,
-                                        GLuint index,
-                                        GLsizei bufSize,
-                                        GLsizei *length,
-                                        GLchar *name)
-{
-    EVENT(
-        "(GLuint program = %u, GLenum programInterface = 0x%X, GLuint index = %u, GLsizei bufSize "
-        "= %d, GLsizei* length = 0x%0.8p, GLchar* name = 0x%0.8p)",
-        program, programInterface, index, bufSize, length, name);
-    Context *context = GetValidGlobalContext();
-    if (context)
-    {
-        if (!context->skipValidation() &&
-            !ValidateGetProgramResourceName(context, program, programInterface, index, bufSize,
-                                            length, name))
-        {
-            return;
-        }
-        context->getProgramResourceName(program, programInterface, index, bufSize, length, name);
-    }
-}
-
-void GL_APIENTRY GetProgramResourceiv(GLuint program,
-                                      GLenum programInterface,
-                                      GLuint index,
-                                      GLsizei propCount,
-                                      const GLenum *props,
-                                      GLsizei bufSize,
-                                      GLsizei *length,
-                                      GLint *params)
-{
-    EVENT(
-        "(GLuint program = %u, GLenum programInterface = 0x%X, GLuint index = %u, GLsizei "
-        "propCount = %d, const GLenum* props = 0x%0.8p, GLsizei bufSize = %d, GLsizei* length = "
-        "0x%0.8p, GLint* params = 0x%0.8p)",
-        program, programInterface, index, propCount, props, bufSize, length, params);
-    Context *context = GetValidGlobalContext();
-    if (context)
-    {
-        if (!context->skipValidation() &&
-            !ValidateGetProgramResourceiv(context, program, programInterface, index, propCount,
-                                          props, bufSize, length, params))
-        {
-            return;
-        }
-        context->getProgramResourceiv(program, programInterface, index, propCount, props, bufSize,
-                                      length, params);
-    }
-}
-
-GLint GL_APIENTRY GetProgramResourceLocation(GLuint program,
-                                             GLenum programInterface,
-                                             const GLchar *name)
-{
-    EVENT("(GLuint program = %u, GLenum programInterface = 0x%X, const GLchar* name = 0x%0.8p)",
-          program, programInterface, name);
-    Context *context = GetValidGlobalContext();
-    if (context)
-    {
-        if (!context->skipValidation() &&
-            !ValidateGetProgramResourceLocation(context, program, programInterface, name))
-        {
-            return -1;
-        }
-        return context->getProgramResourceLocation(program, programInterface, name);
-    }
-    return -1;
-}
-
-void GL_APIENTRY UseProgramStages(GLuint pipeline, GLbitfield stages, GLuint program)
-{
-    EVENT("(GLuint pipeline = %u, GLbitfield stages = 0x%X, GLuint program = %u)", pipeline, stages,
-          program);
-    Context *context = GetValidGlobalContext();
-    if (context)
-    {
-        if (!context->skipValidation())
-        {
-            context->handleError(InvalidOperation() << "Entry point not implemented");
-        }
-        UNIMPLEMENTED();
-    }
-}
-
-void GL_APIENTRY ActiveShaderProgram(GLuint pipeline, GLuint program)
-{
-    EVENT("(GLuint pipeline = %u, GLuint program = %u)", pipeline, program);
-    Context *context = GetValidGlobalContext();
-    if (context)
-    {
-        if (!context->skipValidation())
-        {
-            context->handleError(InvalidOperation() << "Entry point not implemented");
-        }
-        UNIMPLEMENTED();
-    }
-}
-
-GLuint GL_APIENTRY CreateShaderProgramv(GLenum type, GLsizei count, const GLchar *const *strings)
-{
-    EVENT("(GLenum type = %0x%X, GLsizei count = %d, const GLchar *const* = 0x%0.8p)", type, count,
-          strings);
-    Context *context = GetValidGlobalContext();
-    if (context)
-    {
-        if (!context->skipValidation())
-        {
-            context->handleError(InvalidOperation() << "Entry point not implemented");
-        }
-        UNIMPLEMENTED();
-    }
-    return 0u;
-}
-
-void GL_APIENTRY BindProgramPipeline(GLuint pipeline)
-{
-    EVENT("(GLuint pipeline = %u)", pipeline);
-    Context *context = GetValidGlobalContext();
-    if (context)
-    {
-        if (!context->skipValidation() && !ValidateBindProgramPipeline(context, pipeline))
-        {
-            return;
-        }
-
-        context->bindProgramPipeline(pipeline);
-    }
-}
-
-void GL_APIENTRY DeleteProgramPipelines(GLsizei n, const GLuint *pipelines)
-{
-    EVENT("(GLsizei n = %d, const GLuint* pipelines = 0x%0.8p)", n, pipelines);
-    Context *context = GetValidGlobalContext();
-    if (context)
-    {
-        if (!context->skipValidation() && !ValidateDeleteProgramPipelines(context, n, pipelines))
-        {
-            return;
-        }
-
-        context->deleteProgramPipelines(n, pipelines);
-    }
-}
-
-void GL_APIENTRY GenProgramPipelines(GLsizei n, GLuint *pipelines)
-{
-    EVENT("(GLsizei n = %d, GLuint* pipelines = 0x%0.8p)", n, pipelines);
-    Context *context = GetValidGlobalContext();
-    if (context)
-    {
-        if (!context->skipValidation() && !ValidateGenProgramPipelines(context, n, pipelines))
-        {
-            return;
-        }
-
-        context->genProgramPipelines(n, pipelines);
-    }
-}
-
-GLboolean GL_APIENTRY IsProgramPipeline(GLuint pipeline)
-{
-    EVENT("(GLuint pipeline = %u)", pipeline);
-    Context *context = GetValidGlobalContext();
-    if (context)
-    {
-        if (!context->skipValidation() && !ValidateIsProgramPipeline(context, pipeline))
-        {
-            return GL_FALSE;
-        }
-
-        return context->isProgramPipeline(pipeline);
-    }
-
-    return GL_FALSE;
-}
-
-void GL_APIENTRY GetProgramPipelineiv(GLuint pipeline, GLenum pname, GLint *params)
-{
-    EVENT("(GLuint pipeline = %u, GLenum pname = 0x%X, GLint* params = 0x%0.8p)", pipeline, pname,
-          params);
-    Context *context = GetValidGlobalContext();
-    if (context)
-    {
-        if (!context->skipValidation())
-        {
-            context->handleError(InvalidOperation() << "Entry point not implemented");
-        }
-        UNIMPLEMENTED();
-    }
-}
-
-void GL_APIENTRY ProgramUniform1i(GLuint program, GLint location, GLint v0)
-{
-    ProgramUniform1iv(program, location, 1, &v0);
-}
-
-void GL_APIENTRY ProgramUniform2i(GLuint program, GLint location, GLint v0, GLint v1)
-{
-    GLint xy[2] = {v0, v1};
-    ProgramUniform2iv(program, location, 1, xy);
-}
-
-void GL_APIENTRY ProgramUniform3i(GLuint program, GLint location, GLint v0, GLint v1, GLint v2)
-{
-    GLint xyz[3] = {v0, v1, v2};
-    ProgramUniform3iv(program, location, 1, xyz);
-}
-
-void GL_APIENTRY
-ProgramUniform4i(GLuint program, GLint location, GLint v0, GLint v1, GLint v2, GLint v3)
-{
-    GLint xyzw[4] = {v0, v1, v2, v3};
-    ProgramUniform4iv(program, location, 1, xyzw);
-}
-
-void GL_APIENTRY ProgramUniform1ui(GLuint program, GLint location, GLuint v0)
-{
-    ProgramUniform1uiv(program, location, 1, &v0);
-}
-
-void GL_APIENTRY ProgramUniform2ui(GLuint program, GLint location, GLuint v0, GLuint v1)
-{
-    GLuint xy[2] = {v0, v1};
-    ProgramUniform2uiv(program, location, 1, xy);
-}
-
-void GL_APIENTRY ProgramUniform3ui(GLuint program, GLint location, GLuint v0, GLuint v1, GLuint v2)
-{
-    GLuint xyz[3] = {v0, v1, v2};
-    ProgramUniform3uiv(program, location, 1, xyz);
-}
-
-void GL_APIENTRY
-ProgramUniform4ui(GLuint program, GLint location, GLuint v0, GLuint v1, GLuint v2, GLuint v3)
-{
-    GLuint xyzw[4] = {v0, v1, v2, v3};
-    ProgramUniform4uiv(program, location, 1, xyzw);
-}
-
-void GL_APIENTRY ProgramUniform1f(GLuint program, GLint location, GLfloat v0)
-{
-    ProgramUniform1fv(program, location, 1, &v0);
-}
-
-void GL_APIENTRY ProgramUniform2f(GLuint program, GLint location, GLfloat v0, GLfloat v1)
-{
-    GLfloat xy[2] = {v0, v1};
-    ProgramUniform2fv(program, location, 1, xy);
-}
-
-void GL_APIENTRY
-ProgramUniform3f(GLuint program, GLint location, GLfloat v0, GLfloat v1, GLfloat v2)
-{
-    GLfloat xyz[3] = {v0, v1, v2};
-    ProgramUniform3fv(program, location, 1, xyz);
-}
-
-void GL_APIENTRY
-ProgramUniform4f(GLuint program, GLint location, GLfloat v0, GLfloat v1, GLfloat v2, GLfloat v3)
-{
-    GLfloat xyzw[4] = {v0, v1, v2, v3};
-    ProgramUniform4fv(program, location, 1, xyzw);
-}
-
-void GL_APIENTRY ProgramUniform1iv(GLuint program,
-                                   GLint location,
-                                   GLsizei count,
-                                   const GLint *value)
-{
-    EVENT(
-        "(GLuint program = %u, GLint location = %d, GLsizei count = %d, const GLint* value = "
-        "0x%0.8p)",
-        program, location, count, value);
-    Context *context = GetValidGlobalContext();
-    if (context)
-    {
-        if (!ValidateProgramUniform1iv(context, program, location, count, value))
-        {
-            return;
-        }
-
-        context->programUniform1iv(program, location, count, value);
-    }
-}
-
-void GL_APIENTRY ProgramUniform2iv(GLuint program,
-                                   GLint location,
-                                   GLsizei count,
-                                   const GLint *value)
-{
-    EVENT(
-        "(GLuint program = %u, GLint location = %d, GLsizei count = %d, const GLint* value = "
-        "0x%0.8p)",
-        program, location, count, value);
-    Context *context = GetValidGlobalContext();
-    if (context)
-    {
-        if (!ValidateProgramUniform(context, GL_INT_VEC2, program, location, count))
-        {
-            return;
-        }
-
-        Program *programObject = context->getProgram(program);
-        ASSERT(programObject);
-        programObject->setUniform2iv(location, count, value);
-    }
-}
-
-void GL_APIENTRY ProgramUniform3iv(GLuint program,
-                                   GLint location,
-                                   GLsizei count,
-                                   const GLint *value)
-{
-    EVENT(
-        "(GLuint program = %u, GLint location = %d, GLsizei count = %d, const GLint* value = "
-        "0x%0.8p)",
-        program, location, count, value);
-    Context *context = GetValidGlobalContext();
-    if (context)
-    {
-        if (!ValidateProgramUniform(context, GL_INT_VEC3, program, location, count))
-        {
-            return;
-        }
-
-        Program *programObject = context->getProgram(program);
-        ASSERT(programObject);
-        programObject->setUniform3iv(location, count, value);
-    }
-}
-
-void GL_APIENTRY ProgramUniform4iv(GLuint program,
-                                   GLint location,
-                                   GLsizei count,
-                                   const GLint *value)
-{
-    EVENT(
-        "(GLuint program = %u, GLint location = %d, GLsizei count = %d, const GLint* value = "
-        "0x%0.8p)",
-        program, location, count, value);
-    Context *context = GetValidGlobalContext();
-    if (context)
-    {
-        if (!ValidateProgramUniform(context, GL_INT_VEC4, program, location, count))
-        {
-            return;
-        }
-
-        Program *programObject = context->getProgram(program);
-        ASSERT(programObject);
-        programObject->setUniform4iv(location, count, value);
-    }
-}
-
-void GL_APIENTRY ProgramUniform1uiv(GLuint program,
-                                    GLint location,
-                                    GLsizei count,
-                                    const GLuint *value)
-{
-    EVENT(
-        "(GLuint program = %u, GLint location = %d, GLsizei count = %d, const GLuint* value = "
-        "0x%0.8p)",
-        program, location, count, value);
-    Context *context = GetValidGlobalContext();
-    if (context)
-    {
-        if (!ValidateProgramUniform(context, GL_UNSIGNED_INT, program, location, count))
-        {
-            return;
-        }
-
-        Program *programObject = context->getProgram(program);
-        ASSERT(programObject);
-        programObject->setUniform1uiv(location, count, value);
-    }
-}
-
-void GL_APIENTRY ProgramUniform2uiv(GLuint program,
-                                    GLint location,
-                                    GLsizei count,
-                                    const GLuint *value)
-{
-    EVENT(
-        "(GLuint program = %u, GLint location = %d, GLsizei count = %d, const GLuint* value = "
-        "0x%0.8p)",
-        program, location, count, value);
-    Context *context = GetValidGlobalContext();
-    if (context)
-    {
-        if (!ValidateProgramUniform(context, GL_UNSIGNED_INT_VEC2, program, location, count))
-        {
-            return;
-        }
-
-        Program *programObject = context->getProgram(program);
-        ASSERT(programObject);
-        programObject->setUniform2uiv(location, count, value);
-    }
-}
-
-void GL_APIENTRY ProgramUniform3uiv(GLuint program,
-                                    GLint location,
-                                    GLsizei count,
-                                    const GLuint *value)
-{
-    EVENT(
-        "(GLuint program = %u, GLint location = %d, GLsizei count = %d, const GLuint* value = "
-        "0x%0.8p)",
-        program, location, count, value);
-    Context *context = GetValidGlobalContext();
-    if (context)
-    {
-        if (!ValidateProgramUniform(context, GL_UNSIGNED_INT_VEC3, program, location, count))
-        {
-            return;
-        }
-
-        Program *programObject = context->getProgram(program);
-        ASSERT(programObject);
-        programObject->setUniform3uiv(location, count, value);
-    }
-}
-
-void GL_APIENTRY ProgramUniform4uiv(GLuint program,
-                                    GLint location,
-                                    GLsizei count,
-                                    const GLuint *value)
-{
-    EVENT(
-        "(GLuint program = %u, GLint location = %d, GLsizei count = %d, const GLuint* value = "
-        "0x%0.8p)",
-        program, location, count, value);
-    Context *context = GetValidGlobalContext();
-    if (context)
-    {
-        if (!ValidateProgramUniform(context, GL_UNSIGNED_INT_VEC4, program, location, count))
-        {
-            return;
-        }
-
-        Program *programObject = context->getProgram(program);
-        ASSERT(programObject);
-        programObject->setUniform4uiv(location, count, value);
-    }
-}
-
-void GL_APIENTRY ProgramUniform1fv(GLuint program,
-                                   GLint location,
-                                   GLsizei count,
-                                   const GLfloat *value)
-{
-    EVENT(
-        "(GLuint program = %u, GLint location = %d, GLsizei count = %d, const GLfloat* value = "
-        "0x%0.8p)",
-        program, location, count, value);
-    Context *context = GetValidGlobalContext();
-    if (context)
-    {
-        if (!ValidateProgramUniform(context, GL_FLOAT, program, location, count))
-        {
-            return;
-        }
-
-        Program *programObject = context->getProgram(program);
-        ASSERT(programObject);
-        programObject->setUniform1fv(location, count, value);
-    }
-}
-
-void GL_APIENTRY ProgramUniform2fv(GLuint program,
-                                   GLint location,
-                                   GLsizei count,
-                                   const GLfloat *value)
-{
-    EVENT(
-        "(GLuint program = %u, GLint location = %d, GLsizei count = %d, const GLfloat* value = "
-        "0x%0.8p)",
-        program, location, count, value);
-    Context *context = GetValidGlobalContext();
-    if (context)
-    {
-        if (!ValidateProgramUniform(context, GL_FLOAT_VEC2, program, location, count))
-        {
-            return;
-        }
-
-        Program *programObject = context->getProgram(program);
-        ASSERT(programObject);
-        programObject->setUniform2fv(location, count, value);
-    }
-}
-
-void GL_APIENTRY ProgramUniform3fv(GLuint program,
-                                   GLint location,
-                                   GLsizei count,
-                                   const GLfloat *value)
-{
-    EVENT(
-        "(GLuint program = %u, GLint location = %d, GLsizei count = %d, const GLfloat* value = "
-        "0x%0.8p)",
-        program, location, count, value);
-    Context *context = GetValidGlobalContext();
-    if (context)
-    {
-        if (!ValidateProgramUniform(context, GL_FLOAT_VEC3, program, location, count))
-        {
-            return;
-        }
-
-        Program *programObject = context->getProgram(program);
-        ASSERT(programObject);
-        programObject->setUniform3fv(location, count, value);
-    }
-}
-
-void GL_APIENTRY ProgramUniform4fv(GLuint program,
-                                   GLint location,
-                                   GLsizei count,
-                                   const GLfloat *value)
-{
-    EVENT(
-        "(GLuint program = %u, GLint location = %d, GLsizei count = %d, const GLfloat* value = "
-        "0x%0.8p)",
-        program, location, count, value);
-    Context *context = GetValidGlobalContext();
-    if (context)
-    {
-        if (!ValidateProgramUniform(context, GL_FLOAT_VEC4, program, location, count))
-        {
-            return;
-        }
-
-        Program *programObject = context->getProgram(program);
-        ASSERT(programObject);
-        programObject->setUniform4fv(location, count, value);
-    }
-}
-
-void GL_APIENTRY ProgramUniformMatrix2fv(GLuint program,
-                                         GLint location,
-                                         GLsizei count,
-                                         GLboolean transpose,
-                                         const GLfloat *value)
-{
-    EVENT(
-        "(GLuint program = %u, GLint location = %d, GLsizei count = %d, GLboolean transpose = %u, "
-        "const GLfloat* value = 0x%0.8p)",
-        program, location, count, transpose, value);
-    Context *context = GetValidGlobalContext();
-    if (context)
-    {
-        if (!ValidateProgramUniformMatrix(context, GL_FLOAT_MAT2, program, location, count,
-                                          transpose))
-        {
-            return;
-        }
-
-        Program *programObject = context->getProgram(program);
-        ASSERT(programObject);
-        programObject->setUniformMatrix2fv(location, count, transpose, value);
-    }
-}
-
-void GL_APIENTRY ProgramUniformMatrix3fv(GLuint program,
-                                         GLint location,
-                                         GLsizei count,
-                                         GLboolean transpose,
-                                         const GLfloat *value)
-{
-    EVENT(
-        "(GLuint program = %u, GLint location = %d, GLsizei count = %d, GLboolean transpose = %u, "
-        "const GLfloat* value = 0x%0.8p)",
-        program, location, count, transpose, value);
-    Context *context = GetValidGlobalContext();
-    if (context)
-    {
-        if (!ValidateProgramUniformMatrix(context, GL_FLOAT_MAT3, program, location, count,
-                                          transpose))
-        {
-            return;
-        }
-
-        Program *programObject = context->getProgram(program);
-        ASSERT(programObject);
-        programObject->setUniformMatrix3fv(location, count, transpose, value);
-    }
-}
-
-void GL_APIENTRY ProgramUniformMatrix4fv(GLuint program,
-                                         GLint location,
-                                         GLsizei count,
-                                         GLboolean transpose,
-                                         const GLfloat *value)
-{
-    EVENT(
-        "(GLuint program = %u, GLint location = %d, GLsizei count = %d, GLboolean transpose = %u, "
-        "const GLfloat* value = 0x%0.8p)",
-        program, location, count, transpose, value);
-    Context *context = GetValidGlobalContext();
-    if (context)
-    {
-        if (!ValidateProgramUniformMatrix(context, GL_FLOAT_MAT4, program, location, count,
-                                          transpose))
-        {
-            return;
-        }
-
-        Program *programObject = context->getProgram(program);
-        ASSERT(programObject);
-        programObject->setUniformMatrix4fv(location, count, transpose, value);
-    }
-}
-
-void GL_APIENTRY ProgramUniformMatrix2x3fv(GLuint program,
-                                           GLint location,
-                                           GLsizei count,
-                                           GLboolean transpose,
-                                           const GLfloat *value)
-{
-    EVENT(
-        "(GLuint program = %u, GLint location = %d, GLsizei count = %d, GLboolean transpose = %u, "
-        "const GLfloat* value = 0x%0.8p)",
-        program, location, count, transpose, value);
-    Context *context = GetValidGlobalContext();
-    if (context)
-    {
-        if (!ValidateProgramUniformMatrix(context, GL_FLOAT_MAT2x3, program, location, count,
-                                          transpose))
-        {
-            return;
-        }
-
-        Program *programObject = context->getProgram(program);
-        ASSERT(programObject);
-        programObject->setUniformMatrix2x3fv(location, count, transpose, value);
-    }
-}
-
-void GL_APIENTRY ProgramUniformMatrix3x2fv(GLuint program,
-                                           GLint location,
-                                           GLsizei count,
-                                           GLboolean transpose,
-                                           const GLfloat *value)
-{
-    EVENT(
-        "(GLuint program = %u, GLint location = %d, GLsizei count = %d, GLboolean transpose = %u, "
-        "const GLfloat* value = 0x%0.8p)",
-        program, location, count, transpose, value);
-    Context *context = GetValidGlobalContext();
-    if (context)
-    {
-        if (!ValidateProgramUniformMatrix(context, GL_FLOAT_MAT3x2, program, location, count,
-                                          transpose))
-        {
-            return;
-        }
-
-        Program *programObject = context->getProgram(program);
-        ASSERT(programObject);
-        programObject->setUniformMatrix3x2fv(location, count, transpose, value);
-    }
-}
-
-void GL_APIENTRY ProgramUniformMatrix2x4fv(GLuint program,
-                                           GLint location,
-                                           GLsizei count,
-                                           GLboolean transpose,
-                                           const GLfloat *value)
-{
-    EVENT(
-        "(GLuint program = %u, GLint location = %d, GLsizei count = %d, GLboolean transpose = %u, "
-        "const GLfloat* value = 0x%0.8p)",
-        program, location, count, transpose, value);
-    Context *context = GetValidGlobalContext();
-    if (context)
-    {
-        if (!ValidateProgramUniformMatrix(context, GL_FLOAT_MAT2x4, program, location, count,
-                                          transpose))
-        {
-            return;
-        }
-
-        Program *programObject = context->getProgram(program);
-        ASSERT(programObject);
-        programObject->setUniformMatrix2x4fv(location, count, transpose, value);
-    }
-}
-
-void GL_APIENTRY ProgramUniformMatrix4x2fv(GLuint program,
-                                           GLint location,
-                                           GLsizei count,
-                                           GLboolean transpose,
-                                           const GLfloat *value)
-{
-    EVENT(
-        "(GLuint program = %u, GLint location = %d, GLsizei count = %d, GLboolean transpose = %u, "
-        "const GLfloat* value = 0x%0.8p)",
-        program, location, count, transpose, value);
-    Context *context = GetValidGlobalContext();
-    if (context)
-    {
-        if (!ValidateProgramUniformMatrix(context, GL_FLOAT_MAT4x2, program, location, count,
-                                          transpose))
-        {
-            return;
-        }
-
-        Program *programObject = context->getProgram(program);
-        ASSERT(programObject);
-        programObject->setUniformMatrix4x2fv(location, count, transpose, value);
-    }
-}
-
-void GL_APIENTRY ProgramUniformMatrix3x4fv(GLuint program,
-                                           GLint location,
-                                           GLsizei count,
-                                           GLboolean transpose,
-                                           const GLfloat *value)
-{
-    EVENT(
-        "(GLuint program = %u, GLint location = %d, GLsizei count = %d, GLboolean transpose = %u, "
-        "const GLfloat* value = 0x%0.8p)",
-        program, location, count, transpose, value);
-    Context *context = GetValidGlobalContext();
-    if (context)
-    {
-        if (!ValidateProgramUniformMatrix(context, GL_FLOAT_MAT3x4, program, location, count,
-                                          transpose))
-        {
-            return;
-        }
-
-        Program *programObject = context->getProgram(program);
-        ASSERT(programObject);
-        programObject->setUniformMatrix3x4fv(location, count, transpose, value);
-    }
-}
-
-void GL_APIENTRY ProgramUniformMatrix4x3fv(GLuint program,
-                                           GLint location,
-                                           GLsizei count,
-                                           GLboolean transpose,
-                                           const GLfloat *value)
-{
-    EVENT(
-        "(GLuint program = %u, GLint location = %d, GLsizei count = %d, GLboolean transpose = %u, "
-        "const GLfloat* value = 0x%0.8p)",
-        program, location, count, transpose, value);
-    Context *context = GetValidGlobalContext();
-    if (context)
-    {
-        if (!ValidateProgramUniformMatrix(context, GL_FLOAT_MAT4x3, program, location, count,
-                                          transpose))
-        {
-            return;
-        }
-
-        Program *programObject = context->getProgram(program);
-        ASSERT(programObject);
-        programObject->setUniformMatrix4x3fv(location, count, transpose, value);
-    }
-}
-
-void GL_APIENTRY ValidateProgramPipeline(GLuint pipeline)
-{
-    EVENT("(GLuint pipeline = %u)", pipeline);
-    Context *context = GetValidGlobalContext();
-    if (context)
-    {
-        if (!context->skipValidation())
-        {
-            context->handleError(InvalidOperation() << "Entry point not implemented");
-        }
-        UNIMPLEMENTED();
-    }
-}
-
-void GL_APIENTRY GetProgramPipelineInfoLog(GLuint pipeline,
-                                           GLsizei bufSize,
-                                           GLsizei *length,
-                                           GLchar *infoLog)
-{
-    EVENT(
-        "(GLuint pipeline = %u, GLsizei bufSize = %d, GLsizei* length = 0x%0.8p, GLchar* infoLog = "
-        "0x%0.8p)",
-        pipeline, bufSize, length, infoLog);
-    Context *context = GetValidGlobalContext();
-    if (context)
-    {
-        if (!context->skipValidation())
-        {
-            context->handleError(InvalidOperation() << "Entry point not implemented");
-        }
-        UNIMPLEMENTED();
-    }
-}
-
-void GL_APIENTRY BindImageTexture(GLuint unit,
-                                  GLuint texture,
-                                  GLint level,
-                                  GLboolean layered,
-                                  GLint layer,
-                                  GLenum access,
-                                  GLenum format)
-{
-    EVENT(
-        "(GLuint unit = %u, GLuint texture = %u, GLint level = %d, GLboolean layered = %u, GLint "
-        "layer = %d, GLenum access = 0x%X, GLenum format = 0x%X)",
-        unit, texture, level, layered, layer, access, format);
-    Context *context = GetValidGlobalContext();
-    if (context)
-    {
-        if (!context->skipValidation() && !ValidateBindImageTexture(context, unit, texture, level,
-                                                                    layered, layer, access, format))
-        {
-            return;
-        }
-
-        context->bindImageTexture(unit, texture, level, layered, layer, access, format);
-    }
-}
-
-void GL_APIENTRY GetBooleani_v(GLenum target, GLuint index, GLboolean *data)
-{
-    EVENT("(GLenum target = 0x%X, GLuint index = %u, GLboolean* data = 0x%0.8p)", target, index,
-          data);
-
-    Context *context = GetValidGlobalContext();
-    if (context)
-    {
-        if (!context->skipValidation() && !ValidateGetBooleani_v(context, target, index, data))
-        {
-            return;
-        }
-        context->getBooleani_v(target, index, data);
-    }
-}
-
-void GL_APIENTRY MemoryBarrier(GLbitfield barriers)
-{
-    EVENT("(GLbitfield barriers = 0x%X)", barriers);
-    Context *context = GetValidGlobalContext();
-    if (context)
-    {
-        if (!context->skipValidation())
-        {
-            context->handleError(InvalidOperation() << "Entry point not implemented");
-        }
-        UNIMPLEMENTED();
-    }
-}
-
-void GL_APIENTRY MemoryBarrierByRegion(GLbitfield barriers)
-{
-    EVENT("(GLbitfield barriers = 0x%X)", barriers);
-    Context *context = GetValidGlobalContext();
-    if (context)
-    {
-        if (!context->skipValidation())
-        {
-            context->handleError(InvalidOperation() << "Entry point not implemented");
-        }
-        UNIMPLEMENTED();
-    }
-}
-
-void GL_APIENTRY TexStorage2DMultisample(GLenum target,
-                                         GLsizei samples,
-                                         GLenum internalformat,
-                                         GLsizei width,
-                                         GLsizei height,
-                                         GLboolean fixedsamplelocations)
-{
-    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)
-    {
-        if (!context->skipValidation() &&
-            !ValidateTexStorage2DMultiSample(context, target, samples, internalformat, width,
-                                             height, fixedsamplelocations))
-        {
-            return;
-        }
-        context->texStorage2DMultisample(target, samples, internalformat, width, height,
-                                         fixedsamplelocations);
-    }
-}
-
-void GL_APIENTRY GetMultisamplefv(GLenum pname, GLuint index, GLfloat *val)
-{
-    EVENT("(GLenum pname = 0x%X, GLuint index = %u, GLfloat* val = 0x%0.8p)", pname, index, val);
-
-    Context *context = GetValidGlobalContext();
-    if (context)
-    {
-        if (!context->skipValidation() && !ValidateGetMultisamplefv(context, pname, index, val))
-        {
-            return;
-        }
-
-        context->getMultisamplefv(pname, index, val);
-    }
-}
-
-void GL_APIENTRY SampleMaski(GLuint maskNumber, GLbitfield mask)
-{
-    EVENT("(GLuint maskNumber = %u, GLbitfield mask = 0x%X)", maskNumber, mask);
-    Context *context = GetValidGlobalContext();
-    if (context)
-    {
-        if (!context->skipValidation() && !ValidateSampleMaski(context, maskNumber))
-        {
-            return;
-        }
-        context->sampleMaski(maskNumber, mask);
-    }
-}
-
-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)
-    {
-        if (!context->skipValidation() &&
-            !ValidateGetTexLevelParameteriv(context, target, level, pname, params))
-        {
-            return;
-        }
-
-        Texture *texture = context->getTargetTexture(
-            IsCubeMapTextureTarget(target) ? GL_TEXTURE_CUBE_MAP : target);
-        QueryTexLevelParameteriv(texture, target, level, pname, params);
-    }
-}
-
-void GL_APIENTRY GetTexLevelParameterfv(GLenum target, GLint level, GLenum pname, GLfloat *params)
-{
-    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)
-    {
-        if (!context->skipValidation() &&
-            !ValidateGetTexLevelParameterfv(context, target, level, pname, params))
-        {
-            return;
-        }
-
-        Texture *texture = context->getTargetTexture(
-            IsCubeMapTextureTarget(target) ? GL_TEXTURE_CUBE_MAP : target);
-        QueryTexLevelParameterfv(texture, target, level, pname, params);
-    }
-}
-
-void GL_APIENTRY BindVertexBuffer(GLuint bindingindex,
-                                  GLuint buffer,
-                                  GLintptr offset,
-                                  GLsizei stride)
-{
-    EVENT(
-        "(GLuint bindingindex = %u, GLuint buffer = %u, GLintptr offset = %d, GLsizei stride = %d)",
-        bindingindex, buffer, offset, stride);
-    Context *context = GetValidGlobalContext();
-    if (context)
-    {
-        if (!context->skipValidation() &&
-            !ValidateBindVertexBuffer(context, bindingindex, buffer, offset, stride))
-        {
-            return;
-        }
-
-        context->bindVertexBuffer(bindingindex, buffer, offset, stride);
-    }
-}
-
-void GL_APIENTRY VertexAttribFormat(GLuint attribindex,
-                                    GLint size,
-                                    GLenum type,
-                                    GLboolean normalized,
-                                    GLuint relativeoffset)
-{
-    EVENT(
-        "(GLuint attribindex = %u, GLint size = %d, GLenum type = 0x%X, GLboolean normalized = %u, "
-        "GLuint relativeoffset = %u)",
-        attribindex, size, type, normalized, relativeoffset);
-    Context *context = GetValidGlobalContext();
-    if (context)
-    {
-        if (!context->skipValidation() &&
-            !ValidateVertexAttribFormat(context, attribindex, size, type, relativeoffset, false))
-        {
-            return;
-        }
-
-        context->vertexAttribFormat(attribindex, size, type, normalized, relativeoffset);
-    }
-}
-
-void GL_APIENTRY VertexAttribIFormat(GLuint attribindex,
-                                     GLint size,
-                                     GLenum type,
-                                     GLuint relativeoffset)
-{
-    EVENT(
-        "(GLuint attribindex = %u, GLint size = %d, GLenum type = 0x%X, GLuint relativeoffset = "
-        "%u)",
-        attribindex, size, type, relativeoffset);
-    Context *context = GetValidGlobalContext();
-    if (context)
-    {
-        if (!context->skipValidation() &&
-            !ValidateVertexAttribFormat(context, attribindex, size, type, relativeoffset, true))
-        {
-            return;
-        }
-
-        context->vertexAttribIFormat(attribindex, size, type, relativeoffset);
-    }
-}
-
-void GL_APIENTRY VertexAttribBinding(GLuint attribindex, GLuint bindingindex)
-{
-    EVENT("(GLuint attribindex = %u, GLuint bindingindex = %u)", attribindex, bindingindex);
-    Context *context = GetValidGlobalContext();
-    if (context)
-    {
-        if (!context->skipValidation() &&
-            !ValidateVertexAttribBinding(context, attribindex, bindingindex))
-        {
-            return;
-        }
-
-        context->vertexAttribBinding(attribindex, bindingindex);
-    }
-}
-
-void GL_APIENTRY VertexBindingDivisor(GLuint bindingindex, GLuint divisor)
-{
-    EVENT("(GLuint bindingindex = %u, GLuint divisor = %u)", bindingindex, divisor);
-    Context *context = GetValidGlobalContext();
-    if (context)
-    {
-        if (!context->skipValidation() &&
-            !ValidateVertexBindingDivisor(context, bindingindex, divisor))
-        {
-            return;
-        }
-
-        context->setVertexBindingDivisor(bindingindex, divisor);
-    }
-}
-}  // namespace gl
deleted file mode 100644
--- a/gfx/angle/src/libGLESv2/entry_points_gles_3_1.h
+++ /dev/null
@@ -1,229 +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.
-//
-
-// entry_points_gles_3_1.h : Defines the GLES 3.1 entry points.
-
-#ifndef LIBGLESV2_ENTRYPOINTGLES31_H_
-#define LIBGLESV2_ENTRYPOINTGLES31_H_
-
-#include <GLES3/gl31.h>
-#include <export.h>
-
-// we include the platform.h header since it undefines the conflicting MemoryBarrier macro
-#include "common/platform.h"
-
-namespace gl
-{
-
-ANGLE_EXPORT void GL_APIENTRY DispatchCompute(GLuint numGroupsX,
-                                              GLuint numGroupsY,
-                                              GLuint numGroupsZ);
-ANGLE_EXPORT void GL_APIENTRY DispatchComputeIndirect(GLintptr indirect);
-ANGLE_EXPORT void GL_APIENTRY DrawArraysIndirect(GLenum mode, const void *indirect);
-ANGLE_EXPORT void GL_APIENTRY DrawElementsIndirect(GLenum mode, GLenum type, const void *indirect);
-ANGLE_EXPORT void GL_APIENTRY FramebufferParameteri(GLenum target, GLenum pname, GLint param);
-ANGLE_EXPORT void GL_APIENTRY GetFramebufferParameteriv(GLenum target, GLenum pname, GLint *params);
-ANGLE_EXPORT void GL_APIENTRY GetProgramInterfaceiv(GLuint program,
-                                                    GLenum programInterface,
-                                                    GLenum pname,
-                                                    GLint *params);
-ANGLE_EXPORT GLuint GL_APIENTRY GetProgramResourceIndex(GLuint program,
-                                                        GLenum programInterface,
-                                                        const GLchar *name);
-ANGLE_EXPORT void GL_APIENTRY GetProgramResourceName(GLuint program,
-                                                     GLenum programInterface,
-                                                     GLuint index,
-                                                     GLsizei bufSize,
-                                                     GLsizei *length,
-                                                     GLchar *name);
-ANGLE_EXPORT void GL_APIENTRY GetProgramResourceiv(GLuint program,
-                                                   GLenum programInterface,
-                                                   GLuint index,
-                                                   GLsizei propCount,
-                                                   const GLenum *props,
-                                                   GLsizei bufSize,
-                                                   GLsizei *length,
-                                                   GLint *params);
-ANGLE_EXPORT GLint GL_APIENTRY GetProgramResourceLocation(GLuint program,
-                                                          GLenum programInterface,
-                                                          const GLchar *name);
-ANGLE_EXPORT void GL_APIENTRY UseProgramStages(GLuint pipeline, GLbitfield stages, GLuint program);
-ANGLE_EXPORT void GL_APIENTRY ActiveShaderProgram(GLuint pipeline, GLuint program);
-ANGLE_EXPORT GLuint GL_APIENTRY CreateShaderProgramv(GLenum type,
-                                                     GLsizei count,
-                                                     const GLchar *const *strings);
-ANGLE_EXPORT void GL_APIENTRY BindProgramPipeline(GLuint pipeline);
-ANGLE_EXPORT void GL_APIENTRY DeleteProgramPipelines(GLsizei n, const GLuint *pipelines);
-ANGLE_EXPORT void GL_APIENTRY GenProgramPipelines(GLsizei n, GLuint *pipelines);
-ANGLE_EXPORT GLboolean GL_APIENTRY IsProgramPipeline(GLuint pipeline);
-ANGLE_EXPORT void GL_APIENTRY GetProgramPipelineiv(GLuint pipeline, GLenum pname, GLint *params);
-ANGLE_EXPORT void GL_APIENTRY ProgramUniform1i(GLuint program, GLint location, GLint v0);
-ANGLE_EXPORT void GL_APIENTRY ProgramUniform2i(GLuint program, GLint location, GLint v0, GLint v1);
-ANGLE_EXPORT void GL_APIENTRY
-ProgramUniform3i(GLuint program, GLint location, GLint v0, GLint v1, GLint v2);
-ANGLE_EXPORT void GL_APIENTRY
-ProgramUniform4i(GLuint program, GLint location, GLint v0, GLint v1, GLint v2, GLint v3);
-ANGLE_EXPORT void GL_APIENTRY ProgramUniform1ui(GLuint program, GLint location, GLuint v0);
-ANGLE_EXPORT void GL_APIENTRY ProgramUniform2ui(GLuint program,
-                                                GLint location,
-                                                GLuint v0,
-                                                GLuint v1);
-ANGLE_EXPORT void GL_APIENTRY
-ProgramUniform3ui(GLuint program, GLint location, GLuint v0, GLuint v1, GLuint v2);
-ANGLE_EXPORT void GL_APIENTRY
-ProgramUniform4ui(GLuint program, GLint location, GLuint v0, GLuint v1, GLuint v2, GLuint v3);
-ANGLE_EXPORT void GL_APIENTRY ProgramUniform1f(GLuint program, GLint location, GLfloat v0);
-ANGLE_EXPORT void GL_APIENTRY ProgramUniform2f(GLuint program,
-                                               GLint location,
-                                               GLfloat v0,
-                                               GLfloat v1);
-ANGLE_EXPORT void GL_APIENTRY
-ProgramUniform3f(GLuint program, GLint location, GLfloat v0, GLfloat v1, GLfloat v2);
-ANGLE_EXPORT void GL_APIENTRY
-ProgramUniform4f(GLuint program, GLint location, GLfloat v0, GLfloat v1, GLfloat v2, GLfloat v3);
-ANGLE_EXPORT void GL_APIENTRY ProgramUniform1iv(GLuint program,
-                                                GLint location,
-                                                GLsizei count,
-                                                const GLint *value);
-ANGLE_EXPORT void GL_APIENTRY ProgramUniform2iv(GLuint program,
-                                                GLint location,
-                                                GLsizei count,
-                                                const GLint *value);
-ANGLE_EXPORT void GL_APIENTRY ProgramUniform3iv(GLuint program,
-                                                GLint location,
-                                                GLsizei count,
-                                                const GLint *value);
-ANGLE_EXPORT void GL_APIENTRY ProgramUniform4iv(GLuint program,
-                                                GLint location,
-                                                GLsizei count,
-                                                const GLint *value);
-ANGLE_EXPORT void GL_APIENTRY ProgramUniform1uiv(GLuint program,
-                                                 GLint location,
-                                                 GLsizei count,
-                                                 const GLuint *value);
-ANGLE_EXPORT void GL_APIENTRY ProgramUniform2uiv(GLuint program,
-                                                 GLint location,
-                                                 GLsizei count,
-                                                 const GLuint *value);
-ANGLE_EXPORT void GL_APIENTRY ProgramUniform3uiv(GLuint program,
-                                                 GLint location,
-                                                 GLsizei count,
-                                                 const GLuint *value);
-ANGLE_EXPORT void GL_APIENTRY ProgramUniform4uiv(GLuint program,
-                                                 GLint location,
-                                                 GLsizei count,
-                                                 const GLuint *value);
-ANGLE_EXPORT void GL_APIENTRY ProgramUniform1fv(GLuint program,
-                                                GLint location,
-                                                GLsizei count,
-                                                const GLfloat *value);
-ANGLE_EXPORT void GL_APIENTRY ProgramUniform2fv(GLuint program,
-                                                GLint location,
-                                                GLsizei count,
-                                                const GLfloat *value);
-ANGLE_EXPORT void GL_APIENTRY ProgramUniform3fv(GLuint program,
-                                                GLint location,
-                                                GLsizei count,
-                                                const GLfloat *value);
-ANGLE_EXPORT void GL_APIENTRY ProgramUniform4fv(GLuint program,
-                                                GLint location,
-                                                GLsizei count,
-                                                const GLfloat *value);
-ANGLE_EXPORT void GL_APIENTRY ProgramUniformMatrix2fv(GLuint program,
-                                                      GLint location,
-                                                      GLsizei count,
-                                                      GLboolean transpose,
-                                                      const GLfloat *value);
-ANGLE_EXPORT void GL_APIENTRY ProgramUniformMatrix3fv(GLuint program,
-                                                      GLint location,
-                                                      GLsizei count,
-                                                      GLboolean transpose,
-                                                      const GLfloat *value);
-ANGLE_EXPORT void GL_APIENTRY ProgramUniformMatrix4fv(GLuint program,
-                                                      GLint location,
-                                                      GLsizei count,
-                                                      GLboolean transpose,
-                                                      const GLfloat *value);
-ANGLE_EXPORT void GL_APIENTRY ProgramUniformMatrix2x3fv(GLuint program,
-                                                        GLint location,
-                                                        GLsizei count,
-                                                        GLboolean transpose,
-                                                        const GLfloat *value);
-ANGLE_EXPORT void GL_APIENTRY ProgramUniformMatrix3x2fv(GLuint program,
-                                                        GLint location,
-                                                        GLsizei count,
-                                                        GLboolean transpose,
-                                                        const GLfloat *value);
-ANGLE_EXPORT void GL_APIENTRY ProgramUniformMatrix2x4fv(GLuint program,
-                                                        GLint location,
-                                                        GLsizei count,
-                                                        GLboolean transpose,
-                                                        const GLfloat *value);
-ANGLE_EXPORT void GL_APIENTRY ProgramUniformMatrix4x2fv(GLuint program,
-                                                        GLint location,
-                                                        GLsizei count,
-                                                        GLboolean transpose,
-                                                        const GLfloat *value);
-ANGLE_EXPORT void GL_APIENTRY ProgramUniformMatrix3x4fv(GLuint program,
-                                                        GLint location,
-                                                        GLsizei count,
-                                                        GLboolean transpose,
-                                                        const GLfloat *value);
-ANGLE_EXPORT void GL_APIENTRY ProgramUniformMatrix4x3fv(GLuint program,
-                                                        GLint location,
-                                                        GLsizei count,
-                                                        GLboolean transpose,
-                                                        const GLfloat *value);
-ANGLE_EXPORT void GL_APIENTRY ValidateProgramPipeline(GLuint pipeline);
-ANGLE_EXPORT void GL_APIENTRY GetProgramPipelineInfoLog(GLuint pipeline,
-                                                        GLsizei bufSize,
-                                                        GLsizei *length,
-                                                        GLchar *infoLog);
-ANGLE_EXPORT void GL_APIENTRY BindImageTexture(GLuint unit,
-                                               GLuint texture,
-                                               GLint level,
-                                               GLboolean layered,
-                                               GLint layer,
-                                               GLenum access,
-                                               GLenum format);
-ANGLE_EXPORT void GL_APIENTRY GetBooleani_v(GLenum target, GLuint index, GLboolean *data);
-
-ANGLE_EXPORT void GL_APIENTRY MemoryBarrier(GLbitfield barriers);
-ANGLE_EXPORT void GL_APIENTRY MemoryBarrierByRegion(GLbitfield barriers);
-ANGLE_EXPORT void GL_APIENTRY TexStorage2DMultisample(GLenum target,
-                                                      GLsizei samples,
-                                                      GLenum internalformat,
-                                                      GLsizei width,
-                                                      GLsizei height,
-                                                      GLboolean fixedsamplelocations);
-ANGLE_EXPORT void GL_APIENTRY GetMultisamplefv(GLenum pname, GLuint index, GLfloat *val);
-ANGLE_EXPORT void GL_APIENTRY SampleMaski(GLuint maskNumber, GLbitfield mask);
-ANGLE_EXPORT void GL_APIENTRY GetTexLevelParameteriv(GLenum target,
-                                                     GLint level,
-                                                     GLenum pname,
-                                                     GLint *params);
-ANGLE_EXPORT void GL_APIENTRY GetTexLevelParameterfv(GLenum target,
-                                                     GLint level,
-                                                     GLenum pname,
-                                                     GLfloat *params);
-ANGLE_EXPORT void GL_APIENTRY BindVertexBuffer(GLuint bindingindex,
-                                               GLuint buffer,
-                                               GLintptr offset,
-                                               GLsizei stride);
-ANGLE_EXPORT void GL_APIENTRY VertexAttribFormat(GLuint attribindex,
-                                                 GLint size,
-                                                 GLenum type,
-                                                 GLboolean normalized,
-                                                 GLuint relativeoffset);
-ANGLE_EXPORT void GL_APIENTRY VertexAttribIFormat(GLuint attribindex,
-                                                  GLint size,
-                                                  GLenum type,
-                                                  GLuint relativeoffset);
-ANGLE_EXPORT void GL_APIENTRY VertexAttribBinding(GLuint attribindex, GLuint bindingindex);
-ANGLE_EXPORT void GL_APIENTRY VertexBindingDivisor(GLuint bindingindex, GLuint divisor);
-};
-
-#endif  // LIBGLESV2_ENTRYPOINTGLES31_H_
new file mode 100644
--- /dev/null
+++ b/gfx/angle/src/libGLESv2/entry_points_gles_3_1_autogen.cpp
@@ -0,0 +1,1430 @@
+// 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.
+//
+// entry_points_gles_3_1_autogen.cpp:
+//   Defines the GLES 3.1 entry points.
+
+#include "libANGLE/Context.h"
+#include "libANGLE/validationES31.h"
+#include "libGLESv2/global_state.h"
+
+namespace gl
+{
+void GL_APIENTRY ActiveShaderProgram(GLuint pipeline, GLuint program)
+{
+    EVENT("(GLuint pipeline = %u, GLuint program = %u)", pipeline, program);
+
+    Context *context = GetValidGlobalContext();
+    if (context)
+    {
+        context->gatherParams<EntryPoint::ActiveShaderProgram>(pipeline, program);
+
+        if (context->skipValidation() || ValidateActiveShaderProgram(context, pipeline, program))
+        {
+            context->activeShaderProgram(pipeline, program);
+        }
+    }
+}
+
+void GL_APIENTRY BindImageTexture(GLuint unit,
+                                  GLuint texture,
+                                  GLint level,
+                                  GLboolean layered,
+                                  GLint layer,
+                                  GLenum access,
+                                  GLenum format)
+{
+    EVENT(
+        "(GLuint unit = %u, GLuint texture = %u, GLint level = %d, GLboolean layered = %u, GLint "
+        "layer = %d, GLenum access = 0x%X, GLenum format = 0x%X)",
+        unit, texture, level, layered, layer, access, format);
+
+    Context *context = GetValidGlobalContext();
+    if (context)
+    {
+        context->gatherParams<EntryPoint::BindImageTexture>(unit, texture, level, layered, layer,
+                                                            access, format);
+
+        if (context->skipValidation() ||
+            ValidateBindImageTexture(context, unit, texture, level, layered, layer, access, format))
+        {
+            context->bindImageTexture(unit, texture, level, layered, layer, access, format);
+        }
+    }
+}
+
+void GL_APIENTRY BindProgramPipeline(GLuint pipeline)
+{
+    EVENT("(GLuint pipeline = %u)", pipeline);
+
+    Context *context = GetValidGlobalContext();
+    if (context)
+    {
+        context->gatherParams<EntryPoint::BindProgramPipeline>(pipeline);
+
+        if (context->skipValidation() || ValidateBindProgramPipeline(context, pipeline))
+        {
+            context->bindProgramPipeline(pipeline);
+        }
+    }
+}
+
+void GL_APIENTRY BindVertexBuffer(GLuint bindingindex,
+                                  GLuint buffer,
+                                  GLintptr offset,
+                                  GLsizei stride)
+{
+    EVENT(
+        "(GLuint bindingindex = %u, GLuint buffer = %u, GLintptr offset = %d, GLsizei stride = %d)",
+        bindingindex, buffer, offset, stride);
+
+    Context *context = GetValidGlobalContext();
+    if (context)
+    {
+        context->gatherParams<EntryPoint::BindVertexBuffer>(bindingindex, buffer, offset, stride);
+
+        if (context->skipValidation() ||
+            ValidateBindVertexBuffer(context, bindingindex, buffer, offset, stride))
+        {
+            context->bindVertexBuffer(bindingindex, buffer, offset, stride);
+        }
+    }
+}
+
+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);
+
+        if (context->skipValidation() ||
+            ValidateCreateShaderProgramv(context, type, count, strings))
+        {
+            return context->createShaderProgramv(type, count, strings);
+        }
+    }
+
+    return GetDefaultReturnValue<EntryPoint::CreateShaderProgramv, GLuint>();
+}
+
+void GL_APIENTRY DeleteProgramPipelines(GLsizei n, const GLuint *pipelines)
+{
+    EVENT("(GLsizei n = %d, const GLuint *pipelines = 0x%0.8p)", n, pipelines);
+
+    Context *context = GetValidGlobalContext();
+    if (context)
+    {
+        context->gatherParams<EntryPoint::DeleteProgramPipelines>(n, pipelines);
+
+        if (context->skipValidation() || ValidateDeleteProgramPipelines(context, n, pipelines))
+        {
+            context->deleteProgramPipelines(n, pipelines);
+        }
+    }
+}
+
+void GL_APIENTRY DispatchCompute(GLuint num_groups_x, GLuint num_groups_y, GLuint num_groups_z)
+{
+    EVENT("(GLuint num_groups_x = %u, GLuint num_groups_y = %u, GLuint num_groups_z = %u)",
+          num_groups_x, num_groups_y, num_groups_z);
+
+    Context *context = GetValidGlobalContext();
+    if (context)
+    {
+        context->gatherParams<EntryPoint::DispatchCompute>(num_groups_x, num_groups_y,
+                                                           num_groups_z);
+
+        if (context->skipValidation() ||
+            ValidateDispatchCompute(context, num_groups_x, num_groups_y, num_groups_z))
+        {
+            context->dispatchCompute(num_groups_x, num_groups_y, num_groups_z);
+        }
+    }
+}
+
+void GL_APIENTRY DispatchComputeIndirect(GLintptr indirect)
+{
+    EVENT("(GLintptr indirect = %d)", indirect);
+
+    Context *context = GetValidGlobalContext();
+    if (context)
+    {
+        context->gatherParams<EntryPoint::DispatchComputeIndirect>(indirect);
+
+        if (context->skipValidation() || ValidateDispatchComputeIndirect(context, indirect))
+        {
+            context->dispatchComputeIndirect(indirect);
+        }
+    }
+}
+
+void GL_APIENTRY DrawArraysIndirect(GLenum mode, const void *indirect)
+{
+    EVENT("(GLenum mode = 0x%X, const void *indirect = 0x%0.8p)", mode, indirect);
+
+    Context *context = GetValidGlobalContext();
+    if (context)
+    {
+        context->gatherParams<EntryPoint::DrawArraysIndirect>(mode, indirect);
+
+        if (context->skipValidation() || ValidateDrawArraysIndirect(context, mode, indirect))
+        {
+            context->drawArraysIndirect(mode, indirect);
+        }
+    }
+}
+
+void GL_APIENTRY DrawElementsIndirect(GLenum mode, GLenum type, const void *indirect)
+{
+    EVENT("(GLenum mode = 0x%X, GLenum type = 0x%X, const void *indirect = 0x%0.8p)", mode, type,
+          indirect);
+
+    Context *context = GetValidGlobalContext();
+    if (context)
+    {
+        context->gatherParams<EntryPoint::DrawElementsIndirect>(mode, type, indirect);
+
+        if (context->skipValidation() ||
+            ValidateDrawElementsIndirect(context, mode, type, indirect))
+        {
+            context->drawElementsIndirect(mode, type, indirect);
+        }
+    }
+}
+
+void GL_APIENTRY FramebufferParameteri(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::FramebufferParameteri>(target, pname, param);
+
+        if (context->skipValidation() ||
+            ValidateFramebufferParameteri(context, target, pname, param))
+        {
+            context->framebufferParameteri(target, pname, param);
+        }
+    }
+}
+
+void GL_APIENTRY GenProgramPipelines(GLsizei n, GLuint *pipelines)
+{
+    EVENT("(GLsizei n = %d, GLuint *pipelines = 0x%0.8p)", n, pipelines);
+
+    Context *context = GetValidGlobalContext();
+    if (context)
+    {
+        context->gatherParams<EntryPoint::GenProgramPipelines>(n, pipelines);
+
+        if (context->skipValidation() || ValidateGenProgramPipelines(context, n, pipelines))
+        {
+            context->genProgramPipelines(n, pipelines);
+        }
+    }
+}
+
+void GL_APIENTRY GetBooleani_v(GLenum target, GLuint index, GLboolean *data)
+{
+    EVENT("(GLenum target = 0x%X, GLuint index = %u, GLboolean *data = 0x%0.8p)", target, index,
+          data);
+
+    Context *context = GetValidGlobalContext();
+    if (context)
+    {
+        context->gatherParams<EntryPoint::GetBooleani_v>(target, index, data);
+
+        if (context->skipValidation() || ValidateGetBooleani_v(context, target, index, data))
+        {
+            context->getBooleani_v(target, index, data);
+        }
+    }
+}
+
+void GL_APIENTRY GetFramebufferParameteriv(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::GetFramebufferParameteriv>(target, pname, params);
+
+        if (context->skipValidation() ||
+            ValidateGetFramebufferParameteriv(context, target, pname, params))
+        {
+            context->getFramebufferParameteriv(target, pname, params);
+        }
+    }
+}
+
+void GL_APIENTRY GetMultisamplefv(GLenum pname, GLuint index, GLfloat *val)
+{
+    EVENT("(GLenum pname = 0x%X, GLuint index = %u, GLfloat *val = 0x%0.8p)", pname, index, val);
+
+    Context *context = GetValidGlobalContext();
+    if (context)
+    {
+        context->gatherParams<EntryPoint::GetMultisamplefv>(pname, index, val);
+
+        if (context->skipValidation() || ValidateGetMultisamplefv(context, pname, index, val))
+        {
+            context->getMultisamplefv(pname, index, val);
+        }
+    }
+}
+
+void GL_APIENTRY GetProgramInterfaceiv(GLuint program,
+                                       GLenum programInterface,
+                                       GLenum pname,
+                                       GLint *params)
+{
+    EVENT(
+        "(GLuint program = %u, GLenum programInterface = 0x%X, GLenum pname = 0x%X, GLint *params "
+        "= 0x%0.8p)",
+        program, programInterface, pname, params);
+
+    Context *context = GetValidGlobalContext();
+    if (context)
+    {
+        context->gatherParams<EntryPoint::GetProgramInterfaceiv>(program, programInterface, pname,
+                                                                 params);
+
+        if (context->skipValidation() ||
+            ValidateGetProgramInterfaceiv(context, program, programInterface, pname, params))
+        {
+            context->getProgramInterfaceiv(program, programInterface, pname, params);
+        }
+    }
+}
+
+void GL_APIENTRY GetProgramPipelineInfoLog(GLuint pipeline,
+                                           GLsizei bufSize,
+                                           GLsizei *length,
+                                           GLchar *infoLog)
+{
+    EVENT(
+        "(GLuint pipeline = %u, GLsizei bufSize = %d, GLsizei *length = 0x%0.8p, GLchar *infoLog = "
+        "0x%0.8p)",
+        pipeline, bufSize, length, infoLog);
+
+    Context *context = GetValidGlobalContext();
+    if (context)
+    {
+        context->gatherParams<EntryPoint::GetProgramPipelineInfoLog>(pipeline, bufSize, length,
+                                                                     infoLog);
+
+        if (context->skipValidation() ||
+            ValidateGetProgramPipelineInfoLog(context, pipeline, bufSize, length, infoLog))
+        {
+            context->getProgramPipelineInfoLog(pipeline, bufSize, length, infoLog);
+        }
+    }
+}
+
+void GL_APIENTRY GetProgramPipelineiv(GLuint pipeline, GLenum pname, GLint *params)
+{
+    EVENT("(GLuint pipeline = %u, GLenum pname = 0x%X, GLint *params = 0x%0.8p)", pipeline, pname,
+          params);
+
+    Context *context = GetValidGlobalContext();
+    if (context)
+    {
+        context->gatherParams<EntryPoint::GetProgramPipelineiv>(pipeline, pname, params);
+
+        if (context->skipValidation() ||
+            ValidateGetProgramPipelineiv(context, pipeline, pname, params))
+        {
+            context->getProgramPipelineiv(pipeline, pname, params);
+        }
+    }
+}
+
+GLuint GL_APIENTRY GetProgramResourceIndex(GLuint program,
+                                           GLenum programInterface,
+                                           const GLchar *name)
+{
+    EVENT("(GLuint program = %u, GLenum programInterface = 0x%X, const GLchar *name = 0x%0.8p)",
+          program, programInterface, name);
+
+    Context *context = GetValidGlobalContext();
+    if (context)
+    {
+        context->gatherParams<EntryPoint::GetProgramResourceIndex>(program, programInterface, name);
+
+        if (context->skipValidation() ||
+            ValidateGetProgramResourceIndex(context, program, programInterface, name))
+        {
+            return context->getProgramResourceIndex(program, programInterface, name);
+        }
+    }
+
+    return GetDefaultReturnValue<EntryPoint::GetProgramResourceIndex, GLuint>();
+}
+
+GLint GL_APIENTRY GetProgramResourceLocation(GLuint program,
+                                             GLenum programInterface,
+                                             const GLchar *name)
+{
+    EVENT("(GLuint program = %u, GLenum programInterface = 0x%X, const GLchar *name = 0x%0.8p)",
+          program, programInterface, name);
+
+    Context *context = GetValidGlobalContext();
+    if (context)
+    {
+        context->gatherParams<EntryPoint::GetProgramResourceLocation>(program, programInterface,
+                                                                      name);
+
+        if (context->skipValidation() ||
+            ValidateGetProgramResourceLocation(context, program, programInterface, name))
+        {
+            return context->getProgramResourceLocation(program, programInterface, name);
+        }
+    }
+
+    return GetDefaultReturnValue<EntryPoint::GetProgramResourceLocation, GLint>();
+}
+
+void GL_APIENTRY GetProgramResourceName(GLuint program,
+                                        GLenum programInterface,
+                                        GLuint index,
+                                        GLsizei bufSize,
+                                        GLsizei *length,
+                                        GLchar *name)
+{
+    EVENT(
+        "(GLuint program = %u, GLenum programInterface = 0x%X, GLuint index = %u, GLsizei bufSize "
+        "= %d, GLsizei *length = 0x%0.8p, GLchar *name = 0x%0.8p)",
+        program, programInterface, index, bufSize, length, name);
+
+    Context *context = GetValidGlobalContext();
+    if (context)
+    {
+        context->gatherParams<EntryPoint::GetProgramResourceName>(program, programInterface, index,
+                                                                  bufSize, length, name);
+
+        if (context->skipValidation() ||
+            ValidateGetProgramResourceName(context, program, programInterface, index, bufSize,
+                                           length, name))
+        {
+            context->getProgramResourceName(program, programInterface, index, bufSize, length,
+                                            name);
+        }
+    }
+}
+
+void GL_APIENTRY GetProgramResourceiv(GLuint program,
+                                      GLenum programInterface,
+                                      GLuint index,
+                                      GLsizei propCount,
+                                      const GLenum *props,
+                                      GLsizei bufSize,
+                                      GLsizei *length,
+                                      GLint *params)
+{
+    EVENT(
+        "(GLuint program = %u, GLenum programInterface = 0x%X, GLuint index = %u, GLsizei "
+        "propCount = %d, const GLenum *props = 0x%0.8p, GLsizei bufSize = %d, GLsizei *length = "
+        "0x%0.8p, GLint *params = 0x%0.8p)",
+        program, programInterface, index, propCount, props, bufSize, length, params);
+
+    Context *context = GetValidGlobalContext();
+    if (context)
+    {
+        context->gatherParams<EntryPoint::GetProgramResourceiv>(
+            program, programInterface, index, propCount, props, bufSize, length, params);
+
+        if (context->skipValidation() ||
+            ValidateGetProgramResourceiv(context, program, programInterface, index, propCount,
+                                         props, bufSize, length, params))
+        {
+            context->getProgramResourceiv(program, programInterface, index, propCount, props,
+                                          bufSize, length, params);
+        }
+    }
+}
+
+void GL_APIENTRY GetTexLevelParameterfv(GLenum target, GLint level, GLenum pname, GLfloat *params)
+{
+    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);
+
+        if (context->skipValidation() ||
+            ValidateGetTexLevelParameterfv(context, target, level, pname, params))
+        {
+            context->getTexLevelParameterfv(target, 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);
+
+        if (context->skipValidation() ||
+            ValidateGetTexLevelParameteriv(context, target, level, pname, params))
+        {
+            context->getTexLevelParameteriv(target, level, pname, params);
+        }
+    }
+}
+
+GLboolean GL_APIENTRY IsProgramPipeline(GLuint pipeline)
+{
+    EVENT("(GLuint pipeline = %u)", pipeline);
+
+    Context *context = GetValidGlobalContext();
+    if (context)
+    {
+        context->gatherParams<EntryPoint::IsProgramPipeline>(pipeline);
+
+        if (context->skipValidation() || ValidateIsProgramPipeline(context, pipeline))
+        {
+            return context->isProgramPipeline(pipeline);
+        }
+    }
+
+    return GetDefaultReturnValue<EntryPoint::IsProgramPipeline, GLboolean>();
+}
+
+void GL_APIENTRY MemoryBarrier(GLbitfield barriers)
+{
+    EVENT("(GLbitfield barriers = 0x%X)", barriers);
+
+    Context *context = GetValidGlobalContext();
+    if (context)
+    {
+        context->gatherParams<EntryPoint::MemoryBarrier>(barriers);
+
+        if (context->skipValidation() || ValidateMemoryBarrier(context, barriers))
+        {
+            context->memoryBarrier(barriers);
+        }
+    }
+}
+
+void GL_APIENTRY MemoryBarrierByRegion(GLbitfield barriers)
+{
+    EVENT("(GLbitfield barriers = 0x%X)", barriers);
+
+    Context *context = GetValidGlobalContext();
+    if (context)
+    {
+        context->gatherParams<EntryPoint::MemoryBarrierByRegion>(barriers);
+
+        if (context->skipValidation() || ValidateMemoryBarrierByRegion(context, barriers))
+        {
+            context->memoryBarrierByRegion(barriers);
+        }
+    }
+}
+
+void GL_APIENTRY ProgramUniform1f(GLuint program, GLint location, GLfloat v0)
+{
+    EVENT("(GLuint program = %u, GLint location = %d, GLfloat v0 = %f)", program, location, v0);
+
+    Context *context = GetValidGlobalContext();
+    if (context)
+    {
+        context->gatherParams<EntryPoint::ProgramUniform1f>(program, location, v0);
+
+        if (context->skipValidation() || ValidateProgramUniform1f(context, program, location, v0))
+        {
+            context->programUniform1f(program, location, v0);
+        }
+    }
+}
+
+void GL_APIENTRY ProgramUniform1fv(GLuint program,
+                                   GLint location,
+                                   GLsizei count,
+                                   const GLfloat *value)
+{
+    EVENT(
+        "(GLuint program = %u, GLint location = %d, GLsizei count = %d, const GLfloat *value = "
+        "0x%0.8p)",
+        program, location, count, value);
+
+    Context *context = GetValidGlobalContext();
+    if (context)
+    {
+        context->gatherParams<EntryPoint::ProgramUniform1fv>(program, location, count, value);
+
+        if (context->skipValidation() ||
+            ValidateProgramUniform1fv(context, program, location, count, value))
+        {
+            context->programUniform1fv(program, location, count, value);
+        }
+    }
+}
+
+void GL_APIENTRY ProgramUniform1i(GLuint program, GLint location, GLint v0)
+{
+    EVENT("(GLuint program = %u, GLint location = %d, GLint v0 = %d)", program, location, v0);
+
+    Context *context = GetValidGlobalContext();
+    if (context)
+    {
+        context->gatherParams<EntryPoint::ProgramUniform1i>(program, location, v0);
+
+        if (context->skipValidation() || ValidateProgramUniform1i(context, program, location, v0))
+        {
+            context->programUniform1i(program, location, v0);
+        }
+    }
+}
+
+void GL_APIENTRY ProgramUniform1iv(GLuint program,
+                                   GLint location,
+                                   GLsizei count,
+                                   const GLint *value)
+{
+    EVENT(
+        "(GLuint program = %u, GLint location = %d, GLsizei count = %d, const GLint *value = "
+        "0x%0.8p)",
+        program, location, count, value);
+
+    Context *context = GetValidGlobalContext();
+    if (context)
+    {
+        context->gatherParams<EntryPoint::ProgramUniform1iv>(program, location, count, value);
+
+        if (context->skipValidation() ||
+            ValidateProgramUniform1iv(context, program, location, count, value))
+        {
+            context->programUniform1iv(program, location, count, value);
+        }
+    }
+}
+
+void GL_APIENTRY ProgramUniform1ui(GLuint program, GLint location, GLuint v0)
+{
+    EVENT("(GLuint program = %u, GLint location = %d, GLuint v0 = %u)", program, location, v0);
+
+    Context *context = GetValidGlobalContext();
+    if (context)
+    {
+        context->gatherParams<EntryPoint::ProgramUniform1ui>(program, location, v0);
+
+        if (context->skipValidation() || ValidateProgramUniform1ui(context, program, location, v0))
+        {
+            context->programUniform1ui(program, location, v0);
+        }
+    }
+}
+
+void GL_APIENTRY ProgramUniform1uiv(GLuint program,
+                                    GLint location,
+                                    GLsizei count,
+                                    const GLuint *value)
+{
+    EVENT(
+        "(GLuint program = %u, GLint location = %d, GLsizei count = %d, const GLuint *value = "
+        "0x%0.8p)",
+        program, location, count, value);
+
+    Context *context = GetValidGlobalContext();
+    if (context)
+    {
+        context->gatherParams<EntryPoint::ProgramUniform1uiv>(program, location, count, value);
+
+        if (context->skipValidation() ||
+            ValidateProgramUniform1uiv(context, program, location, count, value))
+        {
+            context->programUniform1uiv(program, location, count, value);
+        }
+    }
+}
+
+void GL_APIENTRY ProgramUniform2f(GLuint program, GLint location, GLfloat v0, GLfloat v1)
+{
+    EVENT("(GLuint program = %u, GLint location = %d, GLfloat v0 = %f, GLfloat v1 = %f)", program,
+          location, v0, v1);
+
+    Context *context = GetValidGlobalContext();
+    if (context)
+    {
+        context->gatherParams<EntryPoint::ProgramUniform2f>(program, location, v0, v1);
+
+        if (context->skipValidation() ||
+            ValidateProgramUniform2f(context, program, location, v0, v1))
+        {
+            context->programUniform2f(program, location, v0, v1);
+        }
+    }
+}
+
+void GL_APIENTRY ProgramUniform2fv(GLuint program,
+                                   GLint location,
+                                   GLsizei count,
+                                   const GLfloat *value)
+{
+    EVENT(
+        "(GLuint program = %u, GLint location = %d, GLsizei count = %d, const GLfloat *value = "
+        "0x%0.8p)",
+        program, location, count, value);
+
+    Context *context = GetValidGlobalContext();
+    if (context)
+    {
+        context->gatherParams<EntryPoint::ProgramUniform2fv>(program, location, count, value);
+
+        if (context->skipValidation() ||
+            ValidateProgramUniform2fv(context, program, location, count, value))
+        {
+            context->programUniform2fv(program, location, count, value);
+        }
+    }
+}
+
+void GL_APIENTRY ProgramUniform2i(GLuint program, GLint location, GLint v0, GLint v1)
+{
+    EVENT("(GLuint program = %u, GLint location = %d, GLint v0 = %d, GLint v1 = %d)", program,
+          location, v0, v1);
+
+    Context *context = GetValidGlobalContext();
+    if (context)
+    {
+        context->gatherParams<EntryPoint::ProgramUniform2i>(program, location, v0, v1);
+
+        if (context->skipValidation() ||
+            ValidateProgramUniform2i(context, program, location, v0, v1))
+        {
+            context->programUniform2i(program, location, v0, v1);
+        }
+    }
+}
+
+void GL_APIENTRY ProgramUniform2iv(GLuint program,
+                                   GLint location,
+                                   GLsizei count,
+                                   const GLint *value)
+{
+    EVENT(
+        "(GLuint program = %u, GLint location = %d, GLsizei count = %d, const GLint *value = "
+        "0x%0.8p)",
+        program, location, count, value);
+
+    Context *context = GetValidGlobalContext();
+    if (context)
+    {
+        context->gatherParams<EntryPoint::ProgramUniform2iv>(program, location, count, value);
+
+        if (context->skipValidation() ||
+            ValidateProgramUniform2iv(context, program, location, count, value))
+        {
+            context->programUniform2iv(program, location, count, value);
+        }
+    }
+}
+
+void GL_APIENTRY ProgramUniform2ui(GLuint program, GLint location, GLuint v0, GLuint v1)
+{
+    EVENT("(GLuint program = %u, GLint location = %d, GLuint v0 = %u, GLuint v1 = %u)", program,
+          location, v0, v1);
+
+    Context *context = GetValidGlobalContext();
+    if (context)
+    {
+        context->gatherParams<EntryPoint::ProgramUniform2ui>(program, location, v0, v1);
+
+        if (context->skipValidation() ||
+            ValidateProgramUniform2ui(context, program, location, v0, v1))
+        {
+            context->programUniform2ui(program, location, v0, v1);
+        }
+    }
+}
+
+void GL_APIENTRY ProgramUniform2uiv(GLuint program,
+                                    GLint location,
+                                    GLsizei count,
+                                    const GLuint *value)
+{
+    EVENT(
+        "(GLuint program = %u, GLint location = %d, GLsizei count = %d, const GLuint *value = "
+        "0x%0.8p)",
+        program, location, count, value);
+
+    Context *context = GetValidGlobalContext();
+    if (context)
+    {
+        context->gatherParams<EntryPoint::ProgramUniform2uiv>(program, location, count, value);
+
+        if (context->skipValidation() ||
+            ValidateProgramUniform2uiv(context, program, location, count, value))
+        {
+            context->programUniform2uiv(program, location, count, value);
+        }
+    }
+}
+
+void GL_APIENTRY
+ProgramUniform3f(GLuint program, GLint location, GLfloat v0, GLfloat v1, GLfloat v2)
+{
+    EVENT(
+        "(GLuint program = %u, GLint location = %d, GLfloat v0 = %f, GLfloat v1 = %f, GLfloat v2 = "
+        "%f)",
+        program, location, v0, v1, v2);
+
+    Context *context = GetValidGlobalContext();
+    if (context)
+    {
+        context->gatherParams<EntryPoint::ProgramUniform3f>(program, location, v0, v1, v2);
+
+        if (context->skipValidation() ||
+            ValidateProgramUniform3f(context, program, location, v0, v1, v2))
+        {
+            context->programUniform3f(program, location, v0, v1, v2);
+        }
+    }
+}
+
+void GL_APIENTRY ProgramUniform3fv(GLuint program,
+                                   GLint location,
+                                   GLsizei count,
+                                   const GLfloat *value)
+{
+    EVENT(
+        "(GLuint program = %u, GLint location = %d, GLsizei count = %d, const GLfloat *value = "
+        "0x%0.8p)",
+        program, location, count, value);
+
+    Context *context = GetValidGlobalContext();
+    if (context)
+    {
+        context->gatherParams<EntryPoint::ProgramUniform3fv>(program, location, count, value);
+
+        if (context->skipValidation() ||
+            ValidateProgramUniform3fv(context, program, location, count, value))
+        {
+            context->programUniform3fv(program, location, count, value);
+        }
+    }
+}
+
+void GL_APIENTRY ProgramUniform3i(GLuint program, GLint location, GLint v0, GLint v1, GLint v2)
+{
+    EVENT("(GLuint program = %u, GLint location = %d, GLint v0 = %d, GLint v1 = %d, GLint v2 = %d)",
+          program, location, v0, v1, v2);
+
+    Context *context = GetValidGlobalContext();
+    if (context)
+    {
+        context->gatherParams<EntryPoint::ProgramUniform3i>(program, location, v0, v1, v2);
+
+        if (context->skipValidation() ||
+            ValidateProgramUniform3i(context, program, location, v0, v1, v2))
+        {
+            context->programUniform3i(program, location, v0, v1, v2);
+        }
+    }
+}
+
+void GL_APIENTRY ProgramUniform3iv(GLuint program,
+                                   GLint location,
+                                   GLsizei count,
+                                   const GLint *value)
+{
+    EVENT(
+        "(GLuint program = %u, GLint location = %d, GLsizei count = %d, const GLint *value = "
+        "0x%0.8p)",
+        program, location, count, value);
+
+    Context *context = GetValidGlobalContext();
+    if (context)
+    {
+        context->gatherParams<EntryPoint::ProgramUniform3iv>(program, location, count, value);
+
+        if (context->skipValidation() ||
+            ValidateProgramUniform3iv(context, program, location, count, value))
+        {
+            context->programUniform3iv(program, location, count, value);
+        }
+    }
+}
+
+void GL_APIENTRY ProgramUniform3ui(GLuint program, GLint location, GLuint v0, GLuint v1, GLuint v2)
+{
+    EVENT(
+        "(GLuint program = %u, GLint location = %d, GLuint v0 = %u, GLuint v1 = %u, GLuint v2 = "
+        "%u)",
+        program, location, v0, v1, v2);
+
+    Context *context = GetValidGlobalContext();
+    if (context)
+    {
+        context->gatherParams<EntryPoint::ProgramUniform3ui>(program, location, v0, v1, v2);
+
+        if (context->skipValidation() ||
+            ValidateProgramUniform3ui(context, program, location, v0, v1, v2))
+        {
+            context->programUniform3ui(program, location, v0, v1, v2);
+        }
+    }
+}
+
+void GL_APIENTRY ProgramUniform3uiv(GLuint program,
+                                    GLint location,
+                                    GLsizei count,
+                                    const GLuint *value)
+{
+    EVENT(
+        "(GLuint program = %u, GLint location = %d, GLsizei count = %d, const GLuint *value = "
+        "0x%0.8p)",
+        program, location, count, value);
+
+    Context *context = GetValidGlobalContext();
+    if (context)
+    {
+        context->gatherParams<EntryPoint::ProgramUniform3uiv>(program, location, count, value);
+
+        if (context->skipValidation() ||
+            ValidateProgramUniform3uiv(context, program, location, count, value))
+        {
+            context->programUniform3uiv(program, location, count, value);
+        }
+    }
+}
+
+void GL_APIENTRY
+ProgramUniform4f(GLuint program, GLint location, GLfloat v0, GLfloat v1, GLfloat v2, GLfloat v3)
+{
+    EVENT(
+        "(GLuint program = %u, GLint location = %d, GLfloat v0 = %f, GLfloat v1 = %f, GLfloat v2 = "
+        "%f, GLfloat v3 = %f)",
+        program, location, v0, v1, v2, v3);
+
+    Context *context = GetValidGlobalContext();
+    if (context)
+    {
+        context->gatherParams<EntryPoint::ProgramUniform4f>(program, location, v0, v1, v2, v3);
+
+        if (context->skipValidation() ||
+            ValidateProgramUniform4f(context, program, location, v0, v1, v2, v3))
+        {
+            context->programUniform4f(program, location, v0, v1, v2, v3);
+        }
+    }
+}
+
+void GL_APIENTRY ProgramUniform4fv(GLuint program,
+                                   GLint location,
+                                   GLsizei count,
+                                   const GLfloat *value)
+{
+    EVENT(
+        "(GLuint program = %u, GLint location = %d, GLsizei count = %d, const GLfloat *value = "
+        "0x%0.8p)",
+        program, location, count, value);
+
+    Context *context = GetValidGlobalContext();
+    if (context)
+    {
+        context->gatherParams<EntryPoint::ProgramUniform4fv>(program, location, count, value);
+
+        if (context->skipValidation() ||
+            ValidateProgramUniform4fv(context, program, location, count, value))
+        {
+            context->programUniform4fv(program, location, count, value);
+        }
+    }
+}
+
+void GL_APIENTRY
+ProgramUniform4i(GLuint program, GLint location, GLint v0, GLint v1, GLint v2, GLint v3)
+{
+    EVENT(
+        "(GLuint program = %u, GLint location = %d, GLint v0 = %d, GLint v1 = %d, GLint v2 = %d, "
+        "GLint v3 = %d)",
+        program, location, v0, v1, v2, v3);
+
+    Context *context = GetValidGlobalContext();
+    if (context)
+    {
+        context->gatherParams<EntryPoint::ProgramUniform4i>(program, location, v0, v1, v2, v3);
+
+        if (context->skipValidation() ||
+            ValidateProgramUniform4i(context, program, location, v0, v1, v2, v3))
+        {
+            context->programUniform4i(program, location, v0, v1, v2, v3);
+        }
+    }
+}
+
+void GL_APIENTRY ProgramUniform4iv(GLuint program,
+                                   GLint location,
+                                   GLsizei count,
+                                   const GLint *value)
+{
+    EVENT(
+        "(GLuint program = %u, GLint location = %d, GLsizei count = %d, const GLint *value = "
+        "0x%0.8p)",
+        program, location, count, value);
+
+    Context *context = GetValidGlobalContext();
+    if (context)
+    {
+        context->gatherParams<EntryPoint::ProgramUniform4iv>(program, location, count, value);
+
+        if (context->skipValidation() ||
+            ValidateProgramUniform4iv(context, program, location, count, value))
+        {
+            context->programUniform4iv(program, location, count, value);
+        }
+    }
+}
+
+void GL_APIENTRY
+ProgramUniform4ui(GLuint program, GLint location, GLuint v0, GLuint v1, GLuint v2, GLuint v3)
+{
+    EVENT(
+        "(GLuint program = %u, GLint location = %d, GLuint v0 = %u, GLuint v1 = %u, GLuint v2 = "
+        "%u, GLuint v3 = %u)",
+        program, location, v0, v1, v2, v3);
+
+    Context *context = GetValidGlobalContext();
+    if (context)
+    {
+        context->gatherParams<EntryPoint::ProgramUniform4ui>(program, location, v0, v1, v2, v3);
+
+        if (context->skipValidation() ||
+            ValidateProgramUniform4ui(context, program, location, v0, v1, v2, v3))
+        {
+            context->programUniform4ui(program, location, v0, v1, v2, v3);
+        }
+    }
+}
+
+void GL_APIENTRY ProgramUniform4uiv(GLuint program,
+                                    GLint location,
+                                    GLsizei count,
+                                    const GLuint *value)
+{
+    EVENT(
+        "(GLuint program = %u, GLint location = %d, GLsizei count = %d, const GLuint *value = "
+        "0x%0.8p)",
+        program, location, count, value);
+
+    Context *context = GetValidGlobalContext();
+    if (context)
+    {
+        context->gatherParams<EntryPoint::ProgramUniform4uiv>(program, location, count, value);
+
+        if (context->skipValidation() ||
+            ValidateProgramUniform4uiv(context, program, location, count, value))
+        {
+            context->programUniform4uiv(program, location, count, value);
+        }
+    }
+}
+
+void GL_APIENTRY ProgramUniformMatrix2fv(GLuint program,
+                                         GLint location,
+                                         GLsizei count,
+                                         GLboolean transpose,
+                                         const GLfloat *value)
+{
+    EVENT(
+        "(GLuint program = %u, GLint location = %d, GLsizei count = %d, GLboolean transpose = %u, "
+        "const GLfloat *value = 0x%0.8p)",
+        program, location, count, transpose, value);
+
+    Context *context = GetValidGlobalContext();
+    if (context)
+    {
+        context->gatherParams<EntryPoint::ProgramUniformMatrix2fv>(program, location, count,
+                                                                   transpose, value);
+
+        if (context->skipValidation() ||
+            ValidateProgramUniformMatrix2fv(context, program, location, count, transpose, value))
+        {
+            context->programUniformMatrix2fv(program, location, count, transpose, value);
+        }
+    }
+}
+
+void GL_APIENTRY ProgramUniformMatrix2x3fv(GLuint program,
+                                           GLint location,
+                                           GLsizei count,
+                                           GLboolean transpose,
+                                           const GLfloat *value)
+{
+    EVENT(
+        "(GLuint program = %u, GLint location = %d, GLsizei count = %d, GLboolean transpose = %u, "
+        "const GLfloat *value = 0x%0.8p)",
+        program, location, count, transpose, value);
+
+    Context *context = GetValidGlobalContext();
+    if (context)
+    {
+        context->gatherParams<EntryPoint::ProgramUniformMatrix2x3fv>(program, location, count,
+                                                                     transpose, value);
+
+        if (context->skipValidation() ||
+            ValidateProgramUniformMatrix2x3fv(context, program, location, count, transpose, value))
+        {
+            context->programUniformMatrix2x3fv(program, location, count, transpose, value);
+        }
+    }
+}
+
+void GL_APIENTRY ProgramUniformMatrix2x4fv(GLuint program,
+                                           GLint location,
+                                           GLsizei count,
+                                           GLboolean transpose,
+                                           const GLfloat *value)
+{
+    EVENT(
+        "(GLuint program = %u, GLint location = %d, GLsizei count = %d, GLboolean transpose = %u, "
+        "const GLfloat *value = 0x%0.8p)",
+        program, location, count, transpose, value);
+
+    Context *context = GetValidGlobalContext();
+    if (context)
+    {
+        context->gatherParams<EntryPoint::ProgramUniformMatrix2x4fv>(program, location, count,
+                                                                     transpose, value);
+
+        if (context->skipValidation() ||
+            ValidateProgramUniformMatrix2x4fv(context, program, location, count, transpose, value))
+        {
+            context->programUniformMatrix2x4fv(program, location, count, transpose, value);
+        }
+    }
+}
+
+void GL_APIENTRY ProgramUniformMatrix3fv(GLuint program,
+                                         GLint location,
+                                         GLsizei count,
+                                         GLboolean transpose,
+                                         const GLfloat *value)
+{
+    EVENT(
+        "(GLuint program = %u, GLint location = %d, GLsizei count = %d, GLboolean transpose = %u, "
+        "const GLfloat *value = 0x%0.8p)",
+        program, location, count, transpose, value);
+
+    Context *context = GetValidGlobalContext();
+    if (context)
+    {
+        context->gatherParams<EntryPoint::ProgramUniformMatrix3fv>(program, location, count,
+                                                                   transpose, value);
+
+        if (context->skipValidation() ||
+            ValidateProgramUniformMatrix3fv(context, program, location, count, transpose, value))
+        {
+            context->programUniformMatrix3fv(program, location, count, transpose, value);
+        }
+    }
+}
+
+void GL_APIENTRY ProgramUniformMatrix3x2fv(GLuint program,
+                                           GLint location,
+                                           GLsizei count,
+                                           GLboolean transpose,
+                                           const GLfloat *value)
+{
+    EVENT(
+        "(GLuint program = %u, GLint location = %d, GLsizei count = %d, GLboolean transpose = %u, "
+        "const GLfloat *value = 0x%0.8p)",
+        program, location, count, transpose, value);
+
+    Context *context = GetValidGlobalContext();
+    if (context)
+    {
+        context->gatherParams<EntryPoint::ProgramUniformMatrix3x2fv>(program, location, count,
+                                                                     transpose, value);
+
+        if (context->skipValidation() ||
+            ValidateProgramUniformMatrix3x2fv(context, program, location, count, transpose, value))
+        {
+            context->programUniformMatrix3x2fv(program, location, count, transpose, value);
+        }
+    }
+}
+
+void GL_APIENTRY ProgramUniformMatrix3x4fv(GLuint program,
+                                           GLint location,
+                                           GLsizei count,
+                                           GLboolean transpose,
+                                           const GLfloat *value)
+{
+    EVENT(
+        "(GLuint program = %u, GLint location = %d, GLsizei count = %d, GLboolean transpose = %u, "
+        "const GLfloat *value = 0x%0.8p)",
+        program, location, count, transpose, value);
+
+    Context *context = GetValidGlobalContext();
+    if (context)
+    {
+        context->gatherParams<EntryPoint::ProgramUniformMatrix3x4fv>(program, location, count,
+                                                                     transpose, value);
+
+        if (context->skipValidation() ||
+            ValidateProgramUniformMatrix3x4fv(context, program, location, count, transpose, value))
+        {
+            context->programUniformMatrix3x4fv(program, location, count, transpose, value);
+        }
+    }
+}
+
+void GL_APIENTRY ProgramUniformMatrix4fv(GLuint program,
+                                         GLint location,
+                                         GLsizei count,
+                                         GLboolean transpose,
+                                         const GLfloat *value)
+{
+    EVENT(
+        "(GLuint program = %u, GLint location = %d, GLsizei count = %d, GLboolean transpose = %u, "
+        "const GLfloat *value = 0x%0.8p)",
+        program, location, count, transpose, value);
+
+    Context *context = GetValidGlobalContext();
+    if (context)
+    {
+        context->gatherParams<EntryPoint::ProgramUniformMatrix4fv>(program, location, count,
+                                                                   transpose, value);
+
+        if (context->skipValidation() ||
+            ValidateProgramUniformMatrix4fv(context, program, location, count, transpose, value))
+        {
+            context->programUniformMatrix4fv(program, location, count, transpose, value);
+        }
+    }
+}
+
+void GL_APIENTRY ProgramUniformMatrix4x2fv(GLuint program,
+                                           GLint location,
+                                           GLsizei count,
+                                           GLboolean transpose,
+                                           const GLfloat *value)
+{
+    EVENT(
+        "(GLuint program = %u, GLint location = %d, GLsizei count = %d, GLboolean transpose = %u, "
+        "const GLfloat *value = 0x%0.8p)",
+        program, location, count, transpose, value);
+
+    Context *context = GetValidGlobalContext();
+    if (context)
+    {
+        context->gatherParams<EntryPoint::ProgramUniformMatrix4x2fv>(program, location, count,
+                                                                     transpose, value);
+
+        if (context->skipValidation() ||
+            ValidateProgramUniformMatrix4x2fv(context, program, location, count, transpose, value))
+        {
+            context->programUniformMatrix4x2fv(program, location, count, transpose, value);
+        }
+    }
+}
+
+void GL_APIENTRY ProgramUniformMatrix4x3fv(GLuint program,
+                                           GLint location,
+                                           GLsizei count,
+                                           GLboolean transpose,
+                                           const GLfloat *value)
+{
+    EVENT(
+        "(GLuint program = %u, GLint location = %d, GLsizei count = %d, GLboolean transpose = %u, "
+        "const GLfloat *value = 0x%0.8p)",
+        program, location, count, transpose, value);
+
+    Context *context = GetValidGlobalContext();
+    if (context)
+    {
+        context->gatherParams<EntryPoint::ProgramUniformMatrix4x3fv>(program, location, count,
+                                                                     transpose, value);
+
+        if (context->skipValidation() ||
+            ValidateProgramUniformMatrix4x3fv(context, program, location, count, transpose, value))
+        {
+            context->programUniformMatrix4x3fv(program, location, count, transpose, value);
+        }
+    }
+}
+
+void GL_APIENTRY SampleMaski(GLuint maskNumber, GLbitfield mask)
+{
+    EVENT("(GLuint maskNumber = %u, GLbitfield mask = 0x%X)", maskNumber, mask);
+
+    Context *context = GetValidGlobalContext();
+    if (context)
+    {
+        context->gatherParams<EntryPoint::SampleMaski>(maskNumber, mask);
+
+        if (context->skipValidation() || ValidateSampleMaski(context, maskNumber, mask))
+        {
+            context->sampleMaski(maskNumber, mask);
+        }
+    }
+}
+
+void GL_APIENTRY TexStorage2DMultisample(GLenum target,
+                                         GLsizei samples,
+                                         GLenum internalformat,
+                                         GLsizei width,
+                                         GLsizei height,
+                                         GLboolean fixedsamplelocations)
+{
+    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)
+    {
+        context->gatherParams<EntryPoint::TexStorage2DMultisample>(
+            target, samples, internalformat, width, height, fixedsamplelocations);
+
+        if (context->skipValidation() ||
+            ValidateTexStorage2DMultisample(context, target, samples, internalformat, width, height,
+                                            fixedsamplelocations))
+        {
+            context->texStorage2DMultisample(target, 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,
+          program);
+
+    Context *context = GetValidGlobalContext();
+    if (context)
+    {
+        context->gatherParams<EntryPoint::UseProgramStages>(pipeline, stages, program);
+
+        if (context->skipValidation() ||
+            ValidateUseProgramStages(context, pipeline, stages, program))
+        {
+            context->useProgramStages(pipeline, stages, program);
+        }
+    }
+}
+
+void GL_APIENTRY ValidateProgramPipeline(GLuint pipeline)
+{
+    EVENT("(GLuint pipeline = %u)", pipeline);
+
+    Context *context = GetValidGlobalContext();
+    if (context)
+    {
+        context->gatherParams<EntryPoint::ValidateProgramPipeline>(pipeline);
+
+        if (context->skipValidation() || ValidateValidateProgramPipeline(context, pipeline))
+        {
+            context->validateProgramPipeline(pipeline);
+        }
+    }
+}
+
+void GL_APIENTRY VertexAttribBinding(GLuint attribindex, GLuint bindingindex)
+{
+    EVENT("(GLuint attribindex = %u, GLuint bindingindex = %u)", attribindex, bindingindex);
+
+    Context *context = GetValidGlobalContext();
+    if (context)
+    {
+        context->gatherParams<EntryPoint::VertexAttribBinding>(attribindex, bindingindex);
+
+        if (context->skipValidation() ||
+            ValidateVertexAttribBinding(context, attribindex, bindingindex))
+        {
+            context->vertexAttribBinding(attribindex, bindingindex);
+        }
+    }
+}
+
+void GL_APIENTRY VertexAttribFormat(GLuint attribindex,
+                                    GLint size,
+                                    GLenum type,
+                                    GLboolean normalized,
+                                    GLuint relativeoffset)
+{
+    EVENT(
+        "(GLuint attribindex = %u, GLint size = %d, GLenum type = 0x%X, GLboolean normalized = %u, "
+        "GLuint relativeoffset = %u)",
+        attribindex, size, type, normalized, relativeoffset);
+
+    Context *context = GetValidGlobalContext();
+    if (context)
+    {
+        context->gatherParams<EntryPoint::VertexAttribFormat>(attribindex, size, type, normalized,
+                                                              relativeoffset);
+
+        if (context->skipValidation() ||
+            ValidateVertexAttribFormat(context, attribindex, size, type, normalized,
+                                       relativeoffset))
+        {
+            context->vertexAttribFormat(attribindex, size, type, normalized, relativeoffset);
+        }
+    }
+}
+
+void GL_APIENTRY VertexAttribIFormat(GLuint attribindex,
+                                     GLint size,
+                                     GLenum type,
+                                     GLuint relativeoffset)
+{
+    EVENT(
+        "(GLuint attribindex = %u, GLint size = %d, GLenum type = 0x%X, GLuint relativeoffset = "
+        "%u)",
+        attribindex, size, type, relativeoffset);
+
+    Context *context = GetValidGlobalContext();
+    if (context)
+    {
+        context->gatherParams<EntryPoint::VertexAttribIFormat>(attribindex, size, type,
+                                                               relativeoffset);
+
+        if (context->skipValidation() ||
+            ValidateVertexAttribIFormat(context, attribindex, size, type, relativeoffset))
+        {
+            context->vertexAttribIFormat(attribindex, size, type, relativeoffset);
+        }
+    }
+}
+
+void GL_APIENTRY VertexBindingDivisor(GLuint bindingindex, GLuint divisor)
+{
+    EVENT("(GLuint bindingindex = %u, GLuint divisor = %u)", bindingindex, divisor);
+
+    Context *context = GetValidGlobalContext();
+    if (context)
+    {
+        context->gatherParams<EntryPoint::VertexBindingDivisor>(bindingindex, divisor);
+
+        if (context->skipValidation() ||
+            ValidateVertexBindingDivisor(context, bindingindex, divisor))
+        {
+            context->vertexBindingDivisor(bindingindex, divisor);
+        }
+    }
+}
+}  // namespace gl
new file mode 100644
--- /dev/null
+++ b/gfx/angle/src/libGLESv2/entry_points_gles_3_1_autogen.h
@@ -0,0 +1,227 @@
+// 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.
+//
+// entry_points_gles_3_1_autogen.h:
+//   Defines the GLES 3.1 entry points.
+
+#ifndef LIBGLESV2_ENTRY_POINTS_GLES_3_1_AUTOGEN_H_
+#define LIBGLESV2_ENTRY_POINTS_GLES_3_1_AUTOGEN_H_
+
+#include <GLES3/gl31.h>
+#include <export.h>
+#include "common/platform.h"
+
+namespace gl
+{
+ANGLE_EXPORT void GL_APIENTRY ActiveShaderProgram(GLuint pipeline, GLuint program);
+ANGLE_EXPORT void GL_APIENTRY BindImageTexture(GLuint unit,
+                                               GLuint texture,
+                                               GLint level,
+                                               GLboolean layered,
+                                               GLint layer,
+                                               GLenum access,
+                                               GLenum format);
+ANGLE_EXPORT void GL_APIENTRY BindProgramPipeline(GLuint pipeline);
+ANGLE_EXPORT void GL_APIENTRY BindVertexBuffer(GLuint bindingindex,
+                                               GLuint buffer,
+                                               GLintptr offset,
+                                               GLsizei stride);
+ANGLE_EXPORT GLuint GL_APIENTRY CreateShaderProgramv(GLenum type,
+                                                     GLsizei count,
+                                                     const GLchar *const *strings);
+ANGLE_EXPORT void GL_APIENTRY DeleteProgramPipelines(GLsizei n, const GLuint *pipelines);
+ANGLE_EXPORT void GL_APIENTRY DispatchCompute(GLuint num_groups_x,
+                                              GLuint num_groups_y,
+                                              GLuint num_groups_z);
+ANGLE_EXPORT void GL_APIENTRY DispatchComputeIndirect(GLintptr indirect);
+ANGLE_EXPORT void GL_APIENTRY DrawArraysIndirect(GLenum mode, const void *indirect);
+ANGLE_EXPORT void GL_APIENTRY DrawElementsIndirect(GLenum mode, GLenum type, const void *indirect);
+ANGLE_EXPORT void GL_APIENTRY FramebufferParameteri(GLenum target, GLenum pname, GLint param);
+ANGLE_EXPORT void GL_APIENTRY GenProgramPipelines(GLsizei n, GLuint *pipelines);
+ANGLE_EXPORT void GL_APIENTRY GetBooleani_v(GLenum target, GLuint index, GLboolean *data);
+ANGLE_EXPORT void GL_APIENTRY GetFramebufferParameteriv(GLenum target, GLenum pname, GLint *params);
+ANGLE_EXPORT void GL_APIENTRY GetMultisamplefv(GLenum pname, GLuint index, GLfloat *val);
+ANGLE_EXPORT void GL_APIENTRY GetProgramInterfaceiv(GLuint program,
+                                                    GLenum programInterface,
+                                                    GLenum pname,
+                                                    GLint *params);
+ANGLE_EXPORT void GL_APIENTRY GetProgramPipelineInfoLog(GLuint pipeline,
+                                                        GLsizei bufSize,
+                                                        GLsizei *length,
+                                                        GLchar *infoLog);
+ANGLE_EXPORT void GL_APIENTRY GetProgramPipelineiv(GLuint pipeline, GLenum pname, GLint *params);
+ANGLE_EXPORT GLuint GL_APIENTRY GetProgramResourceIndex(GLuint program,
+                                                        GLenum programInterface,
+                                                        const GLchar *name);
+ANGLE_EXPORT GLint GL_APIENTRY GetProgramResourceLocation(GLuint program,
+                                                          GLenum programInterface,
+                                                          const GLchar *name);
+ANGLE_EXPORT void GL_APIENTRY GetProgramResourceName(GLuint program,
+                                                     GLenum programInterface,
+                                                     GLuint index,
+                                                     GLsizei bufSize,
+                                                     GLsizei *length,
+                                                     GLchar *name);
+ANGLE_EXPORT void GL_APIENTRY GetProgramResourceiv(GLuint program,
+                                                   GLenum programInterface,
+                                                   GLuint index,
+                                                   GLsizei propCount,
+                                                   const GLenum *props,
+                                                   GLsizei bufSize,
+                                                   GLsizei *length,
+                                                   GLint *params);
+ANGLE_EXPORT void GL_APIENTRY GetTexLevelParameterfv(GLenum target,
+                                                     GLint level,
+                                                     GLenum pname,
+                                                     GLfloat *params);
+ANGLE_EXPORT void GL_APIENTRY GetTexLevelParameteriv(GLenum target,
+                                                     GLint level,
+                                                     GLenum pname,
+                                                     GLint *params);
+ANGLE_EXPORT GLboolean GL_APIENTRY IsProgramPipeline(GLuint pipeline);
+ANGLE_EXPORT void GL_APIENTRY MemoryBarrier(GLbitfield barriers);
+ANGLE_EXPORT void GL_APIENTRY MemoryBarrierByRegion(GLbitfield barriers);
+ANGLE_EXPORT void GL_APIENTRY ProgramUniform1f(GLuint program, GLint location, GLfloat v0);
+ANGLE_EXPORT void GL_APIENTRY ProgramUniform1fv(GLuint program,
+                                                GLint location,
+                                                GLsizei count,
+                                                const GLfloat *value);
+ANGLE_EXPORT void GL_APIENTRY ProgramUniform1i(GLuint program, GLint location, GLint v0);
+ANGLE_EXPORT void GL_APIENTRY ProgramUniform1iv(GLuint program,
+                                                GLint location,
+                                                GLsizei count,
+                                                const GLint *value);
+ANGLE_EXPORT void GL_APIENTRY ProgramUniform1ui(GLuint program, GLint location, GLuint v0);
+ANGLE_EXPORT void GL_APIENTRY ProgramUniform1uiv(GLuint program,
+                                                 GLint location,
+                                                 GLsizei count,
+                                                 const GLuint *value);
+ANGLE_EXPORT void GL_APIENTRY ProgramUniform2f(GLuint program,
+                                               GLint location,
+                                               GLfloat v0,
+                                               GLfloat v1);
+ANGLE_EXPORT void GL_APIENTRY ProgramUniform2fv(GLuint program,
+                                                GLint location,
+                                                GLsizei count,
+                                                const GLfloat *value);
+ANGLE_EXPORT void GL_APIENTRY ProgramUniform2i(GLuint program, GLint location, GLint v0, GLint v1);
+ANGLE_EXPORT void GL_APIENTRY ProgramUniform2iv(GLuint program,
+                                                GLint location,
+                                                GLsizei count,
+                                                const GLint *value);
+ANGLE_EXPORT void GL_APIENTRY ProgramUniform2ui(GLuint program,
+                                                GLint location,
+                                                GLuint v0,
+                                                GLuint v1);
+ANGLE_EXPORT void GL_APIENTRY ProgramUniform2uiv(GLuint program,
+                                                 GLint location,
+                                                 GLsizei count,
+                                                 const GLuint *value);
+ANGLE_EXPORT void GL_APIENTRY
+ProgramUniform3f(GLuint program, GLint location, GLfloat v0, GLfloat v1, GLfloat v2);
+ANGLE_EXPORT void GL_APIENTRY ProgramUniform3fv(GLuint program,
+                                                GLint location,
+                                                GLsizei count,
+                                                const GLfloat *value);
+ANGLE_EXPORT void GL_APIENTRY
+ProgramUniform3i(GLuint program, GLint location, GLint v0, GLint v1, GLint v2);
+ANGLE_EXPORT void GL_APIENTRY ProgramUniform3iv(GLuint program,
+                                                GLint location,
+                                                GLsizei count,
+                                                const GLint *value);
+ANGLE_EXPORT void GL_APIENTRY
+ProgramUniform3ui(GLuint program, GLint location, GLuint v0, GLuint v1, GLuint v2);
+ANGLE_EXPORT void GL_APIENTRY ProgramUniform3uiv(GLuint program,
+                                                 GLint location,
+                                                 GLsizei count,
+                                                 const GLuint *value);
+ANGLE_EXPORT void GL_APIENTRY
+ProgramUniform4f(GLuint program, GLint location, GLfloat v0, GLfloat v1, GLfloat v2, GLfloat v3);
+ANGLE_EXPORT void GL_APIENTRY ProgramUniform4fv(GLuint program,
+                                                GLint location,
+                                                GLsizei count,
+                                                const GLfloat *value);
+ANGLE_EXPORT void GL_APIENTRY
+ProgramUniform4i(GLuint program, GLint location, GLint v0, GLint v1, GLint v2, GLint v3);
+ANGLE_EXPORT void GL_APIENTRY ProgramUniform4iv(GLuint program,
+                                                GLint location,
+                                                GLsizei count,
+                                                const GLint *value);
+ANGLE_EXPORT void GL_APIENTRY
+ProgramUniform4ui(GLuint program, GLint location, GLuint v0, GLuint v1, GLuint v2, GLuint v3);
+ANGLE_EXPORT void GL_APIENTRY ProgramUniform4uiv(GLuint program,
+                                                 GLint location,
+                                                 GLsizei count,
+                                                 const GLuint *value);
+ANGLE_EXPORT void GL_APIENTRY ProgramUniformMatrix2fv(GLuint program,
+                                                      GLint location,
+                                                      GLsizei count,
+                                                      GLboolean transpose,
+                                                      const GLfloat *value);
+ANGLE_EXPORT void GL_APIENTRY ProgramUniformMatrix2x3fv(GLuint program,
+                                                        GLint location,
+                                                        GLsizei count,
+                                                        GLboolean transpose,
+                                                        const GLfloat *value);
+ANGLE_EXPORT void GL_APIENTRY ProgramUniformMatrix2x4fv(GLuint program,
+                                                        GLint location,
+                                                        GLsizei count,
+                                                        GLboolean transpose,
+                                                        const GLfloat *value);
+ANGLE_EXPORT void GL_APIENTRY ProgramUniformMatrix3fv(GLuint program,
+                                                      GLint location,
+                                                      GLsizei count,
+                                                      GLboolean transpose,
+                                                      const GLfloat *value);
+ANGLE_EXPORT void GL_APIENTRY ProgramUniformMatrix3x2fv(GLuint program,
+                                                        GLint location,
+                                                        GLsizei count,
+                                                        GLboolean transpose,
+                                                        const GLfloat *value);
+ANGLE_EXPORT void GL_APIENTRY ProgramUniformMatrix3x4fv(GLuint program,
+                                                        GLint location,
+                                                        GLsizei count,
+                                                        GLboolean transpose,
+                                                        const GLfloat *value);
+ANGLE_EXPORT void GL_APIENTRY ProgramUniformMatrix4fv(GLuint program,
+                                                      GLint location,
+                                                      GLsizei count,
+                                                      GLboolean transpose,
+                                                      const GLfloat *value);
+ANGLE_EXPORT void GL_APIENTRY ProgramUniformMatrix4x2fv(GLuint program,
+                                                        GLint location,
+                                                        GLsizei count,
+                                                        GLboolean transpose,
+                                                        const GLfloat *value);
+ANGLE_EXPORT void GL_APIENTRY ProgramUniformMatrix4x3fv(GLuint program,
+                                                        GLint location,
+                                                        GLsizei count,
+                                                        GLboolean transpose,
+                                                        const GLfloat *value);
+ANGLE_EXPORT void GL_APIENTRY SampleMaski(GLuint maskNumber, GLbitfield mask);
+ANGLE_EXPORT void GL_APIENTRY TexStorage2DMultisample(GLenum target,
+                                                      GLsizei samples,
+                                                      GLenum internalformat,
+                                                      GLsizei width,
+                                                      GLsizei height,
+                                                      GLboolean fixedsamplelocations);
+ANGLE_EXPORT void GL_APIENTRY UseProgramStages(GLuint pipeline, GLbitfield stages, GLuint program);
+ANGLE_EXPORT void GL_APIENTRY ValidateProgramPipeline(GLuint pipeline);
+ANGLE_EXPORT void GL_APIENTRY VertexAttribBinding(GLuint attribindex, GLuint bindingindex);
+ANGLE_EXPORT void GL_APIENTRY VertexAttribFormat(GLuint attribindex,
+                                                 GLint size,
+                                                 GLenum type,
+                                                 GLboolean normalized,
+                                                 GLuint relativeoffset);
+ANGLE_EXPORT void GL_APIENTRY VertexAttribIFormat(GLuint attribindex,
+                                                  GLint size,
+                                                  GLenum type,
+                                                  GLuint relativeoffset);
+ANGLE_EXPORT void GL_APIENTRY VertexBindingDivisor(GLuint bindingindex, GLuint divisor);
+}  // namespace gl
+
+#endif  // LIBGLESV2_ENTRY_POINTS_GLES_3_1_AUTOGEN_H_
new file mode 100644
--- /dev/null
+++ b/gfx/angle/src/libGLESv2/gen_proc_table.py
@@ -0,0 +1,78 @@
+#!python
+# 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.
+#
+# gen_proc_table.py:
+#  Code generation for entry point loading tables.
+
+# TODO(jmadill): Should be part of entry point generation.
+
+import sys
+from datetime import date
+
+data_source_name = "proc_table_data.json"
+out_file_name = "proc_table_autogen.cpp"
+
+template_cpp = """// GENERATED FILE - DO NOT EDIT.
+// Generated by {script_name} using data from {data_source_name}.
+//
+// Copyright {copyright_year} The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+// getProcAddress loader table:
+//   Mapping from a string entry point name to function address.
+//
+
+#include "libGLESv2/proc_table.h"
+
+#include "libGLESv2/entry_points_egl.h"
+#include "libGLESv2/entry_points_egl_ext.h"
+#include "libGLESv2/entry_points_gles_2_0_autogen.h"
+#include "libGLESv2/entry_points_gles_2_0_ext.h"
+#include "libGLESv2/entry_points_gles_2_0_ext_autogen.h"
+#include "libGLESv2/entry_points_gles_3_0_autogen.h"
+#include "libGLESv2/entry_points_gles_3_1_autogen.h"
+#include "platform/Platform.h"
+
+#define P(FUNC) reinterpret_cast<__eglMustCastToProperFunctionPointerType>(FUNC)
+
+namespace egl
+{{
+ProcEntry g_procTable[] = {{
+{proc_data}
+}};
+
+size_t g_numProcs = {num_procs};
+}}  // namespace egl
+"""
+
+sys.path.append('../libANGLE/renderer')
+import angle_format
+
+json_data = angle_format.load_json(data_source_name)
+
+all_functions = {}
+
+for description, functions in json_data.iteritems():
+    for function in functions:
+        if function.startswith("gl"):
+            all_functions[function] = "gl::" + function[2:]
+        elif function.startswith("egl"):
+            all_functions[function] = "egl::" + function[3:]
+        else:
+            all_functions[function] = function
+
+proc_data = [('    {"%s", P(%s)}' % (func, angle_func)) for func, angle_func in sorted(all_functions.iteritems())]
+
+with open(out_file_name, 'wb') as out_file:
+    output_cpp = template_cpp.format(
+        script_name = sys.argv[0],
+        data_source_name = data_source_name,
+        copyright_year = date.today().year,
+        proc_data = ",\n".join(proc_data),
+        num_procs = len(proc_data))
+    out_file.write(output_cpp)
+    out_file.close()
+
--- a/gfx/angle/src/libGLESv2/libGLESv2.cpp
+++ b/gfx/angle/src/libGLESv2/libGLESv2.cpp
@@ -3,18 +3,19 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 //
 
 // libGLESv2.cpp: Implements the exported OpenGL ES 2.0 functions.
 
 #include "libGLESv2/entry_points_gles_2_0_autogen.h"
 #include "libGLESv2/entry_points_gles_2_0_ext.h"
+#include "libGLESv2/entry_points_gles_2_0_ext_autogen.h"
 #include "libGLESv2/entry_points_gles_3_0_autogen.h"
-#include "libGLESv2/entry_points_gles_3_1.h"
+#include "libGLESv2/entry_points_gles_3_1_autogen.h"
 
 #include "common/event_tracer.h"
 
 extern "C" {
 
 void GL_APIENTRY glActiveTexture(GLenum texture)
 {
     return gl::ActiveTexture(texture);
@@ -1933,22 +1934,22 @@ void GL_APIENTRY glPathParameterfCHROMIU
 
 void GL_APIENTRY glPathParameteriCHROMIUM(GLuint path, GLenum pname, GLint value)
 {
     gl::PathParameteriCHROMIUM(path, pname, value);
 }
 
 void GL_APIENTRY glGetPathParameterfvCHROMIUM(GLuint path, GLenum pname, GLfloat *value)
 {
-    gl::GetPathParameterfCHROMIUM(path, pname, value);
+    gl::GetPathParameterfvCHROMIUM(path, pname, value);
 }
 
 void GL_APIENTRY glGetPathParameterivCHROMIUM(GLuint path, GLenum pname, GLint *value)
 {
-    gl::GetPathParameteriCHROMIUM(path, pname, value);
+    gl::GetPathParameterivCHROMIUM(path, pname, value);
 }
 
 void GL_APIENTRY glPathStencilFuncCHROMIUM(GLenum func, GLint ref, GLuint mask)
 {
     gl::PathStencilFuncCHROMIUM(func, ref, mask);
 }
 
 void GL_APIENTRY glStencilFillPathCHROMIUM(GLuint path, GLenum fillMode, GLuint mask)
--- a/gfx/angle/src/libGLESv2/libGLESv2.def
+++ b/gfx/angle/src/libGLESv2/libGLESv2.def
@@ -405,12 +405,8 @@ EXPORTS
     glSampleMaski                   @405
     glGetTexLevelParameteriv        @406
     glGetTexLevelParameterfv        @407
     glBindVertexBuffer              @408
     glVertexAttribFormat            @409
     glVertexAttribIFormat           @410
     glVertexAttribBinding           @411
     glVertexBindingDivisor          @412
-
-    ; ANGLE Platform Implementation
-    ANGLEGetDisplayPlatform         @290
-    ANGLEResetDisplayPlatform       @291
--- a/gfx/angle/src/libGLESv2/libGLESv2.rc
+++ b/gfx/angle/src/libGLESv2/libGLESv2.rc
@@ -1,103 +1,103 @@
-// Microsoft Visual C++ generated resource script.
-//
-#include "resource.h"
-
-#define APSTUDIO_READONLY_SYMBOLS
-/////////////////////////////////////////////////////////////////////////////
-//
-// Generated from the TEXTINCLUDE 2 resource.
-//
-#include <windows.h>
-#include "../common/version.h"
-
-/////////////////////////////////////////////////////////////////////////////
-#undef APSTUDIO_READONLY_SYMBOLS
-
-/////////////////////////////////////////////////////////////////////////////
-// English (U.S.) resources
-
-#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)
-#ifdef _WIN32
-LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
-#pragma code_page(1252)
-#endif //_WIN32
-
-#ifdef APSTUDIO_INVOKED
-/////////////////////////////////////////////////////////////////////////////
-//
-// TEXTINCLUDE
-//
-
-1 TEXTINCLUDE 
-BEGIN
-    "resource.h\0"
-END
-
-2 TEXTINCLUDE 
-BEGIN
-    "#include ""afxres.h""\r\n"
-    "#include ""../common/version.h""\0"
-END
-
-3 TEXTINCLUDE 
-BEGIN
-    "\r\n"
-    "\0"
-END
-
-#endif    // APSTUDIO_INVOKED
-
-
-/////////////////////////////////////////////////////////////////////////////
-//
-// Version
-//
-
-VS_VERSION_INFO VERSIONINFO
- FILEVERSION ANGLE_MAJOR_VERSION,ANGLE_MINOR_VERSION,ANGLE_REVISION,0
- PRODUCTVERSION ANGLE_MAJOR_VERSION,ANGLE_MINOR_VERSION,ANGLE_REVISION,0
- FILEFLAGSMASK 0x17L
-#ifdef _DEBUG
- FILEFLAGS 0x1L
-#else
- FILEFLAGS 0x0L
-#endif
- FILEOS 0x4L
- FILETYPE 0x2L
- FILESUBTYPE 0x0L
-BEGIN
-    BLOCK "StringFileInfo"
-    BEGIN
-        BLOCK "040904b0"
-        BEGIN
-            VALUE "FileDescription", "ANGLE libGLESv2 Dynamic Link Library"
-            VALUE "FileVersion", ANGLE_VERSION_STRING
-            VALUE "InternalName", "libGLESv2"
-            VALUE "LegalCopyright", "Copyright (C) 2015 Google Inc."
-            VALUE "OriginalFilename", "libGLESv2.dll"
-            VALUE "PrivateBuild", ANGLE_VERSION_STRING
-            VALUE "ProductName", "ANGLE libGLESv2 Dynamic Link Library"
-            VALUE "ProductVersion", ANGLE_VERSION_STRING
-            VALUE "Comments", "Build Date: " ANGLE_COMMIT_DATE
-        END
-    END
-    BLOCK "VarFileInfo"
-    BEGIN
-        VALUE "Translation", 0x409, 1200
-    END
-END
-
-#endif    // English (U.S.) resources
-/////////////////////////////////////////////////////////////////////////////
-
-
-
-#ifndef APSTUDIO_INVOKED
-/////////////////////////////////////////////////////////////////////////////
-//
-// Generated from the TEXTINCLUDE 3 resource.
-//
-
-
-/////////////////////////////////////////////////////////////////////////////
-#endif    // not APSTUDIO_INVOKED
+// Microsoft Visual C++ generated resource script.
+//
+#include "resource.h"
+
+#define APSTUDIO_READONLY_SYMBOLS
+/////////////////////////////////////////////////////////////////////////////
+//
+// Generated from the TEXTINCLUDE 2 resource.
+//
+#include <windows.h>
+#include "../common/version.h"
+
+/////////////////////////////////////////////////////////////////////////////
+#undef APSTUDIO_READONLY_SYMBOLS
+
+/////////////////////////////////////////////////////////////////////////////
+// English (U.S.) resources
+
+#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)
+#ifdef _WIN32
+LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
+#pragma code_page(1252)
+#endif //_WIN32
+
+#ifdef APSTUDIO_INVOKED
+/////////////////////////////////////////////////////////////////////////////
+//
+// TEXTINCLUDE
+//
+
+1 TEXTINCLUDE 
+BEGIN
+    "resource.h\0"
+END
+
+2 TEXTINCLUDE 
+BEGIN
+    "#include ""afxres.h""\r\n"
+    "#include ""../common/version.h""\0"
+END
+
+3 TEXTINCLUDE 
+BEGIN
+    "\r\n"
+    "\0"
+END
+
+#endif    // APSTUDIO_INVOKED
+
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// Version
+//
+
+VS_VERSION_INFO VERSIONINFO
+ FILEVERSION ANGLE_MAJOR_VERSION,ANGLE_MINOR_VERSION,ANGLE_REVISION,0
+ PRODUCTVERSION ANGLE_MAJOR_VERSION,ANGLE_MINOR_VERSION,ANGLE_REVISION,0
+ FILEFLAGSMASK 0x17L
+#ifdef _DEBUG
+ FILEFLAGS 0x1L
+#else
+ FILEFLAGS 0x0L
+#endif
+ FILEOS 0x4L
+ FILETYPE 0x2L
+ FILESUBTYPE 0x0L
+BEGIN
+    BLOCK "StringFileInfo"
+    BEGIN
+        BLOCK "040904b0"
+        BEGIN
+            VALUE "FileDescription", "ANGLE libGLESv2 Dynamic Link Library"
+            VALUE "FileVersion", ANGLE_VERSION_STRING
+            VALUE "InternalName", "libGLESv2"
+            VALUE "LegalCopyright", "Copyright (C) 2015 Google Inc."
+            VALUE "OriginalFilename", "libGLESv2.dll"
+            VALUE "PrivateBuild", ANGLE_VERSION_STRING
+            VALUE "ProductName", "ANGLE libGLESv2 Dynamic Link Library"
+            VALUE "ProductVersion", ANGLE_VERSION_STRING
+            VALUE "Comments", "Build Date: " ANGLE_COMMIT_DATE
+        END
+    END
+    BLOCK "VarFileInfo"
+    BEGIN
+        VALUE "Translation", 0x409, 1200
+    END
+END
+
+#endif    // English (U.S.) resources
+/////////////////////////////////////////////////////////////////////////////
+
+
+
+#ifndef APSTUDIO_INVOKED
+/////////////////////////////////////////////////////////////////////////////
+//
+// Generated from the TEXTINCLUDE 3 resource.
+//
+
+
+/////////////////////////////////////////////////////////////////////////////
+#endif    // not APSTUDIO_INVOKED
--- a/gfx/angle/src/libGLESv2/moz.build
+++ b/gfx/angle/src/libGLESv2/moz.build
@@ -8,30 +8,33 @@
 #
 # WARNING WARNING WARNING
 #
 UNIFIED_SOURCES += [
     'entry_points_egl.cpp',
     'entry_points_egl_ext.cpp',
     'entry_points_gles_2_0_autogen.cpp',
     'entry_points_gles_2_0_ext.cpp',
+    'entry_points_gles_2_0_ext_autogen.cpp',
     'entry_points_gles_3_0_autogen.cpp',
-    'entry_points_gles_3_1.cpp',
+    'entry_points_gles_3_1_autogen.cpp',
     'global_state.cpp',
     'libGLESv2.cpp',
+    'proc_table_autogen.cpp',
 ]
 
 
 if CONFIG['CC_TYPE'] in ('clang', 'gcc'):
     CXXFLAGS += [
         '-Wno-attributes',
         '-Wno-shadow',
         '-Wno-sign-compare',
         '-Wno-unknown-pragmas',
         '-Wno-unreachable-code',
+        '-Wno-missing-braces',
     ]
     if CONFIG['CC_TYPE'] == 'clang':
         CXXFLAGS += [
             '-Wno-inconsistent-missing-override',
             '-Wno-unused-private-field',
         ]
     else:
         CXXFLAGS += [
@@ -61,17 +64,17 @@ DEFINES['ANGLE_NO_EXCEPTIONS'] = True
 
 # We need these defined to nothing so that we don't get bogus dllimport declspecs
 DEFINES['GL_APICALL'] = ""
 DEFINES['GL_GLEXT_PROTOTYPES'] = ""
 DEFINES['EGLAPI'] = ""
 
 
 
-LOCAL_INCLUDES += [ '../../include', '../../src', '../../src/common/third_party/base', '../../src/third_party/khronos' ]
+LOCAL_INCLUDES += [ '../../include', '../../src', '../../src/common/third_party/base', '../../src/common/third_party/smhasher', '../../src/third_party/khronos' ]
 
 DEFINES['LIBANGLE_IMPLEMENTATION'] = "1"
 DEFINES['ANGLE_ENABLE_HLSL'] = "1"
 DEFINES['ANGLE_ENABLE_KEYEDMUTEX'] = "1"
 
 if CONFIG['MOZ_HAS_WINSDK_WITH_D3D']:
   OS_LIBS += [ 'd3d9', 'dxguid' ]
 else:
new file mode 100644
--- /dev/null
+++ b/gfx/angle/src/libGLESv2/proc_table.h
@@ -0,0 +1,24 @@
+//
+// Copyright 2017 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+// 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 <utility>
+
+namespace egl
+{
+using ProcEntry = std::pair<const char *, __eglMustCastToProperFunctionPointerType>;
+
+extern ProcEntry g_procTable[];
+extern size_t g_numProcs;
+}  // namespace egl
+
+#endif  // LIBGLESV2_PROC_TABLE_H_
new file mode 100644
--- /dev/null
+++ b/gfx/angle/src/libGLESv2/proc_table_autogen.cpp
@@ -0,0 +1,549 @@
+// GENERATED FILE - DO NOT EDIT.
+// Generated by gen_proc_table.py using data from proc_table_data.json.
+//
+// Copyright 2017 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+// getProcAddress loader table:
+//   Mapping from a string entry point name to function address.
+//
+
+#include "libGLESv2/proc_table.h"
+
+#include "libGLESv2/entry_points_egl.h"
+#include "libGLESv2/entry_points_egl_ext.h"
+#include "libGLESv2/entry_points_gles_2_0_autogen.h"
+#include "libGLESv2/entry_points_gles_2_0_ext.h"
+#include "libGLESv2/entry_points_gles_2_0_ext_autogen.h"
+#include "libGLESv2/entry_points_gles_3_0_autogen.h"
+#include "libGLESv2/entry_points_gles_3_1_autogen.h"
+#include "platform/Platform.h"
+
+#define P(FUNC) reinterpret_cast<__eglMustCastToProperFunctionPointerType>(FUNC)
+
+namespace egl
+{
+ProcEntry g_procTable[] = {
+    {"ANGLEGetDisplayPlatform", P(ANGLEGetDisplayPlatform)},
+    {"ANGLEResetDisplayPlatform", P(ANGLEResetDisplayPlatform)},
+    {"eglBindAPI", P(egl::BindAPI)},
+    {"eglBindTexImage", P(egl::BindTexImage)},
+    {"eglChooseConfig", P(egl::ChooseConfig)},
+    {"eglClientWaitSync", P(egl::ClientWaitSync)},
+    {"eglCopyBuffers", P(egl::CopyBuffers)},
+    {"eglCreateContext", P(egl::CreateContext)},
+    {"eglCreateDeviceANGLE", P(egl::CreateDeviceANGLE)},
+    {"eglCreateImage", P(egl::CreateImage)},
+    {"eglCreateImageKHR", P(egl::CreateImageKHR)},
+    {"eglCreatePbufferFromClientBuffer", P(egl::CreatePbufferFromClientBuffer)},
+    {"eglCreatePbufferSurface", P(egl::CreatePbufferSurface)},
+    {"eglCreatePixmapSurface", P(egl::CreatePixmapSurface)},
+    {"eglCreatePlatformPixmapSurface", P(egl::CreatePlatformPixmapSurface)},
+    {"eglCreatePlatformWindowSurface", P(egl::CreatePlatformWindowSurface)},
+    {"eglCreateStreamKHR", P(egl::CreateStreamKHR)},
+    {"eglCreateStreamProducerD3DTextureANGLE", P(egl::CreateStreamProducerD3DTextureANGLE)},
+    {"eglCreateSync", P(egl::CreateSync)},
+    {"eglCreateWindowSurface", P(egl::CreateWindowSurface)},
+    {"eglDestroyContext", P(egl::DestroyContext)},
+    {"eglDestroyImage", P(egl::DestroyImage)},
+    {"eglDestroyImageKHR", P(egl::DestroyImageKHR)},
+    {"eglDestroyStreamKHR", P(egl::DestroyStreamKHR)},
+    {"eglDestroySurface", P(egl::DestroySurface)},
+    {"eglDestroySync", P(egl::DestroySync)},
+    {"eglGetConfigAttrib", P(egl::GetConfigAttrib)},
+    {"eglGetConfigs", P(egl::GetConfigs)},
+    {"eglGetCurrentContext", P(egl::GetCurrentContext)},
+    {"eglGetCurrentDisplay", P(egl::GetCurrentDisplay)},
+    {"eglGetCurrentSurface", P(egl::GetCurrentSurface)},
+    {"eglGetDisplay", P(egl::GetDisplay)},
+    {"eglGetError", P(egl::GetError)},
+    {"eglGetPlatformDisplay", P(egl::GetPlatformDisplay)},
+    {"eglGetPlatformDisplayEXT", P(egl::GetPlatformDisplayEXT)},
+    {"eglGetProcAddress", P(egl::GetProcAddress)},
+    {"eglGetSyncAttrib", P(egl::GetSyncAttrib)},
+    {"eglGetSyncValuesCHROMIUM", P(egl::GetSyncValuesCHROMIUM)},
+    {"eglInitialize", P(egl::Initialize)},
+    {"eglMakeCurrent", P(egl::MakeCurrent)},
+    {"eglPostSubBufferNV", P(egl::PostSubBufferNV)},
+    {"eglProgramCacheGetAttribANGLE", P(egl::ProgramCacheGetAttribANGLE)},
+    {"eglProgramCachePopulateANGLE", P(egl::ProgramCachePopulateANGLE)},
+    {"eglProgramCacheQueryANGLE", P(egl::ProgramCacheQueryANGLE)},
+    {"eglProgramCacheResizeANGLE", P(egl::ProgramCacheResizeANGLE)},
+    {"eglQueryAPI", P(egl::QueryAPI)},
+    {"eglQueryContext", P(egl::QueryContext)},
+    {"eglQueryDeviceAttribEXT", P(egl::QueryDeviceAttribEXT)},
+    {"eglQueryDeviceStringEXT", P(egl::QueryDeviceStringEXT)},
+    {"eglQueryDisplayAttribEXT", P(egl::QueryDisplayAttribEXT)},
+    {"eglQueryStreamKHR", P(egl::QueryStreamKHR)},
+    {"eglQueryStreamu64KHR", P(egl::QueryStreamu64KHR)},
+    {"eglQueryString", P(egl::QueryString)},
+    {"eglQuerySurface", P(egl::QuerySurface)},
+    {"eglQuerySurfacePointerANGLE", P(egl::QuerySurfacePointerANGLE)},
+    {"eglReleaseDeviceANGLE", P(egl::ReleaseDeviceANGLE)},
+    {"eglReleaseTexImage", P(egl::ReleaseTexImage)},
+    {"eglReleaseThread", P(egl::ReleaseThread)},
+    {"eglStreamAttribKHR", P(egl::StreamAttribKHR)},
+    {"eglStreamConsumerAcquireKHR", P(egl::StreamConsumerAcquireKHR)},
+    {"eglStreamConsumerGLTextureExternalAttribsNV",
+     P(egl::StreamConsumerGLTextureExternalAttribsNV)},
+    {"eglStreamConsumerGLTextureExternalKHR", P(egl::StreamConsumerGLTextureExternalKHR)},
+    {"eglStreamConsumerReleaseKHR", P(egl::StreamConsumerReleaseKHR)},
+    {"eglStreamPostD3DTextureANGLE", P(egl::StreamPostD3DTextureANGLE)},
+    {"eglSurfaceAttrib", P(egl::SurfaceAttrib)},
+    {"eglSwapBuffers", P(egl::SwapBuffers)},
+    {"eglSwapBuffersWithDamageEXT", P(egl::SwapBuffersWithDamageEXT)},
+    {"eglSwapInterval", P(egl::SwapInterval)},
+    {"eglTerminate", P(egl::Terminate)},
+    {"eglWaitClient", P(egl::WaitClient)},
+    {"eglWaitGL", P(egl::WaitGL)},
+    {"eglWaitNative", P(egl::WaitNative)},
+    {"eglWaitSync", P(egl::WaitSync)},
+    {"glActiveShaderProgram", P(gl::ActiveShaderProgram)},
+    {"glActiveTexture", P(gl::ActiveTexture)},
+    {"glAttachShader", P(gl::AttachShader)},
+    {"glBeginQuery", P(gl::BeginQuery)},
+    {"glBeginQueryEXT", P(gl::BeginQueryEXT)},
+    {"glBeginTransformFeedback", P(gl::BeginTransformFeedback)},
+    {"glBindAttribLocation", P(gl::BindAttribLocation)},
+    {"glBindBuffer", P(gl::BindBuffer)},
+    {"glBindBufferBase", P(gl::BindBufferBase)},
+    {"glBindBufferRange", P(gl::BindBufferRange)},
+    {"glBindFramebuffer", P(gl::BindFramebuffer)},
+    {"glBindImageTexture", P(gl::BindImageTexture)},
+    {"glBindProgramPipeline", P(gl::BindProgramPipeline)},
+    {"glBindRenderbuffer", P(gl::BindRenderbuffer)},
+    {"glBindSampler", P(gl::BindSampler)},
+    {"glBindTexture", P(gl::BindTexture)},
+    {"glBindTransformFeedback", P(gl::BindTransformFeedback)},
+    {"glBindUniformLocationCHROMIUM", P(gl::BindUniformLocationCHROMIUM)},
+    {"glBindVertexArray", P(gl::BindVertexArray)},
+    {"glBindVertexArrayOES", P(gl::BindVertexArrayOES)},
+    {"glBindVertexBuffer", P(gl::BindVertexBuffer)},
+    {"glBlendColor", P(gl::BlendColor)},
+    {"glBlendEquation", P(gl::BlendEquation)},
+    {"glBlendEquationSeparate", P(gl::BlendEquationSeparate)},
+    {"glBlendFunc", P(gl::BlendFunc)},
+    {"glBlendFuncSeparate", P(gl::BlendFuncSeparate)},
+    {"glBlitFramebuffer", P(gl::BlitFramebuffer)},
+    {"glBlitFramebufferANGLE", P(gl::BlitFramebufferANGLE)},
+    {"glBufferData", P(gl::BufferData)},
+    {"glBufferSubData", P(gl::BufferSubData)},
+    {"glCheckFramebufferStatus", P(gl::CheckFramebufferStatus)},
+    {"glClear", P(gl::Clear)},
+    {"glClearBufferfi", P(gl::ClearBufferfi)},
+    {"glClearBufferfv", P(gl::ClearBufferfv)},
+    {"glClearBufferiv", P(gl::ClearBufferiv)},
+    {"glClearBufferuiv", P(gl::ClearBufferuiv)},
+    {"glClearColor", P(gl::ClearColor)},
+    {"glClearDepthf", P(gl::ClearDepthf)},
+    {"glClearStencil", P(gl::ClearStencil)},
+    {"glClientWaitSync", P(gl::ClientWaitSync)},
+    {"glColorMask", P(gl::ColorMask)},
+    {"glCompileShader", P(gl::CompileShader)},
+    {"glCompressedCopyTextureCHROMIUM", P(gl::CompressedCopyTextureCHROMIUM)},
+    {"glCompressedTexImage2D", P(gl::CompressedTexImage2D)},
+    {"glCompressedTexImage2DRobustANGLE", P(gl::CompressedTexImage2DRobustANGLE)},
+    {"glCompressedTexImage3D", P(gl::CompressedTexImage3D)},
+    {"glCompressedTexImage3DRobustANGLE", P(gl::CompressedTexImage3DRobustANGLE)},
+    {"glCompressedTexSubImage2D", P(gl::CompressedTexSubImage2D)},
+    {"glCompressedTexSubImage2DRobustANGLE", P(gl::CompressedTexSubImage2DRobustANGLE)},
+    {"glCompressedTexSubImage3D", P(gl::CompressedTexSubImage3D)},
+    {"glCompressedTexSubImage3DRobustANGLE", P(gl::CompressedTexSubImage3DRobustANGLE)},
+    {"glCopyBufferSubData", P(gl::CopyBufferSubData)},
+    {"glCopySubTextureCHROMIUM", P(gl::CopySubTextureCHROMIUM)},
+    {"glCopyTexImage2D", P(gl::CopyTexImage2D)},
+    {"glCopyTexSubImage2D", P(gl::CopyTexSubImage2D)},
+    {"glCopyTexSubImage3D", P(gl::CopyTexSubImage3D)},
+    {"glCopyTextureCHROMIUM", P(gl::CopyTextureCHROMIUM)},
+    {"glCreateProgram", P(gl::CreateProgram)},
+    {"glCreateShader", P(gl::CreateShader)},
+    {"glCreateShaderProgramv", P(gl::CreateShaderProgramv)},
+    {"glCullFace", P(gl::CullFace)},
+    {"glDebugMessageCallbackKHR", P(gl::DebugMessageCallbackKHR)},
+    {"glDebugMessageControlKHR", P(gl::DebugMessageControlKHR)},
+    {"glDebugMessageInsertKHR", P(gl::DebugMessageInsertKHR)},
+    {"glDeleteBuffers", P(gl::DeleteBuffers)},
+    {"glDeleteFencesNV", P(gl::DeleteFencesNV)},
+    {"glDeleteFramebuffers", P(gl::DeleteFramebuffers)},
+    {"glDeleteProgram", P(gl::DeleteProgram)},
+    {"glDeleteProgramPipelines", P(gl::DeleteProgramPipelines)},
+    {"glDeleteQueries", P(gl::DeleteQueries)},
+    {"glDeleteQueriesEXT", P(gl::DeleteQueriesEXT)},
+    {"glDeleteRenderbuffers", P(gl::DeleteRenderbuffers)},
+    {"glDeleteSamplers", P(gl::DeleteSamplers)},
+    {"glDeleteShader", P(gl::DeleteShader)},
+    {"glDeleteSync", P(gl::DeleteSync)},
+    {"glDeleteTextures", P(gl::DeleteTextures)},
+    {"glDeleteTransformFeedbacks", P(gl::DeleteTransformFeedbacks)},
+    {"glDeleteVertexArrays", P(gl::DeleteVertexArrays)},
+    {"glDeleteVertexArraysOES", P(gl::DeleteVertexArraysOES)},
+    {"glDepthFunc", P(gl::DepthFunc)},
+    {"glDepthMask", P(gl::DepthMask)},
+    {"glDepthRangef", P(gl::DepthRangef)},
+    {"glDetachShader", P(gl::DetachShader)},
+    {"glDisable", P(gl::Disable)},
+    {"glDisableVertexAttribArray", P(gl::DisableVertexAttribArray)},
+    {"glDiscardFramebufferEXT", P(gl::DiscardFramebufferEXT)},
+    {"glDispatchCompute", P(gl::DispatchCompute)},
+    {"glDispatchComputeIndirect", P(gl::DispatchComputeIndirect)},
+    {"glDrawArrays", P(gl::DrawArrays)},
+    {"glDrawArraysIndirect", P(gl::DrawArraysIndirect)},
+    {"glDrawArraysInstanced", P(gl::DrawArraysInstanced)},
+    {"glDrawArraysInstancedANGLE", P(gl::DrawArraysInstancedANGLE)},
+    {"glDrawBuffers", P(gl::DrawBuffers)},
+    {"glDrawBuffersEXT", P(gl::DrawBuffersEXT)},
+    {"glDrawElements", P(gl::DrawElements)},
+    {"glDrawElementsIndirect", P(gl::DrawElementsIndirect)},
+    {"glDrawElementsInstanced", P(gl::DrawElementsInstanced)},
+    {"glDrawElementsInstancedANGLE", P(gl::DrawElementsInstancedANGLE)},
+    {"glDrawRangeElements", P(gl::DrawRangeElements)},
+    {"glEGLImageTargetRenderbufferStorageOES", P(gl::EGLImageTargetRenderbufferStorageOES)},
+    {"glEGLImageTargetTexture2DOES", P(gl::EGLImageTargetTexture2DOES)},
+    {"glEnable", P(gl::Enable)},
+    {"glEnableVertexAttribArray", P(gl::EnableVertexAttribArray)},
+    {"glEndQuery", P(gl::EndQuery)},
+    {"glEndQueryEXT", P(gl::EndQueryEXT)},
+    {"glEndTransformFeedback", P(gl::EndTransformFeedback)},
+    {"glFenceSync", P(gl::FenceSync)},
+    {"glFinish", P(gl::Finish)},
+    {"glFinishFenceNV", P(gl::FinishFenceNV)},
+    {"glFlush", P(gl::Flush)},
+    {"glFlushMappedBufferRange", P(gl::FlushMappedBufferRange)},
+    {"glFlushMappedBufferRangeEXT", P(gl::FlushMappedBufferRangeEXT)},
+    {"glFramebufferParameteri", P(gl::FramebufferParameteri)},
+    {"glFramebufferRenderbuffer", P(gl::FramebufferRenderbuffer)},
+    {"glFramebufferTexture2D", P(gl::FramebufferTexture2D)},
+    {"glFramebufferTextureLayer", P(gl::FramebufferTextureLayer)},
+    {"glFramebufferTextureMultiviewLayeredANGLE", P(gl::FramebufferTextureMultiviewLayeredANGLE)},
+    {"glFramebufferTextureMultiviewSideBySideANGLE",
+     P(gl::FramebufferTextureMultiviewSideBySideANGLE)},
+    {"glFrontFace", P(gl::FrontFace)},
+    {"glGenBuffers", P(gl::GenBuffers)},
+    {"glGenFencesNV", P(gl::GenFencesNV)},
+    {"glGenFramebuffers", P(gl::GenFramebuffers)},
+    {"glGenProgramPipelines", P(gl::GenProgramPipelines)},
+    {"glGenQueries", P(gl::GenQueries)},
+    {"glGenQueriesEXT", P(gl::GenQueriesEXT)},
+    {"glGenRenderbuffers", P(gl::GenRenderbuffers)},
+    {"glGenSamplers", P(gl::GenSamplers)},
+    {"glGenTextures", P(gl::GenTextures)},
+    {"glGenTransformFeedbacks", P(gl::GenTransformFeedbacks)},
+    {"glGenVertexArrays", P(gl::GenVertexArrays)},
+    {"glGenVertexArraysOES", P(gl::GenVertexArraysOES)},
+    {"glGenerateMipmap", P(gl::GenerateMipmap)},
+    {"glGetActiveAttrib", P(gl::GetActiveAttrib)},
+    {"glGetActiveUniform", P(gl::GetActiveUniform)},
+    {"glGetActiveUniformBlockName", P(gl::GetActiveUniformBlockName)},
+    {"glGetActiveUniformBlockiv", P(gl::GetActiveUniformBlockiv)},
+    {"glGetActiveUniformBlockivRobustANGLE", P(gl::GetActiveUniformBlockivRobustANGLE)},
+    {"glGetActiveUniformsiv", P(gl::GetActiveUniformsiv)},
+    {"glGetAttachedShaders", P(gl::GetAttachedShaders)},
+    {"glGetAttribLocation", P(gl::GetAttribLocation)},
+    {"glGetBooleani_v", P(gl::GetBooleani_v)},
+    {"glGetBooleani_vRobustANGLE", P(gl::GetBooleani_vRobustANGLE)},
+    {"glGetBooleanv", P(gl::GetBooleanv)},
+    {"glGetBooleanvRobustANGLE", P(gl::GetBooleanvRobustANGLE)},
+    {"glGetBufferParameteri64v", P(gl::GetBufferParameteri64v)},
+    {"glGetBufferParameteri64vRobustANGLE", P(gl::GetBufferParameteri64vRobustANGLE)},
+    {"glGetBufferParameteriv", P(gl::GetBufferParameteriv)},
+    {"glGetBufferParameterivRobustANGLE", P(gl::GetBufferParameterivRobustANGLE)},
+    {"glGetBufferPointerv", P(gl::GetBufferPointerv)},
+    {"glGetBufferPointervOES", P(gl::GetBufferPointervOES)},
+    {"glGetBufferPointervRobustANGLE", P(gl::GetBufferPointervRobustANGLE)},
+    {"glGetDebugMessageLogKHR", P(gl::GetDebugMessageLogKHR)},
+    {"glGetError", P(gl::GetError)},
+    {"glGetFenceivNV", P(gl::GetFenceivNV)},
+    {"glGetFloatv", P(gl::GetFloatv)},
+    {"glGetFloatvRobustANGLE", P(gl::GetFloatvRobustANGLE)},
+    {"glGetFragDataLocation", P(gl::GetFragDataLocation)},
+    {"glGetFramebufferAttachmentParameteriv", P(gl::GetFramebufferAttachmentParameteriv)},
+    {"glGetFramebufferAttachmentParameterivRobustANGLE",
+     P(gl::GetFramebufferAttachmentParameterivRobustANGLE)},
+    {"glGetFramebufferParameteriv", P(gl::GetFramebufferParameteriv)},
+    {"glGetFramebufferParameterivRobustANGLE", P(gl::GetFramebufferParameterivRobustANGLE)},
+    {"glGetGraphicsResetStatusEXT", P(gl::GetGraphicsResetStatusEXT)},
+    {"glGetInteger64i_v", P(gl::GetInteger64i_v)},
+    {"glGetInteger64i_vRobustANGLE", P(gl::GetInteger64i_vRobustANGLE)},
+    {"glGetInteger64v", P(gl::GetInteger64v)},
+    {"glGetInteger64vRobustANGLE", P(gl::GetInteger64vRobustANGLE)},
+    {"glGetIntegeri_v", P(gl::GetIntegeri_v)},
+    {"glGetIntegeri_vRobustANGLE", P(gl::GetIntegeri_vRobustANGLE)},
+    {"glGetIntegerv", P(gl::GetIntegerv)},
+    {"glGetIntegervRobustANGLE", P(gl::GetIntegervRobustANGLE)},
+    {"glGetInternalformativ", P(gl::GetInternalformativ)},
+    {"glGetInternalformativRobustANGLE", P(gl::GetInternalformativRobustANGLE)},
+    {"glGetMultisamplefv", P(gl::GetMultisamplefv)},
+    {"glGetMultisamplefvRobustANGLE", P(gl::GetMultisamplefvRobustANGLE)},
+    {"glGetObjectLabelKHR", P(gl::GetObjectLabelKHR)},
+    {"glGetObjectPtrLabelKHR", P(gl::GetObjectPtrLabelKHR)},
+    {"glGetPointervKHR", P(gl::GetPointervKHR)},
+    {"glGetPointervRobustANGLERobustANGLE", P(gl::GetPointervRobustANGLERobustANGLE)},
+    {"glGetProgramBinary", P(gl::GetProgramBinary)},
+    {"glGetProgramBinaryOES", P(gl::GetProgramBinaryOES)},
+    {"glGetProgramInfoLog", P(gl::GetProgramInfoLog)},
+    {"glGetProgramInterfaceiv", P(gl::GetProgramInterfaceiv)},
+    {"glGetProgramInterfaceivRobustANGLE", P(gl::GetProgramInterfaceivRobustANGLE)},
+    {"glGetProgramPipelineInfoLog", P(gl::GetProgramPipelineInfoLog)},
+    {"glGetProgramPipelineiv", P(gl::GetProgramPipelineiv)},
+    {"glGetProgramResourceIndex", P(gl::GetProgramResourceIndex)},
+    {"glGetProgramResourceLocation", P(gl::GetProgramResourceLocation)},
+    {"glGetProgramResourceName", P(gl::GetProgramResourceName)},
+    {"glGetProgramResourceiv", P(gl::GetProgramResourceiv)},
+    {"glGetProgramiv", P(gl::GetProgramiv)},
+    {"glGetProgramivRobustANGLE", P(gl::GetProgramivRobustANGLE)},
+    {"glGetQueryObjecti64vEXT", P(gl::GetQueryObjecti64vEXT)},
+    {"glGetQueryObjecti64vRobustANGLE", P(gl::GetQueryObjecti64vRobustANGLE)},
+    {"glGetQueryObjectivEXT", P(gl::GetQueryObjectivEXT)},
+    {"glGetQueryObjectivRobustANGLE", P(gl::GetQueryObjectivRobustANGLE)},
+    {"glGetQueryObjectui64vEXT", P(gl::GetQueryObjectui64vEXT)},
+    {"glGetQueryObjectui64vRobustANGLE", P(gl::GetQueryObjectui64vRobustANGLE)},
+    {"glGetQueryObjectuiv", P(gl::GetQueryObjectuiv)},
+    {"glGetQueryObjectuivEXT", P(gl::GetQueryObjectuivEXT)},
+    {"glGetQueryObjectuivRobustANGLE", P(gl::GetQueryObjectuivRobustANGLE)},
+    {"glGetQueryiv", P(gl::GetQueryiv)},
+    {"glGetQueryivEXT", P(gl::GetQueryivEXT)},
+    {"glGetQueryivRobustANGLE", P(gl::GetQueryivRobustANGLE)},
+    {"glGetRenderbufferParameteriv", P(gl::GetRenderbufferParameteriv)},
+    {"glGetRenderbufferParameterivRobustANGLE", P(gl::GetRenderbufferParameterivRobustANGLE)},
+    {"glGetSamplerParameterIivRobustANGLE", P(gl::GetSamplerParameterIivRobustANGLE)},
+    {"glGetSamplerParameterIuivRobustANGLE", P(gl::GetSamplerParameterIuivRobustANGLE)},
+    {"glGetSamplerParameterfv", P(gl::GetSamplerParameterfv)},
+    {"glGetSamplerParameterfvRobustANGLE", P(gl::GetSamplerParameterfvRobustANGLE)},
+    {"glGetSamplerParameteriv", P(gl::GetSamplerParameteriv)},
+    {"glGetSamplerParameterivRobustANGLE", P(gl::GetSamplerParameterivRobustANGLE)},
+    {"glGetShaderInfoLog", P(gl::GetShaderInfoLog)},
+    {"glGetShaderPrecisionFormat", P(gl::GetShaderPrecisionFormat)},
+    {"glGetShaderSource", P(gl::GetShaderSource)},
+    {"glGetShaderiv", P(gl::GetShaderiv)},
+    {"glGetShaderivRobustANGLE", P(gl::GetShaderivRobustANGLE)},
+    {"glGetString", P(gl::GetString)},
+    {"glGetStringi", P(gl::GetStringi)},
+    {"glGetSynciv", P(gl::GetSynciv)},
+    {"glGetTexLevelParameterfv", P(gl::GetTexLevelParameterfv)},
+    {"glGetTexLevelParameterfvRobustANGLE", P(gl::GetTexLevelParameterfvRobustANGLE)},
+    {"glGetTexLevelParameteriv", P(gl::GetTexLevelParameteriv)},
+    {"glGetTexLevelParameterivRobustANGLE", P(gl::GetTexLevelParameterivRobustANGLE)},
+    {"glGetTexParameterIivRobustANGLE", P(gl::GetTexParameterIivRobustANGLE)},
+    {"glGetTexParameterIuivRobustANGLE", P(gl::GetTexParameterIuivRobustANGLE)},
+    {"glGetTexParameterfv", P(gl::GetTexParameterfv)},
+    {"glGetTexParameterfvRobustANGLE", P(gl::GetTexParameterfvRobustANGLE)},
+    {"glGetTexParameteriv", P(gl::GetTexParameteriv)},
+    {"glGetTexParameterivRobustANGLE", P(gl::GetTexParameterivRobustANGLE)},
+    {"glGetTransformFeedbackVarying", P(gl::GetTransformFeedbackVarying)},
+    {"glGetTranslatedShaderSourceANGLE", P(gl::GetTranslatedShaderSourceANGLE)},
+    {"glGetUniformBlockIndex", P(gl::GetUniformBlockIndex)},
+    {"glGetUniformIndices", P(gl::GetUniformIndices)},
+    {"glGetUniformLocation", P(gl::GetUniformLocation)},
+    {"glGetUniformfv", P(gl::GetUniformfv)},
+    {"glGetUniformfvRobustANGLE", P(gl::GetUniformfvRobustANGLE)},
+    {"glGetUniformiv", P(gl::GetUniformiv)},
+    {"glGetUniformivRobustANGLE", P(gl::GetUniformivRobustANGLE)},
+    {"glGetUniformuiv", P(gl::GetUniformuiv)},
+    {"glGetUniformuivRobustANGLE", P(gl::GetUniformuivRobustANGLE)},
+    {"glGetVertexAttribIiv", P(gl::GetVertexAttribIiv)},
+    {"glGetVertexAttribIivRobustANGLE", P(gl::GetVertexAttribIivRobustANGLE)},
+    {"glGetVertexAttribIuiv", P(gl::GetVertexAttribIuiv)},
+    {"glGetVertexAttribIuivRobustANGLE", P(gl::GetVertexAttribIuivRobustANGLE)},
+    {"glGetVertexAttribPointerv", P(gl::GetVertexAttribPointerv)},
+    {"glGetVertexAttribPointervRobustANGLE", P(gl::GetVertexAttribPointervRobustANGLE)},
+    {"glGetVertexAttribfv", P(gl::GetVertexAttribfv)},
+    {"glGetVertexAttribfvRobustANGLE", P(gl::GetVertexAttribfvRobustANGLE)},
+    {"glGetVertexAttribiv", P(gl::GetVertexAttribiv)},
+    {"glGetVertexAttribivRobustANGLE", P(gl::GetVertexAttribivRobustANGLE)},
+    {"glGetnUniformfvEXT", P(gl::GetnUniformfvEXT)},
+    {"glGetnUniformfvRobustANGLE", P(gl::GetnUniformfvRobustANGLE)},
+    {"glGetnUniformivEXT", P(gl::GetnUniformivEXT)},
+    {"glGetnUniformivRobustANGLE", P(gl::GetnUniformivRobustANGLE)},
+    {"glGetnUniformuivRobustANGLE", P(gl::GetnUniformuivRobustANGLE)},
+    {"glHint", P(gl::Hint)},
+    {"glInsertEventMarkerEXT", P(gl::InsertEventMarkerEXT)},
+    {"glInvalidateFramebuffer", P(gl::InvalidateFramebuffer)},
+    {"glInvalidateSubFramebuffer", P(gl::InvalidateSubFramebuffer)},
+    {"glIsBuffer", P(gl::IsBuffer)},
+    {"glIsEnabled", P(gl::IsEnabled)},
+    {"glIsFenceNV", P(gl::IsFenceNV)},
+    {"glIsFramebuffer", P(gl::IsFramebuffer)},
+    {"glIsProgram", P(gl::IsProgram)},
+    {"glIsProgramPipeline", P(gl::IsProgramPipeline)},
+    {"glIsQuery", P(gl::IsQuery)},
+    {"glIsQueryEXT", P(gl::IsQueryEXT)},
+    {"glIsRenderbuffer", P(gl::IsRenderbuffer)},
+    {"glIsSampler", P(gl::IsSampler)},
+    {"glIsShader", P(gl::IsShader)},
+    {"glIsSync", P(gl::IsSync)},
+    {"glIsTexture", P(gl::IsTexture)},
+    {"glIsTransformFeedback", P(gl::IsTransformFeedback)},
+    {"glIsVertexArray", P(gl::IsVertexArray)},
+    {"glIsVertexArrayOES", P(gl::IsVertexArrayOES)},
+    {"glLineWidth", P(gl::LineWidth)},
+    {"glLinkProgram", P(gl::LinkProgram)},
+    {"glMapBufferOES", P(gl::MapBufferOES)},
+    {"glMapBufferRange", P(gl::MapBufferRange)},
+    {"glMapBufferRangeEXT", P(gl::MapBufferRangeEXT)},
+    {"glMemoryBarrier", P(gl::MemoryBarrier)},
+    {"glMemoryBarrierByRegion", P(gl::MemoryBarrierByRegion)},
+    {"glObjectLabelKHR", P(gl::ObjectLabelKHR)},
+    {"glObjectPtrLabelKHR", P(gl::ObjectPtrLabelKHR)},
+    {"glPauseTransformFeedback", P(gl::PauseTransformFeedback)},
+    {"glPixelStorei", P(gl::PixelStorei)},
+    {"glPolygonOffset", P(gl::PolygonOffset)},
+    {"glPopDebugGroupKHR", P(gl::PopDebugGroupKHR)},
+    {"glPopGroupMarkerEXT", P(gl::PopGroupMarkerEXT)},
+    {"glProgramBinary", P(gl::ProgramBinary)},
+    {"glProgramBinaryOES", P(gl::ProgramBinaryOES)},
+    {"glProgramParameteri", P(gl::ProgramParameteri)},
+    {"glProgramUniform1f", P(gl::ProgramUniform1f)},
+    {"glProgramUniform1fv", P(gl::ProgramUniform1fv)},
+    {"glProgramUniform1i", P(gl::ProgramUniform1i)},
+    {"glProgramUniform1iv", P(gl::ProgramUniform1iv)},
+    {"glProgramUniform1ui", P(gl::ProgramUniform1ui)},
+    {"glProgramUniform1uiv", P(gl::ProgramUniform1uiv)},
+    {"glProgramUniform2f", P(gl::ProgramUniform2f)},
+    {"glProgramUniform2fv", P(gl::ProgramUniform2fv)},
+    {"glProgramUniform2i", P(gl::ProgramUniform2i)},
+    {"glProgramUniform2iv", P(gl::ProgramUniform2iv)},
+    {"glProgramUniform2ui", P(gl::ProgramUniform2ui)},
+    {"glProgramUniform2uiv", P(gl::ProgramUniform2uiv)},
+    {"glProgramUniform3f", P(gl::ProgramUniform3f)},
+    {"glProgramUniform3fv", P(gl::ProgramUniform3fv)},
+    {"glProgramUniform3i", P(gl::ProgramUniform3i)},
+    {"glProgramUniform3iv", P(gl::ProgramUniform3iv)},
+    {"glProgramUniform3ui", P(gl::ProgramUniform3ui)},
+    {"glProgramUniform3uiv", P(gl::ProgramUniform3uiv)},
+    {"glProgramUniform4f", P(gl::ProgramUniform4f)},
+    {"glProgramUniform4fv", P(gl::ProgramUniform4fv)},
+    {"glProgramUniform4i", P(gl::ProgramUniform4i)},
+    {"glProgramUniform4iv", P(gl::ProgramUniform4iv)},
+    {"glProgramUniform4ui", P(gl::ProgramUniform4ui)},
+    {"glProgramUniform4uiv", P(gl::ProgramUniform4uiv)},
+    {"glProgramUniformMatrix2fv", P(gl::ProgramUniformMatrix2fv)},
+    {"glProgramUniformMatrix2x3fv", P(gl::ProgramUniformMatrix2x3fv)},
+    {"glProgramUniformMatrix2x4fv", P(gl::ProgramUniformMatrix2x4fv)},
+    {"glProgramUniformMatrix3fv", P(gl::ProgramUniformMatrix3fv)},
+    {"glProgramUniformMatrix3x2fv", P(gl::ProgramUniformMatrix3x2fv)},
+    {"glProgramUniformMatrix3x4fv", P(gl::ProgramUniformMatrix3x4fv)},
+    {"glProgramUniformMatrix4fv", P(gl::ProgramUniformMatrix4fv)},
+    {"glProgramUniformMatrix4x2fv", P(gl::ProgramUniformMatrix4x2fv)},
+    {"glProgramUniformMatrix4x3fv", P(gl::ProgramUniformMatrix4x3fv)},
+    {"glPushDebugGroupKHR", P(gl::PushDebugGroupKHR)},
+    {"glPushGroupMarkerEXT", P(gl::PushGroupMarkerEXT)},
+    {"glQueryCounterEXT", P(gl::QueryCounterEXT)},
+    {"glReadBuffer", P(gl::ReadBuffer)},
+    {"glReadPixels", P(gl::ReadPixels)},
+    {"glReadPixelsRobustANGLE", P(gl::ReadPixelsRobustANGLE)},
+    {"glReadnPixelsEXT", P(gl::ReadnPixelsEXT)},
+    {"glReadnPixelsRobustANGLE", P(gl::ReadnPixelsRobustANGLE)},
+    {"glReleaseShaderCompiler", P(gl::ReleaseShaderCompiler)},
+    {"glRenderbufferStorage", P(gl::RenderbufferStorage)},
+    {"glRenderbufferStorageMultisample", P(gl::RenderbufferStorageMultisample)},
+    {"glRenderbufferStorageMultisampleANGLE", P(gl::RenderbufferStorageMultisampleANGLE)},
+    {"glRequestExtensionANGLE", P(gl::RequestExtensionANGLE)},
+    {"glResumeTransformFeedback", P(gl::ResumeTransformFeedback)},
+    {"glSampleCoverage", P(gl::SampleCoverage)},
+    {"glSampleMaski", P(gl::SampleMaski)},
+    {"glSamplerParameterIivRobustANGLE", P(gl::SamplerParameterIivRobustANGLE)},
+    {"glSamplerParameterIuivRobustANGLE", P(gl::SamplerParameterIuivRobustANGLE)},
+    {"glSamplerParameterf", P(gl::SamplerParameterf)},
+    {"glSamplerParameterfv", P(gl::SamplerParameterfv)},
+    {"glSamplerParameterfvRobustANGLE", P(gl::SamplerParameterfvRobustANGLE)},
+    {"glSamplerParameteri", P(gl::SamplerParameteri)},
+    {"glSamplerParameteriv", P(gl::SamplerParameteriv)},
+    {"glSamplerParameterivRobustANGLE", P(gl::SamplerParameterivRobustANGLE)},
+    {"glScissor", P(gl::Scissor)},
+    {"glSetFenceNV", P(gl::SetFenceNV)},
+    {"glShaderBinary", P(gl::ShaderBinary)},
+    {"glShaderSource", P(gl::ShaderSource)},
+    {"glStencilFunc", P(gl::StencilFunc)},
+    {"glStencilFuncSeparate", P(gl::StencilFuncSeparate)},
+    {"glStencilMask", P(gl::StencilMask)},
+    {"glStencilMaskSeparate", P(gl::StencilMaskSeparate)},
+    {"glStencilOp", P(gl::StencilOp)},
+    {"glStencilOpSeparate", P(gl::StencilOpSeparate)},
+    {"glTestFenceNV", P(gl::TestFenceNV)},
+    {"glTexImage2D", P(gl::TexImage2D)},
+    {"glTexImage2DRobustANGLE", P(gl::TexImage2DRobustANGLE)},
+    {"glTexImage3D", P(gl::TexImage3D)},
+    {"glTexImage3DRobustANGLE", P(gl::TexImage3DRobustANGLE)},
+    {"glTexParameterIivRobustANGLE", P(gl::TexParameterIivRobustANGLE)},
+    {"glTexParameterIuivRobustANGLE", P(gl::TexParameterIuivRobustANGLE)},
+    {"glTexParameterf", P(gl::TexParameterf)},
+    {"glTexParameterfv", P(gl::TexParameterfv)},
+    {"glTexParameterfvRobustANGLE", P(gl::TexParameterfvRobustANGLE)},
+    {"glTexParameteri", P(gl::TexParameteri)},
+    {"glTexParameteriv", P(gl::TexParameteriv)},
+    {"glTexParameterivRobustANGLE", P(gl::TexParameterivRobustANGLE)},
+    {"glTexStorage2D", P(gl::TexStorage2D)},
+    {"glTexStorage2DEXT", P(gl::TexStorage2DEXT)},
+    {"glTexStorage2DMultisample", P(gl::TexStorage2DMultisample)},
+    {"glTexStorage3D", P(gl::TexStorage3D)},
+    {"glTexSubImage2D", P(gl::TexSubImage2D)},
+    {"glTexSubImage2DRobustANGLE", P(gl::TexSubImage2DRobustANGLE)},
+    {"glTexSubImage3D", P(gl::TexSubImage3D)},
+    {"glTexSubImage3DRobustANGLE", P(gl::TexSubImage3DRobustANGLE)},
+    {"glTransformFeedbackVaryings", P(gl::TransformFeedbackVaryings)},
+    {"glUniform1f", P(gl::Uniform1f)},
+    {"glUniform1fv", P(gl::Uniform1fv)},
+    {"glUniform1i", P(gl::Uniform1i)},
+    {"glUniform1iv", P(gl::Uniform1iv)},
+    {"glUniform1ui", P(gl::Uniform1ui)},
+    {"glUniform1uiv", P(gl::Uniform1uiv)},
+    {"glUniform2f", P(gl::Uniform2f)},
+    {"glUniform2fv", P(gl::Uniform2fv)},
+    {"glUniform2i", P(gl::Uniform2i)},
+    {"glUniform2iv", P(gl::Uniform2iv)},
+    {"glUniform2ui", P(gl::Uniform2ui)},
+    {"glUniform2uiv", P(gl::Uniform2uiv)},
+    {"glUniform3f", P(gl::Uniform3f)},
+    {"glUniform3fv", P(gl::Uniform3fv)},
+    {"glUniform3i", P(gl::Uniform3i)},
+    {"glUniform3iv", P(gl::Uniform3iv)},
+    {"glUniform3ui", P(gl::Uniform3ui)},
+    {"glUniform3uiv", P(gl::Uniform3uiv)},
+    {"glUniform4f", P(gl::Uniform4f)},
+    {"glUniform4fv", P(gl::Uniform4fv)},
+    {"glUniform4i", P(gl::Uniform4i)},
+    {"glUniform4iv", P(gl::Uniform4iv)},
+    {"glUniform4ui", P(gl::Uniform4ui)},
+    {"glUniform4uiv", P(gl::Uniform4uiv)},
+    {"glUniformBlockBinding", P(gl::UniformBlockBinding)},
+    {"glUniformMatrix2fv", P(gl::UniformMatrix2fv)},
+    {"glUniformMatrix2x3fv", P(gl::UniformMatrix2x3fv)},
+    {"glUniformMatrix2x4fv", P(gl::UniformMatrix2x4fv)},
+    {"glUniformMatrix3fv", P(gl::UniformMatrix3fv)},
+    {"glUniformMatrix3x2fv", P(gl::UniformMatrix3x2fv)},
+    {"glUniformMatrix3x4fv", P(gl::UniformMatrix3x4fv)},
+    {"glUniformMatrix4fv", P(gl::UniformMatrix4fv)},
+    {"glUniformMatrix4x2fv", P(gl::UniformMatrix4x2fv)},
+    {"glUniformMatrix4x3fv", P(gl::UniformMatrix4x3fv)},
+    {"glUnmapBuffer", P(gl::UnmapBuffer)},
+    {"glUnmapBufferOES", P(gl::UnmapBufferOES)},
+    {"glUseProgram", P(gl::UseProgram)},
+    {"glUseProgramStages", P(gl::UseProgramStages)},
+    {"glValidateProgram", P(gl::ValidateProgram)},
+    {"glValidateProgramPipeline", P(gl::ValidateProgramPipeline)},
+    {"glVertexAttrib1f", P(gl::VertexAttrib1f)},
+    {"glVertexAttrib1fv", P(gl::VertexAttrib1fv)},
+    {"glVertexAttrib2f", P(gl::VertexAttrib2f)},
+    {"glVertexAttrib2fv", P(gl::VertexAttrib2fv)},
+    {"glVertexAttrib3f", P(gl::VertexAttrib3f)},
+    {"glVertexAttrib3fv", P(gl::VertexAttrib3fv)},
+    {"glVertexAttrib4f", P(gl::VertexAttrib4f)},
+    {"glVertexAttrib4fv", P(gl::VertexAttrib4fv)},
+    {"glVertexAttribBinding", P(gl::VertexAttribBinding)},
+    {"glVertexAttribDivisor", P(gl::VertexAttribDivisor)},
+    {"glVertexAttribDivisorANGLE", P(gl::VertexAttribDivisorANGLE)},
+    {"glVertexAttribFormat", P(gl::VertexAttribFormat)},
+    {"glVertexAttribI4i", P(gl::VertexAttribI4i)},
+    {"glVertexAttribI4iv", P(gl::VertexAttribI4iv)},
+    {"glVertexAttribI4ui", P(gl::VertexAttribI4ui)},
+    {"glVertexAttribI4uiv", P(gl::VertexAttribI4uiv)},
+    {"glVertexAttribIFormat", P(gl::VertexAttribIFormat)},
+    {"glVertexAttribIPointer", P(gl::VertexAttribIPointer)},
+    {"glVertexAttribPointer", P(gl::VertexAttribPointer)},
+    {"glVertexBindingDivisor", P(gl::VertexBindingDivisor)},
+    {"glViewport", P(gl::Viewport)},
+    {"glWaitSync", P(gl::WaitSync)}};
+
+size_t g_numProcs = 516;
+}  // namespace egl
new file mode 100644
--- /dev/null
+++ b/gfx/angle/src/libGLESv2/proc_table_data.json
@@ -0,0 +1,662 @@
+{
+    "GLES2 core": [
+        "glActiveTexture",
+        "glAttachShader",
+        "glBindAttribLocation",
+        "glBindBuffer",
+        "glBindFramebuffer",
+        "glBindRenderbuffer",
+        "glBindTexture",
+        "glBlendColor",
+        "glBlendEquation",
+        "glBlendEquationSeparate",
+        "glBlendFunc",
+        "glBlendFuncSeparate",
+        "glBufferData",
+        "glBufferSubData",
+        "glCheckFramebufferStatus",
+        "glClear",
+        "glClearColor",
+        "glClearDepthf",
+        "glClearStencil",
+        "glCompileShader",
+        "glColorMask",
+        "glCompressedTexImage2D",
+        "glCompressedTexSubImage2D",
+        "glCopyTexImage2D",
+        "glCopyTexSubImage2D",
+        "glCreateProgram",
+        "glCreateShader",
+        "glCullFace",
+        "glDeleteBuffers",
+        "glDeleteFramebuffers",
+        "glDeleteProgram",
+        "glDeleteRenderbuffers",
+        "glDeleteShader",
+        "glDeleteTextures",
+        "glDepthFunc",
+        "glDepthMask",
+        "glDepthRangef",
+        "glDetachShader",
+        "glDisable",
+        "glDisableVertexAttribArray",
+        "glDrawArrays",
+        "glDrawElements",
+        "glEnable",
+        "glEnableVertexAttribArray",
+        "glFinish",
+        "glFlush",
+        "glFramebufferRenderbuffer",
+        "glFramebufferTexture2D",
+        "glFrontFace",
+        "glGenBuffers",
+        "glGenerateMipmap",
+        "glGenFramebuffers",
+        "glGenRenderbuffers",
+        "glGenTextures",
+        "glGetActiveAttrib",
+        "glGetActiveUniform",
+        "glGetAttachedShaders",
+        "glGetAttribLocation",
+        "glGetBooleanv",
+        "glGetBufferParameteriv",
+        "glGetError",
+        "glGetFloatv",
+        "glGetFramebufferAttachmentParameteriv",
+        "glGetIntegerv",
+        "glGetProgramiv",
+        "glGetProgramInfoLog",
+        "glGetRenderbufferParameteriv",
+        "glGetShaderiv",
+        "glGetShaderInfoLog",
+        "glGetShaderPrecisionFormat",
+        "glGetShaderSource",
+        "glGetString",
+        "glGetTexParameterfv",
+        "glGetTexParameteriv",
+        "glGetUniformfv",
+        "glGetUniformiv",
+        "glGetUniformLocation",
+        "glGetVertexAttribfv",
+        "glGetVertexAttribiv",
+        "glGetVertexAttribPointerv",
+        "glHint",
+        "glIsBuffer",
+        "glIsEnabled",
+        "glIsFramebuffer",
+        "glIsProgram",
+        "glIsRenderbuffer",
+        "glIsShader",
+        "glIsTexture",
+        "glLineWidth",
+        "glLinkProgram",
+        "glPixelStorei",
+        "glPolygonOffset",
+        "glReadPixels",
+        "glReleaseShaderCompiler",
+        "glRenderbufferStorage",
+        "glSampleCoverage",
+        "glScissor",
+        "glShaderBinary",
+        "glShaderSource",
+        "glStencilFunc",
+        "glStencilFuncSeparate",
+        "glStencilMask",
+        "glStencilMaskSeparate",
+        "glStencilOp",
+        "glStencilOpSeparate",
+        "glTexImage2D",
+        "glTexParameterf",
+        "glTexParameterfv",
+        "glTexParameteri",
+        "glTexParameteriv",
+        "glTexSubImage2D",
+        "glUniform1f",
+        "glUniform1fv",
+        "glUniform1i",
+        "glUniform1iv",
+        "glUniform2f",
+        "glUniform2fv",
+        "glUniform2i",
+        "glUniform2iv",
+        "glUniform3f",
+        "glUniform3fv",
+        "glUniform3i",
+        "glUniform3iv",
+        "glUniform4f",
+        "glUniform4fv",
+        "glUniform4i",
+        "glUniform4iv",
+        "glUniformMatrix2fv",
+        "glUniformMatrix3fv",
+        "glUniformMatrix4fv",
+        "glUseProgram",
+        "glValidateProgram",
+        "glVertexAttrib1f",
+        "glVertexAttrib1fv",
+        "glVertexAttrib2f",
+        "glVertexAttrib2fv",
+        "glVertexAttrib3f",
+        "glVertexAttrib3fv",
+        "glVertexAttrib4f",
+        "glVertexAttrib4fv",
+        "glVertexAttribPointer",
+        "glViewport"
+    ],
+
+    "GL_ANGLE_framebuffer_blit": [
+        "glBlitFramebufferANGLE"
+    ],
+
+    "GL_ANGLE_framebuffer_multisample": [
+        "glRenderbufferStorageMultisampleANGLE"
+    ],
+
+    "GL_EXT_discard_framebuffer": [
+        "glDiscardFramebufferEXT"
+    ],
+
+    "GL_NV_fence": [
+        "glDeleteFencesNV",
+        "glGenFencesNV",
+        "glIsFenceNV",
+        "glTestFenceNV",
+        "glGetFenceivNV",
+        "glFinishFenceNV",
+        "glSetFenceNV"
+    ],
+
+    "GL_ANGLE_translated_shader_source": [
+        "glGetTranslatedShaderSourceANGLE"
+    ],
+
+    "GL_EXT_texture_storage": [
+        "glTexStorage2DEXT"
+    ],
+
+    "GL_EXT_robustness": [
+        "glGetGraphicsResetStatusEXT",
+        "glReadnPixelsEXT",
+        "glGetnUniformfvEXT",
+        "glGetnUniformivEXT"
+    ],
+
+    "GL_EXT_occlusion_query_boolean": [
+        "glGenQueriesEXT",
+        "glDeleteQueriesEXT",
+        "glIsQueryEXT",
+        "glBeginQueryEXT",
+        "glEndQueryEXT",
+        "glGetQueryivEXT",
+        "glGetQueryObjectuivEXT"
+    ],
+
+    "GL_EXT_disjoint_timer_query": [
+        "glGenQueriesEXT",
+        "glDeleteQueriesEXT",
+        "glIsQueryEXT",
+        "glBeginQueryEXT",
+        "glEndQueryEXT",
+        "glQueryCounterEXT",
+        "glGetQueryivEXT",
+        "glGetQueryObjectivEXT",
+        "glGetQueryObjectuivEXT",
+        "glGetQueryObjecti64vEXT",
+        "glGetQueryObjectui64vEXT"
+    ],
+
+    "GL_EXT_draw_buffers": [
+        "glDrawBuffersEXT"
+    ],
+
+    "GL_ANGLE_instanced_arrays": [
+        "glDrawArraysInstancedANGLE",
+        "glDrawElementsInstancedANGLE",
+        "glVertexAttribDivisorANGLE"
+    ],
+
+    "GL_OES_get_program_binary": [
+        "glGetProgramBinaryOES",
+        "glProgramBinaryOES"
+    ],
+
+    "GL_OES_mapbuffer": [
+        "glMapBufferOES",
+        "glUnmapBufferOES",
+        "glGetBufferPointervOES"
+    ],
+
+    "GL_EXT_map_buffer_range": [
+        "glMapBufferRangeEXT",
+        "glFlushMappedBufferRangeEXT"
+    ],
+
+    "GL_EXT_debug_marker": [
+        "glInsertEventMarkerEXT",
+        "glPushGroupMarkerEXT",
+        "glPopGroupMarkerEXT"
+    ],
+
+    "GL_OES_EGL_image": [
+        "glEGLImageTargetTexture2DOES",
+        "glEGLImageTargetRenderbufferStorageOES"
+    ],
+
+    "GL_OES_vertex_array_object": [
+        "glBindVertexArrayOES",
+        "glDeleteVertexArraysOES",
+        "glGenVertexArraysOES",
+        "glIsVertexArrayOES"
+    ],
+
+    "GL_KHR_debug": [
+        "glDebugMessageControlKHR",
+        "glDebugMessageInsertKHR",
+        "glDebugMessageCallbackKHR",
+        "glGetDebugMessageLogKHR",
+        "glPushDebugGroupKHR",
+        "glPopDebugGroupKHR",
+        "glObjectLabelKHR",
+        "glGetObjectLabelKHR",
+        "glObjectPtrLabelKHR",
+        "glGetObjectPtrLabelKHR",
+        "glGetPointervKHR"
+    ],
+
+    "GL_CHROMIUM_bind_uniform_location": [
+        "glBindUniformLocationCHROMIUM"
+    ],
+
+    "GL_CHROMIUM_copy_texture": [
+        "glCopyTextureCHROMIUM",
+        "glCopySubTextureCHROMIUM"
+    ],
+
+    "GL_CHROMIUM_copy_compressed_texture": [
+        "glCompressedCopyTextureCHROMIUM"
+    ],
+
+    "GL_ANGLE_request_extension": [
+        "glRequestExtensionANGLE"
+    ],
+
+    "GL_ANGLE_robust_client_memory": [
+        "glGetBooleanvRobustANGLE",
+        "glGetBufferParameterivRobustANGLE",
+        "glGetFloatvRobustANGLE",
+        "glGetFramebufferAttachmentParameterivRobustANGLE",
+        "glGetIntegervRobustANGLE",
+        "glGetProgramivRobustANGLE",
+        "glGetRenderbufferParameterivRobustANGLE",
+        "glGetShaderivRobustANGLE",
+        "glGetTexParameterfvRobustANGLE",
+        "glGetTexParameterivRobustANGLE",
+        "glGetUniformfvRobustANGLE",
+        "glGetUniformivRobustANGLE",
+        "glGetVertexAttribfvRobustANGLE",
+        "glGetVertexAttribivRobustANGLE",
+        "glGetVertexAttribPointervRobustANGLE",
+        "glReadPixelsRobustANGLE",
+        "glTexImage2DRobustANGLE",
+        "glTexParameterfvRobustANGLE",
+        "glTexParameterivRobustANGLE",
+        "glTexSubImage2DRobustANGLE",
+        "glTexImage3DRobustANGLE",
+        "glTexSubImage3DRobustANGLE",
+        "glCompressedTexImage2DRobustANGLE",
+        "glCompressedTexSubImage2DRobustANGLE",
+        "glCompressedTexImage3DRobustANGLE",
+        "glCompressedTexSubImage3DRobustANGLE",
+        "glGetQueryivRobustANGLE",
+        "glGetQueryObjectuivRobustANGLE",
+        "glGetBufferPointervRobustANGLE",
+        "glGetIntegeri_vRobustANGLE",
+        "glGetInternalformativRobustANGLE",
+        "glGetVertexAttribIivRobustANGLE",
+        "glGetVertexAttribIuivRobustANGLE",
+        "glGetUniformuivRobustANGLE",
+        "glGetActiveUniformBlockivRobustANGLE",
+        "glGetInteger64vRobustANGLE",
+        "glGetInteger64i_vRobustANGLE",
+        "glGetBufferParameteri64vRobustANGLE",
+        "glSamplerParameterivRobustANGLE",
+        "glSamplerParameterfvRobustANGLE",
+        "glGetSamplerParameterivRobustANGLE",
+        "glGetSamplerParameterfvRobustANGLE",
+        "glGetFramebufferParameterivRobustANGLE",
+        "glGetProgramInterfaceivRobustANGLE",
+        "glGetBooleani_vRobustANGLE",
+        "glGetMultisamplefvRobustANGLE",
+        "glGetTexLevelParameterivRobustANGLE",
+        "glGetTexLevelParameterfvRobustANGLE",
+        "glGetPointervRobustANGLERobustANGLE",
+        "glReadnPixelsRobustANGLE",
+        "glGetnUniformfvRobustANGLE",
+        "glGetnUniformivRobustANGLE",
+        "glGetnUniformuivRobustANGLE",
+        "glTexParameterIivRobustANGLE",
+        "glTexParameterIuivRobustANGLE",
+        "glGetTexParameterIivRobustANGLE",
+        "glGetTexParameterIuivRobustANGLE",
+        "glSamplerParameterIivRobustANGLE",
+        "glSamplerParameterIuivRobustANGLE",
+        "glGetSamplerParameterIivRobustANGLE",
+        "glGetSamplerParameterIuivRobustANGLE",
+        "glGetQueryObjectivRobustANGLE",
+        "glGetQueryObjecti64vRobustANGLE",
+        "glGetQueryObjectui64vRobustANGLE"
+    ],
+
+    "GL_ANGLE_multiview": [
+        "glFramebufferTextureMultiviewLayeredANGLE",
+        "glFramebufferTextureMultiviewSideBySideANGLE"
+    ],
+
+    "GLES3 core": [
+        "glReadBuffer",
+        "glDrawRangeElements",
+        "glTexImage3D",
+        "glTexSubImage3D",
+        "glCopyTexSubImage3D",
+        "glCompressedTexImage3D",
+        "glCompressedTexSubImage3D",
+        "glGenQueries",
+        "glDeleteQueries",
+        "glIsQuery",
+        "glBeginQuery",
+        "glEndQuery",
+        "glGetQueryiv",
+        "glGetQueryObjectuiv",
+        "glUnmapBuffer",
+        "glGetBufferPointerv",
+        "glDrawBuffers",
+        "glUniformMatrix2x3fv",
+        "glUniformMatrix3x2fv",
+        "glUniformMatrix2x4fv",
+        "glUniformMatrix4x2fv",
+        "glUniformMatrix3x4fv",
+        "glUniformMatrix4x3fv",
+        "glBlitFramebuffer",
+        "glRenderbufferStorageMultisample",
+        "glFramebufferTextureLayer",
+        "glMapBufferRange",
+        "glFlushMappedBufferRange",
+        "glBindVertexArray",
+        "glDeleteVertexArrays",
+        "glGenVertexArrays",
+        "glIsVertexArray",
+        "glGetIntegeri_v",
+        "glBeginTransformFeedback",
+        "glEndTransformFeedback",
+        "glBindBufferRange",
+        "glBindBufferBase",
+        "glTransformFeedbackVaryings",
+        "glGetTransformFeedbackVarying",
+        "glVertexAttribIPointer",
+        "glGetVertexAttribIiv",
+        "glGetVertexAttribIuiv",
+        "glVertexAttribI4i",
+        "glVertexAttribI4ui",
+        "glVertexAttribI4iv",
+        "glVertexAttribI4uiv",
+        "glGetUniformuiv",
+        "glGetFragDataLocation",
+        "glUniform1ui",
+        "glUniform2ui",
+        "glUniform3ui",
+        "glUniform4ui",
+        "glUniform1uiv",
+        "glUniform2uiv",
+        "glUniform3uiv",
+        "glUniform4uiv",
+        "glClearBufferiv",
+        "glClearBufferuiv",
+        "glClearBufferfv",
+        "glClearBufferfi",
+        "glGetStringi",
+        "glCopyBufferSubData",
+        "glGetUniformIndices",
+        "glGetActiveUniformsiv",
+        "glGetUniformBlockIndex",
+        "glGetActiveUniformBlockiv",
+        "glGetActiveUniformBlockName",
+        "glUniformBlockBinding",
+        "glDrawArraysInstanced",
+        "glDrawElementsInstanced",
+        "glFenceSync",
+        "glIsSync",
+        "glDeleteSync",
+        "glClientWaitSync",
+        "glWaitSync",
+        "glGetInteger64v",
+        "glGetSynciv",
+        "glGetInteger64i_v",
+        "glGetBufferParameteri64v",
+        "glGenSamplers",
+        "glDeleteSamplers",
+        "glIsSampler",
+        "glBindSampler",
+        "glSamplerParameteri",
+        "glSamplerParameteriv",
+        "glSamplerParameterf",
+        "glSamplerParameterfv",
+        "glGetSamplerParameteriv",
+        "glGetSamplerParameterfv",
+        "glVertexAttribDivisor",
+        "glBindTransformFeedback",
+        "glDeleteTransformFeedbacks",
+        "glGenTransformFeedbacks",
+        "glIsTransformFeedback",
+        "glPauseTransformFeedback",
+        "glResumeTransformFeedback",
+        "glGetProgramBinary",
+        "glProgramBinary",
+        "glProgramParameteri",
+        "glInvalidateFramebuffer",
+        "glInvalidateSubFramebuffer",
+        "glTexStorage2D",
+        "glTexStorage3D",
+        "glGetInternalformativ"
+    ],
+
+    "GLES31 core": [
+        "glDispatchCompute",
+        "glDispatchComputeIndirect",
+        "glDrawArraysIndirect",
+        "glDrawElementsIndirect",
+        "glFramebufferParameteri",
+        "glGetFramebufferParameteriv",
+        "glGetProgramInterfaceiv",
+        "glGetProgramResourceIndex",
+        "glGetProgramResourceName",
+        "glGetProgramResourceiv",
+        "glGetProgramResourceLocation",
+        "glUseProgramStages",
+        "glActiveShaderProgram",
+        "glCreateShaderProgramv",
+        "glBindProgramPipeline",
+        "glDeleteProgramPipelines",
+        "glGenProgramPipelines",
+        "glIsProgramPipeline",
+        "glGetProgramPipelineiv",
+        "glProgramUniform1i",
+        "glProgramUniform2i",
+        "glProgramUniform3i",
+        "glProgramUniform4i",
+        "glProgramUniform1ui",
+        "glProgramUniform2ui",
+        "glProgramUniform3ui",
+        "glProgramUniform4ui",
+        "glProgramUniform1f",
+        "glProgramUniform2f",
+        "glProgramUniform3f",
+        "glProgramUniform4f",
+        "glProgramUniform1iv",
+        "glProgramUniform2iv",
+        "glProgramUniform3iv",
+        "glProgramUniform4iv",
+        "glProgramUniform1uiv",
+        "glProgramUniform2uiv",
+        "glProgramUniform3uiv",
+        "glProgramUniform4uiv",
+        "glProgramUniform1fv",
+        "glProgramUniform2fv",
+        "glProgramUniform3fv",
+        "glProgramUniform4fv",
+        "glProgramUniformMatrix2fv",
+        "glProgramUniformMatrix3fv",
+        "glProgramUniformMatrix4fv",
+        "glProgramUniformMatrix2x3fv",
+        "glProgramUniformMatrix3x2fv",
+        "glProgramUniformMatrix2x4fv",
+        "glProgramUniformMatrix4x2fv",
+        "glProgramUniformMatrix3x4fv",
+        "glProgramUniformMatrix4x3fv",
+        "glValidateProgramPipeline",
+        "glGetProgramPipelineInfoLog",
+        "glBindImageTexture",
+        "glGetBooleani_v",
+        "glMemoryBarrier",
+        "glMemoryBarrierByRegion",
+        "glTexStorage2DMultisample",
+        "glGetMultisamplefv",
+        "glSampleMaski",
+        "glGetTexLevelParameteriv",
+        "glGetTexLevelParameterfv",
+        "glBindVertexBuffer",
+        "glVertexAttribFormat",
+        "glVertexAttribIFormat",
+        "glVertexAttribBinding",
+        "glVertexBindingDivisor"
+    ],
+
+    "EGL 1.0": [
+        "eglChooseConfig",
+        "eglCopyBuffers",
+        "eglCreateContext",
+        "eglCreatePbufferSurface",
+        "eglCreatePixmapSurface",
+        "eglCreateWindowSurface",
+        "eglDestroyContext",
+        "eglDestroySurface",
+        "eglGetConfigAttrib",
+        "eglGetConfigs",
+        "eglGetCurrentDisplay",
+        "eglGetCurrentSurface",
+        "eglGetDisplay",
+        "eglGetError",
+        "eglGetProcAddress",
+        "eglInitialize",
+        "eglMakeCurrent",
+        "eglQueryContext",
+        "eglQueryString",
+        "eglQuerySurface",
+        "eglSwapBuffers",
+        "eglTerminate",
+        "eglWaitGL",
+        "eglWaitNative"
+    ],
+
+    "EGL 1.1": [
+        "eglBindTexImage",
+        "eglReleaseTexImage",
+        "eglSurfaceAttrib",
+        "eglSwapInterval"
+    ],
+
+    "EGL 1.2": [
+        "eglBindAPI",
+        "eglQueryAPI",
+        "eglCreatePbufferFromClientBuffer",
+        "eglReleaseThread",
+        "eglWaitClient"
+    ],
+
+    "EGL 1.4": [
+        "eglGetCurrentContext"
+    ],
+
+    "EGL 1.5": [
+        "eglCreateSync",
+        "eglDestroySync",
+        "eglClientWaitSync",
+        "eglGetSyncAttrib",
+        "eglCreateImage",
+        "eglDestroyImage",
+        "eglGetPlatformDisplay",
+        "eglCreatePlatformWindowSurface",
+        "eglCreatePlatformPixmapSurface",
+        "eglWaitSync"
+    ],
+
+    "EGL_ANGLE_query_surface_pointer": [
+        "eglQuerySurfacePointerANGLE"
+    ],
+
+    "EGL_NV_post_sub_buffer": [
+        "eglPostSubBufferNV"
+    ],
+
+    "EGL_EXT_platform_base": [
+        "eglGetPlatformDisplayEXT"
+    ],
+
+    "EGL_EXT_device_query": [
+        "eglQueryDisplayAttribEXT",
+        "eglQueryDeviceAttribEXT",
+        "eglQueryDeviceStringEXT"
+    ],
+
+    "EGL_KHR_image_base/EGL_KHR_image": [
+        "eglCreateImageKHR",
+        "eglDestroyImageKHR"
+    ],
+
+    "EGL_EXT_device_creation": [
+        "eglCreateDeviceANGLE",
+        "eglReleaseDeviceANGLE"
+    ],
+
+    "EGL_KHR_stream": [
+        "eglCreateStreamKHR",
+        "eglDestroyStreamKHR",
+        "eglStreamAttribKHR",
+        "eglQueryStreamKHR",
+        "eglQueryStreamu64KHR"
+    ],
+
+    "EGL_KHR_stream_consumer_gltexture": [
+        "eglStreamConsumerGLTextureExternalKHR",
+        "eglStreamConsumerAcquireKHR",
+        "eglStreamConsumerReleaseKHR"
+    ],
+
+    "EGL_NV_stream_consumer_gltexture_yuv": [
+        "eglStreamConsumerGLTextureExternalAttribsNV"
+    ],
+
+    "EGL_ANGLE_stream_producer_d3d_texture": [
+        "eglCreateStreamProducerD3DTextureANGLE",
+        "eglStreamPostD3DTextureANGLE"
+    ],
+
+    "EGL_CHROMIUM_get_sync_values": [
+        "eglGetSyncValuesCHROMIUM"
+    ],
+
+    "EGL_EXT_swap_buffers_with_damage": [
+        "eglSwapBuffersWithDamageEXT"
+    ],
+
+    "EGL_ANGLE_program_cache_control": [
+        "eglProgramCacheGetAttribANGLE",
+        "eglProgramCacheQueryANGLE",
+        "eglProgramCachePopulateANGLE",
+        "eglProgramCacheResizeANGLE"
+    ],
+
+    "angle::Platform related entry points": [
+        "ANGLEGetDisplayPlatform",
+        "ANGLEResetDisplayPlatform"
+    ]
+}
--- a/gfx/angle/src/tests/BUILD.gn
+++ b/gfx/angle/src/tests/BUILD.gn
@@ -1,122 +1,197 @@
 # Copyright 2015 The Chromium Authors. All rights reserved.
 # Use of this source code is governed by a BSD-style license that can be
 # found in the LICENSE file.
 
-import("//testing/test.gni")
+import("../../gni/angle.gni")
 import("//build/config/chromecast_build.gni")
-import("//third_party/angle/gni/angle.gni")
+import("//testing/test.gni")
 
 unittests_gypi = exec_script("//build/gypi_to_gn.py",
                              [
                                rebase_path("angle_unittests.gypi"),
                                "--replace=<(angle_path)=.",
                              ],
                              "scope",
                              [ "angle_unittests.gypi" ])
 
+declare_args() {
+  # Don't build dEQP by default.
+  build_angle_deqp_tests = false
+}
+
+if (build_with_chromium) {
+  googletest_deps = [
+    "//base",
+    "//base/test:test_support",
+    "//testing/gmock",
+    "//testing/gtest",
+  ]
+} else {
+  googletest_deps = [
+    ":angle_internal_gmock",
+    ":angle_internal_gtest",
+  ]
+
+  config("angle_internal_gtest_config") {
+    include_dirs = [
+      "//third_party/googletest/src/googletest",
+      "//third_party/googletest/src/googletest/include",
+    ]
+  }
+
+  static_library("angle_internal_gtest") {
+    sources = [
+      "//third_party/googletest/src/googletest/src/gtest-all.cc",
+    ]
+    public_configs = [ ":angle_internal_gtest_config" ]
+  }
+
+  config("angle_internal_gmock_config") {
+    include_dirs = [
+      "//third_party/googletest/src/googlemock",
+      "//third_party/googletest/src/googlemock/include",
+      "//third_party/googletest/src/googletest/include",
+    ]
+  }
+
+  static_library("angle_internal_gmock") {
+    sources = [
+      "//third_party/googletest/src/googlemock/src/gmock-all.cc",
+    ]
+    public_configs = [ ":angle_internal_gmock_config" ]
+  }
+
+  group("all") {
+    testonly = true
+    deps = [
+      "//src/tests:angle_end2end_tests",
+      "//src/tests:angle_perftests",
+      "//src/tests:angle_unittests",
+      "//src/tests:angle_white_box_tests",
+    ]
+    if (build_angle_deqp_tests) {
+      deps += [
+        "//src/tests:angle_deqp_egl_no_gtest",
+        "//src/tests:angle_deqp_egl_tests",
+        "//src/tests:angle_deqp_gles2_no_gtest",
+        "//src/tests:angle_deqp_gles2_tests",
+        "//src/tests:angle_deqp_gles31_no_gtest",
+        "//src/tests:angle_deqp_gles31_tests",
+        "//src/tests:angle_deqp_gles3_no_gtest",
+        "//src/tests:angle_deqp_gles3_tests",
+      ]
+    }
+  }
+}
+
 test("angle_unittests") {
-  include_dirs = [
-    "testing/gtest/include",
-    "../../src",
-  ]
+  include_dirs = [ "$angle_root/src" ]
 
   sources = rebase_path(unittests_gypi.angle_unittests_sources, ".", "../..")
 
   if (angle_enable_hlsl) {
     sources +=
         rebase_path(unittests_gypi.angle_unittests_hlsl_sources, ".", "../..")
     defines = [ "ANGLE_ENABLE_HLSL" ]
   }
 
-  sources += [ "//gpu/angle_unittest_main.cc" ]
+  if (build_with_chromium) {
+    sources += [ "//gpu/angle_unittest_main.cc" ]
+  } else {
+    sources += [ "angle_unittests_main.cpp" ]
+  }
 
-  deps = [
-    "//base",
-    "//base/test:test_support",
-    "//testing/gmock",
-    "//testing/gtest",
-    "//third_party/angle:libANGLE",
-    "//third_party/angle:preprocessor",
-    "//third_party/angle:translator",
-  ]
+  deps = googletest_deps + [
+           angle_root + ":libANGLE",
+           angle_root + ":preprocessor",
+           angle_root + ":translator",
+         ]
 }
 
 if (is_win || is_linux || is_mac || is_android) {
   end2end_gypi = exec_script("//build/gypi_to_gn.py",
                              [
                                rebase_path("angle_end2end_tests.gypi"),
                                "--replace=<(angle_path)=.",
                              ],
                              "scope",
                              [ "angle_end2end_tests.gypi" ])
 
   test("angle_end2end_tests") {
     include_dirs = [
-      "testing/gtest/include",
       "../../src/tests",
       "../../util",
     ]
 
     if (is_android) {
       use_native_activity = true
     }
 
     sources =
         rebase_path(end2end_gypi.angle_end2end_tests_sources, ".", "../..")
+    libs = []
 
+    if (is_mac) {
+      sources += rebase_path(end2end_gypi.angle_end2end_tests_mac_sources,
+                             ".",
+                             "../..")
+      libs += [
+        "CoreFoundation.framework",
+        "IOSurface.framework",
+      ]
+    }
     if (is_win) {
       sources += rebase_path(end2end_gypi.angle_end2end_tests_win_sources,
                              ".",
                              "../..")
     }
     if (use_x11) {
       sources += rebase_path(end2end_gypi.angle_end2end_tests_x11_sources,
                              ".",
                              "../..")
     }
 
-    sources += [ "//gpu/angle_end2end_tests_main.cc" ]
+    if (build_with_chromium) {
+      sources += [ "//gpu/angle_end2end_tests_main.cc" ]
+    } else {
+      sources += [ "angle_end2end_tests_main.cpp" ]
+    }
 
     configs += [
-      "//third_party/angle:internal_config",
-      "//third_party/angle:libANGLE_config",
+      angle_root + ":internal_config",
+      angle_root + ":libANGLE_config",
     ]
 
     if (is_linux && !is_component_build) {
       # Set rpath to find libEGL.so and libGLESv2.so even in a non-component build.
       configs += [ "//build/config/gcc:rpath_for_built_shared_libraries" ]
     }
 
-    deps = [
-      "//base",
-      "//base/test:test_support",
-      "//testing/gmock",
-      "//testing/gtest",
-      "//third_party/angle:angle_image_util",
-      "//third_party/angle:angle_util",
-      "//third_party/angle:libEGL",
-      "//third_party/angle:libGLESv2",
-      "//third_party/angle:preprocessor",
-      "//third_party/angle:translator",
-    ]
+    deps = googletest_deps + [
+             angle_root + ":angle_image_util",
+             angle_root + ":angle_util",
+             angle_root + ":libEGL",
+             angle_root + ":libGLESv2",
+             angle_root + ":preprocessor",
+             angle_root + ":translator",
+           ]
   }
 
   white_box_gypi = exec_script("//build/gypi_to_gn.py",
                                [
                                  rebase_path("angle_white_box_tests.gypi"),
                                  "--replace=<(angle_path)=.",
                                ],
                                "scope",
                                [ "angle_white_box_tests.gypi" ])
 
   test("angle_white_box_tests") {
     include_dirs = [
-      "testing/gtest/include",
       "../../src/tests",
       "../../util",
     ]
 
     if (is_android) {
       use_native_activity = true
     }
 
@@ -126,170 +201,178 @@ if (is_win || is_linux || is_mac || is_a
     if (is_win) {
       sources += rebase_path(white_box_gypi.angle_white_box_tests_win_sources,
                              ".",
                              "../..")
     }
 
     # Share the same main file as end2end_tests.
     # TODO(jmadill): Probably should rename this if we're sharing.
-    sources += [ "//gpu/angle_end2end_tests_main.cc" ]
+    if (build_with_chromium) {
+      sources += [ "//gpu/angle_end2end_tests_main.cc" ]
+    } else {
+      sources += [ "angle_end2end_tests_main.cpp" ]
+    }
 
     configs += [
-      "//third_party/angle:internal_config",
-      "//third_party/angle:libANGLE_config",
+      angle_root + ":internal_config",
+      angle_root + ":libANGLE_config",
     ]
 
-    deps = [
-      "//base",
-      "//base/test:test_support",
-      "//testing/gmock",
-      "//testing/gtest",
-      "//third_party/angle:angle_util_static",
-      "//third_party/angle:libANGLE",
-      "//third_party/angle:libEGL_static",
-      "//third_party/angle:libGLESv2_static",
-      "//third_party/angle:preprocessor",
-      "//third_party/angle:translator",
-    ]
+    deps = googletest_deps + [
+             angle_root + ":angle_util_static",
+             angle_root + ":libANGLE",
+             angle_root + ":libEGL_static",
+             angle_root + ":libGLESv2_static",
+             angle_root + ":preprocessor",
+             angle_root + ":translator",
+           ]
   }
 }
 
-if (is_win || is_linux) {
+if (is_win || is_linux || is_android || is_mac) {
   perftests_gypi = exec_script("//build/gypi_to_gn.py",
                                [
                                  rebase_path("angle_perftests.gypi"),
                                  "--replace=<(angle_path)=.",
                                ],
                                "scope",
                                [ "angle_perftests.gypi" ])
 
   test("angle_perftests") {
     include_dirs = [
-      "testing/gtest/include",
       "../../src/tests",
       "../../util",
     ]
 
+    if (is_android) {
+      use_native_activity = true
+      configs -= [ "//build/config/android:hide_all_but_jni" ]
+    }
+
     sources = rebase_path(perftests_gypi.angle_perf_tests_sources, ".", "../..")
 
     if (is_win) {
       sources +=
           rebase_path(perftests_gypi.angle_perf_tests_win_sources, ".", "../..")
     }
 
-    sources += [ "//gpu/angle_perftests_main.cc" ]
+    if (build_with_chromium) {
+      sources += [ "//gpu/angle_perftests_main.cc" ]
+    } else {
+      sources += [ "angle_perftests_main.cpp" ]
+    }
 
     configs += [
-      "//third_party/angle:internal_config",
-      "//third_party/angle:libANGLE_config",
+      angle_root + ":internal_config",
+      angle_root + ":libANGLE_config",
     ]
 
-    deps = [
-      "//base",
-      "//base/test:test_support",
-      "//testing/gmock",
-      "//testing/gtest",
-      "//third_party/angle:angle_util_static",
-      "//third_party/angle:libANGLE",
-      "//third_party/angle:libEGL_static",
-      "//third_party/angle:libGLESv2_static",
-    ]
+    deps = googletest_deps + [
+             angle_root + ":angle_util_static",
+             angle_root + ":libANGLE",
+             angle_root + ":libEGL_static",
+             angle_root + ":libGLESv2_static",
+           ]
   }
 }
 
 ###-----------------------------------------------------
 ### dEQP tests
 ###-----------------------------------------------------
 
-declare_args() {
-  # Don't build dEQP by default.
-  build_angle_deqp_tests = false
-}
-
 # TODO(jmadill): Other platforms.
 if (build_angle_deqp_tests) {
   deqp_gypi = exec_script("//build/gypi_to_gn.py",
                           [
                             rebase_path("deqp.gypi"),
                             "--replace=<(angle_path)=.",
-                            "--replace=<(deqp_path)=../deqp/src",
+                            "--replace=<(deqp_path)=//third_party/deqp/src",
                           ],
                           "scope",
                           [ "deqp.gypi" ])
 
   config("angle_deqp_support") {
     include_dirs = rebase_path(deqp_gypi.deqp_include_dirs, ".", "../..")
-    if (is_win) {
+    if (is_win && !is_clang) {
       include_dirs += [ "../deqp/src/framework/platform/win32" ]
       cflags = deqp_gypi.deqp_win_cflags
     }
     if (is_android) {
       include_dirs += [ "../../../deqp/src/framework/platform/android" ]
     }
     defines = deqp_gypi.deqp_defines
     defines += [ "_MBCS" ]
 
+    if (is_clang) {
+      # TODO(jmadill): Remove this once we fix dEQP.
+      cflags_c = [ "-Wno-unused-local-typedef" ]
+      cflags_cc = [ "-Wno-unused-local-typedef" ]
+    }
+
     # Ask the system headers to expose all the regular function otherwise
     # dEQP doesn't compile and produces warnings about implicitly defined
     # functions.
     if (is_linux) {
       # This has to be GNU_SOURCE as on Linux dEQP uses syscall()
       defines += [ "_GNU_SOURCE" ]
     }
     if (is_android || is_mac) {
       # _XOPEN_SOURCE=600 is what is used in deqp/src/Android.mk
       defines += [ "_XOPEN_SOURCE=600" ]
     }
   }
 
   deqp_undefine_configs = [
     "//build/config/compiler:chromium_code",
+    "//build/config/compiler:no_exceptions",
     "//build/config/compiler:no_rtti",
   ]
 
   if (is_win) {
     deqp_undefine_configs += [
       "//build/config/win:lean_and_mean",
       "//build/config/win:nominmax",
       "//build/config/win:unicode",
     ]
   }
 
-  if (is_linux || is_android || is_mac) {
-    deqp_undefine_configs += [ "//build/config/gcc:no_exceptions" ]
-  }
-
   static_library("angle_deqp_decpp") {
     configs -= deqp_undefine_configs
     public_configs = [
       ":angle_deqp_support",
+      "//build/config/compiler:exceptions",
       "//build/config/compiler:no_chromium_code",
-      "//third_party/angle:internal_config",
+      angle_root + ":internal_config",
     ]
+
     sources = rebase_path(deqp_gypi.deqp_libtester_decpp_sources, ".", "../..")
   }
 
   config("angle_deqp_libtester_config") {
     defines = [ "ANGLE_DEQP_LIBTESTER_IMPLEMENTATION" ]
 
     if (is_clang) {
       # TODO(jmadill): Remove this once we fix dEQP.
-      cflags_cc = [ "-Wno-delete-non-virtual-dtor" ]
+      cflags_cc = [
+        "-Wno-delete-non-virtual-dtor",
+        "-Wno-deprecated",
+      ]
     }
   }
 
   static_library("angle_deqp_libtester") {
     public_deps = [
       ":angle_deqp_decpp",
-      "//third_party/angle:angle_common",
-      "//third_party/angle:angle_util",
-      "//third_party/angle:libEGL",
+      angle_root + ":angle_common",
+      angle_root + ":angle_util",
+      angle_root + ":libEGL",
       "//third_party/libpng:libpng",
     ]
+
     configs -= deqp_undefine_configs
     public_configs = [ ":angle_deqp_libtester_config" ]
     sources = rebase_path(deqp_gypi.deqp_libtester_sources, ".", "../..")
     if (is_win) {
       sources += rebase_path(deqp_gypi.deqp_libtester_sources_win, ".", "../..")
     }
     if (is_linux || is_android || is_mac) {
       sources +=
@@ -303,29 +386,38 @@ if (build_angle_deqp_tests) {
   }
 
   config("angle_deqp_gtest_support_config") {
     include_dirs = [ "third_party/gpu_test_expectations" ]
   }
 
   source_set("angle_deqp_gtest_support") {
     testonly = true
-    public_deps = [
-      "//base",
-      "//base/test:test_support",
-      "//testing/gtest",
-      "//third_party/angle:angle_common",
-      "//third_party/angle:angle_util",
-    ]
+
+    public_deps = googletest_deps + [
+                    angle_root + ":angle_common",
+                    angle_root + ":angle_util",
+                  ]
+
     public_configs = [ ":angle_deqp_gtest_support_config" ]
+
     sources = deqp_gypi.deqp_gpu_test_expectations_sources
-    sources += [ "//gpu/angle_deqp_tests_main.cc" ]
+    if (is_mac) {
+      sources += deqp_gypi.deqp_gpu_test_expectations_sources_mac
+      libs = [ "Cocoa.framework" ]
+    }
+
+    if (build_with_chromium) {
+      sources += [ "//gpu/angle_deqp_tests_main.cc" ]
+    } else {
+      sources += [ "deqp_support/angle_deqp_gtest_main.cpp" ]
+    }
 
     if (!is_android) {
-      public_deps += ["//third_party/angle:angle_gpu_info_util"]
+      public_deps += [ angle_root + ":angle_gpu_info_util" ]
     }
   }
 
   api_names = [
     "gles2",
     "gles3",
     "gles31",
     "egl",
@@ -356,33 +448,44 @@ if (build_angle_deqp_tests) {
       defines = [ target_defines[index] ]
     }
 
     shared_library_name = "angle_deqp_lib${api_name}"
     shared_library(shared_library_name) {
       deps = [
         ":angle_deqp_libtester",
         "//build/config:exe_and_shlib_deps",
-        "//third_party/angle:angle_util",
+        angle_root + ":angle_util",
       ]
 
       configs -= deqp_undefine_configs
       if (is_android) {
         configs -= [ "//build/config/android:hide_all_but_jni_onload" ]
       }
       public_configs = [ ":${config_name}" ]
 
       sources = rebase_path(target_sources[index], ".", "../..")
       sources += [
         "deqp_support/angle_deqp_libtester_main.cpp",
         "deqp_support/tcuANGLEPlatform.cpp",
         "deqp_support/tcuANGLEPlatform.h",
       ]
     }
 
+    if (!build_with_chromium) {
+      executable("angle_deqp_${api_name}_no_gtest") {
+        sources = [
+          "deqp_support/angle_deqp_tests_main.cpp",
+        ]
+        deps = [
+          ":${shared_library_name}",
+        ]
+      }
+    }
+
     test_name = "angle_deqp_${api_name}_tests"
     test(test_name) {
       deps = [
         ":${shared_library_name}",
         ":angle_deqp_gtest_support",
       ]
 
       # Must be included outside of the source set for the define
--- a/gfx/angle/src/tests/angle_end2end_tests.gypi
+++ b/gfx/angle/src/tests/angle_end2end_tests.gypi
@@ -40,23 +40,25 @@
             '<(angle_path)/src/tests/gl_tests/DXTSRGBCompressedTextureTest.cpp',
             '<(angle_path)/src/tests/gl_tests/ETCTextureTest.cpp',
             '<(angle_path)/src/tests/gl_tests/FenceSyncTests.cpp',
             '<(angle_path)/src/tests/gl_tests/FloatingPointSurfaceTest.cpp',
             '<(angle_path)/src/tests/gl_tests/FramebufferMixedSamplesTest.cpp',
             '<(angle_path)/src/tests/gl_tests/FramebufferMultiviewTest.cpp',
             '<(angle_path)/src/tests/gl_tests/FramebufferRenderMipmapTest.cpp',
             '<(angle_path)/src/tests/gl_tests/FramebufferTest.cpp',
+            '<(angle_path)/src/tests/gl_tests/GeometryShaderTest.cpp',
             '<(angle_path)/src/tests/gl_tests/GLSLTest.cpp',
             '<(angle_path)/src/tests/gl_tests/ImageTest.cpp',
             '<(angle_path)/src/tests/gl_tests/IncompleteTextureTest.cpp',
             '<(angle_path)/src/tests/gl_tests/IndexBufferOffsetTest.cpp',
             '<(angle_path)/src/tests/gl_tests/IndexedPointsTest.cpp',
             '<(angle_path)/src/tests/gl_tests/InstancingTest.cpp',
             '<(angle_path)/src/tests/gl_tests/LineLoopTest.cpp',
+            '<(angle_path)/src/tests/gl_tests/LinkAndRelinkTest.cpp',
             '<(angle_path)/src/tests/gl_tests/MaxTextureSizeTest.cpp',
             '<(angle_path)/src/tests/gl_tests/MipmapTest.cpp',
             '<(angle_path)/src/tests/gl_tests/MultisampleCompatibilityTest.cpp',
             '<(angle_path)/src/tests/gl_tests/MultiviewDrawTest.cpp',
             '<(angle_path)/src/tests/gl_tests/media/pixel.inl',
             '<(angle_path)/src/tests/gl_tests/PackUnpackTest.cpp',
             '<(angle_path)/src/tests/gl_tests/PathRenderingTest.cpp',
             '<(angle_path)/src/tests/gl_tests/PbufferTest.cpp',
@@ -80,16 +82,17 @@
             '<(angle_path)/src/tests/gl_tests/SRGBFramebufferTest.cpp',
             '<(angle_path)/src/tests/gl_tests/SRGBTextureTest.cpp',
             '<(angle_path)/src/tests/gl_tests/StateChangeTest.cpp',
             '<(angle_path)/src/tests/gl_tests/SwizzleTest.cpp',
             '<(angle_path)/src/tests/gl_tests/SyncQueriesTest.cpp',
             '<(angle_path)/src/tests/gl_tests/TextureMultisampleTest.cpp',
             '<(angle_path)/src/tests/gl_tests/TextureRectangleTest.cpp',
             '<(angle_path)/src/tests/gl_tests/TextureTest.cpp',
+            '<(angle_path)/src/tests/gl_tests/TextureUploadFormatTest.cpp',
             '<(angle_path)/src/tests/gl_tests/TimerQueriesTest.cpp',
             '<(angle_path)/src/tests/gl_tests/TransformFeedbackTest.cpp',
             '<(angle_path)/src/tests/gl_tests/UniformBufferTest.cpp',
             '<(angle_path)/src/tests/gl_tests/UniformTest.cpp',
             '<(angle_path)/src/tests/gl_tests/UnpackAlignmentTest.cpp',
             '<(angle_path)/src/tests/gl_tests/UnpackRowLength.cpp',
             '<(angle_path)/src/tests/gl_tests/VertexAttributeTest.cpp',
             '<(angle_path)/src/tests/gl_tests/ViewportTest.cpp',
@@ -107,16 +110,20 @@
             '<(angle_path)/src/tests/test_utils/ANGLETest.cpp',
             '<(angle_path)/src/tests/test_utils/ANGLETest.h',
             '<(angle_path)/src/tests/test_utils/angle_test_configs.cpp',
             '<(angle_path)/src/tests/test_utils/angle_test_configs.h',
             '<(angle_path)/src/tests/test_utils/angle_test_instantiate.cpp',
             '<(angle_path)/src/tests/test_utils/angle_test_instantiate.h',
             '<(angle_path)/src/tests/test_utils/gl_raii.h',
         ],
+        'angle_end2end_tests_mac_sources':
+        [
+            '<(angle_path)/src/tests/egl_tests/EGLIOSurfaceClientBufferTest.cpp',
+        ],
         'angle_end2end_tests_win_sources':
         [
             '<(angle_path)/src/tests/gl_tests/D3DImageFormatConversionTest.cpp',
             '<(angle_path)/src/tests/egl_tests/EGLDeviceTest.cpp',
             '<(angle_path)/src/tests/egl_tests/EGLPresentPathD3D11Test.cpp',
             '<(angle_path)/src/tests/egl_tests/EGLStreamTest.cpp',
             '<(angle_path)/src/tests/egl_tests/EGLSyncControlTest.cpp',
             # TODO(cwallez) for Linux, requires a portable implementation of threads
@@ -146,16 +153,31 @@
         '<(angle_path)/src/tests'
     ],
     'sources':
     [
         '<@(angle_end2end_tests_sources)',
     ],
     'conditions':
     [
+        ['OS=="mac"',
+        {
+            'sources':
+            [
+                '<@(angle_end2end_tests_mac_sources)',
+            ],
+            'link_settings':
+            {
+                'libraries':
+                [
+                    '$(SDKROOT)/System/Library/Frameworks/CoreFoundation.framework',
+                    '$(SDKROOT)/System/Library/Frameworks/IOSurface.framework',
+                ],
+            },
+        }],
         ['OS=="win"',
         {
             'sources':
             [
                 '<@(angle_end2end_tests_win_sources)',
             ],
         }],
         ['use_x11==1',
--- a/gfx/angle/src/tests/angle_unittests.gypi
+++ b/gfx/angle/src/tests/angle_unittests.gypi
@@ -10,16 +10,17 @@
 # gtest harness in a main.cpp.
 
 {
     'variables':
     {
         'angle_unittests_sources':
         [
             '<(angle_path)/src/common/Optional_unittest.cpp',
+            '<(angle_path)/src/common/angleutils_unittest.cpp',
             '<(angle_path)/src/common/bitset_utils_unittest.cpp',
             '<(angle_path)/src/common/mathutil_unittest.cpp',
             '<(angle_path)/src/common/matrix_utils_unittest.cpp',
             '<(angle_path)/src/common/string_utils_unittest.cpp',
             '<(angle_path)/src/common/utilities_unittest.cpp',
             '<(angle_path)/src/common/vector_utils_unittest.cpp',
             '<(angle_path)/src/gpu_info_util/SystemInfo_unittest.cpp',
             '<(angle_path)/src/libANGLE/BinaryStream_unittest.cpp',
@@ -57,40 +58,45 @@
             '<(angle_path)/src/tests/compiler_tests/ConstantFoldingNaN_test.cpp',
             '<(angle_path)/src/tests/compiler_tests/ConstantFoldingOverflow_test.cpp',
             '<(angle_path)/src/tests/compiler_tests/ConstructCompiler_test.cpp',
             '<(angle_path)/src/tests/compiler_tests/DebugShaderPrecision_test.cpp',
             '<(angle_path)/src/tests/compiler_tests/EmulateGLFragColorBroadcast_test.cpp',
             '<(angle_path)/src/tests/compiler_tests/ExpressionLimit_test.cpp',
             '<(angle_path)/src/tests/compiler_tests/EXT_YUV_target_test.cpp',
             '<(angle_path)/src/tests/compiler_tests/EXT_blend_func_extended_test.cpp',
+            '<(angle_path)/src/tests/compiler_tests/ExtensionDirective_test.cpp',
             '<(angle_path)/src/tests/compiler_tests/FloatLex_test.cpp',
             '<(angle_path)/src/tests/compiler_tests/FragDepth_test.cpp',
             '<(angle_path)/src/tests/compiler_tests/GLSLCompatibilityOutput_test.cpp',
             '<(angle_path)/src/tests/compiler_tests/GeometryShader_test.cpp',
             '<(angle_path)/src/tests/compiler_tests/InitOutputVariables_test.cpp',
             '<(angle_path)/src/tests/compiler_tests/IntermNode_test.cpp',
             '<(angle_path)/src/tests/compiler_tests/NV_draw_buffers_test.cpp',
             '<(angle_path)/src/tests/compiler_tests/Pack_Unpack_test.cpp',
             '<(angle_path)/src/tests/compiler_tests/PruneEmptyDeclarations_test.cpp',
             '<(angle_path)/src/tests/compiler_tests/PrunePureLiteralStatements_test.cpp',
             '<(angle_path)/src/tests/compiler_tests/PruneUnusedFunctions_test.cpp',
             '<(angle_path)/src/tests/compiler_tests/QualificationOrderESSL31_test.cpp',
             '<(angle_path)/src/tests/compiler_tests/QualificationOrder_test.cpp',
             '<(angle_path)/src/tests/compiler_tests/RecordConstantPrecision_test.cpp',
+            '<(angle_path)/src/tests/compiler_tests/RegenerateStructNames_test.cpp',
             '<(angle_path)/src/tests/compiler_tests/RemovePow_test.cpp',
+            '<(angle_path)/src/tests/compiler_tests/RemoveUnreferencedVariables_test.cpp',
             '<(angle_path)/src/tests/compiler_tests/RewriteDoWhile_test.cpp',
             '<(angle_path)/src/tests/compiler_tests/SamplerMultisample_test.cpp',
+            '<(angle_path)/src/tests/compiler_tests/ScalarizeVecAndMatConstructorArgs_test.cpp',
             '<(angle_path)/src/tests/compiler_tests/ShaderExtension_test.cpp',
             '<(angle_path)/src/tests/compiler_tests/ShaderImage_test.cpp',
             '<(angle_path)/src/tests/compiler_tests/ShaderValidation_test.cpp',
             '<(angle_path)/src/tests/compiler_tests/ShaderVariable_test.cpp',
             '<(angle_path)/src/tests/compiler_tests/ShCompile_test.cpp',
             '<(angle_path)/src/tests/compiler_tests/TypeTracking_test.cpp',
             '<(angle_path)/src/tests/compiler_tests/VariablePacker_test.cpp',
+            '<(angle_path)/src/tests/compiler_tests/VectorizeVectorScalarArithmetic_test.cpp',
             '<(angle_path)/src/tests/compiler_tests/WEBGL_multiview_test.cpp',
             '<(angle_path)/src/tests/compiler_tests/WorkGroupSize_test.cpp',
             '<(angle_path)/src/tests/preprocessor_tests/char_test.cpp',
             '<(angle_path)/src/tests/preprocessor_tests/comment_test.cpp',
             '<(angle_path)/src/tests/preprocessor_tests/define_test.cpp',
             '<(angle_path)/src/tests/preprocessor_tests/error_test.cpp',
             '<(angle_path)/src/tests/preprocessor_tests/extension_test.cpp',
             '<(angle_path)/src/tests/preprocessor_tests/identifier_test.cpp',
--- a/gfx/angle/src/tests/angle_unittests_utils.h
+++ b/gfx/angle/src/tests/angle_unittests_utils.h
@@ -114,15 +114,15 @@ class MockEGLFactory : public EGLImplFac
                                const egl::AttributeMap &));
     MOCK_METHOD3(createPixmapSurface,
                  SurfaceImpl *(const egl::SurfaceState &,
                                NativePixmapType,
                                const egl::AttributeMap &));
     MOCK_METHOD3(createImage,
                  ImageImpl *(const egl::ImageState &, EGLenum, const egl::AttributeMap &));
     MOCK_METHOD1(createContext, ContextImpl *(const gl::ContextState &));
-    MOCK_METHOD2(createStreamProducerD3DTextureNV12,
+    MOCK_METHOD2(createStreamProducerD3DTexture,
                  StreamProducerImpl *(egl::Stream::ConsumerType, const egl::AttributeMap &));
 };
 
 }  // namespace rx
 
 #endif // TESTS_ANGLE_UNITTESTS_UTILS_H_
--- a/gfx/angle/src/tests/compiler_tests/ARB_texture_rectangle_test.cpp
+++ b/gfx/angle/src/tests/compiler_tests/ARB_texture_rectangle_test.cpp
@@ -25,73 +25,92 @@ class ARBTextureRectangleTest : public A
 {
   protected:
     void initResources(ShBuiltInResources *resources) override
     {
         resources->ARB_texture_rectangle = 1;
     }
 };
 
-// Check that new types and builtins are disallowed if the extension isn't present in the translator
-// resources
-TEST_F(ARBTextureRectangleTest, NewTypeAndBuiltinsWithoutTranslatorResourceExtension)
-{
-    // The new builtins require Sampler2DRect so we can't test them independently.
-    const std::string &shaderString =
-        "precision mediump float;\n"
-        "uniform sampler2DRect tex;\n"
-        "void main() {\n"
-        "}\n";
-    ASSERT_TRUE(compile(shaderString));
-}
-
 // Check that new types and builtins are usable even with the #extension directive
 // Issue #15 of ARB_texture_rectangle explains that the extension was specified before the
 // #extension mechanism was in place so it doesn't require explicit enabling.
 TEST_F(ARBTextureRectangleTest, NewTypeAndBuiltinsWithoutExtensionDirective)
 {
     const std::string &shaderString =
         "precision mediump float;\n"
         "uniform sampler2DRect tex;\n"
         "void main() {\n"
         "    vec4 color = texture2DRect(tex, vec2(1.0));"
         "    color = texture2DRectProj(tex, vec3(1.0));"
         "    color = texture2DRectProj(tex, vec4(1.0));"
         "}\n";
-    ASSERT_TRUE(compile(shaderString));
+    if (!compile(shaderString))
+    {
+        FAIL() << "Shader compilation failed, expecting success:\n" << mInfoLog;
+    }
 }
 
 // Test valid usage of the new types and builtins
 TEST_F(ARBTextureRectangleTest, NewTypeAndBuiltingsWithExtensionDirective)
 {
     const std::string &shaderString =
         "#extension GL_ARB_texture_rectangle : require\n"
         "precision mediump float;\n"
         "uniform sampler2DRect tex;\n"
         "void main() {\n"
         "    vec4 color = texture2DRect(tex, vec2(1.0));"
         "    color = texture2DRectProj(tex, vec3(1.0));"
         "    color = texture2DRectProj(tex, vec4(1.0));"
         "}\n";
-    ASSERT_TRUE(compile(shaderString));
+    if (!compile(shaderString))
+    {
+        FAIL() << "Shader compilation failed, expecting success:\n" << mInfoLog;
+    }
 }
 
 // Check that it is not possible to pass a sampler2DRect where sampler2D is expected, and vice versa
 TEST_F(ARBTextureRectangleTest, Rect2DVs2DMismatch)
 {
     const std::string &shaderString1 =
         "#extension GL_ARB_texture_rectangle : require\n"
         "precision mediump float;\n"
         "uniform sampler2DRect tex;\n"
         "void main() {\n"
         "    vec4 color = texture2D(tex, vec2(1.0));"
         "}\n";
-    ASSERT_FALSE(compile(shaderString1));
+    if (compile(shaderString1))
+    {
+        FAIL() << "Shader compilation succeeded, expecting failure:\n" << mInfoLog;
+    }
 
     const std::string &shaderString2 =
         "#extension GL_ARB_texture_rectangle : require\n"
         "precision mediump float;\n"
         "uniform sampler2D tex;\n"
         "void main() {\n"
         "    vec4 color = texture2DRect(tex, vec2(1.0));"
         "}\n";
-    ASSERT_FALSE(compile(shaderString2));
+    if (compile(shaderString2))
+    {
+        FAIL() << "Shader compilation succeeded, expecting failure:\n" << mInfoLog;
+    }
 }
+
+// Disabling ARB_texture_rectangle in GLSL should work, even if it is enabled by default.
+// See ARB_texture_rectangle spec: "a shader can still include all variations of #extension
+// GL_ARB_texture_rectangle in its source code"
+TEST_F(ARBTextureRectangleTest, DisableARBTextureRectangle)
+{
+    const std::string &shaderString =
+        R"(
+        #extension GL_ARB_texture_rectangle : disable
+
+        precision mediump float;
+
+        uniform sampler2DRect s;
+        void main()
+        {})";
+    if (compile(shaderString))
+    {
+        FAIL() << "Shader compilation succeeded, expecting failure:\n" << mInfoLog;
+    }
+}
--- a/gfx/angle/src/tests/compiler_tests/AtomicCounter_test.cpp
+++ b/gfx/angle/src/tests/compiler_tests/AtomicCounter_test.cpp
@@ -206,8 +206,25 @@ TEST_F(AtomicCounterTest, OffsetMustNotS
         "void main()\n"
         "{\n"
         "}\n";
     if (compile(source))
     {
         FAIL() << "Shader compilation succeeded, expecting failure:\n" << mInfoLog;
     }
 }
+
+// Test that offset overlapping leads to compile-time error (ESSL 3.10 section 4.4.6).
+// Note that there is some vagueness in the spec when it comes to this test.
+TEST_F(AtomicCounterTest, BindingOffsetOverlappingForArrays)
+{
+    const std::string &source =
+        "#version 310 es\n"
+        "layout(binding = 2, offset = 4) uniform atomic_uint[2] a;\n"
+        "layout(binding = 2, offset = 8) uniform atomic_uint b;\n"
+        "void main()\n"
+        "{\n"
+        "}\n";
+    if (compile(source))
+    {
+        FAIL() << "Shader compilation succeeded, expecting failure:\n" << mInfoLog;
+    }
+}
--- a/gfx/angle/src/tests/compiler_tests/BufferVariables_test.cpp
+++ b/gfx/angle/src/tests/compiler_tests/BufferVariables_test.cpp
@@ -247,17 +247,17 @@ TEST_F(BufferVariablesTest, AccessReadon
 {
     const std::string &source =
         "#version 310 es\n"
         "layout(binding = 3) buffer buf {\n"
         "    readonly float f;\n"
         "} instanceBuffer;\n"
         "void main()\n"
         "{\n"
-        "    float test = instanceBuffer.f;\n"
+        "    gl_Position.x = instanceBuffer.f;\n"
         "}\n";
     if (!compile(source))
     {
         FAIL() << "Shader compilation failed, expecting success:\n" << mInfoLog;
     }
 }
 
 // Test that accessing a buffer variable through an instance name inherits the writeonly qualifier
@@ -478,8 +478,107 @@ TEST_F(BufferVariablesTest, BufferQualif
         "void main()\n"
         "{\n"
         "}\n";
     if (compile(source))
     {
         FAIL() << "Shader compilation succeeded, expecting failure:\n" << mInfoLog;
     }
 }
+
+// Test that std430 qualifier is supported for shader storage blocks.
+TEST_F(BufferVariablesTest, ShaderStorageBlockWithStd430)
+{
+    const std::string &source =
+        "#version 310 es\n"
+        "layout(std430) buffer buf {\n"
+        "    int b1;\n"
+        "    int b2;\n"
+        "};\n"
+        "void main()\n"
+        "{\n"
+        "}\n";
+    if (!compile(source))
+    {
+        FAIL() << "Shader compilation failed, expecting success:\n" << mInfoLog;
+    }
+}
+
+// Test that using std430 qualifier on a uniform block will fail to compile.
+TEST_F(BufferVariablesTest, UniformBlockWithStd430)
+{
+    const std::string &source =
+        "#version 310 es\n"
+        "layout(std430) uniform buf {\n"
+        "    int b1;\n"
+        "    int b2;\n"
+        "};\n"
+        "void main()\n"
+        "{\n"
+        "}\n";
+    if (compile(source))
+    {
+        FAIL() << "Shader compilation succeeded, expecting failure:\n" << mInfoLog;
+    }
+}
+
+// Test that indexing a runtime-sized array with a positive index compiles.
+TEST_F(BufferVariablesTest, IndexRuntimeSizedArray)
+{
+    const std::string &source =
+        R"(#version 310 es
+
+        layout(std430) buffer buf
+        {
+            int arr[];
+        };
+
+        void main()
+        {
+            arr[100];
+        })";
+    if (!compile(source))
+    {
+        FAIL() << "Shader compilation failed, expecting success:\n" << mInfoLog;
+    }
+}
+
+// Test that indexing a runtime-sized array with a negative constant index does not compile.
+TEST_F(BufferVariablesTest, IndexRuntimeSizedArrayWithNegativeIndex)
+{
+    const std::string &source =
+        R"(#version 310 es
+
+        layout(std430) buffer buf
+        {
+            int arr[];
+        };
+
+        void main()
+        {
+            arr[-1];
+        })";
+    if (compile(source))
+    {
+        FAIL() << "Shader compilation succeeded, expecting failure:\n" << mInfoLog;
+    }
+}
+
+// Test that only the last member of a buffer can be runtime-sized.
+TEST_F(BufferVariablesTest, RuntimeSizedVariableInNotLastInBuffer)
+{
+    const std::string &source =
+        R"(#version 310 es
+
+        layout(std430) buffer buf
+        {
+            int arr[];
+            int i;
+        };
+
+        void main()
+        {
+        })";
+    if (compile(source))
+    {
+        FAIL() << "Shader compilation succeeded, expecting failure:\n" << mInfoLog;
+    }
+}
--- a/gfx/angle/src/tests/compiler_tests/CollectVariables_test.cpp
+++ b/gfx/angle/src/tests/compiler_tests/CollectVariables_test.cpp
@@ -83,17 +83,17 @@ class CollectVariablesTest : public test
             }
             else
             {
                 ASSERT_EQ("diff", field.name);
                 EXPECT_FALSE(foundDiff);
                 foundDiff = true;
             }
 
-            EXPECT_EQ(0u, field.arraySize);
+            EXPECT_FALSE(field.isArray());
             EXPECT_FALSE(field.isStruct());
             EXPECT_GLENUM_EQ(GL_HIGH_FLOAT, field.precision);
             EXPECT_TRUE(field.staticUse);
             EXPECT_GLENUM_EQ(GL_FLOAT, field.type);
         }
 
         EXPECT_TRUE(foundNear && foundFar && foundDiff);
     }
@@ -150,63 +150,63 @@ class CollectVariablesTestES31 : public 
     void initTranslator(const ShBuiltInResources &resources) override
     {
         mTranslator.reset(
             new TranslatorGLSL(mShaderType, SH_GLES3_1_SPEC, SH_GLSL_COMPATIBILITY_OUTPUT));
         ASSERT_TRUE(mTranslator->Init(resources));
     }
 };
 
-class CollectVariablesOESGeometryShaderTest : public CollectVariablesTestES31
+class CollectVariablesEXTGeometryShaderTest : public CollectVariablesTestES31
 {
   public:
-    CollectVariablesOESGeometryShaderTest(sh::GLenum shaderType)
+    CollectVariablesEXTGeometryShaderTest(sh::GLenum shaderType)
         : CollectVariablesTestES31(shaderType)
     {
     }
 
   protected:
     void SetUp() override
     {
         ShBuiltInResources resources;
         InitBuiltInResources(&resources);
-        resources.OES_geometry_shader = 1;
+        resources.EXT_geometry_shader = 1;
 
         initTranslator(resources);
     }
 };
 
-class CollectGeometryVariablesTest : public CollectVariablesOESGeometryShaderTest
+class CollectGeometryVariablesTest : public CollectVariablesEXTGeometryShaderTest
 {
   public:
-    CollectGeometryVariablesTest() : CollectVariablesOESGeometryShaderTest(GL_GEOMETRY_SHADER_OES)
+    CollectGeometryVariablesTest() : CollectVariablesEXTGeometryShaderTest(GL_GEOMETRY_SHADER_EXT)
     {
     }
 
   protected:
-    void compileGeometryShaderWithInputPrimitive(const std::string &inputPrimitive)
+    void compileGeometryShaderWithInputPrimitive(const std::string &inputPrimitive,
+                                                 const std::string &inputVarying,
+                                                 const std::string &functionBody)
     {
         std::ostringstream sstream;
         sstream << "#version 310 es\n"
-                << "#extension GL_OES_geometry_shader : require\n"
+                << "#extension GL_EXT_geometry_shader : require\n"
                 << "layout (" << inputPrimitive << ") in;\n"
                 << "layout (points, max_vertices = 2) out;\n"
-                << "void main()\n"
-                << "{\n"
-                << "    vec4 value = gl_in[0].gl_Position;\n"
-                << "}\n";
+                << inputVarying << functionBody;
+
         compile(sstream.str());
     }
 };
 
-class CollectFragmentVariablesOESGeometryShaderTest : public CollectVariablesOESGeometryShaderTest
+class CollectFragmentVariablesEXTGeometryShaderTest : public CollectVariablesEXTGeometryShaderTest
 {
   public:
-    CollectFragmentVariablesOESGeometryShaderTest()
-        : CollectVariablesOESGeometryShaderTest(GL_FRAGMENT_SHADER)
+    CollectFragmentVariablesEXTGeometryShaderTest()
+        : CollectVariablesEXTGeometryShaderTest(GL_FRAGMENT_SHADER)
     {
     }
 
   protected:
     void initTranslator(const ShBuiltInResources &resources)
     {
         mTranslator.reset(
             new TranslatorGLSL(mShaderType, SH_GLES3_1_SPEC, SH_GLSL_COMPATIBILITY_OUTPUT));
@@ -238,17 +238,17 @@ TEST_F(CollectFragmentVariablesTest, Sim
 
     compile(shaderString);
 
     const auto &outputVariables = mTranslator->getOutputVariables();
     ASSERT_EQ(1u, outputVariables.size());
 
     const OutputVariable &outputVariable = outputVariables[0];
 
-    EXPECT_EQ(0u, outputVariable.arraySize);
+    EXPECT_FALSE(outputVariable.isArray());
     EXPECT_EQ(-1, outputVariable.location);
     EXPECT_GLENUM_EQ(GL_MEDIUM_FLOAT, outputVariable.precision);
     EXPECT_TRUE(outputVariable.staticUse);
     EXPECT_GLENUM_EQ(GL_FLOAT_VEC4, outputVariable.type);
     EXPECT_EQ("out_fragColor", outputVariable.name);
 }
 
 TEST_F(CollectFragmentVariablesTest, LocationOutputVar)
@@ -263,17 +263,17 @@ TEST_F(CollectFragmentVariablesTest, Loc
 
     compile(shaderString);
 
     const auto &outputVariables = mTranslator->getOutputVariables();
     ASSERT_EQ(1u, outputVariables.size());
 
     const OutputVariable &outputVariable = outputVariables[0];
 
-    EXPECT_EQ(0u, outputVariable.arraySize);
+    EXPECT_FALSE(outputVariable.isArray());
     EXPECT_EQ(5, outputVariable.location);
     EXPECT_GLENUM_EQ(GL_MEDIUM_FLOAT, outputVariable.precision);
     EXPECT_TRUE(outputVariable.staticUse);
     EXPECT_GLENUM_EQ(GL_FLOAT_VEC4, outputVariable.type);
     EXPECT_EQ("out_fragColor", outputVariable.name);
 }
 
 TEST_F(CollectVertexVariablesTest, LocationAttribute)
@@ -287,17 +287,17 @@ TEST_F(CollectVertexVariablesTest, Locat
 
     compile(shaderString);
 
     const std::vector<Attribute> &attributes = mTranslator->getAttributes();
     ASSERT_EQ(1u, attributes.size());
 
     const Attribute &attribute = attributes[0];
 
-    EXPECT_EQ(0u, attribute.arraySize);
+    EXPECT_FALSE(attribute.isArray());
     EXPECT_EQ(5, attribute.location);
     EXPECT_GLENUM_EQ(GL_HIGH_FLOAT, attribute.precision);
     EXPECT_TRUE(attribute.staticUse);
     EXPECT_GLENUM_EQ(GL_FLOAT_VEC4, attribute.type);
     EXPECT_EQ("in_Position", attribute.name);
 }
 
 TEST_F(CollectVertexVariablesTest, SimpleInterfaceBlock)
@@ -314,17 +314,16 @@ TEST_F(CollectVertexVariablesTest, Simpl
     compile(shaderString);
 
     const std::vector<InterfaceBlock> &interfaceBlocks = mTranslator->getInterfaceBlocks();
     ASSERT_EQ(1u, interfaceBlocks.size());
 
     const InterfaceBlock &interfaceBlock = interfaceBlocks[0];
 
     EXPECT_EQ(0u, interfaceBlock.arraySize);
-    EXPECT_FALSE(interfaceBlock.isRowMajorLayout);
     EXPECT_EQ(BLOCKLAYOUT_SHARED, interfaceBlock.layout);
     EXPECT_EQ("b", interfaceBlock.name);
     EXPECT_TRUE(interfaceBlock.staticUse);
 
     ASSERT_EQ(1u, interfaceBlock.fields.size());
 
     const InterfaceBlockField &field = interfaceBlock.fields[0];
 
@@ -350,17 +349,16 @@ TEST_F(CollectVertexVariablesTest, Simpl
     compile(shaderString);
 
     const std::vector<InterfaceBlock> &interfaceBlocks = mTranslator->getInterfaceBlocks();
     ASSERT_EQ(1u, interfaceBlocks.size());
 
     const InterfaceBlock &interfaceBlock = interfaceBlocks[0];
 
     EXPECT_EQ(0u, interfaceBlock.arraySize);
-    EXPECT_FALSE(interfaceBlock.isRowMajorLayout);
     EXPECT_EQ(BLOCKLAYOUT_SHARED, interfaceBlock.layout);
     EXPECT_EQ("b", interfaceBlock.name);
     EXPECT_EQ("blockInstance", interfaceBlock.instanceName);
     EXPECT_TRUE(interfaceBlock.staticUse);
 
     ASSERT_EQ(1u, interfaceBlock.fields.size());
 
     const InterfaceBlockField &field = interfaceBlock.fields[0];
@@ -388,17 +386,16 @@ TEST_F(CollectVertexVariablesTest, Struc
     compile(shaderString);
 
     const std::vector<InterfaceBlock> &interfaceBlocks = mTranslator->getInterfaceBlocks();
     ASSERT_EQ(1u, interfaceBlocks.size());
 
     const InterfaceBlock &interfaceBlock = interfaceBlocks[0];
 
     EXPECT_EQ(0u, interfaceBlock.arraySize);
-    EXPECT_FALSE(interfaceBlock.isRowMajorLayout);
     EXPECT_EQ(BLOCKLAYOUT_SHARED, interfaceBlock.layout);
     EXPECT_EQ("b", interfaceBlock.name);
     EXPECT_EQ(DecorateName("b"), interfaceBlock.mappedName);
     EXPECT_TRUE(interfaceBlock.staticUse);
 
     ASSERT_EQ(1u, interfaceBlock.fields.size());
 
     const InterfaceBlockField &field = interfaceBlock.fields[0];
@@ -434,17 +431,16 @@ TEST_F(CollectVertexVariablesTest, Struc
     compile(shaderString);
 
     const std::vector<InterfaceBlock> &interfaceBlocks = mTranslator->getInterfaceBlocks();
     ASSERT_EQ(1u, interfaceBlocks.size());
 
     const InterfaceBlock &interfaceBlock = interfaceBlocks[0];
 
     EXPECT_EQ(0u, interfaceBlock.arraySize);
-    EXPECT_FALSE(interfaceBlock.isRowMajorLayout);
     EXPECT_EQ(BLOCKLAYOUT_SHARED, interfaceBlock.layout);
     EXPECT_EQ("b", interfaceBlock.name);
     EXPECT_EQ(DecorateName("b"), interfaceBlock.mappedName);
     EXPECT_EQ("instanceName", interfaceBlock.instanceName);
     EXPECT_TRUE(interfaceBlock.staticUse);
 
     ASSERT_EQ(1u, interfaceBlock.fields.size());
 
@@ -481,17 +477,16 @@ TEST_F(CollectVertexVariablesTest, Neste
     compile(shaderString);
 
     const std::vector<InterfaceBlock> &interfaceBlocks = mTranslator->getInterfaceBlocks();
     ASSERT_EQ(1u, interfaceBlocks.size());
 
     const InterfaceBlock &interfaceBlock = interfaceBlocks[0];
 
     EXPECT_EQ(0u, interfaceBlock.arraySize);
-    EXPECT_TRUE(interfaceBlock.isRowMajorLayout);
     EXPECT_EQ(BLOCKLAYOUT_SHARED, interfaceBlock.layout);
     EXPECT_EQ("b", interfaceBlock.name);
     EXPECT_EQ(DecorateName("b"), interfaceBlock.mappedName);
     EXPECT_TRUE(interfaceBlock.staticUse);
 
     ASSERT_EQ(1u, interfaceBlock.fields.size());
 
     const InterfaceBlockField &field = interfaceBlock.fields[0];
@@ -530,17 +525,17 @@ TEST_F(CollectVertexVariablesTest, Varyi
 
     const Varying *varying = &varyings[0];
 
     if (varying->name == "gl_Position")
     {
         varying = &varyings[1];
     }
 
-    EXPECT_EQ(0u, varying->arraySize);
+    EXPECT_FALSE(varying->isArray());
     EXPECT_GLENUM_EQ(GL_MEDIUM_FLOAT, varying->precision);
     EXPECT_TRUE(varying->staticUse);
     EXPECT_GLENUM_EQ(GL_FLOAT, varying->type);
     EXPECT_EQ("vary", varying->name);
     EXPECT_EQ(DecorateName("vary"), varying->mappedName);
     EXPECT_EQ(INTERPOLATION_CENTROID, varying->interpolation);
 }
 
@@ -576,17 +571,17 @@ TEST_F(CollectFragmentVariablesTest, Out
         "precision mediump float;\n"
         "void main() {\n"
         "   gl_FragColor = vec4(1.0);\n"
         "}\n";
 
     const OutputVariable *outputVariable = nullptr;
     validateOutputVariableForShader(fragColorShader, 0u, "gl_FragColor", &outputVariable);
     ASSERT_NE(outputVariable, nullptr);
-    EXPECT_EQ(0u, outputVariable->arraySize);
+    EXPECT_FALSE(outputVariable->isArray());
     EXPECT_GLENUM_EQ(GL_FLOAT_VEC4, outputVariable->type);
     EXPECT_GLENUM_EQ(GL_MEDIUM_FLOAT, outputVariable->precision);
 }
 
 // Test that gl_FragData built-in usage in ESSL1 fragment shader is reflected in the output
 // variables list.
 TEST_F(CollectFragmentVariablesTest, OutputVarESSL1FragData)
 {
@@ -602,17 +597,18 @@ TEST_F(CollectFragmentVariablesTest, Out
     resources.EXT_draw_buffers         = 1;
     const unsigned int kMaxDrawBuffers = 3u;
     resources.MaxDrawBuffers = kMaxDrawBuffers;
     initTranslator(resources);
 
     const OutputVariable *outputVariable = nullptr;
     validateOutputVariableForShader(fragDataShader, 0u, "gl_FragData", &outputVariable);
     ASSERT_NE(outputVariable, nullptr);
-    EXPECT_EQ(kMaxDrawBuffers, outputVariable->arraySize);
+    ASSERT_EQ(1u, outputVariable->arraySizes.size());
+    EXPECT_EQ(kMaxDrawBuffers, outputVariable->arraySizes.back());
     EXPECT_GLENUM_EQ(GL_FLOAT_VEC4, outputVariable->type);
     EXPECT_GLENUM_EQ(GL_MEDIUM_FLOAT, outputVariable->precision);
 }
 
 // Test that gl_FragDataEXT built-in usage in ESSL1 fragment shader is reflected in the output
 // variables list. Also test that the precision is mediump.
 TEST_F(CollectFragmentVariablesTest, OutputVarESSL1FragDepthMediump)
 {
@@ -625,17 +621,17 @@ TEST_F(CollectFragmentVariablesTest, Out
 
     ShBuiltInResources resources = mTranslator->getResources();
     resources.EXT_frag_depth = 1;
     initTranslator(resources);
 
     const OutputVariable *outputVariable = nullptr;
     validateOutputVariableForShader(fragDepthShader, 0u, "gl_FragDepthEXT", &outputVariable);
     ASSERT_NE(outputVariable, nullptr);
-    EXPECT_EQ(0u, outputVariable->arraySize);
+    EXPECT_FALSE(outputVariable->isArray());
     EXPECT_GLENUM_EQ(GL_FLOAT, outputVariable->type);
     EXPECT_GLENUM_EQ(GL_MEDIUM_FLOAT, outputVariable->precision);
 }
 
 // Test that gl_FragDataEXT built-in usage in ESSL1 fragment shader is reflected in the output
 // variables list. Also test that the precision is highp if user requests it.
 TEST_F(CollectFragmentVariablesTest, OutputVarESSL1FragDepthHighp)
 {
@@ -648,17 +644,17 @@ TEST_F(CollectFragmentVariablesTest, Out
     ShBuiltInResources resources    = mTranslator->getResources();
     resources.EXT_frag_depth        = 1;
     resources.FragmentPrecisionHigh = 1;
     initTranslator(resources);
 
     const OutputVariable *outputVariable = nullptr;
     validateOutputVariableForShader(fragDepthHighShader, 0u, "gl_FragDepthEXT", &outputVariable);
     ASSERT_NE(outputVariable, nullptr);
-    EXPECT_EQ(0u, outputVariable->arraySize);
+    EXPECT_FALSE(outputVariable->isArray());
     EXPECT_GLENUM_EQ(GL_FLOAT, outputVariable->type);
     EXPECT_GLENUM_EQ(GL_HIGH_FLOAT, outputVariable->precision);
 }
 
 // Test that gl_FragData built-in usage in ESSL3 fragment shader is reflected in the output
 // variables list. Also test that the precision is highp.
 TEST_F(CollectFragmentVariablesTest, OutputVarESSL3FragDepthHighp)
 {
@@ -671,17 +667,17 @@ TEST_F(CollectFragmentVariablesTest, Out
 
     ShBuiltInResources resources = mTranslator->getResources();
     resources.EXT_frag_depth = 1;
     initTranslator(resources);
 
     const OutputVariable *outputVariable = nullptr;
     validateOutputVariableForShader(fragDepthHighShader, 0u, "gl_FragDepth", &outputVariable);
     ASSERT_NE(outputVariable, nullptr);
-    EXPECT_EQ(0u, outputVariable->arraySize);
+    EXPECT_FALSE(outputVariable->isArray());
     EXPECT_GLENUM_EQ(GL_FLOAT, outputVariable->type);
     EXPECT_GLENUM_EQ(GL_HIGH_FLOAT, outputVariable->precision);
 }
 
 // Test that gl_SecondaryFragColorEXT built-in usage in ESSL1 fragment shader is reflected in the
 // output variables list.
 TEST_F(CollectFragmentVariablesTest, OutputVarESSL1EXTBlendFuncExtendedSecondaryFragColor)
 {
@@ -699,25 +695,25 @@ TEST_F(CollectFragmentVariablesTest, Out
     resources.EXT_draw_buffers         = 1;
     resources.MaxDrawBuffers           = kMaxDrawBuffers;
     resources.MaxDualSourceDrawBuffers = resources.MaxDrawBuffers;
     initTranslator(resources);
 
     const OutputVariable *outputVariable = nullptr;
     validateOutputVariableForShader(secondaryFragColorShader, 0u, "gl_FragColor", &outputVariable);
     ASSERT_NE(outputVariable, nullptr);
-    EXPECT_EQ(0u, outputVariable->arraySize);
+    EXPECT_FALSE(outputVariable->isArray());
     EXPECT_GLENUM_EQ(GL_FLOAT_VEC4, outputVariable->type);
     EXPECT_GLENUM_EQ(GL_MEDIUM_FLOAT, outputVariable->precision);
 
     outputVariable = nullptr;
     validateOutputVariableForShader(secondaryFragColorShader, 1u, "gl_SecondaryFragColorEXT",
                                     &outputVariable);
     ASSERT_NE(outputVariable, nullptr);
-    EXPECT_EQ(0u, outputVariable->arraySize);
+    EXPECT_FALSE(outputVariable->isArray());
     EXPECT_GLENUM_EQ(GL_FLOAT_VEC4, outputVariable->type);
     EXPECT_GLENUM_EQ(GL_MEDIUM_FLOAT, outputVariable->precision);
 }
 
 // Test that gl_SecondaryFragDataEXT built-in usage in ESSL1 fragment shader is reflected in the
 // output variables list.
 TEST_F(CollectFragmentVariablesTest, OutputVarESSL1EXTBlendFuncExtendedSecondaryFragData)
 {
@@ -737,25 +733,27 @@ TEST_F(CollectFragmentVariablesTest, Out
     resources.EXT_draw_buffers         = 1;
     resources.MaxDrawBuffers           = kMaxDrawBuffers;
     resources.MaxDualSourceDrawBuffers = resources.MaxDrawBuffers;
     initTranslator(resources);
 
     const OutputVariable *outputVariable = nullptr;
     validateOutputVariableForShader(secondaryFragDataShader, 0u, "gl_FragData", &outputVariable);
     ASSERT_NE(outputVariable, nullptr);
-    EXPECT_EQ(kMaxDrawBuffers, outputVariable->arraySize);
+    ASSERT_EQ(1u, outputVariable->arraySizes.size());
+    EXPECT_EQ(kMaxDrawBuffers, outputVariable->arraySizes.back());
     EXPECT_GLENUM_EQ(GL_FLOAT_VEC4, outputVariable->type);
     EXPECT_GLENUM_EQ(GL_MEDIUM_FLOAT, outputVariable->precision);
 
     outputVariable = nullptr;
     validateOutputVariableForShader(secondaryFragDataShader, 1u, "gl_SecondaryFragDataEXT",
                                     &outputVariable);
     ASSERT_NE(outputVariable, nullptr);
-    EXPECT_EQ(kMaxDrawBuffers, outputVariable->arraySize);
+    ASSERT_EQ(1u, outputVariable->arraySizes.size());
+    EXPECT_EQ(kMaxDrawBuffers, outputVariable->arraySizes.back());
     EXPECT_GLENUM_EQ(GL_FLOAT_VEC4, outputVariable->type);
     EXPECT_GLENUM_EQ(GL_MEDIUM_FLOAT, outputVariable->precision);
 }
 
 static khronos_uint64_t SimpleTestHash(const char *str, size_t len)
 {
     return static_cast<uint64_t>(len);
 }
@@ -787,17 +785,16 @@ TEST_F(CollectHashedVertexVariablesTest,
     compile(shaderString);
 
     const std::vector<InterfaceBlock> &interfaceBlocks = mTranslator->getInterfaceBlocks();
     ASSERT_EQ(1u, interfaceBlocks.size());
 
     const InterfaceBlock &interfaceBlock = interfaceBlocks[0];
 
     EXPECT_EQ(0u, interfaceBlock.arraySize);
-    EXPECT_FALSE(interfaceBlock.isRowMajorLayout);
     EXPECT_EQ(BLOCKLAYOUT_SHARED, interfaceBlock.layout);
     EXPECT_EQ("blockName", interfaceBlock.name);
     EXPECT_EQ("blockInstance", interfaceBlock.instanceName);
     EXPECT_EQ("webgl_9", interfaceBlock.mappedName);
     EXPECT_TRUE(interfaceBlock.staticUse);
 
     ASSERT_EQ(1u, interfaceBlock.fields.size());
 
@@ -807,38 +804,83 @@ TEST_F(CollectHashedVertexVariablesTest,
     EXPECT_TRUE(field.staticUse);
     EXPECT_GLENUM_EQ(GL_FLOAT, field.type);
     EXPECT_EQ("field", field.name);
     EXPECT_EQ("webgl_5", field.mappedName);
     EXPECT_FALSE(field.isRowMajorLayout);
     EXPECT_TRUE(field.fields.empty());
 }
 
+// Test a struct uniform where the struct does have a name.
 TEST_F(CollectHashedVertexVariablesTest, StructUniform)
 {
     const std::string &shaderString =
-        "#version 300 es\n"
-        "struct sType {\n"
-        "  float field;\n"
-        "};"
-        "uniform sType u;"
-        "void main() {\n"
-        "   gl_Position = vec4(u.field, 0.0, 0.0, 1.0);\n"
-        "}\n";
+        R"(#version 300 es
+        struct sType
+        {
+            float field;
+        };
+        uniform sType u;
+
+        void main()
+        {
+            gl_Position = vec4(u.field, 0.0, 0.0, 1.0);
+        })";
 
     compile(shaderString);
 
     const auto &uniforms = mTranslator->getUniforms();
     ASSERT_EQ(1u, uniforms.size());
 
     const Uniform &uniform = uniforms[0];
 
-    EXPECT_EQ(0u, uniform.arraySize);
+    EXPECT_FALSE(uniform.isArray());
     EXPECT_EQ("u", uniform.name);
     EXPECT_EQ("webgl_1", uniform.mappedName);
+    EXPECT_EQ("sType", uniform.structName);
+    EXPECT_TRUE(uniform.staticUse);
+
+    ASSERT_EQ(1u, uniform.fields.size());
+
+    const ShaderVariable &field = uniform.fields[0];
+
+    EXPECT_GLENUM_EQ(GL_HIGH_FLOAT, field.precision);
+    // EXPECT_TRUE(field.staticUse); // we don't yet support struct static use
+    EXPECT_GLENUM_EQ(GL_FLOAT, field.type);
+    EXPECT_EQ("field", field.name);
+    EXPECT_EQ("webgl_5", field.mappedName);
+    EXPECT_TRUE(field.fields.empty());
+}
+
+// Test a struct uniform where the struct doesn't have a name.
+TEST_F(CollectHashedVertexVariablesTest, NamelessStructUniform)
+{
+    const std::string &shaderString =
+        R"(#version 300 es
+        uniform struct
+        {
+            float field;
+        } u;
+
+        void main()
+        {
+            gl_Position = vec4(u.field, 0.0, 0.0, 1.0);
+        })";
+
+    compile(shaderString);
+
+    const auto &uniforms = mTranslator->getUniforms();
+    ASSERT_EQ(1u, uniforms.size());
+
+    const Uniform &uniform = uniforms[0];
+
+    EXPECT_FALSE(uniform.isArray());
+    EXPECT_EQ("u", uniform.name);
+    EXPECT_EQ("webgl_1", uniform.mappedName);
+    EXPECT_EQ("", uniform.structName);
     EXPECT_TRUE(uniform.staticUse);
 
     ASSERT_EQ(1u, uniform.fields.size());
 
     const ShaderVariable &field = uniform.fields[0];
 
     EXPECT_GLENUM_EQ(GL_HIGH_FLOAT, field.precision);
     // EXPECT_TRUE(field.staticUse); // we don't yet support struct static use
@@ -863,24 +905,24 @@ TEST_F(CollectFragmentVariablesTest, Mul
         "}\n";
 
     compile(shaderString);
 
     const auto &uniforms = mTranslator->getUniforms();
     ASSERT_EQ(2u, uniforms.size());
 
     const Uniform &uniform = uniforms[0];
-    EXPECT_EQ(0u, uniform.arraySize);
+    EXPECT_FALSE(uniform.isArray());
     EXPECT_GLENUM_EQ(GL_MEDIUM_FLOAT, uniform.precision);
     EXPECT_TRUE(uniform.staticUse);
     EXPECT_GLENUM_EQ(GL_FLOAT, uniform.type);
     EXPECT_EQ("uA", uniform.name);
 
     const Uniform &uniformB = uniforms[1];
-    EXPECT_EQ(0u, uniformB.arraySize);
+    EXPECT_FALSE(uniformB.isArray());
     EXPECT_GLENUM_EQ(GL_MEDIUM_FLOAT, uniformB.precision);
     EXPECT_TRUE(uniformB.staticUse);
     EXPECT_GLENUM_EQ(GL_FLOAT, uniformB.type);
     EXPECT_EQ("uB", uniformB.name);
 }
 
 // Test a uniform declaration starting with an empty declarator.
 TEST_F(CollectFragmentVariablesTest, EmptyDeclarator)
@@ -896,17 +938,17 @@ TEST_F(CollectFragmentVariablesTest, Emp
         "}\n";
 
     compile(shaderString);
 
     const auto &uniforms = mTranslator->getUniforms();
     ASSERT_EQ(1u, uniforms.size());
 
     const Uniform &uniformB = uniforms[0];
-    EXPECT_EQ(0u, uniformB.arraySize);
+    EXPECT_FALSE(uniformB.isArray());
     EXPECT_GLENUM_EQ(GL_MEDIUM_FLOAT, uniformB.precision);
     EXPECT_TRUE(uniformB.staticUse);
     EXPECT_GLENUM_EQ(GL_FLOAT, uniformB.type);
     EXPECT_EQ("uB", uniformB.name);
 }
 
 // Test collecting variables from an instanced multiview shader that has an internal ViewID_OVR
 // varying.
@@ -935,29 +977,33 @@ TEST_F(CollectVertexVariablesTest, ViewI
     const Varying *varying = &varyings[0];
     EXPECT_EQ("gl_Position", varying->name);
 }
 
 // Test all the fields of gl_in can be collected correctly in a geometry shader.
 TEST_F(CollectGeometryVariablesTest, CollectGLInFields)
 {
     const std::string &shaderString =
-        "#version 310 es\n"
-        "#extension GL_OES_geometry_shader : require\n"
-        "layout (points) in;\n"
-        "layout (points, max_vertices = 2) out;\n"
-        "void main()\n"
-        "{\n"
-        "    vec4 value = gl_in[0].gl_Position;\n"
-        "    vec4 value2 = gl_in[0].gl_Position;\n"
-        "}\n";
+        R"(#version 310 es
+        #extension GL_EXT_geometry_shader : require
+
+        layout (points) in;
+        layout (points, max_vertices = 2) out;
+
+        void main()
+        {
+            vec4 value = gl_in[0].gl_Position;
+            vec4 value2 = gl_in[0].gl_Position;
+            gl_Position = value + value2;
+            EmitVertex();
+        })";
 
     compile(shaderString);
 
-    EXPECT_TRUE(mTranslator->getOutputVaryings().empty());
+    EXPECT_EQ(1u, mTranslator->getOutputVaryings().size());
     EXPECT_TRUE(mTranslator->getInputVaryings().empty());
 
     const auto &inBlocks = mTranslator->getInBlocks();
     ASSERT_EQ(1u, inBlocks.size());
 
     const InterfaceBlock *inBlock = &inBlocks[0];
     EXPECT_EQ("gl_PerVertex", inBlock->name);
     EXPECT_EQ("gl_in", inBlock->instanceName);
@@ -976,47 +1022,55 @@ TEST_F(CollectGeometryVariablesTest, Col
     EXPECT_GLENUM_EQ(GL_FLOAT_VEC4, glPositionField.type);
 }
 
 // Test the collected array size of gl_in matches the input primitive declaration.
 TEST_F(CollectGeometryVariablesTest, GLInArraySize)
 {
     const std::array<std::string, 5> kInputPrimitives = {
         {"points", "lines", "lines_adjacency", "triangles", "triangles_adjacency"}};
-    constexpr GLuint kArraySizeForInputPrimitives[] = {1u, 2u, 4u, 3u, 6u};
+
+    const GLuint kArraySizeForInputPrimitives[] = {1u, 2u, 4u, 3u, 6u};
+
+    const std::string &functionBody =
+        R"(void main()
+        {
+            gl_Position = gl_in[0].gl_Position;
+        })";
 
     for (size_t i = 0; i < kInputPrimitives.size(); ++i)
     {
-        compileGeometryShaderWithInputPrimitive(kInputPrimitives[i]);
+        compileGeometryShaderWithInputPrimitive(kInputPrimitives[i], "", functionBody);
 
         const auto &inBlocks = mTranslator->getInBlocks();
         ASSERT_EQ(1u, inBlocks.size());
 
         const InterfaceBlock *inBlock = &inBlocks[0];
         ASSERT_EQ("gl_in", inBlock->instanceName);
         EXPECT_EQ(kArraySizeForInputPrimitives[i], inBlock->arraySize);
     }
 }
 
 // Test collecting gl_PrimitiveIDIn in a geometry shader.
 TEST_F(CollectGeometryVariablesTest, CollectPrimitiveIDIn)
 {
     const std::string &shaderString =
-        "#version 310 es\n"
-        "#extension GL_OES_geometry_shader : require\n"
-        "layout (points) in;\n"
-        "layout (points, max_vertices = 2) out;\n"
-        "void main()\n"
-        "{\n"
-        "    int value = gl_PrimitiveIDIn;\n"
-        "}\n";
+        R"(#version 310 es
+        #extension GL_EXT_geometry_shader : require
+        layout (points) in;
+        layout (points, max_vertices = 2) out;
+        void main()
+        {
+            gl_Position = vec4(gl_PrimitiveIDIn);
+            EmitVertex();
+        })";
 
     compile(shaderString);
 
-    ASSERT_TRUE(mTranslator->getOutputVaryings().empty());
+    EXPECT_EQ(1u, mTranslator->getOutputVaryings().size());
     ASSERT_TRUE(mTranslator->getInBlocks().empty());
 
     const auto &inputVaryings = mTranslator->getInputVaryings();
     ASSERT_EQ(1u, inputVaryings.size());
 
     const Varying *varying = &inputVaryings[0];
     EXPECT_EQ("gl_PrimitiveIDIn", varying->name);
     EXPECT_FALSE(varying->isArray());
@@ -1026,28 +1080,29 @@ TEST_F(CollectGeometryVariablesTest, Col
     EXPECT_GLENUM_EQ(GL_HIGH_INT, varying->precision);
     EXPECT_GLENUM_EQ(GL_INT, varying->type);
 }
 
 // Test collecting gl_InvocationID in a geometry shader.
 TEST_F(CollectGeometryVariablesTest, CollectInvocationID)
 {
     const std::string &shaderString =
-        "#version 310 es\n"
-        "#extension GL_OES_geometry_shader : require\n"
-        "layout (points, invocations = 2) in;\n"
-        "layout (points, max_vertices = 2) out;\n"
-        "void main()\n"
-        "{\n"
-        "    int value = gl_InvocationID;\n"
-        "}\n";
+        R"(#version 310 es
+        #extension GL_EXT_geometry_shader : require
+        layout (points, invocations = 2) in;
+        layout (points, max_vertices = 2) out;
+        void main()
+        {
+            gl_Position = vec4(gl_InvocationID);
+            EmitVertex();
+        })";
 
     compile(shaderString);
 
-    ASSERT_TRUE(mTranslator->getOutputVaryings().empty());
+    EXPECT_EQ(1u, mTranslator->getOutputVaryings().size());
     ASSERT_TRUE(mTranslator->getInBlocks().empty());
 
     const auto &inputVaryings = mTranslator->getInputVaryings();
     ASSERT_EQ(1u, inputVaryings.size());
 
     const Varying *varying = &inputVaryings[0];
     EXPECT_EQ("gl_InvocationID", varying->name);
     EXPECT_FALSE(varying->isArray());
@@ -1057,28 +1112,29 @@ TEST_F(CollectGeometryVariablesTest, Col
     EXPECT_GLENUM_EQ(GL_HIGH_INT, varying->precision);
     EXPECT_GLENUM_EQ(GL_INT, varying->type);
 }
 
 // Test collecting gl_in in a geometry shader when gl_in is indexed by an expression.
 TEST_F(CollectGeometryVariablesTest, CollectGLInIndexedByExpression)
 {
     const std::string &shaderString =
-        "#version 310 es\n"
-        "#extension GL_OES_geometry_shader : require\n"
-        "layout (triangles, invocations = 2) in;\n"
-        "layout (points, max_vertices = 2) out;\n"
-        "void main()\n"
-        "{\n"
-        "    vec4 value = gl_in[gl_InvocationID + 1].gl_Position;\n"
-        "}\n";
+        R"(#version 310 es
+        #extension GL_EXT_geometry_shader : require
+        layout (triangles, invocations = 2) in;
+        layout (points, max_vertices = 2) out;
+        void main()
+        {
+            gl_Position = gl_in[gl_InvocationID + 1].gl_Position;
+            EmitVertex();
+        })";
 
     compile(shaderString);
 
-    ASSERT_TRUE(mTranslator->getOutputVaryings().empty());
+    EXPECT_EQ(1u, mTranslator->getOutputVaryings().size());
 
     const auto &inBlocks = mTranslator->getInBlocks();
     ASSERT_EQ(1u, inBlocks.size());
     const InterfaceBlock *inBlock = &inBlocks[0];
     EXPECT_EQ("gl_PerVertex", inBlock->name);
     EXPECT_EQ("gl_in", inBlock->instanceName);
 
     const auto &inputVaryings = mTranslator->getInputVaryings();
@@ -1086,24 +1142,24 @@ TEST_F(CollectGeometryVariablesTest, Col
     const Varying *glInvocationID = &inputVaryings[0];
     EXPECT_EQ("gl_InvocationID", glInvocationID->name);
 }
 
 // Test collecting gl_Position in a geometry shader.
 TEST_F(CollectGeometryVariablesTest, CollectPosition)
 {
     const std::string &shaderString =
-        "#version 310 es\n"
-        "#extension GL_OES_geometry_shader : require\n"
-        "layout (points) in;\n"
-        "layout (points, max_vertices = 2) out;\n"
-        "void main()\n"
-        "{\n"
-        "    gl_Position = vec4(0.1, 0.2, 0.3, 1);\n"
-        "}\n";
+        R"(#version 310 es
+        #extension GL_EXT_geometry_shader : require
+        layout (points) in;
+        layout (points, max_vertices = 2) out;
+        void main()
+        {
+            gl_Position = vec4(0.1, 0.2, 0.3, 1);
+        })";
 
     compile(shaderString);
 
     ASSERT_TRUE(mTranslator->getInputVaryings().empty());
     ASSERT_TRUE(mTranslator->getInBlocks().empty());
 
     const auto &outputVaryings = mTranslator->getOutputVaryings();
     ASSERT_EQ(1u, outputVaryings.size());
@@ -1117,24 +1173,24 @@ TEST_F(CollectGeometryVariablesTest, Col
     EXPECT_GLENUM_EQ(GL_HIGH_FLOAT, varying->precision);
     EXPECT_GLENUM_EQ(GL_FLOAT_VEC4, varying->type);
 }
 
 // Test collecting gl_PrimitiveID in a geometry shader.
 TEST_F(CollectGeometryVariablesTest, CollectPrimitiveID)
 {
     const std::string &shaderString =
-        "#version 310 es\n"
-        "#extension GL_OES_geometry_shader : require\n"
-        "layout (points) in;\n"
-        "layout (points, max_vertices = 2) out;\n"
-        "void main()\n"
-        "{\n"
-        "    gl_PrimitiveID = 100;\n"
-        "}\n";
+        R"(#version 310 es
+        #extension GL_EXT_geometry_shader : require
+        layout (points) in;
+        layout (points, max_vertices = 2) out;
+        void main()
+        {
+            gl_PrimitiveID = 100;
+        })";
 
     compile(shaderString);
 
     ASSERT_TRUE(mTranslator->getInputVaryings().empty());
     ASSERT_TRUE(mTranslator->getInBlocks().empty());
 
     const auto &OutputVaryings = mTranslator->getOutputVaryings();
     ASSERT_EQ(1u, OutputVaryings.size());
@@ -1148,24 +1204,24 @@ TEST_F(CollectGeometryVariablesTest, Col
     EXPECT_GLENUM_EQ(GL_HIGH_INT, varying->precision);
     EXPECT_GLENUM_EQ(GL_INT, varying->type);
 }
 
 // Test collecting gl_Layer in a geometry shader.
 TEST_F(CollectGeometryVariablesTest, CollectLayer)
 {
     const std::string &shaderString =
-        "#version 310 es\n"
-        "#extension GL_OES_geometry_shader : require\n"
-        "layout (points) in;\n"
-        "layout (points, max_vertices = 2) out;\n"
-        "void main()\n"
-        "{\n"
-        "    gl_Layer = 2;\n"
-        "}\n";
+        R"(#version 310 es
+        #extension GL_EXT_geometry_shader : require
+        layout (points) in;
+        layout (points, max_vertices = 2) out;
+        void main()
+        {
+            gl_Layer = 2;
+        })";
 
     compile(shaderString);
 
     ASSERT_TRUE(mTranslator->getInputVaryings().empty());
     ASSERT_TRUE(mTranslator->getInBlocks().empty());
 
     const auto &OutputVaryings = mTranslator->getOutputVaryings();
     ASSERT_EQ(1u, OutputVaryings.size());
@@ -1176,25 +1232,28 @@ TEST_F(CollectGeometryVariablesTest, Col
     EXPECT_FALSE(varying->isStruct());
     EXPECT_TRUE(varying->staticUse);
     EXPECT_TRUE(varying->isBuiltIn());
     EXPECT_GLENUM_EQ(GL_HIGH_INT, varying->precision);
     EXPECT_GLENUM_EQ(GL_INT, varying->type);
 }
 
 // Test collecting gl_PrimitiveID in a fragment shader.
-TEST_F(CollectFragmentVariablesOESGeometryShaderTest, CollectPrimitiveID)
+TEST_F(CollectFragmentVariablesEXTGeometryShaderTest, CollectPrimitiveID)
 {
     const std::string &shaderString =
-        "#version 310 es\n"
-        "#extension GL_OES_geometry_shader : require\n"
-        "void main()\n"
-        "{\n"
-        "    int value = gl_PrimitiveID;\n"
-        "}\n";
+        R"(#version 310 es
+        #extension GL_EXT_geometry_shader : require
+
+        out int my_out;
+
+        void main()
+        {
+            my_out = gl_PrimitiveID;
+        })";
 
     compile(shaderString);
 
     ASSERT_TRUE(mTranslator->getOutputVaryings().empty());
 
     const auto &inputVaryings = mTranslator->getInputVaryings();
     ASSERT_EQ(1u, inputVaryings.size());
 
@@ -1204,25 +1263,28 @@ TEST_F(CollectFragmentVariablesOESGeomet
     EXPECT_FALSE(varying->isStruct());
     EXPECT_TRUE(varying->staticUse);
     EXPECT_TRUE(varying->isBuiltIn());
     EXPECT_GLENUM_EQ(GL_HIGH_INT, varying->precision);
     EXPECT_GLENUM_EQ(GL_INT, varying->type);
 }
 
 // Test collecting gl_Layer in a fragment shader.
-TEST_F(CollectFragmentVariablesOESGeometryShaderTest, CollectLayer)
+TEST_F(CollectFragmentVariablesEXTGeometryShaderTest, CollectLayer)
 {
     const std::string &shaderString =
-        "#version 310 es\n"
-        "#extension GL_OES_geometry_shader : require\n"
-        "void main()\n"
-        "{\n"
-        "    int value = gl_Layer;\n"
-        "}\n";
+        R"(#version 310 es
+        #extension GL_EXT_geometry_shader : require
+
+        out int my_out;
+
+        void main()
+        {
+            my_out = gl_Layer;
+        })";
 
     compile(shaderString);
 
     ASSERT_TRUE(mTranslator->getOutputVaryings().empty());
 
     const auto &inputVaryings = mTranslator->getInputVaryings();
     ASSERT_EQ(1u, inputVaryings.size());
 
@@ -1235,22 +1297,22 @@ TEST_F(CollectFragmentVariablesOESGeomet
     EXPECT_GLENUM_EQ(GL_HIGH_INT, varying->precision);
     EXPECT_GLENUM_EQ(GL_INT, varying->type);
 }
 
 // Test collecting the location of vertex shader outputs.
 TEST_F(CollectVertexVariablesES31Test, CollectOutputWithLocation)
 {
     const std::string &shaderString =
-        "#version 310 es\n"
-        "out vec4 v_output1;\n"
-        "layout (location = 1) out vec4 v_output2;\n"
-        "void main()\n"
-        "{\n"
-        "}\n";
+        R"(#version 310 es
+        out vec4 v_output1;
+        layout (location = 1) out vec4 v_output2;
+        void main()
+        {
+        })";
 
     compile(shaderString);
 
     const auto &outputVaryings = mTranslator->getOutputVaryings();
     ASSERT_EQ(2u, outputVaryings.size());
 
     const Varying *varying1 = &outputVaryings[0];
     EXPECT_EQ("v_output1", varying1->name);
@@ -1260,31 +1322,234 @@ TEST_F(CollectVertexVariablesES31Test, C
     EXPECT_EQ("v_output2", varying2->name);
     EXPECT_EQ(1, varying2->location);
 }
 
 // Test collecting the location of fragment shader inputs.
 TEST_F(CollectFragmentVariablesES31Test, CollectInputWithLocation)
 {
     const std::string &shaderString =
-        "#version 310 es\n"
-        "precision mediump float;\n"
-        "in vec4 f_input1;\n"
-        "layout (location = 1) in vec4 f_input2;\n"
-        "layout (location = 0) out vec4 o_color;\n"
-        "void main()\n"
-        "{\n"
-        "    o_color = f_input2;\n"
-        "}\n";
+        R"(#version 310 es
+        precision mediump float;
+        in vec4 f_input1;
+        layout (location = 1) in vec4 f_input2;
+        layout (location = 0) out vec4 o_color;
+        void main()
+        {
+            o_color = f_input2;
+        })";
 
     compile(shaderString);
 
     const auto &inputVaryings = mTranslator->getInputVaryings();
     ASSERT_EQ(2u, inputVaryings.size());
 
     const Varying *varying1 = &inputVaryings[0];
     EXPECT_EQ("f_input1", varying1->name);
     EXPECT_EQ(-1, varying1->location);
 
     const Varying *varying2 = &inputVaryings[1];
     EXPECT_EQ("f_input2", varying2->name);
     EXPECT_EQ(1, varying2->location);
 }
+
+// Test collecting the inputs of a geometry shader.
+TEST_F(CollectGeometryVariablesTest, CollectInputs)
+{
+    const std::string &shaderString =
+        R"(#version 310 es
+        #extension GL_EXT_geometry_shader : require
+        layout (points) in;
+        layout (points, max_vertices = 2) out;
+        in vec4 texcoord1[];
+        in vec4 texcoord2[1];
+        void main()
+        {
+            gl_Position = texcoord1[0];
+            gl_Position += texcoord2[0];
+            EmitVertex();
+        })";
+
+    compile(shaderString);
+
+    EXPECT_EQ(1u, mTranslator->getOutputVaryings().size());
+
+    const auto &inputVaryings = mTranslator->getInputVaryings();
+    ASSERT_EQ(2u, inputVaryings.size());
+
+    const std::string kVaryingName[] = {"texcoord1", "texcoord2"};
+
+    for (size_t i = 0; i < inputVaryings.size(); ++i)
+    {
+        const Varying &varying = inputVaryings[i];
+
+        EXPECT_EQ(kVaryingName[i], varying.name);
+        EXPECT_TRUE(varying.isArray());
+        EXPECT_FALSE(varying.isStruct());
+        EXPECT_TRUE(varying.staticUse);
+        EXPECT_FALSE(varying.isBuiltIn());
+        EXPECT_GLENUM_EQ(GL_HIGH_FLOAT, varying.precision);
+        EXPECT_GLENUM_EQ(GL_FLOAT_VEC4, varying.type);
+        EXPECT_FALSE(varying.isInvariant);
+        ASSERT_EQ(1u, varying.arraySizes.size());
+        EXPECT_EQ(1u, varying.arraySizes.back());
+    }
+}
+
+// Test that the unsized input of a geometry shader can be correctly collected.
+TEST_F(CollectGeometryVariablesTest, CollectInputArraySizeForUnsizedInput)
+{
+    const std::array<std::string, 5> kInputPrimitives = {
+        {"points", "lines", "lines_adjacency", "triangles", "triangles_adjacency"}};
+
+    const GLuint kArraySizeForInputPrimitives[] = {1u, 2u, 4u, 3u, 6u};
+
+    const std::string &kVariableDeclaration = "in vec4 texcoord[];\n";
+    const std::string &kFunctionBody =
+        R"(void main()
+        {
+            gl_Position = texcoord[0];
+        })";
+
+    for (size_t i = 0; i < kInputPrimitives.size(); ++i)
+    {
+        compileGeometryShaderWithInputPrimitive(kInputPrimitives[i], kVariableDeclaration,
+                                                kFunctionBody);
+
+        const auto &inputVaryings = mTranslator->getInputVaryings();
+        ASSERT_EQ(1u, inputVaryings.size());
+
+        const Varying *varying = &inputVaryings[0];
+        EXPECT_EQ("texcoord", varying->name);
+        ASSERT_EQ(1u, varying->arraySizes.size());
+        EXPECT_EQ(kArraySizeForInputPrimitives[i], varying->arraySizes.back());
+    }
+}
+
+// Test collecting inputs using interpolation qualifiers in a geometry shader.
+TEST_F(CollectGeometryVariablesTest, CollectInputsWithInterpolationQualifiers)
+{
+    const std::string &kHeader =
+        "#version 310 es\n"
+        "#extension GL_EXT_geometry_shader : require\n";
+    const std::string &kLayout =
+        "layout (points) in;\n"
+        "layout (points, max_vertices = 2) out;\n";
+
+    const std::array<std::string, 3> kInterpolationQualifiers = {{"flat", "smooth", "centroid"}};
+
+    const std::array<InterpolationType, 3> kInterpolationType = {
+        {INTERPOLATION_FLAT, INTERPOLATION_SMOOTH, INTERPOLATION_CENTROID}};
+
+    const std::string &kFunctionBody =
+        R"(void main()
+        {
+            gl_Position = texcoord[0];
+            EmitVertex();
+        })";
+
+    for (size_t i = 0; i < kInterpolationQualifiers.size(); ++i)
+    {
+        const std::string &qualifier = kInterpolationQualifiers[i];
+
+        std::ostringstream stream1;
+        stream1 << kHeader << kLayout << qualifier << " in vec4 texcoord[];\n" << kFunctionBody;
+        compile(stream1.str());
+
+        const auto &inputVaryings = mTranslator->getInputVaryings();
+        ASSERT_EQ(1u, inputVaryings.size());
+        const Varying *varying = &inputVaryings[0];
+        EXPECT_EQ("texcoord", varying->name);
+        EXPECT_EQ(kInterpolationType[i], varying->interpolation);
+    }
+}
+
+// Test collecting outputs using interpolation qualifiers in a geometry shader.
+TEST_F(CollectGeometryVariablesTest, CollectOutputsWithInterpolationQualifiers)
+{
+    const std::string &kHeader =
+        "#version 310 es\n"
+        "#extension GL_EXT_geometry_shader : require\n"
+        "layout (points) in;\n"
+        "layout (points, max_vertices = 2) out;\n";
+
+    const std::array<std::string, 4> kInterpolationQualifiers = {
+        {"", "flat", "smooth", "centroid"}};
+
+    const std::array<InterpolationType, 4> kInterpolationType = {
+        {INTERPOLATION_SMOOTH, INTERPOLATION_FLAT, INTERPOLATION_SMOOTH, INTERPOLATION_CENTROID}};
+
+    const std::string &kFunctionBody =
+        "void main()\n"
+        "{\n"
+        "    texcoord = vec4(1.0, 0.0, 0.0, 1.0);\n"
+        "}\n";
+
+    for (size_t i = 0; i < kInterpolationQualifiers.size(); ++i)
+    {
+        const std::string &qualifier = kInterpolationQualifiers[i];
+        std::ostringstream stream;
+        stream << kHeader << qualifier << " out vec4 texcoord;\n" << kFunctionBody;
+
+        compile(stream.str());
+        const auto &outputVaryings = mTranslator->getOutputVaryings();
+        ASSERT_EQ(1u, outputVaryings.size());
+
+        const Varying *varying = &outputVaryings[0];
+        EXPECT_EQ("texcoord", varying->name);
+        EXPECT_EQ(kInterpolationType[i], varying->interpolation);
+        EXPECT_FALSE(varying->isInvariant);
+    }
+}
+
+// Test collecting outputs using 'invariant' qualifier in a geometry shader.
+TEST_F(CollectGeometryVariablesTest, CollectOutputsWithInvariant)
+{
+    const std::string &shaderString =
+        R"(#version 310 es
+        #extension GL_EXT_geometry_shader : require
+        layout (points) in;
+        layout (points, max_vertices = 2) out;
+        invariant out vec4 texcoord;
+        void main()
+        {
+            texcoord = vec4(1.0, 0.0, 0.0, 1.0);
+        })";
+
+    compile(shaderString);
+
+    const auto &outputVaryings = mTranslator->getOutputVaryings();
+    ASSERT_EQ(1u, outputVaryings.size());
+
+    const Varying *varying = &outputVaryings[0];
+    EXPECT_EQ("texcoord", varying->name);
+    EXPECT_TRUE(varying->isInvariant);
+}
+
+// Test collecting a varying variable that is used inside a folded ternary operator. The result of
+// the folded ternary operator has a different qualifier from the original variable, which makes
+// this case tricky.
+TEST_F(CollectFragmentVariablesTest, VaryingUsedInsideFoldedTernary)
+{
+    const std::string &shaderString =
+        R"(#version 300 es
+        precision highp float;
+        centroid in float vary;
+        out vec4 color;
+        void main() {
+           color = vec4(0.0, true ? vary : 0.0, 0.0, 1.0);
+        })";
+
+    compile(shaderString);
+
+    const std::vector<Varying> &varyings = mTranslator->getInputVaryings();
+    ASSERT_EQ(1u, varyings.size());
+
+    const Varying *varying = &varyings[0];
+
+    EXPECT_FALSE(varying->isArray());
+    EXPECT_GLENUM_EQ(GL_HIGH_FLOAT, varying->precision);
+    EXPECT_TRUE(varying->staticUse);
+    EXPECT_GLENUM_EQ(GL_FLOAT, varying->type);
+    EXPECT_EQ("vary", varying->name);
+    EXPECT_EQ(DecorateName("vary"), varying->mappedName);
+    EXPECT_EQ(INTERPOLATION_CENTROID, varying->interpolation);
+}
--- a/gfx/angle/src/tests/compiler_tests/ConstantFolding_test.cpp
+++ b/gfx/angle/src/tests/compiler_tests/ConstantFolding_test.cpp
@@ -1412,8 +1412,42 @@ TEST_F(ConstantFoldingExpressionTest, Fo
 
 // Test that ldexp is folded correctly.
 TEST_F(ConstantFoldingExpressionTest, FoldLdexp)
 {
     const std::string &floatString = "ldexp(0.625, 1)";
     evaluateFloat(floatString);
     ASSERT_TRUE(constantFoundInAST(1.25f));
 }
+
+// Fold a ternary operator.
+TEST_F(ConstantFoldingTest, FoldTernary)
+{
+    const std::string &shaderString =
+        R"(#version 300 es
+        precision highp int;
+        uniform int u;
+        out int my_FragColor;
+        void main()
+        {
+            my_FragColor = (true ? 1 : u);
+        })";
+    compileAssumeSuccess(shaderString);
+    ASSERT_TRUE(constantFoundInAST(1));
+    ASSERT_FALSE(symbolFoundInMain("u"));
+}
+
+// Fold a ternary operator inside a consuming expression.
+TEST_F(ConstantFoldingTest, FoldTernaryInsideExpression)
+{
+    const std::string &shaderString =
+        R"(#version 300 es
+        precision highp int;
+        uniform int u;
+        out int my_FragColor;
+        void main()
+        {
+            my_FragColor = ivec2((true ? 1 : u) + 2, 4).x;
+        })";
+    compileAssumeSuccess(shaderString);
+    ASSERT_TRUE(constantFoundInAST(3));
+    ASSERT_FALSE(symbolFoundInMain("u"));
+}
--- a/gfx/angle/src/tests/compiler_tests/DebugShaderPrecision_test.cpp
+++ b/gfx/angle/src/tests/compiler_tests/DebugShaderPrecision_test.cpp
@@ -812,18 +812,18 @@ TEST_F(DebugShaderPrecisionTest, Constru
         "   vec4 v1 = vec4(u1, u2, u3, u4);\n"
         "   vec4 v2 = vec4(uiv);\n"
         "   gl_FragColor = v1 + v2;\n"
         "}\n";
     compile(shaderString);
     ASSERT_TRUE(foundInAllGLSLCode("v1 = angle_frm(vec4(_uu1, _uu2, angle_frl(_uu3), _uu4))"));
     ASSERT_TRUE(foundInAllGLSLCode("v2 = angle_frm(vec4(_uuiv))"));
 
-    ASSERT_TRUE(foundInHLSLCode("v1 = angle_frm(vec4(_u1, _u2, angle_frl(_u3), _u4))"));
-    ASSERT_TRUE(foundInHLSLCode("v2 = angle_frm(vec4(_uiv))"));
+    ASSERT_TRUE(foundInHLSLCode("v1 = angle_frm(vec4_ctor(_u1, _u2, angle_frl(_u3), _u4))"));
+    ASSERT_TRUE(foundInHLSLCode("v2 = angle_frm(vec4_ctor(_uiv))"));
 }
 
 TEST_F(DebugShaderPrecisionTest, StructConstructorNoRounding)
 {
     const std::string &shaderString =
         "precision mediump float;\n"
         "struct S { mediump vec4 a; };\n"
         "uniform vec4 u;\n"
--- a/gfx/angle/src/tests/compiler_tests/EXT_YUV_target_test.cpp
+++ b/gfx/angle/src/tests/compiler_tests/EXT_YUV_target_test.cpp
@@ -94,38 +94,59 @@ const char ESSL300_MultipleYUVOutputsFai
     "precision mediump float;\n"
     "layout(yuv) out vec4 fragColor;\n"
     "layout(yuv) out vec4 fragColor1;\n"
     "void main() { \n"
     "}\n";
 
 // Shader that specifies yuvCscStandartEXT type and associated values.
 const char ESSL300_YuvCscStandardEXTShader[] =
-    "precision mediump float;\n"
-    "yuvCscStandardEXT;\n"
-    "yuvCscStandardEXT conv;\n"
-    "yuvCscStandardEXT conv1 = itu_601;\n"
-    "yuvCscStandardEXT conv2 = itu_601_full_range;\n"
-    "yuvCscStandardEXT conv3 = itu_709;\n"
-    "const yuvCscStandardEXT conv4 = itu_709;\n"
-    "yuvCscStandardEXT conv_standard() {\n"
-    "    return itu_601;\n"
-    "}\n"
-    "bool is_itu_601(inout yuvCscStandardEXT csc) {\n"
-    "    csc = itu_601;\n"
-    "    return csc == itu_601;\n"
-    "}\n"
-    "bool is_itu_709(yuvCscStandardEXT csc) {\n"
-    "    return csc == itu_709;\n"
-    "}\n"
-    "void main() { \n"
-    "    yuvCscStandardEXT conv = conv_standard();\n"
-    "    bool csc_check1 = is_itu_601(conv);\n"
-    "    bool csc_check2 = is_itu_709(itu_709);\n"
-    "}\n";
+    R"(precision mediump float;
+    yuvCscStandardEXT;
+    yuvCscStandardEXT conv;
+    yuvCscStandardEXT conv1 = itu_601;
+    yuvCscStandardEXT conv2 = itu_601_full_range;
+    yuvCscStandardEXT conv3 = itu_709;
+    const yuvCscStandardEXT conv4 = itu_709;
+
+    uniform int u;
+    out vec4 my_color;
+
+    yuvCscStandardEXT conv_standard()
+    {
+        switch(u)
+        {
+            case 1:
+                return conv1;
+            case 2:
+                return conv2;
+            case 3:
+                return conv3;
+            default:
+                return conv;
+        }
+    }
+    bool is_itu_601(inout yuvCscStandardEXT csc)
+    {
+        csc = itu_601;
+        return csc == itu_601;
+    }
+    bool is_itu_709(yuvCscStandardEXT csc)
+    {
+        return csc == itu_709;
+    }
+    void main()
+    {
+        yuvCscStandardEXT conv = conv_standard();
+        bool csc_check1 = is_itu_601(conv);
+        bool csc_check2 = is_itu_709(itu_709);
+        if (csc_check1 && csc_check2) {
+            my_color = vec4(0, 1, 0, 1);
+        }
+    })";
 
 // Shader that specifies yuvCscStandartEXT type constructor fails to compile.
 const char ESSL300_YuvCscStandartdEXTConstructFailureShader1[] =
     "precision mediump float;\n"
     "yuvCscStandardEXT conv = yuvCscStandardEXT();\n"
     "void main() { \n"
     "}\n";
 
@@ -182,22 +203,27 @@ const char ESSL300_YuvCscStandartdEXTQua
 const char ESSL300_YuvCscStandartdEXTQualifiersFailureShader3[] =
     "precision mediump float;\n"
     "uniform yuvCscStandardEXT conv = itu_601;\n"
     "void main() { \n"
     "}\n";
 
 // Shader that specifies yuv_to_rgb() and rgb_to_yuv() built-in functions.
 const char ESSL300_BuiltInFunctionsShader[] =
-    "precision mediump float;\n"
-    "yuvCscStandardEXT conv = itu_601;\n"
-    "void main() { \n"
-    "    vec3 yuv = rgb_2_yuv(vec3(0.0f), conv);\n"
-    "    vec3 rgb = yuv_2_rgb(yuv, itu_601);\n"
-    "}\n";
+    R"(precision mediump float;
+    yuvCscStandardEXT conv = itu_601;
+
+    out vec4 my_color;
+
+    void main()
+    {
+        vec3 yuv = rgb_2_yuv(vec3(0.0f), conv);
+        vec3 rgb = yuv_2_rgb(yuv, itu_601);
+        my_color = vec4(rgb, 1.0);
+    })";
 
 class EXTYUVTargetTest : public testing::TestWithParam<testing::tuple<const char *, const char *>>
 {
   protected:
     virtual void SetUp()
     {
         sh::InitBuiltInResources(&mResources);
         mResources.EXT_YUV_target = 1;
new file mode 100644
--- /dev/null
+++ b/gfx/angle/src/tests/compiler_tests/ExtensionDirective_test.cpp
@@ -0,0 +1,178 @@
+//
+// 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.
+//
+// ExtensionDirective_test.cpp:
+//   Miscellaneous tests for extension directives toggling functionality correctly.
+//
+
+#include "GLSLANG/ShaderLang.h"
+#include "angle_gl.h"
+#include "compiler/translator/ExtensionBehavior.h"
+#include "gtest/gtest.h"
+#include "tests/test_utils/ShaderCompileTreeTest.h"
+
+using namespace sh;
+
+class FragmentShaderExtensionDirectiveTest : public ShaderCompileTreeTest
+{
+  public:
+    FragmentShaderExtensionDirectiveTest() {}
+
+  protected:
+    ::GLenum getShaderType() const override { return GL_FRAGMENT_SHADER; }
+    ShShaderSpec getShaderSpec() const override { return SH_GLES3_1_SPEC; }
+
+    void testCompileNeedsExtensionDirective(const std::string &shader, const std::string &extension)
+    {
+        testCompileNeedsExtensionDirective(shader, extension, "");
+    }
+
+    void testCompileNeedsExtensionDirective(const std::string &shader,
+                                            const std::string &extension,
+                                            const std::string &versionDirective)
+    {
+        if (compile(versionDirective + shader))
+        {
+            FAIL()
+                << "Shader compilation without extension directive succeeded, expecting failure:\n"
+                << mInfoLog;
+        }
+        if (compile(versionDirective + getExtensionDirective(extension, sh::EBhDisable) + shader))
+        {
+            FAIL() << "Shader compilation with extension disable directive succeeded, expecting "
+                      "failure:\n"
+                   << mInfoLog;
+        }
+        if (!compile(versionDirective + getExtensionDirective(extension, sh::EBhEnable) + shader))
+        {
+            FAIL()
+                << "Shader compilation with extension enable directive failed, expecting success:\n"
+                << mInfoLog;
+        }
+
+        if (!compile(versionDirective + getExtensionDirective(extension, sh::EBhWarn) + shader))
+        {
+            FAIL()
+                << "Shader compilation with extension warn directive failed, expecting success:\n"
+                << mInfoLog;
+        }
+        else if (!hasWarning())
+        {
+            FAIL() << "Expected compilation to succeed with warning, but warning not present:\n"
+                   << mInfoLog;
+        }
+    }
+
+  private:
+    std::string getExtensionDirective(const std::string &extension, sh::TBehavior behavior)
+    {
+        std::string extensionDirective("#extension ");
+        extensionDirective += extension + " : ";
+        switch (behavior)
+        {
+            case EBhRequire:
+                extensionDirective += "require";
+                break;
+            case EBhEnable:
+                extensionDirective += "enable";
+                break;
+            case EBhWarn:
+                extensionDirective += "warn";
+                break;
+            case EBhDisable:
+                extensionDirective += "disable";
+                break;
+            default:
+                break;
+        }
+        extensionDirective += "\n";
+        return extensionDirective;
+    }
+};
+
+class OESEGLImageExternalTest : public FragmentShaderExtensionDirectiveTest
+{
+  public:
+    OESEGLImageExternalTest() {}
+
+  protected:
+    void initResources(ShBuiltInResources *resources) override
+    {
+        resources->OES_EGL_image_external = 1;
+    }
+};
+
+// OES_EGL_image_external needs to be enabled in GLSL to be able to use samplerExternalOES.
+TEST_F(OESEGLImageExternalTest, SamplerExternalOESUsageNeedsExtensionDirective)
+{
+    const std::string &shaderString =
+        R"(
+        precision mediump float;
+
+        uniform samplerExternalOES s;
+        void main()
+        {})";
+    testCompileNeedsExtensionDirective(shaderString, "GL_OES_EGL_image_external");
+}
+
+class NVEGLStreamConsumerExternalTest : public FragmentShaderExtensionDirectiveTest
+{
+  public:
+    NVEGLStreamConsumerExternalTest() {}
+
+  protected:
+    void initResources(ShBuiltInResources *resources) override
+    {
+        resources->NV_EGL_stream_consumer_external = 1;
+    }
+};
+
+// NV_EGL_stream_consumer_external needs to be enabled in GLSL to be able to use samplerExternalOES.
+TEST_F(NVEGLStreamConsumerExternalTest, SamplerExternalOESUsageNeedsExtensionDirective)
+{
+    const std::string &shaderString =
+        R"(
+        precision mediump float;
+
+        uniform samplerExternalOES s;
+        void main()
+        {})";
+    testCompileNeedsExtensionDirective(shaderString, "GL_NV_EGL_stream_consumer_external");
+}
+
+class EXTYUVTargetTest : public FragmentShaderExtensionDirectiveTest
+{
+  public:
+    EXTYUVTargetTest() {}
+
+  protected:
+    void initResources(ShBuiltInResources *resources) override { resources->EXT_YUV_target = 1; }
+};
+
+// GL_EXT_YUV_target needs to be enabled in GLSL to be able to use samplerExternal2DY2YEXT.
+TEST_F(EXTYUVTargetTest, SamplerExternal2DY2YEXTUsageNeedsExtensionDirective)
+{
+    const std::string &shaderString =
+        R"(
+        precision mediump float;
+
+        uniform __samplerExternal2DY2YEXT s;
+        void main()
+        {})";
+    testCompileNeedsExtensionDirective(shaderString, "GL_EXT_YUV_target", "#version 300 es\n");
+}
+
+// GL_EXT_YUV_target needs to be enabled in GLSL to be able to use samplerExternal2DY2YEXT.
+TEST_F(EXTYUVTargetTest, YUVLayoutNeedsExtensionDirective)
+{
+    const std::string &shaderString =
+        R"(
+        precision mediump float;
+
+        layout(yuv) out vec4 color;
+        void main()
+        {})";
+    testCompileNeedsExtensionDirective(shaderString, "GL_EXT_YUV_target", "#version 300 es\n");
+}
--- a/gfx/angle/src/tests/compiler_tests/GeometryShader_test.cpp
+++ b/gfx/angle/src/tests/compiler_tests/GeometryShader_test.cpp
@@ -7,48 +7,35 @@
 // tests for compiling a Geometry Shader
 //
 
 #include "GLSLANG/ShaderLang.h"
 #include "angle_gl.h"
 #include "compiler/translator/BaseTypes.h"
 #include "compiler/translator/TranslatorESSL.h"
 #include "gtest/gtest.h"
+#include "tests/test_utils/ShaderCompileTreeTest.h"
 #include "tests/test_utils/compiler_test.h"
 
 using namespace sh;
 
-class GeometryShaderTest : public testing::Test
+class GeometryShaderTest : public ShaderCompileTreeTest
 {
   public:
     GeometryShaderTest() {}
 
   protected:
-    void SetUp() override
+    void initResources(ShBuiltInResources *resources) override
     {
-        ShBuiltInResources resources;
-        InitBuiltInResources(&resources);
-        resources.OES_geometry_shader = 1;
-
-        mTranslator = new TranslatorESSL(GL_GEOMETRY_SHADER_OES, SH_GLES3_1_SPEC);
-        ASSERT_TRUE(mTranslator->Init(resources));
+        resources->EXT_geometry_shader = 1;
     }
 
-    void TearDown() override { SafeDelete(mTranslator); }
+    ::GLenum getShaderType() const override { return GL_GEOMETRY_SHADER_EXT; }
 
-    // Return true when compilation succeeds
-    bool compile(const std::string &shaderString)
-    {
-        const char *shaderStrings[] = {shaderString.c_str()};
-
-        bool status         = mTranslator->compile(shaderStrings, 1, SH_OBJECT_CODE | SH_VARIABLES);
-        TInfoSink &infoSink = mTranslator->getInfoSink();
-        mInfoLog            = infoSink.info.c_str();
-        return status;
-    }
+    ShShaderSpec getShaderSpec() const override { return SH_GLES3_1_SPEC; }
 
     bool compileGeometryShader(const std::string &statement1, const std::string &statement2)
     {
         std::ostringstream sstream;
         sstream << kHeader << statement1 << statement2 << kEmptyBody;
         return compile(sstream.str());
     }
 
@@ -82,94 +69,128 @@ class GeometryShaderTest : public testin
         {
             sstream << ", max_vertices = " << maxVertices;
         }
         sstream << ") " << layoutType << ";" << std::endl;
 
         return sstream.str();
     }
 
+    static std::string GetInputDeclaration(const std::string &var, int size)
+    {
+        std::ostringstream sstream;
+
+        sstream << "in ";
+        if (size < 0)
+        {
+            sstream << var << "[];\n";
+        }
+        else
+        {
+            sstream << var << "[" << size << "];\n";
+        }
+
+        return sstream.str();
+    }
+
+    const std::string kVersion = "#version 310 es\n";
     const std::string kHeader =
         "#version 310 es\n"
-        "#extension GL_OES_geometry_shader : require\n";
+        "#extension GL_EXT_geometry_shader : require\n";
+    const std::string kInputLayout  = "layout (points) in;\n";
+    const std::string kOutputLayout = "layout (points, max_vertices = 1) out;\n";
+
+    const std::array<std::string, 4> kInterpolationQualifiers = {{"flat", "smooth", "centroid"}};
+    const std::map<std::string, int> kInputPrimitivesAndInputArraySizeMap = {
+        {"points", 1},
+        {"lines", 2},
+        {"lines_adjacency", 4},
+        {"triangles", 3},
+        {"triangles_adjacency", 6}};
+
     const std::string kEmptyBody =
         "void main()\n"
         "{\n"
         "}\n";
-    const std::string kInputLayout  = "layout (points) in;\n";
-    const std::string kOutputLayout = "layout (points, max_vertices = 1) out;\n";
+};
 
-    std::string mInfoLog;
-    TranslatorESSL *mTranslator = nullptr;
+class GeometryShaderOutputCodeTest : public MatchOutputCodeTest
+{
+  public:
+    GeometryShaderOutputCodeTest()
+        : MatchOutputCodeTest(GL_GEOMETRY_SHADER_EXT, SH_OBJECT_CODE, SH_ESSL_OUTPUT)
+    {
+        getResources()->EXT_geometry_shader = 1;
+    }
 };
 
 // Geometry Shaders are not supported in GLSL ES shaders version lower than 310.
 TEST_F(GeometryShaderTest, Version300)
 {
     const std::string &shaderString =
-        "#version 300 es\n"
-        "layout(points) in;\n"
-        "layout(points, max_vertices = 1) out;\n"
-        "void main()\n"
-        "{\n"
-        "}\n";
+        R"(#version 300 es
+        layout(points) in;
+        layout(points, max_vertices = 1) out;
+        void main()
+        {
+        })";
 
     if (compile(shaderString))
     {
         FAIL() << "Shader compilation succeeded, expecting failure:\n" << mInfoLog;
     }
 }
 
 // Geometry Shaders are not supported in GLSL ES shaders version 310 without extension
-// OES_geometry_shader enabled.
+// EXT_geometry_shader enabled.
 TEST_F(GeometryShaderTest, Version310WithoutExtension)
 {
     const std::string &shaderString =
-        "#version 310 es\n"
-        "layout(points) in;\n"
-        "layout(points, max_vertices = 1) out;\n"
-        "void main()\n"
-        "{\n"
-        "}\n";
+        R"(#version 310 es
+        layout(points) in;
+        layout(points, max_vertices = 1) out;
+        void main()
+        {
+        })";
 
     if (compile(shaderString))
     {
         FAIL() << "Shader compilation succeeded, expecting failure:\n" << mInfoLog;
     }
 }
 
-// Geometry Shaders are supported in GLSL ES shaders version 310 with OES_geometry_shader enabled.
+// Geometry Shaders are supported in GLSL ES shaders version 310 with EXT_geometry_shader enabled.
 TEST_F(GeometryShaderTest, Version310WithOESExtension)
 {
     const std::string &shaderString =
-        "#version 310 es\n"
-        "#extension GL_OES_geometry_shader : require\n"
-        "layout(points) in;\n"
-        "layout(points, max_vertices = 1) out;\n"
-        "void main()\n"
-        "{\n"
-        "}\n";
+        R"(#version 310 es
+        #extension GL_EXT_geometry_shader : require
+        layout(points) in;
+        layout(points, max_vertices = 1) out;
+        void main()
+        {
+        })";
 
     if (!compile(shaderString))
     {
         FAIL() << "Shader compilation failed, expecting success:\n" << mInfoLog;
     }
 }
 
 // Missing the declaration of input primitive in a geometry shader should be a link error instead of
 // a compile error.
 TEST_F(GeometryShaderTest, NoInputPrimitives)
 {
     const std::string &shaderString =
-        "#version 310 es\n"
-        "#extension GL_OES_geometry_shader : require\n"
-        "layout(points, max_vertices = 1) out;\n"
-        "void main()\n"
-        "{\n"
-        "}\n";
+        R"(#version 310 es
+        #extension GL_EXT_geometry_shader : require
+        layout(points, max_vertices = 1) out;
+        void main()
+        {
+        })";
 
     if (!compile(shaderString))
     {
         FAIL() << "Shader compilation failed, expecting success:\n" << mInfoLog;
     }
 }
 
 // Geometry Shaders can only support 5 kinds of input primitives, which cannot be used as output
@@ -221,322 +242,322 @@ TEST_F(GeometryShaderTest, RedeclareInpu
         }
     }
 }
 
 // Geometry Shaders don't allow declaring different input primitives in one layout.
 TEST_F(GeometryShaderTest, DeclareDifferentInputPrimitivesInOneLayout)
 {
     const std::string &shaderString =
-        "#version 310 es\n"
-        "#extension GL_OES_geometry_shader : require\n"
-        "layout (points, triangles) in;\n"
-        "layout (points, max_vertices = 1) out;\n"
-        "void main()\n"
-        "{\n"
-        "}\n";
+        R"(#version 310 es
+        #extension GL_EXT_geometry_shader : require
+        layout (points, triangles) in;
+        layout (points, max_vertices = 1) out;
+        void main()
+        {
+        })";
 
     if (compile(shaderString))
     {
         FAIL() << "Shader compilation succeeded, expecting failure:\n" << mInfoLog;
     }
 }
 
 // Geometry Shaders don't allow 'invocations' < 1.
 TEST_F(GeometryShaderTest, InvocationsLessThanOne)
 {
     const std::string &shaderString =
-        "#version 310 es\n"
-        "#extension GL_OES_geometry_shader : require\n"
-        "layout (points, invocations = 0) in;\n"
-        "layout (points, max_vertices = 1) out;\n"
-        "void main()\n"
-        "{\n"
-        "}\n";
+        R"(#version 310 es
+        #extension GL_EXT_geometry_shader : require
+        layout (points, invocations = 0) in;
+        layout (points, max_vertices = 1) out;
+        void main()
+        {
+        })";
 
     if (compile(shaderString))
     {
         FAIL() << "Shader compilation succeeded, expecting failure:\n" << mInfoLog;
     }
 }
 
 // Geometry Shaders allow declaring 'invocations' == 1 together with input primitive declaration in
 // one layout.
 TEST_F(GeometryShaderTest, InvocationsEqualsOne)
 {
     const std::string &shaderString =
-        "#version 310 es\n"
-        "#extension GL_OES_geometry_shader : require\n"
-        "layout (points, invocations = 1) in;\n"
-        "layout (points, max_vertices = 1) out;\n"
-        "void main()\n"
-        "{\n"
-        "}\n";
+        R"(#version 310 es
+        #extension GL_EXT_geometry_shader : require
+        layout (points, invocations = 1) in;
+        layout (points, max_vertices = 1) out;
+        void main()
+        {
+        })";
 
     if (!compile(shaderString))
     {
         FAIL() << "Shader compilation failed, expecting success:\n" << mInfoLog;
     }
 }
 
 // Geometry Shaders allow declaring 'invocations' == 1 in an individual layout.
 TEST_F(GeometryShaderTest, InvocationsEqualsOneInSeparatedLayout)
 {
     const std::string &shaderString =
-        "#version 310 es\n"
-        "#extension GL_OES_geometry_shader : require\n"
-        "layout (points) in;\n"
-        "layout (invocations = 1) in;\n"
-        "layout (points, max_vertices = 1) out;\n"
-        "void main()\n"
-        "{\n"
-        "}\n";
+        R"(#version 310 es
+        #extension GL_EXT_geometry_shader : require
+        layout (points) in;
+        layout (invocations = 1) in;
+        layout (points, max_vertices = 1) out;
+        void main()
+        {
+        })";
 
     if (!compile(shaderString))
     {
         FAIL() << "Shader compilation failed, expecting success:\n" << mInfoLog;
     }
 }
 
 // Geometry Shaders don't allow 'invocations' larger than the implementation-dependent maximum value
 // (32 in this test).
 TEST_F(GeometryShaderTest, TooLargeInvocations)
 {
     const std::string &shaderString =
-        "#version 310 es\n"
-        "#extension GL_OES_geometry_shader : require\n"
-        "layout (points, invocations = 9989899) in;\n"
-        "layout (points, max_vertices = 1) out;\n"
-        "void main()\n"
-        "{\n"
-        "}\n";
+        R"(#version 310 es
+        #extension GL_EXT_geometry_shader : require
+        layout (points, invocations = 9989899) in;
+        layout (points, max_vertices = 1) out;
+        void main()
+        {
+        })";
 
     if (compile(shaderString))
     {
         FAIL() << "Shader compilation succeeded, expecting failure:\n" << mInfoLog;
     }
 }
 
 // Geometry Shaders allow 'invocations' declared together with input primitives in one layout.
 TEST_F(GeometryShaderTest, InvocationsDeclaredWithInputPrimitives)
 {
     const std::string &shaderString =
-        "#version 310 es\n"
-        "#extension GL_OES_geometry_shader : require\n"
-        "layout (points, invocations = 3) in;\n"
-        "layout (points, max_vertices = 1) out;\n"
-        "void main()\n"
-        "{\n"
-        "}\n";
+        R"(#version 310 es
+        #extension GL_EXT_geometry_shader : require
+        layout (points, invocations = 3) in;
+        layout (points, max_vertices = 1) out;
+        void main()
+        {
+        })";
 
     if (!compile(shaderString))
     {
         FAIL() << "Shader compilation failed, expecting success:\n" << mInfoLog;
     }
 }
 
 // Geometry Shaders allow 'invocations' declared before input primitives in one input layout.
 TEST_F(GeometryShaderTest, InvocationsBeforeInputPrimitives)
 {
     const std::string &shaderString =
-        "#version 310 es\n"
-        "#extension GL_OES_geometry_shader : require\n"
-        "layout (invocations = 3, points) in;\n"
-        "layout (points, max_vertices = 1) out;\n"
-        "void main()\n"
-        "{\n"
-        "}\n";
+        R"(#version 310 es
+        #extension GL_EXT_geometry_shader : require
+        layout (invocations = 3, points) in;
+        layout (points, max_vertices = 1) out;
+        void main()
+        {
+        })";
 
     if (!compile(shaderString))
     {
         FAIL() << "Shader compilation failed, expecting success:\n" << mInfoLog;
     }
 }
 
 // Geometry Shaders allow 'invocations' declared in an individual input layout.
 TEST_F(GeometryShaderTest, InvocationsInIndividualLayout)
 {
     const std::string &shaderString =
-        "#version 310 es\n"
-        "#extension GL_OES_geometry_shader : require\n"
-        "layout (points) in;\n"
-        "layout (invocations = 3) in;\n"
-        "layout (points, max_vertices = 1) out;\n"
-        "void main()\n"
-        "{\n"
-        "}\n";
+        R"(#version 310 es
+        #extension GL_EXT_geometry_shader : require
+        layout (points) in;
+        layout (invocations = 3) in;
+        layout (points, max_vertices = 1) out;
+        void main()
+        {
+        })";
 
     if (!compile(shaderString))
     {
         FAIL() << "Shader compilation failed, expecting success:\n" << mInfoLog;
     }
 }
 
 // Geometry Shaders allow duplicated 'invocations' declarations.
 TEST_F(GeometryShaderTest, DuplicatedInvocations)
 {
     const std::string &shaderString =
-        "#version 310 es\n"
-        "#extension GL_OES_geometry_shader : require\n"
-        "layout (points, invocations = 3) in;\n"
-        "layout (invocations = 3) in;\n"
-        "layout (points, max_vertices = 1) out;\n"
-        "void main()\n"
-        "{\n"
-        "}\n";
+        R"(#version 310 es
+        #extension GL_EXT_geometry_shader : require
+        layout (points, invocations = 3) in;
+        layout (invocations = 3) in;
+        layout (points, max_vertices = 1) out;
+        void main()
+        {
+        })";
 
     if (!compile(shaderString))
     {
         FAIL() << "Shader compilation failed, expecting success:\n" << mInfoLog;
     }
 }
 
 // Geometry Shaders don't allow multiple different 'invocations' declarations in different
 // layouts.
 TEST_F(GeometryShaderTest, RedeclareDifferentInvocations)
 {
     const std::string &shaderString =
-        "#version 310 es\n"
-        "#extension GL_OES_geometry_shader : require\n"
-        "layout (points, invocations = 3) in;\n"
-        "layout (invocations = 5) in;\n"
-        "layout (points, max_vertices = 1) out;\n"
-        "void main()\n"
-        "{\n"
-        "}\n";
+        R"(#version 310 es
+        #extension GL_EXT_geometry_shader : require
+        layout (points, invocations = 3) in;
+        layout (invocations = 5) in;
+        layout (points, max_vertices = 1) out;
+        void main()
+        {
+        })";
 
     if (compile(shaderString))
     {
         FAIL() << "Shader compilation succeeded, expecting failure:\n" << mInfoLog;
     }
 }
 
 // Geometry Shaders don't allow multiple different 'invocations' declarations in different
 // layouts.
 TEST_F(GeometryShaderTest, RedeclareDifferentInvocationsAfterInvocationEqualsOne)
 {
     const std::string &shaderString =
-        "#version 310 es\n"
-        "#extension GL_OES_geometry_shader : require\n"
-        "layout (points, invocations = 1) in;\n"
-        "layout (invocations = 5) in;\n"
-        "layout (points, max_vertices = 1) out;\n"
-        "void main()\n"
-        "{\n"
-        "}\n";
+        R"(#version 310 es
+        #extension GL_EXT_geometry_shader : require
+        layout (points, invocations = 1) in;
+        layout (invocations = 5) in;
+        layout (points, max_vertices = 1) out;
+        void main()
+        {
+        })";
 
     if (compile(shaderString))
     {
         FAIL() << "Shader compilation succeeded, expecting failure:\n" << mInfoLog;
     }
 }
 
 // Geometry Shaders don't allow multiple different 'invocations' declarations in one layout.
 TEST_F(GeometryShaderTest, RedeclareDifferentInvocationsInOneLayout)
 {
     const std::string &shaderString =
-        "#version 310 es\n"
-        "#extension GL_OES_geometry_shader : require\n"
-        "layout (points, invocations = 3, invocations = 5) in;\n"
-        "layout (points, max_vertices = 1) out;\n"
-        "void main()\n"
-        "{\n"
-        "}\n";
+        R"(#version 310 es
+        #extension GL_EXT_geometry_shader : require
+        layout (points, invocations = 3, invocations = 5) in;
+        layout (points, max_vertices = 1) out;
+        void main()
+        {
+        })";
 
     if (compile(shaderString))
     {
         FAIL() << "Shader compilation succeeded, expecting failure:\n" << mInfoLog;
     }
 }
 
 // Geometry Shaders don't allow 'invocations' in out layouts.
 TEST_F(GeometryShaderTest, DeclareInvocationsInOutLayout)
 {
     const std::string &shaderString =
-        "#version 310 es\n"
-        "#extension GL_OES_geometry_shader : require\n"
-        "layout (points) in;\n"
-        "layout (points, invocations = 3, max_vertices = 1) out;\n"
-        "void main()\n"
-        "{\n"
-        "}\n";
+        R"(#version 310 es
+        #extension GL_EXT_geometry_shader : require
+        layout (points) in;
+        layout (points, invocations = 3, max_vertices = 1) out;
+        void main()
+        {
+        })";
 
     if (compile(shaderString))
     {
         FAIL() << "Shader compilation succeeded, expecting failure:\n" << mInfoLog;
     }
 }
 
 // Geometry Shaders don't allow 'invocations' in layouts without 'in' qualifier.
 TEST_F(GeometryShaderTest, DeclareInvocationsInLayoutNoQualifier)
 {
     const std::string &shaderString =
-        "#version 310 es\n"
-        "#extension GL_OES_geometry_shader : require\n"
-        "layout (points) in;\n"
-        "layout (invocations = 3);\n"
-        "layout (points, max_vertices = 1) out;\n"
-        "void main()\n"
-        "{\n"
-        "}\n";
+        R"(#version 310 es
+        #extension GL_EXT_geometry_shader : require
+        layout (points) in;
+        layout (invocations = 3);
+        layout (points, max_vertices = 1) out;
+        void main()
+        {
+        })";
 
     if (compile(shaderString))
     {
         FAIL() << "Shader compilation succeeded, expecting failure:\n" << mInfoLog;
     }
 }
 
 // Geometry Shaders allow declaring output primitive before input primitive declaration.
 TEST_F(GeometryShaderTest, DeclareOutputPrimitiveBeforeInputPrimitiveDeclare)
 {
     const std::string &shaderString =
-        "#version 310 es\n"
-        "#extension GL_OES_geometry_shader : require\n"
-        "layout (points, max_vertices = 1) out;\n"
-        "layout (points) in;\n"
-        "void main()\n"
-        "{\n"
-        "}\n";
+        R"(#version 310 es
+        #extension GL_EXT_geometry_shader : require
+        layout (points, max_vertices = 1) out;
+        layout (points) in;
+        void main()
+        {
+        })";
 
     if (!compile(shaderString))
     {
         FAIL() << "Shader compilation failed, expecting success:\n" << mInfoLog;
     }
 }
 
 // Geometry Shaders allow declaring 'max_vertices' before output primitive in one output layout.
 TEST_F(GeometryShaderTest, DeclareMaxVerticesBeforeOutputPrimitive)
 {
     const std::string &shaderString =
-        "#version 310 es\n"
-        "#extension GL_OES_geometry_shader : require\n"
-        "layout (points) in;\n"
-        "layout (max_vertices = 1, points) out;\n"
-        "void main()\n"
-        "{\n"
-        "}\n";
+        R"(#version 310 es
+        #extension GL_EXT_geometry_shader : require
+        layout (points) in;
+        layout (max_vertices = 1, points) out;
+        void main()
+        {
+        })";
 
     if (!compile(shaderString))
     {
         FAIL() << "Shader compilation failed, expecting success:\n" << mInfoLog;
     }
 }
 
 // Missing the declaration of output primitive should be a link error instead of a compile error in
 // a geometry shader.
 TEST_F(GeometryShaderTest, NoOutputPrimitives)
 {
     const std::string &shaderString =
-        "#version 310 es\n"
-        "#extension GL_OES_geometry_shader : require\n"
-        "layout (points) in;\n"
-        "layout (max_vertices = 1) out;\n"
-        "void main()\n"
-        "{\n"
-        "}\n";
+        R"(#version 310 es
+        #extension GL_EXT_geometry_shader : require
+        layout (points) in;
+        layout (max_vertices = 1) out;
+        void main()
+        {
+        })";
 
     if (!compile(shaderString))
     {
         FAIL() << "Shader compilation failed, expecting success:\n" << mInfoLog;
     }
 }
 
 // Geometry Shaders can only support 3 kinds of output primitives, which cannot be used as input
@@ -589,547 +610,550 @@ TEST_F(GeometryShaderTest, RedeclareOutp
         }
     }
 }
 
 // Geometry Shaders don't allow declaring different output primitives in one layout.
 TEST_F(GeometryShaderTest, RedeclareDifferentOutputPrimitivesInOneLayout)
 {
     const std::string &shaderString =
-        "#version 310 es\n"
-        "#extension GL_OES_geometry_shader : require\n"
-        "layout (points) in;\n"
-        "layout (points, max_vertices = 3, line_strip) out;\n"
-        "void main()\n"
-        "{\n"
-        "}\n";
+        R"(#version 310 es
+        #extension GL_EXT_geometry_shader : require
+        layout (points) in;
+        layout (points, max_vertices = 3, line_strip) out;
+        void main()
+        {
+        })";
 
     if (compile(shaderString))
     {
         FAIL() << "Shader compilation succeeded, expecting failure:\n" << mInfoLog;
     }
 }
 
 // Missing the declarations of output primitives and 'max_vertices' in a geometry shader should
 // be a link error instead of a compile error.
 TEST_F(GeometryShaderTest, NoOutLayouts)
 {
     const std::string &shaderString =
-        "#version 310 es\n"
-        "#extension GL_OES_geometry_shader : require\n"
-        "layout (points) in;\n"
-        "void main()\n"
-        "{\n"
-        "}\n";
+        R"(#version 310 es
+        #extension GL_EXT_geometry_shader : require
+        layout (points) in;
+        void main()
+        {
+        })";
 
     if (!compile(shaderString))
     {
         FAIL() << "Shader compilation failed, expecting success:\n" << mInfoLog;
     }
 }
 
 // Missing the declarations of 'max_vertices' in a geometry shader should be a link error
 // instead of a compile error.
 TEST_F(GeometryShaderTest, NoMaxVertices)
 {
     const std::string &shaderString =
-        "#version 310 es\n"
-        "#extension GL_OES_geometry_shader : require\n"
-        "layout (points) in;\n"
-        "layout (points) out;\n"
-        "void main()\n"
-        "{\n"
-        "}\n";
+        R"(#version 310 es
+        #extension GL_EXT_geometry_shader : require
+        layout (points) in;
+        layout (points) out;
+        void main()
+        {
+        })";
 
     if (!compile(shaderString))
     {
         FAIL() << "Shader compilation failed, expecting success:\n" << mInfoLog;
     }
 }
 
 // Geometry Shaders cannot declare a negative 'max_vertices'.
 TEST_F(GeometryShaderTest, NegativeMaxVertices)
 {
     const std::string &shaderString =
-        "#version 310 es\n"
-        "#extension GL_OES_geometry_shader : require\n"
-        "layout (points) in;\n"
-        "layout (points, max_vertices = -1) out;\n"
-        "void main()\n"
-        "{\n"
-        "}\n";
+        R"(#version 310 es
+        #extension GL_EXT_geometry_shader : require
+        layout (points) in;
+        layout (points, max_vertices = -1) out;
+        void main()
+        {
+        })";
 
     if (compile(shaderString))
     {
         FAIL() << "Shader compilation succeeded, expecting failure:\n" << mInfoLog;
     }
 }
 
 // Geometry Shaders allow max_vertices == 0.
 TEST_F(GeometryShaderTest, ZeroMaxVertices)
 {
     const std::string &shaderString =
-        "#version 310 es\n"
-        "#extension GL_OES_geometry_shader : require\n"
-        "layout (points) in;\n"
-        "layout (points, max_vertices = 0) out;\n"
-        "void main()\n"
-        "{\n"
-        "}\n";
+        R"(#version 310 es
+        #extension GL_EXT_geometry_shader : require
+        layout (points) in;
+        layout (points, max_vertices = 0) out;
+        void main()
+        {
+        })";
 
     if (!compile(shaderString))
     {
         FAIL() << "Shader compilation failed, expecting success:\n" << mInfoLog;
     }
 }
 
 // Geometry Shaders cannot declare a 'max_vertices' that is greater than
 // MAX_GEOMETRY_OUTPUT_VERTICES_EXT (256 in this test).
 TEST_F(GeometryShaderTest, TooLargeMaxVertices)
 {
     const std::string &shaderString =
-        "#version 310 es\n"
-        "#extension GL_OES_geometry_shader : require\n"
-        "layout (points) in;\n"
-        "layout (points, max_vertices = 257) out;\n"
-        "void main()\n"
-        "{\n"
-        "}\n";
+        R"(#version 310 es
+        #extension GL_EXT_geometry_shader : require
+        layout (points) in;
+        layout (points, max_vertices = 257) out;
+        void main()
+        {
+        })";
 
     if (compile(shaderString))
     {
         FAIL() << "Shader compilation succeeded, expecting failure:\n" << mInfoLog;
     }
 }
 
 // Geometry Shaders can declare 'max_vertices' in an individual out layout.
 TEST_F(GeometryShaderTest, MaxVerticesInIndividualLayout)
 {
     const std::string &shaderString =
-        "#version 310 es\n"
-        "#extension GL_OES_geometry_shader : require\n"
-        "layout (points) in;\n"
-        "layout (points) out;\n"
-        "layout (max_vertices = 1) out;\n"
-        "void main()\n"
-        "{\n"
-        "}\n";
+        R"(#version 310 es
+        #extension GL_EXT_geometry_shader : require
+        layout (points) in;
+        layout (points) out;
+        layout (max_vertices = 1) out;
+        void main()
+        {
+        })";
 
     if (!compile(shaderString))
     {
         FAIL() << "Shader compilation failed, expecting success:\n" << mInfoLog;
     }
 }
 
 // Geometry Shaders allow duplicated 'max_vertices' declarations.
 TEST_F(GeometryShaderTest, DuplicatedMaxVertices)
 {
     const std::string &shaderString =
-        "#version 310 es\n"
-        "#extension GL_OES_geometry_shader : require\n"
-        "layout (points) in;\n"
-        "layout (points, max_vertices = 1) out;\n"
-        "layout (max_vertices = 1) out;\n"
-        "void main()\n"
-        "{\n"
-        "}\n";
+        R"(#version 310 es
+        #extension GL_EXT_geometry_shader : require
+        layout (points) in;
+        layout (points, max_vertices = 1) out;
+        layout (max_vertices = 1) out;
+        void main()
+        {
+        })";
 
     if (!compile(shaderString))
     {
         FAIL() << "Shader compilation failed, expecting success:\n" << mInfoLog;
     }
 }
 
 // Geometry Shaders don't allow declaring different 'max_vertices'.
 TEST_F(GeometryShaderTest, RedeclareDifferentMaxVertices)
 {
     const std::string &shaderString =
-        "#version 310 es\n"
-        "#extension GL_OES_geometry_shader : require\n"
-        "layout (points) in;\n"
-        "layout (points, max_vertices = 1) out;\n"
-        "layout (max_vertices = 2) out;\n"
-        "void main()\n"
-        "{\n"
-        "}\n";
+        R"(#version 310 es
+        #extension GL_EXT_geometry_shader : require
+        layout (points) in;
+        layout (points, max_vertices = 1) out;
+        layout (max_vertices = 2) out;
+        void main()
+        {
+        })";
 
     if (compile(shaderString))
     {
         FAIL() << "Shader compilation succeeded, expecting failure:\n" << mInfoLog;
     }
 }
 
 // Geometry Shaders don't allow declaring different 'max_vertices'.
 TEST_F(GeometryShaderTest, RedeclareDifferentMaxVerticesInOneLayout)
 {
     const std::string &shaderString =
-        "#version 310 es\n"
-        "#extension GL_OES_geometry_shader : require\n"
-        "layout (points) in;\n"
-        "layout (points, max_vertices = 2, max_vertices = 1) out;\n"
-        "void main()\n"
-        "{\n"
-        "}\n";
+        R"(#version 310 es
+        #extension GL_EXT_geometry_shader : require
+        layout (points) in;
+        layout (points, max_vertices = 2, max_vertices = 1) out;
+        void main()
+        {
+        })";
 
     if (compile(shaderString))
     {
         FAIL() << "Shader compilation succeeded, expecting failure:\n" << mInfoLog;
     }
 }
 
 // Geometry Shaders don't allow 'location' declared with input/output primitives in one layout.
-TEST_F(GeometryShaderTest, invalidLocation)
+TEST_F(GeometryShaderTest, InvalidLocation)
 {
     const std::string &shaderString1 =
-        "#version 310 es\n"
-        "#extension GL_OES_geometry_shader : require\n"
-        "layout (points, location = 1) in;\n"
-        "layout (points, max_vertices = 2) out;\n"
-        "void main()\n"
-        "{\n"
-        "}\n";
+        R"(#version 310 es
+        #extension GL_EXT_geometry_shader : require
+        layout (points, location = 1) in;
+        layout (points, max_vertices = 2) out;
+        void main()
+        {
+        })";
 
     const std::string &shaderString2 =
-        "#version 310 es\n"
-        "#extension GL_OES_geometry_shader : require\n"
-        "layout (points) in;\n"
-        "layout (invocations = 2, location = 1) in;\n"
-        "layout (points, max_vertices = 2) out;\n"
-        "void main()\n"
-        "{\n"
-        "}\n";
+        R"(#version 310 es
+        #extension GL_EXT_geometry_shader : require
+        layout (points) in;
+        layout (invocations = 2, location = 1) in;
+        layout (points, max_vertices = 2) out;
+        void main()
+        {
+        })";
 
     const std::string &shaderString3 =
-        "#version 310 es\n"
-        "#extension GL_OES_geometry_shader : require\n"
-        "layout (points) in;\n"
-        "layout (points, location = 3, max_vertices = 2) out;\n"
-        "void main()\n"
-        "{\n"
-        "}\n";
+        R"(#version 310 es
+        #extension GL_EXT_geometry_shader : require
+        layout (points) in;
+        layout (points, location = 3, max_vertices = 2) out;
+        void main()
+        {
+        })";
 
     const std::string &shaderString4 =
-        "#version 310 es\n"
-        "#extension GL_OES_geometry_shader : require\n"
-        "layout (points) in;\n"
-        "layout (points) out;\n"
-        "layout (max_vertices = 2, location = 3) out;\n"
-        "void main()\n"
-        "{\n"
-        "}\n";
+        R"(#version 310 es
+        #extension GL_EXT_geometry_shader : require
+        layout (points) in;
+        layout (points) out;
+        layout (max_vertices = 2, location = 3) out;
+        void main()
+        {
+        })";
 
     if (compile(shaderString1) || compile(shaderString2) || compile(shaderString3) ||
         compile(shaderString4))
     {
         FAIL() << "Shader compilation succeeded, expecting failure:\n" << mInfoLog;
     }
 }
 
 // Geometry Shaders don't allow invalid layout qualifier declarations.
-TEST_F(GeometryShaderTest, invalidLayoutQualifiers)
+TEST_F(GeometryShaderTest, InvalidLayoutQualifiers)
 {
     const std::string &shaderString1 =
-        "#version 310 es\n"
-        "#extension GL_OES_geometry_shader : require\n"
-        "layout (points, abc) in;\n"
-        "layout (points, max_vertices = 2) out;\n"
-        "void main()\n"
-        "{\n"
-        "}\n";
+        R"(#version 310 es
+        #extension GL_EXT_geometry_shader : require
+        layout (points, abc) in;
+        layout (points, max_vertices = 2) out;
+        void main()
+        {
+        })";
 
     const std::string &shaderString2 =
-        "#version 310 es\n"
-        "#extension GL_OES_geometry_shader : require\n"
-        "layout (points) in;\n"
-        "layout (points, abc, max_vertices = 2) out;\n"
-        "void main()\n"
-        "{\n"
-        "}\n";
+        R"(#version 310 es
+        #extension GL_EXT_geometry_shader : require
+        layout (points) in;
+        layout (points, abc, max_vertices = 2) out;
+        void main()
+        {
+        })";
 
     const std::string &shaderString3 =
-        "#version 310 es\n"
-        "#extension GL_OES_geometry_shader : require\n"
-        "layout (points, xyz = 2) in;\n"
-        "layout (points, max_vertices = 2) out;\n"
-        "void main()\n"
-        "{\n"
-        "}\n";
+        R"(#version 310 es
+        #extension GL_EXT_geometry_shader : require
+        layout (points, xyz = 2) in;
+        layout (points, max_vertices = 2) out;
+        void main()
+        {
+        })";
 
     const std::string &shaderString4 =
-        "#version 310 es\n"
-        "#extension GL_OES_geometry_shader : require\n"
-        "layout (points) in;\n"
-        "layout (points) out;\n"
-        "layout (max_vertices = 2, xyz = 3) out;\n"
-        "void main()\n"
-        "{\n"
-        "}\n";
+        R"(#version 310 es
+        #extension GL_EXT_geometry_shader : require
+        layout (points) in;
+        layout (points) out;
+        layout (max_vertices = 2, xyz = 3) out;
+        void main()
+        {
+        })";
 
     if (compile(shaderString1) || compile(shaderString2) || compile(shaderString3) ||
         compile(shaderString4))
     {
         FAIL() << "Shader compilation succeeded, expecting failure:\n" << mInfoLog;
     }
 }
 
 // Verify that indexing an array with a constant integer on gl_in is legal.
 TEST_F(GeometryShaderTest, IndexGLInByConstantInteger)
 {
     const std::string &shaderString =
-        "#version 310 es\n"
-        "#extension GL_OES_geometry_shader : require\n"
-        "layout (points) in;\n"
-        "layout (points, max_vertices = 2) out;\n"
-        "void main()\n"
-        "{\n"
-        "    vec4 position;\n"
-        "    position = gl_in[0].gl_Position;\n"
-        "}\n";
+        R"(#version 310 es
+        #extension GL_EXT_geometry_shader : require
+        layout (points) in;
+        layout (points, max_vertices = 2) out;
+        void main()
+        {
+            vec4 position;
+            position = gl_in[0].gl_Position;
+        })";
 
     if (!compile(shaderString))
     {
         FAIL() << "Shader compilation failed, expecting success:\n" << mInfoLog;
     }
 }
 
 // Verify that indexing an array with an integer variable on gl_in is legal.
 TEST_F(GeometryShaderTest, IndexGLInByVariable)
 {
     const std::string &shaderString =
-        "#version 310 es\n"
-        "#extension GL_OES_geometry_shader : require\n"
-        "layout (lines) in;\n"
-        "layout (points, max_vertices = 2) out;\n"
-        "void main()\n"
-        "{\n"
-        "    vec4 position;\n"
-        "    for (int i = 0; i < 2; i++)\n"
-        "    {\n"
-        "        position = gl_in[i].gl_Position;\n"
-        "    }\n"
-        "}\n";
+        R"(#version 310 es
+        #extension GL_EXT_geometry_shader : require
+        layout (lines) in;
+        layout (points, max_vertices = 2) out;
+        void main()
+        {
+            vec4 position;
+            for (int i = 0; i < 2; i++)
+            {
+                position = gl_in[i].gl_Position;
+            }
+        })";
 
     if (!compile(shaderString))
     {
         FAIL() << "Shader compilation failed, expecting success:\n" << mInfoLog;
     }
 }
 
 // Verify that indexing an array on gl_in without input primitive declaration causes a compile
 // error.
 TEST_F(GeometryShaderTest, IndexGLInWithoutInputPrimitive)
 {
     const std::string &shaderString =
-        "#version 310 es\n"
-        "#extension GL_OES_geometry_shader : require\n"
-        "layout (points, max_vertices = 2) out;\n"
-        "void main()\n"
-        "{\n"
-        "    vec4 position = gl_in[0].gl_Position;\n"
-        "}\n";
+        R"(#version 310 es
+        #extension GL_EXT_geometry_shader : require
+        layout (points, max_vertices = 2) out;
+        void main()
+        {
+            vec4 position = gl_in[0].gl_Position;
+        })";
 
     if (compile(shaderString))
     {
         FAIL() << "Shader compilation succeeded, expecting failure:\n" << mInfoLog;
     }
 }
 
 // Verify that using gl_in.length() without input primitive declaration causes a compile error.
 TEST_F(GeometryShaderTest, UseGLInLengthWithoutInputPrimitive)
 {
     const std::string &shaderString =
-        "#version 310 es\n"
-        "#extension GL_OES_geometry_shader : require\n"
-        "layout (points, max_vertices = 2) out;\n"
-        "void main()\n"
-        "{\n"
-        "    int length = gl_in.length();\n"
-        "}\n";
+        R"(#version 310 es
+        #extension GL_EXT_geometry_shader : require
+        layout (points, max_vertices = 2) out;
+        void main()
+        {
+            int length = gl_in.length();
+        })";
 
     if (compile(shaderString))
     {
         FAIL() << "Shader compilation succeeded, expecting failure:\n" << mInfoLog;
     }
 }
 
 // Verify that using gl_in.length() with input primitive declaration can compile.
 TEST_F(GeometryShaderTest, UseGLInLengthWithInputPrimitive)
 {
     const std::string &shaderString =
-        "#version 310 es\n"
-        "#extension GL_OES_geometry_shader : require\n"
-        "layout (points) in;\n"
-        "layout (points, max_vertices = 2) out;\n"
-        "void main()\n"
-        "{\n"
-        "    int length = gl_in.length();\n"
-        "}\n";
+        R"(#version 310 es
+        #extension GL_EXT_geometry_shader : require
+        layout (points) in;
+        layout (points, max_vertices = 2) out;
+        void main()
+        {
+            gl_Position = vec4(gl_in.length());
+            EmitVertex();
+        })";
 
     if (!compile(shaderString))
     {
         FAIL() << "Shader compilation failed, expecting success:\n" << mInfoLog;
     }
 }
 
 // Verify that gl_in[].gl_Position cannot be l-value.
 TEST_F(GeometryShaderTest, AssignValueToGLIn)
 {
     const std::string &shaderString =
-        "#version 310 es\n"
-        "#extension GL_OES_geometry_shader : require\n"
-        "layout (points) in;\n"
-        "layout (points, max_vertices = 2) out;\n"
-        "void main()\n"
-        "{\n"
-        "    gl_in[0].gl_Position = vec4(0, 0, 0, 1);\n"
-        "}\n";
+        R"(#version 310 es
+        #extension GL_EXT_geometry_shader : require
+        layout (points) in;
+        layout (points, max_vertices = 2) out;
+        void main()
+        {
+            gl_in[0].gl_Position = vec4(0, 0, 0, 1);
+        })";
     if (compile(shaderString))
     {
         FAIL() << "Shader compilation succeeded, expecting failure:\n" << mInfoLog;
     }
 }
 
 // Verify Geometry Shader supports all required built-in variables.
 TEST_F(GeometryShaderTest, BuiltInVariables)
 {
     const std::string &shaderString =
-        "#version 310 es\n"
-        "#extension GL_OES_geometry_shader : require\n"
-        "layout (points, invocations = 2) in;\n"
-        "layout (points, max_vertices = 2) out;\n"
-        "void main()\n"
-        "{\n"
-        "    gl_Position = gl_in[gl_InvocationID].gl_Position;\n"
-        "    int invocation = gl_InvocationID;\n"
-        "    gl_Layer = invocation;\n"
-        "    int primitiveIn = gl_PrimitiveIDIn;\n"
-        "    gl_PrimitiveID = primitiveIn;\n"
-        "}\n";
+        R"(#version 310 es
+        #extension GL_EXT_geometry_shader : require
+        layout (points, invocations = 2) in;
+        layout (points, max_vertices = 2) out;
+        void main()
+        {
+            gl_Position = gl_in[gl_InvocationID].gl_Position;
+            int invocation = gl_InvocationID;
+            gl_Layer = invocation;
+            int primitiveIn = gl_PrimitiveIDIn;
+            gl_PrimitiveID = primitiveIn;
+        })";
     if (!compile(shaderString))
     {
         FAIL() << "Shader compilation failed, expecting success:\n" << mInfoLog;
     }
 }
 
 // Verify that gl_PrimitiveIDIn cannot be l-value.
 TEST_F(GeometryShaderTest, AssignValueToGLPrimitiveIn)
 {
     const std::string &shaderString =
-        "#version 310 es\n"
-        "#extension GL_OES_geometry_shader : require\n"
-        "layout (points, invocations = 2) in;\n"
-        "layout (points, max_vertices = 2) out;\n"
-        "void main()\n"
-        "{\n"
-        "    gl_PrimitiveIDIn = 1;\n"
-        "}\n";
+        R"(#version 310 es
+        #extension GL_EXT_geometry_shader : require
+        layout (points, invocations = 2) in;
+        layout (points, max_vertices = 2) out;
+        void main()
+        {
+            gl_PrimitiveIDIn = 1;
+        })";
     if (compile(shaderString))
     {
         FAIL() << "Shader compilation succeeded, expecting failure:\n" << mInfoLog;
     }
 }
 
 // Verify that gl_InvocationID cannot be l-value.
 TEST_F(GeometryShaderTest, AssignValueToGLInvocations)
 {
     const std::string &shaderString =
-        "#version 310 es\n"
-        "#extension GL_OES_geometry_shader : require\n"
-        "layout (points, invocations = 2) in;\n"
-        "layout (points, max_vertices = 2) out;\n"
-        "void main()\n"
-        "{\n"
-        "    gl_InvocationID = 1;\n"
-        "}\n";
+        R"(#version 310 es
+        #extension GL_EXT_geometry_shader : require
+        layout (points, invocations = 2) in;
+        layout (points, max_vertices = 2) out;
+        void main()
+        {
+            gl_InvocationID = 1;
+        })";
     if (compile(shaderString))
     {
         FAIL() << "Shader compilation succeeded, expecting failure:\n" << mInfoLog;
     }
 }
 
 // Verify that both EmitVertex() and EndPrimitive() are supported in Geometry Shader.
 TEST_F(GeometryShaderTest, GeometryShaderBuiltInFunctions)
 {
     const std::string &shaderString =
-        "#version 310 es\n"
-        "#extension GL_OES_geometry_shader : require\n"
-        "layout (points) in;\n"
-        "layout (points, max_vertices = 2) out;\n"
-        "void main()\n"
-        "{\n"
-        "    gl_Position = gl_in[0].gl_Position;\n"
-        "    EmitVertex();\n"
-        "    EndPrimitive();\n"
-        "}\n";
+        R"(#version 310 es
+        #extension GL_EXT_geometry_shader : require
+        layout (points) in;
+        layout (points, max_vertices = 2) out;
+        void main()
+        {
+            gl_Position = gl_in[0].gl_Position;
+            EmitVertex();
+            EndPrimitive();
+        })";
+
     if (!compile(shaderString))
     {
         FAIL() << "Shader compilation failed, expecting success:\n" << mInfoLog;
     }
 }
 
-// Verify that using EmitVertex() or EndPrimitive() without GL_OES_geometry_shader declared causes a
+// Verify that using EmitVertex() or EndPrimitive() without GL_EXT_geometry_shader declared causes a
 // compile error.
 TEST_F(GeometryShaderTest, GeometryShaderBuiltInFunctionsWithoutExtension)
 {
     const std::string &shaderString1 =
-        "#version 310 es\n"
-        "void main()\n"
-        "{\n"
-        "    EmitVertex();\n"
-        "}\n";
+        R"(#version 310 es
+        void main()
+        {
+            EmitVertex();
+        })";
 
     const std::string &shaderString2 =
-        "#version 310 es\n"
-        "void main()\n"
-        "{\n"
-        "    EndPrimitive();\n"
-        "}\n";
+        R"(#version 310 es
+        void main()
+        {
+            EndPrimitive();
+        })";
 
     if (compile(shaderString1) || compile(shaderString2))
     {
         FAIL() << "Shader compilation succeeded, expecting failure:\n" << mInfoLog;
     }
 }
 
 // Verify that all required built-in constant values are supported in Geometry Shaders
 TEST_F(GeometryShaderTest, GeometryShaderBuiltInConstants)
 {
     const std::string &kShaderHeader =
-        "#version 310 es\n"
-        "#extension GL_OES_geometry_shader : require\n"
-        "layout (points) in;\n"
-        "layout (points, max_vertices = 2) out;\n"
-        "void main()\n"
-        "{\n"
-        "    int val = ";
+        R"(#version 310 es
+        #extension GL_EXT_geometry_shader : require
+        layout (points) in;
+        layout (points, max_vertices = 2) out;
+        void main()
+        {
+            gl_Position.x = float()";
 
     const std::array<std::string, 9> kGeometryShaderBuiltinConstants = {{
         "gl_MaxGeometryInputComponents", "gl_MaxGeometryOutputComponents",
         "gl_MaxGeometryImageUniforms", "gl_MaxGeometryTextureImageUnits",
         "gl_MaxGeometryOutputVertices", "gl_MaxGeometryTotalOutputComponents",
         "gl_MaxGeometryUniformComponents", "gl_MaxGeometryAtomicCounters",
         "gl_MaxGeometryAtomicCounterBuffers",
     }};
 
     const std::string &kShaderTail =
-        ";\n"
-        "}\n";
+        R"();
+            EmitVertex();
+        })";
 
     for (const std::string &kGSBuiltinConstant : kGeometryShaderBuiltinConstants)
     {
         std::ostringstream ostream;
         ostream << kShaderHeader << kGSBuiltinConstant << kShaderTail;
         if (!compile(ostream.str()))
         {
             FAIL() << "Shader compilation failed, expecting success: \n" << mInfoLog;
         }
     }
 }
 
-// Verify that using any Geometry Shader built-in constant values without GL_OES_geometry_shader
+// Verify that using any Geometry Shader built-in constant values without GL_EXT_geometry_shader
 // declared causes a compile error.
 TEST_F(GeometryShaderTest, GeometryShaderBuiltInConstantsWithoutExtension)
 {
     const std::string &kShaderHeader =
         "#version 310 es\n"
         "void main()\n"
         "{\n"
         "    int val = ";
@@ -1151,8 +1175,451 @@ TEST_F(GeometryShaderTest, GeometryShade
         std::ostringstream ostream;
         ostream << kShaderHeader << kGSBuiltinConstant << kShaderTail;
         if (compile(ostream.str()))
         {
             FAIL() << "Shader compilation succeeded, expecting failure: \n" << mInfoLog;
         }
     }
 }
+
+// Verify that Geometry Shaders cannot accept non-array inputs.
+TEST_F(GeometryShaderTest, NonArrayInput)
+{
+    const std::string &shaderString =
+        R"(#version 310 es
+        #extension GL_EXT_geometry_shader : require
+        layout (points) in;
+        layout (points, max_vertices = 1) out;
+        in vec4 texcoord;
+        void main()
+        {
+        })";
+
+    if (compile(shaderString))
+    {
+        FAIL() << "Shader compilation succeeded, expecting failure:\n" << mInfoLog;
+    }
+}
+
+// Verify that it is a compile error to declare an unsized Geometry Shader input before a valid
+// input primitive declaration.
+TEST_F(GeometryShaderTest, DeclareUnsizedInputBeforeInputPrimitive)
+{
+    const std::string &shaderString1 =
+        R"(#version 310 es
+        #extension GL_EXT_geometry_shader : require
+        in vec4 texcoord[];
+        layout (points) in;
+        layout (points, max_vertices = 1) out;
+        void main()
+        {
+            vec4 coord = texcoord[0];
+            int length = texcoord.length();
+        })";
+
+    const std::string &shaderString2 =
+        R"(#version 310 es
+        #extension GL_EXT_geometry_shader : require
+        in vec4 texcoord1[1];
+        in vec4 texcoord2[];
+        layout (points) in;
+        layout (points, max_vertices = 1) out;
+        void main()
+        {
+            vec4 coord = texcoord2[0];
+            int length = texcoord2.length();
+        })";
+
+    if (compile(shaderString1) || compile(shaderString2))
+    {
+        FAIL() << "Shader compilation succeeded, expecting failure:\n" << mInfoLog;
+    }
+}
+
+// Verify that it is a compile error to declare an unsized Geometry Shader input without a valid
+// input primitive declaration.
+TEST_F(GeometryShaderTest, DeclareUnsizedInputWithoutInputPrimitive)
+{
+    const std::string &shaderString1 =
+        R"(#version 310 es
+        #extension GL_EXT_geometry_shader : require
+        layout (points, max_vertices = 1) out;
+        in vec4 texcoord[];
+        void main()
+        {
+        })";
+
+    const std::string &shaderString2 =
+        R"(#version 310 es
+        #extension GL_EXT_geometry_shader : require
+        layout (points, max_vertices = 1) out;
+        in vec4 texcoord1[1];
+        in vec4 texcoord2[];
+        void main()
+        {
+        })";
+
+    if (compile(shaderString1) || compile(shaderString2))
+    {
+        FAIL() << "Shader compilation succeeded, expecting failure:\n" << mInfoLog;
+    }
+}
+
+// Verify that indexing an unsized Geometry Shader input which is declared after a
+// valid input primitive declaration can compile.
+TEST_F(GeometryShaderTest, IndexingUnsizedInputDeclaredAfterInputPrimitive)
+{
+    const std::string &shaderString =
+        R"(#version 310 es
+        #extension GL_EXT_geometry_shader : require
+        layout (points) in;
+        layout (points, max_vertices = 1) out;
+        in vec4 texcoord[], texcoord2[];
+        in vec4[] texcoord3, texcoord4;
+        void main()
+        {
+            gl_Position = texcoord[0] + texcoord2[0] + texcoord3[0] + texcoord4[0];
+            EmitVertex();
+        })";
+
+    if (!compile(shaderString))
+    {
+        FAIL() << "Shader compilation failed, expecting success:\n" << mInfoLog;
+    }
+}
+
+// Verify that calling length() function on an unsized Geometry Shader input which
+// is declared before a valid input primitive declaration can compile.
+TEST_F(GeometryShaderTest, CallingLengthOnUnsizedInputDeclaredAfterInputPrimitive)
+{
+    const std::string &shaderString =
+        R"(#version 310 es
+        #extension GL_EXT_geometry_shader : require
+        layout (points) in;
+        layout (points, max_vertices = 1) out;
+        in vec4 texcoord[];
+        void main()
+        {
+            gl_Position = vec4(texcoord.length());
+            EmitVertex();
+        })";
+
+    if (!compile(shaderString))
+    {
+        FAIL() << "Shader compilation failed, expecting success:\n" << mInfoLog;
+    }
+}
+
+// Verify that assigning a value to the input of a geometry shader causes a compile error.
+TEST_F(GeometryShaderTest, AssignValueToInput)
+{
+    const std::string &shaderString =
+        R"(#version 310 es
+        #extension GL_EXT_geometry_shader : require
+        layout (points) in;
+        layout (points, max_vertices = 1) out;
+        in vec4 texcoord[];
+        void main()
+        {
+            texcoord[0] = vec4(1.0, 0.0, 0.0, 1.0);
+        })";
+
+    if (compile(shaderString))
+    {
+        FAIL() << "Shader compilation succeeded, expecting failure:\n" << mInfoLog;
+    }
+}
+
+// Geometry Shaders allow inputs with location qualifier.
+TEST_F(GeometryShaderTest, InputWithLocations)
+{
+    const std::string &shaderString =
+        R"(#version 310 es
+        #extension GL_EXT_geometry_shader : require
+        layout (triangles) in;
+        layout (points, max_vertices = 1) out;
+        layout (location = 0) in vec4 texcoord1[];
+        layout (location = 1) in vec4 texcoord2[];
+        void main()
+        {
+            int index = 0;
+            vec4 coord1 = texcoord1[0];
+            vec4 coord2 = texcoord2[index];
+            gl_Position = coord1 + coord2;
+        })";
+
+    if (!compile(shaderString))
+    {
+        FAIL() << "Shader compilation failed, expecting success:\n" << mInfoLog;
+    }
+}
+
+// Geometry Shaders allow inputs with explicit size declared before the declaration of the
+// input primitive, but they should have same size and match the declaration of the
+// following input primitive declarations.
+TEST_F(GeometryShaderTest, InputWithSizeBeforeInputPrimitive)
+{
+    for (auto &primitiveAndArraySize : kInputPrimitivesAndInputArraySizeMap)
+    {
+        const std::string &inputLayoutStr =
+            GetGeometryShaderLayout("in", primitiveAndArraySize.first, -1, -1);
+        const int inputSize = primitiveAndArraySize.second;
+
+        const std::string &inputDeclaration1 = GetInputDeclaration("vec4 input1", inputSize);
+        if (!compileGeometryShader(inputDeclaration1, "", inputLayoutStr, kOutputLayout))
+        {
+            FAIL() << "Shader compilation failed, expecting success:\n" << mInfoLog;
+        }
+
+        const std::string &inputDeclaration2 = GetInputDeclaration("vec4 input2", inputSize + 1);
+        if (compileGeometryShader(inputDeclaration2, "", inputLayoutStr, kOutputLayout) ||
+            compileGeometryShader(inputDeclaration1, inputDeclaration2, inputLayoutStr,
+                                  kOutputLayout))
+        {
+            FAIL() << "Shader compilation succeeded, expecting failure:\n" << mInfoLog;
+        }
+    }
+}
+
+// Geometry shaders allow inputs with explicit size declared after the declaration of the
+// input primitive, but their sizes should match the previous input primitive declaration.
+TEST_F(GeometryShaderTest, InputWithSizeAfterInputPrimitive)
+{
+    for (auto &primitiveAndArraySize : kInputPrimitivesAndInputArraySizeMap)
+    {
+        const std::string &inputLayoutStr =
+            GetGeometryShaderLayout("in", primitiveAndArraySize.first, -1, -1);
+        const int inputSize = primitiveAndArraySize.second;
+
+        const std::string &inputDeclaration1 = GetInputDeclaration("vec4 input1", inputSize);
+        if (!compileGeometryShader(inputLayoutStr, kOutputLayout, inputDeclaration1, ""))
+        {
+            FAIL() << "Shader compilation failed, expecting success:\n" << mInfoLog;
+        }
+
+        const std::string &inputDeclaration2 = GetInputDeclaration("vec4 input2", inputSize + 1);
+        if (compileGeometryShader(inputLayoutStr, kOutputLayout, inputDeclaration2, ""))
+        {
+            FAIL() << "Shader compilation succeeded, expecting failure:\n" << mInfoLog;
+        }
+    }
+}
+
+// Verify that Geometry Shaders accept non-array outputs.
+TEST_F(GeometryShaderTest, NonArrayOutputs)
+{
+    const std::string &shaderString =
+        R"(#version 310 es
+        #extension GL_EXT_geometry_shader : require
+        layout (points) in;
+        layout (points, max_vertices = 1) out;
+        out vec4 color;
+        void main()
+        {
+        })";
+
+    if (!compile(shaderString))
+    {
+        FAIL() << "Shader compilation failed, expecting success:\n" << mInfoLog;
+    }
+}
+
+// Verify that Geometry Shaders allow declaring outputs with 'location' layout qualifier.
+TEST_F(GeometryShaderTest, OutputsWithLocation)
+{
+    const std::string &shaderString =
+        R"(#version 310 es
+        #extension GL_EXT_geometry_shader : require
+        layout (triangles) in;
+        layout (points, max_vertices = 1) out;
+        layout (location = 0) out vec4 color1;
+        layout (location = 1) out vec4 color2;
+        void main()
+        {
+            color1 = vec4(0.0, 1.0, 0.0, 1.0);
+            color2 = vec4(1.0, 0.0, 0.0, 1.0);
+        })";
+
+    if (!compile(shaderString))
+    {
+        FAIL() << "Shader compilation failed, expecting success:\n" << mInfoLog;
+    }
+}
+
+// Geometry Shaders allow declaring sized array outputs.
+TEST_F(GeometryShaderTest, SizedArrayOutputs)
+{
+    const std::string &shaderString =
+        R"(#version 310 es
+        #extension GL_EXT_geometry_shader : require
+        layout (triangles) in;
+        layout (points, max_vertices = 1) out;
+        out vec4 color[2];
+        void main()
+        {
+            color[0] = vec4(0.0, 1.0, 0.0, 1.0);
+            color[1] = vec4(1.0, 0.0, 0.0, 1.0);
+        })";
+
+    if (!compile(shaderString))
+    {
+        FAIL() << "Shader compilation failed, expecting success:\n" << mInfoLog;
+    }
+}
+
+// Verify that Geometry Shader outputs cannot be declared as an unsized array.
+TEST_F(GeometryShaderTest, UnsizedArrayOutputs)
+{
+    const std::string &shaderString =
+        R"(#version 310 es
+        #extension GL_EXT_geometry_shader : require
+        layout (triangles) in;
+        layout (points, max_vertices = 1) out;
+        out vec4 color[];
+        void main()
+        {
+        })";
+
+    if (compile(shaderString))
+    {
+        FAIL() << "Shader compilation succeeded, expecting failure:\n" << mInfoLog;
+    }
+}
+
+// Verify that Geometry Shader inputs can use interpolation qualifiers.
+TEST_F(GeometryShaderTest, InputWithInterpolationQualifiers)
+{
+    for (const std::string &qualifier : kInterpolationQualifiers)
+    {
+        std::ostringstream stream;
+        stream << kHeader << kInputLayout << kOutputLayout << qualifier << " in vec4 texcoord[];\n"
+               << kEmptyBody;
+
+        if (!compile(stream.str()))
+        {
+            FAIL() << "Shader compilation failed, expecting success:\n" << mInfoLog;
+        }
+    }
+}
+
+// Verify that Geometry Shader outputs can use interpolation qualifiers.
+TEST_F(GeometryShaderTest, OutputWithInterpolationQualifiers)
+{
+    for (const std::string &qualifier : kInterpolationQualifiers)
+    {
+        std::ostringstream stream;
+        stream << kHeader << kInputLayout << kOutputLayout << qualifier << " out vec4 color;\n"
+               << kEmptyBody;
+
+        if (!compile(stream.str()))
+        {
+            FAIL() << "Shader compilation failed, expecting success:\n" << mInfoLog;
+        }
+    }
+}
+
+// Verify that Geometry Shader outputs can use 'invariant' qualifier.
+TEST_F(GeometryShaderTest, InvariantOutput)
+{
+    const std::string &shaderString =
+        R"(#version 310 es
+        #extension GL_EXT_geometry_shader : require
+        layout (points) in;
+        layout (points, max_vertices = 2) out;
+        invariant out vec4 gs_output;
+        void main()
+        {
+            gl_Position = gl_in[0].gl_Position;
+        })";
+
+    if (!compile(shaderString))
+    {
+        FAIL() << "Shader compilation failed, expecting success:\n" << mInfoLog;
+    }
+}
+
+// Verify that the member of gl_in won't be incorrectly changed in the output shader string.
+TEST_F(GeometryShaderOutputCodeTest, ValidateGLInMembersInOutputShaderString)
+{
+    const std::string &shaderString1 =
+        R"(#version 310 es
+        #extension GL_EXT_geometry_shader : require
+        layout (lines) in;
+        layout (points, max_vertices = 2) out;
+        void main()
+        {
+            vec4 position;
+            for (int i = 0; i < 2; i++)
+            {
+                position = gl_in[i].gl_Position;
+            }
+        })";
+
+    compile(shaderString1);
+    EXPECT_TRUE(foundInESSLCode("].gl_Position"));
+
+    const std::string &shaderString2 =
+        R"(#version 310 es
+        #extension GL_EXT_geometry_shader : require
+        layout (points) in;
+        layout (points, max_vertices = 2) out;
+        void main()
+        {
+            vec4 position;
+            position = gl_in[0].gl_Position;
+        })";
+
+    compile(shaderString2);
+    EXPECT_TRUE(foundInESSLCode("].gl_Position"));
+}
+
+// Verify that geometry shader inputs can be declared as struct arrays.
+TEST_F(GeometryShaderTest, StructArrayInput)
+{
+    const std::string &shaderString =
+        R"(#version 310 es
+        #extension GL_EXT_geometry_shader : require
+        layout (points) in;
+        layout (points, max_vertices = 2) out;
+        struct S
+        {
+            float value1;
+            vec4 value2;
+        };
+        in S gs_input[];
+        out S gs_output;
+        void main()
+        {
+            gs_output = gs_input[0];
+        })";
+
+    if (!compile(shaderString))
+    {
+        FAIL() << "Shader compilation failed, expecting success:\n" << mInfoLog;
+    }
+}
+
+// Verify that geometry shader outputs cannot be declared as struct arrays.
+TEST_F(GeometryShaderTest, StructArrayOutput)
+{
+    const std::string &shaderString =
+        R"(#version 310 es
+        #extension GL_EXT_geometry_shader : require
+        layout (points) in;
+        layout (points, max_vertices = 2) out;
+        struct S
+        {
+            float value1;
+            vec4 value2;
+        };
+        out S gs_output[1];
+        void main()
+        {
+            gs_output[0].value1 = 1.0;
+            gs_output[0].value2 = vec4(1.0, 0.0, 0.0, 1.0);
+        })";
+
+    if (compile(shaderString))
+    {
+        FAIL() << "Shader compilation succeeded, expecting failure:\n" << mInfoLog;
+    }
+}
\ No newline at end of file
--- a/gfx/angle/src/tests/compiler_tests/InitOutputVariables_test.cpp
+++ b/gfx/angle/src/tests/compiler_tests/InitOutputVariables_test.cpp
@@ -7,16 +7,17 @@
 // SH_INIT_OUTPUT_VARIABLES.
 //
 
 #include "common/angleutils.h"
 
 #include "compiler/translator/FindMain.h"
 #include "compiler/translator/IntermNode_util.h"
 #include "compiler/translator/IntermTraverse.h"
+#include "compiler/translator/SymbolTable.h"
 #include "tests/test_utils/ShaderCompileTreeTest.h"
 
 #include <algorithm>
 
 namespace sh
 {
 
 namespace
@@ -30,17 +31,19 @@ bool AreSymbolsTheSame(const TIntermSymb
     {
         return false;
     }
     const TType &expectedType  = expected->getType();
     const TType &candidateType = candidate->getType();
     const bool sameTypes       = expectedType == candidateType &&
                            expectedType.getPrecision() == candidateType.getPrecision() &&
                            expectedType.getQualifier() == candidateType.getQualifier();
-    const bool sameSymbols = expected->getSymbol() == candidate->getSymbol();
+    const bool sameSymbols = (expected->variable().symbolType() == SymbolType::Empty &&
+                              candidate->variable().symbolType() == SymbolType::Empty) ||
+                             expected->getName() == candidate->getName();
     return sameSymbols && sameTypes;
 }
 
 bool AreLValuesTheSame(TIntermTyped *expected, TIntermTyped *candidate)
 {
     const TIntermBinary *expectedBinary = expected->getAsBinaryNode();
     if (expectedBinary)
     {
@@ -58,32 +61,41 @@ bool AreLValuesTheSame(TIntermTyped *exp
         return AreSymbolsTheSame(expectedBinary->getLeft()->getAsSymbolNode(),
                                  candidateBinary->getLeft()->getAsSymbolNode());
     }
     return AreSymbolsTheSame(expected->getAsSymbolNode(), candidate->getAsSymbolNode());
 }
 
 TIntermTyped *CreateLValueNode(const TString &lValueName, const TType &type)
 {
-    return new TIntermSymbol(0, lValueName, type);
+    // We're using a dummy symbol table here, don't need to assign proper symbol ids to these nodes.
+    TSymbolTable symbolTable;
+    TVariable *variable = new TVariable(&symbolTable, NewPoolTString(lValueName.c_str()), type,
+                                        SymbolType::UserDefined);
+    return new TIntermSymbol(variable);
 }
 
 ExpectedLValues CreateIndexedLValueNodeList(const TString &lValueName,
                                             TType elementType,
                                             unsigned arraySize)
 {
     ASSERT(elementType.isArray() == false);
     elementType.makeArray(arraySize);
 
+    // We're using a dummy symbol table here, don't need to assign proper symbol ids to these nodes.
+    TSymbolTable symbolTable;
+    TVariable *variable        = new TVariable(&symbolTable, NewPoolTString(lValueName.c_str()),
+                                        elementType, SymbolType::UserDefined);
+    TIntermSymbol *arraySymbol = new TIntermSymbol(variable);
+
     ExpectedLValues expected(arraySize);
     for (unsigned index = 0u; index < arraySize; ++index)
     {
-        expected[index] =
-            new TIntermBinary(EOpIndexDirect, new TIntermSymbol(0, lValueName, elementType),
-                              CreateIndexNode(static_cast<int>(index)));
+        expected[index] = new TIntermBinary(EOpIndexDirect, arraySymbol->deepCopy(),
+                                            CreateIndexNode(static_cast<int>(index)));
     }
     return expected;
 }
 
 // VerifyOutputVariableInitializers traverses the subtree covering main and collects the lvalues in
 // assignments for which the rvalue is an expression containing only zero constants.
 class VerifyOutputVariableInitializers final : public TIntermTraverser
 {
@@ -150,19 +162,20 @@ class FindStructByName final : public TI
 
     void visitSymbol(TIntermSymbol *symbol) override
     {
         if (isStructureFound())
         {
             return;
         }
 
-        TStructure *structure = symbol->getType().getStruct();
+        TStructure *structure = symbol->getTypePointer()->getStruct();
 
-        if (structure != nullptr && structure->name() == mStructName)
+        if (structure != nullptr && structure->symbolType() != SymbolType::Empty &&
+            structure->name() == mStructName)
         {
             mStructure = structure;
         }
     }
 
     bool isStructureFound() const { return mStructure != nullptr; };
     TStructure *getStructure() const { return mStructure; }
 
--- a/gfx/angle/src/tests/compiler_tests/IntermNode_test.cpp
+++ b/gfx/angle/src/tests/compiler_tests/IntermNode_test.cpp
@@ -2,21 +2,22 @@
 // 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.
 //
 // IntermNode_test.cpp:
 //   Unit tests for the AST node classes.
 //
 
+#include "compiler/translator/IntermNode.h"
 #include "angle_gl.h"
-#include "gtest/gtest.h"
 #include "compiler/translator/InfoSink.h"
-#include "compiler/translator/IntermNode.h"
 #include "compiler/translator/PoolAlloc.h"
+#include "compiler/translator/SymbolTable.h"
+#include "gtest/gtest.h"
 
 using namespace sh;
 
 class IntermNodeTest : public testing::Test
 {
   public:
     IntermNodeTest() : mUniqueIndex(0) {}
 
@@ -32,23 +33,28 @@ class IntermNodeTest : public testing::T
         SetGlobalPoolAllocator(nullptr);
         allocator.pop();
     }
 
     TIntermSymbol *createTestSymbol(const TType &type)
     {
         TInfoSinkBase symbolNameOut;
         symbolNameOut << "test" << mUniqueIndex;
-        TString symbolName = symbolNameOut.c_str();
+        TString *symbolName = NewPoolTString(symbolNameOut.c_str());
         ++mUniqueIndex;
 
-        TIntermSymbol *node = new TIntermSymbol(0, symbolName, type);
+        // We're using a dummy symbol table here, don't need to assign proper symbol ids to these
+        // nodes.
+        TSymbolTable symbolTable;
+        TType variableType(type);
+        variableType.setQualifier(EvqTemporary);
+        TVariable *variable =
+            new TVariable(&symbolTable, symbolName, variableType, SymbolType::AngleInternal);
+        TIntermSymbol *node = new TIntermSymbol(variable);
         node->setLine(createUniqueSourceLoc());
-        node->setInternal(true);
-        node->getTypePointer()->setQualifier(EvqTemporary);
         return node;
     }
 
     TIntermSymbol *createTestSymbol()
     {
         TType type(EbtFloat, EbpHigh);
         return createTestSymbol(type);
     }
@@ -63,19 +69,19 @@ class IntermNodeTest : public testing::T
     void checkSymbolCopy(TIntermNode *aOriginal, TIntermNode *aCopy)
     {
         ASSERT_NE(aOriginal, aCopy);
         TIntermSymbol *copy     = aCopy->getAsSymbolNode();
         TIntermSymbol *original = aOriginal->getAsSymbolNode();
         ASSERT_NE(nullptr, copy);
         ASSERT_NE(nullptr, original);
         ASSERT_NE(original, copy);
-        ASSERT_EQ(original->getId(), copy->getId());
-        ASSERT_EQ(original->getName().getString(), copy->getName().getString());
-        ASSERT_EQ(original->getName().isInternal(), copy->getName().isInternal());
+        ASSERT_EQ(&original->variable(), &copy->variable());
+        ASSERT_EQ(original->uniqueId(), copy->uniqueId());
+        ASSERT_EQ(original->getName(), copy->getName());
         checkTypeEqualWithQualifiers(original->getType(), copy->getType());
         ASSERT_EQ(original->getLine().first_file, copy->getLine().first_file);
         ASSERT_EQ(original->getLine().first_line, copy->getLine().first_line);
         ASSERT_EQ(original->getLine().last_file, copy->getLine().last_file);
         ASSERT_EQ(original->getLine().last_line, copy->getLine().last_line);
     }
 
     TSourceLoc createUniqueSourceLoc()
@@ -112,19 +118,24 @@ class IntermNodeTest : public testing::T
     int mUniqueIndex;
 };
 
 // Check that the deep copy of a symbol node is an actual copy with the same attributes as the
 // original.
 TEST_F(IntermNodeTest, DeepCopySymbolNode)
 {
     TType type(EbtInt, EbpHigh);
-    TIntermSymbol *original = new TIntermSymbol(0, TString("name"), type);
+
+    // We're using a dummy symbol table here, don't need to assign proper symbol ids to these nodes.
+    TSymbolTable symbolTable;
+
+    TVariable *variable =
+        new TVariable(&symbolTable, NewPoolTString("name"), type, SymbolType::AngleInternal);
+    TIntermSymbol *original = new TIntermSymbol(variable);
     original->setLine(getTestSourceLoc());
-    original->setInternal(true);
     TIntermTyped *copy = original->deepCopy();
     checkSymbolCopy(original, copy);
     checkTestSourceLoc(copy->getLine());
 }
 
 // Check that the deep copy of a constant union node is an actual copy with the same attributes as
 // the original.
 TEST_F(IntermNodeTest, DeepCopyConstantUnionNode)
--- a/gfx/angle/src/tests/compiler_tests/Pack_Unpack_test.cpp
+++ b/gfx/angle/src/tests/compiler_tests/Pack_Unpack_test.cpp
@@ -22,101 +22,107 @@ class PackUnpackTest : public MatchOutpu
   public:
     PackUnpackTest() : MatchOutputCodeTest(GL_FRAGMENT_SHADER, 0, SH_GLSL_400_CORE_OUTPUT) {}
 };
 
 // Check if PackSnorm2x16 Emulation for GLSL < 4.2 compile correctly.
 TEST_F(PackUnpackTest, PackSnorm2x16Emulation)
 {
     const std::string &shaderString =
-        "#version 300 es\n"
-        "precision mediump float;\n"
-        "layout(location = 0) out mediump vec4 fragColor;"
-        "void main() {\n"
-        "   vec2 v;\n"
-        "   uint u = packSnorm2x16(v);\n"
-        "   fragColor = vec4(0.0);\n"
-        "}\n";
+        R"(#version 300 es
+        precision mediump float;
+        layout(location = 0) out mediump vec4 fragColor;
+        void main()
+        {
+           vec2 v;
+           uint u = packSnorm2x16(v);
+           fragColor = vec4(u);
+        })";
     compile(shaderString);
     ASSERT_TRUE(foundInCode("uint packSnorm2x16_emu(vec2 v)"));
 }
 
 // Check if UnpackSnorm2x16 Emulation for GLSL < 4.2 compile correctly.
 TEST_F(PackUnpackTest, UnpackSnorm2x16Emulation)
 {
     const std::string &shaderString =
-        "#version 300 es\n"
-        "precision mediump float;\n"
-        "layout(location = 0) out mediump vec4 fragColor;"
-        "void main() {\n"
-        "   uint u;\n"
-        "   vec2 v=unpackSnorm2x16(u);\n"
-        "   fragColor = vec4(0.0);\n"
-        "}\n";
+        R"(#version 300 es
+        precision mediump float;
+        layout(location = 0) out mediump vec4 fragColor;
+        void main()
+        {
+           uint u;
+           vec2 v = unpackSnorm2x16(u);
+           fragColor = vec4(v, 0.0, 0.0);
+        })";
     compile(shaderString);
     ASSERT_TRUE(foundInCode("vec2 unpackSnorm2x16_emu(uint u)"));
 }
 
 // Check if PackUnorm2x16 Emulation for GLSL < 4.1 compiles correctly.
 TEST_F(PackUnpackTest, PackUnorm2x16Emulation)
 {
     const std::string &shaderString =
-        "#version 300 es\n"
-        "precision mediump float;\n"
-        "layout(location = 0) out mediump vec4 fragColor;"
-        "void main() {\n"
-        "   vec2 v;\n"
-        "   uint u = packUnorm2x16(v);\n"
-        "   fragColor = vec4(0.0);\n"
-        "}\n";
+        R"(#version 300 es
+        precision mediump float;
+        layout(location = 0) out mediump vec4 fragColor;
+        void main()
+        {
+           vec2 v;
+           uint u = packUnorm2x16(v);
+           fragColor = vec4(u);
+        })";
     compile(shaderString);
     ASSERT_TRUE(foundInCode("uint packUnorm2x16_emu(vec2 v)"));
 }
 
 // Check if UnpackSnorm2x16 Emulation for GLSL < 4.1 compiles correctly.
 TEST_F(PackUnpackTest, UnpackUnorm2x16Emulation)
 {
     const std::string &shaderString =
-        "#version 300 es\n"
-        "precision mediump float;\n"
-        "layout(location = 0) out mediump vec4 fragColor;"
-        "void main() {\n"
-        "   uint u;\n"
-        "   vec2 v=unpackUnorm2x16(u);\n"
-        "   fragColor = vec4(0.0);\n"
-        "}\n";
+        R"(#version 300 es
+        precision mediump float;
+        layout(location = 0) out mediump vec4 fragColor;
+        void main()
+        {
+           uint u;
+           vec2 v = unpackUnorm2x16(u);
+           fragColor = vec4(v, 0.0, 0.0);
+        })";
     compile(shaderString);
     ASSERT_TRUE(foundInCode("vec2 unpackUnorm2x16_emu(uint u)"));
 }
 
 // Check if PackHalf2x16 Emulation for GLSL < 4.2 compiles correctly.
 TEST_F(PackUnpackTest, PackHalf2x16Emulation)
 {
     const std::string &shaderString =
-        "#version 300 es\n"
-        "precision mediump float;\n"
-        "layout(location = 0) out mediump vec4 fragColor;"
-        "void main() {\n"
-        "   vec2 v;\n"
-        "   uint u=packHalf2x16(v);\n"
-        "   fragColor = vec4(0.0);\n"
-        "}\n";
+        R"(#version 300 es
+        precision mediump float;
+        layout(location = 0) out mediump vec4 fragColor;
+        void main()
+        {
+            vec2 v;
+            uint u = packHalf2x16(v);
+            fragColor = vec4(u);
+        })";
     compile(shaderString);
     ASSERT_TRUE(foundInCode("uint packHalf2x16_emu(vec2 v)"));
 }
 
 // Check if UnpackHalf2x16 Emulation for GLSL < 4.2 compiles correctly.
 TEST_F(PackUnpackTest, UnpackHalf2x16Emulation)
 {
     const std::string &shaderString =
-        "#version 300 es\n"
-        "precision mediump float;\n"
-        "layout(location = 0) out mediump vec4 fragColor;"
-        "void main() {\n"
-        "   uint u;\n"
-        "   vec2 v=unpackHalf2x16(u);\n"
-        "   fragColor = vec4(0.0);\n"
-        "}\n";
+        R"(#version 300 es
+        precision mediump float;
+        layout(location = 0) out mediump vec4 fragColor;
+        void main()
+        {
+            uint u;
+            vec2 v = unpackHalf2x16(u);
+            fragColor = vec4(v, 0.0, 0.0);
+        })";
     compile(shaderString);
     ASSERT_TRUE(foundInCode("vec2 unpackHalf2x16_emu(uint u)"));
 }
 
 } // namespace
--- a/gfx/angle/src/tests/compiler_tests/PrunePureLiteralStatements_test.cpp
+++ b/gfx/angle/src/tests/compiler_tests/PrunePureLiteralStatements_test.cpp
@@ -22,37 +22,39 @@ class PrunePureLiteralStatementsTest : p
     // The PrunePureLiteralStatements pass is used when outputting ESSL
     PrunePureLiteralStatementsTest() : MatchOutputCodeTest(GL_FRAGMENT_SHADER, 0, SH_ESSL_OUTPUT) {}
 };
 
 // Most basic test for the pruning
 TEST_F(PrunePureLiteralStatementsTest, FloatLiteralStatement)
 {
     const std::string shaderString =
-        "precision mediump float;\n"
-        "void main()\n"
-        "{\n"
-        "   float f = 41.0;\n"
-        "   42.0;\n"
-        "}\n";
+        R"(precision mediump float;
+        void main()
+        {
+           float f = 41.0;
+           42.0;
+           gl_FragColor = vec4(f);
+        })";
     compile(shaderString);
     ASSERT_TRUE(foundInCode("41"));
     ASSERT_TRUE(notFoundInCode("42"));
 }
 
 // Test the pruning works for constructed types too
 TEST_F(PrunePureLiteralStatementsTest, ConstructorLiteralStatement)
 {
     const std::string shaderString =
-        "precision mediump float;\n"
-        "void main()\n"
-        "{\n"
-        "   vec2 f = vec2(41.0, 41.0);\n"
-        "   vec2(42.0, 42.0);\n"
-        "}\n";
+        R"(precision mediump float;
+        void main()
+        {
+            vec2 f = vec2(41.0, 41.0);
+            vec2(42.0, 42.0);
+            gl_FragColor = vec4(f, 0.0, 0.0);
+        })";
     compile(shaderString);
     ASSERT_TRUE(foundInCode("41"));
     ASSERT_TRUE(notFoundInCode("42"));
 }
 
 // Test the pruning works when the literal is a (non-trivial) expression
 TEST_F(PrunePureLiteralStatementsTest, ExpressionLiteralStatement)
 {
--- a/gfx/angle/src/tests/compiler_tests/QualificationOrderESSL31_test.cpp
+++ b/gfx/angle/src/tests/compiler_tests/QualificationOrderESSL31_test.cpp
@@ -20,19 +20,19 @@ using namespace sh;
 class QualificationVertexShaderTestESSL31 : public ShaderCompileTreeTest
 {
   public:
     QualificationVertexShaderTestESSL31() {}
   protected:
     ::GLenum getShaderType() const override { return GL_VERTEX_SHADER; }
     ShShaderSpec getShaderSpec() const override { return SH_GLES3_1_SPEC; }
 
-    const TIntermSymbol *findSymbolInAST(const TString &symbolName, TBasicType basicType)
+    const TIntermSymbol *findSymbolInAST(const TString &symbolName)
     {
-        return FindSymbolNode(mASTRoot, symbolName, basicType);
+        return FindSymbolNode(mASTRoot, symbolName);
     }
 };
 
 // GLSL ES 3.10 has relaxed checks on qualifier order. Any order is correct.
 TEST_F(QualificationVertexShaderTestESSL31, CentroidOut)
 {
     const std::string &shaderString =
         "#version 310 es\n"
@@ -42,17 +42,17 @@ TEST_F(QualificationVertexShaderTestESSL
         "   something = 1.0;\n"
         "}\n";
     if (!compile(shaderString))
     {
         FAIL() << "Shader compilation failed, expecting success" << mInfoLog;
     }
     else
     {
-        const TIntermSymbol *node = findSymbolInAST("something", EbtFloat);
+        const TIntermSymbol *node = findSymbolInAST("something");
         ASSERT_NE(nullptr, node);
 
         const TType &type = node->getType();
         EXPECT_EQ(EvqCentroidOut, type.getQualifier());
     }
 }
 
 // GLSL ES 3.10 has relaxed checks on qualifier order. Any order is correct.
@@ -65,17 +65,17 @@ TEST_F(QualificationVertexShaderTestESSL
         "void main(){\n"
         "}\n";
     if (!compile(shaderString))
     {
         FAIL() << "Shader compilation failed, expecting success" << mInfoLog;
     }
     else
     {
-        const TIntermSymbol *node = findSymbolInAST("something", EbtFloat);
+        const TIntermSymbol *node = findSymbolInAST("something");
         ASSERT_NE(nullptr, node);
 
         const TType &type = node->getType();
         EXPECT_TRUE(type.isInvariant());
         EXPECT_EQ(EvqFlatOut, type.getQualifier());
         EXPECT_EQ(EbpHigh, type.getPrecision());
     }
 }
@@ -90,17 +90,17 @@ TEST_F(QualificationVertexShaderTestESSL
         "void main(){\n"
         "}\n";
     if (!compile(shaderString))
     {
         FAIL() << "Shader compilation failed, expecting success" << mInfoLog;
     }
     else
     {
-        const TIntermSymbol *node = findSymbolInAST("something", EbtFloat);
+        const TIntermSymbol *node = findSymbolInAST("something");
         ASSERT_NE(nullptr, node);
 
         const TType &type = node->getType();
         EXPECT_EQ(EvqVertexIn, type.getQualifier());
         EXPECT_EQ(2, type.getLayoutQualifier().location);
     }
 }
 
@@ -117,17 +117,17 @@ TEST_F(QualificationVertexShaderTestESSL
         "   someValue = MyInterfaceName.something.r;\n"
         "}\n";
     if (!compile(shaderString))
     {
         FAIL() << "Shader compilation failed, expecting success" << mInfoLog;
     }
     else
     {
-        const TIntermSymbol *node = findSymbolInAST("MyInterfaceName", EbtInterfaceBlock);
+        const TIntermSymbol *node = findSymbolInAST("MyInterfaceName");
         ASSERT_NE(nullptr, node);
 
         const TType &type                = node->getType();
         TLayoutQualifier layoutQualifier = type.getLayoutQualifier();
         EXPECT_EQ(EbsStd140, layoutQualifier.blockStorage);
         EXPECT_EQ(EmpColumnMajor, layoutQualifier.matrixPacking);
     }
 }
@@ -145,17 +145,17 @@ TEST_F(QualificationVertexShaderTestESSL
         "   someValue = MyInterfaceName.something.r;\n"
         "}\n";
     if (!compile(shaderString))
     {
         FAIL() << "Shader compilation failed, expecting success" << mInfoLog;
     }
     else
     {
-        const TIntermSymbol *node = findSymbolInAST("MyInterfaceName", EbtInterfaceBlock);
+        const TIntermSymbol *node = findSymbolInAST("MyInterfaceName");
         ASSERT_NE(nullptr, node);
 
         const TType &type                = node->getType();
         TLayoutQualifier layoutQualifier = type.getLayoutQualifier();
         EXPECT_EQ(EbsShared, layoutQualifier.blockStorage);
         EXPECT_EQ(EmpRowMajor, layoutQualifier.matrixPacking);
     }
 }
new file mode 100644
--- /dev/null
+++ b/gfx/angle/src/tests/compiler_tests/RegenerateStructNames_test.cpp
@@ -0,0 +1,74 @@
+//
+// 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.
+//
+// RegenerateStructNames_test.cpp:
+//   Tests for regenerating struct names.
+//
+
+#include "GLSLANG/ShaderLang.h"
+#include "angle_gl.h"
+#include "gtest/gtest.h"
+#include "tests/test_utils/compiler_test.h"
+
+using namespace sh;
+
+class RegenerateStructNamesTest : public MatchOutputCodeTest
+{
+  public:
+    RegenerateStructNamesTest()
+        : MatchOutputCodeTest(GL_FRAGMENT_SHADER, SH_REGENERATE_STRUCT_NAMES, SH_ESSL_OUTPUT)
+    {
+    }
+};
+
+// Test that a struct defined in a function scope is renamed. The global struct that's used as a
+// type of a uniform cannot be renamed.
+TEST_F(RegenerateStructNamesTest, GlobalStructAndLocalStructWithTheSameName)
+{
+    const std::string &shaderString =
+        R"(precision mediump float;
+
+        struct myStruct
+        {
+            float foo;
+        };
+
+        uniform myStruct us;
+
+        void main()
+        {
+            struct myStruct
+            {
+                vec2 bar;
+            };
+            myStruct scoped;
+            scoped.bar = vec2(1.0, 2.0) * us.foo;
+            gl_FragColor = vec4(scoped.bar, 0.0, 1.0);
+        })";
+    compile(shaderString);
+    EXPECT_TRUE(foundInCode("struct _umyStruct"));
+    EXPECT_TRUE(foundInCode("struct _u_webgl_struct_"));
+}
+
+// Test that a nameless struct is handled gracefully.
+TEST_F(RegenerateStructNamesTest, NamelessStruct)
+{
+    const std::string &shaderString =
+        R"(precision mediump float;
+
+        uniform float u;
+
+        void main()
+        {
+            struct
+            {
+                vec2 bar;
+            } scoped;
+            scoped.bar = vec2(1.0, 2.0) * u;
+            gl_FragColor = vec4(scoped.bar, 0.0, 1.0);
+        })";
+    compile(shaderString);
+    EXPECT_TRUE(foundInCode("struct"));
+}
new file mode 100644
--- /dev/null
+++ b/gfx/angle/src/tests/compiler_tests/RemoveUnreferencedVariables_test.cpp
@@ -0,0 +1,688 @@
+//
+// 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_test.cpp:
+//   Tests for removing unreferenced variables from the AST.
+//
+
+#include "GLSLANG/ShaderLang.h"
+#include "angle_gl.h"
+#include "gtest/gtest.h"
+#include "tests/test_utils/compiler_test.h"
+
+using namespace sh;
+
+class RemoveUnreferencedVariablesTest : public MatchOutputCodeTest
+{
+  public:
+    RemoveUnreferencedVariablesTest() : MatchOutputCodeTest(GL_FRAGMENT_SHADER, 0, SH_ESSL_OUTPUT)
+    {
+    }
+};
+
+// Test that a simple unreferenced declaration is pruned.
+TEST_F(RemoveUnreferencedVariablesTest, SimpleDeclaration)
+{
+    const std::string &shaderString =
+        R"(precision mediump float;
+        void main()
+        {
+            vec4 myUnreferencedVec;
+        })";
+    compile(shaderString);
+
+    ASSERT_TRUE(notFoundInCode("myUnreferencedVec"));
+}
+
+// Test that a simple unreferenced global declaration is pruned.
+TEST_F(RemoveUnreferencedVariablesTest, SimpleGlobalDeclaration)
+{
+    const std::string &shaderString =
+        R"(precision mediump float;
+
+        vec4 myUnreferencedVec;
+
+        void main()
+        {
+        })";
+    compile(shaderString);
+
+    ASSERT_TRUE(notFoundInCode("myUnreferencedVec"));
+}
+
+// Test that a simple unreferenced variable with an initializer is pruned.
+TEST_F(RemoveUnreferencedVariablesTest, SimpleInitializer)
+{
+    const std::string &shaderString =
+        R"(precision mediump float;
+        uniform vec4 uVec;
+        void main()
+        {
+            vec4 myUnreferencedVec = uVec;
+        })";
+    compile(shaderString);
+
+    ASSERT_TRUE(notFoundInCode("myUnreferencedVec"));
+}
+
+// Test that a user-defined function call inside an unreferenced variable initializer is retained.
+TEST_F(RemoveUnreferencedVariablesTest, SideEffectInInitializer)
+{
+    const std::string &shaderString =
+        R"(precision mediump float;
+        vec4 sideEffect(int i)
+        {
+            gl_FragColor = vec4(0, i, 0, 1);
+            return vec4(0);
+        }
+        void main()
+        {
+            vec4 myUnreferencedVec = sideEffect(1);
+        })";
+    compile(shaderString);
+
+    // We're happy as long as the function with side effects is called.
+    ASSERT_TRUE(foundInCode("sideEffect(1)"));
+}
+
+// Test that a modf call inside an unreferenced variable initializer is retained.
+TEST_F(RemoveUnreferencedVariablesTest, BuiltInSideEffectInInitializer)
+{
+    const std::string &shaderString =
+        R"(#version 300 es
+        precision mediump float;
+        uniform float uF;
+        out vec4 my_FragColor;
+
+        void main()
+        {
+            float iPart = 0.0;
+            float myUnreferencedFloat = modf(uF, iPart);
+            my_FragColor = vec4(0.0, iPart, 0.0, 1.0);
+        })";
+    compile(shaderString);
+
+    // We're happy as long as the function with side effects is called.
+    ASSERT_TRUE(foundInCode("modf("));
+}
+
+// Test that an imageStore call inside an unreferenced variable initializer is retained.
+TEST_F(RemoveUnreferencedVariablesTest, ImageStoreSideEffectInInitializer)
+{
+    const std::string &shaderString =
+        R"(#version 310 es
+        precision highp float;
+        layout(rgba32i) uniform highp writeonly iimage2D img;
+
+        void main()
+        {
+            float myUnreferencedFloat = (imageStore(img, ivec2(0), ivec4(1)), 1.0);
+        })";
+    compile(shaderString);
+
+    // We're happy as long as the function with side effects is called.
+    ASSERT_TRUE(foundInCode("imageStore("));
+}
+
+// Test that multiple variables that are chained but otherwise are unreferenced are removed.
+TEST_F(RemoveUnreferencedVariablesTest, MultipleVariablesChained)
+{
+    const std::string &shaderString =
+        R"(precision mediump float;
+        uniform vec4 uVec;
+        void main()
+        {
+            vec4 myUnreferencedVec1 = uVec;
+            vec4 myUnreferencedVec2 = myUnreferencedVec1 * 2.0;
+            vec4 myUnreferencedVec3 = myUnreferencedVec2 + 1.0;
+        })";
+    compile(shaderString);
+
+    ASSERT_TRUE(notFoundInCode("myUnreferencedVec3"));
+    ASSERT_TRUE(notFoundInCode("myUnreferencedVec2"));
+    ASSERT_TRUE(notFoundInCode("myUnreferencedVec1"));
+}
+
+// Test that multiple variables that are chained with the last one being referenced are kept.
+TEST_F(RemoveUnreferencedVariablesTest, MultipleVariablesChainedReferenced)
+{
+    const std::string &shaderString =
+        R"(precision mediump float;
+        uniform vec4 uVec;
+        void main()
+        {
+            vec4 myReferencedVec1 = uVec;
+            vec4 myReferencedVec2 = myReferencedVec1 * 2.0;
+            vec4 myReferencedVec3 = myReferencedVec2 + 1.0;
+            gl_FragColor = myReferencedVec3;
+        })";
+    compile(shaderString);
+
+    ASSERT_TRUE(foundInCode("myReferencedVec3"));
+    ASSERT_TRUE(foundInCode("myReferencedVec2"));
+    ASSERT_TRUE(foundInCode("myReferencedVec1"));
+}
+
+// Test that multiple variables that are chained within two scopes but otherwise are unreferenced
+// are removed.
+TEST_F(RemoveUnreferencedVariablesTest, MultipleVariablesChainedTwoScopes)
+{
+    const std::string &shaderString =
+        R"(precision mediump float;
+        uniform vec4 uVec;
+        void main()
+        {
+            vec4 myUnreferencedVec1 = uVec;
+            vec4 myUnreferencedVec2 = myUnreferencedVec1 * 2.0;
+            if (uVec.x > 0.0)
+            {
+                vec4 myUnreferencedVec3 = myUnreferencedVec2 + 1.0;
+            }
+        })";
+    compile(shaderString);
+
+    ASSERT_TRUE(notFoundInCode("myUnreferencedVec3"));
+    ASSERT_TRUE(notFoundInCode("myUnreferencedVec2"));
+    ASSERT_TRUE(notFoundInCode("myUnreferencedVec1"));
+}
+
+// Test that multiple variables that are chained with the last one being referenced in an inner
+// scope are kept.
+TEST_F(RemoveUnreferencedVariablesTest, VariableReferencedInAnotherScope)
+{
+    const std::string &shaderString =
+        R"(precision mediump float;
+        uniform vec4 uVec;
+        void main()
+        {
+            vec4 myReferencedVec1 = uVec;
+            vec4 myReferencedVec2 = myReferencedVec1 * 2.0;
+            if (uVec.x > 0.0)
+            {
+                vec4 myReferencedVec3 = myReferencedVec2 + 1.0;
+                gl_FragColor = myReferencedVec3;
+            }
+        })";
+    compile(shaderString);
+
+    ASSERT_TRUE(foundInCode("myReferencedVec3"));
+    ASSERT_TRUE(foundInCode("myReferencedVec2"));
+    ASSERT_TRUE(foundInCode("myReferencedVec1"));
+}
+
+// Test that if there are two variables with the same name, one of them can be removed and another
+// one kept.
+TEST_F(RemoveUnreferencedVariablesTest, TwoVariablesWithSameNameInDifferentScopes)
+{
+    const std::string &shaderString =
+        R"(precision mediump float;
+        uniform vec4 uVec;
+        void main()
+        {
+            vec4 myVec = uVec;  // This one is unreferenced.
+            if (uVec.x > 0.0)
+            {
+                vec4 myVec = uVec * 2.0;  // This one is referenced.
+                gl_FragColor = myVec;
+            }
+            vec4 myUnreferencedVec = myVec;
+        })";
+    compile(shaderString);
+
+    ASSERT_TRUE(foundInCode("myVec", 2));
+}
+
+// Test that an unreferenced variable declared in a for loop header is removed.
+TEST_F(RemoveUnreferencedVariablesTest, UnreferencedVariableDeclaredInForLoopHeader)
+{
+    const std::string &shaderString =
+        R"(#version 300 es
+        precision highp float;
+        uniform int ui;
+
+        out vec4 my_FragColor;
+
+        void main()
+        {
+            my_FragColor = vec4(0.0);
+            int index = 0;
+            for (int unreferencedInt = ui; index < 10; ++index)
+            {
+                my_FragColor += vec4(0.0, float(index) * 0.01, 0.0, 0.0);
+            }
+        })";
+    compile(shaderString);
+
+    ASSERT_TRUE(foundInCode("index"));
+    ASSERT_TRUE(notFoundInCode("unreferencedInt"));
+}
+
+// Test that a loop condition is kept even if it declares an unreferenced variable.
+TEST_F(RemoveUnreferencedVariablesTest, UnreferencedVariableDeclaredInWhileLoopCondition)
+{
+    const std::string &shaderString =
+        R"(#version 300 es
+        precision highp float;
+        uniform int ui;
+
+        out vec4 my_FragColor;
+
+        void main()
+        {
+            my_FragColor = vec4(0.0);
+            int index = 0;
+            while (bool b = (index < 10))
+            {
+                my_FragColor += vec4(0.0, float(index) * 0.01, 0.0, 0.0);
+                ++index;
+            }
+        })";
+    compile(shaderString);
+
+    ASSERT_TRUE(foundInCode("index < 10"));
+}
+
+// Test that a variable declared in a for loop header that is only referenced in an unreferenced
+// variable initializer is removed.
+TEST_F(RemoveUnreferencedVariablesTest,
+       VariableDeclaredInForLoopHeaderAccessedInUnreferencedVariableInitializer)
+{
+    const std::string &shaderString =
+        R"(#version 300 es
+        precision highp float;
+        uniform int ui;
+
+        out vec4 my_FragColor;
+
+        void main()
+        {
+            my_FragColor = vec4(0.0);
+            int index = 0;
+            for (int unreferencedInt1 = ui; index < 10; ++index)
+            {
+                int unreferencedInt2 = unreferencedInt1;
+                my_FragColor += vec4(0.0, float(index) * 0.01, 0.0, 0.0);
+            }
+        })";
+    compile(shaderString);
+
+    ASSERT_TRUE(foundInCode("index"));
+    ASSERT_TRUE(notFoundInCode("unreferencedInt2"));
+    ASSERT_TRUE(notFoundInCode("unreferencedInt1"));
+}
+
+// Test that a user-defined type (struct) declaration that's used is not removed, but that the
+// variable that's declared in the same declaration is removed.
+TEST_F(RemoveUnreferencedVariablesTest, UserDefinedTypeReferencedAndVariableNotReferenced)
+{
+    const std::string &shaderString =
+        R"(#version 300 es
+        precision highp float;
+        uniform float uF;
+
+        out vec4 my_FragColor;
+
+        void main()
+        {
+            struct myStruct { float member; } unreferencedStruct;
+            myStruct usedStruct = myStruct(uF);
+            my_FragColor = vec4(usedStruct.member);
+        })";
+    compile(shaderString);
+
+    ASSERT_TRUE(foundInCode("myStruct"));
+    ASSERT_TRUE(foundInCode("usedStruct"));
+    ASSERT_TRUE(notFoundInCode("unreferencedStruct"));
+}
+
+// Test that a nameless user-defined type (struct) declaration is removed entirely.
+TEST_F(RemoveUnreferencedVariablesTest, NamelessUserDefinedTypeUnreferenced)
+{
+    const std::string &shaderString =
+        R"(#version 300 es
+        precision highp float;
+        void main()
+        {
+            struct { float member; } unreferencedStruct;
+        })";
+    compile(shaderString);
+
+    ASSERT_TRUE(notFoundInCode("unreferencedStruct"));
+    ASSERT_TRUE(notFoundInCode("member"));
+}
+
+// Test that a variable that's only referenced in a unused function is removed.
+TEST_F(RemoveUnreferencedVariablesTest, VariableOnlyReferencedInUnusedFunction)
+{
+    const std::string &shaderString =
+        R"(
+        int onlyReferencedInUnusedFunction = 0;
+        void unusedFunc() {
+            onlyReferencedInUnusedFunction++;
+        }
+
+        void main()
+        {
+        })";
+    compile(shaderString);
+
+    ASSERT_TRUE(notFoundInCode("onlyReferencedInUnusedFunction"));
+}
+
+// Test that a variable that's only referenced in an array length() method call is removed.
+TEST_F(RemoveUnreferencedVariablesTest, VariableOnlyReferencedInLengthMethod)
+{
+    const std::string &shaderString =
+        R"(#version 300 es
+        precision highp float;
+
+        out vec4 my_FragColor;
+
+        void main()
+        {
+            float onlyReferencedInLengthMethodCall[1];
+            int len = onlyReferencedInLengthMethodCall.length();
+            my_FragColor = vec4(0, len, 0, 1);
+        })";
+    compile(shaderString);
+
+    ASSERT_TRUE(notFoundInCode("onlyReferencedInLengthMethodCall"));
+}
+
+// Test that an unreferenced user-defined type is removed.
+TEST_F(RemoveUnreferencedVariablesTest, UserDefinedTypeUnreferenced)
+{
+    const std::string &shaderString =
+        R"(
+        struct myStructType
+        {
+            int i;
+        } myStructVariable;
+
+        void main()
+        {
+        })";
+    compile(shaderString);
+
+    ASSERT_TRUE(notFoundInCode("myStructType"));
+}
+
+// Test that a user-defined type that's only referenced in an unreferenced variable is removed.
+TEST_F(RemoveUnreferencedVariablesTest, UserDefinedTypeReferencedInUnreferencedVariable)
+{
+    const std::string &shaderString =
+        R"(
+        struct myStructType
+        {
+            int i;
+        };
+
+        void main()
+        {
+            myStructType myStructVariable;
+        })";
+    compile(shaderString);
+
+    ASSERT_TRUE(notFoundInCode("myStructType"));
+}
+
+// Test that a user-defined type that's declared in an empty declaration and that is only referenced
+// in an unreferenced variable is removed also when the shader contains another independent
+// user-defined type that's declared in an empty declaration. This tests special case handling of
+// reference counting of empty symbols.
+TEST_F(RemoveUnreferencedVariablesTest,
+       TwoUserDefinedTypesDeclaredInEmptyDeclarationsWithOneOfThemUnreferenced)
+{
+    const std::string &shaderString =
+        R"(
+        struct myStructTypeA
+        {
+            int i;
+        };
+
+        struct myStructTypeB
+        {
+            int j;
+        };
+
+        uniform myStructTypeB myStructVariableB;
+
+        void main()
+        {
+            myStructTypeA myStructVariableA;
+        })";
+    compile(shaderString);
+
+    ASSERT_TRUE(notFoundInCode("myStructTypeA"));
+    ASSERT_TRUE(foundInCode("myStructTypeB"));
+}
+
+// Test that a user-defined type that is only referenced in another unreferenced type is removed.
+TEST_F(RemoveUnreferencedVariablesTest, UserDefinedTypeChain)
+{
+    const std::string &shaderString =
+        R"(
+        struct myInnerStructType
+        {
+            int i;
+        };
+
+        struct myOuterStructType
+        {
+            myInnerStructType inner;
+        } myStructVariable;
+
+        void main()
+        {
+            myOuterStructType myStructVariable2;
+        })";
+    compile(shaderString);
+
+    ASSERT_TRUE(notFoundInCode("myInnerStructType"));
+}
+
+// Test that a user-defined type that is referenced in another user-defined type that is used is
+// kept.
+TEST_F(RemoveUnreferencedVariablesTest, UserDefinedTypeChainReferenced)
+{
+    const std::string &shaderString =
+        R"(
+        precision mediump float;
+
+        struct myInnerStructType
+        {
+            int i;
+        };
+
+        uniform struct
+        {
+            myInnerStructType inner;
+        } myStructVariable;
+
+        void main()
+        {
+            if (myStructVariable.inner.i > 0)
+            {
+                gl_FragColor = vec4(0, 1, 0, 1);
+            }
+        })";
+    compile(shaderString);
+
+    ASSERT_TRUE(foundInCode("struct _umyInnerStructType"));
+}
+
+// Test that a struct type that is only referenced in a constructor and function call is kept.
+TEST_F(RemoveUnreferencedVariablesTest, UserDefinedTypeReferencedInConstructorAndCall)
+{
+    const std::string &shaderString =
+        R"(
+        precision mediump float;
+
+        uniform int ui;
+
+        struct myStructType
+        {
+            int iMember;
+        };
+
+        void func(myStructType myStructParam)
+        {
+            if (myStructParam.iMember > 0)
+            {
+                gl_FragColor = vec4(0, 1, 0, 1);
+            }
+        }
+
+        void main()
+        {
+            func(myStructType(ui));
+        })";
+    compile(shaderString);
+
+    ASSERT_TRUE(foundInCode("struct _umyStructType"));
+}
+
+// Test that a struct type that is only referenced in a constructor is kept. This assumes that there
+// isn't more sophisticated folding of struct field access going on.
+TEST_F(RemoveUnreferencedVariablesTest, UserDefinedTypeReferencedInConstructor)
+{
+    const std::string &shaderString =
+        R"(
+        precision mediump float;
+
+        uniform int ui;
+
+        struct myStructType
+        {
+            int iMember;
+        };
+
+        void main()
+        {
+            if (myStructType(ui).iMember > 0)
+            {
+                gl_FragColor = vec4(0, 1, 0, 1);
+            }
+        })";
+    compile(shaderString);
+
+    ASSERT_TRUE(foundInCode("struct _umyStructType"));
+}
+
+// Test that a struct type that is only referenced in an unused function is removed.
+TEST_F(RemoveUnreferencedVariablesTest, UserDefinedTypeReferencedInUnusedFunction)
+{
+    const std::string &shaderString =
+        R"(
+        precision mediump float;
+
+        struct myStructType
+        {
+            int iMember;
+        };
+
+        void func(myStructType myStructParam)
+        {
+            if (myStructParam.iMember > 0)
+            {
+                gl_FragColor = vec4(0, 1, 0, 1);
+            }
+        }
+
+        void main()
+        {
+        })";
+    compile(shaderString);
+
+    ASSERT_TRUE(notFoundInCode("myStructType"));
+}
+
+// Test that a struct type that is only referenced in an unused function is kept in case
+// SH_DONT_PRUNE_UNUSED_FUNCTIONS is specified.
+TEST_F(RemoveUnreferencedVariablesTest, UserDefinedTypeReferencedInUnusedFunctionThatIsNotPruned)
+{
+    const std::string &shaderString =
+        R"(
+        struct myStructType
+        {
+            int iMember;
+        };
+
+        myStructType func()
+        {
+            return myStructType(0);
+        }
+
+        void main()
+        {
+        })";
+    compile(shaderString, SH_DONT_PRUNE_UNUSED_FUNCTIONS);
+
+    ASSERT_TRUE(foundInCode("struct _umyStructType"));
+
+    // Ensure that the struct isn't declared as a part of the function header.
+    ASSERT_TRUE(foundInCode("};"));
+}
+
+// Test that a struct type that is only referenced as a function return value is kept.
+TEST_F(RemoveUnreferencedVariablesTest, UserDefinedTypeReturnedFromFunction)
+{
+    const std::string &shaderString =
+        R"(
+        precision mediump float;
+
+        struct myStructType
+        {
+            int iMember;
+        };
+
+        myStructType func()
+        {
+            gl_FragColor = vec4(0, 1, 0, 1);
+            return myStructType(0);
+        }
+
+        void main()
+        {
+            func();
+        })";
+    compile(shaderString);
+
+    ASSERT_TRUE(foundInCode("struct _umyStructType"));
+
+    // Ensure that the struct isn't declared as a part of the function header.
+    ASSERT_TRUE(foundInCode("};"));
+}
+
+// Test that a struct type that is only referenced in a uniform block is kept.
+TEST_F(RemoveUnreferencedVariablesTest, UserDefinedTypeInUniformBlock)
+{
+    const std::string &shaderString =
+        R"(#version 300 es
+
+        precision highp float;
+        out vec4 my_FragColor;
+
+        struct myStructType
+        {
+            int iMember;
+        };
+
+        layout(std140) uniform myBlock {
+            myStructType uStruct;
+            int ui;
+        };
+
+        void main()
+        {
+            if (ui > 0)
+            {
+                my_FragColor = vec4(0, 1, 0, 1);
+            }
+        })";
+    compile(shaderString);
+
+    ASSERT_TRUE(foundInCode("struct _umyStructType"));
+}
--- a/gfx/angle/src/tests/compiler_tests/RewriteDoWhile_test.cpp
+++ b/gfx/angle/src/tests/compiler_tests/RewriteDoWhile_test.cpp
@@ -25,18 +25,17 @@ class RewriteDoWhileCrashTest : public S
 
     void SetUp() override
     {
         mExtraCompileOptions |= SH_REWRITE_DO_WHILE_LOOPS;
         ShaderCompileTreeTest::SetUp();
     }
 };
 
-// Make sure that the RewriteDoWhile step doesn't crash due to creating temp symbols before calling
-// nextTemporaryId(). Regression test.
+// Make sure that the RewriteDoWhile step doesn't crash. Regression test.
 TEST_F(RewriteDoWhileCrashTest, RunsSuccessfully)
 {
     const std::string &shaderString =
         "#version 300 es\n"
         "precision mediump float;\n"
         "uniform int u;\n"
         "out vec4 my_FragColor;\n"
         "void main()\n"
new file mode 100644
--- /dev/null
+++ b/gfx/angle/src/tests/compiler_tests/ScalarizeVecAndMatConstructorArgs_test.cpp
@@ -0,0 +1,120 @@
+//
+// 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.
+//
+// ScalarizeVecAndMatConstructorArgs_test.cpp:
+//   Tests for scalarizing vector and matrix constructor args.
+//
+
+#include "GLSLANG/ShaderLang.h"
+#include "angle_gl.h"
+#include "gtest/gtest.h"
+#include "tests/test_utils/compiler_test.h"
+
+using namespace sh;
+
+namespace
+{
+
+class ScalarizeVecAndMatConstructorArgsTest : public MatchOutputCodeTest
+{
+  public:
+    ScalarizeVecAndMatConstructorArgsTest()
+        : MatchOutputCodeTest(GL_FRAGMENT_SHADER,
+                              SH_SCALARIZE_VEC_AND_MAT_CONSTRUCTOR_ARGS,
+                              SH_ESSL_OUTPUT)
+    {
+    }
+};
+
+// Verifies scalarizing matrix inside a vector constructor.
+TEST_F(ScalarizeVecAndMatConstructorArgsTest, MatrixInVectorConstructor)
+{
+    const std::string shaderString =
+        R"(
+        precision mediump float;
+
+        uniform mat2 umat2;
+
+        void main()
+        {
+            gl_FragColor = vec4(umat2);
+        })";
+    compile(shaderString);
+
+    std::vector<const char *> expectedStrings = {
+        "main()", " = _uumat2", "gl_FragColor = vec4(", "[0][0],", "[0][1],", "[1][0],", "[1][1])"};
+
+    EXPECT_TRUE(foundInCodeInOrder(expectedStrings));
+}
+
+// Verifies scalarizing a vector insized a matrix constructor.
+TEST_F(ScalarizeVecAndMatConstructorArgsTest, VectorInMatrixConstructor)
+{
+    const std::string shaderString =
+        R"(
+        precision mediump float;
+
+        uniform vec2 uvec2;
+
+        void main()
+        {
+            mat2 m = mat2(uvec2, uvec2);
+            gl_FragColor = vec4(m * uvec2, m * uvec2);
+        })";
+    compile(shaderString);
+
+    std::vector<const char *> expectedStrings = {
+        "main()", " = _uuvec2", "mat2(", "[0],", "[1],", "[0],", "[1])", "gl_FragColor = vec4("};
+
+    EXPECT_TRUE(foundInCodeInOrder(expectedStrings));
+}
+
+// Verifies that scalarizing vector and matrix constructor args inside a sequence operator preserves
+// correct order of operations.
+TEST_F(ScalarizeVecAndMatConstructorArgsTest, SequenceOperator)
+{
+    const std::string shaderString =
+        R"(
+        precision mediump float;
+
+        uniform vec2 u;
+
+        void main()
+        {
+            vec2 v = u;
+            mat2 m = (v[0] += 1.0, mat2(v, v[1], -v[0]));
+            gl_FragColor = vec4(m[0], m[1]);
+        })";
+    compile(shaderString);
+
+    std::vector<const char *> expectedStrings = {"_uv[0] += 1.0", "-_uv[0]"};
+
+    EXPECT_TRUE(foundInCodeInOrder(expectedStrings));
+}
+
+// Verifies that scalarizing vector and matrix constructor args inside multiple declarations
+// preserves the correct order of operations.
+TEST_F(ScalarizeVecAndMatConstructorArgsTest, MultiDeclaration)
+{
+    const std::string shaderString =
+        R"(
+        precision mediump float;
+
+        uniform vec2 u;
+
+        void main()
+        {
+            vec2 v = vec2(u[0]),
+                 w = mat2(v, v) * u;
+            gl_FragColor = vec4(v, w);
+        })";
+    compile(shaderString);
+
+    std::vector<const char *> expectedStrings = {"vec2(_uu[0])", "mat2("};
+
+    EXPECT_TRUE(foundInCodeInOrder(expectedStrings));
+}
+
+}  // anonymous namespace
--- a/gfx/angle/src/tests/compiler_tests/ShaderImage_test.cpp
+++ b/gfx/angle/src/tests/compiler_tests/ShaderImage_test.cpp
@@ -91,19 +91,20 @@ void CheckImageDeclaration(TIntermNode *
                            TLayoutImageInternalFormat internalFormat,
                            bool readonly,
                            bool writeonly,
                            bool coherent,
                            bool restrictQualifier,
                            bool volatileQualifier,
                            int binding)
 {
-    const TIntermSymbol *myImageNode = FindSymbolNode(astRoot, imageName, imageType);
+    const TIntermSymbol *myImageNode = FindSymbolNode(astRoot, imageName);
     ASSERT_NE(nullptr, myImageNode);
 
+    ASSERT_EQ(imageType, myImageNode->getBasicType());
     const TType &myImageType                = myImageNode->getType();
     TLayoutQualifier myImageLayoutQualifier = myImageType.getLayoutQualifier();
     ASSERT_EQ(internalFormat, myImageLayoutQualifier.imageInternalFormat);
     TMemoryQualifier myImageMemoryQualifier = myImageType.getMemoryQualifier();
     ASSERT_EQ(readonly, myImageMemoryQualifier.readonly);
     ASSERT_EQ(writeonly, myImageMemoryQualifier.writeonly);
     ASSERT_EQ(coherent, myImageMemoryQualifier.coherent);
     ASSERT_EQ(restrictQualifier, myImageMemoryQualifier.restrictQualifier);
--- a/gfx/angle/src/tests/compiler_tests/ShaderValidation_test.cpp
+++ b/gfx/angle/src/tests/compiler_tests/ShaderValidation_test.cpp
@@ -96,31 +96,31 @@ class ComputeShaderEnforcePackingValidat
 class GeometryShaderValidationTest : public ShaderCompileTreeTest
 {
   public:
     GeometryShaderValidationTest() {}
 
   protected:
     void initResources(ShBuiltInResources *resources) override
     {
-        resources->OES_geometry_shader = 1;
-    }
-    ::GLenum getShaderType() const override { return GL_GEOMETRY_SHADER_OES; }
+        resources->EXT_geometry_shader = 1;
+    }
+    ::GLenum getShaderType() const override { return GL_GEOMETRY_SHADER_EXT; }
     ShShaderSpec getShaderSpec() const override { return SH_GLES3_1_SPEC; }
 };
 
-class FragmentShaderOESGeometryShaderValidationTest : public FragmentShaderValidationTest
+class FragmentShaderEXTGeometryShaderValidationTest : public FragmentShaderValidationTest
 {
   public:
-    FragmentShaderOESGeometryShaderValidationTest() {}
+    FragmentShaderEXTGeometryShaderValidationTest() {}
 
   protected:
     void initResources(ShBuiltInResources *resources) override
     {
-        resources->OES_geometry_shader = 1;
+        resources->EXT_geometry_shader = 1;
     }
 };
 
 // This is a test for a bug that used to exist in ANGLE:
 // Calling a function with all parameters missing should not succeed.
 TEST_F(FragmentShaderValidationTest, FunctionParameterMismatch)
 {
     const std::string &shaderString =
@@ -2269,52 +2269,52 @@ TEST_F(FragmentShaderValidationTest, Inv
         FAIL() << "Shader compilation succeeded, expecting failure:\n" << mInfoLog;
     }
 }
 
 // The local_size layout qualifier is only available in compute shaders.
 TEST_F(GeometryShaderValidationTest, InvalidUseOfLocalSizeX)
 {
     const std::string &shaderString1 =
-        "#version 310 es\n"
-        "#extension GL_OES_geometry_shader : require\n"
-        "layout (points, local_size_x = 15) in;\n"
-        "layout (points, max_vertices = 2) out;\n"
-        "void main()\n"
-        "{\n"
-        "}\n";
+        R"(#version 310 es
+        #extension GL_EXT_geometry_shader : require
+        layout (points, local_size_x = 15) in;
+        layout (points, max_vertices = 2) out;
+        void main()
+        {
+        })";
 
     const std::string &shaderString2 =
-        "#version 310 es\n"
-        "#extension GL_OES_geometry_shader : require\n"
-        "layout (points) in;\n"
-        "layout (invocations = 2, local_size_x = 15) in;\n"
-        "layout (points, max_vertices = 2) out;\n"
-        "void main()\n"
-        "{\n"
-        "}\n";
+        R"(#version 310 es
+        #extension GL_EXT_geometry_shader : require
+        layout (points) in;
+        layout (invocations = 2, local_size_x = 15) in;
+        layout (points, max_vertices = 2) out;
+        void main()
+        {
+        })";
 
     const std::string &shaderString3 =
-        "#version 310 es\n"
-        "#extension GL_OES_geometry_shader : require\n"
-        "layout (points) in;\n"
-        "layout (points, local_size_x = 15, max_vertices = 2) out;\n"
-        "void main()\n"
-        "{\n"
-        "}\n";
+        R"(#version 310 es
+        #extension GL_EXT_geometry_shader : require
+        layout (points) in;
+        layout (points, local_size_x = 15, max_vertices = 2) out;
+        void main()
+        {
+        })";
 
     const std::string &shaderString4 =
-        "#version 310 es\n"
-        "#extension GL_OES_geometry_shader : require\n"
-        "layout (points) in;\n"
-        "layout (points) out;\n"
-        "layout (max_vertices = 2, local_size_x = 15) out;\n"
-        "void main()\n"
-        "{\n"
-        "}\n";
+        R"(#version 310 es
+        #extension GL_EXT_geometry_shader : require
+        layout (points) in;
+        layout (points) out;
+        layout (max_vertices = 2, local_size_x = 15) out;
+        void main()
+        {
+        })";
     if (compile(shaderString1) || compile(shaderString2) || compile(shaderString3) ||
         compile(shaderString4))
     {
         FAIL() << "Shader compilation succeeded, expecting failure:\n" << mInfoLog;
     }
 }
 
 // It is a compile time error to use the gl_WorkGroupSize constant if
@@ -2334,27 +2334,29 @@ TEST_F(ComputeShaderValidationTest, Inva
         FAIL() << "Shader compilation succeeded, expecting failure:\n" << mInfoLog;
     }
 }
 
 // The test covers the compute shader built-in variables and constants.
 TEST_F(ComputeShaderValidationTest, CorrectUsageOfComputeBuiltins)
 {
     const std::string &shaderString =
-        "#version 310 es\n"
-        "layout(local_size_x = 12) in;\n"
-        "void main()\n"
-        "{\n"
-        "   uvec3 NumWorkGroups = gl_NumWorkGroups;\n"
-        "   uvec3 WorkGroupSize = gl_WorkGroupSize;\n"
-        "   uvec3 WorkGroupID = gl_WorkGroupID;\n"
-        "   uvec3 GlobalInvocationID = gl_GlobalInvocationID;\n"
-        "   uvec3 LocalInvocationID = gl_LocalInvocationID;\n"
-        "   uint LocalInvocationIndex = gl_LocalInvocationIndex;\n"
-        "}\n";
+        R"(#version 310 es
+        layout(local_size_x=4, local_size_y=3, local_size_z=2) in;
+        layout(rgba32ui) uniform highp writeonly uimage2D imageOut;
+        void main()
+        {
+            uvec3 temp1 = gl_NumWorkGroups;
+            uvec3 temp2 = gl_WorkGroupSize;
+            uvec3 temp3 = gl_WorkGroupID;
+            uvec3 temp4 = gl_LocalInvocationID;
+            uvec3 temp5 = gl_GlobalInvocationID;
+            uint  temp6 = gl_LocalInvocationIndex;
+            imageStore(imageOut, ivec2(0), uvec4(temp1 + temp2 + temp3 + temp4 + temp5, temp6));
+        })";
     if (!compile(shaderString))
     {
         FAIL() << "Shader compilation failed, expecting success:\n" << mInfoLog;
     }
 }
 
 // It is illegal to write to a special variable.
 TEST_F(ComputeShaderValidationTest, SpecialVariableNumWorkGroups)
@@ -2584,21 +2586,22 @@ TEST_F(FragmentShaderValidationTest, Var
 }
 
 // Bit shift with a rhs value > 31 has an undefined result in the GLSL spec. Detecting an undefined
 // result at compile time should not generate an error either way.
 // ESSL 3.00.6 section 5.9.
 TEST_F(FragmentShaderValidationTest, ShiftBy32)
 {
     const std::string &shaderString =
-        "#version 300 es\n"
-        "precision mediump float;\n"
-        "void main() {\n"
-        "   uint u = 1u << 32u;\n"
-        "}\n";
+        R"(#version 300 es
+        precision mediump float;
+        out uint my_out;
+        void main() {
+           my_out = 1u << 32u;
+        })";
     if (compile(shaderString))
     {
         if (!hasWarning())
         {
             FAIL() << "Shader compilation succeeded without warnings, expecting warning:\n"
                    << mInfoLog;
         }
     }
@@ -2609,21 +2612,22 @@ TEST_F(FragmentShaderValidationTest, Shi
 }
 
 // Bit shift with a rhs value < 0 has an undefined result in the GLSL spec. Detecting an undefined
 // result at compile time should not generate an error either way.
 // ESSL 3.00.6 section 5.9.
 TEST_F(FragmentShaderValidationTest, ShiftByNegative)
 {
     const std::string &shaderString =
-        "#version 300 es\n"
-        "precision mediump float;\n"
-        "void main() {\n"
-        "   uint u = 1u << (-1);\n"
-        "}\n";
+        R"(#version 300 es
+        precision mediump float;
+        out uint my_out;
+        void main() {
+           my_out = 1u << (-1);
+        })";
     if (compile(shaderString))
     {
         if (!hasWarning())
         {
             FAIL() << "Shader compilation succeeded without warnings, expecting warning:\n"
                    << mInfoLog;
         }
     }
@@ -4012,22 +4016,25 @@ TEST_F(FragmentShaderValidationTest, Inv
         FAIL() << "Shader compilation succeeded, expecting failure:\n" << mInfoLog;
     }
 }
 
 // Test that "buffer" and "shared" are valid identifiers in version lower than GLSL ES 3.10.
 TEST_F(FragmentShaderValidationTest, BufferAndSharedAsIdentifierOnES3)
 {
     const std::string &shaderString =
-        "#version 300 es\n"
-        "void main()\n"
-        "{\n"
-        "    int buffer;\n"
-        "    int shared;\n"
-        "}\n";
+        R"(#version 300 es
+        precision highp float;
+        out vec4 my_out;
+        void main()
+        {
+            int buffer = 1;
+            int shared = 2;
+            my_out = vec4(buffer + shared);
+        })";
 
     if (!compile(shaderString))
     {
         FAIL() << "Shader compilation failed, expecting success:\n" << mInfoLog;
     }
 }
 
 // Test that a struct can not be used as a constructor argument for a scalar.
@@ -4426,178 +4433,178 @@ TEST_F(VertexShaderValidationTest, Viewp
         "}\n";
 
     if (compile(shaderString))
     {
         FAIL() << "Shader compilation succeeded, expecting failure:\n" << mInfoLog;
     }
 }
 
-// Test that gl_PrimitiveID is valid in fragment shader with 'GL_OES_geometry_shader' declared.
-TEST_F(FragmentShaderOESGeometryShaderValidationTest, PrimitiveIDWithExtension)
-{
-    const std::string &shaderString =
-        "#version 310 es\n"
-        "#extension GL_OES_geometry_shader : require\n"
-        "precision mediump float;\n"
-        "layout(location = 0) out mediump vec4 fragColor;\n"
-        "void main(void)\n"
-        "{\n"
-        "    vec4 data = vec4(0.1, 0.2, 0.3, 0.4);\n"
-        "    float value = data[gl_PrimitiveID % 4];\n"
-        "    fragColor = vec4(value, 0, 0, 1);\n"
-        "}\n";
+// Test that gl_PrimitiveID is valid in fragment shader with 'GL_EXT_geometry_shader' declared.
+TEST_F(FragmentShaderEXTGeometryShaderValidationTest, PrimitiveIDWithExtension)
+{
+    const std::string &shaderString =
+        R"(#version 310 es
+        #extension GL_EXT_geometry_shader : require
+        precision mediump float;
+        layout(location = 0) out mediump vec4 fragColor;
+        void main(void)
+        {
+            vec4 data = vec4(0.1, 0.2, 0.3, 0.4);
+            float value = data[gl_PrimitiveID % 4];
+            fragColor = vec4(value, 0, 0, 1);
+        })";
 
     if (!compile(shaderString))
     {
         FAIL() << "Shader compilation failed, expecting success:\n" << mInfoLog;
     }
 }
 
-// Test that gl_PrimitiveID is invalid in fragment shader without 'GL_OES_geometry_shader' declared.
-TEST_F(FragmentShaderOESGeometryShaderValidationTest, PrimitiveIDWithoutExtension)
-{
-    const std::string &shaderString =
-        "#version 310 es\n"
-        "precision mediump float;\n"
-        "layout(location = 0) out mediump vec4 fragColor;\n"
-        "void main(void)\n"
-        "{\n"
-        "    vec4 data = vec4(0.1, 0.2, 0.3, 0.4);\n"
-        "    float value = data[gl_PrimitiveID % 4];\n"
-        "    fragColor = vec4(value, 0, 0, 1);\n"
-        "}\n";
+// Test that gl_PrimitiveID is invalid in fragment shader without 'GL_EXT_geometry_shader' declared.
+TEST_F(FragmentShaderEXTGeometryShaderValidationTest, PrimitiveIDWithoutExtension)
+{
+    const std::string &shaderString =
+        R"(#version 310 es
+        precision mediump float;
+        layout(location = 0) out mediump vec4 fragColor;
+        void main(void)
+        {
+            vec4 data = vec4(0.1, 0.2, 0.3, 0.4);
+            float value = data[gl_PrimitiveID % 4];
+            fragColor = vec4(value, 0, 0, 1);
+        })";
 
     if (compile(shaderString))
     {
         FAIL() << "Shader compilation succeeded, expecting failure:\n" << mInfoLog;
     }
 }
 
 // Test that gl_PrimitiveID cannot be l-value in fragment shader.
-TEST_F(FragmentShaderOESGeometryShaderValidationTest, AssignValueToPrimitiveID)
-{
-    const std::string &shaderString =
-        "#version 310 es\n"
-        "#extension GL_OES_geometry_shader : require\n"
-        "precision mediump float;\n"
-        "layout(location = 0) out mediump vec4 fragColor;\n"
-        "void main(void)\n"
-        "{\n"
-        "    gl_PrimitiveID = 1;\n"
-        "    fragColor = vec4(1.0, 0.0, 0.0, 1.0);\n"
-        "}\n";
-
-    if (compile(shaderString))
-    {
-        FAIL() << "Shader compilation succeeded, expecting failure:\n" << mInfoLog;
-    }
-}
-
-// Test that gl_Layer is valid in fragment shader with 'GL_OES_geometry_shader' declared.
-TEST_F(FragmentShaderOESGeometryShaderValidationTest, LayerWithExtension)
-{
-    const std::string &shaderString =
-        "#version 310 es\n"
-        "#extension GL_OES_geometry_shader : require\n"
-        "precision mediump float;\n"
-        "layout(location = 0) out mediump vec4 fragColor;\n"
-        "void main(void)\n"
-        "{\n"
-        "    vec4 data = vec4(0.1, 0.2, 0.3, 0.4);\n"
-        "    float value = data[gl_Layer % 4];\n"
-        "    fragColor = vec4(value, 0, 0, 1);\n"
-        "}\n";
+TEST_F(FragmentShaderEXTGeometryShaderValidationTest, AssignValueToPrimitiveID)
+{
+    const std::string &shaderString =
+        R"(#version 310 es
+        #extension GL_EXT_geometry_shader : require
+        precision mediump float;
+        layout(location = 0) out mediump vec4 fragColor;
+        void main(void)
+        {
+            gl_PrimitiveID = 1;
+            fragColor = vec4(1.0, 0.0, 0.0, 1.0);
+        })";
+
+    if (compile(shaderString))
+    {
+        FAIL() << "Shader compilation succeeded, expecting failure:\n" << mInfoLog;
+    }
+}
+
+// Test that gl_Layer is valid in fragment shader with 'GL_EXT_geometry_shader' declared.
+TEST_F(FragmentShaderEXTGeometryShaderValidationTest, LayerWithExtension)
+{
+    const std::string &shaderString =
+        R"(#version 310 es
+        #extension GL_EXT_geometry_shader : require
+        precision mediump float;
+        layout(location = 0) out mediump vec4 fragColor;
+        void main(void)
+        {
+            vec4 data = vec4(0.1, 0.2, 0.3, 0.4);
+            float value = data[gl_Layer % 4];
+            fragColor = vec4(value, 0, 0, 1);
+        })";
 
     if (!compile(shaderString))
     {
         FAIL() << "Shader compilation failed, expecting success:\n" << mInfoLog;
     }
 }
 
-// Test that gl_Layer is invalid in fragment shader without 'GL_OES_geometry_shader' declared.
-TEST_F(FragmentShaderOESGeometryShaderValidationTest, LayerWithoutExtension)
-{
-    const std::string &shaderString =
-        "#version 310 es\n"
-        "precision mediump float;\n"
-        "layout(location = 0) out mediump vec4 fragColor;\n"
-        "void main(void)\n"
-        "{\n"
-        "    vec4 data = vec4(0.1, 0.2, 0.3, 0.4);\n"
-        "    float value = data[gl_Layer % 4];\n"
-        "    fragColor = vec4(value, 0, 0, 1);\n"
-        "}\n";
+// Test that gl_Layer is invalid in fragment shader without 'GL_EXT_geometry_shader' declared.
+TEST_F(FragmentShaderEXTGeometryShaderValidationTest, LayerWithoutExtension)
+{
+    const std::string &shaderString =
+        R"(#version 310 es
+        precision mediump float;
+        layout(location = 0) out mediump vec4 fragColor;
+        void main(void)
+        {
+            vec4 data = vec4(0.1, 0.2, 0.3, 0.4);
+            float value = data[gl_Layer % 4];
+            fragColor = vec4(value, 0, 0, 1);
+        })";
 
     if (compile(shaderString))
     {
         FAIL() << "Shader compilation succeeded, expecting failure:\n" << mInfoLog;
     }
 }
 
 // Test that gl_Layer cannot be l-value in fragment shader.
-TEST_F(FragmentShaderOESGeometryShaderValidationTest, AssignValueToLayer)
-{
-    const std::string &shaderString =
-        "#version 310 es\n"
-        "#extension GL_OES_geometry_shader : require\n"
-        "precision mediump float;\n"
-        "layout(location = 0) out mediump vec4 fragColor;\n"
-        "void main(void)\n"
-        "{\n"
-        "    gl_Layer = 1;\n"
-        "    fragColor = vec4(1.0, 0.0, 0.0, 1.0);\n"
-        "}\n";
-
-    if (compile(shaderString))
-    {
-        FAIL() << "Shader compilation succeeded, expecting failure:\n" << mInfoLog;
-    }
-}
-
-// Test that all built-in constants defined in GL_OES_geometry_shader can be used in fragment shader
-// with 'GL_OES_geometry_shader' declared.
-TEST_F(FragmentShaderOESGeometryShaderValidationTest, GeometryShaderBuiltInConstants)
+TEST_F(FragmentShaderEXTGeometryShaderValidationTest, AssignValueToLayer)
+{
+    const std::string &shaderString =
+        R"(#version 310 es
+        #extension GL_EXT_geometry_shader : require
+        precision mediump float;
+        layout(location = 0) out mediump vec4 fragColor;
+        void main(void)
+        {
+            gl_Layer = 1;
+            fragColor = vec4(1.0, 0.0, 0.0, 1.0);
+        })";
+
+    if (compile(shaderString))
+    {
+        FAIL() << "Shader compilation succeeded, expecting failure:\n" << mInfoLog;
+    }
+}
+
+// Test that all built-in constants defined in GL_EXT_geometry_shader can be used in fragment shader
+// with 'GL_EXT_geometry_shader' declared.
+TEST_F(FragmentShaderEXTGeometryShaderValidationTest, GeometryShaderBuiltInConstants)
 {
     const std::string &kShaderHeader =
-        "#version 310 es\n"
-        "#extension GL_OES_geometry_shader : require\n"
-        "precision mediump float;\n"
-        "layout(location = 0) out mediump vec4 fragColor;\n"
-        "void main(void)\n"
-        "{\n"
-        "    int val = ";
+        R"(#version 310 es
+        #extension GL_EXT_geometry_shader : require
+        precision mediump float;
+        layout(location = 0) out mediump vec4 fragColor;
+        void main(void)
+        {
+            int val = )";
 
     const std::array<std::string, 9> kGeometryShaderBuiltinConstants = {{
         "gl_MaxGeometryInputComponents", "gl_MaxGeometryOutputComponents",
         "gl_MaxGeometryImageUniforms", "gl_MaxGeometryTextureImageUnits",
         "gl_MaxGeometryOutputVertices", "gl_MaxGeometryTotalOutputComponents",
         "gl_MaxGeometryUniformComponents", "gl_MaxGeometryAtomicCounters",
         "gl_MaxGeometryAtomicCounterBuffers",
     }};
 
     const std::string &kShaderTail =
-        ";\n"
-        "    fragColor = vec4(1.0, 0.0, 0.0, 1.0);\n"
-        "}\n";
+        R"(;
+            fragColor = vec4(val, 0, 0, 1);
+        })";
 
     for (const std::string &kGSBuiltinConstant : kGeometryShaderBuiltinConstants)
     {
         std::ostringstream ostream;
         ostream << kShaderHeader << kGSBuiltinConstant << kShaderTail;
         if (!compile(ostream.str()))
         {
             FAIL() << "Shader compilation failed, expecting success: \n" << mInfoLog;
         }
     }
 }
 
-// Test that any built-in constants defined in GL_OES_geometry_shader cannot be used in fragment
-// shader without 'GL_OES_geometry_shader' declared.
-TEST_F(FragmentShaderOESGeometryShaderValidationTest,
+// Test that any built-in constants defined in GL_EXT_geometry_shader cannot be used in fragment
+// shader without 'GL_EXT_geometry_shader' declared.
+TEST_F(FragmentShaderEXTGeometryShaderValidationTest,
        GeometryShaderBuiltInConstantsWithoutExtension)
 {
     const std::string &kShaderHeader =
         "#version 310 es\n"
         "precision mediump float;\n"
         "layout(location = 0) out mediump vec4 fragColor;\n"
         "void main(void)\n"
         "{\n"
@@ -4643,53 +4650,53 @@ TEST_F(VertexShaderValidationTest, Inter
         "}\n";
 
     if (compile(shaderString))
     {
         FAIL() << "Shader compilation succeeded, expecting failure:\n" << mInfoLog;
     }
 }
 
-// Test that using shader io blocks without declaration of GL_OES_shader_io_block is not allowed.
+// Test that using shader io blocks without declaration of GL_EXT_shader_io_block is not allowed.
 TEST_F(VertexShaderValidationTest, IOBlockWithoutExtension)
 {
     const std::string &shaderString =
-        "#version 310 es\n"
-        "out block\n"
-        "{\n"
-        "    vec2 value;\n"
-        "} VSOutput[2];\n"
-        "void main()\n"
-        "{\n"
-        "    int i = 0;\n"
-        "    vec2 value1 = VSOutput[i].value;\n"
-        "}\n";
-
-    if (compile(shaderString))
-    {
-        FAIL() << "Shader compilation succeeded, expecting failure:\n" << mInfoLog;
-    }
-}
-
-// Test that using shader io blocks without declaration of GL_OES_shader_io_block is not allowed.
+        R"(#version 310 es
+        out block
+        {
+            vec2 value;
+        } VSOutput[2];
+        void main()
+        {
+            int i = 0;
+            vec2 value1 = VSOutput[i].value;
+        })";
+
+    if (compile(shaderString))
+    {
+        FAIL() << "Shader compilation succeeded, expecting failure:\n" << mInfoLog;
+    }
+}
+
+// Test that using shader io blocks without declaration of GL_EXT_shader_io_block is not allowed.
 TEST_F(FragmentShaderValidationTest, IOBlockWithoutExtension)
 {
     const std::string &shaderString =
-        "#version 310 es\n"
-        "precision mediump float;\n"
-        "in block\n"
-        "{\n"
-        "    vec4 i_color;\n"
-        "} FSInput[2];\n"
-        "out vec4 o_color;\n"
-        "void main()\n"
-        "{\n"
-        "    int i = 0;\n"
-        "    o_color = FSInput[i].i_color;"
-        "}\n";
+        R"(#version 310 es
+        precision mediump float;
+        in block
+        {
+            vec4 i_color;
+        } FSInput[2];
+        out vec4 o_color;
+        void main()
+        {
+            int i = 0;
+            o_color = FSInput[i].i_color;
+        })";
 
     if (compile(shaderString))
     {
         FAIL() << "Shader compilation succeeded, expecting failure:\n" << mInfoLog;
     }
 }
 
 // Test that a shader input with 'flat' qualifier cannot be used as l-value.
@@ -5006,9 +5013,670 @@ TEST_F(VertexShaderValidationTest, Locat
         "void main()\n"
         "{\n"
         "}\n";
 
     if (compile(shaderString))
     {
         FAIL() << "Shader compilation succeeded, expecting failure:\n" << mInfoLog;
     }
-}
\ No newline at end of file
+}
+
+// Test that a block can follow the final case in a switch statement.
+// GLSL ES 3.00.5 section 6 and the grammar suggest that an empty block is a statement.
+TEST_F(FragmentShaderValidationTest, SwitchFinalCaseHasEmptyBlock)
+{
+    const std::string &shaderString =
+        R"(#version 300 es
+
+        precision mediump float;
+        uniform int i;
+        void main()
+        {
+            switch (i)
+            {
+                case 0:
+                    break;
+                default:
+                    {}
+            }
+        })";
+
+    if (!compile(shaderString))
+    {
+        FAIL() << "Shader compilation failed, expecting success:\n" << mInfoLog;
+    }
+}
+
+// Test that an empty declaration can follow the final case in a switch statement.
+TEST_F(FragmentShaderValidationTest, SwitchFinalCaseHasEmptyDeclaration)
+{
+    const std::string &shaderString =
+        R"(#version 300 es
+
+        precision mediump float;
+        uniform int i;
+        void main()
+        {
+            switch (i)
+            {
+                case 0:
+                    break;
+                default:
+                    float;
+            }
+        })";
+
+    if (!compile(shaderString))
+    {
+        FAIL() << "Shader compilation failed, expecting success:\n" << mInfoLog;
+    }
+}
+
+// Test that nothing is needed after the final case in a switch statement in ESSL 3.10.
+TEST_F(FragmentShaderValidationTest, SwitchFinalCaseEmptyESSL310)
+{
+    const std::string &shaderString =
+        R"(#version 310 es
+
+        precision mediump float;
+        uniform int i;
+        void main()
+        {
+            switch (i)
+            {
+                case 0:
+                    break;
+                default:
+            }
+        })";
+
+    if (!compile(shaderString))
+    {
+        FAIL() << "Shader compilation failed, expecting success:\n" << mInfoLog;
+    }
+}
+
+// Test that fragment shader cannot declare unsized inputs.
+TEST_F(FragmentShaderValidationTest, UnsizedInputs)
+{
+    const std::string &shaderString =
+        "#version 310 es\n"
+        "precision mediump float;\n"
+        "in float i_value[];\n"
+        "void main()\n"
+        "{\n"
+        "}\n";
+
+    if (compile(shaderString))
+    {
+        FAIL() << "Shader compilation succeeded, expecting failure:\n" << mInfoLog;
+    }
+}
+
+// Test that unsized struct members are not allowed.
+TEST_F(FragmentShaderValidationTest, UnsizedStructMember)
+{
+    const std::string &shaderString =
+        R"(#version 300 es
+
+        precision highp float;
+        out vec4 color;
+
+        struct S
+        {
+            int[] foo;
+        };
+
+        void main()
+        {
+            color = vec4(1.0);
+        })";
+
+    if (compile(shaderString))
+    {
+        FAIL() << "Shader compilation succeeded, expecting failure:\n" << mInfoLog;
+    }
+}
+
+// Test that unsized parameters without a name are not allowed.
+// GLSL ES 3.10 section 6.1 Function Definitions.
+TEST_F(FragmentShaderValidationTest, UnsizedNamelessParameter)
+{
+    const std::string &shaderString =
+        R"(#version 300 es
+
+        precision highp float;
+        out vec4 color;
+
+        void foo(int[]);
+
+        void main()
+        {
+            color = vec4(1.0);
+        })";
+
+    if (compile(shaderString))
+    {
+        FAIL() << "Shader compilation succeeded, expecting failure:\n" << mInfoLog;
+    }
+}
+
+// Test that partially unsized array of arrays constructor sizes are validated.
+TEST_F(FragmentShaderValidationTest, PartiallyUnsizedArrayOfArraysConstructor)
+{
+    const std::string &shaderString =
+        R"(#version 310 es
+
+        precision highp float;
+        out vec4 color;
+
+        void main()
+        {
+            int a[][] = int[2][](int[1](1));
+            color = vec4(a[0][0]);
+        })";
+
+    if (compile(shaderString))
+    {
+        FAIL() << "Shader compilation succeeded, expecting failure:\n" << mInfoLog;
+    }
+}
+
+// Test that duplicate field names in a struct declarator list are validated.
+TEST_F(FragmentShaderValidationTest, DuplicateFieldNamesInStructDeclaratorList)
+{
+    const std::string &shaderString =
+        R"(precision mediump float;
+
+        struct S {
+            float f, f;
+        };
+
+        void main()
+        {
+            gl_FragColor = vec4(1.0);
+        })";
+
+    if (compile(shaderString))
+    {
+        FAIL() << "Shader compilation succeeded, expecting failure:\n" << mInfoLog;
+    }
+}
+
+// Test that an empty statement is not allowed in switch before the first case.
+TEST_F(FragmentShaderValidationTest, EmptyStatementInSwitchBeforeFirstCase)
+{
+    const std::string &shaderString =
+        R"(#version 300 es
+
+        precision mediump float;
+        uniform int u_zero;
+        out vec4 my_FragColor;
+
+        void main()
+        {
+            switch(u_zero)
+            {
+                    ;
+                case 0:
+                    my_FragColor = vec4(0.0);
+                default:
+                    my_FragColor = vec4(1.0);
+            }
+        })";
+
+    if (compile(shaderString))
+    {
+        FAIL() << "Shader compilation succeeded, expecting failure:\n" << mInfoLog;
+    }
+}
+
+// Test that a nameless struct definition is not allowed as a function parameter type.
+// ESSL 3.00.6 section 12.10. ESSL 3.10 January 2016 section 13.10.
+TEST_F(FragmentShaderValidationTest, NamelessStructDefinitionAsParameterType)
+{
+    const std::string &shaderString =
+        R"(#version 300 es
+
+        precision highp float;
+        out vec4 my_FragColor;
+
+        float foo(struct { float field; } f)
+        {
+            return f.field;
+        }
+
+        void main()
+        {
+            my_FragColor = vec4(0, 1, 0, 1);
+        })";
+
+    if (compile(shaderString))
+    {
+        FAIL() << "Shader compilation succeeded, expecting failure:\n" << mInfoLog;
+    }
+}
+
+// Test that a named struct definition is not allowed as a function parameter type.
+// ESSL 3.00.6 section 12.10. ESSL 3.10 January 2016 section 13.10.
+TEST_F(FragmentShaderValidationTest, NamedStructDefinitionAsParameterType)
+{
+    const std::string &shaderString =
+        R"(#version 300 es
+
+        precision highp float;
+        out vec4 my_FragColor;
+
+        float foo(struct S { float field; } f)
+        {
+            return f.field;
+        }
+
+        void main()
+        {
+            my_FragColor = vec4(0, 1, 0, 1);
+        })";
+
+    if (compile(shaderString))
+    {
+        FAIL() << "Shader compilation succeeded, expecting failure:\n" << mInfoLog;
+    }
+}
+
+// Test that a named struct definition is not allowed as a function parameter type.
+// ESSL 3.00.6 section 12.10. ESSL 3.10 January 2016 section 13.10.
+TEST_F(FragmentShaderValidationTest, StructDefinitionAsTypeOfParameterWithoutName)
+{
+    const std::string &shaderString =
+        R"(#version 300 es
+
+        precision highp float;
+        out vec4 my_FragColor;
+
+        float foo(struct S { float field; } /* no parameter name */)
+        {
+            return 1.0;
+        }
+
+        void main()
+        {
+            my_FragColor = vec4(0, 1, 0, 1);
+        })";
+
+    if (compile(shaderString))
+    {
+        FAIL() << "Shader compilation succeeded, expecting failure:\n" << mInfoLog;
+    }
+}
+
+// Test that an unsized const array doesn't assert.
+TEST_F(FragmentShaderValidationTest, UnsizedConstArray)
+{
+    const std::string &shaderString =
+        R"(#version 300 es
+
+        void main()
+        {
+            const int t[];
+            t[0];
+        })";
+
+    if (compile(shaderString))
+    {
+        FAIL() << "Shader compilation succeeded, expecting failure:\n" << mInfoLog;
+    }
+}
+
+// Test that the value passed to the mem argument of an atomic memory function can be a shared
+// variable.
+TEST_F(ComputeShaderValidationTest, AtomicAddWithSharedVariable)
+{
+    const std::string &shaderString =
+        R"(#version 310 es
+
+        layout(local_size_x = 5) in;
+        shared uint myShared;
+
+        void main() {
+            atomicAdd(myShared, 2u);
+        })";
+
+    if (!compile(shaderString))
+    {
+        FAIL() << "Shader compilation failed, expecting success:\n" << mInfoLog;
+    }
+}
+
+// Test that it is acceptable to pass an element of an array to the mem argument of an atomic memory
+// function, as long as the underlying array is a buffer or shared variable.
+TEST_F(ComputeShaderValidationTest, AtomicAddWithSharedVariableArray)
+{
+    const std::string &shaderString =
+        R"(#version 310 es
+
+        layout(local_size_x = 5) in;
+        shared uint myShared[2];
+
+        void main() {
+            atomicAdd(myShared[0], 2u);
+        })";
+
+    if (!compile(shaderString))
+    {
+        FAIL() << "Shader compilation failed, expecting success:\n" << mInfoLog;
+    }
+}
+
+// Test that it is acceptable to pass a single component of a vector to the mem argument of an
+// atomic memory function, as long as the underlying vector is a buffer or shared variable.
+TEST_F(ComputeShaderValidationTest, AtomicAddWithSharedVariableVector)
+{
+    const std::string &shaderString =
+        R"(#version 310 es
+
+        layout(local_size_x = 5) in;
+        shared uvec4 myShared;
+
+        void main() {
+            atomicAdd(myShared[0], 2u);
+        })";
+
+    if (!compile(shaderString))
+    {
+        FAIL() << "Shader compilation failed, expecting success:\n" << mInfoLog;
+    }
+}
+
+// Test that the value passed to the mem argument of an atomic memory function can be a buffer
+// variable.
+TEST_F(FragmentShaderValidationTest, AtomicAddWithBufferVariable)
+{
+    const std::string &shaderString =
+        R"(#version 310 es
+
+        layout(std140) buffer bufferName1{
+            uint u1;
+        };
+
+        void main()
+        {
+            atomicAdd(u1, 2u);
+        })";
+
+    if (!compile(shaderString))
+    {
+        FAIL() << "Shader compilation failed, expecting success:\n" << mInfoLog;
+    }
+}
+
+// Test that it is acceptable to pass an element of an array to the mem argument of an atomic memory
+// function, as long as the underlying array is a buffer or shared variable.
+TEST_F(FragmentShaderValidationTest, AtomicAddWithBufferVariableArrayElement)
+{
+    const std::string &shaderString =
+        R"(#version 310 es
+
+        layout(std140) buffer bufferName1{
+            uint u1[2];
+        };
+
+        void main()
+        {
+            atomicAdd(u1[0], 2u);
+        })";
+
+    if (!compile(shaderString))
+    {
+        FAIL() << "Shader compilation failed, expecting success:\n" << mInfoLog;
+    }
+}
+
+// Test that it is acceptable to pass a member of a shader storage block instance to the mem
+// argument of an atomic memory function.
+TEST_F(FragmentShaderValidationTest, AtomicAddWithBufferVariableInBlockInstance)
+{
+    const std::string &shaderString =
+        R"(#version 310 es
+
+        layout(std140) buffer bufferName{
+            uint u1;
+        } instanceName;
+
+        void main()
+        {
+            atomicAdd(instanceName.u1, 2u);
+        })";
+
+    if (!compile(shaderString))
+    {
+        FAIL() << "Shader compilation failed, expecting success:\n" << mInfoLog;
+    }
+}
+
+// Test that it is acceptable to pass a member of a shader storage block instance array to the mem
+// argument of an atomic memory function.
+TEST_F(FragmentShaderValidationTest, AtomicAddWithBufferVariableInBlockInstanceArray)
+{
+    const std::string &shaderString =
+        R"(#version 310 es
+
+        layout(std140) buffer bufferName{
+            uint u1;
+        } instanceName[1];
+
+        void main()
+        {
+            atomicAdd(instanceName[0].u1, 2u);
+        })";
+
+    if (!compile(shaderString))
+    {
+        FAIL() << "Shader compilation failed, expecting success:\n" << mInfoLog;
+    }
+}
+
+// Test that it is acceptable to pass an element of an array  of a shader storage block instance to
+// the mem argument of an atomic memory function.
+TEST_F(FragmentShaderValidationTest, AtomicAddWithElementOfArrayInBlockInstance)
+{
+    const std::string &shaderString =
+        R"(#version 310 es
+
+        layout(std140) buffer blockName {
+            uint data[2];
+        } instanceName;
+
+        void main()
+        {
+            atomicAdd(instanceName.data[0], 2u);
+        })";
+
+    if (!compile(shaderString))
+    {
+        FAIL() << "Shader compilation failed, expecting success:\n" << mInfoLog;
+    }
+}
+
+// Test that it is not allowed to pass an atomic counter variable to the mem argument of an atomic
+// memory function.
+TEST_F(FragmentShaderValidationTest, AtomicAddWithAtomicCounter)
+{
+    const std::string &shaderString =
+        R"(#version 310 es
+
+        layout(binding = 0, offset = 4) uniform atomic_uint ac;
+
+        void main()
+        {
+            atomicAdd(ac, 2u);
+        })";
+
+    if (compile(shaderString))
+    {
+        FAIL() << "Shader compilation succeeded, expecting failure:\n" << mInfoLog;
+    }
+}
+
+// Test that it is not allowed to pass an element of an atomic counter array to the mem argument of
+// an atomic memory function.
+TEST_F(FragmentShaderValidationTest, AtomicAddWithAtomicCounterArray)
+{
+    const std::string &shaderString =
+        R"(#version 310 es
+
+        layout(binding = 0, offset = 4) uniform atomic_uint ac[2];
+
+        void main()
+        {
+            atomicAdd(ac[0], 2u);
+        })";
+
+    if (compile(shaderString))
+    {
+        FAIL() << "Shader compilation succeeded, expecting failure:\n" << mInfoLog;
+    }
+}
+
+// Test that it is not allowed to pass a local uint value to the mem argument of an atomic memory
+// function.
+TEST_F(FragmentShaderValidationTest, AtomicAddWithNonStorageVariable)
+{
+    const std::string &shaderString =
+        R"(#version 310 es
+
+        void main()
+        {
+            uint test = 1u;
+            atomicAdd(test, 2u);
+        })";
+
+    if (compile(shaderString))
+    {
+        FAIL() << "Shader compilation succeeded, expecting failure:\n" << mInfoLog;
+    }
+}
+
+// Test that negative indexing of a matrix doesn't result in an assert.
+TEST_F(FragmentShaderValidationTest, MatrixNegativeIndex)
+{
+    const std::string &shaderString =
+        R"(
+        precision mediump float;
+
+        void main()
+        {
+            gl_FragColor = mat4(1.0)[-1];
+        })";
+
+    if (compile(shaderString))
+    {
+        FAIL() << "Shader compilation succeeded, expecting failure:\n" << mInfoLog;
+    }
+}
+
+// Global variable initializers need to be constant expressions. Test with assigning a ternary
+// expression that ANGLE can fold.
+TEST_F(FragmentShaderValidationTest, AssignConstantFoldedFromNonConstantTernaryToGlobal)
+{
+    const std::string &shaderString =
+        R"(#version 300 es
+        precision mediump float;
+
+        uniform float u;
+        float f = true ? 1.0 : u;
+
+        out vec4 my_FragColor;
+
+        void main()
+        {
+           my_FragColor = vec4(f);
+        })";
+    if (compile(shaderString))
+    {
+        FAIL() << "Shader compilation succeeded, expecting failure:\n" << mInfoLog;
+    }
+}
+
+// Global variable initializers need to be constant expressions. Test with assigning a ternary
+// expression that ANGLE can fold.
+TEST_F(FragmentShaderValidationTest,
+       AssignConstantArrayVariableFoldedFromNonConstantTernaryToGlobal)
+{
+    const std::string &shaderString =
+        R"(#version 300 es
+        precision mediump float;
+
+        uniform float u[2];
+        const float c[2] = float[2](1.0, 2.0);
+        float f[2] = true ? c : u;
+
+        out vec4 my_FragColor;
+
+        void main()
+        {
+           my_FragColor = vec4(f[0], f[1], 0.0, 1.0);
+        })";
+    if (compile(shaderString))
+    {
+        FAIL() << "Shader compilation succeeded, expecting failure:\n" << mInfoLog;
+    }
+}
+
+// Test going past the struct nesting limit while simultaneously using invalid nested struct
+// definitions. This makes sure that the code generating an error message about going past the
+// struct nesting limit does not access the name of a nameless struct definition.
+TEST_F(WebGL1FragmentShaderValidationTest, StructNestingLimitWithNestedStructDefinitions)
+{
+    const std::string &shaderString =
+        R"(
+        precision mediump float;
+
+        struct
+        {
+            struct
+            {
+                struct
+                {
+                    struct
+                    {
+                        struct
+                        {
+                            struct
+                            {
+                                float f;
+                            } s5;
+                        } s4;
+                    } s3;
+                } s2;
+            } s1;
+        } s0;
+
+        void main(void)
+        {
+            gl_FragColor = vec4(s0.s1.s2.s3.s4.s5.f);
+        })";
+    if (compile(shaderString))
+    {
+        FAIL() << "Shader compilation succeeded, expecting failure:\n" << mInfoLog;
+    }
+}
+
+// Test that the result of a sequence operator is not a constant-expression.
+// ESSL 3.00 section 12.43.
+TEST_F(FragmentShaderValidationTest, CommaReturnsNonConstant)
+{
+    const std::string &shaderString =
+        R"(#version 300 es
+
+        precision highp float;
+        out vec4 my_FragColor;
+
+        void main(void)
+        {
+            const int i = (0, 0);
+            my_FragColor = vec4(i);
+        })";
+    if (compile(shaderString))
+    {
+        FAIL() << "Shader compilation succeeded, expecting failure:\n" << mInfoLog;
+    }
+}
--- a/gfx/angle/src/tests/compiler_tests/ShaderVariable_test.cpp
+++ b/gfx/angle/src/tests/compiler_tests/ShaderVariable_test.cpp
@@ -20,34 +20,32 @@ TEST(ShaderVariableTest, FindInfoByMappe
     // struct A {
     //   float x[2];
     //   vec3 y;
     // };
     // struct B {
     //   A a[3];
     // };
     // B uni[2];
-    ShaderVariable uni;
-    uni.arraySize = 2;
+    ShaderVariable uni(0, 2);
     uni.name = "uni";
     uni.mappedName = "m_uni";
     uni.structName = "B";
     {
-        ShaderVariable a;
-        a.arraySize = 3;
+        ShaderVariable a(0, 3);
         a.name = "a";
         a.mappedName = "m_a";
         a.structName = "A";
         {
             ShaderVariable x(GL_FLOAT, 2);
             x.name = "x";
             x.mappedName = "m_x";
             a.fields.push_back(x);
 
-            ShaderVariable y(GL_FLOAT_VEC3, 0);
+            ShaderVariable y(GL_FLOAT_VEC3);
             y.name = "y";
             y.mappedName = "m_y";
             a.fields.push_back(y);
         }
         uni.fields.push_back(a);
     }
 
     const ShaderVariable *leafVar = nullptr;
@@ -89,97 +87,93 @@ TEST(ShaderVariableTest, FindInfoByMappe
 TEST(ShaderVariableTest, IsSameUniformWithDifferentFieldOrder)
 {
     // struct A {
     //   float x;
     //   float y;
     // };
     // uniform A uni;
     Uniform vx_a;
-    vx_a.arraySize = 0;
     vx_a.name = "uni";
     vx_a.mappedName = "m_uni";
     vx_a.structName = "A";
     {
-        ShaderVariable x(GL_FLOAT, 0);
+        ShaderVariable x(GL_FLOAT);
         x.name = "x";
         x.mappedName = "m_x";
         vx_a.fields.push_back(x);
 
-        ShaderVariable y(GL_FLOAT, 0);
+        ShaderVariable y(GL_FLOAT);
         y.name = "y";
         y.mappedName = "m_y";
         vx_a.fields.push_back(y);
     }
 
     // struct A {
     //   float y;
     //   float x;
     // };
     // uniform A uni;
     Uniform fx_a;
-    fx_a.arraySize = 0;
     fx_a.name = "uni";
     fx_a.mappedName = "m_uni";
     fx_a.structName = "A";
     {
-        ShaderVariable y(GL_FLOAT, 0);
+        ShaderVariable y(GL_FLOAT);
         y.name = "y";
         y.mappedName = "m_y";
         fx_a.fields.push_back(y);
 
-        ShaderVariable x(GL_FLOAT, 0);
+        ShaderVariable x(GL_FLOAT);
         x.name = "x";
         x.mappedName = "m_x";
         fx_a.fields.push_back(x);
     }
 
     EXPECT_FALSE(vx_a.isSameUniformAtLinkTime(fx_a));
 }
 
 TEST(ShaderVariableTest, IsSameUniformWithDifferentStructNames)
 {
     // struct A {
     //   float x;
     //   float y;
     // };
     // uniform A uni;
     Uniform vx_a;
-    vx_a.arraySize = 0;
     vx_a.name = "uni";
     vx_a.mappedName = "m_uni";
     vx_a.structName = "A";
     {
-        ShaderVariable x(GL_FLOAT, 0);
+        ShaderVariable x(GL_FLOAT);
         x.name = "x";
         x.mappedName = "m_x";
         vx_a.fields.push_back(x);
 
-        ShaderVariable y(GL_FLOAT, 0);
+        ShaderVariable y(GL_FLOAT);
         y.name = "y";
         y.mappedName = "m_y";
         vx_a.fields.push_back(y);
     }
 
     // struct B {
     //   float x;
     //   float y;
     // };
     // uniform B uni;
     Uniform fx_a;
-    fx_a.arraySize = 0;
     fx_a.name = "uni";
     fx_a.mappedName = "m_uni";
     {
-        ShaderVariable x(GL_FLOAT, 0);
+        ShaderVariable x(GL_FLOAT);
         x.name = "x";
         x.mappedName = "m_x";
         fx_a.fields.push_back(x);
 
-        ShaderVariable y(GL_FLOAT, 0);
+        ShaderVariable y(GL_FLOAT);
         y.name = "y";
         y.mappedName = "m_y";
         fx_a.fields.push_back(y);
     }
 
     fx_a.structName = "B";
     EXPECT_FALSE(vx_a.isSameUniformAtLinkTime(fx_a));
 
@@ -190,27 +184,25 @@ TEST(ShaderVariableTest, IsSameUniformWi
     EXPECT_FALSE(vx_a.isSameUniformAtLinkTime(fx_a));
 }
 
 TEST(ShaderVariableTest, IsSameVaryingWithDifferentInvariance)
 {
     // invariant varying float vary;
     Varying vx;
     vx.type = GL_FLOAT;
-    vx.arraySize = 0;
     vx.precision = GL_MEDIUM_FLOAT;
     vx.name = "vary";
     vx.mappedName = "m_vary";
     vx.staticUse = true;
     vx.isInvariant = true;
 
     // varying float vary;
     Varying fx;
     fx.type = GL_FLOAT;
-    fx.arraySize = 0;
     fx.precision = GL_MEDIUM_FLOAT;
     fx.name = "vary";
     fx.mappedName = "m_vary";
     fx.staticUse = true;
     fx.isInvariant = false;
 
     // Default to ESSL1 behavior: invariance must match
     EXPECT_FALSE(vx.isSameVaryingAtLinkTime(fx));
@@ -255,28 +247,27 @@ TEST(ShaderVariableTest, IllegalInvarian
 {
     ShBuiltInResources resources;
     sh::InitBuiltInResources(&resources);
 
     ShHandle compiler = sh::ConstructCompiler(GL_VERTEX_SHADER, SH_GLES2_SPEC,
                                               SH_GLSL_COMPATIBILITY_OUTPUT, &resources);
     EXPECT_NE(static_cast<ShHandle>(0), compiler);
 
-    const char *program1[] =
-    {
-        "void foo() {\n"
-        "  vec4 v;\n"
-        "}\n"
-        "varying vec4 v_varying;\n"
-        "invariant v_varying;\n"
-        "void main() {\n"
-        "  foo();\n"
-        "  gl_Position = v_varying;\n"
-        "}"
-    };
+    const char *program1[] = {
+        R"(void foo()
+        {
+        }
+        varying vec4 v_varying;
+        invariant v_varying;
+        void main()
+        {
+           foo();
+           gl_Position = v_varying;
+        })"};
     const char *program2[] =
     {
         "varying vec4 v_varying;\n"
         "void foo() {\n"
         "  invariant v_varying;\n"
         "}\n"
         "void main() {\n"
         "  foo();\n"
@@ -314,24 +305,28 @@ TEST(ShaderVariableTest, InvariantLeakAc
         "}"
     };
 
     EXPECT_TRUE(sh::Compile(compiler, program1, 1, SH_VARIABLES));
     const std::vector<sh::Varying> *varyings = sh::GetOutputVaryings(compiler);
     for (const sh::Varying &varying : *varyings)
     {
         if (varying.name == "v_varying")
+        {
             EXPECT_TRUE(varying.isInvariant);
+        }
     }
     EXPECT_TRUE(sh::Compile(compiler, program2, 1, SH_VARIABLES));
     varyings = sh::GetOutputVaryings(compiler);
     for (const sh::Varying &varying : *varyings)
     {
         if (varying.name == "v_varying")
+        {
             EXPECT_FALSE(varying.isInvariant);
+        }
     }
     sh::Destruct(compiler);
 }
 
 TEST(ShaderVariableTest, GlobalInvariantLeakAcrossShaders)
 {
     ShBuiltInResources resources;
     sh::InitBuiltInResources(&resources);
@@ -356,24 +351,28 @@ TEST(ShaderVariableTest, GlobalInvariant
         "}"
     };
 
     EXPECT_TRUE(sh::Compile(compiler, program1, 1, SH_VARIABLES));
     const std::vector<sh::Varying> *varyings = sh::GetOutputVaryings(compiler);
     for (const sh::Varying &varying : *varyings)
     {
         if (varying.name == "v_varying")
+        {
             EXPECT_TRUE(varying.isInvariant);
+        }
     }
     EXPECT_TRUE(sh::Compile(compiler, program2, 1, SH_VARIABLES));
     varyings = sh::GetOutputVaryings(compiler);
     for (const sh::Varying &varying : *varyings)
     {
         if (varying.name == "v_varying")
+        {
             EXPECT_FALSE(varying.isInvariant);
+        }
     }
     sh::Destruct(compiler);
 }
 
 TEST(ShaderVariableTest, BuiltinInvariantVarying)
 {
 
     ShBuiltInResources resources;
@@ -404,46 +403,48 @@ TEST(ShaderVariableTest, BuiltinInvarian
         "}"
     };
 
     EXPECT_TRUE(sh::Compile(compiler, program1, 1, SH_VARIABLES));
     const std::vector<sh::Varying> *varyings = sh::GetOutputVaryings(compiler);
     for (const sh::Varying &varying : *varyings)
     {
         if (varying.name == "gl_Position")
+        {
             EXPECT_TRUE(varying.isInvariant);
+        }
     }
     EXPECT_TRUE(sh::Compile(compiler, program2, 1, SH_VARIABLES));
     varyings = sh::GetOutputVaryings(compiler);
     for (const sh::Varying &varying : *varyings)
     {
         if (varying.name == "gl_Position")
+        {
             EXPECT_FALSE(varying.isInvariant);
+        }
     }
     EXPECT_FALSE(sh::Compile(compiler, program3, 1, SH_VARIABLES));
     sh::Destruct(compiler);
 }
 
 // Verify in ES3.1 two varyings with either same name or same declared location can match.
 TEST(ShaderVariableTest, IsSameVaryingWithDifferentName)
 {
     // Varying float vary1;
     Varying vx;
     vx.type        = GL_FLOAT;
-    vx.arraySize   = 0;
     vx.precision   = GL_MEDIUM_FLOAT;
     vx.name        = "vary1";
     vx.mappedName  = "m_vary1";
     vx.staticUse   = true;
     vx.isInvariant = false;
 
     // Varying float vary2;
     Varying fx;
     fx.type        = GL_FLOAT;
-    fx.arraySize   = 0;
     fx.precision   = GL_MEDIUM_FLOAT;
     fx.name        = "vary2";
     fx.mappedName  = "m_vary2";
     fx.staticUse   = true;
     fx.isInvariant = false;
 
     // ESSL3 behavior: name must match
     EXPECT_FALSE(vx.isSameVaryingAtLinkTime(fx, 300));
--- a/gfx/angle/src/tests/compiler_tests/TypeTracking_test.cpp
+++ b/gfx/angle/src/tests/compiler_tests/TypeTracking_test.cpp
@@ -382,17 +382,17 @@ TEST_F(TypeTrackingTest, UnpackHalfResul
 TEST_F(TypeTrackingTest, BuiltInAbsSignFunctionFloatResultTypeAndPrecision)
 {
     const std::string &shaderString =
         "precision mediump float;\n"
         "uniform float fval1;\n"
         "void main() {\n"
         "   float fval2 = abs(fval1);\n"
         "   float fval3 = sign(fval1);\n"
-        "   gl_FragColor = vec4(fval1, 0.0, 0.0, 1.0); \n"
+        "   gl_FragColor = vec4(fval1, fval2, fval3, 1.0); \n"
         "}\n";
     compile(shaderString);
     ASSERT_FALSE(foundErrorInIntermediateTree());
     ASSERT_TRUE(foundInIntermediateTree("abs (mediump float)"));
     ASSERT_TRUE(foundInIntermediateTree("sign (mediump float)"));
 }
 
 TEST_F(TypeTrackingTest, BuiltInAbsSignFunctionIntResultTypeAndPrecision)
@@ -401,17 +401,17 @@ TEST_F(TypeTrackingTest, BuiltInAbsSignF
         "#version 300 es\n"
         "precision mediump float;\n"
         "precision mediump int;\n"
         "uniform int ival1;\n"
         "out vec4 my_FragColor;\n"
         "void main() {\n"
         "   int ival2 = abs(ival1);\n"
         "   int ival3 = sign(ival1);\n"
-        "   my_FragColor = vec4(0.0, 0.0, 0.0, 1.0); \n"
+        "   my_FragColor = vec4(ival2, ival3, 0, 1); \n"
         "}\n";
     compile(shaderString);
     ASSERT_FALSE(foundErrorInIntermediateTree());
     ASSERT_TRUE(foundInIntermediateTree("abs (mediump int)"));
     ASSERT_TRUE(foundInIntermediateTree("sign (mediump int)"));
 }
 
 TEST_F(TypeTrackingTest, BuiltInFloatBitsToIntResultTypeAndPrecision)
@@ -421,17 +421,17 @@ TEST_F(TypeTrackingTest, BuiltInFloatBit
         "#version 300 es\n"
         "precision mediump float;\n"
         "precision mediump int;\n"
         "uniform float f;\n"
         "out vec4 my_FragColor;\n"
         "void main() {\n"
         "   int i = floatBitsToInt(f);\n"
         "   uint u = floatBitsToUint(f);\n"
-        "   my_FragColor = vec4(0.0, 0.0, 0.0, 1.0); \n"
+        "   my_FragColor = vec4(i, int(u), 0, 1); \n"
         "}\n";
     compile(shaderString);
     ASSERT_FALSE(foundErrorInIntermediateTree());
     ASSERT_TRUE(foundInIntermediateTree("floatBitsToInt (highp int)"));
     ASSERT_TRUE(foundInIntermediateTree("floatBitsToUint (highp uint)"));
 }
 
 TEST_F(TypeTrackingTest, BuiltInIntBitsToFloatResultTypeAndPrecision)
--- a/gfx/angle/src/tests/compiler_tests/VariablePacker_test.cpp
+++ b/gfx/angle/src/tests/compiler_tests/VariablePacker_test.cpp
@@ -55,72 +55,83 @@ static sh::GLenum types[] = {
     GL_UNSIGNED_INT_SAMPLER_CUBE,      // 39
     GL_UNSIGNED_INT_SAMPLER_3D,        // 40
     GL_UNSIGNED_INT_SAMPLER_2D_ARRAY,  // 41
 };
 
 static sh::GLenum nonSqMatTypes[] = {GL_FLOAT_MAT2x3, GL_FLOAT_MAT2x4, GL_FLOAT_MAT3x2,
                                      GL_FLOAT_MAT3x4, GL_FLOAT_MAT4x2, GL_FLOAT_MAT4x3};
 
+// Creates either a single variable or an array variable depending on numVars.
+sh::ShaderVariable CreateShaderVariable(sh::GLenum type, int numVars)
+{
+    ASSERT(numVars != 0);
+    if (numVars == 1)
+    {
+        return sh::ShaderVariable(type);
+    }
+    return sh::ShaderVariable(type, numVars);
+}
+
 }  // anonymous namespace
 
 TEST(VariablePacking, Pack)
 {
     std::vector<sh::ShaderVariable> vars;
     const int kMaxRows = 16;
     // test no vars.
     EXPECT_TRUE(CheckVariablesInPackingLimits(kMaxRows, vars));
 
     for (size_t tt = 0; tt < ArraySize(types); ++tt)
     {
         sh::GLenum type            = types[tt];
-        int num_rows               = sh::GetVariablePackingRows(type);
-        int num_components_per_row = sh::GetVariablePackingComponentsPerRow(type);
+        int num_rows               = sh::GetTypePackingRows(type);
+        int num_components_per_row = sh::GetTypePackingComponentsPerRow(type);
         // Check 1 of the type.
         vars.clear();
-        vars.push_back(sh::ShaderVariable(type, 0));
+        vars.push_back(sh::ShaderVariable(type));
         EXPECT_TRUE(CheckVariablesInPackingLimits(kMaxRows, vars));
 
         // Check exactly the right amount of 1 type as an array.
         int num_vars = kMaxRows / num_rows;
         vars.clear();
-        vars.push_back(sh::ShaderVariable(type, num_vars == 1 ? 0 : num_vars));
+        vars.push_back(CreateShaderVariable(type, num_vars));
         EXPECT_TRUE(CheckVariablesInPackingLimits(kMaxRows, vars));
 
         // test too many
         vars.clear();
-        vars.push_back(sh::ShaderVariable(type, num_vars == 0 ? 0 : (num_vars + 1)));
+        vars.push_back(CreateShaderVariable(type, num_vars + 1));
         EXPECT_FALSE(CheckVariablesInPackingLimits(kMaxRows, vars));
 
         // Check exactly the right amount of 1 type as individual vars.
         num_vars =
             kMaxRows / num_rows * ((num_components_per_row > 2) ? 1 : (4 / num_components_per_row));
         vars.clear();
         for (int ii = 0; ii < num_vars; ++ii)
         {
-            vars.push_back(sh::ShaderVariable(type, 0));
+            vars.push_back(sh::ShaderVariable(type));
         }
         EXPECT_TRUE(CheckVariablesInPackingLimits(kMaxRows, vars));
 
         // Check 1 too many.
-        vars.push_back(sh::ShaderVariable(type, 0));
+        vars.push_back(sh::ShaderVariable(type));
         EXPECT_FALSE(CheckVariablesInPackingLimits(kMaxRows, vars));
     }
 
     // Test example from GLSL ES 3.0 spec chapter 11.
     vars.clear();
-    vars.push_back(sh::ShaderVariable(GL_FLOAT_VEC4, 0));
-    vars.push_back(sh::ShaderVariable(GL_FLOAT_MAT3, 0));
-    vars.push_back(sh::ShaderVariable(GL_FLOAT_MAT3, 0));
+    vars.push_back(sh::ShaderVariable(GL_FLOAT_VEC4));
+    vars.push_back(sh::ShaderVariable(GL_FLOAT_MAT3));
+    vars.push_back(sh::ShaderVariable(GL_FLOAT_MAT3));
     vars.push_back(sh::ShaderVariable(GL_FLOAT_VEC2, 6));
     vars.push_back(sh::ShaderVariable(GL_FLOAT_VEC2, 4));
-    vars.push_back(sh::ShaderVariable(GL_FLOAT_VEC2, 0));
+    vars.push_back(sh::ShaderVariable(GL_FLOAT_VEC2));
     vars.push_back(sh::ShaderVariable(GL_FLOAT, 3));
     vars.push_back(sh::ShaderVariable(GL_FLOAT, 2));
-    vars.push_back(sh::ShaderVariable(GL_FLOAT, 0));
+    vars.push_back(sh::ShaderVariable(GL_FLOAT));
     EXPECT_TRUE(CheckVariablesInPackingLimits(kMaxRows, vars));
 }
 
 TEST(VariablePacking, PackSizes)
 {
     for (size_t tt = 0; tt < ArraySize(types); ++tt)
     {
         sh::GLenum type = types[tt];
@@ -134,18 +145,18 @@ TEST(VariablePacking, PackSizes)
         }
         else if (gl::IsMatrixType(type))
         {
             int squareSize = std::max(gl::VariableRowCount(type), gl::VariableColumnCount(type));
             expectedComponents = squareSize;
             expectedRows       = squareSize;
         }
 
-        EXPECT_EQ(expectedComponents, sh::GetVariablePackingComponentsPerRow(type));
-        EXPECT_EQ(expectedRows, sh::GetVariablePackingRows(type));
+        EXPECT_EQ(expectedComponents, sh::GetTypePackingComponentsPerRow(type));
+        EXPECT_EQ(expectedRows, sh::GetTypePackingRows(type));
     }
 }
 
 // Check special assumptions about packing non-square mats
 TEST(VariablePacking, NonSquareMats)
 {
 
     for (size_t mt = 0; mt < ArraySize(nonSqMatTypes); ++mt)
@@ -153,31 +164,31 @@ TEST(VariablePacking, NonSquareMats)
 
         sh::GLenum type = nonSqMatTypes[mt];
 
         int rows       = gl::VariableRowCount(type);
         int cols       = gl::VariableColumnCount(type);
         int squareSize = std::max(rows, cols);
 
         std::vector<sh::ShaderVariable> vars;
-        vars.push_back(sh::ShaderVariable(type, 0));
+        vars.push_back(sh::ShaderVariable(type));
 
         // Fill columns
         for (int row = 0; row < squareSize; row++)
         {
             for (int col = squareSize; col < 4; ++col)
             {
-                vars.push_back(sh::ShaderVariable(GL_FLOAT, 0));
+                vars.push_back(sh::ShaderVariable(GL_FLOAT));
             }
         }
 
         EXPECT_TRUE(CheckVariablesInPackingLimits(squareSize, vars));
 
         // and one scalar and packing should fail
-        vars.push_back(sh::ShaderVariable(GL_FLOAT, 0));
+        vars.push_back(sh::ShaderVariable(GL_FLOAT));
         EXPECT_FALSE(CheckVariablesInPackingLimits(squareSize, vars));
     }
 }
 
 // Scalar type variables can be packed sharing rows with other variables.
 TEST(VariablePacking, ReuseRows)
 {
     std::vector<sh::ShaderVariable> vars;
@@ -213,27 +224,27 @@ TEST(VariablePacking, ReuseRows)
 // Check the packer supports and flattens structures.
 TEST(VariablePacking, Struct)
 {
     std::vector<sh::ShaderVariable> fields;
     const int kMaxRows = 16;
 
     // Test example from GLSL ES 3.0 spec chapter 11, but with structs
     std::vector<sh::ShaderVariable> vars;
-    vars.push_back(sh::ShaderVariable(GL_NONE, 0));
+    vars.push_back(sh::ShaderVariable(GL_NONE));
 
     sh::ShaderVariable &parentStruct = vars[0];
-    parentStruct.fields.push_back(sh::ShaderVariable(GL_FLOAT_VEC4, 0));
-    parentStruct.fields.push_back(sh::ShaderVariable(GL_FLOAT_MAT3, 0));
+    parentStruct.fields.push_back(sh::ShaderVariable(GL_FLOAT_VEC4));
+    parentStruct.fields.push_back(sh::ShaderVariable(GL_FLOAT_MAT3));
 
-    parentStruct.fields.push_back(sh::ShaderVariable(GL_NONE, 0));
+    parentStruct.fields.push_back(sh::ShaderVariable(GL_NONE));
     sh::ShaderVariable &innerStruct = parentStruct.fields.back();
-    innerStruct.fields.push_back(sh::ShaderVariable(GL_FLOAT_MAT3, 0));
+    innerStruct.fields.push_back(sh::ShaderVariable(GL_FLOAT_MAT3));
     innerStruct.fields.push_back(sh::ShaderVariable(GL_FLOAT_VEC2, 6));
     innerStruct.fields.push_back(sh::ShaderVariable(GL_FLOAT_VEC2, 4));
 
-    parentStruct.fields.push_back(sh::ShaderVariable(GL_FLOAT_VEC2, 0));
+    parentStruct.fields.push_back(sh::ShaderVariable(GL_FLOAT_VEC2));
     parentStruct.fields.push_back(sh::ShaderVariable(GL_FLOAT, 3));
     parentStruct.fields.push_back(sh::ShaderVariable(GL_FLOAT, 2));
-    parentStruct.fields.push_back(sh::ShaderVariable(GL_FLOAT, 0));
+    parentStruct.fields.push_back(sh::ShaderVariable(GL_FLOAT));
 
     EXPECT_TRUE(CheckVariablesInPackingLimits(kMaxRows, vars));
 }
new file mode 100644
--- /dev/null
+++ b/gfx/angle/src/tests/compiler_tests/VectorizeVectorScalarArithmetic_test.cpp
@@ -0,0 +1,50 @@
+//
+// 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_test.cpp:
+//  Tests shader compilation with SH_REWRITE_VECTOR_SCALAR_ARITHMETIC workaround on.
+
+#include "GLSLANG/ShaderLang.h"
+#include "angle_gl.h"
+#include "gtest/gtest.h"
+#include "tests/test_utils/ShaderCompileTreeTest.h"
+
+using namespace sh;
+
+class VectorizeVectorScalarArithmeticTest : public ShaderCompileTreeTest
+{
+  public:
+    VectorizeVectorScalarArithmeticTest() : ShaderCompileTreeTest()
+    {
+        mExtraCompileOptions = SH_REWRITE_VECTOR_SCALAR_ARITHMETIC;
+    }
+
+  protected:
+    ::GLenum getShaderType() const override { return GL_FRAGMENT_SHADER; }
+    ShShaderSpec getShaderSpec() const override { return SH_GLES3_1_SPEC; }
+};
+
+// Test that two ops that generate statements in the parent block inside the same statement don't
+// trigger an assert.
+TEST_F(VectorizeVectorScalarArithmeticTest, TwoMutatedOpsWithSideEffectsInsideSameStatement)
+{
+    const std::string &shaderString =
+        R"(#version 300 es
+        precision highp float;
+
+        out vec4 res;
+        uniform float uf;
+
+        void main()
+        {
+            res = vec4(0.0);
+            float f = uf;
+            res += f *= f, res += f *= f;
+        })";
+    if (!compile(shaderString))
+    {
+        FAIL() << "Shader compilation failed, expecting success:\n" << mInfoLog;
+    }
+}
--- a/gfx/angle/src/tests/compiler_tests/WEBGL_multiview_test.cpp
+++ b/gfx/angle/src/tests/compiler_tests/WEBGL_multiview_test.cpp
@@ -57,35 +57,35 @@ class SymbolOccurrenceCounterByQualifier
 
 class SymbolOccurrenceCounterByName : public SymbolOccurrenceCounter
 {
   public:
     SymbolOccurrenceCounterByName(const TString &symbolName) : mSymbolName(symbolName) {}
 
     bool shouldCountSymbol(const TIntermSymbol *node) const override
     {
-        return node->getName().getString() == mSymbolName;
+        return node->variable().symbolType() != SymbolType::Empty && node->getName() == mSymbolName;
     }
 
   private:
     TString mSymbolName;
 };
 
 class SymbolOccurrenceCounterByNameAndQualifier : public SymbolOccurrenceCounter
 {
   public:
     SymbolOccurrenceCounterByNameAndQualifier(const TString &symbolName, TQualifier qualifier)
         : mSymbolName(symbolName), mSymbolQualifier(qualifier)
     {
     }
 
     bool shouldCountSymbol(const TIntermSymbol *node) const override
     {
-        return node->getName().getString() == mSymbolName &&
-               node->getQualifier() == mSymbolQualifier;
+        return node->variable().symbolType() != SymbolType::Empty &&
+               node->getName() == mSymbolName && node->getQualifier() == mSymbolQualifier;
     }
 
   private:
     TString mSymbolName;
     TQualifier mSymbolQualifier;
 };
 
 class WEBGLMultiviewVertexShaderTest : public ShaderCompileTreeTest
@@ -550,18 +550,18 @@ TEST_F(WEBGLMultiviewVertexShaderOutputC
         "   myInstance = gl_InstanceID;\n"
         "}\n";
     requestHLSLOutput();
     compile(shaderString, SH_INITIALIZE_BUILTINS_FOR_INSTANCED_MULTIVIEW);
 
     EXPECT_TRUE(foundInAllGLSLCode("ViewID_OVR = (uint(gl_InstanceID) % 3u)"));
     EXPECT_TRUE(foundInAllGLSLCode("InstanceID = int((uint(gl_InstanceID) / 3u))"));
 
-    EXPECT_TRUE(foundInHLSLCode("ViewID_OVR = (uvec1(gl_InstanceID) % 3)"));
-    EXPECT_TRUE(foundInHLSLCode("InstanceID = ivec1((uvec1(gl_InstanceID) / 3))"));
+    EXPECT_TRUE(foundInHLSLCode("ViewID_OVR = (uint_ctor(gl_InstanceID) % 3)"));
+    EXPECT_TRUE(foundInHLSLCode("InstanceID = int_ctor((uint_ctor(gl_InstanceID) / 3))"));
 }
 
 // The test checks that the directive enabling GL_OVR_multiview is not outputted if the extension is
 // emulated.
 TEST_F(WEBGLMultiviewVertexShaderOutputCodeTest, StrippedOVRMultiviewDirective)
 {
     const std::string &shaderString =
         "#version 300 es\n"
@@ -570,20 +570,16 @@ TEST_F(WEBGLMultiviewVertexShaderOutputC
         "void main()\n"
         "{\n"
         "}\n";
     // The directive must not be present if any of the multiview emulation options are set.
     compile(shaderString, SH_INITIALIZE_BUILTINS_FOR_INSTANCED_MULTIVIEW);
     EXPECT_FALSE(foundInESSLCode("GL_OVR_multiview"));
     EXPECT_FALSE(foundInGLSLCode("GL_OVR_multiview"));
 
-    compile(shaderString, SH_TRANSLATE_VIEWID_OVR_TO_UNIFORM);
-    EXPECT_FALSE(foundInESSLCode("GL_OVR_multiview"));
-    EXPECT_FALSE(foundInGLSLCode("GL_OVR_multiview"));
-
     // The directive should be outputted from the ESSL translator with none of the options being
     // set.
     compile(shaderString);
     EXPECT_TRUE(foundInESSLCode("GL_OVR_multiview"));
 }
 
 // Test that gl_InstanceID is collected in an ESSL1 shader if the
 // SH_INITIALIZE_BUILTINS_FOR_INSTANCED_MULTIVIEW option is set.
@@ -709,55 +705,63 @@ TEST_F(WEBGLMultiviewVertexShaderOutputC
         "#version 300 es\n"
         "#extension GL_OVR_multiview : require\n"
         "layout(num_views = 3) in;\n"
         "void main()\n"
         "{\n"
         "}\n";
     compile(shaderString, SH_INITIALIZE_BUILTINS_FOR_INSTANCED_MULTIVIEW |
                               SH_SELECT_VIEW_IN_NV_GLSL_VERTEX_SHADER);
-    const char glViewportIndexAssignment[] = "gl_ViewportIndex = int(ViewID_OVR)";
 
-    // Check that the viewport index is selected.
-    EXPECT_TRUE(foundInAllGLSLCode(glViewportIndexAssignment));
-
-    // Setting gl_ViewportIndex must happen after ViewID_OVR's initialization.
-    const char viewIDOVRAssignment[] = "ViewID_OVR = (uint(gl_InstanceID) % 3u)";
-    size_t viewIDOVRAssignmentLoc = findInCode(SH_GLSL_COMPATIBILITY_OUTPUT, viewIDOVRAssignment);
-    size_t glViewportIndexAssignmentLoc =
-        findInCode(SH_GLSL_COMPATIBILITY_OUTPUT, glViewportIndexAssignment);
-    EXPECT_LT(viewIDOVRAssignmentLoc, glViewportIndexAssignmentLoc);
-
-    viewIDOVRAssignmentLoc       = findInCode(SH_ESSL_OUTPUT, viewIDOVRAssignment);
-    glViewportIndexAssignmentLoc = findInCode(SH_ESSL_OUTPUT, glViewportIndexAssignment);
-    EXPECT_LT(viewIDOVRAssignmentLoc, glViewportIndexAssignmentLoc);
+    std::vector<const char *> expectedStrings = {"ViewID_OVR = (uint(gl_InstanceID) % 3u)",
+                                                 "gl_ViewportIndex = int(ViewID_OVR)"};
+    EXPECT_TRUE(foundInCodeInOrder(SH_ESSL_OUTPUT, expectedStrings));
+    EXPECT_TRUE(foundInCodeInOrder(SH_GLSL_COMPATIBILITY_OUTPUT, expectedStrings));
 }
 
 // The test checks that the layer is selected after the initialization of ViewID_OVR for
 // GLSL and ESSL ouputs.
 TEST_F(WEBGLMultiviewVertexShaderOutputCodeTest, GlLayerIsSet)
 {
     const std::string &shaderString =
         "#version 300 es\n"
         "#extension GL_OVR_multiview : require\n"
         "layout(num_views = 3) in;\n"
         "void main()\n"
         "{\n"
         "}\n";
     compile(shaderString, SH_INITIALIZE_BUILTINS_FOR_INSTANCED_MULTIVIEW |
                               SH_SELECT_VIEW_IN_NV_GLSL_VERTEX_SHADER);
-    const char glLayerAssignment[] = "gl_Layer = (int(ViewID_OVR) + multiviewBaseViewLayerIndex)";
 
-    // Check that the layer is selected.
-    EXPECT_TRUE(foundInAllGLSLCode(glLayerAssignment));
+    std::vector<const char *> expectedStrings = {
+        "ViewID_OVR = (uint(gl_InstanceID) % 3u)",
+        "gl_Layer = (int(ViewID_OVR) + multiviewBaseViewLayerIndex)"};
+    EXPECT_TRUE(foundInCodeInOrder(SH_ESSL_OUTPUT, expectedStrings));
+    EXPECT_TRUE(foundInCodeInOrder(SH_GLSL_COMPATIBILITY_OUTPUT, expectedStrings));
+}
 
-    // Setting gl_Layer must happen after ViewID_OVR's initialization.
-    const char viewIDOVRAssignment[] = "ViewID_OVR = (uint(gl_InstanceID) % 3u)";
-    size_t viewIDOVRAssignmentLoc = findInCode(SH_GLSL_COMPATIBILITY_OUTPUT, viewIDOVRAssignment);
-    size_t glLayerAssignmentLoc   = findInCode(SH_GLSL_COMPATIBILITY_OUTPUT, glLayerAssignment);
-    EXPECT_LT(viewIDOVRAssignmentLoc, glLayerAssignmentLoc);
+// Test that a warning is generated in an ESSL 1.00 shader when using a layout qualifier to set
+// num_views and the extension is set to warn.
+TEST_F(WEBGLMultiviewVertexShaderTest, WarnOnGlobalLayoutQualifier)
+{
+    const std::string &shaderString =
+        R"(
+        #extension GL_OVR_multiview : warn
+        layout(num_views=2) in;
 
-    viewIDOVRAssignmentLoc = findInCode(SH_ESSL_OUTPUT, viewIDOVRAssignment);
-    glLayerAssignmentLoc   = findInCode(SH_ESSL_OUTPUT, glLayerAssignment);
-    EXPECT_LT(viewIDOVRAssignmentLoc, glLayerAssignmentLoc);
+        void main()
+        {
+        })";
+    if (compile(shaderString))
+    {
+        if (!hasWarning())
+        {
+            FAIL() << "Shader compilation succeeded without warnings, expecting warning:\n"
+                   << mInfoLog;
+        }
+    }
+    else
+    {
+        FAIL() << "Shader compilation failed, expecting success:\n" << mInfoLog;
+    }
 }
 
 }  // namespace
\ No newline at end of file
--- a/gfx/angle/src/tests/deqp.gypi
+++ b/gfx/angle/src/tests/deqp.gypi
@@ -12,17 +12,17 @@
         {
             'angle_build_winrt%': 0,
         },
 
         # Copy conditionally-set variables to the outer variables dict.
         'angle_build_winrt%': '<(angle_build_winrt)',
 
         'deqp_path': '<(DEPTH)/third_party/deqp/src',
-        'libpng_path': '<(DEPTH)/third_party/libpng',
+        'libpng_path': '<(DEPTH)/third_party/libpng/src',
         'zlib_path': '<(DEPTH)/third_party/zlib',
 
         'angle_build_deqp_libraries%' : 0,
         'angle_build_deqp_gtest_support%' : 0,
         'angle_build_deqp_executables%' : 0,
         'angle_build_deqp_gtest_executables%' :0,
 
         'clang_warning_flags':
@@ -103,18 +103,16 @@
             '<(deqp_path)/modules/gles3/performance',
             '<(deqp_path)/modules/gles3/stress',
             '<(deqp_path)/modules/gles3/usecases',
             '<(deqp_path)/modules/gles31',
             '<(deqp_path)/modules/gles31/functional',
             '<(deqp_path)/modules/gles31/stress',
             '<(deqp_path)/modules/glshared',
             '<(deqp_path)/modules/glusecases',
-            '<(libpng_path)',
-            '<(zlib_path)',
         ],
         'deqp_gles2_sources':
         [
             '<(deqp_path)/modules/gles2/accuracy/es2aAccuracyTests.cpp',
             '<(deqp_path)/modules/gles2/accuracy/es2aAccuracyTests.hpp',
             '<(deqp_path)/modules/gles2/accuracy/es2aTextureFilteringTests.cpp',
             '<(deqp_path)/modules/gles2/accuracy/es2aTextureFilteringTests.hpp',
             '<(deqp_path)/modules/gles2/accuracy/es2aTextureMipmapTests.cpp',
@@ -1195,16 +1193,21 @@
         [
             'third_party/gpu_test_expectations/gpu_info.cc',
             'third_party/gpu_test_expectations/gpu_info.h',
             'third_party/gpu_test_expectations/gpu_test_config.cc',
             'third_party/gpu_test_expectations/gpu_test_config.h',
             'third_party/gpu_test_expectations/gpu_test_expectations_parser.cc',
             'third_party/gpu_test_expectations/gpu_test_expectations_parser.h',
         ],
+        'deqp_gpu_test_expectations_sources_mac':
+        [
+            'third_party/gpu_test_expectations/gpu_test_config_mac.mm',
+            'third_party/gpu_test_expectations/gpu_test_config_mac.h',
+        ],
         'conditions':
         [
             ['(OS=="win" or OS=="linux" or OS=="mac")',
             {
                 # Build the dEQP libraries for all Windows/Linux builds
                 'angle_build_deqp_libraries%': 1,
             }],
             ['((OS=="win" or OS=="linux" or OS=="mac") and angle_build_winrt==0)',
@@ -1463,17 +1466,22 @@
                             },
                         },
                         # Re-enable RTTI and exceptions, dEQP needs them.
                         'cflags_cc!':
                         [
                             '-fno-exceptions',
                             '-fno-rtti',
                         ],
-                        'include_dirs': ['<@(deqp_include_dirs)'],
+                        'include_dirs':
+                        [
+                            '<@(deqp_include_dirs)',
+                            '<(libpng_path)',
+                            '<(zlib_path)',
+                        ],
                         'defines': ['<@(deqp_defines)'],
                         'defines!': [ '<@(deqp_undefines)' ],
                         'msvs_settings':
                         {
                             'VCCLCompilerTool':
                             {
                                 'AdditionalOptions': ['<@(deqp_win_cflags)'],
                             },
@@ -1849,18 +1857,17 @@
                             },
                         },
                         'conditions':
                         [
                             ['OS=="mac"',
                             {
                                 'sources':
                                 [
-                                    'third_party/gpu_test_expectations/gpu_test_config_mac.h',
-                                    'third_party/gpu_test_expectations/gpu_test_config_mac.mm',
+                                    '<@(deqp_gpu_test_expectations_sources_mac)',
                                 ],
                             }],
                         ],
                     },
                 },
             ], # targets
         }], # angle_build_deqp_gtest_support
         ['angle_build_deqp_gtest_executables==1',
--- a/gfx/angle/src/tests/deqp_support/deqp_gles2_test_expectations.txt
+++ b/gfx/angle/src/tests/deqp_support/deqp_gles2_test_expectations.txt
@@ -68,16 +68,21 @@ 1655 D3D11 : dEQP-GLES2.functional.fragm
 //
 //  Temporary entries: they should be removed once the bugs are fixed.
 //
 ////////////////////////////////////////////////////////////////////////////////
 
 // Only fails in D3D11 32-bit.
 1418 D3D11 : dEQP-GLES2.functional.clipping.triangle_vertex.clip_three.clip_pos_x_pos_y_pos_z_and_neg_x_pos_y_pos_z_and_neg_x_neg_y_neg_z = FAIL
 
+// Quadro P400
+// TODO(jmadill): Narrow to P400 device only: 0x1CB3.
+2222 D3D11 NVIDIA : dEQP-GLES2.functional.shaders.functions.control_flow.return_in_nested_loop_fragment = FAIL
+2222 D3D11 NVIDIA : dEQP-GLES2.functional.shaders.functions.control_flow.return_in_nested_loop_vertex = FAIL
+
 // Failures on the D3D11 bots that do not reproduce locally
 // TODO(jmadill): Figure out why these fail on the bots, but not locally.
 1108 D3D11 : dEQP-GLES2.functional.shaders.struct.local.dynamic_loop_struct_array_fragment = FAIL
 1108 D3D11 : dEQP-GLES2.functional.shaders.invariance.highp.loop_2 = FAIL
 1108 D3D11 : dEQP-GLES2.functional.shaders.invariance.mediump.loop_2 = FAIL
 
 // OpenGL desktop back-end failures
 1656 OPENGL : dEQP-GLES2.functional.fbo.completeness.renderable.texture.stencil.srgb8_alpha8 = FAIL
--- a/gfx/angle/src/tests/deqp_support/deqp_gles31_test_expectations.txt
+++ b/gfx/angle/src/tests/deqp_support/deqp_gles31_test_expectations.txt
@@ -19,1122 +19,1129 @@
 //
 // Examples:
 //  91530 MAC WIN LINUX : context_lost_restored = TIMEOUT
 //  91533 WIN : gl_min_uniforms = FAIL
 //  91531 MAC WIN LINUX : conformance_more_* = SKIP
 //  91532 MAC NVIDIA 0x0640 : tex_image_and_sub_image_2d_with_video = PASS FAIL
 
 // Crashing Tests
-1659 NVIDIA OPENGL : dEQP-GLES31.functional.draw_indirect.random.0 = SKIP
-1659 NVIDIA OPENGL : dEQP-GLES31.functional.draw_indirect.random.10 = SKIP
-1659 NVIDIA OPENGL : dEQP-GLES31.functional.draw_indirect.random.15 = SKIP
-1659 NVIDIA OPENGL : dEQP-GLES31.functional.draw_indirect.random.18 = SKIP
+1920 NVIDIA D3D11 : dEQP-GLES31.functional.layout_binding.ubo.vertex_binding_max = SKIP
 1442 OPENGL D3D11 : dEQP-GLES31.functional.program_interface_query.transform_feedback_varying.resource_list.vertex_fragment.builtin_gl_position = SKIP
 1442 OPENGL D3D11 : dEQP-GLES31.functional.program_interface_query.transform_feedback_varying.resource_list.vertex_fragment.default_block_struct_member = SKIP
 1442 OPENGL D3D11 : dEQP-GLES31.functional.program_interface_query.transform_feedback_varying.array_size.vertex_fragment.default_block_struct_member = SKIP
 1442 OPENGL D3D11 : dEQP-GLES31.functional.program_interface_query.transform_feedback_varying.name_length.vertex_fragment.default_block_struct_member = SKIP
 1442 OPENGL D3D11 : dEQP-GLES31.functional.program_interface_query.transform_feedback_varying.type.vertex_fragment.struct.* = SKIP
 1442 D3D11 : dEQP-GLES31.functional.vertex_attribute_binding.* = SKIP
 1442 D3D11 : dEQP-GLES31.functional.stencil_texturing.* = SKIP
 1442 D3D11 : dEQP-GLES31.functional.texture.gather.* = SKIP
+// TODO(xinghua.cao@intel.com): FAIL expectation instead of SKIP should be sufficient for OpenGL, but the
+// test expectations parser doesn't support having FAIL for GL and SKIP for D3D with the same test filter.
+1442 OPENGL D3D11 : dEQP-GLES31.functional.image_load_store.* = SKIP
+
+// TODO(jiawei.shao@intel.com): Implement FramebufferTextureEXT entry point defined in OpenGL ES 3.1 extension GL_EXT_geometry_shader
+1941 OPENGL D3D11 : dEQP-GLES31.functional.geometry_shading.query.framebuffer_* = SKIP
+1941 OPENGL D3D11 : dEQP-GLES31.functional.geometry_shading.layered.* = SKIP
+1941 OPENGL D3D11 : dEQP-GLES31.functional.geometry_shading.instanced.invocation_per_layer_* = SKIP
+1941 OPENGL D3D11 : dEQP-GLES31.functional.geometry_shading.instanced.multiple_layers_per_invocation_* = SKIP
+// TODO(jiawei.shao@intel.com): Implement validations on transform feedback required in OpenGL ES 3.1 extension GL_EXT_geometry_shader
+1941 OPENGL D3D11 : dEQP-GLES31.functional.geometry_shading.vertex_transform_feedback.* = SKIP
 
 // D3D11 Failing Tests
-1442 D3D11 : dEQP-GLES31.functional.state_query.boolean.sample_mask_* = FAIL
-1442 D3D11 : dEQP-GLES31.functional.state_query.integer.max_color_texture_samples_* = FAIL
-1442 D3D11 : dEQP-GLES31.functional.state_query.integer.max_depth_texture_samples_* = FAIL
-1442 D3D11 : dEQP-GLES31.functional.state_query.integer.max_integer_samples_* = FAIL
-1442 D3D11 : dEQP-GLES31.functional.state_query.integer.max_sample_mask_words_* = FAIL
-1442 D3D11 : dEQP-GLES31.functional.state_query.integer.max_framebuffer_width_* = FAIL
-1442 D3D11 : dEQP-GLES31.functional.state_query.integer.max_framebuffer_height_* = FAIL
-1442 D3D11 : dEQP-GLES31.functional.state_query.integer.max_framebuffer_samples_* = FAIL
 1442 D3D11 : dEQP-GLES31.functional.state_query.integer.max_compute_shared_memory_size_* = FAIL
 1442 D3D11 : dEQP-GLES31.functional.state_query.integer.max_compute_atomic_counter_buffers_* = FAIL
 1442 D3D11 : dEQP-GLES31.functional.state_query.integer.max_compute_atomic_counters_* = FAIL
-1442 D3D11 : dEQP-GLES31.functional.state_query.integer.max_compute_image_uniforms_* = FAIL
 1442 D3D11 : dEQP-GLES31.functional.state_query.integer.max_compute_shader_storage_blocks_* = FAIL
 1442 D3D11 : dEQP-GLES31.functional.state_query.integer.max_atomic_counter_buffer_bindings_* = FAIL
 1442 D3D11 : dEQP-GLES31.functional.state_query.integer.max_atomic_counter_buffer_size_* = FAIL
 1442 D3D11 : dEQP-GLES31.functional.state_query.integer.max_combined_atomic_counter_buffers_* = FAIL
 1442 D3D11 : dEQP-GLES31.functional.state_query.integer.max_combined_atomic_counters* = FAIL
 1442 D3D11 : dEQP-GLES31.functional.state_query.integer.max_image_units_* = FAIL
 1442 D3D11 : dEQP-GLES31.functional.state_query.integer.max_combined_image_uniforms_* = FAIL
 1442 D3D11 : dEQP-GLES31.functional.state_query.integer.max_shader_storage_buffer_bindings_* = FAIL
 1442 D3D11 : dEQP-GLES31.functional.state_query.integer.max_shader_storage_block_size_* = FAIL
 1442 D3D11 : dEQP-GLES31.functional.state_query.integer.max_combined_shader_storage_blocks_* = FAIL
 1442 D3D11 : dEQP-GLES31.functional.state_query.integer.max_combined_shader_output_resources_* = FAIL
 1442 D3D11 : dEQP-GLES31.functional.state_query.integer.max_uniform_buffer_bindings_* = FAIL
 1442 D3D11 : dEQP-GLES31.functional.state_query.integer.max_combined_texture_image_units_* = FAIL
 1729 D3D11 : dEQP-GLES31.functional.state_query.indexed.atomic_counter_buffer_* = FAIL
-1442 D3D11 : dEQP-GLES31.functional.state_query.indexed.sample_mask_value_* = FAIL
 1951 D3D11 : dEQP-GLES31.functional.state_query.indexed.shader_storage_buffer_* = FAIL
 1442 D3D11 : dEQP-GLES31.functional.state_query.internal_format.renderbuffer.* = FAIL
-1679 D3D11 : dEQP-GLES31.functional.state_query.texture_level.texture_2d_multisample.* = FAIL
-1442 D3D11 : dEQP-GLES31.functional.texture.multisample.samples_1.sample_mask_* = FAIL
-1442 D3D11 : dEQP-GLES31.functional.texture.multisample.samples_2.sample_mask_* = FAIL
-1442 D3D11 : dEQP-GLES31.functional.texture.multisample.samples_3.sample_mask_* = FAIL
-1442 D3D11 : dEQP-GLES31.functional.texture.multisample.samples_4.sample_mask_* = FAIL
-1442 D3D11 : dEQP-GLES31.functional.texture.multisample.samples_8.sample_mask_* = FAIL
-1442 D3D11 : dEQP-GLES31.functional.texture.multisample.samples_10.sample_mask_* = FAIL
-1442 D3D11 : dEQP-GLES31.functional.texture.multisample.samples_12.sample_mask_* = FAIL
-1442 D3D11 : dEQP-GLES31.functional.texture.multisample.samples_13.sample_mask_* = FAIL
-1442 D3D11 : dEQP-GLES31.functional.texture.multisample.samples_64.sample_mask_* = FAIL
+1442 D3D11 : dEQP-GLES31.functional.state_query.program.compute_work_group_size_get_programiv = FAIL
+1442 D3D11 : dEQP-GLES31.functional.layout_binding.ssbo.* = FAIL
+1442 D3D11 : dEQP-GLES31.functional.compute* = FAIL
+1442 D3D11 : dEQP-GLES31.functional.atomic_counter.* = FAIL
 1442 D3D11 : dEQP-GLES31.functional.debug.negative_coverage.callbacks.texture.texparameter* = SKIP
 1442 D3D11 : dEQP-GLES31.functional.debug.negative_coverage.get_error.texture.texparameter* = SKIP
 1442 D3D11 : dEQP-GLES31.functional.debug.negative_coverage.log.texture.texparameter* = SKIP
 1442 D3D11 : dEQP-GLES31.functional.debug.async.case_4_log = SKIP
 1442 D3D11 : dEQP-GLES31.functional.debug.async.case_5_callback = SKIP
 1442 D3D11 : dEQP-GLES31.functional.debug.error_filters.case_2 = SKIP
 1442 D3D11 : dEQP-GLES31.functional.debug.error_filters.case_3 = SKIP
 1442 D3D11 : dEQP-GLES31.functional.debug.error_filters.case_9 = SKIP
 1442 D3D11 : dEQP-GLES31.functional.debug.error_filters.case_10 = SKIP
 1442 D3D11 : dEQP-GLES31.functional.debug.error_filters.case_27 = SKIP
 1442 D3D11 : dEQP-GLES31.functional.debug.error_filters.case_28 = SKIP
 1442 D3D11 : dEQP-GLES31.functional.debug.error_groups.case_2 = SKIP
 1442 D3D11 : dEQP-GLES31.functional.debug.error_groups.case_3 = SKIP
 1442 D3D11 : dEQP-GLES31.functional.debug.error_groups.case_9 = SKIP
 1442 D3D11 : dEQP-GLES31.functional.debug.error_groups.case_10 = SKIP
+1442 D3D11 : dEQP-GLES31.functional.state_query.program.active_atomic_counter_buffers_get_programiv = FAIL
+1442 D3D11 : dEQP-GLES31.functional.layout_binding.ubo.* = FAIL
+1442 D3D11 : dEQP-GLES31.functional.program_interface_query.* = FAIL
+1663 D3D11 : dEQP-GLES31.functional.draw_indirect.compute_interop.* = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.abs.float_lowp_compute = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.abs.float_mediump_compute = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.abs.float_highp_compute = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.abs.vec2_lowp_compute = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.abs.vec2_mediump_compute = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.abs.vec2_highp_compute = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.abs.vec3_lowp_compute = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.abs.vec3_mediump_compute = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.abs.vec3_highp_compute = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.abs.vec4_lowp_compute = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.abs.vec4_mediump_compute = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.abs.vec4_highp_compute = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.abs.int_lowp_compute = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.abs.int_mediump_compute = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.abs.int_highp_compute = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.abs.ivec2_lowp_compute = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.abs.ivec2_mediump_compute = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.abs.ivec2_highp_compute = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.abs.ivec3_lowp_compute = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.abs.ivec3_mediump_compute = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.abs.ivec3_highp_compute = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.abs.ivec4_lowp_compute = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.abs.ivec4_mediump_compute = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.abs.ivec4_highp_compute = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.sign.float_lowp_compute = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.sign.float_mediump_compute = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.sign.float_highp_compute = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.sign.vec2_lowp_compute = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.sign.vec2_mediump_compute = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.sign.vec2_highp_compute = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.sign.vec3_lowp_compute = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.sign.vec3_mediump_compute = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.sign.vec3_highp_compute = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.sign.vec4_lowp_compute = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.sign.vec4_mediump_compute = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.sign.vec4_highp_compute = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.sign.int_lowp_compute = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.sign.int_mediump_compute = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.sign.int_highp_compute = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.sign.ivec2_lowp_compute = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.sign.ivec2_mediump_compute = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.sign.ivec2_highp_compute = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.sign.ivec3_lowp_compute = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.sign.ivec3_mediump_compute = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.sign.ivec3_highp_compute = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.sign.ivec4_lowp_compute = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.sign.ivec4_mediump_compute = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.sign.ivec4_highp_compute = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.floor.float_lowp_compute = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.floor.float_mediump_compute = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.floor.float_highp_compute = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.floor.vec2_lowp_compute = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.floor.vec2_mediump_compute = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.floor.vec2_highp_compute = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.floor.vec3_lowp_compute = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.floor.vec3_mediump_compute = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.floor.vec3_highp_compute = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.floor.vec4_lowp_compute = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.floor.vec4_mediump_compute = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.floor.vec4_highp_compute = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.trunc.float_lowp_compute = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.trunc.float_mediump_compute = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.trunc.float_highp_compute = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.trunc.vec2_lowp_compute = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.trunc.vec2_mediump_compute = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.trunc.vec2_highp_compute = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.trunc.vec3_lowp_compute = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.trunc.vec3_mediump_compute = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.trunc.vec3_highp_compute = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.trunc.vec4_lowp_compute = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.trunc.vec4_mediump_compute = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.trunc.vec4_highp_compute = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.round.float_lowp_compute = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.round.float_mediump_compute = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.round.float_highp_compute = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.round.vec2_lowp_compute = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.round.vec2_mediump_compute = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.round.vec2_highp_compute = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.round.vec3_lowp_compute = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.round.vec3_mediump_compute = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.round.vec3_highp_compute = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.round.vec4_lowp_compute = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.round.vec4_mediump_compute = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.round.vec4_highp_compute = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.roundeven.float_lowp_compute = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.roundeven.float_mediump_compute = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.roundeven.float_highp_compute = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.roundeven.vec2_lowp_compute = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.roundeven.vec2_mediump_compute = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.roundeven.vec2_highp_compute = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.roundeven.vec3_lowp_compute = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.roundeven.vec3_mediump_compute = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.roundeven.vec3_highp_compute = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.roundeven.vec4_lowp_compute = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.roundeven.vec4_mediump_compute = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.roundeven.vec4_highp_compute = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.ceil.float_lowp_compute = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.ceil.float_mediump_compute = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.ceil.float_highp_compute = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.ceil.vec2_lowp_compute = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.ceil.vec2_mediump_compute = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.ceil.vec2_highp_compute = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.ceil.vec3_lowp_compute = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.ceil.vec3_mediump_compute = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.ceil.vec3_highp_compute = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.ceil.vec4_lowp_compute = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.ceil.vec4_mediump_compute = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.ceil.vec4_highp_compute = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.fract.float_lowp_compute = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.fract.float_mediump_compute = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.fract.float_highp_compute = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.fract.vec2_lowp_compute = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.fract.vec2_mediump_compute = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.fract.vec2_highp_compute = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.fract.vec3_lowp_compute = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.fract.vec3_mediump_compute = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.fract.vec3_highp_compute = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.fract.vec4_lowp_compute = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.fract.vec4_mediump_compute = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.fract.vec4_highp_compute = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.modf.float_lowp_compute = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.modf.float_mediump_compute = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.modf.float_highp_compute = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.modf.vec2_lowp_compute = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.modf.vec2_mediump_compute = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.modf.vec2_highp_compute = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.modf.vec3_lowp_compute = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.modf.vec3_mediump_compute = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.modf.vec3_highp_compute = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.modf.vec4_lowp_compute = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.modf.vec4_mediump_compute = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.modf.vec4_highp_compute = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.isnan.float_lowp_compute = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.isnan.float_mediump_compute = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.isnan.float_highp_compute = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.isnan.vec2_lowp_compute = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.isnan.vec2_mediump_compute = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.isnan.vec2_highp_compute = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.isnan.vec3_lowp_compute = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.isnan.vec3_mediump_compute = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.isnan.vec3_highp_compute = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.isnan.vec4_lowp_compute = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.isnan.vec4_mediump_compute = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.isnan.vec4_highp_compute = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.isinf.float_lowp_compute = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.isinf.float_mediump_compute = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.isinf.float_highp_compute = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.isinf.vec2_lowp_compute = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.isinf.vec2_mediump_compute = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.isinf.vec2_highp_compute = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.isinf.vec3_lowp_compute = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.isinf.vec3_mediump_compute = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.isinf.vec3_highp_compute = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.isinf.vec4_lowp_compute = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.isinf.vec4_mediump_compute = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.isinf.vec4_highp_compute = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.floatbitstoint.float_lowp_compute = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.floatbitstoint.float_mediump_compute = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.floatbitstoint.float_highp_compute = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.floatbitstoint.vec2_lowp_compute = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.floatbitstoint.vec2_mediump_compute = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.floatbitstoint.vec2_highp_compute = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.floatbitstoint.vec3_lowp_compute = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.floatbitstoint.vec3_mediump_compute = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.floatbitstoint.vec3_highp_compute = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.floatbitstoint.vec4_lowp_compute = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.floatbitstoint.vec4_mediump_compute = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.floatbitstoint.vec4_highp_compute = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.floatbitstouint.float_lowp_compute = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.floatbitstouint.float_mediump_compute = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.floatbitstouint.float_highp_compute = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.floatbitstouint.vec2_lowp_compute = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.floatbitstouint.vec2_mediump_compute = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.floatbitstouint.vec2_highp_compute = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.floatbitstouint.vec3_lowp_compute = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.floatbitstouint.vec3_mediump_compute = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.floatbitstouint.vec3_highp_compute = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.floatbitstouint.vec4_lowp_compute = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.floatbitstouint.vec4_mediump_compute = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.floatbitstouint.vec4_highp_compute = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.frexp.float_lowp_compute = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.frexp.float_mediump_compute = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.frexp.float_highp_compute = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.frexp.vec2_lowp_compute = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.frexp.vec2_mediump_compute = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.frexp.vec2_highp_compute = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.frexp.vec3_lowp_compute = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.frexp.vec3_mediump_compute = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.frexp.vec3_highp_compute = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.frexp.vec4_lowp_compute = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.frexp.vec4_mediump_compute = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.frexp.vec4_highp_compute = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.ldexp.float_lowp_compute = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.ldexp.float_mediump_compute = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.ldexp.float_highp_compute = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.ldexp.vec2_lowp_compute = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.ldexp.vec2_mediump_compute = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.ldexp.vec2_highp_compute = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.ldexp.vec3_lowp_compute = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.ldexp.vec3_mediump_compute = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.ldexp.vec3_highp_compute = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.ldexp.vec4_lowp_compute = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.ldexp.vec4_mediump_compute = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.ldexp.vec4_highp_compute = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.intbitstofloat.int_highp_compute = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.intbitstofloat.ivec2_highp_compute = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.intbitstofloat.ivec3_highp_compute = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.uintbitstofloat.uint_highp_compute = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.uintbitstofloat.uvec2_highp_compute = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.uintbitstofloat.uvec3_highp_compute = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.pack_unpack.packsnorm4x8_lowp_compute = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.pack_unpack.packsnorm4x8_mediump_compute = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.pack_unpack.packsnorm4x8_highp_compute = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.pack_unpack.unpacksnorm4x8_compute = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.pack_unpack.packunorm4x8_lowp_compute = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.pack_unpack.packunorm4x8_mediump_compute = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.pack_unpack.packunorm4x8_highp_compute = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.pack_unpack.unpackunorm4x8_compute = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.pack_unpack.packsnorm2x16_lowp_compute = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.pack_unpack.packsnorm2x16_mediump_compute = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.pack_unpack.packsnorm2x16_highp_compute = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.pack_unpack.unpacksnorm2x16_compute = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.pack_unpack.packunorm2x16_lowp_compute = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.pack_unpack.packunorm2x16_mediump_compute = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.pack_unpack.packunorm2x16_highp_compute = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.pack_unpack.unpackunorm2x16_compute = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.pack_unpack.packhalf2x16_compute = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.pack_unpack.unpackhalf2x16_compute = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.integer.uaddcarry.uint_lowp_compute = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.integer.uaddcarry.uint_mediump_compute = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.integer.uaddcarry.uint_highp_compute = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.integer.uaddcarry.uvec2_lowp_compute = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.integer.uaddcarry.uvec2_mediump_compute = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.integer.uaddcarry.uvec2_highp_compute = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.integer.uaddcarry.uvec3_lowp_compute = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.integer.uaddcarry.uvec3_mediump_compute = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.integer.uaddcarry.uvec3_highp_compute = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.integer.uaddcarry.uvec4_lowp_compute = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.integer.uaddcarry.uvec4_mediump_compute = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.integer.uaddcarry.uvec4_highp_compute = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.integer.usubborrow.uint_lowp_compute = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.integer.usubborrow.uint_mediump_compute = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.integer.usubborrow.uint_highp_compute = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.integer.usubborrow.uvec2_lowp_compute = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.integer.usubborrow.uvec2_mediump_compute = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.integer.usubborrow.uvec2_highp_compute = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.integer.usubborrow.uvec3_lowp_compute = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.integer.usubborrow.uvec3_mediump_compute = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.integer.usubborrow.uvec3_highp_compute = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.integer.usubborrow.uvec4_lowp_compute = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.integer.usubborrow.uvec4_mediump_compute = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.integer.usubborrow.uvec4_highp_compute = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.integer.umulextended.uint_highp_compute = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.integer.umulextended.uvec2_highp_compute = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.integer.umulextended.uvec3_highp_compute = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.integer.umulextended.uvec4_highp_compute = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.integer.imulextended.int_highp_compute = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.integer.imulextended.ivec2_highp_compute = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.integer.imulextended.ivec3_highp_compute = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.integer.imulextended.ivec4_highp_compute = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.integer.bitfieldextract.int_lowp_compute = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.integer.bitfieldextract.int_mediump_compute = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.integer.bitfieldextract.int_highp_compute = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.integer.bitfieldextract.ivec2_lowp_compute = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.integer.bitfieldextract.ivec2_mediump_compute = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.integer.bitfieldextract.ivec2_highp_compute = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.integer.bitfieldextract.ivec3_lowp_compute = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.integer.bitfieldextract.ivec3_mediump_compute = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.integer.bitfieldextract.ivec3_highp_compute = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.integer.bitfieldextract.ivec4_lowp_compute = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.integer.bitfieldextract.ivec4_mediump_compute = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.integer.bitfieldextract.ivec4_highp_compute = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.integer.bitfieldextract.uint_lowp_compute = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.integer.bitfieldextract.uint_mediump_compute = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.integer.bitfieldextract.uint_highp_compute = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.integer.bitfieldextract.uvec2_lowp_compute = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.integer.bitfieldextract.uvec2_mediump_compute = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.integer.bitfieldextract.uvec2_highp_compute = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.integer.bitfieldextract.uvec3_lowp_compute = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.integer.bitfieldextract.uvec3_mediump_compute = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.integer.bitfieldextract.uvec3_highp_compute = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.integer.bitfieldextract.uvec4_lowp_compute = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.integer.bitfieldextract.uvec4_mediump_compute = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.integer.bitfieldextract.uvec4_highp_compute = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.integer.bitfieldinsert.int_lowp_compute = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.integer.bitfieldinsert.int_mediump_compute = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.integer.bitfieldinsert.int_highp_compute = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.integer.bitfieldinsert.ivec2_lowp_compute = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.integer.bitfieldinsert.ivec2_mediump_compute = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.integer.bitfieldinsert.ivec2_highp_compute = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.integer.bitfieldinsert.ivec3_lowp_compute = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.integer.bitfieldinsert.ivec3_mediump_compute = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.integer.bitfieldinsert.ivec3_highp_compute = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.integer.bitfieldinsert.ivec4_lowp_compute = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.integer.bitfieldinsert.ivec4_mediump_compute = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.integer.bitfieldinsert.ivec4_highp_compute = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.integer.bitfieldinsert.uint_lowp_compute = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.integer.bitfieldinsert.uint_mediump_compute = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.integer.bitfieldinsert.uint_highp_compute = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.integer.bitfieldinsert.uvec2_lowp_compute = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.integer.bitfieldinsert.uvec2_mediump_compute = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.integer.bitfieldinsert.uvec2_highp_compute = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.integer.bitfieldinsert.uvec3_lowp_compute = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.integer.bitfieldinsert.uvec3_mediump_compute = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.integer.bitfieldinsert.uvec3_highp_compute = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.integer.bitfieldinsert.uvec4_lowp_compute = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.integer.bitfieldinsert.uvec4_mediump_compute = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.integer.bitfieldinsert.uvec4_highp_compute = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.integer.bitfieldreverse.int_lowp_compute = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.integer.bitfieldreverse.int_mediump_compute = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.integer.bitfieldreverse.int_highp_compute = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.integer.bitfieldreverse.ivec2_lowp_compute = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.integer.bitfieldreverse.ivec2_mediump_compute = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.integer.bitfieldreverse.ivec2_highp_compute = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.integer.bitfieldreverse.ivec3_lowp_compute = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.integer.bitfieldreverse.ivec3_mediump_compute = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.integer.bitfieldreverse.ivec3_highp_compute = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.integer.bitfieldreverse.ivec4_lowp_compute = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.integer.bitfieldreverse.ivec4_mediump_compute = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.integer.bitfieldreverse.ivec4_highp_compute = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.integer.bitfieldreverse.uint_lowp_compute = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.integer.bitfieldreverse.uint_mediump_compute = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.integer.bitfieldreverse.uint_highp_compute = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.integer.bitfieldreverse.uvec2_lowp_compute = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.integer.bitfieldreverse.uvec2_mediump_compute = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.integer.bitfieldreverse.uvec2_highp_compute = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.integer.bitfieldreverse.uvec3_lowp_compute = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.integer.bitfieldreverse.uvec3_mediump_compute = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.integer.bitfieldreverse.uvec3_highp_compute = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.integer.bitfieldreverse.uvec4_lowp_compute = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.integer.bitfieldreverse.uvec4_mediump_compute = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.integer.bitfieldreverse.uvec4_highp_compute = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.integer.bitcount.int_lowp_compute = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.integer.bitcount.int_mediump_compute = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.integer.bitcount.int_highp_compute = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.integer.bitcount.ivec2_lowp_compute = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.integer.bitcount.ivec2_mediump_compute = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.integer.bitcount.ivec2_highp_compute = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.integer.bitcount.ivec3_lowp_compute = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.integer.bitcount.ivec3_mediump_compute = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.integer.bitcount.ivec3_highp_compute = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.integer.bitcount.ivec4_lowp_compute = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.integer.bitcount.ivec4_mediump_compute = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.integer.bitcount.ivec4_highp_compute = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.integer.bitcount.uint_lowp_compute = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.integer.bitcount.uint_mediump_compute = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.integer.bitcount.uint_highp_compute = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.integer.bitcount.uvec2_lowp_compute = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.integer.bitcount.uvec2_mediump_compute = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.integer.bitcount.uvec2_highp_compute = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.integer.bitcount.uvec3_lowp_compute = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.integer.bitcount.uvec3_mediump_compute = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.integer.bitcount.uvec3_highp_compute = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.integer.bitcount.uvec4_lowp_compute = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.integer.bitcount.uvec4_mediump_compute = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.integer.bitcount.uvec4_highp_compute = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.integer.findlsb.int_lowp_compute = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.integer.findlsb.int_mediump_compute = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.integer.findlsb.int_highp_compute = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.integer.findlsb.ivec2_lowp_compute = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.integer.findlsb.ivec2_mediump_compute = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.integer.findlsb.ivec2_highp_compute = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.integer.findlsb.ivec3_lowp_compute = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.integer.findlsb.ivec3_mediump_compute = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.integer.findlsb.ivec3_highp_compute = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.integer.findlsb.ivec4_lowp_compute = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.integer.findlsb.ivec4_mediump_compute = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.integer.findlsb.ivec4_highp_compute = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.integer.findlsb.uint_lowp_compute = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.integer.findlsb.uint_mediump_compute = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.integer.findlsb.uint_highp_compute = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.integer.findlsb.uvec2_lowp_compute = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.integer.findlsb.uvec2_mediump_compute = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.integer.findlsb.uvec2_highp_compute = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.integer.findlsb.uvec3_lowp_compute = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.integer.findlsb.uvec3_mediump_compute = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.integer.findlsb.uvec3_highp_compute = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.integer.findlsb.uvec4_lowp_compute = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.integer.findlsb.uvec4_mediump_compute = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.integer.findlsb.uvec4_highp_compute = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.integer.findmsb.int_lowp_compute = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.integer.findmsb.int_mediump_compute = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.integer.findmsb.int_highp_compute = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.integer.findmsb.ivec2_lowp_compute = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.integer.findmsb.ivec2_mediump_compute = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.integer.findmsb.ivec2_highp_compute = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.integer.findmsb.ivec3_lowp_compute = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.integer.findmsb.ivec3_mediump_compute = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.integer.findmsb.ivec3_highp_compute = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.integer.findmsb.ivec4_lowp_compute = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.integer.findmsb.ivec4_mediump_compute = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.integer.findmsb.ivec4_highp_compute = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.integer.findmsb.uint_lowp_compute = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.integer.findmsb.uint_mediump_compute = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.integer.findmsb.uint_highp_compute = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.integer.findmsb.uvec2_lowp_compute = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.integer.findmsb.uvec2_mediump_compute = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.integer.findmsb.uvec2_highp_compute = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.integer.findmsb.uvec3_lowp_compute = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.integer.findmsb.uvec3_mediump_compute = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.integer.findmsb.uvec3_highp_compute = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.integer.findmsb.uvec4_lowp_compute = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.integer.findmsb.uvec4_mediump_compute = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.integer.findmsb.uvec4_highp_compute = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.add.lowp_compute.scalar = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.add.lowp_compute.vec2 = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.add.lowp_compute.vec3 = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.add.lowp_compute.vec4 = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.add.mediump_compute.scalar = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.add.mediump_compute.vec2 = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.add.mediump_compute.vec3 = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.add.mediump_compute.vec4 = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.add.highp_compute.scalar = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.add.highp_compute.vec2 = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.add.highp_compute.vec3 = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.add.highp_compute.vec4 = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.sub.lowp_compute.scalar = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.sub.lowp_compute.vec2 = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.sub.lowp_compute.vec3 = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.sub.lowp_compute.vec4 = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.sub.mediump_compute.scalar = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.sub.mediump_compute.vec2 = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.sub.mediump_compute.vec3 = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.sub.mediump_compute.vec4 = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.sub.highp_compute.scalar = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.sub.highp_compute.vec2 = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.sub.highp_compute.vec3 = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.sub.highp_compute.vec4 = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.mul.lowp_compute.scalar = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.mul.lowp_compute.vec2 = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.mul.lowp_compute.vec3 = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.mul.lowp_compute.vec4 = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.mul.mediump_compute.scalar = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.mul.mediump_compute.vec2 = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.mul.mediump_compute.vec3 = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.mul.mediump_compute.vec4 = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.mul.highp_compute.scalar = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.mul.highp_compute.vec2 = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.mul.highp_compute.vec3 = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.mul.highp_compute.vec4 = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.div.lowp_compute.scalar = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.div.lowp_compute.vec2 = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.div.lowp_compute.vec3 = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.div.lowp_compute.vec4 = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.div.mediump_compute.scalar = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.div.mediump_compute.vec2 = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.div.mediump_compute.vec3 = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.div.mediump_compute.vec4 = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.radians.lowp_compute.scalar = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.radians.lowp_compute.vec2 = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.radians.lowp_compute.vec3 = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.radians.lowp_compute.vec4 = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.radians.mediump_compute.scalar = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.radians.mediump_compute.vec2 = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.radians.mediump_compute.vec3 = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.radians.mediump_compute.vec4 = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.radians.highp_compute.scalar = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.radians.highp_compute.vec2 = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.radians.highp_compute.vec3 = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.radians.highp_compute.vec4 = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.degrees.lowp_compute.scalar = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.degrees.lowp_compute.vec2 = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.degrees.lowp_compute.vec3 = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.degrees.lowp_compute.vec4 = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.degrees.mediump_compute.scalar = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.degrees.mediump_compute.vec2 = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.degrees.mediump_compute.vec3 = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.degrees.mediump_compute.vec4 = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.degrees.highp_compute.scalar = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.degrees.highp_compute.vec2 = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.degrees.highp_compute.vec3 = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.degrees.highp_compute.vec4 = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.sin.lowp_compute.scalar = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.sin.lowp_compute.vec2 = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.sin.lowp_compute.vec3 = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.sin.lowp_compute.vec4 = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.sin.highp_compute.scalar = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.sin.highp_compute.vec2 = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.sin.highp_compute.vec3 = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.sin.highp_compute.vec4 = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.cos.lowp_compute.scalar = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.cos.lowp_compute.vec2 = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.cos.lowp_compute.vec3 = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.cos.lowp_compute.vec4 = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.cos.highp_compute.scalar = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.cos.highp_compute.vec2 = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.cos.highp_compute.vec3 = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.cos.highp_compute.vec4 = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.tan.lowp_compute.scalar = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.tan.lowp_compute.vec2 = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.tan.lowp_compute.vec3 = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.tan.lowp_compute.vec4 = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.tan.highp_compute.scalar = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.tan.highp_compute.vec2 = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.tan.highp_compute.vec3 = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.tan.highp_compute.vec4 = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.asin.lowp_compute.scalar = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.asin.lowp_compute.vec2 = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.asin.lowp_compute.vec3 = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.asin.lowp_compute.vec4 = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.asin.mediump_compute.scalar = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.asin.mediump_compute.vec2 = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.asin.mediump_compute.vec3 = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.asin.mediump_compute.vec4 = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.asin.highp_compute.scalar = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.asin.highp_compute.vec2 = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.asin.highp_compute.vec3 = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.asin.highp_compute.vec4 = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.acos.lowp_compute.scalar = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.acos.lowp_compute.vec2 = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.acos.lowp_compute.vec3 = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.acos.lowp_compute.vec4 = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.acos.highp_compute.scalar = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.acos.highp_compute.vec2 = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.acos.highp_compute.vec3 = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.acos.highp_compute.vec4 = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.atan2.lowp_compute.scalar = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.atan2.lowp_compute.vec2 = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.atan2.lowp_compute.vec3 = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.atan2.lowp_compute.vec4 = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.atan.lowp_compute.scalar = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.atan.lowp_compute.vec2 = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.atan.lowp_compute.vec3 = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.atan.lowp_compute.vec4 = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.atan.highp_compute.scalar = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.atan.highp_compute.vec2 = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.atan.highp_compute.vec3 = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.atan.highp_compute.vec4 = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.sinh.lowp_compute.scalar = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.sinh.lowp_compute.vec2 = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.sinh.lowp_compute.vec3 = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.sinh.lowp_compute.vec4 = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.sinh.mediump_compute.scalar = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.sinh.mediump_compute.vec2 = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.sinh.mediump_compute.vec3 = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.sinh.mediump_compute.vec4 = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.sinh.highp_compute.scalar = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.sinh.highp_compute.vec2 = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.sinh.highp_compute.vec3 = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.sinh.highp_compute.vec4 = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.cosh.lowp_compute.scalar = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.cosh.lowp_compute.vec2 = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.cosh.lowp_compute.vec3 = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.cosh.lowp_compute.vec4 = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.cosh.mediump_compute.scalar = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.cosh.mediump_compute.vec2 = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.cosh.mediump_compute.vec3 = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.cosh.mediump_compute.vec4 = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.cosh.highp_compute.scalar = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.cosh.highp_compute.vec2 = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.cosh.highp_compute.vec3 = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.cosh.highp_compute.vec4 = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.tanh.lowp_compute.scalar = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.tanh.lowp_compute.vec2 = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.tanh.lowp_compute.vec3 = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.tanh.lowp_compute.vec4 = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.tanh.mediump_compute.scalar = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.tanh.mediump_compute.vec2 = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.tanh.mediump_compute.vec3 = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.tanh.mediump_compute.vec4 = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.tanh.highp_compute.scalar = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.tanh.highp_compute.vec2 = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.tanh.highp_compute.vec3 = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.tanh.highp_compute.vec4 = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.asinh.lowp_compute.scalar = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.asinh.lowp_compute.vec2 = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.asinh.lowp_compute.vec3 = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.asinh.lowp_compute.vec4 = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.asinh.mediump_compute.scalar = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.asinh.mediump_compute.vec2 = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.asinh.mediump_compute.vec3 = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.asinh.mediump_compute.vec4 = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.asinh.highp_compute.scalar = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.asinh.highp_compute.vec2 = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.asinh.highp_compute.vec3 = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.asinh.highp_compute.vec4 = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.acosh.lowp_compute.scalar = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.acosh.lowp_compute.vec2 = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.acosh.lowp_compute.vec3 = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.acosh.lowp_compute.vec4 = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.acosh.mediump_compute.scalar = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.acosh.mediump_compute.vec2 = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.acosh.mediump_compute.vec3 = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.acosh.mediump_compute.vec4 = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.atanh.lowp_compute.scalar = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.atanh.lowp_compute.vec2 = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.atanh.lowp_compute.vec3 = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.atanh.lowp_compute.vec4 = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.atanh.mediump_compute.scalar = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.atanh.mediump_compute.vec2 = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.atanh.mediump_compute.vec3 = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.atanh.mediump_compute.vec4 = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.pow.lowp_compute.scalar = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.pow.lowp_compute.vec2 = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.pow.lowp_compute.vec3 = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.pow.lowp_compute.vec4 = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.pow.mediump_compute.scalar = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.pow.mediump_compute.vec2 = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.pow.mediump_compute.vec3 = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.pow.mediump_compute.vec4 = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.pow.highp_compute.scalar = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.pow.highp_compute.vec2 = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.pow.highp_compute.vec3 = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.pow.highp_compute.vec4 = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.exp.lowp_compute.scalar = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.exp.lowp_compute.vec2 = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.exp.lowp_compute.vec3 = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.exp.lowp_compute.vec4 = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.exp.mediump_compute.scalar = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.exp.mediump_compute.vec2 = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.exp.mediump_compute.vec3 = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.exp.mediump_compute.vec4 = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.exp.highp_compute.scalar = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.exp.highp_compute.vec2 = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.exp.highp_compute.vec3 = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.exp.highp_compute.vec4 = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.log.lowp_compute.scalar = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.log.lowp_compute.vec2 = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.log.lowp_compute.vec3 = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.log.lowp_compute.vec4 = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.log.mediump_compute.scalar = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.log.mediump_compute.vec2 = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.log.mediump_compute.vec3 = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.log.mediump_compute.vec4 = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.log.highp_compute.scalar = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.log.highp_compute.vec2 = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.log.highp_compute.vec3 = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.log.highp_compute.vec4 = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.exp2.lowp_compute.scalar = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.exp2.lowp_compute.vec2 = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.exp2.lowp_compute.vec3 = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.exp2.lowp_compute.vec4 = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.exp2.mediump_compute.scalar = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.exp2.mediump_compute.vec2 = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.exp2.mediump_compute.vec3 = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.exp2.mediump_compute.vec4 = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.exp2.highp_compute.scalar = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.exp2.highp_compute.vec2 = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.exp2.highp_compute.vec3 = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.exp2.highp_compute.vec4 = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.log2.lowp_compute.scalar = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.log2.lowp_compute.vec2 = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.log2.lowp_compute.vec3 = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.log2.lowp_compute.vec4 = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.log2.mediump_compute.scalar = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.log2.mediump_compute.vec2 = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.log2.mediump_compute.vec3 = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.log2.mediump_compute.vec4 = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.log2.highp_compute.scalar = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.log2.highp_compute.vec2 = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.log2.highp_compute.vec3 = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.log2.highp_compute.vec4 = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.sqrt.lowp_compute.scalar = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.sqrt.lowp_compute.vec2 = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.sqrt.lowp_compute.vec3 = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.sqrt.lowp_compute.vec4 = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.sqrt.mediump_compute.scalar = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.sqrt.mediump_compute.vec2 = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.sqrt.mediump_compute.vec3 = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.sqrt.mediump_compute.vec4 = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.sqrt.highp_compute.scalar = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.sqrt.highp_compute.vec2 = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.sqrt.highp_compute.vec3 = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.sqrt.highp_compute.vec4 = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.inversesqrt.lowp_compute.scalar = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.inversesqrt.lowp_compute.vec2 = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.inversesqrt.lowp_compute.vec3 = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.inversesqrt.lowp_compute.vec4 = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.inversesqrt.mediump_compute.scalar = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.inversesqrt.mediump_compute.vec2 = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.inversesqrt.mediump_compute.vec3 = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.inversesqrt.mediump_compute.vec4 = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.inversesqrt.highp_compute.scalar = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.inversesqrt.highp_compute.vec2 = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.inversesqrt.highp_compute.vec3 = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.inversesqrt.highp_compute.vec4 = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.abs.lowp_compute.scalar = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.abs.lowp_compute.vec2 = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.abs.lowp_compute.vec3 = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.abs.lowp_compute.vec4 = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.abs.mediump_compute.scalar = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.abs.mediump_compute.vec2 = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.abs.mediump_compute.vec3 = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.abs.mediump_compute.vec4 = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.abs.highp_compute.scalar = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.abs.highp_compute.vec2 = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.abs.highp_compute.vec3 = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.abs.highp_compute.vec4 = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.sign.lowp_compute.scalar = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.sign.lowp_compute.vec2 = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.sign.lowp_compute.vec3 = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.sign.lowp_compute.vec4 = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.sign.mediump_compute.scalar = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.sign.mediump_compute.vec2 = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.sign.mediump_compute.vec3 = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.sign.mediump_compute.vec4 = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.sign.highp_compute.scalar = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.sign.highp_compute.vec2 = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.sign.highp_compute.vec3 = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.sign.highp_compute.vec4 = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.floor.lowp_compute.scalar = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.floor.lowp_compute.vec2 = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.floor.lowp_compute.vec3 = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.floor.lowp_compute.vec4 = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.floor.mediump_compute.scalar = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.floor.mediump_compute.vec2 = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.floor.mediump_compute.vec3 = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.floor.mediump_compute.vec4 = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.floor.highp_compute.scalar = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.floor.highp_compute.vec2 = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.floor.highp_compute.vec3 = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.floor.highp_compute.vec4 = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.trunc.lowp_compute.scalar = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.trunc.lowp_compute.vec2 = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.trunc.lowp_compute.vec3 = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.trunc.lowp_compute.vec4 = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.trunc.mediump_compute.scalar = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.trunc.mediump_compute.vec2 = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.trunc.mediump_compute.vec3 = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.trunc.mediump_compute.vec4 = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.trunc.highp_compute.scalar = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.trunc.highp_compute.vec2 = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.trunc.highp_compute.vec3 = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.trunc.highp_compute.vec4 = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.round.lowp_compute.scalar = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.round.lowp_compute.vec2 = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.round.lowp_compute.vec3 = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.round.lowp_compute.vec4 = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.round.mediump_compute.scalar = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.round.mediump_compute.vec2 = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.round.mediump_compute.vec3 = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.round.mediump_compute.vec4 = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.round.highp_compute.scalar = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.round.highp_compute.vec2 = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.round.highp_compute.vec3 = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.round.highp_compute.vec4 = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.roundeven.lowp_compute.scalar = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.roundeven.lowp_compute.vec2 = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.roundeven.lowp_compute.vec3 = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.roundeven.lowp_compute.vec4 = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.roundeven.mediump_compute.scalar = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.roundeven.mediump_compute.vec2 = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.roundeven.mediump_compute.vec3 = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.roundeven.mediump_compute.vec4 = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.roundeven.highp_compute.scalar = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.roundeven.highp_compute.vec2 = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.roundeven.highp_compute.vec3 = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.roundeven.highp_compute.vec4 = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.ceil.lowp_compute.scalar = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.ceil.lowp_compute.vec2 = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.ceil.lowp_compute.vec3 = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.ceil.lowp_compute.vec4 = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.ceil.mediump_compute.scalar = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.ceil.mediump_compute.vec2 = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.ceil.mediump_compute.vec3 = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.ceil.mediump_compute.vec4 = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.ceil.highp_compute.scalar = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.ceil.highp_compute.vec2 = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.ceil.highp_compute.vec3 = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.ceil.highp_compute.vec4 = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.fract.lowp_compute.scalar = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.fract.lowp_compute.vec2 = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.fract.lowp_compute.vec3 = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.fract.lowp_compute.vec4 = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.fract.mediump_compute.scalar = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.fract.mediump_compute.vec2 = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.fract.mediump_compute.vec3 = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.fract.mediump_compute.vec4 = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.fract.highp_compute.scalar = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.fract.highp_compute.vec2 = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.fract.highp_compute.vec3 = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.fract.highp_compute.vec4 = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.mod.lowp_compute.scalar = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.mod.lowp_compute.vec2 = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.mod.lowp_compute.vec3 = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.mod.lowp_compute.vec4 = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.mod.mediump_compute.scalar = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.mod.mediump_compute.vec2 = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.mod.mediump_compute.vec3 = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.mod.mediump_compute.vec4 = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.modf.lowp_compute = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.modf.mediump_compute = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.modf.highp_compute = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.min.lowp_compute.scalar = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.min.lowp_compute.vec2 = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.min.lowp_compute.vec3 = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.min.lowp_compute.vec4 = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.min.mediump_compute.scalar = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.min.mediump_compute.vec2 = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.min.mediump_compute.vec3 = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.min.mediump_compute.vec4 = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.max.lowp_compute.scalar = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.max.lowp_compute.vec2 = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.max.lowp_compute.vec3 = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.max.lowp_compute.vec4 = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.max.mediump_compute.scalar = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.max.mediump_compute.vec2 = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.max.mediump_compute.vec3 = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.max.mediump_compute.vec4 = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.clamp.lowp_compute.scalar = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.clamp.lowp_compute.vec2 = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.clamp.lowp_compute.vec3 = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.clamp.lowp_compute.vec4 = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.clamp.mediump_compute.scalar = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.clamp.mediump_compute.vec2 = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.clamp.mediump_compute.vec3 = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.clamp.mediump_compute.vec4 = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.mix.lowp_compute.scalar = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.mix.lowp_compute.vec2 = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.mix.lowp_compute.vec3 = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.mix.lowp_compute.vec4 = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.mix.mediump_compute.scalar = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.mix.mediump_compute.vec2 = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.mix.mediump_compute.vec3 = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.mix.mediump_compute.vec4 = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.mix.highp_compute.scalar = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.mix.highp_compute.vec2 = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.mix.highp_compute.vec3 = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.mix.highp_compute.vec4 = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.step.lowp_compute.scalar = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.step.lowp_compute.vec2 = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.step.lowp_compute.vec3 = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.step.lowp_compute.vec4 = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.step.mediump_compute.scalar = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.step.mediump_compute.vec2 = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.step.mediump_compute.vec3 = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.step.mediump_compute.vec4 = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.step.highp_compute.scalar = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.step.highp_compute.vec2 = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.step.highp_compute.vec3 = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.step.highp_compute.vec4 = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.smoothstep.lowp_compute.scalar = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.smoothstep.lowp_compute.vec2 = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.smoothstep.lowp_compute.vec3 = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.smoothstep.lowp_compute.vec4 = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.length.lowp_compute.scalar = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.length.lowp_compute.vec2 = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.length.lowp_compute.vec3 = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.length.lowp_compute.vec4 = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.length.mediump_compute.scalar = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.length.mediump_compute.vec2 = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.length.mediump_compute.vec3 = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.length.mediump_compute.vec4 = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.length.highp_compute.scalar = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.length.highp_compute.vec2 = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.length.highp_compute.vec3 = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.length.highp_compute.vec4 = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.distance.lowp_compute.scalar = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.distance.lowp_compute.vec2 = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.distance.lowp_compute.vec3 = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.distance.lowp_compute.vec4 = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.distance.mediump_compute.scalar = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.distance.mediump_compute.vec2 = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.distance.mediump_compute.vec3 = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.distance.mediump_compute.vec4 = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.distance.highp_compute.scalar = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.distance.highp_compute.vec2 = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.distance.highp_compute.vec3 = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.distance.highp_compute.vec4 = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.dot.lowp_compute.scalar = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.dot.lowp_compute.vec2 = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.dot.lowp_compute.vec3 = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.dot.lowp_compute.vec4 = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.dot.mediump_compute.scalar = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.dot.mediump_compute.vec2 = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.dot.mediump_compute.vec3 = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.dot.mediump_compute.vec4 = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.dot.highp_compute.scalar = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.dot.highp_compute.vec2 = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.dot.highp_compute.vec3 = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.cross.lowp_compute = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.cross.mediump_compute = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.cross.highp_compute = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.normalize.lowp_compute.scalar = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.normalize.lowp_compute.vec2 = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.normalize.lowp_compute.vec3 = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.normalize.lowp_compute.vec4 = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.normalize.mediump_compute.scalar = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.normalize.mediump_compute.vec2 = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.normalize.mediump_compute.vec3 = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.normalize.mediump_compute.vec4 = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.normalize.highp_compute.scalar = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.normalize.highp_compute.vec2 = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.normalize.highp_compute.vec3 = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.normalize.highp_compute.vec4 = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.faceforward.lowp_compute.scalar = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.faceforward.lowp_compute.vec2 = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.faceforward.lowp_compute.vec3 = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.faceforward.lowp_compute.vec4 = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.faceforward.mediump_compute.scalar = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.faceforward.mediump_compute.vec2 = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.faceforward.mediump_compute.vec3 = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.faceforward.mediump_compute.vec4 = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.faceforward.highp_compute.scalar = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.faceforward.highp_compute.vec2 = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.faceforward.highp_compute.vec3 = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.faceforward.highp_compute.vec4 = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.reflect.lowp_compute.scalar = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.reflect.lowp_compute.vec2 = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.reflect.lowp_compute.vec3 = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.reflect.lowp_compute.vec4 = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.reflect.mediump_compute.vec2 = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.reflect.mediump_compute.vec3 = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.reflect.mediump_compute.vec4 = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.reflect.highp_compute.vec2 = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.reflect.highp_compute.vec3 = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.refract.lowp_compute.scalar = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.refract.lowp_compute.vec2 = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.refract.lowp_compute.vec3 = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.refract.lowp_compute.vec4 = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.refract.mediump_compute.scalar = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.refract.mediump_compute.vec2 = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.refract.mediump_compute.vec3 = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.refract.mediump_compute.vec4 = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.refract.highp_compute.scalar = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.refract.highp_compute.vec2 = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.refract.highp_compute.vec3 = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.refract.highp_compute.vec4 = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.matrixcompmult.lowp_compute.mat2 = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.matrixcompmult.lowp_compute.mat2x3 = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.matrixcompmult.lowp_compute.mat2x4 = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.matrixcompmult.lowp_compute.mat3x2 = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.matrixcompmult.lowp_compute.mat3 = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.matrixcompmult.lowp_compute.mat3x4 = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.matrixcompmult.lowp_compute.mat4x2 = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.matrixcompmult.lowp_compute.mat4x3 = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.matrixcompmult.lowp_compute.mat4 = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.matrixcompmult.mediump_compute.mat2 = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.matrixcompmult.mediump_compute.mat2x3 = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.matrixcompmult.mediump_compute.mat2x4 = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.matrixcompmult.mediump_compute.mat3x2 = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.matrixcompmult.mediump_compute.mat3 = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.matrixcompmult.mediump_compute.mat3x4 = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.matrixcompmult.mediump_compute.mat4x2 = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.matrixcompmult.mediump_compute.mat4x3 = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.matrixcompmult.mediump_compute.mat4 = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.matrixcompmult.highp_compute.mat2 = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.matrixcompmult.highp_compute.mat2x3 = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.matrixcompmult.highp_compute.mat2x4 = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.matrixcompmult.highp_compute.mat3x2 = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.matrixcompmult.highp_compute.mat3 = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.matrixcompmult.highp_compute.mat3x4 = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.matrixcompmult.highp_compute.mat4x2 = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.matrixcompmult.highp_compute.mat4x3 = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.matrixcompmult.highp_compute.mat4 = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.outerproduct.lowp_compute.mat2 = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.outerproduct.lowp_compute.mat2x3 = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.outerproduct.lowp_compute.mat2x4 = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.outerproduct.lowp_compute.mat3x2 = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.outerproduct.lowp_compute.mat3 = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.outerproduct.lowp_compute.mat3x4 = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.outerproduct.lowp_compute.mat4x2 = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.outerproduct.lowp_compute.mat4x3 = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.outerproduct.lowp_compute.mat4 = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.outerproduct.mediump_compute.mat2 = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.outerproduct.mediump_compute.mat2x3 = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.outerproduct.mediump_compute.mat2x4 = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.outerproduct.mediump_compute.mat3x2 = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.outerproduct.mediump_compute.mat3 = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.outerproduct.mediump_compute.mat3x4 = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.outerproduct.mediump_compute.mat4x2 = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.outerproduct.mediump_compute.mat4x3 = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.outerproduct.mediump_compute.mat4 = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.outerproduct.highp_compute.mat2 = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.outerproduct.highp_compute.mat2x3 = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.outerproduct.highp_compute.mat2x4 = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.outerproduct.highp_compute.mat3x2 = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.outerproduct.highp_compute.mat3 = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.outerproduct.highp_compute.mat3x4 = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.outerproduct.highp_compute.mat4x2 = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.outerproduct.highp_compute.mat4x3 = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.outerproduct.highp_compute.mat4 = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.transpose.lowp_compute.mat2 = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.transpose.lowp_compute.mat2x3 = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.transpose.lowp_compute.mat2x4 = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.transpose.lowp_compute.mat3x2 = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.transpose.lowp_compute.mat3 = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.transpose.lowp_compute.mat3x4 = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.transpose.lowp_compute.mat4x2 = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.transpose.lowp_compute.mat4x3 = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.transpose.lowp_compute.mat4 = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.transpose.mediump_compute.mat2 = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.transpose.mediump_compute.mat2x3 = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.transpose.mediump_compute.mat2x4 = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.transpose.mediump_compute.mat3x2 = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.transpose.mediump_compute.mat3 = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.transpose.mediump_compute.mat3x4 = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.transpose.mediump_compute.mat4x2 = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.transpose.mediump_compute.mat4x3 = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.transpose.mediump_compute.mat4 = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.transpose.highp_compute.mat2 = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.transpose.highp_compute.mat2x3 = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.transpose.highp_compute.mat2x4 = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.transpose.highp_compute.mat3x2 = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.transpose.highp_compute.mat3 = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.transpose.highp_compute.mat3x4 = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.transpose.highp_compute.mat4x2 = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.transpose.highp_compute.mat4x3 = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.transpose.highp_compute.mat4 = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.determinant.lowp_compute.mat2 = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.determinant.mediump_compute.mat2 = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.determinant.highp_compute.mat2 = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.inverse.lowp_compute.mat2 = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.inverse.mediump_compute.mat2 = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.frexp.* = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.ldexp.* = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.linkage.shader_storage_block.mismatch_number_of_declarations = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.linkage.shader_storage_block.mismatch_order = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.linkage.shader_storage_block.mismatch_type = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.linkage.shader_storage_block.mismatch_member_name = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.linkage.shader_storage_block.mismatch_member_unsized_sized_array = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.linkage.shader_storage_block.mismatch_member_array_size = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.linkage.shader_storage_block.mismatch_with_and_without_instance_name = FAIL
+1951 D3D11 : dEQP-GLES31.functional.shaders.linkage.shader_storage_block.mismatch_block_array_size = FAIL
+1442 D3D11 : dEQP-GLES31.functional.synchronization.* = FAIL
+1951 D3D11 : dEQP-GLES31.functional.ssbo.* = FAIL
+1442 D3D11 : dEQP-GLES31.functional.shaders.builtin_var.compute.num_work_groups = FAIL
+1442 D3D11 : dEQP-GLES31.functional.shaders.builtin_var.compute.work_group_size = FAIL
+1442 D3D11 : dEQP-GLES31.functional.shaders.builtin_var.compute.work_group_id = FAIL
+1442 D3D11 : dEQP-GLES31.functional.shaders.builtin_var.compute.local_invocation_id = FAIL
+1442 D3D11 : dEQP-GLES31.functional.shaders.builtin_var.compute.global_invocation_id = FAIL
+1442 D3D11 : dEQP-GLES31.functional.shaders.builtin_var.compute.local_invocation_index = FAIL
 
 // OPENGL Failing Tests
 1665 WIN NVIDIA OPENGL : dEQP-GLES31.functional.draw_indirect.negative.command_offset_not_in_buffer_unsigned32_wrap = FAIL
 1442 NVIDIA OPENGL : dEQP-GLES31.functional.fbo.no_attachments.maximums.all = FAIL
+1442 OPENGL : dEQP-GLES31.functional.program_interface_query.atomic_counter_buffer.buffer_data_size = FAIL
+1442 OPENGL : dEQP-GLES31.functional.program_interface_query.atomic_counter_buffer.referenced_by* = FAIL
+1442 OPENGL : dEQP-GLES31.functional.program_interface_query.buffer_limited_query.* = FAIL
+1442 OPENGL : dEQP-GLES31.functional.program_interface_query.buffer_variable.* = FAIL
+1442 OPENGL : dEQP-GLES31.functional.program_interface_query.program_input.* = FAIL
+1442 OPENGL : dEQP-GLES31.functional.program_interface_query.program_output.* = FAIL
+1442 OPENGL : dEQP-GLES31.functional.program_interface_query.shader_storage_block.* = FAIL
+1442 OPENGL : dEQP-GLES31.functional.program_interface_query.transform_feedback_varying.* = FAIL
+1442 OPENGL : dEQP-GLES31.functional.program_interface_query.uniform.referenced_by_shader.* = FAIL
+1442 OPENGL : dEQP-GLES31.functional.program_interface_query.uniform.random.* = FAIL
+1442 OPENGL : dEQP-GLES31.functional.program_interface_query.uniform_block.resource_list.block_array = FAIL
+1442 OPENGL : dEQP-GLES31.functional.program_interface_query.uniform_block.resource_list.block_array_single_element = FAIL
+1442 OPENGL : dEQP-GLES31.functional.program_interface_query.uniform_block.referenced_by.* = FAIL
+1442 OPENGL : dEQP-GLES31.functional.compute.basic.copy_image_to_ssbo_large = FAIL
+1442 OPENGL : dEQP-GLES31.functional.compute.basic.copy_ssbo_to_image_large = FAIL
+2272 WIN NVIDIA OPENGL : dEQP-GLES31.functional.ssbo.layout.2_level_unsized* = FAIL
+2272 WIN NVIDIA OPENGL : dEQP-GLES31.functional.ssbo.layout.3_level_unsized* = FAIL
+2272 WIN NVIDIA OPENGL : dEQP-GLES31.functional.ssbo.layout.random.arrays_of_arrays* = FAIL
+2272 WIN NVIDIA OPENGL : dEQP-GLES31.functional.ssbo.layout.random.nested_structs* = FAIL
+2272 WIN NVIDIA OPENGL : dEQP-GLES31.functional.ssbo.layout.random.all* = FAIL
 
 // OpenGL and D3D11 Failing Tests
-1663 OPENGL D3D11 : dEQP-GLES31.functional.draw_indirect.compute_interop.* = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_var.compute.num_work_groups = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_var.compute.work_group_size = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_var.compute.work_group_id = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_var.compute.local_invocation_id = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_var.compute.global_invocation_id = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_var.compute.local_invocation_index = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.abs.float_lowp_compute = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.abs.float_mediump_compute = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.abs.float_highp_compute = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.abs.vec2_lowp_compute = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.abs.vec2_mediump_compute = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.abs.vec2_highp_compute = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.abs.vec3_lowp_compute = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.abs.vec3_mediump_compute = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.abs.vec3_highp_compute = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.abs.vec4_lowp_compute = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.abs.vec4_mediump_compute = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.abs.vec4_highp_compute = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.abs.int_lowp_compute = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.abs.int_mediump_compute = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.abs.int_highp_compute = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.abs.ivec2_lowp_compute = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.abs.ivec2_mediump_compute = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.abs.ivec2_highp_compute = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.abs.ivec3_lowp_compute = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.abs.ivec3_mediump_compute = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.abs.ivec3_highp_compute = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.abs.ivec4_lowp_compute = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.abs.ivec4_mediump_compute = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.abs.ivec4_highp_compute = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.sign.float_lowp_compute = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.sign.float_mediump_compute = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.sign.float_highp_compute = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.sign.vec2_lowp_compute = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.sign.vec2_mediump_compute = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.sign.vec2_highp_compute = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.sign.vec3_lowp_compute = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.sign.vec3_mediump_compute = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.sign.vec3_highp_compute = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.sign.vec4_lowp_compute = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.sign.vec4_mediump_compute = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.sign.vec4_highp_compute = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.sign.int_lowp_compute = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.sign.int_mediump_compute = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.sign.int_highp_compute = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.sign.ivec2_lowp_compute = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.sign.ivec2_mediump_compute = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.sign.ivec2_highp_compute = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.sign.ivec3_lowp_compute = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.sign.ivec3_mediump_compute = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.sign.ivec3_highp_compute = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.sign.ivec4_lowp_compute = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.sign.ivec4_mediump_compute = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.sign.ivec4_highp_compute = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.floor.float_lowp_compute = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.floor.float_mediump_compute = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.floor.float_highp_compute = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.floor.vec2_lowp_compute = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.floor.vec2_mediump_compute = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.floor.vec2_highp_compute = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.floor.vec3_lowp_compute = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.floor.vec3_mediump_compute = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.floor.vec3_highp_compute = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.floor.vec4_lowp_compute = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.floor.vec4_mediump_compute = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.floor.vec4_highp_compute = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.trunc.float_lowp_compute = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.trunc.float_mediump_compute = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.trunc.float_highp_compute = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.trunc.vec2_lowp_compute = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.trunc.vec2_mediump_compute = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.trunc.vec2_highp_compute = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.trunc.vec3_lowp_compute = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.trunc.vec3_mediump_compute = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.trunc.vec3_highp_compute = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.trunc.vec4_lowp_compute = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.trunc.vec4_mediump_compute = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.trunc.vec4_highp_compute = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.round.float_lowp_compute = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.round.float_mediump_compute = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.round.float_highp_compute = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.round.vec2_lowp_compute = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.round.vec2_mediump_compute = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.round.vec2_highp_compute = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.round.vec3_lowp_compute = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.round.vec3_mediump_compute = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.round.vec3_highp_compute = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.round.vec4_lowp_compute = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.round.vec4_mediump_compute = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.round.vec4_highp_compute = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.roundeven.float_lowp_compute = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.roundeven.float_mediump_compute = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.roundeven.float_highp_compute = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.roundeven.vec2_lowp_compute = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.roundeven.vec2_mediump_compute = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.roundeven.vec2_highp_compute = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.roundeven.vec3_lowp_compute = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.roundeven.vec3_mediump_compute = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.roundeven.vec3_highp_compute = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.roundeven.vec4_lowp_compute = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.roundeven.vec4_mediump_compute = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.roundeven.vec4_highp_compute = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.ceil.float_lowp_compute = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.ceil.float_mediump_compute = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.ceil.float_highp_compute = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.ceil.vec2_lowp_compute = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.ceil.vec2_mediump_compute = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.ceil.vec2_highp_compute = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.ceil.vec3_lowp_compute = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.ceil.vec3_mediump_compute = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.ceil.vec3_highp_compute = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.ceil.vec4_lowp_compute = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.ceil.vec4_mediump_compute = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.ceil.vec4_highp_compute = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.fract.float_lowp_compute = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.fract.float_mediump_compute = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.fract.float_highp_compute = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.fract.vec2_lowp_compute = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.fract.vec2_mediump_compute = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.fract.vec2_highp_compute = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.fract.vec3_lowp_compute = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.fract.vec3_mediump_compute = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.fract.vec3_highp_compute = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.fract.vec4_lowp_compute = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.fract.vec4_mediump_compute = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.fract.vec4_highp_compute = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.modf.float_lowp_compute = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.modf.float_mediump_compute = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.modf.float_highp_compute = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.modf.vec2_lowp_compute = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.modf.vec2_mediump_compute = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.modf.vec2_highp_compute = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.modf.vec3_lowp_compute = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.modf.vec3_mediump_compute = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.modf.vec3_highp_compute = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.modf.vec4_lowp_compute = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.modf.vec4_mediump_compute = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.modf.vec4_highp_compute = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.isnan.float_lowp_compute = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.isnan.float_mediump_compute = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.isnan.float_highp_compute = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.isnan.vec2_lowp_compute = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.isnan.vec2_mediump_compute = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.isnan.vec2_highp_compute = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.isnan.vec3_lowp_compute = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.isnan.vec3_mediump_compute = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.isnan.vec3_highp_compute = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.isnan.vec4_lowp_compute = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.isnan.vec4_mediump_compute = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.isnan.vec4_highp_compute = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.isinf.float_lowp_compute = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.isinf.float_mediump_compute = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.isinf.float_highp_compute = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.isinf.vec2_lowp_compute = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.isinf.vec2_mediump_compute = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.isinf.vec2_highp_compute = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.isinf.vec3_lowp_compute = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.isinf.vec3_mediump_compute = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.isinf.vec3_highp_compute = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.isinf.vec4_lowp_compute = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.isinf.vec4_mediump_compute = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.isinf.vec4_highp_compute = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.floatbitstoint.float_lowp_compute = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.floatbitstoint.float_mediump_compute = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.floatbitstoint.float_highp_compute = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.floatbitstoint.vec2_lowp_compute = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.floatbitstoint.vec2_mediump_compute = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.floatbitstoint.vec2_highp_compute = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.floatbitstoint.vec3_lowp_compute = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.floatbitstoint.vec3_mediump_compute = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.floatbitstoint.vec3_highp_compute = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.floatbitstoint.vec4_lowp_compute = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.floatbitstoint.vec4_mediump_compute = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.floatbitstoint.vec4_highp_compute = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.floatbitstouint.float_lowp_compute = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.floatbitstouint.float_mediump_compute = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.floatbitstouint.float_highp_compute = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.floatbitstouint.vec2_lowp_compute = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.floatbitstouint.vec2_mediump_compute = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.floatbitstouint.vec2_highp_compute = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.floatbitstouint.vec3_lowp_compute = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.floatbitstouint.vec3_mediump_compute = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.floatbitstouint.vec3_highp_compute = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.floatbitstouint.vec4_lowp_compute = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.floatbitstouint.vec4_mediump_compute = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.floatbitstouint.vec4_highp_compute = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.frexp.float_lowp_compute = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.frexp.float_mediump_compute = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.frexp.float_highp_compute = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.frexp.vec2_lowp_compute = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.frexp.vec2_mediump_compute = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.frexp.vec2_highp_compute = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.frexp.vec3_lowp_compute = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.frexp.vec3_mediump_compute = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.frexp.vec3_highp_compute = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.frexp.vec4_lowp_compute = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.frexp.vec4_mediump_compute = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.frexp.vec4_highp_compute = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.ldexp.float_lowp_compute = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.ldexp.float_mediump_compute = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.ldexp.float_highp_compute = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.ldexp.vec2_lowp_compute = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.ldexp.vec2_mediump_compute = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.ldexp.vec2_highp_compute = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.ldexp.vec3_lowp_compute = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.ldexp.vec3_mediump_compute = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.ldexp.vec3_highp_compute = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.ldexp.vec4_lowp_compute = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.ldexp.vec4_mediump_compute = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.ldexp.vec4_highp_compute = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.intbitstofloat.int_highp_compute = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.intbitstofloat.ivec2_highp_compute = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.intbitstofloat.ivec3_highp_compute = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.uintbitstofloat.uint_highp_compute = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.uintbitstofloat.uvec2_highp_compute = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.uintbitstofloat.uvec3_highp_compute = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.pack_unpack.packsnorm4x8_lowp_compute = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.pack_unpack.packsnorm4x8_mediump_compute = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.pack_unpack.packsnorm4x8_highp_compute = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.pack_unpack.unpacksnorm4x8_compute = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.pack_unpack.packunorm4x8_lowp_compute = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.pack_unpack.packunorm4x8_mediump_compute = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.pack_unpack.packunorm4x8_highp_compute = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.pack_unpack.unpackunorm4x8_compute = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.pack_unpack.packsnorm2x16_lowp_compute = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.pack_unpack.packsnorm2x16_mediump_compute = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.pack_unpack.packsnorm2x16_highp_compute = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.pack_unpack.unpacksnorm2x16_compute = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.pack_unpack.packunorm2x16_lowp_compute = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.pack_unpack.packunorm2x16_mediump_compute = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.pack_unpack.packunorm2x16_highp_compute = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.pack_unpack.unpackunorm2x16_compute = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.pack_unpack.packhalf2x16_compute = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.pack_unpack.unpackhalf2x16_compute = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.integer.uaddcarry.uint_lowp_compute = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.integer.uaddcarry.uint_mediump_compute = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.integer.uaddcarry.uint_highp_compute = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.integer.uaddcarry.uvec2_lowp_compute = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.integer.uaddcarry.uvec2_mediump_compute = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.integer.uaddcarry.uvec2_highp_compute = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.integer.uaddcarry.uvec3_lowp_compute = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.integer.uaddcarry.uvec3_mediump_compute = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.integer.uaddcarry.uvec3_highp_compute = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.integer.uaddcarry.uvec4_lowp_compute = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.integer.uaddcarry.uvec4_mediump_compute = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.integer.uaddcarry.uvec4_highp_compute = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.integer.usubborrow.uint_lowp_compute = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.integer.usubborrow.uint_mediump_compute = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.integer.usubborrow.uint_highp_compute = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.integer.usubborrow.uvec2_lowp_compute = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.integer.usubborrow.uvec2_mediump_compute = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.integer.usubborrow.uvec2_highp_compute = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.integer.usubborrow.uvec3_lowp_compute = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.integer.usubborrow.uvec3_mediump_compute = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.integer.usubborrow.uvec3_highp_compute = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.integer.usubborrow.uvec4_lowp_compute = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.integer.usubborrow.uvec4_mediump_compute = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.integer.usubborrow.uvec4_highp_compute = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.integer.umulextended.uint_highp_compute = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.integer.umulextended.uvec2_highp_compute = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.integer.umulextended.uvec3_highp_compute = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.integer.umulextended.uvec4_highp_compute = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.integer.imulextended.int_highp_compute = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.integer.imulextended.ivec2_highp_compute = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.integer.imulextended.ivec3_highp_compute = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.integer.imulextended.ivec4_highp_compute = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.integer.bitfieldextract.int_lowp_compute = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.integer.bitfieldextract.int_mediump_compute = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.integer.bitfieldextract.int_highp_compute = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.integer.bitfieldextract.ivec2_lowp_compute = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.integer.bitfieldextract.ivec2_mediump_compute = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.integer.bitfieldextract.ivec2_highp_compute = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.integer.bitfieldextract.ivec3_lowp_compute = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.integer.bitfieldextract.ivec3_mediump_compute = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.integer.bitfieldextract.ivec3_highp_compute = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.integer.bitfieldextract.ivec4_lowp_compute = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.integer.bitfieldextract.ivec4_mediump_compute = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.integer.bitfieldextract.ivec4_highp_compute = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.integer.bitfieldextract.uint_lowp_compute = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.integer.bitfieldextract.uint_mediump_compute = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.integer.bitfieldextract.uint_highp_compute = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.integer.bitfieldextract.uvec2_lowp_compute = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.integer.bitfieldextract.uvec2_mediump_compute = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.integer.bitfieldextract.uvec2_highp_compute = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.integer.bitfieldextract.uvec3_lowp_compute = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.integer.bitfieldextract.uvec3_mediump_compute = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.integer.bitfieldextract.uvec3_highp_compute = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.integer.bitfieldextract.uvec4_lowp_compute = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.integer.bitfieldextract.uvec4_mediump_compute = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.integer.bitfieldextract.uvec4_highp_compute = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.integer.bitfieldinsert.int_lowp_compute = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.integer.bitfieldinsert.int_mediump_compute = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.integer.bitfieldinsert.int_highp_compute = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.integer.bitfieldinsert.ivec2_lowp_compute = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.integer.bitfieldinsert.ivec2_mediump_compute = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.integer.bitfieldinsert.ivec2_highp_compute = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.integer.bitfieldinsert.ivec3_lowp_compute = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.integer.bitfieldinsert.ivec3_mediump_compute = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.integer.bitfieldinsert.ivec3_highp_compute = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.integer.bitfieldinsert.ivec4_lowp_compute = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.integer.bitfieldinsert.ivec4_mediump_compute = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.integer.bitfieldinsert.ivec4_highp_compute = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.integer.bitfieldinsert.uint_lowp_compute = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.integer.bitfieldinsert.uint_mediump_compute = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.integer.bitfieldinsert.uint_highp_compute = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.integer.bitfieldinsert.uvec2_lowp_compute = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.integer.bitfieldinsert.uvec2_mediump_compute = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.integer.bitfieldinsert.uvec2_highp_compute = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.integer.bitfieldinsert.uvec3_lowp_compute = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.integer.bitfieldinsert.uvec3_mediump_compute = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.integer.bitfieldinsert.uvec3_highp_compute = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.integer.bitfieldinsert.uvec4_lowp_compute = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.integer.bitfieldinsert.uvec4_mediump_compute = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.integer.bitfieldinsert.uvec4_highp_compute = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.integer.bitfieldreverse.int_lowp_compute = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.integer.bitfieldreverse.int_mediump_compute = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.integer.bitfieldreverse.int_highp_compute = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.integer.bitfieldreverse.ivec2_lowp_compute = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.integer.bitfieldreverse.ivec2_mediump_compute = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.integer.bitfieldreverse.ivec2_highp_compute = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.integer.bitfieldreverse.ivec3_lowp_compute = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.integer.bitfieldreverse.ivec3_mediump_compute = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.integer.bitfieldreverse.ivec3_highp_compute = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.integer.bitfieldreverse.ivec4_lowp_compute = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.integer.bitfieldreverse.ivec4_mediump_compute = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.integer.bitfieldreverse.ivec4_highp_compute = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.integer.bitfieldreverse.uint_lowp_compute = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.integer.bitfieldreverse.uint_mediump_compute = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.integer.bitfieldreverse.uint_highp_compute = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.integer.bitfieldreverse.uvec2_lowp_compute = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.integer.bitfieldreverse.uvec2_mediump_compute = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.integer.bitfieldreverse.uvec2_highp_compute = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.integer.bitfieldreverse.uvec3_lowp_compute = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.integer.bitfieldreverse.uvec3_mediump_compute = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.integer.bitfieldreverse.uvec3_highp_compute = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.integer.bitfieldreverse.uvec4_lowp_compute = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.integer.bitfieldreverse.uvec4_mediump_compute = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.integer.bitfieldreverse.uvec4_highp_compute = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.integer.bitcount.int_lowp_compute = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.integer.bitcount.int_mediump_compute = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.integer.bitcount.int_highp_compute = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.integer.bitcount.ivec2_lowp_compute = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.integer.bitcount.ivec2_mediump_compute = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.integer.bitcount.ivec2_highp_compute = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.integer.bitcount.ivec3_lowp_compute = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.integer.bitcount.ivec3_mediump_compute = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.integer.bitcount.ivec3_highp_compute = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.integer.bitcount.ivec4_lowp_compute = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.integer.bitcount.ivec4_mediump_compute = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.integer.bitcount.ivec4_highp_compute = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.integer.bitcount.uint_lowp_compute = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.integer.bitcount.uint_mediump_compute = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.integer.bitcount.uint_highp_compute = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.integer.bitcount.uvec2_lowp_compute = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.integer.bitcount.uvec2_mediump_compute = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.integer.bitcount.uvec2_highp_compute = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.integer.bitcount.uvec3_lowp_compute = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.integer.bitcount.uvec3_mediump_compute = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.integer.bitcount.uvec3_highp_compute = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.integer.bitcount.uvec4_lowp_compute = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.integer.bitcount.uvec4_mediump_compute = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.integer.bitcount.uvec4_highp_compute = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.integer.findlsb.int_lowp_compute = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.integer.findlsb.int_mediump_compute = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.integer.findlsb.int_highp_compute = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.integer.findlsb.ivec2_lowp_compute = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.integer.findlsb.ivec2_mediump_compute = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.integer.findlsb.ivec2_highp_compute = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.integer.findlsb.ivec3_lowp_compute = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.integer.findlsb.ivec3_mediump_compute = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.integer.findlsb.ivec3_highp_compute = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.integer.findlsb.ivec4_lowp_compute = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.integer.findlsb.ivec4_mediump_compute = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.integer.findlsb.ivec4_highp_compute = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.integer.findlsb.uint_lowp_compute = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.integer.findlsb.uint_mediump_compute = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.integer.findlsb.uint_highp_compute = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.integer.findlsb.uvec2_lowp_compute = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.integer.findlsb.uvec2_mediump_compute = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.integer.findlsb.uvec2_highp_compute = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.integer.findlsb.uvec3_lowp_compute = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.integer.findlsb.uvec3_mediump_compute = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.integer.findlsb.uvec3_highp_compute = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.integer.findlsb.uvec4_lowp_compute = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.integer.findlsb.uvec4_mediump_compute = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.integer.findlsb.uvec4_highp_compute = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.integer.findmsb.int_lowp_compute = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.integer.findmsb.int_mediump_compute = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.integer.findmsb.int_highp_compute = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.integer.findmsb.ivec2_lowp_compute = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.integer.findmsb.ivec2_mediump_compute = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.integer.findmsb.ivec2_highp_compute = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.integer.findmsb.ivec3_lowp_compute = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.integer.findmsb.ivec3_mediump_compute = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.integer.findmsb.ivec3_highp_compute = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.integer.findmsb.ivec4_lowp_compute = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.integer.findmsb.ivec4_mediump_compute = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.integer.findmsb.ivec4_highp_compute = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.integer.findmsb.uint_lowp_compute = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.integer.findmsb.uint_mediump_compute = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.integer.findmsb.uint_highp_compute = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.integer.findmsb.uvec2_lowp_compute = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.integer.findmsb.uvec2_mediump_compute = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.integer.findmsb.uvec2_highp_compute = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.integer.findmsb.uvec3_lowp_compute = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.integer.findmsb.uvec3_mediump_compute = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.integer.findmsb.uvec3_highp_compute = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.integer.findmsb.uvec4_lowp_compute = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.integer.findmsb.uvec4_mediump_compute = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.integer.findmsb.uvec4_highp_compute = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.add.lowp_compute.scalar = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.add.lowp_compute.vec2 = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.add.lowp_compute.vec3 = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.add.lowp_compute.vec4 = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.add.mediump_compute.scalar = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.add.mediump_compute.vec2 = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.add.mediump_compute.vec3 = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.add.mediump_compute.vec4 = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.add.highp_compute.scalar = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.add.highp_compute.vec2 = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.add.highp_compute.vec3 = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.add.highp_compute.vec4 = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.sub.lowp_compute.scalar = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.sub.lowp_compute.vec2 = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.sub.lowp_compute.vec3 = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.sub.lowp_compute.vec4 = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.sub.mediump_compute.scalar = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.sub.mediump_compute.vec2 = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.sub.mediump_compute.vec3 = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.sub.mediump_compute.vec4 = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.sub.highp_compute.scalar = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.sub.highp_compute.vec2 = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.sub.highp_compute.vec3 = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.sub.highp_compute.vec4 = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.mul.lowp_compute.scalar = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.mul.lowp_compute.vec2 = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.mul.lowp_compute.vec3 = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.mul.lowp_compute.vec4 = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.mul.mediump_compute.scalar = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.mul.mediump_compute.vec2 = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.mul.mediump_compute.vec3 = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.mul.mediump_compute.vec4 = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.mul.highp_compute.scalar = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.mul.highp_compute.vec2 = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.mul.highp_compute.vec3 = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.mul.highp_compute.vec4 = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.div.lowp_compute.scalar = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.div.lowp_compute.vec2 = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.div.lowp_compute.vec3 = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.div.lowp_compute.vec4 = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.div.mediump_compute.scalar = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.div.mediump_compute.vec2 = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.div.mediump_compute.vec3 = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.div.mediump_compute.vec4 = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.radians.lowp_compute.scalar = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.radians.lowp_compute.vec2 = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.radians.lowp_compute.vec3 = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.radians.lowp_compute.vec4 = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.radians.mediump_compute.scalar = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.radians.mediump_compute.vec2 = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.radians.mediump_compute.vec3 = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.radians.mediump_compute.vec4 = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.radians.highp_compute.scalar = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.radians.highp_compute.vec2 = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.radians.highp_compute.vec3 = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.radians.highp_compute.vec4 = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.degrees.lowp_compute.scalar = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.degrees.lowp_compute.vec2 = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.degrees.lowp_compute.vec3 = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.degrees.lowp_compute.vec4 = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.degrees.mediump_compute.scalar = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.degrees.mediump_compute.vec2 = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.degrees.mediump_compute.vec3 = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.degrees.mediump_compute.vec4 = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.degrees.highp_compute.scalar = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.degrees.highp_compute.vec2 = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.degrees.highp_compute.vec3 = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.degrees.highp_compute.vec4 = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.sin.lowp_compute.scalar = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.sin.lowp_compute.vec2 = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.sin.lowp_compute.vec3 = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.sin.lowp_compute.vec4 = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.sin.highp_compute.scalar = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.sin.highp_compute.vec2 = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.sin.highp_compute.vec3 = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.sin.highp_compute.vec4 = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.cos.lowp_compute.scalar = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.cos.lowp_compute.vec2 = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.cos.lowp_compute.vec3 = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.cos.lowp_compute.vec4 = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.cos.highp_compute.scalar = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.cos.highp_compute.vec2 = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.cos.highp_compute.vec3 = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.cos.highp_compute.vec4 = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.tan.lowp_compute.scalar = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.tan.lowp_compute.vec2 = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.tan.lowp_compute.vec3 = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.tan.lowp_compute.vec4 = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.tan.highp_compute.scalar = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.tan.highp_compute.vec2 = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.tan.highp_compute.vec3 = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.tan.highp_compute.vec4 = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.asin.lowp_compute.scalar = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.asin.lowp_compute.vec2 = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.asin.lowp_compute.vec3 = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.asin.lowp_compute.vec4 = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.asin.mediump_compute.scalar = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.asin.mediump_compute.vec2 = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.asin.mediump_compute.vec3 = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.asin.mediump_compute.vec4 = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.asin.highp_compute.scalar = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.asin.highp_compute.vec2 = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.asin.highp_compute.vec3 = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.asin.highp_compute.vec4 = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.acos.lowp_compute.scalar = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.acos.lowp_compute.vec2 = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.acos.lowp_compute.vec3 = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.acos.lowp_compute.vec4 = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.acos.highp_compute.scalar = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.acos.highp_compute.vec2 = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.acos.highp_compute.vec3 = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.acos.highp_compute.vec4 = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.atan2.lowp_compute.scalar = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.atan2.lowp_compute.vec2 = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.atan2.lowp_compute.vec3 = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.atan2.lowp_compute.vec4 = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.atan.lowp_compute.scalar = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.atan.lowp_compute.vec2 = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.atan.lowp_compute.vec3 = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.atan.lowp_compute.vec4 = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.atan.highp_compute.scalar = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.atan.highp_compute.vec2 = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.atan.highp_compute.vec3 = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.atan.highp_compute.vec4 = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.sinh.lowp_compute.scalar = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.sinh.lowp_compute.vec2 = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.sinh.lowp_compute.vec3 = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.sinh.lowp_compute.vec4 = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.sinh.mediump_compute.scalar = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.sinh.mediump_compute.vec2 = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.sinh.mediump_compute.vec3 = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.sinh.mediump_compute.vec4 = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.sinh.highp_compute.scalar = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.sinh.highp_compute.vec2 = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.sinh.highp_compute.vec3 = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.sinh.highp_compute.vec4 = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.cosh.lowp_compute.scalar = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.cosh.lowp_compute.vec2 = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.cosh.lowp_compute.vec3 = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.cosh.lowp_compute.vec4 = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.cosh.mediump_compute.scalar = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.cosh.mediump_compute.vec2 = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.cosh.mediump_compute.vec3 = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.cosh.mediump_compute.vec4 = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.cosh.highp_compute.scalar = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.cosh.highp_compute.vec2 = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.cosh.highp_compute.vec3 = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.cosh.highp_compute.vec4 = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.tanh.lowp_compute.scalar = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.tanh.lowp_compute.vec2 = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.tanh.lowp_compute.vec3 = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.tanh.lowp_compute.vec4 = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.tanh.mediump_compute.scalar = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.tanh.mediump_compute.vec2 = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.tanh.mediump_compute.vec3 = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.tanh.mediump_compute.vec4 = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.tanh.highp_compute.scalar = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.tanh.highp_compute.vec2 = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.tanh.highp_compute.vec3 = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.tanh.highp_compute.vec4 = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.asinh.lowp_compute.scalar = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.asinh.lowp_compute.vec2 = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.asinh.lowp_compute.vec3 = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.asinh.lowp_compute.vec4 = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.asinh.mediump_compute.scalar = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.asinh.mediump_compute.vec2 = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.asinh.mediump_compute.vec3 = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.asinh.mediump_compute.vec4 = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.asinh.highp_compute.scalar = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.asinh.highp_compute.vec2 = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.asinh.highp_compute.vec3 = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.asinh.highp_compute.vec4 = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.acosh.lowp_compute.scalar = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.acosh.lowp_compute.vec2 = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.acosh.lowp_compute.vec3 = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.acosh.lowp_compute.vec4 = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.acosh.mediump_compute.scalar = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.acosh.mediump_compute.vec2 = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.acosh.mediump_compute.vec3 = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.acosh.mediump_compute.vec4 = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.atanh.lowp_compute.scalar = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.atanh.lowp_compute.vec2 = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.atanh.lowp_compute.vec3 = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.atanh.lowp_compute.vec4 = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.atanh.mediump_compute.scalar = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.atanh.mediump_compute.vec2 = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.atanh.mediump_compute.vec3 = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.atanh.mediump_compute.vec4 = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.pow.lowp_compute.scalar = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.pow.lowp_compute.vec2 = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.pow.lowp_compute.vec3 = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.pow.lowp_compute.vec4 = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.pow.mediump_compute.scalar = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.pow.mediump_compute.vec2 = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.pow.mediump_compute.vec3 = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.pow.mediump_compute.vec4 = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.pow.highp_compute.scalar = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.pow.highp_compute.vec2 = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.pow.highp_compute.vec3 = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.pow.highp_compute.vec4 = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.exp.lowp_compute.scalar = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.exp.lowp_compute.vec2 = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.exp.lowp_compute.vec3 = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.exp.lowp_compute.vec4 = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.exp.mediump_compute.scalar = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.exp.mediump_compute.vec2 = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.exp.mediump_compute.vec3 = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.exp.mediump_compute.vec4 = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.exp.highp_compute.scalar = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.exp.highp_compute.vec2 = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.exp.highp_compute.vec3 = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.exp.highp_compute.vec4 = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.log.lowp_compute.scalar = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.log.lowp_compute.vec2 = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.log.lowp_compute.vec3 = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.log.lowp_compute.vec4 = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.log.mediump_compute.scalar = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.log.mediump_compute.vec2 = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.log.mediump_compute.vec3 = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.log.mediump_compute.vec4 = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.log.highp_compute.scalar = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.log.highp_compute.vec2 = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.log.highp_compute.vec3 = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.log.highp_compute.vec4 = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.exp2.lowp_compute.scalar = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.exp2.lowp_compute.vec2 = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.exp2.lowp_compute.vec3 = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.exp2.lowp_compute.vec4 = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.exp2.mediump_compute.scalar = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.exp2.mediump_compute.vec2 = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.exp2.mediump_compute.vec3 = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.exp2.mediump_compute.vec4 = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.exp2.highp_compute.scalar = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.exp2.highp_compute.vec2 = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.exp2.highp_compute.vec3 = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.exp2.highp_compute.vec4 = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.log2.lowp_compute.scalar = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.log2.lowp_compute.vec2 = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.log2.lowp_compute.vec3 = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.log2.lowp_compute.vec4 = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.log2.mediump_compute.scalar = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.log2.mediump_compute.vec2 = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.log2.mediump_compute.vec3 = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.log2.mediump_compute.vec4 = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.log2.highp_compute.scalar = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.log2.highp_compute.vec2 = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.log2.highp_compute.vec3 = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.log2.highp_compute.vec4 = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.sqrt.lowp_compute.scalar = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.sqrt.lowp_compute.vec2 = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.sqrt.lowp_compute.vec3 = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.sqrt.lowp_compute.vec4 = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.sqrt.mediump_compute.scalar = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.sqrt.mediump_compute.vec2 = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.sqrt.mediump_compute.vec3 = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.sqrt.mediump_compute.vec4 = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.sqrt.highp_compute.scalar = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.sqrt.highp_compute.vec2 = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.sqrt.highp_compute.vec3 = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.sqrt.highp_compute.vec4 = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.inversesqrt.lowp_compute.scalar = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.inversesqrt.lowp_compute.vec2 = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.inversesqrt.lowp_compute.vec3 = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.inversesqrt.lowp_compute.vec4 = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.inversesqrt.mediump_compute.scalar = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.inversesqrt.mediump_compute.vec2 = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.inversesqrt.mediump_compute.vec3 = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.inversesqrt.mediump_compute.vec4 = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.inversesqrt.highp_compute.scalar = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.inversesqrt.highp_compute.vec2 = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.inversesqrt.highp_compute.vec3 = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.inversesqrt.highp_compute.vec4 = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.abs.lowp_compute.scalar = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.abs.lowp_compute.vec2 = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.abs.lowp_compute.vec3 = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.abs.lowp_compute.vec4 = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.abs.mediump_compute.scalar = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.abs.mediump_compute.vec2 = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.abs.mediump_compute.vec3 = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.abs.mediump_compute.vec4 = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.abs.highp_compute.scalar = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.abs.highp_compute.vec2 = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.abs.highp_compute.vec3 = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.abs.highp_compute.vec4 = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.sign.lowp_compute.scalar = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.sign.lowp_compute.vec2 = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.sign.lowp_compute.vec3 = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.sign.lowp_compute.vec4 = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.sign.mediump_compute.scalar = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.sign.mediump_compute.vec2 = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.sign.mediump_compute.vec3 = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.sign.mediump_compute.vec4 = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.sign.highp_compute.scalar = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.sign.highp_compute.vec2 = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.sign.highp_compute.vec3 = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.sign.highp_compute.vec4 = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.floor.lowp_compute.scalar = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.floor.lowp_compute.vec2 = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.floor.lowp_compute.vec3 = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.floor.lowp_compute.vec4 = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.floor.mediump_compute.scalar = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.floor.mediump_compute.vec2 = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.floor.mediump_compute.vec3 = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.floor.mediump_compute.vec4 = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.floor.highp_compute.scalar = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.floor.highp_compute.vec2 = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.floor.highp_compute.vec3 = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.floor.highp_compute.vec4 = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.trunc.lowp_compute.scalar = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.trunc.lowp_compute.vec2 = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.trunc.lowp_compute.vec3 = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.trunc.lowp_compute.vec4 = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.trunc.mediump_compute.scalar = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.trunc.mediump_compute.vec2 = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.trunc.mediump_compute.vec3 = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.trunc.mediump_compute.vec4 = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.trunc.highp_compute.scalar = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.trunc.highp_compute.vec2 = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.trunc.highp_compute.vec3 = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.trunc.highp_compute.vec4 = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.round.lowp_compute.scalar = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.round.lowp_compute.vec2 = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.round.lowp_compute.vec3 = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.round.lowp_compute.vec4 = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.round.mediump_compute.scalar = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.round.mediump_compute.vec2 = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.round.mediump_compute.vec3 = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.round.mediump_compute.vec4 = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.round.highp_compute.scalar = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.round.highp_compute.vec2 = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.round.highp_compute.vec3 = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.round.highp_compute.vec4 = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.roundeven.lowp_compute.scalar = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.roundeven.lowp_compute.vec2 = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.roundeven.lowp_compute.vec3 = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.roundeven.lowp_compute.vec4 = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.roundeven.mediump_compute.scalar = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.roundeven.mediump_compute.vec2 = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.roundeven.mediump_compute.vec3 = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.roundeven.mediump_compute.vec4 = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.roundeven.highp_compute.scalar = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.roundeven.highp_compute.vec2 = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.roundeven.highp_compute.vec3 = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.roundeven.highp_compute.vec4 = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.ceil.lowp_compute.scalar = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.ceil.lowp_compute.vec2 = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.ceil.lowp_compute.vec3 = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.ceil.lowp_compute.vec4 = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.ceil.mediump_compute.scalar = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.ceil.mediump_compute.vec2 = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.ceil.mediump_compute.vec3 = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.ceil.mediump_compute.vec4 = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.ceil.highp_compute.scalar = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.ceil.highp_compute.vec2 = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.ceil.highp_compute.vec3 = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.ceil.highp_compute.vec4 = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.fract.lowp_compute.scalar = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.fract.lowp_compute.vec2 = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.fract.lowp_compute.vec3 = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.fract.lowp_compute.vec4 = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.fract.mediump_compute.scalar = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.fract.mediump_compute.vec2 = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.fract.mediump_compute.vec3 = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.fract.mediump_compute.vec4 = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.fract.highp_compute.scalar = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.fract.highp_compute.vec2 = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.fract.highp_compute.vec3 = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.fract.highp_compute.vec4 = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.mod.lowp_compute.scalar = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.mod.lowp_compute.vec2 = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.mod.lowp_compute.vec3 = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.mod.lowp_compute.vec4 = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.mod.mediump_compute.scalar = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.mod.mediump_compute.vec2 = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.mod.mediump_compute.vec3 = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.mod.mediump_compute.vec4 = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.modf.lowp_compute = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.modf.mediump_compute = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.modf.highp_compute = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.min.lowp_compute.scalar = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.min.lowp_compute.vec2 = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.min.lowp_compute.vec3 = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.min.lowp_compute.vec4 = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.min.mediump_compute.scalar = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.min.mediump_compute.vec2 = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.min.mediump_compute.vec3 = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.min.mediump_compute.vec4 = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.max.lowp_compute.scalar = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.max.lowp_compute.vec2 = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.max.lowp_compute.vec3 = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.max.lowp_compute.vec4 = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.max.mediump_compute.scalar = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.max.mediump_compute.vec2 = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.max.mediump_compute.vec3 = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.max.mediump_compute.vec4 = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.clamp.lowp_compute.scalar = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.clamp.lowp_compute.vec2 = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.clamp.lowp_compute.vec3 = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.clamp.lowp_compute.vec4 = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.clamp.mediump_compute.scalar = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.clamp.mediump_compute.vec2 = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.clamp.mediump_compute.vec3 = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.clamp.mediump_compute.vec4 = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.mix.lowp_compute.scalar = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.mix.lowp_compute.vec2 = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.mix.lowp_compute.vec3 = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.mix.lowp_compute.vec4 = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.mix.mediump_compute.scalar = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.mix.mediump_compute.vec2 = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.mix.mediump_compute.vec3 = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.mix.mediump_compute.vec4 = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.mix.highp_compute.scalar = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.mix.highp_compute.vec2 = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.mix.highp_compute.vec3 = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.mix.highp_compute.vec4 = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.step.lowp_compute.scalar = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.step.lowp_compute.vec2 = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.step.lowp_compute.vec3 = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.step.lowp_compute.vec4 = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.step.mediump_compute.scalar = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.step.mediump_compute.vec2 = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.step.mediump_compute.vec3 = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.step.mediump_compute.vec4 = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.step.highp_compute.scalar = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.step.highp_compute.vec2 = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.step.highp_compute.vec3 = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.step.highp_compute.vec4 = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.smoothstep.lowp_compute.scalar = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.smoothstep.lowp_compute.vec2 = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.smoothstep.lowp_compute.vec3 = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.smoothstep.lowp_compute.vec4 = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.length.lowp_compute.scalar = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.length.lowp_compute.vec2 = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.length.lowp_compute.vec3 = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.length.lowp_compute.vec4 = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.length.mediump_compute.scalar = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.length.mediump_compute.vec2 = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.length.mediump_compute.vec3 = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.length.mediump_compute.vec4 = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.length.highp_compute.scalar = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.length.highp_compute.vec2 = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.length.highp_compute.vec3 = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.length.highp_compute.vec4 = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.distance.lowp_compute.scalar = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.distance.lowp_compute.vec2 = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.distance.lowp_compute.vec3 = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.distance.lowp_compute.vec4 = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.distance.mediump_compute.scalar = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.distance.mediump_compute.vec2 = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.distance.mediump_compute.vec3 = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.distance.mediump_compute.vec4 = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.distance.highp_compute.scalar = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.distance.highp_compute.vec2 = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.distance.highp_compute.vec3 = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.distance.highp_compute.vec4 = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.dot.lowp_compute.scalar = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.dot.lowp_compute.vec2 = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.dot.lowp_compute.vec3 = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.dot.lowp_compute.vec4 = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.dot.mediump_compute.scalar = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.dot.mediump_compute.vec2 = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.dot.mediump_compute.vec3 = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.dot.mediump_compute.vec4 = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.dot.highp_compute.scalar = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.dot.highp_compute.vec2 = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.dot.highp_compute.vec3 = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.cross.lowp_compute = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.cross.mediump_compute = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.cross.highp_compute = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.normalize.lowp_compute.scalar = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.normalize.lowp_compute.vec2 = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.normalize.lowp_compute.vec3 = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.normalize.lowp_compute.vec4 = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.normalize.mediump_compute.scalar = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.normalize.mediump_compute.vec2 = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.normalize.mediump_compute.vec3 = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.normalize.mediump_compute.vec4 = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.normalize.highp_compute.scalar = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.normalize.highp_compute.vec2 = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.normalize.highp_compute.vec3 = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.normalize.highp_compute.vec4 = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.faceforward.lowp_compute.scalar = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.faceforward.lowp_compute.vec2 = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.faceforward.lowp_compute.vec3 = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.faceforward.lowp_compute.vec4 = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.faceforward.mediump_compute.scalar = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.faceforward.mediump_compute.vec2 = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.faceforward.mediump_compute.vec3 = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.faceforward.mediump_compute.vec4 = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.faceforward.highp_compute.scalar = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.faceforward.highp_compute.vec2 = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.faceforward.highp_compute.vec3 = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.faceforward.highp_compute.vec4 = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.reflect.lowp_compute.scalar = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.reflect.lowp_compute.vec2 = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.reflect.lowp_compute.vec3 = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.reflect.lowp_compute.vec4 = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.reflect.mediump_compute.vec2 = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.reflect.mediump_compute.vec3 = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.reflect.mediump_compute.vec4 = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.reflect.highp_compute.vec2 = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.reflect.highp_compute.vec3 = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.refract.lowp_compute.scalar = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.refract.lowp_compute.vec2 = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.refract.lowp_compute.vec3 = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.refract.lowp_compute.vec4 = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.refract.mediump_compute.scalar = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.refract.mediump_compute.vec2 = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.refract.mediump_compute.vec3 = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.refract.mediump_compute.vec4 = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.refract.highp_compute.scalar = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.refract.highp_compute.vec2 = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.refract.highp_compute.vec3 = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.refract.highp_compute.vec4 = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.matrixcompmult.lowp_compute.mat2 = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.matrixcompmult.lowp_compute.mat2x3 = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.matrixcompmult.lowp_compute.mat2x4 = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.matrixcompmult.lowp_compute.mat3x2 = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.matrixcompmult.lowp_compute.mat3 = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.matrixcompmult.lowp_compute.mat3x4 = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.matrixcompmult.lowp_compute.mat4x2 = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.matrixcompmult.lowp_compute.mat4x3 = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.matrixcompmult.lowp_compute.mat4 = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.matrixcompmult.mediump_compute.mat2 = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.matrixcompmult.mediump_compute.mat2x3 = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.matrixcompmult.mediump_compute.mat2x4 = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.matrixcompmult.mediump_compute.mat3x2 = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.matrixcompmult.mediump_compute.mat3 = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.matrixcompmult.mediump_compute.mat3x4 = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.matrixcompmult.mediump_compute.mat4x2 = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.matrixcompmult.mediump_compute.mat4x3 = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.matrixcompmult.mediump_compute.mat4 = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.matrixcompmult.highp_compute.mat2 = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.matrixcompmult.highp_compute.mat2x3 = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.matrixcompmult.highp_compute.mat2x4 = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.matrixcompmult.highp_compute.mat3x2 = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.matrixcompmult.highp_compute.mat3 = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.matrixcompmult.highp_compute.mat3x4 = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.matrixcompmult.highp_compute.mat4x2 = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.matrixcompmult.highp_compute.mat4x3 = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.matrixcompmult.highp_compute.mat4 = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.outerproduct.lowp_compute.mat2 = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.outerproduct.lowp_compute.mat2x3 = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.outerproduct.lowp_compute.mat2x4 = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.outerproduct.lowp_compute.mat3x2 = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.outerproduct.lowp_compute.mat3 = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.outerproduct.lowp_compute.mat3x4 = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.outerproduct.lowp_compute.mat4x2 = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.outerproduct.lowp_compute.mat4x3 = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.outerproduct.lowp_compute.mat4 = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.outerproduct.mediump_compute.mat2 = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.outerproduct.mediump_compute.mat2x3 = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.outerproduct.mediump_compute.mat2x4 = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.outerproduct.mediump_compute.mat3x2 = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.outerproduct.mediump_compute.mat3 = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.outerproduct.mediump_compute.mat3x4 = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.outerproduct.mediump_compute.mat4x2 = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.outerproduct.mediump_compute.mat4x3 = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.outerproduct.mediump_compute.mat4 = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.outerproduct.highp_compute.mat2 = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.outerproduct.highp_compute.mat2x3 = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.outerproduct.highp_compute.mat2x4 = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.outerproduct.highp_compute.mat3x2 = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.outerproduct.highp_compute.mat3 = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.outerproduct.highp_compute.mat3x4 = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.outerproduct.highp_compute.mat4x2 = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.outerproduct.highp_compute.mat4x3 = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.outerproduct.highp_compute.mat4 = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.transpose.lowp_compute.mat2 = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.transpose.lowp_compute.mat2x3 = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.transpose.lowp_compute.mat2x4 = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.transpose.lowp_compute.mat3x2 = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.transpose.lowp_compute.mat3 = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.transpose.lowp_compute.mat3x4 = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.transpose.lowp_compute.mat4x2 = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.transpose.lowp_compute.mat4x3 = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.transpose.lowp_compute.mat4 = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.transpose.mediump_compute.mat2 = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.transpose.mediump_compute.mat2x3 = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.transpose.mediump_compute.mat2x4 = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.transpose.mediump_compute.mat3x2 = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.transpose.mediump_compute.mat3 = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.transpose.mediump_compute.mat3x4 = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.transpose.mediump_compute.mat4x2 = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.transpose.mediump_compute.mat4x3 = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.transpose.mediump_compute.mat4 = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.transpose.highp_compute.mat2 = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.transpose.highp_compute.mat2x3 = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.transpose.highp_compute.mat2x4 = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.transpose.highp_compute.mat3x2 = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.transpose.highp_compute.mat3 = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.transpose.highp_compute.mat3x4 = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.transpose.highp_compute.mat4x2 = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.transpose.highp_compute.mat4x3 = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.transpose.highp_compute.mat4 = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.determinant.lowp_compute.mat2 = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.determinant.mediump_compute.mat2 = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.determinant.highp_compute.mat2 = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.inverse.lowp_compute.mat2 = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.inverse.mediump_compute.mat2 = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.frexp.* = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.ldexp.* = FAIL
 1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.opaque_type_indexing.* = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.functions.overloading.arrays_of_arrays_size_vertex = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.functions.overloading.arrays_of_arrays_size_fragment = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.arrays_of_arrays.constructor.* = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.arrays_of_arrays.return.* = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.arrays_of_arrays.parameter.* = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.arrays_of_arrays.implicit_size.* = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.arrays_of_arrays.assignment.* = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.arrays_of_arrays.length.* = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.arrays_of_arrays.array_access.* = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.arrays_of_arrays.single_statement_multiple_declarations.* = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.linkage.shader_storage_block.mismatch_number_of_declarations = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.linkage.shader_storage_block.mismatch_order = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.linkage.shader_storage_block.mismatch_type = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.linkage.shader_storage_block.mismatch_member_name = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.linkage.shader_storage_block.mismatch_member_unsized_sized_array = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.linkage.shader_storage_block.mismatch_member_array_size = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.linkage.shader_storage_block.mismatch_with_and_without_instance_name = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.linkage.shader_storage_block.mismatch_block_array_size = FAIL
 1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_constants.core.max_vertex_attribs = FAIL
 1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_constants.core.max_vertex_uniform_vectors = FAIL
 1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_constants.core.max_vertex_output_vectors = FAIL
 1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_constants.core.max_fragment_input_vectors = FAIL
 1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_constants.core.max_fragment_uniform_vectors = FAIL
 1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_constants.core.max_draw_buffers = FAIL
 1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_constants.core.max_vertex_texture_image_units = FAIL
 1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_constants.core.max_combined_texture_image_units = FAIL
@@ -1157,93 +1164,29 @@ 1442 OPENGL D3D11 : dEQP-GLES31.function
 1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_constants.core.max_atomic_counter_bindings = FAIL
 1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_constants.core.max_vertex_atomic_counter_buffers = FAIL
 1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_constants.core.max_fragment_atomic_counter_buffers = FAIL
 1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_constants.core.max_combined_atomic_counter_buffers = FAIL
 1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_constants.core.max_atomic_counter_buffer_size = FAIL
 1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_constants.core.max_compute_work_group_count = FAIL
 1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_constants.core.max_compute_work_group_size = FAIL
 1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.helper_invocation.* = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.compute.basic.empty = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.compute.basic.ubo_to_ssbo_single_invocation = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.compute.basic.ubo_to_ssbo_single_group = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.compute.basic.ubo_to_ssbo_multiple_invocations = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.compute.basic.ubo_to_ssbo_multiple_groups = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.compute.basic.copy_ssbo_single_invocation = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.compute.basic.copy_ssbo_multiple_invocations = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.compute.basic.copy_ssbo_multiple_groups = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.compute.basic.ssbo_rw_single_invocation = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.compute.basic.ssbo_rw_multiple_groups = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.compute.basic.ssbo_unsized_arr_single_invocation = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.compute.basic.ssbo_unsized_arr_multiple_groups = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.compute.basic.write_multiple_arr_single_invocation = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.compute.basic.write_multiple_arr_multiple_groups = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.compute.basic.write_multiple_unsized_arr_single_invocation = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.compute.basic.write_multiple_unsized_arr_multiple_groups = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.compute.basic.ssbo_local_barrier_single_invocation = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.compute.basic.ssbo_local_barrier_single_group = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.compute.basic.ssbo_local_barrier_multiple_groups = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.compute.basic.ssbo_cmd_barrier_single = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.compute.basic.ssbo_cmd_barrier_multiple = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.compute.basic.shared_var_single_invocation = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.compute.basic.shared_var_single_group = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.compute.basic.shared_var_multiple_invocations = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.compute.basic.shared_var_multiple_groups = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.compute.basic.shared_atomic_op_single_invocation = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.compute.basic.shared_atomic_op_single_group = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.compute.basic.shared_atomic_op_multiple_invocations = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.compute.basic.shared_atomic_op_multiple_groups = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.compute.basic.copy_image_to_ssbo_small = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.compute.basic.copy_image_to_ssbo_large = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.compute.basic.copy_ssbo_to_image_small = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.compute.basic.copy_ssbo_to_image_large = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.compute.basic.image_barrier_single = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.compute.basic.image_barrier_multiple = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.compute.basic.atomic_counter_single_invocation = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.compute.basic.atomic_counter_single_group = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.compute.basic.atomic_counter_multiple_invocations = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.compute.basic.atomic_counter_multiple_groups = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.compute.shared_var.* = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.compute.indirect_dispatch.* = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.ssbo.* = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.ubo.2_level_array.* = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.ubo.3_level_array.* = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.ubo.2_level_struct_array.* = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.ubo.random.basic_type_arrays.4 = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.ubo.random.basic_type_arrays.10 = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.ubo.random.all_per_block_buffers.1 = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.ubo.random.all_per_block_buffers.7 = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.ubo.random.all_per_block_buffers.10 = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.ubo.random.all_per_block_buffers.13 = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.ubo.random.all_per_block_buffers.18 = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.ubo.random.all_per_block_buffers.20 = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.ubo.random.all_per_block_buffers.29 = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.ubo.random.all_per_block_buffers.41 = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.ubo.random.all_shared_buffer.1 = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.ubo.random.all_shared_buffer.8 = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.ubo.random.all_shared_buffer.22 = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.ubo.random.all_shared_buffer.37 = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.ubo.random.all_shared_buffer.38 = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.image_load_store.* = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.atomic_counter.* = FAIL
 1442 OPENGL D3D11 : dEQP-GLES31.functional.stencil_texturing.format.depth32f_stencil8_2d = FAIL
 1442 OPENGL D3D11 : dEQP-GLES31.functional.stencil_texturing.format.depth32f_stencil8_2d_array = FAIL
 1442 OPENGL D3D11 : dEQP-GLES31.functional.stencil_texturing.format.depth32f_stencil8_cube = FAIL
 1442 OPENGL D3D11 : dEQP-GLES31.functional.stencil_texturing.format.depth24_stencil8_2d = FAIL
 1442 OPENGL D3D11 : dEQP-GLES31.functional.stencil_texturing.format.depth24_stencil8_2d_array = FAIL
 1442 OPENGL D3D11 : dEQP-GLES31.functional.stencil_texturing.format.depth24_stencil8_cube = FAIL
 1442 OPENGL D3D11 : dEQP-GLES31.functional.stencil_texturing.render.depth32f_stencil8_clear = FAIL
 1442 OPENGL D3D11 : dEQP-GLES31.functional.stencil_texturing.render.depth32f_stencil8_draw = FAIL
 1442 OPENGL D3D11 : dEQP-GLES31.functional.stencil_texturing.render.depth24_stencil8_clear = FAIL
 1442 OPENGL D3D11 : dEQP-GLES31.functional.stencil_texturing.render.depth24_stencil8_draw = FAIL
 1442 OPENGL D3D11 : dEQP-GLES31.functional.stencil_texturing.misc.compare_mode_effect = FAIL
 1442 OPENGL D3D11 : dEQP-GLES31.functional.stencil_texturing.misc.base_level = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.state_query.integer.dispatch_indirect_buffer_binding_* = FAIL
 1442 OPENGL D3D11 : dEQP-GLES31.functional.state_query.integer.program_pipeline_binding_* = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.state_query.indexed.image_binding* = FAIL
 1442 OPENGL D3D11 : dEQP-GLES31.functional.state_query.texture.texture_2d.depth_stencil_mode_* = FAIL
 1442 OPENGL D3D11 : dEQP-GLES31.functional.state_query.texture.texture_cube_map.depth_stencil_mode_* = FAIL
 1442 OPENGL D3D11 : dEQP-GLES31.functional.state_query.texture.texture_2d_array.depth_stencil_mode_* = FAIL
 1442 OPENGL D3D11 : dEQP-GLES31.functional.state_query.texture.texture_3d.depth_stencil_mode_* = FAIL
 1442 OPENGL D3D11 : dEQP-GLES31.functional.state_query.texture.texture_2d_multisample.* = FAIL
 1442 OPENGL D3D11 : dEQP-GLES31.functional.state_query.internal_format.renderbuffer.rgb10_a2ui_samples = FAIL
 1442 OPENGL D3D11 : dEQP-GLES31.functional.state_query.internal_format.renderbuffer.r8i_samples = FAIL
 1442 OPENGL D3D11 : dEQP-GLES31.functional.state_query.internal_format.renderbuffer.r8ui_samples = FAIL
@@ -1258,48 +1201,35 @@ 1442 OPENGL D3D11 : dEQP-GLES31.function
 1442 OPENGL D3D11 : dEQP-GLES31.functional.state_query.internal_format.renderbuffer.rg32i_samples = FAIL
 1442 OPENGL D3D11 : dEQP-GLES31.functional.state_query.internal_format.renderbuffer.rg32ui_samples = FAIL
 1442 OPENGL D3D11 : dEQP-GLES31.functional.state_query.internal_format.renderbuffer.rgba8i_samples = FAIL
 1442 OPENGL D3D11 : dEQP-GLES31.functional.state_query.internal_format.renderbuffer.rgba8ui_samples = FAIL
 1442 OPENGL D3D11 : dEQP-GLES31.functional.state_query.internal_format.renderbuffer.rgba16i_samples = FAIL
 1442 OPENGL D3D11 : dEQP-GLES31.functional.state_query.internal_format.renderbuffer.rgba16ui_samples = FAIL
 1442 OPENGL D3D11 : dEQP-GLES31.functional.state_query.internal_format.renderbuffer.rgba32i_samples = FAIL
 1442 OPENGL D3D11 : dEQP-GLES31.functional.state_query.internal_format.renderbuffer.rgba32ui_samples = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.state_query.internal_format.texture_2d_multisample.* = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.state_query.internal_format.partial_query.num_sample_counts = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.state_query.internal_format.partial_query.samples = FAIL
 1442 OPENGL D3D11 : dEQP-GLES31.functional.state_query.program.program_separable_get_programiv = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.state_query.program.compute_work_group_size_get_programiv = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.state_query.program.active_atomic_counter_buffers_get_programiv = FAIL
 1442 OPENGL D3D11 : dEQP-GLES31.functional.state_query.program_pipeline.* = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.synchronization.* = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.geometry_shading.query.geometry_linked_vertices_out = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.geometry_shading.query.geometry_linked_input_type = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.geometry_shading.query.geometry_linked_output_type = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.geometry_shading.query.geometry_shader_invocations = FAIL
+1442 OPENGL D3D11 : dEQP-GLES31.functional.synchronization.inter_call.without_memory_barrier.atomic_counter_dispatch_100_calls_1k_invocations = FAIL
 1442 OPENGL D3D11 : dEQP-GLES31.functional.separate_shader.* = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.uniform_location.nested_array.* = FAIL
 1442 OPENGL D3D11 : dEQP-GLES31.functional.debug.error_filters.case_11 = FAIL
 1442 OPENGL D3D11 : dEQP-GLES31.functional.debug.error_groups.case_11 = FAIL
 1442 OPENGL D3D11 : dEQP-GLES31.functional.debug.negative_coverage.callbacks.buffer.bind_buffer_range = FAIL
 1442 OPENGL D3D11 : dEQP-GLES31.functional.debug.negative_coverage.callbacks.shader.compile_compute_shader = SKIP
 1442 OPENGL D3D11 : dEQP-GLES31.functional.debug.negative_coverage.callbacks.shader_directive.primitive_bounding_box = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.debug.negative_coverage.callbacks.shader_directive.geometry_shader = FAIL
 1442 OPENGL D3D11 : dEQP-GLES31.functional.debug.negative_coverage.callbacks.shader_directive.tessellation_shader = FAIL
 1442 OPENGL D3D11 : dEQP-GLES31.functional.debug.negative_coverage.log.buffer.bind_buffer_range = FAIL
 1442 OPENGL D3D11 : dEQP-GLES31.functional.debug.negative_coverage.log.shader.compile_compute_shader = SKIP
 1442 OPENGL D3D11 : dEQP-GLES31.functional.debug.negative_coverage.log.shader_directive.primitive_bounding_box = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.debug.negative_coverage.log.shader_directive.geometry_shader = FAIL
 1442 OPENGL D3D11 : dEQP-GLES31.functional.debug.negative_coverage.log.shader_directive.tessellation_shader = FAIL
 1442 OPENGL D3D11 : dEQP-GLES31.functional.debug.negative_coverage.get_error.buffer.bind_buffer_range = FAIL
 1442 OPENGL D3D11 : dEQP-GLES31.functional.debug.negative_coverage.get_error.buffer.read_pixels_format_mismatch = FAIL
 1442 OPENGL D3D11 : dEQP-GLES31.functional.debug.negative_coverage.get_error.buffer.framebuffer_texture2d = FAIL
 1442 OPENGL D3D11 : dEQP-GLES31.functional.debug.negative_coverage.get_error.buffer.blit_framebuffer = FAIL
 1442 OPENGL D3D11 : dEQP-GLES31.functional.debug.negative_coverage.get_error.buffer.invalidate_sub_framebuffer = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.debug.negative_coverage.get_error.buffer.renderbuffer_storage_multisample = FAIL
 1442 OPENGL D3D11 : dEQP-GLES31.functional.debug.negative_coverage.get_error.texture.copyteximage2d_invalid_format = FAIL
 1442 OPENGL D3D11 : dEQP-GLES31.functional.debug.negative_coverage.get_error.texture.copyteximage2d_inequal_width_height_cube = FAIL
 1442 OPENGL D3D11 : dEQP-GLES31.functional.debug.negative_coverage.get_error.texture.copyteximage2d_max_width_height = FAIL
 1442 OPENGL D3D11 : dEQP-GLES31.functional.debug.negative_coverage.get_error.texture.copytexsubimage2d_invalid_offset = FAIL
 1442 OPENGL D3D11 : dEQP-GLES31.functional.debug.negative_coverage.get_error.texture.copytexsubimage2d_texture_internalformat = FAIL
 1442 OPENGL D3D11 : dEQP-GLES31.functional.debug.negative_coverage.get_error.texture.texparameteri = FAIL
 1442 OPENGL D3D11 : dEQP-GLES31.functional.debug.negative_coverage.get_error.texture.texparameterf = FAIL
 1442 OPENGL D3D11 : dEQP-GLES31.functional.debug.negative_coverage.get_error.texture.texparameteriv = FAIL
@@ -1310,16 +1240,443 @@ 1442 OPENGL D3D11 : dEQP-GLES31.function
 1442 OPENGL D3D11 : dEQP-GLES31.functional.debug.negative_coverage.get_error.texture.texsubimage3d_neg_offset = FAIL
 1442 OPENGL D3D11 : dEQP-GLES31.functional.debug.negative_coverage.get_error.texture.copytexsubimage3d_invalid_offset = FAIL
 1442 OPENGL D3D11 : dEQP-GLES31.functional.debug.negative_coverage.get_error.texture.compressedtexsubimage3d = FAIL
 1442 OPENGL D3D11 : dEQP-GLES31.functional.debug.negative_coverage.get_error.texture.compressedtexsubimage3d_invalid_buffer_target = FAIL
 1442 OPENGL D3D11 : dEQP-GLES31.functional.debug.negative_coverage.get_error.shader.compile_compute_shader = SKIP
 1442 OPENGL D3D11 : dEQP-GLES31.functional.debug.negative_coverage.get_error.vertex_array.draw_range_elements = FAIL
 1442 OPENGL D3D11 : dEQP-GLES31.functional.debug.negative_coverage.get_error.vertex_array.draw_range_elements_incomplete_primitive = FAIL
 1442 OPENGL D3D11 : dEQP-GLES31.functional.debug.negative_coverage.get_error.shader_directive.primitive_bounding_box = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.debug.negative_coverage.get_error.shader_directive.geometry_shader = FAIL
 1442 OPENGL D3D11 : dEQP-GLES31.functional.debug.negative_coverage.get_error.shader_directive.tessellation_shader = FAIL
 1442 OPENGL D3D11 : dEQP-GLES31.functional.debug.object_labels.program_pipeline = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.program_interface_query.* = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.layout_binding.ubo.* = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.layout_binding.ssbo.* = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.layout_binding.image.image2d.* = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.layout_binding.image.image3d.* = FAIL
+
+1941 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.abs.float_lowp_geometry = FAIL
+1941 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.abs.float_mediump_geometry = FAIL
+1941 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.abs.float_highp_geometry = FAIL
+1941 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.abs.vec2_lowp_geometry = FAIL
+1941 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.abs.vec2_mediump_geometry = FAIL
+1941 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.abs.vec2_highp_geometry = FAIL
+1941 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.abs.vec3_lowp_geometry = FAIL
+1941 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.abs.vec3_mediump_geometry = FAIL
+1941 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.abs.vec3_highp_geometry = FAIL
+1941 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.abs.vec4_lowp_geometry = FAIL
+1941 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.abs.vec4_mediump_geometry = FAIL
+1941 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.abs.vec4_highp_geometry = FAIL
+1941 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.abs.int_lowp_geometry = FAIL
+1941 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.abs.int_mediump_geometry = FAIL
+1941 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.abs.int_highp_geometry = FAIL
+1941 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.abs.ivec2_lowp_geometry = FAIL
+1941 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.abs.ivec2_mediump_geometry = FAIL
+1941 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.abs.ivec2_highp_geometry = FAIL
+1941 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.abs.ivec3_lowp_geometry = FAIL
+1941 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.abs.ivec3_mediump_geometry = FAIL
+1941 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.abs.ivec3_highp_geometry = FAIL
+1941 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.abs.ivec4_lowp_geometry = FAIL
+1941 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.abs.ivec4_mediump_geometry = FAIL
+1941 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.abs.ivec4_highp_geometry = FAIL
+1941 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.sign.float_lowp_geometry = FAIL
+1941 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.sign.float_mediump_geometry = FAIL
+1941 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.sign.float_highp_geometry = FAIL
+1941 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.sign.vec2_lowp_geometry = FAIL
+1941 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.sign.vec2_mediump_geometry = FAIL
+1941 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.sign.vec2_highp_geometry = FAIL
+1941 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.sign.vec3_lowp_geometry = FAIL
+1941 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.sign.vec3_mediump_geometry = FAIL
+1941 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.sign.vec3_highp_geometry = FAIL
+1941 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.sign.vec4_lowp_geometry = FAIL
+1941 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.sign.vec4_mediump_geometry = FAIL
+1941 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.sign.vec4_highp_geometry = FAIL
+1941 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.sign.int_lowp_geometry = FAIL
+1941 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.sign.int_mediump_geometry = FAIL
+1941 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.sign.int_highp_geometry = FAIL
+1941 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.sign.ivec2_lowp_geometry = FAIL
+1941 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.sign.ivec2_mediump_geometry = FAIL
+1941 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.sign.ivec2_highp_geometry = FAIL
+1941 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.sign.ivec3_lowp_geometry = FAIL
+1941 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.sign.ivec3_mediump_geometry = FAIL
+1941 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.sign.ivec3_highp_geometry = FAIL
+1941 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.sign.ivec4_lowp_geometry = FAIL
+1941 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.sign.ivec4_mediump_geometry = FAIL
+1941 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.sign.ivec4_highp_geometry = FAIL
+1941 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.floor.float_lowp_geometry = FAIL
+1941 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.floor.float_mediump_geometry = FAIL
+1941 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.floor.float_highp_geometry = FAIL
+1941 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.floor.vec2_lowp_geometry = FAIL
+1941 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.floor.vec2_mediump_geometry = FAIL
+1941 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.floor.vec2_highp_geometry = FAIL
+1941 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.floor.vec3_lowp_geometry = FAIL
+1941 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.floor.vec3_mediump_geometry = FAIL
+1941 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.floor.vec3_highp_geometry = FAIL
+1941 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.floor.vec4_lowp_geometry = FAIL
+1941 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.floor.vec4_mediump_geometry = FAIL
+1941 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.floor.vec4_highp_geometry = FAIL
+1941 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.trunc.float_lowp_geometry = FAIL
+1941 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.trunc.float_mediump_geometry = FAIL
+1941 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.trunc.float_highp_geometry = FAIL
+1941 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.trunc.vec2_lowp_geometry = FAIL
+1941 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.trunc.vec2_mediump_geometry = FAIL
+1941 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.trunc.vec2_highp_geometry = FAIL
+1941 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.trunc.vec3_lowp_geometry = FAIL
+1941 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.trunc.vec3_mediump_geometry = FAIL
+1941 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.trunc.vec3_highp_geometry = FAIL
+1941 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.trunc.vec4_lowp_geometry = FAIL
+1941 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.trunc.vec4_mediump_geometry = FAIL
+1941 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.trunc.vec4_highp_geometry = FAIL
+1941 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.round.float_lowp_geometry = FAIL
+1941 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.round.float_mediump_geometry = FAIL
+1941 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.round.float_highp_geometry = FAIL
+1941 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.round.vec2_lowp_geometry = FAIL
+1941 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.round.vec2_mediump_geometry = FAIL
+1941 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.round.vec2_highp_geometry = FAIL
+1941 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.round.vec3_lowp_geometry = FAIL
+1941 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.round.vec3_mediump_geometry = FAIL
+1941 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.round.vec3_highp_geometry = FAIL
+1941 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.round.vec4_lowp_geometry = FAIL
+1941 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.round.vec4_mediump_geometry = FAIL
+1941 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.round.vec4_highp_geometry = FAIL
+1941 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.roundeven.float_lowp_geometry = FAIL
+1941 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.roundeven.float_mediump_geometry = FAIL
+1941 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.roundeven.float_highp_geometry = FAIL
+1941 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.roundeven.vec2_lowp_geometry = FAIL
+1941 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.roundeven.vec2_mediump_geometry = FAIL
+1941 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.roundeven.vec2_highp_geometry = FAIL
+1941 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.roundeven.vec3_lowp_geometry = FAIL
+1941 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.roundeven.vec3_mediump_geometry = FAIL
+1941 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.roundeven.vec3_highp_geometry = FAIL
+1941 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.roundeven.vec4_lowp_geometry = FAIL
+1941 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.roundeven.vec4_mediump_geometry = FAIL
+1941 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.roundeven.vec4_highp_geometry = FAIL
+1941 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.ceil.float_lowp_geometry = FAIL
+1941 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.ceil.float_mediump_geometry = FAIL
+1941 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.ceil.float_highp_geometry = FAIL
+1941 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.ceil.vec2_lowp_geometry = FAIL
+1941 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.ceil.vec2_mediump_geometry = FAIL
+1941 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.ceil.vec2_highp_geometry = FAIL
+1941 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.ceil.vec3_lowp_geometry = FAIL
+1941 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.ceil.vec3_mediump_geometry = FAIL
+1941 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.ceil.vec3_highp_geometry = FAIL
+1941 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.ceil.vec4_lowp_geometry = FAIL
+1941 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.ceil.vec4_mediump_geometry = FAIL
+1941 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.ceil.vec4_highp_geometry = FAIL
+1941 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.fract.float_lowp_geometry = FAIL
+1941 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.fract.float_mediump_geometry = FAIL
+1941 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.fract.float_highp_geometry = FAIL
+1941 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.fract.vec2_lowp_geometry = FAIL
+1941 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.fract.vec2_mediump_geometry = FAIL
+1941 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.fract.vec2_highp_geometry = FAIL
+1941 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.fract.vec3_lowp_geometry = FAIL
+1941 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.fract.vec3_mediump_geometry = FAIL
+1941 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.fract.vec3_highp_geometry = FAIL
+1941 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.fract.vec4_lowp_geometry = FAIL
+1941 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.fract.vec4_mediump_geometry = FAIL
+1941 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.fract.vec4_highp_geometry = FAIL
+1941 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.modf.float_lowp_geometry = FAIL
+1941 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.modf.float_mediump_geometry = FAIL
+1941 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.modf.float_highp_geometry = FAIL
+1941 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.modf.vec2_lowp_geometry = FAIL
+1941 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.modf.vec2_mediump_geometry = FAIL
+1941 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.modf.vec2_highp_geometry = FAIL
+1941 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.modf.vec3_lowp_geometry = FAIL
+1941 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.modf.vec3_mediump_geometry = FAIL
+1941 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.modf.vec3_highp_geometry = FAIL
+1941 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.modf.vec4_lowp_geometry = FAIL
+1941 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.modf.vec4_mediump_geometry = FAIL
+1941 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.modf.vec4_highp_geometry = FAIL
+1941 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.isnan.float_lowp_geometry = FAIL
+1941 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.isnan.float_mediump_geometry = FAIL
+1941 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.isnan.float_highp_geometry = FAIL
+1941 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.isnan.vec2_lowp_geometry = FAIL
+1941 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.isnan.vec2_mediump_geometry = FAIL
+1941 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.isnan.vec2_highp_geometry = FAIL
+1941 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.isnan.vec3_lowp_geometry = FAIL
+1941 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.isnan.vec3_mediump_geometry = FAIL
+1941 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.isnan.vec3_highp_geometry = FAIL
+1941 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.isnan.vec4_lowp_geometry = FAIL
+1941 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.isnan.vec4_mediump_geometry = FAIL
+1941 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.isnan.vec4_highp_geometry = FAIL
+1941 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.isinf.float_lowp_geometry = FAIL
+1941 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.isinf.float_mediump_geometry = FAIL
+1941 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.isinf.float_highp_geometry = FAIL
+1941 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.isinf.vec2_lowp_geometry = FAIL
+1941 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.isinf.vec2_mediump_geometry = FAIL
+1941 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.isinf.vec2_highp_geometry = FAIL
+1941 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.isinf.vec3_lowp_geometry = FAIL
+1941 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.isinf.vec3_mediump_geometry = FAIL
+1941 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.isinf.vec3_highp_geometry = FAIL
+1941 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.isinf.vec4_lowp_geometry = FAIL
+1941 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.isinf.vec4_mediump_geometry = FAIL
+1941 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.isinf.vec4_highp_geometry = FAIL
+1941 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.floatbitstoint.float_lowp_geometry = FAIL
+1941 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.floatbitstoint.float_mediump_geometry = FAIL
+1941 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.floatbitstoint.float_highp_geometry = FAIL
+1941 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.floatbitstoint.vec2_lowp_geometry = FAIL
+1941 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.floatbitstoint.vec2_mediump_geometry = FAIL
+1941 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.floatbitstoint.vec2_highp_geometry = FAIL
+1941 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.floatbitstoint.vec3_lowp_geometry = FAIL
+1941 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.floatbitstoint.vec3_mediump_geometry = FAIL
+1941 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.floatbitstoint.vec3_highp_geometry = FAIL
+1941 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.floatbitstoint.vec4_lowp_geometry = FAIL
+1941 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.floatbitstoint.vec4_mediump_geometry = FAIL
+1941 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.floatbitstoint.vec4_highp_geometry = FAIL
+1941 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.floatbitstouint.float_lowp_geometry = FAIL
+1941 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.floatbitstouint.float_mediump_geometry = FAIL
+1941 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.floatbitstouint.float_highp_geometry = FAIL
+1941 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.floatbitstouint.vec2_lowp_geometry = FAIL
+1941 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.floatbitstouint.vec2_mediump_geometry = FAIL
+1941 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.floatbitstouint.vec2_highp_geometry = FAIL
+1941 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.floatbitstouint.vec3_lowp_geometry = FAIL
+1941 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.floatbitstouint.vec3_mediump_geometry = FAIL
+1941 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.floatbitstouint.vec3_highp_geometry = FAIL
+1941 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.floatbitstouint.vec4_lowp_geometry = FAIL
+1941 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.floatbitstouint.vec4_mediump_geometry = FAIL
+1941 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.floatbitstouint.vec4_highp_geometry = FAIL
+1941 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.frexp.float_lowp_geometry = FAIL
+1941 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.frexp.float_mediump_geometry = FAIL
+1941 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.frexp.float_highp_geometry = FAIL
+1941 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.frexp.vec2_lowp_geometry = FAIL
+1941 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.frexp.vec2_mediump_geometry = FAIL
+1941 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.frexp.vec2_highp_geometry = FAIL
+1941 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.frexp.vec3_lowp_geometry = FAIL
+1941 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.frexp.vec3_mediump_geometry = FAIL
+1941 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.frexp.vec3_highp_geometry = FAIL
+1941 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.frexp.vec4_lowp_geometry = FAIL
+1941 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.frexp.vec4_mediump_geometry = FAIL
+1941 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.frexp.vec4_highp_geometry = FAIL
+1941 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.ldexp.float_lowp_geometry = FAIL
+1941 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.ldexp.float_mediump_geometry = FAIL
+1941 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.ldexp.float_highp_geometry = FAIL
+1941 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.ldexp.vec2_lowp_geometry = FAIL
+1941 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.ldexp.vec2_mediump_geometry = FAIL
+1941 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.ldexp.vec2_highp_geometry = FAIL
+1941 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.ldexp.vec3_lowp_geometry = FAIL
+1941 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.ldexp.vec3_mediump_geometry = FAIL
+1941 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.ldexp.vec3_highp_geometry = FAIL
+1941 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.ldexp.vec4_lowp_geometry = FAIL
+1941 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.ldexp.vec4_mediump_geometry = FAIL
+1941 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.ldexp.vec4_highp_geometry = FAIL
+1941 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.fma.float_lowp_geometry = FAIL
+1941 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.fma.float_mediump_geometry = FAIL
+1941 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.fma.float_highp_geometry = FAIL
+1941 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.fma.vec2_lowp_geometry = FAIL
+1941 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.fma.vec2_mediump_geometry = FAIL
+1941 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.fma.vec2_highp_geometry = FAIL
+1941 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.fma.vec3_lowp_geometry = FAIL
+1941 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.fma.vec3_mediump_geometry = FAIL
+1941 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.fma.vec3_highp_geometry = FAIL
+1941 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.fma.vec4_lowp_geometry = FAIL
+1941 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.fma.vec4_mediump_geometry = FAIL
+1941 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.fma.vec4_highp_geometry = FAIL
+1941 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.intbitstofloat.int_highp_geometry = FAIL
+1941 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.intbitstofloat.ivec2_highp_geometry = FAIL
+1941 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.intbitstofloat.ivec3_highp_geometry = FAIL
+1941 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.uintbitstofloat.uint_highp_geometry = FAIL
+1941 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.uintbitstofloat.uvec2_highp_geometry = FAIL
+1941 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.uintbitstofloat.uvec3_highp_geometry = FAIL
+1941 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.pack_unpack.packsnorm4x8_lowp_geometry = FAIL
+1941 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.pack_unpack.packsnorm4x8_mediump_geometry = FAIL
+1941 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.pack_unpack.packsnorm4x8_highp_geometry = FAIL
+1941 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.pack_unpack.unpacksnorm4x8_geometry = FAIL
+1941 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.pack_unpack.packunorm4x8_lowp_geometry = FAIL
+1941 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.pack_unpack.packunorm4x8_mediump_geometry = FAIL
+1941 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.pack_unpack.packunorm4x8_highp_geometry = FAIL
+1941 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.pack_unpack.unpackunorm4x8_geometry = FAIL
+1941 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.pack_unpack.packsnorm2x16_lowp_geometry = FAIL
+1941 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.pack_unpack.packsnorm2x16_mediump_geometry = FAIL
+1941 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.pack_unpack.packsnorm2x16_highp_geometry = FAIL
+1941 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.pack_unpack.unpacksnorm2x16_geometry = FAIL
+1941 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.pack_unpack.packunorm2x16_lowp_geometry = FAIL
+1941 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.pack_unpack.packunorm2x16_mediump_geometry = FAIL
+1941 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.pack_unpack.packunorm2x16_highp_geometry = FAIL
+1941 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.pack_unpack.unpackunorm2x16_geometry = FAIL
+1941 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.pack_unpack.packhalf2x16_geometry = FAIL
+1941 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.pack_unpack.unpackhalf2x16_geometry = FAIL
+1941 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.integer.uaddcarry.uint_lowp_geometry = FAIL
+1941 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.integer.uaddcarry.uint_mediump_geometry = FAIL
+1941 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.integer.uaddcarry.uint_highp_geometry = FAIL
+1941 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.integer.uaddcarry.uvec2_lowp_geometry = FAIL
+1941 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.integer.uaddcarry.uvec2_mediump_geometry = FAIL
+1941 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.integer.uaddcarry.uvec2_highp_geometry = FAIL
+1941 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.integer.uaddcarry.uvec3_lowp_geometry = FAIL
+1941 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.integer.uaddcarry.uvec3_mediump_geometry = FAIL
+1941 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.integer.uaddcarry.uvec3_highp_geometry = FAIL
+1941 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.integer.uaddcarry.uvec4_lowp_geometry = FAIL
+1941 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.integer.uaddcarry.uvec4_mediump_geometry = FAIL
+1941 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.integer.uaddcarry.uvec4_highp_geometry = FAIL
+1941 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.integer.usubborrow.uint_lowp_geometry = FAIL
+1941 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.integer.usubborrow.uint_mediump_geometry = FAIL
+1941 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.integer.usubborrow.uint_highp_geometry = FAIL
+1941 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.integer.usubborrow.uvec2_lowp_geometry = FAIL
+1941 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.integer.usubborrow.uvec2_mediump_geometry = FAIL
+1941 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.integer.usubborrow.uvec2_highp_geometry = FAIL
+1941 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.integer.usubborrow.uvec3_lowp_geometry = FAIL
+1941 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.integer.usubborrow.uvec3_mediump_geometry = FAIL
+1941 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.integer.usubborrow.uvec3_highp_geometry = FAIL
+1941 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.integer.usubborrow.uvec4_lowp_geometry = FAIL
+1941 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.integer.usubborrow.uvec4_mediump_geometry = FAIL
+1941 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.integer.usubborrow.uvec4_highp_geometry = FAIL
+1941 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.integer.umulextended.uint_highp_geometry = FAIL
+1941 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.integer.umulextended.uvec2_highp_geometry = FAIL
+1941 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.integer.umulextended.uvec3_highp_geometry = FAIL
+1941 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.integer.umulextended.uvec4_highp_geometry = FAIL
+1941 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.integer.imulextended.int_highp_geometry = FAIL
+1941 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.integer.imulextended.ivec2_highp_geometry = FAIL
+1941 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.integer.imulextended.ivec3_highp_geometry = FAIL
+1941 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.integer.imulextended.ivec4_highp_geometry = FAIL
+1941 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.integer.bitfieldextract.int_lowp_geometry = FAIL
+1941 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.integer.bitfieldextract.int_mediump_geometry = FAIL
+1941 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.integer.bitfieldextract.int_highp_geometry = FAIL
+1941 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.integer.bitfieldextract.ivec2_lowp_geometry = FAIL
+1941 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.integer.bitfieldextract.ivec2_mediump_geometry = FAIL
+1941 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.integer.bitfieldextract.ivec2_highp_geometry = FAIL
+1941 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.integer.bitfieldextract.ivec3_lowp_geometry = FAIL
+1941 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.integer.bitfieldextract.ivec3_mediump_geometry = FAIL
+1941 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.integer.bitfieldextract.ivec3_highp_geometry = FAIL
+1941 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.integer.bitfieldextract.ivec4_lowp_geometry = FAIL
+1941 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.integer.bitfieldextract.ivec4_mediump_geometry = FAIL
+1941 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.integer.bitfieldextract.ivec4_highp_geometry = FAIL
+1941 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.integer.bitfieldextract.uint_lowp_geometry = FAIL
+1941 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.integer.bitfieldextract.uint_mediump_geometry = FAIL
+1941 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.integer.bitfieldextract.uint_highp_geometry = FAIL
+1941 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.integer.bitfieldextract.uvec2_lowp_geometry = FAIL
+1941 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.integer.bitfieldextract.uvec2_mediump_geometry = FAIL
+1941 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.integer.bitfieldextract.uvec2_highp_geometry = FAIL
+1941 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.integer.bitfieldextract.uvec3_lowp_geometry = FAIL
+1941 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.integer.bitfieldextract.uvec3_mediump_geometry = FAIL
+1941 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.integer.bitfieldextract.uvec3_highp_geometry = FAIL
+1941 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.integer.bitfieldextract.uvec4_lowp_geometry = FAIL
+1941 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.integer.bitfieldextract.uvec4_mediump_geometry = FAIL
+1941 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.integer.bitfieldextract.uvec4_highp_geometry = FAIL
+1941 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.integer.bitfieldinsert.int_lowp_geometry = FAIL
+1941 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.integer.bitfieldinsert.int_mediump_geometry = FAIL
+1941 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.integer.bitfieldinsert.int_highp_geometry = FAIL
+1941 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.integer.bitfieldinsert.ivec2_lowp_geometry = FAIL
+1941 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.integer.bitfieldinsert.ivec2_mediump_geometry = FAIL
+1941 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.integer.bitfieldinsert.ivec2_highp_geometry = FAIL
+1941 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.integer.bitfieldinsert.ivec3_lowp_geometry = FAIL
+1941 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.integer.bitfieldinsert.ivec3_mediump_geometry = FAIL
+1941 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.integer.bitfieldinsert.ivec3_highp_geometry = FAIL
+1941 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.integer.bitfieldinsert.ivec4_lowp_geometry = FAIL
+1941 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.integer.bitfieldinsert.ivec4_mediump_geometry = FAIL
+1941 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.integer.bitfieldinsert.ivec4_highp_geometry = FAIL
+1941 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.integer.bitfieldinsert.uint_lowp_geometry = FAIL
+1941 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.integer.bitfieldinsert.uint_mediump_geometry = FAIL
+1941 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.integer.bitfieldinsert.uint_highp_geometry = FAIL
+1941 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.integer.bitfieldinsert.uvec2_lowp_geometry = FAIL
+1941 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.integer.bitfieldinsert.uvec2_mediump_geometry = FAIL
+1941 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.integer.bitfieldinsert.uvec2_highp_geometry = FAIL
+1941 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.integer.bitfieldinsert.uvec3_lowp_geometry = FAIL
+1941 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.integer.bitfieldinsert.uvec3_mediump_geometry = FAIL
+1941 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.integer.bitfieldinsert.uvec3_highp_geometry = FAIL
+1941 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.integer.bitfieldinsert.uvec4_lowp_geometry = FAIL
+1941 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.integer.bitfieldinsert.uvec4_mediump_geometry = FAIL
+1941 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.integer.bitfieldinsert.uvec4_highp_geometry = FAIL
+1941 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.integer.bitfieldreverse.int_lowp_geometry = FAIL
+1941 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.integer.bitfieldreverse.int_mediump_geometry = FAIL
+1941 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.integer.bitfieldreverse.int_highp_geometry = FAIL
+1941 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.integer.bitfieldreverse.ivec2_lowp_geometry = FAIL
+1941 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.integer.bitfieldreverse.ivec2_mediump_geometry = FAIL
+1941 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.integer.bitfieldreverse.ivec2_highp_geometry = FAIL
+1941 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.integer.bitfieldreverse.ivec3_lowp_geometry = FAIL
+1941 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.integer.bitfieldreverse.ivec3_mediump_geometry = FAIL
+1941 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.integer.bitfieldreverse.ivec3_highp_geometry = FAIL
+1941 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.integer.bitfieldreverse.ivec4_lowp_geometry = FAIL
+1941 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.integer.bitfieldreverse.ivec4_mediump_geometry = FAIL
+1941 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.integer.bitfieldreverse.ivec4_highp_geometry = FAIL
+1941 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.integer.bitfieldreverse.uint_lowp_geometry = FAIL
+1941 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.integer.bitfieldreverse.uint_mediump_geometry = FAIL
+1941 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.integer.bitfieldreverse.uint_highp_geometry = FAIL
+1941 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.integer.bitfieldreverse.uvec2_lowp_geometry = FAIL
+1941 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.integer.bitfieldreverse.uvec2_mediump_geometry = FAIL
+1941 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.integer.bitfieldreverse.uvec2_highp_geometry = FAIL
+1941 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.integer.bitfieldreverse.uvec3_lowp_geometry = FAIL
+1941 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.integer.bitfieldreverse.uvec3_mediump_geometry = FAIL
+1941 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.integer.bitfieldreverse.uvec3_highp_geometry = FAIL
+1941 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.integer.bitfieldreverse.uvec4_lowp_geometry = FAIL
+1941 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.integer.bitfieldreverse.uvec4_mediump_geometry = FAIL
+1941 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.integer.bitfieldreverse.uvec4_highp_geometry = FAIL
+1941 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.integer.bitcount.int_lowp_geometry = FAIL
+1941 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.integer.bitcount.int_mediump_geometry = FAIL
+1941 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.integer.bitcount.int_highp_geometry = FAIL
+1941 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.integer.bitcount.ivec2_lowp_geometry = FAIL
+1941 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.integer.bitcount.ivec2_mediump_geometry = FAIL
+1941 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.integer.bitcount.ivec2_highp_geometry = FAIL
+1941 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.integer.bitcount.ivec3_lowp_geometry = FAIL
+1941 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.integer.bitcount.ivec3_mediump_geometry = FAIL
+1941 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.integer.bitcount.ivec3_highp_geometry = FAIL
+1941 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.integer.bitcount.ivec4_lowp_geometry = FAIL
+1941 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.integer.bitcount.ivec4_mediump_geometry = FAIL
+1941 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.integer.bitcount.ivec4_highp_geometry = FAIL
+1941 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.integer.bitcount.uint_lowp_geometry = FAIL
+1941 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.integer.bitcount.uint_mediump_geometry = FAIL
+1941 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.integer.bitcount.uint_highp_geometry = FAIL
+1941 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.integer.bitcount.uvec2_lowp_geometry = FAIL
+1941 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.integer.bitcount.uvec2_mediump_geometry = FAIL
+1941 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.integer.bitcount.uvec2_highp_geometry = FAIL
+1941 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.integer.bitcount.uvec3_lowp_geometry = FAIL
+1941 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.integer.bitcount.uvec3_mediump_geometry = FAIL
+1941 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.integer.bitcount.uvec3_highp_geometry = FAIL
+1941 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.integer.bitcount.uvec4_lowp_geometry = FAIL
+1941 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.integer.bitcount.uvec4_mediump_geometry = FAIL
+1941 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.integer.bitcount.uvec4_highp_geometry = FAIL
+1941 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.integer.findlsb.int_lowp_geometry = FAIL
+1941 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.integer.findlsb.int_mediump_geometry = FAIL
+1941 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.integer.findlsb.int_highp_geometry = FAIL
+1941 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.integer.findlsb.ivec2_lowp_geometry = FAIL
+1941 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.integer.findlsb.ivec2_mediump_geometry = FAIL
+1941 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.integer.findlsb.ivec2_highp_geometry = FAIL
+1941 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.integer.findlsb.ivec3_lowp_geometry = FAIL
+1941 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.integer.findlsb.ivec3_mediump_geometry = FAIL
+1941 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.integer.findlsb.ivec3_highp_geometry = FAIL
+1941 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.integer.findlsb.ivec4_lowp_geometry = FAIL
+1941 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.integer.findlsb.ivec4_mediump_geometry = FAIL
+1941 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.integer.findlsb.ivec4_highp_geometry = FAIL
+1941 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.integer.findlsb.uint_lowp_geometry = FAIL
+1941 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.integer.findlsb.uint_mediump_geometry = FAIL
+1941 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.integer.findlsb.uint_highp_geometry = FAIL
+1941 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.integer.findlsb.uvec2_lowp_geometry = FAIL
+1941 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.integer.findlsb.uvec2_mediump_geometry = FAIL
+1941 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.integer.findlsb.uvec2_highp_geometry = FAIL
+1941 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.integer.findlsb.uvec3_lowp_geometry = FAIL
+1941 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.integer.findlsb.uvec3_mediump_geometry = FAIL
+1941 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.integer.findlsb.uvec3_highp_geometry = FAIL
+1941 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.integer.findlsb.uvec4_lowp_geometry = FAIL
+1941 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.integer.findlsb.uvec4_mediump_geometry = FAIL
+1941 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.integer.findlsb.uvec4_highp_geometry = FAIL
+1941 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.integer.findmsb.int_lowp_geometry = FAIL
+1941 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.integer.findmsb.int_mediump_geometry = FAIL
+1941 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.integer.findmsb.int_highp_geometry = FAIL
+1941 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.integer.findmsb.ivec2_lowp_geometry = FAIL
+1941 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.integer.findmsb.ivec2_mediump_geometry = FAIL
+1941 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.integer.findmsb.ivec2_highp_geometry = FAIL
+1941 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.integer.findmsb.ivec3_lowp_geometry = FAIL
+1941 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.integer.findmsb.ivec3_mediump_geometry = FAIL
+1941 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.integer.findmsb.ivec3_highp_geometry = FAIL
+1941 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.integer.findmsb.ivec4_lowp_geometry = FAIL
+1941 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.integer.findmsb.ivec4_mediump_geometry = FAIL
+1941 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.integer.findmsb.ivec4_highp_geometry = FAIL
+1941 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.integer.findmsb.uint_lowp_geometry = FAIL
+1941 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.integer.findmsb.uint_mediump_geometry = FAIL
+1941 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.integer.findmsb.uint_highp_geometry = FAIL
+1941 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.integer.findmsb.uvec2_lowp_geometry = FAIL
+1941 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.integer.findmsb.uvec2_mediump_geometry = FAIL
+1941 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.integer.findmsb.uvec2_highp_geometry = FAIL
+1941 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.integer.findmsb.uvec3_lowp_geometry = FAIL
+1941 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.integer.findmsb.uvec3_mediump_geometry = FAIL
+1941 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.integer.findmsb.uvec3_highp_geometry = FAIL
+1941 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.integer.findmsb.uvec4_lowp_geometry = FAIL
+1941 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.integer.findmsb.uvec4_mediump_geometry = FAIL
+1941 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.integer.findmsb.uvec4_highp_geometry = FAIL
+1941 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_constants.geometry_shader.* = FAIL
+1941 OPENGL D3D11 : dEQP-GLES31.functional.shaders.linkage.geometry.* = FAIL
+1941 OPENGL D3D11 : dEQP-GLES31.functional.state_query.program.geometry_shader_state_get_programiv = FAIL
+1941 OPENGL D3D11 : dEQP-GLES31.functional.debug.negative_coverage.callbacks.shader_directive.geometry_shader = FAIL
+1941 OPENGL D3D11 : dEQP-GLES31.functional.debug.negative_coverage.log.shader_directive.geometry_shader = FAIL
+1941 OPENGL D3D11 : dEQP-GLES31.functional.debug.negative_coverage.get_error.shader_directive.geometry_shader = FAIL
+1941 OPENGL D3D11 : dEQP-GLES31.functional.geometry_shading.query.* = FAIL
+1941 OPENGL D3D11 : dEQP-GLES31.functional.geometry_shading.basic.* = FAIL
+1941 OPENGL D3D11 : dEQP-GLES31.functional.geometry_shading.input.* = FAIL
+1941 OPENGL D3D11 : dEQP-GLES31.functional.geometry_shading.conversion.* = FAIL
+1941 OPENGL D3D11 : dEQP-GLES31.functional.geometry_shading.emit.* = FAIL
+1941 OPENGL D3D11 : dEQP-GLES31.functional.geometry_shading.varying.* = FAIL
+1941 OPENGL D3D11 : dEQP-GLES31.functional.geometry_shading.instanced.geometry_* = FAIL
+1941 OPENGL D3D11 : dEQP-GLES31.functional.geometry_shading.instanced.invocation_output_* = FAIL
+1941 OPENGL D3D11 : dEQP-GLES31.functional.geometry_shading.instanced.draw_* = FAIL
+1941 OPENGL D3D11 : dEQP-GLES31.functional.geometry_shading.negative.* = FAIL
--- a/gfx/angle/src/tests/deqp_support/deqp_gles3_test_expectations.txt
+++ b/gfx/angle/src/tests/deqp_support/deqp_gles3_test_expectations.txt
@@ -77,40 +77,42 @@ 1436 WIN : dEQP-GLES3.functional.shaders
 1436 WIN : dEQP-GLES3.functional.shaders.texture_functions.texturegradoffset.sampler2darrayshadow_fragment = FAIL
 1436 WIN : dEQP-GLES3.functional.shaders.texture_functions.textureprojgrad.sampler2dshadow_vertex = FAIL
 1436 WIN : dEQP-GLES3.functional.shaders.texture_functions.textureprojgrad.sampler2dshadow_fragment = FAIL
 1436 WIN : dEQP-GLES3.functional.shaders.texture_functions.textureprojgradoffset.sampler2dshadow_vertex = FAIL
 1436 WIN : dEQP-GLES3.functional.shaders.texture_functions.textureprojgradoffset.sampler2dshadow_fragment = FAIL
 
 // TODO(jmadill, cwallez): triage the failures below into permanent and temporary failures
 
+// Quadro P400
+// TODO(jmadill): Narrow to P400 device only: 0x1CB3.
+2222 D3D11 NVIDIA : dEQP-GLES3.functional.shaders.functions.control_flow.return_in_nested_loop_fragment = FAIL
+2222 D3D11 NVIDIA : dEQP-GLES3.functional.shaders.functions.control_flow.return_in_nested_loop_vertex = FAIL
+2222 D3D11 NVIDIA : dEQP-GLES3.functional.texture.mipmap.2d.min_lod.linear_nearest = FAIL
+2222 D3D11 NVIDIA : dEQP-GLES3.functional.texture.mipmap.2d.min_lod.nearest_nearest = FAIL
+2222 D3D11 NVIDIA : dEQP-GLES3.functional.texture.mipmap.3d.min_lod.linear_nearest = FAIL
+2222 D3D11 NVIDIA : dEQP-GLES3.functional.texture.mipmap.3d.min_lod.nearest_nearest = FAIL
+2222 LINUX NVIDIA : dEQP-GLES3.functional.fbo.completeness.samples.rbo2_rbo2_rbo0 = FAIL
+
 // Failing everywhere
 1101 DEBUG RELEASE : dEQP-GLES3.functional.negative_api.texture.compressedtexsubimage2d = FAIL
 1101 DEBUG RELEASE : dEQP-GLES3.functional.negative_api.texture.compressedtexsubimage3d = FAIL
 1101 DEBUG RELEASE : dEQP-GLES3.functional.negative_api.texture.compressedtexsubimage3d_invalid_buffer_target = FAIL
 
 // Windows and Linux failures
 
 1095 WIN LINUX : dEQP-GLES3.functional.texture.mipmap.2d.projected.nearest_nearest_clamp = FAIL
 1095 WIN LINUX : dEQP-GLES3.functional.texture.mipmap.2d.projected.nearest_nearest_repeat = FAIL
 1095 WIN LINUX : dEQP-GLES3.functional.texture.mipmap.2d.projected.nearest_nearest_mirror = FAIL
 1095 WIN LINUX : dEQP-GLES3.functional.texture.mipmap.2d.projected.linear_nearest_clamp = FAIL
 1095 WIN LINUX : dEQP-GLES3.functional.texture.mipmap.2d.projected.linear_nearest_repeat = FAIL
 1095 WIN LINUX : dEQP-GLES3.functional.texture.mipmap.2d.projected.linear_nearest_mirror = FAIL
 
 // Windows only failure
 
-1093 WIN : dEQP-GLES3.functional.shaders.builtin_functions.precision.tanh.highp_vertex.scalar = FAIL
-1093 WIN : dEQP-GLES3.functional.shaders.builtin_functions.precision.tanh.highp_vertex.vec2 = FAIL
-1093 WIN : dEQP-GLES3.functional.shaders.builtin_functions.precision.tanh.highp_vertex.vec3 = FAIL
-1093 WIN : dEQP-GLES3.functional.shaders.builtin_functions.precision.tanh.highp_vertex.vec4 = FAIL
-1093 WIN : dEQP-GLES3.functional.shaders.builtin_functions.precision.tanh.highp_fragment.scalar = FAIL
-1093 WIN : dEQP-GLES3.functional.shaders.builtin_functions.precision.tanh.highp_fragment.vec2 = FAIL
-1093 WIN : dEQP-GLES3.functional.shaders.builtin_functions.precision.tanh.highp_fragment.vec3 = FAIL
-1093 WIN : dEQP-GLES3.functional.shaders.builtin_functions.precision.tanh.highp_fragment.vec4 = FAIL
 1092 WIN : dEQP-GLES3.functional.shaders.texture_functions.textureoffset.sampler3d_fixed_fragment = FAIL
 1092 WIN : dEQP-GLES3.functional.shaders.texture_functions.textureoffset.sampler3d_float_fragment = FAIL
 1092 WIN : dEQP-GLES3.functional.shaders.texture_functions.textureprojoffset.sampler3d_fixed_fragment = FAIL
 1092 WIN : dEQP-GLES3.functional.shaders.texture_functions.textureprojoffset.sampler3d_float_fragment = FAIL
 1096 WIN : dEQP-GLES3.functional.fragment_ops.depth_stencil.stencil_depth_funcs.stencil_* = FAIL
 1096 WIN : dEQP-GLES3.functional.fragment_ops.depth_stencil.stencil_ops.* = FAIL
 1096 WIN : dEQP-GLES3.functional.fragment_ops.depth_stencil.write_mask.* = FAIL
 1096 WIN : dEQP-GLES3.functional.fragment_ops.depth_stencil.random.* = FAIL
--- a/gfx/angle/src/tests/egl_tests/EGLContextCompatibilityTest.cpp
+++ b/gfx/angle/src/tests/egl_tests/EGLContextCompatibilityTest.cpp
@@ -278,16 +278,21 @@ TEST_P(EGLContextCompatibilityTest, Pbuf
         }
     }
 }
 
 // Check that a context rendering to a window with a different
 // config works or errors according to the EGL compatibility rules
 TEST_P(EGLContextCompatibilityTest, WindowDifferentConfig)
 {
+    // anglebug.com/2183
+    // Actually failed only on (IsIntel() && IsWindows() && IsD3D11()),
+    // but it's impossible to do other tests since GL_RENDERER is NULL
+    ANGLE_SKIP_TEST_IF(IsWindows());
+
     for (size_t i = 0; i < mConfigs.size(); i++)
     {
         EGLConfig config1 = mConfigs[i];
         // Disabling multisampled configurations due to test instability with various graphics cards
         if (isMultisampledConfig(config1))
         {
             continue;
         }
new file mode 100644
--- /dev/null
+++ b/gfx/angle/src/tests/egl_tests/EGLIOSurfaceClientBufferTest.cpp
@@ -0,0 +1,118 @@
+//
+// 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.
+//
+//    EGLIOSurfaceClientBufferTest.cpp: tests for the EGL_ANGLE_iosurface_client_buffer extension.
+//
+
+#include "test_utils/ANGLETest.h"
+#include "test_utils/gl_raii.h"
+
+#include <CoreFoundation/CoreFoundation.h>
+#include <IOSurface/IOSurface.h>
+
+#define GL_UNSIGNED_INT_8_8_8_8_REV 0x8367
+
+using namespace angle;
+
+namespace
+{
+
+void AddIntegerValue(CFMutableDictionaryRef dictionary, const CFStringRef key, int32_t value)
+{
+    CFNumberRef number = CFNumberCreate(nullptr, kCFNumberSInt32Type, &value);
+    CFDictionaryAddValue(dictionary, key, number);
+    CFRelease(number);
+}
+
+}  // anonymous namespace
+
+class IOSurfaceClientBufferTest : public ANGLETest
+{
+  protected:
+    IOSurfaceClientBufferTest() : mConfig(0), mDisplay(nullptr) {}
+
+    void SetUp() override
+    {
+        ANGLETest::SetUp();
+
+        mConfig  = getEGLWindow()->getConfig();
+        mDisplay = getEGLWindow()->getDisplay();
+    }
+
+    void TearDown() override { ANGLETest::TearDown(); }
+
+    EGLConfig mConfig;
+    EGLDisplay mDisplay;
+};
+
+TEST_P(IOSurfaceClientBufferTest, RenderToBGRA8888IOSurface)
+{
+    // Create a 1 by 1 BGRA8888 IOSurface
+    IOSurfaceRef ioSurface = nullptr;
+
+    CFMutableDictionaryRef dict = CFDictionaryCreateMutable(
+        kCFAllocatorDefault, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
+    AddIntegerValue(dict, kIOSurfaceWidth, 1);
+    AddIntegerValue(dict, kIOSurfaceHeight, 1);
+    AddIntegerValue(dict, kIOSurfacePixelFormat, 'BGRA');
+    AddIntegerValue(dict, kIOSurfaceBytesPerElement, 4);
+
+    ioSurface = IOSurfaceCreate(dict);
+    CFRelease(dict);
+
+    EXPECT_NE(nullptr, ioSurface);
+
+    // Make a PBuffer from it using the EGL_ANGLE_iosurface_client_buffer extension
+    // clang-format off
+    const EGLint attribs[] = {
+        EGL_WIDTH,                         1,
+        EGL_HEIGHT,                        1,
+        EGL_IOSURFACE_PLANE_ANGLE,         0,
+        EGL_TEXTURE_TARGET,                EGL_TEXTURE_RECTANGLE_ANGLE,
+        EGL_TEXTURE_INTERNAL_FORMAT_ANGLE, GL_BGRA_EXT,
+        EGL_TEXTURE_FORMAT,                EGL_TEXTURE_RGBA,
+        EGL_TEXTURE_TYPE_ANGLE,            GL_UNSIGNED_BYTE,
+        EGL_NONE,                          EGL_NONE,
+    };
+    // clang-format off
+
+    EGLSurface pbuffer = eglCreatePbufferFromClientBuffer(mDisplay, EGL_IOSURFACE_ANGLE, ioSurface, mConfig, attribs);
+    EXPECT_NE(EGL_NO_SURFACE, pbuffer);
+
+    // Bind and glClear the pbuffer
+    GLTexture tex;
+    glBindTexture(GL_TEXTURE_RECTANGLE_ANGLE, tex);
+    EGLBoolean result = eglBindTexImage(mDisplay, pbuffer, EGL_BACK_BUFFER);
+    EXPECT_EGL_TRUE(result);
+    EXPECT_EGL_SUCCESS();
+
+    GLFramebuffer fbo;
+    glBindFramebuffer(GL_FRAMEBUFFER, fbo);
+    EXPECT_GL_NO_ERROR();
+    glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_RECTANGLE_ANGLE, tex, 0);
+    EXPECT_GL_NO_ERROR();
+    EXPECT_GLENUM_EQ(glCheckFramebufferStatus(GL_FRAMEBUFFER), GL_FRAMEBUFFER_COMPLETE);
+    EXPECT_GL_NO_ERROR();
+
+    glClearColor(0, 1, 0, 1);
+    EXPECT_GL_NO_ERROR();
+    glClear(GL_COLOR_BUFFER_BIT);
+    EXPECT_GL_NO_ERROR();
+
+    // Unbind pbuffer and check content.
+    result = eglReleaseTexImage(mDisplay, pbuffer, EGL_BACK_BUFFER);
+    EXPECT_EGL_TRUE(result);
+    EXPECT_EGL_SUCCESS();
+
+    IOSurfaceLock(ioSurface, kIOSurfaceLockReadOnly, nullptr);
+    GLColor color = *reinterpret_cast<const GLColor*>(IOSurfaceGetBaseAddress(ioSurface));
+    IOSurfaceUnlock(ioSurface, kIOSurfaceLockReadOnly, nullptr);
+
+    CFRelease(ioSurface);
+
+    EXPECT_EQ(color, GLColor::green);
+}
+
+ANGLE_INSTANTIATE_TEST(IOSurfaceClientBufferTest, ES3_OPENGL());
--- a/gfx/angle/src/tests/egl_tests/EGLSanityCheckTest.cpp
+++ b/gfx/angle/src/tests/egl_tests/EGLSanityCheckTest.cpp
@@ -23,8 +23,15 @@ TEST(EGLSanityCheckTest, IsRunningOnANGL
 TEST(EGLSanityCheckTest, HasGetPlatformDisplayEXT)
 {
     PFNEGLGETPLATFORMDISPLAYEXTPROC eglGetPlatformDisplayEXT =
         reinterpret_cast<PFNEGLGETPLATFORMDISPLAYEXTPROC>(
             eglGetProcAddress("eglGetPlatformDisplayEXT"));
 
     ASSERT_NE(eglGetPlatformDisplayEXT, nullptr);
 }
+
+// Checks that calling GetProcAddress for a non-existant function fails.
+TEST(EGLSanityCheckTest, GetProcAddressNegativeTest)
+{
+    auto check = eglGetProcAddress("WigglyWombats");
+    EXPECT_EQ(nullptr, check);
+}
\ No newline at end of file
--- a/gfx/angle/src/tests/egl_tests/EGLStreamTest.cpp
+++ b/gfx/angle/src/tests/egl_tests/EGLStreamTest.cpp
@@ -6,25 +6,38 @@
 // EGLStreamTest:
 //   Tests pertaining to egl::Stream.
 //
 
 #include <gtest/gtest.h>
 
 #include <vector>
 
+#include "OSWindow.h"
 #include "media/yuvtest.inl"
-#include "OSWindow.h"
 #include "test_utils/ANGLETest.h"
+#include "test_utils/gl_raii.h"
 
 using namespace angle;
 
 namespace
 {
 
+bool CheckNV12TextureSupport(ID3D11Device *device)
+{
+    HRESULT result;
+    UINT formatSupport;
+    result = device->CheckFormatSupport(DXGI_FORMAT_NV12, &formatSupport);
+    if (result == E_FAIL)
+    {
+        return false;
+    }
+    return (formatSupport & D3D11_FORMAT_SUPPORT_TEXTURE2D) != 0;
+}
+
 class EGLStreamTest : public ANGLETest
 {
   protected:
     EGLStreamTest()
     {
         setWindowWidth(128);
         setWindowHeight(128);
         setConfigRedBits(8);
@@ -286,19 +299,19 @@ TEST_P(EGLStreamTest, StreamConsumerGLTe
 }
 
 // Tests that deleting a texture invalidates the associated stream
 TEST_P(EGLStreamTest, StreamConsumerGLTextureYUVDeletionTest)
 {
     EGLWindow *window            = getEGLWindow();
     EGLDisplay display           = window->getDisplay();
     const char *extensionsString = eglQueryString(display, EGL_EXTENSIONS);
-    if (strstr(extensionsString, "EGL_ANGLE_stream_producer_d3d_texture_nv12") == nullptr)
+    if (strstr(extensionsString, "EGL_ANGLE_stream_producer_d3d_texture") == nullptr)
     {
-        std::cout << "Stream producer d3d nv12 texture not supported" << std::endl;
+        std::cout << "Stream producer d3d texture not supported" << std::endl;
         return;
     }
 
     const EGLint streamAttributes[] = {
         EGL_CONSUMER_LATENCY_USEC_KHR, 0, EGL_CONSUMER_ACQUIRE_TIMEOUT_USEC_KHR, 0, EGL_NONE,
     };
 
     EGLStreamKHR stream = eglCreateStreamKHR(display, streamAttributes);
@@ -327,17 +340,17 @@ TEST_P(EGLStreamTest, StreamConsumerGLTe
         eglStreamConsumerGLTextureExternalAttribsNV(display, stream, consumerAttributes);
     ASSERT_EGL_TRUE(result);
     ASSERT_EGL_SUCCESS();
 
     EGLAttrib producerAttributes[] = {
         EGL_NONE,
     };
 
-    result = eglCreateStreamProducerD3DTextureNV12ANGLE(display, stream, producerAttributes);
+    result = eglCreateStreamProducerD3DTextureANGLE(display, stream, producerAttributes);
     ASSERT_EGL_TRUE(result);
     ASSERT_EGL_SUCCESS();
 
     EGLint state;
     eglQueryStreamKHR(display, stream, EGL_STREAM_STATE_KHR, &state);
     ASSERT_EGL_SUCCESS();
     ASSERT_EQ(EGL_STREAM_STATE_EMPTY_KHR, state);
 
@@ -347,27 +360,302 @@ TEST_P(EGLStreamTest, StreamConsumerGLTe
     eglQueryStreamKHR(display, stream, EGL_STREAM_STATE_KHR, &state);
     ASSERT_EGL_SUCCESS();
     ASSERT_EQ(EGL_STREAM_STATE_DISCONNECTED_KHR, state);
 
     eglDestroyStreamKHR(display, stream);
     ASSERT_EGL_SUCCESS();
 }
 
+class D3D11TextureStreamSamplingTest : public ANGLETest
+{
+  protected:
+    void SetUp() override
+    {
+        ANGLETest::SetUp();
+
+        EGLWindow *window = getEGLWindow();
+        mDisplay          = window->getDisplay();
+        if (!eglDisplayExtensionEnabled(mDisplay, "EGL_ANGLE_stream_producer_d3d_texture"))
+        {
+            std::cout << "Stream producer d3d texture not supported" << std::endl;
+            return;
+        }
+
+        glGenRenderbuffers(1, &mRB);
+        glBindRenderbuffer(GL_RENDERBUFFER, mRB);
+        glRenderbufferStorage(GL_RENDERBUFFER, GL_RGBA8, 2, 2);
+        glBindRenderbuffer(GL_RENDERBUFFER, 0);
+
+        glGenFramebuffers(1, &mFB);
+        glBindFramebuffer(GL_FRAMEBUFFER, mFB);
+        glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, mRB);
+        ASSERT_GLENUM_EQ(GL_FRAMEBUFFER_COMPLETE, glCheckFramebufferStatus(GL_FRAMEBUFFER));
+
+        glViewport(0, 0, 2, 2);
+        glClearColor(1, 0, 0, 1);
+        glClear(GL_COLOR_BUFFER_BIT);
+        ASSERT_GL_NO_ERROR();
+
+        uint32_t pixel;
+        glReadPixels(0, 0, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, &pixel);
+        ASSERT_EQ(pixel, 0xff0000ff);
+
+        mStream = eglCreateStreamKHR(mDisplay, nullptr);
+        ASSERT_EGL_SUCCESS();
+
+        EGLDeviceEXT eglDevice;
+        eglQueryDisplayAttribEXT(mDisplay, EGL_DEVICE_EXT, (EGLAttrib *)&eglDevice);
+        eglQueryDeviceAttribEXT(eglDevice, EGL_D3D11_DEVICE_ANGLE, (EGLAttrib *)&mD3D);
+    }
+
+    void TearDown() override
+    {
+        EGLBoolean result = eglDestroyStreamKHR(mDisplay, mStream);
+        ASSERT_EGL_TRUE(result);
+        ASSERT_EGL_SUCCESS();
+
+        glDeleteRenderbuffers(1, &mRB);
+        glDeleteFramebuffers(1, &mFB);
+
+        ANGLETest::TearDown();
+    }
+
+    EGLDisplay mDisplay  = 0;
+    EGLStreamKHR mStream = 0;
+    GLuint mRB           = 0;
+    GLuint mFB           = 0;
+    ID3D11Device *mD3D;
+};
+
+// Test RGBA texture sampling via EGLStreams
+TEST_P(D3D11TextureStreamSamplingTest, RGBA)
+{
+    EGLWindow *window  = getEGLWindow();
+    EGLDisplay display = window->getDisplay();
+    ANGLE_SKIP_TEST_IF(
+        !eglDisplayExtensionEnabled(display, "EGL_ANGLE_stream_producer_d3d_texture"));
+
+    constexpr char kVertShader[] = R"(
+        attribute vec4 aPos;
+        varying vec2 vTexCoord;
+        void main()
+        {
+            gl_Position = aPos;
+            vTexCoord = gl_Position.xy * 0.5 + 0.5;
+        }
+    )";
+    constexpr char kFragShader[] = R"(
+        #extension GL_NV_EGL_stream_consumer_external : require
+        precision mediump float;
+        uniform samplerExternalOES uTex;
+        varying vec2 vTexCoord;
+        void main()
+        {
+            gl_FragColor = texture2D(uTex, vTexCoord);
+        }
+    )";
+    ANGLE_GL_PROGRAM(prog, kVertShader, kFragShader);
+    glUseProgram(prog);
+    glUniform1i(glGetUniformLocation(prog, "uTex"), 0);
+
+    GLTexture tex;
+    glActiveTexture(GL_TEXTURE0);
+    glBindTexture(GL_TEXTURE_EXTERNAL_OES, tex);
+    glTexParameteri(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
+    ASSERT_GL_NO_ERROR();
+
+    EGLBoolean result = eglStreamConsumerGLTextureExternalAttribsNV(mDisplay, mStream, nullptr);
+    ASSERT_EGL_TRUE(result);
+    ASSERT_EGL_SUCCESS();
+    glActiveTexture(GL_TEXTURE3);  // Set to an unused slot to ensure StreamConsumer picked up
+                                   // the current slot.
+
+    result = eglCreateStreamProducerD3DTextureANGLE(mDisplay, mStream, nullptr);
+    ASSERT_EGL_TRUE(result);
+    ASSERT_EGL_SUCCESS();
+
+    // Create and post the d3d11 texture
+
+    D3D11_TEXTURE2D_DESC desc = {};
+    desc.Width                = 1;
+    desc.Height               = 1;
+    desc.Format               = DXGI_FORMAT_R8G8B8A8_UNORM;
+    desc.MipLevels            = 1;
+    desc.ArraySize            = 1;
+    desc.SampleDesc.Count     = 1;
+    desc.Usage                = D3D11_USAGE_DEFAULT;
+    desc.BindFlags            = D3D11_BIND_SHADER_RESOURCE;
+
+    constexpr uint8_t texData[] = {0x10, 0x20, 0x30, 0x40};
+    D3D11_SUBRESOURCE_DATA subres;
+    subres.pSysMem     = texData;
+    subres.SysMemPitch = 4;
+
+    ID3D11Texture2D *texture = nullptr;
+    (void)mD3D->CreateTexture2D(&desc, &subres, &texture);
+    ASSERT_NE(nullptr, texture);
+
+    result = eglStreamPostD3DTextureANGLE(mDisplay, mStream, (void *)texture, nullptr);
+    ASSERT_EGL_TRUE(result);
+    ASSERT_EGL_SUCCESS();
+
+    // Sample and test
+
+    result = eglStreamConsumerAcquireKHR(mDisplay, mStream);
+    ASSERT_EGL_TRUE(result);
+    ASSERT_EGL_SUCCESS();
+
+    drawQuad(prog, "aPos", 0.0);
+
+    uint32_t pixel;
+    glReadPixels(0, 0, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, &pixel);
+    ASSERT_GL_NO_ERROR();
+    ASSERT_EQ(pixel, static_cast<uint32_t>(0x40302010));
+
+    result = eglStreamConsumerReleaseKHR(mDisplay, mStream);
+    ASSERT_EGL_TRUE(result);
+    ASSERT_EGL_SUCCESS();
+}
+
+// Test NV12 texture sampling via EGLStreams
+TEST_P(D3D11TextureStreamSamplingTest, NV12)
+{
+    EGLWindow *window  = getEGLWindow();
+    EGLDisplay display = window->getDisplay();
+    ANGLE_SKIP_TEST_IF(
+        !eglDisplayExtensionEnabled(display, "EGL_ANGLE_stream_producer_d3d_texture"));
+    ANGLE_SKIP_TEST_IF(!CheckNV12TextureSupport(mD3D));
+
+    constexpr char kVertShader[] = R"(
+        attribute vec4 aPos;
+        varying vec2 vTexCoord;
+        void main()
+        {
+            gl_Position = aPos;
+            vTexCoord = gl_Position.xy * 0.5 + 0.5;
+        }
+    )";
+    const char kFragShader[]     = R"(
+        #extension GL_NV_EGL_stream_consumer_external : require
+        precision mediump float;
+        uniform samplerExternalOES uTexY;
+        uniform samplerExternalOES uTexUV;
+        varying vec2 vTexCoord;
+        void main()
+        {
+            gl_FragColor.r = texture2D(uTexY, vTexCoord).r;
+            gl_FragColor.gb = texture2D(uTexUV, vTexCoord).rg;
+            gl_FragColor.a = 1.0;
+        }
+    )";
+    ANGLE_GL_PROGRAM(prog, kVertShader, kFragShader);
+    glUseProgram(prog);
+    glUniform1i(glGetUniformLocation(prog, "uTexY"), 0);
+    glUniform1i(glGetUniformLocation(prog, "uTexUV"), 1);
+
+    ASSERT_GL_NO_ERROR();
+
+    GLTexture tex[2];
+    glActiveTexture(GL_TEXTURE0);
+    glBindTexture(GL_TEXTURE_EXTERNAL_OES, tex[0]);
+    glTexParameteri(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
+    ASSERT_GL_NO_ERROR();
+    glActiveTexture(GL_TEXTURE1);
+    glBindTexture(GL_TEXTURE_EXTERNAL_OES, tex[1]);
+    glTexParameteri(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
+    ASSERT_GL_NO_ERROR();
+
+    glActiveTexture(GL_TEXTURE3);  // Set to an unused slot to ensure StreamConsumer picks up
+                                   // the current slot.
+    constexpr EGLAttrib consumerAttributes[] = {
+        EGL_COLOR_BUFFER_TYPE,
+        EGL_YUV_BUFFER_EXT,
+        EGL_YUV_NUMBER_OF_PLANES_EXT,
+        2,
+        EGL_YUV_PLANE0_TEXTURE_UNIT_NV,
+        0,
+        EGL_YUV_PLANE1_TEXTURE_UNIT_NV,
+        1,
+        EGL_NONE,
+    };
+    EGLBoolean result = eglStreamConsumerGLTextureExternalAttribsNV(
+        mDisplay, mStream, const_cast<EGLAttrib *>(consumerAttributes));
+    ASSERT_EGL_TRUE(result);
+    ASSERT_EGL_SUCCESS();
+
+    result = eglCreateStreamProducerD3DTextureANGLE(mDisplay, mStream, nullptr);
+    ASSERT_EGL_TRUE(result);
+    ASSERT_EGL_SUCCESS();
+
+    // Create and post the d3d11 texture
+
+    D3D11_TEXTURE2D_DESC desc = {};
+    desc.Width                = 2;
+    desc.Height               = 2;
+    desc.Format               = DXGI_FORMAT_NV12;
+    desc.MipLevels            = 1;
+    desc.ArraySize            = 1;
+    desc.SampleDesc.Count     = 1;
+    desc.Usage                = D3D11_USAGE_DEFAULT;
+    desc.BindFlags            = D3D11_BIND_SHADER_RESOURCE;
+
+    /* DXGI_FORMAT_NV12:
+     * Width and height must be even.
+     * Direct3D 11 staging resources and initData parameters for this format use
+     * (rowPitch * (height + (height / 2))) bytes.
+     * The first (SysMemPitch * height) bytes are the Y plane, the remaining
+     * (SysMemPitch * (height / 2)) bytes are the UV plane.
+     */
+    constexpr uint8_t texData[] = {0x10, 0x20, 0x30, 0x40, 0x50, 0x60};
+    D3D11_SUBRESOURCE_DATA subres;
+    subres.pSysMem     = texData;
+    subres.SysMemPitch = 2;
+
+    ID3D11Texture2D *texture = nullptr;
+    (void)mD3D->CreateTexture2D(&desc, &subres, &texture);
+    ASSERT_NE(nullptr, texture);
+
+    result = eglStreamPostD3DTextureANGLE(mDisplay, mStream, (void *)texture, nullptr);
+    ASSERT_EGL_TRUE(result);
+    ASSERT_EGL_SUCCESS();
+
+    // Sample and test
+
+    result = eglStreamConsumerAcquireKHR(mDisplay, mStream);
+    ASSERT_EGL_TRUE(result);
+    ASSERT_EGL_SUCCESS();
+
+    drawQuad(prog, "aPos", 0.0);
+    uint32_t pixel;
+    glReadPixels(0, 0, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, &pixel);
+    ASSERT_EQ(pixel, 0xff605010);
+
+    glReadPixels(1, 0, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, &pixel);
+    ASSERT_EQ(pixel, 0xff605020);
+
+    glReadPixels(0, 1, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, &pixel);
+    ASSERT_EQ(pixel, 0xff605030);
+
+    glReadPixels(1, 1, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, &pixel);
+    ASSERT_EQ(pixel, 0xff605040);
+
+    result = eglStreamConsumerReleaseKHR(mDisplay, mStream);
+    ASSERT_EGL_TRUE(result);
+    ASSERT_EGL_SUCCESS();
+}
+
 // End2end test for rendering an NV12 texture. Renders a YUV quad, reads back the RGB values, and
 // ensures they are correct
 TEST_P(EGLStreamTest, StreamProducerTextureNV12End2End)
 {
     EGLWindow *window            = getEGLWindow();
     EGLDisplay display           = window->getDisplay();
-    if (!eglDisplayExtensionEnabled(display, "EGL_ANGLE_stream_producer_d3d_texture_nv12"))
-    {
-        std::cout << "Stream producer d3d nv12 texture not supported" << std::endl;
-        return;
-    }
+    ANGLE_SKIP_TEST_IF(
+        !eglDisplayExtensionEnabled(display, "EGL_ANGLE_stream_producer_d3d_texture"));
 
     bool useESSL3Shaders =
         getClientMajorVersion() >= 3 && extensionEnabled("GL_OES_EGL_image_external_essl3");
 
     // yuv to rgb conversion shader using Microsoft's given conversion formulas
     std::string yuvVS, yuvPS;
     if (useESSL3Shaders)
     {
@@ -437,18 +725,19 @@ TEST_P(EGLStreamTest, StreamProducerText
     GLuint uvUniform = glGetUniformLocation(program, "uv");
 
     // Fetch the D3D11 device
     EGLDeviceEXT eglDevice;
     eglQueryDisplayAttribEXT(display, EGL_DEVICE_EXT, (EGLAttrib *)&eglDevice);
     ID3D11Device *device;
     eglQueryDeviceAttribEXT(eglDevice, EGL_D3D11_DEVICE_ANGLE, (EGLAttrib *)&device);
 
+    ANGLE_SKIP_TEST_IF(!CheckNV12TextureSupport(device));
+
     // Create the NV12 D3D11 texture
-    HRESULT res;
     D3D11_TEXTURE2D_DESC desc;
     desc.Width              = yuvtest_width;
     desc.Height             = yuvtest_height;
     desc.Format             = DXGI_FORMAT_NV12;
     desc.MipLevels          = 1;
     desc.ArraySize          = 1;
     desc.SampleDesc.Count   = 1;
     desc.SampleDesc.Quality = 0;
@@ -458,17 +747,18 @@ TEST_P(EGLStreamTest, StreamProducerText
     desc.MiscFlags          = 0;
 
     D3D11_SUBRESOURCE_DATA subres;
     subres.pSysMem          = yuvtest_data;
     subres.SysMemPitch      = yuvtest_width;
     subres.SysMemSlicePitch = yuvtest_width * yuvtest_height * 3 / 2;
 
     ID3D11Texture2D *texture = nullptr;
-    res                      = device->CreateTexture2D(&desc, &subres, &texture);
+    (void)device->CreateTexture2D(&desc, &subres, &texture);
+    ASSERT_NE(nullptr, texture);
 
     // Create the stream
     const EGLint streamAttributes[] = {
         EGL_CONSUMER_LATENCY_USEC_KHR, 0, EGL_CONSUMER_ACQUIRE_TIMEOUT_USEC_KHR, 0, EGL_NONE,
     };
 
     EGLStreamKHR stream = eglCreateStreamKHR(display, streamAttributes);
     ASSERT_EGL_SUCCESS();
@@ -500,25 +790,25 @@ TEST_P(EGLStreamTest, StreamProducerText
         eglStreamConsumerGLTextureExternalAttribsNV(display, stream, consumerAttributes);
     ASSERT_EGL_TRUE(result);
     ASSERT_EGL_SUCCESS();
 
     EGLAttrib producerAttributes[] = {
         EGL_NONE,
     };
 
-    result = eglCreateStreamProducerD3DTextureNV12ANGLE(display, stream, producerAttributes);
+    result = eglCreateStreamProducerD3DTextureANGLE(display, stream, producerAttributes);
     ASSERT_EGL_TRUE(result);
     ASSERT_EGL_SUCCESS();
 
     // Insert the frame
     EGLAttrib frameAttributes[] = {
         EGL_D3D_TEXTURE_SUBRESOURCE_ID_ANGLE, 0, EGL_NONE,
     };
-    result = eglStreamPostD3DTextureNV12ANGLE(display, stream, (void *)texture, frameAttributes);
+    result = eglStreamPostD3DTextureANGLE(display, stream, (void *)texture, frameAttributes);
     ASSERT_EGL_TRUE(result);
     ASSERT_EGL_SUCCESS();
 
     EGLint state;
     eglQueryStreamKHR(display, stream, EGL_STREAM_STATE_KHR, &state);
     ASSERT_EGL_SUCCESS();
     ASSERT_EQ(EGL_STREAM_STATE_NEW_FRAME_AVAILABLE_KHR, state);
 
@@ -539,9 +829,10 @@ TEST_P(EGLStreamTest, StreamProducerText
 }
 
 ANGLE_INSTANTIATE_TEST(EGLStreamTest,
                        ES2_D3D9(),
                        ES2_D3D11(),
                        ES3_D3D11(),
                        ES2_OPENGL(),
                        ES3_OPENGL());
+ANGLE_INSTANTIATE_TEST(D3D11TextureStreamSamplingTest, ES2_D3D11(), ES3_D3D11());
 }  // anonymous namespace
--- a/gfx/angle/src/tests/gl_tests/BindGeneratesResourceTest.cpp
+++ b/gfx/angle/src/tests/gl_tests/BindGeneratesResourceTest.cpp
@@ -25,31 +25,31 @@ TEST_P(BindGeneratesResourceTest, Extens
 }
 
 // Verify that GL_BIND_GENERATES_RESOURCE_CHROMIUM can be queried but not changed
 TEST_P(BindGeneratesResourceTest, QueryValidation)
 {
     GLint intValue = 2;
     glGetIntegerv(GL_BIND_GENERATES_RESOURCE_CHROMIUM, &intValue);
     EXPECT_GL_NO_ERROR();
-    EXPECT_EQ(intValue, GL_FALSE);
+    EXPECT_GL_FALSE(intValue);
 
     float floatValue = 2.0f;
     glGetFloatv(GL_BIND_GENERATES_RESOURCE_CHROMIUM, &floatValue);
     EXPECT_GL_NO_ERROR();
     EXPECT_EQ(floatValue, 0.0f);
 
     GLboolean boolValue = GL_TRUE;
     glGetBooleanv(GL_BIND_GENERATES_RESOURCE_CHROMIUM, &boolValue);
     EXPECT_GL_NO_ERROR();
-    EXPECT_EQ(boolValue, GL_FALSE);
+    EXPECT_GL_FALSE(boolValue);
 
     boolValue = glIsEnabled(GL_BIND_GENERATES_RESOURCE_CHROMIUM);
     EXPECT_GL_NO_ERROR();
-    EXPECT_EQ(boolValue, GL_FALSE);
+    EXPECT_GL_FALSE(boolValue);
 
     glEnable(GL_BIND_GENERATES_RESOURCE_CHROMIUM);
     EXPECT_GL_ERROR(GL_INVALID_ENUM);
 
     glDisable(GL_BIND_GENERATES_RESOURCE_CHROMIUM);
     EXPECT_GL_ERROR(GL_INVALID_ENUM);
 }
 
--- a/gfx/angle/src/tests/gl_tests/BindUniformLocationTest.cpp
+++ b/gfx/angle/src/tests/gl_tests/BindUniformLocationTest.cpp
@@ -647,16 +647,62 @@ TEST_P(BindUniformLocationES31Test, Loca
     EXPECT_NE(0u, fs);
     linkProgramWithUniformLocation(vs, fs, "tex2", tex2Location);
 
     GLint linked = GL_FALSE;
     glGetProgramiv(mProgram, GL_LINK_STATUS, &linked);
     ASSERT_GL_FALSE(linked);
 }
 
+// Test for binding a location for an array of arrays uniform.
+TEST_P(BindUniformLocationES31Test, ArrayOfArrays)
+{
+    ANGLE_SKIP_TEST_IF(!extensionEnabled("GL_CHROMIUM_bind_uniform_location"));
+
+    const std::string vsSource =
+        R"(#version 310 es
+
+        in vec4 a_position;
+
+        void main()
+        {
+            gl_Position = a_position;
+        })";
+
+    const std::string fsSource =
+        R"(#version 310 es
+        precision highp float;
+        uniform vec4 sourceColor[2][1];
+        out highp vec4 my_FragColor;
+        void main()
+        {
+            my_FragColor = sourceColor[1][0];
+        })";
+
+    const GLuint location = 8;
+
+    GLuint vs = CompileShader(GL_VERTEX_SHADER, vsSource);
+    EXPECT_NE(0u, vs);
+    GLuint fs = CompileShader(GL_FRAGMENT_SHADER, fsSource);
+    EXPECT_NE(0u, fs);
+    linkProgramWithUniformLocation(vs, fs, "sourceColor[1]", location);
+
+    GLint linked = GL_FALSE;
+    glGetProgramiv(mProgram, GL_LINK_STATUS, &linked);
+    ASSERT_GL_TRUE(linked);
+
+    glUseProgram(mProgram);
+    glUniform4f(location, 0.0f, 1.0f, 0.0f, 1.0f);
+
+    drawQuad(mProgram, "a_position", 0.5f);
+    EXPECT_GL_NO_ERROR();
+
+    EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
+}
+
 // Use this to select which configurations (e.g. which renderer, which GLES major version) these
 // tests should be run against.
 ANGLE_INSTANTIATE_TEST(BindUniformLocationTest,
                        ES2_D3D9(),
                        ES2_D3D11(),
                        ES2_D3D11_FL9_3(),
                        ES2_OPENGL(),
                        ES2_OPENGLES());
--- a/gfx/angle/src/tests/gl_tests/BlendMinMaxTest.cpp
+++ b/gfx/angle/src/tests/gl_tests/BlendMinMaxTest.cpp
@@ -153,23 +153,22 @@ class BlendMinMaxTest : public ANGLETest
 
         glEnable(GL_BLEND);
         glDisable(GL_DEPTH_TEST);
     }
 
     void SetUpFramebuffer(GLenum colorFormat)
     {
         glGenFramebuffers(1, &mFramebuffer);
-        glBindFramebuffer(GL_DRAW_FRAMEBUFFER, mFramebuffer);
-        glBindFramebuffer(GL_READ_FRAMEBUFFER, mFramebuffer);
+        glBindFramebuffer(GL_FRAMEBUFFER, mFramebuffer);
 
         glGenRenderbuffers(1, &mColorRenderbuffer);
         glBindRenderbuffer(GL_RENDERBUFFER, mColorRenderbuffer);
         glRenderbufferStorage(GL_RENDERBUFFER, colorFormat, getWindowWidth(), getWindowHeight());
-        glFramebufferRenderbuffer(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, mColorRenderbuffer);
+        glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, mColorRenderbuffer);
 
         glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
         glClear(GL_COLOR_BUFFER_BIT);
 
         ASSERT_GL_NO_ERROR();
     }
 
     virtual void TearDown()
@@ -197,23 +196,16 @@ TEST_P(BlendMinMaxTest, RGBA32F)
 {
     if (getClientMajorVersion() < 3 || !extensionEnabled("GL_EXT_color_buffer_float"))
     {
         std::cout << "Test skipped because ES3 and GL_EXT_color_buffer_float are not available."
                   << std::endl;
         return;
     }
 
-    // TODO(jmadill): Figure out why this is broken on Intel
-    if (IsIntel() && (GetParam() == ES2_D3D11() || GetParam() == ES2_D3D9()))
-    {
-        std::cout << "Test skipped on Intel OpenGL." << std::endl;
-        return;
-    }
-
     // TODO (bug 1284): Investigate RGBA32f D3D SDK Layers messages on D3D11_FL9_3
     if (IsD3D11_FL93())
     {
         std::cout << "Test skipped on Feature Level 9_3." << std::endl;
         return;
     }
 
     runTest(GL_RGBA32F, GL_FLOAT);
@@ -223,23 +215,16 @@ TEST_P(BlendMinMaxTest, RGBA16F)
 {
     if (getClientMajorVersion() < 3 && !extensionEnabled("GL_EXT_color_buffer_half_float"))
     {
         std::cout << "Test skipped because ES3 or GL_EXT_color_buffer_half_float is not available."
                   << std::endl;
         return;
     }
 
-    // TODO(jmadill): figure out why this fails
-    if (IsIntel() && (GetParam() == ES2_D3D11() || GetParam() == ES2_D3D9()))
-    {
-        std::cout << "Test skipped on Intel due to failures." << std::endl;
-        return;
-    }
-
     runTest(GL_RGBA16F, GL_FLOAT);
 }
 
 // Use this to select which configurations (e.g. which renderer, which GLES major version) these tests should be run against.
 ANGLE_INSTANTIATE_TEST(BlendMinMaxTest,
                        ES2_D3D9(),
                        ES2_D3D11(),
                        ES3_D3D11(),
--- a/gfx/angle/src/tests/gl_tests/BufferDataTest.cpp
+++ b/gfx/angle/src/tests/gl_tests/BufferDataTest.cpp
@@ -130,87 +130,16 @@ TEST_P(BufferDataTest, NULLResolvedData)
     glUseProgram(mProgram);
     glVertexAttribPointer(mAttribLocation, 1, GL_FLOAT, GL_FALSE, 4, nullptr);
     glEnableVertexAttribArray(mAttribLocation);
     glBindBuffer(GL_ARRAY_BUFFER, 0);
 
     drawQuad(mProgram, "position", 0.5f);
 }
 
-// Tests that a huge allocation returns GL_OUT_OF_MEMORY
-// TODO(jmadill): Figure out how to test this reliably on the Chromium bots
-TEST_P(BufferDataTest, DISABLED_HugeSetDataShouldNotCrash)
-{
-    glBindBuffer(GL_ARRAY_BUFFER, mBuffer);
-    EXPECT_GL_NO_ERROR();
-
-    GLsizei allocSize = std::numeric_limits<GLsizei>::max() >> 2;
-
-    uint8_t *data = nullptr;
-    while (data == nullptr && allocSize >= 4)
-    {
-        data = new (std::nothrow) uint8_t[allocSize];
-
-        if (data == nullptr)
-        {
-            allocSize >>= 1;
-        }
-    }
-
-    ASSERT_NE(static_cast<uint8_t *>(nullptr), data);
-    memset(data, 0, allocSize);
-
-    float * fValue = reinterpret_cast<float*>(data);
-    for (unsigned int f = 0; f < 6; f++)
-    {
-        fValue[f] = 1.0f;
-    }
-
-    glBufferData(GL_ARRAY_BUFFER, allocSize, data, GL_STATIC_DRAW);
-
-    GLenum error = glGetError();
-    if (error == GL_NO_ERROR)
-    {
-        // If we didn't fail because of an out of memory error, try drawing a quad
-        // using the large buffer
-
-        // DISABLED because it takes a long time, but left for posterity
-
-        //glUseProgram(mProgram);
-        // glVertexAttribPointer(mAttribLocation, 1, GL_FLOAT, GL_FALSE, 4, nullptr);
-        // glEnableVertexAttribArray(mAttribLocation);
-        // glBindBuffer(GL_ARRAY_BUFFER, 0);
-        // drawQuad(mProgram, "position", 0.5f);
-        // swapBuffers();
-
-        //// Draw operations can also generate out-of-memory, which is in-spec
-        //error = glGetError();
-        //if (error == GL_NO_ERROR)
-        //{
-        //    GLint viewportSize[4];
-        //    glGetIntegerv(GL_VIEWPORT, viewportSize);
-
-        //    GLint midPixelX = (viewportSize[0] + viewportSize[2]) / 2;
-        //    GLint midPixelY = (viewportSize[1] + viewportSize[3]) / 2;
-
-        //    EXPECT_PIXEL_EQ(midPixelX, midPixelY, 255, 0, 0, 255);
-        //}
-        //else
-        //{
-        //    EXPECT_EQ(GL_OUT_OF_MEMORY, error);
-        //}
-    }
-    else
-    {
-        EXPECT_GLENUM_EQ(GL_OUT_OF_MEMORY, error);
-    }
-
-    delete[] data;
-}
-
 // Internally in D3D, we promote dynamic data to static after many draw loops. This code tests
 // path.
 TEST_P(BufferDataTest, RepeatedDrawWithDynamic)
 {
     std::vector<GLfloat> data;
     for (int i = 0; i < 16; ++i)
     {
         data.push_back(static_cast<GLfloat>(i));
@@ -470,16 +399,33 @@ TEST_P(BufferDataTest, MapBufferOES)
     ASSERT_GL_NO_ERROR();
     std::vector<uint8_t> actualData(data.size());
     memcpy(actualData.data(), readMapPtr, data.size());
     glUnmapBufferOES(GL_ARRAY_BUFFER);
 
     EXPECT_EQ(data, actualData);
 }
 
+// Tests a bug where copying buffer data immediately after creation hit a nullptr in D3D11.
+TEST_P(BufferDataTestES3, NoBufferInitDataCopyBug)
+{
+    constexpr GLsizei size = 64;
+
+    GLBuffer sourceBuffer;
+    glBindBuffer(GL_COPY_READ_BUFFER, sourceBuffer);
+    glBufferData(GL_COPY_READ_BUFFER, size, nullptr, GL_STATIC_DRAW);
+
+    GLBuffer destBuffer;
+    glBindBuffer(GL_ARRAY_BUFFER, destBuffer);
+    glBufferData(GL_ARRAY_BUFFER, size, nullptr, GL_STATIC_DRAW);
+
+    glCopyBufferSubData(GL_COPY_READ_BUFFER, GL_ARRAY_BUFFER, 0, 0, size);
+    ASSERT_GL_NO_ERROR();
+}
+
 // Use this to select which configurations (e.g. which renderer, which GLES major version) these tests should be run against.
 ANGLE_INSTANTIATE_TEST(BufferDataTest, ES2_D3D9(), ES2_D3D11(), ES2_OPENGL(), ES2_OPENGLES());
 ANGLE_INSTANTIATE_TEST(BufferDataTestES3, ES3_D3D11(), ES3_OPENGL(), ES3_OPENGLES());
 ANGLE_INSTANTIATE_TEST(IndexedBufferCopyTest, ES3_D3D11(), ES3_OPENGL(), ES3_OPENGLES());
 
 #ifdef _WIN64
 
 // Test a bug where an integer overflow bug could trigger a crash in D3D.
--- a/gfx/angle/src/tests/gl_tests/BuiltinVariableTest.cpp
+++ b/gfx/angle/src/tests/gl_tests/BuiltinVariableTest.cpp
@@ -3,16 +3,17 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 //
 // BuiltinVariableTest:
 //   Tests the correctness of the builtin GLSL variables.
 //
 
 #include "test_utils/ANGLETest.h"
+#include "test_utils/gl_raii.h"
 
 using namespace angle;
 
 class BuiltinVariableVertexIdTest : public ANGLETest
 {
   protected:
     BuiltinVariableVertexIdTest()
     {
@@ -199,11 +200,119 @@ TEST_P(BuiltinVariableVertexIdTest, Tria
     indices.push_back(1);
     indices.push_back(2);
     indices.push_back(1);
     indices.push_back(2);
     indices.push_back(3);
     runTest(GL_TRIANGLES, indices, 6);
 }
 
-// Use this to select which configurations (e.g. which renderer, which GLES major version) these
-// tests should be run against.
 ANGLE_INSTANTIATE_TEST(BuiltinVariableVertexIdTest, ES3_D3D11(), ES3_OPENGL(), ES3_OPENGLES());
+
+class BuiltinVariableFragDepthClampingFloatRBOTest : public ANGLETest
+{
+  protected:
+    void SetUp() override
+    {
+        ANGLETest::SetUp();
+
+        const std::string vs =
+            R"(#version 300 es
+            in vec4 a_position;
+            void main(){
+                gl_Position = a_position;
+            })";
+
+        // Writes a fixed detph value and green.
+        // Section 15.2.3 of the GL 4.5 specification says that conversion is not
+        // done but clamping is so the output depth should be in [0.0, 1.0]
+        const std::string depthFs =
+            R"(#version 300 es
+            precision highp float;
+            layout(location = 0) out vec4 fragColor;
+            uniform float u_depth;
+            void main(){
+                gl_FragDepth = u_depth;
+                fragColor = vec4(0.0, 1.0, 0.0, 1.0);
+            })";
+
+        mProgram = CompileProgram(vs, depthFs);
+        ASSERT_NE(0u, mProgram);
+
+        mDepthLocation = glGetUniformLocation(mProgram, "u_depth");
+        ASSERT_NE(-1, mDepthLocation);
+
+        glBindTexture(GL_TEXTURE_2D, mColorTexture);
+        glTexStorage2D(GL_TEXTURE_2D, 1, GL_RGBA8, 1, 1);
+        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
+        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
+
+        glBindTexture(GL_TEXTURE_2D, mDepthTexture);
+        glTexStorage2D(GL_TEXTURE_2D, 1, GL_DEPTH_COMPONENT32F, 1, 1);
+        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+
+        glBindFramebuffer(GL_FRAMEBUFFER, mFramebuffer);
+        glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, mColorTexture,
+                               0);
+        glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, mDepthTexture,
+                               0);
+
+        ASSERT_GLENUM_EQ(GL_FRAMEBUFFER_COMPLETE, glCheckFramebufferStatus(GL_FRAMEBUFFER));
+        ASSERT_GL_NO_ERROR();
+    }
+
+    void TearDown() override
+    {
+        glDeleteProgram(mProgram);
+
+        ANGLETest::TearDown();
+    }
+
+    void CheckDepthWritten(float expectedDepth, float fsDepth)
+    {
+        glBindFramebuffer(GL_FRAMEBUFFER, mFramebuffer);
+        glUseProgram(mProgram);
+
+        // Clear to red, the FS will write green on success
+        glClearColor(1.0f, 0.0f, 0.0f, 0.0f);
+        // Clear to the expected depth so it will be compared to the FS depth with
+        // DepthFunc(GL_EQUAL)
+        glClearDepthf(expectedDepth);
+        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
+
+        glUniform1f(mDepthLocation, fsDepth);
+        glDepthFunc(GL_EQUAL);
+        glEnable(GL_DEPTH_TEST);
+
+        drawQuad(mProgram, "a_position", 0.0f);
+        EXPECT_GL_NO_ERROR();
+
+        EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
+    }
+
+  private:
+    GLuint mProgram;
+    GLint mDepthLocation;
+
+    GLTexture mColorTexture;
+    GLTexture mDepthTexture;
+    GLFramebuffer mFramebuffer;
+};
+
+// Test that gl_FragDepth is clamped above 0
+TEST_P(BuiltinVariableFragDepthClampingFloatRBOTest, Above0)
+{
+    ANGLE_SKIP_TEST_IF(IsNVIDIA());
+    CheckDepthWritten(0.0f, -1.0f);
+}
+
+// Test that gl_FragDepth is clamped below 1
+TEST_P(BuiltinVariableFragDepthClampingFloatRBOTest, Below1)
+{
+    ANGLE_SKIP_TEST_IF(IsNVIDIA());
+    CheckDepthWritten(1.0f, 42.0f);
+}
+
+ANGLE_INSTANTIATE_TEST(BuiltinVariableFragDepthClampingFloatRBOTest,
+                       ES3_D3D11(),
+                       ES3_OPENGL(),
+                       ES3_OPENGLES());
--- a/gfx/angle/src/tests/gl_tests/ClearTest.cpp
+++ b/gfx/angle/src/tests/gl_tests/ClearTest.cpp
@@ -346,24 +346,16 @@ TEST_P(ClearTestES3, MixedSRGBClear)
 
 // This test covers a D3D11 bug where calling ClearRenderTargetView sometimes wouldn't sync
 // before a draw call. The test draws small quads to a larger FBO (the default back buffer).
 // Before each blit to the back buffer it clears the quad to a certain color using
 // ClearBufferfv to give a solid color. The sync problem goes away if we insert a call to
 // flush or finish after ClearBufferfv or each draw.
 TEST_P(ClearTestES3, RepeatedClear)
 {
-    if (IsD3D11() && IsIntel())
-    {
-        // Note that there's been a bug affecting this test on NVIDIA drivers as well, until fall
-        // 2016 driver releases.
-        std::cout << "Test skipped on Intel D3D11." << std::endl;
-        return;
-    }
-
     const std::string &vertexSource =
         "#version 300 es\n"
         "in highp vec2 position;\n"
         "out highp vec2 v_coord;\n"
         "void main(void)\n"
         "{\n"
         "    gl_Position = vec4(position, 0, 1);\n"
         "    vec2 texCoord = (position * 0.5) + 0.5;\n"
--- a/gfx/angle/src/tests/gl_tests/ClientArraysTest.cpp
+++ b/gfx/angle/src/tests/gl_tests/ClientArraysTest.cpp
@@ -46,17 +46,17 @@ TEST_P(ClientArraysTest, QueryValidation
     float floatValue = 2.0f;
     glGetFloatv(GL_CLIENT_ARRAYS_ANGLE, &floatValue);
     EXPECT_GL_NO_ERROR();
     EXPECT_EQ(0.0f, floatValue);
 
     GLboolean boolValue = GL_TRUE;
     glGetBooleanv(GL_CLIENT_ARRAYS_ANGLE, &boolValue);
     EXPECT_GL_NO_ERROR();
-    EXPECT_GL_FALSE(GL_FALSE);
+    EXPECT_GL_FALSE(boolValue);
 
     EXPECT_GL_FALSE(glIsEnabled(GL_CLIENT_ARRAYS_ANGLE));
     EXPECT_GL_NO_ERROR();
 
     glEnable(GL_CLIENT_ARRAYS_ANGLE);
     EXPECT_GL_ERROR(GL_INVALID_ENUM);
 
     glDisable(GL_CLIENT_ARRAYS_ANGLE);
--- a/gfx/angle/src/tests/gl_tests/ComputeShaderTest.cpp
+++ b/gfx/angle/src/tests/gl_tests/ComputeShaderTest.cpp
@@ -1,19 +1,19 @@
 //
 // 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.
 //
 // ComputeShaderTest:
 //   Compute shader specific tests.
 
+#include <vector>
 #include "test_utils/ANGLETest.h"
 #include "test_utils/gl_raii.h"
-#include <vector>
 
 using namespace angle;
 
 namespace
 {
 
 class ComputeShaderTest : public ANGLETest
 {
@@ -26,95 +26,127 @@ class ComputeShaderTestES3 : public ANGL
   protected:
     ComputeShaderTestES3() {}
 };
 
 // link a simple compute program. It should be successful.
 TEST_P(ComputeShaderTest, LinkComputeProgram)
 {
     const std::string csSource =
-        "#version 310 es\n"
-        "layout(local_size_x=1) in;\n"
-        "void main()\n"
-        "{\n"
-        "}\n";
+        R"(#version 310 es
+        layout(local_size_x=1) in;
+        void main()
+        {\
+        })";
 
     ANGLE_GL_COMPUTE_PROGRAM(program, csSource);
 
     EXPECT_GL_NO_ERROR();
 }
 
+// Link a simple compute program. Then detach the shader and dispatch compute.
+// It should be successful.
+TEST_P(ComputeShaderTest, DetachShaderAfterLinkSuccess)
+{
+    const std::string csSource =
+        R"(#version 310 es
+        layout(local_size_x=1) in;
+        void main()
+        {
+        })";
+
+    GLuint program = glCreateProgram();
+
+    GLuint cs = CompileShader(GL_COMPUTE_SHADER, csSource);
+    EXPECT_NE(0u, cs);
+
+    glAttachShader(program, cs);
+    glDeleteShader(cs);
+
+    glLinkProgram(program);
+    GLint linkStatus;
+    glGetProgramiv(program, GL_LINK_STATUS, &linkStatus);
+    EXPECT_GL_TRUE(linkStatus);
+
+    glDetachShader(program, cs);
+    EXPECT_GL_NO_ERROR();
+
+    glUseProgram(program);
+    glDispatchCompute(8, 4, 2);
+    EXPECT_GL_NO_ERROR();
+}
+
 // link a simple compute program. There is no local size and linking should fail.
 TEST_P(ComputeShaderTest, LinkComputeProgramNoLocalSizeLinkError)
 {
     const std::string csSource =
-        "#version 310 es\n"
-        "void main()\n"
-        "{\n"
-        "}\n";
+        R"(#version 310 es
+        void main()
+        {
+        })";
 
     GLuint program = CompileComputeProgram(csSource, false);
     EXPECT_EQ(0u, program);
 
     glDeleteProgram(program);
 
     EXPECT_GL_NO_ERROR();
 }
 
 // link a simple compute program.
 // make sure that uniforms and uniform samplers get recorded
 TEST_P(ComputeShaderTest, LinkComputeProgramWithUniforms)
 {
     const std::string csSource =
-        "#version 310 es\n"
-        "precision mediump sampler2D;\n"
-        "layout(local_size_x=1) in;\n"
-        "uniform int myUniformInt;\n"
-        "uniform sampler2D myUniformSampler;\n"
-        "void main()\n"
-        "{\n"
-        "int q = myUniformInt;\n"
-        "texture(myUniformSampler, vec2(0.0));\n"
-        "}\n";
+        R"(#version 310 es
+        precision mediump sampler2D;
+        layout(local_size_x=1) in;
+        uniform int myUniformInt;
+        uniform sampler2D myUniformSampler;
+        layout(rgba32i) uniform highp writeonly iimage2D imageOut;
+        void main()
+        {
+            int q = myUniformInt;
+            vec4 v = textureLod(myUniformSampler, vec2(0.0), 0.0);
+            imageStore(imageOut, ivec2(0), ivec4(v) * q);
+        })";
 
     ANGLE_GL_COMPUTE_PROGRAM(program, csSource);
 
-    // It's not possible to validate uniforms are present since they are unreferenced.
-    // TODO(jmadill): Make uniforms referenced.
-    // GLint uniformLoc = glGetUniformLocation(program.get(), "myUniformInt");
-    // EXPECT_NE(-1, uniformLoc);
+    GLint uniformLoc = glGetUniformLocation(program.get(), "myUniformInt");
+    EXPECT_NE(-1, uniformLoc);
 
-    // uniformLoc = glGetUniformLocation(program.get(), "myUniformSampler");
-    // EXPECT_NE(-1, uniformLoc);
+    uniformLoc = glGetUniformLocation(program.get(), "myUniformSampler");
+    EXPECT_NE(-1, uniformLoc);
 
     EXPECT_GL_NO_ERROR();
 }
 
 // Attach both compute and non-compute shaders. A link time error should occur.
 // OpenGL ES 3.10, 7.3 Program Objects
 TEST_P(ComputeShaderTest, AttachMultipleShaders)
 {
     const std::string csSource =
-        "#version 310 es\n"
-        "layout(local_size_x=1) in;\n"
-        "void main()\n"
-        "{\n"
-        "}\n";
+        R"(#version 310 es
+        layout(local_size_x=1) in;
+        void main()
+        {
+        })";
 
     const std::string vsSource =
-        "#version 310 es\n"
-        "void main()\n"
-        "{\n"
-        "}\n";
+        R"(#version 310 es
+        void main()
+        {
+        })";
 
     const std::string fsSource =
-        "#version 310 es\n"
-        "void main()\n"
-        "{\n"
-        "}\n";
+        R"(#version 310 es
+        void main()
+        {
+        })";
 
     GLuint program = glCreateProgram();
 
     GLuint vs = CompileShader(GL_VERTEX_SHADER, vsSource);
     GLuint fs = CompileShader(GL_FRAGMENT_SHADER, fsSource);
     GLuint cs = CompileShader(GL_COMPUTE_SHADER, csSource);
 
     EXPECT_NE(0u, vs);
@@ -130,43 +162,43 @@ TEST_P(ComputeShaderTest, AttachMultiple
     glAttachShader(program, cs);
     glDeleteShader(cs);
 
     glLinkProgram(program);
 
     GLint linkStatus;
     glGetProgramiv(program, GL_LINK_STATUS, &linkStatus);
 
-    EXPECT_EQ(0, linkStatus);
+    EXPECT_GL_FALSE(linkStatus);
 
     EXPECT_GL_NO_ERROR();
 }
 
 // Attach a vertex, fragment and compute shader.
 // Query for the number of attached shaders and check the count.
 TEST_P(ComputeShaderTest, AttachmentCount)
 {
     const std::string csSource =
-        "#version 310 es\n"
-        "layout(local_size_x=1) in;\n"
-        "void main()\n"
-        "{\n"
-        "}\n";
+        R"(#version 310 es
+        layout(local_size_x=1) in;
+        void main()
+        {
+        })";
 
     const std::string vsSource =
-        "#version 310 es\n"
-        "void main()\n"
-        "{\n"
-        "}\n";
+        R"(#version 310 es
+        void main()
+        {
+        })";
 
     const std::string fsSource =
-        "#version 310 es\n"
-        "void main()\n"
-        "{\n"
-        "}\n";
+        R"(#version 310 es
+        void main()
+        {
+        })";
 
     GLuint program = glCreateProgram();
 
     GLuint vs = CompileShader(GL_VERTEX_SHADER, vsSource);
     GLuint fs = CompileShader(GL_FRAGMENT_SHADER, fsSource);
     GLuint cs = CompileShader(GL_COMPUTE_SHADER, csSource);
 
     EXPECT_NE(0u, vs);
@@ -187,87 +219,151 @@ TEST_P(ComputeShaderTest, AttachmentCoun
 
     EXPECT_EQ(3, numAttachedShaders);
 
     glDeleteProgram(program);
 
     EXPECT_GL_NO_ERROR();
 }
 
+// Attach a compute shader and link, but start rendering.
+TEST_P(ComputeShaderTest, StartRenderingWithComputeProgram)
+{
+    const std::string csSource =
+        R"(#version 310 es
+        layout(local_size_x=1) in;
+        void main()
+        {
+        })";
+
+    ANGLE_GL_COMPUTE_PROGRAM(program, csSource);
+    EXPECT_GL_NO_ERROR();
+
+    glUseProgram(program);
+    glDrawArrays(GL_POINTS, 0, 2);
+    EXPECT_GL_ERROR(GL_INVALID_OPERATION);
+}
+
+// Attach a vertex and fragment shader and link, but dispatch compute.
+TEST_P(ComputeShaderTest, DispatchComputeWithRenderingProgram)
+{
+    const std::string vsSource =
+        R"(#version 310 es
+        void main()
+        {
+        })";
+
+    const std::string fsSource =
+        R"(#version 310 es
+        void main()
+        {
+        })";
+
+    GLuint program = glCreateProgram();
+
+    GLuint vs = CompileShader(GL_VERTEX_SHADER, vsSource);
+    GLuint fs = CompileShader(GL_FRAGMENT_SHADER, fsSource);
+
+    EXPECT_NE(0u, vs);
+    EXPECT_NE(0u, fs);
+
+    glAttachShader(program, vs);
+    glDeleteShader(vs);
+
+    glAttachShader(program, fs);
+    glDeleteShader(fs);
+
+    glLinkProgram(program);
+
+    GLint linkStatus;
+    glGetProgramiv(program, GL_LINK_STATUS, &linkStatus);
+    EXPECT_GL_TRUE(linkStatus);
+
+    EXPECT_GL_NO_ERROR();
+
+    glUseProgram(program);
+    glDispatchCompute(8, 4, 2);
+    EXPECT_GL_ERROR(GL_INVALID_OPERATION);
+}
+
 // Access all compute shader special variables.
 TEST_P(ComputeShaderTest, AccessAllSpecialVariables)
 {
     const std::string csSource =
-        "#version 310 es\n"
-        "layout(local_size_x=4, local_size_y=3, local_size_z=2) in;\n"
-        "void main()\n"
-        "{\n"
-        "    uvec3 temp1 = gl_NumWorkGroups;\n"
-        "    uvec3 temp2 = gl_WorkGroupSize;\n"
-        "    uvec3 temp3 = gl_WorkGroupID;\n"
-        "    uvec3 temp4 = gl_LocalInvocationID;\n"
-        "    uvec3 temp5 = gl_GlobalInvocationID;\n"
-        "    uint  temp6 = gl_LocalInvocationIndex;\n"
-        "}\n";
+        R"(#version 310 es
+        layout(local_size_x=4, local_size_y=3, local_size_z=2) in;
+        layout(rgba32ui) uniform highp writeonly uimage2D imageOut;
+        void main()
+        {
+            uvec3 temp1 = gl_NumWorkGroups;
+            uvec3 temp2 = gl_WorkGroupSize;
+            uvec3 temp3 = gl_WorkGroupID;
+            uvec3 temp4 = gl_LocalInvocationID;
+            uvec3 temp5 = gl_GlobalInvocationID;
+            uint  temp6 = gl_LocalInvocationIndex;
+            imageStore(imageOut, ivec2(gl_LocalInvocationIndex, 0), uvec4(temp1 + temp2 + temp3 + temp4 + temp5, temp6));
+        })";
 
     ANGLE_GL_COMPUTE_PROGRAM(program, csSource);
 }
 
 // Access part compute shader special variables.
 TEST_P(ComputeShaderTest, AccessPartSpecialVariables)
 {
     const std::string csSource =
-        "#version 310 es\n"
-        "layout(local_size_x=4, local_size_y=3, local_size_z=2) in;\n"
-        "void main()\n"
-        "{\n"
-        "    uvec3 temp1 = gl_WorkGroupSize;\n"
-        "    uvec3 temp2 = gl_WorkGroupID;\n"
-        "    uint  temp3 = gl_LocalInvocationIndex;\n"
-        "}\n";
+        R"(#version 310 es
+        layout(local_size_x=4, local_size_y=3, local_size_z=2) in;
+        layout(rgba32ui) uniform highp writeonly uimage2D imageOut;
+        void main()
+        {
+            uvec3 temp1 = gl_WorkGroupSize;
+            uvec3 temp2 = gl_WorkGroupID;
+            uint  temp3 = gl_LocalInvocationIndex;
+            imageStore(imageOut, ivec2(gl_LocalInvocationIndex, 0), uvec4(temp1 + temp2, temp3));
+        })";
 
     ANGLE_GL_COMPUTE_PROGRAM(program, csSource);
 }
 
 // Use glDispatchCompute to define work group count.
 TEST_P(ComputeShaderTest, DispatchCompute)
 {
     const std::string csSource =
-        "#version 310 es\n"
-        "layout(local_size_x=4, local_size_y=3, local_size_z=2) in;\n"
-        "void main()\n"
-        "{\n"
-        "    uvec3 temp = gl_NumWorkGroups;\n"
-        "}\n";
+        R"(#version 310 es
+        layout(local_size_x=4, local_size_y=3, local_size_z=2) in;
+        layout(rgba32ui) uniform highp writeonly uimage2D imageOut;
+        void main()
+        {
+            uvec3 temp = gl_NumWorkGroups;
+            imageStore(imageOut, ivec2(0), uvec4(temp, 0u));
+        })";
 
     ANGLE_GL_COMPUTE_PROGRAM(program, csSource);
 
     glUseProgram(program.get());
     glDispatchCompute(8, 4, 2);
     EXPECT_GL_NO_ERROR();
 }
 
 // Use image uniform to write texture in compute shader, and verify the content is expected.
 TEST_P(ComputeShaderTest, BindImageTexture)
 {
-    ANGLE_SKIP_TEST_IF(IsD3D11());
-
     GLTexture mTexture[2];
     GLFramebuffer mFramebuffer;
     const std::string csSource =
-        "#version 310 es\n"
-        "layout(local_size_x=2, local_size_y=2, local_size_z=1) in;\n"
-        "layout(r32ui, binding = 0) writeonly uniform highp uimage2D uImage[2];"
-        "void main()\n"
-        "{\n"
-        "    imageStore(uImage[0], ivec2(gl_LocalInvocationIndex, gl_WorkGroupID.x), uvec4(100, 0, "
-        "0, 0));"
-        "    imageStore(uImage[1], ivec2(gl_LocalInvocationIndex, gl_WorkGroupID.x), uvec4(100, 0, "
-        "0, 0));"
-        "}\n";
+        R"(#version 310 es
+        layout(local_size_x=2, local_size_y=2, local_size_z=1) in;
+        layout(r32ui, binding = 0) writeonly uniform highp uimage2D uImage[2];
+        void main()
+        {
+            imageStore(uImage[0], ivec2(gl_LocalInvocationIndex, gl_WorkGroupID.x), uvec4(100, 0,
+        0, 0));
+            imageStore(uImage[1], ivec2(gl_LocalInvocationIndex, gl_WorkGroupID.x), uvec4(100, 0,
+        0, 0));
+        })";
 
     ANGLE_GL_COMPUTE_PROGRAM(program, csSource);
     glUseProgram(program.get());
     int width = 4, height = 2;
     GLuint inputValues[] = {200, 200, 200, 200, 200, 200, 200, 200};
 
     glBindTexture(GL_TEXTURE_2D, mTexture[0]);
     glTexStorage2D(GL_TEXTURE_2D, 1, GL_R32UI, width, height);
@@ -321,24 +417,24 @@ TEST_P(ComputeShaderTest, ImageArrayWith
 
     // TODO(xinghua.cao@intel.com): On AMD desktop OpenGL, bind two image variables to unit 0,
     // only one variable is valid.
     ANGLE_SKIP_TEST_IF(IsAMD() && IsDesktopOpenGL());
 
     GLTexture mTexture;
     GLFramebuffer mFramebuffer;
     const std::string csSource =
-        "#version 310 es\n"
-        "layout(local_size_x=2, local_size_y=2, local_size_z=1) in;\n"
-        "layout(r32ui) writeonly uniform highp uimage2D uImage[2];"
-        "void main()\n"
-        "{\n"
-        "    imageStore(uImage[0], ivec2(gl_LocalInvocationIndex, 0), uvec4(100, 0, 0, 0));"
-        "    imageStore(uImage[1], ivec2(gl_LocalInvocationIndex, 1), uvec4(100, 0, 0, 0));"
-        "}\n";
+        R"(#version 310 es
+        layout(local_size_x=2, local_size_y=2, local_size_z=1) in;
+        layout(r32ui) writeonly uniform highp uimage2D uImage[2];
+        void main()
+        {
+            imageStore(uImage[0], ivec2(gl_LocalInvocationIndex, 0), uvec4(100, 0, 0, 0));
+            imageStore(uImage[1], ivec2(gl_LocalInvocationIndex, 1), uvec4(100, 0, 0, 0));
+        })";
 
     ANGLE_GL_COMPUTE_PROGRAM(program, csSource);
     glUseProgram(program.get());
     constexpr int kTextureWidth = 4, kTextureHeight = 2;
     GLuint inputValues[] = {200, 200, 200, 200, 200, 200, 200, 200};
 
     glBindTexture(GL_TEXTURE_2D, mTexture);
     glTexStorage2D(GL_TEXTURE_2D, 1, GL_R32UI, kTextureWidth, kTextureHeight);
@@ -361,16 +457,482 @@ TEST_P(ComputeShaderTest, ImageArrayWith
 
     GLuint expectedValue = 100;
     for (int i = 0; i < kTextureWidth * kTextureHeight; i++)
     {
         EXPECT_EQ(expectedValue, outputValues[i]);
     }
 }
 
+// imageLoad functions
+TEST_P(ComputeShaderTest, ImageLoad)
+{
+    const std::string csSource =
+        R"(#version 310 es
+        layout(local_size_x=8) in;
+        layout(rgba8) uniform highp readonly image2D mImage2DInput;
+        layout(rgba16i) uniform highp readonly iimageCube mImageCubeInput;
+        layout(rgba32ui) uniform highp readonly uimage3D mImage3DInput;
+        layout(r32i) uniform highp writeonly iimage2D imageOut;
+        void main()
+        {
+            vec4 result2d = imageLoad(mImage2DInput, ivec2(gl_LocalInvocationID.xy));
+            ivec4 resultCube = imageLoad(mImageCubeInput, ivec3(gl_LocalInvocationID.xyz));
+            uvec4 result3d = imageLoad(mImage3DInput, ivec3(gl_LocalInvocationID.xyz));
+            imageStore(imageOut, ivec2(gl_LocalInvocationIndex, 0), ivec4(result2d) + resultCube + ivec4(result3d));
+        })";
+
+    ANGLE_GL_COMPUTE_PROGRAM(program, csSource);
+    EXPECT_GL_NO_ERROR();
+}
+
+// imageStore functions
+TEST_P(ComputeShaderTest, ImageStore)
+{
+    const std::string csSource =
+        R"(#version 310 es
+        layout(local_size_x=8) in;
+        layout(rgba16f) uniform highp writeonly imageCube mImageCubeOutput;
+        layout(r32f) uniform highp writeonly image3D mImage3DOutput;
+        layout(rgba8ui) uniform highp writeonly uimage2DArray mImage2DArrayOutput;
+        void main()
+        {
+            imageStore(mImageCubeOutput, ivec3(gl_LocalInvocationID.xyz), vec4(0.0));
+            imageStore(mImage3DOutput, ivec3(gl_LocalInvocationID.xyz), vec4(0.0));
+            imageStore(mImage2DArrayOutput, ivec3(gl_LocalInvocationID.xyz), uvec4(0));
+        })";
+
+    ANGLE_GL_COMPUTE_PROGRAM(program, csSource);
+    EXPECT_GL_NO_ERROR();
+}
+
+// imageSize functions
+TEST_P(ComputeShaderTest, ImageSize)
+{
+    const std::string csSource =
+        R"(#version 310 es
+        layout(local_size_x=8) in;
+        layout(rgba8) uniform highp readonly imageCube mImageCubeInput;
+        layout(r32i) uniform highp readonly iimage2D mImage2DInput;
+        layout(rgba16ui) uniform highp readonly uimage2DArray mImage2DArrayInput;
+        layout(r32i) uniform highp writeonly iimage2D imageOut;
+        void main()
+        {
+            ivec2 sizeCube = imageSize(mImageCubeInput);
+            ivec2 size2D = imageSize(mImage2DInput);
+            ivec3 size2DArray = imageSize(mImage2DArrayInput);
+            imageStore(imageOut, ivec2(gl_LocalInvocationIndex, 0), ivec4(sizeCube, size2D.x, size2DArray.x));
+        })";
+
+    ANGLE_GL_COMPUTE_PROGRAM(program, csSource);
+    EXPECT_GL_NO_ERROR();
+}
+
+// Use image uniform to read and write Texture2D in compute shader, and verify the contents.
+TEST_P(ComputeShaderTest, BindImageTextureWithTexture2D)
+{
+    GLTexture texture[2];
+    GLFramebuffer framebuffer;
+    const std::string csSource =
+        R"(#version 310 es
+        layout(local_size_x=4, local_size_y=2, local_size_z=1) in;
+        layout(r32ui, binding = 0) readonly uniform highp uimage2D uImage_1;
+        layout(r32ui, binding = 1) writeonly uniform highp uimage2D uImage_2;
+        void main()
+        {
+            uvec4 value = imageLoad(uImage_1, ivec2(gl_LocalInvocationID.xy));
+            imageStore(uImage_2, ivec2(gl_LocalInvocationID.xy), value);
+        })";
+
+    constexpr int kWidth = 4, kHeight = 2;
+    constexpr GLuint kInputValues[2][8] = {{200, 200, 200, 200, 200, 200, 200, 200},
+                                           {100, 100, 100, 100, 100, 100, 100, 100}};
+
+    glBindTexture(GL_TEXTURE_2D, texture[0]);
+    glTexStorage2D(GL_TEXTURE_2D, 1, GL_R32UI, kWidth, kHeight);
+    glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, kWidth, kHeight, GL_RED_INTEGER, GL_UNSIGNED_INT,
+                    kInputValues[0]);
+    EXPECT_GL_NO_ERROR();
+
+    glBindTexture(GL_TEXTURE_2D, texture[1]);
+    glTexStorage2D(GL_TEXTURE_2D, 1, GL_R32UI, kWidth, kHeight);
+    glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, kWidth, kHeight, GL_RED_INTEGER, GL_UNSIGNED_INT,
+                    kInputValues[1]);
+    EXPECT_GL_NO_ERROR();
+
+    glUseProgram(0);
+    GLuint outputValues[8];
+    constexpr GLuint expectedValue_1 = 200;
+    constexpr GLuint expectedValue_2 = 100;
+    glBindFramebuffer(GL_READ_FRAMEBUFFER, framebuffer);
+
+    glFramebufferTexture2D(GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture[0], 0);
+    EXPECT_GL_NO_ERROR();
+    glReadPixels(0, 0, kWidth, kHeight, GL_RED_INTEGER, GL_UNSIGNED_INT, outputValues);
+
+    for (int i = 0; i < kWidth * kHeight; i++)
+    {
+        EXPECT_EQ(expectedValue_1, outputValues[i]);
+    }
+
+    glFramebufferTexture2D(GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture[1], 0);
+    EXPECT_GL_NO_ERROR();
+    glReadPixels(0, 0, kWidth, kHeight, GL_RED_INTEGER, GL_UNSIGNED_INT, outputValues);
+
+    for (int i = 0; i < kWidth * kHeight; i++)
+    {
+        EXPECT_EQ(expectedValue_2, outputValues[i]);
+    }
+
+    ANGLE_GL_COMPUTE_PROGRAM(program, csSource);
+    glUseProgram(program.get());
+
+    glBindImageTexture(0, texture[0], 0, GL_FALSE, 0, GL_READ_ONLY, GL_R32UI);
+    EXPECT_GL_NO_ERROR();
+
+    glBindImageTexture(1, texture[1], 0, GL_FALSE, 0, GL_WRITE_ONLY, GL_R32UI);
+    EXPECT_GL_NO_ERROR();
+
+    glDispatchCompute(1, 1, 1);
+    EXPECT_GL_NO_ERROR();
+
+    glUseProgram(0);
+    glBindFramebuffer(GL_READ_FRAMEBUFFER, framebuffer);
+
+    glFramebufferTexture2D(GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture[1], 0);
+    EXPECT_GL_NO_ERROR();
+    glReadPixels(0, 0, kWidth, kHeight, GL_RED_INTEGER, GL_UNSIGNED_INT, outputValues);
+    EXPECT_GL_NO_ERROR();
+
+    for (int i = 0; i < kWidth * kHeight; i++)
+    {
+        EXPECT_EQ(expectedValue_1, outputValues[i]);
+    }
+}
+
+// Use image uniform to read and write Texture2DArray in compute shader, and verify the contents.
+TEST_P(ComputeShaderTest, BindImageTextureWithTexture2DArray)
+{
+    GLTexture texture[2];
+    GLFramebuffer framebuffer;
+    const std::string csSource =
+        R"(#version 310 es
+        layout(local_size_x=2, local_size_y=2, local_size_z=2) in;
+        layout(r32ui, binding = 0) readonly uniform highp uimage2DArray uImage_1;
+        layout(r32ui, binding = 1) writeonly uniform highp uimage2DArray uImage_2;
+        void main()
+        {
+            uvec4 value = imageLoad(uImage_1, ivec3(gl_LocalInvocationID.xyz));
+            imageStore(uImage_2, ivec3(gl_LocalInvocationID.xyz), value);
+        })";
+
+    constexpr int kWidth = 2, kHeight = 2, kDepth = 2;
+    constexpr GLuint kInputValues[2][8] = {{200, 200, 200, 200, 200, 200, 200, 200},
+                                           {100, 100, 100, 100, 100, 100, 100, 100}};
+
+    glBindTexture(GL_TEXTURE_2D_ARRAY, texture[0]);
+    glTexStorage3D(GL_TEXTURE_2D_ARRAY, 1, GL_R32UI, kWidth, kHeight, kDepth);
+    glTexSubImage3D(GL_TEXTURE_2D_ARRAY, 0, 0, 0, 0, kWidth, kHeight, kDepth, GL_RED_INTEGER,
+                    GL_UNSIGNED_INT, kInputValues[0]);
+    EXPECT_GL_NO_ERROR();
+
+    glBindTexture(GL_TEXTURE_2D_ARRAY, texture[1]);
+    glTexStorage3D(GL_TEXTURE_2D_ARRAY, 1, GL_R32UI, kWidth, kHeight, kDepth);
+    glTexSubImage3D(GL_TEXTURE_2D_ARRAY, 0, 0, 0, 0, kWidth, kHeight, kDepth, GL_RED_INTEGER,
+                    GL_UNSIGNED_INT, kInputValues[1]);
+    EXPECT_GL_NO_ERROR();
+
+    glUseProgram(0);
+    GLuint outputValues[4];
+    constexpr GLuint expectedValue_1 = 200;
+    constexpr GLuint expectedValue_2 = 100;
+    glBindFramebuffer(GL_READ_FRAMEBUFFER, framebuffer);
+
+    glFramebufferTextureLayer(GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, texture[0], 0, 0);
+    glFramebufferTextureLayer(GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT1, texture[0], 0, 1);
+    EXPECT_GL_NO_ERROR();
+
+    glReadBuffer(GL_COLOR_ATTACHMENT0);
+    glReadPixels(0, 0, kWidth, kHeight, GL_RED_INTEGER, GL_UNSIGNED_INT, outputValues);
+    for (int i = 0; i < kWidth * kHeight; i++)
+    {
+        EXPECT_EQ(expectedValue_1, outputValues[i]);
+    }
+
+    glReadBuffer(GL_COLOR_ATTACHMENT1);
+    glReadPixels(0, 0, kWidth, kHeight, GL_RED_INTEGER, GL_UNSIGNED_INT, outputValues);
+
+    for (int i = 0; i < kWidth * kHeight; i++)
+    {
+        EXPECT_EQ(expectedValue_1, outputValues[i]);
+    }
+
+    glFramebufferTextureLayer(GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, texture[1], 0, 0);
+    glFramebufferTextureLayer(GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT1, texture[1], 0, 1);
+    EXPECT_GL_NO_ERROR();
+
+    glReadBuffer(GL_COLOR_ATTACHMENT0);
+    glReadPixels(0, 0, kWidth, kHeight, GL_RED_INTEGER, GL_UNSIGNED_INT, outputValues);
+    for (int i = 0; i < kWidth * kHeight; i++)
+    {
+        EXPECT_EQ(expectedValue_2, outputValues[i]);
+    }
+
+    glReadBuffer(GL_COLOR_ATTACHMENT1);
+    glReadPixels(0, 0, kWidth, kHeight, GL_RED_INTEGER, GL_UNSIGNED_INT, outputValues);
+    for (int i = 0; i < kWidth * kHeight; i++)
+    {
+        EXPECT_EQ(expectedValue_2, outputValues[i]);
+    }
+
+    ANGLE_GL_COMPUTE_PROGRAM(program, csSource);
+    glUseProgram(program.get());
+
+    glBindImageTexture(0, texture[0], 0, GL_TRUE, 0, GL_READ_ONLY, GL_R32UI);
+    EXPECT_GL_NO_ERROR();
+
+    glBindImageTexture(1, texture[1], 0, GL_TRUE, 0, GL_WRITE_ONLY, GL_R32UI);
+    EXPECT_GL_NO_ERROR();
+
+    glDispatchCompute(1, 1, 1);
+    EXPECT_GL_NO_ERROR();
+
+    glUseProgram(0);
+    glBindFramebuffer(GL_READ_FRAMEBUFFER, framebuffer);
+
+    glFramebufferTextureLayer(GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, texture[1], 0, 0);
+    glFramebufferTextureLayer(GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT1, texture[1], 0, 1);
+    EXPECT_GL_NO_ERROR();
+    glReadBuffer(GL_COLOR_ATTACHMENT0);
+    glReadPixels(0, 0, kWidth, kHeight, GL_RED_INTEGER, GL_UNSIGNED_INT, outputValues);
+    EXPECT_GL_NO_ERROR();
+    for (int i = 0; i < kWidth * kHeight; i++)
+    {
+        EXPECT_EQ(expectedValue_1, outputValues[i]);
+    }
+    glReadBuffer(GL_COLOR_ATTACHMENT1);
+    glReadPixels(0, 0, kWidth, kHeight, GL_RED_INTEGER, GL_UNSIGNED_INT, outputValues);
+    EXPECT_GL_NO_ERROR();
+    for (int i = 0; i < kWidth * kHeight; i++)
+    {
+        EXPECT_EQ(expectedValue_1, outputValues[i]);
+    }
+}
+
+// Use image uniform to read and write Texture3D in compute shader, and verify the contents.
+TEST_P(ComputeShaderTest, BindImageTextureWithTexture3D)
+{
+    GLTexture texture[2];
+    GLFramebuffer framebuffer;
+    const std::string csSource =
+        R"(#version 310 es
+        layout(local_size_x=2, local_size_y=2, local_size_z=2) in;
+        layout(r32ui, binding = 0) readonly uniform highp uimage3D uImage_1;
+        layout(r32ui, binding = 1) writeonly uniform highp uimage3D uImage_2;
+        void main()
+        {
+            uvec4 value = imageLoad(uImage_1, ivec3(gl_LocalInvocationID.xyz));
+            imageStore(uImage_2, ivec3(gl_LocalInvocationID.xyz), value);
+        })";
+
+    constexpr int kWidth = 2, kHeight = 2, kDepth = 2;
+    constexpr GLuint kInputValues[2][8] = {{200, 200, 200, 200, 200, 200, 200, 200},
+                                           {100, 100, 100, 100, 100, 100, 100, 100}};
+
+    glBindTexture(GL_TEXTURE_3D, texture[0]);
+    glTexStorage3D(GL_TEXTURE_3D, 1, GL_R32UI, kWidth, kHeight, kDepth);
+    glTexSubImage3D(GL_TEXTURE_3D, 0, 0, 0, 0, kWidth, kHeight, kDepth, GL_RED_INTEGER,
+                    GL_UNSIGNED_INT, kInputValues[0]);
+    EXPECT_GL_NO_ERROR();
+
+    glBindTexture(GL_TEXTURE_3D, texture[1]);
+    glTexStorage3D(GL_TEXTURE_3D, 1, GL_R32UI, kWidth, kHeight, kDepth);
+    glTexSubImage3D(GL_TEXTURE_3D, 0, 0, 0, 0, kWidth, kHeight, kDepth, GL_RED_INTEGER,
+                    GL_UNSIGNED_INT, kInputValues[1]);
+    EXPECT_GL_NO_ERROR();
+
+    glUseProgram(0);
+    GLuint outputValues[4];
+    constexpr GLuint expectedValue_1 = 200;
+    constexpr GLuint expectedValue_2 = 100;
+    glBindFramebuffer(GL_READ_FRAMEBUFFER, framebuffer);
+
+    glFramebufferTextureLayer(GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, texture[0], 0, 0);
+    glFramebufferTextureLayer(GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT1, texture[0], 0, 1);
+    EXPECT_GL_NO_ERROR();
+
+    glReadBuffer(GL_COLOR_ATTACHMENT0);
+    glReadPixels(0, 0, kWidth, kHeight, GL_RED_INTEGER, GL_UNSIGNED_INT, outputValues);
+    for (int i = 0; i < kWidth * kHeight; i++)
+    {
+        EXPECT_EQ(expectedValue_1, outputValues[i]);
+    }
+
+    glReadBuffer(GL_COLOR_ATTACHMENT1);
+    glReadPixels(0, 0, kWidth, kHeight, GL_RED_INTEGER, GL_UNSIGNED_INT, outputValues);
+
+    for (int i = 0; i < kWidth * kHeight; i++)
+    {
+        EXPECT_EQ(expectedValue_1, outputValues[i]);
+    }
+
+    glFramebufferTextureLayer(GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, texture[1], 0, 0);
+    glFramebufferTextureLayer(GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT1, texture[1], 0, 1);
+    EXPECT_GL_NO_ERROR();
+
+    glReadBuffer(GL_COLOR_ATTACHMENT0);
+    glReadPixels(0, 0, kWidth, kHeight, GL_RED_INTEGER, GL_UNSIGNED_INT, outputValues);
+    for (int i = 0; i < kWidth * kHeight; i++)
+    {
+        EXPECT_EQ(expectedValue_2, outputValues[i]);
+    }
+
+    glReadBuffer(GL_COLOR_ATTACHMENT1);
+    glReadPixels(0, 0, kWidth, kHeight, GL_RED_INTEGER, GL_UNSIGNED_INT, outputValues);
+    for (int i = 0; i < kWidth * kHeight; i++)
+    {
+        EXPECT_EQ(expectedValue_2, outputValues[i]);
+    }
+
+    ANGLE_GL_COMPUTE_PROGRAM(program, csSource);
+    glUseProgram(program.get());
+
+    glBindImageTexture(0, texture[0], 0, GL_TRUE, 0, GL_READ_ONLY, GL_R32UI);
+    EXPECT_GL_NO_ERROR();
+
+    glBindImageTexture(1, texture[1], 0, GL_TRUE, 0, GL_WRITE_ONLY, GL_R32UI);
+    EXPECT_GL_NO_ERROR();
+
+    glDispatchCompute(1, 1, 1);
+    EXPECT_GL_NO_ERROR();
+
+    glUseProgram(0);
+    glBindFramebuffer(GL_READ_FRAMEBUFFER, framebuffer);
+
+    glFramebufferTextureLayer(GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, texture[1], 0, 0);
+    glFramebufferTextureLayer(GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT1, texture[1], 0, 1);
+    EXPECT_GL_NO_ERROR();
+    glReadBuffer(GL_COLOR_ATTACHMENT0);
+    glReadPixels(0, 0, kWidth, kHeight, GL_RED_INTEGER, GL_UNSIGNED_INT, outputValues);
+    EXPECT_GL_NO_ERROR();
+    for (int i = 0; i < kWidth * kHeight; i++)
+    {
+        EXPECT_EQ(expectedValue_1, outputValues[i]);
+    }
+    glReadBuffer(GL_COLOR_ATTACHMENT1);
+    glReadPixels(0, 0, kWidth, kHeight, GL_RED_INTEGER, GL_UNSIGNED_INT, outputValues);
+    EXPECT_GL_NO_ERROR();
+    for (int i = 0; i < kWidth * kHeight; i++)
+    {
+        EXPECT_EQ(expectedValue_1, outputValues[i]);
+    }
+}
+
+// Use image uniform to read and write TextureCube in compute shader, and verify the contents.
+TEST_P(ComputeShaderTest, BindImageTextureWithTextureCube)
+{
+    GLTexture texture[2];
+    GLFramebuffer framebuffer;
+    const std::string csSource =
+        R"(#version 310 es
+        layout(local_size_x=2, local_size_y=2, local_size_z=1) in;
+        layout(r32ui, binding = 0) readonly uniform highp uimageCube uImage_1;
+        layout(r32ui, binding = 1) writeonly uniform highp uimageCube uImage_2;
+        void main()
+        {
+            for (int i = 0; i < 6; i++)
+            {
+                uvec4 value = imageLoad(uImage_1, ivec3(gl_LocalInvocationID.xy, i));
+                imageStore(uImage_2, ivec3(gl_LocalInvocationID.xy, i), value);
+            }
+        })";
+
+    constexpr int kWidth = 2, kHeight = 2;
+    constexpr GLuint kInputValues[2][4] = {{200, 200, 200, 200}, {100, 100, 100, 100}};
+
+    glBindTexture(GL_TEXTURE_CUBE_MAP, texture[0]);
+    glTexStorage2D(GL_TEXTURE_CUBE_MAP, 1, GL_R32UI, kWidth, kHeight);
+    for (GLenum face = GL_TEXTURE_CUBE_MAP_POSITIVE_X; face <= GL_TEXTURE_CUBE_MAP_NEGATIVE_Z;
+         face++)
+    {
+        glTexSubImage2D(face, 0, 0, 0, kWidth, kHeight, GL_RED_INTEGER, GL_UNSIGNED_INT,
+                        kInputValues[0]);
+    }
+    EXPECT_GL_NO_ERROR();
+
+    glBindTexture(GL_TEXTURE_CUBE_MAP, texture[1]);
+    glTexStorage2D(GL_TEXTURE_CUBE_MAP, 1, GL_R32UI, kWidth, kHeight);
+    for (GLenum face = GL_TEXTURE_CUBE_MAP_POSITIVE_X; face <= GL_TEXTURE_CUBE_MAP_NEGATIVE_Z;
+         face++)
+    {
+        glTexSubImage2D(face, 0, 0, 0, kWidth, kHeight, GL_RED_INTEGER, GL_UNSIGNED_INT,
+                        kInputValues[1]);
+    }
+    EXPECT_GL_NO_ERROR();
+
+    glUseProgram(0);
+    GLuint outputValues[4];
+    constexpr GLuint expectedValue_1 = 200;
+    constexpr GLuint expectedValue_2 = 100;
+    glBindFramebuffer(GL_READ_FRAMEBUFFER, framebuffer);
+    for (GLenum face = 0; face < 6; face++)
+    {
+        glFramebufferTexture2D(GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
+                               GL_TEXTURE_CUBE_MAP_POSITIVE_X + face, texture[0], 0);
+        EXPECT_GL_NO_ERROR();
+        glReadPixels(0, 0, kWidth, kHeight, GL_RED_INTEGER, GL_UNSIGNED_INT, outputValues);
+        EXPECT_GL_NO_ERROR();
+
+        for (int i = 0; i < kWidth * kHeight; i++)
+        {
+            EXPECT_EQ(expectedValue_1, outputValues[i]);
+        }
+
+        glFramebufferTexture2D(GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
+                               GL_TEXTURE_CUBE_MAP_POSITIVE_X + face, texture[1], 0);
+        EXPECT_GL_NO_ERROR();
+        glReadPixels(0, 0, kWidth, kHeight, GL_RED_INTEGER, GL_UNSIGNED_INT, outputValues);
+        EXPECT_GL_NO_ERROR();
+
+        for (int i = 0; i < kWidth * kHeight; i++)
+        {
+            EXPECT_EQ(expectedValue_2, outputValues[i]);
+        }
+    }
+
+    ANGLE_GL_COMPUTE_PROGRAM(program, csSource);
+    glUseProgram(program.get());
+
+    glBindImageTexture(0, texture[0], 0, GL_TRUE, 0, GL_READ_ONLY, GL_R32UI);
+    EXPECT_GL_NO_ERROR();
+
+    glBindImageTexture(1, texture[1], 0, GL_TRUE, 0, GL_WRITE_ONLY, GL_R32UI);
+    EXPECT_GL_NO_ERROR();
+
+    glDispatchCompute(1, 1, 1);
+    EXPECT_GL_NO_ERROR();
+
+    glUseProgram(0);
+    glBindFramebuffer(GL_READ_FRAMEBUFFER, framebuffer);
+
+    for (GLenum face = 0; face < 6; face++)
+    {
+        glFramebufferTexture2D(GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
+                               GL_TEXTURE_CUBE_MAP_POSITIVE_X + face, texture[1], 0);
+        EXPECT_GL_NO_ERROR();
+        glReadPixels(0, 0, kWidth, kHeight, GL_RED_INTEGER, GL_UNSIGNED_INT, outputValues);
+        EXPECT_GL_NO_ERROR();
+
+        for (int i = 0; i < kWidth * kHeight; i++)
+        {
+            EXPECT_EQ(expectedValue_1, outputValues[i]);
+        }
+    }
+}
+
 // Check that it is not possible to create a compute shader when the context does not support ES
 // 3.10
 TEST_P(ComputeShaderTestES3, NotSupported)
 {
     GLuint computeShaderHandle = glCreateShader(GL_COMPUTE_SHADER);
     EXPECT_EQ(0u, computeShaderHandle);
     EXPECT_GL_ERROR(GL_INVALID_ENUM);
 }
--- a/gfx/angle/src/tests/gl_tests/CopyTextureTest.cpp
+++ b/gfx/angle/src/tests/gl_tests/CopyTextureTest.cpp
@@ -251,20 +251,18 @@ TEST_P(CopyTextureTest, InternalFormat)
             EXPECT_GL_NO_ERROR();
         }
     }
 }
 
 // Test to ensure that the destination texture is redefined if the properties are different.
 TEST_P(CopyTextureTest, RedefineDestinationTexture)
 {
-    if (!checkExtensions())
-    {
-        return;
-    }
+    ANGLE_SKIP_TEST_IF(!checkExtensions());
+    ANGLE_SKIP_TEST_IF(!extensionEnabled("GL_EXT_texture_format_BGRA8888"));
 
     GLColor pixels[4] = {GLColor::red, GLColor::red, GLColor::red, GLColor::red};
 
     glBindTexture(GL_TEXTURE_2D, mTextures[0]);
     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE, pixels);
 
     glBindTexture(GL_TEXTURE_2D, mTextures[1]);
     glTexImage2D(GL_TEXTURE_2D, 0, GL_BGRA_EXT, 1, 1, 0, GL_BGRA_EXT, GL_UNSIGNED_BYTE, pixels);
@@ -392,16 +390,39 @@ TEST_P(CopyTextureTest, CopySubTextureIn
                              false);
     EXPECT_GL_ERROR(GL_INVALID_VALUE);
 
     glCopySubTextureCHROMIUM(mTextures[0], 0, GL_TEXTURE_2D, mTextures[1], 0, 1, 1, 0, 0, 1, 1,
                              false, false, false);
     EXPECT_GL_NO_ERROR();
 }
 
+TEST_P(CopyTextureTest, InvalidTarget)
+{
+    ANGLE_SKIP_TEST_IF(!checkExtensions());
+
+    GLTexture textures[2];
+
+    glBindTexture(GL_TEXTURE_2D, textures[0]);
+    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
+
+    glBindTexture(GL_TEXTURE_2D, textures[1]);
+    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 3, 3, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
+
+    // Invalid enum for a completely invalid target
+    glCopySubTextureCHROMIUM(textures[0], 0, GL_INVALID_VALUE, textures[1], 0, 1, 1, 0, 0, 1, 1,
+                             false, false, false);
+    EXPECT_GL_ERROR(GL_INVALID_ENUM);
+
+    // Invalid value for a valid target enum but is not valid for the destination texture
+    glCopySubTextureCHROMIUM(textures[0], 0, GL_TEXTURE_CUBE_MAP_POSITIVE_X, textures[1], 0, 1, 1,
+                             0, 0, 1, 1, false, false, false);
+    EXPECT_GL_ERROR(GL_INVALID_VALUE);
+}
+
 // Test that using an offset in CopySubTexture works correctly
 TEST_P(CopyTextureTest, CopySubTextureOffset)
 {
     if (!checkExtensions())
     {
         return;
     }
 
@@ -1000,16 +1021,45 @@ TEST_P(CopyTextureTestDest, AlphaUnmulti
     glCopyTextureCHROMIUM(mTextures[0], 0, GL_TEXTURE_2D, mTextures[1], 0, GL_RGBA,
                           GL_UNSIGNED_BYTE, false, false, false);
 
     EXPECT_GL_NO_ERROR();
 
     EXPECT_PIXEL_COLOR_EQ(0, 0, expectedPixels);
 }
 
+// Test to ensure that CopyTexture uses the correct ALPHA passthrough shader to ensure RGB channels
+// are set to 0.
+TEST_P(CopyTextureTestDest, AlphaCopyWithRGB)
+{
+    ANGLE_SKIP_TEST_IF(!checkExtensions());
+
+    GLColor originalPixels(50u, 100u, 150u, 155u);
+    GLColor expectedPixels(0u, 0u, 0u, 155u);
+
+    // ReadPixels doesn't work with ALPHA (non-renderable), so we copy again back to an RGBA
+    // texture to verify contents.
+    glBindTexture(GL_TEXTURE_2D, mTextures[1]);
+    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, &originalPixels);
+    glBindTexture(GL_TEXTURE_2D, mTextures[0]);
+    glTexImage2D(GL_TEXTURE_2D, 0, GL_ALPHA, 1, 1, 0, GL_ALPHA, GL_HALF_FLOAT_OES, nullptr);
+
+    glCopyTextureCHROMIUM(mTextures[1], 0, GL_TEXTURE_2D, mTextures[0], 0, GL_ALPHA,
+                          GL_HALF_FLOAT_OES, false, false, false);
+
+    EXPECT_GL_NO_ERROR();
+
+    glCopyTextureCHROMIUM(mTextures[0], 0, GL_TEXTURE_2D, mTextures[1], 0, GL_RGBA,
+                          GL_UNSIGNED_BYTE, false, false, false);
+
+    EXPECT_GL_NO_ERROR();
+
+    EXPECT_PIXEL_COLOR_EQ(0, 0, expectedPixels);
+}
+
 // Test the newly added ES3 unorm formats
 TEST_P(CopyTextureTestES3, ES3UnormFormats)
 {
     if (!checkExtensions())
     {
         return;
     }
 
--- a/gfx/angle/src/tests/gl_tests/CubeMapTextureTest.cpp
+++ b/gfx/angle/src/tests/gl_tests/CubeMapTextureTest.cpp
@@ -126,13 +126,14 @@ TEST_P(CubeMapTextureTest, RenderToFaces
     glDeleteTextures(1, &tex);
 
     EXPECT_GL_NO_ERROR();
 }
 
 // Use this to select which configurations (e.g. which renderer, which GLES major version) these tests should be run against.
 ANGLE_INSTANTIATE_TEST(CubeMapTextureTest,
                        ES2_D3D11(),
+                       ES2_D3D11_FL10_0(),
                        ES2_D3D11_FL9_3(),
                        ES2_OPENGL(),
                        ES3_OPENGL(),
                        ES2_OPENGLES(),
                        ES3_OPENGLES());
--- a/gfx/angle/src/tests/gl_tests/D3D11EmulatedIndexedBufferTest.cpp
+++ b/gfx/angle/src/tests/gl_tests/D3D11EmulatedIndexedBufferTest.cpp
@@ -32,18 +32,18 @@ class D3D11EmulatedIndexedBufferTest : p
         ASSERT_EQ(EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE, GetParam().getRenderer());
 
         mContext                 = reinterpret_cast<gl::Context *>(getEGLWindow()->getContext());
         rx::Context11 *context11 = rx::GetImplAs<rx::Context11>(mContext);
         mRenderer                = context11->getRenderer();
 
         mSourceBuffer      = new rx::Buffer11(mBufferState, mRenderer);
         GLfloat testData[] = { 1.0f, 2.0f, 3.0f, 4.0f, 5.0f, 6.0f };
-        gl::Error error    = mSourceBuffer->setData(nullptr, GL_ARRAY_BUFFER, testData,
-                                                 sizeof(testData), GL_STATIC_DRAW);
+        gl::Error error    = mSourceBuffer->setData(nullptr, gl::BufferBinding::Array, testData,
+                                                 sizeof(testData), gl::BufferUsage::StaticDraw);
         ASSERT_FALSE(error.isError());
 
         mTranslatedAttribute.baseOffset            = 0;
         mTranslatedAttribute.usesFirstVertexOffset = false;
         mTranslatedAttribute.stride = sizeof(GLfloat);
 
         GLubyte indices[] = {0, 0, 3, 4, 2, 1, 1};
 
--- a/gfx/angle/src/tests/gl_tests/D3D11FormatTablesTest.cpp
+++ b/gfx/angle/src/tests/gl_tests/D3D11FormatTablesTest.cpp
@@ -65,86 +65,91 @@ TEST_P(D3D11FormatTablesTest, TestFormat
             {
                 texSupportMask |= D3D11_FORMAT_SUPPORT_TEXTURE3D;
             }
         }
 
         UINT texSupport  = 0;
         bool texSuccess  = SUCCEEDED(device->CheckFormatSupport(formatInfo.texFormat, &texSupport));
         bool textureable = texSuccess && ((texSupport & texSupportMask) == texSupportMask);
-        EXPECT_EQ(textureable, textureInfo.texturable);
+        EXPECT_EQ(textureable, textureInfo.texturable) << "for 0x" << std::hex << internalFormat;
 
         // Bits for mipmap auto-gen.
         bool expectedMipGen = texSuccess && ((texSupport & D3D11_FORMAT_SUPPORT_MIP_AUTOGEN) != 0);
         auto featureLevel   = renderer->getRenderer11DeviceCaps().featureLevel;
         const auto &dxgiSupport = rx::d3d11::GetDXGISupport(formatInfo.texFormat, featureLevel);
         bool actualMipGen =
             ((dxgiSupport.alwaysSupportedFlags & D3D11_FORMAT_SUPPORT_MIP_AUTOGEN) != 0);
-        EXPECT_EQ(0u, dxgiSupport.optionallySupportedFlags & D3D11_FORMAT_SUPPORT_MIP_AUTOGEN);
-        EXPECT_EQ(expectedMipGen, actualMipGen);
+        EXPECT_EQ(0u, dxgiSupport.optionallySupportedFlags & D3D11_FORMAT_SUPPORT_MIP_AUTOGEN)
+            << "for 0x" << std::hex << internalFormat;
+        EXPECT_EQ(expectedMipGen, actualMipGen) << "for 0x" << std::hex << internalFormat;
 
         // Bits for filtering
         UINT filterSupport = 0;
         bool filterSuccess =
             SUCCEEDED(device->CheckFormatSupport(formatInfo.srvFormat, &filterSupport));
         bool filterable = filterSuccess && ((filterSupport & D3D11_FORMAT_SUPPORT_SHADER_SAMPLE) != 0);
-        EXPECT_EQ(filterable, textureInfo.filterable);
+        EXPECT_EQ(filterable, textureInfo.filterable) << "for 0x" << std::hex << internalFormat;
 
         // Bits for renderable
         bool renderable = false;
         UINT renderSupport       = 0u;
         DXGI_FORMAT renderFormat = DXGI_FORMAT_UNKNOWN;
         if (internalFormatInfo.depthBits > 0 || internalFormatInfo.stencilBits > 0)
         {
             renderFormat = formatInfo.dsvFormat;
             bool depthSuccess =
                 SUCCEEDED(device->CheckFormatSupport(formatInfo.dsvFormat, &renderSupport));
             renderable =
                 depthSuccess && ((renderSupport & D3D11_FORMAT_SUPPORT_DEPTH_STENCIL) != 0);
             if (renderable)
             {
-                EXPECT_NE(DXGI_FORMAT_UNKNOWN, formatInfo.dsvFormat);
+                EXPECT_NE(DXGI_FORMAT_UNKNOWN, formatInfo.dsvFormat)
+                    << "for 0x" << std::hex << internalFormat;
             }
         }
         else
         {
             renderFormat = formatInfo.rtvFormat;
             bool rtSuccess =
                 SUCCEEDED(device->CheckFormatSupport(formatInfo.rtvFormat, &renderSupport));
             renderable = rtSuccess && ((renderSupport & D3D11_FORMAT_SUPPORT_RENDER_TARGET) != 0);
             if (renderable)
             {
-                EXPECT_NE(DXGI_FORMAT_UNKNOWN, formatInfo.rtvFormat);
+                EXPECT_NE(DXGI_FORMAT_UNKNOWN, formatInfo.rtvFormat)
+                    << "for 0x" << std::hex << internalFormat;
             }
         }
-        EXPECT_EQ(renderable, textureInfo.renderable);
+        EXPECT_EQ(renderable, textureInfo.renderable) << "for 0x" << std::hex << internalFormat;
         if (!textureInfo.sampleCounts.empty())
         {
-            EXPECT_TRUE(renderable);
+            EXPECT_TRUE(renderable) << "for 0x" << std::hex << internalFormat;
         }
 
         // Multisample counts
         if (renderable)
         {
             if ((renderSupport & D3D11_FORMAT_SUPPORT_MULTISAMPLE_RENDERTARGET) != 0)
             {
                 EXPECT_TRUE(!textureInfo.sampleCounts.empty());
                 for (unsigned int sampleCount = 1;
                      sampleCount <= D3D11_MAX_MULTISAMPLE_SAMPLE_COUNT; sampleCount *= 2)
                 {
                     UINT qualityCount  = 0;
                     bool sampleSuccess = SUCCEEDED(device->CheckMultisampleQualityLevels(
                         renderFormat, sampleCount, &qualityCount));
                     GLuint expectedCount = (!sampleSuccess || qualityCount == 0) ? 0 : 1;
-                    EXPECT_EQ(expectedCount, textureInfo.sampleCounts.count(sampleCount));
+                    EXPECT_EQ(expectedCount, textureInfo.sampleCounts.count(sampleCount))
+                        << "for 0x" << std::hex << internalFormat;
                 }
             }
             else
             {
-                EXPECT_TRUE(textureInfo.sampleCounts.empty());
+                EXPECT_TRUE(textureInfo.sampleCounts.empty())
+                    << "for 0x" << std::hex << internalFormat;
             }
         }
     }
 }
 
 ANGLE_INSTANTIATE_TEST(D3D11FormatTablesTest,
                        ES2_D3D11_FL9_3(),
                        ES2_D3D11_FL10_0(),
--- a/gfx/angle/src/tests/gl_tests/D3DImageFormatConversionTest.cpp
+++ b/gfx/angle/src/tests/gl_tests/D3DImageFormatConversionTest.cpp
@@ -117,85 +117,40 @@ class D3DImageFormatConversionTest : pub
 
     GLuint m2DProgram;
     GLint mTexture2DUniformLocation;
 };
 
 // Validation test for rx::R4G4B4A4's writeColor functions
 TEST_P(D3DImageFormatConversionTest, WriteColorFunctionR4G4B4A4)
 {
-    // These tests fail on certain Intel machines running an un-updated version of Win7
-    // The tests pass after installing the latest updates from Windows Update.
-    // TODO: reenable these tests once the bots have been updated
-    if (IsIntel() && getPlatformRenderer() == EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE)
-    {
-        std::cout << "Test skipped on Intel D3D11." << std::endl;
-        return;
-    }
-
     runTest<R4G4B4A4>(GL_RGBA, GL_UNSIGNED_SHORT_4_4_4_4);
 }
 
 // Validation test for rx::R5G5B5A1's writeColor functions
 TEST_P(D3DImageFormatConversionTest, WriteColorFunctionR5G5B5A1)
 {
-    // These tests fail on certain Intel machines running an un-updated version of Win7
-    // The tests pass after installing the latest updates from Windows Update.
-    // TODO: reenable these tests once the bots have been updated
-    if (IsIntel() && getPlatformRenderer() == EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE)
-    {
-        std::cout << "Test skipped on Intel D3D11." << std::endl;
-        return;
-    }
-
     runTest<R5G5B5A1>(GL_RGBA, GL_UNSIGNED_SHORT_5_5_5_1);
 }
 
 // Validation test for rx::R5G6B5's writeColor functions
 TEST_P(D3DImageFormatConversionTest, WriteColorFunctionR5G6B5)
 {
-    // These tests fail on certain Intel machines running an un-updated version of Win7
-    // The tests pass after installing the latest updates from Windows Update.
-    // TODO: reenable these tests once the bots have been updated
-    if (IsIntel() && getPlatformRenderer() == EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE)
-    {
-        std::cout << "Test skipped on Intel D3D11." << std::endl;
-        return;
-    }
-
     runTest<R5G6B5>(GL_RGB, GL_UNSIGNED_SHORT_5_6_5);
 }
 
 // Validation test for rx::R8G8B8A8's writeColor functions
 TEST_P(D3DImageFormatConversionTest, WriteColorFunctionR8G8B8A8)
 {
-    // These tests fail on certain Intel machines running an un-updated version of Win7
-    // The tests pass after installing the latest updates from Windows Update.
-    // TODO: reenable these tests once the bots have been updated
-    if (IsIntel() && getPlatformRenderer() == EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE)
-    {
-        std::cout << "Test skipped on Intel D3D11." << std::endl;
-        return;
-    }
-
     runTest<R8G8B8A8>(GL_RGBA, GL_UNSIGNED_BYTE);
 }
 
 // Validation test for rx::R8G8B8's writeColor functions
 TEST_P(D3DImageFormatConversionTest, WriteColorFunctionR8G8B8)
 {
-    // These tests fail on certain Intel machines running an un-updated version of Win7
-    // The tests pass after installing the latest updates from Windows Update.
-    // TODO: reenable these tests once the bots have been updated
-    if (IsIntel() && getPlatformRenderer() == EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE)
-    {
-        std::cout << "Test skipped on Intel D3D11." << std::endl;
-        return;
-    }
-
     glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
     runTest<R8G8B8>(GL_RGB, GL_UNSIGNED_BYTE);
 }
 
 // Use this to select which configurations (e.g. which renderer, which GLES major version) these tests should be run against.
 // Even though this test is only run on Windows (since it includes imageformats.h from the D3D renderer), we can still run the test
 // against OpenGL. This is valuable, since it provides extra validation using a renderer that doesn't use imageformats.h itself.
 ANGLE_INSTANTIATE_TEST(D3DImageFormatConversionTest, ES2_D3D9(), ES2_D3D11(), ES2_D3D11_FL9_3(), ES2_OPENGL());
--- a/gfx/angle/src/tests/gl_tests/D3DTextureTest.cpp
+++ b/gfx/angle/src/tests/gl_tests/D3DTextureTest.cpp
@@ -145,31 +145,32 @@ class D3DTextureTest : public ANGLETest
     }
 
     EGLSurface createD3D11PBuffer(size_t width,
                                   size_t height,
                                   EGLint eglTextureFormat,
                                   EGLint eglTextureTarget,
                                   UINT sampleCount,
                                   UINT sampleQuality,
-                                  UINT bindFlags)
+                                  UINT bindFlags,
+                                  DXGI_FORMAT format)
     {
         EGLWindow *window  = getEGLWindow();
         EGLDisplay display = window->getDisplay();
         EGLConfig config   = window->getConfig();
 
         EGLint attribs[] = {
             EGL_TEXTURE_FORMAT, eglTextureFormat, EGL_TEXTURE_TARGET,
             eglTextureTarget,   EGL_NONE,         EGL_NONE,
         };
 
         ASSERT(mD3D11Device);
         ID3D11Texture2D *texture = nullptr;
-        CD3D11_TEXTURE2D_DESC desc(DXGI_FORMAT_R8G8B8A8_UNORM, static_cast<UINT>(width),
-                                   static_cast<UINT>(height), 1, 1, bindFlags);
+        CD3D11_TEXTURE2D_DESC desc(format, static_cast<UINT>(width), static_cast<UINT>(height), 1,
+                                   1, bindFlags);
         desc.SampleDesc.Count   = sampleCount;
         desc.SampleDesc.Quality = sampleQuality;
         EXPECT_TRUE(SUCCEEDED(mD3D11Device->CreateTexture2D(&desc, nullptr, &texture)));
 
         EGLSurface pbuffer = eglCreatePbufferFromClientBuffer(display, EGL_D3D_TEXTURE_ANGLE,
                                                               texture, config, attribs);
 
         texture->Release();
@@ -181,19 +182,19 @@ class D3DTextureTest : public ANGLETest
                              size_t height,
                              EGLint eglTextureFormat,
                              EGLint eglTextureTarget,
                              UINT sampleCount,
                              UINT sampleQuality)
     {
         if (mD3D11Device)
         {
-            return createD3D11PBuffer(width, height, eglTextureFormat, eglTextureTarget,
-                                      sampleCount, sampleQuality,
-                                      D3D11_BIND_SHADER_RESOURCE | D3D11_BIND_RENDER_TARGET);
+            return createD3D11PBuffer(
+                width, height, eglTextureFormat, eglTextureTarget, sampleCount, sampleQuality,
+                D3D11_BIND_SHADER_RESOURCE | D3D11_BIND_RENDER_TARGET, DXGI_FORMAT_R8G8B8A8_UNORM);
         }
 
         if (mD3D9Device)
         {
             EGLWindow *window  = getEGLWindow();
             EGLDisplay display = window->getDisplay();
             EGLConfig config   = window->getConfig();
 
@@ -260,16 +261,78 @@ class D3DTextureTest : public ANGLETest
     GLint mTextureUniformLocation;
 
     HMODULE mD3D11Module       = nullptr;
     ID3D11Device *mD3D11Device = nullptr;
 
     IDirect3DDevice9 *mD3D9Device = nullptr;
 };
 
+// Test creating pbuffer from textures with several
+// different DXGI formats.
+TEST_P(D3DTextureTest, TestD3D11SupportedFormats)
+{
+    ANGLE_SKIP_TEST_IF(!valid() || !IsD3D11());
+
+    const DXGI_FORMAT formats[] = {DXGI_FORMAT_R8G8B8A8_UNORM, DXGI_FORMAT_R8G8B8A8_UNORM_SRGB,
+                                   DXGI_FORMAT_B8G8R8A8_UNORM, DXGI_FORMAT_B8G8R8A8_UNORM_SRGB};
+    for (size_t i = 0; i < 4; ++i)
+    {
+        EGLSurface pbuffer = createD3D11PBuffer(32, 32, EGL_TEXTURE_RGBA, EGL_TEXTURE_2D, 1, 0,
+                                                D3D11_BIND_RENDER_TARGET, formats[i]);
+        ASSERT_EGL_SUCCESS();
+        ASSERT_NE(pbuffer, EGL_NO_SURFACE);
+
+        EGLWindow *window  = getEGLWindow();
+        EGLDisplay display = window->getDisplay();
+        eglMakeCurrent(display, pbuffer, pbuffer, window->getContext());
+        ASSERT_EGL_SUCCESS();
+
+        window->makeCurrent();
+        eglDestroySurface(display, pbuffer);
+    }
+}
+
+// Test creating a pbuffer with unnecessary EGL_WIDTH and EGL_HEIGHT attributes because that's what
+// Chromium does. This is a regression test for crbug.com/794086
+TEST_P(D3DTextureTest, UnnecessaryWidthHeightAttributes)
+{
+    ANGLE_SKIP_TEST_IF(!valid() || !IsD3D11());
+    ASSERT(mD3D11Device);
+    ID3D11Texture2D *texture = nullptr;
+    CD3D11_TEXTURE2D_DESC desc(DXGI_FORMAT_R8G8B8A8_UNORM, 1, 1, 1, 1, D3D11_BIND_RENDER_TARGET);
+    desc.SampleDesc.Count   = 1;
+    desc.SampleDesc.Quality = 0;
+    EXPECT_TRUE(SUCCEEDED(mD3D11Device->CreateTexture2D(&desc, nullptr, &texture)));
+
+    EGLint attribs[] = {
+        EGL_TEXTURE_FORMAT, EGL_TEXTURE_RGBA,
+        EGL_TEXTURE_TARGET, EGL_TEXTURE_2D,
+        EGL_WIDTH,          1,
+        EGL_HEIGHT,         1,
+        EGL_NONE,           EGL_NONE,
+    };
+
+    EGLWindow *window  = getEGLWindow();
+    EGLDisplay display = window->getDisplay();
+    EGLConfig config   = window->getConfig();
+
+    EGLSurface pbuffer =
+        eglCreatePbufferFromClientBuffer(display, EGL_D3D_TEXTURE_ANGLE, texture, config, attribs);
+
+    ASSERT_EGL_SUCCESS();
+    ASSERT_NE(pbuffer, EGL_NO_SURFACE);
+
+    texture->Release();
+
+    // Make current with fixture EGL to ensure the Surface can be released immediately.
+    getEGLWindow()->makeCurrent();
+    eglDestroySurface(display, pbuffer);
+}
+
 // Test creating a pbuffer from a d3d surface and clearing it
 TEST_P(D3DTextureTest, Clear)
 {
     if (!valid())
     {
         return;
     }
 
@@ -444,18 +507,19 @@ TEST_P(D3DTextureTest, CheckSampleMismat
 
 // Tests what happens when we make a PBuffer that isn't shader-readable.
 TEST_P(D3DTextureTest, NonReadablePBuffer)
 {
     ANGLE_SKIP_TEST_IF(!valid() || !IsD3D11());
 
     constexpr size_t bufferSize = 32;
 
-    EGLSurface pbuffer = createD3D11PBuffer(bufferSize, bufferSize, EGL_TEXTURE_RGBA,
-                                            EGL_TEXTURE_2D, 1, 0, D3D11_BIND_RENDER_TARGET);
+    EGLSurface pbuffer =
+        createD3D11PBuffer(bufferSize, bufferSize, EGL_TEXTURE_RGBA, EGL_TEXTURE_2D, 1, 0,
+                           D3D11_BIND_RENDER_TARGET, DXGI_FORMAT_R8G8B8A8_UNORM);
 
     ASSERT_EGL_SUCCESS();
     ASSERT_NE(pbuffer, EGL_NO_SURFACE);
 
     EGLWindow *window  = getEGLWindow();
     EGLDisplay display = window->getDisplay();
 
     eglMakeCurrent(display, pbuffer, pbuffer, window->getContext());
--- a/gfx/angle/src/tests/gl_tests/DXT1CompressedTextureTest.cpp
+++ b/gfx/angle/src/tests/gl_tests/DXT1CompressedTextureTest.cpp
@@ -187,16 +187,41 @@ TEST_P(DXT1CompressedTextureTest, Compre
     glCompressedTexImage2D(GL_TEXTURE_2D, 0, GL_COMPRESSED_RGBA_S3TC_DXT1_EXT, pixel_0_width,
                            pixel_0_height, 0, pixel_0_size, nullptr);
     ASSERT_GL_NO_ERROR();
 
     // Set a sub image with an offset that isn't a multiple of the block size
     glCompressedTexSubImage2D(GL_TEXTURE_2D, 0, 1, 3, pixel_1_width, pixel_1_height,
                               GL_COMPRESSED_RGBA_S3TC_DXT1_EXT, pixel_1_size, pixel_1_data);
     ASSERT_GL_ERROR(GL_INVALID_OPERATION);
+
+    // Set a sub image with a negative offset
+    glCompressedTexSubImage2D(GL_TEXTURE_2D, 0, -1, 0, 4, 4, GL_COMPRESSED_RGBA_S3TC_DXT1_EXT, 8,
+                              pixel_1_data);
+    ASSERT_GL_ERROR(GL_INVALID_VALUE);
+
+    glCompressedTexSubImage2D(GL_TEXTURE_2D, 0, 0, -1, 4, 4, GL_COMPRESSED_RGBA_S3TC_DXT1_EXT, 8,
+                              pixel_1_data);
+    ASSERT_GL_ERROR(GL_INVALID_VALUE);
+}
+
+// Test that it's not possible to call CopyTexSubImage2D on a compressed texture
+TEST_P(DXT1CompressedTextureTest, CopyTexSubImage2DDisallowed)
+{
+    ANGLE_SKIP_TEST_IF(!extensionEnabled("GL_EXT_texture_compression_dxt1"));
+
+    GLTexture texture;
+    glBindTexture(GL_TEXTURE_2D, texture.get());
+
+    glCompressedTexImage2D(GL_TEXTURE_2D, 0, GL_COMPRESSED_RGBA_S3TC_DXT1_EXT, pixel_0_width,
+                           pixel_0_height, 0, pixel_0_size, nullptr);
+    ASSERT_GL_NO_ERROR();
+
+    glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 0, 4, 4);
+    ASSERT_GL_ERROR(GL_INVALID_OPERATION);
 }
 
 class DXT1CompressedTextureTestES3 : public DXT1CompressedTextureTest { };
 
 class DXT1CompressedTextureTestD3D11 : public DXT1CompressedTextureTest { };
 
 TEST_P(DXT1CompressedTextureTestES3, PBOCompressedTexImage)
 {
@@ -262,16 +287,42 @@ TEST_P(DXT1CompressedTextureTestES3, PBO
     EXPECT_GL_NO_ERROR();
 
     glDeleteTextures(1, &buffer);
     glDeleteTextures(1, &texture);
 
     EXPECT_GL_NO_ERROR();
 }
 
+// Test validation of glCompressedTexSubImage3D with DXT formats
+TEST_P(DXT1CompressedTextureTestES3, CompressedTexSubImageValidation)
+{
+    ANGLE_SKIP_TEST_IF(!extensionEnabled("GL_EXT_texture_compression_dxt1"));
+
+    GLTexture texture;
+    glBindTexture(GL_TEXTURE_2D_ARRAY, texture.get());
+
+    // Size mip 0 to a large size
+    glCompressedTexImage3D(GL_TEXTURE_2D_ARRAY, 0, GL_COMPRESSED_RGBA_S3TC_DXT1_EXT, pixel_0_width,
+                           pixel_0_height, 1, 0, pixel_0_size, nullptr);
+    ASSERT_GL_NO_ERROR();
+
+    // Set a sub image with a negative offset
+    glCompressedTexSubImage3D(GL_TEXTURE_2D_ARRAY, 0, -1, 0, 0, 4, 4, 1,
+                              GL_COMPRESSED_RGBA_S3TC_DXT1_EXT, 8, pixel_1_data);
+    ASSERT_GL_ERROR(GL_INVALID_VALUE);
+
+    glCompressedTexSubImage3D(GL_TEXTURE_2D_ARRAY, 0, 0, -1, 0, 4, 4, 1,
+                              GL_COMPRESSED_RGBA_S3TC_DXT1_EXT, 8, pixel_1_data);
+    ASSERT_GL_ERROR(GL_INVALID_VALUE);
+
+    glCompressedTexSubImage3D(GL_TEXTURE_2D_ARRAY, 0, 0, 0, -1, 4, 4, 1,
+                              GL_COMPRESSED_RGBA_S3TC_DXT1_EXT, 8, pixel_1_data);
+    ASSERT_GL_ERROR(GL_INVALID_VALUE);
+}
 
 TEST_P(DXT1CompressedTextureTestD3D11, PBOCompressedTexStorage)
 {
     if (getClientMajorVersion() < 3 && !extensionEnabled("GL_EXT_texture_compression_dxt1"))
     {
         return;
     }
 
@@ -345,16 +396,33 @@ TEST_P(DXT1CompressedTextureTestD3D11, P
 
     EXPECT_GL_NO_ERROR();
 
     glDeleteTextures(1, &texture);
 
     EXPECT_GL_NO_ERROR();
 }
 
+// Test validation of glCompressedTexSubImage3D with DXT formats
+TEST_P(DXT1CompressedTextureTestES3, CopyTexSubImage3DDisallowed)
+{
+    ANGLE_SKIP_TEST_IF(!extensionEnabled("GL_EXT_texture_compression_dxt1"));
+
+    GLTexture texture;
+    glBindTexture(GL_TEXTURE_2D_ARRAY, texture.get());
+
+    GLsizei depth = 4;
+    glCompressedTexImage3D(GL_TEXTURE_2D_ARRAY, 0, GL_COMPRESSED_RGBA_S3TC_DXT1_EXT, pixel_0_width,
+                           pixel_0_height, depth, 0, pixel_0_size * depth, nullptr);
+    ASSERT_GL_NO_ERROR();
+
+    glCopyTexSubImage3D(GL_TEXTURE_2D_ARRAY, 0, 0, 0, 0, 0, 0, 4, 4);
+    ASSERT_GL_ERROR(GL_INVALID_OPERATION);
+}
+
 // Use this to select which configurations (e.g. which renderer, which GLES major version) these tests should be run against.
 ANGLE_INSTANTIATE_TEST(DXT1CompressedTextureTest,
                        ES2_D3D9(),
                        ES2_D3D11(),
                        ES2_D3D11_FL9_3(),
                        ES2_OPENGL(),
                        ES3_OPENGL(),
                        ES2_OPENGLES(),
--- a/gfx/angle/src/tests/gl_tests/FenceSyncTests.cpp
+++ b/gfx/angle/src/tests/gl_tests/FenceSyncTests.cpp
@@ -46,52 +46,52 @@ TEST_P(FenceNVTest, IsFence)
         std::cout << "Test skipped due to missing GL_NV_fence extension." << std::endl;
         return;
     }
 
     GLuint fence = 0;
     glGenFencesNV(1, &fence);
     EXPECT_GL_NO_ERROR();
 
-    EXPECT_EQ(GL_FALSE, glIsFenceNV(fence));
+    EXPECT_GL_FALSE(glIsFenceNV(fence));
     EXPECT_GL_NO_ERROR();
 
     glSetFenceNV(fence, GL_ALL_COMPLETED_NV);
     EXPECT_GL_NO_ERROR();
 
-    EXPECT_EQ(GL_TRUE, glIsFenceNV(fence));
+    EXPECT_GL_TRUE(glIsFenceNV(fence));
     EXPECT_GL_NO_ERROR();
 }
 
 // Test error cases for all FenceNV functions
 TEST_P(FenceNVTest, Errors)
 {
     if (!extensionEnabled("GL_NV_fence"))
     {
         std::cout << "Test skipped due to missing GL_NV_fence extension." << std::endl;
         return;
     }
 
-    // glTestFenceNV should still return TRUE for an invalid fence and generate an INVALID_OPERATION
-    EXPECT_EQ(GL_TRUE, glTestFenceNV(10));
+    EXPECT_GL_TRUE(glTestFenceNV(10)) << "glTestFenceNV should still return TRUE for an invalid "
+                                         "fence and generate an INVALID_OPERATION";
     EXPECT_GL_ERROR(GL_INVALID_OPERATION);
 
     GLuint fence = 20;
 
     // glGenFencesNV should generate INVALID_VALUE for a negative n and not write anything to the fences pointer
     glGenFencesNV(-1, &fence);
     EXPECT_GL_ERROR(GL_INVALID_VALUE);
     EXPECT_EQ(20u, fence);
 
     // Generate a real fence
     glGenFencesNV(1, &fence);
     EXPECT_GL_NO_ERROR();
 
-    // glTestFenceNV should still return TRUE for a fence that is not started and generate an INVALID_OPERATION
-    EXPECT_EQ(GL_TRUE, glTestFenceNV(fence));
+    EXPECT_GL_TRUE(glTestFenceNV(fence)) << "glTestFenceNV should still return TRUE for a fence "
+                                            "that is not started and generate an INVALID_OPERATION";
     EXPECT_GL_ERROR(GL_INVALID_OPERATION);
 
     // glGetFenceivNV should generate an INVALID_OPERATION for an invalid or unstarted fence and not modify the params
     GLint result = 30;
     glGetFenceivNV(10, GL_FENCE_STATUS_NV, &result);
     EXPECT_GL_ERROR(GL_INVALID_OPERATION);
     EXPECT_EQ(30, result);
 
@@ -134,30 +134,30 @@ TEST_P(FenceNVTest, BasicOperations)
 
     for (GLuint fence : fences)
     {
         GLint status = 0;
         glGetFenceivNV(fence, GL_FENCE_STATUS_NV, &status);
         EXPECT_GL_NO_ERROR();
 
         // Fence should be complete now that Finish has been called
-        EXPECT_EQ(GL_TRUE, status);
+        EXPECT_GL_TRUE(status);
     }
 
     EXPECT_PIXEL_EQ(0, 0, 255, 0, 255, 255);
 }
 
 // Sync objects should respond true to IsSync after they are created with glFenceSync
 TEST_P(FenceSyncTest, IsSync)
 {
     GLsync sync = glFenceSync(GL_SYNC_GPU_COMMANDS_COMPLETE, 0);
     EXPECT_GL_NO_ERROR();
 
-    EXPECT_EQ(GL_TRUE, glIsSync(sync));
-    EXPECT_EQ(GL_FALSE, glIsSync(reinterpret_cast<GLsync>(40)));
+    EXPECT_GL_TRUE(glIsSync(sync));
+    EXPECT_GL_FALSE(glIsSync(reinterpret_cast<GLsync>(40)));
 }
 
 // Test error cases for all Sync function
 TEST_P(FenceSyncTest, Errors)
 {
     GLsync sync = glFenceSync(GL_SYNC_GPU_COMMANDS_COMPLETE, 0);
 
     // DeleteSync generates INVALID_VALUE when the sync is not valid
--- a/gfx/angle/src/tests/gl_tests/FramebufferTest.cpp
+++ b/gfx/angle/src/tests/gl_tests/FramebufferTest.cpp
@@ -2,16 +2,17 @@
 // Copyright 2015 The ANGLE Project Authors. All rights reserved.
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 //
 // Framebuffer tests:
 //   Various tests related for Frambuffers.
 //
 
+#include "platform/WorkaroundsD3D.h"
 #include "test_utils/ANGLETest.h"
 #include "test_utils/gl_raii.h"
 
 using namespace angle;
 
 namespace
 {
 
@@ -512,16 +513,35 @@ TEST_P(FramebufferTest_ES3, MultisampleD
     EXPECT_GL_NO_ERROR();
 
     GLint samples = 0;
     glGetIntegerv(GL_SAMPLES, &samples);
     EXPECT_GL_NO_ERROR();
     EXPECT_GE(samples, 2);
 }
 
+// Check that we only compare width and height of attachments, not depth.
+TEST_P(FramebufferTest_ES3, AttachmentWith3DLayers)
+{
+    GLTexture texA;
+    glBindTexture(GL_TEXTURE_2D, texA);
+    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, 4, 4, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
+
+    GLTexture texB;
+    glBindTexture(GL_TEXTURE_3D, texB);
+    glTexImage3D(GL_TEXTURE_3D, 0, GL_RGBA8, 4, 4, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
+
+    GLFramebuffer framebuffer;
+    glBindFramebuffer(GL_FRAMEBUFFER, framebuffer);
+    glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texA, 0);
+    glFramebufferTextureLayer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT1, texB, 0, 0);
+    ASSERT_GLENUM_EQ(GL_FRAMEBUFFER_COMPLETE, glCheckFramebufferStatus(GL_FRAMEBUFFER));
+    EXPECT_GL_NO_ERROR();
+}
+
 ANGLE_INSTANTIATE_TEST(FramebufferTest_ES3, ES3_D3D11(), ES3_OPENGL(), ES3_OPENGLES());
 
 class FramebufferTest_ES31 : public ANGLETest
 {
   protected:
     void validateSamplePass(GLuint &query, GLuint &passedCount, GLint width, GLint height)
     {
         glUniform2i(0, width - 1, height - 1);
@@ -665,40 +685,62 @@ TEST_P(FramebufferTest_ES31, IncompleteM
     ASSERT_GL_NO_ERROR();
 }
 
 // If there are no attachments, rendering will be limited to a rectangle having a lower left of
 // (0, 0) and an upper right of(width, height), where width and height are the framebuffer
 // object's default width and height.
 TEST_P(FramebufferTest_ES31, RenderingLimitToDefaultFBOSizeWithNoAttachments)
 {
-    // TODO(yizhou): Investigate why this case fail on Intel GPU.
-    ANGLE_SKIP_TEST_IF(IsIntel() && IsD3D11());
+    // anglebug.com/2253
+    ANGLE_SKIP_TEST_IF(IsLinux() && IsAMD() && IsDesktopOpenGL());
+
+    const std::string &vertexShader1 =
+        R"(#version 310 es
+        in layout(location = 0) highp vec2 a_position;
+        void main()
+        {
+           gl_Position = vec4(a_position, 0.0, 1.0);
+        })";
+
+    const std::string &fragShader1 =
+        R"(#version 310 es
+        uniform layout(location = 0) highp ivec2 u_expectedSize;
+        out layout(location = 5) mediump vec4 f_color;
+        void main()
+        {
+           if (ivec2(gl_FragCoord.xy) != u_expectedSize) discard;
+           f_color = vec4(1.0, 0.5, 0.25, 1.0);
+        })";
 
-    const std::string &vertexShader =
-        "#version 310 es\n"
-        "in layout(location = 0) highp vec2 a_position;\n\n"
-        "void main()\n"
-        "{\n"
-        "	gl_Position = vec4(a_position, 0.0, 1.0);\n"
-        "}\n";
-    const std::string &fragShader =
-        "#version 310 es\n"
-        "uniform layout(location = 0) highp ivec2 u_expectedSize;\n"
-        "out layout(location = 0) mediump vec4 f_color;\n\n"
-        "void main()\n"
-        "{\n"
-        "	if (ivec2(gl_FragCoord.xy) != u_expectedSize) discard;\n"
-        "	f_color = vec4(1.0, 0.5, 0.25, 1.0);\n"
-        "}\n";
+    const std::string &vertexShader2 =
+        R"(#version 310 es
+        in layout(location = 0) highp vec2 a_position;
+        void main()
+        {
+           gl_Position = vec4(a_position, 0.0, 1.0);
+        })";
 
-    GLuint program = CompileProgram(vertexShader, fragShader);
-    ASSERT_NE(program, 0u);
+    const std::string &fragShader2 =
+        R"(#version 310 es
+        uniform layout(location = 0) highp ivec2 u_expectedSize;
+        out layout(location = 2) mediump vec4 f_color;
+        void main()
+        {
+           if (ivec2(gl_FragCoord.xy) != u_expectedSize) discard;
+           f_color = vec4(1.0, 0.5, 0.25, 1.0);
+        })";
 
-    glUseProgram(program);
+    GLuint program1 = CompileProgram(vertexShader1, fragShader1);
+    ASSERT_NE(program1, 0u);
+
+    GLuint program2 = CompileProgram(vertexShader2, fragShader2);
+    ASSERT_NE(program2, 0u);
+
+    glUseProgram(program1);
 
     GLFramebuffer mFramebuffer;
     glBindFramebuffer(GL_DRAW_FRAMEBUFFER, mFramebuffer);
     GLuint defaultWidth  = 1;
     GLuint defaultHeight = 1;
 
     glFramebufferParameteri(GL_FRAMEBUFFER, GL_FRAMEBUFFER_DEFAULT_WIDTH, defaultWidth);
     glFramebufferParameteri(GL_FRAMEBUFFER, GL_FRAMEBUFFER_DEFAULT_HEIGHT, defaultHeight);
@@ -718,40 +760,85 @@ TEST_P(FramebufferTest_ES31, RenderingLi
     glBindVertexArray(vertexArray);
 
     glGenBuffers(1, &vertexBuffer);
     glBindBuffer(GL_ARRAY_BUFFER, vertexBuffer);
     glBufferData(GL_ARRAY_BUFFER, sizeof(data), data, GL_STATIC_DRAW);
 
     glEnableVertexAttribArray(0);
     glVertexAttribPointer(0, 2, GL_FLOAT, false, 0, 0);
+    EXPECT_GLENUM_EQ(GL_FRAMEBUFFER_COMPLETE, glCheckFramebufferStatus(GL_FRAMEBUFFER));
 
     validateSamplePass(query, passedCount, defaultWidth, defaultHeight);
 
+    glUseProgram(program2);
+    validateSamplePass(query, passedCount, defaultWidth, defaultHeight);
+
+    glUseProgram(program1);
     // If fbo has attachments, the rendering size should be the same as its attachment.
     GLTexture mTexture;
     GLuint width  = 2;
     GLuint height = 2;
     glBindTexture(GL_TEXTURE_2D, mTexture.get());
     glTexStorage2D(GL_TEXTURE_2D, 1, GL_RGBA8, width, height);
-    glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, mTexture.get(),
+
+    const GLenum bufs[] = {GL_NONE, GL_NONE, GL_NONE, GL_NONE, GL_NONE, GL_COLOR_ATTACHMENT5};
+
+    glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT5, GL_TEXTURE_2D, mTexture.get(),
                            0);
     EXPECT_GLENUM_EQ(GL_FRAMEBUFFER_COMPLETE, glCheckFramebufferStatus(GL_FRAMEBUFFER));
+    glDrawBuffers(6, bufs);
 
     validateSamplePass(query, passedCount, width, height);
 
     // If fbo's attachment has been removed, the rendering size should be the same as framebuffer
     // default size.
-    glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, 0, 0, 0);
+    glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT5, 0, 0, 0);
     EXPECT_GLENUM_EQ(GL_FRAMEBUFFER_COMPLETE, glCheckFramebufferStatus(GL_FRAMEBUFFER));
 
     validateSamplePass(query, passedCount, defaultWidth, defaultHeight);
 
     glDisableVertexAttribArray(0);
     glBindBuffer(GL_ARRAY_BUFFER, 0);
     glBindVertexArray(0);
     glDeleteBuffers(1, &vertexBuffer);
     glDeleteVertexArrays(1, &vertexArray);
 
     ASSERT_GL_NO_ERROR();
 }
 
 ANGLE_INSTANTIATE_TEST(FramebufferTest_ES31, ES31_D3D11(), ES31_OPENGL(), ES31_OPENGLES());
+
+class AddDummyTextureNoRenderTargetTest : public ANGLETest
+{
+  public:
+    AddDummyTextureNoRenderTargetTest()
+    {
+        setWindowWidth(512);
+        setWindowHeight(512);
+        setConfigRedBits(8);
+        setConfigGreenBits(8);
+        setConfigBlueBits(8);
+        setConfigAlphaBits(8);
+    }
+
+    void overrideWorkaroundsD3D(WorkaroundsD3D *workarounds) override
+    {
+        workarounds->addDummyTextureNoRenderTarget = true;
+    }
+};
+
+// Test to verify workaround succeeds when no program outputs exist http://anglebug.com/2283
+TEST_P(AddDummyTextureNoRenderTargetTest, NoProgramOutputWorkaround)
+{
+    const std::string &vShader = "void main() {}";
+    const std::string &fShader = "void main() {}";
+
+    ANGLE_GL_PROGRAM(drawProgram, vShader, fShader);
+
+    glUseProgram(drawProgram);
+
+    glDrawArrays(GL_TRIANGLES, 0, 6);
+
+    ASSERT_GL_NO_ERROR();
+}
+
+ANGLE_INSTANTIATE_TEST(AddDummyTextureNoRenderTargetTest, ES2_D3D11());
--- a/gfx/angle/src/tests/gl_tests/GLSLTest.cpp
+++ b/gfx/angle/src/tests/gl_tests/GLSLTest.cpp
@@ -426,16 +426,34 @@ class GLSLTest : public ANGLETest
             EXPECT_NE(0u, program);
         }
         else
         {
             EXPECT_EQ(0u, program);
         }
     }
 
+    std::string QueryErrorMessage(GLuint program)
+    {
+        GLint infoLogLength;
+        glGetProgramiv(program, GL_INFO_LOG_LENGTH, &infoLogLength);
+        EXPECT_GL_NO_ERROR();
+
+        if (infoLogLength >= 1)
+        {
+            std::vector<GLchar> infoLog(infoLogLength);
+            glGetProgramInfoLog(program, static_cast<GLsizei>(infoLog.size()), nullptr,
+                                infoLog.data());
+            EXPECT_GL_NO_ERROR();
+            return infoLog.data();
+        }
+
+        return "";
+    }
+
     std::string mSimpleVSSource;
 };
 
 class GLSLTestNoValidation : public GLSLTest
 {
   public:
     GLSLTestNoValidation() { setNoErrorEnabled(true); }
 };
@@ -1624,32 +1642,38 @@ std::string GenerateSmallPowShader(doubl
 
     return stream.str();
 }
 
 // Covers the WebGL test 'glsl/bugs/pow-of-small-constant-in-user-defined-function'
 // See http://anglebug.com/851
 TEST_P(GLSLTest, PowOfSmallConstant)
 {
-    std::vector<double> bads;
-    for (int eps = -1; eps <= 1; ++eps)
+    // Test with problematic exponents that are close to an integer.
+    std::vector<double> testExponents;
+    std::array<double, 5> epsilonMultipliers = {-100.0, -1.0, 0.0, 1.0, 100.0};
+    for (double epsilonMultiplier : epsilonMultipliers)
     {
         for (int i = -4; i <= 5; ++i)
         {
             if (i >= -1 && i <= 1)
                 continue;
             const double epsilon = 1.0e-8;
-            double bad           = static_cast<double>(i) + static_cast<double>(eps) * epsilon;
-            bads.push_back(bad);
+            double bad           = static_cast<double>(i) + epsilonMultiplier * epsilon;
+            testExponents.push_back(bad);
         }
     }
 
-    for (double bad : bads)
+    // Also test with a few exponents that are not close to an integer.
+    testExponents.push_back(3.6);
+    testExponents.push_back(3.4);
+
+    for (double testExponent : testExponents)
     {
-        const std::string &fragmentShaderSource = GenerateSmallPowShader(1.0e-6, bad);
+        const std::string &fragmentShaderSource = GenerateSmallPowShader(1.0e-6, testExponent);
 
         ANGLE_GL_PROGRAM(program, mSimpleVSSource, fragmentShaderSource);
 
         drawQuad(program.get(), "inputAttribute", 0.5f);
 
         EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
         EXPECT_GL_NO_ERROR();
     }
@@ -2404,24 +2428,26 @@ TEST_P(GLSLTest, ExternalAnd2DSampler)
     if (!extensionEnabled("GL_OES_EGL_image_external"))
     {
         std::cout << "Test skipped because GL_OES_EGL_image_external is not available."
                   << std::endl;
         return;
     }
 
     const std::string fragmentShader =
-        "precision mediump float;\n"
-        "uniform samplerExternalOES tex0;\n"
-        "uniform sampler2D tex1;\n"
-        "void main(void)\n"
-        "{\n"
-        " vec2 uv = vec2(0.0, 0.0);"
-        " gl_FragColor = texture2D(tex0, uv) + texture2D(tex1, uv);\n"
-        "}\n";
+        R"(
+        #extension GL_OES_EGL_image_external : enable
+        precision mediump float;
+        uniform samplerExternalOES tex0;
+        uniform sampler2D tex1;
+        void main(void)
+        {
+            vec2 uv = vec2(0.0, 0.0);
+            gl_FragColor = texture2D(tex0, uv) + texture2D(tex1, uv);
+        })";
 
     ANGLE_GL_PROGRAM(program, mSimpleVSSource, fragmentShader);
 }
 
 // Test that literal infinity can be written out from the shader translator.
 // A similar test can't be made for NaNs, since ESSL 3.00.6 requirements for NaNs are very loose.
 TEST_P(GLSLTest_ES3, LiteralInfinityOutput)
 {
@@ -2467,44 +2493,62 @@ TEST_P(GLSLTest_ES3, LiteralNegativeInfi
 // passes. Because the interaction of multiple passes must be tested, it is difficult to write
 // a unittest for them. Instead we add the tests as end2end so will in particular test
 // TranslatorHLSL when run on Windows.
 
 // Test that passes splitting multiple declarations and comma operators are correctly ordered.
 TEST_P(GLSLTest_ES3, MultipleDeclarationWithCommaOperator)
 {
     const std::string &fragmentShader =
-        "#version 300 es\n"
-        "precision mediump float;\n"
-        "out vec4 color;\n"
-        "void main(void)\n"
-        "{\n"
-        " float a = 0.0, b = ((gl_FragCoord.x < 0.5 ? a : 0.0), 1.0);\n"
-        " color = vec4(b);\n"
-        "}\n";
+        R"(#version 300 es
+        precision mediump float;
+        out vec4 color;
+
+        uniform float u;
+        float c = 0.0;
+        float sideEffect()
+        {
+            c = u;
+            return c;
+        }
+
+        void main(void)
+        {
+            float a = 0.0, b = ((gl_FragCoord.x < 0.5 ? a : sideEffect()), a);
+            color = vec4(b + c);
+        })";
 
     ANGLE_GL_PROGRAM(program, mSimpleVSSource, fragmentShader);
 }
 
 // Test that passes splitting multiple declarations and comma operators and for loops are
 // correctly ordered.
 TEST_P(GLSLTest_ES3, MultipleDeclarationWithCommaOperatorInForLoop)
 {
     const std::string &fragmentShader =
-        "#version 300 es\n"
-        "precision mediump float;\n"
-        "out vec4 color;\n"
-        "void main(void)\n"
-        "{\n"
-        " for(float a = 0.0, b = ((gl_FragCoord.x < 0.5 ? a : 0.0), 1.0); a < 10.0; a++)\n"
-        " {\n"
-        "  b += 1.0;\n"
-        "  color = vec4(b);\n"
-        " }\n"
-        "}\n";
+        R"(#version 300 es
+        precision mediump float;
+        out vec4 color;
+
+        uniform float u;
+        float c = 0.0;
+        float sideEffect()
+        {
+            c = u;
+            return c;
+        }
+
+        void main(void)
+        {
+            for(float a = 0.0, b = ((gl_FragCoord.x < 0.5 ? a : sideEffect()), a); a < 10.0; a++)
+            {
+                b += 1.0;
+                color = vec4(b);
+            }
+        })";
 
     ANGLE_GL_PROGRAM(program, mSimpleVSSource, fragmentShader);
 }
 
 // Test that splitting multiple declaration in for loops works with no loop condition
 TEST_P(GLSLTest_ES3, MultipleDeclarationInForLoopEmptyCondition)
 {
     const std::string &fragmentShader =
@@ -2835,24 +2879,16 @@ TEST_P(GLSLTest_ES3, InitUninitializedLo
     {
         // http://anglebug.com/2046
         std::cout
             << "Test skipped on Android GLES because local variable initialization is disabled."
             << std::endl;
         return;
     }
 
-    if (IsOSX() && IsOpenGL())
-    {
-        // http://anglebug.com/2041
-        std::cout << "Test skipped on Mac OpenGL because local variable initialization is disabled."
-                  << std::endl;
-        return;
-    }
-
     const std::string &fragmentShader =
         "#version 300 es\n"
         "precision mediump float;\n"
         "out vec4 my_FragColor;\n"
         "int result = 0;\n"
         "void main()\n"
         "{\n"
         "    int u;\n"
@@ -3480,16 +3516,488 @@ TEST_P(GLSLTest_ES3, NestedArrayLengthMe
             }
         })";
 
     ANGLE_GL_PROGRAM(program, mSimpleVSSource, fragmentShader);
     drawQuad(program.get(), "inputAttribute", 0.5f);
     EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
 }
 
+// Test that statements inside switch() get translated to correct HLSL.
+TEST_P(GLSLTest_ES3, DifferentStatementsInsideSwitch)
+{
+    const std::string &fragmentShader =
+        R"(#version 300 es
+
+        precision highp float;
+
+        uniform int u;
+
+        void main()
+        {
+            switch (u)
+            {
+                case 0:
+                    ivec2 i;
+                    i.yx;
+            }
+        })";
+    ANGLE_GL_PROGRAM(program, mSimpleVSSource, fragmentShader);
+}
+
+// Test that switch fall-through works correctly.
+// This is a regression test for http://anglebug.com/2178
+TEST_P(GLSLTest_ES3, SwitchFallThroughCodeDuplication)
+{
+    const std::string &fragmentShader =
+        R"(#version 300 es
+
+        precision highp float;
+
+        out vec4 my_FragColor;
+
+        uniform int u_zero;
+
+        void main()
+        {
+            int i = 0;
+            // switch should fall through both cases.
+            switch(u_zero)
+            {
+                case 0:
+                    i += 1;
+                case 1:
+                    i += 2;
+            }
+            if (i == 3)
+            {
+                my_FragColor = vec4(0, 1, 0, 1);
+            }
+            else
+            {
+                my_FragColor = vec4(1, 0, 0, 1);
+            }
+        })";
+
+    ANGLE_GL_PROGRAM(program, mSimpleVSSource, fragmentShader);
+    drawQuad(program.get(), "inputAttribute", 0.5f);
+    EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
+}
+
+// Test that a switch statement with an empty block inside as a final statement compiles.
+TEST_P(GLSLTest_ES3, SwitchFinalCaseHasEmptyBlock)
+{
+    const std::string &fragmentShader =
+        R"(#version 300 es
+
+        precision mediump float;
+        uniform int i;
+        void main()
+        {
+            switch (i)
+            {
+                case 0:
+                    break;
+                default:
+                    {}
+            }
+        })";
+    ANGLE_GL_PROGRAM(program, mSimpleVSSource, fragmentShader);
+}
+
+// Test that a switch statement with an empty declaration inside as a final statement compiles.
+TEST_P(GLSLTest_ES3, SwitchFinalCaseHasEmptyDeclaration)
+{
+    const std::string &fragmentShader =
+        R"(#version 300 es
+
+        precision mediump float;
+        uniform int i;
+        void main()
+        {
+            switch (i)
+            {
+                case 0:
+                    break;
+                default:
+                    float;
+            }
+        })";
+    ANGLE_GL_PROGRAM(program, mSimpleVSSource, fragmentShader);
+}
+
+// Test switch/case where break/return statements are within blocks.
+TEST_P(GLSLTest_ES3, SwitchBreakOrReturnInsideBlocks)
+{
+    const std::string &fragmentShader =
+        R"(#version 300 es
+
+        precision highp float;
+
+        uniform int u_zero;
+        out vec4 my_FragColor;
+
+        bool test(int n)
+        {
+            switch(n) {
+                case 0:
+                {
+                    {
+                        break;
+                    }
+                }
+                case 1:
+                {
+                    return true;
+                }
+                case 2:
+                {
+                    n++;
+                }
+            }
+            return false;
+        }
+
+        void main()
+        {
+            my_FragColor = test(u_zero + 1) ? vec4(0, 1, 0, 1) : vec4(1, 0, 0, 1);
+        })";
+
+    ANGLE_GL_PROGRAM(program, mSimpleVSSource, fragmentShader);
+    drawQuad(program.get(), "inputAttribute", 0.5f);
+    EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
+}
+
+// Test switch/case where a variable is declared inside one of the cases and is accessed by a
+// subsequent case.
+TEST_P(GLSLTest_ES3, SwitchWithVariableDeclarationInside)
+{
+    const std::string &fragmentShader =
+        R"(#version 300 es
+
+        precision highp float;
+        out vec4 my_FragColor;
+
+        uniform int u_zero;
+
+        void main()
+        {
+            my_FragColor = vec4(1, 0, 0, 1);
+            switch (u_zero)
+            {
+                case 0:
+                    ivec2 i;
+                    i = ivec2(1, 0);
+                default:
+                    my_FragColor = vec4(0, i[0], 0, 1);
+            }
+        })";
+
+    ANGLE_GL_PROGRAM(program, mSimpleVSSource, fragmentShader);
+    drawQuad(program.get(), "inputAttribute", 0.5f);
+    EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
+}
+
+// Test nested switch/case where a variable is declared inside one of the cases and is accessed by a
+// subsequent case.
+TEST_P(GLSLTest_ES3, NestedSwitchWithVariableDeclarationInside)
+{
+    const std::string &fragmentShader =
+        R"(#version 300 es
+
+        precision highp float;
+        out vec4 my_FragColor;
+
+        uniform int u_zero;
+        uniform int u_zero2;
+
+        void main()
+        {
+            my_FragColor = vec4(1, 0, 0, 1);
+            switch (u_zero)
+            {
+                case 0:
+                    ivec2 i;
+                    i = ivec2(1, 0);
+                    switch (u_zero2)
+                    {
+                        case 0:
+                            int j;
+                        default:
+                            j = 1;
+                            i *= j;
+                    }
+                default:
+                    my_FragColor = vec4(0, i[0], 0, 1);
+            }
+        })";
+
+    ANGLE_GL_PROGRAM(program, mSimpleVSSource, fragmentShader);
+    drawQuad(program.get(), "inputAttribute", 0.5f);
+    EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
+}
+
+// Test that an empty switch/case statement is translated in a way that compiles and executes the
+// init-statement.
+TEST_P(GLSLTest_ES3, EmptySwitch)
+{
+    const std::string &fragmentShader =
+        R"(#version 300 es
+
+        precision highp float;
+
+        uniform int u_zero;
+        out vec4 my_FragColor;
+
+        void main()
+        {
+            int i = u_zero;
+            switch(++i) {}
+            my_FragColor = (i == 1) ? vec4(0, 1, 0, 1) : vec4(1, 0, 0, 1);
+        })";
+
+    ANGLE_GL_PROGRAM(program, mSimpleVSSource, fragmentShader);
+    drawQuad(program.get(), "inputAttribute", 0.5f);
+    EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
+}
+
+// Test that a constant struct inside an expression is handled correctly.
+TEST_P(GLSLTest_ES3, ConstStructInsideExpression)
+{
+    // Incorrect output color was seen on Android. http://anglebug.com/2226
+    ANGLE_SKIP_TEST_IF(IsAndroid() && !IsNVIDIA() && IsOpenGLES());
+
+    const std::string &fragmentShader =
+        R"(#version 300 es
+
+        precision highp float;
+        out vec4 my_FragColor;
+
+        uniform float u_zero;
+
+        struct S
+        {
+            float field;
+        };
+
+        void main()
+        {
+            const S constS = S(1.0);
+            S nonConstS = constS;
+            nonConstS.field = u_zero;
+            bool fail = (constS == nonConstS);
+            my_FragColor = vec4(0, 1, 0, 1);
+            if (fail)
+            {
+                my_FragColor = vec4(1, 0, 0, 1);
+            }
+        })";
+
+    ANGLE_GL_PROGRAM(program, mSimpleVSSource, fragmentShader);
+    drawQuad(program.get(), "inputAttribute", 0.5f);
+    EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
+}
+
+// Test that a varying struct that's defined as a part of the declaration is handled correctly.
+TEST_P(GLSLTest_ES3, VaryingStructWithInlineDefinition)
+{
+    const std::string &vertexShader =
+        R"(#version 300 es
+            in vec4 inputAttribute;
+
+            flat out struct S
+            {
+                int field;
+            } v_s;
+
+            void main()
+            {
+                v_s.field = 1;
+                gl_Position = inputAttribute;
+            })";
+
+    const std::string &fragmentShader =
+        R"(#version 300 es
+
+        precision highp float;
+        out vec4 my_FragColor;
+
+        flat in struct S
+        {
+            int field;
+        } v_s;
+
+        void main()
+        {
+            bool success = (v_s.field == 1);
+            my_FragColor = vec4(1, 0, 0, 1);
+            if (success)
+            {
+                my_FragColor = vec4(0, 1, 0, 1);
+            }
+        })";
+
+    ANGLE_GL_PROGRAM(program, vertexShader, fragmentShader);
+    drawQuad(program.get(), "inputAttribute", 0.5f);
+    EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
+}
+
+// Test vector/scalar arithmetic (in this case multiplication and addition). Meant to reproduce a
+// bug that appeared in NVIDIA OpenGL drivers and that is worked around by
+// VectorizeVectorScalarArithmetic AST transform.
+TEST_P(GLSLTest, VectorScalarMultiplyAndAddInLoop)
+{
+    const std::string &fragmentShader =
+        R"(
+
+        precision mediump float;
+
+        void main() {
+            gl_FragColor = vec4(0.0, 0.0, 0.0, 0.0);
+            for (int i = 0; i < 2; i++)
+            {
+                gl_FragColor += (2.0 * gl_FragCoord.x);
+            }
+            if (gl_FragColor.g == gl_FragColor.r &&
+                gl_FragColor.b == gl_FragColor.r &&
+                gl_FragColor.a == gl_FragColor.r)
+            {
+                gl_FragColor = vec4(0, 1, 0, 1);
+            }
+        })";
+
+    ANGLE_GL_PROGRAM(program, mSimpleVSSource, fragmentShader);
+    drawQuad(program.get(), "inputAttribute", 0.5f);
+    EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
+}
+
+// Test vector/scalar arithmetic (in this case compound division and addition). Meant to reproduce a
+// bug that appeared in NVIDIA OpenGL drivers and that is worked around by
+// VectorizeVectorScalarArithmetic AST transform.
+TEST_P(GLSLTest, VectorScalarDivideAndAddInLoop)
+{
+    const std::string &fragmentShader =
+        R"(
+
+        precision mediump float;
+
+        void main() {
+            gl_FragColor = vec4(0.0, 0.0, 0.0, 0.0);
+            for (int i = 0; i < 2; i++)
+            {
+                float x = gl_FragCoord.x;
+                gl_FragColor = gl_FragColor + (x /= 2.0);
+            }
+            if (gl_FragColor.g == gl_FragColor.r &&
+                gl_FragColor.b == gl_FragColor.r &&
+                gl_FragColor.a == gl_FragColor.r)
+            {
+                gl_FragColor = vec4(0, 1, 0, 1);
+            }
+        })";
+
+    ANGLE_GL_PROGRAM(program, mSimpleVSSource, fragmentShader);
+    drawQuad(program.get(), "inputAttribute", 0.5f);
+    EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
+}
+
+// Test that a varying with a flat qualifier that is used as an operand of a folded ternary operator
+// is handled correctly.
+TEST_P(GLSLTest_ES3, FlatVaryingUsedInFoldedTernary)
+{
+    const std::string &vertexShader =
+        R"(#version 300 es
+
+        in vec4 inputAttribute;
+
+        flat out int v;
+
+        void main()
+        {
+            v = 1;
+            gl_Position = inputAttribute;
+        })";
+
+    const std::string &fragmentShader =
+        R"(#version 300 es
+
+        precision highp float;
+        out vec4 my_FragColor;
+
+        flat in int v;
+
+        void main()
+        {
+            my_FragColor = vec4(0, (true ? v : 0), 0, 1);
+        })";
+
+    ANGLE_GL_PROGRAM(program, vertexShader, fragmentShader);
+    drawQuad(program.get(), "inputAttribute", 0.5f);
+    EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
+}
+
+// Verify that the link error message from last link failure is cleared when the new link is
+// finished.
+TEST_P(GLSLTest, ClearLinkErrorLog)
+{
+    const std::string &vertexShader =
+        R"(
+
+        attribute vec4 vert_in;
+        varying vec4 vert_out;
+        void main()
+        {
+            gl_Position = vert_in;
+            vert_out = vert_in;
+        })";
+
+    const std::string &fragmentShader =
+        R"(
+
+        precision mediump float;
+        varying vec4 frag_in;
+        void main()
+        {
+            gl_FragColor = frag_in;
+        })";
+
+    GLuint vs = CompileShader(GL_VERTEX_SHADER, vertexShader);
+    GLuint fs = CompileShader(GL_FRAGMENT_SHADER, fragmentShader);
+
+    GLuint program = glCreateProgram();
+
+    // The first time the program link fails because of lack of fragment shader.
+    glAttachShader(program, vs);
+    glLinkProgram(program);
+    GLint linkStatus = GL_TRUE;
+    glGetProgramiv(program, GL_LINK_STATUS, &linkStatus);
+    ASSERT_FALSE(linkStatus);
+
+    const std::string &lackOfFragmentShader = QueryErrorMessage(program);
+
+    // The second time the program link fails because of the mismatch of the varying types.
+    glAttachShader(program, fs);
+    glLinkProgram(program);
+    linkStatus = GL_TRUE;
+    glGetProgramiv(program, GL_LINK_STATUS, &linkStatus);
+    ASSERT_FALSE(linkStatus);
+
+    const std::string &varyingTypeMismatch = QueryErrorMessage(program);
+
+    EXPECT_EQ(std::string::npos, varyingTypeMismatch.find(lackOfFragmentShader));
+
+    glDetachShader(program, vs);
+    glDetachShader(program, fs);
+    glDeleteShader(vs);
+    glDeleteShader(fs);
+    glDeleteProgram(program);
+
+    ASSERT_GL_NO_ERROR();
+}
+
 // Use this to select which configurations (e.g. which renderer, which GLES major version) these tests should be run against.
 ANGLE_INSTANTIATE_TEST(GLSLTest,
                        ES2_D3D9(),
                        ES2_D3D11(),
                        ES2_D3D11_FL9_3(),
                        ES2_OPENGL(),
                        ES3_OPENGL(),
                        ES2_OPENGLES(),
new file mode 100644
--- /dev/null
+++ b/gfx/angle/src/tests/gl_tests/GeometryShaderTest.cpp
@@ -0,0 +1,132 @@
+//
+// 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.
+//
+
+// GeometryShaderTest.cpp : Tests of the implementation of geometry shader
+
+#include "test_utils/ANGLETest.h"
+
+using namespace angle;
+
+namespace
+{
+
+class GeometryShaderTest : public ANGLETest
+{
+};
+
+class GeometryShaderTestES3 : public ANGLETest
+{
+};
+
+// Verify that Geometry Shader cannot be created in an OpenGL ES 3.0 context.
+TEST_P(GeometryShaderTestES3, CreateGeometryShaderInES3)
+{
+    EXPECT_TRUE(!extensionEnabled("GL_EXT_geometry_shader"));
+    GLuint geometryShader = glCreateShader(GL_GEOMETRY_SHADER_EXT);
+    EXPECT_EQ(0u, geometryShader);
+    EXPECT_GL_ERROR(GL_INVALID_ENUM);
+}
+
+// Verify that Geometry Shader can be created and attached to a program.
+TEST_P(GeometryShaderTest, CreateAndAttachGeometryShader)
+{
+    ANGLE_SKIP_TEST_IF(!extensionEnabled("GL_EXT_geometry_shader"));
+
+    const std::string &geometryShaderSource =
+        R"(#version 310 es
+        #extension GL_EXT_geometry_shader : require
+        layout (invocations = 3, triangles) in;
+        layout (triangle_strip, max_vertices = 3) out;
+        in vec4 texcoord[];
+        out vec4 o_texcoord;
+        void main()
+        {
+            int n;
+            for (n = 0; n < gl_in.length(); n++)
+            {
+                gl_Position = gl_in[n].gl_Position;
+                gl_Layer   = gl_InvocationID;
+                o_texcoord = texcoord[n];
+                EmitVertex();
+            }
+            EndPrimitive();
+        })";
+
+    GLuint geometryShader = CompileShader(GL_GEOMETRY_SHADER_EXT, geometryShaderSource);
+
+    EXPECT_NE(0u, geometryShader);
+
+    GLuint programID = glCreateProgram();
+    glAttachShader(programID, geometryShader);
+
+    glDetachShader(programID, geometryShader);
+    glDeleteShader(geometryShader);
+    glDeleteProgram(programID);
+
+    EXPECT_GL_NO_ERROR();
+}
+
+// Verify that all the implementation dependent geometry shader related resource limits meet the
+// requirement of GL_EXT_geometry_shader SPEC.
+TEST_P(GeometryShaderTest, GeometryShaderImplementationDependentLimits)
+{
+    ANGLE_SKIP_TEST_IF(!extensionEnabled("GL_EXT_geometry_shader"));
+
+    const std::map<GLenum, int> limits = {{GL_MAX_FRAMEBUFFER_LAYERS_EXT, 256},
+                                          {GL_MAX_GEOMETRY_UNIFORM_COMPONENTS_EXT, 1024},
+                                          {GL_MAX_GEOMETRY_UNIFORM_BLOCKS_EXT, 12},
+                                          {GL_MAX_GEOMETRY_INPUT_COMPONENTS_EXT, 64},
+                                          {GL_MAX_GEOMETRY_OUTPUT_COMPONENTS_EXT, 64},
+                                          {GL_MAX_GEOMETRY_OUTPUT_VERTICES_EXT, 256},
+                                          {GL_MAX_GEOMETRY_TOTAL_OUTPUT_COMPONENTS_EXT, 1024},
+                                          {GL_MAX_GEOMETRY_TEXTURE_IMAGE_UNITS_EXT, 16},
+                                          {GL_MAX_GEOMETRY_ATOMIC_COUNTER_BUFFERS_EXT, 0},
+                                          {GL_MAX_GEOMETRY_ATOMIC_COUNTERS_EXT, 0},
+                                          {GL_MAX_GEOMETRY_SHADER_STORAGE_BLOCKS_EXT, 0},
+                                          {GL_MAX_GEOMETRY_IMAGE_UNIFORMS_EXT, 0},
+                                          {GL_MAX_GEOMETRY_SHADER_INVOCATIONS_EXT, 32}};
+
+    GLint value;
+    for (const auto &limit : limits)
+    {
+        value = 0;
+        glGetIntegerv(limit.first, &value);
+        EXPECT_GL_NO_ERROR();
+        EXPECT_GE(value, limit.second);
+    }
+
+    value = 0;
+    glGetIntegerv(GL_LAYER_PROVOKING_VERTEX_EXT, &value);
+    EXPECT_GL_NO_ERROR();
+    EXPECT_TRUE(value == GL_FIRST_VERTEX_CONVENTION_EXT || value == GL_LAST_VERTEX_CONVENTION_EXT ||
+                value == GL_UNDEFINED_VERTEX_EXT);
+}
+
+// Verify that all the combined resource limits meet the requirement of GL_EXT_geometry_shader SPEC.
+TEST_P(GeometryShaderTest, CombinedResourceLimits)
+{
+    ANGLE_SKIP_TEST_IF(!extensionEnabled("GL_EXT_geometry_shader"));
+
+    // See http://anglebug.com/2261.
+    ANGLE_SKIP_TEST_IF(IsAndroid());
+
+    const std::map<GLenum, int> limits = {{GL_MAX_UNIFORM_BUFFER_BINDINGS, 48},
+                                          {GL_MAX_COMBINED_UNIFORM_BLOCKS, 36},
+                                          {GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS, 64}};
+
+    GLint value;
+    for (const auto &limit : limits)
+    {
+        value = 0;
+        glGetIntegerv(limit.first, &value);
+        EXPECT_GL_NO_ERROR();
+        EXPECT_GE(value, limit.second);
+    }
+}
+
+ANGLE_INSTANTIATE_TEST(GeometryShaderTestES3, ES3_OPENGL(), ES3_OPENGLES(), ES3_D3D11());
+ANGLE_INSTANTIATE_TEST(GeometryShaderTest, ES31_OPENGL(), ES31_OPENGLES(), ES31_D3D11());
+}
--- a/gfx/angle/src/tests/gl_tests/IncompleteTextureTest.cpp
+++ b/gfx/angle/src/tests/gl_tests/IncompleteTextureTest.cpp
@@ -19,17 +19,17 @@ class IncompleteTextureTest : public ANG
         setWindowWidth(128);
         setWindowHeight(128);
         setConfigRedBits(8);
         setConfigGreenBits(8);
         setConfigBlueBits(8);
         setConfigAlphaBits(8);
     }
 
-    virtual void SetUp()
+    void SetUp() override
     {
         ANGLETest::SetUp();
 
         const std::string vertexShaderSource =
             R"(precision highp float;
             attribute vec4 position;
             varying vec2 texcoord;
 
@@ -53,39 +53,42 @@ class IncompleteTextureTest : public ANG
         if (mProgram == 0)
         {
             FAIL() << "shader compilation failed.";
         }
 
         mTextureUniformLocation = glGetUniformLocation(mProgram, "tex");
     }
 
-    virtual void TearDown()
+    void TearDown() override
     {
         glDeleteProgram(mProgram);
 
         ANGLETest::TearDown();
     }
 
-    void fillTextureData(std::vector<GLubyte> &buffer, GLubyte r, GLubyte g, GLubyte b, GLubyte a)
-    {
-        size_t count = buffer.size() / 4;
-        for (size_t i = 0; i < count; i++)
-        {
-            buffer[i * 4 + 0] = r;
-            buffer[i * 4 + 1] = g;
-            buffer[i * 4 + 2] = b;
-            buffer[i * 4 + 3] = a;
-        }
-    }
-
     GLuint mProgram;
     GLint mTextureUniformLocation;
 };
 
+class IncompleteTextureTestES31 : public ANGLETest
+{
+  protected:
+    IncompleteTextureTestES31()
+    {
+        setWindowWidth(128);
+        setWindowHeight(128);
+        setConfigRedBits(8);
+        setConfigGreenBits(8);
+        setConfigBlueBits(8);
+        setConfigAlphaBits(8);
+    }
+};
+
+// Test rendering with an incomplete texture.
 TEST_P(IncompleteTextureTest, IncompleteTexture2D)
 {
     GLTexture tex;
     glActiveTexture(GL_TEXTURE0);
     glBindTexture(GL_TEXTURE_2D, tex);
 
     glUseProgram(mProgram);
     glUniform1i(mTextureUniformLocation, 0);
@@ -95,73 +98,114 @@ TEST_P(IncompleteTextureTest, Incomplete
 
     // Make a complete texture.
     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, kTextureSize, kTextureSize, 0, GL_RGBA,
                  GL_UNSIGNED_BYTE, textureData.data());
     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
 
     // Should be complete - expect red.
     drawQuad(mProgram, "position", 0.5f);
-    EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::red);
+    EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::red) << "complete texture should be red";
 
     // Make texture incomplete.
     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
 
     // Should be incomplete - expect black.
     drawQuad(mProgram, "position", 0.5f);
-    EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::black);
+    EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::black) << "incomplete texture should be black";
 
     // Make texture complete by defining the second mip.
     glTexImage2D(GL_TEXTURE_2D, 1, GL_RGBA, kTextureSize >> 1, kTextureSize >> 1, 0, GL_RGBA,
                  GL_UNSIGNED_BYTE, textureData.data());
 
     // Should be complete - expect red.
     drawQuad(mProgram, "position", 0.5f);
-    EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::red);
+    EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::red) << "mip-complete texture should be red";
 }
 
+// Tests redefining a texture with half the size works as expected.
 TEST_P(IncompleteTextureTest, UpdateTexture)
 {
     GLTexture tex;
     glActiveTexture(GL_TEXTURE0);
     glBindTexture(GL_TEXTURE_2D, tex);
 
     glUseProgram(mProgram);
     glUniform1i(mTextureUniformLocation, 0);
 
-    const GLsizei redTextureWidth = 64;
-    const GLsizei redTextureHeight = 64;
-    std::vector<GLubyte> redTextureData(redTextureWidth * redTextureHeight * 4);
-    fillTextureData(redTextureData, 255, 0, 0, 255);
-    for (size_t i = 0; i < 7; i++)
+    constexpr GLsizei redTextureSize = 64;
+    std::vector<GLColor> redTextureData(redTextureSize * redTextureSize, GLColor::red);
+    for (GLint mip = 0; mip < 7; ++mip)
     {
-        glTexImage2D(GL_TEXTURE_2D, static_cast<GLint>(i), GL_RGBA, redTextureWidth >> i,
-                     redTextureHeight >> i, 0, GL_RGBA, GL_UNSIGNED_BYTE, &redTextureData[0]);
+        const GLsizei mipSize = redTextureSize >> mip;
+
+        glTexImage2D(GL_TEXTURE_2D, mip, GL_RGBA, mipSize, mipSize, 0, GL_RGBA, GL_UNSIGNED_BYTE,
+                     redTextureData.data());
     }
 
     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
 
     drawQuad(mProgram, "position", 0.5f);
-    EXPECT_PIXEL_EQ(0, 0, 255, 0, 0, 255);
+    EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::red);
+
+    constexpr GLsizei greenTextureSize = 32;
+    std::vector<GLColor> greenTextureData(greenTextureSize * greenTextureSize, GLColor::green);
 
-    const GLsizei greenTextureWidth = 32;
-    const GLsizei greenTextureHeight = 32;
-    std::vector<GLubyte> greenTextureData(greenTextureWidth * greenTextureHeight * 4);
-    fillTextureData(greenTextureData, 0, 255, 0, 255);
+    for (GLint mip = 0; mip < 6; ++mip)
+    {
+        const GLsizei mipSize = greenTextureSize >> mip;
 
-    for (size_t i = 0; i < 6; i++)
-    {
-        glTexSubImage2D(GL_TEXTURE_2D, static_cast<GLint>(i), greenTextureWidth >> i,
-                        greenTextureHeight >> i, greenTextureWidth >> i, greenTextureHeight >> i,
-                        GL_RGBA, GL_UNSIGNED_BYTE, &greenTextureData[0]);
+        glTexSubImage2D(GL_TEXTURE_2D, mip, mipSize, mipSize, mipSize, mipSize, GL_RGBA,
+                        GL_UNSIGNED_BYTE, greenTextureData.data());
     }
 
     drawQuad(mProgram, "position", 0.5f);
-    EXPECT_PIXEL_EQ(getWindowWidth() - greenTextureWidth, getWindowHeight() - greenTextureWidth, 0, 255, 0, 255);
+    EXPECT_PIXEL_COLOR_EQ(getWindowWidth() - greenTextureSize, getWindowHeight() - greenTextureSize,
+                          GLColor::green);
+}
+
+// Tests that the incomplete multisample texture has the correct alpha value.
+TEST_P(IncompleteTextureTestES31, MultisampleTexture)
+{
+    const std::string vertexShader = R"(#version 310 es
+in vec2 position;
+out vec2 texCoord;
+void main()
+{
+    gl_Position = vec4(position, 0, 1);
+    texCoord = (position * 0.5) + 0.5;
+}
+)";
+
+    const std::string fragmentShader = R"(#version 310 es
+precision mediump float;
+in vec2 texCoord;
+out vec4 color;
+uniform mediump sampler2DMS tex;
+void main()
+{
+    ivec2 texSize = textureSize(tex);
+    ivec2 texel = ivec2(vec2(texSize) * texCoord);
+    color = texelFetch(tex, texel, 0);
+}
+)";
+
+    glClearColor(1.0f, 0.0f, 0.0f, 1.0f);
+    glClear(GL_COLOR_BUFFER_BIT);
+    EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::red);
+
+    // The zero texture will be incomplete by default.
+    ANGLE_GL_PROGRAM(program, vertexShader, fragmentShader);
+    drawQuad(program, "position", 0.5f);
+    ASSERT_GL_NO_ERROR();
+
+    EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::black);
 }
 
 // Use this to select which configurations (e.g. which renderer, which GLES major version) these tests should be run against.
 ANGLE_INSTANTIATE_TEST(IncompleteTextureTest,
                        ES2_D3D9(),
                        ES2_D3D11(),
                        ES2_OPENGL(),
                        ES2_OPENGLES());
+
+ANGLE_INSTANTIATE_TEST(IncompleteTextureTestES31, ES31_D3D11(), ES31_OPENGL(), ES31_OPENGLES());
new file mode 100644
--- /dev/null
+++ b/gfx/angle/src/tests/gl_tests/LinkAndRelinkTest.cpp
@@ -0,0 +1,440 @@
+//
+// 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.
+//
+// LinkAndRelinkFailureTest:
+//   Link and relink failure tests for rendering pipeline and compute pipeline.
+
+#include <vector>
+#include "test_utils/ANGLETest.h"
+#include "test_utils/gl_raii.h"
+
+using namespace angle;
+
+namespace
+{
+
+class LinkAndRelinkTest : public ANGLETest
+{
+  protected:
+    LinkAndRelinkTest() {}
+};
+
+class LinkAndRelinkTestES31 : public ANGLETest
+{
+  protected:
+    LinkAndRelinkTestES31() {}
+};
+
+// When a program link or relink fails, if you try to install the unsuccessfully
+// linked program (via UseProgram) and start rendering or dispatch compute,
+// We can not always report INVALID_OPERATION for rendering/compute pipeline.
+// The result depends on the previous state: Whether a valid program is
+// installed in current GL state before the link.
+// If a program successfully relinks when it is in use, the program might
+// change from a rendering program to a compute program in theory,
+// or vice versa.
+
+// When program link fails and no valid rendering program is installed in the GL
+// state before the link, it should report an error for UseProgram and
+// DrawArrays/DrawElements.
+TEST_P(LinkAndRelinkTest, RenderingProgramFailsWithoutProgramInstalled)
+{
+    glUseProgram(0);
+    GLuint program = glCreateProgram();
+
+    glLinkProgram(program);
+    GLint linkStatus;
+    glGetProgramiv(program, GL_LINK_STATUS, &linkStatus);
+    EXPECT_GL_FALSE(linkStatus);
+
+    glUseProgram(program);
+    EXPECT_GL_ERROR(GL_INVALID_OPERATION);
+
+    glDrawArrays(GL_POINTS, 0, 1);
+    EXPECT_GL_ERROR(GL_INVALID_OPERATION);
+}
+
+// When program link or relink fails and a valid rendering program is installed
+// in the GL state before the link, using the failed program via UseProgram
+// should report an error, but starting rendering should succeed.
+// However, dispatching compute always fails.
+TEST_P(LinkAndRelinkTest, RenderingProgramFailsWithProgramInstalled)
+{
+    // Install a render program in current GL state via UseProgram, then render.
+    // It should succeed.
+    const std::string vsSource =
+        R"(void main()
+        {
+        })";
+
+    const std::string fsSource =
+        R"(void main()
+        {
+        })";
+
+    GLuint program = glCreateProgram();
+
+    GLuint vs = CompileShader(GL_VERTEX_SHADER, vsSource);
+    GLuint fs = CompileShader(GL_FRAGMENT_SHADER, fsSource);
+
+    EXPECT_NE(0u, vs);
+    EXPECT_NE(0u, fs);
+
+    glAttachShader(program, vs);
+    glDeleteShader(vs);
+
+    glAttachShader(program, fs);
+    glDeleteShader(fs);
+
+    glLinkProgram(program);
+
+    GLint linkStatus;
+    glGetProgramiv(program, GL_LINK_STATUS, &linkStatus);
+    EXPECT_GL_TRUE(linkStatus);
+
+    EXPECT_GL_NO_ERROR();
+
+    glUseProgram(program);
+    EXPECT_GL_NO_ERROR();
+    glDrawArrays(GL_POINTS, 0, 1);
+    EXPECT_GL_NO_ERROR();
+
+    glDispatchCompute(8, 4, 2);
+    EXPECT_GL_ERROR(GL_INVALID_OPERATION);
+
+    // Link failure, and a valid program has been installed in the GL state.
+    GLuint programNull = glCreateProgram();
+
+    glLinkProgram(programNull);
+    glGetProgramiv(programNull, GL_LINK_STATUS, &linkStatus);
+    EXPECT_GL_FALSE(linkStatus);
+
+    // Starting rendering should succeed.
+    glDrawArrays(GL_POINTS, 0, 1);
+    EXPECT_GL_NO_ERROR();
+
+    glDispatchCompute(8, 4, 2);
+    EXPECT_GL_ERROR(GL_INVALID_OPERATION);
+
+    // Using the unsuccessfully linked program should report an error.
+    glUseProgram(programNull);
+    EXPECT_GL_ERROR(GL_INVALID_OPERATION);
+
+    // Using the unsuccessfully linked program, that program should not
+    // replace the program binary residing in the GL state. It will not make
+    // the installed program invalid either, like what UseProgram(0) can do.
+    // So, starting rendering should succeed.
+    glDrawArrays(GL_POINTS, 0, 1);
+    EXPECT_GL_NO_ERROR();
+
+    glDispatchCompute(8, 4, 2);
+    EXPECT_GL_ERROR(GL_INVALID_OPERATION);
+
+    // We try to relink the installed program, but make it fail.
+
+    // No vertex shader, relink fails.
+    glDetachShader(program, vs);
+    glLinkProgram(program);
+    glGetProgramiv(program, GL_LINK_STATUS, &linkStatus);
+    EXPECT_GL_FALSE(linkStatus);
+    EXPECT_GL_NO_ERROR();
+
+    // Starting rendering should succeed.
+    glDrawArrays(GL_POINTS, 0, 1);
+    EXPECT_GL_NO_ERROR();
+
+    glDispatchCompute(8, 4, 2);
+    EXPECT_GL_ERROR(GL_INVALID_OPERATION);
+
+    // Using the unsuccessfully relinked program should report an error.
+    glUseProgram(program);
+    EXPECT_GL_ERROR(GL_INVALID_OPERATION);
+
+    // Using the unsuccessfully relinked program, that program should not
+    // replace the program binary residing in the GL state. It will not make
+    // the installed program invalid either, like what UseProgram(0) can do.
+    // So, starting rendering should succeed.
+    glDrawArrays(GL_POINTS, 0, 1);
+    EXPECT_GL_NO_ERROR();
+
+    glDispatchCompute(8, 4, 2);
+    EXPECT_GL_ERROR(GL_INVALID_OPERATION);
+}
+
+// When program link fails and no valid compute program is installed in the GL
+// state before the link, it should report an error for UseProgram and
+// DispatchCompute.
+TEST_P(LinkAndRelinkTestES31, ComputeProgramFailsWithoutProgramInstalled)
+{
+    glUseProgram(0);
+    GLuint program = glCreateProgram();
+
+    glLinkProgram(program);
+    GLint linkStatus;
+    glGetProgramiv(program, GL_LINK_STATUS, &linkStatus);
+    EXPECT_GL_FALSE(linkStatus);
+
+    glUseProgram(program);
+    EXPECT_GL_ERROR(GL_INVALID_OPERATION);
+
+    glDispatchCompute(8, 4, 2);
+    EXPECT_GL_ERROR(GL_INVALID_OPERATION);
+}
+
+// When program link or relink fails and a valid compute program is installed in
+// the GL state before the link, using the failed program via UseProgram should
+// report an error, but dispatching compute should succeed.
+// However, starting rendering always fails.
+TEST_P(LinkAndRelinkTestES31, ComputeProgramFailsWithProgramInstalled)
+{
+    // Install a compute program in the GL state via UseProgram, then dispatch
+    // compute. It should succeed.
+    const std::string csSource =
+        R"(#version 310 es
+        layout(local_size_x=1) in;
+        void main()
+        {
+        })";
+
+    GLuint program = glCreateProgram();
+
+    GLuint cs = CompileShader(GL_COMPUTE_SHADER, csSource);
+    EXPECT_NE(0u, cs);
+
+    glAttachShader(program, cs);
+    glDeleteShader(cs);
+
+    glLinkProgram(program);
+    GLint linkStatus;
+    glGetProgramiv(program, GL_LINK_STATUS, &linkStatus);
+    EXPECT_GL_TRUE(linkStatus);
+
+    EXPECT_GL_NO_ERROR();
+
+    glUseProgram(program);
+    EXPECT_GL_NO_ERROR();
+    glDispatchCompute(8, 4, 2);
+    EXPECT_GL_NO_ERROR();
+
+    glDrawArrays(GL_POINTS, 0, 1);
+    EXPECT_GL_ERROR(GL_INVALID_OPERATION);
+
+    // Link failure, and a valid program has been installed in the GL state.
+    GLuint programNull = glCreateProgram();
+
+    glLinkProgram(programNull);
+    glGetProgramiv(programNull, GL_LINK_STATUS, &linkStatus);
+    EXPECT_GL_FALSE(linkStatus);
+
+    // Dispatching compute should succeed.
+    glDispatchCompute(8, 4, 2);
+    EXPECT_GL_NO_ERROR();
+
+    glDrawArrays(GL_POINTS, 0, 1);
+    EXPECT_GL_ERROR(GL_INVALID_OPERATION);
+
+    // Using the unsuccessfully linked program should report an error.
+    glUseProgram(programNull);
+    EXPECT_GL_ERROR(GL_INVALID_OPERATION);
+
+    // Using the unsuccessfully linked program, that program should not
+    // replace the program binary residing in the GL state. It will not make
+    // the installed program invalid either, like what UseProgram(0) can do.
+    // So, dispatching compute should succeed.
+    glDispatchCompute(8, 4, 2);
+    EXPECT_GL_NO_ERROR();
+
+    glDrawArrays(GL_POINTS, 0, 1);
+    EXPECT_GL_ERROR(GL_INVALID_OPERATION);
+
+    // We try to relink the installed program, but make it fail.
+
+    // No compute shader, relink fails.
+    glDetachShader(program, cs);
+    glLinkProgram(program);
+    glGetProgramiv(program, GL_LINK_STATUS, &linkStatus);
+    EXPECT_GL_FALSE(linkStatus);
+    EXPECT_GL_NO_ERROR();
+
+    // Dispatching compute should succeed.
+    glDispatchCompute(8, 4, 2);
+    EXPECT_GL_NO_ERROR();
+
+    glDrawArrays(GL_POINTS, 0, 1);
+    EXPECT_GL_ERROR(GL_INVALID_OPERATION);
+
+    // Using the unsuccessfully relinked program should report an error.
+    glUseProgram(program);
+    EXPECT_GL_ERROR(GL_INVALID_OPERATION);
+
+    // Using the unsuccessfully relinked program, that program should not
+    // replace the program binary residing in the GL state. It will not make
+    // the installed program invalid either, like what UseProgram(0) can do.
+    // So, dispatching compute should succeed.
+    glDispatchCompute(8, 4, 2);
+    EXPECT_GL_NO_ERROR();
+
+    glDrawArrays(GL_POINTS, 0, 1);
+    EXPECT_GL_ERROR(GL_INVALID_OPERATION);
+}
+
+// If you compile and link a compute program successfully and use the program,
+// then dispatching compute can succeed, while starting rendering will fail.
+// If you relink the compute program to a rendering program when it is in use,
+// then dispatching compute will fail, but starting rendering can succeed.
+TEST_P(LinkAndRelinkTestES31, RelinkProgramSucceedsFromComputeToRendering)
+{
+    const std::string csSource =
+        R"(#version 310 es
+        layout(local_size_x=1) in;
+        void main()
+        {
+        })";
+
+    GLuint program = glCreateProgram();
+
+    GLuint cs = CompileShader(GL_COMPUTE_SHADER, csSource);
+    EXPECT_NE(0u, cs);
+
+    glAttachShader(program, cs);
+    glDeleteShader(cs);
+
+    glLinkProgram(program);
+    glDetachShader(program, cs);
+    GLint linkStatus;
+    glGetProgramiv(program, GL_LINK_STATUS, &linkStatus);
+    EXPECT_GL_TRUE(linkStatus);
+
+    EXPECT_GL_NO_ERROR();
+
+    glUseProgram(program);
+    EXPECT_GL_NO_ERROR();
+    glDispatchCompute(8, 4, 2);
+    EXPECT_GL_NO_ERROR();
+
+    glDrawArrays(GL_POINTS, 0, 1);
+    EXPECT_GL_ERROR(GL_INVALID_OPERATION);
+
+    const std::string vsSource =
+        R"(void main()
+        {
+        })";
+
+    const std::string fsSource =
+        R"(void main()
+        {
+        })";
+
+    GLuint vs = CompileShader(GL_VERTEX_SHADER, vsSource);
+    GLuint fs = CompileShader(GL_FRAGMENT_SHADER, fsSource);
+    EXPECT_NE(0u, vs);
+    EXPECT_NE(0u, fs);
+
+    glAttachShader(program, vs);
+    glDeleteShader(vs);
+
+    glAttachShader(program, fs);
+    glDeleteShader(fs);
+
+    glLinkProgram(program);
+    glDetachShader(program, vs);
+    glDetachShader(program, fs);
+    glGetProgramiv(program, GL_LINK_STATUS, &linkStatus);
+    EXPECT_GL_TRUE(linkStatus);
+
+    EXPECT_GL_NO_ERROR();
+
+    glDrawArrays(GL_POINTS, 0, 1);
+    EXPECT_GL_NO_ERROR();
+
+    glDispatchCompute(8, 4, 2);
+    EXPECT_GL_ERROR(GL_INVALID_OPERATION);
+}
+
+// If you compile and link a rendering program successfully and use the program,
+// then starting rendering can succeed, while dispatching compute will fail.
+// If you relink the rendering program to a compute program when it is in use,
+// then starting rendering will fail, but dispatching compute can succeed.
+TEST_P(LinkAndRelinkTestES31, RelinkProgramSucceedsFromRenderingToCompute)
+{
+    const std::string vsSource =
+        R"(void main()
+        {
+        })";
+
+    const std::string fsSource =
+        R"(void main()
+        {
+        })";
+
+    GLuint program = glCreateProgram();
+
+    GLuint vs = CompileShader(GL_VERTEX_SHADER, vsSource);
+    GLuint fs = CompileShader(GL_FRAGMENT_SHADER, fsSource);
+
+    EXPECT_NE(0u, vs);
+    EXPECT_NE(0u, fs);
+
+    glAttachShader(program, vs);
+    glDeleteShader(vs);
+
+    glAttachShader(program, fs);
+    glDeleteShader(fs);
+
+    glLinkProgram(program);
+    glDetachShader(program, vs);
+    glDetachShader(program, fs);
+    GLint linkStatus;
+    glGetProgramiv(program, GL_LINK_STATUS, &linkStatus);
+    EXPECT_GL_TRUE(linkStatus);
+
+    EXPECT_GL_NO_ERROR();
+
+    glUseProgram(program);
+    EXPECT_GL_NO_ERROR();
+    glDrawArrays(GL_POINTS, 0, 1);
+    EXPECT_GL_NO_ERROR();
+
+    glDispatchCompute(8, 4, 2);
+    EXPECT_GL_ERROR(GL_INVALID_OPERATION);
+
+    const std::string csSource =
+        R"(#version 310 es
+        layout(local_size_x=1) in;
+        void main()
+        {
+        })";
+
+    GLuint cs = CompileShader(GL_COMPUTE_SHADER, csSource);
+    EXPECT_NE(0u, cs);
+
+    glAttachShader(program, cs);
+    glDeleteShader(cs);
+
+    glLinkProgram(program);
+    glDetachShader(program, cs);
+    glGetProgramiv(program, GL_LINK_STATUS, &linkStatus);
+    EXPECT_GL_TRUE(linkStatus);
+
+    EXPECT_GL_NO_ERROR();
+
+    glDispatchCompute(8, 4, 2);
+    EXPECT_GL_NO_ERROR();
+
+    glDrawArrays(GL_POINTS, 0, 1);
+    EXPECT_GL_ERROR(GL_INVALID_OPERATION);
+}
+
+ANGLE_INSTANTIATE_TEST(LinkAndRelinkTest,
+                       ES2_OPENGL(),
+                       ES2_OPENGLES(),
+                       ES2_D3D9(),
+                       ES2_D3D11(),
+                       ES3_OPENGL(),
+                       ES3_OPENGLES(),
+                       ES3_D3D11());
+ANGLE_INSTANTIATE_TEST(LinkAndRelinkTestES31, ES31_OPENGL(), ES31_OPENGLES());
+
+}  // namespace
--- a/gfx/angle/src/tests/gl_tests/MultiviewDrawTest.cpp
+++ b/gfx/angle/src/tests/gl_tests/MultiviewDrawTest.cpp
@@ -433,26 +433,40 @@ class MultiviewRenderDualViewTest : publ
     GLuint mProgram;
 };
 
 class MultiviewOcclusionQueryTest : public MultiviewRenderTest
 {
   protected:
     MultiviewOcclusionQueryTest() {}
 
+    bool requestOcclusionQueryExtension()
+    {
+        if (extensionRequestable("GL_EXT_occlusion_query_boolean"))
+        {
+            glRequestExtensionANGLE("GL_EXT_occlusion_query_boolean");
+        }
+
+        if (!extensionEnabled("GL_EXT_occlusion_query_boolean"))
+        {
+            std::cout << "Test skipped due to missing GL_EXT_occlusion_query_boolean." << std::endl;
+            return false;
+        }
+        return true;
+    }
+
     GLuint drawAndRetrieveOcclusionQueryResult(GLuint program)
     {
-        GLuint query;
-        glGenQueries(1, &query);
-        glBeginQuery(GL_ANY_SAMPLES_PASSED, query);
+        GLQueryEXT query;
+        glBeginQueryEXT(GL_ANY_SAMPLES_PASSED, query);
         drawQuad(program, "vPosition", 0.0f, 1.0f, true);
         glEndQueryEXT(GL_ANY_SAMPLES_PASSED);
 
         GLuint result = GL_TRUE;
-        glGetQueryObjectuiv(query, GL_QUERY_RESULT, &result);
+        glGetQueryObjectuivEXT(query, GL_QUERY_RESULT, &result);
         return result;
     }
 };
 
 class MultiviewProgramGenerationTest : public MultiviewRenderTest
 {
   protected:
     MultiviewProgramGenerationTest() {}
@@ -687,33 +701,42 @@ TEST_P(MultiviewDrawValidationTest, Acti
     if (!requestMultiviewExtension())
     {
         return;
     }
 
     const GLint viewportOffsets[4] = {0, 0, 2, 0};
 
     const std::string &vsSource =
-        "#version 300 es\n"
-        "void main()\n"
-        "{}\n";
+        R"(#version 300 es
+        out float tfVarying;
+        void main()
+        {
+            tfVarying = 1.0;
+        })";
     const std::string &fsSource =
-        "#version 300 es\n"
-        "precision mediump float;\n"
-        "void main()\n"
-        "{}\n";
-    ANGLE_GL_PROGRAM(program, vsSource, fsSource);
+        R"(#version 300 es
+        precision mediump float;
+        void main()
+        {})";
+    std::vector<std::string> tfVaryings;
+    tfVaryings.push_back(std::string("tfVarying"));
+    ANGLE_GL_PROGRAM_TRANSFORM_FEEDBACK(program, vsSource, fsSource, tfVaryings,
+                                        GL_SEPARATE_ATTRIBS);
     glUseProgram(program);
 
     GLBuffer tbo;
     glBindBuffer(GL_TRANSFORM_FEEDBACK_BUFFER, tbo);
     glBufferData(GL_TRANSFORM_FEEDBACK_BUFFER, sizeof(float) * 4u, nullptr, GL_STATIC_DRAW);
 
     GLTransformFeedback transformFeedback;
     glBindTransformFeedback(GL_TRANSFORM_FEEDBACK, transformFeedback);
+
+    glBindBufferBase(GL_TRANSFORM_FEEDBACK_BUFFER, 0, tbo);
+
     glBeginTransformFeedback(GL_TRIANGLES);
     ASSERT_GL_NO_ERROR();
 
     // Check that drawArrays generates an error when there is an active transform feedback object
     // and the number of views in the draw framebuffer is greater than 1.
     {
         glFramebufferTextureMultiviewSideBySideANGLE(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, mTex2d,
                                                      0, 2, &viewportOffsets[0]);
@@ -1187,20 +1210,18 @@ TEST_P(MultiviewRenderTest, DivisorOrder
     EXPECT_EQ(GLColor::green, GetViewColor(0, 0, 0));
     EXPECT_EQ(GLColor::green, GetViewColor(0, 0, 1));
 }
 
 // Test that no fragments pass the occlusion query for a multi-view vertex shader which always
 // transforms geometry to be outside of the clip region.
 TEST_P(MultiviewOcclusionQueryTest, OcclusionQueryNothingVisible)
 {
-    if (!requestMultiviewExtension())
-    {
-        return;
-    }
+    ANGLE_SKIP_TEST_IF(!requestMultiviewExtension());
+    ANGLE_SKIP_TEST_IF(!requestOcclusionQueryExtension());
 
     const std::string vsSource =
         "#version 300 es\n"
         "#extension GL_OVR_multiview : require\n"
         "layout(num_views = 2) in;\n"
         "in vec3 vPosition;\n"
         "void main()\n"
         "{\n"
@@ -1224,20 +1245,18 @@ TEST_P(MultiviewOcclusionQueryTest, Occl
     ASSERT_GL_NO_ERROR();
     EXPECT_GL_FALSE(result);
 }
 
 // Test that there are fragments passing the occlusion query if only view 0 can produce
 // output.
 TEST_P(MultiviewOcclusionQueryTest, OcclusionQueryOnlyLeftVisible)
 {
-    if (!requestMultiviewExtension())
-    {
-        return;
-    }
+    ANGLE_SKIP_TEST_IF(!requestMultiviewExtension());
+    ANGLE_SKIP_TEST_IF(!requestOcclusionQueryExtension());
 
     const std::string vsSource =
         "#version 300 es\n"
         "#extension GL_OVR_multiview : require\n"
         "layout(num_views = 2) in;\n"
         "in vec3 vPosition;\n"
         "void main()\n"
         "{\n"
@@ -1261,20 +1280,18 @@ TEST_P(MultiviewOcclusionQueryTest, Occl
     ASSERT_GL_NO_ERROR();
     EXPECT_GL_TRUE(result);
 }
 
 // Test that there are fragments passing the occlusion query if only view 1 can produce
 // output.
 TEST_P(MultiviewOcclusionQueryTest, OcclusionQueryOnlyRightVisible)
 {
-    if (!requestMultiviewExtension())
-    {
-        return;
-    }
+    ANGLE_SKIP_TEST_IF(!requestMultiviewExtension());
+    ANGLE_SKIP_TEST_IF(!requestOcclusionQueryExtension());
 
     const std::string vsSource =
         "#version 300 es\n"
         "#extension GL_OVR_multiview : require\n"
         "layout(num_views = 2) in;\n"
         "in vec3 vPosition;\n"
         "void main()\n"
         "{\n"
@@ -1406,16 +1423,19 @@ TEST_P(MultiviewProgramGenerationTest, U
 // The test checks that GL_POINTS is correctly rendered.
 TEST_P(MultiviewRenderPrimitiveTest, Points)
 {
     if (!requestMultiviewExtension())
     {
         return;
     }
 
+    // Test failing on P400 graphics card (anglebug.com/2228)
+    ANGLE_SKIP_TEST_IF(IsWindows() && IsD3D11() && IsNVIDIA());
+
     const std::string vsSource =
         "#version 300 es\n"
         "#extension GL_OVR_multiview : require\n"
         "layout(num_views = 2) in;\n"
         "layout(location=0) in vec2 vPosition;\n"
         "void main()\n"
         "{\n"
         "   gl_PointSize = 1.0;\n"
@@ -1845,16 +1865,19 @@ TEST_P(MultiviewRenderTest, ProgramRelin
 // divisor.
 TEST_P(MultiviewRenderTest, DivisorUpdatedOnProgramChange)
 {
     if (!requestMultiviewExtension())
     {
         return;
     }
 
+    // Test failing on P400 graphics card (anglebug.com/2228)
+    ANGLE_SKIP_TEST_IF(IsWindows() && IsD3D11() && IsNVIDIA());
+
     GLVertexArray vao;
     glBindVertexArray(vao);
     GLBuffer vbo;
     glBindBuffer(GL_ARRAY_BUFFER, vbo);
     std::vector<Vector2I> windowCoordinates = {Vector2I(0, 0), Vector2I(1, 0), Vector2I(2, 0),
                                                Vector2I(3, 0)};
     std::vector<Vector2> vertexDataInClipSpace =
         ConvertPixelCoordinatesToClipSpace(windowCoordinates, 4, 1);
@@ -1991,16 +2014,19 @@ TEST_P(MultiviewLayeredRenderTest, Rende
 // green for view 1.
 TEST_P(MultiviewRenderTest, FlatInterpolation)
 {
     if (!requestMultiviewExtension())
     {
         return;
     }
 
+    // Test failing on P400 graphics card (anglebug.com/2228)
+    ANGLE_SKIP_TEST_IF(IsWindows() && IsD3D11() && IsNVIDIA());
+
     // TODO(mradev): Find out why this fails on Win10 Intel HD 630 D3D11
     // (http://anglebug.com/2062)
     ANGLE_SKIP_TEST_IF(IsWindows() && IsIntel() && IsD3D11());
 
     const std::string vsSource =
         "#version 300 es\n"
         "#extension GL_OVR_multiview : require\n"
         "layout(num_views = 2) in;\n"
--- a/gfx/angle/src/tests/gl_tests/OcclusionQueriesTest.cpp
+++ b/gfx/angle/src/tests/gl_tests/OcclusionQueriesTest.cpp
@@ -96,17 +96,17 @@ TEST_P(OcclusionQueriesTest, IsOccluded)
 
     GLuint result = GL_TRUE;
     glGetQueryObjectuivEXT(query, GL_QUERY_RESULT_EXT, &result);
 
     EXPECT_GL_NO_ERROR();
 
     glDeleteQueriesEXT(1, &query);
 
-    EXPECT_GLENUM_EQ(GL_FALSE, result);
+    EXPECT_GL_FALSE(result);
 }
 
 TEST_P(OcclusionQueriesTest, IsNotOccluded)
 {
     if (getClientMajorVersion() < 3 && !extensionEnabled("GL_EXT_occlusion_query_boolean"))
     {
         std::cout << "Test skipped because ES3 or GL_EXT_occlusion_query_boolean are not available."
                   << std::endl;
@@ -130,17 +130,17 @@ TEST_P(OcclusionQueriesTest, IsNotOcclud
 
     GLuint result = GL_TRUE;
     glGetQueryObjectuivEXT(query, GL_QUERY_RESULT_EXT, &result); // will block waiting for result
 
     EXPECT_GL_NO_ERROR();
 
     glDeleteQueriesEXT(1, &query);
 
-    EXPECT_GLENUM_EQ(GL_TRUE, result);
+    EXPECT_GL_TRUE(result);
 }
 
 TEST_P(OcclusionQueriesTest, Errors)
 {
     if (getClientMajorVersion() < 3 && !extensionEnabled("GL_EXT_occlusion_query_boolean"))
     {
         std::cout << "Test skipped because ES3 or GL_EXT_occlusion_query_boolean are not available."
                   << std::endl;
@@ -151,43 +151,43 @@ TEST_P(OcclusionQueriesTest, Errors)
     glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
 
     EXPECT_GL_NO_ERROR();
 
     GLuint query = 0;
     GLuint query2 = 0;
     glGenQueriesEXT(1, &query);
 
-    EXPECT_EQ(glIsQueryEXT(query), GL_FALSE);
-    EXPECT_EQ(glIsQueryEXT(query2), GL_FALSE);
+    EXPECT_GL_FALSE(glIsQueryEXT(query));
+    EXPECT_GL_FALSE(glIsQueryEXT(query2));
 
     glBeginQueryEXT(GL_ANY_SAMPLES_PASSED_EXT, 0); // can't pass 0 as query id
     EXPECT_GL_ERROR(GL_INVALID_OPERATION);
 
     glBeginQueryEXT(GL_ANY_SAMPLES_PASSED_EXT, query);
     glBeginQueryEXT(GL_ANY_SAMPLES_PASSED_CONSERVATIVE_EXT, query2); // can't initiate a query while one's already active
     EXPECT_GL_ERROR(GL_INVALID_OPERATION);
 
-    EXPECT_EQ(glIsQueryEXT(query), GL_TRUE);
-    EXPECT_EQ(glIsQueryEXT(query2), GL_FALSE); // have not called begin
+    EXPECT_GL_TRUE(glIsQueryEXT(query));
+    EXPECT_GL_FALSE(glIsQueryEXT(query2));  // have not called begin
 
     drawQuad(mProgram, "position", 0.8f); // this quad should not be occluded
     glEndQueryEXT(GL_ANY_SAMPLES_PASSED_CONSERVATIVE_EXT); // no active query for this target
     EXPECT_GL_ERROR(GL_INVALID_OPERATION);
     glEndQueryEXT(GL_ANY_SAMPLES_PASSED_EXT);
 
     glBeginQueryEXT(GL_ANY_SAMPLES_PASSED_CONSERVATIVE_EXT, query); // can't begin a query as a different type than previously used
     EXPECT_GL_ERROR(GL_INVALID_OPERATION);
 
     glBeginQueryEXT(GL_ANY_SAMPLES_PASSED_CONSERVATIVE_EXT, query2); // have to call genqueries first
     EXPECT_GL_ERROR(GL_INVALID_OPERATION);
 
     glGenQueriesEXT(1, &query2);
     glBeginQueryEXT(GL_ANY_SAMPLES_PASSED_CONSERVATIVE_EXT, query2); // should be ok now
-    EXPECT_EQ(glIsQueryEXT(query2), GL_TRUE);
+    EXPECT_GL_TRUE(glIsQueryEXT(query2));
 
     drawQuad(mProgram, "position", 0.3f); // this should draw in front of other quad
     glDeleteQueriesEXT(1, &query2); // should delete when query becomes inactive
     glEndQueryEXT(GL_ANY_SAMPLES_PASSED_CONSERVATIVE_EXT); // should not incur error; should delete query + 1 at end of execution.
     EXPECT_GL_NO_ERROR();
 
     swapBuffers();
 
--- a/gfx/angle/src/tests/gl_tests/PathRenderingTest.cpp
+++ b/gfx/angle/src/tests/gl_tests/PathRenderingTest.cpp
@@ -257,17 +257,17 @@ TEST_P(CHROMIUMPathRenderingTest, TestPa
 
     GLuint path = glGenPathsCHROMIUM(1);
 
     // specify the data.
     GLubyte commands[] = {GL_MOVE_TO_CHROMIUM, GL_CLOSE_PATH_CHROMIUM};
     GLfloat coords[] = {50.0f, 50.0f};
     glPathCommandsCHROMIUM(path, 2, commands, 2, GL_FLOAT, coords);
     ASSERT_GL_NO_ERROR();
-    EXPECT_TRUE(glIsPathCHROMIUM(path) == GL_TRUE);
+    EXPECT_GL_TRUE(glIsPathCHROMIUM(path));
 
     static const GLenum kEndCaps[] = {GL_FLAT_CHROMIUM, GL_SQUARE_CHROMIUM, GL_ROUND_CHROMIUM};
     for (std::size_t i = 0; i < 3; ++i)
     {
         GLint x;
         glPathParameteriCHROMIUM(path, GL_PATH_END_CAPS_CHROMIUM, static_cast<GLenum>(kEndCaps[i]));
         ASSERT_GL_NO_ERROR();
         glGetPathParameterivCHROMIUM(path, GL_PATH_END_CAPS_CHROMIUM, &x);
@@ -355,42 +355,42 @@ TEST_P(CHROMIUMPathRenderingTest, TestPa
     glPathStencilFuncCHROMIUM(GL_ALWAYS, 0, 0xFF);
     glStencilOp(GL_KEEP, GL_KEEP, GL_ZERO);
     ASSERT_GL_NO_ERROR();
 
     // Test that trying to draw non-existing paths does not produce errors or results.
     GLuint non_existing_paths[] = {0, 55, 74744};
     for (auto &p : non_existing_paths)
     {
-        EXPECT_TRUE(glIsPathCHROMIUM(p) == GL_FALSE);
+        EXPECT_GL_FALSE(glIsPathCHROMIUM(p));
         ASSERT_GL_NO_ERROR();
         tryAllDrawFunctions(p, GL_NO_ERROR);
     }
 
     // Path name marked as used but without path object state causes
     // a GL error upon any draw command.
     GLuint path = glGenPathsCHROMIUM(1);
-    EXPECT_TRUE(glIsPathCHROMIUM(path) == GL_FALSE);
+    EXPECT_GL_FALSE(glIsPathCHROMIUM(path));
     tryAllDrawFunctions(path, GL_INVALID_OPERATION);
     glDeletePathsCHROMIUM(path, 1);
 
     // Document a bit of an inconsistency: path name marked as used but without
     // path object state causes a GL error upon any draw command (tested above).
     // Path name that had path object state, but then was "cleared", still has a
     // path object state, even though the state is empty.
     path = glGenPathsCHROMIUM(1);
-    EXPECT_TRUE(glIsPathCHROMIUM(path) == GL_FALSE);
+    EXPECT_GL_FALSE(glIsPathCHROMIUM(path));
 
     GLubyte commands[] = {GL_MOVE_TO_CHROMIUM, GL_CLOSE_PATH_CHROMIUM};
     GLfloat coords[] = {50.0f, 50.0f};
     glPathCommandsCHROMIUM(path, 2, commands, 2, GL_FLOAT, coords);
-    EXPECT_TRUE(glIsPathCHROMIUM(path) == GL_TRUE);
+    EXPECT_GL_TRUE(glIsPathCHROMIUM(path));
 
     glPathCommandsCHROMIUM(path, 0, nullptr, 0, GL_FLOAT, nullptr);
-    EXPECT_TRUE(glIsPathCHROMIUM(path) == GL_TRUE);  // The surprise.
+    EXPECT_GL_TRUE(glIsPathCHROMIUM(path));  // The surprise.
 
     tryAllDrawFunctions(path, GL_NO_ERROR);
     glDeletePathsCHROMIUM(path, 1);
 
     // Make sure nothing got drawn by the drawing commands that should not produce
     // anything.
     const angle::GLColor black = {0, 0, 0, 0};
     EXPECT_TRUE(CheckPixels(0, 0, kResolution, kResolution, 0, black));
@@ -1629,17 +1629,17 @@ TEST_P(CHROMIUMPathRenderingWithTexturin
 
     glProgramPathFragmentInputGenCHROMIUM(mProgram, -1, kValidGenMode, kInvalidComponents,
                                           kCoefficients16);
     ASSERT_GL_ERROR(GL_INVALID_VALUE);
 
     glDeleteProgram(mProgram);
 
     // Test that using invalid (deleted) program is an invalid operation.
-    EXPECT_FALSE(glIsProgram(mProgram) == GL_FALSE);
+    EXPECT_GL_TRUE(glIsProgram(mProgram));
 
     glProgramPathFragmentInputGenCHROMIUM(mProgram, -1, kValidGenMode, kValidComponents,
                                           kCoefficients16);
     ASSERT_GL_ERROR(GL_INVALID_OPERATION);
 
     glProgramPathFragmentInputGenCHROMIUM(mProgram, -1, kInvalidGenMode, kValidComponents,
                                           kCoefficients16);
     ASSERT_GL_ERROR(GL_INVALID_OPERATION);
@@ -1976,9 +1976,9 @@ ANGLE_INSTANTIATE_TEST(CHROMIUMPathRende
                        ES2_OPENGLES(),
                        ES3_OPENGL(),
                        ES3_OPENGLES());
 
 ANGLE_INSTANTIATE_TEST(CHROMIUMPathRenderingWithTexturingTest,
                        ES2_OPENGL(),
                        ES2_OPENGLES(),
                        ES3_OPENGL(),
-                       ES3_OPENGLES());
\ No newline at end of file
+                       ES3_OPENGLES());
--- a/gfx/angle/src/tests/gl_tests/PointSpritesTest.cpp
+++ b/gfx/angle/src/tests/gl_tests/PointSpritesTest.cpp
@@ -32,23 +32,16 @@ class PointSpritesTest : public ANGLETes
 
     float s2p(float s) { return (s + 1.0f) * 0.5f * (GLfloat)windowWidth; }
 };
 
 // Checks gl_PointCoord and gl_PointSize
 // https://www.khronos.org/registry/webgl/sdk/tests/conformance/glsl/variables/gl-pointcoord.html
 TEST_P(PointSpritesTest, PointCoordAndPointSizeCompliance)
 {
-    // TODO(jmadill): figure out why this fails
-    if (IsIntel() && GetParam() == ES2_D3D9())
-    {
-        std::cout << "Test skipped on Intel due to failures." << std::endl;
-        return;
-    }
-
     // TODO(jmadill): Investigate potential AMD driver bug.
     // http://anglebug.com/1643
     if (IsAMD() && IsDesktopOpenGL() && IsWindows())
     {
         std::cout << "Test skipped on desktop GL AMD Windows." << std::endl;
         return;
     }
 
@@ -149,24 +142,16 @@ TEST_P(PointSpritesTest, PointWithoutAtt
     // TODO(jmadill): Investigate potential AMD driver bug.
     // http://anglebug.com/1643
     if (IsAMD() && IsDesktopOpenGL() && IsWindows())
     {
         std::cout << "Test skipped on desktop GL AMD Windows." << std::endl;
         return;
     }
 
-    // TODO(jmadill): Figure out why this fails on Intel.
-    // http://anglebug.com/1346
-    if (IsIntel() && IsWindows() && (IsD3D11() || IsD3D9()))
-    {
-        std::cout << "Test skipped on Intel Windows D3D." << std::endl;
-        return;
-    }
-
     const std::string fs =
         R"(precision mediump float;
         void main()
         {
             gl_FragColor = vec4(0.0, 1.0, 0.0, 1.0);
         })";
 
     const std::string vs =
--- a/gfx/angle/src/tests/gl_tests/ProgramBinaryTest.cpp
+++ b/gfx/angle/src/tests/gl_tests/ProgramBinaryTest.cpp
@@ -418,19 +418,21 @@ TEST_P(ProgramBinaryES31Test, ProgramBin
     std::vector<uint8_t> binary(programLength);
     glGetProgramBinary(program.get(), programLength, &readLength, &binaryFormat, binary.data());
     ASSERT_GL_NO_ERROR();
 
     EXPECT_EQ(static_cast<GLsizei>(programLength), readLength);
 
     // Load a new program with the binary.
     ANGLE_GL_BINARY_ES3_PROGRAM(binaryProgram, binary, binaryFormat);
+    ASSERT_GL_NO_ERROR();
 
-    // TODO(Xinghua): add dispatch support when available.
-
+    // Dispatch compute with the loaded binary program
+    glUseProgram(binaryProgram.get());
+    glDispatchCompute(8, 4, 2);
     ASSERT_GL_NO_ERROR();
 }
 
 ANGLE_INSTANTIATE_TEST(ProgramBinaryES31Test, ES31_D3D11(), ES31_OPENGL(), ES31_OPENGLES());
 
 class ProgramBinaryTransformFeedbackTest : public ANGLETest
 {
   protected:
@@ -741,18 +743,18 @@ TEST_P(ProgramBinariesAcrossPlatforms, C
     if (eglWindow == nullptr)
     {
         FAIL() << "Failed to create EGL window";
         return;
     }
 
     // If the test is trying to use both the default GPU and WARP, but the default GPU *IS* WARP,
     // then our expectations for the test results will be invalid.
-    if (firstRenderer.eglParameters.deviceType != EGL_PLATFORM_ANGLE_DEVICE_TYPE_WARP_ANGLE &&
-        secondRenderer.eglParameters.deviceType == EGL_PLATFORM_ANGLE_DEVICE_TYPE_WARP_ANGLE)
+    if (firstRenderer.eglParameters.deviceType != EGL_PLATFORM_ANGLE_DEVICE_TYPE_D3D_WARP_ANGLE &&
+        secondRenderer.eglParameters.deviceType == EGL_PLATFORM_ANGLE_DEVICE_TYPE_D3D_WARP_ANGLE)
     {
         std::string rendererString = std::string(reinterpret_cast<const char*>(glGetString(GL_RENDERER)));
         angle::ToLower(&rendererString);
 
         auto basicRenderPos = rendererString.find(std::string("microsoft basic render"));
         auto softwareAdapterPos = rendererString.find(std::string("software adapter"));
 
         if (basicRenderPos != std::string::npos || softwareAdapterPos != std::string::npos)
--- a/gfx/angle/src/tests/gl_tests/ProgramInterfaceTest.cpp
+++ b/gfx/angle/src/tests/gl_tests/ProgramInterfaceTest.cpp
@@ -154,19 +154,19 @@ TEST_P(ProgramInterfaceTestES31, GetReso
         "layout(location = 2) out vec4 oColor[4];\n"
         "void main()\n"
         "{\n"
         "    oColor[0] = color;\n"
         "}";
 
     ANGLE_GL_PROGRAM(program, vertexShaderSource, fragmentShaderSource);
 
-    std::array<GLenum, 5> invalidInterfaces = {{GL_UNIFORM_BLOCK, GL_TRANSFORM_FEEDBACK_VARYING,
-                                                GL_BUFFER_VARIABLE, GL_SHADER_STORAGE_BLOCK,
-                                                GL_ATOMIC_COUNTER_BUFFER}};
+    GLenum invalidInterfaces[] = {GL_UNIFORM_BLOCK, GL_TRANSFORM_FEEDBACK_VARYING,
+                                  GL_BUFFER_VARIABLE, GL_SHADER_STORAGE_BLOCK,
+                                  GL_ATOMIC_COUNTER_BUFFER};
     GLint location;
     for (auto &invalidInterface : invalidInterfaces)
     {
         location = glGetProgramResourceLocation(program, invalidInterface, "any");
         EXPECT_GL_ERROR(GL_INVALID_ENUM);
         EXPECT_EQ(-1, location);
     }
 
@@ -216,51 +216,57 @@ TEST_P(ProgramInterfaceTestES31, GetReso
         "}";
 
     ANGLE_GL_PROGRAM(program, vertexShaderSource, fragmentShaderSource);
 
     GLuint index = glGetProgramResourceIndex(program, GL_PROGRAM_INPUT, "position");
     EXPECT_GL_NO_ERROR();
     EXPECT_NE(GL_INVALID_INDEX, index);
 
-    constexpr int kPropCount = 7;
-    std::array<GLint, kPropCount> params;
+    GLenum props[]    = {GL_TYPE,
+                      GL_ARRAY_SIZE,
+                      GL_LOCATION,
+                      GL_NAME_LENGTH,
+                      GL_REFERENCED_BY_VERTEX_SHADER,
+                      GL_REFERENCED_BY_FRAGMENT_SHADER,
+                      GL_REFERENCED_BY_COMPUTE_SHADER};
+    GLsizei propCount = static_cast<GLsizei>(ArraySize(props));
+    GLint params[ArraySize(props)];
     GLsizei length;
-    std::array<GLenum, kPropCount> props = {
-        {GL_TYPE, GL_ARRAY_SIZE, GL_LOCATION, GL_NAME_LENGTH, GL_REFERENCED_BY_VERTEX_SHADER,
-         GL_REFERENCED_BY_FRAGMENT_SHADER, GL_REFERENCED_BY_COMPUTE_SHADER}};
-    glGetProgramResourceiv(program, GL_PROGRAM_INPUT, index, kPropCount, props.data(), kPropCount,
-                           &length, params.data());
+
+    glGetProgramResourceiv(program, GL_PROGRAM_INPUT, index, propCount, props, propCount, &length,
+                           params);
     EXPECT_GL_NO_ERROR();
-    EXPECT_EQ(kPropCount, length);
-    EXPECT_EQ(GL_FLOAT_VEC4, params[0]);
-    EXPECT_EQ(1, params[1]);
-    EXPECT_EQ(3, params[2]);
-    EXPECT_EQ(9, params[3]);
-    EXPECT_EQ(1, params[4]);
-    EXPECT_EQ(0, params[5]);
-    EXPECT_EQ(0, params[6]);
+    EXPECT_EQ(propCount, length);
+    EXPECT_EQ(GL_FLOAT_VEC4, params[0]);  // type
+    EXPECT_EQ(1, params[1]);              // array_size
+    EXPECT_EQ(3, params[2]);              // location
+    EXPECT_EQ(9, params[3]);              // name_length
+    EXPECT_EQ(1, params[4]);              // referenced_by_vertex_shader
+    EXPECT_EQ(0, params[5]);              // referenced_by_fragment_shader
+    EXPECT_EQ(0, params[6]);              // referenced_by_compute_shader
 
     index = glGetProgramResourceIndex(program, GL_PROGRAM_OUTPUT, "oColor[0]");
     EXPECT_GL_NO_ERROR();
     EXPECT_NE(index, GL_INVALID_INDEX);
-    glGetProgramResourceiv(program, GL_PROGRAM_OUTPUT, index, kPropCount, props.data(),
-                           kPropCount - 1, &length, params.data());
+    // bufSize is smaller than propCount.
+    glGetProgramResourceiv(program, GL_PROGRAM_OUTPUT, index, propCount, props, propCount - 1,
+                           &length, params);
     EXPECT_GL_NO_ERROR();
-    EXPECT_EQ(kPropCount - 1, length);
-    EXPECT_EQ(GL_FLOAT_VEC4, params[0]);
-    EXPECT_EQ(4, params[1]);
-    EXPECT_EQ(2, params[2]);
-    EXPECT_EQ(10, params[3]);
-    EXPECT_EQ(0, params[4]);
-    EXPECT_EQ(1, params[5]);
+    EXPECT_EQ(propCount - 1, length);
+    EXPECT_EQ(GL_FLOAT_VEC4, params[0]);  // type
+    EXPECT_EQ(4, params[1]);              // array_size
+    EXPECT_EQ(2, params[2]);              // location
+    EXPECT_EQ(10, params[3]);             // name_length
+    EXPECT_EQ(0, params[4]);              // referenced_by_vertex_shader
+    EXPECT_EQ(1, params[5]);              // referenced_by_fragment_shader
 
     GLenum invalidOutputProp = GL_OFFSET;
     glGetProgramResourceiv(program, GL_PROGRAM_OUTPUT, index, 1, &invalidOutputProp, 1, &length,
-                           params.data());
+                           params);
     EXPECT_GL_ERROR(GL_INVALID_OPERATION);
 }
 
 // Tests glGetProgramInterfaceiv.
 TEST_P(ProgramInterfaceTestES31, GetProgramInterface)
 {
     const std::string &vertexShaderSource =
         "#version 310 es\n"
@@ -329,10 +335,569 @@ TEST_P(ProgramInterfaceTestES31, GetProg
     glGetProgramInterfaceiv(program, GL_UNIFORM, GL_MAX_NAME_LENGTH, &num);
     EXPECT_GL_NO_ERROR();
     EXPECT_EQ(8, num);  // "ub.mem0"
 
     glGetProgramInterfaceiv(program, GL_UNIFORM, GL_MAX_NUM_ACTIVE_VARIABLES, &num);
     EXPECT_GL_ERROR(GL_INVALID_OPERATION);
 }
 
-ANGLE_INSTANTIATE_TEST(ProgramInterfaceTestES31, ES31_OPENGL(), ES31_D3D11(), ES31_OPENGLES());
+// Tests the resource property query for uniform can be done correctly.
+TEST_P(ProgramInterfaceTestES31, GetUniformProperties)
+{
+    const std::string &vertexShaderSource =
+        "#version 310 es\n"
+        "precision highp float;\n"
+        "uniform layout(location=12) vec4 color;\n"
+        "layout(binding = 2, offset = 4) uniform atomic_uint foo;\n"
+        "void main()\n"
+        "{\n"
+        "    atomicCounterIncrement(foo);\n"
+        "}";
+
+    const std::string &fragmentShaderSource =
+        "#version 310 es\n"
+        "precision highp float;\n"
+        "uniform vec4 color;\n"
+        "out vec4 oColor;\n"
+        "void main()\n"
+        "{\n"
+        "    oColor = color;\n"
+        "}";
+
+    ANGLE_GL_PROGRAM(program, vertexShaderSource, fragmentShaderSource);
+
+    GLuint index = glGetProgramResourceIndex(program, GL_UNIFORM, "color");
+    EXPECT_GL_NO_ERROR();
+    EXPECT_NE(GL_INVALID_INDEX, index);
+
+    GLchar name[64];
+    GLsizei length;
+    glGetProgramResourceName(program, GL_UNIFORM, index, sizeof(name), &length, name);
+    EXPECT_GL_NO_ERROR();
+    EXPECT_EQ(5, length);
+    EXPECT_EQ("color", std::string(name));
+
+    GLint location = glGetProgramResourceLocation(program, GL_UNIFORM, "color");
+    EXPECT_GL_NO_ERROR();
+    EXPECT_EQ(12, location);
+
+    GLenum props[]    = {GL_TYPE,
+                      GL_ARRAY_SIZE,
+                      GL_LOCATION,
+                      GL_NAME_LENGTH,
+                      GL_REFERENCED_BY_VERTEX_SHADER,
+                      GL_REFERENCED_BY_FRAGMENT_SHADER,
+                      GL_REFERENCED_BY_COMPUTE_SHADER,
+                      GL_ARRAY_STRIDE,
+                      GL_BLOCK_INDEX,
+                      GL_IS_ROW_MAJOR,
+                      GL_MATRIX_STRIDE,
+                      GL_OFFSET,
+                      GL_ATOMIC_COUNTER_BUFFER_INDEX};
+    GLsizei propCount = static_cast<GLsizei>(ArraySize(props));
+    GLint params[ArraySize(props)];
+    glGetProgramResourceiv(program, GL_UNIFORM, index, propCount, props, propCount, &length,
+                           params);
+    EXPECT_GL_NO_ERROR();
+    EXPECT_EQ(propCount, length);
+    EXPECT_EQ(GL_FLOAT_VEC4, params[0]);  // type
+    EXPECT_EQ(1, params[1]);              // array_size
+    EXPECT_EQ(12, params[2]);             // location
+    EXPECT_EQ(6, params[3]);              // name_length
+    EXPECT_EQ(0, params[4]);              // referenced_by_vertex_shader
+    EXPECT_EQ(1, params[5]);              // referenced_by_fragment_shader
+    EXPECT_EQ(0, params[6]);              // referenced_by_compute_shader
+    EXPECT_EQ(-1, params[7]);             // array_stride
+    EXPECT_EQ(-1, params[8]);             // block_index
+    EXPECT_EQ(0, params[9]);              // is_row_major
+    EXPECT_EQ(-1, params[10]);            // matrix_stride
+    EXPECT_EQ(-1, params[11]);            // offset
+    EXPECT_EQ(-1, params[12]);            // atomic_counter_buffer_index
+
+    index = glGetProgramResourceIndex(program, GL_UNIFORM, "foo");
+    EXPECT_GL_NO_ERROR();
+    EXPECT_NE(GL_INVALID_INDEX, index);
+
+    glGetProgramResourceName(program, GL_UNIFORM, index, sizeof(name), &length, name);
+    EXPECT_GL_NO_ERROR();
+    EXPECT_EQ(3, length);
+    EXPECT_EQ("foo", std::string(name));
+
+    location = glGetProgramResourceLocation(program, GL_UNIFORM, "foo");
+    EXPECT_GL_NO_ERROR();
+    EXPECT_EQ(-1, location);
+
+    glGetProgramResourceiv(program, GL_UNIFORM, index, propCount, props, propCount, &length,
+                           params);
+    EXPECT_GL_NO_ERROR();
+    EXPECT_EQ(propCount, length);
+    EXPECT_EQ(GL_UNSIGNED_INT_ATOMIC_COUNTER, params[0]);  // type
+    EXPECT_EQ(1, params[1]);                               // array_size
+    EXPECT_EQ(-1, params[2]);                              // location
+    EXPECT_EQ(4, params[3]);                               // name_length
+    EXPECT_EQ(1, params[4]);                               // referenced_by_vertex_shader
+    EXPECT_EQ(0, params[5]);                               // referenced_by_fragment_shader
+    EXPECT_EQ(0, params[6]);                               // referenced_by_compute_shader
+    EXPECT_EQ(0, params[7]);                               // array_stride
+    EXPECT_EQ(-1, params[8]);                              // block_index
+    EXPECT_EQ(0, params[9]);                               // is_row_major
+    EXPECT_EQ(0, params[10]);                              // matrix_stride
+    EXPECT_EQ(4, params[11]);                              // offset
+    EXPECT_NE(-1, params[12]);                             // atomic_counter_buffer_index
+}
+
+// Tests the resource property query for uniform block can be done correctly.
+TEST_P(ProgramInterfaceTestES31, GetUniformBlockProperties)
+{
+    const std::string &vertexShaderSource =
+        "#version 310 es\n"
+        "in vec2 position;\n"
+        "out vec2 v;\n"
+        "layout(binding = 2) uniform blockName {\n"
+        "  float f1;\n"
+        "  float f2;\n"
+        "} instanceName;\n"
+        "void main() {\n"
+        "  v = vec2(instanceName.f1, instanceName.f2);\n"
+        "  gl_Position = vec4(position, 0, 1);\n"
+        "}";
+
+    const std::string &fragmentShaderSource =
+        "#version 310 es\n"
+        "precision highp float;\n"
+        "in vec2 v;\n"
+        "out vec4 color;\n"
+        "void main() {\n"
+        "  color = vec4(v, 0, 1);\n"
+        "}";
+
+    ANGLE_GL_PROGRAM(program, vertexShaderSource, fragmentShaderSource);
+
+    GLuint index = glGetProgramResourceIndex(program, GL_UNIFORM_BLOCK, "blockName");
+    EXPECT_GL_NO_ERROR();
+    EXPECT_NE(GL_INVALID_INDEX, index);
+
+    GLchar name[64];
+    GLsizei length;
+    glGetProgramResourceName(program, GL_UNIFORM_BLOCK, index, sizeof(name), &length, name);
+    EXPECT_GL_NO_ERROR();
+    EXPECT_EQ(9, length);
+    EXPECT_EQ("blockName", std::string(name));
+
+    GLenum props[]         = {GL_BUFFER_BINDING,
+                      GL_BUFFER_DATA_SIZE,
+                      GL_NAME_LENGTH,
+                      GL_NUM_ACTIVE_VARIABLES,
+                      GL_ACTIVE_VARIABLES,
+                      GL_REFERENCED_BY_VERTEX_SHADER,
+                      GL_REFERENCED_BY_FRAGMENT_SHADER,
+                      GL_REFERENCED_BY_COMPUTE_SHADER};
+    GLsizei propCount      = static_cast<GLsizei>(ArraySize(props));
+    constexpr int kBufSize = 256;
+    GLint params[kBufSize];
+    GLint magic = 0xBEEF;
+
+    // Tests bufSize is respected even some prop returns more than one value.
+    params[propCount] = magic;
+    glGetProgramResourceiv(program, GL_UNIFORM_BLOCK, index, propCount, props, propCount, &length,
+                           params);
+    EXPECT_GL_NO_ERROR();
+    EXPECT_EQ(propCount, length);
+    EXPECT_EQ(2, params[0]);   // buffer_binding
+    EXPECT_NE(0, params[1]);   // buffer_data_size
+    EXPECT_EQ(10, params[2]);  // name_length
+    EXPECT_EQ(2, params[3]);   // num_active_variables
+    EXPECT_LE(0, params[4]);   // index of 'f1' or 'f2'
+    EXPECT_LE(0, params[5]);   // index of 'f1' or 'f2'
+    EXPECT_EQ(1, params[6]);   // referenced_by_vertex_shader
+    EXPECT_EQ(0, params[7]);   // referenced_by_fragment_shader
+    EXPECT_EQ(magic, params[8]);
+
+    glGetProgramResourceiv(program, GL_UNIFORM_BLOCK, index, propCount, props, kBufSize, &length,
+                           params);
+    EXPECT_GL_NO_ERROR();
+    EXPECT_EQ(propCount + 1, length);
+    EXPECT_EQ(0, params[8]);  // referenced_by_compute_shader
+
+    // bufSize is reached in middle of outputting values for GL_ACTIVE_VARIABLES.
+    GLenum actvieVariablesProperty = GL_ACTIVE_VARIABLES;
+    params[1]                      = magic;
+    glGetProgramResourceiv(program, GL_UNIFORM_BLOCK, index, 1, &actvieVariablesProperty, 1,
+                           &length, params);
+    EXPECT_GL_NO_ERROR();
+    EXPECT_EQ(1, length);
+    EXPECT_LE(0, params[0]);  // index of 'f1' or 'f2'
+    EXPECT_EQ(magic, params[1]);
+}
+
+// Tests atomic counter buffer qeury works correctly.
+TEST_P(ProgramInterfaceTestES31, QueryAtomicCounteBuffer)
+{
+    const std::string &vertShader =
+        "#version 310 es\n"
+        "precision highp float;\n"
+        "layout(binding = 2, offset = 0) uniform atomic_uint vcounter;\n"
+        "in highp vec4 a_position;\n"
+        "void main()\n"
+        "{\n"
+        "    atomicCounterIncrement(vcounter);\n"
+        "    gl_Position = a_position;\n"
+        "}\n";
+
+    const std::string &fragShader =
+        "#version 310 es\n"
+        "precision highp float;\n"
+        "layout(binding = 2, offset = 4) uniform atomic_uint fcounter;\n"
+        "out highp vec4 my_color;\n"
+        "void main()\n"
+        "{\n"
+        "    atomicCounterDecrement(fcounter);\n"
+        "    my_color = vec4(0.0);\n"
+        "}\n";
+
+    ANGLE_GL_PROGRAM(program, vertShader, fragShader);
+    GLint num;
+    glGetProgramInterfaceiv(program, GL_ATOMIC_COUNTER_BUFFER, GL_ACTIVE_RESOURCES, &num);
+    EXPECT_GL_NO_ERROR();
+    EXPECT_EQ(1, num);
+
+    glGetProgramInterfaceiv(program, GL_ATOMIC_COUNTER_BUFFER, GL_MAX_NUM_ACTIVE_VARIABLES, &num);
+    EXPECT_GL_NO_ERROR();
+    EXPECT_EQ(2, num);
+
+    GLenum props[]    = {GL_BUFFER_BINDING, GL_NUM_ACTIVE_VARIABLES, GL_REFERENCED_BY_VERTEX_SHADER,
+                      GL_REFERENCED_BY_FRAGMENT_SHADER, GL_REFERENCED_BY_COMPUTE_SHADER};
+    GLsizei propCount = static_cast<GLsizei>(ArraySize(props));
+    GLint params[ArraySize(props)];
+    GLsizei length = 0;
+    glGetProgramResourceiv(program, GL_ATOMIC_COUNTER_BUFFER, 0, propCount, props, propCount,
+                           &length, params);
+    EXPECT_GL_NO_ERROR();
+    EXPECT_EQ(propCount, length);
+    EXPECT_EQ(2, params[0]);  // buffer_binding
+    EXPECT_EQ(2, params[1]);  // num_active_variables
+    EXPECT_EQ(1, params[2]);  // referenced_by_vertex_shader
+    EXPECT_EQ(1, params[3]);  // referenced_by_fragment_shader
+    EXPECT_EQ(0, params[4]);  // referenced_by_compute_shader
+}
+
+// Tests the resource property query for buffer variable can be done correctly.
+TEST_P(ProgramInterfaceTestES31, GetBufferVariableProperties)
+{
+    const std::string &vertexShaderSource =
+        "#version 310 es\n"
+        "precision highp float;\n"
+        "struct S {\n"
+        "    vec3 a;\n"
+        "    ivec2 b[4];\n"
+        "};\n"
+        "layout(std140) buffer blockName0 {\n"
+        "    S s0;\n"
+        "    vec2 v0;\n"
+        "    S s1[2];\n"
+        "    uint u0;\n"
+        "};\n"
+        "layout(binding = 1) buffer blockName1 {\n"
+        "    uint u1[2];\n"
+        "    float f1;\n"
+        "} instanceName1[2];\n"
+        "void main()\n"
+        "{\n"
+        "    gl_Position = vec4(instanceName1[0].f1, s1[0].a);\n"
+        "}\n";
+
+    const std::string &fragmentShaderSource =
+        "#version 310 es\n"
+        "precision highp float;\n"
+        "layout(binding = 1) buffer blockName1 {\n"
+        "    uint u1[2];\n"
+        "    float f1;\n"
+        "} instanceName1[2];\n"
+        "out vec4 oColor;\n"
+        "void main()\n"
+        "{\n"
+        "    oColor = vec4(instanceName1[0].f1, 0, 0, 1);\n"
+        "}";
+
+    ANGLE_GL_PROGRAM(program, vertexShaderSource, fragmentShaderSource);
+
+    GLuint index = glGetProgramResourceIndex(program, GL_BUFFER_VARIABLE, "blockName1.f1");
+    EXPECT_GL_NO_ERROR();
+    EXPECT_NE(GL_INVALID_INDEX, index);
+
+    GLchar name[64];
+    GLsizei length;
+    glGetProgramResourceName(program, GL_BUFFER_VARIABLE, index, sizeof(name), &length, name);
+    EXPECT_GL_NO_ERROR();
+    EXPECT_EQ(13, length);
+    EXPECT_EQ("blockName1.f1", std::string(name));
+
+    GLenum props[]         = {GL_ARRAY_SIZE,
+                      GL_ARRAY_STRIDE,
+                      GL_BLOCK_INDEX,
+                      GL_IS_ROW_MAJOR,
+                      GL_MATRIX_STRIDE,
+                      GL_NAME_LENGTH,
+                      GL_OFFSET,
+                      GL_REFERENCED_BY_VERTEX_SHADER,
+                      GL_REFERENCED_BY_FRAGMENT_SHADER,
+                      GL_REFERENCED_BY_COMPUTE_SHADER,
+                      GL_TOP_LEVEL_ARRAY_SIZE,
+                      GL_TOP_LEVEL_ARRAY_STRIDE,
+                      GL_TYPE};
+    GLsizei propCount      = static_cast<GLsizei>(ArraySize(props));
+    constexpr int kBufSize = 256;
+    GLint params[kBufSize];
+
+    glGetProgramResourceiv(program, GL_BUFFER_VARIABLE, index, propCount, props, kBufSize, &length,
+                           params);
+    EXPECT_GL_NO_ERROR();
+    EXPECT_EQ(propCount, length);
+    EXPECT_EQ(1, params[0]);   // array_size
+    EXPECT_LE(0, params[1]);   // array_stride
+    EXPECT_LE(0, params[2]);   // block_index
+    EXPECT_EQ(0, params[3]);   // is_row_major
+    EXPECT_EQ(0, params[4]);   // matrix_stride
+    EXPECT_EQ(14, params[5]);  // name_length
+    EXPECT_LE(0, params[6]);   // offset
+
+    // TODO(jiajia.qin@intel.com): Enable them once the block member staticUse are implemented.
+    // EXPECT_EQ(1, params[7]);  // referenced_by_vertex_shader
+    // EXPECT_EQ(1, params[8]);  // referenced_by_fragment_shader
+    // EXPECT_EQ(0, params[9]);  // referenced_by_compute_shader
+
+    EXPECT_EQ(1, params[10]);  // top_level_array_size
+    EXPECT_LE(0, params[11]);  // top_level_array_stride
+
+    EXPECT_EQ(GL_FLOAT, params[12]);  // type
+
+    index = glGetProgramResourceIndex(program, GL_BUFFER_VARIABLE, "s1[0].a");
+    EXPECT_GL_NO_ERROR();
+    EXPECT_NE(GL_INVALID_INDEX, index);
+
+    glGetProgramResourceName(program, GL_BUFFER_VARIABLE, index, sizeof(name), &length, name);
+    EXPECT_GL_NO_ERROR();
+    EXPECT_EQ(7, length);
+    EXPECT_EQ("s1[0].a", std::string(name));
+
+    glGetProgramResourceiv(program, GL_BUFFER_VARIABLE, index, propCount, props, kBufSize, &length,
+                           params);
+    EXPECT_GL_NO_ERROR();
+    EXPECT_EQ(propCount, length);
+    EXPECT_EQ(1, params[0]);  // array_size
+    EXPECT_LE(0, params[1]);  // array_stride
+    EXPECT_LE(0, params[2]);  // block_index
+    EXPECT_EQ(0, params[3]);  // is_row_major
+    EXPECT_EQ(0, params[4]);  // matrix_stride
+    EXPECT_EQ(8, params[5]);  // name_length
+    EXPECT_LE(0, params[6]);  // offset
+
+    // TODO(jiajia.qin@intel.com): Enable them once the block member staticUse are implemented.
+    // EXPECT_EQ(1, params[7]);  // referenced_by_vertex_shader
+    // EXPECT_EQ(0, params[8]);  // referenced_by_fragment_shader
+    // EXPECT_EQ(0, params[9]);  // referenced_by_compute_shader
+
+    EXPECT_EQ(2, params[10]);   // top_level_array_size
+    EXPECT_EQ(80, params[11]);  // top_level_array_stride
+
+    EXPECT_EQ(GL_FLOAT_VEC3, params[12]);  // type
+}
+
+// Tests the resource property query for shader storage block can be done correctly.
+TEST_P(ProgramInterfaceTestES31, GetShaderStorageBlockProperties)
+{
+    const std::string &vertexShaderSource =
+        "#version 310 es\n"
+        "precision highp float;\n"
+        "struct S {\n"
+        "    vec3 a;\n"
+        "    ivec2 b[4];\n"
+        "};\n"
+        "layout(std140) buffer blockName0 {\n"
+        "    S s0;\n"
+        "    vec2 v0;\n"
+        "    S s1[2];\n"
+        "    uint u0;\n"
+        "};\n"
+        "layout(binding = 1) buffer blockName1 {\n"
+        "    uint u1[2];\n"
+        "    float f1;\n"
+        "} instanceName1[2];\n"
+        "layout(binding = 2) buffer blockName2 {\n"
+        "    uint u2;\n"
+        "    float f2;\n"
+        "};\n"
+        "void main()\n"
+        "{\n"
+        "    gl_Position = vec4(instanceName1[0].f1, s1[0].a);\n"
+        "}\n";
+
+    const std::string &fragmentShaderSource =
+        "#version 310 es\n"
+        "precision highp float;\n"
+        "uniform vec4 color;\n"
+        "out vec4 oColor;\n"
+        "void main()\n"
+        "{\n"
+        "    oColor = color;\n"
+        "}";
+
+    ANGLE_GL_PROGRAM(program, vertexShaderSource, fragmentShaderSource);
+
+    GLuint index = glGetProgramResourceIndex(program, GL_SHADER_STORAGE_BLOCK, "blockName0");
+    EXPECT_GL_NO_ERROR();
+    EXPECT_NE(GL_INVALID_INDEX, index);
+
+    GLchar name[64];
+    GLsizei length;
+    glGetProgramResourceName(program, GL_SHADER_STORAGE_BLOCK, index, sizeof(name), &length, name);
+    EXPECT_GL_NO_ERROR();
+    EXPECT_EQ(10, length);
+    EXPECT_EQ("blockName0", std::string(name));
+
+    GLenum props[]         = {GL_ACTIVE_VARIABLES,
+                      GL_BUFFER_BINDING,
+                      GL_NUM_ACTIVE_VARIABLES,
+                      GL_BUFFER_DATA_SIZE,
+                      GL_NAME_LENGTH,
+                      GL_REFERENCED_BY_VERTEX_SHADER,
+                      GL_REFERENCED_BY_FRAGMENT_SHADER,
+                      GL_REFERENCED_BY_COMPUTE_SHADER};
+    GLsizei propCount      = static_cast<GLsizei>(ArraySize(props));
+    constexpr int kBufSize = 256;
+    GLint params[kBufSize];
+
+    glGetProgramResourceiv(program, GL_SHADER_STORAGE_BLOCK, index, propCount, props, kBufSize,
+                           &length, params);
+    EXPECT_GL_NO_ERROR();
+    EXPECT_EQ(13, length);
+    EXPECT_LE(0, params[0]);   // active_variables s0.a
+    EXPECT_LE(0, params[1]);   // active_variables s0.b
+    EXPECT_LE(0, params[2]);   // active_variables v0
+    EXPECT_LE(0, params[3]);   // active_variables s1[0].a
+    EXPECT_LE(0, params[4]);   // active_variables s1[0].b
+    EXPECT_LE(0, params[5]);   // active_variables u0
+    EXPECT_EQ(0, params[6]);   // buffer_binding
+    EXPECT_EQ(6, params[7]);   // num_active_variables
+    EXPECT_LE(0, params[8]);   // buffer_data_size
+    EXPECT_EQ(11, params[9]);  // name_length
+
+    EXPECT_EQ(1, params[10]);  // referenced_by_vertex_shader
+    EXPECT_EQ(0, params[11]);  // referenced_by_fragment_shader
+    EXPECT_EQ(0, params[12]);  // referenced_by_compute_shader
+
+    index = glGetProgramResourceIndex(program, GL_SHADER_STORAGE_BLOCK, "blockName1");
+    EXPECT_GL_NO_ERROR();
+    EXPECT_NE(GL_INVALID_INDEX, index);
+
+    glGetProgramResourceName(program, GL_SHADER_STORAGE_BLOCK, index, sizeof(name), &length, name);
+    EXPECT_GL_NO_ERROR();
+    EXPECT_EQ(13, length);
+    EXPECT_EQ("blockName1[0]", std::string(name));
+}
+
+// Tests transform feedback varying qeury works correctly.
+TEST_P(ProgramInterfaceTestES31, QueryTransformFeedbackVarying)
+{
+    const std::string &vertexShaderSource =
+        R"(#version 310 es
+
+        in vec3 position;\
+        out float outSingleType;
+        out vec2 outWholeArray[2];
+        out vec3 outArrayElements[16];
+        void main() {
+          outSingleType = 0.0;
+          outWholeArray[0] = vec2(position);
+          outArrayElements[7] = vec3(0, 0, 0);
+          outArrayElements[15] = position;
+          gl_Position = vec4(position, 1);
+        })";
+
+    const std::string &fragmentShaderSource =
+        R"(#version 310 es
+
+        precision mediump float;
+        out vec4 color;
+        in float outSingleType;
+        in vec2 outWholeArray[2];
+        in vec3 outArrayElements[16];
+        void main() {
+          color = vec4(0);
+        })";
+
+    std::vector<std::string> tfVaryings;
+    tfVaryings.push_back("outArrayElements[7]");
+    tfVaryings.push_back("outArrayElements[15]");
+    tfVaryings.push_back("outSingleType");
+    tfVaryings.push_back("outWholeArray");
+
+    GLuint program = CompileProgramWithTransformFeedback(vertexShaderSource, fragmentShaderSource,
+                                                         tfVaryings, GL_INTERLEAVED_ATTRIBS);
+    ASSERT_NE(0u, program);
+
+    GLint num;
+    glGetProgramInterfaceiv(program, GL_TRANSFORM_FEEDBACK_VARYING, GL_ACTIVE_RESOURCES, &num);
+    EXPECT_GL_NO_ERROR();
+    EXPECT_EQ(4, num);
+
+    glGetProgramInterfaceiv(program, GL_TRANSFORM_FEEDBACK_VARYING, GL_MAX_NAME_LENGTH, &num);
+    EXPECT_GL_NO_ERROR();
+    EXPECT_EQ(21, num);  // outArrayElements[15]
+
+    // GLES 3.10, Page 77:
+    // For TRANSFORM_FEEDBACK_VARYING, the active resource list will use the variable order
+    // specified in the most recent call to TransformFeedbackVaryings before the last call to
+    // LinkProgram.
+    GLuint index =
+        glGetProgramResourceIndex(program, GL_TRANSFORM_FEEDBACK_VARYING, "outArrayElements[7]");
+    EXPECT_GL_NO_ERROR();
+    EXPECT_EQ(0u, index);
+    index =
+        glGetProgramResourceIndex(program, GL_TRANSFORM_FEEDBACK_VARYING, "outArrayElements[15]");
+    EXPECT_GL_NO_ERROR();
+    EXPECT_EQ(1u, index);
+    index = glGetProgramResourceIndex(program, GL_TRANSFORM_FEEDBACK_VARYING, "outSingleType");
+    EXPECT_GL_NO_ERROR();
+    EXPECT_EQ(2u, index);
+    index = glGetProgramResourceIndex(program, GL_TRANSFORM_FEEDBACK_VARYING, "outWholeArray");
+    EXPECT_GL_NO_ERROR();
+    EXPECT_EQ(3u, index);
+
+    // GLES 3.10, Page 80:
+    // For TRANSFORM_FEEDBACK_VARYING resources, name must match one of the variables to be captured
+    // as specified by a previous call to TransformFeedbackVaryings. Otherwise, INVALID_INDEX is
+    // returned.
+    // If name does not match a resource as described above, the value INVALID_INDEX is returned,
+    // but no GL error is generated.
+    index = glGetProgramResourceIndex(program, GL_TRANSFORM_FEEDBACK_VARYING, "outWholeArray[0]");
+    EXPECT_GL_NO_ERROR();
+    EXPECT_EQ(GL_INVALID_INDEX, index);
+
+    GLenum props[]    = {GL_TYPE, GL_ARRAY_SIZE, GL_NAME_LENGTH};
+    GLsizei propCount = static_cast<GLsizei>(ArraySize(props));
+    GLint params[ArraySize(props)];
+    GLsizei length = 0;
+    // Query properties of 'outArrayElements[15]'.
+    glGetProgramResourceiv(program, GL_TRANSFORM_FEEDBACK_VARYING, 1, propCount, props, propCount,
+                           &length, params);
+    EXPECT_GL_NO_ERROR();
+    EXPECT_EQ(propCount, length);
+    EXPECT_EQ(GL_FLOAT_VEC3, params[0]);  // type
+    EXPECT_EQ(1, params[1]);              // array_size
+    EXPECT_EQ(21, params[2]);             // name_length
+
+    // Query properties of 'outWholeArray'.
+    glGetProgramResourceiv(program, GL_TRANSFORM_FEEDBACK_VARYING, 3, propCount, props, propCount,
+                           &length, params);
+    EXPECT_GL_NO_ERROR();
+    EXPECT_EQ(propCount, length);
+    EXPECT_EQ(GL_FLOAT_VEC2, params[0]);  // type
+    EXPECT_EQ(2, params[1]);              // array_size
+    EXPECT_EQ(14, params[2]);             // name_length
+
+    glDeleteProgram(program);
+}
+
+ANGLE_INSTANTIATE_TEST(ProgramInterfaceTestES31, ES31_OPENGL(), ES31_OPENGLES());
+
 }  // anonymous namespace
--- a/gfx/angle/src/tests/gl_tests/ProgramPipelineTest.cpp
+++ b/gfx/angle/src/tests/gl_tests/ProgramPipelineTest.cpp
@@ -83,31 +83,31 @@ TEST_P(ProgramPipelineTest31, BindProgra
     glDeleteProgramPipelines(1, &pipeline);
     glBindProgramPipeline(pipeline);
     EXPECT_GL_ERROR(GL_INVALID_OPERATION);
 }
 
 // Test IsProgramPipeline
 TEST_P(ProgramPipelineTest31, IsProgramPipelineTest)
 {
-    EXPECT_EQ(GL_FALSE, glIsProgramPipeline(0));
+    EXPECT_GL_FALSE(glIsProgramPipeline(0));
     EXPECT_GL_NO_ERROR();
 
-    EXPECT_EQ(GL_FALSE, glIsProgramPipeline(2));
+    EXPECT_GL_FALSE(glIsProgramPipeline(2));
     EXPECT_GL_NO_ERROR();
 
     GLuint pipeline;
     glGenProgramPipelines(1, &pipeline);
     glBindProgramPipeline(pipeline);
-    EXPECT_EQ(GL_TRUE, glIsProgramPipeline(pipeline));
+    EXPECT_GL_TRUE(glIsProgramPipeline(pipeline));
     EXPECT_GL_NO_ERROR();
 
     glBindProgramPipeline(0);
     glDeleteProgramPipelines(1, &pipeline);
-    EXPECT_EQ(GL_FALSE, glIsProgramPipeline(pipeline));
+    EXPECT_GL_FALSE(glIsProgramPipeline(pipeline));
     EXPECT_GL_NO_ERROR();
 }
 
 ANGLE_INSTANTIATE_TEST(ProgramPipelineTest,
                        ES3_OPENGL(),
                        ES3_OPENGLES(),
                        ES31_OPENGL(),
                        ES31_OPENGLES());
--- a/gfx/angle/src/tests/gl_tests/ReadPixelsTest.cpp
+++ b/gfx/angle/src/tests/gl_tests/ReadPixelsTest.cpp
@@ -222,16 +222,19 @@ TEST_P(ReadPixelsPBOTest, ExistingDataPr
 
     glUnmapBuffer(GL_PIXEL_PACK_BUFFER);
     EXPECT_GL_NO_ERROR();
 }
 
 // Test that calling SubData preserves PBO data.
 TEST_P(ReadPixelsPBOTest, SubDataPreservesContents)
 {
+    // anglebug.com/2185
+    ANGLE_SKIP_TEST_IF(IsOSX() && IsNVIDIA() && IsDesktopOpenGL());
+
     glClearColor(1.0f, 0.0f, 0.0f, 1.0f);
     glClear(GL_COLOR_BUFFER_BIT);
     EXPECT_GL_NO_ERROR();
 
     glBindBuffer(GL_PIXEL_PACK_BUFFER, mPBO);
     glReadPixels(0, 0, 16, 16, GL_RGBA, GL_UNSIGNED_BYTE, 0);
 
     unsigned char data[4] = {1, 2, 3, 4};
@@ -248,22 +251,20 @@ TEST_P(ReadPixelsPBOTest, SubDataPreserv
 
     glUnmapBuffer(GL_ARRAY_BUFFER);
     EXPECT_GL_NO_ERROR();
 }
 
 // Same as the prior test, but with an offset.
 TEST_P(ReadPixelsPBOTest, SubDataOffsetPreservesContents)
 {
-    // TODO: re-enable once root cause of http://anglebug.com/1415 is fixed
-    if (IsAndroid() && IsAdreno() && IsOpenGLES())
-    {
-        std::cout << "Test skipped on Adreno OpenGLES on Android." << std::endl;
-        return;
-    }
+    // anglebug.com/1415
+    ANGLE_SKIP_TEST_IF(IsAndroid() && IsAdreno() && IsOpenGLES());
+    // anglebug.com/2185
+    ANGLE_SKIP_TEST_IF(IsOSX() && IsNVIDIA() && IsDesktopOpenGL());
 
     glClearColor(1.0f, 0.0f, 0.0f, 1.0f);
     glClear(GL_COLOR_BUFFER_BIT);
     EXPECT_GL_NO_ERROR();
 
     glBindBuffer(GL_PIXEL_PACK_BUFFER, mPBO);
     glReadPixels(0, 0, 16, 16, GL_RGBA, GL_UNSIGNED_BYTE, 0);
 
--- a/gfx/angle/src/tests/gl_tests/RendererTest.cpp
+++ b/gfx/angle/src/tests/gl_tests/RendererTest.cpp
@@ -48,17 +48,17 @@ TEST_P(RendererTest, RequestedRendererCr
     {
         ASSERT_NE(rendererString.find(std::string("direct3d9")), std::string::npos);
     }
 
     // Ensure that the major and minor versions trigger expected behavior in D3D11
     if (platform.renderer == EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE)
     {
         // Ensure that the renderer uses WARP, if we requested it.
-        if (platform.deviceType == EGL_PLATFORM_ANGLE_DEVICE_TYPE_WARP_ANGLE)
+        if (platform.deviceType == EGL_PLATFORM_ANGLE_DEVICE_TYPE_D3D_WARP_ANGLE)
         {
             auto basicRenderPos = rendererString.find(std::string("microsoft basic render"));
             auto softwareAdapterPos = rendererString.find(std::string("software adapter"));
             ASSERT_TRUE(basicRenderPos != std::string::npos || softwareAdapterPos != std::string::npos);
         }
 
         std::vector<std::string> acceptableShaderModels;
 
--- a/gfx/angle/src/tests/gl_tests/RobustResourceInitTest.cpp
+++ b/gfx/angle/src/tests/gl_tests/RobustResourceInitTest.cpp
@@ -7,51 +7,208 @@
 
 #include "test_utils/ANGLETest.h"
 
 #include "test_utils/gl_raii.h"
 
 namespace angle
 {
 
+// TODO(jmadill): Would be useful in a shared place in a utils folder.
+void UncompressDXTBlock(int destX,
+                        int destY,
+                        int destWidth,
+                        const std::vector<uint8_t> &src,
+                        int srcOffset,
+                        GLenum format,
+                        std::vector<GLColor> *colorsOut)
+{
+    auto make565 = [src](int offset) {
+        return static_cast<int>(src[offset + 0]) + static_cast<int>(src[offset + 1]) * 256;
+    };
+    auto make8888From565 = [](int c) {
+        return GLColor(
+            static_cast<GLubyte>(floor(static_cast<float>((c >> 11) & 0x1F) * (255.0f / 31.0f))),
+            static_cast<GLubyte>(floor(static_cast<float>((c >> 5) & 0x3F) * (255.0f / 63.0f))),
+            static_cast<GLubyte>(floor(static_cast<float>((c >> 0) & 0x1F) * (255.0f / 31.0f))),
+            255);
+    };
+    auto mix = [](int mult, GLColor c0, GLColor c1, float div) {
+        GLColor r = GLColor::transparentBlack;
+        for (int ii = 0; ii < 4; ++ii)
+        {
+            r[ii] = static_cast<GLubyte>(floor(static_cast<float>(c0[ii] * mult + c1[ii]) / div));
+        }
+        return r;
+    };
+    bool isDXT1 =
+        (format == GL_COMPRESSED_RGB_S3TC_DXT1_EXT) || (format == GL_COMPRESSED_RGBA_S3TC_DXT1_EXT);
+    int colorOffset = srcOffset + (isDXT1 ? 0 : 8);
+    int color0      = make565(colorOffset + 0);
+    int color1      = make565(colorOffset + 2);
+    bool c0gtc1     = color0 > color1 || !isDXT1;
+    GLColor rgba0   = make8888From565(color0);
+    GLColor rgba1   = make8888From565(color1);
+    std::array<GLColor, 4> colors = {{rgba0, rgba1,
+                                      c0gtc1 ? mix(2, rgba0, rgba1, 3) : mix(1, rgba0, rgba1, 2),
+                                      c0gtc1 ? mix(2, rgba1, rgba0, 3) : GLColor::black}};
+
+    // Original comment preserved below for posterity:
+    // "yea I know there is a lot of math in this inner loop. so sue me."
+    for (int yy = 0; yy < 4; ++yy)
+    {
+        uint8_t pixels = src[colorOffset + 4 + yy];
+        for (int xx = 0; xx < 4; ++xx)
+        {
+            uint8_t code     = (pixels >> (xx * 2)) & 0x3;
+            GLColor srcColor = colors[code];
+            uint8_t alpha    = 0;
+            switch (format)
+            {
+                case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
+                    alpha = 255;
+                    break;
+                case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
+                    alpha = (code == 3 && !c0gtc1) ? 0 : 255;
+                    break;
+                case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT:
+                {
+                    uint8_t alpha0 = src[srcOffset + yy * 2 + (xx >> 1)];
+                    uint8_t alpha1 = (alpha0 >> ((xx % 2) * 4)) & 0xF;
+                    alpha          = alpha1 | (alpha1 << 4);
+                }
+                break;
+                case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT:
+                {
+                    uint8_t alpha0 = src[srcOffset + 0];
+                    uint8_t alpha1 = src[srcOffset + 1];
+                    int alphaOff   = (yy >> 1) * 3 + 2;
+                    uint32_t alphaBits =
+                        static_cast<uint32_t>(src[srcOffset + alphaOff + 0]) +
+                        static_cast<uint32_t>(src[srcOffset + alphaOff + 1]) * 256 +
+                        static_cast<uint32_t>(src[srcOffset + alphaOff + 2]) * 65536;
+                    int alphaShift    = (yy % 2) * 12 + xx * 3;
+                    uint8_t alphaCode = static_cast<uint8_t>((alphaBits >> alphaShift) & 0x7);
+                    if (alpha0 > alpha1)
+                    {
+                        switch (alphaCode)
+                        {
+                            case 0:
+                                alpha = alpha0;
+                                break;
+                            case 1:
+                                alpha = alpha1;
+                                break;
+                            default:
+                                // TODO(jmadill): fix rounding
+                                alpha = ((8 - alphaCode) * alpha0 + (alphaCode - 1) * alpha1) / 7;
+                                break;
+                        }
+                    }
+                    else
+                    {
+                        switch (alphaCode)
+                        {
+                            case 0:
+                                alpha = alpha0;
+                                break;
+                            case 1:
+                                alpha = alpha1;
+                                break;
+                            case 6:
+                                alpha = 0;
+                                break;
+                            case 7:
+                                alpha = 255;
+                                break;
+                            default:
+                                // TODO(jmadill): fix rounding
+                                alpha = ((6 - alphaCode) * alpha0 + (alphaCode - 1) * alpha1) / 5;
+                                break;
+                        }
+                    }
+                }
+                break;
+                default:
+                    ASSERT_FALSE(true);
+                    break;
+            }
+            int dstOff           = ((destY + yy) * destWidth + destX + xx);
+            (*colorsOut)[dstOff] = GLColor(srcColor[0], srcColor[1], srcColor[2], alpha);
+        }
+    }
+}
+
+int GetBlockSize(GLenum format)
+{
+    bool isDXT1 =
+        format == GL_COMPRESSED_RGB_S3TC_DXT1_EXT || format == GL_COMPRESSED_RGBA_S3TC_DXT1_EXT;
+    return isDXT1 ? 8 : 16;
+}
+
+std::vector<GLColor> UncompressDXTIntoSubRegion(int width,
+                                                int height,
+                                                int subX0,
+                                                int subY0,
+                                                int subWidth,
+                                                int subHeight,
+                                                const std::vector<uint8_t> &data,
+                                                GLenum format)
+{
+    std::vector<GLColor> dest(width * height, GLColor::transparentBlack);
+
+    if ((width % 4) != 0 || (height % 4) != 0 || (subX0 % 4) != 0 || (subY0 % 4) != 0 ||
+        (subWidth % 4) != 0 || (subHeight % 4) != 0)
+    {
+        std::cout << "Implementation error in UncompressDXTIntoSubRegion.";
+        return dest;
+    }
+
+    int blocksAcross = subWidth / 4;
+    int blocksDown   = subHeight / 4;
+    int blockSize    = GetBlockSize(format);
+    for (int yy = 0; yy < blocksDown; ++yy)
+    {
+        for (int xx = 0; xx < blocksAcross; ++xx)
+        {
+            UncompressDXTBlock(subX0 + xx * 4, subY0 + yy * 4, width, data,
+                               (yy * blocksAcross + xx) * blockSize, format, &dest);
+        }
+    }
+    return dest;
+}
+
 class RobustResourceInitTest : public ANGLETest
 {
   protected:
     constexpr static int kWidth  = 128;
     constexpr static int kHeight = 128;
 
     RobustResourceInitTest()
     {
         setWindowWidth(kWidth);
         setWindowHeight(kHeight);
         setConfigRedBits(8);
         setConfigGreenBits(8);
         setConfigBlueBits(8);
         setConfigAlphaBits(8);
+
+        setRobustResourceInit(true);
     }
 
-    bool hasEGLExtension()
+    bool hasGLExtension()
     {
-        return eglClientExtensionEnabled("EGL_ANGLE_display_robust_resource_initialization");
-    }
-
-    bool hasGLExtension() { return extensionEnabled("GL_ANGLE_robust_resource_initialization"); }
-
-    bool setup()
-    {
-        if (!hasEGLExtension())
+        // Skip all tests on the OpenGL backend. It is not fully implemented but still needs to be
+        // exposed to test in Chromium.
+        if (IsDesktopOpenGL() || IsOpenGLES())
         {
             return false;
         }
 
-        TearDown();
-        setRobustResourceInit(true);
-        SetUp();
-
-        return true;
+        return extensionEnabled("GL_ANGLE_robust_resource_initialization");
     }
 
     void setupTexture(GLTexture *tex);
     void setup3DTexture(GLTexture *tex);
 
     // Checks for uninitialized (non-zero pixels) in a Texture.
     void checkNonZeroPixels(GLTexture *texture,
                             int skipX,
@@ -59,93 +216,115 @@ class RobustResourceInitTest : public AN
                             int skipWidth,
                             int skipHeight,
                             const GLColor &skip);
     void checkNonZeroPixels3D(GLTexture *texture,
                               int skipX,
                               int skipY,
                               int skipWidth,
                               int skipHeight,
+                              int textureLayer,
                               const GLColor &skip);
     void checkFramebufferNonZeroPixels(int skipX,
                                        int skipY,
                                        int skipWidth,
                                        int skipHeight,
                                        const GLColor &skip);
+
+    void checkCustomFramebufferNonZeroPixels(int fboWidth,
+                                             int fboHeight,
+                                             int skipX,
+                                             int skipY,
+                                             int skipWidth,
+                                             int skipHeight,
+                                             const GLColor &skip);
+
+    const std::string kSimpleTextureVertexShader =
+        "#version 300 es\n"
+        "in vec4 position;\n"
+        "out vec2 texcoord;\n"
+        "void main()\n"
+        "{\n"
+        "    gl_Position = position;\n"
+        "    texcoord = vec2(position.xy * 0.5 - 0.5);\n"
+        "}";
+
+    static std::string GetSimpleTextureFragmentShader(const char *samplerType)
+    {
+        std::stringstream fragmentStream;
+        fragmentStream << "#version 300 es\n"
+                          "precision mediump "
+                       << samplerType
+                       << "sampler2D;\n"
+                          "precision mediump float;\n"
+                          "out "
+                       << samplerType
+                       << "vec4 color;\n"
+                          "in vec2 texcoord;\n"
+                          "uniform "
+                       << samplerType
+                       << "sampler2D tex;\n"
+                          "void main()\n"
+                          "{\n"
+                          "    color = texture(tex, texcoord);\n"
+                          "}";
+        return fragmentStream.str();
+    }
+
+    template <typename ClearFunc>
+    void maskedDepthClear(ClearFunc clearFunc);
+
+    template <typename ClearFunc>
+    void maskedStencilClear(ClearFunc clearFunc);
 };
 
-// Display creation should fail if EGL_ANGLE_display_robust_resource_initialization
-// is not available, and succeed otherwise.
-TEST_P(RobustResourceInitTest, ExtensionInit)
+class RobustResourceInitTestES3 : public RobustResourceInitTest
 {
-    if (setup())
+  protected:
+    template <typename PixelT>
+    void testIntegerTextureInit(const char *samplerType,
+                                GLenum internalFormatRGBA,
+                                GLenum internalFormatRGB,
+                                GLenum type);
+};
+
+// Robust resource initialization is not based on hardware support or native extensions, check that
+// it only works on the implemented renderers
+TEST_P(RobustResourceInitTest, ExpectedRendererSupport)
+{
+    bool shouldHaveSupport = IsD3D11() || IsD3D11_FL93() || IsD3D9();
+    EXPECT_EQ(shouldHaveSupport, hasGLExtension());
+}
+
+// Tests of the GL_ROBUST_RESOURCE_INITIALIZATION_ANGLE query.
+TEST_P(RobustResourceInitTest, Queries)
+{
+    // If context extension string exposed, check queries.
+    if (extensionEnabled("GL_ANGLE_robust_resource_initialization"))
     {
-        // Robust resource init extension should be available.
-        EXPECT_TRUE(hasGLExtension());
-
-        // Querying the state value should return true.
         GLboolean enabled = 0;
-        glGetBooleanv(GL_CONTEXT_ROBUST_RESOURCE_INITIALIZATION_ANGLE, &enabled);
-        EXPECT_GL_NO_ERROR();
+        glGetBooleanv(GL_ROBUST_RESOURCE_INITIALIZATION_ANGLE, &enabled);
         EXPECT_GL_TRUE(enabled);
 
-        EXPECT_GL_TRUE(glIsEnabled(GL_CONTEXT_ROBUST_RESOURCE_INITIALIZATION_ANGLE));
+        EXPECT_GL_TRUE(glIsEnabled(GL_ROBUST_RESOURCE_INITIALIZATION_ANGLE));
+        EXPECT_GL_NO_ERROR();
     }
     else
     {
-        // If context extension string exposed, check queries.
-        if (hasGLExtension())
-        {
-            GLboolean enabled = 0;
-            glGetBooleanv(GL_CONTEXT_ROBUST_RESOURCE_INITIALIZATION_ANGLE, &enabled);
-            EXPECT_GL_FALSE(enabled);
-
-            EXPECT_GL_FALSE(glIsEnabled(GL_CONTEXT_ROBUST_RESOURCE_INITIALIZATION_ANGLE));
-            EXPECT_GL_NO_ERROR();
-        }
-        else
-        {
-            // Querying robust resource init should return INVALID_ENUM.
-            GLboolean enabled = 0;
-            glGetBooleanv(GL_CONTEXT_ROBUST_RESOURCE_INITIALIZATION_ANGLE, &enabled);
-            EXPECT_GL_ERROR(GL_INVALID_ENUM);
-        }
+        // Querying robust resource init should return INVALID_ENUM.
+        GLboolean enabled = 0;
+        glGetBooleanv(GL_ROBUST_RESOURCE_INITIALIZATION_ANGLE, &enabled);
+        EXPECT_GL_ERROR(GL_INVALID_ENUM);
     }
 }
 
-// Test queries on a normal, non-robust enabled context.
-TEST_P(RobustResourceInitTest, QueriesOnNonRobustContext)
-{
-    EGLDisplay display = getEGLWindow()->getDisplay();
-    ASSERT_TRUE(display != EGL_NO_DISPLAY);
-
-    if (!hasEGLExtension())
-    {
-        return;
-    }
-
-    // If context extension string exposed, check queries.
-    ASSERT_TRUE(hasGLExtension());
-
-    // Querying robust resource init should return INVALID_ENUM.
-    GLboolean enabled = 0;
-    glGetBooleanv(GL_CONTEXT_ROBUST_RESOURCE_INITIALIZATION_ANGLE, &enabled);
-    EXPECT_GL_FALSE(enabled);
-
-    EXPECT_GL_FALSE(glIsEnabled(GL_CONTEXT_ROBUST_RESOURCE_INITIALIZATION_ANGLE));
-    EXPECT_GL_NO_ERROR();
-}
-
 // Tests that buffers start zero-filled if the data pointer is null.
 TEST_P(RobustResourceInitTest, BufferData)
 {
-    if (!setup())
-    {
-        return;
-    }
+    ANGLE_SKIP_TEST_IF(!hasGLExtension());
 
     GLBuffer buffer;
     glBindBuffer(GL_ARRAY_BUFFER, buffer);
     glBufferData(GL_ARRAY_BUFFER, getWindowWidth() * getWindowHeight() * sizeof(GLfloat), nullptr,
                  GL_STATIC_DRAW);
 
     const std::string &vertexShader =
         "attribute vec2 position;\n"
@@ -180,20 +359,17 @@ TEST_P(RobustResourceInitTest, BufferDat
     glReadPixels(0, 0, getWindowWidth(), getWindowHeight(), GL_RGBA, GL_UNSIGNED_BYTE,
                  actual.data());
     EXPECT_EQ(expected, actual);
 }
 
 // Regression test for passing a zero size init buffer with the extension.
 TEST_P(RobustResourceInitTest, BufferDataZeroSize)
 {
-    if (!setup())
-    {
-        return;
-    }
+    ANGLE_SKIP_TEST_IF(!hasGLExtension());
 
     GLBuffer buffer;
     glBindBuffer(GL_ARRAY_BUFFER, buffer);
     glBufferData(GL_ARRAY_BUFFER, 0, nullptr, GL_STATIC_DRAW);
 }
 
 // The following test code translated from WebGL 1 test:
 // https://www.khronos.org/registry/webgl/sdk/tests/conformance/misc/uninitialized-test.html
@@ -266,42 +442,55 @@ void RobustResourceInitTest::checkNonZer
     checkFramebufferNonZeroPixels(skipX, skipY, skipWidth, skipHeight, skip);
 }
 
 void RobustResourceInitTest::checkNonZeroPixels3D(GLTexture *texture,
                                                   int skipX,
                                                   int skipY,
                                                   int skipWidth,
                                                   int skipHeight,
+                                                  int textureLayer,
                                                   const GLColor &skip)
 {
     glBindTexture(GL_TEXTURE_3D, 0);
     GLFramebuffer fb;
     glBindFramebuffer(GL_FRAMEBUFFER, fb);
-    glFramebufferTextureLayer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, texture->get(), 0, 0);
+    glFramebufferTextureLayer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, texture->get(), 0,
+                              textureLayer);
     EXPECT_GLENUM_EQ(GL_FRAMEBUFFER_COMPLETE, glCheckFramebufferStatus(GL_FRAMEBUFFER));
 
     checkFramebufferNonZeroPixels(skipX, skipY, skipWidth, skipHeight, skip);
 }
 
 void RobustResourceInitTest::checkFramebufferNonZeroPixels(int skipX,
                                                            int skipY,
                                                            int skipWidth,
                                                            int skipHeight,
                                                            const GLColor &skip)
 {
-    std::array<GLColor, kWidth * kHeight> data;
-    glReadPixels(0, 0, kWidth, kHeight, GL_RGBA, GL_UNSIGNED_BYTE, data.data());
+    checkCustomFramebufferNonZeroPixels(kWidth, kHeight, skipX, skipY, skipWidth, skipHeight, skip);
+}
+
+void RobustResourceInitTest::checkCustomFramebufferNonZeroPixels(int fboWidth,
+                                                                 int fboHeight,
+                                                                 int skipX,
+                                                                 int skipY,
+                                                                 int skipWidth,
+                                                                 int skipHeight,
+                                                                 const GLColor &skip)
+{
+    std::vector<GLColor> data(fboWidth * fboHeight);
+    glReadPixels(0, 0, fboWidth, fboHeight, GL_RGBA, GL_UNSIGNED_BYTE, data.data());
 
     int k = 0;
-    for (int y = 0; y < kHeight; ++y)
+    for (int y = 0; y < fboHeight; ++y)
     {
-        for (int x = 0; x < kWidth; ++x)
+        for (int x = 0; x < fboWidth; ++x)
         {
-            int index = (y * kWidth + x);
+            int index = (y * fboWidth + x);
             if (x >= skipX && x < skipX + skipWidth && y >= skipY && y < skipY + skipHeight)
             {
                 ASSERT_EQ(skip, data[index]);
             }
             else
             {
                 k += (data[index] != GLColor::transparentBlack) ? 1 : 0;
             }
@@ -309,50 +498,30 @@ void RobustResourceInitTest::checkFrameb
     }
 
     EXPECT_EQ(0, k);
 }
 
 // Reading an uninitialized texture (texImage2D) should succeed with all bytes set to 0.
 TEST_P(RobustResourceInitTest, ReadingUninitializedTexture)
 {
-    if (!setup())
-    {
-        return;
-    }
-
-    if (IsOpenGL() || IsD3D9())
-    {
-        std::cout << "Robust resource init is not yet fully implemented. (" << GetParam() << ")"
-                  << std::endl;
-        return;
-    }
+    ANGLE_SKIP_TEST_IF(!hasGLExtension());
 
     GLTexture tex;
     setupTexture(&tex);
     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, kWidth, kHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
     checkNonZeroPixels(&tex, 0, 0, 0, 0, GLColor::transparentBlack);
     EXPECT_GL_NO_ERROR();
 }
 
 // Test that calling glTexImage2D multiple times with the same size and no data resets all texture
 // data
 TEST_P(RobustResourceInitTest, ReuploadingClearsTexture)
 {
-    if (!setup())
-    {
-        return;
-    }
-
-    if (IsOpenGL() || IsD3D9())
-    {
-        std::cout << "Robust resource init is not yet fully implemented. (" << GetParam() << ")"
-                  << std::endl;
-        return;
-    }
+    ANGLE_SKIP_TEST_IF(!hasGLExtension());
 
     // Put some data into the texture
     std::array<GLColor, kWidth * kHeight> data;
     data.fill(GLColor::white);
 
     GLTexture tex;
     glBindTexture(GL_TEXTURE_2D, tex);
     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, kWidth, kHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE,
@@ -363,27 +532,17 @@ TEST_P(RobustResourceInitTest, Reuploadi
     checkNonZeroPixels(&tex, 0, 0, 0, 0, GLColor::transparentBlack);
     EXPECT_GL_NO_ERROR();
 }
 
 // Cover the case where null pixel data is uploaded to a texture and then sub image is used to
 // upload partial data
 TEST_P(RobustResourceInitTest, TexImageThenSubImage)
 {
-    if (!setup())
-    {
-        return;
-    }
-
-    if (IsOpenGL() || IsD3D9())
-    {
-        std::cout << "Robust resource init is not yet fully implemented. (" << GetParam() << ")"
-                  << std::endl;
-        return;
-    }
+    ANGLE_SKIP_TEST_IF(!hasGLExtension());
 
     // Put some data into the texture
 
     GLTexture tex;
     glBindTexture(GL_TEXTURE_2D, tex);
     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, kWidth, kHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
 
     // Force the D3D texture to create a storage
@@ -396,54 +555,34 @@ TEST_P(RobustResourceInitTest, TexImageT
     data.fill(GLColor::white);
 
     glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, kWidth / 2, kHeight / 2, GL_RGBA, GL_UNSIGNED_BYTE,
                     data.data());
     checkNonZeroPixels(&tex, 0, 0, kWidth / 2, kHeight / 2, GLColor::white);
     EXPECT_GL_NO_ERROR();
 }
 
-// Reading an uninitialized texture (texImage2D) should succeed with all bytes set to 0.
-TEST_P(RobustResourceInitTest, ReadingUninitialized3DTexture)
+// Reading an uninitialized texture (texImage3D) should succeed with all bytes set to 0.
+TEST_P(RobustResourceInitTestES3, ReadingUninitialized3DTexture)
 {
-    if (!setup() || getClientMajorVersion() < 3)
-    {
-        return;
-    }
-
-    if (IsOpenGL())
-    {
-        std::cout << "Robust resource init is not yet fully implemented. (" << GetParam() << ")"
-                  << std::endl;
-        return;
-    }
+    ANGLE_SKIP_TEST_IF(!hasGLExtension());
 
     GLTexture tex;
     setup3DTexture(&tex);
     glTexImage3D(GL_TEXTURE_3D, 0, GL_RGBA, kWidth, kHeight, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE,
                  nullptr);
-    checkNonZeroPixels3D(&tex, 0, 0, 0, 0, GLColor::transparentBlack);
+    checkNonZeroPixels3D(&tex, 0, 0, 0, 0, 0, GLColor::transparentBlack);
     EXPECT_GL_NO_ERROR();
 }
 
 // Copy of the copytexsubimage3d_texture_wrongly_initialized test that is part of the WebGL2
 // conformance suite: copy-texture-image-webgl-specific.html
-TEST_P(RobustResourceInitTest, CopyTexSubImage3DTextureWronglyInitialized)
+TEST_P(RobustResourceInitTestES3, CopyTexSubImage3DTextureWronglyInitialized)
 {
-    if (!setup() || getClientMajorVersion() < 3)
-    {
-        return;
-    }
-
-    if (IsOpenGL())
-    {
-        std::cout << "Robust resource init is not yet fully implemented. (" << GetParam() << ")"
-                  << std::endl;
-        return;
-    }
+    ANGLE_SKIP_TEST_IF(!hasGLExtension());
 
     constexpr GLint kTextureLayer     = 0;
     constexpr GLint kTextureWidth     = 2;
     constexpr GLint kTextureHeight    = 2;
     constexpr GLint kTextureDepth     = 2;
     constexpr size_t kTextureDataSize = kTextureWidth * kTextureHeight * 4;
 
     GLTexture texture2D;
@@ -467,29 +606,19 @@ TEST_P(RobustResourceInitTest, CopyTexSu
     glFramebufferTextureLayer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, texture3D, 0, kTextureLayer);
     std::array<uint8_t, kTextureDataSize> pixels;
     glReadPixels(0, 0, kTextureWidth, kTextureHeight, GL_RGBA, GL_UNSIGNED_BYTE, pixels.data());
     ASSERT_GL_NO_ERROR();
     EXPECT_EQ(data, pixels);
 }
 
 // Test that binding an EGL surface to a texture does not cause it to be cleared.
-TEST_P(RobustResourceInitTest, BindTexImage)
+TEST_P(RobustResourceInitTestES3, BindTexImage)
 {
-    if (!setup() || getClientMajorVersion() < 3)
-    {
-        return;
-    }
-
-    if (IsOpenGL())
-    {
-        std::cout << "Robust resource init is not yet fully implemented. (" << GetParam() << ")"
-                  << std::endl;
-        return;
-    }
+    ANGLE_SKIP_TEST_IF(!hasGLExtension());
 
     EGLWindow *window  = getEGLWindow();
     EGLSurface surface = window->getSurface();
     EGLDisplay display = window->getDisplay();
     EGLConfig config   = window->getConfig();
     EGLContext context = window->getContext();
 
     EGLint surfaceType = 0;
@@ -529,18 +658,862 @@ TEST_P(RobustResourceInitTest, BindTexIm
     GLFramebuffer fbo;
     glBindFramebuffer(GL_FRAMEBUFFER, fbo);
     glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture, 0);
     EXPECT_PIXEL_COLOR_EQ(0, 0, clearColor);
 
     eglDestroySurface(display, pbuffer);
 }
 
+// Tests that drawing with an uninitialized Texture works as expected.
+TEST_P(RobustResourceInitTest, DrawWithTexture)
+{
+    ANGLE_SKIP_TEST_IF(!hasGLExtension());
+
+    GLTexture texture;
+    glBindTexture(GL_TEXTURE_2D, texture);
+    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, kWidth, kHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
+    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+
+    const std::string &vertexShader =
+        "attribute vec2 position;\n"
+        "varying vec2 texCoord;\n"
+        "void main() {\n"
+        "    gl_Position = vec4(position, 0, 1);\n"
+        "    texCoord = (position * 0.5) + 0.5;\n"
+        "}";
+    const std::string &fragmentShader =
+        "precision mediump float;\n"
+        "varying vec2 texCoord;\n"
+        "uniform sampler2D tex;\n"
+        "void main() {\n"
+        "    gl_FragColor = texture2D(tex, texCoord);\n"
+        "}";
+
+    ANGLE_GL_PROGRAM(program, vertexShader, fragmentShader);
+    drawQuad(program, "position", 0.5f);
+
+    checkFramebufferNonZeroPixels(0, 0, 0, 0, GLColor::black);
+}
+
+// Reading a partially initialized texture (texImage2D) should succeed with all uninitialized bytes
+// set to 0 and initialized bytes untouched.
+TEST_P(RobustResourceInitTest, ReadingPartiallyInitializedTexture)
+{
+    ANGLE_SKIP_TEST_IF(!hasGLExtension());
+
+    GLTexture tex;
+    setupTexture(&tex);
+    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, kWidth, kHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
+    GLColor data(108, 72, 36, 9);
+    glTexSubImage2D(GL_TEXTURE_2D, 0, kWidth / 2, kHeight / 2, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE,
+                    &data.R);
+    checkNonZeroPixels(&tex, kWidth / 2, kHeight / 2, 1, 1, data);
+    EXPECT_GL_NO_ERROR();
+}
+
+// Uninitialized parts of textures initialized via copyTexImage2D should have all bytes set to 0.
+TEST_P(RobustResourceInitTest, UninitializedPartsOfCopied2DTexturesAreBlack)
+{
+    ANGLE_SKIP_TEST_IF(!hasGLExtension());
+
+    GLTexture tex;
+    setupTexture(&tex);
+    GLFramebuffer fbo;
+    glBindFramebuffer(GL_FRAMEBUFFER, fbo);
+    GLRenderbuffer rbo;
+    glBindRenderbuffer(GL_RENDERBUFFER, rbo);
+    constexpr int fboWidth  = 16;
+    constexpr int fboHeight = 16;
+    glRenderbufferStorage(GL_RENDERBUFFER, GL_RGBA4, fboWidth, fboHeight);
+    glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, rbo);
+    EXPECT_GLENUM_EQ(GL_FRAMEBUFFER_COMPLETE, glCheckFramebufferStatus(GL_FRAMEBUFFER));
+    glClearColor(1.0, 0.0, 0.0, 1.0);
+    glClear(GL_COLOR_BUFFER_BIT);
+    EXPECT_GL_NO_ERROR();
+    glCopyTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 0, 0, kWidth, kHeight, 0);
+    checkNonZeroPixels(&tex, 0, 0, fboWidth, fboHeight, GLColor::red);
+    EXPECT_GL_NO_ERROR();
+}
+
+// Reading an uninitialized portion of a texture (copyTexImage2D with negative x and y) should
+// succeed with all bytes set to 0.
+TEST_P(RobustResourceInitTest, ReadingOutOfboundsCopiedTexture)
+{
+    ANGLE_SKIP_TEST_IF(!hasGLExtension());
+
+    GLTexture tex;
+    setupTexture(&tex);
+    GLFramebuffer fbo;
+    glBindFramebuffer(GL_FRAMEBUFFER, fbo);
+    GLRenderbuffer rbo;
+    glBindRenderbuffer(GL_RENDERBUFFER, rbo);
+    constexpr int fboWidth  = 16;
+    constexpr int fboHeight = 16;
+    glRenderbufferStorage(GL_RENDERBUFFER, GL_RGBA4, fboWidth, fboHeight);
+    glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, rbo);
+    EXPECT_GLENUM_EQ(GL_FRAMEBUFFER_COMPLETE, glCheckFramebufferStatus(GL_FRAMEBUFFER));
+    glClearColor(1.0, 0.0, 0.0, 1.0);
+    glClear(GL_COLOR_BUFFER_BIT);
+    EXPECT_GL_NO_ERROR();
+    constexpr int x = -8;
+    constexpr int y = -8;
+    glCopyTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, x, y, kWidth, kHeight, 0);
+    checkNonZeroPixels(&tex, -x, -y, fboWidth, fboHeight, GLColor::red);
+    EXPECT_GL_NO_ERROR();
+}
+
+// Tests resources are initialized properly with multisample resolve.
+TEST_P(RobustResourceInitTestES3, MultisampledDepthInitializedCorrectly)
+{
+    ANGLE_SKIP_TEST_IF(!hasGLExtension());
+
+    const std::string vs = "attribute vec4 position; void main() { gl_Position = position; }";
+    const std::string fs = "void main() { gl_FragColor = vec4(1, 0, 0, 1); }";
+    ANGLE_GL_PROGRAM(program, vs, fs);
+
+    // Make the destination non-multisampled depth FBO.
+    GLTexture color;
+    glBindTexture(GL_TEXTURE_2D, color);
+    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, kWidth, kHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
+
+    GLRenderbuffer depth;
+    glBindRenderbuffer(GL_RENDERBUFFER, depth);
+    glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT16, kWidth, kHeight);
+
+    GLFramebuffer fbo;
+    glBindFramebuffer(GL_FRAMEBUFFER, fbo);
+    glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, color, 0);
+    glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, depth);
+    ASSERT_GLENUM_EQ(GL_FRAMEBUFFER_COMPLETE, glCheckFramebufferStatus(GL_FRAMEBUFFER));
+
+    glClearColor(0, 1, 0, 1);
+    glClearDepthf(0);
+    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
+    ASSERT_GL_NO_ERROR();
+    EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
+
+    // Make the multisampled depth FBO.
+    GLRenderbuffer msDepth;
+    glBindRenderbuffer(GL_RENDERBUFFER, msDepth);
+    glRenderbufferStorageMultisample(GL_RENDERBUFFER, 4, GL_DEPTH_COMPONENT16, kWidth, kHeight);
+
+    GLFramebuffer msFBO;
+    glBindFramebuffer(GL_READ_FRAMEBUFFER, msFBO);
+    glFramebufferRenderbuffer(GL_READ_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, msDepth);
+    ASSERT_GLENUM_EQ(GL_FRAMEBUFFER_COMPLETE, glCheckFramebufferStatus(GL_READ_FRAMEBUFFER));
+
+    // Multisample resolve.
+    glBlitFramebuffer(0, 0, kWidth, kHeight, 0, 0, kWidth, kHeight, GL_DEPTH_BUFFER_BIT,
+                      GL_NEAREST);
+    ASSERT_GL_NO_ERROR();
+
+    // Test drawing with the resolved depth buffer.
+    glBindFramebuffer(GL_FRAMEBUFFER, fbo);
+    glDepthMask(GL_FALSE);
+    glEnable(GL_DEPTH_TEST);
+    glDepthFunc(GL_EQUAL);
+    drawQuad(program, "position", 1.0f);
+    ASSERT_GL_NO_ERROR();
+    EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::red);
+}
+
+// Basic test that textures are initialized correctly.
+TEST_P(RobustResourceInitTest, Texture)
+{
+    ANGLE_SKIP_TEST_IF(!hasGLExtension());
+
+    GLTexture texture;
+    glBindTexture(GL_TEXTURE_2D, texture);
+    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, kWidth, kHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
+
+    GLFramebuffer framebuffer;
+    glBindFramebuffer(GL_FRAMEBUFFER, framebuffer);
+    glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture, 0);
+    checkFramebufferNonZeroPixels(0, 0, 0, 0, GLColor::black);
+}
+
+template <typename PixelT>
+void RobustResourceInitTestES3::testIntegerTextureInit(const char *samplerType,
+                                                       GLenum internalFormatRGBA,
+                                                       GLenum internalFormatRGB,
+                                                       GLenum type)
+{
+    ANGLE_SKIP_TEST_IF(!hasGLExtension());
+
+    ANGLE_GL_PROGRAM(program, kSimpleTextureVertexShader,
+                     GetSimpleTextureFragmentShader(samplerType));
+
+    // Make an RGBA framebuffer.
+    GLTexture framebufferTexture;
+    glBindTexture(GL_TEXTURE_2D, framebufferTexture);
+    glTexImage2D(GL_TEXTURE_2D, 0, internalFormatRGBA, kWidth, kHeight, 0, GL_RGBA_INTEGER, type,
+                 nullptr);
+    ASSERT_GL_NO_ERROR();
+
+    GLFramebuffer framebuffer;
+    glBindFramebuffer(GL_FRAMEBUFFER, framebuffer);
+    glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, framebufferTexture,
+                           0);
+
+    // Make an RGB texture.
+    GLTexture texture;
+    glBindTexture(GL_TEXTURE_2D, texture);
+    glTexImage2D(GL_TEXTURE_2D, 0, internalFormatRGB, kWidth, kHeight, 0, GL_RGB_INTEGER, type,
+                 nullptr);
+    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+    ASSERT_GL_NO_ERROR();
+
+    // Blit from the texture to the framebuffer.
+    drawQuad(program, "position", 0.5f);
+
+    std::array<PixelT, kWidth * kHeight * 4> data;
+    glReadPixels(0, 0, kWidth, kHeight, GL_RGBA_INTEGER, type, data.data());
+
+    // Check the color channels are zero and the alpha channel is 1.
+    int incorrectPixels = 0;
+    for (int y = 0; y < kHeight; ++y)
+    {
+        for (int x = 0; x < kWidth; ++x)
+        {
+            int index    = (y * kWidth + x) * 4;
+            bool correct = (data[index] == 0 && data[index + 1] == 0 && data[index + 2] == 0 &&
+                            data[index + 3] == 1);
+            incorrectPixels += (!correct ? 1 : 0);
+        }
+    }
+
+    ASSERT_GL_NO_ERROR();
+    EXPECT_EQ(0, incorrectPixels);
+}
+
+// Simple tests for integer formats that ANGLE must emulate on D3D11.
+TEST_P(RobustResourceInitTestES3, TextureInit_UIntRGB8)
+{
+    ANGLE_SKIP_TEST_IF(!hasGLExtension());
+    testIntegerTextureInit<uint8_t>("u", GL_RGBA8UI, GL_RGB8UI, GL_UNSIGNED_BYTE);
+}
+
+TEST_P(RobustResourceInitTestES3, TextureInit_UIntRGB32)
+{
+    ANGLE_SKIP_TEST_IF(!hasGLExtension());
+    testIntegerTextureInit<uint32_t>("u", GL_RGBA32UI, GL_RGB32UI, GL_UNSIGNED_INT);
+}
+
+TEST_P(RobustResourceInitTestES3, TextureInit_IntRGB8)
+{
+    ANGLE_SKIP_TEST_IF(!hasGLExtension());
+    testIntegerTextureInit<int8_t>("i", GL_RGBA8I, GL_RGB8I, GL_BYTE);
+}
+
+TEST_P(RobustResourceInitTestES3, TextureInit_IntRGB32)
+{
+    ANGLE_SKIP_TEST_IF(!hasGLExtension());
+    testIntegerTextureInit<int32_t>("i", GL_RGBA32I, GL_RGB32I, GL_INT);
+}
+
+// Basic test that renderbuffers are initialized correctly.
+TEST_P(RobustResourceInitTest, Renderbuffer)
+{
+    ANGLE_SKIP_TEST_IF(!hasGLExtension());
+
+    GLRenderbuffer renderbuffer;
+    glBindRenderbuffer(GL_RENDERBUFFER, renderbuffer);
+    glRenderbufferStorage(GL_RENDERBUFFER, GL_RGBA8, kWidth, kHeight);
+
+    GLFramebuffer framebuffer;
+    glBindFramebuffer(GL_FRAMEBUFFER, framebuffer);
+    glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, renderbuffer);
+
+    checkFramebufferNonZeroPixels(0, 0, 0, 0, GLColor::black);
+}
+
+// Tests creating mipmaps with robust resource init.
+TEST_P(RobustResourceInitTestES3, GenerateMipmap)
+{
+    ANGLE_SKIP_TEST_IF(!hasGLExtension());
+
+    constexpr GLint kTextureSize = 16;
+
+    // Initialize a 16x16 RGBA8 texture with no data.
+    GLTexture tex;
+    glBindTexture(GL_TEXTURE_2D, tex);
+    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, kTextureSize, kTextureSize, 0, GL_RGBA,
+                 GL_UNSIGNED_BYTE, nullptr);
+    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_NEAREST);
+    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+
+    ANGLE_GL_PROGRAM(program, kSimpleTextureVertexShader, GetSimpleTextureFragmentShader(""));
+
+    // Generate mipmaps and verify all the mips.
+    glGenerateMipmap(GL_TEXTURE_2D);
+    ASSERT_GL_NO_ERROR();
+
+    // Validate a small texture.
+    glClearColor(1, 0, 0, 1);
+    glClear(GL_COLOR_BUFFER_BIT);
+    EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::red);
+
+    // Set viewport to resize the texture and draw.
+    glViewport(0, 0, 2, 2);
+    drawQuad(program, "position", 0.5f);
+    ASSERT_GL_NO_ERROR();
+    EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::transparentBlack);
+}
+
+// Test blitting a framebuffer out-of-bounds. Multiple iterations.
+TEST_P(RobustResourceInitTestES3, BlitFramebufferOutOfBounds)
+{
+    ANGLE_SKIP_TEST_IF(!hasGLExtension());
+
+    // Initiate data to read framebuffer
+    constexpr int size                = 8;
+    constexpr GLenum readbufferFormat = GL_RGBA8;
+    constexpr GLenum drawbufferFormat = GL_RGBA8;
+    constexpr GLenum filter           = GL_NEAREST;
+
+    std::vector<GLColor> readColors(size * size, GLColor::yellow);
+
+    // Create read framebuffer and feed data to read buffer
+    // Read buffer may have srgb image
+    GLTexture tex_read;
+    glBindTexture(GL_TEXTURE_2D, tex_read);
+    glTexImage2D(GL_TEXTURE_2D, 0, readbufferFormat, size, size, 0, GL_RGBA, GL_UNSIGNED_BYTE,
+                 readColors.data());
+
+    GLFramebuffer fbo_read;
+    glBindFramebuffer(GL_READ_FRAMEBUFFER, fbo_read);
+    glFramebufferTexture2D(GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, tex_read, 0);
+
+    // Create draw framebuffer. Color in draw buffer is initialized to 0.
+    // Draw buffer may have srgb image
+    GLTexture tex_draw;
+    glBindTexture(GL_TEXTURE_2D, tex_draw);
+    glTexImage2D(GL_TEXTURE_2D, 0, drawbufferFormat, size, size, 0, GL_RGBA, GL_UNSIGNED_BYTE,
+                 nullptr);
+
+    GLFramebuffer fbo_draw;
+    glBindFramebuffer(GL_DRAW_FRAMEBUFFER, fbo_draw);
+    glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, tex_draw, 0);
+
+    ASSERT_GL_NO_ERROR();
+    ASSERT_GLENUM_EQ(GL_FRAMEBUFFER_COMPLETE, glCheckFramebufferStatus(GL_READ_FRAMEBUFFER));
+
+    using Region = std::array<int, 4>;
+
+    struct Test
+    {
+        constexpr Test(const Region &read, const Region &draw, const Region &real)
+            : readRegion(read), drawRegion(draw), realRegion(real)
+        {
+        }
+
+        Region readRegion;
+        Region drawRegion;
+        Region realRegion;
+    };
+
+    constexpr std::array<Test, 2> tests = {{
+        // only src region is out-of-bounds, dst region has different width/height as src region.
+        {{{-2, -2, 4, 4}}, {{1, 1, 4, 4}}, {{2, 2, 4, 4}}},
+        // only src region is out-of-bounds, dst region has the same width/height as src region.
+        {{{-2, -2, 4, 4}}, {{1, 1, 7, 7}}, {{3, 3, 7, 7}}},
+    }};
+
+    // Blit read framebuffer to the image in draw framebuffer.
+    for (const auto &test : tests)
+    {
+        // both the read framebuffer and draw framebuffer bounds are [0, 0, 8, 8]
+        // blitting from src region to dst region
+        glBindTexture(GL_TEXTURE_2D, tex_draw);
+        glTexImage2D(GL_TEXTURE_2D, 0, drawbufferFormat, size, size, 0, GL_RGBA, GL_UNSIGNED_BYTE,
+                     nullptr);
+
+        const auto &read = test.readRegion;
+        const auto &draw = test.drawRegion;
+        const auto &real = test.realRegion;
+
+        glBlitFramebuffer(read[0], read[1], read[2], read[3], draw[0], draw[1], draw[2], draw[3],
+                          GL_COLOR_BUFFER_BIT, filter);
+
+        // Read pixels and check the correctness.
+        std::vector<GLColor> pixels(size * size);
+        glBindFramebuffer(GL_READ_FRAMEBUFFER, fbo_draw);
+        glPixelStorei(GL_PACK_ROW_LENGTH, 0);
+        glReadPixels(0, 0, size, size, GL_RGBA, GL_UNSIGNED_BYTE, pixels.data());
+        glBindFramebuffer(GL_READ_FRAMEBUFFER, fbo_read);
+        ASSERT_GL_NO_ERROR();
+
+        for (int ii = 0; ii < size; ++ii)
+        {
+            for (int jj = 0; jj < size; ++jj)
+            {
+                GLColor expectedColor = GLColor::transparentBlack;
+                if (ii >= real[0] && ii < real[2] && jj >= real[1] && jj < real[3])
+                {
+                    expectedColor = GLColor::yellow;
+                }
+
+                int loc = ii * size + jj;
+                EXPECT_EQ(expectedColor, pixels[loc]) << " at [" << jj << ", " << ii << "]";
+            }
+        }
+    }
+}
+
+template <typename ClearFunc>
+void RobustResourceInitTest::maskedDepthClear(ClearFunc clearFunc)
+{
+    ANGLE_SKIP_TEST_IF(!hasGLExtension());
+
+    constexpr int kSize = 16;
+
+    // Initialize a FBO with depth and simple color.
+    GLRenderbuffer depthbuffer;
+    glBindRenderbuffer(GL_RENDERBUFFER, depthbuffer);
+    glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT16, kSize, kSize);
+
+    GLTexture colorbuffer;
+    glBindTexture(GL_TEXTURE_2D, colorbuffer);
+    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, kSize, kSize, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
+
+    GLFramebuffer framebuffer;
+    glBindFramebuffer(GL_FRAMEBUFFER, framebuffer);
+    glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, colorbuffer, 0);
+    glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, depthbuffer);
+
+    ASSERT_GL_NO_ERROR();
+    ASSERT_GLENUM_EQ(GL_FRAMEBUFFER_COMPLETE, glCheckFramebufferStatus(GL_FRAMEBUFFER));
+
+    // Disable depth writes and trigger a clear.
+    glDepthMask(GL_FALSE);
+
+    clearFunc(0.5f);
+    EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::black);
+
+    // Draw red with a depth function that checks for the clear value.
+    glEnable(GL_DEPTH_TEST);
+    glDepthFunc(GL_EQUAL);
+
+    const std::string vertexShader =
+        "attribute vec4 position; void main() { gl_Position = position; }";
+    const std::string fragmentShader = "void main() { gl_FragColor = vec4(1, 0, 0, 1); }";
+    ANGLE_GL_PROGRAM(program, vertexShader, fragmentShader);
+
+    drawQuad(program, "position", 0.5f);
+    ASSERT_GL_NO_ERROR();
+    EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::black) << "depth should not be 0.5f";
+
+    drawQuad(program, "position", 1.0f);
+    EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::red) << "depth should be initialized to 1.0f";
+}
+
+// Test that clearing a masked depth buffer doesn't mark it clean.
+TEST_P(RobustResourceInitTest, MaskedDepthClear)
+{
+    ANGLE_SKIP_TEST_IF(!hasGLExtension());
+
+    auto clearFunc = [](float depth) {
+        glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
+        glClearDepthf(depth);
+        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
+    };
+
+    maskedDepthClear(clearFunc);
+}
+
+// Tests the same as MaskedDepthClear, but using ClearBuffer calls.
+TEST_P(RobustResourceInitTestES3, MaskedDepthClearBuffer)
+{
+    ANGLE_SKIP_TEST_IF(!hasGLExtension());
+
+    auto clearFunc = [](float depth) {
+        glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
+        glClear(GL_COLOR_BUFFER_BIT);
+        glClearBufferfv(GL_DEPTH, 0, &depth);
+    };
+
+    maskedDepthClear(clearFunc);
+}
+
+template <typename ClearFunc>
+void RobustResourceInitTest::maskedStencilClear(ClearFunc clearFunc)
+{
+    constexpr int kSize = 16;
+
+    // Initialize a FBO with stencil and simple color.
+    GLRenderbuffer stencilbuffer;
+    glBindRenderbuffer(GL_RENDERBUFFER, stencilbuffer);
+    glRenderbufferStorage(GL_RENDERBUFFER, GL_STENCIL_INDEX8, kSize, kSize);
+
+    GLTexture colorbuffer;
+    glBindTexture(GL_TEXTURE_2D, colorbuffer);
+    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, kSize, kSize, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
+
+    GLFramebuffer framebuffer;
+    glBindFramebuffer(GL_FRAMEBUFFER, framebuffer);
+    glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, colorbuffer, 0);
+    glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER,
+                              stencilbuffer);
+
+    ASSERT_GL_NO_ERROR();
+    ASSERT_GLENUM_EQ(GL_FRAMEBUFFER_COMPLETE, glCheckFramebufferStatus(GL_FRAMEBUFFER));
+
+    // Disable stencil writes and trigger a clear. Use a tricky mask that does not overlap the
+    // clear.
+    glStencilMask(0xF0);
+    clearFunc(0x0F);
+    EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::black);
+
+    // Draw red with a stencil function that checks for stencil == 0
+    glEnable(GL_STENCIL_TEST);
+    glStencilFunc(GL_EQUAL, 0x00, 0xFF);
+    glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP);
+
+    const std::string vertexShader =
+        "attribute vec4 position; void main() { gl_Position = position; }";
+    const std::string fragmentShader = "void main() { gl_FragColor = vec4(1, 0, 0, 1); }";
+    ANGLE_GL_PROGRAM(program, vertexShader, fragmentShader);
+
+    drawQuad(program, "position", 0.5f);
+    ASSERT_GL_NO_ERROR();
+    EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::red) << "stencil should be equal to zero";
+}
+
+// Test that clearing a masked stencil buffer doesn't mark it clean.
+TEST_P(RobustResourceInitTest, MaskedStencilClear)
+{
+    ANGLE_SKIP_TEST_IF(!hasGLExtension());
+    ANGLE_SKIP_TEST_IF(IsD3D11_FL93());
+
+    auto clearFunc = [](GLint clearValue) {
+        glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
+        glClearStencil(clearValue);
+        glClear(GL_COLOR_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
+    };
+
+    maskedStencilClear(clearFunc);
+}
+
+// Test that clearing a masked stencil buffer doesn't mark it clean, with ClearBufferi.
+TEST_P(RobustResourceInitTestES3, MaskedStencilClearBuffer)
+{
+    ANGLE_SKIP_TEST_IF(!hasGLExtension());
+
+    auto clearFunc = [](GLint clearValue) {
+        glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
+        glClear(GL_COLOR_BUFFER_BIT);
+        glClearBufferiv(GL_STENCIL, 0, &clearValue);
+    };
+
+    maskedStencilClear(clearFunc);
+}
+
+template <int Size, typename InitializedTest>
+void VerifyRGBA8PixelRect(InitializedTest inInitialized)
+{
+    std::array<std::array<GLColor, Size>, Size> actualPixels;
+    glReadPixels(0, 0, Size, Size, GL_RGBA, GL_UNSIGNED_BYTE, actualPixels.data());
+    ASSERT_GL_NO_ERROR();
+
+    for (int y = 0; y < Size; ++y)
+    {
+        for (int x = 0; x < Size; ++x)
+        {
+            if (inInitialized(x, y))
+            {
+                EXPECT_EQ(actualPixels[y][x], GLColor::red) << " at " << x << ", " << y;
+            }
+            else
+            {
+                EXPECT_EQ(actualPixels[y][x], GLColor::transparentBlack)
+                    << " at " << x << ", " << y;
+            }
+        }
+    }
+}
+
+// Tests that calling CopyTexSubImage2D will initialize the source & destination.
+TEST_P(RobustResourceInitTest, CopyTexSubImage2D)
+{
+    ANGLE_SKIP_TEST_IF(!hasGLExtension());
+    ANGLE_SKIP_TEST_IF(IsD3D11_FL93());
+
+    constexpr int kDestSize = 4;
+    constexpr int kSrcSize  = kDestSize / 2;
+    constexpr int kOffset   = kSrcSize / 2;
+
+    std::vector<GLColor> redColors(kDestSize * kDestSize, GLColor::red);
+
+    // Initialize source texture with red.
+    GLTexture srcTexture;
+    glBindTexture(GL_TEXTURE_2D, srcTexture);
+    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, kSrcSize, kSrcSize, 0, GL_RGBA, GL_UNSIGNED_BYTE,
+                 redColors.data());
+
+    GLFramebuffer framebuffer;
+    glBindFramebuffer(GL_FRAMEBUFFER, framebuffer);
+    glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, srcTexture, 0);
+
+    ASSERT_GL_NO_ERROR();
+    ASSERT_GLENUM_EQ(GL_FRAMEBUFFER_COMPLETE, glCheckFramebufferStatus(GL_FRAMEBUFFER));
+
+    // Create uninitialized destination texture.
+    GLTexture destTexture;
+    glBindTexture(GL_TEXTURE_2D, destTexture);
+    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, kDestSize, kDestSize, 0, GL_RGBA, GL_UNSIGNED_BYTE,
+                 nullptr);
+
+    // Trigger the copy from initialized source into uninitialized dest.
+    glCopyTexSubImage2D(GL_TEXTURE_2D, 0, kOffset, kOffset, 0, 0, kSrcSize, kSrcSize);
+
+    // Verify the pixel rectangle.
+    glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, destTexture, 0);
+    ASSERT_GL_NO_ERROR();
+
+    auto srcInitTest = [kOffset, kDestSize](int x, int y) {
+        return (x >= kOffset) && x < (kDestSize - kOffset) && (y >= kOffset) &&
+               y < (kDestSize - kOffset);
+    };
+
+    VerifyRGBA8PixelRect<kDestSize>(srcInitTest);
+
+    // Make source texture uninitialized. Force a release by redefining a new size.
+    glBindTexture(GL_TEXTURE_2D, srcTexture);
+    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, kSrcSize, kSrcSize, 0, GL_RGBA, GL_UNSIGNED_BYTE,
+                 nullptr);
+    glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, srcTexture, 0);
+
+    // Fill destination texture with red.
+    glBindTexture(GL_TEXTURE_2D, destTexture);
+    glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, kDestSize, kDestSize, GL_RGBA, GL_UNSIGNED_BYTE,
+                    redColors.data());
+
+    // Trigger a copy from uninitialized source into initialized dest.
+    glCopyTexSubImage2D(GL_TEXTURE_2D, 0, kOffset, kOffset, 0, 0, kSrcSize, kSrcSize);
+
+    // Verify the pixel rectangle.
+    glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, destTexture, 0);
+    ASSERT_GL_NO_ERROR();
+
+    auto destInitTest = [srcInitTest](int x, int y) { return !srcInitTest(x, y); };
+
+    VerifyRGBA8PixelRect<kDestSize>(destInitTest);
+}
+
+// Tests that calling CopyTexSubImage3D will initialize the source & destination.
+TEST_P(RobustResourceInitTestES3, CopyTexSubImage3D)
+{
+    ANGLE_SKIP_TEST_IF(!hasGLExtension());
+
+    constexpr int kDestSize = 4;
+    constexpr int kSrcSize  = kDestSize / 2;
+    constexpr int kOffset   = kSrcSize / 2;
+
+    std::vector<GLColor> redColors(kDestSize * kDestSize * kDestSize, GLColor::red);
+
+    GLTexture srcTexture;
+    GLFramebuffer framebuffer;
+    GLTexture destTexture;
+    glBindFramebuffer(GL_FRAMEBUFFER, framebuffer);
+
+    // Initialize source texture with red.
+    glBindTexture(GL_TEXTURE_3D, srcTexture);
+    glTexImage3D(GL_TEXTURE_3D, 0, GL_RGBA8, kSrcSize, kSrcSize, kSrcSize, 0, GL_RGBA,
+                 GL_UNSIGNED_BYTE, redColors.data());
+
+    glFramebufferTextureLayer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, srcTexture, 0, 0);
+
+    ASSERT_GL_NO_ERROR();
+    ASSERT_GLENUM_EQ(GL_FRAMEBUFFER_COMPLETE, glCheckFramebufferStatus(GL_FRAMEBUFFER));
+
+    // Create uninitialized destination texture.
+    glBindTexture(GL_TEXTURE_3D, destTexture);
+    glTexImage3D(GL_TEXTURE_3D, 0, GL_RGBA8, kDestSize, kDestSize, kDestSize, 0, GL_RGBA,
+                 GL_UNSIGNED_BYTE, nullptr);
+
+    // Trigger the copy from initialized source into uninitialized dest.
+    glCopyTexSubImage3D(GL_TEXTURE_3D, 0, kOffset, kOffset, 0, 0, 0, kSrcSize, kSrcSize);
+
+    // Verify the pixel rectangle.
+    glFramebufferTextureLayer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, destTexture, 0, 0);
+    ASSERT_GL_NO_ERROR();
+
+    auto srcInitTest = [kOffset, kDestSize](int x, int y) {
+        return (x >= kOffset) && x < (kDestSize - kOffset) && (y >= kOffset) &&
+               y < (kDestSize - kOffset);
+    };
+
+    VerifyRGBA8PixelRect<kDestSize>(srcInitTest);
+
+    // Make source texture uninitialized.
+    glBindTexture(GL_TEXTURE_3D, srcTexture);
+    glTexImage3D(GL_TEXTURE_3D, 0, GL_RGBA8, kSrcSize, kSrcSize, kSrcSize, 0, GL_RGBA,
+                 GL_UNSIGNED_BYTE, nullptr);
+    glFramebufferTextureLayer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, srcTexture, 0, 0);
+
+    ASSERT_GL_NO_ERROR();
+    ASSERT_GLENUM_EQ(GL_FRAMEBUFFER_COMPLETE, glCheckFramebufferStatus(GL_FRAMEBUFFER));
+
+    // Fill destination texture with red.
+    glBindTexture(GL_TEXTURE_3D, destTexture);
+    glTexImage3D(GL_TEXTURE_3D, 0, GL_RGBA8, kDestSize, kDestSize, kDestSize, 0, GL_RGBA,
+                 GL_UNSIGNED_BYTE, redColors.data());
+
+    // Trigger a copy from uninitialized source into initialized dest.
+    glCopyTexSubImage3D(GL_TEXTURE_3D, 0, kOffset, kOffset, 0, 0, 0, kSrcSize, kSrcSize);
+
+    // Verify the pixel rectangle.
+    glFramebufferTextureLayer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, destTexture, 0, 0);
+    ASSERT_GL_NO_ERROR();
+
+    auto destInitTest = [srcInitTest](int x, int y) { return !srcInitTest(x, y); };
+
+    VerifyRGBA8PixelRect<kDestSize>(destInitTest);
+}
+
+// Test basic robustness with 2D array textures.
+TEST_P(RobustResourceInitTestES3, Texture2DArray)
+{
+    ANGLE_SKIP_TEST_IF(!hasGLExtension());
+
+    constexpr int kSize   = 1024;
+    constexpr int kLayers = 8;
+
+    GLTexture texture;
+    glBindTexture(GL_TEXTURE_2D_ARRAY, texture);
+    glTexImage3D(GL_TEXTURE_2D_ARRAY, 0, GL_RGBA8, kSize, kSize, kLayers, 0, GL_RGBA,
+                 GL_UNSIGNED_BYTE, nullptr);
+
+    GLFramebuffer framebuffer;
+    glBindFramebuffer(GL_FRAMEBUFFER, framebuffer);
+
+    for (int layer = 0; layer < kLayers; ++layer)
+    {
+        checkNonZeroPixels3D(&texture, 0, 0, 0, 0, layer, GLColor::transparentBlack);
+    }
+}
+
+// Test that using TexStorage2D followed by CompressedSubImage works with robust init.
+// Taken from WebGL test conformance/extensions/webgl-compressed-texture-s3tc.
+TEST_P(RobustResourceInitTestES3, CompressedSubImage)
+{
+    ANGLE_SKIP_TEST_IF(!hasGLExtension());
+    ANGLE_SKIP_TEST_IF(!extensionEnabled("GL_EXT_texture_compression_dxt1"));
+
+    constexpr int width     = 8;
+    constexpr int height    = 8;
+    constexpr int subX0     = 0;
+    constexpr int subY0     = 0;
+    constexpr int subWidth  = 4;
+    constexpr int subHeight = 4;
+    constexpr GLenum format = GL_COMPRESSED_RGB_S3TC_DXT1_EXT;
+
+    static constexpr uint8_t img_8x8_rgb_dxt1[] = {
+        0xe0, 0x07, 0x00, 0xf8, 0x11, 0x10, 0x15, 0x00, 0x1f, 0x00, 0xe0,
+        0xff, 0x11, 0x10, 0x15, 0x00, 0xe0, 0x07, 0x1f, 0xf8, 0x44, 0x45,
+        0x40, 0x55, 0x1f, 0x00, 0xff, 0x07, 0x44, 0x45, 0x40, 0x55,
+    };
+
+    static constexpr uint8_t img_4x4_rgb_dxt1[] = {
+        0xe0, 0x07, 0x00, 0xf8, 0x11, 0x10, 0x15, 0x00,
+    };
+
+    std::vector<uint8_t> data(img_8x8_rgb_dxt1, img_8x8_rgb_dxt1 + ArraySize(img_8x8_rgb_dxt1));
+    std::vector<uint8_t> subData(img_4x4_rgb_dxt1, img_4x4_rgb_dxt1 + ArraySize(img_4x4_rgb_dxt1));
+
+    GLTexture colorbuffer;
+    glBindTexture(GL_TEXTURE_2D, colorbuffer);
+    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
+
+    GLFramebuffer framebuffer;
+    glBindFramebuffer(GL_FRAMEBUFFER, framebuffer);
+    glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, colorbuffer, 0);
+    ASSERT_GLENUM_EQ(GL_FRAMEBUFFER_COMPLETE, glCheckFramebufferStatus(GL_FRAMEBUFFER));
+
+    glViewport(0, 0, width, height);
+
+    // testing format width-x-height via texStorage2D
+    const auto &expectedData = UncompressDXTIntoSubRegion(width, height, subX0, subY0, subWidth,
+                                                          subHeight, subData, format);
+
+    GLTexture tex;
+    glBindTexture(GL_TEXTURE_2D, tex);
+    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
+    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
+    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+
+    glTexStorage2D(GL_TEXTURE_2D, 1, format, width, height);
+    ASSERT_GL_NO_ERROR();
+    glCompressedTexSubImage2D(GL_TEXTURE_2D, 0, subX0, subY0, subWidth, subHeight, format,
+                              static_cast<GLsizei>(subData.size()), subData.data());
+    ASSERT_GL_NO_ERROR();
+
+    draw2DTexturedQuad(0.5f, 1.0f, true);
+    ASSERT_GL_NO_ERROR();
+
+    std::vector<GLColor> actualData(width * height);
+    glReadPixels(0, 0, width, height, GL_RGBA, GL_UNSIGNED_BYTE, actualData.data());
+    ASSERT_GL_NO_ERROR();
+
+    for (int y = 0; y < height; ++y)
+    {
+        for (int x = 0; x < width; ++x)
+        {
+            int offset                  = x + y * width;
+            const GLColor expectedColor = expectedData[offset];
+            const GLColor actualColor   = actualData[offset];
+
+            // Allow for some minor variation because the format is compressed.
+            EXPECT_NEAR(expectedColor.R, actualColor.R, 1) << " at (" << x << ", " << y << ")";
+            EXPECT_NEAR(expectedColor.G, actualColor.G, 1) << " at (" << x << ", " << y << ")";
+            EXPECT_NEAR(expectedColor.B, actualColor.B, 1) << " at (" << x << ", " << y << ")";
+        }
+    }
+}
+
+// Tests that a partial scissor still initializes contents as expected.
+TEST_P(RobustResourceInitTest, ClearWithScissor)
+{
+    ANGLE_SKIP_TEST_IF(!hasGLExtension());
+
+    constexpr int kSize = 16;
+
+    GLRenderbuffer colorbuffer;
+    glBindRenderbuffer(GL_RENDERBUFFER, colorbuffer);
+    glRenderbufferStorage(GL_RENDERBUFFER, GL_RGBA8, kSize, kSize);
+
+    GLFramebuffer framebuffer;
+    glBindFramebuffer(GL_FRAMEBUFFER, framebuffer);
+    glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, colorbuffer);
+
+    ASSERT_GL_NO_ERROR();
+    ASSERT_GLENUM_EQ(GL_FRAMEBUFFER_COMPLETE, glCheckFramebufferStatus(GL_FRAMEBUFFER));
+
+    // Scissor to half the width.
+    glEnable(GL_SCISSOR_TEST);
+    glScissor(0, 0, kSize / 2, kSize);
+
+    // Clear. Half the texture should be black, and half red.
+    glClearColor(1.0f, 0.0f, 0.0f, 1.0f);
+    glClear(GL_COLOR_BUFFER_BIT);
+
+    EXPECT_GL_NO_ERROR();
+    EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::red);
+    EXPECT_PIXEL_COLOR_EQ(kSize - 1, 0, GLColor::transparentBlack);
+}
+
 ANGLE_INSTANTIATE_TEST(RobustResourceInitTest,
                        ES2_D3D9(),
                        ES2_D3D11(),
                        ES3_D3D11(),
                        ES2_D3D11_FL9_3(),
                        ES2_OPENGL(),
                        ES3_OPENGL(),
                        ES2_OPENGLES(),
                        ES3_OPENGLES());
+
+ANGLE_INSTANTIATE_TEST(RobustResourceInitTestES3, ES3_D3D11(), ES3_OPENGL(), ES3_OPENGLES());
+
 }  // namespace
--- a/gfx/angle/src/tests/gl_tests/SRGBFramebufferTest.cpp
+++ b/gfx/angle/src/tests/gl_tests/SRGBFramebufferTest.cpp
@@ -72,27 +72,27 @@ TEST_P(SRGBFramebufferTest, Validation)
     GLboolean value = GL_FALSE;
     glEnable(GL_FRAMEBUFFER_SRGB_EXT);
     EXPECT_GL_ERROR(expectedError);
 
     glGetBooleanv(GL_FRAMEBUFFER_SRGB_EXT, &value);
     EXPECT_GL_ERROR(expectedError);
     if (expectedError == GL_NO_ERROR)
     {
-        EXPECT_EQ(GL_TRUE, value);
+        EXPECT_GL_TRUE(value);
     }
 
     glDisable(GL_FRAMEBUFFER_SRGB_EXT);
     EXPECT_GL_ERROR(expectedError);
 
     glGetBooleanv(GL_FRAMEBUFFER_SRGB_EXT, &value);
     EXPECT_GL_ERROR(expectedError);
     if (expectedError == GL_NO_ERROR)
     {
-        EXPECT_EQ(GL_FALSE, value);
+        EXPECT_GL_FALSE(value);
     }
 }
 
 // Test basic functionality of GL_EXT_sRGB_write_control
 TEST_P(SRGBFramebufferTest, BasicUsage)
 {
     if (!extensionEnabled("GL_EXT_sRGB_write_control") ||
         (!extensionEnabled("GL_EXT_sRGB") && getClientMajorVersion() < 3))
--- a/gfx/angle/src/tests/gl_tests/ShaderStorageBufferTest.cpp
+++ b/gfx/angle/src/tests/gl_tests/ShaderStorageBufferTest.cpp
@@ -129,11 +129,154 @@ TEST_P(ShaderStorageBufferTest31, Shader
     glUnmapBuffer(GL_SHADER_STORAGE_BUFFER);
     glBindBuffer(GL_SHADER_STORAGE_BUFFER, 0);
     EXPECT_EQ(3u, bufferData[0]);
     EXPECT_EQ(4u, bufferData[1]);
 
     EXPECT_GL_NO_ERROR();
 }
 
+// Test atomic memory functions.
+TEST_P(ShaderStorageBufferTest31, AtomicMemoryFunctions)
+{
+    ANGLE_SKIP_TEST_IF(IsAMD() && IsDesktopOpenGL() && IsWindows());
+    ANGLE_SKIP_TEST_IF(IsLinux() && IsIntel() && IsOpenGL());
+    // anglebug.com/2255
+    ANGLE_SKIP_TEST_IF(IsLinux() && IsAMD() && IsDesktopOpenGL());
+
+    const std::string &csSource =
+        R"(#version 310 es
+
+        layout(local_size_x=1, local_size_y=1, local_size_z=1) in;
+        layout(binding = 1) buffer blockName {
+            uint data[2];
+        } instanceName;
+
+        void main()
+        {
+            instanceName.data[0] = 0u;
+            instanceName.data[1] = 0u;
+            atomicAdd(instanceName.data[0], 5u);
+            atomicMax(instanceName.data[1], 7u);
+
+        })";
+
+    ANGLE_GL_COMPUTE_PROGRAM(program, csSource);
+
+    glUseProgram(program.get());
+
+    unsigned int bufferData[2] = {0u};
+    // Create shader storage buffer
+    GLBuffer shaderStorageBuffer;
+    glBindBuffer(GL_SHADER_STORAGE_BUFFER, shaderStorageBuffer);
+    glBufferData(GL_SHADER_STORAGE_BUFFER, sizeof(bufferData), nullptr, GL_STATIC_DRAW);
+
+    // Bind shader storage buffer
+    glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 1, shaderStorageBuffer);
+
+    // Dispath compute
+    glDispatchCompute(1, 1, 1);
+
+    glFinish();
+
+    // Read back shader storage buffer
+    glBindBuffer(GL_SHADER_STORAGE_BUFFER, shaderStorageBuffer);
+    void *ptr = glMapBufferRange(GL_SHADER_STORAGE_BUFFER, 0, sizeof(bufferData), GL_MAP_READ_BIT);
+    memcpy(bufferData, ptr, sizeof(bufferData));
+    glUnmapBuffer(GL_SHADER_STORAGE_BUFFER);
+    glBindBuffer(GL_SHADER_STORAGE_BUFFER, 0);
+    EXPECT_EQ(5u, bufferData[0]);
+    EXPECT_EQ(7u, bufferData[1]);
+
+    EXPECT_GL_NO_ERROR();
+}
+
+// Test multiple storage buffers work correctly when program switching. In angle, storage buffer
+// bindings are updated accord to current program. If switch program, need to update storage buffer
+// bindings again.
+TEST_P(ShaderStorageBufferTest31, MultiStorageBuffersForMultiPrograms)
+{
+    const std::string &csSource1 =
+        R"(#version 310 es
+        layout(local_size_x=3, local_size_y=1, local_size_z=1) in;
+        layout(binding = 1) buffer Output {
+            uint result1[];
+        } sb_out1;
+        void main()
+        {
+            highp uint offset = gl_LocalInvocationID.x;
+            sb_out1.result1[gl_LocalInvocationIndex] = gl_LocalInvocationIndex + 1u;
+        })";
+
+    const std::string &csSource2 =
+        R"(#version 310 es
+        layout(local_size_x=3, local_size_y=1, local_size_z=1) in;
+        layout(binding = 2) buffer Output {
+            uint result2[];
+        } sb_out2;
+        void main()
+        {
+            highp uint offset = gl_LocalInvocationID.x;
+            sb_out2.result2[gl_LocalInvocationIndex] = gl_LocalInvocationIndex + 2u;
+        })";
+
+    constexpr unsigned int numInvocations = 3;
+    int arrayStride1 = 0, arrayStride2 = 0;
+    GLenum props[] = {GL_ARRAY_STRIDE};
+    GLBuffer shaderStorageBuffer1, shaderStorageBuffer2;
+
+    ANGLE_GL_COMPUTE_PROGRAM(program1, csSource1);
+    ANGLE_GL_COMPUTE_PROGRAM(program2, csSource2);
+    EXPECT_GL_NO_ERROR();
+
+    unsigned int outVarIndex1 =
+        glGetProgramResourceIndex(program1.get(), GL_BUFFER_VARIABLE, "Output.result1");
+    glGetProgramResourceiv(program1.get(), GL_BUFFER_VARIABLE, outVarIndex1, 1, props, 1, 0,
+                           &arrayStride1);
+    glBindBuffer(GL_SHADER_STORAGE_BUFFER, shaderStorageBuffer1);
+    glBufferData(GL_SHADER_STORAGE_BUFFER, numInvocations * arrayStride1, nullptr, GL_STREAM_READ);
+    glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 1, shaderStorageBuffer1);
+    EXPECT_GL_NO_ERROR();
+
+    unsigned int outVarIndex2 =
+        glGetProgramResourceIndex(program2.get(), GL_BUFFER_VARIABLE, "Output.result2");
+    glGetProgramResourceiv(program2.get(), GL_BUFFER_VARIABLE, outVarIndex2, 1, props, 1, 0,
+                           &arrayStride2);
+    glBindBuffer(GL_SHADER_STORAGE_BUFFER, shaderStorageBuffer2);
+    glBufferData(GL_SHADER_STORAGE_BUFFER, numInvocations * arrayStride2, nullptr, GL_STREAM_READ);
+    glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 2, shaderStorageBuffer2);
+    EXPECT_GL_NO_ERROR();
+
+    glUseProgram(program1.get());
+    glDispatchCompute(1, 1, 1);
+    EXPECT_GL_NO_ERROR();
+    glUseProgram(program2.get());
+    glDispatchCompute(1, 1, 1);
+    EXPECT_GL_NO_ERROR();
+
+    glBindBuffer(GL_SHADER_STORAGE_BUFFER, shaderStorageBuffer1);
+    const void *ptr1 =
+        glMapBufferRange(GL_SHADER_STORAGE_BUFFER, 0, 3 * arrayStride1, GL_MAP_READ_BIT);
+    for (unsigned int idx = 0; idx < numInvocations; idx++)
+    {
+        EXPECT_EQ(idx + 1, *((const GLuint *)((const GLbyte *)ptr1 + idx * arrayStride1)));
+    }
+    glUnmapBuffer(GL_SHADER_STORAGE_BUFFER);
+    EXPECT_GL_NO_ERROR();
+
+    glBindBuffer(GL_SHADER_STORAGE_BUFFER, shaderStorageBuffer2);
+    const void *ptr2 =
+        glMapBufferRange(GL_SHADER_STORAGE_BUFFER, 0, 3 * arrayStride2, GL_MAP_READ_BIT);
+    EXPECT_GL_NO_ERROR();
+    for (unsigned int idx = 0; idx < numInvocations; idx++)
+    {
+        EXPECT_EQ(idx + 2, *((const GLuint *)((const GLbyte *)ptr2 + idx * arrayStride2)));
+    }
+    glUnmapBuffer(GL_SHADER_STORAGE_BUFFER);
+    EXPECT_GL_NO_ERROR();
+
+    glBindBuffer(GL_SHADER_STORAGE_BUFFER, 0);
+    EXPECT_GL_NO_ERROR();
+}
+
 ANGLE_INSTANTIATE_TEST(ShaderStorageBufferTest31, ES31_OPENGL(), ES31_OPENGLES());
 
 }  // namespace
--- a/gfx/angle/src/tests/gl_tests/SimpleOperationTest.cpp
+++ b/gfx/angle/src/tests/gl_tests/SimpleOperationTest.cpp
@@ -103,23 +103,16 @@ TEST_P(SimpleOperationTest, LinkProgram)
     EXPECT_NE(program, 0u);
     glDeleteProgram(program);
 
     EXPECT_GL_NO_ERROR();
 }
 
 TEST_P(SimpleOperationTest, LinkProgramWithUniforms)
 {
-    if (IsVulkan())
-    {
-        // TODO(jmadill): Complete Vulkan implementation.
-        std::cout << "Test skipped on Vulkan." << std::endl;
-        return;
-    }
-
     const std::string vsSource =
         R"(void main()
         {
             gl_Position = vec4(1.0, 1.0, 1.0, 1.0);
         })";
 
     const std::string fsSource =
         R"(precision mediump float;
@@ -137,23 +130,16 @@ TEST_P(SimpleOperationTest, LinkProgramW
 
     glDeleteProgram(program);
 
     EXPECT_GL_NO_ERROR();
 }
 
 TEST_P(SimpleOperationTest, LinkProgramWithAttributes)
 {
-    if (IsVulkan())
-    {
-        // TODO(jmadill): Complete Vulkan implementation.
-        std::cout << "Test skipped on Vulkan." << std::endl;
-        return;
-    }
-
     const std::string vsSource =
         R"(attribute vec4 a_input;
         void main()
         {
             gl_Position = a_input;
         })";
 
     const std::string fsSource =
@@ -237,19 +223,22 @@ TEST_P(SimpleOperationTest, DrawQuad)
     ANGLE_GL_PROGRAM(program, vertexShader, fragmentShader);
 
     drawQuad(program.get(), "position", 0.5f, 1.0f, true);
 
     EXPECT_GL_NO_ERROR();
     EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
 }
 
-// Simple repeatd draw and swap test.
+// Simple repeated draw and swap test.
 TEST_P(SimpleOperationTest, DrawQuadAndSwap)
 {
+    // anglebug.com/2301
+    ANGLE_SKIP_TEST_IF(IsLinux() && IsIntel() && IsVulkan());
+
     const std::string &vertexShader =
         "attribute vec3 position;\n"
         "void main()\n"
         "{\n"
         "    gl_Position = vec4(position, 1);\n"
         "}";
     const std::string &fragmentShader =
         "void main()\n"
@@ -264,16 +253,290 @@ TEST_P(SimpleOperationTest, DrawQuadAndS
         EXPECT_GL_NO_ERROR();
         EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
         swapBuffers();
     }
 
     EXPECT_GL_NO_ERROR();
 }
 
+// Simple indexed quad test.
+TEST_P(SimpleOperationTest, DrawIndexedQuad)
+{
+    const std::string vertexShader =
+        "attribute vec3 position;\n"
+        "void main()\n"
+        "{\n"
+        "    gl_Position = vec4(position, 1);\n"
+        "}";
+    const std::string fragmentShader =
+        "void main()\n"
+        "{\n"
+        "    gl_FragColor = vec4(0, 1, 0, 1);\n"
+        "}";
+    ANGLE_GL_PROGRAM(program, vertexShader, fragmentShader);
+
+    drawIndexedQuad(program.get(), "position", 0.5f, 1.0f, true);
+
+    EXPECT_GL_NO_ERROR();
+    EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
+}
+
+// Draw with a fragment uniform.
+TEST_P(SimpleOperationTest, DrawQuadWithFragmentUniform)
+{
+    const std::string &vertexShader =
+        "attribute vec3 position;\n"
+        "void main()\n"
+        "{\n"
+        "    gl_Position = vec4(position, 1);\n"
+        "}";
+    const std::string &fragmentShader =
+        "uniform mediump vec4 color;\n"
+        "void main()\n"
+        "{\n"
+        "    gl_FragColor = color;\n"
+        "}";
+    ANGLE_GL_PROGRAM(program, vertexShader, fragmentShader);
+
+    GLint location = glGetUniformLocation(program, "color");
+    ASSERT_NE(-1, location);
+
+    glUseProgram(program);
+    glUniform4f(location, 0.0f, 1.0f, 0.0f, 1.0f);
+
+    drawQuad(program.get(), "position", 0.5f, 1.0f, true);
+
+    EXPECT_GL_NO_ERROR();
+    EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
+}
+
+// Draw with a vertex uniform.
+TEST_P(SimpleOperationTest, DrawQuadWithVertexUniform)
+{
+    const std::string &vertexShader =
+        "attribute vec3 position;\n"
+        "uniform vec4 color;\n"
+        "varying vec4 vcolor;\n"
+        "void main()\n"
+        "{\n"
+        "    gl_Position = vec4(position, 1);\n"
+        "    vcolor = color;\n"
+        "}";
+    const std::string &fragmentShader =
+        "varying mediump vec4 vcolor;\n"
+        "void main()\n"
+        "{\n"
+        "    gl_FragColor = vcolor;\n"
+        "}";
+    ANGLE_GL_PROGRAM(program, vertexShader, fragmentShader);
+
+    GLint location = glGetUniformLocation(program, "color");
+    ASSERT_NE(-1, location);
+
+    glUseProgram(program);
+    glUniform4f(location, 0.0f, 1.0f, 0.0f, 1.0f);
+
+    drawQuad(program.get(), "position", 0.5f, 1.0f, true);
+
+    EXPECT_GL_NO_ERROR();
+    EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
+}
+
+// Draw with two uniforms.
+TEST_P(SimpleOperationTest, DrawQuadWithTwoUniforms)
+{
+    const std::string &vertexShader =
+        "attribute vec3 position;\n"
+        "uniform vec4 color1;\n"
+        "varying vec4 vcolor1;\n"
+        "void main()\n"
+        "{\n"
+        "    gl_Position = vec4(position, 1);\n"
+        "    vcolor1 = color1;\n"
+        "}";
+    const std::string &fragmentShader =
+        "uniform mediump vec4 color2;\n"
+        "varying mediump vec4 vcolor1;\n"
+        "void main()\n"
+        "{\n"
+        "    gl_FragColor = vcolor1 + color2;\n"
+        "}";
+    ANGLE_GL_PROGRAM(program, vertexShader, fragmentShader);
+
+    GLint location1 = glGetUniformLocation(program, "color1");
+    ASSERT_NE(-1, location1);
+
+    GLint location2 = glGetUniformLocation(program, "color2");
+    ASSERT_NE(-1, location2);
+
+    glUseProgram(program);
+    glUniform4f(location1, 0.0f, 1.0f, 0.0f, 1.0f);
+    glUniform4f(location2, 1.0f, 0.0f, 0.0f, 1.0f);
+
+    drawQuad(program.get(), "position", 0.5f, 1.0f, true);
+
+    EXPECT_GL_NO_ERROR();
+    EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::yellow);
+}
+
+// Tests a shader program with more than one vertex attribute, with vertex buffers.
+TEST_P(SimpleOperationTest, ThreeVertexAttributes)
+{
+    const std::string vertexShader =
+        R"(attribute vec2 position;
+attribute vec4 color1;
+attribute vec4 color2;
+varying vec4 color;
+void main()
+{
+    gl_Position = vec4(position, 0, 1);
+    color = color1 + color2;
+})";
+
+    const std::string fragmentShader =
+        R"(precision mediump float;
+varying vec4 color;
+void main()
+{
+    gl_FragColor = color;
+}
+)";
+
+    ANGLE_GL_PROGRAM(program, vertexShader, fragmentShader);
+
+    glUseProgram(program);
+
+    GLint color1Loc = glGetAttribLocation(program, "color1");
+    GLint color2Loc = glGetAttribLocation(program, "color2");
+    ASSERT_NE(-1, color1Loc);
+    ASSERT_NE(-1, color2Loc);
+
+    const auto &indices = GetQuadIndices();
+
+    // Make colored corners with red == x or 1 -x , and green = y or 1 - y.
+
+    std::array<GLColor, 4> baseColors1 = {
+        {GLColor::black, GLColor::red, GLColor::green, GLColor::yellow}};
+    std::array<GLColor, 4> baseColors2 = {
+        {GLColor::yellow, GLColor::green, GLColor::red, GLColor::black}};
+
+    std::vector<GLColor> colors1;
+    std::vector<GLColor> colors2;
+
+    for (GLushort index : indices)
+    {
+        colors1.push_back(baseColors1[index]);
+        colors2.push_back(baseColors2[index]);
+    }
+
+    GLBuffer color1Buffer;
+    glBindBuffer(GL_ARRAY_BUFFER, color1Buffer);
+    glBufferData(GL_ARRAY_BUFFER, colors1.size() * sizeof(GLColor), colors1.data(), GL_STATIC_DRAW);
+    glVertexAttribPointer(color1Loc, 4, GL_UNSIGNED_BYTE, GL_TRUE, 0, nullptr);
+    glEnableVertexAttribArray(color1Loc);
+
+    GLBuffer color2Buffer;
+    glBindBuffer(GL_ARRAY_BUFFER, color2Buffer);
+    glBufferData(GL_ARRAY_BUFFER, colors2.size() * sizeof(GLColor), colors2.data(), GL_STATIC_DRAW);
+    glVertexAttribPointer(color2Loc, 4, GL_UNSIGNED_BYTE, GL_TRUE, 0, nullptr);
+    glEnableVertexAttribArray(color2Loc);
+
+    // Draw a non-indexed quad with all vertex buffers. Should draw yellow to the entire window.
+    drawQuad(program, "position", 0.5f, 1.0f, true);
+    ASSERT_GL_NO_ERROR();
+    EXPECT_PIXEL_RECT_EQ(0, 0, getWindowWidth(), getWindowHeight(), GLColor::yellow);
+}
+
+// Creates a texture, no other operations.
+TEST_P(SimpleOperationTest, CreateTexture2DNoData)
+{
+    GLTexture texture;
+    glBindTexture(GL_TEXTURE_2D, texture);
+    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 16, 16, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
+    ASSERT_GL_NO_ERROR();
+}
+
+// Creates a texture, no other operations.
+TEST_P(SimpleOperationTest, CreateTexture2DWithData)
+{
+    std::vector<GLColor> colors(16 * 16, GLColor::red);
+
+    GLTexture texture;
+    glBindTexture(GL_TEXTURE_2D, texture);
+    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 16, 16, 0, GL_RGBA, GL_UNSIGNED_BYTE, colors.data());
+    ASSERT_GL_NO_ERROR();
+}
+
+// Creates a program with a texture.
+TEST_P(SimpleOperationTest, LinkProgramWithTexture)
+{
+    ASSERT_NE(0u, get2DTexturedQuadProgram());
+    EXPECT_GL_NO_ERROR();
+}
+
+// Creates a program with a texture and renders with it.
+TEST_P(SimpleOperationTest, DrawWithTexture)
+{
+    std::array<GLColor, 4> colors = {
+        {GLColor::red, GLColor::green, GLColor::blue, GLColor::yellow}};
+
+    GLTexture tex;
+    glBindTexture(GL_TEXTURE_2D, tex);
+    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE, colors.data());
+    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+
+    draw2DTexturedQuad(0.5f, 1.0f, true);
+    EXPECT_GL_NO_ERROR();
+
+    int w = getWindowWidth() - 2;
+    int h = getWindowHeight() - 2;
+
+    EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::red);
+    EXPECT_PIXEL_COLOR_EQ(w, 0, GLColor::green);
+    EXPECT_PIXEL_COLOR_EQ(0, h, GLColor::blue);
+    EXPECT_PIXEL_COLOR_EQ(w, h, GLColor::yellow);
+}
+
+// Tests rendering to a user framebuffer.
+TEST_P(SimpleOperationTest, RenderToTexture)
+{
+    constexpr int kSize = 16;
+
+    GLTexture texture;
+    glBindTexture(GL_TEXTURE_2D, texture);
+    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, kSize, kSize, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
+    ASSERT_GL_NO_ERROR();
+
+    GLFramebuffer framebuffer;
+    glBindFramebuffer(GL_FRAMEBUFFER, framebuffer);
+    glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture, 0);
+    ASSERT_GL_NO_ERROR();
+    ASSERT_GLENUM_EQ(GL_FRAMEBUFFER_COMPLETE, glCheckFramebufferStatus(GL_FRAMEBUFFER));
+
+    glViewport(0, 0, kSize, kSize);
+
+    const std::string &vertexShader =
+        "attribute vec3 position;\n"
+        "void main()\n"
+        "{\n"
+        "    gl_Position = vec4(position, 1);\n"
+        "}";
+    const std::string &fragmentShader =
+        "void main()\n"
+        "{\n"
+        "    gl_FragColor = vec4(0, 1, 0, 1);\n"
+        "}";
+    ANGLE_GL_PROGRAM(program, vertexShader, fragmentShader);
+    drawQuad(program, "position", 0.5f, 1.0f, true);
+    ASSERT_GL_NO_ERROR();
+    EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
+}
+
 // Use this to select which configurations (e.g. which renderer, which GLES major version) these tests should be run against.
 ANGLE_INSTANTIATE_TEST(SimpleOperationTest,
                        ES2_D3D9(),
                        ES2_D3D11(EGL_EXPERIMENTAL_PRESENT_PATH_COPY_ANGLE),
                        ES2_D3D11(EGL_EXPERIMENTAL_PRESENT_PATH_FAST_ANGLE),
                        ES3_D3D11(),
                        ES2_OPENGL(),
                        ES3_OPENGL(),
--- a/gfx/angle/src/tests/gl_tests/SixteenBppTextureTest.cpp
+++ b/gfx/angle/src/tests/gl_tests/SixteenBppTextureTest.cpp
@@ -144,25 +144,16 @@ class SixteenBppTextureTest : public ANG
 class SixteenBppTextureTestES3 : public SixteenBppTextureTest
 {
 };
 
 // Simple validation test for GL_RGB565 textures.
 // Samples from the texture, renders to it, generates mipmaps etc.
 TEST_P(SixteenBppTextureTest, RGB565Validation)
 {
-    // These tests fail on certain Intel machines running an un-updated version of Win7
-    // The tests pass after installing the latest updates from Windows Update.
-    // TODO: reenable these tests once the bots have been updated
-    if (IsIntel() && getPlatformRenderer() == EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE)
-    {
-        std::cout << "Test skipped on Intel D3D11." << std::endl;
-        return;
-    }
-
     GLuint test;
     memcpy(&test, &GLColor::black, 4);
 
     R5G6B5 pixels[4] = {Convert565(GLColor::red), Convert565(GLColor::green),
                         Convert565(GLColor::blue), Convert565(GLColor::yellow)};
 
     glClearColor(0, 0, 0, 0);
 
@@ -180,25 +171,16 @@ TEST_P(SixteenBppTextureTest, RGB565Vali
 
     simpleValidationBase(tex.get());
 }
 
 // Simple validation test for GL_RGBA5551 textures.
 // Samples from the texture, renders to it, generates mipmaps etc.
 TEST_P(SixteenBppTextureTest, RGBA5551Validation)
 {
-    // These tests fail on certain Intel machines running an un-updated version of Win7
-    // The tests pass after installing the latest updates from Windows Update.
-    // TODO: reenable these tests once the bots have been updated
-    if (IsIntel() && getPlatformRenderer() == EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE)
-    {
-        std::cout << "Test skipped on Intel D3D11." << std::endl;
-        return;
-    }
-
     GLushort pixels[4] =
     {
         0xF801, // Red
         0x07C1, // Green
         0x003F, // Blue
         0xFFC1  // Red + Green
     };
 
@@ -215,25 +197,16 @@ TEST_P(SixteenBppTextureTest, RGBA5551Va
 
     simpleValidationBase(tex.get());
 }
 
 // Test to ensure calling Clear() on an RGBA5551 texture does something reasonable
 // Based on WebGL test conformance/textures/texture-attachment-formats.html
 TEST_P(SixteenBppTextureTest, RGBA5551ClearAlpha)
 {
-    // These tests fail on certain Intel machines running an un-updated version of Win7
-    // The tests pass after installing the latest updates from Windows Update.
-    // TODO: reenable these tests once the bots have been updated
-    if (IsIntel() && getPlatformRenderer() == EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE)
-    {
-        std::cout << "Test skipped on Intel D3D11." << std::endl;
-        return;
-    }
-
     GLTexture tex;
     GLFramebuffer fbo;
 
     // Create a simple 5551 texture
     glBindTexture(GL_TEXTURE_2D, tex.get());
     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 2, 2, 0, GL_RGBA, GL_UNSIGNED_SHORT_5_5_5_1, nullptr);
     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
@@ -259,25 +232,16 @@ TEST_P(SixteenBppTextureTest, RGBA5551Cl
         std::cout << "Skipping rendering to an unsupported framebuffer format" << std::endl;
     }
 }
 
 // Simple validation test for GL_RGBA4444 textures.
 // Samples from the texture, renders to it, generates mipmaps etc.
 TEST_P(SixteenBppTextureTest, RGBA4444Validation)
 {
-    // These tests fail on certain Intel machines running an un-updated version of Win7
-    // The tests pass after installing the latest updates from Windows Update.
-    // TODO: reenable these tests once the bots have been updated
-    if (IsIntel() && getPlatformRenderer() == EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE)
-    {
-        std::cout << "Test skipped on Intel D3D11." << std::endl;
-        return;
-    }
-
     GLushort pixels[4] =
     {
         0xF00F, // Red
         0x0F0F, // Green
         0x00FF, // Blue
         0xFF0F  // Red + Green
     };
 
--- a/gfx/angle/src/tests/gl_tests/StateChangeTest.cpp
+++ b/gfx/angle/src/tests/gl_tests/StateChangeTest.cpp
@@ -68,18 +68,16 @@ class StateChangeTest : public ANGLETest
 };
 
 class StateChangeTestES3 : public StateChangeTest
 {
   protected:
     StateChangeTestES3() {}
 };
 
-}  // anonymous namespace
-
 // Ensure that CopyTexImage2D syncs framebuffer changes.
 TEST_P(StateChangeTest, CopyTexImage2DSync)
 {
     if (IsAMD() && getPlatformRenderer() == EGL_PLATFORM_ANGLE_TYPE_OPENGL_ANGLE)
     {
         // TODO(geofflang): Fix on Linux AMD drivers (http://anglebug.com/1291)
         std::cout << "Test disabled on AMD OpenGL." << std::endl;
         return;
@@ -735,15 +733,355 @@ TEST_P(StateChangeTestES3, VertexArrayOb
     // Re-bind VAO and try to draw with different program, without changing state.
     // Should draw black since current value is not initialized.
     glBindVertexArray(vertexArray);
     glDrawArrays(GL_TRIANGLES, 0, 6);
     ASSERT_GL_NO_ERROR();
     EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::black);
 }
 
+// Simple state change tests, primarily focused on basic object lifetime and dependency management
+// with back-ends that don't support that automatically (i.e. Vulkan).
+class SimpleStateChangeTest : public ANGLETest
+{
+  protected:
+    SimpleStateChangeTest()
+    {
+        setWindowWidth(64);
+        setWindowHeight(64);
+        setConfigRedBits(8);
+        setConfigGreenBits(8);
+        setConfigBlueBits(8);
+        setConfigAlphaBits(8);
+    }
+
+    void simpleDrawWithBuffer(GLBuffer *buffer);
+    void simpleDrawWithColor(const GLColor &color);
+};
+
+constexpr char kSimpleVertexShader[] = R"(attribute vec2 position;
+attribute vec4 color;
+varying vec4 vColor;
+void main()
+{
+    gl_Position = vec4(position, 0, 1);
+    vColor = color;
+}
+)";
+
+constexpr char kSimpleFragmentShader[] = R"(precision mediump float;
+varying vec4 vColor;
+void main()
+{
+    gl_FragColor = vColor;
+}
+)";
+
+void SimpleStateChangeTest::simpleDrawWithBuffer(GLBuffer *buffer)
+{
+    ANGLE_GL_PROGRAM(program, kSimpleVertexShader, kSimpleFragmentShader);
+    glUseProgram(program);
+
+    GLint colorLoc = glGetAttribLocation(program, "color");
+    ASSERT_NE(-1, colorLoc);
+
+    glBindBuffer(GL_ARRAY_BUFFER, *buffer);
+    glVertexAttribPointer(colorLoc, 4, GL_UNSIGNED_BYTE, GL_TRUE, 0, nullptr);
+    glEnableVertexAttribArray(colorLoc);
+
+    drawQuad(program, "position", 0.5f, 1.0f, true);
+    ASSERT_GL_NO_ERROR();
+}
+
+void SimpleStateChangeTest::simpleDrawWithColor(const GLColor &color)
+{
+    std::vector<GLColor> colors(6, color);
+    GLBuffer colorBuffer;
+    glBindBuffer(GL_ARRAY_BUFFER, colorBuffer);
+    glBufferData(GL_ARRAY_BUFFER, colors.size() * sizeof(GLColor), colors.data(), GL_STATIC_DRAW);
+    simpleDrawWithBuffer(&colorBuffer);
+}
+
+// Handles deleting a Buffer when it's being used.
+TEST_P(SimpleStateChangeTest, DeleteBufferInUse)
+{
+    std::vector<GLColor> colorData(6, GLColor::red);
+
+    GLBuffer buffer;
+    glBindBuffer(GL_ARRAY_BUFFER, buffer);
+    glBufferData(GL_ARRAY_BUFFER, sizeof(GLColor) * colorData.size(), colorData.data(),
+                 GL_STATIC_DRAW);
+
+    simpleDrawWithBuffer(&buffer);
+
+    buffer.reset();
+    EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::red);
+}
+
+// Tests that resizing a Buffer during a draw works as expected.
+TEST_P(SimpleStateChangeTest, RedefineBufferInUse)
+{
+    std::vector<GLColor> redColorData(6, GLColor::red);
+
+    GLBuffer buffer;
+    glBindBuffer(GL_ARRAY_BUFFER, buffer);
+    glBufferData(GL_ARRAY_BUFFER, sizeof(GLColor) * redColorData.size(), redColorData.data(),
+                 GL_STATIC_DRAW);
+
+    // Trigger a pull from the buffer.
+    simpleDrawWithBuffer(&buffer);
+
+    // Redefine the buffer that's in-flight.
+    std::vector<GLColor> greenColorData(1024, GLColor::green);
+    glBufferData(GL_ARRAY_BUFFER, sizeof(GLColor) * greenColorData.size(), greenColorData.data(),
+                 GL_STATIC_DRAW);
+
+    // Trigger the flush and verify the first draw worked.
+    EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::red);
+
+    // Draw again and verify the new data is correct.
+    simpleDrawWithBuffer(&buffer);
+    EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
+}
+
+// Tests updating a buffer's contents while in use, without redefining it.
+TEST_P(SimpleStateChangeTest, UpdateBufferInUse)
+{
+    std::vector<GLColor> redColorData(6, GLColor::red);
+
+    GLBuffer buffer;
+    glBindBuffer(GL_ARRAY_BUFFER, buffer);
+    glBufferData(GL_ARRAY_BUFFER, sizeof(GLColor) * redColorData.size(), redColorData.data(),
+                 GL_STATIC_DRAW);
+
+    // Trigger a pull from the buffer.
+    simpleDrawWithBuffer(&buffer);
+
+    // Update the buffer that's in-flight.
+    std::vector<GLColor> greenColorData(6, GLColor::green);
+    glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(GLColor) * greenColorData.size(),
+                    greenColorData.data());
+
+    // Trigger the flush and verify the first draw worked.
+    EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::red);
+
+    // Draw again and verify the new data is correct.
+    simpleDrawWithBuffer(&buffer);
+    EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
+}
+
+// Tests that deleting an in-flight Texture does not immediately delete the resource.
+TEST_P(SimpleStateChangeTest, DeleteTextureInUse)
+{
+    std::array<GLColor, 4> colors = {
+        {GLColor::red, GLColor::green, GLColor::blue, GLColor::yellow}};
+
+    GLTexture tex;
+    glBindTexture(GL_TEXTURE_2D, tex);
+    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE, colors.data());
+    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+
+    draw2DTexturedQuad(0.5f, 1.0f, true);
+    tex.reset();
+    EXPECT_GL_NO_ERROR();
+
+    int w = getWindowWidth() - 2;
+    int h = getWindowHeight() - 2;
+
+    EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::red);
+    EXPECT_PIXEL_COLOR_EQ(w, 0, GLColor::green);
+    EXPECT_PIXEL_COLOR_EQ(0, h, GLColor::blue);
+    EXPECT_PIXEL_COLOR_EQ(w, h, GLColor::yellow);
+}
+
+// Tests that redefining an in-flight Texture does not affect the in-flight resource.
+TEST_P(SimpleStateChangeTest, RedefineTextureInUse)
+{
+    std::array<GLColor, 4> colors = {
+        {GLColor::red, GLColor::green, GLColor::blue, GLColor::yellow}};
+
+    GLTexture tex;
+    glBindTexture(GL_TEXTURE_2D, tex);
+    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE, colors.data());
+    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+
+    // Draw with the first texture.
+    draw2DTexturedQuad(0.5f, 1.0f, true);
+
+    // Redefine the in-flight texture.
+    constexpr int kBigSize = 32;
+    std::vector<GLColor> bigColors;
+    for (int y = 0; y < kBigSize; ++y)
+    {
+        for (int x = 0; x < kBigSize; ++x)
+        {
+            bool xComp = x < kBigSize / 2;
+            bool yComp = y < kBigSize / 2;
+            if (yComp)
+            {
+                bigColors.push_back(xComp ? GLColor::cyan : GLColor::magenta);
+            }
+            else
+            {
+                bigColors.push_back(xComp ? GLColor::yellow : GLColor::white);
+            }
+        }
+    }
+
+    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 32, 32, 0, GL_RGBA, GL_UNSIGNED_BYTE, bigColors.data());
+    EXPECT_GL_NO_ERROR();
+
+    // Verify the first draw had the correct data via ReadPixels.
+    int w = getWindowWidth() - 2;
+    int h = getWindowHeight() - 2;
+
+    EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::red);
+    EXPECT_PIXEL_COLOR_EQ(w, 0, GLColor::green);
+    EXPECT_PIXEL_COLOR_EQ(0, h, GLColor::blue);
+    EXPECT_PIXEL_COLOR_EQ(w, h, GLColor::yellow);
+
+    // Draw and verify with the redefined data.
+    draw2DTexturedQuad(0.5f, 1.0f, true);
+    EXPECT_GL_NO_ERROR();
+
+    EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::cyan);
+    EXPECT_PIXEL_COLOR_EQ(w, 0, GLColor::magenta);
+    EXPECT_PIXEL_COLOR_EQ(0, h, GLColor::yellow);
+    EXPECT_PIXEL_COLOR_EQ(w, h, GLColor::white);
+}
+
+// Test updating a Texture's contents while in use by GL works as expected.
+TEST_P(SimpleStateChangeTest, UpdateTextureInUse)
+{
+    std::array<GLColor, 4> rgby = {{GLColor::red, GLColor::green, GLColor::blue, GLColor::yellow}};
+
+    GLTexture tex;
+    glBindTexture(GL_TEXTURE_2D, tex);
+    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE, rgby.data());
+    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+
+    // Draw RGBY to the Framebuffer. The texture is now in-use by GL.
+    draw2DTexturedQuad(0.5f, 1.0f, true);
+
+    // Update the texture to be YBGR, while the Texture is in-use. Should not affect the draw.
+    std::array<GLColor, 4> ybgr = {{GLColor::yellow, GLColor::blue, GLColor::green, GLColor::red}};
+    glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 2, 2, GL_RGBA, GL_UNSIGNED_BYTE, ybgr.data());
+    ASSERT_GL_NO_ERROR();
+
+    // Check the Framebuffer. The draw call should have completed with the original RGBY data.
+    int w = getWindowWidth() - 2;
+    int h = getWindowHeight() - 2;
+
+    EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::red);
+    EXPECT_PIXEL_COLOR_EQ(w, 0, GLColor::green);
+    EXPECT_PIXEL_COLOR_EQ(0, h, GLColor::blue);
+    EXPECT_PIXEL_COLOR_EQ(w, h, GLColor::yellow);
+
+    // Draw again to the Framebuffer. The second draw call should use the updated YBGR data.
+    draw2DTexturedQuad(0.5f, 1.0f, true);
+
+    EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::yellow);
+    EXPECT_PIXEL_COLOR_EQ(w, 0, GLColor::blue);
+    EXPECT_PIXEL_COLOR_EQ(0, h, GLColor::green);
+    EXPECT_PIXEL_COLOR_EQ(w, h, GLColor::red);
+    ASSERT_GL_NO_ERROR();
+}
+
+const char kSolidColorVertexShader[] = R"(attribute vec2 position;
+void main()
+{
+    gl_Position = vec4(position, 0, 1);
+})";
+
+const char kSolidColorFragmentShader[] = R"(void main()
+{
+    gl_FragColor = vec4(1, 0, 0, 1);
+})";
+
+// Tests deleting a Framebuffer that is in use.
+TEST_P(SimpleStateChangeTest, DeleteFramebufferInUse)
+{
+    constexpr int kSize = 16;
+
+    // Create a simple framebuffer.
+    GLTexture texture;
+    glBindTexture(GL_TEXTURE_2D, texture);
+    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, kSize, kSize, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
+
+    GLFramebuffer framebuffer;
+    glBindFramebuffer(GL_FRAMEBUFFER, framebuffer);
+    glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture, 0);
+    ASSERT_GLENUM_EQ(GL_FRAMEBUFFER_COMPLETE, glCheckFramebufferStatus(GL_FRAMEBUFFER));
+
+    glViewport(0, 0, kSize, kSize);
+
+    // Draw a solid red color to the framebuffer.
+    ANGLE_GL_PROGRAM(program, kSolidColorVertexShader, kSolidColorFragmentShader);
+    drawQuad(program, "position", 0.5f, 1.0f, true);
+
+    // Delete the framebuffer while the call is in flight.
+    framebuffer.reset();
+
+    // Make a new framebuffer so we can read back the texture.
+    glBindFramebuffer(GL_FRAMEBUFFER, framebuffer);
+    glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture, 0);
+    ASSERT_GLENUM_EQ(GL_FRAMEBUFFER_COMPLETE, glCheckFramebufferStatus(GL_FRAMEBUFFER));
+
+    // Flush via ReadPixels and check red was drawn.
+    EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::red);
+    ASSERT_GL_NO_ERROR();
+}
+
+// Tests deleting a Framebuffer that is in use.
+TEST_P(SimpleStateChangeTest, RedefineFramebufferInUse)
+{
+    constexpr int kSize = 16;
+
+    // Create a simple framebuffer.
+    GLTexture texture;
+    glBindTexture(GL_TEXTURE_2D, texture);
+    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, kSize, kSize, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
+
+    GLFramebuffer framebuffer;
+    glBindFramebuffer(GL_FRAMEBUFFER, framebuffer);
+    glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture, 0);
+    ASSERT_GLENUM_EQ(GL_FRAMEBUFFER_COMPLETE, glCheckFramebufferStatus(GL_FRAMEBUFFER));
+
+    glViewport(0, 0, kSize, kSize);
+
+    // Draw red to the framebuffer.
+    simpleDrawWithColor(GLColor::red);
+
+    // Change the framebuffer while the call is in flight to a new texture.
+    GLTexture otherTexture;
+    glBindTexture(GL_TEXTURE_2D, otherTexture);
+    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, kSize, kSize, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
+
+    glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, otherTexture, 0);
+    ASSERT_GLENUM_EQ(GL_FRAMEBUFFER_COMPLETE, glCheckFramebufferStatus(GL_FRAMEBUFFER));
+
+    // Draw green to the framebuffer. Verify the color.
+    simpleDrawWithColor(GLColor::green);
+    EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
+
+    // Make a new framebuffer so we can read back the first texture and verify red.
+    glBindFramebuffer(GL_FRAMEBUFFER, framebuffer);
+    glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture, 0);
+    ASSERT_GLENUM_EQ(GL_FRAMEBUFFER_COMPLETE, glCheckFramebufferStatus(GL_FRAMEBUFFER));
+
+    EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::red);
+    ASSERT_GL_NO_ERROR();
+}
+
+}  // anonymous namespace
+
 ANGLE_INSTANTIATE_TEST(StateChangeTest, ES2_D3D9(), ES2_D3D11(), ES2_OPENGL());
 ANGLE_INSTANTIATE_TEST(StateChangeRenderTest,
                        ES2_D3D9(),
                        ES2_D3D11(),
                        ES2_OPENGL(),
                        ES2_D3D11_FL9_3());
 ANGLE_INSTANTIATE_TEST(StateChangeTestES3, ES3_D3D11(), ES3_OPENGL());
+
+ANGLE_INSTANTIATE_TEST(SimpleStateChangeTest, ES2_VULKAN(), ES2_OPENGL());
--- a/gfx/angle/src/tests/gl_tests/SyncQueriesTest.cpp
+++ b/gfx/angle/src/tests/gl_tests/SyncQueriesTest.cpp
@@ -55,17 +55,17 @@ TEST_P(SyncQueriesTest, Basic)
     glClearColor(0.0, 0.0, 1.0, 1.0);
     glClear(GL_COLOR_BUFFER_BIT);
 
     glEndQueryEXT(GL_COMMANDS_COMPLETED_CHROMIUM);
 
     glFlush();
     GLuint result = 0;
     glGetQueryObjectuivEXT(mQuery, GL_QUERY_RESULT_EXT, &result);
-    EXPECT_EQ(static_cast<GLuint>(GL_TRUE), result);
+    EXPECT_GL_TRUE(result);
     EXPECT_GL_NO_ERROR();
 }
 
 // Test that the sync query enums are not accepted unless the extension is available
 TEST_P(SyncQueriesTest, Validation)
 {
     // Need the GL_EXT_occlusion_query_boolean extension for the entry points
     if (!extensionEnabled("GL_EXT_occlusion_query_boolean"))
--- a/gfx/angle/src/tests/gl_tests/TextureRectangleTest.cpp
+++ b/gfx/angle/src/tests/gl_tests/TextureRectangleTest.cpp
@@ -335,16 +335,36 @@ TEST_P(TextureRectangleTest, RenderToRec
 
     // Clearing a texture is just as good as checking we can render to it, right?
     glClearColor(0.0, 1.0, 0.0, 1.0);
     glClear(GL_COLOR_BUFFER_BIT);
     EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
     ASSERT_GL_NO_ERROR();
 }
 
+TEST_P(TextureRectangleTest, DefaultSamplerParameters)
+{
+    ANGLE_SKIP_TEST_IF(!checkExtensionSupported());
+
+    GLTexture tex;
+    glBindTexture(GL_TEXTURE_RECTANGLE_ANGLE, tex);
+
+    GLint minFilter = 0;
+    glGetTexParameteriv(GL_TEXTURE_RECTANGLE_ANGLE, GL_TEXTURE_MIN_FILTER, &minFilter);
+    EXPECT_EQ(GL_LINEAR, minFilter);
+
+    GLint wrapS = 0;
+    glGetTexParameteriv(GL_TEXTURE_RECTANGLE_ANGLE, GL_TEXTURE_WRAP_S, &wrapS);
+    EXPECT_EQ(GL_CLAMP_TO_EDGE, wrapS);
+
+    GLint wrapT = 0;
+    glGetTexParameteriv(GL_TEXTURE_RECTANGLE_ANGLE, GL_TEXTURE_WRAP_T, &wrapT);
+    EXPECT_EQ(GL_CLAMP_TO_EDGE, wrapT);
+}
+
 // Test glCopyTexImage with rectangle textures
 TEST_P(TextureRectangleTestES3, CopyTexImage)
 {
     ANGLE_SKIP_TEST_IF(!checkExtensionSupported());
 
     GLTexture tex;
     glBindTexture(GL_TEXTURE_RECTANGLE_ANGLE, tex);
 
--- a/gfx/angle/src/tests/gl_tests/TextureTest.cpp
+++ b/gfx/angle/src/tests/gl_tests/TextureTest.cpp
@@ -169,23 +169,16 @@ class Texture2DTest : public TexCoordDra
     {
         glDeleteTextures(1, &mTexture2D);
         TexCoordDrawTest::TearDown();
     }
 
     // Tests CopyTexSubImage with floating point textures of various formats.
     void testFloatCopySubImage(int sourceImageChannels, int destImageChannels)
     {
-        // TODO(jmadill): Figure out why this is broken on Intel D3D11
-        if (IsIntel() && getPlatformRenderer() == EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE)
-        {
-            std::cout << "Test skipped on Intel D3D11." << std::endl;
-            return;
-        }
-
         setUpProgram();
 
         if (getClientMajorVersion() < 3)
         {
             if (!extensionEnabled("GL_EXT_texture_storage"))
             {
                 std::cout << "Test skipped due to missing GL_EXT_texture_storage." << std::endl;
                 return;
@@ -1488,19 +1481,18 @@ TEST_P(Texture2DTest, TexStorage)
     glUseProgram(mProgram);
     glUniform1i(mTexture2DUniformLocation, 0);
     drawQuad(mProgram, "position", 0.5f);
     glDeleteTextures(1, &tex2D);
     EXPECT_GL_NO_ERROR();
     EXPECT_PIXEL_EQ(width / 4, height / 4, 255, 0, 0, 255);
 
     // Validate that the region of the texture without data has an alpha of 1.0
-    GLubyte pixel[4];
-    glReadPixels(3 * width / 4, 3 * height / 4, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, pixel);
-    EXPECT_EQ(pixel[3], 255);
+    angle::GLColor pixel = ReadColor(3 * width / 4, 3 * height / 4);
+    EXPECT_EQ(255, pixel.A);
 }
 
 // Test that glTexSubImage2D combined with a PBO works properly when glTexStorage2DEXT has initialized the image with a default color.
 TEST_P(Texture2DTest, TexStorageWithPBO)
 {
     if (extensionEnabled("NV_pixel_buffer_object"))
     {
         int width = getWindowWidth();
@@ -1730,37 +1722,29 @@ TEST_P(Texture2DTest, TextureNPOT_GL_ALP
     EXPECT_PIXEL_EQ(getWindowWidth() / 2, getWindowHeight() / 2, 0, 0, 0, 64);
     EXPECT_GL_NO_ERROR();
 }
 
 // Test to ensure that glTexSubImage2D always accepts data for non-power-of-two subregions.
 // ANGLE previously rejected this if GL_OES_texture_npot wasn't active, which is incorrect.
 TEST_P(Texture2DTest, NPOTSubImageParameters)
 {
-    // TODO(geofflang): Allow the GL backend to accept SubImage calls with a null data ptr. (bug
-    // 1278)
-    if (getPlatformRenderer() == EGL_PLATFORM_ANGLE_TYPE_OPENGL_ANGLE ||
-        getPlatformRenderer() == EGL_PLATFORM_ANGLE_TYPE_OPENGLES_ANGLE)
-    {
-        std::cout << "Test disabled on OpenGL." << std::endl;
-        return;
-    }
-
     glActiveTexture(GL_TEXTURE0);
     glBindTexture(GL_TEXTURE_2D, mTexture2D);
 
     // Create an 8x8 (i.e. power-of-two) texture.
     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 8, 8, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_NEAREST);
     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
     glGenerateMipmap(GL_TEXTURE_2D);
 
     // Supply a 3x3 (i.e. non-power-of-two) subimage to the texture.
     // This should always work, even if GL_OES_texture_npot isn't active.
-    glTexSubImage2D(GL_TEXTURE_2D, 1, 0, 0, 3, 3, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
+    std::array<GLColor, 3 * 3> data;
+    glTexSubImage2D(GL_TEXTURE_2D, 1, 0, 0, 3, 3, GL_RGBA, GL_UNSIGNED_BYTE, data.data());
 
     EXPECT_GL_NO_ERROR();
 }
 
 // Test to check that texture completeness is determined correctly when the texture base level is
 // greater than 0, and also that level 0 is not sampled when base level is greater than 0.
 TEST_P(Texture2DTestES3, DrawWithBaseLevel1)
 {
@@ -2528,19 +2512,19 @@ TEST_P(SamplerTypeMixTestES3, SamplerTyp
     // 0.125 * <comparison result (0.0)>
     EXPECT_PIXEL_NEAR(0, 0, 64, 154, 184, 255, 2);
 }
 
 // Test different base levels on textures accessed through the same sampler array.
 // Calling textureSize() on the samplers hits the D3D sampler metadata workaround.
 TEST_P(TextureSizeTextureArrayTest, BaseLevelVariesInTextureArray)
 {
-    if ((IsAMD() || IsIntel()) && getPlatformRenderer() == EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE)
+    if (IsAMD() && IsD3D11())
     {
-        std::cout << "Test skipped on Intel and AMD D3D." << std::endl;
+        std::cout << "Test skipped on AMD D3D." << std::endl;
         return;
     }
     glActiveTexture(GL_TEXTURE0);
     glBindTexture(GL_TEXTURE_2D, mTexture2DA);
     GLsizei size = 64;
     for (GLint level = 0; level < 7; ++level)
     {
         ASSERT_LT(0, size);
@@ -2861,52 +2845,36 @@ TEST_P(SamplerInStructAsFunctionParamete
 {
     // TODO(ynovikov): re-enable once root cause of http://anglebug.com/1427 is fixed
     if (IsAndroid() && IsAdreno() && IsOpenGLES())
     {
         std::cout << "Test skipped on Adreno OpenGLES on Android." << std::endl;
         return;
     }
 
-    if (IsWindows() && IsIntel() && IsOpenGL())
-    {
-        std::cout << "Test skipped on Windows OpenGL on Intel." << std::endl;
-        return;
-    }
-
     runSamplerInStructTest();
 }
 
 // Use a sampler in a uniform struct array with a struct from the array passed as a function
 // parameter.
 TEST_P(SamplerInStructArrayAsFunctionParameterTest, SamplerInStructArrayAsFunctionParameter)
 {
-    if (IsIntel() && GetParam().getRenderer() == EGL_PLATFORM_ANGLE_TYPE_OPENGL_ANGLE)
-    {
-        std::cout << "Test skipped on Intel OpenGL." << std::endl;
-        return;
-    }
     // TODO(ynovikov): re-enable once root cause of http://anglebug.com/1427 is fixed
     if (IsAndroid() && IsAdreno() && IsOpenGLES())
     {
         std::cout << "Test skipped on Adreno OpenGLES on Android." << std::endl;
         return;
     }
     runSamplerInStructTest();
 }
 
 // Use a sampler in a struct inside a uniform struct with the nested struct passed as a function
 // parameter.
 TEST_P(SamplerInNestedStructAsFunctionParameterTest, SamplerInNestedStructAsFunctionParameter)
 {
-    if (IsIntel() && GetParam().getRenderer() == EGL_PLATFORM_ANGLE_TYPE_OPENGL_ANGLE)
-    {
-        std::cout << "Test skipped on Intel OpenGL." << std::endl;
-        return;
-    }
     // TODO(ynovikov): re-enable once root cause of http://anglebug.com/1427 is fixed
     if (IsAndroid() && IsAdreno() && IsOpenGLES())
     {
         std::cout << "Test skipped on Adreno OpenGLES on Android." << std::endl;
         return;
     }
     runSamplerInStructTest();
 }
@@ -3689,16 +3657,35 @@ TEST_P(Texture2DTestES3, StaleUnpackData
                     GL_UNSIGNED_BYTE, nullptr);
 
     drawQuad(mProgram, "position", 0.5f);
 
     ASSERT_GL_NO_ERROR();
     EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
 }
 
+// Ensure that texture parameters passed as floats that are converted to ints are rounded before
+// validating they are less than 0.
+TEST_P(Texture2DTestES3, TextureBaseMaxLevelRoundingValidation)
+{
+    GLTexture texture;
+    glBindTexture(GL_TEXTURE_2D, texture);
+
+    // Use a negative number that will round to zero when converted to an integer
+    // According to the spec(2.3.1 Data Conversion For State - Setting Commands):
+    // "Validation of values performed by state-setting commands is performed after conversion,
+    // unless specified otherwise for a specific command."
+    GLfloat param = -7.30157126e-07f;
+    glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, param);
+    EXPECT_GL_NO_ERROR();
+
+    glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, param);
+    EXPECT_GL_NO_ERROR();
+}
+
 // This test covers a D3D format redefinition bug for 3D textures. The base level format was not
 // being properly checked, and the texture storage of the previous texture format was persisting.
 // This would result in an ASSERT in debug and incorrect rendering in release.
 // See http://anglebug.com/1609 and WebGL 2 test conformance2/misc/views-with-offsets.html.
 TEST_P(Texture3DTestES3, FormatRedefinitionBug)
 {
     GLTexture tex;
     glBindTexture(GL_TEXTURE_3D, tex.get());
@@ -3972,16 +3959,17 @@ ANGLE_INSTANTIATE_TEST(Texture2DTest,
                        ES2_D3D9(),
                        ES2_D3D11(),
                        ES2_D3D11_FL9_3(),
                        ES2_OPENGL(),
                        ES2_OPENGLES());
 ANGLE_INSTANTIATE_TEST(TextureCubeTest,
                        ES2_D3D9(),
                        ES2_D3D11(),
+                       ES2_D3D11_FL10_0(),
                        ES2_D3D11_FL9_3(),
                        ES2_OPENGL(),
                        ES2_OPENGLES());
 ANGLE_INSTANTIATE_TEST(Texture2DTestWithDrawScale,
                        ES2_D3D9(),
                        ES2_D3D11(),
                        ES2_D3D11_FL9_3(),
                        ES2_OPENGL(),
new file mode 100644
--- /dev/null
+++ b/gfx/angle/src/tests/gl_tests/TextureUploadFormatTest.cpp
@@ -0,0 +1,682 @@
+//
+// Copyright 2015 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+// Texture upload format tests:
+//   Test all texture unpack/upload formats for sampling correctness.
+//
+
+#include "common/mathutil.h"
+#include "test_utils/ANGLETest.h"
+#include "test_utils/gl_raii.h"
+
+using namespace angle;
+
+namespace
+{
+
+class TextureUploadFormatTest : public ANGLETest
+{
+};
+
+struct TexFormat final
+{
+    GLenum internalFormat;
+    GLenum unpackFormat;
+    GLenum unpackType;
+
+    TexFormat() = delete;
+
+    uint8_t bytesPerPixel() const
+    {
+        uint8_t bytesPerChannel;
+        switch (unpackType)
+        {
+            case GL_UNSIGNED_SHORT_5_6_5:
+            case GL_UNSIGNED_SHORT_4_4_4_4:
+            case GL_UNSIGNED_SHORT_5_5_5_1:
+                return 2;
+
+            case GL_UNSIGNED_INT_2_10_10_10_REV:
+            case GL_UNSIGNED_INT_24_8:
+            case GL_UNSIGNED_INT_10F_11F_11F_REV:
+            case GL_UNSIGNED_INT_5_9_9_9_REV:
+                return 4;
+
+            case GL_FLOAT_32_UNSIGNED_INT_24_8_REV:
+                return 8;
+
+            case GL_UNSIGNED_BYTE:
+            case GL_BYTE:
+                bytesPerChannel = 1;
+                break;
+
+            case GL_UNSIGNED_SHORT:
+            case GL_SHORT:
+            case GL_HALF_FLOAT:
+            case GL_HALF_FLOAT_OES:
+                bytesPerChannel = 2;
+                break;
+
+            case GL_UNSIGNED_INT:
+            case GL_INT:
+            case GL_FLOAT:
+                bytesPerChannel = 4;
+                break;
+
+            default:
+                assert(false);
+                return 0;
+        }
+
+        switch (unpackFormat)
+        {
+            case GL_RGBA:
+            case GL_RGBA_INTEGER:
+                return bytesPerChannel * 4;
+
+            case GL_RGB:
+            case GL_RGB_INTEGER:
+                return bytesPerChannel * 3;
+
+            case GL_RG:
+            case GL_RG_INTEGER:
+            case GL_LUMINANCE_ALPHA:
+                return bytesPerChannel * 2;
+
+            case GL_RED:
+            case GL_RED_INTEGER:
+            case GL_LUMINANCE:
+            case GL_ALPHA:
+            case GL_DEPTH_COMPONENT:
+                return bytesPerChannel * 1;
+
+            default:
+                assert(false);
+                return 0;
+        }
+    }
+};
+
+template <const uint8_t bits>
+constexpr uint32_t EncodeNormUint(const float val)
+{
+    return static_cast<uint32_t>(val * (UINT32_MAX >> (32 - bits)) + 0.5);  // round-half-up
+}
+
+template <const int signBit, const int eBits, const int mBits>
+struct SizedFloat
+{
+    static constexpr int kSignBit = signBit;
+    static constexpr int kEBits   = eBits;
+    static constexpr int kMBits   = mBits;
+
+    static constexpr uint32_t Assemble(const uint32_t sVal,
+                                       const uint32_t eVal,
+                                       const uint32_t mVal)
+    {
+        return (signBit ? (sVal << (eBits + mBits)) : 0) | (eVal << mBits) | mVal;
+    }
+
+    static uint32_t Encode(const float signedV)
+    {
+        const float v = signBit ? fabsf(signedV) : std::max(0.0f, signedV);
+
+        const int eBias   = (1 << (eBits - 1)) - 1;
+        const int eValMax = (1 << eBits) - 1;
+
+        const float eApprox = log2f(v);
+        const auto eActual  = static_cast<int>(floorf(eApprox));
+
+        int eVal      = eBias + eActual;
+        uint32_t mVal = 0;
+        if (v != v)
+        {  // NaN
+            eVal = eValMax;
+            mVal = 1;
+        }
+        else if (eVal < 0)
+        {  // underflow to zero
+            eVal = 0;
+            mVal = 0;
+        }
+        else if (eVal >= eValMax)
+        {  // overfloat to Inf
+            eVal = eValMax;
+            mVal = 0;
+        }
+        else
+        {
+            float mFloat = 0.0;
+            if (eVal == 0)
+            {  // denormal
+                mFloat = v * powf(2, 1 - eBias);
+            }
+            else
+            {  // standard range
+                mFloat = v * powf(2, -static_cast<float>(eActual)) - 1.0f;
+            }
+            mVal = static_cast<uint32_t>(mFloat * (1 << mBits) + 0.5);
+        }
+
+        const auto sVal = static_cast<uint32_t>(v < 0.0f);
+        return Assemble(sVal, eVal, mVal);
+    }
+};
+using Float16  = SizedFloat<1, 5, 10>;
+using UFloat11 = SizedFloat<0, 5, 6>;
+using UFloat10 = SizedFloat<0, 5, 5>;
+
+uint32_t EncodeRGB9_E5_Rev(const float signedR, const float signedG, const float signedB)
+{
+    const float r       = std::max(0.0f, signedR);
+    const float g       = std::max(0.0f, signedG);
+    const float b       = std::max(0.0f, signedB);
+    const int eBits     = 5;
+    const int eBias     = (1 << (eBits - 1)) - 1;  // 15
+    const int eMax      = (1 << eBits) - 1;
+    const int mBits     = 9;
+    const uint32_t mMax = (1 << mBits) - 1;
+    // Maximize mVal for one channel
+    // => Find the lowest viable exponent
+    int minViableActualExp                    = 1 << eBits;
+    const auto fnMinimizeViableActualExponent = [&](const float v) {
+        const auto cur = static_cast<int>(ceil(log2f(v / mMax)));
+        if (cur < minViableActualExp)
+        {
+            minViableActualExp = cur;
+        }
+    };
+    fnMinimizeViableActualExponent(r);
+    fnMinimizeViableActualExponent(g);
+    fnMinimizeViableActualExponent(b);
+    const int eVal = std::max(0, std::min(minViableActualExp + eBias + mBits, eMax));
+
+    const auto fnM = [&](const float v) {
+        const auto m = static_cast<uint32_t>(v * powf(2, static_cast<float>(mBits + eBias - eVal)));
+        return std::min(m, mMax);
+    };
+
+    const auto mR = fnM(r);
+    const auto mG = fnM(g);
+    const auto mB = fnM(b);
+    return (mR << 0) | (mG << 9) | (mB << 18) | (eVal << 27);
+}
+
+}  // anonymous namespace
+
+// Test our encoding code to ensure we get the values out that we expect.
+// We could alternatively hardcode our inputs for these couple cases, but it's nice to do this
+// programatically, since it should make it easier to write any further tests without having to
+// re-encode by hand.
+TEST(TextureUploadFormatTestInternals, Float16Encoding)
+{
+    EXPECT_EQ(Float16::Assemble(0, 0x0f, 0), Float16::Encode(1.0));
+    EXPECT_EQ(Float16::Assemble(0, 0x0f - 1, 0), Float16::Encode(1.0 / 2));
+
+    EXPECT_EQ(Float16::Assemble(0, 0x0f - 3, 0), Float16::Encode(1.0 / 8));
+    EXPECT_EQ(Float16::Assemble(0, 0x0f - 2, 0), Float16::Encode(2.0 / 8));
+    EXPECT_EQ(Float16::Assemble(0, 0x0f - 2, 1 << (Float16::kMBits - 1)), Float16::Encode(3.0 / 8));
+    EXPECT_EQ(Float16::Assemble(0, 0x0f - 1, 1 << (Float16::kMBits - 2)), Float16::Encode(5.0 / 8));
+}
+
+namespace
+{
+
+template <typename DestT, typename SrcT, size_t SrcN>
+void ZeroAndCopy(DestT &dest, const SrcT (&src)[SrcN])
+{
+    dest.fill(0);
+    memcpy(dest.data(), src, sizeof(SrcT) * SrcN);
+}
+
+std::string EnumStr(const GLenum v)
+{
+    std::stringstream ret;
+    ret << "0x" << std::hex << v;
+    return ret.str();
+}
+
+}  // anonymous namespace
+
+// Upload (1,2,5,3) to integer formats, and (1,2,5,3)/8.0 to float formats.
+// Draw a point into a 1x1 renderbuffer and readback the result for comparison with expectations.
+// Test all internalFormat/unpackFormat/unpackType combinations from ES3.0.
+TEST_P(TextureUploadFormatTest, All)
+{
+    ANGLE_SKIP_TEST_IF(IsD3D9() || IsD3D11_FL93());
+
+    constexpr char kVertShader[] = R"(
+        void main()
+        {
+            gl_PointSize = 1.0;
+            gl_Position = vec4(0, 0, 0, 1);
+        })";
+
+    constexpr char kFragShader_Floats[] = R"(
+        precision mediump float;
+        uniform sampler2D uTex;
+
+        void main()
+        {
+            gl_FragColor = texture2D(uTex, vec2(0,0));
+        })";
+    constexpr char kFragShader_Ints[]   = R"(
+        precision mediump float;
+        uniform sampler2D uTex;
+
+        void main()
+        {
+            gl_FragColor = texture2D(uTex, vec2(0,0)) / 8.0;
+        })";
+    ANGLE_GL_PROGRAM(floatsProg, kVertShader, kFragShader_Floats);
+    ANGLE_GL_PROGRAM(intsProg, kVertShader, kFragShader_Ints);
+
+    GLint uTex = glGetUniformLocation(floatsProg, "uTex");
+    ASSERT_NE(uTex, -1);
+    glUseProgram(floatsProg);
+    glUniform1i(uTex, 0);
+
+    uTex = glGetUniformLocation(intsProg, "uTex");
+    ASSERT_NE(uTex, -1);
+    glUseProgram(intsProg);
+    glUniform1i(uTex, 0);
+
+    glDisable(GL_DITHER);
+
+    ASSERT_GL_NO_ERROR();
+
+    // Create the 1x1 framebuffer
+
+    GLRenderbuffer backbufferRB;
+    glBindRenderbuffer(GL_RENDERBUFFER, backbufferRB);
+    glRenderbufferStorage(GL_RENDERBUFFER, GL_RGBA8, 1, 1);
+    glBindRenderbuffer(GL_RENDERBUFFER, 0);
+
+    GLFramebuffer backbufferFB;
+    glBindFramebuffer(GL_FRAMEBUFFER, backbufferFB);
+    glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, backbufferRB);
+    ASSERT_GL_NO_ERROR();
+    ASSERT_GLENUM_EQ(GL_FRAMEBUFFER_COMPLETE, glCheckFramebufferStatus(GL_FRAMEBUFFER));
+
+    glViewport(0, 0, 1, 1);
+
+    // Create and bind our test texture
+
+    GLTexture testTex;
+    glBindTexture(GL_TEXTURE_2D, testTex);
+
+    ASSERT_GL_NO_ERROR();
+
+    // Initialize our test variables
+
+    glPixelStorei(GL_UNPACK_SKIP_PIXELS, 0);
+    const bool hasSubrectUploads = !glGetError();
+
+    constexpr uint8_t srcIntVals[4] = {1u, 2u, 5u, 3u};
+    constexpr float srcVals[4] = {srcIntVals[0] / 8.0f, srcIntVals[1] / 8.0f, srcIntVals[2] / 8.0f,
+                                  srcIntVals[3] / 8.0f};
+    constexpr uint8_t refVals[4] = {static_cast<uint8_t>(EncodeNormUint<8>(srcVals[0])),
+                                    static_cast<uint8_t>(EncodeNormUint<8>(srcVals[1])),
+                                    static_cast<uint8_t>(EncodeNormUint<8>(srcVals[2])),
+                                    static_cast<uint8_t>(EncodeNormUint<8>(srcVals[3]))};
+
+    // Test a format with the specified data
+
+    const auto fnTestData = [&](const TexFormat &format, const void *const data, const GLColor &err,
+                                const char *const info) {
+        ASSERT_GL_NO_ERROR();
+        glTexImage2D(GL_TEXTURE_2D, 0, format.internalFormat, 1, 1, 0, format.unpackFormat,
+                     format.unpackType, data);
+        const auto uploadErr = glGetError();
+        if (uploadErr)
+            return;
+
+        glClearColor(1, 0, 1, 1);
+        glClear(GL_COLOR_BUFFER_BIT);
+        glDrawArrays(GL_POINTS, 0, 1);
+
+        const auto actual = ReadColor(0, 0);
+
+        GLColor expected;
+        switch (format.unpackFormat)
+        {
+            case GL_RGBA:
+            case GL_RGBA_INTEGER:
+                expected = {refVals[0], refVals[1], refVals[2], refVals[3]};
+                break;
+            case GL_RGB:
+                expected = {refVals[0], refVals[1], refVals[2], 255};
+                break;
+            case GL_RG:
+                expected = {refVals[0], refVals[1], 0, 255};
+                break;
+            case GL_RED:
+            case GL_DEPTH_COMPONENT:
+            case GL_DEPTH_STENCIL:
+                expected = {refVals[0], 0, 0, 255};
+                break;
+
+            case GL_RGB_INTEGER:
+                expected = {refVals[0], refVals[1], refVals[2], refVals[0]};
+                break;
+            case GL_RG_INTEGER:
+                expected = {refVals[0], refVals[1], 0, refVals[0]};
+                break;
+            case GL_RED_INTEGER:
+                expected = {refVals[0], 0, 0, refVals[0]};
+                break;
+
+            case GL_LUMINANCE_ALPHA:
+                expected = {refVals[0], refVals[0], refVals[0], refVals[1]};
+                break;
+            case GL_LUMINANCE:
+                expected = {refVals[0], refVals[0], refVals[0], 255};
+                break;
+            case GL_ALPHA:
+                expected = {0, 0, 0, refVals[0]};
+                break;
+
+            default:
+                assert(false);
+        }
+
+        ASSERT_GL_NO_ERROR();
+        auto result = actual.ExpectNear(expected, err);
+        if (!result)
+        {
+            result << " [" << EnumStr(format.internalFormat) << "/" << EnumStr(format.unpackFormat)
+                   << "/" << EnumStr(format.unpackType) << " " << info << "]";
+        }
+        EXPECT_TRUE(result);
+    };
+
+    // Provide buffers for test data, and a func to run the test on both the data directly, and on
+    // a basic subrect selection to ensure pixel byte size is calculated correctly.
+    // Possible todo here is to add tests to ensure stride calculation.
+
+    std::array<uint8_t, sizeof(float) * 4> srcBuffer;
+
+    std::array<uint8_t, srcBuffer.size() * 2> subrectBuffer;
+    const auto fnTest = [&](const TexFormat &format, const GLColor &err) {
+        fnTestData(format, srcBuffer.data(), err, "simple");
+
+        if (!hasSubrectUploads)
+            return;
+
+        const auto bytesPerPixel = format.bytesPerPixel();
+
+        glPixelStorei(GL_UNPACK_SKIP_PIXELS, 1);
+
+        subrectBuffer.fill(0);
+        memcpy(subrectBuffer.data() + bytesPerPixel, srcBuffer.data(), bytesPerPixel);
+        fnTestData(format, subrectBuffer.data(), err, "subrect");
+
+        glPixelStorei(GL_UNPACK_SKIP_PIXELS, 0);
+    };
+
+    // Test All The Formats, organized by unpack format and type.
+    // (Combos from GLES 3.0.5 p111-112: Table 3.2: "Valid combinations of format, type, and sized
+    // internalformat.")
+
+    // Start with normalized ints
+    glUseProgram(floatsProg);
+
+    // RGBA+UNSIGNED_BYTE
+    {
+        constexpr uint8_t src[] = {static_cast<uint8_t>(EncodeNormUint<8>(srcVals[0])),
+                                   static_cast<uint8_t>(EncodeNormUint<8>(srcVals[1])),
+                                   static_cast<uint8_t>(EncodeNormUint<8>(srcVals[2])),
+                                   static_cast<uint8_t>(EncodeNormUint<8>(srcVals[3]))};
+        ZeroAndCopy(srcBuffer, src);
+
+        fnTest({GL_RGBA8, GL_RGBA, GL_UNSIGNED_BYTE}, {1, 1, 1, 1});
+        fnTest({GL_RGB5_A1, GL_RGBA, GL_UNSIGNED_BYTE}, {8, 8, 8, 255});
+        fnTest({GL_RGBA4, GL_RGBA, GL_UNSIGNED_BYTE}, {16, 16, 16, 16});
+
+        fnTest({GL_RGB8, GL_RGB, GL_UNSIGNED_BYTE}, {1, 1, 1, 0});
+        fnTest({GL_RGB565, GL_RGB, GL_UNSIGNED_BYTE}, {8, 4, 8, 0});
+
+        fnTest({GL_RG8, GL_RG, GL_UNSIGNED_BYTE}, {1, 1, 0, 0});
+
+        fnTest({GL_R8, GL_RED, GL_UNSIGNED_BYTE}, {1, 0, 0, 0});
+
+        fnTest({GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE}, {1, 1, 1, 1});
+        fnTest({GL_RGB, GL_RGB, GL_UNSIGNED_BYTE}, {1, 1, 1, 0});
+        fnTest({GL_LUMINANCE_ALPHA, GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE}, {1, 1, 1, 1});
+        fnTest({GL_LUMINANCE, GL_LUMINANCE, GL_UNSIGNED_BYTE}, {1, 1, 1, 0});
+        fnTest({GL_ALPHA, GL_ALPHA, GL_UNSIGNED_BYTE}, {0, 0, 0, 1});
+    }
+
+    // RGBA+BYTE
+    {
+        constexpr uint8_t src[] = {static_cast<uint8_t>(EncodeNormUint<7>(srcVals[0])),
+                                   static_cast<uint8_t>(EncodeNormUint<7>(srcVals[1])),
+                                   static_cast<uint8_t>(EncodeNormUint<7>(srcVals[2])),
+                                   static_cast<uint8_t>(EncodeNormUint<7>(srcVals[3]))};
+        ZeroAndCopy(srcBuffer, src);
+
+        fnTest({GL_RGBA8_SNORM, GL_RGBA, GL_BYTE}, {2, 2, 2, 2});
+        fnTest({GL_RGB8_SNORM, GL_RGB, GL_BYTE}, {2, 2, 2, 0});
+        fnTest({GL_RG8_SNORM, GL_RG, GL_BYTE}, {2, 2, 0, 0});
+        fnTest({GL_R8_SNORM, GL_RED, GL_BYTE}, {2, 0, 0, 0});
+    }
+
+    // RGB+UNSIGNED_SHORT_5_6_5
+    {
+        constexpr uint16_t src[] = {static_cast<uint16_t>((EncodeNormUint<5>(srcVals[0]) << 11) |
+                                                          (EncodeNormUint<6>(srcVals[1]) << 5) |
+                                                          (EncodeNormUint<5>(srcVals[2]) << 0))};
+        ZeroAndCopy(srcBuffer, src);
+
+        fnTest({GL_RGB565, GL_RGB, GL_UNSIGNED_SHORT_5_6_5}, {8, 4, 8, 0});
+        fnTest({GL_RGB, GL_RGB, GL_UNSIGNED_SHORT_5_6_5}, {8, 4, 8, 0});
+    }
+
+    // RGBA+UNSIGNED_SHORT_4_4_4_4
+    {
+        constexpr uint16_t src[] = {static_cast<uint16_t>(
+            (EncodeNormUint<4>(srcVals[0]) << 12) | (EncodeNormUint<4>(srcVals[1]) << 8) |
+            (EncodeNormUint<4>(srcVals[2]) << 4) | (EncodeNormUint<4>(srcVals[3]) << 0))};
+        ZeroAndCopy(srcBuffer, src);
+
+        // fnTest({GL_RGBA4, GL_RGBA, GL_UNSIGNED_SHORT_4_4_4_4}, {16,16,16,16});
+        fnTest({GL_RGBA, GL_RGBA, GL_UNSIGNED_SHORT_4_4_4_4}, {16, 16, 16, 16});
+    }
+
+    // RGBA+UNSIGNED_SHORT_5_5_5_1
+    {
+        constexpr uint16_t src[] = {static_cast<uint16_t>(
+            (EncodeNormUint<5>(srcVals[0]) << 11) | (EncodeNormUint<5>(srcVals[1]) << 6) |
+            (EncodeNormUint<5>(srcVals[2]) << 1) | (EncodeNormUint<1>(srcVals[3]) << 0))};
+        ZeroAndCopy(srcBuffer, src);
+
+        fnTest({GL_RGBA4, GL_RGBA, GL_UNSIGNED_SHORT_5_5_5_1}, {8, 8, 8, 255});
+        fnTest({GL_RGBA, GL_RGBA, GL_UNSIGNED_SHORT_5_5_5_1}, {8, 8, 8, 255});
+    }
+
+    // RGBA+UNSIGNED_INT_2_10_10_10_REV
+    {
+        constexpr uint32_t src[] = {
+            (EncodeNormUint<10>(srcVals[0]) << 0) | (EncodeNormUint<10>(srcVals[1]) << 10) |
+            (EncodeNormUint<10>(srcVals[2]) << 20) | (EncodeNormUint<2>(srcVals[3]) << 30)};
+        ZeroAndCopy(srcBuffer, src);
+
+        fnTest({GL_RGB10_A2, GL_RGBA, GL_UNSIGNED_INT_2_10_10_10_REV}, {1, 1, 1, 128});
+        fnTest({GL_RGB5_A1, GL_RGBA, GL_UNSIGNED_INT_2_10_10_10_REV}, {8, 8, 8, 255});
+    }
+
+    // DEPTH_COMPONENT+UNSIGNED_SHORT
+    {
+        const uint16_t src[] = {static_cast<uint16_t>(EncodeNormUint<16>(srcVals[0]))};
+        ZeroAndCopy(srcBuffer, src);
+
+        fnTest({GL_DEPTH_COMPONENT16, GL_DEPTH_COMPONENT, GL_UNSIGNED_SHORT}, {1, 0, 0, 0});
+    }
+
+    // DEPTH_COMPONENT+UNSIGNED_INT
+    {
+        constexpr uint32_t src[] = {EncodeNormUint<32>(srcVals[0])};
+        ZeroAndCopy(srcBuffer, src);
+
+        fnTest({GL_DEPTH_COMPONENT24, GL_DEPTH_COMPONENT, GL_UNSIGNED_INT}, {1, 0, 0, 0});
+        fnTest({GL_DEPTH_COMPONENT16, GL_DEPTH_COMPONENT, GL_UNSIGNED_INT}, {1, 0, 0, 0});
+    }
+
+    // DEPTH_STENCIL+UNSIGNED_INT_24_8
+    {
+        // Drop stencil.
+        constexpr uint32_t src[] = {EncodeNormUint<24>(srcVals[0]) << 8};
+        ZeroAndCopy(srcBuffer, src);
+
+        fnTest({GL_DEPTH24_STENCIL8, GL_DEPTH_STENCIL, GL_UNSIGNED_INT_24_8}, {1, 0, 0, 0});
+    }
+
+    // Non-normalized ints
+    glUseProgram(intsProg);
+
+    // RGBA_INTEGER+UNSIGNED_BYTE
+    {
+        constexpr uint8_t src[4] = {srcIntVals[0], srcIntVals[1], srcIntVals[2], srcIntVals[3]};
+        ZeroAndCopy(srcBuffer, src);
+
+        fnTest({GL_RGBA8UI, GL_RGBA_INTEGER, GL_UNSIGNED_BYTE}, {1, 1, 1, 1});
+        fnTest({GL_RGB8UI, GL_RGB_INTEGER, GL_UNSIGNED_BYTE}, {1, 1, 1, 1});
+        fnTest({GL_RG8UI, GL_RG_INTEGER, GL_UNSIGNED_BYTE}, {1, 1, 1, 1});
+        fnTest({GL_R8UI, GL_RED_INTEGER, GL_UNSIGNED_BYTE}, {1, 1, 1, 1});
+
+        fnTest({GL_RGBA8I, GL_RGBA_INTEGER, GL_BYTE}, {1, 1, 1, 1});
+        fnTest({GL_RGB8I, GL_RGB_INTEGER, GL_BYTE}, {1, 1, 1, 1});
+        fnTest({GL_RG8I, GL_RG_INTEGER, GL_BYTE}, {1, 1, 1, 1});
+        fnTest({GL_R8I, GL_RED_INTEGER, GL_BYTE}, {1, 1, 1, 1});
+    }
+
+    // RGBA_INTEGER+UNSIGNED_SHORT
+    {
+        constexpr uint16_t src[4] = {srcIntVals[0], srcIntVals[1], srcIntVals[2], srcIntVals[3]};
+        ZeroAndCopy(srcBuffer, src);
+
+        fnTest({GL_RGBA16UI, GL_RGBA_INTEGER, GL_UNSIGNED_SHORT}, {1, 1, 1, 1});
+        fnTest({GL_RGB16UI, GL_RGB_INTEGER, GL_UNSIGNED_SHORT}, {1, 1, 1, 1});
+        fnTest({GL_RG16UI, GL_RG_INTEGER, GL_UNSIGNED_SHORT}, {1, 1, 1, 1});
+        fnTest({GL_R16UI, GL_RED_INTEGER, GL_UNSIGNED_SHORT}, {1, 1, 1, 1});
+
+        fnTest({GL_RGBA16I, GL_RGBA_INTEGER, GL_SHORT}, {1, 1, 1, 1});
+        fnTest({GL_RGB16I, GL_RGB_INTEGER, GL_SHORT}, {1, 1, 1, 1});
+        fnTest({GL_RG16I, GL_RG_INTEGER, GL_SHORT}, {1, 1, 1, 1});
+        fnTest({GL_R16I, GL_RED_INTEGER, GL_SHORT}, {1, 1, 1, 1});
+    }
+
+    // RGBA_INTEGER+UNSIGNED_INT
+    {
+        constexpr uint32_t src[4] = {srcIntVals[0], srcIntVals[1], srcIntVals[2], srcIntVals[3]};
+        ZeroAndCopy(srcBuffer, src);
+
+        fnTest({GL_RGBA32UI, GL_RGBA_INTEGER, GL_UNSIGNED_INT}, {1, 1, 1, 1});
+        fnTest({GL_RGB32UI, GL_RGB_INTEGER, GL_UNSIGNED_INT}, {1, 1, 1, 1});
+        fnTest({GL_RG32UI, GL_RG_INTEGER, GL_UNSIGNED_INT}, {1, 1, 1, 1});
+        fnTest({GL_R32UI, GL_RED_INTEGER, GL_UNSIGNED_INT}, {1, 1, 1, 1});
+
+        fnTest({GL_RGBA32I, GL_RGBA_INTEGER, GL_INT}, {1, 1, 1, 1});
+        fnTest({GL_RGB32I, GL_RGB_INTEGER, GL_INT}, {1, 1, 1, 1});
+        fnTest({GL_RG32I, GL_RG_INTEGER, GL_INT}, {1, 1, 1, 1});
+        fnTest({GL_R32I, GL_RED_INTEGER, GL_INT}, {1, 1, 1, 1});
+    }
+
+    // RGBA_INTEGER+UNSIGNED_INT_2_10_10_10_REV
+    {
+        constexpr uint32_t src[] = {static_cast<uint32_t>(srcIntVals[0] << 0) |
+                                    static_cast<uint32_t>(srcIntVals[1] << 10) |
+                                    static_cast<uint32_t>(srcIntVals[2] << 20) |
+                                    static_cast<uint32_t>(srcIntVals[3] << 30)};
+        ZeroAndCopy(srcBuffer, src);
+
+        fnTest({GL_RGB10_A2UI, GL_RGBA_INTEGER, GL_UNSIGNED_INT_2_10_10_10_REV}, {1, 1, 1, 1});
+    }
+
+    // True floats
+    glUseProgram(floatsProg);
+
+    // RGBA+HALF_FLOAT
+    {
+        const uint16_t src[] = {static_cast<uint16_t>(Float16::Encode(srcVals[0])),
+                                static_cast<uint16_t>(Float16::Encode(srcVals[1])),
+                                static_cast<uint16_t>(Float16::Encode(srcVals[2])),
+                                static_cast<uint16_t>(Float16::Encode(srcVals[3]))};
+        ZeroAndCopy(srcBuffer, src);
+
+        fnTest({GL_RGBA16F, GL_RGBA, GL_HALF_FLOAT}, {1, 1, 1, 1});
+
+        fnTest({GL_RGB16F, GL_RGB, GL_HALF_FLOAT}, {1, 1, 1, 0});
+        fnTest({GL_R11F_G11F_B10F, GL_RGB, GL_HALF_FLOAT}, {1, 1, 1, 0});
+        fnTest({GL_RGB9_E5, GL_RGB, GL_HALF_FLOAT}, {1, 1, 1, 0});
+
+        fnTest({GL_RG16F, GL_RG, GL_HALF_FLOAT}, {1, 1, 0, 0});
+
+        fnTest({GL_R16F, GL_RED, GL_HALF_FLOAT}, {1, 0, 0, 0});
+
+        fnTest({GL_RGBA, GL_RGBA, GL_HALF_FLOAT_OES}, {1, 1, 1, 1});
+        fnTest({GL_RGB, GL_RGB, GL_HALF_FLOAT_OES}, {1, 1, 1, 0});
+        fnTest({GL_LUMINANCE_ALPHA, GL_LUMINANCE_ALPHA, GL_HALF_FLOAT_OES}, {1, 1, 1, 1});
+        fnTest({GL_LUMINANCE, GL_LUMINANCE, GL_HALF_FLOAT_OES}, {1, 1, 1, 0});
+        fnTest({GL_ALPHA, GL_ALPHA, GL_HALF_FLOAT_OES}, {0, 0, 0, 1});
+    }
+
+    // RGBA+FLOAT
+    {
+        ZeroAndCopy(srcBuffer, srcVals);
+
+        fnTest({GL_RGBA32F, GL_RGBA, GL_FLOAT}, {1, 1, 1, 1});
+        fnTest({GL_RGBA16F, GL_RGBA, GL_FLOAT}, {1, 1, 1, 1});
+
+        fnTest({GL_RGB32F, GL_RGB, GL_FLOAT}, {1, 1, 1, 0});
+        fnTest({GL_RGB16F, GL_RGB, GL_FLOAT}, {1, 1, 1, 0});
+        fnTest({GL_R11F_G11F_B10F, GL_RGB, GL_FLOAT}, {1, 1, 1, 0});
+        fnTest({GL_RGB9_E5, GL_RGB, GL_FLOAT}, {1, 1, 1, 0});
+
+        fnTest({GL_RG32F, GL_RG, GL_FLOAT}, {1, 1, 0, 0});
+        fnTest({GL_RG16F, GL_RG, GL_FLOAT}, {1, 1, 0, 0});
+
+        fnTest({GL_R32F, GL_RED, GL_FLOAT}, {1, 0, 0, 0});
+        fnTest({GL_R16F, GL_RED, GL_FLOAT}, {1, 0, 0, 0});
+    }
+
+    // UNSIGNED_INT_10F_11F_11F_REV
+    {
+        const uint32_t src[] = {(UFloat11::Encode(srcVals[0]) << 0) |
+                                (UFloat11::Encode(srcVals[1]) << 11) |
+                                (UFloat10::Encode(srcVals[2]) << 22)};
+        ZeroAndCopy(srcBuffer, src);
+
+        fnTest({GL_R11F_G11F_B10F, GL_RGB, GL_UNSIGNED_INT_10F_11F_11F_REV}, {1, 1, 1, 0});
+    }
+
+    // UNSIGNED_INT_5_9_9_9_REV
+    {
+        const uint32_t src[] = {EncodeRGB9_E5_Rev(srcVals[0], srcVals[1], srcVals[2])};
+        ZeroAndCopy(srcBuffer, src);
+
+        fnTest({GL_RGB9_E5, GL_RGB, GL_UNSIGNED_INT_5_9_9_9_REV}, {1, 1, 1, 0});
+    }
+
+    // DEPTH_COMPONENT+FLOAT
+    {
+        // Skip stencil.
+        constexpr float src[] = {srcVals[0], 0};
+        ZeroAndCopy(srcBuffer, src);
+
+        fnTest({GL_DEPTH_COMPONENT32F, GL_DEPTH_COMPONENT, GL_FLOAT}, {1, 0, 0, 0});
+        fnTest({GL_DEPTH32F_STENCIL8, GL_DEPTH_STENCIL, GL_FLOAT_32_UNSIGNED_INT_24_8_REV},
+               {1, 0, 0, 0});
+    }
+
+    EXPECT_GL_NO_ERROR();
+}
+
+ANGLE_INSTANTIATE_TEST(TextureUploadFormatTest,
+                       ES2_D3D11(),
+                       ES2_D3D11_FL9_3(),
+                       ES2_D3D9(),
+                       ES2_OPENGL(),
+                       ES2_OPENGLES());
--- a/gfx/angle/src/tests/gl_tests/TransformFeedbackTest.cpp
+++ b/gfx/angle/src/tests/gl_tests/TransformFeedbackTest.cpp
@@ -213,23 +213,16 @@ TEST_P(TransformFeedbackTest, BufferRebi
 
     EXPECT_GL_NO_ERROR();
 }
 
 // Test that XFB can write back vertices to a buffer and that we can draw from this buffer
 // afterward.
 TEST_P(TransformFeedbackTest, RecordAndDraw)
 {
-    // TODO(jmadill): Figure out why this fails on Intel.
-    if (IsIntel() && GetParam().getRenderer() == EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE)
-    {
-        std::cout << "Test skipped on Intel." << std::endl;
-        return;
-    }
-
     glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
     glClear(GL_COLOR_BUFFER_BIT);
 
     // Set the program's transform feedback varyings (just gl_Position)
     std::vector<std::string> tfVaryings;
     tfVaryings.push_back("gl_Position");
     compileDefaultProgram(tfVaryings, GL_INTERLEAVED_ATTRIBS);
 
@@ -1053,23 +1046,16 @@ class TransformFeedbackLifetimeTest : pu
     }
 
     GLuint mVertexArray;
 };
 
 // Tests a bug with state syncing and deleted transform feedback buffers.
 TEST_P(TransformFeedbackLifetimeTest, DeletedBuffer)
 {
-    // TODO(ynovikov): Obscure driver error on Intel HD 530 http://anglebug.com/1879
-    if (IsWindows() && IsIntel() && IsDesktopOpenGL())
-    {
-        std::cout << "Test skipped on Intel OpenGL on Windows." << std::endl;
-        return;
-    }
-
     // First stream vertex data to mTransformFeedbackBuffer.
     glBindTransformFeedback(GL_TRANSFORM_FEEDBACK, mTransformFeedback);
     glBindBufferBase(GL_TRANSFORM_FEEDBACK_BUFFER, 0, mTransformFeedbackBuffer);
 
     glUseProgram(mProgram);
 
     glBeginTransformFeedback(GL_TRIANGLES);
     drawQuad(mProgram, "position", 0.5f, 1.0f, true);
@@ -1138,16 +1124,76 @@ TEST_P(TransformFeedbackTestES31, SameAr
     tfVaryings.push_back("outAttribs");
     tfVaryings.push_back("outAttribs[1]");
 
     mProgram = CompileProgramWithTransformFeedback(vertexShaderSource, fragmentShaderSource,
                                                    tfVaryings, GL_INTERLEAVED_ATTRIBS);
     ASSERT_EQ(0u, mProgram);
 }
 
+// Test that program link fails in case to capture array element on a non-array varying.
+TEST_P(TransformFeedbackTestES31, ElementCaptureOnNonArrayVarying)
+{
+    const std::string &vertexShaderSource =
+        "#version 310 es\n"
+        "in vec3 position;\n"
+        "out vec3 outAttrib;\n"
+        "void main() {"
+        "  outAttrib = position;\n"
+        "  gl_Position = vec4(position, 1);\n"
+        "}";
+
+    const std::string &fragmentShaderSource =
+        "#version 310 es\n"
+        "precision mediump float;\n"
+        "out vec4 color;\n"
+        "in vec3 outAttrib;\n"
+        "void main() {\n"
+        "  color = vec4(0);\n"
+        "}";
+
+    std::vector<std::string> tfVaryings;
+    tfVaryings.push_back("outAttrib[1]");
+
+    mProgram = CompileProgramWithTransformFeedback(vertexShaderSource, fragmentShaderSource,
+                                                   tfVaryings, GL_INTERLEAVED_ATTRIBS);
+    ASSERT_EQ(0u, mProgram);
+}
+
+// Test that program link fails in case to capure an outbound array element.
+TEST_P(TransformFeedbackTestES31, CaptureOutboundElement)
+{
+    const std::string &vertexShaderSource =
+        "#version 310 es\n"
+        "in vec3 position;\n"
+        "out vec3 outAttribs[3];\n"
+        "void main() {"
+        "  outAttribs[0] = position;\n"
+        "  outAttribs[1] = vec3(0, 0, 0);\n"
+        "  outAttribs[2] = position;\n"
+        "  gl_Position = vec4(position, 1);\n"
+        "}";
+
+    const std::string &fragmentShaderSource =
+        "#version 310 es\n"
+        "precision mediump float;\n"
+        "out vec4 color;\n"
+        "in vec3 outAttribs[3];\n"
+        "void main() {\n"
+        "  color = vec4(0);\n"
+        "}";
+
+    std::vector<std::string> tfVaryings;
+    tfVaryings.push_back("outAttribs[3]");
+
+    mProgram = CompileProgramWithTransformFeedback(vertexShaderSource, fragmentShaderSource,
+                                                   tfVaryings, GL_INTERLEAVED_ATTRIBS);
+    ASSERT_EQ(0u, mProgram);
+}
+
 // Test transform feedback names can be specified using array element.
 TEST_P(TransformFeedbackTestES31, DifferentArrayElementVaryings)
 {
     const std::string &vertexShaderSource =
         "#version 310 es\n"
         "in vec3 position;\n"
         "out vec3 outAttribs[3];\n"
         "void main() {"
@@ -1201,16 +1247,135 @@ TEST_P(TransformFeedbackTestES31, Differ
         EXPECT_EQ(quadVertices[vectorIndex], vecPointer[stream1Index]);
         EXPECT_EQ(quadVertices[vectorIndex], vecPointer[stream2Index]);
     }
     glUnmapBuffer(GL_TRANSFORM_FEEDBACK_BUFFER);
 
     ASSERT_GL_NO_ERROR();
 }
 
+// Test transform feedback varying for base-level members of struct.
+TEST_P(TransformFeedbackTestES31, StructMemberVaryings)
+{
+    const std::string &vertexShaderSource =
+        R"(#version 310 es
+
+        in vec3 position;
+        struct S {
+          vec3 field0;
+          vec3 field1;
+          vec3 field2;
+        };
+        out S s;
+
+        void main() {
+          s.field0 = position;
+          s.field1 = vec3(0, 0, 0);
+          s.field2 = position;
+          gl_Position = vec4(position, 1);
+        })";
+
+    const std::string &fragmentShaderSource =
+        R"(#version 310 es
+
+        precision mediump float;
+        struct S {
+          vec3 field0;
+          vec3 field1;
+          vec3 field2;
+        };
+        out vec4 color;
+        in S s;
+
+        void main() {
+          color = vec4(s.field1, 1);
+        })";
+
+    std::vector<std::string> tfVaryings;
+    tfVaryings.push_back("s.field0");
+    tfVaryings.push_back("s.field2");
+
+    mProgram = CompileProgramWithTransformFeedback(vertexShaderSource, fragmentShaderSource,
+                                                   tfVaryings, GL_INTERLEAVED_ATTRIBS);
+    ASSERT_NE(0u, mProgram);
+
+    glBindBuffer(GL_TRANSFORM_FEEDBACK_BUFFER, mTransformFeedbackBuffer);
+    glBufferData(GL_TRANSFORM_FEEDBACK_BUFFER, sizeof(Vector3) * 2 * 6, nullptr, GL_STREAM_DRAW);
+
+    glBindTransformFeedback(GL_TRANSFORM_FEEDBACK, mTransformFeedback);
+    glBindBufferBase(GL_TRANSFORM_FEEDBACK_BUFFER, 0, mTransformFeedbackBuffer);
+
+    glUseProgram(mProgram);
+    glBeginTransformFeedback(GL_TRIANGLES);
+    drawQuad(mProgram, "position", 0.5f);
+    glEndTransformFeedback();
+    glUseProgram(0);
+    ASSERT_GL_NO_ERROR();
+
+    const GLvoid *mapPointer =
+        glMapBufferRange(GL_TRANSFORM_FEEDBACK_BUFFER, 0, sizeof(Vector3) * 2 * 6, GL_MAP_READ_BIT);
+    ASSERT_NE(nullptr, mapPointer);
+
+    const auto &quadVertices = GetQuadVertices();
+
+    const Vector3 *vecPointer = static_cast<const Vector3 *>(mapPointer);
+    for (unsigned int vectorIndex = 0; vectorIndex < 3; ++vectorIndex)
+    {
+        unsigned int stream1Index = vectorIndex * 2;
+        unsigned int stream2Index = vectorIndex * 2 + 1;
+        EXPECT_EQ(quadVertices[vectorIndex], vecPointer[stream1Index]);
+        EXPECT_EQ(quadVertices[vectorIndex], vecPointer[stream2Index]);
+    }
+    glUnmapBuffer(GL_TRANSFORM_FEEDBACK_BUFFER);
+
+    ASSERT_GL_NO_ERROR();
+}
+
+// Test transform feedback varying for struct is not allowed.
+TEST_P(TransformFeedbackTestES31, InvalidStructVaryings)
+{
+    const std::string &vertexShaderSource =
+        R"(#version 310 es
+
+        in vec3 position;
+        struct S {
+          vec3 field0;
+          vec3 field1;
+        };
+        out S s;
+
+        void main() {
+          s.field0 = position;
+          s.field1 = vec3(0, 0, 0);
+          gl_Position = vec4(position, 1);
+        })";
+
+    const std::string &fragmentShaderSource =
+        R"(#version 310 es
+
+        precision mediump float;
+        struct S {
+          vec3 field0;
+          vec3 field1;
+        };
+        out vec4 color;
+        in S s;
+
+        void main() {
+          color = vec4(s.field1, 1);
+        })";
+
+    std::vector<std::string> tfVaryings;
+    tfVaryings.push_back("s");
+
+    mProgram = CompileProgramWithTransformFeedback(vertexShaderSource, fragmentShaderSource,
+                                                   tfVaryings, GL_INTERLEAVED_ATTRIBS);
+    ASSERT_EQ(0u, mProgram);
+}
+
 // Test that nonexistent transform feedback varyings don't assert when linking.
 TEST_P(TransformFeedbackTest, NonExistentTransformFeedbackVarying)
 {
     const std::string &vertexShaderSource =
         "#version 300 es\n"
         "in vec4 a_position;\n"
         "void main()\n"
         "{\n"
@@ -1316,15 +1481,61 @@ TEST_P(TransformFeedbackTest, VaryingRes
     {
         EXPECT_EQ(quadVertices[vectorIndex], vecPointer[vectorIndex]);
     }
     glUnmapBuffer(GL_TRANSFORM_FEEDBACK_BUFFER);
 
     ASSERT_GL_NO_ERROR();
 }
 
+// Test that calling BeginTransformFeedback when no program is currentwill generate an
+// INVALID_OPERATION error.
+TEST_P(TransformFeedbackTest, NoCurrentProgram)
+{
+    glUseProgram(0);
+    glBeginTransformFeedback(GL_TRIANGLES);
+
+    // GLES 3.0.5 section 2.15.2: "The error INVALID_OPERATION is also generated by
+    // BeginTransformFeedback if no binding points would be used, either because no program object
+    // is active or because the active program object has specified no output variables to record."
+    EXPECT_GL_ERROR(GL_INVALID_OPERATION);
+}
+
+// Test that calling BeginTransformFeedback when no transform feedback varyings are in use will
+// generate an INVALID_OPERATION error.
+TEST_P(TransformFeedbackTest, NoTransformFeedbackVaryingsInUse)
+{
+    const std::string &vertexShaderSource =
+        "#version 300 es\n"
+        "in vec4 a_position;\n"
+        "void main()\n"
+        "{\n"
+        "    gl_Position = a_position;\n"
+        "}\n";
+
+    const std::string &fragmentShaderSource =
+        "#version 300 es\n"
+        "precision mediump float;\n"
+        "out vec4 fragColor;\n"
+        "void main()\n"
+        "{\n"
+        "    fragColor = vec4(0);\n"
+        "}\n";
+
+    ANGLE_GL_PROGRAM(program, vertexShaderSource, fragmentShaderSource);
+
+    glUseProgram(program);
+    glBeginTransformFeedback(GL_TRIANGLES);
+
+    // GLES 3.0.5 section 2.15.2: "The error INVALID_OPERATION is also generated by
+    // BeginTransformFeedback if no binding points would be used, either because no program object
+    // is active or because the active program object has specified no output variables to record."
+
+    EXPECT_GL_ERROR(GL_INVALID_OPERATION);
+}
+
 // Use this to select which configurations (e.g. which renderer, which GLES major version) these
 // tests should be run against.
 ANGLE_INSTANTIATE_TEST(TransformFeedbackTest, ES3_D3D11(), ES3_OPENGL(), ES3_OPENGLES());
 ANGLE_INSTANTIATE_TEST(TransformFeedbackLifetimeTest, ES3_D3D11(), ES3_OPENGL(), ES3_OPENGLES());
 ANGLE_INSTANTIATE_TEST(TransformFeedbackTestES31, ES31_D3D11(), ES31_OPENGL(), ES31_OPENGLES());
 
 }  // anonymous namespace
--- a/gfx/angle/src/tests/gl_tests/UniformBufferTest.cpp
+++ b/gfx/angle/src/tests/gl_tests/UniformBufferTest.cpp
@@ -861,41 +861,100 @@ TEST_P(UniformBufferTest, BlockContainin
     glBufferData(GL_UNIFORM_BUFFER, kDataSize, v.data(), GL_STATIC_DRAW);
 
     glBindBufferBase(GL_UNIFORM_BUFFER, 0, mUniformBuffer);
     glUniformBlockBinding(program, uniformBufferIndex, 0);
     drawQuad(program.get(), "position", 0.5f);
     EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
 }
 
+// Test with a block instance array containing an array of structs.
+TEST_P(UniformBufferTest, BlockArrayContainingArrayOfStructs)
+{
+    const std::string &fragmentShader =
+        R"(#version 300 es
+
+        precision highp float;
+        out vec4 my_FragColor;
+        struct light_t
+        {
+            vec4 intensity;
+        };
+
+        layout(std140) uniform lightData { light_t lights[2]; } buffers[2];
+
+        vec4 processLight(vec4 lighting, light_t light)
+        {
+            return lighting + light.intensity;
+        }
+        void main()
+        {
+            vec4 lighting = vec4(0, 0, 0, 1);
+            lighting = processLight(lighting, buffers[0].lights[0]);
+            lighting = processLight(lighting, buffers[1].lights[1]);
+            my_FragColor = lighting;
+        })";
+
+    ANGLE_GL_PROGRAM(program, mVertexShaderSource, fragmentShader);
+    GLint uniformBufferIndex  = glGetUniformBlockIndex(program, "lightData[0]");
+    GLint uniformBuffer2Index = glGetUniformBlockIndex(program, "lightData[1]");
+
+    glBindBuffer(GL_UNIFORM_BUFFER, mUniformBuffer);
+    const GLsizei kStructCount        = 2;
+    const GLsizei kVectorElementCount = 4;
+    const GLsizei kBytesPerElement    = 4;
+    const GLsizei kDataSize           = kStructCount * kVectorElementCount * kBytesPerElement;
+    std::vector<GLubyte> v(kDataSize, 0);
+    float *vAsFloat = reinterpret_cast<float *>(v.data());
+
+    // In the first struct/vector of the first block
+    vAsFloat[1] = 0.5f;
+
+    glBufferData(GL_UNIFORM_BUFFER, kDataSize, v.data(), GL_STATIC_DRAW);
+
+    GLBuffer uniformBuffer2;
+    glBindBuffer(GL_UNIFORM_BUFFER, uniformBuffer2);
+
+    vAsFloat[1] = 0.0f;
+    // In the second struct/vector of the second block
+    vAsFloat[kVectorElementCount + 1] = 0.5f;
+    glBufferData(GL_UNIFORM_BUFFER, kDataSize, v.data(), GL_STATIC_DRAW);
+
+    glBindBufferBase(GL_UNIFORM_BUFFER, 0, mUniformBuffer);
+    glBindBufferBase(GL_UNIFORM_BUFFER, 1, uniformBuffer2);
+    glUniformBlockBinding(program, uniformBufferIndex, 0);
+    glUniformBlockBinding(program, uniformBuffer2Index, 1);
+    drawQuad(program.get(), "position", 0.5f);
+    EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
+}
+
 // Test with a block containing an array of structs containing arrays.
 TEST_P(UniformBufferTest, BlockContainingArrayOfStructsContainingArrays)
 {
     const std::string &fragmentShader =
-        "#version 300 es\n"
-        "precision highp float;\n"
-        "out vec4 my_FragColor;\n"
-        "struct light_t {\n"
-        "    vec4 intensity[3];\n"
-        "};\n"
-        "const int maxLights = 2;\n"
-        "layout(std140) uniform lightData { light_t lights[maxLights]; };\n"
-        "vec4 processLight(vec4 lighting, light_t light)\n"
-        "{\n"
-        "    return lighting + light.intensity[1];\n"
-        "}\n"
-        "void main()\n"
-        "{\n"
-        "    vec4 lighting = vec4(0, 0, 0, 1);\n"
-        "    for (int n = 0; n < maxLights; n++)\n"
-        "    {\n"
-        "        lighting = processLight(lighting, lights[n]);\n"
-        "    }\n"
-        "    my_FragColor = lighting;\n"
-        "}\n";
+        R"(#version 300 es
+        precision highp float;
+        out vec4 my_FragColor;
+        struct light_t
+        {
+            vec4 intensity[3];
+        };
+        const int maxLights = 2;
+        layout(std140) uniform lightData { light_t lights[maxLights]; };
+        vec4 processLight(vec4 lighting, light_t light)
+        {
+            return lighting + light.intensity[1];
+        }
+        void main()
+        {
+            vec4 lighting = vec4(0, 0, 0, 1);
+            lighting = processLight(lighting, lights[0]);
+            lighting = processLight(lighting, lights[1]);
+            my_FragColor = lighting;
+        })";
 
     ANGLE_GL_PROGRAM(program, mVertexShaderSource, fragmentShader);
     GLint uniformBufferIndex = glGetUniformBlockIndex(program, "lightData");
 
     glBindBuffer(GL_UNIFORM_BUFFER, mUniformBuffer);
     const GLsizei kStructCount       = 2;
     const GLsizei kVectorsPerStruct  = 3;
     const GLsizei kElementsPerVector = 4;
@@ -1033,16 +1092,465 @@ TEST_P(UniformBufferTest, UniformBlockIn
 
     glBufferData(GL_UNIFORM_BUFFER, kDataSize, v.data(), GL_STATIC_DRAW);
     glBindBufferBase(GL_UNIFORM_BUFFER, 0, mUniformBuffer);
     glUniformBlockBinding(program, uniformBufferIndex, 0);
     drawQuad(program.get(), "position", 0.5f);
     EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
 }
 
+// Test that uniform block instance with nested structs that contain vec3s inside is handled
+// correctly. This is meant to test that HLSL structure padding to implement std140 layout works
+// together with uniform blocks.
+TEST_P(UniformBufferTest, Std140UniformBlockInstanceWithNestedStructsContainingVec3s)
+{
+    // Got incorrect test result on non-NVIDIA Android - the alpha channel was not set correctly
+    // from the second vector, possibly the platform doesn't implement std140 packing right?
+    // http://anglebug.com/2217
+    ANGLE_SKIP_TEST_IF(IsAndroid() && !IsNVIDIA());
+
+    const std::string &fragmentShader =
+        R"(#version 300 es
+
+        precision highp float;
+        out vec4 my_FragColor;
+
+        struct Sinner {
+          vec3 v;
+        };
+
+        struct S {
+            Sinner s1;
+            Sinner s2;
+        };
+
+        layout(std140) uniform structBuffer { S s; } buffer;
+
+        void accessStruct(S s)
+        {
+            my_FragColor = vec4(s.s1.v.xy, s.s2.v.xy);
+        }
+
+        void main()
+        {
+            accessStruct(buffer.s);
+        })";
+
+    ANGLE_GL_PROGRAM(program, mVertexShaderSource, fragmentShader);
+    GLint uniformBufferIndex = glGetUniformBlockIndex(program, "structBuffer");
+
+    glBindBuffer(GL_UNIFORM_BUFFER, mUniformBuffer);
+    const GLsizei kVectorsPerBlock         = 2;
+    const GLsizei kElementsPerPaddedVector = 4;
+    const GLsizei kBytesPerElement         = 4;
+    const GLsizei kDataSize = kVectorsPerBlock * kElementsPerPaddedVector * kBytesPerElement;
+    std::vector<GLubyte> v(kDataSize, 0);
+    float *vAsFloat = reinterpret_cast<float *>(v.data());
+
+    // Set second value in each vec3.
+    vAsFloat[1u]      = 1.0f;
+    vAsFloat[4u + 1u] = 1.0f;
+
+    glBufferData(GL_UNIFORM_BUFFER, kDataSize, v.data(), GL_STATIC_DRAW);
+    glBindBufferBase(GL_UNIFORM_BUFFER, 0, mUniformBuffer);
+    glUniformBlockBinding(program, uniformBufferIndex, 0);
+    drawQuad(program.get(), "position", 0.5f);
+    EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
+}
+
+// Tests the detaching shaders from the program and using uniform blocks works.
+// This covers a bug in ANGLE's D3D back-end.
+TEST_P(UniformBufferTest, DetachShaders)
+{
+    GLuint vertexShader = CompileShader(GL_VERTEX_SHADER, mVertexShaderSource);
+    ASSERT_NE(0u, vertexShader);
+    GLuint fragmentShader = CompileShader(GL_FRAGMENT_SHADER, mFragmentShaderSource);
+    ASSERT_NE(0u, fragmentShader);
+
+    GLuint program = glCreateProgram();
+    glAttachShader(program, vertexShader);
+    glAttachShader(program, fragmentShader);
+
+    ASSERT_TRUE(LinkAttachedProgram(program));
+
+    glDetachShader(program, vertexShader);
+    glDetachShader(program, fragmentShader);
+    glDeleteShader(vertexShader);
+    glDeleteShader(fragmentShader);
+
+    glClear(GL_COLOR_BUFFER_BIT);
+    float floatData[4] = {0.5f, 0.75f, 0.25f, 1.0f};
+
+    glBindBuffer(GL_UNIFORM_BUFFER, mUniformBuffer);
+    glBufferData(GL_UNIFORM_BUFFER, sizeof(float) * 4, floatData, GL_STATIC_DRAW);
+
+    glBindBufferBase(GL_UNIFORM_BUFFER, 0, mUniformBuffer);
+
+    GLint uniformBufferIndex = glGetUniformBlockIndex(mProgram, "uni");
+    ASSERT_NE(uniformBufferIndex, -1);
+
+    glUniformBlockBinding(program, uniformBufferIndex, 0);
+    drawQuad(program, "position", 0.5f);
+
+    ASSERT_GL_NO_ERROR();
+    EXPECT_PIXEL_NEAR(0, 0, 128, 191, 64, 255, 1);
+
+    glDeleteProgram(program);
+}
+
+// Test a uniform block where the whole block is set as row-major.
+TEST_P(UniformBufferTest, Std140UniformBlockWithRowMajorQualifier)
+{
+    // AMD OpenGL driver doesn't seem to apply the row-major qualifier right.
+    // http://anglebug.com/2273
+    ANGLE_SKIP_TEST_IF(IsAMD() && IsOpenGL());
+
+    const std::string &fragmentShader =
+        R"(#version 300 es
+
+        precision highp float;
+        out vec4 my_FragColor;
+
+        layout(std140, row_major) uniform matrixBuffer
+        {
+            mat2 m;
+        } buffer;
+
+        void main()
+        {
+            // Vector constructor accesses elements in column-major order.
+            my_FragColor = vec4(buffer.m);
+        })";
+
+    ANGLE_GL_PROGRAM(program, mVertexShaderSource, fragmentShader);
+    GLint uniformBufferIndex = glGetUniformBlockIndex(program, "matrixBuffer");
+
+    glBindBuffer(GL_UNIFORM_BUFFER, mUniformBuffer);
+    const GLsizei kElementsPerMatrix = 8;  // Each mat2 row gets padded into a vec4.
+    const GLsizei kBytesPerElement   = 4;
+    const GLsizei kDataSize          = kElementsPerMatrix * kBytesPerElement;
+    std::vector<GLubyte> v(kDataSize, 0);
+    float *vAsFloat = reinterpret_cast<float *>(v.data());
+
+    vAsFloat[0u] = 1.0f;
+    vAsFloat[1u] = 128.0f / 255.0f;
+    vAsFloat[4u] = 64.0f / 255.0f;
+    vAsFloat[5u] = 32.0f / 255.0f;
+
+    glBufferData(GL_UNIFORM_BUFFER, kDataSize, v.data(), GL_STATIC_DRAW);
+    glBindBufferBase(GL_UNIFORM_BUFFER, 0, mUniformBuffer);
+    glUniformBlockBinding(program, uniformBufferIndex, 0);
+    drawQuad(program.get(), "position", 0.5f);
+    ASSERT_GL_NO_ERROR();
+    EXPECT_PIXEL_COLOR_NEAR(0, 0, GLColor(255, 64, 128, 32), 5);
+}
+
+// Test a uniform block where an individual matrix field is set as row-major whereas the whole block
+// is set as column-major.
+TEST_P(UniformBufferTest, Std140UniformBlockWithPerMemberRowMajorQualifier)
+{
+    // AMD OpenGL driver doesn't seem to apply the row-major qualifier right.
+    // http://anglebug.com/2273
+    ANGLE_SKIP_TEST_IF(IsAMD() && IsOpenGL());
+
+    const std::string &fragmentShader =
+        R"(#version 300 es
+
+        precision highp float;
+        out vec4 my_FragColor;
+
+        layout(std140, column_major) uniform matrixBuffer
+        {
+            layout(row_major) mat2 m;
+        } buffer;
+
+        void main()
+        {
+            // Vector constructor accesses elements in column-major order.
+            my_FragColor = vec4(buffer.m);
+        })";
+
+    ANGLE_GL_PROGRAM(program, mVertexShaderSource, fragmentShader);
+    GLint uniformBufferIndex = glGetUniformBlockIndex(program, "matrixBuffer");
+
+    glBindBuffer(GL_UNIFORM_BUFFER, mUniformBuffer);
+    const GLsizei kElementsPerMatrix = 8;  // Each mat2 row gets padded into a vec4.
+    const GLsizei kBytesPerElement   = 4;
+    const GLsizei kDataSize          = kElementsPerMatrix * kBytesPerElement;
+    std::vector<GLubyte> v(kDataSize, 0);
+    float *vAsFloat = reinterpret_cast<float *>(v.data());
+
+    vAsFloat[0u] = 1.0f;
+    vAsFloat[1u] = 128.0f / 255.0f;
+    vAsFloat[4u] = 64.0f / 255.0f;
+    vAsFloat[5u] = 32.0f / 255.0f;
+
+    glBufferData(GL_UNIFORM_BUFFER, kDataSize, v.data(), GL_STATIC_DRAW);
+    glBindBufferBase(GL_UNIFORM_BUFFER, 0, mUniformBuffer);
+    glUniformBlockBinding(program, uniformBufferIndex, 0);
+    drawQuad(program.get(), "position", 0.5f);
+    ASSERT_GL_NO_ERROR();
+    EXPECT_PIXEL_COLOR_NEAR(0, 0, GLColor(255, 64, 128, 32), 5);
+}
+
+// Test a uniform block where an individual matrix field is set as column-major whereas the whole
+// block is set as row-major.
+TEST_P(UniformBufferTest, Std140UniformBlockWithPerMemberColumnMajorQualifier)
+{
+    const std::string &fragmentShader =
+        R"(#version 300 es
+
+        precision highp float;
+        out vec4 my_FragColor;
+
+        layout(std140, row_major) uniform matrixBuffer
+        {
+            // 2 columns, 3 rows.
+            layout(column_major) mat2x3 m;
+        } buffer;
+
+        void main()
+        {
+            // Vector constructor accesses elements in column-major order.
+            my_FragColor = vec4(buffer.m);
+        })";
+
+    ANGLE_GL_PROGRAM(program, mVertexShaderSource, fragmentShader);
+    GLint uniformBufferIndex = glGetUniformBlockIndex(program, "matrixBuffer");
+
+    glBindBuffer(GL_UNIFORM_BUFFER, mUniformBuffer);
+    const GLsizei kElementsPerMatrix = 8;  // Each mat2x3 column gets padded into a vec4.
+    const GLsizei kBytesPerElement   = 4;
+    const GLsizei kDataSize          = kElementsPerMatrix * kBytesPerElement;
+    std::vector<GLubyte> v(kDataSize, 0);
+    float *vAsFloat = reinterpret_cast<float *>(v.data());
+
+    vAsFloat[0u] = 1.0f;
+    vAsFloat[1u] = 192.0f / 255.0f;
+    vAsFloat[2u] = 128.0f / 255.0f;
+    vAsFloat[4u] = 96.0f / 255.0f;
+    vAsFloat[5u] = 64.0f / 255.0f;
+    vAsFloat[6u] = 32.0f / 255.0f;
+
+    glBufferData(GL_UNIFORM_BUFFER, kDataSize, v.data(), GL_STATIC_DRAW);
+    glBindBufferBase(GL_UNIFORM_BUFFER, 0, mUniformBuffer);
+    glUniformBlockBinding(program, uniformBufferIndex, 0);
+    drawQuad(program.get(), "position", 0.5f);
+    ASSERT_GL_NO_ERROR();
+    EXPECT_PIXEL_COLOR_NEAR(0, 0, GLColor(255, 192, 128, 96), 5);
+}
+
+// Test a uniform block where a struct field is set as row-major.
+TEST_P(UniformBufferTest, Std140UniformBlockWithRowMajorQualifierOnStruct)
+{
+    // AMD OpenGL driver doesn't seem to apply the row-major qualifier right.
+    // http://anglebug.com/2273
+    ANGLE_SKIP_TEST_IF(IsAMD() && IsOpenGL());
+
+    const std::string &fragmentShader =
+        R"(#version 300 es
+
+        precision highp float;
+        out vec4 my_FragColor;
+
+        struct S
+        {
+            mat2 m;
+        };
+
+        layout(std140) uniform matrixBuffer
+        {
+            layout(row_major) S s;
+        } buffer;
+
+        void main()
+        {
+            // Vector constructor accesses elements in column-major order.
+            my_FragColor = vec4(buffer.s.m);
+        })";
+
+    ANGLE_GL_PROGRAM(program, mVertexShaderSource, fragmentShader);
+    GLint uniformBufferIndex = glGetUniformBlockIndex(program, "matrixBuffer");
+
+    glBindBuffer(GL_UNIFORM_BUFFER, mUniformBuffer);
+    const GLsizei kElementsPerMatrix = 8;  // Each mat2 row gets padded into a vec4.
+    const GLsizei kBytesPerElement   = 4;
+    const GLsizei kDataSize          = kElementsPerMatrix * kBytesPerElement;
+    std::vector<GLubyte> v(kDataSize, 0);
+    float *vAsFloat = reinterpret_cast<float *>(v.data());
+
+    vAsFloat[0u] = 1.0f;
+    vAsFloat[1u] = 128.0f / 255.0f;
+    vAsFloat[4u] = 64.0f / 255.0f;
+    vAsFloat[5u] = 32.0f / 255.0f;
+
+    glBufferData(GL_UNIFORM_BUFFER, kDataSize, v.data(), GL_STATIC_DRAW);
+    glBindBufferBase(GL_UNIFORM_BUFFER, 0, mUniformBuffer);
+    glUniformBlockBinding(program, uniformBufferIndex, 0);
+    drawQuad(program.get(), "position", 0.5f);
+    ASSERT_GL_NO_ERROR();
+    EXPECT_PIXEL_COLOR_NEAR(0, 0, GLColor(255, 64, 128, 32), 5);
+}
+
+constexpr char kVertexShader[] = R"(#version 300 es
+in vec4 a_vertex;
+void main()
+{
+  gl_Position = a_vertex;
+})";
+
+constexpr char kFragmentShader[] = R"(#version 300 es
+precision mediump float;
+
+layout (std140) uniform color_ubo
+{
+  vec4 color;
+};
+
+out vec4 fragColor;
+void main()
+{
+  fragColor = color;
+})";
+
+// Regression test for a dirty bit bug in ANGLE. See http://crbug.com/792966
+TEST_P(UniformBufferTest, SimpleBindingChange)
+{
+    // http://anglebug.com/2287
+    ANGLE_SKIP_TEST_IF(IsOSX() && IsNVIDIA() && IsDesktopOpenGL());
+
+    ANGLE_GL_PROGRAM(program, kVertexShader, kFragmentShader);
+
+    glBindAttribLocation(program, 0, "a_vertex");
+    glUseProgram(program);
+    GLint uboIndex = glGetUniformBlockIndex(program, "color_ubo");
+
+    std::array<GLfloat, 12> vertices{{-1, -1, 0, 1, -1, 0, -1, 1, 0, 1, 1, 0}};
+    GLBuffer vertexBuf;
+    glBindBuffer(GL_ARRAY_BUFFER, vertexBuf);
+    glBufferData(GL_ARRAY_BUFFER, vertices.size() * sizeof(GLfloat), vertices.data(),
+                 GL_STATIC_DRAW);
+    glEnableVertexAttribArray(0);
+    glVertexAttribPointer(0, 3, GL_FLOAT, false, 0, 0);
+
+    std::array<GLshort, 12> indexData = {{0, 1, 2, 2, 1, 3, 0, 1, 2, 2, 1, 3}};
+
+    GLBuffer indexBuf;
+    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, indexBuf);
+    glBufferData(GL_ELEMENT_ARRAY_BUFFER, indexData.size() * sizeof(GLshort), indexData.data(),
+                 GL_STATIC_DRAW);
+
+    // Bind a first buffer with red.
+    GLBuffer uboBuf1;
+    glBindBufferBase(GL_UNIFORM_BUFFER, 0, uboBuf1);
+    glBufferData(GL_UNIFORM_BUFFER, sizeof(GLColor32F), &kFloatRed, GL_STATIC_DRAW);
+    glUniformBlockBinding(program, uboIndex, 0);
+
+    glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_SHORT, 0);
+
+    // Bind a second buffer with green, updating the buffer binding.
+    GLBuffer uboBuf2;
+    glBindBufferBase(GL_UNIFORM_BUFFER, 1, uboBuf2);
+    glBufferData(GL_UNIFORM_BUFFER, sizeof(GLColor32F), &kFloatGreen, GL_STATIC_DRAW);
+    glUniformBlockBinding(program, uboIndex, 1);
+
+    glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_SHORT, reinterpret_cast<const GLvoid *>(12));
+
+    // Verify we get the second buffer.
+    ASSERT_GL_NO_ERROR();
+    EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
+}
+
+// Regression test for a dirty bit bug in ANGLE. Same as above but for the indexed bindings.
+TEST_P(UniformBufferTest, SimpleBufferChange)
+{
+    ANGLE_GL_PROGRAM(program, kVertexShader, kFragmentShader);
+
+    glBindAttribLocation(program, 0, "a_vertex");
+    glUseProgram(program);
+    GLint uboIndex = glGetUniformBlockIndex(program, "color_ubo");
+
+    std::array<GLfloat, 12> vertices{{-1, -1, 0, 1, -1, 0, -1, 1, 0, 1, 1, 0}};
+    GLBuffer vertexBuf;
+    glBindBuffer(GL_ARRAY_BUFFER, vertexBuf);
+    glBufferData(GL_ARRAY_BUFFER, vertices.size() * sizeof(GLfloat), vertices.data(),
+                 GL_STATIC_DRAW);
+    glEnableVertexAttribArray(0);
+    glVertexAttribPointer(0, 3, GL_FLOAT, false, 0, 0);
+
+    std::array<GLshort, 12> indexData = {{0, 1, 2, 2, 1, 3, 0, 1, 2, 2, 1, 3}};
+
+    GLBuffer indexBuf;
+    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, indexBuf);
+    glBufferData(GL_ELEMENT_ARRAY_BUFFER, indexData.size() * sizeof(GLshort), indexData.data(),
+                 GL_STATIC_DRAW);
+
+    // Bind a first buffer with red.
+    GLBuffer uboBuf1;
+    glBindBufferBase(GL_UNIFORM_BUFFER, 0, uboBuf1);
+    glBufferData(GL_UNIFORM_BUFFER, sizeof(GLColor32F), &kFloatRed, GL_STATIC_DRAW);
+    glUniformBlockBinding(program, uboIndex, 0);
+
+    glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_SHORT, 0);
+
+    // Bind a second buffer to the same binding point (0). This should set to draw green.
+    GLBuffer uboBuf2;
+    glBindBufferBase(GL_UNIFORM_BUFFER, 0, uboBuf2);
+    glBufferData(GL_UNIFORM_BUFFER, sizeof(GLColor32F), &kFloatGreen, GL_STATIC_DRAW);
+
+    glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_SHORT, reinterpret_cast<const GLvoid *>(12));
+
+    ASSERT_GL_NO_ERROR();
+    EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
+}
+
+// Tests a bug in the D3D11 back-end where re-creating the buffer storage should trigger a state
+// update in the State Manager class.
+TEST_P(UniformBufferTest, DependentBufferChange)
+{
+    ANGLE_GL_PROGRAM(program, kVertexShader, kFragmentShader);
+
+    glBindAttribLocation(program, 0, "a_vertex");
+    glUseProgram(program);
+    GLint uboIndex = glGetUniformBlockIndex(program, "color_ubo");
+
+    std::array<GLfloat, 12> vertices{{-1, -1, 0, 1, -1, 0, -1, 1, 0, 1, 1, 0}};
+    GLBuffer vertexBuf;
+    glBindBuffer(GL_ARRAY_BUFFER, vertexBuf);
+    glBufferData(GL_ARRAY_BUFFER, vertices.size() * sizeof(GLfloat), vertices.data(),
+                 GL_STATIC_DRAW);
+    glEnableVertexAttribArray(0);
+    glVertexAttribPointer(0, 3, GL_FLOAT, false, 0, 0);
+
+    std::array<GLshort, 6> indexData = {{0, 1, 2, 2, 1, 3}};
+
+    GLBuffer indexBuf;
+    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, indexBuf);
+    glBufferData(GL_ELEMENT_ARRAY_BUFFER, indexData.size() * sizeof(GLshort), indexData.data(),
+                 GL_STATIC_DRAW);
+
+    GLBuffer ubo;
+    glBindBufferBase(GL_UNIFORM_BUFFER, 0, ubo);
+    glBufferData(GL_UNIFORM_BUFFER, sizeof(GLColor32F), &kFloatRed, GL_STATIC_DRAW);
+    glUniformBlockBinding(program, uboIndex, 0);
+
+    glDrawElements(GL_TRIANGLES, 3, GL_UNSIGNED_SHORT, 0);
+    ASSERT_GL_NO_ERROR();
+    EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::red);
+
+    // Resize the buffer - triggers a re-allocation in the D3D11 back-end.
+    std::vector<GLColor32F> bigData(128, kFloatGreen);
+    glBufferData(GL_UNIFORM_BUFFER, sizeof(GLColor32F) * bigData.size(), bigData.data(),
+                 GL_STATIC_DRAW);
+
+    glDrawElements(GL_TRIANGLES, 3, GL_UNSIGNED_SHORT, 0);
+    ASSERT_GL_NO_ERROR();
+    EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
+}
+
 // Use this to select which configurations (e.g. which renderer, which GLES major version) these tests should be run against.
 ANGLE_INSTANTIATE_TEST(UniformBufferTest,
                        ES3_D3D11(),
                        ES3_D3D11_FL11_1(),
                        ES3_D3D11_FL11_1_REFERENCE(),
                        ES3_OPENGL(),
                        ES3_OPENGLES());
 ANGLE_INSTANTIATE_TEST(UniformBufferTest31, ES31_D3D11(), ES31_OPENGL(), ES31_OPENGLES());
--- a/gfx/angle/src/tests/gl_tests/VertexAttributeTest.cpp
+++ b/gfx/angle/src/tests/gl_tests/VertexAttributeTest.cpp
@@ -1457,16 +1457,64 @@ TEST_P(VertexAttributeCachingTest, Buffe
                               sizeof(GLfloat) * baseStride, expected.data());
         drawQuad(mProgram, "position", 0.5f);
 
         ASSERT_GL_NO_ERROR();
         EXPECT_PIXEL_EQ(getWindowWidth() / 2, getWindowHeight() / 2, 255, 255, 255, 255);
     }
 }
 
+// Tests that repeatedly updating a disabled vertex attribute works as expected.
+// This covers an ANGLE bug where dirty bits for current values were ignoring repeated updates.
+TEST_P(VertexAttributeTest, DisabledAttribUpdates)
+{
+    constexpr char kVertexShader[] = R"(attribute vec2 position;
+attribute float actualValue;
+uniform float expectedValue;
+varying float result;
+void main()
+{
+    result = (actualValue == expectedValue) ? 1.0 : 0.0;
+    gl_Position = vec4(position, 0, 1);
+})";
+
+    constexpr char kFragmentShader[] = R"(varying mediump float result;
+void main()
+{
+    gl_FragColor = result > 0.0 ? vec4(0, 1, 0, 1) : vec4(1, 0, 0, 1);
+})";
+
+    ANGLE_GL_PROGRAM(program, kVertexShader, kFragmentShader);
+
+    glUseProgram(program);
+    GLint attribLoc = glGetAttribLocation(program, "actualValue");
+    ASSERT_NE(-1, attribLoc);
+
+    GLint uniLoc = glGetUniformLocation(program, "expectedValue");
+    ASSERT_NE(-1, uniLoc);
+
+    glVertexAttribPointer(attribLoc, 1, GL_FLOAT, GL_FALSE, 0, nullptr);
+
+    GLint positionLocation = glGetAttribLocation(program, "position");
+    ASSERT_NE(-1, positionLocation);
+    setupQuadVertexBuffer(0.5f, 1.0f);
+    glVertexAttribPointer(positionLocation, 3, GL_FLOAT, GL_FALSE, 0, 0);
+    glEnableVertexAttribArray(positionLocation);
+
+    std::array<GLfloat, 4> testValues = {{1, 2, 3, 4}};
+    for (GLfloat testValue : testValues)
+    {
+        glUniform1f(uniLoc, testValue);
+        glVertexAttrib1f(attribLoc, testValue);
+        glDrawArrays(GL_TRIANGLES, 0, 6);
+        ASSERT_GL_NO_ERROR();
+        EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
+    }
+}
+
 // Use this to select which configurations (e.g. which renderer, which GLES major version) these
 // tests should be run against.
 // D3D11 Feature Level 9_3 uses different D3D formats for vertex attribs compared to Feature Levels
 // 10_0+, so we should test them separately.
 ANGLE_INSTANTIATE_TEST(VertexAttributeTest,
                        ES2_D3D9(),
                        ES2_D3D11(),
                        ES2_D3D11_FL9_3(),
--- a/gfx/angle/src/tests/gl_tests/WebGLCompatibilityTest.cpp
+++ b/gfx/angle/src/tests/gl_tests/WebGLCompatibilityTest.cpp
@@ -113,16 +113,24 @@ class WebGLCompatibilityTest : public AN
             "    {\n"
             "        gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0);\n"
             "    }\n"
             "}\n";
 
         ANGLE_GL_PROGRAM(samplingProgram, samplingVs, samplingFs);
         glUseProgram(samplingProgram.get());
 
+        // Need RGBA8 renderbuffers for enough precision on the readback
+        if (extensionRequestable("GL_OES_rgb8_rgba8"))
+        {
+            glRequestExtensionANGLE("GL_OES_rgb8_rgba8");
+        }
+        ANGLE_SKIP_TEST_IF(!extensionEnabled("GL_OES_rgb8_rgba8") && getClientMajorVersion() < 3);
+        ASSERT_GL_NO_ERROR();
+
         GLRenderbuffer rbo;
         glBindRenderbuffer(GL_RENDERBUFFER, rbo.get());
         glRenderbufferStorage(GL_RENDERBUFFER, GL_RGBA8, 1, 1);
 
         GLFramebuffer fbo;
         glBindFramebuffer(GL_FRAMEBUFFER, fbo.get());
         glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, rbo.get());
 
@@ -222,16 +230,25 @@ class WebGLCompatibilityTest : public AN
                                     const std::array<GLenum, 2> &drawBuffers,
                                     GLenum expectedError);
 
     // Called from RenderingFeedbackLoopWithDrawBuffers.
     void drawBuffersFeedbackLoop(GLuint program,
                                  const std::array<GLenum, 2> &drawBuffers,
                                  GLenum expectedError);
 
+    // Called from Enable[Compressed]TextureFormatExtensions
+    void validateTexImageExtensionFormat(GLenum format, const std::string &extName);
+    void validateCompressedTexImageExtensionFormat(GLenum format,
+                                                   GLsizei width,
+                                                   GLsizei height,
+                                                   GLsizei blockSize,
+                                                   const std::string &extName,
+                                                   bool subImageAllowed);
+
     PFNGLREQUESTEXTENSIONANGLEPROC glRequestExtensionANGLE = nullptr;
 };
 
 class WebGL2CompatibilityTest : public WebGLCompatibilityTest
 {
 };
 
 // Context creation would fail if EGL_ANGLE_create_context_webgl_compatibility was not available so
@@ -442,19 +459,538 @@ TEST_P(WebGLCompatibilityTest, Extension
         "    gl_FragColor = vec4(1.0,0.0,0.0,1.0);\n"
         "}";
 
     GLuint program = CompileProgram(vert, frag);
     EXPECT_EQ(0u, program);
     glDeleteProgram(program);
 }
 
+// Test enabling the GL_NV_pixel_buffer_object extension
+TEST_P(WebGLCompatibilityTest, EnablePixelBufferObjectExtensions)
+{
+    EXPECT_FALSE(extensionEnabled("GL_NV_pixel_buffer_object"));
+    EXPECT_FALSE(extensionEnabled("GL_OES_mapbuffer"));
+    EXPECT_FALSE(extensionEnabled("GL_EXT_map_buffer_range"));
+
+    // These extensions become core in in ES3/WebGL2.
+    ANGLE_SKIP_TEST_IF(getClientMajorVersion() >= 3);
+
+    GLBuffer buffer;
+    glBindBuffer(GL_PIXEL_PACK_BUFFER, buffer);
+    EXPECT_GL_ERROR(GL_INVALID_ENUM);
+
+    if (extensionRequestable("GL_NV_pixel_buffer_object"))
+    {
+        glRequestExtensionANGLE("GL_NV_pixel_buffer_object");
+        EXPECT_GL_NO_ERROR();
+
+        glBindBuffer(GL_PIXEL_PACK_BUFFER, buffer);
+        EXPECT_GL_NO_ERROR();
+
+        glBufferData(GL_PIXEL_PACK_BUFFER, 4, nullptr, GL_STATIC_DRAW);
+        glReadPixels(0, 0, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
+        EXPECT_GL_NO_ERROR();
+    }
+}
+
+// Test enabling the GL_OES_mapbuffer and GL_EXT_map_buffer_range extensions
+TEST_P(WebGLCompatibilityTest, EnableMapBufferExtensions)
+{
+    EXPECT_FALSE(extensionEnabled("GL_OES_mapbuffer"));
+    EXPECT_FALSE(extensionEnabled("GL_EXT_map_buffer_range"));
+
+    // These extensions become core in in ES3/WebGL2.
+    ANGLE_SKIP_TEST_IF(getClientMajorVersion() >= 3);
+
+    GLBuffer buffer;
+    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, buffer);
+    glBufferData(GL_ELEMENT_ARRAY_BUFFER, 4, nullptr, GL_STATIC_DRAW);
+
+    glMapBufferOES(GL_ELEMENT_ARRAY_BUFFER, GL_WRITE_ONLY_OES);
+    EXPECT_GL_ERROR(GL_INVALID_OPERATION);
+
+    glMapBufferRangeEXT(GL_ELEMENT_ARRAY_BUFFER, 0, 4, GL_MAP_WRITE_BIT);
+    EXPECT_GL_ERROR(GL_INVALID_OPERATION);
+
+    GLint access = 0;
+    glGetBufferParameteriv(GL_ELEMENT_ARRAY_BUFFER, GL_BUFFER_ACCESS_OES, &access);
+    EXPECT_GL_ERROR(GL_INVALID_ENUM);
+
+    if (extensionRequestable("GL_OES_mapbuffer"))
+    {
+        glRequestExtensionANGLE("GL_OES_mapbuffer");
+        EXPECT_GL_NO_ERROR();
+
+        glMapBufferOES(GL_ELEMENT_ARRAY_BUFFER, GL_WRITE_ONLY_OES);
+        glUnmapBufferOES(GL_ELEMENT_ARRAY_BUFFER);
+        glGetBufferParameteriv(GL_ELEMENT_ARRAY_BUFFER, GL_BUFFER_ACCESS_OES, &access);
+        EXPECT_GL_NO_ERROR();
+    }
+
+    if (extensionRequestable("GL_EXT_map_buffer_range"))
+    {
+        glRequestExtensionANGLE("GL_EXT_map_buffer_range");
+        EXPECT_GL_NO_ERROR();
+
+        glMapBufferRangeEXT(GL_ELEMENT_ARRAY_BUFFER, 0, 4, GL_MAP_WRITE_BIT);
+        glUnmapBufferOES(GL_ELEMENT_ARRAY_BUFFER);
+        glGetBufferParameteriv(GL_ELEMENT_ARRAY_BUFFER, GL_BUFFER_ACCESS_OES, &access);
+        EXPECT_GL_NO_ERROR();
+    }
+}
+
+// Test enabling the GL_OES_fbo_render_mipmap extension
+TEST_P(WebGLCompatibilityTest, EnableRenderMipmapExtension)
+{
+    EXPECT_FALSE(extensionEnabled("GL_OES_fbo_render_mipmap"));
+
+    // This extensions become core in in ES3/WebGL2.
+    ANGLE_SKIP_TEST_IF(getClientMajorVersion() >= 3);
+
+    GLTexture texture;
+    glBindTexture(GL_TEXTURE_2D, texture);
+    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
+    glTexImage2D(GL_TEXTURE_2D, 1, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
+
+    GLFramebuffer fbo;
+    glBindFramebuffer(GL_FRAMEBUFFER, fbo);
+    glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture, 0);
+    EXPECT_GL_NO_ERROR();
+
+    glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture, 1);
+    EXPECT_GL_ERROR(GL_INVALID_VALUE);
+
+    if (extensionRequestable("GL_OES_fbo_render_mipmap"))
+    {
+        glRequestExtensionANGLE("GL_OES_fbo_render_mipmap");
+        EXPECT_GL_NO_ERROR();
+
+        glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture, 1);
+        EXPECT_GL_NO_ERROR();
+    }
+}
+
+// Test enabling the GL_EXT_blend_minmax extension
+TEST_P(WebGLCompatibilityTest, EnableBlendMinMaxExtension)
+{
+    EXPECT_FALSE(extensionEnabled("GL_EXT_blend_minmax"));
+
+    // This extensions become core in in ES3/WebGL2.
+    ANGLE_SKIP_TEST_IF(getClientMajorVersion() >= 3);
+
+    glBlendEquation(GL_MIN);
+    EXPECT_GL_ERROR(GL_INVALID_ENUM);
+
+    glBlendEquation(GL_MAX);
+    EXPECT_GL_ERROR(GL_INVALID_ENUM);
+
+    if (extensionRequestable("GL_EXT_blend_minmax"))
+    {
+        glRequestExtensionANGLE("GL_EXT_blend_minmax");
+        EXPECT_GL_NO_ERROR();
+
+        glBlendEquation(GL_MIN);
+        glBlendEquation(GL_MAX);
+        EXPECT_GL_NO_ERROR();
+    }
+}
+
+// Test enabling the query extensions
+TEST_P(WebGLCompatibilityTest, EnableQueryExtensions)
+{
+    EXPECT_FALSE(extensionEnabled("GL_EXT_occlusion_query_boolean"));
+    EXPECT_FALSE(extensionEnabled("GL_EXT_disjoint_timer_query"));
+    EXPECT_FALSE(extensionEnabled("GL_CHROMIUM_sync_query"));
+
+    // This extensions become core in in ES3/WebGL2.
+    ANGLE_SKIP_TEST_IF(getClientMajorVersion() >= 3);
+
+    GLQueryEXT badQuery;
+
+    glBeginQueryEXT(GL_ANY_SAMPLES_PASSED_EXT, badQuery);
+    EXPECT_GL_ERROR(GL_INVALID_OPERATION);
+
+    glBeginQueryEXT(GL_ANY_SAMPLES_PASSED_CONSERVATIVE, badQuery);
+    EXPECT_GL_ERROR(GL_INVALID_OPERATION);
+
+    glBeginQueryEXT(GL_TIME_ELAPSED_EXT, badQuery);
+    EXPECT_GL_ERROR(GL_INVALID_OPERATION);
+
+    glQueryCounterEXT(GL_TIMESTAMP_EXT, badQuery);
+    EXPECT_GL_ERROR(GL_INVALID_OPERATION);
+
+    glBeginQueryEXT(GL_COMMANDS_COMPLETED_CHROMIUM, badQuery);
+    EXPECT_GL_ERROR(GL_INVALID_OPERATION);
+
+    if (extensionRequestable("GL_EXT_occlusion_query_boolean"))
+    {
+        glRequestExtensionANGLE("GL_EXT_occlusion_query_boolean");
+        EXPECT_GL_NO_ERROR();
+
+        GLQueryEXT query;
+        glBeginQueryEXT(GL_ANY_SAMPLES_PASSED_EXT, query);
+        glEndQueryEXT(GL_ANY_SAMPLES_PASSED_EXT);
+        EXPECT_GL_NO_ERROR();
+    }
+
+    if (extensionRequestable("GL_EXT_disjoint_timer_query"))
+    {
+        glRequestExtensionANGLE("GL_EXT_disjoint_timer_query");
+        EXPECT_GL_NO_ERROR();
+
+        GLQueryEXT query1;
+        glBeginQueryEXT(GL_TIME_ELAPSED_EXT, query1);
+        glEndQueryEXT(GL_TIME_ELAPSED_EXT);
+        EXPECT_GL_NO_ERROR();
+
+        GLQueryEXT query2;
+        glQueryCounterEXT(query2, GL_TIMESTAMP_EXT);
+        EXPECT_GL_NO_ERROR();
+    }
+
+    if (extensionRequestable("GL_CHROMIUM_sync_query"))
+    {
+        glRequestExtensionANGLE("GL_CHROMIUM_sync_query");
+        EXPECT_GL_NO_ERROR();
+
+        GLQueryEXT query;
+        glBeginQueryEXT(GL_COMMANDS_COMPLETED_CHROMIUM, query);
+        glEndQueryEXT(GL_COMMANDS_COMPLETED_CHROMIUM);
+        EXPECT_GL_NO_ERROR();
+    }
+}
+
+// Test enabling the GL_ANGLE_framebuffer_multisample extension
+TEST_P(WebGLCompatibilityTest, EnableFramebufferMultisampleExtension)
+{
+    EXPECT_FALSE(extensionEnabled("GL_ANGLE_framebuffer_multisample"));
+
+    // This extensions become core in in ES3/WebGL2.
+    ANGLE_SKIP_TEST_IF(getClientMajorVersion() >= 3);
+
+    GLint maxSamples = 0;
+    glGetIntegerv(GL_MAX_SAMPLES, &maxSamples);
+    EXPECT_GL_ERROR(GL_INVALID_ENUM);
+
+    GLRenderbuffer renderbuffer;
+    glBindRenderbuffer(GL_RENDERBUFFER, renderbuffer);
+    glRenderbufferStorageMultisampleANGLE(GL_RENDERBUFFER, 1, GL_RGBA4, 1, 1);
+    EXPECT_GL_ERROR(GL_INVALID_OPERATION);
+
+    if (extensionRequestable("GL_ANGLE_framebuffer_multisample"))
+    {
+        glRequestExtensionANGLE("GL_ANGLE_framebuffer_multisample");
+        EXPECT_GL_NO_ERROR();
+
+        glGetIntegerv(GL_MAX_SAMPLES, &maxSamples);
+        EXPECT_GL_NO_ERROR();
+
+        glRenderbufferStorageMultisampleANGLE(GL_RENDERBUFFER, maxSamples, GL_RGBA4, 1, 1);
+        EXPECT_GL_NO_ERROR();
+    }
+}
+
+// Test enabling the GL_ANGLE_instanced_arrays extension
+TEST_P(WebGLCompatibilityTest, EnableInstancedArraysExtension)
+{
+    EXPECT_FALSE(extensionEnabled("GL_ANGLE_instanced_arrays"));
+
+    // This extensions become core in in ES3/WebGL2.
+    ANGLE_SKIP_TEST_IF(getClientMajorVersion() >= 3);
+
+    GLint divisor = 0;
+    glGetVertexAttribiv(0, GL_VERTEX_ATTRIB_ARRAY_DIVISOR, &divisor);
+    EXPECT_GL_ERROR(GL_INVALID_ENUM);
+
+    glVertexAttribDivisorANGLE(0, 1);
+    EXPECT_GL_ERROR(GL_INVALID_OPERATION);
+
+    if (extensionRequestable("GL_ANGLE_instanced_arrays"))
+    {
+        glRequestExtensionANGLE("GL_ANGLE_instanced_arrays");
+        EXPECT_GL_NO_ERROR();
+
+        glGetVertexAttribiv(0, GL_VERTEX_ATTRIB_ARRAY_DIVISOR, &divisor);
+        glVertexAttribDivisorANGLE(0, 1);
+        EXPECT_GL_NO_ERROR();
+    }
+}
+
+// Test enabling the GL_ANGLE_pack_reverse_row_order extension
+TEST_P(WebGLCompatibilityTest, EnablePackReverseRowOrderExtension)
+{
+    EXPECT_FALSE(extensionEnabled("GL_ANGLE_pack_reverse_row_order"));
+
+    GLint result = 0;
+    glGetIntegerv(GL_PACK_REVERSE_ROW_ORDER_ANGLE, &result);
+    EXPECT_GL_ERROR(GL_INVALID_ENUM);
+
+    glPixelStorei(GL_PACK_REVERSE_ROW_ORDER_ANGLE, GL_TRUE);
+    EXPECT_GL_ERROR(GL_INVALID_ENUM);
+
+    if (extensionRequestable("GL_ANGLE_pack_reverse_row_order"))
+    {
+        glRequestExtensionANGLE("GL_ANGLE_pack_reverse_row_order");
+        EXPECT_GL_NO_ERROR();
+
+        glGetIntegerv(GL_PACK_REVERSE_ROW_ORDER_ANGLE, &result);
+        glPixelStorei(GL_PACK_REVERSE_ROW_ORDER_ANGLE, GL_TRUE);
+        EXPECT_GL_NO_ERROR();
+    }
+}
+
+// Test enabling the GL_EXT_unpack_subimage extension
+TEST_P(WebGLCompatibilityTest, EnablePackUnpackSubImageExtension)
+{
+    EXPECT_FALSE(extensionEnabled("GL_EXT_unpack_subimage"));
+
+    // This extensions become core in in ES3/WebGL2.
+    ANGLE_SKIP_TEST_IF(getClientMajorVersion() >= 3);
+
+    constexpr GLenum parameters[] = {
+        GL_UNPACK_ROW_LENGTH_EXT, GL_UNPACK_SKIP_ROWS_EXT, GL_UNPACK_SKIP_PIXELS_EXT,
+    };
+
+    for (GLenum param : parameters)
+    {
+        GLint resultI = 0;
+        glGetIntegerv(param, &resultI);
+        EXPECT_GL_ERROR(GL_INVALID_ENUM);
+
+        GLfloat resultF = 0.0f;
+        glGetFloatv(param, &resultF);
+        EXPECT_GL_ERROR(GL_INVALID_ENUM);
+
+        glPixelStorei(param, 0);
+        EXPECT_GL_ERROR(GL_INVALID_ENUM);
+    }
+
+    if (extensionRequestable("GL_EXT_unpack_subimage"))
+    {
+        glRequestExtensionANGLE("GL_EXT_unpack_subimage");
+        EXPECT_GL_NO_ERROR();
+
+        for (GLenum param : parameters)
+        {
+            GLint resultI = 0;
+            glGetIntegerv(param, &resultI);
+
+            GLfloat resultF = 0.0f;
+            glGetFloatv(param, &resultF);
+
+            glPixelStorei(param, 0);
+
+            EXPECT_GL_NO_ERROR();
+        }
+    }
+}
+
+TEST_P(WebGLCompatibilityTest, EnableTextureRectangle)
+{
+    EXPECT_FALSE(extensionEnabled("GL_ANGLE_texture_rectangle"));
+
+    GLTexture texture;
+    glBindTexture(GL_TEXTURE_RECTANGLE_ANGLE, texture);
+    EXPECT_GL_ERROR(GL_INVALID_ENUM);
+
+    GLint minFilter = 0;
+    glGetTexParameteriv(GL_TEXTURE_RECTANGLE_ANGLE, GL_TEXTURE_MIN_FILTER, &minFilter);
+    EXPECT_GL_ERROR(GL_INVALID_ENUM);
+
+    if (extensionRequestable("GL_ANGLE_texture_rectangle"))
+    {
+        glRequestExtensionANGLE("GL_ANGLE_texture_rectangle");
+        EXPECT_GL_NO_ERROR();
+
+        EXPECT_TRUE(extensionEnabled("GL_ANGLE_texture_rectangle"));
+
+        glBindTexture(GL_TEXTURE_RECTANGLE_ANGLE, texture);
+        EXPECT_GL_NO_ERROR();
+
+        glTexImage2D(GL_TEXTURE_RECTANGLE_ANGLE, 0, GL_RGBA, 16, 16, 0, GL_RGBA, GL_UNSIGNED_BYTE,
+                     nullptr);
+        EXPECT_GL_NO_ERROR();
+    }
+}
+
+// Test enabling the GL_NV_pack_subimage extension
+TEST_P(WebGLCompatibilityTest, EnablePackPackSubImageExtension)
+{
+    EXPECT_FALSE(extensionEnabled("GL_NV_pack_subimage"));
+
+    // This extensions become core in in ES3/WebGL2.
+    ANGLE_SKIP_TEST_IF(getClientMajorVersion() >= 3);
+
+    constexpr GLenum parameters[] = {
+        GL_PACK_ROW_LENGTH, GL_PACK_SKIP_ROWS, GL_PACK_SKIP_PIXELS,
+    };
+
+    for (GLenum param : parameters)
+    {
+        GLint resultI = 0;
+        glGetIntegerv(param, &resultI);
+        EXPECT_GL_ERROR(GL_INVALID_ENUM);
+
+        GLfloat resultF = 0.0f;
+        glGetFloatv(param, &resultF);
+        EXPECT_GL_ERROR(GL_INVALID_ENUM);
+
+        glPixelStorei(param, 0);
+        EXPECT_GL_ERROR(GL_INVALID_ENUM);
+    }
+
+    if (extensionRequestable("GL_NV_pack_subimage"))
+    {
+        glRequestExtensionANGLE("GL_NV_pack_subimage");
+        EXPECT_GL_NO_ERROR();
+
+        for (GLenum param : parameters)
+        {
+            GLint resultI = 0;
+            glGetIntegerv(param, &resultI);
+
+            GLfloat resultF = 0.0f;
+            glGetFloatv(param, &resultF);
+
+            glPixelStorei(param, 0);
+
+            EXPECT_GL_NO_ERROR();
+        }
+    }
+}
+
+TEST_P(WebGLCompatibilityTest, EnableRGB8RGBA8Extension)
+{
+    EXPECT_FALSE(extensionEnabled("GL_OES_rgb8_rgba8"));
+
+    // This extensions become core in in ES3/WebGL2.
+    ANGLE_SKIP_TEST_IF(getClientMajorVersion() >= 3);
+
+    GLRenderbuffer renderbuffer;
+    glBindRenderbuffer(GL_RENDERBUFFER, renderbuffer);
+    EXPECT_GL_NO_ERROR();
+
+    glRenderbufferStorage(GL_RENDERBUFFER, GL_RGB8_OES, 1, 1);
+    EXPECT_GL_ERROR(GL_INVALID_ENUM);
+
+    glRenderbufferStorage(GL_RENDERBUFFER, GL_RGBA8_OES, 1, 1);
+    EXPECT_GL_ERROR(GL_INVALID_ENUM);
+
+    if (extensionRequestable("GL_OES_rgb8_rgba8"))
+    {
+        glRequestExtensionANGLE("GL_OES_rgb8_rgba8");
+        EXPECT_GL_NO_ERROR();
+
+        EXPECT_TRUE(extensionEnabled("GL_OES_rgb8_rgba8"));
+
+        glRenderbufferStorage(GL_RENDERBUFFER, GL_RGB8_OES, 1, 1);
+        EXPECT_GL_NO_ERROR();
+
+        glRenderbufferStorage(GL_RENDERBUFFER, GL_RGBA8_OES, 1, 1);
+        EXPECT_GL_NO_ERROR();
+    }
+}
+
+// Test enabling the GL_ANGLE_framebuffer_blit extension
+TEST_P(WebGLCompatibilityTest, EnableFramebufferBlitExtension)
+{
+    EXPECT_FALSE(extensionEnabled("GL_ANGLE_framebuffer_blit"));
+
+    // This extensions become core in in ES3/WebGL2.
+    ANGLE_SKIP_TEST_IF(getClientMajorVersion() >= 3);
+
+    GLFramebuffer fbo;
+
+    glBindFramebuffer(GL_READ_FRAMEBUFFER_ANGLE, fbo);
+    EXPECT_GL_ERROR(GL_INVALID_ENUM);
+
+    GLint result;
+    glGetIntegerv(GL_READ_FRAMEBUFFER_BINDING_ANGLE, &result);
+    EXPECT_GL_ERROR(GL_INVALID_ENUM);
+
+    glBlitFramebufferANGLE(0, 0, 1, 1, 0, 0, 1, 1, GL_COLOR_BUFFER_BIT, GL_NEAREST);
+    EXPECT_GL_ERROR(GL_INVALID_OPERATION);
+
+    if (extensionRequestable("GL_ANGLE_framebuffer_blit"))
+    {
+        glRequestExtensionANGLE("GL_ANGLE_framebuffer_blit");
+        EXPECT_GL_NO_ERROR();
+
+        glBindFramebuffer(GL_READ_FRAMEBUFFER_ANGLE, fbo);
+        glGetIntegerv(GL_READ_FRAMEBUFFER_BINDING_ANGLE, &result);
+        EXPECT_GL_NO_ERROR();
+    }
+}
+
+// Test enabling the GL_OES_get_program_binary extension
+TEST_P(WebGLCompatibilityTest, EnableProgramBinaryExtension)
+{
+    EXPECT_FALSE(extensionEnabled("GL_OES_get_program_binary"));
+
+    // This extensions become core in in ES3/WebGL2.
+    ANGLE_SKIP_TEST_IF(getClientMajorVersion() >= 3);
+
+    GLint result = 0;
+    glGetIntegerv(GL_NUM_PROGRAM_BINARY_FORMATS, &result);
+    EXPECT_GL_ERROR(GL_INVALID_ENUM);
+
+    glGetIntegerv(GL_PROGRAM_BINARY_FORMATS, &result);
+    EXPECT_GL_ERROR(GL_INVALID_ENUM);
+
+    const std::string &vert =
+        "void main()\n"
+        "{\n"
+        "    gl_Position = vec4(0.0, 0.0, 0.0, 1.0);\n"
+        "}\n";
+    const std::string &frag =
+        "precision highp float;\n"
+        "void main()\n"
+        "{\n"
+        "    gl_FragColor = vec4(1.0);\n"
+        "}\n";
+    ANGLE_GL_PROGRAM(program, vert, frag);
+
+    glGetProgramiv(program, GL_PROGRAM_BINARY_LENGTH, &result);
+    EXPECT_GL_ERROR(GL_INVALID_ENUM);
+
+    uint8_t tempArray[512];
+    GLenum tempFormat  = 0;
+    GLsizei tempLength = 0;
+    glGetProgramBinaryOES(program, static_cast<GLsizei>(ArraySize(tempArray)), &tempLength,
+                          &tempFormat, tempArray);
+    EXPECT_GL_ERROR(GL_INVALID_OPERATION);
+
+    if (extensionRequestable("GL_OES_get_program_binary"))
+    {
+        glRequestExtensionANGLE("GL_OES_get_program_binary");
+        EXPECT_GL_NO_ERROR();
+
+        glGetIntegerv(GL_NUM_PROGRAM_BINARY_FORMATS, &result);
+        glGetIntegerv(GL_PROGRAM_BINARY_FORMATS, &result);
+        EXPECT_GL_NO_ERROR();
+
+        GLint binaryLength = 0;
+        glGetProgramiv(program, GL_PROGRAM_BINARY_LENGTH, &binaryLength);
+        EXPECT_GL_NO_ERROR();
+
+        GLenum binaryFormat;
+        GLsizei writeLength = 0;
+        std::vector<uint8_t> binary(binaryLength);
+        glGetProgramBinaryOES(program, binaryLength, &writeLength, &binaryFormat, binary.data());
+        EXPECT_GL_NO_ERROR();
+
+        glProgramBinaryOES(program, binaryFormat, binary.data(), binaryLength);
+        EXPECT_GL_NO_ERROR();
+    }
+}
+
 // Verify that the context generates the correct error when the framebuffer attachments are
 // different sizes
-TEST_P(WebGLCompatibilityTest, FramebufferAttachmentSizeMissmatch)
+TEST_P(WebGLCompatibilityTest, FramebufferAttachmentSizeMismatch)
 {
     GLFramebuffer fbo;
     glBindFramebuffer(GL_FRAMEBUFFER, fbo);
 
     GLTexture textures[2];
     glBindTexture(GL_TEXTURE_2D, textures[0]);
     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
     glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, textures[0], 0);
@@ -597,16 +1133,57 @@ TEST_P(WebGLCompatibilityTest, ForbidsCl
     glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 4, vertices.data());
     glEnableVertexAttribArray(0);
 
     ASSERT_GL_NO_ERROR();
     glDrawArrays(GL_TRIANGLES, 0, 6);
     EXPECT_GL_ERROR(GL_INVALID_OPERATION);
 }
 
+// Test that passing a null pixel data pointer to TexSubImage calls generates an INVALID_VALUE error
+TEST_P(WebGLCompatibilityTest, NullPixelDataForSubImage)
+{
+    // glTexSubImage2D
+    {
+        GLTexture texture;
+        glBindTexture(GL_TEXTURE_2D, texture);
+
+        // TexImage with null data - OK
+        glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
+        EXPECT_GL_NO_ERROR();
+
+        // TexSubImage with zero size and null data - OK
+        glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
+        EXPECT_GL_NO_ERROR();
+
+        // TexSubImage with non-zero size and null data - Invalid value
+        glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
+        EXPECT_GL_ERROR(GL_INVALID_VALUE);
+    }
+
+    // glTexSubImage3D
+    if (getClientMajorVersion() >= 3)
+    {
+        GLTexture texture;
+        glBindTexture(GL_TEXTURE_3D, texture);
+
+        // TexImage with null data - OK
+        glTexImage3D(GL_TEXTURE_3D, 0, GL_RGBA, 1, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
+        EXPECT_GL_NO_ERROR();
+
+        // TexSubImage with zero size and null data - OK
+        glTexSubImage3D(GL_TEXTURE_3D, 0, 0, 0, 0, 0, 0, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
+        EXPECT_GL_NO_ERROR();
+
+        // TexSubImage with non-zero size and null data - Invalid value
+        glTexSubImage3D(GL_TEXTURE_3D, 0, 0, 0, 0, 1, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
+        EXPECT_GL_ERROR(GL_INVALID_VALUE);
+    }
+}
+
 // Tests the WebGL requirement of having the same stencil mask, writemask and ref for fron and back
 TEST_P(WebGLCompatibilityTest, RequiresSameStencilMaskAndRef)
 {
     // Run the test in an FBO to make sure we have some stencil bits.
     GLRenderbuffer renderbuffer;
     glBindRenderbuffer(GL_RENDERBUFFER, renderbuffer.get());
     glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH24_STENCIL8, 32, 32);
 
@@ -703,53 +1280,200 @@ TEST_P(WebGLCompatibilityTest, DrawArray
     const std::string &frag =
         "precision highp float;\n"
         "void main()\n"
         "{\n"
         "    gl_FragColor = vec4(1.0);\n"
         "}\n";
 
     ANGLE_GL_PROGRAM(program, vert, frag);
-
     GLint posLocation = glGetAttribLocation(program.get(), "a_pos");
     ASSERT_NE(-1, posLocation);
     glUseProgram(program.get());
 
     GLBuffer buffer;
     glBindBuffer(GL_ARRAY_BUFFER, buffer.get());
     glBufferData(GL_ARRAY_BUFFER, 16, nullptr, GL_STATIC_DRAW);
 
     glEnableVertexAttribArray(posLocation);
 
     const uint8_t* zeroOffset = nullptr;
 
     // Test touching the last element is valid.
-    glVertexAttribPointer(0, 1, GL_UNSIGNED_BYTE, GL_FALSE, 0, zeroOffset + 12);
+    glVertexAttribPointer(posLocation, 1, GL_UNSIGNED_BYTE, GL_FALSE, 0, zeroOffset + 12);
     glDrawArrays(GL_POINTS, 0, 4);
     ASSERT_GL_NO_ERROR();
 
     // Test touching the last element + 1 is invalid.
-    glVertexAttribPointer(0, 1, GL_UNSIGNED_BYTE, GL_FALSE, 0, zeroOffset + 13);
+    glVertexAttribPointer(posLocation, 1, GL_UNSIGNED_BYTE, GL_FALSE, 0, zeroOffset + 13);
     glDrawArrays(GL_POINTS, 0, 4);
     EXPECT_GL_ERROR(GL_INVALID_OPERATION);
 
     // Test touching the last element is valid, using a stride.
-    glVertexAttribPointer(0, 1, GL_UNSIGNED_BYTE, GL_FALSE, 2, zeroOffset + 9);
+    glVertexAttribPointer(posLocation, 1, GL_UNSIGNED_BYTE, GL_FALSE, 2, zeroOffset + 9);
     glDrawArrays(GL_POINTS, 0, 4);
     ASSERT_GL_NO_ERROR();
 
     // Test touching the last element + 1 is invalid, using a stride.
-    glVertexAttribPointer(0, 1, GL_UNSIGNED_BYTE, GL_FALSE, 2, zeroOffset + 10);
+    glVertexAttribPointer(posLocation, 1, GL_UNSIGNED_BYTE, GL_FALSE, 2, zeroOffset + 10);
     glDrawArrays(GL_POINTS, 0, 4);
     EXPECT_GL_ERROR(GL_INVALID_OPERATION);
 
     // Test any offset is valid if no vertices are drawn.
-    glVertexAttribPointer(0, 1, GL_UNSIGNED_BYTE, GL_FALSE, 0, zeroOffset + 32);
+    glVertexAttribPointer(posLocation, 1, GL_UNSIGNED_BYTE, GL_FALSE, 0, zeroOffset + 32);
     glDrawArrays(GL_POINTS, 0, 0);
     ASSERT_GL_NO_ERROR();
+
+    // Test a case of overflow that could give a max vertex that's negative
+    constexpr GLint kIntMax = std::numeric_limits<GLint>::max();
+    glVertexAttribPointer(posLocation, 1, GL_UNSIGNED_BYTE, GL_FALSE, 0, zeroOffset + 0);
+    glDrawArrays(GL_POINTS, kIntMax, kIntMax);
+    EXPECT_GL_ERROR(GL_INVALID_OPERATION);
+}
+
+// Test the checks for OOB reads in the vertex buffers, instanced version
+TEST_P(WebGL2CompatibilityTest, DrawArraysBufferOutOfBoundsInstanced)
+{
+    const std::string &vert =
+        "attribute float a_pos;\n"
+        "attribute float a_w;\n"
+        "void main()\n"
+        "{\n"
+        "    gl_Position = vec4(a_pos, a_pos, a_pos, a_w);\n"
+        "}\n";
+
+    const std::string &frag =
+        "precision highp float;\n"
+        "void main()\n"
+        "{\n"
+        "    gl_FragColor = vec4(1.0);\n"
+        "}\n";
+
+    ANGLE_GL_PROGRAM(program, vert, frag);
+    GLint posLocation = glGetAttribLocation(program.get(), "a_pos");
+    GLint wLocation = glGetAttribLocation(program.get(), "a_w");
+    ASSERT_NE(-1, posLocation);
+    ASSERT_NE(-1, wLocation);
+    glUseProgram(program.get());
+
+    GLBuffer buffer;
+    glBindBuffer(GL_ARRAY_BUFFER, buffer.get());
+    glBufferData(GL_ARRAY_BUFFER, 16, nullptr, GL_STATIC_DRAW);
+
+    glEnableVertexAttribArray(posLocation);
+    glVertexAttribPointer(posLocation, 1, GL_UNSIGNED_BYTE, GL_FALSE, 0, 0);
+    glVertexAttribDivisor(posLocation, 0);
+
+    glEnableVertexAttribArray(wLocation);
+    glVertexAttribDivisor(wLocation, 1);
+
+    const uint8_t* zeroOffset = nullptr;
+
+    // Test touching the last element is valid.
+    glVertexAttribPointer(wLocation, 1, GL_UNSIGNED_BYTE, GL_FALSE, 0, zeroOffset + 12);
+    glDrawArraysInstanced(GL_POINTS, 0, 1, 4);
+    ASSERT_GL_NO_ERROR();
+
+    // Test touching the last element + 1 is invalid.
+    glVertexAttribPointer(wLocation, 1, GL_UNSIGNED_BYTE, GL_FALSE, 0, zeroOffset + 13);
+    glDrawArraysInstanced(GL_POINTS, 0, 1, 4);
+    EXPECT_GL_ERROR(GL_INVALID_OPERATION);
+
+    // Test touching the last element is valid, using a stride.
+    glVertexAttribPointer(wLocation, 1, GL_UNSIGNED_BYTE, GL_FALSE, 2, zeroOffset + 9);
+    glDrawArraysInstanced(GL_POINTS, 0, 1, 4);
+    ASSERT_GL_NO_ERROR();
+
+    // Test touching the last element + 1 is invalid, using a stride.
+    glVertexAttribPointer(wLocation, 1, GL_UNSIGNED_BYTE, GL_FALSE, 2, zeroOffset + 10);
+    glDrawArraysInstanced(GL_POINTS, 0, 1, 4);
+    EXPECT_GL_ERROR(GL_INVALID_OPERATION);
+
+    // Test any offset is valid if no vertices are drawn.
+    glVertexAttribPointer(wLocation, 1, GL_UNSIGNED_BYTE, GL_FALSE, 0, zeroOffset + 32);
+    glDrawArraysInstanced(GL_POINTS, 0, 0, 1);
+    ASSERT_GL_NO_ERROR();
+
+    // Test any offset is valid if no primitives are drawn.
+    glVertexAttribPointer(wLocation, 1, GL_UNSIGNED_BYTE, GL_FALSE, 0, zeroOffset + 32);
+    glDrawArraysInstanced(GL_POINTS, 0, 1, 0);
+    ASSERT_GL_NO_ERROR();
+}
+
+// Test the checks for OOB reads in the vertex buffers, ANGLE_instanced_arrays version
+TEST_P(WebGLCompatibilityTest, DrawArraysBufferOutOfBoundsInstancedANGLE)
+{
+    ANGLE_SKIP_TEST_IF(!extensionRequestable("GL_ANGLE_instanced_arrays"));
+    glRequestExtensionANGLE("GL_ANGLE_instanced_arrays");
+    EXPECT_GL_NO_ERROR();
+
+    const std::string &vert =
+        "attribute float a_pos;\n"
+        "attribute float a_w;\n"
+        "void main()\n"
+        "{\n"
+        "    gl_Position = vec4(a_pos, a_pos, a_pos, a_w);\n"
+        "}\n";
+
+    const std::string &frag =
+        "precision highp float;\n"
+        "void main()\n"
+        "{\n"
+        "    gl_FragColor = vec4(1.0);\n"
+        "}\n";
+
+    ANGLE_GL_PROGRAM(program, vert, frag);
+    GLint posLocation = glGetAttribLocation(program.get(), "a_pos");
+    GLint wLocation = glGetAttribLocation(program.get(), "a_w");
+    ASSERT_NE(-1, posLocation);
+    ASSERT_NE(-1, wLocation);
+    glUseProgram(program.get());
+
+    GLBuffer buffer;
+    glBindBuffer(GL_ARRAY_BUFFER, buffer.get());
+    glBufferData(GL_ARRAY_BUFFER, 16, nullptr, GL_STATIC_DRAW);
+
+    glEnableVertexAttribArray(posLocation);
+    glVertexAttribPointer(posLocation, 1, GL_UNSIGNED_BYTE, GL_FALSE, 0, 0);
+    glVertexAttribDivisorANGLE(posLocation, 0);
+
+    glEnableVertexAttribArray(wLocation);
+    glVertexAttribDivisorANGLE(wLocation, 1);
+
+    const uint8_t* zeroOffset = nullptr;
+
+    // Test touching the last element is valid.
+    glVertexAttribPointer(wLocation, 1, GL_UNSIGNED_BYTE, GL_FALSE, 0, zeroOffset + 12);
+    glDrawArraysInstancedANGLE(GL_POINTS, 0, 1, 4);
+    ASSERT_GL_NO_ERROR();
+
+    // Test touching the last element + 1 is invalid.
+    glVertexAttribPointer(wLocation, 1, GL_UNSIGNED_BYTE, GL_FALSE, 0, zeroOffset + 13);
+    glDrawArraysInstancedANGLE(GL_POINTS, 0, 1, 4);
+    EXPECT_GL_ERROR(GL_INVALID_OPERATION);
+
+    // Test touching the last element is valid, using a stride.
+    glVertexAttribPointer(wLocation, 1, GL_UNSIGNED_BYTE, GL_FALSE, 2, zeroOffset + 9);
+    glDrawArraysInstancedANGLE(GL_POINTS, 0, 1, 4);
+    ASSERT_GL_NO_ERROR();
+
+    // Test touching the last element + 1 is invalid, using a stride.
+    glVertexAttribPointer(wLocation, 1, GL_UNSIGNED_BYTE, GL_FALSE, 2, zeroOffset + 10);
+    glDrawArraysInstancedANGLE(GL_POINTS, 0, 1, 4);
+    EXPECT_GL_ERROR(GL_INVALID_OPERATION);
+
+    // Test any offset is valid if no vertices are drawn.
+    glVertexAttribPointer(wLocation, 1, GL_UNSIGNED_BYTE, GL_FALSE, 0, zeroOffset + 32);
+    glDrawArraysInstancedANGLE(GL_POINTS, 0, 0, 1);
+    ASSERT_GL_NO_ERROR();
+
+    // Test any offset is valid if no primitives are drawn.
+    glVertexAttribPointer(wLocation, 1, GL_UNSIGNED_BYTE, GL_FALSE, 0, zeroOffset + 32);
+    glDrawArraysInstancedANGLE(GL_POINTS, 0, 1, 0);
+    ASSERT_GL_NO_ERROR();
 }
 
 // Test the checks for OOB reads in the index buffer
 TEST_P(WebGLCompatibilityTest, DrawElementsBufferOutOfBoundsInIndexBuffer)
 {
     const std::string &vert =
         "attribute float a_pos;\n"
         "void main()\n"
@@ -760,32 +1484,30 @@ TEST_P(WebGLCompatibilityTest, DrawEleme
     const std::string &frag =
         "precision highp float;\n"
         "void main()\n"
         "{\n"
         "    gl_FragColor = vec4(1.0);\n"
         "}\n";
 
     ANGLE_GL_PROGRAM(program, vert, frag);
-
     GLint posLocation = glGetAttribLocation(program.get(), "a_pos");
     ASSERT_NE(-1, posLocation);
     glUseProgram(program.get());
 
     GLBuffer vertexBuffer;
     glBindBuffer(GL_ARRAY_BUFFER, vertexBuffer.get());
     glBufferData(GL_ARRAY_BUFFER, 16, nullptr, GL_STATIC_DRAW);
 
     glEnableVertexAttribArray(posLocation);
+    glVertexAttribPointer(posLocation, 1, GL_UNSIGNED_BYTE, GL_FALSE, 0, nullptr);
 
     const uint8_t *zeroOffset   = nullptr;
     const uint8_t zeroIndices[] = {0, 0, 0, 0, 0, 0, 0, 0};
 
-    glVertexAttribPointer(0, 1, GL_UNSIGNED_BYTE, GL_FALSE, 0, zeroOffset);
-
     GLBuffer indexBuffer;
     glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, indexBuffer.get());
     glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(zeroIndices), zeroIndices, GL_STATIC_DRAW);
     ASSERT_GL_NO_ERROR();
 
     // Test touching the last index is valid
     glDrawElements(GL_POINTS, 4, GL_UNSIGNED_BYTE, zeroOffset + 4);
     ASSERT_GL_NO_ERROR();
@@ -804,16 +1526,70 @@ TEST_P(WebGLCompatibilityTest, DrawEleme
 
     // Test touching the first - 1 index is invalid
     // The error ha been specified to be INVALID_VALUE instead of INVALID_OPERATION because it was
     // the historic behavior of WebGL implementations
     glDrawElements(GL_POINTS, 4, GL_UNSIGNED_BYTE, zeroOffset - 1);
     EXPECT_GL_ERROR(GL_INVALID_VALUE);
 }
 
+// Test the checks for OOB in vertex buffers caused by indices, non-instanced version
+TEST_P(WebGLCompatibilityTest, DrawElementsBufferOutOfBoundsInVertexBuffer)
+{
+    const std::string &vert =
+        "attribute float a_pos;\n"
+        "void main()\n"
+        "{\n"
+        "    gl_Position = vec4(a_pos, a_pos, a_pos, 1.0);\n"
+        "}\n";
+
+    const std::string &frag =
+        "precision highp float;\n"
+        "void main()\n"
+        "{\n"
+        "    gl_FragColor = vec4(1.0);\n"
+        "}\n";
+
+    ANGLE_GL_PROGRAM(program, vert, frag);
+    GLint posLocation = glGetAttribLocation(program.get(), "a_pos");
+    ASSERT_NE(-1, posLocation);
+    glUseProgram(program.get());
+
+    GLBuffer vertexBuffer;
+    glBindBuffer(GL_ARRAY_BUFFER, vertexBuffer.get());
+    glBufferData(GL_ARRAY_BUFFER, 8, nullptr, GL_STATIC_DRAW);
+
+    glEnableVertexAttribArray(posLocation);
+    glVertexAttribPointer(posLocation, 1, GL_UNSIGNED_BYTE, GL_FALSE, 0, nullptr);
+
+    const uint8_t *zeroOffset   = nullptr;
+    const uint8_t testIndices[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 255};
+
+    GLBuffer indexBuffer;
+    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, indexBuffer.get());
+    glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(testIndices), testIndices, GL_STATIC_DRAW);
+    ASSERT_GL_NO_ERROR();
+
+    // Test touching the end of the vertex buffer is valid
+    glDrawElements(GL_POINTS, 1, GL_UNSIGNED_BYTE, zeroOffset + 7);
+    ASSERT_GL_NO_ERROR();
+
+    // Test touching just after the end of the vertex buffer is invalid
+    glDrawElements(GL_POINTS, 1, GL_UNSIGNED_BYTE, zeroOffset + 8);
+    EXPECT_GL_ERROR(GL_INVALID_OPERATION);
+
+    // Test touching the whole vertex buffer is valid
+    glDrawElements(GL_POINTS, 8, GL_UNSIGNED_BYTE, zeroOffset + 0);
+    ASSERT_GL_NO_ERROR();
+
+    // Test an index that would be negative
+    glDrawElements(GL_POINTS, 1, GL_UNSIGNED_BYTE, zeroOffset + 9);
+    EXPECT_GL_ERROR(GL_INVALID_OPERATION);
+}
+
 // Test depth range with 'near' more or less than 'far.'
 TEST_P(WebGLCompatibilityTest, DepthRange)
 {
     glDepthRangef(0, 1);
     ASSERT_GL_NO_ERROR();
 
     glDepthRangef(.5, .5);
     ASSERT_GL_NO_ERROR();
@@ -941,16 +1717,49 @@ TEST_P(WebGLCompatibilityTest, InvalidAt
         GLuint shader = glCreateShader(GL_VERTEX_SHADER);
         glShaderSource(shader, static_cast<GLsizei>(ArraySize(invalidVert)), invalidVert, nullptr);
         EXPECT_GL_ERROR(GL_INVALID_VALUE);
         glDeleteShader(shader);
     }
 }
 
 // Test that line continuation is handled correctly when valdiating shader source
+TEST_P(WebGLCompatibilityTest, ShaderSourceLineContinuation)
+{
+    // Verify that a line continuation character (i.e. backslash) cannot be used
+    // within a preprocessor directive in a ES2 context.
+    ANGLE_SKIP_TEST_IF(getClientMajorVersion() >= 3);
+
+    const char *validVert =
+        "#define foo this is a test\n"
+        "precision mediump float;\n"
+        "void main()\n"
+        "{\n"
+        "    gl_Position = vec4(1.0);\n"
+        "}\n";
+
+    const char *invalidVert =
+        "#define foo this \\n"
+        "  is a test\n"
+        "precision mediump float;\n"
+        "void main()\n"
+        "{\n"
+        "    gl_Position = vec4(1.0);\n"
+        "}\n";
+
+    GLuint shader = glCreateShader(GL_VERTEX_SHADER);
+    glShaderSource(shader, 1, &validVert, nullptr);
+    EXPECT_GL_NO_ERROR();
+
+    glShaderSource(shader, 1, &invalidVert, nullptr);
+    EXPECT_GL_ERROR(GL_INVALID_VALUE);
+    glDeleteShader(shader);
+}
+
+// Test that line continuation is handled correctly when valdiating shader source
 TEST_P(WebGL2CompatibilityTest, ShaderSourceLineContinuation)
 {
     const char *validVert =
         "#version 300 es\n"
         "precision mediump float;\n"
         "\n"
         "void main ()\n"
         "{\n"
@@ -988,83 +1797,16 @@ TEST_P(WebGLCompatibilityTest, BindAttri
 
     EXPECT_GL_ERROR(GL_INVALID_OPERATION);
 
     glBindAttribLocation(0, 0, static_cast<const GLchar *>(tooLongString.c_str()));
 
     EXPECT_GL_ERROR(GL_INVALID_VALUE);
 }
 
-// Test the checks for OOB reads in the vertex buffers, instanced version
-TEST_P(WebGL2CompatibilityTest, DrawArraysBufferOutOfBoundsInstanced)
-{
-    const std::string &vert =
-        "attribute float a_pos;\n"
-        "attribute float a_w;\n"
-        "void main()\n"
-        "{\n"
-        "    gl_Position = vec4(a_pos, a_pos, a_pos, a_w);\n"
-        "}\n";
-
-    const std::string &frag =
-        "precision highp float;\n"
-        "void main()\n"
-        "{\n"
-        "    gl_FragColor = vec4(1.0);\n"
-        "}\n";
-
-    ANGLE_GL_PROGRAM(program, vert, frag);
-
-    GLint posLocation = glGetAttribLocation(program.get(), "a_pos");
-    ASSERT_NE(-1, posLocation);
-
-    GLint wLocation = glGetAttribLocation(program.get(), "a_w");
-    ASSERT_NE(-1, wLocation);
-
-    glUseProgram(program.get());
-
-    GLBuffer buffer;
-    glBindBuffer(GL_ARRAY_BUFFER, buffer.get());
-    glBufferData(GL_ARRAY_BUFFER, 16, nullptr, GL_STATIC_DRAW);
-
-    glEnableVertexAttribArray(posLocation);
-    glVertexAttribDivisor(posLocation, 1);
-
-    glEnableVertexAttribArray(wLocation);
-    glVertexAttribPointer(wLocation, 1, GL_UNSIGNED_BYTE, GL_FALSE, 0, 0);
-    glVertexAttribDivisor(wLocation, 0);
-
-    const uint8_t* zeroOffset = nullptr;
-
-    // Test touching the last element is valid.
-    glVertexAttribPointer(0, 1, GL_UNSIGNED_BYTE, GL_FALSE, 0, zeroOffset + 12);
-    glDrawArraysInstanced(GL_POINTS, 0, 1, 4);
-    ASSERT_GL_NO_ERROR();
-
-    // Test touching the last element + 1 is invalid.
-    glVertexAttribPointer(0, 1, GL_UNSIGNED_BYTE, GL_FALSE, 0, zeroOffset + 13);
-    glDrawArraysInstanced(GL_POINTS, 0, 1, 4);
-    EXPECT_GL_ERROR(GL_INVALID_OPERATION);
-
-    // Test touching the last element is valid, using a stride.
-    glVertexAttribPointer(0, 1, GL_UNSIGNED_BYTE, GL_FALSE, 2, zeroOffset + 9);
-    glDrawArraysInstanced(GL_POINTS, 0, 1, 4);
-    ASSERT_GL_NO_ERROR();
-
-    // Test touching the last element + 1 is invalid, using a stride.
-    glVertexAttribPointer(0, 1, GL_UNSIGNED_BYTE, GL_FALSE, 2, zeroOffset + 10);
-    glDrawArraysInstanced(GL_POINTS, 0, 1, 4);
-    EXPECT_GL_ERROR(GL_INVALID_OPERATION);
-
-    // Test any offset is valid if no vertices are drawn.
-    glVertexAttribPointer(0, 1, GL_UNSIGNED_BYTE, GL_FALSE, 0, zeroOffset + 32);
-    glDrawArraysInstanced(GL_POINTS, 0, 1, 0);
-    ASSERT_GL_NO_ERROR();
-}
-
 // Test that having no attributes with a zero divisor is valid in WebGL2
 TEST_P(WebGL2CompatibilityTest, InstancedDrawZeroDivisor)
 {
     const std::string &vert =
         "attribute float a_pos;\n"
         "void main()\n"
         "{\n"
         "    gl_Position = vec4(a_pos, a_pos, a_pos, 1.0);\n"
@@ -2174,16 +2916,93 @@ TEST_P(WebGLCompatibilityTest, SizedRGBA
         glRequestExtensionANGLE("GL_CHROMIUM_color_buffer_float_rgb");
         ASSERT_GL_NO_ERROR();
 
         glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB32F, 1, 1, 0, GL_RGB, GL_FLOAT, nullptr);
         EXPECT_GL_NO_ERROR();
     }
 }
 
+// Verify GL_DEPTH_STENCIL_ATTACHMENT is a valid attachment point.
+TEST_P(WebGLCompatibilityTest, DepthStencilAttachment)
+{
+    ANGLE_SKIP_TEST_IF(getClientMajorVersion() > 2);
+
+    // Test that attaching a bound texture succeeds.
+    GLTexture texture;
+    glBindTexture(GL_TEXTURE_2D, texture);
+
+    GLFramebuffer fbo;
+    glBindFramebuffer(GL_FRAMEBUFFER, fbo);
+
+    glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_TEXTURE_2D, texture, 0);
+
+    GLint attachmentType = 0;
+    glGetFramebufferAttachmentParameteriv(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT,
+                                          GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE, &attachmentType);
+    EXPECT_GL_NO_ERROR();
+    EXPECT_GLENUM_EQ(GL_TEXTURE, attachmentType);
+
+    // Test when if no attach object at the named attachment point and pname is not OBJECT_TYPE.
+    GLFramebuffer fbo2;
+    glBindFramebuffer(GL_FRAMEBUFFER, fbo2);
+
+    glGetFramebufferAttachmentParameteriv(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT,
+                                          GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME, &attachmentType);
+    EXPECT_GL_ERROR(GL_INVALID_ENUM);
+}
+
+// Verify framebuffer attachments return expected types when in an inconsistant state.
+TEST_P(WebGLCompatibilityTest, FramebufferAttachmentConsistancy)
+{
+    ANGLE_SKIP_TEST_IF(getClientMajorVersion() > 2);
+
+    GLFramebuffer fbo;
+    glBindFramebuffer(GL_FRAMEBUFFER, fbo);
+
+    GLRenderbuffer rb1;
+    glBindRenderbuffer(GL_RENDERBUFFER, rb1);
+
+    glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, rb1);
+
+    GLint attachmentType = 0;
+    glGetFramebufferAttachmentParameteriv(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT,
+                                          GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE, &attachmentType);
+
+    EXPECT_GL_NO_ERROR();
+    EXPECT_GLENUM_EQ(GL_RENDERBUFFER, attachmentType);
+
+    GLRenderbuffer rb2;
+    glBindRenderbuffer(GL_RENDERBUFFER, rb2);
+
+    glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_RENDERBUFFER, rb2);
+
+    glGetFramebufferAttachmentParameteriv(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT,
+                                          GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE, &attachmentType);
+
+    EXPECT_GL_NO_ERROR();
+    EXPECT_GLENUM_EQ(GL_RENDERBUFFER, attachmentType);
+
+    glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, rb2);
+
+    glGetFramebufferAttachmentParameteriv(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT,
+                                          GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE, &attachmentType);
+
+    EXPECT_GL_NO_ERROR();
+    EXPECT_GLENUM_EQ(GL_RENDERBUFFER, attachmentType);
+
+    glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, rb2);
+
+    glGetFramebufferAttachmentParameteriv(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT,
+                                          GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE, &attachmentType);
+
+    EXPECT_GL_NO_ERROR();
+    EXPECT_GLENUM_EQ(GL_RENDERBUFFER, attachmentType);
+}
+
 // This tests that rendering feedback loops works as expected with WebGL 2.
 // Based on WebGL test conformance2/rendering/rendering-sampling-feedback-loop.html
 TEST_P(WebGL2CompatibilityTest, RenderingFeedbackLoopWithDrawBuffers)
 {
     const std::string vertexShader =
         "#version 300 es\n"
         "in vec4 aPosition;\n"
         "out vec2 texCoord;\n"
@@ -2665,17 +3484,17 @@ TEST_P(WebGL2CompatibilityTest, Fragment
     glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0 + intLocation, GL_RENDERBUFFER,
                               intRenderbuffer);
     glDrawArrays(GL_TRIANGLES, 0, 6);
     EXPECT_GL_ERROR(GL_INVALID_OPERATION);
 }
 
 // Verify that errors are generated when the vertex shader intput doesn't match the bound attribute
 // types
-TEST_P(WebGL2CompatibilityTest, VertexShaderAttributeTypeMissmatch)
+TEST_P(WebGL2CompatibilityTest, VertexShaderAttributeTypeMismatch)
 {
     const std::string vertexShader =
         "#version 300 es\n"
         "in vec4 floatInput;\n"
         "in uvec4 uintInput;\n"
         "in ivec4 intInput;\n"
         "void main() {\n"
         "    gl_Position = vec4(floatInput.x, uintInput.x, intInput.x, 1);\n"
@@ -2727,16 +3546,39 @@ TEST_P(WebGL2CompatibilityTest, VertexSh
     EXPECT_GL_ERROR(GL_INVALID_OPERATION);
 
     // Use a uint pointer for the uint input
     glVertexAttribIPointer(uintLocation, 4, GL_UNSIGNED_INT, 0, nullptr);
     glDrawArrays(GL_TRIANGLES, 0, 6);
     EXPECT_GL_NO_ERROR();
 }
 
+// Test that it's not possible to query the non-zero color attachments without the drawbuffers
+// extension in WebGL1
+TEST_P(WebGLCompatibilityTest, FramebufferAttachmentQuery)
+{
+    ANGLE_SKIP_TEST_IF(getClientMajorVersion() > 2);
+    ANGLE_SKIP_TEST_IF(extensionEnabled("GL_EXT_draw_buffers"));
+
+    GLFramebuffer fbo;
+    glBindFramebuffer(GL_FRAMEBUFFER, fbo);
+    EXPECT_GL_NO_ERROR();
+
+    GLint result;
+    glGetFramebufferAttachmentParameteriv(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT1,
+                                          GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE, &result);
+    EXPECT_GL_ERROR(GL_INVALID_ENUM);
+
+    GLRenderbuffer renderbuffer;
+    glBindRenderbuffer(GL_RENDERBUFFER, renderbuffer);
+    glRenderbufferStorage(GL_RENDERBUFFER, GL_RGBA4, 1, 1);
+    glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT1, GL_RENDERBUFFER, renderbuffer);
+    EXPECT_GL_ERROR(GL_INVALID_ENUM);
+}
+
 // Tests the WebGL removal of undefined behavior when attachments aren't written to.
 TEST_P(WebGLCompatibilityTest, DrawBuffers)
 {
     // Make sure we can use at least 4 attachments for the tests.
     bool useEXT = false;
     if (getClientMajorVersion() < 3)
     {
         if (!extensionRequestable("GL_EXT_draw_buffers"))
@@ -2756,39 +3598,39 @@ TEST_P(WebGLCompatibilityTest, DrawBuffe
     {
         std::cout << "Test skipped because MAX_DRAW_BUFFERS is too small." << std::endl;
         return;
     }
 
     // Clears all the renderbuffers to red.
     auto ClearEverythingToRed = [](GLRenderbuffer *renderbuffers) {
         GLFramebuffer clearFBO;
-        glBindFramebuffer(GL_DRAW_FRAMEBUFFER, clearFBO);
+        glBindFramebuffer(GL_FRAMEBUFFER, clearFBO);
 
         glClearColor(1, 0, 0, 1);
         for (int i = 0; i < 4; ++i)
         {
-            glFramebufferRenderbuffer(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER,
+            glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER,
                                       renderbuffers[i]);
             glClear(GL_COLOR_BUFFER_BIT);
         }
         ASSERT_GL_NO_ERROR();
     };
 
     // Checks that the renderbuffers specified by mask have the correct color
     auto CheckColors = [](GLRenderbuffer *renderbuffers, int mask, GLColor color) {
         GLFramebuffer readFBO;
-        glBindFramebuffer(GL_READ_FRAMEBUFFER, readFBO);
+        glBindFramebuffer(GL_FRAMEBUFFER, readFBO);
 
         for (int i = 0; i < 4; ++i)
         {
             if (mask & (1 << i))
             {
-                glFramebufferRenderbuffer(GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
-                                          GL_RENDERBUFFER, renderbuffers[i]);
+                glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER,
+                                          renderbuffers[i]);
                 EXPECT_PIXEL_COLOR_EQ(0, 0, color);
             }
         }
         ASSERT_GL_NO_ERROR();
     };
 
     // Depending on whether we are using the extension or ES3, a different entrypoint must be called
     auto DrawBuffers = [](bool useEXT, int numBuffers, GLenum *buffers) {
@@ -2799,24 +3641,24 @@ TEST_P(WebGLCompatibilityTest, DrawBuffe
         else
         {
             glDrawBuffers(numBuffers, buffers);
         }
     };
 
     // Initialized the test framebuffer
     GLFramebuffer drawFBO;
-    glBindFramebuffer(GL_DRAW_FRAMEBUFFER, drawFBO);
+    glBindFramebuffer(GL_FRAMEBUFFER, drawFBO);
 
     GLRenderbuffer renderbuffers[4];
     for (int i = 0; i < 4; ++i)
     {
         glBindRenderbuffer(GL_RENDERBUFFER, renderbuffers[i]);
-        glRenderbufferStorage(GL_RENDERBUFFER, GL_RGBA8, 1, 1);
-        glFramebufferRenderbuffer(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0 + i, GL_RENDERBUFFER,
+        glRenderbufferStorage(GL_RENDERBUFFER, GL_RGBA4, 1, 1);
+        glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0 + i, GL_RENDERBUFFER,
                                   renderbuffers[i]);
     }
 
     ASSERT_GL_NO_ERROR();
 
     const char *vertESSL1 =
         "attribute vec4 a_pos;\n"
         "void main()\n"
@@ -2846,31 +3688,31 @@ TEST_P(WebGLCompatibilityTest, DrawBuffe
         "{\n"
         "    gl_FragColor = vec4(0.0, 1.0, 0.0, 1.0);\n"
         "}\n";
     ANGLE_GL_PROGRAM(programESSL1, vertESSL1, fragESSL1);
 
     {
         ClearEverythingToRed(renderbuffers);
 
-        glBindFramebuffer(GL_DRAW_FRAMEBUFFER, drawFBO);
+        glBindFramebuffer(GL_FRAMEBUFFER, drawFBO);
         DrawBuffers(useEXT, 4, allDrawBuffers);
         drawQuad(programESSL1, "a_pos", 0.5, 1.0, true);
         ASSERT_GL_NO_ERROR();
 
         CheckColors(renderbuffers, 0b0001, GLColor::green);
         CheckColors(renderbuffers, 0b1110, GLColor::red);
     }
 
     // Test that when using gl_FragColor, but the first draw buffer is 0, then no attachment is
     // written to.
     {
         ClearEverythingToRed(renderbuffers);
 
-        glBindFramebuffer(GL_DRAW_FRAMEBUFFER, drawFBO);
+        glBindFramebuffer(GL_FRAMEBUFFER, drawFBO);
         DrawBuffers(useEXT, 4, halfDrawBuffers);
         drawQuad(programESSL1, "a_pos", 0.5, 1.0, true);
         ASSERT_GL_NO_ERROR();
 
         CheckColors(renderbuffers, 0b1111, GLColor::red);
     }
 
     // Test what happens when rendering to a subset of the outputs. There is a behavior difference
@@ -2913,41 +3755,274 @@ TEST_P(WebGLCompatibilityTest, DrawBuffe
             "}\n";
     }
     ANGLE_GL_PROGRAM(writeOddOutputsProgram, writeOddOutputsVert, writeOddOutputsFrag);
 
     // Test that attachments not written to get the "unwritten" color
     {
         ClearEverythingToRed(renderbuffers);
 
-        glBindFramebuffer(GL_DRAW_FRAMEBUFFER, drawFBO);
+        glBindFramebuffer(GL_FRAMEBUFFER, drawFBO);
         DrawBuffers(useEXT, 4, allDrawBuffers);
         drawQuad(writeOddOutputsProgram, "a_pos", 0.5, 1.0, true);
         ASSERT_GL_NO_ERROR();
 
         CheckColors(renderbuffers, 0b1010, GLColor::green);
         CheckColors(renderbuffers, 0b0101, unwrittenColor);
     }
 
     // Test that attachments not written to get the "unwritten" color but that even when the
     // extension is used, disabled attachments are not written at all and stay red.
     {
         ClearEverythingToRed(renderbuffers);
 
-        glBindFramebuffer(GL_DRAW_FRAMEBUFFER, drawFBO);
+        glBindFramebuffer(GL_FRAMEBUFFER, drawFBO);
         DrawBuffers(useEXT, 4, halfDrawBuffers);
         drawQuad(writeOddOutputsProgram, "a_pos", 0.5, 1.0, true);
         ASSERT_GL_NO_ERROR();
 
         CheckColors(renderbuffers, 0b1000, GLColor::green);
         CheckColors(renderbuffers, 0b0100, unwrittenColor);
         CheckColors(renderbuffers, 0b0011, GLColor::red);
     }
 }
 
+// Test that it's possible to generate mipmaps on unsized floating point textures once the
+// extensions have been enabled
+TEST_P(WebGLCompatibilityTest, GenerateMipmapUnsizedFloatingPointTexture)
+{
+    if (extensionRequestable("GL_OES_texture_float"))
+    {
+        glRequestExtensionANGLE("GL_OES_texture_float");
+    }
+    ANGLE_SKIP_TEST_IF(!extensionEnabled("GL_OES_texture_float"));
+
+    GLTexture texture;
+    glBindTexture(GL_TEXTURE_2D, texture);
+
+    constexpr GLColor32F data[4] = {
+        kFloatRed, kFloatRed, kFloatGreen, kFloatBlue,
+    };
+    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 4, 4, 0, GL_RGBA, GL_FLOAT, data);
+    ASSERT_GL_NO_ERROR();
+
+    glGenerateMipmap(GL_TEXTURE_2D);
+    EXPECT_GL_NO_ERROR();
+}
+// Test that it's possible to generate mipmaps on unsized floating point textures once the
+// extensions have been enabled
+TEST_P(WebGLCompatibilityTest, GenerateMipmapSizedFloatingPointTexture)
+{
+    if (extensionRequestable("GL_OES_texture_float"))
+    {
+        glRequestExtensionANGLE("GL_OES_texture_float");
+    }
+    ANGLE_SKIP_TEST_IF(!extensionEnabled("GL_OES_texture_float"));
+
+    if (extensionRequestable("GL_EXT_texture_storage"))
+    {
+        glRequestExtensionANGLE("GL_EXT_texture_storage");
+    }
+    ANGLE_SKIP_TEST_IF(!extensionEnabled("GL_EXT_texture_storage"));
+
+    GLTexture texture;
+    glBindTexture(GL_TEXTURE_2D, texture);
+
+    constexpr GLColor32F data[4] = {
+        kFloatRed, kFloatRed, kFloatGreen, kFloatBlue,
+    };
+    glTexStorage2DEXT(GL_TEXTURE_2D, 2, GL_RGBA32F, 2, 2);
+    glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 2, 2, GL_RGBA, GL_FLOAT, data);
+    ASSERT_GL_NO_ERROR();
+
+    glGenerateMipmap(GL_TEXTURE_2D);
+    EXPECT_GL_ERROR(GL_INVALID_OPERATION);
+
+    if (extensionRequestable("GL_EXT_color_buffer_float"))
+    {
+        // Format is renderable but not filterable
+        glRequestExtensionANGLE("GL_EXT_color_buffer_float");
+        glGenerateMipmap(GL_TEXTURE_2D);
+        EXPECT_GL_ERROR(GL_INVALID_OPERATION);
+    }
+
+    if (extensionRequestable("GL_EXT_color_buffer_float_linear"))
+    {
+        // Format is renderable but not filterable
+        glRequestExtensionANGLE("GL_EXT_color_buffer_float_linear");
+
+        if (extensionEnabled("GL_EXT_color_buffer_float"))
+        {
+            // Format is filterable and renderable
+            glGenerateMipmap(GL_TEXTURE_2D);
+            EXPECT_GL_NO_ERROR();
+        }
+        else
+        {
+            // Format is filterable but not renderable
+            glGenerateMipmap(GL_TEXTURE_2D);
+            EXPECT_GL_ERROR(GL_INVALID_OPERATION);
+        }
+    }
+}
+
+// Verify that a texture format is only allowed with extension enabled.
+void WebGLCompatibilityTest::validateTexImageExtensionFormat(GLenum format,
+                                                             const std::string &extName)
+{
+    // Verify texture format fails by default.
+    glTexImage2D(GL_TEXTURE_2D, 0, format, 1, 1, 0, format, GL_UNSIGNED_BYTE, nullptr);
+    EXPECT_GL_ERROR(GL_INVALID_ENUM);
+
+    if (extensionRequestable(extName))
+    {
+        // Verify texture format is allowed once extension is enabled.
+        glRequestExtensionANGLE(extName.c_str());
+        EXPECT_TRUE(extensionEnabled(extName));
+
+        glTexImage2D(GL_TEXTURE_2D, 0, format, 1, 1, 0, format, GL_UNSIGNED_BYTE, nullptr);
+        ASSERT_GL_NO_ERROR();
+    }
+}
+
+// Test enabling various non-compressed texture format extensions
+TEST_P(WebGLCompatibilityTest, EnableTextureFormatExtensions)
+{
+    ANGLE_SKIP_TEST_IF(IsOzone());
+    ANGLE_SKIP_TEST_IF(getClientMajorVersion() != 2);
+
+    GLTexture texture;
+    glBindTexture(GL_TEXTURE_2D, texture.get());
+
+    // Verify valid format is allowed.
+    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
+    ASSERT_GL_NO_ERROR();
+
+    // Verify invalid format fails.
+    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA32F, 1, 1, 0, GL_RGBA32F, GL_UNSIGNED_BYTE, nullptr);
+    EXPECT_GL_ERROR(GL_INVALID_ENUM);
+
+    // Verify formats from enableable extensions.
+    if (!IsOpenGLES())
+    {
+        validateTexImageExtensionFormat(GL_RED_EXT, "GL_EXT_texture_rg");
+    }
+
+    validateTexImageExtensionFormat(GL_SRGB_EXT, "GL_EXT_texture_sRGB");
+    validateTexImageExtensionFormat(GL_BGRA_EXT, "GL_EXT_texture_format_BGRA8888");
+}
+
+void WebGLCompatibilityTest::validateCompressedTexImageExtensionFormat(GLenum format,
+                                                                       GLsizei width,
+                                                                       GLsizei height,
+                                                                       GLsizei blockSize,
+                                                                       const std::string &extName,
+                                                                       bool subImageAllowed)
+{
+    std::vector<GLubyte> data(blockSize, 0u);
+
+    GLTexture texture;
+    glBindTexture(GL_TEXTURE_2D, texture.get());
+
+    // Verify texture format fails by default.
+    glCompressedTexImage2D(GL_TEXTURE_2D, 0, format, width, height, 0, blockSize, data.data());
+    EXPECT_GL_ERROR(GL_INVALID_ENUM);
+
+    if (extensionRequestable(extName))
+    {
+        // Verify texture format is allowed once extension is enabled.
+        glRequestExtensionANGLE(extName.c_str());
+        EXPECT_TRUE(extensionEnabled(extName));
+
+        glCompressedTexImage2D(GL_TEXTURE_2D, 0, format, width, height, 0, blockSize, data.data());
+        EXPECT_GL_NO_ERROR();
+
+        glCompressedTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, width, height, format, blockSize,
+                                  data.data());
+        if (subImageAllowed)
+        {
+            EXPECT_GL_NO_ERROR();
+        }
+        else
+        {
+            EXPECT_GL_ERROR(GL_INVALID_OPERATION);
+        }
+    }
+}
+
+// Test enabling GL_EXT_texture_compression_dxt1 for GL_COMPRESSED_RGB_S3TC_DXT1_EXT
+TEST_P(WebGLCompatibilityTest, EnableCompressedTextureExtensionDXT1RGB)
+{
+    validateCompressedTexImageExtensionFormat(GL_COMPRESSED_RGB_S3TC_DXT1_EXT, 4, 4, 8,
+                                              "GL_EXT_texture_compression_dxt1", true);
+}
+
+// Test enabling GL_EXT_texture_compression_dxt1 for GL_COMPRESSED_RGBA_S3TC_DXT1_EXT
+TEST_P(WebGLCompatibilityTest, EnableCompressedTextureExtensionDXT1RGBA)
+{
+    validateCompressedTexImageExtensionFormat(GL_COMPRESSED_RGBA_S3TC_DXT1_EXT, 4, 4, 8,
+                                              "GL_EXT_texture_compression_dxt1", true);
+}
+
+// Test enabling GL_ANGLE_texture_compression_dxt3
+TEST_P(WebGLCompatibilityTest, EnableCompressedTextureExtensionDXT3)
+{
+    validateCompressedTexImageExtensionFormat(GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE, 4, 4, 16,
+                                              "GL_ANGLE_texture_compression_dxt3", true);
+}
+
+// Test enabling GL_ANGLE_texture_compression_dxt5
+TEST_P(WebGLCompatibilityTest, EnableCompressedTextureExtensionDXT5)
+{
+    validateCompressedTexImageExtensionFormat(GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE, 4, 4, 16,
+                                              "GL_ANGLE_texture_compression_dxt5", true);
+}
+
+// Test enabling GL_EXT_texture_compression_s3tc_srgb for GL_COMPRESSED_SRGB_S3TC_DXT1_EXT
+TEST_P(WebGLCompatibilityTest, EnableCompressedTextureExtensionDXT1SRGB)
+{
+    validateCompressedTexImageExtensionFormat(GL_COMPRESSED_SRGB_S3TC_DXT1_EXT, 4, 4, 8,
+                                              "GL_EXT_texture_compression_s3tc_srgb", true);
+}
+
+// Test enabling GL_EXT_texture_compression_s3tc_srgb for GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT
+TEST_P(WebGLCompatibilityTest, EnableCompressedTextureExtensionDXT1SRGBA)
+{
+    validateCompressedTexImageExtensionFormat(GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT, 4, 4, 8,
+                                              "GL_EXT_texture_compression_s3tc_srgb", true);
+}
+
+// Test enabling GL_EXT_texture_compression_s3tc_srgb for GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT
+TEST_P(WebGLCompatibilityTest, EnableCompressedTextureExtensionDXT3SRGBA)
+{
+    validateCompressedTexImageExtensionFormat(GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT, 4, 4, 16,
+                                              "GL_EXT_texture_compression_s3tc_srgb", true);
+}
+
+// Test enabling GL_EXT_texture_compression_s3tc_srgb for GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT
+TEST_P(WebGLCompatibilityTest, EnableCompressedTextureExtensionDXT5SRGBA)
+{
+    validateCompressedTexImageExtensionFormat(GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT, 4, 4, 16,
+                                              "GL_EXT_texture_compression_s3tc_srgb", true);
+}
+
+// Test enabling GL_OES_compressed_ETC1_RGB8_texture
+TEST_P(WebGLCompatibilityTest, EnableCompressedTextureExtensionETC1)
+{
+    validateCompressedTexImageExtensionFormat(GL_ETC1_RGB8_OES, 4, 4, 8,
+                                              "GL_OES_compressed_ETC1_RGB8_texture", false);
+}
+
+// Test enabling GL_ANGLE_lossy_etc_decode
+TEST_P(WebGLCompatibilityTest, EnableCompressedTextureExtensionLossyDecode)
+{
+    validateCompressedTexImageExtensionFormat(GL_ETC1_RGB8_LOSSY_DECODE_ANGLE, 4, 4, 8,
+                                              "GL_ANGLE_lossy_etc_decode", true);
+}
+
 // Linking should fail when corresponding vertex/fragment uniform blocks have different precision
 // qualifiers.
 TEST_P(WebGL2CompatibilityTest, UniformBlockPrecisionMismatch)
 {
     const std::string vertexShader =
         "#version 300 es\n"
         "uniform Block { mediump vec4 val; };\n"
         "void main() { gl_Position = val; }\n";
--- a/gfx/angle/src/tests/gl_tests/WebGLFramebufferTest.cpp
+++ b/gfx/angle/src/tests/gl_tests/WebGLFramebufferTest.cpp
@@ -348,19 +348,23 @@ void WebGLFramebufferTest::testDepthSten
     GLRenderbuffer depthStencilBuffer;
     glBindRenderbuffer(GL_RENDERBUFFER, depthStencilBuffer);
     glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_STENCIL, width, height);
     EXPECT_GL_NO_ERROR();
 
     // OpenGL itself doesn't seem to guarantee that e.g. a 2 x 0
     // renderbuffer will report 2 for its width when queried.
     if (!(height == 0 && width > 0))
+    {
         EXPECT_EQ(width, getRenderbufferParameter(GL_RENDERBUFFER_WIDTH));
+    }
     if (!(width == 0 && height > 0))
+    {
         EXPECT_EQ(height, getRenderbufferParameter(GL_RENDERBUFFER_HEIGHT));
+    }
     EXPECT_EQ(GL_DEPTH_STENCIL, getRenderbufferParameter(GL_RENDERBUFFER_INTERNAL_FORMAT));
     EXPECT_EQ(0, getRenderbufferParameter(GL_RENDERBUFFER_RED_SIZE));
     EXPECT_EQ(0, getRenderbufferParameter(GL_RENDERBUFFER_GREEN_SIZE));
     EXPECT_EQ(0, getRenderbufferParameter(GL_RENDERBUFFER_BLUE_SIZE));
     EXPECT_EQ(0, getRenderbufferParameter(GL_RENDERBUFFER_ALPHA_SIZE));
 
     // Avoid verifying these for zero-sized renderbuffers for the time
     // being since it appears that even OpenGL doesn't guarantee them.
--- a/gfx/angle/src/tests/gl_tests/WebGLReadOutsideFramebufferTest.cpp
+++ b/gfx/angle/src/tests/gl_tests/WebGLReadOutsideFramebufferTest.cpp
@@ -354,23 +354,16 @@ TEST_P(WebGLReadOutsideFramebufferTest, 
 {
     Main2D(&WebGLReadOutsideFramebufferTest::TestReadPixels, false);
 }
 
 // Check that copyTexSubImage2D does not set a destination pixel when
 // the corresponding source pixel is outside the framebuffer.
 TEST_P(WebGLReadOutsideFramebufferTest, CopyTexSubImage2D)
 {
-    // TODO(fjhenigman): Figure out why this fails on Win10 Intel OpenGL
-    if (IsWindows() && IsIntel() && IsDesktopOpenGL())
-    {
-        std::cout << "Test skipped on Windows OpenGL on Intel." << std::endl;
-        return;
-    }
-
     Main2D(&WebGLReadOutsideFramebufferTest::TestCopyTexSubImage2D, false);
 
 #ifdef _WIN64
     // TODO(fjhenigman): Figure out this failure.
     if (GetParam() == ES2_D3D11_FL9_3())
     {
         std::cout << "Cube map skipped on 64-bit " << GetParam() << "." << std::endl;
         return;
@@ -378,23 +371,16 @@ TEST_P(WebGLReadOutsideFramebufferTest, 
 #endif
 
     Main2D(&WebGLReadOutsideFramebufferTest::TestCopyTexSubImageCube, false);
 }
 
 // Check that copyTexImage2D sets (0,0,0,0) for pixels outside the framebuffer.
 TEST_P(WebGLReadOutsideFramebufferTest, CopyTexImage2D)
 {
-    // TODO(fjhenigman): Figure out why this fails on Win10 Intel OpenGL
-    if (IsWindows() && IsIntel() && IsDesktopOpenGL())
-    {
-        std::cout << "Test skipped on Windows OpenGL on Intel." << std::endl;
-        return;
-    }
-
     Main2D(&WebGLReadOutsideFramebufferTest::TestCopyTexImage2D, true);
 
 #ifdef _WIN64
     // TODO(fjhenigman): Figure out this failure.
     if (GetParam() == ES2_D3D11_FL9_3())
     {
         std::cout << "Cube map skipped on 64-bit " << GetParam() << "." << std::endl;
         return;
--- a/gfx/angle/src/tests/perf_tests/ANGLEPerfTest.cpp
+++ b/gfx/angle/src/tests/perf_tests/ANGLEPerfTest.cpp
@@ -118,45 +118,44 @@ std::string RenderTestParams::suffix() c
             assert(0);
             return "_unk";
     }
 }
 
 ANGLERenderTest::ANGLERenderTest(const std::string &name, const RenderTestParams &testParams)
     : ANGLEPerfTest(name, testParams.suffix()),
       mTestParams(testParams),
-      mEGLWindow(nullptr),
+      mEGLWindow(createEGLWindow(testParams)),
       mOSWindow(nullptr)
 {
 }
 
 ANGLERenderTest::ANGLERenderTest(const std::string &name,
                                  const RenderTestParams &testParams,
                                  const std::vector<std::string> &extensionPrerequisites)
     : ANGLEPerfTest(name, testParams.suffix()),
       mTestParams(testParams),
-      mEGLWindow(nullptr),
+      mEGLWindow(createEGLWindow(testParams)),
       mOSWindow(nullptr),
       mExtensionPrerequisites(extensionPrerequisites)
 {
 }
 
 ANGLERenderTest::~ANGLERenderTest()
 {
     SafeDelete(mOSWindow);
     SafeDelete(mEGLWindow);
 }
 
 void ANGLERenderTest::SetUp()
 {
     ANGLEPerfTest::SetUp();
 
     mOSWindow = CreateOSWindow();
-    mEGLWindow = new EGLWindow(mTestParams.majorVersion, mTestParams.minorVersion,
-                               mTestParams.eglParameters);
+    ASSERT(mEGLWindow != nullptr);
     mEGLWindow->setSwapInterval(0);
 
     mPlatformMethods.overrideWorkaroundsD3D = OverrideWorkaroundsD3D;
     mPlatformMethods.logError               = EmptyPlatformMethod;
     mPlatformMethods.logWarning             = EmptyPlatformMethod;
     mPlatformMethods.logInfo                = EmptyPlatformMethod;
     mPlatformMethods.context                = this;
     mEGLWindow->setPlatformMethods(&mPlatformMethods);
@@ -253,9 +252,26 @@ bool ANGLERenderTest::areExtensionPrereq
     {
         if (!CheckExtensionExists(reinterpret_cast<const char *>(glGetString(GL_EXTENSIONS)),
                                   extension))
         {
             return false;
         }
     }
     return true;
-}
\ No newline at end of file
+}
+
+void ANGLERenderTest::setWebGLCompatibilityEnabled(bool webglCompatibility)
+{
+    mEGLWindow->setWebGLCompatibilityEnabled(webglCompatibility);
+}
+
+void ANGLERenderTest::setRobustResourceInit(bool enabled)
+{
+    mEGLWindow->setRobustResourceInit(enabled);
+}
+
+// static
+EGLWindow *ANGLERenderTest::createEGLWindow(const RenderTestParams &testParams)
+{
+    return new EGLWindow(testParams.majorVersion, testParams.minorVersion,
+                         testParams.eglParameters);
+}
--- a/gfx/angle/src/tests/perf_tests/ANGLEPerfTest.h
+++ b/gfx/angle/src/tests/perf_tests/ANGLEPerfTest.h
@@ -73,18 +73,18 @@ class ANGLEPerfTest : public testing::Te
     unsigned int mNumStepsPerformed;
     bool mRunning;
 };
 
 struct RenderTestParams : public angle::PlatformParameters
 {
     virtual std::string suffix() const;
 
-    EGLint windowWidth;
-    EGLint windowHeight;
+    EGLint windowWidth  = 64;
+    EGLint windowHeight = 64;
 };
 
 class ANGLERenderTest : public ANGLEPerfTest
 {
   public:
     ANGLERenderTest(const std::string &name, const RenderTestParams &testParams);
     ANGLERenderTest(const std::string &name,
                     const RenderTestParams &testParams,
@@ -100,25 +100,30 @@ class ANGLERenderTest : public ANGLEPerf
 
     OSWindow *getWindow();
 
     virtual void overrideWorkaroundsD3D(angle::WorkaroundsD3D *workaroundsD3D) {}
 
   protected:
     const RenderTestParams &mTestParams;
 
+    void setWebGLCompatibilityEnabled(bool webglCompatibility);
+    void setRobustResourceInit(bool enabled);
+
   private:
     void SetUp() override;
     void TearDown() override;
 
     void step() override;
     void finishTest() override;
 
     bool areExtensionPrerequisitesFulfilled() const;
 
+    static EGLWindow *createEGLWindow(const RenderTestParams &testParams);
+
     EGLWindow *mEGLWindow;
     OSWindow *mOSWindow;
     std::vector<std::string> mExtensionPrerequisites;
     angle::PlatformMethods mPlatformMethods;
 };
 
 extern bool g_OnlyOneRunFrame;
 
--- a/gfx/angle/src/tests/perf_tests/BindingPerf.cpp
+++ b/gfx/angle/src/tests/perf_tests/BindingPerf.cpp
@@ -179,30 +179,30 @@ BindingsParams D3D11Params(AllocationSty
 BindingsParams D3D9Params(AllocationStyle allocationStyle)
 {
     BindingsParams params;
     params.eglParameters   = egl_platform::D3D9_NULL();
     params.allocationStyle = allocationStyle;
     return params;
 }
 
-BindingsParams OpenGLParams(AllocationStyle allocationStyle)
+BindingsParams OpenGLOrGLESParams(AllocationStyle allocationStyle)
 {
     BindingsParams params;
-    params.eglParameters   = egl_platform::OPENGL_NULL();
+    params.eglParameters   = egl_platform::OPENGL_OR_GLES(true);
     params.allocationStyle = allocationStyle;
     return params;
 }
 
 TEST_P(BindingsBenchmark, Run)
 {
     run();
 }
 
 ANGLE_INSTANTIATE_TEST(BindingsBenchmark,
                        D3D11Params(EVERY_ITERATION),
                        D3D11Params(AT_INITIALIZATION),
                        D3D9Params(EVERY_ITERATION),
                        D3D9Params(AT_INITIALIZATION),
-                       OpenGLParams(EVERY_ITERATION),
-                       OpenGLParams(AT_INITIALIZATION));
+                       OpenGLOrGLESParams(EVERY_ITERATION),
+                       OpenGLOrGLESParams(AT_INITIALIZATION));
 
 }  // namespace angle
--- a/gfx/angle/src/tests/perf_tests/BitSetIteratorPerf.cpp
+++ b/gfx/angle/src/tests/perf_tests/BitSetIteratorPerf.cpp
@@ -44,21 +44,21 @@ void BitSetIteratorPerfTest<T>::step()
     {
         UNUSED_VARIABLE(bit);
     }
 
     mBits.reset();
 }
 
 // These type names unfortunately don't get printed correctly in Gtest.
-#if defined(ANGLE_X64_CPU)
+#if defined(ANGLE_IS_64_BIT_CPU)
 using TestTypes = Types<angle::IterableBitSet<32>, angle::BitSet32<32>, angle::BitSet64<32>>;
 #else
 using TestTypes = Types<angle::IterableBitSet<32>, angle::BitSet32<32>>;
-#endif  // defined(ANGLE_X64_CPU)
+#endif  // defined(ANGLE_IS_64_BIT_CPU)
 TYPED_TEST_CASE(BitSetIteratorPerfTest, TestTypes);
 
 TYPED_TEST(BitSetIteratorPerfTest, Run)
 {
     this->run();
 }
 
 }  // anonymous namespace
--- a/gfx/angle/src/tests/perf_tests/BufferSubData.cpp
+++ b/gfx/angle/src/tests/perf_tests/BufferSubData.cpp
@@ -363,28 +363,29 @@ BufferSubDataParams BufferUpdateD3D9Para
     BufferSubDataParams params;
     params.eglParameters = egl_platform::D3D9();
     params.vertexType = GL_FLOAT;
     params.vertexComponentCount = 4;
     params.vertexNormalized = GL_FALSE;
     return params;
 }
 
-BufferSubDataParams BufferUpdateOpenGLParams()
+BufferSubDataParams BufferUpdateOpenGLOrGLESParams()
 {
     BufferSubDataParams params;
-    params.eglParameters = egl_platform::OPENGL();
+    params.eglParameters        = egl_platform::OPENGL_OR_GLES(false);
     params.vertexType = GL_FLOAT;
     params.vertexComponentCount = 4;
     params.vertexNormalized = GL_FALSE;
     return params;
 }
 
 TEST_P(BufferSubDataBenchmark, Run)
 {
     run();
 }
 
 ANGLE_INSTANTIATE_TEST(BufferSubDataBenchmark,
-                       BufferUpdateD3D11Params(), BufferUpdateD3D9Params(),
-                       BufferUpdateOpenGLParams());
+                       BufferUpdateD3D11Params(),
+                       BufferUpdateD3D9Params(),
+                       BufferUpdateOpenGLOrGLESParams());
 
 } // namespace
--- a/gfx/angle/src/tests/perf_tests/DrawCallPerf.cpp
+++ b/gfx/angle/src/tests/perf_tests/DrawCallPerf.cpp
@@ -101,15 +101,15 @@ TEST_P(DrawCallPerfBenchmark, Run)
 }
 
 ANGLE_INSTANTIATE_TEST(DrawCallPerfBenchmark,
                        DrawCallPerfD3D9Params(false, false),
                        DrawCallPerfD3D9Params(true, false),
                        DrawCallPerfD3D11Params(false, false),
                        DrawCallPerfD3D11Params(true, false),
                        DrawCallPerfD3D11Params(true, true),
-                       DrawCallPerfOpenGLParams(false, false),
-                       DrawCallPerfOpenGLParams(true, false),
-                       DrawCallPerfOpenGLParams(true, true),
+                       DrawCallPerfOpenGLOrGLESParams(false, false),
+                       DrawCallPerfOpenGLOrGLESParams(true, false),
+                       DrawCallPerfOpenGLOrGLESParams(true, true),
                        DrawCallPerfValidationOnly(),
                        DrawCallPerfVulkanParams(false));
 
 } // namespace
--- a/gfx/angle/src/tests/perf_tests/DrawCallPerfParams.cpp
+++ b/gfx/angle/src/tests/perf_tests/DrawCallPerfParams.cpp
@@ -54,20 +54,20 @@ DrawCallPerfParams DrawCallPerfD3D11Para
 DrawCallPerfParams DrawCallPerfD3D9Params(bool useNullDevice, bool renderToTexture)
 {
     DrawCallPerfParams params;
     params.eglParameters = useNullDevice ? D3D9_NULL() : D3D9();
     params.useFBO        = renderToTexture;
     return params;
 }
 
-DrawCallPerfParams DrawCallPerfOpenGLParams(bool useNullDevice, bool renderToTexture)
+DrawCallPerfParams DrawCallPerfOpenGLOrGLESParams(bool useNullDevice, bool renderToTexture)
 {
     DrawCallPerfParams params;
-    params.eglParameters = useNullDevice ? OPENGL_NULL() : OPENGL();
+    params.eglParameters = OPENGL_OR_GLES(useNullDevice);
     params.useFBO        = renderToTexture;
     return params;
 }
 
 DrawCallPerfParams DrawCallPerfValidationOnly()
 {
     DrawCallPerfParams params;
     params.eglParameters  = DEFAULT();
--- a/gfx/angle/src/tests/perf_tests/DrawCallPerfParams.h
+++ b/gfx/angle/src/tests/perf_tests/DrawCallPerfParams.h
@@ -35,15 +35,15 @@ struct DrawCallPerfParams : public Rende
 };
 
 std::ostream &operator<<(std::ostream &os, const DrawCallPerfParams &params);
 
 DrawCallPerfParams DrawCallPerfD3D11Params(bool useNullDevice, bool renderToTexture);
 
 DrawCallPerfParams DrawCallPerfD3D9Params(bool useNullDevice, bool renderToTexture);
 
-DrawCallPerfParams DrawCallPerfOpenGLParams(bool useNullDevice, bool renderToTexture);
+DrawCallPerfParams DrawCallPerfOpenGLOrGLESParams(bool useNullDevice, bool renderToTexture);
 
 DrawCallPerfParams DrawCallPerfValidationOnly();
 
 DrawCallPerfParams DrawCallPerfVulkanParams(bool renderToTexture);
 
 #endif  // TESTS_PERF_TESTS_DRAW_CALL_PERF_PARAMS_H_
--- a/gfx/angle/src/tests/perf_tests/DrawElementsPerf.cpp
+++ b/gfx/angle/src/tests/perf_tests/DrawElementsPerf.cpp
@@ -6,16 +6,17 @@
 // DrawElementsPerf:
 //   Performance tests for ANGLE DrawElements call overhead.
 //
 
 #include <sstream>
 
 #include "ANGLEPerfTest.h"
 #include "DrawCallPerfParams.h"
+#include "common/utilities.h"
 #include "test_utils/draw_call_perf_utils.h"
 
 namespace
 {
 
 GLuint CreateElementArrayBuffer(size_t count, GLenum type, GLenum usage)
 {
     GLuint buffer = 0u;
@@ -41,16 +42,21 @@ struct DrawElementsPerfParams final : pu
 
         strstr << DrawCallPerfParams::suffix();
 
         if (indexBufferChanged)
         {
             strstr << "_index_buffer_changed";
         }
 
+        if (type == GL_UNSIGNED_SHORT)
+        {
+            strstr << "_ushort";
+        }
+
         return strstr.str();
     }
 
     GLenum type             = GL_UNSIGNED_INT;
     bool indexBufferChanged = false;
 };
 
 std::ostream &operator<<(std::ostream &os, const DrawElementsPerfParams &params)
@@ -70,18 +76,20 @@ class DrawElementsPerfBenchmark : public
     void drawBenchmark() override;
 
   private:
     GLuint mProgram     = 0;
     GLuint mBuffer      = 0;
     GLuint mIndexBuffer = 0;
     GLuint mFBO         = 0;
     GLuint mTexture     = 0;
+    GLsizei mBufferSize = 0;
     int mCount          = 3 * GetParam().numTris;
-    std::vector<GLuint> mIndexData;
+    std::vector<GLuint> mIntIndexData;
+    std::vector<GLushort> mShortIndexData;
 };
 
 DrawElementsPerfBenchmark::DrawElementsPerfBenchmark()
     : ANGLERenderTest("DrawElementsPerf", GetParam())
 {
     mRunTimeSeconds = GetParam().runTimeSeconds;
 }
 
@@ -96,21 +104,33 @@ void DrawElementsPerfBenchmark::initiali
 
     glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
 
     mBuffer      = Create2DTriangleBuffer(params.numTris, GL_STATIC_DRAW);
     mIndexBuffer = CreateElementArrayBuffer(mCount, params.type, GL_STATIC_DRAW);
 
     for (int i = 0; i < mCount; i++)
     {
-        mIndexData.push_back(rand() % mCount);
+        ASSERT_GE(std::numeric_limits<GLushort>::max(), mCount);
+        mShortIndexData.push_back(static_cast<GLushort>(rand() % mCount));
+        mIntIndexData.push_back(rand() % mCount);
     }
+
     glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, mIndexBuffer);
-    glBufferSubData(GL_ELEMENT_ARRAY_BUFFER, 0, sizeof(params.type) * mIndexData.size(),
-                    mIndexData.data());
+
+    mBufferSize = gl::ElementTypeSize(params.type) * mCount;
+
+    if (params.type == GL_UNSIGNED_INT)
+    {
+        glBufferSubData(GL_ELEMENT_ARRAY_BUFFER, 0, mBufferSize, mIntIndexData.data());
+    }
+    else
+    {
+        glBufferSubData(GL_ELEMENT_ARRAY_BUFFER, 0, mBufferSize, mShortIndexData.data());
+    }
 
     glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 0, 0);
     glEnableVertexAttribArray(0);
 
     // Set the viewport
     glViewport(0, 0, getWindow()->getWidth(), getWindow()->getHeight());
 
     if (params.useFBO)
@@ -144,55 +164,68 @@ void DrawElementsPerfBenchmark::drawBenc
     }
 
     const auto &params = GetParam();
 
     for (unsigned int it = 0; it < params.iterations; it++)
     {
         if (params.indexBufferChanged)
         {
-            glBufferSubData(GL_ELEMENT_ARRAY_BUFFER, 0, sizeof(params.type) * mIndexData.size(),
-                            mIndexData.data());
+            if (params.type == GL_UNSIGNED_INT)
+            {
+                glBufferSubData(GL_ELEMENT_ARRAY_BUFFER, 0, mBufferSize, mIntIndexData.data());
+            }
+            else
+            {
+                glBufferSubData(GL_ELEMENT_ARRAY_BUFFER, 0, mBufferSize, mShortIndexData.data());
+            }
         }
         glDrawElements(GL_TRIANGLES, static_cast<GLsizei>(mCount), params.type, 0);
     }
 
     ASSERT_GL_NO_ERROR();
 }
 
-DrawElementsPerfParams DrawElementsPerfD3D11Params(bool indexBufferChanged)
+DrawElementsPerfParams DrawElementsPerfD3D11Params(bool indexBufferChanged,
+                                                   bool useNullDevice,
+                                                   GLenum indexType)
 {
     DrawElementsPerfParams params;
-    params.eglParameters      = angle::egl_platform::D3D11();
+    params.eglParameters =
+        useNullDevice ? angle::egl_platform::D3D11_NULL() : angle::egl_platform::D3D11();
     params.indexBufferChanged = indexBufferChanged;
+    params.type               = indexType;
     return params;
 }
 
 DrawElementsPerfParams DrawElementsPerfD3D9Params(bool indexBufferChanged)
 {
     DrawElementsPerfParams params;
     params.eglParameters      = angle::egl_platform::D3D9();
     params.indexBufferChanged = indexBufferChanged;
     return params;
 }
 
-DrawElementsPerfParams DrawElementsPerfOpenGLParams(bool indexBufferChanged)
+DrawElementsPerfParams DrawElementsPerfOpenGLOrGLESParams(bool indexBufferChanged)
 {
     DrawElementsPerfParams params;
-    params.eglParameters      = angle::egl_platform::OPENGL();
+    params.eglParameters      = angle::egl_platform::OPENGL_OR_GLES(false);
     params.indexBufferChanged = indexBufferChanged;
     return params;
 }
 
 TEST_P(DrawElementsPerfBenchmark, Run)
 {
     run();
 }
 
 ANGLE_INSTANTIATE_TEST(DrawElementsPerfBenchmark,
                        DrawElementsPerfD3D9Params(false),
                        DrawElementsPerfD3D9Params(true),
-                       DrawElementsPerfD3D11Params(false),
-                       DrawElementsPerfD3D11Params(true),
-                       DrawElementsPerfOpenGLParams(false),
-                       DrawElementsPerfOpenGLParams(true));
+                       DrawElementsPerfD3D11Params(false, true, GL_UNSIGNED_INT),
+                       DrawElementsPerfD3D11Params(true, true, GL_UNSIGNED_INT),
+                       DrawElementsPerfD3D11Params(false, false, GL_UNSIGNED_INT),
+                       DrawElementsPerfD3D11Params(true, false, GL_UNSIGNED_INT),
+                       DrawElementsPerfD3D11Params(false, true, GL_UNSIGNED_SHORT),
+                       DrawElementsPerfOpenGLOrGLESParams(false),
+                       DrawElementsPerfOpenGLOrGLESParams(true));
 
 }  // namespace
--- a/gfx/angle/src/tests/perf_tests/IndexDataManagerTest.cpp
+++ b/gfx/angle/src/tests/perf_tests/IndexDataManagerTest.cpp
@@ -74,30 +74,31 @@ class MockBufferFactoryD3D : public rx::
 
 class MockBufferD3D : public rx::BufferD3D
 {
   public:
     MockBufferD3D(rx::BufferFactoryD3D *factory) : BufferD3D(mockState, factory), mData() {}
 
     // BufferImpl
     gl::Error setData(const gl::Context *context,
-                      GLenum target,
+                      gl::BufferBinding target,
                       const void *data,
                       size_t size,
-                      GLenum) override
+                      gl::BufferUsage) override
     {
         mData.resize(size);
         if (data && size > 0)
         {
             memcpy(&mData[0], data, size);
         }
         return gl::NoError();
     }
 
-    MOCK_METHOD5(setSubData, gl::Error(const gl::Context *, GLenum, const void *, size_t, size_t));
+    MOCK_METHOD5(setSubData,
+                 gl::Error(const gl::Context *, gl::BufferBinding, const void *, size_t, size_t));
     MOCK_METHOD5(copySubData,
                  gl::Error(const gl::Context *, BufferImpl *, GLintptr, GLintptr, GLsizeiptr));
     MOCK_METHOD3(map, gl::Error(const gl::Context *context, GLenum, void **));
     MOCK_METHOD5(mapRange, gl::Error(const gl::Context *, size_t, size_t, GLbitfield, void **));
     MOCK_METHOD2(unmap, gl::Error(const gl::Context *context, GLboolean *));
 
     // BufferD3D
     MOCK_METHOD1(markTransformFeedbackUsage, gl::Error(const gl::Context *));
@@ -149,44 +150,45 @@ class IndexDataManagerPerfTest : public 
     unsigned int mBufferSize;
     MockBufferFactoryD3D mMockBufferFactory;
     MockGLFactoryD3D mMockGLFactory;
     gl::Buffer mIndexBuffer;
 };
 
 IndexDataManagerPerfTest::IndexDataManagerPerfTest()
     : ANGLEPerfTest("IndexDataManger", "_run"),
-      mIndexDataManager(&mMockBufferFactory, rx::RENDERER_D3D11),
+      mIndexDataManager(&mMockBufferFactory),
       mIndexCount(4000),
       mBufferSize(mIndexCount * sizeof(GLushort)),
       mMockBufferFactory(mBufferSize, GL_UNSIGNED_SHORT),
       mMockGLFactory(&mMockBufferFactory),
       mIndexBuffer(&mMockGLFactory, 1)
 {
     std::vector<GLushort> indexData(mIndexCount);
     for (GLsizei index = 0; index < mIndexCount; ++index)
     {
         indexData[index] = static_cast<GLushort>(index);
     }
     EXPECT_FALSE(mIndexBuffer
-                     .bufferData(nullptr, GL_ARRAY_BUFFER, &indexData[0],
-                                 indexData.size() * sizeof(GLushort), GL_STATIC_DRAW)
+                     .bufferData(nullptr, gl::BufferBinding::Array, &indexData[0],
+                                 indexData.size() * sizeof(GLushort), gl::BufferUsage::StaticDraw)
                      .isError());
 }
 
 void IndexDataManagerPerfTest::step()
 {
     rx::TranslatedIndexData translatedIndexData;
+    gl::IndexRange indexRange;
     for (unsigned int iteration = 0; iteration < 100; ++iteration)
     {
         (void)mIndexBuffer.getIndexRange(nullptr, GL_UNSIGNED_SHORT, 0, mIndexCount, false,
-                                         &translatedIndexData.indexRange);
-        (void)mIndexDataManager.prepareIndexData(nullptr, GL_UNSIGNED_SHORT, mIndexCount,
-                                                 &mIndexBuffer, nullptr, &translatedIndexData,
-                                                 false);
+                                         &indexRange);
+        (void)mIndexDataManager.prepareIndexData(nullptr, GL_UNSIGNED_SHORT, GL_UNSIGNED_SHORT,
+                                                 mIndexCount, &mIndexBuffer, nullptr,
+                                                 &translatedIndexData);
     }
 }
 
 TEST_F(IndexDataManagerPerfTest, Run)
 {
     run();
 }
 
--- a/gfx/angle/src/tests/perf_tests/InstancingPerf.cpp
+++ b/gfx/angle/src/tests/perf_tests/InstancingPerf.cpp
@@ -339,26 +339,26 @@ InstancingPerfParams InstancingPerfD3D11
 
 InstancingPerfParams InstancingPerfD3D9Params()
 {
     InstancingPerfParams params;
     params.eglParameters = D3D9();
     return params;
 }
 
-InstancingPerfParams InstancingPerfOpenGLParams()
+InstancingPerfParams InstancingPerfOpenGLOrGLESParams()
 {
     InstancingPerfParams params;
-    params.eglParameters = OPENGL();
+    params.eglParameters = OPENGL_OR_GLES(false);
     return params;
 }
 
 TEST_P(InstancingPerfBenchmark, Run)
 {
     run();
 }
 
 ANGLE_INSTANTIATE_TEST(InstancingPerfBenchmark,
                        InstancingPerfD3D11Params(),
                        InstancingPerfD3D9Params(),
-                       InstancingPerfOpenGLParams());
+                       InstancingPerfOpenGLOrGLESParams());
 
 }  // anonymous namespace
--- a/gfx/angle/src/tests/perf_tests/InterleavedAttributeData.cpp
+++ b/gfx/angle/src/tests/perf_tests/InterleavedAttributeData.cpp
@@ -56,17 +56,20 @@ class InterleavedAttributeDataBenchmark
     void destroyBenchmark() override;
     void drawBenchmark() override;
 
   private:
     GLuint mPointSpriteProgram;
     GLuint mPositionColorBuffer[2];
 
     // The buffers contain two floats and 3 unsigned bytes per point sprite
-    const size_t mBytesPerSprite = 2 * sizeof(float) + 3;
+    // Has to be aligned for float access on arm
+    const size_t mBytesPerSpriteUnaligned = 2 * sizeof(float) + 3;
+    const size_t mBytesPerSprite =
+        ((mBytesPerSpriteUnaligned + sizeof(float) - 1) / sizeof(float)) * sizeof(float);
 };
 
 InterleavedAttributeDataBenchmark::InterleavedAttributeDataBenchmark()
     : ANGLERenderTest("InterleavedAttributeData", GetParam()), mPointSpriteProgram(0)
 {
 }
 
 void InterleavedAttributeDataBenchmark::initializeBenchmark()
@@ -210,22 +213,22 @@ InterleavedAttributeDataParams D3D11_9_3
 
 InterleavedAttributeDataParams D3D9Params()
 {
     InterleavedAttributeDataParams params;
     params.eglParameters = egl_platform::D3D9();
     return params;
 }
 
-InterleavedAttributeDataParams OpenGLParams()
+InterleavedAttributeDataParams OpenGLOrGLESParams()
 {
     InterleavedAttributeDataParams params;
-    params.eglParameters = egl_platform::OPENGL();
+    params.eglParameters = egl_platform::OPENGL_OR_GLES(false);
     return params;
 }
 
 ANGLE_INSTANTIATE_TEST(InterleavedAttributeDataBenchmark,
                        D3D11Params(),
                        D3D11_9_3Params(),
                        D3D9Params(),
-                       OpenGLParams());
+                       OpenGLOrGLESParams());
 
 }  // anonymous namespace
--- a/gfx/angle/src/tests/perf_tests/LinkProgramPerfTest.cpp
+++ b/gfx/angle/src/tests/perf_tests/LinkProgramPerfTest.cpp
@@ -123,26 +123,26 @@ LinkProgramParams LinkProgramD3D11Params
 
 LinkProgramParams LinkProgramD3D9Params()
 {
     LinkProgramParams params;
     params.eglParameters = D3D9();
     return params;
 }
 
-LinkProgramParams LinkProgramOpenGLParams()
+LinkProgramParams LinkProgramOpenGLOrGLESParams()
 {
     LinkProgramParams params;
-    params.eglParameters = OPENGL();
+    params.eglParameters = OPENGL_OR_GLES(false);
     return params;
 }
 
 TEST_P(LinkProgramBenchmark, Run)
 {
     run();
 }
 
 ANGLE_INSTANTIATE_TEST(LinkProgramBenchmark,
                        LinkProgramD3D11Params(),
                        LinkProgramD3D9Params(),
-                       LinkProgramOpenGLParams());
+                       LinkProgramOpenGLOrGLESParams());
 
 }  // anonymous namespace
--- a/gfx/angle/src/tests/perf_tests/MultiviewPerf.cpp
+++ b/gfx/angle/src/tests/perf_tests/MultiviewPerf.cpp
@@ -509,27 +509,28 @@ MultiviewPerfParams SelectViewInVertexSh
 }  // namespace
 
 TEST_P(MultiviewCPUBoundBenchmark, Run)
 {
     run();
 }
 
 ANGLE_INSTANTIATE_TEST(MultiviewCPUBoundBenchmark,
-                       NoAcceleration(egl_platform::OPENGL(), SmallWorkload()),
+                       NoAcceleration(egl_platform::OPENGL_OR_GLES(false), SmallWorkload()),
                        NoAcceleration(egl_platform::D3D11(), SmallWorkload()),
                        SelectViewInGeometryShader(SmallWorkload()),
-                       SelectViewInVertexShader(egl_platform::OPENGL(), SmallWorkload()),
+                       SelectViewInVertexShader(egl_platform::OPENGL_OR_GLES(false),
+                                                SmallWorkload()),
                        SelectViewInVertexShader(egl_platform::D3D11(), SmallWorkload()));
 
 TEST_P(MultiviewGPUBoundBenchmark, Run)
 {
     run();
 }
 
 ANGLE_INSTANTIATE_TEST(MultiviewGPUBoundBenchmark,
-                       NoAcceleration(egl_platform::OPENGL(), BigWorkload()),
+                       NoAcceleration(egl_platform::OPENGL_OR_GLES(false), BigWorkload()),
                        NoAcceleration(egl_platform::D3D11(), BigWorkload()),
                        SelectViewInGeometryShader(BigWorkload()),
-                       SelectViewInVertexShader(egl_platform::OPENGL(), BigWorkload()),
+                       SelectViewInVertexShader(egl_platform::OPENGL_OR_GLES(false), BigWorkload()),
                        SelectViewInVertexShader(egl_platform::D3D11(), BigWorkload()));
 
 }  // anonymous namespace
--- a/gfx/angle/src/tests/perf_tests/PointSprites.cpp
+++ b/gfx/angle/src/tests/perf_tests/PointSprites.cpp
@@ -207,24 +207,23 @@ PointSpritesParams D3D11Params()
 
 PointSpritesParams D3D9Params()
 {
     PointSpritesParams params;
     params.eglParameters = egl_platform::D3D9();
     return params;
 }
 
-PointSpritesParams OpenGLParams()
+PointSpritesParams OpenGLOrGLESParams()
 {
     PointSpritesParams params;
-    params.eglParameters = egl_platform::OPENGL();
+    params.eglParameters = egl_platform::OPENGL_OR_GLES(false);
     return params;
 }
 
 } // namespace
 
 TEST_P(PointSpritesBenchmark, Run)
 {
     run();
 }
 
-ANGLE_INSTANTIATE_TEST(PointSpritesBenchmark,
-                       D3D11Params(), D3D9Params(), OpenGLParams());
+ANGLE_INSTANTIATE_TEST(PointSpritesBenchmark, D3D11Params(), D3D9Params(), OpenGLOrGLESParams());
--- a/gfx/angle/src/tests/perf_tests/TexSubImage.cpp
+++ b/gfx/angle/src/tests/perf_tests/TexSubImage.cpp
@@ -85,17 +85,17 @@ class TexSubImageBenchmark : public ANGL
 
 std::string TexSubImageParams::suffix() const
 {
     // TODO(jmadill)
     return RenderTestParams::suffix();
 }
 
 TexSubImageBenchmark::TexSubImageBenchmark()
-    : ANGLERenderTest("TexSubImage", GetParam()),
+    : ANGLERenderTest("TexSubImage", GetParam(), {"GL_EXT_texture_storage"}),
       mProgram(0),
       mPositionLoc(-1),
       mTexCoordLoc(-1),
       mSamplerLoc(-1),
       mTexture(0),
       mVertexBuffer(0),
       mIndexBuffer(0),
       mPixels(nullptr)
@@ -269,23 +269,23 @@ TexSubImageParams D3D11Params()
 
 TexSubImageParams D3D9Params()
 {
     TexSubImageParams params;
     params.eglParameters = egl_platform::D3D9();
     return params;
 }
 
-TexSubImageParams OpenGLParams()
+TexSubImageParams OpenGLOrGLESParams()
 {
     TexSubImageParams params;
-    params.eglParameters = egl_platform::OPENGL();
+    params.eglParameters = egl_platform::OPENGL_OR_GLES(false);
     return params;
 }
 
 }  // namespace
 
 TEST_P(TexSubImageBenchmark, Run)
 {
     run();
 }
 
-ANGLE_INSTANTIATE_TEST(TexSubImageBenchmark, D3D11Params(), D3D9Params(), OpenGLParams());
+ANGLE_INSTANTIATE_TEST(TexSubImageBenchmark, D3D11Params(), D3D9Params(), OpenGLOrGLESParams());
--- a/gfx/angle/src/tests/perf_tests/TextureSampling.cpp
+++ b/gfx/angle/src/tests/perf_tests/TextureSampling.cpp
@@ -266,23 +266,23 @@ TextureSamplingParams D3D11Params()
 
 TextureSamplingParams D3D9Params()
 {
     TextureSamplingParams params;
     params.eglParameters = egl_platform::D3D9();
     return params;
 }
 
-TextureSamplingParams OpenGLParams()
+TextureSamplingParams OpenGLOrGLESParams()
 {
     TextureSamplingParams params;
-    params.eglParameters = egl_platform::OPENGL();
+    params.eglParameters = egl_platform::OPENGL_OR_GLES(false);
     return params;
 }
 
 }  // anonymous namespace
 
 TEST_P(TextureSamplingBenchmark, Run)
 {
     run();
 }
 
-ANGLE_INSTANTIATE_TEST(TextureSamplingBenchmark, D3D11Params(), D3D9Params(), OpenGLParams());
+ANGLE_INSTANTIATE_TEST(TextureSamplingBenchmark, D3D11Params(), D3D9Params(), OpenGLOrGLESParams());
--- a/gfx/angle/src/tests/perf_tests/TexturesPerf.cpp
+++ b/gfx/angle/src/tests/perf_tests/TexturesPerf.cpp
@@ -28,24 +28,28 @@ struct TexturesParams final : public Ren
         windowWidth  = 720;
         windowHeight = 720;
         iterations   = 256;
 
         numTextures                 = 8;
         textureRebindFrequency      = 5;
         textureStateUpdateFrequency = 3;
         textureMipCount             = 8;
+
+        webgl = false;
     }
 
     std::string suffix() const override;
     size_t numTextures;
     size_t textureRebindFrequency;
     size_t textureStateUpdateFrequency;
     size_t textureMipCount;
 
+    bool webgl;
+
     // static parameters
     size_t iterations;
 };
 
 std::ostream &operator<<(std::ostream &os, const TexturesParams &params)
 {
     os << params.suffix().substr(1);
     return os;
@@ -56,16 +60,21 @@ std::string TexturesParams::suffix() con
     std::stringstream strstr;
 
     strstr << RenderTestParams::suffix();
     strstr << "_" << numTextures << "_textures";
     strstr << "_" << textureRebindFrequency << "_rebind";
     strstr << "_" << textureStateUpdateFrequency << "_state";
     strstr << "_" << textureMipCount << "_mips";
 
+    if (webgl)
+    {
+        strstr << "_webgl";
+    }
+
     return strstr.str();
 }
 
 class TexturesBenchmark : public ANGLERenderTest,
                           public ::testing::WithParamInterface<TexturesParams>
 {
   public:
     TexturesBenchmark();
@@ -81,16 +90,18 @@ class TexturesBenchmark : public ANGLERe
     std::vector<GLuint> mTextures;
 
     GLuint mProgram;
     std::vector<GLuint> mUniformLocations;
 };
 
 TexturesBenchmark::TexturesBenchmark() : ANGLERenderTest("Textures", GetParam()), mProgram(0u)
 {
+    setWebGLCompatibilityEnabled(GetParam().webgl);
+    setRobustResourceInit(GetParam().webgl);
 }
 
 void TexturesBenchmark::initializeBenchmark()
 {
     const auto &params = GetParam();
 
     ASSERT_GT(params.iterations, 0u);
 
@@ -257,37 +268,45 @@ void TexturesBenchmark::drawBenchmark()
         }
 
         glDrawArrays(GL_TRIANGLES, 0, 3);
     }
 
     ASSERT_GL_NO_ERROR();
 }
 
-TexturesParams D3D11Params()
+TexturesParams D3D11Params(bool webglCompat)
 {
     TexturesParams params;
     params.eglParameters = egl_platform::D3D11_NULL();
+    params.webgl         = webglCompat;
     return params;
 }
 
-TexturesParams D3D9Params()
+TexturesParams D3D9Params(bool webglCompat)
 {
     TexturesParams params;
     params.eglParameters = egl_platform::D3D9_NULL();
+    params.webgl         = webglCompat;
     return params;
 }
 
-TexturesParams OpenGLParams()
+TexturesParams OpenGLOrGLESParams(bool webglCompat)
 {
     TexturesParams params;
-    params.eglParameters = egl_platform::OPENGL_NULL();
+    params.eglParameters = egl_platform::OPENGL_OR_GLES(true);
+    params.webgl         = webglCompat;
     return params;
 }
 
 TEST_P(TexturesBenchmark, Run)
 {
     run();
 }
 
-ANGLE_INSTANTIATE_TEST(TexturesBenchmark, D3D11Params(), D3D9Params(), OpenGLParams());
+ANGLE_INSTANTIATE_TEST(TexturesBenchmark,
+                       D3D11Params(false),
+                       D3D11Params(true),
+                       D3D9Params(true),
+                       OpenGLOrGLESParams(false),
+                       OpenGLOrGLESParams(true));
 
 }  // namespace angle
--- a/gfx/angle/src/tests/perf_tests/UniformsPerf.cpp
+++ b/gfx/angle/src/tests/perf_tests/UniformsPerf.cpp
@@ -391,32 +391,32 @@ UniformsParams VectorUniforms(const EGLP
 UniformsParams MatrixUniforms(const EGLPlatformParameters &egl, DataMode dataMode)
 {
     UniformsParams params;
     params.eglParameters = egl;
     params.dataType      = DataType::MAT4;
     params.dataMode      = dataMode;
 
     // Reduce the number of uniforms to fit within smaller upper limits on some configs.
-    params.numVertexUniforms   = 100;
-    params.numFragmentUniforms = 100;
+    params.numVertexUniforms   = 64;
+    params.numFragmentUniforms = 64;
 
     return params;
 }
 
 }  // anonymous namespace
 
 TEST_P(UniformsBenchmark, Run)
 {
     run();
 }
 
 ANGLE_INSTANTIATE_TEST(UniformsBenchmark,
                        VectorUniforms(D3D9(), DataMode::UPDATE),
                        VectorUniforms(D3D11(), DataMode::REPEAT),
                        VectorUniforms(D3D11(), DataMode::UPDATE),
                        VectorUniforms(D3D11_NULL(), DataMode::UPDATE),
-                       VectorUniforms(OPENGL(), DataMode::UPDATE),
-                       VectorUniforms(OPENGL(), DataMode::REPEAT),
-                       VectorUniforms(OPENGL_NULL(), DataMode::UPDATE),
+                       VectorUniforms(OPENGL_OR_GLES(false), DataMode::UPDATE),
+                       VectorUniforms(OPENGL_OR_GLES(false), DataMode::REPEAT),
+                       VectorUniforms(OPENGL_OR_GLES(true), DataMode::UPDATE),
                        MatrixUniforms(D3D11(), DataMode::UPDATE),
-                       MatrixUniforms(OPENGL(), DataMode::UPDATE),
+                       MatrixUniforms(OPENGL_OR_GLES(false), DataMode::UPDATE),
                        VectorUniforms(D3D11_NULL(), DataMode::REPEAT, ProgramMode::MULTIPLE));
--- a/gfx/angle/src/tests/preprocessor_tests/if_test.cpp
+++ b/gfx/angle/src/tests/preprocessor_tests/if_test.cpp
@@ -953,16 +953,51 @@ TEST_F(IfTest, BitShiftLeftOperatorNegat
     const char *expected =
         "\n"
         "pass\n"
         "\n";
 
     preprocess(str, expected);
 }
 
+// Left shift overflows. Note that the intended result is not explicitly specified, but we assume it
+// to do the same operation on the 2's complement bit representation as unsigned shift in C++.
+TEST_F(IfTest, BitShiftLeftOverflow)
+{
+    const char *str =
+        "#if (0x10000 + 0x1) << 28 == 0x10000000\n"
+        "pass\n"
+        "#endif\n";
+    const char *expected =
+        "\n"
+        "pass\n"
+        "\n";
+
+    preprocess(str, expected);
+}
+
+// Left shift of a negative number overflows. Note that the intended result is not explicitly
+// specified, but we assume it to do the same operation on the 2's complement bit representation as
+// unsigned shift in C++.
+TEST_F(IfTest, BitShiftLeftNegativeOverflow)
+{
+    // The bit representation of -5 is 11111111 11111111 11111111 11111011.
+    // Shifting by 30 leaves:          11000000 00000000 00000000 00000000.
+    const char *str =
+        "#if (-5) << 30 == -1073741824\n"
+        "pass\n"
+        "#endif\n";
+    const char *expected =
+        "\n"
+        "pass\n"
+        "\n";
+
+    preprocess(str, expected);
+}
+
 // Undefined shift: shift offset is out of range.
 TEST_F(IfTest, BitShiftRightOperatorNegativeOffset)
 {
     const char *str =
         "#if 2 >> -1 == 4\n"
         "foo\n"
         "#endif\n";
 
--- a/gfx/angle/src/tests/preprocessor_tests/input_test.cpp
+++ b/gfx/angle/src/tests/preprocessor_tests/input_test.cpp
@@ -16,17 +16,17 @@ TEST_F(InitTest, ZeroCount)
 {
     EXPECT_TRUE(mPreprocessor.init(0, nullptr, nullptr));
 
     pp::Token token;
     mPreprocessor.lex(&token);
     EXPECT_EQ(pp::Token::LAST, token.type);
 }
 
-TEST_F(InitTest, VoidString)
+TEST_F(InitTest, NullString)
 {
     EXPECT_FALSE(mPreprocessor.init(1, nullptr, nullptr));
 }
 
 TEST(InputTest, DefaultConstructor)
 {
     pp::Input input;
     EXPECT_EQ(0u, input.count());
--- a/gfx/angle/src/tests/preprocessor_tests/location_test.cpp
+++ b/gfx/angle/src/tests/preprocessor_tests/location_test.cpp
@@ -265,32 +265,64 @@ TEST_F(LocationTest, LineDirectiveMissin
 
     pp::Token token;
     mPreprocessor.lex(&token);
 }
 
 // Test for an error being generated when the line number overflows - regular version
 TEST_F(LocationTest, LineOverflowRegular)
 {
-    const char *str = "#line 2147483647\n\n";
+    const char *str = "#line 0x7FFFFFFF\n\n";
 
     ASSERT_TRUE(mPreprocessor.init(1, &str, NULL));
 
     using testing::_;
     // Error reported about EOF.
     EXPECT_CALL(mDiagnostics, print(pp::Diagnostics::PP_TOKENIZER_ERROR, _, _));
 
     pp::Token token;
     mPreprocessor.lex(&token);
 }
 
 // Test for an error being generated when the line number overflows - inside /* */ comment version
 TEST_F(LocationTest, LineOverflowInComment)
 {
-    const char *str = "#line 2147483647\n/*\n*/";
+    const char *str = "#line 0x7FFFFFFF\n/*\n*/";
+
+    ASSERT_TRUE(mPreprocessor.init(1, &str, NULL));
+
+    using testing::_;
+    // Error reported about EOF.
+    EXPECT_CALL(mDiagnostics, print(pp::Diagnostics::PP_TOKENIZER_ERROR, _, _));
+
+    pp::Token token;
+    mPreprocessor.lex(&token);
+}
+
+// Test for an error being generated when the line number overflows - inside \n continuation
+// version
+TEST_F(LocationTest, LineOverflowInContinuationN)
+{
+    const char *str = "#line 0x7FFFFFFF\n \\\n\n";
+
+    ASSERT_TRUE(mPreprocessor.init(1, &str, NULL));
+
+    using testing::_;
+    // Error reported about EOF.
+    EXPECT_CALL(mDiagnostics, print(pp::Diagnostics::PP_TOKENIZER_ERROR, _, _));
+
+    pp::Token token;
+    mPreprocessor.lex(&token);
+}
+
+// Test for an error being generated when the line number overflows - inside \r\n continuation
+// version
+TEST_F(LocationTest, LineOverflowInContinuationRN)
+{
+    const char *str = "#line 0x7FFFFFFF\n \\\r\n\n";
 
     ASSERT_TRUE(mPreprocessor.init(1, &str, NULL));
 
     using testing::_;
     // Error reported about EOF.
     EXPECT_CALL(mDiagnostics, print(pp::Diagnostics::PP_TOKENIZER_ERROR, _, _));
 
     pp::Token token;
--- a/gfx/angle/src/tests/test_utils/ANGLETest.cpp
+++ b/gfx/angle/src/tests/test_utils/ANGLETest.cpp
@@ -84,17 +84,17 @@ std::array<angle::Vector3, 4> GetIndexed
     std::array<angle::Vector3, 4> vertices;
     vertices[0] = angle::Vector3(-1.0f, 1.0f, 0.5f);
     vertices[1] = angle::Vector3(-1.0f, -1.0f, 0.5f);
     vertices[2] = angle::Vector3(1.0f, -1.0f, 0.5f);
     vertices[3] = angle::Vector3(1.0f, 1.0f, 0.5f);
     return vertices;
 }
 
-static constexpr GLushort IndexedQuadIndices[6] = {0, 1, 2, 0, 2, 3};
+static constexpr std::array<GLushort, 6> IndexedQuadIndices = {{0, 1, 2, 0, 2, 3}};
 
 }  // anonymous namespace
 
 GLColorRGB::GLColorRGB() : R(0), G(0), B(0)
 {
 }
 
 GLColorRGB::GLColorRGB(GLubyte r, GLubyte g, GLubyte b) : R(r), G(g), B(b)
@@ -122,16 +122,28 @@ GLColor::GLColor(const angle::Vector4 &f
 {
 }
 
 GLColor::GLColor(GLuint colorValue) : R(0), G(0), B(0), A(0)
 {
     memcpy(&R, &colorValue, sizeof(GLuint));
 }
 
+testing::AssertionResult GLColor::ExpectNear(const GLColor &expected, const GLColor &err) const
+{
+    testing::AssertionResult result(
+        abs(int(expected.R) - this->R) <= err.R && abs(int(expected.G) - this->G) <= err.G &&
+        abs(int(expected.B) - this->B) <= err.B && abs(int(expected.A) - this->A) <= err.A);
+    if (!bool(result))
+    {
+        result << "Expected " << expected << "+/-" << err << ", was " << *this;
+    }
+    return result;
+}
+
 angle::Vector4 GLColor::toNormalizedVector() const
 {
     return angle::Vector4(ColorNorm(R), ColorNorm(G), ColorNorm(B), ColorNorm(A));
 }
 
 GLColor ReadColor(GLint x, GLint y)
 {
     GLColor actual;
@@ -187,16 +199,22 @@ std::array<angle::Vector3, 6> ANGLETestB
     vertices[1] = angle::Vector3(-1.0f, -1.0f, 0.5f);
     vertices[2] = angle::Vector3(1.0f, -1.0f, 0.5f);
     vertices[3] = angle::Vector3(-1.0f, 1.0f, 0.5f);
     vertices[4] = angle::Vector3(1.0f, -1.0f, 0.5f);
     vertices[5] = angle::Vector3(1.0f, 1.0f, 0.5f);
     return vertices;
 }
 
+// static
+std::array<GLushort, 6> ANGLETestBase::GetQuadIndices()
+{
+    return angle::IndexedQuadIndices;
+}
+
 ANGLETestBase::ANGLETestBase(const angle::PlatformParameters &params)
     : mEGLWindow(nullptr),
       mWidth(16),
       mHeight(16),
       mIgnoreD3D11SDKLayersWarnings(false),
       mQuadVertexBuffer(0),
       mQuadIndexBuffer(0),
       m2DTexturedQuadProgram(0),
@@ -378,17 +396,17 @@ void ANGLETestBase::setupIndexedQuadInde
 {
     if (mQuadIndexBuffer == 0)
     {
         glGenBuffers(1, &mQuadIndexBuffer);
     }
 
     glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, mQuadIndexBuffer);
     glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(angle::IndexedQuadIndices),
-                 angle::IndexedQuadIndices, GL_STATIC_DRAW);
+                 angle::IndexedQuadIndices.data(), GL_STATIC_DRAW);
 }
 
 // static
 void ANGLETestBase::drawQuad(GLuint program,
                              const std::string &positionAttribName,
                              GLfloat positionAttribZ)
 {
     drawQuad(program, positionAttribName, positionAttribZ, 1.0f);
@@ -547,17 +565,17 @@ void ANGLETestBase::drawIndexedQuad(GLui
         glGetIntegerv(GL_ELEMENT_ARRAY_BUFFER_BINDING,
                       reinterpret_cast<GLint *>(&prevIndexBinding));
 
         setupIndexedQuadIndexBuffer();
         indices = 0;
     }
     else
     {
-        indices = angle::IndexedQuadIndices;
+        indices = angle::IndexedQuadIndices.data();
     }
 
     if (!restrictedRange)
     {
         glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_SHORT, indices);
     }
     else
     {
--- a/gfx/angle/src/tests/test_utils/ANGLETest.h
+++ b/gfx/angle/src/tests/test_utils/ANGLETest.h
@@ -73,16 +73,22 @@ struct GLColor
 {
     GLColor();
     GLColor(GLubyte r, GLubyte g, GLubyte b, GLubyte a);
     GLColor(const angle::Vector4 &floatColor);
     GLColor(GLuint colorValue);
 
     angle::Vector4 toNormalizedVector() const;
 
+    GLubyte &operator[](size_t index) { return (&R)[index]; }
+
+    const GLubyte &operator[](size_t index) const { return (&R)[index]; }
+
+    testing::AssertionResult ExpectNear(const GLColor &expected, const GLColor &err) const;
+
     GLubyte R, G, B, A;
 
     static const GLColor black;
     static const GLColor blue;
     static const GLColor cyan;
     static const GLColor green;
     static const GLColor red;
     static const GLColor transparentBlack;
@@ -147,16 +153,26 @@ GLColor32F ReadColor32F(GLint x, GLint y
 
 #define EXPECT_PIXEL_COLOR_EQ(x, y, angleColor) EXPECT_EQ(angleColor, angle::ReadColor(x, y))
 #define EXPECT_PIXEL_COLOR_EQ_VEC2(vec2, angleColor) \
     EXPECT_EQ(angleColor,                            \
               angle::ReadColor(static_cast<GLint>(vec2.x()), static_cast<GLint>(vec2.y())))
 
 #define EXPECT_PIXEL_COLOR32F_EQ(x, y, angleColor) EXPECT_EQ(angleColor, angle::ReadColor32F(x, y))
 
+#define EXPECT_PIXEL_RECT_EQ(x, y, width, height, color)                                           \
+    \
+{                                                                                           \
+        std::vector<GLColor> actualColors(width *height);                                          \
+        glReadPixels((x), (y), (width), (height), GL_RGBA, GL_UNSIGNED_BYTE, actualColors.data()); \
+        std::vector<GLColor> expectedColors(width *height, color);                                 \
+        EXPECT_EQ(expectedColors, actualColors);                                                   \
+    \
+}
+
 #define EXPECT_PIXEL_NEAR(x, y, r, g, b, a, abs_error) \
 { \
     GLubyte pixel[4]; \
     glReadPixels((x), (y), 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, pixel); \
     EXPECT_GL_NO_ERROR(); \
     EXPECT_NEAR((r), pixel[0], abs_error); \
     EXPECT_NEAR((g), pixel[1], abs_error); \
     EXPECT_NEAR((b), pixel[2], abs_error); \
@@ -253,16 +269,17 @@ class ANGLETestBase
     void drawQuadInstanced(GLuint program,
                            const std::string &positionAttribName,
                            GLfloat positionAttribZ,
                            GLfloat positionAttribXYScale,
                            bool useVertexBuffer,
                            GLuint numInstances);
 
     static std::array<angle::Vector3, 6> GetQuadVertices();
+    static std::array<GLushort, 6> GetQuadIndices();
     void drawIndexedQuad(GLuint program,
                          const std::string &positionAttribName,
                          GLfloat positionAttribZ);
     void drawIndexedQuad(GLuint program,
                          const std::string &positionAttribName,
                          GLfloat positionAttribZ,
                          GLfloat positionAttribXYScale);
     void drawIndexedQuad(GLuint program,
@@ -321,16 +338,18 @@ class ANGLETestBase
     bool isMultisampleEnabled() const;
 
     EGLint getPlatformRenderer() const;
 
     void ignoreD3D11SDKLayersWarnings();
 
     static OSWindow *GetOSWindow() { return mOSWindow; }
 
+    GLuint get2DTexturedQuadProgram();
+
     angle::PlatformMethods mPlatformMethods;
 
     class ScopedIgnorePlatformMessages : angle::NonCopyable
     {
       public:
         ScopedIgnorePlatformMessages(ANGLETestBase *test);
         ~ScopedIgnorePlatformMessages();
 
@@ -338,18 +357,16 @@ class ANGLETestBase
         ANGLETestBase *mTest;
     };
 
   private:
     bool destroyEGLContext();
 
     void checkD3D11SDKLayersMessages();
 
-    GLuint get2DTexturedQuadProgram();
-
     void drawQuad(GLuint program,
                   const std::string &positionAttribName,
                   GLfloat positionAttribZ,
                   GLfloat positionAttribXYScale,
                   bool useVertexBuffer,
                   bool useInstancedDrawCalls,
                   GLuint numInstances);
 
@@ -431,11 +448,11 @@ bool IsRelease();
 #define ANGLE_SKIP_TEST_IF(COND)                              \
     \
 if(COND)                                                      \
     \
 {                                                      \
         std::cout << "Test skipped: " #COND "." << std::endl; \
         return;                                               \
     \
-}
+} ANGLE_EMPTY_STATEMENT
 
 #endif  // ANGLE_TESTS_ANGLE_TEST_H_
--- a/gfx/angle/src/tests/test_utils/ConstantFoldingTest.h
+++ b/gfx/angle/src/tests/test_utils/ConstantFoldingTest.h
@@ -8,16 +8,18 @@
 //
 
 #ifndef TESTS_TEST_UTILS_CONSTANTFOLDINGTEST_H_
 #define TESTS_TEST_UTILS_CONSTANTFOLDINGTEST_H_
 
 #include <vector>
 
 #include "common/mathutil.h"
+#include "compiler/translator/FindMain.h"
+#include "compiler/translator/FindSymbolNode.h"
 #include "compiler/translator/IntermTraverse.h"
 #include "tests/test_utils/ShaderCompileTreeTest.h"
 
 namespace sh
 {
 
 class TranslatorESSL;
 
@@ -164,16 +166,21 @@ class ConstantFoldingTest : public Shade
 
     template <typename T>
     bool constantVectorNearFoundInAST(const std::vector<T> &constantVector, const T &faultTolerance)
     {
         ConstantFinder<T> finder(constantVector, faultTolerance);
         mASTRoot->traverse(&finder);
         return finder.found();
     }
+
+    bool symbolFoundInMain(const char *symbolName)
+    {
+        return FindSymbolNode(FindMain(mASTRoot), TString(symbolName)) != nullptr;
+    }
 };
 
 class ConstantFoldingExpressionTest : public ConstantFoldingTest
 {
   public:
     ConstantFoldingExpressionTest() {}
 
     void evaluateFloat(const std::string &floatExpression);
--- a/gfx/angle/src/tests/test_utils/angle_test_configs.cpp
+++ b/gfx/angle/src/tests/test_utils/angle_test_configs.cpp
@@ -101,23 +101,23 @@ std::ostream &operator<<(std::ostream& s
       case EGL_PLATFORM_ANGLE_DEVICE_TYPE_HARDWARE_ANGLE:
         // default
         break;
 
       case EGL_PLATFORM_ANGLE_DEVICE_TYPE_NULL_ANGLE:
           stream << "_NULL";
           break;
 
-      case EGL_PLATFORM_ANGLE_DEVICE_TYPE_REFERENCE_ANGLE:
-        stream << "_REFERENCE";
-        break;
+      case EGL_PLATFORM_ANGLE_DEVICE_TYPE_D3D_REFERENCE_ANGLE:
+          stream << "_REFERENCE";
+          break;
 
-      case EGL_PLATFORM_ANGLE_DEVICE_TYPE_WARP_ANGLE:
-        stream << "_WARP";
-        break;
+      case EGL_PLATFORM_ANGLE_DEVICE_TYPE_D3D_WARP_ANGLE:
+          stream << "_WARP";
+          break;
 
       default:
         UNREACHABLE();
         break;
     }
 
     switch (pp.eglParameters.presentPath)
     {
@@ -171,20 +171,18 @@ EGLPlatformParameters D3D9_NULL()
     return EGLPlatformParameters(
         EGL_PLATFORM_ANGLE_TYPE_D3D9_ANGLE,
         EGL_DONT_CARE, EGL_DONT_CARE,
         EGL_PLATFORM_ANGLE_DEVICE_TYPE_NULL_ANGLE);
 }
 
 EGLPlatformParameters D3D9_REFERENCE()
 {
-    return EGLPlatformParameters(
-        EGL_PLATFORM_ANGLE_TYPE_D3D9_ANGLE,
-        EGL_DONT_CARE, EGL_DONT_CARE,
-        EGL_PLATFORM_ANGLE_DEVICE_TYPE_REFERENCE_ANGLE);
+    return EGLPlatformParameters(EGL_PLATFORM_ANGLE_TYPE_D3D9_ANGLE, EGL_DONT_CARE, EGL_DONT_CARE,
+                                 EGL_PLATFORM_ANGLE_DEVICE_TYPE_D3D_REFERENCE_ANGLE);
 }
 
 EGLPlatformParameters D3D11()
 {
     return EGLPlatformParameters(
         EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE,
         EGL_DONT_CARE, EGL_DONT_CARE,
         EGL_PLATFORM_ANGLE_DEVICE_TYPE_HARDWARE_ANGLE);
@@ -241,108 +239,84 @@ EGLPlatformParameters D3D11_NULL()
     return EGLPlatformParameters(
         EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE,
         EGL_DONT_CARE, EGL_DONT_CARE,
         EGL_PLATFORM_ANGLE_DEVICE_TYPE_NULL_ANGLE);
 }
 
 EGLPlatformParameters D3D11_WARP()
 {
-    return EGLPlatformParameters(
-        EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE,
-        EGL_DONT_CARE, EGL_DONT_CARE,
-        EGL_PLATFORM_ANGLE_DEVICE_TYPE_WARP_ANGLE);
+    return EGLPlatformParameters(EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE, EGL_DONT_CARE, EGL_DONT_CARE,
+                                 EGL_PLATFORM_ANGLE_DEVICE_TYPE_D3D_WARP_ANGLE);
 }
 
 EGLPlatformParameters D3D11_FL11_1_WARP()
 {
-    return EGLPlatformParameters(
-        EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE,
-        11, 1,
-        EGL_PLATFORM_ANGLE_DEVICE_TYPE_WARP_ANGLE);
+    return EGLPlatformParameters(EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE, 11, 1,
+                                 EGL_PLATFORM_ANGLE_DEVICE_TYPE_D3D_WARP_ANGLE);
 }
 
 EGLPlatformParameters D3D11_FL11_0_WARP()
 {
-    return EGLPlatformParameters(
-        EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE,
-        11, 0,
-        EGL_PLATFORM_ANGLE_DEVICE_TYPE_WARP_ANGLE);
+    return EGLPlatformParameters(EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE, 11, 0,
+                                 EGL_PLATFORM_ANGLE_DEVICE_TYPE_D3D_WARP_ANGLE);
 }
 
 EGLPlatformParameters D3D11_FL10_1_WARP()
 {
-    return EGLPlatformParameters(
-        EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE,
-        10, 1,
-        EGL_PLATFORM_ANGLE_DEVICE_TYPE_WARP_ANGLE);
+    return EGLPlatformParameters(EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE, 10, 1,
+                                 EGL_PLATFORM_ANGLE_DEVICE_TYPE_D3D_WARP_ANGLE);
 }
 
 EGLPlatformParameters D3D11_FL10_0_WARP()
 {
-    return EGLPlatformParameters(
-        EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE,
-        10, 0,
-        EGL_PLATFORM_ANGLE_DEVICE_TYPE_WARP_ANGLE);
+    return EGLPlatformParameters(EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE, 10, 0,
+                                 EGL_PLATFORM_ANGLE_DEVICE_TYPE_D3D_WARP_ANGLE);
 }
 
 EGLPlatformParameters D3D11_FL9_3_WARP()
 {
-    return EGLPlatformParameters(
-        EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE,
-        9, 3,
-        EGL_PLATFORM_ANGLE_DEVICE_TYPE_WARP_ANGLE);
+    return EGLPlatformParameters(EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE, 9, 3,
+                                 EGL_PLATFORM_ANGLE_DEVICE_TYPE_D3D_WARP_ANGLE);
 }
 
 EGLPlatformParameters D3D11_REFERENCE()
 {
-    return EGLPlatformParameters(
-        EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE,
-        EGL_DONT_CARE, EGL_DONT_CARE,
-        EGL_PLATFORM_ANGLE_DEVICE_TYPE_REFERENCE_ANGLE);
+    return EGLPlatformParameters(EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE, EGL_DONT_CARE, EGL_DONT_CARE,
+                                 EGL_PLATFORM_ANGLE_DEVICE_TYPE_D3D_REFERENCE_ANGLE);
 }
 
 EGLPlatformParameters D3D11_FL11_1_REFERENCE()
 {
-    return EGLPlatformParameters(
-        EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE,
-        11, 1,
-        EGL_PLATFORM_ANGLE_DEVICE_TYPE_REFERENCE_ANGLE);
+    return EGLPlatformParameters(EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE, 11, 1,
+                                 EGL_PLATFORM_ANGLE_DEVICE_TYPE_D3D_REFERENCE_ANGLE);
 }
 
 EGLPlatformParameters D3D11_FL11_0_REFERENCE()
 {
-    return EGLPlatformParameters(
-        EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE,
-        11, 0,
-        EGL_PLATFORM_ANGLE_DEVICE_TYPE_REFERENCE_ANGLE);
+    return EGLPlatformParameters(EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE, 11, 0,
+                                 EGL_PLATFORM_ANGLE_DEVICE_TYPE_D3D_REFERENCE_ANGLE);
 }
 
 EGLPlatformParameters D3D11_FL10_1_REFERENCE()
 {
-    return EGLPlatformParameters(
-        EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE,
-        10, 1,
-        EGL_PLATFORM_ANGLE_DEVICE_TYPE_REFERENCE_ANGLE);
+    return EGLPlatformParameters(EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE, 10, 1,
+                                 EGL_PLATFORM_ANGLE_DEVICE_TYPE_D3D_REFERENCE_ANGLE);
 }
 
 EGLPlatformParameters D3D11_FL10_0_REFERENCE()
 {
-    return EGLPlatformParameters(
-        EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE,
-        10, 0,
-        EGL_PLATFORM_ANGLE_DEVICE_TYPE_REFERENCE_ANGLE);
+    return EGLPlatformParameters(EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE, 10, 0,
+                                 EGL_PLATFORM_ANGLE_DEVICE_TYPE_D3D_REFERENCE_ANGLE);
 }
 
 EGLPlatformParameters D3D11_FL9_3_REFERENCE()
 {
-    return EGLPlatformParameters(
-        EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE,
-        9, 3,
-        EGL_PLATFORM_ANGLE_DEVICE_TYPE_REFERENCE_ANGLE);
+    return EGLPlatformParameters(EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE, 9, 3,
+                                 EGL_PLATFORM_ANGLE_DEVICE_TYPE_D3D_REFERENCE_ANGLE);
 }
 
 EGLPlatformParameters OPENGL()
 {
     return EGLPlatformParameters(EGL_PLATFORM_ANGLE_TYPE_OPENGL_ANGLE);
 }
 
 
@@ -368,16 +342,31 @@ EGLPlatformParameters OPENGLES()
 }
 
 EGLPlatformParameters OPENGLES(EGLint major, EGLint minor)
 {
     return EGLPlatformParameters(EGL_PLATFORM_ANGLE_TYPE_OPENGLES_ANGLE, major, minor,
                                  EGL_DONT_CARE);
 }
 
+EGLPlatformParameters OPENGLES_NULL()
+{
+    return EGLPlatformParameters(EGL_PLATFORM_ANGLE_TYPE_OPENGLES_ANGLE, EGL_DONT_CARE,
+                                 EGL_DONT_CARE, EGL_PLATFORM_ANGLE_DEVICE_TYPE_NULL_ANGLE);
+}
+
+EGLPlatformParameters OPENGL_OR_GLES(bool useNullDevice)
+{
+#if defined(ANGLE_PLATFORM_ANDROID)
+    return useNullDevice ? OPENGLES_NULL() : OPENGLES();
+#else
+    return useNullDevice ? OPENGL_NULL() : OPENGL();
+#endif
+}
+
 EGLPlatformParameters VULKAN()
 {
     return EGLPlatformParameters(EGL_PLATFORM_ANGLE_TYPE_VULKAN_ANGLE);
 }
 
 }  // namespace egl_platform
 
 // ANGLE tests platforms
--- a/gfx/angle/src/tests/test_utils/angle_test_configs.h
+++ b/gfx/angle/src/tests/test_utils/angle_test_configs.h
@@ -76,16 +76,19 @@ EGLPlatformParameters D3D11_FL10_0_REFER
 EGLPlatformParameters D3D11_FL9_3_REFERENCE();
 
 EGLPlatformParameters OPENGL();
 EGLPlatformParameters OPENGL(EGLint major, EGLint minor);
 EGLPlatformParameters OPENGL_NULL();
 
 EGLPlatformParameters OPENGLES();
 EGLPlatformParameters OPENGLES(EGLint major, EGLint minor);
+EGLPlatformParameters OPENGLES_NULL();
+
+EGLPlatformParameters OPENGL_OR_GLES(bool useNullDevice);
 
 EGLPlatformParameters VULKAN();
 
 }  // namespace egl_platform
 
 // ANGLE tests platforms
 PlatformParameters ES2_D3D9();
 PlatformParameters ES2_D3D9_REFERENCE();
--- a/gfx/angle/src/tests/test_utils/compiler_test.cpp
+++ b/gfx/angle/src/tests/test_utils/compiler_test.cpp
@@ -129,59 +129,81 @@ void MatchOutputCodeTest::compile(const 
 }
 
 bool MatchOutputCodeTest::compileWithSettings(ShShaderOutput output,
                                               const std::string &shaderString,
                                               const ShCompileOptions compileOptions,
                                               std::string *translatedCode,
                                               std::string *infoLog)
 {
-    return compileTestShader(mShaderType, SH_GLES3_SPEC, output, shaderString, &mResources,
+    return compileTestShader(mShaderType, SH_GLES3_1_SPEC, output, shaderString, &mResources,
                              compileOptions, translatedCode, infoLog);
 }
 
 bool MatchOutputCodeTest::foundInCode(ShShaderOutput output, const char *stringToFind) const
 {
-    return findInCode(output, stringToFind) != std::string::npos;
-}
-
-size_t MatchOutputCodeTest::findInCode(ShShaderOutput output, const char *stringToFind) const
-{
     const auto code = mOutputCode.find(output);
     EXPECT_NE(mOutputCode.end(), code);
     if (code == mOutputCode.end())
     {
         return std::string::npos;
     }
+    return code->second.find(stringToFind) != std::string::npos;
+}
 
-    return code->second.find(stringToFind);
+bool MatchOutputCodeTest::foundInCodeInOrder(ShShaderOutput output,
+                                             std::vector<const char *> stringsToFind)
+{
+    const auto code = mOutputCode.find(output);
+    EXPECT_NE(mOutputCode.end(), code);
+    if (code == mOutputCode.end())
+    {
+        return false;
+    }
+
+    size_t currentPos = 0;
+    for (const char *stringToFind : stringsToFind)
+    {
+        auto position = code->second.find(stringToFind, currentPos);
+        if (position == std::string::npos)
+        {
+            return false;
+        }
+        currentPos = position + strlen(stringToFind);
+    }
+    return true;
 }
 
 bool MatchOutputCodeTest::foundInCode(ShShaderOutput output,
                                       const char *stringToFind,
                                       const int expectedOccurrences) const
 {
     const auto code = mOutputCode.find(output);
     EXPECT_NE(mOutputCode.end(), code);
     if (code == mOutputCode.end())
     {
         return false;
     }
 
     size_t currentPos  = 0;
     int occurencesLeft = expectedOccurrences;
+
+    const size_t searchStringLength = strlen(stringToFind);
+
     while (occurencesLeft-- > 0)
     {
         auto position = code->second.find(stringToFind, currentPos);
         if (position == std::string::npos)
         {
             return false;
         }
-        currentPos = position + 1;
+        // Search strings should not overlap.
+        currentPos = position + searchStringLength;
     }
+    // Make sure that there aren't extra occurrences.
     return code->second.find(stringToFind, currentPos) == std::string::npos;
 }
 
 bool MatchOutputCodeTest::foundInCode(const char *stringToFind) const
 {
     for (auto &code : mOutputCode)
     {
         if (!foundInCode(code.first, stringToFind))
@@ -199,16 +221,28 @@ bool MatchOutputCodeTest::foundInCode(co
         if (!foundInCode(code.first, stringToFind, expectedOccurrences))
         {
             return false;
         }
     }
     return true;
 }
 
+bool MatchOutputCodeTest::foundInCodeInOrder(std::vector<const char *> stringsToFind)
+{
+    for (auto &code : mOutputCode)
+    {
+        if (!foundInCodeInOrder(code.first, stringsToFind))
+        {
+            return false;
+        }
+    }
+    return true;
+}
+
 bool MatchOutputCodeTest::notFoundInCode(const char *stringToFind) const
 {
     for (auto &code : mOutputCode)
     {
         if (foundInCode(code.first, stringToFind))
         {
             return false;
         }
--- a/gfx/angle/src/tests/test_utils/compiler_test.h
+++ b/gfx/angle/src/tests/test_utils/compiler_test.h
@@ -5,16 +5,17 @@
 //
 // compiler_test.h:
 //     utilities for compiler unit tests.
 
 #ifndef TESTS_TEST_UTILS_COMPILER_TEST_H_
 #define TESTS_TEST_UTILS_COMPILER_TEST_H_
 
 #include <map>
+#include <vector>
 
 #include "gtest/gtest.h"
 
 #include "angle_gl.h"
 #include "compiler/translator/TranslatorESSL.h"
 #include "GLSLANG/ShaderLang.h"
 #include "compiler/translator/FindSymbolNode.h"
 
@@ -59,31 +60,34 @@ class MatchOutputCodeTest : public testi
     }
 
     bool foundInGLSLCode(const char *stringToFind) const
     {
         return foundInCode(SH_GLSL_COMPATIBILITY_OUTPUT, stringToFind);
     }
 
     bool foundInCode(ShShaderOutput output, const char *stringToFind) const;
-    // Returns the position of the first character of the first match in the translated output
-    // source. If no matches are found, then string::npos is returned.
-    size_t findInCode(ShShaderOutput output, const char *stringToFind) const;
+
+    // Test that the strings are found in the specified output in the specified order.
+    bool foundInCodeInOrder(ShShaderOutput output, std::vector<const char *> stringsToFind);
 
     // Test that the string occurs for exactly expectedOccurrences times
     bool foundInCode(ShShaderOutput output,
                      const char *stringToFind,
                      const int expectedOccurrences) const;
 
     // Test that the string is found in all outputs
     bool foundInCode(const char *stringToFind) const;
 
     // Test that the string occurs for exactly expectedOccurrences times in all outputs
     bool foundInCode(const char *stringToFind, const int expectedOccurrences) const;
 
+    // Test that the strings are found in all outputs in the specified order.
+    bool foundInCodeInOrder(std::vector<const char *> stringsToFind);
+
     // Test that the string is found in none of the outputs
     bool notFoundInCode(const char *stringToFind) const;
 
   private:
     bool compileWithSettings(ShShaderOutput output,
                              const std::string &shaderString,
                              ShCompileOptions compileOptions,
                              std::string *translatedCode,
--- a/gfx/angle/src/tests/test_utils/gl_raii.h
+++ b/gfx/angle/src/tests/test_utils/gl_raii.h
@@ -68,16 +68,17 @@ class GLWrapper : angle::NonCopyable
 using GLVertexArray       = GLWrapper<glGenVertexArrays, glDeleteVertexArrays>;
 using GLBuffer            = GLWrapper<glGenBuffers, glDeleteBuffers>;
 using GLTexture           = GLWrapper<glGenTextures, glDeleteTextures>;
 using GLFramebuffer       = GLWrapper<glGenFramebuffers, glDeleteFramebuffers>;
 using GLRenderbuffer      = GLWrapper<glGenRenderbuffers, glDeleteRenderbuffers>;
 using GLSampler           = GLWrapper<glGenSamplers, glDeleteSamplers>;
 using GLTransformFeedback = GLWrapper<glGenTransformFeedbacks, glDeleteTransformFeedbacks>;
 using GLProgramPipeline   = GLWrapper<glGenProgramPipelines, glDeleteProgramPipelines>;
+using GLQueryEXT          = GLWrapper<glGenQueriesEXT, glDeleteQueriesEXT>;
 
 // Don't use GLProgram directly, use ANGLE_GL_PROGRAM.
 namespace priv
 {
 class GLProgram
 {
   public:
     GLProgram() : mHandle(0) {}
@@ -89,16 +90,25 @@ class GLProgram
         mHandle = CompileComputeProgram(computeShader);
     }
 
     void makeRaster(const std::string &vertexShader, const std::string &fragmentShader)
     {
         mHandle = CompileProgram(vertexShader, fragmentShader);
     }
 
+    void makeRasterWithTransformFeedback(const std::string &vertexShader,
+                                         const std::string &fragmentShader,
+                                         const std::vector<std::string> &tfVaryings,
+                                         GLenum bufferMode)
+    {
+        mHandle = CompileProgramWithTransformFeedback(vertexShader, fragmentShader, tfVaryings,
+                                                      bufferMode);
+    }
+
     void makeBinaryOES(const std::vector<uint8_t> &binary, GLenum binaryFormat)
     {
         mHandle = LoadBinaryProgramOES(binary, binaryFormat);
     }
 
     void makeBinaryES3(const std::vector<uint8_t> &binary, GLenum binaryFormat)
     {
         mHandle = LoadBinaryProgramES3(binary, binaryFormat);
@@ -119,16 +129,21 @@ class GLProgram
 };
 }  // namespace priv
 
 #define ANGLE_GL_PROGRAM(name, vertex, fragment) \
     priv::GLProgram name;                        \
     name.makeRaster(vertex, fragment);           \
     ASSERT_TRUE(name.valid());
 
+#define ANGLE_GL_PROGRAM_TRANSFORM_FEEDBACK(name, vertex, fragment, tfVaryings, bufferMode) \
+    priv::GLProgram name;                                                                   \
+    name.makeRasterWithTransformFeedback(vertex, fragment, tfVaryings, bufferMode);         \
+    ASSERT_TRUE(name.valid());
+
 #define ANGLE_GL_COMPUTE_PROGRAM(name, compute) \
     priv::GLProgram name;                       \
     name.makeCompute(compute);                  \
     ASSERT_TRUE(name.valid());
 
 #define ANGLE_GL_BINARY_OES_PROGRAM(name, binary, binaryFormat) \
     priv::GLProgram name;                                       \
     name.makeBinaryOES(binary, binaryFormat);                   \
--- a/gfx/angle/src/tests/tests.gyp
+++ b/gfx/angle/src/tests/tests.gyp
@@ -36,16 +36,23 @@
             'third_party/rapidjson/include/rapidjson/internal/meta.h',
             'third_party/rapidjson/include/rapidjson/internal/pow10.h',
             'third_party/rapidjson/include/rapidjson/internal/stack.h',
             'third_party/rapidjson/include/rapidjson/internal/strfunc.h',
             'third_party/rapidjson/include/rapidjson/msinttypes/inttypes.h',
             'third_party/rapidjson/include/rapidjson/msinttypes/stdint.h',
         ],
     },
+    'target_defaults':
+    {
+        'dependencies':
+        [
+            '../../gyp/warnings.gyp:gyp_deprecation',
+        ],
+    },
     'conditions':
     [
         # GoogleTest doesn't support WinRT
         ['angle_build_winrt==0',
         {
             'targets':
             [
                 {
@@ -66,70 +73,70 @@
                 # Hide these targets from Chromium, because it can't
                 # find our standalone copy of the gtest/gmock sources.
                 {
                     'target_name': 'angle_internal_gtest',
                     'type': 'static_library',
                     'includes': [ '../../gyp/common_defines.gypi', ],
                     'include_dirs':
                     [
-                        '<(angle_path)/testing/gtest',
-                        '<(angle_path)/testing/gtest/include',
+                        '<(angle_path)/third_party/googletest/src/googletest',
+                        '<(angle_path)/third_party/googletest/src/googletest/include',
                     ],
                     'sources':
                     [
-                        '<(angle_path)/testing/gtest/src/gtest-all.cc',
+                        '<(angle_path)/third_party/googletest/src/googletest/src/gtest-all.cc',
                     ],
                     'defines':
                     [
                         '_VARIADIC_MAX=10',
                     ],
                     'all_dependent_settings':
                     {
                         'defines':
                         [
                             '_VARIADIC_MAX=10',
                         ],
                         'include_dirs':
                         [
-                            '<(angle_path)/testing/gtest',
-                            '<(angle_path)/testing/gtest/include',
+                            '<(angle_path)/third_party/googletest/src/googletest',
+                            '<(angle_path)/third_party/googletest/src/googletest/include',
                         ],
                     },
                 },
 
                 {
                     'target_name': 'angle_internal_gmock',
                     'type': 'static_library',
                     'includes': [ '../../gyp/common_defines.gypi', ],
                     'include_dirs':
                     [
-                        '<(angle_path)/testing/gmock',
-                        '<(angle_path)/testing/gmock/include',
-                        '<(angle_path)/testing/gtest/include',
+                        '<(angle_path)/third_party/googletest/src/googlemock',
+                        '<(angle_path)/third_party/googletest/src/googlemock/include',
+                        '<(angle_path)/third_party/googletest/src/googletest/include',
                     ],
                     'sources':
                     [
-                        '<(angle_path)/testing/gmock/src/gmock-all.cc',
+                        '<(angle_path)/third_party/googletest/src/googlemock/src/gmock-all.cc',
                     ],
                     'defines':
                     [
                         '_VARIADIC_MAX=10',
                     ],
                     'all_dependent_settings':
                     {
                         'defines':
                         [
                             '_VARIADIC_MAX=10',
                         ],
                         'include_dirs':
                         [
-                            '<(angle_path)/testing/gmock',
-                            '<(angle_path)/testing/gmock/include',
-                            '<(angle_path)/testing/gtest/include',
+                            '<(angle_path)/third_party/googletest/src/googlemock',
+                            '<(angle_path)/third_party/googletest/src/googlemock/include',
+                            '<(angle_path)/third_party/googletest/src/googletest/include',
                         ],
                     },
                 },
 
                 # These same target names exist on the Chromium side,
                 # which is forbidden, so we make them conditional on
                 # ANGLE's standalone build.
                 {
--- a/gfx/angle/src/tests/third_party/gpu_test_expectations/angle-mods.patch
+++ b/gfx/angle/src/tests/third_party/gpu_test_expectations/angle-mods.patch
@@ -1,11 +1,37 @@
+diff -u -rupN gpu_test_expectations_reverted/HowToMakeChanges.md gpu_test_expectations/HowToMakeChanges.md
+--- gpu_test_expectations_reverted/HowToMakeChanges.md	1969-12-31 19:00:00.000000000 -0500
++++ gpu_test_expectations/HowToMakeChanges.md	2016-09-13 10:06:02.000000000 -0400
+@@ -0,0 +1,22 @@
++Because the ```gpu_test_expectations``` directory is based on parts of Chromium's ```gpu/config```
++directory, we want to keep a patch of the changes added to make it compile with ANGLE. This
++will allow us to merge Chromium changes easily in our ```gpu_test_expectations```.
++
++In order to make a change to this directory, do the following:
++
++ * copy the directory somewhere like in ```gpu_test_expectations_reverted```
++ * in ```gpu_test_expectations_reverted``` run ```patch -p 1 -R < angle-mods.patch```
++ * do your changes in ```gpu_test_expectations```
++ * delete angle-mods.patch in both directories
++ * run ```diff -rupN gpu_test_expectations_reverted gpu_test_expectations > angle-mods.patch```
++ * copy ```angle-mods.patch``` in ```gpu_test_expectations```
++
++How to update from Chromium:
++
++ * ```git apply -R angle-mods.patch```, ```git add . -u```, ```git commit```
++ * Copy over Chromium files, ```git add . -u```, ```git commit```
++ * ```git revert HEAD~```
++ * ```rm angle-mods.patch```
++ * ```git diff HEAD~ (`)ls(`) > angle-mods.patch```,```git add angle-mods.patch```, ```git commit --amend```
++ * ```git rebase -i``` to squash the three patches into one.
++
 diff -u -rupN gpu_test_expectations_reverted/angle_config.h gpu_test_expectations/angle_config.h
 --- gpu_test_expectations_reverted/angle_config.h	1969-12-31 19:00:00.000000000 -0500
-+++ gpu_test_expectations/angle_config.h	2017-09-07 13:19:49.903835490 -0400
++++ gpu_test_expectations/angle_config.h	2017-09-11 17:18:07.000000000 -0400
 @@ -0,0 +1,73 @@
 +//
 +// Copyright 2015 The ANGLE Project Authors. All rights reserved.
 +// Use of this source code is governed by a BSD-style license that can be
 +// found in the LICENSE file.
 +//
 +// angle_config.h:
 +//   Helpers for importing the gpu test expectations package from Chrome.
@@ -71,18 +97,18 @@ diff -u -rupN gpu_test_expectations_reve
 +#    define OS_MACOSX
 +#else
 +#    error "Unsupported platform"
 +#endif
 +// clang-format on
 +
 +#endif
 diff -u -rupN gpu_test_expectations_reverted/gpu_info.cc gpu_test_expectations/gpu_info.cc
---- gpu_test_expectations_reverted/gpu_info.cc	2017-09-06 11:43:12.749280785 -0400
-+++ gpu_test_expectations/gpu_info.cc	2017-09-07 13:17:55.282894551 -0400
+--- gpu_test_expectations_reverted/gpu_info.cc	2017-10-30 14:30:27.000000000 -0400
++++ gpu_test_expectations/gpu_info.cc	2017-10-27 13:46:39.000000000 -0400
 @@ -4,7 +4,7 @@
  
  #include <stdint.h>
  
 -#include "gpu/config/gpu_info.h"
 +#include "gpu_info.h"
  
  namespace {
@@ -92,18 +118,18 @@ diff -u -rupN gpu_test_expectations_reve
        return secondary_gpu;
    }
 -  DLOG(ERROR) << "No active GPU found, returning primary GPU.";
 +  DLOG(ERROR) << "No active GPU found, returning primary GPU.\n";
    return gpu;
  }
  
 diff -u -rupN gpu_test_expectations_reverted/gpu_info.h gpu_test_expectations/gpu_info.h
---- gpu_test_expectations_reverted/gpu_info.h	2017-09-06 11:43:16.229309773 -0400
-+++ gpu_test_expectations/gpu_info.h	2017-09-07 13:18:25.187140020 -0400
+--- gpu_test_expectations_reverted/gpu_info.h	2017-10-30 14:30:27.000000000 -0400
++++ gpu_test_expectations/gpu_info.h	2017-10-27 13:46:39.000000000 -0400
 @@ -2,8 +2,8 @@
  // Use of this source code is governed by a BSD-style license that can be
  // found in the LICENSE file.
  
 -#ifndef GPU_CONFIG_GPU_INFO_H_
 -#define GPU_CONFIG_GPU_INFO_H_
 +#ifndef ANGLE_GPU_CONFIG_GPU_INFO_H_
 +#define ANGLE_GPU_CONFIG_GPU_INFO_H_
@@ -119,25 +145,25 @@ diff -u -rupN gpu_test_expectations_reve
 -#include "build/build_config.h"
 -#include "gpu/config/dx_diag_node.h"
 -#include "gpu/gpu_export.h"
 -#include "ui/gfx/geometry/size.h"
 +#include "angle_config.h"
  
  #if defined(USE_X11)
  typedef unsigned long VisualID;
-@@ -301,4 +296,4 @@ struct GPU_EXPORT GPUInfo {
+@@ -299,4 +294,4 @@ struct GPU_EXPORT GPUInfo {
  
  }  // namespace gpu
  
 -#endif  // GPU_CONFIG_GPU_INFO_H_
 +#endif  // ANGLE_GPU_CONFIG_GPU_INFO_H_
 diff -u -rupN gpu_test_expectations_reverted/gpu_test_config.cc gpu_test_expectations/gpu_test_config.cc
---- gpu_test_expectations_reverted/gpu_test_config.cc	2017-09-06 11:43:27.173400936 -0400
-+++ gpu_test_expectations/gpu_test_config.cc	2017-09-07 13:17:55.282894551 -0400
+--- gpu_test_expectations_reverted/gpu_test_config.cc	2017-10-30 14:30:27.000000000 -0400
++++ gpu_test_expectations/gpu_test_config.cc	2017-10-30 14:44:19.000000000 -0400
 @@ -2,21 +2,53 @@
  // Use of this source code is governed by a BSD-style license that can be
  // found in the LICENSE file.
  
 -#include "gpu/config/gpu_test_config.h"
 +#include "gpu_test_config.h"
  
  #include <stddef.h>
@@ -190,17 +216,27 @@ diff -u -rupN gpu_test_expectations_reve
 +} // anonymous namespace
 +} // namespace base
 +
 +#endif // defined(OS_WIN)
 +
  namespace gpu {
  
  namespace {
-@@ -74,6 +106,26 @@ GPUTestConfig::OS GetCurrentOS() {
+@@ -46,8 +78,7 @@ GPUTestConfig::OS GetCurrentOS() {
+   int32_t major_version = 0;
+   int32_t minor_version = 0;
+   int32_t bugfix_version = 0;
+-  base::SysInfo::OperatingSystemVersionNumbers(
+-      &major_version, &minor_version, &bugfix_version);
++  angle::GetOperatingSystemVersionNumbers(&major_version, &minor_version, &bugfix_version);
+   if (major_version == 10) {
+     switch (minor_version) {
+       case 5:
+@@ -76,6 +107,26 @@ GPUTestConfig::OS GetCurrentOS() {
    return GPUTestConfig::kOsUnknown;
  }
  
 +#if !defined(OS_ANDROID)
 +CollectInfoResult CollectBasicGraphicsInfo(GPUInfo* gpu_info) {
 +  angle::SystemInfo info;
 +  if (!angle::GetSystemInfo(&info)) {
 +    return kCollectInfoFatalFailure;
@@ -217,37 +253,37 @@ diff -u -rupN gpu_test_expectations_reve
 +  gpu_info->gpu.device_id = 0;
 +  gpu_info->gpu.active = true;
 +  return kCollectInfoNonFatalFailure;
 +}
 +#endif  // defined(OS_ANDROID)
  }  // namespace anonymous
  
  GPUTestConfig::GPUTestConfig()
-@@ -257,7 +309,7 @@ bool GPUTestBotConfig::LoadCurrentConfig
+@@ -260,7 +311,7 @@ bool GPUTestBotConfig::LoadCurrentConfig
      GPUInfo my_gpu_info;
      CollectInfoResult result = CollectBasicGraphicsInfo(&my_gpu_info);
      if (result != kCollectInfoSuccess) {
 -      LOG(ERROR) << "Fail to identify GPU";
 +      LOG(ERROR) << "Fail to identify GPU\n";
        DisableGPUInfoValidation();
        rt = true;
      } else {
-@@ -268,7 +320,7 @@ bool GPUTestBotConfig::LoadCurrentConfig
+@@ -271,7 +322,7 @@ bool GPUTestBotConfig::LoadCurrentConfig
    }
    set_os(GetCurrentOS());
    if (os() == kOsUnknown) {
 -    LOG(ERROR) << "Unknown OS";
 +    LOG(ERROR) << "Unknown OS\n";
      rt = false;
    }
  #if defined(NDEBUG)
 diff -u -rupN gpu_test_expectations_reverted/gpu_test_config.h gpu_test_expectations/gpu_test_config.h
---- gpu_test_expectations_reverted/gpu_test_config.h	2017-09-06 11:43:24.205376213 -0400
-+++ gpu_test_expectations/gpu_test_config.h	2017-09-07 13:18:46.207312571 -0400
+--- gpu_test_expectations_reverted/gpu_test_config.h	2017-10-30 14:30:27.000000000 -0400
++++ gpu_test_expectations/gpu_test_config.h	2017-10-27 13:46:39.000000000 -0400
 @@ -2,16 +2,15 @@
  // Use of this source code is governed by a BSD-style license that can be
  // found in the LICENSE file.
  
 -#ifndef GPU_CONFIG_GPU_TEST_CONFIG_H_
 -#define GPU_CONFIG_GPU_TEST_CONFIG_H_
 +#ifndef ANGLE_GPU_CONFIG_GPU_TEST_CONFIG_H_
 +#define ANGLE_GPU_CONFIG_GPU_TEST_CONFIG_H_
@@ -258,99 +294,107 @@ diff -u -rupN gpu_test_expectations_reve
  #include <vector>
  
 -#include "base/compiler_specific.h"
 -#include "gpu/gpu_export.h"
 +#include "angle_config.h"
  
  namespace gpu {
  
-@@ -144,5 +143,5 @@ class GPU_EXPORT GPUTestBotConfig : publ
+@@ -145,5 +144,5 @@ class GPU_EXPORT GPUTestBotConfig : publ
  
  }  // namespace gpu
  
 -#endif  // GPU_CONFIG_GPU_TEST_CONFIG_H_
 +#endif  // ANGLE_GPU_CONFIG_GPU_TEST_CONFIG_H_
  
 diff -u -rupN gpu_test_expectations_reverted/gpu_test_config_mac.h gpu_test_expectations/gpu_test_config_mac.h
 --- gpu_test_expectations_reverted/gpu_test_config_mac.h	1969-12-31 19:00:00.000000000 -0500
-+++ gpu_test_expectations/gpu_test_config_mac.h	2017-09-07 13:19:06.823481813 -0400
-@@ -0,0 +1,27 @@
++++ gpu_test_expectations/gpu_test_config_mac.h	2017-10-30 14:44:19.000000000 -0400
+@@ -0,0 +1,24 @@
 +//
 +// Copyright 2015 The ANGLE Project Authors. All rights reserved.
 +// Use of this source code is governed by a BSD-style license that can be
 +// found in the LICENSE file.
 +//
 +// gpu_test_config_mac.h:
 +//   Helper functions for gpu_test_config that have to be compiled in ObjectiveC++
 +//
 +
 +#ifndef ANGLE_GPU_TEST_EXPECTATIONS_GPU_TEST_CONFIG_MAC_H_
 +#define ANGLE_GPU_TEST_EXPECTATIONS_GPU_TEST_CONFIG_MAC_H_
 +
 +#include "gpu_info.h"
 +
-+namespace base {
-+
-+class SysInfo
++namespace angle
 +{
-+  public:
-+    static void OperatingSystemVersionNumbers(int32_t *major_version,
-+                                              int32_t *minor_version,
-+                                              int32_t *bugfix_version);
-+};
 +
-+} // namespace base
++void GetOperatingSystemVersionNumbers(int32_t *major_version,
++                                      int32_t *minor_version,
++                                      int32_t *bugfix_version);
++
++} // namespace angle
 +
 +#endif // ANGLE_GPU_TEST_EXPECTATIONS_GPU_TEST_CONFIG_MAC_H_
 diff -u -rupN gpu_test_expectations_reverted/gpu_test_config_mac.mm gpu_test_expectations/gpu_test_config_mac.mm
 --- gpu_test_expectations_reverted/gpu_test_config_mac.mm	1969-12-31 19:00:00.000000000 -0500
-+++ gpu_test_expectations/gpu_test_config_mac.mm	2017-09-07 13:17:55.282894551 -0400
-@@ -0,0 +1,38 @@
++++ gpu_test_expectations/gpu_test_config_mac.mm	2017-10-30 14:31:32.000000000 -0400
+@@ -0,0 +1,49 @@
 +// Copyright (c) 2012 The Chromium Authors. All rights reserved.
 +// Use of this source code is governed by a BSD-style license that can be
 +// found in the LICENSE file.
 +
 +// gpu_test_config_mac.mm:
 +//   Helper functions for gpu_test_config that have to be compiled in ObjectiveC++
 +
 +#include "gpu_test_config_mac.h"
 +
 +#import <Cocoa/Cocoa.h>
 +
-+namespace base {
-+
 +// OSX 10.8 deprecates Gestalt but doesn't make the operatingSystemVersion property part of the
 +// public interface of NSProcessInfo until 10.10. Add a forward declaration.
 +#if !defined(MAC_OS_X_VERSION_10_10) || MAC_OS_X_VERSION_MIN_REQUIRED < MAC_OS_X_VERSION_10_10
 +@interface NSProcessInfo (YosemiteSDK)
 +@property(readonly) NSOperatingSystemVersion operatingSystemVersion;
 +@end
 +#endif
 +
-+void SysInfo::OperatingSystemVersionNumbers(int32_t *major_version,
-+                                            int32_t *minor_version,
-+                                            int32_t *bugfix_version)
++namespace angle
++{
++
++void GetOperatingSystemVersionNumbers(int32_t *major_version,
++                                      int32_t *minor_version,
++                                      int32_t *bugfix_version)
 +{
 +#if MAC_OS_X_VERSION_MIN_REQUIRED < MAC_OS_X_VERSION_10_8
-+  Gestalt(gestaltSystemVersionMajor, reinterpret_cast<SInt32*>(major_version));
-+  Gestalt(gestaltSystemVersionMinor, reinterpret_cast<SInt32*>(minor_version));
-+  Gestalt(gestaltSystemVersionBugFix, reinterpret_cast<SInt32*>(bugfix_version));
++    Gestalt(gestaltSystemVersionMajor, reinterpret_cast<SInt32 *>(major_version));
++    Gestalt(gestaltSystemVersionMinor, reinterpret_cast<SInt32 *>(minor_version));
++    Gestalt(gestaltSystemVersionBugFix, reinterpret_cast<SInt32 *>(bugfix_version));
 +#else
-+  NSOperatingSystemVersion version = [[NSProcessInfo processInfo] operatingSystemVersion];
-+  *major_version = version.majorVersion;
-+  *minor_version = version.minorVersion;
-+  *bugfix_version = version.patchVersion;
++    if (@available(macOS 10.10, *))
++    {
++        NSOperatingSystemVersion version = [[NSProcessInfo processInfo] operatingSystemVersion];
++        *major_version                   = version.majorVersion;
++        *minor_version                   = version.minorVersion;
++        *bugfix_version                  = version.patchVersion;
++    }
++    else
++    {
++        // This can only happen on 10.9
++        *major_version  = 10;
++        *minor_version  = 9;
++        *bugfix_version = 0;
++    }
 +#endif
 +}
 +
-+} // namespace base
++} // namespace angle
 diff -u -rupN gpu_test_expectations_reverted/gpu_test_expectations_parser.cc gpu_test_expectations/gpu_test_expectations_parser.cc
---- gpu_test_expectations_reverted/gpu_test_expectations_parser.cc	2017-09-06 11:43:34.317460444 -0400
-+++ gpu_test_expectations/gpu_test_expectations_parser.cc	2017-09-07 13:17:55.282894551 -0400
+--- gpu_test_expectations_reverted/gpu_test_expectations_parser.cc	2017-10-30 14:30:35.000000000 -0400
++++ gpu_test_expectations/gpu_test_expectations_parser.cc	2017-10-27 13:46:39.000000000 -0400
 @@ -2,17 +2,47 @@
  // Use of this source code is governed by a BSD-style license that can be
  // found in the LICENSE file.
  
 -#include "gpu/config/gpu_test_expectations_parser.h"
 +#include "gpu_test_expectations_parser.h"
  
  #include <stddef.h>
@@ -396,40 +440,40 @@ diff -u -rupN gpu_test_expectations_reve
 +}
 +
 +} // anonymous namespace
 +
 +} // namespace base
  
  namespace gpu {
  
-@@ -151,9 +181,9 @@ const char* kErrorMessage[] = {
+@@ -153,9 +183,9 @@ const char* kErrorMessage[] = {
  };
  
  Token ParseToken(const std::string& word) {
 -  if (base::StartsWith(word, "//", base::CompareCase::INSENSITIVE_ASCII))
 +  if (base::StartsWithASCII(word, "//", false))
      return kTokenComment;
 -  if (base::StartsWith(word, "0x", base::CompareCase::INSENSITIVE_ASCII))
 +  if (base::StartsWithASCII(word, "0x", false))
      return kConfigGPUDeviceID;
  
    for (int32_t i = 0; i < kNumberOfExactMatchTokens; ++i) {
-@@ -209,8 +239,8 @@ bool GPUTestExpectationsParser::LoadTest
+@@ -211,8 +241,8 @@ bool GPUTestExpectationsParser::LoadTest
    return rt;
  }
  
 -bool GPUTestExpectationsParser::LoadTestExpectations(
 -    const base::FilePath& path) {
 +bool GPUTestExpectationsParser::LoadTestExpectationsFromFile(
 +    const std::string& path) {
    entries_.clear();
    error_messages_.clear();
  
-@@ -537,20 +567,17 @@ bool GPUTestExpectationsParser::DetectCo
+@@ -542,20 +572,17 @@ bool GPUTestExpectationsParser::DetectCo
  
  void GPUTestExpectationsParser::PushErrorMessage(
      const std::string& message, size_t line_number) {
 -  error_messages_.push_back(
 -      base::StringPrintf("Line %d : %s",
 -                         static_cast<int>(line_number), message.c_str()));
 +  error_messages_.push_back("Line " + ToString(line_number) +
 +                            " : " + message.c_str());
@@ -446,18 +490,18 @@ diff -u -rupN gpu_test_expectations_reve
 -                         message.c_str()));
 +  error_messages_.push_back("Line " + ToString(entry1_line_number) +
 +                            " and " + ToString(entry2_line_number) +
 +                            " : " + message.c_str());
  }
  
  GPUTestExpectationsParser:: GPUTestExpectationEntry::GPUTestExpectationEntry()
 diff -u -rupN gpu_test_expectations_reverted/gpu_test_expectations_parser.h gpu_test_expectations/gpu_test_expectations_parser.h
---- gpu_test_expectations_reverted/gpu_test_expectations_parser.h	2017-09-06 11:43:37.229484701 -0400
-+++ gpu_test_expectations/gpu_test_expectations_parser.h	2017-09-07 13:19:27.383650602 -0400
+--- gpu_test_expectations_reverted/gpu_test_expectations_parser.h	2017-10-30 14:30:35.000000000 -0400
++++ gpu_test_expectations/gpu_test_expectations_parser.h	2017-09-11 17:18:07.000000000 -0400
 @@ -2,8 +2,8 @@
  // Use of this source code is governed by a BSD-style license that can be
  // found in the LICENSE file.
  
 -#ifndef GPU_CONFIG_GPU_TEST_EXPECTATIONS_PARSER_H_
 -#define GPU_CONFIG_GPU_TEST_EXPECTATIONS_PARSER_H_
 +#ifndef ANGLE_GPU_CONFIG_GPU_TEST_EXPECTATIONS_PARSER_H_
 +#define ANGLE_GPU_CONFIG_GPU_TEST_EXPECTATIONS_PARSER_H_
@@ -487,34 +531,8 @@ diff -u -rupN gpu_test_expectations_reve
    const std::vector<std::string>& GetErrorMessages() const;
 @@ -87,5 +86,5 @@ class GPU_EXPORT GPUTestExpectationsPars
  
  }  // namespace gpu
  
 -#endif  // GPU_CONFIG_GPU_TEST_EXPECTATIONS_PARSER_H_
 +#endif  // ANGLE_GPU_CONFIG_GPU_TEST_EXPECTATIONS_PARSER_H_
  
-diff -u -rupN gpu_test_expectations_reverted/HowToMakeChanges.md gpu_test_expectations/HowToMakeChanges.md
---- gpu_test_expectations_reverted/HowToMakeChanges.md	1969-12-31 19:00:00.000000000 -0500
-+++ gpu_test_expectations/HowToMakeChanges.md	2017-09-06 11:40:47.432070186 -0400
-@@ -0,0 +1,22 @@
-+Because the ```gpu_test_expectations``` directory is based on parts of Chromium's ```gpu/config```
-+directory, we want to keep a patch of the changes added to make it compile with ANGLE. This
-+will allow us to merge Chromium changes easily in our ```gpu_test_expectations```.
-+
-+In order to make a change to this directory, do the following:
-+
-+ * copy the directory somewhere like in ```gpu_test_expectations_reverted```
-+ * in ```gpu_test_expectations_reverted``` run ```patch -p 1 -R < angle-mods.patch```
-+ * do your changes in ```gpu_test_expectations```
-+ * delete angle-mods.patch in both directories
-+ * run ```diff -rupN gpu_test_expectations_reverted gpu_test_expectations > angle-mods.patch```
-+ * copy ```angle-mods.patch``` in ```gpu_test_expectations```
-+
-+How to update from Chromium:
-+
-+ * ```git apply -R angle-mods.patch```, ```git add . -u```, ```git commit```
-+ * Copy over Chromium files, ```git add . -u```, ```git commit```
-+ * ```git revert HEAD~```
-+ * ```rm angle-mods.patch```
-+ * ```git diff HEAD~ (`)ls(`) > angle-mods.patch```,```git add angle-mods.patch```, ```git commit --amend```
-+ * ```git rebase -i``` to squash the three patches into one.
-+
--- a/gfx/angle/src/tests/third_party/gpu_test_expectations/gpu_info.cc
+++ b/gfx/angle/src/tests/third_party/gpu_test_expectations/gpu_info.cc
@@ -129,17 +129,16 @@ void GPUInfo::EnumerateFields(Enumerator
     uint32_t gl_reset_notification_strategy;
     bool software_rendering;
     bool direct_rendering;
     bool sandboxed;
     int process_crash_count;
     bool in_process_gpu;
     bool passthrough_cmd_decoder;
     bool supports_overlays;
-    bool hdr;
     bool can_support_threaded_texture_mailbox;
     CollectInfoResult basic_info_state;
     CollectInfoResult context_info_state;
 #if defined(OS_WIN)
     CollectInfoResult dx_diagnostics_info_state;
     DxDiagNode dx_diagnostics;
 #endif
     VideoDecodeAcceleratorCapabilities video_decode_accelerator_capabilities;
@@ -190,17 +189,16 @@ void GPUInfo::EnumerateFields(Enumerator
   // TODO(kbr): add performance_stats.
   enumerator->AddBool("softwareRendering", software_rendering);
   enumerator->AddBool("directRendering", direct_rendering);
   enumerator->AddBool("sandboxed", sandboxed);
   enumerator->AddInt("processCrashCount", process_crash_count);
   enumerator->AddBool("inProcessGpu", in_process_gpu);
   enumerator->AddBool("passthroughCmdDecoder", passthrough_cmd_decoder);
   enumerator->AddBool("supportsOverlays", supports_overlays);
-  enumerator->AddBool("hdr", hdr);
   enumerator->AddBool("canSupportThreadedTextureMailbox",
                       can_support_threaded_texture_mailbox);
   enumerator->AddInt("basicInfoState", basic_info_state);
   enumerator->AddInt("contextInfoState", context_info_state);
 #if defined(OS_WIN)
   enumerator->AddInt("DxDiagnosticsInfoState", dx_diagnostics_info_state);
 #endif
   // TODO(kbr): add dx_diagnostics on Windows.
--- a/gfx/angle/src/tests/third_party/gpu_test_expectations/gpu_info.h
+++ b/gfx/angle/src/tests/third_party/gpu_test_expectations/gpu_info.h
@@ -56,17 +56,18 @@ enum VideoCodecProfile {
   VP9PROFILE_PROFILE3,
   HEVCPROFILE_MAIN,
   HEVCPROFILE_MAIN10,
   HEVCPROFILE_MAIN_STILL_PICTURE,
   DOLBYVISION_PROFILE0,
   DOLBYVISION_PROFILE4,
   DOLBYVISION_PROFILE5,
   DOLBYVISION_PROFILE7,
-  VIDEO_CODEC_PROFILE_MAX = DOLBYVISION_PROFILE7,
+  THEORAPROFILE_ANY,
+  VIDEO_CODEC_PROFILE_MAX = THEORAPROFILE_ANY,
 };
 
 // Specification of a decoding profile supported by a hardware decoder.
 struct GPU_EXPORT VideoDecodeAcceleratorSupportedProfile {
   VideoCodecProfile profile;
   gfx::Size max_resolution;
   gfx::Size min_resolution;
   bool encrypted_only;
@@ -213,19 +214,16 @@ struct GPU_EXPORT GPUInfo {
   bool in_process_gpu;
 
   // True if the GPU process is using the passthrough command decoder.
   bool passthrough_cmd_decoder;
 
   // True if the current set of outputs supports overlays.
   bool supports_overlays = false;
 
-  // True if the current set of outputs supports HDR.
-  bool hdr = false;
-
   // True only on android when extensions for threaded mailbox sharing are
   // present. Threaded mailbox sharing is used on Android only, so this check
   // is only implemented on Android.
   bool can_support_threaded_texture_mailbox = false;
 
   // The state of whether the basic/context/DxDiagnostics info is collected and
   // if the collection fails or not.
   CollectInfoResult basic_info_state;
--- a/gfx/angle/src/tests/third_party/gpu_test_expectations/gpu_test_config.cc
+++ b/gfx/angle/src/tests/third_party/gpu_test_expectations/gpu_test_config.cc
@@ -73,18 +73,17 @@ GPUTestConfig::OS GetCurrentOS() {
   if (major_version == 6 && (minor_version == 2 || minor_version == 3))
     return GPUTestConfig::kOsWin8;
   if (major_version == 10)
     return GPUTestConfig::kOsWin10;
 #elif defined(OS_MACOSX)
   int32_t major_version = 0;
   int32_t minor_version = 0;
   int32_t bugfix_version = 0;
-  base::SysInfo::OperatingSystemVersionNumbers(
-      &major_version, &minor_version, &bugfix_version);
+  angle::GetOperatingSystemVersionNumbers(&major_version, &minor_version, &bugfix_version);
   if (major_version == 10) {
     switch (minor_version) {
       case 5:
         return GPUTestConfig::kOsMacLeopard;
       case 6:
         return GPUTestConfig::kOsMacSnowLeopard;
       case 7:
         return GPUTestConfig::kOsMacLion;
@@ -93,16 +92,18 @@ GPUTestConfig::OS GetCurrentOS() {
       case 9:
         return GPUTestConfig::kOsMacMavericks;
       case 10:
         return GPUTestConfig::kOsMacYosemite;
       case 11:
         return GPUTestConfig::kOsMacElCapitan;
       case 12:
         return GPUTestConfig::kOsMacSierra;
+      case 13:
+        return GPUTestConfig::kOsMacHighSierra;
     }
   }
 #elif defined(OS_ANDROID)
   return GPUTestConfig::kOsAndroid;
 #endif
   return GPUTestConfig::kOsUnknown;
 }
 
@@ -239,16 +240,17 @@ bool GPUTestBotConfig::IsValid() const {
     case kOsMacLeopard:
     case kOsMacSnowLeopard:
     case kOsMacLion:
     case kOsMacMountainLion:
     case kOsMacMavericks:
     case kOsMacYosemite:
     case kOsMacElCapitan:
     case kOsMacSierra:
+    case kOsMacHighSierra:
     case kOsLinux:
     case kOsChromeOS:
     case kOsAndroid:
       break;
     default:
       return false;
   }
   if (validate_gpu_info_) {
@@ -270,17 +272,17 @@ bool GPUTestBotConfig::IsValid() const {
 bool GPUTestBotConfig::Matches(const GPUTestConfig& config) const {
   DCHECK(IsValid());
   DCHECK(config.IsValid());
   if (config.os() != kOsUnknown && (os() & config.os()) == 0)
     return false;
   if (config.gpu_vendor().size() > 0) {
     bool contained = false;
     for (size_t i = 0; i < config.gpu_vendor().size(); ++i) {
-      if (config.gpu_vendor()[i] == gpu_vendor()[0]) {
+      if (!gpu_vendor().empty() && config.gpu_vendor()[i] == gpu_vendor()[0]) {
         contained = true;
         break;
       }
     }
     if (!contained)
       return false;
   }
   if (config.gpu_device_id() != 0 &&
--- a/gfx/angle/src/tests/third_party/gpu_test_expectations/gpu_test_config.h
+++ b/gfx/angle/src/tests/third_party/gpu_test_expectations/gpu_test_config.h
@@ -27,23 +27,24 @@ class GPU_EXPORT GPUTestConfig {
     kOsMacLeopard = 1 << 4,
     kOsMacSnowLeopard = 1 << 5,
     kOsMacLion = 1 << 6,
     kOsMacMountainLion = 1 << 7,
     kOsMacMavericks = 1 << 8,
     kOsMacYosemite = 1 << 9,
     kOsMacElCapitan = 1 << 10,
     kOsMacSierra = 1 << 11,
+    kOsMacHighSierra = 1 << 12,
     kOsMac = kOsMacLeopard | kOsMacSnowLeopard | kOsMacLion |
              kOsMacMountainLion | kOsMacMavericks | kOsMacYosemite |
-             kOsMacElCapitan | kOsMacSierra,
-    kOsLinux = 1 << 12,
-    kOsChromeOS = 1 << 13,
-    kOsAndroid = 1 << 14,
-    kOsWin10 = 1 << 15,
+             kOsMacElCapitan | kOsMacSierra | kOsMacHighSierra,
+    kOsLinux = 1 << 13,
+    kOsChromeOS = 1 << 14,
+    kOsAndroid = 1 << 15,
+    kOsWin10 = 1 << 16,
     kOsWin = kOsWinXP | kOsWinVista | kOsWin7 | kOsWin8 | kOsWin10,
   };
 
   enum BuildType {
     kBuildTypeUnknown = 0,
     kBuildTypeRelease = 1 << 0,
     kBuildTypeDebug = 1 << 1,
   };
--- a/gfx/angle/src/tests/third_party/gpu_test_expectations/gpu_test_config_mac.h
+++ b/gfx/angle/src/tests/third_party/gpu_test_expectations/gpu_test_config_mac.h
@@ -7,21 +7,18 @@
 //   Helper functions for gpu_test_config that have to be compiled in ObjectiveC++
 //
 
 #ifndef ANGLE_GPU_TEST_EXPECTATIONS_GPU_TEST_CONFIG_MAC_H_
 #define ANGLE_GPU_TEST_EXPECTATIONS_GPU_TEST_CONFIG_MAC_H_
 
 #include "gpu_info.h"
 
-namespace base {
-
-class SysInfo
+namespace angle
 {
-  public:
-    static void OperatingSystemVersionNumbers(int32_t *major_version,
-                                              int32_t *minor_version,
-                                              int32_t *bugfix_version);
-};
 
-} // namespace base
+void GetOperatingSystemVersionNumbers(int32_t *major_version,
+                                      int32_t *minor_version,
+                                      int32_t *bugfix_version);
+
+} // namespace angle
 
 #endif // ANGLE_GPU_TEST_EXPECTATIONS_GPU_TEST_CONFIG_MAC_H_
--- a/gfx/angle/src/tests/third_party/gpu_test_expectations/gpu_test_config_mac.mm
+++ b/gfx/angle/src/tests/third_party/gpu_test_expectations/gpu_test_config_mac.mm
@@ -4,35 +4,46 @@
 
 // gpu_test_config_mac.mm:
 //   Helper functions for gpu_test_config that have to be compiled in ObjectiveC++
 
 #include "gpu_test_config_mac.h"
 
 #import <Cocoa/Cocoa.h>
 
-namespace base {
-
 // OSX 10.8 deprecates Gestalt but doesn't make the operatingSystemVersion property part of the
 // public interface of NSProcessInfo until 10.10. Add a forward declaration.
 #if !defined(MAC_OS_X_VERSION_10_10) || MAC_OS_X_VERSION_MIN_REQUIRED < MAC_OS_X_VERSION_10_10
 @interface NSProcessInfo (YosemiteSDK)
 @property(readonly) NSOperatingSystemVersion operatingSystemVersion;
 @end
 #endif
 
-void SysInfo::OperatingSystemVersionNumbers(int32_t *major_version,
-                                            int32_t *minor_version,
-                                            int32_t *bugfix_version)
+namespace angle
+{
+
+void GetOperatingSystemVersionNumbers(int32_t *major_version,
+                                      int32_t *minor_version,
+                                      int32_t *bugfix_version)
 {
 #if MAC_OS_X_VERSION_MIN_REQUIRED < MAC_OS_X_VERSION_10_8
-  Gestalt(gestaltSystemVersionMajor, reinterpret_cast<SInt32*>(major_version));
-  Gestalt(gestaltSystemVersionMinor, reinterpret_cast<SInt32*>(minor_version));
-  Gestalt(gestaltSystemVersionBugFix, reinterpret_cast<SInt32*>(bugfix_version));
+    Gestalt(gestaltSystemVersionMajor, reinterpret_cast<SInt32 *>(major_version));
+    Gestalt(gestaltSystemVersionMinor, reinterpret_cast<SInt32 *>(minor_version));
+    Gestalt(gestaltSystemVersionBugFix, reinterpret_cast<SInt32 *>(bugfix_version));
 #else
-  NSOperatingSystemVersion version = [[NSProcessInfo processInfo] operatingSystemVersion];
-  *major_version = version.majorVersion;
-  *minor_version = version.minorVersion;
-  *bugfix_version = version.patchVersion;
+    if (@available(macOS 10.10, *))
+    {
+        NSOperatingSystemVersion version = [[NSProcessInfo processInfo] operatingSystemVersion];
+        *major_version                   = version.majorVersion;
+        *minor_version                   = version.minorVersion;
+        *bugfix_version                  = version.patchVersion;
+    }
+    else
+    {
+        // This can only happen on 10.9
+        *major_version  = 10;
+        *minor_version  = 9;
+        *bugfix_version = 0;
+    }
 #endif
 }
 
-} // namespace base
+} // namespace angle
--- a/gfx/angle/src/tests/third_party/gpu_test_expectations/gpu_test_expectations_parser.cc
+++ b/gfx/angle/src/tests/third_party/gpu_test_expectations/gpu_test_expectations_parser.cc
@@ -69,16 +69,17 @@ enum Token {
   kConfigMacLeopard,
   kConfigMacSnowLeopard,
   kConfigMacLion,
   kConfigMacMountainLion,
   kConfigMacMavericks,
   kConfigMacYosemite,
   kConfigMacElCapitan,
   kConfigMacSierra,
+  kConfigMacHighSierra,
   kConfigMac,
   kConfigLinux,
   kConfigChromeOS,
   kConfigAndroid,
   // gpu vendor
   kConfigNVidia,
   kConfigAMD,
   kConfigIntel,
@@ -124,16 +125,17 @@ const TokenInfo kTokenData[] = {
     {"leopard", GPUTestConfig::kOsMacLeopard},
     {"snowleopard", GPUTestConfig::kOsMacSnowLeopard},
     {"lion", GPUTestConfig::kOsMacLion},
     {"mountainlion", GPUTestConfig::kOsMacMountainLion},
     {"mavericks", GPUTestConfig::kOsMacMavericks},
     {"yosemite", GPUTestConfig::kOsMacYosemite},
     {"elcapitan", GPUTestConfig::kOsMacElCapitan},
     {"sierra", GPUTestConfig::kOsMacSierra},
+    {"highsierra", GPUTestConfig::kOsMacHighSierra},
     {"mac", GPUTestConfig::kOsMac},
     {"linux", GPUTestConfig::kOsLinux},
     {"chromeos", GPUTestConfig::kOsChromeOS},
     {"android", GPUTestConfig::kOsAndroid},
     {"nvidia", 0x10DE},
     {"amd", 0x1002},
     {"intel", 0x8086},
     {"vmware", 0x15ad},
@@ -287,16 +289,17 @@ bool GPUTestExpectationsParser::ParseCon
       case kConfigMacLeopard:
       case kConfigMacSnowLeopard:
       case kConfigMacLion:
       case kConfigMacMountainLion:
       case kConfigMacMavericks:
       case kConfigMacYosemite:
       case kConfigMacElCapitan:
       case kConfigMacSierra:
+      case kConfigMacHighSierra:
       case kConfigMac:
       case kConfigLinux:
       case kConfigChromeOS:
       case kConfigAndroid:
       case kConfigNVidia:
       case kConfigAMD:
       case kConfigIntel:
       case kConfigVMWare:
@@ -347,16 +350,17 @@ bool GPUTestExpectationsParser::ParseLin
       case kConfigMacLeopard:
       case kConfigMacSnowLeopard:
       case kConfigMacLion:
       case kConfigMacMountainLion:
       case kConfigMacMavericks:
       case kConfigMacYosemite:
       case kConfigMacElCapitan:
       case kConfigMacSierra:
+      case kConfigMacHighSierra:
       case kConfigMac:
       case kConfigLinux:
       case kConfigChromeOS:
       case kConfigAndroid:
       case kConfigNVidia:
       case kConfigAMD:
       case kConfigIntel:
       case kConfigVMWare:
@@ -470,16 +474,17 @@ bool GPUTestExpectationsParser::UpdateTe
     case kConfigMacLeopard:
     case kConfigMacSnowLeopard:
     case kConfigMacLion:
     case kConfigMacMountainLion:
     case kConfigMacMavericks:
     case kConfigMacYosemite:
     case kConfigMacElCapitan:
     case kConfigMacSierra:
+    case kConfigMacHighSierra:
     case kConfigMac:
     case kConfigLinux:
     case kConfigChromeOS:
     case kConfigAndroid:
       if ((config->os() & kTokenData[token].flag) != 0) {
         PushErrorMessage(kErrorMessage[kErrorEntryWithOsConflicts],
                          line_number);
         return false;
--- a/gfx/angle/src/vulkan_support/BUILD.gn
+++ b/gfx/angle/src/vulkan_support/BUILD.gn
@@ -1,87 +1,83 @@
 # 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.
 
 # TODO(jmadill): Redo the file entirely when we have standalone GN ANGLE.
 
-third_party_dir = "../../../../third_party"
+import("../../gni/angle.gni")
+
+if (build_with_chromium) {
+  third_party_dir = "../../../../third_party"
+} else {
+  third_party_dir = "../../third_party"
+}
+
 glslang_dir = "$third_party_dir/glslang-angle/src"
 spirv_headers_dir = "$third_party_dir/spirv-headers/src"
 spirv_tools_dir = "$third_party_dir/spirv-tools-angle/src"
 vulkan_layers_dir = "$third_party_dir/vulkan-validation-layers/src"
 raw_vulkan_layers_dir = rebase_path(vulkan_layers_dir, root_build_dir)
 
-vulkan_gypi =
-    exec_script("//build/gypi_to_gn.py",
-                [
-                  rebase_path("vulkan.gypi"),
-                  "--replace=<(angle_gen_path)=$target_gen_dir/angle",
-                  "--replace=<(glslang_path)=../$glslang_dir",
-                  "--replace=<(spirv_headers_path)=../$spirv_headers_dir",
-                  "--replace=<(spirv_tools_path)=../$spirv_tools_dir",
-                  "--replace=<(vulkan_layers_path)=../$vulkan_layers_dir",
-                ],
-                "scope",
-                [ "vulkan.gypi" ])
-
 # Subdirectory to place data files (e.g. layer JSON files).
 data_dir = "angledata"
 
-vulkan_gen_json_files_outputs = [
-  "$root_out_dir/$data_dir/VkLayer_core_validation.json",
-  "$root_out_dir/$data_dir/VkLayer_object_tracker.json",
-  "$root_out_dir/$data_dir/VkLayer_parameter_validation.json",
-  "$root_out_dir/$data_dir/VkLayer_swapchain.json",
-  "$root_out_dir/$data_dir/VkLayer_threading.json",
-  "$root_out_dir/$data_dir/VkLayer_unique_objects.json",
-]
-
 vulkan_undefine_configs = []
 if (is_win) {
   vulkan_undefine_configs += [
     "//build/config/win:nominmax",
     "//build/config/win:unicode",
   ]
 }
 
 vulkan_gen_dir = "$target_gen_dir/angle/vulkan"
 raw_vulkan_gen_dir = rebase_path(vulkan_gen_dir, root_build_dir)
+raw_spirv_tools_dir = rebase_path(spirv_tools_dir, root_build_dir)
 
 # Vulkan helper scripts
 # ---------------------
 
 helper_script_and_deps = [
   [
     "vulkan_gen_dispatch_table_helper_h",
     "vk_dispatch_table_helper.h",
     "dispatch_table_helper_generator.py",
   ],
   [
     "vulkan_gen_enum_string_helper",
     "vk_enum_string_helper.h",
     "helper_file_generator.py",
   ],
   [
+    "vulkan_gen_extension_helper",
+    "vk_extension_helper.h",
+    "helper_file_generator.py",
+  ],
+  [
     "vulkan_gen_layer_dispatch_table_h",
     "vk_layer_dispatch_table.h",
     "loader_extension_generator.py",
   ],
   [
     "vulkan_gen_loader_extensions_c",
     "vk_loader_extensions.c",
     "loader_extension_generator.py",
   ],
   [
     "vulkan_gen_loader_extensions_h",
     "vk_loader_extensions.h",
     "loader_extension_generator.py",
   ],
   [
+    "vulkan_gen_object_types_h",
+    "vk_object_types.h",
+    "helper_file_generator.py",
+  ],
+  [
     "vulkan_gen_safe_struct_cpp",
     "vk_safe_struct.cpp",
     "helper_file_generator.py",
   ],
   [
     "vulkan_gen_safe_struct_h",
     "vk_safe_struct.h",
     "helper_file_generator.py",
@@ -97,18 +93,28 @@ helper_script_and_deps = [
     "helper_file_generator.py",
   ],
   [
     "vulkan_gen_thread_check_helper",
     "thread_check.h",
     "threading_generator.py",
   ],
   [
-    "vulkan_gen_parameter_validation_helper",
-    "parameter_validation.h",
+    "vulkan_gen_typemap_helper",
+    "vk_typemap_helper.h",
+    "helper_file_generator.py",
+  ],
+  [
+    "vulkan_gen_object_tracker_cpp",
+    "object_tracker.cpp",
+    "object_tracker_generator.py",
+  ],
+  [
+    "vulkan_gen_parameter_validation_cpp",
+    "parameter_validation.cpp",
     "parameter_validation_generator.py",
   ],
   [
     "vulkan_gen_unique_objects_wrappers_helper",
     "unique_objects_wrappers.h",
     "unique_objects_generator.py",
   ],
 ]
@@ -134,25 +140,63 @@ foreach(script_and_dep, helper_script_an
       "-registry",
       "$raw_vulkan_layers_dir/scripts/vk.xml",
       "$file",
       "-quiet",
     ]
   }
 }
 
+spirv_git_is_present = exec_script("$angle_root/src/commit_id.py",
+                                   [
+                                     "check",
+                                     raw_spirv_tools_dir,
+                                   ],
+                                   "value")
+
+spirv_use_commit_id = spirv_git_is_present == 1
+
+if (spirv_use_commit_id) {
+  # This could be generalized to a foreach if other revisions are added.
+  action("spirv_tools_external_revision_generate") {
+    script = "$vulkan_layers_dir/scripts/external_revision_generator.py"
+    inputs = [
+      "$angle_root/DEPS",
+    ]
+    outputs = [
+      "$vulkan_gen_dir/spirv_tools_commit_id.h",
+    ]
+    args = [
+      "$raw_spirv_tools_dir",
+      "SPIRV_TOOLS_COMMIT_ID",
+      "$raw_vulkan_gen_dir/spirv_tools_commit_id.h",
+    ]
+  }
+} else {
+  copy("spirv_tools_external_revision_generate") {
+    sources = [
+      "dummy_spirv_tools_commit_id.h",
+    ]
+    outputs = [
+      "$vulkan_gen_dir/spirv_tools_commit_id.h",
+    ]
+  }
+}
+
 config("vulkan_generate_helper_files_config") {
   include_dirs = [
     vulkan_gen_dir,
     "$vulkan_layers_dir/include",
   ]
 }
 
 group("vulkan_generate_helper_files") {
-  public_deps = []
+  public_deps = [
+    ":spirv_tools_external_revision_generate",
+  ]
   public_configs = [ ":vulkan_generate_helper_files_config" ]
   foreach(script_and_dep, helper_script_and_deps) {
     target_name = script_and_dep[0]
     public_deps += [ ":$target_name" ]
   }
 }
 
 config("vulkan_config") {
@@ -187,38 +231,76 @@ config("vulkan_internal_config") {
     ]
   }
 }
 
 # Vulkan loader
 # -------------
 
 config("vulkan_loader_config") {
-  include_dirs = rebase_path(vulkan_gypi.vulkan_loader_include_dirs, ".", "src")
-  include_dirs += [ vulkan_gen_dir ]
+  include_dirs = [
+    vulkan_gen_dir,
+    "$vulkan_layers_dir/include",
+    "$vulkan_layers_dir/loader",
+  ]
   defines = [
     "ANGLE_VK_LAYERS_DIR=\"$data_dir\"",
     "API_NAME=\"Vulkan\"",
   ]
 
   if (is_win) {
     cflags = [ "/wd4201" ]
   }
   if (is_linux) {
     # assume secure_getenv() is available
     defines += [ "HAVE_SECURE_GETENV" ]
   }
 }
 
 static_library("vulkan_loader") {
-  sources = rebase_path(vulkan_gypi.vulkan_loader_sources, ".", "src")
+  sources = [
+    "$vulkan_layers_dir/loader/cJSON.c",
+    "$vulkan_layers_dir/loader/cJSON.h",
+    "$vulkan_layers_dir/loader/debug_report.c",
+    "$vulkan_layers_dir/loader/debug_report.h",
+    "$vulkan_layers_dir/loader/dev_ext_trampoline.c",
+    "$vulkan_layers_dir/loader/extension_manual.c",
+    "$vulkan_layers_dir/loader/extension_manual.h",
+    "$vulkan_layers_dir/loader/gpa_helper.h",
+    "$vulkan_layers_dir/loader/loader.c",
+    "$vulkan_layers_dir/loader/loader.h",
+    "$vulkan_layers_dir/loader/murmurhash.c",
+    "$vulkan_layers_dir/loader/murmurhash.h",
+    "$vulkan_layers_dir/loader/phys_dev_ext.c",
+    "$vulkan_layers_dir/loader/trampoline.c",
+
+    # TODO(jmadill): Use assembler where available.
+    "$vulkan_layers_dir/loader/unknown_ext_chain.c",
+    "$vulkan_layers_dir/loader/vk_loader_platform.h",
+    "$vulkan_layers_dir/loader/wsi.c",
+    "$vulkan_layers_dir/loader/wsi.h",
+  ]
   if (is_win) {
-    sources += rebase_path(vulkan_gypi.vulkan_loader_win_sources, ".", "src")
+    sources += [
+      "$vulkan_layers_dir/loader/dirent_on_windows.c",
+      "$vulkan_layers_dir/loader/dirent_on_windows.h",
+    ]
     if (!is_clang) {
-      cflags = vulkan_gypi.vulkan_loader_cflags_win
+      cflags = [
+        "/wd4054",  # Type cast from function pointer
+        "/wd4055",  # Type cast from data pointer
+        "/wd4100",  # Unreferenced formal parameter
+        "/wd4152",  # Nonstandard extension used (pointer conversion)
+        "/wd4201",  # Nonstandard extension used: nameless struct/union
+        "/wd4214",  # Nonstandard extension used: bit field types other than int
+        "/wd4232",  # Nonstandard extension used: address of dllimport is not static
+        "/wd4305",  # Type cast truncation
+        "/wd4706",  # Assignment within conditional expression
+        "/wd4996",  # Unsafe stdlib function
+      ]
     }
   }
   deps = [
     ":vulkan_generate_helper_files",
   ]
   configs += [ ":vulkan_internal_config" ]
   public_configs = [
     ":vulkan_config",
@@ -231,53 +313,87 @@ static_library("vulkan_loader") {
 # -----------
 
 spirv_source_dir = "$spirv_tools_dir/source"
 spirv_include_dir = "$spirv_headers_dir/include/spirv"
 raw_spirv_source_dir = rebase_path(spirv_source_dir, root_build_dir)
 raw_spirv_include_dir = rebase_path(spirv_include_dir, root_build_dir)
 raw_spirv_headers_dir = rebase_path(spirv_headers_dir, root_build_dir)
 
-action("spirv_tools_gen_tables_1_0") {
-  script = "$spirv_tools_dir/utils/generate_grammar_tables.py"
+grammar_processing_script = "$spirv_tools_dir/utils/generate_grammar_tables.py"
+
+action("spirv_tools_gen_enum_string_mapping") {
+  script = grammar_processing_script
+  sources = [
+    "$spirv_include_dir/1.2/spirv.core.grammar.json",
+  ]
+  outputs = [
+    "$vulkan_gen_dir/extension_enum.inc",
+    "$vulkan_gen_dir/enum_string_mapping.inc",
+  ]
+  args = [
+    "--spirv-core-grammar=$raw_spirv_include_dir/1.2/spirv.core.grammar.json",
+    "--extension-enum-output=$raw_vulkan_gen_dir/extension_enum.inc",
+    "--enum-string-mapping-output=$raw_vulkan_gen_dir/enum_string_mapping.inc",
+  ]
+}
+
+spvtools_core_tables = [
+  "1.0",
+  "1.1",
+  "1.2",
+]
+
+foreach(version, spvtools_core_tables) {
+  action("spirv_tools_gen_core_tables_" + version) {
+    script = grammar_processing_script
+    sources = [
+      "$spirv_include_dir/$version/spirv.core.grammar.json",
+    ]
+    outputs = [
+      "$vulkan_gen_dir/core.insts-$version.inc",
+      "$vulkan_gen_dir/operand.kinds-$version.inc",
+    ]
+    args = [
+      "--spirv-core-grammar=$raw_spirv_include_dir/$version/spirv.core.grammar.json",
+      "--core-insts-output=$raw_vulkan_gen_dir/core.insts-$version.inc",
+      "--operand-kinds-output=$raw_vulkan_gen_dir/operand.kinds-$version.inc",
+    ]
+  }
+}
+
+action("spirv_tools_gen_glsl_tables") {
+  script = grammar_processing_script
   sources = [
     "$spirv_include_dir/1.0/extinst.glsl.std.450.grammar.json",
     "$spirv_include_dir/1.0/spirv.core.grammar.json",
-    "$spirv_source_dir/extinst-1.0.opencl.std.grammar.json",
   ]
   outputs = [
-    "$vulkan_gen_dir/core.insts-1.0.inc",
     "$vulkan_gen_dir/glsl.std.450.insts-1.0.inc",
-    "$vulkan_gen_dir/opencl.std.insts-1.0.inc",
-    "$vulkan_gen_dir/operand.kinds-1.0.inc",
   ]
   args = [
     "--spirv-core-grammar=$raw_spirv_include_dir/1.0/spirv.core.grammar.json",
     "--extinst-glsl-grammar=$raw_spirv_include_dir/1.0/extinst.glsl.std.450.grammar.json",
-    "--extinst-opencl-grammar=$raw_spirv_source_dir/extinst-1.0.opencl.std.grammar.json",
-    "--core-insts-output=$raw_vulkan_gen_dir/core.insts-1.0.inc",
     "--glsl-insts-output=$raw_vulkan_gen_dir/glsl.std.450.insts-1.0.inc",
-    "--opencl-insts-output=$raw_vulkan_gen_dir/opencl.std.insts-1.0.inc",
-    "--operand-kinds-output=$raw_vulkan_gen_dir/operand.kinds-1.0.inc",
   ]
 }
 
-action("spirv_tools_gen_tables_1_1") {
-  script = "$spirv_tools_dir/utils/generate_grammar_tables.py"
+action("spirv_tools_gen_opencl_tables") {
+  script = grammar_processing_script
   sources = [
-    "$spirv_include_dir/1.1/spirv.core.grammar.json",
+    "$spirv_include_dir/1.0/extinst.opencl.std.100.grammar.json",
+    "$spirv_include_dir/1.0/spirv.core.grammar.json",
   ]
   outputs = [
-    "$vulkan_gen_dir/core.insts-1.1.inc",
-    "$vulkan_gen_dir/operand.kinds-1.1.inc",
+    "$vulkan_gen_dir/opencl.std.insts-1.0.inc",
   ]
   args = [
-    "--spirv-core-grammar=$raw_spirv_include_dir/1.1/spirv.core.grammar.json",
-    "--core-insts-output=$raw_vulkan_gen_dir/core.insts-1.1.inc",
-    "--operand-kinds-output=$raw_vulkan_gen_dir/operand.kinds-1.1.inc",
+    "--spirv-core-grammar=$raw_spirv_include_dir/1.0/spirv.core.grammar.json",
+    "--extinst-opencl-grammar=$raw_spirv_include_dir/1.0/extinst.opencl.std.100.grammar.json",
+    "--opencl-insts-output=$raw_vulkan_gen_dir/opencl.std.insts-1.0.inc",
   ]
 }
 
 action("spirv_tools_gen_generators_inc") {
   script = "$spirv_tools_dir/utils/generate_registry_tables.py"
   sources = [
     "$spirv_headers_dir/include/spirv/spir-v.xml",
   ]
@@ -285,43 +401,152 @@ action("spirv_tools_gen_generators_inc")
     "$vulkan_gen_dir/generators.inc",
   ]
   args = [
     "--xml=$raw_spirv_headers_dir/include/spirv/spir-v.xml",
     "--generator-output=$raw_vulkan_gen_dir/generators.inc",
   ]
 }
 
+spvtools_vendor_tables = [
+  "spv-amd-shader-explicit-vertex-parameter",
+  "spv-amd-shader-trinary-minmax",
+  "spv-amd-gcn-shader",
+  "spv-amd-shader-ballot",
+]
+
+foreach(target_name, spvtools_vendor_tables) {
+  insts_file = "$target_name.insts.inc"
+  grammar_file = "extinst.$target_name.grammar.json"
+
+  action(target_name) {
+    script = grammar_processing_script
+
+    sources = [
+      "$spirv_source_dir/$grammar_file",
+    ]
+
+    outputs = [
+      "$vulkan_gen_dir/$insts_file",
+    ]
+
+    args = [
+      "--extinst-vendor-grammar=$raw_spirv_source_dir/$grammar_file",
+      "--vendor-insts-output=$raw_vulkan_gen_dir/$insts_file",
+    ]
+  }
+}
+
 config("spirv_tools_config") {
   include_dirs = [ "$spirv_tools_dir/include" ]
   if (is_win) {
     cflags = [
       "/wd4706",
 
       # These are triggered in higher optimization levels. Disable for now until
       # fixes are landed upstream. See https://crbug.com/677837.
       "/wd4701",
       "/wd4703",
     ]
   }
 }
 
 static_library("spirv_tools") {
   deps = [
+    ":spirv_tools_gen_core_tables_1.0",
+    ":spirv_tools_gen_core_tables_1.1",
+    ":spirv_tools_gen_core_tables_1.2",
+    ":spirv_tools_gen_enum_string_mapping",
     ":spirv_tools_gen_generators_inc",
-    ":spirv_tools_gen_tables_1_0",
-    ":spirv_tools_gen_tables_1_1",
+    ":spirv_tools_gen_glsl_tables",
+    ":spirv_tools_gen_opencl_tables",
   ]
   include_dirs = [
     vulkan_gen_dir,
     "$spirv_headers_dir/include",
     "$spirv_tools_dir/source",
   ]
-  sources = rebase_path(vulkan_gypi.spirv_tools_sources, ".", "src")
+  sources = [
+    "$spirv_tools_dir/source/assembly_grammar.cpp",
+    "$spirv_tools_dir/source/assembly_grammar.h",
+    "$spirv_tools_dir/source/binary.cpp",
+    "$spirv_tools_dir/source/binary.h",
+    "$spirv_tools_dir/source/diagnostic.cpp",
+    "$spirv_tools_dir/source/diagnostic.h",
+    "$spirv_tools_dir/source/disassemble.cpp",
+    "$spirv_tools_dir/source/enum_set.h",
+    "$spirv_tools_dir/source/ext_inst.cpp",
+    "$spirv_tools_dir/source/ext_inst.h",
+    "$spirv_tools_dir/source/instruction.h",
+    "$spirv_tools_dir/source/libspirv.cpp",
+    "$spirv_tools_dir/source/macro.h",
+    "$spirv_tools_dir/source/message.cpp",
+    "$spirv_tools_dir/source/name_mapper.cpp",
+    "$spirv_tools_dir/source/name_mapper.h",
+    "$spirv_tools_dir/source/opcode.cpp",
+    "$spirv_tools_dir/source/opcode.h",
+    "$spirv_tools_dir/source/operand.cpp",
+    "$spirv_tools_dir/source/operand.h",
+    "$spirv_tools_dir/source/parsed_operand.cpp",
+    "$spirv_tools_dir/source/parsed_operand.h",
+    "$spirv_tools_dir/source/print.cpp",
+    "$spirv_tools_dir/source/print.h",
+
+    # TODO(jmadill): Determine if this is ever needed.
+    #"$spirv_tools_dir/source/software_version.cpp",
+    "$spirv_tools_dir/source/enum_string_mapping.cpp",
+    "$spirv_tools_dir/source/extensions.cpp",
+    "$spirv_tools_dir/source/extensions.h",
+    "$spirv_tools_dir/source/spirv_constant.h",
+    "$spirv_tools_dir/source/spirv_definition.h",
+    "$spirv_tools_dir/source/spirv_endian.cpp",
+    "$spirv_tools_dir/source/spirv_endian.h",
+    "$spirv_tools_dir/source/spirv_target_env.cpp",
+    "$spirv_tools_dir/source/spirv_target_env.h",
+    "$spirv_tools_dir/source/spirv_validator_options.cpp",
+    "$spirv_tools_dir/source/spirv_validator_options.h",
+    "$spirv_tools_dir/source/table.cpp",
+    "$spirv_tools_dir/source/table.h",
+    "$spirv_tools_dir/source/text.cpp",
+    "$spirv_tools_dir/source/text.h",
+    "$spirv_tools_dir/source/text_handler.cpp",
+    "$spirv_tools_dir/source/text_handler.h",
+    "$spirv_tools_dir/source/util/bitutils.h",
+    "$spirv_tools_dir/source/util/hex_float.h",
+    "$spirv_tools_dir/source/util/parse_number.cpp",
+    "$spirv_tools_dir/source/util/parse_number.h",
+    "$spirv_tools_dir/source/util/string_utils.cpp",
+    "$spirv_tools_dir/source/util/string_utils.h",
+    "$spirv_tools_dir/source/val/basic_block.cpp",
+    "$spirv_tools_dir/source/val/construct.cpp",
+    "$spirv_tools_dir/source/val/function.cpp",
+    "$spirv_tools_dir/source/val/instruction.cpp",
+    "$spirv_tools_dir/source/val/validation_state.cpp",
+    "$spirv_tools_dir/source/validate.cpp",
+    "$spirv_tools_dir/source/validate.h",
+    "$spirv_tools_dir/source/validate_arithmetics.cpp",
+    "$spirv_tools_dir/source/validate_bitwise.cpp",
+    "$spirv_tools_dir/source/validate_capability.cpp",
+    "$spirv_tools_dir/source/validate_cfg.cpp",
+    "$spirv_tools_dir/source/validate_conversion.cpp",
+    "$spirv_tools_dir/source/validate_datarules.cpp",
+    "$spirv_tools_dir/source/validate_decorations.cpp",
+    "$spirv_tools_dir/source/validate_derivatives.cpp",
+    "$spirv_tools_dir/source/validate_id.cpp",
+    "$spirv_tools_dir/source/validate_image.cpp",
+    "$spirv_tools_dir/source/validate_instruction.cpp",
+    "$spirv_tools_dir/source/validate_layout.cpp",
+    "$spirv_tools_dir/source/validate_logicals.cpp",
+    "$spirv_tools_dir/source/validate_type_unique.cpp",
+  ]
   public_configs = [ ":spirv_tools_config" ]
+
+  foreach(target_name, spvtools_vendor_tables) {
+    deps += [ ":$target_name" ]
+  }
 }
 
 # glslang
 # -------
 
 config("glslang_config") {
   include_dirs = [
     glslang_dir,
@@ -334,34 +559,116 @@ config("glslang_internal_config") {
     cflags = [
       "-Wno-ignored-qualifiers",
       "-Wno-reorder",
     ]
   }
 }
 
 static_library("glslang") {
-  sources = rebase_path(vulkan_gypi.glslang_sources, ".", "src")
+  sources = [
+    "$glslang_dir/OGLCompilersDLL/InitializeDll.cpp",
+    "$glslang_dir/OGLCompilersDLL/InitializeDll.h",
+    "$glslang_dir/SPIRV/GLSL.ext.KHR.h",
+    "$glslang_dir/SPIRV/GLSL.std.450.h",
+    "$glslang_dir/SPIRV/GlslangToSpv.cpp",
+    "$glslang_dir/SPIRV/GlslangToSpv.h",
+    "$glslang_dir/SPIRV/InReadableOrder.cpp",
+    "$glslang_dir/SPIRV/Logger.cpp",
+    "$glslang_dir/SPIRV/Logger.h",
+    "$glslang_dir/SPIRV/SpvBuilder.cpp",
+    "$glslang_dir/SPIRV/SpvBuilder.h",
+    "$glslang_dir/SPIRV/bitutils.h",
+    "$glslang_dir/SPIRV/disassemble.cpp",
+    "$glslang_dir/SPIRV/disassemble.h",
+    "$glslang_dir/SPIRV/doc.cpp",
+    "$glslang_dir/SPIRV/doc.h",
+    "$glslang_dir/SPIRV/hex_float.h",
+    "$glslang_dir/SPIRV/spirv.hpp",
+    "$glslang_dir/SPIRV/spvIR.h",
+    "$glslang_dir/StandAlone/ResourceLimits.cpp",
+    "$glslang_dir/StandAlone/ResourceLimits.h",
+    "$glslang_dir/glslang/GenericCodeGen/CodeGen.cpp",
+    "$glslang_dir/glslang/GenericCodeGen/Link.cpp",
+    "$glslang_dir/glslang/Include/BaseTypes.h",
+    "$glslang_dir/glslang/Include/Common.h",
+    "$glslang_dir/glslang/Include/ConstantUnion.h",
+    "$glslang_dir/glslang/Include/InfoSink.h",
+    "$glslang_dir/glslang/Include/InitializeGlobals.h",
+    "$glslang_dir/glslang/Include/PoolAlloc.h",
+    "$glslang_dir/glslang/Include/ResourceLimits.h",
+    "$glslang_dir/glslang/Include/ShHandle.h",
+    "$glslang_dir/glslang/Include/Types.h",
+    "$glslang_dir/glslang/Include/arrays.h",
+    "$glslang_dir/glslang/Include/intermediate.h",
+    "$glslang_dir/glslang/Include/revision.h",
+    "$glslang_dir/glslang/MachineIndependent/Constant.cpp",
+    "$glslang_dir/glslang/MachineIndependent/InfoSink.cpp",
+    "$glslang_dir/glslang/MachineIndependent/Initialize.cpp",
+    "$glslang_dir/glslang/MachineIndependent/Initialize.h",
+    "$glslang_dir/glslang/MachineIndependent/IntermTraverse.cpp",
+    "$glslang_dir/glslang/MachineIndependent/Intermediate.cpp",
+    "$glslang_dir/glslang/MachineIndependent/LiveTraverser.h",
+    "$glslang_dir/glslang/MachineIndependent/ParseContextBase.cpp",
+    "$glslang_dir/glslang/MachineIndependent/ParseHelper.cpp",
+    "$glslang_dir/glslang/MachineIndependent/ParseHelper.h",
+    "$glslang_dir/glslang/MachineIndependent/PoolAlloc.cpp",
+    "$glslang_dir/glslang/MachineIndependent/RemoveTree.cpp",
+    "$glslang_dir/glslang/MachineIndependent/RemoveTree.h",
+    "$glslang_dir/glslang/MachineIndependent/Scan.cpp",
+    "$glslang_dir/glslang/MachineIndependent/Scan.h",
+    "$glslang_dir/glslang/MachineIndependent/ScanContext.h",
+    "$glslang_dir/glslang/MachineIndependent/ShaderLang.cpp",
+    "$glslang_dir/glslang/MachineIndependent/SymbolTable.cpp",
+    "$glslang_dir/glslang/MachineIndependent/SymbolTable.h",
+    "$glslang_dir/glslang/MachineIndependent/Versions.cpp",
+    "$glslang_dir/glslang/MachineIndependent/Versions.h",
+    "$glslang_dir/glslang/MachineIndependent/gl_types.h",
+    "$glslang_dir/glslang/MachineIndependent/glslang.y",
+    "$glslang_dir/glslang/MachineIndependent/glslang_tab.cpp",
+    "$glslang_dir/glslang/MachineIndependent/glslang_tab.cpp.h",
+    "$glslang_dir/glslang/MachineIndependent/intermOut.cpp",
+    "$glslang_dir/glslang/MachineIndependent/iomapper.cpp",
+    "$glslang_dir/glslang/MachineIndependent/iomapper.h",
+    "$glslang_dir/glslang/MachineIndependent/limits.cpp",
+    "$glslang_dir/glslang/MachineIndependent/linkValidate.cpp",
+    "$glslang_dir/glslang/MachineIndependent/localintermediate.h",
+    "$glslang_dir/glslang/MachineIndependent/parseConst.cpp",
+    "$glslang_dir/glslang/MachineIndependent/parseVersions.h",
+    "$glslang_dir/glslang/MachineIndependent/preprocessor/Pp.cpp",
+    "$glslang_dir/glslang/MachineIndependent/preprocessor/PpAtom.cpp",
+    "$glslang_dir/glslang/MachineIndependent/preprocessor/PpContext.cpp",
+    "$glslang_dir/glslang/MachineIndependent/preprocessor/PpContext.h",
+    "$glslang_dir/glslang/MachineIndependent/preprocessor/PpScanner.cpp",
+    "$glslang_dir/glslang/MachineIndependent/preprocessor/PpTokens.cpp",
+    "$glslang_dir/glslang/MachineIndependent/preprocessor/PpTokens.h",
+    "$glslang_dir/glslang/MachineIndependent/propagateNoContraction.cpp",
+    "$glslang_dir/glslang/MachineIndependent/propagateNoContraction.h",
+    "$glslang_dir/glslang/MachineIndependent/reflection.cpp",
+    "$glslang_dir/glslang/MachineIndependent/reflection.h",
+    "$glslang_dir/glslang/OSDependent/osinclude.h",
+    "$glslang_dir/glslang/Public/ShaderLang.h",
+  ]
   public_configs = [ ":glslang_config" ]
   configs += [ ":glslang_internal_config" ]
 
   if (is_win) {
     cflags = [
       "/wd4100",  # Unreferenced formal parameter
       "/wd4456",  # Declaration hides previous local declaration
       "/wd4457",  # Declaration hides function parameter
       "/wd4458",  # Declaration hides class member
       "/wd4702",  # Unreachable code (from glslang_tab.cpp)
       "/wd4718",  # Recursive call has no side effects (from PpContext.cpp)
     ]
 
-    sources += rebase_path(vulkan_gypi.glslang_win_sources, ".", "src")
+    sources += [ "$glslang_dir/glslang/OSDependent/Windows/ossource.cpp" ]
   }
   if (is_linux) {
-    sources += rebase_path(vulkan_gypi.glslang_unix_sources, ".", "src")
+    sources += [ "$glslang_dir/glslang/OSDependent/Unix/ossource.cpp" ]
   }
 }
 
 # The validation layers
 # ---------------------
 
 config("vulkan_layer_config") {
   include_dirs = [ "$vulkan_layers_dir/layers" ]
@@ -380,70 +687,136 @@ source_set("vulkan_layer_table") {
   sources = [
     "$target_gen_dir/angle/vulkan/vk_dispatch_table_helper.h",
     "$target_gen_dir/angle/vulkan/vk_enum_string_helper.h",
     "$vulkan_layers_dir/layers/vk_layer_table.cpp",
     "$vulkan_layers_dir/layers/vk_layer_table.h",
   ]
 }
 
+core_validation_sources = [
+  # This file is manually included in the layer
+  # "$vulkan_gen_dir/vk_safe_struct.cpp",
+  "$vulkan_gen_dir/vk_safe_struct.h",
+  "$vulkan_layers_dir/layers/buffer_validation.cpp",
+  "$vulkan_layers_dir/layers/buffer_validation.h",
+  "$vulkan_layers_dir/layers/core_validation.cpp",
+  "$vulkan_layers_dir/layers/core_validation.h",
+  "$vulkan_layers_dir/layers/descriptor_sets.cpp",
+  "$vulkan_layers_dir/layers/descriptor_sets.h",
+  "$vulkan_layers_dir/layers/shader_validation.cpp",
+  "$vulkan_layers_dir/layers/shader_validation.h",
+  "$vulkan_layers_dir/layers/xxhash.c",
+  "$vulkan_layers_dir/layers/xxhash.h",
+]
+
+object_tracker_sources = [
+  "$vulkan_gen_dir/object_tracker.cpp",
+  "$vulkan_layers_dir/layers/object_tracker.h",
+  "$vulkan_layers_dir/layers/object_tracker_utils.cpp",
+]
+
+parameter_validation_sources = [
+  "$vulkan_gen_dir/parameter_validation.cpp",
+  "$vulkan_layers_dir/layers/parameter_validation.h",
+  "$vulkan_layers_dir/layers/parameter_validation_utils.cpp",
+]
+
+threading_sources = [
+  "$vulkan_gen_dir/thread_check.h",
+  "$vulkan_layers_dir/layers/threading.cpp",
+  "$vulkan_layers_dir/layers/threading.h",
+]
+
+unique_objects_sources = [
+  "$vulkan_gen_dir/unique_objects_wrappers.h",
+
+  # This file is manually included in the layer
+  # "$vulkan_gen_dir/vk_safe_struct.cpp",
+  "$vulkan_gen_dir/vk_safe_struct.h",
+  "$vulkan_layers_dir/layers/unique_objects.cpp",
+  "$vulkan_layers_dir/layers/unique_objects.h",
+]
+
 layers = [
   [
     "core_validation",
-    vulkan_gypi.VkLayer_core_validation_sources,
+    core_validation_sources,
     ":vulkan_core_validation_glslang",
   ],
   [
     "object_tracker",
-    vulkan_gypi.VkLayer_object_tracker_sources,
-    "",
-  ],
-  [
-    "unique_objects",
-    vulkan_gypi.VkLayer_unique_objects_sources,
-    ":vulkan_gen_unique_objects_wrappers_helper",
+    object_tracker_sources,
+    ":vulkan_gen_object_tracker_cpp",
   ],
   [
     "parameter_validation",
-    vulkan_gypi.VkLayer_parameter_validation_sources,
-    ":vulkan_gen_parameter_validation_helper",
-  ],
-  [
-    "swapchain",
-    vulkan_gypi.VkLayer_swapchain_sources,
-    "",
+    parameter_validation_sources,
+    ":vulkan_gen_parameter_validation",
   ],
   [
     "threading",
-    vulkan_gypi.VkLayer_threading_sources,
+    threading_sources,
     ":vulkan_gen_thread_check_helper",
   ],
+  [
+    "unique_objects",
+    unique_objects_sources,
+    ":vulkan_gen_unique_objects_wrappers_helper",
+  ],
+]
+
+vulkan_gen_json_files_outputs = [
+  "$root_out_dir/$data_dir/VkLayer_core_validation.json",
+  "$root_out_dir/$data_dir/VkLayer_object_tracker.json",
+  "$root_out_dir/$data_dir/VkLayer_parameter_validation.json",
+  "$root_out_dir/$data_dir/VkLayer_threading.json",
+  "$root_out_dir/$data_dir/VkLayer_unique_objects.json",
 ]
 
 action("vulkan_gen_json_files") {
-  script = "$third_party_dir/angle/scripts/generate_vulkan_layers_json.py"
+  script = "$angle_root/scripts/generate_vulkan_layers_json.py"
   if (is_win) {
-    sources =
-        rebase_path(vulkan_gypi.vulkan_gen_json_files_sources_win, ".", "src")
+    sources = [
+      "$vulkan_layers_dir/layers/windows/VkLayer_core_validation.json",
+      "$vulkan_layers_dir/layers/windows/VkLayer_object_tracker.json",
+      "$vulkan_layers_dir/layers/windows/VkLayer_parameter_validation.json",
+      "$vulkan_layers_dir/layers/windows/VkLayer_threading.json",
+      "$vulkan_layers_dir/layers/windows/VkLayer_unique_objects.json",
+    ]
     args = [ "$raw_vulkan_layers_dir/layers/windows" ]
   }
   if (is_linux) {
-    sources =
-        rebase_path(vulkan_gypi.vulkan_gen_json_files_sources_linux, ".", "src")
+    sources = [
+      "$vulkan_layers_dir/layers/linux/VkLayer_core_validation.json",
+      "$vulkan_layers_dir/layers/linux/VkLayer_object_tracker.json",
+      "$vulkan_layers_dir/layers/linux/VkLayer_parameter_validation.json",
+      "$vulkan_layers_dir/layers/linux/VkLayer_threading.json",
+      "$vulkan_layers_dir/layers/linux/VkLayer_unique_objects.json",
+    ]
     args = [ "$raw_vulkan_layers_dir/layers/linux" ]
   }
 
   # The layer JSON files are part of the necessary data deps.
   outputs = vulkan_gen_json_files_outputs
   data = vulkan_gen_json_files_outputs
   args += [ rebase_path("$root_out_dir/$data_dir", root_build_dir) ]
 }
 
 source_set("vulkan_layer_utils") {
-  sources = rebase_path(vulkan_gypi.vulkan_layer_utils_sources, ".", "src")
+  sources = [
+    "$vulkan_layers_dir/layers/vk_format_utils.cpp",
+    "$vulkan_layers_dir/layers/vk_format_utils.h",
+    "$vulkan_layers_dir/layers/vk_layer_config.cpp",
+    "$vulkan_layers_dir/layers/vk_layer_config.h",
+    "$vulkan_layers_dir/layers/vk_layer_extension_utils.cpp",
+    "$vulkan_layers_dir/layers/vk_layer_extension_utils.h",
+    "$vulkan_layers_dir/layers/vk_layer_utils.cpp",
+    "$vulkan_layers_dir/layers/vk_layer_utils.h",
+  ]
   public_configs = [
     ":vulkan_config",
     ":vulkan_loader_config",
     ":vulkan_internal_config",
   ]
   public_deps = [
     ":vulkan_generate_helper_files",
   ]
@@ -456,32 +829,67 @@ config("vulkan_core_validation_config") 
 
 source_set("vulkan_core_validation_glslang") {
   public_deps = [
     ":spirv_tools",
   ]
   public_configs = [ ":vulkan_core_validation_config" ]
 }
 
+config("vulkan_parameter_validation_config") {
+  if (is_clang) {
+    cflags_cc = [ "-Wno-unused-const-variable" ]
+  }
+}
+
+# This special action is needed to remove the generated param header.
+# Otherwise the param gen cpp file will pick up the old file and the
+# build will fail. It's a bit unfortunate but necessary.
+action("vulkan_clean_parameter_gen_header") {
+  script = "$angle_root/scripts/remove_file_if_exists.py"
+  inputs = parameter_validation_sources
+  deps = [
+    ":vulkan_gen_parameter_validation_cpp",
+  ]
+  outputs = [
+    "$vulkan_gen_dir/parameter_validation_h_is_removed",
+  ]
+  args = [
+    "$raw_vulkan_gen_dir/parameter_validation.h",
+    "$raw_vulkan_gen_dir/parameter_validation_h_is_removed",
+  ]
+}
+
+source_set("vulkan_gen_parameter_validation") {
+  deps = [
+    ":vulkan_clean_parameter_gen_header",
+    ":vulkan_gen_parameter_validation_cpp",
+  ]
+  public_configs = [ ":vulkan_parameter_validation_config" ]
+}
+
 foreach(layer_info, layers) {
   name = layer_info[0]
   shared_library("VkLayer_$name") {
     configs -= vulkan_undefine_configs
     deps = [
       ":vulkan_layer_table",
       ":vulkan_layer_utils",
       "//build/config:exe_and_shlib_deps",
     ]
     if (layer_info[2] != "") {
       deps += [ layer_info[2] ]
     }
-    sources = rebase_path(layer_info[1], ".", "src")
+    sources = layer_info[1]
     if (is_win) {
       sources += [ "$vulkan_layers_dir/layers/VkLayer_$name.def" ]
     }
+    if (is_linux) {
+      ldflags = [ "-Wl,-Bsymbolic,--exclude-libs,ALL" ]
+    }
   }
 }
 
 # Use this target to include everything ANGLE needs for Vulkan.
 group("angle_vulkan") {
   deps = [
     ":glslang",
     ":vulkan_loader",
new file mode 100644
--- /dev/null
+++ b/gfx/angle/src/vulkan_support/dummy_spirv_tools_commit_id.h
@@ -0,0 +1,10 @@
+//
+// 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.
+//
+// This file is a dummy file to enable building SPIRV tools when git is absent.
+
+#pragma once
+
+#define SPIRV_TOOLS_COMMIT_ID "0000000000000000000000000000000000000000"
deleted file mode 100644
--- a/gfx/angle/src/vulkan_support/vulkan.gypi
+++ /dev/null
@@ -1,1315 +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.
-
-{
-    'variables':
-    {
-        'glslang_path': '../../third_party/glslang-angle/src',
-        'spirv_headers_path': '../../third_party/spirv-headers/src',
-        'spirv_tools_path': '../../third_party/spirv-tools-angle/src',
-        'vulkan_layers_path': '../../third_party/vulkan-validation-layers/src',
-        'vulkan_json': 'angledata',
-        'vulkan_loader_sources':
-        [
-            '<(vulkan_layers_path)/loader/cJSON.c',
-            '<(vulkan_layers_path)/loader/cJSON.h',
-            '<(vulkan_layers_path)/loader/debug_report.c',
-            '<(vulkan_layers_path)/loader/debug_report.h',
-            '<(vulkan_layers_path)/loader/dev_ext_trampoline.c',
-            '<(vulkan_layers_path)/loader/extension_manual.c',
-            '<(vulkan_layers_path)/loader/extension_manual.h',
-            '<(vulkan_layers_path)/loader/gpa_helper.h',
-            '<(vulkan_layers_path)/loader/loader.c',
-            '<(vulkan_layers_path)/loader/loader.h',
-            '<(vulkan_layers_path)/loader/murmurhash.c',
-            '<(vulkan_layers_path)/loader/murmurhash.h',
-            '<(vulkan_layers_path)/loader/phys_dev_ext.c',
-            '<(vulkan_layers_path)/loader/trampoline.c',
-            '<(vulkan_layers_path)/loader/vk_loader_platform.h',
-            '<(vulkan_layers_path)/loader/wsi.c',
-            '<(vulkan_layers_path)/loader/wsi.h',
-        ],
-        'vulkan_loader_win_sources':
-        [
-            '<(vulkan_layers_path)/loader/dirent_on_windows.c',
-            '<(vulkan_layers_path)/loader/dirent_on_windows.h',
-        ],
-        'vulkan_loader_include_dirs':
-        [
-            '<(vulkan_layers_path)/include',
-            '<(vulkan_layers_path)/loader',
-        ],
-        'vulkan_loader_cflags_win':
-        [
-            '/wd4054', # Type cast from function pointer
-            '/wd4055', # Type cast from data pointer
-            '/wd4100', # Unreferenced formal parameter
-            '/wd4152', # Nonstandard extension used (pointer conversion)
-            '/wd4201', # Nonstandard extension used: nameless struct/union
-            '/wd4214', # Nonstandard extension used: bit field types other than int
-            '/wd4232', # Nonstandard extension used: address of dllimport is not static
-            '/wd4305', # Type cast truncation
-            '/wd4706', # Assignment within conditional expression
-            '/wd4996', # Unsafe stdlib function
-        ],
-        'vulkan_layer_generated_files':
-        [
-            '<(angle_gen_path)/vulkan/vk_enum_string_helper.h',
-            '<(angle_gen_path)/vulkan/vk_struct_size_helper.h',
-            '<(angle_gen_path)/vulkan/vk_struct_size_helper.c',
-            '<(angle_gen_path)/vulkan/vk_safe_struct.h',
-            '<(angle_gen_path)/vulkan/vk_safe_struct.cpp',
-            '<(angle_gen_path)/vulkan/vk_layer_dispatch_table.h',
-            '<(angle_gen_path)/vulkan/vk_dispatch_table_helper.h',
-            '<(angle_gen_path)/vulkan/vk_loader_extensions.h',
-            '<(angle_gen_path)/vulkan/vk_loader_extensions.c',
-            '<@(vulkan_gen_json_files_outputs)',
-        ],
-        'glslang_sources':
-        [
-            '<(glslang_path)/glslang/GenericCodeGen/CodeGen.cpp',
-            '<(glslang_path)/glslang/GenericCodeGen/Link.cpp',
-            '<(glslang_path)/glslang/Include/arrays.h',
-            '<(glslang_path)/glslang/Include/BaseTypes.h',
-            '<(glslang_path)/glslang/Include/Common.h',
-            '<(glslang_path)/glslang/Include/ConstantUnion.h',
-            '<(glslang_path)/glslang/Include/InfoSink.h',
-            '<(glslang_path)/glslang/Include/InitializeGlobals.h',
-            '<(glslang_path)/glslang/Include/intermediate.h',
-            '<(glslang_path)/glslang/Include/PoolAlloc.h',
-            '<(glslang_path)/glslang/Include/ResourceLimits.h',
-            '<(glslang_path)/glslang/Include/revision.h',
-            '<(glslang_path)/glslang/Include/ShHandle.h',
-            '<(glslang_path)/glslang/Include/Types.h',
-            '<(glslang_path)/glslang/MachineIndependent/Constant.cpp',
-            '<(glslang_path)/glslang/MachineIndependent/gl_types.h',
-            '<(glslang_path)/glslang/MachineIndependent/glslang.y',
-            '<(glslang_path)/glslang/MachineIndependent/glslang_tab.cpp',
-            '<(glslang_path)/glslang/MachineIndependent/glslang_tab.cpp.h',
-            '<(glslang_path)/glslang/MachineIndependent/InfoSink.cpp',
-            '<(glslang_path)/glslang/MachineIndependent/Initialize.cpp',
-            '<(glslang_path)/glslang/MachineIndependent/Initialize.h',
-            '<(glslang_path)/glslang/MachineIndependent/Intermediate.cpp',
-            '<(glslang_path)/glslang/MachineIndependent/intermOut.cpp',
-            '<(glslang_path)/glslang/MachineIndependent/IntermTraverse.cpp',
-            '<(glslang_path)/glslang/MachineIndependent/iomapper.cpp',
-            '<(glslang_path)/glslang/MachineIndependent/iomapper.h',
-            '<(glslang_path)/glslang/MachineIndependent/limits.cpp',
-            '<(glslang_path)/glslang/MachineIndependent/linkValidate.cpp',
-            '<(glslang_path)/glslang/MachineIndependent/LiveTraverser.h',
-            '<(glslang_path)/glslang/MachineIndependent/localintermediate.h',
-            '<(glslang_path)/glslang/MachineIndependent/parseConst.cpp',
-            '<(glslang_path)/glslang/MachineIndependent/ParseContextBase.cpp',
-            '<(glslang_path)/glslang/MachineIndependent/ParseHelper.cpp',
-            '<(glslang_path)/glslang/MachineIndependent/ParseHelper.h',
-            '<(glslang_path)/glslang/MachineIndependent/parseVersions.h',
-            '<(glslang_path)/glslang/MachineIndependent/PoolAlloc.cpp',
-            '<(glslang_path)/glslang/MachineIndependent/preprocessor/Pp.cpp',
-            '<(glslang_path)/glslang/MachineIndependent/preprocessor/PpAtom.cpp',
-            '<(glslang_path)/glslang/MachineIndependent/preprocessor/PpContext.cpp',
-            '<(glslang_path)/glslang/MachineIndependent/preprocessor/PpContext.h',
-            '<(glslang_path)/glslang/MachineIndependent/preprocessor/PpMemory.cpp',
-            '<(glslang_path)/glslang/MachineIndependent/preprocessor/PpScanner.cpp',
-            '<(glslang_path)/glslang/MachineIndependent/preprocessor/PpSymbols.cpp',
-            '<(glslang_path)/glslang/MachineIndependent/preprocessor/PpTokens.cpp',
-            '<(glslang_path)/glslang/MachineIndependent/preprocessor/PpTokens.h',
-            '<(glslang_path)/glslang/MachineIndependent/propagateNoContraction.cpp',
-            '<(glslang_path)/glslang/MachineIndependent/propagateNoContraction.h',
-            '<(glslang_path)/glslang/MachineIndependent/reflection.cpp',
-            '<(glslang_path)/glslang/MachineIndependent/reflection.h',
-            '<(glslang_path)/glslang/MachineIndependent/RemoveTree.cpp',
-            '<(glslang_path)/glslang/MachineIndependent/RemoveTree.h',
-            '<(glslang_path)/glslang/MachineIndependent/Scan.cpp',
-            '<(glslang_path)/glslang/MachineIndependent/Scan.h',
-            '<(glslang_path)/glslang/MachineIndependent/ScanContext.h',
-            '<(glslang_path)/glslang/MachineIndependent/ShaderLang.cpp',
-            '<(glslang_path)/glslang/MachineIndependent/SymbolTable.cpp',
-            '<(glslang_path)/glslang/MachineIndependent/SymbolTable.h',
-            '<(glslang_path)/glslang/MachineIndependent/Versions.cpp',
-            '<(glslang_path)/glslang/MachineIndependent/Versions.h',
-            '<(glslang_path)/glslang/OSDependent/osinclude.h',
-            '<(glslang_path)/glslang/Public/ShaderLang.h',
-            '<(glslang_path)/hlsl/hlslAttributes.cpp',
-            '<(glslang_path)/hlsl/hlslAttributes.h',
-            '<(glslang_path)/hlsl/hlslGrammar.cpp',
-            '<(glslang_path)/hlsl/hlslGrammar.h',
-            '<(glslang_path)/hlsl/hlslOpMap.cpp',
-            '<(glslang_path)/hlsl/hlslOpMap.h',
-            '<(glslang_path)/hlsl/hlslParseables.cpp',
-            '<(glslang_path)/hlsl/hlslParseables.h',
-            '<(glslang_path)/hlsl/hlslParseHelper.cpp',
-            '<(glslang_path)/hlsl/hlslParseHelper.h',
-            '<(glslang_path)/hlsl/hlslScanContext.cpp',
-            '<(glslang_path)/hlsl/hlslScanContext.h',
-            '<(glslang_path)/hlsl/hlslTokens.h',
-            '<(glslang_path)/hlsl/hlslTokenStream.cpp',
-            '<(glslang_path)/hlsl/hlslTokenStream.h',
-            '<(glslang_path)/OGLCompilersDLL/InitializeDll.cpp',
-            '<(glslang_path)/OGLCompilersDLL/InitializeDll.h',
-            '<(glslang_path)/SPIRV/bitutils.h',
-            '<(glslang_path)/SPIRV/disassemble.cpp',
-            '<(glslang_path)/SPIRV/disassemble.h',
-            '<(glslang_path)/SPIRV/doc.cpp',
-            '<(glslang_path)/SPIRV/doc.h',
-            '<(glslang_path)/SPIRV/GLSL.ext.KHR.h',
-            '<(glslang_path)/SPIRV/GLSL.std.450.h',
-            '<(glslang_path)/SPIRV/GlslangToSpv.cpp',
-            '<(glslang_path)/SPIRV/GlslangToSpv.h',
-            '<(glslang_path)/SPIRV/hex_float.h',
-            '<(glslang_path)/SPIRV/InReadableOrder.cpp',
-            '<(glslang_path)/SPIRV/Logger.cpp',
-            '<(glslang_path)/SPIRV/Logger.h',
-            '<(glslang_path)/SPIRV/spirv.hpp',
-            '<(glslang_path)/SPIRV/SpvBuilder.cpp',
-            '<(glslang_path)/SPIRV/SpvBuilder.h',
-            '<(glslang_path)/SPIRV/spvIR.h',
-            '<(glslang_path)/StandAlone/ResourceLimits.cpp',
-            '<(glslang_path)/StandAlone/ResourceLimits.h',
-        ],
-        'glslang_win_sources':
-        [
-            '<(glslang_path)/glslang/OSDependent/Windows/ossource.cpp',
-        ],
-        'glslang_unix_sources':
-        [
-            '<(glslang_path)/glslang/OSDependent/Unix/ossource.cpp',
-        ],
-        'spirv_tools_sources':
-        [
-            '<(angle_gen_path)/vulkan/core.insts-1.0.inc',
-            '<(angle_gen_path)/vulkan/core.insts-1.1.inc',
-            '<(angle_gen_path)/vulkan/generators.inc',
-            '<(angle_gen_path)/vulkan/glsl.std.450.insts-1.0.inc',
-            '<(angle_gen_path)/vulkan/opencl.std.insts-1.0.inc',
-            '<(angle_gen_path)/vulkan/operand.kinds-1.0.inc',
-            '<(angle_gen_path)/vulkan/operand.kinds-1.1.inc',
-            '<(spirv_tools_path)/source/assembly_grammar.cpp',
-            '<(spirv_tools_path)/source/assembly_grammar.h',
-            '<(spirv_tools_path)/source/binary.cpp',
-            '<(spirv_tools_path)/source/binary.h',
-            '<(spirv_tools_path)/source/diagnostic.cpp',
-            '<(spirv_tools_path)/source/diagnostic.h',
-            '<(spirv_tools_path)/source/disassemble.cpp',
-            '<(spirv_tools_path)/source/enum_set.h',
-            '<(spirv_tools_path)/source/ext_inst.cpp',
-            '<(spirv_tools_path)/source/ext_inst.h',
-            '<(spirv_tools_path)/source/instruction.h',
-            '<(spirv_tools_path)/source/libspirv.cpp',
-            '<(spirv_tools_path)/source/macro.h',
-            '<(spirv_tools_path)/source/message.cpp',
-            '<(spirv_tools_path)/source/name_mapper.cpp',
-            '<(spirv_tools_path)/source/name_mapper.h',
-            '<(spirv_tools_path)/source/opcode.cpp',
-            '<(spirv_tools_path)/source/opcode.h',
-            '<(spirv_tools_path)/source/operand.cpp',
-            '<(spirv_tools_path)/source/operand.h',
-            '<(spirv_tools_path)/source/parsed_operand.cpp',
-            '<(spirv_tools_path)/source/parsed_operand.h',
-            '<(spirv_tools_path)/source/print.cpp',
-            '<(spirv_tools_path)/source/print.h',
-            # TODO(jmadill): Determine if this is ever needed.
-            #'<(spirv_tools_path)/source/software_version.cpp',
-            '<(spirv_tools_path)/source/spirv_constant.h',
-            '<(spirv_tools_path)/source/spirv_definition.h',
-            '<(spirv_tools_path)/source/spirv_endian.cpp',
-            '<(spirv_tools_path)/source/spirv_endian.h',
-            '<(spirv_tools_path)/source/spirv_target_env.cpp',
-            '<(spirv_tools_path)/source/spirv_target_env.h',
-            '<(spirv_tools_path)/source/table.cpp',
-            '<(spirv_tools_path)/source/table.h',
-            '<(spirv_tools_path)/source/text.cpp',
-            '<(spirv_tools_path)/source/text.h',
-            '<(spirv_tools_path)/source/text_handler.cpp',
-            '<(spirv_tools_path)/source/text_handler.h',
-            '<(spirv_tools_path)/source/util/bitutils.h',
-            '<(spirv_tools_path)/source/util/hex_float.h',
-            '<(spirv_tools_path)/source/util/parse_number.cpp',
-            '<(spirv_tools_path)/source/util/parse_number.h',
-            '<(spirv_tools_path)/source/val/basic_block.cpp',
-            '<(spirv_tools_path)/source/val/construct.cpp',
-            '<(spirv_tools_path)/source/val/function.cpp',
-            '<(spirv_tools_path)/source/val/instruction.cpp',
-            '<(spirv_tools_path)/source/val/validation_state.cpp',
-            '<(spirv_tools_path)/source/validate.cpp',
-            '<(spirv_tools_path)/source/validate.h',
-            '<(spirv_tools_path)/source/validate_cfg.cpp',
-            '<(spirv_tools_path)/source/validate_datarules.cpp',
-            '<(spirv_tools_path)/source/validate_id.cpp',
-            '<(spirv_tools_path)/source/validate_instruction.cpp',
-            '<(spirv_tools_path)/source/validate_layout.cpp',
-        ],
-        'vulkan_layer_utils_sources':
-        [
-            '<(vulkan_layers_path)/layers/vk_layer_config.cpp',
-            '<(vulkan_layers_path)/layers/vk_layer_config.h',
-            '<(vulkan_layers_path)/layers/vk_layer_extension_utils.cpp',
-            '<(vulkan_layers_path)/layers/vk_layer_extension_utils.h',
-            '<(vulkan_layers_path)/layers/vk_layer_utils.cpp',
-            '<(vulkan_layers_path)/layers/vk_layer_utils.h',
-        ],
-        'vulkan_struct_wrappers_outputs':
-        [
-            '<(angle_gen_path)/vulkan/vk_safe_struct.cpp',
-            '<(angle_gen_path)/vulkan/vk_safe_struct.h',
-            '<(angle_gen_path)/vulkan/vk_struct_size_helper.c',
-            '<(angle_gen_path)/vulkan/vk_struct_size_helper.h',
-            '<(angle_gen_path)/vulkan/vk_struct_string_helper.h',
-            '<(angle_gen_path)/vulkan/vk_struct_string_helper_cpp.h',
-        ],
-        'VkLayer_core_validation_sources':
-        [
-            # This file is manually included in the layer
-            # '<(angle_gen_path)/vulkan/vk_safe_struct.cpp',
-            '<(angle_gen_path)/vulkan/vk_safe_struct.h',
-            '<(vulkan_layers_path)/layers/buffer_validation.cpp',
-            '<(vulkan_layers_path)/layers/buffer_validation.h',
-            '<(vulkan_layers_path)/layers/core_validation.cpp',
-            '<(vulkan_layers_path)/layers/core_validation.h',
-            '<(vulkan_layers_path)/layers/descriptor_sets.cpp',
-            '<(vulkan_layers_path)/layers/descriptor_sets.h',
-        ],
-        'VkLayer_swapchain_sources':
-        [
-            '<(vulkan_layers_path)/layers/swapchain.cpp',
-            '<(vulkan_layers_path)/layers/swapchain.h',
-        ],
-        'VkLayer_object_tracker_sources':
-        [
-            '<(vulkan_layers_path)/layers/object_tracker.cpp',
-            '<(vulkan_layers_path)/layers/object_tracker.h',
-        ],
-        'VkLayer_unique_objects_sources':
-        [
-            '<(angle_gen_path)/vulkan/unique_objects_wrappers.h',
-            # This file is manually included in the layer
-            # '<(angle_gen_path)/vulkan/vk_safe_struct.cpp',
-            '<(angle_gen_path)/vulkan/vk_safe_struct.h',
-            '<(vulkan_layers_path)/layers/unique_objects.cpp',
-            '<(vulkan_layers_path)/layers/unique_objects.h',
-        ],
-        'VkLayer_threading_sources':
-        [
-            '<(angle_gen_path)/vulkan/thread_check.h',
-            '<(vulkan_layers_path)/layers/threading.cpp',
-            '<(vulkan_layers_path)/layers/threading.h',
-        ],
-        'VkLayer_parameter_validation_sources':
-        [
-            '<(angle_gen_path)/vulkan/parameter_validation.h',
-            '<(vulkan_layers_path)/layers/parameter_validation.cpp',
-        ],
-        'vulkan_gen_json_files_sources_win':
-        [
-            '<(vulkan_layers_path)/layers/windows/VkLayer_core_validation.json',
-            '<(vulkan_layers_path)/layers/windows/VkLayer_object_tracker.json',
-            '<(vulkan_layers_path)/layers/windows/VkLayer_parameter_validation.json',
-            '<(vulkan_layers_path)/layers/windows/VkLayer_swapchain.json',
-            '<(vulkan_layers_path)/layers/windows/VkLayer_threading.json',
-            '<(vulkan_layers_path)/layers/windows/VkLayer_unique_objects.json',
-        ],
-        'vulkan_gen_json_files_sources_linux':
-        [
-            '<(vulkan_layers_path)/layers/linux/VkLayer_core_validation.json',
-            '<(vulkan_layers_path)/layers/linux/VkLayer_object_tracker.json',
-            '<(vulkan_layers_path)/layers/linux/VkLayer_parameter_validation.json',
-            '<(vulkan_layers_path)/layers/linux/VkLayer_swapchain.json',
-            '<(vulkan_layers_path)/layers/linux/VkLayer_threading.json',
-            '<(vulkan_layers_path)/layers/linux/VkLayer_unique_objects.json',
-        ],
-        'vulkan_gen_json_files_outputs':
-        [
-            '<(PRODUCT_DIR)/<(vulkan_json)/VkLayer_core_validation.json',
-            '<(PRODUCT_DIR)/<(vulkan_json)/VkLayer_object_tracker.json',
-            '<(PRODUCT_DIR)/<(vulkan_json)/VkLayer_parameter_validation.json',
-            '<(PRODUCT_DIR)/<(vulkan_json)/VkLayer_swapchain.json',
-            '<(PRODUCT_DIR)/<(vulkan_json)/VkLayer_threading.json',
-            '<(PRODUCT_DIR)/<(vulkan_json)/VkLayer_unique_objects.json',
-        ],
-    },
-    'conditions':
-    [
-        ['angle_enable_vulkan==1',
-        {
-            'targets':
-            [
-                {
-                    'target_name': 'glslang',
-                    'type': 'static_library',
-                    'sources':
-                    [
-                        '<@(glslang_sources)',
-                    ],
-                    'include_dirs':
-                    [
-                        '<(glslang_path)',
-                    ],
-                    'msvs_settings':
-                    {
-                        'VCCLCompilerTool':
-                        {
-                            'PreprocessorDefinitions':
-                            [
-                                '_HAS_EXCEPTIONS=0',
-                            ],
-                            'AdditionalOptions':
-                            [
-                                '/wd4100', # Unreferenced formal parameter
-                                '/wd4244', # Conversion from 'int' to 'char', possible loss of data
-                                '/wd4456', # Declaration hides previous local declaration
-                                '/wd4457', # Declaration hides function parameter
-                                '/wd4458', # Declaration hides class member
-                                '/wd4702', # Unreachable code (from glslang_tab.cpp)
-                                '/wd4718', # Recursive call has no side effects (from PpContext.cpp)
-                            ],
-                        },
-                    },
-                    'direct_dependent_settings':
-                    {
-                        'include_dirs':
-                        [
-                            '<(glslang_path)/glslang/Public',
-                            '<(glslang_path)',
-                        ],
-                    },
-                    'conditions':
-                    [
-                        ['OS=="win"',
-                        {
-                            'sources':
-                            [
-                                '<@(glslang_win_sources)',
-                            ],
-                        }],
-                        ['OS=="linux"',
-                        {
-                            'sources':
-                            [
-                                '<@(glslang_unix_sources)',
-                            ],
-                        }],
-                    ],
-                },
-
-                {
-                    'target_name': 'spirv_tools',
-                    'type': 'static_library',
-                    'sources':
-                    [
-                        '<@(spirv_tools_sources)',
-                    ],
-                    'include_dirs':
-                    [
-                        '<(angle_gen_path)/vulkan',
-                        '<(spirv_headers_path)/include',
-                        '<(spirv_tools_path)/include',
-                        '<(spirv_tools_path)/source',
-                    ],
-                    'msvs_settings':
-                    {
-                        'VCCLCompilerTool':
-                        {
-                            'PreprocessorDefinitions':
-                            [
-                                '_HAS_EXCEPTIONS=0',
-                            ],
-                            'AdditionalOptions':
-                            [
-                                '/wd4127', # Conditional expression is constant, happens in a template in hex_float.h.
-                                '/wd4706', # Assignment within conditional expression
-                                '/wd4996', # Unsafe stdlib function
-                            ],
-                        },
-                    },
-                    'actions':
-                    [
-                        {
-                            'action_name': 'spirv_tools_gen_build_tables_1_0',
-                            'message': 'generating info tables for SPIR-V 1.0 instructions and operands',
-                            'msvs_cygwin_shell': 0,
-                            'inputs':
-                            [
-                                '<(spirv_headers_path)/include/spirv/1.0/extinst.glsl.std.450.grammar.json',
-                                '<(spirv_headers_path)/include/spirv/1.0/spirv.core.grammar.json',
-                                '<(spirv_tools_path)/source/extinst-1.0.opencl.std.grammar.json',
-                                '<(spirv_tools_path)/utils/generate_grammar_tables.py',
-                            ],
-                            'outputs':
-                            [
-                                '<(angle_gen_path)/vulkan/core.insts-1.0.inc',
-                                '<(angle_gen_path)/vulkan/glsl.std.450.insts-1.0.inc',
-                                '<(angle_gen_path)/vulkan/opencl.std.insts-1.0.inc',
-                                '<(angle_gen_path)/vulkan/operand.kinds-1.0.inc',
-                            ],
-                            'action':
-                            [
-                                'python', '<(spirv_tools_path)/utils/generate_grammar_tables.py',
-                                '--spirv-core-grammar=<(spirv_headers_path)/include/spirv/1.0/spirv.core.grammar.json',
-                                '--extinst-glsl-grammar=<(spirv_headers_path)/include/spirv/1.0/extinst.glsl.std.450.grammar.json',
-                                '--extinst-opencl-grammar=<(spirv_tools_path)/source/extinst-1.0.opencl.std.grammar.json',
-                                '--core-insts-output=<(angle_gen_path)/vulkan/core.insts-1.0.inc',
-                                '--glsl-insts-output=<(angle_gen_path)/vulkan/glsl.std.450.insts-1.0.inc',
-                                '--opencl-insts-output=<(angle_gen_path)/vulkan/opencl.std.insts-1.0.inc',
-                                '--operand-kinds-output=<(angle_gen_path)/vulkan/operand.kinds-1.0.inc',
-                            ],
-                        },
-
-                        {
-                            'action_name': 'spirv_tools_gen_build_tables_1_1',
-                            'message': 'generating info tables for SPIR-V 1.1 instructions and operands',
-                            'msvs_cygwin_shell': 0,
-                            'inputs':
-                            [
-                                '<(spirv_tools_path)/utils/generate_grammar_tables.py',
-                                '<(spirv_headers_path)/include/spirv/1.1/spirv.core.grammar.json',
-                            ],
-                            'outputs':
-                            [
-                                '<(angle_gen_path)/vulkan/core.insts-1.1.inc',
-                                '<(angle_gen_path)/vulkan/operand.kinds-1.1.inc',
-                            ],
-                            'action':
-                            [
-                                'python', '<(spirv_tools_path)/utils/generate_grammar_tables.py',
-                                '--spirv-core-grammar=<(spirv_headers_path)/include/spirv/1.1/spirv.core.grammar.json',
-                                '--core-insts-output=<(angle_gen_path)/vulkan/core.insts-1.1.inc',
-                                '--operand-kinds-output=<(angle_gen_path)/vulkan/operand.kinds-1.1.inc',
-                            ],
-                        },
-
-                        {
-                            'action_name': 'spirv_tools_gen_generators_inc',
-                            'message': 'generating generators.inc for SPIRV-Tools',
-                            'msvs_cygwin_shell': 0,
-                            'inputs':
-                            [
-                                '<(spirv_tools_path)/utils/generate_registry_tables.py',
-                                '<(spirv_headers_path)/include/spirv/spir-v.xml',
-                            ],
-                            'outputs':
-                            [
-                                '<(angle_gen_path)/vulkan/generators.inc',
-                            ],
-                            'action':
-                            [
-                                'python', '<(spirv_tools_path)/utils/generate_registry_tables.py',
-                                '--xml=<(spirv_headers_path)/include/spirv/spir-v.xml',
-                                '--generator-output=<(angle_gen_path)/vulkan/generators.inc',
-                            ],
-                        },
-                    ],
-
-                    'direct_dependent_settings':
-                    {
-                        'include_dirs':
-                        [
-                            '<(spirv_headers_path)/include',
-                            '<(spirv_tools_path)/include',
-                        ],
-                    },
-                },
-
-                {
-                    'target_name': 'vulkan_layer_utils_static',
-                    'type': 'static_library',
-                    'msvs_cygwin_shell': 0,
-                    'sources':
-                    [
-                        '<@(vulkan_layer_utils_sources)',
-                    ],
-                    'include_dirs':
-                    [
-                        '<(angle_gen_path)/vulkan',
-                        '<@(vulkan_loader_include_dirs)',
-                    ],
-                    'msvs_settings':
-                    {
-                        'VCCLCompilerTool':
-                        {
-                            'PreprocessorDefinitions':
-                            [
-                                '_HAS_EXCEPTIONS=0',
-                            ],
-                            'AdditionalOptions':
-                            [
-                                '/wd4100', # Unreferenced formal parameter
-                                '/wd4309', # Truncation of constant value
-                                '/wd4505', # Unreferenced local function has been removed
-                                '/wd4996', # Unsafe stdlib function
-                            ],
-                        },
-                    },
-                    'conditions':
-                    [
-                        ['OS=="win"',
-                        {
-                            'defines':
-                            [
-                                'WIN32',
-                                'WIN32_LEAN_AND_MEAN',
-                                'VK_USE_PLATFORM_WIN32_KHR',
-                                'VK_USE_PLATFORM_WIN32_KHX',
-                            ],
-                        }],
-                        ['OS=="linux"',
-                        {
-                            'defines':
-                            [
-                                'VK_USE_PLATFORM_XCB_KHR',
-                                'VK_USE_PLATFORM_XCB_KHX',
-                            ],
-                        }],
-                    ],
-                    'direct_dependent_settings':
-                    {
-                        'msvs_cygwin_shell': 0,
-                        'sources':
-                        [
-                            '<(vulkan_layers_path)/layers/vk_layer_table.cpp',
-                            '<(vulkan_layers_path)/layers/vk_layer_table.h',
-                        ],
-                        'include_dirs':
-                        [
-                            '<(angle_gen_path)/vulkan',
-                            '<(glslang_path)',
-                            '<(vulkan_layers_path)/layers',
-                            '<@(vulkan_loader_include_dirs)',
-                        ],
-                        'msvs_settings':
-                        {
-                            'VCCLCompilerTool':
-                            {
-                                'PreprocessorDefinitions':
-                                [
-                                    '_HAS_EXCEPTIONS=0',
-                                ],
-                                'AdditionalOptions':
-                                [
-                                    '/wd4100', # Unreferenced local parameter
-                                    '/wd4201', # Nonstandard extension used: nameless struct/union
-                                    '/wd4456', # declaration hides previous local declaration
-                                    '/wd4505', # Unreferenced local function has been removed
-                                    '/wd4996', # Unsafe stdlib function
-                                ],
-                            }
-                        },
-                        'conditions':
-                        [
-                            ['OS=="win"',
-                            {
-                                'defines':
-                                [
-                                    'WIN32_LEAN_AND_MEAN',
-                                    'VK_USE_PLATFORM_WIN32_KHR',
-                                    'VK_USE_PLATFORM_WIN32_KHX',
-                                ],
-                                'configurations':
-                                {
-                                    'Debug_Base':
-                                    {
-                                        'msvs_settings':
-                                        {
-                                            'VCCLCompilerTool':
-                                            {
-                                                'AdditionalOptions':
-                                                [
-                                                    '/bigobj',
-                                                ],
-                                            },
-                                        },
-                                    },
-                                },
-                            }],
-                            ['OS=="linux"',
-                            {
-                                'defines':
-                                [
-                                    'VK_USE_PLATFORM_XCB_KHR',
-                                    'VK_USE_PLATFORM_XCB_KHX',
-                                ],
-                            }],
-                        ],
-                    },
-
-                    'actions':
-                    [
-                        # Duplicate everything because of GYP limitations.
-                        {
-                            'action_name': 'vulkan_run_vk_xml_generate_vk_enum_string_helper_h',
-                            'message': 'generating vk_enum_string_helper.h',
-                            'msvs_cygwin_shell': 0,
-                            'inputs':
-                            [
-                                '<(vulkan_layers_path)/scripts/generator.py',
-                                '<(vulkan_layers_path)/scripts/helper_file_generator.py',
-                                '<(vulkan_layers_path)/scripts/lvl_genvk.py',
-                                '<(vulkan_layers_path)/scripts/reg.py',
-                                '<(vulkan_layers_path)/scripts/vk.xml',
-                            ],
-                            'outputs':
-                            [
-                                '<(angle_gen_path)/vulkan/vk_enum_string_helper.h'
-                            ],
-                            'action':
-                            [
-                                'python', '<(vulkan_layers_path)/scripts/lvl_genvk.py',
-                                 '-o', '<(angle_gen_path)/vulkan',
-                                '-registry', '<(vulkan_layers_path)/scripts/vk.xml',
-                                'vk_enum_string_helper.h', '-quiet',
-                            ],
-                        },
-
-                        {
-                            'action_name': 'vulkan_run_vk_xml_generate_vk_struct_size_helper_h',
-                            'message': 'generating vk_struct_size_helper.h',
-                            'msvs_cygwin_shell': 0,
-                            'inputs':
-                            [
-                                '<(vulkan_layers_path)/scripts/generator.py',
-                                '<(vulkan_layers_path)/scripts/helper_file_generator.py',
-                                '<(vulkan_layers_path)/scripts/lvl_genvk.py',
-                                '<(vulkan_layers_path)/scripts/reg.py',
-                                '<(vulkan_layers_path)/scripts/vk.xml',
-                            ],
-                            'outputs':
-                            [
-                                '<(angle_gen_path)/vulkan/vk_struct_size_helper.h'
-                            ],
-                            'action':
-                            [
-                                'python', '<(vulkan_layers_path)/scripts/lvl_genvk.py',
-                                 '-o', '<(angle_gen_path)/vulkan',
-                                '-registry', '<(vulkan_layers_path)/scripts/vk.xml',
-                                'vk_struct_size_helper.h', '-quiet',
-                            ],
-                        },
-
-                        {
-                            'action_name': 'vulkan_run_vk_xml_generate_vk_struct_size_helper_c',
-                            'message': 'generating vk_struct_size_helper.c',
-                            'msvs_cygwin_shell': 0,
-                            'inputs':
-                            [
-                                '<(vulkan_layers_path)/scripts/generator.py',
-                                '<(vulkan_layers_path)/scripts/helper_file_generator.py',
-                                '<(vulkan_layers_path)/scripts/lvl_genvk.py',
-                                '<(vulkan_layers_path)/scripts/reg.py',
-                                '<(vulkan_layers_path)/scripts/vk.xml',
-                            ],
-                            'outputs':
-                            [
-                                '<(angle_gen_path)/vulkan/vk_struct_size_helper.c'
-                            ],
-                            'action':
-                            [
-                                'python', '<(vulkan_layers_path)/scripts/lvl_genvk.py',
-                                 '-o', '<(angle_gen_path)/vulkan',
-                                '-registry', '<(vulkan_layers_path)/scripts/vk.xml',
-                                'vk_struct_size_helper.c', '-quiet',
-                            ],
-                        },
-
-                        {
-                            'action_name': 'vulkan_run_vk_xml_generate_vk_safe_struct_h',
-                            'message': 'generating vk_safe_struct.h',
-                            'msvs_cygwin_shell': 0,
-                            'inputs':
-                            [
-                                '<(vulkan_layers_path)/scripts/generator.py',
-                                '<(vulkan_layers_path)/scripts/helper_file_generator.py',
-                                '<(vulkan_layers_path)/scripts/lvl_genvk.py',
-                                '<(vulkan_layers_path)/scripts/reg.py',
-                                '<(vulkan_layers_path)/scripts/vk.xml',
-                            ],
-                            'outputs':
-                            [
-                                '<(angle_gen_path)/vulkan/vk_safe_struct.h'
-                            ],
-                            'action':
-                            [
-                                'python', '<(vulkan_layers_path)/scripts/lvl_genvk.py',
-                                 '-o', '<(angle_gen_path)/vulkan',
-                                '-registry', '<(vulkan_layers_path)/scripts/vk.xml',
-                                'vk_safe_struct.h', '-quiet',
-                            ],
-                        },
-
-                        {
-                            'action_name': 'vulkan_run_vk_xml_generate_vk_safe_struct_cpp',
-                            'message': 'generating vk_safe_struct.cpp',
-                            'msvs_cygwin_shell': 0,
-                            'inputs':
-                            [
-                                '<(vulkan_layers_path)/scripts/generator.py',
-                                '<(vulkan_layers_path)/scripts/helper_file_generator.py',
-                                '<(vulkan_layers_path)/scripts/lvl_genvk.py',
-                                '<(vulkan_layers_path)/scripts/reg.py',
-                                '<(vulkan_layers_path)/scripts/vk.xml',
-                            ],
-                            'outputs':
-                            [
-                                '<(angle_gen_path)/vulkan/vk_safe_struct.cpp'
-                            ],
-                            'action':
-                            [
-                                'python', '<(vulkan_layers_path)/scripts/lvl_genvk.py',
-                                 '-o', '<(angle_gen_path)/vulkan',
-                                '-registry', '<(vulkan_layers_path)/scripts/vk.xml',
-                                'vk_safe_struct.cpp', '-quiet',
-                            ],
-                        },
-
-                        {
-                            'action_name': 'vulkan_run_vk_xml_generate_vk_layer_dispatch_table_h',
-                            'message': 'generating vk_layer_dispatch_table.h',
-                            'msvs_cygwin_shell': 0,
-                            'inputs':
-                            [
-                                '<(vulkan_layers_path)/scripts/loader_extension_generator.py',
-                                '<(vulkan_layers_path)/scripts/generator.py',
-                                '<(vulkan_layers_path)/scripts/lvl_genvk.py',
-                                '<(vulkan_layers_path)/scripts/reg.py',
-                                '<(vulkan_layers_path)/scripts/vk.xml',
-                            ],
-                            'outputs':
-                            [
-                                '<(angle_gen_path)/vulkan/vk_layer_dispatch_table.h',
-                            ],
-                            'action':
-                            [
-                                'python', '<(vulkan_layers_path)/scripts/lvl_genvk.py', '-o', '<(angle_gen_path)/vulkan',
-                                '-registry', '<(vulkan_layers_path)/scripts/vk.xml', 'vk_layer_dispatch_table.h', '-quiet',
-                            ],
-                        },
-
-                        {
-                            'action_name': 'vulkan_run_vk_xml_generate_vk_dispatch_table_helper_h',
-                            'message': 'generating vk_dispatch_table_helper.h',
-                            'msvs_cygwin_shell': 0,
-                            'inputs':
-                            [
-                                '<(vulkan_layers_path)/scripts/dispatch_table_helper_generator.py',
-                                '<(vulkan_layers_path)/scripts/generator.py',
-                                '<(vulkan_layers_path)/scripts/lvl_genvk.py',
-                                '<(vulkan_layers_path)/scripts/reg.py',
-                                '<(vulkan_layers_path)/scripts/vk.xml',
-                            ],
-                            'outputs':
-                            [
-                                '<(angle_gen_path)/vulkan/vk_dispatch_table_helper.h',
-                            ],
-                            'action':
-                            [
-                                'python', '<(vulkan_layers_path)/scripts/lvl_genvk.py', '-o', '<(angle_gen_path)/vulkan',
-                                '-registry', '<(vulkan_layers_path)/scripts/vk.xml', 'vk_dispatch_table_helper.h', '-quiet',
-                            ],
-                        },
-
-                        {
-                            'action_name': 'vulkan_run_vk_xml_generate_vk_loader_extensions_h',
-                            'message': 'generating vk_loader_extensions.h',
-                            'msvs_cygwin_shell': 0,
-                            'inputs':
-                            [
-                                '<(vulkan_layers_path)/scripts/loader_extension_generator.py',
-                                '<(vulkan_layers_path)/scripts/generator.py',
-                                '<(vulkan_layers_path)/scripts/lvl_genvk.py',
-                                '<(vulkan_layers_path)/scripts/reg.py',
-                                '<(vulkan_layers_path)/scripts/vk.xml',
-                            ],
-                            'outputs':
-                            [
-                                '<(angle_gen_path)/vulkan/vk_loader_extensions.h',
-                            ],
-                            'action':
-                            [
-                                'python', '<(vulkan_layers_path)/scripts/lvl_genvk.py', '-o', '<(angle_gen_path)/vulkan',
-                                '-registry', '<(vulkan_layers_path)/scripts/vk.xml', 'vk_loader_extensions.h', '-quiet',
-                            ],
-                        },
-
-                        {
-                            'action_name': 'vulkan_run_vk_xml_generate_vk_loader_extensions_c',
-                            'message': 'generating vk_loader_extensions.c',
-                            'msvs_cygwin_shell': 0,
-                            'inputs':
-                            [
-                                '<(vulkan_layers_path)/scripts/loader_extension_generator.py',
-                                '<(vulkan_layers_path)/scripts/generator.py',
-                                '<(vulkan_layers_path)/scripts/lvl_genvk.py',
-                                '<(vulkan_layers_path)/scripts/reg.py',
-                                '<(vulkan_layers_path)/scripts/vk.xml',
-                            ],
-                            'outputs':
-                            [
-                                '<(angle_gen_path)/vulkan/vk_loader_extensions.c',
-                            ],
-                            'action':
-                            [
-                                'python', '<(vulkan_layers_path)/scripts/lvl_genvk.py', '-o', '<(angle_gen_path)/vulkan',
-                                '-registry', '<(vulkan_layers_path)/scripts/vk.xml', 'vk_loader_extensions.c', '-quiet',
-                            ],
-                        },
-
-                        {
-                            'action_name': 'vulkan_generate_json_files',
-                            'message': 'generating Vulkan json files',
-                            'inputs':
-                            [
-                                '<(angle_path)/scripts/generate_vulkan_layers_json.py',
-                            ],
-                            'outputs':
-                            [
-                                '<@(vulkan_gen_json_files_outputs)',
-                            ],
-                            'conditions':
-                            [
-                                ['OS=="win"',
-                                {
-                                    'inputs':
-                                    [
-                                        '<@(vulkan_gen_json_files_sources_win)',
-                                    ],
-                                    'action':
-                                    [
-                                        'python', '<(angle_path)/scripts/generate_vulkan_layers_json.py',
-                                        '<(vulkan_layers_path)/layers/windows', '<(PRODUCT_DIR)/<(vulkan_json)',
-                                    ],
-                                }],
-                                ['OS=="linux"',
-                                {
-                                    'inputs':
-                                    [
-                                        '<@(vulkan_gen_json_files_sources_linux)',
-                                    ],
-                                    'action':
-                                    [
-                                        'python', '<(angle_path)/scripts/generate_vulkan_layers_json.py',
-                                        '<(vulkan_layers_path)/layers/linux', '<(PRODUCT_DIR)/<(vulkan_json)',
-                                    ],
-                                }],
-                            ],
-                        },
-                    ],
-                },
-
-                {
-                    'target_name': 'vulkan_loader',
-                    'type': 'static_library',
-                    'sources':
-                    [
-                        '<@(vulkan_loader_sources)',
-                    ],
-                    'include_dirs':
-                    [
-                        '<@(vulkan_loader_include_dirs)',
-                        '<(angle_gen_path)/vulkan',
-                    ],
-                    'defines':
-                    [
-                        'API_NAME="Vulkan"',
-                        'VULKAN_NON_CMAKE_BUILD',
-                    ],
-                    'msvs_settings':
-                    {
-                        'VCCLCompilerTool':
-                        {
-                            'AdditionalOptions':
-                            [
-                                '<@(vulkan_loader_cflags_win)',
-                            ],
-                        },
-                        'VCLinkerTool':
-                        {
-                            'AdditionalDependencies':
-                            [
-                                'shlwapi.lib',
-                            ],
-                        },
-                    },
-                    'direct_dependent_settings':
-                    {
-                        'include_dirs':
-                        [
-                            '<@(vulkan_loader_include_dirs)',
-                        ],
-                        'msvs_settings':
-                        {
-                            'VCLinkerTool':
-                            {
-                                'AdditionalDependencies':
-                                [
-                                    'shlwapi.lib',
-                                ],
-                            },
-                        },
-                        'defines':
-                        [
-                            'ANGLE_VK_LAYERS_DIR="<(vulkan_json)"',
-                        ],
-                        'conditions':
-                        [
-                            ['OS=="win"',
-                            {
-                                'defines':
-                                [
-                                    'VK_USE_PLATFORM_WIN32_KHR',
-                                    'VK_USE_PLATFORM_WIN32_KHX',
-                                ],
-                            }],
-                            ['OS=="linux"',
-                            {
-                                'defines':
-                                [
-                                    'VK_USE_PLATFORM_XCB_KHR',
-                                    'VK_USE_PLATFORM_XCB_KHX',
-                                ],
-                            }],
-                        ],
-                    },
-                    'conditions':
-                    [
-                        ['OS=="win"',
-                        {
-                            'sources':
-                            [
-                                '<@(vulkan_loader_win_sources)',
-                            ],
-                            'defines':
-                            [
-                                'VK_USE_PLATFORM_WIN32_KHR',
-                                'VK_USE_PLATFORM_WIN32_KHX',
-                            ],
-                        }],
-                        ['OS=="linux"',
-                        {
-                            'defines':
-                            [
-                                'HAVE_SECURE_GETENV',
-                                'VK_USE_PLATFORM_XCB_KHR',
-                                'VK_USE_PLATFORM_XCB_KHX',
-                            ],
-                        }],
-                    ],
-                },
-
-                {
-                    'target_name': 'VkLayer_core_validation',
-                    'type': 'shared_library',
-                    'dependencies':
-                    [
-                        'spirv_tools',
-                        'vulkan_layer_utils_static',
-                    ],
-                    'sources':
-                    [
-                        '<@(VkLayer_core_validation_sources)',
-                    ],
-                    'actions':
-                    [
-                        {
-                            'action_name': 'layer_core_validation_order_deps',
-                            'message': 'stamping for layer_core_validation_order_deps',
-                            'msvs_cygwin_shell': 0,
-                            'inputs': [ '<@(vulkan_layer_generated_files)' ],
-                            'outputs': [ '<(angle_gen_path)/vulkan/layer_core_validation_order_deps.stamp' ],
-                            'action':
-                            [
-                                'python', '<(angle_path)/gyp/touch_stamp.py',
-                                '<(angle_gen_path)/vulkan/layer_core_validation_order_deps.stamp',
-                            ]
-                        },
-                    ],
-                    'conditions':
-                    [
-                        ['OS=="win"',
-                        {
-                            'sources':
-                            [
-                                '<(vulkan_layers_path)/layers/VkLayer_core_validation.def',
-                            ]
-                        }],
-                    ],
-                },
-
-                {
-                    'target_name': 'VkLayer_swapchain',
-                    'type': 'shared_library',
-                    'dependencies':
-                    [
-                        'vulkan_layer_utils_static',
-                    ],
-                    'sources':
-                    [
-                        '<@(VkLayer_swapchain_sources)',
-                    ],
-                    'actions':
-                    [
-                        {
-                            'action_name': 'layer_swapchain_order_deps',
-                            'message': 'stamping for layer_swapchain_order_deps',
-                            'msvs_cygwin_shell': 0,
-                            'inputs': [ '<@(vulkan_layer_generated_files)' ],
-                            'outputs': [ '<(angle_gen_path)/vulkan/layer_swapchain_order_deps.stamp' ],
-                            'action':
-                            [
-                                'python', '<(angle_path)/gyp/touch_stamp.py',
-                                '<(angle_gen_path)/vulkan/layer_swapchain_order_deps.stamp',
-                            ]
-                        },
-                    ],
-                    'conditions':
-                    [
-                        ['OS=="win"',
-                        {
-                            'sources':
-                            [
-                                '<(vulkan_layers_path)/layers/VkLayer_swapchain.def',
-                            ]
-                        }],
-                    ],
-                },
-
-                {
-                    'target_name': 'VkLayer_object_tracker',
-                    'type': 'shared_library',
-                    'dependencies':
-                    [
-                        'vulkan_layer_utils_static',
-                    ],
-                    'sources':
-                    [
-                        '<@(VkLayer_object_tracker_sources)',
-                    ],
-                    'actions':
-                    [
-                        {
-                            'action_name': 'layer_object_tracker_order_deps',
-                            'message': 'stamping for layer_object_tracker_order_deps',
-                            'msvs_cygwin_shell': 0,
-                            'inputs': [ '<@(vulkan_layer_generated_files)' ],
-                            'outputs': [ '<(angle_gen_path)/vulkan/layer_object_tracker_order_deps.stamp' ],
-                            'action':
-                            [
-                                'python', '<(angle_path)/gyp/touch_stamp.py',
-                                '<(angle_gen_path)/vulkan/layer_object_tracker_order_deps.stamp',
-                            ]
-                        },
-                    ],
-                    'conditions':
-                    [
-                        ['OS=="win"',
-                        {
-                            'sources':
-                            [
-                                '<(vulkan_layers_path)/layers/VkLayer_object_tracker.def',
-                            ]
-                        }],
-                    ],
-                },
-
-                {
-                    'target_name': 'VkLayer_unique_objects',
-                    'type': 'shared_library',
-                    'dependencies':
-                    [
-                        'vulkan_layer_utils_static',
-                    ],
-                    'sources':
-                    [
-                        '<@(VkLayer_unique_objects_sources)',
-                    ],
-                    'conditions':
-                    [
-                        ['OS=="win"',
-                        {
-                            'sources':
-                            [
-                                '<(vulkan_layers_path)/layers/VkLayer_unique_objects.def',
-                            ]
-                        }],
-                    ],
-                    'actions':
-                    [
-                        {
-                            'action_name': 'layer_unique_objects_order_deps',
-                            'message': 'stamping for layer_unique_objects_order_deps',
-                            'msvs_cygwin_shell': 0,
-                            'inputs': [ '<@(vulkan_layer_generated_files)' ],
-                            'outputs': [ '<(angle_gen_path)/vulkan/layer_unique_objects_order_deps.stamp' ],
-                            'action':
-                            [
-                                'python', '<(angle_path)/gyp/touch_stamp.py',
-                                '<(angle_gen_path)/vulkan/layer_unique_objects_order_deps.stamp',
-                            ]
-                        },
-                        {
-                            'action_name': 'vulkan_layer_unique_objects_generate',
-                            'message': 'generating Vulkan unique_objects helpers',
-                            'msvs_cygwin_shell': 0,
-                            'inputs':
-                            [
-                                '<(vulkan_layers_path)/scripts/generator.py',
-                                '<(vulkan_layers_path)/scripts/lvl_genvk.py',
-                                '<(vulkan_layers_path)/scripts/reg.py',
-                                '<(vulkan_layers_path)/scripts/unique_objects_generator.py',
-                                '<(vulkan_layers_path)/scripts/vk.xml',
-                            ],
-                            'outputs':
-                            [
-                                '<(angle_gen_path)/vulkan/unique_objects_wrappers.h',
-                            ],
-                            'action':
-                            [
-                                'python', '<(vulkan_layers_path)/scripts/lvl_genvk.py', '-o', '<(angle_gen_path)/vulkan',
-                                '-registry', '<(vulkan_layers_path)/scripts/vk.xml', 'unique_objects_wrappers.h', '-quiet',
-                            ],
-                        },
-                    ],
-                },
-
-                {
-                    'target_name': 'VkLayer_threading',
-                    'type': 'shared_library',
-                    'dependencies':
-                    [
-                        'vulkan_layer_utils_static',
-                    ],
-                    'sources':
-                    [
-                        '<@(VkLayer_threading_sources)',
-                    ],
-                    'conditions':
-                    [
-                        ['OS=="win"',
-                        {
-                            'sources':
-                            [
-                                '<(vulkan_layers_path)/layers/VkLayer_threading.def',
-                            ]
-                        }],
-                    ],
-                    'actions':
-                    [
-                        {
-                            'action_name': 'layer_threading_order_deps',
-                            'message': 'stamping for layer_threading_order_deps',
-                            'msvs_cygwin_shell': 0,
-                            'inputs': [ '<@(vulkan_layer_generated_files)' ],
-                            'outputs': [ '<(angle_gen_path)/vulkan/layer_threading_order_deps.stamp' ],
-                            'action':
-                            [
-                                'python', '<(angle_path)/gyp/touch_stamp.py',
-                                '<(angle_gen_path)/vulkan/layer_threading_order_deps.stamp',
-                            ]
-                        },
-                        {
-                            'action_name': 'vulkan_layer_threading_generate',
-                            'message': 'generating Vulkan threading header',
-                            'msvs_cygwin_shell': 0,
-                            'inputs':
-                            [
-                                '<(vulkan_layers_path)/scripts/generator.py',
-                                '<(vulkan_layers_path)/scripts/lvl_genvk.py',
-                                '<(vulkan_layers_path)/scripts/reg.py',
-                                '<(vulkan_layers_path)/scripts/vk.xml',
-                            ],
-                            'outputs':
-                            [
-                                '<(angle_gen_path)/vulkan/thread_check.h',
-                            ],
-                            'action':
-                            [
-                                'python', '<(vulkan_layers_path)/scripts/lvl_genvk.py', '-o',
-                                '<(angle_gen_path)/vulkan', '-registry', '<(vulkan_layers_path)/scripts/vk.xml',
-                                'thread_check.h', '-quiet',
-                            ],
-                        },
-                    ],
-                },
-
-                {
-                    'target_name': 'VkLayer_parameter_validation',
-                    'type': 'shared_library',
-                    'dependencies':
-                    [
-                        'vulkan_layer_utils_static',
-                    ],
-                    'sources':
-                    [
-                        '<@(VkLayer_parameter_validation_sources)',
-                    ],
-                    'conditions':
-                    [
-                        ['OS=="win"',
-                        {
-                            'sources':
-                            [
-                                '<(vulkan_layers_path)/layers/VkLayer_parameter_validation.def',
-                            ]
-                        }],
-                    ],
-                    'actions':
-                    [
-                        {
-                            'action_name': 'layer_parameter_validation_order_deps',
-                            'message': 'stamping for layer_parameter_validation_order_deps',
-                            'msvs_cygwin_shell': 0,
-                            'inputs': [ '<@(vulkan_layer_generated_files)' ],
-                            'outputs': [ '<(angle_gen_path)/vulkan/layer_parameter_validation_order_deps.stamp' ],
-                            'action':
-                            [
-                                'python', '<(angle_path)/gyp/touch_stamp.py',
-                                '<(angle_gen_path)/vulkan/layer_parameter_validation_order_deps.stamp',
-                            ]
-                        },
-                        {
-                            'action_name': 'vulkan_layer_parameter_validation_generate',
-                            'message': 'generating Vulkan parameter_validation header',
-                            'msvs_cygwin_shell': 0,
-                            'inputs':
-                            [
-                                '<(vulkan_layers_path)/scripts/generator.py',
-                                '<(vulkan_layers_path)/scripts/lvl_genvk.py',
-                                '<(vulkan_layers_path)/scripts/reg.py',
-                                '<(vulkan_layers_path)/scripts/vk.xml',
-                            ],
-                            'outputs':
-                            [
-                                '<(angle_gen_path)/vulkan/parameter_validation.h',
-                            ],
-                            'action':
-                            [
-                                'python', '<(vulkan_layers_path)/scripts/lvl_genvk.py', '-o', '<(angle_gen_path)/vulkan',
-                                '-registry', '<(vulkan_layers_path)/scripts/vk.xml', 'parameter_validation.h', '-quiet',
-                            ],
-                        },
-                    ],
-                },
-
-                {
-                    'target_name': 'angle_vulkan',
-                    'type': 'none',
-                    'dependencies':
-                    [
-                        'glslang',
-                        # Need to disable these to prevent multiply defined symbols with ninja.
-                        # TODO(jmadill): Figure out how to implement data_deps in gyp.
-                        # 'VkLayer_core_validation',
-                        # 'VkLayer_object_tracker',
-                        # 'VkLayer_parameter_validation',
-                        # 'VkLayer_swapchain',
-                        # 'VkLayer_threading',
-                        # 'VkLayer_unique_objects',
-                        'vulkan_loader',
-                    ],
-                    'export_dependent_settings':
-                    [
-                        'glslang',
-                        'vulkan_loader',
-                    ],
-                }
-            ],
-        }],
-    ],
-}