Merge from Chromium at DEPS revision 267aeeb8d85c

This commit was generated by merge_to_master.py.

Change-Id: I7bfd484a94a948094969e81de49bceec18e0af9b
diff --git a/.gclient b/.gclient
deleted file mode 100644
index 4f13bce..0000000
--- a/.gclient
+++ /dev/null
@@ -1,7 +0,0 @@
-solutions = [ {
-    u'managed': False,
-    u'name': u'.',
-    u'url': u'https://chromium.googlesource.com/angle/angle',
-    u'custom_deps': { },
-    u'deps_file': u'DEPS'
-} ]
diff --git a/.gitignore b/.gitignore
index ff5ddbc..82b5f9a 100644
--- a/.gitignore
+++ b/.gitignore
@@ -19,6 +19,9 @@
 build/*.sln
 build/*.vcxproj
 build/*.vcxproj.filters
+util/*.sln
+util/*.vcxproj
+util/*.vcxproj.filters
 *.vcxproj.user
 patches-*
 *.target.mk
@@ -35,3 +38,5 @@
 Makefile
 *.Makefile
 *~
+.gclient
+angle_internal
diff --git a/AUTHORS b/AUTHORS
index 0bdb65e..b79bb5d 100644
--- a/AUTHORS
+++ b/AUTHORS
@@ -20,6 +20,7 @@
 Mozilla Corporation
 Turbulenz
 Klarälvdalens Datakonsult AB
+Microsoft Open Technologies, Inc.
 
 Jacek Caban
 Mark Callow
diff --git a/BUILD.gn b/BUILD.gn
index 86339be..7c5a563 100644
--- a/BUILD.gn
+++ b/BUILD.gn
@@ -150,7 +150,12 @@
   angle_enable_d3d11 = true
 
   shared_library("libGLESv2") {
-    sources = rebase_path(gles_gypi.angle_libglesv2_sources, ".", "src")
+    sources = rebase_path(gles_gypi.angle_libangle_sources, ".", "src")
+    sources += [
+      "src/libGLESv2/libGLESv2.cpp",
+      "src/libGLESv2/libGLESv2.def",
+      "src/libGLESv2/libGLESv2.rc",
+    ]
 
     defines = [
       "ANGLE_PRELOADED_D3DCOMPILER_MODULE_NAMES={ " +
diff --git a/CONTRIBUTORS b/CONTRIBUTORS
index 7d152e7..0cae10a 100644
--- a/CONTRIBUTORS
+++ b/CONTRIBUTORS
@@ -59,6 +59,7 @@
  Jin Yang
  Andy Chen
  Josh Triplett
+ Sudarsana Nagineni
 
 Klarälvdalens Datakonsult AB
  Milian Wolff
@@ -78,3 +79,6 @@
 Mark Banner (standard8mbp)
 David Kilzer
 
+Microsoft Open Technologies, Inc.
+Cooper Partin
+Austin Kinross
diff --git a/README.md b/README.md
new file mode 100644
index 0000000..c9205da
--- /dev/null
+++ b/README.md
@@ -0,0 +1,21 @@
+#ANGLE
+The goal of ANGLE is to allow Windows users to seamlessly run WebGL and other OpenGL ES content by translating OpenGL ES API calls to DirectX 9 or DirectX 11 API calls.
+
+ANGLE is a conformant implementation of the OpenGL ES 2.0 specification that is hardware‐accelerated via Direct3D. 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. Work on ANGLE's OpenGL ES 3.0 implementation is currently in progress, but should not be considered stable.
+
+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.
+
+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.
+
+##Building
+For building instructions, visit the [dev setup wiki](https://code.google.com/p/angleproject/wiki/DevSetup).
+
+##Contributing
+* Join our [Google group](https://groups.google.com/group/angleproject) to keep up to date.
+* Read about ANGLE development on the [wiki](http://code.google.com/p/angleproject/w/list).
+* Become a [code contributor](https://code.google.com/p/angleproject/wiki/ContributingCode).
+* File bugs in the [issue tracker](http://code.google.com/p/angleproject/issues/list) (preferably with an isolated test-case).
+* 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://code.google.com/p/angleproject/downloads/detail?name=ANGLE%20and%20Cross-Platform%20WebGL%20Support.pdf&can=2&q=).
+* 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!
\ No newline at end of file
diff --git a/build/all.gyp b/build/all.gyp
index 735fbea..32d3c8d 100644
--- a/build/all.gyp
+++ b/build/all.gyp
@@ -19,6 +19,10 @@
                 {
                     'dependencies': [ '../tests/tests.gyp:*', ],
                 }],
+                ['angle_build_samples==1 or angle_build_tests==1',
+                {
+                    'dependencies': [ '../util/util.gyp:*', ],
+                }],
             ],
         },
     ],
diff --git a/build/common.gypi b/build/common.gypi
index 173253a..b35a79e 100644
--- a/build/common.gypi
+++ b/build/common.gypi
@@ -151,6 +151,7 @@
                     },
                     'VCLibrarianTool':
                     {
+                        'TargetMachine': '1',
                         'AdditionalLibraryDirectories':
                         [
                             '<(windows_sdk_path)/Lib/win8/um/x86',
diff --git a/include/GLSLANG/ShaderLang.h b/include/GLSLANG/ShaderLang.h
index a61fcb4..b7989f5 100644
--- a/include/GLSLANG/ShaderLang.h
+++ b/include/GLSLANG/ShaderLang.h
@@ -39,6 +39,7 @@
 }
 
 // Must be included after GLenum proxy typedef
+// Note: make sure to increment ANGLE_SH_VERSION when changing ShaderVars.h
 #include "ShaderVars.h"
 
 #ifdef __cplusplus
@@ -47,7 +48,7 @@
 
 // Version number for shader translation API.
 // It is incremented every time the API changes.
-#define ANGLE_SH_VERSION 129
+#define ANGLE_SH_VERSION 130
 
 typedef enum {
   SH_GLES2_SPEC = 0x8B40,
diff --git a/include/GLSLANG/ShaderVars.h b/include/GLSLANG/ShaderVars.h
index 74f2b34..9c38647 100644
--- a/include/GLSLANG/ShaderVars.h
+++ b/include/GLSLANG/ShaderVars.h
@@ -15,6 +15,7 @@
 #include <algorithm>
 
 // Assume ShaderLang.h is included before ShaderVars.h, for sh::GLenum
+// Note: make sure to increment ANGLE_SH_VERSION when changing ShaderVars.h
 
 namespace sh
 {
@@ -49,6 +50,7 @@
 
     bool isArray() const { return arraySize > 0; }
     unsigned int elementCount() const { return std::max(1u, arraySize); }
+    bool isStruct() const { return !fields.empty(); }
 
     GLenum type;
     GLenum precision;
@@ -56,6 +58,8 @@
     std::string mappedName;
     unsigned int arraySize;
     bool staticUse;
+    std::vector<ShaderVariable> fields;
+    std::string structName;
 };
 
 struct COMPILER_EXPORT Uniform : public ShaderVariable
@@ -64,10 +68,6 @@
     ~Uniform();
     Uniform(const Uniform &other);
     Uniform &operator=(const Uniform &other);
-
-    bool isStruct() const { return !fields.empty(); }
-
-    std::vector<Uniform> fields;
 };
 
 struct COMPILER_EXPORT Attribute : public ShaderVariable
@@ -87,10 +87,7 @@
     InterfaceBlockField(const InterfaceBlockField &other);
     InterfaceBlockField &operator=(const InterfaceBlockField &other);
 
-    bool isStruct() const { return !fields.empty(); }
-
-    bool isRowMajorMatrix;
-    std::vector<InterfaceBlockField> fields;
+    bool isRowMajorLayout;
 };
 
 struct COMPILER_EXPORT Varying : public ShaderVariable
@@ -100,11 +97,8 @@
     Varying(const Varying &other);
     Varying &operator=(const Varying &other);
 
-    bool isStruct() const { return !fields.empty(); }
-
     InterpolationType interpolation;
-    std::vector<Varying> fields;
-    std::string structName;
+    bool isInvariant;
 };
 
 struct COMPILER_EXPORT InterfaceBlock
@@ -116,6 +110,7 @@
 
     std::string name;
     std::string mappedName;
+    std::string instanceName;
     unsigned int arraySize;
     BlockLayoutType layout;
     bool isRowMajorLayout;
diff --git a/projects/build/All.vcxproj b/projects/build/All.vcxproj
index 3a0c230..057f1b7 100644
--- a/projects/build/All.vcxproj
+++ b/projects/build/All.vcxproj
@@ -49,7 +49,7 @@
   </PropertyGroup>
   <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
     <ClCompile>
-      <AdditionalIncludeDirectories>$(OutDir)obj\global_intermediate\angle;..\..\include;..\..\samples\angle\sample_util;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <AdditionalIncludeDirectories>$(OutDir)obj\global_intermediate\angle;..\..\src;..\..\include;..\..\src\libGLESv2;..\..\samples\angle\sample_util;..\..\util;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
       <AdditionalOptions>/MP %(AdditionalOptions)</AdditionalOptions>
       <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
       <BufferSecurityCheck>true</BufferSecurityCheck>
@@ -59,7 +59,7 @@
       <FunctionLevelLinking>true</FunctionLevelLinking>
       <MinimalRebuild>false</MinimalRebuild>
       <Optimization>Disabled</Optimization>
-      <PreprocessorDefinitions>ANGLE_TRANSLATOR_STATIC;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <PreprocessorDefinitions>ANGLE_TRANSLATOR_STATIC;GL_APICALL=;GL_GLEXT_PROTOTYPES=;EGLAPI=;ANGLE_PRELOADED_D3DCOMPILER_MODULE_NAMES={ &quot;d3dcompiler_46.dll&quot;, &quot;d3dcompiler_43.dll&quot; };%(PreprocessorDefinitions)</PreprocessorDefinitions>
       <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
       <RuntimeTypeInfo>true</RuntimeTypeInfo>
       <TreatWarningAsError>true</TreatWarningAsError>
@@ -67,6 +67,7 @@
     </ClCompile>
     <Lib>
       <AdditionalLibraryDirectories>C:/Program Files (x86)/Windows Kits/8.0/Lib/win8/um/x86;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
+      <TargetMachine>MachineX86</TargetMachine>
     </Lib>
     <Link>
       <AdditionalDependencies></AdditionalDependencies>
@@ -79,14 +80,14 @@
       <TargetMachine>MachineX86</TargetMachine>
     </Link>
     <ResourceCompile>
-      <AdditionalIncludeDirectories>$(OutDir)obj\global_intermediate\angle;..\..\include;..\..\samples\angle\sample_util;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <AdditionalIncludeDirectories>$(OutDir)obj\global_intermediate\angle;..\..\src;..\..\include;..\..\src\libGLESv2;..\..\samples\angle\sample_util;..\..\util;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
       <Culture>0x0409</Culture>
-      <PreprocessorDefinitions>ANGLE_TRANSLATOR_STATIC;%(PreprocessorDefinitions);%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <PreprocessorDefinitions>ANGLE_TRANSLATOR_STATIC;GL_APICALL=;GL_GLEXT_PROTOTYPES=;EGLAPI=;ANGLE_PRELOADED_D3DCOMPILER_MODULE_NAMES={ &quot;d3dcompiler_46.dll&quot;, &quot;d3dcompiler_43.dll&quot; };%(PreprocessorDefinitions);%(PreprocessorDefinitions)</PreprocessorDefinitions>
     </ResourceCompile>
   </ItemDefinitionGroup>
   <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
     <ClCompile>
-      <AdditionalIncludeDirectories>$(OutDir)obj\global_intermediate\angle;..\..\include;..\..\samples\angle\sample_util;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <AdditionalIncludeDirectories>$(OutDir)obj\global_intermediate\angle;..\..\src;..\..\include;..\..\src\libGLESv2;..\..\samples\angle\sample_util;..\..\util;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
       <AdditionalOptions>/MP %(AdditionalOptions)</AdditionalOptions>
       <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
       <BufferSecurityCheck>true</BufferSecurityCheck>
@@ -96,7 +97,7 @@
       <FunctionLevelLinking>true</FunctionLevelLinking>
       <MinimalRebuild>false</MinimalRebuild>
       <Optimization>Disabled</Optimization>
-      <PreprocessorDefinitions>ANGLE_TRANSLATOR_STATIC;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <PreprocessorDefinitions>ANGLE_TRANSLATOR_STATIC;GL_APICALL=;GL_GLEXT_PROTOTYPES=;EGLAPI=;ANGLE_PRELOADED_D3DCOMPILER_MODULE_NAMES={ &quot;d3dcompiler_46.dll&quot;, &quot;d3dcompiler_43.dll&quot; };%(PreprocessorDefinitions)</PreprocessorDefinitions>
       <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
       <RuntimeTypeInfo>true</RuntimeTypeInfo>
       <TreatWarningAsError>true</TreatWarningAsError>
@@ -116,14 +117,14 @@
       <TargetMachine>MachineX64</TargetMachine>
     </Link>
     <ResourceCompile>
-      <AdditionalIncludeDirectories>$(OutDir)obj\global_intermediate\angle;..\..\include;..\..\samples\angle\sample_util;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <AdditionalIncludeDirectories>$(OutDir)obj\global_intermediate\angle;..\..\src;..\..\include;..\..\src\libGLESv2;..\..\samples\angle\sample_util;..\..\util;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
       <Culture>0x0409</Culture>
-      <PreprocessorDefinitions>ANGLE_TRANSLATOR_STATIC;%(PreprocessorDefinitions);%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <PreprocessorDefinitions>ANGLE_TRANSLATOR_STATIC;GL_APICALL=;GL_GLEXT_PROTOTYPES=;EGLAPI=;ANGLE_PRELOADED_D3DCOMPILER_MODULE_NAMES={ &quot;d3dcompiler_46.dll&quot;, &quot;d3dcompiler_43.dll&quot; };%(PreprocessorDefinitions);%(PreprocessorDefinitions)</PreprocessorDefinitions>
     </ResourceCompile>
   </ItemDefinitionGroup>
   <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
     <ClCompile>
-      <AdditionalIncludeDirectories>$(OutDir)obj\global_intermediate\angle;..\..\include;..\..\samples\angle\sample_util;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <AdditionalIncludeDirectories>$(OutDir)obj\global_intermediate\angle;..\..\src;..\..\include;..\..\src\libGLESv2;..\..\samples\angle\sample_util;..\..\util;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
       <AdditionalOptions>/MP %(AdditionalOptions)</AdditionalOptions>
       <BufferSecurityCheck>true</BufferSecurityCheck>
       <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
@@ -132,7 +133,7 @@
       <FunctionLevelLinking>true</FunctionLevelLinking>
       <MinimalRebuild>false</MinimalRebuild>
       <Optimization>MaxSpeed</Optimization>
-      <PreprocessorDefinitions>ANGLE_TRANSLATOR_STATIC;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <PreprocessorDefinitions>ANGLE_TRANSLATOR_STATIC;GL_APICALL=;GL_GLEXT_PROTOTYPES=;EGLAPI=;ANGLE_PRELOADED_D3DCOMPILER_MODULE_NAMES={ &quot;d3dcompiler_46.dll&quot;, &quot;d3dcompiler_43.dll&quot; };%(PreprocessorDefinitions)</PreprocessorDefinitions>
       <RuntimeLibrary>MultiThreaded</RuntimeLibrary>
       <RuntimeTypeInfo>true</RuntimeTypeInfo>
       <TreatWarningAsError>true</TreatWarningAsError>
@@ -140,6 +141,7 @@
     </ClCompile>
     <Lib>
       <AdditionalLibraryDirectories>C:/Program Files (x86)/Windows Kits/8.0/Lib/win8/um/x86;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
+      <TargetMachine>MachineX86</TargetMachine>
     </Lib>
     <Link>
       <AdditionalDependencies></AdditionalDependencies>
@@ -152,14 +154,14 @@
       <TargetMachine>MachineX86</TargetMachine>
     </Link>
     <ResourceCompile>
-      <AdditionalIncludeDirectories>$(OutDir)obj\global_intermediate\angle;..\..\include;..\..\samples\angle\sample_util;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <AdditionalIncludeDirectories>$(OutDir)obj\global_intermediate\angle;..\..\src;..\..\include;..\..\src\libGLESv2;..\..\samples\angle\sample_util;..\..\util;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
       <Culture>0x0409</Culture>
-      <PreprocessorDefinitions>ANGLE_TRANSLATOR_STATIC;%(PreprocessorDefinitions);%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <PreprocessorDefinitions>ANGLE_TRANSLATOR_STATIC;GL_APICALL=;GL_GLEXT_PROTOTYPES=;EGLAPI=;ANGLE_PRELOADED_D3DCOMPILER_MODULE_NAMES={ &quot;d3dcompiler_46.dll&quot;, &quot;d3dcompiler_43.dll&quot; };%(PreprocessorDefinitions);%(PreprocessorDefinitions)</PreprocessorDefinitions>
     </ResourceCompile>
   </ItemDefinitionGroup>
   <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
     <ClCompile>
-      <AdditionalIncludeDirectories>$(OutDir)obj\global_intermediate\angle;..\..\include;..\..\samples\angle\sample_util;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <AdditionalIncludeDirectories>$(OutDir)obj\global_intermediate\angle;..\..\src;..\..\include;..\..\src\libGLESv2;..\..\samples\angle\sample_util;..\..\util;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
       <AdditionalOptions>/MP %(AdditionalOptions)</AdditionalOptions>
       <BufferSecurityCheck>true</BufferSecurityCheck>
       <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
@@ -168,7 +170,7 @@
       <FunctionLevelLinking>true</FunctionLevelLinking>
       <MinimalRebuild>false</MinimalRebuild>
       <Optimization>MaxSpeed</Optimization>
-      <PreprocessorDefinitions>ANGLE_TRANSLATOR_STATIC;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <PreprocessorDefinitions>ANGLE_TRANSLATOR_STATIC;GL_APICALL=;GL_GLEXT_PROTOTYPES=;EGLAPI=;ANGLE_PRELOADED_D3DCOMPILER_MODULE_NAMES={ &quot;d3dcompiler_46.dll&quot;, &quot;d3dcompiler_43.dll&quot; };%(PreprocessorDefinitions)</PreprocessorDefinitions>
       <RuntimeLibrary>MultiThreaded</RuntimeLibrary>
       <RuntimeTypeInfo>true</RuntimeTypeInfo>
       <TreatWarningAsError>true</TreatWarningAsError>
@@ -188,9 +190,9 @@
       <TargetMachine>MachineX64</TargetMachine>
     </Link>
     <ResourceCompile>
-      <AdditionalIncludeDirectories>$(OutDir)obj\global_intermediate\angle;..\..\include;..\..\samples\angle\sample_util;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <AdditionalIncludeDirectories>$(OutDir)obj\global_intermediate\angle;..\..\src;..\..\include;..\..\src\libGLESv2;..\..\samples\angle\sample_util;..\..\util;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
       <Culture>0x0409</Culture>
-      <PreprocessorDefinitions>ANGLE_TRANSLATOR_STATIC;%(PreprocessorDefinitions);%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <PreprocessorDefinitions>ANGLE_TRANSLATOR_STATIC;GL_APICALL=;GL_GLEXT_PROTOTYPES=;EGLAPI=;ANGLE_PRELOADED_D3DCOMPILER_MODULE_NAMES={ &quot;d3dcompiler_46.dll&quot;, &quot;d3dcompiler_43.dll&quot; };%(PreprocessorDefinitions);%(PreprocessorDefinitions)</PreprocessorDefinitions>
     </ResourceCompile>
   </ItemDefinitionGroup>
   <ItemGroup>
@@ -225,10 +227,18 @@
       <Project>{22DC02D5-1598-943C-13E1-82185B469F81}</Project>
       <ReferenceOutputAssembly>false</ReferenceOutputAssembly>
     </ProjectReference>
+    <ProjectReference Include="..\src\libANGLE.vcxproj">
+      <Project>{CAAA04EE-A56A-43FB-D011-1A56053C070C}</Project>
+      <ReferenceOutputAssembly>false</ReferenceOutputAssembly>
+    </ProjectReference>
     <ProjectReference Include="..\src\libGLESv2.vcxproj">
       <Project>{7FBD6F69-B9A4-69F1-A12B-8DACB3F8CD81}</Project>
       <ReferenceOutputAssembly>false</ReferenceOutputAssembly>
     </ProjectReference>
+    <ProjectReference Include="..\src\libGLESv2_static.vcxproj">
+      <Project>{F8ABD31A-EC2F-A211-D514-076C763B69F9}</Project>
+      <ReferenceOutputAssembly>false</ReferenceOutputAssembly>
+    </ProjectReference>
     <ProjectReference Include="..\src\libEGL.vcxproj">
       <Project>{FBAEE4F6-562A-588F-01F9-72DCABB3B061}</Project>
       <ReferenceOutputAssembly>false</ReferenceOutputAssembly>
@@ -297,6 +307,10 @@
       <Project>{CBE3D362-43EA-60FC-D5AC-490039CA449A}</Project>
       <ReferenceOutputAssembly>false</ReferenceOutputAssembly>
     </ProjectReference>
+    <ProjectReference Include="..\util\angle_util.vcxproj">
+      <Project>{E4DD691C-228B-A904-A008-10E26DC0F09E}</Project>
+      <ReferenceOutputAssembly>false</ReferenceOutputAssembly>
+    </ProjectReference>
   </ItemGroup>
   <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets"/>
   <ImportGroup Label="ExtensionTargets"/>
diff --git a/projects/build/all.sln b/projects/build/all.sln
index 09b7846..ba79f14 100644
--- a/projects/build/all.sln
+++ b/projects/build/all.sln
@@ -9,7 +9,9 @@
 		{19386E01-D811-FA3B-9F1E-122BB0C0E9F5} = {19386E01-D811-FA3B-9F1E-122BB0C0E9F5}
 		{3B7F5656-177F-52EE-26B3-D6A75368D0A9} = {3B7F5656-177F-52EE-26B3-D6A75368D0A9}
 		{22DC02D5-1598-943C-13E1-82185B469F81} = {22DC02D5-1598-943C-13E1-82185B469F81}
+		{CAAA04EE-A56A-43FB-D011-1A56053C070C} = {CAAA04EE-A56A-43FB-D011-1A56053C070C}
 		{7FBD6F69-B9A4-69F1-A12B-8DACB3F8CD81} = {7FBD6F69-B9A4-69F1-A12B-8DACB3F8CD81}
+		{F8ABD31A-EC2F-A211-D514-076C763B69F9} = {F8ABD31A-EC2F-A211-D514-076C763B69F9}
 		{FBAEE4F6-562A-588F-01F9-72DCABB3B061} = {FBAEE4F6-562A-588F-01F9-72DCABB3B061}
 		{293E74D1-544C-D368-02A0-52F61A4D0679} = {293E74D1-544C-D368-02A0-52F61A4D0679}
 		{B4D06330-EED1-6F99-BCA4-2F913908C38A} = {B4D06330-EED1-6F99-BCA4-2F913908C38A}
@@ -27,6 +29,13 @@
 		{92582B26-5131-8C32-39D9-5768C7FA12B4} = {92582B26-5131-8C32-39D9-5768C7FA12B4}
 		{46160987-0221-9E14-3B88-80F9FCFCFFBF} = {46160987-0221-9E14-3B88-80F9FCFCFFBF}
 		{CBE3D362-43EA-60FC-D5AC-490039CA449A} = {CBE3D362-43EA-60FC-D5AC-490039CA449A}
+		{E4DD691C-228B-A904-A008-10E26DC0F09E} = {E4DD691C-228B-A904-A008-10E26DC0F09E}
+	EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "angle_util", "..\util\angle_util.vcxproj", "{E4DD691C-228B-A904-A008-10E26DC0F09E}"
+	ProjectSection(ProjectDependencies) = postProject
+		{FBAEE4F6-562A-588F-01F9-72DCABB3B061} = {FBAEE4F6-562A-588F-01F9-72DCABB3B061}
+		{7FBD6F69-B9A4-69F1-A12B-8DACB3F8CD81} = {7FBD6F69-B9A4-69F1-A12B-8DACB3F8CD81}
 	EndProjectSection
 EndProject
 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "commit_id", "..\src\commit_id.vcxproj", "{3B7F5656-177F-52EE-26B3-D6A75368D0A9}"
@@ -59,6 +68,13 @@
 		{297C46B0-9263-A9EA-82B1-EA221E7D7C7F} = {297C46B0-9263-A9EA-82B1-EA221E7D7C7F}
 		{FBAEE4F6-562A-588F-01F9-72DCABB3B061} = {FBAEE4F6-562A-588F-01F9-72DCABB3B061}
 		{7FBD6F69-B9A4-69F1-A12B-8DACB3F8CD81} = {7FBD6F69-B9A4-69F1-A12B-8DACB3F8CD81}
+		{E4DD691C-228B-A904-A008-10E26DC0F09E} = {E4DD691C-228B-A904-A008-10E26DC0F09E}
+	EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libANGLE", "..\src\libANGLE.vcxproj", "{CAAA04EE-A56A-43FB-D011-1A56053C070C}"
+	ProjectSection(ProjectDependencies) = postProject
+		{3B7F5656-177F-52EE-26B3-D6A75368D0A9} = {3B7F5656-177F-52EE-26B3-D6A75368D0A9}
+		{22DC02D5-1598-943C-13E1-82185B469F81} = {22DC02D5-1598-943C-13E1-82185B469F81}
 	EndProjectSection
 EndProject
 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libEGL", "..\src\libEGL.vcxproj", "{FBAEE4F6-562A-588F-01F9-72DCABB3B061}"
@@ -69,19 +85,26 @@
 EndProject
 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libGLESv2", "..\src\libGLESv2.vcxproj", "{7FBD6F69-B9A4-69F1-A12B-8DACB3F8CD81}"
 	ProjectSection(ProjectDependencies) = postProject
+		{CAAA04EE-A56A-43FB-D011-1A56053C070C} = {CAAA04EE-A56A-43FB-D011-1A56053C070C}
 		{C15697F6-5057-016E-BD29-422971875679} = {C15697F6-5057-016E-BD29-422971875679}
-		{3B7F5656-177F-52EE-26B3-D6A75368D0A9} = {3B7F5656-177F-52EE-26B3-D6A75368D0A9}
-		{22DC02D5-1598-943C-13E1-82185B469F81} = {22DC02D5-1598-943C-13E1-82185B469F81}
 		{276D20F5-2943-414C-0FF6-21F4723A5CF6} = {276D20F5-2943-414C-0FF6-21F4723A5CF6}
 		{C7BAF548-697D-2DCB-9DF3-9D1506A7B444} = {C7BAF548-697D-2DCB-9DF3-9D1506A7B444}
+		{3B7F5656-177F-52EE-26B3-D6A75368D0A9} = {3B7F5656-177F-52EE-26B3-D6A75368D0A9}
+		{22DC02D5-1598-943C-13E1-82185B469F81} = {22DC02D5-1598-943C-13E1-82185B469F81}
 		{63FB0B97-D1D9-5158-8E85-7F5B1E403817} = {63FB0B97-D1D9-5158-8E85-7F5B1E403817}
 	EndProjectSection
 EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libGLESv2_static", "..\src\libGLESv2_static.vcxproj", "{F8ABD31A-EC2F-A211-D514-076C763B69F9}"
+	ProjectSection(ProjectDependencies) = postProject
+		{3B7F5656-177F-52EE-26B3-D6A75368D0A9} = {3B7F5656-177F-52EE-26B3-D6A75368D0A9}
+	EndProjectSection
+EndProject
 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "mip_map_2d", "..\samples\mip_map_2d.vcxproj", "{A6E86EB3-561F-9FAB-670F-EF23556344BE}"
 	ProjectSection(ProjectDependencies) = postProject
 		{297C46B0-9263-A9EA-82B1-EA221E7D7C7F} = {297C46B0-9263-A9EA-82B1-EA221E7D7C7F}
 		{FBAEE4F6-562A-588F-01F9-72DCABB3B061} = {FBAEE4F6-562A-588F-01F9-72DCABB3B061}
 		{7FBD6F69-B9A4-69F1-A12B-8DACB3F8CD81} = {7FBD6F69-B9A4-69F1-A12B-8DACB3F8CD81}
+		{E4DD691C-228B-A904-A008-10E26DC0F09E} = {E4DD691C-228B-A904-A008-10E26DC0F09E}
 	EndProjectSection
 EndProject
 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "multi_texture", "..\samples\multi_texture.vcxproj", "{37E1BB43-65DC-A25A-042E-30B88E6C75A2}"
@@ -89,6 +112,7 @@
 		{297C46B0-9263-A9EA-82B1-EA221E7D7C7F} = {297C46B0-9263-A9EA-82B1-EA221E7D7C7F}
 		{FBAEE4F6-562A-588F-01F9-72DCABB3B061} = {FBAEE4F6-562A-588F-01F9-72DCABB3B061}
 		{7FBD6F69-B9A4-69F1-A12B-8DACB3F8CD81} = {7FBD6F69-B9A4-69F1-A12B-8DACB3F8CD81}
+		{E4DD691C-228B-A904-A008-10E26DC0F09E} = {E4DD691C-228B-A904-A008-10E26DC0F09E}
 	EndProjectSection
 EndProject
 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "multiple_draw_buffers", "..\samples\multiple_draw_buffers.vcxproj", "{58BE89D7-25D5-CC84-EDBF-412C12C59709}"
@@ -96,6 +120,7 @@
 		{297C46B0-9263-A9EA-82B1-EA221E7D7C7F} = {297C46B0-9263-A9EA-82B1-EA221E7D7C7F}
 		{FBAEE4F6-562A-588F-01F9-72DCABB3B061} = {FBAEE4F6-562A-588F-01F9-72DCABB3B061}
 		{7FBD6F69-B9A4-69F1-A12B-8DACB3F8CD81} = {7FBD6F69-B9A4-69F1-A12B-8DACB3F8CD81}
+		{E4DD691C-228B-A904-A008-10E26DC0F09E} = {E4DD691C-228B-A904-A008-10E26DC0F09E}
 	EndProjectSection
 EndProject
 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "particle_system", "..\samples\particle_system.vcxproj", "{8C20B90A-FBCB-B63F-435A-3299A1C38B2C}"
@@ -103,6 +128,7 @@
 		{297C46B0-9263-A9EA-82B1-EA221E7D7C7F} = {297C46B0-9263-A9EA-82B1-EA221E7D7C7F}
 		{FBAEE4F6-562A-588F-01F9-72DCABB3B061} = {FBAEE4F6-562A-588F-01F9-72DCABB3B061}
 		{7FBD6F69-B9A4-69F1-A12B-8DACB3F8CD81} = {7FBD6F69-B9A4-69F1-A12B-8DACB3F8CD81}
+		{E4DD691C-228B-A904-A008-10E26DC0F09E} = {E4DD691C-228B-A904-A008-10E26DC0F09E}
 	EndProjectSection
 EndProject
 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "post_sub_buffer", "..\samples\post_sub_buffer.vcxproj", "{CBE3D362-43EA-60FC-D5AC-490039CA449A}"
@@ -110,6 +136,7 @@
 		{297C46B0-9263-A9EA-82B1-EA221E7D7C7F} = {297C46B0-9263-A9EA-82B1-EA221E7D7C7F}
 		{FBAEE4F6-562A-588F-01F9-72DCABB3B061} = {FBAEE4F6-562A-588F-01F9-72DCABB3B061}
 		{7FBD6F69-B9A4-69F1-A12B-8DACB3F8CD81} = {7FBD6F69-B9A4-69F1-A12B-8DACB3F8CD81}
+		{E4DD691C-228B-A904-A008-10E26DC0F09E} = {E4DD691C-228B-A904-A008-10E26DC0F09E}
 	EndProjectSection
 EndProject
 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "preprocessor", "..\src\preprocessor.vcxproj", "{C7BAF548-697D-2DCB-9DF3-9D1506A7B444}"
@@ -125,6 +152,7 @@
 		{297C46B0-9263-A9EA-82B1-EA221E7D7C7F} = {297C46B0-9263-A9EA-82B1-EA221E7D7C7F}
 		{FBAEE4F6-562A-588F-01F9-72DCABB3B061} = {FBAEE4F6-562A-588F-01F9-72DCABB3B061}
 		{7FBD6F69-B9A4-69F1-A12B-8DACB3F8CD81} = {7FBD6F69-B9A4-69F1-A12B-8DACB3F8CD81}
+		{E4DD691C-228B-A904-A008-10E26DC0F09E} = {E4DD691C-228B-A904-A008-10E26DC0F09E}
 	EndProjectSection
 EndProject
 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "simple_texture_2d", "..\samples\simple_texture_2d.vcxproj", "{0BD6333E-E82C-7665-C386-CDA40096413D}"
@@ -132,6 +160,7 @@
 		{297C46B0-9263-A9EA-82B1-EA221E7D7C7F} = {297C46B0-9263-A9EA-82B1-EA221E7D7C7F}
 		{FBAEE4F6-562A-588F-01F9-72DCABB3B061} = {FBAEE4F6-562A-588F-01F9-72DCABB3B061}
 		{7FBD6F69-B9A4-69F1-A12B-8DACB3F8CD81} = {7FBD6F69-B9A4-69F1-A12B-8DACB3F8CD81}
+		{E4DD691C-228B-A904-A008-10E26DC0F09E} = {E4DD691C-228B-A904-A008-10E26DC0F09E}
 	EndProjectSection
 EndProject
 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "simple_texture_cubemap", "..\samples\simple_texture_cubemap.vcxproj", "{93B7F18A-947E-69A1-9CD8-D1E5144E792A}"
@@ -139,6 +168,7 @@
 		{297C46B0-9263-A9EA-82B1-EA221E7D7C7F} = {297C46B0-9263-A9EA-82B1-EA221E7D7C7F}
 		{FBAEE4F6-562A-588F-01F9-72DCABB3B061} = {FBAEE4F6-562A-588F-01F9-72DCABB3B061}
 		{7FBD6F69-B9A4-69F1-A12B-8DACB3F8CD81} = {7FBD6F69-B9A4-69F1-A12B-8DACB3F8CD81}
+		{E4DD691C-228B-A904-A008-10E26DC0F09E} = {E4DD691C-228B-A904-A008-10E26DC0F09E}
 	EndProjectSection
 EndProject
 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "simple_vertex_shader", "..\samples\simple_vertex_shader.vcxproj", "{459E5678-892C-4EF9-6ED8-0D9E5272B4FF}"
@@ -146,6 +176,7 @@
 		{297C46B0-9263-A9EA-82B1-EA221E7D7C7F} = {297C46B0-9263-A9EA-82B1-EA221E7D7C7F}
 		{FBAEE4F6-562A-588F-01F9-72DCABB3B061} = {FBAEE4F6-562A-588F-01F9-72DCABB3B061}
 		{7FBD6F69-B9A4-69F1-A12B-8DACB3F8CD81} = {7FBD6F69-B9A4-69F1-A12B-8DACB3F8CD81}
+		{E4DD691C-228B-A904-A008-10E26DC0F09E} = {E4DD691C-228B-A904-A008-10E26DC0F09E}
 	EndProjectSection
 EndProject
 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "stencil_operations", "..\samples\stencil_operations.vcxproj", "{92582B26-5131-8C32-39D9-5768C7FA12B4}"
@@ -153,6 +184,7 @@
 		{297C46B0-9263-A9EA-82B1-EA221E7D7C7F} = {297C46B0-9263-A9EA-82B1-EA221E7D7C7F}
 		{FBAEE4F6-562A-588F-01F9-72DCABB3B061} = {FBAEE4F6-562A-588F-01F9-72DCABB3B061}
 		{7FBD6F69-B9A4-69F1-A12B-8DACB3F8CD81} = {7FBD6F69-B9A4-69F1-A12B-8DACB3F8CD81}
+		{E4DD691C-228B-A904-A008-10E26DC0F09E} = {E4DD691C-228B-A904-A008-10E26DC0F09E}
 	EndProjectSection
 EndProject
 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "texture_wrap", "..\samples\texture_wrap.vcxproj", "{46160987-0221-9E14-3B88-80F9FCFCFFBF}"
@@ -160,6 +192,7 @@
 		{297C46B0-9263-A9EA-82B1-EA221E7D7C7F} = {297C46B0-9263-A9EA-82B1-EA221E7D7C7F}
 		{FBAEE4F6-562A-588F-01F9-72DCABB3B061} = {FBAEE4F6-562A-588F-01F9-72DCABB3B061}
 		{7FBD6F69-B9A4-69F1-A12B-8DACB3F8CD81} = {7FBD6F69-B9A4-69F1-A12B-8DACB3F8CD81}
+		{E4DD691C-228B-A904-A008-10E26DC0F09E} = {E4DD691C-228B-A904-A008-10E26DC0F09E}
 	EndProjectSection
 EndProject
 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "translator", "..\src\translator.vcxproj", "{C15697F6-5057-016E-BD29-422971875679}"
@@ -360,6 +393,14 @@
 		{C7BAF548-697D-2DCB-9DF3-9D1506A7B444}.Release|x64.Build.0 = Release|x64
 		{C7BAF548-697D-2DCB-9DF3-9D1506A7B444}.Release|Win32.ActiveCfg = Release|Win32
 		{C7BAF548-697D-2DCB-9DF3-9D1506A7B444}.Release|Win32.Build.0 = Release|Win32
+		{CAAA04EE-A56A-43FB-D011-1A56053C070C}.Debug|x64.ActiveCfg = Debug|x64
+		{CAAA04EE-A56A-43FB-D011-1A56053C070C}.Debug|x64.Build.0 = Debug|x64
+		{CAAA04EE-A56A-43FB-D011-1A56053C070C}.Debug|Win32.ActiveCfg = Debug|Win32
+		{CAAA04EE-A56A-43FB-D011-1A56053C070C}.Debug|Win32.Build.0 = Debug|Win32
+		{CAAA04EE-A56A-43FB-D011-1A56053C070C}.Release|x64.ActiveCfg = Release|x64
+		{CAAA04EE-A56A-43FB-D011-1A56053C070C}.Release|x64.Build.0 = Release|x64
+		{CAAA04EE-A56A-43FB-D011-1A56053C070C}.Release|Win32.ActiveCfg = Release|Win32
+		{CAAA04EE-A56A-43FB-D011-1A56053C070C}.Release|Win32.Build.0 = Release|Win32
 		{CBE3D362-43EA-60FC-D5AC-490039CA449A}.Debug|x64.ActiveCfg = Debug|x64
 		{CBE3D362-43EA-60FC-D5AC-490039CA449A}.Debug|x64.Build.0 = Debug|x64
 		{CBE3D362-43EA-60FC-D5AC-490039CA449A}.Debug|Win32.ActiveCfg = Debug|Win32
@@ -376,6 +417,22 @@
 		{D048EF6F-5312-AF41-8D8A-DB22CD8634E6}.Release|x64.Build.0 = Release|x64
 		{D048EF6F-5312-AF41-8D8A-DB22CD8634E6}.Release|Win32.ActiveCfg = Release|Win32
 		{D048EF6F-5312-AF41-8D8A-DB22CD8634E6}.Release|Win32.Build.0 = Release|Win32
+		{E4DD691C-228B-A904-A008-10E26DC0F09E}.Debug|x64.ActiveCfg = Debug|x64
+		{E4DD691C-228B-A904-A008-10E26DC0F09E}.Debug|x64.Build.0 = Debug|x64
+		{E4DD691C-228B-A904-A008-10E26DC0F09E}.Debug|Win32.ActiveCfg = Debug|Win32
+		{E4DD691C-228B-A904-A008-10E26DC0F09E}.Debug|Win32.Build.0 = Debug|Win32
+		{E4DD691C-228B-A904-A008-10E26DC0F09E}.Release|x64.ActiveCfg = Release|x64
+		{E4DD691C-228B-A904-A008-10E26DC0F09E}.Release|x64.Build.0 = Release|x64
+		{E4DD691C-228B-A904-A008-10E26DC0F09E}.Release|Win32.ActiveCfg = Release|Win32
+		{E4DD691C-228B-A904-A008-10E26DC0F09E}.Release|Win32.Build.0 = Release|Win32
+		{F8ABD31A-EC2F-A211-D514-076C763B69F9}.Debug|x64.ActiveCfg = Debug|x64
+		{F8ABD31A-EC2F-A211-D514-076C763B69F9}.Debug|x64.Build.0 = Debug|x64
+		{F8ABD31A-EC2F-A211-D514-076C763B69F9}.Debug|Win32.ActiveCfg = Debug|Win32
+		{F8ABD31A-EC2F-A211-D514-076C763B69F9}.Debug|Win32.Build.0 = Debug|Win32
+		{F8ABD31A-EC2F-A211-D514-076C763B69F9}.Release|x64.ActiveCfg = Release|x64
+		{F8ABD31A-EC2F-A211-D514-076C763B69F9}.Release|x64.Build.0 = Release|x64
+		{F8ABD31A-EC2F-A211-D514-076C763B69F9}.Release|Win32.ActiveCfg = Release|Win32
+		{F8ABD31A-EC2F-A211-D514-076C763B69F9}.Release|Win32.Build.0 = Release|Win32
 		{FBAEE4F6-562A-588F-01F9-72DCABB3B061}.Debug|x64.ActiveCfg = Debug|x64
 		{FBAEE4F6-562A-588F-01F9-72DCABB3B061}.Debug|x64.Build.0 = Debug|x64
 		{FBAEE4F6-562A-588F-01F9-72DCABB3B061}.Debug|Win32.ActiveCfg = Debug|Win32
diff --git a/projects/samples/dds_to_header.vcxproj b/projects/samples/dds_to_header.vcxproj
index f1fba2a..48cd7d7 100644
--- a/projects/samples/dds_to_header.vcxproj
+++ b/projects/samples/dds_to_header.vcxproj
@@ -68,6 +68,7 @@
     </ClCompile>
     <Lib>
       <AdditionalLibraryDirectories>C:/Program Files (x86)/Windows Kits/8.0/Lib/win8/um/x86;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
+      <TargetMachine>MachineX86</TargetMachine>
     </Lib>
     <Link>
       <AdditionalDependencies>kernel32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;user32.lib;uuid.lib;odbc32.lib;odbccp32.lib;delayimp.lib</AdditionalDependencies>
@@ -142,6 +143,7 @@
     </ClCompile>
     <Lib>
       <AdditionalLibraryDirectories>C:/Program Files (x86)/Windows Kits/8.0/Lib/win8/um/x86;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
+      <TargetMachine>MachineX86</TargetMachine>
     </Lib>
     <Link>
       <AdditionalDependencies>kernel32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;user32.lib;uuid.lib;odbc32.lib;odbccp32.lib;delayimp.lib</AdditionalDependencies>
diff --git a/projects/samples/essl_to_glsl.vcxproj b/projects/samples/essl_to_glsl.vcxproj
index 59ff03e..ec07d28 100644
--- a/projects/samples/essl_to_glsl.vcxproj
+++ b/projects/samples/essl_to_glsl.vcxproj
@@ -68,6 +68,7 @@
     </ClCompile>
     <Lib>
       <AdditionalLibraryDirectories>C:/Program Files (x86)/Windows Kits/8.0/Lib/win8/um/x86;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
+      <TargetMachine>MachineX86</TargetMachine>
     </Lib>
     <Link>
       <AdditionalDependencies>kernel32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;user32.lib;uuid.lib;odbc32.lib;odbccp32.lib;delayimp.lib</AdditionalDependencies>
@@ -143,6 +144,7 @@
     </ClCompile>
     <Lib>
       <AdditionalLibraryDirectories>C:/Program Files (x86)/Windows Kits/8.0/Lib/win8/um/x86;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
+      <TargetMachine>MachineX86</TargetMachine>
     </Lib>
     <Link>
       <AdditionalDependencies>kernel32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;user32.lib;uuid.lib;odbc32.lib;odbccp32.lib;delayimp.lib</AdditionalDependencies>
diff --git a/projects/samples/essl_to_hlsl.vcxproj b/projects/samples/essl_to_hlsl.vcxproj
index 9765438..da4aa21 100644
--- a/projects/samples/essl_to_hlsl.vcxproj
+++ b/projects/samples/essl_to_hlsl.vcxproj
@@ -68,6 +68,7 @@
     </ClCompile>
     <Lib>
       <AdditionalLibraryDirectories>C:/Program Files (x86)/Windows Kits/8.0/Lib/win8/um/x86;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
+      <TargetMachine>MachineX86</TargetMachine>
     </Lib>
     <Link>
       <AdditionalDependencies>kernel32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;user32.lib;uuid.lib;odbc32.lib;odbccp32.lib;delayimp.lib</AdditionalDependencies>
@@ -143,6 +144,7 @@
     </ClCompile>
     <Lib>
       <AdditionalLibraryDirectories>C:/Program Files (x86)/Windows Kits/8.0/Lib/win8/um/x86;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
+      <TargetMachine>MachineX86</TargetMachine>
     </Lib>
     <Link>
       <AdditionalDependencies>kernel32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;user32.lib;uuid.lib;odbc32.lib;odbccp32.lib;delayimp.lib</AdditionalDependencies>
diff --git a/projects/samples/hello_triangle.vcxproj b/projects/samples/hello_triangle.vcxproj
index 8c4f106..95349e8 100644
--- a/projects/samples/hello_triangle.vcxproj
+++ b/projects/samples/hello_triangle.vcxproj
@@ -50,7 +50,7 @@
   </PropertyGroup>
   <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
     <ClCompile>
-      <AdditionalIncludeDirectories>..\..\include;..\..\samples\angle\sample_util;C:\Program Files (x86)\Windows Kits\8.0\Include\shared;C:\Program Files (x86)\Windows Kits\8.0\Include\um;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <AdditionalIncludeDirectories>$(OutDir)obj\global_intermediate\angle;..\..\include;..\..\samples\angle\sample_util;..\..\util;C:\Program Files (x86)\Windows Kits\8.0\Include\shared;C:\Program Files (x86)\Windows Kits\8.0\Include\um;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
       <AdditionalOptions>/MP %(AdditionalOptions)</AdditionalOptions>
       <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
       <BufferSecurityCheck>true</BufferSecurityCheck>
@@ -68,6 +68,7 @@
     </ClCompile>
     <Lib>
       <AdditionalLibraryDirectories>C:/Program Files (x86)/Windows Kits/8.0/Lib/win8/um/x86;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
+      <TargetMachine>MachineX86</TargetMachine>
     </Lib>
     <Link>
       <AdditionalDependencies>kernel32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;user32.lib;uuid.lib;odbc32.lib;odbccp32.lib;delayimp.lib</AdditionalDependencies>
@@ -81,14 +82,14 @@
       <TargetMachine>MachineX86</TargetMachine>
     </Link>
     <ResourceCompile>
-      <AdditionalIncludeDirectories>..\..\include;..\..\samples\angle\sample_util;C:\Program Files (x86)\Windows Kits\8.0\Include\shared;C:\Program Files (x86)\Windows Kits\8.0\Include\um;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <AdditionalIncludeDirectories>$(OutDir)obj\global_intermediate\angle;..\..\include;..\..\samples\angle\sample_util;..\..\util;C:\Program Files (x86)\Windows Kits\8.0\Include\shared;C:\Program Files (x86)\Windows Kits\8.0\Include\um;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
       <Culture>0x0409</Culture>
       <PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
     </ResourceCompile>
   </ItemDefinitionGroup>
   <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
     <ClCompile>
-      <AdditionalIncludeDirectories>..\..\include;..\..\samples\angle\sample_util;C:\Program Files (x86)\Windows Kits\8.0\Include\shared;C:\Program Files (x86)\Windows Kits\8.0\Include\um;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <AdditionalIncludeDirectories>$(OutDir)obj\global_intermediate\angle;..\..\include;..\..\samples\angle\sample_util;..\..\util;C:\Program Files (x86)\Windows Kits\8.0\Include\shared;C:\Program Files (x86)\Windows Kits\8.0\Include\um;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
       <AdditionalOptions>/MP %(AdditionalOptions)</AdditionalOptions>
       <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
       <BufferSecurityCheck>true</BufferSecurityCheck>
@@ -119,13 +120,13 @@
       <TargetMachine>MachineX64</TargetMachine>
     </Link>
     <ResourceCompile>
-      <AdditionalIncludeDirectories>..\..\include;..\..\samples\angle\sample_util;C:\Program Files (x86)\Windows Kits\8.0\Include\shared;C:\Program Files (x86)\Windows Kits\8.0\Include\um;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <AdditionalIncludeDirectories>$(OutDir)obj\global_intermediate\angle;..\..\include;..\..\samples\angle\sample_util;..\..\util;C:\Program Files (x86)\Windows Kits\8.0\Include\shared;C:\Program Files (x86)\Windows Kits\8.0\Include\um;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
       <Culture>0x0409</Culture>
     </ResourceCompile>
   </ItemDefinitionGroup>
   <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
     <ClCompile>
-      <AdditionalIncludeDirectories>..\..\include;..\..\samples\angle\sample_util;C:\Program Files (x86)\Windows Kits\8.0\Include\shared;C:\Program Files (x86)\Windows Kits\8.0\Include\um;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <AdditionalIncludeDirectories>$(OutDir)obj\global_intermediate\angle;..\..\include;..\..\samples\angle\sample_util;..\..\util;C:\Program Files (x86)\Windows Kits\8.0\Include\shared;C:\Program Files (x86)\Windows Kits\8.0\Include\um;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
       <AdditionalOptions>/MP %(AdditionalOptions)</AdditionalOptions>
       <BufferSecurityCheck>true</BufferSecurityCheck>
       <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
@@ -142,6 +143,7 @@
     </ClCompile>
     <Lib>
       <AdditionalLibraryDirectories>C:/Program Files (x86)/Windows Kits/8.0/Lib/win8/um/x86;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
+      <TargetMachine>MachineX86</TargetMachine>
     </Lib>
     <Link>
       <AdditionalDependencies>kernel32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;user32.lib;uuid.lib;odbc32.lib;odbccp32.lib;delayimp.lib</AdditionalDependencies>
@@ -155,14 +157,14 @@
       <TargetMachine>MachineX86</TargetMachine>
     </Link>
     <ResourceCompile>
-      <AdditionalIncludeDirectories>..\..\include;..\..\samples\angle\sample_util;C:\Program Files (x86)\Windows Kits\8.0\Include\shared;C:\Program Files (x86)\Windows Kits\8.0\Include\um;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <AdditionalIncludeDirectories>$(OutDir)obj\global_intermediate\angle;..\..\include;..\..\samples\angle\sample_util;..\..\util;C:\Program Files (x86)\Windows Kits\8.0\Include\shared;C:\Program Files (x86)\Windows Kits\8.0\Include\um;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
       <Culture>0x0409</Culture>
       <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
     </ResourceCompile>
   </ItemDefinitionGroup>
   <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
     <ClCompile>
-      <AdditionalIncludeDirectories>..\..\include;..\..\samples\angle\sample_util;C:\Program Files (x86)\Windows Kits\8.0\Include\shared;C:\Program Files (x86)\Windows Kits\8.0\Include\um;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <AdditionalIncludeDirectories>$(OutDir)obj\global_intermediate\angle;..\..\include;..\..\samples\angle\sample_util;..\..\util;C:\Program Files (x86)\Windows Kits\8.0\Include\shared;C:\Program Files (x86)\Windows Kits\8.0\Include\um;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
       <AdditionalOptions>/MP %(AdditionalOptions)</AdditionalOptions>
       <BufferSecurityCheck>true</BufferSecurityCheck>
       <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
@@ -192,7 +194,7 @@
       <TargetMachine>MachineX64</TargetMachine>
     </Link>
     <ResourceCompile>
-      <AdditionalIncludeDirectories>..\..\include;..\..\samples\angle\sample_util;C:\Program Files (x86)\Windows Kits\8.0\Include\shared;C:\Program Files (x86)\Windows Kits\8.0\Include\um;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <AdditionalIncludeDirectories>$(OutDir)obj\global_intermediate\angle;..\..\include;..\..\samples\angle\sample_util;..\..\util;C:\Program Files (x86)\Windows Kits\8.0\Include\shared;C:\Program Files (x86)\Windows Kits\8.0\Include\um;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
       <Culture>0x0409</Culture>
     </ResourceCompile>
   </ItemDefinitionGroup>
@@ -215,6 +217,10 @@
       <Project>{7FBD6F69-B9A4-69F1-A12B-8DACB3F8CD81}</Project>
       <ReferenceOutputAssembly>false</ReferenceOutputAssembly>
     </ProjectReference>
+    <ProjectReference Include="..\util\angle_util.vcxproj">
+      <Project>{E4DD691C-228B-A904-A008-10E26DC0F09E}</Project>
+      <ReferenceOutputAssembly>false</ReferenceOutputAssembly>
+    </ProjectReference>
   </ItemGroup>
   <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets"/>
   <ImportGroup Label="ExtensionTargets"/>
diff --git a/projects/samples/mip_map_2d.vcxproj b/projects/samples/mip_map_2d.vcxproj
index fab8a1c..787b1c7 100644
--- a/projects/samples/mip_map_2d.vcxproj
+++ b/projects/samples/mip_map_2d.vcxproj
@@ -50,7 +50,7 @@
   </PropertyGroup>
   <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
     <ClCompile>
-      <AdditionalIncludeDirectories>..\..\include;..\..\samples\angle\sample_util;C:\Program Files (x86)\Windows Kits\8.0\Include\shared;C:\Program Files (x86)\Windows Kits\8.0\Include\um;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <AdditionalIncludeDirectories>$(OutDir)obj\global_intermediate\angle;..\..\include;..\..\samples\angle\sample_util;..\..\util;C:\Program Files (x86)\Windows Kits\8.0\Include\shared;C:\Program Files (x86)\Windows Kits\8.0\Include\um;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
       <AdditionalOptions>/MP %(AdditionalOptions)</AdditionalOptions>
       <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
       <BufferSecurityCheck>true</BufferSecurityCheck>
@@ -68,6 +68,7 @@
     </ClCompile>
     <Lib>
       <AdditionalLibraryDirectories>C:/Program Files (x86)/Windows Kits/8.0/Lib/win8/um/x86;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
+      <TargetMachine>MachineX86</TargetMachine>
     </Lib>
     <Link>
       <AdditionalDependencies>kernel32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;user32.lib;uuid.lib;odbc32.lib;odbccp32.lib;delayimp.lib</AdditionalDependencies>
@@ -81,14 +82,14 @@
       <TargetMachine>MachineX86</TargetMachine>
     </Link>
     <ResourceCompile>
-      <AdditionalIncludeDirectories>..\..\include;..\..\samples\angle\sample_util;C:\Program Files (x86)\Windows Kits\8.0\Include\shared;C:\Program Files (x86)\Windows Kits\8.0\Include\um;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <AdditionalIncludeDirectories>$(OutDir)obj\global_intermediate\angle;..\..\include;..\..\samples\angle\sample_util;..\..\util;C:\Program Files (x86)\Windows Kits\8.0\Include\shared;C:\Program Files (x86)\Windows Kits\8.0\Include\um;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
       <Culture>0x0409</Culture>
       <PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
     </ResourceCompile>
   </ItemDefinitionGroup>
   <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
     <ClCompile>
-      <AdditionalIncludeDirectories>..\..\include;..\..\samples\angle\sample_util;C:\Program Files (x86)\Windows Kits\8.0\Include\shared;C:\Program Files (x86)\Windows Kits\8.0\Include\um;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <AdditionalIncludeDirectories>$(OutDir)obj\global_intermediate\angle;..\..\include;..\..\samples\angle\sample_util;..\..\util;C:\Program Files (x86)\Windows Kits\8.0\Include\shared;C:\Program Files (x86)\Windows Kits\8.0\Include\um;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
       <AdditionalOptions>/MP %(AdditionalOptions)</AdditionalOptions>
       <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
       <BufferSecurityCheck>true</BufferSecurityCheck>
@@ -119,13 +120,13 @@
       <TargetMachine>MachineX64</TargetMachine>
     </Link>
     <ResourceCompile>
-      <AdditionalIncludeDirectories>..\..\include;..\..\samples\angle\sample_util;C:\Program Files (x86)\Windows Kits\8.0\Include\shared;C:\Program Files (x86)\Windows Kits\8.0\Include\um;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <AdditionalIncludeDirectories>$(OutDir)obj\global_intermediate\angle;..\..\include;..\..\samples\angle\sample_util;..\..\util;C:\Program Files (x86)\Windows Kits\8.0\Include\shared;C:\Program Files (x86)\Windows Kits\8.0\Include\um;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
       <Culture>0x0409</Culture>
     </ResourceCompile>
   </ItemDefinitionGroup>
   <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
     <ClCompile>
-      <AdditionalIncludeDirectories>..\..\include;..\..\samples\angle\sample_util;C:\Program Files (x86)\Windows Kits\8.0\Include\shared;C:\Program Files (x86)\Windows Kits\8.0\Include\um;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <AdditionalIncludeDirectories>$(OutDir)obj\global_intermediate\angle;..\..\include;..\..\samples\angle\sample_util;..\..\util;C:\Program Files (x86)\Windows Kits\8.0\Include\shared;C:\Program Files (x86)\Windows Kits\8.0\Include\um;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
       <AdditionalOptions>/MP %(AdditionalOptions)</AdditionalOptions>
       <BufferSecurityCheck>true</BufferSecurityCheck>
       <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
@@ -142,6 +143,7 @@
     </ClCompile>
     <Lib>
       <AdditionalLibraryDirectories>C:/Program Files (x86)/Windows Kits/8.0/Lib/win8/um/x86;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
+      <TargetMachine>MachineX86</TargetMachine>
     </Lib>
     <Link>
       <AdditionalDependencies>kernel32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;user32.lib;uuid.lib;odbc32.lib;odbccp32.lib;delayimp.lib</AdditionalDependencies>
@@ -155,14 +157,14 @@
       <TargetMachine>MachineX86</TargetMachine>
     </Link>
     <ResourceCompile>
-      <AdditionalIncludeDirectories>..\..\include;..\..\samples\angle\sample_util;C:\Program Files (x86)\Windows Kits\8.0\Include\shared;C:\Program Files (x86)\Windows Kits\8.0\Include\um;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <AdditionalIncludeDirectories>$(OutDir)obj\global_intermediate\angle;..\..\include;..\..\samples\angle\sample_util;..\..\util;C:\Program Files (x86)\Windows Kits\8.0\Include\shared;C:\Program Files (x86)\Windows Kits\8.0\Include\um;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
       <Culture>0x0409</Culture>
       <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
     </ResourceCompile>
   </ItemDefinitionGroup>
   <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
     <ClCompile>
-      <AdditionalIncludeDirectories>..\..\include;..\..\samples\angle\sample_util;C:\Program Files (x86)\Windows Kits\8.0\Include\shared;C:\Program Files (x86)\Windows Kits\8.0\Include\um;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <AdditionalIncludeDirectories>$(OutDir)obj\global_intermediate\angle;..\..\include;..\..\samples\angle\sample_util;..\..\util;C:\Program Files (x86)\Windows Kits\8.0\Include\shared;C:\Program Files (x86)\Windows Kits\8.0\Include\um;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
       <AdditionalOptions>/MP %(AdditionalOptions)</AdditionalOptions>
       <BufferSecurityCheck>true</BufferSecurityCheck>
       <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
@@ -192,7 +194,7 @@
       <TargetMachine>MachineX64</TargetMachine>
     </Link>
     <ResourceCompile>
-      <AdditionalIncludeDirectories>..\..\include;..\..\samples\angle\sample_util;C:\Program Files (x86)\Windows Kits\8.0\Include\shared;C:\Program Files (x86)\Windows Kits\8.0\Include\um;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <AdditionalIncludeDirectories>$(OutDir)obj\global_intermediate\angle;..\..\include;..\..\samples\angle\sample_util;..\..\util;C:\Program Files (x86)\Windows Kits\8.0\Include\shared;C:\Program Files (x86)\Windows Kits\8.0\Include\um;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
       <Culture>0x0409</Culture>
     </ResourceCompile>
   </ItemDefinitionGroup>
@@ -215,6 +217,10 @@
       <Project>{7FBD6F69-B9A4-69F1-A12B-8DACB3F8CD81}</Project>
       <ReferenceOutputAssembly>false</ReferenceOutputAssembly>
     </ProjectReference>
+    <ProjectReference Include="..\util\angle_util.vcxproj">
+      <Project>{E4DD691C-228B-A904-A008-10E26DC0F09E}</Project>
+      <ReferenceOutputAssembly>false</ReferenceOutputAssembly>
+    </ProjectReference>
   </ItemGroup>
   <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets"/>
   <ImportGroup Label="ExtensionTargets"/>
diff --git a/projects/samples/multi_texture.vcxproj b/projects/samples/multi_texture.vcxproj
index b2bb9b1..774df3d 100644
--- a/projects/samples/multi_texture.vcxproj
+++ b/projects/samples/multi_texture.vcxproj
@@ -50,7 +50,7 @@
   </PropertyGroup>
   <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
     <ClCompile>
-      <AdditionalIncludeDirectories>..\..\include;..\..\samples\angle\sample_util;C:\Program Files (x86)\Windows Kits\8.0\Include\shared;C:\Program Files (x86)\Windows Kits\8.0\Include\um;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <AdditionalIncludeDirectories>$(OutDir)obj\global_intermediate\angle;..\..\include;..\..\samples\angle\sample_util;..\..\util;C:\Program Files (x86)\Windows Kits\8.0\Include\shared;C:\Program Files (x86)\Windows Kits\8.0\Include\um;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
       <AdditionalOptions>/MP %(AdditionalOptions)</AdditionalOptions>
       <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
       <BufferSecurityCheck>true</BufferSecurityCheck>
@@ -68,6 +68,7 @@
     </ClCompile>
     <Lib>
       <AdditionalLibraryDirectories>C:/Program Files (x86)/Windows Kits/8.0/Lib/win8/um/x86;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
+      <TargetMachine>MachineX86</TargetMachine>
     </Lib>
     <Link>
       <AdditionalDependencies>kernel32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;user32.lib;uuid.lib;odbc32.lib;odbccp32.lib;delayimp.lib</AdditionalDependencies>
@@ -81,14 +82,14 @@
       <TargetMachine>MachineX86</TargetMachine>
     </Link>
     <ResourceCompile>
-      <AdditionalIncludeDirectories>..\..\include;..\..\samples\angle\sample_util;C:\Program Files (x86)\Windows Kits\8.0\Include\shared;C:\Program Files (x86)\Windows Kits\8.0\Include\um;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <AdditionalIncludeDirectories>$(OutDir)obj\global_intermediate\angle;..\..\include;..\..\samples\angle\sample_util;..\..\util;C:\Program Files (x86)\Windows Kits\8.0\Include\shared;C:\Program Files (x86)\Windows Kits\8.0\Include\um;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
       <Culture>0x0409</Culture>
       <PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
     </ResourceCompile>
   </ItemDefinitionGroup>
   <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
     <ClCompile>
-      <AdditionalIncludeDirectories>..\..\include;..\..\samples\angle\sample_util;C:\Program Files (x86)\Windows Kits\8.0\Include\shared;C:\Program Files (x86)\Windows Kits\8.0\Include\um;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <AdditionalIncludeDirectories>$(OutDir)obj\global_intermediate\angle;..\..\include;..\..\samples\angle\sample_util;..\..\util;C:\Program Files (x86)\Windows Kits\8.0\Include\shared;C:\Program Files (x86)\Windows Kits\8.0\Include\um;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
       <AdditionalOptions>/MP %(AdditionalOptions)</AdditionalOptions>
       <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
       <BufferSecurityCheck>true</BufferSecurityCheck>
@@ -119,13 +120,13 @@
       <TargetMachine>MachineX64</TargetMachine>
     </Link>
     <ResourceCompile>
-      <AdditionalIncludeDirectories>..\..\include;..\..\samples\angle\sample_util;C:\Program Files (x86)\Windows Kits\8.0\Include\shared;C:\Program Files (x86)\Windows Kits\8.0\Include\um;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <AdditionalIncludeDirectories>$(OutDir)obj\global_intermediate\angle;..\..\include;..\..\samples\angle\sample_util;..\..\util;C:\Program Files (x86)\Windows Kits\8.0\Include\shared;C:\Program Files (x86)\Windows Kits\8.0\Include\um;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
       <Culture>0x0409</Culture>
     </ResourceCompile>
   </ItemDefinitionGroup>
   <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
     <ClCompile>
-      <AdditionalIncludeDirectories>..\..\include;..\..\samples\angle\sample_util;C:\Program Files (x86)\Windows Kits\8.0\Include\shared;C:\Program Files (x86)\Windows Kits\8.0\Include\um;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <AdditionalIncludeDirectories>$(OutDir)obj\global_intermediate\angle;..\..\include;..\..\samples\angle\sample_util;..\..\util;C:\Program Files (x86)\Windows Kits\8.0\Include\shared;C:\Program Files (x86)\Windows Kits\8.0\Include\um;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
       <AdditionalOptions>/MP %(AdditionalOptions)</AdditionalOptions>
       <BufferSecurityCheck>true</BufferSecurityCheck>
       <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
@@ -142,6 +143,7 @@
     </ClCompile>
     <Lib>
       <AdditionalLibraryDirectories>C:/Program Files (x86)/Windows Kits/8.0/Lib/win8/um/x86;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
+      <TargetMachine>MachineX86</TargetMachine>
     </Lib>
     <Link>
       <AdditionalDependencies>kernel32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;user32.lib;uuid.lib;odbc32.lib;odbccp32.lib;delayimp.lib</AdditionalDependencies>
@@ -155,14 +157,14 @@
       <TargetMachine>MachineX86</TargetMachine>
     </Link>
     <ResourceCompile>
-      <AdditionalIncludeDirectories>..\..\include;..\..\samples\angle\sample_util;C:\Program Files (x86)\Windows Kits\8.0\Include\shared;C:\Program Files (x86)\Windows Kits\8.0\Include\um;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <AdditionalIncludeDirectories>$(OutDir)obj\global_intermediate\angle;..\..\include;..\..\samples\angle\sample_util;..\..\util;C:\Program Files (x86)\Windows Kits\8.0\Include\shared;C:\Program Files (x86)\Windows Kits\8.0\Include\um;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
       <Culture>0x0409</Culture>
       <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
     </ResourceCompile>
   </ItemDefinitionGroup>
   <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
     <ClCompile>
-      <AdditionalIncludeDirectories>..\..\include;..\..\samples\angle\sample_util;C:\Program Files (x86)\Windows Kits\8.0\Include\shared;C:\Program Files (x86)\Windows Kits\8.0\Include\um;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <AdditionalIncludeDirectories>$(OutDir)obj\global_intermediate\angle;..\..\include;..\..\samples\angle\sample_util;..\..\util;C:\Program Files (x86)\Windows Kits\8.0\Include\shared;C:\Program Files (x86)\Windows Kits\8.0\Include\um;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
       <AdditionalOptions>/MP %(AdditionalOptions)</AdditionalOptions>
       <BufferSecurityCheck>true</BufferSecurityCheck>
       <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
@@ -192,7 +194,7 @@
       <TargetMachine>MachineX64</TargetMachine>
     </Link>
     <ResourceCompile>
-      <AdditionalIncludeDirectories>..\..\include;..\..\samples\angle\sample_util;C:\Program Files (x86)\Windows Kits\8.0\Include\shared;C:\Program Files (x86)\Windows Kits\8.0\Include\um;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <AdditionalIncludeDirectories>$(OutDir)obj\global_intermediate\angle;..\..\include;..\..\samples\angle\sample_util;..\..\util;C:\Program Files (x86)\Windows Kits\8.0\Include\shared;C:\Program Files (x86)\Windows Kits\8.0\Include\um;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
       <Culture>0x0409</Culture>
     </ResourceCompile>
   </ItemDefinitionGroup>
@@ -229,6 +231,10 @@
       <Project>{7FBD6F69-B9A4-69F1-A12B-8DACB3F8CD81}</Project>
       <ReferenceOutputAssembly>false</ReferenceOutputAssembly>
     </ProjectReference>
+    <ProjectReference Include="..\util\angle_util.vcxproj">
+      <Project>{E4DD691C-228B-A904-A008-10E26DC0F09E}</Project>
+      <ReferenceOutputAssembly>false</ReferenceOutputAssembly>
+    </ProjectReference>
   </ItemGroup>
   <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets"/>
   <ImportGroup Label="ExtensionTargets"/>
diff --git a/projects/samples/multiple_draw_buffers.vcxproj b/projects/samples/multiple_draw_buffers.vcxproj
index c9c3763..c145002 100644
--- a/projects/samples/multiple_draw_buffers.vcxproj
+++ b/projects/samples/multiple_draw_buffers.vcxproj
@@ -50,7 +50,7 @@
   </PropertyGroup>
   <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
     <ClCompile>
-      <AdditionalIncludeDirectories>..\..\include;..\..\samples\angle\sample_util;C:\Program Files (x86)\Windows Kits\8.0\Include\shared;C:\Program Files (x86)\Windows Kits\8.0\Include\um;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <AdditionalIncludeDirectories>$(OutDir)obj\global_intermediate\angle;..\..\include;..\..\samples\angle\sample_util;..\..\util;C:\Program Files (x86)\Windows Kits\8.0\Include\shared;C:\Program Files (x86)\Windows Kits\8.0\Include\um;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
       <AdditionalOptions>/MP %(AdditionalOptions)</AdditionalOptions>
       <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
       <BufferSecurityCheck>true</BufferSecurityCheck>
@@ -68,6 +68,7 @@
     </ClCompile>
     <Lib>
       <AdditionalLibraryDirectories>C:/Program Files (x86)/Windows Kits/8.0/Lib/win8/um/x86;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
+      <TargetMachine>MachineX86</TargetMachine>
     </Lib>
     <Link>
       <AdditionalDependencies>kernel32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;user32.lib;uuid.lib;odbc32.lib;odbccp32.lib;delayimp.lib</AdditionalDependencies>
@@ -81,14 +82,14 @@
       <TargetMachine>MachineX86</TargetMachine>
     </Link>
     <ResourceCompile>
-      <AdditionalIncludeDirectories>..\..\include;..\..\samples\angle\sample_util;C:\Program Files (x86)\Windows Kits\8.0\Include\shared;C:\Program Files (x86)\Windows Kits\8.0\Include\um;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <AdditionalIncludeDirectories>$(OutDir)obj\global_intermediate\angle;..\..\include;..\..\samples\angle\sample_util;..\..\util;C:\Program Files (x86)\Windows Kits\8.0\Include\shared;C:\Program Files (x86)\Windows Kits\8.0\Include\um;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
       <Culture>0x0409</Culture>
       <PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
     </ResourceCompile>
   </ItemDefinitionGroup>
   <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
     <ClCompile>
-      <AdditionalIncludeDirectories>..\..\include;..\..\samples\angle\sample_util;C:\Program Files (x86)\Windows Kits\8.0\Include\shared;C:\Program Files (x86)\Windows Kits\8.0\Include\um;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <AdditionalIncludeDirectories>$(OutDir)obj\global_intermediate\angle;..\..\include;..\..\samples\angle\sample_util;..\..\util;C:\Program Files (x86)\Windows Kits\8.0\Include\shared;C:\Program Files (x86)\Windows Kits\8.0\Include\um;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
       <AdditionalOptions>/MP %(AdditionalOptions)</AdditionalOptions>
       <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
       <BufferSecurityCheck>true</BufferSecurityCheck>
@@ -119,13 +120,13 @@
       <TargetMachine>MachineX64</TargetMachine>
     </Link>
     <ResourceCompile>
-      <AdditionalIncludeDirectories>..\..\include;..\..\samples\angle\sample_util;C:\Program Files (x86)\Windows Kits\8.0\Include\shared;C:\Program Files (x86)\Windows Kits\8.0\Include\um;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <AdditionalIncludeDirectories>$(OutDir)obj\global_intermediate\angle;..\..\include;..\..\samples\angle\sample_util;..\..\util;C:\Program Files (x86)\Windows Kits\8.0\Include\shared;C:\Program Files (x86)\Windows Kits\8.0\Include\um;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
       <Culture>0x0409</Culture>
     </ResourceCompile>
   </ItemDefinitionGroup>
   <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
     <ClCompile>
-      <AdditionalIncludeDirectories>..\..\include;..\..\samples\angle\sample_util;C:\Program Files (x86)\Windows Kits\8.0\Include\shared;C:\Program Files (x86)\Windows Kits\8.0\Include\um;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <AdditionalIncludeDirectories>$(OutDir)obj\global_intermediate\angle;..\..\include;..\..\samples\angle\sample_util;..\..\util;C:\Program Files (x86)\Windows Kits\8.0\Include\shared;C:\Program Files (x86)\Windows Kits\8.0\Include\um;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
       <AdditionalOptions>/MP %(AdditionalOptions)</AdditionalOptions>
       <BufferSecurityCheck>true</BufferSecurityCheck>
       <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
@@ -142,6 +143,7 @@
     </ClCompile>
     <Lib>
       <AdditionalLibraryDirectories>C:/Program Files (x86)/Windows Kits/8.0/Lib/win8/um/x86;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
+      <TargetMachine>MachineX86</TargetMachine>
     </Lib>
     <Link>
       <AdditionalDependencies>kernel32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;user32.lib;uuid.lib;odbc32.lib;odbccp32.lib;delayimp.lib</AdditionalDependencies>
@@ -155,14 +157,14 @@
       <TargetMachine>MachineX86</TargetMachine>
     </Link>
     <ResourceCompile>
-      <AdditionalIncludeDirectories>..\..\include;..\..\samples\angle\sample_util;C:\Program Files (x86)\Windows Kits\8.0\Include\shared;C:\Program Files (x86)\Windows Kits\8.0\Include\um;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <AdditionalIncludeDirectories>$(OutDir)obj\global_intermediate\angle;..\..\include;..\..\samples\angle\sample_util;..\..\util;C:\Program Files (x86)\Windows Kits\8.0\Include\shared;C:\Program Files (x86)\Windows Kits\8.0\Include\um;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
       <Culture>0x0409</Culture>
       <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
     </ResourceCompile>
   </ItemDefinitionGroup>
   <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
     <ClCompile>
-      <AdditionalIncludeDirectories>..\..\include;..\..\samples\angle\sample_util;C:\Program Files (x86)\Windows Kits\8.0\Include\shared;C:\Program Files (x86)\Windows Kits\8.0\Include\um;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <AdditionalIncludeDirectories>$(OutDir)obj\global_intermediate\angle;..\..\include;..\..\samples\angle\sample_util;..\..\util;C:\Program Files (x86)\Windows Kits\8.0\Include\shared;C:\Program Files (x86)\Windows Kits\8.0\Include\um;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
       <AdditionalOptions>/MP %(AdditionalOptions)</AdditionalOptions>
       <BufferSecurityCheck>true</BufferSecurityCheck>
       <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
@@ -192,7 +194,7 @@
       <TargetMachine>MachineX64</TargetMachine>
     </Link>
     <ResourceCompile>
-      <AdditionalIncludeDirectories>..\..\include;..\..\samples\angle\sample_util;C:\Program Files (x86)\Windows Kits\8.0\Include\shared;C:\Program Files (x86)\Windows Kits\8.0\Include\um;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <AdditionalIncludeDirectories>$(OutDir)obj\global_intermediate\angle;..\..\include;..\..\samples\angle\sample_util;..\..\util;C:\Program Files (x86)\Windows Kits\8.0\Include\shared;C:\Program Files (x86)\Windows Kits\8.0\Include\um;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
       <Culture>0x0409</Culture>
     </ResourceCompile>
   </ItemDefinitionGroup>
@@ -235,6 +237,10 @@
       <Project>{7FBD6F69-B9A4-69F1-A12B-8DACB3F8CD81}</Project>
       <ReferenceOutputAssembly>false</ReferenceOutputAssembly>
     </ProjectReference>
+    <ProjectReference Include="..\util\angle_util.vcxproj">
+      <Project>{E4DD691C-228B-A904-A008-10E26DC0F09E}</Project>
+      <ReferenceOutputAssembly>false</ReferenceOutputAssembly>
+    </ProjectReference>
   </ItemGroup>
   <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets"/>
   <ImportGroup Label="ExtensionTargets"/>
diff --git a/projects/samples/particle_system.vcxproj b/projects/samples/particle_system.vcxproj
index 451388c..751bc23 100644
--- a/projects/samples/particle_system.vcxproj
+++ b/projects/samples/particle_system.vcxproj
@@ -50,7 +50,7 @@
   </PropertyGroup>
   <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
     <ClCompile>
-      <AdditionalIncludeDirectories>..\..\include;..\..\samples\angle\sample_util;C:\Program Files (x86)\Windows Kits\8.0\Include\shared;C:\Program Files (x86)\Windows Kits\8.0\Include\um;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <AdditionalIncludeDirectories>$(OutDir)obj\global_intermediate\angle;..\..\include;..\..\samples\angle\sample_util;..\..\util;C:\Program Files (x86)\Windows Kits\8.0\Include\shared;C:\Program Files (x86)\Windows Kits\8.0\Include\um;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
       <AdditionalOptions>/MP %(AdditionalOptions)</AdditionalOptions>
       <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
       <BufferSecurityCheck>true</BufferSecurityCheck>
@@ -68,6 +68,7 @@
     </ClCompile>
     <Lib>
       <AdditionalLibraryDirectories>C:/Program Files (x86)/Windows Kits/8.0/Lib/win8/um/x86;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
+      <TargetMachine>MachineX86</TargetMachine>
     </Lib>
     <Link>
       <AdditionalDependencies>kernel32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;user32.lib;uuid.lib;odbc32.lib;odbccp32.lib;delayimp.lib</AdditionalDependencies>
@@ -81,14 +82,14 @@
       <TargetMachine>MachineX86</TargetMachine>
     </Link>
     <ResourceCompile>
-      <AdditionalIncludeDirectories>..\..\include;..\..\samples\angle\sample_util;C:\Program Files (x86)\Windows Kits\8.0\Include\shared;C:\Program Files (x86)\Windows Kits\8.0\Include\um;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <AdditionalIncludeDirectories>$(OutDir)obj\global_intermediate\angle;..\..\include;..\..\samples\angle\sample_util;..\..\util;C:\Program Files (x86)\Windows Kits\8.0\Include\shared;C:\Program Files (x86)\Windows Kits\8.0\Include\um;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
       <Culture>0x0409</Culture>
       <PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
     </ResourceCompile>
   </ItemDefinitionGroup>
   <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
     <ClCompile>
-      <AdditionalIncludeDirectories>..\..\include;..\..\samples\angle\sample_util;C:\Program Files (x86)\Windows Kits\8.0\Include\shared;C:\Program Files (x86)\Windows Kits\8.0\Include\um;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <AdditionalIncludeDirectories>$(OutDir)obj\global_intermediate\angle;..\..\include;..\..\samples\angle\sample_util;..\..\util;C:\Program Files (x86)\Windows Kits\8.0\Include\shared;C:\Program Files (x86)\Windows Kits\8.0\Include\um;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
       <AdditionalOptions>/MP %(AdditionalOptions)</AdditionalOptions>
       <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
       <BufferSecurityCheck>true</BufferSecurityCheck>
@@ -119,13 +120,13 @@
       <TargetMachine>MachineX64</TargetMachine>
     </Link>
     <ResourceCompile>
-      <AdditionalIncludeDirectories>..\..\include;..\..\samples\angle\sample_util;C:\Program Files (x86)\Windows Kits\8.0\Include\shared;C:\Program Files (x86)\Windows Kits\8.0\Include\um;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <AdditionalIncludeDirectories>$(OutDir)obj\global_intermediate\angle;..\..\include;..\..\samples\angle\sample_util;..\..\util;C:\Program Files (x86)\Windows Kits\8.0\Include\shared;C:\Program Files (x86)\Windows Kits\8.0\Include\um;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
       <Culture>0x0409</Culture>
     </ResourceCompile>
   </ItemDefinitionGroup>
   <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
     <ClCompile>
-      <AdditionalIncludeDirectories>..\..\include;..\..\samples\angle\sample_util;C:\Program Files (x86)\Windows Kits\8.0\Include\shared;C:\Program Files (x86)\Windows Kits\8.0\Include\um;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <AdditionalIncludeDirectories>$(OutDir)obj\global_intermediate\angle;..\..\include;..\..\samples\angle\sample_util;..\..\util;C:\Program Files (x86)\Windows Kits\8.0\Include\shared;C:\Program Files (x86)\Windows Kits\8.0\Include\um;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
       <AdditionalOptions>/MP %(AdditionalOptions)</AdditionalOptions>
       <BufferSecurityCheck>true</BufferSecurityCheck>
       <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
@@ -142,6 +143,7 @@
     </ClCompile>
     <Lib>
       <AdditionalLibraryDirectories>C:/Program Files (x86)/Windows Kits/8.0/Lib/win8/um/x86;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
+      <TargetMachine>MachineX86</TargetMachine>
     </Lib>
     <Link>
       <AdditionalDependencies>kernel32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;user32.lib;uuid.lib;odbc32.lib;odbccp32.lib;delayimp.lib</AdditionalDependencies>
@@ -155,14 +157,14 @@
       <TargetMachine>MachineX86</TargetMachine>
     </Link>
     <ResourceCompile>
-      <AdditionalIncludeDirectories>..\..\include;..\..\samples\angle\sample_util;C:\Program Files (x86)\Windows Kits\8.0\Include\shared;C:\Program Files (x86)\Windows Kits\8.0\Include\um;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <AdditionalIncludeDirectories>$(OutDir)obj\global_intermediate\angle;..\..\include;..\..\samples\angle\sample_util;..\..\util;C:\Program Files (x86)\Windows Kits\8.0\Include\shared;C:\Program Files (x86)\Windows Kits\8.0\Include\um;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
       <Culture>0x0409</Culture>
       <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
     </ResourceCompile>
   </ItemDefinitionGroup>
   <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
     <ClCompile>
-      <AdditionalIncludeDirectories>..\..\include;..\..\samples\angle\sample_util;C:\Program Files (x86)\Windows Kits\8.0\Include\shared;C:\Program Files (x86)\Windows Kits\8.0\Include\um;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <AdditionalIncludeDirectories>$(OutDir)obj\global_intermediate\angle;..\..\include;..\..\samples\angle\sample_util;..\..\util;C:\Program Files (x86)\Windows Kits\8.0\Include\shared;C:\Program Files (x86)\Windows Kits\8.0\Include\um;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
       <AdditionalOptions>/MP %(AdditionalOptions)</AdditionalOptions>
       <BufferSecurityCheck>true</BufferSecurityCheck>
       <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
@@ -192,7 +194,7 @@
       <TargetMachine>MachineX64</TargetMachine>
     </Link>
     <ResourceCompile>
-      <AdditionalIncludeDirectories>..\..\include;..\..\samples\angle\sample_util;C:\Program Files (x86)\Windows Kits\8.0\Include\shared;C:\Program Files (x86)\Windows Kits\8.0\Include\um;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <AdditionalIncludeDirectories>$(OutDir)obj\global_intermediate\angle;..\..\include;..\..\samples\angle\sample_util;..\..\util;C:\Program Files (x86)\Windows Kits\8.0\Include\shared;C:\Program Files (x86)\Windows Kits\8.0\Include\um;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
       <Culture>0x0409</Culture>
     </ResourceCompile>
   </ItemDefinitionGroup>
@@ -223,6 +225,10 @@
       <Project>{7FBD6F69-B9A4-69F1-A12B-8DACB3F8CD81}</Project>
       <ReferenceOutputAssembly>false</ReferenceOutputAssembly>
     </ProjectReference>
+    <ProjectReference Include="..\util\angle_util.vcxproj">
+      <Project>{E4DD691C-228B-A904-A008-10E26DC0F09E}</Project>
+      <ReferenceOutputAssembly>false</ReferenceOutputAssembly>
+    </ProjectReference>
   </ItemGroup>
   <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets"/>
   <ImportGroup Label="ExtensionTargets"/>
diff --git a/projects/samples/post_sub_buffer.vcxproj b/projects/samples/post_sub_buffer.vcxproj
index c323973..44a985c 100644
--- a/projects/samples/post_sub_buffer.vcxproj
+++ b/projects/samples/post_sub_buffer.vcxproj
@@ -50,7 +50,7 @@
   </PropertyGroup>
   <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
     <ClCompile>
-      <AdditionalIncludeDirectories>..\..\include;..\..\samples\angle\sample_util;C:\Program Files (x86)\Windows Kits\8.0\Include\shared;C:\Program Files (x86)\Windows Kits\8.0\Include\um;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <AdditionalIncludeDirectories>$(OutDir)obj\global_intermediate\angle;..\..\include;..\..\samples\angle\sample_util;..\..\util;C:\Program Files (x86)\Windows Kits\8.0\Include\shared;C:\Program Files (x86)\Windows Kits\8.0\Include\um;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
       <AdditionalOptions>/MP %(AdditionalOptions)</AdditionalOptions>
       <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
       <BufferSecurityCheck>true</BufferSecurityCheck>
@@ -68,6 +68,7 @@
     </ClCompile>
     <Lib>
       <AdditionalLibraryDirectories>C:/Program Files (x86)/Windows Kits/8.0/Lib/win8/um/x86;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
+      <TargetMachine>MachineX86</TargetMachine>
     </Lib>
     <Link>
       <AdditionalDependencies>kernel32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;user32.lib;uuid.lib;odbc32.lib;odbccp32.lib;delayimp.lib</AdditionalDependencies>
@@ -81,14 +82,14 @@
       <TargetMachine>MachineX86</TargetMachine>
     </Link>
     <ResourceCompile>
-      <AdditionalIncludeDirectories>..\..\include;..\..\samples\angle\sample_util;C:\Program Files (x86)\Windows Kits\8.0\Include\shared;C:\Program Files (x86)\Windows Kits\8.0\Include\um;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <AdditionalIncludeDirectories>$(OutDir)obj\global_intermediate\angle;..\..\include;..\..\samples\angle\sample_util;..\..\util;C:\Program Files (x86)\Windows Kits\8.0\Include\shared;C:\Program Files (x86)\Windows Kits\8.0\Include\um;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
       <Culture>0x0409</Culture>
       <PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
     </ResourceCompile>
   </ItemDefinitionGroup>
   <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
     <ClCompile>
-      <AdditionalIncludeDirectories>..\..\include;..\..\samples\angle\sample_util;C:\Program Files (x86)\Windows Kits\8.0\Include\shared;C:\Program Files (x86)\Windows Kits\8.0\Include\um;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <AdditionalIncludeDirectories>$(OutDir)obj\global_intermediate\angle;..\..\include;..\..\samples\angle\sample_util;..\..\util;C:\Program Files (x86)\Windows Kits\8.0\Include\shared;C:\Program Files (x86)\Windows Kits\8.0\Include\um;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
       <AdditionalOptions>/MP %(AdditionalOptions)</AdditionalOptions>
       <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
       <BufferSecurityCheck>true</BufferSecurityCheck>
@@ -119,13 +120,13 @@
       <TargetMachine>MachineX64</TargetMachine>
     </Link>
     <ResourceCompile>
-      <AdditionalIncludeDirectories>..\..\include;..\..\samples\angle\sample_util;C:\Program Files (x86)\Windows Kits\8.0\Include\shared;C:\Program Files (x86)\Windows Kits\8.0\Include\um;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <AdditionalIncludeDirectories>$(OutDir)obj\global_intermediate\angle;..\..\include;..\..\samples\angle\sample_util;..\..\util;C:\Program Files (x86)\Windows Kits\8.0\Include\shared;C:\Program Files (x86)\Windows Kits\8.0\Include\um;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
       <Culture>0x0409</Culture>
     </ResourceCompile>
   </ItemDefinitionGroup>
   <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
     <ClCompile>
-      <AdditionalIncludeDirectories>..\..\include;..\..\samples\angle\sample_util;C:\Program Files (x86)\Windows Kits\8.0\Include\shared;C:\Program Files (x86)\Windows Kits\8.0\Include\um;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <AdditionalIncludeDirectories>$(OutDir)obj\global_intermediate\angle;..\..\include;..\..\samples\angle\sample_util;..\..\util;C:\Program Files (x86)\Windows Kits\8.0\Include\shared;C:\Program Files (x86)\Windows Kits\8.0\Include\um;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
       <AdditionalOptions>/MP %(AdditionalOptions)</AdditionalOptions>
       <BufferSecurityCheck>true</BufferSecurityCheck>
       <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
@@ -142,6 +143,7 @@
     </ClCompile>
     <Lib>
       <AdditionalLibraryDirectories>C:/Program Files (x86)/Windows Kits/8.0/Lib/win8/um/x86;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
+      <TargetMachine>MachineX86</TargetMachine>
     </Lib>
     <Link>
       <AdditionalDependencies>kernel32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;user32.lib;uuid.lib;odbc32.lib;odbccp32.lib;delayimp.lib</AdditionalDependencies>
@@ -155,14 +157,14 @@
       <TargetMachine>MachineX86</TargetMachine>
     </Link>
     <ResourceCompile>
-      <AdditionalIncludeDirectories>..\..\include;..\..\samples\angle\sample_util;C:\Program Files (x86)\Windows Kits\8.0\Include\shared;C:\Program Files (x86)\Windows Kits\8.0\Include\um;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <AdditionalIncludeDirectories>$(OutDir)obj\global_intermediate\angle;..\..\include;..\..\samples\angle\sample_util;..\..\util;C:\Program Files (x86)\Windows Kits\8.0\Include\shared;C:\Program Files (x86)\Windows Kits\8.0\Include\um;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
       <Culture>0x0409</Culture>
       <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
     </ResourceCompile>
   </ItemDefinitionGroup>
   <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
     <ClCompile>
-      <AdditionalIncludeDirectories>..\..\include;..\..\samples\angle\sample_util;C:\Program Files (x86)\Windows Kits\8.0\Include\shared;C:\Program Files (x86)\Windows Kits\8.0\Include\um;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <AdditionalIncludeDirectories>$(OutDir)obj\global_intermediate\angle;..\..\include;..\..\samples\angle\sample_util;..\..\util;C:\Program Files (x86)\Windows Kits\8.0\Include\shared;C:\Program Files (x86)\Windows Kits\8.0\Include\um;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
       <AdditionalOptions>/MP %(AdditionalOptions)</AdditionalOptions>
       <BufferSecurityCheck>true</BufferSecurityCheck>
       <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
@@ -192,7 +194,7 @@
       <TargetMachine>MachineX64</TargetMachine>
     </Link>
     <ResourceCompile>
-      <AdditionalIncludeDirectories>..\..\include;..\..\samples\angle\sample_util;C:\Program Files (x86)\Windows Kits\8.0\Include\shared;C:\Program Files (x86)\Windows Kits\8.0\Include\um;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <AdditionalIncludeDirectories>$(OutDir)obj\global_intermediate\angle;..\..\include;..\..\samples\angle\sample_util;..\..\util;C:\Program Files (x86)\Windows Kits\8.0\Include\shared;C:\Program Files (x86)\Windows Kits\8.0\Include\um;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
       <Culture>0x0409</Culture>
     </ResourceCompile>
   </ItemDefinitionGroup>
@@ -215,6 +217,10 @@
       <Project>{7FBD6F69-B9A4-69F1-A12B-8DACB3F8CD81}</Project>
       <ReferenceOutputAssembly>false</ReferenceOutputAssembly>
     </ProjectReference>
+    <ProjectReference Include="..\util\angle_util.vcxproj">
+      <Project>{E4DD691C-228B-A904-A008-10E26DC0F09E}</Project>
+      <ReferenceOutputAssembly>false</ReferenceOutputAssembly>
+    </ProjectReference>
   </ItemGroup>
   <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets"/>
   <ImportGroup Label="ExtensionTargets"/>
diff --git a/projects/samples/sample_util.vcxproj b/projects/samples/sample_util.vcxproj
index da4865a..5944555 100644
--- a/projects/samples/sample_util.vcxproj
+++ b/projects/samples/sample_util.vcxproj
@@ -50,7 +50,7 @@
   </PropertyGroup>
   <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
     <ClCompile>
-      <AdditionalIncludeDirectories>..\..\include;..\..\samples\angle\sample_util;C:\Program Files (x86)\Windows Kits\8.0\Include\shared;C:\Program Files (x86)\Windows Kits\8.0\Include\um;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <AdditionalIncludeDirectories>..\..\include;..\..\samples\angle\sample_util;$(OutDir)obj\global_intermediate\angle;..\..\util;C:\Program Files (x86)\Windows Kits\8.0\Include\shared;C:\Program Files (x86)\Windows Kits\8.0\Include\um;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
       <AdditionalOptions>/MP %(AdditionalOptions)</AdditionalOptions>
       <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
       <BufferSecurityCheck>true</BufferSecurityCheck>
@@ -69,6 +69,7 @@
     <Lib>
       <AdditionalLibraryDirectories>C:/Program Files (x86)/Windows Kits/8.0/Lib/win8/um/x86;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
       <OutputFile>$(OutDir)lib\$(ProjectName)$(TargetExt)</OutputFile>
+      <TargetMachine>MachineX86</TargetMachine>
     </Lib>
     <Link>
       <AdditionalDependencies>kernel32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;user32.lib;uuid.lib;odbc32.lib;odbccp32.lib;delayimp.lib</AdditionalDependencies>
@@ -81,14 +82,14 @@
       <TargetMachine>MachineX86</TargetMachine>
     </Link>
     <ResourceCompile>
-      <AdditionalIncludeDirectories>..\..\include;..\..\samples\angle\sample_util;C:\Program Files (x86)\Windows Kits\8.0\Include\shared;C:\Program Files (x86)\Windows Kits\8.0\Include\um;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <AdditionalIncludeDirectories>..\..\include;..\..\samples\angle\sample_util;$(OutDir)obj\global_intermediate\angle;..\..\util;C:\Program Files (x86)\Windows Kits\8.0\Include\shared;C:\Program Files (x86)\Windows Kits\8.0\Include\um;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
       <Culture>0x0409</Culture>
       <PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
     </ResourceCompile>
   </ItemDefinitionGroup>
   <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
     <ClCompile>
-      <AdditionalIncludeDirectories>..\..\include;..\..\samples\angle\sample_util;C:\Program Files (x86)\Windows Kits\8.0\Include\shared;C:\Program Files (x86)\Windows Kits\8.0\Include\um;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <AdditionalIncludeDirectories>..\..\include;..\..\samples\angle\sample_util;$(OutDir)obj\global_intermediate\angle;..\..\util;C:\Program Files (x86)\Windows Kits\8.0\Include\shared;C:\Program Files (x86)\Windows Kits\8.0\Include\um;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
       <AdditionalOptions>/MP %(AdditionalOptions)</AdditionalOptions>
       <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
       <BufferSecurityCheck>true</BufferSecurityCheck>
@@ -119,13 +120,13 @@
       <TargetMachine>MachineX64</TargetMachine>
     </Link>
     <ResourceCompile>
-      <AdditionalIncludeDirectories>..\..\include;..\..\samples\angle\sample_util;C:\Program Files (x86)\Windows Kits\8.0\Include\shared;C:\Program Files (x86)\Windows Kits\8.0\Include\um;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <AdditionalIncludeDirectories>..\..\include;..\..\samples\angle\sample_util;$(OutDir)obj\global_intermediate\angle;..\..\util;C:\Program Files (x86)\Windows Kits\8.0\Include\shared;C:\Program Files (x86)\Windows Kits\8.0\Include\um;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
       <Culture>0x0409</Culture>
     </ResourceCompile>
   </ItemDefinitionGroup>
   <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
     <ClCompile>
-      <AdditionalIncludeDirectories>..\..\include;..\..\samples\angle\sample_util;C:\Program Files (x86)\Windows Kits\8.0\Include\shared;C:\Program Files (x86)\Windows Kits\8.0\Include\um;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <AdditionalIncludeDirectories>..\..\include;..\..\samples\angle\sample_util;$(OutDir)obj\global_intermediate\angle;..\..\util;C:\Program Files (x86)\Windows Kits\8.0\Include\shared;C:\Program Files (x86)\Windows Kits\8.0\Include\um;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
       <AdditionalOptions>/MP %(AdditionalOptions)</AdditionalOptions>
       <BufferSecurityCheck>true</BufferSecurityCheck>
       <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
@@ -143,6 +144,7 @@
     <Lib>
       <AdditionalLibraryDirectories>C:/Program Files (x86)/Windows Kits/8.0/Lib/win8/um/x86;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
       <OutputFile>$(OutDir)lib\$(ProjectName)$(TargetExt)</OutputFile>
+      <TargetMachine>MachineX86</TargetMachine>
     </Lib>
     <Link>
       <AdditionalDependencies>kernel32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;user32.lib;uuid.lib;odbc32.lib;odbccp32.lib;delayimp.lib</AdditionalDependencies>
@@ -155,14 +157,14 @@
       <TargetMachine>MachineX86</TargetMachine>
     </Link>
     <ResourceCompile>
-      <AdditionalIncludeDirectories>..\..\include;..\..\samples\angle\sample_util;C:\Program Files (x86)\Windows Kits\8.0\Include\shared;C:\Program Files (x86)\Windows Kits\8.0\Include\um;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <AdditionalIncludeDirectories>..\..\include;..\..\samples\angle\sample_util;$(OutDir)obj\global_intermediate\angle;..\..\util;C:\Program Files (x86)\Windows Kits\8.0\Include\shared;C:\Program Files (x86)\Windows Kits\8.0\Include\um;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
       <Culture>0x0409</Culture>
       <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
     </ResourceCompile>
   </ItemDefinitionGroup>
   <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
     <ClCompile>
-      <AdditionalIncludeDirectories>..\..\include;..\..\samples\angle\sample_util;C:\Program Files (x86)\Windows Kits\8.0\Include\shared;C:\Program Files (x86)\Windows Kits\8.0\Include\um;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <AdditionalIncludeDirectories>..\..\include;..\..\samples\angle\sample_util;$(OutDir)obj\global_intermediate\angle;..\..\util;C:\Program Files (x86)\Windows Kits\8.0\Include\shared;C:\Program Files (x86)\Windows Kits\8.0\Include\um;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
       <AdditionalOptions>/MP %(AdditionalOptions)</AdditionalOptions>
       <BufferSecurityCheck>true</BufferSecurityCheck>
       <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
@@ -192,7 +194,7 @@
       <TargetMachine>MachineX64</TargetMachine>
     </Link>
     <ResourceCompile>
-      <AdditionalIncludeDirectories>..\..\include;..\..\samples\angle\sample_util;C:\Program Files (x86)\Windows Kits\8.0\Include\shared;C:\Program Files (x86)\Windows Kits\8.0\Include\um;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <AdditionalIncludeDirectories>..\..\include;..\..\samples\angle\sample_util;$(OutDir)obj\global_intermediate\angle;..\..\util;C:\Program Files (x86)\Windows Kits\8.0\Include\shared;C:\Program Files (x86)\Windows Kits\8.0\Include\um;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
       <Culture>0x0409</Culture>
     </ResourceCompile>
   </ItemDefinitionGroup>
@@ -200,36 +202,22 @@
     <None Include="..\..\samples\samples.gyp"/>
   </ItemGroup>
   <ItemGroup>
-    <ClInclude Include="..\..\samples\angle\sample_util\Window.h"/>
-    <ClInclude Include="..\..\samples\angle\sample_util\path_utils.h"/>
     <ClInclude Include="..\..\samples\angle\sample_util\Vector.h"/>
-    <ClInclude Include="..\..\samples\angle\sample_util\keyboard.h"/>
-    <ClInclude Include="..\..\samples\angle\sample_util\shader_utils.h"/>
-    <ClInclude Include="..\..\samples\angle\sample_util\Matrix.h"/>
-    <ClInclude Include="..\..\samples\angle\sample_util\Timer.h"/>
-    <ClInclude Include="..\..\samples\angle\sample_util\mouse.h"/>
     <ClInclude Include="..\..\samples\angle\sample_util\geometry_utils.h"/>
-    <ClInclude Include="..\..\samples\angle\sample_util\Event.h"/>
+    <ClInclude Include="..\..\samples\angle\sample_util\Matrix.h"/>
     <ClInclude Include="..\..\samples\angle\sample_util\random_utils.h"/>
     <ClInclude Include="..\..\samples\angle\sample_util\tga_utils.h"/>
     <ClInclude Include="..\..\samples\angle\sample_util\SampleApplication.h"/>
     <ClInclude Include="..\..\samples\angle\sample_util\texture_utils.h"/>
-    <ClInclude Include="..\..\samples\angle\sample_util\win32\Win32Timer.h"/>
-    <ClInclude Include="..\..\samples\angle\sample_util\win32\Win32Window.h"/>
   </ItemGroup>
   <ItemGroup>
-    <ClCompile Include="..\..\samples\angle\sample_util\Window.cpp"/>
     <ClCompile Include="..\..\samples\angle\sample_util\texture_utils.cpp"/>
-    <ClCompile Include="..\..\samples\angle\sample_util\Vector.cpp"/>
-    <ClCompile Include="..\..\samples\angle\sample_util\shader_utils.cpp"/>
     <ClCompile Include="..\..\samples\angle\sample_util\SampleApplication.cpp"/>
     <ClCompile Include="..\..\samples\angle\sample_util\geometry_utils.cpp"/>
+    <ClCompile Include="..\..\samples\angle\sample_util\Vector.cpp"/>
     <ClCompile Include="..\..\samples\angle\sample_util\tga_utils.cpp"/>
     <ClCompile Include="..\..\samples\angle\sample_util\random_utils.cpp"/>
     <ClCompile Include="..\..\samples\angle\sample_util\Matrix.cpp"/>
-    <ClCompile Include="..\..\samples\angle\sample_util\win32\Win32Timer.cpp"/>
-    <ClCompile Include="..\..\samples\angle\sample_util\win32\Win32Window.cpp"/>
-    <ClCompile Include="..\..\samples\angle\sample_util\win32\Win32_path_utils.cpp"/>
   </ItemGroup>
   <ItemGroup>
     <ProjectReference Include="..\src\libEGL.vcxproj">
diff --git a/projects/samples/sample_util.vcxproj.filters b/projects/samples/sample_util.vcxproj.filters
index 5cd3b69..7ac54a3 100644
--- a/projects/samples/sample_util.vcxproj.filters
+++ b/projects/samples/sample_util.vcxproj.filters
@@ -7,63 +7,33 @@
     <Filter Include="angle\sample_util">
       <UniqueIdentifier>{60D21765-6E5A-8668-B584-931D7874AF54}</UniqueIdentifier>
     </Filter>
-    <Filter Include="angle\sample_util\win32">
-      <UniqueIdentifier>{789FEF16-EFE7-512E-F91B-DF7E0D72FB79}</UniqueIdentifier>
-    </Filter>
   </ItemGroup>
   <ItemGroup>
     <None Include="..\..\samples\samples.gyp"/>
-    <ClCompile Include="..\..\samples\angle\sample_util\Window.cpp">
-      <Filter>angle\sample_util</Filter>
-    </ClCompile>
-    <ClInclude Include="..\..\samples\angle\sample_util\Window.h">
-      <Filter>angle\sample_util</Filter>
-    </ClInclude>
-    <ClCompile Include="..\..\samples\angle\sample_util\texture_utils.cpp">
-      <Filter>angle\sample_util</Filter>
-    </ClCompile>
-    <ClInclude Include="..\..\samples\angle\sample_util\path_utils.h">
-      <Filter>angle\sample_util</Filter>
-    </ClInclude>
-    <ClCompile Include="..\..\samples\angle\sample_util\Vector.cpp">
-      <Filter>angle\sample_util</Filter>
-    </ClCompile>
     <ClInclude Include="..\..\samples\angle\sample_util\Vector.h">
       <Filter>angle\sample_util</Filter>
     </ClInclude>
-    <ClInclude Include="..\..\samples\angle\sample_util\keyboard.h">
-      <Filter>angle\sample_util</Filter>
-    </ClInclude>
-    <ClInclude Include="..\..\samples\angle\sample_util\shader_utils.h">
-      <Filter>angle\sample_util</Filter>
-    </ClInclude>
-    <ClCompile Include="..\..\samples\angle\sample_util\shader_utils.cpp">
-      <Filter>angle\sample_util</Filter>
-    </ClCompile>
-    <ClInclude Include="..\..\samples\angle\sample_util\Matrix.h">
-      <Filter>angle\sample_util</Filter>
-    </ClInclude>
-    <ClInclude Include="..\..\samples\angle\sample_util\Timer.h">
-      <Filter>angle\sample_util</Filter>
-    </ClInclude>
-    <ClInclude Include="..\..\samples\angle\sample_util\mouse.h">
-      <Filter>angle\sample_util</Filter>
-    </ClInclude>
     <ClInclude Include="..\..\samples\angle\sample_util\geometry_utils.h">
       <Filter>angle\sample_util</Filter>
     </ClInclude>
-    <ClInclude Include="..\..\samples\angle\sample_util\Event.h">
+    <ClCompile Include="..\..\samples\angle\sample_util\texture_utils.cpp">
       <Filter>angle\sample_util</Filter>
-    </ClInclude>
+    </ClCompile>
     <ClCompile Include="..\..\samples\angle\sample_util\SampleApplication.cpp">
       <Filter>angle\sample_util</Filter>
     </ClCompile>
-    <ClCompile Include="..\..\samples\angle\sample_util\geometry_utils.cpp">
+    <ClInclude Include="..\..\samples\angle\sample_util\Matrix.h">
       <Filter>angle\sample_util</Filter>
-    </ClCompile>
+    </ClInclude>
     <ClInclude Include="..\..\samples\angle\sample_util\random_utils.h">
       <Filter>angle\sample_util</Filter>
     </ClInclude>
+    <ClCompile Include="..\..\samples\angle\sample_util\geometry_utils.cpp">
+      <Filter>angle\sample_util</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\samples\angle\sample_util\Vector.cpp">
+      <Filter>angle\sample_util</Filter>
+    </ClCompile>
     <ClCompile Include="..\..\samples\angle\sample_util\tga_utils.cpp">
       <Filter>angle\sample_util</Filter>
     </ClCompile>
@@ -82,20 +52,5 @@
     <ClInclude Include="..\..\samples\angle\sample_util\texture_utils.h">
       <Filter>angle\sample_util</Filter>
     </ClInclude>
-    <ClInclude Include="..\..\samples\angle\sample_util\win32\Win32Timer.h">
-      <Filter>angle\sample_util\win32</Filter>
-    </ClInclude>
-    <ClCompile Include="..\..\samples\angle\sample_util\win32\Win32Timer.cpp">
-      <Filter>angle\sample_util\win32</Filter>
-    </ClCompile>
-    <ClCompile Include="..\..\samples\angle\sample_util\win32\Win32Window.cpp">
-      <Filter>angle\sample_util\win32</Filter>
-    </ClCompile>
-    <ClInclude Include="..\..\samples\angle\sample_util\win32\Win32Window.h">
-      <Filter>angle\sample_util\win32</Filter>
-    </ClInclude>
-    <ClCompile Include="..\..\samples\angle\sample_util\win32\Win32_path_utils.cpp">
-      <Filter>angle\sample_util\win32</Filter>
-    </ClCompile>
   </ItemGroup>
 </Project>
diff --git a/projects/samples/samples.sln b/projects/samples/samples.sln
index 1b878b2..a0d4f12 100644
--- a/projects/samples/samples.sln
+++ b/projects/samples/samples.sln
@@ -1,5 +1,11 @@
 Microsoft Visual Studio Solution File, Format Version 13.00
 # Visual Studio 2013
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "angle_util", "..\util\angle_util.vcxproj", "{E4DD691C-228B-A904-A008-10E26DC0F09E}"
+	ProjectSection(ProjectDependencies) = postProject
+		{FBAEE4F6-562A-588F-01F9-72DCABB3B061} = {FBAEE4F6-562A-588F-01F9-72DCABB3B061}
+		{7FBD6F69-B9A4-69F1-A12B-8DACB3F8CD81} = {7FBD6F69-B9A4-69F1-A12B-8DACB3F8CD81}
+	EndProjectSection
+EndProject
 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "commit_id", "..\src\commit_id.vcxproj", "{3B7F5656-177F-52EE-26B3-D6A75368D0A9}"
 EndProject
 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "copy_compiler_dll", "..\src\copy_compiler_dll.vcxproj", "{22DC02D5-1598-943C-13E1-82185B469F81}"
@@ -30,6 +36,13 @@
 		{297C46B0-9263-A9EA-82B1-EA221E7D7C7F} = {297C46B0-9263-A9EA-82B1-EA221E7D7C7F}
 		{FBAEE4F6-562A-588F-01F9-72DCABB3B061} = {FBAEE4F6-562A-588F-01F9-72DCABB3B061}
 		{7FBD6F69-B9A4-69F1-A12B-8DACB3F8CD81} = {7FBD6F69-B9A4-69F1-A12B-8DACB3F8CD81}
+		{E4DD691C-228B-A904-A008-10E26DC0F09E} = {E4DD691C-228B-A904-A008-10E26DC0F09E}
+	EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libANGLE", "..\src\libANGLE.vcxproj", "{CAAA04EE-A56A-43FB-D011-1A56053C070C}"
+	ProjectSection(ProjectDependencies) = postProject
+		{3B7F5656-177F-52EE-26B3-D6A75368D0A9} = {3B7F5656-177F-52EE-26B3-D6A75368D0A9}
+		{22DC02D5-1598-943C-13E1-82185B469F81} = {22DC02D5-1598-943C-13E1-82185B469F81}
 	EndProjectSection
 EndProject
 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libEGL", "..\src\libEGL.vcxproj", "{FBAEE4F6-562A-588F-01F9-72DCABB3B061}"
@@ -40,11 +53,12 @@
 EndProject
 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libGLESv2", "..\src\libGLESv2.vcxproj", "{7FBD6F69-B9A4-69F1-A12B-8DACB3F8CD81}"
 	ProjectSection(ProjectDependencies) = postProject
+		{CAAA04EE-A56A-43FB-D011-1A56053C070C} = {CAAA04EE-A56A-43FB-D011-1A56053C070C}
 		{C15697F6-5057-016E-BD29-422971875679} = {C15697F6-5057-016E-BD29-422971875679}
-		{3B7F5656-177F-52EE-26B3-D6A75368D0A9} = {3B7F5656-177F-52EE-26B3-D6A75368D0A9}
-		{22DC02D5-1598-943C-13E1-82185B469F81} = {22DC02D5-1598-943C-13E1-82185B469F81}
 		{276D20F5-2943-414C-0FF6-21F4723A5CF6} = {276D20F5-2943-414C-0FF6-21F4723A5CF6}
 		{C7BAF548-697D-2DCB-9DF3-9D1506A7B444} = {C7BAF548-697D-2DCB-9DF3-9D1506A7B444}
+		{3B7F5656-177F-52EE-26B3-D6A75368D0A9} = {3B7F5656-177F-52EE-26B3-D6A75368D0A9}
+		{22DC02D5-1598-943C-13E1-82185B469F81} = {22DC02D5-1598-943C-13E1-82185B469F81}
 		{63FB0B97-D1D9-5158-8E85-7F5B1E403817} = {63FB0B97-D1D9-5158-8E85-7F5B1E403817}
 	EndProjectSection
 EndProject
@@ -53,6 +67,7 @@
 		{297C46B0-9263-A9EA-82B1-EA221E7D7C7F} = {297C46B0-9263-A9EA-82B1-EA221E7D7C7F}
 		{FBAEE4F6-562A-588F-01F9-72DCABB3B061} = {FBAEE4F6-562A-588F-01F9-72DCABB3B061}
 		{7FBD6F69-B9A4-69F1-A12B-8DACB3F8CD81} = {7FBD6F69-B9A4-69F1-A12B-8DACB3F8CD81}
+		{E4DD691C-228B-A904-A008-10E26DC0F09E} = {E4DD691C-228B-A904-A008-10E26DC0F09E}
 	EndProjectSection
 EndProject
 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "multi_texture", "multi_texture.vcxproj", "{37E1BB43-65DC-A25A-042E-30B88E6C75A2}"
@@ -60,6 +75,7 @@
 		{297C46B0-9263-A9EA-82B1-EA221E7D7C7F} = {297C46B0-9263-A9EA-82B1-EA221E7D7C7F}
 		{FBAEE4F6-562A-588F-01F9-72DCABB3B061} = {FBAEE4F6-562A-588F-01F9-72DCABB3B061}
 		{7FBD6F69-B9A4-69F1-A12B-8DACB3F8CD81} = {7FBD6F69-B9A4-69F1-A12B-8DACB3F8CD81}
+		{E4DD691C-228B-A904-A008-10E26DC0F09E} = {E4DD691C-228B-A904-A008-10E26DC0F09E}
 	EndProjectSection
 EndProject
 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "multiple_draw_buffers", "multiple_draw_buffers.vcxproj", "{58BE89D7-25D5-CC84-EDBF-412C12C59709}"
@@ -67,6 +83,7 @@
 		{297C46B0-9263-A9EA-82B1-EA221E7D7C7F} = {297C46B0-9263-A9EA-82B1-EA221E7D7C7F}
 		{FBAEE4F6-562A-588F-01F9-72DCABB3B061} = {FBAEE4F6-562A-588F-01F9-72DCABB3B061}
 		{7FBD6F69-B9A4-69F1-A12B-8DACB3F8CD81} = {7FBD6F69-B9A4-69F1-A12B-8DACB3F8CD81}
+		{E4DD691C-228B-A904-A008-10E26DC0F09E} = {E4DD691C-228B-A904-A008-10E26DC0F09E}
 	EndProjectSection
 EndProject
 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "particle_system", "particle_system.vcxproj", "{8C20B90A-FBCB-B63F-435A-3299A1C38B2C}"
@@ -74,6 +91,7 @@
 		{297C46B0-9263-A9EA-82B1-EA221E7D7C7F} = {297C46B0-9263-A9EA-82B1-EA221E7D7C7F}
 		{FBAEE4F6-562A-588F-01F9-72DCABB3B061} = {FBAEE4F6-562A-588F-01F9-72DCABB3B061}
 		{7FBD6F69-B9A4-69F1-A12B-8DACB3F8CD81} = {7FBD6F69-B9A4-69F1-A12B-8DACB3F8CD81}
+		{E4DD691C-228B-A904-A008-10E26DC0F09E} = {E4DD691C-228B-A904-A008-10E26DC0F09E}
 	EndProjectSection
 EndProject
 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "post_sub_buffer", "post_sub_buffer.vcxproj", "{CBE3D362-43EA-60FC-D5AC-490039CA449A}"
@@ -81,6 +99,7 @@
 		{297C46B0-9263-A9EA-82B1-EA221E7D7C7F} = {297C46B0-9263-A9EA-82B1-EA221E7D7C7F}
 		{FBAEE4F6-562A-588F-01F9-72DCABB3B061} = {FBAEE4F6-562A-588F-01F9-72DCABB3B061}
 		{7FBD6F69-B9A4-69F1-A12B-8DACB3F8CD81} = {7FBD6F69-B9A4-69F1-A12B-8DACB3F8CD81}
+		{E4DD691C-228B-A904-A008-10E26DC0F09E} = {E4DD691C-228B-A904-A008-10E26DC0F09E}
 	EndProjectSection
 EndProject
 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "preprocessor", "..\src\preprocessor.vcxproj", "{C7BAF548-697D-2DCB-9DF3-9D1506A7B444}"
@@ -96,6 +115,7 @@
 		{297C46B0-9263-A9EA-82B1-EA221E7D7C7F} = {297C46B0-9263-A9EA-82B1-EA221E7D7C7F}
 		{FBAEE4F6-562A-588F-01F9-72DCABB3B061} = {FBAEE4F6-562A-588F-01F9-72DCABB3B061}
 		{7FBD6F69-B9A4-69F1-A12B-8DACB3F8CD81} = {7FBD6F69-B9A4-69F1-A12B-8DACB3F8CD81}
+		{E4DD691C-228B-A904-A008-10E26DC0F09E} = {E4DD691C-228B-A904-A008-10E26DC0F09E}
 	EndProjectSection
 EndProject
 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "simple_texture_2d", "simple_texture_2d.vcxproj", "{0BD6333E-E82C-7665-C386-CDA40096413D}"
@@ -103,6 +123,7 @@
 		{297C46B0-9263-A9EA-82B1-EA221E7D7C7F} = {297C46B0-9263-A9EA-82B1-EA221E7D7C7F}
 		{FBAEE4F6-562A-588F-01F9-72DCABB3B061} = {FBAEE4F6-562A-588F-01F9-72DCABB3B061}
 		{7FBD6F69-B9A4-69F1-A12B-8DACB3F8CD81} = {7FBD6F69-B9A4-69F1-A12B-8DACB3F8CD81}
+		{E4DD691C-228B-A904-A008-10E26DC0F09E} = {E4DD691C-228B-A904-A008-10E26DC0F09E}
 	EndProjectSection
 EndProject
 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "simple_texture_cubemap", "simple_texture_cubemap.vcxproj", "{93B7F18A-947E-69A1-9CD8-D1E5144E792A}"
@@ -110,6 +131,7 @@
 		{297C46B0-9263-A9EA-82B1-EA221E7D7C7F} = {297C46B0-9263-A9EA-82B1-EA221E7D7C7F}
 		{FBAEE4F6-562A-588F-01F9-72DCABB3B061} = {FBAEE4F6-562A-588F-01F9-72DCABB3B061}
 		{7FBD6F69-B9A4-69F1-A12B-8DACB3F8CD81} = {7FBD6F69-B9A4-69F1-A12B-8DACB3F8CD81}
+		{E4DD691C-228B-A904-A008-10E26DC0F09E} = {E4DD691C-228B-A904-A008-10E26DC0F09E}
 	EndProjectSection
 EndProject
 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "simple_vertex_shader", "simple_vertex_shader.vcxproj", "{459E5678-892C-4EF9-6ED8-0D9E5272B4FF}"
@@ -117,6 +139,7 @@
 		{297C46B0-9263-A9EA-82B1-EA221E7D7C7F} = {297C46B0-9263-A9EA-82B1-EA221E7D7C7F}
 		{FBAEE4F6-562A-588F-01F9-72DCABB3B061} = {FBAEE4F6-562A-588F-01F9-72DCABB3B061}
 		{7FBD6F69-B9A4-69F1-A12B-8DACB3F8CD81} = {7FBD6F69-B9A4-69F1-A12B-8DACB3F8CD81}
+		{E4DD691C-228B-A904-A008-10E26DC0F09E} = {E4DD691C-228B-A904-A008-10E26DC0F09E}
 	EndProjectSection
 EndProject
 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "stencil_operations", "stencil_operations.vcxproj", "{92582B26-5131-8C32-39D9-5768C7FA12B4}"
@@ -124,6 +147,7 @@
 		{297C46B0-9263-A9EA-82B1-EA221E7D7C7F} = {297C46B0-9263-A9EA-82B1-EA221E7D7C7F}
 		{FBAEE4F6-562A-588F-01F9-72DCABB3B061} = {FBAEE4F6-562A-588F-01F9-72DCABB3B061}
 		{7FBD6F69-B9A4-69F1-A12B-8DACB3F8CD81} = {7FBD6F69-B9A4-69F1-A12B-8DACB3F8CD81}
+		{E4DD691C-228B-A904-A008-10E26DC0F09E} = {E4DD691C-228B-A904-A008-10E26DC0F09E}
 	EndProjectSection
 EndProject
 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "texture_wrap", "texture_wrap.vcxproj", "{46160987-0221-9E14-3B88-80F9FCFCFFBF}"
@@ -131,6 +155,7 @@
 		{297C46B0-9263-A9EA-82B1-EA221E7D7C7F} = {297C46B0-9263-A9EA-82B1-EA221E7D7C7F}
 		{FBAEE4F6-562A-588F-01F9-72DCABB3B061} = {FBAEE4F6-562A-588F-01F9-72DCABB3B061}
 		{7FBD6F69-B9A4-69F1-A12B-8DACB3F8CD81} = {7FBD6F69-B9A4-69F1-A12B-8DACB3F8CD81}
+		{E4DD691C-228B-A904-A008-10E26DC0F09E} = {E4DD691C-228B-A904-A008-10E26DC0F09E}
 	EndProjectSection
 EndProject
 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "translator", "..\src\translator.vcxproj", "{C15697F6-5057-016E-BD29-422971875679}"
@@ -331,6 +356,14 @@
 		{C7BAF548-697D-2DCB-9DF3-9D1506A7B444}.Release|x64.Build.0 = Release|x64
 		{C7BAF548-697D-2DCB-9DF3-9D1506A7B444}.Release|Win32.ActiveCfg = Release|Win32
 		{C7BAF548-697D-2DCB-9DF3-9D1506A7B444}.Release|Win32.Build.0 = Release|Win32
+		{CAAA04EE-A56A-43FB-D011-1A56053C070C}.Debug|x64.ActiveCfg = Debug|x64
+		{CAAA04EE-A56A-43FB-D011-1A56053C070C}.Debug|x64.Build.0 = Debug|x64
+		{CAAA04EE-A56A-43FB-D011-1A56053C070C}.Debug|Win32.ActiveCfg = Debug|Win32
+		{CAAA04EE-A56A-43FB-D011-1A56053C070C}.Debug|Win32.Build.0 = Debug|Win32
+		{CAAA04EE-A56A-43FB-D011-1A56053C070C}.Release|x64.ActiveCfg = Release|x64
+		{CAAA04EE-A56A-43FB-D011-1A56053C070C}.Release|x64.Build.0 = Release|x64
+		{CAAA04EE-A56A-43FB-D011-1A56053C070C}.Release|Win32.ActiveCfg = Release|Win32
+		{CAAA04EE-A56A-43FB-D011-1A56053C070C}.Release|Win32.Build.0 = Release|Win32
 		{CBE3D362-43EA-60FC-D5AC-490039CA449A}.Debug|x64.ActiveCfg = Debug|x64
 		{CBE3D362-43EA-60FC-D5AC-490039CA449A}.Debug|x64.Build.0 = Debug|x64
 		{CBE3D362-43EA-60FC-D5AC-490039CA449A}.Debug|Win32.ActiveCfg = Debug|Win32
@@ -339,6 +372,14 @@
 		{CBE3D362-43EA-60FC-D5AC-490039CA449A}.Release|x64.Build.0 = Release|x64
 		{CBE3D362-43EA-60FC-D5AC-490039CA449A}.Release|Win32.ActiveCfg = Release|Win32
 		{CBE3D362-43EA-60FC-D5AC-490039CA449A}.Release|Win32.Build.0 = Release|Win32
+		{E4DD691C-228B-A904-A008-10E26DC0F09E}.Debug|x64.ActiveCfg = Debug|x64
+		{E4DD691C-228B-A904-A008-10E26DC0F09E}.Debug|x64.Build.0 = Debug|x64
+		{E4DD691C-228B-A904-A008-10E26DC0F09E}.Debug|Win32.ActiveCfg = Debug|Win32
+		{E4DD691C-228B-A904-A008-10E26DC0F09E}.Debug|Win32.Build.0 = Debug|Win32
+		{E4DD691C-228B-A904-A008-10E26DC0F09E}.Release|x64.ActiveCfg = Release|x64
+		{E4DD691C-228B-A904-A008-10E26DC0F09E}.Release|x64.Build.0 = Release|x64
+		{E4DD691C-228B-A904-A008-10E26DC0F09E}.Release|Win32.ActiveCfg = Release|Win32
+		{E4DD691C-228B-A904-A008-10E26DC0F09E}.Release|Win32.Build.0 = Release|Win32
 		{FBAEE4F6-562A-588F-01F9-72DCABB3B061}.Debug|x64.ActiveCfg = Debug|x64
 		{FBAEE4F6-562A-588F-01F9-72DCABB3B061}.Debug|x64.Build.0 = Debug|x64
 		{FBAEE4F6-562A-588F-01F9-72DCABB3B061}.Debug|Win32.ActiveCfg = Debug|Win32
diff --git a/projects/samples/simple_instancing.vcxproj b/projects/samples/simple_instancing.vcxproj
index 189b99a..577f0d3 100644
--- a/projects/samples/simple_instancing.vcxproj
+++ b/projects/samples/simple_instancing.vcxproj
@@ -50,7 +50,7 @@
   </PropertyGroup>
   <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
     <ClCompile>
-      <AdditionalIncludeDirectories>..\..\include;..\..\samples\angle\sample_util;C:\Program Files (x86)\Windows Kits\8.0\Include\shared;C:\Program Files (x86)\Windows Kits\8.0\Include\um;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <AdditionalIncludeDirectories>$(OutDir)obj\global_intermediate\angle;..\..\include;..\..\samples\angle\sample_util;..\..\util;C:\Program Files (x86)\Windows Kits\8.0\Include\shared;C:\Program Files (x86)\Windows Kits\8.0\Include\um;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
       <AdditionalOptions>/MP %(AdditionalOptions)</AdditionalOptions>
       <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
       <BufferSecurityCheck>true</BufferSecurityCheck>
@@ -68,6 +68,7 @@
     </ClCompile>
     <Lib>
       <AdditionalLibraryDirectories>C:/Program Files (x86)/Windows Kits/8.0/Lib/win8/um/x86;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
+      <TargetMachine>MachineX86</TargetMachine>
     </Lib>
     <Link>
       <AdditionalDependencies>kernel32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;user32.lib;uuid.lib;odbc32.lib;odbccp32.lib;delayimp.lib</AdditionalDependencies>
@@ -81,14 +82,14 @@
       <TargetMachine>MachineX86</TargetMachine>
     </Link>
     <ResourceCompile>
-      <AdditionalIncludeDirectories>..\..\include;..\..\samples\angle\sample_util;C:\Program Files (x86)\Windows Kits\8.0\Include\shared;C:\Program Files (x86)\Windows Kits\8.0\Include\um;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <AdditionalIncludeDirectories>$(OutDir)obj\global_intermediate\angle;..\..\include;..\..\samples\angle\sample_util;..\..\util;C:\Program Files (x86)\Windows Kits\8.0\Include\shared;C:\Program Files (x86)\Windows Kits\8.0\Include\um;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
       <Culture>0x0409</Culture>
       <PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
     </ResourceCompile>
   </ItemDefinitionGroup>
   <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
     <ClCompile>
-      <AdditionalIncludeDirectories>..\..\include;..\..\samples\angle\sample_util;C:\Program Files (x86)\Windows Kits\8.0\Include\shared;C:\Program Files (x86)\Windows Kits\8.0\Include\um;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <AdditionalIncludeDirectories>$(OutDir)obj\global_intermediate\angle;..\..\include;..\..\samples\angle\sample_util;..\..\util;C:\Program Files (x86)\Windows Kits\8.0\Include\shared;C:\Program Files (x86)\Windows Kits\8.0\Include\um;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
       <AdditionalOptions>/MP %(AdditionalOptions)</AdditionalOptions>
       <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
       <BufferSecurityCheck>true</BufferSecurityCheck>
@@ -119,13 +120,13 @@
       <TargetMachine>MachineX64</TargetMachine>
     </Link>
     <ResourceCompile>
-      <AdditionalIncludeDirectories>..\..\include;..\..\samples\angle\sample_util;C:\Program Files (x86)\Windows Kits\8.0\Include\shared;C:\Program Files (x86)\Windows Kits\8.0\Include\um;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <AdditionalIncludeDirectories>$(OutDir)obj\global_intermediate\angle;..\..\include;..\..\samples\angle\sample_util;..\..\util;C:\Program Files (x86)\Windows Kits\8.0\Include\shared;C:\Program Files (x86)\Windows Kits\8.0\Include\um;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
       <Culture>0x0409</Culture>
     </ResourceCompile>
   </ItemDefinitionGroup>
   <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
     <ClCompile>
-      <AdditionalIncludeDirectories>..\..\include;..\..\samples\angle\sample_util;C:\Program Files (x86)\Windows Kits\8.0\Include\shared;C:\Program Files (x86)\Windows Kits\8.0\Include\um;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <AdditionalIncludeDirectories>$(OutDir)obj\global_intermediate\angle;..\..\include;..\..\samples\angle\sample_util;..\..\util;C:\Program Files (x86)\Windows Kits\8.0\Include\shared;C:\Program Files (x86)\Windows Kits\8.0\Include\um;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
       <AdditionalOptions>/MP %(AdditionalOptions)</AdditionalOptions>
       <BufferSecurityCheck>true</BufferSecurityCheck>
       <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
@@ -142,6 +143,7 @@
     </ClCompile>
     <Lib>
       <AdditionalLibraryDirectories>C:/Program Files (x86)/Windows Kits/8.0/Lib/win8/um/x86;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
+      <TargetMachine>MachineX86</TargetMachine>
     </Lib>
     <Link>
       <AdditionalDependencies>kernel32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;user32.lib;uuid.lib;odbc32.lib;odbccp32.lib;delayimp.lib</AdditionalDependencies>
@@ -155,14 +157,14 @@
       <TargetMachine>MachineX86</TargetMachine>
     </Link>
     <ResourceCompile>
-      <AdditionalIncludeDirectories>..\..\include;..\..\samples\angle\sample_util;C:\Program Files (x86)\Windows Kits\8.0\Include\shared;C:\Program Files (x86)\Windows Kits\8.0\Include\um;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <AdditionalIncludeDirectories>$(OutDir)obj\global_intermediate\angle;..\..\include;..\..\samples\angle\sample_util;..\..\util;C:\Program Files (x86)\Windows Kits\8.0\Include\shared;C:\Program Files (x86)\Windows Kits\8.0\Include\um;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
       <Culture>0x0409</Culture>
       <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
     </ResourceCompile>
   </ItemDefinitionGroup>
   <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
     <ClCompile>
-      <AdditionalIncludeDirectories>..\..\include;..\..\samples\angle\sample_util;C:\Program Files (x86)\Windows Kits\8.0\Include\shared;C:\Program Files (x86)\Windows Kits\8.0\Include\um;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <AdditionalIncludeDirectories>$(OutDir)obj\global_intermediate\angle;..\..\include;..\..\samples\angle\sample_util;..\..\util;C:\Program Files (x86)\Windows Kits\8.0\Include\shared;C:\Program Files (x86)\Windows Kits\8.0\Include\um;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
       <AdditionalOptions>/MP %(AdditionalOptions)</AdditionalOptions>
       <BufferSecurityCheck>true</BufferSecurityCheck>
       <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
@@ -192,7 +194,7 @@
       <TargetMachine>MachineX64</TargetMachine>
     </Link>
     <ResourceCompile>
-      <AdditionalIncludeDirectories>..\..\include;..\..\samples\angle\sample_util;C:\Program Files (x86)\Windows Kits\8.0\Include\shared;C:\Program Files (x86)\Windows Kits\8.0\Include\um;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <AdditionalIncludeDirectories>$(OutDir)obj\global_intermediate\angle;..\..\include;..\..\samples\angle\sample_util;..\..\util;C:\Program Files (x86)\Windows Kits\8.0\Include\shared;C:\Program Files (x86)\Windows Kits\8.0\Include\um;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
       <Culture>0x0409</Culture>
     </ResourceCompile>
   </ItemDefinitionGroup>
@@ -215,6 +217,10 @@
       <Project>{7FBD6F69-B9A4-69F1-A12B-8DACB3F8CD81}</Project>
       <ReferenceOutputAssembly>false</ReferenceOutputAssembly>
     </ProjectReference>
+    <ProjectReference Include="..\util\angle_util.vcxproj">
+      <Project>{E4DD691C-228B-A904-A008-10E26DC0F09E}</Project>
+      <ReferenceOutputAssembly>false</ReferenceOutputAssembly>
+    </ProjectReference>
   </ItemGroup>
   <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets"/>
   <ImportGroup Label="ExtensionTargets"/>
diff --git a/projects/samples/simple_texture_2d.vcxproj b/projects/samples/simple_texture_2d.vcxproj
index 50e0e3f..afd56a0 100644
--- a/projects/samples/simple_texture_2d.vcxproj
+++ b/projects/samples/simple_texture_2d.vcxproj
@@ -50,7 +50,7 @@
   </PropertyGroup>
   <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
     <ClCompile>
-      <AdditionalIncludeDirectories>..\..\include;..\..\samples\angle\sample_util;C:\Program Files (x86)\Windows Kits\8.0\Include\shared;C:\Program Files (x86)\Windows Kits\8.0\Include\um;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <AdditionalIncludeDirectories>$(OutDir)obj\global_intermediate\angle;..\..\include;..\..\samples\angle\sample_util;..\..\util;C:\Program Files (x86)\Windows Kits\8.0\Include\shared;C:\Program Files (x86)\Windows Kits\8.0\Include\um;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
       <AdditionalOptions>/MP %(AdditionalOptions)</AdditionalOptions>
       <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
       <BufferSecurityCheck>true</BufferSecurityCheck>
@@ -68,6 +68,7 @@
     </ClCompile>
     <Lib>
       <AdditionalLibraryDirectories>C:/Program Files (x86)/Windows Kits/8.0/Lib/win8/um/x86;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
+      <TargetMachine>MachineX86</TargetMachine>
     </Lib>
     <Link>
       <AdditionalDependencies>kernel32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;user32.lib;uuid.lib;odbc32.lib;odbccp32.lib;delayimp.lib</AdditionalDependencies>
@@ -81,14 +82,14 @@
       <TargetMachine>MachineX86</TargetMachine>
     </Link>
     <ResourceCompile>
-      <AdditionalIncludeDirectories>..\..\include;..\..\samples\angle\sample_util;C:\Program Files (x86)\Windows Kits\8.0\Include\shared;C:\Program Files (x86)\Windows Kits\8.0\Include\um;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <AdditionalIncludeDirectories>$(OutDir)obj\global_intermediate\angle;..\..\include;..\..\samples\angle\sample_util;..\..\util;C:\Program Files (x86)\Windows Kits\8.0\Include\shared;C:\Program Files (x86)\Windows Kits\8.0\Include\um;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
       <Culture>0x0409</Culture>
       <PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
     </ResourceCompile>
   </ItemDefinitionGroup>
   <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
     <ClCompile>
-      <AdditionalIncludeDirectories>..\..\include;..\..\samples\angle\sample_util;C:\Program Files (x86)\Windows Kits\8.0\Include\shared;C:\Program Files (x86)\Windows Kits\8.0\Include\um;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <AdditionalIncludeDirectories>$(OutDir)obj\global_intermediate\angle;..\..\include;..\..\samples\angle\sample_util;..\..\util;C:\Program Files (x86)\Windows Kits\8.0\Include\shared;C:\Program Files (x86)\Windows Kits\8.0\Include\um;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
       <AdditionalOptions>/MP %(AdditionalOptions)</AdditionalOptions>
       <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
       <BufferSecurityCheck>true</BufferSecurityCheck>
@@ -119,13 +120,13 @@
       <TargetMachine>MachineX64</TargetMachine>
     </Link>
     <ResourceCompile>
-      <AdditionalIncludeDirectories>..\..\include;..\..\samples\angle\sample_util;C:\Program Files (x86)\Windows Kits\8.0\Include\shared;C:\Program Files (x86)\Windows Kits\8.0\Include\um;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <AdditionalIncludeDirectories>$(OutDir)obj\global_intermediate\angle;..\..\include;..\..\samples\angle\sample_util;..\..\util;C:\Program Files (x86)\Windows Kits\8.0\Include\shared;C:\Program Files (x86)\Windows Kits\8.0\Include\um;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
       <Culture>0x0409</Culture>
     </ResourceCompile>
   </ItemDefinitionGroup>
   <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
     <ClCompile>
-      <AdditionalIncludeDirectories>..\..\include;..\..\samples\angle\sample_util;C:\Program Files (x86)\Windows Kits\8.0\Include\shared;C:\Program Files (x86)\Windows Kits\8.0\Include\um;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <AdditionalIncludeDirectories>$(OutDir)obj\global_intermediate\angle;..\..\include;..\..\samples\angle\sample_util;..\..\util;C:\Program Files (x86)\Windows Kits\8.0\Include\shared;C:\Program Files (x86)\Windows Kits\8.0\Include\um;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
       <AdditionalOptions>/MP %(AdditionalOptions)</AdditionalOptions>
       <BufferSecurityCheck>true</BufferSecurityCheck>
       <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
@@ -142,6 +143,7 @@
     </ClCompile>
     <Lib>
       <AdditionalLibraryDirectories>C:/Program Files (x86)/Windows Kits/8.0/Lib/win8/um/x86;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
+      <TargetMachine>MachineX86</TargetMachine>
     </Lib>
     <Link>
       <AdditionalDependencies>kernel32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;user32.lib;uuid.lib;odbc32.lib;odbccp32.lib;delayimp.lib</AdditionalDependencies>
@@ -155,14 +157,14 @@
       <TargetMachine>MachineX86</TargetMachine>
     </Link>
     <ResourceCompile>
-      <AdditionalIncludeDirectories>..\..\include;..\..\samples\angle\sample_util;C:\Program Files (x86)\Windows Kits\8.0\Include\shared;C:\Program Files (x86)\Windows Kits\8.0\Include\um;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <AdditionalIncludeDirectories>$(OutDir)obj\global_intermediate\angle;..\..\include;..\..\samples\angle\sample_util;..\..\util;C:\Program Files (x86)\Windows Kits\8.0\Include\shared;C:\Program Files (x86)\Windows Kits\8.0\Include\um;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
       <Culture>0x0409</Culture>
       <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
     </ResourceCompile>
   </ItemDefinitionGroup>
   <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
     <ClCompile>
-      <AdditionalIncludeDirectories>..\..\include;..\..\samples\angle\sample_util;C:\Program Files (x86)\Windows Kits\8.0\Include\shared;C:\Program Files (x86)\Windows Kits\8.0\Include\um;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <AdditionalIncludeDirectories>$(OutDir)obj\global_intermediate\angle;..\..\include;..\..\samples\angle\sample_util;..\..\util;C:\Program Files (x86)\Windows Kits\8.0\Include\shared;C:\Program Files (x86)\Windows Kits\8.0\Include\um;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
       <AdditionalOptions>/MP %(AdditionalOptions)</AdditionalOptions>
       <BufferSecurityCheck>true</BufferSecurityCheck>
       <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
@@ -192,7 +194,7 @@
       <TargetMachine>MachineX64</TargetMachine>
     </Link>
     <ResourceCompile>
-      <AdditionalIncludeDirectories>..\..\include;..\..\samples\angle\sample_util;C:\Program Files (x86)\Windows Kits\8.0\Include\shared;C:\Program Files (x86)\Windows Kits\8.0\Include\um;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <AdditionalIncludeDirectories>$(OutDir)obj\global_intermediate\angle;..\..\include;..\..\samples\angle\sample_util;..\..\util;C:\Program Files (x86)\Windows Kits\8.0\Include\shared;C:\Program Files (x86)\Windows Kits\8.0\Include\um;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
       <Culture>0x0409</Culture>
     </ResourceCompile>
   </ItemDefinitionGroup>
@@ -215,6 +217,10 @@
       <Project>{7FBD6F69-B9A4-69F1-A12B-8DACB3F8CD81}</Project>
       <ReferenceOutputAssembly>false</ReferenceOutputAssembly>
     </ProjectReference>
+    <ProjectReference Include="..\util\angle_util.vcxproj">
+      <Project>{E4DD691C-228B-A904-A008-10E26DC0F09E}</Project>
+      <ReferenceOutputAssembly>false</ReferenceOutputAssembly>
+    </ProjectReference>
   </ItemGroup>
   <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets"/>
   <ImportGroup Label="ExtensionTargets"/>
diff --git a/projects/samples/simple_texture_cubemap.vcxproj b/projects/samples/simple_texture_cubemap.vcxproj
index 8a949cd..037e1ba 100644
--- a/projects/samples/simple_texture_cubemap.vcxproj
+++ b/projects/samples/simple_texture_cubemap.vcxproj
@@ -50,7 +50,7 @@
   </PropertyGroup>
   <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
     <ClCompile>
-      <AdditionalIncludeDirectories>..\..\include;..\..\samples\angle\sample_util;C:\Program Files (x86)\Windows Kits\8.0\Include\shared;C:\Program Files (x86)\Windows Kits\8.0\Include\um;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <AdditionalIncludeDirectories>$(OutDir)obj\global_intermediate\angle;..\..\include;..\..\samples\angle\sample_util;..\..\util;C:\Program Files (x86)\Windows Kits\8.0\Include\shared;C:\Program Files (x86)\Windows Kits\8.0\Include\um;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
       <AdditionalOptions>/MP %(AdditionalOptions)</AdditionalOptions>
       <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
       <BufferSecurityCheck>true</BufferSecurityCheck>
@@ -68,6 +68,7 @@
     </ClCompile>
     <Lib>
       <AdditionalLibraryDirectories>C:/Program Files (x86)/Windows Kits/8.0/Lib/win8/um/x86;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
+      <TargetMachine>MachineX86</TargetMachine>
     </Lib>
     <Link>
       <AdditionalDependencies>kernel32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;user32.lib;uuid.lib;odbc32.lib;odbccp32.lib;delayimp.lib</AdditionalDependencies>
@@ -81,14 +82,14 @@
       <TargetMachine>MachineX86</TargetMachine>
     </Link>
     <ResourceCompile>
-      <AdditionalIncludeDirectories>..\..\include;..\..\samples\angle\sample_util;C:\Program Files (x86)\Windows Kits\8.0\Include\shared;C:\Program Files (x86)\Windows Kits\8.0\Include\um;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <AdditionalIncludeDirectories>$(OutDir)obj\global_intermediate\angle;..\..\include;..\..\samples\angle\sample_util;..\..\util;C:\Program Files (x86)\Windows Kits\8.0\Include\shared;C:\Program Files (x86)\Windows Kits\8.0\Include\um;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
       <Culture>0x0409</Culture>
       <PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
     </ResourceCompile>
   </ItemDefinitionGroup>
   <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
     <ClCompile>
-      <AdditionalIncludeDirectories>..\..\include;..\..\samples\angle\sample_util;C:\Program Files (x86)\Windows Kits\8.0\Include\shared;C:\Program Files (x86)\Windows Kits\8.0\Include\um;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <AdditionalIncludeDirectories>$(OutDir)obj\global_intermediate\angle;..\..\include;..\..\samples\angle\sample_util;..\..\util;C:\Program Files (x86)\Windows Kits\8.0\Include\shared;C:\Program Files (x86)\Windows Kits\8.0\Include\um;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
       <AdditionalOptions>/MP %(AdditionalOptions)</AdditionalOptions>
       <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
       <BufferSecurityCheck>true</BufferSecurityCheck>
@@ -119,13 +120,13 @@
       <TargetMachine>MachineX64</TargetMachine>
     </Link>
     <ResourceCompile>
-      <AdditionalIncludeDirectories>..\..\include;..\..\samples\angle\sample_util;C:\Program Files (x86)\Windows Kits\8.0\Include\shared;C:\Program Files (x86)\Windows Kits\8.0\Include\um;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <AdditionalIncludeDirectories>$(OutDir)obj\global_intermediate\angle;..\..\include;..\..\samples\angle\sample_util;..\..\util;C:\Program Files (x86)\Windows Kits\8.0\Include\shared;C:\Program Files (x86)\Windows Kits\8.0\Include\um;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
       <Culture>0x0409</Culture>
     </ResourceCompile>
   </ItemDefinitionGroup>
   <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
     <ClCompile>
-      <AdditionalIncludeDirectories>..\..\include;..\..\samples\angle\sample_util;C:\Program Files (x86)\Windows Kits\8.0\Include\shared;C:\Program Files (x86)\Windows Kits\8.0\Include\um;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <AdditionalIncludeDirectories>$(OutDir)obj\global_intermediate\angle;..\..\include;..\..\samples\angle\sample_util;..\..\util;C:\Program Files (x86)\Windows Kits\8.0\Include\shared;C:\Program Files (x86)\Windows Kits\8.0\Include\um;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
       <AdditionalOptions>/MP %(AdditionalOptions)</AdditionalOptions>
       <BufferSecurityCheck>true</BufferSecurityCheck>
       <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
@@ -142,6 +143,7 @@
     </ClCompile>
     <Lib>
       <AdditionalLibraryDirectories>C:/Program Files (x86)/Windows Kits/8.0/Lib/win8/um/x86;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
+      <TargetMachine>MachineX86</TargetMachine>
     </Lib>
     <Link>
       <AdditionalDependencies>kernel32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;user32.lib;uuid.lib;odbc32.lib;odbccp32.lib;delayimp.lib</AdditionalDependencies>
@@ -155,14 +157,14 @@
       <TargetMachine>MachineX86</TargetMachine>
     </Link>
     <ResourceCompile>
-      <AdditionalIncludeDirectories>..\..\include;..\..\samples\angle\sample_util;C:\Program Files (x86)\Windows Kits\8.0\Include\shared;C:\Program Files (x86)\Windows Kits\8.0\Include\um;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <AdditionalIncludeDirectories>$(OutDir)obj\global_intermediate\angle;..\..\include;..\..\samples\angle\sample_util;..\..\util;C:\Program Files (x86)\Windows Kits\8.0\Include\shared;C:\Program Files (x86)\Windows Kits\8.0\Include\um;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
       <Culture>0x0409</Culture>
       <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
     </ResourceCompile>
   </ItemDefinitionGroup>
   <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
     <ClCompile>
-      <AdditionalIncludeDirectories>..\..\include;..\..\samples\angle\sample_util;C:\Program Files (x86)\Windows Kits\8.0\Include\shared;C:\Program Files (x86)\Windows Kits\8.0\Include\um;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <AdditionalIncludeDirectories>$(OutDir)obj\global_intermediate\angle;..\..\include;..\..\samples\angle\sample_util;..\..\util;C:\Program Files (x86)\Windows Kits\8.0\Include\shared;C:\Program Files (x86)\Windows Kits\8.0\Include\um;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
       <AdditionalOptions>/MP %(AdditionalOptions)</AdditionalOptions>
       <BufferSecurityCheck>true</BufferSecurityCheck>
       <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
@@ -192,7 +194,7 @@
       <TargetMachine>MachineX64</TargetMachine>
     </Link>
     <ResourceCompile>
-      <AdditionalIncludeDirectories>..\..\include;..\..\samples\angle\sample_util;C:\Program Files (x86)\Windows Kits\8.0\Include\shared;C:\Program Files (x86)\Windows Kits\8.0\Include\um;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <AdditionalIncludeDirectories>$(OutDir)obj\global_intermediate\angle;..\..\include;..\..\samples\angle\sample_util;..\..\util;C:\Program Files (x86)\Windows Kits\8.0\Include\shared;C:\Program Files (x86)\Windows Kits\8.0\Include\um;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
       <Culture>0x0409</Culture>
     </ResourceCompile>
   </ItemDefinitionGroup>
@@ -215,6 +217,10 @@
       <Project>{7FBD6F69-B9A4-69F1-A12B-8DACB3F8CD81}</Project>
       <ReferenceOutputAssembly>false</ReferenceOutputAssembly>
     </ProjectReference>
+    <ProjectReference Include="..\util\angle_util.vcxproj">
+      <Project>{E4DD691C-228B-A904-A008-10E26DC0F09E}</Project>
+      <ReferenceOutputAssembly>false</ReferenceOutputAssembly>
+    </ProjectReference>
   </ItemGroup>
   <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets"/>
   <ImportGroup Label="ExtensionTargets"/>
diff --git a/projects/samples/simple_vertex_shader.vcxproj b/projects/samples/simple_vertex_shader.vcxproj
index a73f52f..146b578 100644
--- a/projects/samples/simple_vertex_shader.vcxproj
+++ b/projects/samples/simple_vertex_shader.vcxproj
@@ -50,7 +50,7 @@
   </PropertyGroup>
   <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
     <ClCompile>
-      <AdditionalIncludeDirectories>..\..\include;..\..\samples\angle\sample_util;C:\Program Files (x86)\Windows Kits\8.0\Include\shared;C:\Program Files (x86)\Windows Kits\8.0\Include\um;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <AdditionalIncludeDirectories>$(OutDir)obj\global_intermediate\angle;..\..\include;..\..\samples\angle\sample_util;..\..\util;C:\Program Files (x86)\Windows Kits\8.0\Include\shared;C:\Program Files (x86)\Windows Kits\8.0\Include\um;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
       <AdditionalOptions>/MP %(AdditionalOptions)</AdditionalOptions>
       <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
       <BufferSecurityCheck>true</BufferSecurityCheck>
@@ -68,6 +68,7 @@
     </ClCompile>
     <Lib>
       <AdditionalLibraryDirectories>C:/Program Files (x86)/Windows Kits/8.0/Lib/win8/um/x86;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
+      <TargetMachine>MachineX86</TargetMachine>
     </Lib>
     <Link>
       <AdditionalDependencies>kernel32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;user32.lib;uuid.lib;odbc32.lib;odbccp32.lib;delayimp.lib</AdditionalDependencies>
@@ -81,14 +82,14 @@
       <TargetMachine>MachineX86</TargetMachine>
     </Link>
     <ResourceCompile>
-      <AdditionalIncludeDirectories>..\..\include;..\..\samples\angle\sample_util;C:\Program Files (x86)\Windows Kits\8.0\Include\shared;C:\Program Files (x86)\Windows Kits\8.0\Include\um;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <AdditionalIncludeDirectories>$(OutDir)obj\global_intermediate\angle;..\..\include;..\..\samples\angle\sample_util;..\..\util;C:\Program Files (x86)\Windows Kits\8.0\Include\shared;C:\Program Files (x86)\Windows Kits\8.0\Include\um;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
       <Culture>0x0409</Culture>
       <PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
     </ResourceCompile>
   </ItemDefinitionGroup>
   <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
     <ClCompile>
-      <AdditionalIncludeDirectories>..\..\include;..\..\samples\angle\sample_util;C:\Program Files (x86)\Windows Kits\8.0\Include\shared;C:\Program Files (x86)\Windows Kits\8.0\Include\um;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <AdditionalIncludeDirectories>$(OutDir)obj\global_intermediate\angle;..\..\include;..\..\samples\angle\sample_util;..\..\util;C:\Program Files (x86)\Windows Kits\8.0\Include\shared;C:\Program Files (x86)\Windows Kits\8.0\Include\um;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
       <AdditionalOptions>/MP %(AdditionalOptions)</AdditionalOptions>
       <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
       <BufferSecurityCheck>true</BufferSecurityCheck>
@@ -119,13 +120,13 @@
       <TargetMachine>MachineX64</TargetMachine>
     </Link>
     <ResourceCompile>
-      <AdditionalIncludeDirectories>..\..\include;..\..\samples\angle\sample_util;C:\Program Files (x86)\Windows Kits\8.0\Include\shared;C:\Program Files (x86)\Windows Kits\8.0\Include\um;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <AdditionalIncludeDirectories>$(OutDir)obj\global_intermediate\angle;..\..\include;..\..\samples\angle\sample_util;..\..\util;C:\Program Files (x86)\Windows Kits\8.0\Include\shared;C:\Program Files (x86)\Windows Kits\8.0\Include\um;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
       <Culture>0x0409</Culture>
     </ResourceCompile>
   </ItemDefinitionGroup>
   <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
     <ClCompile>
-      <AdditionalIncludeDirectories>..\..\include;..\..\samples\angle\sample_util;C:\Program Files (x86)\Windows Kits\8.0\Include\shared;C:\Program Files (x86)\Windows Kits\8.0\Include\um;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <AdditionalIncludeDirectories>$(OutDir)obj\global_intermediate\angle;..\..\include;..\..\samples\angle\sample_util;..\..\util;C:\Program Files (x86)\Windows Kits\8.0\Include\shared;C:\Program Files (x86)\Windows Kits\8.0\Include\um;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
       <AdditionalOptions>/MP %(AdditionalOptions)</AdditionalOptions>
       <BufferSecurityCheck>true</BufferSecurityCheck>
       <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
@@ -142,6 +143,7 @@
     </ClCompile>
     <Lib>
       <AdditionalLibraryDirectories>C:/Program Files (x86)/Windows Kits/8.0/Lib/win8/um/x86;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
+      <TargetMachine>MachineX86</TargetMachine>
     </Lib>
     <Link>
       <AdditionalDependencies>kernel32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;user32.lib;uuid.lib;odbc32.lib;odbccp32.lib;delayimp.lib</AdditionalDependencies>
@@ -155,14 +157,14 @@
       <TargetMachine>MachineX86</TargetMachine>
     </Link>
     <ResourceCompile>
-      <AdditionalIncludeDirectories>..\..\include;..\..\samples\angle\sample_util;C:\Program Files (x86)\Windows Kits\8.0\Include\shared;C:\Program Files (x86)\Windows Kits\8.0\Include\um;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <AdditionalIncludeDirectories>$(OutDir)obj\global_intermediate\angle;..\..\include;..\..\samples\angle\sample_util;..\..\util;C:\Program Files (x86)\Windows Kits\8.0\Include\shared;C:\Program Files (x86)\Windows Kits\8.0\Include\um;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
       <Culture>0x0409</Culture>
       <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
     </ResourceCompile>
   </ItemDefinitionGroup>
   <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
     <ClCompile>
-      <AdditionalIncludeDirectories>..\..\include;..\..\samples\angle\sample_util;C:\Program Files (x86)\Windows Kits\8.0\Include\shared;C:\Program Files (x86)\Windows Kits\8.0\Include\um;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <AdditionalIncludeDirectories>$(OutDir)obj\global_intermediate\angle;..\..\include;..\..\samples\angle\sample_util;..\..\util;C:\Program Files (x86)\Windows Kits\8.0\Include\shared;C:\Program Files (x86)\Windows Kits\8.0\Include\um;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
       <AdditionalOptions>/MP %(AdditionalOptions)</AdditionalOptions>
       <BufferSecurityCheck>true</BufferSecurityCheck>
       <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
@@ -192,7 +194,7 @@
       <TargetMachine>MachineX64</TargetMachine>
     </Link>
     <ResourceCompile>
-      <AdditionalIncludeDirectories>..\..\include;..\..\samples\angle\sample_util;C:\Program Files (x86)\Windows Kits\8.0\Include\shared;C:\Program Files (x86)\Windows Kits\8.0\Include\um;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <AdditionalIncludeDirectories>$(OutDir)obj\global_intermediate\angle;..\..\include;..\..\samples\angle\sample_util;..\..\util;C:\Program Files (x86)\Windows Kits\8.0\Include\shared;C:\Program Files (x86)\Windows Kits\8.0\Include\um;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
       <Culture>0x0409</Culture>
     </ResourceCompile>
   </ItemDefinitionGroup>
@@ -215,6 +217,10 @@
       <Project>{7FBD6F69-B9A4-69F1-A12B-8DACB3F8CD81}</Project>
       <ReferenceOutputAssembly>false</ReferenceOutputAssembly>
     </ProjectReference>
+    <ProjectReference Include="..\util\angle_util.vcxproj">
+      <Project>{E4DD691C-228B-A904-A008-10E26DC0F09E}</Project>
+      <ReferenceOutputAssembly>false</ReferenceOutputAssembly>
+    </ProjectReference>
   </ItemGroup>
   <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets"/>
   <ImportGroup Label="ExtensionTargets"/>
diff --git a/projects/samples/stencil_operations.vcxproj b/projects/samples/stencil_operations.vcxproj
index 7478879..4cc706a 100644
--- a/projects/samples/stencil_operations.vcxproj
+++ b/projects/samples/stencil_operations.vcxproj
@@ -50,7 +50,7 @@
   </PropertyGroup>
   <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
     <ClCompile>
-      <AdditionalIncludeDirectories>..\..\include;..\..\samples\angle\sample_util;C:\Program Files (x86)\Windows Kits\8.0\Include\shared;C:\Program Files (x86)\Windows Kits\8.0\Include\um;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <AdditionalIncludeDirectories>$(OutDir)obj\global_intermediate\angle;..\..\include;..\..\samples\angle\sample_util;..\..\util;C:\Program Files (x86)\Windows Kits\8.0\Include\shared;C:\Program Files (x86)\Windows Kits\8.0\Include\um;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
       <AdditionalOptions>/MP %(AdditionalOptions)</AdditionalOptions>
       <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
       <BufferSecurityCheck>true</BufferSecurityCheck>
@@ -68,6 +68,7 @@
     </ClCompile>
     <Lib>
       <AdditionalLibraryDirectories>C:/Program Files (x86)/Windows Kits/8.0/Lib/win8/um/x86;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
+      <TargetMachine>MachineX86</TargetMachine>
     </Lib>
     <Link>
       <AdditionalDependencies>kernel32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;user32.lib;uuid.lib;odbc32.lib;odbccp32.lib;delayimp.lib</AdditionalDependencies>
@@ -81,14 +82,14 @@
       <TargetMachine>MachineX86</TargetMachine>
     </Link>
     <ResourceCompile>
-      <AdditionalIncludeDirectories>..\..\include;..\..\samples\angle\sample_util;C:\Program Files (x86)\Windows Kits\8.0\Include\shared;C:\Program Files (x86)\Windows Kits\8.0\Include\um;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <AdditionalIncludeDirectories>$(OutDir)obj\global_intermediate\angle;..\..\include;..\..\samples\angle\sample_util;..\..\util;C:\Program Files (x86)\Windows Kits\8.0\Include\shared;C:\Program Files (x86)\Windows Kits\8.0\Include\um;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
       <Culture>0x0409</Culture>
       <PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
     </ResourceCompile>
   </ItemDefinitionGroup>
   <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
     <ClCompile>
-      <AdditionalIncludeDirectories>..\..\include;..\..\samples\angle\sample_util;C:\Program Files (x86)\Windows Kits\8.0\Include\shared;C:\Program Files (x86)\Windows Kits\8.0\Include\um;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <AdditionalIncludeDirectories>$(OutDir)obj\global_intermediate\angle;..\..\include;..\..\samples\angle\sample_util;..\..\util;C:\Program Files (x86)\Windows Kits\8.0\Include\shared;C:\Program Files (x86)\Windows Kits\8.0\Include\um;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
       <AdditionalOptions>/MP %(AdditionalOptions)</AdditionalOptions>
       <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
       <BufferSecurityCheck>true</BufferSecurityCheck>
@@ -119,13 +120,13 @@
       <TargetMachine>MachineX64</TargetMachine>
     </Link>
     <ResourceCompile>
-      <AdditionalIncludeDirectories>..\..\include;..\..\samples\angle\sample_util;C:\Program Files (x86)\Windows Kits\8.0\Include\shared;C:\Program Files (x86)\Windows Kits\8.0\Include\um;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <AdditionalIncludeDirectories>$(OutDir)obj\global_intermediate\angle;..\..\include;..\..\samples\angle\sample_util;..\..\util;C:\Program Files (x86)\Windows Kits\8.0\Include\shared;C:\Program Files (x86)\Windows Kits\8.0\Include\um;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
       <Culture>0x0409</Culture>
     </ResourceCompile>
   </ItemDefinitionGroup>
   <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
     <ClCompile>
-      <AdditionalIncludeDirectories>..\..\include;..\..\samples\angle\sample_util;C:\Program Files (x86)\Windows Kits\8.0\Include\shared;C:\Program Files (x86)\Windows Kits\8.0\Include\um;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <AdditionalIncludeDirectories>$(OutDir)obj\global_intermediate\angle;..\..\include;..\..\samples\angle\sample_util;..\..\util;C:\Program Files (x86)\Windows Kits\8.0\Include\shared;C:\Program Files (x86)\Windows Kits\8.0\Include\um;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
       <AdditionalOptions>/MP %(AdditionalOptions)</AdditionalOptions>
       <BufferSecurityCheck>true</BufferSecurityCheck>
       <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
@@ -142,6 +143,7 @@
     </ClCompile>
     <Lib>
       <AdditionalLibraryDirectories>C:/Program Files (x86)/Windows Kits/8.0/Lib/win8/um/x86;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
+      <TargetMachine>MachineX86</TargetMachine>
     </Lib>
     <Link>
       <AdditionalDependencies>kernel32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;user32.lib;uuid.lib;odbc32.lib;odbccp32.lib;delayimp.lib</AdditionalDependencies>
@@ -155,14 +157,14 @@
       <TargetMachine>MachineX86</TargetMachine>
     </Link>
     <ResourceCompile>
-      <AdditionalIncludeDirectories>..\..\include;..\..\samples\angle\sample_util;C:\Program Files (x86)\Windows Kits\8.0\Include\shared;C:\Program Files (x86)\Windows Kits\8.0\Include\um;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <AdditionalIncludeDirectories>$(OutDir)obj\global_intermediate\angle;..\..\include;..\..\samples\angle\sample_util;..\..\util;C:\Program Files (x86)\Windows Kits\8.0\Include\shared;C:\Program Files (x86)\Windows Kits\8.0\Include\um;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
       <Culture>0x0409</Culture>
       <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
     </ResourceCompile>
   </ItemDefinitionGroup>
   <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
     <ClCompile>
-      <AdditionalIncludeDirectories>..\..\include;..\..\samples\angle\sample_util;C:\Program Files (x86)\Windows Kits\8.0\Include\shared;C:\Program Files (x86)\Windows Kits\8.0\Include\um;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <AdditionalIncludeDirectories>$(OutDir)obj\global_intermediate\angle;..\..\include;..\..\samples\angle\sample_util;..\..\util;C:\Program Files (x86)\Windows Kits\8.0\Include\shared;C:\Program Files (x86)\Windows Kits\8.0\Include\um;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
       <AdditionalOptions>/MP %(AdditionalOptions)</AdditionalOptions>
       <BufferSecurityCheck>true</BufferSecurityCheck>
       <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
@@ -192,7 +194,7 @@
       <TargetMachine>MachineX64</TargetMachine>
     </Link>
     <ResourceCompile>
-      <AdditionalIncludeDirectories>..\..\include;..\..\samples\angle\sample_util;C:\Program Files (x86)\Windows Kits\8.0\Include\shared;C:\Program Files (x86)\Windows Kits\8.0\Include\um;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <AdditionalIncludeDirectories>$(OutDir)obj\global_intermediate\angle;..\..\include;..\..\samples\angle\sample_util;..\..\util;C:\Program Files (x86)\Windows Kits\8.0\Include\shared;C:\Program Files (x86)\Windows Kits\8.0\Include\um;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
       <Culture>0x0409</Culture>
     </ResourceCompile>
   </ItemDefinitionGroup>
@@ -215,6 +217,10 @@
       <Project>{7FBD6F69-B9A4-69F1-A12B-8DACB3F8CD81}</Project>
       <ReferenceOutputAssembly>false</ReferenceOutputAssembly>
     </ProjectReference>
+    <ProjectReference Include="..\util\angle_util.vcxproj">
+      <Project>{E4DD691C-228B-A904-A008-10E26DC0F09E}</Project>
+      <ReferenceOutputAssembly>false</ReferenceOutputAssembly>
+    </ProjectReference>
   </ItemGroup>
   <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets"/>
   <ImportGroup Label="ExtensionTargets"/>
diff --git a/projects/samples/texture_wrap.vcxproj b/projects/samples/texture_wrap.vcxproj
index deb6130..3218dfd 100644
--- a/projects/samples/texture_wrap.vcxproj
+++ b/projects/samples/texture_wrap.vcxproj
@@ -50,7 +50,7 @@
   </PropertyGroup>
   <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
     <ClCompile>
-      <AdditionalIncludeDirectories>..\..\include;..\..\samples\angle\sample_util;C:\Program Files (x86)\Windows Kits\8.0\Include\shared;C:\Program Files (x86)\Windows Kits\8.0\Include\um;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <AdditionalIncludeDirectories>$(OutDir)obj\global_intermediate\angle;..\..\include;..\..\samples\angle\sample_util;..\..\util;C:\Program Files (x86)\Windows Kits\8.0\Include\shared;C:\Program Files (x86)\Windows Kits\8.0\Include\um;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
       <AdditionalOptions>/MP %(AdditionalOptions)</AdditionalOptions>
       <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
       <BufferSecurityCheck>true</BufferSecurityCheck>
@@ -68,6 +68,7 @@
     </ClCompile>
     <Lib>
       <AdditionalLibraryDirectories>C:/Program Files (x86)/Windows Kits/8.0/Lib/win8/um/x86;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
+      <TargetMachine>MachineX86</TargetMachine>
     </Lib>
     <Link>
       <AdditionalDependencies>kernel32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;user32.lib;uuid.lib;odbc32.lib;odbccp32.lib;delayimp.lib</AdditionalDependencies>
@@ -81,14 +82,14 @@
       <TargetMachine>MachineX86</TargetMachine>
     </Link>
     <ResourceCompile>
-      <AdditionalIncludeDirectories>..\..\include;..\..\samples\angle\sample_util;C:\Program Files (x86)\Windows Kits\8.0\Include\shared;C:\Program Files (x86)\Windows Kits\8.0\Include\um;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <AdditionalIncludeDirectories>$(OutDir)obj\global_intermediate\angle;..\..\include;..\..\samples\angle\sample_util;..\..\util;C:\Program Files (x86)\Windows Kits\8.0\Include\shared;C:\Program Files (x86)\Windows Kits\8.0\Include\um;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
       <Culture>0x0409</Culture>
       <PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
     </ResourceCompile>
   </ItemDefinitionGroup>
   <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
     <ClCompile>
-      <AdditionalIncludeDirectories>..\..\include;..\..\samples\angle\sample_util;C:\Program Files (x86)\Windows Kits\8.0\Include\shared;C:\Program Files (x86)\Windows Kits\8.0\Include\um;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <AdditionalIncludeDirectories>$(OutDir)obj\global_intermediate\angle;..\..\include;..\..\samples\angle\sample_util;..\..\util;C:\Program Files (x86)\Windows Kits\8.0\Include\shared;C:\Program Files (x86)\Windows Kits\8.0\Include\um;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
       <AdditionalOptions>/MP %(AdditionalOptions)</AdditionalOptions>
       <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
       <BufferSecurityCheck>true</BufferSecurityCheck>
@@ -119,13 +120,13 @@
       <TargetMachine>MachineX64</TargetMachine>
     </Link>
     <ResourceCompile>
-      <AdditionalIncludeDirectories>..\..\include;..\..\samples\angle\sample_util;C:\Program Files (x86)\Windows Kits\8.0\Include\shared;C:\Program Files (x86)\Windows Kits\8.0\Include\um;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <AdditionalIncludeDirectories>$(OutDir)obj\global_intermediate\angle;..\..\include;..\..\samples\angle\sample_util;..\..\util;C:\Program Files (x86)\Windows Kits\8.0\Include\shared;C:\Program Files (x86)\Windows Kits\8.0\Include\um;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
       <Culture>0x0409</Culture>
     </ResourceCompile>
   </ItemDefinitionGroup>
   <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
     <ClCompile>
-      <AdditionalIncludeDirectories>..\..\include;..\..\samples\angle\sample_util;C:\Program Files (x86)\Windows Kits\8.0\Include\shared;C:\Program Files (x86)\Windows Kits\8.0\Include\um;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <AdditionalIncludeDirectories>$(OutDir)obj\global_intermediate\angle;..\..\include;..\..\samples\angle\sample_util;..\..\util;C:\Program Files (x86)\Windows Kits\8.0\Include\shared;C:\Program Files (x86)\Windows Kits\8.0\Include\um;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
       <AdditionalOptions>/MP %(AdditionalOptions)</AdditionalOptions>
       <BufferSecurityCheck>true</BufferSecurityCheck>
       <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
@@ -142,6 +143,7 @@
     </ClCompile>
     <Lib>
       <AdditionalLibraryDirectories>C:/Program Files (x86)/Windows Kits/8.0/Lib/win8/um/x86;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
+      <TargetMachine>MachineX86</TargetMachine>
     </Lib>
     <Link>
       <AdditionalDependencies>kernel32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;user32.lib;uuid.lib;odbc32.lib;odbccp32.lib;delayimp.lib</AdditionalDependencies>
@@ -155,14 +157,14 @@
       <TargetMachine>MachineX86</TargetMachine>
     </Link>
     <ResourceCompile>
-      <AdditionalIncludeDirectories>..\..\include;..\..\samples\angle\sample_util;C:\Program Files (x86)\Windows Kits\8.0\Include\shared;C:\Program Files (x86)\Windows Kits\8.0\Include\um;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <AdditionalIncludeDirectories>$(OutDir)obj\global_intermediate\angle;..\..\include;..\..\samples\angle\sample_util;..\..\util;C:\Program Files (x86)\Windows Kits\8.0\Include\shared;C:\Program Files (x86)\Windows Kits\8.0\Include\um;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
       <Culture>0x0409</Culture>
       <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
     </ResourceCompile>
   </ItemDefinitionGroup>
   <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
     <ClCompile>
-      <AdditionalIncludeDirectories>..\..\include;..\..\samples\angle\sample_util;C:\Program Files (x86)\Windows Kits\8.0\Include\shared;C:\Program Files (x86)\Windows Kits\8.0\Include\um;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <AdditionalIncludeDirectories>$(OutDir)obj\global_intermediate\angle;..\..\include;..\..\samples\angle\sample_util;..\..\util;C:\Program Files (x86)\Windows Kits\8.0\Include\shared;C:\Program Files (x86)\Windows Kits\8.0\Include\um;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
       <AdditionalOptions>/MP %(AdditionalOptions)</AdditionalOptions>
       <BufferSecurityCheck>true</BufferSecurityCheck>
       <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
@@ -192,7 +194,7 @@
       <TargetMachine>MachineX64</TargetMachine>
     </Link>
     <ResourceCompile>
-      <AdditionalIncludeDirectories>..\..\include;..\..\samples\angle\sample_util;C:\Program Files (x86)\Windows Kits\8.0\Include\shared;C:\Program Files (x86)\Windows Kits\8.0\Include\um;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <AdditionalIncludeDirectories>$(OutDir)obj\global_intermediate\angle;..\..\include;..\..\samples\angle\sample_util;..\..\util;C:\Program Files (x86)\Windows Kits\8.0\Include\shared;C:\Program Files (x86)\Windows Kits\8.0\Include\um;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
       <Culture>0x0409</Culture>
     </ResourceCompile>
   </ItemDefinitionGroup>
@@ -215,6 +217,10 @@
       <Project>{7FBD6F69-B9A4-69F1-A12B-8DACB3F8CD81}</Project>
       <ReferenceOutputAssembly>false</ReferenceOutputAssembly>
     </ProjectReference>
+    <ProjectReference Include="..\util\angle_util.vcxproj">
+      <Project>{E4DD691C-228B-A904-A008-10E26DC0F09E}</Project>
+      <ReferenceOutputAssembly>false</ReferenceOutputAssembly>
+    </ProjectReference>
   </ItemGroup>
   <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets"/>
   <ImportGroup Label="ExtensionTargets"/>
diff --git a/projects/src/angle.sln b/projects/src/angle.sln
index 65679bc..9726e34 100644
--- a/projects/src/angle.sln
+++ b/projects/src/angle.sln
@@ -9,6 +9,12 @@
 EndProject
 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "copy_scripts", "copy_scripts.vcxproj", "{63FB0B97-D1D9-5158-8E85-7F5B1E403817}"
 EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libANGLE", "libANGLE.vcxproj", "{CAAA04EE-A56A-43FB-D011-1A56053C070C}"
+	ProjectSection(ProjectDependencies) = postProject
+		{3B7F5656-177F-52EE-26B3-D6A75368D0A9} = {3B7F5656-177F-52EE-26B3-D6A75368D0A9}
+		{22DC02D5-1598-943C-13E1-82185B469F81} = {22DC02D5-1598-943C-13E1-82185B469F81}
+	EndProjectSection
+EndProject
 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libEGL", "libEGL.vcxproj", "{FBAEE4F6-562A-588F-01F9-72DCABB3B061}"
 	ProjectSection(ProjectDependencies) = postProject
 		{7FBD6F69-B9A4-69F1-A12B-8DACB3F8CD81} = {7FBD6F69-B9A4-69F1-A12B-8DACB3F8CD81}
@@ -17,14 +23,20 @@
 EndProject
 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libGLESv2", "libGLESv2.vcxproj", "{7FBD6F69-B9A4-69F1-A12B-8DACB3F8CD81}"
 	ProjectSection(ProjectDependencies) = postProject
+		{CAAA04EE-A56A-43FB-D011-1A56053C070C} = {CAAA04EE-A56A-43FB-D011-1A56053C070C}
 		{C15697F6-5057-016E-BD29-422971875679} = {C15697F6-5057-016E-BD29-422971875679}
-		{3B7F5656-177F-52EE-26B3-D6A75368D0A9} = {3B7F5656-177F-52EE-26B3-D6A75368D0A9}
-		{22DC02D5-1598-943C-13E1-82185B469F81} = {22DC02D5-1598-943C-13E1-82185B469F81}
 		{276D20F5-2943-414C-0FF6-21F4723A5CF6} = {276D20F5-2943-414C-0FF6-21F4723A5CF6}
 		{C7BAF548-697D-2DCB-9DF3-9D1506A7B444} = {C7BAF548-697D-2DCB-9DF3-9D1506A7B444}
+		{3B7F5656-177F-52EE-26B3-D6A75368D0A9} = {3B7F5656-177F-52EE-26B3-D6A75368D0A9}
+		{22DC02D5-1598-943C-13E1-82185B469F81} = {22DC02D5-1598-943C-13E1-82185B469F81}
 		{63FB0B97-D1D9-5158-8E85-7F5B1E403817} = {63FB0B97-D1D9-5158-8E85-7F5B1E403817}
 	EndProjectSection
 EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libGLESv2_static", "libGLESv2_static.vcxproj", "{F8ABD31A-EC2F-A211-D514-076C763B69F9}"
+	ProjectSection(ProjectDependencies) = postProject
+		{3B7F5656-177F-52EE-26B3-D6A75368D0A9} = {3B7F5656-177F-52EE-26B3-D6A75368D0A9}
+	EndProjectSection
+EndProject
 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "preprocessor", "preprocessor.vcxproj", "{C7BAF548-697D-2DCB-9DF3-9D1506A7B444}"
 EndProject
 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "translator", "translator.vcxproj", "{C15697F6-5057-016E-BD29-422971875679}"
@@ -105,6 +117,22 @@
 		{C7BAF548-697D-2DCB-9DF3-9D1506A7B444}.Release|x64.Build.0 = Release|x64
 		{C7BAF548-697D-2DCB-9DF3-9D1506A7B444}.Release|Win32.ActiveCfg = Release|Win32
 		{C7BAF548-697D-2DCB-9DF3-9D1506A7B444}.Release|Win32.Build.0 = Release|Win32
+		{CAAA04EE-A56A-43FB-D011-1A56053C070C}.Debug|x64.ActiveCfg = Debug|x64
+		{CAAA04EE-A56A-43FB-D011-1A56053C070C}.Debug|x64.Build.0 = Debug|x64
+		{CAAA04EE-A56A-43FB-D011-1A56053C070C}.Debug|Win32.ActiveCfg = Debug|Win32
+		{CAAA04EE-A56A-43FB-D011-1A56053C070C}.Debug|Win32.Build.0 = Debug|Win32
+		{CAAA04EE-A56A-43FB-D011-1A56053C070C}.Release|x64.ActiveCfg = Release|x64
+		{CAAA04EE-A56A-43FB-D011-1A56053C070C}.Release|x64.Build.0 = Release|x64
+		{CAAA04EE-A56A-43FB-D011-1A56053C070C}.Release|Win32.ActiveCfg = Release|Win32
+		{CAAA04EE-A56A-43FB-D011-1A56053C070C}.Release|Win32.Build.0 = Release|Win32
+		{F8ABD31A-EC2F-A211-D514-076C763B69F9}.Debug|x64.ActiveCfg = Debug|x64
+		{F8ABD31A-EC2F-A211-D514-076C763B69F9}.Debug|x64.Build.0 = Debug|x64
+		{F8ABD31A-EC2F-A211-D514-076C763B69F9}.Debug|Win32.ActiveCfg = Debug|Win32
+		{F8ABD31A-EC2F-A211-D514-076C763B69F9}.Debug|Win32.Build.0 = Debug|Win32
+		{F8ABD31A-EC2F-A211-D514-076C763B69F9}.Release|x64.ActiveCfg = Release|x64
+		{F8ABD31A-EC2F-A211-D514-076C763B69F9}.Release|x64.Build.0 = Release|x64
+		{F8ABD31A-EC2F-A211-D514-076C763B69F9}.Release|Win32.ActiveCfg = Release|Win32
+		{F8ABD31A-EC2F-A211-D514-076C763B69F9}.Release|Win32.Build.0 = Release|Win32
 		{FBAEE4F6-562A-588F-01F9-72DCABB3B061}.Debug|x64.ActiveCfg = Debug|x64
 		{FBAEE4F6-562A-588F-01F9-72DCABB3B061}.Debug|x64.Build.0 = Debug|x64
 		{FBAEE4F6-562A-588F-01F9-72DCABB3B061}.Debug|Win32.ActiveCfg = Debug|Win32
diff --git a/projects/src/commit_id.vcxproj b/projects/src/commit_id.vcxproj
index e6862c5..da98f64 100644
--- a/projects/src/commit_id.vcxproj
+++ b/projects/src/commit_id.vcxproj
@@ -64,6 +64,7 @@
     </ClCompile>
     <Lib>
       <AdditionalLibraryDirectories>C:/Program Files (x86)/Windows Kits/8.0/Lib/win8/um/x86;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
+      <TargetMachine>MachineX86</TargetMachine>
     </Lib>
     <Link>
       <AdditionalDependencies></AdditionalDependencies>
@@ -127,6 +128,7 @@
     </ClCompile>
     <Lib>
       <AdditionalLibraryDirectories>C:/Program Files (x86)/Windows Kits/8.0/Lib/win8/um/x86;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
+      <TargetMachine>MachineX86</TargetMachine>
     </Lib>
     <Link>
       <AdditionalDependencies></AdditionalDependencies>
diff --git a/projects/src/copy_compiler_dll.vcxproj b/projects/src/copy_compiler_dll.vcxproj
index 8095b27..b01ab2b 100644
--- a/projects/src/copy_compiler_dll.vcxproj
+++ b/projects/src/copy_compiler_dll.vcxproj
@@ -67,6 +67,7 @@
     </ClCompile>
     <Lib>
       <AdditionalLibraryDirectories>C:/Program Files (x86)/Windows Kits/8.0/Lib/win8/um/x86;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
+      <TargetMachine>MachineX86</TargetMachine>
     </Lib>
     <Link>
       <AdditionalDependencies>kernel32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;user32.lib;uuid.lib;odbc32.lib;odbccp32.lib;delayimp.lib</AdditionalDependencies>
@@ -139,6 +140,7 @@
     </ClCompile>
     <Lib>
       <AdditionalLibraryDirectories>C:/Program Files (x86)/Windows Kits/8.0/Lib/win8/um/x86;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
+      <TargetMachine>MachineX86</TargetMachine>
     </Lib>
     <Link>
       <AdditionalDependencies>kernel32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;user32.lib;uuid.lib;odbc32.lib;odbccp32.lib;delayimp.lib</AdditionalDependencies>
diff --git a/projects/src/copy_scripts.vcxproj b/projects/src/copy_scripts.vcxproj
index df912f2..e7c2613 100644
--- a/projects/src/copy_scripts.vcxproj
+++ b/projects/src/copy_scripts.vcxproj
@@ -64,6 +64,7 @@
     </ClCompile>
     <Lib>
       <AdditionalLibraryDirectories>C:/Program Files (x86)/Windows Kits/8.0/Lib/win8/um/x86;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
+      <TargetMachine>MachineX86</TargetMachine>
     </Lib>
     <Link>
       <AdditionalDependencies></AdditionalDependencies>
@@ -127,6 +128,7 @@
     </ClCompile>
     <Lib>
       <AdditionalLibraryDirectories>C:/Program Files (x86)/Windows Kits/8.0/Lib/win8/um/x86;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
+      <TargetMachine>MachineX86</TargetMachine>
     </Lib>
     <Link>
       <AdditionalDependencies></AdditionalDependencies>
diff --git a/projects/src/libANGLE.vcxproj b/projects/src/libANGLE.vcxproj
new file mode 100644
index 0000000..c4185b7
--- /dev/null
+++ b/projects/src/libANGLE.vcxproj
@@ -0,0 +1,502 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <ItemGroup Label="ProjectConfigurations">
+    <ProjectConfiguration Include="Debug|Win32">
+      <Configuration>Debug</Configuration>
+      <Platform>Win32</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="Debug|x64">
+      <Configuration>Debug</Configuration>
+      <Platform>x64</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="Release|Win32">
+      <Configuration>Release</Configuration>
+      <Platform>Win32</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="Release|x64">
+      <Configuration>Release</Configuration>
+      <Platform>x64</Platform>
+    </ProjectConfiguration>
+  </ItemGroup>
+  <PropertyGroup Label="Globals">
+    <ProjectGuid>{CAAA04EE-A56A-43FB-D011-1A56053C070C}</ProjectGuid>
+    <Keyword>Win32Proj</Keyword>
+    <RootNamespace>libANGLE</RootNamespace>
+  </PropertyGroup>
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props"/>
+  <PropertyGroup Label="Configuration">
+    <CharacterSet>MultiByte</CharacterSet>
+    <ConfigurationType>StaticLibrary</ConfigurationType>
+  </PropertyGroup>
+  <PropertyGroup Label="Locals">
+    <PlatformToolset>v120</PlatformToolset>
+  </PropertyGroup>
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props"/>
+  <ImportGroup Label="ExtensionSettings"/>
+  <ImportGroup Label="PropertySheets">
+    <Import Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props"/>
+  </ImportGroup>
+  <PropertyGroup Label="UserMacros"/>
+  <PropertyGroup>
+    <ExecutablePath>$(ExecutablePath);$(MSBuildProjectDirectory)\..\..\third_party\cygwin\bin\;$(MSBuildProjectDirectory)\..\..\third_party\python_26\</ExecutablePath>
+    <OutDir>$(SolutionDir)$(Configuration)_$(Platform)\</OutDir>
+    <IntDir>$(OutDir)obj\$(ProjectName)\</IntDir>
+    <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">false</LinkIncremental>
+    <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Release|x64'">false</LinkIncremental>
+    <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</LinkIncremental>
+    <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</LinkIncremental>
+    <TargetName>$(ProjectName)</TargetName>
+    <TargetPath>$(OutDir)lib\$(ProjectName)$(TargetExt)</TargetPath>
+  </PropertyGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+    <ClCompile>
+      <AdditionalIncludeDirectories>..\..\src;..\..\include;..\..\src\libGLESv2;$(OutDir)obj\global_intermediate\angle;C:\Program Files (x86)\Windows Kits\8.0\Include\shared;C:\Program Files (x86)\Windows Kits\8.0\Include\um;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <AdditionalOptions>/MP %(AdditionalOptions)</AdditionalOptions>
+      <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
+      <BufferSecurityCheck>true</BufferSecurityCheck>
+      <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+      <DisableSpecificWarnings>4100;4127;4239;4244;4245;4251;4512;4702;4530;4718;4267;%(DisableSpecificWarnings)</DisableSpecificWarnings>
+      <ExceptionHandling>false</ExceptionHandling>
+      <FunctionLevelLinking>true</FunctionLevelLinking>
+      <MinimalRebuild>false</MinimalRebuild>
+      <Optimization>Disabled</Optimization>
+      <PreprocessorDefinitions>_CRT_SECURE_NO_DEPRECATE;_SCL_SECURE_NO_WARNINGS;NOMINMAX;GL_APICALL=;GL_GLEXT_PROTOTYPES=;EGLAPI=;ANGLE_PRELOADED_D3DCOMPILER_MODULE_NAMES={ &quot;d3dcompiler_46.dll&quot;, &quot;d3dcompiler_43.dll&quot; };ANGLE_ENABLE_D3D9;ANGLE_ENABLE_D3D11;ANGLE_ENABLE_PERF;_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
+      <RuntimeTypeInfo>true</RuntimeTypeInfo>
+      <TreatWarningAsError>true</TreatWarningAsError>
+      <WarningLevel>Level4</WarningLevel>
+    </ClCompile>
+    <Lib>
+      <AdditionalLibraryDirectories>C:/Program Files (x86)/Windows Kits/8.0/Lib/win8/um/x86;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
+      <OutputFile>$(OutDir)lib\$(ProjectName)$(TargetExt)</OutputFile>
+      <TargetMachine>MachineX86</TargetMachine>
+    </Lib>
+    <Link>
+      <AdditionalDependencies>kernel32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;user32.lib;uuid.lib;odbc32.lib;odbccp32.lib;delayimp.lib;d3d9.lib</AdditionalDependencies>
+      <AdditionalLibraryDirectories>C:/Program Files (x86)/Windows Kits/8.0/Lib/win8/um/x86;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
+      <FixedBaseAddress>false</FixedBaseAddress>
+      <GenerateDebugInformation>true</GenerateDebugInformation>
+      <ImportLibrary>$(OutDir)lib\$(TargetName).lib</ImportLibrary>
+      <MapFileName>$(OutDir)$(TargetName).map</MapFileName>
+      <SubSystem>Console</SubSystem>
+      <TargetMachine>MachineX86</TargetMachine>
+    </Link>
+    <ResourceCompile>
+      <AdditionalIncludeDirectories>..\..\src;..\..\include;..\..\src\libGLESv2;$(OutDir)obj\global_intermediate\angle;C:\Program Files (x86)\Windows Kits\8.0\Include\shared;C:\Program Files (x86)\Windows Kits\8.0\Include\um;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <Culture>0x0409</Culture>
+      <PreprocessorDefinitions>GL_APICALL=;GL_GLEXT_PROTOTYPES=;EGLAPI=;ANGLE_PRELOADED_D3DCOMPILER_MODULE_NAMES={ &quot;d3dcompiler_46.dll&quot;, &quot;d3dcompiler_43.dll&quot; };ANGLE_ENABLE_D3D9;ANGLE_ENABLE_D3D11;ANGLE_ENABLE_PERF;_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+    </ResourceCompile>
+  </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+    <ClCompile>
+      <AdditionalIncludeDirectories>..\..\src;..\..\include;..\..\src\libGLESv2;$(OutDir)obj\global_intermediate\angle;C:\Program Files (x86)\Windows Kits\8.0\Include\shared;C:\Program Files (x86)\Windows Kits\8.0\Include\um;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <AdditionalOptions>/MP %(AdditionalOptions)</AdditionalOptions>
+      <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
+      <BufferSecurityCheck>true</BufferSecurityCheck>
+      <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+      <DisableSpecificWarnings>4100;4127;4239;4244;4245;4251;4512;4702;4530;4718;4267;%(DisableSpecificWarnings)</DisableSpecificWarnings>
+      <ExceptionHandling>false</ExceptionHandling>
+      <FunctionLevelLinking>true</FunctionLevelLinking>
+      <MinimalRebuild>false</MinimalRebuild>
+      <Optimization>Disabled</Optimization>
+      <PreprocessorDefinitions>_CRT_SECURE_NO_DEPRECATE;_SCL_SECURE_NO_WARNINGS;NOMINMAX;GL_APICALL=;GL_GLEXT_PROTOTYPES=;EGLAPI=;ANGLE_PRELOADED_D3DCOMPILER_MODULE_NAMES={ &quot;d3dcompiler_46.dll&quot;, &quot;d3dcompiler_43.dll&quot; };ANGLE_ENABLE_D3D9;ANGLE_ENABLE_D3D11;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
+      <RuntimeTypeInfo>true</RuntimeTypeInfo>
+      <TreatWarningAsError>true</TreatWarningAsError>
+      <WarningLevel>Level4</WarningLevel>
+    </ClCompile>
+    <Lib>
+      <AdditionalLibraryDirectories>C:/Program Files (x86)/Windows Kits/8.0/Lib/win8/um/x64;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
+      <OutputFile>$(OutDir)lib\$(ProjectName)$(TargetExt)</OutputFile>
+    </Lib>
+    <Link>
+      <AdditionalDependencies>kernel32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;user32.lib;uuid.lib;odbc32.lib;odbccp32.lib;delayimp.lib</AdditionalDependencies>
+      <AdditionalLibraryDirectories>C:/Program Files (x86)/Windows Kits/8.0/Lib/win8/um/x64;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
+      <FixedBaseAddress>false</FixedBaseAddress>
+      <GenerateDebugInformation>true</GenerateDebugInformation>
+      <ImportLibrary>$(OutDir)lib\$(TargetName).lib</ImportLibrary>
+      <MapFileName>$(OutDir)$(TargetName).map</MapFileName>
+      <SubSystem>Console</SubSystem>
+      <TargetMachine>MachineX64</TargetMachine>
+    </Link>
+    <ResourceCompile>
+      <AdditionalIncludeDirectories>..\..\src;..\..\include;..\..\src\libGLESv2;$(OutDir)obj\global_intermediate\angle;C:\Program Files (x86)\Windows Kits\8.0\Include\shared;C:\Program Files (x86)\Windows Kits\8.0\Include\um;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <Culture>0x0409</Culture>
+      <PreprocessorDefinitions>GL_APICALL=;GL_GLEXT_PROTOTYPES=;EGLAPI=;ANGLE_PRELOADED_D3DCOMPILER_MODULE_NAMES={ &quot;d3dcompiler_46.dll&quot;, &quot;d3dcompiler_43.dll&quot; };ANGLE_ENABLE_D3D9;ANGLE_ENABLE_D3D11;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+    </ResourceCompile>
+  </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+    <ClCompile>
+      <AdditionalIncludeDirectories>..\..\src;..\..\include;..\..\src\libGLESv2;$(OutDir)obj\global_intermediate\angle;C:\Program Files (x86)\Windows Kits\8.0\Include\shared;C:\Program Files (x86)\Windows Kits\8.0\Include\um;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <AdditionalOptions>/MP %(AdditionalOptions)</AdditionalOptions>
+      <BufferSecurityCheck>true</BufferSecurityCheck>
+      <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+      <DisableSpecificWarnings>4100;4127;4239;4244;4245;4251;4512;4702;4530;4718;4267;%(DisableSpecificWarnings)</DisableSpecificWarnings>
+      <ExceptionHandling>false</ExceptionHandling>
+      <FunctionLevelLinking>true</FunctionLevelLinking>
+      <MinimalRebuild>false</MinimalRebuild>
+      <Optimization>MaxSpeed</Optimization>
+      <PreprocessorDefinitions>_CRT_SECURE_NO_DEPRECATE;_SCL_SECURE_NO_WARNINGS;NOMINMAX;GL_APICALL=;GL_GLEXT_PROTOTYPES=;EGLAPI=;ANGLE_PRELOADED_D3DCOMPILER_MODULE_NAMES={ &quot;d3dcompiler_46.dll&quot;, &quot;d3dcompiler_43.dll&quot; };ANGLE_ENABLE_D3D9;ANGLE_ENABLE_D3D11;NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <RuntimeLibrary>MultiThreaded</RuntimeLibrary>
+      <RuntimeTypeInfo>true</RuntimeTypeInfo>
+      <TreatWarningAsError>true</TreatWarningAsError>
+      <WarningLevel>Level4</WarningLevel>
+    </ClCompile>
+    <Lib>
+      <AdditionalLibraryDirectories>C:/Program Files (x86)/Windows Kits/8.0/Lib/win8/um/x86;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
+      <OutputFile>$(OutDir)lib\$(ProjectName)$(TargetExt)</OutputFile>
+      <TargetMachine>MachineX86</TargetMachine>
+    </Lib>
+    <Link>
+      <AdditionalDependencies>kernel32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;user32.lib;uuid.lib;odbc32.lib;odbccp32.lib;delayimp.lib</AdditionalDependencies>
+      <AdditionalLibraryDirectories>C:/Program Files (x86)/Windows Kits/8.0/Lib/win8/um/x86;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
+      <FixedBaseAddress>false</FixedBaseAddress>
+      <GenerateDebugInformation>false</GenerateDebugInformation>
+      <ImportLibrary>$(OutDir)lib\$(TargetName).lib</ImportLibrary>
+      <MapFileName>$(OutDir)$(TargetName).map</MapFileName>
+      <SubSystem>Console</SubSystem>
+      <TargetMachine>MachineX86</TargetMachine>
+    </Link>
+    <ResourceCompile>
+      <AdditionalIncludeDirectories>..\..\src;..\..\include;..\..\src\libGLESv2;$(OutDir)obj\global_intermediate\angle;C:\Program Files (x86)\Windows Kits\8.0\Include\shared;C:\Program Files (x86)\Windows Kits\8.0\Include\um;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <Culture>0x0409</Culture>
+      <PreprocessorDefinitions>GL_APICALL=;GL_GLEXT_PROTOTYPES=;EGLAPI=;ANGLE_PRELOADED_D3DCOMPILER_MODULE_NAMES={ &quot;d3dcompiler_46.dll&quot;, &quot;d3dcompiler_43.dll&quot; };ANGLE_ENABLE_D3D9;ANGLE_ENABLE_D3D11;NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+    </ResourceCompile>
+  </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+    <ClCompile>
+      <AdditionalIncludeDirectories>..\..\src;..\..\include;..\..\src\libGLESv2;$(OutDir)obj\global_intermediate\angle;C:\Program Files (x86)\Windows Kits\8.0\Include\shared;C:\Program Files (x86)\Windows Kits\8.0\Include\um;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <AdditionalOptions>/MP %(AdditionalOptions)</AdditionalOptions>
+      <BufferSecurityCheck>true</BufferSecurityCheck>
+      <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+      <DisableSpecificWarnings>4100;4127;4239;4244;4245;4251;4512;4702;4530;4718;4267;%(DisableSpecificWarnings)</DisableSpecificWarnings>
+      <ExceptionHandling>false</ExceptionHandling>
+      <FunctionLevelLinking>true</FunctionLevelLinking>
+      <MinimalRebuild>false</MinimalRebuild>
+      <Optimization>MaxSpeed</Optimization>
+      <PreprocessorDefinitions>_CRT_SECURE_NO_DEPRECATE;_SCL_SECURE_NO_WARNINGS;NOMINMAX;GL_APICALL=;GL_GLEXT_PROTOTYPES=;EGLAPI=;ANGLE_PRELOADED_D3DCOMPILER_MODULE_NAMES={ &quot;d3dcompiler_46.dll&quot;, &quot;d3dcompiler_43.dll&quot; };ANGLE_ENABLE_D3D9;ANGLE_ENABLE_D3D11;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <RuntimeLibrary>MultiThreaded</RuntimeLibrary>
+      <RuntimeTypeInfo>true</RuntimeTypeInfo>
+      <TreatWarningAsError>true</TreatWarningAsError>
+      <WarningLevel>Level4</WarningLevel>
+    </ClCompile>
+    <Lib>
+      <AdditionalLibraryDirectories>C:/Program Files (x86)/Windows Kits/8.0/Lib/win8/um/x64;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
+      <OutputFile>$(OutDir)lib\$(ProjectName)$(TargetExt)</OutputFile>
+    </Lib>
+    <Link>
+      <AdditionalDependencies>kernel32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;user32.lib;uuid.lib;odbc32.lib;odbccp32.lib;delayimp.lib</AdditionalDependencies>
+      <AdditionalLibraryDirectories>C:/Program Files (x86)/Windows Kits/8.0/Lib/win8/um/x64;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
+      <FixedBaseAddress>false</FixedBaseAddress>
+      <GenerateDebugInformation>false</GenerateDebugInformation>
+      <ImportLibrary>$(OutDir)lib\$(TargetName).lib</ImportLibrary>
+      <MapFileName>$(OutDir)$(TargetName).map</MapFileName>
+      <SubSystem>Console</SubSystem>
+      <TargetMachine>MachineX64</TargetMachine>
+    </Link>
+    <ResourceCompile>
+      <AdditionalIncludeDirectories>..\..\src;..\..\include;..\..\src\libGLESv2;$(OutDir)obj\global_intermediate\angle;C:\Program Files (x86)\Windows Kits\8.0\Include\shared;C:\Program Files (x86)\Windows Kits\8.0\Include\um;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <Culture>0x0409</Culture>
+      <PreprocessorDefinitions>GL_APICALL=;GL_GLEXT_PROTOTYPES=;EGLAPI=;ANGLE_PRELOADED_D3DCOMPILER_MODULE_NAMES={ &quot;d3dcompiler_46.dll&quot;, &quot;d3dcompiler_43.dll&quot; };ANGLE_ENABLE_D3D9;ANGLE_ENABLE_D3D11;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+    </ResourceCompile>
+  </ItemDefinitionGroup>
+  <ItemGroup>
+    <None Include="..\..\src\angle.gyp"/>
+    <None Include="..\..\src\libGLESv2\renderer\loadimage.inl"/>
+    <None Include="..\..\src\libGLESv2\renderer\copyvertex.inl"/>
+    <None Include="..\..\src\libGLESv2\renderer\copyimage.inl"/>
+    <None Include="..\..\src\libGLESv2\renderer\generatemip.inl"/>
+  </ItemGroup>
+  <ItemGroup>
+    <ClInclude Include="..\..\src\libGLESv2\Shader.h"/>
+    <ClInclude Include="..\..\src\libGLESv2\BinaryStream.h"/>
+    <ClInclude Include="..\..\src\libGLESv2\resource.h"/>
+    <ClInclude Include="..\..\src\libGLESv2\ImageIndex.h"/>
+    <ClInclude Include="..\..\src\libGLESv2\Sampler.h"/>
+    <ClInclude Include="..\..\src\libGLESv2\Caps.h"/>
+    <ClInclude Include="..\..\src\libGLESv2\TransformFeedback.h"/>
+    <ClInclude Include="..\..\src\libGLESv2\Context.h"/>
+    <ClInclude Include="..\..\src\libGLESv2\Query.h"/>
+    <ClInclude Include="..\..\src\libGLESv2\Texture.h"/>
+    <ClInclude Include="..\..\src\libGLESv2\Uniform.h"/>
+    <ClInclude Include="..\..\src\libGLESv2\ProgramBinary.h"/>
+    <ClInclude Include="..\..\src\libGLESv2\constants.h"/>
+    <ClInclude Include="..\..\src\libGLESv2\FramebufferAttachment.h"/>
+    <ClInclude Include="..\..\src\libGLESv2\Renderbuffer.h"/>
+    <ClInclude Include="..\..\src\libGLESv2\queryconversions.h"/>
+    <ClInclude Include="..\..\src\libGLESv2\validationES3.h"/>
+    <ClInclude Include="..\..\src\libGLESv2\Program.h"/>
+    <ClInclude Include="..\..\src\libGLESv2\HandleAllocator.h"/>
+    <ClInclude Include="..\..\src\libGLESv2\Error.h"/>
+    <ClInclude Include="..\..\src\libGLESv2\ResourceManager.h"/>
+    <ClInclude Include="..\..\src\libGLESv2\VertexAttribute.h"/>
+    <ClInclude Include="..\..\src\libGLESv2\validationES2.h"/>
+    <ClInclude Include="..\..\src\libGLESv2\Fence.h"/>
+    <ClInclude Include="..\..\src\libGLESv2\angletypes.h"/>
+    <ClInclude Include="..\..\src\libGLESv2\main.h"/>
+    <ClInclude Include="..\..\src\libGLESv2\VertexArray.h"/>
+    <ClInclude Include="..\..\src\libGLESv2\Framebuffer.h"/>
+    <ClInclude Include="..\..\src\libGLESv2\formatutils.h"/>
+    <ClInclude Include="..\..\src\libGLESv2\Buffer.h"/>
+    <ClInclude Include="..\..\src\libGLESv2\State.h"/>
+    <ClInclude Include="..\..\src\libGLESv2\validationES.h"/>
+    <ClInclude Include="..\..\src\libGLESv2\renderer\TextureImpl.h"/>
+    <ClInclude Include="..\..\src\libGLESv2\renderer\Renderer.h"/>
+    <ClInclude Include="..\..\src\libGLESv2\renderer\ShaderImpl.h"/>
+    <ClInclude Include="..\..\src\libGLESv2\renderer\TransformFeedbackImpl.h"/>
+    <ClInclude Include="..\..\src\libGLESv2\renderer\ShaderExecutable.h"/>
+    <ClInclude Include="..\..\src\libGLESv2\renderer\ProgramImpl.h"/>
+    <ClInclude Include="..\..\src\libGLESv2\renderer\loadimage.h"/>
+    <ClInclude Include="..\..\src\libGLESv2\renderer\copyimage.h"/>
+    <ClInclude Include="..\..\src\libGLESv2\renderer\BufferImpl.h"/>
+    <ClInclude Include="..\..\src\libGLESv2\renderer\copyvertex.h"/>
+    <ClInclude Include="..\..\src\libGLESv2\renderer\VertexArrayImpl.h"/>
+    <ClInclude Include="..\..\src\libGLESv2\renderer\SwapChain.h"/>
+    <ClInclude Include="..\..\src\libGLESv2\renderer\imageformats.h"/>
+    <ClInclude Include="..\..\src\libGLESv2\renderer\QueryImpl.h"/>
+    <ClInclude Include="..\..\src\libGLESv2\renderer\IndexRangeCache.h"/>
+    <ClInclude Include="..\..\src\libGLESv2\renderer\FenceImpl.h"/>
+    <ClInclude Include="..\..\src\libGLESv2\renderer\Image.h"/>
+    <ClInclude Include="..\..\src\libGLESv2\renderer\generatemip.h"/>
+    <ClInclude Include="..\..\src\libGLESv2\renderer\RenderTarget.h"/>
+    <ClInclude Include="..\..\src\libGLESv2\renderer\vertexconversion.h"/>
+    <ClInclude Include="..\..\src\libGLESv2\renderer\d3d\DynamicHLSL.h"/>
+    <ClInclude Include="..\..\src\libGLESv2\renderer\d3d\IndexBuffer.h"/>
+    <ClInclude Include="..\..\src\libGLESv2\renderer\d3d\HLSLCompiler.h"/>
+    <ClInclude Include="..\..\src\libGLESv2\renderer\d3d\ImageD3D.h"/>
+    <ClInclude Include="..\..\src\libGLESv2\renderer\d3d\ProgramD3D.h"/>
+    <ClInclude Include="..\..\src\libGLESv2\renderer\d3d\MemoryBuffer.h"/>
+    <ClInclude Include="..\..\src\libGLESv2\renderer\d3d\TextureD3D.h"/>
+    <ClInclude Include="..\..\src\libGLESv2\renderer\d3d\TextureStorage.h"/>
+    <ClInclude Include="..\..\src\libGLESv2\renderer\d3d\IndexDataManager.h"/>
+    <ClInclude Include="..\..\src\libGLESv2\renderer\d3d\TransformFeedbackD3D.h"/>
+    <ClInclude Include="..\..\src\libGLESv2\renderer\d3d\VertexBuffer.h"/>
+    <ClInclude Include="..\..\src\libGLESv2\renderer\d3d\ShaderD3D.h"/>
+    <ClInclude Include="..\..\src\libGLESv2\renderer\d3d\BufferD3D.h"/>
+    <ClInclude Include="..\..\src\libGLESv2\renderer\d3d\VertexDataManager.h"/>
+    <ClInclude Include="..\..\src\libGLESv2\renderer\d3d\d3d11\Clear11.h"/>
+    <ClInclude Include="..\..\src\libGLESv2\renderer\d3d\d3d11\RenderStateCache.h"/>
+    <ClInclude Include="..\..\src\libGLESv2\renderer\d3d\d3d11\ShaderExecutable11.h"/>
+    <ClInclude Include="..\..\src\libGLESv2\renderer\d3d\d3d11\IndexBuffer11.h"/>
+    <ClInclude Include="..\..\src\libGLESv2\renderer\d3d\d3d11\Query11.h"/>
+    <ClInclude Include="..\..\src\libGLESv2\renderer\d3d\d3d11\Buffer11.h"/>
+    <ClInclude Include="..\..\src\libGLESv2\renderer\d3d\d3d11\VertexBuffer11.h"/>
+    <ClInclude Include="..\..\src\libGLESv2\renderer\d3d\d3d11\TextureStorage11.h"/>
+    <ClInclude Include="..\..\src\libGLESv2\renderer\d3d\d3d11\Blit11.h"/>
+    <ClInclude Include="..\..\src\libGLESv2\renderer\d3d\d3d11\Image11.h"/>
+    <ClInclude Include="..\..\src\libGLESv2\renderer\d3d\d3d11\RenderTarget11.h"/>
+    <ClInclude Include="..\..\src\libGLESv2\renderer\d3d\d3d11\InputLayoutCache.h"/>
+    <ClInclude Include="..\..\src\libGLESv2\renderer\d3d\d3d11\SwapChain11.h"/>
+    <ClInclude Include="..\..\src\libGLESv2\renderer\d3d\d3d11\Fence11.h"/>
+    <ClInclude Include="..\..\src\libGLESv2\renderer\d3d\d3d11\VertexArray11.h"/>
+    <ClInclude Include="..\..\src\libGLESv2\renderer\d3d\d3d11\renderer11_utils.h"/>
+    <ClInclude Include="..\..\src\libGLESv2\renderer\d3d\d3d11\Renderer11.h"/>
+    <ClInclude Include="..\..\src\libGLESv2\renderer\d3d\d3d11\PixelTransfer11.h"/>
+    <ClInclude Include="..\..\src\libGLESv2\renderer\d3d\d3d11\formatutils11.h"/>
+    <ClInclude Include="..\..\src\libGLESv2\renderer\d3d\d3d11\shaders\compiled\swizzleui2dps.h"/>
+    <ClInclude Include="..\..\src\libGLESv2\renderer\d3d\d3d11\shaders\compiled\passthroughr2d11ps.h"/>
+    <ClInclude Include="..\..\src\libGLESv2\renderer\d3d\d3d11\shaders\compiled\passthroughr3dui11ps.h"/>
+    <ClInclude Include="..\..\src\libGLESv2\renderer\d3d\d3d11\shaders\compiled\swizzlef3dps.h"/>
+    <ClInclude Include="..\..\src\libGLESv2\renderer\d3d\d3d11\shaders\compiled\passthroughlumalpha2d11ps.h"/>
+    <ClInclude Include="..\..\src\libGLESv2\renderer\d3d\d3d11\shaders\compiled\passthroughrg2dui11ps.h"/>
+    <ClInclude Include="..\..\src\libGLESv2\renderer\d3d\d3d11\shaders\compiled\passthroughrgb3d11ps.h"/>
+    <ClInclude Include="..\..\src\libGLESv2\renderer\d3d\d3d11\shaders\compiled\passthroughrgb2di11ps.h"/>
+    <ClInclude Include="..\..\src\libGLESv2\renderer\d3d\d3d11\shaders\compiled\swizzleui3dps.h"/>
+    <ClInclude Include="..\..\src\libGLESv2\renderer\d3d\d3d11\shaders\compiled\clearsint11ps.h"/>
+    <ClInclude Include="..\..\src\libGLESv2\renderer\d3d\d3d11\shaders\compiled\swizzlef2dps.h"/>
+    <ClInclude Include="..\..\src\libGLESv2\renderer\d3d\d3d11\shaders\compiled\passthroughrg3di11ps.h"/>
+    <ClInclude Include="..\..\src\libGLESv2\renderer\d3d\d3d11\shaders\compiled\swizzlei2darrayps.h"/>
+    <ClInclude Include="..\..\src\libGLESv2\renderer\d3d\d3d11\shaders\compiled\passthroughlumalpha3d11ps.h"/>
+    <ClInclude Include="..\..\src\libGLESv2\renderer\d3d\d3d11\shaders\compiled\passthroughrgba3di11ps.h"/>
+    <ClInclude Include="..\..\src\libGLESv2\renderer\d3d\d3d11\shaders\compiled\passthroughrgb2d11ps.h"/>
+    <ClInclude Include="..\..\src\libGLESv2\renderer\d3d\d3d11\shaders\compiled\clearsint11vs.h"/>
+    <ClInclude Include="..\..\src\libGLESv2\renderer\d3d\d3d11\shaders\compiled\passthrough2d11vs.h"/>
+    <ClInclude Include="..\..\src\libGLESv2\renderer\d3d\d3d11\shaders\compiled\buffertotexture11_ps_4f.h"/>
+    <ClInclude Include="..\..\src\libGLESv2\renderer\d3d\d3d11\shaders\compiled\buffertotexture11_gs.h"/>
+    <ClInclude Include="..\..\src\libGLESv2\renderer\d3d\d3d11\shaders\compiled\clearfloat11vs.h"/>
+    <ClInclude Include="..\..\src\libGLESv2\renderer\d3d\d3d11\shaders\compiled\passthroughrgba2di11ps.h"/>
+    <ClInclude Include="..\..\src\libGLESv2\renderer\d3d\d3d11\shaders\compiled\passthroughr2dui11ps.h"/>
+    <ClInclude Include="..\..\src\libGLESv2\renderer\d3d\d3d11\shaders\compiled\clearfloat11ps.h"/>
+    <ClInclude Include="..\..\src\libGLESv2\renderer\d3d\d3d11\shaders\compiled\buffertotexture11_ps_4i.h"/>
+    <ClInclude Include="..\..\src\libGLESv2\renderer\d3d\d3d11\shaders\compiled\passthroughrg3dui11ps.h"/>
+    <ClInclude Include="..\..\src\libGLESv2\renderer\d3d\d3d11\shaders\compiled\swizzlei2dps.h"/>
+    <ClInclude Include="..\..\src\libGLESv2\renderer\d3d\d3d11\shaders\compiled\passthroughrg2d11ps.h"/>
+    <ClInclude Include="..\..\src\libGLESv2\renderer\d3d\d3d11\shaders\compiled\passthroughrgba2dui11ps.h"/>
+    <ClInclude Include="..\..\src\libGLESv2\renderer\d3d\d3d11\shaders\compiled\passthroughr2di11ps.h"/>
+    <ClInclude Include="..\..\src\libGLESv2\renderer\d3d\d3d11\shaders\compiled\passthroughrgba3d11ps.h"/>
+    <ClInclude Include="..\..\src\libGLESv2\renderer\d3d\d3d11\shaders\compiled\passthroughlum3d11ps.h"/>
+    <ClInclude Include="..\..\src\libGLESv2\renderer\d3d\d3d11\shaders\compiled\clearuint11vs.h"/>
+    <ClInclude Include="..\..\src\libGLESv2\renderer\d3d\d3d11\shaders\compiled\passthroughr3d11ps.h"/>
+    <ClInclude Include="..\..\src\libGLESv2\renderer\d3d\d3d11\shaders\compiled\passthroughrg2di11ps.h"/>
+    <ClInclude Include="..\..\src\libGLESv2\renderer\d3d\d3d11\shaders\compiled\clearuint11ps.h"/>
+    <ClInclude Include="..\..\src\libGLESv2\renderer\d3d\d3d11\shaders\compiled\passthrough3d11vs.h"/>
+    <ClInclude Include="..\..\src\libGLESv2\renderer\d3d\d3d11\shaders\compiled\passthroughdepth2d11ps.h"/>
+    <ClInclude Include="..\..\src\libGLESv2\renderer\d3d\d3d11\shaders\compiled\passthroughlum2d11ps.h"/>
+    <ClInclude Include="..\..\src\libGLESv2\renderer\d3d\d3d11\shaders\compiled\passthroughrgb2dui11ps.h"/>
+    <ClInclude Include="..\..\src\libGLESv2\renderer\d3d\d3d11\shaders\compiled\swizzlei3dps.h"/>
+    <ClInclude Include="..\..\src\libGLESv2\renderer\d3d\d3d11\shaders\compiled\passthroughrgb3dui11ps.h"/>
+    <ClInclude Include="..\..\src\libGLESv2\renderer\d3d\d3d11\shaders\compiled\swizzlef2darrayps.h"/>
+    <ClInclude Include="..\..\src\libGLESv2\renderer\d3d\d3d11\shaders\compiled\buffertotexture11_vs.h"/>
+    <ClInclude Include="..\..\src\libGLESv2\renderer\d3d\d3d11\shaders\compiled\passthroughrgb3di11ps.h"/>
+    <ClInclude Include="..\..\src\libGLESv2\renderer\d3d\d3d11\shaders\compiled\passthroughrg3d11ps.h"/>
+    <ClInclude Include="..\..\src\libGLESv2\renderer\d3d\d3d11\shaders\compiled\passthroughrgba2d11ps.h"/>
+    <ClInclude Include="..\..\src\libGLESv2\renderer\d3d\d3d11\shaders\compiled\swizzleui2darrayps.h"/>
+    <ClInclude Include="..\..\src\libGLESv2\renderer\d3d\d3d11\shaders\compiled\passthroughrgba3dui11ps.h"/>
+    <ClInclude Include="..\..\src\libGLESv2\renderer\d3d\d3d11\shaders\compiled\buffertotexture11_ps_4ui.h"/>
+    <ClInclude Include="..\..\src\libGLESv2\renderer\d3d\d3d11\shaders\compiled\passthroughr3di11ps.h"/>
+    <ClInclude Include="..\..\src\libGLESv2\renderer\d3d\d3d11\shaders\compiled\passthrough3d11gs.h"/>
+    <ClInclude Include="..\..\src\libGLESv2\renderer\d3d\d3d9\renderer9_utils.h"/>
+    <ClInclude Include="..\..\src\libGLESv2\renderer\d3d\d3d9\TextureStorage9.h"/>
+    <ClInclude Include="..\..\src\libGLESv2\renderer\d3d\d3d9\IndexBuffer9.h"/>
+    <ClInclude Include="..\..\src\libGLESv2\renderer\d3d\d3d9\ShaderCache.h"/>
+    <ClInclude Include="..\..\src\libGLESv2\renderer\d3d\d3d9\Fence9.h"/>
+    <ClInclude Include="..\..\src\libGLESv2\renderer\d3d\d3d9\VertexArray9.h"/>
+    <ClInclude Include="..\..\src\libGLESv2\renderer\d3d\d3d9\Renderer9.h"/>
+    <ClInclude Include="..\..\src\libGLESv2\renderer\d3d\d3d9\Blit9.h"/>
+    <ClInclude Include="..\..\src\libGLESv2\renderer\d3d\d3d9\VertexDeclarationCache.h"/>
+    <ClInclude Include="..\..\src\libGLESv2\renderer\d3d\d3d9\Image9.h"/>
+    <ClInclude Include="..\..\src\libGLESv2\renderer\d3d\d3d9\VertexBuffer9.h"/>
+    <ClInclude Include="..\..\src\libGLESv2\renderer\d3d\d3d9\formatutils9.h"/>
+    <ClInclude Include="..\..\src\libGLESv2\renderer\d3d\d3d9\Query9.h"/>
+    <ClInclude Include="..\..\src\libGLESv2\renderer\d3d\d3d9\RenderTarget9.h"/>
+    <ClInclude Include="..\..\src\libGLESv2\renderer\d3d\d3d9\SwapChain9.h"/>
+    <ClInclude Include="..\..\src\libGLESv2\renderer\d3d\d3d9\Buffer9.h"/>
+    <ClInclude Include="..\..\src\libGLESv2\renderer\d3d\d3d9\shaders\compiled\standardvs.h"/>
+    <ClInclude Include="..\..\src\libGLESv2\renderer\d3d\d3d9\shaders\compiled\luminanceps.h"/>
+    <ClInclude Include="..\..\src\libGLESv2\renderer\d3d\d3d9\shaders\compiled\componentmaskps.h"/>
+    <ClInclude Include="..\..\src\libGLESv2\renderer\d3d\d3d9\shaders\compiled\passthroughps.h"/>
+    <ClInclude Include="..\..\src\libGLESv2\renderer\d3d\d3d9\shaders\compiled\flipyvs.h"/>
+    <ClInclude Include="..\..\src\common\tls.h"/>
+    <ClInclude Include="..\..\src\common\mathutil.h"/>
+    <ClInclude Include="..\..\src\common\blocklayout.h"/>
+    <ClInclude Include="..\..\src\common\debug.h"/>
+    <ClInclude Include="..\..\src\common\utilities.h"/>
+    <ClInclude Include="..\..\src\common\RefCountObject.h"/>
+    <ClInclude Include="..\..\src\common\event_tracer.h"/>
+    <ClInclude Include="..\..\src\common\angleutils.h"/>
+    <ClInclude Include="..\..\src\common\platform.h"/>
+    <ClInclude Include="..\..\src\common\version.h"/>
+    <ClInclude Include="..\..\src\third_party\systeminfo\SystemInfo.h"/>
+    <ClInclude Include="..\..\src\third_party\murmurhash\MurmurHash3.h"/>
+    <ClInclude Include="..\..\include\angle_gl.h"/>
+    <ClInclude Include="..\..\include\KHR\khrplatform.h"/>
+    <ClInclude Include="..\..\include\GLSLANG\ShaderLang.h"/>
+    <ClInclude Include="..\..\include\GLSLANG\ShaderVars.h"/>
+    <ClInclude Include="..\..\include\GLES2\gl2ext.h"/>
+    <ClInclude Include="..\..\include\GLES2\gl2.h"/>
+    <ClInclude Include="..\..\include\GLES2\gl2platform.h"/>
+    <ClInclude Include="..\..\include\GLES3\gl3ext.h"/>
+    <ClInclude Include="..\..\include\GLES3\gl3.h"/>
+    <ClInclude Include="..\..\include\GLES3\gl3platform.h"/>
+    <ClInclude Include="..\..\include\EGL\eglext.h"/>
+    <ClInclude Include="..\..\include\EGL\egl.h"/>
+    <ClInclude Include="..\..\include\EGL\eglplatform.h"/>
+  </ItemGroup>
+  <ItemGroup>
+    <ClCompile Include="..\..\src\libGLESv2\Error.cpp"/>
+    <ClCompile Include="..\..\src\libGLESv2\validationES2.cpp"/>
+    <ClCompile Include="..\..\src\libGLESv2\HandleAllocator.cpp"/>
+    <ClCompile Include="..\..\src\libGLESv2\queryconversions.cpp"/>
+    <ClCompile Include="..\..\src\libGLESv2\formatutils.cpp"/>
+    <ClCompile Include="..\..\src\libGLESv2\Fence.cpp"/>
+    <ClCompile Include="..\..\src\libGLESv2\validationES.cpp"/>
+    <ClCompile Include="..\..\src\libGLESv2\Program.cpp"/>
+    <ClCompile Include="..\..\src\libGLESv2\ResourceManager.cpp"/>
+    <ClCompile Include="..\..\src\libGLESv2\angletypes.cpp"/>
+    <ClCompile Include="..\..\src\libGLESv2\Float16ToFloat32.cpp"/>
+    <ClCompile Include="..\..\src\libGLESv2\validationES3.cpp"/>
+    <ClCompile Include="..\..\src\libGLESv2\FramebufferAttachment.cpp"/>
+    <ClCompile Include="..\..\src\libGLESv2\Query.cpp"/>
+    <ClCompile Include="..\..\src\libGLESv2\TransformFeedback.cpp"/>
+    <ClCompile Include="..\..\src\libGLESv2\State.cpp"/>
+    <ClCompile Include="..\..\src\libGLESv2\ProgramBinary.cpp"/>
+    <ClCompile Include="..\..\src\libGLESv2\VertexAttribute.cpp"/>
+    <ClCompile Include="..\..\src\libGLESv2\Caps.cpp"/>
+    <ClCompile Include="..\..\src\libGLESv2\Context.cpp"/>
+    <ClCompile Include="..\..\src\libGLESv2\Buffer.cpp"/>
+    <ClCompile Include="..\..\src\libGLESv2\VertexArray.cpp"/>
+    <ClCompile Include="..\..\src\libGLESv2\Shader.cpp"/>
+    <ClCompile Include="..\..\src\libGLESv2\Uniform.cpp"/>
+    <ClCompile Include="..\..\src\libGLESv2\main.cpp"/>
+    <ClCompile Include="..\..\src\libGLESv2\Renderbuffer.cpp"/>
+    <ClCompile Include="..\..\src\libGLESv2\ImageIndex.cpp"/>
+    <ClCompile Include="..\..\src\libGLESv2\Sampler.cpp"/>
+    <ClCompile Include="..\..\src\libGLESv2\Framebuffer.cpp"/>
+    <ClCompile Include="..\..\src\libGLESv2\Texture.cpp"/>
+    <ClCompile Include="..\..\src\libGLESv2\renderer\copyimage.cpp"/>
+    <ClCompile Include="..\..\src\libGLESv2\renderer\loadimage.cpp"/>
+    <ClCompile Include="..\..\src\libGLESv2\renderer\loadimageSSE2.cpp"/>
+    <ClCompile Include="..\..\src\libGLESv2\renderer\Image.cpp"/>
+    <ClCompile Include="..\..\src\libGLESv2\renderer\Renderer.cpp"/>
+    <ClCompile Include="..\..\src\libGLESv2\renderer\IndexRangeCache.cpp"/>
+    <ClCompile Include="..\..\src\libGLESv2\renderer\d3d\HLSLCompiler.cpp"/>
+    <ClCompile Include="..\..\src\libGLESv2\renderer\d3d\DynamicHLSL.cpp"/>
+    <ClCompile Include="..\..\src\libGLESv2\renderer\d3d\ShaderD3D.cpp"/>
+    <ClCompile Include="..\..\src\libGLESv2\renderer\d3d\BufferD3D.cpp"/>
+    <ClCompile Include="..\..\src\libGLESv2\renderer\d3d\ProgramD3D.cpp"/>
+    <ClCompile Include="..\..\src\libGLESv2\renderer\d3d\IndexBuffer.cpp"/>
+    <ClCompile Include="..\..\src\libGLESv2\renderer\d3d\VertexBuffer.cpp"/>
+    <ClCompile Include="..\..\src\libGLESv2\renderer\d3d\TextureD3D.cpp"/>
+    <ClCompile Include="..\..\src\libGLESv2\renderer\d3d\VertexDataManager.cpp"/>
+    <ClCompile Include="..\..\src\libGLESv2\renderer\d3d\MemoryBuffer.cpp"/>
+    <ClCompile Include="..\..\src\libGLESv2\renderer\d3d\ImageD3D.cpp"/>
+    <ClCompile Include="..\..\src\libGLESv2\renderer\d3d\TextureStorage.cpp"/>
+    <ClCompile Include="..\..\src\libGLESv2\renderer\d3d\TransformFeedbackD3D.cpp"/>
+    <ClCompile Include="..\..\src\libGLESv2\renderer\d3d\IndexDataManager.cpp"/>
+    <ClCompile Include="..\..\src\libGLESv2\renderer\d3d\d3d11\Renderer11.cpp"/>
+    <ClCompile Include="..\..\src\libGLESv2\renderer\d3d\d3d11\InputLayoutCache.cpp"/>
+    <ClCompile Include="..\..\src\libGLESv2\renderer\d3d\d3d11\PixelTransfer11.cpp"/>
+    <ClCompile Include="..\..\src\libGLESv2\renderer\d3d\d3d11\VertexBuffer11.cpp"/>
+    <ClCompile Include="..\..\src\libGLESv2\renderer\d3d\d3d11\Query11.cpp"/>
+    <ClCompile Include="..\..\src\libGLESv2\renderer\d3d\d3d11\ShaderExecutable11.cpp"/>
+    <ClCompile Include="..\..\src\libGLESv2\renderer\d3d\d3d11\Blit11.cpp"/>
+    <ClCompile Include="..\..\src\libGLESv2\renderer\d3d\d3d11\RenderStateCache.cpp"/>
+    <ClCompile Include="..\..\src\libGLESv2\renderer\d3d\d3d11\IndexBuffer11.cpp"/>
+    <ClCompile Include="..\..\src\libGLESv2\renderer\d3d\d3d11\formatutils11.cpp"/>
+    <ClCompile Include="..\..\src\libGLESv2\renderer\d3d\d3d11\SwapChain11.cpp"/>
+    <ClCompile Include="..\..\src\libGLESv2\renderer\d3d\d3d11\renderer11_utils.cpp"/>
+    <ClCompile Include="..\..\src\libGLESv2\renderer\d3d\d3d11\Image11.cpp"/>
+    <ClCompile Include="..\..\src\libGLESv2\renderer\d3d\d3d11\TextureStorage11.cpp"/>
+    <ClCompile Include="..\..\src\libGLESv2\renderer\d3d\d3d11\Buffer11.cpp"/>
+    <ClCompile Include="..\..\src\libGLESv2\renderer\d3d\d3d11\RenderTarget11.cpp"/>
+    <ClCompile Include="..\..\src\libGLESv2\renderer\d3d\d3d11\Fence11.cpp"/>
+    <ClCompile Include="..\..\src\libGLESv2\renderer\d3d\d3d11\Clear11.cpp"/>
+    <ClCompile Include="..\..\src\libGLESv2\renderer\d3d\d3d9\VertexDeclarationCache.cpp"/>
+    <ClCompile Include="..\..\src\libGLESv2\renderer\d3d\d3d9\Query9.cpp"/>
+    <ClCompile Include="..\..\src\libGLESv2\renderer\d3d\d3d9\VertexBuffer9.cpp"/>
+    <ClCompile Include="..\..\src\libGLESv2\renderer\d3d\d3d9\Fence9.cpp"/>
+    <ClCompile Include="..\..\src\libGLESv2\renderer\d3d\d3d9\Image9.cpp"/>
+    <ClCompile Include="..\..\src\libGLESv2\renderer\d3d\d3d9\TextureStorage9.cpp"/>
+    <ClCompile Include="..\..\src\libGLESv2\renderer\d3d\d3d9\Renderer9.cpp"/>
+    <ClCompile Include="..\..\src\libGLESv2\renderer\d3d\d3d9\RenderTarget9.cpp"/>
+    <ClCompile Include="..\..\src\libGLESv2\renderer\d3d\d3d9\formatutils9.cpp"/>
+    <ClCompile Include="..\..\src\libGLESv2\renderer\d3d\d3d9\Buffer9.cpp"/>
+    <ClCompile Include="..\..\src\libGLESv2\renderer\d3d\d3d9\ShaderExecutable9.cpp"/>
+    <ClCompile Include="..\..\src\libGLESv2\renderer\d3d\d3d9\renderer9_utils.cpp"/>
+    <ClCompile Include="..\..\src\libGLESv2\renderer\d3d\d3d9\SwapChain9.cpp"/>
+    <ClCompile Include="..\..\src\libGLESv2\renderer\d3d\d3d9\Blit9.cpp"/>
+    <ClCompile Include="..\..\src\libGLESv2\renderer\d3d\d3d9\IndexBuffer9.cpp"/>
+    <ClCompile Include="..\..\src\common\event_tracer.cpp"/>
+    <ClCompile Include="..\..\src\common\RefCountObject.cpp"/>
+    <ClCompile Include="..\..\src\common\tls.cpp"/>
+    <ClCompile Include="..\..\src\common\utilities.cpp"/>
+    <ClCompile Include="..\..\src\common\mathutil.cpp"/>
+    <ClCompile Include="..\..\src\common\debug.cpp"/>
+    <ClCompile Include="..\..\src\common\blocklayout.cpp"/>
+    <ClCompile Include="..\..\src\common\angleutils.cpp"/>
+    <ClCompile Include="..\..\src\third_party\systeminfo\SystemInfo.cpp"/>
+    <ClCompile Include="..\..\src\third_party\murmurhash\MurmurHash3.cpp"/>
+  </ItemGroup>
+  <ItemGroup>
+    <ProjectReference Include="commit_id.vcxproj">
+      <Project>{3B7F5656-177F-52EE-26B3-D6A75368D0A9}</Project>
+      <ReferenceOutputAssembly>false</ReferenceOutputAssembly>
+    </ProjectReference>
+    <ProjectReference Include="copy_compiler_dll.vcxproj">
+      <Project>{22DC02D5-1598-943C-13E1-82185B469F81}</Project>
+      <ReferenceOutputAssembly>false</ReferenceOutputAssembly>
+    </ProjectReference>
+  </ItemGroup>
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets"/>
+  <ImportGroup Label="ExtensionTargets"/>
+</Project>
diff --git a/projects/src/libANGLE.vcxproj.filters b/projects/src/libANGLE.vcxproj.filters
new file mode 100644
index 0000000..2776e86
--- /dev/null
+++ b/projects/src/libANGLE.vcxproj.filters
@@ -0,0 +1,910 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <ItemGroup>
+    <Filter Include="src">
+      <UniqueIdentifier>{8CDEE807-BC53-E450-C8B8-4DEBB66742D4}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="src\libGLESv2">
+      <UniqueIdentifier>{A62A9415-2E9D-A6D2-631D-1F25A5CD626F}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="src\libGLESv2\renderer">
+      <UniqueIdentifier>{AC4EF684-2900-10EA-3D11-A6DF0901358C}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="src\libGLESv2\renderer\d3d">
+      <UniqueIdentifier>{3AC19AE3-A12C-4021-D645-4CEA5BC956DB}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="src\libGLESv2\renderer\d3d\d3d11">
+      <UniqueIdentifier>{10FB1414-88D2-B512-6D76-522749905268}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="src\libGLESv2\renderer\d3d\d3d11\shaders">
+      <UniqueIdentifier>{467D5622-06CC-2CF1-19E5-3CDD46A4008C}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="src\libGLESv2\renderer\d3d\d3d11\shaders\compiled">
+      <UniqueIdentifier>{F444E9E6-7D51-0546-F1E4-B6C8FCDA5FC6}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="src\libGLESv2\renderer\d3d\d3d9">
+      <UniqueIdentifier>{8BB193D2-4A8B-A094-A81E-D5E262AB1F92}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="src\libGLESv2\renderer\d3d\d3d9\shaders">
+      <UniqueIdentifier>{467D5622-06CC-2CF1-19E5-3CDD46A4008C}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="src\libGLESv2\renderer\d3d\d3d9\shaders\compiled">
+      <UniqueIdentifier>{F444E9E6-7D51-0546-F1E4-B6C8FCDA5FC6}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="src\common">
+      <UniqueIdentifier>{2F5FD094-EF52-77F7-7AA8-4327A01BF747}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="src\third_party">
+      <UniqueIdentifier>{D6C6CEA7-AAD0-03AD-2394-AC6FCBF8A498}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="src\third_party\systeminfo">
+      <UniqueIdentifier>{8E42519F-DD71-5875-38CA-0ED32E34DB55}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="src\third_party\murmurhash">
+      <UniqueIdentifier>{FBF5769C-D63C-9100-0719-0B97CE76B013}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="include">
+      <UniqueIdentifier>{57CA55B8-BCC5-4000-CE3A-58972F82E9CB}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="include\KHR">
+      <UniqueIdentifier>{6D4588DE-6319-FB13-135F-FA88843373FC}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="include\GLSLANG">
+      <UniqueIdentifier>{AD7D3D9B-E716-B150-1F3A-64569B7F5415}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="include\GLES2">
+      <UniqueIdentifier>{3FFE2AF8-8DA3-57BA-8037-4BE936BC5045}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="include\GLES3">
+      <UniqueIdentifier>{E18FF71E-3DE4-F6D0-36B6-93BA54EEDEE1}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="include\EGL">
+      <UniqueIdentifier>{79AE79DD-7922-70CC-3439-C9B3586338EF}</UniqueIdentifier>
+    </Filter>
+  </ItemGroup>
+  <ItemGroup>
+    <None Include="..\..\src\angle.gyp">
+      <Filter>src</Filter>
+    </None>
+    <ClInclude Include="..\..\src\libGLESv2\Shader.h">
+      <Filter>src\libGLESv2</Filter>
+    </ClInclude>
+    <ClCompile Include="..\..\src\libGLESv2\Error.cpp">
+      <Filter>src\libGLESv2</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\src\libGLESv2\validationES2.cpp">
+      <Filter>src\libGLESv2</Filter>
+    </ClCompile>
+    <ClInclude Include="..\..\src\libGLESv2\BinaryStream.h">
+      <Filter>src\libGLESv2</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\src\libGLESv2\resource.h">
+      <Filter>src\libGLESv2</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\src\libGLESv2\ImageIndex.h">
+      <Filter>src\libGLESv2</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\src\libGLESv2\Sampler.h">
+      <Filter>src\libGLESv2</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\src\libGLESv2\Caps.h">
+      <Filter>src\libGLESv2</Filter>
+    </ClInclude>
+    <ClCompile Include="..\..\src\libGLESv2\HandleAllocator.cpp">
+      <Filter>src\libGLESv2</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\src\libGLESv2\queryconversions.cpp">
+      <Filter>src\libGLESv2</Filter>
+    </ClCompile>
+    <ClInclude Include="..\..\src\libGLESv2\TransformFeedback.h">
+      <Filter>src\libGLESv2</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\src\libGLESv2\Context.h">
+      <Filter>src\libGLESv2</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\src\libGLESv2\Query.h">
+      <Filter>src\libGLESv2</Filter>
+    </ClInclude>
+    <ClCompile Include="..\..\src\libGLESv2\formatutils.cpp">
+      <Filter>src\libGLESv2</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\src\libGLESv2\Fence.cpp">
+      <Filter>src\libGLESv2</Filter>
+    </ClCompile>
+    <ClInclude Include="..\..\src\libGLESv2\Texture.h">
+      <Filter>src\libGLESv2</Filter>
+    </ClInclude>
+    <ClCompile Include="..\..\src\libGLESv2\validationES.cpp">
+      <Filter>src\libGLESv2</Filter>
+    </ClCompile>
+    <ClInclude Include="..\..\src\libGLESv2\Uniform.h">
+      <Filter>src\libGLESv2</Filter>
+    </ClInclude>
+    <ClCompile Include="..\..\src\libGLESv2\Program.cpp">
+      <Filter>src\libGLESv2</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\src\libGLESv2\ResourceManager.cpp">
+      <Filter>src\libGLESv2</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\src\libGLESv2\angletypes.cpp">
+      <Filter>src\libGLESv2</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\src\libGLESv2\Float16ToFloat32.cpp">
+      <Filter>src\libGLESv2</Filter>
+    </ClCompile>
+    <ClInclude Include="..\..\src\libGLESv2\ProgramBinary.h">
+      <Filter>src\libGLESv2</Filter>
+    </ClInclude>
+    <ClCompile Include="..\..\src\libGLESv2\validationES3.cpp">
+      <Filter>src\libGLESv2</Filter>
+    </ClCompile>
+    <ClInclude Include="..\..\src\libGLESv2\constants.h">
+      <Filter>src\libGLESv2</Filter>
+    </ClInclude>
+    <ClCompile Include="..\..\src\libGLESv2\FramebufferAttachment.cpp">
+      <Filter>src\libGLESv2</Filter>
+    </ClCompile>
+    <ClInclude Include="..\..\src\libGLESv2\FramebufferAttachment.h">
+      <Filter>src\libGLESv2</Filter>
+    </ClInclude>
+    <ClCompile Include="..\..\src\libGLESv2\Query.cpp">
+      <Filter>src\libGLESv2</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\src\libGLESv2\TransformFeedback.cpp">
+      <Filter>src\libGLESv2</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\src\libGLESv2\State.cpp">
+      <Filter>src\libGLESv2</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\src\libGLESv2\ProgramBinary.cpp">
+      <Filter>src\libGLESv2</Filter>
+    </ClCompile>
+    <ClInclude Include="..\..\src\libGLESv2\Renderbuffer.h">
+      <Filter>src\libGLESv2</Filter>
+    </ClInclude>
+    <ClCompile Include="..\..\src\libGLESv2\VertexAttribute.cpp">
+      <Filter>src\libGLESv2</Filter>
+    </ClCompile>
+    <ClInclude Include="..\..\src\libGLESv2\queryconversions.h">
+      <Filter>src\libGLESv2</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\src\libGLESv2\validationES3.h">
+      <Filter>src\libGLESv2</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\src\libGLESv2\Program.h">
+      <Filter>src\libGLESv2</Filter>
+    </ClInclude>
+    <ClCompile Include="..\..\src\libGLESv2\Caps.cpp">
+      <Filter>src\libGLESv2</Filter>
+    </ClCompile>
+    <ClInclude Include="..\..\src\libGLESv2\HandleAllocator.h">
+      <Filter>src\libGLESv2</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\src\libGLESv2\Error.h">
+      <Filter>src\libGLESv2</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\src\libGLESv2\ResourceManager.h">
+      <Filter>src\libGLESv2</Filter>
+    </ClInclude>
+    <ClCompile Include="..\..\src\libGLESv2\Context.cpp">
+      <Filter>src\libGLESv2</Filter>
+    </ClCompile>
+    <ClInclude Include="..\..\src\libGLESv2\VertexAttribute.h">
+      <Filter>src\libGLESv2</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\src\libGLESv2\validationES2.h">
+      <Filter>src\libGLESv2</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\src\libGLESv2\Fence.h">
+      <Filter>src\libGLESv2</Filter>
+    </ClInclude>
+    <ClCompile Include="..\..\src\libGLESv2\Buffer.cpp">
+      <Filter>src\libGLESv2</Filter>
+    </ClCompile>
+    <ClInclude Include="..\..\src\libGLESv2\angletypes.h">
+      <Filter>src\libGLESv2</Filter>
+    </ClInclude>
+    <ClCompile Include="..\..\src\libGLESv2\VertexArray.cpp">
+      <Filter>src\libGLESv2</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\src\libGLESv2\Shader.cpp">
+      <Filter>src\libGLESv2</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\src\libGLESv2\Uniform.cpp">
+      <Filter>src\libGLESv2</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\src\libGLESv2\main.cpp">
+      <Filter>src\libGLESv2</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\src\libGLESv2\Renderbuffer.cpp">
+      <Filter>src\libGLESv2</Filter>
+    </ClCompile>
+    <ClInclude Include="..\..\src\libGLESv2\main.h">
+      <Filter>src\libGLESv2</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\src\libGLESv2\VertexArray.h">
+      <Filter>src\libGLESv2</Filter>
+    </ClInclude>
+    <ClCompile Include="..\..\src\libGLESv2\ImageIndex.cpp">
+      <Filter>src\libGLESv2</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\src\libGLESv2\Sampler.cpp">
+      <Filter>src\libGLESv2</Filter>
+    </ClCompile>
+    <ClInclude Include="..\..\src\libGLESv2\Framebuffer.h">
+      <Filter>src\libGLESv2</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\src\libGLESv2\formatutils.h">
+      <Filter>src\libGLESv2</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\src\libGLESv2\Buffer.h">
+      <Filter>src\libGLESv2</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\src\libGLESv2\State.h">
+      <Filter>src\libGLESv2</Filter>
+    </ClInclude>
+    <ClCompile Include="..\..\src\libGLESv2\Framebuffer.cpp">
+      <Filter>src\libGLESv2</Filter>
+    </ClCompile>
+    <ClInclude Include="..\..\src\libGLESv2\validationES.h">
+      <Filter>src\libGLESv2</Filter>
+    </ClInclude>
+    <ClCompile Include="..\..\src\libGLESv2\Texture.cpp">
+      <Filter>src\libGLESv2</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\src\libGLESv2\renderer\copyimage.cpp">
+      <Filter>src\libGLESv2\renderer</Filter>
+    </ClCompile>
+    <ClInclude Include="..\..\src\libGLESv2\renderer\TextureImpl.h">
+      <Filter>src\libGLESv2\renderer</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\src\libGLESv2\renderer\Renderer.h">
+      <Filter>src\libGLESv2\renderer</Filter>
+    </ClInclude>
+    <None Include="..\..\src\libGLESv2\renderer\loadimage.inl">
+      <Filter>src\libGLESv2\renderer</Filter>
+    </None>
+    <ClInclude Include="..\..\src\libGLESv2\renderer\ShaderImpl.h">
+      <Filter>src\libGLESv2\renderer</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\src\libGLESv2\renderer\TransformFeedbackImpl.h">
+      <Filter>src\libGLESv2\renderer</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\src\libGLESv2\renderer\ShaderExecutable.h">
+      <Filter>src\libGLESv2\renderer</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\src\libGLESv2\renderer\ProgramImpl.h">
+      <Filter>src\libGLESv2\renderer</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\src\libGLESv2\renderer\loadimage.h">
+      <Filter>src\libGLESv2\renderer</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\src\libGLESv2\renderer\copyimage.h">
+      <Filter>src\libGLESv2\renderer</Filter>
+    </ClInclude>
+    <ClCompile Include="..\..\src\libGLESv2\renderer\loadimage.cpp">
+      <Filter>src\libGLESv2\renderer</Filter>
+    </ClCompile>
+    <ClInclude Include="..\..\src\libGLESv2\renderer\BufferImpl.h">
+      <Filter>src\libGLESv2\renderer</Filter>
+    </ClInclude>
+    <ClCompile Include="..\..\src\libGLESv2\renderer\loadimageSSE2.cpp">
+      <Filter>src\libGLESv2\renderer</Filter>
+    </ClCompile>
+    <ClInclude Include="..\..\src\libGLESv2\renderer\copyvertex.h">
+      <Filter>src\libGLESv2\renderer</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\src\libGLESv2\renderer\VertexArrayImpl.h">
+      <Filter>src\libGLESv2\renderer</Filter>
+    </ClInclude>
+    <None Include="..\..\src\libGLESv2\renderer\copyvertex.inl">
+      <Filter>src\libGLESv2\renderer</Filter>
+    </None>
+    <ClInclude Include="..\..\src\libGLESv2\renderer\SwapChain.h">
+      <Filter>src\libGLESv2\renderer</Filter>
+    </ClInclude>
+    <ClCompile Include="..\..\src\libGLESv2\renderer\Image.cpp">
+      <Filter>src\libGLESv2\renderer</Filter>
+    </ClCompile>
+    <ClInclude Include="..\..\src\libGLESv2\renderer\imageformats.h">
+      <Filter>src\libGLESv2\renderer</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\src\libGLESv2\renderer\QueryImpl.h">
+      <Filter>src\libGLESv2\renderer</Filter>
+    </ClInclude>
+    <None Include="..\..\src\libGLESv2\renderer\copyimage.inl">
+      <Filter>src\libGLESv2\renderer</Filter>
+    </None>
+    <ClInclude Include="..\..\src\libGLESv2\renderer\IndexRangeCache.h">
+      <Filter>src\libGLESv2\renderer</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\src\libGLESv2\renderer\FenceImpl.h">
+      <Filter>src\libGLESv2\renderer</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\src\libGLESv2\renderer\Image.h">
+      <Filter>src\libGLESv2\renderer</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\src\libGLESv2\renderer\generatemip.h">
+      <Filter>src\libGLESv2\renderer</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\src\libGLESv2\renderer\RenderTarget.h">
+      <Filter>src\libGLESv2\renderer</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\src\libGLESv2\renderer\vertexconversion.h">
+      <Filter>src\libGLESv2\renderer</Filter>
+    </ClInclude>
+    <ClCompile Include="..\..\src\libGLESv2\renderer\Renderer.cpp">
+      <Filter>src\libGLESv2\renderer</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\src\libGLESv2\renderer\IndexRangeCache.cpp">
+      <Filter>src\libGLESv2\renderer</Filter>
+    </ClCompile>
+    <None Include="..\..\src\libGLESv2\renderer\generatemip.inl">
+      <Filter>src\libGLESv2\renderer</Filter>
+    </None>
+    <ClInclude Include="..\..\src\libGLESv2\renderer\d3d\DynamicHLSL.h">
+      <Filter>src\libGLESv2\renderer\d3d</Filter>
+    </ClInclude>
+    <ClCompile Include="..\..\src\libGLESv2\renderer\d3d\HLSLCompiler.cpp">
+      <Filter>src\libGLESv2\renderer\d3d</Filter>
+    </ClCompile>
+    <ClInclude Include="..\..\src\libGLESv2\renderer\d3d\IndexBuffer.h">
+      <Filter>src\libGLESv2\renderer\d3d</Filter>
+    </ClInclude>
+    <ClCompile Include="..\..\src\libGLESv2\renderer\d3d\DynamicHLSL.cpp">
+      <Filter>src\libGLESv2\renderer\d3d</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\src\libGLESv2\renderer\d3d\ShaderD3D.cpp">
+      <Filter>src\libGLESv2\renderer\d3d</Filter>
+    </ClCompile>
+    <ClInclude Include="..\..\src\libGLESv2\renderer\d3d\HLSLCompiler.h">
+      <Filter>src\libGLESv2\renderer\d3d</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\src\libGLESv2\renderer\d3d\ImageD3D.h">
+      <Filter>src\libGLESv2\renderer\d3d</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\src\libGLESv2\renderer\d3d\ProgramD3D.h">
+      <Filter>src\libGLESv2\renderer\d3d</Filter>
+    </ClInclude>
+    <ClCompile Include="..\..\src\libGLESv2\renderer\d3d\BufferD3D.cpp">
+      <Filter>src\libGLESv2\renderer\d3d</Filter>
+    </ClCompile>
+    <ClInclude Include="..\..\src\libGLESv2\renderer\d3d\MemoryBuffer.h">
+      <Filter>src\libGLESv2\renderer\d3d</Filter>
+    </ClInclude>
+    <ClCompile Include="..\..\src\libGLESv2\renderer\d3d\ProgramD3D.cpp">
+      <Filter>src\libGLESv2\renderer\d3d</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\src\libGLESv2\renderer\d3d\IndexBuffer.cpp">
+      <Filter>src\libGLESv2\renderer\d3d</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\src\libGLESv2\renderer\d3d\VertexBuffer.cpp">
+      <Filter>src\libGLESv2\renderer\d3d</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\src\libGLESv2\renderer\d3d\TextureD3D.cpp">
+      <Filter>src\libGLESv2\renderer\d3d</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\src\libGLESv2\renderer\d3d\VertexDataManager.cpp">
+      <Filter>src\libGLESv2\renderer\d3d</Filter>
+    </ClCompile>
+    <ClInclude Include="..\..\src\libGLESv2\renderer\d3d\TextureD3D.h">
+      <Filter>src\libGLESv2\renderer\d3d</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\src\libGLESv2\renderer\d3d\TextureStorage.h">
+      <Filter>src\libGLESv2\renderer\d3d</Filter>
+    </ClInclude>
+    <ClCompile Include="..\..\src\libGLESv2\renderer\d3d\MemoryBuffer.cpp">
+      <Filter>src\libGLESv2\renderer\d3d</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\src\libGLESv2\renderer\d3d\ImageD3D.cpp">
+      <Filter>src\libGLESv2\renderer\d3d</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\src\libGLESv2\renderer\d3d\TextureStorage.cpp">
+      <Filter>src\libGLESv2\renderer\d3d</Filter>
+    </ClCompile>
+    <ClInclude Include="..\..\src\libGLESv2\renderer\d3d\IndexDataManager.h">
+      <Filter>src\libGLESv2\renderer\d3d</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\src\libGLESv2\renderer\d3d\TransformFeedbackD3D.h">
+      <Filter>src\libGLESv2\renderer\d3d</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\src\libGLESv2\renderer\d3d\VertexBuffer.h">
+      <Filter>src\libGLESv2\renderer\d3d</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\src\libGLESv2\renderer\d3d\ShaderD3D.h">
+      <Filter>src\libGLESv2\renderer\d3d</Filter>
+    </ClInclude>
+    <ClCompile Include="..\..\src\libGLESv2\renderer\d3d\TransformFeedbackD3D.cpp">
+      <Filter>src\libGLESv2\renderer\d3d</Filter>
+    </ClCompile>
+    <ClInclude Include="..\..\src\libGLESv2\renderer\d3d\BufferD3D.h">
+      <Filter>src\libGLESv2\renderer\d3d</Filter>
+    </ClInclude>
+    <ClCompile Include="..\..\src\libGLESv2\renderer\d3d\IndexDataManager.cpp">
+      <Filter>src\libGLESv2\renderer\d3d</Filter>
+    </ClCompile>
+    <ClInclude Include="..\..\src\libGLESv2\renderer\d3d\VertexDataManager.h">
+      <Filter>src\libGLESv2\renderer\d3d</Filter>
+    </ClInclude>
+    <ClCompile Include="..\..\src\libGLESv2\renderer\d3d\d3d11\Renderer11.cpp">
+      <Filter>src\libGLESv2\renderer\d3d\d3d11</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\src\libGLESv2\renderer\d3d\d3d11\InputLayoutCache.cpp">
+      <Filter>src\libGLESv2\renderer\d3d\d3d11</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\src\libGLESv2\renderer\d3d\d3d11\PixelTransfer11.cpp">
+      <Filter>src\libGLESv2\renderer\d3d\d3d11</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\src\libGLESv2\renderer\d3d\d3d11\VertexBuffer11.cpp">
+      <Filter>src\libGLESv2\renderer\d3d\d3d11</Filter>
+    </ClCompile>
+    <ClInclude Include="..\..\src\libGLESv2\renderer\d3d\d3d11\Clear11.h">
+      <Filter>src\libGLESv2\renderer\d3d\d3d11</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\src\libGLESv2\renderer\d3d\d3d11\RenderStateCache.h">
+      <Filter>src\libGLESv2\renderer\d3d\d3d11</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\src\libGLESv2\renderer\d3d\d3d11\ShaderExecutable11.h">
+      <Filter>src\libGLESv2\renderer\d3d\d3d11</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\src\libGLESv2\renderer\d3d\d3d11\IndexBuffer11.h">
+      <Filter>src\libGLESv2\renderer\d3d\d3d11</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\src\libGLESv2\renderer\d3d\d3d11\Query11.h">
+      <Filter>src\libGLESv2\renderer\d3d\d3d11</Filter>
+    </ClInclude>
+    <ClCompile Include="..\..\src\libGLESv2\renderer\d3d\d3d11\Query11.cpp">
+      <Filter>src\libGLESv2\renderer\d3d\d3d11</Filter>
+    </ClCompile>
+    <ClInclude Include="..\..\src\libGLESv2\renderer\d3d\d3d11\Buffer11.h">
+      <Filter>src\libGLESv2\renderer\d3d\d3d11</Filter>
+    </ClInclude>
+    <ClCompile Include="..\..\src\libGLESv2\renderer\d3d\d3d11\ShaderExecutable11.cpp">
+      <Filter>src\libGLESv2\renderer\d3d\d3d11</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\src\libGLESv2\renderer\d3d\d3d11\Blit11.cpp">
+      <Filter>src\libGLESv2\renderer\d3d\d3d11</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\src\libGLESv2\renderer\d3d\d3d11\RenderStateCache.cpp">
+      <Filter>src\libGLESv2\renderer\d3d\d3d11</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\src\libGLESv2\renderer\d3d\d3d11\IndexBuffer11.cpp">
+      <Filter>src\libGLESv2\renderer\d3d\d3d11</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\src\libGLESv2\renderer\d3d\d3d11\formatutils11.cpp">
+      <Filter>src\libGLESv2\renderer\d3d\d3d11</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\src\libGLESv2\renderer\d3d\d3d11\SwapChain11.cpp">
+      <Filter>src\libGLESv2\renderer\d3d\d3d11</Filter>
+    </ClCompile>
+    <ClInclude Include="..\..\src\libGLESv2\renderer\d3d\d3d11\VertexBuffer11.h">
+      <Filter>src\libGLESv2\renderer\d3d\d3d11</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\src\libGLESv2\renderer\d3d\d3d11\TextureStorage11.h">
+      <Filter>src\libGLESv2\renderer\d3d\d3d11</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\src\libGLESv2\renderer\d3d\d3d11\Blit11.h">
+      <Filter>src\libGLESv2\renderer\d3d\d3d11</Filter>
+    </ClInclude>
+    <ClCompile Include="..\..\src\libGLESv2\renderer\d3d\d3d11\renderer11_utils.cpp">
+      <Filter>src\libGLESv2\renderer\d3d\d3d11</Filter>
+    </ClCompile>
+    <ClInclude Include="..\..\src\libGLESv2\renderer\d3d\d3d11\Image11.h">
+      <Filter>src\libGLESv2\renderer\d3d\d3d11</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\src\libGLESv2\renderer\d3d\d3d11\RenderTarget11.h">
+      <Filter>src\libGLESv2\renderer\d3d\d3d11</Filter>
+    </ClInclude>
+    <ClCompile Include="..\..\src\libGLESv2\renderer\d3d\d3d11\Image11.cpp">
+      <Filter>src\libGLESv2\renderer\d3d\d3d11</Filter>
+    </ClCompile>
+    <ClInclude Include="..\..\src\libGLESv2\renderer\d3d\d3d11\InputLayoutCache.h">
+      <Filter>src\libGLESv2\renderer\d3d\d3d11</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\src\libGLESv2\renderer\d3d\d3d11\SwapChain11.h">
+      <Filter>src\libGLESv2\renderer\d3d\d3d11</Filter>
+    </ClInclude>
+    <ClCompile Include="..\..\src\libGLESv2\renderer\d3d\d3d11\TextureStorage11.cpp">
+      <Filter>src\libGLESv2\renderer\d3d\d3d11</Filter>
+    </ClCompile>
+    <ClInclude Include="..\..\src\libGLESv2\renderer\d3d\d3d11\Fence11.h">
+      <Filter>src\libGLESv2\renderer\d3d\d3d11</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\src\libGLESv2\renderer\d3d\d3d11\VertexArray11.h">
+      <Filter>src\libGLESv2\renderer\d3d\d3d11</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\src\libGLESv2\renderer\d3d\d3d11\renderer11_utils.h">
+      <Filter>src\libGLESv2\renderer\d3d\d3d11</Filter>
+    </ClInclude>
+    <ClCompile Include="..\..\src\libGLESv2\renderer\d3d\d3d11\Buffer11.cpp">
+      <Filter>src\libGLESv2\renderer\d3d\d3d11</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\src\libGLESv2\renderer\d3d\d3d11\RenderTarget11.cpp">
+      <Filter>src\libGLESv2\renderer\d3d\d3d11</Filter>
+    </ClCompile>
+    <ClInclude Include="..\..\src\libGLESv2\renderer\d3d\d3d11\Renderer11.h">
+      <Filter>src\libGLESv2\renderer\d3d\d3d11</Filter>
+    </ClInclude>
+    <ClCompile Include="..\..\src\libGLESv2\renderer\d3d\d3d11\Fence11.cpp">
+      <Filter>src\libGLESv2\renderer\d3d\d3d11</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\src\libGLESv2\renderer\d3d\d3d11\Clear11.cpp">
+      <Filter>src\libGLESv2\renderer\d3d\d3d11</Filter>
+    </ClCompile>
+    <ClInclude Include="..\..\src\libGLESv2\renderer\d3d\d3d11\PixelTransfer11.h">
+      <Filter>src\libGLESv2\renderer\d3d\d3d11</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\src\libGLESv2\renderer\d3d\d3d11\formatutils11.h">
+      <Filter>src\libGLESv2\renderer\d3d\d3d11</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\src\libGLESv2\renderer\d3d\d3d11\shaders\compiled\swizzleui2dps.h">
+      <Filter>src\libGLESv2\renderer\d3d\d3d11\shaders\compiled</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\src\libGLESv2\renderer\d3d\d3d11\shaders\compiled\passthroughr2d11ps.h">
+      <Filter>src\libGLESv2\renderer\d3d\d3d11\shaders\compiled</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\src\libGLESv2\renderer\d3d\d3d11\shaders\compiled\passthroughr3dui11ps.h">
+      <Filter>src\libGLESv2\renderer\d3d\d3d11\shaders\compiled</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\src\libGLESv2\renderer\d3d\d3d11\shaders\compiled\swizzlef3dps.h">
+      <Filter>src\libGLESv2\renderer\d3d\d3d11\shaders\compiled</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\src\libGLESv2\renderer\d3d\d3d11\shaders\compiled\passthroughlumalpha2d11ps.h">
+      <Filter>src\libGLESv2\renderer\d3d\d3d11\shaders\compiled</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\src\libGLESv2\renderer\d3d\d3d11\shaders\compiled\passthroughrg2dui11ps.h">
+      <Filter>src\libGLESv2\renderer\d3d\d3d11\shaders\compiled</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\src\libGLESv2\renderer\d3d\d3d11\shaders\compiled\passthroughrgb3d11ps.h">
+      <Filter>src\libGLESv2\renderer\d3d\d3d11\shaders\compiled</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\src\libGLESv2\renderer\d3d\d3d11\shaders\compiled\passthroughrgb2di11ps.h">
+      <Filter>src\libGLESv2\renderer\d3d\d3d11\shaders\compiled</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\src\libGLESv2\renderer\d3d\d3d11\shaders\compiled\swizzleui3dps.h">
+      <Filter>src\libGLESv2\renderer\d3d\d3d11\shaders\compiled</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\src\libGLESv2\renderer\d3d\d3d11\shaders\compiled\clearsint11ps.h">
+      <Filter>src\libGLESv2\renderer\d3d\d3d11\shaders\compiled</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\src\libGLESv2\renderer\d3d\d3d11\shaders\compiled\swizzlef2dps.h">
+      <Filter>src\libGLESv2\renderer\d3d\d3d11\shaders\compiled</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\src\libGLESv2\renderer\d3d\d3d11\shaders\compiled\passthroughrg3di11ps.h">
+      <Filter>src\libGLESv2\renderer\d3d\d3d11\shaders\compiled</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\src\libGLESv2\renderer\d3d\d3d11\shaders\compiled\swizzlei2darrayps.h">
+      <Filter>src\libGLESv2\renderer\d3d\d3d11\shaders\compiled</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\src\libGLESv2\renderer\d3d\d3d11\shaders\compiled\passthroughlumalpha3d11ps.h">
+      <Filter>src\libGLESv2\renderer\d3d\d3d11\shaders\compiled</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\src\libGLESv2\renderer\d3d\d3d11\shaders\compiled\passthroughrgba3di11ps.h">
+      <Filter>src\libGLESv2\renderer\d3d\d3d11\shaders\compiled</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\src\libGLESv2\renderer\d3d\d3d11\shaders\compiled\passthroughrgb2d11ps.h">
+      <Filter>src\libGLESv2\renderer\d3d\d3d11\shaders\compiled</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\src\libGLESv2\renderer\d3d\d3d11\shaders\compiled\clearsint11vs.h">
+      <Filter>src\libGLESv2\renderer\d3d\d3d11\shaders\compiled</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\src\libGLESv2\renderer\d3d\d3d11\shaders\compiled\passthrough2d11vs.h">
+      <Filter>src\libGLESv2\renderer\d3d\d3d11\shaders\compiled</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\src\libGLESv2\renderer\d3d\d3d11\shaders\compiled\buffertotexture11_ps_4f.h">
+      <Filter>src\libGLESv2\renderer\d3d\d3d11\shaders\compiled</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\src\libGLESv2\renderer\d3d\d3d11\shaders\compiled\buffertotexture11_gs.h">
+      <Filter>src\libGLESv2\renderer\d3d\d3d11\shaders\compiled</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\src\libGLESv2\renderer\d3d\d3d11\shaders\compiled\clearfloat11vs.h">
+      <Filter>src\libGLESv2\renderer\d3d\d3d11\shaders\compiled</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\src\libGLESv2\renderer\d3d\d3d11\shaders\compiled\passthroughrgba2di11ps.h">
+      <Filter>src\libGLESv2\renderer\d3d\d3d11\shaders\compiled</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\src\libGLESv2\renderer\d3d\d3d11\shaders\compiled\passthroughr2dui11ps.h">
+      <Filter>src\libGLESv2\renderer\d3d\d3d11\shaders\compiled</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\src\libGLESv2\renderer\d3d\d3d11\shaders\compiled\clearfloat11ps.h">
+      <Filter>src\libGLESv2\renderer\d3d\d3d11\shaders\compiled</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\src\libGLESv2\renderer\d3d\d3d11\shaders\compiled\buffertotexture11_ps_4i.h">
+      <Filter>src\libGLESv2\renderer\d3d\d3d11\shaders\compiled</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\src\libGLESv2\renderer\d3d\d3d11\shaders\compiled\passthroughrg3dui11ps.h">
+      <Filter>src\libGLESv2\renderer\d3d\d3d11\shaders\compiled</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\src\libGLESv2\renderer\d3d\d3d11\shaders\compiled\swizzlei2dps.h">
+      <Filter>src\libGLESv2\renderer\d3d\d3d11\shaders\compiled</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\src\libGLESv2\renderer\d3d\d3d11\shaders\compiled\passthroughrg2d11ps.h">
+      <Filter>src\libGLESv2\renderer\d3d\d3d11\shaders\compiled</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\src\libGLESv2\renderer\d3d\d3d11\shaders\compiled\passthroughrgba2dui11ps.h">
+      <Filter>src\libGLESv2\renderer\d3d\d3d11\shaders\compiled</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\src\libGLESv2\renderer\d3d\d3d11\shaders\compiled\passthroughr2di11ps.h">
+      <Filter>src\libGLESv2\renderer\d3d\d3d11\shaders\compiled</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\src\libGLESv2\renderer\d3d\d3d11\shaders\compiled\passthroughrgba3d11ps.h">
+      <Filter>src\libGLESv2\renderer\d3d\d3d11\shaders\compiled</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\src\libGLESv2\renderer\d3d\d3d11\shaders\compiled\passthroughlum3d11ps.h">
+      <Filter>src\libGLESv2\renderer\d3d\d3d11\shaders\compiled</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\src\libGLESv2\renderer\d3d\d3d11\shaders\compiled\clearuint11vs.h">
+      <Filter>src\libGLESv2\renderer\d3d\d3d11\shaders\compiled</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\src\libGLESv2\renderer\d3d\d3d11\shaders\compiled\passthroughr3d11ps.h">
+      <Filter>src\libGLESv2\renderer\d3d\d3d11\shaders\compiled</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\src\libGLESv2\renderer\d3d\d3d11\shaders\compiled\passthroughrg2di11ps.h">
+      <Filter>src\libGLESv2\renderer\d3d\d3d11\shaders\compiled</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\src\libGLESv2\renderer\d3d\d3d11\shaders\compiled\clearuint11ps.h">
+      <Filter>src\libGLESv2\renderer\d3d\d3d11\shaders\compiled</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\src\libGLESv2\renderer\d3d\d3d11\shaders\compiled\passthrough3d11vs.h">
+      <Filter>src\libGLESv2\renderer\d3d\d3d11\shaders\compiled</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\src\libGLESv2\renderer\d3d\d3d11\shaders\compiled\passthroughdepth2d11ps.h">
+      <Filter>src\libGLESv2\renderer\d3d\d3d11\shaders\compiled</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\src\libGLESv2\renderer\d3d\d3d11\shaders\compiled\passthroughlum2d11ps.h">
+      <Filter>src\libGLESv2\renderer\d3d\d3d11\shaders\compiled</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\src\libGLESv2\renderer\d3d\d3d11\shaders\compiled\passthroughrgb2dui11ps.h">
+      <Filter>src\libGLESv2\renderer\d3d\d3d11\shaders\compiled</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\src\libGLESv2\renderer\d3d\d3d11\shaders\compiled\swizzlei3dps.h">
+      <Filter>src\libGLESv2\renderer\d3d\d3d11\shaders\compiled</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\src\libGLESv2\renderer\d3d\d3d11\shaders\compiled\passthroughrgb3dui11ps.h">
+      <Filter>src\libGLESv2\renderer\d3d\d3d11\shaders\compiled</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\src\libGLESv2\renderer\d3d\d3d11\shaders\compiled\swizzlef2darrayps.h">
+      <Filter>src\libGLESv2\renderer\d3d\d3d11\shaders\compiled</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\src\libGLESv2\renderer\d3d\d3d11\shaders\compiled\buffertotexture11_vs.h">
+      <Filter>src\libGLESv2\renderer\d3d\d3d11\shaders\compiled</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\src\libGLESv2\renderer\d3d\d3d11\shaders\compiled\passthroughrgb3di11ps.h">
+      <Filter>src\libGLESv2\renderer\d3d\d3d11\shaders\compiled</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\src\libGLESv2\renderer\d3d\d3d11\shaders\compiled\passthroughrg3d11ps.h">
+      <Filter>src\libGLESv2\renderer\d3d\d3d11\shaders\compiled</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\src\libGLESv2\renderer\d3d\d3d11\shaders\compiled\passthroughrgba2d11ps.h">
+      <Filter>src\libGLESv2\renderer\d3d\d3d11\shaders\compiled</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\src\libGLESv2\renderer\d3d\d3d11\shaders\compiled\swizzleui2darrayps.h">
+      <Filter>src\libGLESv2\renderer\d3d\d3d11\shaders\compiled</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\src\libGLESv2\renderer\d3d\d3d11\shaders\compiled\passthroughrgba3dui11ps.h">
+      <Filter>src\libGLESv2\renderer\d3d\d3d11\shaders\compiled</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\src\libGLESv2\renderer\d3d\d3d11\shaders\compiled\buffertotexture11_ps_4ui.h">
+      <Filter>src\libGLESv2\renderer\d3d\d3d11\shaders\compiled</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\src\libGLESv2\renderer\d3d\d3d11\shaders\compiled\passthroughr3di11ps.h">
+      <Filter>src\libGLESv2\renderer\d3d\d3d11\shaders\compiled</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\src\libGLESv2\renderer\d3d\d3d11\shaders\compiled\passthrough3d11gs.h">
+      <Filter>src\libGLESv2\renderer\d3d\d3d11\shaders\compiled</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\src\libGLESv2\renderer\d3d\d3d9\renderer9_utils.h">
+      <Filter>src\libGLESv2\renderer\d3d\d3d9</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\src\libGLESv2\renderer\d3d\d3d9\TextureStorage9.h">
+      <Filter>src\libGLESv2\renderer\d3d\d3d9</Filter>
+    </ClInclude>
+    <ClCompile Include="..\..\src\libGLESv2\renderer\d3d\d3d9\VertexDeclarationCache.cpp">
+      <Filter>src\libGLESv2\renderer\d3d\d3d9</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\src\libGLESv2\renderer\d3d\d3d9\Query9.cpp">
+      <Filter>src\libGLESv2\renderer\d3d\d3d9</Filter>
+    </ClCompile>
+    <ClInclude Include="..\..\src\libGLESv2\renderer\d3d\d3d9\IndexBuffer9.h">
+      <Filter>src\libGLESv2\renderer\d3d\d3d9</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\src\libGLESv2\renderer\d3d\d3d9\ShaderCache.h">
+      <Filter>src\libGLESv2\renderer\d3d\d3d9</Filter>
+    </ClInclude>
+    <ClCompile Include="..\..\src\libGLESv2\renderer\d3d\d3d9\VertexBuffer9.cpp">
+      <Filter>src\libGLESv2\renderer\d3d\d3d9</Filter>
+    </ClCompile>
+    <ClInclude Include="..\..\src\libGLESv2\renderer\d3d\d3d9\Fence9.h">
+      <Filter>src\libGLESv2\renderer\d3d\d3d9</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\src\libGLESv2\renderer\d3d\d3d9\VertexArray9.h">
+      <Filter>src\libGLESv2\renderer\d3d\d3d9</Filter>
+    </ClInclude>
+    <ClCompile Include="..\..\src\libGLESv2\renderer\d3d\d3d9\Fence9.cpp">
+      <Filter>src\libGLESv2\renderer\d3d\d3d9</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\src\libGLESv2\renderer\d3d\d3d9\Image9.cpp">
+      <Filter>src\libGLESv2\renderer\d3d\d3d9</Filter>
+    </ClCompile>
+    <ClInclude Include="..\..\src\libGLESv2\renderer\d3d\d3d9\Renderer9.h">
+      <Filter>src\libGLESv2\renderer\d3d\d3d9</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\src\libGLESv2\renderer\d3d\d3d9\Blit9.h">
+      <Filter>src\libGLESv2\renderer\d3d\d3d9</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\src\libGLESv2\renderer\d3d\d3d9\VertexDeclarationCache.h">
+      <Filter>src\libGLESv2\renderer\d3d\d3d9</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\src\libGLESv2\renderer\d3d\d3d9\Image9.h">
+      <Filter>src\libGLESv2\renderer\d3d\d3d9</Filter>
+    </ClInclude>
+    <ClCompile Include="..\..\src\libGLESv2\renderer\d3d\d3d9\TextureStorage9.cpp">
+      <Filter>src\libGLESv2\renderer\d3d\d3d9</Filter>
+    </ClCompile>
+    <ClInclude Include="..\..\src\libGLESv2\renderer\d3d\d3d9\VertexBuffer9.h">
+      <Filter>src\libGLESv2\renderer\d3d\d3d9</Filter>
+    </ClInclude>
+    <ClCompile Include="..\..\src\libGLESv2\renderer\d3d\d3d9\Renderer9.cpp">
+      <Filter>src\libGLESv2\renderer\d3d\d3d9</Filter>
+    </ClCompile>
+    <ClInclude Include="..\..\src\libGLESv2\renderer\d3d\d3d9\formatutils9.h">
+      <Filter>src\libGLESv2\renderer\d3d\d3d9</Filter>
+    </ClInclude>
+    <ClCompile Include="..\..\src\libGLESv2\renderer\d3d\d3d9\RenderTarget9.cpp">
+      <Filter>src\libGLESv2\renderer\d3d\d3d9</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\src\libGLESv2\renderer\d3d\d3d9\formatutils9.cpp">
+      <Filter>src\libGLESv2\renderer\d3d\d3d9</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\src\libGLESv2\renderer\d3d\d3d9\Buffer9.cpp">
+      <Filter>src\libGLESv2\renderer\d3d\d3d9</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\src\libGLESv2\renderer\d3d\d3d9\ShaderExecutable9.cpp">
+      <Filter>src\libGLESv2\renderer\d3d\d3d9</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\src\libGLESv2\renderer\d3d\d3d9\renderer9_utils.cpp">
+      <Filter>src\libGLESv2\renderer\d3d\d3d9</Filter>
+    </ClCompile>
+    <ClInclude Include="..\..\src\libGLESv2\renderer\d3d\d3d9\Query9.h">
+      <Filter>src\libGLESv2\renderer\d3d\d3d9</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\src\libGLESv2\renderer\d3d\d3d9\RenderTarget9.h">
+      <Filter>src\libGLESv2\renderer\d3d\d3d9</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\src\libGLESv2\renderer\d3d\d3d9\SwapChain9.h">
+      <Filter>src\libGLESv2\renderer\d3d\d3d9</Filter>
+    </ClInclude>
+    <ClCompile Include="..\..\src\libGLESv2\renderer\d3d\d3d9\SwapChain9.cpp">
+      <Filter>src\libGLESv2\renderer\d3d\d3d9</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\src\libGLESv2\renderer\d3d\d3d9\Blit9.cpp">
+      <Filter>src\libGLESv2\renderer\d3d\d3d9</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\src\libGLESv2\renderer\d3d\d3d9\IndexBuffer9.cpp">
+      <Filter>src\libGLESv2\renderer\d3d\d3d9</Filter>
+    </ClCompile>
+    <ClInclude Include="..\..\src\libGLESv2\renderer\d3d\d3d9\Buffer9.h">
+      <Filter>src\libGLESv2\renderer\d3d\d3d9</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\src\libGLESv2\renderer\d3d\d3d9\shaders\compiled\standardvs.h">
+      <Filter>src\libGLESv2\renderer\d3d\d3d9\shaders\compiled</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\src\libGLESv2\renderer\d3d\d3d9\shaders\compiled\luminanceps.h">
+      <Filter>src\libGLESv2\renderer\d3d\d3d9\shaders\compiled</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\src\libGLESv2\renderer\d3d\d3d9\shaders\compiled\componentmaskps.h">
+      <Filter>src\libGLESv2\renderer\d3d\d3d9\shaders\compiled</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\src\libGLESv2\renderer\d3d\d3d9\shaders\compiled\passthroughps.h">
+      <Filter>src\libGLESv2\renderer\d3d\d3d9\shaders\compiled</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\src\libGLESv2\renderer\d3d\d3d9\shaders\compiled\flipyvs.h">
+      <Filter>src\libGLESv2\renderer\d3d\d3d9\shaders\compiled</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\src\common\tls.h">
+      <Filter>src\common</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\src\common\mathutil.h">
+      <Filter>src\common</Filter>
+    </ClInclude>
+    <ClCompile Include="..\..\src\common\event_tracer.cpp">
+      <Filter>src\common</Filter>
+    </ClCompile>
+    <ClInclude Include="..\..\src\common\blocklayout.h">
+      <Filter>src\common</Filter>
+    </ClInclude>
+    <ClCompile Include="..\..\src\common\RefCountObject.cpp">
+      <Filter>src\common</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\src\common\tls.cpp">
+      <Filter>src\common</Filter>
+    </ClCompile>
+    <ClInclude Include="..\..\src\common\debug.h">
+      <Filter>src\common</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\src\common\utilities.h">
+      <Filter>src\common</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\src\common\RefCountObject.h">
+      <Filter>src\common</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\src\common\event_tracer.h">
+      <Filter>src\common</Filter>
+    </ClInclude>
+    <ClCompile Include="..\..\src\common\utilities.cpp">
+      <Filter>src\common</Filter>
+    </ClCompile>
+    <ClInclude Include="..\..\src\common\angleutils.h">
+      <Filter>src\common</Filter>
+    </ClInclude>
+    <ClCompile Include="..\..\src\common\mathutil.cpp">
+      <Filter>src\common</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\src\common\debug.cpp">
+      <Filter>src\common</Filter>
+    </ClCompile>
+    <ClInclude Include="..\..\src\common\platform.h">
+      <Filter>src\common</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\src\common\version.h">
+      <Filter>src\common</Filter>
+    </ClInclude>
+    <ClCompile Include="..\..\src\common\blocklayout.cpp">
+      <Filter>src\common</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\src\common\angleutils.cpp">
+      <Filter>src\common</Filter>
+    </ClCompile>
+    <ClInclude Include="..\..\src\third_party\systeminfo\SystemInfo.h">
+      <Filter>src\third_party\systeminfo</Filter>
+    </ClInclude>
+    <ClCompile Include="..\..\src\third_party\systeminfo\SystemInfo.cpp">
+      <Filter>src\third_party\systeminfo</Filter>
+    </ClCompile>
+    <ClInclude Include="..\..\src\third_party\murmurhash\MurmurHash3.h">
+      <Filter>src\third_party\murmurhash</Filter>
+    </ClInclude>
+    <ClCompile Include="..\..\src\third_party\murmurhash\MurmurHash3.cpp">
+      <Filter>src\third_party\murmurhash</Filter>
+    </ClCompile>
+    <ClInclude Include="..\..\include\angle_gl.h">
+      <Filter>include</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\include\KHR\khrplatform.h">
+      <Filter>include\KHR</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\include\GLSLANG\ShaderLang.h">
+      <Filter>include\GLSLANG</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\include\GLSLANG\ShaderVars.h">
+      <Filter>include\GLSLANG</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\include\GLES2\gl2ext.h">
+      <Filter>include\GLES2</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\include\GLES2\gl2.h">
+      <Filter>include\GLES2</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\include\GLES2\gl2platform.h">
+      <Filter>include\GLES2</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\include\GLES3\gl3ext.h">
+      <Filter>include\GLES3</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\include\GLES3\gl3.h">
+      <Filter>include\GLES3</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\include\GLES3\gl3platform.h">
+      <Filter>include\GLES3</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\include\EGL\eglext.h">
+      <Filter>include\EGL</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\include\EGL\egl.h">
+      <Filter>include\EGL</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\include\EGL\eglplatform.h">
+      <Filter>include\EGL</Filter>
+    </ClInclude>
+  </ItemGroup>
+</Project>
diff --git a/projects/src/libEGL.vcxproj b/projects/src/libEGL.vcxproj
index 0817262..8e25de4 100644
--- a/projects/src/libEGL.vcxproj
+++ b/projects/src/libEGL.vcxproj
@@ -68,6 +68,7 @@
     </ClCompile>
     <Lib>
       <AdditionalLibraryDirectories>C:/Program Files (x86)/Windows Kits/8.0/Lib/win8/um/x86;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
+      <TargetMachine>MachineX86</TargetMachine>
     </Lib>
     <Link>
       <AdditionalDependencies>d3d9.lib;kernel32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;user32.lib;uuid.lib;odbc32.lib;odbccp32.lib;delayimp.lib</AdditionalDependencies>
@@ -145,6 +146,7 @@
     </ClCompile>
     <Lib>
       <AdditionalLibraryDirectories>C:/Program Files (x86)/Windows Kits/8.0/Lib/win8/um/x86;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
+      <TargetMachine>MachineX86</TargetMachine>
     </Lib>
     <Link>
       <AdditionalDependencies>d3d9.lib;kernel32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;user32.lib;uuid.lib;odbc32.lib;odbccp32.lib;delayimp.lib</AdditionalDependencies>
@@ -247,6 +249,7 @@
     <ClCompile Include="..\..\src\common\debug.cpp"/>
     <ClCompile Include="..\..\src\common\event_tracer.cpp"/>
     <ClCompile Include="..\..\src\common\utilities.cpp"/>
+    <ClCompile Include="..\..\src\common\angleutils.cpp"/>
   </ItemGroup>
   <ItemGroup>
     <ResourceCompile Include="..\..\src\libEGL\libEGL.rc"/>
diff --git a/projects/src/libEGL.vcxproj.filters b/projects/src/libEGL.vcxproj.filters
index e55fe42..feb9c0c 100644
--- a/projects/src/libEGL.vcxproj.filters
+++ b/projects/src/libEGL.vcxproj.filters
@@ -114,6 +114,9 @@
     <ClInclude Include="..\..\src\common\angleutils.h">
       <Filter>src\common</Filter>
     </ClInclude>
+    <ClCompile Include="..\..\src\common\angleutils.cpp">
+      <Filter>src\common</Filter>
+    </ClCompile>
     <ClInclude Include="..\..\include\angle_gl.h">
       <Filter>include</Filter>
     </ClInclude>
diff --git a/projects/src/libGLESv2.vcxproj b/projects/src/libGLESv2.vcxproj
index c684911..2be234a 100644
--- a/projects/src/libGLESv2.vcxproj
+++ b/projects/src/libGLESv2.vcxproj
@@ -50,7 +50,7 @@
   </PropertyGroup>
   <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
     <ClCompile>
-      <AdditionalIncludeDirectories>..\..\src;..\..\include;..\..\src\libGLESv2;$(OutDir)obj\global_intermediate\angle;C:\Program Files (x86)\Windows Kits\8.0\Include\shared;C:\Program Files (x86)\Windows Kits\8.0\Include\um;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <AdditionalIncludeDirectories>$(OutDir)obj\global_intermediate\angle;..\..\src;..\..\include;..\..\src\libGLESv2;C:\Program Files (x86)\Windows Kits\8.0\Include\shared;C:\Program Files (x86)\Windows Kits\8.0\Include\um;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
       <AdditionalOptions>/MP %(AdditionalOptions)</AdditionalOptions>
       <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
       <BufferSecurityCheck>true</BufferSecurityCheck>
@@ -60,7 +60,7 @@
       <FunctionLevelLinking>true</FunctionLevelLinking>
       <MinimalRebuild>false</MinimalRebuild>
       <Optimization>Disabled</Optimization>
-      <PreprocessorDefinitions>_CRT_SECURE_NO_DEPRECATE;_SCL_SECURE_NO_WARNINGS;NOMINMAX;GL_APICALL=;GL_GLEXT_PROTOTYPES=;EGLAPI=;ANGLE_PRELOADED_D3DCOMPILER_MODULE_NAMES={ &quot;d3dcompiler_46.dll&quot;, &quot;d3dcompiler_43.dll&quot; };ANGLE_ENABLE_D3D9;ANGLE_ENABLE_D3D11;ANGLE_ENABLE_PERF;_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <PreprocessorDefinitions>_CRT_SECURE_NO_DEPRECATE;_SCL_SECURE_NO_WARNINGS;NOMINMAX;GL_APICALL=;GL_GLEXT_PROTOTYPES=;EGLAPI=;ANGLE_PRELOADED_D3DCOMPILER_MODULE_NAMES={ &quot;d3dcompiler_46.dll&quot;, &quot;d3dcompiler_43.dll&quot; };_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
       <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
       <RuntimeTypeInfo>true</RuntimeTypeInfo>
       <TreatWarningAsError>true</TreatWarningAsError>
@@ -68,6 +68,7 @@
     </ClCompile>
     <Lib>
       <AdditionalLibraryDirectories>C:/Program Files (x86)/Windows Kits/8.0/Lib/win8/um/x86;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
+      <TargetMachine>MachineX86</TargetMachine>
     </Lib>
     <Link>
       <AdditionalDependencies>kernel32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;user32.lib;uuid.lib;odbc32.lib;odbccp32.lib;delayimp.lib;d3d9.lib;dxguid.lib</AdditionalDependencies>
@@ -82,14 +83,14 @@
       <TargetMachine>MachineX86</TargetMachine>
     </Link>
     <ResourceCompile>
-      <AdditionalIncludeDirectories>..\..\src;..\..\include;..\..\src\libGLESv2;$(OutDir)obj\global_intermediate\angle;C:\Program Files (x86)\Windows Kits\8.0\Include\shared;C:\Program Files (x86)\Windows Kits\8.0\Include\um;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <AdditionalIncludeDirectories>$(OutDir)obj\global_intermediate\angle;..\..\src;..\..\include;..\..\src\libGLESv2;C:\Program Files (x86)\Windows Kits\8.0\Include\shared;C:\Program Files (x86)\Windows Kits\8.0\Include\um;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
       <Culture>0x0409</Culture>
-      <PreprocessorDefinitions>GL_APICALL=;GL_GLEXT_PROTOTYPES=;EGLAPI=;ANGLE_PRELOADED_D3DCOMPILER_MODULE_NAMES={ &quot;d3dcompiler_46.dll&quot;, &quot;d3dcompiler_43.dll&quot; };ANGLE_ENABLE_D3D9;ANGLE_ENABLE_D3D11;ANGLE_ENABLE_PERF;_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <PreprocessorDefinitions>GL_APICALL=;GL_GLEXT_PROTOTYPES=;EGLAPI=;ANGLE_PRELOADED_D3DCOMPILER_MODULE_NAMES={ &quot;d3dcompiler_46.dll&quot;, &quot;d3dcompiler_43.dll&quot; };_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
     </ResourceCompile>
   </ItemDefinitionGroup>
   <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
     <ClCompile>
-      <AdditionalIncludeDirectories>..\..\src;..\..\include;..\..\src\libGLESv2;$(OutDir)obj\global_intermediate\angle;C:\Program Files (x86)\Windows Kits\8.0\Include\shared;C:\Program Files (x86)\Windows Kits\8.0\Include\um;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <AdditionalIncludeDirectories>$(OutDir)obj\global_intermediate\angle;..\..\src;..\..\include;..\..\src\libGLESv2;C:\Program Files (x86)\Windows Kits\8.0\Include\shared;C:\Program Files (x86)\Windows Kits\8.0\Include\um;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
       <AdditionalOptions>/MP %(AdditionalOptions)</AdditionalOptions>
       <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
       <BufferSecurityCheck>true</BufferSecurityCheck>
@@ -99,7 +100,7 @@
       <FunctionLevelLinking>true</FunctionLevelLinking>
       <MinimalRebuild>false</MinimalRebuild>
       <Optimization>Disabled</Optimization>
-      <PreprocessorDefinitions>_CRT_SECURE_NO_DEPRECATE;_SCL_SECURE_NO_WARNINGS;NOMINMAX;GL_APICALL=;GL_GLEXT_PROTOTYPES=;EGLAPI=;ANGLE_PRELOADED_D3DCOMPILER_MODULE_NAMES={ &quot;d3dcompiler_46.dll&quot;, &quot;d3dcompiler_43.dll&quot; };ANGLE_ENABLE_D3D9;ANGLE_ENABLE_D3D11;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <PreprocessorDefinitions>_CRT_SECURE_NO_DEPRECATE;_SCL_SECURE_NO_WARNINGS;NOMINMAX;GL_APICALL=;GL_GLEXT_PROTOTYPES=;EGLAPI=;ANGLE_PRELOADED_D3DCOMPILER_MODULE_NAMES={ &quot;d3dcompiler_46.dll&quot;, &quot;d3dcompiler_43.dll&quot; };%(PreprocessorDefinitions)</PreprocessorDefinitions>
       <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
       <RuntimeTypeInfo>true</RuntimeTypeInfo>
       <TreatWarningAsError>true</TreatWarningAsError>
@@ -121,14 +122,14 @@
       <TargetMachine>MachineX64</TargetMachine>
     </Link>
     <ResourceCompile>
-      <AdditionalIncludeDirectories>..\..\src;..\..\include;..\..\src\libGLESv2;$(OutDir)obj\global_intermediate\angle;C:\Program Files (x86)\Windows Kits\8.0\Include\shared;C:\Program Files (x86)\Windows Kits\8.0\Include\um;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <AdditionalIncludeDirectories>$(OutDir)obj\global_intermediate\angle;..\..\src;..\..\include;..\..\src\libGLESv2;C:\Program Files (x86)\Windows Kits\8.0\Include\shared;C:\Program Files (x86)\Windows Kits\8.0\Include\um;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
       <Culture>0x0409</Culture>
-      <PreprocessorDefinitions>GL_APICALL=;GL_GLEXT_PROTOTYPES=;EGLAPI=;ANGLE_PRELOADED_D3DCOMPILER_MODULE_NAMES={ &quot;d3dcompiler_46.dll&quot;, &quot;d3dcompiler_43.dll&quot; };ANGLE_ENABLE_D3D9;ANGLE_ENABLE_D3D11;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <PreprocessorDefinitions>GL_APICALL=;GL_GLEXT_PROTOTYPES=;EGLAPI=;ANGLE_PRELOADED_D3DCOMPILER_MODULE_NAMES={ &quot;d3dcompiler_46.dll&quot;, &quot;d3dcompiler_43.dll&quot; };%(PreprocessorDefinitions)</PreprocessorDefinitions>
     </ResourceCompile>
   </ItemDefinitionGroup>
   <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
     <ClCompile>
-      <AdditionalIncludeDirectories>..\..\src;..\..\include;..\..\src\libGLESv2;$(OutDir)obj\global_intermediate\angle;C:\Program Files (x86)\Windows Kits\8.0\Include\shared;C:\Program Files (x86)\Windows Kits\8.0\Include\um;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <AdditionalIncludeDirectories>$(OutDir)obj\global_intermediate\angle;..\..\src;..\..\include;..\..\src\libGLESv2;C:\Program Files (x86)\Windows Kits\8.0\Include\shared;C:\Program Files (x86)\Windows Kits\8.0\Include\um;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
       <AdditionalOptions>/MP %(AdditionalOptions)</AdditionalOptions>
       <BufferSecurityCheck>true</BufferSecurityCheck>
       <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
@@ -137,7 +138,7 @@
       <FunctionLevelLinking>true</FunctionLevelLinking>
       <MinimalRebuild>false</MinimalRebuild>
       <Optimization>MaxSpeed</Optimization>
-      <PreprocessorDefinitions>_CRT_SECURE_NO_DEPRECATE;_SCL_SECURE_NO_WARNINGS;NOMINMAX;GL_APICALL=;GL_GLEXT_PROTOTYPES=;EGLAPI=;ANGLE_PRELOADED_D3DCOMPILER_MODULE_NAMES={ &quot;d3dcompiler_46.dll&quot;, &quot;d3dcompiler_43.dll&quot; };ANGLE_ENABLE_D3D9;ANGLE_ENABLE_D3D11;NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <PreprocessorDefinitions>_CRT_SECURE_NO_DEPRECATE;_SCL_SECURE_NO_WARNINGS;NOMINMAX;GL_APICALL=;GL_GLEXT_PROTOTYPES=;EGLAPI=;ANGLE_PRELOADED_D3DCOMPILER_MODULE_NAMES={ &quot;d3dcompiler_46.dll&quot;, &quot;d3dcompiler_43.dll&quot; };NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
       <RuntimeLibrary>MultiThreaded</RuntimeLibrary>
       <RuntimeTypeInfo>true</RuntimeTypeInfo>
       <TreatWarningAsError>true</TreatWarningAsError>
@@ -145,6 +146,7 @@
     </ClCompile>
     <Lib>
       <AdditionalLibraryDirectories>C:/Program Files (x86)/Windows Kits/8.0/Lib/win8/um/x86;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
+      <TargetMachine>MachineX86</TargetMachine>
     </Lib>
     <Link>
       <AdditionalDependencies>kernel32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;user32.lib;uuid.lib;odbc32.lib;odbccp32.lib;delayimp.lib;d3d9.lib;dxguid.lib</AdditionalDependencies>
@@ -159,14 +161,14 @@
       <TargetMachine>MachineX86</TargetMachine>
     </Link>
     <ResourceCompile>
-      <AdditionalIncludeDirectories>..\..\src;..\..\include;..\..\src\libGLESv2;$(OutDir)obj\global_intermediate\angle;C:\Program Files (x86)\Windows Kits\8.0\Include\shared;C:\Program Files (x86)\Windows Kits\8.0\Include\um;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <AdditionalIncludeDirectories>$(OutDir)obj\global_intermediate\angle;..\..\src;..\..\include;..\..\src\libGLESv2;C:\Program Files (x86)\Windows Kits\8.0\Include\shared;C:\Program Files (x86)\Windows Kits\8.0\Include\um;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
       <Culture>0x0409</Culture>
-      <PreprocessorDefinitions>GL_APICALL=;GL_GLEXT_PROTOTYPES=;EGLAPI=;ANGLE_PRELOADED_D3DCOMPILER_MODULE_NAMES={ &quot;d3dcompiler_46.dll&quot;, &quot;d3dcompiler_43.dll&quot; };ANGLE_ENABLE_D3D9;ANGLE_ENABLE_D3D11;NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <PreprocessorDefinitions>GL_APICALL=;GL_GLEXT_PROTOTYPES=;EGLAPI=;ANGLE_PRELOADED_D3DCOMPILER_MODULE_NAMES={ &quot;d3dcompiler_46.dll&quot;, &quot;d3dcompiler_43.dll&quot; };NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
     </ResourceCompile>
   </ItemDefinitionGroup>
   <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
     <ClCompile>
-      <AdditionalIncludeDirectories>..\..\src;..\..\include;..\..\src\libGLESv2;$(OutDir)obj\global_intermediate\angle;C:\Program Files (x86)\Windows Kits\8.0\Include\shared;C:\Program Files (x86)\Windows Kits\8.0\Include\um;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <AdditionalIncludeDirectories>$(OutDir)obj\global_intermediate\angle;..\..\src;..\..\include;..\..\src\libGLESv2;C:\Program Files (x86)\Windows Kits\8.0\Include\shared;C:\Program Files (x86)\Windows Kits\8.0\Include\um;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
       <AdditionalOptions>/MP %(AdditionalOptions)</AdditionalOptions>
       <BufferSecurityCheck>true</BufferSecurityCheck>
       <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
@@ -175,7 +177,7 @@
       <FunctionLevelLinking>true</FunctionLevelLinking>
       <MinimalRebuild>false</MinimalRebuild>
       <Optimization>MaxSpeed</Optimization>
-      <PreprocessorDefinitions>_CRT_SECURE_NO_DEPRECATE;_SCL_SECURE_NO_WARNINGS;NOMINMAX;GL_APICALL=;GL_GLEXT_PROTOTYPES=;EGLAPI=;ANGLE_PRELOADED_D3DCOMPILER_MODULE_NAMES={ &quot;d3dcompiler_46.dll&quot;, &quot;d3dcompiler_43.dll&quot; };ANGLE_ENABLE_D3D9;ANGLE_ENABLE_D3D11;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <PreprocessorDefinitions>_CRT_SECURE_NO_DEPRECATE;_SCL_SECURE_NO_WARNINGS;NOMINMAX;GL_APICALL=;GL_GLEXT_PROTOTYPES=;EGLAPI=;ANGLE_PRELOADED_D3DCOMPILER_MODULE_NAMES={ &quot;d3dcompiler_46.dll&quot;, &quot;d3dcompiler_43.dll&quot; };%(PreprocessorDefinitions)</PreprocessorDefinitions>
       <RuntimeLibrary>MultiThreaded</RuntimeLibrary>
       <RuntimeTypeInfo>true</RuntimeTypeInfo>
       <TreatWarningAsError>true</TreatWarningAsError>
@@ -197,302 +199,30 @@
       <TargetMachine>MachineX64</TargetMachine>
     </Link>
     <ResourceCompile>
-      <AdditionalIncludeDirectories>..\..\src;..\..\include;..\..\src\libGLESv2;$(OutDir)obj\global_intermediate\angle;C:\Program Files (x86)\Windows Kits\8.0\Include\shared;C:\Program Files (x86)\Windows Kits\8.0\Include\um;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <AdditionalIncludeDirectories>$(OutDir)obj\global_intermediate\angle;..\..\src;..\..\include;..\..\src\libGLESv2;C:\Program Files (x86)\Windows Kits\8.0\Include\shared;C:\Program Files (x86)\Windows Kits\8.0\Include\um;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
       <Culture>0x0409</Culture>
-      <PreprocessorDefinitions>GL_APICALL=;GL_GLEXT_PROTOTYPES=;EGLAPI=;ANGLE_PRELOADED_D3DCOMPILER_MODULE_NAMES={ &quot;d3dcompiler_46.dll&quot;, &quot;d3dcompiler_43.dll&quot; };ANGLE_ENABLE_D3D9;ANGLE_ENABLE_D3D11;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <PreprocessorDefinitions>GL_APICALL=;GL_GLEXT_PROTOTYPES=;EGLAPI=;ANGLE_PRELOADED_D3DCOMPILER_MODULE_NAMES={ &quot;d3dcompiler_46.dll&quot;, &quot;d3dcompiler_43.dll&quot; };%(PreprocessorDefinitions)</PreprocessorDefinitions>
     </ResourceCompile>
   </ItemDefinitionGroup>
   <ItemGroup>
     <None Include="..\..\src\angle.gyp"/>
     <None Include="..\..\src\libGLESv2\libGLESv2.def"/>
-    <None Include="..\..\src\libGLESv2\renderer\loadimage.inl"/>
-    <None Include="..\..\src\libGLESv2\renderer\generatemip.inl"/>
   </ItemGroup>
   <ItemGroup>
-    <ClInclude Include="..\..\src\libGLESv2\Shader.h"/>
-    <ClInclude Include="..\..\src\libGLESv2\BinaryStream.h"/>
-    <ClInclude Include="..\..\src\libGLESv2\resource.h"/>
-    <ClInclude Include="..\..\src\libGLESv2\Sampler.h"/>
-    <ClInclude Include="..\..\src\libGLESv2\Caps.h"/>
-    <ClInclude Include="..\..\src\libGLESv2\precompiled.h"/>
-    <ClInclude Include="..\..\src\libGLESv2\TransformFeedback.h"/>
-    <ClInclude Include="..\..\src\libGLESv2\Context.h"/>
-    <ClInclude Include="..\..\src\libGLESv2\Query.h"/>
-    <ClInclude Include="..\..\src\libGLESv2\Texture.h"/>
-    <ClInclude Include="..\..\src\libGLESv2\Uniform.h"/>
-    <ClInclude Include="..\..\src\libGLESv2\ProgramBinary.h"/>
-    <ClInclude Include="..\..\src\libGLESv2\constants.h"/>
-    <ClInclude Include="..\..\src\libGLESv2\FramebufferAttachment.h"/>
-    <ClInclude Include="..\..\src\libGLESv2\Renderbuffer.h"/>
-    <ClInclude Include="..\..\src\libGLESv2\queryconversions.h"/>
-    <ClInclude Include="..\..\src\libGLESv2\validationES3.h"/>
-    <ClInclude Include="..\..\src\libGLESv2\Program.h"/>
-    <ClInclude Include="..\..\src\libGLESv2\HandleAllocator.h"/>
-    <ClInclude Include="..\..\src\libGLESv2\ResourceManager.h"/>
-    <ClInclude Include="..\..\src\libGLESv2\DynamicHLSL.h"/>
-    <ClInclude Include="..\..\src\libGLESv2\VertexAttribute.h"/>
-    <ClInclude Include="..\..\src\libGLESv2\validationES2.h"/>
-    <ClInclude Include="..\..\src\libGLESv2\Fence.h"/>
-    <ClInclude Include="..\..\src\libGLESv2\angletypes.h"/>
-    <ClInclude Include="..\..\src\libGLESv2\main.h"/>
-    <ClInclude Include="..\..\src\libGLESv2\VertexArray.h"/>
-    <ClInclude Include="..\..\src\libGLESv2\Framebuffer.h"/>
-    <ClInclude Include="..\..\src\libGLESv2\formatutils.h"/>
-    <ClInclude Include="..\..\src\libGLESv2\Buffer.h"/>
-    <ClInclude Include="..\..\src\libGLESv2\State.h"/>
-    <ClInclude Include="..\..\src\libGLESv2\validationES.h"/>
-    <ClInclude Include="..\..\src\libGLESv2\renderer\TextureImpl.h"/>
-    <ClInclude Include="..\..\src\libGLESv2\renderer\Renderer.h"/>
-    <ClInclude Include="..\..\src\libGLESv2\renderer\ShaderExecutable.h"/>
-    <ClInclude Include="..\..\src\libGLESv2\renderer\loadimage.h"/>
-    <ClInclude Include="..\..\src\libGLESv2\renderer\copyimage.h"/>
-    <ClInclude Include="..\..\src\libGLESv2\renderer\BufferImpl.h"/>
-    <ClInclude Include="..\..\src\libGLESv2\renderer\copyvertex.h"/>
-    <ClInclude Include="..\..\src\libGLESv2\renderer\SwapChain.h"/>
-    <ClInclude Include="..\..\src\libGLESv2\renderer\imageformats.h"/>
-    <ClInclude Include="..\..\src\libGLESv2\renderer\QueryImpl.h"/>
-    <ClInclude Include="..\..\src\libGLESv2\renderer\IndexRangeCache.h"/>
-    <ClInclude Include="..\..\src\libGLESv2\renderer\FenceImpl.h"/>
-    <ClInclude Include="..\..\src\libGLESv2\renderer\Image.h"/>
-    <ClInclude Include="..\..\src\libGLESv2\renderer\generatemip.h"/>
-    <ClInclude Include="..\..\src\libGLESv2\renderer\RenderTarget.h"/>
-    <ClInclude Include="..\..\src\libGLESv2\renderer\vertexconversion.h"/>
-    <ClInclude Include="..\..\src\libGLESv2\renderer\VertexArrayImpl.h"/>
-    <ClInclude Include="..\..\src\libGLESv2\renderer\d3d\IndexBuffer.h"/>
-    <ClInclude Include="..\..\src\libGLESv2\renderer\d3d\HLSLCompiler.h"/>
-    <ClInclude Include="..\..\src\libGLESv2\renderer\d3d\ImageD3D.h"/>
-    <ClInclude Include="..\..\src\libGLESv2\renderer\d3d\MemoryBuffer.h"/>
-    <ClInclude Include="..\..\src\libGLESv2\renderer\d3d\TextureD3D.h"/>
-    <ClInclude Include="..\..\src\libGLESv2\renderer\d3d\TextureStorage.h"/>
-    <ClInclude Include="..\..\src\libGLESv2\renderer\d3d\IndexDataManager.h"/>
-    <ClInclude Include="..\..\src\libGLESv2\renderer\d3d\VertexBuffer.h"/>
-    <ClInclude Include="..\..\src\libGLESv2\renderer\d3d\BufferD3D.h"/>
-    <ClInclude Include="..\..\src\libGLESv2\renderer\d3d\VertexDataManager.h"/>
-    <ClInclude Include="..\..\src\libGLESv2\renderer\d3d\d3d11\Clear11.h"/>
-    <ClInclude Include="..\..\src\libGLESv2\renderer\d3d\d3d11\RenderStateCache.h"/>
-    <ClInclude Include="..\..\src\libGLESv2\renderer\d3d\d3d11\ShaderExecutable11.h"/>
-    <ClInclude Include="..\..\src\libGLESv2\renderer\d3d\d3d11\IndexBuffer11.h"/>
-    <ClInclude Include="..\..\src\libGLESv2\renderer\d3d\d3d11\Query11.h"/>
-    <ClInclude Include="..\..\src\libGLESv2\renderer\d3d\d3d11\Buffer11.h"/>
-    <ClInclude Include="..\..\src\libGLESv2\renderer\d3d\d3d11\VertexBuffer11.h"/>
-    <ClInclude Include="..\..\src\libGLESv2\renderer\d3d\d3d11\TextureStorage11.h"/>
-    <ClInclude Include="..\..\src\libGLESv2\renderer\d3d\d3d11\Blit11.h"/>
-    <ClInclude Include="..\..\src\libGLESv2\renderer\d3d\d3d11\Image11.h"/>
-    <ClInclude Include="..\..\src\libGLESv2\renderer\d3d\d3d11\RenderTarget11.h"/>
-    <ClInclude Include="..\..\src\libGLESv2\renderer\d3d\d3d11\InputLayoutCache.h"/>
-    <ClInclude Include="..\..\src\libGLESv2\renderer\d3d\d3d11\SwapChain11.h"/>
-    <ClInclude Include="..\..\src\libGLESv2\renderer\d3d\d3d11\Fence11.h"/>
-    <ClInclude Include="..\..\src\libGLESv2\renderer\d3d\d3d11\VertexArray11.h"/>
-    <ClInclude Include="..\..\src\libGLESv2\renderer\d3d\d3d11\renderer11_utils.h"/>
-    <ClInclude Include="..\..\src\libGLESv2\renderer\d3d\d3d11\Renderer11.h"/>
-    <ClInclude Include="..\..\src\libGLESv2\renderer\d3d\d3d11\PixelTransfer11.h"/>
-    <ClInclude Include="..\..\src\libGLESv2\renderer\d3d\d3d11\formatutils11.h"/>
-    <ClInclude Include="..\..\src\libGLESv2\renderer\d3d\d3d11\shaders\compiled\swizzleui2dps.h"/>
-    <ClInclude Include="..\..\src\libGLESv2\renderer\d3d\d3d11\shaders\compiled\passthroughr2d11ps.h"/>
-    <ClInclude Include="..\..\src\libGLESv2\renderer\d3d\d3d11\shaders\compiled\passthroughr3dui11ps.h"/>
-    <ClInclude Include="..\..\src\libGLESv2\renderer\d3d\d3d11\shaders\compiled\swizzlef3dps.h"/>
-    <ClInclude Include="..\..\src\libGLESv2\renderer\d3d\d3d11\shaders\compiled\clearfloat11ps.h"/>
-    <ClInclude Include="..\..\src\libGLESv2\renderer\d3d\d3d11\shaders\compiled\passthroughlumalpha2d11ps.h"/>
-    <ClInclude Include="..\..\src\libGLESv2\renderer\d3d\d3d11\shaders\compiled\passthroughrg2dui11ps.h"/>
-    <ClInclude Include="..\..\src\libGLESv2\renderer\d3d\d3d11\shaders\compiled\passthroughrgb3d11ps.h"/>
-    <ClInclude Include="..\..\src\libGLESv2\renderer\d3d\d3d11\shaders\compiled\passthroughrgb2di11ps.h"/>
-    <ClInclude Include="..\..\src\libGLESv2\renderer\d3d\d3d11\shaders\compiled\swizzleui3dps.h"/>
-    <ClInclude Include="..\..\src\libGLESv2\renderer\d3d\d3d11\shaders\compiled\clearsint11ps.h"/>
-    <ClInclude Include="..\..\src\libGLESv2\renderer\d3d\d3d11\shaders\compiled\swizzlef2dps.h"/>
-    <ClInclude Include="..\..\src\libGLESv2\renderer\d3d\d3d11\shaders\compiled\passthroughrg3di11ps.h"/>
-    <ClInclude Include="..\..\src\libGLESv2\renderer\d3d\d3d11\shaders\compiled\swizzlei2darrayps.h"/>
-    <ClInclude Include="..\..\src\libGLESv2\renderer\d3d\d3d11\shaders\compiled\passthroughlumalpha3d11ps.h"/>
-    <ClInclude Include="..\..\src\libGLESv2\renderer\d3d\d3d11\shaders\compiled\passthroughrgba3di11ps.h"/>
-    <ClInclude Include="..\..\src\libGLESv2\renderer\d3d\d3d11\shaders\compiled\passthroughrgb2d11ps.h"/>
-    <ClInclude Include="..\..\src\libGLESv2\renderer\d3d\d3d11\shaders\compiled\clearsint11vs.h"/>
-    <ClInclude Include="..\..\src\libGLESv2\renderer\d3d\d3d11\shaders\compiled\passthrough2d11vs.h"/>
-    <ClInclude Include="..\..\src\libGLESv2\renderer\d3d\d3d11\shaders\compiled\buffertotexture11_ps_4f.h"/>
-    <ClInclude Include="..\..\src\libGLESv2\renderer\d3d\d3d11\shaders\compiled\buffertotexture11_gs.h"/>
-    <ClInclude Include="..\..\src\libGLESv2\renderer\d3d\d3d11\shaders\compiled\clearfloat11vs.h"/>
-    <ClInclude Include="..\..\src\libGLESv2\renderer\d3d\d3d11\shaders\compiled\passthroughrgba2di11ps.h"/>
-    <ClInclude Include="..\..\src\libGLESv2\renderer\d3d\d3d11\shaders\compiled\passthroughr2dui11ps.h"/>
-    <ClInclude Include="..\..\src\libGLESv2\renderer\d3d\d3d11\shaders\compiled\buffertotexture11_ps_4i.h"/>
-    <ClInclude Include="..\..\src\libGLESv2\renderer\d3d\d3d11\shaders\compiled\passthroughrg3dui11ps.h"/>
-    <ClInclude Include="..\..\src\libGLESv2\renderer\d3d\d3d11\shaders\compiled\swizzlei2dps.h"/>
-    <ClInclude Include="..\..\src\libGLESv2\renderer\d3d\d3d11\shaders\compiled\passthroughrg2d11ps.h"/>
-    <ClInclude Include="..\..\src\libGLESv2\renderer\d3d\d3d11\shaders\compiled\passthroughrgba2dui11ps.h"/>
-    <ClInclude Include="..\..\src\libGLESv2\renderer\d3d\d3d11\shaders\compiled\passthroughrgb3dui11ps.h"/>
-    <ClInclude Include="..\..\src\libGLESv2\renderer\d3d\d3d11\shaders\compiled\passthroughr2di11ps.h"/>
-    <ClInclude Include="..\..\src\libGLESv2\renderer\d3d\d3d11\shaders\compiled\passthroughrgba3d11ps.h"/>
-    <ClInclude Include="..\..\src\libGLESv2\renderer\d3d\d3d11\shaders\compiled\passthroughlum3d11ps.h"/>
-    <ClInclude Include="..\..\src\libGLESv2\renderer\d3d\d3d11\shaders\compiled\clearuint11vs.h"/>
-    <ClInclude Include="..\..\src\libGLESv2\renderer\d3d\d3d11\shaders\compiled\passthroughr3d11ps.h"/>
-    <ClInclude Include="..\..\src\libGLESv2\renderer\d3d\d3d11\shaders\compiled\passthroughrg2di11ps.h"/>
-    <ClInclude Include="..\..\src\libGLESv2\renderer\d3d\d3d11\shaders\compiled\clearuint11ps.h"/>
-    <ClInclude Include="..\..\src\libGLESv2\renderer\d3d\d3d11\shaders\compiled\passthrough3d11vs.h"/>
-    <ClInclude Include="..\..\src\libGLESv2\renderer\d3d\d3d11\shaders\compiled\passthroughdepth2d11ps.h"/>
-    <ClInclude Include="..\..\src\libGLESv2\renderer\d3d\d3d11\shaders\compiled\passthroughlum2d11ps.h"/>
-    <ClInclude Include="..\..\src\libGLESv2\renderer\d3d\d3d11\shaders\compiled\passthroughrgb2dui11ps.h"/>
-    <ClInclude Include="..\..\src\libGLESv2\renderer\d3d\d3d11\shaders\compiled\swizzlei3dps.h"/>
-    <ClInclude Include="..\..\src\libGLESv2\renderer\d3d\d3d11\shaders\compiled\swizzlef2darrayps.h"/>
-    <ClInclude Include="..\..\src\libGLESv2\renderer\d3d\d3d11\shaders\compiled\buffertotexture11_vs.h"/>
-    <ClInclude Include="..\..\src\libGLESv2\renderer\d3d\d3d11\shaders\compiled\passthroughrgb3di11ps.h"/>
-    <ClInclude Include="..\..\src\libGLESv2\renderer\d3d\d3d11\shaders\compiled\passthroughrg3d11ps.h"/>
-    <ClInclude Include="..\..\src\libGLESv2\renderer\d3d\d3d11\shaders\compiled\passthroughrgba2d11ps.h"/>
-    <ClInclude Include="..\..\src\libGLESv2\renderer\d3d\d3d11\shaders\compiled\swizzleui2darrayps.h"/>
-    <ClInclude Include="..\..\src\libGLESv2\renderer\d3d\d3d11\shaders\compiled\passthroughrgba3dui11ps.h"/>
-    <ClInclude Include="..\..\src\libGLESv2\renderer\d3d\d3d11\shaders\compiled\buffertotexture11_ps_4ui.h"/>
-    <ClInclude Include="..\..\src\libGLESv2\renderer\d3d\d3d11\shaders\compiled\passthroughr3di11ps.h"/>
-    <ClInclude Include="..\..\src\libGLESv2\renderer\d3d\d3d11\shaders\compiled\passthrough3d11gs.h"/>
-    <ClInclude Include="..\..\src\libGLESv2\renderer\d3d\d3d9\renderer9_utils.h"/>
-    <ClInclude Include="..\..\src\libGLESv2\renderer\d3d\d3d9\TextureStorage9.h"/>
-    <ClInclude Include="..\..\src\libGLESv2\renderer\d3d\d3d9\IndexBuffer9.h"/>
-    <ClInclude Include="..\..\src\libGLESv2\renderer\d3d\d3d9\ShaderCache.h"/>
-    <ClInclude Include="..\..\src\libGLESv2\renderer\d3d\d3d9\Fence9.h"/>
-    <ClInclude Include="..\..\src\libGLESv2\renderer\d3d\d3d9\VertexArray9.h"/>
-    <ClInclude Include="..\..\src\libGLESv2\renderer\d3d\d3d9\Renderer9.h"/>
-    <ClInclude Include="..\..\src\libGLESv2\renderer\d3d\d3d9\Blit9.h"/>
-    <ClInclude Include="..\..\src\libGLESv2\renderer\d3d\d3d9\VertexDeclarationCache.h"/>
-    <ClInclude Include="..\..\src\libGLESv2\renderer\d3d\d3d9\Image9.h"/>
-    <ClInclude Include="..\..\src\libGLESv2\renderer\d3d\d3d9\VertexBuffer9.h"/>
-    <ClInclude Include="..\..\src\libGLESv2\renderer\d3d\d3d9\formatutils9.h"/>
-    <ClInclude Include="..\..\src\libGLESv2\renderer\d3d\d3d9\Query9.h"/>
-    <ClInclude Include="..\..\src\libGLESv2\renderer\d3d\d3d9\RenderTarget9.h"/>
-    <ClInclude Include="..\..\src\libGLESv2\renderer\d3d\d3d9\SwapChain9.h"/>
-    <ClInclude Include="..\..\src\libGLESv2\renderer\d3d\d3d9\Buffer9.h"/>
-    <ClInclude Include="..\..\src\libGLESv2\renderer\d3d\d3d9\shaders\compiled\standardvs.h"/>
-    <ClInclude Include="..\..\src\libGLESv2\renderer\d3d\d3d9\shaders\compiled\luminanceps.h"/>
-    <ClInclude Include="..\..\src\libGLESv2\renderer\d3d\d3d9\shaders\compiled\componentmaskps.h"/>
-    <ClInclude Include="..\..\src\libGLESv2\renderer\d3d\d3d9\shaders\compiled\passthroughps.h"/>
-    <ClInclude Include="..\..\src\libGLESv2\renderer\d3d\d3d9\shaders\compiled\flipyvs.h"/>
-    <ClInclude Include="..\..\src\common\tls.h"/>
-    <ClInclude Include="..\..\src\common\mathutil.h"/>
-    <ClInclude Include="..\..\src\common\blocklayout.h"/>
-    <ClInclude Include="..\..\src\common\debug.h"/>
-    <ClInclude Include="..\..\src\common\utilities.h"/>
-    <ClInclude Include="..\..\src\common\RefCountObject.h"/>
-    <ClInclude Include="..\..\src\common\event_tracer.h"/>
-    <ClInclude Include="..\..\src\common\angleutils.h"/>
-    <ClInclude Include="..\..\src\common\platform.h"/>
-    <ClInclude Include="..\..\src\common\version.h"/>
-    <ClInclude Include="..\..\src\third_party\systeminfo\SystemInfo.h"/>
-    <ClInclude Include="..\..\src\third_party\murmurhash\MurmurHash3.h"/>
-    <ClInclude Include="..\..\include\angle_gl.h"/>
-    <ClInclude Include="..\..\include\KHR\khrplatform.h"/>
-    <ClInclude Include="..\..\include\GLSLANG\ShaderLang.h"/>
-    <ClInclude Include="..\..\include\GLSLANG\ShaderVars.h"/>
-    <ClInclude Include="..\..\include\GLES2\gl2ext.h"/>
-    <ClInclude Include="..\..\include\GLES2\gl2.h"/>
-    <ClInclude Include="..\..\include\GLES2\gl2platform.h"/>
-    <ClInclude Include="..\..\include\GLES3\gl3ext.h"/>
-    <ClInclude Include="..\..\include\GLES3\gl3.h"/>
-    <ClInclude Include="..\..\include\GLES3\gl3platform.h"/>
-    <ClInclude Include="..\..\include\EGL\eglext.h"/>
-    <ClInclude Include="..\..\include\EGL\egl.h"/>
-    <ClInclude Include="..\..\include\EGL\eglplatform.h"/>
-  </ItemGroup>
-  <ItemGroup>
-    <ClCompile Include="..\..\src\libGLESv2\validationES2.cpp"/>
-    <ClCompile Include="..\..\src\libGLESv2\precompiled.cpp"/>
-    <ClCompile Include="..\..\src\libGLESv2\DynamicHLSL.cpp"/>
-    <ClCompile Include="..\..\src\libGLESv2\HandleAllocator.cpp"/>
-    <ClCompile Include="..\..\src\libGLESv2\queryconversions.cpp"/>
-    <ClCompile Include="..\..\src\libGLESv2\formatutils.cpp"/>
-    <ClCompile Include="..\..\src\libGLESv2\Fence.cpp"/>
-    <ClCompile Include="..\..\src\libGLESv2\validationES.cpp"/>
-    <ClCompile Include="..\..\src\libGLESv2\Renderbuffer.cpp"/>
-    <ClCompile Include="..\..\src\libGLESv2\Program.cpp"/>
-    <ClCompile Include="..\..\src\libGLESv2\ResourceManager.cpp"/>
-    <ClCompile Include="..\..\src\libGLESv2\angletypes.cpp"/>
-    <ClCompile Include="..\..\src\libGLESv2\Float16ToFloat32.cpp"/>
-    <ClCompile Include="..\..\src\libGLESv2\validationES3.cpp"/>
-    <ClCompile Include="..\..\src\libGLESv2\FramebufferAttachment.cpp"/>
-    <ClCompile Include="..\..\src\libGLESv2\Query.cpp"/>
-    <ClCompile Include="..\..\src\libGLESv2\TransformFeedback.cpp"/>
     <ClCompile Include="..\..\src\libGLESv2\libGLESv2.cpp"/>
-    <ClCompile Include="..\..\src\libGLESv2\State.cpp"/>
-    <ClCompile Include="..\..\src\libGLESv2\ProgramBinary.cpp"/>
-    <ClCompile Include="..\..\src\libGLESv2\VertexAttribute.cpp"/>
-    <ClCompile Include="..\..\src\libGLESv2\Caps.cpp"/>
-    <ClCompile Include="..\..\src\libGLESv2\Context.cpp"/>
-    <ClCompile Include="..\..\src\libGLESv2\Buffer.cpp"/>
-    <ClCompile Include="..\..\src\libGLESv2\VertexArray.cpp"/>
-    <ClCompile Include="..\..\src\libGLESv2\Shader.cpp"/>
-    <ClCompile Include="..\..\src\libGLESv2\Uniform.cpp"/>
-    <ClCompile Include="..\..\src\libGLESv2\main.cpp"/>
-    <ClCompile Include="..\..\src\libGLESv2\Sampler.cpp"/>
-    <ClCompile Include="..\..\src\libGLESv2\Framebuffer.cpp"/>
-    <ClCompile Include="..\..\src\libGLESv2\Texture.cpp"/>
-    <ClCompile Include="..\..\src\libGLESv2\renderer\copyimage.cpp"/>
-    <ClCompile Include="..\..\src\libGLESv2\renderer\loadimage.cpp"/>
-    <ClCompile Include="..\..\src\libGLESv2\renderer\loadimageSSE2.cpp"/>
-    <ClCompile Include="..\..\src\libGLESv2\renderer\Image.cpp"/>
-    <ClCompile Include="..\..\src\libGLESv2\renderer\Renderer.cpp"/>
-    <ClCompile Include="..\..\src\libGLESv2\renderer\IndexRangeCache.cpp"/>
-    <ClCompile Include="..\..\src\libGLESv2\renderer\d3d\HLSLCompiler.cpp"/>
-    <ClCompile Include="..\..\src\libGLESv2\renderer\d3d\BufferD3D.cpp"/>
-    <ClCompile Include="..\..\src\libGLESv2\renderer\d3d\IndexBuffer.cpp"/>
-    <ClCompile Include="..\..\src\libGLESv2\renderer\d3d\VertexBuffer.cpp"/>
-    <ClCompile Include="..\..\src\libGLESv2\renderer\d3d\TextureD3D.cpp"/>
-    <ClCompile Include="..\..\src\libGLESv2\renderer\d3d\VertexDataManager.cpp"/>
-    <ClCompile Include="..\..\src\libGLESv2\renderer\d3d\MemoryBuffer.cpp"/>
-    <ClCompile Include="..\..\src\libGLESv2\renderer\d3d\ImageD3D.cpp"/>
-    <ClCompile Include="..\..\src\libGLESv2\renderer\d3d\TextureStorage.cpp"/>
-    <ClCompile Include="..\..\src\libGLESv2\renderer\d3d\IndexDataManager.cpp"/>
-    <ClCompile Include="..\..\src\libGLESv2\renderer\d3d\d3d11\Renderer11.cpp"/>
-    <ClCompile Include="..\..\src\libGLESv2\renderer\d3d\d3d11\InputLayoutCache.cpp"/>
-    <ClCompile Include="..\..\src\libGLESv2\renderer\d3d\d3d11\PixelTransfer11.cpp"/>
-    <ClCompile Include="..\..\src\libGLESv2\renderer\d3d\d3d11\VertexBuffer11.cpp"/>
-    <ClCompile Include="..\..\src\libGLESv2\renderer\d3d\d3d11\Query11.cpp"/>
-    <ClCompile Include="..\..\src\libGLESv2\renderer\d3d\d3d11\ShaderExecutable11.cpp"/>
-    <ClCompile Include="..\..\src\libGLESv2\renderer\d3d\d3d11\Blit11.cpp"/>
-    <ClCompile Include="..\..\src\libGLESv2\renderer\d3d\d3d11\RenderStateCache.cpp"/>
-    <ClCompile Include="..\..\src\libGLESv2\renderer\d3d\d3d11\IndexBuffer11.cpp"/>
-    <ClCompile Include="..\..\src\libGLESv2\renderer\d3d\d3d11\formatutils11.cpp"/>
-    <ClCompile Include="..\..\src\libGLESv2\renderer\d3d\d3d11\SwapChain11.cpp"/>
-    <ClCompile Include="..\..\src\libGLESv2\renderer\d3d\d3d11\renderer11_utils.cpp"/>
-    <ClCompile Include="..\..\src\libGLESv2\renderer\d3d\d3d11\Image11.cpp"/>
-    <ClCompile Include="..\..\src\libGLESv2\renderer\d3d\d3d11\TextureStorage11.cpp"/>
-    <ClCompile Include="..\..\src\libGLESv2\renderer\d3d\d3d11\Buffer11.cpp"/>
-    <ClCompile Include="..\..\src\libGLESv2\renderer\d3d\d3d11\RenderTarget11.cpp"/>
-    <ClCompile Include="..\..\src\libGLESv2\renderer\d3d\d3d11\Fence11.cpp"/>
-    <ClCompile Include="..\..\src\libGLESv2\renderer\d3d\d3d11\Clear11.cpp"/>
-    <ClCompile Include="..\..\src\libGLESv2\renderer\d3d\d3d9\VertexDeclarationCache.cpp"/>
-    <ClCompile Include="..\..\src\libGLESv2\renderer\d3d\d3d9\Query9.cpp"/>
-    <ClCompile Include="..\..\src\libGLESv2\renderer\d3d\d3d9\VertexBuffer9.cpp"/>
-    <ClCompile Include="..\..\src\libGLESv2\renderer\d3d\d3d9\Fence9.cpp"/>
-    <ClCompile Include="..\..\src\libGLESv2\renderer\d3d\d3d9\Image9.cpp"/>
-    <ClCompile Include="..\..\src\libGLESv2\renderer\d3d\d3d9\renderer9_utils.cpp"/>
-    <ClCompile Include="..\..\src\libGLESv2\renderer\d3d\d3d9\TextureStorage9.cpp"/>
-    <ClCompile Include="..\..\src\libGLESv2\renderer\d3d\d3d9\Renderer9.cpp"/>
-    <ClCompile Include="..\..\src\libGLESv2\renderer\d3d\d3d9\RenderTarget9.cpp"/>
-    <ClCompile Include="..\..\src\libGLESv2\renderer\d3d\d3d9\formatutils9.cpp"/>
-    <ClCompile Include="..\..\src\libGLESv2\renderer\d3d\d3d9\Buffer9.cpp"/>
-    <ClCompile Include="..\..\src\libGLESv2\renderer\d3d\d3d9\ShaderExecutable9.cpp"/>
-    <ClCompile Include="..\..\src\libGLESv2\renderer\d3d\d3d9\SwapChain9.cpp"/>
-    <ClCompile Include="..\..\src\libGLESv2\renderer\d3d\d3d9\Blit9.cpp"/>
-    <ClCompile Include="..\..\src\libGLESv2\renderer\d3d\d3d9\IndexBuffer9.cpp"/>
-    <ClCompile Include="..\..\src\common\event_tracer.cpp"/>
-    <ClCompile Include="..\..\src\common\RefCountObject.cpp"/>
-    <ClCompile Include="..\..\src\common\tls.cpp"/>
-    <ClCompile Include="..\..\src\common\utilities.cpp"/>
-    <ClCompile Include="..\..\src\common\mathutil.cpp"/>
-    <ClCompile Include="..\..\src\common\debug.cpp"/>
-    <ClCompile Include="..\..\src\common\blocklayout.cpp"/>
-    <ClCompile Include="..\..\src\third_party\systeminfo\SystemInfo.cpp"/>
-    <ClCompile Include="..\..\src\third_party\murmurhash\MurmurHash3.cpp"/>
   </ItemGroup>
   <ItemGroup>
     <ResourceCompile Include="..\..\src\libGLESv2\libGLESv2.rc"/>
   </ItemGroup>
   <ItemGroup>
+    <ProjectReference Include="libANGLE.vcxproj">
+      <Project>{CAAA04EE-A56A-43FB-D011-1A56053C070C}</Project>
+      <ReferenceOutputAssembly>false</ReferenceOutputAssembly>
+    </ProjectReference>
     <ProjectReference Include="translator.vcxproj">
       <Project>{C15697F6-5057-016E-BD29-422971875679}</Project>
       <ReferenceOutputAssembly>false</ReferenceOutputAssembly>
     </ProjectReference>
-    <ProjectReference Include="commit_id.vcxproj">
-      <Project>{3B7F5656-177F-52EE-26B3-D6A75368D0A9}</Project>
-      <ReferenceOutputAssembly>false</ReferenceOutputAssembly>
-    </ProjectReference>
-    <ProjectReference Include="copy_compiler_dll.vcxproj">
-      <Project>{22DC02D5-1598-943C-13E1-82185B469F81}</Project>
-      <ReferenceOutputAssembly>false</ReferenceOutputAssembly>
-    </ProjectReference>
     <ProjectReference Include="translator_lib.vcxproj">
       <Project>{276D20F5-2943-414C-0FF6-21F4723A5CF6}</Project>
       <ReferenceOutputAssembly>false</ReferenceOutputAssembly>
@@ -501,6 +231,14 @@
       <Project>{C7BAF548-697D-2DCB-9DF3-9D1506A7B444}</Project>
       <ReferenceOutputAssembly>false</ReferenceOutputAssembly>
     </ProjectReference>
+    <ProjectReference Include="commit_id.vcxproj">
+      <Project>{3B7F5656-177F-52EE-26B3-D6A75368D0A9}</Project>
+      <ReferenceOutputAssembly>false</ReferenceOutputAssembly>
+    </ProjectReference>
+    <ProjectReference Include="copy_compiler_dll.vcxproj">
+      <Project>{22DC02D5-1598-943C-13E1-82185B469F81}</Project>
+      <ReferenceOutputAssembly>false</ReferenceOutputAssembly>
+    </ProjectReference>
     <ProjectReference Include="copy_scripts.vcxproj">
       <Project>{63FB0B97-D1D9-5158-8E85-7F5B1E403817}</Project>
       <ReferenceOutputAssembly>false</ReferenceOutputAssembly>
diff --git a/projects/src/libGLESv2.vcxproj.filters b/projects/src/libGLESv2.vcxproj.filters
index 6ec68bd..6707221 100644
--- a/projects/src/libGLESv2.vcxproj.filters
+++ b/projects/src/libGLESv2.vcxproj.filters
@@ -1,877 +1,20 @@
 <?xml version="1.0" encoding="utf-8"?>
 <Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
   <ItemGroup>
-    <Filter Include="src">
-      <UniqueIdentifier>{8CDEE807-BC53-E450-C8B8-4DEBB66742D4}</UniqueIdentifier>
-    </Filter>
-    <Filter Include="src\libGLESv2">
+    <Filter Include="libGLESv2">
       <UniqueIdentifier>{A62A9415-2E9D-A6D2-631D-1F25A5CD626F}</UniqueIdentifier>
     </Filter>
-    <Filter Include="src\libGLESv2\renderer">
-      <UniqueIdentifier>{AC4EF684-2900-10EA-3D11-A6DF0901358C}</UniqueIdentifier>
-    </Filter>
-    <Filter Include="src\libGLESv2\renderer\d3d">
-      <UniqueIdentifier>{3AC19AE3-A12C-4021-D645-4CEA5BC956DB}</UniqueIdentifier>
-    </Filter>
-    <Filter Include="src\libGLESv2\renderer\d3d\d3d11">
-      <UniqueIdentifier>{10FB1414-88D2-B512-6D76-522749905268}</UniqueIdentifier>
-    </Filter>
-    <Filter Include="src\libGLESv2\renderer\d3d\d3d11\shaders">
-      <UniqueIdentifier>{467D5622-06CC-2CF1-19E5-3CDD46A4008C}</UniqueIdentifier>
-    </Filter>
-    <Filter Include="src\libGLESv2\renderer\d3d\d3d11\shaders\compiled">
-      <UniqueIdentifier>{F444E9E6-7D51-0546-F1E4-B6C8FCDA5FC6}</UniqueIdentifier>
-    </Filter>
-    <Filter Include="src\libGLESv2\renderer\d3d\d3d9">
-      <UniqueIdentifier>{8BB193D2-4A8B-A094-A81E-D5E262AB1F92}</UniqueIdentifier>
-    </Filter>
-    <Filter Include="src\libGLESv2\renderer\d3d\d3d9\shaders">
-      <UniqueIdentifier>{467D5622-06CC-2CF1-19E5-3CDD46A4008C}</UniqueIdentifier>
-    </Filter>
-    <Filter Include="src\libGLESv2\renderer\d3d\d3d9\shaders\compiled">
-      <UniqueIdentifier>{F444E9E6-7D51-0546-F1E4-B6C8FCDA5FC6}</UniqueIdentifier>
-    </Filter>
-    <Filter Include="src\common">
-      <UniqueIdentifier>{2F5FD094-EF52-77F7-7AA8-4327A01BF747}</UniqueIdentifier>
-    </Filter>
-    <Filter Include="src\third_party">
-      <UniqueIdentifier>{D6C6CEA7-AAD0-03AD-2394-AC6FCBF8A498}</UniqueIdentifier>
-    </Filter>
-    <Filter Include="src\third_party\systeminfo">
-      <UniqueIdentifier>{8E42519F-DD71-5875-38CA-0ED32E34DB55}</UniqueIdentifier>
-    </Filter>
-    <Filter Include="src\third_party\murmurhash">
-      <UniqueIdentifier>{FBF5769C-D63C-9100-0719-0B97CE76B013}</UniqueIdentifier>
-    </Filter>
-    <Filter Include="include">
-      <UniqueIdentifier>{57CA55B8-BCC5-4000-CE3A-58972F82E9CB}</UniqueIdentifier>
-    </Filter>
-    <Filter Include="include\KHR">
-      <UniqueIdentifier>{6D4588DE-6319-FB13-135F-FA88843373FC}</UniqueIdentifier>
-    </Filter>
-    <Filter Include="include\GLSLANG">
-      <UniqueIdentifier>{AD7D3D9B-E716-B150-1F3A-64569B7F5415}</UniqueIdentifier>
-    </Filter>
-    <Filter Include="include\GLES2">
-      <UniqueIdentifier>{3FFE2AF8-8DA3-57BA-8037-4BE936BC5045}</UniqueIdentifier>
-    </Filter>
-    <Filter Include="include\GLES3">
-      <UniqueIdentifier>{E18FF71E-3DE4-F6D0-36B6-93BA54EEDEE1}</UniqueIdentifier>
-    </Filter>
-    <Filter Include="include\EGL">
-      <UniqueIdentifier>{79AE79DD-7922-70CC-3439-C9B3586338EF}</UniqueIdentifier>
-    </Filter>
   </ItemGroup>
   <ItemGroup>
-    <None Include="..\..\src\angle.gyp">
-      <Filter>src</Filter>
-    </None>
-    <ClInclude Include="..\..\src\libGLESv2\Shader.h">
-      <Filter>src\libGLESv2</Filter>
-    </ClInclude>
-    <ClCompile Include="..\..\src\libGLESv2\validationES2.cpp">
-      <Filter>src\libGLESv2</Filter>
-    </ClCompile>
-    <ClInclude Include="..\..\src\libGLESv2\BinaryStream.h">
-      <Filter>src\libGLESv2</Filter>
-    </ClInclude>
-    <ClInclude Include="..\..\src\libGLESv2\resource.h">
-      <Filter>src\libGLESv2</Filter>
-    </ClInclude>
-    <ClCompile Include="..\..\src\libGLESv2\precompiled.cpp">
-      <Filter>src\libGLESv2</Filter>
-    </ClCompile>
-    <ClCompile Include="..\..\src\libGLESv2\DynamicHLSL.cpp">
-      <Filter>src\libGLESv2</Filter>
-    </ClCompile>
-    <ClInclude Include="..\..\src\libGLESv2\Sampler.h">
-      <Filter>src\libGLESv2</Filter>
-    </ClInclude>
-    <ClInclude Include="..\..\src\libGLESv2\Caps.h">
-      <Filter>src\libGLESv2</Filter>
-    </ClInclude>
-    <ClCompile Include="..\..\src\libGLESv2\HandleAllocator.cpp">
-      <Filter>src\libGLESv2</Filter>
-    </ClCompile>
-    <ClCompile Include="..\..\src\libGLESv2\queryconversions.cpp">
-      <Filter>src\libGLESv2</Filter>
-    </ClCompile>
-    <ClInclude Include="..\..\src\libGLESv2\precompiled.h">
-      <Filter>src\libGLESv2</Filter>
-    </ClInclude>
-    <ClInclude Include="..\..\src\libGLESv2\TransformFeedback.h">
-      <Filter>src\libGLESv2</Filter>
-    </ClInclude>
-    <ClInclude Include="..\..\src\libGLESv2\Context.h">
-      <Filter>src\libGLESv2</Filter>
-    </ClInclude>
-    <ClInclude Include="..\..\src\libGLESv2\Query.h">
-      <Filter>src\libGLESv2</Filter>
-    </ClInclude>
-    <ClCompile Include="..\..\src\libGLESv2\formatutils.cpp">
-      <Filter>src\libGLESv2</Filter>
-    </ClCompile>
-    <ClCompile Include="..\..\src\libGLESv2\Fence.cpp">
-      <Filter>src\libGLESv2</Filter>
-    </ClCompile>
-    <ClInclude Include="..\..\src\libGLESv2\Texture.h">
-      <Filter>src\libGLESv2</Filter>
-    </ClInclude>
-    <ClCompile Include="..\..\src\libGLESv2\validationES.cpp">
-      <Filter>src\libGLESv2</Filter>
-    </ClCompile>
-    <ClCompile Include="..\..\src\libGLESv2\Renderbuffer.cpp">
-      <Filter>src\libGLESv2</Filter>
-    </ClCompile>
-    <ClInclude Include="..\..\src\libGLESv2\Uniform.h">
-      <Filter>src\libGLESv2</Filter>
-    </ClInclude>
-    <ClCompile Include="..\..\src\libGLESv2\Program.cpp">
-      <Filter>src\libGLESv2</Filter>
-    </ClCompile>
-    <ClCompile Include="..\..\src\libGLESv2\ResourceManager.cpp">
-      <Filter>src\libGLESv2</Filter>
-    </ClCompile>
-    <ClCompile Include="..\..\src\libGLESv2\angletypes.cpp">
-      <Filter>src\libGLESv2</Filter>
-    </ClCompile>
-    <ClCompile Include="..\..\src\libGLESv2\Float16ToFloat32.cpp">
-      <Filter>src\libGLESv2</Filter>
-    </ClCompile>
-    <ClInclude Include="..\..\src\libGLESv2\ProgramBinary.h">
-      <Filter>src\libGLESv2</Filter>
-    </ClInclude>
+    <None Include="..\..\src\angle.gyp"/>
     <None Include="..\..\src\libGLESv2\libGLESv2.def">
-      <Filter>src\libGLESv2</Filter>
+      <Filter>libGLESv2</Filter>
     </None>
-    <ClCompile Include="..\..\src\libGLESv2\validationES3.cpp">
-      <Filter>src\libGLESv2</Filter>
-    </ClCompile>
-    <ClInclude Include="..\..\src\libGLESv2\constants.h">
-      <Filter>src\libGLESv2</Filter>
-    </ClInclude>
-    <ClCompile Include="..\..\src\libGLESv2\FramebufferAttachment.cpp">
-      <Filter>src\libGLESv2</Filter>
-    </ClCompile>
-    <ClInclude Include="..\..\src\libGLESv2\FramebufferAttachment.h">
-      <Filter>src\libGLESv2</Filter>
-    </ClInclude>
-    <ClCompile Include="..\..\src\libGLESv2\Query.cpp">
-      <Filter>src\libGLESv2</Filter>
-    </ClCompile>
-    <ClCompile Include="..\..\src\libGLESv2\TransformFeedback.cpp">
-      <Filter>src\libGLESv2</Filter>
-    </ClCompile>
-    <ClCompile Include="..\..\src\libGLESv2\libGLESv2.cpp">
-      <Filter>src\libGLESv2</Filter>
-    </ClCompile>
-    <ClCompile Include="..\..\src\libGLESv2\State.cpp">
-      <Filter>src\libGLESv2</Filter>
-    </ClCompile>
-    <ClCompile Include="..\..\src\libGLESv2\ProgramBinary.cpp">
-      <Filter>src\libGLESv2</Filter>
-    </ClCompile>
-    <ClInclude Include="..\..\src\libGLESv2\Renderbuffer.h">
-      <Filter>src\libGLESv2</Filter>
-    </ClInclude>
-    <ClCompile Include="..\..\src\libGLESv2\VertexAttribute.cpp">
-      <Filter>src\libGLESv2</Filter>
-    </ClCompile>
-    <ClInclude Include="..\..\src\libGLESv2\queryconversions.h">
-      <Filter>src\libGLESv2</Filter>
-    </ClInclude>
-    <ClInclude Include="..\..\src\libGLESv2\validationES3.h">
-      <Filter>src\libGLESv2</Filter>
-    </ClInclude>
-    <ClInclude Include="..\..\src\libGLESv2\Program.h">
-      <Filter>src\libGLESv2</Filter>
-    </ClInclude>
-    <ClCompile Include="..\..\src\libGLESv2\Caps.cpp">
-      <Filter>src\libGLESv2</Filter>
-    </ClCompile>
-    <ClInclude Include="..\..\src\libGLESv2\HandleAllocator.h">
-      <Filter>src\libGLESv2</Filter>
-    </ClInclude>
-    <ClInclude Include="..\..\src\libGLESv2\ResourceManager.h">
-      <Filter>src\libGLESv2</Filter>
-    </ClInclude>
     <ResourceCompile Include="..\..\src\libGLESv2\libGLESv2.rc">
-      <Filter>src\libGLESv2</Filter>
+      <Filter>libGLESv2</Filter>
     </ResourceCompile>
-    <ClCompile Include="..\..\src\libGLESv2\Context.cpp">
-      <Filter>src\libGLESv2</Filter>
-    </ClCompile>
-    <ClInclude Include="..\..\src\libGLESv2\DynamicHLSL.h">
-      <Filter>src\libGLESv2</Filter>
-    </ClInclude>
-    <ClInclude Include="..\..\src\libGLESv2\VertexAttribute.h">
-      <Filter>src\libGLESv2</Filter>
-    </ClInclude>
-    <ClInclude Include="..\..\src\libGLESv2\validationES2.h">
-      <Filter>src\libGLESv2</Filter>
-    </ClInclude>
-    <ClInclude Include="..\..\src\libGLESv2\Fence.h">
-      <Filter>src\libGLESv2</Filter>
-    </ClInclude>
-    <ClCompile Include="..\..\src\libGLESv2\Buffer.cpp">
-      <Filter>src\libGLESv2</Filter>
-    </ClCompile>
-    <ClInclude Include="..\..\src\libGLESv2\angletypes.h">
-      <Filter>src\libGLESv2</Filter>
-    </ClInclude>
-    <ClCompile Include="..\..\src\libGLESv2\VertexArray.cpp">
-      <Filter>src\libGLESv2</Filter>
-    </ClCompile>
-    <ClCompile Include="..\..\src\libGLESv2\Shader.cpp">
-      <Filter>src\libGLESv2</Filter>
-    </ClCompile>
-    <ClCompile Include="..\..\src\libGLESv2\Uniform.cpp">
-      <Filter>src\libGLESv2</Filter>
-    </ClCompile>
-    <ClCompile Include="..\..\src\libGLESv2\main.cpp">
-      <Filter>src\libGLESv2</Filter>
-    </ClCompile>
-    <ClInclude Include="..\..\src\libGLESv2\main.h">
-      <Filter>src\libGLESv2</Filter>
-    </ClInclude>
-    <ClInclude Include="..\..\src\libGLESv2\VertexArray.h">
-      <Filter>src\libGLESv2</Filter>
-    </ClInclude>
-    <ClCompile Include="..\..\src\libGLESv2\Sampler.cpp">
-      <Filter>src\libGLESv2</Filter>
-    </ClCompile>
-    <ClInclude Include="..\..\src\libGLESv2\Framebuffer.h">
-      <Filter>src\libGLESv2</Filter>
-    </ClInclude>
-    <ClInclude Include="..\..\src\libGLESv2\formatutils.h">
-      <Filter>src\libGLESv2</Filter>
-    </ClInclude>
-    <ClInclude Include="..\..\src\libGLESv2\Buffer.h">
-      <Filter>src\libGLESv2</Filter>
-    </ClInclude>
-    <ClInclude Include="..\..\src\libGLESv2\State.h">
-      <Filter>src\libGLESv2</Filter>
-    </ClInclude>
-    <ClCompile Include="..\..\src\libGLESv2\Framebuffer.cpp">
-      <Filter>src\libGLESv2</Filter>
-    </ClCompile>
-    <ClInclude Include="..\..\src\libGLESv2\validationES.h">
-      <Filter>src\libGLESv2</Filter>
-    </ClInclude>
-    <ClCompile Include="..\..\src\libGLESv2\Texture.cpp">
-      <Filter>src\libGLESv2</Filter>
-    </ClCompile>
-    <ClCompile Include="..\..\src\libGLESv2\renderer\copyimage.cpp">
-      <Filter>src\libGLESv2\renderer</Filter>
-    </ClCompile>
-    <ClInclude Include="..\..\src\libGLESv2\renderer\TextureImpl.h">
-      <Filter>src\libGLESv2\renderer</Filter>
-    </ClInclude>
-    <ClInclude Include="..\..\src\libGLESv2\renderer\Renderer.h">
-      <Filter>src\libGLESv2\renderer</Filter>
-    </ClInclude>
-    <None Include="..\..\src\libGLESv2\renderer\loadimage.inl">
-      <Filter>src\libGLESv2\renderer</Filter>
-    </None>
-    <ClInclude Include="..\..\src\libGLESv2\renderer\ShaderExecutable.h">
-      <Filter>src\libGLESv2\renderer</Filter>
-    </ClInclude>
-    <ClInclude Include="..\..\src\libGLESv2\renderer\loadimage.h">
-      <Filter>src\libGLESv2\renderer</Filter>
-    </ClInclude>
-    <ClInclude Include="..\..\src\libGLESv2\renderer\copyimage.h">
-      <Filter>src\libGLESv2\renderer</Filter>
-    </ClInclude>
-    <ClCompile Include="..\..\src\libGLESv2\renderer\loadimage.cpp">
-      <Filter>src\libGLESv2\renderer</Filter>
-    </ClCompile>
-    <ClInclude Include="..\..\src\libGLESv2\renderer\BufferImpl.h">
-      <Filter>src\libGLESv2\renderer</Filter>
-    </ClInclude>
-    <ClCompile Include="..\..\src\libGLESv2\renderer\loadimageSSE2.cpp">
-      <Filter>src\libGLESv2\renderer</Filter>
-    </ClCompile>
-    <ClInclude Include="..\..\src\libGLESv2\renderer\copyvertex.h">
-      <Filter>src\libGLESv2\renderer</Filter>
-    </ClInclude>
-    <ClInclude Include="..\..\src\libGLESv2\renderer\SwapChain.h">
-      <Filter>src\libGLESv2\renderer</Filter>
-    </ClInclude>
-    <ClCompile Include="..\..\src\libGLESv2\renderer\Image.cpp">
-      <Filter>src\libGLESv2\renderer</Filter>
-    </ClCompile>
-    <ClInclude Include="..\..\src\libGLESv2\renderer\imageformats.h">
-      <Filter>src\libGLESv2\renderer</Filter>
-    </ClInclude>
-    <ClInclude Include="..\..\src\libGLESv2\renderer\QueryImpl.h">
-      <Filter>src\libGLESv2\renderer</Filter>
-    </ClInclude>
-    <ClInclude Include="..\..\src\libGLESv2\renderer\IndexRangeCache.h">
-      <Filter>src\libGLESv2\renderer</Filter>
-    </ClInclude>
-    <ClInclude Include="..\..\src\libGLESv2\renderer\FenceImpl.h">
-      <Filter>src\libGLESv2\renderer</Filter>
-    </ClInclude>
-    <ClInclude Include="..\..\src\libGLESv2\renderer\Image.h">
-      <Filter>src\libGLESv2\renderer</Filter>
-    </ClInclude>
-    <ClInclude Include="..\..\src\libGLESv2\renderer\generatemip.h">
-      <Filter>src\libGLESv2\renderer</Filter>
-    </ClInclude>
-    <ClInclude Include="..\..\src\libGLESv2\renderer\RenderTarget.h">
-      <Filter>src\libGLESv2\renderer</Filter>
-    </ClInclude>
-    <ClInclude Include="..\..\src\libGLESv2\renderer\vertexconversion.h">
-      <Filter>src\libGLESv2\renderer</Filter>
-    </ClInclude>
-    <ClInclude Include="..\..\src\libGLESv2\renderer\VertexArrayImpl.h">
-      <Filter>src\libGLESv2\renderer</Filter>
-    </ClInclude>
-    <ClCompile Include="..\..\src\libGLESv2\renderer\Renderer.cpp">
-      <Filter>src\libGLESv2\renderer</Filter>
-    </ClCompile>
-    <ClCompile Include="..\..\src\libGLESv2\renderer\IndexRangeCache.cpp">
-      <Filter>src\libGLESv2\renderer</Filter>
-    </ClCompile>
-    <None Include="..\..\src\libGLESv2\renderer\generatemip.inl">
-      <Filter>src\libGLESv2\renderer</Filter>
-    </None>
-    <ClCompile Include="..\..\src\libGLESv2\renderer\d3d\HLSLCompiler.cpp">
-      <Filter>src\libGLESv2\renderer\d3d</Filter>
-    </ClCompile>
-    <ClInclude Include="..\..\src\libGLESv2\renderer\d3d\IndexBuffer.h">
-      <Filter>src\libGLESv2\renderer\d3d</Filter>
-    </ClInclude>
-    <ClInclude Include="..\..\src\libGLESv2\renderer\d3d\HLSLCompiler.h">
-      <Filter>src\libGLESv2\renderer\d3d</Filter>
-    </ClInclude>
-    <ClInclude Include="..\..\src\libGLESv2\renderer\d3d\ImageD3D.h">
-      <Filter>src\libGLESv2\renderer\d3d</Filter>
-    </ClInclude>
-    <ClCompile Include="..\..\src\libGLESv2\renderer\d3d\BufferD3D.cpp">
-      <Filter>src\libGLESv2\renderer\d3d</Filter>
-    </ClCompile>
-    <ClInclude Include="..\..\src\libGLESv2\renderer\d3d\MemoryBuffer.h">
-      <Filter>src\libGLESv2\renderer\d3d</Filter>
-    </ClInclude>
-    <ClCompile Include="..\..\src\libGLESv2\renderer\d3d\IndexBuffer.cpp">
-      <Filter>src\libGLESv2\renderer\d3d</Filter>
-    </ClCompile>
-    <ClCompile Include="..\..\src\libGLESv2\renderer\d3d\VertexBuffer.cpp">
-      <Filter>src\libGLESv2\renderer\d3d</Filter>
-    </ClCompile>
-    <ClCompile Include="..\..\src\libGLESv2\renderer\d3d\TextureD3D.cpp">
-      <Filter>src\libGLESv2\renderer\d3d</Filter>
-    </ClCompile>
-    <ClCompile Include="..\..\src\libGLESv2\renderer\d3d\VertexDataManager.cpp">
-      <Filter>src\libGLESv2\renderer\d3d</Filter>
-    </ClCompile>
-    <ClInclude Include="..\..\src\libGLESv2\renderer\d3d\TextureD3D.h">
-      <Filter>src\libGLESv2\renderer\d3d</Filter>
-    </ClInclude>
-    <ClInclude Include="..\..\src\libGLESv2\renderer\d3d\TextureStorage.h">
-      <Filter>src\libGLESv2\renderer\d3d</Filter>
-    </ClInclude>
-    <ClCompile Include="..\..\src\libGLESv2\renderer\d3d\MemoryBuffer.cpp">
-      <Filter>src\libGLESv2\renderer\d3d</Filter>
-    </ClCompile>
-    <ClCompile Include="..\..\src\libGLESv2\renderer\d3d\ImageD3D.cpp">
-      <Filter>src\libGLESv2\renderer\d3d</Filter>
-    </ClCompile>
-    <ClCompile Include="..\..\src\libGLESv2\renderer\d3d\TextureStorage.cpp">
-      <Filter>src\libGLESv2\renderer\d3d</Filter>
-    </ClCompile>
-    <ClInclude Include="..\..\src\libGLESv2\renderer\d3d\IndexDataManager.h">
-      <Filter>src\libGLESv2\renderer\d3d</Filter>
-    </ClInclude>
-    <ClInclude Include="..\..\src\libGLESv2\renderer\d3d\VertexBuffer.h">
-      <Filter>src\libGLESv2\renderer\d3d</Filter>
-    </ClInclude>
-    <ClInclude Include="..\..\src\libGLESv2\renderer\d3d\BufferD3D.h">
-      <Filter>src\libGLESv2\renderer\d3d</Filter>
-    </ClInclude>
-    <ClCompile Include="..\..\src\libGLESv2\renderer\d3d\IndexDataManager.cpp">
-      <Filter>src\libGLESv2\renderer\d3d</Filter>
-    </ClCompile>
-    <ClInclude Include="..\..\src\libGLESv2\renderer\d3d\VertexDataManager.h">
-      <Filter>src\libGLESv2\renderer\d3d</Filter>
-    </ClInclude>
-    <ClCompile Include="..\..\src\libGLESv2\renderer\d3d\d3d11\Renderer11.cpp">
-      <Filter>src\libGLESv2\renderer\d3d\d3d11</Filter>
-    </ClCompile>
-    <ClCompile Include="..\..\src\libGLESv2\renderer\d3d\d3d11\InputLayoutCache.cpp">
-      <Filter>src\libGLESv2\renderer\d3d\d3d11</Filter>
-    </ClCompile>
-    <ClCompile Include="..\..\src\libGLESv2\renderer\d3d\d3d11\PixelTransfer11.cpp">
-      <Filter>src\libGLESv2\renderer\d3d\d3d11</Filter>
-    </ClCompile>
-    <ClCompile Include="..\..\src\libGLESv2\renderer\d3d\d3d11\VertexBuffer11.cpp">
-      <Filter>src\libGLESv2\renderer\d3d\d3d11</Filter>
-    </ClCompile>
-    <ClInclude Include="..\..\src\libGLESv2\renderer\d3d\d3d11\Clear11.h">
-      <Filter>src\libGLESv2\renderer\d3d\d3d11</Filter>
-    </ClInclude>
-    <ClInclude Include="..\..\src\libGLESv2\renderer\d3d\d3d11\RenderStateCache.h">
-      <Filter>src\libGLESv2\renderer\d3d\d3d11</Filter>
-    </ClInclude>
-    <ClInclude Include="..\..\src\libGLESv2\renderer\d3d\d3d11\ShaderExecutable11.h">
-      <Filter>src\libGLESv2\renderer\d3d\d3d11</Filter>
-    </ClInclude>
-    <ClInclude Include="..\..\src\libGLESv2\renderer\d3d\d3d11\IndexBuffer11.h">
-      <Filter>src\libGLESv2\renderer\d3d\d3d11</Filter>
-    </ClInclude>
-    <ClInclude Include="..\..\src\libGLESv2\renderer\d3d\d3d11\Query11.h">
-      <Filter>src\libGLESv2\renderer\d3d\d3d11</Filter>
-    </ClInclude>
-    <ClCompile Include="..\..\src\libGLESv2\renderer\d3d\d3d11\Query11.cpp">
-      <Filter>src\libGLESv2\renderer\d3d\d3d11</Filter>
-    </ClCompile>
-    <ClInclude Include="..\..\src\libGLESv2\renderer\d3d\d3d11\Buffer11.h">
-      <Filter>src\libGLESv2\renderer\d3d\d3d11</Filter>
-    </ClInclude>
-    <ClCompile Include="..\..\src\libGLESv2\renderer\d3d\d3d11\ShaderExecutable11.cpp">
-      <Filter>src\libGLESv2\renderer\d3d\d3d11</Filter>
-    </ClCompile>
-    <ClCompile Include="..\..\src\libGLESv2\renderer\d3d\d3d11\Blit11.cpp">
-      <Filter>src\libGLESv2\renderer\d3d\d3d11</Filter>
-    </ClCompile>
-    <ClCompile Include="..\..\src\libGLESv2\renderer\d3d\d3d11\RenderStateCache.cpp">
-      <Filter>src\libGLESv2\renderer\d3d\d3d11</Filter>
-    </ClCompile>
-    <ClCompile Include="..\..\src\libGLESv2\renderer\d3d\d3d11\IndexBuffer11.cpp">
-      <Filter>src\libGLESv2\renderer\d3d\d3d11</Filter>
-    </ClCompile>
-    <ClCompile Include="..\..\src\libGLESv2\renderer\d3d\d3d11\formatutils11.cpp">
-      <Filter>src\libGLESv2\renderer\d3d\d3d11</Filter>
-    </ClCompile>
-    <ClCompile Include="..\..\src\libGLESv2\renderer\d3d\d3d11\SwapChain11.cpp">
-      <Filter>src\libGLESv2\renderer\d3d\d3d11</Filter>
-    </ClCompile>
-    <ClInclude Include="..\..\src\libGLESv2\renderer\d3d\d3d11\VertexBuffer11.h">
-      <Filter>src\libGLESv2\renderer\d3d\d3d11</Filter>
-    </ClInclude>
-    <ClInclude Include="..\..\src\libGLESv2\renderer\d3d\d3d11\TextureStorage11.h">
-      <Filter>src\libGLESv2\renderer\d3d\d3d11</Filter>
-    </ClInclude>
-    <ClInclude Include="..\..\src\libGLESv2\renderer\d3d\d3d11\Blit11.h">
-      <Filter>src\libGLESv2\renderer\d3d\d3d11</Filter>
-    </ClInclude>
-    <ClCompile Include="..\..\src\libGLESv2\renderer\d3d\d3d11\renderer11_utils.cpp">
-      <Filter>src\libGLESv2\renderer\d3d\d3d11</Filter>
-    </ClCompile>
-    <ClInclude Include="..\..\src\libGLESv2\renderer\d3d\d3d11\Image11.h">
-      <Filter>src\libGLESv2\renderer\d3d\d3d11</Filter>
-    </ClInclude>
-    <ClInclude Include="..\..\src\libGLESv2\renderer\d3d\d3d11\RenderTarget11.h">
-      <Filter>src\libGLESv2\renderer\d3d\d3d11</Filter>
-    </ClInclude>
-    <ClCompile Include="..\..\src\libGLESv2\renderer\d3d\d3d11\Image11.cpp">
-      <Filter>src\libGLESv2\renderer\d3d\d3d11</Filter>
-    </ClCompile>
-    <ClInclude Include="..\..\src\libGLESv2\renderer\d3d\d3d11\InputLayoutCache.h">
-      <Filter>src\libGLESv2\renderer\d3d\d3d11</Filter>
-    </ClInclude>
-    <ClInclude Include="..\..\src\libGLESv2\renderer\d3d\d3d11\SwapChain11.h">
-      <Filter>src\libGLESv2\renderer\d3d\d3d11</Filter>
-    </ClInclude>
-    <ClCompile Include="..\..\src\libGLESv2\renderer\d3d\d3d11\TextureStorage11.cpp">
-      <Filter>src\libGLESv2\renderer\d3d\d3d11</Filter>
-    </ClCompile>
-    <ClInclude Include="..\..\src\libGLESv2\renderer\d3d\d3d11\Fence11.h">
-      <Filter>src\libGLESv2\renderer\d3d\d3d11</Filter>
-    </ClInclude>
-    <ClInclude Include="..\..\src\libGLESv2\renderer\d3d\d3d11\VertexArray11.h">
-      <Filter>src\libGLESv2\renderer\d3d\d3d11</Filter>
-    </ClInclude>
-    <ClInclude Include="..\..\src\libGLESv2\renderer\d3d\d3d11\renderer11_utils.h">
-      <Filter>src\libGLESv2\renderer\d3d\d3d11</Filter>
-    </ClInclude>
-    <ClCompile Include="..\..\src\libGLESv2\renderer\d3d\d3d11\Buffer11.cpp">
-      <Filter>src\libGLESv2\renderer\d3d\d3d11</Filter>
-    </ClCompile>
-    <ClCompile Include="..\..\src\libGLESv2\renderer\d3d\d3d11\RenderTarget11.cpp">
-      <Filter>src\libGLESv2\renderer\d3d\d3d11</Filter>
-    </ClCompile>
-    <ClInclude Include="..\..\src\libGLESv2\renderer\d3d\d3d11\Renderer11.h">
-      <Filter>src\libGLESv2\renderer\d3d\d3d11</Filter>
-    </ClInclude>
-    <ClCompile Include="..\..\src\libGLESv2\renderer\d3d\d3d11\Fence11.cpp">
-      <Filter>src\libGLESv2\renderer\d3d\d3d11</Filter>
-    </ClCompile>
-    <ClCompile Include="..\..\src\libGLESv2\renderer\d3d\d3d11\Clear11.cpp">
-      <Filter>src\libGLESv2\renderer\d3d\d3d11</Filter>
-    </ClCompile>
-    <ClInclude Include="..\..\src\libGLESv2\renderer\d3d\d3d11\PixelTransfer11.h">
-      <Filter>src\libGLESv2\renderer\d3d\d3d11</Filter>
-    </ClInclude>
-    <ClInclude Include="..\..\src\libGLESv2\renderer\d3d\d3d11\formatutils11.h">
-      <Filter>src\libGLESv2\renderer\d3d\d3d11</Filter>
-    </ClInclude>
-    <ClInclude Include="..\..\src\libGLESv2\renderer\d3d\d3d11\shaders\compiled\swizzleui2dps.h">
-      <Filter>src\libGLESv2\renderer\d3d\d3d11\shaders\compiled</Filter>
-    </ClInclude>
-    <ClInclude Include="..\..\src\libGLESv2\renderer\d3d\d3d11\shaders\compiled\passthroughr2d11ps.h">
-      <Filter>src\libGLESv2\renderer\d3d\d3d11\shaders\compiled</Filter>
-    </ClInclude>
-    <ClInclude Include="..\..\src\libGLESv2\renderer\d3d\d3d11\shaders\compiled\passthroughr3dui11ps.h">
-      <Filter>src\libGLESv2\renderer\d3d\d3d11\shaders\compiled</Filter>
-    </ClInclude>
-    <ClInclude Include="..\..\src\libGLESv2\renderer\d3d\d3d11\shaders\compiled\swizzlef3dps.h">
-      <Filter>src\libGLESv2\renderer\d3d\d3d11\shaders\compiled</Filter>
-    </ClInclude>
-    <ClInclude Include="..\..\src\libGLESv2\renderer\d3d\d3d11\shaders\compiled\clearfloat11ps.h">
-      <Filter>src\libGLESv2\renderer\d3d\d3d11\shaders\compiled</Filter>
-    </ClInclude>
-    <ClInclude Include="..\..\src\libGLESv2\renderer\d3d\d3d11\shaders\compiled\passthroughlumalpha2d11ps.h">
-      <Filter>src\libGLESv2\renderer\d3d\d3d11\shaders\compiled</Filter>
-    </ClInclude>
-    <ClInclude Include="..\..\src\libGLESv2\renderer\d3d\d3d11\shaders\compiled\passthroughrg2dui11ps.h">
-      <Filter>src\libGLESv2\renderer\d3d\d3d11\shaders\compiled</Filter>
-    </ClInclude>
-    <ClInclude Include="..\..\src\libGLESv2\renderer\d3d\d3d11\shaders\compiled\passthroughrgb3d11ps.h">
-      <Filter>src\libGLESv2\renderer\d3d\d3d11\shaders\compiled</Filter>
-    </ClInclude>
-    <ClInclude Include="..\..\src\libGLESv2\renderer\d3d\d3d11\shaders\compiled\passthroughrgb2di11ps.h">
-      <Filter>src\libGLESv2\renderer\d3d\d3d11\shaders\compiled</Filter>
-    </ClInclude>
-    <ClInclude Include="..\..\src\libGLESv2\renderer\d3d\d3d11\shaders\compiled\swizzleui3dps.h">
-      <Filter>src\libGLESv2\renderer\d3d\d3d11\shaders\compiled</Filter>
-    </ClInclude>
-    <ClInclude Include="..\..\src\libGLESv2\renderer\d3d\d3d11\shaders\compiled\clearsint11ps.h">
-      <Filter>src\libGLESv2\renderer\d3d\d3d11\shaders\compiled</Filter>
-    </ClInclude>
-    <ClInclude Include="..\..\src\libGLESv2\renderer\d3d\d3d11\shaders\compiled\swizzlef2dps.h">
-      <Filter>src\libGLESv2\renderer\d3d\d3d11\shaders\compiled</Filter>
-    </ClInclude>
-    <ClInclude Include="..\..\src\libGLESv2\renderer\d3d\d3d11\shaders\compiled\passthroughrg3di11ps.h">
-      <Filter>src\libGLESv2\renderer\d3d\d3d11\shaders\compiled</Filter>
-    </ClInclude>
-    <ClInclude Include="..\..\src\libGLESv2\renderer\d3d\d3d11\shaders\compiled\swizzlei2darrayps.h">
-      <Filter>src\libGLESv2\renderer\d3d\d3d11\shaders\compiled</Filter>
-    </ClInclude>
-    <ClInclude Include="..\..\src\libGLESv2\renderer\d3d\d3d11\shaders\compiled\passthroughlumalpha3d11ps.h">
-      <Filter>src\libGLESv2\renderer\d3d\d3d11\shaders\compiled</Filter>
-    </ClInclude>
-    <ClInclude Include="..\..\src\libGLESv2\renderer\d3d\d3d11\shaders\compiled\passthroughrgba3di11ps.h">
-      <Filter>src\libGLESv2\renderer\d3d\d3d11\shaders\compiled</Filter>
-    </ClInclude>
-    <ClInclude Include="..\..\src\libGLESv2\renderer\d3d\d3d11\shaders\compiled\passthroughrgb2d11ps.h">
-      <Filter>src\libGLESv2\renderer\d3d\d3d11\shaders\compiled</Filter>
-    </ClInclude>
-    <ClInclude Include="..\..\src\libGLESv2\renderer\d3d\d3d11\shaders\compiled\clearsint11vs.h">
-      <Filter>src\libGLESv2\renderer\d3d\d3d11\shaders\compiled</Filter>
-    </ClInclude>
-    <ClInclude Include="..\..\src\libGLESv2\renderer\d3d\d3d11\shaders\compiled\passthrough2d11vs.h">
-      <Filter>src\libGLESv2\renderer\d3d\d3d11\shaders\compiled</Filter>
-    </ClInclude>
-    <ClInclude Include="..\..\src\libGLESv2\renderer\d3d\d3d11\shaders\compiled\buffertotexture11_ps_4f.h">
-      <Filter>src\libGLESv2\renderer\d3d\d3d11\shaders\compiled</Filter>
-    </ClInclude>
-    <ClInclude Include="..\..\src\libGLESv2\renderer\d3d\d3d11\shaders\compiled\buffertotexture11_gs.h">
-      <Filter>src\libGLESv2\renderer\d3d\d3d11\shaders\compiled</Filter>
-    </ClInclude>
-    <ClInclude Include="..\..\src\libGLESv2\renderer\d3d\d3d11\shaders\compiled\clearfloat11vs.h">
-      <Filter>src\libGLESv2\renderer\d3d\d3d11\shaders\compiled</Filter>
-    </ClInclude>
-    <ClInclude Include="..\..\src\libGLESv2\renderer\d3d\d3d11\shaders\compiled\passthroughrgba2di11ps.h">
-      <Filter>src\libGLESv2\renderer\d3d\d3d11\shaders\compiled</Filter>
-    </ClInclude>
-    <ClInclude Include="..\..\src\libGLESv2\renderer\d3d\d3d11\shaders\compiled\passthroughr2dui11ps.h">
-      <Filter>src\libGLESv2\renderer\d3d\d3d11\shaders\compiled</Filter>
-    </ClInclude>
-    <ClInclude Include="..\..\src\libGLESv2\renderer\d3d\d3d11\shaders\compiled\buffertotexture11_ps_4i.h">
-      <Filter>src\libGLESv2\renderer\d3d\d3d11\shaders\compiled</Filter>
-    </ClInclude>
-    <ClInclude Include="..\..\src\libGLESv2\renderer\d3d\d3d11\shaders\compiled\passthroughrg3dui11ps.h">
-      <Filter>src\libGLESv2\renderer\d3d\d3d11\shaders\compiled</Filter>
-    </ClInclude>
-    <ClInclude Include="..\..\src\libGLESv2\renderer\d3d\d3d11\shaders\compiled\swizzlei2dps.h">
-      <Filter>src\libGLESv2\renderer\d3d\d3d11\shaders\compiled</Filter>
-    </ClInclude>
-    <ClInclude Include="..\..\src\libGLESv2\renderer\d3d\d3d11\shaders\compiled\passthroughrg2d11ps.h">
-      <Filter>src\libGLESv2\renderer\d3d\d3d11\shaders\compiled</Filter>
-    </ClInclude>
-    <ClInclude Include="..\..\src\libGLESv2\renderer\d3d\d3d11\shaders\compiled\passthroughrgba2dui11ps.h">
-      <Filter>src\libGLESv2\renderer\d3d\d3d11\shaders\compiled</Filter>
-    </ClInclude>
-    <ClInclude Include="..\..\src\libGLESv2\renderer\d3d\d3d11\shaders\compiled\passthroughrgb3dui11ps.h">
-      <Filter>src\libGLESv2\renderer\d3d\d3d11\shaders\compiled</Filter>
-    </ClInclude>
-    <ClInclude Include="..\..\src\libGLESv2\renderer\d3d\d3d11\shaders\compiled\passthroughr2di11ps.h">
-      <Filter>src\libGLESv2\renderer\d3d\d3d11\shaders\compiled</Filter>
-    </ClInclude>
-    <ClInclude Include="..\..\src\libGLESv2\renderer\d3d\d3d11\shaders\compiled\passthroughrgba3d11ps.h">
-      <Filter>src\libGLESv2\renderer\d3d\d3d11\shaders\compiled</Filter>
-    </ClInclude>
-    <ClInclude Include="..\..\src\libGLESv2\renderer\d3d\d3d11\shaders\compiled\passthroughlum3d11ps.h">
-      <Filter>src\libGLESv2\renderer\d3d\d3d11\shaders\compiled</Filter>
-    </ClInclude>
-    <ClInclude Include="..\..\src\libGLESv2\renderer\d3d\d3d11\shaders\compiled\clearuint11vs.h">
-      <Filter>src\libGLESv2\renderer\d3d\d3d11\shaders\compiled</Filter>
-    </ClInclude>
-    <ClInclude Include="..\..\src\libGLESv2\renderer\d3d\d3d11\shaders\compiled\passthroughr3d11ps.h">
-      <Filter>src\libGLESv2\renderer\d3d\d3d11\shaders\compiled</Filter>
-    </ClInclude>
-    <ClInclude Include="..\..\src\libGLESv2\renderer\d3d\d3d11\shaders\compiled\passthroughrg2di11ps.h">
-      <Filter>src\libGLESv2\renderer\d3d\d3d11\shaders\compiled</Filter>
-    </ClInclude>
-    <ClInclude Include="..\..\src\libGLESv2\renderer\d3d\d3d11\shaders\compiled\clearuint11ps.h">
-      <Filter>src\libGLESv2\renderer\d3d\d3d11\shaders\compiled</Filter>
-    </ClInclude>
-    <ClInclude Include="..\..\src\libGLESv2\renderer\d3d\d3d11\shaders\compiled\passthrough3d11vs.h">
-      <Filter>src\libGLESv2\renderer\d3d\d3d11\shaders\compiled</Filter>
-    </ClInclude>
-    <ClInclude Include="..\..\src\libGLESv2\renderer\d3d\d3d11\shaders\compiled\passthroughdepth2d11ps.h">
-      <Filter>src\libGLESv2\renderer\d3d\d3d11\shaders\compiled</Filter>
-    </ClInclude>
-    <ClInclude Include="..\..\src\libGLESv2\renderer\d3d\d3d11\shaders\compiled\passthroughlum2d11ps.h">
-      <Filter>src\libGLESv2\renderer\d3d\d3d11\shaders\compiled</Filter>
-    </ClInclude>
-    <ClInclude Include="..\..\src\libGLESv2\renderer\d3d\d3d11\shaders\compiled\passthroughrgb2dui11ps.h">
-      <Filter>src\libGLESv2\renderer\d3d\d3d11\shaders\compiled</Filter>
-    </ClInclude>
-    <ClInclude Include="..\..\src\libGLESv2\renderer\d3d\d3d11\shaders\compiled\swizzlei3dps.h">
-      <Filter>src\libGLESv2\renderer\d3d\d3d11\shaders\compiled</Filter>
-    </ClInclude>
-    <ClInclude Include="..\..\src\libGLESv2\renderer\d3d\d3d11\shaders\compiled\swizzlef2darrayps.h">
-      <Filter>src\libGLESv2\renderer\d3d\d3d11\shaders\compiled</Filter>
-    </ClInclude>
-    <ClInclude Include="..\..\src\libGLESv2\renderer\d3d\d3d11\shaders\compiled\buffertotexture11_vs.h">
-      <Filter>src\libGLESv2\renderer\d3d\d3d11\shaders\compiled</Filter>
-    </ClInclude>
-    <ClInclude Include="..\..\src\libGLESv2\renderer\d3d\d3d11\shaders\compiled\passthroughrgb3di11ps.h">
-      <Filter>src\libGLESv2\renderer\d3d\d3d11\shaders\compiled</Filter>
-    </ClInclude>
-    <ClInclude Include="..\..\src\libGLESv2\renderer\d3d\d3d11\shaders\compiled\passthroughrg3d11ps.h">
-      <Filter>src\libGLESv2\renderer\d3d\d3d11\shaders\compiled</Filter>
-    </ClInclude>
-    <ClInclude Include="..\..\src\libGLESv2\renderer\d3d\d3d11\shaders\compiled\passthroughrgba2d11ps.h">
-      <Filter>src\libGLESv2\renderer\d3d\d3d11\shaders\compiled</Filter>
-    </ClInclude>
-    <ClInclude Include="..\..\src\libGLESv2\renderer\d3d\d3d11\shaders\compiled\swizzleui2darrayps.h">
-      <Filter>src\libGLESv2\renderer\d3d\d3d11\shaders\compiled</Filter>
-    </ClInclude>
-    <ClInclude Include="..\..\src\libGLESv2\renderer\d3d\d3d11\shaders\compiled\passthroughrgba3dui11ps.h">
-      <Filter>src\libGLESv2\renderer\d3d\d3d11\shaders\compiled</Filter>
-    </ClInclude>
-    <ClInclude Include="..\..\src\libGLESv2\renderer\d3d\d3d11\shaders\compiled\buffertotexture11_ps_4ui.h">
-      <Filter>src\libGLESv2\renderer\d3d\d3d11\shaders\compiled</Filter>
-    </ClInclude>
-    <ClInclude Include="..\..\src\libGLESv2\renderer\d3d\d3d11\shaders\compiled\passthroughr3di11ps.h">
-      <Filter>src\libGLESv2\renderer\d3d\d3d11\shaders\compiled</Filter>
-    </ClInclude>
-    <ClInclude Include="..\..\src\libGLESv2\renderer\d3d\d3d11\shaders\compiled\passthrough3d11gs.h">
-      <Filter>src\libGLESv2\renderer\d3d\d3d11\shaders\compiled</Filter>
-    </ClInclude>
-    <ClInclude Include="..\..\src\libGLESv2\renderer\d3d\d3d9\renderer9_utils.h">
-      <Filter>src\libGLESv2\renderer\d3d\d3d9</Filter>
-    </ClInclude>
-    <ClInclude Include="..\..\src\libGLESv2\renderer\d3d\d3d9\TextureStorage9.h">
-      <Filter>src\libGLESv2\renderer\d3d\d3d9</Filter>
-    </ClInclude>
-    <ClCompile Include="..\..\src\libGLESv2\renderer\d3d\d3d9\VertexDeclarationCache.cpp">
-      <Filter>src\libGLESv2\renderer\d3d\d3d9</Filter>
-    </ClCompile>
-    <ClCompile Include="..\..\src\libGLESv2\renderer\d3d\d3d9\Query9.cpp">
-      <Filter>src\libGLESv2\renderer\d3d\d3d9</Filter>
-    </ClCompile>
-    <ClInclude Include="..\..\src\libGLESv2\renderer\d3d\d3d9\IndexBuffer9.h">
-      <Filter>src\libGLESv2\renderer\d3d\d3d9</Filter>
-    </ClInclude>
-    <ClInclude Include="..\..\src\libGLESv2\renderer\d3d\d3d9\ShaderCache.h">
-      <Filter>src\libGLESv2\renderer\d3d\d3d9</Filter>
-    </ClInclude>
-    <ClCompile Include="..\..\src\libGLESv2\renderer\d3d\d3d9\VertexBuffer9.cpp">
-      <Filter>src\libGLESv2\renderer\d3d\d3d9</Filter>
-    </ClCompile>
-    <ClInclude Include="..\..\src\libGLESv2\renderer\d3d\d3d9\Fence9.h">
-      <Filter>src\libGLESv2\renderer\d3d\d3d9</Filter>
-    </ClInclude>
-    <ClInclude Include="..\..\src\libGLESv2\renderer\d3d\d3d9\VertexArray9.h">
-      <Filter>src\libGLESv2\renderer\d3d\d3d9</Filter>
-    </ClInclude>
-    <ClCompile Include="..\..\src\libGLESv2\renderer\d3d\d3d9\Fence9.cpp">
-      <Filter>src\libGLESv2\renderer\d3d\d3d9</Filter>
-    </ClCompile>
-    <ClCompile Include="..\..\src\libGLESv2\renderer\d3d\d3d9\Image9.cpp">
-      <Filter>src\libGLESv2\renderer\d3d\d3d9</Filter>
-    </ClCompile>
-    <ClInclude Include="..\..\src\libGLESv2\renderer\d3d\d3d9\Renderer9.h">
-      <Filter>src\libGLESv2\renderer\d3d\d3d9</Filter>
-    </ClInclude>
-    <ClCompile Include="..\..\src\libGLESv2\renderer\d3d\d3d9\renderer9_utils.cpp">
-      <Filter>src\libGLESv2\renderer\d3d\d3d9</Filter>
-    </ClCompile>
-    <ClInclude Include="..\..\src\libGLESv2\renderer\d3d\d3d9\Blit9.h">
-      <Filter>src\libGLESv2\renderer\d3d\d3d9</Filter>
-    </ClInclude>
-    <ClInclude Include="..\..\src\libGLESv2\renderer\d3d\d3d9\VertexDeclarationCache.h">
-      <Filter>src\libGLESv2\renderer\d3d\d3d9</Filter>
-    </ClInclude>
-    <ClInclude Include="..\..\src\libGLESv2\renderer\d3d\d3d9\Image9.h">
-      <Filter>src\libGLESv2\renderer\d3d\d3d9</Filter>
-    </ClInclude>
-    <ClCompile Include="..\..\src\libGLESv2\renderer\d3d\d3d9\TextureStorage9.cpp">
-      <Filter>src\libGLESv2\renderer\d3d\d3d9</Filter>
-    </ClCompile>
-    <ClInclude Include="..\..\src\libGLESv2\renderer\d3d\d3d9\VertexBuffer9.h">
-      <Filter>src\libGLESv2\renderer\d3d\d3d9</Filter>
-    </ClInclude>
-    <ClCompile Include="..\..\src\libGLESv2\renderer\d3d\d3d9\Renderer9.cpp">
-      <Filter>src\libGLESv2\renderer\d3d\d3d9</Filter>
-    </ClCompile>
-    <ClInclude Include="..\..\src\libGLESv2\renderer\d3d\d3d9\formatutils9.h">
-      <Filter>src\libGLESv2\renderer\d3d\d3d9</Filter>
-    </ClInclude>
-    <ClCompile Include="..\..\src\libGLESv2\renderer\d3d\d3d9\RenderTarget9.cpp">
-      <Filter>src\libGLESv2\renderer\d3d\d3d9</Filter>
-    </ClCompile>
-    <ClCompile Include="..\..\src\libGLESv2\renderer\d3d\d3d9\formatutils9.cpp">
-      <Filter>src\libGLESv2\renderer\d3d\d3d9</Filter>
-    </ClCompile>
-    <ClCompile Include="..\..\src\libGLESv2\renderer\d3d\d3d9\Buffer9.cpp">
-      <Filter>src\libGLESv2\renderer\d3d\d3d9</Filter>
-    </ClCompile>
-    <ClCompile Include="..\..\src\libGLESv2\renderer\d3d\d3d9\ShaderExecutable9.cpp">
-      <Filter>src\libGLESv2\renderer\d3d\d3d9</Filter>
-    </ClCompile>
-    <ClInclude Include="..\..\src\libGLESv2\renderer\d3d\d3d9\Query9.h">
-      <Filter>src\libGLESv2\renderer\d3d\d3d9</Filter>
-    </ClInclude>
-    <ClInclude Include="..\..\src\libGLESv2\renderer\d3d\d3d9\RenderTarget9.h">
-      <Filter>src\libGLESv2\renderer\d3d\d3d9</Filter>
-    </ClInclude>
-    <ClInclude Include="..\..\src\libGLESv2\renderer\d3d\d3d9\SwapChain9.h">
-      <Filter>src\libGLESv2\renderer\d3d\d3d9</Filter>
-    </ClInclude>
-    <ClCompile Include="..\..\src\libGLESv2\renderer\d3d\d3d9\SwapChain9.cpp">
-      <Filter>src\libGLESv2\renderer\d3d\d3d9</Filter>
-    </ClCompile>
-    <ClCompile Include="..\..\src\libGLESv2\renderer\d3d\d3d9\Blit9.cpp">
-      <Filter>src\libGLESv2\renderer\d3d\d3d9</Filter>
-    </ClCompile>
-    <ClCompile Include="..\..\src\libGLESv2\renderer\d3d\d3d9\IndexBuffer9.cpp">
-      <Filter>src\libGLESv2\renderer\d3d\d3d9</Filter>
-    </ClCompile>
-    <ClInclude Include="..\..\src\libGLESv2\renderer\d3d\d3d9\Buffer9.h">
-      <Filter>src\libGLESv2\renderer\d3d\d3d9</Filter>
-    </ClInclude>
-    <ClInclude Include="..\..\src\libGLESv2\renderer\d3d\d3d9\shaders\compiled\standardvs.h">
-      <Filter>src\libGLESv2\renderer\d3d\d3d9\shaders\compiled</Filter>
-    </ClInclude>
-    <ClInclude Include="..\..\src\libGLESv2\renderer\d3d\d3d9\shaders\compiled\luminanceps.h">
-      <Filter>src\libGLESv2\renderer\d3d\d3d9\shaders\compiled</Filter>
-    </ClInclude>
-    <ClInclude Include="..\..\src\libGLESv2\renderer\d3d\d3d9\shaders\compiled\componentmaskps.h">
-      <Filter>src\libGLESv2\renderer\d3d\d3d9\shaders\compiled</Filter>
-    </ClInclude>
-    <ClInclude Include="..\..\src\libGLESv2\renderer\d3d\d3d9\shaders\compiled\passthroughps.h">
-      <Filter>src\libGLESv2\renderer\d3d\d3d9\shaders\compiled</Filter>
-    </ClInclude>
-    <ClInclude Include="..\..\src\libGLESv2\renderer\d3d\d3d9\shaders\compiled\flipyvs.h">
-      <Filter>src\libGLESv2\renderer\d3d\d3d9\shaders\compiled</Filter>
-    </ClInclude>
-    <ClInclude Include="..\..\src\common\tls.h">
-      <Filter>src\common</Filter>
-    </ClInclude>
-    <ClInclude Include="..\..\src\common\mathutil.h">
-      <Filter>src\common</Filter>
-    </ClInclude>
-    <ClCompile Include="..\..\src\common\event_tracer.cpp">
-      <Filter>src\common</Filter>
-    </ClCompile>
-    <ClInclude Include="..\..\src\common\blocklayout.h">
-      <Filter>src\common</Filter>
-    </ClInclude>
-    <ClCompile Include="..\..\src\common\RefCountObject.cpp">
-      <Filter>src\common</Filter>
-    </ClCompile>
-    <ClCompile Include="..\..\src\common\tls.cpp">
-      <Filter>src\common</Filter>
-    </ClCompile>
-    <ClInclude Include="..\..\src\common\debug.h">
-      <Filter>src\common</Filter>
-    </ClInclude>
-    <ClInclude Include="..\..\src\common\utilities.h">
-      <Filter>src\common</Filter>
-    </ClInclude>
-    <ClInclude Include="..\..\src\common\RefCountObject.h">
-      <Filter>src\common</Filter>
-    </ClInclude>
-    <ClInclude Include="..\..\src\common\event_tracer.h">
-      <Filter>src\common</Filter>
-    </ClInclude>
-    <ClCompile Include="..\..\src\common\utilities.cpp">
-      <Filter>src\common</Filter>
-    </ClCompile>
-    <ClInclude Include="..\..\src\common\angleutils.h">
-      <Filter>src\common</Filter>
-    </ClInclude>
-    <ClCompile Include="..\..\src\common\mathutil.cpp">
-      <Filter>src\common</Filter>
-    </ClCompile>
-    <ClCompile Include="..\..\src\common\debug.cpp">
-      <Filter>src\common</Filter>
-    </ClCompile>
-    <ClInclude Include="..\..\src\common\platform.h">
-      <Filter>src\common</Filter>
-    </ClInclude>
-    <ClInclude Include="..\..\src\common\version.h">
-      <Filter>src\common</Filter>
-    </ClInclude>
-    <ClCompile Include="..\..\src\common\blocklayout.cpp">
-      <Filter>src\common</Filter>
-    </ClCompile>
-    <ClInclude Include="..\..\src\third_party\systeminfo\SystemInfo.h">
-      <Filter>src\third_party\systeminfo</Filter>
-    </ClInclude>
-    <ClCompile Include="..\..\src\third_party\systeminfo\SystemInfo.cpp">
-      <Filter>src\third_party\systeminfo</Filter>
-    </ClCompile>
-    <ClInclude Include="..\..\src\third_party\murmurhash\MurmurHash3.h">
-      <Filter>src\third_party\murmurhash</Filter>
-    </ClInclude>
-    <ClCompile Include="..\..\src\third_party\murmurhash\MurmurHash3.cpp">
-      <Filter>src\third_party\murmurhash</Filter>
+    <ClCompile Include="..\..\src\libGLESv2\libGLESv2.cpp">
+      <Filter>libGLESv2</Filter>
     </ClCompile>
-    <ClInclude Include="..\..\include\angle_gl.h">
-      <Filter>include</Filter>
-    </ClInclude>
-    <ClInclude Include="..\..\include\KHR\khrplatform.h">
-      <Filter>include\KHR</Filter>
-    </ClInclude>
-    <ClInclude Include="..\..\include\GLSLANG\ShaderLang.h">
-      <Filter>include\GLSLANG</Filter>
-    </ClInclude>
-    <ClInclude Include="..\..\include\GLSLANG\ShaderVars.h">
-      <Filter>include\GLSLANG</Filter>
-    </ClInclude>
-    <ClInclude Include="..\..\include\GLES2\gl2ext.h">
-      <Filter>include\GLES2</Filter>
-    </ClInclude>
-    <ClInclude Include="..\..\include\GLES2\gl2.h">
-      <Filter>include\GLES2</Filter>
-    </ClInclude>
-    <ClInclude Include="..\..\include\GLES2\gl2platform.h">
-      <Filter>include\GLES2</Filter>
-    </ClInclude>
-    <ClInclude Include="..\..\include\GLES3\gl3ext.h">
-      <Filter>include\GLES3</Filter>
-    </ClInclude>
-    <ClInclude Include="..\..\include\GLES3\gl3.h">
-      <Filter>include\GLES3</Filter>
-    </ClInclude>
-    <ClInclude Include="..\..\include\GLES3\gl3platform.h">
-      <Filter>include\GLES3</Filter>
-    </ClInclude>
-    <ClInclude Include="..\..\include\EGL\eglext.h">
-      <Filter>include\EGL</Filter>
-    </ClInclude>
-    <ClInclude Include="..\..\include\EGL\egl.h">
-      <Filter>include\EGL</Filter>
-    </ClInclude>
-    <ClInclude Include="..\..\include\EGL\eglplatform.h">
-      <Filter>include\EGL</Filter>
-    </ClInclude>
   </ItemGroup>
 </Project>
diff --git a/projects/src/libGLESv2_static.vcxproj b/projects/src/libGLESv2_static.vcxproj
new file mode 100644
index 0000000..811a3da
--- /dev/null
+++ b/projects/src/libGLESv2_static.vcxproj
@@ -0,0 +1,220 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <ItemGroup Label="ProjectConfigurations">
+    <ProjectConfiguration Include="Debug|Win32">
+      <Configuration>Debug</Configuration>
+      <Platform>Win32</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="Debug|x64">
+      <Configuration>Debug</Configuration>
+      <Platform>x64</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="Release|Win32">
+      <Configuration>Release</Configuration>
+      <Platform>Win32</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="Release|x64">
+      <Configuration>Release</Configuration>
+      <Platform>x64</Platform>
+    </ProjectConfiguration>
+  </ItemGroup>
+  <PropertyGroup Label="Globals">
+    <ProjectGuid>{F8ABD31A-EC2F-A211-D514-076C763B69F9}</ProjectGuid>
+    <Keyword>Win32Proj</Keyword>
+    <RootNamespace>libGLESv2_static</RootNamespace>
+  </PropertyGroup>
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props"/>
+  <PropertyGroup Label="Configuration">
+    <CharacterSet>MultiByte</CharacterSet>
+    <ConfigurationType>StaticLibrary</ConfigurationType>
+  </PropertyGroup>
+  <PropertyGroup Label="Locals">
+    <PlatformToolset>v120</PlatformToolset>
+  </PropertyGroup>
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props"/>
+  <ImportGroup Label="ExtensionSettings"/>
+  <ImportGroup Label="PropertySheets">
+    <Import Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props"/>
+  </ImportGroup>
+  <PropertyGroup Label="UserMacros"/>
+  <PropertyGroup>
+    <ExecutablePath>$(ExecutablePath);$(MSBuildProjectDirectory)\..\..\third_party\cygwin\bin\;$(MSBuildProjectDirectory)\..\..\third_party\python_26\</ExecutablePath>
+    <OutDir>$(SolutionDir)$(Configuration)_$(Platform)\</OutDir>
+    <IntDir>$(OutDir)obj\$(ProjectName)\</IntDir>
+    <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">false</LinkIncremental>
+    <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Release|x64'">false</LinkIncremental>
+    <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</LinkIncremental>
+    <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</LinkIncremental>
+    <TargetName>$(ProjectName)</TargetName>
+    <TargetPath>$(OutDir)lib\$(ProjectName)$(TargetExt)</TargetPath>
+  </PropertyGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+    <ClCompile>
+      <AdditionalIncludeDirectories>$(OutDir)obj\global_intermediate\angle;..\..\src;..\..\include;..\..\src\libGLESv2;C:\Program Files (x86)\Windows Kits\8.0\Include\shared;C:\Program Files (x86)\Windows Kits\8.0\Include\um;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <AdditionalOptions>/MP %(AdditionalOptions)</AdditionalOptions>
+      <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
+      <BufferSecurityCheck>true</BufferSecurityCheck>
+      <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+      <DisableSpecificWarnings>4100;4127;4239;4244;4245;4251;4512;4702;4530;4718;4267;%(DisableSpecificWarnings)</DisableSpecificWarnings>
+      <ExceptionHandling>false</ExceptionHandling>
+      <FunctionLevelLinking>true</FunctionLevelLinking>
+      <MinimalRebuild>false</MinimalRebuild>
+      <Optimization>Disabled</Optimization>
+      <PreprocessorDefinitions>_CRT_SECURE_NO_DEPRECATE;_SCL_SECURE_NO_WARNINGS;NOMINMAX;GL_APICALL=;GL_GLEXT_PROTOTYPES=;EGLAPI=;ANGLE_PRELOADED_D3DCOMPILER_MODULE_NAMES={ &quot;d3dcompiler_46.dll&quot;, &quot;d3dcompiler_43.dll&quot; };_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
+      <RuntimeTypeInfo>true</RuntimeTypeInfo>
+      <TreatWarningAsError>true</TreatWarningAsError>
+      <WarningLevel>Level4</WarningLevel>
+    </ClCompile>
+    <Lib>
+      <AdditionalLibraryDirectories>C:/Program Files (x86)/Windows Kits/8.0/Lib/win8/um/x86;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
+      <OutputFile>$(OutDir)lib\$(ProjectName)$(TargetExt)</OutputFile>
+      <TargetMachine>MachineX86</TargetMachine>
+    </Lib>
+    <Link>
+      <AdditionalDependencies>kernel32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;user32.lib;uuid.lib;odbc32.lib;odbccp32.lib;delayimp.lib</AdditionalDependencies>
+      <AdditionalLibraryDirectories>C:/Program Files (x86)/Windows Kits/8.0/Lib/win8/um/x86;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
+      <FixedBaseAddress>false</FixedBaseAddress>
+      <GenerateDebugInformation>true</GenerateDebugInformation>
+      <ImportLibrary>$(OutDir)lib\$(TargetName).lib</ImportLibrary>
+      <MapFileName>$(OutDir)$(TargetName).map</MapFileName>
+      <SubSystem>Console</SubSystem>
+      <TargetMachine>MachineX86</TargetMachine>
+    </Link>
+    <ResourceCompile>
+      <AdditionalIncludeDirectories>$(OutDir)obj\global_intermediate\angle;..\..\src;..\..\include;..\..\src\libGLESv2;C:\Program Files (x86)\Windows Kits\8.0\Include\shared;C:\Program Files (x86)\Windows Kits\8.0\Include\um;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <Culture>0x0409</Culture>
+      <PreprocessorDefinitions>GL_APICALL=;GL_GLEXT_PROTOTYPES=;EGLAPI=;ANGLE_PRELOADED_D3DCOMPILER_MODULE_NAMES={ &quot;d3dcompiler_46.dll&quot;, &quot;d3dcompiler_43.dll&quot; };_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+    </ResourceCompile>
+  </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+    <ClCompile>
+      <AdditionalIncludeDirectories>$(OutDir)obj\global_intermediate\angle;..\..\src;..\..\include;..\..\src\libGLESv2;C:\Program Files (x86)\Windows Kits\8.0\Include\shared;C:\Program Files (x86)\Windows Kits\8.0\Include\um;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <AdditionalOptions>/MP %(AdditionalOptions)</AdditionalOptions>
+      <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
+      <BufferSecurityCheck>true</BufferSecurityCheck>
+      <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+      <DisableSpecificWarnings>4100;4127;4239;4244;4245;4251;4512;4702;4530;4718;4267;%(DisableSpecificWarnings)</DisableSpecificWarnings>
+      <ExceptionHandling>false</ExceptionHandling>
+      <FunctionLevelLinking>true</FunctionLevelLinking>
+      <MinimalRebuild>false</MinimalRebuild>
+      <Optimization>Disabled</Optimization>
+      <PreprocessorDefinitions>_CRT_SECURE_NO_DEPRECATE;_SCL_SECURE_NO_WARNINGS;NOMINMAX;GL_APICALL=;GL_GLEXT_PROTOTYPES=;EGLAPI=;ANGLE_PRELOADED_D3DCOMPILER_MODULE_NAMES={ &quot;d3dcompiler_46.dll&quot;, &quot;d3dcompiler_43.dll&quot; };%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
+      <RuntimeTypeInfo>true</RuntimeTypeInfo>
+      <TreatWarningAsError>true</TreatWarningAsError>
+      <WarningLevel>Level4</WarningLevel>
+    </ClCompile>
+    <Lib>
+      <AdditionalLibraryDirectories>C:/Program Files (x86)/Windows Kits/8.0/Lib/win8/um/x64;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
+      <OutputFile>$(OutDir)lib\$(ProjectName)$(TargetExt)</OutputFile>
+    </Lib>
+    <Link>
+      <AdditionalDependencies>kernel32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;user32.lib;uuid.lib;odbc32.lib;odbccp32.lib;delayimp.lib</AdditionalDependencies>
+      <AdditionalLibraryDirectories>C:/Program Files (x86)/Windows Kits/8.0/Lib/win8/um/x64;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
+      <FixedBaseAddress>false</FixedBaseAddress>
+      <GenerateDebugInformation>true</GenerateDebugInformation>
+      <ImportLibrary>$(OutDir)lib\$(TargetName).lib</ImportLibrary>
+      <MapFileName>$(OutDir)$(TargetName).map</MapFileName>
+      <SubSystem>Console</SubSystem>
+      <TargetMachine>MachineX64</TargetMachine>
+    </Link>
+    <ResourceCompile>
+      <AdditionalIncludeDirectories>$(OutDir)obj\global_intermediate\angle;..\..\src;..\..\include;..\..\src\libGLESv2;C:\Program Files (x86)\Windows Kits\8.0\Include\shared;C:\Program Files (x86)\Windows Kits\8.0\Include\um;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <Culture>0x0409</Culture>
+      <PreprocessorDefinitions>GL_APICALL=;GL_GLEXT_PROTOTYPES=;EGLAPI=;ANGLE_PRELOADED_D3DCOMPILER_MODULE_NAMES={ &quot;d3dcompiler_46.dll&quot;, &quot;d3dcompiler_43.dll&quot; };%(PreprocessorDefinitions)</PreprocessorDefinitions>
+    </ResourceCompile>
+  </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+    <ClCompile>
+      <AdditionalIncludeDirectories>$(OutDir)obj\global_intermediate\angle;..\..\src;..\..\include;..\..\src\libGLESv2;C:\Program Files (x86)\Windows Kits\8.0\Include\shared;C:\Program Files (x86)\Windows Kits\8.0\Include\um;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <AdditionalOptions>/MP %(AdditionalOptions)</AdditionalOptions>
+      <BufferSecurityCheck>true</BufferSecurityCheck>
+      <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+      <DisableSpecificWarnings>4100;4127;4239;4244;4245;4251;4512;4702;4530;4718;4267;%(DisableSpecificWarnings)</DisableSpecificWarnings>
+      <ExceptionHandling>false</ExceptionHandling>
+      <FunctionLevelLinking>true</FunctionLevelLinking>
+      <MinimalRebuild>false</MinimalRebuild>
+      <Optimization>MaxSpeed</Optimization>
+      <PreprocessorDefinitions>_CRT_SECURE_NO_DEPRECATE;_SCL_SECURE_NO_WARNINGS;NOMINMAX;GL_APICALL=;GL_GLEXT_PROTOTYPES=;EGLAPI=;ANGLE_PRELOADED_D3DCOMPILER_MODULE_NAMES={ &quot;d3dcompiler_46.dll&quot;, &quot;d3dcompiler_43.dll&quot; };NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <RuntimeLibrary>MultiThreaded</RuntimeLibrary>
+      <RuntimeTypeInfo>true</RuntimeTypeInfo>
+      <TreatWarningAsError>true</TreatWarningAsError>
+      <WarningLevel>Level4</WarningLevel>
+    </ClCompile>
+    <Lib>
+      <AdditionalLibraryDirectories>C:/Program Files (x86)/Windows Kits/8.0/Lib/win8/um/x86;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
+      <OutputFile>$(OutDir)lib\$(ProjectName)$(TargetExt)</OutputFile>
+      <TargetMachine>MachineX86</TargetMachine>
+    </Lib>
+    <Link>
+      <AdditionalDependencies>kernel32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;user32.lib;uuid.lib;odbc32.lib;odbccp32.lib;delayimp.lib</AdditionalDependencies>
+      <AdditionalLibraryDirectories>C:/Program Files (x86)/Windows Kits/8.0/Lib/win8/um/x86;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
+      <FixedBaseAddress>false</FixedBaseAddress>
+      <GenerateDebugInformation>false</GenerateDebugInformation>
+      <ImportLibrary>$(OutDir)lib\$(TargetName).lib</ImportLibrary>
+      <MapFileName>$(OutDir)$(TargetName).map</MapFileName>
+      <SubSystem>Console</SubSystem>
+      <TargetMachine>MachineX86</TargetMachine>
+    </Link>
+    <ResourceCompile>
+      <AdditionalIncludeDirectories>$(OutDir)obj\global_intermediate\angle;..\..\src;..\..\include;..\..\src\libGLESv2;C:\Program Files (x86)\Windows Kits\8.0\Include\shared;C:\Program Files (x86)\Windows Kits\8.0\Include\um;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <Culture>0x0409</Culture>
+      <PreprocessorDefinitions>GL_APICALL=;GL_GLEXT_PROTOTYPES=;EGLAPI=;ANGLE_PRELOADED_D3DCOMPILER_MODULE_NAMES={ &quot;d3dcompiler_46.dll&quot;, &quot;d3dcompiler_43.dll&quot; };NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+    </ResourceCompile>
+  </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+    <ClCompile>
+      <AdditionalIncludeDirectories>$(OutDir)obj\global_intermediate\angle;..\..\src;..\..\include;..\..\src\libGLESv2;C:\Program Files (x86)\Windows Kits\8.0\Include\shared;C:\Program Files (x86)\Windows Kits\8.0\Include\um;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <AdditionalOptions>/MP %(AdditionalOptions)</AdditionalOptions>
+      <BufferSecurityCheck>true</BufferSecurityCheck>
+      <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+      <DisableSpecificWarnings>4100;4127;4239;4244;4245;4251;4512;4702;4530;4718;4267;%(DisableSpecificWarnings)</DisableSpecificWarnings>
+      <ExceptionHandling>false</ExceptionHandling>
+      <FunctionLevelLinking>true</FunctionLevelLinking>
+      <MinimalRebuild>false</MinimalRebuild>
+      <Optimization>MaxSpeed</Optimization>
+      <PreprocessorDefinitions>_CRT_SECURE_NO_DEPRECATE;_SCL_SECURE_NO_WARNINGS;NOMINMAX;GL_APICALL=;GL_GLEXT_PROTOTYPES=;EGLAPI=;ANGLE_PRELOADED_D3DCOMPILER_MODULE_NAMES={ &quot;d3dcompiler_46.dll&quot;, &quot;d3dcompiler_43.dll&quot; };%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <RuntimeLibrary>MultiThreaded</RuntimeLibrary>
+      <RuntimeTypeInfo>true</RuntimeTypeInfo>
+      <TreatWarningAsError>true</TreatWarningAsError>
+      <WarningLevel>Level4</WarningLevel>
+    </ClCompile>
+    <Lib>
+      <AdditionalLibraryDirectories>C:/Program Files (x86)/Windows Kits/8.0/Lib/win8/um/x64;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
+      <OutputFile>$(OutDir)lib\$(ProjectName)$(TargetExt)</OutputFile>
+    </Lib>
+    <Link>
+      <AdditionalDependencies>kernel32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;user32.lib;uuid.lib;odbc32.lib;odbccp32.lib;delayimp.lib</AdditionalDependencies>
+      <AdditionalLibraryDirectories>C:/Program Files (x86)/Windows Kits/8.0/Lib/win8/um/x64;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
+      <FixedBaseAddress>false</FixedBaseAddress>
+      <GenerateDebugInformation>false</GenerateDebugInformation>
+      <ImportLibrary>$(OutDir)lib\$(TargetName).lib</ImportLibrary>
+      <MapFileName>$(OutDir)$(TargetName).map</MapFileName>
+      <SubSystem>Console</SubSystem>
+      <TargetMachine>MachineX64</TargetMachine>
+    </Link>
+    <ResourceCompile>
+      <AdditionalIncludeDirectories>$(OutDir)obj\global_intermediate\angle;..\..\src;..\..\include;..\..\src\libGLESv2;C:\Program Files (x86)\Windows Kits\8.0\Include\shared;C:\Program Files (x86)\Windows Kits\8.0\Include\um;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <Culture>0x0409</Culture>
+      <PreprocessorDefinitions>GL_APICALL=;GL_GLEXT_PROTOTYPES=;EGLAPI=;ANGLE_PRELOADED_D3DCOMPILER_MODULE_NAMES={ &quot;d3dcompiler_46.dll&quot;, &quot;d3dcompiler_43.dll&quot; };%(PreprocessorDefinitions)</PreprocessorDefinitions>
+    </ResourceCompile>
+  </ItemDefinitionGroup>
+  <ItemGroup>
+    <None Include="..\..\src\angle.gyp"/>
+  </ItemGroup>
+  <ItemGroup>
+    <ClCompile Include="..\..\src\libGLESv2\libGLESv2.cpp"/>
+  </ItemGroup>
+  <ItemGroup>
+    <ResourceCompile Include="..\..\src\libGLESv2\libGLESv2.rc"/>
+  </ItemGroup>
+  <ItemGroup>
+    <ProjectReference Include="commit_id.vcxproj">
+      <Project>{3B7F5656-177F-52EE-26B3-D6A75368D0A9}</Project>
+      <ReferenceOutputAssembly>false</ReferenceOutputAssembly>
+    </ProjectReference>
+  </ItemGroup>
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets"/>
+  <ImportGroup Label="ExtensionTargets"/>
+</Project>
diff --git a/projects/src/libGLESv2_static.vcxproj.filters b/projects/src/libGLESv2_static.vcxproj.filters
new file mode 100644
index 0000000..69b1a1d
--- /dev/null
+++ b/projects/src/libGLESv2_static.vcxproj.filters
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <ItemGroup>
+    <Filter Include="libGLESv2">
+      <UniqueIdentifier>{A62A9415-2E9D-A6D2-631D-1F25A5CD626F}</UniqueIdentifier>
+    </Filter>
+  </ItemGroup>
+  <ItemGroup>
+    <None Include="..\..\src\angle.gyp"/>
+    <ResourceCompile Include="..\..\src\libGLESv2\libGLESv2.rc">
+      <Filter>libGLESv2</Filter>
+    </ResourceCompile>
+    <ClCompile Include="..\..\src\libGLESv2\libGLESv2.cpp">
+      <Filter>libGLESv2</Filter>
+    </ClCompile>
+  </ItemGroup>
+</Project>
diff --git a/projects/src/preprocessor.vcxproj b/projects/src/preprocessor.vcxproj
index 951e0e5..fc818cf 100644
--- a/projects/src/preprocessor.vcxproj
+++ b/projects/src/preprocessor.vcxproj
@@ -69,6 +69,7 @@
     <Lib>
       <AdditionalLibraryDirectories>C:/Program Files (x86)/Windows Kits/8.0/Lib/win8/um/x86;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
       <OutputFile>$(OutDir)lib\$(ProjectName)$(TargetExt)</OutputFile>
+      <TargetMachine>MachineX86</TargetMachine>
     </Lib>
     <Link>
       <AdditionalDependencies>kernel32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;user32.lib;uuid.lib;odbc32.lib;odbccp32.lib;delayimp.lib</AdditionalDependencies>
@@ -143,6 +144,7 @@
     <Lib>
       <AdditionalLibraryDirectories>C:/Program Files (x86)/Windows Kits/8.0/Lib/win8/um/x86;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
       <OutputFile>$(OutDir)lib\$(ProjectName)$(TargetExt)</OutputFile>
+      <TargetMachine>MachineX86</TargetMachine>
     </Lib>
     <Link>
       <AdditionalDependencies>kernel32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;user32.lib;uuid.lib;odbc32.lib;odbccp32.lib;delayimp.lib</AdditionalDependencies>
diff --git a/projects/src/translator.vcxproj b/projects/src/translator.vcxproj
index 91fb7ff..3258264 100644
--- a/projects/src/translator.vcxproj
+++ b/projects/src/translator.vcxproj
@@ -69,6 +69,7 @@
     <Lib>
       <AdditionalLibraryDirectories>C:/Program Files (x86)/Windows Kits/8.0/Lib/win8/um/x86;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
       <OutputFile>$(OutDir)lib\$(ProjectName)$(TargetExt)</OutputFile>
+      <TargetMachine>MachineX86</TargetMachine>
     </Lib>
     <Link>
       <AdditionalDependencies>kernel32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;user32.lib;uuid.lib;odbc32.lib;odbccp32.lib;delayimp.lib</AdditionalDependencies>
@@ -144,6 +145,7 @@
     <Lib>
       <AdditionalLibraryDirectories>C:/Program Files (x86)/Windows Kits/8.0/Lib/win8/um/x86;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
       <OutputFile>$(OutDir)lib\$(ProjectName)$(TargetExt)</OutputFile>
+      <TargetMachine>MachineX86</TargetMachine>
     </Lib>
     <Link>
       <AdditionalDependencies>kernel32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;user32.lib;uuid.lib;odbc32.lib;odbccp32.lib;delayimp.lib</AdditionalDependencies>
diff --git a/projects/src/translator_lib.vcxproj b/projects/src/translator_lib.vcxproj
index a27f70c..259d91a 100644
--- a/projects/src/translator_lib.vcxproj
+++ b/projects/src/translator_lib.vcxproj
@@ -70,6 +70,7 @@
       <AdditionalLibraryDirectories>C:/Program Files (x86)/Windows Kits/8.0/Lib/win8/um/x86;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
       <AdditionalOptions>/ignore:4221 %(AdditionalOptions)</AdditionalOptions>
       <OutputFile>$(OutDir)lib\$(ProjectName)$(TargetExt)</OutputFile>
+      <TargetMachine>MachineX86</TargetMachine>
     </Lib>
     <Link>
       <AdditionalDependencies>kernel32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;user32.lib;uuid.lib;odbc32.lib;odbccp32.lib;delayimp.lib</AdditionalDependencies>
@@ -147,6 +148,7 @@
       <AdditionalLibraryDirectories>C:/Program Files (x86)/Windows Kits/8.0/Lib/win8/um/x86;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
       <AdditionalOptions>/ignore:4221 %(AdditionalOptions)</AdditionalOptions>
       <OutputFile>$(OutDir)lib\$(ProjectName)$(TargetExt)</OutputFile>
+      <TargetMachine>MachineX86</TargetMachine>
     </Lib>
     <Link>
       <AdditionalDependencies>kernel32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;user32.lib;uuid.lib;odbc32.lib;odbccp32.lib;delayimp.lib</AdditionalDependencies>
@@ -247,9 +249,10 @@
     <ClInclude Include="..\..\src\compiler\translator\NodeSearch.h"/>
     <ClInclude Include="..\..\src\compiler\translator\TranslatorESSL.h"/>
     <ClInclude Include="..\..\src\compiler\translator\InitializeDll.h"/>
+    <ClInclude Include="..\..\src\compiler\translator\IntermNode.h"/>
     <ClInclude Include="..\..\src\compiler\translator\ValidateOutputs.h"/>
+    <ClInclude Include="..\..\src\compiler\translator\Intermediate.h"/>
     <ClInclude Include="..\..\src\compiler\translator\InitializeVariables.h"/>
-    <ClInclude Include="..\..\src\compiler\translator\localintermediate.h"/>
     <ClInclude Include="..\..\src\compiler\translator\OutputGLSLBase.h"/>
     <ClInclude Include="..\..\src\compiler\translator\ForLoopUnroll.h"/>
     <ClInclude Include="..\..\src\compiler\translator\Pragma.h"/>
@@ -259,10 +262,10 @@
     <ClInclude Include="..\..\src\compiler\translator\StructureHLSL.h"/>
     <ClInclude Include="..\..\src\compiler\translator\ValidateLimitations.h"/>
     <ClInclude Include="..\..\src\compiler\translator\Types.h"/>
-    <ClInclude Include="..\..\src\compiler\translator\InfoSink.h"/>
+    <ClInclude Include="..\..\src\compiler\translator\MMap.h"/>
     <ClInclude Include="..\..\src\compiler\translator\RemoveTree.h"/>
     <ClInclude Include="..\..\src\compiler\translator\DetectCallDepth.h"/>
-    <ClInclude Include="..\..\src\compiler\translator\MMap.h"/>
+    <ClInclude Include="..\..\src\compiler\translator\InfoSink.h"/>
     <ClInclude Include="..\..\src\compiler\translator\VariablePacker.h"/>
     <ClInclude Include="..\..\src\compiler\translator\glslang.h"/>
     <ClInclude Include="..\..\src\compiler\translator\SearchSymbol.h"/>
@@ -336,6 +339,7 @@
     <ClCompile Include="..\..\src\compiler\translator\CodeGen.cpp"/>
     <ClCompile Include="..\..\src\compiler\translator\Intermediate.cpp"/>
     <ClCompile Include="..\..\src\compiler\translator\IntermTraverse.cpp"/>
+    <ClCompile Include="..\..\src\compiler\translator\IntermNode.cpp"/>
     <ClCompile Include="..\..\src\compiler\translator\intermOut.cpp"/>
     <ClCompile Include="..\..\src\compiler\translator\glslang_tab.cpp"/>
     <ClCompile Include="..\..\src\compiler\translator\ForLoopUnroll.cpp"/>
diff --git a/projects/src/translator_lib.vcxproj.filters b/projects/src/translator_lib.vcxproj.filters
index b12b1b8..0a85957 100644
--- a/projects/src/translator_lib.vcxproj.filters
+++ b/projects/src/translator_lib.vcxproj.filters
@@ -249,13 +249,16 @@
     <ClInclude Include="..\..\src\compiler\translator\InitializeDll.h">
       <Filter>src\compiler\translator</Filter>
     </ClInclude>
+    <ClInclude Include="..\..\src\compiler\translator\IntermNode.h">
+      <Filter>src\compiler\translator</Filter>
+    </ClInclude>
     <ClInclude Include="..\..\src\compiler\translator\ValidateOutputs.h">
       <Filter>src\compiler\translator</Filter>
     </ClInclude>
-    <ClInclude Include="..\..\src\compiler\translator\InitializeVariables.h">
+    <ClInclude Include="..\..\src\compiler\translator\Intermediate.h">
       <Filter>src\compiler\translator</Filter>
     </ClInclude>
-    <ClInclude Include="..\..\src\compiler\translator\localintermediate.h">
+    <ClInclude Include="..\..\src\compiler\translator\InitializeVariables.h">
       <Filter>src\compiler\translator</Filter>
     </ClInclude>
     <ClCompile Include="..\..\src\compiler\translator\RegenerateStructNames.cpp">
@@ -300,7 +303,7 @@
     <ClInclude Include="..\..\src\compiler\translator\Types.h">
       <Filter>src\compiler\translator</Filter>
     </ClInclude>
-    <ClInclude Include="..\..\src\compiler\translator\InfoSink.h">
+    <ClInclude Include="..\..\src\compiler\translator\MMap.h">
       <Filter>src\compiler\translator</Filter>
     </ClInclude>
     <ClInclude Include="..\..\src\compiler\translator\RemoveTree.h">
@@ -315,7 +318,7 @@
     <ClInclude Include="..\..\src\compiler\translator\DetectCallDepth.h">
       <Filter>src\compiler\translator</Filter>
     </ClInclude>
-    <ClInclude Include="..\..\src\compiler\translator\MMap.h">
+    <ClInclude Include="..\..\src\compiler\translator\InfoSink.h">
       <Filter>src\compiler\translator</Filter>
     </ClInclude>
     <ClInclude Include="..\..\src\compiler\translator\VariablePacker.h">
@@ -342,6 +345,9 @@
     <ClCompile Include="..\..\src\compiler\translator\IntermTraverse.cpp">
       <Filter>src\compiler\translator</Filter>
     </ClCompile>
+    <ClCompile Include="..\..\src\compiler\translator\IntermNode.cpp">
+      <Filter>src\compiler\translator</Filter>
+    </ClCompile>
     <None Include="..\..\src\compiler\translator\glslang.l">
       <Filter>src\compiler\translator</Filter>
     </None>
diff --git a/projects/src/translator_static.vcxproj b/projects/src/translator_static.vcxproj
index 8268a31..c723225 100644
--- a/projects/src/translator_static.vcxproj
+++ b/projects/src/translator_static.vcxproj
@@ -69,6 +69,7 @@
     <Lib>
       <AdditionalLibraryDirectories>C:/Program Files (x86)/Windows Kits/8.0/Lib/win8/um/x86;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
       <OutputFile>$(OutDir)lib\$(ProjectName)$(TargetExt)</OutputFile>
+      <TargetMachine>MachineX86</TargetMachine>
     </Lib>
     <Link>
       <AdditionalDependencies>kernel32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;user32.lib;uuid.lib;odbc32.lib;odbccp32.lib;delayimp.lib</AdditionalDependencies>
@@ -144,6 +145,7 @@
     <Lib>
       <AdditionalLibraryDirectories>C:/Program Files (x86)/Windows Kits/8.0/Lib/win8/um/x86;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
       <OutputFile>$(OutDir)lib\$(ProjectName)$(TargetExt)</OutputFile>
+      <TargetMachine>MachineX86</TargetMachine>
     </Lib>
     <Link>
       <AdditionalDependencies>kernel32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;user32.lib;uuid.lib;odbc32.lib;odbccp32.lib;delayimp.lib</AdditionalDependencies>
diff --git a/projects/util/angle_util.vcxproj b/projects/util/angle_util.vcxproj
new file mode 100644
index 0000000..38e9ade
--- /dev/null
+++ b/projects/util/angle_util.vcxproj
@@ -0,0 +1,237 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <ItemGroup Label="ProjectConfigurations">
+    <ProjectConfiguration Include="Debug|Win32">
+      <Configuration>Debug</Configuration>
+      <Platform>Win32</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="Debug|x64">
+      <Configuration>Debug</Configuration>
+      <Platform>x64</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="Release|Win32">
+      <Configuration>Release</Configuration>
+      <Platform>Win32</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="Release|x64">
+      <Configuration>Release</Configuration>
+      <Platform>x64</Platform>
+    </ProjectConfiguration>
+  </ItemGroup>
+  <PropertyGroup Label="Globals">
+    <ProjectGuid>{E4DD691C-228B-A904-A008-10E26DC0F09E}</ProjectGuid>
+    <Keyword>Win32Proj</Keyword>
+    <RootNamespace>angle_util</RootNamespace>
+  </PropertyGroup>
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props"/>
+  <PropertyGroup Label="Configuration">
+    <CharacterSet>MultiByte</CharacterSet>
+    <ConfigurationType>StaticLibrary</ConfigurationType>
+  </PropertyGroup>
+  <PropertyGroup Label="Locals">
+    <PlatformToolset>v120</PlatformToolset>
+  </PropertyGroup>
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props"/>
+  <ImportGroup Label="ExtensionSettings"/>
+  <ImportGroup Label="PropertySheets">
+    <Import Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props"/>
+  </ImportGroup>
+  <PropertyGroup Label="UserMacros"/>
+  <PropertyGroup>
+    <ExecutablePath>$(ExecutablePath);$(MSBuildProjectDirectory)\..\..\third_party\cygwin\bin\;$(MSBuildProjectDirectory)\..\..\third_party\python_26\</ExecutablePath>
+    <OutDir>$(SolutionDir)$(Configuration)_$(Platform)\</OutDir>
+    <IntDir>$(OutDir)obj\$(ProjectName)\</IntDir>
+    <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">false</LinkIncremental>
+    <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Release|x64'">false</LinkIncremental>
+    <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</LinkIncremental>
+    <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</LinkIncremental>
+    <TargetName>$(ProjectName)</TargetName>
+    <TargetPath>$(OutDir)lib\$(ProjectName)$(TargetExt)</TargetPath>
+  </PropertyGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+    <ClCompile>
+      <AdditionalIncludeDirectories>..\..\include;..\..\util;$(OutDir)obj\global_intermediate\angle;C:\Program Files (x86)\Windows Kits\8.0\Include\shared;C:\Program Files (x86)\Windows Kits\8.0\Include\um;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <AdditionalOptions>/MP %(AdditionalOptions)</AdditionalOptions>
+      <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
+      <BufferSecurityCheck>true</BufferSecurityCheck>
+      <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+      <DisableSpecificWarnings>4201;4100;4127;4239;4244;4245;4251;4512;4702;4530;4718;4267;%(DisableSpecificWarnings)</DisableSpecificWarnings>
+      <ExceptionHandling>false</ExceptionHandling>
+      <FunctionLevelLinking>true</FunctionLevelLinking>
+      <MinimalRebuild>false</MinimalRebuild>
+      <Optimization>Disabled</Optimization>
+      <PreprocessorDefinitions>_CRT_SECURE_NO_DEPRECATE;_SCL_SECURE_NO_WARNINGS;NOMINMAX;_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
+      <RuntimeTypeInfo>true</RuntimeTypeInfo>
+      <TreatWarningAsError>true</TreatWarningAsError>
+      <WarningLevel>Level4</WarningLevel>
+    </ClCompile>
+    <Lib>
+      <AdditionalLibraryDirectories>C:/Program Files (x86)/Windows Kits/8.0/Lib/win8/um/x86;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
+      <OutputFile>$(OutDir)lib\$(ProjectName)$(TargetExt)</OutputFile>
+      <TargetMachine>MachineX86</TargetMachine>
+    </Lib>
+    <Link>
+      <AdditionalDependencies>kernel32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;user32.lib;uuid.lib;odbc32.lib;odbccp32.lib;delayimp.lib</AdditionalDependencies>
+      <AdditionalLibraryDirectories>C:/Program Files (x86)/Windows Kits/8.0/Lib/win8/um/x86;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
+      <FixedBaseAddress>false</FixedBaseAddress>
+      <GenerateDebugInformation>true</GenerateDebugInformation>
+      <ImportLibrary>$(OutDir)lib\$(TargetName).lib</ImportLibrary>
+      <MapFileName>$(OutDir)$(TargetName).map</MapFileName>
+      <SubSystem>Console</SubSystem>
+      <TargetMachine>MachineX86</TargetMachine>
+    </Link>
+    <ResourceCompile>
+      <AdditionalIncludeDirectories>..\..\include;..\..\util;$(OutDir)obj\global_intermediate\angle;C:\Program Files (x86)\Windows Kits\8.0\Include\shared;C:\Program Files (x86)\Windows Kits\8.0\Include\um;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <Culture>0x0409</Culture>
+      <PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+    </ResourceCompile>
+  </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+    <ClCompile>
+      <AdditionalIncludeDirectories>..\..\include;..\..\util;$(OutDir)obj\global_intermediate\angle;C:\Program Files (x86)\Windows Kits\8.0\Include\shared;C:\Program Files (x86)\Windows Kits\8.0\Include\um;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <AdditionalOptions>/MP %(AdditionalOptions)</AdditionalOptions>
+      <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
+      <BufferSecurityCheck>true</BufferSecurityCheck>
+      <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+      <DisableSpecificWarnings>4201;4100;4127;4239;4244;4245;4251;4512;4702;4530;4718;4267;%(DisableSpecificWarnings)</DisableSpecificWarnings>
+      <ExceptionHandling>false</ExceptionHandling>
+      <FunctionLevelLinking>true</FunctionLevelLinking>
+      <MinimalRebuild>false</MinimalRebuild>
+      <Optimization>Disabled</Optimization>
+      <PreprocessorDefinitions>_CRT_SECURE_NO_DEPRECATE;_SCL_SECURE_NO_WARNINGS;NOMINMAX;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
+      <RuntimeTypeInfo>true</RuntimeTypeInfo>
+      <TreatWarningAsError>true</TreatWarningAsError>
+      <WarningLevel>Level4</WarningLevel>
+    </ClCompile>
+    <Lib>
+      <AdditionalLibraryDirectories>C:/Program Files (x86)/Windows Kits/8.0/Lib/win8/um/x64;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
+      <OutputFile>$(OutDir)lib\$(ProjectName)$(TargetExt)</OutputFile>
+    </Lib>
+    <Link>
+      <AdditionalDependencies>kernel32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;user32.lib;uuid.lib;odbc32.lib;odbccp32.lib;delayimp.lib</AdditionalDependencies>
+      <AdditionalLibraryDirectories>C:/Program Files (x86)/Windows Kits/8.0/Lib/win8/um/x64;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
+      <FixedBaseAddress>false</FixedBaseAddress>
+      <GenerateDebugInformation>true</GenerateDebugInformation>
+      <ImportLibrary>$(OutDir)lib\$(TargetName).lib</ImportLibrary>
+      <MapFileName>$(OutDir)$(TargetName).map</MapFileName>
+      <SubSystem>Console</SubSystem>
+      <TargetMachine>MachineX64</TargetMachine>
+    </Link>
+    <ResourceCompile>
+      <AdditionalIncludeDirectories>..\..\include;..\..\util;$(OutDir)obj\global_intermediate\angle;C:\Program Files (x86)\Windows Kits\8.0\Include\shared;C:\Program Files (x86)\Windows Kits\8.0\Include\um;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <Culture>0x0409</Culture>
+    </ResourceCompile>
+  </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+    <ClCompile>
+      <AdditionalIncludeDirectories>..\..\include;..\..\util;$(OutDir)obj\global_intermediate\angle;C:\Program Files (x86)\Windows Kits\8.0\Include\shared;C:\Program Files (x86)\Windows Kits\8.0\Include\um;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <AdditionalOptions>/MP %(AdditionalOptions)</AdditionalOptions>
+      <BufferSecurityCheck>true</BufferSecurityCheck>
+      <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+      <DisableSpecificWarnings>4201;4100;4127;4239;4244;4245;4251;4512;4702;4530;4718;4267;%(DisableSpecificWarnings)</DisableSpecificWarnings>
+      <ExceptionHandling>false</ExceptionHandling>
+      <FunctionLevelLinking>true</FunctionLevelLinking>
+      <MinimalRebuild>false</MinimalRebuild>
+      <Optimization>MaxSpeed</Optimization>
+      <PreprocessorDefinitions>_CRT_SECURE_NO_DEPRECATE;_SCL_SECURE_NO_WARNINGS;NOMINMAX;NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <RuntimeLibrary>MultiThreaded</RuntimeLibrary>
+      <RuntimeTypeInfo>true</RuntimeTypeInfo>
+      <TreatWarningAsError>true</TreatWarningAsError>
+      <WarningLevel>Level4</WarningLevel>
+    </ClCompile>
+    <Lib>
+      <AdditionalLibraryDirectories>C:/Program Files (x86)/Windows Kits/8.0/Lib/win8/um/x86;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
+      <OutputFile>$(OutDir)lib\$(ProjectName)$(TargetExt)</OutputFile>
+      <TargetMachine>MachineX86</TargetMachine>
+    </Lib>
+    <Link>
+      <AdditionalDependencies>kernel32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;user32.lib;uuid.lib;odbc32.lib;odbccp32.lib;delayimp.lib</AdditionalDependencies>
+      <AdditionalLibraryDirectories>C:/Program Files (x86)/Windows Kits/8.0/Lib/win8/um/x86;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
+      <FixedBaseAddress>false</FixedBaseAddress>
+      <GenerateDebugInformation>false</GenerateDebugInformation>
+      <ImportLibrary>$(OutDir)lib\$(TargetName).lib</ImportLibrary>
+      <MapFileName>$(OutDir)$(TargetName).map</MapFileName>
+      <SubSystem>Console</SubSystem>
+      <TargetMachine>MachineX86</TargetMachine>
+    </Link>
+    <ResourceCompile>
+      <AdditionalIncludeDirectories>..\..\include;..\..\util;$(OutDir)obj\global_intermediate\angle;C:\Program Files (x86)\Windows Kits\8.0\Include\shared;C:\Program Files (x86)\Windows Kits\8.0\Include\um;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <Culture>0x0409</Culture>
+      <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+    </ResourceCompile>
+  </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+    <ClCompile>
+      <AdditionalIncludeDirectories>..\..\include;..\..\util;$(OutDir)obj\global_intermediate\angle;C:\Program Files (x86)\Windows Kits\8.0\Include\shared;C:\Program Files (x86)\Windows Kits\8.0\Include\um;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <AdditionalOptions>/MP %(AdditionalOptions)</AdditionalOptions>
+      <BufferSecurityCheck>true</BufferSecurityCheck>
+      <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+      <DisableSpecificWarnings>4201;4100;4127;4239;4244;4245;4251;4512;4702;4530;4718;4267;%(DisableSpecificWarnings)</DisableSpecificWarnings>
+      <ExceptionHandling>false</ExceptionHandling>
+      <FunctionLevelLinking>true</FunctionLevelLinking>
+      <MinimalRebuild>false</MinimalRebuild>
+      <Optimization>MaxSpeed</Optimization>
+      <PreprocessorDefinitions>_CRT_SECURE_NO_DEPRECATE;_SCL_SECURE_NO_WARNINGS;NOMINMAX;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <RuntimeLibrary>MultiThreaded</RuntimeLibrary>
+      <RuntimeTypeInfo>true</RuntimeTypeInfo>
+      <TreatWarningAsError>true</TreatWarningAsError>
+      <WarningLevel>Level4</WarningLevel>
+    </ClCompile>
+    <Lib>
+      <AdditionalLibraryDirectories>C:/Program Files (x86)/Windows Kits/8.0/Lib/win8/um/x64;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
+      <OutputFile>$(OutDir)lib\$(ProjectName)$(TargetExt)</OutputFile>
+    </Lib>
+    <Link>
+      <AdditionalDependencies>kernel32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;user32.lib;uuid.lib;odbc32.lib;odbccp32.lib;delayimp.lib</AdditionalDependencies>
+      <AdditionalLibraryDirectories>C:/Program Files (x86)/Windows Kits/8.0/Lib/win8/um/x64;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
+      <FixedBaseAddress>false</FixedBaseAddress>
+      <GenerateDebugInformation>false</GenerateDebugInformation>
+      <ImportLibrary>$(OutDir)lib\$(TargetName).lib</ImportLibrary>
+      <MapFileName>$(OutDir)$(TargetName).map</MapFileName>
+      <SubSystem>Console</SubSystem>
+      <TargetMachine>MachineX64</TargetMachine>
+    </Link>
+    <ResourceCompile>
+      <AdditionalIncludeDirectories>..\..\include;..\..\util;$(OutDir)obj\global_intermediate\angle;C:\Program Files (x86)\Windows Kits\8.0\Include\shared;C:\Program Files (x86)\Windows Kits\8.0\Include\um;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <Culture>0x0409</Culture>
+    </ResourceCompile>
+  </ItemDefinitionGroup>
+  <ItemGroup>
+    <None Include="..\..\util\util.gyp"/>
+  </ItemGroup>
+  <ItemGroup>
+    <ClInclude Include="..\..\util\mouse.h"/>
+    <ClInclude Include="..\..\util\shared_utils.h"/>
+    <ClInclude Include="..\..\util\Timer.h"/>
+    <ClInclude Include="..\..\util\EGLWindow.h"/>
+    <ClInclude Include="..\..\util\path_utils.h"/>
+    <ClInclude Include="..\..\util\shader_utils.h"/>
+    <ClInclude Include="..\..\util\OSWindow.h"/>
+    <ClInclude Include="..\..\util\keyboard.h"/>
+    <ClInclude Include="..\..\util\Event.h"/>
+    <ClInclude Include="..\..\util\win32\Win32Window.h"/>
+    <ClInclude Include="..\..\util\win32\Win32Timer.h"/>
+  </ItemGroup>
+  <ItemGroup>
+    <ClCompile Include="..\..\util\shader_utils.cpp"/>
+    <ClCompile Include="..\..\util\OSWindow.cpp"/>
+    <ClCompile Include="..\..\util\EGLWindow.cpp"/>
+    <ClCompile Include="..\..\util\win32\Win32_path_utils.cpp"/>
+    <ClCompile Include="..\..\util\win32\Win32Window.cpp"/>
+    <ClCompile Include="..\..\util\win32\Win32Timer.cpp"/>
+  </ItemGroup>
+  <ItemGroup>
+    <ProjectReference Include="..\src\libEGL.vcxproj">
+      <Project>{FBAEE4F6-562A-588F-01F9-72DCABB3B061}</Project>
+      <ReferenceOutputAssembly>false</ReferenceOutputAssembly>
+    </ProjectReference>
+    <ProjectReference Include="..\src\libGLESv2.vcxproj">
+      <Project>{7FBD6F69-B9A4-69F1-A12B-8DACB3F8CD81}</Project>
+      <ReferenceOutputAssembly>false</ReferenceOutputAssembly>
+    </ProjectReference>
+  </ItemGroup>
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets"/>
+  <ImportGroup Label="ExtensionTargets"/>
+</Project>
diff --git a/projects/util/angle_util.vcxproj.filters b/projects/util/angle_util.vcxproj.filters
new file mode 100644
index 0000000..f32e6de
--- /dev/null
+++ b/projects/util/angle_util.vcxproj.filters
@@ -0,0 +1,38 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <ItemGroup>
+    <Filter Include="win32">
+      <UniqueIdentifier>{789FEF16-EFE7-512E-F91B-DF7E0D72FB79}</UniqueIdentifier>
+    </Filter>
+  </ItemGroup>
+  <ItemGroup>
+    <ClInclude Include="..\..\util\mouse.h"/>
+    <ClInclude Include="..\..\util\shared_utils.h"/>
+    <ClInclude Include="..\..\util\Timer.h"/>
+    <ClInclude Include="..\..\util\EGLWindow.h"/>
+    <ClInclude Include="..\..\util\path_utils.h"/>
+    <None Include="..\..\util\util.gyp"/>
+    <ClInclude Include="..\..\util\shader_utils.h"/>
+    <ClCompile Include="..\..\util\shader_utils.cpp"/>
+    <ClInclude Include="..\..\util\OSWindow.h"/>
+    <ClCompile Include="..\..\util\OSWindow.cpp"/>
+    <ClInclude Include="..\..\util\keyboard.h"/>
+    <ClCompile Include="..\..\util\EGLWindow.cpp"/>
+    <ClInclude Include="..\..\util\Event.h"/>
+    <ClCompile Include="..\..\util\win32\Win32_path_utils.cpp">
+      <Filter>win32</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\util\win32\Win32Window.cpp">
+      <Filter>win32</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\util\win32\Win32Timer.cpp">
+      <Filter>win32</Filter>
+    </ClCompile>
+    <ClInclude Include="..\..\util\win32\Win32Window.h">
+      <Filter>win32</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\util\win32\Win32Timer.h">
+      <Filter>win32</Filter>
+    </ClInclude>
+  </ItemGroup>
+</Project>
diff --git a/projects/util/util.sln b/projects/util/util.sln
new file mode 100644
index 0000000..abf3267
--- /dev/null
+++ b/projects/util/util.sln
@@ -0,0 +1,139 @@
+Microsoft Visual Studio Solution File, Format Version 13.00
+# Visual Studio 2013
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "angle_util", "angle_util.vcxproj", "{E4DD691C-228B-A904-A008-10E26DC0F09E}"
+	ProjectSection(ProjectDependencies) = postProject
+		{FBAEE4F6-562A-588F-01F9-72DCABB3B061} = {FBAEE4F6-562A-588F-01F9-72DCABB3B061}
+		{7FBD6F69-B9A4-69F1-A12B-8DACB3F8CD81} = {7FBD6F69-B9A4-69F1-A12B-8DACB3F8CD81}
+	EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "commit_id", "..\src\commit_id.vcxproj", "{3B7F5656-177F-52EE-26B3-D6A75368D0A9}"
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "copy_compiler_dll", "..\src\copy_compiler_dll.vcxproj", "{22DC02D5-1598-943C-13E1-82185B469F81}"
+	ProjectSection(ProjectDependencies) = postProject
+		{63FB0B97-D1D9-5158-8E85-7F5B1E403817} = {63FB0B97-D1D9-5158-8E85-7F5B1E403817}
+	EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "copy_scripts", "..\src\copy_scripts.vcxproj", "{63FB0B97-D1D9-5158-8E85-7F5B1E403817}"
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libANGLE", "..\src\libANGLE.vcxproj", "{CAAA04EE-A56A-43FB-D011-1A56053C070C}"
+	ProjectSection(ProjectDependencies) = postProject
+		{3B7F5656-177F-52EE-26B3-D6A75368D0A9} = {3B7F5656-177F-52EE-26B3-D6A75368D0A9}
+		{22DC02D5-1598-943C-13E1-82185B469F81} = {22DC02D5-1598-943C-13E1-82185B469F81}
+	EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libEGL", "..\src\libEGL.vcxproj", "{FBAEE4F6-562A-588F-01F9-72DCABB3B061}"
+	ProjectSection(ProjectDependencies) = postProject
+		{7FBD6F69-B9A4-69F1-A12B-8DACB3F8CD81} = {7FBD6F69-B9A4-69F1-A12B-8DACB3F8CD81}
+		{3B7F5656-177F-52EE-26B3-D6A75368D0A9} = {3B7F5656-177F-52EE-26B3-D6A75368D0A9}
+	EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libGLESv2", "..\src\libGLESv2.vcxproj", "{7FBD6F69-B9A4-69F1-A12B-8DACB3F8CD81}"
+	ProjectSection(ProjectDependencies) = postProject
+		{CAAA04EE-A56A-43FB-D011-1A56053C070C} = {CAAA04EE-A56A-43FB-D011-1A56053C070C}
+		{C15697F6-5057-016E-BD29-422971875679} = {C15697F6-5057-016E-BD29-422971875679}
+		{276D20F5-2943-414C-0FF6-21F4723A5CF6} = {276D20F5-2943-414C-0FF6-21F4723A5CF6}
+		{C7BAF548-697D-2DCB-9DF3-9D1506A7B444} = {C7BAF548-697D-2DCB-9DF3-9D1506A7B444}
+		{3B7F5656-177F-52EE-26B3-D6A75368D0A9} = {3B7F5656-177F-52EE-26B3-D6A75368D0A9}
+		{22DC02D5-1598-943C-13E1-82185B469F81} = {22DC02D5-1598-943C-13E1-82185B469F81}
+		{63FB0B97-D1D9-5158-8E85-7F5B1E403817} = {63FB0B97-D1D9-5158-8E85-7F5B1E403817}
+	EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "preprocessor", "..\src\preprocessor.vcxproj", "{C7BAF548-697D-2DCB-9DF3-9D1506A7B444}"
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "translator", "..\src\translator.vcxproj", "{C15697F6-5057-016E-BD29-422971875679}"
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "translator_lib", "..\src\translator_lib.vcxproj", "{276D20F5-2943-414C-0FF6-21F4723A5CF6}"
+EndProject
+Global
+	GlobalSection(SolutionConfigurationPlatforms) = preSolution
+		Debug|x64 = Debug|x64
+		Debug|Win32 = Debug|Win32
+		Release|x64 = Release|x64
+		Release|Win32 = Release|Win32
+	EndGlobalSection
+	GlobalSection(ProjectConfigurationPlatforms) = postSolution
+		{22DC02D5-1598-943C-13E1-82185B469F81}.Debug|x64.ActiveCfg = Debug|x64
+		{22DC02D5-1598-943C-13E1-82185B469F81}.Debug|x64.Build.0 = Debug|x64
+		{22DC02D5-1598-943C-13E1-82185B469F81}.Debug|Win32.ActiveCfg = Debug|Win32
+		{22DC02D5-1598-943C-13E1-82185B469F81}.Debug|Win32.Build.0 = Debug|Win32
+		{22DC02D5-1598-943C-13E1-82185B469F81}.Release|x64.ActiveCfg = Release|x64
+		{22DC02D5-1598-943C-13E1-82185B469F81}.Release|x64.Build.0 = Release|x64
+		{22DC02D5-1598-943C-13E1-82185B469F81}.Release|Win32.ActiveCfg = Release|Win32
+		{22DC02D5-1598-943C-13E1-82185B469F81}.Release|Win32.Build.0 = Release|Win32
+		{276D20F5-2943-414C-0FF6-21F4723A5CF6}.Debug|x64.ActiveCfg = Debug|x64
+		{276D20F5-2943-414C-0FF6-21F4723A5CF6}.Debug|x64.Build.0 = Debug|x64
+		{276D20F5-2943-414C-0FF6-21F4723A5CF6}.Debug|Win32.ActiveCfg = Debug|Win32
+		{276D20F5-2943-414C-0FF6-21F4723A5CF6}.Debug|Win32.Build.0 = Debug|Win32
+		{276D20F5-2943-414C-0FF6-21F4723A5CF6}.Release|x64.ActiveCfg = Release|x64
+		{276D20F5-2943-414C-0FF6-21F4723A5CF6}.Release|x64.Build.0 = Release|x64
+		{276D20F5-2943-414C-0FF6-21F4723A5CF6}.Release|Win32.ActiveCfg = Release|Win32
+		{276D20F5-2943-414C-0FF6-21F4723A5CF6}.Release|Win32.Build.0 = Release|Win32
+		{3B7F5656-177F-52EE-26B3-D6A75368D0A9}.Debug|x64.ActiveCfg = Debug|x64
+		{3B7F5656-177F-52EE-26B3-D6A75368D0A9}.Debug|x64.Build.0 = Debug|x64
+		{3B7F5656-177F-52EE-26B3-D6A75368D0A9}.Debug|Win32.ActiveCfg = Debug|Win32
+		{3B7F5656-177F-52EE-26B3-D6A75368D0A9}.Debug|Win32.Build.0 = Debug|Win32
+		{3B7F5656-177F-52EE-26B3-D6A75368D0A9}.Release|x64.ActiveCfg = Release|x64
+		{3B7F5656-177F-52EE-26B3-D6A75368D0A9}.Release|x64.Build.0 = Release|x64
+		{3B7F5656-177F-52EE-26B3-D6A75368D0A9}.Release|Win32.ActiveCfg = Release|Win32
+		{3B7F5656-177F-52EE-26B3-D6A75368D0A9}.Release|Win32.Build.0 = Release|Win32
+		{63FB0B97-D1D9-5158-8E85-7F5B1E403817}.Debug|x64.ActiveCfg = Debug|x64
+		{63FB0B97-D1D9-5158-8E85-7F5B1E403817}.Debug|x64.Build.0 = Debug|x64
+		{63FB0B97-D1D9-5158-8E85-7F5B1E403817}.Debug|Win32.ActiveCfg = Debug|Win32
+		{63FB0B97-D1D9-5158-8E85-7F5B1E403817}.Debug|Win32.Build.0 = Debug|Win32
+		{63FB0B97-D1D9-5158-8E85-7F5B1E403817}.Release|x64.ActiveCfg = Release|x64
+		{63FB0B97-D1D9-5158-8E85-7F5B1E403817}.Release|x64.Build.0 = Release|x64
+		{63FB0B97-D1D9-5158-8E85-7F5B1E403817}.Release|Win32.ActiveCfg = Release|Win32
+		{63FB0B97-D1D9-5158-8E85-7F5B1E403817}.Release|Win32.Build.0 = Release|Win32
+		{7FBD6F69-B9A4-69F1-A12B-8DACB3F8CD81}.Debug|x64.ActiveCfg = Debug|x64
+		{7FBD6F69-B9A4-69F1-A12B-8DACB3F8CD81}.Debug|x64.Build.0 = Debug|x64
+		{7FBD6F69-B9A4-69F1-A12B-8DACB3F8CD81}.Debug|Win32.ActiveCfg = Debug|Win32
+		{7FBD6F69-B9A4-69F1-A12B-8DACB3F8CD81}.Debug|Win32.Build.0 = Debug|Win32
+		{7FBD6F69-B9A4-69F1-A12B-8DACB3F8CD81}.Release|x64.ActiveCfg = Release|x64
+		{7FBD6F69-B9A4-69F1-A12B-8DACB3F8CD81}.Release|x64.Build.0 = Release|x64
+		{7FBD6F69-B9A4-69F1-A12B-8DACB3F8CD81}.Release|Win32.ActiveCfg = Release|Win32
+		{7FBD6F69-B9A4-69F1-A12B-8DACB3F8CD81}.Release|Win32.Build.0 = Release|Win32
+		{C15697F6-5057-016E-BD29-422971875679}.Debug|x64.ActiveCfg = Debug|x64
+		{C15697F6-5057-016E-BD29-422971875679}.Debug|x64.Build.0 = Debug|x64
+		{C15697F6-5057-016E-BD29-422971875679}.Debug|Win32.ActiveCfg = Debug|Win32
+		{C15697F6-5057-016E-BD29-422971875679}.Debug|Win32.Build.0 = Debug|Win32
+		{C15697F6-5057-016E-BD29-422971875679}.Release|x64.ActiveCfg = Release|x64
+		{C15697F6-5057-016E-BD29-422971875679}.Release|x64.Build.0 = Release|x64
+		{C15697F6-5057-016E-BD29-422971875679}.Release|Win32.ActiveCfg = Release|Win32
+		{C15697F6-5057-016E-BD29-422971875679}.Release|Win32.Build.0 = Release|Win32
+		{C7BAF548-697D-2DCB-9DF3-9D1506A7B444}.Debug|x64.ActiveCfg = Debug|x64
+		{C7BAF548-697D-2DCB-9DF3-9D1506A7B444}.Debug|x64.Build.0 = Debug|x64
+		{C7BAF548-697D-2DCB-9DF3-9D1506A7B444}.Debug|Win32.ActiveCfg = Debug|Win32
+		{C7BAF548-697D-2DCB-9DF3-9D1506A7B444}.Debug|Win32.Build.0 = Debug|Win32
+		{C7BAF548-697D-2DCB-9DF3-9D1506A7B444}.Release|x64.ActiveCfg = Release|x64
+		{C7BAF548-697D-2DCB-9DF3-9D1506A7B444}.Release|x64.Build.0 = Release|x64
+		{C7BAF548-697D-2DCB-9DF3-9D1506A7B444}.Release|Win32.ActiveCfg = Release|Win32
+		{C7BAF548-697D-2DCB-9DF3-9D1506A7B444}.Release|Win32.Build.0 = Release|Win32
+		{CAAA04EE-A56A-43FB-D011-1A56053C070C}.Debug|x64.ActiveCfg = Debug|x64
+		{CAAA04EE-A56A-43FB-D011-1A56053C070C}.Debug|x64.Build.0 = Debug|x64
+		{CAAA04EE-A56A-43FB-D011-1A56053C070C}.Debug|Win32.ActiveCfg = Debug|Win32
+		{CAAA04EE-A56A-43FB-D011-1A56053C070C}.Debug|Win32.Build.0 = Debug|Win32
+		{CAAA04EE-A56A-43FB-D011-1A56053C070C}.Release|x64.ActiveCfg = Release|x64
+		{CAAA04EE-A56A-43FB-D011-1A56053C070C}.Release|x64.Build.0 = Release|x64
+		{CAAA04EE-A56A-43FB-D011-1A56053C070C}.Release|Win32.ActiveCfg = Release|Win32
+		{CAAA04EE-A56A-43FB-D011-1A56053C070C}.Release|Win32.Build.0 = Release|Win32
+		{E4DD691C-228B-A904-A008-10E26DC0F09E}.Debug|x64.ActiveCfg = Debug|x64
+		{E4DD691C-228B-A904-A008-10E26DC0F09E}.Debug|x64.Build.0 = Debug|x64
+		{E4DD691C-228B-A904-A008-10E26DC0F09E}.Debug|Win32.ActiveCfg = Debug|Win32
+		{E4DD691C-228B-A904-A008-10E26DC0F09E}.Debug|Win32.Build.0 = Debug|Win32
+		{E4DD691C-228B-A904-A008-10E26DC0F09E}.Release|x64.ActiveCfg = Release|x64
+		{E4DD691C-228B-A904-A008-10E26DC0F09E}.Release|x64.Build.0 = Release|x64
+		{E4DD691C-228B-A904-A008-10E26DC0F09E}.Release|Win32.ActiveCfg = Release|Win32
+		{E4DD691C-228B-A904-A008-10E26DC0F09E}.Release|Win32.Build.0 = Release|Win32
+		{FBAEE4F6-562A-588F-01F9-72DCABB3B061}.Debug|x64.ActiveCfg = Debug|x64
+		{FBAEE4F6-562A-588F-01F9-72DCABB3B061}.Debug|x64.Build.0 = Debug|x64
+		{FBAEE4F6-562A-588F-01F9-72DCABB3B061}.Debug|Win32.ActiveCfg = Debug|Win32
+		{FBAEE4F6-562A-588F-01F9-72DCABB3B061}.Debug|Win32.Build.0 = Debug|Win32
+		{FBAEE4F6-562A-588F-01F9-72DCABB3B061}.Release|x64.ActiveCfg = Release|x64
+		{FBAEE4F6-562A-588F-01F9-72DCABB3B061}.Release|x64.Build.0 = Release|x64
+		{FBAEE4F6-562A-588F-01F9-72DCABB3B061}.Release|Win32.ActiveCfg = Release|Win32
+		{FBAEE4F6-562A-588F-01F9-72DCABB3B061}.Release|Win32.Build.0 = Release|Win32
+	EndGlobalSection
+	GlobalSection(SolutionProperties) = preSolution
+		HideSolutionNode = FALSE
+	EndGlobalSection
+EndGlobal
diff --git a/samples/angle/sample_util/SampleApplication.cpp b/samples/angle/sample_util/SampleApplication.cpp
index 4d15b03..e0228fb 100644
--- a/samples/angle/sample_util/SampleApplication.cpp
+++ b/samples/angle/sample_util/SampleApplication.cpp
@@ -5,30 +5,26 @@
 //
 
 #include "SampleApplication.h"
-
-#ifdef _WIN32
-#include "win32/Win32Timer.h"
-#include "win32/Win32Window.h"
-#else
-#error unsupported OS.
-#endif
+#include "EGLWindow.h"
 
 SampleApplication::SampleApplication(const std::string& name, size_t width, size_t height,
                                      EGLint glesMajorVersion, EGLint requestedRenderer)
-    : mSurface(EGL_NO_SURFACE),
-      mContext(EGL_NO_CONTEXT),
-      mDisplay(EGL_NO_DISPLAY),
-      mClientVersion(glesMajorVersion),
-      mRequestedRenderer(requestedRenderer),
-      mWidth(width),
-      mHeight(height),
-      mName(name),
-      mRunning(false),
-#ifdef _WIN32
-      mTimer(new Win32Timer()),
-      mWindow(new Win32Window())
-#endif
+    : mName(name),
+      mRunning(false)
 {
+    mEGLWindow.reset(new EGLWindow(width, height, glesMajorVersion, requestedRenderer));
+    mTimer.reset(CreateTimer());
+    mOSWindow.reset(CreateOSWindow());
+
+    mEGLWindow->setConfigRedBits(8);
+    mEGLWindow->setConfigGreenBits(8);
+    mEGLWindow->setConfigBlueBits(8);
+    mEGLWindow->setConfigAlphaBits(8);
+    mEGLWindow->setConfigDepthBits(24);
+    mEGLWindow->setConfigStencilBits(8);
+
+    // Disable vsync
+    mEGLWindow->setSwapInterval(0);
 }
 
 SampleApplication::~SampleApplication()
@@ -54,42 +50,42 @@
 
 void SampleApplication::swap()
 {
-    eglSwapBuffers(mDisplay, mSurface);
+    mEGLWindow->swap();
 }
 
-Window *SampleApplication::getWindow() const
+OSWindow *SampleApplication::getWindow() const
 {
-    return mWindow.get();
+    return mOSWindow.get();
 }
 
 EGLConfig SampleApplication::getConfig() const
 {
-    return mConfig;
+    return mEGLWindow->getConfig();
 }
 
 EGLDisplay SampleApplication::getDisplay() const
 {
-    return mDisplay;
+    return mEGLWindow->getDisplay();
 }
 
 EGLSurface SampleApplication::getSurface() const
 {
-    return mSurface;
+    return mEGLWindow->getSurface();
 }
 
 EGLContext SampleApplication::getContext() const
 {
-    return mContext;
+    return mEGLWindow->getContext();
 }
 
 int SampleApplication::run()
 {
-    if (!mWindow->initialize(mName, mWidth, mHeight))
+    if (!mOSWindow->initialize(mName, mEGLWindow->getWidth(), mEGLWindow->getHeight()))
     {
         return -1;
     }
 
-    if (!initializeGL())
+    if (!mEGLWindow->initializeGL(mOSWindow.get()))
     {
         return -1;
     }
@@ -132,14 +128,14 @@
         draw();
         swap();
 
-        mWindow->messageLoop();
+        mOSWindow->messageLoop();
 
         prevTime = elapsedTime;
     }
 
     destroy();
-    destroyGL();
-    mWindow->destroy();
+    mEGLWindow->destroyGL();
+    mOSWindow->destroy();
 
     return result;
 }
@@ -151,116 +147,5 @@
 
 bool SampleApplication::popEvent(Event *event)
 {
-    return mWindow->popEvent(event);
-}
-
-bool SampleApplication::initializeGL()
-{
-    PFNEGLGETPLATFORMDISPLAYEXTPROC eglGetPlatformDisplayEXT = reinterpret_cast<PFNEGLGETPLATFORMDISPLAYEXTPROC>(eglGetProcAddress("eglGetPlatformDisplayEXT"));
-    if (!eglGetPlatformDisplayEXT)
-    {
-        return false;
-    }
-
-    const EGLint displayAttributes[] =
-    {
-        EGL_PLATFORM_ANGLE_TYPE_ANGLE, mRequestedRenderer,
-        EGL_NONE,
-    };
-
-    mDisplay = eglGetPlatformDisplayEXT(EGL_PLATFORM_ANGLE_ANGLE, mWindow->getNativeDisplay(), displayAttributes);
-    if (mDisplay == EGL_NO_DISPLAY)
-    {
-        destroyGL();
-        return false;
-    }
-
-    EGLint majorVersion, minorVersion;
-    if (!eglInitialize(mDisplay, &majorVersion, &minorVersion))
-    {
-        destroyGL();
-        return false;
-    }
-
-    eglBindAPI(EGL_OPENGL_ES_API);
-    if (eglGetError() != EGL_SUCCESS)
-    {
-        destroyGL();
-        return false;
-    }
-
-    const EGLint configAttributes[] =
-    {
-        EGL_RED_SIZE,       8,
-        EGL_GREEN_SIZE,     8,
-        EGL_BLUE_SIZE,      8,
-        EGL_ALPHA_SIZE,     8,
-        EGL_DEPTH_SIZE,     24,
-        EGL_STENCIL_SIZE,   8,
-        EGL_SAMPLE_BUFFERS, EGL_DONT_CARE,
-        EGL_NONE
-    };
-
-    EGLint configCount;
-    if (!eglChooseConfig(mDisplay, configAttributes, &mConfig, 1, &configCount) || (configCount != 1))
-    {
-        destroyGL();
-        return false;
-    }
-
-    const EGLint surfaceAttributes[] =
-    {
-        EGL_POST_SUB_BUFFER_SUPPORTED_NV, EGL_TRUE,
-        EGL_NONE, EGL_NONE,
-    };
-
-    mSurface = eglCreateWindowSurface(mDisplay, mConfig, mWindow->getNativeWindow(), surfaceAttributes);
-    if (mSurface == EGL_NO_SURFACE)
-    {
-        eglGetError(); // Clear error and try again
-        mSurface = eglCreateWindowSurface(mDisplay, mConfig, NULL, NULL);
-    }
-
-    if (eglGetError() != EGL_SUCCESS)
-    {
-        destroyGL();
-        return false;
-    }
-
-    EGLint contextAttibutes[] =
-    {
-        EGL_CONTEXT_CLIENT_VERSION, mClientVersion,
-        EGL_NONE
-    };
-    mContext = eglCreateContext(mDisplay, mConfig, NULL, contextAttibutes);
-    if (eglGetError() != EGL_SUCCESS)
-    {
-        destroyGL();
-        return false;
-    }
-
-    eglMakeCurrent(mDisplay, mSurface, mSurface, mContext);
-    if (eglGetError() != EGL_SUCCESS)
-    {
-        destroyGL();
-        return false;
-    }
-
-    // Turn off vsync
-    eglSwapInterval(mDisplay, 0);
-
-    return true;
-}
-
-void SampleApplication::destroyGL()
-{
-    eglDestroySurface(mDisplay, mSurface);
-    mSurface = 0;
-
-    eglDestroyContext(mDisplay, mContext);
-    mContext = 0;
-
-    eglMakeCurrent(mDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
-    eglTerminate(mDisplay);
-    mDisplay = EGL_NO_DISPLAY;
+    return mOSWindow->popEvent(event);
 }
diff --git a/samples/angle/sample_util/SampleApplication.h b/samples/angle/sample_util/SampleApplication.h
index f928643..47ef544 100644
--- a/samples/angle/sample_util/SampleApplication.h
+++ b/samples/angle/sample_util/SampleApplication.h
@@ -7,16 +7,10 @@
 #ifndef SAMPLE_UTIL_SAMPLE_APPLICATION_H
 #define SAMPLE_UTIL_SAMPLE_APPLICATION_H
 
-#define GL_GLEXT_PROTOTYPES
-
-#include <GLES3/gl3.h>
-#include <GLES3/gl3ext.h>
-#include <GLES2/gl2.h>
-#include <GLES2/gl2ext.h>
 #include <EGL/egl.h>
 #include <EGL/eglext.h>
 
-#include "Window.h"
+#include "OSWindow.h"
 #include "Timer.h"
 
 #include <string>
@@ -24,6 +18,8 @@
 #include <cstdint>
 #include <memory>
 
+class EGLWindow;
+
 class SampleApplication
 {
   public:
@@ -39,7 +35,7 @@
 
     virtual void swap();
 
-    Window *getWindow() const;
+    OSWindow *getWindow() const;
     EGLConfig getConfig() const;
     EGLDisplay getDisplay() const;
     EGLSurface getSurface() const;
@@ -51,24 +47,12 @@
     void exit();
 
   private:
-    bool initializeGL();
-    void destroyGL();
-
-    EGLConfig mConfig;
-    EGLDisplay mDisplay;
-    EGLSurface mSurface;
-    EGLContext mContext;
-
-    GLuint mClientVersion;
-    EGLint mRequestedRenderer;
-    size_t mWidth;
-    size_t mHeight;
     std::string mName;
-
     bool mRunning;
 
     std::unique_ptr<Timer> mTimer;
-    std::unique_ptr<Window> mWindow;
+    std::unique_ptr<EGLWindow> mEGLWindow;
+    std::unique_ptr<OSWindow> mOSWindow;
 };
 
 #endif // SAMPLE_UTIL_SAMPLE_APPLICATION_H
diff --git a/samples/samples.gyp b/samples/samples.gyp
index 9f85ce1..2770c52 100644
--- a/samples/samples.gyp
+++ b/samples/samples.gyp
@@ -54,6 +54,7 @@
                     [
                         '../src/angle.gyp:libEGL',
                         '../src/angle.gyp:libGLESv2',
+                        '../util/util.gyp:angle_util',
                     ],
                     'include_dirs':
                     [
@@ -72,6 +73,7 @@
                         [
                             '../include',
                             'angle/sample_util',
+                            '../util',
                         ],
                     },
                 },
diff --git a/src/angle.gypi b/src/angle.gypi
index 09f70ff..8629c2e 100644
--- a/src/angle.gypi
+++ b/src/angle.gypi
@@ -26,6 +26,7 @@
         {
             'target_name': 'copy_scripts',
             'type': 'none',
+            'hard_dependency': 1,
             'copies':
             [
                 {
@@ -46,6 +47,7 @@
                     'type': 'none',
                     'includes': [ '../build/common_defines.gypi', ],
                     'dependencies': [ 'copy_scripts', ],
+                    'hard_dependency': 1,
                     'actions':
                     [
                         {
@@ -61,7 +63,7 @@
                             ],
                         },
                     ],
-                    'direct_dependent_settings':
+                    'all_dependent_settings':
                     {
                         'include_dirs':
                         [
@@ -77,6 +79,7 @@
                 {
                     'target_name': 'commit_id',
                     'type': 'none',
+                    'hard_dependency': 1,
                     'copies':
                     [
                         {
@@ -84,7 +87,7 @@
                             'files': [ '<(angle_id_header_base)' ]
                         }
                     ],
-                    'direct_dependent_settings':
+                    'all_dependent_settings':
                     {
                         'include_dirs':
                         [
diff --git a/src/commit_id.target.darwin-arm.mk b/src/commit_id.target.darwin-arm.mk
index 20fe326..20a9059 100644
--- a/src/commit_id.target.darwin-arm.mk
+++ b/src/commit_id.target.darwin-arm.mk
@@ -6,7 +6,6 @@
 LOCAL_MODULE := third_party_angle_src_commit_id_gyp
 LOCAL_MODULE_STEM := commit_id
 LOCAL_MODULE_SUFFIX := .stamp
-LOCAL_MODULE_TAGS := optional
 LOCAL_MODULE_TARGET_ARCH := $(TARGET_$(GYP_VAR_PREFIX)ARCH)
 gyp_intermediate_dir := $(call local-intermediates-dir,,$(GYP_VAR_PREFIX))
 gyp_shared_intermediate_dir := $(call intermediates-dir-for,GYP,shared,,,$(GYP_VAR_PREFIX))
diff --git a/src/commit_id.target.darwin-arm64.mk b/src/commit_id.target.darwin-arm64.mk
index 20fe326..20a9059 100644
--- a/src/commit_id.target.darwin-arm64.mk
+++ b/src/commit_id.target.darwin-arm64.mk
@@ -6,7 +6,6 @@
 LOCAL_MODULE := third_party_angle_src_commit_id_gyp
 LOCAL_MODULE_STEM := commit_id
 LOCAL_MODULE_SUFFIX := .stamp
-LOCAL_MODULE_TAGS := optional
 LOCAL_MODULE_TARGET_ARCH := $(TARGET_$(GYP_VAR_PREFIX)ARCH)
 gyp_intermediate_dir := $(call local-intermediates-dir,,$(GYP_VAR_PREFIX))
 gyp_shared_intermediate_dir := $(call intermediates-dir-for,GYP,shared,,,$(GYP_VAR_PREFIX))
diff --git a/src/commit_id.target.darwin-mips.mk b/src/commit_id.target.darwin-mips.mk
index 20fe326..20a9059 100644
--- a/src/commit_id.target.darwin-mips.mk
+++ b/src/commit_id.target.darwin-mips.mk
@@ -6,7 +6,6 @@
 LOCAL_MODULE := third_party_angle_src_commit_id_gyp
 LOCAL_MODULE_STEM := commit_id
 LOCAL_MODULE_SUFFIX := .stamp
-LOCAL_MODULE_TAGS := optional
 LOCAL_MODULE_TARGET_ARCH := $(TARGET_$(GYP_VAR_PREFIX)ARCH)
 gyp_intermediate_dir := $(call local-intermediates-dir,,$(GYP_VAR_PREFIX))
 gyp_shared_intermediate_dir := $(call intermediates-dir-for,GYP,shared,,,$(GYP_VAR_PREFIX))
diff --git a/src/commit_id.target.darwin-x86.mk b/src/commit_id.target.darwin-x86.mk
index 20fe326..20a9059 100644
--- a/src/commit_id.target.darwin-x86.mk
+++ b/src/commit_id.target.darwin-x86.mk
@@ -6,7 +6,6 @@
 LOCAL_MODULE := third_party_angle_src_commit_id_gyp
 LOCAL_MODULE_STEM := commit_id
 LOCAL_MODULE_SUFFIX := .stamp
-LOCAL_MODULE_TAGS := optional
 LOCAL_MODULE_TARGET_ARCH := $(TARGET_$(GYP_VAR_PREFIX)ARCH)
 gyp_intermediate_dir := $(call local-intermediates-dir,,$(GYP_VAR_PREFIX))
 gyp_shared_intermediate_dir := $(call intermediates-dir-for,GYP,shared,,,$(GYP_VAR_PREFIX))
diff --git a/src/commit_id.target.darwin-x86_64.mk b/src/commit_id.target.darwin-x86_64.mk
index 20fe326..20a9059 100644
--- a/src/commit_id.target.darwin-x86_64.mk
+++ b/src/commit_id.target.darwin-x86_64.mk
@@ -6,7 +6,6 @@
 LOCAL_MODULE := third_party_angle_src_commit_id_gyp
 LOCAL_MODULE_STEM := commit_id
 LOCAL_MODULE_SUFFIX := .stamp
-LOCAL_MODULE_TAGS := optional
 LOCAL_MODULE_TARGET_ARCH := $(TARGET_$(GYP_VAR_PREFIX)ARCH)
 gyp_intermediate_dir := $(call local-intermediates-dir,,$(GYP_VAR_PREFIX))
 gyp_shared_intermediate_dir := $(call intermediates-dir-for,GYP,shared,,,$(GYP_VAR_PREFIX))
diff --git a/src/commit_id.target.linux-arm.mk b/src/commit_id.target.linux-arm.mk
index 20fe326..20a9059 100644
--- a/src/commit_id.target.linux-arm.mk
+++ b/src/commit_id.target.linux-arm.mk
@@ -6,7 +6,6 @@
 LOCAL_MODULE := third_party_angle_src_commit_id_gyp
 LOCAL_MODULE_STEM := commit_id
 LOCAL_MODULE_SUFFIX := .stamp
-LOCAL_MODULE_TAGS := optional
 LOCAL_MODULE_TARGET_ARCH := $(TARGET_$(GYP_VAR_PREFIX)ARCH)
 gyp_intermediate_dir := $(call local-intermediates-dir,,$(GYP_VAR_PREFIX))
 gyp_shared_intermediate_dir := $(call intermediates-dir-for,GYP,shared,,,$(GYP_VAR_PREFIX))
diff --git a/src/commit_id.target.linux-arm64.mk b/src/commit_id.target.linux-arm64.mk
index 20fe326..20a9059 100644
--- a/src/commit_id.target.linux-arm64.mk
+++ b/src/commit_id.target.linux-arm64.mk
@@ -6,7 +6,6 @@
 LOCAL_MODULE := third_party_angle_src_commit_id_gyp
 LOCAL_MODULE_STEM := commit_id
 LOCAL_MODULE_SUFFIX := .stamp
-LOCAL_MODULE_TAGS := optional
 LOCAL_MODULE_TARGET_ARCH := $(TARGET_$(GYP_VAR_PREFIX)ARCH)
 gyp_intermediate_dir := $(call local-intermediates-dir,,$(GYP_VAR_PREFIX))
 gyp_shared_intermediate_dir := $(call intermediates-dir-for,GYP,shared,,,$(GYP_VAR_PREFIX))
diff --git a/src/commit_id.target.linux-mips.mk b/src/commit_id.target.linux-mips.mk
index 20fe326..20a9059 100644
--- a/src/commit_id.target.linux-mips.mk
+++ b/src/commit_id.target.linux-mips.mk
@@ -6,7 +6,6 @@
 LOCAL_MODULE := third_party_angle_src_commit_id_gyp
 LOCAL_MODULE_STEM := commit_id
 LOCAL_MODULE_SUFFIX := .stamp
-LOCAL_MODULE_TAGS := optional
 LOCAL_MODULE_TARGET_ARCH := $(TARGET_$(GYP_VAR_PREFIX)ARCH)
 gyp_intermediate_dir := $(call local-intermediates-dir,,$(GYP_VAR_PREFIX))
 gyp_shared_intermediate_dir := $(call intermediates-dir-for,GYP,shared,,,$(GYP_VAR_PREFIX))
diff --git a/src/commit_id.target.linux-x86.mk b/src/commit_id.target.linux-x86.mk
index 20fe326..20a9059 100644
--- a/src/commit_id.target.linux-x86.mk
+++ b/src/commit_id.target.linux-x86.mk
@@ -6,7 +6,6 @@
 LOCAL_MODULE := third_party_angle_src_commit_id_gyp
 LOCAL_MODULE_STEM := commit_id
 LOCAL_MODULE_SUFFIX := .stamp
-LOCAL_MODULE_TAGS := optional
 LOCAL_MODULE_TARGET_ARCH := $(TARGET_$(GYP_VAR_PREFIX)ARCH)
 gyp_intermediate_dir := $(call local-intermediates-dir,,$(GYP_VAR_PREFIX))
 gyp_shared_intermediate_dir := $(call intermediates-dir-for,GYP,shared,,,$(GYP_VAR_PREFIX))
diff --git a/src/commit_id.target.linux-x86_64.mk b/src/commit_id.target.linux-x86_64.mk
index 20fe326..20a9059 100644
--- a/src/commit_id.target.linux-x86_64.mk
+++ b/src/commit_id.target.linux-x86_64.mk
@@ -6,7 +6,6 @@
 LOCAL_MODULE := third_party_angle_src_commit_id_gyp
 LOCAL_MODULE_STEM := commit_id
 LOCAL_MODULE_SUFFIX := .stamp
-LOCAL_MODULE_TAGS := optional
 LOCAL_MODULE_TARGET_ARCH := $(TARGET_$(GYP_VAR_PREFIX)ARCH)
 gyp_intermediate_dir := $(call local-intermediates-dir,,$(GYP_VAR_PREFIX))
 gyp_shared_intermediate_dir := $(call intermediates-dir-for,GYP,shared,,,$(GYP_VAR_PREFIX))
diff --git a/src/common/RefCountObject.h b/src/common/RefCountObject.h
index 8635aa5..6eeaee1 100644
--- a/src/common/RefCountObject.h
+++ b/src/common/RefCountObject.h
@@ -12,11 +12,11 @@
 #ifndef COMMON_REFCOUNTOBJECT_H_
 #define COMMON_REFCOUNTOBJECT_H_
 
-#include <cstddef>
+#include "common/debug.h"
 
 #include "angle_gl.h"
 
-#include "common/debug.h"
+#include <cstddef>
 
 class RefCountObject
 {
diff --git a/src/common/angleutils.cpp b/src/common/angleutils.cpp
new file mode 100644
index 0000000..2673abf
--- /dev/null
+++ b/src/common/angleutils.cpp
@@ -0,0 +1,37 @@
+//
+// 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 "common/angleutils.h"
+
+#include <vector>
+
+std::string FormatString(const char *fmt, va_list vararg)
+{
+    static std::vector<char> buffer(512);
+
+    // Attempt to just print to the current buffer
+    int len = vsnprintf(&buffer[0], buffer.size(), fmt, vararg);
+    if (len < 0 || static_cast<size_t>(len) >= buffer.size())
+    {
+        // Buffer was not large enough, calculate the required size and resize the buffer
+        len = vsnprintf(NULL, 0, fmt, vararg);
+        buffer.resize(len + 1);
+
+        // Print again
+        vsnprintf(&buffer[0], buffer.size(), fmt, vararg);
+    }
+
+    return std::string(buffer.data(), len);
+}
+
+std::string FormatString(const char *fmt, ...)
+{
+    va_list vararg;
+    va_start(vararg, fmt);
+    std::string result = FormatString(fmt, vararg);
+    va_end(vararg);
+    return result;
+}
diff --git a/src/common/angleutils.h b/src/common/angleutils.h
index 7701a42..50a4132 100644
--- a/src/common/angleutils.h
+++ b/src/common/angleutils.h
@@ -16,6 +16,7 @@
 #include <string>
 #include <set>
 #include <sstream>
+#include <cstdarg>
 
 // A macro to disallow the copy constructor and operator= functions
 // This must be used in the private: declarations for a class
@@ -23,8 +24,8 @@
   TypeName(const TypeName&);               \
   void operator=(const TypeName&)
 
-template <typename T, unsigned int N>
-inline unsigned int ArraySize(T(&)[N])
+template <typename T, size_t N>
+inline size_t ArraySize(T(&)[N])
 {
     return N;
 }
@@ -131,6 +132,9 @@
     return strstr.str();
 }
 
+std::string FormatString(const char *fmt, va_list vararg);
+std::string FormatString(const char *fmt, ...);
+
 #if defined(_MSC_VER)
 #define snprintf _snprintf
 #endif
diff --git a/src/common/blocklayout.cpp b/src/common/blocklayout.cpp
index c1f0c3a..e3b2d43 100644
--- a/src/common/blocklayout.cpp
+++ b/src/common/blocklayout.cpp
@@ -19,46 +19,7 @@
 {
 }
 
-void BlockLayoutEncoder::encodeInterfaceBlockFields(const std::vector<InterfaceBlockField> &fields)
-{
-    for (unsigned int fieldIndex = 0; fieldIndex < fields.size(); fieldIndex++)
-    {
-        const InterfaceBlockField &variable = fields[fieldIndex];
-
-        if (variable.fields.size() > 0)
-        {
-            const unsigned int elementCount = std::max(1u, variable.arraySize);
-
-            for (unsigned int elementIndex = 0; elementIndex < elementCount; elementIndex++)
-            {
-                enterAggregateType();
-                encodeInterfaceBlockFields(variable.fields);
-                exitAggregateType();
-            }
-        }
-        else
-        {
-            encodeInterfaceBlockField(variable);
-        }
-    }
-}
-
-BlockMemberInfo BlockLayoutEncoder::encodeInterfaceBlockField(const InterfaceBlockField &field)
-{
-    int arrayStride;
-    int matrixStride;
-
-    ASSERT(field.fields.empty());
-    getBlockLayoutInfo(field.type, field.arraySize, field.isRowMajorMatrix, &arrayStride, &matrixStride);
-
-    const BlockMemberInfo memberInfo(mCurrentOffset * BytesPerComponent, arrayStride * BytesPerComponent, matrixStride * BytesPerComponent, field.isRowMajorMatrix);
-
-    advanceOffset(field.type, field.arraySize, field.isRowMajorMatrix, arrayStride, matrixStride);
-
-    return memberInfo;
-}
-
-void BlockLayoutEncoder::encodeType(GLenum type, unsigned int arraySize, bool isRowMajorMatrix)
+BlockMemberInfo BlockLayoutEncoder::encodeType(GLenum type, unsigned int arraySize, bool isRowMajorMatrix)
 {
     int arrayStride;
     int matrixStride;
@@ -68,6 +29,8 @@
     const BlockMemberInfo memberInfo(mCurrentOffset * BytesPerComponent, arrayStride * BytesPerComponent, matrixStride * BytesPerComponent, isRowMajorMatrix);
 
     advanceOffset(type, arraySize, isRowMajorMatrix, arrayStride, matrixStride);
+
+    return memberInfo;
 }
 
 void BlockLayoutEncoder::nextRegister()
diff --git a/src/common/blocklayout.h b/src/common/blocklayout.h
index bed99c4..d46ac6e 100644
--- a/src/common/blocklayout.h
+++ b/src/common/blocklayout.h
@@ -49,9 +49,7 @@
   public:
     BlockLayoutEncoder();
 
-    void encodeInterfaceBlockFields(const std::vector<InterfaceBlockField> &fields);
-    BlockMemberInfo encodeInterfaceBlockField(const InterfaceBlockField &field);
-    void encodeType(GLenum type, unsigned int arraySize, bool isRowMajorMatrix);
+    BlockMemberInfo encodeType(GLenum type, unsigned int arraySize, bool isRowMajorMatrix);
 
     size_t getBlockSize() const { return mCurrentOffset * BytesPerComponent; }
     size_t getCurrentRegister() const { return mCurrentOffset / ComponentsPerRegister; }
diff --git a/src/common/debug.cpp b/src/common/debug.cpp
index d6eecf7..dcad327 100644
--- a/src/common/debug.cpp
+++ b/src/common/debug.cpp
@@ -8,6 +8,7 @@
 
 #include "common/debug.h"
 #include "common/platform.h"
+#include "common/angleutils.h"
 
 #include <stdarg.h>
 #include <vector>
@@ -25,22 +26,7 @@
 static void output(bool traceFileDebugOnly, PerfOutputFunction perfFunc, const char *format, va_list vararg)
 {
 #if defined(ANGLE_ENABLE_PERF) || defined(ANGLE_ENABLE_TRACE)
-    static std::vector<char> asciiMessageBuffer(512);
-
-    // Attempt to just print to the current buffer
-    int len = vsnprintf(&asciiMessageBuffer[0], asciiMessageBuffer.size(), format, vararg);
-    if (len < 0 || static_cast<size_t>(len) >= asciiMessageBuffer.size())
-    {
-        // Buffer was not large enough, calculate the required size and resize the buffer
-        len = vsnprintf(NULL, 0, format, vararg);
-        asciiMessageBuffer.resize(len + 1);
-
-        // Print again
-        vsnprintf(&asciiMessageBuffer[0], asciiMessageBuffer.size(), format, vararg);
-    }
-
-    // NULL terminate the buffer to be safe
-    asciiMessageBuffer[len] = '\0';
+    std::string formattedMessage = FormatString(format, vararg);
 #endif
 
 #if defined(ANGLE_ENABLE_PERF)
@@ -48,12 +34,12 @@
     {
         // The perf function only accepts wide strings, widen the ascii message
         static std::wstring wideMessage;
-        if (wideMessage.capacity() < asciiMessageBuffer.size())
+        if (wideMessage.capacity() < formattedMessage.length())
         {
-            wideMessage.reserve(asciiMessageBuffer.size());
+            wideMessage.reserve(formattedMessage.size());
         }
 
-        wideMessage.assign(asciiMessageBuffer.begin(), asciiMessageBuffer.begin() + len);
+        wideMessage.assign(formattedMessage.begin(), formattedMessage.end());
 
         perfFunc(0, wideMessage.c_str());
     }
@@ -70,7 +56,7 @@
     static std::ofstream file(TRACE_OUTPUT_FILE, std::ofstream::app);
     if (file)
     {
-        file.write(&asciiMessageBuffer[0], len);
+        file.write(formattedMessage.c_str(), formattedMessage.length());
         file.flush();
     }
 
diff --git a/src/common/mathutil.cpp b/src/common/mathutil.cpp
index 20b3f0c..4966336 100644
--- a/src/common/mathutil.cpp
+++ b/src/common/mathutil.cpp
@@ -7,6 +7,7 @@
 // mathutil.cpp: Math and bit manipulation functions.
 
 #include "common/mathutil.h"
+
 #include <algorithm>
 #include <math.h>
 
diff --git a/src/common/mathutil.h b/src/common/mathutil.h
index 02b44c2..ffcb908 100644
--- a/src/common/mathutil.h
+++ b/src/common/mathutil.h
@@ -503,15 +503,21 @@
 namespace rx
 {
 
+template <typename T>
 struct Range
 {
     Range() {}
-    Range(int lo, int hi) : start(lo), end(hi) { ASSERT(lo <= hi); }
+    Range(T lo, T hi) : start(lo), end(hi) { ASSERT(lo <= hi); }
 
-    int start;
-    int end;
+    T start;
+    T end;
+
+    T length() const { return end - start; }
 };
 
+typedef Range<int> RangeI;
+typedef Range<unsigned int> RangeUI;
+
 template <typename T>
 T roundUp(const T value, const T alignment)
 {
diff --git a/src/compiler.gypi b/src/compiler.gypi
index ff180e7..dadc4ca 100644
--- a/src/compiler.gypi
+++ b/src/compiler.gypi
@@ -72,7 +72,10 @@
             'compiler/translator/InitializeVariables.cpp',
             'compiler/translator/InitializeVariables.h',
             'compiler/translator/IntermTraverse.cpp',
+            'compiler/translator/Intermediate.h',
             'compiler/translator/Intermediate.cpp',
+            'compiler/translator/IntermNode.h',
+            'compiler/translator/IntermNode.cpp',
             'compiler/translator/LoopInfo.cpp',
             'compiler/translator/LoopInfo.h',
             'compiler/translator/MMap.h',
@@ -151,7 +154,6 @@
             'compiler/translator/intermOut.cpp',
             'compiler/translator/intermediate.h',
             'compiler/translator/length_limits.h',
-            'compiler/translator/localintermediate.h',
             'compiler/translator/parseConst.cpp',
             'compiler/translator/timing/RestrictFragmentShaderTiming.cpp',
             'compiler/translator/timing/RestrictFragmentShaderTiming.h',
diff --git a/src/compiler/translator/BaseTypes.h b/src/compiler/translator/BaseTypes.h
index 7260799..324b066 100644
--- a/src/compiler/translator/BaseTypes.h
+++ b/src/compiler/translator/BaseTypes.h
@@ -69,7 +69,6 @@
     EbtStruct,
     EbtInterfaceBlock,
     EbtAddress,            // should be deprecated??
-    EbtInvariant          // used as a type when qualifying a previously declared variable as being invariant
 };
 
 const char* getBasicString(TBasicType t);
diff --git a/src/compiler/translator/BuiltInFunctionEmulator.h b/src/compiler/translator/BuiltInFunctionEmulator.h
index 926b6be..c6bf77c 100644
--- a/src/compiler/translator/BuiltInFunctionEmulator.h
+++ b/src/compiler/translator/BuiltInFunctionEmulator.h
@@ -8,7 +8,7 @@
 #define COMPILIER_BUILT_IN_FUNCTION_EMULATOR_H_
 
 #include "compiler/translator/InfoSink.h"
-#include "compiler/translator/intermediate.h"
+#include "compiler/translator/IntermNode.h"
 
 //
 // This class decides which built-in functions need to be replaced with the
diff --git a/src/compiler/translator/Compiler.cpp b/src/compiler/translator/Compiler.cpp
index bcb431a..368cd2a 100644
--- a/src/compiler/translator/Compiler.cpp
+++ b/src/compiler/translator/Compiler.cpp
@@ -502,18 +502,18 @@
 
 void TCompiler::collectVariables(TIntermNode* root)
 {
-    CollectVariables collect(&attributes,
-                             &outputVariables,
-                             &uniforms,
-                             &varyings,
-                             &interfaceBlocks,
-                             hashFunction);
+    sh::CollectVariables collect(&attributes,
+                                 &outputVariables,
+                                 &uniforms,
+                                 &varyings,
+                                 &interfaceBlocks,
+                                 hashFunction);
     root->traverse(&collect);
 
     // For backwards compatiblity with ShGetVariableInfo, expand struct
     // uniforms and varyings into separate variables for each field.
-    ExpandVariables(uniforms, &expandedUniforms);
-    ExpandVariables(varyings, &expandedVaryings);
+    sh::ExpandVariables(uniforms, &expandedUniforms);
+    sh::ExpandVariables(varyings, &expandedVaryings);
 }
 
 bool TCompiler::enforcePackingRestrictions()
diff --git a/src/compiler/translator/Compiler.h b/src/compiler/translator/Compiler.h
index 5eac2d8..ca0c157 100644
--- a/src/compiler/translator/Compiler.h
+++ b/src/compiler/translator/Compiler.h
@@ -71,9 +71,9 @@
     const std::vector<sh::Attribute> &getAttributes() const { return attributes; }
     const std::vector<sh::Attribute> &getOutputVariables() const { return outputVariables; }
     const std::vector<sh::Uniform> &getUniforms() const { return uniforms; }
-    const std::vector<sh::Uniform> &getExpandedUniforms() const { return expandedUniforms; }
+    const std::vector<sh::ShaderVariable> &getExpandedUniforms() const { return expandedUniforms; }
     const std::vector<sh::Varying> &getVaryings() const { return varyings; }
-    const std::vector<sh::Varying> &getExpandedVaryings() const { return expandedVaryings; }
+    const std::vector<sh::ShaderVariable> &getExpandedVaryings() const { return expandedVaryings; }
     const std::vector<sh::InterfaceBlock> &getInterfaceBlocks() const { return interfaceBlocks; }
 
     ShHashFunction64 getHashFunction() const { return hashFunction; }
@@ -83,6 +83,9 @@
     ShShaderOutput getOutputType() const { return outputType; }
     std::string getBuiltInResourcesString() const { return builtInResourcesString; }
 
+    // Get the resources set by InitBuiltInSymbolTable
+    const ShBuiltInResources& getResources() const;
+
   protected:
     sh::GLenum getShaderType() const { return shaderType; }
     // Initialize symbol-table with built-in symbols.
@@ -128,8 +131,6 @@
     bool limitExpressionComplexity(TIntermNode* root);
     // Get built-in extensions with default behavior.
     const TExtensionBehavior& getExtensionBehavior() const;
-    // Get the resources set by InitBuiltInSymbolTable
-    const ShBuiltInResources& getResources() const;
 
     const ArrayBoundsClamper& getArrayBoundsClamper() const;
     ShArrayIndexClampingStrategy getArrayIndexClampingStrategy() const;
@@ -138,9 +139,9 @@
     std::vector<sh::Attribute> attributes;
     std::vector<sh::Attribute> outputVariables;
     std::vector<sh::Uniform> uniforms;
-    std::vector<sh::Uniform> expandedUniforms;
+    std::vector<sh::ShaderVariable> expandedUniforms;
     std::vector<sh::Varying> varyings;
-    std::vector<sh::Varying> expandedVaryings;
+    std::vector<sh::ShaderVariable> expandedVaryings;
     std::vector<sh::InterfaceBlock> interfaceBlocks;
 
   private:
diff --git a/src/compiler/translator/DetectCallDepth.h b/src/compiler/translator/DetectCallDepth.h
index cb76f1d..8681065 100644
--- a/src/compiler/translator/DetectCallDepth.h
+++ b/src/compiler/translator/DetectCallDepth.h
@@ -8,7 +8,7 @@
 #define COMPILER_DETECT_RECURSION_H_
 
 #include <limits.h>
-#include "compiler/translator/intermediate.h"
+#include "compiler/translator/IntermNode.h"
 #include "compiler/translator/VariableInfo.h"
 
 class TInfoSink;
diff --git a/src/compiler/translator/DetectDiscontinuity.h b/src/compiler/translator/DetectDiscontinuity.h
index 1dd8be9..35d66cb 100644
--- a/src/compiler/translator/DetectDiscontinuity.h
+++ b/src/compiler/translator/DetectDiscontinuity.h
@@ -11,7 +11,7 @@
 #ifndef COMPILER_DETECTDISCONTINUITY_H_
 #define COMPILER_DETECTDISCONTINUITY_H_
 
-#include "compiler/translator/intermediate.h"
+#include "compiler/translator/IntermNode.h"
 
 namespace sh
 {
diff --git a/src/compiler/translator/FlagStd140Structs.h b/src/compiler/translator/FlagStd140Structs.h
index 610205e..c93a6f8 100644
--- a/src/compiler/translator/FlagStd140Structs.h
+++ b/src/compiler/translator/FlagStd140Structs.h
@@ -7,7 +7,7 @@
 #ifndef COMPILER_FLAGSTD140STRUCTS_H_
 #define COMPILER_FLAGSTD140STRUCTS_H_
 
-#include "compiler/translator/intermediate.h"
+#include "compiler/translator/IntermNode.h"
 
 namespace sh
 {
diff --git a/src/compiler/translator/HashNames.h b/src/compiler/translator/HashNames.h
index 8516142..26546a3 100644
--- a/src/compiler/translator/HashNames.h
+++ b/src/compiler/translator/HashNames.h
@@ -9,7 +9,7 @@
 
 #include <map>
 
-#include "compiler/translator/intermediate.h"
+#include "compiler/translator/IntermNode.h"
 
 #define HASHED_NAME_PREFIX "webgl_"
 
diff --git a/src/compiler/translator/Initialize.cpp b/src/compiler/translator/Initialize.cpp
index e91d64f..10b21e6 100644
--- a/src/compiler/translator/Initialize.cpp
+++ b/src/compiler/translator/Initialize.cpp
@@ -12,7 +12,7 @@
 
 #include "compiler/translator/Initialize.h"
 
-#include "compiler/translator/intermediate.h"
+#include "compiler/translator/IntermNode.h"
 #include "angle_gl.h"
 
 void InsertBuiltInFunctions(sh::GLenum type, ShShaderSpec spec, const ShBuiltInResources &resources, TSymbolTable &symbolTable)
diff --git a/src/compiler/translator/InitializeVariables.h b/src/compiler/translator/InitializeVariables.h
index 81ab9fe..59c3ea0 100644
--- a/src/compiler/translator/InitializeVariables.h
+++ b/src/compiler/translator/InitializeVariables.h
@@ -7,7 +7,7 @@
 #ifndef COMPILER_INITIALIZE_VARIABLES_H_
 #define COMPILER_INITIALIZE_VARIABLES_H_
 
-#include "compiler/translator/intermediate.h"
+#include "compiler/translator/IntermNode.h"
 
 class InitializeVariables : public TIntermTraverser
 {
diff --git a/src/compiler/translator/IntermNode.cpp b/src/compiler/translator/IntermNode.cpp
new file mode 100644
index 0000000..b155545
--- /dev/null
+++ b/src/compiler/translator/IntermNode.cpp
@@ -0,0 +1,1107 @@
+//
+// 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.
+//
+
+//
+// Build the intermediate representation.
+//
+
+#include <float.h>
+#include <limits.h>
+#include <algorithm>
+
+#include "compiler/translator/HashNames.h"
+#include "compiler/translator/IntermNode.h"
+#include "compiler/translator/SymbolTable.h"
+
+namespace
+{
+
+TPrecision GetHigherPrecision(TPrecision left, TPrecision right)
+{
+    return left > right ? left : right;
+}
+
+bool ValidateMultiplication(TOperator op, const TType &left, const TType &right)
+{
+    switch (op)
+    {
+      case EOpMul:
+      case EOpMulAssign:
+        return left.getNominalSize() == right.getNominalSize() &&
+               left.getSecondarySize() == right.getSecondarySize();
+      case EOpVectorTimesScalar:
+      case EOpVectorTimesScalarAssign:
+        return true;
+      case EOpVectorTimesMatrix:
+        return left.getNominalSize() == right.getRows();
+      case EOpVectorTimesMatrixAssign:
+        return left.getNominalSize() == right.getRows() &&
+               left.getNominalSize() == right.getCols();
+      case EOpMatrixTimesVector:
+        return left.getCols() == right.getNominalSize();
+      case EOpMatrixTimesScalar:
+      case EOpMatrixTimesScalarAssign:
+        return true;
+      case EOpMatrixTimesMatrix:
+        return left.getCols() == right.getRows();
+      case EOpMatrixTimesMatrixAssign:
+        return left.getCols() == right.getCols() &&
+               left.getRows() == right.getRows();
+
+      default:
+        UNREACHABLE();
+        return false;
+    }
+}
+
+bool CompareStructure(const TType& leftNodeType,
+                      ConstantUnion *rightUnionArray,
+                      ConstantUnion *leftUnionArray);
+
+bool CompareStruct(const TType &leftNodeType,
+                   ConstantUnion *rightUnionArray,
+                   ConstantUnion *leftUnionArray)
+{
+    const TFieldList &fields = leftNodeType.getStruct()->fields();
+
+    size_t structSize = fields.size();
+    size_t index = 0;
+
+    for (size_t j = 0; j < structSize; j++)
+    {
+        size_t size = fields[j]->type()->getObjectSize();
+        for (size_t i = 0; i < size; i++)
+        {
+            if (fields[j]->type()->getBasicType() == EbtStruct)
+            {
+                if (!CompareStructure(*fields[j]->type(),
+                                      &rightUnionArray[index],
+                                      &leftUnionArray[index]))
+                {
+                    return false;
+                }
+            }
+            else
+            {
+                if (leftUnionArray[index] != rightUnionArray[index])
+                    return false;
+                index++;
+            }
+        }
+    }
+    return true;
+}
+
+bool CompareStructure(const TType &leftNodeType,
+                      ConstantUnion *rightUnionArray,
+                      ConstantUnion *leftUnionArray)
+{
+    if (leftNodeType.isArray())
+    {
+        TType typeWithoutArrayness = leftNodeType;
+        typeWithoutArrayness.clearArrayness();
+
+        size_t arraySize = leftNodeType.getArraySize();
+
+        for (size_t i = 0; i < arraySize; ++i)
+        {
+            size_t offset = typeWithoutArrayness.getObjectSize() * i;
+            if (!CompareStruct(typeWithoutArrayness,
+                               &rightUnionArray[offset],
+                               &leftUnionArray[offset]))
+            {
+                return false;
+            }
+        }
+    }
+    else
+    {
+        return CompareStruct(leftNodeType, rightUnionArray, leftUnionArray);
+    }
+    return true;
+}
+
+}  // namespace anonymous
+
+
+////////////////////////////////////////////////////////////////
+//
+// Member functions of the nodes used for building the tree.
+//
+////////////////////////////////////////////////////////////////
+
+#define REPLACE_IF_IS(node, type, original, replacement) \
+    if (node == original) { \
+        node = static_cast<type *>(replacement); \
+        return true; \
+    }
+
+bool TIntermLoop::replaceChildNode(
+    TIntermNode *original, TIntermNode *replacement)
+{
+    REPLACE_IF_IS(mInit, TIntermNode, original, replacement);
+    REPLACE_IF_IS(mCond, TIntermTyped, original, replacement);
+    REPLACE_IF_IS(mExpr, TIntermTyped, original, replacement);
+    REPLACE_IF_IS(mBody, TIntermNode, original, replacement);
+    return false;
+}
+
+void TIntermLoop::enqueueChildren(std::queue<TIntermNode *> *nodeQueue) const
+{
+    if (mInit)
+    {
+        nodeQueue->push(mInit);
+    }
+    if (mCond)
+    {
+        nodeQueue->push(mCond);
+    }
+    if (mExpr)
+    {
+        nodeQueue->push(mExpr);
+    }
+    if (mBody)
+    {
+        nodeQueue->push(mBody);
+    }
+}
+
+bool TIntermBranch::replaceChildNode(
+    TIntermNode *original, TIntermNode *replacement)
+{
+    REPLACE_IF_IS(mExpression, TIntermTyped, original, replacement);
+    return false;
+}
+
+void TIntermBranch::enqueueChildren(std::queue<TIntermNode *> *nodeQueue) const
+{
+    if (mExpression)
+    {
+        nodeQueue->push(mExpression);
+    }
+}
+
+bool TIntermBinary::replaceChildNode(
+    TIntermNode *original, TIntermNode *replacement)
+{
+    REPLACE_IF_IS(mLeft, TIntermTyped, original, replacement);
+    REPLACE_IF_IS(mRight, TIntermTyped, original, replacement);
+    return false;
+}
+
+void TIntermBinary::enqueueChildren(std::queue<TIntermNode *> *nodeQueue) const
+{
+    if (mLeft)
+    {
+        nodeQueue->push(mLeft);
+    }
+    if (mRight)
+    {
+        nodeQueue->push(mRight);
+    }
+}
+
+bool TIntermUnary::replaceChildNode(
+    TIntermNode *original, TIntermNode *replacement)
+{
+    REPLACE_IF_IS(mOperand, TIntermTyped, original, replacement);
+    return false;
+}
+
+void TIntermUnary::enqueueChildren(std::queue<TIntermNode *> *nodeQueue) const
+{
+    if (mOperand)
+    {
+        nodeQueue->push(mOperand);
+    }
+}
+
+bool TIntermAggregate::replaceChildNode(
+    TIntermNode *original, TIntermNode *replacement)
+{
+    for (size_t ii = 0; ii < mSequence.size(); ++ii)
+    {
+        REPLACE_IF_IS(mSequence[ii], TIntermNode, original, replacement);
+    }
+    return false;
+}
+
+void TIntermAggregate::enqueueChildren(std::queue<TIntermNode *> *nodeQueue) const
+{
+    for (size_t childIndex = 0; childIndex < mSequence.size(); childIndex++)
+    {
+        nodeQueue->push(mSequence[childIndex]);
+    }
+}
+
+bool TIntermSelection::replaceChildNode(
+    TIntermNode *original, TIntermNode *replacement)
+{
+    REPLACE_IF_IS(mCondition, TIntermTyped, original, replacement);
+    REPLACE_IF_IS(mTrueBlock, TIntermNode, original, replacement);
+    REPLACE_IF_IS(mFalseBlock, TIntermNode, original, replacement);
+    return false;
+}
+
+void TIntermSelection::enqueueChildren(std::queue<TIntermNode *> *nodeQueue) const
+{
+    if (mCondition)
+    {
+        nodeQueue->push(mCondition);
+    }
+    if (mTrueBlock)
+    {
+        nodeQueue->push(mTrueBlock);
+    }
+    if (mFalseBlock)
+    {
+        nodeQueue->push(mFalseBlock);
+    }
+}
+
+//
+// Say whether or not an operation node changes the value of a variable.
+//
+bool TIntermOperator::isAssignment() const
+{
+    switch (mOp)
+    {
+      case EOpPostIncrement:
+      case EOpPostDecrement:
+      case EOpPreIncrement:
+      case EOpPreDecrement:
+      case EOpAssign:
+      case EOpAddAssign:
+      case EOpSubAssign:
+      case EOpMulAssign:
+      case EOpVectorTimesMatrixAssign:
+      case EOpVectorTimesScalarAssign:
+      case EOpMatrixTimesScalarAssign:
+      case EOpMatrixTimesMatrixAssign:
+      case EOpDivAssign:
+        return true;
+      default:
+        return false;
+    }
+}
+
+//
+// returns true if the operator is for one of the constructors
+//
+bool TIntermOperator::isConstructor() const
+{
+    switch (mOp)
+    {
+      case EOpConstructVec2:
+      case EOpConstructVec3:
+      case EOpConstructVec4:
+      case EOpConstructMat2:
+      case EOpConstructMat3:
+      case EOpConstructMat4:
+      case EOpConstructFloat:
+      case EOpConstructIVec2:
+      case EOpConstructIVec3:
+      case EOpConstructIVec4:
+      case EOpConstructInt:
+      case EOpConstructUVec2:
+      case EOpConstructUVec3:
+      case EOpConstructUVec4:
+      case EOpConstructUInt:
+      case EOpConstructBVec2:
+      case EOpConstructBVec3:
+      case EOpConstructBVec4:
+      case EOpConstructBool:
+      case EOpConstructStruct:
+        return true;
+      default:
+        return false;
+    }
+}
+
+//
+// Make sure the type of a unary operator is appropriate for its
+// combination of operation and operand type.
+//
+// Returns false in nothing makes sense.
+//
+bool TIntermUnary::promote(TInfoSink &)
+{
+    switch (mOp)
+    {
+      case EOpLogicalNot:
+        if (mOperand->getBasicType() != EbtBool)
+            return false;
+        break;
+      case EOpNegative:
+      case EOpPostIncrement:
+      case EOpPostDecrement:
+      case EOpPreIncrement:
+      case EOpPreDecrement:
+        if (mOperand->getBasicType() == EbtBool)
+            return false;
+        break;
+
+      // operators for built-ins are already type checked against their prototype
+      case EOpAny:
+      case EOpAll:
+      case EOpVectorLogicalNot:
+        return true;
+
+      default:
+        if (mOperand->getBasicType() != EbtFloat)
+            return false;
+    }
+
+    setType(mOperand->getType());
+    mType.setQualifier(EvqTemporary);
+
+    return true;
+}
+
+//
+// Establishes the type of the resultant operation, as well as
+// makes the operator the correct one for the operands.
+//
+// Returns false if operator can't work on operands.
+//
+bool TIntermBinary::promote(TInfoSink &infoSink)
+{
+    // This function only handles scalars, vectors, and matrices.
+    if (mLeft->isArray() || mRight->isArray())
+    {
+        infoSink.info.message(EPrefixInternalError, getLine(),
+                              "Invalid operation for arrays");
+        return false;
+    }
+
+    // GLSL ES 2.0 does not support implicit type casting.
+    // So the basic type should always match.
+    if (mLeft->getBasicType() != mRight->getBasicType())
+    {
+        return false;
+    }
+
+    //
+    // Base assumption:  just make the type the same as the left
+    // operand.  Then only deviations from this need be coded.
+    //
+    setType(mLeft->getType());
+
+    // The result gets promoted to the highest precision.
+    TPrecision higherPrecision = GetHigherPrecision(
+        mLeft->getPrecision(), mRight->getPrecision());
+    getTypePointer()->setPrecision(higherPrecision);
+
+    // Binary operations results in temporary variables unless both
+    // operands are const.
+    if (mLeft->getQualifier() != EvqConst || mRight->getQualifier() != EvqConst)
+    {
+        getTypePointer()->setQualifier(EvqTemporary);
+    }
+
+    const int nominalSize =
+        std::max(mLeft->getNominalSize(), mRight->getNominalSize());
+
+    //
+    // All scalars or structs. Code after this test assumes this case is removed!
+    //
+    if (nominalSize == 1)
+    {
+        switch (mOp)
+        {
+          //
+          // Promote to conditional
+          //
+          case EOpEqual:
+          case EOpNotEqual:
+          case EOpLessThan:
+          case EOpGreaterThan:
+          case EOpLessThanEqual:
+          case EOpGreaterThanEqual:
+            setType(TType(EbtBool, EbpUndefined));
+            break;
+
+          //
+          // And and Or operate on conditionals
+          //
+          case EOpLogicalAnd:
+          case EOpLogicalOr:
+            // Both operands must be of type bool.
+            if (mLeft->getBasicType() != EbtBool || mRight->getBasicType() != EbtBool)
+            {
+                return false;
+            }
+            setType(TType(EbtBool, EbpUndefined));
+            break;
+
+          default:
+            break;
+        }
+        return true;
+    }
+
+    // If we reach here, at least one of the operands is vector or matrix.
+    // The other operand could be a scalar, vector, or matrix.
+    // Can these two operands be combined?
+    //
+    TBasicType basicType = mLeft->getBasicType();
+    switch (mOp)
+    {
+      case EOpMul:
+        if (!mLeft->isMatrix() && mRight->isMatrix())
+        {
+            if (mLeft->isVector())
+            {
+                mOp = EOpVectorTimesMatrix;
+                setType(TType(basicType, higherPrecision, EvqTemporary,
+                              mRight->getCols(), 1));
+            }
+            else
+            {
+                mOp = EOpMatrixTimesScalar;
+                setType(TType(basicType, higherPrecision, EvqTemporary,
+                              mRight->getCols(), mRight->getRows()));
+            }
+        }
+        else if (mLeft->isMatrix() && !mRight->isMatrix())
+        {
+            if (mRight->isVector())
+            {
+                mOp = EOpMatrixTimesVector;
+                setType(TType(basicType, higherPrecision, EvqTemporary,
+                              mLeft->getRows(), 1));
+            }
+            else
+            {
+                mOp = EOpMatrixTimesScalar;
+            }
+        }
+        else if (mLeft->isMatrix() && mRight->isMatrix())
+        {
+            mOp = EOpMatrixTimesMatrix;
+            setType(TType(basicType, higherPrecision, EvqTemporary,
+                          mRight->getCols(), mLeft->getRows()));
+        }
+        else if (!mLeft->isMatrix() && !mRight->isMatrix())
+        {
+            if (mLeft->isVector() && mRight->isVector())
+            {
+                // leave as component product
+            }
+            else if (mLeft->isVector() || mRight->isVector())
+            {
+                mOp = EOpVectorTimesScalar;
+                setType(TType(basicType, higherPrecision, EvqTemporary,
+                              nominalSize, 1));
+            }
+        }
+        else
+        {
+            infoSink.info.message(EPrefixInternalError, getLine(),
+                                  "Missing elses");
+            return false;
+        }
+
+        if (!ValidateMultiplication(mOp, mLeft->getType(), mRight->getType()))
+        {
+            return false;
+        }
+        break;
+
+      case EOpMulAssign:
+        if (!mLeft->isMatrix() && mRight->isMatrix())
+        {
+            if (mLeft->isVector())
+            {
+                mOp = EOpVectorTimesMatrixAssign;
+            }
+            else
+            {
+                return false;
+            }
+        }
+        else if (mLeft->isMatrix() && !mRight->isMatrix())
+        {
+            if (mRight->isVector())
+            {
+                return false;
+            }
+            else
+            {
+                mOp = EOpMatrixTimesScalarAssign;
+            }
+        }
+        else if (mLeft->isMatrix() && mRight->isMatrix())
+        {
+            mOp = EOpMatrixTimesMatrixAssign;
+            setType(TType(basicType, higherPrecision, EvqTemporary,
+                          mRight->getCols(), mLeft->getRows()));
+        }
+        else if (!mLeft->isMatrix() && !mRight->isMatrix())
+        {
+            if (mLeft->isVector() && mRight->isVector())
+            {
+                // leave as component product
+            }
+            else if (mLeft->isVector() || mRight->isVector())
+            {
+                if (!mLeft->isVector())
+                    return false;
+                mOp = EOpVectorTimesScalarAssign;
+                setType(TType(basicType, higherPrecision, EvqTemporary,
+                              mLeft->getNominalSize(), 1));
+            }
+        }
+        else
+        {
+            infoSink.info.message(EPrefixInternalError, getLine(),
+                                  "Missing elses");
+            return false;
+        }
+
+        if (!ValidateMultiplication(mOp, mLeft->getType(), mRight->getType()))
+        {
+            return false;
+        }
+        break;
+
+      case EOpAssign:
+      case EOpInitialize:
+      case EOpAdd:
+      case EOpSub:
+      case EOpDiv:
+      case EOpAddAssign:
+      case EOpSubAssign:
+      case EOpDivAssign:
+        if ((mLeft->isMatrix() && mRight->isVector()) ||
+            (mLeft->isVector() && mRight->isMatrix()))
+        {
+            return false;
+        }
+
+        // Are the sizes compatible?
+        if (mLeft->getNominalSize() != mRight->getNominalSize() ||
+            mLeft->getSecondarySize() != mRight->getSecondarySize())
+        {
+            // If the nominal size of operands do not match:
+            // One of them must be scalar.
+            if (!mLeft->isScalar() && !mRight->isScalar())
+                return false;
+
+            // Operator cannot be of type pure assignment.
+            if (mOp == EOpAssign || mOp == EOpInitialize)
+                return false;
+        }
+
+        {
+            const int secondarySize = std::max(
+                mLeft->getSecondarySize(), mRight->getSecondarySize());
+            setType(TType(basicType, higherPrecision, EvqTemporary,
+                          nominalSize, secondarySize));
+        }
+        break;
+
+      case EOpEqual:
+      case EOpNotEqual:
+      case EOpLessThan:
+      case EOpGreaterThan:
+      case EOpLessThanEqual:
+      case EOpGreaterThanEqual:
+        if ((mLeft->getNominalSize() != mRight->getNominalSize()) ||
+            (mLeft->getSecondarySize() != mRight->getSecondarySize()))
+        {
+            return false;
+        }
+        setType(TType(EbtBool, EbpUndefined));
+        break;
+
+      default:
+        return false;
+    }
+    return true;
+}
+
+//
+// The fold functions see if an operation on a constant can be done in place,
+// without generating run-time code.
+//
+// Returns the node to keep using, which may or may not be the node passed in.
+//
+TIntermTyped *TIntermConstantUnion::fold(
+    TOperator op, TIntermTyped *constantNode, TInfoSink &infoSink)
+{
+    ConstantUnion *unionArray = getUnionArrayPointer();
+
+    if (!unionArray)
+        return NULL;
+
+    size_t objectSize = getType().getObjectSize();
+
+    if (constantNode)
+    {
+        // binary operations
+        TIntermConstantUnion *node = constantNode->getAsConstantUnion();
+        ConstantUnion *rightUnionArray = node->getUnionArrayPointer();
+        TType returnType = getType();
+
+        if (!rightUnionArray)
+            return NULL;
+
+        // for a case like float f = 1.2 + vec4(2,3,4,5);
+        if (constantNode->getType().getObjectSize() == 1 && objectSize > 1)
+        {
+            rightUnionArray = new ConstantUnion[objectSize];
+            for (size_t i = 0; i < objectSize; ++i)
+            {
+                rightUnionArray[i] = *node->getUnionArrayPointer();
+            }
+            returnType = getType();
+        }
+        else if (constantNode->getType().getObjectSize() > 1 && objectSize == 1)
+        {
+            // for a case like float f = vec4(2,3,4,5) + 1.2;
+            unionArray = new ConstantUnion[constantNode->getType().getObjectSize()];
+            for (size_t i = 0; i < constantNode->getType().getObjectSize(); ++i)
+            {
+                unionArray[i] = *getUnionArrayPointer();
+            }
+            returnType = node->getType();
+            objectSize = constantNode->getType().getObjectSize();
+        }
+
+        ConstantUnion *tempConstArray = NULL;
+        TIntermConstantUnion *tempNode;
+
+        bool boolNodeFlag = false;
+        switch(op)
+        {
+          case EOpAdd:
+            tempConstArray = new ConstantUnion[objectSize];
+            for (size_t i = 0; i < objectSize; i++)
+                tempConstArray[i] = unionArray[i] + rightUnionArray[i];
+            break;
+          case EOpSub:
+            tempConstArray = new ConstantUnion[objectSize];
+            for (size_t i = 0; i < objectSize; i++)
+                tempConstArray[i] = unionArray[i] - rightUnionArray[i];
+            break;
+
+          case EOpMul:
+          case EOpVectorTimesScalar:
+          case EOpMatrixTimesScalar:
+            tempConstArray = new ConstantUnion[objectSize];
+            for (size_t i = 0; i < objectSize; i++)
+                tempConstArray[i] = unionArray[i] * rightUnionArray[i];
+            break;
+
+          case EOpMatrixTimesMatrix:
+            {
+                if (getType().getBasicType() != EbtFloat ||
+                    node->getBasicType() != EbtFloat)
+                {
+                    infoSink.info.message(
+                        EPrefixInternalError, getLine(),
+                        "Constant Folding cannot be done for matrix multiply");
+                    return NULL;
+                }
+
+                const int leftCols = getCols();
+                const int leftRows = getRows();
+                const int rightCols = constantNode->getType().getCols();
+                const int rightRows = constantNode->getType().getRows();
+                const int resultCols = rightCols;
+                const int resultRows = leftRows;
+
+                tempConstArray = new ConstantUnion[resultCols*resultRows];
+                for (int row = 0; row < resultRows; row++)
+                {
+                    for (int column = 0; column < resultCols; column++)
+                    {
+                        tempConstArray[resultRows * column + row].setFConst(0.0f);
+                        for (int i = 0; i < leftCols; i++)
+                        {
+                            tempConstArray[resultRows * column + row].setFConst(
+                                tempConstArray[resultRows * column + row].getFConst() +
+                                unionArray[i * leftRows + row].getFConst() *
+                                rightUnionArray[column * rightRows + i].getFConst());
+                        }
+                    }
+                }
+
+                // update return type for matrix product
+                returnType.setPrimarySize(resultCols);
+                returnType.setSecondarySize(resultRows);
+            }
+            break;
+
+          case EOpDiv:
+            {
+                tempConstArray = new ConstantUnion[objectSize];
+                for (size_t i = 0; i < objectSize; i++)
+                {
+                    switch (getType().getBasicType())
+                    {
+                      case EbtFloat:
+                        if (rightUnionArray[i] == 0.0f)
+                        {
+                            infoSink.info.message(
+                                EPrefixWarning, getLine(),
+                                "Divide by zero error during constant folding");
+                            tempConstArray[i].setFConst(
+                                unionArray[i].getFConst() < 0 ? -FLT_MAX : FLT_MAX);
+                        }
+                        else
+                        {
+                            tempConstArray[i].setFConst(
+                                unionArray[i].getFConst() /
+                                rightUnionArray[i].getFConst());
+                        }
+                        break;
+
+                      case EbtInt:
+                        if (rightUnionArray[i] == 0)
+                        {
+                            infoSink.info.message(
+                                EPrefixWarning, getLine(),
+                                "Divide by zero error during constant folding");
+                            tempConstArray[i].setIConst(INT_MAX);
+                        }
+                        else
+                        {
+                            tempConstArray[i].setIConst(
+                                unionArray[i].getIConst() /
+                                rightUnionArray[i].getIConst());
+                        }
+                        break;
+
+                      case EbtUInt:
+                        if (rightUnionArray[i] == 0)
+                        {
+                            infoSink.info.message(
+                                EPrefixWarning, getLine(),
+                                "Divide by zero error during constant folding");
+                            tempConstArray[i].setUConst(UINT_MAX);
+                        }
+                        else
+                        {
+                            tempConstArray[i].setUConst(
+                                unionArray[i].getUConst() /
+                                rightUnionArray[i].getUConst());
+                        }
+                        break;
+
+                      default:
+                        infoSink.info.message(
+                            EPrefixInternalError, getLine(),
+                            "Constant folding cannot be done for \"/\"");
+                        return NULL;
+                    }
+                }
+            }
+            break;
+
+          case EOpMatrixTimesVector:
+            {
+                if (node->getBasicType() != EbtFloat)
+                {
+                    infoSink.info.message(
+                        EPrefixInternalError, getLine(),
+                        "Constant Folding cannot be done for matrix times vector");
+                    return NULL;
+                }
+
+                const int matrixCols = getCols();
+                const int matrixRows = getRows();
+
+                tempConstArray = new ConstantUnion[matrixRows];
+
+                for (int matrixRow = 0; matrixRow < matrixRows; matrixRow++)
+                {
+                    tempConstArray[matrixRow].setFConst(0.0f);
+                    for (int col = 0; col < matrixCols; col++)
+                    {
+                        tempConstArray[matrixRow].setFConst(
+                            tempConstArray[matrixRow].getFConst() +
+                            unionArray[col * matrixRows + matrixRow].getFConst() *
+                            rightUnionArray[col].getFConst());
+                    }
+                }
+
+                returnType = node->getType();
+                returnType.setPrimarySize(matrixRows);
+
+                tempNode = new TIntermConstantUnion(tempConstArray, returnType);
+                tempNode->setLine(getLine());
+
+                return tempNode;
+            }
+
+          case EOpVectorTimesMatrix:
+            {
+                if (getType().getBasicType() != EbtFloat)
+                {
+                    infoSink.info.message(
+                        EPrefixInternalError, getLine(),
+                        "Constant Folding cannot be done for vector times matrix");
+                    return NULL;
+                }
+
+                const int matrixCols = constantNode->getType().getCols();
+                const int matrixRows = constantNode->getType().getRows();
+
+                tempConstArray = new ConstantUnion[matrixCols];
+
+                for (int matrixCol = 0; matrixCol < matrixCols; matrixCol++)
+                {
+                    tempConstArray[matrixCol].setFConst(0.0f);
+                    for (int matrixRow = 0; matrixRow < matrixRows; matrixRow++)
+                    {
+                        tempConstArray[matrixCol].setFConst(
+                            tempConstArray[matrixCol].getFConst() +
+                            unionArray[matrixRow].getFConst() *
+                            rightUnionArray[matrixCol * matrixRows + matrixRow].getFConst());
+                    }
+                }
+
+                returnType.setPrimarySize(matrixCols);
+            }
+            break;
+
+          case EOpLogicalAnd:
+            // this code is written for possible future use,
+            // will not get executed currently
+            {
+                tempConstArray = new ConstantUnion[objectSize];
+                for (size_t i = 0; i < objectSize; i++)
+                {
+                    tempConstArray[i] = unionArray[i] && rightUnionArray[i];
+                }
+            }
+            break;
+
+          case EOpLogicalOr:
+            // this code is written for possible future use,
+            // will not get executed currently
+            {
+                tempConstArray = new ConstantUnion[objectSize];
+                for (size_t i = 0; i < objectSize; i++)
+                {
+                    tempConstArray[i] = unionArray[i] || rightUnionArray[i];
+                }
+            }
+            break;
+
+          case EOpLogicalXor:
+            {
+                tempConstArray = new ConstantUnion[objectSize];
+                for (size_t i = 0; i < objectSize; i++)
+                {
+                    switch (getType().getBasicType())
+                    {
+                      case EbtBool:
+                        tempConstArray[i].setBConst(
+                            unionArray[i] == rightUnionArray[i] ? false : true);
+                        break;
+                      default:
+                        UNREACHABLE();
+                        break;
+                    }
+                }
+            }
+            break;
+
+          case EOpLessThan:
+            ASSERT(objectSize == 1);
+            tempConstArray = new ConstantUnion[1];
+            tempConstArray->setBConst(*unionArray < *rightUnionArray);
+            returnType = TType(EbtBool, EbpUndefined, EvqConst);
+            break;
+
+          case EOpGreaterThan:
+            ASSERT(objectSize == 1);
+            tempConstArray = new ConstantUnion[1];
+            tempConstArray->setBConst(*unionArray > *rightUnionArray);
+            returnType = TType(EbtBool, EbpUndefined, EvqConst);
+            break;
+
+          case EOpLessThanEqual:
+            {
+                ASSERT(objectSize == 1);
+                ConstantUnion constant;
+                constant.setBConst(*unionArray > *rightUnionArray);
+                tempConstArray = new ConstantUnion[1];
+                tempConstArray->setBConst(!constant.getBConst());
+                returnType = TType(EbtBool, EbpUndefined, EvqConst);
+                break;
+            }
+
+          case EOpGreaterThanEqual:
+            {
+                ASSERT(objectSize == 1);
+                ConstantUnion constant;
+                constant.setBConst(*unionArray < *rightUnionArray);
+                tempConstArray = new ConstantUnion[1];
+                tempConstArray->setBConst(!constant.getBConst());
+                returnType = TType(EbtBool, EbpUndefined, EvqConst);
+                break;
+            }
+
+          case EOpEqual:
+            if (getType().getBasicType() == EbtStruct)
+            {
+                if (!CompareStructure(node->getType(),
+                                      node->getUnionArrayPointer(),
+                                      unionArray))
+                {
+                    boolNodeFlag = true;
+                }
+            }
+            else
+            {
+                for (size_t i = 0; i < objectSize; i++)
+                {
+                    if (unionArray[i] != rightUnionArray[i])
+                    {
+                        boolNodeFlag = true;
+                        break;  // break out of for loop
+                    }
+                }
+            }
+
+            tempConstArray = new ConstantUnion[1];
+            if (!boolNodeFlag)
+            {
+                tempConstArray->setBConst(true);
+            }
+            else
+            {
+                tempConstArray->setBConst(false);
+            }
+
+            tempNode = new TIntermConstantUnion(
+                tempConstArray, TType(EbtBool, EbpUndefined, EvqConst));
+            tempNode->setLine(getLine());
+
+            return tempNode;
+
+          case EOpNotEqual:
+            if (getType().getBasicType() == EbtStruct)
+            {
+                if (CompareStructure(node->getType(),
+                                     node->getUnionArrayPointer(),
+                                     unionArray))
+                {
+                    boolNodeFlag = true;
+                }
+            }
+            else
+            {
+                for (size_t i = 0; i < objectSize; i++)
+                {
+                    if (unionArray[i] == rightUnionArray[i])
+                    {
+                        boolNodeFlag = true;
+                        break;  // break out of for loop
+                    }
+                }
+            }
+
+            tempConstArray = new ConstantUnion[1];
+            if (!boolNodeFlag)
+            {
+                tempConstArray->setBConst(true);
+            }
+            else
+            {
+                tempConstArray->setBConst(false);
+            }
+
+            tempNode = new TIntermConstantUnion(
+                tempConstArray, TType(EbtBool, EbpUndefined, EvqConst));
+            tempNode->setLine(getLine());
+
+            return tempNode;
+
+          default:
+            infoSink.info.message(
+                EPrefixInternalError, getLine(),
+                "Invalid operator for constant folding");
+            return NULL;
+        }
+        tempNode = new TIntermConstantUnion(tempConstArray, returnType);
+        tempNode->setLine(getLine());
+
+        return tempNode;
+    }
+    else
+    {
+        //
+        // Do unary operations
+        //
+        TIntermConstantUnion *newNode = 0;
+        ConstantUnion* tempConstArray = new ConstantUnion[objectSize];
+        for (size_t i = 0; i < objectSize; i++)
+        {
+            switch(op)
+            {
+              case EOpNegative:
+                switch (getType().getBasicType())
+                {
+                  case EbtFloat:
+                    tempConstArray[i].setFConst(-unionArray[i].getFConst());
+                    break;
+                  case EbtInt:
+                    tempConstArray[i].setIConst(-unionArray[i].getIConst());
+                    break;
+                  case EbtUInt:
+                    tempConstArray[i].setUConst(static_cast<unsigned int>(
+                        -static_cast<int>(unionArray[i].getUConst())));
+                    break;
+                  default:
+                    infoSink.info.message(
+                        EPrefixInternalError, getLine(),
+                        "Unary operation not folded into constant");
+                    return NULL;
+                }
+                break;
+
+              case EOpLogicalNot:
+                // this code is written for possible future use,
+                // will not get executed currently
+                switch (getType().getBasicType())
+                {
+                  case EbtBool:
+                    tempConstArray[i].setBConst(!unionArray[i].getBConst());
+                    break;
+                  default:
+                    infoSink.info.message(
+                        EPrefixInternalError, getLine(),
+                        "Unary operation not folded into constant");
+                    return NULL;
+                }
+                break;
+
+              default:
+                return NULL;
+            }
+        }
+        newNode = new TIntermConstantUnion(tempConstArray, getType());
+        newNode->setLine(getLine());
+        return newNode;
+    }
+}
+
+// static
+TString TIntermTraverser::hash(const TString &name, ShHashFunction64 hashFunction)
+{
+    if (hashFunction == NULL || name.empty())
+        return name;
+    khronos_uint64_t number = (*hashFunction)(name.c_str(), name.length());
+    TStringStream stream;
+    stream << HASHED_NAME_PREFIX << std::hex << number;
+    TString hashedName = stream.str();
+    return hashedName;
+}
diff --git a/src/compiler/translator/intermediate.h b/src/compiler/translator/IntermNode.h
similarity index 99%
rename from src/compiler/translator/intermediate.h
rename to src/compiler/translator/IntermNode.h
index 892f284..ec440da 100644
--- a/src/compiler/translator/intermediate.h
+++ b/src/compiler/translator/IntermNode.h
@@ -37,6 +37,7 @@
     EOpParameters,      // an aggregate listing the parameters to a function
 
     EOpDeclaration,
+    EOpInvariantDeclaration, // Specialized declarations for attributing invariance
     EOpPrototype,
 
     //
diff --git a/src/compiler/translator/IntermTraverse.cpp b/src/compiler/translator/IntermTraverse.cpp
index 48d2013..72b2033 100644
--- a/src/compiler/translator/IntermTraverse.cpp
+++ b/src/compiler/translator/IntermTraverse.cpp
@@ -4,7 +4,7 @@
 // found in the LICENSE file.
 //
 
-#include "compiler/translator/intermediate.h"
+#include "compiler/translator/IntermNode.h"
 
 //
 // Traverse the intermediate representation tree, and
diff --git a/src/compiler/translator/Intermediate.cpp b/src/compiler/translator/Intermediate.cpp
index fa0c9f7..ef4f833 100644
--- a/src/compiler/translator/Intermediate.cpp
+++ b/src/compiler/translator/Intermediate.cpp
@@ -12,122 +12,10 @@
 #include <limits.h>
 #include <algorithm>
 
-#include "compiler/translator/HashNames.h"
-#include "compiler/translator/localintermediate.h"
-#include "compiler/translator/QualifierAlive.h"
+#include "compiler/translator/Intermediate.h"
 #include "compiler/translator/RemoveTree.h"
 #include "compiler/translator/SymbolTable.h"
 
-namespace
-{
-
-TPrecision GetHigherPrecision(TPrecision left, TPrecision right)
-{
-    return left > right ? left : right;
-}
-
-bool ValidateMultiplication(TOperator op, const TType &left, const TType &right)
-{
-    switch (op)
-    {
-      case EOpMul:
-      case EOpMulAssign:
-        return left.getNominalSize() == right.getNominalSize() &&
-               left.getSecondarySize() == right.getSecondarySize();
-      case EOpVectorTimesScalar:
-      case EOpVectorTimesScalarAssign:
-        return true;
-      case EOpVectorTimesMatrix:
-        return left.getNominalSize() == right.getRows();
-      case EOpVectorTimesMatrixAssign:
-        return left.getNominalSize() == right.getRows() &&
-               left.getNominalSize() == right.getCols();
-      case EOpMatrixTimesVector:
-        return left.getCols() == right.getNominalSize();
-      case EOpMatrixTimesScalar:
-      case EOpMatrixTimesScalarAssign:
-        return true;
-      case EOpMatrixTimesMatrix:
-        return left.getCols() == right.getRows();
-      case EOpMatrixTimesMatrixAssign:
-        return left.getCols() == right.getCols() &&
-               left.getRows() == right.getRows();
-
-      default:
-        UNREACHABLE();
-        return false;
-    }
-}
-
-bool CompareStructure(const TType& leftNodeType,
-                      ConstantUnion *rightUnionArray,
-                      ConstantUnion *leftUnionArray);
-
-bool CompareStruct(const TType &leftNodeType,
-                   ConstantUnion *rightUnionArray,
-                   ConstantUnion *leftUnionArray)
-{
-    const TFieldList &fields = leftNodeType.getStruct()->fields();
-
-    size_t structSize = fields.size();
-    size_t index = 0;
-
-    for (size_t j = 0; j < structSize; j++)
-    {
-        size_t size = fields[j]->type()->getObjectSize();
-        for (size_t i = 0; i < size; i++)
-        {
-            if (fields[j]->type()->getBasicType() == EbtStruct)
-            {
-                if (!CompareStructure(*fields[j]->type(),
-                                      &rightUnionArray[index],
-                                      &leftUnionArray[index]))
-                {
-                    return false;
-                }
-            }
-            else
-            {
-                if (leftUnionArray[index] != rightUnionArray[index])
-                    return false;
-                index++;
-            }
-        }
-    }
-    return true;
-}
-
-bool CompareStructure(const TType &leftNodeType,
-                      ConstantUnion *rightUnionArray,
-                      ConstantUnion *leftUnionArray)
-{
-    if (leftNodeType.isArray())
-    {
-        TType typeWithoutArrayness = leftNodeType;
-        typeWithoutArrayness.clearArrayness();
-
-        size_t arraySize = leftNodeType.getArraySize();
-
-        for (size_t i = 0; i < arraySize; ++i)
-        {
-            size_t offset = typeWithoutArrayness.getObjectSize() * i;
-            if (!CompareStruct(typeWithoutArrayness,
-                               &rightUnionArray[offset],
-                               &leftUnionArray[offset]))
-            {
-                return false;
-            }
-        }
-    }
-    else
-    {
-        return CompareStruct(leftNodeType, rightUnionArray, leftUnionArray);
-    }
-    return true;
-}
-
-}  // namespace anonymous
-
 ////////////////////////////////////////////////////////////////////////////
 //
 // First set of functions are to help build the intermediate representation.
@@ -630,982 +518,3 @@
     if (root)
         RemoveAllTreeNodes(root);
 }
-
-////////////////////////////////////////////////////////////////
-//
-// Member functions of the nodes used for building the tree.
-//
-////////////////////////////////////////////////////////////////
-
-#define REPLACE_IF_IS(node, type, original, replacement) \
-    if (node == original) { \
-        node = static_cast<type *>(replacement); \
-        return true; \
-    }
-
-bool TIntermLoop::replaceChildNode(
-    TIntermNode *original, TIntermNode *replacement)
-{
-    REPLACE_IF_IS(mInit, TIntermNode, original, replacement);
-    REPLACE_IF_IS(mCond, TIntermTyped, original, replacement);
-    REPLACE_IF_IS(mExpr, TIntermTyped, original, replacement);
-    REPLACE_IF_IS(mBody, TIntermNode, original, replacement);
-    return false;
-}
-
-void TIntermLoop::enqueueChildren(std::queue<TIntermNode *> *nodeQueue) const
-{
-    if (mInit)
-    {
-        nodeQueue->push(mInit);
-    }
-    if (mCond)
-    {
-        nodeQueue->push(mCond);
-    }
-    if (mExpr)
-    {
-        nodeQueue->push(mExpr);
-    }
-    if (mBody)
-    {
-        nodeQueue->push(mBody);
-    }
-}
-
-bool TIntermBranch::replaceChildNode(
-    TIntermNode *original, TIntermNode *replacement)
-{
-    REPLACE_IF_IS(mExpression, TIntermTyped, original, replacement);
-    return false;
-}
-
-void TIntermBranch::enqueueChildren(std::queue<TIntermNode *> *nodeQueue) const
-{
-    if (mExpression)
-    {
-        nodeQueue->push(mExpression);
-    }
-}
-
-bool TIntermBinary::replaceChildNode(
-    TIntermNode *original, TIntermNode *replacement)
-{
-    REPLACE_IF_IS(mLeft, TIntermTyped, original, replacement);
-    REPLACE_IF_IS(mRight, TIntermTyped, original, replacement);
-    return false;
-}
-
-void TIntermBinary::enqueueChildren(std::queue<TIntermNode *> *nodeQueue) const
-{
-    if (mLeft)
-    {
-        nodeQueue->push(mLeft);
-    }
-    if (mRight)
-    {
-        nodeQueue->push(mRight);
-    }
-}
-
-bool TIntermUnary::replaceChildNode(
-    TIntermNode *original, TIntermNode *replacement)
-{
-    REPLACE_IF_IS(mOperand, TIntermTyped, original, replacement);
-    return false;
-}
-
-void TIntermUnary::enqueueChildren(std::queue<TIntermNode *> *nodeQueue) const
-{
-    if (mOperand)
-    {
-        nodeQueue->push(mOperand);
-    }
-}
-
-bool TIntermAggregate::replaceChildNode(
-    TIntermNode *original, TIntermNode *replacement)
-{
-    for (size_t ii = 0; ii < mSequence.size(); ++ii)
-    {
-        REPLACE_IF_IS(mSequence[ii], TIntermNode, original, replacement);
-    }
-    return false;
-}
-
-void TIntermAggregate::enqueueChildren(std::queue<TIntermNode *> *nodeQueue) const
-{
-    for (size_t childIndex = 0; childIndex < mSequence.size(); childIndex++)
-    {
-        nodeQueue->push(mSequence[childIndex]);
-    }
-}
-
-bool TIntermSelection::replaceChildNode(
-    TIntermNode *original, TIntermNode *replacement)
-{
-    REPLACE_IF_IS(mCondition, TIntermTyped, original, replacement);
-    REPLACE_IF_IS(mTrueBlock, TIntermNode, original, replacement);
-    REPLACE_IF_IS(mFalseBlock, TIntermNode, original, replacement);
-    return false;
-}
-
-void TIntermSelection::enqueueChildren(std::queue<TIntermNode *> *nodeQueue) const
-{
-    if (mCondition)
-    {
-        nodeQueue->push(mCondition);
-    }
-    if (mTrueBlock)
-    {
-        nodeQueue->push(mTrueBlock);
-    }
-    if (mFalseBlock)
-    {
-        nodeQueue->push(mFalseBlock);
-    }
-}
-
-//
-// Say whether or not an operation node changes the value of a variable.
-//
-bool TIntermOperator::isAssignment() const
-{
-    switch (mOp)
-    {
-      case EOpPostIncrement:
-      case EOpPostDecrement:
-      case EOpPreIncrement:
-      case EOpPreDecrement:
-      case EOpAssign:
-      case EOpAddAssign:
-      case EOpSubAssign:
-      case EOpMulAssign:
-      case EOpVectorTimesMatrixAssign:
-      case EOpVectorTimesScalarAssign:
-      case EOpMatrixTimesScalarAssign:
-      case EOpMatrixTimesMatrixAssign:
-      case EOpDivAssign:
-        return true;
-      default:
-        return false;
-    }
-}
-
-//
-// returns true if the operator is for one of the constructors
-//
-bool TIntermOperator::isConstructor() const
-{
-    switch (mOp)
-    {
-      case EOpConstructVec2:
-      case EOpConstructVec3:
-      case EOpConstructVec4:
-      case EOpConstructMat2:
-      case EOpConstructMat3:
-      case EOpConstructMat4:
-      case EOpConstructFloat:
-      case EOpConstructIVec2:
-      case EOpConstructIVec3:
-      case EOpConstructIVec4:
-      case EOpConstructInt:
-      case EOpConstructUVec2:
-      case EOpConstructUVec3:
-      case EOpConstructUVec4:
-      case EOpConstructUInt:
-      case EOpConstructBVec2:
-      case EOpConstructBVec3:
-      case EOpConstructBVec4:
-      case EOpConstructBool:
-      case EOpConstructStruct:
-        return true;
-      default:
-        return false;
-    }
-}
-
-//
-// Make sure the type of a unary operator is appropriate for its
-// combination of operation and operand type.
-//
-// Returns false in nothing makes sense.
-//
-bool TIntermUnary::promote(TInfoSink &)
-{
-    switch (mOp)
-    {
-      case EOpLogicalNot:
-        if (mOperand->getBasicType() != EbtBool)
-            return false;
-        break;
-      case EOpNegative:
-      case EOpPostIncrement:
-      case EOpPostDecrement:
-      case EOpPreIncrement:
-      case EOpPreDecrement:
-        if (mOperand->getBasicType() == EbtBool)
-            return false;
-        break;
-
-      // operators for built-ins are already type checked against their prototype
-      case EOpAny:
-      case EOpAll:
-      case EOpVectorLogicalNot:
-        return true;
-
-      default:
-        if (mOperand->getBasicType() != EbtFloat)
-            return false;
-    }
-
-    setType(mOperand->getType());
-    mType.setQualifier(EvqTemporary);
-
-    return true;
-}
-
-//
-// Establishes the type of the resultant operation, as well as
-// makes the operator the correct one for the operands.
-//
-// Returns false if operator can't work on operands.
-//
-bool TIntermBinary::promote(TInfoSink &infoSink)
-{
-    // This function only handles scalars, vectors, and matrices.
-    if (mLeft->isArray() || mRight->isArray())
-    {
-        infoSink.info.message(EPrefixInternalError, getLine(),
-                              "Invalid operation for arrays");
-        return false;
-    }
-
-    // GLSL ES 2.0 does not support implicit type casting.
-    // So the basic type should always match.
-    if (mLeft->getBasicType() != mRight->getBasicType())
-    {
-        return false;
-    }
-
-    //
-    // Base assumption:  just make the type the same as the left
-    // operand.  Then only deviations from this need be coded.
-    //
-    setType(mLeft->getType());
-
-    // The result gets promoted to the highest precision.
-    TPrecision higherPrecision = GetHigherPrecision(
-        mLeft->getPrecision(), mRight->getPrecision());
-    getTypePointer()->setPrecision(higherPrecision);
-
-    // Binary operations results in temporary variables unless both
-    // operands are const.
-    if (mLeft->getQualifier() != EvqConst || mRight->getQualifier() != EvqConst)
-    {
-        getTypePointer()->setQualifier(EvqTemporary);
-    }
-
-    const int nominalSize =
-        std::max(mLeft->getNominalSize(), mRight->getNominalSize());
-
-    //
-    // All scalars or structs. Code after this test assumes this case is removed!
-    //
-    if (nominalSize == 1)
-    {
-        switch (mOp)
-        {
-          //
-          // Promote to conditional
-          //
-          case EOpEqual:
-          case EOpNotEqual:
-          case EOpLessThan:
-          case EOpGreaterThan:
-          case EOpLessThanEqual:
-          case EOpGreaterThanEqual:
-            setType(TType(EbtBool, EbpUndefined));
-            break;
-
-          //
-          // And and Or operate on conditionals
-          //
-          case EOpLogicalAnd:
-          case EOpLogicalOr:
-            // Both operands must be of type bool.
-            if (mLeft->getBasicType() != EbtBool || mRight->getBasicType() != EbtBool)
-            {
-                return false;
-            }
-            setType(TType(EbtBool, EbpUndefined));
-            break;
-
-          default:
-            break;
-        }
-        return true;
-    }
-
-    // If we reach here, at least one of the operands is vector or matrix.
-    // The other operand could be a scalar, vector, or matrix.
-    // Can these two operands be combined?
-    //
-    TBasicType basicType = mLeft->getBasicType();
-    switch (mOp)
-    {
-      case EOpMul:
-        if (!mLeft->isMatrix() && mRight->isMatrix())
-        {
-            if (mLeft->isVector())
-            {
-                mOp = EOpVectorTimesMatrix;
-                setType(TType(basicType, higherPrecision, EvqTemporary,
-                              mRight->getCols(), 1));
-            }
-            else
-            {
-                mOp = EOpMatrixTimesScalar;
-                setType(TType(basicType, higherPrecision, EvqTemporary,
-                              mRight->getCols(), mRight->getRows()));
-            }
-        }
-        else if (mLeft->isMatrix() && !mRight->isMatrix())
-        {
-            if (mRight->isVector())
-            {
-                mOp = EOpMatrixTimesVector;
-                setType(TType(basicType, higherPrecision, EvqTemporary,
-                              mLeft->getRows(), 1));
-            }
-            else
-            {
-                mOp = EOpMatrixTimesScalar;
-            }
-        }
-        else if (mLeft->isMatrix() && mRight->isMatrix())
-        {
-            mOp = EOpMatrixTimesMatrix;
-            setType(TType(basicType, higherPrecision, EvqTemporary,
-                          mRight->getCols(), mLeft->getRows()));
-        }
-        else if (!mLeft->isMatrix() && !mRight->isMatrix())
-        {
-            if (mLeft->isVector() && mRight->isVector())
-            {
-                // leave as component product
-            }
-            else if (mLeft->isVector() || mRight->isVector())
-            {
-                mOp = EOpVectorTimesScalar;
-                setType(TType(basicType, higherPrecision, EvqTemporary,
-                              nominalSize, 1));
-            }
-        }
-        else
-        {
-            infoSink.info.message(EPrefixInternalError, getLine(),
-                                  "Missing elses");
-            return false;
-        }
-
-        if (!ValidateMultiplication(mOp, mLeft->getType(), mRight->getType()))
-        {
-            return false;
-        }
-        break;
-
-      case EOpMulAssign:
-        if (!mLeft->isMatrix() && mRight->isMatrix())
-        {
-            if (mLeft->isVector())
-            {
-                mOp = EOpVectorTimesMatrixAssign;
-            }
-            else
-            {
-                return false;
-            }
-        }
-        else if (mLeft->isMatrix() && !mRight->isMatrix())
-        {
-            if (mRight->isVector())
-            {
-                return false;
-            }
-            else
-            {
-                mOp = EOpMatrixTimesScalarAssign;
-            }
-        }
-        else if (mLeft->isMatrix() && mRight->isMatrix())
-        {
-            mOp = EOpMatrixTimesMatrixAssign;
-            setType(TType(basicType, higherPrecision, EvqTemporary,
-                          mRight->getCols(), mLeft->getRows()));
-        }
-        else if (!mLeft->isMatrix() && !mRight->isMatrix())
-        {
-            if (mLeft->isVector() && mRight->isVector())
-            {
-                // leave as component product
-            }
-            else if (mLeft->isVector() || mRight->isVector())
-            {
-                if (!mLeft->isVector())
-                    return false;
-                mOp = EOpVectorTimesScalarAssign;
-                setType(TType(basicType, higherPrecision, EvqTemporary,
-                              mLeft->getNominalSize(), 1));
-            }
-        }
-        else
-        {
-            infoSink.info.message(EPrefixInternalError, getLine(),
-                                  "Missing elses");
-            return false;
-        }
-
-        if (!ValidateMultiplication(mOp, mLeft->getType(), mRight->getType()))
-        {
-            return false;
-        }
-        break;
-
-      case EOpAssign:
-      case EOpInitialize:
-      case EOpAdd:
-      case EOpSub:
-      case EOpDiv:
-      case EOpAddAssign:
-      case EOpSubAssign:
-      case EOpDivAssign:
-        if ((mLeft->isMatrix() && mRight->isVector()) ||
-            (mLeft->isVector() && mRight->isMatrix()))
-        {
-            return false;
-        }
-
-        // Are the sizes compatible?
-        if (mLeft->getNominalSize() != mRight->getNominalSize() ||
-            mLeft->getSecondarySize() != mRight->getSecondarySize())
-        {
-            // If the nominal size of operands do not match:
-            // One of them must be scalar.
-            if (!mLeft->isScalar() && !mRight->isScalar())
-                return false;
-
-            // Operator cannot be of type pure assignment.
-            if (mOp == EOpAssign || mOp == EOpInitialize)
-                return false;
-        }
-
-        {
-            const int secondarySize = std::max(
-                mLeft->getSecondarySize(), mRight->getSecondarySize());
-            setType(TType(basicType, higherPrecision, EvqTemporary,
-                          nominalSize, secondarySize));
-        }
-        break;
-
-      case EOpEqual:
-      case EOpNotEqual:
-      case EOpLessThan:
-      case EOpGreaterThan:
-      case EOpLessThanEqual:
-      case EOpGreaterThanEqual:
-        if ((mLeft->getNominalSize() != mRight->getNominalSize()) ||
-            (mLeft->getSecondarySize() != mRight->getSecondarySize()))
-        {
-            return false;
-        }
-        setType(TType(EbtBool, EbpUndefined));
-        break;
-
-      default:
-        return false;
-    }
-    return true;
-}
-
-//
-// The fold functions see if an operation on a constant can be done in place,
-// without generating run-time code.
-//
-// Returns the node to keep using, which may or may not be the node passed in.
-//
-TIntermTyped *TIntermConstantUnion::fold(
-    TOperator op, TIntermTyped *constantNode, TInfoSink &infoSink)
-{
-    ConstantUnion *unionArray = getUnionArrayPointer();
-
-    if (!unionArray)
-        return NULL;
-
-    size_t objectSize = getType().getObjectSize();
-
-    if (constantNode)
-    {
-        // binary operations
-        TIntermConstantUnion *node = constantNode->getAsConstantUnion();
-        ConstantUnion *rightUnionArray = node->getUnionArrayPointer();
-        TType returnType = getType();
-
-        if (!rightUnionArray)
-            return NULL;
-
-        // for a case like float f = 1.2 + vec4(2,3,4,5);
-        if (constantNode->getType().getObjectSize() == 1 && objectSize > 1)
-        {
-            rightUnionArray = new ConstantUnion[objectSize];
-            for (size_t i = 0; i < objectSize; ++i)
-            {
-                rightUnionArray[i] = *node->getUnionArrayPointer();
-            }
-            returnType = getType();
-        }
-        else if (constantNode->getType().getObjectSize() > 1 && objectSize == 1)
-        {
-            // for a case like float f = vec4(2,3,4,5) + 1.2;
-            unionArray = new ConstantUnion[constantNode->getType().getObjectSize()];
-            for (size_t i = 0; i < constantNode->getType().getObjectSize(); ++i)
-            {
-                unionArray[i] = *getUnionArrayPointer();
-            }
-            returnType = node->getType();
-            objectSize = constantNode->getType().getObjectSize();
-        }
-
-        ConstantUnion *tempConstArray = NULL;
-        TIntermConstantUnion *tempNode;
-
-        bool boolNodeFlag = false;
-        switch(op)
-        {
-          case EOpAdd:
-            tempConstArray = new ConstantUnion[objectSize];
-            for (size_t i = 0; i < objectSize; i++)
-                tempConstArray[i] = unionArray[i] + rightUnionArray[i];
-            break;
-          case EOpSub:
-            tempConstArray = new ConstantUnion[objectSize];
-            for (size_t i = 0; i < objectSize; i++)
-                tempConstArray[i] = unionArray[i] - rightUnionArray[i];
-            break;
-
-          case EOpMul:
-          case EOpVectorTimesScalar:
-          case EOpMatrixTimesScalar:
-            tempConstArray = new ConstantUnion[objectSize];
-            for (size_t i = 0; i < objectSize; i++)
-                tempConstArray[i] = unionArray[i] * rightUnionArray[i];
-            break;
-
-          case EOpMatrixTimesMatrix:
-            {
-                if (getType().getBasicType() != EbtFloat ||
-                    node->getBasicType() != EbtFloat)
-                {
-                    infoSink.info.message(
-                        EPrefixInternalError, getLine(),
-                        "Constant Folding cannot be done for matrix multiply");
-                    return NULL;
-                }
-
-                const int leftCols = getCols();
-                const int leftRows = getRows();
-                const int rightCols = constantNode->getType().getCols();
-                const int rightRows = constantNode->getType().getRows();
-                const int resultCols = rightCols;
-                const int resultRows = leftRows;
-
-                tempConstArray = new ConstantUnion[resultCols*resultRows];
-                for (int row = 0; row < resultRows; row++)
-                {
-                    for (int column = 0; column < resultCols; column++)
-                    {
-                        tempConstArray[resultRows * column + row].setFConst(0.0f);
-                        for (int i = 0; i < leftCols; i++)
-                        {
-                            tempConstArray[resultRows * column + row].setFConst(
-                                tempConstArray[resultRows * column + row].getFConst() +
-                                unionArray[i * leftRows + row].getFConst() *
-                                rightUnionArray[column * rightRows + i].getFConst());
-                        }
-                    }
-                }
-
-                // update return type for matrix product
-                returnType.setPrimarySize(resultCols);
-                returnType.setSecondarySize(resultRows);
-            }
-            break;
-
-          case EOpDiv:
-            {
-                tempConstArray = new ConstantUnion[objectSize];
-                for (size_t i = 0; i < objectSize; i++)
-                {
-                    switch (getType().getBasicType())
-                    {
-                      case EbtFloat:
-                        if (rightUnionArray[i] == 0.0f)
-                        {
-                            infoSink.info.message(
-                                EPrefixWarning, getLine(),
-                                "Divide by zero error during constant folding");
-                            tempConstArray[i].setFConst(
-                                unionArray[i].getFConst() < 0 ? -FLT_MAX : FLT_MAX);
-                        }
-                        else
-                        {
-                            tempConstArray[i].setFConst(
-                                unionArray[i].getFConst() /
-                                rightUnionArray[i].getFConst());
-                        }
-                        break;
-
-                      case EbtInt:
-                        if (rightUnionArray[i] == 0)
-                        {
-                            infoSink.info.message(
-                                EPrefixWarning, getLine(),
-                                "Divide by zero error during constant folding");
-                            tempConstArray[i].setIConst(INT_MAX);
-                        }
-                        else
-                        {
-                            tempConstArray[i].setIConst(
-                                unionArray[i].getIConst() /
-                                rightUnionArray[i].getIConst());
-                        }
-                        break;
-
-                      case EbtUInt:
-                        if (rightUnionArray[i] == 0)
-                        {
-                            infoSink.info.message(
-                                EPrefixWarning, getLine(),
-                                "Divide by zero error during constant folding");
-                            tempConstArray[i].setUConst(UINT_MAX);
-                        }
-                        else
-                        {
-                            tempConstArray[i].setUConst(
-                                unionArray[i].getUConst() /
-                                rightUnionArray[i].getUConst());
-                        }
-                        break;
-
-                      default:
-                        infoSink.info.message(
-                            EPrefixInternalError, getLine(),
-                            "Constant folding cannot be done for \"/\"");
-                        return NULL;
-                    }
-                }
-            }
-            break;
-
-          case EOpMatrixTimesVector:
-            {
-                if (node->getBasicType() != EbtFloat)
-                {
-                    infoSink.info.message(
-                        EPrefixInternalError, getLine(),
-                        "Constant Folding cannot be done for matrix times vector");
-                    return NULL;
-                }
-
-                const int matrixCols = getCols();
-                const int matrixRows = getRows();
-
-                tempConstArray = new ConstantUnion[matrixRows];
-
-                for (int matrixRow = 0; matrixRow < matrixRows; matrixRow++)
-                {
-                    tempConstArray[matrixRow].setFConst(0.0f);
-                    for (int col = 0; col < matrixCols; col++)
-                    {
-                        tempConstArray[matrixRow].setFConst(
-                            tempConstArray[matrixRow].getFConst() +
-                            unionArray[col * matrixRows + matrixRow].getFConst() *
-                            rightUnionArray[col].getFConst());
-                    }
-                }
-
-                returnType = node->getType();
-                returnType.setPrimarySize(matrixRows);
-
-                tempNode = new TIntermConstantUnion(tempConstArray, returnType);
-                tempNode->setLine(getLine());
-
-                return tempNode;
-            }
-
-          case EOpVectorTimesMatrix:
-            {
-                if (getType().getBasicType() != EbtFloat)
-                {
-                    infoSink.info.message(
-                        EPrefixInternalError, getLine(),
-                        "Constant Folding cannot be done for vector times matrix");
-                    return NULL;
-                }
-
-                const int matrixCols = constantNode->getType().getCols();
-                const int matrixRows = constantNode->getType().getRows();
-
-                tempConstArray = new ConstantUnion[matrixCols];
-
-                for (int matrixCol = 0; matrixCol < matrixCols; matrixCol++)
-                {
-                    tempConstArray[matrixCol].setFConst(0.0f);
-                    for (int matrixRow = 0; matrixRow < matrixRows; matrixRow++)
-                    {
-                        tempConstArray[matrixCol].setFConst(
-                            tempConstArray[matrixCol].getFConst() +
-                            unionArray[matrixRow].getFConst() *
-                            rightUnionArray[matrixCol * matrixRows + matrixRow].getFConst());
-                    }
-                }
-
-                returnType.setPrimarySize(matrixCols);
-            }
-            break;
-
-          case EOpLogicalAnd:
-            // this code is written for possible future use,
-            // will not get executed currently
-            {
-                tempConstArray = new ConstantUnion[objectSize];
-                for (size_t i = 0; i < objectSize; i++)
-                {
-                    tempConstArray[i] = unionArray[i] && rightUnionArray[i];
-                }
-            }
-            break;
-
-          case EOpLogicalOr:
-            // this code is written for possible future use,
-            // will not get executed currently
-            {
-                tempConstArray = new ConstantUnion[objectSize];
-                for (size_t i = 0; i < objectSize; i++)
-                {
-                    tempConstArray[i] = unionArray[i] || rightUnionArray[i];
-                }
-            }
-            break;
-
-          case EOpLogicalXor:
-            {
-                tempConstArray = new ConstantUnion[objectSize];
-                for (size_t i = 0; i < objectSize; i++)
-                {
-                    switch (getType().getBasicType())
-                    {
-                      case EbtBool:
-                        tempConstArray[i].setBConst(
-                            unionArray[i] == rightUnionArray[i] ? false : true);
-                        break;
-                      default:
-                        UNREACHABLE();
-                        break;
-                    }
-                }
-            }
-            break;
-
-          case EOpLessThan:
-            ASSERT(objectSize == 1);
-            tempConstArray = new ConstantUnion[1];
-            tempConstArray->setBConst(*unionArray < *rightUnionArray);
-            returnType = TType(EbtBool, EbpUndefined, EvqConst);
-            break;
-
-          case EOpGreaterThan:
-            ASSERT(objectSize == 1);
-            tempConstArray = new ConstantUnion[1];
-            tempConstArray->setBConst(*unionArray > *rightUnionArray);
-            returnType = TType(EbtBool, EbpUndefined, EvqConst);
-            break;
-
-          case EOpLessThanEqual:
-            {
-                ASSERT(objectSize == 1);
-                ConstantUnion constant;
-                constant.setBConst(*unionArray > *rightUnionArray);
-                tempConstArray = new ConstantUnion[1];
-                tempConstArray->setBConst(!constant.getBConst());
-                returnType = TType(EbtBool, EbpUndefined, EvqConst);
-                break;
-            }
-
-          case EOpGreaterThanEqual:
-            {
-                ASSERT(objectSize == 1);
-                ConstantUnion constant;
-                constant.setBConst(*unionArray < *rightUnionArray);
-                tempConstArray = new ConstantUnion[1];
-                tempConstArray->setBConst(!constant.getBConst());
-                returnType = TType(EbtBool, EbpUndefined, EvqConst);
-                break;
-            }
-
-          case EOpEqual:
-            if (getType().getBasicType() == EbtStruct)
-            {
-                if (!CompareStructure(node->getType(),
-                                      node->getUnionArrayPointer(),
-                                      unionArray))
-                {
-                    boolNodeFlag = true;
-                }
-            }
-            else
-            {
-                for (size_t i = 0; i < objectSize; i++)
-                {
-                    if (unionArray[i] != rightUnionArray[i])
-                    {
-                        boolNodeFlag = true;
-                        break;  // break out of for loop
-                    }
-                }
-            }
-
-            tempConstArray = new ConstantUnion[1];
-            if (!boolNodeFlag)
-            {
-                tempConstArray->setBConst(true);
-            }
-            else
-            {
-                tempConstArray->setBConst(false);
-            }
-
-            tempNode = new TIntermConstantUnion(
-                tempConstArray, TType(EbtBool, EbpUndefined, EvqConst));
-            tempNode->setLine(getLine());
-
-            return tempNode;
-
-          case EOpNotEqual:
-            if (getType().getBasicType() == EbtStruct)
-            {
-                if (CompareStructure(node->getType(),
-                                     node->getUnionArrayPointer(),
-                                     unionArray))
-                {
-                    boolNodeFlag = true;
-                }
-            }
-            else
-            {
-                for (size_t i = 0; i < objectSize; i++)
-                {
-                    if (unionArray[i] == rightUnionArray[i])
-                    {
-                        boolNodeFlag = true;
-                        break;  // break out of for loop
-                    }
-                }
-            }
-
-            tempConstArray = new ConstantUnion[1];
-            if (!boolNodeFlag)
-            {
-                tempConstArray->setBConst(true);
-            }
-            else
-            {
-                tempConstArray->setBConst(false);
-            }
-
-            tempNode = new TIntermConstantUnion(
-                tempConstArray, TType(EbtBool, EbpUndefined, EvqConst));
-            tempNode->setLine(getLine());
-
-            return tempNode;
-
-          default:
-            infoSink.info.message(
-                EPrefixInternalError, getLine(),
-                "Invalid operator for constant folding");
-            return NULL;
-        }
-        tempNode = new TIntermConstantUnion(tempConstArray, returnType);
-        tempNode->setLine(getLine());
-
-        return tempNode;
-    }
-    else
-    {
-        //
-        // Do unary operations
-        //
-        TIntermConstantUnion *newNode = 0;
-        ConstantUnion* tempConstArray = new ConstantUnion[objectSize];
-        for (size_t i = 0; i < objectSize; i++)
-        {
-            switch(op)
-            {
-              case EOpNegative:
-                switch (getType().getBasicType())
-                {
-                  case EbtFloat:
-                    tempConstArray[i].setFConst(-unionArray[i].getFConst());
-                    break;
-                  case EbtInt:
-                    tempConstArray[i].setIConst(-unionArray[i].getIConst());
-                    break;
-                  case EbtUInt:
-                    tempConstArray[i].setUConst(static_cast<unsigned int>(
-                        -static_cast<int>(unionArray[i].getUConst())));
-                    break;
-                  default:
-                    infoSink.info.message(
-                        EPrefixInternalError, getLine(),
-                        "Unary operation not folded into constant");
-                    return NULL;
-                }
-                break;
-
-              case EOpLogicalNot:
-                // this code is written for possible future use,
-                // will not get executed currently
-                switch (getType().getBasicType())
-                {
-                  case EbtBool:
-                    tempConstArray[i].setBConst(!unionArray[i].getBConst());
-                    break;
-                  default:
-                    infoSink.info.message(
-                        EPrefixInternalError, getLine(),
-                        "Unary operation not folded into constant");
-                    return NULL;
-                }
-                break;
-
-              default:
-                return NULL;
-            }
-        }
-        newNode = new TIntermConstantUnion(tempConstArray, getType());
-        newNode->setLine(getLine());
-        return newNode;
-    }
-}
-
-// static
-TString TIntermTraverser::hash(const TString &name, ShHashFunction64 hashFunction)
-{
-    if (hashFunction == NULL || name.empty())
-        return name;
-    khronos_uint64_t number = (*hashFunction)(name.c_str(), name.length());
-    TStringStream stream;
-    stream << HASHED_NAME_PREFIX << std::hex << number;
-    TString hashedName = stream.str();
-    return hashedName;
-}
diff --git a/src/compiler/translator/localintermediate.h b/src/compiler/translator/Intermediate.h
similarity index 98%
rename from src/compiler/translator/localintermediate.h
rename to src/compiler/translator/Intermediate.h
index 0809bbd..3b7e7bd 100644
--- a/src/compiler/translator/localintermediate.h
+++ b/src/compiler/translator/Intermediate.h
@@ -7,7 +7,7 @@
 #ifndef COMPILER_TRANSLATOR_LOCAL_INTERMEDIATE_H_
 #define COMPILER_TRANSLATOR_LOCAL_INTERMEDIATE_H_
 
-#include "compiler/translator/intermediate.h"
+#include "compiler/translator/IntermNode.h"
 
 struct TVectorFields
 {
diff --git a/src/compiler/translator/LoopInfo.h b/src/compiler/translator/LoopInfo.h
index 5a140c3..5f72a6e 100644
--- a/src/compiler/translator/LoopInfo.h
+++ b/src/compiler/translator/LoopInfo.h
@@ -7,7 +7,7 @@
 #ifndef COMPILER_TRANSLATOR_LOOP_INFO_H_
 #define COMPILER_TRANSLATOR_LOOP_INFO_H_
 
-#include "compiler/translator/intermediate.h"
+#include "compiler/translator/IntermNode.h"
 
 class TLoopIndexInfo
 {
diff --git a/src/compiler/translator/NodeSearch.h b/src/compiler/translator/NodeSearch.h
index b58c7ec..60070c9 100644
--- a/src/compiler/translator/NodeSearch.h
+++ b/src/compiler/translator/NodeSearch.h
@@ -9,7 +9,7 @@
 #ifndef TRANSLATOR_NODESEARCH_H_
 #define TRANSLATOR_NODESEARCH_H_
 
-#include "compiler/translator/intermediate.h"
+#include "compiler/translator/IntermNode.h"
 
 namespace sh
 {
diff --git a/src/compiler/translator/OutputGLSLBase.cpp b/src/compiler/translator/OutputGLSLBase.cpp
index 09f7ad9..6d07ccc 100644
--- a/src/compiler/translator/OutputGLSLBase.cpp
+++ b/src/compiler/translator/OutputGLSLBase.cpp
@@ -81,8 +81,7 @@
 {
     TInfoSinkBase &out = objSink();
     TQualifier qualifier = type.getQualifier();
-    if (qualifier != EvqTemporary && qualifier != EvqGlobal &&
-        type.getBasicType() != EbtInvariant)
+    if (qualifier != EvqTemporary && qualifier != EvqGlobal)
     {
         out << type.getQualifierString() << " ";
     }
@@ -650,6 +649,17 @@
             mDeclaringVariables = false;
         }
         break;
+      case EOpInvariantDeclaration: {
+            // Invariant declaration.
+            ASSERT(visit == PreVisit);
+            const TIntermSequence *sequence = node->getSequence();
+            ASSERT(sequence && sequence->size() == 1);
+            const TIntermSymbol *symbol = sequence->front()->getAsSymbolNode();
+            ASSERT(symbol);
+            out << "invariant " << symbol->getSymbol() << ";";
+            visitChildren = false;
+            break;
+        }
       case EOpConstructFloat:
         writeTriplet(visit, "float(", NULL, ")");
         break;
diff --git a/src/compiler/translator/OutputGLSLBase.h b/src/compiler/translator/OutputGLSLBase.h
index 42364de..e5174f5 100644
--- a/src/compiler/translator/OutputGLSLBase.h
+++ b/src/compiler/translator/OutputGLSLBase.h
@@ -9,7 +9,7 @@
 
 #include <set>
 
-#include "compiler/translator/intermediate.h"
+#include "compiler/translator/IntermNode.h"
 #include "compiler/translator/LoopInfo.h"
 #include "compiler/translator/ParseContext.h"
 
diff --git a/src/compiler/translator/OutputHLSL.cpp b/src/compiler/translator/OutputHLSL.cpp
index 93994ba..a5ea715 100644
--- a/src/compiler/translator/OutputHLSL.cpp
+++ b/src/compiler/translator/OutputHLSL.cpp
@@ -21,6 +21,7 @@
 #include "compiler/translator/util.h"
 #include "compiler/translator/UniformHLSL.h"
 #include "compiler/translator/StructureHLSL.h"
+#include "compiler/translator/TranslatorHLSL.h"
 
 #include <algorithm>
 #include <cfloat>
@@ -29,18 +30,6 @@
 namespace sh
 {
 
-static sh::Attribute MakeAttributeFromType(const TType &type, const TString &name)
-{
-    sh::Attribute attributeVar;
-    attributeVar.type = GLVariableType(type);
-    attributeVar.precision = GLVariablePrecision(type);
-    attributeVar.name = name.c_str();
-    attributeVar.arraySize = static_cast<unsigned int>(type.getArraySize());
-    attributeVar.location = type.getLayoutQualifier().location;
-
-    return attributeVar;
-}
-
 TString OutputHLSL::TextureFunction::name() const
 {
     TString name = "gl_texture";
@@ -105,8 +94,10 @@
     return false;
 }
 
-OutputHLSL::OutputHLSL(TParseContext &context, const ShBuiltInResources& resources, ShShaderOutput outputType)
-    : TIntermTraverser(true, true, true), mContext(context), mOutputType(outputType)
+OutputHLSL::OutputHLSL(TParseContext &context, TranslatorHLSL *parentTranslator)
+    : TIntermTraverser(true, true, true),
+      mContext(context),
+      mOutputType(parentTranslator->getOutputType())
 {
     mUnfoldShortCircuit = new UnfoldShortCircuit(context, this);
     mInsideFunction = false;
@@ -138,6 +129,7 @@
     mUsesDiscardRewriting = false;
     mUsesNestedBreak = false;
 
+    const ShBuiltInResources &resources = parentTranslator->getResources();
     mNumRenderTargets = resources.EXT_draw_buffers ? resources.MaxDrawBuffers : 1;
 
     mUniqueIndex = 0;
@@ -150,7 +142,7 @@
     mExcessiveLoopIndex = NULL;
 
     mStructureHLSL = new StructureHLSL;
-    mUniformHLSL = new UniformHLSL(mStructureHLSL, mOutputType);
+    mUniformHLSL = new UniformHLSL(mStructureHLSL, parentTranslator);
 
     if (mOutputType == SH_HLSL9_OUTPUT)
     {
@@ -224,31 +216,6 @@
     return mBody;
 }
 
-const std::vector<sh::Uniform> &OutputHLSL::getUniforms()
-{
-    return mUniformHLSL->getUniforms();
-}
-
-const std::vector<sh::InterfaceBlock> &OutputHLSL::getInterfaceBlocks() const
-{
-    return mUniformHLSL->getInterfaceBlocks();
-}
-
-const std::vector<sh::Attribute> &OutputHLSL::getOutputVariables() const
-{
-    return mActiveOutputVariables;
-}
-
-const std::vector<sh::Attribute> &OutputHLSL::getAttributes() const
-{
-    return mActiveAttributes;
-}
-
-const std::vector<sh::Varying> &OutputHLSL::getVaryings() const
-{
-    return mActiveVaryings;
-}
-
 const std::map<std::string, unsigned int> &OutputHLSL::getInterfaceBlockRegisterMap() const
 {
     return mUniformHLSL->getInterfaceBlockRegisterMap();
@@ -336,8 +303,6 @@
         // Program linking depends on this exact format
         varyings += "static " + InterpolationString(type.getQualifier()) + " " + TypeString(type) + " " +
                     Decorate(name) + ArrayString(type) + " = " + initializer(type) + ";\n";
-
-        declareVaryingToList(type, type.getQualifier(), name, mActiveVaryings);
     }
 
     for (ReferencedSymbols::const_iterator attribute = mReferencedAttributes.begin(); attribute != mReferencedAttributes.end(); attribute++)
@@ -346,9 +311,6 @@
         const TString &name = attribute->second->getSymbol();
 
         attributes += "static " + TypeString(type) + " " + Decorate(name) + ArrayString(type) + " = " + initializer(type) + ";\n";
-
-        sh::Attribute attributeVar = MakeAttributeFromType(type, name);
-        mActiveAttributes.push_back(attributeVar);
     }
 
     out << mStructureHLSL->structsHeader();
@@ -384,9 +346,6 @@
 
                 out << "static " + TypeString(variableType) + " out_" + variableName + ArrayString(variableType) +
                        " = " + initializer(variableType) + ";\n";
-
-                sh::Attribute outputVar = MakeAttributeFromType(variableType, variableName);
-                mActiveOutputVariables.push_back(outputVar);
             }
         }
         else
@@ -1937,12 +1896,6 @@
             }
             else if (variable && IsVaryingOut(variable->getQualifier()))
             {
-                // Skip translation of invariant declarations
-                if (variable->getBasicType() == EbtInvariant)
-                {
-                    return false;
-                }
-
                 for (TIntermSequence::iterator sit = sequence->begin(); sit != sequence->end(); sit++)
                 {
                     TIntermSymbol *symbol = (*sit)->getAsSymbolNode();
@@ -1966,6 +1919,9 @@
             out << ", ";
         }
         break;
+      case EOpInvariantDeclaration:
+        // Do not do any translation
+        return false;
       case EOpPrototype:
         if (visit == PreVisit)
         {
@@ -2925,29 +2881,4 @@
     return constUnion;
 }
 
-class DeclareVaryingTraverser : public GetVariableTraverser<Varying>
-{
-  public:
-    DeclareVaryingTraverser(std::vector<Varying> *output,
-                            InterpolationType interpolation)
-        : GetVariableTraverser(output),
-          mInterpolation(interpolation)
-    {}
-
-  private:
-    void visitVariable(Varying *varying)
-    {
-        varying->interpolation = mInterpolation;
-    }
-
-    InterpolationType mInterpolation;
-};
-
-void OutputHLSL::declareVaryingToList(const TType &type, TQualifier baseTypeQualifier,
-                                      const TString &name, std::vector<Varying> &fieldsOut)
-{
-    DeclareVaryingTraverser traverser(&fieldsOut, GetInterpolationType(baseTypeQualifier));
-    traverser.traverse(type, name);
-}
-
 }
diff --git a/src/compiler/translator/OutputHLSL.h b/src/compiler/translator/OutputHLSL.h
index eb34aa2..bec0247 100644
--- a/src/compiler/translator/OutputHLSL.h
+++ b/src/compiler/translator/OutputHLSL.h
@@ -13,7 +13,7 @@
 
 #include "angle_gl.h"
 
-#include "compiler/translator/intermediate.h"
+#include "compiler/translator/IntermNode.h"
 #include "compiler/translator/ParseContext.h"
 
 namespace sh
@@ -27,17 +27,12 @@
 class OutputHLSL : public TIntermTraverser
 {
   public:
-    OutputHLSL(TParseContext &context, const ShBuiltInResources& resources, ShShaderOutput outputType);
+    OutputHLSL(TParseContext &context, TranslatorHLSL *parentTranslator);
     ~OutputHLSL();
 
     void output();
 
     TInfoSinkBase &getBodyStream();
-    const std::vector<sh::Uniform> &getUniforms();
-    const std::vector<sh::InterfaceBlock> &getInterfaceBlocks() const;
-    const std::vector<sh::Attribute> &getOutputVariables() const;
-    const std::vector<sh::Attribute> &getAttributes() const;
-    const std::vector<sh::Varying> &getVaryings() const;
 
     const std::map<std::string, unsigned int> &getInterfaceBlockRegisterMap() const;
     const std::map<std::string, unsigned int> &getUniformRegisterMap() const;
@@ -155,13 +150,8 @@
 
     TIntermSymbol *mExcessiveLoopIndex;
 
-    void declareVaryingToList(const TType &type, TQualifier baseTypeQualifier, const TString &name, std::vector<sh::Varying>& fieldsOut);
-
     TString structInitializerString(int indent, const TStructure &structure, const TString &rhsStructName);
 
-    std::vector<sh::Attribute> mActiveOutputVariables;
-    std::vector<sh::Attribute> mActiveAttributes;
-    std::vector<sh::Varying> mActiveVaryings;
     std::map<TIntermTyped*, TString> mFlaggedStructMappedNames;
     std::map<TIntermTyped*, TString> mFlaggedStructOriginalNames;
 
diff --git a/src/compiler/translator/ParseContext.cpp b/src/compiler/translator/ParseContext.cpp
index 605612a..ff0a496 100644
--- a/src/compiler/translator/ParseContext.cpp
+++ b/src/compiler/translator/ParseContext.cpp
@@ -1018,6 +1018,45 @@
 //
 /////////////////////////////////////////////////////////////////////////////////
 
+const TVariable *TParseContext::getNamedVariable(const TSourceLoc &location,
+                                                 const TString *name,
+                                                 const TSymbol *symbol)
+{
+    const TVariable *variable = NULL;
+
+    if (!symbol)
+    {
+        error(location, "undeclared identifier", name->c_str());
+        recover();
+    }
+    else if (!symbol->isVariable())
+    {
+        error(location, "variable expected", name->c_str());
+        recover();
+    }
+    else
+    {
+        variable = static_cast<const TVariable*>(symbol);
+
+        if (symbolTable.findBuiltIn(variable->getName(), shaderVersion) &&
+            !variable->getExtension().empty() &&
+            extensionErrorCheck(location, variable->getExtension()))
+        {
+            recover();
+        }
+    }
+
+    if (!variable)
+    {
+        TType type(EbtFloat, EbpUndefined);
+        TVariable *fakeVariable = new TVariable(name, type);
+        symbolTable.declare(fakeVariable);
+        variable = fakeVariable;
+    }
+
+    return variable;
+}
+
 //
 // Look up a function name in the symbol table, and make sure it is a function.
 //
@@ -1050,6 +1089,8 @@
 // Initializers show up in several places in the grammar.  Have one set of
 // code to handle them here.
 //
+// Returns true on error, false if no error
+//
 bool TParseContext::executeInitializer(const TSourceLoc& line, const TString& identifier, TPublicType& pType, 
                                        TIntermTyped* initializer, TIntermNode*& intermNode, TVariable* variable)
 {
@@ -1308,14 +1349,40 @@
     }
 }
 
-TIntermAggregate* TParseContext::parseDeclarator(TPublicType &publicType, TIntermAggregate *aggregateDeclaration, TSymbol *identifierSymbol, const TSourceLoc& identifierLocation, const TString &identifier)
+TIntermAggregate* TParseContext::parseInvariantDeclaration(const TSourceLoc &invariantLoc,
+                                                           const TSourceLoc &identifierLoc,
+                                                           const TString *identifier,
+                                                           const TSymbol *symbol)
 {
-    if (publicType.type == EbtInvariant && !identifierSymbol)
+    // invariant declaration
+    if (globalErrorCheck(invariantLoc, symbolTable.atGlobalLevel(), "invariant varying"))
     {
-        error(identifierLocation, "undeclared identifier declared as invariant", identifier.c_str());
         recover();
     }
 
+    if (!symbol)
+    {
+        error(identifierLoc, "undeclared identifier declared as invariant", identifier->c_str());
+        recover();
+
+        return NULL;
+    }
+    else
+    {
+        const TVariable *variable = getNamedVariable(identifierLoc, identifier, symbol);
+        ASSERT(variable);
+        const TType &type = variable->getType();
+        TIntermSymbol *intermSymbol = intermediate.addSymbol(variable->getUniqueId(),
+                                                             *identifier, type, identifierLoc);
+
+        TIntermAggregate *aggregate = intermediate.makeAggregate(intermSymbol, identifierLoc);
+        aggregate->setOp(EOpInvariantDeclaration);
+        return aggregate;
+    }
+}
+
+TIntermAggregate* TParseContext::parseDeclarator(TPublicType &publicType, TIntermAggregate *aggregateDeclaration, TSymbol *identifierSymbol, const TSourceLoc& identifierLocation, const TString &identifier)
+{
     TIntermSymbol* symbol = intermediate.addSymbol(0, identifier, TType(publicType), identifierLocation);
     TIntermAggregate* intermAggregate = intermediate.growAggregate(aggregateDeclaration, symbol, identifierLocation);
 
@@ -1548,7 +1615,7 @@
 
         for (size_t i = 0; i < fields.size(); i++)
         {
-            if ((*args)[i]->getAsTyped()->getType() != *fields[i]->type())
+            if (i >= args->size() || (*args)[i]->getAsTyped()->getType() != *fields[i]->type())
             {
                 error(line, "Structure constructor arguments do not match structure fields", "Error");
                 recover();
diff --git a/src/compiler/translator/ParseContext.h b/src/compiler/translator/ParseContext.h
index a402eec..1f4cbde 100644
--- a/src/compiler/translator/ParseContext.h
+++ b/src/compiler/translator/ParseContext.h
@@ -9,7 +9,7 @@
 #include "compiler/translator/Compiler.h"
 #include "compiler/translator/Diagnostics.h"
 #include "compiler/translator/DirectiveHandler.h"
-#include "compiler/translator/localintermediate.h"
+#include "compiler/translator/Intermediate.h"
 #include "compiler/translator/SymbolTable.h"
 #include "compiler/preprocessor/Preprocessor.h"
 
@@ -77,6 +77,9 @@
     void trace(const char* str);
     void recover();
 
+    // This method is guaranteed to succeed, even if no variable with 'name' exists.
+    const TVariable *getNamedVariable(const TSourceLoc &location, const TString *name, const TSymbol *symbol);
+
     bool parseVectorFields(const TString&, int vecSize, TVectorFields&, const TSourceLoc& line);
     bool parseMatrixFields(const TString&, int matCols, int matRows, TMatrixFields&, const TSourceLoc& line);
 
@@ -126,6 +129,8 @@
     TIntermAggregate* parseSingleDeclaration(TPublicType &publicType, const TSourceLoc& identifierLocation, const TString &identifier);
     TIntermAggregate* parseSingleArrayDeclaration(TPublicType &publicType, const TSourceLoc& identifierLocation, const TString &identifier, const TSourceLoc& indexLocation, TIntermTyped *indexExpression);
     TIntermAggregate* parseSingleInitDeclaration(TPublicType &publicType, const TSourceLoc& identifierLocation, const TString &identifier, const TSourceLoc& initLocation, TIntermTyped *initializer);
+    TIntermAggregate* parseInvariantDeclaration(const TSourceLoc &invariantLoc, const TSourceLoc &identifierLoc, const TString *identifier, const TSymbol *symbol);
+
     TIntermAggregate* parseDeclarator(TPublicType &publicType, TIntermAggregate *aggregateDeclaration, TSymbol *identifierSymbol, const TSourceLoc& identifierLocation, const TString &identifier);
     TIntermAggregate* parseArrayDeclarator(TPublicType &publicType, const TSourceLoc& identifierLocation, const TString &identifier, const TSourceLoc& arrayLocation, TIntermNode *declaratorList, TIntermTyped *indexExpression);
     TIntermAggregate* parseInitDeclarator(TPublicType &publicType, TIntermAggregate *declaratorList, const TSourceLoc& identifierLocation, const TString &identifier, const TSourceLoc& initLocation, TIntermTyped *initializer);
diff --git a/src/compiler/translator/QualifierAlive.cpp b/src/compiler/translator/QualifierAlive.cpp
index 1ba087e..1f6fb75 100644
--- a/src/compiler/translator/QualifierAlive.cpp
+++ b/src/compiler/translator/QualifierAlive.cpp
@@ -4,7 +4,7 @@
 // found in the LICENSE file.
 //
 
-#include "compiler/translator/intermediate.h"
+#include "compiler/translator/IntermNode.h"
 
 class TAliveTraverser : public TIntermTraverser {
 public:
diff --git a/src/compiler/translator/RegenerateStructNames.h b/src/compiler/translator/RegenerateStructNames.h
index 79f197a..ac87600 100644
--- a/src/compiler/translator/RegenerateStructNames.h
+++ b/src/compiler/translator/RegenerateStructNames.h
@@ -7,7 +7,7 @@
 #ifndef COMPILER_TRANSLATOR_REGENERATE_STRUCT_NAMES_H_
 #define COMPILER_TRANSLATOR_REGENERATE_STRUCT_NAMES_H_
 
-#include "compiler/translator/intermediate.h"
+#include "compiler/translator/Intermediate.h"
 #include "compiler/translator/SymbolTable.h"
 
 #include <set>
diff --git a/src/compiler/translator/RemoveTree.cpp b/src/compiler/translator/RemoveTree.cpp
index e381c32..0cf6910 100644
--- a/src/compiler/translator/RemoveTree.cpp
+++ b/src/compiler/translator/RemoveTree.cpp
@@ -4,7 +4,7 @@
 // found in the LICENSE file.
 //
 
-#include "compiler/translator/intermediate.h"
+#include "compiler/translator/IntermNode.h"
 #include "compiler/translator/RemoveTree.h"
 
 //
diff --git a/src/compiler/translator/RenameFunction.h b/src/compiler/translator/RenameFunction.h
index 1f7fb16..d43e6ef 100644
--- a/src/compiler/translator/RenameFunction.h
+++ b/src/compiler/translator/RenameFunction.h
@@ -7,7 +7,7 @@
 #ifndef COMPILER_RENAME_FUNCTION
 #define COMPILER_RENAME_FUNCTION
 
-#include "compiler/translator/intermediate.h"
+#include "compiler/translator/IntermNode.h"
 
 //
 // Renames a function, including its declaration and any calls to it.
diff --git a/src/compiler/translator/RewriteElseBlocks.h b/src/compiler/translator/RewriteElseBlocks.h
index 39963d6..d87baea 100644
--- a/src/compiler/translator/RewriteElseBlocks.h
+++ b/src/compiler/translator/RewriteElseBlocks.h
@@ -10,7 +10,7 @@
 #ifndef COMPILER_REWRITE_ELSE_BLOCKS_H_
 #define COMPILER_REWRITE_ELSE_BLOCKS_H_
 
-#include "compiler/translator/intermediate.h"
+#include "compiler/translator/IntermNode.h"
 
 namespace sh
 {
diff --git a/src/compiler/translator/ScalarizeVecAndMatConstructorArgs.h b/src/compiler/translator/ScalarizeVecAndMatConstructorArgs.h
index c81c5cf..7c6d09c 100644
--- a/src/compiler/translator/ScalarizeVecAndMatConstructorArgs.h
+++ b/src/compiler/translator/ScalarizeVecAndMatConstructorArgs.h
@@ -7,7 +7,7 @@
 #ifndef COMPILER_TRANSLATOR_SCALARIZE_VEC_AND_MAT_CONSTRUCTOR_ARGS_H_
 #define COMPILER_TRANSLATOR_SCALARIZE_VEC_AND_MAT_CONSTRUCTOR_ARGS_H_
 
-#include "compiler/translator/intermediate.h"
+#include "compiler/translator/IntermNode.h"
 
 class ScalarizeVecAndMatConstructorArgs : public TIntermTraverser
 {
diff --git a/src/compiler/translator/SearchSymbol.h b/src/compiler/translator/SearchSymbol.h
index 8ddd3cb..029ac30 100644
--- a/src/compiler/translator/SearchSymbol.h
+++ b/src/compiler/translator/SearchSymbol.h
@@ -9,7 +9,7 @@
 #ifndef COMPILER_SEARCHSYMBOL_H_
 #define COMPILER_SEARCHSYMBOL_H_
 
-#include "compiler/translator/intermediate.h"
+#include "compiler/translator/IntermNode.h"
 #include "compiler/translator/ParseContext.h"
 
 namespace sh
diff --git a/src/compiler/translator/ShaderVars.cpp b/src/compiler/translator/ShaderVars.cpp
index 164eaa6..822c558 100644
--- a/src/compiler/translator/ShaderVars.cpp
+++ b/src/compiler/translator/ShaderVars.cpp
@@ -35,7 +35,9 @@
       name(other.name),
       mappedName(other.mappedName),
       arraySize(other.arraySize),
-      staticUse(other.staticUse)
+      staticUse(other.staticUse),
+      fields(other.fields),
+      structName(other.structName)
 {}
 
 ShaderVariable &ShaderVariable::operator=(const ShaderVariable &other)
@@ -46,6 +48,8 @@
     mappedName = other.mappedName;
     arraySize = other.arraySize;
     staticUse = other.staticUse;
+    fields = other.fields;
+    structName = other.structName;
     return *this;
 }
 
@@ -56,14 +60,12 @@
 {}
 
 Uniform::Uniform(const Uniform &other)
-    : ShaderVariable(other),
-      fields(other.fields)
+    : ShaderVariable(other)
 {}
 
 Uniform &Uniform::operator=(const Uniform &other)
 {
     ShaderVariable::operator=(other);
-    fields = other.fields;
     return *this;
 }
 
@@ -87,7 +89,7 @@
 }
 
 InterfaceBlockField::InterfaceBlockField()
-    : isRowMajorMatrix(false)
+    : isRowMajorLayout(false)
 {}
 
 InterfaceBlockField::~InterfaceBlockField()
@@ -95,20 +97,19 @@
 
 InterfaceBlockField::InterfaceBlockField(const InterfaceBlockField &other)
     : ShaderVariable(other),
-      isRowMajorMatrix(other.isRowMajorMatrix),
-      fields(other.fields)
+      isRowMajorLayout(other.isRowMajorLayout)
 {}
 
 InterfaceBlockField &InterfaceBlockField::operator=(const InterfaceBlockField &other)
 {
     ShaderVariable::operator=(other);
-    isRowMajorMatrix = other.isRowMajorMatrix;
-    fields = other.fields;
+    isRowMajorLayout = other.isRowMajorLayout;
     return *this;
 }
 
 Varying::Varying()
-    : interpolation(INTERPOLATION_SMOOTH)
+    : interpolation(INTERPOLATION_SMOOTH),
+      isInvariant(false)
 {}
 
 Varying::~Varying()
@@ -117,16 +118,14 @@
 Varying::Varying(const Varying &other)
     : ShaderVariable(other),
       interpolation(other.interpolation),
-      fields(other.fields),
-      structName(other.structName)
+      isInvariant(other.isInvariant)
 {}
 
 Varying &Varying::operator=(const Varying &other)
 {
     ShaderVariable::operator=(other);
     interpolation = other.interpolation;
-    fields = other.fields;
-    structName = other.structName;
+    isInvariant = other.isInvariant;
     return *this;
 }
 
@@ -143,6 +142,7 @@
 InterfaceBlock::InterfaceBlock(const InterfaceBlock &other)
     : name(other.name),
       mappedName(other.mappedName),
+      instanceName(other.instanceName),
       arraySize(other.arraySize),
       layout(other.layout),
       isRowMajorLayout(other.isRowMajorLayout),
@@ -154,6 +154,7 @@
 {
     name = other.name;
     mappedName = other.mappedName;
+    instanceName = other.instanceName;
     arraySize = other.arraySize;
     layout = other.layout;
     isRowMajorLayout = other.isRowMajorLayout;
diff --git a/src/compiler/translator/StructureHLSL.cpp b/src/compiler/translator/StructureHLSL.cpp
index 7aaf47c..48929af 100644
--- a/src/compiler/translator/StructureHLSL.cpp
+++ b/src/compiler/translator/StructureHLSL.cpp
@@ -17,12 +17,19 @@
 namespace sh
 {
 
-Std140PaddingHelper::Std140PaddingHelper(const std::map<TString, int> &structElementIndexes)
-    : mPaddingCounter(0),
+Std140PaddingHelper::Std140PaddingHelper(const std::map<TString, int> &structElementIndexes,
+                                         unsigned *uniqueCounter)
+    : mPaddingCounter(uniqueCounter),
       mElementIndex(0),
       mStructElementIndexes(structElementIndexes)
 {}
 
+TString Std140PaddingHelper::next()
+{
+    unsigned value = (*mPaddingCounter)++;
+    return str(value);
+}
+
 int Std140PaddingHelper::prePadding(const TType &type)
 {
     if (type.getBasicType() == EbtStruct || type.isMatrix() || type.isArray())
@@ -68,7 +75,7 @@
 
     for (int paddingIndex = 0; paddingIndex < paddingCount; paddingIndex++)
     {
-        padding += "    float pad_" + str(mPaddingCounter++) + ";\n";
+        padding += "    float pad_" + next() + ";\n";
     }
 
     return padding;
@@ -116,19 +123,25 @@
     TString padding;
     for (int paddingOffset = numComponents; paddingOffset < 4; paddingOffset++)
     {
-        padding += "    float pad_" + str(mPaddingCounter++) + ";\n";
+        padding += "    float pad_" + next() + ";\n";
     }
     return padding;
 }
 
 StructureHLSL::StructureHLSL()
+    : mUniquePaddingCounter(0)
 {}
 
+Std140PaddingHelper StructureHLSL::getPaddingHelper()
+{
+    return Std140PaddingHelper(mStd140StructElementIndexes, &mUniquePaddingCounter);
+}
+
 TString StructureHLSL::defineQualified(const TStructure &structure, bool useHLSLRowMajorPacking, bool useStd140Packing)
 {
     if (useStd140Packing)
     {
-        Std140PaddingHelper padHelper(mStd140StructElementIndexes);
+        Std140PaddingHelper padHelper = getPaddingHelper();
         return define(structure, useHLSLRowMajorPacking, useStd140Packing, &padHelper);
     }
     else
@@ -461,7 +474,7 @@
 
 void StructureHLSL::storeStd140ElementIndex(const TStructure &structure, bool useHLSLRowMajorPacking)
 {
-    Std140PaddingHelper padHelper(mStd140StructElementIndexes);
+    Std140PaddingHelper padHelper = getPaddingHelper();
     const TFieldList &fields = structure.fields();
 
     for (unsigned int i = 0; i < fields.size(); i++)
diff --git a/src/compiler/translator/StructureHLSL.h b/src/compiler/translator/StructureHLSL.h
index 63fbaaa..ed002fe 100644
--- a/src/compiler/translator/StructureHLSL.h
+++ b/src/compiler/translator/StructureHLSL.h
@@ -11,7 +11,7 @@
 #define TRANSLATOR_STRUCTUREHLSL_H_
 
 #include "compiler/translator/Common.h"
-#include "compiler/translator/intermediate.h"
+#include "compiler/translator/IntermNode.h"
 
 #include <set>
 
@@ -26,7 +26,8 @@
 class Std140PaddingHelper
 {
   public:
-    explicit Std140PaddingHelper(const std::map<TString, int> &structElementIndexes);
+    explicit Std140PaddingHelper(const std::map<TString, int> &structElementIndexes,
+                                 unsigned *uniqueCounter);
 
     int elementIndex() const { return mElementIndex; }
     int prePadding(const TType &type);
@@ -34,7 +35,9 @@
     TString postPaddingString(const TType &type, bool useHLSLRowMajorPacking);
 
   private:
-    int mPaddingCounter;
+    TString next();
+
+    unsigned *mPaddingCounter;
     int mElementIndex;
     const std::map<TString, int> &mStructElementIndexes;
 };
@@ -50,9 +53,11 @@
     TString defineQualified(const TStructure &structure, bool useHLSLRowMajorPacking, bool useStd140Packing);
     static TString defineNameless(const TStructure &structure);
 
-    Std140PaddingHelper getPaddingHelper() const { return Std140PaddingHelper(mStd140StructElementIndexes); }
+    Std140PaddingHelper getPaddingHelper();
 
   private:
+    unsigned mUniquePaddingCounter;
+
     std::map<TString, int> mStd140StructElementIndexes;
 
     typedef std::set<TString> StructNames;
diff --git a/src/compiler/translator/SymbolTable.h b/src/compiler/translator/SymbolTable.h
index 6525dee..6b0e0c0 100644
--- a/src/compiler/translator/SymbolTable.h
+++ b/src/compiler/translator/SymbolTable.h
@@ -34,7 +34,7 @@
 
 #include "common/angleutils.h"
 #include "compiler/translator/InfoSink.h"
-#include "compiler/translator/intermediate.h"
+#include "compiler/translator/IntermNode.h"
 
 // Symbol base class. (Can build functions or variables out of these...)
 class TSymbol
diff --git a/src/compiler/translator/TranslatorHLSL.cpp b/src/compiler/translator/TranslatorHLSL.cpp
index 52588e4..22bf60e 100644
--- a/src/compiler/translator/TranslatorHLSL.cpp
+++ b/src/compiler/translator/TranslatorHLSL.cpp
@@ -17,16 +17,10 @@
 void TranslatorHLSL::translate(TIntermNode *root)
 {
     TParseContext& parseContext = *GetGlobalParseContext();
-    sh::OutputHLSL outputHLSL(parseContext, getResources(), getOutputType());
+    sh::OutputHLSL outputHLSL(parseContext, this);
 
     outputHLSL.output();
 
-    attributes      = outputHLSL.getAttributes();
-    outputVariables = outputHLSL.getOutputVariables();
-    uniforms        = outputHLSL.getUniforms();
-    varyings        = outputHLSL.getVaryings();
-    interfaceBlocks = outputHLSL.getInterfaceBlocks();
-
     mInterfaceBlockRegisterMap = outputHLSL.getInterfaceBlockRegisterMap();
     mUniformRegisterMap = outputHLSL.getUniformRegisterMap();
 }
diff --git a/src/compiler/translator/Types.cpp b/src/compiler/translator/Types.cpp
index d39ab01..d36936f 100644
--- a/src/compiler/translator/Types.cpp
+++ b/src/compiler/translator/Types.cpp
@@ -41,7 +41,6 @@
       case EbtSampler2DArrayShadow: return "sampler2DArrayShadow"; break;
       case EbtStruct:               return "structure";            break;
       case EbtInterfaceBlock:       return "interface block";      break;
-      case EbtInvariant:            return "invariant";            break;
       default: UNREACHABLE();       return "unknown type";
     }
 }
diff --git a/src/compiler/translator/UnfoldShortCircuit.h b/src/compiler/translator/UnfoldShortCircuit.h
index 1e416bc..6fd3b45 100644
--- a/src/compiler/translator/UnfoldShortCircuit.h
+++ b/src/compiler/translator/UnfoldShortCircuit.h
@@ -9,7 +9,7 @@
 #ifndef COMPILER_UNFOLDSHORTCIRCUIT_H_
 #define COMPILER_UNFOLDSHORTCIRCUIT_H_
 
-#include "compiler/translator/intermediate.h"
+#include "compiler/translator/IntermNode.h"
 #include "compiler/translator/ParseContext.h"
 
 namespace sh
diff --git a/src/compiler/translator/UnfoldShortCircuitAST.h b/src/compiler/translator/UnfoldShortCircuitAST.h
index 24c14a6..3acaf7e 100644
--- a/src/compiler/translator/UnfoldShortCircuitAST.h
+++ b/src/compiler/translator/UnfoldShortCircuitAST.h
@@ -11,7 +11,7 @@
 #define COMPILER_UNFOLD_SHORT_CIRCUIT_AST_H_
 
 #include "common/angleutils.h"
-#include "compiler/translator/intermediate.h"
+#include "compiler/translator/IntermNode.h"
 
 // This traverser identifies all the short circuit binary  nodes that need to
 // be replaced, and creates the corresponding replacement nodes. However,
diff --git a/src/compiler/translator/UniformHLSL.cpp b/src/compiler/translator/UniformHLSL.cpp
index 1c0af19..61b6ed7 100644
--- a/src/compiler/translator/UniformHLSL.cpp
+++ b/src/compiler/translator/UniformHLSL.cpp
@@ -14,6 +14,7 @@
 #include "compiler/translator/StructureHLSL.h"
 #include "compiler/translator/util.h"
 #include "compiler/translator/UtilsHLSL.h"
+#include "compiler/translator/TranslatorHLSL.h"
 
 namespace sh
 {
@@ -30,18 +31,6 @@
     }
 }
 
-static TString InterfaceBlockFieldName(const TInterfaceBlock &interfaceBlock, const TField &field)
-{
-    if (interfaceBlock.hasInstanceName())
-    {
-        return interfaceBlock.name() + "." + field.name();
-    }
-    else
-    {
-        return field.name();
-    }
-}
-
 static TString InterfaceBlockFieldTypeString(const TField &field, TLayoutBlockStorage blockStorage)
 {
     const TType &fieldType = *field.type();
@@ -72,12 +61,13 @@
     return DecoratePrivate(interfaceBlock.name()) + "_type";
 }
 
-UniformHLSL::UniformHLSL(StructureHLSL *structureHLSL, ShShaderOutput outputType)
+UniformHLSL::UniformHLSL(StructureHLSL *structureHLSL, TranslatorHLSL *translator)
     : mUniformRegister(0),
       mInterfaceBlockRegister(0),
       mSamplerRegister(0),
       mStructureHLSL(structureHLSL),
-      mOutputType(outputType)
+      mOutputType(translator->getOutputType()),
+      mUniforms(translator->getUniforms())
 {}
 
 void UniformHLSL::reserveUniformRegisters(unsigned int registerCount)
@@ -90,18 +80,32 @@
     mInterfaceBlockRegister = registerCount;
 }
 
+const Uniform *UniformHLSL::findUniformByName(const TString &name) const
+{
+    for (size_t uniformIndex = 0; uniformIndex < mUniforms.size(); ++uniformIndex)
+    {
+        if (mUniforms[uniformIndex].name == name.c_str())
+        {
+            return &mUniforms[uniformIndex];
+        }
+    }
+
+    UNREACHABLE();
+    return NULL;
+}
+
 unsigned int UniformHLSL::declareUniformAndAssignRegister(const TType &type, const TString &name)
 {
     unsigned int registerIndex = (IsSampler(type.getBasicType()) ? mSamplerRegister : mUniformRegister);
 
-    GetVariableTraverser<Uniform> traverser(&mActiveUniforms);
-    traverser.traverse(type, name);
+    const Uniform *uniform = findUniformByName(name);
+    ASSERT(uniform);
 
-    const sh::Uniform &activeUniform = mActiveUniforms.back();
-    mUniformRegisterMap[activeUniform.name] = registerIndex;
+    mUniformRegisterMap[uniform->name] = registerIndex;
 
-    unsigned int registerCount = HLSLVariableRegisterCount(activeUniform, mOutputType);
-    if (IsSampler(type.getBasicType()))
+    unsigned int registerCount = HLSLVariableRegisterCount(*uniform, mOutputType);
+
+    if (gl::IsSampler(uniform->type))
     {
         mSamplerRegister += registerCount;
     }
@@ -138,9 +142,9 @@
         {
             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, but layout qualifiers will not be taken into
-            // account in this case.
-            // TODO: handle nameless structs with layout qualifiers.
+            // 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()) ?
                                         QualifiedStructNameString(*structure, false, false) : TypeString(type));
 
@@ -162,36 +166,14 @@
     {
         const TType &nodeType = interfaceBlockIt->second->getType();
         const TInterfaceBlock &interfaceBlock = *nodeType.getInterfaceBlock();
-        const TFieldList &fieldList = interfaceBlock.fields();
 
         unsigned int arraySize = static_cast<unsigned int>(interfaceBlock.arraySize());
         unsigned int activeRegister = mInterfaceBlockRegister;
 
-        InterfaceBlock activeBlock;
-        activeBlock.name = interfaceBlock.name().c_str();
-        activeBlock.arraySize = arraySize;
-
-        for (unsigned int typeIndex = 0; typeIndex < fieldList.size(); typeIndex++)
-        {
-            const TField &field = *fieldList[typeIndex];
-            const TString &fullFieldName = InterfaceBlockFieldName(interfaceBlock, field);
-
-            bool isRowMajor = (field.type()->getLayoutQualifier().matrixPacking == EmpRowMajor);
-            GetInterfaceBlockFieldTraverser traverser(&activeBlock.fields, isRowMajor);
-            traverser.traverse(*field.type(), fullFieldName);
-        }
-
-        mInterfaceBlockRegisterMap[activeBlock.name] = activeRegister;
+        mInterfaceBlockRegisterMap[interfaceBlock.name().c_str()] = activeRegister;
         mInterfaceBlockRegister += std::max(1u, arraySize);
 
-        activeBlock.layout = GetBlockLayoutType(interfaceBlock.blockStorage());
-
-        if (interfaceBlock.matrixPacking() == EmpRowMajor)
-        {
-            activeBlock.isRowMajorLayout = true;
-        }
-
-        mActiveInterfaceBlocks.push_back(activeBlock);
+        // FIXME: interface block field names
 
         if (interfaceBlock.hasInstanceName())
         {
@@ -269,7 +251,7 @@
         if (blockStorage == EbsStd140)
         {
             // 2 and 3 component vector types in some cases need pre-padding
-            hlsl += padHelper.prePadding(fieldType);
+            hlsl += padHelper.prePaddingString(fieldType);
         }
 
         hlsl += "    " + InterfaceBlockFieldTypeString(field, blockStorage) +
diff --git a/src/compiler/translator/UniformHLSL.h b/src/compiler/translator/UniformHLSL.h
index d61457d..91fa515 100644
--- a/src/compiler/translator/UniformHLSL.h
+++ b/src/compiler/translator/UniformHLSL.h
@@ -19,7 +19,7 @@
 class UniformHLSL
 {
   public:
-    UniformHLSL(StructureHLSL *structureHLSL, ShShaderOutput outputType);
+    UniformHLSL(StructureHLSL *structureHLSL, TranslatorHLSL *translator);
 
     void reserveUniformRegisters(unsigned int registerCount);
     void reserveInterfaceBlockRegisters(unsigned int registerCount);
@@ -29,8 +29,6 @@
     // Used for direct index references
     static TString interfaceBlockInstanceString(const TInterfaceBlock& interfaceBlock, unsigned int arrayIndex);
 
-    const std::vector<Uniform> &getUniforms() const { return mActiveUniforms; }
-    const std::vector<InterfaceBlock> &getInterfaceBlocks() const { return mActiveInterfaceBlocks; }
     const std::map<std::string, unsigned int> &getInterfaceBlockRegisterMap() const
     {
         return mInterfaceBlockRegisterMap;
@@ -44,6 +42,7 @@
     TString interfaceBlockString(const TInterfaceBlock &interfaceBlock, unsigned int registerIndex, unsigned int arrayIndex);
     TString interfaceBlockMembersString(const TInterfaceBlock &interfaceBlock, TLayoutBlockStorage blockStorage);
     TString interfaceBlockStructString(const TInterfaceBlock &interfaceBlock);
+    const Uniform *findUniformByName(const TString &name) const;
 
     // Returns the uniform's register index
     unsigned int declareUniformAndAssignRegister(const TType &type, const TString &name);
@@ -54,8 +53,7 @@
     StructureHLSL *mStructureHLSL;
     ShShaderOutput mOutputType;
 
-    std::vector<Uniform> mActiveUniforms;
-    std::vector<InterfaceBlock> mActiveInterfaceBlocks;
+    const std::vector<Uniform> &mUniforms;
     std::map<std::string, unsigned int> mInterfaceBlockRegisterMap;
     std::map<std::string, unsigned int> mUniformRegisterMap;
 };
diff --git a/src/compiler/translator/ValidateLimitations.h b/src/compiler/translator/ValidateLimitations.h
index 8c9ebf5..e6e8a96 100644
--- a/src/compiler/translator/ValidateLimitations.h
+++ b/src/compiler/translator/ValidateLimitations.h
@@ -4,7 +4,7 @@
 // found in the LICENSE file.
 //
 
-#include "compiler/translator/intermediate.h"
+#include "compiler/translator/IntermNode.h"
 #include "compiler/translator/LoopInfo.h"
 
 class TInfoSinkBase;
diff --git a/src/compiler/translator/ValidateOutputs.h b/src/compiler/translator/ValidateOutputs.h
index e391ad9..0f808db 100644
--- a/src/compiler/translator/ValidateOutputs.h
+++ b/src/compiler/translator/ValidateOutputs.h
@@ -4,7 +4,7 @@
 // found in the LICENSE file.
 //
 
-#include "compiler/translator/intermediate.h"
+#include "compiler/translator/IntermNode.h"
 
 #include <set>
 
diff --git a/src/compiler/translator/VariableInfo.cpp b/src/compiler/translator/VariableInfo.cpp
index 0bd95cb..f26c156 100644
--- a/src/compiler/translator/VariableInfo.cpp
+++ b/src/compiler/translator/VariableInfo.cpp
@@ -9,20 +9,46 @@
 #include "compiler/translator/util.h"
 #include "common/utilities.h"
 
-template <typename VarT>
-static void ExpandUserDefinedVariable(const VarT &variable,
-                                      const std::string &name,
-                                      const std::string &mappedName,
-                                      bool markStaticUse,
-                                      std::vector<VarT> *expanded);
+namespace sh
+{
 
-// Returns info for an attribute, uniform, or varying.
-template <typename VarT>
-static void ExpandVariable(const VarT &variable,
-                           const std::string &name,
-                           const std::string &mappedName,
-                           bool markStaticUse,
-                           std::vector<VarT> *expanded)
+namespace
+{
+
+TString InterfaceBlockFieldName(const TInterfaceBlock &interfaceBlock, const TField &field)
+{
+    if (interfaceBlock.hasInstanceName())
+    {
+        return interfaceBlock.name() + "." + field.name();
+    }
+    else
+    {
+        return field.name();
+    }
+}
+
+BlockLayoutType GetBlockLayoutType(TLayoutBlockStorage blockStorage)
+{
+    switch (blockStorage)
+    {
+      case EbsPacked:         return BLOCKLAYOUT_PACKED;
+      case EbsShared:         return BLOCKLAYOUT_SHARED;
+      case EbsStd140:         return BLOCKLAYOUT_STANDARD;
+      default: UNREACHABLE(); return BLOCKLAYOUT_SHARED;
+    }
+}
+
+void ExpandUserDefinedVariable(const ShaderVariable &variable,
+                               const std::string &name,
+                               const std::string &mappedName,
+                               bool markStaticUse,
+                               std::vector<ShaderVariable> *expanded);
+
+void ExpandVariable(const ShaderVariable &variable,
+                    const std::string &name,
+                    const std::string &mappedName,
+                    bool markStaticUse,
+                    std::vector<ShaderVariable> *expanded)
 {
     if (variable.isStruct())
     {
@@ -30,8 +56,8 @@
         {
             for (size_t elementIndex = 0; elementIndex < variable.elementCount(); elementIndex++)
             {
-                std::string lname = name + ArrayString(elementIndex);
-                std::string lmappedName = mappedName + ArrayString(elementIndex);
+                std::string lname = name + ::ArrayString(elementIndex);
+                std::string lmappedName = mappedName + ::ArrayString(elementIndex);
                 ExpandUserDefinedVariable(variable, lname, lmappedName, markStaticUse, expanded);
             }
         }
@@ -42,7 +68,7 @@
     }
     else
     {
-        VarT expandedVar = variable;
+        ShaderVariable expandedVar = variable;
 
         expandedVar.name = name;
         expandedVar.mappedName = mappedName;
@@ -63,20 +89,19 @@
     }
 }
 
-template <class VarT>
-static void ExpandUserDefinedVariable(const VarT &variable,
-                                      const std::string &name,
-                                      const std::string &mappedName,
-                                      bool markStaticUse,
-                                      std::vector<VarT> *expanded)
+void ExpandUserDefinedVariable(const ShaderVariable &variable,
+                               const std::string &name,
+                               const std::string &mappedName,
+                               bool markStaticUse,
+                               std::vector<ShaderVariable> *expanded)
 {
     ASSERT(variable.isStruct());
 
-    const std::vector<VarT> &fields = variable.fields;
+    const std::vector<ShaderVariable> &fields = variable.fields;
 
     for (size_t fieldIndex = 0; fieldIndex < fields.size(); fieldIndex++)
     {
-        const VarT &field = fields[fieldIndex];
+        const ShaderVariable &field = fields[fieldIndex];
         ExpandVariable(field,
                        name + "." + field.name,
                        mappedName + "." + field.mappedName,
@@ -86,8 +111,8 @@
 }
 
 template <class VarT>
-static VarT *FindVariable(const TString &name,
-                          std::vector<VarT> *infoList)
+VarT *FindVariable(const TString &name,
+                  std::vector<VarT> *infoList)
 {
     // TODO(zmo): optimize this function.
     for (size_t ii = 0; ii < infoList->size(); ++ii)
@@ -99,6 +124,8 @@
     return NULL;
 }
 
+}
+
 CollectVariables::CollectVariables(std::vector<sh::Attribute> *attribs,
                                    std::vector<sh::Attribute> *outputVariables,
                                    std::vector<sh::Uniform> *uniforms,
@@ -125,14 +152,18 @@
 void CollectVariables::visitSymbol(TIntermSymbol *symbol)
 {
     ASSERT(symbol != NULL);
-    sh::ShaderVariable *var = NULL;
+    ShaderVariable *var = NULL;
     const TString &symbolName = symbol->getSymbol();
 
-    if (sh::IsVarying(symbol->getQualifier()))
+    if (IsVarying(symbol->getQualifier()))
     {
         var = FindVariable(symbolName, mVaryings);
     }
-    else if (symbol->getType() != EbtInterfaceBlock)
+    else if (symbol->getType().getBasicType() == EbtInterfaceBlock)
+    {
+        UNREACHABLE();
+    }
+    else
     {
         switch (symbol->getQualifier())
         {
@@ -148,12 +179,13 @@
                 const TInterfaceBlock *interfaceBlock = symbol->getType().getInterfaceBlock();
                 if (interfaceBlock)
                 {
-                    sh::InterfaceBlock *namedBlock = FindVariable(interfaceBlock->name(), mInterfaceBlocks);
+                    InterfaceBlock *namedBlock = FindVariable(interfaceBlock->name(), mInterfaceBlocks);
                     ASSERT(namedBlock);
                     var = FindVariable(symbolName, &namedBlock->fields);
 
                     // Set static use on the parent interface block here
                     namedBlock->staticUse = true;
+
                 }
                 else
                 {
@@ -167,7 +199,7 @@
           case EvqFragCoord:
             if (!mFragCoordAdded)
             {
-                sh::Varying info;
+                Varying info;
                 info.name = "gl_FragCoord";
                 info.mappedName = "gl_FragCoord";
                 info.type = GL_FLOAT_VEC4;
@@ -181,7 +213,7 @@
           case EvqFrontFacing:
             if (!mFrontFacingAdded)
             {
-                sh::Varying info;
+                Varying info;
                 info.name = "gl_FrontFacing";
                 info.mappedName = "gl_FrontFacing";
                 info.type = GL_BOOL;
@@ -195,7 +227,7 @@
           case EvqPointCoord:
             if (!mPointCoordAdded)
             {
-                sh::Varying info;
+                Varying info;
                 info.name = "gl_PointCoord";
                 info.mappedName = "gl_PointCoord";
                 info.type = GL_FLOAT_VEC2;
@@ -216,17 +248,17 @@
     }
 }
 
-template <typename VarT>
-class NameHashingTraverser : public sh::GetVariableTraverser<VarT>
+class NameHashingTraverser : public GetVariableTraverser
 {
   public:
-    NameHashingTraverser(std::vector<VarT> *output, ShHashFunction64 hashFunction)
-        : sh::GetVariableTraverser<VarT>(output),
-          mHashFunction(hashFunction)
+    NameHashingTraverser(ShHashFunction64 hashFunction)
+        : mHashFunction(hashFunction)
     {}
 
   private:
-    void visitVariable(VarT *variable)
+    DISALLOW_COPY_AND_ASSIGN(NameHashingTraverser);
+
+    virtual void visitVariable(ShaderVariable *variable)
     {
         TString stringName = TString(variable->name.c_str());
         variable->mappedName = TIntermTraverser::hash(stringName, mHashFunction).c_str();
@@ -238,16 +270,16 @@
 // Attributes, which cannot have struct fields, are a special case
 template <>
 void CollectVariables::visitVariable(const TIntermSymbol *variable,
-                                     std::vector<sh::Attribute> *infoList) const
+                                     std::vector<Attribute> *infoList) const
 {
     ASSERT(variable);
     const TType &type = variable->getType();
     ASSERT(!type.getStruct());
 
-    sh::Attribute attribute;
+    Attribute attribute;
 
-    attribute.type = sh::GLVariableType(type);
-    attribute.precision = sh::GLVariablePrecision(type);
+    attribute.type = GLVariableType(type);
+    attribute.precision = GLVariablePrecision(type);
     attribute.name = variable->getSymbol().c_str();
     attribute.arraySize = static_cast<unsigned int>(type.getArraySize());
     attribute.mappedName = TIntermTraverser::hash(variable->getSymbol(), mHashFunction).c_str();
@@ -258,29 +290,32 @@
 
 template <>
 void CollectVariables::visitVariable(const TIntermSymbol *variable,
-                                     std::vector<sh::InterfaceBlock> *infoList) const
+                                     std::vector<InterfaceBlock> *infoList) const
 {
-    sh::InterfaceBlock interfaceBlock;
+    InterfaceBlock interfaceBlock;
     const TInterfaceBlock *blockType = variable->getType().getInterfaceBlock();
-
-    bool isRowMajor = (blockType->matrixPacking() == EmpRowMajor);
+    ASSERT(blockType);
 
     interfaceBlock.name = blockType->name().c_str();
     interfaceBlock.mappedName = TIntermTraverser::hash(variable->getSymbol(), mHashFunction).c_str();
+    interfaceBlock.instanceName = (blockType->hasInstanceName() ? blockType->instanceName().c_str() : "");
     interfaceBlock.arraySize = variable->getArraySize();
-    interfaceBlock.isRowMajorLayout = isRowMajor;
-    interfaceBlock.layout = sh::GetBlockLayoutType(blockType->blockStorage());
+    interfaceBlock.isRowMajorLayout = (blockType->matrixPacking() == EmpRowMajor);
+    interfaceBlock.layout = GetBlockLayoutType(blockType->blockStorage());
 
-    ASSERT(blockType);
-    const TFieldList &blockFields = blockType->fields();
+    // Gather field information
+    const TFieldList &fieldList = blockType->fields();
 
-    for (size_t fieldIndex = 0; fieldIndex < blockFields.size(); fieldIndex++)
+    for (size_t fieldIndex = 0; fieldIndex < fieldList.size(); ++fieldIndex)
     {
-        const TField *field = blockFields[fieldIndex];
-        ASSERT(field);
+        const TField &field = *fieldList[fieldIndex];
+        const TString &fullFieldName = InterfaceBlockFieldName(*blockType, field);
+        const TType &fieldType = *field.type();
 
-        sh::GetInterfaceBlockFieldTraverser traverser(&interfaceBlock.fields, isRowMajor);
-        traverser.traverse(*field->type(), field->name());
+        GetVariableTraverser traverser;
+        traverser.traverse(fieldType, fullFieldName, &interfaceBlock.fields);
+
+        interfaceBlock.fields.back().isRowMajorLayout = (fieldType.getLayoutQualifier().matrixPacking == EmpRowMajor);
     }
 
     infoList->push_back(interfaceBlock);
@@ -290,8 +325,8 @@
 void CollectVariables::visitVariable(const TIntermSymbol *variable,
                                      std::vector<VarT> *infoList) const
 {
-    NameHashingTraverser<VarT> traverser(infoList, mHashFunction);
-    traverser.traverse(variable->getType(), variable->getSymbol());
+    NameHashingTraverser traverser(mHashFunction);
+    traverser.traverse(variable->getType(), variable->getSymbol(), infoList);
 }
 
 template <typename VarT>
@@ -328,10 +363,11 @@
             if (typedNode.getBasicType() == EbtInterfaceBlock)
             {
                 visitInfoList(sequence, mInterfaceBlocks);
+                visitChildren = false;
             }
             else if (qualifier == EvqAttribute || qualifier == EvqVertexIn ||
                      qualifier == EvqFragmentOut || qualifier == EvqUniform ||
-                     sh::IsVarying(qualifier))
+                     IsVarying(qualifier))
             {
                 switch (qualifier)
                 {
@@ -346,12 +382,7 @@
                     visitInfoList(sequence, mUniforms);
                     break;
                   default:
-                    // do not traverse invariant declarations such as
-                    //  "invariant gl_Position;"
-                    if (typedNode.getBasicType() != EbtInvariant)
-                    {
-                        visitInfoList(sequence, mVaryings);
-                    }
+                    visitInfoList(sequence, mVaryings);
                     break;
                 }
 
@@ -365,15 +396,43 @@
     return visitChildren;
 }
 
+bool CollectVariables::visitBinary(Visit, TIntermBinary *binaryNode)
+{
+    if (binaryNode->getOp() == EOpIndexDirectInterfaceBlock)
+    {
+        // NOTE: we do not determine static use for individual blocks of an array
+        TIntermTyped *blockNode = binaryNode->getLeft()->getAsTyped();
+        ASSERT(blockNode);
+
+        TIntermConstantUnion *constantUnion = binaryNode->getRight()->getAsConstantUnion();
+        ASSERT(constantUnion);
+
+        const TInterfaceBlock *interfaceBlock = blockNode->getType().getInterfaceBlock();
+        InterfaceBlock *namedBlock = FindVariable(interfaceBlock->name(), mInterfaceBlocks);
+        ASSERT(namedBlock);
+        namedBlock->staticUse = true;
+
+        unsigned int fieldIndex = constantUnion->getUConst(0);
+        ASSERT(fieldIndex < namedBlock->fields.size());
+        namedBlock->fields[fieldIndex].staticUse = true;
+        return false;
+    }
+
+    return true;
+}
+
 template <typename VarT>
-void ExpandVariables(const std::vector<VarT> &compact, std::vector<VarT> *expanded)
+void ExpandVariables(const std::vector<VarT> &compact,
+                     std::vector<ShaderVariable> *expanded)
 {
     for (size_t variableIndex = 0; variableIndex < compact.size(); variableIndex++)
     {
-        const VarT &variable = compact[variableIndex];
+        const ShaderVariable &variable = compact[variableIndex];
         ExpandVariable(variable, variable.name, variable.mappedName, variable.staticUse, expanded);
     }
 }
 
-template void ExpandVariables(const std::vector<sh::Uniform> &, std::vector<sh::Uniform> *);
-template void ExpandVariables(const std::vector<sh::Varying> &, std::vector<sh::Varying> *);
+template void ExpandVariables(const std::vector<Uniform> &, std::vector<ShaderVariable> *);
+template void ExpandVariables(const std::vector<Varying> &, std::vector<ShaderVariable> *);
+
+}
diff --git a/src/compiler/translator/VariableInfo.h b/src/compiler/translator/VariableInfo.h
index 916a115..5ac4c46 100644
--- a/src/compiler/translator/VariableInfo.h
+++ b/src/compiler/translator/VariableInfo.h
@@ -9,21 +9,25 @@
 
 #include <GLSLANG/ShaderLang.h>
 
-#include "compiler/translator/intermediate.h"
+#include "compiler/translator/IntermNode.h"
+
+namespace sh
+{
 
 // Traverses intermediate tree to collect all attributes, uniforms, varyings.
 class CollectVariables : public TIntermTraverser
 {
   public:
-    CollectVariables(std::vector<sh::Attribute> *attribs,
-                     std::vector<sh::Attribute> *outputVariables,
-                     std::vector<sh::Uniform> *uniforms,
-                     std::vector<sh::Varying> *varyings,
-                     std::vector<sh::InterfaceBlock> *interfaceBlocks,
+    CollectVariables(std::vector<Attribute> *attribs,
+                     std::vector<Attribute> *outputVariables,
+                     std::vector<Uniform> *uniforms,
+                     std::vector<Varying> *varyings,
+                     std::vector<InterfaceBlock> *interfaceBlocks,
                      ShHashFunction64 hashFunction);
 
     virtual void visitSymbol(TIntermSymbol *symbol);
     virtual bool visitAggregate(Visit, TIntermAggregate *node);
+    virtual bool visitBinary(Visit visit, TIntermBinary *binaryNode);
 
   private:
     template <typename VarT>
@@ -32,13 +36,13 @@
     template <typename VarT>
     void visitInfoList(const TIntermSequence &sequence, std::vector<VarT> *infoList) const;
 
-    std::vector<sh::Attribute> *mAttribs;
-    std::vector<sh::Attribute> *mOutputVariables;
-    std::vector<sh::Uniform> *mUniforms;
-    std::vector<sh::Varying> *mVaryings;
-    std::vector<sh::InterfaceBlock> *mInterfaceBlocks;
+    std::vector<Attribute> *mAttribs;
+    std::vector<Attribute> *mOutputVariables;
+    std::vector<Uniform> *mUniforms;
+    std::vector<Varying> *mVaryings;
+    std::vector<InterfaceBlock> *mInterfaceBlocks;
 
-    std::map<std::string, sh::InterfaceBlockField *> mInterfaceBlockFields;
+    std::map<std::string, InterfaceBlockField *> mInterfaceBlockFields;
 
     bool mPointCoordAdded;
     bool mFrontFacingAdded;
@@ -48,8 +52,10 @@
 };
 
 // Expand struct variables to flattened lists of split variables
-// Implemented for sh::Varying and sh::Uniform.
 template <typename VarT>
-void ExpandVariables(const std::vector<VarT> &compact, std::vector<VarT> *expanded);
+void ExpandVariables(const std::vector<VarT> &compact,
+                     std::vector<ShaderVariable> *expanded);
+
+}
 
 #endif  // COMPILER_VARIABLE_INFO_H_
diff --git a/src/compiler/translator/VersionGLSL.cpp b/src/compiler/translator/VersionGLSL.cpp
index 12dc9e0..8edbd00 100644
--- a/src/compiler/translator/VersionGLSL.cpp
+++ b/src/compiler/translator/VersionGLSL.cpp
@@ -67,6 +67,9 @@
             }
             break;
         }
+      case EOpInvariantDeclaration:
+        updateVersion(GLSL_VERSION_120);
+        break;
       case EOpParameters:
         {
             const TIntermSequence &params = *(node->getSequence());
diff --git a/src/compiler/translator/VersionGLSL.h b/src/compiler/translator/VersionGLSL.h
index de4141d..30f5a13 100644
--- a/src/compiler/translator/VersionGLSL.h
+++ b/src/compiler/translator/VersionGLSL.h
@@ -7,7 +7,7 @@
 #ifndef COMPILER_TRANSLATOR_VERSIONGLSL_H_
 #define COMPILER_TRANSLATOR_VERSIONGLSL_H_
 
-#include "compiler/translator/intermediate.h"
+#include "compiler/translator/IntermNode.h"
 
 // Traverses the intermediate tree to return the minimum GLSL version
 // required to legally access all built-in features used in the shader.
diff --git a/src/compiler/translator/depgraph/DependencyGraph.h b/src/compiler/translator/depgraph/DependencyGraph.h
index 5ea1cbb..bc25fe7 100644
--- a/src/compiler/translator/depgraph/DependencyGraph.h
+++ b/src/compiler/translator/depgraph/DependencyGraph.h
@@ -7,7 +7,7 @@
 #ifndef COMPILER_DEPGRAPH_DEPENDENCY_GRAPH_H
 #define COMPILER_DEPGRAPH_DEPENDENCY_GRAPH_H
 
-#include "compiler/translator/intermediate.h"
+#include "compiler/translator/IntermNode.h"
 
 #include <set>
 #include <stack>
diff --git a/src/compiler/translator/glslang.y b/src/compiler/translator/glslang.y
index fb2d835..5c945ad 100644
--- a/src/compiler/translator/glslang.y
+++ b/src/compiler/translator/glslang.y
@@ -209,38 +209,7 @@
 variable_identifier
     : IDENTIFIER {
         // The symbol table search was done in the lexical phase
-        const TSymbol *symbol = $1.symbol;
-        const TVariable *variable = 0;
-
-        if (!symbol)
-        {
-            context->error(@1, "undeclared identifier", $1.string->c_str());
-            context->recover();
-        }
-        else if (!symbol->isVariable())
-        {
-            context->error(@1, "variable expected", $1.string->c_str());
-            context->recover();
-        }
-        else
-        {
-            variable = static_cast<const TVariable*>(symbol);
-
-            if (context->symbolTable.findBuiltIn(variable->getName(), context->shaderVersion) &&
-                !variable->getExtension().empty() &&
-                context->extensionErrorCheck(@1, variable->getExtension()))
-            {
-                context->recover();
-            }
-        }
-
-        if (!variable)
-        {
-            TType type(EbtFloat, EbpUndefined);
-            TVariable *fakeVariable = new TVariable($1.string, type);
-            context->symbolTable.declare(fakeVariable);
-            variable = fakeVariable;
-        }
+        const TVariable *variable = context->getNamedVariable(@1, $1.string, $1.symbol);
 
         if (variable->getType().getQualifier() == EvqConst)
         {
@@ -816,9 +785,10 @@
         context->symbolTable.pop();
     }
     | init_declarator_list SEMICOLON {
-        if ($1.intermAggregate)
-            $1.intermAggregate->setOp(EOpDeclaration);
-        $$ = $1.intermAggregate;
+        TIntermAggregate *aggNode = $1.intermAggregate;
+        if (aggNode && aggNode->getOp() == EOpNull)
+            aggNode->setOp(EOpDeclaration);
+        $$ = aggNode;
     }
     | PRECISION precision_qualifier type_specifier_no_prec SEMICOLON {
         if (($2 == EbpHigh) && (context->shaderType == GL_FRAGMENT_SHADER) && !context->fragmentPrecisionHigh) {
@@ -1102,22 +1072,8 @@
         $$.intermAggregate = context->parseSingleInitDeclaration($$.type, @2, *$2.string, @3, $4);
     }
     | INVARIANT IDENTIFIER {
-        VERTEX_ONLY("invariant declaration", @1);
-        if (context->globalErrorCheck(@1, context->symbolTable.atGlobalLevel(), "invariant varying"))
-            context->recover();
-        $$.type.setBasic(EbtInvariant, EvqInvariantVaryingOut, @2);
-        if (!$2.symbol)
-        {
-            context->error(@2, "undeclared identifier declared as invariant", $2.string->c_str());
-            context->recover();
-            
-            $$.intermAggregate = 0;
-        }
-        else
-        {
-            TIntermSymbol *symbol = context->intermediate.addSymbol(0, *$2.string, TType($$.type), @2);
-            $$.intermAggregate = context->intermediate.makeAggregate(symbol, @2);
-        }
+        // $$.type is not used in invariant declarations.
+        $$.intermAggregate = context->parseInvariantDeclaration(@1, @2, $2.string, $2.symbol);
     }
     ;
 
diff --git a/src/compiler/translator/glslang_tab.cpp b/src/compiler/translator/glslang_tab.cpp
index 597db8b..6d483b1 100644
--- a/src/compiler/translator/glslang_tab.cpp
+++ b/src/compiler/translator/glslang_tab.cpp
@@ -795,32 +795,32 @@
 /* YYRLINE[YYN] -- source line where rule number YYN was defined.  */
 static const yytype_uint16 yyrline[] =
 {
-       0,   205,   205,   206,   209,   264,   267,   272,   277,   282,
-     287,   293,   296,   299,   302,   305,   315,   328,   336,   436,
-     439,   447,   450,   456,   460,   467,   473,   482,   490,   493,
-     503,   506,   516,   526,   547,   548,   549,   554,   555,   563,
-     574,   575,   583,   594,   598,   599,   609,   619,   629,   642,
-     643,   653,   666,   670,   674,   678,   679,   692,   693,   706,
-     707,   720,   721,   738,   739,   752,   753,   754,   755,   756,
-     760,   763,   774,   782,   790,   817,   822,   833,   837,   841,
-     845,   852,   907,   910,   917,   925,   946,   967,   977,  1005,
-    1010,  1020,  1025,  1035,  1038,  1041,  1044,  1050,  1057,  1060,
-    1064,  1068,  1072,  1079,  1083,  1087,  1094,  1098,  1102,  1123,
-    1132,  1138,  1141,  1147,  1153,  1160,  1169,  1178,  1186,  1189,
-    1196,  1200,  1207,  1210,  1214,  1218,  1227,  1236,  1244,  1254,
-    1266,  1269,  1272,  1278,  1285,  1288,  1294,  1297,  1300,  1306,
-    1309,  1324,  1328,  1332,  1336,  1340,  1344,  1349,  1354,  1359,
-    1364,  1369,  1374,  1379,  1384,  1389,  1394,  1399,  1404,  1409,
-    1414,  1419,  1424,  1429,  1434,  1439,  1444,  1449,  1453,  1457,
-    1461,  1465,  1469,  1473,  1477,  1481,  1485,  1489,  1493,  1497,
-    1501,  1505,  1509,  1517,  1525,  1529,  1542,  1542,  1545,  1545,
-    1551,  1554,  1570,  1573,  1582,  1586,  1592,  1599,  1614,  1618,
-    1622,  1623,  1629,  1630,  1631,  1632,  1633,  1637,  1638,  1638,
-    1638,  1648,  1649,  1653,  1653,  1654,  1654,  1659,  1662,  1672,
-    1675,  1681,  1682,  1686,  1694,  1698,  1708,  1713,  1730,  1730,
-    1735,  1735,  1742,  1742,  1750,  1753,  1759,  1762,  1768,  1772,
-    1779,  1786,  1793,  1800,  1811,  1820,  1824,  1831,  1834,  1840,
-    1840
+       0,   206,   206,   207,   210,   234,   237,   242,   247,   252,
+     257,   263,   266,   269,   272,   275,   285,   298,   306,   406,
+     409,   417,   420,   426,   430,   437,   443,   452,   460,   463,
+     473,   476,   486,   496,   517,   518,   519,   524,   525,   533,
+     544,   545,   553,   564,   568,   569,   579,   589,   599,   612,
+     613,   623,   636,   640,   644,   648,   649,   662,   663,   676,
+     677,   690,   691,   708,   709,   722,   723,   724,   725,   726,
+     730,   733,   744,   752,   760,   787,   793,   804,   808,   812,
+     816,   823,   879,   882,   889,   897,   918,   939,   949,   977,
+     982,   992,   997,  1007,  1010,  1013,  1016,  1022,  1029,  1032,
+    1036,  1040,  1044,  1051,  1055,  1059,  1066,  1070,  1074,  1081,
+    1090,  1096,  1099,  1105,  1111,  1118,  1127,  1136,  1144,  1147,
+    1154,  1158,  1165,  1168,  1172,  1176,  1185,  1194,  1202,  1212,
+    1224,  1227,  1230,  1236,  1243,  1246,  1252,  1255,  1258,  1264,
+    1267,  1282,  1286,  1290,  1294,  1298,  1302,  1307,  1312,  1317,
+    1322,  1327,  1332,  1337,  1342,  1347,  1352,  1357,  1362,  1367,
+    1372,  1377,  1382,  1387,  1392,  1397,  1402,  1407,  1411,  1415,
+    1419,  1423,  1427,  1431,  1435,  1439,  1443,  1447,  1451,  1455,
+    1459,  1463,  1467,  1475,  1483,  1487,  1500,  1500,  1503,  1503,
+    1509,  1512,  1528,  1531,  1540,  1544,  1550,  1557,  1572,  1576,
+    1580,  1581,  1587,  1588,  1589,  1590,  1591,  1595,  1596,  1596,
+    1596,  1606,  1607,  1611,  1611,  1612,  1612,  1617,  1620,  1630,
+    1633,  1639,  1640,  1644,  1652,  1656,  1666,  1671,  1688,  1688,
+    1693,  1693,  1700,  1700,  1708,  1711,  1717,  1720,  1726,  1730,
+    1737,  1744,  1751,  1758,  1769,  1778,  1782,  1789,  1792,  1798,
+    1798
 };
 #endif
 
@@ -2547,38 +2547,7 @@
 
     {
         // The symbol table search was done in the lexical phase
-        const TSymbol *symbol = (yyvsp[(1) - (1)].lex).symbol;
-        const TVariable *variable = 0;
-
-        if (!symbol)
-        {
-            context->error((yylsp[(1) - (1)]), "undeclared identifier", (yyvsp[(1) - (1)].lex).string->c_str());
-            context->recover();
-        }
-        else if (!symbol->isVariable())
-        {
-            context->error((yylsp[(1) - (1)]), "variable expected", (yyvsp[(1) - (1)].lex).string->c_str());
-            context->recover();
-        }
-        else
-        {
-            variable = static_cast<const TVariable*>(symbol);
-
-            if (context->symbolTable.findBuiltIn(variable->getName(), context->shaderVersion) &&
-                !variable->getExtension().empty() &&
-                context->extensionErrorCheck((yylsp[(1) - (1)]), variable->getExtension()))
-            {
-                context->recover();
-            }
-        }
-
-        if (!variable)
-        {
-            TType type(EbtFloat, EbpUndefined);
-            TVariable *fakeVariable = new TVariable((yyvsp[(1) - (1)].lex).string, type);
-            context->symbolTable.declare(fakeVariable);
-            variable = fakeVariable;
-        }
+        const TVariable *variable = context->getNamedVariable((yylsp[(1) - (1)]), (yyvsp[(1) - (1)].lex).string, (yyvsp[(1) - (1)].lex).symbol);
 
         if (variable->getType().getQualifier() == EvqConst)
         {
@@ -3344,9 +3313,10 @@
   case 75:
 
     {
-        if ((yyvsp[(1) - (2)].interm).intermAggregate)
-            (yyvsp[(1) - (2)].interm).intermAggregate->setOp(EOpDeclaration);
-        (yyval.interm.intermNode) = (yyvsp[(1) - (2)].interm).intermAggregate;
+        TIntermAggregate *aggNode = (yyvsp[(1) - (2)].interm).intermAggregate;
+        if (aggNode && aggNode->getOp() == EOpNull)
+            aggNode->setOp(EOpDeclaration);
+        (yyval.interm.intermNode) = aggNode;
     }
     break;
 
@@ -3719,22 +3689,8 @@
   case 108:
 
     {
-        VERTEX_ONLY("invariant declaration", (yylsp[(1) - (2)]));
-        if (context->globalErrorCheck((yylsp[(1) - (2)]), context->symbolTable.atGlobalLevel(), "invariant varying"))
-            context->recover();
-        (yyval.interm).type.setBasic(EbtInvariant, EvqInvariantVaryingOut, (yylsp[(2) - (2)]));
-        if (!(yyvsp[(2) - (2)].lex).symbol)
-        {
-            context->error((yylsp[(2) - (2)]), "undeclared identifier declared as invariant", (yyvsp[(2) - (2)].lex).string->c_str());
-            context->recover();
-            
-            (yyval.interm).intermAggregate = 0;
-        }
-        else
-        {
-            TIntermSymbol *symbol = context->intermediate.addSymbol(0, *(yyvsp[(2) - (2)].lex).string, TType((yyval.interm).type), (yylsp[(2) - (2)]));
-            (yyval.interm).intermAggregate = context->intermediate.makeAggregate(symbol, (yylsp[(2) - (2)]));
-        }
+        // $$.type is not used in invariant declarations.
+        (yyval.interm).intermAggregate = context->parseInvariantDeclaration((yylsp[(1) - (2)]), (yylsp[(2) - (2)]), (yyvsp[(2) - (2)].lex).string, (yyvsp[(2) - (2)].lex).symbol);
     }
     break;
 
diff --git a/src/compiler/translator/intermOut.cpp b/src/compiler/translator/intermOut.cpp
index a6e7ab4..56340c6 100644
--- a/src/compiler/translator/intermOut.cpp
+++ b/src/compiler/translator/intermOut.cpp
@@ -4,7 +4,7 @@
 // found in the LICENSE file.
 //
 
-#include "compiler/translator/localintermediate.h"
+#include "compiler/translator/Intermediate.h"
 #include "compiler/translator/SymbolTable.h"
 
 namespace
@@ -342,6 +342,7 @@
       case EOpMul:           out << "component-wise multiply"; break;
 
       case EOpDeclaration:   out << "Declaration: ";   break;
+      case EOpInvariantDeclaration: out << "Invariant Declaration: "; break;
 
       default:
         out.prefix(EPrefixError);
diff --git a/src/compiler/translator/timing/RestrictFragmentShaderTiming.h b/src/compiler/translator/timing/RestrictFragmentShaderTiming.h
index e77d8c2..80d5f7f 100644
--- a/src/compiler/translator/timing/RestrictFragmentShaderTiming.h
+++ b/src/compiler/translator/timing/RestrictFragmentShaderTiming.h
@@ -7,7 +7,7 @@
 #ifndef COMPILER_TIMING_RESTRICT_FRAGMENT_SHADER_TIMING_H_
 #define COMPILER_TIMING_RESTRICT_FRAGMENT_SHADER_TIMING_H_
 
-#include "compiler/translator/intermediate.h"
+#include "compiler/translator/IntermNode.h"
 #include "compiler/translator/depgraph/DependencyGraph.h"
 
 class TInfoSinkBase;
diff --git a/src/compiler/translator/timing/RestrictVertexShaderTiming.h b/src/compiler/translator/timing/RestrictVertexShaderTiming.h
index d461fbd..a626356 100644
--- a/src/compiler/translator/timing/RestrictVertexShaderTiming.h
+++ b/src/compiler/translator/timing/RestrictVertexShaderTiming.h
@@ -7,7 +7,7 @@
 #ifndef COMPILER_TIMING_RESTRICT_VERTEX_SHADER_TIMING_H_
 #define COMPILER_TIMING_RESTRICT_VERTEX_SHADER_TIMING_H_
 
-#include "compiler/translator/intermediate.h"
+#include "compiler/translator/IntermNode.h"
 #include "compiler/translator/InfoSink.h"
 
 class TInfoSinkBase;
diff --git a/src/compiler/translator/util.cpp b/src/compiler/translator/util.cpp
index 46ce99c..f74c7d1 100644
--- a/src/compiler/translator/util.cpp
+++ b/src/compiler/translator/util.cpp
@@ -282,7 +282,7 @@
 }
 
 template <typename VarT>
-void GetVariableTraverser<VarT>::traverse(const TType &type, const TString &name)
+void GetVariableTraverser::traverse(const TType &type, const TString &name, std::vector<VarT> *output)
 {
     const TStructure *structure = type.getStruct();
 
@@ -297,61 +297,27 @@
     }
     else
     {
+        // Note: this enum value is not exposed outside ANGLE
         variable.type = GL_STRUCT_ANGLEX;
-
-        mOutputStack.push(&variable.fields);
+        variable.structName = structure->name().c_str();
 
         const TFieldList &fields = structure->fields();
 
         for (size_t fieldIndex = 0; fieldIndex < fields.size(); fieldIndex++)
         {
             TField *field = fields[fieldIndex];
-            traverse(*field->type(), field->name());
+            traverse(*field->type(), field->name(), &variable.fields);
         }
-
-        mOutputStack.pop();
     }
 
     visitVariable(&variable);
 
-    ASSERT(!mOutputStack.empty());
-    mOutputStack.top()->push_back(variable);
-}
-
-template <typename VarT>
-GetVariableTraverser<VarT>::GetVariableTraverser(std::vector<VarT> *output)
-{
     ASSERT(output);
-    mOutputStack.push(output);
+    output->push_back(variable);
 }
 
-template class GetVariableTraverser<Uniform>;
-template class GetVariableTraverser<Varying>;
-template class GetVariableTraverser<InterfaceBlockField>;
-
-GetInterfaceBlockFieldTraverser::GetInterfaceBlockFieldTraverser(std::vector<InterfaceBlockField> *output, bool isRowMajorMatrix)
-    : GetVariableTraverser(output),
-      mIsRowMajorMatrix(isRowMajorMatrix)
-{
-}
-
-void GetInterfaceBlockFieldTraverser::visitVariable(InterfaceBlockField *newField)
-{
-    if (gl::IsMatrixType(newField->type))
-    {
-        newField->isRowMajorMatrix = mIsRowMajorMatrix;
-    }
-}
-
-BlockLayoutType GetBlockLayoutType(TLayoutBlockStorage blockStorage)
-{
-    switch (blockStorage)
-    {
-      case EbsPacked:         return BLOCKLAYOUT_PACKED;
-      case EbsShared:         return BLOCKLAYOUT_SHARED;
-      case EbsStd140:         return BLOCKLAYOUT_STANDARD;
-      default: UNREACHABLE(); return BLOCKLAYOUT_SHARED;
-    }
-}
+template void GetVariableTraverser::traverse(const TType &, const TString &, std::vector<Uniform> *);
+template void GetVariableTraverser::traverse(const TType &, const TString &, std::vector<Varying> *);
+template void GetVariableTraverser::traverse(const TType &, const TString &, std::vector<InterfaceBlockField> *);
 
 }
diff --git a/src/compiler/translator/util.h b/src/compiler/translator/util.h
index 2c16a1d..241e2cc 100644
--- a/src/compiler/translator/util.h
+++ b/src/compiler/translator/util.h
@@ -33,33 +33,22 @@
 bool IsVaryingOut(TQualifier qualifier);
 bool IsVarying(TQualifier qualifier);
 InterpolationType GetInterpolationType(TQualifier qualifier);
-BlockLayoutType GetBlockLayoutType(TLayoutBlockStorage blockStorage);
 TString ArrayString(const TType &type);
 
-template <typename VarT>
 class GetVariableTraverser
 {
   public:
-    GetVariableTraverser(std::vector<VarT> *output);
-    void traverse(const TType &type, const TString &name);
+    GetVariableTraverser() {}
+
+    template <typename VarT>
+    void traverse(const TType &type, const TString &name, std::vector<VarT> *output);
 
   protected:
     // May be overloaded
-    virtual void visitVariable(VarT *newVar) {}
+    virtual void visitVariable(ShaderVariable *newVar) {}
 
   private:
-    std::stack<std::vector<VarT> *> mOutputStack;
-};
-
-struct GetInterfaceBlockFieldTraverser : public GetVariableTraverser<InterfaceBlockField>
-{
-  public:
-    GetInterfaceBlockFieldTraverser(std::vector<InterfaceBlockField> *output, bool isRowMajorMatrix);
-
-  private:
-    virtual void visitVariable(InterfaceBlockField *newField);
-
-    bool mIsRowMajorMatrix;
+    DISALLOW_COPY_AND_ASSIGN(GetVariableTraverser);
 };
 
 }
diff --git a/src/copy_scripts.target.darwin-arm.mk b/src/copy_scripts.target.darwin-arm.mk
index 57d01e3..a406fcb 100644
--- a/src/copy_scripts.target.darwin-arm.mk
+++ b/src/copy_scripts.target.darwin-arm.mk
@@ -6,7 +6,6 @@
 LOCAL_MODULE := third_party_angle_src_copy_scripts_gyp
 LOCAL_MODULE_STEM := copy_scripts
 LOCAL_MODULE_SUFFIX := .stamp
-LOCAL_MODULE_TAGS := optional
 LOCAL_MODULE_TARGET_ARCH := $(TARGET_$(GYP_VAR_PREFIX)ARCH)
 gyp_intermediate_dir := $(call local-intermediates-dir,,$(GYP_VAR_PREFIX))
 gyp_shared_intermediate_dir := $(call intermediates-dir-for,GYP,shared,,,$(GYP_VAR_PREFIX))
diff --git a/src/copy_scripts.target.darwin-arm64.mk b/src/copy_scripts.target.darwin-arm64.mk
index 57d01e3..a406fcb 100644
--- a/src/copy_scripts.target.darwin-arm64.mk
+++ b/src/copy_scripts.target.darwin-arm64.mk
@@ -6,7 +6,6 @@
 LOCAL_MODULE := third_party_angle_src_copy_scripts_gyp
 LOCAL_MODULE_STEM := copy_scripts
 LOCAL_MODULE_SUFFIX := .stamp
-LOCAL_MODULE_TAGS := optional
 LOCAL_MODULE_TARGET_ARCH := $(TARGET_$(GYP_VAR_PREFIX)ARCH)
 gyp_intermediate_dir := $(call local-intermediates-dir,,$(GYP_VAR_PREFIX))
 gyp_shared_intermediate_dir := $(call intermediates-dir-for,GYP,shared,,,$(GYP_VAR_PREFIX))
diff --git a/src/copy_scripts.target.darwin-mips.mk b/src/copy_scripts.target.darwin-mips.mk
index 57d01e3..a406fcb 100644
--- a/src/copy_scripts.target.darwin-mips.mk
+++ b/src/copy_scripts.target.darwin-mips.mk
@@ -6,7 +6,6 @@
 LOCAL_MODULE := third_party_angle_src_copy_scripts_gyp
 LOCAL_MODULE_STEM := copy_scripts
 LOCAL_MODULE_SUFFIX := .stamp
-LOCAL_MODULE_TAGS := optional
 LOCAL_MODULE_TARGET_ARCH := $(TARGET_$(GYP_VAR_PREFIX)ARCH)
 gyp_intermediate_dir := $(call local-intermediates-dir,,$(GYP_VAR_PREFIX))
 gyp_shared_intermediate_dir := $(call intermediates-dir-for,GYP,shared,,,$(GYP_VAR_PREFIX))
diff --git a/src/copy_scripts.target.darwin-x86.mk b/src/copy_scripts.target.darwin-x86.mk
index 57d01e3..a406fcb 100644
--- a/src/copy_scripts.target.darwin-x86.mk
+++ b/src/copy_scripts.target.darwin-x86.mk
@@ -6,7 +6,6 @@
 LOCAL_MODULE := third_party_angle_src_copy_scripts_gyp
 LOCAL_MODULE_STEM := copy_scripts
 LOCAL_MODULE_SUFFIX := .stamp
-LOCAL_MODULE_TAGS := optional
 LOCAL_MODULE_TARGET_ARCH := $(TARGET_$(GYP_VAR_PREFIX)ARCH)
 gyp_intermediate_dir := $(call local-intermediates-dir,,$(GYP_VAR_PREFIX))
 gyp_shared_intermediate_dir := $(call intermediates-dir-for,GYP,shared,,,$(GYP_VAR_PREFIX))
diff --git a/src/copy_scripts.target.darwin-x86_64.mk b/src/copy_scripts.target.darwin-x86_64.mk
index 57d01e3..a406fcb 100644
--- a/src/copy_scripts.target.darwin-x86_64.mk
+++ b/src/copy_scripts.target.darwin-x86_64.mk
@@ -6,7 +6,6 @@
 LOCAL_MODULE := third_party_angle_src_copy_scripts_gyp
 LOCAL_MODULE_STEM := copy_scripts
 LOCAL_MODULE_SUFFIX := .stamp
-LOCAL_MODULE_TAGS := optional
 LOCAL_MODULE_TARGET_ARCH := $(TARGET_$(GYP_VAR_PREFIX)ARCH)
 gyp_intermediate_dir := $(call local-intermediates-dir,,$(GYP_VAR_PREFIX))
 gyp_shared_intermediate_dir := $(call intermediates-dir-for,GYP,shared,,,$(GYP_VAR_PREFIX))
diff --git a/src/copy_scripts.target.linux-arm.mk b/src/copy_scripts.target.linux-arm.mk
index 57d01e3..a406fcb 100644
--- a/src/copy_scripts.target.linux-arm.mk
+++ b/src/copy_scripts.target.linux-arm.mk
@@ -6,7 +6,6 @@
 LOCAL_MODULE := third_party_angle_src_copy_scripts_gyp
 LOCAL_MODULE_STEM := copy_scripts
 LOCAL_MODULE_SUFFIX := .stamp
-LOCAL_MODULE_TAGS := optional
 LOCAL_MODULE_TARGET_ARCH := $(TARGET_$(GYP_VAR_PREFIX)ARCH)
 gyp_intermediate_dir := $(call local-intermediates-dir,,$(GYP_VAR_PREFIX))
 gyp_shared_intermediate_dir := $(call intermediates-dir-for,GYP,shared,,,$(GYP_VAR_PREFIX))
diff --git a/src/copy_scripts.target.linux-arm64.mk b/src/copy_scripts.target.linux-arm64.mk
index 57d01e3..a406fcb 100644
--- a/src/copy_scripts.target.linux-arm64.mk
+++ b/src/copy_scripts.target.linux-arm64.mk
@@ -6,7 +6,6 @@
 LOCAL_MODULE := third_party_angle_src_copy_scripts_gyp
 LOCAL_MODULE_STEM := copy_scripts
 LOCAL_MODULE_SUFFIX := .stamp
-LOCAL_MODULE_TAGS := optional
 LOCAL_MODULE_TARGET_ARCH := $(TARGET_$(GYP_VAR_PREFIX)ARCH)
 gyp_intermediate_dir := $(call local-intermediates-dir,,$(GYP_VAR_PREFIX))
 gyp_shared_intermediate_dir := $(call intermediates-dir-for,GYP,shared,,,$(GYP_VAR_PREFIX))
diff --git a/src/copy_scripts.target.linux-mips.mk b/src/copy_scripts.target.linux-mips.mk
index 57d01e3..a406fcb 100644
--- a/src/copy_scripts.target.linux-mips.mk
+++ b/src/copy_scripts.target.linux-mips.mk
@@ -6,7 +6,6 @@
 LOCAL_MODULE := third_party_angle_src_copy_scripts_gyp
 LOCAL_MODULE_STEM := copy_scripts
 LOCAL_MODULE_SUFFIX := .stamp
-LOCAL_MODULE_TAGS := optional
 LOCAL_MODULE_TARGET_ARCH := $(TARGET_$(GYP_VAR_PREFIX)ARCH)
 gyp_intermediate_dir := $(call local-intermediates-dir,,$(GYP_VAR_PREFIX))
 gyp_shared_intermediate_dir := $(call intermediates-dir-for,GYP,shared,,,$(GYP_VAR_PREFIX))
diff --git a/src/copy_scripts.target.linux-x86.mk b/src/copy_scripts.target.linux-x86.mk
index 57d01e3..a406fcb 100644
--- a/src/copy_scripts.target.linux-x86.mk
+++ b/src/copy_scripts.target.linux-x86.mk
@@ -6,7 +6,6 @@
 LOCAL_MODULE := third_party_angle_src_copy_scripts_gyp
 LOCAL_MODULE_STEM := copy_scripts
 LOCAL_MODULE_SUFFIX := .stamp
-LOCAL_MODULE_TAGS := optional
 LOCAL_MODULE_TARGET_ARCH := $(TARGET_$(GYP_VAR_PREFIX)ARCH)
 gyp_intermediate_dir := $(call local-intermediates-dir,,$(GYP_VAR_PREFIX))
 gyp_shared_intermediate_dir := $(call intermediates-dir-for,GYP,shared,,,$(GYP_VAR_PREFIX))
diff --git a/src/copy_scripts.target.linux-x86_64.mk b/src/copy_scripts.target.linux-x86_64.mk
index 57d01e3..a406fcb 100644
--- a/src/copy_scripts.target.linux-x86_64.mk
+++ b/src/copy_scripts.target.linux-x86_64.mk
@@ -6,7 +6,6 @@
 LOCAL_MODULE := third_party_angle_src_copy_scripts_gyp
 LOCAL_MODULE_STEM := copy_scripts
 LOCAL_MODULE_SUFFIX := .stamp
-LOCAL_MODULE_TAGS := optional
 LOCAL_MODULE_TARGET_ARCH := $(TARGET_$(GYP_VAR_PREFIX)ARCH)
 gyp_intermediate_dir := $(call local-intermediates-dir,,$(GYP_VAR_PREFIX))
 gyp_shared_intermediate_dir := $(call intermediates-dir-for,GYP,shared,,,$(GYP_VAR_PREFIX))
diff --git a/src/libEGL.gypi b/src/libEGL.gypi
index 96cd0ff..85ac315 100644
--- a/src/libEGL.gypi
+++ b/src/libEGL.gypi
@@ -25,6 +25,7 @@
             '../include/angle_gl.h',
             'common/RefCountObject.cpp',
             'common/RefCountObject.h',
+            'common/angleutils.cpp',
             'common/angleutils.h',
             'common/debug.cpp',
             'common/debug.h',
diff --git a/src/libEGL/libEGL.cpp b/src/libEGL/libEGL.cpp
index 23df448..f9a4780 100644
--- a/src/libEGL/libEGL.cpp
+++ b/src/libEGL/libEGL.cpp
@@ -794,12 +794,19 @@
     egl::Display *display = static_cast<egl::Display*>(dpy);
     gl::Context *context = static_cast<gl::Context*>(ctx);
 
+    bool noContext = (ctx == EGL_NO_CONTEXT);
+    bool noSurface = (draw == EGL_NO_SURFACE || read == EGL_NO_SURFACE);
+    if (noContext != noSurface)
+    {
+        return egl::error(EGL_BAD_MATCH, EGL_FALSE);
+    }
+
     if (ctx != EGL_NO_CONTEXT && !validateContext(display, context))
     {
         return EGL_FALSE;
     }
 
-    if (dpy != EGL_NO_DISPLAY)
+    if (dpy != EGL_NO_DISPLAY && display->isInitialized())
     {
         rx::Renderer *renderer = display->getRenderer();
         if (renderer->testDeviceLost(true))
diff --git a/src/libGLESv2.gypi b/src/libGLESv2.gypi
index f8061a2..7f238af 100644
--- a/src/libGLESv2.gypi
+++ b/src/libGLESv2.gypi
@@ -8,7 +8,7 @@
         'angle_enable_d3d9%': 1,
         'angle_enable_d3d11%': 1,
         # These file lists are shared with the GN build.
-        'angle_libglesv2_sources':
+        'angle_libangle_sources':
         [
             '../include/EGL/egl.h',
             '../include/EGL/eglext.h',
@@ -25,6 +25,7 @@
             '../include/angle_gl.h',
             'common/RefCountObject.cpp',
             'common/RefCountObject.h',
+            'common/angleutils.cpp',
             'common/angleutils.h',
             'common/blocklayout.cpp',
             'common/blocklayout.h',
@@ -47,8 +48,8 @@
             'libGLESv2/Caps.h',
             'libGLESv2/Context.cpp',
             'libGLESv2/Context.h',
-            'libGLESv2/DynamicHLSL.cpp',
-            'libGLESv2/DynamicHLSL.h',
+            'libGLESv2/Error.cpp',
+            'libGLESv2/Error.h',
             'libGLESv2/Fence.cpp',
             'libGLESv2/Fence.h',
             'libGLESv2/Float16ToFloat32.cpp',
@@ -58,6 +59,8 @@
             'libGLESv2/FramebufferAttachment.h',
             'libGLESv2/HandleAllocator.cpp',
             'libGLESv2/HandleAllocator.h',
+            'libGLESv2/ImageIndex.h',
+            'libGLESv2/ImageIndex.cpp',
             'libGLESv2/Program.cpp',
             'libGLESv2/Program.h',
             'libGLESv2/ProgramBinary.cpp',
@@ -89,13 +92,8 @@
             'libGLESv2/constants.h',
             'libGLESv2/formatutils.cpp',
             'libGLESv2/formatutils.h',
-            'libGLESv2/libGLESv2.cpp',
-            'libGLESv2/libGLESv2.def',
-            'libGLESv2/libGLESv2.rc',
             'libGLESv2/main.cpp',
             'libGLESv2/main.h',
-            'libGLESv2/precompiled.cpp',
-            'libGLESv2/precompiled.h',
             'libGLESv2/queryconversions.cpp',
             'libGLESv2/queryconversions.h',
             'libGLESv2/renderer/BufferImpl.h',
@@ -104,17 +102,22 @@
             'libGLESv2/renderer/Image.h',
             'libGLESv2/renderer/IndexRangeCache.cpp',
             'libGLESv2/renderer/IndexRangeCache.h',
+            'libGLESv2/renderer/ProgramImpl.h',
             'libGLESv2/renderer/QueryImpl.h',
             'libGLESv2/renderer/RenderTarget.h',
             'libGLESv2/renderer/Renderer.cpp',
             'libGLESv2/renderer/Renderer.h',
             'libGLESv2/renderer/ShaderExecutable.h',
+            'libGLESv2/renderer/ShaderImpl.h',
             'libGLESv2/renderer/SwapChain.h',
             'libGLESv2/renderer/TextureImpl.h',
+            'libGLESv2/renderer/TransformFeedbackImpl.h',
             'libGLESv2/renderer/VertexArrayImpl.h',
             'libGLESv2/renderer/copyimage.cpp',
             'libGLESv2/renderer/copyimage.h',
+            'libGLESv2/renderer/copyimage.inl',
             'libGLESv2/renderer/copyvertex.h',
+            'libGLESv2/renderer/copyvertex.inl',
             'libGLESv2/renderer/generatemip.h',
             'libGLESv2/renderer/generatemip.inl',
             'libGLESv2/renderer/imageformats.h',
@@ -139,6 +142,8 @@
         [
             'libGLESv2/renderer/d3d/BufferD3D.cpp',
             'libGLESv2/renderer/d3d/BufferD3D.h',
+            'libGLESv2/renderer/d3d/DynamicHLSL.cpp',
+            'libGLESv2/renderer/d3d/DynamicHLSL.h',
             'libGLESv2/renderer/d3d/HLSLCompiler.cpp',
             'libGLESv2/renderer/d3d/HLSLCompiler.h',
             'libGLESv2/renderer/d3d/ImageD3D.cpp',
@@ -149,10 +154,16 @@
             'libGLESv2/renderer/d3d/IndexDataManager.h',
             'libGLESv2/renderer/d3d/MemoryBuffer.cpp',
             'libGLESv2/renderer/d3d/MemoryBuffer.h',
+            'libGLESv2/renderer/d3d/ProgramD3D.cpp',
+            'libGLESv2/renderer/d3d/ProgramD3D.h',
+            'libGLESv2/renderer/d3d/ShaderD3D.cpp',
+            'libGLESv2/renderer/d3d/ShaderD3D.h',
             'libGLESv2/renderer/d3d/TextureD3D.cpp',
             'libGLESv2/renderer/d3d/TextureD3D.h',
             'libGLESv2/renderer/d3d/TextureStorage.cpp',
             'libGLESv2/renderer/d3d/TextureStorage.h',
+            'libGLESv2/renderer/d3d/TransformFeedbackD3D.cpp',
+            'libGLESv2/renderer/d3d/TransformFeedbackD3D.h',
             'libGLESv2/renderer/d3d/VertexBuffer.cpp',
             'libGLESv2/renderer/d3d/VertexBuffer.h',
             'libGLESv2/renderer/d3d/VertexDataManager.cpp',
@@ -299,8 +310,9 @@
             'targets':
             [
                 {
-                    'target_name': 'libGLESv2',
-                    'type': 'shared_library',
+                    'target_name': 'libANGLE',
+                    #TODO(jamdill/geofflang): support shared
+                    'type': 'static_library',
                     'dependencies': [ 'translator', 'commit_id', 'copy_compiler_dll' ],
                     'includes': [ '../build/common_defines.gypi', ],
                     'include_dirs':
@@ -311,7 +323,7 @@
                     ],
                     'sources':
                     [
-                        '<@(angle_libglesv2_sources)',
+                        '<@(angle_libangle_sources)',
                     ],
                     'defines':
                     [
@@ -320,6 +332,22 @@
                         'EGLAPI=',
                         'ANGLE_PRELOADED_D3DCOMPILER_MODULE_NAMES={ "d3dcompiler_46.dll", "d3dcompiler_43.dll" }',
                     ],
+                    'direct_dependent_settings':
+                    {
+                        'include_dirs':
+                        [
+                            '.',
+                            '../include',
+                            'libGLESv2',
+                        ],
+                        'defines':
+                        [
+                            'GL_APICALL=',
+                            'GL_GLEXT_PROTOTYPES=',
+                            'EGLAPI=',
+                            'ANGLE_PRELOADED_D3DCOMPILER_MODULE_NAMES={ "d3dcompiler_46.dll", "d3dcompiler_43.dll" }',
+                        ],
+                    },
                     'conditions':
                     [
                         ['angle_enable_d3d9==1 or angle_enable_d3d11==1',
@@ -339,15 +367,18 @@
                             [
                                 'ANGLE_ENABLE_D3D9',
                             ],
-                            'msvs_settings':
+                            'link_settings':
                             {
-                                'VCLinkerTool':
+                                'msvs_settings':
                                 {
-                                    'AdditionalDependencies':
-                                    [
-                                        'd3d9.lib',
-                                    ]
-                                }
+                                    'VCLinkerTool':
+                                    {
+                                        'AdditionalDependencies':
+                                        [
+                                            'd3d9.lib',
+                                        ]
+                                    }
+                                },
                             },
                         }],
                         ['angle_enable_d3d11==1',
@@ -360,14 +391,17 @@
                             [
                                 'ANGLE_ENABLE_D3D11',
                             ],
-                            'msvs_settings':
+                            'link_settings':
                             {
-                                'VCLinkerTool':
+                                'msvs_settings':
                                 {
-                                    'AdditionalDependencies':
-                                    [
-                                        'dxguid.lib',
-                                    ],
+                                    'VCLinkerTool':
+                                    {
+                                        'AdditionalDependencies':
+                                        [
+                                            'dxguid.lib',
+                                        ]
+                                    }
                                 },
                             },
                         }],
@@ -394,6 +428,31 @@
                         },
                     },
                 },
+                {
+                    'target_name': 'libGLESv2',
+                    'type': 'shared_library',
+                    'dependencies': [ 'libANGLE' ],
+                    'includes': [ '../build/common_defines.gypi', ],
+                    'sources':
+                    [
+                        'libGLESv2/libGLESv2.cpp',
+                        'libGLESv2/libGLESv2.def',
+                        'libGLESv2/libGLESv2.rc',
+                    ],
+                },
+                {
+                    'target_name': 'libGLESv2_static',
+                    'type': 'static_library',
+                    # make sure we depend on commit_id as a hard dependency, otherwise
+                    # we will try to build the static_lib in parallel
+                    'dependencies': [ 'libANGLE', 'commit_id' ],
+                    'includes': [ '../build/common_defines.gypi', ],
+                    'sources':
+                    [
+                        'libGLESv2/libGLESv2.cpp',
+                        'libGLESv2/libGLESv2.rc',
+                    ],
+                },
             ],
         },
         ],
diff --git a/src/libGLESv2/BinaryStream.h b/src/libGLESv2/BinaryStream.h
index 1cbfc67..4d7dde0 100644
--- a/src/libGLESv2/BinaryStream.h
+++ b/src/libGLESv2/BinaryStream.h
@@ -12,6 +12,10 @@
 #include "common/angleutils.h"
 #include "common/mathutil.h"
 
+#include <cstddef>
+#include <string>
+#include <vector>
+
 namespace gl
 {
 
diff --git a/src/libGLESv2/Buffer.cpp b/src/libGLESv2/Buffer.cpp
index 7d31a82..3b2a1a9 100644
--- a/src/libGLESv2/Buffer.cpp
+++ b/src/libGLESv2/Buffer.cpp
@@ -1,4 +1,3 @@
-#include "precompiled.h"
 //
 // 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
@@ -31,59 +30,99 @@
 
 Buffer::~Buffer()
 {
-    delete mBuffer;
+    SafeDelete(mBuffer);
 }
 
-void Buffer::bufferData(const void *data, GLsizeiptr size, GLenum usage)
+Error Buffer::bufferData(const void *data, GLsizeiptr size, GLenum usage)
 {
+    gl::Error error = mBuffer->setData(data, size, usage);
+    if (error.isError())
+    {
+        return error;
+    }
+
+    mIndexRangeCache.clear();
     mUsage = usage;
     mSize = size;
-    mBuffer->setData(data, size, usage);
+
+    return error;
 }
 
-void Buffer::bufferSubData(const void *data, GLsizeiptr size, GLintptr offset)
+Error Buffer::bufferSubData(const void *data, GLsizeiptr size, GLintptr offset)
 {
-    mBuffer->setSubData(data, size, offset);
+    gl::Error error = mBuffer->setSubData(data, size, offset);
+    if (error.isError())
+    {
+        return error;
+    }
+
+    mIndexRangeCache.invalidateRange(offset, size);
+
+    return error;
 }
 
-void Buffer::copyBufferSubData(Buffer* source, GLintptr sourceOffset, GLintptr destOffset, GLsizeiptr size)
+Error Buffer::copyBufferSubData(Buffer* source, GLintptr sourceOffset, GLintptr destOffset, GLsizeiptr size)
 {
-    mBuffer->copySubData(source->getImplementation(), sourceOffset, destOffset, size);
+    gl::Error error = mBuffer->copySubData(source->getImplementation(), sourceOffset, destOffset, size);
+    if (error.isError())
+    {
+        return error;
+    }
+
+    mIndexRangeCache.invalidateRange(destOffset, size);
+
+    return error;
 }
 
-GLvoid *Buffer::mapRange(GLintptr offset, GLsizeiptr length, GLbitfield access)
+Error Buffer::mapRange(GLintptr offset, GLsizeiptr length, GLbitfield access)
 {
     ASSERT(!mMapped);
     ASSERT(offset + length <= mSize);
 
-    void *dataPointer = mBuffer->map(offset, length, access);
+    Error error = mBuffer->map(offset, length, access, &mMapPointer);
+    if (error.isError())
+    {
+        mMapPointer = NULL;
+        return error;
+    }
 
     mMapped = GL_TRUE;
-    mMapPointer = static_cast<GLvoid*>(static_cast<GLubyte*>(dataPointer));
     mMapOffset = static_cast<GLint64>(offset);
     mMapLength = static_cast<GLint64>(length);
     mAccessFlags = static_cast<GLint>(access);
 
-    return mMapPointer;
+    if ((access & GL_MAP_WRITE_BIT) > 0)
+    {
+        mIndexRangeCache.invalidateRange(offset, length);
+    }
+
+    return error;
 }
 
-void Buffer::unmap()
+Error Buffer::unmap()
 {
     ASSERT(mMapped);
 
-    mBuffer->unmap();
+    Error error = mBuffer->unmap();
+    if (error.isError())
+    {
+        return error;
+    }
 
     mMapped = GL_FALSE;
     mMapPointer = NULL;
     mMapOffset = 0;
     mMapLength = 0;
     mAccessFlags = 0;
+
+    return error;
 }
 
 void Buffer::markTransformFeedbackUsage()
 {
     // TODO: Only used by the DX11 backend. Refactor to a more appropriate place.
     mBuffer->markTransformFeedbackUsage();
+    mIndexRangeCache.clear();
 }
 
 }
diff --git a/src/libGLESv2/Buffer.h b/src/libGLESv2/Buffer.h
index 389c3d4..35a6767 100644
--- a/src/libGLESv2/Buffer.h
+++ b/src/libGLESv2/Buffer.h
@@ -11,8 +11,11 @@
 #ifndef LIBGLESV2_BUFFER_H_
 #define LIBGLESV2_BUFFER_H_
 
+#include "libGLESv2/Error.h"
+
 #include "common/angleutils.h"
 #include "common/RefCountObject.h"
+#include "libGLESv2/renderer/IndexRangeCache.h"
 
 namespace rx
 {
@@ -30,13 +33,13 @@
 
     virtual ~Buffer();
 
-    void bufferData(const void *data, GLsizeiptr size, GLenum usage);
-    void bufferSubData(const void *data, GLsizeiptr size, GLintptr offset);
-    void copyBufferSubData(Buffer* source, GLintptr sourceOffset, GLintptr destOffset, GLsizeiptr size);
-    GLvoid *mapRange(GLintptr offset, GLsizeiptr length, GLbitfield access);
-    void unmap();
+    Error bufferData(const void *data, GLsizeiptr size, GLenum usage);
+    Error bufferSubData(const void *data, GLsizeiptr size, GLintptr offset);
+    Error copyBufferSubData(Buffer* source, GLintptr sourceOffset, GLintptr destOffset, GLsizeiptr size);
+    Error mapRange(GLintptr offset, GLsizeiptr length, GLbitfield access);
+    Error unmap();
 
-    GLenum  getUsage() const { return mUsage; }
+    GLenum getUsage() const { return mUsage; }
     GLint getAccessFlags() const {  return mAccessFlags; }
     GLboolean isMapped() const { return mMapped; }
     GLvoid *getMapPointer() const { return mMapPointer; }
@@ -48,18 +51,23 @@
 
     void markTransformFeedbackUsage();
 
+    rx::IndexRangeCache *getIndexRangeCache() { return &mIndexRangeCache; }
+    const rx::IndexRangeCache *getIndexRangeCache() const { return &mIndexRangeCache; }
+
   private:
     DISALLOW_COPY_AND_ASSIGN(Buffer);
 
     rx::BufferImpl *mBuffer;
 
     GLenum mUsage;
-    GLsizeiptr mSize;
+    GLint64 mSize;
     GLint mAccessFlags;
     GLboolean mMapped;
     GLvoid *mMapPointer;
     GLint64 mMapOffset;
     GLint64 mMapLength;
+
+    rx::IndexRangeCache mIndexRangeCache;
 };
 
 }
diff --git a/src/libGLESv2/Caps.cpp b/src/libGLESv2/Caps.cpp
index 26ba4ad..0c2b821 100644
--- a/src/libGLESv2/Caps.cpp
+++ b/src/libGLESv2/Caps.cpp
@@ -380,7 +380,40 @@
       maxViewportHeight(0),
       minAliasedPointSize(0),
       maxAliasedPointSize(0),
-      minAliasedLineWidth(0)
+      minAliasedLineWidth(0),
+      // Table 6.29
+      maxElementsIndices(0),
+      maxElementsVertices(0),
+      maxServerWaitTimeout(0),
+      // Table 6.31
+      maxVertexAttributes(0),
+      maxVertexUniformComponents(0),
+      maxVertexUniformVectors(0),
+      maxVertexUniformBlocks(0),
+      maxVertexOutputComponents(0),
+      maxVertexTextureImageUnits(0),
+      // Table 6.32
+      maxFragmentUniformComponents(0),
+      maxFragmentUniformVectors(0),
+      maxFragmentUniformBlocks(0),
+      maxFragmentInputComponents(0),
+      maxTextureImageUnits(0),
+      minProgramTexelOffset(0),
+      maxProgramTexelOffset(0),
+
+      maxUniformBufferBindings(0),
+      maxUniformBlockSize(0),
+      uniformBufferOffsetAlignment(0),
+      maxCombinedUniformBlocks(0),
+      maxCombinedVertexUniformComponents(0),
+      maxCombinedFragmentUniformComponents(0),
+      maxVaryingComponents(0),
+      maxVaryingVectors(0),
+      maxCombinedTextureImageUnits(0),
+
+      maxTransformFeedbackInterleavedComponents(0),
+      maxTransformFeedbackSeparateAttributes(0),
+      maxTransformFeedbackSeparateComponents(0)
 {
 }
 
diff --git a/src/libGLESv2/Caps.h b/src/libGLESv2/Caps.h
index b353f12..a00e554 100644
--- a/src/libGLESv2/Caps.h
+++ b/src/libGLESv2/Caps.h
@@ -226,6 +226,46 @@
     GLfloat minAliasedLineWidth;
     GLfloat maxAliasedLineWidth;
 
+    // Table 6.29, implementation dependent values (cont.)
+    GLuint maxElementsIndices;
+    GLuint maxElementsVertices;
+    std::vector<GLenum> compressedTextureFormats;
+    std::vector<GLenum> programBinaryFormats;
+    std::vector<GLenum> shaderBinaryFormats;
+    GLuint64 maxServerWaitTimeout;
+
+    // Table 6.31, implementation dependent vertex shader limits
+    GLuint maxVertexAttributes;
+    GLuint maxVertexUniformComponents;
+    GLuint maxVertexUniformVectors;
+    GLuint maxVertexUniformBlocks;
+    GLuint maxVertexOutputComponents;
+    GLuint maxVertexTextureImageUnits;
+
+    // Table 6.32, implementation dependent fragment shader limits
+    GLuint maxFragmentUniformComponents;
+    GLuint maxFragmentUniformVectors;
+    GLuint maxFragmentUniformBlocks;
+    GLuint maxFragmentInputComponents;
+    GLuint maxTextureImageUnits;
+    GLint minProgramTexelOffset;
+    GLint maxProgramTexelOffset;
+
+    // Table 6.33, implementation dependent aggregate shader limits
+    GLuint maxUniformBufferBindings;
+    GLuint64 maxUniformBlockSize;
+    GLuint uniformBufferOffsetAlignment;
+    GLuint maxCombinedUniformBlocks;
+    GLuint64 maxCombinedVertexUniformComponents;
+    GLuint64 maxCombinedFragmentUniformComponents;
+    GLuint maxVaryingComponents;
+    GLuint maxVaryingVectors;
+    GLuint maxCombinedTextureImageUnits;
+
+    // Table 6.34, implementation dependent transform feedback limits
+    GLuint maxTransformFeedbackInterleavedComponents;
+    GLuint maxTransformFeedbackSeparateAttributes;
+    GLuint maxTransformFeedbackSeparateComponents;
 };
 
 }
diff --git a/src/libGLESv2/Context.cpp b/src/libGLESv2/Context.cpp
index a16a13f..c467fa8 100644
--- a/src/libGLESv2/Context.cpp
+++ b/src/libGLESv2/Context.cpp
@@ -1,4 +1,3 @@
-#include "precompiled.h"
 //
 // 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
@@ -12,6 +11,7 @@
 
 #include "libGLESv2/main.h"
 #include "common/utilities.h"
+#include "common/platform.h"
 #include "libGLESv2/formatutils.h"
 #include "libGLESv2/Buffer.h"
 #include "libGLESv2/Fence.h"
@@ -24,7 +24,6 @@
 #include "libGLESv2/Texture.h"
 #include "libGLESv2/ResourceManager.h"
 #include "libGLESv2/renderer/d3d/IndexDataManager.h"
-#include "libGLESv2/renderer/RenderTarget.h"
 #include "libGLESv2/renderer/Renderer.h"
 #include "libGLESv2/VertexArray.h"
 #include "libGLESv2/Sampler.h"
@@ -33,8 +32,7 @@
 
 #include "libEGL/Surface.h"
 
-#undef near
-#undef far
+#include <sstream>
 
 namespace gl
 {
@@ -45,6 +43,7 @@
     ASSERT(robustAccess == false);   // Unimplemented
 
     initCaps(clientVersion);
+    mState.initialize(mCaps, clientVersion);
 
     mClientVersion = clientVersion;
 
@@ -66,16 +65,26 @@
     // In order that access to these initial textures not be lost, they are treated as texture
     // objects all of whose names are 0.
 
-    mTexture2DZero.set(new Texture2D(mRenderer->createTexture2D(), 0));
-    mTextureCubeMapZero.set(new TextureCubeMap(mRenderer->createTextureCube(), 0));
-    mTexture3DZero.set(new Texture3D(mRenderer->createTexture3D(), 0));
-    mTexture2DArrayZero.set(new Texture2DArray(mRenderer->createTexture2DArray(), 0));
+    mZeroTextures[GL_TEXTURE_2D].set(new Texture2D(mRenderer->createTexture(GL_TEXTURE_2D), 0));
+    bindTexture(GL_TEXTURE_2D, 0);
+
+    mZeroTextures[GL_TEXTURE_CUBE_MAP].set(new TextureCubeMap(mRenderer->createTexture(GL_TEXTURE_CUBE_MAP), 0));
+    bindTexture(GL_TEXTURE_CUBE_MAP, 0);
+
+    if (mClientVersion >= 3)
+    {
+        // TODO: These could also be enabled via extension
+        mZeroTextures[GL_TEXTURE_3D].set(new Texture3D(mRenderer->createTexture(GL_TEXTURE_3D), 0));
+        bindTexture(GL_TEXTURE_3D, 0);
+
+        mZeroTextures[GL_TEXTURE_2D_ARRAY].set(new Texture2DArray(mRenderer->createTexture(GL_TEXTURE_2D_ARRAY), 0));
+        bindTexture(GL_TEXTURE_2D_ARRAY, 0);
+    }
 
     bindVertexArray(0);
     bindArrayBuffer(0);
     bindElementArrayBuffer(0);
-    bindTextureCubeMap(0);
-    bindTexture2D(0);
+
     bindReadFramebuffer(0);
     bindDrawFramebuffer(0);
     bindRenderbuffer(0);
@@ -101,23 +110,15 @@
     // 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
-    mTransformFeedbackZero.set(new TransformFeedback(0));
+    mTransformFeedbackZero.set(new TransformFeedback(mRenderer->createTransformFeedback(), 0));
     bindTransformFeedback(0);
 
-    mInvalidEnum = false;
-    mInvalidValue = false;
-    mInvalidOperation = false;
-    mOutOfMemory = false;
-    mInvalidFramebufferOperation = false;
-
     mHasBeenCurrent = false;
     mContextLost = false;
     mResetStatus = GL_NO_ERROR;
     mResetStrategy = (notifyResets ? GL_LOSE_CONTEXT_ON_RESET_EXT : GL_NO_RESET_NOTIFICATION_EXT);
     mRobustAccess = robustAccess;
 
-    mNumCompressedTextureFormats = 0;
-
     mState.setContext(this);
 }
 
@@ -161,15 +162,17 @@
         deleteTransformFeedback(mTransformFeedbackMap.begin()->first);
     }
 
-    for (int type = 0; type < TEXTURE_TYPE_COUNT; type++)
+    for (TextureMap::iterator i = mIncompleteTextures.begin(); i != mIncompleteTextures.end(); i++)
     {
-        mIncompleteTextures[type].set(NULL);
+        i->second.set(NULL);
     }
+    mIncompleteTextures.clear();
 
-    mTexture2DZero.set(NULL);
-    mTextureCubeMapZero.set(NULL);
-    mTexture3DZero.set(NULL);
-    mTexture2DArrayZero.set(NULL);
+    for (TextureMap::iterator i = mZeroTextures.begin(); i != mZeroTextures.end(); i++)
+    {
+        i->second.set(NULL);
+    }
+    mZeroTextures.clear();
 
     mResourceManager->release();
 }
@@ -178,22 +181,6 @@
 {
     if (!mHasBeenCurrent)
     {
-        mSupportsVertexTexture = mRenderer->getVertexTextureSupport();
-
-        mNumCompressedTextureFormats = 0;
-        if (mExtensions.textureCompressionDXT1)
-        {
-            mNumCompressedTextureFormats += 2;
-        }
-        if (mExtensions.textureCompressionDXT3)
-        {
-            mNumCompressedTextureFormats += 1;
-        }
-        if (mExtensions.textureCompressionDXT5)
-        {
-            mNumCompressedTextureFormats += 1;
-        }
-
         initRendererString();
         initExtensionStrings();
 
@@ -286,7 +273,7 @@
 GLuint Context::createTransformFeedback()
 {
     GLuint handle = mTransformFeedbackAllocator.allocate();
-    TransformFeedback *transformFeedback = new TransformFeedback(handle);
+    TransformFeedback *transformFeedback = new TransformFeedback(mRenderer->createTransformFeedback(), handle);
     transformFeedback->addRef();
     mTransformFeedbackMap[handle] = transformFeedback;
     return handle;
@@ -527,32 +514,11 @@
     mState.getVertexArray()->setElementArrayBuffer(getBuffer(buffer));
 }
 
-void Context::bindTexture2D(GLuint texture)
+void Context::bindTexture(GLenum target, GLuint texture)
 {
-    mResourceManager->checkTextureAllocation(texture, TEXTURE_2D);
+    mResourceManager->checkTextureAllocation(texture, target);
 
-    mState.setSamplerTexture(TEXTURE_2D, getTexture(texture));
-}
-
-void Context::bindTextureCubeMap(GLuint texture)
-{
-    mResourceManager->checkTextureAllocation(texture, TEXTURE_CUBE);
-
-    mState.setSamplerTexture(TEXTURE_CUBE, getTexture(texture));
-}
-
-void Context::bindTexture3D(GLuint texture)
-{
-    mResourceManager->checkTextureAllocation(texture, TEXTURE_3D);
-
-    mState.setSamplerTexture(TEXTURE_3D, getTexture(texture));
-}
-
-void Context::bindTexture2DArray(GLuint texture)
-{
-    mResourceManager->checkTextureAllocation(texture, TEXTURE_2D_ARRAY);
-
-    mState.setSamplerTexture(TEXTURE_2D_ARRAY, getTexture(texture));
+    mState.setSamplerTexture(target, getTexture(texture));
 }
 
 void Context::bindReadFramebuffer(GLuint framebuffer)
@@ -595,7 +561,7 @@
 
 void Context::bindSampler(GLuint textureUnit, GLuint sampler)
 {
-    ASSERT(textureUnit < IMPLEMENTATION_MAX_COMBINED_TEXTURE_IMAGE_UNITS); // TODO: Update for backend-determined array size
+    ASSERT(textureUnit < mCaps.maxCombinedTextureImageUnits);
     mResourceManager->checkSamplerAllocation(sampler);
 
     mState.setSamplerBinding(textureUnit, getSampler(sampler));
@@ -677,7 +643,7 @@
 {
     Program *programObject = mResourceManager->getProgram(program);
 
-    bool linked = programObject->link();
+    bool linked = programObject->link(getCaps());
 
     // if the current program was relinked successfully we
     // need to install the new executables
@@ -687,11 +653,11 @@
     }
 }
 
-void Context::setProgramBinary(GLuint program, const void *binary, GLint length)
+void Context::setProgramBinary(GLuint program, GLenum binaryFormat, const void *binary, GLint length)
 {
     Program *programObject = mResourceManager->getProgram(program);
 
-    bool loaded = programObject->setProgramBinary(binary, length);
+    bool loaded = programObject->setProgramBinary(binaryFormat, binary, length);
 
     // if the current program was reloaded successfully we
     // need to install the new executables
@@ -707,26 +673,35 @@
     mState.setTransformFeedbackBinding(getTransformFeedback(transformFeedback));
 }
 
-void Context::beginQuery(GLenum target, GLuint query)
+Error Context::beginQuery(GLenum target, GLuint query)
 {
     Query *queryObject = getQuery(query, true, target);
     ASSERT(queryObject);
 
-    // set query as active for specified target
+    // begin query
+    Error error = queryObject->begin();
+    if (error.isError())
+    {
+        return error;
+    }
+
+    // set query as active for specified target only if begin succeeded
     mState.setActiveQuery(target, queryObject);
 
-    // begin query
-    queryObject->begin();
+    return Error(GL_NO_ERROR);
 }
 
-void Context::endQuery(GLenum target)
+Error Context::endQuery(GLenum target)
 {
     Query *queryObject = mState.getActiveQuery(target);
     ASSERT(queryObject);
 
-    queryObject->end();
+    gl::Error error = queryObject->end();
 
+    // Always unbind the query, even if there was an error. This may delete the query object.
     mState.setActiveQuery(target, NULL);
+
+    return error;
 }
 
 void Context::setFramebufferZero(Framebuffer *buffer)
@@ -815,7 +790,7 @@
     {
         if (!query->second && create)
         {
-            query->second = new Query(mRenderer, type, handle);
+            query->second = new Query(mRenderer->createQuery(type), handle);
             query->second->addRef();
         }
         return query->second;
@@ -841,36 +816,29 @@
 
 Texture2D *Context::getTexture2D() const
 {
-    return static_cast<Texture2D*>(getSamplerTexture(mState.getActiveSampler(), TEXTURE_2D));
+    return static_cast<Texture2D*>(getSamplerTexture(mState.getActiveSampler(), GL_TEXTURE_2D));
 }
 
 TextureCubeMap *Context::getTextureCubeMap() const
 {
-    return static_cast<TextureCubeMap*>(getSamplerTexture(mState.getActiveSampler(), TEXTURE_CUBE));
+    return static_cast<TextureCubeMap*>(getSamplerTexture(mState.getActiveSampler(), GL_TEXTURE_CUBE_MAP));
 }
 
 Texture3D *Context::getTexture3D() const
 {
-    return static_cast<Texture3D*>(getSamplerTexture(mState.getActiveSampler(), TEXTURE_3D));
+    return static_cast<Texture3D*>(getSamplerTexture(mState.getActiveSampler(), GL_TEXTURE_3D));
 }
 
 Texture2DArray *Context::getTexture2DArray() const
 {
-    return static_cast<Texture2DArray*>(getSamplerTexture(mState.getActiveSampler(), TEXTURE_2D_ARRAY));
+    return static_cast<Texture2DArray*>(getSamplerTexture(mState.getActiveSampler(), GL_TEXTURE_2D_ARRAY));
 }
 
-Texture *Context::getSamplerTexture(unsigned int sampler, TextureType type) const
+Texture *Context::getSamplerTexture(unsigned int sampler, GLenum type) const
 {
     if (mState.getSamplerTextureId(sampler, type) == 0)
     {
-        switch (type)
-        {
-          default: UNREACHABLE();
-          case TEXTURE_2D:       return mTexture2DZero.get();
-          case TEXTURE_CUBE:     return mTextureCubeMapZero.get();
-          case TEXTURE_3D:       return mTexture3DZero.get();
-          case TEXTURE_2D_ARRAY: return mTexture2DArrayZero.get();
-        }
+        return mZeroTextures.at(type).get();
     }
     else
     {
@@ -921,42 +889,38 @@
 
     switch (pname)
     {
-      case GL_MAX_VERTEX_ATTRIBS:                       *params = gl::MAX_VERTEX_ATTRIBS;                               break;
-      case GL_MAX_VERTEX_UNIFORM_VECTORS:               *params = mRenderer->getMaxVertexUniformVectors();              break;
-      case GL_MAX_VERTEX_UNIFORM_COMPONENTS:            *params = mRenderer->getMaxVertexUniformVectors() * 4;          break;
-      case GL_MAX_VARYING_VECTORS:                      *params = mRenderer->getMaxVaryingVectors();                    break;
-      case GL_MAX_VARYING_COMPONENTS:                   *params = mRenderer->getMaxVaryingVectors() * 4;                break;
-      case GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS:         *params = mRenderer->getMaxCombinedTextureImageUnits();         break;
-      case GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS:           *params = mRenderer->getMaxVertexTextureImageUnits();           break;
-      case GL_MAX_TEXTURE_IMAGE_UNITS:                  *params = gl::MAX_TEXTURE_IMAGE_UNITS;                          break;
-      case GL_MAX_FRAGMENT_UNIFORM_VECTORS:             *params = mRenderer->getMaxFragmentUniformVectors();            break;
-      case GL_MAX_FRAGMENT_UNIFORM_COMPONENTS:          *params = mRenderer->getMaxFragmentUniformVectors() * 4;        break;
+      case GL_MAX_VERTEX_ATTRIBS:                       *params = mCaps.maxVertexAttributes;                            break;
+      case GL_MAX_VERTEX_UNIFORM_VECTORS:               *params = mCaps.maxVertexUniformVectors;                        break;
+      case GL_MAX_VERTEX_UNIFORM_COMPONENTS:            *params = mCaps.maxVertexUniformComponents;                     break;
+      case GL_MAX_VARYING_VECTORS:                      *params = mCaps.maxVaryingVectors;                              break;
+      case GL_MAX_VARYING_COMPONENTS:                   *params = mCaps.maxVertexOutputComponents;                      break;
+      case GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS:         *params = mCaps.maxCombinedTextureImageUnits;                   break;
+      case GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS:           *params = mCaps.maxVertexTextureImageUnits;                     break;
+      case GL_MAX_TEXTURE_IMAGE_UNITS:                  *params = mCaps.maxTextureImageUnits;                           break;
+      case GL_MAX_FRAGMENT_UNIFORM_VECTORS:             *params = mCaps.maxFragmentUniformVectors;                      break;
+      case GL_MAX_FRAGMENT_UNIFORM_COMPONENTS:          *params = mCaps.maxFragmentInputComponents;                     break;
       case GL_MAX_RENDERBUFFER_SIZE:                    *params = mCaps.maxRenderbufferSize;                            break;
       case GL_MAX_COLOR_ATTACHMENTS_EXT:                *params = mCaps.maxColorAttachments;                            break;
       case GL_MAX_DRAW_BUFFERS_EXT:                     *params = mCaps.maxDrawBuffers;                                 break;
-      case GL_NUM_SHADER_BINARY_FORMATS:                *params = 0;                                                    break;
-      case GL_SHADER_BINARY_FORMATS:                    /* no shader binary formats are supported */                    break;
       //case GL_FRAMEBUFFER_BINDING:                    // now equivalent to GL_DRAW_FRAMEBUFFER_BINDING_ANGLE
       case GL_SUBPIXEL_BITS:                            *params = 4;                                                    break;
       case GL_MAX_TEXTURE_SIZE:                         *params = mCaps.max2DTextureSize;                               break;
       case GL_MAX_CUBE_MAP_TEXTURE_SIZE:                *params = mCaps.maxCubeMapTextureSize;                          break;
       case GL_MAX_3D_TEXTURE_SIZE:                      *params = mCaps.max3DTextureSize;                               break;
       case GL_MAX_ARRAY_TEXTURE_LAYERS:                 *params = mCaps.maxArrayTextureLayers;                          break;
-      case GL_UNIFORM_BUFFER_OFFSET_ALIGNMENT:          *params = getUniformBufferOffsetAlignment();                    break;
-      case GL_MAX_UNIFORM_BUFFER_BINDINGS:              *params = getMaximumCombinedUniformBufferBindings();            break;
-      case GL_MAX_VERTEX_UNIFORM_BLOCKS:                *params = mRenderer->getMaxVertexShaderUniformBuffers();        break;
-      case GL_MAX_FRAGMENT_UNIFORM_BLOCKS:              *params = mRenderer->getMaxFragmentShaderUniformBuffers();      break;
-      case GL_MAX_COMBINED_UNIFORM_BLOCKS:              *params = getMaximumCombinedUniformBufferBindings();            break;
+      case GL_UNIFORM_BUFFER_OFFSET_ALIGNMENT:          *params = mCaps.uniformBufferOffsetAlignment;                   break;
+      case GL_MAX_UNIFORM_BUFFER_BINDINGS:              *params = mCaps.maxUniformBufferBindings;                       break;
+      case GL_MAX_VERTEX_UNIFORM_BLOCKS:                *params = mCaps.maxVertexUniformBlocks;                         break;
+      case GL_MAX_FRAGMENT_UNIFORM_BLOCKS:              *params = mCaps.maxFragmentUniformBlocks;                       break;
+      case GL_MAX_COMBINED_UNIFORM_BLOCKS:              *params = mCaps.maxCombinedTextureImageUnits;                   break;
       case GL_MAJOR_VERSION:                            *params = mClientVersion;                                       break;
       case GL_MINOR_VERSION:                            *params = 0;                                                    break;
-      case GL_MAX_ELEMENTS_INDICES:                     *params = mRenderer->getMaxRecommendedElementsIndices();        break;
-      case GL_MAX_ELEMENTS_VERTICES:                    *params = mRenderer->getMaxRecommendedElementsVertices();       break;
-      case GL_MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS: *params = mRenderer->getMaxTransformFeedbackInterleavedComponents(); break;
-      case GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS:       *params = mRenderer->getMaxTransformFeedbackBuffers();               break;
-      case GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS:    *params = mRenderer->getMaxTransformFeedbackSeparateComponents();    break;
-      case GL_NUM_COMPRESSED_TEXTURE_FORMATS:
-        params[0] = mNumCompressedTextureFormats;
-        break;
+      case GL_MAX_ELEMENTS_INDICES:                     *params = mCaps.maxElementsIndices;                             break;
+      case GL_MAX_ELEMENTS_VERTICES:                    *params = mCaps.maxElementsVertices;                            break;
+      case GL_MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS: *params = mCaps.maxTransformFeedbackInterleavedComponents; break;
+      case GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS:       *params = mCaps.maxTransformFeedbackSeparateAttributes;    break;
+      case GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS:    *params = mCaps.maxTransformFeedbackSeparateComponents;    break;
+      case GL_NUM_COMPRESSED_TEXTURE_FORMATS:           *params = mCaps.compressedTextureFormats.size();                break;
       case GL_MAX_SAMPLES_ANGLE:                        *params = mExtensions.maxSamples;                               break;
       case GL_IMPLEMENTATION_COLOR_READ_TYPE:
       case GL_IMPLEMENTATION_COLOR_READ_FORMAT:
@@ -976,30 +940,22 @@
         }
         break;
       case GL_COMPRESSED_TEXTURE_FORMATS:
-        {
-            if (mExtensions.textureCompressionDXT1)
-            {
-                *params++ = GL_COMPRESSED_RGB_S3TC_DXT1_EXT;
-                *params++ = GL_COMPRESSED_RGBA_S3TC_DXT1_EXT;
-            }
-            if (mExtensions.textureCompressionDXT3)
-            {
-                *params++ = GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE;
-            }
-            if (mExtensions.textureCompressionDXT5)
-            {
-                *params++ = GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE;
-            }
-        }
+        std::copy(mCaps.compressedTextureFormats.begin(), mCaps.compressedTextureFormats.end(), params);
         break;
       case GL_RESET_NOTIFICATION_STRATEGY_EXT:
         *params = mResetStrategy;
         break;
-      case GL_NUM_PROGRAM_BINARY_FORMATS_OES:
-        *params = 1;
+      case GL_NUM_SHADER_BINARY_FORMATS:
+        *params = mCaps.shaderBinaryFormats.size();
         break;
-      case GL_PROGRAM_BINARY_FORMATS_OES:
-        *params = GL_PROGRAM_BINARY_ANGLE;
+      case GL_SHADER_BINARY_FORMATS:
+        std::copy(mCaps.shaderBinaryFormats.begin(), mCaps.shaderBinaryFormats.end(), params);
+        break;
+      case GL_NUM_PROGRAM_BINARY_FORMATS:
+        *params = mCaps.programBinaryFormats.size();
+        break;
+      case GL_PROGRAM_BINARY_FORMATS:
+        std::copy(mCaps.programBinaryFormats.begin(), mCaps.programBinaryFormats.end(), params);
         break;
       case GL_NUM_EXTENSIONS:
         *params = static_cast<GLint>(mExtensionStrings.size());
@@ -1020,25 +976,16 @@
         *params = mCaps.maxElementIndex;
         break;
       case GL_MAX_UNIFORM_BLOCK_SIZE:
-        *params = static_cast<GLint64>(mRenderer->getMaxUniformBufferSize());
+        *params = mCaps.maxUniformBlockSize;
         break;
       case GL_MAX_COMBINED_VERTEX_UNIFORM_COMPONENTS:
-        {
-            GLint64 uniformBufferComponents = static_cast<GLint64>(mRenderer->getMaxVertexShaderUniformBuffers()) * static_cast<GLint64>(mRenderer->getMaxUniformBufferSize() / 4);
-            GLint64 defaultBufferComponents = static_cast<GLint64>(mRenderer->getMaxVertexUniformVectors() * 4);
-            *params = uniformBufferComponents + defaultBufferComponents;
-        }
+        *params = mCaps.maxCombinedVertexUniformComponents;
         break;
       case GL_MAX_COMBINED_FRAGMENT_UNIFORM_COMPONENTS:
-        {
-            GLint64 uniformBufferComponents = static_cast<GLint64>(mRenderer->getMaxFragmentShaderUniformBuffers()) * static_cast<GLint64>(mRenderer->getMaxUniformBufferSize() / 4);
-            GLint64 defaultBufferComponents = static_cast<GLint64>(mRenderer->getMaxVertexUniformVectors() * 4);
-            *params = uniformBufferComponents + defaultBufferComponents;
-        }
+        *params = mCaps.maxCombinedFragmentUniformComponents;
         break;
       case GL_MAX_SERVER_WAIT_TIMEOUT:
-        // We do not wait for server fence objects internally, so report a max timeout of zero.
-        *params = 0;
+        *params = mCaps.maxServerWaitTimeout;
         break;
       default:
         UNREACHABLE();
@@ -1085,13 +1032,19 @@
       case GL_COMPRESSED_TEXTURE_FORMATS:
         {
             *type = GL_INT;
-            *numParams = mNumCompressedTextureFormats;
+            *numParams = mCaps.compressedTextureFormats.size();
+        }
+        return true;
+      case GL_PROGRAM_BINARY_FORMATS_OES:
+        {
+            *type = GL_INT;
+            *numParams = mCaps.programBinaryFormats.size();
         }
         return true;
       case GL_SHADER_BINARY_FORMATS:
         {
             *type = GL_INT;
-            *numParams = 0;
+            *numParams = mCaps.shaderBinaryFormats.size();
         }
         return true;
       case GL_MAX_VERTEX_ATTRIBS:
@@ -1160,7 +1113,6 @@
       case GL_TEXTURE_BINDING_CUBE_MAP:
       case GL_RESET_NOTIFICATION_STRATEGY_EXT:
       case GL_NUM_PROGRAM_BINARY_FORMATS_OES:
-      case GL_PROGRAM_BINARY_FORMATS_OES:
         {
             *type = GL_INT;
             *numParams = 1;
@@ -1358,7 +1310,7 @@
 
 // Applies the render target surface, depth stencil surface, viewport rectangle and
 // scissor rectangle to the renderer
-bool Context::applyRenderTarget(GLenum drawMode, bool ignoreViewport)
+void Context::applyRenderTarget(GLenum drawMode, bool ignoreViewport)
 {
     Framebuffer *framebufferObject = mState.getDrawFramebuffer();
     ASSERT(framebufferObject && framebufferObject->completeness() == GL_FRAMEBUFFER_COMPLETE);
@@ -1367,15 +1319,10 @@
 
     float nearZ, farZ;
     mState.getDepthRange(&nearZ, &farZ);
-    if (!mRenderer->setViewport(mState.getViewport(), nearZ, farZ, drawMode, mState.getRasterizerState().frontFace,
-                                ignoreViewport))
-    {
-        return false;
-    }
+    mRenderer->setViewport(mState.getViewport(), nearZ, farZ, drawMode, mState.getRasterizerState().frontFace,
+                           ignoreViewport);
 
     mRenderer->setScissorRectangle(mState.getScissor(), mState.isScissorTestEnabled());
-
-    return true;
 }
 
 // Applies the fixed-function state (culling, depth test, alpha blending, stenciling, etc) to the Direct3D 9 device
@@ -1433,7 +1380,7 @@
 {
     const VertexAttribute *vertexAttributes = mState.getVertexArray()->getVertexAttributes();
 
-    VertexFormat inputLayout[gl::MAX_VERTEX_ATTRIBS];
+    VertexFormat inputLayout[MAX_VERTEX_ATTRIBS];
     VertexFormat::GetInputLayout(inputLayout, programBinary, vertexAttributes, mState.getVertexAttribCurrentValues());
 
     const Framebuffer *fbo = mState.getDrawFramebuffer();
@@ -1443,65 +1390,56 @@
     programBinary->applyUniforms();
 }
 
-size_t Context::getCurrentTexturesAndSamplerStates(ProgramBinary *programBinary, SamplerType type, Texture **outTextures,
-                                                   TextureType *outTextureTypes, SamplerState *outSamplers)
+void Context::generateSwizzles(ProgramBinary *programBinary, SamplerType type)
 {
     size_t samplerRange = programBinary->getUsedSamplerRange(type);
+
     for (size_t i = 0; i < samplerRange; i++)
     {
-        outTextureTypes[i] = programBinary->getSamplerTextureType(type, i);
-        GLint textureUnit = programBinary->getSamplerMapping(type, i);   // OpenGL texture image unit index
+        GLenum textureType = programBinary->getSamplerTextureType(type, i);
+        GLint textureUnit = programBinary->getSamplerMapping(type, i, getCaps());
         if (textureUnit != -1)
         {
-            outTextures[i] = getSamplerTexture(textureUnit, outTextureTypes[i]);
-            outTextures[i]->getSamplerStateWithNativeOffset(&outSamplers[i]);
-            Sampler *samplerObject = mState.getSampler(textureUnit);
-            if (samplerObject)
+            Texture* texture = getSamplerTexture(textureUnit, textureType);
+            if (texture->getSamplerState().swizzleRequired())
             {
-                samplerObject->getState(&outSamplers[i]);
+                mRenderer->generateSwizzle(texture);
             }
         }
-        else
-        {
-            outTextures[i] = NULL;
-        }
     }
-
-    return samplerRange;
 }
 
-void Context::generateSwizzles(Texture *textures[], size_t count)
+void Context::generateSwizzles(ProgramBinary *programBinary)
 {
-    for (size_t i = 0; i < count; i++)
-    {
-        if (textures[i] && textures[i]->getSamplerState().swizzleRequired())
-        {
-            mRenderer->generateSwizzle(textures[i]);
-        }
-    }
+    generateSwizzles(programBinary, SAMPLER_VERTEX);
+    generateSwizzles(programBinary, SAMPLER_PIXEL);
 }
 
 // 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).
-void Context::applyTextures(SamplerType shaderType, Texture *textures[], TextureType *textureTypes, SamplerState *samplers,
-                            size_t textureCount, const FramebufferTextureSerialArray& framebufferSerials,
-                            size_t framebufferSerialCount)
+void Context::applyTextures(ProgramBinary *programBinary, SamplerType shaderType,
+                            const FramebufferTextureSerialArray &framebufferSerials, size_t framebufferSerialCount)
 {
-    // Range of Direct3D samplers of given sampler type
-    size_t samplerCount = (shaderType == SAMPLER_PIXEL) ? MAX_TEXTURE_IMAGE_UNITS
-                                                        : mRenderer->getMaxVertexTextureImageUnits();
-
-    for (size_t samplerIndex = 0; samplerIndex < textureCount; samplerIndex++)
+    size_t samplerRange = programBinary->getUsedSamplerRange(shaderType);
+    for (size_t samplerIndex = 0; samplerIndex < samplerRange; samplerIndex++)
     {
-        Texture *texture = textures[samplerIndex];
-        const SamplerState &sampler = samplers[samplerIndex];
-        TextureType textureType = textureTypes[samplerIndex];
-
-        if (texture)
+        GLenum textureType = programBinary->getSamplerTextureType(shaderType, samplerIndex);
+        GLint textureUnit = programBinary->getSamplerMapping(shaderType, samplerIndex, getCaps());
+        if (textureUnit != -1)
         {
+            SamplerState sampler;
+            Texture* texture = getSamplerTexture(textureUnit, textureType);
+            texture->getSamplerStateWithNativeOffset(&sampler);
+
+            Sampler *samplerObject = mState.getSampler(textureUnit);
+            if (samplerObject)
+            {
+                samplerObject->getState(&sampler);
+            }
+
             // TODO: std::binary_search may become unavailable using older versions of GCC
-            if (texture->isSamplerComplete(sampler) &&
+            if (texture->isSamplerComplete(sampler, mTextureCaps, mExtensions, mClientVersion) &&
                 !std::binary_search(framebufferSerials.begin(), framebufferSerials.begin() + framebufferSerialCount, texture->getTextureSerial()))
             {
                 mRenderer->setSamplerState(shaderType, samplerIndex, sampler);
@@ -1509,28 +1447,42 @@
             }
             else
             {
+                // Texture is not sampler complete or it is in use by the framebuffer.  Bind the incomplete texture.
                 Texture *incompleteTexture = getIncompleteTexture(textureType);
                 mRenderer->setTexture(shaderType, samplerIndex, incompleteTexture);
             }
         }
         else
         {
+            // No texture bound to this slot even though it is used by the shader, bind a NULL texture
             mRenderer->setTexture(shaderType, samplerIndex, NULL);
         }
     }
 
-    for (size_t samplerIndex = textureCount; samplerIndex < samplerCount; samplerIndex++)
+    // Set all the remaining textures to NULL
+    size_t samplerCount = (shaderType == SAMPLER_PIXEL) ? mCaps.maxTextureImageUnits
+                                                        : mCaps.maxVertexTextureImageUnits;
+    for (size_t samplerIndex = samplerRange; samplerIndex < samplerCount; samplerIndex++)
     {
         mRenderer->setTexture(shaderType, samplerIndex, NULL);
     }
 }
 
+void Context::applyTextures(ProgramBinary *programBinary)
+{
+    FramebufferTextureSerialArray framebufferSerials;
+    size_t framebufferSerialCount = getBoundFramebufferTextureSerials(&framebufferSerials);
+
+    applyTextures(programBinary, SAMPLER_VERTEX, framebufferSerials, framebufferSerialCount);
+    applyTextures(programBinary, SAMPLER_PIXEL, framebufferSerials, framebufferSerialCount);
+}
+
 bool Context::applyUniformBuffers()
 {
     Program *programObject = getProgram(mState.getCurrentProgramId());
     ProgramBinary *programBinary = programObject->getProgramBinary();
 
-    std::vector<gl::Buffer*> boundBuffers;
+    std::vector<Buffer*> boundBuffers;
 
     for (unsigned int uniformBlockIndex = 0; uniformBlockIndex < programBinary->getActiveUniformBlockCount(); uniformBlockIndex++)
     {
@@ -1549,7 +1501,7 @@
         }
     }
 
-    return programBinary->applyUniformBuffers(boundBuffers);
+    return programBinary->applyUniformBuffers(boundBuffers, getCaps());
 }
 
 bool Context::applyTransformFeedbackBuffers()
@@ -1585,28 +1537,25 @@
     }
 }
 
-void Context::clear(GLbitfield mask)
+Error Context::clear(GLbitfield mask)
 {
     if (mState.isRasterizerDiscardEnabled())
     {
-        return;
+        return Error(GL_NO_ERROR);
     }
 
     ClearParameters clearParams = mState.getClearParameters(mask);
 
-    if (!applyRenderTarget(GL_TRIANGLES, true))   // Clips the clear to the scissor rectangle but not the viewport
-    {
-        return;
-    }
+    applyRenderTarget(GL_TRIANGLES, true);   // Clips the clear to the scissor rectangle but not the viewport
 
-    mRenderer->clear(clearParams, mState.getDrawFramebuffer());
+    return mRenderer->clear(clearParams, mState.getDrawFramebuffer());
 }
 
-void Context::clearBufferfv(GLenum buffer, int drawbuffer, const float *values)
+Error Context::clearBufferfv(GLenum buffer, int drawbuffer, const float *values)
 {
     if (mState.isRasterizerDiscardEnabled())
     {
-        return;
+        return Error(GL_NO_ERROR);
     }
 
     // glClearBufferfv can be called to clear the color buffer or depth buffer
@@ -1628,19 +1577,16 @@
         clearParams.depthClearValue = values[0];
     }
 
-    if (!applyRenderTarget(GL_TRIANGLES, true))   // Clips the clear to the scissor rectangle but not the viewport
-    {
-        return;
-    }
+    applyRenderTarget(GL_TRIANGLES, true);   // Clips the clear to the scissor rectangle but not the viewport
 
-    mRenderer->clear(clearParams, mState.getDrawFramebuffer());
+    return mRenderer->clear(clearParams, mState.getDrawFramebuffer());
 }
 
-void Context::clearBufferuiv(GLenum buffer, int drawbuffer, const unsigned int *values)
+Error Context::clearBufferuiv(GLenum buffer, int drawbuffer, const unsigned int *values)
 {
     if (mState.isRasterizerDiscardEnabled())
     {
-        return;
+        return Error(GL_NO_ERROR);
     }
 
     // glClearBufferuv can only be called to clear a color buffer
@@ -1652,19 +1598,16 @@
     clearParams.colorUIClearValue = ColorUI(values[0], values[1], values[2], values[3]);
     clearParams.colorClearType = GL_UNSIGNED_INT;
 
-    if (!applyRenderTarget(GL_TRIANGLES, true))   // Clips the clear to the scissor rectangle but not the viewport
-    {
-        return;
-    }
+    applyRenderTarget(GL_TRIANGLES, true);   // Clips the clear to the scissor rectangle but not the viewport
 
-    mRenderer->clear(clearParams, mState.getDrawFramebuffer());
+    return mRenderer->clear(clearParams, mState.getDrawFramebuffer());
 }
 
-void Context::clearBufferiv(GLenum buffer, int drawbuffer, const int *values)
+Error Context::clearBufferiv(GLenum buffer, int drawbuffer, const int *values)
 {
     if (mState.isRasterizerDiscardEnabled())
     {
-        return;
+        return Error(GL_NO_ERROR);
     }
 
     // glClearBufferfv can be called to clear the color buffer or stencil buffer
@@ -1686,19 +1629,16 @@
         clearParams.stencilClearValue = values[1];
     }
 
-    if (!applyRenderTarget(GL_TRIANGLES, true))   // Clips the clear to the scissor rectangle but not the viewport
-    {
-        return;
-    }
+    applyRenderTarget(GL_TRIANGLES, true);   // Clips the clear to the scissor rectangle but not the viewport
 
-    mRenderer->clear(clearParams, mState.getDrawFramebuffer());
+    return mRenderer->clear(clearParams, mState.getDrawFramebuffer());
 }
 
-void Context::clearBufferfi(GLenum buffer, int drawbuffer, float depth, int stencil)
+Error Context::clearBufferfi(GLenum buffer, int drawbuffer, float depth, int stencil)
 {
     if (mState.isRasterizerDiscardEnabled())
     {
-        return;
+        return Error(GL_NO_ERROR);
     }
 
     // glClearBufferfi can only be called to clear a depth stencil buffer
@@ -1708,24 +1648,22 @@
     clearParams.clearStencil = true;
     clearParams.stencilClearValue = stencil;
 
-    if (!applyRenderTarget(GL_TRIANGLES, true))   // Clips the clear to the scissor rectangle but not the viewport
-    {
-        return;
-    }
+    applyRenderTarget(GL_TRIANGLES, true);   // Clips the clear to the scissor rectangle but not the viewport
 
-    mRenderer->clear(clearParams, mState.getDrawFramebuffer());
+    return mRenderer->clear(clearParams, mState.getDrawFramebuffer());
 }
 
-void Context::readPixels(GLint x, GLint y, GLsizei width, GLsizei height,
-                         GLenum format, GLenum type, GLsizei *bufSize, void* pixels)
+Error Context::readPixels(GLint x, GLint y, GLsizei width, GLsizei height,
+                          GLenum format, GLenum type, GLsizei *bufSize, void* pixels)
 {
-    gl::Framebuffer *framebuffer = mState.getReadFramebuffer();
+    Framebuffer *framebuffer = mState.getReadFramebuffer();
 
     GLenum sizedInternalFormat = GetSizedInternalFormat(format, type);
     const InternalFormat &sizedFormatInfo = GetInternalFormatInfo(sizedInternalFormat);
     GLuint outputPitch = sizedFormatInfo.computeRowPitch(type, width, mState.getPackAlignment());
 
-    mRenderer->readPixels(framebuffer, x, y, width, height, format, type, outputPitch, mState.getPackState(), pixels);
+    return mRenderer->readPixels(framebuffer, x, y, width, height, format, type, outputPitch, mState.getPackState(),
+                                 reinterpret_cast<uint8_t*>(pixels));
 }
 
 void Context::drawArrays(GLenum mode, GLint first, GLsizei count, GLsizei instances)
@@ -1735,46 +1673,27 @@
     ProgramBinary *programBinary = mState.getCurrentProgramBinary();
     programBinary->updateSamplerMapping();
 
-    Texture *vsTextures[IMPLEMENTATION_MAX_VERTEX_TEXTURE_IMAGE_UNITS];
-    TextureType vsTextureTypes[IMPLEMENTATION_MAX_VERTEX_TEXTURE_IMAGE_UNITS];
-    SamplerState vsSamplers[IMPLEMENTATION_MAX_VERTEX_TEXTURE_IMAGE_UNITS];
-    size_t vsTextureCount = getCurrentTexturesAndSamplerStates(programBinary, SAMPLER_VERTEX, vsTextures, vsTextureTypes, vsSamplers);
-
-    Texture *psTextures[MAX_TEXTURE_IMAGE_UNITS];
-    TextureType psTextureTypes[MAX_TEXTURE_IMAGE_UNITS];
-    SamplerState psSamplers[MAX_TEXTURE_IMAGE_UNITS];
-    size_t psTextureCount = getCurrentTexturesAndSamplerStates(programBinary, SAMPLER_PIXEL, psTextures, psTextureTypes, psSamplers);
-
-    generateSwizzles(vsTextures, vsTextureCount);
-    generateSwizzles(psTextures, psTextureCount);
+    generateSwizzles(programBinary);
 
     if (!mRenderer->applyPrimitiveType(mode, count))
     {
         return;
     }
 
-    if (!applyRenderTarget(mode, false))
-    {
-        return;
-    }
-
+    applyRenderTarget(mode, false);
     applyState(mode);
 
-    GLenum err = mRenderer->applyVertexBuffer(programBinary, mState.getVertexArray()->getVertexAttributes(), mState.getVertexAttribCurrentValues(), first, count, instances);
-    if (err != GL_NO_ERROR)
+    Error error = mRenderer->applyVertexBuffer(programBinary, mState.getVertexArray()->getVertexAttributes(), mState.getVertexAttribCurrentValues(), first, count, instances);
+    if (error.isError())
     {
-        return gl::error(err);
+        return gl::error(error.getCode());
     }
 
     bool transformFeedbackActive = applyTransformFeedbackBuffers();
 
     applyShaders(programBinary, transformFeedbackActive);
 
-    FramebufferTextureSerialArray frameBufferSerials;
-    size_t framebufferSerialCount = getBoundFramebufferTextureSerials(&frameBufferSerials);
-
-    applyTextures(SAMPLER_VERTEX, vsTextures, vsTextureTypes, vsSamplers, vsTextureCount, frameBufferSerials, framebufferSerialCount);
-    applyTextures(SAMPLER_PIXEL, psTextures, psTextureTypes, psSamplers, psTextureCount, frameBufferSerials, framebufferSerialCount);
+    applyTextures(programBinary);
 
     if (!applyUniformBuffers())
     {
@@ -1792,51 +1711,41 @@
     }
 }
 
-void Context::drawElements(GLenum mode, GLsizei count, GLenum type, const GLvoid *indices, GLsizei instances)
+void Context::drawElements(GLenum mode, GLsizei count, GLenum type,
+                           const GLvoid *indices, GLsizei instances,
+                           const rx::RangeUI &indexRange)
 {
     ASSERT(mState.getCurrentProgramId() != 0);
 
     ProgramBinary *programBinary = mState.getCurrentProgramBinary();
     programBinary->updateSamplerMapping();
 
-    Texture *vsTextures[IMPLEMENTATION_MAX_VERTEX_TEXTURE_IMAGE_UNITS];
-    TextureType vsTextureTypes[IMPLEMENTATION_MAX_VERTEX_TEXTURE_IMAGE_UNITS];
-    SamplerState vsSamplers[IMPLEMENTATION_MAX_VERTEX_TEXTURE_IMAGE_UNITS];
-    size_t vsTextureCount = getCurrentTexturesAndSamplerStates(programBinary, SAMPLER_VERTEX, vsTextures, vsTextureTypes, vsSamplers);
-
-    Texture *psTextures[MAX_TEXTURE_IMAGE_UNITS];
-    TextureType psTextureTypes[MAX_TEXTURE_IMAGE_UNITS];
-    SamplerState psSamplers[MAX_TEXTURE_IMAGE_UNITS];
-    size_t psTextureCount = getCurrentTexturesAndSamplerStates(programBinary, SAMPLER_PIXEL, psTextures, psTextureTypes, psSamplers);
-
-    generateSwizzles(vsTextures, vsTextureCount);
-    generateSwizzles(psTextures, psTextureCount);
+    generateSwizzles(programBinary);
 
     if (!mRenderer->applyPrimitiveType(mode, count))
     {
         return;
     }
 
-    if (!applyRenderTarget(mode, false))
-    {
-        return;
-    }
-
+    applyRenderTarget(mode, false);
     applyState(mode);
 
     VertexArray *vao = mState.getVertexArray();
     rx::TranslatedIndexData indexInfo;
-    GLenum err = mRenderer->applyIndexBuffer(indices, vao->getElementArrayBuffer(), count, mode, type, &indexInfo);
-    if (err != GL_NO_ERROR)
+    indexInfo.indexRange = indexRange;
+    Error error = mRenderer->applyIndexBuffer(indices, vao->getElementArrayBuffer(), count, mode, type, &indexInfo);
+    if (error.isError())
     {
-        return gl::error(err);
+        return gl::error(error.getCode());
     }
 
-    GLsizei vertexCount = indexInfo.maxIndex - indexInfo.minIndex + 1;
-    err = mRenderer->applyVertexBuffer(programBinary, vao->getVertexAttributes(), mState.getVertexAttribCurrentValues(), indexInfo.minIndex, vertexCount, instances);
-    if (err != GL_NO_ERROR)
+    GLsizei vertexCount = indexInfo.indexRange.length() + 1;
+    error = mRenderer->applyVertexBuffer(programBinary, vao->getVertexAttributes(),
+                                         mState.getVertexAttribCurrentValues(),
+                                         indexInfo.indexRange.start, vertexCount, instances);
+    if (error.isError())
     {
-        return gl::error(err);
+        return gl::error(error.getCode());
     }
 
     bool transformFeedbackActive = applyTransformFeedbackBuffers();
@@ -1846,11 +1755,7 @@
 
     applyShaders(programBinary, transformFeedbackActive);
 
-    FramebufferTextureSerialArray frameBufferSerials;
-    size_t framebufferSerialCount = getBoundFramebufferTextureSerials(&frameBufferSerials);
-
-    applyTextures(SAMPLER_VERTEX, vsTextures, vsTextureTypes, vsSamplers, vsTextureCount, frameBufferSerials, framebufferSerialCount);
-    applyTextures(SAMPLER_PIXEL, psTextures, psTextureTypes, psSamplers, psTextureCount, frameBufferSerials, framebufferSerialCount);
+    applyTextures(programBinary);
 
     if (!applyUniformBuffers())
     {
@@ -1869,71 +1774,28 @@
     mRenderer->sync(block);
 }
 
-void Context::recordInvalidEnum()
+void Context::recordError(const Error &error)
 {
-    mInvalidEnum = true;
-}
-
-void Context::recordInvalidValue()
-{
-    mInvalidValue = true;
-}
-
-void Context::recordInvalidOperation()
-{
-    mInvalidOperation = true;
-}
-
-void Context::recordOutOfMemory()
-{
-    mOutOfMemory = true;
-}
-
-void Context::recordInvalidFramebufferOperation()
-{
-    mInvalidFramebufferOperation = true;
+    if (error.isError())
+    {
+        mErrors.insert(error.getCode());
+    }
 }
 
 // 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 (mInvalidEnum)
+    if (mErrors.empty())
     {
-        mInvalidEnum = false;
-
-        return GL_INVALID_ENUM;
+        return GL_NO_ERROR;
     }
-
-    if (mInvalidValue)
+    else
     {
-        mInvalidValue = false;
-
-        return GL_INVALID_VALUE;
+        GLenum error = *mErrors.begin();
+        mErrors.erase(mErrors.begin());
+        return error;
     }
-
-    if (mInvalidOperation)
-    {
-        mInvalidOperation = false;
-
-        return GL_INVALID_OPERATION;
-    }
-
-    if (mOutOfMemory)
-    {
-        mOutOfMemory = false;
-
-        return GL_OUT_OF_MEMORY;
-    }
-
-    if (mInvalidFramebufferOperation)
-    {
-        mInvalidFramebufferOperation = false;
-
-        return GL_INVALID_FRAMEBUFFER_OPERATION;
-    }
-
-    return GL_NO_ERROR;
 }
 
 GLenum Context::getResetStatus()
@@ -1985,28 +1847,6 @@
     return mExtensions;
 }
 
-unsigned int Context::getMaximumCombinedTextureImageUnits() const
-{
-    return mRenderer->getMaxCombinedTextureImageUnits();
-}
-
-unsigned int Context::getMaximumCombinedUniformBufferBindings() const
-{
-    return mRenderer->getMaxVertexShaderUniformBuffers() +
-           mRenderer->getMaxFragmentShaderUniformBuffers();
-}
-
-unsigned int Context::getMaxTransformFeedbackBufferBindings() const
-{
-    return mRenderer->getMaxTransformFeedbackBuffers();
-}
-
-GLintptr Context::getUniformBufferOffsetAlignment() const
-{
-    // setting a large alignment forces uniform buffers to bind with zero offset
-    return static_cast<GLintptr>(std::numeric_limits<GLint>::max());
-}
-
 void Context::getCurrentReadFormatType(GLenum *internalFormat, GLenum *format, GLenum *type)
 {
     Framebuffer *framebuffer = mState.getReadFramebuffer();
@@ -2101,32 +1941,31 @@
     mState.detachSampler(sampler);
 }
 
-Texture *Context::getIncompleteTexture(TextureType type)
+Texture *Context::getIncompleteTexture(GLenum type)
 {
-    Texture *t = mIncompleteTextures[type].get();
-
-    if (t == NULL)
+    if (mIncompleteTextures.find(type) == mIncompleteTextures.end())
     {
         const GLubyte color[] = { 0, 0, 0, 255 };
         const PixelUnpackState incompleteUnpackState(1);
 
+        Texture* t = NULL;
         switch (type)
         {
           default:
             UNREACHABLE();
             // default falls through to TEXTURE_2D
 
-          case TEXTURE_2D:
+          case GL_TEXTURE_2D:
             {
-                Texture2D *incomplete2d = new Texture2D(mRenderer->createTexture2D(), Texture::INCOMPLETE_TEXTURE_ID);
+                Texture2D *incomplete2d = new Texture2D(mRenderer->createTexture(GL_TEXTURE_2D), Texture::INCOMPLETE_TEXTURE_ID);
                 incomplete2d->setImage(0, 1, 1, GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, incompleteUnpackState, color);
                 t = incomplete2d;
             }
             break;
 
-          case TEXTURE_CUBE:
+          case GL_TEXTURE_CUBE_MAP:
             {
-              TextureCubeMap *incompleteCube = new TextureCubeMap(mRenderer->createTextureCube(), Texture::INCOMPLETE_TEXTURE_ID);
+              TextureCubeMap *incompleteCube = new TextureCubeMap(mRenderer->createTexture(GL_TEXTURE_CUBE_MAP), Texture::INCOMPLETE_TEXTURE_ID);
 
               incompleteCube->setImagePosX(0, 1, 1, GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, incompleteUnpackState, color);
               incompleteCube->setImageNegX(0, 1, 1, GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, incompleteUnpackState, color);
@@ -2139,18 +1978,18 @@
             }
             break;
 
-          case TEXTURE_3D:
+          case GL_TEXTURE_3D:
             {
-                Texture3D *incomplete3d = new Texture3D(mRenderer->createTexture3D(), Texture::INCOMPLETE_TEXTURE_ID);
+                Texture3D *incomplete3d = new Texture3D(mRenderer->createTexture(GL_TEXTURE_3D), Texture::INCOMPLETE_TEXTURE_ID);
                 incomplete3d->setImage(0, 1, 1, 1, GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, incompleteUnpackState, color);
 
                 t = incomplete3d;
             }
             break;
 
-          case TEXTURE_2D_ARRAY:
+          case GL_TEXTURE_2D_ARRAY:
             {
-                Texture2DArray *incomplete2darray = new Texture2DArray(mRenderer->createTexture2DArray(), Texture::INCOMPLETE_TEXTURE_ID);
+                Texture2DArray *incomplete2darray = new Texture2DArray(mRenderer->createTexture(GL_TEXTURE_2D_ARRAY), Texture::INCOMPLETE_TEXTURE_ID);
                 incomplete2darray->setImage(0, 1, 1, 1, GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, incompleteUnpackState, color);
 
                 t = incomplete2darray;
@@ -2161,7 +2000,7 @@
         mIncompleteTextures[type].set(t);
     }
 
-    return t;
+    return mIncompleteTextures[type].get();
 }
 
 bool Context::skipDraw(GLenum drawMode)
@@ -2333,14 +2172,16 @@
         FramebufferAttachment *attachment = drawFramebuffer->getColorbuffer(i);
         if (attachment && attachment->isTexture())
         {
-            (*outSerialArray)[serialCount++] = attachment->getTextureSerial();
+            Texture *texture = attachment->getTexture();
+            (*outSerialArray)[serialCount++] = texture->getTextureSerial();
         }
     }
 
     FramebufferAttachment *depthStencilAttachment = drawFramebuffer->getDepthOrStencilbuffer();
     if (depthStencilAttachment && depthStencilAttachment->isTexture())
     {
-        (*outSerialArray)[serialCount++] = depthStencilAttachment->getTextureSerial();
+        Texture *depthStencilTexture = depthStencilAttachment->getTexture();
+        (*outSerialArray)[serialCount++] = depthStencilTexture->getTextureSerial();
     }
 
     std::sort(outSerialArray->begin(), outSerialArray->begin() + serialCount);
@@ -2370,87 +2211,19 @@
         blitDepth = true;
     }
 
-    gl::Rectangle srcRect(srcX0, srcY0, srcX1 - srcX0, srcY1 - srcY0);
-    gl::Rectangle dstRect(dstX0, dstY0, dstX1 - dstX0, dstY1 - dstY0);
+    Rectangle srcRect(srcX0, srcY0, srcX1 - srcX0, srcY1 - srcY0);
+    Rectangle dstRect(dstX0, dstY0, dstX1 - dstX0, dstY1 - dstY0);
     if (blitRenderTarget || blitDepth || blitStencil)
     {
-        const gl::Rectangle *scissor = mState.isScissorTestEnabled() ? &mState.getScissor() : NULL;
+        const Rectangle *scissor = mState.isScissorTestEnabled() ? &mState.getScissor() : NULL;
         mRenderer->blitRect(readFramebuffer, srcRect, drawFramebuffer, dstRect, scissor,
                             blitRenderTarget, blitDepth, blitStencil, filter);
     }
 }
 
-void Context::invalidateFrameBuffer(GLenum target, GLsizei numAttachments, const GLenum* attachments,
-                                    GLint x, GLint y, GLsizei width, GLsizei height)
+void Context::releaseShaderCompiler()
 {
-    Framebuffer *frameBuffer = NULL;
-    switch (target)
-    {
-      case GL_FRAMEBUFFER:
-      case GL_DRAW_FRAMEBUFFER:
-        frameBuffer = mState.getDrawFramebuffer();
-        break;
-      case GL_READ_FRAMEBUFFER:
-        frameBuffer = mState.getReadFramebuffer();
-        break;
-      default:
-        UNREACHABLE();
-    }
-
-    if (frameBuffer && frameBuffer->completeness() == GL_FRAMEBUFFER_COMPLETE)
-    {
-        for (int i = 0; i < numAttachments; ++i)
-        {
-            rx::RenderTarget *renderTarget = NULL;
-
-            if (attachments[i] >= GL_COLOR_ATTACHMENT0 && attachments[i] <= GL_COLOR_ATTACHMENT15)
-            {
-                gl::FramebufferAttachment *attachment = frameBuffer->getColorbuffer(attachments[i] - GL_COLOR_ATTACHMENT0);
-                if (attachment)
-                {
-                    renderTarget = attachment->getRenderTarget();
-                }
-            }
-            else if (attachments[i] == GL_COLOR)
-            {
-                 gl::FramebufferAttachment *attachment = frameBuffer->getColorbuffer(0);
-                 if (attachment)
-                 {
-                     renderTarget = attachment->getRenderTarget();
-                 }
-            }
-            else
-            {
-                gl::FramebufferAttachment *attachment = NULL;
-                switch (attachments[i])
-                {
-                  case GL_DEPTH_ATTACHMENT:
-                  case GL_DEPTH:
-                    attachment = frameBuffer->getDepthbuffer();
-                    break;
-                  case GL_STENCIL_ATTACHMENT:
-                  case GL_STENCIL:
-                    attachment = frameBuffer->getStencilbuffer();
-                    break;
-                  case GL_DEPTH_STENCIL_ATTACHMENT:
-                    attachment = frameBuffer->getDepthOrStencilbuffer();
-                    break;
-                  default:
-                    UNREACHABLE();
-                }
-
-                if (attachment)
-                {
-                    renderTarget = attachment->getDepthStencil();
-                }
-            }
-
-            if (renderTarget)
-            {
-                renderTarget->invalidate(x, y, width, height);
-            }
-        }
-    }
+    mRenderer->releaseShaderCompiler();
 }
 
 void Context::initCaps(GLuint clientVersion)
@@ -2471,7 +2244,16 @@
         //mExtensions.sRGB = false;
     }
 
+    // Apply implementation limits
+    mCaps.maxVertexAttributes = std::min<GLuint>(mCaps.maxVertexAttributes, MAX_VERTEX_ATTRIBS);
+    mCaps.maxVertexUniformBlocks = std::min<GLuint>(mCaps.maxVertexUniformBlocks, IMPLEMENTATION_MAX_VERTEX_SHADER_UNIFORM_BUFFERS);
+    mCaps.maxVertexOutputComponents = std::min<GLuint>(mCaps.maxVertexOutputComponents, IMPLEMENTATION_MAX_VARYING_VECTORS * 4);
+
+    mCaps.maxFragmentInputComponents = std::min<GLuint>(mCaps.maxFragmentInputComponents, IMPLEMENTATION_MAX_VARYING_VECTORS * 4);
+
     GLuint maxSamples = 0;
+    mCaps.compressedTextureFormats.clear();
+
     const TextureCapsMap &rendererFormats = mRenderer->getRendererTextureCaps();
     for (TextureCapsMap::const_iterator i = rendererFormats.begin(); i != rendererFormats.end(); i++)
     {
@@ -2492,6 +2274,11 @@
             }
             maxSamples = std::max(maxSamples, formatCaps.getMaxSamples());
 
+            if (formatInfo.compressed)
+            {
+                mCaps.compressedTextureFormats.push_back(format);
+            }
+
             mTextureCaps.insert(format, formatCaps);
         }
     }
diff --git a/src/libGLESv2/Context.h b/src/libGLESv2/Context.h
index eb2e287..bf886a8 100644
--- a/src/libGLESv2/Context.h
+++ b/src/libGLESv2/Context.h
@@ -10,8 +10,17 @@
 #ifndef LIBGLESV2_CONTEXT_H_
 #define LIBGLESV2_CONTEXT_H_
 
+#include "common/angleutils.h"
+#include "common/RefCountObject.h"
+#include "libGLESv2/Caps.h"
+#include "libGLESv2/Error.h"
+#include "libGLESv2/HandleAllocator.h"
+#include "libGLESv2/angletypes.h"
+#include "libGLESv2/Constants.h"
+#include "libGLESv2/VertexAttribute.h"
+#include "libGLESv2/State.h"
+
 #include "angle_gl.h"
-#include <EGL/egl.h>
 
 #include <string>
 #include <set>
@@ -19,15 +28,6 @@
 #include <unordered_map>
 #include <array>
 
-#include "common/angleutils.h"
-#include "common/RefCountObject.h"
-#include "libGLESv2/Caps.h"
-#include "libGLESv2/HandleAllocator.h"
-#include "libGLESv2/angletypes.h"
-#include "libGLESv2/Constants.h"
-#include "libGLESv2/VertexAttribute.h"
-#include "libGLESv2/State.h"
-
 namespace rx
 {
 class Renderer;
@@ -115,10 +115,7 @@
 
     void bindArrayBuffer(GLuint buffer);
     void bindElementArrayBuffer(GLuint buffer);
-    void bindTexture2D(GLuint texture);
-    void bindTextureCubeMap(GLuint texture);
-    void bindTexture3D(GLuint texture);
-    void bindTexture2DArray(GLuint texture);
+    void bindTexture(GLenum target, GLuint texture);
     void bindReadFramebuffer(GLuint framebuffer);
     void bindDrawFramebuffer(GLuint framebuffer);
     void bindRenderbuffer(GLuint renderbuffer);
@@ -134,11 +131,11 @@
     void bindPixelUnpackBuffer(GLuint buffer);
     void useProgram(GLuint program);
     void linkProgram(GLuint program);
-    void setProgramBinary(GLuint program, const void *binary, GLint length);
+    void setProgramBinary(GLuint program, GLenum binaryFormat, const void *binary, GLint length);
     void bindTransformFeedback(GLuint transformFeedback);
 
-    void beginQuery(GLenum target, GLuint query);
-    void endQuery(GLenum target);
+    Error beginQuery(GLenum target, GLuint query);
+    Error endQuery(GLenum target);
 
     void setFramebufferZero(Framebuffer *framebuffer);
 
@@ -170,7 +167,7 @@
     Texture3D *getTexture3D() const;
     Texture2DArray *getTexture2DArray() const;
 
-    Texture *getSamplerTexture(unsigned int sampler, TextureType type) const;
+    Texture *getSamplerTexture(unsigned int sampler, GLenum type) const;
 
     bool isSampler(GLuint samplerName) const;
 
@@ -185,22 +182,20 @@
     bool getQueryParameterInfo(GLenum pname, GLenum *type, unsigned int *numParams);
     bool getIndexedQueryParameterInfo(GLenum target, GLenum *type, unsigned int *numParams);
 
-    void clear(GLbitfield mask);
-    void clearBufferfv(GLenum buffer, int drawbuffer, const float *values);
-    void clearBufferuiv(GLenum buffer, int drawbuffer, const unsigned int *values);
-    void clearBufferiv(GLenum buffer, int drawbuffer, const int *values);
-    void clearBufferfi(GLenum buffer, int drawbuffer, float depth, int stencil);
+    Error clear(GLbitfield mask);
+    Error clearBufferfv(GLenum buffer, int drawbuffer, const float *values);
+    Error clearBufferuiv(GLenum buffer, int drawbuffer, const unsigned int *values);
+    Error clearBufferiv(GLenum buffer, int drawbuffer, const int *values);
+    Error clearBufferfi(GLenum buffer, int drawbuffer, float depth, int stencil);
 
-    void readPixels(GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, GLsizei *bufSize, void* pixels);
+    Error readPixels(GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, GLsizei *bufSize, void* pixels);
     void drawArrays(GLenum mode, GLint first, GLsizei count, GLsizei instances);
-    void drawElements(GLenum mode, GLsizei count, GLenum type, const GLvoid *indices, GLsizei instances);
+    void drawElements(GLenum mode, GLsizei count, GLenum type,
+                      const GLvoid *indices, GLsizei instances,
+                      const rx::RangeUI &indexRange);
     void sync(bool block);   // flush/finish
 
-    void recordInvalidEnum();
-    void recordInvalidValue();
-    void recordInvalidOperation();
-    void recordOutOfMemory();
-    void recordInvalidFramebufferOperation();
+    void recordError(const Error &error);
 
     GLenum getError();
     GLenum getResetStatus();
@@ -212,10 +207,6 @@
     const TextureCapsMap &getTextureCaps() const;
     const Extensions &getExtensions() const;
 
-    unsigned int getMaximumCombinedTextureImageUnits() const;
-    unsigned int getMaximumCombinedUniformBufferBindings() const;
-    unsigned int getMaxTransformFeedbackBufferBindings() const;
-    GLintptr getUniformBufferOffsetAlignment() const;
     const std::string &getRendererString() const;
 
     const std::string &getExtensionString() const;
@@ -227,26 +218,25 @@
     void blitFramebuffer(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1,
                          GLbitfield mask, GLenum filter);
 
-    void invalidateFrameBuffer(GLenum target, GLsizei numAttachments, const GLenum* attachments,
-                               GLint x, GLint y, GLsizei width, GLsizei height);
-
     rx::Renderer *getRenderer() { return mRenderer; }
 
     State &getState() { return mState; }
     const State &getState() const { return mState; }
 
+    void releaseShaderCompiler();
+
   private:
     DISALLOW_COPY_AND_ASSIGN(Context);
 
     // TODO: std::array may become unavailable using older versions of GCC
     typedef std::array<unsigned int, IMPLEMENTATION_MAX_FRAMEBUFFER_ATTACHMENTS> FramebufferTextureSerialArray;
 
-    bool applyRenderTarget(GLenum drawMode, bool ignoreViewport);
+    void applyRenderTarget(GLenum drawMode, bool ignoreViewport);
     void applyState(GLenum drawMode);
     void applyShaders(ProgramBinary *programBinary, bool transformFeedbackActive);
-    void applyTextures(SamplerType shaderType, Texture *textures[], TextureType *textureTypes, SamplerState *samplers,
-                       size_t textureCount, const FramebufferTextureSerialArray& framebufferSerials,
+    void applyTextures(ProgramBinary *programBinary, SamplerType shaderType, const FramebufferTextureSerialArray &framebufferSerials,
                        size_t framebufferSerialCount);
+    void applyTextures(ProgramBinary *programBinary);
     bool applyUniformBuffers();
     bool applyTransformFeedbackBuffers();
     void markTransformFeedbackUsage();
@@ -259,10 +249,10 @@
     void detachTransformFeedback(GLuint transformFeedback);
     void detachSampler(GLuint sampler);
 
-    void generateSwizzles(Texture *textures[], size_t count);
-    size_t getCurrentTexturesAndSamplerStates(ProgramBinary *programBinary, SamplerType type, Texture **outTextures,
-                                              TextureType *outTextureTypes, SamplerState *outSamplers);
-    Texture *getIncompleteTexture(TextureType type);
+    void generateSwizzles(ProgramBinary *programBinary, SamplerType type);
+    void generateSwizzles(ProgramBinary *programBinary);
+
+    Texture *getIncompleteTexture(GLenum type);
 
     bool skipDraw(GLenum drawMode);
 
@@ -283,10 +273,9 @@
 
     int mClientVersion;
 
-    BindingPointer<Texture2D> mTexture2DZero;
-    BindingPointer<TextureCubeMap> mTextureCubeMapZero;
-    BindingPointer<Texture3D> mTexture3DZero;
-    BindingPointer<Texture2DArray> mTexture2DArrayZero;
+    typedef std::map< GLenum, BindingPointer<Texture> > TextureMap;
+    TextureMap mZeroTextures;
+    TextureMap mIncompleteTextures;
 
     typedef std::unordered_map<GLuint, Framebuffer*> FramebufferMap;
     FramebufferMap mFramebufferMap;
@@ -313,14 +302,9 @@
     std::string mExtensionString;
     std::vector<std::string> mExtensionStrings;
 
-    BindingPointer<Texture> mIncompleteTextures[TEXTURE_TYPE_COUNT];
-
     // Recorded errors
-    bool mInvalidEnum;
-    bool mInvalidValue;
-    bool mInvalidOperation;
-    bool mOutOfMemory;
-    bool mInvalidFramebufferOperation;
+    typedef std::set<GLenum> ErrorSet;
+    ErrorSet mErrors;
 
     // Current/lost context flags
     bool mHasBeenCurrent;
@@ -329,9 +313,6 @@
     GLenum mResetStrategy;
     bool mRobustAccess;
 
-    bool mSupportsVertexTexture;
-    int mNumCompressedTextureFormats;
-
     ResourceManager *mResourceManager;
 };
 }
diff --git a/src/libGLESv2/DynamicHLSL.h b/src/libGLESv2/DynamicHLSL.h
deleted file mode 100644
index 68abd6e..0000000
--- a/src/libGLESv2/DynamicHLSL.h
+++ /dev/null
@@ -1,96 +0,0 @@
-//
-// Copyright (c) 2014 The ANGLE Project Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-//
-// DynamicHLSL.h: Interface for link and run-time HLSL generation
-//
-
-#ifndef LIBGLESV2_DYNAMIC_HLSL_H_
-#define LIBGLESV2_DYNAMIC_HLSL_H_
-
-#include "common/angleutils.h"
-#include "libGLESv2/constants.h"
-
-namespace rx
-{
-class Renderer;
-}
-
-namespace sh
-{
-struct Attribute;
-struct ShaderVariable;
-}
-
-namespace gl
-{
-
-class InfoLog;
-class FragmentShader;
-class VertexShader;
-struct VariableLocation;
-struct LinkedVarying;
-struct VertexAttribute;
-struct VertexFormat;
-struct PackedVarying;
-
-typedef const PackedVarying *VaryingPacking[IMPLEMENTATION_MAX_VARYING_VECTORS][4];
-
-struct PixelShaderOuputVariable
-{
-    GLenum type;
-    std::string name;
-    std::string source;
-    size_t outputIndex;
-};
-
-class DynamicHLSL
-{
-  public:
-    explicit DynamicHLSL(rx::Renderer *const renderer);
-
-    int packVaryings(InfoLog &infoLog, VaryingPacking packing, FragmentShader *fragmentShader,
-                     VertexShader *vertexShader, const std::vector<std::string>& transformFeedbackVaryings);
-    std::string generateVertexShaderForInputLayout(const std::string &sourceShader, const VertexFormat inputLayout[],
-                                                   const sh::Attribute shaderAttributes[]) const;
-    std::string generatePixelShaderForOutputSignature(const std::string &sourceShader, const std::vector<PixelShaderOuputVariable> &outputVariables,
-                                                      bool usesFragDepth, const std::vector<GLenum> &outputLayout) const;
-    bool generateShaderLinkHLSL(InfoLog &infoLog, int registers, const VaryingPacking packing,
-                                std::string& pixelHLSL, std::string& vertexHLSL,
-                                FragmentShader *fragmentShader, VertexShader *vertexShader,
-                                const std::vector<std::string>& transformFeedbackVaryings,
-                                std::vector<LinkedVarying> *linkedVaryings,
-                                std::map<int, VariableLocation> *programOutputVars,
-                                std::vector<PixelShaderOuputVariable> *outPixelShaderKey,
-                                bool *outUsesFragDepth) const;
-
-    std::string generateGeometryShaderHLSL(int registers, FragmentShader *fragmentShader, VertexShader *vertexShader) const;
-    void getInputLayoutSignature(const VertexFormat inputLayout[], GLenum signature[]) const;
-
-  private:
-    DISALLOW_COPY_AND_ASSIGN(DynamicHLSL);
-
-    rx::Renderer *const mRenderer;
-
-    struct SemanticInfo;
-
-    std::string getVaryingSemantic(bool pointSize) const;
-    SemanticInfo getSemanticInfo(int startRegisters, bool fragCoord, bool pointCoord, bool pointSize,
-                                        bool pixelShader) const;
-    std::string generateVaryingLinkHLSL(const SemanticInfo &info, const std::string &varyingHLSL) const;
-    std::string generateVaryingHLSL(VertexShader *shader) const;
-    void storeUserLinkedVaryings(const VertexShader *vertexShader, std::vector<LinkedVarying> *linkedVaryings) const;
-    void storeBuiltinLinkedVaryings(const SemanticInfo &info, std::vector<LinkedVarying> *linkedVaryings) const;
-    void defineOutputVariables(FragmentShader *fragmentShader, std::map<int, VariableLocation> *programOutputVars) const;
-    std::string generatePointSpriteHLSL(int registers, FragmentShader *fragmentShader, VertexShader *vertexShader) const;
-
-    // Prepend an underscore
-    static std::string decorateVariable(const std::string &name);
-
-    std::string generateAttributeConversionHLSL(const VertexFormat &vertexFormat, const sh::ShaderVariable &shaderAttrib) const;
-};
-
-}
-
-#endif // LIBGLESV2_DYNAMIC_HLSL_H_
diff --git a/src/libGLESv2/Error.cpp b/src/libGLESv2/Error.cpp
new file mode 100644
index 0000000..cc7d17e
--- /dev/null
+++ b/src/libGLESv2/Error.cpp
@@ -0,0 +1,48 @@
+//
+// 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.
+//
+
+// Error.cpp: Implements the gl::Error class which encapsulates an OpenGL error
+// and optional error message.
+
+#include "libGLESv2/Error.h"
+
+#include "common/angleutils.h"
+
+#include <cstdarg>
+
+namespace gl
+{
+
+Error::Error(GLenum errorCode)
+    : mCode(errorCode),
+      mMessage()
+{
+}
+
+Error::Error(GLenum errorCode, const char *msg, ...)
+    : mCode(errorCode),
+      mMessage()
+{
+    va_list vararg;
+    va_start(vararg, msg);
+    mMessage = FormatString(msg, vararg);
+    va_end(vararg);
+}
+
+Error::Error(const Error &other)
+    : mCode(other.mCode),
+      mMessage(other.mMessage)
+{
+}
+
+Error &Error::operator=(const Error &other)
+{
+    mCode = other.mCode;
+    mMessage = other.mMessage;
+    return *this;
+}
+
+}
diff --git a/src/libGLESv2/Error.h b/src/libGLESv2/Error.h
new file mode 100644
index 0000000..b70b5a5
--- /dev/null
+++ b/src/libGLESv2/Error.h
@@ -0,0 +1,39 @@
+//
+// 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.
+
+// Error.h: Defines the gl::Error class which encapsulates an OpenGL error
+// and optional error message.
+
+#ifndef LIBGLESV2_ERROR_H_
+#define LIBGLESV2_ERROR_H_
+
+#include "angle_gl.h"
+
+#include <string>
+
+namespace gl
+{
+
+class Error
+{
+  public:
+    explicit Error(GLenum errorCode);
+    Error(GLenum errorCode, const char *msg, ...);
+    Error(const Error &other);
+    Error &operator=(const Error &other);
+
+    GLenum getCode() const { return mCode; }
+    bool isError() const { return (mCode != GL_NO_ERROR); }
+
+    const std::string &getMessage() const { return mMessage; }
+
+  private:
+    GLenum mCode;
+    std::string mMessage;
+};
+
+}
+
+#endif // LIBGLESV2_ERROR_H_
diff --git a/src/libGLESv2/Fence.cpp b/src/libGLESv2/Fence.cpp
index 31d149d..ee9a07a 100644
--- a/src/libGLESv2/Fence.cpp
+++ b/src/libGLESv2/Fence.cpp
@@ -1,4 +1,3 @@
-#include "precompiled.h"
 //
 // 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
@@ -23,6 +22,8 @@
 #include "libGLESv2/renderer/Renderer.h"
 #include "libGLESv2/main.h"
 
+#include "angle_gl.h"
+
 namespace gl
 {
 
diff --git a/src/libGLESv2/Float16ToFloat32.cpp b/src/libGLESv2/Float16ToFloat32.cpp
index b90d2f6..5bf7b3f 100644
--- a/src/libGLESv2/Float16ToFloat32.cpp
+++ b/src/libGLESv2/Float16ToFloat32.cpp
@@ -1,4 +1,3 @@
-#include "precompiled.h"
 //
 // Copyright (c) 2012 The ANGLE Project Authors. All rights reserved.
 // Use of this source code is governed by a BSD-style license that can be
diff --git a/src/libGLESv2/Framebuffer.cpp b/src/libGLESv2/Framebuffer.cpp
index 30b042e..5b21433 100644
--- a/src/libGLESv2/Framebuffer.cpp
+++ b/src/libGLESv2/Framebuffer.cpp
@@ -1,4 +1,3 @@
-#include "precompiled.h"
 //
 // 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
@@ -9,15 +8,60 @@
 // objects and related functionality. [OpenGL ES 2.0.24] section 4.4 page 105.
 
 #include "libGLESv2/Framebuffer.h"
-
 #include "libGLESv2/main.h"
-#include "common/utilities.h"
 #include "libGLESv2/formatutils.h"
 #include "libGLESv2/Texture.h"
 #include "libGLESv2/Context.h"
-#include "libGLESv2/renderer/Renderer.h"
 #include "libGLESv2/Renderbuffer.h"
 #include "libGLESv2/FramebufferAttachment.h"
+#include "libGLESv2/renderer/Renderer.h"
+#include "libGLESv2/renderer/RenderTarget.h"
+#include "libGLESv2/renderer/d3d/TextureD3D.h"
+
+#include "common/utilities.h"
+
+namespace rx
+{
+RenderTarget *GetAttachmentRenderTarget(gl::FramebufferAttachment *attachment)
+{
+    if (attachment->isTexture())
+    {
+        gl::Texture *texture = attachment->getTexture();
+        ASSERT(texture);
+        TextureD3D *textureD3D = TextureD3D::makeTextureD3D(texture->getImplementation());
+        const gl::ImageIndex *index = attachment->getTextureImageIndex();
+        ASSERT(index);
+        return textureD3D->getRenderTarget(*index);
+    }
+
+    gl::Renderbuffer *renderbuffer = attachment->getRenderbuffer();
+    ASSERT(renderbuffer);
+
+    // TODO: cast to RenderbufferD3D
+    return renderbuffer->getStorage()->getRenderTarget();
+}
+
+// Note: RenderTarget serials should ideally be in the RenderTargets themselves.
+unsigned int GetAttachmentSerial(gl::FramebufferAttachment *attachment)
+{
+    if (attachment->isTexture())
+    {
+        gl::Texture *texture = attachment->getTexture();
+        ASSERT(texture);
+        TextureD3D *textureD3D = TextureD3D::makeTextureD3D(texture->getImplementation());
+        const gl::ImageIndex *index = attachment->getTextureImageIndex();
+        ASSERT(index);
+        return textureD3D->getRenderTargetSerial(*index);
+    }
+
+    gl::Renderbuffer *renderbuffer = attachment->getRenderbuffer();
+    ASSERT(renderbuffer);
+
+    // TODO: cast to RenderbufferD3D
+    return renderbuffer->getStorage()->getSerial();
+}
+
+}
 
 namespace gl
 {
@@ -47,7 +91,7 @@
     SafeDelete(mStencilbuffer);
 }
 
-FramebufferAttachment *Framebuffer::createAttachment(GLenum type, GLuint handle, GLint level, GLint layer) const
+FramebufferAttachment *Framebuffer::createAttachment(GLenum binding, GLenum type, GLuint handle, GLint level, GLint layer) const
 {
     if (handle == 0)
     {
@@ -62,15 +106,14 @@
         return NULL;
 
       case GL_RENDERBUFFER:
-        return new RenderbufferAttachment(context->getRenderbuffer(handle));
+        return new RenderbufferAttachment(binding, context->getRenderbuffer(handle));
 
       case GL_TEXTURE_2D:
         {
             Texture *texture = context->getTexture(handle);
             if (texture && texture->getTarget() == GL_TEXTURE_2D)
             {
-                Texture2D *tex2D = static_cast<Texture2D*>(texture);
-                return new Texture2DAttachment(tex2D, level);
+                return new TextureAttachment(binding, texture, ImageIndex::Make2D(level));
             }
             else
             {
@@ -88,8 +131,7 @@
             Texture *texture = context->getTexture(handle);
             if (texture && texture->getTarget() == GL_TEXTURE_CUBE_MAP)
             {
-                TextureCubeMap *texCube = static_cast<TextureCubeMap*>(texture);
-                return new TextureCubeMapAttachment(texCube, type, level);
+                return new TextureAttachment(binding, texture, ImageIndex::MakeCube(type, level));
             }
             else
             {
@@ -102,8 +144,7 @@
             Texture *texture = context->getTexture(handle);
             if (texture && texture->getTarget() == GL_TEXTURE_3D)
             {
-                Texture3D *tex3D = static_cast<Texture3D*>(texture);
-                return new Texture3DAttachment(tex3D, level, layer);
+                return new TextureAttachment(binding, texture, ImageIndex::Make3D(level, layer));
             }
             else
             {
@@ -116,8 +157,7 @@
             Texture *texture = context->getTexture(handle);
             if (texture && texture->getTarget() == GL_TEXTURE_2D_ARRAY)
             {
-                Texture2DArray *tex2DArray = static_cast<Texture2DArray*>(texture);
-                return new Texture2DArrayAttachment(tex2DArray, level, layer);
+                return new TextureAttachment(binding, texture, ImageIndex::Make2DArray(level, layer));
             }
             else
             {
@@ -135,24 +175,25 @@
 {
     ASSERT(colorAttachment < IMPLEMENTATION_MAX_DRAW_BUFFERS);
     SafeDelete(mColorbuffers[colorAttachment]);
-    mColorbuffers[colorAttachment] = createAttachment(type, colorbuffer, level, layer);
+    GLenum binding = colorAttachment + GL_COLOR_ATTACHMENT0;
+    mColorbuffers[colorAttachment] = createAttachment(binding, type, colorbuffer, level, layer);
 }
 
 void Framebuffer::setDepthbuffer(GLenum type, GLuint depthbuffer, GLint level, GLint layer)
 {
     SafeDelete(mDepthbuffer);
-    mDepthbuffer = createAttachment(type, depthbuffer, level, layer);
+    mDepthbuffer = createAttachment(GL_DEPTH_ATTACHMENT, type, depthbuffer, level, layer);
 }
 
 void Framebuffer::setStencilbuffer(GLenum type, GLuint stencilbuffer, GLint level, GLint layer)
 {
     SafeDelete(mStencilbuffer);
-    mStencilbuffer = createAttachment(type, stencilbuffer, level, layer);
+    mStencilbuffer = createAttachment(GL_STENCIL_ATTACHMENT, type, stencilbuffer, level, layer);
 }
 
 void Framebuffer::setDepthStencilBuffer(GLenum type, GLuint depthStencilBuffer, GLint level, GLint layer)
 {
-    FramebufferAttachment *attachment = createAttachment(type, depthStencilBuffer, level, layer);
+    FramebufferAttachment *attachment = createAttachment(GL_DEPTH_STENCIL_ATTACHMENT, type, depthStencilBuffer, level, layer);
 
     SafeDelete(mDepthbuffer);
     SafeDelete(mStencilbuffer);
@@ -164,7 +205,7 @@
 
         // Make a new attachment object to ensure we do not double-delete
         // See angle issue 686
-        mStencilbuffer = createAttachment(type, depthStencilBuffer, level, layer);
+        mStencilbuffer = createAttachment(GL_DEPTH_STENCIL_ATTACHMENT, type, depthStencilBuffer, level, layer);
     }
 }
 
@@ -561,18 +602,47 @@
     return GL_FRAMEBUFFER_COMPLETE;
 }
 
+void Framebuffer::invalidate(const Caps &caps, GLsizei numAttachments, const GLenum *attachments)
+{
+    GLuint maxDimension = caps.maxRenderbufferSize;
+    invalidateSub(caps, numAttachments, attachments, 0, 0, maxDimension, maxDimension);
+}
+
+void Framebuffer::invalidateSub(const Caps &caps, GLsizei numAttachments, const GLenum *attachments,
+                                GLint x, GLint y, GLsizei width, GLsizei height)
+{
+    ASSERT(completeness() == GL_FRAMEBUFFER_COMPLETE);
+    for (GLsizei attachIndex = 0; attachIndex < numAttachments; ++attachIndex)
+    {
+        GLenum attachmentTarget = attachments[attachIndex];
+
+        gl::FramebufferAttachment *attachment =
+            (attachmentTarget == GL_DEPTH_STENCIL_ATTACHMENT) ? getDepthOrStencilbuffer() :
+                                                                getAttachment(attachmentTarget);
+
+        if (attachment)
+        {
+            rx::RenderTarget *renderTarget = rx::GetAttachmentRenderTarget(attachment);
+            if (renderTarget)
+            {
+                renderTarget->invalidate(x, y, width, height);
+            }
+        }
+    }
+}
+
 DefaultFramebuffer::DefaultFramebuffer(rx::Renderer *renderer, Colorbuffer *colorbuffer, DepthStencilbuffer *depthStencil)
     : Framebuffer(renderer, 0)
 {
     Renderbuffer *colorRenderbuffer = new Renderbuffer(0, colorbuffer);
-    mColorbuffers[0] = new RenderbufferAttachment(colorRenderbuffer);
+    mColorbuffers[0] = new RenderbufferAttachment(GL_BACK, colorRenderbuffer);
 
     Renderbuffer *depthStencilBuffer = new Renderbuffer(0, depthStencil);
 
     // Make a new attachment objects to ensure we do not double-delete
     // See angle issue 686
-    mDepthbuffer = (depthStencilBuffer->getDepthSize() != 0 ? new RenderbufferAttachment(depthStencilBuffer) : NULL);
-    mStencilbuffer = (depthStencilBuffer->getStencilSize() != 0 ? new RenderbufferAttachment(depthStencilBuffer) : NULL);
+    mDepthbuffer = (depthStencilBuffer->getDepthSize() != 0 ? new RenderbufferAttachment(GL_DEPTH_ATTACHMENT, depthStencilBuffer) : NULL);
+    mStencilbuffer = (depthStencilBuffer->getStencilSize() != 0 ? new RenderbufferAttachment(GL_STENCIL_ATTACHMENT, depthStencilBuffer) : NULL);
 
     mDrawBufferStates[0] = GL_BACK;
     mReadBufferState = GL_BACK;
@@ -605,6 +675,31 @@
             mDepthbuffer->id() == mStencilbuffer->id());
 }
 
+ColorbufferInfo Framebuffer::getColorbuffersForRender() const
+{
+    ColorbufferInfo colorbuffersForRender;
+
+    for (size_t colorAttachment = 0; colorAttachment < IMPLEMENTATION_MAX_DRAW_BUFFERS; ++colorAttachment)
+    {
+        GLenum drawBufferState = mDrawBufferStates[colorAttachment];
+        FramebufferAttachment *colorbuffer = mColorbuffers[colorAttachment];
+
+        if (colorbuffer != NULL && drawBufferState != GL_NONE)
+        {
+            ASSERT(drawBufferState == GL_BACK || drawBufferState == (GL_COLOR_ATTACHMENT0_EXT + colorAttachment));
+            colorbuffersForRender.push_back(colorbuffer);
+        }
+#if (ANGLE_MRT_PERF_WORKAROUND == ANGLE_WORKAROUND_DISABLED)
+        else
+        {
+            colorbuffersForRender.push_back(NULL);
+        }
+#endif
+    }
+
+    return colorbuffersForRender;
+}
+
 GLenum DefaultFramebuffer::completeness() const
 {
     // The default framebuffer *must* always be complete, though it may not be
@@ -616,6 +711,7 @@
 {
     switch (attachment)
     {
+      case GL_COLOR:
       case GL_BACK:
         return getColorbuffer(0);
       case GL_DEPTH:
diff --git a/src/libGLESv2/Framebuffer.h b/src/libGLESv2/Framebuffer.h
index 035e16f..cc12d22 100644
--- a/src/libGLESv2/Framebuffer.h
+++ b/src/libGLESv2/Framebuffer.h
@@ -10,6 +10,8 @@
 #ifndef LIBGLESV2_FRAMEBUFFER_H_
 #define LIBGLESV2_FRAMEBUFFER_H_
 
+#include <vector>
+
 #include "common/angleutils.h"
 #include "common/RefCountObject.h"
 #include "constants.h"
@@ -26,6 +28,9 @@
 class Depthbuffer;
 class Stencilbuffer;
 class DepthStencilbuffer;
+struct Caps;
+
+typedef std::vector<FramebufferAttachment *> ColorbufferInfo;
 
 class Framebuffer
 {
@@ -67,6 +72,15 @@
     virtual GLenum completeness() const;
     bool hasValidDepthStencil() const;
 
+    void invalidate(const Caps &caps, GLsizei numAttachments, const GLenum *attachments);
+    void invalidateSub(const Caps &caps, GLsizei numAttachments, const GLenum *attachments,
+                       GLint x, GLint y, GLsizei width, GLsizei height);
+
+    // Use this method to retrieve the color buffer map when doing rendering.
+    // It will apply a workaround for poor shader performance on some systems
+    // by compacting the list to skip NULL values.
+    ColorbufferInfo getColorbuffersForRender() const;
+
   protected:
     rx::Renderer *mRenderer;
 
@@ -79,10 +93,10 @@
     FramebufferAttachment *mDepthbuffer;
     FramebufferAttachment *mStencilbuffer;
 
-private:
+  private:
     DISALLOW_COPY_AND_ASSIGN(Framebuffer);
 
-    FramebufferAttachment *createAttachment(GLenum type, GLuint handle, GLint level, GLint layer) const;
+    FramebufferAttachment *createAttachment(GLenum binding, GLenum type, GLuint handle, GLint level, GLint layer) const;
 };
 
 class DefaultFramebuffer : public Framebuffer
@@ -99,4 +113,14 @@
 
 }
 
+namespace rx
+{
+class RenderTarget;
+
+// TODO: place this in FramebufferD3D.h
+RenderTarget *GetAttachmentRenderTarget(gl::FramebufferAttachment *attachment);
+unsigned int GetAttachmentSerial(gl::FramebufferAttachment *attachment);
+
+}
+
 #endif   // LIBGLESV2_FRAMEBUFFER_H_
diff --git a/src/libGLESv2/FramebufferAttachment.cpp b/src/libGLESv2/FramebufferAttachment.cpp
index 6f40edf..540ede1 100644
--- a/src/libGLESv2/FramebufferAttachment.cpp
+++ b/src/libGLESv2/FramebufferAttachment.cpp
@@ -1,4 +1,3 @@
-#include "precompiled.h"
 //
 // 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
@@ -9,21 +8,22 @@
 // objects and related functionality. [OpenGL ES 2.0.24] section 4.4.3 page 108.
 
 #include "libGLESv2/FramebufferAttachment.h"
-#include "libGLESv2/renderer/RenderTarget.h"
-
 #include "libGLESv2/Texture.h"
-#include "libGLESv2/renderer/Renderer.h"
-#include "libGLESv2/renderer/d3d/TextureStorage.h"
-#include "common/utilities.h"
 #include "libGLESv2/formatutils.h"
 #include "libGLESv2/Renderbuffer.h"
+#include "libGLESv2/renderer/RenderTarget.h"
+#include "libGLESv2/renderer/Renderer.h"
+#include "libGLESv2/renderer/d3d/TextureStorage.h"
+
+#include "common/utilities.h"
 
 namespace gl
 {
 
 ////// FramebufferAttachment Implementation //////
 
-FramebufferAttachment::FramebufferAttachment()
+FramebufferAttachment::FramebufferAttachment(GLenum binding)
+    : mBinding(binding)
 {
 }
 
@@ -76,340 +76,85 @@
     return (type() != GL_RENDERBUFFER);
 }
 
-///// Texture2DAttachment Implementation ////////
+///// TextureAttachment Implementation ////////
 
-Texture2DAttachment::Texture2DAttachment(Texture2D *texture, GLint level) : mLevel(level)
+TextureAttachment::TextureAttachment(GLenum binding, Texture *texture, const ImageIndex &index)
+    : FramebufferAttachment(binding),
+      mIndex(index)
 {
-    mTexture2D.set(texture);
+    mTexture.set(texture);
 }
 
-Texture2DAttachment::~Texture2DAttachment()
+TextureAttachment::~TextureAttachment()
 {
-    mTexture2D.set(NULL);
+    mTexture.set(NULL);
 }
 
-rx::RenderTarget *Texture2DAttachment::getRenderTarget()
-{
-    return mTexture2D->getRenderTarget(mLevel);
-}
-
-rx::RenderTarget *Texture2DAttachment::getDepthStencil()
-{
-    return mTexture2D->getDepthStencil(mLevel);
-}
-
-rx::TextureStorage *Texture2DAttachment::getTextureStorage()
-{
-    return mTexture2D->getNativeTexture()->getStorageInstance();
-}
-
-GLsizei Texture2DAttachment::getWidth() const
-{
-    return mTexture2D->getWidth(mLevel);
-}
-
-GLsizei Texture2DAttachment::getHeight() const
-{
-    return mTexture2D->getHeight(mLevel);
-}
-
-GLenum Texture2DAttachment::getInternalFormat() const
-{
-    return mTexture2D->getInternalFormat(mLevel);
-}
-
-GLenum Texture2DAttachment::getActualFormat() const
-{
-    return mTexture2D->getActualFormat(mLevel);
-}
-
-GLsizei Texture2DAttachment::getSamples() const
+GLsizei TextureAttachment::getSamples() const
 {
     return 0;
 }
 
-unsigned int Texture2DAttachment::getSerial() const
+GLuint TextureAttachment::id() const
 {
-    return mTexture2D->getRenderTargetSerial(mLevel);
+    return mTexture->id();
 }
 
-GLuint Texture2DAttachment::id() const
+GLsizei TextureAttachment::getWidth() const
 {
-    return mTexture2D->id();
+    return mTexture->getWidth(mIndex);
 }
 
-GLenum Texture2DAttachment::type() const
+GLsizei TextureAttachment::getHeight() const
 {
-    return GL_TEXTURE_2D;
+    return mTexture->getHeight(mIndex);
 }
 
-GLint Texture2DAttachment::mipLevel() const
+GLenum TextureAttachment::getInternalFormat() const
 {
-    return mLevel;
+    return mTexture->getInternalFormat(mIndex);
 }
 
-GLint Texture2DAttachment::layer() const
+GLenum TextureAttachment::getActualFormat() const
 {
-    return 0;
+    return mTexture->getActualFormat(mIndex);
 }
 
-unsigned int Texture2DAttachment::getTextureSerial() const
+GLenum TextureAttachment::type() const
 {
-    return mTexture2D->getTextureSerial();
+    return mIndex.type;
 }
 
-///// TextureCubeMapAttachment Implementation ////////
-
-TextureCubeMapAttachment::TextureCubeMapAttachment(TextureCubeMap *texture, GLenum faceTarget, GLint level)
-    : mFaceTarget(faceTarget), mLevel(level)
+GLint TextureAttachment::mipLevel() const
 {
-    mTextureCubeMap.set(texture);
+    return mIndex.mipIndex;
 }
 
-TextureCubeMapAttachment::~TextureCubeMapAttachment()
+GLint TextureAttachment::layer() const
 {
-    mTextureCubeMap.set(NULL);
+    return mIndex.layerIndex;
 }
 
-rx::RenderTarget *TextureCubeMapAttachment::getRenderTarget()
+Texture *TextureAttachment::getTexture()
 {
-    return mTextureCubeMap->getRenderTarget(mFaceTarget, mLevel);
+    return mTexture.get();
 }
 
-rx::RenderTarget *TextureCubeMapAttachment::getDepthStencil()
+const ImageIndex *TextureAttachment::getTextureImageIndex() const
 {
-    return mTextureCubeMap->getDepthStencil(mFaceTarget, mLevel);
+    return &mIndex;
 }
 
-rx::TextureStorage *TextureCubeMapAttachment::getTextureStorage()
+Renderbuffer *TextureAttachment::getRenderbuffer()
 {
-    return mTextureCubeMap->getNativeTexture()->getStorageInstance();
-}
-
-GLsizei TextureCubeMapAttachment::getWidth() const
-{
-    return mTextureCubeMap->getWidth(mFaceTarget, mLevel);
-}
-
-GLsizei TextureCubeMapAttachment::getHeight() const
-{
-    return mTextureCubeMap->getHeight(mFaceTarget, mLevel);
-}
-
-GLenum TextureCubeMapAttachment::getInternalFormat() const
-{
-    return mTextureCubeMap->getInternalFormat(mFaceTarget, mLevel);
-}
-
-GLenum TextureCubeMapAttachment::getActualFormat() const
-{
-    return mTextureCubeMap->getActualFormat(mFaceTarget, mLevel);
-}
-
-GLsizei TextureCubeMapAttachment::getSamples() const
-{
-    return 0;
-}
-
-unsigned int TextureCubeMapAttachment::getSerial() const
-{
-    return mTextureCubeMap->getRenderTargetSerial(mFaceTarget, mLevel);
-}
-
-GLuint TextureCubeMapAttachment::id() const
-{
-    return mTextureCubeMap->id();
-}
-
-GLenum TextureCubeMapAttachment::type() const
-{
-    return mFaceTarget;
-}
-
-GLint TextureCubeMapAttachment::mipLevel() const
-{
-    return mLevel;
-}
-
-GLint TextureCubeMapAttachment::layer() const
-{
-    return 0;
-}
-
-unsigned int TextureCubeMapAttachment::getTextureSerial() const
-{
-    return mTextureCubeMap->getTextureSerial();
-}
-
-///// Texture3DAttachment Implementation ////////
-
-Texture3DAttachment::Texture3DAttachment(Texture3D *texture, GLint level, GLint layer)
-    : mLevel(level), mLayer(layer)
-{
-    mTexture3D.set(texture);
-}
-
-Texture3DAttachment::~Texture3DAttachment()
-{
-    mTexture3D.set(NULL);
-}
-
-rx::RenderTarget *Texture3DAttachment::getRenderTarget()
-{
-    return mTexture3D->getRenderTarget(mLevel, mLayer);
-}
-
-rx::RenderTarget *Texture3DAttachment::getDepthStencil()
-{
-    return mTexture3D->getDepthStencil(mLevel, mLayer);
-}
-
-rx::TextureStorage *Texture3DAttachment::getTextureStorage()
-{
-    return mTexture3D->getNativeTexture()->getStorageInstance();
-}
-
-GLsizei Texture3DAttachment::getWidth() const
-{
-    return mTexture3D->getWidth(mLevel);
-}
-
-GLsizei Texture3DAttachment::getHeight() const
-{
-    return mTexture3D->getHeight(mLevel);
-}
-
-GLenum Texture3DAttachment::getInternalFormat() const
-{
-    return mTexture3D->getInternalFormat(mLevel);
-}
-
-GLenum Texture3DAttachment::getActualFormat() const
-{
-    return mTexture3D->getActualFormat(mLevel);
-}
-
-GLsizei Texture3DAttachment::getSamples() const
-{
-    return 0;
-}
-
-unsigned int Texture3DAttachment::getSerial() const
-{
-    return mTexture3D->getRenderTargetSerial(mLevel, mLayer);
-}
-
-GLuint Texture3DAttachment::id() const
-{
-    return mTexture3D->id();
-}
-
-GLenum Texture3DAttachment::type() const
-{
-    return GL_TEXTURE_3D;
-}
-
-GLint Texture3DAttachment::mipLevel() const
-{
-    return mLevel;
-}
-
-GLint Texture3DAttachment::layer() const
-{
-    return mLayer;
-}
-
-unsigned int Texture3DAttachment::getTextureSerial() const
-{
-    return mTexture3D->getTextureSerial();
-}
-
-////// Texture2DArrayAttachment Implementation //////
-
-Texture2DArrayAttachment::Texture2DArrayAttachment(Texture2DArray *texture, GLint level, GLint layer)
-    : mLevel(level), mLayer(layer)
-{
-    mTexture2DArray.set(texture);
-}
-
-Texture2DArrayAttachment::~Texture2DArrayAttachment()
-{
-    mTexture2DArray.set(NULL);
-}
-
-rx::RenderTarget *Texture2DArrayAttachment::getRenderTarget()
-{
-    return mTexture2DArray->getRenderTarget(mLevel, mLayer);
-}
-
-rx::RenderTarget *Texture2DArrayAttachment::getDepthStencil()
-{
-    return mTexture2DArray->getDepthStencil(mLevel, mLayer);
-}
-
-rx::TextureStorage *Texture2DArrayAttachment::getTextureStorage()
-{
-    return mTexture2DArray->getNativeTexture()->getStorageInstance();
-}
-
-GLsizei Texture2DArrayAttachment::getWidth() const
-{
-    return mTexture2DArray->getWidth(mLevel);
-}
-
-GLsizei Texture2DArrayAttachment::getHeight() const
-{
-    return mTexture2DArray->getHeight(mLevel);
-}
-
-GLenum Texture2DArrayAttachment::getInternalFormat() const
-{
-    return mTexture2DArray->getInternalFormat(mLevel);
-}
-
-GLenum Texture2DArrayAttachment::getActualFormat() const
-{
-    return mTexture2DArray->getActualFormat(mLevel);
-}
-
-GLsizei Texture2DArrayAttachment::getSamples() const
-{
-    return 0;
-}
-
-unsigned int Texture2DArrayAttachment::getSerial() const
-{
-    return mTexture2DArray->getRenderTargetSerial(mLevel, mLayer);
-}
-
-GLuint Texture2DArrayAttachment::id() const
-{
-    return mTexture2DArray->id();
-}
-
-GLenum Texture2DArrayAttachment::type() const
-{
-    return GL_TEXTURE_2D_ARRAY;
-}
-
-GLint Texture2DArrayAttachment::mipLevel() const
-{
-    return mLevel;
-}
-
-GLint Texture2DArrayAttachment::layer() const
-{
-    return mLayer;
-}
-
-unsigned int Texture2DArrayAttachment::getTextureSerial() const
-{
-    return mTexture2DArray->getTextureSerial();
+    UNREACHABLE();
+    return NULL;
 }
 
 ////// RenderbufferAttachment Implementation //////
 
-RenderbufferAttachment::RenderbufferAttachment(Renderbuffer *renderbuffer)
+RenderbufferAttachment::RenderbufferAttachment(GLenum binding, Renderbuffer *renderbuffer)
+    : FramebufferAttachment(binding)
 {
     ASSERT(renderbuffer);
     mRenderbuffer.set(renderbuffer);
@@ -420,22 +165,6 @@
     mRenderbuffer.set(NULL);
 }
 
-rx::RenderTarget *RenderbufferAttachment::getRenderTarget()
-{
-    return mRenderbuffer->getStorage()->getRenderTarget();
-}
-
-rx::RenderTarget *RenderbufferAttachment::getDepthStencil()
-{
-    return mRenderbuffer->getStorage()->getDepthStencil();
-}
-
-rx::TextureStorage *RenderbufferAttachment::getTextureStorage()
-{
-    UNREACHABLE();
-    return NULL;
-}
-
 GLsizei RenderbufferAttachment::getWidth() const
 {
     return mRenderbuffer->getWidth();
@@ -461,11 +190,6 @@
     return mRenderbuffer->getStorage()->getSamples();
 }
 
-unsigned int RenderbufferAttachment::getSerial() const
-{
-    return mRenderbuffer->getStorage()->getSerial();
-}
-
 GLuint RenderbufferAttachment::id() const
 {
     return mRenderbuffer->id();
@@ -486,10 +210,21 @@
     return 0;
 }
 
-unsigned int RenderbufferAttachment::getTextureSerial() const
+Texture *RenderbufferAttachment::getTexture()
 {
     UNREACHABLE();
-    return 0;
+    return NULL;
+}
+
+const ImageIndex *RenderbufferAttachment::getTextureImageIndex() const
+{
+    UNREACHABLE();
+    return NULL;
+}
+
+Renderbuffer *RenderbufferAttachment::getRenderbuffer()
+{
+    return mRenderbuffer.get();
 }
 
 }
diff --git a/src/libGLESv2/FramebufferAttachment.h b/src/libGLESv2/FramebufferAttachment.h
index 18768f9..c18ef73 100644
--- a/src/libGLESv2/FramebufferAttachment.h
+++ b/src/libGLESv2/FramebufferAttachment.h
@@ -10,10 +10,11 @@
 #ifndef LIBGLESV2_FRAMEBUFFERATTACHMENT_H_
 #define LIBGLESV2_FRAMEBUFFERATTACHMENT_H_
 
-#include "angle_gl.h"
-
 #include "common/angleutils.h"
 #include "common/RefCountObject.h"
+#include "Texture.h"
+
+#include "angle_gl.h"
 
 namespace rx
 {
@@ -24,10 +25,6 @@
 
 namespace gl
 {
-class Texture2D;
-class TextureCubeMap;
-class Texture3D;
-class Texture2DArray;
 class Renderbuffer;
 
 // FramebufferAttachment implements a GL framebuffer attachment.
@@ -39,7 +36,7 @@
 class FramebufferAttachment
 {
   public:
-    FramebufferAttachment();
+    explicit FramebufferAttachment(GLenum binding);
     virtual ~FramebufferAttachment();
 
     // Helper methods
@@ -56,184 +53,80 @@
     bool isTextureWithId(GLuint textureId) const { return isTexture() && id() == textureId; }
     bool isRenderbufferWithId(GLuint renderbufferId) const { return !isTexture() && id() == renderbufferId; }
 
-    // Child class interface
-    virtual rx::RenderTarget *getRenderTarget() = 0;
-    virtual rx::RenderTarget *getDepthStencil() = 0;
-    virtual rx::TextureStorage *getTextureStorage() = 0;
+    GLenum getBinding() const { return mBinding; }
 
+    // Child class interface
     virtual GLsizei getWidth() const = 0;
     virtual GLsizei getHeight() const = 0;
     virtual GLenum getInternalFormat() const = 0;
     virtual GLenum getActualFormat() const = 0;
     virtual GLsizei getSamples() const = 0;
 
-    virtual unsigned int getSerial() const = 0;
-
     virtual GLuint id() const = 0;
     virtual GLenum type() const = 0;
     virtual GLint mipLevel() const = 0;
     virtual GLint layer() const = 0;
-    virtual unsigned int getTextureSerial() const = 0;
+
+    virtual Texture *getTexture() = 0;
+    virtual const ImageIndex *getTextureImageIndex() const = 0;
+    virtual Renderbuffer *getRenderbuffer() = 0;
 
   private:
     DISALLOW_COPY_AND_ASSIGN(FramebufferAttachment);
+
+    GLenum mBinding;
 };
 
-class Texture2DAttachment : public FramebufferAttachment
+class TextureAttachment : public FramebufferAttachment
 {
   public:
-    Texture2DAttachment(Texture2D *texture, GLint level);
+    TextureAttachment(GLenum binding, Texture *texture, const ImageIndex &index);
+    virtual ~TextureAttachment();
 
-    virtual ~Texture2DAttachment();
-
-    rx::RenderTarget *getRenderTarget();
-    rx::RenderTarget *getDepthStencil();
-    rx::TextureStorage *getTextureStorage();
+    virtual GLsizei getSamples() const;
+    virtual GLuint id() const;
 
     virtual GLsizei getWidth() const;
     virtual GLsizei getHeight() const;
     virtual GLenum getInternalFormat() const;
     virtual GLenum getActualFormat() const;
-    virtual GLsizei getSamples() const;
 
-    virtual unsigned int getSerial() const;
-
-    virtual GLuint id() const;
     virtual GLenum type() const;
     virtual GLint mipLevel() const;
     virtual GLint layer() const;
-    virtual unsigned int getTextureSerial() const;
+
+    virtual Texture *getTexture();
+    virtual const ImageIndex *getTextureImageIndex() const;
+    virtual Renderbuffer *getRenderbuffer();
 
   private:
-    DISALLOW_COPY_AND_ASSIGN(Texture2DAttachment);
+    DISALLOW_COPY_AND_ASSIGN(TextureAttachment);
 
-    BindingPointer<Texture2D> mTexture2D;
-    const GLint mLevel;
-};
-
-class TextureCubeMapAttachment : public FramebufferAttachment
-{
-  public:
-    TextureCubeMapAttachment(TextureCubeMap *texture, GLenum faceTarget, GLint level);
-
-    virtual ~TextureCubeMapAttachment();
-
-    rx::RenderTarget *getRenderTarget();
-    rx::RenderTarget *getDepthStencil();
-    rx::TextureStorage *getTextureStorage();
-
-    virtual GLsizei getWidth() const;
-    virtual GLsizei getHeight() const;
-    virtual GLenum getInternalFormat() const;
-    virtual GLenum getActualFormat() const;
-    virtual GLsizei getSamples() const;
-
-    virtual unsigned int getSerial() const;
-
-    virtual GLuint id() const;
-    virtual GLenum type() const;
-    virtual GLint mipLevel() const;
-    virtual GLint layer() const;
-    virtual unsigned int getTextureSerial() const;
-
-  private:
-    DISALLOW_COPY_AND_ASSIGN(TextureCubeMapAttachment);
-
-    BindingPointer<TextureCubeMap> mTextureCubeMap;
-    const GLint mLevel;
-    const GLenum mFaceTarget;
-};
-
-class Texture3DAttachment : public FramebufferAttachment
-{
-  public:
-    Texture3DAttachment(Texture3D *texture, GLint level, GLint layer);
-
-    virtual ~Texture3DAttachment();
-
-    rx::RenderTarget *getRenderTarget();
-    rx::RenderTarget *getDepthStencil();
-    rx::TextureStorage *getTextureStorage();
-
-    virtual GLsizei getWidth() const;
-    virtual GLsizei getHeight() const;
-    virtual GLenum getInternalFormat() const;
-    virtual GLenum getActualFormat() const;
-    virtual GLsizei getSamples() const;
-
-    virtual unsigned int getSerial() const;
-
-    virtual GLuint id() const;
-    virtual GLenum type() const;
-    virtual GLint mipLevel() const;
-    virtual GLint layer() const;
-    virtual unsigned int getTextureSerial() const;
-
-  private:
-    DISALLOW_COPY_AND_ASSIGN(Texture3DAttachment);
-
-    BindingPointer<Texture3D> mTexture3D;
-    const GLint mLevel;
-    const GLint mLayer;
-};
-
-class Texture2DArrayAttachment : public FramebufferAttachment
-{
-  public:
-    Texture2DArrayAttachment(Texture2DArray *texture, GLint level, GLint layer);
-
-    virtual ~Texture2DArrayAttachment();
-
-    rx::RenderTarget *getRenderTarget();
-    rx::RenderTarget *getDepthStencil();
-    rx::TextureStorage *getTextureStorage();
-
-    virtual GLsizei getWidth() const;
-    virtual GLsizei getHeight() const;
-    virtual GLenum getInternalFormat() const;
-    virtual GLenum getActualFormat() const;
-    virtual GLsizei getSamples() const;
-
-    virtual unsigned int getSerial() const;
-
-    virtual GLuint id() const;
-    virtual GLenum type() const;
-    virtual GLint mipLevel() const;
-    virtual GLint layer() const;
-    virtual unsigned int getTextureSerial() const;
-
-  private:
-    DISALLOW_COPY_AND_ASSIGN(Texture2DArrayAttachment);
-
-    BindingPointer<Texture2DArray> mTexture2DArray;
-    const GLint mLevel;
-    const GLint mLayer;
+    BindingPointer<Texture> mTexture;
+    ImageIndex mIndex;
 };
 
 class RenderbufferAttachment : public FramebufferAttachment
 {
   public:
-    RenderbufferAttachment(Renderbuffer *renderbuffer);
+    RenderbufferAttachment(GLenum binding, Renderbuffer *renderbuffer);
 
     virtual ~RenderbufferAttachment();
 
-    rx::RenderTarget *getRenderTarget();
-    rx::RenderTarget *getDepthStencil();
-    rx::TextureStorage *getTextureStorage();
-
     virtual GLsizei getWidth() const;
     virtual GLsizei getHeight() const;
     virtual GLenum getInternalFormat() const;
     virtual GLenum getActualFormat() const;
     virtual GLsizei getSamples() const;
 
-    virtual unsigned int getSerial() const;
-
     virtual GLuint id() const;
     virtual GLenum type() const;
     virtual GLint mipLevel() const;
     virtual GLint layer() const;
-    virtual unsigned int getTextureSerial() const;
+
+    virtual Texture *getTexture();
+    virtual const ImageIndex *getTextureImageIndex() const;
+    virtual Renderbuffer *getRenderbuffer();
 
   private:
     DISALLOW_COPY_AND_ASSIGN(RenderbufferAttachment);
diff --git a/src/libGLESv2/HandleAllocator.cpp b/src/libGLESv2/HandleAllocator.cpp
index 37da99a..c498f8a 100644
--- a/src/libGLESv2/HandleAllocator.cpp
+++ b/src/libGLESv2/HandleAllocator.cpp
@@ -1,4 +1,3 @@
-#include "precompiled.h"
 //
 // 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
diff --git a/src/libGLESv2/HandleAllocator.h b/src/libGLESv2/HandleAllocator.h
index bbded02..a89cc86 100644
--- a/src/libGLESv2/HandleAllocator.h
+++ b/src/libGLESv2/HandleAllocator.h
@@ -10,12 +10,12 @@
 #ifndef LIBGLESV2_HANDLEALLOCATOR_H_
 #define LIBGLESV2_HANDLEALLOCATOR_H_
 
+#include "common/angleutils.h"
+
 #include "angle_gl.h"
 
 #include <vector>
 
-#include "common/angleutils.h"
-
 namespace gl
 {
 
diff --git a/src/libGLESv2/ImageIndex.cpp b/src/libGLESv2/ImageIndex.cpp
new file mode 100644
index 0000000..3522b99
--- /dev/null
+++ b/src/libGLESv2/ImageIndex.cpp
@@ -0,0 +1,57 @@
+//
+// Copyright 2014 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+
+// ImageIndex.cpp: Implementation for ImageIndex methods.
+
+#include "libGLESv2/ImageIndex.h"
+#include "libGLESv2/Texture.h"
+#include "common/utilities.h"
+
+namespace gl
+{
+
+ImageIndex::ImageIndex(const ImageIndex &other)
+    : type(other.type),
+      mipIndex(other.mipIndex),
+      layerIndex(other.layerIndex)
+{}
+
+ImageIndex &ImageIndex::operator=(const ImageIndex &other)
+{
+    type = other.type;
+    mipIndex = other.mipIndex;
+    layerIndex = other.layerIndex;
+    return *this;
+}
+
+ImageIndex ImageIndex::Make2D(GLint mipIndex)
+{
+    return ImageIndex(GL_TEXTURE_2D, mipIndex, ENTIRE_LEVEL);
+}
+
+ImageIndex ImageIndex::MakeCube(GLenum target, GLint mipIndex)
+{
+    ASSERT(gl::IsCubemapTextureTarget(target));
+    return ImageIndex(target, mipIndex, TextureCubeMap::targetToLayerIndex(target));
+}
+
+ImageIndex ImageIndex::Make2DArray(GLint mipIndex, GLint layerIndex)
+{
+    return ImageIndex(GL_TEXTURE_2D_ARRAY, mipIndex, layerIndex);
+}
+
+ImageIndex ImageIndex::Make3D(GLint mipIndex, GLint layerIndex)
+{
+    return ImageIndex(GL_TEXTURE_3D, mipIndex, layerIndex);
+}
+
+ImageIndex::ImageIndex(GLenum typeIn, GLint mipIndexIn, GLint layerIndexIn)
+    : type(typeIn),
+      mipIndex(mipIndexIn),
+      layerIndex(layerIndexIn)
+{}
+
+}
diff --git a/src/libGLESv2/ImageIndex.h b/src/libGLESv2/ImageIndex.h
new file mode 100644
index 0000000..9f2df88
--- /dev/null
+++ b/src/libGLESv2/ImageIndex.h
@@ -0,0 +1,41 @@
+//
+// Copyright 2014 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+
+// ImageIndex.h: A helper struct for indexing into an Image array
+
+#ifndef LIBGLESV2_IMAGE_INDEX_H_
+#define LIBGLESV2_IMAGE_INDEX_H_
+
+#include "angle_gl.h"
+
+namespace gl
+{
+
+struct ImageIndex
+{
+    GLenum type;
+    GLint mipIndex;
+    GLint layerIndex;
+
+    ImageIndex(const ImageIndex &other);
+    ImageIndex &operator=(const ImageIndex &other);
+
+    bool hasLayer() const { return layerIndex != ENTIRE_LEVEL; }
+
+    static ImageIndex Make2D(GLint mipIndex);
+    static ImageIndex MakeCube(GLenum target, GLint mipIndex);
+    static ImageIndex Make2DArray(GLint mipIndex, GLint layerIndex);
+    static ImageIndex Make3D(GLint mipIndex, GLint layerIndex = ENTIRE_LEVEL);
+
+    static const GLint ENTIRE_LEVEL = static_cast<GLint>(-1);
+
+  private:
+    ImageIndex(GLenum typeIn, GLint mipIndexIn, GLint layerIndexIn);
+};
+
+}
+
+#endif // LIBGLESV2_IMAGE_INDEX_H_
diff --git a/src/libGLESv2/Program.cpp b/src/libGLESv2/Program.cpp
index 8a9fb04..9bfda09 100644
--- a/src/libGLESv2/Program.cpp
+++ b/src/libGLESv2/Program.cpp
@@ -1,4 +1,3 @@
-#include "precompiled.h"
 //
 // 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
@@ -11,6 +10,7 @@
 #include "libGLESv2/Program.h"
 #include "libGLESv2/ProgramBinary.h"
 #include "libGLESv2/ResourceManager.h"
+#include "libGLESv2/renderer/Renderer.h"
 
 namespace gl
 {
@@ -173,7 +173,7 @@
             return false;
         }
 
-        mVertexShader = (VertexShader*)shader;
+        mVertexShader = shader;
         mVertexShader->addRef();
     }
     else if (shader->getType() == GL_FRAGMENT_SHADER)
@@ -183,7 +183,7 @@
             return false;
         }
 
-        mFragmentShader = (FragmentShader*)shader;
+        mFragmentShader = shader;
         mFragmentShader->addRef();
     }
     else UNREACHABLE();
@@ -244,16 +244,16 @@
 // Links the HLSL code of the vertex and pixel shader by matching up their varyings,
 // compiling them into binaries, determining the attribute mappings, and collecting
 // a list of uniforms
-bool Program::link()
+bool Program::link(const Caps &caps)
 {
     unlink(false);
 
     mInfoLog.reset();
     resetUniformBlockBindings();
 
-    mProgramBinary.set(new ProgramBinary(mRenderer));
+    mProgramBinary.set(new ProgramBinary(mRenderer->createProgram()));
     mLinked = mProgramBinary->link(mInfoLog, mAttributeBindings, mFragmentShader, mVertexShader,
-                                   mTransformFeedbackVaryings, mTransformFeedbackBufferMode);
+                                   mTransformFeedbackVaryings, mTransformFeedbackBufferMode, caps);
 
     return mLinked;
 }
@@ -303,14 +303,15 @@
     return mProgramBinary.get();
 }
 
-bool Program::setProgramBinary(const void *binary, GLsizei length)
+bool Program::setProgramBinary(GLenum binaryFormat, const void *binary, GLsizei length)
 {
     unlink(false);
 
     mInfoLog.reset();
 
-    mProgramBinary.set(new ProgramBinary(mRenderer));
-    mLinked = mProgramBinary->load(mInfoLog, binary, length);
+    mProgramBinary.set(new ProgramBinary(mRenderer->createProgram()));
+    mLinked = mProgramBinary->load(mInfoLog, binaryFormat, binary, length);
+
     if (!mLinked)
     {
         mProgramBinary.set(NULL);
@@ -502,14 +503,14 @@
     return mDeleteStatus;
 }
 
-void Program::validate()
+void Program::validate(const Caps &caps)
 {
     mInfoLog.reset();
 
     ProgramBinary *programBinary = getProgramBinary();
     if (isLinked() && programBinary)
     {
-        programBinary->validate(mInfoLog);
+        programBinary->validate(mInfoLog, caps);
     }
     else
     {
diff --git a/src/libGLESv2/Program.h b/src/libGLESv2/Program.h
index ce821a4..6528dd1 100644
--- a/src/libGLESv2/Program.h
+++ b/src/libGLESv2/Program.h
@@ -10,14 +10,17 @@
 #ifndef LIBGLESV2_PROGRAM_H_
 #define LIBGLESV2_PROGRAM_H_
 
-#include <string>
-#include <set>
-
 #include "common/angleutils.h"
 #include "common/RefCountObject.h"
 #include "libGLESv2/Constants.h"
 #include "libGLESv2/ProgramBinary.h"
 
+#include <GLES2/gl2.h>
+
+#include <vector>
+#include <string>
+#include <set>
+
 namespace rx
 {
 class Renderer;
@@ -25,9 +28,8 @@
 
 namespace gl
 {
+struct Caps;
 class ResourceManager;
-class FragmentShader;
-class VertexShader;
 class Shader;
 
 extern const char * const g_fakepath;
@@ -75,9 +77,9 @@
 
     void bindAttributeLocation(GLuint index, const char *name);
 
-    bool link();
+    bool link(const Caps &caps);
     bool isLinked();
-    bool setProgramBinary(const void *binary, GLsizei length);
+    bool setProgramBinary(GLenum binaryFormat, const void *binary, GLsizei length);
     ProgramBinary *getProgramBinary() const;
 
     int getInfoLogLength() const;
@@ -110,7 +112,7 @@
     void flagForDeletion();
     bool isFlaggedForDeletion() const;
 
-    void validate();
+    void validate(const Caps &caps);
     bool isValidated() const;
 
     GLint getProgramBinaryLength() const;
@@ -121,8 +123,8 @@
     void unlink(bool destroy = false);
     void resetUniformBlockBindings();
 
-    FragmentShader *mFragmentShader;
-    VertexShader *mVertexShader;
+    Shader *mFragmentShader;
+    Shader *mVertexShader;
 
     AttributeBindings mAttributeBindings;
 
diff --git a/src/libGLESv2/ProgramBinary.cpp b/src/libGLESv2/ProgramBinary.cpp
index 38a6604..405a73c 100644
--- a/src/libGLESv2/ProgramBinary.cpp
+++ b/src/libGLESv2/ProgramBinary.cpp
@@ -1,4 +1,3 @@
-#include "precompiled.h"
 //
 // 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
@@ -11,33 +10,34 @@
 #include "libGLESv2/BinaryStream.h"
 #include "libGLESv2/ProgramBinary.h"
 #include "libGLESv2/Framebuffer.h"
+#include "libGLESv2/FramebufferAttachment.h"
 #include "libGLESv2/Renderbuffer.h"
 #include "libGLESv2/renderer/ShaderExecutable.h"
 
 #include "common/debug.h"
 #include "common/version.h"
 #include "common/utilities.h"
+#include "common/platform.h"
 
 #include "libGLESv2/main.h"
 #include "libGLESv2/Shader.h"
 #include "libGLESv2/Program.h"
+#include "libGLESv2/renderer/ProgramImpl.h"
 #include "libGLESv2/renderer/Renderer.h"
+#include "libGLESv2/renderer/d3d/DynamicHLSL.h"
+#include "libGLESv2/renderer/d3d/ShaderD3D.h"
 #include "libGLESv2/renderer/d3d/VertexDataManager.h"
 #include "libGLESv2/Context.h"
 #include "libGLESv2/Buffer.h"
-#include "libGLESv2/DynamicHLSL.h"
 #include "common/blocklayout.h"
 
-#undef near
-#undef far
-
 namespace gl
 {
 
 namespace
 {
 
-TextureType GetTextureType(GLenum samplerType)
+GLenum GetTextureType(GLenum samplerType)
 {
     switch (samplerType)
     {
@@ -45,26 +45,26 @@
       case GL_INT_SAMPLER_2D:
       case GL_UNSIGNED_INT_SAMPLER_2D:
       case GL_SAMPLER_2D_SHADOW:
-        return TEXTURE_2D;
+        return GL_TEXTURE_2D;
       case GL_SAMPLER_3D:
       case GL_INT_SAMPLER_3D:
       case GL_UNSIGNED_INT_SAMPLER_3D:
-        return TEXTURE_3D;
+        return GL_TEXTURE_3D;
       case GL_SAMPLER_CUBE:
       case GL_SAMPLER_CUBE_SHADOW:
-        return TEXTURE_CUBE;
+        return GL_TEXTURE_CUBE_MAP;
       case GL_INT_SAMPLER_CUBE:
       case GL_UNSIGNED_INT_SAMPLER_CUBE:
-        return TEXTURE_CUBE;
+        return GL_TEXTURE_CUBE_MAP;
       case GL_SAMPLER_2D_ARRAY:
       case GL_INT_SAMPLER_2D_ARRAY:
       case GL_UNSIGNED_INT_SAMPLER_2D_ARRAY:
       case GL_SAMPLER_2D_ARRAY_SHADOW:
-        return TEXTURE_2D_ARRAY;
+        return GL_TEXTURE_2D_ARRAY;
       default: UNREACHABLE();
     }
 
-    return TEXTURE_2D;
+    return GL_TEXTURE_2D;
 }
 
 unsigned int ParseAndStripArrayIndex(std::string* name)
@@ -83,7 +83,7 @@
     return subscript;
 }
 
-void GetInputLayoutFromShader(const std::vector<sh::Attribute> &shaderAttributes, VertexFormat inputLayout[MAX_VERTEX_ATTRIBS])
+void GetDefaultInputLayoutFromShader(const std::vector<sh::Attribute> &shaderAttributes, VertexFormat inputLayout[MAX_VERTEX_ATTRIBS])
 {
     size_t layoutIndex = 0;
     for (size_t attributeIndex = 0; attributeIndex < shaderAttributes.size(); attributeIndex++)
@@ -109,6 +109,26 @@
     }
 }
 
+std::vector<GLenum> GetDefaultOutputLayoutFromShader(const std::vector<rx::PixelShaderOutputVariable> &shaderOutputVars)
+{
+    std::vector<GLenum> defaultPixelOutput(1);
+
+    ASSERT(!shaderOutputVars.empty());
+    defaultPixelOutput[0] = GL_COLOR_ATTACHMENT0 + shaderOutputVars[0].outputIndex;
+
+    return defaultPixelOutput;
+}
+
+bool IsRowMajorLayout(const sh::InterfaceBlockField &var)
+{
+    return var.isRowMajorLayout;
+}
+
+bool IsRowMajorLayout(const sh::ShaderVariable &var)
+{
+    return false;
+}
+
 }
 
 VariableLocation::VariableLocation(const std::string &name, unsigned int element, unsigned int index)
@@ -169,45 +189,30 @@
 
 unsigned int ProgramBinary::mCurrentSerial = 1;
 
-ProgramBinary::ProgramBinary(rx::Renderer *renderer)
+ProgramBinary::ProgramBinary(rx::ProgramImpl *impl)
     : RefCountObject(0),
-      mRenderer(renderer),
-      mDynamicHLSL(NULL),
-      mVertexWorkarounds(rx::ANGLE_D3D_WORKAROUND_NONE),
-      mPixelWorkarounds(rx::ANGLE_D3D_WORKAROUND_NONE),
+      mProgram(impl),
       mGeometryExecutable(NULL),
       mUsedVertexSamplerRange(0),
       mUsedPixelSamplerRange(0),
       mUsesPointSize(false),
       mShaderVersion(100),
       mDirtySamplerMapping(true),
-      mVertexUniformStorage(NULL),
-      mFragmentUniformStorage(NULL),
       mValidated(false),
       mSerial(issueSerial())
 {
+    ASSERT(impl);
+
     for (int index = 0; index < MAX_VERTEX_ATTRIBS; index++)
     {
         mSemanticIndex[index] = -1;
     }
-
-    for (int index = 0; index < MAX_TEXTURE_IMAGE_UNITS; index++)
-    {
-        mSamplersPS[index].active = false;
-    }
-
-    for (int index = 0; index < IMPLEMENTATION_MAX_VERTEX_TEXTURE_IMAGE_UNITS; index++)
-    {
-        mSamplersVS[index].active = false;
-    }
-
-    mDynamicHLSL = new DynamicHLSL(renderer);
 }
 
 ProgramBinary::~ProgramBinary()
 {
     reset();
-    SafeDelete(mDynamicHLSL);
+    SafeDelete(mProgram);
 }
 
 unsigned int ProgramBinary::getSerial() const
@@ -227,17 +232,21 @@
 
 rx::ShaderExecutable *ProgramBinary::getPixelExecutableForFramebuffer(const Framebuffer *fbo)
 {
-    std::vector<GLenum> outputs(IMPLEMENTATION_MAX_DRAW_BUFFERS);
-    for (size_t outputIndex = 0; outputIndex < IMPLEMENTATION_MAX_DRAW_BUFFERS; outputIndex++)
+    std::vector<GLenum> outputs;
+
+    const gl::ColorbufferInfo &colorbuffers = fbo->getColorbuffersForRender();
+
+    for (size_t colorAttachment = 0; colorAttachment < colorbuffers.size(); ++colorAttachment)
     {
-        if (fbo->getColorbuffer(outputIndex) != NULL)
+        const gl::FramebufferAttachment *colorbuffer = colorbuffers[colorAttachment];
+
+        if (colorbuffer)
         {
-            // Always output floats for now
-            outputs[outputIndex] = GL_FLOAT;
+            outputs.push_back(colorbuffer->getBinding() == GL_BACK ? GL_COLOR_ATTACHMENT0 : colorbuffer->getBinding());
         }
         else
         {
-            outputs[outputIndex] = GL_NONE;
+            outputs.push_back(GL_NONE);
         }
     }
 
@@ -254,15 +263,9 @@
         }
     }
 
-    std::string finalPixelHLSL = mDynamicHLSL->generatePixelShaderForOutputSignature(mPixelHLSL, mPixelShaderKey, mUsesFragDepth,
-                                                                                     outputSignature);
-
-    // Generate new pixel executable
     InfoLog tempInfoLog;
-    rx::ShaderExecutable *pixelExecutable = mRenderer->compileToExecutable(tempInfoLog, finalPixelHLSL.c_str(), rx::SHADER_PIXEL,
-                                                                           mTransformFeedbackLinkedVaryings,
-                                                                           (mTransformFeedbackBufferMode == GL_SEPARATE_ATTRIBS),
-                                                                           mPixelWorkarounds);
+    rx::ShaderExecutable *pixelExecutable = mProgram->getPixelExecutableForOutputLayout(tempInfoLog, outputSignature,
+            mTransformFeedbackLinkedVaryings, (mTransformFeedbackBufferMode == GL_SEPARATE_ATTRIBS));
 
     if (!pixelExecutable)
     {
@@ -281,7 +284,7 @@
 rx::ShaderExecutable *ProgramBinary::getVertexExecutableForInputLayout(const VertexFormat inputLayout[MAX_VERTEX_ATTRIBS])
 {
     GLenum signature[MAX_VERTEX_ATTRIBS];
-    mDynamicHLSL->getInputLayoutSignature(inputLayout, signature);
+    mProgram->getDynamicHLSL()->getInputLayoutSignature(inputLayout, signature);
 
     for (size_t executableIndex = 0; executableIndex < mVertexExecutables.size(); executableIndex++)
     {
@@ -291,16 +294,9 @@
         }
     }
 
-    // Generate new dynamic layout with attribute conversions
-    std::string finalVertexHLSL = mDynamicHLSL->generateVertexShaderForInputLayout(mVertexHLSL, inputLayout, mShaderAttributes);
-
-    // Generate new vertex executable
     InfoLog tempInfoLog;
-    rx::ShaderExecutable *vertexExecutable = mRenderer->compileToExecutable(tempInfoLog, finalVertexHLSL.c_str(),
-                                                                            rx::SHADER_VERTEX,
-                                                                            mTransformFeedbackLinkedVaryings,
-                                                                            (mTransformFeedbackBufferMode == GL_SEPARATE_ATTRIBS),
-                                                                            mVertexWorkarounds);
+    rx::ShaderExecutable *vertexExecutable = mProgram->getVertexExecutableForInputLayout(tempInfoLog, inputLayout, mShaderAttributes,
+            mTransformFeedbackLinkedVaryings, (mTransformFeedbackBufferMode == GL_SEPARATE_ATTRIBS));
 
     if (!vertexExecutable)
     {
@@ -366,7 +362,7 @@
 
 bool ProgramBinary::usesPointSpriteEmulation() const
 {
-    return mUsesPointSize && mRenderer->getMajorShaderModel() >= 4;
+    return mUsesPointSize && mProgram->getRenderer()->getMajorShaderModel() >= 4;
 }
 
 bool ProgramBinary::usesGeometryShader() const
@@ -374,26 +370,22 @@
     return usesPointSpriteEmulation();
 }
 
-// Returns the index of the texture image unit (0-19) corresponding to a Direct3D 9 sampler
-// index (0-15 for the pixel shader and 0-3 for the vertex shader).
-GLint ProgramBinary::getSamplerMapping(SamplerType type, unsigned int samplerIndex)
+GLint ProgramBinary::getSamplerMapping(SamplerType type, unsigned int samplerIndex, const Caps &caps)
 {
     GLint logicalTextureUnit = -1;
 
     switch (type)
     {
       case SAMPLER_PIXEL:
-        ASSERT(samplerIndex < ArraySize(mSamplersPS));
-
-        if (mSamplersPS[samplerIndex].active)
+        ASSERT(samplerIndex < caps.maxTextureImageUnits);
+        if (samplerIndex < mSamplersPS.size() && mSamplersPS[samplerIndex].active)
         {
             logicalTextureUnit = mSamplersPS[samplerIndex].logicalTextureUnit;
         }
         break;
       case SAMPLER_VERTEX:
-        ASSERT(samplerIndex < ArraySize(mSamplersVS));
-
-        if (mSamplersVS[samplerIndex].active)
+        ASSERT(samplerIndex < caps.maxVertexTextureImageUnits);
+        if (samplerIndex < mSamplersVS.size() && mSamplersVS[samplerIndex].active)
         {
             logicalTextureUnit = mSamplersVS[samplerIndex].logicalTextureUnit;
         }
@@ -401,7 +393,7 @@
       default: UNREACHABLE();
     }
 
-    if (logicalTextureUnit >= 0 && logicalTextureUnit < (GLint)mRenderer->getMaxCombinedTextureImageUnits())
+    if (logicalTextureUnit >= 0 && logicalTextureUnit < static_cast<GLint>(caps.maxCombinedTextureImageUnits))
     {
         return logicalTextureUnit;
     }
@@ -411,22 +403,22 @@
 
 // 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).
-TextureType ProgramBinary::getSamplerTextureType(SamplerType type, unsigned int samplerIndex)
+GLenum ProgramBinary::getSamplerTextureType(SamplerType type, unsigned int samplerIndex)
 {
     switch (type)
     {
       case SAMPLER_PIXEL:
-        ASSERT(samplerIndex < ArraySize(mSamplersPS));
+        ASSERT(samplerIndex < mSamplersPS.size());
         ASSERT(mSamplersPS[samplerIndex].active);
         return mSamplersPS[samplerIndex].textureType;
       case SAMPLER_VERTEX:
-        ASSERT(samplerIndex < ArraySize(mSamplersVS));
+        ASSERT(samplerIndex < mSamplersVS.size());
         ASSERT(mSamplersVS[samplerIndex].active);
         return mSamplersVS[samplerIndex].textureType;
       default: UNREACHABLE();
     }
 
-    return TEXTURE_2D;
+    return GL_TEXTURE_2D;
 }
 
 GLint ProgramBinary::getUniformLocation(std::string name)
@@ -562,38 +554,64 @@
 
     if (targetUniform->type == targetUniformType)
     {
-        T *target = (T*)targetUniform->data + mUniformIndex[location].element * 4;
+        T *target = reinterpret_cast<T*>(targetUniform->data) + mUniformIndex[location].element * 4;
 
         for (int i = 0; i < count; i++)
         {
+            T *dest = target + (i * 4);
+            const T *source = v + (i * components);
+
             for (int c = 0; c < components; c++)
             {
-                SetIfDirty(target + c, v[c], &targetUniform->dirty);
+                SetIfDirty(dest + c, source[c], &targetUniform->dirty);
             }
             for (int c = components; c < 4; c++)
             {
-                SetIfDirty(target + c, T(0), &targetUniform->dirty);
+                SetIfDirty(dest + c, T(0), &targetUniform->dirty);
             }
-            target += 4;
-            v += components;
         }
     }
     else if (targetUniform->type == targetBoolType)
     {
-        GLint *boolParams = (GLint*)targetUniform->data + mUniformIndex[location].element * 4;
+        GLint *boolParams = reinterpret_cast<GLint*>(targetUniform->data) + mUniformIndex[location].element * 4;
 
         for (int i = 0; i < count; i++)
         {
+            GLint *dest = boolParams + (i * 4);
+            const T *source = v + (i * components);
+
             for (int c = 0; c < components; c++)
             {
-                SetIfDirty(boolParams + c, (v[c] == static_cast<T>(0)) ? GL_FALSE : GL_TRUE, &targetUniform->dirty);
+                SetIfDirty(dest + c, (source[c] == static_cast<T>(0)) ? GL_FALSE : GL_TRUE, &targetUniform->dirty);
             }
             for (int c = components; c < 4; c++)
             {
-                SetIfDirty(boolParams + c, GL_FALSE, &targetUniform->dirty);
+                SetIfDirty(dest + c, GL_FALSE, &targetUniform->dirty);
             }
-            boolParams += 4;
-            v += components;
+        }
+    }
+    else if (IsSampler(targetUniform->type))
+    {
+        ASSERT(targetUniformType == GL_INT);
+
+        GLint *target = reinterpret_cast<GLint*>(targetUniform->data) + mUniformIndex[location].element * 4;
+
+        bool wasDirty = targetUniform->dirty;
+
+        for (int i = 0; i < count; i++)
+        {
+            GLint *dest = target + (i * 4);
+            const GLint *source = reinterpret_cast<const GLint*>(v) + (i * components);
+
+            SetIfDirty(dest + 0, source[0], &targetUniform->dirty);
+            SetIfDirty(dest + 1, 0, &targetUniform->dirty);
+            SetIfDirty(dest + 2, 0, &targetUniform->dirty);
+            SetIfDirty(dest + 3, 0, &targetUniform->dirty);
+        }
+
+        if (!wasDirty && targetUniform->dirty)
+        {
+            mDirtySamplerMapping = true;
         }
     }
     else UNREACHABLE();
@@ -761,48 +779,7 @@
 
 void ProgramBinary::setUniform1iv(GLint location, GLsizei count, const GLint *v)
 {
-    LinkedUniform *targetUniform = mUniforms[mUniformIndex[location].index];
-
-    int elementCount = targetUniform->elementCount();
-
-    count = std::min(elementCount - (int)mUniformIndex[location].element, count);
-
-    if (targetUniform->type == GL_INT || IsSampler(targetUniform->type))
-    {
-        GLint *target = (GLint*)targetUniform->data + mUniformIndex[location].element * 4;
-
-        for (int i = 0; i < count; i++)
-        {
-            SetIfDirty(target + 0, v[0], &targetUniform->dirty);
-            SetIfDirty(target + 1, 0, &targetUniform->dirty);
-            SetIfDirty(target + 2, 0, &targetUniform->dirty);
-            SetIfDirty(target + 3, 0, &targetUniform->dirty);
-            target += 4;
-            v += 1;
-        }
-    }
-    else if (targetUniform->type == GL_BOOL)
-    {
-        GLint *boolParams = (GLint*)targetUniform->data + mUniformIndex[location].element * 4;
-
-        for (int i = 0; i < count; i++)
-        {
-            SetIfDirty(boolParams + 0, (v[0] == 0) ? GL_FALSE : GL_TRUE, &targetUniform->dirty);
-            SetIfDirty(boolParams + 1, GL_FALSE, &targetUniform->dirty);
-            SetIfDirty(boolParams + 2, GL_FALSE, &targetUniform->dirty);
-            SetIfDirty(boolParams + 3, GL_FALSE, &targetUniform->dirty);
-            boolParams += 4;
-            v += 1;
-        }
-    }
-    else UNREACHABLE();
-
-    // Set a special flag if we change a sampler uniform
-    if (IsSampler(targetUniform->type) &&
-        (memcmp(targetUniform->data, v, sizeof(GLint)) != 0))
-    {
-        mDirtySamplerMapping = true;
-    }
+    setUniform(location, count, v, GL_INT);
 }
 
 void ProgramBinary::setUniform2iv(GLint location, GLsizei count, const GLint *v)
@@ -841,20 +818,10 @@
 }
 
 template <typename T>
-bool ProgramBinary::getUniformv(GLint location, GLsizei *bufSize, T *params, GLenum uniformType)
+void ProgramBinary::getUniformv(GLint location, T *params, GLenum uniformType)
 {
     LinkedUniform *targetUniform = mUniforms[mUniformIndex[location].index];
 
-    // sized queries -- ensure the provided buffer is large enough
-    if (bufSize)
-    {
-        int requiredBytes = VariableExternalSize(targetUniform->type);
-        if (*bufSize < requiredBytes)
-        {
-            return false;
-        }
-    }
-
     if (IsMatrixType(targetUniform->type))
     {
         const int rows = VariableRowCount(targetUniform->type);
@@ -919,23 +886,21 @@
           default: UNREACHABLE();
         }
     }
-
-    return true;
 }
 
-bool ProgramBinary::getUniformfv(GLint location, GLsizei *bufSize, GLfloat *params)
+void ProgramBinary::getUniformfv(GLint location, GLfloat *params)
 {
-    return getUniformv(location, bufSize, params, GL_FLOAT);
+    getUniformv(location, params, GL_FLOAT);
 }
 
-bool ProgramBinary::getUniformiv(GLint location, GLsizei *bufSize, GLint *params)
+void ProgramBinary::getUniformiv(GLint location, GLint *params)
 {
-    return getUniformv(location, bufSize, params, GL_INT);
+    getUniformv(location, params, GL_INT);
 }
 
-bool ProgramBinary::getUniformuiv(GLint location, GLsizei *bufSize, GLuint *params)
+void ProgramBinary::getUniformuiv(GLint location, GLuint *params)
 {
-    return getUniformv(location, bufSize, params, GL_UNSIGNED_INT);
+    getUniformv(location, params, GL_UNSIGNED_INT);
 }
 
 void ProgramBinary::dirtyAllUniforms()
@@ -976,7 +941,7 @@
                     {
                         unsigned int samplerIndex = firstIndex + i;
 
-                        if (samplerIndex < MAX_TEXTURE_IMAGE_UNITS)
+                        if (samplerIndex < mSamplersPS.size())
                         {
                             ASSERT(mSamplersPS[samplerIndex].active);
                             mSamplersPS[samplerIndex].logicalTextureUnit = v[i][0];
@@ -992,7 +957,7 @@
                     {
                         unsigned int samplerIndex = firstIndex + i;
 
-                        if (samplerIndex < IMPLEMENTATION_MAX_VERTEX_TEXTURE_IMAGE_UNITS)
+                        if (samplerIndex < mSamplersVS.size())
                         {
                             ASSERT(mSamplersVS[samplerIndex].active);
                             mSamplersVS[samplerIndex].logicalTextureUnit = v[i][0];
@@ -1009,7 +974,7 @@
 {
     updateSamplerMapping();
 
-    mRenderer->applyUniforms(*this);
+    mProgram->getRenderer()->applyUniforms(*this);
 
     for (size_t uniformIndex = 0; uniformIndex < mUniforms.size(); uniformIndex++)
     {
@@ -1017,13 +982,13 @@
     }
 }
 
-bool ProgramBinary::applyUniformBuffers(const std::vector<gl::Buffer*> boundBuffers)
+bool ProgramBinary::applyUniformBuffers(const std::vector<gl::Buffer*> boundBuffers, const Caps &caps)
 {
     const gl::Buffer *vertexUniformBuffers[gl::IMPLEMENTATION_MAX_VERTEX_SHADER_UNIFORM_BUFFERS] = {NULL};
     const gl::Buffer *fragmentUniformBuffers[gl::IMPLEMENTATION_MAX_FRAGMENT_SHADER_UNIFORM_BUFFERS] = {NULL};
 
-    const unsigned int reservedBuffersInVS = mRenderer->getReservedVertexUniformBuffers();
-    const unsigned int reservedBuffersInFS = mRenderer->getReservedFragmentUniformBuffers();
+    const unsigned int reservedBuffersInVS = mProgram->getRenderer()->getReservedVertexUniformBuffers();
+    const unsigned int reservedBuffersInFS = mProgram->getRenderer()->getReservedFragmentUniformBuffers();
 
     ASSERT(boundBuffers.size() == mUniformBlocks.size());
 
@@ -1040,13 +1005,17 @@
             return false;
         }
 
-        ASSERT(uniformBlock->isReferencedByVertexShader() || uniformBlock->isReferencedByFragmentShader());
+        // Unnecessary to apply an unreferenced standard or shared UBO
+        if (!uniformBlock->isReferencedByVertexShader() && !uniformBlock->isReferencedByFragmentShader())
+        {
+            continue;
+        }
 
         if (uniformBlock->isReferencedByVertexShader())
         {
             unsigned int registerIndex = uniformBlock->vsRegisterIndex - reservedBuffersInVS;
             ASSERT(vertexUniformBuffers[registerIndex] == NULL);
-            ASSERT(registerIndex < mRenderer->getMaxVertexShaderUniformBuffers());
+            ASSERT(registerIndex < caps.maxVertexUniformBlocks);
             vertexUniformBuffers[registerIndex] = uniformBuffer;
         }
 
@@ -1054,15 +1023,15 @@
         {
             unsigned int registerIndex = uniformBlock->psRegisterIndex - reservedBuffersInFS;
             ASSERT(fragmentUniformBuffers[registerIndex] == NULL);
-            ASSERT(registerIndex < mRenderer->getMaxFragmentShaderUniformBuffers());
+            ASSERT(registerIndex < caps.maxFragmentUniformBlocks);
             fragmentUniformBuffers[registerIndex] = uniformBuffer;
         }
     }
 
-    return mRenderer->setUniformBuffers(vertexUniformBuffers, fragmentUniformBuffers);
+    return mProgram->getRenderer()->setUniformBuffers(vertexUniformBuffers, fragmentUniformBuffers);
 }
 
-bool ProgramBinary::linkVaryings(InfoLog &infoLog, FragmentShader *fragmentShader, VertexShader *vertexShader)
+bool ProgramBinary::linkVaryings(InfoLog &infoLog, Shader *fragmentShader, Shader *vertexShader)
 {
     std::vector<PackedVarying> &fragmentVaryings = fragmentShader->getVaryings();
     std::vector<PackedVarying> &vertexVaryings = vertexShader->getVaryings();
@@ -1072,24 +1041,32 @@
         PackedVarying *input = &fragmentVaryings[fragVaryingIndex];
         bool matched = false;
 
+        // Built-in varyings obey special rules
+        if (input->isBuiltIn())
+        {
+            continue;
+        }
+
         for (size_t vertVaryingIndex = 0; vertVaryingIndex < vertexVaryings.size(); vertVaryingIndex++)
         {
             PackedVarying *output = &vertexVaryings[vertVaryingIndex];
             if (output->name == input->name)
             {
-                if (!linkValidateVariables(infoLog, output->name, *input, *output))
+                if (!linkValidateVaryings(infoLog, output->name, *input, *output))
                 {
                     return false;
                 }
 
                 output->registerIndex = input->registerIndex;
+                output->columnIndex = input->columnIndex;
 
                 matched = true;
                 break;
             }
         }
 
-        if (!matched)
+        // We permit unmatched, unreferenced varyings
+        if (!matched && input->staticUse)
         {
             infoLog.append("Fragment varying %s does not match any vertex varying", input->name.c_str());
             return false;
@@ -1099,17 +1076,19 @@
     return true;
 }
 
-bool ProgramBinary::load(InfoLog &infoLog, const void *binary, GLsizei length)
+bool ProgramBinary::load(InfoLog &infoLog, GLenum binaryFormat, const void *binary, GLsizei length)
 {
 #ifdef ANGLE_DISABLE_PROGRAM_BINARY_LOAD
     return false;
 #else
+    ASSERT(binaryFormat == mProgram->getBinaryFormat());
+
     reset();
 
     BinaryInputStream stream(binary, length);
 
-    int format = stream.readInt<int>();
-    if (format != GL_PROGRAM_BINARY_ANGLE)
+    GLenum format = stream.readInt<GLenum>();
+    if (format != mProgram->getBinaryFormat())
     {
         infoLog.append("Invalid program binary format.");
         return false;
@@ -1149,18 +1128,23 @@
 
     initAttributesByLayout();
 
-    for (unsigned int i = 0; i < MAX_TEXTURE_IMAGE_UNITS; ++i)
+    const unsigned int psSamplerCount = stream.readInt<unsigned int>();
+    for (unsigned int i = 0; i < psSamplerCount; ++i)
     {
-        stream.readBool(&mSamplersPS[i].active);
-        stream.readInt(&mSamplersPS[i].logicalTextureUnit);
-        stream.readInt(&mSamplersPS[i].textureType);
+        Sampler sampler;
+        stream.readBool(&sampler.active);
+        stream.readInt(&sampler.logicalTextureUnit);
+        stream.readInt(&sampler.textureType);
+        mSamplersPS.push_back(sampler);
     }
-
-    for (unsigned int i = 0; i < IMPLEMENTATION_MAX_VERTEX_TEXTURE_IMAGE_UNITS; ++i)
+    const unsigned int vsSamplerCount = stream.readInt<unsigned int>();
+    for (unsigned int i = 0; i < vsSamplerCount; ++i)
     {
-        stream.readBool(&mSamplersVS[i].active);
-        stream.readInt(&mSamplersVS[i].logicalTextureUnit);
-        stream.readInt(&mSamplersVS[i].textureType);
+        Sampler sampler;
+        stream.readBool(&sampler.active);
+        stream.readInt(&sampler.logicalTextureUnit);
+        stream.readInt(&sampler.textureType);
+        mSamplersVS.push_back(sampler);
     }
 
     stream.readInt(&mUsedVertexSamplerRange);
@@ -1260,10 +1244,6 @@
         stream.readInt(&varying.semanticIndexCount);
     }
 
-    stream.readString(&mVertexHLSL);
-
-    stream.readInt(&mVertexWorkarounds);
-
     const unsigned int vertexShaderCount = stream.readInt<unsigned int>();
     for (unsigned int vertexShaderIndex = 0; vertexShaderIndex < vertexShaderCount; vertexShaderIndex++)
     {
@@ -1280,7 +1260,7 @@
 
         unsigned int vertexShaderSize = stream.readInt<unsigned int>();
         const unsigned char *vertexShaderFunction = reinterpret_cast<const unsigned char*>(binary) + stream.offset();
-        rx::ShaderExecutable *shaderExecutable = mRenderer->loadExecutable(reinterpret_cast<const DWORD*>(vertexShaderFunction),
+        rx::ShaderExecutable *shaderExecutable = mProgram->getRenderer()->loadExecutable(reinterpret_cast<const DWORD*>(vertexShaderFunction),
                                                                            vertexShaderSize, rx::SHADER_VERTEX,
                                                                            mTransformFeedbackLinkedVaryings,
                                                                            (mTransformFeedbackBufferMode == GL_SEPARATE_ATTRIBS));
@@ -1292,7 +1272,7 @@
 
         // generated converted input layout
         GLenum signature[MAX_VERTEX_ATTRIBS];
-        mDynamicHLSL->getInputLayoutSignature(inputLayout, signature);
+        mProgram->getDynamicHLSL()->getInputLayoutSignature(inputLayout, signature);
 
         // add new binary
         mVertexExecutables.push_back(new VertexExecutable(inputLayout, signature, shaderExecutable));
@@ -1300,20 +1280,6 @@
         stream.skip(vertexShaderSize);
     }
 
-    stream.readString(&mPixelHLSL);
-    stream.readInt(&mPixelWorkarounds);
-    stream.readBool(&mUsesFragDepth);
-
-    const size_t pixelShaderKeySize = stream.readInt<unsigned int>();
-    mPixelShaderKey.resize(pixelShaderKeySize);
-    for (size_t pixelShaderKeyIndex = 0; pixelShaderKeyIndex < pixelShaderKeySize; pixelShaderKeyIndex++)
-    {
-        stream.readInt(&mPixelShaderKey[pixelShaderKeyIndex].type);
-        stream.readString(&mPixelShaderKey[pixelShaderKeyIndex].name);
-        stream.readString(&mPixelShaderKey[pixelShaderKeyIndex].source);
-        stream.readInt(&mPixelShaderKey[pixelShaderKeyIndex].outputIndex);
-    }
-
     const size_t pixelShaderCount = stream.readInt<unsigned int>();
     for (size_t pixelShaderIndex = 0; pixelShaderIndex < pixelShaderCount; pixelShaderIndex++)
     {
@@ -1326,10 +1292,11 @@
 
         const size_t pixelShaderSize = stream.readInt<unsigned int>();
         const unsigned char *pixelShaderFunction = reinterpret_cast<const unsigned char*>(binary) + stream.offset();
-        rx::ShaderExecutable *shaderExecutable = mRenderer->loadExecutable(pixelShaderFunction, pixelShaderSize,
-                                                                           rx::SHADER_PIXEL,
-                                                                           mTransformFeedbackLinkedVaryings,
-                                                                           (mTransformFeedbackBufferMode == GL_SEPARATE_ATTRIBS));
+        rx::Renderer *renderer = mProgram->getRenderer();
+        rx::ShaderExecutable *shaderExecutable = renderer->loadExecutable(pixelShaderFunction, pixelShaderSize,
+                                                                          rx::SHADER_PIXEL, mTransformFeedbackLinkedVaryings,
+                                                                          (mTransformFeedbackBufferMode == GL_SEPARATE_ATTRIBS));
+
         if (!shaderExecutable)
         {
             infoLog.append("Could not create pixel shader.");
@@ -1347,9 +1314,11 @@
     if (geometryShaderSize > 0)
     {
         const char *geometryShaderFunction = (const char*) binary + stream.offset();
-        mGeometryExecutable = mRenderer->loadExecutable(reinterpret_cast<const DWORD*>(geometryShaderFunction),
-                                                        geometryShaderSize, rx::SHADER_GEOMETRY, mTransformFeedbackLinkedVaryings,
-                                                        (mTransformFeedbackBufferMode == GL_SEPARATE_ATTRIBS));
+        rx::Renderer *renderer = mProgram->getRenderer();
+        mGeometryExecutable = renderer->loadExecutable(reinterpret_cast<const DWORD*>(geometryShaderFunction),
+                                                       geometryShaderSize, rx::SHADER_GEOMETRY, mTransformFeedbackLinkedVaryings,
+                                                       (mTransformFeedbackBufferMode == GL_SEPARATE_ATTRIBS));
+
         if (!mGeometryExecutable)
         {
             infoLog.append("Could not create geometry shader.");
@@ -1358,29 +1327,39 @@
         stream.skip(geometryShaderSize);
     }
 
+    if (!mProgram->load(infoLog, &stream))
+    {
+        return false;
+    }
+
     const char *ptr = (const char*) binary + stream.offset();
 
     const GUID *binaryIdentifier = (const GUID *) ptr;
     ptr += sizeof(GUID);
 
-    GUID identifier = mRenderer->getAdapterIdentifier();
+    GUID identifier = mProgram->getRenderer()->getAdapterIdentifier();
     if (memcmp(&identifier, binaryIdentifier, sizeof(GUID)) != 0)
     {
         infoLog.append("Invalid program binary.");
         return false;
     }
 
-    initializeUniformStorage();
+    mProgram->initializeUniformStorage(mUniforms);
 
     return true;
 #endif // #ifdef ANGLE_DISABLE_PROGRAM_BINARY_LOAD
 }
 
-bool ProgramBinary::save(void* binary, GLsizei bufSize, GLsizei *length)
+bool ProgramBinary::save(GLenum *binaryFormat, void *binary, GLsizei bufSize, GLsizei *length)
 {
+    if (binaryFormat)
+    {
+        *binaryFormat = mProgram->getBinaryFormat();
+    }
+
     BinaryOutputStream stream;
 
-    stream.writeInt(GL_PROGRAM_BINARY_ANGLE);
+    stream.writeInt(mProgram->getBinaryFormat());
     stream.writeInt(ANGLE_MAJOR_VERSION);
     stream.writeInt(ANGLE_MINOR_VERSION);
     stream.writeBytes(reinterpret_cast<const unsigned char*>(ANGLE_COMMIT_HASH), ANGLE_COMMIT_HASH_SIZE);
@@ -1395,14 +1374,16 @@
         stream.writeInt(mSemanticIndex[i]);
     }
 
-    for (unsigned int i = 0; i < MAX_TEXTURE_IMAGE_UNITS; ++i)
+    stream.writeInt(mSamplersPS.size());
+    for (unsigned int i = 0; i < mSamplersPS.size(); ++i)
     {
         stream.writeInt(mSamplersPS[i].active);
         stream.writeInt(mSamplersPS[i].logicalTextureUnit);
         stream.writeInt(mSamplersPS[i].textureType);
     }
 
-    for (unsigned int i = 0; i < IMPLEMENTATION_MAX_VERTEX_TEXTURE_IMAGE_UNITS; ++i)
+    stream.writeInt(mSamplersVS.size());
+    for (unsigned int i = 0; i < mSamplersVS.size(); ++i)
     {
         stream.writeInt(mSamplersVS[i].active);
         stream.writeInt(mSamplersVS[i].logicalTextureUnit);
@@ -1477,9 +1458,6 @@
         stream.writeInt(varying.semanticIndexCount);
     }
 
-    stream.writeString(mVertexHLSL);
-    stream.writeInt(mVertexWorkarounds);
-
     stream.writeInt(mVertexExecutables.size());
     for (size_t vertexExecutableIndex = 0; vertexExecutableIndex < mVertexExecutables.size(); vertexExecutableIndex++)
     {
@@ -1501,20 +1479,6 @@
         stream.writeBytes(vertexBlob, vertexShaderSize);
     }
 
-    stream.writeString(mPixelHLSL);
-    stream.writeInt(mPixelWorkarounds);
-    stream.writeInt(mUsesFragDepth);
-
-    stream.writeInt(mPixelShaderKey.size());
-    for (size_t pixelShaderKeyIndex = 0; pixelShaderKeyIndex < mPixelShaderKey.size(); pixelShaderKeyIndex++)
-    {
-        const PixelShaderOuputVariable &variable = mPixelShaderKey[pixelShaderKeyIndex];
-        stream.writeInt(variable.type);
-        stream.writeString(variable.name);
-        stream.writeString(variable.source);
-        stream.writeInt(variable.outputIndex);
-    }
-
     stream.writeInt(mPixelExecutables.size());
     for (size_t pixelExecutableIndex = 0; pixelExecutableIndex < mPixelExecutables.size(); pixelExecutableIndex++)
     {
@@ -1543,7 +1507,17 @@
         stream.writeBytes(geometryBlob, geometryShaderSize);
     }
 
-    GUID identifier = mRenderer->getAdapterIdentifier();
+    if (!mProgram->save(&stream))
+    {
+        if (length)
+        {
+            *length = 0;
+        }
+
+        return false;
+    }
+
+    GUID identifier = mProgram->getRenderer()->getAdapterIdentifier();
 
     GLsizei streamLength = stream.length();
     const void *streamData = stream.data();
@@ -1583,7 +1557,7 @@
 GLint ProgramBinary::getLength()
 {
     GLint length;
-    if (save(NULL, INT_MAX, &length))
+    if (save(NULL, NULL, INT_MAX, &length))
     {
         return length;
     }
@@ -1593,68 +1567,56 @@
     }
 }
 
-bool ProgramBinary::link(InfoLog &infoLog, const AttributeBindings &attributeBindings, FragmentShader *fragmentShader, VertexShader *vertexShader,
-                         const std::vector<std::string>& transformFeedbackVaryings, GLenum transformFeedbackBufferMode)
+bool ProgramBinary::link(InfoLog &infoLog, const AttributeBindings &attributeBindings, Shader *fragmentShader, Shader *vertexShader,
+                         const std::vector<std::string>& transformFeedbackVaryings, GLenum transformFeedbackBufferMode, const Caps &caps)
 {
     if (!fragmentShader || !fragmentShader->isCompiled())
     {
         return false;
     }
+    ASSERT(fragmentShader->getType() == GL_FRAGMENT_SHADER);
 
     if (!vertexShader || !vertexShader->isCompiled())
     {
         return false;
     }
+    ASSERT(vertexShader->getType() == GL_VERTEX_SHADER);
 
     reset();
 
+    mSamplersPS.resize(caps.maxTextureImageUnits);
+    mSamplersVS.resize(caps.maxVertexTextureImageUnits);
+
     mTransformFeedbackBufferMode = transformFeedbackBufferMode;
 
-    mShaderVersion = vertexShader->getShaderVersion();
+    rx::ShaderD3D *vertexShaderD3D = rx::ShaderD3D::makeShaderD3D(vertexShader->getImplementation());
+    rx::ShaderD3D *fragmentShaderD3D = rx::ShaderD3D::makeShaderD3D(fragmentShader->getImplementation());
 
-    mPixelHLSL = fragmentShader->getHLSL();
-    mPixelWorkarounds = fragmentShader->getD3DWorkarounds();
+    mShaderVersion = vertexShaderD3D->getShaderVersion();
 
-    mVertexHLSL = vertexShader->getHLSL();
-    mVertexWorkarounds = vertexShader->getD3DWorkarounds();
-
-    // Map the varyings to the register file
-    VaryingPacking packing = { NULL };
-    int registers = mDynamicHLSL->packVaryings(infoLog, packing, fragmentShader, vertexShader, transformFeedbackVaryings);
-
-    if (registers < 0)
-    {
-        return false;
-    }
-
-    if (!linkVaryings(infoLog, fragmentShader, vertexShader))
-    {
-        return false;
-    }
-
-    mUsesPointSize = vertexShader->usesPointSize();
+    int registers;
     std::vector<LinkedVarying> linkedVaryings;
-    if (!mDynamicHLSL->generateShaderLinkHLSL(infoLog, registers, packing, mPixelHLSL, mVertexHLSL,
-                                              fragmentShader, vertexShader, transformFeedbackVaryings,
-                                              &linkedVaryings, &mOutputVariables, &mPixelShaderKey, &mUsesFragDepth))
+    if (!mProgram->link(infoLog, fragmentShader, vertexShader, transformFeedbackVaryings, &registers, &linkedVaryings, &mOutputVariables))
     {
         return false;
     }
 
+    mUsesPointSize = vertexShaderD3D->usesPointSize();
+
     bool success = true;
 
-    if (!linkAttributes(infoLog, attributeBindings, fragmentShader, vertexShader))
+    if (!linkAttributes(infoLog, attributeBindings, vertexShader))
     {
         success = false;
     }
 
-    if (!linkUniforms(infoLog, *vertexShader, *fragmentShader))
+    if (!linkUniforms(infoLog, *vertexShader, *fragmentShader, caps))
     {
         success = false;
     }
 
     // special case for gl_DepthRange, the only built-in uniform (also a struct)
-    if (vertexShader->usesDepthRange() || fragmentShader->usesDepthRange())
+    if (vertexShaderD3D->usesDepthRange() || fragmentShaderD3D->usesDepthRange())
     {
         const sh::BlockMemberInfo &defaultInfo = sh::BlockMemberInfo::getDefaultBlockInfo();
 
@@ -1663,13 +1625,13 @@
         mUniforms.push_back(new LinkedUniform(GL_FLOAT, GL_HIGH_FLOAT, "gl_DepthRange.diff", 0, -1, defaultInfo));
     }
 
-    if (!linkUniformBlocks(infoLog, *vertexShader, *fragmentShader))
+    if (!linkUniformBlocks(infoLog, *vertexShader, *fragmentShader, caps))
     {
         success = false;
     }
 
     if (!gatherTransformFeedbackLinkedVaryings(infoLog, linkedVaryings, transformFeedbackVaryings,
-                                               transformFeedbackBufferMode, &mTransformFeedbackLinkedVaryings))
+                                               transformFeedbackBufferMode, &mTransformFeedbackLinkedVaryings, caps))
     {
         success = false;
     }
@@ -1677,23 +1639,19 @@
     if (success)
     {
         VertexFormat defaultInputLayout[MAX_VERTEX_ATTRIBS];
-        GetInputLayoutFromShader(vertexShader->activeAttributes(), defaultInputLayout);
+        GetDefaultInputLayoutFromShader(vertexShader->getActiveAttributes(), defaultInputLayout);
         rx::ShaderExecutable *defaultVertexExecutable = getVertexExecutableForInputLayout(defaultInputLayout);
 
-        std::vector<GLenum> defaultPixelOutput(IMPLEMENTATION_MAX_DRAW_BUFFERS);
-        for (size_t i = 0; i < defaultPixelOutput.size(); i++)
-        {
-            defaultPixelOutput[i] = (i == 0) ? GL_FLOAT : GL_NONE;
-        }
+        std::vector<GLenum> defaultPixelOutput = GetDefaultOutputLayoutFromShader(mProgram->getPixelShaderKey());
         rx::ShaderExecutable *defaultPixelExecutable = getPixelExecutableForOutputLayout(defaultPixelOutput);
 
         if (usesGeometryShader())
         {
-            std::string geometryHLSL = mDynamicHLSL->generateGeometryShaderHLSL(registers, fragmentShader, vertexShader);
-            mGeometryExecutable = mRenderer->compileToExecutable(infoLog, geometryHLSL.c_str(), rx::SHADER_GEOMETRY,
-                                                                 mTransformFeedbackLinkedVaryings,
-                                                                 (mTransformFeedbackBufferMode == GL_SEPARATE_ATTRIBS),
-                                                                 rx::ANGLE_D3D_WORKAROUND_NONE);
+            std::string geometryHLSL = mProgram->getDynamicHLSL()->generateGeometryShaderHLSL(registers, fragmentShaderD3D, vertexShaderD3D);
+            mGeometryExecutable = mProgram->getRenderer()->compileToExecutable(infoLog, geometryHLSL.c_str(),
+                                                                               rx::SHADER_GEOMETRY, mTransformFeedbackLinkedVaryings,
+                                                                               (mTransformFeedbackBufferMode == GL_SEPARATE_ATTRIBS),
+                                                                               rx::ANGLE_D3D_WORKAROUND_NONE);
         }
 
         if (!defaultVertexExecutable || !defaultPixelExecutable || (usesGeometryShader() && !mGeometryExecutable))
@@ -1708,15 +1666,20 @@
 }
 
 // Determines the mapping between GL attributes and Direct3D 9 vertex stream usage indices
-bool ProgramBinary::linkAttributes(InfoLog &infoLog, const AttributeBindings &attributeBindings, FragmentShader *fragmentShader, VertexShader *vertexShader)
+bool ProgramBinary::linkAttributes(InfoLog &infoLog, const AttributeBindings &attributeBindings, const Shader *vertexShader)
 {
+    const rx::ShaderD3D *vertexShaderD3D = rx::ShaderD3D::makeShaderD3D(vertexShader->getImplementation());
+
     unsigned int usedLocations = 0;
-    const std::vector<sh::Attribute> &activeAttributes = vertexShader->activeAttributes();
+    const std::vector<sh::Attribute> &shaderAttributes = vertexShader->getActiveAttributes();
 
     // Link attributes that have a binding location
-    for (unsigned int attributeIndex = 0; attributeIndex < activeAttributes.size(); attributeIndex++)
+    for (unsigned int attributeIndex = 0; attributeIndex < shaderAttributes.size(); attributeIndex++)
     {
-        const sh::Attribute &attribute = activeAttributes[attributeIndex];
+        const sh::Attribute &attribute = shaderAttributes[attributeIndex];
+
+        ASSERT(attribute.staticUse);
+
         const int location = attribute.location == -1 ? attributeBindings.getAttributeBinding(attribute.name) : attribute.location;
 
         mShaderAttributes[attributeIndex] = attribute;
@@ -1755,9 +1718,12 @@
     }
 
     // Link attributes that don't have a binding location
-    for (unsigned int attributeIndex = 0; attributeIndex < activeAttributes.size(); attributeIndex++)
+    for (unsigned int attributeIndex = 0; attributeIndex < shaderAttributes.size(); attributeIndex++)
     {
-        const sh::Attribute &attribute = activeAttributes[attributeIndex];
+        const sh::Attribute &attribute = shaderAttributes[attributeIndex];
+
+        ASSERT(attribute.staticUse);
+
         const int location = attribute.location == -1 ? attributeBindings.getAttributeBinding(attribute.name) : attribute.location;
 
         if (location == -1)   // Not set by glBindAttribLocation or by location layout qualifier
@@ -1778,7 +1744,7 @@
 
     for (int attributeIndex = 0; attributeIndex < MAX_VERTEX_ATTRIBS; )
     {
-        int index = vertexShader->getSemanticIndex(mLinkedAttribute[attributeIndex].name);
+        int index = vertexShaderD3D->getSemanticIndex(mLinkedAttribute[attributeIndex].name);
         int rows = VariableRegisterCount(mLinkedAttribute[attributeIndex].type);
 
         for (int r = 0; r < rows; r++)
@@ -1811,32 +1777,29 @@
         return false;
     }
 
-    return true;
-}
-
-template <class ShaderVarType>
-bool ProgramBinary::linkValidateFields(InfoLog &infoLog, const std::string &varName, const ShaderVarType &vertexVar, const ShaderVarType &fragmentVar)
-{
-    if (vertexVar.fields.size() != fragmentVar.fields.size())
+    if (vertexVariable.fields.size() != fragmentVariable.fields.size())
     {
-        infoLog.append("Structure lengths for %s differ between vertex and fragment shaders", varName.c_str());
+        infoLog.append("Structure lengths for %s differ between vertex and fragment shaders", variableName.c_str());
         return false;
     }
-    const unsigned int numMembers = vertexVar.fields.size();
+    const unsigned int numMembers = vertexVariable.fields.size();
     for (unsigned int memberIndex = 0; memberIndex < numMembers; memberIndex++)
     {
-        const ShaderVarType &vertexMember = vertexVar.fields[memberIndex];
-        const ShaderVarType &fragmentMember = fragmentVar.fields[memberIndex];
+        const sh::ShaderVariable &vertexMember = vertexVariable.fields[memberIndex];
+        const sh::ShaderVariable &fragmentMember = fragmentVariable.fields[memberIndex];
 
         if (vertexMember.name != fragmentMember.name)
         {
             infoLog.append("Name mismatch for field '%d' of %s: (in vertex: '%s', in fragment: '%s')",
-                           memberIndex, varName.c_str(), vertexMember.name.c_str(), fragmentMember.name.c_str());
+                           memberIndex, variableName.c_str(),
+                           vertexMember.name.c_str(), fragmentMember.name.c_str());
             return false;
         }
 
-        const std::string memberName = varName.substr(0, varName.length()-1) + "." + vertexVar.name + "'";
-        if (!linkValidateVariables(infoLog, memberName, vertexMember, fragmentMember))
+        const std::string memberName = variableName.substr(0, variableName.length() - 1) + "." +
+                                       vertexMember.name + "'";
+
+        if (!linkValidateVariablesBase(infoLog, vertexMember.name, vertexMember, fragmentMember, validatePrecision))
         {
             return false;
         }
@@ -1845,22 +1808,17 @@
     return true;
 }
 
-bool ProgramBinary::linkValidateVariables(InfoLog &infoLog, const std::string &uniformName, const sh::Uniform &vertexUniform, const sh::Uniform &fragmentUniform)
+bool ProgramBinary::linkValidateUniforms(InfoLog &infoLog, const std::string &uniformName, const sh::Uniform &vertexUniform, const sh::Uniform &fragmentUniform)
 {
     if (!linkValidateVariablesBase(infoLog, uniformName, vertexUniform, fragmentUniform, true))
     {
         return false;
     }
 
-    if (!linkValidateFields<sh::Uniform>(infoLog, uniformName, vertexUniform, fragmentUniform))
-    {
-        return false;
-    }
-
     return true;
 }
 
-bool ProgramBinary::linkValidateVariables(InfoLog &infoLog, const std::string &varyingName, const sh::Varying &vertexVarying, const sh::Varying &fragmentVarying)
+bool ProgramBinary::linkValidateVaryings(InfoLog &infoLog, const std::string &varyingName, const sh::Varying &vertexVarying, const sh::Varying &fragmentVarying)
 {
     if (!linkValidateVariablesBase(infoLog, varyingName, vertexVarying, fragmentVarying, false))
     {
@@ -1873,37 +1831,30 @@
         return false;
     }
 
-    if (!linkValidateFields<sh::Varying>(infoLog, varyingName, vertexVarying, fragmentVarying))
-    {
-        return false;
-    }
-
     return true;
 }
 
-bool ProgramBinary::linkValidateVariables(InfoLog &infoLog, const std::string &uniformName, const sh::InterfaceBlockField &vertexUniform, const sh::InterfaceBlockField &fragmentUniform)
+bool ProgramBinary::linkValidateInterfaceBlockFields(InfoLog &infoLog, const std::string &uniformName, const sh::InterfaceBlockField &vertexUniform, const sh::InterfaceBlockField &fragmentUniform)
 {
     if (!linkValidateVariablesBase(infoLog, uniformName, vertexUniform, fragmentUniform, true))
     {
         return false;
     }
 
-    if (vertexUniform.isRowMajorMatrix != fragmentUniform.isRowMajorMatrix)
+    if (vertexUniform.isRowMajorLayout != fragmentUniform.isRowMajorLayout)
     {
         infoLog.append("Matrix packings for %s differ between vertex and fragment shaders", uniformName.c_str());
         return false;
     }
 
-    if (!linkValidateFields<sh::InterfaceBlockField>(infoLog, uniformName, vertexUniform, fragmentUniform))
-    {
-        return false;
-    }
-
     return true;
 }
 
-bool ProgramBinary::linkUniforms(InfoLog &infoLog, const VertexShader &vertexShader, const FragmentShader &fragmentShader)
+bool ProgramBinary::linkUniforms(InfoLog &infoLog, const Shader &vertexShader, const Shader &fragmentShader, const Caps &caps)
 {
+    const rx::ShaderD3D *vertexShaderD3D = rx::ShaderD3D::makeShaderD3D(vertexShader.getImplementation());
+    const rx::ShaderD3D *fragmentShaderD3D = rx::ShaderD3D::makeShaderD3D(fragmentShader.getImplementation());
+
     const std::vector<sh::Uniform> &vertexUniforms = vertexShader.getUniforms();
     const std::vector<sh::Uniform> &fragmentUniforms = fragmentShader.getUniforms();
 
@@ -1925,7 +1876,7 @@
         {
             const sh::Uniform &vertexUniform = *entry->second;
             const std::string &uniformName = "uniform '" + vertexUniform.name + "'";
-            if (!linkValidateVariables(infoLog, uniformName, vertexUniform, fragmentUniform))
+            if (!linkValidateUniforms(infoLog, uniformName, vertexUniform, fragmentUniform))
             {
                 return false;
             }
@@ -1935,35 +1886,43 @@
     for (unsigned int uniformIndex = 0; uniformIndex < vertexUniforms.size(); uniformIndex++)
     {
         const sh::Uniform &uniform = vertexUniforms[uniformIndex];
-        defineUniformBase(GL_VERTEX_SHADER, uniform, vertexShader.getUniformRegister(uniform.name));
+
+        if (uniform.staticUse)
+        {
+            defineUniformBase(GL_VERTEX_SHADER, uniform, vertexShaderD3D->getUniformRegister(uniform.name));
+        }
     }
 
     for (unsigned int uniformIndex = 0; uniformIndex < fragmentUniforms.size(); uniformIndex++)
     {
         const sh::Uniform &uniform = fragmentUniforms[uniformIndex];
-        defineUniformBase(GL_FRAGMENT_SHADER, uniform, fragmentShader.getUniformRegister(uniform.name));
+
+        if (uniform.staticUse)
+        {
+            defineUniformBase(GL_FRAGMENT_SHADER, uniform, fragmentShaderD3D->getUniformRegister(uniform.name));
+        }
     }
 
-    if (!indexUniforms(infoLog))
+    if (!indexUniforms(infoLog, caps))
     {
         return false;
     }
 
-    initializeUniformStorage();
+    mProgram->initializeUniformStorage(mUniforms);
 
     return true;
 }
 
 void ProgramBinary::defineUniformBase(GLenum shader, const sh::Uniform &uniform, unsigned int uniformRegister)
 {
-    ShShaderOutput outputType = Shader::getCompilerOutputType(shader);
+    ShShaderOutput outputType = rx::ShaderD3D::getCompilerOutputType(shader);
     sh::HLSLBlockEncoder encoder(sh::HLSLBlockEncoder::GetStrategyFor(outputType));
     encoder.skipRegisters(uniformRegister);
 
     defineUniform(shader, uniform, uniform.name, &encoder);
 }
 
-void ProgramBinary::defineUniform(GLenum shader, const sh::Uniform &uniform,
+void ProgramBinary::defineUniform(GLenum shader, const sh::ShaderVariable &uniform,
                                   const std::string &fullName, sh::HLSLBlockEncoder *encoder)
 {
     if (uniform.isStruct())
@@ -1976,7 +1935,7 @@
 
             for (size_t fieldIndex = 0; fieldIndex < uniform.fields.size(); fieldIndex++)
             {
-                const sh::Uniform &field = uniform.fields[fieldIndex];
+                const sh::ShaderVariable &field = uniform.fields[fieldIndex];
                 const std::string &fieldFullName = (fullName + elementString + "." + field.name);
 
                 defineUniform(shader, field, fieldFullName, encoder);
@@ -2027,7 +1986,7 @@
     }
 }
 
-bool ProgramBinary::indexSamplerUniform(const LinkedUniform &uniform, InfoLog &infoLog)
+bool ProgramBinary::indexSamplerUniform(const LinkedUniform &uniform, InfoLog &infoLog, const Caps &caps)
 {
     ASSERT(IsSampler(uniform.type));
     ASSERT(uniform.vsRegisterIndex != GL_INVALID_INDEX || uniform.psRegisterIndex != GL_INVALID_INDEX);
@@ -2035,19 +1994,18 @@
     if (uniform.vsRegisterIndex != GL_INVALID_INDEX)
     {
         if (!assignSamplers(uniform.vsRegisterIndex, uniform.type, uniform.arraySize, mSamplersVS,
-                            &mUsedVertexSamplerRange, mRenderer->getMaxVertexTextureImageUnits()))
+                            &mUsedVertexSamplerRange))
         {
             infoLog.append("Vertex shader sampler count exceeds the maximum vertex texture units (%d).",
-                            mRenderer->getMaxVertexTextureImageUnits());
+                           mSamplersVS.size());
             return false;
         }
 
-        unsigned int maxVertexVectors = mRenderer->getReservedVertexUniformVectors() +
-                                        mRenderer->getMaxVertexUniformVectors();
+        unsigned int maxVertexVectors = mProgram->getRenderer()->getReservedVertexUniformVectors() + caps.maxVertexUniformVectors;
         if (uniform.vsRegisterIndex + uniform.registerCount > maxVertexVectors)
         {
             infoLog.append("Vertex shader active uniforms exceed GL_MAX_VERTEX_UNIFORM_VECTORS (%u)",
-                           mRenderer->getMaxVertexUniformVectors());
+                           caps.maxVertexUniformVectors);
             return false;
         }
     }
@@ -2055,19 +2013,18 @@
     if (uniform.psRegisterIndex != GL_INVALID_INDEX)
     {
         if (!assignSamplers(uniform.psRegisterIndex, uniform.type, uniform.arraySize, mSamplersPS,
-                            &mUsedPixelSamplerRange, MAX_TEXTURE_IMAGE_UNITS))
+                            &mUsedPixelSamplerRange))
         {
             infoLog.append("Pixel shader sampler count exceeds MAX_TEXTURE_IMAGE_UNITS (%d).",
-                           MAX_TEXTURE_IMAGE_UNITS);
+                           mSamplersPS.size());
             return false;
         }
 
-        unsigned int maxFragmentVectors = mRenderer->getReservedFragmentUniformVectors() +
-                                          mRenderer->getMaxFragmentUniformVectors();
+        unsigned int maxFragmentVectors = mProgram->getRenderer()->getReservedFragmentUniformVectors() + caps.maxFragmentUniformVectors;
         if (uniform.psRegisterIndex + uniform.registerCount > maxFragmentVectors)
         {
             infoLog.append("Fragment shader active uniforms exceed GL_MAX_FRAGMENT_UNIFORM_VECTORS (%u)",
-                           mRenderer->getMaxFragmentUniformVectors());
+                           caps.maxFragmentUniformVectors);
             return false;
         }
     }
@@ -2075,7 +2032,7 @@
     return true;
 }
 
-bool ProgramBinary::indexUniforms(InfoLog &infoLog)
+bool ProgramBinary::indexUniforms(InfoLog &infoLog, const Caps &caps)
 {
     for (size_t uniformIndex = 0; uniformIndex < mUniforms.size(); uniformIndex++)
     {
@@ -2083,7 +2040,7 @@
 
         if (IsSampler(uniform.type))
         {
-            if (!indexSamplerUniform(uniform, infoLog))
+            if (!indexSamplerUniform(uniform, infoLog, caps))
             {
                 return false;
             }
@@ -2101,20 +2058,20 @@
 bool ProgramBinary::assignSamplers(unsigned int startSamplerIndex,
                                    GLenum samplerType,
                                    unsigned int samplerCount,
-                                   Sampler *outArray,
-                                   GLuint *usedRange,
-                                   unsigned int limit)
+                                   std::vector<Sampler> &outSamplers,
+                                   GLuint *outUsedRange)
 {
     unsigned int samplerIndex = startSamplerIndex;
 
     do
     {
-        if (samplerIndex < limit)
+        if (samplerIndex < outSamplers.size())
         {
-            outArray[samplerIndex].active = true;
-            outArray[samplerIndex].textureType = GetTextureType(samplerType);
-            outArray[samplerIndex].logicalTextureUnit = 0;
-            *usedRange = std::max(samplerIndex + 1, *usedRange);
+            Sampler& sampler = outSamplers[samplerIndex];
+            sampler.active = true;
+            sampler.textureType = GetTextureType(samplerType);
+            sampler.logicalTextureUnit = 0;
+            *outUsedRange = std::max(samplerIndex + 1, *outUsedRange);
         }
         else
         {
@@ -2163,8 +2120,8 @@
             return false;
         }
 
-        std::string uniformName = "interface block '" + vertexInterfaceBlock.name + "' member '" + vertexMember.name + "'";
-        if (!linkValidateVariables(infoLog, uniformName, vertexMember, fragmentMember))
+        std::string memberName = "interface block '" + vertexInterfaceBlock.name + "' member '" + vertexMember.name + "'";
+        if (!linkValidateInterfaceBlockFields(infoLog, memberName, vertexMember, fragmentMember))
         {
             return false;
         }
@@ -2173,8 +2130,7 @@
     return true;
 }
 
-bool ProgramBinary::linkUniformBlocks(InfoLog &infoLog, const VertexShader &vertexShader,
-                                      const FragmentShader &fragmentShader)
+bool ProgramBinary::linkUniformBlocks(InfoLog &infoLog, const Shader &vertexShader, const Shader &fragmentShader, const Caps &caps)
 {
     const std::vector<sh::InterfaceBlock> &vertexInterfaceBlocks = vertexShader.getInterfaceBlocks();
     const std::vector<sh::InterfaceBlock> &fragmentInterfaceBlocks = fragmentShader.getInterfaceBlocks();
@@ -2205,17 +2161,29 @@
 
     for (unsigned int blockIndex = 0; blockIndex < vertexInterfaceBlocks.size(); blockIndex++)
     {
-        if (!defineUniformBlock(infoLog, vertexShader, vertexInterfaceBlocks[blockIndex]))
+        const sh::InterfaceBlock &interfaceBlock = vertexInterfaceBlocks[blockIndex];
+
+        // Note: shared and std140 layouts are always considered active
+        if (interfaceBlock.staticUse || interfaceBlock.layout != sh::BLOCKLAYOUT_PACKED)
         {
-            return false;
+            if (!defineUniformBlock(infoLog, vertexShader, interfaceBlock, caps))
+            {
+                return false;
+            }
         }
     }
 
     for (unsigned int blockIndex = 0; blockIndex < fragmentInterfaceBlocks.size(); blockIndex++)
     {
-        if (!defineUniformBlock(infoLog, fragmentShader, fragmentInterfaceBlocks[blockIndex]))
+        const sh::InterfaceBlock &interfaceBlock = fragmentInterfaceBlocks[blockIndex];
+
+        // Note: shared and std140 layouts are always considered active
+        if (interfaceBlock.staticUse || interfaceBlock.layout != sh::BLOCKLAYOUT_PACKED)
         {
-            return false;
+            if (!defineUniformBlock(infoLog, fragmentShader, interfaceBlock, caps))
+            {
+                return false;
+            }
         }
     }
 
@@ -2225,11 +2193,10 @@
 bool ProgramBinary::gatherTransformFeedbackLinkedVaryings(InfoLog &infoLog, const std::vector<LinkedVarying> &linkedVaryings,
                                                           const std::vector<std::string> &transformFeedbackVaryingNames,
                                                           GLenum transformFeedbackBufferMode,
-                                                          std::vector<LinkedVarying> *outTransformFeedbackLinkedVaryings) const
+                                                          std::vector<LinkedVarying> *outTransformFeedbackLinkedVaryings,
+                                                          const Caps &caps) const
 {
     size_t totalComponents = 0;
-    const size_t maxSeparateComponents = mRenderer->getMaxTransformFeedbackSeparateComponents();
-    const size_t maxInterleavedComponents = mRenderer->getMaxTransformFeedbackInterleavedComponents();
 
     // Gather the linked varyings that are used for transform feedback, they should all exist.
     outTransformFeedbackLinkedVaryings->clear();
@@ -2251,10 +2218,10 @@
 
                 size_t componentCount = linkedVaryings[j].semanticIndexCount * 4;
                 if (transformFeedbackBufferMode == GL_SEPARATE_ATTRIBS &&
-                    componentCount > maxSeparateComponents)
+                    componentCount > caps.maxTransformFeedbackSeparateComponents)
                 {
                     infoLog.append("Transform feedback varying's %s components (%u) exceed the maximum separate components (%u).",
-                                   linkedVaryings[j].name.c_str(), componentCount, maxSeparateComponents);
+                                   linkedVaryings[j].name.c_str(), componentCount, caps.maxTransformFeedbackSeparateComponents);
                     return false;
                 }
 
@@ -2270,39 +2237,45 @@
         ASSERT(found);
     }
 
-    if (transformFeedbackBufferMode == GL_INTERLEAVED_ATTRIBS && totalComponents > maxInterleavedComponents)
+    if (transformFeedbackBufferMode == GL_INTERLEAVED_ATTRIBS && totalComponents > caps.maxTransformFeedbackInterleavedComponents)
     {
         infoLog.append("Transform feedback varying total components (%u) exceed the maximum interleaved components (%u).",
-                       totalComponents, maxInterleavedComponents);
+                       totalComponents, caps.maxTransformFeedbackInterleavedComponents);
         return false;
     }
 
     return true;
 }
 
-void ProgramBinary::defineUniformBlockMembers(const std::vector<sh::InterfaceBlockField> &fields, const std::string &prefix, int blockIndex,
-                                              sh::BlockLayoutEncoder *encoder, std::vector<unsigned int> *blockUniformIndexes)
+template <typename VarT>
+void ProgramBinary::defineUniformBlockMembers(const std::vector<VarT> &fields, const std::string &prefix, int blockIndex,
+                                              sh::BlockLayoutEncoder *encoder, std::vector<unsigned int> *blockUniformIndexes,
+                                              bool inRowMajorLayout)
 {
     for (unsigned int uniformIndex = 0; uniformIndex < fields.size(); uniformIndex++)
     {
-        const sh::InterfaceBlockField &field = fields[uniformIndex];
+        const VarT &field = fields[uniformIndex];
         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) : "");
-                defineUniformBlockMembers(field.fields, uniformElementName, blockIndex, encoder, blockUniformIndexes);
+                defineUniformBlockMembers(field.fields, uniformElementName, blockIndex, encoder, blockUniformIndexes, rowMajorLayout);
 
                 encoder->exitAggregateType();
             }
         }
         else
         {
-            sh::BlockMemberInfo memberInfo = encoder->encodeInterfaceBlockField(field);
+            bool isRowMajorMatrix = (IsMatrixType(field.type) && inRowMajorLayout);
+
+            sh::BlockMemberInfo memberInfo = encoder->encodeType(field.type, field.arraySize, isRowMajorMatrix);
 
             LinkedUniform *newUniform = new LinkedUniform(field.type, field.precision, fieldName, field.arraySize,
                                                           blockIndex, memberInfo);
@@ -2314,8 +2287,10 @@
     }
 }
 
-bool ProgramBinary::defineUniformBlock(InfoLog &infoLog, const Shader &shader, const sh::InterfaceBlock &interfaceBlock)
+bool ProgramBinary::defineUniformBlock(InfoLog &infoLog, const Shader &shader, const sh::InterfaceBlock &interfaceBlock, const Caps &caps)
 {
+    const rx::ShaderD3D* shaderD3D = rx::ShaderD3D::makeShaderD3D(shader.getImplementation());
+
     // create uniform block entries if they do not exist
     if (getUniformBlockIndex(interfaceBlock.name) == GL_INVALID_INDEX)
     {
@@ -2335,7 +2310,7 @@
         }
         ASSERT(encoder);
 
-        defineUniformBlockMembers(interfaceBlock.fields, "", blockIndex, encoder, &blockUniformIndexes);
+        defineUniformBlockMembers(interfaceBlock.fields, "", blockIndex, encoder, &blockUniformIndexes, interfaceBlock.isRowMajorLayout);
 
         size_t dataSize = encoder->getBlockSize();
 
@@ -2357,50 +2332,49 @@
         }
     }
 
-    // Assign registers to the uniform blocks
-    const GLuint blockIndex = getUniformBlockIndex(interfaceBlock.name);
-    const unsigned int elementCount = std::max(1u, interfaceBlock.arraySize);
-    ASSERT(blockIndex != GL_INVALID_INDEX);
-    ASSERT(blockIndex + elementCount <= mUniformBlocks.size());
-
-    unsigned int interfaceBlockRegister = shader.getInterfaceBlockRegister(interfaceBlock.name);
-
-    for (unsigned int uniformBlockElement = 0; uniformBlockElement < elementCount; uniformBlockElement++)
+    if (interfaceBlock.staticUse)
     {
-        UniformBlock *uniformBlock = mUniformBlocks[blockIndex + uniformBlockElement];
-        ASSERT(uniformBlock->name == interfaceBlock.name);
+        // Assign registers to the uniform blocks
+        const GLuint blockIndex = getUniformBlockIndex(interfaceBlock.name);
+        const unsigned int elementCount = std::max(1u, interfaceBlock.arraySize);
+        ASSERT(blockIndex != GL_INVALID_INDEX);
+        ASSERT(blockIndex + elementCount <= mUniformBlocks.size());
 
-        if (!assignUniformBlockRegister(infoLog, uniformBlock, shader.getType(),
-                                        interfaceBlockRegister + uniformBlockElement))
+        unsigned int interfaceBlockRegister = shaderD3D->getInterfaceBlockRegister(interfaceBlock.name);
+
+        for (unsigned int uniformBlockElement = 0; uniformBlockElement < elementCount; uniformBlockElement++)
         {
-            return false;
+            UniformBlock *uniformBlock = mUniformBlocks[blockIndex + uniformBlockElement];
+            ASSERT(uniformBlock->name == interfaceBlock.name);
+
+            if (!assignUniformBlockRegister(infoLog, uniformBlock, shader.getType(),
+                                            interfaceBlockRegister + uniformBlockElement, caps))
+            {
+                return false;
+            }
         }
     }
 
     return true;
 }
 
-bool ProgramBinary::assignUniformBlockRegister(InfoLog &infoLog, UniformBlock *uniformBlock, GLenum shader, unsigned int registerIndex)
+bool ProgramBinary::assignUniformBlockRegister(InfoLog &infoLog, UniformBlock *uniformBlock, GLenum shader, unsigned int registerIndex, const Caps &caps)
 {
     if (shader == GL_VERTEX_SHADER)
     {
         uniformBlock->vsRegisterIndex = registerIndex;
-        unsigned int maximumBlocks = mRenderer->getMaxVertexShaderUniformBuffers();
-
-        if (registerIndex - mRenderer->getReservedVertexUniformBuffers() >= maximumBlocks)
+        if (registerIndex - mProgram->getRenderer()->getReservedVertexUniformBuffers() >= caps.maxVertexUniformBlocks)
         {
-            infoLog.append("Vertex shader uniform block count exceed GL_MAX_VERTEX_UNIFORM_BLOCKS (%u)", maximumBlocks);
+            infoLog.append("Vertex shader uniform block count exceed GL_MAX_VERTEX_UNIFORM_BLOCKS (%u)", caps.maxVertexUniformBlocks);
             return false;
         }
     }
     else if (shader == GL_FRAGMENT_SHADER)
     {
         uniformBlock->psRegisterIndex = registerIndex;
-        unsigned int maximumBlocks = mRenderer->getMaxFragmentShaderUniformBuffers();
-
-        if (registerIndex - mRenderer->getReservedFragmentUniformBuffers() >= maximumBlocks)
+        if (registerIndex - mProgram->getRenderer()->getReservedFragmentUniformBuffers() >= caps.maxFragmentUniformBlocks)
         {
-            infoLog.append("Fragment shader uniform block count exceed GL_MAX_FRAGMENT_UNIFORM_BLOCKS (%u)", maximumBlocks);
+            infoLog.append("Fragment shader uniform block count exceed GL_MAX_FRAGMENT_UNIFORM_BLOCKS (%u)", caps.maxFragmentUniformBlocks);
             return false;
         }
     }
@@ -2670,10 +2644,10 @@
     return maxLength;
 }
 
-void ProgramBinary::validate(InfoLog &infoLog)
+void ProgramBinary::validate(InfoLog &infoLog, const Caps &caps)
 {
     applyUniforms();
-    if (!validateSamplers(&infoLog))
+    if (!validateSamplers(&infoLog, caps))
     {
         mValidated = false;
     }
@@ -2683,20 +2657,14 @@
     }
 }
 
-bool ProgramBinary::validateSamplers(InfoLog *infoLog)
+bool ProgramBinary::validateSamplers(InfoLog *infoLog, const Caps &caps)
 {
     // if any two active samplers in a program are of different types, but refer to the same
     // texture image unit, and this is the current program, then ValidateProgram will fail, and
     // DrawArrays and DrawElements will issue the INVALID_OPERATION error.
     updateSamplerMapping();
 
-    const unsigned int maxCombinedTextureImageUnits = mRenderer->getMaxCombinedTextureImageUnits();
-    TextureType textureUnitType[IMPLEMENTATION_MAX_COMBINED_TEXTURE_IMAGE_UNITS];
-
-    for (unsigned int i = 0; i < IMPLEMENTATION_MAX_COMBINED_TEXTURE_IMAGE_UNITS; ++i)
-    {
-        textureUnitType[i] = TEXTURE_UNKNOWN;
-    }
+    std::vector<GLenum> textureUnitTypes(caps.maxCombinedTextureImageUnits, GL_NONE);
 
     for (unsigned int i = 0; i < mUsedPixelSamplerRange; ++i)
     {
@@ -2704,19 +2672,19 @@
         {
             unsigned int unit = mSamplersPS[i].logicalTextureUnit;
 
-            if (unit >= maxCombinedTextureImageUnits)
+            if (unit >= textureUnitTypes.size())
             {
                 if (infoLog)
                 {
-                    infoLog->append("Sampler uniform (%d) exceeds IMPLEMENTATION_MAX_COMBINED_TEXTURE_IMAGE_UNITS (%d)", unit, maxCombinedTextureImageUnits);
+                    infoLog->append("Sampler uniform (%d) exceeds GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS (%d)", unit, textureUnitTypes.size());
                 }
 
                 return false;
             }
 
-            if (textureUnitType[unit] != TEXTURE_UNKNOWN)
+            if (textureUnitTypes[unit] != GL_NONE)
             {
-                if (mSamplersPS[i].textureType != textureUnitType[unit])
+                if (mSamplersPS[i].textureType != textureUnitTypes[unit])
                 {
                     if (infoLog)
                     {
@@ -2728,7 +2696,7 @@
             }
             else
             {
-                textureUnitType[unit] = mSamplersPS[i].textureType;
+                textureUnitTypes[unit] = mSamplersPS[i].textureType;
             }
         }
     }
@@ -2739,19 +2707,19 @@
         {
             unsigned int unit = mSamplersVS[i].logicalTextureUnit;
 
-            if (unit >= maxCombinedTextureImageUnits)
+            if (unit >= textureUnitTypes.size())
             {
                 if (infoLog)
                 {
-                    infoLog->append("Sampler uniform (%d) exceeds IMPLEMENTATION_MAX_COMBINED_TEXTURE_IMAGE_UNITS (%d)", unit, maxCombinedTextureImageUnits);
+                    infoLog->append("Sampler uniform (%d) exceeds GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS (%d)", unit, textureUnitTypes.size());
                 }
 
                 return false;
             }
 
-            if (textureUnitType[unit] != TEXTURE_UNKNOWN)
+            if (textureUnitTypes[unit] != GL_NONE)
             {
-                if (mSamplersVS[i].textureType != textureUnitType[unit])
+                if (mSamplersVS[i].textureType != textureUnitTypes[unit])
                 {
                     if (infoLog)
                     {
@@ -2763,7 +2731,7 @@
             }
             else
             {
-                textureUnitType[unit] = mSamplersVS[i].textureType;
+                textureUnitTypes[unit] = mSamplersVS[i].textureType;
             }
         }
     }
@@ -2771,7 +2739,7 @@
     return true;
 }
 
-ProgramBinary::Sampler::Sampler() : active(false), logicalTextureUnit(0), textureType(TEXTURE_2D)
+ProgramBinary::Sampler::Sampler() : active(false), logicalTextureUnit(0), textureType(GL_TEXTURE_2D)
 {
 }
 
@@ -2819,42 +2787,9 @@
     }
 }
 
-void ProgramBinary::initializeUniformStorage()
-{
-    // Compute total default block size
-    unsigned int vertexRegisters = 0;
-    unsigned int fragmentRegisters = 0;
-    for (size_t uniformIndex = 0; uniformIndex < mUniforms.size(); uniformIndex++)
-    {
-        const LinkedUniform &uniform = *mUniforms[uniformIndex];
-
-        if (!IsSampler(uniform.type))
-        {
-            if (uniform.isReferencedByVertexShader())
-            {
-                vertexRegisters = std::max(vertexRegisters, uniform.vsRegisterIndex + uniform.registerCount);
-            }
-            if (uniform.isReferencedByFragmentShader())
-            {
-                fragmentRegisters = std::max(fragmentRegisters, uniform.psRegisterIndex + uniform.registerCount);
-            }
-        }
-    }
-
-    mVertexUniformStorage = mRenderer->createUniformStorage(vertexRegisters * 16u);
-    mFragmentUniformStorage = mRenderer->createUniformStorage(fragmentRegisters * 16u);
-}
-
 void ProgramBinary::reset()
 {
-    mVertexHLSL.clear();
-    mVertexWorkarounds = rx::ANGLE_D3D_WORKAROUND_NONE;
     SafeDeleteContainer(mVertexExecutables);
-
-    mPixelHLSL.clear();
-    mPixelWorkarounds = rx::ANGLE_D3D_WORKAROUND_NONE;
-    mUsesFragDepth = false;
-    mPixelShaderKey.clear();
     SafeDeleteContainer(mPixelExecutables);
 
     SafeDelete(mGeometryExecutable);
@@ -2862,14 +2797,9 @@
     mTransformFeedbackBufferMode = GL_NONE;
     mTransformFeedbackLinkedVaryings.clear();
 
-    for (size_t i = 0; i < ArraySize(mSamplersPS); i++)
-    {
-        mSamplersPS[i] = Sampler();
-    }
-    for (size_t i = 0; i < ArraySize(mSamplersVS); i++)
-    {
-        mSamplersVS[i] = Sampler();
-    }
+    mSamplersPS.clear();
+    mSamplersVS.clear();
+
     mUsedVertexSamplerRange = 0;
     mUsedPixelSamplerRange = 0;
     mUsesPointSize = false;
@@ -2880,8 +2810,8 @@
     SafeDeleteContainer(mUniformBlocks);
     mUniformIndex.clear();
     mOutputVariables.clear();
-    SafeDelete(mVertexUniformStorage);
-    SafeDelete(mFragmentUniformStorage);
+
+    mProgram->reset();
 
     mValidated = false;
 }
diff --git a/src/libGLESv2/ProgramBinary.h b/src/libGLESv2/ProgramBinary.h
index f0fc431..738d63f 100644
--- a/src/libGLESv2/ProgramBinary.h
+++ b/src/libGLESv2/ProgramBinary.h
@@ -10,11 +10,6 @@
 #ifndef LIBGLESV2_PROGRAM_BINARY_H_
 #define LIBGLESV2_PROGRAM_BINARY_H_
 
-#include "angle_gl.h"
-
-#include <string>
-#include <vector>
-
 #include "common/RefCountObject.h"
 #include "angletypes.h"
 #include "common/mathutil.h"
@@ -22,25 +17,43 @@
 #include "libGLESv2/Shader.h"
 #include "libGLESv2/Constants.h"
 #include "libGLESv2/renderer/d3d/VertexDataManager.h"
-#include "libGLESv2/DynamicHLSL.h"
+#include "libGLESv2/renderer/d3d/DynamicHLSL.h"
+
+#include "angle_gl.h"
+
+#include <string>
+#include <vector>
+
+// TODO(jmadill): place this in workarounds library
+#define ANGLE_WORKAROUND_ENABLED 1
+#define ANGLE_WORKAROUND_DISABLED 2
+#define ANGLE_MRT_PERF_WORKAROUND ANGLE_WORKAROUND_ENABLED
 
 namespace sh
 {
 class HLSLBlockEncoder;
 }
 
+#include <GLES3/gl3.h>
+#include <GLES2/gl2.h>
+#include <GLES2/gl2ext.h>
+
+#include <string>
+#include <vector>
+
 namespace rx
 {
 class ShaderExecutable;
 class Renderer;
 struct TranslatedAttribute;
 class UniformStorage;
+class ProgramImpl;
 }
 
 namespace gl
 {
-class FragmentShader;
-class VertexShader;
+struct Caps;
+class Shader;
 class InfoLog;
 class AttributeBindings;
 class Buffer;
@@ -82,9 +95,12 @@
 class ProgramBinary : public RefCountObject
 {
   public:
-    explicit ProgramBinary(rx::Renderer *renderer);
+    explicit ProgramBinary(rx::ProgramImpl *impl);
     ~ProgramBinary();
 
+    rx::ProgramImpl *getImplementation() { return mProgram; }
+    const rx::ProgramImpl *getImplementation() const { return mProgram; }
+
     rx::ShaderExecutable *getPixelExecutableForFramebuffer(const Framebuffer *fbo);
     rx::ShaderExecutable *getPixelExecutableForOutputLayout(const std::vector<GLenum> &outputLayout);
     rx::ShaderExecutable *getVertexExecutableForInputLayout(const VertexFormat inputLayout[MAX_VERTEX_ATTRIBS]);
@@ -93,8 +109,8 @@
     GLuint getAttributeLocation(const char *name);
     int getSemanticIndex(int attributeIndex);
 
-    GLint getSamplerMapping(SamplerType type, unsigned int samplerIndex);
-    TextureType getSamplerTextureType(SamplerType type, unsigned int samplerIndex);
+    GLint getSamplerMapping(SamplerType type, unsigned int samplerIndex, const Caps &caps);
+    GLenum getSamplerTextureType(SamplerType type, unsigned int samplerIndex);
     GLint getUsedSamplerRange(SamplerType type);
     bool usesPointSize() const;
     bool usesPointSpriteEmulation() const;
@@ -125,20 +141,20 @@
     void setUniformMatrix3x4fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
     void setUniformMatrix4x3fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
 
-    bool getUniformfv(GLint location, GLsizei *bufSize, GLfloat *params);
-    bool getUniformiv(GLint location, GLsizei *bufSize, GLint *params);
-    bool getUniformuiv(GLint location, GLsizei *bufSize, GLuint *params);
+    void getUniformfv(GLint location, GLfloat *params);
+    void getUniformiv(GLint location, GLint *params);
+    void getUniformuiv(GLint location, GLuint *params);
 
     void dirtyAllUniforms();
     void applyUniforms();
-    bool applyUniformBuffers(const std::vector<Buffer*> boundBuffers);
+    bool applyUniformBuffers(const std::vector<Buffer*> boundBuffers, const Caps &caps);
 
-    bool load(InfoLog &infoLog, const void *binary, GLsizei length);
-    bool save(void* binary, GLsizei bufSize, GLsizei *length);
+    bool load(InfoLog &infoLog, GLenum binaryFormat, const void *binary, GLsizei length);
+    bool save(GLenum *binaryFormat, void *binary, GLsizei bufSize, GLsizei *length);
     GLint getLength();
 
-    bool link(InfoLog &infoLog, const AttributeBindings &attributeBindings, FragmentShader *fragmentShader, VertexShader *vertexShader,
-              const std::vector<std::string>& transformFeedbackVaryings, GLenum transformFeedbackBufferMode);
+    bool link(InfoLog &infoLog, const AttributeBindings &attributeBindings, Shader *fragmentShader, Shader *vertexShader,
+              const std::vector<std::string>& transformFeedbackVaryings, GLenum transformFeedbackBufferMode, const Caps &caps);
     void getAttachedShaders(GLsizei maxCount, GLsizei *count, GLuint *shaders);
 
     void getActiveAttribute(GLuint index, GLsizei bufsize, GLsizei *length, GLint *size, GLenum *type, GLchar *name) const;
@@ -165,8 +181,8 @@
     const LinkedVarying &getTransformFeedbackVarying(size_t idx) const;
     GLenum getTransformFeedbackBufferMode() const;
 
-    void validate(InfoLog &infoLog);
-    bool validateSamplers(InfoLog *infoLog);
+    void validate(InfoLog &infoLog, const Caps &caps);
+    bool validateSamplers(InfoLog *infoLog, const Caps &caps);
     bool isValidated() const;
     void updateSamplerMapping();
 
@@ -177,8 +193,8 @@
     void sortAttributesByLayout(rx::TranslatedAttribute attributes[MAX_VERTEX_ATTRIBS], int sortedSemanticIndices[MAX_VERTEX_ATTRIBS]) const;
 
     const std::vector<LinkedUniform*> &getUniforms() const { return mUniforms; }
-    const rx::UniformStorage &getVertexUniformStorage() const { return *mVertexUniformStorage; }
-    const rx::UniformStorage &getFragmentUniformStorage() const { return *mFragmentUniformStorage; }
+
+    static bool linkVaryings(InfoLog &infoLog, Shader *fragmentShader, Shader *vertexShader);
 
   private:
     DISALLOW_COPY_AND_ASSIGN(ProgramBinary);
@@ -189,40 +205,43 @@
 
         bool active;
         GLint logicalTextureUnit;
-        TextureType textureType;
+        GLenum textureType;
     };
 
     void reset();
 
-    bool linkVaryings(InfoLog &infoLog, FragmentShader *fragmentShader, VertexShader *vertexShader);
-    bool linkAttributes(InfoLog &infoLog, const AttributeBindings &attributeBindings, FragmentShader *fragmentShader, VertexShader *vertexShader);
+    bool linkAttributes(InfoLog &infoLog, const AttributeBindings &attributeBindings, const Shader *vertexShader);
 
-    template <class ShaderVarType>
-    bool linkValidateFields(InfoLog &infoLog, const std::string &varName, const ShaderVarType &vertexVar, const ShaderVarType &fragmentVar);
-    bool linkValidateVariablesBase(InfoLog &infoLog, const std::string &variableName, const sh::ShaderVariable &vertexVariable, const sh::ShaderVariable &fragmentVariable, bool validatePrecision);
+    static bool linkValidateVariablesBase(InfoLog &infoLog,
+                                          const std::string &variableName,
+                                          const sh::ShaderVariable &vertexVariable,
+                                          const sh::ShaderVariable &fragmentVariable,
+                                          bool validatePrecision);
 
-    bool linkValidateVariables(InfoLog &infoLog, const std::string &uniformName, const sh::Uniform &vertexUniform, const sh::Uniform &fragmentUniform);
-    bool linkValidateVariables(InfoLog &infoLog, const std::string &varyingName, const sh::Varying &vertexVarying, const sh::Varying &fragmentVarying);
-    bool linkValidateVariables(InfoLog &infoLog, const std::string &uniformName, const sh::InterfaceBlockField &vertexUniform, const sh::InterfaceBlockField &fragmentUniform);
-    bool linkUniforms(InfoLog &infoLog, const VertexShader &vertexShader, const FragmentShader &fragmentShader);
+    static bool linkValidateUniforms(InfoLog &infoLog, const std::string &uniformName, const sh::Uniform &vertexUniform, const sh::Uniform &fragmentUniform);
+    static bool linkValidateVaryings(InfoLog &infoLog, const std::string &varyingName, const sh::Varying &vertexVarying, const sh::Varying &fragmentVarying);
+    static bool linkValidateInterfaceBlockFields(InfoLog &infoLog, const std::string &uniformName, const sh::InterfaceBlockField &vertexUniform, const sh::InterfaceBlockField &fragmentUniform);
+    bool linkUniforms(InfoLog &infoLog, const Shader &vertexShader, const Shader &fragmentShader, const Caps &caps);
     void defineUniformBase(GLenum shader, const sh::Uniform &uniform, unsigned int uniformRegister);
-    void defineUniform(GLenum shader, const sh::Uniform &uniform, const std::string &fullName, sh::HLSLBlockEncoder *encoder);
-    bool indexSamplerUniform(const LinkedUniform &uniform, InfoLog &infoLog);
-    bool indexUniforms(InfoLog &infoLog);
+    void defineUniform(GLenum shader, const sh::ShaderVariable &uniform, const std::string &fullName, sh::HLSLBlockEncoder *encoder);
+    bool indexSamplerUniform(const LinkedUniform &uniform, InfoLog &infoLog, const Caps &caps);
+    bool indexUniforms(InfoLog &infoLog, const Caps &caps);
     static bool assignSamplers(unsigned int startSamplerIndex, GLenum samplerType, unsigned int samplerCount,
-                               Sampler *outArray, GLuint *usedRange, unsigned int limit);
+                               std::vector<Sampler> &outSamplers, GLuint *outUsedRange);
     bool areMatchingInterfaceBlocks(InfoLog &infoLog, const sh::InterfaceBlock &vertexInterfaceBlock, const sh::InterfaceBlock &fragmentInterfaceBlock);
-    bool linkUniformBlocks(InfoLog &infoLog, const VertexShader &vertexShader, const FragmentShader &fragmentShader);
+    bool linkUniformBlocks(InfoLog &infoLog, const Shader &vertexShader, const Shader &fragmentShader, const Caps &caps);
     bool gatherTransformFeedbackLinkedVaryings(InfoLog &infoLog, const std::vector<LinkedVarying> &linkedVaryings,
                                                const std::vector<std::string> &transformFeedbackVaryingNames,
                                                GLenum transformFeedbackBufferMode,
-                                               std::vector<LinkedVarying> *outTransformFeedbackLinkedVaryings) const;
-    void defineUniformBlockMembers(const std::vector<sh::InterfaceBlockField> &fields, const std::string &prefix, int blockIndex,
-                                   sh::BlockLayoutEncoder *encoder, std::vector<unsigned int> *blockUniformIndexes);
-    bool defineUniformBlock(InfoLog &infoLog, const Shader &shader, const sh::InterfaceBlock &interfaceBlock);
-    bool assignUniformBlockRegister(InfoLog &infoLog, UniformBlock *uniformBlock, GLenum shader, unsigned int registerIndex);
-    void defineOutputVariables(FragmentShader *fragmentShader);
-    void initializeUniformStorage();
+                                               std::vector<LinkedVarying> *outTransformFeedbackLinkedVaryings,
+                                               const Caps &caps) const;
+    template <typename VarT>
+    void defineUniformBlockMembers(const std::vector<VarT> &fields, const std::string &prefix, int blockIndex,
+                                   sh::BlockLayoutEncoder *encoder, std::vector<unsigned int> *blockUniformIndexes,
+                                   bool inRowMajorLayout);
+    bool defineUniformBlock(InfoLog &infoLog, const Shader &shader, const sh::InterfaceBlock &interfaceBlock, const Caps &caps);
+    bool assignUniformBlockRegister(InfoLog &infoLog, UniformBlock *uniformBlock, GLenum shader, unsigned int registerIndex, const Caps &caps);
+    void defineOutputVariables(Shader *fragmentShader);
 
     template <typename T>
     void setUniform(GLint location, GLsizei count, const T* v, GLenum targetUniformType);
@@ -231,7 +250,7 @@
     void setUniformMatrixfv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value, GLenum targetUniformType);
 
     template <typename T>
-    bool getUniformv(GLint location, GLsizei *bufSize, T *params, GLenum uniformType);
+    void getUniformv(GLint location, T *params, GLenum uniformType);
 
     class VertexExecutable
     {
@@ -259,8 +278,7 @@
         PixelExecutable(const std::vector<GLenum> &outputSignature, rx::ShaderExecutable *shaderExecutable);
         ~PixelExecutable();
 
-        // FIXME(geofflang): Work around NVIDIA driver bug by repacking buffers
-        bool matchesSignature(const std::vector<GLenum> &signature) const { return true; /* mOutputSignature == signature; */ }
+        bool matchesSignature(const std::vector<GLenum> &signature) const { return mOutputSignature == signature; }
 
         const std::vector<GLenum> &outputSignature() const { return mOutputSignature; }
         rx::ShaderExecutable *shaderExecutable() const { return mShaderExecutable; }
@@ -270,17 +288,9 @@
         rx::ShaderExecutable *mShaderExecutable;
     };
 
-    rx::Renderer *const mRenderer;
-    DynamicHLSL *mDynamicHLSL;
+    rx::ProgramImpl *mProgram;
 
-    std::string mVertexHLSL;
-    rx::D3DWorkaroundType mVertexWorkarounds;
     std::vector<VertexExecutable *> mVertexExecutables;
-
-    std::string mPixelHLSL;
-    rx::D3DWorkaroundType mPixelWorkarounds;
-    bool mUsesFragDepth;
-    std::vector<PixelShaderOuputVariable> mPixelShaderKey;
     std::vector<PixelExecutable *> mPixelExecutables;
 
     rx::ShaderExecutable *mGeometryExecutable;
@@ -293,8 +303,8 @@
     GLenum mTransformFeedbackBufferMode;
     std::vector<LinkedVarying> mTransformFeedbackLinkedVaryings;
 
-    Sampler mSamplersPS[MAX_TEXTURE_IMAGE_UNITS];
-    Sampler mSamplersVS[IMPLEMENTATION_MAX_VERTEX_TEXTURE_IMAGE_UNITS];
+    std::vector<Sampler> mSamplersPS;
+    std::vector<Sampler> mSamplersVS;
     GLuint mUsedVertexSamplerRange;
     GLuint mUsedPixelSamplerRange;
     bool mUsesPointSize;
@@ -305,8 +315,6 @@
     std::vector<UniformBlock*> mUniformBlocks;
     std::vector<VariableLocation> mUniformIndex;
     std::map<int, VariableLocation> mOutputVariables;
-    rx::UniformStorage *mVertexUniformStorage;
-    rx::UniformStorage *mFragmentUniformStorage;
 
     bool mValidated;
 
diff --git a/src/libGLESv2/Query.cpp b/src/libGLESv2/Query.cpp
index 6546d06..4ee3525 100644
--- a/src/libGLESv2/Query.cpp
+++ b/src/libGLESv2/Query.cpp
@@ -1,4 +1,3 @@
-#include "precompiled.h"
 //
 // Copyright (c) 2012 The ANGLE Project Authors. All rights reserved.
 // Use of this source code is governed by a BSD-style license that can be
@@ -9,39 +8,38 @@
 
 #include "libGLESv2/Query.h"
 #include "libGLESv2/renderer/QueryImpl.h"
-#include "libGLESv2/renderer/Renderer.h"
 
 namespace gl
 {
-
-Query::Query(rx::Renderer *renderer, GLenum type, GLuint id) : RefCountObject(id)
-{ 
-    mQuery = renderer->createQuery(type);
+Query::Query(rx::QueryImpl *impl, GLuint id)
+    : RefCountObject(id),
+      mQuery(impl)
+{
 }
 
 Query::~Query()
 {
-    delete mQuery;
+    SafeDelete(mQuery);
 }
 
-void Query::begin()
+Error Query::begin()
 {
-    mQuery->begin();
+    return mQuery->begin();
 }
 
-void Query::end()
+Error Query::end()
 {
-    mQuery->end();
+    return mQuery->end();
 }
 
-GLuint Query::getResult()
+Error Query::getResult(GLuint *params)
 {
-    return mQuery->getResult();
+    return mQuery->getResult(params);
 }
 
-GLboolean Query::isResultAvailable()
+Error Query::isResultAvailable(GLuint *available)
 {
-    return mQuery->isResultAvailable();
+    return mQuery->isResultAvailable(available);
 }
 
 GLenum Query::getType() const
@@ -49,9 +47,4 @@
     return mQuery->getType();
 }
 
-bool Query::isStarted() const
-{
-    return mQuery->isStarted();
-}
-
 }
diff --git a/src/libGLESv2/Query.h b/src/libGLESv2/Query.h
index a4726a8..a7ec404 100644
--- a/src/libGLESv2/Query.h
+++ b/src/libGLESv2/Query.h
@@ -9,14 +9,14 @@
 #ifndef LIBGLESV2_QUERY_H_
 #define LIBGLESV2_QUERY_H_
 
-#include "angle_gl.h"
-
+#include "libGLESv2/Error.h"
 #include "common/angleutils.h"
 #include "common/RefCountObject.h"
 
+#include "angle_gl.h"
+
 namespace rx
 {
-class Renderer;
 class QueryImpl;
 }
 
@@ -26,17 +26,16 @@
 class Query : public RefCountObject
 {
   public:
-    Query(rx::Renderer *renderer, GLenum type, GLuint id);
+    Query(rx::QueryImpl *impl, GLuint id);
     virtual ~Query();
 
-    void begin();
-    void end();
+    Error begin();
+    Error end();
 
-    GLuint getResult();
-    GLboolean isResultAvailable();
+    Error getResult(GLuint *params);
+    Error isResultAvailable(GLuint *available);
 
     GLenum getType() const;
-    bool isStarted() const;
 
   private:
     DISALLOW_COPY_AND_ASSIGN(Query);
diff --git a/src/libGLESv2/Renderbuffer.cpp b/src/libGLESv2/Renderbuffer.cpp
index 8f9cfb9..9406fce 100644
--- a/src/libGLESv2/Renderbuffer.cpp
+++ b/src/libGLESv2/Renderbuffer.cpp
@@ -1,4 +1,3 @@
-#include "precompiled.h"
 //
 // 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
@@ -10,13 +9,13 @@
 // objects and related functionality. [OpenGL ES 2.0.24] section 4.4.3 page 108.
 
 #include "libGLESv2/Renderbuffer.h"
-#include "libGLESv2/renderer/RenderTarget.h"
-
 #include "libGLESv2/Texture.h"
-#include "libGLESv2/renderer/Renderer.h"
-#include "common/utilities.h"
 #include "libGLESv2/formatutils.h"
 #include "libGLESv2/FramebufferAttachment.h"
+#include "libGLESv2/renderer/Renderer.h"
+#include "libGLESv2/renderer/RenderTarget.h"
+
+#include "common/utilities.h"
 
 namespace gl
 {
@@ -29,6 +28,11 @@
     ASSERT(mStorage);
 }
 
+Renderbuffer::~Renderbuffer()
+{
+    SafeDelete(mStorage);
+}
+
 void Renderbuffer::setStorage(RenderbufferStorage *newStorage)
 {
     ASSERT(newStorage);
@@ -121,11 +125,6 @@
     return NULL;
 }
 
-rx::RenderTarget *RenderbufferStorage::getDepthStencil()
-{
-    return NULL;
-}
-
 GLsizei RenderbufferStorage::getWidth() const
 {
     return mWidth;
@@ -156,7 +155,7 @@
     return mSerial;
 }
 
-unsigned int RenderbufferStorage::issueSerials(GLuint count)
+unsigned int RenderbufferStorage::issueSerials(unsigned int count)
 {
     unsigned int firstSerial = mCurrentSerial;
     mCurrentSerial += count;
@@ -247,7 +246,7 @@
     }
 }
 
-rx::RenderTarget *DepthStencilbuffer::getDepthStencil()
+rx::RenderTarget *DepthStencilbuffer::getRenderTarget()
 {
     return mDepthStencil;
 }
diff --git a/src/libGLESv2/Renderbuffer.h b/src/libGLESv2/Renderbuffer.h
index e2d0c6b..71bcb0e 100644
--- a/src/libGLESv2/Renderbuffer.h
+++ b/src/libGLESv2/Renderbuffer.h
@@ -39,6 +39,7 @@
 {
   public:
     Renderbuffer(GLuint id, RenderbufferStorage *newStorage);
+    virtual ~Renderbuffer();
 
     void setStorage(RenderbufferStorage *newStorage);
     RenderbufferStorage *getStorage();
@@ -70,7 +71,6 @@
     virtual ~RenderbufferStorage() = 0;
 
     virtual rx::RenderTarget *getRenderTarget();
-    virtual rx::RenderTarget *getDepthStencil();
 
     virtual GLsizei getWidth() const;
     virtual GLsizei getHeight() const;
@@ -83,7 +83,7 @@
     virtual bool isTexture() const;
     virtual unsigned int getTextureSerial() const;
 
-    static unsigned int issueSerials(GLuint count);
+    static unsigned int issueSerials(unsigned int count);
 
   protected:
     GLsizei mWidth;
@@ -124,7 +124,7 @@
 
     ~DepthStencilbuffer();
 
-    virtual rx::RenderTarget *getDepthStencil();
+    virtual rx::RenderTarget *getRenderTarget();
 
   protected:
     rx::RenderTarget  *mDepthStencil;
diff --git a/src/libGLESv2/ResourceManager.cpp b/src/libGLESv2/ResourceManager.cpp
index 3606532..9121de1 100644
--- a/src/libGLESv2/ResourceManager.cpp
+++ b/src/libGLESv2/ResourceManager.cpp
@@ -1,4 +1,3 @@
-#include "precompiled.h"
 //
 // 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
@@ -93,13 +92,9 @@
 {
     GLuint handle = mProgramShaderHandleAllocator.allocate();
 
-    if (type == GL_VERTEX_SHADER)
+    if (type == GL_VERTEX_SHADER || type == GL_FRAGMENT_SHADER)
     {
-        mShaderMap[handle] = new VertexShader(this, mRenderer, handle);
-    }
-    else if (type == GL_FRAGMENT_SHADER)
-    {
-        mShaderMap[handle] = new FragmentShader(this, mRenderer, handle);
+        mShaderMap[handle] = new Shader(this, mRenderer->createShader(type), type, handle);
     }
     else UNREACHABLE();
 
@@ -151,7 +146,9 @@
 {
     GLuint handle = mFenceSyncHandleAllocator.allocate();
 
-    mFenceSyncMap[handle] = new FenceSync(mRenderer, handle);
+    FenceSync *fenceSync = new FenceSync(mRenderer, handle);
+    fenceSync->addRef();
+    mFenceSyncMap[handle] = fenceSync;
 
     return handle;
 }
@@ -369,27 +366,27 @@
     }
 }
 
-void ResourceManager::checkTextureAllocation(GLuint texture, TextureType type)
+void ResourceManager::checkTextureAllocation(GLuint texture, GLenum type)
 {
     if (!getTexture(texture) && texture != 0)
     {
         Texture *textureObject;
 
-        if (type == TEXTURE_2D)
+        if (type == GL_TEXTURE_2D)
         {
-            textureObject = new Texture2D(mRenderer->createTexture2D(), texture);
+            textureObject = new Texture2D(mRenderer->createTexture(GL_TEXTURE_2D), texture);
         }
-        else if (type == TEXTURE_CUBE)
+        else if (type == GL_TEXTURE_CUBE_MAP)
         {
-            textureObject = new TextureCubeMap(mRenderer->createTextureCube(), texture);
+            textureObject = new TextureCubeMap(mRenderer->createTexture(GL_TEXTURE_CUBE_MAP), texture);
         }
-        else if (type == TEXTURE_3D)
+        else if (type == GL_TEXTURE_3D)
         {
-            textureObject = new Texture3D(mRenderer->createTexture3D(), texture);
+            textureObject = new Texture3D(mRenderer->createTexture(GL_TEXTURE_3D), texture);
         }
-        else if (type == TEXTURE_2D_ARRAY)
+        else if (type == GL_TEXTURE_2D_ARRAY)
         {
-            textureObject = new Texture2DArray(mRenderer->createTexture2DArray(), texture);
+            textureObject = new Texture2DArray(mRenderer->createTexture(GL_TEXTURE_2D_ARRAY), texture);
         }
         else
         {
diff --git a/src/libGLESv2/ResourceManager.h b/src/libGLESv2/ResourceManager.h
index d646c0d..7d53bd4 100644
--- a/src/libGLESv2/ResourceManager.h
+++ b/src/libGLESv2/ResourceManager.h
@@ -10,14 +10,14 @@
 #ifndef LIBGLESV2_RESOURCEMANAGER_H_
 #define LIBGLESV2_RESOURCEMANAGER_H_
 
-#include "angle_gl.h"
-
-#include <unordered_map>
-
 #include "common/angleutils.h"
 #include "libGLESv2/angletypes.h"
 #include "libGLESv2/HandleAllocator.h"
 
+#include "angle_gl.h"
+
+#include <unordered_map>
+
 namespace rx
 {
 class Renderer;
@@ -65,11 +65,11 @@
     Renderbuffer *getRenderbuffer(GLuint handle);
     Sampler *getSampler(GLuint handle);
     FenceSync *getFenceSync(GLuint handle);
-    
+
     void setRenderbuffer(GLuint handle, Renderbuffer *renderbuffer);
 
     void checkBufferAllocation(unsigned int buffer);
-    void checkTextureAllocation(GLuint texture, TextureType type);
+    void checkTextureAllocation(GLuint texture, GLenum type);
     void checkRenderbufferAllocation(GLuint renderbuffer);
     void checkSamplerAllocation(GLuint sampler);
 
diff --git a/src/libGLESv2/Sampler.cpp b/src/libGLESv2/Sampler.cpp
index ed6e29f..b906e65 100644
--- a/src/libGLESv2/Sampler.cpp
+++ b/src/libGLESv2/Sampler.cpp
@@ -1,4 +1,3 @@
-#include "precompiled.h"
 //
 // 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
diff --git a/src/libGLESv2/Shader.cpp b/src/libGLESv2/Shader.cpp
index 1906657..e3da2b1 100644
--- a/src/libGLESv2/Shader.cpp
+++ b/src/libGLESv2/Shader.cpp
@@ -1,4 +1,3 @@
-#include "precompiled.h"
 //
 // 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
@@ -10,35 +9,30 @@
 // functionality. [OpenGL ES 2.0.24] section 2.10 page 24 and section 3.8 page 84.
 
 #include "libGLESv2/Shader.h"
-
-#include "GLSLANG/ShaderLang.h"
-#include "common/utilities.h"
 #include "libGLESv2/renderer/Renderer.h"
+#include "libGLESv2/renderer/ShaderImpl.h"
 #include "libGLESv2/Constants.h"
 #include "libGLESv2/ResourceManager.h"
 
+#include "common/utilities.h"
+
+#include "GLSLANG/ShaderLang.h"
+
+#include <sstream>
+
 namespace gl
 {
-void *Shader::mFragmentCompiler = NULL;
-void *Shader::mVertexCompiler = NULL;
 
-template <typename VarT>
-const std::vector<VarT> *GetShaderVariables(const std::vector<VarT> *variableList)
+Shader::Shader(ResourceManager *manager, rx::ShaderImpl *impl, GLenum type, GLuint handle)
+    : mShader(impl),
+      mType(type),
+      mHandle(handle),
+      mResourceManager(manager),
+      mRefCount(0),
+      mDeleteStatus(false),
+      mCompiled(false)
 {
-    // TODO: handle staticUse. for now, assume all returned variables are active.
-    ASSERT(variableList);
-    return variableList;
-}
-
-Shader::Shader(ResourceManager *manager, const rx::Renderer *renderer, GLuint handle)
-    : mHandle(handle), mRenderer(renderer), mResourceManager(manager)
-{
-    uncompile();
-    initializeCompiler();
-
-    mRefCount = 0;
-    mDeleteStatus = false;
-    mShaderVersion = 100;
+    ASSERT(impl);
 }
 
 Shader::~Shader()
@@ -64,7 +58,7 @@
 
 int Shader::getInfoLogLength() const
 {
-    return mInfoLog.empty() ? 0 : (mInfoLog.length() + 1);
+    return  mShader->getInfoLog().empty() ? 0 : (mShader->getInfoLog().length() + 1);
 }
 
 void Shader::getInfoLog(GLsizei bufSize, GLsizei *length, char *infoLog) const
@@ -73,8 +67,8 @@
 
     if (bufSize > 0)
     {
-        index = std::min(bufSize - 1, static_cast<GLsizei>(mInfoLog.length()));
-        memcpy(infoLog, mInfoLog.c_str(), index);
+        index = std::min(bufSize - 1, static_cast<GLsizei>(mShader->getInfoLog().length()));
+        memcpy(infoLog, mShader->getInfoLog().c_str(), index);
 
         infoLog[index] = '\0';
     }
@@ -92,10 +86,10 @@
 
 int Shader::getTranslatedSourceLength() const
 {
-    return mHlsl.empty() ? 0 : (mHlsl.length() + 1);
+    return mShader->getTranslatedSource().empty() ? 0 : (mShader->getTranslatedSource().length() + 1);
 }
 
-void Shader::getSourceImpl(const std::string &source, GLsizei bufSize, GLsizei *length, char *buffer) const
+void Shader::getSourceImpl(const std::string &source, GLsizei bufSize, GLsizei *length, char *buffer)
 {
     int index = 0;
 
@@ -120,44 +114,12 @@
 
 void Shader::getTranslatedSource(GLsizei bufSize, GLsizei *length, char *buffer) const
 {
-    getSourceImpl(mHlsl, bufSize, length, buffer);
+    getSourceImpl(mShader->getTranslatedSource(), bufSize, length, buffer);
 }
 
-unsigned int Shader::getUniformRegister(const std::string &uniformName) const
+void Shader::compile()
 {
-    ASSERT(mUniformRegisterMap.count(uniformName) > 0);
-    return mUniformRegisterMap.find(uniformName)->second;
-}
-
-unsigned int Shader::getInterfaceBlockRegister(const std::string &blockName) const
-{
-    ASSERT(mInterfaceBlockRegisterMap.count(blockName) > 0);
-    return mInterfaceBlockRegisterMap.find(blockName)->second;
-}
-
-const std::vector<sh::Uniform> &Shader::getUniforms() const
-{
-    return mActiveUniforms;
-}
-
-const std::vector<sh::InterfaceBlock> &Shader::getInterfaceBlocks() const
-{
-    return mActiveInterfaceBlocks;
-}
-
-std::vector<PackedVarying> &Shader::getVaryings()
-{
-    return mVaryings;
-}
-
-bool Shader::isCompiled() const
-{
-    return !mHlsl.empty();
-}
-
-const std::string &Shader::getHLSL() const
-{
-    return mHlsl;
+    mCompiled = mShader->compile(mSource);
 }
 
 void Shader::addRef()
@@ -190,404 +152,54 @@
     mDeleteStatus = true;
 }
 
-// Perform a one-time initialization of the shader compiler (or after being destructed by releaseCompiler)
-void Shader::initializeCompiler()
+const std::vector<gl::PackedVarying> &Shader::getVaryings() const
 {
-    if (!mFragmentCompiler)
-    {
-        int result = ShInitialize();
-
-        if (result)
-        {
-            ShShaderOutput hlslVersion = (mRenderer->getMajorShaderModel() >= 4) ? SH_HLSL11_OUTPUT : SH_HLSL9_OUTPUT;
-
-            ShBuiltInResources resources;
-            ShInitBuiltInResources(&resources);
-
-            // TODO(geofflang): use context's caps
-            const gl::Caps &caps = mRenderer->getRendererCaps();
-            const gl::Extensions &extensions = mRenderer->getRendererExtensions();
-
-            resources.MaxVertexAttribs = MAX_VERTEX_ATTRIBS;
-            resources.MaxVertexUniformVectors = mRenderer->getMaxVertexUniformVectors();
-            resources.MaxVaryingVectors = mRenderer->getMaxVaryingVectors();
-            resources.MaxVertexTextureImageUnits = mRenderer->getMaxVertexTextureImageUnits();
-            resources.MaxCombinedTextureImageUnits = mRenderer->getMaxCombinedTextureImageUnits();
-            resources.MaxTextureImageUnits = MAX_TEXTURE_IMAGE_UNITS;
-            resources.MaxFragmentUniformVectors = mRenderer->getMaxFragmentUniformVectors();
-            resources.MaxDrawBuffers = caps.maxDrawBuffers;
-            resources.OES_standard_derivatives = extensions.standardDerivatives;
-            resources.EXT_draw_buffers = extensions.drawBuffers;
-            resources.EXT_shader_texture_lod = 1;
-            // resources.OES_EGL_image_external = mRenderer->getShareHandleSupport() ? 1 : 0; // TODO: commented out until the extension is actually supported.
-            resources.FragmentPrecisionHigh = 1;   // Shader Model 2+ always supports FP24 (s16e7) which corresponds to highp
-            resources.EXT_frag_depth = 1; // Shader Model 2+ always supports explicit depth output
-            // GLSL ES 3.0 constants
-            resources.MaxVertexOutputVectors = mRenderer->getMaxVaryingVectors();
-            resources.MaxFragmentInputVectors = mRenderer->getMaxVaryingVectors();
-            resources.MinProgramTexelOffset = -8;   // D3D10_COMMONSHADER_TEXEL_OFFSET_MAX_NEGATIVE
-            resources.MaxProgramTexelOffset = 7;    // D3D10_COMMONSHADER_TEXEL_OFFSET_MAX_POSITIVE
-
-            mFragmentCompiler = ShConstructCompiler(GL_FRAGMENT_SHADER, SH_GLES2_SPEC, hlslVersion, &resources);
-            mVertexCompiler = ShConstructCompiler(GL_VERTEX_SHADER, SH_GLES2_SPEC, hlslVersion, &resources);
-        }
-    }
+    return mShader->getVaryings();
 }
 
-void Shader::releaseCompiler()
+const std::vector<sh::Uniform> &Shader::getUniforms() const
 {
-    ShDestruct(mFragmentCompiler);
-    ShDestruct(mVertexCompiler);
-
-    mFragmentCompiler = NULL;
-    mVertexCompiler = NULL;
-
-    ShFinalize();
+    return mShader->getUniforms();
 }
 
-void Shader::parseVaryings(void *compiler)
+const std::vector<sh::InterfaceBlock> &Shader::getInterfaceBlocks() const
 {
-    if (!mHlsl.empty())
-    {
-        const std::vector<sh::Varying> *activeVaryings = ShGetVaryings(compiler);
-        ASSERT(activeVaryings);
-
-        for (size_t varyingIndex = 0; varyingIndex < activeVaryings->size(); varyingIndex++)
-        {
-            mVaryings.push_back(PackedVarying((*activeVaryings)[varyingIndex]));
-        }
-
-        mUsesMultipleRenderTargets = mHlsl.find("GL_USES_MRT")          != std::string::npos;
-        mUsesFragColor             = mHlsl.find("GL_USES_FRAG_COLOR")   != std::string::npos;
-        mUsesFragData              = mHlsl.find("GL_USES_FRAG_DATA")    != std::string::npos;
-        mUsesFragCoord             = mHlsl.find("GL_USES_FRAG_COORD")   != std::string::npos;
-        mUsesFrontFacing           = mHlsl.find("GL_USES_FRONT_FACING") != std::string::npos;
-        mUsesPointSize             = mHlsl.find("GL_USES_POINT_SIZE")   != std::string::npos;
-        mUsesPointCoord            = mHlsl.find("GL_USES_POINT_COORD")  != std::string::npos;
-        mUsesDepthRange            = mHlsl.find("GL_USES_DEPTH_RANGE")  != std::string::npos;
-        mUsesFragDepth             = mHlsl.find("GL_USES_FRAG_DEPTH")   != std::string::npos;
-        mUsesDiscardRewriting      = mHlsl.find("ANGLE_USES_DISCARD_REWRITING") != std::string::npos;
-        mUsesNestedBreak           = mHlsl.find("ANGLE_USES_NESTED_BREAK") != std::string::npos;
-    }
+    return mShader->getInterfaceBlocks();
 }
 
-void Shader::resetVaryingsRegisterAssignment()
+const std::vector<sh::Attribute> &Shader::getActiveAttributes() const
 {
-    for (unsigned int varyingIndex = 0; varyingIndex < mVaryings.size(); varyingIndex++)
-    {
-        mVaryings[varyingIndex].resetRegisterAssignment();
-    }
+    return mShader->getActiveAttributes();
 }
 
-// initialize/clean up previous state
-void Shader::uncompile()
+const std::vector<sh::Attribute> &Shader::getActiveOutputVariables() const
 {
-    // set by compileToHLSL
-    mHlsl.clear();
-    mInfoLog.clear();
-
-    // set by parseVaryings
-    mVaryings.clear();
-
-    mUsesMultipleRenderTargets = false;
-    mUsesFragColor = false;
-    mUsesFragData = false;
-    mUsesFragCoord = false;
-    mUsesFrontFacing = false;
-    mUsesPointSize = false;
-    mUsesPointCoord = false;
-    mUsesDepthRange = false;
-    mUsesFragDepth = false;
-    mShaderVersion = 100;
-    mUsesDiscardRewriting = false;
-    mUsesNestedBreak = false;
-
-    mActiveUniforms.clear();
-    mActiveInterfaceBlocks.clear();
+    return mShader->getActiveOutputVariables();
 }
 
-void Shader::compileToHLSL(void *compiler)
+std::vector<gl::PackedVarying> &Shader::getVaryings()
 {
-    // ensure the compiler is loaded
-    initializeCompiler();
-
-    int compileOptions = SH_OBJECT_CODE;
-    std::string sourcePath;
-    if (perfActive())
-    {
-        sourcePath = getTempPath();
-        writeFile(sourcePath.c_str(), mSource.c_str(), mSource.length());
-        compileOptions |= SH_LINE_DIRECTIVES;
-    }
-
-    int result;
-    if (sourcePath.empty())
-    {
-        const char* sourceStrings[] =
-        {
-            mSource.c_str(),
-        };
-
-        result = ShCompile(compiler, sourceStrings, ArraySize(sourceStrings), compileOptions);
-    }
-    else
-    {
-        const char* sourceStrings[] =
-        {
-            sourcePath.c_str(),
-            mSource.c_str(),
-        };
-
-        result = ShCompile(compiler, sourceStrings, ArraySize(sourceStrings), compileOptions | SH_SOURCE_PATH);
-    }
-
-    size_t shaderVersion = 100;
-    ShGetInfo(compiler, SH_SHADER_VERSION, &shaderVersion);
-
-    mShaderVersion = static_cast<int>(shaderVersion);
-
-    if (shaderVersion == 300 && mRenderer->getCurrentClientVersion() < 3)
-    {
-        mInfoLog = "GLSL ES 3.00 is not supported by OpenGL ES 2.0 contexts";
-        TRACE("\n%s", mInfoLog.c_str());
-    }
-    else if (result)
-    {
-        size_t objCodeLen = 0;
-        ShGetInfo(compiler, SH_OBJECT_CODE_LENGTH, &objCodeLen);
-
-        char* outputHLSL = new char[objCodeLen];
-        ShGetObjectCode(compiler, outputHLSL);
-
-#ifdef _DEBUG
-        std::ostringstream hlslStream;
-        hlslStream << "// GLSL\n";
-        hlslStream << "//\n";
-
-        size_t curPos = 0;
-        while (curPos != std::string::npos)
-        {
-            size_t nextLine = mSource.find("\n", curPos);
-            size_t len = (nextLine == std::string::npos) ? std::string::npos : (nextLine - curPos + 1);
-
-            hlslStream << "// " << mSource.substr(curPos, len);
-
-            curPos = (nextLine == std::string::npos) ? std::string::npos : (nextLine + 1);
-        }
-        hlslStream << "\n\n";
-        hlslStream << outputHLSL;
-        mHlsl = hlslStream.str();
-#else
-        mHlsl = outputHLSL;
-#endif
-
-        SafeDeleteArray(outputHLSL);
-
-        mActiveUniforms = *GetShaderVariables(ShGetUniforms(compiler));
-
-        for (size_t uniformIndex = 0; uniformIndex < mActiveUniforms.size(); uniformIndex++)
-        {
-            const sh::Uniform &uniform = mActiveUniforms[uniformIndex];
-
-            unsigned int index = -1;
-            bool result = ShGetUniformRegister(compiler, uniform.name.c_str(), &index);
-            UNUSED_ASSERTION_VARIABLE(result);
-            ASSERT(result);
-
-            mUniformRegisterMap[uniform.name] = index;
-        }
-
-        mActiveInterfaceBlocks = *GetShaderVariables(ShGetInterfaceBlocks(compiler));
-
-        for (size_t blockIndex = 0; blockIndex < mActiveInterfaceBlocks.size(); blockIndex++)
-        {
-            const sh::InterfaceBlock &interfaceBlock = mActiveInterfaceBlocks[blockIndex];
-
-            unsigned int index = -1;
-            bool result = ShGetInterfaceBlockRegister(compiler, interfaceBlock.name.c_str(), &index);
-            UNUSED_ASSERTION_VARIABLE(result);
-            ASSERT(result);
-
-            mInterfaceBlockRegisterMap[interfaceBlock.name] = index;
-        }
-    }
-    else
-    {
-        size_t infoLogLen = 0;
-        ShGetInfo(compiler, SH_INFO_LOG_LENGTH, &infoLogLen);
-
-        char* infoLog = new char[infoLogLen];
-        ShGetInfoLog(compiler, infoLog);
-        mInfoLog = infoLog;
-
-        TRACE("\n%s", mInfoLog.c_str());
-    }
+    return mShader->getVaryings();
 }
 
-rx::D3DWorkaroundType Shader::getD3DWorkarounds() const
+std::vector<sh::Uniform> &Shader::getUniforms()
 {
-    if (mUsesDiscardRewriting)
-    {
-        // ANGLE issue 486:
-        // Work-around a D3D9 compiler bug that presents itself when using conditional discard, by disabling optimization
-        return rx::ANGLE_D3D_WORKAROUND_SKIP_OPTIMIZATION;
-    }
-
-    if (mUsesNestedBreak)
-    {
-        // ANGLE issue 603:
-        // Work-around a D3D9 compiler bug that presents itself when using break in a nested loop, by maximizing optimization
-        // We want to keep the use of ANGLE_D3D_WORKAROUND_MAX_OPTIMIZATION minimal to prevent hangs, so usesDiscard takes precedence
-        return rx::ANGLE_D3D_WORKAROUND_MAX_OPTIMIZATION;
-    }
-
-    return rx::ANGLE_D3D_WORKAROUND_NONE;
+    return mShader->getUniforms();
 }
 
-// true if varying x has a higher priority in packing than y
-bool Shader::compareVarying(const PackedVarying &x, const PackedVarying &y)
+std::vector<sh::InterfaceBlock> &Shader::getInterfaceBlocks()
 {
-    if (x.type == y.type)
-    {
-        return x.arraySize > y.arraySize;
-    }
-
-    // Special case for handling structs: we sort these to the end of the list
-    if (x.type == GL_STRUCT_ANGLEX)
-    {
-        return false;
-    }
-
-    if (y.type == GL_STRUCT_ANGLEX)
-    {
-        return true;
-    }
-
-    return gl::VariableSortOrder(x.type) <= gl::VariableSortOrder(y.type);
+    return mShader->getInterfaceBlocks();
 }
 
-int Shader::getShaderVersion() const
+std::vector<sh::Attribute> &Shader::getActiveAttributes()
 {
-    return mShaderVersion;
+    return mShader->getActiveAttributes();
 }
 
-VertexShader::VertexShader(ResourceManager *manager, const rx::Renderer *renderer, GLuint handle)
-    : Shader(manager, renderer, handle)
+std::vector<sh::Attribute> &Shader::getActiveOutputVariables()
 {
-}
-
-VertexShader::~VertexShader()
-{
-}
-
-GLenum VertexShader::getType() const
-{
-    return GL_VERTEX_SHADER;
-}
-
-void VertexShader::uncompile()
-{
-    Shader::uncompile();
-
-    // set by ParseAttributes
-    mActiveAttributes.clear();
-}
-
-void VertexShader::compile()
-{
-    uncompile();
-
-    compileToHLSL(mVertexCompiler);
-    parseAttributes();
-    parseVaryings(mVertexCompiler);
-}
-
-int VertexShader::getSemanticIndex(const std::string &attributeName)
-{
-    if (!attributeName.empty())
-    {
-        int semanticIndex = 0;
-        for (unsigned int attributeIndex = 0; attributeIndex < mActiveAttributes.size(); attributeIndex++)
-        {
-            const sh::ShaderVariable &attribute = mActiveAttributes[attributeIndex];
-
-            if (attribute.name == attributeName)
-            {
-                return semanticIndex;
-            }
-
-            semanticIndex += VariableRegisterCount(attribute.type);
-        }
-    }
-
-    return -1;
-}
-
-void VertexShader::parseAttributes()
-{
-    const std::string &hlsl = getHLSL();
-    if (!hlsl.empty())
-    {
-        mActiveAttributes = *GetShaderVariables(ShGetAttributes(mVertexCompiler));
-    }
-}
-
-FragmentShader::FragmentShader(ResourceManager *manager, const rx::Renderer *renderer, GLuint handle)
-    : Shader(manager, renderer, handle)
-{
-}
-
-FragmentShader::~FragmentShader()
-{
-}
-
-GLenum FragmentShader::getType() const
-{
-    return GL_FRAGMENT_SHADER;
-}
-
-void FragmentShader::compile()
-{
-    uncompile();
-
-    compileToHLSL(mFragmentCompiler);
-    parseVaryings(mFragmentCompiler);
-    std::sort(mVaryings.begin(), mVaryings.end(), compareVarying);
-
-    const std::string &hlsl = getHLSL();
-    if (!hlsl.empty())
-    {
-        mActiveOutputVariables = *GetShaderVariables(ShGetOutputVariables(mFragmentCompiler));
-    }
-}
-
-void FragmentShader::uncompile()
-{
-    Shader::uncompile();
-
-    mActiveOutputVariables.clear();
-}
-
-const std::vector<sh::Attribute> &FragmentShader::getOutputVariables() const
-{
-    return mActiveOutputVariables;
-}
-
-ShShaderOutput Shader::getCompilerOutputType(GLenum shader)
-{
-    void *compiler = NULL;
-
-    switch (shader)
-    {
-      case GL_VERTEX_SHADER:   compiler = mVertexCompiler;   break;
-      case GL_FRAGMENT_SHADER: compiler = mFragmentCompiler; break;
-      default: UNREACHABLE();  return SH_HLSL9_OUTPUT;
-    }
-
-    size_t outputType = 0;
-    ShGetInfo(compiler, SH_OUTPUT_TYPE, &outputType);
-
-    return static_cast<ShShaderOutput>(outputType);
+    return mShader->getActiveOutputVariables();
 }
 
 }
diff --git a/src/libGLESv2/Shader.h b/src/libGLESv2/Shader.h
index c322520..7ba3bd1 100644
--- a/src/libGLESv2/Shader.h
+++ b/src/libGLESv2/Shader.h
@@ -25,7 +25,7 @@
 
 namespace rx
 {
-class Renderer;
+class ShaderImpl;
 }
 
 namespace gl
@@ -35,13 +35,16 @@
 struct PackedVarying : public sh::Varying
 {
     unsigned int registerIndex; // Assigned during link
+    unsigned int columnIndex; // Assigned during link, defaults to 0
 
     PackedVarying(const sh::Varying &varying)
       : sh::Varying(varying),
-        registerIndex(GL_INVALID_INDEX)
+        registerIndex(GL_INVALID_INDEX),
+        columnIndex(0)
     {}
 
     bool registerAssigned() const { return registerIndex != GL_INVALID_INDEX; }
+    bool isBuiltIn() const { return name.compare(0, 3, "gl_") == 0; }
 
     void resetRegisterAssignment()
     {
@@ -51,16 +54,17 @@
 
 class Shader
 {
-    friend class DynamicHLSL;
-
   public:
-    Shader(ResourceManager *manager, const rx::Renderer *renderer, GLuint handle);
+    Shader(ResourceManager *manager, rx::ShaderImpl *impl, GLenum type, GLuint handle);
 
     virtual ~Shader();
 
-    virtual GLenum getType() const = 0;
+    GLenum getType() const { return mType; }
     GLuint getHandle() const;
 
+    rx::ShaderImpl *getImplementation() { return mShader; }
+    const rx::ShaderImpl *getImplementation() const { return mShader; }
+
     void deleteSource();
     void setSource(GLsizei count, const char *const *string, const GLint *length);
     int getInfoLogLength() const;
@@ -69,122 +73,44 @@
     void getSource(GLsizei bufSize, GLsizei *length, char *buffer) const;
     int getTranslatedSourceLength() const;
     void getTranslatedSource(GLsizei bufSize, GLsizei *length, char *buffer) const;
-    const std::vector<sh::Uniform> &getUniforms() const;
-    const std::vector<sh::InterfaceBlock> &getInterfaceBlocks() const;
-    std::vector<PackedVarying> &getVaryings();
 
-    virtual void compile() = 0;
-    virtual void uncompile();
-    bool isCompiled() const;
-    const std::string &getHLSL() const;
+    void compile();
+    bool isCompiled() const { return mCompiled; }
 
     void addRef();
     void release();
     unsigned int getRefCount() const;
     bool isFlaggedForDeletion() const;
     void flagForDeletion();
-    int getShaderVersion() const;
-    void resetVaryingsRegisterAssignment();
 
-    static void releaseCompiler();
-    static ShShaderOutput getCompilerOutputType(GLenum shader);
-    unsigned int getUniformRegister(const std::string &uniformName) const;
-    unsigned int getInterfaceBlockRegister(const std::string &blockName) const;
+    const std::vector<gl::PackedVarying> &getVaryings() const;
+    const std::vector<sh::Uniform> &getUniforms() const;
+    const std::vector<sh::InterfaceBlock> &getInterfaceBlocks() const;
+    const std::vector<sh::Attribute> &getActiveAttributes() const;
+    const std::vector<sh::Attribute> &getActiveOutputVariables() const;
 
-    bool usesDepthRange() const { return mUsesDepthRange; }
-    bool usesPointSize() const { return mUsesPointSize; }
-    rx::D3DWorkaroundType getD3DWorkarounds() const;
-
-  protected:
-    void parseVaryings(void *compiler);
-
-    void compileToHLSL(void *compiler);
-
-    void getSourceImpl(const std::string &source, GLsizei bufSize, GLsizei *length, char *buffer) const;
-
-    static bool compareVarying(const PackedVarying &x, const PackedVarying &y);
-
-    const rx::Renderer *const mRenderer;
-
-    std::vector<PackedVarying> mVaryings;
-
-    bool mUsesMultipleRenderTargets;
-    bool mUsesFragColor;
-    bool mUsesFragData;
-    bool mUsesFragCoord;
-    bool mUsesFrontFacing;
-    bool mUsesPointSize;
-    bool mUsesPointCoord;
-    bool mUsesDepthRange;
-    bool mUsesFragDepth;
-    int mShaderVersion;
-    bool mUsesDiscardRewriting;
-    bool mUsesNestedBreak;
-
-    static void *mFragmentCompiler;
-    static void *mVertexCompiler;
+    std::vector<gl::PackedVarying> &getVaryings();
+    std::vector<sh::Uniform> &getUniforms();
+    std::vector<sh::InterfaceBlock> &getInterfaceBlocks();
+    std::vector<sh::Attribute> &getActiveAttributes();
+    std::vector<sh::Attribute> &getActiveOutputVariables();
 
   private:
     DISALLOW_COPY_AND_ASSIGN(Shader);
 
-    void initializeCompiler();
+    static void getSourceImpl(const std::string &source, GLsizei bufSize, GLsizei *length, char *buffer);
 
+    rx::ShaderImpl *mShader;
     const GLuint mHandle;
+    const GLenum mType;
+    std::string mSource;
     unsigned int mRefCount;     // Number of program objects this shader is attached to
     bool mDeleteStatus;         // Flag to indicate that the shader can be deleted when no longer in use
-
-    std::string mSource;
-    std::string mHlsl;
-    std::string mInfoLog;
-    std::vector<sh::Uniform> mActiveUniforms;
-    std::vector<sh::InterfaceBlock> mActiveInterfaceBlocks;
-    std::map<std::string, unsigned int> mUniformRegisterMap;
-    std::map<std::string, unsigned int> mInterfaceBlockRegisterMap;
+    bool mCompiled;             // Indicates if this shader has been successfully compiled
 
     ResourceManager *mResourceManager;
 };
 
-class VertexShader : public Shader
-{
-    friend class DynamicHLSL;
-
-  public:
-    VertexShader(ResourceManager *manager, const rx::Renderer *renderer, GLuint handle);
-
-    ~VertexShader();
-
-    virtual GLenum getType() const;
-    virtual void compile();
-    virtual void uncompile();
-    int getSemanticIndex(const std::string &attributeName);
-
-    const std::vector<sh::Attribute> &activeAttributes() const { return mActiveAttributes; }
-
-  private:
-    DISALLOW_COPY_AND_ASSIGN(VertexShader);
-
-    void parseAttributes();
-
-    std::vector<sh::Attribute> mActiveAttributes;
-};
-
-class FragmentShader : public Shader
-{
-  public:
-    FragmentShader(ResourceManager *manager,const rx::Renderer *renderer, GLuint handle);
-
-    ~FragmentShader();
-
-    virtual GLenum getType() const;
-    virtual void compile();
-    virtual void uncompile();
-    const std::vector<sh::Attribute> &getOutputVariables() const;
-
-  private:
-    DISALLOW_COPY_AND_ASSIGN(FragmentShader);
-
-    std::vector<sh::Attribute> mActiveOutputVariables;
-};
 }
 
 #endif   // LIBGLESV2_SHADER_H_
diff --git a/src/libGLESv2/State.cpp b/src/libGLESv2/State.cpp
index 07e198c..3c03b90 100644
--- a/src/libGLESv2/State.cpp
+++ b/src/libGLESv2/State.cpp
@@ -1,4 +1,3 @@
-#include "precompiled.h"
 //
 // 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
@@ -10,6 +9,7 @@
 #include "libGLESv2/State.h"
 
 #include "libGLESv2/Context.h"
+#include "libGLESv2/Caps.h"
 #include "libGLESv2/VertexArray.h"
 #include "libGLESv2/Query.h"
 #include "libGLESv2/Framebuffer.h"
@@ -19,8 +19,18 @@
 
 namespace gl
 {
+
 State::State()
 {
+}
+
+State::~State()
+{
+    reset();
+}
+
+void State::initialize(const Caps& caps, GLuint clientVersion)
+{
     mContext = NULL;
 
     setClearColor(0.0f, 0.0f, 0.0f, 0.0f);
@@ -66,7 +76,7 @@
     mDepthStencil.stencilMask = -1;
     mDepthStencil.stencilWritemask = -1;
     mDepthStencil.stencilBackFunc = GL_ALWAYS;
-    mDepthStencil.stencilBackMask = - 1;
+    mDepthStencil.stencilBackMask = -1;
     mDepthStencil.stencilBackWritemask = -1;
     mDepthStencil.stencilFail = GL_KEEP;
     mDepthStencil.stencilPassDepthFail = GL_KEEP;
@@ -98,18 +108,24 @@
     mBlend.colorMaskBlue = true;
     mBlend.colorMaskAlpha = true;
 
+    mActiveSampler = 0;
+
     const GLfloat defaultFloatValues[] = { 0.0f, 0.0f, 0.0f, 1.0f };
     for (int attribIndex = 0; attribIndex < MAX_VERTEX_ATTRIBS; attribIndex++)
     {
         mVertexAttribCurrentValues[attribIndex].setFloatValues(defaultFloatValues);
     }
 
-    for (unsigned int textureUnit = 0; textureUnit < ArraySize(mSamplers); textureUnit++)
+    mSamplerTextures[GL_TEXTURE_2D].resize(caps.maxCombinedTextureImageUnits);
+    mSamplerTextures[GL_TEXTURE_CUBE_MAP].resize(caps.maxCombinedTextureImageUnits);
+    if (clientVersion >= 3)
     {
-        mSamplers[textureUnit].set(NULL);
+        // TODO: These could also be enabled via extension
+        mSamplerTextures[GL_TEXTURE_2D_ARRAY].resize(caps.maxCombinedTextureImageUnits);
+        mSamplerTextures[GL_TEXTURE_3D].resize(caps.maxCombinedTextureImageUnits);
     }
 
-    mActiveSampler = 0;
+    mSamplers.resize(caps.maxCombinedTextureImageUnits);
 
     mActiveQueries[GL_ANY_SAMPLES_PASSED].set(NULL);
     mActiveQueries[GL_ANY_SAMPLES_PASSED_CONSERVATIVE].set(NULL);
@@ -122,15 +138,20 @@
     mDrawFramebuffer = NULL;
 }
 
-State::~State()
+void State::reset()
 {
-    for (int type = 0; type < TEXTURE_TYPE_COUNT; type++)
+    for (TextureBindingMap::iterator bindingVec = mSamplerTextures.begin(); bindingVec != mSamplerTextures.end(); bindingVec++)
     {
-        for (int sampler = 0; sampler < IMPLEMENTATION_MAX_COMBINED_TEXTURE_IMAGE_UNITS; sampler++)
+        TextureBindingVector &textureVector = bindingVec->second;
+        for (size_t textureIdx = 0; textureIdx < textureVector.size(); textureIdx++)
         {
-            mSamplerTexture[type][sampler].set(NULL);
+            textureVector[textureIdx].set(NULL);
         }
     }
+    for (size_t samplerIdx = 0; samplerIdx < mSamplers.size(); samplerIdx++)
+    {
+        mSamplers[samplerIdx].set(NULL);
+    }
 
     const GLfloat defaultFloatValues[] = { 0.0f, 0.0f, 0.0f, 1.0f };
     for (int attribIndex = 0; attribIndex < MAX_VERTEX_ATTRIBS; attribIndex++)
@@ -245,15 +266,8 @@
     {
         if (framebufferObject->getStencilbuffer() != NULL)
         {
-            rx::RenderTarget *depthStencil = framebufferObject->getStencilbuffer()->getDepthStencil();
-            if (!depthStencil)
-            {
-                ERR("Depth stencil pointer unexpectedly null.");
-                ClearParameters nullClearParam = { 0 };
-                return nullClearParam;
-            }
-
-            if (GetInternalFormatInfo(depthStencil->getActualFormat()).stencilBits > 0)
+            GLenum stencilActualFormat = framebufferObject->getStencilbuffer()->getActualFormat();
+            if (GetInternalFormatInfo(stencilActualFormat).stencilBits > 0)
             {
                 clearParams.clearStencil = true;
             }
@@ -591,26 +605,26 @@
     return mActiveSampler;
 }
 
-void State::setSamplerTexture(TextureType type, Texture *texture)
+void State::setSamplerTexture(GLenum type, Texture *texture)
 {
-    mSamplerTexture[type][mActiveSampler].set(texture);
+    mSamplerTextures[type][mActiveSampler].set(texture);
 }
 
-Texture *State::getSamplerTexture(unsigned int sampler, TextureType type) const
+Texture *State::getSamplerTexture(unsigned int sampler, GLenum type) const
 {
-    GLuint texid = mSamplerTexture[type][sampler].id();
+    const BindingPointer<Texture>& binding = mSamplerTextures.at(type)[sampler];
 
-    if (texid == 0)   // Special case: 0 refers to default textures held by Context
+    if (binding.id() == 0)   // Special case: 0 refers to default textures held by Context
     {
         return NULL;
     }
 
-    return mSamplerTexture[type][sampler].get();
+    return binding.get();
 }
 
-GLuint State::getSamplerTextureId(unsigned int sampler, TextureType type) const
+GLuint State::getSamplerTextureId(unsigned int sampler, GLenum type) const
 {
-    return mSamplerTexture[type][sampler].id();
+    return mSamplerTextures.at(type)[sampler].id();
 }
 
 void State::detachTexture(GLuint texture)
@@ -624,13 +638,15 @@
     // If a texture object is deleted, it is as if all texture units which are bound to that texture object are
     // rebound to texture object zero
 
-    for (int type = 0; type < TEXTURE_TYPE_COUNT; type++)
+    for (TextureBindingMap::iterator bindingVec = mSamplerTextures.begin(); bindingVec != mSamplerTextures.end(); bindingVec++)
     {
-        for (int sampler = 0; sampler < IMPLEMENTATION_MAX_COMBINED_TEXTURE_IMAGE_UNITS; sampler++)
+        TextureBindingVector &textureVector = bindingVec->second;
+        for (size_t textureIdx = 0; textureIdx < textureVector.size(); textureIdx++)
         {
-            if (mSamplerTexture[type][sampler].id() == texture)
+            BindingPointer<Texture> &binding = textureVector[textureIdx];
+            if (binding.id() == texture)
             {
-                mSamplerTexture[type][sampler].set(NULL);
+                binding.set(NULL);
             }
         }
     }
@@ -658,7 +674,7 @@
 
 GLuint State::getSamplerId(GLuint textureUnit) const
 {
-    ASSERT(textureUnit < ArraySize(mSamplers));
+    ASSERT(textureUnit < mSamplers.size());
     return mSamplers[textureUnit].id();
 }
 
@@ -673,11 +689,12 @@
     // If a sampler object that is currently bound to one or more texture units is
     // deleted, it is as though BindSampler is called once for each texture unit to
     // which the sampler is bound, with unit set to the texture unit and sampler set to zero.
-    for (unsigned int textureUnit = 0; textureUnit < ArraySize(mSamplers); textureUnit++)
+    for (size_t textureUnit = 0; textureUnit < mSamplers.size(); textureUnit++)
     {
-        if (mSamplers[textureUnit].id() == sampler)
+        BindingPointer<Sampler> &samplerBinding = mSamplers[textureUnit];
+        if (samplerBinding.id() == sampler)
         {
-            mSamplers[textureUnit].set(NULL);
+            samplerBinding.set(NULL);
         }
     }
 }
@@ -1315,20 +1332,20 @@
         }
         break;
       case GL_TEXTURE_BINDING_2D:
-        ASSERT(mActiveSampler < mContext->getMaximumCombinedTextureImageUnits());
-        *params = mSamplerTexture[TEXTURE_2D][mActiveSampler].id();
+        ASSERT(mActiveSampler < mContext->getCaps().maxCombinedTextureImageUnits);
+        *params = mSamplerTextures.at(GL_TEXTURE_2D)[mActiveSampler].id();
         break;
       case GL_TEXTURE_BINDING_CUBE_MAP:
-        ASSERT(mActiveSampler < mContext->getMaximumCombinedTextureImageUnits());
-        *params = mSamplerTexture[TEXTURE_CUBE][mActiveSampler].id();
+        ASSERT(mActiveSampler < mContext->getCaps().maxCombinedTextureImageUnits);
+        *params = mSamplerTextures.at(GL_TEXTURE_CUBE_MAP)[mActiveSampler].id();
         break;
       case GL_TEXTURE_BINDING_3D:
-        ASSERT(mActiveSampler < mContext->getMaximumCombinedTextureImageUnits());
-        *params = mSamplerTexture[TEXTURE_3D][mActiveSampler].id();
+        ASSERT(mActiveSampler <mContext->getCaps().maxCombinedTextureImageUnits);
+        *params = mSamplerTextures.at(GL_TEXTURE_3D)[mActiveSampler].id();
         break;
       case GL_TEXTURE_BINDING_2D_ARRAY:
-        ASSERT(mActiveSampler < mContext->getMaximumCombinedTextureImageUnits());
-        *params = mSamplerTexture[TEXTURE_2D_ARRAY][mActiveSampler].id();
+        ASSERT(mActiveSampler < mContext->getCaps().maxCombinedTextureImageUnits);
+        *params = mSamplerTextures.at(GL_TEXTURE_2D_ARRAY)[mActiveSampler].id();
         break;
       case GL_UNIFORM_BUFFER_BINDING:
         *params = mGenericUniformBuffer.id();
diff --git a/src/libGLESv2/State.h b/src/libGLESv2/State.h
index d3b3edc..5f04331 100644
--- a/src/libGLESv2/State.h
+++ b/src/libGLESv2/State.h
@@ -24,6 +24,7 @@
 class Query;
 class VertexArray;
 class Context;
+struct Caps;
 
 class State
 {
@@ -31,6 +32,9 @@
     State();
     ~State();
 
+    void initialize(const Caps& caps, GLuint clientVersion);
+    void reset();
+
     void setContext(Context *context) { mContext = context; }
 
     // State chunk getters
@@ -126,9 +130,9 @@
     // Texture binding & active texture unit manipulation
     void setActiveSampler(unsigned int active);
     unsigned int getActiveSampler() const;
-    void setSamplerTexture(TextureType type, Texture *texture);
-    Texture *getSamplerTexture(unsigned int sampler, TextureType type) const;
-    GLuint getSamplerTextureId(unsigned int sampler, TextureType type) const;
+    void setSamplerTexture(GLenum type, Texture *texture);
+    Texture *getSamplerTexture(unsigned int sampler, GLenum type) const;
+    GLuint getSamplerTextureId(unsigned int sampler, GLenum type) const;
     void detachTexture(GLuint texture);
 
     // Sampler object binding manipulation
@@ -272,7 +276,6 @@
     float mNearZ;
     float mFarZ;
 
-    unsigned int mActiveSampler;   // Active texture unit selector - GL_TEXTURE0
     BindingPointer<Buffer> mArrayBuffer;
     Framebuffer *mReadFramebuffer;
     Framebuffer *mDrawFramebuffer;
@@ -283,8 +286,15 @@
     VertexAttribCurrentValueData mVertexAttribCurrentValues[MAX_VERTEX_ATTRIBS]; // From glVertexAttrib
     VertexArray *mVertexArray;
 
-    BindingPointer<Texture> mSamplerTexture[TEXTURE_TYPE_COUNT][IMPLEMENTATION_MAX_COMBINED_TEXTURE_IMAGE_UNITS];
-    BindingPointer<Sampler> mSamplers[IMPLEMENTATION_MAX_COMBINED_TEXTURE_IMAGE_UNITS];
+    // 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;
+
+    typedef std::vector< BindingPointer<Sampler> > SamplerBindingVector;
+    SamplerBindingVector mSamplers;
 
     typedef std::map< GLenum, BindingPointer<Query> > ActiveQueryMap;
     ActiveQueryMap mActiveQueries;
diff --git a/src/libGLESv2/Texture.cpp b/src/libGLESv2/Texture.cpp
index 87e0304..3ec492d 100644
--- a/src/libGLESv2/Texture.cpp
+++ b/src/libGLESv2/Texture.cpp
@@ -1,4 +1,3 @@
-#include "precompiled.h"
 //
 // 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
@@ -10,22 +9,47 @@
 // functionality. [OpenGL ES 2.0.24] section 3.7 page 63.
 
 #include "libGLESv2/Texture.h"
-
 #include "libGLESv2/main.h"
-#include "common/mathutil.h"
-#include "common/utilities.h"
+#include "libGLESv2/Context.h"
 #include "libGLESv2/formatutils.h"
+#include "libGLESv2/ImageIndex.h"
 #include "libGLESv2/Renderbuffer.h"
 #include "libGLESv2/renderer/Image.h"
 #include "libGLESv2/renderer/d3d/TextureStorage.h"
+
 #include "libEGL/Surface.h"
-#include "libGLESv2/renderer/RenderTarget.h"
+
+#include "common/mathutil.h"
+#include "common/utilities.h"
 
 namespace gl
 {
 
-Texture::Texture(GLuint id, GLenum target)
+bool IsMipmapFiltered(const gl::SamplerState &samplerState)
+{
+    switch (samplerState.minFilter)
+    {
+      case GL_NEAREST:
+      case GL_LINEAR:
+        return false;
+      case GL_NEAREST_MIPMAP_NEAREST:
+      case GL_LINEAR_MIPMAP_NEAREST:
+      case GL_NEAREST_MIPMAP_LINEAR:
+      case GL_LINEAR_MIPMAP_LINEAR:
+        return true;
+      default: UNREACHABLE();
+        return false;
+    }
+}
+
+bool IsPointSampled(const gl::SamplerState &samplerState)
+{
+    return (samplerState.magFilter == GL_NEAREST && (samplerState.minFilter == GL_NEAREST || samplerState.minFilter == GL_NEAREST_MIPMAP_NEAREST));
+}
+
+Texture::Texture(rx::TextureImpl *impl, GLuint id, GLenum target)
     : RefCountObject(id),
+      mTexture(impl),
       mUsage(GL_NONE),
       mImmutable(false),
       mTarget(target)
@@ -34,6 +58,7 @@
 
 Texture::~Texture()
 {
+    SafeDelete(mTexture);
 }
 
 GLenum Texture::getTarget() const
@@ -52,7 +77,7 @@
     *sampler = mSamplerState;
 
     // Offset the effective base level by the texture storage's top level
-    rx::TextureStorageInterface *texture = getNativeTexture();
+    rx::TextureStorage *texture = getNativeTexture();
     int topLevel = texture ? texture->getTopLevel() : 0;
     sampler->baseLevel = topLevel + mSamplerState.baseLevel;
 }
@@ -89,13 +114,31 @@
     return (baseImage ? baseImage->getInternalFormat() : GL_NONE);
 }
 
-// Tests for texture sampling completeness
-bool Texture::isSamplerComplete(const SamplerState &samplerState) const
+GLsizei Texture::getWidth(const ImageIndex &index) const
 {
-    return getImplementation()->isSamplerComplete(samplerState);
+    rx::Image *image = mTexture->getImage(index);
+    return image->getWidth();
 }
 
-rx::TextureStorageInterface *Texture::getNativeTexture()
+GLsizei Texture::getHeight(const ImageIndex &index) const
+{
+    rx::Image *image = mTexture->getImage(index);
+    return image->getHeight();
+}
+
+GLenum Texture::getInternalFormat(const ImageIndex &index) const
+{
+    rx::Image *image = mTexture->getImage(index);
+    return image->getInternalFormat();
+}
+
+GLenum Texture::getActualFormat(const ImageIndex &index) const
+{
+    rx::Image *image = mTexture->getImage(index);
+    return image->getActualFormat();
+}
+
+rx::TextureStorage *Texture::getNativeTexture()
 {
     return getImplementation()->getNativeTexture();
 }
@@ -112,7 +155,7 @@
 
 unsigned int Texture::getTextureSerial()
 {
-    rx::TextureStorageInterface *texture = getNativeTexture();
+    rx::TextureStorage *texture = getNativeTexture();
     return texture ? texture->getTextureSerial() : 0;
 }
 
@@ -123,7 +166,7 @@
 
 int Texture::immutableLevelCount()
 {
-    return (mImmutable ? getNativeTexture()->getStorageInstance()->getLevelCount() : 0);
+    return (mImmutable ? getNativeTexture()->getLevelCount() : 0);
 }
 
 int Texture::mipLevels() const
@@ -136,17 +179,14 @@
     return (getImplementation()->getLayerCount(0) > 0 ? getImplementation()->getImage(0, 0) : NULL);
 }
 
-Texture2D::Texture2D(rx::Texture2DImpl *impl, GLuint id)
-    : Texture(id, GL_TEXTURE_2D),
-      mTexture(impl)
+Texture2D::Texture2D(rx::TextureImpl *impl, GLuint id)
+    : Texture(impl, id, GL_TEXTURE_2D)
 {
     mSurface = NULL;
 }
 
 Texture2D::~Texture2D()
 {
-    SafeDelete(mTexture);
-
     if (mSurface)
     {
         mSurface->setBoundTexture(NULL);
@@ -245,6 +285,70 @@
     mTexture->storage(GL_TEXTURE_2D, levels, internalformat, width, height, 1);
 }
 
+// Tests for 2D texture sampling completeness. [OpenGL ES 2.0.24] section 3.8.2 page 85.
+bool Texture2D::isSamplerComplete(const SamplerState &samplerState, const TextureCapsMap &textureCaps, const Extensions &extensions, int clientVersion) const
+{
+    GLsizei width = getBaseLevelWidth();
+    GLsizei height = getBaseLevelHeight();
+
+    if (width <= 0 || height <= 0)
+    {
+        return false;
+    }
+
+    if (!textureCaps.get(getInternalFormat(0)).filterable && !IsPointSampled(samplerState))
+    {
+        return false;
+    }
+
+    bool npotSupport = extensions.textureNPOT;
+
+    if (!npotSupport)
+    {
+        if ((samplerState.wrapS != GL_CLAMP_TO_EDGE && !gl::isPow2(width)) ||
+            (samplerState.wrapT != GL_CLAMP_TO_EDGE && !gl::isPow2(height)))
+        {
+            return false;
+        }
+    }
+
+    if (IsMipmapFiltered(samplerState))
+    {
+        if (!npotSupport)
+        {
+            if (!gl::isPow2(width) || !gl::isPow2(height))
+            {
+                return false;
+            }
+        }
+
+        if (!isMipmapComplete())
+        {
+            return false;
+        }
+    }
+
+    // OpenGLES 3.0.2 spec section 3.8.13 states that a texture is not mipmap complete if:
+    // The internalformat specified for the texture arrays is a sized internal depth or
+    // depth and stencil format (see table 3.13), the value of TEXTURE_COMPARE_-
+    // MODE is NONE, and either the magnification filter is not NEAREST or the mini-
+    // fication filter is neither NEAREST nor NEAREST_MIPMAP_NEAREST.
+    const gl::InternalFormat &formatInfo = gl::GetInternalFormatInfo(getInternalFormat(0));
+    if (formatInfo.depthBits > 0 && clientVersion > 2)
+    {
+        if (samplerState.compareMode == GL_NONE)
+        {
+            if ((samplerState.minFilter != GL_NEAREST && samplerState.minFilter != GL_NEAREST_MIPMAP_NEAREST) ||
+                samplerState.magFilter != GL_NEAREST)
+            {
+                return false;
+            }
+        }
+    }
+
+    return true;
+}
+
 bool Texture2D::isCompressed(GLint level) const
 {
     return GetInternalFormatInfo(getInternalFormat(level)).compressed;
@@ -262,30 +366,73 @@
     mTexture->generateMipmaps();
 }
 
-unsigned int Texture2D::getRenderTargetSerial(GLint level)
+// Tests for 2D texture (mipmap) completeness. [OpenGL ES 2.0.24] section 3.7.10 page 81.
+bool Texture2D::isMipmapComplete() const
 {
-    return mTexture->getRenderTargetSerial(level, 0);
+    int levelCount = mipLevels();
+
+    for (int level = 0; level < levelCount; level++)
+    {
+        if (!isLevelComplete(level))
+        {
+            return false;
+        }
+    }
+
+    return true;
 }
 
-rx::RenderTarget *Texture2D::getRenderTarget(GLint level)
+bool Texture2D::isLevelComplete(int level) const
 {
-    return mTexture->getRenderTarget(level, 0);
+    if (isImmutable())
+    {
+        return true;
+    }
+
+    const rx::Image *baseImage = getBaseLevelImage();
+
+    GLsizei width = baseImage->getWidth();
+    GLsizei height = baseImage->getHeight();
+
+    if (width <= 0 || height <= 0)
+    {
+        return false;
+    }
+
+    // The base image level is complete if the width and height are positive
+    if (level == 0)
+    {
+        return true;
+    }
+
+    ASSERT(level >= 1 && level < IMPLEMENTATION_MAX_TEXTURE_LEVELS && mTexture->getImage(level, 0) != NULL);
+    rx::Image *image = mTexture->getImage(level, 0);
+
+    if (image->getInternalFormat() != baseImage->getInternalFormat())
+    {
+        return false;
+    }
+
+    if (image->getWidth() != std::max(1, width >> level))
+    {
+        return false;
+    }
+
+    if (image->getHeight() != std::max(1, height >> level))
+    {
+        return false;
+    }
+
+    return true;
 }
 
-rx::RenderTarget *Texture2D::getDepthStencil(GLint level)
-{
-    return mTexture->getDepthStencil(level, 0);
-}
-
-TextureCubeMap::TextureCubeMap(rx::TextureCubeImpl *impl, GLuint id)
-    : Texture(id, GL_TEXTURE_CUBE_MAP),
-      mTexture(impl)
+TextureCubeMap::TextureCubeMap(rx::TextureImpl *impl, GLuint id)
+    : Texture(impl, id, GL_TEXTURE_CUBE_MAP)
 {
 }
 
 TextureCubeMap::~TextureCubeMap()
 {
-    SafeDelete(mTexture);
 }
 
 GLsizei TextureCubeMap::getWidth(GLenum target, GLint level) const
@@ -368,7 +515,28 @@
 // Tests for cube texture completeness. [OpenGL ES 2.0.24] section 3.7.10 page 81.
 bool TextureCubeMap::isCubeComplete() const
 {
-    return mTexture->isCubeComplete();
+    int    baseWidth  = getBaseLevelWidth();
+    int    baseHeight = getBaseLevelHeight();
+    GLenum baseFormat = getBaseLevelInternalFormat();
+
+    if (baseWidth <= 0 || baseWidth != baseHeight)
+    {
+        return false;
+    }
+
+    for (int faceIndex = 1; faceIndex < 6; faceIndex++)
+    {
+        const rx::Image *faceBaseImage = mTexture->getImage(0, faceIndex);
+
+        if (faceBaseImage->getWidth()          != baseWidth  ||
+            faceBaseImage->getHeight()         != baseHeight ||
+            faceBaseImage->getInternalFormat() != baseFormat )
+        {
+            return false;
+        }
+    }
+
+    return true;
 }
 
 bool TextureCubeMap::isCompressed(GLenum target, GLint level) const
@@ -393,9 +561,42 @@
     mTexture->storage(GL_TEXTURE_CUBE_MAP, levels, internalformat, size, size, 1);
 }
 
-unsigned int TextureCubeMap::getRenderTargetSerial(GLenum target, GLint level)
+// Tests for texture sampling completeness
+bool TextureCubeMap::isSamplerComplete(const SamplerState &samplerState, const TextureCapsMap &textureCaps, const Extensions &extensions, int clientVersion) const
 {
-    return mTexture->getRenderTargetSerial(level, targetToLayerIndex(target));
+    int size = getBaseLevelWidth();
+
+    bool mipmapping = IsMipmapFiltered(samplerState);
+
+    if (!textureCaps.get(getInternalFormat(GL_TEXTURE_CUBE_MAP_POSITIVE_X, 0)).filterable && !IsPointSampled(samplerState))
+    {
+        return false;
+    }
+
+    if (!gl::isPow2(size) && !extensions.textureNPOT)
+    {
+        if (samplerState.wrapS != GL_CLAMP_TO_EDGE || samplerState.wrapT != GL_CLAMP_TO_EDGE || mipmapping)
+        {
+            return false;
+        }
+    }
+
+    if (!mipmapping)
+    {
+        if (!isCubeComplete())
+        {
+            return false;
+        }
+    }
+    else
+    {
+        if (!isMipmapComplete())   // Also tests for isCubeComplete()
+        {
+            return false;
+        }
+    }
+
+    return true;
 }
 
 int TextureCubeMap::targetToLayerIndex(GLenum target)
@@ -420,25 +621,82 @@
     return GL_TEXTURE_CUBE_MAP_POSITIVE_X + layer;
 }
 
-rx::RenderTarget *TextureCubeMap::getRenderTarget(GLenum target, GLint level)
+bool TextureCubeMap::isMipmapComplete() const
 {
-    return mTexture->getRenderTarget(level, targetToLayerIndex(target));
+    if (isImmutable())
+    {
+        return true;
+    }
+
+    if (!isCubeComplete())
+    {
+        return false;
+    }
+
+    int levelCount = mipLevels();
+
+    for (int face = 0; face < 6; face++)
+    {
+        for (int level = 1; level < levelCount; level++)
+        {
+            if (!isFaceLevelComplete(face, level))
+            {
+                return false;
+            }
+        }
+    }
+
+    return true;
 }
 
-rx::RenderTarget *TextureCubeMap::getDepthStencil(GLenum target, GLint level)
+bool TextureCubeMap::isFaceLevelComplete(int faceIndex, int level) const
 {
-    return mTexture->getDepthStencil(level, targetToLayerIndex(target));
+    ASSERT(level >= 0 && faceIndex < 6 && level < IMPLEMENTATION_MAX_TEXTURE_LEVELS && mTexture->getImage(level, faceIndex) != NULL);
+
+    if (isImmutable())
+    {
+        return true;
+    }
+
+    int baseSize = getBaseLevelWidth();
+
+    if (baseSize <= 0)
+    {
+        return false;
+    }
+
+    // "isCubeComplete" checks for base level completeness and we must call that
+    // to determine if any face at level 0 is complete. We omit that check here
+    // to avoid re-checking cube-completeness for every face at level 0.
+    if (level == 0)
+    {
+        return true;
+    }
+
+    // Check that non-zero levels are consistent with the base level.
+    const rx::Image *faceLevelImage = mTexture->getImage(level, faceIndex);
+
+    if (faceLevelImage->getInternalFormat() != getBaseLevelInternalFormat())
+    {
+        return false;
+    }
+
+    if (faceLevelImage->getWidth() != std::max(1, baseSize >> level))
+    {
+        return false;
+    }
+
+    return true;
 }
 
-Texture3D::Texture3D(rx::Texture3DImpl *impl, GLuint id)
-    : Texture(id, GL_TEXTURE_3D),
-      mTexture(impl)
+
+Texture3D::Texture3D(rx::TextureImpl *impl, GLuint id)
+    : Texture(impl, id, GL_TEXTURE_3D)
 {
 }
 
 Texture3D::~Texture3D()
 {
-    SafeDelete(mTexture);
 }
 
 GLsizei Texture3D::getWidth(GLint level) const
@@ -503,31 +761,100 @@
     mTexture->storage(GL_TEXTURE_3D, levels, internalformat, width, height, depth);
 }
 
-unsigned int Texture3D::getRenderTargetSerial(GLint level, GLint layer)
+bool Texture3D::isSamplerComplete(const SamplerState &samplerState, const TextureCapsMap &textureCaps, const Extensions &extensions, int clientVersion) const
 {
-    return mTexture->getRenderTargetSerial(level, layer);
+    GLsizei width = getBaseLevelWidth();
+    GLsizei height = getBaseLevelHeight();
+    GLsizei depth = getBaseLevelDepth();
+
+    if (width <= 0 || height <= 0 || depth <= 0)
+    {
+        return false;
+    }
+
+    if (!textureCaps.get(getInternalFormat(0)).filterable && !IsPointSampled(samplerState))
+    {
+        return false;
+    }
+
+    if (IsMipmapFiltered(samplerState) && !isMipmapComplete())
+    {
+        return false;
+    }
+
+    return true;
 }
 
-
-rx::RenderTarget *Texture3D::getRenderTarget(GLint level, GLint layer)
+bool Texture3D::isMipmapComplete() const
 {
-    return mTexture->getRenderTarget(level, layer);
+    int levelCount = mipLevels();
+
+    for (int level = 0; level < levelCount; level++)
+    {
+        if (!isLevelComplete(level))
+        {
+            return false;
+        }
+    }
+
+    return true;
 }
 
-rx::RenderTarget *Texture3D::getDepthStencil(GLint level, GLint layer)
+bool Texture3D::isLevelComplete(int level) const
 {
-    return mTexture->getDepthStencil(level, layer);
+    ASSERT(level >= 0 && level < IMPLEMENTATION_MAX_TEXTURE_LEVELS && mTexture->getImage(level, 0) != NULL);
+
+    if (isImmutable())
+    {
+        return true;
+    }
+
+    GLsizei width = getBaseLevelWidth();
+    GLsizei height = getBaseLevelHeight();
+    GLsizei depth = getBaseLevelDepth();
+
+    if (width <= 0 || height <= 0 || depth <= 0)
+    {
+        return false;
+    }
+
+    if (level == 0)
+    {
+        return true;
+    }
+
+    rx::Image *levelImage = mTexture->getImage(level, 0);
+
+    if (levelImage->getInternalFormat() != getBaseLevelInternalFormat())
+    {
+        return false;
+    }
+
+    if (levelImage->getWidth() != std::max(1, width >> level))
+    {
+        return false;
+    }
+
+    if (levelImage->getHeight() != std::max(1, height >> level))
+    {
+        return false;
+    }
+
+    if (levelImage->getDepth() != std::max(1, depth >> level))
+    {
+        return false;
+    }
+
+    return true;
 }
 
-Texture2DArray::Texture2DArray(rx::Texture2DArrayImpl *impl, GLuint id)
-    : Texture(id, GL_TEXTURE_2D_ARRAY),
-      mTexture(impl)
+Texture2DArray::Texture2DArray(rx::TextureImpl *impl, GLuint id)
+    : Texture(impl, id, GL_TEXTURE_2D_ARRAY)
 {
 }
 
 Texture2DArray::~Texture2DArray()
 {
-    SafeDelete(mTexture);
 }
 
 GLsizei Texture2DArray::getWidth(GLint level) const
@@ -592,19 +919,89 @@
     mTexture->storage(GL_TEXTURE_2D_ARRAY, levels, internalformat, width, height, depth);
 }
 
-unsigned int Texture2DArray::getRenderTargetSerial(GLint level, GLint layer)
+bool Texture2DArray::isSamplerComplete(const SamplerState &samplerState, const TextureCapsMap &textureCaps, const Extensions &extensions, int clientVersion) const
 {
-    return mTexture->getRenderTargetSerial(level, layer);
+    GLsizei width = getBaseLevelWidth();
+    GLsizei height = getBaseLevelHeight();
+    GLsizei depth = getLayers(0);
+
+    if (width <= 0 || height <= 0 || depth <= 0)
+    {
+        return false;
+    }
+
+    if (!textureCaps.get(getBaseLevelInternalFormat()).filterable && !IsPointSampled(samplerState))
+    {
+        return false;
+    }
+
+    if (IsMipmapFiltered(samplerState) && !isMipmapComplete())
+    {
+        return false;
+    }
+
+    return true;
 }
 
-rx::RenderTarget *Texture2DArray::getRenderTarget(GLint level, GLint layer)
+bool Texture2DArray::isMipmapComplete() const
 {
-    return mTexture->getRenderTarget(level, layer);
+    int levelCount = mipLevels();
+
+    for (int level = 1; level < levelCount; level++)
+    {
+        if (!isLevelComplete(level))
+        {
+            return false;
+        }
+    }
+
+    return true;
 }
 
-rx::RenderTarget *Texture2DArray::getDepthStencil(GLint level, GLint layer)
+bool Texture2DArray::isLevelComplete(int level) const
 {
-    return mTexture->getDepthStencil(level, layer);
+    ASSERT(level >= 0 && level < IMPLEMENTATION_MAX_TEXTURE_LEVELS);
+
+    if (isImmutable())
+    {
+        return true;
+    }
+
+    GLsizei width = getBaseLevelWidth();
+    GLsizei height = getBaseLevelHeight();
+    GLsizei layers = getLayers(0);
+
+    if (width <= 0 || height <= 0 || layers <= 0)
+    {
+        return false;
+    }
+
+    if (level == 0)
+    {
+        return true;
+    }
+
+    if (getInternalFormat(level) != getInternalFormat(0))
+    {
+        return false;
+    }
+
+    if (getWidth(level) != std::max(1, width >> level))
+    {
+        return false;
+    }
+
+    if (getHeight(level) != std::max(1, height >> level))
+    {
+        return false;
+    }
+
+    if (getLayers(level) != layers)
+    {
+        return false;
+    }
+
+    return true;
 }
 
 }
diff --git a/src/libGLESv2/Texture.h b/src/libGLESv2/Texture.h
index eaa4cf7..ca5686f 100644
--- a/src/libGLESv2/Texture.h
+++ b/src/libGLESv2/Texture.h
@@ -11,15 +11,16 @@
 #ifndef LIBGLESV2_TEXTURE_H_
 #define LIBGLESV2_TEXTURE_H_
 
-#include <vector>
-
-#include "angle_gl.h"
-
 #include "common/debug.h"
 #include "common/RefCountObject.h"
 #include "libGLESv2/angletypes.h"
 #include "libGLESv2/constants.h"
 #include "libGLESv2/renderer/TextureImpl.h"
+#include "libGLESv2/Caps.h"
+
+#include "angle_gl.h"
+
+#include <vector>
 
 namespace egl
 {
@@ -29,7 +30,6 @@
 namespace rx
 {
 class TextureStorageInterface;
-class RenderTarget;
 class Image;
 }
 
@@ -37,11 +37,14 @@
 {
 class Framebuffer;
 class FramebufferAttachment;
+struct ImageIndex;
+
+bool IsMipmapFiltered(const gl::SamplerState &samplerState);
 
 class Texture : public RefCountObject
 {
   public:
-    Texture(GLuint id, GLenum target);
+    Texture(rx::TextureImpl *impl, GLuint id, GLenum target);
 
     virtual ~Texture();
 
@@ -59,9 +62,14 @@
     GLint getBaseLevelDepth() const;
     GLenum getBaseLevelInternalFormat() const;
 
-    bool isSamplerComplete(const SamplerState &samplerState) const;
+    GLsizei getWidth(const ImageIndex &index) const;
+    GLsizei getHeight(const ImageIndex &index) const;
+    GLenum getInternalFormat(const ImageIndex &index) const;
+    GLenum getActualFormat(const ImageIndex &index) const;
 
-    rx::TextureStorageInterface *getNativeTexture();
+    virtual bool isSamplerComplete(const SamplerState &samplerState, const TextureCapsMap &textureCaps, const Extensions &extensions, int clientVersion) const = 0;
+
+    rx::TextureStorage *getNativeTexture();
 
     virtual void generateMipmaps();
     virtual void copySubImage(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height, Framebuffer *source);
@@ -71,14 +79,16 @@
     bool isImmutable() const;
     int immutableLevelCount();
 
-    virtual rx::TextureImpl *getImplementation() = 0;
-    virtual const rx::TextureImpl *getImplementation() const = 0;
+    rx::TextureImpl *getImplementation() { return mTexture; }
+    const rx::TextureImpl *getImplementation() const { return mTexture; }
 
     static const GLuint INCOMPLETE_TEXTURE_ID = static_cast<GLuint>(-1);   // Every texture takes an id at creation time. The value is arbitrary because it is never registered with the resource manager.
 
   protected:
     int mipLevels() const;
 
+    rx::TextureImpl *mTexture;
+
     SamplerState mSamplerState;
     GLenum mUsage;
 
@@ -86,18 +96,18 @@
 
     GLenum mTarget;
 
+    const rx::Image *getBaseLevelImage() const;
+
   private:
     DISALLOW_COPY_AND_ASSIGN(Texture);
-
-    const rx::Image *getBaseLevelImage() const;
 };
 
 class Texture2D : public Texture
 {
   public:
-    Texture2D(rx::Texture2DImpl *impl, GLuint id);
+    Texture2D(rx::TextureImpl *impl, GLuint id);
 
-    ~Texture2D();
+    virtual ~Texture2D();
 
     GLsizei getWidth(GLint level) const;
     GLsizei getHeight(GLint level) const;
@@ -113,34 +123,27 @@
     void copyImage(GLint level, GLenum format, GLint x, GLint y, GLsizei width, GLsizei height, Framebuffer *source);
     void storage(GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height);
 
+    virtual bool isSamplerComplete(const SamplerState &samplerState, const TextureCapsMap &textureCaps, const Extensions &extensions, int clientVersion) const;
     virtual void bindTexImage(egl::Surface *surface);
     virtual void releaseTexImage();
 
     virtual void generateMipmaps();
 
-    unsigned int getRenderTargetSerial(GLint level);
-
-    virtual rx::TextureImpl *getImplementation() { return mTexture; }
-    virtual const rx::TextureImpl *getImplementation() const { return mTexture; }
-
-  protected:
-    friend class Texture2DAttachment;
-    rx::RenderTarget *getRenderTarget(GLint level);
-    rx::RenderTarget *getDepthStencil(GLint level);
-
   private:
     DISALLOW_COPY_AND_ASSIGN(Texture2D);
 
-    rx::Texture2DImpl *mTexture;
+    bool isMipmapComplete() const;
+    bool isLevelComplete(int level) const;
+
     egl::Surface *mSurface;
 };
 
 class TextureCubeMap : public Texture
 {
   public:
-    TextureCubeMap(rx::TextureCubeImpl *impl, GLuint id);
+    TextureCubeMap(rx::TextureImpl *impl, GLuint id);
 
-    ~TextureCubeMap();
+    virtual ~TextureCubeMap();
 
     GLsizei getWidth(GLenum target, GLint level) const;
     GLsizei getHeight(GLenum target, GLint level) const;
@@ -163,33 +166,26 @@
     void copyImage(GLenum target, GLint level, GLenum format, GLint x, GLint y, GLsizei width, GLsizei height, Framebuffer *source);
     void storage(GLsizei levels, GLenum internalformat, GLsizei size);
 
-    bool isCubeComplete() const;
+    virtual bool isSamplerComplete(const SamplerState &samplerState, const TextureCapsMap &textureCaps, const Extensions &extensions, int clientVersion) const;
 
-    unsigned int getRenderTargetSerial(GLenum target, GLint level);
+    bool isCubeComplete() const;
 
     static int targetToLayerIndex(GLenum target);
     static GLenum layerIndexToTarget(GLint layer);
 
-    virtual rx::TextureImpl *getImplementation() { return mTexture; }
-    virtual const rx::TextureImpl *getImplementation() const { return mTexture; }
-
-  protected:
-    friend class TextureCubeMapAttachment;
-    rx::RenderTarget *getRenderTarget(GLenum target, GLint level);
-    rx::RenderTarget *getDepthStencil(GLenum target, GLint level);
-
   private:
     DISALLOW_COPY_AND_ASSIGN(TextureCubeMap);
 
-    rx::TextureCubeImpl *mTexture;
+    bool isMipmapComplete() const;
+    bool isFaceLevelComplete(int faceIndex, int level) const;
 };
 
 class Texture3D : public Texture
 {
   public:
-    Texture3D(rx::Texture3DImpl *impl, GLuint id);
+    Texture3D(rx::TextureImpl *impl, GLuint id);
 
-    ~Texture3D();
+    virtual ~Texture3D();
 
     GLsizei getWidth(GLint level) const;
     GLsizei getHeight(GLint level) const;
@@ -205,28 +201,21 @@
     void subImageCompressed(GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const void *pixels);
     void storage(GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth);
 
-    unsigned int getRenderTargetSerial(GLint level, GLint layer);
-
-    virtual rx::TextureImpl *getImplementation() { return mTexture; }
-    virtual const rx::TextureImpl *getImplementation() const { return mTexture; }
-
-  protected:
-    friend class Texture3DAttachment;
-    rx::RenderTarget *getRenderTarget(GLint level, GLint layer);
-    rx::RenderTarget *getDepthStencil(GLint level, GLint layer);
+    virtual bool isSamplerComplete(const SamplerState &samplerState, const TextureCapsMap &textureCaps, const Extensions &extensions, int clientVersion) const;
 
   private:
     DISALLOW_COPY_AND_ASSIGN(Texture3D);
 
-    rx::Texture3DImpl *mTexture;
+    bool isMipmapComplete() const;
+    bool isLevelComplete(int level) const;
 };
 
 class Texture2DArray : public Texture
 {
   public:
-    Texture2DArray(rx::Texture2DArrayImpl *impl, GLuint id);
+    Texture2DArray(rx::TextureImpl *impl, GLuint id);
 
-    ~Texture2DArray();
+    virtual ~Texture2DArray();
 
     GLsizei getWidth(GLint level) const;
     GLsizei getHeight(GLint level) const;
@@ -242,20 +231,13 @@
     void subImageCompressed(GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const void *pixels);
     void storage(GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth);
 
-    unsigned int getRenderTargetSerial(GLint level, GLint layer);
-
-    virtual rx::TextureImpl *getImplementation() { return mTexture; }
-    virtual const rx::TextureImpl *getImplementation() const { return mTexture; }
-
-  protected:
-    friend class Texture2DArrayAttachment;
-    rx::RenderTarget *getRenderTarget(GLint level, GLint layer);
-    rx::RenderTarget *getDepthStencil(GLint level, GLint layer);
+    virtual bool isSamplerComplete(const SamplerState &samplerState, const TextureCapsMap &textureCaps, const Extensions &extensions, int clientVersion) const;
 
   private:
     DISALLOW_COPY_AND_ASSIGN(Texture2DArray);
 
-    rx::Texture2DArrayImpl *mTexture;
+    bool isMipmapComplete() const;
+    bool isLevelComplete(int level) const;
 };
 
 }
diff --git a/src/libGLESv2/TransformFeedback.cpp b/src/libGLESv2/TransformFeedback.cpp
index 79ce084..bfa7072 100644
--- a/src/libGLESv2/TransformFeedback.cpp
+++ b/src/libGLESv2/TransformFeedback.cpp
@@ -5,20 +5,24 @@
 //
 
 #include "libGLESv2/TransformFeedback.h"
+#include "libGLESv2/renderer/TransformFeedbackImpl.h"
 
 namespace gl
 {
 
-TransformFeedback::TransformFeedback(GLuint id)
+TransformFeedback::TransformFeedback(rx::TransformFeedbackImpl* impl, GLuint id)
     : RefCountObject(id),
+      mTransformFeedback(impl),
       mStarted(GL_FALSE),
       mPrimitiveMode(GL_NONE),
       mPaused(GL_FALSE)
 {
+    ASSERT(impl != NULL);
 }
 
 TransformFeedback::~TransformFeedback()
 {
+    SafeDelete(mTransformFeedback);
 }
 
 void TransformFeedback::start(GLenum primitiveMode)
@@ -26,6 +30,7 @@
     mStarted = GL_TRUE;
     mPrimitiveMode = primitiveMode;
     mPaused = GL_FALSE;
+    mTransformFeedback->begin(primitiveMode);
 }
 
 void TransformFeedback::stop()
@@ -33,6 +38,7 @@
     mStarted = GL_FALSE;
     mPrimitiveMode = GL_NONE;
     mPaused = GL_FALSE;
+    mTransformFeedback->end();
 }
 
 GLboolean TransformFeedback::isStarted() const
@@ -48,11 +54,13 @@
 void TransformFeedback::pause()
 {
     mPaused = GL_TRUE;
+    mTransformFeedback->pause();
 }
 
 void TransformFeedback::resume()
 {
     mPaused = GL_FALSE;
+    mTransformFeedback->resume();
 }
 
 GLboolean TransformFeedback::isPaused() const
diff --git a/src/libGLESv2/TransformFeedback.h b/src/libGLESv2/TransformFeedback.h
index d6f4522..885a4fe 100644
--- a/src/libGLESv2/TransformFeedback.h
+++ b/src/libGLESv2/TransformFeedback.h
@@ -12,13 +12,18 @@
 
 #include "angle_gl.h"
 
+namespace rx
+{
+class TransformFeedbackImpl;
+}
+
 namespace gl
 {
 
 class TransformFeedback : public RefCountObject
 {
   public:
-    explicit TransformFeedback(GLuint id);
+    TransformFeedback(rx::TransformFeedbackImpl* impl, GLuint id);
     virtual ~TransformFeedback();
 
     void start(GLenum primitiveMode);
@@ -34,6 +39,8 @@
   private:
     DISALLOW_COPY_AND_ASSIGN(TransformFeedback);
 
+    rx::TransformFeedbackImpl* mTransformFeedback;
+
     GLboolean mStarted;
     GLenum mPrimitiveMode;
     GLboolean mPaused;
diff --git a/src/libGLESv2/Uniform.cpp b/src/libGLESv2/Uniform.cpp
index cddc7ec..bd0cd2e 100644
--- a/src/libGLESv2/Uniform.cpp
+++ b/src/libGLESv2/Uniform.cpp
@@ -1,4 +1,3 @@
-#include "precompiled.h"
 //
 // Copyright (c) 2010-2013 The ANGLE Project Authors. All rights reserved.
 // Use of this source code is governed by a BSD-style license that can be
diff --git a/src/libGLESv2/Uniform.h b/src/libGLESv2/Uniform.h
index b7039a1..633d70b 100644
--- a/src/libGLESv2/Uniform.h
+++ b/src/libGLESv2/Uniform.h
@@ -7,14 +7,15 @@
 #ifndef LIBGLESV2_UNIFORM_H_
 #define LIBGLESV2_UNIFORM_H_
 
-#include <string>
-#include <vector>
+#include "common/debug.h"
+#include "common/blocklayout.h"
+
+#include "libGLESv2/angletypes.h"
 
 #include "angle_gl.h"
 
-#include "common/debug.h"
-#include "angletypes.h"
-#include "common/blocklayout.h"
+#include <string>
+#include <vector>
 
 namespace gl
 {
diff --git a/src/libGLESv2/VertexArray.cpp b/src/libGLESv2/VertexArray.cpp
index 120064a..f8ca661 100644
--- a/src/libGLESv2/VertexArray.cpp
+++ b/src/libGLESv2/VertexArray.cpp
@@ -1,4 +1,3 @@
-#include "precompiled.h"
 //
 // 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
diff --git a/src/libGLESv2/VertexArray.h b/src/libGLESv2/VertexArray.h
index accd987..993ba04 100644
--- a/src/libGLESv2/VertexArray.h
+++ b/src/libGLESv2/VertexArray.h
@@ -17,6 +17,8 @@
 #include "libGLESv2/constants.h"
 #include "libGLESv2/VertexAttribute.h"
 
+#include <vector>
+
 namespace rx
 {
 class Renderer;
diff --git a/src/libGLESv2/VertexAttribute.cpp b/src/libGLESv2/VertexAttribute.cpp
index 7d011ef..1096856 100644
--- a/src/libGLESv2/VertexAttribute.cpp
+++ b/src/libGLESv2/VertexAttribute.cpp
@@ -1,4 +1,3 @@
-#include "precompiled.h"
 //
 // Copyright 2014 The ANGLE Project Authors. All rights reserved.
 // Use of this source code is governed by a BSD-style license that can be
diff --git a/src/libGLESv2/angletypes.cpp b/src/libGLESv2/angletypes.cpp
index ec5521e..06618d5 100644
--- a/src/libGLESv2/angletypes.cpp
+++ b/src/libGLESv2/angletypes.cpp
@@ -1,4 +1,3 @@
-#include "precompiled.h"
 //
 // 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
diff --git a/src/libGLESv2/angletypes.h b/src/libGLESv2/angletypes.h
index 79ad810..922053e 100644
--- a/src/libGLESv2/angletypes.h
+++ b/src/libGLESv2/angletypes.h
@@ -19,17 +19,6 @@
 struct VertexAttribute;
 struct VertexAttribCurrentValueData;
 
-enum TextureType
-{
-    TEXTURE_2D,
-    TEXTURE_CUBE,
-    TEXTURE_3D,
-    TEXTURE_2D_ARRAY,
-
-    TEXTURE_TYPE_COUNT,
-    TEXTURE_UNKNOWN
-};
-
 enum SamplerType
 {
     SAMPLER_PIXEL,
diff --git a/src/libGLESv2/constants.h b/src/libGLESv2/constants.h
index c87f92d..69c4823 100644
--- a/src/libGLESv2/constants.h
+++ b/src/libGLESv2/constants.h
@@ -15,12 +15,8 @@
 enum
 {
     MAX_VERTEX_ATTRIBS = 16,
-    MAX_TEXTURE_IMAGE_UNITS = 16,
 
     // Implementation upper limits, real maximums depend on the hardware
-    IMPLEMENTATION_MAX_VERTEX_TEXTURE_IMAGE_UNITS = 16,
-    IMPLEMENTATION_MAX_COMBINED_TEXTURE_IMAGE_UNITS = MAX_TEXTURE_IMAGE_UNITS + IMPLEMENTATION_MAX_VERTEX_TEXTURE_IMAGE_UNITS,    
-
     IMPLEMENTATION_MAX_VARYING_VECTORS = 32,
     IMPLEMENTATION_MAX_DRAW_BUFFERS = 8,
     IMPLEMENTATION_MAX_FRAMEBUFFER_ATTACHMENTS = IMPLEMENTATION_MAX_DRAW_BUFFERS + 2, // 2 extra for depth and/or stencil buffers
diff --git a/src/libGLESv2/formatutils.cpp b/src/libGLESv2/formatutils.cpp
index 008189a..9d98829 100644
--- a/src/libGLESv2/formatutils.cpp
+++ b/src/libGLESv2/formatutils.cpp
@@ -1,4 +1,3 @@
-#include "precompiled.h"
 //
 // Copyright (c) 2013-2014 The ANGLE Project Authors. All rights reserved.
 // Use of this source code is governed by a BSD-style license that can be
diff --git a/src/libGLESv2/formatutils.h b/src/libGLESv2/formatutils.h
index 1fc1c1f..25106a5 100644
--- a/src/libGLESv2/formatutils.h
+++ b/src/libGLESv2/formatutils.h
@@ -9,12 +9,13 @@
 #ifndef LIBGLESV2_FORMATUTILS_H_
 #define LIBGLESV2_FORMATUTILS_H_
 
-#include "angle_gl.h"
-
 #include "libGLESv2/Caps.h"
 #include "libGLESv2/angletypes.h"
 
+#include "angle_gl.h"
+
 #include <cstddef>
+#include <cstdint>
 
 typedef void (*MipGenerationFunction)(size_t sourceWidth, size_t sourceHeight, size_t sourceDepth,
                                       const uint8_t *sourceData, size_t sourceRowPitch, size_t sourceDepthPitch,
@@ -27,11 +28,11 @@
 typedef void (*InitializeTextureDataFunction)(size_t width, size_t height, size_t depth,
                                               uint8_t *output, size_t outputRowPitch, size_t outputDepthPitch);
 
-typedef void (*ColorReadFunction)(const void *source, void *dest);
-typedef void (*ColorWriteFunction)(const void *source, void *dest);
-typedef void (*ColorCopyFunction)(const void *source, void *dest);
+typedef void (*ColorReadFunction)(const uint8_t *source, uint8_t *dest);
+typedef void (*ColorWriteFunction)(const uint8_t *source, uint8_t *dest);
+typedef void (*ColorCopyFunction)(const uint8_t *source, uint8_t *dest);
 
-typedef void (*VertexCopyFunction)(const void *input, size_t stride, size_t count, void *output);
+typedef void (*VertexCopyFunction)(const uint8_t *input, size_t stride, size_t count, uint8_t *output);
 
 namespace gl
 {
@@ -102,4 +103,4 @@
 
 }
 
-#endif LIBGLESV2_FORMATUTILS_H_
+#endif // LIBGLESV2_FORMATUTILS_H_
diff --git a/src/libGLESv2/libGLESv2.cpp b/src/libGLESv2/libGLESv2.cpp
index 73f4572..a62e163 100644
--- a/src/libGLESv2/libGLESv2.cpp
+++ b/src/libGLESv2/libGLESv2.cpp
@@ -1,4 +1,3 @@
-#include "precompiled.h"
 //
 // 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
@@ -8,9 +7,9 @@
 // libGLESv2.cpp: Implements the exported OpenGL ES 2.0 functions.
 
 #include "common/version.h"
+#include "common/utilities.h"
 
 #include "libGLESv2/main.h"
-#include "common/utilities.h"
 #include "libGLESv2/formatutils.h"
 #include "libGLESv2/Buffer.h"
 #include "libGLESv2/Fence.h"
@@ -41,12 +40,12 @@
     EVENT("(GLenum texture = 0x%X)", texture);
 
     gl::Context *context = gl::getNonLostContext();
-
     if (context)
     {
-        if (texture < GL_TEXTURE0 || texture > GL_TEXTURE0 + context->getMaximumCombinedTextureImageUnits() - 1)
+        if (texture < GL_TEXTURE0 || texture > GL_TEXTURE0 + context->getCaps().maxCombinedTextureImageUnits - 1)
         {
-            return gl::error(GL_INVALID_ENUM);
+            context->recordError(gl::Error(GL_INVALID_ENUM));
+            return;
         }
 
         context->getState().setActiveSampler(texture - GL_TEXTURE0);
@@ -58,7 +57,6 @@
     EVENT("(GLuint program = %d, GLuint shader = %d)", program, shader);
 
     gl::Context *context = gl::getNonLostContext();
-
     if (context)
     {
         gl::Program *programObject = context->getProgram(program);
@@ -68,11 +66,13 @@
         {
             if (context->getShader(program))
             {
-                return gl::error(GL_INVALID_OPERATION);
+                context->recordError(gl::Error(GL_INVALID_OPERATION));
+                return;
             }
             else
             {
-                return gl::error(GL_INVALID_VALUE);
+                context->recordError(gl::Error(GL_INVALID_VALUE));
+                return;
             }
         }
 
@@ -80,17 +80,20 @@
         {
             if (context->getProgram(shader))
             {
-                return gl::error(GL_INVALID_OPERATION);
+                context->recordError(gl::Error(GL_INVALID_OPERATION));
+                return;
             }
             else
             {
-                return gl::error(GL_INVALID_VALUE);
+                context->recordError(gl::Error(GL_INVALID_VALUE));
+                return;
             }
         }
 
         if (!programObject->attachShader(shaderObject))
         {
-            return gl::error(GL_INVALID_OPERATION);
+            context->recordError(gl::Error(GL_INVALID_OPERATION));
+            return;
         }
     }
 }
@@ -100,7 +103,6 @@
     EVENT("(GLenum target = 0x%X, GLuint %d)", target, id);
 
     gl::Context *context = gl::getNonLostContext();
-
     if (context)
     {
         if (!ValidateBeginQuery(context, target, id))
@@ -108,7 +110,12 @@
             return;
         }
 
-        context->beginQuery(target, id);
+        gl::Error error = context->beginQuery(target, id);
+        if (error.isError())
+        {
+            context->recordError(error);
+            return;
+        }
     }
 }
 
@@ -116,32 +123,35 @@
 {
     EVENT("(GLuint program = %d, GLuint index = %d, const GLchar* name = 0x%0.8p)", program, index, name);
 
-    if (index >= gl::MAX_VERTEX_ATTRIBS)
-    {
-        return gl::error(GL_INVALID_VALUE);
-    }
-
     gl::Context *context = gl::getNonLostContext();
-
     if (context)
     {
+        if (index >= gl::MAX_VERTEX_ATTRIBS)
+        {
+            context->recordError(gl::Error(GL_INVALID_VALUE));
+            return;
+        }
+
         gl::Program *programObject = context->getProgram(program);
 
         if (!programObject)
         {
             if (context->getShader(program))
             {
-                return gl::error(GL_INVALID_OPERATION);
+                context->recordError(gl::Error(GL_INVALID_OPERATION));
+                return;
             }
             else
             {
-                return gl::error(GL_INVALID_VALUE);
+                context->recordError(gl::Error(GL_INVALID_VALUE));
+                return;
             }
         }
 
         if (strncmp(name, "gl_", 3) == 0)
         {
-            return gl::error(GL_INVALID_OPERATION);
+            context->recordError(gl::Error(GL_INVALID_OPERATION));
+            return;
         }
 
         programObject->bindAttributeLocation(index, name);
@@ -153,12 +163,12 @@
     EVENT("(GLenum target = 0x%X, GLuint buffer = %d)", target, buffer);
 
     gl::Context *context = gl::getNonLostContext();
-
     if (context)
     {
         if (!gl::ValidBufferTarget(context, target))
         {
-            return gl::error(GL_INVALID_ENUM);
+            context->recordError(gl::Error(GL_INVALID_ENUM));
+            return;
         }
 
         switch (target)
@@ -187,8 +197,10 @@
           case GL_TRANSFORM_FEEDBACK_BUFFER:
             context->bindGenericTransformFeedbackBuffer(buffer);
             return;
+
           default:
-            return gl::error(GL_INVALID_ENUM);
+            context->recordError(gl::Error(GL_INVALID_ENUM));
+            return;
         }
     }
 }
@@ -197,15 +209,15 @@
 {
     EVENT("(GLenum target = 0x%X, GLuint framebuffer = %d)", target, framebuffer);
 
-    if (!gl::ValidFramebufferTarget(target))
-    {
-        return gl::error(GL_INVALID_ENUM);
-    }
-
     gl::Context *context = gl::getNonLostContext();
-
     if (context)
     {
+        if (!gl::ValidFramebufferTarget(target))
+        {
+            context->recordError(gl::Error(GL_INVALID_ENUM));
+            return;
+        }
+
         if (target == GL_READ_FRAMEBUFFER_ANGLE || target == GL_FRAMEBUFFER)
         {
             context->bindReadFramebuffer(framebuffer);
@@ -222,15 +234,15 @@
 {
     EVENT("(GLenum target = 0x%X, GLuint renderbuffer = %d)", target, renderbuffer);
 
-    if (target != GL_RENDERBUFFER)
-    {
-        return gl::error(GL_INVALID_ENUM);
-    }
-
     gl::Context *context = gl::getNonLostContext();
-
     if (context)
     {
+        if (target != GL_RENDERBUFFER)
+        {
+            context->recordError(gl::Error(GL_INVALID_ENUM));
+            return;
+        }
+
         context->bindRenderbuffer(renderbuffer);
     }
 }
@@ -240,41 +252,37 @@
     EVENT("(GLenum target = 0x%X, GLuint texture = %d)", target, texture);
 
     gl::Context *context = gl::getNonLostContext();
-
     if (context)
     {
         gl::Texture *textureObject = context->getTexture(texture);
 
         if (textureObject && textureObject->getTarget() != target && texture != 0)
         {
-            return gl::error(GL_INVALID_OPERATION);
+            context->recordError(gl::Error(GL_INVALID_OPERATION));
+            return;
         }
 
         switch (target)
         {
           case GL_TEXTURE_2D:
-            context->bindTexture2D(texture);
-            return;
           case GL_TEXTURE_CUBE_MAP:
-            context->bindTextureCubeMap(texture);
-            return;
+            break;
+
           case GL_TEXTURE_3D:
-            if (context->getClientVersion() < 3)
-            {
-                return gl::error(GL_INVALID_ENUM);
-            }
-            context->bindTexture3D(texture);
-            return;
           case GL_TEXTURE_2D_ARRAY:
             if (context->getClientVersion() < 3)
             {
-                return gl::error(GL_INVALID_ENUM);
+                context->recordError(gl::Error(GL_INVALID_ENUM));
+                return;
             }
-            context->bindTexture2DArray(texture);
-            return;
+            break;
+
           default:
-            return gl::error(GL_INVALID_ENUM);
+            context->recordError(gl::Error(GL_INVALID_ENUM));
+            return;
         }
+
+        context->bindTexture(target, texture);
     }
 }
 
@@ -301,35 +309,36 @@
     EVENT("(GLenum modeRGB = 0x%X, GLenum modeAlpha = 0x%X)", modeRGB, modeAlpha);
 
     gl::Context *context = gl::getNonLostContext();
-
-    switch (modeRGB)
-    {
-      case GL_FUNC_ADD:
-      case GL_FUNC_SUBTRACT:
-      case GL_FUNC_REVERSE_SUBTRACT:
-      case GL_MIN:
-      case GL_MAX:
-        break;
-
-      default:
-        return gl::error(GL_INVALID_ENUM);
-    }
-
-    switch (modeAlpha)
-    {
-      case GL_FUNC_ADD:
-      case GL_FUNC_SUBTRACT:
-      case GL_FUNC_REVERSE_SUBTRACT:
-      case GL_MIN:
-      case GL_MAX:
-        break;
-
-      default:
-        return gl::error(GL_INVALID_ENUM);
-    }
-
     if (context)
     {
+        switch (modeRGB)
+        {
+          case GL_FUNC_ADD:
+          case GL_FUNC_SUBTRACT:
+          case GL_FUNC_REVERSE_SUBTRACT:
+          case GL_MIN:
+          case GL_MAX:
+            break;
+
+          default:
+            context->recordError(gl::Error(GL_INVALID_ENUM));
+            return;
+        }
+
+        switch (modeAlpha)
+        {
+          case GL_FUNC_ADD:
+          case GL_FUNC_SUBTRACT:
+          case GL_FUNC_REVERSE_SUBTRACT:
+          case GL_MIN:
+          case GL_MAX:
+            break;
+
+          default:
+            context->recordError(gl::Error(GL_INVALID_ENUM));
+            return;
+        }
+
         context->getState().setBlendEquation(modeRGB, modeAlpha);
     }
 }
@@ -345,123 +354,131 @@
           srcRGB, dstRGB, srcAlpha, dstAlpha);
 
     gl::Context *context = gl::getNonLostContext();
-
-    switch (srcRGB)
-    {
-      case GL_ZERO:
-      case GL_ONE:
-      case GL_SRC_COLOR:
-      case GL_ONE_MINUS_SRC_COLOR:
-      case GL_DST_COLOR:
-      case GL_ONE_MINUS_DST_COLOR:
-      case GL_SRC_ALPHA:
-      case GL_ONE_MINUS_SRC_ALPHA:
-      case GL_DST_ALPHA:
-      case GL_ONE_MINUS_DST_ALPHA:
-      case GL_CONSTANT_COLOR:
-      case GL_ONE_MINUS_CONSTANT_COLOR:
-      case GL_CONSTANT_ALPHA:
-      case GL_ONE_MINUS_CONSTANT_ALPHA:
-      case GL_SRC_ALPHA_SATURATE:
-        break;
-      default:
-        return gl::error(GL_INVALID_ENUM);
-    }
-
-    switch (dstRGB)
-    {
-      case GL_ZERO:
-      case GL_ONE:
-      case GL_SRC_COLOR:
-      case GL_ONE_MINUS_SRC_COLOR:
-      case GL_DST_COLOR:
-      case GL_ONE_MINUS_DST_COLOR:
-      case GL_SRC_ALPHA:
-      case GL_ONE_MINUS_SRC_ALPHA:
-      case GL_DST_ALPHA:
-      case GL_ONE_MINUS_DST_ALPHA:
-      case GL_CONSTANT_COLOR:
-      case GL_ONE_MINUS_CONSTANT_COLOR:
-      case GL_CONSTANT_ALPHA:
-      case GL_ONE_MINUS_CONSTANT_ALPHA:
-        break;
-
-      case GL_SRC_ALPHA_SATURATE:
-        if (!context || context->getClientVersion() < 3)
-        {
-            return gl::error(GL_INVALID_ENUM);
-        }
-        break;
-
-      default:
-        return gl::error(GL_INVALID_ENUM);
-    }
-
-    switch (srcAlpha)
-    {
-      case GL_ZERO:
-      case GL_ONE:
-      case GL_SRC_COLOR:
-      case GL_ONE_MINUS_SRC_COLOR:
-      case GL_DST_COLOR:
-      case GL_ONE_MINUS_DST_COLOR:
-      case GL_SRC_ALPHA:
-      case GL_ONE_MINUS_SRC_ALPHA:
-      case GL_DST_ALPHA:
-      case GL_ONE_MINUS_DST_ALPHA:
-      case GL_CONSTANT_COLOR:
-      case GL_ONE_MINUS_CONSTANT_COLOR:
-      case GL_CONSTANT_ALPHA:
-      case GL_ONE_MINUS_CONSTANT_ALPHA:
-      case GL_SRC_ALPHA_SATURATE:
-        break;
-      default:
-        return gl::error(GL_INVALID_ENUM);
-    }
-
-    switch (dstAlpha)
-    {
-      case GL_ZERO:
-      case GL_ONE:
-      case GL_SRC_COLOR:
-      case GL_ONE_MINUS_SRC_COLOR:
-      case GL_DST_COLOR:
-      case GL_ONE_MINUS_DST_COLOR:
-      case GL_SRC_ALPHA:
-      case GL_ONE_MINUS_SRC_ALPHA:
-      case GL_DST_ALPHA:
-      case GL_ONE_MINUS_DST_ALPHA:
-      case GL_CONSTANT_COLOR:
-      case GL_ONE_MINUS_CONSTANT_COLOR:
-      case GL_CONSTANT_ALPHA:
-      case GL_ONE_MINUS_CONSTANT_ALPHA:
-        break;
-
-      case GL_SRC_ALPHA_SATURATE:
-        if (!context || context->getClientVersion() < 3)
-        {
-            return gl::error(GL_INVALID_ENUM);
-        }
-        break;
-
-      default:
-        return gl::error(GL_INVALID_ENUM);
-    }
-
-    bool constantColorUsed = (srcRGB == GL_CONSTANT_COLOR || srcRGB == GL_ONE_MINUS_CONSTANT_COLOR ||
-                              dstRGB == GL_CONSTANT_COLOR || dstRGB == GL_ONE_MINUS_CONSTANT_COLOR);
-
-    bool constantAlphaUsed = (srcRGB == GL_CONSTANT_ALPHA || srcRGB == GL_ONE_MINUS_CONSTANT_ALPHA ||
-                              dstRGB == GL_CONSTANT_ALPHA || dstRGB == GL_ONE_MINUS_CONSTANT_ALPHA);
-
-    if (constantColorUsed && constantAlphaUsed)
-    {
-        ERR("Simultaneous use of GL_CONSTANT_ALPHA/GL_ONE_MINUS_CONSTANT_ALPHA and GL_CONSTANT_COLOR/GL_ONE_MINUS_CONSTANT_COLOR invalid under WebGL");
-        return gl::error(GL_INVALID_OPERATION);
-    }
-
     if (context)
     {
+        switch (srcRGB)
+        {
+          case GL_ZERO:
+          case GL_ONE:
+          case GL_SRC_COLOR:
+          case GL_ONE_MINUS_SRC_COLOR:
+          case GL_DST_COLOR:
+          case GL_ONE_MINUS_DST_COLOR:
+          case GL_SRC_ALPHA:
+          case GL_ONE_MINUS_SRC_ALPHA:
+          case GL_DST_ALPHA:
+          case GL_ONE_MINUS_DST_ALPHA:
+          case GL_CONSTANT_COLOR:
+          case GL_ONE_MINUS_CONSTANT_COLOR:
+          case GL_CONSTANT_ALPHA:
+          case GL_ONE_MINUS_CONSTANT_ALPHA:
+          case GL_SRC_ALPHA_SATURATE:
+            break;
+
+          default:
+              context->recordError(gl::Error(GL_INVALID_ENUM));
+              return;
+        }
+
+        switch (dstRGB)
+        {
+          case GL_ZERO:
+          case GL_ONE:
+          case GL_SRC_COLOR:
+          case GL_ONE_MINUS_SRC_COLOR:
+          case GL_DST_COLOR:
+          case GL_ONE_MINUS_DST_COLOR:
+          case GL_SRC_ALPHA:
+          case GL_ONE_MINUS_SRC_ALPHA:
+          case GL_DST_ALPHA:
+          case GL_ONE_MINUS_DST_ALPHA:
+          case GL_CONSTANT_COLOR:
+          case GL_ONE_MINUS_CONSTANT_COLOR:
+          case GL_CONSTANT_ALPHA:
+          case GL_ONE_MINUS_CONSTANT_ALPHA:
+            break;
+
+          case GL_SRC_ALPHA_SATURATE:
+            if (context->getClientVersion() < 3)
+            {
+                context->recordError(gl::Error(GL_INVALID_ENUM));
+                return;
+            }
+            break;
+
+          default:
+            context->recordError(gl::Error(GL_INVALID_ENUM));
+            return;
+        }
+
+        switch (srcAlpha)
+        {
+          case GL_ZERO:
+          case GL_ONE:
+          case GL_SRC_COLOR:
+          case GL_ONE_MINUS_SRC_COLOR:
+          case GL_DST_COLOR:
+          case GL_ONE_MINUS_DST_COLOR:
+          case GL_SRC_ALPHA:
+          case GL_ONE_MINUS_SRC_ALPHA:
+          case GL_DST_ALPHA:
+          case GL_ONE_MINUS_DST_ALPHA:
+          case GL_CONSTANT_COLOR:
+          case GL_ONE_MINUS_CONSTANT_COLOR:
+          case GL_CONSTANT_ALPHA:
+          case GL_ONE_MINUS_CONSTANT_ALPHA:
+          case GL_SRC_ALPHA_SATURATE:
+            break;
+
+          default:
+              context->recordError(gl::Error(GL_INVALID_ENUM));
+              return;
+        }
+
+        switch (dstAlpha)
+        {
+          case GL_ZERO:
+          case GL_ONE:
+          case GL_SRC_COLOR:
+          case GL_ONE_MINUS_SRC_COLOR:
+          case GL_DST_COLOR:
+          case GL_ONE_MINUS_DST_COLOR:
+          case GL_SRC_ALPHA:
+          case GL_ONE_MINUS_SRC_ALPHA:
+          case GL_DST_ALPHA:
+          case GL_ONE_MINUS_DST_ALPHA:
+          case GL_CONSTANT_COLOR:
+          case GL_ONE_MINUS_CONSTANT_COLOR:
+          case GL_CONSTANT_ALPHA:
+          case GL_ONE_MINUS_CONSTANT_ALPHA:
+            break;
+
+          case GL_SRC_ALPHA_SATURATE:
+            if (context->getClientVersion() < 3)
+            {
+                context->recordError(gl::Error(GL_INVALID_ENUM));
+                return;
+            }
+            break;
+
+          default:
+            context->recordError(gl::Error(GL_INVALID_ENUM));
+            return;
+        }
+
+        bool constantColorUsed = (srcRGB == GL_CONSTANT_COLOR || srcRGB == GL_ONE_MINUS_CONSTANT_COLOR ||
+                                  dstRGB == GL_CONSTANT_COLOR || dstRGB == GL_ONE_MINUS_CONSTANT_COLOR);
+
+        bool constantAlphaUsed = (srcRGB == GL_CONSTANT_ALPHA || srcRGB == GL_ONE_MINUS_CONSTANT_ALPHA ||
+                                  dstRGB == GL_CONSTANT_ALPHA || dstRGB == GL_ONE_MINUS_CONSTANT_ALPHA);
+
+        if (constantColorUsed && constantAlphaUsed)
+        {
+            ERR("Simultaneous use of GL_CONSTANT_ALPHA/GL_ONE_MINUS_CONSTANT_ALPHA and GL_CONSTANT_COLOR/GL_ONE_MINUS_CONSTANT_COLOR invalid under WebGL");
+            context->recordError(gl::Error(GL_INVALID_OPERATION));
+            return;
+        }
+
         context->getState().setBlendFactors(srcRGB, dstRGB, srcAlpha, dstAlpha);
     }
 }
@@ -471,51 +488,60 @@
     EVENT("(GLenum target = 0x%X, GLsizeiptr size = %d, const GLvoid* data = 0x%0.8p, GLenum usage = %d)",
           target, size, data, usage);
 
-    if (size < 0)
-    {
-        return gl::error(GL_INVALID_VALUE);
-    }
-
     gl::Context *context = gl::getNonLostContext();
-
-    switch (usage)
-    {
-      case GL_STREAM_DRAW:
-      case GL_STATIC_DRAW:
-      case GL_DYNAMIC_DRAW:
-        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:
-        if (context && context->getClientVersion() < 3)
-        {
-          return gl::error(GL_INVALID_ENUM);
-        }
-        break;
-
-      default:
-        return gl::error(GL_INVALID_ENUM);
-    }
-
     if (context)
     {
+        if (size < 0)
+        {
+            context->recordError(gl::Error(GL_INVALID_VALUE));
+            return;
+        }
+
+        switch (usage)
+        {
+          case GL_STREAM_DRAW:
+          case GL_STATIC_DRAW:
+          case GL_DYNAMIC_DRAW:
+            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:
+            if (context->getClientVersion() < 3)
+            {
+                context->recordError(gl::Error(GL_INVALID_ENUM));
+                return;
+            }
+            break;
+
+          default:
+              context->recordError(gl::Error(GL_INVALID_ENUM));
+              return;
+        }
+
         if (!gl::ValidBufferTarget(context, target))
         {
-            return gl::error(GL_INVALID_ENUM);
+            context->recordError(gl::Error(GL_INVALID_ENUM));
+            return;
         }
 
         gl::Buffer *buffer = context->getState().getTargetBuffer(target);
 
         if (!buffer)
         {
-            return gl::error(GL_INVALID_OPERATION);
+            context->recordError(gl::Error(GL_INVALID_OPERATION));
+            return;
         }
 
-        buffer->bufferData(data, size, usage);
+        gl::Error error = buffer->bufferData(data, size, usage);
+        if (error.isError())
+        {
+            context->recordError(error);
+            return;
+        }
     }
 }
 
@@ -524,49 +550,59 @@
     EVENT("(GLenum target = 0x%X, GLintptr offset = %d, GLsizeiptr size = %d, const GLvoid* data = 0x%0.8p)",
           target, offset, size, data);
 
-    if (size < 0 || offset < 0)
-    {
-        return gl::error(GL_INVALID_VALUE);
-    }
-
-    if (data == NULL)
-    {
-        return;
-    }
-
     gl::Context *context = gl::getNonLostContext();
-
     if (context)
     {
+        if (size < 0 || offset < 0)
+        {
+            context->recordError(gl::Error(GL_INVALID_VALUE));
+            return;
+        }
+
+        if (data == NULL)
+        {
+            return;
+        }
+
         if (!gl::ValidBufferTarget(context, target))
         {
-            return gl::error(GL_INVALID_ENUM);
+            context->recordError(gl::Error(GL_INVALID_ENUM));
+            return;
         }
 
         gl::Buffer *buffer = context->getState().getTargetBuffer(target);
 
         if (!buffer)
         {
-            return gl::error(GL_INVALID_OPERATION);
+            context->recordError(gl::Error(GL_INVALID_OPERATION));
+            return;
         }
 
         if (buffer->isMapped())
         {
-            return gl::error(GL_INVALID_OPERATION);
+            context->recordError(gl::Error(GL_INVALID_OPERATION));
+            return;
         }
 
         // Check for possible overflow of size + offset
         if (!rx::IsUnsignedAdditionSafe<size_t>(size, offset))
         {
-            return gl::error(GL_OUT_OF_MEMORY);
+            context->recordError(gl::Error(GL_OUT_OF_MEMORY));
+            return;
         }
 
         if (size + offset > buffer->getSize())
         {
-            return gl::error(GL_INVALID_VALUE);
+            context->recordError(gl::Error(GL_INVALID_VALUE));
+            return;
         }
 
-        buffer->bufferSubData(data, size, offset);
+        gl::Error error = buffer->bufferSubData(data, size, offset);
+        if (error.isError())
+        {
+            context->recordError(error);
+            return;
+        }
     }
 }
 
@@ -574,15 +610,15 @@
 {
     EVENT("(GLenum target = 0x%X)", target);
 
-    if (!gl::ValidFramebufferTarget(target))
-    {
-        return gl::error(GL_INVALID_ENUM, 0);
-    }
-
     gl::Context *context = gl::getNonLostContext();
-
     if (context)
     {
+        if (!gl::ValidFramebufferTarget(target))
+        {
+            context->recordError(gl::Error(GL_INVALID_ENUM));
+            return 0;
+        }
+
         gl::Framebuffer *framebuffer = context->getState().getTargetFramebuffer(target);
         ASSERT(framebuffer);
         return framebuffer->completeness();
@@ -596,22 +632,28 @@
     EVENT("(GLbitfield mask = 0x%X)", mask);
 
     gl::Context *context = gl::getNonLostContext();
-
     if (context)
     {
         gl::Framebuffer *framebufferObject = context->getState().getDrawFramebuffer();
 
         if (!framebufferObject || framebufferObject->completeness() != GL_FRAMEBUFFER_COMPLETE)
         {
-            return gl::error(GL_INVALID_FRAMEBUFFER_OPERATION);
+            context->recordError(gl::Error(GL_INVALID_FRAMEBUFFER_OPERATION));
+            return;
         }
 
         if ((mask & ~(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT)) != 0)
         {
-            return gl::error(GL_INVALID_VALUE);
+            context->recordError(gl::Error(GL_INVALID_VALUE));
+            return;
         }
 
-        context->clear(mask);
+        gl::Error error = context->clear(mask);
+        if (error.isError())
+        {
+            context->recordError(error);
+            return;
+        }
     }
 }
 
@@ -621,7 +663,6 @@
           red, green, blue, alpha);
 
     gl::Context *context = gl::getNonLostContext();
-
     if (context)
     {
         context->getState().setClearColor(red, green, blue, alpha);
@@ -633,7 +674,6 @@
     EVENT("(GLclampf depth = %f)", depth);
 
     gl::Context *context = gl::getNonLostContext();
-
     if (context)
     {
         context->getState().setClearDepth(depth);
@@ -645,7 +685,6 @@
     EVENT("(GLint s = %d)", s);
 
     gl::Context *context = gl::getNonLostContext();
-
     if (context)
     {
         context->getState().setClearStencil(s);
@@ -658,7 +697,6 @@
           red, green, blue, alpha);
 
     gl::Context *context = gl::getNonLostContext();
-
     if (context)
     {
         context->getState().setColorMask(red == GL_TRUE, green == GL_TRUE, blue == GL_TRUE, alpha == GL_TRUE);
@@ -670,7 +708,6 @@
     EVENT("(GLuint shader = %d)", shader);
 
     gl::Context *context = gl::getNonLostContext();
-
     if (context)
     {
         gl::Shader *shaderObject = context->getShader(shader);
@@ -679,11 +716,13 @@
         {
             if (context->getProgram(shader))
             {
-                return gl::error(GL_INVALID_OPERATION);
+                context->recordError(gl::Error(GL_INVALID_OPERATION));
+                return;
             }
             else
             {
-                return gl::error(GL_INVALID_VALUE);
+                context->recordError(gl::Error(GL_INVALID_VALUE));
+                return;
             }
         }
 
@@ -699,7 +738,6 @@
           target, level, internalformat, width, height, border, imageSize, data);
 
     gl::Context *context = gl::getNonLostContext();
-
     if (context)
     {
         if (context->getClientVersion() < 3 &&
@@ -719,7 +757,8 @@
         const gl::InternalFormat &formatInfo = gl::GetInternalFormatInfo(internalformat);
         if (imageSize < 0 || static_cast<GLuint>(imageSize) != formatInfo.computeBlockSize(GL_UNSIGNED_BYTE, width, height))
         {
-            return gl::error(GL_INVALID_VALUE);
+            context->recordError(gl::Error(GL_INVALID_VALUE));
+            return;
         }
 
         switch (target)
@@ -744,7 +783,8 @@
             break;
 
           default:
-            return gl::error(GL_INVALID_ENUM);
+            context->recordError(gl::Error(GL_INVALID_ENUM));
+            return;
         }
     }
 }
@@ -758,7 +798,6 @@
           target, level, xoffset, yoffset, width, height, format, imageSize, data);
 
     gl::Context *context = gl::getNonLostContext();
-
     if (context)
     {
         if (context->getClientVersion() < 3 &&
@@ -778,7 +817,8 @@
         const gl::InternalFormat &formatInfo = gl::GetInternalFormatInfo(format);
         if (imageSize < 0 || static_cast<GLuint>(imageSize) != formatInfo.computeBlockSize(GL_UNSIGNED_BYTE, width, height))
         {
-            return gl::error(GL_INVALID_VALUE);
+            context->recordError(gl::Error(GL_INVALID_VALUE));
+            return;
         }
 
         switch (target)
@@ -803,7 +843,8 @@
             break;
 
           default:
-            return gl::error(GL_INVALID_ENUM);
+            context->recordError(gl::Error(GL_INVALID_ENUM));
+            return;
         }
     }
 }
@@ -815,7 +856,6 @@
           target, level, internalformat, x, y, width, height, border);
 
     gl::Context *context = gl::getNonLostContext();
-
     if (context)
     {
         if (context->getClientVersion() < 3 &&
@@ -855,8 +895,9 @@
             }
             break;
 
-         default:
-            return gl::error(GL_INVALID_ENUM);
+          default:
+            context->recordError(gl::Error(GL_INVALID_ENUM));
+            return;
         }
     }
 }
@@ -868,7 +909,6 @@
           target, level, xoffset, yoffset, x, y, width, height);
 
     gl::Context *context = gl::getNonLostContext();
-
     if (context)
     {
         if (context->getClientVersion() < 3 &&
@@ -909,7 +949,8 @@
             break;
 
           default:
-            return gl::error(GL_INVALID_ENUM);
+            context->recordError(gl::Error(GL_INVALID_ENUM));
+            return;
         }
     }
 }
@@ -932,7 +973,6 @@
     EVENT("(GLenum type = 0x%X)", type);
 
     gl::Context *context = gl::getNonLostContext();
-
     if (context)
     {
         switch (type)
@@ -940,8 +980,10 @@
           case GL_FRAGMENT_SHADER:
           case GL_VERTEX_SHADER:
             return context->createShader(type);
+
           default:
-            return gl::error(GL_INVALID_ENUM, 0);
+            context->recordError(gl::Error(GL_INVALID_ENUM));
+            return 0;
         }
     }
 
@@ -952,22 +994,22 @@
 {
     EVENT("(GLenum mode = 0x%X)", mode);
 
-    switch (mode)
+    gl::Context *context = gl::getNonLostContext();
+    if (context)
     {
-      case GL_FRONT:
-      case GL_BACK:
-      case GL_FRONT_AND_BACK:
+        switch (mode)
         {
-            gl::Context *context = gl::getNonLostContext();
+          case GL_FRONT:
+          case GL_BACK:
+          case GL_FRONT_AND_BACK:
+            break;
 
-            if (context)
-            {
-                context->getState().setCullMode(mode);
-            }
+          default:
+            context->recordError(gl::Error(GL_INVALID_ENUM));
+            return;
         }
-        break;
-      default:
-        return gl::error(GL_INVALID_ENUM);
+
+        context->getState().setCullMode(mode);
     }
 }
 
@@ -975,15 +1017,15 @@
 {
     EVENT("(GLsizei n = %d, const GLuint* buffers = 0x%0.8p)", n, buffers);
 
-    if (n < 0)
-    {
-        return gl::error(GL_INVALID_VALUE);
-    }
-
     gl::Context *context = gl::getNonLostContext();
-
     if (context)
     {
+        if (n < 0)
+        {
+            context->recordError(gl::Error(GL_INVALID_VALUE));
+            return;
+        }
+
         for (int i = 0; i < n; i++)
         {
             context->deleteBuffer(buffers[i]);
@@ -995,15 +1037,15 @@
 {
     EVENT("(GLsizei n = %d, const GLuint* fences = 0x%0.8p)", n, fences);
 
-    if (n < 0)
-    {
-        return gl::error(GL_INVALID_VALUE);
-    }
-
     gl::Context *context = gl::getNonLostContext();
-
     if (context)
     {
+        if (n < 0)
+        {
+            context->recordError(gl::Error(GL_INVALID_VALUE));
+            return;
+        }
+
         for (int i = 0; i < n; i++)
         {
             context->deleteFenceNV(fences[i]);
@@ -1015,15 +1057,15 @@
 {
     EVENT("(GLsizei n = %d, const GLuint* framebuffers = 0x%0.8p)", n, framebuffers);
 
-    if (n < 0)
-    {
-        return gl::error(GL_INVALID_VALUE);
-    }
-
     gl::Context *context = gl::getNonLostContext();
-
     if (context)
     {
+        if (n < 0)
+        {
+            context->recordError(gl::Error(GL_INVALID_VALUE));
+            return;
+        }
+
         for (int i = 0; i < n; i++)
         {
             if (framebuffers[i] != 0)
@@ -1038,24 +1080,25 @@
 {
     EVENT("(GLuint program = %d)", program);
 
-    if (program == 0)
-    {
-        return;
-    }
-
     gl::Context *context = gl::getNonLostContext();
-
     if (context)
     {
+        if (program == 0)
+        {
+            return;
+        }
+
         if (!context->getProgram(program))
         {
             if(context->getShader(program))
             {
-                return gl::error(GL_INVALID_OPERATION);
+                context->recordError(gl::Error(GL_INVALID_OPERATION));
+                return;
             }
             else
             {
-                return gl::error(GL_INVALID_VALUE);
+                context->recordError(gl::Error(GL_INVALID_VALUE));
+                return;
             }
         }
 
@@ -1067,15 +1110,15 @@
 {
     EVENT("(GLsizei n = %d, const GLuint *ids = 0x%0.8p)", n, ids);
 
-    if (n < 0)
-    {
-        return gl::error(GL_INVALID_VALUE);
-    }
-
     gl::Context *context = gl::getNonLostContext();
-
     if (context)
     {
+        if (n < 0)
+        {
+            context->recordError(gl::Error(GL_INVALID_VALUE));
+            return;
+        }
+
         for (int i = 0; i < n; i++)
         {
             context->deleteQuery(ids[i]);
@@ -1087,15 +1130,15 @@
 {
     EVENT("(GLsizei n = %d, const GLuint* renderbuffers = 0x%0.8p)", n, renderbuffers);
 
-    if (n < 0)
-    {
-        return gl::error(GL_INVALID_VALUE);
-    }
-
     gl::Context *context = gl::getNonLostContext();
-
     if (context)
     {
+        if (n < 0)
+        {
+            context->recordError(gl::Error(GL_INVALID_VALUE));
+            return;
+        }
+
         for (int i = 0; i < n; i++)
         {
             context->deleteRenderbuffer(renderbuffers[i]);
@@ -1107,24 +1150,25 @@
 {
     EVENT("(GLuint shader = %d)", shader);
 
-    if (shader == 0)
-    {
-        return;
-    }
-
     gl::Context *context = gl::getNonLostContext();
-
     if (context)
     {
+        if (shader == 0)
+        {
+            return;
+        }
+
         if (!context->getShader(shader))
         {
             if(context->getProgram(shader))
             {
-                return gl::error(GL_INVALID_OPERATION);
+                context->recordError(gl::Error(GL_INVALID_OPERATION));
+                return;
             }
             else
             {
-                return gl::error(GL_INVALID_VALUE);
+                context->recordError(gl::Error(GL_INVALID_VALUE));
+                return;
             }
         }
 
@@ -1136,15 +1180,15 @@
 {
     EVENT("(GLsizei n = %d, const GLuint* textures = 0x%0.8p)", n, textures);
 
-    if (n < 0)
-    {
-        return gl::error(GL_INVALID_VALUE);
-    }
-
     gl::Context *context = gl::getNonLostContext();
-
     if (context)
     {
+        if (n < 0)
+        {
+            context->recordError(gl::Error(GL_INVALID_VALUE));
+            return;
+        }
+
         for (int i = 0; i < n; i++)
         {
             if (textures[i] != 0)
@@ -1159,26 +1203,26 @@
 {
     EVENT("(GLenum func = 0x%X)", func);
 
-    switch (func)
-    {
-      case GL_NEVER:
-      case GL_ALWAYS:
-      case GL_LESS:
-      case GL_LEQUAL:
-      case GL_EQUAL:
-      case GL_GREATER:
-      case GL_GEQUAL:
-      case GL_NOTEQUAL:
-        break;
-      default:
-        return gl::error(GL_INVALID_ENUM);
-    }
-
     gl::Context *context = gl::getNonLostContext();
-
     if (context)
     {
-        context->getState().setDepthFunc(func);
+        switch (func)
+        {
+          case GL_NEVER:
+          case GL_ALWAYS:
+          case GL_LESS:
+          case GL_LEQUAL:
+          case GL_EQUAL:
+          case GL_GREATER:
+          case GL_GEQUAL:
+          case GL_NOTEQUAL:
+            context->getState().setDepthFunc(func);
+            break;
+
+          default:
+            context->recordError(gl::Error(GL_INVALID_ENUM));
+            return;
+        }
     }
 }
 
@@ -1187,7 +1231,6 @@
     EVENT("(GLboolean flag = %u)", flag);
 
     gl::Context *context = gl::getNonLostContext();
-
     if (context)
     {
         context->getState().setDepthMask(flag != GL_FALSE);
@@ -1199,7 +1242,6 @@
     EVENT("(GLclampf zNear = %f, GLclampf zFar = %f)", zNear, zFar);
 
     gl::Context *context = gl::getNonLostContext();
-
     if (context)
     {
         context->getState().setDepthRange(zNear, zFar);
@@ -1211,10 +1253,8 @@
     EVENT("(GLuint program = %d, GLuint shader = %d)", program, shader);
 
     gl::Context *context = gl::getNonLostContext();
-
     if (context)
     {
-
         gl::Program *programObject = context->getProgram(program);
         gl::Shader *shaderObject = context->getShader(shader);
 
@@ -1224,11 +1264,13 @@
             shaderByProgramHandle = context->getShader(program);
             if (!shaderByProgramHandle)
             {
-                return gl::error(GL_INVALID_VALUE);
+                context->recordError(gl::Error(GL_INVALID_VALUE));
+                return;
             }
             else
             {
-                return gl::error(GL_INVALID_OPERATION);
+                context->recordError(gl::Error(GL_INVALID_OPERATION));
+                return;
             }
         }
 
@@ -1237,17 +1279,20 @@
             gl::Program *programByShaderHandle = context->getProgram(shader);
             if (!programByShaderHandle)
             {
-                return gl::error(GL_INVALID_VALUE);
+                context->recordError(gl::Error(GL_INVALID_VALUE));
+                return;
             }
             else
             {
-                return gl::error(GL_INVALID_OPERATION);
+                context->recordError(gl::Error(GL_INVALID_OPERATION));
+                return;
             }
         }
 
         if (!programObject->detachShader(shaderObject))
         {
-            return gl::error(GL_INVALID_OPERATION);
+            context->recordError(gl::Error(GL_INVALID_OPERATION));
+            return;
         }
     }
 }
@@ -1257,12 +1302,12 @@
     EVENT("(GLenum cap = 0x%X)", cap);
 
     gl::Context *context = gl::getNonLostContext();
-
     if (context)
     {
         if (!ValidCap(context, cap))
         {
-            return gl::error(GL_INVALID_ENUM);
+            context->recordError(gl::Error(GL_INVALID_ENUM));
+            return;
         }
 
         context->getState().setEnableFeature(cap, false);
@@ -1273,15 +1318,15 @@
 {
     EVENT("(GLuint index = %d)", index);
 
-    if (index >= gl::MAX_VERTEX_ATTRIBS)
-    {
-        return gl::error(GL_INVALID_VALUE);
-    }
-
     gl::Context *context = gl::getNonLostContext();
-
     if (context)
     {
+        if (index >= gl::MAX_VERTEX_ATTRIBS)
+        {
+            context->recordError(gl::Error(GL_INVALID_VALUE));
+            return;
+        }
+
         context->getState().setEnableVertexAttribArray(index, false);
     }
 }
@@ -1291,10 +1336,9 @@
     EVENT("(GLenum mode = 0x%X, GLint first = %d, GLsizei count = %d)", mode, first, count);
 
     gl::Context *context = gl::getNonLostContext();
-
     if (context)
     {
-        if (!ValidateDrawArrays(context, mode, first, count))
+        if (!ValidateDrawArrays(context, mode, first, count, 0))
         {
             return;
         }
@@ -1308,10 +1352,9 @@
     EVENT("(GLenum mode = 0x%X, GLint first = %d, GLsizei count = %d, GLsizei primcount = %d)", mode, first, count, primcount);
 
     gl::Context *context = gl::getNonLostContext();
-
     if (context)
     {
-        if (!ValidateDrawArraysInstanced(context, mode, first, count, primcount))
+        if (!ValidateDrawArraysInstancedANGLE(context, mode, first, count, primcount))
         {
             return;
         }
@@ -1326,15 +1369,15 @@
           mode, count, type, indices);
 
     gl::Context *context = gl::getNonLostContext();
-
     if (context)
     {
-        if (!ValidateDrawElements(context, mode, count, type, indices))
+        rx::RangeUI indexRange;
+        if (!ValidateDrawElements(context, mode, count, type, indices, 0, &indexRange))
         {
             return;
         }
 
-        context->drawElements(mode, count, type, indices, 0);
+        context->drawElements(mode, count, type, indices, 0, indexRange);
     }
 }
 
@@ -1344,15 +1387,15 @@
           mode, count, type, indices, primcount);
 
     gl::Context *context = gl::getNonLostContext();
-
     if (context)
     {
-        if (!ValidateDrawElementsInstanced(context, mode, count, type, indices, primcount))
+        rx::RangeUI indexRange;
+        if (!ValidateDrawElementsInstancedANGLE(context, mode, count, type, indices, primcount, &indexRange))
         {
             return;
         }
 
-        context->drawElements(mode, count, type, indices, primcount);
+        context->drawElements(mode, count, type, indices, primcount, indexRange);
     }
 }
 
@@ -1361,12 +1404,12 @@
     EVENT("(GLenum cap = 0x%X)", cap);
 
     gl::Context *context = gl::getNonLostContext();
-
     if (context)
     {
         if (!ValidCap(context, cap))
         {
-            return gl::error(GL_INVALID_ENUM);
+            context->recordError(gl::Error(GL_INVALID_ENUM));
+            return;
         }
 
         context->getState().setEnableFeature(cap, true);
@@ -1377,15 +1420,15 @@
 {
     EVENT("(GLuint index = %d)", index);
 
-    if (index >= gl::MAX_VERTEX_ATTRIBS)
-    {
-        return gl::error(GL_INVALID_VALUE);
-    }
-
     gl::Context *context = gl::getNonLostContext();
-
     if (context)
     {
+        if (index >= gl::MAX_VERTEX_ATTRIBS)
+        {
+            context->recordError(gl::Error(GL_INVALID_VALUE));
+            return;
+        }
+
         context->getState().setEnableVertexAttribArray(index, true);
     }
 }
@@ -1395,7 +1438,6 @@
     EVENT("GLenum target = 0x%X)", target);
 
     gl::Context *context = gl::getNonLostContext();
-
     if (context)
     {
         if (!ValidateEndQuery(context, target))
@@ -1403,7 +1445,12 @@
             return;
         }
 
-        context->endQuery(target);
+        gl::Error error = context->endQuery(target);
+        if (error.isError())
+        {
+            context->recordError(error);
+            return;
+        }
     }
 }
 
@@ -1412,19 +1459,20 @@
     EVENT("(GLuint fence = %d)", fence);
 
     gl::Context *context = gl::getNonLostContext();
-
     if (context)
     {
         gl::FenceNV *fenceObject = context->getFenceNV(fence);
 
         if (fenceObject == NULL)
         {
-            return gl::error(GL_INVALID_OPERATION);
+            context->recordError(gl::Error(GL_INVALID_OPERATION));
+            return;
         }
 
         if (fenceObject->isFence() != GL_TRUE)
         {
-            return gl::error(GL_INVALID_OPERATION);
+            context->recordError(gl::Error(GL_INVALID_OPERATION));
+            return;
         }
 
         fenceObject->finishFence();
@@ -1436,7 +1484,6 @@
     EVENT("()");
 
     gl::Context *context = gl::getNonLostContext();
-
     if (context)
     {
         context->sync(true);
@@ -1448,7 +1495,6 @@
     EVENT("()");
 
     gl::Context *context = gl::getNonLostContext();
-
     if (context)
     {
         context->sync(false);
@@ -1460,15 +1506,15 @@
     EVENT("(GLenum target = 0x%X, GLenum attachment = 0x%X, GLenum renderbuffertarget = 0x%X, "
           "GLuint renderbuffer = %d)", target, attachment, renderbuffertarget, renderbuffer);
 
-    if (!gl::ValidFramebufferTarget(target) || (renderbuffertarget != GL_RENDERBUFFER && renderbuffer != 0))
-    {
-        return gl::error(GL_INVALID_ENUM);
-    }
-
     gl::Context *context = gl::getNonLostContext();
-
     if (context)
     {
+        if (!gl::ValidFramebufferTarget(target) || (renderbuffertarget != GL_RENDERBUFFER && renderbuffer != 0))
+        {
+            context->recordError(gl::Error(GL_INVALID_ENUM));
+            return;
+        }
+
         if (!gl::ValidateFramebufferRenderbufferParameters(context, target, attachment, renderbuffertarget, renderbuffer))
         {
             return;
@@ -1544,21 +1590,19 @@
 {
     EVENT("(GLenum mode = 0x%X)", mode);
 
-    switch (mode)
+    gl::Context *context = gl::getNonLostContext();
+    if (context)
     {
-      case GL_CW:
-      case GL_CCW:
+        switch (mode)
         {
-            gl::Context *context = gl::getNonLostContext();
-
-            if (context)
-            {
-                context->getState().setFrontFace(mode);
-            }
+          case GL_CW:
+          case GL_CCW:
+            context->getState().setFrontFace(mode);
+            break;
+          default:
+            context->recordError(gl::Error(GL_INVALID_ENUM));
+            return;
         }
-        break;
-      default:
-        return gl::error(GL_INVALID_ENUM);
     }
 }
 
@@ -1566,15 +1610,15 @@
 {
     EVENT("(GLsizei n = %d, GLuint* buffers = 0x%0.8p)", n, buffers);
 
-    if (n < 0)
-    {
-        return gl::error(GL_INVALID_VALUE);
-    }
-
     gl::Context *context = gl::getNonLostContext();
-
     if (context)
     {
+        if (n < 0)
+        {
+            context->recordError(gl::Error(GL_INVALID_VALUE));
+            return;
+        }
+
         for (int i = 0; i < n; i++)
         {
             buffers[i] = context->createBuffer();
@@ -1587,19 +1631,20 @@
     EVENT("(GLenum target = 0x%X)", target);
 
     gl::Context *context = gl::getNonLostContext();
-
     if (context)
     {
         if (!ValidTextureTarget(context, target))
         {
-            return gl::error(GL_INVALID_ENUM);
+            context->recordError(gl::Error(GL_INVALID_ENUM));
+            return;
         }
 
         gl::Texture *texture = context->getTargetTexture(target);
 
         if (texture == NULL)
         {
-            return gl::error(GL_INVALID_OPERATION);
+            context->recordError(gl::Error(GL_INVALID_OPERATION));
+            return;
         }
 
         GLenum internalFormat = texture->getBaseLevelInternalFormat();
@@ -1621,20 +1666,23 @@
         if (formatInfo.depthBits > 0 || formatInfo.stencilBits > 0 || !formatCaps.filterable ||
             (!formatCaps.renderable && !isLUMA) || formatInfo.compressed)
         {
-            return gl::error(GL_INVALID_OPERATION);
+            context->recordError(gl::Error(GL_INVALID_OPERATION));
+            return;
         }
 
         // GL_EXT_sRGB does not support mipmap generation on sRGB textures
         if (context->getClientVersion() == 2 && formatInfo.colorEncoding == GL_SRGB)
         {
-            return gl::error(GL_INVALID_OPERATION);
+            context->recordError(gl::Error(GL_INVALID_OPERATION));
+            return;
         }
 
         // Non-power of 2 ES2 check
         if (!context->getExtensions().textureNPOT && (!gl::isPow2(texture->getBaseLevelWidth()) || !gl::isPow2(texture->getBaseLevelHeight())))
         {
             ASSERT(context->getClientVersion() <= 2 && (target == GL_TEXTURE_2D || target == GL_TEXTURE_CUBE_MAP));
-            return gl::error(GL_INVALID_OPERATION);
+            context->recordError(gl::Error(GL_INVALID_OPERATION));
+            return;
         }
 
         // Cube completeness check
@@ -1643,7 +1691,8 @@
             gl::TextureCubeMap *textureCube = static_cast<gl::TextureCubeMap *>(texture);
             if (!textureCube->isCubeComplete())
             {
-                return gl::error(GL_INVALID_OPERATION);
+                context->recordError(gl::Error(GL_INVALID_OPERATION));
+                return;
             }
         }
 
@@ -1655,15 +1704,15 @@
 {
     EVENT("(GLsizei n = %d, GLuint* fences = 0x%0.8p)", n, fences);
 
-    if (n < 0)
-    {
-        return gl::error(GL_INVALID_VALUE);
-    }
-
     gl::Context *context = gl::getNonLostContext();
-
     if (context)
     {
+        if (n < 0)
+        {
+            context->recordError(gl::Error(GL_INVALID_VALUE));
+            return;
+        }
+
         for (int i = 0; i < n; i++)
         {
             fences[i] = context->createFenceNV();
@@ -1675,15 +1724,15 @@
 {
     EVENT("(GLsizei n = %d, GLuint* framebuffers = 0x%0.8p)", n, framebuffers);
 
-    if (n < 0)
-    {
-        return gl::error(GL_INVALID_VALUE);
-    }
-
     gl::Context *context = gl::getNonLostContext();
-
     if (context)
     {
+        if (n < 0)
+        {
+            context->recordError(gl::Error(GL_INVALID_VALUE));
+            return;
+        }
+
         for (int i = 0; i < n; i++)
         {
             framebuffers[i] = context->createFramebuffer();
@@ -1696,12 +1745,12 @@
     EVENT("(GLsizei n = %d, GLuint* ids = 0x%0.8p)", n, ids);
 
     gl::Context *context = gl::getNonLostContext();
-
     if (context)
     {
         if (n < 0)
         {
-            return gl::error(GL_INVALID_VALUE);
+            context->recordError(gl::Error(GL_INVALID_VALUE));
+            return;
         }
 
         for (GLsizei i = 0; i < n; i++)
@@ -1715,15 +1764,15 @@
 {
     EVENT("(GLsizei n = %d, GLuint* renderbuffers = 0x%0.8p)", n, renderbuffers);
 
-    if (n < 0)
-    {
-        return gl::error(GL_INVALID_VALUE);
-    }
-
     gl::Context *context = gl::getNonLostContext();
-
     if (context)
     {
+        if (n < 0)
+        {
+            context->recordError(gl::Error(GL_INVALID_VALUE));
+            return;
+        }
+
         for (int i = 0; i < n; i++)
         {
             renderbuffers[i] = context->createRenderbuffer();
@@ -1735,15 +1784,15 @@
 {
     EVENT("(GLsizei n = %d, GLuint* textures = 0x%0.8p)", n, textures);
 
-    if (n < 0)
-    {
-        return gl::error(GL_INVALID_VALUE);
-    }
-
     gl::Context *context = gl::getNonLostContext();
-
     if (context)
     {
+        if (n < 0)
+        {
+            context->recordError(gl::Error(GL_INVALID_VALUE));
+            return;
+        }
+
         for (int i = 0; i < n; i++)
         {
             textures[i] = context->createTexture();
@@ -1757,32 +1806,35 @@
           "GLint *size = 0x%0.8p, GLenum *type = %0.8p, GLchar *name = %0.8p)",
           program, index, bufsize, length, size, type, name);
 
-    if (bufsize < 0)
-    {
-        return gl::error(GL_INVALID_VALUE);
-    }
-
     gl::Context *context = gl::getNonLostContext();
-
     if (context)
     {
+        if (bufsize < 0)
+        {
+            context->recordError(gl::Error(GL_INVALID_VALUE));
+            return;
+        }
+
         gl::Program *programObject = context->getProgram(program);
 
         if (!programObject)
         {
             if (context->getShader(program))
             {
-                return gl::error(GL_INVALID_OPERATION);
+                context->recordError(gl::Error(GL_INVALID_OPERATION));
+                return;
             }
             else
             {
-                return gl::error(GL_INVALID_VALUE);
+                context->recordError(gl::Error(GL_INVALID_VALUE));
+                return;
             }
         }
 
         if (index >= (GLuint)programObject->getActiveAttributeCount())
         {
-            return gl::error(GL_INVALID_VALUE);
+            context->recordError(gl::Error(GL_INVALID_VALUE));
+            return;
         }
 
         programObject->getActiveAttribute(index, bufsize, length, size, type, name);
@@ -1795,32 +1847,36 @@
           "GLsizei* length = 0x%0.8p, GLint* size = 0x%0.8p, GLenum* type = 0x%0.8p, GLchar* name = 0x%0.8p)",
           program, index, bufsize, length, size, type, name);
 
-    if (bufsize < 0)
-    {
-        return gl::error(GL_INVALID_VALUE);
-    }
 
     gl::Context *context = gl::getNonLostContext();
-
     if (context)
     {
+        if (bufsize < 0)
+        {
+            context->recordError(gl::Error(GL_INVALID_VALUE));
+            return;
+        }
+
         gl::Program *programObject = context->getProgram(program);
 
         if (!programObject)
         {
             if (context->getShader(program))
             {
-                return gl::error(GL_INVALID_OPERATION);
+                context->recordError(gl::Error(GL_INVALID_OPERATION));
+                return;
             }
             else
             {
-                return gl::error(GL_INVALID_VALUE);
+                context->recordError(gl::Error(GL_INVALID_VALUE));
+                return;
             }
         }
 
         if (index >= (GLuint)programObject->getActiveUniformCount())
         {
-            return gl::error(GL_INVALID_VALUE);
+            context->recordError(gl::Error(GL_INVALID_VALUE));
+            return;
         }
 
         programObject->getActiveUniform(index, bufsize, length, size, type, name);
@@ -1832,26 +1888,28 @@
     EVENT("(GLuint program = %d, GLsizei maxcount = %d, GLsizei* count = 0x%0.8p, GLuint* shaders = 0x%0.8p)",
           program, maxcount, count, shaders);
 
-    if (maxcount < 0)
-    {
-        return gl::error(GL_INVALID_VALUE);
-    }
-
     gl::Context *context = gl::getNonLostContext();
-
     if (context)
     {
+        if (maxcount < 0)
+        {
+            context->recordError(gl::Error(GL_INVALID_VALUE));
+            return;
+        }
+
         gl::Program *programObject = context->getProgram(program);
 
         if (!programObject)
         {
             if (context->getShader(program))
             {
-                return gl::error(GL_INVALID_OPERATION);
+                context->recordError(gl::Error(GL_INVALID_OPERATION));
+                return;
             }
             else
             {
-                return gl::error(GL_INVALID_VALUE);
+                context->recordError(gl::Error(GL_INVALID_VALUE));
+                return;
             }
         }
 
@@ -1859,33 +1917,34 @@
     }
 }
 
-int __stdcall glGetAttribLocation(GLuint program, const GLchar* name)
+GLint __stdcall glGetAttribLocation(GLuint program, const GLchar* name)
 {
     EVENT("(GLuint program = %d, const GLchar* name = %s)", program, name);
 
     gl::Context *context = gl::getNonLostContext();
-
     if (context)
     {
-
         gl::Program *programObject = context->getProgram(program);
 
         if (!programObject)
         {
             if (context->getShader(program))
             {
-                return gl::error(GL_INVALID_OPERATION, -1);
+                context->recordError(gl::Error(GL_INVALID_OPERATION));
+                return -1;
             }
             else
             {
-                return gl::error(GL_INVALID_VALUE, -1);
+                context->recordError(gl::Error(GL_INVALID_VALUE));
+                return -1;
             }
         }
 
         gl::ProgramBinary *programBinary = programObject->getProgramBinary();
         if (!programObject->isLinked() || !programBinary)
         {
-            return gl::error(GL_INVALID_OPERATION, -1);
+            context->recordError(gl::Error(GL_INVALID_OPERATION));
+            return -1;
         }
 
         return programBinary->getAttributeLocation(name);
@@ -1899,7 +1958,6 @@
     EVENT("(GLenum pname = 0x%X, GLboolean* params = 0x%0.8p)",  pname, params);
 
     gl::Context *context = gl::getNonLostContext();
-
     if (context)
     {
         GLenum nativeType;
@@ -1925,17 +1983,18 @@
     EVENT("(GLenum target = 0x%X, GLenum pname = 0x%X, GLint* params = 0x%0.8p)", target, pname, params);
 
     gl::Context *context = gl::getNonLostContext();
-
     if (context)
     {
         if (!gl::ValidBufferTarget(context, target))
         {
-            return gl::error(GL_INVALID_ENUM);
+            context->recordError(gl::Error(GL_INVALID_ENUM));
+            return;
         }
 
         if (!gl::ValidBufferParameter(context, pname))
         {
-            return gl::error(GL_INVALID_ENUM);
+            context->recordError(gl::Error(GL_INVALID_ENUM));
+            return;
         }
 
         gl::Buffer *buffer = context->getState().getTargetBuffer(target);
@@ -1943,7 +2002,8 @@
         if (!buffer)
         {
             // A null buffer means that "0" is bound to the requested buffer target
-            return gl::error(GL_INVALID_OPERATION);
+            context->recordError(gl::Error(GL_INVALID_OPERATION));
+            return;
         }
 
         switch (pname)
@@ -1989,21 +2049,21 @@
 {
     EVENT("(GLuint fence = %d, GLenum pname = 0x%X, GLint *params = 0x%0.8p)", fence, pname, params);
 
-
     gl::Context *context = gl::getNonLostContext();
-
     if (context)
     {
         gl::FenceNV *fenceObject = context->getFenceNV(fence);
 
         if (fenceObject == NULL)
         {
-            return gl::error(GL_INVALID_OPERATION);
+            context->recordError(gl::Error(GL_INVALID_OPERATION));
+            return;
         }
 
         if (fenceObject->isFence() != GL_TRUE)
         {
-            return gl::error(GL_INVALID_OPERATION);
+            context->recordError(gl::Error(GL_INVALID_OPERATION));
+            return;
         }
 
         switch (pname)
@@ -2012,7 +2072,9 @@
           case GL_FENCE_CONDITION_NV:
             break;
 
-          default: return gl::error(GL_INVALID_ENUM);
+          default:
+            context->recordError(gl::Error(GL_INVALID_ENUM));
+            return;
         }
 
         params[0] = fenceObject->getFencei(pname);
@@ -2024,7 +2086,6 @@
     EVENT("(GLenum pname = 0x%X, GLfloat* params = 0x%0.8p)", pname, params);
 
     gl::Context *context = gl::getNonLostContext();
-
     if (context)
     {
         GLenum nativeType;
@@ -2051,12 +2112,12 @@
           target, attachment, pname, params);
 
     gl::Context *context = gl::getNonLostContext();
-
     if (context)
     {
         if (!gl::ValidFramebufferTarget(target))
         {
-            return gl::error(GL_INVALID_ENUM);
+            context->recordError(gl::Error(GL_INVALID_ENUM));
+            return;
         }
 
         int clientVersion = context->getClientVersion();
@@ -2068,12 +2129,15 @@
           case GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL:
           case GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE:
             break;
+
           case GL_FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING:
             if (clientVersion < 3 && !context->getExtensions().sRGB)
             {
-                return gl::error(GL_INVALID_ENUM);
+                context->recordError(gl::Error(GL_INVALID_ENUM));
+                return;
             }
             break;
+
           case GL_FRAMEBUFFER_ATTACHMENT_RED_SIZE:
           case GL_FRAMEBUFFER_ATTACHMENT_GREEN_SIZE:
           case GL_FRAMEBUFFER_ATTACHMENT_BLUE_SIZE:
@@ -2084,11 +2148,14 @@
           case GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LAYER:
             if (clientVersion < 3)
             {
-                return gl::error(GL_INVALID_ENUM);
+                context->recordError(gl::Error(GL_INVALID_ENUM));
+                return;
             }
             break;
+
           default:
-            return gl::error(GL_INVALID_ENUM);
+            context->recordError(gl::Error(GL_INVALID_ENUM));
+            return;
         }
 
         // Determine if the attachment is a valid enum
@@ -2101,7 +2168,8 @@
           case GL_DEPTH_STENCIL_ATTACHMENT:
             if (clientVersion < 3)
             {
-                return gl::error(GL_INVALID_ENUM);
+                context->recordError(gl::Error(GL_INVALID_ENUM));
+                return;
             }
             break;
 
@@ -2113,7 +2181,8 @@
             if (attachment < GL_COLOR_ATTACHMENT0_EXT ||
                 (attachment - GL_COLOR_ATTACHMENT0_EXT) >= context->getCaps().maxColorAttachments)
             {
-                return gl::error(GL_INVALID_ENUM);
+                context->recordError(gl::Error(GL_INVALID_ENUM));
+                return;
             }
             break;
         }
@@ -2125,7 +2194,8 @@
         {
             if (clientVersion < 3)
             {
-                return gl::error(GL_INVALID_OPERATION);
+                context->recordError(gl::Error(GL_INVALID_OPERATION));
+                return;
             }
 
             switch (attachment)
@@ -2134,8 +2204,10 @@
               case GL_DEPTH:
               case GL_STENCIL:
                 break;
+
               default:
-                return gl::error(GL_INVALID_OPERATION);
+                context->recordError(gl::Error(GL_INVALID_OPERATION));
+                return;
             }
         }
         else
@@ -2151,14 +2223,18 @@
                   case GL_DEPTH_ATTACHMENT:
                   case GL_STENCIL_ATTACHMENT:
                     break;
+
                   case GL_DEPTH_STENCIL_ATTACHMENT:
                     if (framebuffer->hasValidDepthStencil())
                     {
-                        return gl::error(GL_INVALID_OPERATION);
+                        context->recordError(gl::Error(GL_INVALID_OPERATION));
+                        return;
                     }
                     break;
+
                   default:
-                    return gl::error(GL_INVALID_OPERATION);
+                    context->recordError(gl::Error(GL_INVALID_OPERATION));
+                    return;
                 }
             }
         }
@@ -2215,7 +2291,8 @@
               case GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME:
                 if (clientVersion < 3)
                 {
-                    return gl::error(GL_INVALID_ENUM);
+                    context->recordError(gl::Error(GL_INVALID_ENUM));
+                    return;
                 }
                 *params = 0;
                 break;
@@ -2223,11 +2300,13 @@
               default:
                 if (clientVersion < 3)
                 {
-                    return gl::error(GL_INVALID_ENUM);
+                    context->recordError(gl::Error(GL_INVALID_ENUM));
+                    return;
                 }
                 else
                 {
-                    gl::error(GL_INVALID_OPERATION);
+                    context->recordError(gl::Error(GL_INVALID_OPERATION));
+                    return;
                 }
             }
         }
@@ -2246,7 +2325,8 @@
               case GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME:
                 if (attachmentObjectType != GL_RENDERBUFFER && attachmentObjectType != GL_TEXTURE)
                 {
-                    return gl::error(GL_INVALID_ENUM);
+                    context->recordError(gl::Error(GL_INVALID_ENUM));
+                    return;
                 }
                 *params = attachmentHandle;
                 break;
@@ -2254,7 +2334,8 @@
               case GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL:
                 if (attachmentObjectType != GL_TEXTURE)
                 {
-                    return gl::error(GL_INVALID_ENUM);
+                    context->recordError(gl::Error(GL_INVALID_ENUM));
+                    return;
                 }
                 *params = attachmentLevel;
                 break;
@@ -2262,7 +2343,8 @@
               case GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE:
                 if (attachmentObjectType != GL_TEXTURE)
                 {
-                    return gl::error(GL_INVALID_ENUM);
+                    context->recordError(gl::Error(GL_INVALID_ENUM));
+                    return;
                 }
                 *params = gl::IsCubemapTextureTarget(attachmentType) ? attachmentType : 0;
                 break;
@@ -2292,9 +2374,10 @@
                 break;
 
               case GL_FRAMEBUFFER_ATTACHMENT_COMPONENT_TYPE:
-                if (attachment == GL_DEPTH_STENCIL)
+                if (attachment == GL_DEPTH_STENCIL_ATTACHMENT)
                 {
-                    gl::error(GL_INVALID_OPERATION);
+                    context->recordError(gl::Error(GL_INVALID_OPERATION));
+                    return;
                 }
                 *params = attachmentObject->getComponentType();
                 break;
@@ -2306,7 +2389,8 @@
               case GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LAYER:
                 if (attachmentObjectType != GL_TEXTURE)
                 {
-                    return gl::error(GL_INVALID_ENUM);
+                    context->recordError(gl::Error(GL_INVALID_ENUM));
+                    return;
                 }
                 *params = attachmentLayer;
                 break;
@@ -2338,7 +2422,6 @@
     EVENT("(GLenum pname = 0x%X, GLint* params = 0x%0.8p)", pname, params);
 
     gl::Context *context = gl::getNonLostContext();
-
     if (context)
     {
         GLenum nativeType;
@@ -2365,14 +2448,14 @@
     EVENT("(GLuint program = %d, GLenum pname = %d, GLint* params = 0x%0.8p)", program, pname, params);
 
     gl::Context *context = gl::getNonLostContext();
-
     if (context)
     {
         gl::Program *programObject = context->getProgram(program);
 
         if (!programObject)
         {
-            return gl::error(GL_INVALID_VALUE);
+            context->recordError(gl::Error(GL_INVALID_VALUE));
+            return;
         }
 
         if (context->getClientVersion() < 3)
@@ -2384,7 +2467,8 @@
               case GL_TRANSFORM_FEEDBACK_BUFFER_MODE:
               case GL_TRANSFORM_FEEDBACK_VARYINGS:
               case GL_TRANSFORM_FEEDBACK_VARYING_MAX_LENGTH:
-                return gl::error(GL_INVALID_ENUM);
+                context->recordError(gl::Error(GL_INVALID_ENUM));
+                return;
             }
         }
 
@@ -2435,8 +2519,10 @@
           case GL_TRANSFORM_FEEDBACK_VARYING_MAX_LENGTH:
             *params = programObject->getTransformFeedbackVaryingMaxLength();
             break;
+
           default:
-            return gl::error(GL_INVALID_ENUM);
+            context->recordError(gl::Error(GL_INVALID_ENUM));
+            return;
         }
     }
 }
@@ -2446,20 +2532,21 @@
     EVENT("(GLuint program = %d, GLsizei bufsize = %d, GLsizei* length = 0x%0.8p, GLchar* infolog = 0x%0.8p)",
           program, bufsize, length, infolog);
 
-    if (bufsize < 0)
-    {
-        return gl::error(GL_INVALID_VALUE);
-    }
-
     gl::Context *context = gl::getNonLostContext();
-
     if (context)
     {
+        if (bufsize < 0)
+        {
+            context->recordError(gl::Error(GL_INVALID_VALUE));
+            return;
+        }
+
         gl::Program *programObject = context->getProgram(program);
 
         if (!programObject)
         {
-            return gl::error(GL_INVALID_VALUE);
+            context->recordError(gl::Error(GL_INVALID_VALUE));
+            return;
         }
 
         programObject->getInfoLog(bufsize, length, infolog);
@@ -2471,12 +2558,12 @@
     EVENT("GLenum target = 0x%X, GLenum pname = 0x%X, GLint *params = 0x%0.8p)", target, pname, params);
 
     gl::Context *context = gl::getNonLostContext();
-
     if (context)
     {
         if (!ValidQueryType(context, target))
         {
-            return gl::error(GL_INVALID_ENUM);
+            context->recordError(gl::Error(GL_INVALID_ENUM));
+            return;
         }
 
         switch (pname)
@@ -2486,7 +2573,8 @@
             break;
 
           default:
-            return gl::error(GL_INVALID_ENUM);
+            context->recordError(gl::Error(GL_INVALID_ENUM));
+            return;
         }
     }
 }
@@ -2496,31 +2584,49 @@
     EVENT("(GLuint id = %d, GLenum pname = 0x%X, GLuint *params = 0x%0.8p)", id, pname, params);
 
     gl::Context *context = gl::getNonLostContext();
-
     if (context)
     {
         gl::Query *queryObject = context->getQuery(id, false, GL_NONE);
 
         if (!queryObject)
         {
-            return gl::error(GL_INVALID_OPERATION);
+            context->recordError(gl::Error(GL_INVALID_OPERATION));
+            return;
         }
 
         if (context->getState().getActiveQueryId(queryObject->getType()) == id)
         {
-            return gl::error(GL_INVALID_OPERATION);
+            context->recordError(gl::Error(GL_INVALID_OPERATION));
+            return;
         }
 
         switch(pname)
         {
           case GL_QUERY_RESULT_EXT:
-            params[0] = queryObject->getResult();
+            {
+                gl::Error error = queryObject->getResult(params);
+                if (error.isError())
+                {
+                    context->recordError(error);
+                    return;
+                }
+            }
             break;
+
           case GL_QUERY_RESULT_AVAILABLE_EXT:
-            params[0] = queryObject->isResultAvailable();
+            {
+                gl::Error error = queryObject->isResultAvailable(params);
+                if (error.isError())
+                {
+                    context->recordError(error);
+                    return;
+                }
+            }
             break;
+
           default:
-            return gl::error(GL_INVALID_ENUM);
+            context->recordError(gl::Error(GL_INVALID_ENUM));
+            return;
         }
     }
 }
@@ -2530,17 +2636,18 @@
     EVENT("(GLenum target = 0x%X, GLenum pname = 0x%X, GLint* params = 0x%0.8p)", target, pname, params);
 
     gl::Context *context = gl::getNonLostContext();
-
     if (context)
     {
         if (target != GL_RENDERBUFFER)
         {
-            return gl::error(GL_INVALID_ENUM);
+            context->recordError(gl::Error(GL_INVALID_ENUM));
+            return;
         }
 
         if (context->getState().getRenderbufferId() == 0)
         {
-            return gl::error(GL_INVALID_OPERATION);
+            context->recordError(gl::Error(GL_INVALID_OPERATION));
+            return;
         }
 
         gl::Renderbuffer *renderbuffer = context->getRenderbuffer(context->getState().getRenderbufferId());
@@ -2556,15 +2663,19 @@
           case GL_RENDERBUFFER_ALPHA_SIZE:      *params = renderbuffer->getAlphaSize();      break;
           case GL_RENDERBUFFER_DEPTH_SIZE:      *params = renderbuffer->getDepthSize();      break;
           case GL_RENDERBUFFER_STENCIL_SIZE:    *params = renderbuffer->getStencilSize();    break;
+
           case GL_RENDERBUFFER_SAMPLES_ANGLE:
             if (!context->getExtensions().framebufferMultisample)
             {
-                return gl::error(GL_INVALID_ENUM);
+                context->recordError(gl::Error(GL_INVALID_ENUM));
+                return;
             }
             *params = renderbuffer->getSamples();
             break;
+
           default:
-            return gl::error(GL_INVALID_ENUM);
+            context->recordError(gl::Error(GL_INVALID_ENUM));
+            return;
         }
     }
 }
@@ -2574,14 +2685,14 @@
     EVENT("(GLuint shader = %d, GLenum pname = %d, GLint* params = 0x%0.8p)", shader, pname, params);
 
     gl::Context *context = gl::getNonLostContext();
-
     if (context)
     {
         gl::Shader *shaderObject = context->getShader(shader);
 
         if (!shaderObject)
         {
-            return gl::error(GL_INVALID_VALUE);
+            context->recordError(gl::Error(GL_INVALID_VALUE));
+            return;
         }
 
         switch (pname)
@@ -2604,8 +2715,10 @@
           case GL_TRANSLATED_SHADER_SOURCE_LENGTH_ANGLE:
             *params = shaderObject->getTranslatedSourceLength();
             return;
+
           default:
-            return gl::error(GL_INVALID_ENUM);
+            context->recordError(gl::Error(GL_INVALID_ENUM));
+            return;
         }
     }
 }
@@ -2615,20 +2728,21 @@
     EVENT("(GLuint shader = %d, GLsizei bufsize = %d, GLsizei* length = 0x%0.8p, GLchar* infolog = 0x%0.8p)",
           shader, bufsize, length, infolog);
 
-    if (bufsize < 0)
-    {
-        return gl::error(GL_INVALID_VALUE);
-    }
-
     gl::Context *context = gl::getNonLostContext();
-
     if (context)
     {
+        if (bufsize < 0)
+        {
+            context->recordError(gl::Error(GL_INVALID_VALUE));
+            return;
+        }
+
         gl::Shader *shaderObject = context->getShader(shader);
 
         if (!shaderObject)
         {
-            return gl::error(GL_INVALID_VALUE);
+            context->recordError(gl::Error(GL_INVALID_VALUE));
+            return;
         }
 
         shaderObject->getInfoLog(bufsize, length, infolog);
@@ -2640,36 +2754,45 @@
     EVENT("(GLenum shadertype = 0x%X, GLenum precisiontype = 0x%X, GLint* range = 0x%0.8p, GLint* precision = 0x%0.8p)",
           shadertype, precisiontype, range, precision);
 
-    switch (shadertype)
+    gl::Context *context = gl::getNonLostContext();
+    if (context)
     {
-      case GL_VERTEX_SHADER:
-      case GL_FRAGMENT_SHADER:
-        break;
-      default:
-        return gl::error(GL_INVALID_ENUM);
-    }
+        switch (shadertype)
+        {
+          case GL_VERTEX_SHADER:
+          case GL_FRAGMENT_SHADER:
+            break;
 
-    switch (precisiontype)
-    {
-      case GL_LOW_FLOAT:
-      case GL_MEDIUM_FLOAT:
-      case GL_HIGH_FLOAT:
-        // Assume IEEE 754 precision
-        range[0] = 127;
-        range[1] = 127;
-        *precision = 23;
-        break;
-      case GL_LOW_INT:
-      case GL_MEDIUM_INT:
-      case GL_HIGH_INT:
-        // Some (most) hardware only supports single-precision floating-point numbers,
-        // which can accurately represent integers up to +/-16777216
-        range[0] = 24;
-        range[1] = 24;
-        *precision = 0;
-        break;
-      default:
-        return gl::error(GL_INVALID_ENUM);
+          default:
+            context->recordError(gl::Error(GL_INVALID_ENUM));
+            return;
+        }
+
+        switch (precisiontype)
+        {
+          case GL_LOW_FLOAT:
+          case GL_MEDIUM_FLOAT:
+          case GL_HIGH_FLOAT:
+            // Assume IEEE 754 precision
+            range[0] = 127;
+            range[1] = 127;
+            *precision = 23;
+            break;
+
+          case GL_LOW_INT:
+          case GL_MEDIUM_INT:
+          case GL_HIGH_INT:
+            // Some (most) hardware only supports single-precision floating-point numbers,
+            // which can accurately represent integers up to +/-16777216
+            range[0] = 24;
+            range[1] = 24;
+            *precision = 0;
+            break;
+
+          default:
+            context->recordError(gl::Error(GL_INVALID_ENUM));
+            return;
+        }
     }
 }
 
@@ -2678,20 +2801,21 @@
     EVENT("(GLuint shader = %d, GLsizei bufsize = %d, GLsizei* length = 0x%0.8p, GLchar* source = 0x%0.8p)",
           shader, bufsize, length, source);
 
-    if (bufsize < 0)
-    {
-        return gl::error(GL_INVALID_VALUE);
-    }
-
     gl::Context *context = gl::getNonLostContext();
-
     if (context)
     {
+        if (bufsize < 0)
+        {
+            context->recordError(gl::Error(GL_INVALID_VALUE));
+            return;
+        }
+
         gl::Shader *shaderObject = context->getShader(shader);
 
         if (!shaderObject)
         {
-            return gl::error(GL_INVALID_OPERATION);
+            context->recordError(gl::Error(GL_INVALID_OPERATION));
+            return;
         }
 
         shaderObject->getSource(bufsize, length, source);
@@ -2703,20 +2827,21 @@
     EVENT("(GLuint shader = %d, GLsizei bufsize = %d, GLsizei* length = 0x%0.8p, GLchar* source = 0x%0.8p)",
           shader, bufsize, length, source);
 
-    if (bufsize < 0)
-    {
-        return gl::error(GL_INVALID_VALUE);
-    }
-
     gl::Context *context = gl::getNonLostContext();
-
     if (context)
     {
+        if (bufsize < 0)
+        {
+            context->recordError(gl::Error(GL_INVALID_VALUE));
+            return;
+        }
+
         gl::Shader *shaderObject = context->getShader(shader);
 
         if (!shaderObject)
         {
-            return gl::error(GL_INVALID_OPERATION);
+            context->recordError(gl::Error(GL_INVALID_OPERATION));
+            return;
         }
 
         shaderObject->getTranslatedSource(bufsize, length, source);
@@ -2733,8 +2858,10 @@
     {
       case GL_VENDOR:
         return (GLubyte*)"Google Inc.";
+
       case GL_RENDERER:
         return (GLubyte*)((context != NULL) ? context->getRendererString().c_str() : "ANGLE");
+
       case GL_VERSION:
         if (context->getClientVersion() == 2)
         {
@@ -2744,6 +2871,7 @@
         {
             return (GLubyte*)"OpenGL ES 3.0 (ANGLE " ANGLE_VERSION_STRING ")";
         }
+
       case GL_SHADING_LANGUAGE_VERSION:
         if (context->getClientVersion() == 2)
         {
@@ -2753,10 +2881,16 @@
         {
             return (GLubyte*)"OpenGL ES GLSL ES 3.00 (ANGLE " ANGLE_VERSION_STRING ")";
         }
+
       case GL_EXTENSIONS:
         return (GLubyte*)((context != NULL) ? context->getExtensionString().c_str() : "");
+
       default:
-        return gl::error(GL_INVALID_ENUM, (GLubyte*)NULL);
+        if (context)
+        {
+            context->recordError(gl::Error(GL_INVALID_ENUM));
+        }
+        return NULL;
     }
 }
 
@@ -2765,14 +2899,14 @@
     EVENT("(GLenum target = 0x%X, GLenum pname = 0x%X, GLfloat* params = 0x%0.8p)", target, pname, params);
 
     gl::Context *context = gl::getNonLostContext();
-
     if (context)
     {
         gl::Texture *texture = context->getTargetTexture(target);
 
         if (!texture)
         {
-            return gl::error(GL_INVALID_ENUM);
+            context->recordError(gl::Error(GL_INVALID_ENUM));
+            return;
         }
 
         switch (pname)
@@ -2792,7 +2926,8 @@
           case GL_TEXTURE_WRAP_R:
             if (context->getClientVersion() < 3)
             {
-                return gl::error(GL_INVALID_ENUM);
+                context->recordError(gl::Error(GL_INVALID_ENUM));
+                return;
             }
             *params = (GLfloat)texture->getSamplerState().wrapR;
             break;
@@ -2803,7 +2938,8 @@
           case GL_TEXTURE_IMMUTABLE_LEVELS:
             if (context->getClientVersion() < 3)
             {
-                return gl::error(GL_INVALID_ENUM);
+                context->recordError(gl::Error(GL_INVALID_ENUM));
+                return;
             }
             *params = (GLfloat)texture->immutableLevelCount();
             break;
@@ -2813,68 +2949,79 @@
           case GL_TEXTURE_MAX_ANISOTROPY_EXT:
             if (!context->getExtensions().textureFilterAnisotropic)
             {
-                return gl::error(GL_INVALID_ENUM);
+                context->recordError(gl::Error(GL_INVALID_ENUM));
+                return;
             }
             *params = (GLfloat)texture->getSamplerState().maxAnisotropy;
             break;
           case GL_TEXTURE_SWIZZLE_R:
             if (context->getClientVersion() < 3)
             {
-                return gl::error(GL_INVALID_ENUM);
+                context->recordError(gl::Error(GL_INVALID_ENUM));
+                return;
             }
             *params = (GLfloat)texture->getSamplerState().swizzleRed;
             break;
           case GL_TEXTURE_SWIZZLE_G:
             if (context->getClientVersion() < 3)
             {
-                return gl::error(GL_INVALID_ENUM);
+                context->recordError(gl::Error(GL_INVALID_ENUM));
+                return;
             }
             *params = (GLfloat)texture->getSamplerState().swizzleGreen;
             break;
           case GL_TEXTURE_SWIZZLE_B:
             if (context->getClientVersion() < 3)
             {
-                return gl::error(GL_INVALID_ENUM);
+                context->recordError(gl::Error(GL_INVALID_ENUM));
+                return;
             }
             *params = (GLfloat)texture->getSamplerState().swizzleBlue;
             break;
           case GL_TEXTURE_SWIZZLE_A:
             if (context->getClientVersion() < 3)
             {
-                return gl::error(GL_INVALID_ENUM);
+                context->recordError(gl::Error(GL_INVALID_ENUM));
+                return;
             }
             *params = (GLfloat)texture->getSamplerState().swizzleAlpha;
             break;
           case GL_TEXTURE_BASE_LEVEL:
             if (context->getClientVersion() < 3)
             {
-                return gl::error(GL_INVALID_ENUM);
+                context->recordError(gl::Error(GL_INVALID_ENUM));
+                return;
             }
             *params = (GLfloat)texture->getSamplerState().baseLevel;
             break;
           case GL_TEXTURE_MAX_LEVEL:
             if (context->getClientVersion() < 3)
             {
-                return gl::error(GL_INVALID_ENUM);
+                context->recordError(gl::Error(GL_INVALID_ENUM));
+                return;
             }
             *params = (GLfloat)texture->getSamplerState().maxLevel;
             break;
           case GL_TEXTURE_MIN_LOD:
             if (context->getClientVersion() < 3)
             {
-                return gl::error(GL_INVALID_ENUM);
+                context->recordError(gl::Error(GL_INVALID_ENUM));
+                return;
             }
             *params = texture->getSamplerState().minLod;
             break;
           case GL_TEXTURE_MAX_LOD:
             if (context->getClientVersion() < 3)
             {
-                return gl::error(GL_INVALID_ENUM);
+                context->recordError(gl::Error(GL_INVALID_ENUM));
+                return;
             }
             *params = texture->getSamplerState().maxLod;
             break;
+
           default:
-            return gl::error(GL_INVALID_ENUM);
+            context->recordError(gl::Error(GL_INVALID_ENUM));
+            return;
         }
     }
 }
@@ -2884,14 +3031,14 @@
     EVENT("(GLenum target = 0x%X, GLenum pname = 0x%X, GLint* params = 0x%0.8p)", target, pname, params);
 
     gl::Context *context = gl::getNonLostContext();
-
     if (context)
     {
         gl::Texture *texture = context->getTargetTexture(target);
 
         if (!texture)
         {
-            return gl::error(GL_INVALID_ENUM);
+            context->recordError(gl::Error(GL_INVALID_ENUM));
+            return;
         }
 
         switch (pname)
@@ -2911,7 +3058,8 @@
           case GL_TEXTURE_WRAP_R:
             if (context->getClientVersion() < 3)
             {
-                return gl::error(GL_INVALID_ENUM);
+                context->recordError(gl::Error(GL_INVALID_ENUM));
+                return;
             }
             *params = texture->getSamplerState().wrapR;
             break;
@@ -2922,7 +3070,8 @@
           case GL_TEXTURE_IMMUTABLE_LEVELS:
             if (context->getClientVersion() < 3)
             {
-                return gl::error(GL_INVALID_ENUM);
+                context->recordError(gl::Error(GL_INVALID_ENUM));
+                return;
             }
             *params = texture->immutableLevelCount();
             break;
@@ -2932,68 +3081,79 @@
           case GL_TEXTURE_MAX_ANISOTROPY_EXT:
             if (!context->getExtensions().textureFilterAnisotropic)
             {
-                return gl::error(GL_INVALID_ENUM);
+                context->recordError(gl::Error(GL_INVALID_ENUM));
+                return;
             }
             *params = (GLint)texture->getSamplerState().maxAnisotropy;
             break;
           case GL_TEXTURE_SWIZZLE_R:
             if (context->getClientVersion() < 3)
             {
-                return gl::error(GL_INVALID_ENUM);
+                context->recordError(gl::Error(GL_INVALID_ENUM));
+                return;
             }
             *params = texture->getSamplerState().swizzleRed;
             break;
           case GL_TEXTURE_SWIZZLE_G:
             if (context->getClientVersion() < 3)
             {
-                return gl::error(GL_INVALID_ENUM);
+                context->recordError(gl::Error(GL_INVALID_ENUM));
+                return;
             }
             *params = texture->getSamplerState().swizzleGreen;
             break;
           case GL_TEXTURE_SWIZZLE_B:
             if (context->getClientVersion() < 3)
             {
-                return gl::error(GL_INVALID_ENUM);
+                context->recordError(gl::Error(GL_INVALID_ENUM));
+                return;
             }
             *params = texture->getSamplerState().swizzleBlue;
             break;
           case GL_TEXTURE_SWIZZLE_A:
             if (context->getClientVersion() < 3)
             {
-                return gl::error(GL_INVALID_ENUM);
+                context->recordError(gl::Error(GL_INVALID_ENUM));
+                return;
             }
             *params = texture->getSamplerState().swizzleAlpha;
             break;
           case GL_TEXTURE_BASE_LEVEL:
             if (context->getClientVersion() < 3)
             {
-                return gl::error(GL_INVALID_ENUM);
+                context->recordError(gl::Error(GL_INVALID_ENUM));
+                return;
             }
             *params = texture->getSamplerState().baseLevel;
             break;
           case GL_TEXTURE_MAX_LEVEL:
             if (context->getClientVersion() < 3)
             {
-                return gl::error(GL_INVALID_ENUM);
+                context->recordError(gl::Error(GL_INVALID_ENUM));
+                return;
             }
             *params = texture->getSamplerState().maxLevel;
             break;
           case GL_TEXTURE_MIN_LOD:
             if (context->getClientVersion() < 3)
             {
-                return gl::error(GL_INVALID_ENUM);
+                context->recordError(gl::Error(GL_INVALID_ENUM));
+                return;
             }
             *params = (GLint)texture->getSamplerState().minLod;
             break;
           case GL_TEXTURE_MAX_LOD:
             if (context->getClientVersion() < 3)
             {
-                return gl::error(GL_INVALID_ENUM);
+                context->recordError(gl::Error(GL_INVALID_ENUM));
+                return;
             }
             *params = (GLint)texture->getSamplerState().maxLod;
             break;
+
           default:
-            return gl::error(GL_INVALID_ENUM);
+            context->recordError(gl::Error(GL_INVALID_ENUM));
+            return;
         }
     }
 }
@@ -3003,37 +3163,20 @@
     EVENT("(GLuint program = %d, GLint location = %d, GLsizei bufSize = %d, GLfloat* params = 0x%0.8p)",
           program, location, bufSize, params);
 
-    if (bufSize < 0)
-    {
-        return gl::error(GL_INVALID_VALUE);
-    }
-
     gl::Context *context = gl::getNonLostContext();
-
     if (context)
     {
-        if (program == 0)
+        if (!ValidateGetnUniformfvEXT(context, program, location, bufSize, params))
         {
-            return gl::error(GL_INVALID_VALUE);
+            return;
         }
 
         gl::Program *programObject = context->getProgram(program);
-
-        if (!programObject || !programObject->isLinked())
-        {
-            return gl::error(GL_INVALID_OPERATION);
-        }
-
+        ASSERT(programObject);
         gl::ProgramBinary *programBinary = programObject->getProgramBinary();
-        if (!programBinary)
-        {
-            return gl::error(GL_INVALID_OPERATION);
-        }
+        ASSERT(programBinary);
 
-        if (!programBinary->getUniformfv(location, &bufSize, params))
-        {
-            return gl::error(GL_INVALID_OPERATION);
-        }
+        programBinary->getUniformfv(location, params);
     }
 }
 
@@ -3042,31 +3185,19 @@
     EVENT("(GLuint program = %d, GLint location = %d, GLfloat* params = 0x%0.8p)", program, location, params);
 
     gl::Context *context = gl::getNonLostContext();
-
     if (context)
     {
-        if (program == 0)
+        if (!ValidateGetUniformfv(context, program, location, params))
         {
-            return gl::error(GL_INVALID_VALUE);
+            return;
         }
 
         gl::Program *programObject = context->getProgram(program);
-
-        if (!programObject || !programObject->isLinked())
-        {
-            return gl::error(GL_INVALID_OPERATION);
-        }
-
+        ASSERT(programObject);
         gl::ProgramBinary *programBinary = programObject->getProgramBinary();
-        if (!programBinary)
-        {
-            return gl::error(GL_INVALID_OPERATION);
-        }
+        ASSERT(programBinary);
 
-        if (!programBinary->getUniformfv(location, NULL, params))
-        {
-            return gl::error(GL_INVALID_OPERATION);
-        }
+        programBinary->getUniformfv(location, params);
     }
 }
 
@@ -3075,37 +3206,20 @@
     EVENT("(GLuint program = %d, GLint location = %d, GLsizei bufSize = %d, GLint* params = 0x%0.8p)",
           program, location, bufSize, params);
 
-    if (bufSize < 0)
-    {
-        return gl::error(GL_INVALID_VALUE);
-    }
-
     gl::Context *context = gl::getNonLostContext();
-
     if (context)
     {
-        if (program == 0)
+        if (!ValidateGetnUniformivEXT(context, program, location, bufSize, params))
         {
-            return gl::error(GL_INVALID_VALUE);
+            return;
         }
 
         gl::Program *programObject = context->getProgram(program);
-
-        if (!programObject || !programObject->isLinked())
-        {
-            return gl::error(GL_INVALID_OPERATION);
-        }
-
+        ASSERT(programObject);
         gl::ProgramBinary *programBinary = programObject->getProgramBinary();
-        if (!programBinary)
-        {
-            return gl::error(GL_INVALID_OPERATION);
-        }
+        ASSERT(programBinary);
 
-        if (!programBinary->getUniformiv(location, &bufSize, params))
-        {
-            return gl::error(GL_INVALID_OPERATION);
-        }
+        programBinary->getUniformiv(location, params);
     }
 }
 
@@ -3114,65 +3228,55 @@
     EVENT("(GLuint program = %d, GLint location = %d, GLint* params = 0x%0.8p)", program, location, params);
 
     gl::Context *context = gl::getNonLostContext();
-
     if (context)
     {
-        if (program == 0)
+        if (!ValidateGetUniformiv(context, program, location, params))
         {
-            return gl::error(GL_INVALID_VALUE);
+            return;
         }
 
         gl::Program *programObject = context->getProgram(program);
-
-        if (!programObject || !programObject->isLinked())
-        {
-            return gl::error(GL_INVALID_OPERATION);
-        }
-
+        ASSERT(programObject);
         gl::ProgramBinary *programBinary = programObject->getProgramBinary();
-        if (!programBinary)
-        {
-            return gl::error(GL_INVALID_OPERATION);
-        }
+        ASSERT(programBinary);
 
-        if (!programBinary->getUniformiv(location, NULL, params))
-        {
-            return gl::error(GL_INVALID_OPERATION);
-        }
+        programBinary->getUniformiv(location, params);
     }
 }
 
-int __stdcall glGetUniformLocation(GLuint program, const GLchar* name)
+GLint __stdcall glGetUniformLocation(GLuint program, const GLchar* name)
 {
     EVENT("(GLuint program = %d, const GLchar* name = 0x%0.8p)", program, name);
 
     gl::Context *context = gl::getNonLostContext();
-
-    if (strstr(name, "gl_") == name)
-    {
-        return -1;
-    }
-
     if (context)
     {
+        if (strstr(name, "gl_") == name)
+        {
+            return -1;
+        }
+
         gl::Program *programObject = context->getProgram(program);
 
         if (!programObject)
         {
             if (context->getShader(program))
             {
-                return gl::error(GL_INVALID_OPERATION, -1);
+                context->recordError(gl::Error(GL_INVALID_OPERATION));
+                return -1;
             }
             else
             {
-                return gl::error(GL_INVALID_VALUE, -1);
+                context->recordError(gl::Error(GL_INVALID_VALUE));
+                return -1;
             }
         }
 
         gl::ProgramBinary *programBinary = programObject->getProgramBinary();
         if (!programObject->isLinked() || !programBinary)
         {
-            return gl::error(GL_INVALID_OPERATION, -1);
+            context->recordError(gl::Error(GL_INVALID_OPERATION));
+            return -1;
         }
 
         return programBinary->getUniformLocation(name);
@@ -3186,16 +3290,16 @@
     EVENT("(GLuint index = %d, GLenum pname = 0x%X, GLfloat* params = 0x%0.8p)", index, pname, params);
 
     gl::Context *context = gl::getNonLostContext();
-
     if (context)
     {
         if (index >= gl::MAX_VERTEX_ATTRIBS)
         {
-            return gl::error(GL_INVALID_VALUE);
+            context->recordError(gl::Error(GL_INVALID_VALUE));
+            return;
         }
 
         const gl::VertexAttribute &attribState = context->getState().getVertexAttribState(index);
-        if (!gl::ValidateGetVertexAttribParameters(pname, context->getClientVersion()))
+        if (!gl::ValidateGetVertexAttribParameters(context, pname))
         {
             return;
         }
@@ -3220,17 +3324,17 @@
     EVENT("(GLuint index = %d, GLenum pname = 0x%X, GLint* params = 0x%0.8p)", index, pname, params);
 
     gl::Context *context = gl::getNonLostContext();
-
     if (context)
     {
         if (index >= gl::MAX_VERTEX_ATTRIBS)
         {
-            return gl::error(GL_INVALID_VALUE);
+            context->recordError(gl::Error(GL_INVALID_VALUE));
+            return;
         }
 
         const gl::VertexAttribute &attribState = context->getState().getVertexAttribState(index);
 
-        if (!gl::ValidateGetVertexAttribParameters(pname, context->getClientVersion()))
+        if (!gl::ValidateGetVertexAttribParameters(context, pname))
         {
             return;
         }
@@ -3256,17 +3360,18 @@
     EVENT("(GLuint index = %d, GLenum pname = 0x%X, GLvoid** pointer = 0x%0.8p)", index, pname, pointer);
 
     gl::Context *context = gl::getNonLostContext();
-
     if (context)
     {
         if (index >= gl::MAX_VERTEX_ATTRIBS)
         {
-            return gl::error(GL_INVALID_VALUE);
+            context->recordError(gl::Error(GL_INVALID_VALUE));
+            return;
         }
 
         if (pname != GL_VERTEX_ATTRIB_ARRAY_POINTER)
         {
-            return gl::error(GL_INVALID_ENUM);
+            context->recordError(gl::Error(GL_INVALID_ENUM));
+            return;
         }
 
         *pointer = const_cast<GLvoid*>(context->getState().getVertexAttribPointer(index));
@@ -3277,27 +3382,35 @@
 {
     EVENT("(GLenum target = 0x%X, GLenum mode = 0x%X)", target, mode);
 
-    switch (mode)
-    {
-      case GL_FASTEST:
-      case GL_NICEST:
-      case GL_DONT_CARE:
-        break;
-      default:
-        return gl::error(GL_INVALID_ENUM);
-    }
-
     gl::Context *context = gl::getNonLostContext();
-    switch (target)
+    if (context)
     {
-      case GL_GENERATE_MIPMAP_HINT:
-        if (context) context->getState().setGenerateMipmapHint(mode);
-        break;
-      case GL_FRAGMENT_SHADER_DERIVATIVE_HINT_OES:
-        if (context) context->getState().setFragmentShaderDerivativeHint(mode);
-        break;
-      default:
-        return gl::error(GL_INVALID_ENUM);
+        switch (mode)
+        {
+          case GL_FASTEST:
+          case GL_NICEST:
+          case GL_DONT_CARE:
+            break;
+
+          default:
+            context->recordError(gl::Error(GL_INVALID_ENUM));
+            return;
+        }
+
+        switch (target)
+        {
+          case GL_GENERATE_MIPMAP_HINT:
+            context->getState().setGenerateMipmapHint(mode);
+            break;
+
+          case GL_FRAGMENT_SHADER_DERIVATIVE_HINT_OES:
+            context->getState().setFragmentShaderDerivativeHint(mode);
+            break;
+
+          default:
+            context->recordError(gl::Error(GL_INVALID_ENUM));
+            return;
+        }
     }
 }
 
@@ -3306,7 +3419,6 @@
     EVENT("(GLuint buffer = %d)", buffer);
 
     gl::Context *context = gl::getNonLostContext();
-
     if (context && buffer)
     {
         gl::Buffer *bufferObject = context->getBuffer(buffer);
@@ -3325,12 +3437,12 @@
     EVENT("(GLenum cap = 0x%X)", cap);
 
     gl::Context *context = gl::getNonLostContext();
-
     if (context)
     {
         if (!ValidCap(context, cap))
         {
-            return gl::error(GL_INVALID_ENUM, false);
+            context->recordError(gl::Error(GL_INVALID_ENUM));
+            return GL_FALSE;
         }
 
         return context->getState().getEnableFeature(cap);
@@ -3344,7 +3456,6 @@
     EVENT("(GLuint fence = %d)", fence);
 
     gl::Context *context = gl::getNonLostContext();
-
     if (context)
     {
         gl::FenceNV *fenceObject = context->getFenceNV(fence);
@@ -3365,7 +3476,6 @@
     EVENT("(GLuint framebuffer = %d)", framebuffer);
 
     gl::Context *context = gl::getNonLostContext();
-
     if (context && framebuffer)
     {
         gl::Framebuffer *framebufferObject = context->getFramebuffer(framebuffer);
@@ -3384,7 +3494,6 @@
     EVENT("(GLuint program = %d)", program);
 
     gl::Context *context = gl::getNonLostContext();
-
     if (context && program)
     {
         gl::Program *programObject = context->getProgram(program);
@@ -3403,7 +3512,6 @@
     EVENT("(GLuint id = %d)", id);
 
     gl::Context *context = gl::getNonLostContext();
-
     if (context)
     {
         return (context->getQuery(id, false, GL_NONE) != NULL) ? GL_TRUE : GL_FALSE;
@@ -3417,7 +3525,6 @@
     EVENT("(GLuint renderbuffer = %d)", renderbuffer);
 
     gl::Context *context = gl::getNonLostContext();
-
     if (context && renderbuffer)
     {
         gl::Renderbuffer *renderbufferObject = context->getRenderbuffer(renderbuffer);
@@ -3436,7 +3543,6 @@
     EVENT("(GLuint shader = %d)", shader);
 
     gl::Context *context = gl::getNonLostContext();
-
     if (context && shader)
     {
         gl::Shader *shaderObject = context->getShader(shader);
@@ -3455,7 +3561,6 @@
     EVENT("(GLuint texture = %d)", texture);
 
     gl::Context *context = gl::getNonLostContext();
-
     if (context && texture)
     {
         gl::Texture *textureObject = context->getTexture(texture);
@@ -3473,15 +3578,15 @@
 {
     EVENT("(GLfloat width = %f)", width);
 
-    if (width <= 0.0f)
-    {
-        return gl::error(GL_INVALID_VALUE);
-    }
-
     gl::Context *context = gl::getNonLostContext();
-
     if (context)
     {
+        if (width <= 0.0f)
+        {
+            context->recordError(gl::Error(GL_INVALID_VALUE));
+            return;
+        }
+
         context->getState().setLineWidth(width);
     }
 }
@@ -3491,7 +3596,6 @@
     EVENT("(GLuint program = %d)", program);
 
     gl::Context *context = gl::getNonLostContext();
-
     if (context)
     {
         gl::Program *programObject = context->getProgram(program);
@@ -3500,11 +3604,13 @@
         {
             if (context->getShader(program))
             {
-                return gl::error(GL_INVALID_OPERATION);
+                context->recordError(gl::Error(GL_INVALID_OPERATION));
+                return;
             }
             else
             {
-                return gl::error(GL_INVALID_VALUE);
+                context->recordError(gl::Error(GL_INVALID_VALUE));
+                return;
             }
         }
 
@@ -3517,7 +3623,6 @@
     EVENT("(GLenum pname = 0x%X, GLint param = %d)", pname, param);
 
     gl::Context *context = gl::getNonLostContext();
-
     if (context)
     {
         switch (pname)
@@ -3525,7 +3630,8 @@
           case GL_UNPACK_ALIGNMENT:
             if (param != 1 && param != 2 && param != 4 && param != 8)
             {
-                return gl::error(GL_INVALID_VALUE);
+                context->recordError(gl::Error(GL_INVALID_VALUE));
+                return;
             }
 
             context->getState().setUnpackAlignment(param);
@@ -3534,7 +3640,8 @@
           case GL_PACK_ALIGNMENT:
             if (param != 1 && param != 2 && param != 4 && param != 8)
             {
-                return gl::error(GL_INVALID_VALUE);
+                context->recordError(gl::Error(GL_INVALID_VALUE));
+                return;
             }
 
             context->getState().setPackAlignment(param);
@@ -3554,13 +3661,15 @@
           case GL_PACK_SKIP_PIXELS:
             if (context->getClientVersion() < 3)
             {
-                return gl::error(GL_INVALID_ENUM);
+                context->recordError(gl::Error(GL_INVALID_ENUM));
+                return;
             }
             UNIMPLEMENTED();
             break;
 
           default:
-            return gl::error(GL_INVALID_ENUM);
+            context->recordError(gl::Error(GL_INVALID_ENUM));
+            return;
         }
     }
 }
@@ -3570,7 +3679,6 @@
     EVENT("(GLfloat factor = %f, GLfloat units = %f)", factor, units);
 
     gl::Context *context = gl::getNonLostContext();
-
     if (context)
     {
         context->getState().setPolygonOffsetParams(factor, units);
@@ -3585,22 +3693,27 @@
           "GLenum format = 0x%X, GLenum type = 0x%X, GLsizei bufSize = 0x%d, GLvoid *data = 0x%0.8p)",
           x, y, width, height, format, type, bufSize, data);
 
-    if (width < 0 || height < 0 || bufSize < 0)
-    {
-        return gl::error(GL_INVALID_VALUE);
-    }
-
     gl::Context *context = gl::getNonLostContext();
-
     if (context)
     {
+        if (width < 0 || height < 0 || bufSize < 0)
+        {
+            context->recordError(gl::Error(GL_INVALID_VALUE));
+            return;
+        }
+
         if (!gl::ValidateReadPixelsParameters(context, x, y, width, height,
                                               format, type, &bufSize, data))
         {
             return;
         }
 
-        context->readPixels(x, y, width, height, format, type, &bufSize, data);
+        gl::Error error = context->readPixels(x, y, width, height, format, type, &bufSize, data);
+        if (error.isError())
+        {
+            context->recordError(error);
+            return;
+        }
     }
 }
 
@@ -3611,22 +3724,27 @@
           "GLenum format = 0x%X, GLenum type = 0x%X, GLvoid* pixels = 0x%0.8p)",
           x, y, width, height, format, type,  pixels);
 
-    if (width < 0 || height < 0)
-    {
-        return gl::error(GL_INVALID_VALUE);
-    }
-
     gl::Context *context = gl::getNonLostContext();
-
     if (context)
     {
+        if (width < 0 || height < 0)
+        {
+            context->recordError(gl::Error(GL_INVALID_VALUE));
+            return;
+        }
+
         if (!gl::ValidateReadPixelsParameters(context, x, y, width, height,
                                               format, type, NULL, pixels))
         {
             return;
         }
 
-        context->readPixels(x, y, width, height, format, type, NULL, pixels);
+        gl::Error error = context->readPixels(x, y, width, height, format, type, NULL, pixels);
+        if (error.isError())
+        {
+            context->recordError(error);
+            return;
+        }
     }
 }
 
@@ -3634,7 +3752,12 @@
 {
     EVENT("()");
 
-    gl::Shader::releaseCompiler();
+    gl::Context *context = gl::getNonLostContext();
+
+    if (context)
+    {
+        context->releaseShaderCompiler();
+    }
 }
 
 void __stdcall glRenderbufferStorageMultisampleANGLE(GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height)
@@ -3643,7 +3766,6 @@
           target, samples, internalformat, width, height);
 
     gl::Context *context = gl::getNonLostContext();
-
     if (context)
     {
         if (!ValidateRenderbufferStorageParameters(context, target, samples, internalformat,
@@ -3677,20 +3799,21 @@
 {
     EVENT("(GLuint fence = %d, GLenum condition = 0x%X)", fence, condition);
 
-    if (condition != GL_ALL_COMPLETED_NV)
-    {
-        return gl::error(GL_INVALID_ENUM);
-    }
-
     gl::Context *context = gl::getNonLostContext();
-
     if (context)
     {
+        if (condition != GL_ALL_COMPLETED_NV)
+        {
+            context->recordError(gl::Error(GL_INVALID_ENUM));
+            return;
+        }
+
         gl::FenceNV *fenceObject = context->getFenceNV(fence);
 
         if (fenceObject == NULL)
         {
-            return gl::error(GL_INVALID_OPERATION);
+            context->recordError(gl::Error(GL_INVALID_OPERATION));
+            return;
         }
 
         fenceObject->setFence(condition);
@@ -3701,15 +3824,15 @@
 {
     EVENT("(GLint x = %d, GLint y = %d, GLsizei width = %d, GLsizei height = %d)", x, y, width, height);
 
-    if (width < 0 || height < 0)
-    {
-        return gl::error(GL_INVALID_VALUE);
-    }
-
     gl::Context* context = gl::getNonLostContext();
-
     if (context)
     {
+        if (width < 0 || height < 0)
+        {
+            context->recordError(gl::Error(GL_INVALID_VALUE));
+            return;
+        }
+
         context->getState().setScissorParams(x, y, width, height);
     }
 }
@@ -3720,8 +3843,19 @@
           "const GLvoid* binary = 0x%0.8p, GLsizei length = %d)",
           n, shaders, binaryformat, binary, length);
 
-    // No binary shader formats are supported.
-    return gl::error(GL_INVALID_ENUM);
+    gl::Context* context = gl::getNonLostContext();
+    if (context)
+    {
+        const std::vector<GLenum> &shaderBinaryFormats = context->getCaps().shaderBinaryFormats;
+        if (std::find(shaderBinaryFormats.begin(), shaderBinaryFormats.end(), binaryformat) == shaderBinaryFormats.end())
+        {
+            context->recordError(gl::Error(GL_INVALID_ENUM));
+            return;
+        }
+
+        // No binary shader formats are supported.
+        UNIMPLEMENTED();
+    }
 }
 
 void __stdcall glShaderSource(GLuint shader, GLsizei count, const GLchar* const* string, const GLint* length)
@@ -3729,26 +3863,28 @@
     EVENT("(GLuint shader = %d, GLsizei count = %d, const GLchar** string = 0x%0.8p, const GLint* length = 0x%0.8p)",
           shader, count, string, length);
 
-    if (count < 0)
-    {
-        return gl::error(GL_INVALID_VALUE);
-    }
-
     gl::Context *context = gl::getNonLostContext();
-
     if (context)
     {
+        if (count < 0)
+        {
+            context->recordError(gl::Error(GL_INVALID_VALUE));
+            return;
+        }
+
         gl::Shader *shaderObject = context->getShader(shader);
 
         if (!shaderObject)
         {
             if (context->getProgram(shader))
             {
-                return gl::error(GL_INVALID_OPERATION);
+                context->recordError(gl::Error(GL_INVALID_OPERATION));
+                return;
             }
             else
             {
-                return gl::error(GL_INVALID_VALUE);
+                context->recordError(gl::Error(GL_INVALID_VALUE));
+                return;
             }
         }
 
@@ -3765,35 +3901,38 @@
 {
     EVENT("(GLenum face = 0x%X, GLenum func = 0x%X, GLint ref = %d, GLuint mask = %d)", face, func, ref, mask);
 
-    switch (face)
-    {
-      case GL_FRONT:
-      case GL_BACK:
-      case GL_FRONT_AND_BACK:
-        break;
-      default:
-        return gl::error(GL_INVALID_ENUM);
-    }
-
-    switch (func)
-    {
-      case GL_NEVER:
-      case GL_ALWAYS:
-      case GL_LESS:
-      case GL_LEQUAL:
-      case GL_EQUAL:
-      case GL_GEQUAL:
-      case GL_GREATER:
-      case GL_NOTEQUAL:
-        break;
-      default:
-        return gl::error(GL_INVALID_ENUM);
-    }
-
     gl::Context *context = gl::getNonLostContext();
-
     if (context)
     {
+        switch (face)
+        {
+          case GL_FRONT:
+          case GL_BACK:
+          case GL_FRONT_AND_BACK:
+            break;
+
+          default:
+            context->recordError(gl::Error(GL_INVALID_ENUM));
+            return;
+        }
+
+        switch (func)
+        {
+          case GL_NEVER:
+          case GL_ALWAYS:
+          case GL_LESS:
+          case GL_LEQUAL:
+          case GL_EQUAL:
+          case GL_GEQUAL:
+          case GL_GREATER:
+          case GL_NOTEQUAL:
+            break;
+
+          default:
+            context->recordError(gl::Error(GL_INVALID_ENUM));
+            return;
+        }
+
         if (face == GL_FRONT || face == GL_FRONT_AND_BACK)
         {
             context->getState().setStencilParams(func, ref, mask);
@@ -3815,20 +3954,21 @@
 {
     EVENT("(GLenum face = 0x%X, GLuint mask = %d)", face, mask);
 
-    switch (face)
-    {
-      case GL_FRONT:
-      case GL_BACK:
-      case GL_FRONT_AND_BACK:
-        break;
-      default:
-        return gl::error(GL_INVALID_ENUM);
-    }
-
     gl::Context *context = gl::getNonLostContext();
-
     if (context)
     {
+        switch (face)
+        {
+          case GL_FRONT:
+          case GL_BACK:
+          case GL_FRONT_AND_BACK:
+            break;
+
+          default:
+            context->recordError(gl::Error(GL_INVALID_ENUM));
+            return;
+        }
+
         if (face == GL_FRONT || face == GL_FRONT_AND_BACK)
         {
             context->getState().setStencilWritemask(mask);
@@ -3851,65 +3991,72 @@
     EVENT("(GLenum face = 0x%X, GLenum fail = 0x%X, GLenum zfail = 0x%X, GLenum zpas = 0x%Xs)",
           face, fail, zfail, zpass);
 
-    switch (face)
-    {
-      case GL_FRONT:
-      case GL_BACK:
-      case GL_FRONT_AND_BACK:
-        break;
-      default:
-        return gl::error(GL_INVALID_ENUM);
-    }
-
-    switch (fail)
-    {
-      case GL_ZERO:
-      case GL_KEEP:
-      case GL_REPLACE:
-      case GL_INCR:
-      case GL_DECR:
-      case GL_INVERT:
-      case GL_INCR_WRAP:
-      case GL_DECR_WRAP:
-        break;
-      default:
-        return gl::error(GL_INVALID_ENUM);
-    }
-
-    switch (zfail)
-    {
-      case GL_ZERO:
-      case GL_KEEP:
-      case GL_REPLACE:
-      case GL_INCR:
-      case GL_DECR:
-      case GL_INVERT:
-      case GL_INCR_WRAP:
-      case GL_DECR_WRAP:
-        break;
-      default:
-        return gl::error(GL_INVALID_ENUM);
-    }
-
-    switch (zpass)
-    {
-      case GL_ZERO:
-      case GL_KEEP:
-      case GL_REPLACE:
-      case GL_INCR:
-      case GL_DECR:
-      case GL_INVERT:
-      case GL_INCR_WRAP:
-      case GL_DECR_WRAP:
-        break;
-      default:
-        return gl::error(GL_INVALID_ENUM);
-    }
-
     gl::Context *context = gl::getNonLostContext();
-
     if (context)
     {
+        switch (face)
+        {
+          case GL_FRONT:
+          case GL_BACK:
+          case GL_FRONT_AND_BACK:
+            break;
+
+          default:
+            context->recordError(gl::Error(GL_INVALID_ENUM));
+            return;
+        }
+
+        switch (fail)
+        {
+          case GL_ZERO:
+          case GL_KEEP:
+          case GL_REPLACE:
+          case GL_INCR:
+          case GL_DECR:
+          case GL_INVERT:
+          case GL_INCR_WRAP:
+          case GL_DECR_WRAP:
+            break;
+
+          default:
+            context->recordError(gl::Error(GL_INVALID_ENUM));
+            return;
+        }
+
+        switch (zfail)
+        {
+          case GL_ZERO:
+          case GL_KEEP:
+          case GL_REPLACE:
+          case GL_INCR:
+          case GL_DECR:
+          case GL_INVERT:
+          case GL_INCR_WRAP:
+          case GL_DECR_WRAP:
+            break;
+
+          default:
+            context->recordError(gl::Error(GL_INVALID_ENUM));
+            return;
+        }
+
+        switch (zpass)
+        {
+          case GL_ZERO:
+          case GL_KEEP:
+          case GL_REPLACE:
+          case GL_INCR:
+          case GL_DECR:
+          case GL_INVERT:
+          case GL_INCR_WRAP:
+          case GL_DECR_WRAP:
+            break;
+
+          default:
+            context->recordError(gl::Error(GL_INVALID_ENUM));
+            return;
+        }
+
         if (face == GL_FRONT || face == GL_FRONT_AND_BACK)
         {
             context->getState().setStencilOperations(fail, zfail, zpass);
@@ -3927,19 +4074,20 @@
     EVENT("(GLuint fence = %d)", fence);
 
     gl::Context *context = gl::getNonLostContext();
-
     if (context)
     {
         gl::FenceNV *fenceObject = context->getFenceNV(fence);
 
         if (fenceObject == NULL)
         {
-            return gl::error(GL_INVALID_OPERATION, GL_TRUE);
+            context->recordError(gl::Error(GL_INVALID_OPERATION));
+            return GL_TRUE;
         }
 
         if (fenceObject->isFence() != GL_TRUE)
         {
-            return gl::error(GL_INVALID_OPERATION, GL_TRUE);
+            context->recordError(gl::Error(GL_INVALID_OPERATION));
+            return GL_TRUE;
         }
 
         return fenceObject->testFence();
@@ -3956,7 +4104,6 @@
           target, level, internalformat, width, height, border, format, type, pixels);
 
     gl::Context *context = gl::getNonLostContext();
-
     if (context)
     {
         if (context->getClientVersion() < 3 &&
@@ -4027,7 +4174,6 @@
     EVENT("(GLenum target = 0x%X, GLenum pname = 0x%X, GLint param = %f)", target, pname, param);
 
     gl::Context *context = gl::getNonLostContext();
-
     if (context)
     {
         if (!ValidateTexParamParameters(context, pname, static_cast<GLint>(param)))
@@ -4039,7 +4185,8 @@
 
         if (!texture)
         {
-            return gl::error(GL_INVALID_ENUM);
+            context->recordError(gl::Error(GL_INVALID_ENUM));
+            return;
         }
 
         switch (pname)
@@ -4076,7 +4223,6 @@
     EVENT("(GLenum target = 0x%X, GLenum pname = 0x%X, GLint param = %d)", target, pname, param);
 
     gl::Context *context = gl::getNonLostContext();
-
     if (context)
     {
         if (!ValidateTexParamParameters(context, pname, param))
@@ -4088,7 +4234,8 @@
 
         if (!texture)
         {
-            return gl::error(GL_INVALID_ENUM);
+            context->recordError(gl::Error(GL_INVALID_ENUM));
+            return;
         }
 
         switch (pname)
@@ -4126,12 +4273,12 @@
            target, levels, internalformat, width, height);
 
     gl::Context *context = gl::getNonLostContext();
-
     if (context)
     {
         if (!context->getExtensions().textureStorage)
         {
-            return gl::error(GL_INVALID_OPERATION);
+            context->recordError(gl::Error(GL_INVALID_OPERATION));
+            return;
         }
 
         if (context->getClientVersion() < 3 &&
@@ -4163,7 +4310,8 @@
             break;
 
           default:
-            return gl::error(GL_INVALID_ENUM);
+            context->recordError(gl::Error(GL_INVALID_ENUM));
+            return;
         }
     }
 }
@@ -4177,7 +4325,6 @@
            target, level, xoffset, yoffset, width, height, format, type, pixels);
 
     gl::Context *context = gl::getNonLostContext();
-
     if (context)
     {
         if (context->getClientVersion() < 3 &&
@@ -4237,7 +4384,6 @@
     EVENT("(GLint location = %d, GLsizei count = %d, const GLfloat* v = 0x%0.8p)", location, count, v);
 
     gl::Context *context = gl::getNonLostContext();
-
     if (context)
     {
         if (!ValidateUniform(context, GL_FLOAT, location, count))
@@ -4260,7 +4406,6 @@
     EVENT("(GLint location = %d, GLsizei count = %d, const GLint* v = 0x%0.8p)", location, count, v);
 
     gl::Context *context = gl::getNonLostContext();
-
     if (context)
     {
         if (!ValidateUniform(context, GL_INT, location, count))
@@ -4285,7 +4430,6 @@
     EVENT("(GLint location = %d, GLsizei count = %d, const GLfloat* v = 0x%0.8p)", location, count, v);
 
     gl::Context *context = gl::getNonLostContext();
-
     if (context)
     {
         if (!ValidateUniform(context, GL_FLOAT_VEC2, location, count))
@@ -4310,7 +4454,6 @@
     EVENT("(GLint location = %d, GLsizei count = %d, const GLint* v = 0x%0.8p)", location, count, v);
 
     gl::Context *context = gl::getNonLostContext();
-
     if (context)
     {
         if (!ValidateUniform(context, GL_INT_VEC2, location, count))
@@ -4335,7 +4478,6 @@
     EVENT("(GLint location = %d, GLsizei count = %d, const GLfloat* v = 0x%0.8p)", location, count, v);
 
     gl::Context *context = gl::getNonLostContext();
-
     if (context)
     {
         if (!ValidateUniform(context, GL_FLOAT_VEC3, location, count))
@@ -4360,7 +4502,6 @@
     EVENT("(GLint location = %d, GLsizei count = %d, const GLint* v = 0x%0.8p)", location, count, v);
 
     gl::Context *context = gl::getNonLostContext();
-
     if (context)
     {
         if (!ValidateUniform(context, GL_INT_VEC3, location, count))
@@ -4385,7 +4526,6 @@
     EVENT("(GLint location = %d, GLsizei count = %d, const GLfloat* v = 0x%0.8p)", location, count, v);
 
     gl::Context *context = gl::getNonLostContext();
-
     if (context)
     {
         if (!ValidateUniform(context, GL_FLOAT_VEC4, location, count))
@@ -4410,7 +4550,6 @@
     EVENT("(GLint location = %d, GLsizei count = %d, const GLint* v = 0x%0.8p)", location, count, v);
 
     gl::Context *context = gl::getNonLostContext();
-
     if (context)
     {
         if (!ValidateUniform(context, GL_INT_VEC4, location, count))
@@ -4429,7 +4568,6 @@
           location, count, transpose, value);
 
     gl::Context *context = gl::getNonLostContext();
-
     if (context)
     {
         if (!ValidateUniformMatrix(context, GL_FLOAT_MAT2, location, count, transpose))
@@ -4448,7 +4586,6 @@
           location, count, transpose, value);
 
     gl::Context *context = gl::getNonLostContext();
-
     if (context)
     {
         if (!ValidateUniformMatrix(context, GL_FLOAT_MAT3, location, count, transpose))
@@ -4467,7 +4604,6 @@
           location, count, transpose, value);
 
     gl::Context *context = gl::getNonLostContext();
-
     if (context)
     {
         if (!ValidateUniformMatrix(context, GL_FLOAT_MAT4, location, count, transpose))
@@ -4485,7 +4621,6 @@
     EVENT("(GLuint program = %d)", program);
 
     gl::Context *context = gl::getNonLostContext();
-
     if (context)
     {
         gl::Program *programObject = context->getProgram(program);
@@ -4494,17 +4629,20 @@
         {
             if (context->getShader(program))
             {
-                return gl::error(GL_INVALID_OPERATION);
+                context->recordError(gl::Error(GL_INVALID_OPERATION));
+                return;
             }
             else
             {
-                return gl::error(GL_INVALID_VALUE);
+                context->recordError(gl::Error(GL_INVALID_VALUE));
+                return;
             }
         }
 
         if (program != 0 && !programObject->isLinked())
         {
-            return gl::error(GL_INVALID_OPERATION);
+            context->recordError(gl::Error(GL_INVALID_OPERATION));
+            return;
         }
 
         context->useProgram(program);
@@ -4516,7 +4654,6 @@
     EVENT("(GLuint program = %d)", program);
 
     gl::Context *context = gl::getNonLostContext();
-
     if (context)
     {
         gl::Program *programObject = context->getProgram(program);
@@ -4525,15 +4662,17 @@
         {
             if (context->getShader(program))
             {
-                return gl::error(GL_INVALID_OPERATION);
+                context->recordError(gl::Error(GL_INVALID_OPERATION));
+                return;
             }
             else
             {
-                return gl::error(GL_INVALID_VALUE);
+                context->recordError(gl::Error(GL_INVALID_VALUE));
+                return;
             }
         }
 
-        programObject->validate();
+        programObject->validate(context->getCaps());
     }
 }
 
@@ -4541,15 +4680,15 @@
 {
     EVENT("(GLuint index = %d, GLfloat x = %f)", index, x);
 
-    if (index >= gl::MAX_VERTEX_ATTRIBS)
-    {
-        return gl::error(GL_INVALID_VALUE);
-    }
-
     gl::Context *context = gl::getNonLostContext();
-
     if (context)
     {
+        if (index >= gl::MAX_VERTEX_ATTRIBS)
+        {
+            context->recordError(gl::Error(GL_INVALID_VALUE));
+            return;
+        }
+
         GLfloat vals[4] = { x, 0, 0, 1 };
         context->getState().setVertexAttribf(index, vals);
     }
@@ -4559,15 +4698,15 @@
 {
     EVENT("(GLuint index = %d, const GLfloat* values = 0x%0.8p)", index, values);
 
-    if (index >= gl::MAX_VERTEX_ATTRIBS)
-    {
-        return gl::error(GL_INVALID_VALUE);
-    }
-
     gl::Context *context = gl::getNonLostContext();
-
     if (context)
     {
+        if (index >= gl::MAX_VERTEX_ATTRIBS)
+        {
+            context->recordError(gl::Error(GL_INVALID_VALUE));
+            return;
+        }
+
         GLfloat vals[4] = { values[0], 0, 0, 1 };
         context->getState().setVertexAttribf(index, vals);
     }
@@ -4577,15 +4716,15 @@
 {
     EVENT("(GLuint index = %d, GLfloat x = %f, GLfloat y = %f)", index, x, y);
 
-    if (index >= gl::MAX_VERTEX_ATTRIBS)
-    {
-        return gl::error(GL_INVALID_VALUE);
-    }
-
     gl::Context *context = gl::getNonLostContext();
-
     if (context)
     {
+        if (index >= gl::MAX_VERTEX_ATTRIBS)
+        {
+            context->recordError(gl::Error(GL_INVALID_VALUE));
+            return;
+        }
+
         GLfloat vals[4] = { x, y, 0, 1 };
         context->getState().setVertexAttribf(index, vals);
     }
@@ -4595,15 +4734,15 @@
 {
     EVENT("(GLuint index = %d, const GLfloat* values = 0x%0.8p)", index, values);
 
-    if (index >= gl::MAX_VERTEX_ATTRIBS)
-    {
-        return gl::error(GL_INVALID_VALUE);
-    }
-
     gl::Context *context = gl::getNonLostContext();
-
     if (context)
     {
+        if (index >= gl::MAX_VERTEX_ATTRIBS)
+        {
+            context->recordError(gl::Error(GL_INVALID_VALUE));
+            return;
+        }
+
         GLfloat vals[4] = { values[0], values[1], 0, 1 };
         context->getState().setVertexAttribf(index, vals);
     }
@@ -4613,15 +4752,15 @@
 {
     EVENT("(GLuint index = %d, GLfloat x = %f, GLfloat y = %f, GLfloat z = %f)", index, x, y, z);
 
-    if (index >= gl::MAX_VERTEX_ATTRIBS)
-    {
-        return gl::error(GL_INVALID_VALUE);
-    }
-
     gl::Context *context = gl::getNonLostContext();
-
     if (context)
     {
+        if (index >= gl::MAX_VERTEX_ATTRIBS)
+        {
+            context->recordError(gl::Error(GL_INVALID_VALUE));
+            return;
+        }
+
         GLfloat vals[4] = { x, y, z, 1 };
         context->getState().setVertexAttribf(index, vals);
     }
@@ -4631,15 +4770,15 @@
 {
     EVENT("(GLuint index = %d, const GLfloat* values = 0x%0.8p)", index, values);
 
-    if (index >= gl::MAX_VERTEX_ATTRIBS)
-    {
-        return gl::error(GL_INVALID_VALUE);
-    }
-
     gl::Context *context = gl::getNonLostContext();
-
     if (context)
     {
+        if (index >= gl::MAX_VERTEX_ATTRIBS)
+        {
+            context->recordError(gl::Error(GL_INVALID_VALUE));
+            return;
+        }
+
         GLfloat vals[4] = { values[0], values[1], values[2], 1 };
         context->getState().setVertexAttribf(index, vals);
     }
@@ -4649,15 +4788,15 @@
 {
     EVENT("(GLuint index = %d, GLfloat x = %f, GLfloat y = %f, GLfloat z = %f, GLfloat w = %f)", index, x, y, z, w);
 
-    if (index >= gl::MAX_VERTEX_ATTRIBS)
-    {
-        return gl::error(GL_INVALID_VALUE);
-    }
-
     gl::Context *context = gl::getNonLostContext();
-
     if (context)
     {
+        if (index >= gl::MAX_VERTEX_ATTRIBS)
+        {
+            context->recordError(gl::Error(GL_INVALID_VALUE));
+            return;
+        }
+
         GLfloat vals[4] = { x, y, z, w };
         context->getState().setVertexAttribf(index, vals);
     }
@@ -4667,15 +4806,15 @@
 {
     EVENT("(GLuint index = %d, const GLfloat* values = 0x%0.8p)", index, values);
 
-    if (index >= gl::MAX_VERTEX_ATTRIBS)
-    {
-        return gl::error(GL_INVALID_VALUE);
-    }
-
     gl::Context *context = gl::getNonLostContext();
-
     if (context)
     {
+        if (index >= gl::MAX_VERTEX_ATTRIBS)
+        {
+            context->recordError(gl::Error(GL_INVALID_VALUE));
+            return;
+        }
+
         context->getState().setVertexAttribf(index, values);
     }
 }
@@ -4684,15 +4823,15 @@
 {
     EVENT("(GLuint index = %d, GLuint divisor = %d)", index, divisor);
 
-    if (index >= gl::MAX_VERTEX_ATTRIBS)
-    {
-        return gl::error(GL_INVALID_VALUE);
-    }
-
     gl::Context *context = gl::getNonLostContext();
-
     if (context)
     {
+        if (index >= gl::MAX_VERTEX_ATTRIBS)
+        {
+            context->recordError(gl::Error(GL_INVALID_VALUE));
+            return;
+        }
+
         context->setVertexAttribDivisor(index, divisor);
     }
 }
@@ -4703,63 +4842,68 @@
           "GLboolean normalized = %u, GLsizei stride = %d, const GLvoid* ptr = 0x%0.8p)",
           index, size, type, normalized, stride, ptr);
 
-    if (index >= gl::MAX_VERTEX_ATTRIBS)
-    {
-        return gl::error(GL_INVALID_VALUE);
-    }
-
-    if (size < 1 || size > 4)
-    {
-        return gl::error(GL_INVALID_VALUE);
-    }
-
     gl::Context *context = gl::getNonLostContext();
-
-    switch (type)
-    {
-      case GL_BYTE:
-      case GL_UNSIGNED_BYTE:
-      case GL_SHORT:
-      case GL_UNSIGNED_SHORT:
-      case GL_FIXED:
-      case GL_FLOAT:
-        break;
-      case GL_HALF_FLOAT:
-      case GL_INT:
-      case GL_UNSIGNED_INT:
-      case GL_INT_2_10_10_10_REV:
-      case GL_UNSIGNED_INT_2_10_10_10_REV:
-        if (context && context->getClientVersion() < 3)
-        {
-            return gl::error(GL_INVALID_ENUM);
-        }
-        else
-        {
-            break;
-        }
-      default:
-        return gl::error(GL_INVALID_ENUM);
-    }
-
-    if (stride < 0)
-    {
-        return gl::error(GL_INVALID_VALUE);
-    }
-
-    if ((type == GL_INT_2_10_10_10_REV || type == GL_UNSIGNED_INT_2_10_10_10_REV) && size != 4)
-    {
-        return gl::error(GL_INVALID_OPERATION);
-    }
-
     if (context)
     {
+        if (index >= gl::MAX_VERTEX_ATTRIBS)
+        {
+            context->recordError(gl::Error(GL_INVALID_VALUE));
+            return;
+        }
+
+        if (size < 1 || size > 4)
+        {
+            context->recordError(gl::Error(GL_INVALID_VALUE));
+            return;
+        }
+
+        switch (type)
+        {
+          case GL_BYTE:
+          case GL_UNSIGNED_BYTE:
+          case GL_SHORT:
+          case GL_UNSIGNED_SHORT:
+          case GL_FIXED:
+          case GL_FLOAT:
+            break;
+
+          case GL_HALF_FLOAT:
+          case GL_INT:
+          case GL_UNSIGNED_INT:
+          case GL_INT_2_10_10_10_REV:
+          case GL_UNSIGNED_INT_2_10_10_10_REV:
+            if (context->getClientVersion() < 3)
+            {
+                context->recordError(gl::Error(GL_INVALID_ENUM));
+                return;
+            }
+            break;
+
+          default:
+            context->recordError(gl::Error(GL_INVALID_ENUM));
+            return;
+        }
+
+        if (stride < 0)
+        {
+            context->recordError(gl::Error(GL_INVALID_VALUE));
+            return;
+        }
+
+        if ((type == GL_INT_2_10_10_10_REV || type == GL_UNSIGNED_INT_2_10_10_10_REV) && size != 4)
+        {
+            context->recordError(gl::Error(GL_INVALID_OPERATION));
+            return;
+        }
+
         // [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->getState().getVertexArray()->id() != 0 && context->getState().getArrayBufferId() == 0 && ptr != NULL)
         {
-            return gl::error(GL_INVALID_OPERATION);
+            context->recordError(gl::Error(GL_INVALID_OPERATION));
+            return;
         }
 
         context->getState().setVertexAttribState(index, context->getState().getTargetBuffer(GL_ARRAY_BUFFER), size, type,
@@ -4771,15 +4915,15 @@
 {
     EVENT("(GLint x = %d, GLint y = %d, GLsizei width = %d, GLsizei height = %d)", x, y, width, height);
 
-    if (width < 0 || height < 0)
-    {
-        return gl::error(GL_INVALID_VALUE);
-    }
-
     gl::Context *context = gl::getNonLostContext();
-
     if (context)
     {
+        if (width < 0 || height < 0)
+        {
+            context->recordError(gl::Error(GL_INVALID_VALUE));
+            return;
+        }
+
         context->getState().setViewportParams(x, y, width, height);
     }
 }
@@ -4791,12 +4935,12 @@
     EVENT("(GLenum mode = 0x%X)", mode);
 
     gl::Context *context = gl::getNonLostContext();
-
     if (context)
     {
         if (context->getClientVersion() < 3)
         {
-            return gl::error(GL_INVALID_OPERATION);
+            context->recordError(gl::Error(GL_INVALID_OPERATION));
+            return;
         }
 
         // glReadBuffer
@@ -4810,12 +4954,12 @@
           "const GLvoid* indices = 0x%0.8p)", mode, start, end, count, type, indices);
 
     gl::Context *context = gl::getNonLostContext();
-
     if (context)
     {
         if (context->getClientVersion() < 3)
         {
-            return gl::error(GL_INVALID_OPERATION);
+            context->recordError(gl::Error(GL_INVALID_OPERATION));
+            return;
         }
 
         // glDrawRangeElements
@@ -4831,12 +4975,12 @@
           target, level, internalformat, width, height, depth, border, format, type, pixels);
 
     gl::Context *context = gl::getNonLostContext();
-
     if (context)
     {
         if (context->getClientVersion() < 3)
         {
-            return gl::error(GL_INVALID_OPERATION);
+            context->recordError(gl::Error(GL_INVALID_OPERATION));
+            return;
         }
 
         // validateES3TexImageFormat sets the error code if there is an error
@@ -4863,7 +5007,8 @@
             break;
 
           default:
-            return gl::error(GL_INVALID_ENUM);
+            context->recordError(gl::Error(GL_INVALID_ENUM));
+            return;
         }
     }
 }
@@ -4876,12 +5021,12 @@
           target, level, xoffset, yoffset, zoffset, width, height, depth, format, type, pixels);
 
     gl::Context *context = gl::getNonLostContext();
-
     if (context)
     {
         if (context->getClientVersion() < 3)
         {
-            return gl::error(GL_INVALID_OPERATION);
+            context->recordError(gl::Error(GL_INVALID_OPERATION));
+            return;
         }
 
         // validateES3TexImageFormat sets the error code if there is an error
@@ -4915,7 +5060,8 @@
             break;
 
           default:
-            return gl::error(GL_INVALID_ENUM);
+            context->recordError(gl::Error(GL_INVALID_ENUM));
+            return;
         }
     }
 }
@@ -4927,12 +5073,12 @@
           target, level, xoffset, yoffset, zoffset, x, y, width, height);
 
     gl::Context *context = gl::getNonLostContext();
-
     if (context)
     {
         if (context->getClientVersion() < 3)
         {
-            return gl::error(GL_INVALID_OPERATION);
+            context->recordError(gl::Error(GL_INVALID_OPERATION));
+            return;
         }
 
         if (!ValidateES3CopyTexImageParameters(context, target, level, GL_NONE, true, xoffset, yoffset, zoffset,
@@ -4954,7 +5100,8 @@
             break;
 
           default:
-            return gl::error(GL_INVALID_ENUM);
+            context->recordError(gl::Error(GL_INVALID_ENUM));
+            return;
         }
 
         texture->copySubImage(target, level, xoffset, yoffset, zoffset, x, y, width, height, framebuffer);
@@ -4969,18 +5116,19 @@
           target, level, internalformat, width, height, depth, border, imageSize, data);
 
     gl::Context *context = gl::getNonLostContext();
-
     if (context)
     {
         if (context->getClientVersion() < 3)
         {
-            return gl::error(GL_INVALID_OPERATION);
+            context->recordError(gl::Error(GL_INVALID_OPERATION));
+            return;
         }
 
         const gl::InternalFormat &formatInfo = gl::GetInternalFormatInfo(internalformat);
         if (imageSize < 0 || static_cast<GLuint>(imageSize) != formatInfo.computeBlockSize(GL_UNSIGNED_BYTE, width, height))
         {
-            return gl::error(GL_INVALID_VALUE);
+            context->recordError(gl::Error(GL_INVALID_VALUE));
+            return;
         }
 
         // validateES3TexImageFormat sets the error code if there is an error
@@ -5007,7 +5155,8 @@
             break;
 
           default:
-            return gl::error(GL_INVALID_ENUM);
+            context->recordError(gl::Error(GL_INVALID_ENUM));
+            return;
         }
     }
 }
@@ -5020,23 +5169,25 @@
         target, level, xoffset, yoffset, zoffset, width, height, depth, format, imageSize, data);
 
     gl::Context *context = gl::getNonLostContext();
-
     if (context)
     {
         if (context->getClientVersion() < 3)
         {
-            return gl::error(GL_INVALID_OPERATION);
+            context->recordError(gl::Error(GL_INVALID_OPERATION));
+            return;
         }
 
         const gl::InternalFormat &formatInfo = gl::GetInternalFormatInfo(format);
         if (imageSize < 0 || static_cast<GLuint>(imageSize) != formatInfo.computeBlockSize(GL_UNSIGNED_BYTE, width, height))
         {
-            return gl::error(GL_INVALID_VALUE);
+            context->recordError(gl::Error(GL_INVALID_VALUE));
+            return;
         }
 
         if (!data)
         {
-            return gl::error(GL_INVALID_VALUE);
+            context->recordError(gl::Error(GL_INVALID_VALUE));
+            return;
         }
 
         // validateES3TexImageFormat sets the error code if there is an error
@@ -5070,8 +5221,9 @@
             }
             break;
 
-        default:
-            return gl::error(GL_INVALID_ENUM);
+          default:
+            context->recordError(gl::Error(GL_INVALID_ENUM));
+            return;
         }
     }
 }
@@ -5081,17 +5233,18 @@
     EVENT("(GLsizei n = %d, GLuint* ids = 0x%0.8p)", n, ids);
 
     gl::Context *context = gl::getNonLostContext();
-
     if (context)
     {
         if (context->getClientVersion() < 3)
         {
-            return gl::error(GL_INVALID_OPERATION);
+            context->recordError(gl::Error(GL_INVALID_OPERATION));
+            return;
         }
 
         if (n < 0)
         {
-            return gl::error(GL_INVALID_VALUE);
+            context->recordError(gl::Error(GL_INVALID_VALUE));
+            return;
         }
 
         for (GLsizei i = 0; i < n; i++)
@@ -5106,17 +5259,18 @@
     EVENT("(GLsizei n = %d, GLuint* ids = 0x%0.8p)", n, ids);
 
     gl::Context *context = gl::getNonLostContext();
-
     if (context)
     {
         if (context->getClientVersion() < 3)
         {
-            return gl::error(GL_INVALID_OPERATION);
+            context->recordError(gl::Error(GL_INVALID_OPERATION));
+            return;
         }
 
         if (n < 0)
         {
-            return gl::error(GL_INVALID_VALUE);
+            context->recordError(gl::Error(GL_INVALID_VALUE));
+            return;
         }
 
         for (GLsizei i = 0; i < n; i++)
@@ -5131,12 +5285,12 @@
     EVENT("(GLuint id = %u)", id);
 
     gl::Context *context = gl::getNonLostContext();
-
     if (context)
     {
         if (context->getClientVersion() < 3)
         {
-            return gl::error(GL_INVALID_OPERATION, GL_FALSE);
+            context->recordError(gl::Error(GL_INVALID_OPERATION));
+            return GL_FALSE;
         }
 
         return (context->getQuery(id, false, GL_NONE) != NULL) ? GL_TRUE : GL_FALSE;
@@ -5150,19 +5304,25 @@
     EVENT("(GLenum target = 0x%X, GLuint id = %u)", target, id);
 
     gl::Context *context = gl::getNonLostContext();
-
     if (context)
     {
         if (context->getClientVersion() < 3)
         {
-            return gl::error(GL_INVALID_OPERATION);
+            context->recordError(gl::Error(GL_INVALID_OPERATION));
+            return;
         }
 
         if (!ValidateBeginQuery(context, target, id))
         {
             return;
         }
-        context->beginQuery(target, id);
+
+        gl::Error error = context->beginQuery(target, id);
+        if (error.isError())
+        {
+            context->recordError(error);
+            return;
+        }
     }
 }
 
@@ -5171,12 +5331,12 @@
     EVENT("(GLenum target = 0x%X)", target);
 
     gl::Context *context = gl::getNonLostContext();
-
     if (context)
     {
         if (context->getClientVersion() < 3)
         {
-            return gl::error(GL_INVALID_OPERATION);
+            context->recordError(gl::Error(GL_INVALID_OPERATION));
+            return;
         }
 
         if (!ValidateEndQuery(context, target))
@@ -5184,7 +5344,12 @@
             return;
         }
 
-        context->endQuery(target);
+        gl::Error error = context->endQuery(target);
+        if (error.isError())
+        {
+            context->recordError(error);
+            return;
+        }
     }
 }
 
@@ -5193,17 +5358,18 @@
     EVENT("(GLenum target = 0x%X, GLenum pname = 0x%X, GLint* params = 0x%0.8p)", target, pname, params);
 
     gl::Context *context = gl::getNonLostContext();
-
     if (context)
     {
         if (context->getClientVersion() < 3)
         {
-            return gl::error(GL_INVALID_OPERATION);
+            context->recordError(gl::Error(GL_INVALID_OPERATION));
+            return;
         }
 
         if (!ValidQueryType(context, target))
         {
-            return gl::error(GL_INVALID_ENUM);
+            context->recordError(gl::Error(GL_INVALID_ENUM));
+            return;
         }
 
         switch (pname)
@@ -5213,7 +5379,8 @@
             break;
 
           default:
-            return gl::error(GL_INVALID_ENUM);
+            context->recordError(gl::Error(GL_INVALID_ENUM));
+            return;
         }
     }
 }
@@ -5223,36 +5390,55 @@
     EVENT("(GLuint id = %u, GLenum pname = 0x%X, GLint* params = 0x%0.8p)", id, pname, params);
 
     gl::Context *context = gl::getNonLostContext();
-
     if (context)
     {
         if (context->getClientVersion() < 3)
         {
-            return gl::error(GL_INVALID_OPERATION);
+            context->recordError(gl::Error(GL_INVALID_OPERATION));
+            return;
         }
 
         gl::Query *queryObject = context->getQuery(id, false, GL_NONE);
 
         if (!queryObject)
         {
-            return gl::error(GL_INVALID_OPERATION);
+            context->recordError(gl::Error(GL_INVALID_OPERATION));
+            return;
         }
 
         if (context->getState().getActiveQueryId(queryObject->getType()) == id)
         {
-            return gl::error(GL_INVALID_OPERATION);
+            context->recordError(gl::Error(GL_INVALID_OPERATION));
+            return;
         }
 
         switch(pname)
         {
-          case GL_QUERY_RESULT:
-            params[0] = queryObject->getResult();
+          case GL_QUERY_RESULT_EXT:
+            {
+                gl::Error error = queryObject->getResult(params);
+                if (error.isError())
+                {
+                    context->recordError(error);
+                    return;
+                }
+            }
             break;
-          case GL_QUERY_RESULT_AVAILABLE:
-            params[0] = queryObject->isResultAvailable();
+
+          case GL_QUERY_RESULT_AVAILABLE_EXT:
+            {
+                gl::Error error = queryObject->isResultAvailable(params);
+                if (error.isError())
+                {
+                    context->recordError(error);
+                    return;
+                }
+            }
             break;
+
           default:
-            return gl::error(GL_INVALID_ENUM);
+            context->recordError(gl::Error(GL_INVALID_ENUM));
+            return;
         }
     }
 }
@@ -5262,12 +5448,12 @@
     EVENT("(GLenum target = 0x%X)", target);
 
     gl::Context *context = gl::getNonLostContext();
-
     if (context)
     {
         if (context->getClientVersion() < 3)
         {
-            return gl::error(GL_INVALID_OPERATION, GL_FALSE);
+            context->recordError(gl::Error(GL_INVALID_OPERATION));
+            return GL_FALSE;
         }
 
         return glUnmapBufferOES(target);
@@ -5281,12 +5467,12 @@
     EVENT("(GLenum target = 0x%X, GLenum pname = 0x%X, GLvoid** params = 0x%0.8p)", target, pname, params);
 
     gl::Context *context = gl::getNonLostContext();
-
     if (context)
     {
         if (context->getClientVersion() < 3)
         {
-            return gl::error(GL_INVALID_OPERATION);
+            context->recordError(gl::Error(GL_INVALID_OPERATION));
+            return;
         }
 
         glGetBufferPointervOES(target, pname, params);
@@ -5296,12 +5482,12 @@
 void __stdcall glDrawBuffers(GLsizei n, const GLenum* bufs)
 {
     gl::Context *context = gl::getNonLostContext();
-
     if (context)
     {
         if (context->getClientVersion() < 3)
         {
-            return gl::error(GL_INVALID_OPERATION);
+            context->recordError(gl::Error(GL_INVALID_OPERATION));
+            return;
         }
 
         glDrawBuffersEXT(n, bufs);
@@ -5314,7 +5500,6 @@
           location, count, transpose, value);
 
     gl::Context *context = gl::getNonLostContext();
-
     if (context)
     {
         if (!ValidateUniformMatrix(context, GL_FLOAT_MAT2x3, location, count, transpose))
@@ -5333,7 +5518,6 @@
           location, count, transpose, value);
 
     gl::Context *context = gl::getNonLostContext();
-
     if (context)
     {
         if (!ValidateUniformMatrix(context, GL_FLOAT_MAT3x2, location, count, transpose))
@@ -5352,7 +5536,6 @@
           location, count, transpose, value);
 
     gl::Context *context = gl::getNonLostContext();
-
     if (context)
     {
         if (!ValidateUniformMatrix(context, GL_FLOAT_MAT2x4, location, count, transpose))
@@ -5371,7 +5554,6 @@
           location, count, transpose, value);
 
     gl::Context *context = gl::getNonLostContext();
-
     if (context)
     {
         if (!ValidateUniformMatrix(context, GL_FLOAT_MAT4x2, location, count, transpose))
@@ -5390,7 +5572,6 @@
           location, count, transpose, value);
 
     gl::Context *context = gl::getNonLostContext();
-
     if (context)
     {
         if (!ValidateUniformMatrix(context, GL_FLOAT_MAT3x4, location, count, transpose))
@@ -5409,7 +5590,6 @@
           location, count, transpose, value);
 
     gl::Context *context = gl::getNonLostContext();
-
     if (context)
     {
         if (!ValidateUniformMatrix(context, GL_FLOAT_MAT4x3, location, count, transpose))
@@ -5433,7 +5613,8 @@
     {
         if (context->getClientVersion() < 3)
         {
-            return gl::error(GL_INVALID_OPERATION);
+            context->recordError(gl::Error(GL_INVALID_OPERATION));
+            return;
         }
 
         if (!ValidateBlitFramebufferParameters(context, srcX0, srcY0, srcX1, srcY1,
@@ -5454,12 +5635,12 @@
         target, samples, internalformat, width, height);
 
     gl::Context *context = gl::getNonLostContext();
-
     if (context)
     {
         if (context->getClientVersion() < 3)
         {
-            return gl::error(GL_INVALID_OPERATION);
+            context->recordError(gl::Error(GL_INVALID_OPERATION));
+            return;
         }
 
         if (!ValidateRenderbufferStorageParameters(context, target, samples, internalformat,
@@ -5478,7 +5659,6 @@
         target, attachment, texture, level, layer);
 
     gl::Context *context = gl::getNonLostContext();
-
     if (context)
     {
         if (!ValidateFramebufferTextureLayer(context, target, attachment, texture,
@@ -5516,12 +5696,12 @@
           target, offset, length, access);
 
     gl::Context *context = gl::getNonLostContext();
-
     if (context)
     {
         if (context->getClientVersion() < 3)
         {
-            return gl::error(GL_INVALID_OPERATION, reinterpret_cast<GLvoid*>(NULL));
+            context->recordError(gl::Error(GL_INVALID_OPERATION));
+            return NULL;
         }
 
         return glMapBufferRangeEXT(target, offset, length, access);
@@ -5535,12 +5715,12 @@
     EVENT("(GLenum target = 0x%X, GLintptr offset = %d, GLsizeiptr length = %d)", target, offset, length);
 
     gl::Context *context = gl::getNonLostContext();
-
     if (context)
     {
         if (context->getClientVersion() < 3)
         {
-            return gl::error(GL_INVALID_OPERATION);
+            context->recordError(gl::Error(GL_INVALID_OPERATION));
+            return;
         }
 
         glFlushMappedBufferRangeEXT(target, offset, length);
@@ -5552,12 +5732,12 @@
     EVENT("(GLuint array = %u)", array);
 
     gl::Context *context = gl::getNonLostContext();
-
     if (context)
     {
         if (context->getClientVersion() < 3)
         {
-            return gl::error(GL_INVALID_OPERATION);
+            context->recordError(gl::Error(GL_INVALID_OPERATION));
+            return;
         }
 
         gl::VertexArray *vao = context->getVertexArray(array);
@@ -5566,7 +5746,8 @@
         {
             // The default VAO should always exist
             ASSERT(array != 0);
-            return gl::error(GL_INVALID_OPERATION);
+            context->recordError(gl::Error(GL_INVALID_OPERATION));
+            return;
         }
 
         context->bindVertexArray(array);
@@ -5578,17 +5759,18 @@
     EVENT("(GLsizei n = %d, const GLuint* arrays = 0x%0.8p)", n, arrays);
 
     gl::Context *context = gl::getNonLostContext();
-
     if (context)
     {
         if (context->getClientVersion() < 3)
         {
-            return gl::error(GL_INVALID_OPERATION);
+            context->recordError(gl::Error(GL_INVALID_OPERATION));
+            return;
         }
 
         if (n < 0)
         {
-            return gl::error(GL_INVALID_VALUE);
+            context->recordError(gl::Error(GL_INVALID_VALUE));
+            return;
         }
 
         for (int arrayIndex = 0; arrayIndex < n; arrayIndex++)
@@ -5606,17 +5788,18 @@
     EVENT("(GLsizei n = %d, GLuint* arrays = 0x%0.8p)", n, arrays);
 
     gl::Context *context = gl::getNonLostContext();
-
     if (context)
     {
         if (context->getClientVersion() < 3)
         {
-            return gl::error(GL_INVALID_OPERATION);
+            context->recordError(gl::Error(GL_INVALID_OPERATION));
+            return;
         }
 
         if (n < 0)
         {
-            return gl::error(GL_INVALID_VALUE);
+            context->recordError(gl::Error(GL_INVALID_VALUE));
+            return;
         }
 
         for (int arrayIndex = 0; arrayIndex < n; arrayIndex++)
@@ -5631,12 +5814,12 @@
     EVENT("(GLuint array = %u)", array);
 
     gl::Context *context = gl::getNonLostContext();
-
     if (context)
     {
         if (context->getClientVersion() < 3)
         {
-            return gl::error(GL_INVALID_OPERATION, GL_FALSE);
+            context->recordError(gl::Error(GL_INVALID_OPERATION));
+            return GL_FALSE;
         }
 
         if (array == 0)
@@ -5658,30 +5841,40 @@
           target, index, data);
 
     gl::Context *context = gl::getNonLostContext();
-
     if (context)
     {
         if (context->getClientVersion() < 3)
         {
-            return gl::error(GL_INVALID_OPERATION);
+            context->recordError(gl::Error(GL_INVALID_OPERATION));
+            return;
         }
 
+        const gl::Caps &caps = context->getCaps();
         switch (target)
         {
           case GL_TRANSFORM_FEEDBACK_BUFFER_START:
           case GL_TRANSFORM_FEEDBACK_BUFFER_SIZE:
           case GL_TRANSFORM_FEEDBACK_BUFFER_BINDING:
-            if (index >= context->getMaxTransformFeedbackBufferBindings())
-                return gl::error(GL_INVALID_VALUE);
+            if (index >= caps.maxTransformFeedbackSeparateAttributes)
+            {
+                context->recordError(gl::Error(GL_INVALID_VALUE));
+                return;
+            }
             break;
+
           case GL_UNIFORM_BUFFER_START:
           case GL_UNIFORM_BUFFER_SIZE:
           case GL_UNIFORM_BUFFER_BINDING:
-            if (index >= context->getMaximumCombinedUniformBufferBindings())
-                return gl::error(GL_INVALID_VALUE);
+            if (index >= caps.maxCombinedUniformBlocks)
+            {
+                context->recordError(gl::Error(GL_INVALID_VALUE));
+                return;
+            }
             break;
+
           default:
-            return gl::error(GL_INVALID_ENUM);
+            context->recordError(gl::Error(GL_INVALID_ENUM));
+            return;
         }
 
         if (!(context->getIndexedIntegerv(target, index, data)))
@@ -5689,10 +5882,15 @@
             GLenum nativeType;
             unsigned int numParams = 0;
             if (!context->getIndexedQueryParameterInfo(target, &nativeType, &numParams))
-                return gl::error(GL_INVALID_ENUM);
+            {
+                context->recordError(gl::Error(GL_INVALID_ENUM));
+                return;
+            }
 
             if (numParams == 0)
+            {
                 return; // it is known that pname is valid, but there are no parameters to return
+            }
 
             if (nativeType == GL_INT_64_ANGLEX)
             {
@@ -5723,12 +5921,12 @@
     EVENT("(GLenum primitiveMode = 0x%X)", primitiveMode);
 
     gl::Context *context = gl::getNonLostContext();
-
     if (context)
     {
         if (context->getClientVersion() < 3)
         {
-            return gl::error(GL_INVALID_OPERATION);
+            context->recordError(gl::Error(GL_INVALID_OPERATION));
+            return;
         }
 
         switch (primitiveMode)
@@ -5737,8 +5935,10 @@
           case GL_LINES:
           case GL_POINTS:
             break;
+
           default:
-            return gl::error(GL_INVALID_ENUM);
+            context->recordError(gl::Error(GL_INVALID_ENUM));
+            return;
         }
 
         gl::TransformFeedback *transformFeedback = context->getState().getCurrentTransformFeedback();
@@ -5746,7 +5946,8 @@
 
         if (transformFeedback->isStarted())
         {
-            return gl::error(GL_INVALID_OPERATION);
+            context->recordError(gl::Error(GL_INVALID_OPERATION));
+            return;
         }
 
         if (transformFeedback->isPaused())
@@ -5765,12 +5966,12 @@
     EVENT("(void)");
 
     gl::Context *context = gl::getNonLostContext();
-
     if (context)
     {
         if (context->getClientVersion() < 3)
         {
-            return gl::error(GL_INVALID_OPERATION);
+            context->recordError(gl::Error(GL_INVALID_OPERATION));
+            return;
         }
 
         gl::TransformFeedback *transformFeedback = context->getState().getCurrentTransformFeedback();
@@ -5778,7 +5979,8 @@
 
         if (!transformFeedback->isStarted())
         {
-            return gl::error(GL_INVALID_OPERATION);
+            context->recordError(gl::Error(GL_INVALID_OPERATION));
+            return;
         }
 
         transformFeedback->stop();
@@ -5791,37 +5993,42 @@
           target, index, buffer, offset, size);
 
     gl::Context *context = gl::getNonLostContext();
-
     if (context)
     {
         if (context->getClientVersion() < 3)
         {
-            return gl::error(GL_INVALID_OPERATION);
+            context->recordError(gl::Error(GL_INVALID_OPERATION));
+            return;
         }
 
+        const gl::Caps &caps = context->getCaps();
         switch (target)
         {
           case GL_TRANSFORM_FEEDBACK_BUFFER:
-            if (index >= context->getMaxTransformFeedbackBufferBindings())
+            if (index >= caps.maxTransformFeedbackSeparateAttributes)
             {
-                return gl::error(GL_INVALID_VALUE);
+                context->recordError(gl::Error(GL_INVALID_VALUE));
+                return;
             }
             break;
 
           case GL_UNIFORM_BUFFER:
-            if (index >= context->getMaximumCombinedUniformBufferBindings())
+            if (index >= caps.maxUniformBufferBindings)
             {
-                return gl::error(GL_INVALID_VALUE);
+                context->recordError(gl::Error(GL_INVALID_VALUE));
+                return;
             }
             break;
 
           default:
-            return gl::error(GL_INVALID_ENUM);
+            context->recordError(gl::Error(GL_INVALID_ENUM));
+            return;
         }
 
         if (buffer != 0 && size <= 0)
         {
-            return gl::error(GL_INVALID_VALUE);
+            context->recordError(gl::Error(GL_INVALID_VALUE));
+            return;
         }
 
         switch (target)
@@ -5831,7 +6038,8 @@
             // size and offset must be a multiple of 4
             if (buffer != 0 && ((offset % 4) != 0 || (size % 4) != 0))
             {
-                return gl::error(GL_INVALID_VALUE);
+                context->recordError(gl::Error(GL_INVALID_VALUE));
+                return;
             }
 
             context->bindIndexedTransformFeedbackBuffer(buffer, index, offset, size);
@@ -5841,9 +6049,10 @@
           case GL_UNIFORM_BUFFER:
 
             // it is an error to bind an offset not a multiple of the alignment
-            if (buffer != 0 && (offset % context->getUniformBufferOffsetAlignment()) != 0)
+            if (buffer != 0 && (offset % caps.uniformBufferOffsetAlignment) != 0)
             {
-                return gl::error(GL_INVALID_VALUE);
+                context->recordError(gl::Error(GL_INVALID_VALUE));
+                return;
             }
 
             context->bindIndexedUniformBuffer(buffer, index, offset, size);
@@ -5862,32 +6071,36 @@
           target, index, buffer);
 
     gl::Context *context = gl::getNonLostContext();
-
     if (context)
     {
         if (context->getClientVersion() < 3)
         {
-            return gl::error(GL_INVALID_OPERATION);
+            context->recordError(gl::Error(GL_INVALID_OPERATION));
+            return;
         }
 
+        const gl::Caps &caps = context->getCaps();
         switch (target)
         {
           case GL_TRANSFORM_FEEDBACK_BUFFER:
-            if (index >= context->getMaxTransformFeedbackBufferBindings())
+            if (index >= caps.maxTransformFeedbackSeparateAttributes)
             {
-                return gl::error(GL_INVALID_VALUE);
+                context->recordError(gl::Error(GL_INVALID_VALUE));
+                return;
             }
             break;
 
           case GL_UNIFORM_BUFFER:
-            if (index >= context->getMaximumCombinedUniformBufferBindings())
+            if (index >= caps.maxUniformBufferBindings)
             {
-                return gl::error(GL_INVALID_VALUE);
+                context->recordError(gl::Error(GL_INVALID_VALUE));
+                return;
             }
             break;
 
           default:
-            return gl::error(GL_INVALID_ENUM);
+            context->recordError(gl::Error(GL_INVALID_ENUM));
+            return;
         }
 
         switch (target)
@@ -5914,31 +6127,35 @@
           program, count, varyings, bufferMode);
 
     gl::Context *context = gl::getNonLostContext();
-
     if (context)
     {
         if (context->getClientVersion() < 3)
         {
-            return gl::error(GL_INVALID_OPERATION);
+            context->recordError(gl::Error(GL_INVALID_OPERATION));
+            return;
         }
 
         if (count < 0)
         {
-            return gl::error(GL_INVALID_VALUE);
+            context->recordError(gl::Error(GL_INVALID_VALUE));
+            return;
         }
 
+        const gl::Caps &caps = context->getCaps();
         switch (bufferMode)
         {
           case GL_INTERLEAVED_ATTRIBS:
             break;
           case GL_SEPARATE_ATTRIBS:
-            if (static_cast<GLuint>(count) > context->getMaxTransformFeedbackBufferBindings())
+            if (static_cast<GLuint>(count) > caps.maxTransformFeedbackSeparateAttributes)
             {
-                return gl::error(GL_INVALID_VALUE);
+                context->recordError(gl::Error(GL_INVALID_VALUE));
+                return;
             }
             break;
           default:
-            return gl::error(GL_INVALID_ENUM);
+            context->recordError(gl::Error(GL_INVALID_ENUM));
+            return;
         }
 
         if (!gl::ValidProgram(context, program))
@@ -5960,17 +6177,18 @@
           program, index, bufSize, length, size, type, name);
 
     gl::Context *context = gl::getNonLostContext();
-
     if (context)
     {
         if (context->getClientVersion() < 3)
         {
-            return gl::error(GL_INVALID_OPERATION);
+            context->recordError(gl::Error(GL_INVALID_OPERATION));
+            return;
         }
 
         if (bufSize < 0)
         {
-            return gl::error(GL_INVALID_VALUE);
+            context->recordError(gl::Error(GL_INVALID_VALUE));
+            return;
         }
 
         if (!gl::ValidProgram(context, program))
@@ -5983,7 +6201,8 @@
 
         if (index >= static_cast<GLuint>(programObject->getTransformFeedbackVaryingCount()))
         {
-            return gl::error(GL_INVALID_VALUE);
+            context->recordError(gl::Error(GL_INVALID_VALUE));
+            return;
         }
 
         programObject->getTransformFeedbackVarying(index, bufSize, length, size, type, name);
@@ -5996,59 +6215,63 @@
           index, size, type, stride, pointer);
 
     gl::Context *context = gl::getNonLostContext();
-
     if (context)
     {
         if (context->getClientVersion() < 3)
         {
-            return gl::error(GL_INVALID_OPERATION);
+            context->recordError(gl::Error(GL_INVALID_OPERATION));
+            return;
         }
-    }
 
-    if (index >= gl::MAX_VERTEX_ATTRIBS)
-    {
-        return gl::error(GL_INVALID_VALUE);
-    }
+        if (index >= gl::MAX_VERTEX_ATTRIBS)
+        {
+            context->recordError(gl::Error(GL_INVALID_VALUE));
+            return;
+        }
 
-    if (size < 1 || size > 4)
-    {
-        return gl::error(GL_INVALID_VALUE);
-    }
+        if (size < 1 || size > 4)
+        {
+            context->recordError(gl::Error(GL_INVALID_VALUE));
+            return;
+        }
 
-    switch (type)
-    {
-      case GL_BYTE:
-      case GL_UNSIGNED_BYTE:
-      case GL_SHORT:
-      case GL_UNSIGNED_SHORT:
-      case GL_INT:
-      case GL_UNSIGNED_INT:
-      case GL_INT_2_10_10_10_REV:
-      case GL_UNSIGNED_INT_2_10_10_10_REV:
-        break;
-      default:
-        return gl::error(GL_INVALID_ENUM);
-    }
+        switch (type)
+        {
+          case GL_BYTE:
+          case GL_UNSIGNED_BYTE:
+          case GL_SHORT:
+          case GL_UNSIGNED_SHORT:
+          case GL_INT:
+          case GL_UNSIGNED_INT:
+          case GL_INT_2_10_10_10_REV:
+          case GL_UNSIGNED_INT_2_10_10_10_REV:
+            break;
 
-    if (stride < 0)
-    {
-        return gl::error(GL_INVALID_VALUE);
-    }
+          default:
+            context->recordError(gl::Error(GL_INVALID_ENUM));
+            return;
+        }
 
-    if ((type == GL_INT_2_10_10_10_REV || type == GL_UNSIGNED_INT_2_10_10_10_REV) && size != 4)
-    {
-        return gl::error(GL_INVALID_OPERATION);
-    }
+        if (stride < 0)
+        {
+            context->recordError(gl::Error(GL_INVALID_VALUE));
+            return;
+        }
 
-    if (context)
-    {
+        if ((type == GL_INT_2_10_10_10_REV || type == GL_UNSIGNED_INT_2_10_10_10_REV) && size != 4)
+        {
+            context->recordError(gl::Error(GL_INVALID_OPERATION));
+            return;
+        }
+
         // [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->getState().getVertexArray()->id() != 0 && context->getState().getArrayBufferId() == 0 && pointer != NULL)
         {
-            return gl::error(GL_INVALID_OPERATION);
+            context->recordError(gl::Error(GL_INVALID_OPERATION));
+            return;
         }
 
         context->getState().setVertexAttribState(index, context->getState().getTargetBuffer(GL_ARRAY_BUFFER), size, type, false, true,
@@ -6062,22 +6285,23 @@
           index, pname, params);
 
     gl::Context *context = gl::getNonLostContext();
-
     if (context)
     {
         if (context->getClientVersion() < 3)
         {
-            return gl::error(GL_INVALID_OPERATION);
+            context->recordError(gl::Error(GL_INVALID_OPERATION));
+            return;
         }
 
         if (index >= gl::MAX_VERTEX_ATTRIBS)
         {
-            return gl::error(GL_INVALID_VALUE);
+            context->recordError(gl::Error(GL_INVALID_VALUE));
+            return;
         }
 
         const gl::VertexAttribute &attribState = context->getState().getVertexAttribState(index);
 
-        if (!gl::ValidateGetVertexAttribParameters(pname, context->getClientVersion()))
+        if (!gl::ValidateGetVertexAttribParameters(context, pname))
         {
             return;
         }
@@ -6103,22 +6327,23 @@
           index, pname, params);
 
     gl::Context *context = gl::getNonLostContext();
-
     if (context)
     {
         if (context->getClientVersion() < 3)
         {
-            return gl::error(GL_INVALID_OPERATION);
+            context->recordError(gl::Error(GL_INVALID_OPERATION));
+            return;
         }
 
         if (index >= gl::MAX_VERTEX_ATTRIBS)
         {
-            return gl::error(GL_INVALID_VALUE);
+            context->recordError(gl::Error(GL_INVALID_VALUE));
+            return;
         }
 
         const gl::VertexAttribute &attribState = context->getState().getVertexAttribState(index);
 
-        if (!gl::ValidateGetVertexAttribParameters(pname, context->getClientVersion()))
+        if (!gl::ValidateGetVertexAttribParameters(context, pname))
         {
             return;
         }
@@ -6144,17 +6369,18 @@
           index, x, y, z, w);
 
     gl::Context *context = gl::getNonLostContext();
-
     if (context)
     {
         if (context->getClientVersion() < 3)
         {
-            return gl::error(GL_INVALID_OPERATION);
+            context->recordError(gl::Error(GL_INVALID_OPERATION));
+            return;
         }
 
         if (index >= gl::MAX_VERTEX_ATTRIBS)
         {
-            return gl::error(GL_INVALID_VALUE);
+            context->recordError(gl::Error(GL_INVALID_VALUE));
+            return;
         }
 
         GLint vals[4] = { x, y, z, w };
@@ -6168,17 +6394,18 @@
           index, x, y, z, w);
 
     gl::Context *context = gl::getNonLostContext();
-
     if (context)
     {
         if (context->getClientVersion() < 3)
         {
-            return gl::error(GL_INVALID_OPERATION);
+            context->recordError(gl::Error(GL_INVALID_OPERATION));
+            return;
         }
 
         if (index >= gl::MAX_VERTEX_ATTRIBS)
         {
-            return gl::error(GL_INVALID_VALUE);
+            context->recordError(gl::Error(GL_INVALID_VALUE));
+            return;
         }
 
         GLuint vals[4] = { x, y, z, w };
@@ -6191,17 +6418,18 @@
     EVENT("(GLuint index = %u, const GLint* v = 0x%0.8p)", index, v);
 
     gl::Context *context = gl::getNonLostContext();
-
     if (context)
     {
         if (context->getClientVersion() < 3)
         {
-            return gl::error(GL_INVALID_OPERATION);
+            context->recordError(gl::Error(GL_INVALID_OPERATION));
+            return;
         }
 
         if (index >= gl::MAX_VERTEX_ATTRIBS)
         {
-            return gl::error(GL_INVALID_VALUE);
+            context->recordError(gl::Error(GL_INVALID_VALUE));
+            return;
         }
 
         context->getState().setVertexAttribi(index, v);
@@ -6213,17 +6441,18 @@
     EVENT("(GLuint index = %u, const GLuint* v = 0x%0.8p)", index, v);
 
     gl::Context *context = gl::getNonLostContext();
-
     if (context)
     {
         if (context->getClientVersion() < 3)
         {
-            return gl::error(GL_INVALID_OPERATION);
+            context->recordError(gl::Error(GL_INVALID_OPERATION));
+            return;
         }
 
         if (index >= gl::MAX_VERTEX_ATTRIBS)
         {
-            return gl::error(GL_INVALID_VALUE);
+            context->recordError(gl::Error(GL_INVALID_VALUE));
+            return;
         }
 
         context->getState().setVertexAttribu(index, v);
@@ -6236,36 +6465,19 @@
           program, location, params);
 
     gl::Context *context = gl::getNonLostContext();
-
     if (context)
     {
-        if (context->getClientVersion() < 3)
+        if (!ValidateGetUniformuiv(context, program, location, params))
         {
-            return gl::error(GL_INVALID_OPERATION);
-        }
-
-        if (program == 0)
-        {
-            return gl::error(GL_INVALID_VALUE);
+            return;
         }
 
         gl::Program *programObject = context->getProgram(program);
-
-        if (!programObject || !programObject->isLinked())
-        {
-            return gl::error(GL_INVALID_OPERATION);
-        }
-
+        ASSERT(programObject);
         gl::ProgramBinary *programBinary = programObject->getProgramBinary();
-        if (!programBinary)
-        {
-            return gl::error(GL_INVALID_OPERATION);
-        }
+        ASSERT(programBinary);
 
-        if (!programBinary->getUniformuiv(location, NULL, params))
-        {
-            return gl::error(GL_INVALID_OPERATION);
-        }
+        programBinary->getUniformuiv(location, params);
     }
 }
 
@@ -6275,30 +6487,33 @@
           program, name);
 
     gl::Context *context = gl::getNonLostContext();
-
     if (context)
     {
         if (context->getClientVersion() < 3)
         {
-            return gl::error(GL_INVALID_OPERATION, -1);
+            context->recordError(gl::Error(GL_INVALID_OPERATION));
+            return -1;
         }
 
         if (program == 0)
         {
-            return gl::error(GL_INVALID_VALUE, -1);
+            context->recordError(gl::Error(GL_INVALID_VALUE));
+            return -1;
         }
 
         gl::Program *programObject = context->getProgram(program);
 
         if (!programObject || !programObject->isLinked())
         {
-            return gl::error(GL_INVALID_OPERATION, -1);
+            context->recordError(gl::Error(GL_INVALID_OPERATION));
+            return -1;
         }
 
         gl::ProgramBinary *programBinary = programObject->getProgramBinary();
         if (!programBinary)
         {
-            return gl::error(GL_INVALID_OPERATION, -1);
+            context->recordError(gl::Error(GL_INVALID_OPERATION));
+            return -1;
         }
 
         return programBinary->getFragDataLocation(name);
@@ -6336,7 +6551,6 @@
           location, count, value);
 
     gl::Context *context = gl::getNonLostContext();
-
     if (context)
     {
         if (!ValidateUniform(context, GL_UNSIGNED_INT, location, count))
@@ -6355,7 +6569,6 @@
           location, count, value);
 
     gl::Context *context = gl::getNonLostContext();
-
     if (context)
     {
         if (!ValidateUniform(context, GL_UNSIGNED_INT_VEC2, location, count))
@@ -6374,7 +6587,6 @@
           location, count, value);
 
     gl::Context *context = gl::getNonLostContext();
-
     if (context)
     {
         if (!ValidateUniform(context, GL_UNSIGNED_INT_VEC3, location, count))
@@ -6393,7 +6605,6 @@
           location, count, value);
 
     gl::Context *context = gl::getNonLostContext();
-
     if (context)
     {
         if (!ValidateUniform(context, GL_UNSIGNED_INT_VEC4, location, count))
@@ -6412,7 +6623,6 @@
           buffer, drawbuffer, value);
 
     gl::Context *context = gl::getNonLostContext();
-
     if (context)
     {
         if (!ValidateClearBuffer(context))
@@ -6425,20 +6635,30 @@
           case GL_COLOR:
             if (drawbuffer < 0 || static_cast<GLuint>(drawbuffer) >= context->getCaps().maxDrawBuffers)
             {
-                return gl::error(GL_INVALID_VALUE);
+                context->recordError(gl::Error(GL_INVALID_VALUE));
+                return;
             }
             break;
+
           case GL_STENCIL:
             if (drawbuffer != 0)
             {
-                return gl::error(GL_INVALID_VALUE);
+                context->recordError(gl::Error(GL_INVALID_VALUE));
+                return;
             }
             break;
+
           default:
-            return gl::error(GL_INVALID_ENUM);
+            context->recordError(gl::Error(GL_INVALID_ENUM));
+            return;
         }
 
-        context->clearBufferiv(buffer, drawbuffer, value);
+        gl::Error error = context->clearBufferiv(buffer, drawbuffer, value);
+        if (error.isError())
+        {
+            context->recordError(error);
+            return;
+        }
     }
 }
 
@@ -6448,7 +6668,6 @@
           buffer, drawbuffer, value);
 
     gl::Context *context = gl::getNonLostContext();
-
     if (context)
     {
         if (!ValidateClearBuffer(context))
@@ -6461,14 +6680,22 @@
           case GL_COLOR:
             if (drawbuffer < 0 || static_cast<GLuint>(drawbuffer) >= context->getCaps().maxDrawBuffers)
             {
-                return gl::error(GL_INVALID_VALUE);
+                context->recordError(gl::Error(GL_INVALID_VALUE));
+                return;
             }
             break;
+
           default:
-            return gl::error(GL_INVALID_ENUM);
+            context->recordError(gl::Error(GL_INVALID_ENUM));
+            return;
         }
 
-        context->clearBufferuiv(buffer, drawbuffer, value);
+        gl::Error error = context->clearBufferuiv(buffer, drawbuffer, value);
+        if (error.isError())
+        {
+            context->recordError(error);
+            return;
+        }
     }
 }
 
@@ -6478,7 +6705,6 @@
           buffer, drawbuffer, value);
 
     gl::Context *context = gl::getNonLostContext();
-
     if (context)
     {
         if (!ValidateClearBuffer(context))
@@ -6491,20 +6717,30 @@
           case GL_COLOR:
             if (drawbuffer < 0 || static_cast<GLuint>(drawbuffer) >= context->getCaps().maxDrawBuffers)
             {
-                return gl::error(GL_INVALID_VALUE);
+                context->recordError(gl::Error(GL_INVALID_VALUE));
+                return;
             }
             break;
+
           case GL_DEPTH:
             if (drawbuffer != 0)
             {
-                return gl::error(GL_INVALID_VALUE);
+                context->recordError(gl::Error(GL_INVALID_VALUE));
+                return;
             }
             break;
+
           default:
-            return gl::error(GL_INVALID_ENUM);
+            context->recordError(gl::Error(GL_INVALID_ENUM));
+            return;
         }
 
-        context->clearBufferfv(buffer, drawbuffer, value);
+        gl::Error error = context->clearBufferfv(buffer, drawbuffer, value);
+        if (error.isError())
+        {
+            context->recordError(error);
+            return;
+        }
     }
 }
 
@@ -6514,7 +6750,6 @@
           buffer, drawbuffer, depth, stencil);
 
     gl::Context *context = gl::getNonLostContext();
-
     if (context)
     {
         if (!ValidateClearBuffer(context))
@@ -6527,14 +6762,22 @@
           case GL_DEPTH_STENCIL:
             if (drawbuffer != 0)
             {
-                return gl::error(GL_INVALID_VALUE);
+                context->recordError(gl::Error(GL_INVALID_VALUE));
+                return;
             }
             break;
+
           default:
-            return gl::error(GL_INVALID_ENUM);
+            context->recordError(gl::Error(GL_INVALID_ENUM));
+            return;
         }
 
-        context->clearBufferfi(buffer, drawbuffer, depth, stencil);
+        gl::Error error = context->clearBufferfi(buffer, drawbuffer, depth, stencil);
+        if (error.isError())
+        {
+            context->recordError(error);
+            return;
+        }
     }
 }
 
@@ -6543,22 +6786,24 @@
     EVENT("(GLenum name = 0x%X, GLuint index = %u)", name, index);
 
     gl::Context *context = gl::getNonLostContext();
-
     if (context)
     {
         if (context->getClientVersion() < 3)
         {
-            return gl::error(GL_INVALID_OPERATION, reinterpret_cast<GLubyte*>(NULL));
+            context->recordError(gl::Error(GL_INVALID_OPERATION));
+            return NULL;
         }
 
         if (name != GL_EXTENSIONS)
         {
-            return gl::error(GL_INVALID_ENUM, reinterpret_cast<GLubyte*>(NULL));
+            context->recordError(gl::Error(GL_INVALID_ENUM));
+            return NULL;
         }
 
         if (index >= context->getExtensionStringCount())
         {
-            return gl::error(GL_INVALID_VALUE, reinterpret_cast<GLubyte*>(NULL));
+            context->recordError(gl::Error(GL_INVALID_VALUE));
+            return NULL;
         }
 
         return reinterpret_cast<const GLubyte*>(context->getExtensionString(index).c_str());
@@ -6573,17 +6818,18 @@
           readTarget, writeTarget, readOffset, writeOffset, size);
 
     gl::Context *context = gl::getNonLostContext();
-
     if (context)
     {
         if (context->getClientVersion() < 3)
         {
-            return gl::error(GL_INVALID_OPERATION);
+            context->recordError(gl::Error(GL_INVALID_OPERATION));
+            return;
         }
 
         if (!gl::ValidBufferTarget(context, readTarget) || !gl::ValidBufferTarget(context, readTarget))
         {
-            return gl::error(GL_INVALID_ENUM);
+            context->recordError(gl::Error(GL_INVALID_ENUM));
+            return;
         }
 
         gl::Buffer *readBuffer = context->getState().getTargetBuffer(readTarget);
@@ -6591,31 +6837,40 @@
 
         if (!readBuffer || !writeBuffer)
         {
-            return gl::error(GL_INVALID_OPERATION);
+            context->recordError(gl::Error(GL_INVALID_OPERATION));
+            return;
         }
 
         // Verify that readBuffer and writeBuffer are not currently mapped
         if (readBuffer->isMapped() || writeBuffer->isMapped())
         {
-            return gl::error(GL_INVALID_OPERATION);
+            context->recordError(gl::Error(GL_INVALID_OPERATION));
+            return;
         }
 
         if (readOffset < 0 || writeOffset < 0 || size < 0 ||
             static_cast<unsigned int>(readOffset + size) > readBuffer->getSize() ||
             static_cast<unsigned int>(writeOffset + size) > writeBuffer->getSize())
         {
-            return gl::error(GL_INVALID_VALUE);
+            context->recordError(gl::Error(GL_INVALID_VALUE));
+            return;
         }
 
         if (readBuffer == writeBuffer && abs(readOffset - writeOffset) < size)
         {
-            return gl::error(GL_INVALID_VALUE);
+            context->recordError(gl::Error(GL_INVALID_VALUE));
+            return;
         }
 
         // if size is zero, the copy is a successful no-op
         if (size > 0)
         {
-            writeBuffer->copyBufferSubData(readBuffer, readOffset, writeOffset, size);
+            gl::Error error = writeBuffer->copyBufferSubData(readBuffer, readOffset, writeOffset, size);
+            if (error.isError())
+            {
+                context->recordError(error);
+                return;
+            }
         }
     }
 }
@@ -6626,17 +6881,18 @@
           program, uniformCount, uniformNames, uniformIndices);
 
     gl::Context *context = gl::getNonLostContext();
-
     if (context)
     {
         if (context->getClientVersion() < 3)
         {
-            return gl::error(GL_INVALID_OPERATION);
+            context->recordError(gl::Error(GL_INVALID_OPERATION));
+            return;
         }
 
         if (uniformCount < 0)
         {
-            return gl::error(GL_INVALID_VALUE);
+            context->recordError(gl::Error(GL_INVALID_VALUE));
+            return;
         }
 
         gl::Program *programObject = context->getProgram(program);
@@ -6645,11 +6901,13 @@
         {
             if (context->getShader(program))
             {
-                return gl::error(GL_INVALID_OPERATION);
+                context->recordError(gl::Error(GL_INVALID_OPERATION));
+                return;
             }
             else
             {
-                return gl::error(GL_INVALID_VALUE);
+                context->recordError(gl::Error(GL_INVALID_VALUE));
+                return;
             }
         }
 
@@ -6677,17 +6935,18 @@
           program, uniformCount, uniformIndices, pname, params);
 
     gl::Context *context = gl::getNonLostContext();
-
     if (context)
     {
         if (context->getClientVersion() < 3)
         {
-            return gl::error(GL_INVALID_OPERATION);
+            context->recordError(gl::Error(GL_INVALID_OPERATION));
+            return;
         }
 
         if (uniformCount < 0)
         {
-            return gl::error(GL_INVALID_VALUE);
+            context->recordError(gl::Error(GL_INVALID_VALUE));
+            return;
         }
 
         gl::Program *programObject = context->getProgram(program);
@@ -6696,11 +6955,13 @@
         {
             if (context->getShader(program))
             {
-                return gl::error(GL_INVALID_OPERATION);
+                context->recordError(gl::Error(GL_INVALID_OPERATION));
+                return;
             }
             else
             {
-                return gl::error(GL_INVALID_VALUE);
+                context->recordError(gl::Error(GL_INVALID_VALUE));
+                return;
             }
         }
 
@@ -6715,15 +6976,18 @@
           case GL_UNIFORM_MATRIX_STRIDE:
           case GL_UNIFORM_IS_ROW_MAJOR:
             break;
+
           default:
-            return gl::error(GL_INVALID_ENUM);
+            context->recordError(gl::Error(GL_INVALID_ENUM));
+            return;
         }
 
         gl::ProgramBinary *programBinary = programObject->getProgramBinary();
 
         if (!programBinary && uniformCount > 0)
         {
-            return gl::error(GL_INVALID_VALUE);
+            context->recordError(gl::Error(GL_INVALID_VALUE));
+            return;
         }
 
         for (int uniformId = 0; uniformId < uniformCount; uniformId++)
@@ -6732,7 +6996,8 @@
 
             if (index >= (GLuint)programBinary->getActiveUniformCount())
             {
-                return gl::error(GL_INVALID_VALUE);
+                context->recordError(gl::Error(GL_INVALID_VALUE));
+                return;
             }
         }
 
@@ -6749,12 +7014,12 @@
     EVENT("(GLuint program = %u, const GLchar* uniformBlockName = 0x%0.8p)", program, uniformBlockName);
 
     gl::Context *context = gl::getNonLostContext();
-
     if (context)
     {
         if (context->getClientVersion() < 3)
         {
-            return gl::error(GL_INVALID_OPERATION, GL_INVALID_INDEX);
+            context->recordError(gl::Error(GL_INVALID_OPERATION));
+            return GL_INVALID_INDEX;
         }
 
         gl::Program *programObject = context->getProgram(program);
@@ -6763,11 +7028,13 @@
         {
             if (context->getShader(program))
             {
-                return gl::error(GL_INVALID_OPERATION, GL_INVALID_INDEX);
+                context->recordError(gl::Error(GL_INVALID_OPERATION));
+                return GL_INVALID_INDEX;
             }
             else
             {
-                return gl::error(GL_INVALID_VALUE, GL_INVALID_INDEX);
+                context->recordError(gl::Error(GL_INVALID_VALUE));
+                return GL_INVALID_INDEX;
             }
         }
 
@@ -6789,12 +7056,12 @@
           program, uniformBlockIndex, pname, params);
 
     gl::Context *context = gl::getNonLostContext();
-
     if (context)
     {
         if (context->getClientVersion() < 3)
         {
-            return gl::error(GL_INVALID_OPERATION);
+            context->recordError(gl::Error(GL_INVALID_OPERATION));
+            return;
         }
         gl::Program *programObject = context->getProgram(program);
 
@@ -6802,11 +7069,13 @@
         {
             if (context->getShader(program))
             {
-                return gl::error(GL_INVALID_OPERATION);
+                context->recordError(gl::Error(GL_INVALID_OPERATION));
+                return;
             }
             else
             {
-                return gl::error(GL_INVALID_VALUE);
+                context->recordError(gl::Error(GL_INVALID_VALUE));
+                return;
             }
         }
 
@@ -6814,7 +7083,8 @@
 
         if (!programBinary || uniformBlockIndex >= programBinary->getActiveUniformBlockCount())
         {
-            return gl::error(GL_INVALID_VALUE);
+            context->recordError(gl::Error(GL_INVALID_VALUE));
+            return;
         }
 
         switch (pname)
@@ -6833,7 +7103,8 @@
             break;
 
           default:
-            return gl::error(GL_INVALID_ENUM);
+            context->recordError(gl::Error(GL_INVALID_ENUM));
+            return;
         }
     }
 }
@@ -6844,12 +7115,12 @@
           program, uniformBlockIndex, bufSize, length, uniformBlockName);
 
     gl::Context *context = gl::getNonLostContext();
-
     if (context)
     {
         if (context->getClientVersion() < 3)
         {
-            return gl::error(GL_INVALID_OPERATION);
+            context->recordError(gl::Error(GL_INVALID_OPERATION));
+            return;
         }
 
         gl::Program *programObject = context->getProgram(program);
@@ -6858,11 +7129,13 @@
         {
             if (context->getShader(program))
             {
-                return gl::error(GL_INVALID_OPERATION);
+                context->recordError(gl::Error(GL_INVALID_OPERATION));
+                return;
             }
             else
             {
-                return gl::error(GL_INVALID_VALUE);
+                context->recordError(gl::Error(GL_INVALID_VALUE));
+                return;
             }
         }
 
@@ -6870,7 +7143,8 @@
 
         if (!programBinary || uniformBlockIndex >= programBinary->getActiveUniformBlockCount())
         {
-            return gl::error(GL_INVALID_VALUE);
+            context->recordError(gl::Error(GL_INVALID_VALUE));
+            return;
         }
 
         programBinary->getActiveUniformBlockName(uniformBlockIndex, bufSize, length, uniformBlockName);
@@ -6883,17 +7157,18 @@
           program, uniformBlockIndex, uniformBlockBinding);
 
     gl::Context *context = gl::getNonLostContext();
-
     if (context)
     {
         if (context->getClientVersion() < 3)
         {
-            return gl::error(GL_INVALID_OPERATION);
+            context->recordError(gl::Error(GL_INVALID_OPERATION));
+            return;
         }
 
-        if (uniformBlockBinding >= context->getMaximumCombinedUniformBufferBindings())
+        if (uniformBlockBinding >= context->getCaps().maxUniformBufferBindings)
         {
-            return gl::error(GL_INVALID_VALUE);
+            context->recordError(gl::Error(GL_INVALID_VALUE));
+            return;
         }
 
         gl::Program *programObject = context->getProgram(program);
@@ -6902,11 +7177,13 @@
         {
             if (context->getShader(program))
             {
-                return gl::error(GL_INVALID_OPERATION);
+                context->recordError(gl::Error(GL_INVALID_OPERATION));
+                return;
             }
             else
             {
-                return gl::error(GL_INVALID_VALUE);
+                context->recordError(gl::Error(GL_INVALID_VALUE));
+                return;
             }
         }
 
@@ -6915,7 +7192,8 @@
         // if never linked, there won't be any uniform blocks
         if (!programBinary || uniformBlockIndex >= programBinary->getActiveUniformBlockCount())
         {
-            return gl::error(GL_INVALID_VALUE);
+            context->recordError(gl::Error(GL_INVALID_VALUE));
+            return;
         }
 
         programObject->bindUniformBlock(uniformBlockIndex, uniformBlockBinding);
@@ -6928,12 +7206,12 @@
           mode, first, count, instanceCount);
 
     gl::Context *context = gl::getNonLostContext();
-
     if (context)
     {
         if (context->getClientVersion() < 3)
         {
-            return gl::error(GL_INVALID_OPERATION);
+            context->recordError(gl::Error(GL_INVALID_OPERATION));
+            return;
         }
 
         // glDrawArraysInstanced
@@ -6947,12 +7225,12 @@
           mode, count, type, indices, instanceCount);
 
     gl::Context *context = gl::getNonLostContext();
-
     if (context)
     {
         if (context->getClientVersion() < 3)
         {
-            return gl::error(GL_INVALID_OPERATION);
+            context->recordError(gl::Error(GL_INVALID_OPERATION));
+            return;
         }
 
         // glDrawElementsInstanced
@@ -6965,22 +7243,24 @@
     EVENT("(GLenum condition = 0x%X, GLbitfield flags = 0x%X)", condition, flags);
 
     gl::Context *context = gl::getNonLostContext();
-
     if (context)
     {
         if (context->getClientVersion() < 3)
         {
-            return gl::error(GL_INVALID_OPERATION, reinterpret_cast<GLsync>(0));
+            context->recordError(gl::Error(GL_INVALID_OPERATION));
+            return 0;
         }
 
         if (condition != GL_SYNC_GPU_COMMANDS_COMPLETE)
         {
-            return gl::error(GL_INVALID_ENUM, reinterpret_cast<GLsync>(0));
+            context->recordError(gl::Error(GL_INVALID_ENUM));
+            return 0;
         }
 
         if (flags != 0)
         {
-            return gl::error(GL_INVALID_VALUE, reinterpret_cast<GLsync>(0));
+            context->recordError(gl::Error(GL_INVALID_VALUE));
+            return 0;
         }
 
         return context->createFenceSync(condition);
@@ -6994,12 +7274,12 @@
     EVENT("(GLsync sync = 0x%0.8p)", sync);
 
     gl::Context *context = gl::getNonLostContext();
-
     if (context)
     {
         if (context->getClientVersion() < 3)
         {
-            return gl::error(GL_INVALID_OPERATION, GL_FALSE);
+            context->recordError(gl::Error(GL_INVALID_OPERATION));
+            return GL_FALSE;
         }
 
         return (context->getFenceSync(sync) != NULL);
@@ -7013,17 +7293,18 @@
     EVENT("(GLsync sync = 0x%0.8p)", sync);
 
     gl::Context *context = gl::getNonLostContext();
-
     if (context)
     {
         if (context->getClientVersion() < 3)
         {
-            return gl::error(GL_INVALID_OPERATION);
+            context->recordError(gl::Error(GL_INVALID_OPERATION));
+            return;
         }
 
         if (sync != static_cast<GLsync>(0) && !context->getFenceSync(sync))
         {
-            return gl::error(GL_INVALID_VALUE);
+            context->recordError(gl::Error(GL_INVALID_VALUE));
+            return;
         }
 
         context->deleteFenceSync(sync);
@@ -7036,24 +7317,26 @@
           sync, flags, timeout);
 
     gl::Context *context = gl::getNonLostContext();
-
     if (context)
     {
         if (context->getClientVersion() < 3)
         {
-            return gl::error(GL_INVALID_OPERATION, GL_WAIT_FAILED);
+            context->recordError(gl::Error(GL_INVALID_OPERATION));
+            return GL_WAIT_FAILED;
         }
 
         if ((flags & ~(GL_SYNC_FLUSH_COMMANDS_BIT)) != 0)
         {
-            return gl::error(GL_INVALID_VALUE, GL_WAIT_FAILED);
+            context->recordError(gl::Error(GL_INVALID_VALUE));
+            return GL_WAIT_FAILED;
         }
 
         gl::FenceSync *fenceSync = context->getFenceSync(sync);
 
         if (!fenceSync)
         {
-            return gl::error(GL_INVALID_VALUE, GL_WAIT_FAILED);
+            context->recordError(gl::Error(GL_INVALID_VALUE));
+            return GL_WAIT_FAILED;
         }
 
         return fenceSync->clientWait(flags, timeout);
@@ -7068,29 +7351,32 @@
           sync, flags, timeout);
 
     gl::Context *context = gl::getNonLostContext();
-
     if (context)
     {
         if (context->getClientVersion() < 3)
         {
-            return gl::error(GL_INVALID_OPERATION);
+            context->recordError(gl::Error(GL_INVALID_OPERATION));
+            return;
         }
 
         if (flags != 0)
         {
-            return gl::error(GL_INVALID_VALUE);
+            context->recordError(gl::Error(GL_INVALID_VALUE));
+            return;
         }
 
         if (timeout != GL_TIMEOUT_IGNORED)
         {
-            return gl::error(GL_INVALID_VALUE);
+            context->recordError(gl::Error(GL_INVALID_VALUE));
+            return;
         }
 
         gl::FenceSync *fenceSync = context->getFenceSync(sync);
 
         if (!fenceSync)
         {
-            return gl::error(GL_INVALID_VALUE);
+            context->recordError(gl::Error(GL_INVALID_VALUE));
+            return;
         }
 
         fenceSync->serverWait();
@@ -7103,12 +7389,12 @@
           pname, params);
 
     gl::Context *context = gl::getNonLostContext();
-
     if (context)
     {
         if (context->getClientVersion() < 3)
         {
-            return gl::error(GL_INVALID_OPERATION);
+            context->recordError(gl::Error(GL_INVALID_OPERATION));
+            return;
         }
 
         GLenum nativeType;
@@ -7135,24 +7421,26 @@
           sync, pname, bufSize, length, values);
 
     gl::Context *context = gl::getNonLostContext();
-
     if (context)
     {
         if (context->getClientVersion() < 3)
         {
-            return gl::error(GL_INVALID_OPERATION);
+            context->recordError(gl::Error(GL_INVALID_OPERATION));
+            return;
         }
 
         if (bufSize < 0)
         {
-            return gl::error(GL_INVALID_VALUE);
+            context->recordError(gl::Error(GL_INVALID_VALUE));
+            return;
         }
 
         gl::FenceSync *fenceSync = context->getFenceSync(sync);
 
         if (!fenceSync)
         {
-            return gl::error(GL_INVALID_VALUE);
+            context->recordError(gl::Error(GL_INVALID_VALUE));
+            return;
         }
 
         switch (pname)
@@ -7163,7 +7451,8 @@
           case GL_SYNC_FLAGS:      values[0] = 0;                                              break;
 
           default:
-            return gl::error(GL_INVALID_ENUM);
+            context->recordError(gl::Error(GL_INVALID_ENUM));
+            return;
         }
     }
 }
@@ -7174,30 +7463,40 @@
           target, index, data);
 
     gl::Context *context = gl::getNonLostContext();
-
     if (context)
     {
         if (context->getClientVersion() < 3)
         {
-            return gl::error(GL_INVALID_OPERATION);
+            context->recordError(gl::Error(GL_INVALID_OPERATION));
+            return;
         }
 
+        const gl::Caps &caps = context->getCaps();
         switch (target)
         {
           case GL_TRANSFORM_FEEDBACK_BUFFER_START:
           case GL_TRANSFORM_FEEDBACK_BUFFER_SIZE:
           case GL_TRANSFORM_FEEDBACK_BUFFER_BINDING:
-            if (index >= context->getMaxTransformFeedbackBufferBindings())
-                return gl::error(GL_INVALID_VALUE);
+            if (index >= caps.maxTransformFeedbackSeparateAttributes)
+            {
+                context->recordError(gl::Error(GL_INVALID_VALUE));
+                return;
+            }
             break;
+
           case GL_UNIFORM_BUFFER_START:
           case GL_UNIFORM_BUFFER_SIZE:
           case GL_UNIFORM_BUFFER_BINDING:
-            if (index >= context->getMaximumCombinedUniformBufferBindings())
-                return gl::error(GL_INVALID_VALUE);
+            if (index >= caps.maxUniformBufferBindings)
+            {
+                context->recordError(gl::Error(GL_INVALID_VALUE));
+                return;
+            }
             break;
+
           default:
-            return gl::error(GL_INVALID_ENUM);
+            context->recordError(gl::Error(GL_INVALID_ENUM));
+            return;
         }
 
         if (!(context->getIndexedInteger64v(target, index, data)))
@@ -7205,7 +7504,10 @@
             GLenum nativeType;
             unsigned int numParams = 0;
             if (!context->getIndexedQueryParameterInfo(target, &nativeType, &numParams))
-                return gl::error(GL_INVALID_ENUM);
+            {
+                context->recordError(gl::Error(GL_INVALID_ENUM));
+                return;
+            }
 
             if (numParams == 0)
                 return; // it is known that pname is valid, but there are no parameters to return
@@ -7237,22 +7539,24 @@
           target, pname, params);
 
     gl::Context *context = gl::getNonLostContext();
-
     if (context)
     {
         if (context->getClientVersion() < 3)
         {
-            return gl::error(GL_INVALID_OPERATION);
+            context->recordError(gl::Error(GL_INVALID_OPERATION));
+            return;
         }
 
         if (!gl::ValidBufferTarget(context, target))
         {
-            return gl::error(GL_INVALID_ENUM);
+            context->recordError(gl::Error(GL_INVALID_ENUM));
+            return;
         }
 
         if (!gl::ValidBufferParameter(context, pname))
         {
-            return gl::error(GL_INVALID_ENUM);
+            context->recordError(gl::Error(GL_INVALID_ENUM));
+            return;
         }
 
         gl::Buffer *buffer = context->getState().getTargetBuffer(target);
@@ -7260,7 +7564,8 @@
         if (!buffer)
         {
             // A null buffer means that "0" is bound to the requested buffer target
-            return gl::error(GL_INVALID_OPERATION);
+            context->recordError(gl::Error(GL_INVALID_OPERATION));
+            return;
         }
 
         switch (pname)
@@ -7293,17 +7598,18 @@
     EVENT("(GLsizei count = %d, GLuint* samplers = 0x%0.8p)", count, samplers);
 
     gl::Context *context = gl::getNonLostContext();
-
     if (context)
     {
         if (context->getClientVersion() < 3)
         {
-            return gl::error(GL_INVALID_OPERATION);
+            context->recordError(gl::Error(GL_INVALID_OPERATION));
+            return;
         }
 
         if (count < 0)
         {
-            return gl::error(GL_INVALID_VALUE);
+            context->recordError(gl::Error(GL_INVALID_VALUE));
+            return;
         }
 
         for (int i = 0; i < count; i++)
@@ -7318,17 +7624,18 @@
     EVENT("(GLsizei count = %d, const GLuint* samplers = 0x%0.8p)", count, samplers);
 
     gl::Context *context = gl::getNonLostContext();
-
     if (context)
     {
         if (context->getClientVersion() < 3)
         {
-            return gl::error(GL_INVALID_OPERATION);
+            context->recordError(gl::Error(GL_INVALID_OPERATION));
+            return;
         }
 
         if (count < 0)
         {
-            return gl::error(GL_INVALID_VALUE);
+            context->recordError(gl::Error(GL_INVALID_VALUE));
+            return;
         }
 
         for (int i = 0; i < count; i++)
@@ -7343,12 +7650,12 @@
     EVENT("(GLuint sampler = %u)", sampler);
 
     gl::Context *context = gl::getNonLostContext();
-
     if (context)
     {
         if (context->getClientVersion() < 3)
         {
-            return gl::error(GL_INVALID_OPERATION, GL_FALSE);
+            context->recordError(gl::Error(GL_INVALID_OPERATION));
+            return GL_FALSE;
         }
 
         return context->isSampler(sampler);
@@ -7362,22 +7669,24 @@
     EVENT("(GLuint unit = %u, GLuint sampler = %u)", unit, sampler);
 
     gl::Context *context = gl::getNonLostContext();
-
     if (context)
     {
         if (context->getClientVersion() < 3)
         {
-            return gl::error(GL_INVALID_OPERATION);
+            context->recordError(gl::Error(GL_INVALID_OPERATION));
+            return;
         }
 
         if (sampler != 0 && !context->isSampler(sampler))
         {
-            return gl::error(GL_INVALID_OPERATION);
+            context->recordError(gl::Error(GL_INVALID_OPERATION));
+            return;
         }
 
-        if (unit >= context->getMaximumCombinedTextureImageUnits())
+        if (unit >= context->getCaps().maxCombinedTextureImageUnits)
         {
-            return gl::error(GL_INVALID_VALUE);
+            context->recordError(gl::Error(GL_INVALID_VALUE));
+            return;
         }
 
         context->bindSampler(unit, sampler);
@@ -7389,15 +7698,15 @@
     EVENT("(GLuint sampler = %u, GLenum pname = 0x%X, GLint param = %d)", sampler, pname, param);
 
     gl::Context *context = gl::getNonLostContext();
-
     if (context)
     {
         if (context->getClientVersion() < 3)
         {
-            return gl::error(GL_INVALID_OPERATION);
+            context->recordError(gl::Error(GL_INVALID_OPERATION));
+            return;
         }
 
-        if (!gl::ValidateSamplerObjectParameter(pname))
+        if (!gl::ValidateSamplerObjectParameter(context, pname))
         {
             return;
         }
@@ -7409,7 +7718,8 @@
 
         if (!context->isSampler(sampler))
         {
-            return gl::error(GL_INVALID_OPERATION);
+            context->recordError(gl::Error(GL_INVALID_OPERATION));
+            return;
         }
 
         context->samplerParameteri(sampler, pname, param);
@@ -7426,15 +7736,15 @@
     EVENT("(GLuint sampler = %u, GLenum pname = 0x%X, GLfloat param = %g)", sampler, pname, param);
 
     gl::Context *context = gl::getNonLostContext();
-
     if (context)
     {
         if (context->getClientVersion() < 3)
         {
-            return gl::error(GL_INVALID_OPERATION);
+            context->recordError(gl::Error(GL_INVALID_OPERATION));
+            return;
         }
 
-        if (!gl::ValidateSamplerObjectParameter(pname))
+        if (!gl::ValidateSamplerObjectParameter(context, pname))
         {
             return;
         }
@@ -7446,7 +7756,8 @@
 
         if (!context->isSampler(sampler))
         {
-            return gl::error(GL_INVALID_OPERATION);
+            context->recordError(gl::Error(GL_INVALID_OPERATION));
+            return;
         }
 
         context->samplerParameterf(sampler, pname, param);
@@ -7463,22 +7774,23 @@
     EVENT("(GLuint sampler = %u, GLenum pname = 0x%X, GLint* params = 0x%0.8p)", sampler, pname, params);
 
     gl::Context *context = gl::getNonLostContext();
-
     if (context)
     {
         if (context->getClientVersion() < 3)
         {
-            return gl::error(GL_INVALID_OPERATION);
+            context->recordError(gl::Error(GL_INVALID_OPERATION));
+            return;
         }
 
-        if (!gl::ValidateSamplerObjectParameter(pname))
+        if (!gl::ValidateSamplerObjectParameter(context, pname))
         {
             return;
         }
 
         if (!context->isSampler(sampler))
         {
-            return gl::error(GL_INVALID_OPERATION);
+            context->recordError(gl::Error(GL_INVALID_OPERATION));
+            return;
         }
 
         *params = context->getSamplerParameteri(sampler, pname);
@@ -7490,22 +7802,23 @@
     EVENT("(GLuint sample = %ur, GLenum pname = 0x%X, GLfloat* params = 0x%0.8p)", sampler, pname, params);
 
     gl::Context *context = gl::getNonLostContext();
-
     if (context)
     {
         if (context->getClientVersion() < 3)
         {
-            return gl::error(GL_INVALID_OPERATION);
+            context->recordError(gl::Error(GL_INVALID_OPERATION));
+            return;
         }
 
-        if (!gl::ValidateSamplerObjectParameter(pname))
+        if (!gl::ValidateSamplerObjectParameter(context, pname))
         {
             return;
         }
 
         if (!context->isSampler(sampler))
         {
-            return gl::error(GL_INVALID_OPERATION);
+            context->recordError(gl::Error(GL_INVALID_OPERATION));
+            return;
         }
 
         *params = context->getSamplerParameterf(sampler, pname);
@@ -7516,18 +7829,19 @@
 {
     EVENT("(GLuint index = %u, GLuint divisor = %u)", index, divisor);
 
-    if (index >= gl::MAX_VERTEX_ATTRIBS)
-    {
-        return gl::error(GL_INVALID_VALUE);
-    }
-
     gl::Context *context = gl::getNonLostContext();
-
     if (context)
     {
         if (context->getClientVersion() < 3)
         {
-            return gl::error(GL_INVALID_OPERATION);
+            context->recordError(gl::Error(GL_INVALID_OPERATION));
+            return;
+        }
+
+        if (index >= gl::MAX_VERTEX_ATTRIBS)
+        {
+            context->recordError(gl::Error(GL_INVALID_VALUE));
+            return;
         }
 
         context->setVertexAttribDivisor(index, divisor);
@@ -7539,12 +7853,12 @@
     EVENT("(GLenum target = 0x%X, GLuint id = %u)", target, id);
 
     gl::Context *context = gl::getNonLostContext();
-
     if (context)
     {
         if (context->getClientVersion() < 3)
         {
-            return gl::error(GL_INVALID_OPERATION);
+            context->recordError(gl::Error(GL_INVALID_OPERATION));
+            return;
         }
 
         switch (target)
@@ -7555,13 +7869,15 @@
                 gl::TransformFeedback *curTransformFeedback = context->getState().getCurrentTransformFeedback();
                 if (curTransformFeedback && curTransformFeedback->isStarted() && !curTransformFeedback->isPaused())
                 {
-                    return gl::error(GL_INVALID_OPERATION);
+                    context->recordError(gl::Error(GL_INVALID_OPERATION));
+                    return;
                 }
 
                 // Cannot bind a transform feedback object that does not exist (3.0.2 pg 85 section 2.14.1)
                 if (context->getTransformFeedback(id) == NULL)
                 {
-                    return gl::error(GL_INVALID_OPERATION);
+                    context->recordError(gl::Error(GL_INVALID_OPERATION));
+                    return;
                 }
 
                 context->bindTransformFeedback(id);
@@ -7569,7 +7885,8 @@
             break;
 
           default:
-            return gl::error(GL_INVALID_ENUM);
+            context->recordError(gl::Error(GL_INVALID_ENUM));
+            return;
         }
     }
 }
@@ -7579,12 +7896,12 @@
     EVENT("(GLsizei n = %d, const GLuint* ids = 0x%0.8p)", n, ids);
 
     gl::Context *context = gl::getNonLostContext();
-
     if (context)
     {
         if (context->getClientVersion() < 3)
         {
-            return gl::error(GL_INVALID_OPERATION);
+            context->recordError(gl::Error(GL_INVALID_OPERATION));
+            return;
         }
 
         for (int i = 0; i < n; i++)
@@ -7599,12 +7916,12 @@
     EVENT("(GLsizei n = %d, GLuint* ids = 0x%0.8p)", n, ids);
 
     gl::Context *context = gl::getNonLostContext();
-
     if (context)
     {
         if (context->getClientVersion() < 3)
         {
-            return gl::error(GL_INVALID_OPERATION);
+            context->recordError(gl::Error(GL_INVALID_OPERATION));
+            return;
         }
 
         for (int i = 0; i < n; i++)
@@ -7619,12 +7936,12 @@
     EVENT("(GLuint id = %u)", id);
 
     gl::Context *context = gl::getNonLostContext();
-
     if (context)
     {
         if (context->getClientVersion() < 3)
         {
-            return gl::error(GL_INVALID_OPERATION, GL_FALSE);
+            context->recordError(gl::Error(GL_INVALID_OPERATION));
+            return GL_FALSE;
         }
 
         return ((context->getTransformFeedback(id) != NULL) ? GL_TRUE : GL_FALSE);
@@ -7638,12 +7955,12 @@
     EVENT("(void)");
 
     gl::Context *context = gl::getNonLostContext();
-
     if (context)
     {
         if (context->getClientVersion() < 3)
         {
-            return gl::error(GL_INVALID_OPERATION);
+            context->recordError(gl::Error(GL_INVALID_OPERATION));
+            return;
         }
 
         gl::TransformFeedback *transformFeedback = context->getState().getCurrentTransformFeedback();
@@ -7652,7 +7969,8 @@
         // Current transform feedback must be started and not paused in order to pause (3.0.2 pg 86)
         if (!transformFeedback->isStarted() || transformFeedback->isPaused())
         {
-            return gl::error(GL_INVALID_OPERATION);
+            context->recordError(gl::Error(GL_INVALID_OPERATION));
+            return;
         }
 
         transformFeedback->pause();
@@ -7664,12 +7982,12 @@
     EVENT("(void)");
 
     gl::Context *context = gl::getNonLostContext();
-
     if (context)
     {
         if (context->getClientVersion() < 3)
         {
-            return gl::error(GL_INVALID_OPERATION);
+            context->recordError(gl::Error(GL_INVALID_OPERATION));
+            return;
         }
 
         gl::TransformFeedback *transformFeedback = context->getState().getCurrentTransformFeedback();
@@ -7678,7 +7996,8 @@
         // Current transform feedback must be started and paused in order to resume (3.0.2 pg 86)
         if (!transformFeedback->isStarted() || !transformFeedback->isPaused())
         {
-            return gl::error(GL_INVALID_OPERATION);
+            context->recordError(gl::Error(GL_INVALID_OPERATION));
+            return;
         }
 
         transformFeedback->resume();
@@ -7691,12 +8010,12 @@
           program, bufSize, length, binaryFormat, binary);
 
     gl::Context *context = gl::getNonLostContext();
-
     if (context)
     {
         if (context->getClientVersion() < 3)
         {
-            return gl::error(GL_INVALID_OPERATION);
+            context->recordError(gl::Error(GL_INVALID_OPERATION));
+            return;
         }
 
         // glGetProgramBinary
@@ -7710,12 +8029,12 @@
           program, binaryFormat, binary, length);
 
     gl::Context *context = gl::getNonLostContext();
-
     if (context)
     {
         if (context->getClientVersion() < 3)
         {
-            return gl::error(GL_INVALID_OPERATION);
+            context->recordError(gl::Error(GL_INVALID_OPERATION));
+            return;
         }
 
         // glProgramBinary
@@ -7729,12 +8048,12 @@
           program, pname, value);
 
     gl::Context *context = gl::getNonLostContext();
-
     if (context)
     {
         if (context->getClientVersion() < 3)
         {
-            return gl::error(GL_INVALID_OPERATION);
+            context->recordError(gl::Error(GL_INVALID_OPERATION));
+            return;
         }
 
         // glProgramParameteri
@@ -7748,12 +8067,12 @@
           target, numAttachments, attachments);
 
     gl::Context *context = gl::getNonLostContext();
-
     if (context)
     {
         if (context->getClientVersion() < 3)
         {
-            return gl::error(GL_INVALID_OPERATION);
+            context->recordError(gl::Error(GL_INVALID_OPERATION));
+            return;
         }
 
         if (!ValidateInvalidateFramebufferParameters(context, target, numAttachments, attachments))
@@ -7761,8 +8080,11 @@
             return;
         }
 
-        GLuint maxDimension = context->getCaps().maxRenderbufferSize;
-        context->invalidateFrameBuffer(target, numAttachments, attachments, 0, 0, maxDimension, maxDimension);
+        gl::Framebuffer *framebuffer = context->getState().getTargetFramebuffer(target);
+        if (framebuffer && framebuffer->completeness() == GL_FRAMEBUFFER_COMPLETE)
+        {
+            framebuffer->invalidate(context->getCaps(), numAttachments, attachments);
+        }
     }
 }
 
@@ -7773,12 +8095,12 @@
           target, numAttachments, attachments, x, y, width, height);
 
     gl::Context *context = gl::getNonLostContext();
-
     if (context)
     {
         if (context->getClientVersion() < 3)
         {
-            return gl::error(GL_INVALID_OPERATION);
+            context->recordError(gl::Error(GL_INVALID_OPERATION));
+            return;
         }
 
         if (!ValidateInvalidateFramebufferParameters(context, target, numAttachments, attachments))
@@ -7786,7 +8108,11 @@
             return;
         }
 
-        context->invalidateFrameBuffer(target, numAttachments, attachments, x, y, width, height);
+        gl::Framebuffer *framebuffer = context->getState().getTargetFramebuffer(target);
+        if (framebuffer && framebuffer->completeness() == GL_FRAMEBUFFER_COMPLETE)
+        {
+            framebuffer->invalidateSub(context->getCaps(), numAttachments, attachments, x, y, width, height);
+        }
     }
 }
 
@@ -7796,12 +8122,12 @@
           target, levels, internalformat, width, height);
 
     gl::Context *context = gl::getNonLostContext();
-
     if (context)
     {
         if (context->getClientVersion() < 3)
         {
-            return gl::error(GL_INVALID_OPERATION);
+            context->recordError(gl::Error(GL_INVALID_OPERATION));
+            return;
         }
 
         if (!ValidateES3TexStorageParameters(context, target, levels, internalformat, width, height, 1))
@@ -7826,7 +8152,8 @@
             break;
 
           default:
-            return gl::error(GL_INVALID_ENUM);
+            context->recordError(gl::Error(GL_INVALID_ENUM));
+            return;
         }
     }
 }
@@ -7838,12 +8165,12 @@
           target, levels, internalformat, width, height, depth);
 
     gl::Context *context = gl::getNonLostContext();
-
     if (context)
     {
         if (context->getClientVersion() < 3)
         {
-            return gl::error(GL_INVALID_OPERATION);
+            context->recordError(gl::Error(GL_INVALID_OPERATION));
+            return;
         }
 
         if (!ValidateES3TexStorageParameters(context, target, levels, internalformat, width, height, depth))
@@ -7880,28 +8207,31 @@
           target, internalformat, pname, bufSize, params);
 
     gl::Context *context = gl::getNonLostContext();
-
     if (context)
     {
         if (context->getClientVersion() < 3)
         {
-            return gl::error(GL_INVALID_OPERATION);
+            context->recordError(gl::Error(GL_INVALID_OPERATION));
+            return;
         }
 
         const gl::TextureCaps &formatCaps = context->getTextureCaps().get(internalformat);
         if (!formatCaps.renderable)
         {
-            return gl::error(GL_INVALID_ENUM);
+            context->recordError(gl::Error(GL_INVALID_ENUM));
+            return;
         }
 
         if (target != GL_RENDERBUFFER)
         {
-            return gl::error(GL_INVALID_ENUM);
+            context->recordError(gl::Error(GL_INVALID_ENUM));
+            return;
         }
 
         if (bufSize < 0)
         {
-            return gl::error(GL_INVALID_VALUE);
+            context->recordError(gl::Error(GL_INVALID_VALUE));
+            return;
         }
 
         switch (pname)
@@ -7912,11 +8242,14 @@
                 *params = formatCaps.sampleCounts.size();
             }
             break;
+
           case GL_SAMPLES:
             std::copy_n(formatCaps.sampleCounts.rbegin(), std::min<size_t>(bufSize, formatCaps.sampleCounts.size()), params);
             break;
+
           default:
-            return gl::error(GL_INVALID_ENUM);
+            context->recordError(gl::Error(GL_INVALID_ENUM));
+            return;
         }
     }
 }
@@ -7932,7 +8265,6 @@
           srcX0, srcY0, srcX1, srcX1, dstX0, dstY0, dstX1, dstY1, mask, filter);
 
     gl::Context *context = gl::getNonLostContext();
-
     if (context)
     {
         if (!ValidateBlitFramebufferParameters(context, srcX0, srcY0, srcX1, srcY1,
@@ -7965,29 +8297,29 @@
           program, bufSize, length, binaryFormat, binary);
 
     gl::Context *context = gl::getNonLostContext();
-
     if (context)
     {
         gl::Program *programObject = context->getProgram(program);
 
         if (!programObject || !programObject->isLinked())
         {
-            return gl::error(GL_INVALID_OPERATION);
+            context->recordError(gl::Error(GL_INVALID_OPERATION));
+            return;
         }
 
         gl::ProgramBinary *programBinary = programObject->getProgramBinary();
 
         if (!programBinary)
         {
-            return gl::error(GL_INVALID_OPERATION);
+            context->recordError(gl::Error(GL_INVALID_OPERATION));
+            return;
         }
 
-        if (!programBinary->save(binary, bufSize, length))
+        if (!programBinary->save(binaryFormat, binary, bufSize, length))
         {
-            return gl::error(GL_INVALID_OPERATION);
+            context->recordError(gl::Error(GL_INVALID_OPERATION));
+            return;
         }
-
-        *binaryFormat = GL_PROGRAM_BINARY_ANGLE;
     }
 }
 
@@ -7998,22 +8330,23 @@
           program, binaryFormat, binary, length);
 
     gl::Context *context = gl::getNonLostContext();
-
     if (context)
     {
-        if (binaryFormat != GL_PROGRAM_BINARY_ANGLE)
+        const std::vector<GLenum> &programBinaryFormats = context->getCaps().programBinaryFormats;
+        if (std::find(programBinaryFormats.begin(), programBinaryFormats.end(), binaryFormat) == programBinaryFormats.end())
         {
-            return gl::error(GL_INVALID_ENUM);
+            context->recordError(gl::Error(GL_INVALID_ENUM));
+            return;
         }
 
         gl::Program *programObject = context->getProgram(program);
-
         if (!programObject)
         {
-            return gl::error(GL_INVALID_OPERATION);
+            context->recordError(gl::Error(GL_INVALID_OPERATION));
+            return;
         }
 
-        context->setProgramBinary(program, binary, length);
+        context->setProgramBinary(program, binaryFormat, binary, length);
     }
 }
 
@@ -8022,24 +8355,26 @@
     EVENT("(GLenum n = %d, bufs = 0x%0.8p)", n, bufs);
 
     gl::Context *context = gl::getNonLostContext();
-
     if (context)
     {
         if (n < 0 || static_cast<GLuint>(n) > context->getCaps().maxDrawBuffers)
         {
-            return gl::error(GL_INVALID_VALUE);
+            context->recordError(gl::Error(GL_INVALID_VALUE));
+            return;
         }
 
         if (context->getState().getDrawFramebuffer()->id() == 0)
         {
             if (n != 1)
             {
-                return gl::error(GL_INVALID_OPERATION);
+                context->recordError(gl::Error(GL_INVALID_OPERATION));
+                return;
             }
 
             if (bufs[0] != GL_NONE && bufs[0] != GL_BACK)
             {
-                return gl::error(GL_INVALID_OPERATION);
+                context->recordError(gl::Error(GL_INVALID_OPERATION));
+                return;
             }
         }
         else
@@ -8049,7 +8384,8 @@
                 const GLenum attachment = GL_COLOR_ATTACHMENT0_EXT + colorAttachment;
                 if (bufs[colorAttachment] != GL_NONE && bufs[colorAttachment] != attachment)
                 {
-                    return gl::error(GL_INVALID_OPERATION);
+                    context->recordError(gl::Error(GL_INVALID_OPERATION));
+                    return;
                 }
             }
         }
@@ -8073,17 +8409,18 @@
     EVENT("(GLenum target = 0x%X, GLenum pname = 0x%X, GLvoid** params = 0x%0.8p)", target, pname, params);
 
     gl::Context *context = gl::getNonLostContext();
-
     if (context)
     {
         if (!gl::ValidBufferTarget(context, target))
         {
-            return gl::error(GL_INVALID_ENUM);
+            context->recordError(gl::Error(GL_INVALID_ENUM));
+            return;
         }
 
         if (pname != GL_BUFFER_MAP_POINTER)
         {
-            return gl::error(GL_INVALID_ENUM);
+            context->recordError(gl::Error(GL_INVALID_ENUM));
+            return;
         }
 
         gl::Buffer *buffer = context->getState().getTargetBuffer(target);
@@ -8104,32 +8441,42 @@
     EVENT("(GLenum target = 0x%X, GLbitfield access = 0x%X)", target, access);
 
     gl::Context *context = gl::getNonLostContext();
-
     if (context)
     {
         if (!gl::ValidBufferTarget(context, target))
         {
-            return gl::error(GL_INVALID_ENUM, reinterpret_cast<GLvoid*>(NULL));
+            context->recordError(gl::Error(GL_INVALID_ENUM));
+            return NULL;
         }
 
         gl::Buffer *buffer = context->getState().getTargetBuffer(target);
 
         if (buffer == NULL)
         {
-            return gl::error(GL_INVALID_OPERATION, reinterpret_cast<GLvoid*>(NULL));
+            context->recordError(gl::Error(GL_INVALID_OPERATION));
+            return NULL;
         }
 
         if (access != GL_WRITE_ONLY_OES)
         {
-            return gl::error(GL_INVALID_ENUM, reinterpret_cast<GLvoid*>(NULL));
+            context->recordError(gl::Error(GL_INVALID_ENUM));
+            return NULL;
         }
 
         if (buffer->isMapped())
         {
-            return gl::error(GL_INVALID_OPERATION, reinterpret_cast<GLvoid*>(NULL));
+            context->recordError(gl::Error(GL_INVALID_OPERATION));
+            return NULL;
         }
 
-        return buffer->mapRange(0, buffer->getSize(), GL_MAP_WRITE_BIT);
+        gl::Error error = buffer->mapRange(0, buffer->getSize(), GL_MAP_WRITE_BIT);
+        if (error.isError())
+        {
+            context->recordError(error);
+            return NULL;
+        }
+
+        return buffer->getMapPointer();
     }
 
     return NULL;
@@ -8140,24 +8487,30 @@
     EVENT("(GLenum target = 0x%X)", target);
 
     gl::Context *context = gl::getNonLostContext();
-
     if (context)
     {
         if (!gl::ValidBufferTarget(context, target))
         {
-            return gl::error(GL_INVALID_ENUM, GL_FALSE);
+            context->recordError(gl::Error(GL_INVALID_ENUM));
+            return GL_FALSE;
         }
 
         gl::Buffer *buffer = context->getState().getTargetBuffer(target);
 
         if (buffer == NULL || !buffer->isMapped())
         {
-            return gl::error(GL_INVALID_OPERATION, GL_FALSE);
+            context->recordError(gl::Error(GL_INVALID_OPERATION));
+            return GL_FALSE;
         }
 
         // TODO: detect if we had corruption. if so, throw an error and return false.
 
-        buffer->unmap();
+        gl::Error error = buffer->unmap();
+        if (error.isError())
+        {
+            context->recordError(error);
+            return GL_FALSE;
+        }
 
         return GL_TRUE;
     }
@@ -8171,24 +8524,26 @@
           target, offset, length, access);
 
     gl::Context *context = gl::getNonLostContext();
-
     if (context)
     {
         if (!gl::ValidBufferTarget(context, target))
         {
-            return gl::error(GL_INVALID_ENUM, reinterpret_cast<GLvoid*>(NULL));
+            context->recordError(gl::Error(GL_INVALID_ENUM));
+            return NULL;
         }
 
         if (offset < 0 || length < 0)
         {
-            return gl::error(GL_INVALID_VALUE, reinterpret_cast<GLvoid*>(NULL));
+            context->recordError(gl::Error(GL_INVALID_VALUE));
+            return NULL;
         }
 
         gl::Buffer *buffer = context->getState().getTargetBuffer(target);
 
         if (buffer == NULL)
         {
-            return gl::error(GL_INVALID_OPERATION, reinterpret_cast<GLvoid*>(NULL));
+            context->recordError(gl::Error(GL_INVALID_OPERATION));
+            return NULL;
         }
 
         // Check for buffer overflow
@@ -8198,7 +8553,8 @@
         if (!rx::IsUnsignedAdditionSafe(offsetSize, lengthSize) ||
             offsetSize + lengthSize > static_cast<size_t>(buffer->getSize()))
         {
-            return gl::error(GL_INVALID_VALUE, reinterpret_cast<GLvoid*>(NULL));
+            context->recordError(gl::Error(GL_INVALID_VALUE));
+            return NULL;
         }
 
         // Check for invalid bits in the mask
@@ -8211,18 +8567,21 @@
 
         if (access & ~(allAccessBits))
         {
-            return gl::error(GL_INVALID_VALUE, reinterpret_cast<GLvoid*>(NULL));
+            context->recordError(gl::Error(GL_INVALID_VALUE));
+            return NULL;
         }
 
         if (length == 0 || buffer->isMapped())
         {
-            return gl::error(GL_INVALID_OPERATION, reinterpret_cast<GLvoid*>(NULL));
+            context->recordError(gl::Error(GL_INVALID_OPERATION));
+            return NULL;
         }
 
         // Check for invalid bit combinations
         if ((access & (GL_MAP_READ_BIT | GL_MAP_WRITE_BIT)) == 0)
         {
-            return gl::error(GL_INVALID_OPERATION, reinterpret_cast<GLvoid*>(NULL));
+            context->recordError(gl::Error(GL_INVALID_OPERATION));
+            return NULL;
         }
 
         GLbitfield writeOnlyBits = GL_MAP_INVALIDATE_RANGE_BIT |
@@ -8231,15 +8590,24 @@
 
         if ((access & GL_MAP_READ_BIT) != 0 && (access & writeOnlyBits) != 0)
         {
-            return gl::error(GL_INVALID_OPERATION, reinterpret_cast<GLvoid*>(NULL));
+            context->recordError(gl::Error(GL_INVALID_OPERATION));
+            return NULL;
         }
 
         if ((access & GL_MAP_WRITE_BIT) == 0 && (access & GL_MAP_FLUSH_EXPLICIT_BIT) != 0)
         {
-            return gl::error(GL_INVALID_OPERATION, reinterpret_cast<GLvoid*>(NULL));
+            context->recordError(gl::Error(GL_INVALID_OPERATION));
+            return NULL;
         }
 
-        return buffer->mapRange(offset, length, access);
+        gl::Error error = buffer->mapRange(offset, length, access);
+        if (error.isError())
+        {
+            context->recordError(error);
+            return NULL;
+        }
+
+        return buffer->getMapPointer();
     }
 
     return NULL;
@@ -8250,29 +8618,32 @@
     EVENT("(GLenum target = 0x%X, GLintptr offset = %d, GLsizeiptr length = %d)", target, offset, length);
 
     gl::Context *context = gl::getNonLostContext();
-
     if (context)
     {
         if (offset < 0 || length < 0)
         {
-            return gl::error(GL_INVALID_VALUE);
+            context->recordError(gl::Error(GL_INVALID_VALUE));
+            return;
         }
 
         if (!gl::ValidBufferTarget(context, target))
         {
-            return gl::error(GL_INVALID_ENUM);
+            context->recordError(gl::Error(GL_INVALID_ENUM));
+            return;
         }
 
         gl::Buffer *buffer = context->getState().getTargetBuffer(target);
 
         if (buffer == NULL)
         {
-            return gl::error(GL_INVALID_OPERATION);
+            context->recordError(gl::Error(GL_INVALID_OPERATION));
+            return;
         }
 
         if (!buffer->isMapped() || (buffer->getAccessFlags() & GL_MAP_FLUSH_EXPLICIT_BIT) == 0)
         {
-            return gl::error(GL_INVALID_OPERATION);
+            context->recordError(gl::Error(GL_INVALID_OPERATION));
+            return;
         }
 
         // Check for buffer overflow
@@ -8282,7 +8653,8 @@
         if (!rx::IsUnsignedAdditionSafe(offsetSize, lengthSize) ||
             offsetSize + lengthSize > static_cast<size_t>(buffer->getMapLength()))
         {
-            return gl::error(GL_INVALID_VALUE);
+            context->recordError(gl::Error(GL_INVALID_VALUE));
+            return;
         }
 
         // We do not currently support a non-trivial implementation of FlushMappedBufferRange
@@ -8353,7 +8725,6 @@
           surface);
 
     gl::Context *context = gl::getNonLostContext();
-
     if (context)
     {
         gl::Texture2D *textureObject = context->getTexture2D();
diff --git a/src/libGLESv2/main.cpp b/src/libGLESv2/main.cpp
index 81e70a4..4444d1a 100644
--- a/src/libGLESv2/main.cpp
+++ b/src/libGLESv2/main.cpp
@@ -1,4 +1,3 @@
-#include "precompiled.h"
 //
 // 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
@@ -145,33 +144,26 @@
 void error(GLenum errorCode)
 {
     gl::Context *context = glGetCurrentContext();
+    context->recordError(Error(errorCode));
 
-    if (context)
+    switch (errorCode)
     {
-        switch (errorCode)
-        {
-          case GL_INVALID_ENUM:
-            context->recordInvalidEnum();
-            TRACE("\t! Error generated: invalid enum\n");
-            break;
-          case GL_INVALID_VALUE:
-            context->recordInvalidValue();
-            TRACE("\t! Error generated: invalid value\n");
-            break;
-          case GL_INVALID_OPERATION:
-            context->recordInvalidOperation();
-            TRACE("\t! Error generated: invalid operation\n");
-            break;
-          case GL_OUT_OF_MEMORY:
-            context->recordOutOfMemory();
-            TRACE("\t! Error generated: out of memory\n");
-            break;
-          case GL_INVALID_FRAMEBUFFER_OPERATION:
-            context->recordInvalidFramebufferOperation();
-            TRACE("\t! Error generated: invalid framebuffer operation\n");
-            break;
-          default: UNREACHABLE();
-        }
+      case GL_INVALID_ENUM:
+        TRACE("\t! Error generated: invalid enum\n");
+        break;
+      case GL_INVALID_VALUE:
+        TRACE("\t! Error generated: invalid value\n");
+        break;
+      case GL_INVALID_OPERATION:
+        TRACE("\t! Error generated: invalid operation\n");
+        break;
+      case GL_OUT_OF_MEMORY:
+        TRACE("\t! Error generated: out of memory\n");
+        break;
+      case GL_INVALID_FRAMEBUFFER_OPERATION:
+        TRACE("\t! Error generated: invalid framebuffer operation\n");
+        break;
+      default: UNREACHABLE();
     }
 }
 
diff --git a/src/libGLESv2/main.h b/src/libGLESv2/main.h
index 372b03f..684c302 100644
--- a/src/libGLESv2/main.h
+++ b/src/libGLESv2/main.h
@@ -11,6 +11,9 @@
 
 #include "common/debug.h"
 
+#include <GLES2/gl2.h>
+#include <EGL/egl.h>
+
 namespace egl
 {
 class Display;
diff --git a/src/libGLESv2/precompiled.cpp b/src/libGLESv2/precompiled.cpp
deleted file mode 100644
index 2621cd6..0000000
--- a/src/libGLESv2/precompiled.cpp
+++ /dev/null
@@ -1,9 +0,0 @@
-//
-// 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.
-//
-
-// precompiled.cpp: Precompiled header source file for libGLESv2.
-
-#include "precompiled.h"
diff --git a/src/libGLESv2/precompiled.h b/src/libGLESv2/precompiled.h
deleted file mode 100644
index cc935a1..0000000
--- a/src/libGLESv2/precompiled.h
+++ /dev/null
@@ -1,31 +0,0 @@
-//
-// 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.
-//
-
-// precompiled.h: Precompiled header file for libGLESv2.
-
-#include "angle_gl.h"
-#include <EGL/egl.h>
-#include <EGL/eglext.h>
-
-#include <assert.h>
-#include <cstddef>
-#include <float.h>
-#include <stdint.h>
-#include <intrin.h>
-#include <math.h>
-#include <stdarg.h>
-#include <stdlib.h>
-#include <stdio.h>
-#include <string.h>
-
-#include <algorithm> // for std::min and std::max
-#include <limits>
-#include <map>
-#include <set>
-#include <sstream>
-#include <string>
-#include <unordered_map>
-#include <vector>
diff --git a/src/libGLESv2/queryconversions.cpp b/src/libGLESv2/queryconversions.cpp
index 67578ef..7245902 100644
--- a/src/libGLESv2/queryconversions.cpp
+++ b/src/libGLESv2/queryconversions.cpp
@@ -1,4 +1,3 @@
-#include "precompiled.h"
 //
 // 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
diff --git a/src/libGLESv2/renderer/BufferImpl.h b/src/libGLESv2/renderer/BufferImpl.h
index bea689b..f0b5f02 100644
--- a/src/libGLESv2/renderer/BufferImpl.h
+++ b/src/libGLESv2/renderer/BufferImpl.h
@@ -20,12 +20,12 @@
   public:
     virtual ~BufferImpl() { }
 
-    virtual void setData(const void* data, size_t size, GLenum usage) = 0;
+    virtual gl::Error setData(const void* data, size_t size, GLenum usage) = 0;
     virtual void *getData() = 0;
-    virtual void setSubData(const void* data, size_t size, size_t offset) = 0;
-    virtual void copySubData(BufferImpl* source, GLintptr sourceOffset, GLintptr destOffset, GLsizeiptr size) = 0;
-    virtual GLvoid* map(size_t offset, size_t length, GLbitfield access) = 0;
-    virtual void unmap() = 0;
+    virtual gl::Error setSubData(const void* data, size_t size, size_t offset) = 0;
+    virtual gl::Error copySubData(BufferImpl* source, GLintptr sourceOffset, GLintptr destOffset, GLsizeiptr size) = 0;
+    virtual gl::Error map(size_t offset, size_t length, GLbitfield access, GLvoid **mapPtr) = 0;
+    virtual gl::Error unmap() = 0;
     virtual void markTransformFeedbackUsage() = 0;
 };
 
diff --git a/src/libGLESv2/renderer/Image.cpp b/src/libGLESv2/renderer/Image.cpp
index 5963534..370b086 100644
--- a/src/libGLESv2/renderer/Image.cpp
+++ b/src/libGLESv2/renderer/Image.cpp
@@ -1,4 +1,3 @@
-#include "precompiled.h"
 //
 // 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
diff --git a/src/libGLESv2/renderer/Image.h b/src/libGLESv2/renderer/Image.h
index 8fcffa4..3bfc663 100644
--- a/src/libGLESv2/renderer/Image.h
+++ b/src/libGLESv2/renderer/Image.h
@@ -13,6 +13,8 @@
 
 #include "common/debug.h"
 
+#include <GLES2/gl2.h>
+
 namespace gl
 {
 class Framebuffer;
diff --git a/src/libGLESv2/renderer/IndexRangeCache.cpp b/src/libGLESv2/renderer/IndexRangeCache.cpp
index 4fdb0ca..d472e14 100644
--- a/src/libGLESv2/renderer/IndexRangeCache.cpp
+++ b/src/libGLESv2/renderer/IndexRangeCache.cpp
@@ -1,4 +1,3 @@
-#include "precompiled.h"
 //
 // 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
@@ -10,16 +9,49 @@
 
 #include "libGLESv2/renderer/IndexRangeCache.h"
 #include "libGLESv2/formatutils.h"
+
 #include "common/debug.h"
+
 #include <tuple>
 
 namespace rx
 {
 
-void IndexRangeCache::addRange(GLenum type, unsigned int offset, GLsizei count, unsigned int minIdx, unsigned int maxIdx,
+template <class IndexType>
+static RangeUI ComputeTypedRange(const IndexType *indices, GLsizei count)
+{
+    unsigned int minIndex = indices[0];
+    unsigned int maxIndex = indices[0];
+
+    for (GLsizei i = 1; i < count; i++)
+    {
+        if (minIndex > indices[i]) minIndex = indices[i];
+        if (maxIndex < indices[i]) maxIndex = indices[i];
+    }
+
+    return RangeUI(minIndex, maxIndex);
+}
+
+RangeUI IndexRangeCache::ComputeRange(GLenum type, const GLvoid *indices, GLsizei count)
+{
+    switch (type)
+    {
+      case GL_UNSIGNED_BYTE:
+        return ComputeTypedRange(static_cast<const GLubyte*>(indices), count);
+      case GL_UNSIGNED_INT:
+        return ComputeTypedRange(static_cast<const GLuint*>(indices), count);
+      case GL_UNSIGNED_SHORT:
+        return ComputeTypedRange(static_cast<const GLushort*>(indices), count);
+      default:
+        UNREACHABLE();
+        return RangeUI();
+    }
+}
+
+void IndexRangeCache::addRange(GLenum type, unsigned int offset, GLsizei count, const RangeUI &range,
                                unsigned int streamOffset)
 {
-    mIndexRangeCache[IndexRange(type, offset, count)] = IndexBounds(minIdx, maxIdx, streamOffset);
+    mIndexRangeCache[IndexRange(type, offset, count)] = IndexBounds(range, streamOffset);
 }
 
 void IndexRangeCache::invalidateRange(unsigned int offset, unsigned int size)
@@ -44,21 +76,19 @@
     }
 }
 
-bool IndexRangeCache::findRange(GLenum type, unsigned int offset, GLsizei count, unsigned int *outMinIndex,
-                                unsigned int *outMaxIndex, unsigned int *outStreamOffset) const
+bool IndexRangeCache::findRange(GLenum type, unsigned int offset, GLsizei count,
+                                RangeUI *outRange, unsigned int *outStreamOffset) const
 {
     IndexRangeMap::const_iterator i = mIndexRangeCache.find(IndexRange(type, offset, count));
     if (i != mIndexRangeCache.end())
     {
-        if (outMinIndex)     *outMinIndex = i->second.minIndex;
-        if (outMaxIndex)     *outMaxIndex = i->second.maxIndex;
+        if (outRange)        *outRange = i->second.range;
         if (outStreamOffset) *outStreamOffset = i->second.streamOffset;
         return true;
     }
     else
     {
-        if (outMinIndex)     *outMinIndex = 0;
-        if (outMaxIndex)     *outMaxIndex = 0;
+        if (outRange)        *outRange = RangeUI(0, 0);
         if (outStreamOffset) *outStreamOffset = 0;
         return false;
     }
@@ -85,12 +115,13 @@
 }
 
 IndexRangeCache::IndexBounds::IndexBounds()
-    : minIndex(0), maxIndex(0), streamOffset(0)
+    : range(0, 0),
+      streamOffset(0)
 {
 }
 
-IndexRangeCache::IndexBounds::IndexBounds(unsigned int minIdx, unsigned int maxIdx, unsigned int offset)
-    : minIndex(minIdx), maxIndex(maxIdx), streamOffset(offset)
+IndexRangeCache::IndexBounds::IndexBounds(const RangeUI &rangeIn, unsigned int offset)
+    : range(rangeIn), streamOffset(offset)
 {
 }
 
diff --git a/src/libGLESv2/renderer/IndexRangeCache.h b/src/libGLESv2/renderer/IndexRangeCache.h
index 4318e2b..a7d91e0 100644
--- a/src/libGLESv2/renderer/IndexRangeCache.h
+++ b/src/libGLESv2/renderer/IndexRangeCache.h
@@ -11,6 +11,10 @@
 #define LIBGLESV2_RENDERER_INDEXRANGECACHE_H_
 
 #include "common/angleutils.h"
+#include "common/mathutil.h"
+
+#include "angle_gl.h"
+
 #include <map>
 
 namespace rx
@@ -19,14 +23,16 @@
 class IndexRangeCache
 {
   public:
-    void addRange(GLenum type, unsigned int offset, GLsizei count, unsigned int minIdx, unsigned int maxIdx,
+    void addRange(GLenum type, unsigned int offset, GLsizei count, const RangeUI &range,
                   unsigned int streamOffset);
-    bool findRange(GLenum type, unsigned int offset, GLsizei count, unsigned int *outMinIndex,
-                   unsigned int *outMaxIndex, unsigned int *outStreamOffset) const;
+    bool findRange(GLenum type, unsigned int offset, GLsizei count, RangeUI *rangeOut,
+                   unsigned int *outStreamOffset) const;
 
     void invalidateRange(unsigned int offset, unsigned int size);
     void clear();
 
+    static RangeUI ComputeRange(GLenum type, const GLvoid *indices, GLsizei count);
+
   private:
     struct IndexRange
     {
@@ -42,12 +48,11 @@
 
     struct IndexBounds
     {
-        unsigned int minIndex;
-        unsigned int maxIndex;
+        RangeUI range;
         unsigned int streamOffset;
 
         IndexBounds();
-        IndexBounds(unsigned int minIdx, unsigned int maxIdx, unsigned int offset);
+        IndexBounds(const RangeUI &range, unsigned int offset);
     };
 
     typedef std::map<IndexRange, IndexBounds> IndexRangeMap;
@@ -56,4 +61,4 @@
 
 }
 
-#endif LIBGLESV2_RENDERER_INDEXRANGECACHE_H
+#endif // LIBGLESV2_RENDERER_INDEXRANGECACHE_H
diff --git a/src/libGLESv2/renderer/ProgramImpl.h b/src/libGLESv2/renderer/ProgramImpl.h
new file mode 100644
index 0000000..ba0955f
--- /dev/null
+++ b/src/libGLESv2/renderer/ProgramImpl.h
@@ -0,0 +1,58 @@
+//
+// Copyright 2014 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+
+// ProgramImpl.h: Defines the abstract rx::ProgramImpl class.
+
+#ifndef LIBGLESV2_RENDERER_PROGRAMIMPL_H_
+#define LIBGLESV2_RENDERER_PROGRAMIMPL_H_
+
+#include "common/angleutils.h"
+#include "libGLESv2/BinaryStream.h"
+#include "libGLESv2/Constants.h"
+#include "libGLESv2/ProgramBinary.h"
+
+namespace rx
+{
+
+class DynamicHLSL;
+class Renderer;
+
+class ProgramImpl
+{
+public:
+    virtual ~ProgramImpl() { }
+
+    // TODO: Temporary interfaces to ease migration. Remove soon!
+    virtual Renderer *getRenderer() = 0;
+    virtual DynamicHLSL *getDynamicHLSL() = 0;
+    virtual const std::vector<rx::PixelShaderOutputVariable> &getPixelShaderKey() = 0;
+
+    virtual GLenum getBinaryFormat() = 0;
+    virtual bool load(gl::InfoLog &infoLog, gl::BinaryInputStream *stream) = 0;
+    virtual bool save(gl::BinaryOutputStream *stream) = 0;
+
+    virtual rx::ShaderExecutable *getPixelExecutableForOutputLayout(gl::InfoLog &infoLog, const std::vector<GLenum> &outputSignature,
+                                                                    const std::vector<gl::LinkedVarying> &transformFeedbackLinkedVaryings,
+                                                                    bool separatedOutputBuffers) = 0;
+    virtual rx::ShaderExecutable *getVertexExecutableForInputLayout(gl::InfoLog &infoLog,
+                                                                    const gl::VertexFormat inputLayout[gl::MAX_VERTEX_ATTRIBS],
+                                                                    const sh::Attribute shaderAttributes[],
+                                                                    const std::vector<gl::LinkedVarying> &transformFeedbackLinkedVaryings,
+                                                                    bool separatedOutputBuffers) = 0;
+
+    virtual bool link(gl::InfoLog &infoLog, gl::Shader *fragmentShader, gl::Shader *vertexShader,
+                      const std::vector<std::string> &transformFeedbackVaryings, int *registers,
+                      std::vector<gl::LinkedVarying> *linkedVaryings, std::map<int,
+                      gl::VariableLocation> *outputVariables) = 0;
+
+    virtual void initializeUniformStorage(const std::vector<gl::LinkedUniform*> &uniforms) = 0;
+
+    virtual void reset() = 0;
+};
+
+}
+
+#endif // LIBGLESV2_RENDERER_PROGRAMIMPL_H_
diff --git a/src/libGLESv2/renderer/QueryImpl.h b/src/libGLESv2/renderer/QueryImpl.h
index a6750a2..6b45810 100644
--- a/src/libGLESv2/renderer/QueryImpl.h
+++ b/src/libGLESv2/renderer/QueryImpl.h
@@ -9,28 +9,27 @@
 #ifndef LIBGLESV2_RENDERER_QUERYIMPL_H_
 #define LIBGLESV2_RENDERER_QUERYIMPL_H_
 
+#include "libGLESv2/Error.h"
+
 #include "common/angleutils.h"
 
+#include <GLES2/gl2.h>
+
 namespace rx
 {
 
 class QueryImpl
 {
   public:
-    explicit QueryImpl(GLenum type) : mType(type), mStatus(GL_FALSE), mResult(0) { }
+    explicit QueryImpl(GLenum type) { mType = type; }
     virtual ~QueryImpl() { }
 
-    virtual void begin() = 0;
-    virtual void end() = 0;
-    virtual GLuint getResult() = 0;
-    virtual GLboolean isResultAvailable() = 0;
-    virtual bool isStarted() const = 0;
+    virtual gl::Error begin() = 0;
+    virtual gl::Error end() = 0;
+    virtual gl::Error getResult(GLuint *params) = 0;
+    virtual gl::Error isResultAvailable(GLuint *available) = 0;
 
-    GLenum getType() const { return mType; }
-
-  protected:
-    GLuint mResult;
-    GLboolean mStatus;
+    GLenum getType() const { return mType;  }
 
   private:
     DISALLOW_COPY_AND_ASSIGN(QueryImpl);
diff --git a/src/libGLESv2/renderer/Renderer.cpp b/src/libGLESv2/renderer/Renderer.cpp
index 590004a..a0682e9 100644
--- a/src/libGLESv2/renderer/Renderer.cpp
+++ b/src/libGLESv2/renderer/Renderer.cpp
@@ -1,4 +1,3 @@
-#include "precompiled.h"
 //
 // Copyright (c) 2012-2014 The ANGLE Project Authors. All rights reserved.
 // Use of this source code is governed by a BSD-style license that can be
@@ -7,7 +6,6 @@
 
 // Renderer.cpp: Implements EGL dependencies for creating and destroying Renderer instances.
 
-#include <EGL/eglext.h>
 #include "libGLESv2/main.h"
 #include "libGLESv2/Program.h"
 #include "libGLESv2/renderer/Renderer.h"
@@ -28,6 +26,8 @@
 #define ANGLE_DEFAULT_D3D11 0
 #endif
 
+#include <EGL/eglext.h>
+
 namespace rx
 {
 
@@ -40,7 +40,6 @@
 
 Renderer::~Renderer()
 {
-    gl::Shader::releaseCompiler();
 }
 
 const gl::Caps &Renderer::getRendererCaps() const
diff --git a/src/libGLESv2/renderer/Renderer.h b/src/libGLESv2/renderer/Renderer.h
index 9e1a6f4..f104a95 100644
--- a/src/libGLESv2/renderer/Renderer.h
+++ b/src/libGLESv2/renderer/Renderer.h
@@ -13,6 +13,11 @@
 #include "libGLESv2/Uniform.h"
 #include "libGLESv2/angletypes.h"
 #include "libGLESv2/Caps.h"
+#include "libGLESv2/Error.h"
+
+#include <cstdint>
+
+#include <EGL/egl.h>
 
 #if !defined(ANGLE_COMPILE_OPTIMIZATION_LEVEL)
 // WARNING: D3DCOMPILE_OPTIMIZATION_LEVEL3 may lead to a DX9 shader compiler hang.
@@ -39,10 +44,7 @@
 
 namespace rx
 {
-class TextureStorageInterface2D;
-class TextureStorageInterfaceCube;
-class TextureStorageInterface3D;
-class TextureStorageInterface2DArray;
+class TextureStorage;
 class VertexBuffer;
 class IndexBuffer;
 class QueryImpl;
@@ -51,16 +53,16 @@
 class VertexArrayImpl;
 class BufferStorage;
 struct TranslatedIndexData;
+class ShaderImpl;
+class ProgramImpl;
 class ShaderExecutable;
 class SwapChain;
 class RenderTarget;
 class Image;
 class TextureStorage;
 class UniformStorage;
-class Texture2DImpl;
-class TextureCubeImpl;
-class Texture3DImpl;
-class Texture2DArrayImpl;
+class TextureImpl;
+class TransformFeedbackImpl;
 
 struct ConfigDesc
 {
@@ -120,7 +122,7 @@
                                       int stencilBackRef, bool frontFaceCCW) = 0;
 
     virtual void setScissorRectangle(const gl::Rectangle &scissor, bool enabled) = 0;
-    virtual bool setViewport(const gl::Rectangle &viewport, float zNear, float zFar, GLenum drawMode, GLenum frontFace,
+    virtual void setViewport(const gl::Rectangle &viewport, float zNear, float zFar, GLenum drawMode, GLenum frontFace,
                              bool ignoreViewport) = 0;
 
     virtual bool applyRenderTarget(gl::Framebuffer *frameBuffer) = 0;
@@ -128,16 +130,16 @@
                               bool rasterizerDiscard, bool transformFeedbackActive) = 0;
     virtual void applyUniforms(const gl::ProgramBinary &programBinary) = 0;
     virtual bool applyPrimitiveType(GLenum primitiveType, GLsizei elementCount) = 0;
-    virtual GLenum applyVertexBuffer(gl::ProgramBinary *programBinary, const gl::VertexAttribute vertexAttributes[], const gl::VertexAttribCurrentValueData currentValues[],
-                                     GLint first, GLsizei count, GLsizei instances) = 0;
-    virtual GLenum applyIndexBuffer(const GLvoid *indices, gl::Buffer *elementArrayBuffer, GLsizei count, GLenum mode, GLenum type, TranslatedIndexData *indexInfo) = 0;
+    virtual gl::Error applyVertexBuffer(gl::ProgramBinary *programBinary, const gl::VertexAttribute vertexAttributes[], const gl::VertexAttribCurrentValueData currentValues[],
+                                        GLint first, GLsizei count, GLsizei instances) = 0;
+    virtual gl::Error applyIndexBuffer(const GLvoid *indices, gl::Buffer *elementArrayBuffer, GLsizei count, GLenum mode, GLenum type, TranslatedIndexData *indexInfo) = 0;
     virtual void applyTransformFeedbackBuffers(gl::Buffer *transformFeedbackBuffers[], GLintptr offsets[]) = 0;
 
     virtual void drawArrays(GLenum mode, GLsizei count, GLsizei instances, bool transformFeedbackActive) = 0;
     virtual void drawElements(GLenum mode, GLsizei count, GLenum type, const GLvoid *indices,
                               gl::Buffer *elementArrayBuffer, const TranslatedIndexData &indexInfo, GLsizei instances) = 0;
 
-    virtual void clear(const gl::ClearParameters &clearParams, gl::Framebuffer *frameBuffer) = 0;
+    virtual gl::Error clear(const gl::ClearParameters &clearParams, gl::Framebuffer *frameBuffer) = 0;
 
     virtual void markAllStateDirty() = 0;
 
@@ -156,56 +158,48 @@
     virtual std::string getRendererDescription() const = 0;
     virtual GUID getAdapterIdentifier() const = 0;
 
-    bool getVertexTextureSupport() const { return getMaxVertexTextureImageUnits() > 0; }
-    virtual unsigned int getMaxVertexTextureImageUnits() const = 0;
-    virtual unsigned int getMaxCombinedTextureImageUnits() const = 0;
     virtual unsigned int getReservedVertexUniformVectors() const = 0;
     virtual unsigned int getReservedFragmentUniformVectors() const = 0;
-    virtual unsigned int getMaxVertexUniformVectors() const = 0;
-    virtual unsigned int getMaxFragmentUniformVectors() const = 0;
-    virtual unsigned int getMaxVaryingVectors() const = 0;
-    virtual unsigned int getMaxVertexShaderUniformBuffers() const = 0;
-    virtual unsigned int getMaxFragmentShaderUniformBuffers() const = 0;
     virtual unsigned int getReservedVertexUniformBuffers() const = 0;
     virtual unsigned int getReservedFragmentUniformBuffers() const = 0;
-    virtual unsigned int getMaxTransformFeedbackBuffers() const = 0;
-    virtual unsigned int getMaxTransformFeedbackSeparateComponents() const = 0;
-    virtual unsigned int getMaxTransformFeedbackInterleavedComponents() const = 0;
-    virtual unsigned int getMaxUniformBufferSize() const = 0;
     virtual bool getShareHandleSupport() const = 0;
     virtual bool getPostSubBufferSupport() const = 0;
-    virtual int getMaxRecommendedElementsIndices() const = 0;
-    virtual int getMaxRecommendedElementsVertices() const = 0;
 
     virtual int getMajorShaderModel() const = 0;
     virtual int getMinSwapInterval() const = 0;
     virtual int getMaxSwapInterval() const = 0;
 
     // Pixel operations
-    virtual bool copyToRenderTarget(TextureStorageInterface2D *dest, TextureStorageInterface2D *source) = 0;
-    virtual bool copyToRenderTarget(TextureStorageInterfaceCube *dest, TextureStorageInterfaceCube *source) = 0;
-    virtual bool copyToRenderTarget(TextureStorageInterface3D *dest, TextureStorageInterface3D *source) = 0;
-    virtual bool copyToRenderTarget(TextureStorageInterface2DArray *dest, TextureStorageInterface2DArray *source) = 0;
+    virtual bool copyToRenderTarget2D(TextureStorage *dest, TextureStorage *source) = 0;
+    virtual bool copyToRenderTargetCube(TextureStorage *dest, TextureStorage *source) = 0;
+    virtual bool copyToRenderTarget3D(TextureStorage *dest, TextureStorage *source) = 0;
+    virtual bool copyToRenderTarget2DArray(TextureStorage *dest, TextureStorage *source) = 0;
 
-    virtual bool copyImage(gl::Framebuffer *framebuffer, const gl::Rectangle &sourceRect, GLenum destFormat,
-                           GLint xoffset, GLint yoffset, TextureStorageInterface2D *storage, GLint level) = 0;
-    virtual bool copyImage(gl::Framebuffer *framebuffer, const gl::Rectangle &sourceRect, GLenum destFormat,
-                           GLint xoffset, GLint yoffset, TextureStorageInterfaceCube *storage, GLenum target, GLint level) = 0;
-    virtual bool copyImage(gl::Framebuffer *framebuffer, const gl::Rectangle &sourceRect, GLenum destFormat,
-                           GLint xoffset, GLint yoffset, GLint zOffset, TextureStorageInterface3D *storage, GLint level) = 0;
-    virtual bool copyImage(gl::Framebuffer *framebuffer, const gl::Rectangle &sourceRect, GLenum destFormat,
-                           GLint xoffset, GLint yoffset, GLint zOffset, TextureStorageInterface2DArray *storage, GLint level) = 0;
+    virtual bool copyImage2D(gl::Framebuffer *framebuffer, const gl::Rectangle &sourceRect, GLenum destFormat,
+                             GLint xoffset, GLint yoffset, TextureStorage *storage, GLint level) = 0;
+    virtual bool copyImageCube(gl::Framebuffer *framebuffer, const gl::Rectangle &sourceRect, GLenum destFormat,
+                               GLint xoffset, GLint yoffset, TextureStorage *storage, GLenum target, GLint level) = 0;
+    virtual bool copyImage3D(gl::Framebuffer *framebuffer, const gl::Rectangle &sourceRect, GLenum destFormat,
+                             GLint xoffset, GLint yoffset, GLint zOffset, TextureStorage *storage, GLint level) = 0;
+    virtual bool copyImage2DArray(gl::Framebuffer *framebuffer, const gl::Rectangle &sourceRect, GLenum destFormat,
+                                  GLint xoffset, GLint yoffset, GLint zOffset, TextureStorage *storage, GLint level) = 0;
 
     virtual bool blitRect(gl::Framebuffer *readTarget, const gl::Rectangle &readRect, gl::Framebuffer *drawTarget, const gl::Rectangle &drawRect,
                           const gl::Rectangle *scissor, bool blitRenderTarget, bool blitDepth, bool blitStencil, GLenum filter) = 0;
-    virtual void readPixels(gl::Framebuffer *framebuffer, GLint x, GLint y, GLsizei width, GLsizei height, GLenum format,
-                            GLenum type, GLuint outputPitch, const gl::PixelPackState &pack, void* pixels) = 0;
+
+    virtual gl::Error readPixels(gl::Framebuffer *framebuffer, GLint x, GLint y, GLsizei width, GLsizei height, GLenum format,
+                                 GLenum type, GLuint outputPitch, const gl::PixelPackState &pack, uint8_t *pixels) = 0;
 
     // RenderTarget creation
     virtual RenderTarget *createRenderTarget(SwapChain *swapChain, bool depth) = 0;
     virtual RenderTarget *createRenderTarget(int width, int height, GLenum format, GLsizei samples) = 0;
 
+    // Shader creation
+    virtual ShaderImpl *createShader(GLenum type) = 0;
+    virtual ProgramImpl *createProgram() = 0;
+
     // Shader operations
+    virtual void releaseShaderCompiler() = 0;
     virtual ShaderExecutable *loadExecutable(const void *function, size_t length, rx::ShaderType type,
                                              const std::vector<gl::LinkedVarying> &transformFeedbackVaryings,
                                              bool separatedOutputBuffers) = 0;
@@ -224,10 +218,7 @@
     virtual TextureStorage *createTextureStorage2DArray(GLenum internalformat, bool renderTarget, GLsizei width, GLsizei height, GLsizei depth, int levels) = 0;
 
     // Texture creation
-    virtual Texture2DImpl *createTexture2D() = 0;
-    virtual TextureCubeImpl *createTextureCube() = 0;
-    virtual Texture3DImpl *createTexture3D() = 0;
-    virtual Texture2DArrayImpl *createTexture2DArray() = 0;
+    virtual TextureImpl *createTexture(GLenum target) = 0;
 
     // Buffer creation
     virtual BufferImpl *createBuffer() = 0;
@@ -241,6 +232,9 @@
     virtual QueryImpl *createQuery(GLenum type) = 0;
     virtual FenceImpl *createFence() = 0;
 
+    // Transform Feedback creation
+    virtual TransformFeedbackImpl* createTransformFeedback() = 0;
+
     // Current GLES client version
     void setCurrentClientVersion(int clientVersion) { mCurrentClientVersion = clientVersion; }
     int getCurrentClientVersion() const { return mCurrentClientVersion; }
diff --git a/src/libGLESv2/renderer/ShaderExecutable.h b/src/libGLESv2/renderer/ShaderExecutable.h
index 054d00a..f171956 100644
--- a/src/libGLESv2/renderer/ShaderExecutable.h
+++ b/src/libGLESv2/renderer/ShaderExecutable.h
@@ -13,6 +13,9 @@
 #include "common/angleutils.h"
 #include "common/debug.h"
 
+#include <vector>
+#include <cstdint>
+
 namespace rx
 {
 
diff --git a/src/libGLESv2/renderer/ShaderImpl.h b/src/libGLESv2/renderer/ShaderImpl.h
new file mode 100644
index 0000000..de5d30e
--- /dev/null
+++ b/src/libGLESv2/renderer/ShaderImpl.h
@@ -0,0 +1,54 @@
+//
+// Copyright 2014 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+
+// ShaderImpl.h: Defines the abstract rx::ShaderImpl class.
+
+#ifndef LIBGLESV2_RENDERER_SHADERIMPL_H_
+#define LIBGLESV2_RENDERER_SHADERIMPL_H_
+
+#include <vector>
+
+#include "common/angleutils.h"
+#include "libGLESv2/Shader.h"
+
+namespace rx
+{
+
+class ShaderImpl
+{
+  public:
+    ShaderImpl() { }
+    virtual ~ShaderImpl() { }
+
+    virtual bool compile(const std::string &source) = 0;
+    virtual const std::string &getInfoLog() const = 0;
+    virtual const std::string &getTranslatedSource() const = 0;
+
+    const std::vector<gl::PackedVarying> &getVaryings() const { return mVaryings; }
+    const std::vector<sh::Uniform> &getUniforms() const { return mUniforms; }
+    const std::vector<sh::InterfaceBlock> &getInterfaceBlocks() const  { return mInterfaceBlocks; }
+    const std::vector<sh::Attribute> &getActiveAttributes() const { return mActiveAttributes; }
+    const std::vector<sh::Attribute> &getActiveOutputVariables() const { return mActiveOutputVariables; }
+
+    std::vector<gl::PackedVarying> &getVaryings() { return mVaryings; }
+    std::vector<sh::Uniform> &getUniforms() { return mUniforms; }
+    std::vector<sh::InterfaceBlock> &getInterfaceBlocks() { return mInterfaceBlocks; }
+    std::vector<sh::Attribute> &getActiveAttributes() { return mActiveAttributes; }
+    std::vector<sh::Attribute> &getActiveOutputVariables() { return mActiveOutputVariables; }
+
+  protected:
+    DISALLOW_COPY_AND_ASSIGN(ShaderImpl);
+
+    std::vector<gl::PackedVarying> mVaryings;
+    std::vector<sh::Uniform> mUniforms;
+    std::vector<sh::InterfaceBlock> mInterfaceBlocks;
+    std::vector<sh::Attribute> mActiveAttributes;
+    std::vector<sh::Attribute> mActiveOutputVariables;
+};
+
+}
+
+#endif // LIBGLESV2_RENDERER_SHADERIMPL_H_
diff --git a/src/libGLESv2/renderer/SwapChain.h b/src/libGLESv2/renderer/SwapChain.h
index f09f19b..c53b2af 100644
--- a/src/libGLESv2/renderer/SwapChain.h
+++ b/src/libGLESv2/renderer/SwapChain.h
@@ -11,6 +11,10 @@
 #define LIBGLESV2_RENDERER_SWAPCHAIN_H_
 
 #include "common/angleutils.h"
+#include "common/platform.h"
+
+#include <GLES2/gl2.h>
+#include <EGL/egl.h>
 
 #if !defined(ANGLE_FORCE_VSYNC_OFF)
 #define ANGLE_FORCE_VSYNC_OFF 0
diff --git a/src/libGLESv2/renderer/TextureImpl.h b/src/libGLESv2/renderer/TextureImpl.h
index 2aa0d55..e3cc50d 100644
--- a/src/libGLESv2/renderer/TextureImpl.h
+++ b/src/libGLESv2/renderer/TextureImpl.h
@@ -11,6 +11,10 @@
 
 #include "common/angleutils.h"
 
+#include "angle_gl.h"
+
+#include "libGLESv2/ImageIndex.h"
+
 namespace egl
 {
 class Surface;
@@ -27,27 +31,26 @@
 {
 
 class Image;
-class RenderTarget;
 class Renderer;
-class TextureStorageInterface;
+class TextureStorage;
 
 class TextureImpl
 {
   public:
+    virtual ~TextureImpl() {};
+
     // TODO: If this methods could go away that would be ideal;
     // TextureStorage should only be necessary for the D3D backend, and as such
     // higher level code should not rely on it.
-    virtual TextureStorageInterface *getNativeTexture() = 0;
+    virtual TextureStorage *getNativeTexture() = 0;
 
+    // Deprecated in favour of the ImageIndex method
     virtual Image *getImage(int level, int layer) const = 0;
+    virtual Image *getImage(const gl::ImageIndex &index) const = 0;
     virtual GLsizei getLayerCount(int level) const = 0;
 
-    virtual bool hasDirtyImages() const = 0;
-    virtual void resetDirty() = 0;
     virtual void setUsage(GLenum usage) = 0;
 
-    virtual bool isSamplerComplete(const gl::SamplerState &samplerState) const = 0;
-
     virtual void setImage(GLenum target, GLint level, GLsizei width, GLsizei height, GLsizei depth, GLenum internalFormat, GLenum format, GLenum type, const gl::PixelUnpackState &unpack, const void *pixels) = 0;
     virtual void setCompressedImage(GLenum target, GLint level, GLenum format, GLsizei width, GLsizei height, GLsizei depth, GLsizei imageSize, const void *pixels) = 0;
     virtual void subImage(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const gl::PixelUnpackState &unpack, const void *pixels) = 0;
@@ -58,40 +61,10 @@
 
     virtual void generateMipmaps() = 0;
 
-    virtual unsigned int getRenderTargetSerial(GLint level, GLint layer) = 0;
-    virtual RenderTarget *getRenderTarget(GLint level, GLint layer) = 0;
-    virtual RenderTarget *getDepthStencil(GLint level, GLint layer) = 0;
-};
-
-class Texture2DImpl : public TextureImpl
-{
-  public:
-    virtual ~Texture2DImpl() {}
-
     virtual void bindTexImage(egl::Surface *surface) = 0;
     virtual void releaseTexImage() = 0;
 };
 
-class TextureCubeImpl : public TextureImpl
-{
-  public:
-    virtual ~TextureCubeImpl() {}
-
-    virtual bool isCubeComplete() const = 0;
-};
-
-class Texture3DImpl : public TextureImpl
-{
-  public:
-    virtual ~Texture3DImpl() {}
-};
-
-class Texture2DArrayImpl : public TextureImpl
-{
-  public:
-    virtual ~Texture2DArrayImpl() {}
-};
-
 }
 
 #endif // LIBGLESV2_RENDERER_TEXTUREIMPL_H_
diff --git a/src/libGLESv2/renderer/TransformFeedbackImpl.h b/src/libGLESv2/renderer/TransformFeedbackImpl.h
new file mode 100644
index 0000000..8425604
--- /dev/null
+++ b/src/libGLESv2/renderer/TransformFeedbackImpl.h
@@ -0,0 +1,31 @@
+//
+// Copyright 2014 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+
+// TransformFeedbackImpl.h: Defines the abstract rx::TransformFeedbackImpl class.
+
+#ifndef LIBGLESV2_RENDERER_TRANSFORMFEEDBACKIMPL_H_
+#define LIBGLESV2_RENDERER_TRANSFORMFEEDBACKIMPL_H_
+
+#include "common/angleutils.h"
+#include "libGLESv2/TransformFeedback.h"
+
+namespace rx
+{
+
+class TransformFeedbackImpl
+{
+  public:
+    virtual ~TransformFeedbackImpl() { }
+
+    virtual void begin(GLenum primitiveMode) = 0;
+    virtual void end() = 0;
+    virtual void pause() = 0;
+    virtual void resume() = 0;
+};
+
+}
+
+#endif // LIBGLESV2_RENDERER_TRANSFORMFEEDBACKIMPL_H_
diff --git a/src/libGLESv2/renderer/copyimage.cpp b/src/libGLESv2/renderer/copyimage.cpp
index 765089c..004223d 100644
--- a/src/libGLESv2/renderer/copyimage.cpp
+++ b/src/libGLESv2/renderer/copyimage.cpp
@@ -1,4 +1,3 @@
-#include "precompiled.h"
 //
 // 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
@@ -12,12 +11,12 @@
 namespace rx
 {
 
-void CopyBGRAUByteToRGBAUByte(const void *source, void *dest)
+void CopyBGRA8ToRGBA8(const uint8_t *source, uint8_t *dest)
 {
-    unsigned int argb = *(unsigned int*)source;
-    *(unsigned int*)dest = (argb & 0xFF00FF00) |       // Keep alpha and green
-                           (argb & 0x00FF0000) >> 16 | // Move red to blue
-                           (argb & 0x000000FF) << 16;  // Move blue to red
+    uint32_t argb = *reinterpret_cast<const uint32_t*>(source);
+    *reinterpret_cast<uint32_t*>(dest) = (argb & 0xFF00FF00) |       // Keep alpha and green
+                                         (argb & 0x00FF0000) >> 16 | // Move red to blue
+                                         (argb & 0x000000FF) << 16;  // Move blue to red
 }
 
 }
diff --git a/src/libGLESv2/renderer/copyimage.h b/src/libGLESv2/renderer/copyimage.h
index 2f37e1c..513eb5c 100644
--- a/src/libGLESv2/renderer/copyimage.h
+++ b/src/libGLESv2/renderer/copyimage.h
@@ -1,5 +1,5 @@
 //
-// Copyright (c) 2013 The ANGLE Project Authors. All rights reserved.
+// Copyright (c) 2013-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.
 //
@@ -12,31 +12,24 @@
 #include "common/mathutil.h"
 #include "libGLESv2/angletypes.h"
 
+#include <cstdint>
+
 namespace rx
 {
 
 template <typename sourceType, typename colorDataType>
-void ReadColor(const void *source, void *dest)
-{
-    sourceType::readColor(reinterpret_cast<gl::Color<colorDataType>*>(dest), reinterpret_cast<const sourceType*>(source));
-}
+void ReadColor(const uint8_t *source, uint8_t *dest);
 
 template <typename destType, typename colorDataType>
-void WriteColor(const void *source, void *dest)
-{
-    destType::writeColor(reinterpret_cast<destType*>(dest), reinterpret_cast<const gl::Color<colorDataType>*>(source));
-}
+void WriteColor(const uint8_t *source, uint8_t *dest);
 
 template <typename sourceType, typename destType, typename colorDataType>
-void CopyPixel(const void *source, void *dest)
-{
-    colorType temp;
-    ReadColor<sourceType, colorDataType>(source, &temp);
-    WriteColor<destType, colorDataType>(&temp, dest);
-}
+void CopyPixel(const uint8_t *source, uint8_t *dest);
 
-void CopyBGRAUByteToRGBAUByte(const void *source, void *dest);
+void CopyBGRA8ToRGBA8(const uint8_t *source, uint8_t *dest);
 
 }
 
+#include "copyimage.inl"
+
 #endif // LIBGLESV2_RENDERER_COPYIMAGE_H_
diff --git a/src/libGLESv2/renderer/copyimage.inl b/src/libGLESv2/renderer/copyimage.inl
new file mode 100644
index 0000000..ea6970c
--- /dev/null
+++ b/src/libGLESv2/renderer/copyimage.inl
@@ -0,0 +1,32 @@
+//
+// 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.
+//
+
+// copyimage.inl: Defines image copying functions
+
+namespace rx
+{
+
+template <typename sourceType, typename colorDataType>
+inline void ReadColor(const uint8_t *source, uint8_t *dest)
+{
+    sourceType::readColor(reinterpret_cast<gl::Color<colorDataType>*>(dest), reinterpret_cast<const sourceType*>(source));
+}
+
+template <typename destType, typename colorDataType>
+inline void WriteColor(const uint8_t *source, uint8_t *dest)
+{
+    destType::writeColor(reinterpret_cast<destType*>(dest), reinterpret_cast<const gl::Color<colorDataType>*>(source));
+}
+
+template <typename sourceType, typename destType, typename colorDataType>
+inline void CopyPixel(const uint8_t *source, uint8_t *dest)
+{
+    colorType temp;
+    ReadColor<sourceType, colorDataType>(source, &temp);
+    WriteColor<destType, colorDataType>(&temp, dest);
+}
+
+}
diff --git a/src/libGLESv2/renderer/copyvertex.h b/src/libGLESv2/renderer/copyvertex.h
index aca0317..e0e8af1 100644
--- a/src/libGLESv2/renderer/copyvertex.h
+++ b/src/libGLESv2/renderer/copyvertex.h
@@ -1,5 +1,5 @@
 //
-// Copyright (c) 2013 The ANGLE Project Authors. All rights reserved.
+// Copyright (c) 2013-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.
 //
@@ -11,299 +11,25 @@
 
 #include "common/mathutil.h"
 
+namespace rx
+{
+
 // 'widenDefaultValueBits' gives the default value for the alpha channel (4th component)
 //  the sentinel value 0 means we do not want to widen the input or add an alpha channel
-template <typename T, unsigned int componentCount, unsigned int widenDefaultValueBits>
-inline void copyVertexData(const void *input, size_t stride, size_t count, void *output)
-{
-    const unsigned int attribSize = sizeof(T) * componentCount;
-    const T defaultValue = gl::bitCast<T>(widenDefaultValueBits);
-    const bool widen = (widenDefaultValueBits != 0);
+template <typename T, size_t componentCount, uint32_t widenDefaultValueBits>
+inline void CopyNativeVertexData(const uint8_t *input, size_t stride, size_t count, uint8_t *output);
 
-    if (attribSize == stride && !widen)
-    {
-        memcpy(output, input, count * attribSize);
-    }
-    else
-    {
-        unsigned int outputStride = widen ? 4 : componentCount;
+template <size_t componentCount>
+inline void Copy32FixedTo32FVertexData(const uint8_t *input, size_t stride, size_t count, uint8_t *output);
 
-        for (unsigned int i = 0; i < count; i++)
-        {
-            const T *offsetInput = reinterpret_cast<const T*>(reinterpret_cast<const char*>(input) + i * stride);
-            T *offsetOutput = reinterpret_cast<T*>(output) + i * outputStride;
-
-            for (unsigned int j = 0; j < componentCount; j++)
-            {
-                offsetOutput[j] = offsetInput[j];
-            }
-
-            if (widen)
-            {
-                offsetOutput[3] = defaultValue;
-            }
-        }
-    }
-}
-
-template <unsigned int componentCount>
-inline void copyFixedVertexData(const void* input, size_t stride, size_t count, void* output)
-{
-    static const float divisor = 1.0f / (1 << 16);
-
-    for (unsigned int i = 0; i < count; i++)
-    {
-        const GLfixed* offsetInput = reinterpret_cast<const GLfixed*>(reinterpret_cast<const char*>(input) + stride * i);
-        float* offsetOutput = reinterpret_cast<float*>(output) + i * componentCount;
-
-        for (unsigned int j = 0; j < componentCount; j++)
-        {
-            offsetOutput[j] = static_cast<float>(offsetInput[j]) * divisor;
-        }
-    }
-}
-
-template <typename T, unsigned int componentCount, bool normalized>
-inline void copyToFloatVertexData(const void* input, size_t stride, size_t count, void* output)
-{
-    typedef std::numeric_limits<T> NL;
-
-    for (unsigned int i = 0; i < count; i++)
-    {
-        const T *offsetInput = reinterpret_cast<const T*>(reinterpret_cast<const char*>(input) + stride * i);
-        float *offsetOutput = reinterpret_cast<float*>(output) + i * componentCount;
-
-        for (unsigned int j = 0; j < componentCount; j++)
-        {
-            if (normalized)
-            {
-                if (NL::is_signed)
-                {
-                    const float divisor = 1.0f / (2 * static_cast<float>(NL::max()) + 1);
-                    offsetOutput[j] = (2 * static_cast<float>(offsetInput[j]) + 1) * divisor;
-                }
-                else
-                {
-                    offsetOutput[j] =  static_cast<float>(offsetInput[j]) / NL::max();
-                }
-            }
-            else
-            {
-                offsetOutput[j] =  static_cast<float>(offsetInput[j]);
-            }
-        }
-    }
-}
-
-inline void copyPackedUnsignedVertexData(const void* input, size_t stride, size_t count, void* output)
-{
-    const unsigned int attribSize = 4;
-
-    if (attribSize == stride)
-    {
-        memcpy(output, input, count * attribSize);
-    }
-    else
-    {
-        for (unsigned int i = 0; i < count; i++)
-        {
-            const GLuint *offsetInput = reinterpret_cast<const GLuint*>(reinterpret_cast<const char*>(input) + (i * stride));
-            GLuint *offsetOutput = reinterpret_cast<GLuint*>(output) + (i * attribSize);
-
-            offsetOutput[i] = offsetInput[i];
-        }
-    }
-}
+template <typename T, size_t componentCount, bool normalized>
+inline void CopyTo32FVertexData(const uint8_t *input, size_t stride, size_t count, uint8_t *output);
 
 template <bool isSigned, bool normalized, bool toFloat>
-static inline void copyPackedRGB(unsigned int data, void *output)
-{
-    const unsigned int rgbSignMask = 0x200;       // 1 set at the 9 bit
-    const unsigned int negativeMask = 0xFFFFFC00; // All bits from 10 to 31 set to 1
+inline void CopyXYZ10W2ToXYZW32FVertexData(const uint8_t *input, size_t stride, size_t count, uint8_t *output);
 
-    if (toFloat)
-    {
-        GLfloat *floatOutput = reinterpret_cast<GLfloat*>(output);
-        if (isSigned)
-        {
-            GLfloat finalValue = 0;
-            if (data & rgbSignMask)
-            {
-                int negativeNumber = data | negativeMask;
-                finalValue = static_cast<GLfloat>(negativeNumber);
-            }
-            else
-            {
-                finalValue = static_cast<GLfloat>(data);
-            }
-
-            if (normalized)
-            {
-                const int maxValue = 0x1FF;      // 1 set in bits 0 through 8
-                const int minValue = 0xFFFFFE01; // Inverse of maxValue
-
-                // A 10-bit two's complement number has the possibility of being minValue - 1 but
-                // OpenGL's normalization rules dictate that it should be clamped to minValue in this
-                // case.
-                if (finalValue < minValue)
-                {
-                    finalValue = minValue;
-                }
-
-                const int halfRange = (maxValue - minValue) >> 1;
-                *floatOutput = ((finalValue - minValue) / halfRange) - 1.0f;
-            }
-            else
-            {
-                *floatOutput = finalValue;
-            }
-        }
-        else
-        {
-            if (normalized)
-            {
-                const unsigned int maxValue = 0x3FF; // 1 set in bits 0 through 9
-                *floatOutput = static_cast<GLfloat>(data) / static_cast<GLfloat>(maxValue);
-            }
-            else
-            {
-                *floatOutput = static_cast<GLfloat>(data);
-            }
-        }
-    }
-    else
-    {
-        if (isSigned)
-        {
-            GLshort *intOutput = reinterpret_cast<GLshort*>(output);
-
-            if (data & rgbSignMask)
-            {
-                *intOutput = data | negativeMask;
-            }
-            else
-            {
-                *intOutput = data;
-            }
-        }
-        else
-        {
-            GLushort *uintOutput = reinterpret_cast<GLushort*>(output);
-            *uintOutput = data;
-        }
-    }
 }
 
-template <bool isSigned, bool normalized, bool toFloat>
-inline void copyPackedAlpha(unsigned int data, void *output)
-{
-    if (toFloat)
-    {
-        GLfloat *floatOutput = reinterpret_cast<GLfloat*>(output);
-        if (isSigned)
-        {
-            if (normalized)
-            {
-                switch (data)
-                {
-                  case 0x0: *floatOutput =  0.0f; break;
-                  case 0x1: *floatOutput =  1.0f; break;
-                  case 0x2: *floatOutput = -1.0f; break;
-                  case 0x3: *floatOutput = -1.0f; break;
-                  default: UNREACHABLE();
-                }
-            }
-            else
-            {
-                switch (data)
-                {
-                  case 0x0: *floatOutput =  0.0f; break;
-                  case 0x1: *floatOutput =  1.0f; break;
-                  case 0x2: *floatOutput = -2.0f; break;
-                  case 0x3: *floatOutput = -1.0f; break;
-                  default: UNREACHABLE();
-                }
-            }
-        }
-        else
-        {
-            if (normalized)
-            {
-                switch (data)
-                {
-                  case 0x0: *floatOutput = 0.0f / 3.0f; break;
-                  case 0x1: *floatOutput = 1.0f / 3.0f; break;
-                  case 0x2: *floatOutput = 2.0f / 3.0f; break;
-                  case 0x3: *floatOutput = 3.0f / 3.0f; break;
-                  default: UNREACHABLE();
-                }
-            }
-            else
-            {
-                switch (data)
-                {
-                  case 0x0: *floatOutput = 0.0f; break;
-                  case 0x1: *floatOutput = 1.0f; break;
-                  case 0x2: *floatOutput = 2.0f; break;
-                  case 0x3: *floatOutput = 3.0f; break;
-                  default: UNREACHABLE();
-                }
-            }
-        }
-    }
-    else
-    {
-        if (isSigned)
-        {
-            GLshort *intOutput = reinterpret_cast<GLshort*>(output);
-            switch (data)
-            {
-              case 0x0: *intOutput =  0; break;
-              case 0x1: *intOutput =  1; break;
-              case 0x2: *intOutput = -2; break;
-              case 0x3: *intOutput = -1; break;
-              default: UNREACHABLE();
-            }
-        }
-        else
-        {
-            GLushort *uintOutput = reinterpret_cast<GLushort*>(output);
-            switch (data)
-            {
-              case 0x0: *uintOutput = 0; break;
-              case 0x1: *uintOutput = 1; break;
-              case 0x2: *uintOutput = 2; break;
-              case 0x3: *uintOutput = 3; break;
-              default: UNREACHABLE();
-            }
-        }
-    }
-}
-
-template <bool isSigned, bool normalized, bool toFloat>
-inline void copyPackedVertexData(const void* input, size_t stride, size_t count, void* output)
-{
-    const unsigned int outputComponentSize = toFloat ? 4 : 2;
-    const unsigned int componentCount = 4;
-
-    const unsigned int rgbMask = 0x3FF; // 1 set in bits 0 through 9
-    const unsigned int redShift = 0;    // red is bits 0 through 9
-    const unsigned int greenShift = 10; // green is bits 10 through 19
-    const unsigned int blueShift = 20;  // blue is bits 20 through 29
-
-    const unsigned int alphaMask = 0x3; // 1 set in bits 0 and 1
-    const unsigned int alphaShift = 30; // Alpha is the 30 and 31 bits
-
-    for (unsigned int i = 0; i < count; i++)
-    {
-        GLuint packedValue = *reinterpret_cast<const GLuint*>(reinterpret_cast<const char*>(input) + (i * stride));
-        GLbyte *offsetOutput = reinterpret_cast<GLbyte*>(output) + (i * outputComponentSize * componentCount);
-
-        copyPackedRGB<isSigned, normalized, toFloat>(  (packedValue >> redShift) & rgbMask,     offsetOutput + (0 * outputComponentSize));
-        copyPackedRGB<isSigned, normalized, toFloat>(  (packedValue >> greenShift) & rgbMask,   offsetOutput + (1 * outputComponentSize));
-        copyPackedRGB<isSigned, normalized, toFloat>(  (packedValue >> blueShift) & rgbMask,    offsetOutput + (2 * outputComponentSize));
-        copyPackedAlpha<isSigned, normalized, toFloat>((packedValue >> alphaShift) & alphaMask, offsetOutput + (3* outputComponentSize));
-    }
-}
+#include "copyvertex.inl"
 
 #endif // LIBGLESV2_RENDERER_COPYVERTEX_H_
diff --git a/src/libGLESv2/renderer/copyvertex.inl b/src/libGLESv2/renderer/copyvertex.inl
new file mode 100644
index 0000000..7eef17b
--- /dev/null
+++ b/src/libGLESv2/renderer/copyvertex.inl
@@ -0,0 +1,288 @@
+//
+// 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.
+//
+
+namespace rx
+{
+
+template <typename T, size_t componentCount, uint32_t widenDefaultValueBits>
+inline void CopyNativeVertexData(const uint8_t *input, size_t stride, size_t count, uint8_t *output)
+{
+    const size_t attribSize = sizeof(T)* componentCount;
+    const T defaultValue = gl::bitCast<T>(widenDefaultValueBits);
+    const bool widen = (widenDefaultValueBits != 0);
+
+    if (attribSize == stride && !widen)
+    {
+        memcpy(output, input, count * attribSize);
+    }
+    else
+    {
+        size_t outputStride = widen ? 4 : componentCount;
+
+        for (size_t i = 0; i < count; i++)
+        {
+            const T *offsetInput = reinterpret_cast<const T*>(input + (i * stride));
+            T *offsetOutput = reinterpret_cast<T*>(output) + i * outputStride;
+
+            for (size_t j = 0; j < componentCount; j++)
+            {
+                offsetOutput[j] = offsetInput[j];
+            }
+
+            if (widen)
+            {
+                offsetOutput[3] = defaultValue;
+            }
+        }
+    }
+}
+
+template <size_t componentCount>
+inline void Copy32FixedTo32FVertexData(const uint8_t *input, size_t stride, size_t count, uint8_t *output)
+{
+    static const float divisor = 1.0f / (1 << 16);
+
+    for (size_t i = 0; i < count; i++)
+    {
+        const GLfixed* offsetInput = reinterpret_cast<const GLfixed*>(input + (stride * i));
+        float* offsetOutput = reinterpret_cast<float*>(output) + i * componentCount;
+
+        for (size_t j = 0; j < componentCount; j++)
+        {
+            offsetOutput[j] = static_cast<float>(offsetInput[j]) * divisor;
+        }
+    }
+}
+
+template <typename T, size_t componentCount, bool normalized>
+inline void CopyTo32FVertexData(const uint8_t *input, size_t stride, size_t count, uint8_t *output)
+{
+    typedef std::numeric_limits<T> NL;
+
+    for (size_t i = 0; i < count; i++)
+    {
+        const T *offsetInput = reinterpret_cast<const T*>(input + (stride * i));
+        float *offsetOutput = reinterpret_cast<float*>(output) + i * componentCount;
+
+        for (size_t j = 0; j < componentCount; j++)
+        {
+            if (normalized)
+            {
+                if (NL::is_signed)
+                {
+                    const float divisor = 1.0f / (2 * static_cast<float>(NL::max()) + 1);
+                    offsetOutput[j] = (2 * static_cast<float>(offsetInput[j]) + 1) * divisor;
+                }
+                else
+                {
+                    offsetOutput[j] =  static_cast<float>(offsetInput[j]) / NL::max();
+                }
+            }
+            else
+            {
+                offsetOutput[j] =  static_cast<float>(offsetInput[j]);
+            }
+        }
+    }
+}
+
+namespace priv
+{
+
+template <bool isSigned, bool normalized, bool toFloat>
+static inline void CopyPackedRGB(uint32_t data, uint8_t *output)
+{
+    const uint32_t rgbSignMask = 0x200;       // 1 set at the 9 bit
+    const uint32_t negativeMask = 0xFFFFFC00; // All bits from 10 to 31 set to 1
+
+    if (toFloat)
+    {
+        GLfloat *floatOutput = reinterpret_cast<GLfloat*>(output);
+        if (isSigned)
+        {
+            GLfloat finalValue = 0;
+            if (data & rgbSignMask)
+            {
+                int negativeNumber = data | negativeMask;
+                finalValue = static_cast<GLfloat>(negativeNumber);
+            }
+            else
+            {
+                finalValue = static_cast<GLfloat>(data);
+            }
+
+            if (normalized)
+            {
+                const int32_t maxValue = 0x1FF;      // 1 set in bits 0 through 8
+                const int32_t minValue = 0xFFFFFE01; // Inverse of maxValue
+
+                // A 10-bit two's complement number has the possibility of being minValue - 1 but
+                // OpenGL's normalization rules dictate that it should be clamped to minValue in this
+                // case.
+                if (finalValue < minValue)
+                {
+                    finalValue = minValue;
+                }
+
+                const int32_t halfRange = (maxValue - minValue) >> 1;
+                *floatOutput = ((finalValue - minValue) / halfRange) - 1.0f;
+            }
+            else
+            {
+                *floatOutput = finalValue;
+            }
+        }
+        else
+        {
+            if (normalized)
+            {
+                const uint32_t maxValue = 0x3FF; // 1 set in bits 0 through 9
+                *floatOutput = static_cast<GLfloat>(data) / static_cast<GLfloat>(maxValue);
+            }
+            else
+            {
+                *floatOutput = static_cast<GLfloat>(data);
+            }
+        }
+    }
+    else
+    {
+        if (isSigned)
+        {
+            GLshort *intOutput = reinterpret_cast<GLshort*>(output);
+
+            if (data & rgbSignMask)
+            {
+                *intOutput = data | negativeMask;
+            }
+            else
+            {
+                *intOutput = data;
+            }
+        }
+        else
+        {
+            GLushort *uintOutput = reinterpret_cast<GLushort*>(output);
+            *uintOutput = data;
+        }
+    }
+}
+
+template <bool isSigned, bool normalized, bool toFloat>
+inline void CopyPackedAlpha(uint32_t data, uint8_t *output)
+{
+    if (toFloat)
+    {
+        GLfloat *floatOutput = reinterpret_cast<GLfloat*>(output);
+        if (isSigned)
+        {
+            if (normalized)
+            {
+                switch (data)
+                {
+                  case 0x0: *floatOutput =  0.0f; break;
+                  case 0x1: *floatOutput =  1.0f; break;
+                  case 0x2: *floatOutput = -1.0f; break;
+                  case 0x3: *floatOutput = -1.0f; break;
+                  default: UNREACHABLE();
+                }
+            }
+            else
+            {
+                switch (data)
+                {
+                  case 0x0: *floatOutput =  0.0f; break;
+                  case 0x1: *floatOutput =  1.0f; break;
+                  case 0x2: *floatOutput = -2.0f; break;
+                  case 0x3: *floatOutput = -1.0f; break;
+                  default: UNREACHABLE();
+                }
+            }
+        }
+        else
+        {
+            if (normalized)
+            {
+                switch (data)
+                {
+                  case 0x0: *floatOutput = 0.0f / 3.0f; break;
+                  case 0x1: *floatOutput = 1.0f / 3.0f; break;
+                  case 0x2: *floatOutput = 2.0f / 3.0f; break;
+                  case 0x3: *floatOutput = 3.0f / 3.0f; break;
+                  default: UNREACHABLE();
+                }
+            }
+            else
+            {
+                switch (data)
+                {
+                  case 0x0: *floatOutput = 0.0f; break;
+                  case 0x1: *floatOutput = 1.0f; break;
+                  case 0x2: *floatOutput = 2.0f; break;
+                  case 0x3: *floatOutput = 3.0f; break;
+                  default: UNREACHABLE();
+                }
+            }
+        }
+    }
+    else
+    {
+        if (isSigned)
+        {
+            GLshort *intOutput = reinterpret_cast<GLshort*>(output);
+            switch (data)
+            {
+              case 0x0: *intOutput =  0; break;
+              case 0x1: *intOutput =  1; break;
+              case 0x2: *intOutput = -2; break;
+              case 0x3: *intOutput = -1; break;
+              default: UNREACHABLE();
+            }
+        }
+        else
+        {
+            GLushort *uintOutput = reinterpret_cast<GLushort*>(output);
+            switch (data)
+            {
+              case 0x0: *uintOutput = 0; break;
+              case 0x1: *uintOutput = 1; break;
+              case 0x2: *uintOutput = 2; break;
+              case 0x3: *uintOutput = 3; break;
+              default: UNREACHABLE();
+            }
+        }
+    }
+}
+
+}
+
+template <bool isSigned, bool normalized, bool toFloat>
+inline void CopyXYZ10W2ToXYZW32FVertexData(const uint8_t *input, size_t stride, size_t count, uint8_t *output)
+{
+    const size_t outputComponentSize = toFloat ? 4 : 2;
+    const size_t componentCount = 4;
+
+    const uint32_t rgbMask = 0x3FF; // 1 set in bits 0 through 9
+    const size_t redShift = 0;    // red is bits 0 through 9
+    const size_t greenShift = 10; // green is bits 10 through 19
+    const size_t blueShift = 20;  // blue is bits 20 through 29
+
+    const uint32_t alphaMask = 0x3; // 1 set in bits 0 and 1
+    const size_t alphaShift = 30; // Alpha is the 30 and 31 bits
+
+    for (size_t i = 0; i < count; i++)
+    {
+        GLuint packedValue = *reinterpret_cast<const GLuint*>(input + (i * stride));
+        uint8_t *offsetOutput = output + (i * outputComponentSize * componentCount);
+
+        priv::CopyPackedRGB<isSigned, normalized, toFloat>(  (packedValue >> redShift)   & rgbMask,   offsetOutput + (0 * outputComponentSize));
+        priv::CopyPackedRGB<isSigned, normalized, toFloat>(  (packedValue >> greenShift) & rgbMask,   offsetOutput + (1 * outputComponentSize));
+        priv::CopyPackedRGB<isSigned, normalized, toFloat>(  (packedValue >> blueShift)  & rgbMask,   offsetOutput + (2 * outputComponentSize));
+        priv::CopyPackedAlpha<isSigned, normalized, toFloat>((packedValue >> alphaShift) & alphaMask, offsetOutput + (3 * outputComponentSize));
+    }
+}
+
+}
diff --git a/src/libGLESv2/renderer/d3d/BufferD3D.cpp b/src/libGLESv2/renderer/d3d/BufferD3D.cpp
index 08457af..a34ef03 100644
--- a/src/libGLESv2/renderer/d3d/BufferD3D.cpp
+++ b/src/libGLESv2/renderer/d3d/BufferD3D.cpp
@@ -1,4 +1,3 @@
-#include "precompiled.h"
 //
 // Copyright 2014 The ANGLE Project Authors. All rights reserved.
 // Use of this source code is governed by a BSD-style license that can be
@@ -8,9 +7,9 @@
 // BufferD3D.cpp Defines common functionality between the Buffer9 and Buffer11 classes.
 
 #include "libGLESv2/renderer/d3d/BufferD3D.h"
-#include "libGLESv2/renderer/Renderer.h"
 #include "libGLESv2/renderer/d3d/VertexBuffer.h"
 #include "libGLESv2/renderer/d3d/IndexBuffer.h"
+#include "libGLESv2/renderer/Renderer.h"
 #include "libGLESv2/main.h"
 
 namespace rx
diff --git a/src/libGLESv2/renderer/d3d/BufferD3D.h b/src/libGLESv2/renderer/d3d/BufferD3D.h
index 0d57338..44f14ce 100644
--- a/src/libGLESv2/renderer/d3d/BufferD3D.h
+++ b/src/libGLESv2/renderer/d3d/BufferD3D.h
@@ -11,7 +11,6 @@
 
 #include "libGLESv2/renderer/BufferImpl.h"
 #include "libGLESv2/angletypes.h"
-#include "libGLESv2/renderer/IndexRangeCache.h"
 
 namespace rx
 {
@@ -36,7 +35,6 @@
 
     rx::StaticVertexBufferInterface *getStaticVertexBuffer() { return mStaticVertexBuffer; }
     rx::StaticIndexBufferInterface *getStaticIndexBuffer() { return mStaticIndexBuffer; }
-    rx::IndexRangeCache *getIndexRangeCache() { return &mIndexRangeCache; }
 
     void initializeStaticData();
     void invalidateStaticData();
@@ -50,7 +48,6 @@
 
     rx::StaticVertexBufferInterface *mStaticVertexBuffer;
     rx::StaticIndexBufferInterface *mStaticIndexBuffer;
-    rx::IndexRangeCache mIndexRangeCache;
     unsigned int mUnmodifiedDataUse;
 };
 
diff --git a/src/libGLESv2/DynamicHLSL.cpp b/src/libGLESv2/renderer/d3d/DynamicHLSL.cpp
similarity index 86%
rename from src/libGLESv2/DynamicHLSL.cpp
rename to src/libGLESv2/renderer/d3d/DynamicHLSL.cpp
index e3ec391..13411eb 100644
--- a/src/libGLESv2/DynamicHLSL.cpp
+++ b/src/libGLESv2/renderer/d3d/DynamicHLSL.cpp
@@ -6,21 +6,23 @@
 // DynamicHLSL.cpp: Implementation for link and run-time HLSL generation
 //
 
-#include "precompiled.h"
-
-#include "libGLESv2/DynamicHLSL.h"
+#include "libGLESv2/renderer/d3d/DynamicHLSL.h"
+#include "libGLESv2/renderer/d3d/ShaderD3D.h"
+#include "libGLESv2/renderer/Renderer.h"
 #include "libGLESv2/Shader.h"
 #include "libGLESv2/Program.h"
-#include "libGLESv2/renderer/Renderer.h"
-#include "common/utilities.h"
 #include "libGLESv2/ProgramBinary.h"
 #include "libGLESv2/formatutils.h"
+
+#include "common/utilities.h"
 #include "common/blocklayout.h"
 
 // For use with ArrayString, see angleutils.h
 META_ASSERT(GL_INVALID_INDEX == UINT_MAX);
 
-namespace gl_d3d
+using namespace gl;
+
+namespace
 {
 
 std::string HLSLComponentTypeString(GLenum componentType)
@@ -68,9 +70,24 @@
     return HLSLComponentTypeString(gl::VariableComponentType(type), gl::VariableComponentCount(type));
 }
 
+const rx::PixelShaderOutputVariable &GetOutputAtLocation(const std::vector<rx::PixelShaderOutputVariable> &outputVariables,
+                                                        unsigned int location)
+{
+    for (size_t variableIndex = 0; variableIndex < outputVariables.size(); ++variableIndex)
+    {
+        if (outputVariables[variableIndex].outputIndex == location)
+        {
+            return outputVariables[variableIndex];
+        }
+    }
+
+    UNREACHABLE();
+    return outputVariables[0];
 }
 
-namespace gl
+}
+
+namespace rx
 {
 
 const std::string VERTEX_ATTRIBUTE_STUB_STRING = "@@ VERTEX ATTRIBUTES @@";
@@ -109,6 +126,7 @@
             if (available)
             {
                 varying->registerIndex = r;
+                varying->columnIndex = 0;
 
                 for (int y = 0; y < registers; y++)
                 {
@@ -142,6 +160,7 @@
                 if (available)
                 {
                     varying->registerIndex = r;
+                    varying->columnIndex = 2;
 
                     for (int y = 0; y < registers; y++)
                     {
@@ -172,7 +191,7 @@
 
         for (int x = 0; x < 4; x++)
         {
-            if (space[x] >= registers && space[x] < space[column])
+            if (space[x] >= registers && (space[column] < registers || space[x] < space[column]))
             {
                 column = x;
             }
@@ -185,6 +204,7 @@
                 if (!packing[r][column])
                 {
                     varying->registerIndex = r;
+                    varying->columnIndex = column;
 
                     for (int y = r; y < r + registers; y++)
                     {
@@ -205,19 +225,29 @@
 
 // Packs varyings into generic varying registers, using the algorithm from [OpenGL ES Shading Language 1.00 rev. 17] appendix A section 7 page 111
 // Returns the number of used varying registers, or -1 if unsuccesful
-int DynamicHLSL::packVaryings(InfoLog &infoLog, VaryingPacking packing, FragmentShader *fragmentShader,
-                              VertexShader *vertexShader, const std::vector<std::string>& transformFeedbackVaryings)
+int DynamicHLSL::packVaryings(InfoLog &infoLog, VaryingPacking packing, rx::ShaderD3D *fragmentShader,
+                              rx::ShaderD3D *vertexShader, const std::vector<std::string>& transformFeedbackVaryings)
 {
-    const int maxVaryingVectors = mRenderer->getMaxVaryingVectors();
+    // TODO (geofflang):  Use context's caps
+    const int maxVaryingVectors = mRenderer->getRendererCaps().maxVaryingVectors;
 
     vertexShader->resetVaryingsRegisterAssignment();
     fragmentShader->resetVaryingsRegisterAssignment();
 
     std::set<std::string> packedVaryings;
 
-    for (unsigned int varyingIndex = 0; varyingIndex < fragmentShader->mVaryings.size(); varyingIndex++)
+    std::vector<gl::PackedVarying> &fragmentVaryings = fragmentShader->getVaryings();
+    std::vector<gl::PackedVarying> &vertexVaryings = vertexShader->getVaryings();
+    for (unsigned int varyingIndex = 0; varyingIndex < fragmentVaryings.size(); varyingIndex++)
     {
-        PackedVarying *varying = &fragmentShader->mVaryings[varyingIndex];
+        PackedVarying *varying = &fragmentVaryings[varyingIndex];
+
+        // Do not assign registers to built-in or unreferenced varyings
+        if (varying->isBuiltIn() || !varying->staticUse)
+        {
+            continue;
+        }
+
         if (packVarying(varying, maxVaryingVectors, packing))
         {
             packedVaryings.insert(varying->name);
@@ -235,9 +265,9 @@
         if (packedVaryings.find(transformFeedbackVarying) == packedVaryings.end())
         {
             bool found = false;
-            for (unsigned int varyingIndex = 0; varyingIndex < vertexShader->mVaryings.size(); varyingIndex++)
+            for (unsigned int varyingIndex = 0; varyingIndex < vertexVaryings.size(); varyingIndex++)
             {
-                PackedVarying *varying = &vertexShader->mVaryings[varyingIndex];
+                PackedVarying *varying = &vertexVaryings[varyingIndex];
                 if (transformFeedbackVarying == varying->name)
                 {
                     if (!packVarying(varying, maxVaryingVectors, packing))
@@ -273,16 +303,19 @@
     return registers;
 }
 
-std::string DynamicHLSL::generateVaryingHLSL(VertexShader *shader) const
+std::string DynamicHLSL::generateVaryingHLSL(const ShaderD3D *shader) const
 {
     std::string varyingSemantic = getVaryingSemantic(shader->mUsesPointSize);
     std::string varyingHLSL;
 
-    for (unsigned int varyingIndex = 0; varyingIndex < shader->mVaryings.size(); varyingIndex++)
+    const std::vector<gl::PackedVarying> &varyings = shader->getVaryings();
+
+    for (unsigned int varyingIndex = 0; varyingIndex < varyings.size(); varyingIndex++)
     {
-        const PackedVarying &varying = shader->mVaryings[varyingIndex];
+        const PackedVarying &varying = varyings[varyingIndex];
         if (varying.registerAssigned())
         {
+            ASSERT(!varying.isBuiltIn());
             GLenum transposedType = TransposeMatrixType(varying.type);
             int variableRows = (varying.isStruct() ? 1 : VariableRowCount(transposedType));
 
@@ -290,6 +323,10 @@
             {
                 for (int row = 0; row < variableRows; row++)
                 {
+                    // TODO: Add checks to ensure D3D interpolation modifiers don't result in too many registers being used.
+                    // For example, if there are N registers, and we have N vec3 varyings and 1 float varying, then D3D will pack them into N registers.
+                    // If the float varying has the 'nointerpolation' modifier on it then we would need N + 1 registers, and D3D compilation will fail.
+
                     switch (varying.interpolation)
                     {
                       case sh::INTERPOLATION_SMOOTH:   varyingHLSL += "    ";                 break;
@@ -298,7 +335,7 @@
                       default:  UNREACHABLE();
                     }
 
-                    unsigned int semanticIndex = elementIndex * variableRows + varying.registerIndex + row;
+                    unsigned int semanticIndex = elementIndex * variableRows + varying.columnIndex * mRenderer->getRendererCaps().maxVaryingVectors + varying.registerIndex + row;
                     std::string n = Str(semanticIndex);
 
                     std::string typeString;
@@ -313,7 +350,7 @@
                     {
                         GLenum componentType = VariableComponentType(transposedType);
                         int columnCount = VariableColumnCount(transposedType);
-                        typeString = gl_d3d::HLSLComponentTypeString(componentType, columnCount);
+                        typeString = HLSLComponentTypeString(componentType, columnCount);
                     }
                     varyingHLSL += typeString + " v" + n + " : " + varyingSemantic + n + ";\n";
                 }
@@ -335,23 +372,22 @@
 
     for (unsigned int attributeIndex = 0; attributeIndex < MAX_VERTEX_ATTRIBS; attributeIndex++)
     {
-        ASSERT(inputIndex < MAX_VERTEX_ATTRIBS);
-
-        const VertexFormat &vertexFormat = inputLayout[inputIndex];
         const sh::Attribute &shaderAttribute = shaderAttributes[attributeIndex];
-
         if (!shaderAttribute.name.empty())
         {
+            ASSERT(inputIndex < MAX_VERTEX_ATTRIBS);
+            const VertexFormat &vertexFormat = inputLayout[inputIndex];
+
             // HLSL code for input structure
             if (IsMatrixType(shaderAttribute.type))
             {
                 // Matrix types are always transposed
-                structHLSL += "    " + gl_d3d::HLSLMatrixTypeString(TransposeMatrixType(shaderAttribute.type));
+                structHLSL += "    " + HLSLMatrixTypeString(TransposeMatrixType(shaderAttribute.type));
             }
             else
             {
                 GLenum componentType = mRenderer->getVertexComponentType(vertexFormat);
-                structHLSL += "    " + gl_d3d::HLSLComponentTypeString(componentType, VariableComponentCount(shaderAttribute.type));
+                structHLSL += "    " + HLSLComponentTypeString(componentType, VariableComponentCount(shaderAttribute.type));
             }
 
             structHLSL += " " + decorateVariable(shaderAttribute.name) + " : TEXCOORD" + Str(semanticIndex) + ";\n";
@@ -397,7 +433,7 @@
     return vertexHLSL;
 }
 
-std::string DynamicHLSL::generatePixelShaderForOutputSignature(const std::string &sourceShader, const std::vector<PixelShaderOuputVariable> &outputVariables,
+std::string DynamicHLSL::generatePixelShaderForOutputSignature(const std::string &sourceShader, const std::vector<PixelShaderOutputVariable> &outputVariables,
                                                                bool usesFragDepth, const std::vector<GLenum> &outputLayout) const
 {
     const int shaderModel = mRenderer->getMajorShaderModel();
@@ -406,17 +442,19 @@
 
     std::string declarationHLSL;
     std::string copyHLSL;
-    for (size_t i = 0; i < outputVariables.size(); i++)
-    {
-        const PixelShaderOuputVariable& outputVariable = outputVariables[i];
-        ASSERT(outputLayout.size() > outputVariable.outputIndex);
 
-        // FIXME(geofflang): Work around NVIDIA driver bug by repacking buffers
-        bool outputIndexEnabled = true; // outputLayout[outputVariable.outputIndex] != GL_NONE
-        if (outputIndexEnabled)
+    for (size_t layoutIndex = 0; layoutIndex < outputLayout.size(); ++layoutIndex)
+    {
+        GLenum binding = outputLayout[layoutIndex];
+
+        if (binding != GL_NONE)
         {
-            declarationHLSL += "    " + gl_d3d::HLSLTypeString(outputVariable.type) + " " + outputVariable.name +
-                               " : " + targetSemantic + Str(outputVariable.outputIndex) + ";\n";
+            unsigned int location = (binding - GL_COLOR_ATTACHMENT0);
+
+            const PixelShaderOutputVariable &outputVariable = GetOutputAtLocation(outputVariables, location);
+
+            declarationHLSL += "    " + HLSLTypeString(outputVariable.type) + " " + outputVariable.name +
+                               " : " + targetSemantic + Str(layoutIndex) + ";\n";
 
             copyHLSL += "    output." + outputVariable.name + " = " + outputVariable.source + ";\n";
         }
@@ -601,17 +639,19 @@
     }
 }
 
-void DynamicHLSL::storeUserLinkedVaryings(const VertexShader *vertexShader,
+void DynamicHLSL::storeUserLinkedVaryings(const rx::ShaderD3D *vertexShader,
                                           std::vector<LinkedVarying> *linkedVaryings) const
 {
     const std::string &varyingSemantic = getVaryingSemantic(vertexShader->mUsesPointSize);
-    const std::vector<PackedVarying> &varyings = vertexShader->mVaryings;
+    const std::vector<PackedVarying> &varyings = vertexShader->getVaryings();
 
     for (unsigned int varyingIndex = 0; varyingIndex < varyings.size(); varyingIndex++)
     {
         const PackedVarying &varying = varyings[varyingIndex];
+
         if (varying.registerAssigned())
         {
+            ASSERT(!varying.isBuiltIn());
             GLenum transposedType = TransposeMatrixType(varying.type);
             int variableRows = (varying.isStruct() ? 1 : VariableRowCount(transposedType));
 
@@ -624,11 +664,11 @@
 
 bool DynamicHLSL::generateShaderLinkHLSL(InfoLog &infoLog, int registers, const VaryingPacking packing,
                                          std::string& pixelHLSL, std::string& vertexHLSL,
-                                         FragmentShader *fragmentShader, VertexShader *vertexShader,
+                                         rx::ShaderD3D *fragmentShader, rx::ShaderD3D *vertexShader,
                                          const std::vector<std::string>& transformFeedbackVaryings,
                                          std::vector<LinkedVarying> *linkedVaryings,
                                          std::map<int, VariableLocation> *programOutputVars,
-                                         std::vector<PixelShaderOuputVariable> *outPixelShaderKey,
+                                         std::vector<PixelShaderOutputVariable> *outPixelShaderKey,
                                          bool *outUsesFragDepth) const
 {
     if (pixelHLSL.empty() || vertexHLSL.empty())
@@ -651,7 +691,9 @@
 
     // Write the HLSL input/output declarations
     const int shaderModel = mRenderer->getMajorShaderModel();
-    const int maxVaryingVectors = mRenderer->getMaxVaryingVectors();
+
+    // TODO (geofflang):  Use context's caps
+    const int maxVaryingVectors = mRenderer->getRendererCaps().maxVaryingVectors;
 
     const int registersNeeded = registers + (usesFragCoord ? 1 : 0) + (usesPointCoord ? 1 : 0);
 
@@ -718,9 +760,10 @@
         vertexHLSL += "    output.gl_FragCoord = gl_Position;\n";
     }
 
-    for (unsigned int vertVaryingIndex = 0; vertVaryingIndex < vertexShader->mVaryings.size(); vertVaryingIndex++)
+    const std::vector<PackedVarying> &vertexVaryings = vertexShader->getVaryings();
+    for (unsigned int vertVaryingIndex = 0; vertVaryingIndex < vertexVaryings.size(); vertVaryingIndex++)
     {
-        const PackedVarying &varying = vertexShader->mVaryings[vertVaryingIndex];
+        const PackedVarying &varying = vertexVaryings[vertVaryingIndex];
         if (varying.registerAssigned())
         {
             for (unsigned int elementIndex = 0; elementIndex < varying.elementCount(); elementIndex++)
@@ -729,39 +772,9 @@
 
                 for (int row = 0; row < variableRows; row++)
                 {
-                    int r = varying.registerIndex + elementIndex * variableRows + row;
+                    int r = varying.registerIndex + varying.columnIndex * mRenderer->getRendererCaps().maxVaryingVectors + elementIndex * variableRows + row;
                     vertexHLSL += "    output.v" + Str(r);
 
-                    bool sharedRegister = false;   // Register used by multiple varyings
-
-                    for (int x = 0; x < 4; x++)
-                    {
-                        if (packing[r][x] && packing[r][x] != packing[r][0])
-                        {
-                            sharedRegister = true;
-                            break;
-                        }
-                    }
-
-                    if(sharedRegister)
-                    {
-                        vertexHLSL += ".";
-
-                        for (int x = 0; x < 4; x++)
-                        {
-                            if (packing[r][x] == &varying)
-                            {
-                                switch(x)
-                                {
-                                  case 0: vertexHLSL += "x"; break;
-                                  case 1: vertexHLSL += "y"; break;
-                                  case 2: vertexHLSL += "z"; break;
-                                  case 3: vertexHLSL += "w"; break;
-                                }
-                            }
-                        }
-                    }
-
                     vertexHLSL += " = _" + varying.name;
 
                     if (varying.isArray())
@@ -793,7 +806,7 @@
     {
         for (unsigned int renderTargetIndex = 0; renderTargetIndex < numRenderTargets; renderTargetIndex++)
         {
-            PixelShaderOuputVariable outputKeyVariable;
+            PixelShaderOutputVariable outputKeyVariable;
             outputKeyVariable.type = GL_FLOAT_VEC4;
             outputKeyVariable.name = "gl_Color" + Str(renderTargetIndex);
             outputKeyVariable.source = broadcast ? "gl_Color[0]" : "gl_Color[" + Str(renderTargetIndex) + "]";
@@ -808,7 +821,7 @@
     {
         defineOutputVariables(fragmentShader, programOutputVars);
 
-        const std::vector<sh::Attribute> &shaderOutputVars = fragmentShader->getOutputVariables();
+        const std::vector<sh::Attribute> &shaderOutputVars = fragmentShader->getActiveOutputVariables();
         for (auto locationIt = programOutputVars->begin(); locationIt != programOutputVars->end(); locationIt++)
         {
             const VariableLocation &outputLocation = locationIt->second;
@@ -816,7 +829,9 @@
             const std::string &variableName = "out_" + outputLocation.name;
             const std::string &elementString = (outputLocation.element == GL_INVALID_INDEX ? "" : Str(outputLocation.element));
 
-            PixelShaderOuputVariable outputKeyVariable;
+            ASSERT(outputVariable.staticUse);
+
+            PixelShaderOutputVariable outputKeyVariable;
             outputKeyVariable.type = outputVariable.type;
             outputKeyVariable.name = variableName + elementString;
             outputKeyVariable.source = variableName + ArrayString(outputLocation.element);
@@ -892,18 +907,20 @@
         }
     }
 
-    for (unsigned int varyingIndex = 0; varyingIndex < fragmentShader->mVaryings.size(); varyingIndex++)
+    const std::vector<PackedVarying> &fragmentVaryings = fragmentShader->getVaryings();
+    for (unsigned int varyingIndex = 0; varyingIndex < fragmentVaryings.size(); varyingIndex++)
     {
-        const PackedVarying &varying = fragmentShader->mVaryings[varyingIndex];
+        const PackedVarying &varying = fragmentVaryings[varyingIndex];
         if (varying.registerAssigned())
         {
+            ASSERT(!varying.isBuiltIn());
             for (unsigned int elementIndex = 0; elementIndex < varying.elementCount(); elementIndex++)
             {
                 GLenum transposedType = TransposeMatrixType(varying.type);
                 int variableRows = (varying.isStruct() ? 1 : VariableRowCount(transposedType));
                 for (int row = 0; row < variableRows; row++)
                 {
-                    std::string n = Str(varying.registerIndex + elementIndex * variableRows + row);
+                    std::string n = Str(varying.registerIndex + varying.columnIndex * mRenderer->getRendererCaps().maxVaryingVectors + elementIndex * variableRows + row);
                     pixelHLSL += "    _" + varying.name;
 
                     if (varying.isArray())
@@ -934,7 +951,10 @@
                 }
             }
         }
-        else UNREACHABLE();
+        else
+        {
+            ASSERT(varying.isBuiltIn() || !varying.staticUse);
+        }
     }
 
     pixelHLSL += "\n"
@@ -946,15 +966,17 @@
     return true;
 }
 
-void DynamicHLSL::defineOutputVariables(FragmentShader *fragmentShader, std::map<int, VariableLocation> *programOutputVars) const
+void DynamicHLSL::defineOutputVariables(rx::ShaderD3D *fragmentShader, std::map<int, VariableLocation> *programOutputVars) const
 {
-    const std::vector<sh::Attribute> &shaderOutputVars = fragmentShader->getOutputVariables();
+    const std::vector<sh::Attribute> &shaderOutputVars = fragmentShader->getActiveOutputVariables();
 
     for (unsigned int outputVariableIndex = 0; outputVariableIndex < shaderOutputVars.size(); outputVariableIndex++)
     {
         const sh::Attribute &outputVariable = shaderOutputVars[outputVariableIndex];
         const int baseLocation = outputVariable.location == -1 ? 0 : outputVariable.location;
 
+        ASSERT(outputVariable.staticUse);
+
         if (outputVariable.arraySize > 0)
         {
             for (unsigned int elementIndex = 0; elementIndex < outputVariable.arraySize; elementIndex++)
@@ -972,14 +994,14 @@
     }
 }
 
-std::string DynamicHLSL::generateGeometryShaderHLSL(int registers, FragmentShader *fragmentShader, VertexShader *vertexShader) const
+std::string DynamicHLSL::generateGeometryShaderHLSL(int registers, rx::ShaderD3D *fragmentShader, rx::ShaderD3D *vertexShader) const
 {
     // for now we only handle point sprite emulation
     ASSERT(vertexShader->mUsesPointSize && mRenderer->getMajorShaderModel() >= 4);
     return generatePointSpriteHLSL(registers, fragmentShader, vertexShader);
 }
 
-std::string DynamicHLSL::generatePointSpriteHLSL(int registers, FragmentShader *fragmentShader, VertexShader *vertexShader) const
+std::string DynamicHLSL::generatePointSpriteHLSL(int registers, rx::ShaderD3D *fragmentShader, rx::ShaderD3D *vertexShader) const
 {
     ASSERT(registers >= 0);
     ASSERT(vertexShader->mUsesPointSize);
diff --git a/src/libGLESv2/renderer/d3d/DynamicHLSL.h b/src/libGLESv2/renderer/d3d/DynamicHLSL.h
new file mode 100644
index 0000000..f68ed98
--- /dev/null
+++ b/src/libGLESv2/renderer/d3d/DynamicHLSL.h
@@ -0,0 +1,104 @@
+//
+// 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.
+//
+// DynamicHLSL.h: Interface for link and run-time HLSL generation
+//
+
+#ifndef LIBGLESV2_RENDERER_DYNAMIC_HLSL_H_
+#define LIBGLESV2_RENDERER_DYNAMIC_HLSL_H_
+
+#include "common/angleutils.h"
+#include "libGLESv2/constants.h"
+
+#include "angle_gl.h"
+
+#include <vector>
+#include <map>
+
+namespace rx
+{
+class Renderer;
+}
+
+namespace sh
+{
+struct Attribute;
+struct ShaderVariable;
+}
+
+namespace gl
+{
+class InfoLog;
+struct VariableLocation;
+struct LinkedVarying;
+struct VertexAttribute;
+struct VertexFormat;
+struct PackedVarying;
+}
+
+namespace rx
+{
+class Renderer;
+class ShaderD3D;
+
+typedef const gl::PackedVarying *VaryingPacking[gl::IMPLEMENTATION_MAX_VARYING_VECTORS][4];
+
+struct PixelShaderOutputVariable
+{
+    GLenum type;
+    std::string name;
+    std::string source;
+    size_t outputIndex;
+};
+
+class DynamicHLSL
+{
+  public:
+    explicit DynamicHLSL(rx::Renderer *const renderer);
+
+    int packVaryings(gl::InfoLog &infoLog, VaryingPacking packing, rx::ShaderD3D *fragmentShader,
+                     rx::ShaderD3D *vertexShader, const std::vector<std::string>& transformFeedbackVaryings);
+    std::string generateVertexShaderForInputLayout(const std::string &sourceShader, const gl::VertexFormat inputLayout[],
+                                                   const sh::Attribute shaderAttributes[]) const;
+    std::string generatePixelShaderForOutputSignature(const std::string &sourceShader, const std::vector<PixelShaderOutputVariable> &outputVariables,
+                                                      bool usesFragDepth, const std::vector<GLenum> &outputLayout) const;
+    bool generateShaderLinkHLSL(gl::InfoLog &infoLog, int registers, const VaryingPacking packing,
+                                std::string& pixelHLSL, std::string& vertexHLSL,
+                                rx::ShaderD3D *fragmentShader, rx::ShaderD3D *vertexShader,
+                                const std::vector<std::string>& transformFeedbackVaryings,
+                                std::vector<gl::LinkedVarying> *linkedVaryings,
+                                std::map<int, gl::VariableLocation> *programOutputVars,
+                                std::vector<PixelShaderOutputVariable> *outPixelShaderKey,
+                                bool *outUsesFragDepth) const;
+
+    std::string generateGeometryShaderHLSL(int registers, rx::ShaderD3D *fragmentShader, rx::ShaderD3D *vertexShader) const;
+    void getInputLayoutSignature(const gl::VertexFormat inputLayout[], GLenum signature[]) const;
+
+  private:
+    DISALLOW_COPY_AND_ASSIGN(DynamicHLSL);
+
+    rx::Renderer *const mRenderer;
+
+    struct SemanticInfo;
+
+    std::string getVaryingSemantic(bool pointSize) const;
+    SemanticInfo getSemanticInfo(int startRegisters, bool fragCoord, bool pointCoord, bool pointSize,
+                                        bool pixelShader) const;
+    std::string generateVaryingLinkHLSL(const SemanticInfo &info, const std::string &varyingHLSL) const;
+    std::string generateVaryingHLSL(const ShaderD3D *shader) const;
+    void storeUserLinkedVaryings(const rx::ShaderD3D *vertexShader, std::vector<gl::LinkedVarying> *linkedVaryings) const;
+    void storeBuiltinLinkedVaryings(const SemanticInfo &info, std::vector<gl::LinkedVarying> *linkedVaryings) const;
+    void defineOutputVariables(rx::ShaderD3D *fragmentShader, std::map<int, gl::VariableLocation> *programOutputVars) const;
+    std::string generatePointSpriteHLSL(int registers, rx::ShaderD3D *fragmentShader, rx::ShaderD3D *vertexShader) const;
+
+    // Prepend an underscore
+    static std::string decorateVariable(const std::string &name);
+
+    std::string generateAttributeConversionHLSL(const gl::VertexFormat &vertexFormat, const sh::ShaderVariable &shaderAttrib) const;
+};
+
+}
+
+#endif // LIBGLESV2_RENDERER_DYNAMIC_HLSL_H_
diff --git a/src/libGLESv2/renderer/d3d/HLSLCompiler.cpp b/src/libGLESv2/renderer/d3d/HLSLCompiler.cpp
index fc7357a..df2e46c 100644
--- a/src/libGLESv2/renderer/d3d/HLSLCompiler.cpp
+++ b/src/libGLESv2/renderer/d3d/HLSLCompiler.cpp
@@ -1,4 +1,9 @@
-#include "precompiled.h"
+//
+// Copyright 2014 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+
 #include "libGLESv2/renderer/d3d/HLSLCompiler.h"
 #include "libGLESv2/Program.h"
 #include "libGLESv2/main.h"
diff --git a/src/libGLESv2/renderer/d3d/ImageD3D.cpp b/src/libGLESv2/renderer/d3d/ImageD3D.cpp
index 615d11a..0854b96 100644
--- a/src/libGLESv2/renderer/d3d/ImageD3D.cpp
+++ b/src/libGLESv2/renderer/d3d/ImageD3D.cpp
@@ -1,4 +1,3 @@
-#include "precompiled.h"
 //
 // 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
diff --git a/src/libGLESv2/renderer/d3d/ImageD3D.h b/src/libGLESv2/renderer/d3d/ImageD3D.h
index 242ce5a..60a6ffd 100644
--- a/src/libGLESv2/renderer/d3d/ImageD3D.h
+++ b/src/libGLESv2/renderer/d3d/ImageD3D.h
@@ -21,10 +21,7 @@
 
 namespace rx
 {
-class TextureStorageInterface2D;
-class TextureStorageInterfaceCube;
-class TextureStorageInterface3D;
-class TextureStorageInterface2DArray;
+class TextureStorage;
 
 class ImageD3D : public Image
 {
@@ -36,14 +33,14 @@
 
     virtual bool isDirty() const = 0;
 
-    virtual void setManagedSurface(TextureStorageInterface2D *storage, int level) {};
-    virtual void setManagedSurface(TextureStorageInterfaceCube *storage, int face, int level) {};
-    virtual void setManagedSurface(TextureStorageInterface3D *storage, int level) {};
-    virtual void setManagedSurface(TextureStorageInterface2DArray *storage, int layer, int level) {};
-    virtual bool copyToStorage(TextureStorageInterface2D *storage, int level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height) = 0;
-    virtual bool copyToStorage(TextureStorageInterfaceCube *storage, int face, int level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height) = 0;
-    virtual bool copyToStorage(TextureStorageInterface3D *storage, int level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth) = 0;
-    virtual bool copyToStorage(TextureStorageInterface2DArray *storage, int level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height) = 0;
+    virtual void setManagedSurface2D(TextureStorage *storage, int level) {};
+    virtual void setManagedSurfaceCube(TextureStorage *storage, int face, int level) {};
+    virtual void setManagedSurface3D(TextureStorage *storage, int level) {};
+    virtual void setManagedSurface2DArray(TextureStorage *storage, int layer, int level) {};
+    virtual bool copyToStorage2D(TextureStorage *storage, int level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height) = 0;
+    virtual bool copyToStorageCube(TextureStorage *storage, int face, int level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height) = 0;
+    virtual bool copyToStorage3D(TextureStorage *storage, int level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth) = 0;
+    virtual bool copyToStorage2DArray(TextureStorage *storage, int level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height) = 0;
 
   private:
     DISALLOW_COPY_AND_ASSIGN(ImageD3D);
diff --git a/src/libGLESv2/renderer/d3d/IndexBuffer.cpp b/src/libGLESv2/renderer/d3d/IndexBuffer.cpp
index 13e35e0..1dce127 100644
--- a/src/libGLESv2/renderer/d3d/IndexBuffer.cpp
+++ b/src/libGLESv2/renderer/d3d/IndexBuffer.cpp
@@ -1,4 +1,3 @@
-#include "precompiled.h"
 //
 // 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
@@ -67,21 +66,22 @@
     return mIndexBuffer->getSerial();
 }
 
-bool IndexBufferInterface::mapBuffer(unsigned int size, void** outMappedMemory, unsigned int *streamOffset)
+gl::Error IndexBufferInterface::mapBuffer(unsigned int size, void** outMappedMemory, unsigned int *streamOffset)
 {
     // Protect against integer overflow
     if (mWritePosition + size < mWritePosition)
     {
-        return false;
+        return gl::Error(GL_OUT_OF_MEMORY, "Mapping of internal index buffer would cause an integer overflow.");
     }
 
-    if (!mIndexBuffer->mapBuffer(mWritePosition, size, outMappedMemory))
+    gl::Error error = mIndexBuffer->mapBuffer(mWritePosition, size, outMappedMemory);
+    if (error.isError())
     {
         if (outMappedMemory)
         {
             *outMappedMemory = NULL;
         }
-        return false;
+        return error;
     }
 
     if (streamOffset)
@@ -90,10 +90,10 @@
     }
 
     mWritePosition += size;
-    return true;
+    return gl::Error(GL_NO_ERROR);
 }
 
-bool IndexBufferInterface::unmapBuffer()
+gl::Error IndexBufferInterface::unmapBuffer()
 {
     return mIndexBuffer->unmapBuffer();
 }
@@ -113,12 +113,12 @@
     mWritePosition = writePosition;
 }
 
-bool IndexBufferInterface::discard()
+gl::Error IndexBufferInterface::discard()
 {
     return mIndexBuffer->discard();
 }
 
-bool IndexBufferInterface::setBufferSize(unsigned int bufferSize, GLenum indexType)
+gl::Error IndexBufferInterface::setBufferSize(unsigned int bufferSize, GLenum indexType)
 {
     if (mIndexBuffer->getBufferSize() == 0)
     {
@@ -138,26 +138,30 @@
 {
 }
 
-bool StreamingIndexBufferInterface::reserveBufferSpace(unsigned int size, GLenum indexType)
+gl::Error StreamingIndexBufferInterface::reserveBufferSpace(unsigned int size, GLenum indexType)
 {
-    bool result = true;
     unsigned int curBufferSize = getBufferSize();
     unsigned int writePos = getWritePosition();
     if (size > curBufferSize)
     {
-        result = setBufferSize(std::max(size, 2 * curBufferSize), indexType);
+        gl::Error error = setBufferSize(std::max(size, 2 * curBufferSize), indexType);
+        if (error.isError())
+        {
+            return error;
+        }
         setWritePosition(0);
     }
     else if (writePos + size > curBufferSize || writePos + size < writePos)
     {
-        if (!discard())
+        gl::Error error = discard();
+        if (error.isError())
         {
-            return false;
+            return error;
         }
         setWritePosition(0);
     }
 
-    return result;
+    return gl::Error(GL_NO_ERROR);
 }
 
 
@@ -169,7 +173,7 @@
 {
 }
 
-bool StaticIndexBufferInterface::reserveBufferSpace(unsigned int size, GLenum indexType)
+gl::Error StaticIndexBufferInterface::reserveBufferSpace(unsigned int size, GLenum indexType)
 {
     unsigned int curSize = getBufferSize();
     if (curSize == 0)
@@ -178,13 +182,12 @@
     }
     else if (curSize >= size && indexType == getIndexType())
     {
-        return true;
+        return gl::Error(GL_NO_ERROR);
     }
     else
     {
-        ERR("Static index buffers can't be resized");
         UNREACHABLE();
-        return false;
+        return gl::Error(GL_INVALID_OPERATION, "Internal static index buffers can't be resized");
     }
 }
 
diff --git a/src/libGLESv2/renderer/d3d/IndexBuffer.h b/src/libGLESv2/renderer/d3d/IndexBuffer.h
index 6fb885a..1bb5ae2 100644
--- a/src/libGLESv2/renderer/d3d/IndexBuffer.h
+++ b/src/libGLESv2/renderer/d3d/IndexBuffer.h
@@ -11,6 +11,7 @@
 #define LIBGLESV2_RENDERER_INDEXBUFFER_H_
 
 #include "common/angleutils.h"
+#include "libGLESv2/Error.h"
 #include "libGLESv2/renderer/IndexRangeCache.h"
 
 namespace rx
@@ -23,16 +24,16 @@
     IndexBuffer();
     virtual ~IndexBuffer();
 
-    virtual bool initialize(unsigned int bufferSize, GLenum indexType, bool dynamic) = 0;
+    virtual gl::Error initialize(unsigned int bufferSize, GLenum indexType, bool dynamic) = 0;
 
-    virtual bool mapBuffer(unsigned int offset, unsigned int size, void** outMappedMemory) = 0;
-    virtual bool unmapBuffer() = 0;
+    virtual gl::Error mapBuffer(unsigned int offset, unsigned int size, void** outMappedMemory) = 0;
+    virtual gl::Error unmapBuffer() = 0;
 
-    virtual bool discard() = 0;
+    virtual gl::Error discard() = 0;
 
     virtual GLenum getIndexType() const = 0;
     virtual unsigned int getBufferSize() const = 0;
-    virtual bool setSize(unsigned int bufferSize, GLenum indexType) = 0;
+    virtual gl::Error setSize(unsigned int bufferSize, GLenum indexType) = 0;
 
     unsigned int getSerial() const;
 
@@ -52,15 +53,15 @@
     IndexBufferInterface(Renderer *renderer, bool dynamic);
     virtual ~IndexBufferInterface();
 
-    virtual bool reserveBufferSpace(unsigned int size, GLenum indexType) = 0;
+    virtual gl::Error reserveBufferSpace(unsigned int size, GLenum indexType) = 0;
 
     GLenum getIndexType() const;
     unsigned int getBufferSize() const;
 
     unsigned int getSerial() const;
 
-    bool mapBuffer(unsigned int size, void** outMappedMemory, unsigned int *streamOffset);
-    bool unmapBuffer();
+    gl::Error mapBuffer(unsigned int size, void** outMappedMemory, unsigned int *streamOffset);
+    gl::Error unmapBuffer();
 
     IndexBuffer *getIndexBuffer() const;
 
@@ -68,9 +69,9 @@
     unsigned int getWritePosition() const;
     void setWritePosition(unsigned int writePosition);
 
-    bool discard();
+    gl::Error discard();
 
-    bool setBufferSize(unsigned int bufferSize, GLenum indexType);
+    gl::Error setBufferSize(unsigned int bufferSize, GLenum indexType);
 
   private:
     DISALLOW_COPY_AND_ASSIGN(IndexBufferInterface);
@@ -89,7 +90,7 @@
     StreamingIndexBufferInterface(Renderer *renderer);
     ~StreamingIndexBufferInterface();
 
-    virtual bool reserveBufferSpace(unsigned int size, GLenum indexType);
+    virtual gl::Error reserveBufferSpace(unsigned int size, GLenum indexType);
 };
 
 class StaticIndexBufferInterface : public IndexBufferInterface
@@ -98,7 +99,7 @@
     explicit StaticIndexBufferInterface(Renderer *renderer);
     ~StaticIndexBufferInterface();
 
-    virtual bool reserveBufferSpace(unsigned int size, GLenum indexType);
+    virtual gl::Error reserveBufferSpace(unsigned int size, GLenum indexType);
 
     IndexRangeCache *getIndexRangeCache();
 
@@ -108,4 +109,4 @@
 
 }
 
-#endif // LIBGLESV2_RENDERER_INDEXBUFFER_H_
\ No newline at end of file
+#endif // LIBGLESV2_RENDERER_INDEXBUFFER_H_
diff --git a/src/libGLESv2/renderer/d3d/IndexDataManager.cpp b/src/libGLESv2/renderer/d3d/IndexDataManager.cpp
index 98716c1..8d455b4 100644
--- a/src/libGLESv2/renderer/d3d/IndexDataManager.cpp
+++ b/src/libGLESv2/renderer/d3d/IndexDataManager.cpp
@@ -1,4 +1,3 @@
-#include "precompiled.h"
 //
 // 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
@@ -10,52 +9,16 @@
 
 #include "libGLESv2/renderer/d3d/IndexDataManager.h"
 #include "libGLESv2/renderer/d3d/BufferD3D.h"
-
+#include "libGLESv2/renderer/d3d/IndexBuffer.h"
+#include "libGLESv2/renderer/Renderer.h"
 #include "libGLESv2/Buffer.h"
 #include "libGLESv2/main.h"
 #include "libGLESv2/formatutils.h"
-#include "libGLESv2/renderer/d3d/IndexBuffer.h"
-#include "libGLESv2/renderer/Renderer.h"
 
 namespace rx
 {
 
-IndexDataManager::IndexDataManager(Renderer *renderer) : mRenderer(renderer)
-{
-    mStreamingBufferShort = new StreamingIndexBufferInterface(mRenderer);
-    if (!mStreamingBufferShort->reserveBufferSpace(INITIAL_INDEX_BUFFER_SIZE, GL_UNSIGNED_SHORT))
-    {
-        delete mStreamingBufferShort;
-        mStreamingBufferShort = NULL;
-    }
-
-    mStreamingBufferInt = new StreamingIndexBufferInterface(mRenderer);
-    if (!mStreamingBufferInt->reserveBufferSpace(INITIAL_INDEX_BUFFER_SIZE, GL_UNSIGNED_INT))
-    {
-        delete mStreamingBufferInt;
-        mStreamingBufferInt = NULL;
-    }
-
-    if (!mStreamingBufferShort)
-    {
-        // Make sure both buffers are deleted.
-        delete mStreamingBufferInt;
-        mStreamingBufferInt = NULL;
-
-        ERR("Failed to allocate the streaming index buffer(s).");
-    }
-
-    mCountingBuffer = NULL;
-}
-
-IndexDataManager::~IndexDataManager()
-{
-    delete mStreamingBufferShort;
-    delete mStreamingBufferInt;
-    delete mCountingBuffer;
-}
-
-static void convertIndices(GLenum sourceType, GLenum destinationType, const void *input, GLsizei count, void *output)
+static void ConvertIndices(GLenum sourceType, GLenum destinationType, const void *input, GLsizei count, void *output)
 {
     if (sourceType == GL_UNSIGNED_BYTE)
     {
@@ -94,43 +57,21 @@
     else UNREACHABLE();
 }
 
-template <class IndexType>
-static void computeRange(const IndexType *indices, GLsizei count, GLuint *minIndex, GLuint *maxIndex)
+IndexDataManager::IndexDataManager(Renderer *renderer)
+    : mRenderer(renderer),
+      mStreamingBufferShort(NULL),
+      mStreamingBufferInt(NULL)
 {
-    *minIndex = indices[0];
-    *maxIndex = indices[0];
-
-    for (GLsizei i = 0; i < count; i++)
-    {
-        if (*minIndex > indices[i]) *minIndex = indices[i];
-        if (*maxIndex < indices[i]) *maxIndex = indices[i];
-    }
 }
 
-static void computeRange(GLenum type, const GLvoid *indices, GLsizei count, GLuint *minIndex, GLuint *maxIndex)
+IndexDataManager::~IndexDataManager()
 {
-    if (type == GL_UNSIGNED_BYTE)
-    {
-        computeRange(static_cast<const GLubyte*>(indices), count, minIndex, maxIndex);
-    }
-    else if (type == GL_UNSIGNED_INT)
-    {
-        computeRange(static_cast<const GLuint*>(indices), count, minIndex, maxIndex);
-    }
-    else if (type == GL_UNSIGNED_SHORT)
-    {
-        computeRange(static_cast<const GLushort*>(indices), count, minIndex, maxIndex);
-    }
-    else UNREACHABLE();
+    SafeDelete(mStreamingBufferShort);
+    SafeDelete(mStreamingBufferInt);
 }
 
-GLenum IndexDataManager::prepareIndexData(GLenum type, GLsizei count, gl::Buffer *buffer, const GLvoid *indices, TranslatedIndexData *translated)
+gl::Error IndexDataManager::prepareIndexData(GLenum type, GLsizei count, gl::Buffer *buffer, const GLvoid *indices, TranslatedIndexData *translated)
 {
-    if (!mStreamingBufferShort)
-    {
-        return GL_OUT_OF_MEMORY;
-    }
-
     const gl::Type &typeInfo = gl::GetTypeInfo(type);
 
     GLenum destinationIndexType = (type == GL_UNSIGNED_INT) ? GL_UNSIGNED_INT : GL_UNSIGNED_SHORT;
@@ -142,10 +83,6 @@
 
     if (buffer != NULL)
     {
-        if (reinterpret_cast<uintptr_t>(indices) > std::numeric_limits<unsigned int>::max())
-        {
-            return GL_OUT_OF_MEMORY;
-        }
         offset = static_cast<unsigned int>(reinterpret_cast<uintptr_t>(indices));
 
         storage = BufferD3D::makeBufferD3D(buffer->getImplementation());
@@ -158,17 +95,7 @@
           default: UNREACHABLE(); alignedOffset = false;
         }
 
-        // check for integer overflows
-        if (static_cast<unsigned int>(count) > (std::numeric_limits<unsigned int>::max() / typeInfo.bytes) ||
-            typeInfo.bytes * static_cast<unsigned int>(count) + offset < offset)
-        {
-            return GL_OUT_OF_MEMORY;
-        }
-
-        if (typeInfo.bytes * static_cast<unsigned int>(count) + offset > storage->getSize())
-        {
-            return GL_INVALID_OPERATION;
-        }
+        ASSERT(typeInfo.bytes * static_cast<unsigned int>(count) + offset <= storage->getSize());
 
         indices = static_cast<const GLubyte*>(storage->getData()) + offset;
     }
@@ -183,35 +110,25 @@
     {
         streamOffset = offset;
 
-        if (!storage->getIndexRangeCache()->findRange(type, offset, count, &translated->minIndex,
-                                                     &translated->maxIndex, NULL))
+        if (!buffer->getIndexRangeCache()->findRange(type, offset, count, NULL, NULL))
         {
-            computeRange(type, indices, count, &translated->minIndex, &translated->maxIndex);
-            storage->getIndexRangeCache()->addRange(type, offset, count, translated->minIndex,
-                                                   translated->maxIndex, offset);
+            buffer->getIndexRangeCache()->addRange(type, offset, count, translated->indexRange, offset);
         }
     }
     else if (staticBuffer && staticBuffer->getBufferSize() != 0 && staticBuffer->getIndexType() == type && alignedOffset)
     {
         indexBuffer = staticBuffer;
 
-        if (!staticBuffer->getIndexRangeCache()->findRange(type, offset, count, &translated->minIndex,
-                                                           &translated->maxIndex, &streamOffset))
+        if (!staticBuffer->getIndexRangeCache()->findRange(type, offset, count, NULL, &streamOffset))
         {
             streamOffset = (offset / typeInfo.bytes) * gl::GetTypeInfo(destinationIndexType).bytes;
-            computeRange(type, indices, count, &translated->minIndex, &translated->maxIndex);
-            staticBuffer->getIndexRangeCache()->addRange(type, offset, count, translated->minIndex,
-                                                         translated->maxIndex, streamOffset);
+            staticBuffer->getIndexRangeCache()->addRange(type, offset, count, translated->indexRange, streamOffset);
         }
     }
-    else
-    {
-        computeRange(type, indices, count, &translated->minIndex, &translated->maxIndex);
-    }
 
     // Avoid D3D11's primitive restart index value
     // see http://msdn.microsoft.com/en-us/library/windows/desktop/bb205124(v=vs.85).aspx
-    if (translated->maxIndex == 0xFFFF && type == GL_UNSIGNED_SHORT && mRenderer->getMajorShaderModel() > 3)
+    if (translated->indexRange.end == 0xFFFF && type == GL_UNSIGNED_SHORT && mRenderer->getMajorShaderModel() > 3)
     {
         destinationIndexType = GL_UNSIGNED_INT;
         directStorage = false;
@@ -222,7 +139,11 @@
 
     if (!directStorage && !indexBuffer)
     {
-        indexBuffer = (destinationIndexType == GL_UNSIGNED_INT) ? mStreamingBufferInt : mStreamingBufferShort;
+        gl::Error error = getStreamingIndexBuffer(destinationIndexType, &indexBuffer);
+        if (error.isError())
+        {
+            return error;
+        }
 
         unsigned int convertCount = count;
 
@@ -240,45 +161,40 @@
             }
         }
 
-        if (!indexBuffer)
-        {
-            ERR("No valid index buffer.");
-            return GL_INVALID_OPERATION;
-        }
+        ASSERT(indexBuffer);
 
         if (convertCount > std::numeric_limits<unsigned int>::max() / destTypeInfo.bytes)
         {
-            ERR("Reserving %u indicies of %u bytes each exceeds the maximum buffer size.", convertCount, destTypeInfo.bytes);
-            return GL_OUT_OF_MEMORY;
+            return gl::Error(GL_OUT_OF_MEMORY, "Reserving %u indices of %u bytes each exceeds the maximum buffer size.",
+                             convertCount, destTypeInfo.bytes);
         }
 
         unsigned int bufferSizeRequired = convertCount * destTypeInfo.bytes;
-        if (!indexBuffer->reserveBufferSpace(bufferSizeRequired, type))
+        error = indexBuffer->reserveBufferSpace(bufferSizeRequired, type);
+        if (error.isError())
         {
-            ERR("Failed to reserve %u bytes in an index buffer.", bufferSizeRequired);
-            return GL_OUT_OF_MEMORY;
+            return error;
         }
 
         void* output = NULL;
-        if (!indexBuffer->mapBuffer(bufferSizeRequired, &output, &streamOffset))
+        error = indexBuffer->mapBuffer(bufferSizeRequired, &output, &streamOffset);
+        if (error.isError())
         {
-            ERR("Failed to map index buffer.");
-            return GL_OUT_OF_MEMORY;
+            return error;
         }
 
-        convertIndices(type, destinationIndexType, staticBuffer ? storage->getData() : indices, convertCount, output);
+        ConvertIndices(type, destinationIndexType, staticBuffer ? storage->getData() : indices, convertCount, output);
 
-        if (!indexBuffer->unmapBuffer())
+        error = indexBuffer->unmapBuffer();
+        if (error.isError())
         {
-            ERR("Failed to unmap index buffer.");
-            return GL_OUT_OF_MEMORY;
+            return error;
         }
 
         if (staticBuffer)
         {
             streamOffset = (offset / typeInfo.bytes) * destTypeInfo.bytes;
-            staticBuffer->getIndexRangeCache()->addRange(type, offset, count, translated->minIndex,
-                                                         translated->maxIndex, streamOffset);
+            staticBuffer->getIndexRangeCache()->addRange(type, offset, count, translated->indexRange, streamOffset);
         }
     }
 
@@ -294,77 +210,46 @@
         storage->promoteStaticUsage(count * typeInfo.bytes);
     }
 
-    return GL_NO_ERROR;
+    return gl::Error(GL_NO_ERROR);
 }
 
-StaticIndexBufferInterface *IndexDataManager::getCountingIndices(GLsizei count)
+gl::Error IndexDataManager::getStreamingIndexBuffer(GLenum destinationIndexType, IndexBufferInterface **outBuffer)
 {
-    if (count <= 65536)   // 16-bit indices
+    ASSERT(outBuffer);
+    if (destinationIndexType == GL_UNSIGNED_INT)
     {
-        const unsigned int spaceNeeded = count * sizeof(unsigned short);
-
-        if (!mCountingBuffer || mCountingBuffer->getBufferSize() < spaceNeeded)
+        if (!mStreamingBufferInt)
         {
-            delete mCountingBuffer;
-            mCountingBuffer = new StaticIndexBufferInterface(mRenderer);
-            mCountingBuffer->reserveBufferSpace(spaceNeeded, GL_UNSIGNED_SHORT);
-
-            void* mappedMemory = NULL;
-            if (!mCountingBuffer->mapBuffer(spaceNeeded, &mappedMemory, NULL))
+            mStreamingBufferInt = new StreamingIndexBufferInterface(mRenderer);
+            gl::Error error = mStreamingBufferInt->reserveBufferSpace(INITIAL_INDEX_BUFFER_SIZE, GL_UNSIGNED_INT);
+            if (error.isError())
             {
-                ERR("Failed to map counting buffer.");
-                return NULL;
-            }
-
-            unsigned short *data = reinterpret_cast<unsigned short*>(mappedMemory);
-            for(int i = 0; i < count; i++)
-            {
-                data[i] = i;
-            }
-
-            if (!mCountingBuffer->unmapBuffer())
-            {
-                ERR("Failed to unmap counting buffer.");
-                return NULL;
+                SafeDelete(mStreamingBufferInt);
+                return error;
             }
         }
-    }
-    else if (mStreamingBufferInt)   // 32-bit indices supported
-    {
-        const unsigned int spaceNeeded = count * sizeof(unsigned int);
 
-        if (!mCountingBuffer || mCountingBuffer->getBufferSize() < spaceNeeded)
-        {
-            delete mCountingBuffer;
-            mCountingBuffer = new StaticIndexBufferInterface(mRenderer);
-            mCountingBuffer->reserveBufferSpace(spaceNeeded, GL_UNSIGNED_INT);
-
-            void* mappedMemory = NULL;
-            if (!mCountingBuffer->mapBuffer(spaceNeeded, &mappedMemory, NULL))
-            {
-                ERR("Failed to map counting buffer.");
-                return NULL;
-            }
-
-            unsigned int *data = reinterpret_cast<unsigned int*>(mappedMemory);
-            for(int i = 0; i < count; i++)
-            {
-                data[i] = i;
-            }
-
-            if (!mCountingBuffer->unmapBuffer())
-            {
-                ERR("Failed to unmap counting buffer.");
-                return NULL;
-            }
-        }
+        *outBuffer = mStreamingBufferInt;
+        return gl::Error(GL_NO_ERROR);
     }
     else
     {
-        return NULL;
-    }
+        ASSERT(destinationIndexType == GL_UNSIGNED_SHORT);
 
-    return mCountingBuffer;
+        if (!mStreamingBufferShort)
+        {
+            mStreamingBufferShort = new StreamingIndexBufferInterface(mRenderer);
+            gl::Error error = mStreamingBufferShort->reserveBufferSpace(INITIAL_INDEX_BUFFER_SIZE, GL_UNSIGNED_SHORT);
+            if (error.isError())
+            {
+                SafeDelete(mStreamingBufferShort);
+                return error;
+            }
+        }
+
+        *outBuffer = mStreamingBufferShort;
+        return gl::Error(GL_NO_ERROR);
+    }
 }
 
 }
diff --git a/src/libGLESv2/renderer/d3d/IndexDataManager.h b/src/libGLESv2/renderer/d3d/IndexDataManager.h
index b27c223..6d0b89e 100644
--- a/src/libGLESv2/renderer/d3d/IndexDataManager.h
+++ b/src/libGLESv2/renderer/d3d/IndexDataManager.h
@@ -11,6 +11,10 @@
 #define LIBGLESV2_INDEXDATAMANAGER_H_
 
 #include "common/angleutils.h"
+#include "common/mathutil.h"
+#include "libGLESv2/Error.h"
+
+#include <GLES2/gl2.h>
 
 namespace
 {
@@ -24,6 +28,7 @@
 
 namespace rx
 {
+class IndexBufferInterface;
 class StaticIndexBufferInterface;
 class StreamingIndexBufferInterface;
 class IndexBuffer;
@@ -32,8 +37,7 @@
 
 struct TranslatedIndexData
 {
-    unsigned int minIndex;
-    unsigned int maxIndex;
+    RangeUI indexRange;
     unsigned int startIndex;
     unsigned int startOffset;   // In bytes
 
@@ -49,17 +53,17 @@
     explicit IndexDataManager(Renderer *renderer);
     virtual ~IndexDataManager();
 
-    GLenum prepareIndexData(GLenum type, GLsizei count, gl::Buffer *arrayElementBuffer, const GLvoid *indices, TranslatedIndexData *translated);
-    StaticIndexBufferInterface *getCountingIndices(GLsizei count);
+    gl::Error prepareIndexData(GLenum type, GLsizei count, gl::Buffer *arrayElementBuffer, const GLvoid *indices, TranslatedIndexData *translated);
 
   private:
+     gl::Error getStreamingIndexBuffer(GLenum destinationIndexType, IndexBufferInterface **outBuffer);
+
     DISALLOW_COPY_AND_ASSIGN(IndexDataManager);
 
     Renderer *const mRenderer;
 
     StreamingIndexBufferInterface *mStreamingBufferShort;
     StreamingIndexBufferInterface *mStreamingBufferInt;
-    StaticIndexBufferInterface *mCountingBuffer;
 };
 
 }
diff --git a/src/libGLESv2/renderer/d3d/MemoryBuffer.cpp b/src/libGLESv2/renderer/d3d/MemoryBuffer.cpp
index 301bbe8..2b5b09a 100644
--- a/src/libGLESv2/renderer/d3d/MemoryBuffer.cpp
+++ b/src/libGLESv2/renderer/d3d/MemoryBuffer.cpp
@@ -5,6 +5,7 @@
 //
 
 #include "libGLESv2/renderer/d3d/MemoryBuffer.h"
+#include "common/debug.h"
 
 #include <algorithm>
 #include <cstdlib>
@@ -66,6 +67,7 @@
 
 uint8_t *MemoryBuffer::data()
 {
+    ASSERT(mData);
     return mData;
 }
 
diff --git a/src/libGLESv2/renderer/d3d/MemoryBuffer.h b/src/libGLESv2/renderer/d3d/MemoryBuffer.h
index 2484c07..c65f79f 100644
--- a/src/libGLESv2/renderer/d3d/MemoryBuffer.h
+++ b/src/libGLESv2/renderer/d3d/MemoryBuffer.h
@@ -21,6 +21,7 @@
 
     bool resize(size_t size);
     size_t size() const;
+    bool empty() const { return mSize == 0; }
 
     const uint8_t *data() const;
     uint8_t *data();
diff --git a/src/libGLESv2/renderer/d3d/ProgramD3D.cpp b/src/libGLESv2/renderer/d3d/ProgramD3D.cpp
new file mode 100644
index 0000000..d7d97cc
--- /dev/null
+++ b/src/libGLESv2/renderer/d3d/ProgramD3D.cpp
@@ -0,0 +1,205 @@
+//
+// 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.
+//
+
+// ProgramD3D.cpp: Defines the rx::ProgramD3D class which implements rx::ProgramImpl.
+
+#include "libGLESv2/renderer/d3d/ProgramD3D.h"
+
+#include "common/utilities.h"
+#include "libGLESv2/ProgramBinary.h"
+#include "libGLESv2/renderer/Renderer.h"
+#include "libGLESv2/renderer/ShaderExecutable.h"
+#include "libGLESv2/renderer/d3d/DynamicHLSL.h"
+#include "libGLESv2/renderer/d3d/ShaderD3D.h"
+#include "libGLESv2/main.h"
+
+namespace rx
+{
+
+ProgramD3D::ProgramD3D(rx::Renderer *renderer)
+    : ProgramImpl(),
+      mRenderer(renderer),
+      mDynamicHLSL(NULL),
+      mVertexWorkarounds(rx::ANGLE_D3D_WORKAROUND_NONE),
+      mPixelWorkarounds(rx::ANGLE_D3D_WORKAROUND_NONE),
+      mVertexUniformStorage(NULL),
+      mFragmentUniformStorage(NULL)
+{
+    mDynamicHLSL = new rx::DynamicHLSL(renderer);
+}
+
+ProgramD3D::~ProgramD3D()
+{
+    reset();
+    SafeDelete(mDynamicHLSL);
+}
+
+ProgramD3D *ProgramD3D::makeProgramD3D(ProgramImpl *impl)
+{
+    ASSERT(HAS_DYNAMIC_TYPE(ProgramD3D*, impl));
+    return static_cast<ProgramD3D*>(impl);
+}
+
+const ProgramD3D *ProgramD3D::makeProgramD3D(const ProgramImpl *impl)
+{
+    ASSERT(HAS_DYNAMIC_TYPE(const ProgramD3D*, impl));
+    return static_cast<const ProgramD3D*>(impl);
+}
+
+bool ProgramD3D::load(gl::InfoLog &infoLog, gl::BinaryInputStream *stream)
+{
+    stream->readString(&mVertexHLSL);
+    stream->readInt(&mVertexWorkarounds);
+    stream->readString(&mPixelHLSL);
+    stream->readInt(&mPixelWorkarounds);
+    stream->readBool(&mUsesFragDepth);
+
+    const size_t pixelShaderKeySize = stream->readInt<unsigned int>();
+    mPixelShaderKey.resize(pixelShaderKeySize);
+    for (size_t pixelShaderKeyIndex = 0; pixelShaderKeyIndex < pixelShaderKeySize; pixelShaderKeyIndex++)
+    {
+        stream->readInt(&mPixelShaderKey[pixelShaderKeyIndex].type);
+        stream->readString(&mPixelShaderKey[pixelShaderKeyIndex].name);
+        stream->readString(&mPixelShaderKey[pixelShaderKeyIndex].source);
+        stream->readInt(&mPixelShaderKey[pixelShaderKeyIndex].outputIndex);
+    }
+
+    return true;
+}
+
+bool ProgramD3D::save(gl::BinaryOutputStream *stream)
+{
+    stream->writeString(mVertexHLSL);
+    stream->writeInt(mVertexWorkarounds);
+    stream->writeString(mPixelHLSL);
+    stream->writeInt(mPixelWorkarounds);
+    stream->writeInt(mUsesFragDepth);
+
+    const std::vector<rx::PixelShaderOutputVariable> &pixelShaderKey = mPixelShaderKey;
+    stream->writeInt(pixelShaderKey.size());
+    for (size_t pixelShaderKeyIndex = 0; pixelShaderKeyIndex < pixelShaderKey.size(); pixelShaderKeyIndex++)
+    {
+        const rx::PixelShaderOutputVariable &variable = pixelShaderKey[pixelShaderKeyIndex];
+        stream->writeInt(variable.type);
+        stream->writeString(variable.name);
+        stream->writeString(variable.source);
+        stream->writeInt(variable.outputIndex);
+    }
+
+    return true;
+}
+
+rx::ShaderExecutable *ProgramD3D::getPixelExecutableForOutputLayout(gl::InfoLog &infoLog, const std::vector<GLenum> &outputSignature,
+                                                                    const std::vector<gl::LinkedVarying> &transformFeedbackLinkedVaryings,
+                                                                    bool separatedOutputBuffers)
+{
+    std::string finalPixelHLSL = mDynamicHLSL->generatePixelShaderForOutputSignature(mPixelHLSL, mPixelShaderKey, mUsesFragDepth,
+                                                                                     outputSignature);
+
+    // Generate new pixel executable
+    rx::ShaderExecutable *pixelExecutable = mRenderer->compileToExecutable(infoLog, finalPixelHLSL.c_str(), rx::SHADER_PIXEL,
+                                                                           transformFeedbackLinkedVaryings, separatedOutputBuffers,
+                                                                           mPixelWorkarounds);
+
+    return pixelExecutable;
+}
+
+rx::ShaderExecutable *ProgramD3D::getVertexExecutableForInputLayout(gl::InfoLog &infoLog,
+                                                                    const gl::VertexFormat inputLayout[gl::MAX_VERTEX_ATTRIBS],
+                                                                    const sh::Attribute shaderAttributes[],
+                                                                    const std::vector<gl::LinkedVarying> &transformFeedbackLinkedVaryings,
+                                                                    bool separatedOutputBuffers)
+{
+    // Generate new dynamic layout with attribute conversions
+    std::string finalVertexHLSL = mDynamicHLSL->generateVertexShaderForInputLayout(mVertexHLSL, inputLayout, shaderAttributes);
+
+    // Generate new vertex executable
+    rx::ShaderExecutable *vertexExecutable = mRenderer->compileToExecutable(infoLog, finalVertexHLSL.c_str(),
+                                                                            rx::SHADER_VERTEX,
+                                                                            transformFeedbackLinkedVaryings, separatedOutputBuffers,
+                                                                            mVertexWorkarounds);
+
+    return vertexExecutable;
+}
+
+bool ProgramD3D::link(gl::InfoLog &infoLog, gl::Shader *fragmentShader, gl::Shader *vertexShader,
+                      const std::vector<std::string> &transformFeedbackVaryings, int *registers,
+                      std::vector<gl::LinkedVarying> *linkedVaryings, std::map<int, gl::VariableLocation> *outputVariables)
+{
+    rx::ShaderD3D *vertexShaderD3D = rx::ShaderD3D::makeShaderD3D(vertexShader->getImplementation());
+    rx::ShaderD3D *fragmentShaderD3D = rx::ShaderD3D::makeShaderD3D(fragmentShader->getImplementation());
+
+    mPixelHLSL = fragmentShaderD3D->getTranslatedSource();
+    mPixelWorkarounds = fragmentShaderD3D->getD3DWorkarounds();
+
+    mVertexHLSL = vertexShaderD3D->getTranslatedSource();
+    mVertexWorkarounds = vertexShaderD3D->getD3DWorkarounds();
+
+    // Map the varyings to the register file
+    rx::VaryingPacking packing = { NULL };
+    *registers = mDynamicHLSL->packVaryings(infoLog, packing, fragmentShaderD3D, vertexShaderD3D, transformFeedbackVaryings);
+
+    if (*registers < 0)
+    {
+        return false;
+    }
+
+    if (!gl::ProgramBinary::linkVaryings(infoLog, fragmentShader, vertexShader))
+    {
+        return false;
+    }
+
+    if (!mDynamicHLSL->generateShaderLinkHLSL(infoLog, *registers, packing, mPixelHLSL, mVertexHLSL,
+                                              fragmentShaderD3D, vertexShaderD3D, transformFeedbackVaryings,
+                                              linkedVaryings, outputVariables, &mPixelShaderKey, &mUsesFragDepth))
+    {
+        return false;
+    }
+
+    return true;
+}
+
+void ProgramD3D::initializeUniformStorage(const std::vector<gl::LinkedUniform*> &uniforms)
+{
+    // Compute total default block size
+    unsigned int vertexRegisters = 0;
+    unsigned int fragmentRegisters = 0;
+    for (size_t uniformIndex = 0; uniformIndex < uniforms.size(); uniformIndex++)
+    {
+        const gl::LinkedUniform &uniform = *uniforms[uniformIndex];
+
+        if (!gl::IsSampler(uniform.type))
+        {
+            if (uniform.isReferencedByVertexShader())
+            {
+                vertexRegisters = std::max(vertexRegisters, uniform.vsRegisterIndex + uniform.registerCount);
+            }
+            if (uniform.isReferencedByFragmentShader())
+            {
+                fragmentRegisters = std::max(fragmentRegisters, uniform.psRegisterIndex + uniform.registerCount);
+            }
+        }
+    }
+
+    mVertexUniformStorage = mRenderer->createUniformStorage(vertexRegisters * 16u);
+    mFragmentUniformStorage = mRenderer->createUniformStorage(fragmentRegisters * 16u);
+}
+
+void ProgramD3D::reset()
+{
+    mVertexHLSL.clear();
+    mVertexWorkarounds = rx::ANGLE_D3D_WORKAROUND_NONE;
+
+    mPixelHLSL.clear();
+    mPixelWorkarounds = rx::ANGLE_D3D_WORKAROUND_NONE;
+    mUsesFragDepth = false;
+    mPixelShaderKey.clear();
+
+    SafeDelete(mVertexUniformStorage);
+    SafeDelete(mFragmentUniformStorage);
+}
+
+}
diff --git a/src/libGLESv2/renderer/d3d/ProgramD3D.h b/src/libGLESv2/renderer/d3d/ProgramD3D.h
new file mode 100644
index 0000000..d645c57
--- /dev/null
+++ b/src/libGLESv2/renderer/d3d/ProgramD3D.h
@@ -0,0 +1,87 @@
+//
+// 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.
+//
+
+// ProgramD3D.h: Defines the rx::ProgramD3D class which implements rx::ProgramImpl.
+
+#ifndef LIBGLESV2_RENDERER_PROGRAMD3D_H_
+#define LIBGLESV2_RENDERER_PROGRAMD3D_H_
+
+#include "libGLESv2/renderer/ProgramImpl.h"
+
+#include <string>
+#include <vector>
+
+namespace gl
+{
+struct LinkedUniform;
+struct VariableLocation;
+struct VertexFormat;
+}
+
+namespace rx
+{
+
+class UniformStorage;
+
+class ProgramD3D : public ProgramImpl
+{
+  public:
+    ProgramD3D(rx::Renderer *renderer);
+    virtual ~ProgramD3D();
+
+    static ProgramD3D *makeProgramD3D(ProgramImpl *impl);
+    static const ProgramD3D *makeProgramD3D(const ProgramImpl *impl);
+
+    Renderer *getRenderer() { return mRenderer; }
+    DynamicHLSL *getDynamicHLSL() { return mDynamicHLSL; }
+    const std::vector<rx::PixelShaderOutputVariable> &getPixelShaderKey() { return mPixelShaderKey; }
+
+    GLenum getBinaryFormat() { return GL_PROGRAM_BINARY_ANGLE; }
+    bool load(gl::InfoLog &infoLog, gl::BinaryInputStream *stream);
+    bool save(gl::BinaryOutputStream *stream);
+
+    ShaderExecutable *getPixelExecutableForOutputLayout(gl::InfoLog &infoLog, const std::vector<GLenum> &outputSignature,
+                                                        const std::vector<gl::LinkedVarying> &transformFeedbackLinkedVaryings,
+                                                        bool separatedOutputBuffers);
+    ShaderExecutable *getVertexExecutableForInputLayout(gl::InfoLog &infoLog,
+                                                        const gl::VertexFormat inputLayout[gl::MAX_VERTEX_ATTRIBS],
+                                                        const sh::Attribute shaderAttributes[],
+                                                        const std::vector<gl::LinkedVarying> &transformFeedbackLinkedVaryings,
+                                                        bool separatedOutputBuffers);
+
+    bool link(gl::InfoLog &infoLog, gl::Shader *fragmentShader, gl::Shader *vertexShader,
+              const std::vector<std::string> &transformFeedbackVaryings, int *registers,
+              std::vector<gl::LinkedVarying> *linkedVaryings, std::map<int, gl::VariableLocation> *outputVariables);
+
+    // D3D only
+    void initializeUniformStorage(const std::vector<gl::LinkedUniform*> &uniforms);
+
+    const UniformStorage &getVertexUniformStorage() const { return *mVertexUniformStorage; }
+    const UniformStorage &getFragmentUniformStorage() const { return *mFragmentUniformStorage; }
+
+    void reset();
+
+  private:
+    DISALLOW_COPY_AND_ASSIGN(ProgramD3D);
+
+    Renderer *mRenderer;
+    DynamicHLSL *mDynamicHLSL;
+
+    std::string mVertexHLSL;
+    rx::D3DWorkaroundType mVertexWorkarounds;
+
+    std::string mPixelHLSL;
+    rx::D3DWorkaroundType mPixelWorkarounds;
+    bool mUsesFragDepth;
+    std::vector<rx::PixelShaderOutputVariable> mPixelShaderKey;
+
+    UniformStorage *mVertexUniformStorage;
+    UniformStorage *mFragmentUniformStorage;
+};
+
+}
+
+#endif // LIBGLESV2_RENDERER_PROGRAMD3D_H_
diff --git a/src/libGLESv2/renderer/d3d/ShaderD3D.cpp b/src/libGLESv2/renderer/d3d/ShaderD3D.cpp
new file mode 100644
index 0000000..c472113
--- /dev/null
+++ b/src/libGLESv2/renderer/d3d/ShaderD3D.cpp
@@ -0,0 +1,457 @@
+//
+// 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.
+//
+
+// ShaderD3D.cpp: Defines the rx::ShaderD3D class which implements rx::ShaderImpl.
+
+#include "libGLESv2/renderer/d3d/ShaderD3D.h"
+#include "libGLESv2/renderer/Renderer.h"
+#include "libGLESv2/Shader.h"
+#include "libGLESv2/main.h"
+
+#include "common/utilities.h"
+
+namespace rx
+{
+
+template <typename VarT>
+void FilterInactiveVariables(std::vector<VarT> *variableList)
+{
+    ASSERT(variableList);
+
+    for (size_t varIndex = 0; varIndex < variableList->size();)
+    {
+        if (!(*variableList)[varIndex].staticUse)
+        {
+            variableList->erase(variableList->begin() + varIndex);
+        }
+        else
+        {
+            varIndex++;
+        }
+    }
+}
+
+void *ShaderD3D::mFragmentCompiler = NULL;
+void *ShaderD3D::mVertexCompiler = NULL;
+
+template <typename VarT>
+const std::vector<VarT> *GetShaderVariables(const std::vector<VarT> *variableList)
+{
+    ASSERT(variableList);
+    return variableList;
+}
+
+ShaderD3D::ShaderD3D(GLenum type, rx::Renderer *renderer)
+    : mType(type),
+      mRenderer(renderer),
+      mShaderVersion(100)
+{
+    uncompile();
+    initializeCompiler();
+}
+
+ShaderD3D::~ShaderD3D()
+{
+}
+
+ShaderD3D *ShaderD3D::makeShaderD3D(ShaderImpl *impl)
+{
+    ASSERT(HAS_DYNAMIC_TYPE(ShaderD3D*, impl));
+    return static_cast<ShaderD3D*>(impl);
+}
+
+const ShaderD3D *ShaderD3D::makeShaderD3D(const ShaderImpl *impl)
+{
+    ASSERT(HAS_DYNAMIC_TYPE(const ShaderD3D*, impl));
+    return static_cast<const ShaderD3D*>(impl);
+}
+
+// Perform a one-time initialization of the shader compiler (or after being destructed by releaseCompiler)
+void ShaderD3D::initializeCompiler()
+{
+    if (!mFragmentCompiler)
+    {
+        int result = ShInitialize();
+
+        if (result)
+        {
+            ShShaderOutput hlslVersion = (mRenderer->getMajorShaderModel() >= 4) ? SH_HLSL11_OUTPUT : SH_HLSL9_OUTPUT;
+
+            ShBuiltInResources resources;
+            ShInitBuiltInResources(&resources);
+
+            // TODO(geofflang): use context's caps
+            const gl::Caps &caps = mRenderer->getRendererCaps();
+            const gl::Extensions &extensions = mRenderer->getRendererExtensions();
+
+            resources.MaxVertexAttribs = caps.maxVertexAttributes;
+            resources.MaxVertexUniformVectors = caps.maxVertexUniformVectors;
+            resources.MaxVaryingVectors = caps.maxVaryingVectors;
+            resources.MaxVertexTextureImageUnits = caps.maxVertexTextureImageUnits;
+            resources.MaxCombinedTextureImageUnits = caps.maxCombinedTextureImageUnits;
+            resources.MaxTextureImageUnits = caps.maxTextureImageUnits;
+            resources.MaxFragmentUniformVectors = caps.maxFragmentUniformVectors;
+            resources.MaxDrawBuffers = caps.maxDrawBuffers;
+            resources.OES_standard_derivatives = extensions.standardDerivatives;
+            resources.EXT_draw_buffers = extensions.drawBuffers;
+            resources.EXT_shader_texture_lod = 1;
+            // resources.OES_EGL_image_external = mRenderer->getShareHandleSupport() ? 1 : 0; // TODO: commented out until the extension is actually supported.
+            resources.FragmentPrecisionHigh = 1;   // Shader Model 2+ always supports FP24 (s16e7) which corresponds to highp
+            resources.EXT_frag_depth = 1; // Shader Model 2+ always supports explicit depth output
+            // GLSL ES 3.0 constants
+            resources.MaxVertexOutputVectors = caps.maxVertexOutputComponents / 4;
+            resources.MaxFragmentInputVectors = caps.maxFragmentInputComponents / 4;
+            resources.MinProgramTexelOffset = caps.minProgramTexelOffset;
+            resources.MaxProgramTexelOffset = caps.maxProgramTexelOffset;
+
+            mFragmentCompiler = ShConstructCompiler(GL_FRAGMENT_SHADER, SH_GLES2_SPEC, hlslVersion, &resources);
+            mVertexCompiler = ShConstructCompiler(GL_VERTEX_SHADER, SH_GLES2_SPEC, hlslVersion, &resources);
+        }
+    }
+}
+
+void ShaderD3D::releaseCompiler()
+{
+    ShDestruct(mFragmentCompiler);
+    ShDestruct(mVertexCompiler);
+
+    mFragmentCompiler = NULL;
+    mVertexCompiler = NULL;
+
+    ShFinalize();
+}
+
+void ShaderD3D::parseVaryings(void *compiler)
+{
+     if (!mHlsl.empty())
+    {
+        const std::vector<sh::Varying> *varyings = ShGetVaryings(compiler);
+        ASSERT(varyings);
+
+        for (size_t varyingIndex = 0; varyingIndex < varyings->size(); varyingIndex++)
+        {
+            mVaryings.push_back(gl::PackedVarying((*varyings)[varyingIndex]));
+        }
+
+        mUsesMultipleRenderTargets = mHlsl.find("GL_USES_MRT")          != std::string::npos;
+        mUsesFragColor             = mHlsl.find("GL_USES_FRAG_COLOR")   != std::string::npos;
+        mUsesFragData              = mHlsl.find("GL_USES_FRAG_DATA")    != std::string::npos;
+        mUsesFragCoord             = mHlsl.find("GL_USES_FRAG_COORD")   != std::string::npos;
+        mUsesFrontFacing           = mHlsl.find("GL_USES_FRONT_FACING") != std::string::npos;
+        mUsesPointSize             = mHlsl.find("GL_USES_POINT_SIZE")   != std::string::npos;
+        mUsesPointCoord            = mHlsl.find("GL_USES_POINT_COORD")  != std::string::npos;
+        mUsesDepthRange            = mHlsl.find("GL_USES_DEPTH_RANGE")  != std::string::npos;
+        mUsesFragDepth             = mHlsl.find("GL_USES_FRAG_DEPTH")   != std::string::npos;
+        mUsesDiscardRewriting      = mHlsl.find("ANGLE_USES_DISCARD_REWRITING") != std::string::npos;
+        mUsesNestedBreak           = mHlsl.find("ANGLE_USES_NESTED_BREAK") != std::string::npos;
+    }
+}
+
+void ShaderD3D::resetVaryingsRegisterAssignment()
+{
+    for (size_t varyingIndex = 0; varyingIndex < mVaryings.size(); varyingIndex++)
+    {
+        mVaryings[varyingIndex].resetRegisterAssignment();
+    }
+}
+
+// initialize/clean up previous state
+void ShaderD3D::uncompile()
+{
+    // set by compileToHLSL
+    mHlsl.clear();
+    mInfoLog.clear();
+
+    mUsesMultipleRenderTargets = false;
+    mUsesFragColor = false;
+    mUsesFragData = false;
+    mUsesFragCoord = false;
+    mUsesFrontFacing = false;
+    mUsesPointSize = false;
+    mUsesPointCoord = false;
+    mUsesDepthRange = false;
+    mUsesFragDepth = false;
+    mShaderVersion = 100;
+    mUsesDiscardRewriting = false;
+    mUsesNestedBreak = false;
+
+    mVaryings.clear();
+    mUniforms.clear();
+    mInterfaceBlocks.clear();
+    mActiveAttributes.clear();
+    mActiveOutputVariables.clear();
+}
+
+void ShaderD3D::compileToHLSL(void *compiler, const std::string &source)
+{
+    // ensure the compiler is loaded
+    initializeCompiler();
+
+    int compileOptions = (SH_OBJECT_CODE | SH_VARIABLES);
+    std::string sourcePath;
+    if (gl::perfActive())
+    {
+        sourcePath = getTempPath();
+        writeFile(sourcePath.c_str(), source.c_str(), source.length());
+        compileOptions |= SH_LINE_DIRECTIVES;
+    }
+
+    int result;
+    if (sourcePath.empty())
+    {
+        const char* sourceStrings[] =
+        {
+            source.c_str(),
+        };
+
+        result = ShCompile(compiler, sourceStrings, ArraySize(sourceStrings), compileOptions);
+    }
+    else
+    {
+        const char* sourceStrings[] =
+        {
+            sourcePath.c_str(),
+            source.c_str(),
+        };
+
+        result = ShCompile(compiler, sourceStrings, ArraySize(sourceStrings), compileOptions | SH_SOURCE_PATH);
+    }
+
+    size_t shaderVersion = 100;
+    ShGetInfo(compiler, SH_SHADER_VERSION, &shaderVersion);
+
+    mShaderVersion = static_cast<int>(shaderVersion);
+
+    if (shaderVersion == 300 && mRenderer->getCurrentClientVersion() < 3)
+    {
+        mInfoLog = "GLSL ES 3.00 is not supported by OpenGL ES 2.0 contexts";
+        TRACE("\n%s", mInfoLog.c_str());
+    }
+    else if (result)
+    {
+        size_t objCodeLen = 0;
+        ShGetInfo(compiler, SH_OBJECT_CODE_LENGTH, &objCodeLen);
+
+        char* outputHLSL = new char[objCodeLen];
+        ShGetObjectCode(compiler, outputHLSL);
+
+#ifdef _DEBUG
+        std::ostringstream hlslStream;
+        hlslStream << "// GLSL\n";
+        hlslStream << "//\n";
+
+        size_t curPos = 0;
+        while (curPos != std::string::npos)
+        {
+            size_t nextLine = source.find("\n", curPos);
+            size_t len = (nextLine == std::string::npos) ? std::string::npos : (nextLine - curPos + 1);
+
+            hlslStream << "// " << source.substr(curPos, len);
+
+            curPos = (nextLine == std::string::npos) ? std::string::npos : (nextLine + 1);
+        }
+        hlslStream << "\n\n";
+        hlslStream << outputHLSL;
+        mHlsl = hlslStream.str();
+#else
+        mHlsl = outputHLSL;
+#endif
+
+        SafeDeleteArray(outputHLSL);
+
+        mUniforms = *GetShaderVariables(ShGetUniforms(compiler));
+
+        for (size_t uniformIndex = 0; uniformIndex < mUniforms.size(); uniformIndex++)
+        {
+            const sh::Uniform &uniform = mUniforms[uniformIndex];
+
+            if (uniform.staticUse)
+            {
+                unsigned int index = -1;
+                bool result = ShGetUniformRegister(compiler, uniform.name.c_str(), &index);
+                UNUSED_ASSERTION_VARIABLE(result);
+                ASSERT(result);
+
+                mUniformRegisterMap[uniform.name] = index;
+            }
+        }
+
+        mInterfaceBlocks = *GetShaderVariables(ShGetInterfaceBlocks(compiler));
+
+        for (size_t blockIndex = 0; blockIndex < mInterfaceBlocks.size(); blockIndex++)
+        {
+            const sh::InterfaceBlock &interfaceBlock = mInterfaceBlocks[blockIndex];
+
+            if (interfaceBlock.staticUse)
+            {
+                unsigned int index = -1;
+                bool result = ShGetInterfaceBlockRegister(compiler, interfaceBlock.name.c_str(), &index);
+                UNUSED_ASSERTION_VARIABLE(result);
+                ASSERT(result);
+
+                mInterfaceBlockRegisterMap[interfaceBlock.name] = index;
+            }
+        }
+    }
+    else
+    {
+        size_t infoLogLen = 0;
+        ShGetInfo(compiler, SH_INFO_LOG_LENGTH, &infoLogLen);
+
+        char* infoLog = new char[infoLogLen];
+        ShGetInfoLog(compiler, infoLog);
+        mInfoLog = infoLog;
+
+        TRACE("\n%s", mInfoLog.c_str());
+    }
+}
+
+rx::D3DWorkaroundType ShaderD3D::getD3DWorkarounds() const
+{
+    if (mUsesDiscardRewriting)
+    {
+        // ANGLE issue 486:
+        // Work-around a D3D9 compiler bug that presents itself when using conditional discard, by disabling optimization
+        return rx::ANGLE_D3D_WORKAROUND_SKIP_OPTIMIZATION;
+    }
+
+    if (mUsesNestedBreak)
+    {
+        // ANGLE issue 603:
+        // Work-around a D3D9 compiler bug that presents itself when using break in a nested loop, by maximizing optimization
+        // We want to keep the use of ANGLE_D3D_WORKAROUND_MAX_OPTIMIZATION minimal to prevent hangs, so usesDiscard takes precedence
+        return rx::ANGLE_D3D_WORKAROUND_MAX_OPTIMIZATION;
+    }
+
+    return rx::ANGLE_D3D_WORKAROUND_NONE;
+}
+
+// true if varying x has a higher priority in packing than y
+bool ShaderD3D::compareVarying(const gl::PackedVarying &x, const gl::PackedVarying &y)
+{
+    if (x.type == y.type)
+    {
+        return x.arraySize > y.arraySize;
+    }
+
+    // Special case for handling structs: we sort these to the end of the list
+    if (x.type == GL_STRUCT_ANGLEX)
+    {
+        return false;
+    }
+
+    if (y.type == GL_STRUCT_ANGLEX)
+    {
+        return true;
+    }
+
+    return gl::VariableSortOrder(x.type) < gl::VariableSortOrder(y.type);
+}
+
+unsigned int ShaderD3D::getUniformRegister(const std::string &uniformName) const
+{
+    ASSERT(mUniformRegisterMap.count(uniformName) > 0);
+    return mUniformRegisterMap.find(uniformName)->second;
+}
+
+unsigned int ShaderD3D::getInterfaceBlockRegister(const std::string &blockName) const
+{
+    ASSERT(mInterfaceBlockRegisterMap.count(blockName) > 0);
+    return mInterfaceBlockRegisterMap.find(blockName)->second;
+}
+
+void *ShaderD3D::getCompiler()
+{
+    if (mType == GL_VERTEX_SHADER)
+    {
+        return mVertexCompiler;
+    }
+    else
+    {
+        ASSERT(mType == GL_FRAGMENT_SHADER);
+        return mFragmentCompiler;
+    }
+}
+
+ShShaderOutput ShaderD3D::getCompilerOutputType(GLenum shader)
+{
+    void *compiler = NULL;
+
+    switch (shader)
+    {
+      case GL_VERTEX_SHADER:   compiler = mVertexCompiler;   break;
+      case GL_FRAGMENT_SHADER: compiler = mFragmentCompiler; break;
+      default: UNREACHABLE();  return SH_HLSL9_OUTPUT;
+    }
+
+    size_t outputType = 0;
+    ShGetInfo(compiler, SH_OUTPUT_TYPE, &outputType);
+
+    return static_cast<ShShaderOutput>(outputType);
+}
+
+bool ShaderD3D::compile(const std::string &source)
+{
+    uncompile();
+
+    void *compiler = getCompiler();
+
+    compileToHLSL(compiler, source);
+
+    if (mType == GL_VERTEX_SHADER)
+    {
+        parseAttributes(compiler);
+    }
+
+    parseVaryings(compiler);
+
+    if (mType == GL_FRAGMENT_SHADER)
+    {
+        std::sort(mVaryings.begin(), mVaryings.end(), compareVarying);
+
+        const std::string &hlsl = getTranslatedSource();
+        if (!hlsl.empty())
+        {
+            mActiveOutputVariables = *GetShaderVariables(ShGetOutputVariables(compiler));
+            FilterInactiveVariables(&mActiveOutputVariables);
+        }
+    }
+
+    return !getTranslatedSource().empty();
+}
+
+void ShaderD3D::parseAttributes(void *compiler)
+{
+    const std::string &hlsl = getTranslatedSource();
+    if (!hlsl.empty())
+    {
+        mActiveAttributes = *GetShaderVariables(ShGetAttributes(compiler));
+        FilterInactiveVariables(&mActiveAttributes);
+    }
+}
+
+int ShaderD3D::getSemanticIndex(const std::string &attributeName) const
+{
+    if (!attributeName.empty())
+    {
+        int semanticIndex = 0;
+        for (size_t attributeIndex = 0; attributeIndex < mActiveAttributes.size(); attributeIndex++)
+        {
+            const sh::ShaderVariable &attribute = mActiveAttributes[attributeIndex];
+
+            if (attribute.name == attributeName)
+            {
+                return semanticIndex;
+            }
+
+            semanticIndex += gl::VariableRegisterCount(attribute.type);
+        }
+    }
+
+    return -1;
+}
+
+}
diff --git a/src/libGLESv2/renderer/d3d/ShaderD3D.h b/src/libGLESv2/renderer/d3d/ShaderD3D.h
new file mode 100644
index 0000000..40e64cf
--- /dev/null
+++ b/src/libGLESv2/renderer/d3d/ShaderD3D.h
@@ -0,0 +1,94 @@
+//
+// 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.
+//
+
+// ShaderD3D.h: Defines the rx::ShaderD3D class which implements rx::ShaderImpl.
+
+#ifndef LIBGLESV2_RENDERER_SHADERD3D_H_
+#define LIBGLESV2_RENDERER_SHADERD3D_H_
+
+#include "libGLESv2/renderer/ShaderImpl.h"
+#include "libGLESv2/Shader.h"
+
+#include <map>
+
+namespace rx
+{
+class DynamicHLSL;
+class Renderer;
+
+class ShaderD3D : public ShaderImpl
+{
+    friend class DynamicHLSL;
+
+  public:
+    ShaderD3D(GLenum type, rx::Renderer *renderer);
+    virtual ~ShaderD3D();
+
+    static ShaderD3D *makeShaderD3D(ShaderImpl *impl);
+    static const ShaderD3D *makeShaderD3D(const ShaderImpl *impl);
+
+    // ShaderImpl implementation
+    const std::string &getInfoLog() const { return mInfoLog; }
+    const std::string &getTranslatedSource() const { return mHlsl; }
+
+    // D3D-specific methods
+    virtual void uncompile();
+    void resetVaryingsRegisterAssignment();
+    unsigned int getUniformRegister(const std::string &uniformName) const;
+    unsigned int getInterfaceBlockRegister(const std::string &blockName) const;
+    int getSemanticIndex(const std::string &attributeName) const;
+
+    rx::D3DWorkaroundType getD3DWorkarounds() const;
+    int getShaderVersion() const { return mShaderVersion; }
+    bool usesDepthRange() const { return mUsesDepthRange; }
+    bool usesPointSize() const { return mUsesPointSize; }
+
+    static void releaseCompiler();
+    static ShShaderOutput getCompilerOutputType(GLenum shader);
+
+    virtual bool compile(const std::string &source);
+
+  private:
+    DISALLOW_COPY_AND_ASSIGN(ShaderD3D);
+
+    void compileToHLSL(void *compiler, const std::string &source);
+    void parseVaryings(void *compiler);
+
+    void initializeCompiler();
+    void parseAttributes(void *compiler);
+    void *getCompiler();
+
+    static bool compareVarying(const gl::PackedVarying &x, const gl::PackedVarying &y);
+
+    static void *mFragmentCompiler;
+    static void *mVertexCompiler;
+
+    GLenum mType;
+    rx::Renderer *mRenderer;
+
+    int mShaderVersion;
+
+    bool mUsesMultipleRenderTargets;
+    bool mUsesFragColor;
+    bool mUsesFragData;
+    bool mUsesFragCoord;
+    bool mUsesFrontFacing;
+    bool mUsesPointSize;
+    bool mUsesPointCoord;
+    bool mUsesDepthRange;
+    bool mUsesFragDepth;
+    bool mUsesDiscardRewriting;
+    bool mUsesNestedBreak;
+
+    std::string mHlsl;
+    std::string mInfoLog;
+    std::map<std::string, unsigned int> mUniformRegisterMap;
+    std::map<std::string, unsigned int> mInterfaceBlockRegisterMap;
+};
+
+}
+
+#endif // LIBGLESV2_RENDERER_SHADERD3D_H_
diff --git a/src/libGLESv2/renderer/d3d/TextureD3D.cpp b/src/libGLESv2/renderer/d3d/TextureD3D.cpp
index b33c471..2650913 100644
--- a/src/libGLESv2/renderer/d3d/TextureD3D.cpp
+++ b/src/libGLESv2/renderer/d3d/TextureD3D.cpp
@@ -1,4 +1,3 @@
-#include "precompiled.h"
 //
 // Copyright 2014 The ANGLE Project Authors. All rights reserved.
 // Use of this source code is governed by a BSD-style license that can be
@@ -7,9 +6,9 @@
 
 // TextureD3D.cpp: Implementations of the Texture interfaces shared betweeen the D3D backends.
 
-#include "common/mathutil.h"
-#include "common/utilities.h"
-#include "libEGL/Surface.h"
+#include "libGLESv2/renderer/d3d/TextureD3D.h"
+#include "libGLESv2/renderer/d3d/TextureStorage.h"
+#include "libGLESv2/renderer/d3d/ImageD3D.h"
 #include "libGLESv2/Buffer.h"
 #include "libGLESv2/Framebuffer.h"
 #include "libGLESv2/Texture.h"
@@ -18,30 +17,15 @@
 #include "libGLESv2/renderer/BufferImpl.h"
 #include "libGLESv2/renderer/RenderTarget.h"
 #include "libGLESv2/renderer/Renderer.h"
-#include "libGLESv2/renderer/d3d/ImageD3D.h"
-#include "libGLESv2/renderer/d3d/TextureD3D.h"
-#include "libGLESv2/renderer/d3d/TextureStorage.h"
+
+#include "libEGL/Surface.h"
+
+#include "common/mathutil.h"
+#include "common/utilities.h"
 
 namespace rx
 {
 
-bool IsMipmapFiltered(const gl::SamplerState &samplerState)
-{
-    switch (samplerState.minFilter)
-    {
-      case GL_NEAREST:
-      case GL_LINEAR:
-        return false;
-      case GL_NEAREST_MIPMAP_NEAREST:
-      case GL_LINEAR_MIPMAP_NEAREST:
-      case GL_NEAREST_MIPMAP_LINEAR:
-      case GL_LINEAR_MIPMAP_LINEAR:
-        return true;
-      default: UNREACHABLE();
-        return false;
-    }
-}
-
 bool IsRenderTargetUsage(GLenum usage)
 {
     return (usage == GL_FRAMEBUFFER_ATTACHMENT_ANGLE);
@@ -59,6 +43,26 @@
 {
 }
 
+TextureD3D *TextureD3D::makeTextureD3D(TextureImpl *texture)
+{
+    ASSERT(HAS_DYNAMIC_TYPE(TextureD3D*, texture));
+    return static_cast<TextureD3D*>(texture);
+}
+
+TextureStorage *TextureD3D::getNativeTexture()
+{
+    // ensure the underlying texture is created
+    initializeStorage(false);
+
+    TextureStorage *storage = getBaseLevelStorage();
+    if (storage)
+    {
+        updateStorage();
+    }
+
+    return storage;
+}
+
 GLint TextureD3D::getBaseLevelWidth() const
 {
     const Image *baseImage = getBaseLevelImage();
@@ -117,7 +121,7 @@
 }
 
 bool TextureD3D::subImage(GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth,
-                       GLenum format, GLenum type, const gl::PixelUnpackState &unpack, const void *pixels, Image *image)
+                          GLenum format, GLenum type, const gl::PixelUnpackState &unpack, const void *pixels, const gl::ImageIndex &index)
 {
     const void *pixelData = pixels;
 
@@ -134,6 +138,9 @@
 
     if (pixelData != NULL)
     {
+        Image *image = getImage(index);
+        ASSERT(image);
+
         image->loadData(xoffset, yoffset, zoffset, width, height, depth, unpack.alignment, type, pixelData);
         mDirtyImages = true;
     }
@@ -206,7 +213,6 @@
 
 TextureD3D_2D::TextureD3D_2D(Renderer *renderer)
     : TextureD3D(renderer),
-      Texture2DImpl(),
       mTexStorage(NULL)
 {
     for (int i = 0; i < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS; ++i)
@@ -217,32 +223,15 @@
 
 TextureD3D_2D::~TextureD3D_2D()
 {
-    SafeDelete(mTexStorage);
-
+    // Delete the Images before the TextureStorage.
+    // Images might be relying on the TextureStorage for some of their data.
+    // If TextureStorage is deleted before the Images, then their data will be wastefully copied back from the GPU before we delete the Images.
     for (int i = 0; i < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS; ++i)
     {
         delete mImageArray[i];
     }
-}
 
-TextureD3D_2D *TextureD3D_2D::makeTextureD3D_2D(Texture2DImpl *texture)
-{
-    ASSERT(HAS_DYNAMIC_TYPE(TextureD3D_2D*, texture));
-    return static_cast<TextureD3D_2D*>(texture);
-}
-
-TextureStorageInterface *TextureD3D_2D::getNativeTexture()
-{
-    // ensure the underlying texture is created
-    initializeStorage(false);
-
-    TextureStorageInterface *storage = getBaseLevelStorage();
-    if (storage)
-    {
-        updateStorage();
-    }
-
-    return storage;
+    SafeDelete(mTexStorage);
 }
 
 Image *TextureD3D_2D::getImage(int level, int layer) const
@@ -252,6 +241,14 @@
     return mImageArray[level];
 }
 
+Image *TextureD3D_2D::getImage(const gl::ImageIndex &index) const
+{
+    ASSERT(index.mipIndex < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS);
+    ASSERT(!index.hasLayer());
+    ASSERT(index.type == GL_TEXTURE_2D);
+    return mImageArray[index.mipIndex];
+}
+
 GLsizei TextureD3D_2D::getLayerCount(int level) const
 {
     ASSERT(level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS);
@@ -308,8 +305,10 @@
     // Attempt a fast gpu copy of the pixel data to the surface
     if (isFastUnpackable(unpack, sizedInternalFormat) && isLevelComplete(level))
     {
+        gl::ImageIndex index = gl::ImageIndex::Make2D(level);
+
         // Will try to create RT storage if it does not exist
-        RenderTarget *destRenderTarget = getRenderTarget(level, 0);
+        RenderTarget *destRenderTarget = getRenderTarget(index);
         gl::Box destArea(0, 0, 0, getWidth(level), getHeight(level), 1);
 
         if (destRenderTarget && fastUnpackPixels(unpack, pixels, destArea, sizedInternalFormat, type, destRenderTarget))
@@ -343,9 +342,10 @@
 
     bool fastUnpacked = false;
 
+    gl::ImageIndex index = gl::ImageIndex::Make2D(level);
     if (isFastUnpackable(unpack, getInternalFormat(level)) && isLevelComplete(level))
     {
-        RenderTarget *renderTarget = getRenderTarget(level, 0);
+        RenderTarget *renderTarget = getRenderTarget(index);
         gl::Box destArea(xoffset, yoffset, 0, width, height, 1);
 
         if (renderTarget && fastUnpackPixels(unpack, pixels, destArea, getInternalFormat(level), type, renderTarget))
@@ -357,7 +357,7 @@
         }
     }
 
-    if (!fastUnpacked && TextureD3D::subImage(xoffset, yoffset, 0, width, height, 1, format, type, unpack, pixels, mImageArray[level]))
+    if (!fastUnpacked && TextureD3D::subImage(xoffset, yoffset, 0, width, height, 1, format, type, unpack, pixels, index))
     {
         commitRect(level, xoffset, yoffset, width, height);
     }
@@ -398,7 +398,7 @@
             sourceRect.y = y;
             sourceRect.height = height;
 
-            mRenderer->copyImage(source, sourceRect, format, 0, 0, mTexStorage, level);
+            mRenderer->copyImage2D(source, sourceRect, format, 0, 0, mTexStorage, level);
         }
     }
 }
@@ -430,9 +430,9 @@
             sourceRect.y = y;
             sourceRect.height = height;
 
-            mRenderer->copyImage(source, sourceRect,
-                                 gl::GetInternalFormatInfo(getBaseLevelInternalFormat()).format,
-                                 xoffset, yoffset, mTexStorage, level);
+            mRenderer->copyImage2D(source, sourceRect,
+                                   gl::GetInternalFormatInfo(getBaseLevelInternalFormat()).format,
+                                   xoffset, yoffset, mTexStorage, level);
         }
     }
 }
@@ -455,76 +455,9 @@
 
     mImmutable = true;
 
-    setCompleteTexStorage(new TextureStorageInterface2D(mRenderer, internalformat, IsRenderTargetUsage(mUsage), width, height, levels));
-}
-
-// Tests for 2D texture sampling completeness. [OpenGL ES 2.0.24] section 3.8.2 page 85.
-bool TextureD3D_2D::isSamplerComplete(const gl::SamplerState &samplerState) const
-{
-    GLsizei width = getBaseLevelWidth();
-    GLsizei height = getBaseLevelHeight();
-
-    if (width <= 0 || height <= 0)
-    {
-        return false;
-    }
-
-    if (!mRenderer->getRendererTextureCaps().get(getInternalFormat(0)).filterable)
-    {
-        if (samplerState.magFilter != GL_NEAREST ||
-            (samplerState.minFilter != GL_NEAREST && samplerState.minFilter != GL_NEAREST_MIPMAP_NEAREST))
-        {
-            return false;
-        }
-    }
-
-    // TODO(geofflang): use context's extensions
-    bool npotSupport = mRenderer->getRendererExtensions().textureNPOT;
-
-    if (!npotSupport)
-    {
-        if ((samplerState.wrapS != GL_CLAMP_TO_EDGE && !gl::isPow2(width)) ||
-            (samplerState.wrapT != GL_CLAMP_TO_EDGE && !gl::isPow2(height)))
-        {
-            return false;
-        }
-    }
-
-    if (IsMipmapFiltered(samplerState))
-    {
-        if (!npotSupport)
-        {
-            if (!gl::isPow2(width) || !gl::isPow2(height))
-            {
-                return false;
-            }
-        }
-
-        if (!isMipmapComplete())
-        {
-            return false;
-        }
-    }
-
-    // OpenGLES 3.0.2 spec section 3.8.13 states that a texture is not mipmap complete if:
-    // The internalformat specified for the texture arrays is a sized internal depth or
-    // depth and stencil format (see table 3.13), the value of TEXTURE_COMPARE_-
-    // MODE is NONE, and either the magnification filter is not NEAREST or the mini-
-    // fication filter is neither NEAREST nor NEAREST_MIPMAP_NEAREST.
-    const gl::InternalFormat &formatInfo = gl::GetInternalFormatInfo(getInternalFormat(0));
-    if (formatInfo.depthBits > 0 && mRenderer->getCurrentClientVersion() > 2)
-    {
-        if (samplerState.compareMode == GL_NONE)
-        {
-            if ((samplerState.minFilter != GL_NEAREST && samplerState.minFilter != GL_NEAREST_MIPMAP_NEAREST) ||
-                samplerState.magFilter != GL_NEAREST)
-            {
-                return false;
-            }
-        }
-    }
-
-    return true;
+    bool renderTarget = IsRenderTargetUsage(mUsage);
+    TextureStorage *storage = mRenderer->createTextureStorage2D(internalformat, renderTarget, width, height, levels);
+    setCompleteTexStorage(storage);
 }
 
 void TextureD3D_2D::bindTexImage(egl::Surface *surface)
@@ -537,7 +470,8 @@
     {
         SafeDelete(mTexStorage);
     }
-    mTexStorage = new TextureStorageInterface2D(mRenderer, surface->getSwapChain());
+
+    mTexStorage = mRenderer->createTextureStorage2D(surface->getSwapChain());
 
     mDirtyImages = true;
 }
@@ -568,10 +502,9 @@
 
     if (mTexStorage && mTexStorage->isRenderTarget())
     {
+        mTexStorage->generateMipmaps();
         for (int level = 1; level < levelCount; level++)
         {
-            mTexStorage->generateMipmap(level);
-
             mImageArray[level]->markClean();
         }
     }
@@ -584,15 +517,15 @@
     }
 }
 
-unsigned int TextureD3D_2D::getRenderTargetSerial(GLint level, GLint layer)
+unsigned int TextureD3D_2D::getRenderTargetSerial(const gl::ImageIndex &index)
 {
-    ASSERT(layer == 0);
-    return (ensureRenderTarget() ? mTexStorage->getRenderTargetSerial(level) : 0);
+    ASSERT(!index.hasLayer());
+    return (ensureRenderTarget() ? mTexStorage->getRenderTargetSerial(index) : 0);
 }
 
-RenderTarget *TextureD3D_2D::getRenderTarget(GLint level, GLint layer)
+RenderTarget *TextureD3D_2D::getRenderTarget(const gl::ImageIndex &index)
 {
-    ASSERT(layer == 0);
+    ASSERT(!index.hasLayer());
 
     // ensure the underlying texture is created
     if (!ensureRenderTarget())
@@ -600,52 +533,8 @@
         return NULL;
     }
 
-    updateStorageLevel(level);
-
-    // ensure this is NOT a depth texture
-    if (isDepth(level))
-    {
-        return NULL;
-    }
-
-    return mTexStorage->getRenderTarget(level);
-}
-
-RenderTarget *TextureD3D_2D::getDepthStencil(GLint level, GLint layer)
-{
-    ASSERT(layer == 0);
-
-    // ensure the underlying texture is created
-    if (!ensureRenderTarget())
-    {
-        return NULL;
-    }
-
-    updateStorageLevel(level);
-
-    // ensure this is actually a depth texture
-    if (!isDepth(level))
-    {
-        return NULL;
-    }
-
-    return mTexStorage->getRenderTarget(level);
-}
-
-// Tests for 2D texture (mipmap) completeness. [OpenGL ES 2.0.24] section 3.7.10 page 81.
-bool TextureD3D_2D::isMipmapComplete() const
-{
-    int levelCount = mipLevels();
-
-    for (int level = 0; level < levelCount; level++)
-    {
-        if (!isLevelComplete(level))
-        {
-            return false;
-        }
-    }
-
-    return true;
+    updateStorageLevel(index.mipIndex);
+    return mTexStorage->getRenderTarget(index);
 }
 
 bool TextureD3D_2D::isValidLevel(int level) const
@@ -721,20 +610,21 @@
     updateStorage();
 }
 
-TextureStorageInterface2D *TextureD3D_2D::createCompleteStorage(bool renderTarget) const
+TextureStorage *TextureD3D_2D::createCompleteStorage(bool renderTarget) const
 {
     GLsizei width = getBaseLevelWidth();
     GLsizei height = getBaseLevelHeight();
+    GLenum internalFormat = getBaseLevelInternalFormat();
 
     ASSERT(width > 0 && height > 0);
 
     // use existing storage level count, when previously specified by TexStorage*D
     GLint levels = (mTexStorage ? mTexStorage->getLevelCount() : creationLevels(width, height, 1));
 
-    return new TextureStorageInterface2D(mRenderer, getBaseLevelInternalFormat(), renderTarget, width, height, levels);
+    return mRenderer->createTextureStorage2D(internalFormat, renderTarget, width, height, levels);
 }
 
-void TextureD3D_2D::setCompleteTexStorage(TextureStorageInterface2D *newCompleteTexStorage)
+void TextureD3D_2D::setCompleteTexStorage(TextureStorage *newCompleteTexStorage)
 {
     SafeDelete(mTexStorage);
     mTexStorage = newCompleteTexStorage;
@@ -743,7 +633,7 @@
     {
         for (int level = 0; level < mTexStorage->getLevelCount(); level++)
         {
-            mImageArray[level]->setManagedSurface(mTexStorage, level);
+            mImageArray[level]->setManagedSurface2D(mTexStorage, level);
         }
     }
 
@@ -772,9 +662,9 @@
         ASSERT(mTexStorage);
         if (!mTexStorage->isRenderTarget())
         {
-            TextureStorageInterface2D *newRenderTargetStorage = createCompleteStorage(true);
+            TextureStorage *newRenderTargetStorage = createCompleteStorage(true);
 
-            if (!mRenderer->copyToRenderTarget(newRenderTargetStorage, mTexStorage))
+            if (!mRenderer->copyToRenderTarget2D(newRenderTargetStorage, mTexStorage))
             {
                 delete newRenderTargetStorage;
                 return gl::error(GL_OUT_OF_MEMORY, false);
@@ -787,7 +677,7 @@
     return (mTexStorage && mTexStorage->isRenderTarget());
 }
 
-TextureStorageInterface *TextureD3D_2D::getBaseLevelStorage()
+TextureStorage *TextureD3D_2D::getBaseLevelStorage()
 {
     return mTexStorage;
 }
@@ -842,7 +732,7 @@
     if (isValidLevel(level))
     {
         ImageD3D *image = mImageArray[level];
-        if (image->copyToStorage(mTexStorage, level, xoffset, yoffset, width, height))
+        if (image->copyToStorage2D(mTexStorage, level, xoffset, yoffset, width, height))
         {
             image->markClean();
         }
@@ -851,8 +741,7 @@
 
 
 TextureD3D_Cube::TextureD3D_Cube(Renderer *renderer)
-    : TextureCubeImpl(),
-      TextureD3D(renderer),
+    : TextureD3D(renderer),
       mTexStorage(NULL)
 {
     for (int i = 0; i < 6; i++)
@@ -866,8 +755,9 @@
 
 TextureD3D_Cube::~TextureD3D_Cube()
 {
-    SafeDelete(mTexStorage);
-
+    // Delete the Images before the TextureStorage.
+    // Images might be relying on the TextureStorage for some of their data.
+    // If TextureStorage is deleted before the Images, then their data will be wastefully copied back from the GPU before we delete the Images.
     for (int i = 0; i < 6; i++)
     {
         for (int j = 0; j < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS; ++j)
@@ -875,26 +765,8 @@
             SafeDelete(mImageArray[i][j]);
         }
     }
-}
 
-TextureD3D_Cube *TextureD3D_Cube::makeTextureD3D_Cube(TextureCubeImpl *texture)
-{
-    ASSERT(HAS_DYNAMIC_TYPE(TextureD3D_Cube*, texture));
-    return static_cast<TextureD3D_Cube*>(texture);
-}
-
-TextureStorageInterface *TextureD3D_Cube::getNativeTexture()
-{
-    // ensure the underlying texture is created
-    initializeStorage(false);
-
-    TextureStorageInterface *storage = getBaseLevelStorage();
-    if (storage)
-    {
-        updateStorage();
-    }
-
-    return storage;
+    SafeDelete(mTexStorage);
 }
 
 Image *TextureD3D_Cube::getImage(int level, int layer) const
@@ -904,6 +776,13 @@
     return mImageArray[layer][level];
 }
 
+Image *TextureD3D_Cube::getImage(const gl::ImageIndex &index) const
+{
+    ASSERT(index.mipIndex < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS);
+    ASSERT(index.layerIndex < 6);
+    return mImageArray[index.layerIndex][index.mipIndex];
+}
+
 GLsizei TextureD3D_Cube::getLayerCount(int level) const
 {
     ASSERT(level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS);
@@ -953,7 +832,8 @@
 
     int faceIndex = gl::TextureCubeMap::targetToLayerIndex(target);
 
-    if (TextureD3D::subImage(xoffset, yoffset, 0, width, height, 1, format, type, unpack, pixels, mImageArray[faceIndex][level]))
+    gl::ImageIndex index = gl::ImageIndex::MakeCube(target, level);
+    if (TextureD3D::subImage(xoffset, yoffset, 0, width, height, 1, format, type, unpack, pixels, index))
     {
         commitRect(faceIndex, level, xoffset, yoffset, width, height);
     }
@@ -998,7 +878,7 @@
             sourceRect.y = y;
             sourceRect.height = height;
 
-            mRenderer->copyImage(source, sourceRect, format, 0, 0, mTexStorage, target, level);
+            mRenderer->copyImageCube(source, sourceRect, format, 0, 0, mTexStorage, target, level);
         }
     }
 }
@@ -1031,8 +911,8 @@
             sourceRect.y = y;
             sourceRect.height = height;
 
-            mRenderer->copyImage(source, sourceRect, gl::GetInternalFormatInfo(getBaseLevelInternalFormat()).format,
-                                 xoffset, yoffset, mTexStorage, target, level);
+            mRenderer->copyImageCube(source, sourceRect, gl::GetInternalFormatInfo(getBaseLevelInternalFormat()).format,
+                                     xoffset, yoffset, mTexStorage, target, level);
         }
     }
 }
@@ -1061,50 +941,9 @@
 
     mImmutable = true;
 
-    setCompleteTexStorage(new TextureStorageInterfaceCube(mRenderer, internalformat, IsRenderTargetUsage(mUsage), width, levels));
-}
-
-bool TextureD3D_Cube::isSamplerComplete(const gl::SamplerState &samplerState) const
-{
-    int size = getBaseLevelWidth();
-
-    bool mipmapping = IsMipmapFiltered(samplerState);
-
-    // TODO(geofflang): use context's texture caps
-    if (!mRenderer->getRendererTextureCaps().get(getInternalFormat(0, 0)).filterable)
-    {
-        if (samplerState.magFilter != GL_NEAREST ||
-            (samplerState.minFilter != GL_NEAREST && samplerState.minFilter != GL_NEAREST_MIPMAP_NEAREST))
-        {
-            return false;
-        }
-    }
-
-    // TODO(geofflang): use context's extensions
-    if (!gl::isPow2(size) && !mRenderer->getRendererExtensions().textureNPOT)
-    {
-        if (samplerState.wrapS != GL_CLAMP_TO_EDGE || samplerState.wrapT != GL_CLAMP_TO_EDGE || mipmapping)
-        {
-            return false;
-        }
-    }
-
-    if (!mipmapping)
-    {
-        if (!isCubeComplete())
-        {
-            return false;
-        }
-    }
-    else
-    {
-        if (!isMipmapCubeComplete())   // Also tests for isCubeComplete()
-        {
-            return false;
-        }
-    }
-
-    return true;
+    bool renderTarget = IsRenderTargetUsage(mUsage);
+    TextureStorage *storage = mRenderer->createTextureStorageCube(internalformat, renderTarget, width, levels);
+    setCompleteTexStorage(storage);
 }
 
 // Tests for cube texture completeness. [OpenGL ES 2.0.24] section 3.7.10 page 81.
@@ -1134,6 +973,17 @@
     return true;
 }
 
+void TextureD3D_Cube::bindTexImage(egl::Surface *surface)
+{
+    UNREACHABLE();
+}
+
+void TextureD3D_Cube::releaseTexImage()
+{
+    UNREACHABLE();
+}
+
+
 void TextureD3D_Cube::generateMipmaps()
 {
     // Purge array levels 1 through q and reset them to represent the generated mipmap levels.
@@ -1149,12 +999,12 @@
 
     if (mTexStorage && mTexStorage->isRenderTarget())
     {
+        mTexStorage->generateMipmaps();
+
         for (int faceIndex = 0; faceIndex < 6; faceIndex++)
         {
             for (int level = 1; level < levelCount; level++)
             {
-                mTexStorage->generateMipmap(faceIndex, level);
-
                 mImageArray[faceIndex][level]->markClean();
             }
         }
@@ -1171,16 +1021,14 @@
     }
 }
 
-unsigned int TextureD3D_Cube::getRenderTargetSerial(GLint level, GLint layer)
+unsigned int TextureD3D_Cube::getRenderTargetSerial(const gl::ImageIndex &index)
 {
-    GLenum target = gl::TextureCubeMap::layerIndexToTarget(layer);
-    return (ensureRenderTarget() ? mTexStorage->getRenderTargetSerial(target, level) : 0);
+    return (ensureRenderTarget() ? mTexStorage->getRenderTargetSerial(index) : 0);
 }
 
-RenderTarget *TextureD3D_Cube::getRenderTarget(GLint level, GLint layer)
+RenderTarget *TextureD3D_Cube::getRenderTarget(const gl::ImageIndex &index)
 {
-    GLenum target = gl::TextureCubeMap::layerIndexToTarget(layer);
-    ASSERT(gl::IsCubemapTextureTarget(target));
+    ASSERT(gl::IsCubemapTextureTarget(index.type));
 
     // ensure the underlying texture is created
     if (!ensureRenderTarget())
@@ -1188,37 +1036,8 @@
         return NULL;
     }
 
-    updateStorageFaceLevel(layer, level);
-
-    // ensure this is NOT a depth texture
-    if (isDepth(level, layer))
-    {
-        return NULL;
-    }
-
-    return mTexStorage->getRenderTarget(target, level);
-}
-
-RenderTarget *TextureD3D_Cube::getDepthStencil(GLint level, GLint layer)
-{
-    GLenum target = gl::TextureCubeMap::layerIndexToTarget(layer);
-    ASSERT(gl::IsCubemapTextureTarget(target));
-
-    // ensure the underlying texture is created
-    if (!ensureRenderTarget())
-    {
-        return NULL;
-    }
-
-    updateStorageFaceLevel(layer, level);
-
-    // ensure this is a depth texture
-    if (!isDepth(level, layer))
-    {
-        return NULL;
-    }
-
-    return mTexStorage->getRenderTarget(target, level);
+    updateStorageFaceLevel(index.layerIndex, index.mipIndex);
+    return mTexStorage->getRenderTarget(index);
 }
 
 void TextureD3D_Cube::initializeStorage(bool renderTarget)
@@ -1244,7 +1063,7 @@
     updateStorage();
 }
 
-TextureStorageInterfaceCube *TextureD3D_Cube::createCompleteStorage(bool renderTarget) const
+TextureStorage *TextureD3D_Cube::createCompleteStorage(bool renderTarget) const
 {
     GLsizei size = getBaseLevelWidth();
 
@@ -1253,10 +1072,10 @@
     // use existing storage level count, when previously specified by TexStorage*D
     GLint levels = (mTexStorage ? mTexStorage->getLevelCount() : creationLevels(size, size, 1));
 
-    return new TextureStorageInterfaceCube(mRenderer, getBaseLevelInternalFormat(), renderTarget, size, levels);
+    return mRenderer->createTextureStorageCube(getBaseLevelInternalFormat(), renderTarget, size, levels);
 }
 
-void TextureD3D_Cube::setCompleteTexStorage(TextureStorageInterfaceCube *newCompleteTexStorage)
+void TextureD3D_Cube::setCompleteTexStorage(TextureStorage *newCompleteTexStorage)
 {
     SafeDelete(mTexStorage);
     mTexStorage = newCompleteTexStorage;
@@ -1267,7 +1086,7 @@
         {
             for (int level = 0; level < mTexStorage->getLevelCount(); level++)
             {
-                mImageArray[faceIndex][level]->setManagedSurface(mTexStorage, faceIndex, level);
+                mImageArray[faceIndex][level]->setManagedSurfaceCube(mTexStorage, faceIndex, level);
             }
         }
     }
@@ -1300,9 +1119,9 @@
         ASSERT(mTexStorage);
         if (!mTexStorage->isRenderTarget())
         {
-            TextureStorageInterfaceCube *newRenderTargetStorage = createCompleteStorage(true);
+            TextureStorage *newRenderTargetStorage = createCompleteStorage(true);
 
-            if (!mRenderer->copyToRenderTarget(newRenderTargetStorage, mTexStorage))
+            if (!mRenderer->copyToRenderTargetCube(newRenderTargetStorage, mTexStorage))
             {
                 delete newRenderTargetStorage;
                 return gl::error(GL_OUT_OF_MEMORY, false);
@@ -1315,7 +1134,7 @@
     return (mTexStorage && mTexStorage->isRenderTarget());
 }
 
-TextureStorageInterface *TextureD3D_Cube::getBaseLevelStorage()
+TextureStorage *TextureD3D_Cube::getBaseLevelStorage()
 {
     return mTexStorage;
 }
@@ -1327,40 +1146,11 @@
     return mImageArray[0][0];
 }
 
-bool TextureD3D_Cube::isMipmapCubeComplete() const
-{
-    if (isImmutable())
-    {
-        return true;
-    }
-
-    if (!isCubeComplete())
-    {
-        return false;
-    }
-
-    int levelCount = mipLevels();
-
-    for (int face = 0; face < 6; face++)
-    {
-        for (int level = 1; level < levelCount; level++)
-        {
-            if (!isFaceLevelComplete(face, level))
-            {
-                return false;
-            }
-        }
-    }
-
-    return true;
-}
-
 bool TextureD3D_Cube::isValidFaceLevel(int faceIndex, int level) const
 {
     return (mTexStorage ? (level >= 0 && level < mTexStorage->getLevelCount()) : 0);
 }
 
-
 bool TextureD3D_Cube::isFaceLevelComplete(int faceIndex, int level) const
 {
     ASSERT(level >= 0 && faceIndex < 6 && level < (int)ArraySize(mImageArray[faceIndex]) && mImageArray[faceIndex][level] != NULL);
@@ -1450,15 +1240,14 @@
     if (isValidFaceLevel(faceIndex, level))
     {
         ImageD3D *image = mImageArray[faceIndex][level];
-        if (image->copyToStorage(mTexStorage, faceIndex, level, xoffset, yoffset, width, height))
+        if (image->copyToStorageCube(mTexStorage, faceIndex, level, xoffset, yoffset, width, height))
             image->markClean();
     }
 }
 
 
 TextureD3D_3D::TextureD3D_3D(Renderer *renderer)
-    : Texture3DImpl(),
-      TextureD3D(renderer),
+    : TextureD3D(renderer),
       mTexStorage(NULL)
 {
     for (int i = 0; i < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS; ++i)
@@ -1469,32 +1258,15 @@
 
 TextureD3D_3D::~TextureD3D_3D()
 {
-    SafeDelete(mTexStorage);
-
+    // Delete the Images before the TextureStorage.
+    // Images might be relying on the TextureStorage for some of their data.
+    // If TextureStorage is deleted before the Images, then their data will be wastefully copied back from the GPU before we delete the Images.
     for (int i = 0; i < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS; ++i)
     {
         delete mImageArray[i];
     }
-}
 
-TextureD3D_3D *TextureD3D_3D::makeTextureD3D_3D(Texture3DImpl *texture)
-{
-    ASSERT(HAS_DYNAMIC_TYPE(TextureD3D_3D*, texture));
-    return static_cast<TextureD3D_3D*>(texture);
-}
-
-TextureStorageInterface *TextureD3D_3D::getNativeTexture()
-{
-    // ensure the underlying texture is created
-    initializeStorage(false);
-
-    TextureStorageInterface *storage = getBaseLevelStorage();
-    if (storage)
-    {
-        updateStorage();
-    }
-
-    return storage;
+    SafeDelete(mTexStorage);
 }
 
 Image *TextureD3D_3D::getImage(int level, int layer) const
@@ -1504,6 +1276,14 @@
     return mImageArray[level];
 }
 
+Image *TextureD3D_3D::getImage(const gl::ImageIndex &index) const
+{
+    ASSERT(index.mipIndex < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS);
+    ASSERT(!index.hasLayer());
+    ASSERT(index.type == GL_TEXTURE_3D);
+    return mImageArray[index.mipIndex];
+}
+
 GLsizei TextureD3D_3D::getLayerCount(int level) const
 {
     ASSERT(level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS);
@@ -1560,7 +1340,8 @@
     if (isFastUnpackable(unpack, sizedInternalFormat))
     {
         // Will try to create RT storage if it does not exist
-        RenderTarget *destRenderTarget = getRenderTarget(level);
+        gl::ImageIndex index = gl::ImageIndex::Make3D(level);
+        RenderTarget *destRenderTarget = getRenderTarget(index);
         gl::Box destArea(0, 0, 0, getWidth(level), getHeight(level), getDepth(level));
 
         if (destRenderTarget && fastUnpackPixels(unpack, pixels, destArea, sizedInternalFormat, type, destRenderTarget))
@@ -1594,10 +1375,12 @@
 
     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, getInternalFormat(level)))
     {
-        RenderTarget *destRenderTarget = getRenderTarget(level);
+        RenderTarget *destRenderTarget = getRenderTarget(index);
         gl::Box destArea(xoffset, yoffset, zoffset, width, height, depth);
 
         if (destRenderTarget && fastUnpackPixels(unpack, pixels, destArea, getInternalFormat(level), type, destRenderTarget))
@@ -1609,7 +1392,7 @@
         }
     }
 
-    if (!fastUnpacked && TextureD3D::subImage(xoffset, yoffset, zoffset, width, height, depth, format, type, unpack, pixels, mImageArray[level]))
+    if (!fastUnpacked && TextureD3D::subImage(xoffset, yoffset, zoffset, width, height, depth, format, type, unpack, pixels, index))
     {
         commitRect(level, xoffset, yoffset, zoffset, width, height, depth);
     }
@@ -1657,9 +1440,9 @@
             sourceRect.y = y;
             sourceRect.height = height;
 
-            mRenderer->copyImage(source, sourceRect,
-                                 gl::GetInternalFormatInfo(getBaseLevelInternalFormat()).format,
-                                 xoffset, yoffset, zoffset, mTexStorage, level);
+            mRenderer->copyImage3D(source, sourceRect,
+                                   gl::GetInternalFormatInfo(getBaseLevelInternalFormat()).format,
+                                   xoffset, yoffset, zoffset, mTexStorage, level);
         }
     }
 }
@@ -1683,53 +1466,22 @@
 
     mImmutable = true;
 
-    setCompleteTexStorage(new TextureStorageInterface3D(mRenderer, internalformat, IsRenderTargetUsage(mUsage), width, height, depth, levels));
+    bool renderTarget = IsRenderTargetUsage(mUsage);
+    TextureStorage *storage = mRenderer->createTextureStorage3D(internalformat, renderTarget, width, height, depth, levels);
+    setCompleteTexStorage(storage);
 }
 
-bool TextureD3D_3D::isSamplerComplete(const gl::SamplerState &samplerState) const
+void TextureD3D_3D::bindTexImage(egl::Surface *surface)
 {
-    GLsizei width = getBaseLevelWidth();
-    GLsizei height = getBaseLevelHeight();
-    GLsizei depth = getBaseLevelDepth();
-
-    if (width <= 0 || height <= 0 || depth <= 0)
-    {
-        return false;
-    }
-
-    // TODO(geofflang): use context's texture caps
-    if (!mRenderer->getRendererTextureCaps().get(getInternalFormat(0)).filterable)
-    {
-        if (samplerState.magFilter != GL_NEAREST ||
-            (samplerState.minFilter != GL_NEAREST && samplerState.minFilter != GL_NEAREST_MIPMAP_NEAREST))
-        {
-            return false;
-        }
-    }
-
-    if (IsMipmapFiltered(samplerState) && !isMipmapComplete())
-    {
-        return false;
-    }
-
-    return true;
+    UNREACHABLE();
 }
 
-bool TextureD3D_3D::isMipmapComplete() const
+void TextureD3D_3D::releaseTexImage()
 {
-    int levelCount = mipLevels();
-
-    for (int level = 0; level < levelCount; level++)
-    {
-        if (!isLevelComplete(level))
-        {
-            return false;
-        }
-    }
-
-    return true;
+    UNREACHABLE();
 }
 
+
 void TextureD3D_3D::generateMipmaps()
 {
     // Purge array levels 1 through q and reset them to represent the generated mipmap levels.
@@ -1744,10 +1496,10 @@
 
     if (mTexStorage && mTexStorage->isRenderTarget())
     {
+        mTexStorage->generateMipmaps();
+
         for (int level = 1; level < levelCount; level++)
         {
-            mTexStorage->generateMipmap(level);
-
             mImageArray[level]->markClean();
         }
     }
@@ -1760,12 +1512,12 @@
     }
 }
 
-unsigned int TextureD3D_3D::getRenderTargetSerial(GLint level, GLint layer)
+unsigned int TextureD3D_3D::getRenderTargetSerial(const gl::ImageIndex &index)
 {
-    return (ensureRenderTarget() ? mTexStorage->getRenderTargetSerial(level, layer) : 0);
+    return (ensureRenderTarget() ? mTexStorage->getRenderTargetSerial(index) : 0);
 }
 
-RenderTarget *TextureD3D_3D::getRenderTarget(GLint level)
+RenderTarget *TextureD3D_3D::getRenderTarget(const gl::ImageIndex &index)
 {
     // ensure the underlying texture is created
     if (!ensureRenderTarget())
@@ -1773,53 +1525,16 @@
         return NULL;
     }
 
-    updateStorageLevel(level);
-
-    // ensure this is NOT a depth texture
-    if (isDepth(level))
+    if (index.hasLayer())
     {
-        return NULL;
+        updateStorage();
+    }
+    else
+    {
+        updateStorageLevel(index.mipIndex);
     }
 
-    return mTexStorage->getRenderTarget(level);
-}
-
-RenderTarget *TextureD3D_3D::getRenderTarget(GLint level, GLint layer)
-{
-    // ensure the underlying texture is created
-    if (!ensureRenderTarget())
-    {
-        return NULL;
-    }
-
-    updateStorage();
-
-    // ensure this is NOT a depth texture
-    if (isDepth(level))
-    {
-        return NULL;
-    }
-
-    return mTexStorage->getRenderTarget(level, layer);
-}
-
-RenderTarget *TextureD3D_3D::getDepthStencil(GLint level, GLint layer)
-{
-    // ensure the underlying texture is created
-    if (!ensureRenderTarget())
-    {
-        return NULL;
-    }
-
-    updateStorageLevel(level);
-
-    // ensure this is a depth texture
-    if (!isDepth(level))
-    {
-        return NULL;
-    }
-
-    return mTexStorage->getRenderTarget(level, layer);
+    return mTexStorage->getRenderTarget(index);
 }
 
 void TextureD3D_3D::initializeStorage(bool renderTarget)
@@ -1845,21 +1560,22 @@
     updateStorage();
 }
 
-TextureStorageInterface3D *TextureD3D_3D::createCompleteStorage(bool renderTarget) const
+TextureStorage *TextureD3D_3D::createCompleteStorage(bool renderTarget) const
 {
     GLsizei width = getBaseLevelWidth();
     GLsizei height = getBaseLevelHeight();
     GLsizei depth = getBaseLevelDepth();
+    GLenum internalFormat = getBaseLevelInternalFormat();
 
     ASSERT(width > 0 && height > 0 && depth > 0);
 
     // use existing storage level count, when previously specified by TexStorage*D
     GLint levels = (mTexStorage ? mTexStorage->getLevelCount() : creationLevels(width, height, depth));
 
-    return new TextureStorageInterface3D(mRenderer, getBaseLevelInternalFormat(), renderTarget, width, height, depth, levels);
+    return mRenderer->createTextureStorage3D(internalFormat, renderTarget, width, height, depth, levels);
 }
 
-void TextureD3D_3D::setCompleteTexStorage(TextureStorageInterface3D *newCompleteTexStorage)
+void TextureD3D_3D::setCompleteTexStorage(TextureStorage *newCompleteTexStorage)
 {
     SafeDelete(mTexStorage);
     mTexStorage = newCompleteTexStorage;
@@ -1891,9 +1607,9 @@
         ASSERT(mTexStorage);
         if (!mTexStorage->isRenderTarget())
         {
-            TextureStorageInterface3D *newRenderTargetStorage = createCompleteStorage(true);
+            TextureStorage *newRenderTargetStorage = createCompleteStorage(true);
 
-            if (!mRenderer->copyToRenderTarget(newRenderTargetStorage, mTexStorage))
+            if (!mRenderer->copyToRenderTarget3D(newRenderTargetStorage, mTexStorage))
             {
                 delete newRenderTargetStorage;
                 return gl::error(GL_OUT_OF_MEMORY, false);
@@ -1906,7 +1622,7 @@
     return (mTexStorage && mTexStorage->isRenderTarget());
 }
 
-TextureStorageInterface *TextureD3D_3D::getBaseLevelStorage()
+TextureStorage *TextureD3D_3D::getBaseLevelStorage()
 {
     return mTexStorage;
 }
@@ -2016,7 +1732,7 @@
     if (isValidLevel(level))
     {
         ImageD3D *image = mImageArray[level];
-        if (image->copyToStorage(mTexStorage, level, xoffset, yoffset, zoffset, width, height, depth))
+        if (image->copyToStorage3D(mTexStorage, level, xoffset, yoffset, zoffset, width, height, depth))
         {
             image->markClean();
         }
@@ -2025,8 +1741,7 @@
 
 
 TextureD3D_2DArray::TextureD3D_2DArray(Renderer *renderer)
-    : Texture2DArrayImpl(),
-      TextureD3D(renderer),
+    : TextureD3D(renderer),
       mTexStorage(NULL)
 {
     for (int level = 0; level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS; ++level)
@@ -2038,29 +1753,11 @@
 
 TextureD3D_2DArray::~TextureD3D_2DArray()
 {
-    SafeDelete(mTexStorage);
-
+    // Delete the Images before the TextureStorage.
+    // Images might be relying on the TextureStorage for some of their data.
+    // If TextureStorage is deleted before the Images, then their data will be wastefully copied back from the GPU before we delete the Images.
     deleteImages();
-}
-
-TextureD3D_2DArray *TextureD3D_2DArray::makeTextureD3D_2DArray(Texture2DArrayImpl *texture)
-{
-    ASSERT(HAS_DYNAMIC_TYPE(TextureD3D_2DArray*, texture));
-    return static_cast<TextureD3D_2DArray*>(texture);
-}
-
-TextureStorageInterface *TextureD3D_2DArray::getNativeTexture()
-{
-    // ensure the underlying texture is created
-    initializeStorage(false);
-
-    TextureStorageInterface *storage = getBaseLevelStorage();
-    if (storage)
-    {
-        updateStorage();
-    }
-
-    return storage;
+    SafeDelete(mTexStorage);
 }
 
 Image *TextureD3D_2DArray::getImage(int level, int layer) const
@@ -2070,6 +1767,14 @@
     return mImageArray[level][layer];
 }
 
+Image *TextureD3D_2DArray::getImage(const gl::ImageIndex &index) const
+{
+    ASSERT(index.mipIndex < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS);
+    ASSERT(index.layerIndex < mLayerCounts[index.mipIndex]);
+    ASSERT(index.type == GL_TEXTURE_2D_ARRAY);
+    return mImageArray[index.mipIndex][index.layerIndex];
+}
+
 GLsizei TextureD3D_2DArray::getLayerCount(int level) const
 {
     ASSERT(level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS);
@@ -2148,7 +1853,8 @@
         int layer = zoffset + i;
         const void *layerPixels = pixels ? (reinterpret_cast<const unsigned char*>(pixels) + (inputDepthPitch * i)) : NULL;
 
-        if (TextureD3D::subImage(xoffset, yoffset, zoffset, width, height, 1, format, type, unpack, layerPixels, mImageArray[level][layer]))
+        gl::ImageIndex index = gl::ImageIndex::Make2DArray(level, layer);
+        if (TextureD3D::subImage(xoffset, yoffset, zoffset, width, height, 1, format, type, unpack, layerPixels, index))
         {
             commitRect(level, xoffset, yoffset, layer, width, height);
         }
@@ -2206,8 +1912,8 @@
             sourceRect.y = y;
             sourceRect.height = height;
 
-            mRenderer->copyImage(source, sourceRect, gl::GetInternalFormatInfo(getInternalFormat(0)).format,
-                                 xoffset, yoffset, zoffset, mTexStorage, level);
+            mRenderer->copyImage2DArray(source, sourceRect, gl::GetInternalFormatInfo(getInternalFormat(0)).format,
+                                        xoffset, yoffset, zoffset, mTexStorage, level);
         }
     }
 }
@@ -2240,53 +1946,23 @@
     }
 
     mImmutable = true;
-    setCompleteTexStorage(new TextureStorageInterface2DArray(mRenderer, internalformat, IsRenderTargetUsage(mUsage), width, height, depth, levels));
+
+    bool renderTarget = IsRenderTargetUsage(mUsage);
+    TextureStorage *storage = mRenderer->createTextureStorage2DArray(internalformat, renderTarget, width, height, depth, levels);
+    setCompleteTexStorage(storage);
 }
 
-bool TextureD3D_2DArray::isSamplerComplete(const gl::SamplerState &samplerState) const
+void TextureD3D_2DArray::bindTexImage(egl::Surface *surface)
 {
-    GLsizei width = getBaseLevelWidth();
-    GLsizei height = getBaseLevelHeight();
-    GLsizei depth = getLayers(0);
-
-    if (width <= 0 || height <= 0 || depth <= 0)
-    {
-        return false;
-    }
-
-    // TODO(geofflang): use context's texture caps
-    if (!mRenderer->getRendererTextureCaps().get(getBaseLevelInternalFormat()).filterable)
-    {
-        if (samplerState.magFilter != GL_NEAREST ||
-            (samplerState.minFilter != GL_NEAREST && samplerState.minFilter != GL_NEAREST_MIPMAP_NEAREST))
-        {
-            return false;
-        }
-    }
-
-    if (IsMipmapFiltered(samplerState) && !isMipmapComplete())
-    {
-        return false;
-    }
-
-    return true;
+    UNREACHABLE();
 }
 
-bool TextureD3D_2DArray::isMipmapComplete() const
+void TextureD3D_2DArray::releaseTexImage()
 {
-    int levelCount = mipLevels();
-
-    for (int level = 1; level < levelCount; level++)
-    {
-        if (!isLevelComplete(level))
-        {
-            return false;
-        }
-    }
-
-    return true;
+    UNREACHABLE();
 }
 
+
 void TextureD3D_2DArray::generateMipmaps()
 {
     int baseWidth = getBaseLevelWidth();
@@ -2303,10 +1979,10 @@
 
     if (mTexStorage && mTexStorage->isRenderTarget())
     {
+        mTexStorage->generateMipmaps();
+
         for (int level = 1; level < levelCount; level++)
         {
-            mTexStorage->generateMipmap(level);
-
             for (int layer = 0; layer < mLayerCounts[level]; layer++)
             {
                 mImageArray[level][layer]->markClean();
@@ -2325,12 +2001,12 @@
     }
 }
 
-unsigned int TextureD3D_2DArray::getRenderTargetSerial(GLint level, GLint layer)
+unsigned int TextureD3D_2DArray::getRenderTargetSerial(const gl::ImageIndex &index)
 {
-    return (ensureRenderTarget() ? mTexStorage->getRenderTargetSerial(level, layer) : 0);
+    return (ensureRenderTarget() ? mTexStorage->getRenderTargetSerial(index) : 0);
 }
 
-RenderTarget *TextureD3D_2DArray::getRenderTarget(GLint level, GLint layer)
+RenderTarget *TextureD3D_2DArray::getRenderTarget(const gl::ImageIndex &index)
 {
     // ensure the underlying texture is created
     if (!ensureRenderTarget())
@@ -2338,34 +2014,8 @@
         return NULL;
     }
 
-    updateStorageLevel(level);
-
-    // ensure this is NOT a depth texture
-    if (isDepth(level))
-    {
-        return NULL;
-    }
-
-    return mTexStorage->getRenderTarget(level, layer);
-}
-
-RenderTarget *TextureD3D_2DArray::getDepthStencil(GLint level, GLint layer)
-{
-    // ensure the underlying texture is created
-    if (!ensureRenderTarget())
-    {
-        return NULL;
-    }
-
-    updateStorageLevel(level);
-
-    // ensure this is a depth texture
-    if (!isDepth(level))
-    {
-        return NULL;
-    }
-
-    return mTexStorage->getRenderTarget(level, layer);
+    updateStorageLevel(index.mipIndex);
+    return mTexStorage->getRenderTarget(index);
 }
 
 void TextureD3D_2DArray::initializeStorage(bool renderTarget)
@@ -2391,21 +2041,22 @@
     updateStorage();
 }
 
-TextureStorageInterface2DArray *TextureD3D_2DArray::createCompleteStorage(bool renderTarget) const
+TextureStorage *TextureD3D_2DArray::createCompleteStorage(bool renderTarget) const
 {
     GLsizei width = getBaseLevelWidth();
     GLsizei height = getBaseLevelHeight();
     GLsizei depth = getLayers(0);
+    GLenum internalFormat = getBaseLevelInternalFormat();
 
     ASSERT(width > 0 && height > 0 && depth > 0);
 
     // use existing storage level count, when previously specified by TexStorage*D
     GLint levels = (mTexStorage ? mTexStorage->getLevelCount() : creationLevels(width, height, 1));
 
-    return new TextureStorageInterface2DArray(mRenderer, getBaseLevelInternalFormat(), renderTarget, width, height, depth, levels);
+    return mRenderer->createTextureStorage2DArray(internalFormat, renderTarget, width, height, depth, levels);
 }
 
-void TextureD3D_2DArray::setCompleteTexStorage(TextureStorageInterface2DArray *newCompleteTexStorage)
+void TextureD3D_2DArray::setCompleteTexStorage(TextureStorage *newCompleteTexStorage)
 {
     SafeDelete(mTexStorage);
     mTexStorage = newCompleteTexStorage;
@@ -2437,9 +2088,9 @@
         ASSERT(mTexStorage);
         if (!mTexStorage->isRenderTarget())
         {
-            TextureStorageInterface2DArray *newRenderTargetStorage = createCompleteStorage(true);
+            TextureStorage *newRenderTargetStorage = createCompleteStorage(true);
 
-            if (!mRenderer->copyToRenderTarget(newRenderTargetStorage, mTexStorage))
+            if (!mRenderer->copyToRenderTarget2DArray(newRenderTargetStorage, mTexStorage))
             {
                 delete newRenderTargetStorage;
                 return gl::error(GL_OUT_OF_MEMORY, false);
@@ -2457,7 +2108,7 @@
     return (mLayerCounts[0] > 0 ? mImageArray[0][0] : NULL);
 }
 
-TextureStorageInterface *TextureD3D_2DArray::getBaseLevelStorage()
+TextureStorage *TextureD3D_2DArray::getBaseLevelStorage()
 {
     return mTexStorage;
 }
@@ -2599,7 +2250,7 @@
     if (isValidLevel(level) && layerTarget < getLayers(level))
     {
         ImageD3D *image = mImageArray[level][layerTarget];
-        if (image->copyToStorage(mTexStorage, level, xoffset, yoffset, layerTarget, width, height))
+        if (image->copyToStorage2DArray(mTexStorage, level, xoffset, yoffset, layerTarget, width, height))
         {
             image->markClean();
         }
diff --git a/src/libGLESv2/renderer/d3d/TextureD3D.h b/src/libGLESv2/renderer/d3d/TextureD3D.h
index 626316a..41c7318 100644
--- a/src/libGLESv2/renderer/d3d/TextureD3D.h
+++ b/src/libGLESv2/renderer/d3d/TextureD3D.h
@@ -24,20 +24,23 @@
 class Image;
 class ImageD3D;
 class Renderer;
-class TextureStorageInterface;
-class TextureStorageInterface2D;
-class TextureStorageInterfaceCube;
-class TextureStorageInterface3D;
-class TextureStorageInterface2DArray;
+class RenderTarget;
+class TextureStorage;
 
-bool IsMipmapFiltered(const gl::SamplerState &samplerState);
-
-class TextureD3D
+class TextureD3D : public TextureImpl
 {
   public:
     TextureD3D(Renderer *renderer);
     virtual ~TextureD3D();
 
+    static TextureD3D *makeTextureD3D(TextureImpl *texture);
+
+    virtual TextureStorage *getNativeTexture();
+
+    virtual void setUsage(GLenum usage) { mUsage = usage; }
+    bool hasDirtyImages() const { return mDirtyImages; }
+    void resetDirty() { mDirtyImages = false; }
+
     GLint getBaseLevelWidth() const;
     GLint getBaseLevelHeight() const;
     GLint getBaseLevelDepth() const;
@@ -45,16 +48,19 @@
 
     bool isImmutable() const { return mImmutable; }
 
+    virtual RenderTarget *getRenderTarget(const gl::ImageIndex &index) = 0;
+    virtual unsigned int getRenderTargetSerial(const gl::ImageIndex &index) = 0;
+
   protected:
     void setImage(const gl::PixelUnpackState &unpack, GLenum type, const void *pixels, Image *image);
     bool subImage(GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth,
-                  GLenum format, GLenum type, const gl::PixelUnpackState &unpack, const void *pixels, Image *image);
+                  GLenum format, GLenum type, const gl::PixelUnpackState &unpack, const void *pixels, const gl::ImageIndex &index);
     void setCompressedImage(GLsizei imageSize, const void *pixels, Image *image);
     bool subImageCompressed(GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth,
                             GLenum format, GLsizei imageSize, const void *pixels, Image *image);
     bool isFastUnpackable(const gl::PixelUnpackState &unpack, GLenum sizedInternalFormat);
     bool fastUnpackPixels(const gl::PixelUnpackState &unpack, const void *pixels, const gl::Box &destArea,
-                                  GLenum sizedInternalFormat, GLenum type, RenderTarget *destRenderTarget);
+                          GLenum sizedInternalFormat, GLenum type, RenderTarget *destRenderTarget);
 
     GLint creationLevels(GLsizei width, GLsizei height, GLsizei depth) const;
     int mipLevels() const;
@@ -70,27 +76,23 @@
   private:
     DISALLOW_COPY_AND_ASSIGN(TextureD3D);
 
-    virtual TextureStorageInterface *getBaseLevelStorage() = 0;
+    virtual void initializeStorage(bool renderTarget) = 0;
+
+    virtual void updateStorage() = 0;
+    virtual TextureStorage *getBaseLevelStorage() = 0;
     virtual const ImageD3D *getBaseLevelImage() const = 0;
 };
 
-class TextureD3D_2D : public Texture2DImpl, public TextureD3D
+class TextureD3D_2D : public TextureD3D
 {
   public:
     TextureD3D_2D(Renderer *renderer);
     virtual ~TextureD3D_2D();
 
-    static TextureD3D_2D *makeTextureD3D_2D(Texture2DImpl *texture);
-
-    virtual TextureStorageInterface *getNativeTexture();
-
     virtual Image *getImage(int level, int layer) const;
+    virtual Image *getImage(const gl::ImageIndex &index) const;
     virtual GLsizei getLayerCount(int level) const;
 
-    virtual bool hasDirtyImages() const { return mDirtyImages; }
-    virtual void resetDirty() { mDirtyImages = false; }
-    virtual void setUsage(GLenum usage) { mUsage = usage; }
-
     GLsizei getWidth(GLint level) const;
     GLsizei getHeight(GLint level) const;
     GLenum getInternalFormat(GLint level) const;
@@ -105,30 +107,26 @@
     virtual void copySubImage(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height, gl::Framebuffer *source);
     virtual void storage(GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth);
 
-    virtual bool isSamplerComplete(const gl::SamplerState &samplerState) const;
     virtual void bindTexImage(egl::Surface *surface);
     virtual void releaseTexImage();
 
     virtual void generateMipmaps();
 
-    virtual unsigned int getRenderTargetSerial(GLint level, GLint layer);
-
-    virtual RenderTarget *getRenderTarget(GLint level, GLint layer);
-    virtual RenderTarget *getDepthStencil(GLint level, GLint layer);
+    virtual RenderTarget *getRenderTarget(const gl::ImageIndex &index);
+    virtual unsigned int getRenderTargetSerial(const gl::ImageIndex &index);
 
   private:
     DISALLOW_COPY_AND_ASSIGN(TextureD3D_2D);
 
-    void initializeStorage(bool renderTarget);
-    TextureStorageInterface2D *createCompleteStorage(bool renderTarget) const;
-    void setCompleteTexStorage(TextureStorageInterface2D *newCompleteTexStorage);
+    virtual void initializeStorage(bool renderTarget);
+    TextureStorage *createCompleteStorage(bool renderTarget) const;
+    void setCompleteTexStorage(TextureStorage *newCompleteTexStorage);
 
-    void updateStorage();
+    virtual void updateStorage();
     bool ensureRenderTarget();
-    virtual TextureStorageInterface *getBaseLevelStorage();
+    virtual TextureStorage *getBaseLevelStorage();
     virtual const ImageD3D *getBaseLevelImage() const;
 
-    bool isMipmapComplete() const;
     bool isValidLevel(int level) const;
     bool isLevelComplete(int level) const;
 
@@ -137,21 +135,18 @@
     void redefineImage(GLint level, GLenum internalformat, GLsizei width, GLsizei height);
     void commitRect(GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height);
 
-    TextureStorageInterface2D *mTexStorage;
+    TextureStorage *mTexStorage;
     ImageD3D *mImageArray[gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS];
 };
 
-class TextureD3D_Cube : public TextureCubeImpl, public TextureD3D
+class TextureD3D_Cube : public TextureD3D
 {
   public:
     TextureD3D_Cube(Renderer *renderer);
     virtual ~TextureD3D_Cube();
 
-    static TextureD3D_Cube *makeTextureD3D_Cube(TextureCubeImpl *texture);
-
-    virtual TextureStorageInterface *getNativeTexture();
-
     virtual Image *getImage(int level, int layer) const;
+    virtual Image *getImage(const gl::ImageIndex &index) const;
     virtual GLsizei getLayerCount(int level) const;
 
     virtual bool hasDirtyImages() const { return mDirtyImages; }
@@ -169,31 +164,29 @@
     virtual void copySubImage(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height, gl::Framebuffer *source);
     virtual void storage(GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth);
 
-    virtual bool isSamplerComplete(const gl::SamplerState &samplerState) const;
-    virtual bool isCubeComplete() const;
+    virtual void bindTexImage(egl::Surface *surface);
+    virtual void releaseTexImage();
 
     virtual void generateMipmaps();
 
-    virtual unsigned int getRenderTargetSerial(GLint level, GLint layer);
-
-    virtual RenderTarget *getRenderTarget(GLint level, GLint layer);
-    virtual RenderTarget *getDepthStencil(GLint level, GLint layer);
+    virtual RenderTarget *getRenderTarget(const gl::ImageIndex &index);
+    virtual unsigned int getRenderTargetSerial(const gl::ImageIndex &index);
 
   private:
     DISALLOW_COPY_AND_ASSIGN(TextureD3D_Cube);
 
-    void initializeStorage(bool renderTarget);
-    TextureStorageInterfaceCube *createCompleteStorage(bool renderTarget) const;
-    void setCompleteTexStorage(TextureStorageInterfaceCube *newCompleteTexStorage);
+    virtual void initializeStorage(bool renderTarget);
+    TextureStorage *createCompleteStorage(bool renderTarget) const;
+    void setCompleteTexStorage(TextureStorage *newCompleteTexStorage);
 
-    void updateStorage();
+    virtual void updateStorage();
     bool ensureRenderTarget();
-    virtual TextureStorageInterface *getBaseLevelStorage();
+    virtual TextureStorage *getBaseLevelStorage();
     virtual const ImageD3D *getBaseLevelImage() const;
 
-    bool isMipmapCubeComplete() const;
     bool isValidFaceLevel(int faceIndex, int level) const;
     bool isFaceLevelComplete(int faceIndex, int level) const;
+    bool isCubeComplete() const;
     void updateStorageFaceLevel(int faceIndex, int level);
 
     void redefineImage(int faceIndex, GLint level, GLenum internalformat, GLsizei width, GLsizei height);
@@ -201,26 +194,19 @@
 
     ImageD3D *mImageArray[6][gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS];
 
-    TextureStorageInterfaceCube *mTexStorage;
+    TextureStorage *mTexStorage;
 };
 
-class TextureD3D_3D : public Texture3DImpl, public TextureD3D
+class TextureD3D_3D : public TextureD3D
 {
   public:
     TextureD3D_3D(Renderer *renderer);
     virtual ~TextureD3D_3D();
 
-    static TextureD3D_3D *makeTextureD3D_3D(Texture3DImpl *texture);
-
-    virtual TextureStorageInterface *getNativeTexture();
-
     virtual Image *getImage(int level, int layer) const;
+    virtual Image *getImage(const gl::ImageIndex &index) const;
     virtual GLsizei getLayerCount(int level) const;
 
-    virtual bool hasDirtyImages() const { return mDirtyImages; }
-    virtual void resetDirty() { mDirtyImages = false; }
-    virtual void setUsage(GLenum usage) { mUsage = usage; }
-
     GLsizei getWidth(GLint level) const;
     GLsizei getHeight(GLint level) const;
     GLsizei getDepth(GLint level) const;
@@ -235,29 +221,26 @@
     virtual void copySubImage(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height, gl::Framebuffer *source);
     virtual void storage(GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth);
 
-    virtual bool isSamplerComplete(const gl::SamplerState &samplerState) const;
+    virtual void bindTexImage(egl::Surface *surface);
+    virtual void releaseTexImage();
 
     virtual void generateMipmaps();
 
-    virtual unsigned int getRenderTargetSerial(GLint level, GLint layer);
-
-    virtual RenderTarget *getRenderTarget(GLint level);
-    virtual RenderTarget *getRenderTarget(GLint level, GLint layer);
-    virtual RenderTarget *getDepthStencil(GLint level, GLint layer);
+    virtual RenderTarget *getRenderTarget(const gl::ImageIndex &index);
+    virtual unsigned int getRenderTargetSerial(const gl::ImageIndex &index);
 
   private:
     DISALLOW_COPY_AND_ASSIGN(TextureD3D_3D);
 
     virtual void initializeStorage(bool renderTarget);
-    TextureStorageInterface3D *createCompleteStorage(bool renderTarget) const;
-    void setCompleteTexStorage(TextureStorageInterface3D *newCompleteTexStorage);
+    TextureStorage *createCompleteStorage(bool renderTarget) const;
+    void setCompleteTexStorage(TextureStorage *newCompleteTexStorage);
 
-    void updateStorage();
+    virtual void updateStorage();
     bool ensureRenderTarget();
-    virtual TextureStorageInterface *getBaseLevelStorage();
+    virtual TextureStorage *getBaseLevelStorage();
     virtual const ImageD3D *getBaseLevelImage() const;
 
-    bool isMipmapComplete() const;
     bool isValidLevel(int level) const;
     bool isLevelComplete(int level) const;
     void updateStorageLevel(int level);
@@ -267,26 +250,19 @@
 
     ImageD3D *mImageArray[gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS];
 
-    TextureStorageInterface3D *mTexStorage;
+    TextureStorage *mTexStorage;
 };
 
-class TextureD3D_2DArray : public Texture2DArrayImpl, public TextureD3D
+class TextureD3D_2DArray : public TextureD3D
 {
   public:
     TextureD3D_2DArray(Renderer *renderer);
     virtual ~TextureD3D_2DArray();
 
-    static TextureD3D_2DArray *makeTextureD3D_2DArray(Texture2DArrayImpl *texture);
-
-    virtual TextureStorageInterface *getNativeTexture();
-
     virtual Image *getImage(int level, int layer) const;
+    virtual Image *getImage(const gl::ImageIndex &index) const;
     virtual GLsizei getLayerCount(int level) const;
 
-    virtual bool hasDirtyImages() const { return mDirtyImages; }
-    virtual void resetDirty() { mDirtyImages = false; }
-    virtual void setUsage(GLenum usage) { mUsage = usage; }
-
     GLsizei getWidth(GLint level) const;
     GLsizei getHeight(GLint level) const;
     GLsizei getLayers(GLint level) const;
@@ -301,28 +277,26 @@
     virtual void copySubImage(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height, gl::Framebuffer *source);
     virtual void storage(GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth);
 
-    virtual bool isSamplerComplete(const gl::SamplerState &samplerState) const;
+    virtual void bindTexImage(egl::Surface *surface);
+    virtual void releaseTexImage();
 
     virtual void generateMipmaps();
 
-    virtual unsigned int getRenderTargetSerial(GLint level, GLint layer);
-
-    virtual RenderTarget *getRenderTarget(GLint level, GLint layer);
-    virtual RenderTarget *getDepthStencil(GLint level, GLint layer);
+    virtual RenderTarget *getRenderTarget(const gl::ImageIndex &index);
+    virtual unsigned int getRenderTargetSerial(const gl::ImageIndex &index);
 
   private:
     DISALLOW_COPY_AND_ASSIGN(TextureD3D_2DArray);
 
     virtual void initializeStorage(bool renderTarget);
-    TextureStorageInterface2DArray *createCompleteStorage(bool renderTarget) const;
-    void setCompleteTexStorage(TextureStorageInterface2DArray *newCompleteTexStorage);
+    TextureStorage *createCompleteStorage(bool renderTarget) const;
+    void setCompleteTexStorage(TextureStorage *newCompleteTexStorage);
 
-    void updateStorage();
+    virtual void updateStorage();
     bool ensureRenderTarget();
-    virtual TextureStorageInterface *getBaseLevelStorage();
+    virtual TextureStorage *getBaseLevelStorage();
     virtual const ImageD3D *getBaseLevelImage() const;
 
-    bool isMipmapComplete() const;
     bool isValidLevel(int level) const;
     bool isLevelComplete(int level) const;
     void updateStorageLevel(int level);
@@ -338,7 +312,7 @@
     GLsizei mLayerCounts[gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS];
     ImageD3D **mImageArray[gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS];
 
-    TextureStorageInterface2DArray *mTexStorage;
+    TextureStorage *mTexStorage;
 };
 
 }
diff --git a/src/libGLESv2/renderer/d3d/TextureStorage.cpp b/src/libGLESv2/renderer/d3d/TextureStorage.cpp
index be82d33..dedd266 100644
--- a/src/libGLESv2/renderer/d3d/TextureStorage.cpp
+++ b/src/libGLESv2/renderer/d3d/TextureStorage.cpp
@@ -1,13 +1,10 @@
-#include "precompiled.h"
 //
 // 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.
 //
 
-// TextureStorage.cpp: Implements the abstract rx::TextureStorageInterface class and its concrete derived
-// classes TextureStorageInterface2D and TextureStorageInterfaceCube, which act as the interface to the
-// GPU-side texture.
+// TextureStorage.cpp: Shared members of abstract rx::TextureStorage class.
 
 #include "libGLESv2/renderer/d3d/TextureStorage.h"
 #include "libGLESv2/renderer/d3d/TextureD3D.h"
@@ -20,162 +17,35 @@
 
 namespace rx
 {
-unsigned int TextureStorageInterface::mCurrentTextureSerial = 1;
 
-TextureStorageInterface::TextureStorageInterface()
+unsigned int TextureStorage::mCurrentTextureSerial = 1;
+
+TextureStorage::TextureStorage()
     : mTextureSerial(issueTextureSerial()),
-      mInstance(NULL)
+      mFirstRenderTargetSerial(0),
+      mRenderTargetSerialsLayerStride(0)
+{}
+
+void TextureStorage::initializeSerials(unsigned int rtSerialsToReserve, unsigned int rtSerialsLayerStride)
 {
+    mFirstRenderTargetSerial = gl::RenderbufferStorage::issueSerials(rtSerialsToReserve);
+    mRenderTargetSerialsLayerStride = rtSerialsLayerStride;
 }
 
-TextureStorageInterface::~TextureStorageInterface()
+unsigned int TextureStorage::getRenderTargetSerial(const gl::ImageIndex &index) const
 {
-    delete mInstance;
+    unsigned int layerOffset = (index.hasLayer() ? (static_cast<unsigned int>(index.layerIndex) * mRenderTargetSerialsLayerStride) : 0);
+    return mFirstRenderTargetSerial + static_cast<unsigned int>(index.mipIndex) + layerOffset;
 }
 
-bool TextureStorageInterface::isRenderTarget() const
-{
-    return mInstance->isRenderTarget();
-}
-
-bool TextureStorageInterface::isManaged() const
-{
-    return mInstance->isManaged();
-}
-
-unsigned int TextureStorageInterface::getTextureSerial() const
+unsigned int TextureStorage::getTextureSerial() const
 {
     return mTextureSerial;
 }
 
-unsigned int TextureStorageInterface::issueTextureSerial()
+unsigned int TextureStorage::issueTextureSerial()
 {
     return mCurrentTextureSerial++;
 }
 
-int TextureStorageInterface::getTopLevel() const
-{
-    return mInstance->getTopLevel();
-}
-
-int TextureStorageInterface::getLevelCount() const
-{
-    return mInstance->getLevelCount();
-}
-
-TextureStorageInterface2D::TextureStorageInterface2D(Renderer *renderer, SwapChain *swapchain)
-{
-    mFirstRenderTargetSerial = gl::RenderbufferStorage::issueSerials(1);
-
-    mInstance = renderer->createTextureStorage2D(swapchain);
-}
-
-TextureStorageInterface2D::TextureStorageInterface2D(Renderer *renderer, GLenum internalformat, bool renderTarget, GLsizei width, GLsizei height, int levels)
-{
-    mInstance = renderer->createTextureStorage2D(internalformat, renderTarget, width, height, levels);
-    mFirstRenderTargetSerial = gl::RenderbufferStorage::issueSerials(static_cast<GLuint>(mInstance->getLevelCount()));
-}
-
-TextureStorageInterface2D::~TextureStorageInterface2D()
-{
-}
-
-RenderTarget *TextureStorageInterface2D::getRenderTarget(GLint level) const
-{
-    return mInstance->getRenderTarget(level);
-}
-
-void TextureStorageInterface2D::generateMipmap(int level)
-{
-    mInstance->generateMipmap(level);
-}
-
-unsigned int TextureStorageInterface2D::getRenderTargetSerial(GLint level) const
-{
-    return mFirstRenderTargetSerial + level;
-}
-
-TextureStorageInterfaceCube::TextureStorageInterfaceCube(Renderer *renderer, GLenum internalformat, bool renderTarget, int size, int levels)
-{
-    mInstance = renderer->createTextureStorageCube(internalformat, renderTarget, size, levels);
-    mFirstRenderTargetSerial = gl::RenderbufferStorage::issueSerials(static_cast<GLuint>(mInstance->getLevelCount() * 6));
-}
-
-TextureStorageInterfaceCube::~TextureStorageInterfaceCube()
-{
-}
-
-RenderTarget *TextureStorageInterfaceCube::getRenderTarget(GLenum faceTarget, GLint level) const
-{
-    return mInstance->getRenderTargetFace(faceTarget, level);
-}
-
-void TextureStorageInterfaceCube::generateMipmap(int faceIndex, int level)
-{
-    mInstance->generateMipmap(faceIndex, level);
-}
-
-unsigned int TextureStorageInterfaceCube::getRenderTargetSerial(GLenum target, GLint level) const
-{
-    return mFirstRenderTargetSerial + (level * 6) + gl::TextureCubeMap::targetToLayerIndex(target);
-}
-
-TextureStorageInterface3D::TextureStorageInterface3D(Renderer *renderer, GLenum internalformat, bool renderTarget,
-                                                     GLsizei width, GLsizei height, GLsizei depth, int levels)
-{
-
-    mInstance = renderer->createTextureStorage3D(internalformat, renderTarget, width, height, depth, levels);
-    mFirstRenderTargetSerial = gl::RenderbufferStorage::issueSerials(static_cast<GLuint>(mInstance->getLevelCount() * depth));
-}
-
-TextureStorageInterface3D::~TextureStorageInterface3D()
-{
-}
-
-void TextureStorageInterface3D::generateMipmap(int level)
-{
-    mInstance->generateMipmap(level);
-}
-
-RenderTarget *TextureStorageInterface3D::getRenderTarget(GLint level) const
-{
-    return mInstance->getRenderTarget(level);
-}
-
-RenderTarget *TextureStorageInterface3D::getRenderTarget(GLint level, GLint layer) const
-{
-    return mInstance->getRenderTargetLayer(level, layer);
-}
-
-unsigned int TextureStorageInterface3D::getRenderTargetSerial(GLint level, GLint layer) const
-{
-    return mFirstRenderTargetSerial + static_cast<unsigned int>((layer * mInstance->getLevelCount()) + level);
-}
-
-TextureStorageInterface2DArray::TextureStorageInterface2DArray(Renderer *renderer, GLenum internalformat, bool renderTarget,
-                                                               GLsizei width, GLsizei height, GLsizei depth, int levels)
-{
-    mInstance = renderer->createTextureStorage2DArray(internalformat, renderTarget, width, height, depth, levels);
-    mFirstRenderTargetSerial = gl::RenderbufferStorage::issueSerials(static_cast<GLuint>(mInstance->getLevelCount() * depth));
-}
-
-TextureStorageInterface2DArray::~TextureStorageInterface2DArray()
-{
-}
-
-void TextureStorageInterface2DArray::generateMipmap(int level)
-{
-    mInstance->generateMipmap(level);
-}
-
-RenderTarget *TextureStorageInterface2DArray::getRenderTarget(GLint level, GLint layer) const
-{
-    return mInstance->getRenderTargetLayer(level, layer);
-}
-
-unsigned int TextureStorageInterface2DArray::getRenderTargetSerial(GLint level, GLint layer) const
-{
-    return mFirstRenderTargetSerial + static_cast<unsigned int>((layer * mInstance->getLevelCount()) + level);
-}
-
 }
diff --git a/src/libGLESv2/renderer/d3d/TextureStorage.h b/src/libGLESv2/renderer/d3d/TextureStorage.h
index 0a212e1..9cc2c29 100644
--- a/src/libGLESv2/renderer/d3d/TextureStorage.h
+++ b/src/libGLESv2/renderer/d3d/TextureStorage.h
@@ -4,15 +4,20 @@
 // found in the LICENSE file.
 //
 
-// TextureStorage.h: Defines the abstract rx::TextureStorageInterface class and its concrete derived
-// classes TextureStorageInterface2D and TextureStorageInterfaceCube, which act as the interface to the
-// GPU-side texture.
+// TextureStorage.h: Defines the abstract rx::TextureStorage class.
 
 #ifndef LIBGLESV2_RENDERER_TEXTURESTORAGE_H_
 #define LIBGLESV2_RENDERER_TEXTURESTORAGE_H_
 
 #include "common/debug.h"
 
+#include <GLES2/gl2.h>
+
+namespace gl
+{
+struct ImageIndex;
+}
+
 namespace rx
 {
 class Renderer;
@@ -22,7 +27,7 @@
 class TextureStorage
 {
   public:
-    TextureStorage() {};
+    TextureStorage();
     virtual ~TextureStorage() {};
 
     virtual int getTopLevel() const = 0;
@@ -30,114 +35,25 @@
     virtual bool isManaged() const = 0;
     virtual int getLevelCount() const = 0;
 
-    virtual RenderTarget *getRenderTarget(int level) = 0;
-    virtual RenderTarget *getRenderTargetFace(GLenum faceTarget, int level) = 0;
-    virtual RenderTarget *getRenderTargetLayer(int mipLevel, int layer) = 0;
-    virtual void generateMipmap(int level) = 0;
-    virtual void generateMipmap(int face, int level) = 0;
+    virtual RenderTarget *getRenderTarget(const gl::ImageIndex &index) = 0;
+    virtual void generateMipmaps() = 0;
+
+    unsigned int getRenderTargetSerial(const gl::ImageIndex &index) const;
+    unsigned int getTextureSerial() const;
+
+  protected:
+    void initializeSerials(unsigned int rtSerialsToReserve, unsigned int rtSerialsLayerStride);
 
   private:
     DISALLOW_COPY_AND_ASSIGN(TextureStorage);
 
-};
-
-class TextureStorageInterface
-{
-  public:
-    TextureStorageInterface();
-    virtual ~TextureStorageInterface();
-
-    TextureStorage *getStorageInstance() { return mInstance; }
-
-    unsigned int getTextureSerial() const;
-
-    virtual int getTopLevel() const;
-    virtual bool isRenderTarget() const;
-    virtual bool isManaged() const;
-    virtual int getLevelCount() const;
-
-  protected:
-    TextureStorage *mInstance;
-
-  private:
-    DISALLOW_COPY_AND_ASSIGN(TextureStorageInterface);
-
     const unsigned int mTextureSerial;
     static unsigned int issueTextureSerial();
 
     static unsigned int mCurrentTextureSerial;
-};
-
-class TextureStorageInterface2D : public TextureStorageInterface
-{
-  public:
-    TextureStorageInterface2D(Renderer *renderer, SwapChain *swapchain);
-    TextureStorageInterface2D(Renderer *renderer, GLenum internalformat, bool renderTarget, GLsizei width, GLsizei height, int levels);
-    virtual ~TextureStorageInterface2D();
-
-    void generateMipmap(int level);
-    RenderTarget *getRenderTarget(GLint level) const;
-
-    unsigned int getRenderTargetSerial(GLint level) const;
-
-  private:
-    DISALLOW_COPY_AND_ASSIGN(TextureStorageInterface2D);
 
     unsigned int mFirstRenderTargetSerial;
-};
-
-class TextureStorageInterfaceCube : public TextureStorageInterface
-{
-  public:
-    TextureStorageInterfaceCube(Renderer *renderer, GLenum internalformat, bool renderTarget, int size, int levels);
-    virtual ~TextureStorageInterfaceCube();
-
-    void generateMipmap(int faceIndex, int level);
-    RenderTarget *getRenderTarget(GLenum faceTarget, GLint level) const;
-
-    virtual unsigned int getRenderTargetSerial(GLenum target, GLint level) const;
-
-  private:
-    DISALLOW_COPY_AND_ASSIGN(TextureStorageInterfaceCube);
-
-    unsigned int mFirstRenderTargetSerial;
-};
-
-class TextureStorageInterface3D : public TextureStorageInterface
-{
-  public:
-    TextureStorageInterface3D(Renderer *renderer, GLenum internalformat, bool renderTarget,
-                              GLsizei width, GLsizei height, GLsizei depth, int levels);
-    virtual ~TextureStorageInterface3D();
-
-    void generateMipmap(int level);
-    RenderTarget *getRenderTarget(GLint level) const;
-    RenderTarget *getRenderTarget(GLint level, GLint layer) const;
-
-    virtual unsigned int getRenderTargetSerial(GLint level, GLint layer) const;
-
-  private:
-    DISALLOW_COPY_AND_ASSIGN(TextureStorageInterface3D);
-
-    unsigned int mFirstRenderTargetSerial;
-};
-
-class TextureStorageInterface2DArray : public TextureStorageInterface
-{
-  public:
-    TextureStorageInterface2DArray(Renderer *renderer, GLenum internalformat, bool renderTarget,
-                                   GLsizei width, GLsizei height, GLsizei depth, int levels);
-    virtual ~TextureStorageInterface2DArray();
-
-    void generateMipmap(int level);
-    RenderTarget *getRenderTarget(GLint level, GLint layer) const;
-
-    virtual unsigned int getRenderTargetSerial(GLint level, GLint layer) const;
-
-  private:
-    DISALLOW_COPY_AND_ASSIGN(TextureStorageInterface2DArray);
-
-    unsigned int mFirstRenderTargetSerial;
+    unsigned int mRenderTargetSerialsLayerStride;
 };
 
 }
diff --git a/src/libGLESv2/renderer/d3d/TransformFeedbackD3D.cpp b/src/libGLESv2/renderer/d3d/TransformFeedbackD3D.cpp
new file mode 100644
index 0000000..1159600
--- /dev/null
+++ b/src/libGLESv2/renderer/d3d/TransformFeedbackD3D.cpp
@@ -0,0 +1,38 @@
+//
+// Copyright 2014 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+
+// TransformFeedbackD3D.cpp is a no-op implementation for both the D3D9 and D3D11 renderers.
+
+#include "libGLESv2/renderer/d3d/TransformFeedbackD3D.h"
+
+namespace rx
+{
+
+TransformFeedbackD3D::TransformFeedbackD3D()
+{
+}
+
+TransformFeedbackD3D::~TransformFeedbackD3D()
+{
+}
+
+void TransformFeedbackD3D::begin(GLenum primitiveMode)
+{
+}
+
+void TransformFeedbackD3D::end()
+{
+}
+
+void TransformFeedbackD3D::pause()
+{
+}
+
+void TransformFeedbackD3D::resume()
+{
+}
+
+}
diff --git a/src/libGLESv2/renderer/d3d/TransformFeedbackD3D.h b/src/libGLESv2/renderer/d3d/TransformFeedbackD3D.h
new file mode 100644
index 0000000..7c367ab
--- /dev/null
+++ b/src/libGLESv2/renderer/d3d/TransformFeedbackD3D.h
@@ -0,0 +1,32 @@
+//
+// Copyright 2014 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+
+// TransformFeedbackD3D.h: Implements the abstract rx::TransformFeedbackImpl class.
+
+#ifndef LIBGLESV2_RENDERER_D3D_TRANSFORMFEEDBACKD3D_H_
+#define LIBGLESV2_RENDERER_D3D_TRANSFORMFEEDBACKD3D_H_
+
+#include "libGLESv2/renderer/TransformFeedbackImpl.h"
+#include "libGLESv2/angletypes.h"
+
+namespace rx
+{
+
+class TransformFeedbackD3D : public TransformFeedbackImpl
+{
+  public:
+    TransformFeedbackD3D();
+    virtual ~TransformFeedbackD3D();
+
+    virtual void begin(GLenum primitiveMode);
+    virtual void end();
+    virtual void pause();
+    virtual void resume();
+};
+
+}
+
+#endif // LIBGLESV2_RENDERER_D3D_TRANSFORMFEEDBACKD3D_H_
diff --git a/src/libGLESv2/renderer/d3d/VertexBuffer.cpp b/src/libGLESv2/renderer/d3d/VertexBuffer.cpp
index 901ca19..4f85eb9 100644
--- a/src/libGLESv2/renderer/d3d/VertexBuffer.cpp
+++ b/src/libGLESv2/renderer/d3d/VertexBuffer.cpp
@@ -1,4 +1,3 @@
-#include "precompiled.h"
 //
 // 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
@@ -9,9 +8,10 @@
 // class with derivations, classes that perform graphics API agnostic vertex buffer operations.
 
 #include "libGLESv2/renderer/d3d/VertexBuffer.h"
+#include "libGLESv2/renderer/d3d/BufferD3D.h"
 #include "libGLESv2/renderer/Renderer.h"
 #include "libGLESv2/VertexAttribute.h"
-#include "libGLESv2/renderer/d3d/BufferD3D.h"
+
 #include "common/mathutil.h"
 
 namespace rx
@@ -62,7 +62,7 @@
     return mVertexBuffer->getBufferSize();
 }
 
-bool VertexBufferInterface::setBufferSize(unsigned int size)
+gl::Error VertexBufferInterface::setBufferSize(unsigned int size)
 {
     if (mVertexBuffer->getBufferSize() == 0)
     {
@@ -84,34 +84,39 @@
     mWritePosition = writePosition;
 }
 
-bool VertexBufferInterface::discard()
+gl::Error VertexBufferInterface::discard()
 {
     return mVertexBuffer->discard();
 }
 
-bool VertexBufferInterface::storeVertexAttributes(const gl::VertexAttribute &attrib, const gl::VertexAttribCurrentValueData &currentValue,
-                                                  GLint start, GLsizei count, GLsizei instances, unsigned int *outStreamOffset)
+gl::Error VertexBufferInterface::storeVertexAttributes(const gl::VertexAttribute &attrib, const gl::VertexAttribCurrentValueData &currentValue,
+                                                       GLint start, GLsizei count, GLsizei instances, unsigned int *outStreamOffset)
 {
+    gl::Error error(GL_NO_ERROR);
+
     unsigned int spaceRequired;
-    if (!mVertexBuffer->getSpaceRequired(attrib, count, instances, &spaceRequired))
+    error = mVertexBuffer->getSpaceRequired(attrib, count, instances, &spaceRequired);
+    if (error.isError())
     {
-        return false;
+        return error;
     }
 
     if (mWritePosition + spaceRequired < mWritePosition)
     {
-        return false;
+        return gl::Error(GL_OUT_OF_MEMORY, "Internal error, new vertex buffer write position would overflow.");
     }
 
-    if (!reserveSpace(mReservedSpace))
+    error = reserveSpace(mReservedSpace);
+    if (error.isError())
     {
-        return false;
+        return error;
     }
     mReservedSpace = 0;
 
-    if (!mVertexBuffer->storeVertexAttributes(attrib, currentValue, start, count, instances, mWritePosition))
+    error = mVertexBuffer->storeVertexAttributes(attrib, currentValue, start, count, instances, mWritePosition);
+    if (error.isError())
     {
-        return false;
+        return error;
     }
 
     if (outStreamOffset)
@@ -124,21 +129,25 @@
     // Align to 16-byte boundary
     mWritePosition = rx::roundUp(mWritePosition, 16u);
 
-    return true;
+    return gl::Error(GL_NO_ERROR);
 }
 
-bool VertexBufferInterface::reserveVertexSpace(const gl::VertexAttribute &attrib, GLsizei count, GLsizei instances)
+gl::Error VertexBufferInterface::reserveVertexSpace(const gl::VertexAttribute &attrib, GLsizei count, GLsizei instances)
 {
+    gl::Error error(GL_NO_ERROR);
+
     unsigned int requiredSpace;
-    if (!mVertexBuffer->getSpaceRequired(attrib, count, instances, &requiredSpace))
+    error = mVertexBuffer->getSpaceRequired(attrib, count, instances, &requiredSpace);
+    if (error.isError())
     {
-        return false;
+        return error;
     }
 
     // Protect against integer overflow
     if (mReservedSpace + requiredSpace < mReservedSpace)
     {
-         return false;
+        return gl::Error(GL_OUT_OF_MEMORY, "Unable to reserve %u extra bytes in internal vertex buffer, "
+                         "it would result in an overflow.", requiredSpace);
     }
 
     mReservedSpace += requiredSpace;
@@ -146,7 +155,7 @@
     // Align to 16-byte boundary
     mReservedSpace = rx::roundUp(mReservedSpace, 16u);
 
-    return true;
+    return gl::Error(GL_NO_ERROR);
 }
 
 VertexBuffer* VertexBufferInterface::getVertexBuffer() const
@@ -197,25 +206,29 @@
 {
 }
 
-bool StreamingVertexBufferInterface::reserveSpace(unsigned int size)
+gl::Error StreamingVertexBufferInterface::reserveSpace(unsigned int size)
 {
-    bool result = true;
     unsigned int curBufferSize = getBufferSize();
     if (size > curBufferSize)
     {
-        result = setBufferSize(std::max(size, 3 * curBufferSize / 2));
+        gl::Error error = setBufferSize(std::max(size, 3 * curBufferSize / 2));
+        if (error.isError())
+        {
+            return error;
+        }
         setWritePosition(0);
     }
     else if (getWritePosition() + size > curBufferSize)
     {
-        if (!discard())
+        gl::Error error = discard();
+        if (error.isError())
         {
-            return false;
+            return error;
         }
         setWritePosition(0);
     }
 
-    return result;
+    return gl::Error(GL_NO_ERROR);
 }
 
 StaticVertexBufferInterface::StaticVertexBufferInterface(rx::Renderer *renderer) : VertexBufferInterface(renderer, false)
@@ -251,46 +264,44 @@
     return false;
 }
 
-bool StaticVertexBufferInterface::reserveSpace(unsigned int size)
+gl::Error StaticVertexBufferInterface::reserveSpace(unsigned int size)
 {
     unsigned int curSize = getBufferSize();
     if (curSize == 0)
     {
-        setBufferSize(size);
-        return true;
+        return setBufferSize(size);
     }
     else if (curSize >= size)
     {
-        return true;
+        return gl::Error(GL_NO_ERROR);
     }
     else
     {
-        UNREACHABLE();   // Static vertex buffers can't be resized
-        return false;
+        UNREACHABLE();
+        return gl::Error(GL_INVALID_OPERATION, "Internal error, Static vertex buffers can't be resized.");
     }
 }
 
-bool StaticVertexBufferInterface::storeVertexAttributes(const gl::VertexAttribute &attrib, const gl::VertexAttribCurrentValueData &currentValue,
-                                                       GLint start, GLsizei count, GLsizei instances, unsigned int *outStreamOffset)
+gl::Error StaticVertexBufferInterface::storeVertexAttributes(const gl::VertexAttribute &attrib, const gl::VertexAttribCurrentValueData &currentValue,
+                                                             GLint start, GLsizei count, GLsizei instances, unsigned int *outStreamOffset)
 {
     unsigned int streamOffset;
-    if (VertexBufferInterface::storeVertexAttributes(attrib, currentValue, start, count, instances, &streamOffset))
+    gl::Error error = VertexBufferInterface::storeVertexAttributes(attrib, currentValue, start, count, instances, &streamOffset);
+    if (error.isError())
     {
-        size_t attributeOffset = static_cast<size_t>(attrib.offset) % ComputeVertexAttributeStride(attrib);
-        VertexElement element = { attrib.type, attrib.size, ComputeVertexAttributeStride(attrib), attrib.normalized, attrib.pureInteger, attributeOffset, streamOffset };
-        mCache.push_back(element);
-
-        if (outStreamOffset)
-        {
-            *outStreamOffset = streamOffset;
-        }
-
-        return true;
+        return error;
     }
-    else
+
+    size_t attributeOffset = static_cast<size_t>(attrib.offset) % ComputeVertexAttributeStride(attrib);
+    VertexElement element = { attrib.type, attrib.size, ComputeVertexAttributeStride(attrib), attrib.normalized, attrib.pureInteger, attributeOffset, streamOffset };
+    mCache.push_back(element);
+
+    if (outStreamOffset)
     {
-        return false;
+        *outStreamOffset = streamOffset;
     }
+
+    return gl::Error(GL_NO_ERROR);
 }
 
 }
diff --git a/src/libGLESv2/renderer/d3d/VertexBuffer.h b/src/libGLESv2/renderer/d3d/VertexBuffer.h
index c5022d8..fa747d9 100644
--- a/src/libGLESv2/renderer/d3d/VertexBuffer.h
+++ b/src/libGLESv2/renderer/d3d/VertexBuffer.h
@@ -11,6 +11,12 @@
 #define LIBGLESV2_RENDERER_VERTEXBUFFER_H_
 
 #include "common/angleutils.h"
+#include "libGLESv2/Error.h"
+
+#include <GLES2/gl2.h>
+
+#include <cstddef>
+#include <vector>
 
 namespace gl
 {
@@ -28,16 +34,16 @@
     VertexBuffer();
     virtual ~VertexBuffer();
 
-    virtual bool initialize(unsigned int size, bool dynamicUsage) = 0;
+    virtual gl::Error initialize(unsigned int size, bool dynamicUsage) = 0;
 
-    virtual bool storeVertexAttributes(const gl::VertexAttribute &attrib, const gl::VertexAttribCurrentValueData &currentValue,
-                                       GLint start, GLsizei count, GLsizei instances, unsigned int offset) = 0;
-    virtual bool getSpaceRequired(const gl::VertexAttribute &attrib, GLsizei count, GLsizei instances,
-                                  unsigned int *outSpaceRequired) const = 0;
+    virtual gl::Error storeVertexAttributes(const gl::VertexAttribute &attrib, const gl::VertexAttribCurrentValueData &currentValue,
+                                            GLint start, GLsizei count, GLsizei instances, unsigned int offset) = 0;
+    virtual gl::Error getSpaceRequired(const gl::VertexAttribute &attrib, GLsizei count, GLsizei instances,
+                                       unsigned int *outSpaceRequired) const = 0;
 
     virtual unsigned int getBufferSize() const = 0;
-    virtual bool setBufferSize(unsigned int size) = 0;
-    virtual bool discard() = 0;
+    virtual gl::Error setBufferSize(unsigned int size) = 0;
+    virtual gl::Error discard() = 0;
 
     unsigned int getSerial() const;
 
@@ -57,14 +63,14 @@
     VertexBufferInterface(rx::Renderer *renderer, bool dynamic);
     virtual ~VertexBufferInterface();
 
-    bool reserveVertexSpace(const gl::VertexAttribute &attribute, GLsizei count, GLsizei instances);
+    gl::Error reserveVertexSpace(const gl::VertexAttribute &attribute, GLsizei count, GLsizei instances);
 
     unsigned int getBufferSize() const;
 
     unsigned int getSerial() const;
 
-    virtual bool storeVertexAttributes(const gl::VertexAttribute &attrib, const gl::VertexAttribCurrentValueData &currentValue,
-                                      GLint start, GLsizei count, GLsizei instances, unsigned int *outStreamOffset);
+    virtual gl::Error storeVertexAttributes(const gl::VertexAttribute &attrib, const gl::VertexAttribCurrentValueData &currentValue,
+                                            GLint start, GLsizei count, GLsizei instances, unsigned int *outStreamOffset);
 
     bool directStoragePossible(const gl::VertexAttribute &attrib,
                                const gl::VertexAttribCurrentValueData &currentValue) const;
@@ -72,14 +78,14 @@
     VertexBuffer* getVertexBuffer() const;
 
   protected:
-    virtual bool reserveSpace(unsigned int size) = 0;
+    virtual gl::Error reserveSpace(unsigned int size) = 0;
 
     unsigned int getWritePosition() const;
     void setWritePosition(unsigned int writePosition);
 
-    bool discard();
+    gl::Error discard();
 
-    bool setBufferSize(unsigned int size);
+    gl::Error setBufferSize(unsigned int size);
 
   private:
     DISALLOW_COPY_AND_ASSIGN(VertexBufferInterface);
@@ -100,7 +106,7 @@
     ~StreamingVertexBufferInterface();
 
   protected:
-    bool reserveSpace(unsigned int size);
+    gl::Error reserveSpace(unsigned int size);
 };
 
 class StaticVertexBufferInterface : public VertexBufferInterface
@@ -109,13 +115,13 @@
     explicit StaticVertexBufferInterface(rx::Renderer *renderer);
     ~StaticVertexBufferInterface();
 
-    bool storeVertexAttributes(const gl::VertexAttribute &attrib, const gl::VertexAttribCurrentValueData &currentValue,
-                               GLint start, GLsizei count, GLsizei instances, unsigned int *outStreamOffset);
+    gl::Error storeVertexAttributes(const gl::VertexAttribute &attrib, const gl::VertexAttribCurrentValueData &currentValue,
+                                    GLint start, GLsizei count, GLsizei instances, unsigned int *outStreamOffset);
 
     bool lookupAttribute(const gl::VertexAttribute &attribute, unsigned int* outStreamFffset);
 
   protected:
-    bool reserveSpace(unsigned int size);
+    gl::Error reserveSpace(unsigned int size);
 
   private:
     struct VertexElement
diff --git a/src/libGLESv2/renderer/d3d/VertexDataManager.cpp b/src/libGLESv2/renderer/d3d/VertexDataManager.cpp
index fc2b8ff..7034b78 100644
--- a/src/libGLESv2/renderer/d3d/VertexDataManager.cpp
+++ b/src/libGLESv2/renderer/d3d/VertexDataManager.cpp
@@ -1,4 +1,3 @@
-#include "precompiled.h"
 //
 // 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
@@ -10,12 +9,11 @@
 
 #include "libGLESv2/renderer/d3d/VertexDataManager.h"
 #include "libGLESv2/renderer/d3d/BufferD3D.h"
-
+#include "libGLESv2/renderer/d3d/VertexBuffer.h"
+#include "libGLESv2/renderer/Renderer.h"
 #include "libGLESv2/Buffer.h"
 #include "libGLESv2/ProgramBinary.h"
 #include "libGLESv2/VertexAttribute.h"
-#include "libGLESv2/renderer/d3d/VertexBuffer.h"
-#include "libGLESv2/renderer/Renderer.h"
 
 namespace
 {
@@ -84,37 +82,22 @@
     }
 }
 
-GLenum VertexDataManager::prepareVertexData(const gl::VertexAttribute attribs[], const gl::VertexAttribCurrentValueData currentValues[],
-                                            gl::ProgramBinary *programBinary, GLint start, GLsizei count, TranslatedAttribute *translated, GLsizei instances)
+gl::Error VertexDataManager::prepareVertexData(const gl::VertexAttribute attribs[], const gl::VertexAttribCurrentValueData currentValues[],
+                                               gl::ProgramBinary *programBinary, GLint start, GLsizei count, TranslatedAttribute *translated, GLsizei instances)
 {
     if (!mStreamingBuffer)
     {
-        return GL_OUT_OF_MEMORY;
-    }
-
-    for (int attributeIndex = 0; attributeIndex < gl::MAX_VERTEX_ATTRIBS; attributeIndex++)
-    {
-        translated[attributeIndex].active = (programBinary->getSemanticIndex(attributeIndex) != -1);
+        return gl::Error(GL_OUT_OF_MEMORY, "Internal streaming vertex buffer is unexpectedly NULL.");
     }
 
     // Invalidate static buffers that don't contain matching attributes
-    for (int i = 0; i < gl::MAX_VERTEX_ATTRIBS; i++)
+    for (int attributeIndex = 0; attributeIndex < gl::MAX_VERTEX_ATTRIBS; attributeIndex++)
     {
-        if (translated[i].active && attribs[i].enabled)
+        translated[attributeIndex].active = (programBinary->getSemanticIndex(attributeIndex) != -1);
+
+        if (translated[attributeIndex].active && attribs[attributeIndex].enabled)
         {
-            gl::Buffer *buffer = attribs[i].buffer.get();
-
-            if (buffer)
-            {
-                BufferD3D *bufferImpl = BufferD3D::makeBufferD3D(buffer->getImplementation());
-                StaticVertexBufferInterface *staticBuffer = bufferImpl->getStaticVertexBuffer();
-
-                if (staticBuffer && staticBuffer->getBufferSize() > 0 && !staticBuffer->lookupAttribute(attribs[i], NULL) &&
-                    !staticBuffer->directStoragePossible(attribs[i], currentValues[i]))
-                {
-                    bufferImpl->invalidateStaticData();
-                }
-            }
+            invalidateMatchingStaticData(attribs[attributeIndex], currentValues[attributeIndex]);
         }
     }
 
@@ -123,40 +106,10 @@
     {
         if (translated[i].active && attribs[i].enabled)
         {
-            gl::Buffer *buffer = attribs[i].buffer.get();
-            BufferD3D *bufferImpl = buffer ? BufferD3D::makeBufferD3D(buffer->getImplementation()) : NULL;
-            StaticVertexBufferInterface *staticBuffer = bufferImpl ? bufferImpl->getStaticVertexBuffer() : NULL;
-            VertexBufferInterface *vertexBuffer = staticBuffer ? staticBuffer : static_cast<VertexBufferInterface*>(mStreamingBuffer);
-
-            if (!vertexBuffer->directStoragePossible(attribs[i], currentValues[i]))
+            gl::Error error = reserveSpaceForAttrib(attribs[i], currentValues[i], count, instances);
+            if (error.isError())
             {
-                if (staticBuffer)
-                {
-                    if (staticBuffer->getBufferSize() == 0)
-                    {
-                        int totalCount = ElementsInBuffer(attribs[i], bufferImpl->getSize());
-                        if (!staticBuffer->reserveVertexSpace(attribs[i], totalCount, 0))
-                        {
-                            return GL_OUT_OF_MEMORY;
-                        }
-                    }
-                }
-                else
-                {
-                    int totalCount = StreamingBufferElementCount(attribs[i], count, instances);
-
-                    // [OpenGL ES 3.0.2] section 2.9.4 page 40:
-                    // We can return INVALID_OPERATION if our vertex attribute does not have enough backing data.
-                    if (bufferImpl && ElementsInBuffer(attribs[i], bufferImpl->getSize()) < totalCount)
-                    {
-                        return GL_INVALID_OPERATION;
-                    }
-
-                    if (!mStreamingBuffer->reserveVertexSpace(attribs[i], totalCount, instances))
-                    {
-                        return GL_OUT_OF_MEMORY;
-                    }
-                }
+                return error;
             }
         }
     }
@@ -168,77 +121,12 @@
         {
             if (attribs[i].enabled)
             {
-                gl::Buffer *buffer = attribs[i].buffer.get();
-
-                if (!buffer && attribs[i].pointer == NULL)
+                gl::Error error = storeAttribute(attribs[i], currentValues[i], &translated[i],
+                                                 start, count, instances);
+                if (error.isError())
                 {
-                    // This is an application error that would normally result in a crash, but we catch it and return an error
-                    ERR("An enabled vertex array has no buffer and no pointer.");
-                    return GL_INVALID_OPERATION;
+                    return error;
                 }
-
-                BufferD3D *storage = buffer ? BufferD3D::makeBufferD3D(buffer->getImplementation()) : NULL;
-                StaticVertexBufferInterface *staticBuffer = storage ? storage->getStaticVertexBuffer() : NULL;
-                VertexBufferInterface *vertexBuffer = staticBuffer ? staticBuffer : static_cast<VertexBufferInterface*>(mStreamingBuffer);
-                bool directStorage = vertexBuffer->directStoragePossible(attribs[i], currentValues[i]);
-
-                unsigned int streamOffset = 0;
-                unsigned int outputElementSize = 0;
-
-                if (directStorage)
-                {
-                    outputElementSize = ComputeVertexAttributeStride(attribs[i]);
-                    streamOffset = attribs[i].offset + outputElementSize * start;
-                }
-                else if (staticBuffer)
-                {
-                    if (!staticBuffer->getVertexBuffer()->getSpaceRequired(attribs[i], 1, 0, &outputElementSize))
-                    {
-                        return GL_OUT_OF_MEMORY;
-                    }
-
-                    if (!staticBuffer->lookupAttribute(attribs[i], &streamOffset))
-                    {
-                        // Convert the entire buffer
-                        int totalCount = ElementsInBuffer(attribs[i], storage->getSize());
-                        int startIndex = attribs[i].offset / ComputeVertexAttributeStride(attribs[i]);
-
-                        if (!staticBuffer->storeVertexAttributes(attribs[i], currentValues[i], -startIndex, totalCount,
-                                                                 0, &streamOffset))
-                        {
-                            return GL_OUT_OF_MEMORY;
-                        }
-                    }
-
-                    unsigned int firstElementOffset = (attribs[i].offset / ComputeVertexAttributeStride(attribs[i])) * outputElementSize;
-                    unsigned int startOffset = (instances == 0 || attribs[i].divisor == 0) ? start * outputElementSize : 0;
-                    if (streamOffset + firstElementOffset + startOffset < streamOffset)
-                    {
-                        return GL_OUT_OF_MEMORY;
-                    }
-
-                    streamOffset += firstElementOffset + startOffset;
-                }
-                else
-                {
-                    int totalCount = StreamingBufferElementCount(attribs[i], count, instances);
-                    if (!mStreamingBuffer->getVertexBuffer()->getSpaceRequired(attribs[i], 1, 0, &outputElementSize) ||
-                        !mStreamingBuffer->storeVertexAttributes(attribs[i], currentValues[i], start, totalCount, instances,
-                                                                 &streamOffset))
-                    {
-                        return GL_OUT_OF_MEMORY;
-                    }
-                }
-
-                translated[i].storage = directStorage ? storage : NULL;
-                translated[i].vertexBuffer = vertexBuffer->getVertexBuffer();
-                translated[i].serial = directStorage ? storage->getSerial() : vertexBuffer->getSerial();
-                translated[i].divisor = attribs[i].divisor;
-
-                translated[i].attribute = &attribs[i];
-                translated[i].currentValueType = currentValues[i].Type;
-                translated[i].stride = outputElementSize;
-                translated[i].offset = streamOffset;
             }
             else
             {
@@ -247,34 +135,13 @@
                     mCurrentValueBuffer[i] = new StreamingVertexBufferInterface(mRenderer, CONSTANT_VERTEX_BUFFER_SIZE);
                 }
 
-                StreamingVertexBufferInterface *buffer = mCurrentValueBuffer[i];
-
-                if (mCurrentValue[i] != currentValues[i])
+                gl::Error error = storeCurrentValue(attribs[i], currentValues[i], &translated[i],
+                                                    &mCurrentValue[i], &mCurrentValueOffsets[i],
+                                                    mCurrentValueBuffer[i]);
+                if (error.isError())
                 {
-                    if (!buffer->reserveVertexSpace(attribs[i], 1, 0))
-                    {
-                        return GL_OUT_OF_MEMORY;
-                    }
-
-                    unsigned int streamOffset;
-                    if (!buffer->storeVertexAttributes(attribs[i], currentValues[i], 0, 1, 0, &streamOffset))
-                    {
-                        return GL_OUT_OF_MEMORY;
-                    }
-
-                    mCurrentValue[i] = currentValues[i];
-                    mCurrentValueOffsets[i] = streamOffset;
+                    return error;
                 }
-
-                translated[i].storage = NULL;
-                translated[i].vertexBuffer = mCurrentValueBuffer[i]->getVertexBuffer();
-                translated[i].serial = mCurrentValueBuffer[i]->getSerial();
-                translated[i].divisor = 0;
-
-                translated[i].attribute = &attribs[i];
-                translated[i].currentValueType = currentValues[i].Type;
-                translated[i].stride = 0;
-                translated[i].offset = mCurrentValueOffsets[i];
             }
         }
     }
@@ -293,7 +160,189 @@
         }
     }
 
-    return GL_NO_ERROR;
+    return gl::Error(GL_NO_ERROR);
+}
+
+void VertexDataManager::invalidateMatchingStaticData(const gl::VertexAttribute &attrib,
+                                                     const gl::VertexAttribCurrentValueData &currentValue) const
+{
+    gl::Buffer *buffer = attrib.buffer.get();
+
+    if (buffer)
+    {
+        BufferD3D *bufferImpl = BufferD3D::makeBufferD3D(buffer->getImplementation());
+        StaticVertexBufferInterface *staticBuffer = bufferImpl->getStaticVertexBuffer();
+
+        if (staticBuffer &&
+            staticBuffer->getBufferSize() > 0 &&
+            !staticBuffer->lookupAttribute(attrib, NULL) &&
+            !staticBuffer->directStoragePossible(attrib, currentValue))
+        {
+            bufferImpl->invalidateStaticData();
+        }
+    }
+}
+
+gl::Error VertexDataManager::reserveSpaceForAttrib(const gl::VertexAttribute &attrib,
+                                                   const gl::VertexAttribCurrentValueData &currentValue,
+                                                   GLsizei count,
+                                                   GLsizei instances) const
+{
+    gl::Buffer *buffer = attrib.buffer.get();
+    BufferD3D *bufferImpl = buffer ? BufferD3D::makeBufferD3D(buffer->getImplementation()) : NULL;
+    StaticVertexBufferInterface *staticBuffer = bufferImpl ? bufferImpl->getStaticVertexBuffer() : NULL;
+    VertexBufferInterface *vertexBuffer = staticBuffer ? staticBuffer : static_cast<VertexBufferInterface*>(mStreamingBuffer);
+
+    if (!vertexBuffer->directStoragePossible(attrib, currentValue))
+    {
+        if (staticBuffer)
+        {
+            if (staticBuffer->getBufferSize() == 0)
+            {
+                int totalCount = ElementsInBuffer(attrib, bufferImpl->getSize());
+                gl::Error error = staticBuffer->reserveVertexSpace(attrib, totalCount, 0);
+                if (error.isError())
+                {
+                    return error;
+                }
+            }
+        }
+        else
+        {
+            int totalCount = StreamingBufferElementCount(attrib, count, instances);
+            ASSERT(!bufferImpl || ElementsInBuffer(attrib, bufferImpl->getSize()) >= totalCount);
+
+            gl::Error error = mStreamingBuffer->reserveVertexSpace(attrib, totalCount, instances);
+            if (error.isError())
+            {
+                return error;
+            }
+        }
+    }
+
+    return gl::Error(GL_NO_ERROR);
+}
+
+gl::Error VertexDataManager::storeAttribute(const gl::VertexAttribute &attrib,
+                                            const gl::VertexAttribCurrentValueData &currentValue,
+                                            TranslatedAttribute *translated,
+                                            GLint start,
+                                            GLsizei count,
+                                            GLsizei instances)
+{
+    gl::Buffer *buffer = attrib.buffer.get();
+    ASSERT(buffer || attrib.pointer);
+
+    BufferD3D *storage = buffer ? BufferD3D::makeBufferD3D(buffer->getImplementation()) : NULL;
+    StaticVertexBufferInterface *staticBuffer = storage ? storage->getStaticVertexBuffer() : NULL;
+    VertexBufferInterface *vertexBuffer = staticBuffer ? staticBuffer : static_cast<VertexBufferInterface*>(mStreamingBuffer);
+    bool directStorage = vertexBuffer->directStoragePossible(attrib, currentValue);
+
+    unsigned int streamOffset = 0;
+    unsigned int outputElementSize = 0;
+
+    if (directStorage)
+    {
+        outputElementSize = ComputeVertexAttributeStride(attrib);
+        streamOffset = attrib.offset + outputElementSize * start;
+    }
+    else if (staticBuffer)
+    {
+        gl::Error error = staticBuffer->getVertexBuffer()->getSpaceRequired(attrib, 1, 0, &outputElementSize);
+        if (error.isError())
+        {
+            return error;
+        }
+
+        if (!staticBuffer->lookupAttribute(attrib, &streamOffset))
+        {
+            // Convert the entire buffer
+            int totalCount = ElementsInBuffer(attrib, storage->getSize());
+            int startIndex = attrib.offset / ComputeVertexAttributeStride(attrib);
+
+            gl::Error error = staticBuffer->storeVertexAttributes(attrib, currentValue, -startIndex, totalCount,
+                                                                  0, &streamOffset);
+            if (error.isError())
+            {
+                return error;
+            }
+        }
+
+        unsigned int firstElementOffset = (attrib.offset / ComputeVertexAttributeStride(attrib)) * outputElementSize;
+        unsigned int startOffset = (instances == 0 || attrib.divisor == 0) ? start * outputElementSize : 0;
+        if (streamOffset + firstElementOffset + startOffset < streamOffset)
+        {
+            return gl::Error(GL_OUT_OF_MEMORY);
+        }
+
+        streamOffset += firstElementOffset + startOffset;
+    }
+    else
+    {
+        int totalCount = StreamingBufferElementCount(attrib, count, instances);
+        gl::Error error = mStreamingBuffer->getVertexBuffer()->getSpaceRequired(attrib, 1, 0, &outputElementSize);
+        if (error.isError())
+        {
+            return error;
+        }
+
+        error = mStreamingBuffer->storeVertexAttributes(attrib, currentValue, start, totalCount, instances, &streamOffset);
+        if (error.isError())
+        {
+            return error;
+        }
+    }
+
+    translated->storage = directStorage ? storage : NULL;
+    translated->vertexBuffer = vertexBuffer->getVertexBuffer();
+    translated->serial = directStorage ? storage->getSerial() : vertexBuffer->getSerial();
+    translated->divisor = attrib.divisor;
+
+    translated->attribute = &attrib;
+    translated->currentValueType = currentValue.Type;
+    translated->stride = outputElementSize;
+    translated->offset = streamOffset;
+
+    return gl::Error(GL_NO_ERROR);
+}
+
+gl::Error VertexDataManager::storeCurrentValue(const gl::VertexAttribute &attrib,
+                                               const gl::VertexAttribCurrentValueData &currentValue,
+                                               TranslatedAttribute *translated,
+                                               gl::VertexAttribCurrentValueData *cachedValue,
+                                               size_t *cachedOffset,
+                                               StreamingVertexBufferInterface *buffer)
+{
+    if (*cachedValue != currentValue)
+    {
+        gl::Error error = buffer->reserveVertexSpace(attrib, 1, 0);
+        if (error.isError())
+        {
+            return error;
+        }
+
+        unsigned int streamOffset;
+        error = buffer->storeVertexAttributes(attrib, currentValue, 0, 1, 0, &streamOffset);
+        if (error.isError())
+        {
+            return error;
+        }
+
+        *cachedValue = currentValue;
+        *cachedOffset = streamOffset;
+    }
+
+    translated->storage = NULL;
+    translated->vertexBuffer = buffer->getVertexBuffer();
+    translated->serial = buffer->getSerial();
+    translated->divisor = 0;
+
+    translated->attribute = &attrib;
+    translated->currentValueType = currentValue.Type;
+    translated->stride = 0;
+    translated->offset = *cachedOffset;
+
+    return gl::Error(GL_NO_ERROR);
 }
 
 }
diff --git a/src/libGLESv2/renderer/d3d/VertexDataManager.h b/src/libGLESv2/renderer/d3d/VertexDataManager.h
index 4164fbe..7728722 100644
--- a/src/libGLESv2/renderer/d3d/VertexDataManager.h
+++ b/src/libGLESv2/renderer/d3d/VertexDataManager.h
@@ -30,6 +30,9 @@
 
 struct TranslatedAttribute
 {
+    TranslatedAttribute() : active(false), attribute(NULL), currentValueType(GL_NONE),
+                            offset(0), stride(0), vertexBuffer(NULL), storage(NULL),
+                            serial(0), divisor(0) {};
     bool active;
 
     const gl::VertexAttribute *attribute;
@@ -49,12 +52,34 @@
     VertexDataManager(rx::Renderer *renderer);
     virtual ~VertexDataManager();
 
-    GLenum prepareVertexData(const gl::VertexAttribute attribs[], const gl::VertexAttribCurrentValueData currentValues[],
-                             gl::ProgramBinary *programBinary, GLint start, GLsizei count, TranslatedAttribute *outAttribs, GLsizei instances);
+    gl::Error prepareVertexData(const gl::VertexAttribute attribs[], const gl::VertexAttribCurrentValueData currentValues[],
+                                gl::ProgramBinary *programBinary, GLint start, GLsizei count, TranslatedAttribute *outAttribs, GLsizei instances);
 
   private:
     DISALLOW_COPY_AND_ASSIGN(VertexDataManager);
 
+    gl::Error reserveSpaceForAttrib(const gl::VertexAttribute &attrib,
+                                    const gl::VertexAttribCurrentValueData &currentValue,
+                                    GLsizei count,
+                                    GLsizei instances) const;
+
+    void invalidateMatchingStaticData(const gl::VertexAttribute &attrib,
+                                      const gl::VertexAttribCurrentValueData &currentValue) const;
+
+    gl::Error storeAttribute(const gl::VertexAttribute &attrib,
+                             const gl::VertexAttribCurrentValueData &currentValue,
+                             TranslatedAttribute *translated,
+                             GLint start,
+                             GLsizei count,
+                             GLsizei instances);
+
+    gl::Error storeCurrentValue(const gl::VertexAttribute &attrib,
+                                const gl::VertexAttribCurrentValueData &currentValue,
+                                TranslatedAttribute *translated,
+                                gl::VertexAttribCurrentValueData *cachedValue,
+                                size_t *cachedOffset,
+                                StreamingVertexBufferInterface *buffer);
+
     rx::Renderer *const mRenderer;
 
     StreamingVertexBufferInterface *mStreamingBuffer;
diff --git a/src/libGLESv2/renderer/d3d/d3d11/Blit11.cpp b/src/libGLESv2/renderer/d3d/d3d11/Blit11.cpp
index 4ac50e8..edbc169 100644
--- a/src/libGLESv2/renderer/d3d/d3d11/Blit11.cpp
+++ b/src/libGLESv2/renderer/d3d/d3d11/Blit11.cpp
@@ -1,4 +1,3 @@
-#include "precompiled.h"
 //
 // 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
@@ -7,12 +6,12 @@
 
 // Blit11.cpp: Texture copy utility class.
 
-#include "libGLESv2/main.h"
-#include "libGLESv2/formatutils.h"
 #include "libGLESv2/renderer/d3d/d3d11/Blit11.h"
 #include "libGLESv2/renderer/d3d/d3d11/Renderer11.h"
 #include "libGLESv2/renderer/d3d/d3d11/renderer11_utils.h"
 #include "libGLESv2/renderer/d3d/d3d11/formatutils11.h"
+#include "libGLESv2/main.h"
+#include "libGLESv2/formatutils.h"
 
 #include "libGLESv2/renderer/d3d/d3d11/shaders/compiled/passthrough2d11vs.h"
 #include "libGLESv2/renderer/d3d/d3d11/shaders/compiled/passthroughdepth2d11ps.h"
diff --git a/src/libGLESv2/renderer/d3d/d3d11/Blit11.h b/src/libGLESv2/renderer/d3d/d3d11/Blit11.h
index fba89e2..4e57042 100644
--- a/src/libGLESv2/renderer/d3d/d3d11/Blit11.h
+++ b/src/libGLESv2/renderer/d3d/d3d11/Blit11.h
@@ -12,6 +12,8 @@
 #include "common/angleutils.h"
 #include "libGLESv2/angletypes.h"
 
+#include <map>
+
 namespace rx
 {
 class Renderer11;
diff --git a/src/libGLESv2/renderer/d3d/d3d11/Buffer11.cpp b/src/libGLESv2/renderer/d3d/d3d11/Buffer11.cpp
index 48514db..43ce5ba 100644
--- a/src/libGLESv2/renderer/d3d/d3d11/Buffer11.cpp
+++ b/src/libGLESv2/renderer/d3d/d3d11/Buffer11.cpp
@@ -1,4 +1,3 @@
-#include "precompiled.h"
 //
 // Copyright 2014 The ANGLE Project Authors. All rights reserved.
 // Use of this source code is governed by a BSD-style license that can be
@@ -8,9 +7,9 @@
 // Buffer11.cpp Defines the Buffer11 class.
 
 #include "libGLESv2/renderer/d3d/d3d11/Buffer11.h"
-#include "libGLESv2/main.h"
 #include "libGLESv2/renderer/d3d/d3d11/Renderer11.h"
 #include "libGLESv2/renderer/d3d/d3d11/formatutils11.h"
+#include "libGLESv2/main.h"
 
 namespace rx
 {
@@ -118,6 +117,8 @@
     virtual void *map(size_t offset, size_t length, GLbitfield access);
     virtual void unmap();
 
+    bool setData(D3D11_MAP mapMode, const uint8_t *data, size_t size, size_t offset);
+
   private:
     ID3D11Buffer *mNativeBuffer;
 
@@ -139,7 +140,7 @@
     virtual void *map(size_t offset, size_t length, GLbitfield access);
     virtual void unmap();
 
-    void packPixels(ID3D11Texture2D *srcTexure, UINT srcSubresource, const PackPixelsParams &params);
+    gl::Error packPixels(ID3D11Texture2D *srcTexure, UINT srcSubresource, const PackPixelsParams &params);
 
   private:
 
@@ -178,16 +179,20 @@
     return static_cast<Buffer11*>(buffer);
 }
 
-void Buffer11::setData(const void* data, size_t size, GLenum usage)
+gl::Error Buffer11::setData(const void *data, size_t size, GLenum usage)
 {
-    mIndexRangeCache.clear();
-
-    setSubData(data, size, 0);
+    gl::Error error = setSubData(data, size, 0);
+    if (error.isError())
+    {
+        return error;
+    }
 
     if (usage == GL_STATIC_DRAW)
     {
         initializeStaticData();
     }
+
+    return error;
 }
 
 void *Buffer11::getData()
@@ -228,16 +233,23 @@
 
     mReadUsageCount = 0;
 
+    // Only happens if we initialized the buffer with no data (NULL)
+    if (mResolvedData.empty())
+    {
+        if (!mResolvedData.resize(mSize))
+        {
+            return gl::error(GL_OUT_OF_MEMORY, (void*)NULL);
+        }
+    }
+
+    ASSERT(mResolvedData.size() >= mSize);
+
     return mResolvedData.data();
 }
 
-void Buffer11::setSubData(const void* data, size_t size, size_t offset)
+gl::Error Buffer11::setSubData(const void *data, size_t size, size_t offset)
 {
     size_t requiredSize = size + offset;
-    mSize = std::max(mSize, requiredSize);
-
-    mIndexRangeCache.invalidateRange(offset, size);
-    invalidateStaticData();
 
     if (data && size > 0)
     {
@@ -245,8 +257,7 @@
 
         if (!stagingBuffer)
         {
-            // Out-of-memory
-            return;
+            return gl::Error(GL_OUT_OF_MEMORY, "Failed to allocate internal staging buffer.");
         }
 
         // Explicitly resize the staging buffer, preserving data if the new data will not
@@ -256,81 +267,78 @@
             bool preserveData = (offset > 0);
             if (!stagingBuffer->resize(requiredSize, preserveData))
             {
-                // Out-of-memory
-                return;
+                return gl::Error(GL_OUT_OF_MEMORY, "Failed to resize internal staging buffer.");
             }
         }
 
-        ID3D11DeviceContext *context = mRenderer->getDeviceContext();
-
-        D3D11_MAPPED_SUBRESOURCE mappedResource;
-        HRESULT result = context->Map(stagingBuffer->getNativeBuffer(), 0, D3D11_MAP_WRITE, 0, &mappedResource);
-        if (FAILED(result))
+        if (!stagingBuffer->setData(D3D11_MAP_WRITE, reinterpret_cast<const uint8_t *>(data), size, offset))
         {
-            return gl::error(GL_OUT_OF_MEMORY);
+            return gl::Error(GL_OUT_OF_MEMORY, "Failed to set data on internal staging buffer.");
         }
 
-        unsigned char *offsetBufferPointer = reinterpret_cast<unsigned char *>(mappedResource.pData) + offset;
-        memcpy(offsetBufferPointer, data, size);
-
-        context->Unmap(stagingBuffer->getNativeBuffer(), 0);
-
         stagingBuffer->setDataRevision(stagingBuffer->getDataRevision() + 1);
     }
+
+    mSize = std::max(mSize, requiredSize);
+    invalidateStaticData();
+
+    return gl::Error(GL_NO_ERROR);
 }
 
-void Buffer11::copySubData(BufferImpl* source, GLintptr sourceOffset, GLintptr destOffset, GLsizeiptr size)
+gl::Error Buffer11::copySubData(BufferImpl* source, GLintptr sourceOffset, GLintptr destOffset, GLsizeiptr size)
 {
     Buffer11 *sourceBuffer = makeBuffer11(source);
-    if (sourceBuffer)
+    ASSERT(sourceBuffer != NULL);
+
+    BufferStorage11 *copyDest = getLatestBufferStorage();
+    if (!copyDest)
     {
-        BufferStorage11 *dest = getLatestBufferStorage();
-        if (!dest)
-        {
-            dest = getStagingBuffer();
-        }
-
-        BufferStorage11 *source = sourceBuffer->getLatestBufferStorage();
-        if (source && dest)
-        {
-            // If copying to/from a pixel pack buffer, we must have a staging or
-            // pack buffer partner, because other native buffers can't be mapped
-            if (dest->getUsage() == BUFFER_USAGE_PIXEL_PACK && !source->isMappable())
-            {
-                source = sourceBuffer->getStagingBuffer();
-            }
-            else if (source->getUsage() == BUFFER_USAGE_PIXEL_PACK && !dest->isMappable())
-            {
-                dest = getStagingBuffer();
-            }
-
-            // D3D11 does not allow overlapped copies until 11.1, and only if the
-            // device supports D3D11_FEATURE_DATA_D3D11_OPTIONS::CopyWithOverlap
-            // Get around this via a different source buffer
-            if (source == dest)
-            {
-                if (source->getUsage() == BUFFER_USAGE_STAGING)
-                {
-                    source = getBufferStorage(BUFFER_USAGE_VERTEX_OR_TRANSFORM_FEEDBACK);
-                }
-                else
-                {
-                    source = getStagingBuffer();
-                }
-            }
-
-            dest->copyFromStorage(source, sourceOffset, size, destOffset);
-            dest->setDataRevision(dest->getDataRevision() + 1);
-        }
-
-        mSize = std::max<size_t>(mSize, destOffset + size);
+        copyDest = getStagingBuffer();
     }
 
-    mIndexRangeCache.invalidateRange(destOffset, size);
+    BufferStorage11 *copySource = sourceBuffer->getLatestBufferStorage();
+
+    if (!copySource || !copyDest)
+    {
+        return gl::Error(GL_OUT_OF_MEMORY, "Failed to allocate internal staging buffer.");
+    }
+
+    // If copying to/from a pixel pack buffer, we must have a staging or
+    // pack buffer partner, because other native buffers can't be mapped
+    if (copyDest->getUsage() == BUFFER_USAGE_PIXEL_PACK && !copySource->isMappable())
+    {
+        copySource = sourceBuffer->getStagingBuffer();
+    }
+    else if (copySource->getUsage() == BUFFER_USAGE_PIXEL_PACK && !copyDest->isMappable())
+    {
+        copyDest = getStagingBuffer();
+    }
+
+    // D3D11 does not allow overlapped copies until 11.1, and only if the
+    // device supports D3D11_FEATURE_DATA_D3D11_OPTIONS::CopyWithOverlap
+    // Get around this via a different source buffer
+    if (copySource == copyDest)
+    {
+        if (copySource->getUsage() == BUFFER_USAGE_STAGING)
+        {
+            copySource = getBufferStorage(BUFFER_USAGE_VERTEX_OR_TRANSFORM_FEEDBACK);
+        }
+        else
+        {
+            copySource = getStagingBuffer();
+        }
+    }
+
+    copyDest->copyFromStorage(copySource, sourceOffset, size, destOffset);
+    copyDest->setDataRevision(copyDest->getDataRevision() + 1);
+
+    mSize = std::max<size_t>(mSize, destOffset + size);
     invalidateStaticData();
+
+    return gl::Error(GL_NO_ERROR);
 }
 
-GLvoid *Buffer11::map(size_t offset, size_t length, GLbitfield access)
+gl::Error Buffer11::map(size_t offset, size_t length, GLbitfield access, GLvoid **mapPtr)
 {
     ASSERT(!mMappedStorage);
 
@@ -351,26 +359,31 @@
 
     if (!mMappedStorage)
     {
-        // Out-of-memory
-        return NULL;
+        return gl::Error(GL_OUT_OF_MEMORY, "Failed to allocate mappable internal buffer.");
     }
 
     if ((access & GL_MAP_WRITE_BIT) > 0)
     {
-        mIndexRangeCache.invalidateRange(offset, length);
-
         // Update the data revision immediately, since the data might be changed at any time
         mMappedStorage->setDataRevision(mMappedStorage->getDataRevision() + 1);
     }
 
-    return mMappedStorage->map(offset, length, access);
+    void *mappedBuffer = mMappedStorage->map(offset, length, access);
+    if (!mappedBuffer)
+    {
+        return gl::Error(GL_OUT_OF_MEMORY, "Failed to map internal buffer.");
+    }
+
+    *mapPtr = mappedBuffer;
+    return gl::Error(GL_NO_ERROR);
 }
 
-void Buffer11::unmap()
+gl::Error Buffer11::unmap()
 {
     ASSERT(mMappedStorage);
     mMappedStorage->unmap();
     mMappedStorage = NULL;
+    return gl::Error(GL_NO_ERROR);
 }
 
 void Buffer11::markTransformFeedbackUsage()
@@ -382,7 +395,6 @@
         transformFeedbackStorage->setDataRevision(transformFeedbackStorage->getDataRevision() + 1);
     }
 
-    mIndexRangeCache.clear();
     invalidateStaticData();
 }
 
@@ -469,7 +481,7 @@
     return bufferSRV;
 }
 
-void Buffer11::packPixels(ID3D11Texture2D *srcTexture, UINT srcSubresource, const PackPixelsParams &params)
+gl::Error Buffer11::packPixels(ID3D11Texture2D *srcTexture, UINT srcSubresource, const PackPixelsParams &params)
 {
     PackStorage11 *packStorage = getPackStorage();
 
@@ -477,11 +489,15 @@
 
     if (packStorage)
     {
-        packStorage->packPixels(srcTexture, srcSubresource, params);
+        gl::Error error = packStorage->packPixels(srcTexture, srcSubresource, params);
+        if (error.isError())
+        {
+            return error;
+        }
         packStorage->setDataRevision(latestStorage ? latestStorage->getDataRevision() + 1 : 1);
     }
 
-    mIndexRangeCache.clear();
+    return gl::Error(GL_NO_ERROR);
 }
 
 Buffer11::BufferStorage11 *Buffer11::getBufferStorage(BufferUsage usage)
@@ -592,6 +608,14 @@
     return static_cast<PackStorage11*>(packStorage);
 }
 
+bool Buffer11::supportsDirectBinding() const
+{
+    // Do not support direct buffers for dynamic data. The streaming buffer
+    // offers better performance for data which changes every frame.
+    // Check for absence of static buffer interfaces to detect dynamic data.
+    return (mStaticVertexBuffer && mStaticIndexBuffer);
+}
+
 Buffer11::BufferStorage11::BufferStorage11(Renderer11 *renderer, BufferUsage usage)
     : mRenderer(renderer),
       mUsage(usage),
@@ -747,7 +771,7 @@
         // Constant buffers must be of a limited size, and aligned to 16 byte boundaries
         // For our purposes we ignore any buffer data past the maximum constant buffer size
         bufferDesc->ByteWidth = roundUp(bufferDesc->ByteWidth, 16u);
-        bufferDesc->ByteWidth = std::min(bufferDesc->ByteWidth, renderer->getMaxUniformBufferSize());
+        bufferDesc->ByteWidth = std::min<UINT>(bufferDesc->ByteWidth, renderer->getRendererCaps().maxUniformBlockSize);
         break;
 
     default:
@@ -771,6 +795,25 @@
     return static_cast<GLubyte*>(mappedResource.pData) + offset;
 }
 
+bool Buffer11::NativeBuffer11::setData(D3D11_MAP mapMode, const uint8_t *data, size_t size, size_t offset)
+{
+    ID3D11DeviceContext *context = mRenderer->getDeviceContext();
+
+    D3D11_MAPPED_SUBRESOURCE mappedResource;
+    HRESULT result = context->Map(mNativeBuffer, 0, mapMode, 0, &mappedResource);
+    if (FAILED(result))
+    {
+        return gl::error(GL_OUT_OF_MEMORY, false);
+    }
+
+    uint8_t *offsetBufferPointer = reinterpret_cast<uint8_t *>(mappedResource.pData) + offset;
+    memcpy(offsetBufferPointer, data, size);
+
+    context->Unmap(mNativeBuffer, 0);
+
+    return true;
+}
+
 void Buffer11::NativeBuffer11::unmap()
 {
     ASSERT(mUsage == BUFFER_USAGE_STAGING);
@@ -835,7 +878,7 @@
     // No-op
 }
 
-void Buffer11::PackStorage11::packPixels(ID3D11Texture2D *srcTexure, UINT srcSubresource, const PackPixelsParams &params)
+gl::Error Buffer11::PackStorage11::packPixels(ID3D11Texture2D *srcTexure, UINT srcSubresource, const PackPixelsParams &params)
 {
     flushQueuedPackCommand();
     mQueuedPackCommand = new PackPixelsParams(params);
@@ -877,7 +920,11 @@
         stagingDesc.MiscFlags = 0;
 
         hr = device->CreateTexture2D(&stagingDesc, NULL, &mStagingTexture);
-        ASSERT(SUCCEEDED(hr));
+        if (FAILED(hr))
+        {
+            ASSERT(hr == E_OUTOFMEMORY);
+            return gl::Error(GL_OUT_OF_MEMORY, "Failed to allocate internal staging texture.");
+        }
     }
 
     // ReadPixels from multisampled FBOs isn't supported in current GL
@@ -894,6 +941,8 @@
 
     // Asynchronous copy
     immediateContext->CopySubresourceRegion(mStagingTexture, 0, 0, 0, 0, srcTexure, srcSubresource, &srcBox);
+
+    return gl::Error(GL_NO_ERROR);
 }
 
 void Buffer11::PackStorage11::flushQueuedPackCommand()
diff --git a/src/libGLESv2/renderer/d3d/d3d11/Buffer11.h b/src/libGLESv2/renderer/d3d/d3d11/Buffer11.h
index 51d47ec..5f24fb4 100644
--- a/src/libGLESv2/renderer/d3d/d3d11/Buffer11.h
+++ b/src/libGLESv2/renderer/d3d/d3d11/Buffer11.h
@@ -55,20 +55,20 @@
     ID3D11Buffer *getBuffer(BufferUsage usage);
     ID3D11ShaderResourceView *getSRV(DXGI_FORMAT srvFormat);
     bool isMapped() const { return mMappedStorage != NULL; }
-    void packPixels(ID3D11Texture2D *srcTexure, UINT srcSubresource, const PackPixelsParams &params);
+    gl::Error packPixels(ID3D11Texture2D *srcTexure, UINT srcSubresource, const PackPixelsParams &params);
 
     // BufferD3D implementation
     virtual size_t getSize() const { return mSize; }
-    virtual bool supportsDirectBinding() const { return true; }
+    virtual bool supportsDirectBinding() const;
     virtual Renderer* getRenderer();
 
     // BufferImpl implementation
-    virtual void setData(const void* data, size_t size, GLenum usage);
+    virtual gl::Error setData(const void* data, size_t size, GLenum usage);
     virtual void *getData();
-    virtual void setSubData(const void* data, size_t size, size_t offset);
-    virtual void copySubData(BufferImpl* source, GLintptr sourceOffset, GLintptr destOffset, GLsizeiptr size);
-    virtual GLvoid* map(size_t offset, size_t length, GLbitfield access);
-    virtual void unmap();
+    virtual gl::Error setSubData(const void* data, size_t size, size_t offset);
+    virtual gl::Error copySubData(BufferImpl* source, GLintptr sourceOffset, GLintptr destOffset, GLsizeiptr size);
+    virtual gl::Error map(size_t offset, size_t length, GLbitfield access, GLvoid **mapPtr);
+    virtual gl::Error unmap();
     virtual void markTransformFeedbackUsage();
 
   private:
diff --git a/src/libGLESv2/renderer/d3d/d3d11/Clear11.cpp b/src/libGLESv2/renderer/d3d/d3d11/Clear11.cpp
index 1d20fd9..c60b7a6 100644
--- a/src/libGLESv2/renderer/d3d/d3d11/Clear11.cpp
+++ b/src/libGLESv2/renderer/d3d/d3d11/Clear11.cpp
@@ -1,4 +1,3 @@
-#include "precompiled.h"
 //
 // 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
@@ -11,11 +10,11 @@
 #include "libGLESv2/renderer/d3d/d3d11/Renderer11.h"
 #include "libGLESv2/renderer/d3d/d3d11/renderer11_utils.h"
 #include "libGLESv2/renderer/d3d/d3d11/RenderTarget11.h"
-
 #include "libGLESv2/formatutils.h"
 #include "libGLESv2/Framebuffer.h"
 #include "libGLESv2/FramebufferAttachment.h"
 
+// Precompiled shaders
 #include "libGLESv2/renderer/d3d/d3d11/shaders/compiled/clearfloat11vs.h"
 #include "libGLESv2/renderer/d3d/d3d11/shaders/compiled/clearfloat11ps.h"
 
@@ -149,7 +148,7 @@
     SafeRelease(mRasterizerState);
 }
 
-void Clear11::clearFramebuffer(const gl::ClearParameters &clearParams, gl::Framebuffer *frameBuffer)
+gl::Error Clear11::clearFramebuffer(const gl::ClearParameters &clearParams, gl::Framebuffer *frameBuffer)
 {
     // First determine if a scissored clear is needed, this will always require drawing a quad.
     //
@@ -184,7 +183,7 @@
     else
     {
         UNREACHABLE();
-        return;
+        return gl::Error(GL_INVALID_OPERATION);
     }
 
     if (clearParams.scissorEnabled && (clearParams.scissor.x >= framebufferSize.width || 
@@ -193,7 +192,7 @@
                                        clearParams.scissor.y + clearParams.scissor.height <= 0))
     {
         // Scissor is enabled and the scissor rectangle is outside the renderbuffer
-        return;
+        return gl::Error(GL_NO_ERROR);
     }
 
     bool needScissoredClear = clearParams.scissorEnabled && (clearParams.scissor.x > 0 || clearParams.scissor.y > 0 ||
@@ -212,11 +211,10 @@
             gl::FramebufferAttachment *attachment = frameBuffer->getColorbuffer(colorAttachment);
             if (attachment)
             {
-                RenderTarget11 *renderTarget = RenderTarget11::makeRenderTarget11(attachment->getRenderTarget());
+                RenderTarget11 *renderTarget = d3d11::GetAttachmentRenderTarget(attachment);
                 if (!renderTarget)
                 {
-                    ERR("Render target pointer unexpectedly null.");
-                    return;
+                    return gl::Error(GL_OUT_OF_MEMORY, "Internal render target view pointer unexpectedly null.");
                 }
 
                 const gl::InternalFormat &formatInfo = gl::GetInternalFormatInfo(attachment->getInternalFormat());
@@ -260,8 +258,7 @@
                     ID3D11RenderTargetView *framebufferRTV = renderTarget->getRenderTargetView();
                     if (!framebufferRTV)
                     {
-                        ERR("Render target view pointer unexpectedly null.");
-                        return;
+                        return gl::Error(GL_OUT_OF_MEMORY, "Internal render target view pointer unexpectedly null.");
                     }
 
                     const gl::InternalFormat &actualFormatInfo = gl::GetInternalFormatInfo(attachment->getActualFormat());
@@ -287,11 +284,10 @@
         gl::FramebufferAttachment *attachment = frameBuffer->getDepthOrStencilbuffer();
         if (attachment)
         {
-            RenderTarget11 *renderTarget = RenderTarget11::makeRenderTarget11(attachment->getDepthStencil());
+            RenderTarget11 *renderTarget = d3d11::GetAttachmentRenderTarget(attachment);
             if (!renderTarget)
             {
-                ERR("Depth stencil render target pointer unexpectedly null.");
-                return;
+                return gl::Error(GL_OUT_OF_MEMORY, "Internal depth stencil view pointer unexpectedly null.");
             }
 
             const gl::InternalFormat &actualFormatInfo = gl::GetInternalFormatInfo(attachment->getActualFormat());
@@ -308,8 +304,7 @@
                 ID3D11DepthStencilView *framebufferDSV = renderTarget->getDepthStencilView();
                 if (!framebufferDSV)
                 {
-                    ERR("Depth stencil view pointer unexpectedly null.");
-                    return;
+                    return gl::Error(GL_OUT_OF_MEMORY, "Internal depth stencil view pointer unexpectedly null.");
                 }
 
                 UINT clearFlags = (clearParams.clearDepth   ? D3D11_CLEAR_DEPTH   : 0) |
@@ -356,8 +351,7 @@
             ID3D11RenderTargetView *rtv = renderTarget->getRenderTargetView();
             if (!rtv)
             {
-                ERR("Render target view unexpectedly null.");
-                return;
+                return gl::Error(GL_OUT_OF_MEMORY, "Internal render target view pointer unexpectedly null.");
             }
 
             rtvs[i] = rtv;
@@ -379,8 +373,7 @@
         HRESULT result = deviceContext->Map(mVertexBuffer, 0, D3D11_MAP_WRITE_DISCARD, 0, &mappedResource);
         if (FAILED(result))
         {
-            ERR("Failed to map masked clear vertex buffer, HRESULT: 0x%X.", result);
-            return;
+            return gl::Error(GL_OUT_OF_MEMORY, "Failed to map internal masked clear vertex buffer, HRESULT: 0x%X.", result);
         }
 
         const gl::Rectangle *scissorPtr = clearParams.scissorEnabled ? &clearParams.scissor : NULL;
@@ -445,6 +438,8 @@
         // Clean up
         mRenderer->markAllStateDirty();
     }
+
+    return gl::Error(GL_NO_ERROR);
 }
 
 ID3D11BlendState *Clear11::getBlendState(const std::vector<MaskedRenderTarget>& rts)
diff --git a/src/libGLESv2/renderer/d3d/d3d11/Clear11.h b/src/libGLESv2/renderer/d3d/d3d11/Clear11.h
index 0cb9a85..be8e187 100644
--- a/src/libGLESv2/renderer/d3d/d3d11/Clear11.h
+++ b/src/libGLESv2/renderer/d3d/d3d11/Clear11.h
@@ -10,6 +10,10 @@
 #define LIBGLESV2_RENDERER_CLEAR11_H_
 
 #include "libGLESv2/angletypes.h"
+#include "libGLESv2/Error.h"
+
+#include <map>
+#include <vector>
 
 namespace gl
 {
@@ -28,7 +32,7 @@
     ~Clear11();
 
     // Clears the framebuffer with the supplied clear parameters, assumes that the framebuffer is currently applied.
-    void clearFramebuffer(const gl::ClearParameters &clearParams, gl::Framebuffer *frameBuffer);
+    gl::Error clearFramebuffer(const gl::ClearParameters &clearParams, gl::Framebuffer *frameBuffer);
 
   private:
     Renderer11 *mRenderer;
diff --git a/src/libGLESv2/renderer/d3d/d3d11/Fence11.cpp b/src/libGLESv2/renderer/d3d/d3d11/Fence11.cpp
index 8698776..a841b52 100644
--- a/src/libGLESv2/renderer/d3d/d3d11/Fence11.cpp
+++ b/src/libGLESv2/renderer/d3d/d3d11/Fence11.cpp
@@ -1,4 +1,3 @@
-#include "precompiled.h"
 //
 // 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
@@ -8,8 +7,8 @@
 // Fence11.cpp: Defines the rx::Fence11 class which implements rx::FenceImpl.
 
 #include "libGLESv2/renderer/d3d/d3d11/Fence11.h"
-#include "libGLESv2/main.h"
 #include "libGLESv2/renderer/d3d/d3d11/Renderer11.h"
+#include "libGLESv2/main.h"
 
 namespace rx
 {
diff --git a/src/libGLESv2/renderer/d3d/d3d11/Image11.cpp b/src/libGLESv2/renderer/d3d/d3d11/Image11.cpp
index 08b16ee..7536713 100644
--- a/src/libGLESv2/renderer/d3d/d3d11/Image11.cpp
+++ b/src/libGLESv2/renderer/d3d/d3d11/Image11.cpp
@@ -1,4 +1,3 @@
-#include "precompiled.h"
 //
 // Copyright (c) 2012 The ANGLE Project Authors. All rights reserved.
 // Use of this source code is governed by a BSD-style license that can be
@@ -11,13 +10,13 @@
 #include "libGLESv2/renderer/d3d/d3d11/Renderer11.h"
 #include "libGLESv2/renderer/d3d/d3d11/Image11.h"
 #include "libGLESv2/renderer/d3d/d3d11/TextureStorage11.h"
-#include "libGLESv2/Framebuffer.h"
-#include "libGLESv2/FramebufferAttachment.h"
-
-#include "libGLESv2/main.h"
-#include "common/utilities.h"
 #include "libGLESv2/renderer/d3d/d3d11/formatutils11.h"
 #include "libGLESv2/renderer/d3d/d3d11/renderer11_utils.h"
+#include "libGLESv2/Framebuffer.h"
+#include "libGLESv2/FramebufferAttachment.h"
+#include "libGLESv2/main.h"
+
+#include "common/utilities.h"
 
 namespace rx
 {
@@ -27,11 +26,17 @@
     mStagingTexture = NULL;
     mRenderer = NULL;
     mDXGIFormat = DXGI_FORMAT_UNKNOWN;
+    mRecoverFromStorage = false;
+    mAssociatedStorage = NULL;
+    mAssociatedStorageLevel = 0;
+    mAssociatedStorageLayerTarget = 0;
+    mRecoveredFromStorageCount = 0;
 }
 
 Image11::~Image11()
 {
-    SafeRelease(mStagingTexture);
+    disassociateStorage();
+    releaseStagingTexture();
 }
 
 Image11 *Image11::makeImage11(Image *img)
@@ -82,33 +87,117 @@
 
 bool Image11::isDirty() const
 {
-    // Make sure that this image is marked as dirty even if the staging texture hasn't been created yet
-    // if initialization is required before use.
-    return (mDirty && (mStagingTexture || d3d11::GetTextureFormatInfo(mInternalFormat).dataInitializerFunction != NULL));
+    // 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)
+    // then isDirty should still return false.
+    if (mDirty && !mStagingTexture && !mRecoverFromStorage && !(d3d11::GetTextureFormatInfo(mInternalFormat).dataInitializerFunction != NULL))
+    {
+        return false;
+    }
+
+    return mDirty;
 }
 
-bool Image11::copyToStorage(TextureStorageInterface2D *storage, int level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height)
+bool Image11::copyToStorage2D(TextureStorage *storage, int level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height)
 {
-    TextureStorage11_2D *storage11 = TextureStorage11_2D::makeTextureStorage11_2D(storage->getStorageInstance());
-    return storage11->updateSubresourceLevel(getStagingTexture(), getStagingSubresource(), level, 0, xoffset, yoffset, 0, width, height, 1);
+    TextureStorage11_2D *storage11 = TextureStorage11_2D::makeTextureStorage11_2D(storage);
+    return copyToStorageImpl(storage11, level, 0, xoffset, yoffset, width, height);
 }
 
-bool Image11::copyToStorage(TextureStorageInterfaceCube *storage, int face, int level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height)
+bool Image11::copyToStorageCube(TextureStorage *storage, int face, int level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height)
 {
-    TextureStorage11_Cube *storage11 = TextureStorage11_Cube::makeTextureStorage11_Cube(storage->getStorageInstance());
-    return storage11->updateSubresourceLevel(getStagingTexture(), getStagingSubresource(), level, face, xoffset, yoffset, 0, width, height, 1);
+    TextureStorage11_Cube *storage11 = TextureStorage11_Cube::makeTextureStorage11_Cube(storage);
+    return copyToStorageImpl(storage11, level, face, xoffset, yoffset, width, height);
 }
 
-bool Image11::copyToStorage(TextureStorageInterface3D *storage, int level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth)
+bool Image11::copyToStorage3D(TextureStorage *storage, int level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth)
 {
-    TextureStorage11_3D *storage11 = TextureStorage11_3D::makeTextureStorage11_3D(storage->getStorageInstance());
-    return storage11->updateSubresourceLevel(getStagingTexture(), getStagingSubresource(), level, 0, xoffset, yoffset, zoffset, width, height, depth);
+    TextureStorage11_3D *storage11 = TextureStorage11_3D::makeTextureStorage11_3D(storage);
+    return copyToStorageImpl(storage11, level, 0, xoffset, yoffset, width, height);
 }
 
-bool Image11::copyToStorage(TextureStorageInterface2DArray *storage, int level, GLint xoffset, GLint yoffset, GLint arrayLayer, GLsizei width, GLsizei height)
+bool Image11::copyToStorage2DArray(TextureStorage *storage, int level, GLint xoffset, GLint yoffset, GLint arrayLayer, GLsizei width, GLsizei height)
 {
-    TextureStorage11_2DArray *storage11 = TextureStorage11_2DArray::makeTextureStorage11_2DArray(storage->getStorageInstance());
-    return storage11->updateSubresourceLevel(getStagingTexture(), getStagingSubresource(), level, arrayLayer, xoffset, yoffset, 0, width, height, 1);
+    TextureStorage11_2DArray *storage11 = TextureStorage11_2DArray::makeTextureStorage11_2DArray(storage);
+    return copyToStorageImpl(storage11, level, arrayLayer, xoffset, yoffset, width, height);
+}
+
+bool Image11::copyToStorageImpl(TextureStorage11 *storage11, int level, int layerTarget, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height)
+{
+    // If an app's behavior results in an Image11 copying its data to/from to a TextureStorage multiple times,
+    // then we should just keep the staging texture around to prevent the copying from impacting perf.
+    // We allow the Image11 to copy its data to/from TextureStorage once.
+    // This accounts for an app making a late call to glGenerateMipmap.
+    bool attemptToReleaseStagingTexture = (mRecoveredFromStorageCount < 2);
+
+    if (attemptToReleaseStagingTexture)
+    {
+        // If another image is relying on this Storage for its data, then we must let it recover its data before we overwrite it.
+        storage11->releaseAssociatedImage(level, layerTarget, this);
+    }
+
+    bool updateSubresourceSuccess = storage11->updateSubresourceLevel(getStagingTexture(), getStagingSubresource(), level, layerTarget, xoffset, yoffset, 0, width, height, 1);
+
+    // Once the image data has been copied into the Storage, we can release it locally.
+    if (attemptToReleaseStagingTexture && updateSubresourceSuccess)
+    {
+        storage11->associateImage(this, level, layerTarget);
+        releaseStagingTexture();
+        mRecoverFromStorage = true;
+        mAssociatedStorage = storage11;
+        mAssociatedStorageLevel = level;
+        mAssociatedStorageLayerTarget = layerTarget;
+    }
+
+    return updateSubresourceSuccess;
+}
+
+bool Image11::isAssociatedStorageValid(TextureStorage11* textureStorage) const
+{
+    return (mAssociatedStorage == textureStorage);
+}
+
+bool Image11::recoverFromAssociatedStorage()
+{
+    if (mRecoverFromStorage)
+    {
+        createStagingTexture();
+
+        bool textureStorageCorrect = mAssociatedStorage->isAssociatedImageValid(mAssociatedStorageLevel, mAssociatedStorageLayerTarget, this);
+
+        // This means that the cached TextureStorage has been modified after this Image11 released its copy of its data. 
+        // This should not have happened. The TextureStorage should have told this Image11 to recover its data before it was overwritten.
+        ASSERT(textureStorageCorrect);
+
+        if (textureStorageCorrect)
+        {
+            // CopySubResource from the Storage to the Staging texture
+            mAssociatedStorage->copySubresourceLevel(mStagingTexture, mStagingSubresource, mAssociatedStorageLevel, mAssociatedStorageLayerTarget, 0, 0, 0, mWidth, mHeight, mDepth);
+            mRecoveredFromStorageCount += 1;
+        }
+
+        // Reset all the recovery parameters, even if the texture storage association is broken.
+        disassociateStorage();
+
+        return textureStorageCorrect;
+    }
+
+    return false;
+}
+
+void Image11::disassociateStorage()
+{
+    if (mRecoverFromStorage)
+    {
+        // Make the texturestorage release the Image11 too
+        mAssociatedStorage->disassociateImage(mAssociatedStorageLevel, mAssociatedStorageLayerTarget, this);
+
+        mRecoverFromStorage = false;
+        mAssociatedStorage = NULL;
+        mAssociatedStorageLevel = 0;
+        mAssociatedStorageLayerTarget = 0;
+    }
 }
 
 bool Image11::redefine(Renderer *renderer, GLenum target, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, bool forceRelease)
@@ -118,6 +207,11 @@
         mInternalFormat != internalformat ||
         forceRelease)
     {
+        // End the association with the TextureStorage, since that data will be out of date.
+        // Also reset mRecoveredFromStorageCount since this Image is getting completely redefined.
+        disassociateStorage();
+        mRecoveredFromStorageCount = 0;
+
         mRenderer = Renderer11::makeRenderer11(renderer);
 
         mWidth = width;
@@ -296,7 +390,7 @@
 
         // determine the offset coordinate into the destination buffer
         GLsizei rowOffset = gl::GetInternalFormatInfo(mActualFormat).pixelBytes * xoffset;
-        void *dataOffset = static_cast<unsigned char*>(mappedImage.pData) + mappedImage.RowPitch * yoffset + rowOffset + zoffset * mappedImage.DepthPitch;
+        uint8_t *dataOffset = static_cast<uint8_t*>(mappedImage.pData) + mappedImage.RowPitch * yoffset + rowOffset + zoffset * mappedImage.DepthPitch;
 
         const gl::InternalFormat &formatInfo = gl::GetInternalFormatInfo(mInternalFormat);
 
@@ -313,6 +407,11 @@
     return mStagingTexture;
 }
 
+void Image11::releaseStagingTexture()
+{
+    SafeRelease(mStagingTexture);
+}
+
 unsigned int Image11::getStagingSubresource()
 {
     createStagingTexture();
@@ -434,6 +533,9 @@
 {
     createStagingTexture();
 
+    // We must recover from the TextureStorage if necessary, even for D3D11_MAP_WRITE.
+    recoverFromAssociatedStorage();
+
     HRESULT result = E_FAIL;
 
     if (mStagingTexture)
diff --git a/src/libGLESv2/renderer/d3d/d3d11/Image11.h b/src/libGLESv2/renderer/d3d/d3d11/Image11.h
index 7d873a2..a76a61f 100644
--- a/src/libGLESv2/renderer/d3d/d3d11/Image11.h
+++ b/src/libGLESv2/renderer/d3d/d3d11/Image11.h
@@ -23,8 +23,7 @@
 {
 class Renderer;
 class Renderer11;
-class TextureStorageInterface2D;
-class TextureStorageInterfaceCube;
+class TextureStorage11;
 
 class Image11 : public ImageD3D
 {
@@ -38,10 +37,10 @@
 
     virtual bool isDirty() const;
 
-    virtual bool copyToStorage(TextureStorageInterface2D *storage, int level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height);
-    virtual bool copyToStorage(TextureStorageInterfaceCube *storage, int face, int level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height);
-    virtual bool copyToStorage(TextureStorageInterface3D *storage, int level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth);
-    virtual bool copyToStorage(TextureStorageInterface2DArray *storage, int level, GLint xoffset, GLint yoffset, GLint arrayLayer, GLsizei width, GLsizei height);
+    virtual bool copyToStorage2D(TextureStorage *storage, int level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height);
+    virtual bool copyToStorageCube(TextureStorage *storage, int face, int level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height);
+    virtual bool copyToStorage3D(TextureStorage *storage, int level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth);
+    virtual bool copyToStorage2DArray(TextureStorage *storage, int level, GLint xoffset, GLint yoffset, GLint arrayLayer, GLsizei width, GLsizei height);
 
     virtual bool redefine(Renderer *renderer, GLenum target, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, bool forceRelease);
 
@@ -54,6 +53,10 @@
 
     virtual void copy(GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height, gl::Framebuffer *source);
 
+    bool recoverFromAssociatedStorage();
+    bool isAssociatedStorageValid(TextureStorage11* textureStorage) const;
+    void disassociateStorage();
+
   protected:
     HRESULT map(D3D11_MAP mapType, D3D11_MAPPED_SUBRESOURCE *map);
     void unmap();
@@ -61,15 +64,24 @@
   private:
     DISALLOW_COPY_AND_ASSIGN(Image11);
 
+    bool copyToStorageImpl(TextureStorage11 *storage11, int level, int layerTarget, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height);
+
     ID3D11Resource *getStagingTexture();
     unsigned int getStagingSubresource();
     void createStagingTexture();
+    void releaseStagingTexture();
 
     Renderer11 *mRenderer;
 
     DXGI_FORMAT mDXGIFormat;
     ID3D11Resource *mStagingTexture;
     unsigned int mStagingSubresource;
+
+    bool mRecoverFromStorage;
+    TextureStorage11 *mAssociatedStorage;
+    int mAssociatedStorageLevel;
+    int mAssociatedStorageLayerTarget;
+    unsigned int mRecoveredFromStorageCount;
 };
 
 }
diff --git a/src/libGLESv2/renderer/d3d/d3d11/IndexBuffer11.cpp b/src/libGLESv2/renderer/d3d/d3d11/IndexBuffer11.cpp
index 03e4e66..9a61182 100644
--- a/src/libGLESv2/renderer/d3d/d3d11/IndexBuffer11.cpp
+++ b/src/libGLESv2/renderer/d3d/d3d11/IndexBuffer11.cpp
@@ -1,4 +1,3 @@
-#include "precompiled.h"
 //
 // Copyright (c) 2012 The ANGLE Project Authors. All rights reserved.
 // Use of this source code is governed by a BSD-style license that can be
@@ -25,7 +24,7 @@
     SafeRelease(mBuffer);
 }
 
-bool IndexBuffer11::initialize(unsigned int bufferSize, GLenum indexType, bool dynamic)
+gl::Error IndexBuffer11::initialize(unsigned int bufferSize, GLenum indexType, bool dynamic)
 {
     SafeRelease(mBuffer);
 
@@ -46,7 +45,7 @@
         HRESULT result = dxDevice->CreateBuffer(&bufferDesc, NULL, &mBuffer);
         if (FAILED(result))
         {
-            return false;
+            return gl::Error(GL_OUT_OF_MEMORY, "Failed to allocate internal index buffer of size, %lu.", bufferSize);
         }
     }
 
@@ -54,7 +53,7 @@
     mIndexType = indexType;
     mDynamicUsage = dynamic;
 
-    return true;
+    return gl::Error(GL_NO_ERROR);
 }
 
 IndexBuffer11 *IndexBuffer11::makeIndexBuffer11(IndexBuffer *indexBuffer)
@@ -63,50 +62,42 @@
     return static_cast<IndexBuffer11*>(indexBuffer);
 }
 
-bool IndexBuffer11::mapBuffer(unsigned int offset, unsigned int size, void** outMappedMemory)
+gl::Error IndexBuffer11::mapBuffer(unsigned int offset, unsigned int size, void** outMappedMemory)
 {
-    if (mBuffer)
+    if (!mBuffer)
     {
-        // Check for integer overflows and out-out-bounds map requests
-        if (offset + size < offset || offset + size > mBufferSize)
-        {
-            ERR("Index buffer map range is not inside the buffer.");
-            return false;
-        }
-
-        ID3D11DeviceContext *dxContext = mRenderer->getDeviceContext();
-
-        D3D11_MAPPED_SUBRESOURCE mappedResource;
-        HRESULT result = dxContext->Map(mBuffer, 0, D3D11_MAP_WRITE_NO_OVERWRITE, 0, &mappedResource);
-        if (FAILED(result))
-        {
-            ERR("Index buffer map failed with error 0x%08x", result);
-            return false;
-        }
-
-        *outMappedMemory = reinterpret_cast<char*>(mappedResource.pData) + offset;
-        return true;
+        return gl::Error(GL_OUT_OF_MEMORY, "Internal index buffer is not initialized.");
     }
-    else
+
+    // Check for integer overflows and out-out-bounds map requests
+    if (offset + size < offset || offset + size > mBufferSize)
     {
-        ERR("Index buffer not initialized.");
-        return false;
+        return gl::Error(GL_OUT_OF_MEMORY, "Index buffer map range is not inside the buffer.");
     }
+
+    ID3D11DeviceContext *dxContext = mRenderer->getDeviceContext();
+
+    D3D11_MAPPED_SUBRESOURCE mappedResource;
+    HRESULT result = dxContext->Map(mBuffer, 0, D3D11_MAP_WRITE_NO_OVERWRITE, 0, &mappedResource);
+    if (FAILED(result))
+    {
+        return gl::Error(GL_OUT_OF_MEMORY, "Failed to map internal index buffer, HRESULT: 0x%08x.", result);
+    }
+
+    *outMappedMemory = reinterpret_cast<char*>(mappedResource.pData) + offset;
+    return gl::Error(GL_NO_ERROR);
 }
 
-bool IndexBuffer11::unmapBuffer()
+gl::Error IndexBuffer11::unmapBuffer()
 {
-    if (mBuffer)
+    if (!mBuffer)
     {
-        ID3D11DeviceContext *dxContext = mRenderer->getDeviceContext();
-        dxContext->Unmap(mBuffer, 0);
-        return true;
+        return gl::Error(GL_OUT_OF_MEMORY, "Internal index buffer is not initialized.");
     }
-    else
-    {
-        ERR("Index buffer not initialized.");
-        return false;
-    }
+
+    ID3D11DeviceContext *dxContext = mRenderer->getDeviceContext();
+    dxContext->Unmap(mBuffer, 0);
+    return gl::Error(GL_NO_ERROR);
 }
 
 GLenum IndexBuffer11::getIndexType() const
@@ -119,7 +110,7 @@
     return mBufferSize;
 }
 
-bool IndexBuffer11::setSize(unsigned int bufferSize, GLenum indexType)
+gl::Error IndexBuffer11::setSize(unsigned int bufferSize, GLenum indexType)
 {
     if (bufferSize > mBufferSize || indexType != mIndexType)
     {
@@ -127,33 +118,29 @@
     }
     else
     {
-        return true;
+        return gl::Error(GL_NO_ERROR);
     }
 }
 
-bool IndexBuffer11::discard()
+gl::Error IndexBuffer11::discard()
 {
-    if (mBuffer)
+    if (!mBuffer)
     {
-        ID3D11DeviceContext *dxContext = mRenderer->getDeviceContext();
-
-        D3D11_MAPPED_SUBRESOURCE mappedResource;
-        HRESULT result = dxContext->Map(mBuffer, 0, D3D11_MAP_WRITE_DISCARD, 0, &mappedResource);
-        if (FAILED(result))
-        {
-            ERR("Index buffer map failed with error 0x%08x", result);
-            return false;
-        }
-
-        dxContext->Unmap(mBuffer, 0);
-
-        return true;
+        return gl::Error(GL_OUT_OF_MEMORY, "Internal index buffer is not initialized.");
     }
-    else
+
+    ID3D11DeviceContext *dxContext = mRenderer->getDeviceContext();
+
+    D3D11_MAPPED_SUBRESOURCE mappedResource;
+    HRESULT result = dxContext->Map(mBuffer, 0, D3D11_MAP_WRITE_DISCARD, 0, &mappedResource);
+    if (FAILED(result))
     {
-        ERR("Index buffer not initialized.");
-        return false;
+        return gl::Error(GL_OUT_OF_MEMORY, "Failed to map internal index buffer, HRESULT: 0x%08x.", result);
     }
+
+    dxContext->Unmap(mBuffer, 0);
+
+    return gl::Error(GL_NO_ERROR);
 }
 
 DXGI_FORMAT IndexBuffer11::getIndexFormat() const
@@ -172,4 +159,4 @@
     return mBuffer;
 }
 
-}
\ No newline at end of file
+}
diff --git a/src/libGLESv2/renderer/d3d/d3d11/IndexBuffer11.h b/src/libGLESv2/renderer/d3d/d3d11/IndexBuffer11.h
index e821b7f..f7c2b38 100644
--- a/src/libGLESv2/renderer/d3d/d3d11/IndexBuffer11.h
+++ b/src/libGLESv2/renderer/d3d/d3d11/IndexBuffer11.h
@@ -21,18 +21,18 @@
     explicit IndexBuffer11(Renderer11 *const renderer);
     virtual ~IndexBuffer11();
 
-    virtual bool initialize(unsigned int bufferSize, GLenum indexType, bool dynamic);
+    virtual gl::Error initialize(unsigned int bufferSize, GLenum indexType, bool dynamic);
 
     static IndexBuffer11 *makeIndexBuffer11(IndexBuffer *indexBuffer);
 
-    virtual bool mapBuffer(unsigned int offset, unsigned int size, void** outMappedMemory);
-    virtual bool unmapBuffer();
+    virtual gl::Error mapBuffer(unsigned int offset, unsigned int size, void** outMappedMemory);
+    virtual gl::Error unmapBuffer();
 
     virtual GLenum getIndexType() const;
     virtual unsigned int getBufferSize() const;
-    virtual bool setSize(unsigned int bufferSize, GLenum indexType);
+    virtual gl::Error setSize(unsigned int bufferSize, GLenum indexType);
 
-    virtual bool discard();
+    virtual gl::Error discard();
 
     DXGI_FORMAT getIndexFormat() const;
     ID3D11Buffer *getBuffer() const;
diff --git a/src/libGLESv2/renderer/d3d/d3d11/InputLayoutCache.cpp b/src/libGLESv2/renderer/d3d/d3d11/InputLayoutCache.cpp
index 2b9a7e5..b006c04 100644
--- a/src/libGLESv2/renderer/d3d/d3d11/InputLayoutCache.cpp
+++ b/src/libGLESv2/renderer/d3d/d3d11/InputLayoutCache.cpp
@@ -1,4 +1,3 @@
-#include "precompiled.h"
 //
 // Copyright (c) 2012 The ANGLE Project Authors. All rights reserved.
 // Use of this source code is governed by a BSD-style license that can be
@@ -12,10 +11,10 @@
 #include "libGLESv2/renderer/d3d/d3d11/VertexBuffer11.h"
 #include "libGLESv2/renderer/d3d/d3d11/Buffer11.h"
 #include "libGLESv2/renderer/d3d/d3d11/ShaderExecutable11.h"
+#include "libGLESv2/renderer/d3d/d3d11/formatutils11.h"
+#include "libGLESv2/renderer/d3d/VertexDataManager.h"
 #include "libGLESv2/ProgramBinary.h"
 #include "libGLESv2/VertexAttribute.h"
-#include "libGLESv2/renderer/d3d/VertexDataManager.h"
-#include "libGLESv2/renderer/d3d/d3d11/formatutils11.h"
 
 #include "third_party/murmurhash/MurmurHash3.h"
 
@@ -86,16 +85,15 @@
     }
 }
 
-GLenum InputLayoutCache::applyVertexBuffers(TranslatedAttribute attributes[gl::MAX_VERTEX_ATTRIBS],
-                                            gl::ProgramBinary *programBinary)
+gl::Error InputLayoutCache::applyVertexBuffers(TranslatedAttribute attributes[gl::MAX_VERTEX_ATTRIBS],
+                                               gl::ProgramBinary *programBinary)
 {
     int sortedSemanticIndices[gl::MAX_VERTEX_ATTRIBS];
     programBinary->sortAttributesByLayout(attributes, sortedSemanticIndices);
 
     if (!mDevice || !mDeviceContext)
     {
-        ERR("InputLayoutCache is not initialized.");
-        return GL_INVALID_OPERATION;
+        return gl::Error(GL_OUT_OF_MEMORY, "Internal input layout cache is not initialized.");
     }
 
     InputLayoutKey ilKey = { 0 };
@@ -150,8 +148,7 @@
         HRESULT result = mDevice->CreateInputLayout(descs, ilKey.elementCount, shader->getFunction(), shader->getLength(), &inputLayout);
         if (FAILED(result))
         {
-            ERR("Failed to crate input layout, result: 0x%08x", result);
-            return GL_INVALID_OPERATION;
+            return gl::Error(GL_OUT_OF_MEMORY, "Failed to create internal input layout, HRESULT: 0x%08x", result);
         }
 
         if (mInputLayoutMap.size() >= kMaxInputLayouts)
@@ -223,7 +220,7 @@
                                            mCurrentVertexStrides + minDiff, mCurrentVertexOffsets + minDiff);
     }
 
-    return GL_NO_ERROR;
+    return gl::Error(GL_NO_ERROR);
 }
 
 std::size_t InputLayoutCache::hashInputLayout(const InputLayoutKey &inputLayout)
diff --git a/src/libGLESv2/renderer/d3d/d3d11/InputLayoutCache.h b/src/libGLESv2/renderer/d3d/d3d11/InputLayoutCache.h
index 5d0ac60..cc71ac3 100644
--- a/src/libGLESv2/renderer/d3d/d3d11/InputLayoutCache.h
+++ b/src/libGLESv2/renderer/d3d/d3d11/InputLayoutCache.h
@@ -11,8 +11,14 @@
 #define LIBGLESV2_RENDERER_INPUTLAYOUTCACHE_H_
 
 #include "libGLESv2/Constants.h"
+#include "libGLESv2/Error.h"
 #include "common/angleutils.h"
 
+#include <GLES2/gl2.h>
+
+#include <cstddef>
+#include <unordered_map>
+
 namespace gl
 {
 class ProgramBinary;
@@ -32,8 +38,8 @@
     void clear();
     void markDirty();
 
-    GLenum applyVertexBuffers(TranslatedAttribute attributes[gl::MAX_VERTEX_ATTRIBS],
-                              gl::ProgramBinary *programBinary);
+    gl::Error applyVertexBuffers(TranslatedAttribute attributes[gl::MAX_VERTEX_ATTRIBS],
+                                 gl::ProgramBinary *programBinary);
 
   private:
     DISALLOW_COPY_AND_ASSIGN(InputLayoutCache);
diff --git a/src/libGLESv2/renderer/d3d/d3d11/PixelTransfer11.cpp b/src/libGLESv2/renderer/d3d/d3d11/PixelTransfer11.cpp
index ad04c4f..f54bacc 100644
--- a/src/libGLESv2/renderer/d3d/d3d11/PixelTransfer11.cpp
+++ b/src/libGLESv2/renderer/d3d/d3d11/PixelTransfer11.cpp
@@ -1,4 +1,3 @@
-#include "precompiled.h"
 //
 // 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
@@ -11,15 +10,15 @@
 //
 
 #include "libGLESv2/renderer/d3d/d3d11/PixelTransfer11.h"
-#include "libGLESv2/formatutils.h"
-#include "libGLESv2/Texture.h"
-#include "libGLESv2/Buffer.h"
 #include "libGLESv2/renderer/d3d/d3d11/Renderer11.h"
 #include "libGLESv2/renderer/d3d/d3d11/renderer11_utils.h"
 #include "libGLESv2/renderer/d3d/d3d11/formatutils11.h"
 #include "libGLESv2/renderer/d3d/d3d11/Buffer11.h"
 #include "libGLESv2/renderer/d3d/d3d11/TextureStorage11.h"
 #include "libGLESv2/renderer/d3d/d3d11/RenderTarget11.h"
+#include "libGLESv2/formatutils.h"
+#include "libGLESv2/Texture.h"
+#include "libGLESv2/Buffer.h"
 #include "libGLESv2/Context.h"
 
 // Precompiled shaders
diff --git a/src/libGLESv2/renderer/d3d/d3d11/PixelTransfer11.h b/src/libGLESv2/renderer/d3d/d3d11/PixelTransfer11.h
index 2e2fee8..ed1a3ae 100644
--- a/src/libGLESv2/renderer/d3d/d3d11/PixelTransfer11.h
+++ b/src/libGLESv2/renderer/d3d/d3d11/PixelTransfer11.h
@@ -13,6 +13,10 @@
 
 #include "common/platform.h"
 
+#include <GLES2/gl2.h>
+
+#include <map>
+
 namespace gl
 {
 
diff --git a/src/libGLESv2/renderer/d3d/d3d11/Query11.cpp b/src/libGLESv2/renderer/d3d/d3d11/Query11.cpp
index 17cf5ca..7109be3 100644
--- a/src/libGLESv2/renderer/d3d/d3d11/Query11.cpp
+++ b/src/libGLESv2/renderer/d3d/d3d11/Query11.cpp
@@ -1,4 +1,3 @@
-#include "precompiled.h"
 //
 // 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
@@ -12,27 +11,18 @@
 #include "libGLESv2/renderer/d3d/d3d11/renderer11_utils.h"
 #include "libGLESv2/main.h"
 
+#include <GLES2/gl2ext.h>
+
 namespace rx
 {
 
-static bool checkOcclusionQuery(ID3D11DeviceContext *context, ID3D11Query *query, UINT64 *numPixels)
+Query11::Query11(rx::Renderer11 *renderer, GLenum type)
+    : QueryImpl(type),
+      mResult(0),
+      mQueryFinished(false),
+      mRenderer(renderer),
+      mQuery(NULL)
 {
-    HRESULT result = context->GetData(query, numPixels, sizeof(UINT64), 0);
-    return (result == S_OK);
-}
-
-static bool checkStreamOutPrimitivesWritten(ID3D11DeviceContext *context, ID3D11Query *query, UINT64 *numPrimitives)
-{
-    D3D11_QUERY_DATA_SO_STATISTICS soStats = { 0 };
-    HRESULT result = context->GetData(query, &soStats, sizeof(D3D11_QUERY_DATA_SO_STATISTICS), 0);
-    *numPrimitives = soStats.NumPrimitivesWritten;
-    return (result == S_OK);
-}
-
-Query11::Query11(rx::Renderer11 *renderer, GLenum type) : QueryImpl(type)
-{
-    mRenderer = renderer;
-    mQuery = NULL;
 }
 
 Query11::~Query11()
@@ -40,7 +30,7 @@
     SafeRelease(mQuery);
 }
 
-void Query11::begin()
+gl::Error Query11::begin()
 {
     if (mQuery == NULL)
     {
@@ -48,69 +38,85 @@
         queryDesc.Query = gl_d3d11::ConvertQueryType(getType());
         queryDesc.MiscFlags = 0;
 
-        if (FAILED(mRenderer->getDevice()->CreateQuery(&queryDesc, &mQuery)))
+        HRESULT result = mRenderer->getDevice()->CreateQuery(&queryDesc, &mQuery);
+        if (FAILED(result))
         {
-            return gl::error(GL_OUT_OF_MEMORY);
+            return gl::Error(GL_OUT_OF_MEMORY, "Internal query creation failed, result: 0x%X.", result);
         }
     }
 
     mRenderer->getDeviceContext()->Begin(mQuery);
+    return gl::Error(GL_NO_ERROR);
 }
 
-void Query11::end()
+gl::Error Query11::end()
 {
     ASSERT(mQuery);
     mRenderer->getDeviceContext()->End(mQuery);
 
-    mStatus = GL_FALSE;
+    mQueryFinished = false;
     mResult = GL_FALSE;
+
+    return gl::Error(GL_NO_ERROR);
 }
 
-GLuint Query11::getResult()
+gl::Error Query11::getResult(GLuint *params)
 {
-    if (mQuery != NULL)
+    while (!mQueryFinished)
     {
-        while (!testQuery())
+        gl::Error error = testQuery();
+        if (error.isError())
+        {
+            return error;
+        }
+
+        if (!mQueryFinished)
         {
             Sleep(0);
-            // explicitly check for device loss, some drivers seem to return S_FALSE
-            // if the device is lost
-            if (mRenderer->testDeviceLost(true))
-            {
-                return gl::error(GL_OUT_OF_MEMORY, 0);
-            }
         }
     }
 
-    return mResult;
+    ASSERT(mQueryFinished);
+    *params = mResult;
+
+    return gl::Error(GL_NO_ERROR);
 }
 
-GLboolean Query11::isResultAvailable()
+gl::Error Query11::isResultAvailable(GLuint *available)
 {
-    if (mQuery != NULL)
+    gl::Error error = testQuery();
+    if (error.isError())
     {
-        testQuery();
+        return error;
     }
 
-    return mStatus;
+    *available = (mQueryFinished ? GL_TRUE : GL_FALSE);
+
+    return gl::Error(GL_NO_ERROR);
 }
 
-GLboolean Query11::testQuery()
+gl::Error Query11::testQuery()
 {
-    if (mQuery != NULL && mStatus != GL_TRUE)
+    if (!mQueryFinished)
     {
-        ID3D11DeviceContext *context = mRenderer->getDeviceContext();
+        ASSERT(mQuery);
 
-        bool queryFinished = false;
+        ID3D11DeviceContext *context = mRenderer->getDeviceContext();
         switch (getType())
         {
           case GL_ANY_SAMPLES_PASSED_EXT:
           case GL_ANY_SAMPLES_PASSED_CONSERVATIVE_EXT:
             {
                 UINT64 numPixels = 0;
-                queryFinished = checkOcclusionQuery(context, mQuery, &numPixels);
-                if (queryFinished)
+                HRESULT result = context->GetData(mQuery, &numPixels, sizeof(numPixels), 0);
+                if (FAILED(result))
                 {
+                    return gl::Error(GL_OUT_OF_MEMORY, "Failed to get the data of an internal query, result: 0x%X.", result);
+                }
+
+                if (result == S_OK)
+                {
+                    mQueryFinished = true;
                     mResult = (numPixels > 0) ? GL_TRUE : GL_FALSE;
                 }
             }
@@ -118,11 +124,17 @@
 
           case GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN:
             {
-                UINT64 numPrimitives = 0;
-                queryFinished = checkStreamOutPrimitivesWritten(context, mQuery, &numPrimitives);
-                if (queryFinished)
+                D3D11_QUERY_DATA_SO_STATISTICS soStats = { 0 };
+                HRESULT result = context->GetData(mQuery, &soStats, sizeof(soStats), 0);
+                if (FAILED(result))
                 {
-                    mResult = static_cast<GLuint>(numPrimitives);
+                    return gl::Error(GL_OUT_OF_MEMORY, "Failed to get the data of an internal query, result: 0x%X.", result);
+                }
+
+                if (result == S_OK)
+                {
+                    mQueryFinished = true;
+                    mResult = static_cast<GLuint>(soStats.NumPrimitivesWritten);
                 }
             }
             break;
@@ -132,24 +144,13 @@
             break;
         }
 
-        if (queryFinished)
+        if (!mQueryFinished && mRenderer->testDeviceLost(true))
         {
-            mStatus = GL_TRUE;
+            return gl::Error(GL_OUT_OF_MEMORY, "Failed to test get query result, device is lost.");
         }
-        else if (mRenderer->testDeviceLost(true))
-        {
-            return gl::error(GL_OUT_OF_MEMORY, GL_TRUE);
-        }
-
-        return mStatus;
     }
 
-    return GL_TRUE; // prevent blocking when query is null
-}
-
-bool Query11::isStarted() const
-{
-    return (mQuery != NULL);
+    return gl::Error(GL_NO_ERROR);
 }
 
 }
diff --git a/src/libGLESv2/renderer/d3d/d3d11/Query11.h b/src/libGLESv2/renderer/d3d/d3d11/Query11.h
index 7a3df46..822f254 100644
--- a/src/libGLESv2/renderer/d3d/d3d11/Query11.h
+++ b/src/libGLESv2/renderer/d3d/d3d11/Query11.h
@@ -21,16 +21,19 @@
     Query11(rx::Renderer11 *renderer, GLenum type);
     virtual ~Query11();
 
-    virtual void begin();
-    virtual void end();
-    virtual GLuint getResult();
-    virtual GLboolean isResultAvailable();
-    virtual bool isStarted() const;
+    virtual gl::Error begin();
+    virtual gl::Error end();
+    virtual gl::Error getResult(GLuint *params);
+    virtual gl::Error isResultAvailable(GLuint *available);
 
   private:
     DISALLOW_COPY_AND_ASSIGN(Query11);
 
-    GLboolean testQuery();
+    gl::Error testQuery();
+
+    GLuint mResult;
+
+    bool mQueryFinished;
 
     rx::Renderer11 *mRenderer;
     ID3D11Query *mQuery;
diff --git a/src/libGLESv2/renderer/d3d/d3d11/RenderStateCache.cpp b/src/libGLESv2/renderer/d3d/d3d11/RenderStateCache.cpp
index b185d97..71b931f 100644
--- a/src/libGLESv2/renderer/d3d/d3d11/RenderStateCache.cpp
+++ b/src/libGLESv2/renderer/d3d/d3d11/RenderStateCache.cpp
@@ -1,4 +1,3 @@
-#include "precompiled.h"
 //
 // Copyright (c) 2012-2014 The ANGLE Project Authors. All rights reserved.
 // Use of this source code is governed by a BSD-style license that can be
@@ -15,6 +14,7 @@
 #include "libGLESv2/FramebufferAttachment.h"
 
 #include "common/debug.h"
+
 #include "third_party/murmurhash/MurmurHash3.h"
 
 namespace rx
@@ -79,39 +79,37 @@
     return memcmp(&a, &b, sizeof(BlendStateKey)) == 0;
 }
 
-ID3D11BlendState *RenderStateCache::getBlendState(const gl::Framebuffer *framebuffer, const gl::BlendState &blendState)
+gl::Error RenderStateCache::getBlendState(const gl::Framebuffer *framebuffer, const gl::BlendState &blendState,
+                                          ID3D11BlendState **outBlendState)
 {
     if (!mDevice)
     {
-        ERR("RenderStateCache is not initialized.");
-        return NULL;
+        return gl::Error(GL_OUT_OF_MEMORY, "Internal error, RenderStateCache is not initialized.");
     }
 
     bool mrt = false;
 
+    const gl::ColorbufferInfo &colorbuffers = framebuffer->getColorbuffersForRender();
+
     BlendStateKey key = { 0 };
     key.blendState = blendState;
-    for (unsigned int i = 0; i < D3D11_SIMULTANEOUS_RENDER_TARGET_COUNT; i++)
+    for (size_t colorAttachment = 0; colorAttachment < colorbuffers.size(); ++colorAttachment)
     {
-        const gl::FramebufferAttachment *attachment = framebuffer->getColorbuffer(i);
+        const gl::FramebufferAttachment *attachment = colorbuffers[colorAttachment];
+
+        auto rtChannels = key.rtChannels[colorAttachment];
+
         if (attachment)
         {
-            if (i > 0)
+            if (colorAttachment > 0)
             {
                 mrt = true;
             }
 
-            key.rtChannels[i][0] = attachment->getRedSize()   > 0;
-            key.rtChannels[i][1] = attachment->getGreenSize() > 0;
-            key.rtChannels[i][2] = attachment->getBlueSize()  > 0;
-            key.rtChannels[i][3] = attachment->getAlphaSize() > 0;
-        }
-        else
-        {
-            key.rtChannels[i][0] = false;
-            key.rtChannels[i][1] = false;
-            key.rtChannels[i][2] = false;
-            key.rtChannels[i][3] = false;
+            rtChannels[0] = attachment->getRedSize()   > 0;
+            rtChannels[1] = attachment->getGreenSize() > 0;
+            rtChannels[2] = attachment->getBlueSize()  > 0;
+            rtChannels[3] = attachment->getAlphaSize() > 0;
         }
     }
 
@@ -120,7 +118,8 @@
     {
         BlendStateCounterPair &state = keyIter->second;
         state.second = mCounter++;
-        return state.first;
+        *outBlendState = state.first;
+        return gl::Error(GL_NO_ERROR);
     }
     else
     {
@@ -172,13 +171,13 @@
         HRESULT result = mDevice->CreateBlendState(&blendDesc, &dx11BlendState);
         if (FAILED(result) || !dx11BlendState)
         {
-            ERR("Unable to create a ID3D11BlendState, HRESULT: 0x%X.", result);
-            return NULL;
+            return gl::Error(GL_OUT_OF_MEMORY, "Unable to create a ID3D11BlendState, HRESULT: 0x%X.", result);
         }
 
         mBlendStateCache.insert(std::make_pair(key, std::make_pair(dx11BlendState, mCounter++)));
 
-        return dx11BlendState;
+        *outBlendState = dx11BlendState;
+        return gl::Error(GL_NO_ERROR);
     }
 }
 
@@ -196,12 +195,12 @@
     return memcmp(&a, &b, sizeof(RasterizerStateKey)) == 0;
 }
 
-ID3D11RasterizerState *RenderStateCache::getRasterizerState(const gl::RasterizerState &rasterState, bool scissorEnabled)
+gl::Error RenderStateCache::getRasterizerState(const gl::RasterizerState &rasterState, bool scissorEnabled,
+                                               ID3D11RasterizerState **outRasterizerState)
 {
     if (!mDevice)
     {
-        ERR("RenderStateCache is not initialized.");
-        return NULL;
+        return gl::Error(GL_OUT_OF_MEMORY, "Internal error, RenderStateCache is not initialized.");
     }
 
     RasterizerStateKey key = { 0 };
@@ -213,7 +212,8 @@
     {
         RasterizerStateCounterPair &state = keyIter->second;
         state.second = mCounter++;
-        return state.first;
+        *outRasterizerState = state.first;
+        return gl::Error(GL_NO_ERROR);
     }
     else
     {
@@ -267,13 +267,13 @@
         HRESULT result = mDevice->CreateRasterizerState(&rasterDesc, &dx11RasterizerState);
         if (FAILED(result) || !dx11RasterizerState)
         {
-            ERR("Unable to create a ID3D11RasterizerState, HRESULT: 0x%X.", result);
-            return NULL;
+            return gl::Error(GL_OUT_OF_MEMORY, "Unable to create a ID3D11RasterizerState, HRESULT: 0x%X.", result);
         }
 
         mRasterizerStateCache.insert(std::make_pair(key, std::make_pair(dx11RasterizerState, mCounter++)));
 
-        return dx11RasterizerState;
+        *outRasterizerState = dx11RasterizerState;
+        return gl::Error(GL_NO_ERROR);
     }
 }
 
@@ -291,12 +291,11 @@
     return memcmp(&a, &b, sizeof(gl::DepthStencilState)) == 0;
 }
 
-ID3D11DepthStencilState *RenderStateCache::getDepthStencilState(const gl::DepthStencilState &dsState)
+gl::Error RenderStateCache::getDepthStencilState(const gl::DepthStencilState &dsState, ID3D11DepthStencilState **outDSState)
 {
     if (!mDevice)
     {
-        ERR("RenderStateCache is not initialized.");
-        return NULL;
+        return gl::Error(GL_OUT_OF_MEMORY, "Internal error, RenderStateCache is not initialized.");
     }
 
     DepthStencilStateMap::iterator keyIter = mDepthStencilStateCache.find(dsState);
@@ -304,7 +303,8 @@
     {
         DepthStencilStateCounterPair &state = keyIter->second;
         state.second = mCounter++;
-        return state.first;
+        *outDSState = state.first;
+        return gl::Error(GL_NO_ERROR);
     }
     else
     {
@@ -345,13 +345,13 @@
         HRESULT result = mDevice->CreateDepthStencilState(&dsDesc, &dx11DepthStencilState);
         if (FAILED(result) || !dx11DepthStencilState)
         {
-            ERR("Unable to create a ID3D11DepthStencilState, HRESULT: 0x%X.", result);
-            return NULL;
+            return gl::Error(GL_OUT_OF_MEMORY, "Unable to create a ID3D11DepthStencilState, HRESULT: 0x%X.", result);
         }
 
         mDepthStencilStateCache.insert(std::make_pair(dsState, std::make_pair(dx11DepthStencilState, mCounter++)));
 
-        return dx11DepthStencilState;
+        *outDSState = dx11DepthStencilState;
+        return gl::Error(GL_NO_ERROR);
     }
 }
 
@@ -369,12 +369,11 @@
     return memcmp(&a, &b, sizeof(gl::SamplerState)) == 0;
 }
 
-ID3D11SamplerState *RenderStateCache::getSamplerState(const gl::SamplerState &samplerState)
+gl::Error RenderStateCache::getSamplerState(const gl::SamplerState &samplerState, ID3D11SamplerState **outSamplerState)
 {
     if (!mDevice)
     {
-        ERR("RenderStateCache is not initialized.");
-        return NULL;
+        return gl::Error(GL_OUT_OF_MEMORY, "Internal error, RenderStateCache is not initialized.");
     }
 
     SamplerStateMap::iterator keyIter = mSamplerStateCache.find(samplerState);
@@ -382,7 +381,8 @@
     {
         SamplerStateCounterPair &state = keyIter->second;
         state.second = mCounter++;
-        return state.first;
+        *outSamplerState = state.first;
+        return gl::Error(GL_NO_ERROR);
     }
     else
     {
@@ -423,13 +423,13 @@
         HRESULT result = mDevice->CreateSamplerState(&samplerDesc, &dx11SamplerState);
         if (FAILED(result) || !dx11SamplerState)
         {
-            ERR("Unable to create a ID3D11DepthStencilState, HRESULT: 0x%X.", result);
-            return NULL;
+            return gl::Error(GL_OUT_OF_MEMORY, "Unable to create a ID3D11SamplerState, HRESULT: 0x%X.", result);
         }
 
         mSamplerStateCache.insert(std::make_pair(samplerState, std::make_pair(dx11SamplerState, mCounter++)));
 
-        return dx11SamplerState;
+        *outSamplerState = dx11SamplerState;
+        return gl::Error(GL_NO_ERROR);
     }
 }
 
diff --git a/src/libGLESv2/renderer/d3d/d3d11/RenderStateCache.h b/src/libGLESv2/renderer/d3d/d3d11/RenderStateCache.h
index e6380fb..d5471a3 100644
--- a/src/libGLESv2/renderer/d3d/d3d11/RenderStateCache.h
+++ b/src/libGLESv2/renderer/d3d/d3d11/RenderStateCache.h
@@ -11,8 +11,11 @@
 #define LIBGLESV2_RENDERER_RENDERSTATECACHE_H_
 
 #include "libGLESv2/angletypes.h"
+#include "libGLESv2/Error.h"
 #include "common/angleutils.h"
 
+#include <unordered_map>
+
 namespace gl
 {
 class Framebuffer;
@@ -31,10 +34,10 @@
     void initialize(ID3D11Device *device);
     void clear();
 
-    ID3D11BlendState *getBlendState(const gl::Framebuffer *framebuffer, const gl::BlendState &blendState);
-    ID3D11RasterizerState *getRasterizerState(const gl::RasterizerState &rasterState, bool scissorEnabled);
-    ID3D11DepthStencilState *getDepthStencilState(const gl::DepthStencilState &dsState);
-    ID3D11SamplerState *getSamplerState(const gl::SamplerState &samplerState);
+    gl::Error getBlendState(const gl::Framebuffer *framebuffer, const gl::BlendState &blendState, ID3D11BlendState **outBlendState);
+    gl::Error getRasterizerState(const gl::RasterizerState &rasterState, bool scissorEnabled, ID3D11RasterizerState **outRasterizerState);
+    gl::Error getDepthStencilState(const gl::DepthStencilState &dsState, ID3D11DepthStencilState **outDSState);
+    gl::Error getSamplerState(const gl::SamplerState &samplerState, ID3D11SamplerState **outSamplerState);
 
   private:
     DISALLOW_COPY_AND_ASSIGN(RenderStateCache);
diff --git a/src/libGLESv2/renderer/d3d/d3d11/RenderTarget11.cpp b/src/libGLESv2/renderer/d3d/d3d11/RenderTarget11.cpp
index a068ed0..3041f21 100644
--- a/src/libGLESv2/renderer/d3d/d3d11/RenderTarget11.cpp
+++ b/src/libGLESv2/renderer/d3d/d3d11/RenderTarget11.cpp
@@ -1,4 +1,3 @@
-#include "precompiled.h"
 //
 // Copyright (c) 2012 The ANGLE Project Authors. All rights reserved.
 // Use of this source code is governed by a BSD-style license that can be
@@ -10,7 +9,6 @@
 
 #include "libGLESv2/renderer/d3d/d3d11/RenderTarget11.h"
 #include "libGLESv2/renderer/d3d/d3d11/Renderer11.h"
-
 #include "libGLESv2/renderer/d3d/d3d11/renderer11_utils.h"
 #include "libGLESv2/renderer/d3d/d3d11/formatutils11.h"
 #include "libGLESv2/main.h"
diff --git a/src/libGLESv2/renderer/d3d/d3d11/RenderTarget11.h b/src/libGLESv2/renderer/d3d/d3d11/RenderTarget11.h
index ba9f76e..8218295 100644
--- a/src/libGLESv2/renderer/d3d/d3d11/RenderTarget11.h
+++ b/src/libGLESv2/renderer/d3d/d3d11/RenderTarget11.h
@@ -51,4 +51,4 @@
 
 }
 
-#endif LIBGLESV2_RENDERER_RENDERTARGET11_H_
+#endif // LIBGLESV2_RENDERER_RENDERTARGET11_H_
diff --git a/src/libGLESv2/renderer/d3d/d3d11/Renderer11.cpp b/src/libGLESv2/renderer/d3d/d3d11/Renderer11.cpp
index 8baac11..c93def8 100644
--- a/src/libGLESv2/renderer/d3d/d3d11/Renderer11.cpp
+++ b/src/libGLESv2/renderer/d3d/d3d11/Renderer11.cpp
@@ -1,4 +1,3 @@
-#include "precompiled.h"
 //
 // Copyright (c) 2012-2014 The ANGLE Project Authors. All rights reserved.
 // Use of this source code is governed by a BSD-style license that can be
@@ -8,12 +7,14 @@
 // Renderer11.cpp: Implements a back-end specific class for the D3D11 renderer.
 
 #include "libGLESv2/main.h"
-#include "common/utilities.h"
 #include "libGLESv2/Buffer.h"
 #include "libGLESv2/FramebufferAttachment.h"
 #include "libGLESv2/ProgramBinary.h"
 #include "libGLESv2/Framebuffer.h"
+#include "libGLESv2/renderer/d3d/ProgramD3D.h"
+#include "libGLESv2/renderer/d3d/ShaderD3D.h"
 #include "libGLESv2/renderer/d3d/TextureD3D.h"
+#include "libGLESv2/renderer/d3d/TransformFeedbackD3D.h"
 #include "libGLESv2/renderer/d3d/d3d11/Renderer11.h"
 #include "libGLESv2/renderer/d3d/d3d11/RenderTarget11.h"
 #include "libGLESv2/renderer/d3d/d3d11/renderer11_utils.h"
@@ -34,8 +35,15 @@
 #include "libGLESv2/renderer/d3d/d3d11/PixelTransfer11.h"
 #include "libGLESv2/renderer/d3d/d3d11/VertexArray11.h"
 #include "libGLESv2/renderer/d3d/d3d11/Buffer11.h"
+
 #include "libEGL/Display.h"
 
+#include "common/utilities.h"
+
+#include <EGL/eglext.h>
+
+#include <sstream>
+
 // 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
@@ -307,6 +315,17 @@
     ASSERT(!mPixelTransfer);
     mPixelTransfer = new PixelTransfer11(this);
 
+    const gl::Caps &rendererCaps = getRendererCaps();
+
+    mForceSetVertexSamplerStates.resize(rendererCaps.maxVertexTextureImageUnits);
+    mCurVertexSamplerStates.resize(rendererCaps.maxVertexTextureImageUnits);
+
+    mForceSetPixelSamplerStates.resize(rendererCaps.maxTextureImageUnits);
+    mCurPixelSamplerStates.resize(rendererCaps.maxTextureImageUnits);
+
+    mCurVertexSRVs.resize(rendererCaps.maxVertexTextureImageUnits);
+    mCurPixelSRVs.resize(rendererCaps.maxTextureImageUnits);
+
     markAllStateDirty();
 }
 
@@ -316,7 +335,7 @@
     unsigned int numDepthFormats = ArraySize(DepthStencilFormats);
     (*configDescList) = new ConfigDesc[numRenderFormats * numDepthFormats];
     int numConfigs = 0;
-    
+
     for (unsigned int formatIndex = 0; formatIndex < numRenderFormats; formatIndex++)
     {
         const d3d11::DXGIFormat &renderTargetFormatInfo = d3d11::GetDXGIFormatInfo(RenderTargetFormats[formatIndex]);
@@ -398,10 +417,10 @@
 {
     if (texture)
     {
-        TextureStorageInterface *texStorage = texture->getNativeTexture();
+        TextureStorage *texStorage = texture->getNativeTexture();
         if (texStorage)
         {
-            TextureStorage11 *storage11 = TextureStorage11::makeTextureStorage11(texStorage->getStorageInstance());
+            TextureStorage11 *storage11 = TextureStorage11::makeTextureStorage11(texStorage);
 
             storage11->generateSwizzles(texture->getSamplerState().swizzleRed,
                                         texture->getSamplerState().swizzleGreen,
@@ -415,20 +434,17 @@
 {
     if (type == gl::SAMPLER_PIXEL)
     {
-        if (index < 0 || index >= gl::MAX_TEXTURE_IMAGE_UNITS)
-        {
-            ERR("Pixel shader sampler index %i is not valid.", index);
-            return;
-        }
+        ASSERT(static_cast<unsigned int>(index) < getRendererCaps().maxTextureImageUnits);
 
         if (mForceSetPixelSamplerStates[index] || memcmp(&samplerState, &mCurPixelSamplerStates[index], sizeof(gl::SamplerState)) != 0)
         {
-            ID3D11SamplerState *dxSamplerState = mStateCache.getSamplerState(samplerState);
-
-            if (!dxSamplerState)
+            ID3D11SamplerState *dxSamplerState = NULL;
+            gl::Error error = mStateCache.getSamplerState(samplerState, &dxSamplerState);
+            if (error.isError())
             {
                 ERR("NULL sampler state returned by RenderStateCache::getSamplerState, setting the default"
                     "sampler state for pixel shaders at slot %i.", index);
+                dxSamplerState = NULL;
             }
 
             mDeviceContext->PSSetSamplers(index, 1, &dxSamplerState);
@@ -440,20 +456,17 @@
     }
     else if (type == gl::SAMPLER_VERTEX)
     {
-        if (index < 0 || index >= (int)getMaxVertexTextureImageUnits())
-        {
-            ERR("Vertex shader sampler index %i is not valid.", index);
-            return;
-        }
+        ASSERT(static_cast<unsigned int>(index) < getRendererCaps().maxVertexTextureImageUnits);
 
         if (mForceSetVertexSamplerStates[index] || memcmp(&samplerState, &mCurVertexSamplerStates[index], sizeof(gl::SamplerState)) != 0)
         {
-            ID3D11SamplerState *dxSamplerState = mStateCache.getSamplerState(samplerState);
-
-            if (!dxSamplerState)
+            ID3D11SamplerState *dxSamplerState = NULL;
+            gl::Error error = mStateCache.getSamplerState(samplerState, &dxSamplerState);
+            if (error.isError())
             {
                 ERR("NULL sampler state returned by RenderStateCache::getSamplerState, setting the default"
                     "sampler state for vertex shaders at slot %i.", index);
+                dxSamplerState = NULL;
             }
 
             mDeviceContext->VSSetSamplers(index, 1, &dxSamplerState);
@@ -473,12 +486,12 @@
 
     if (texture)
     {
-        TextureImpl* textureImpl = texture->getImplementation();
+        TextureD3D* textureImpl = TextureD3D::makeTextureD3D(texture->getImplementation());
 
-        TextureStorageInterface *texStorage = textureImpl->getNativeTexture();
+        TextureStorage *texStorage = textureImpl->getNativeTexture();
         if (texStorage)
         {
-            TextureStorage11 *storage11 = TextureStorage11::makeTextureStorage11(texStorage->getStorageInstance());
+            TextureStorage11 *storage11 = TextureStorage11::makeTextureStorage11(texStorage);
             gl::SamplerState samplerState;
             texture->getSamplerStateWithNativeOffset(&samplerState);
             textureSRV = storage11->getSRV(samplerState);
@@ -494,11 +507,7 @@
 
     if (type == gl::SAMPLER_PIXEL)
     {
-        if (index < 0 || index >= gl::MAX_TEXTURE_IMAGE_UNITS)
-        {
-            ERR("Pixel shader sampler index %i is not valid.", index);
-            return;
-        }
+        ASSERT(static_cast<unsigned int>(index) < getRendererCaps().maxTextureImageUnits);
 
         if (forceSetTexture || mCurPixelSRVs[index] != textureSRV)
         {
@@ -509,11 +518,7 @@
     }
     else if (type == gl::SAMPLER_VERTEX)
     {
-        if (index < 0 || index >= (int)getMaxVertexTextureImageUnits())
-        {
-            ERR("Vertex shader sampler index %i is not valid.", index);
-            return;
-        }
+        ASSERT(static_cast<unsigned int>(index) < getRendererCaps().maxVertexTextureImageUnits);
 
         if (forceSetTexture || mCurVertexSRVs[index] != textureSRV)
         {
@@ -578,11 +583,13 @@
 {
     if (mForceSetRasterState || memcmp(&rasterState, &mCurRasterState, sizeof(gl::RasterizerState)) != 0)
     {
-        ID3D11RasterizerState *dxRasterState = mStateCache.getRasterizerState(rasterState, mScissorEnabled);
-        if (!dxRasterState)
+        ID3D11RasterizerState *dxRasterState = NULL;
+        gl::Error error = mStateCache.getRasterizerState(rasterState, mScissorEnabled, &dxRasterState);
+        if (error.isError())
         {
             ERR("NULL rasterizer state returned by RenderStateCache::getRasterizerState, setting the default"
                 "rasterizer state.");
+            dxRasterState = NULL;
         }
 
         mDeviceContext->RSSetState(dxRasterState);
@@ -601,11 +608,13 @@
         memcmp(&blendColor, &mCurBlendColor, sizeof(gl::ColorF)) != 0 ||
         sampleMask != mCurSampleMask)
     {
-        ID3D11BlendState *dxBlendState = mStateCache.getBlendState(framebuffer, blendState);
-        if (!dxBlendState)
+        ID3D11BlendState *dxBlendState = NULL;
+        gl::Error error = mStateCache.getBlendState(framebuffer, blendState, &dxBlendState);
+        if (error.isError())
         {
             ERR("NULL blend state returned by RenderStateCache::getBlendState, setting the default "
                 "blend state.");
+            dxBlendState = NULL;
         }
 
         float blendColors[4] = {0.0f};
@@ -646,11 +655,13 @@
         ASSERT(stencilRef == stencilBackRef);
         ASSERT(depthStencilState.stencilMask == depthStencilState.stencilBackMask);
 
-        ID3D11DepthStencilState *dxDepthStencilState = mStateCache.getDepthStencilState(depthStencilState);
-        if (!dxDepthStencilState)
+        ID3D11DepthStencilState *dxDepthStencilState = NULL;
+        gl::Error error = mStateCache.getDepthStencilState(depthStencilState, &dxDepthStencilState);
+        if (error.isError())
         {
             ERR("NULL depth stencil state returned by RenderStateCache::getDepthStencilState, "
                 "setting the default depth stencil state.");
+            dxDepthStencilState = NULL;
         }
 
         // Max D3D11 stencil reference value is 0xFF, corresponding to the max 8 bits in a stencil buffer
@@ -697,7 +708,7 @@
     mForceSetScissor = false;
 }
 
-bool Renderer11::setViewport(const gl::Rectangle &viewport, float zNear, float zFar, GLenum drawMode, GLenum frontFace, 
+void Renderer11::setViewport(const gl::Rectangle &viewport, float zNear, float zFar, GLenum drawMode, GLenum frontFace,
                              bool ignoreViewport)
 {
     gl::Rectangle actualViewport = viewport;
@@ -724,11 +735,6 @@
     dxViewport.MinDepth = actualZNear;
     dxViewport.MaxDepth = actualZFar;
 
-    if (dxViewport.Width <= 0 || dxViewport.Height <= 0)
-    {
-        return false;   // Nothing to render
-    }
-
     bool viewportChanged = mForceSetViewport || memcmp(&actualViewport, &mCurViewport, sizeof(gl::Rectangle)) != 0 ||
                            actualZNear != mCurNear || actualZFar != mCurFar;
 
@@ -758,7 +764,6 @@
     }
 
     mForceSetViewport = false;
-    return true;
 }
 
 bool Renderer11::applyPrimitiveType(GLenum mode, GLsizei count)
@@ -802,15 +807,15 @@
     ID3D11RenderTargetView* framebufferRTVs[gl::IMPLEMENTATION_MAX_DRAW_BUFFERS] = {NULL};
     bool missingColorRenderTarget = true;
 
-    for (unsigned int colorAttachment = 0; colorAttachment < gl::IMPLEMENTATION_MAX_DRAW_BUFFERS; colorAttachment++)
-    {
-        const GLenum drawBufferState = framebuffer->getDrawBufferState(colorAttachment);
-        gl::FramebufferAttachment *colorbuffer = framebuffer->getColorbuffer(colorAttachment);
+    const gl::ColorbufferInfo &colorbuffers = framebuffer->getColorbuffersForRender();
 
-        if (colorbuffer && drawBufferState != GL_NONE)
+    for (size_t colorAttachment = 0; colorAttachment < colorbuffers.size(); ++colorAttachment)
+    {
+        gl::FramebufferAttachment *colorbuffer = colorbuffers[colorAttachment];
+
+        if (colorbuffer)
         {
             // the draw buffer must be either "none", "back" for the default buffer or the same index as this color (in order)
-            ASSERT(drawBufferState == GL_BACK || drawBufferState == (GL_COLOR_ATTACHMENT0_EXT + colorAttachment));
 
             // check for zero-sized default framebuffer, which is a special case.
             // in this case we do not wish to modify any state and just silently return false.
@@ -820,10 +825,10 @@
                 return false;
             }
 
-            renderTargetSerials[colorAttachment] = colorbuffer->getSerial();
+            renderTargetSerials[colorAttachment] = GetAttachmentSerial(colorbuffer);
 
             // Extract the render target dimensions and view
-            RenderTarget11 *renderTarget = RenderTarget11::makeRenderTarget11(colorbuffer->getRenderTarget());
+            RenderTarget11 *renderTarget = d3d11::GetAttachmentRenderTarget(colorbuffer);
             if (!renderTarget)
             {
                 ERR("render target pointer unexpectedly null.");
@@ -850,24 +855,24 @@
         }
     }
 
-    // Get the depth stencil render buffer and serials
+    // Get the depth stencil render buffter and serials
     gl::FramebufferAttachment *depthStencil = framebuffer->getDepthbuffer();
     unsigned int depthbufferSerial = 0;
     unsigned int stencilbufferSerial = 0;
     if (depthStencil)
     {
-        depthbufferSerial = depthStencil->getSerial();
+        depthbufferSerial = GetAttachmentSerial(depthStencil);
     }
     else if (framebuffer->getStencilbuffer())
     {
         depthStencil = framebuffer->getStencilbuffer();
-        stencilbufferSerial = depthStencil->getSerial();
+        stencilbufferSerial = GetAttachmentSerial(depthStencil);
     }
 
     ID3D11DepthStencilView* framebufferDSV = NULL;
     if (depthStencil)
     {
-        RenderTarget11 *depthStencilRenderTarget = RenderTarget11::makeRenderTarget11(depthStencil->getDepthStencil());
+        RenderTarget11 *depthStencilRenderTarget = d3d11::GetAttachmentRenderTarget(depthStencil);
         if (!depthStencilRenderTarget)
         {
             ERR("render target pointer unexpectedly null.");
@@ -928,50 +933,51 @@
     return true;
 }
 
-GLenum Renderer11::applyVertexBuffer(gl::ProgramBinary *programBinary, const gl::VertexAttribute vertexAttributes[], const gl::VertexAttribCurrentValueData currentValues[],
-                                     GLint first, GLsizei count, GLsizei instances)
+gl::Error Renderer11::applyVertexBuffer(gl::ProgramBinary *programBinary, const gl::VertexAttribute vertexAttributes[], const gl::VertexAttribCurrentValueData currentValues[],
+                                        GLint first, GLsizei count, GLsizei instances)
 {
     TranslatedAttribute attributes[gl::MAX_VERTEX_ATTRIBS];
-    GLenum err = mVertexDataManager->prepareVertexData(vertexAttributes, currentValues, programBinary, first, count, attributes, instances);
-    if (err != GL_NO_ERROR)
+    gl::Error error = mVertexDataManager->prepareVertexData(vertexAttributes, currentValues, programBinary, first, count, attributes, instances);
+    if (error.isError())
     {
-        return err;
+        return error;
     }
 
     return mInputLayoutCache.applyVertexBuffers(attributes, programBinary);
 }
 
-GLenum Renderer11::applyIndexBuffer(const GLvoid *indices, gl::Buffer *elementArrayBuffer, GLsizei count, GLenum mode, GLenum type, TranslatedIndexData *indexInfo)
+gl::Error Renderer11::applyIndexBuffer(const GLvoid *indices, gl::Buffer *elementArrayBuffer, GLsizei count, GLenum mode, GLenum type, TranslatedIndexData *indexInfo)
 {
-    GLenum err = mIndexDataManager->prepareIndexData(type, count, elementArrayBuffer, indices, indexInfo);
-
-    if (err == GL_NO_ERROR)
+    gl::Error error = mIndexDataManager->prepareIndexData(type, count, elementArrayBuffer, indices, indexInfo);
+    if (error.isError())
     {
-        ID3D11Buffer *buffer = NULL;
-        DXGI_FORMAT bufferFormat = (indexInfo->indexType == GL_UNSIGNED_INT) ? DXGI_FORMAT_R32_UINT : DXGI_FORMAT_R16_UINT;
-
-        if (indexInfo->storage)
-        {
-            Buffer11 *storage = Buffer11::makeBuffer11(indexInfo->storage);
-            buffer = storage->getBuffer(BUFFER_USAGE_INDEX);
-        }
-        else
-        {
-            IndexBuffer11* indexBuffer = IndexBuffer11::makeIndexBuffer11(indexInfo->indexBuffer);
-            buffer = indexBuffer->getBuffer();
-        }
-
-        if (buffer != mAppliedIB || bufferFormat != mAppliedIBFormat || indexInfo->startOffset != mAppliedIBOffset)
-        {
-            mDeviceContext->IASetIndexBuffer(buffer, bufferFormat, indexInfo->startOffset);
-
-            mAppliedIB = buffer;
-            mAppliedIBFormat = bufferFormat;
-            mAppliedIBOffset = indexInfo->startOffset;
-        }
+        return error;
     }
 
-    return err;
+    ID3D11Buffer *buffer = NULL;
+    DXGI_FORMAT bufferFormat = (indexInfo->indexType == GL_UNSIGNED_INT) ? DXGI_FORMAT_R32_UINT : DXGI_FORMAT_R16_UINT;
+
+    if (indexInfo->storage)
+    {
+        Buffer11 *storage = Buffer11::makeBuffer11(indexInfo->storage);
+        buffer = storage->getBuffer(BUFFER_USAGE_INDEX);
+    }
+    else
+    {
+        IndexBuffer11* indexBuffer = IndexBuffer11::makeIndexBuffer11(indexInfo->indexBuffer);
+        buffer = indexBuffer->getBuffer();
+    }
+
+    if (buffer != mAppliedIB || bufferFormat != mAppliedIBFormat || indexInfo->startOffset != mAppliedIBOffset)
+    {
+        mDeviceContext->IASetIndexBuffer(buffer, bufferFormat, indexInfo->startOffset);
+
+        mAppliedIB = buffer;
+        mAppliedIBFormat = bufferFormat;
+        mAppliedIBOffset = indexInfo->startOffset;
+    }
+
+    return gl::Error(GL_NO_ERROR);
 }
 
 void Renderer11::applyTransformFeedbackBuffers(gl::Buffer *transformFeedbackBuffers[], GLintptr offsets[])
@@ -1067,21 +1073,23 @@
 void Renderer11::drawElements(GLenum mode, GLsizei count, GLenum type, const GLvoid *indices,
                               gl::Buffer *elementArrayBuffer, const TranslatedIndexData &indexInfo, GLsizei instances)
 {
+    int minIndex = static_cast<int>(indexInfo.indexRange.start);
+
     if (mode == GL_LINE_LOOP)
     {
-        drawLineLoop(count, type, indices, indexInfo.minIndex, elementArrayBuffer);
+        drawLineLoop(count, type, indices, minIndex, elementArrayBuffer);
     }
     else if (mode == GL_TRIANGLE_FAN)
     {
-        drawTriangleFan(count, type, indices, indexInfo.minIndex, elementArrayBuffer, instances);
+        drawTriangleFan(count, type, indices, minIndex, elementArrayBuffer, instances);
     }
     else if (instances > 0)
     {
-        mDeviceContext->DrawIndexedInstanced(count, instances, 0, -static_cast<int>(indexInfo.minIndex), 0);
+        mDeviceContext->DrawIndexedInstanced(count, instances, 0, -minIndex, 0);
     }
     else
     {
-        mDeviceContext->DrawIndexed(count, 0, -static_cast<int>(indexInfo.minIndex));
+        mDeviceContext->DrawIndexed(count, 0, -minIndex);
     }
 }
 
@@ -1099,10 +1107,10 @@
     if (!mLineLoopIB)
     {
         mLineLoopIB = new StreamingIndexBufferInterface(this);
-        if (!mLineLoopIB->reserveBufferSpace(INITIAL_INDEX_BUFFER_SIZE, GL_UNSIGNED_INT))
+        gl::Error error = mLineLoopIB->reserveBufferSpace(INITIAL_INDEX_BUFFER_SIZE, GL_UNSIGNED_INT);
+        if (error.isError())
         {
-            delete mLineLoopIB;
-            mLineLoopIB = NULL;
+            SafeDelete(mLineLoopIB);
 
             ERR("Could not create a 32-bit looping index buffer for GL_LINE_LOOP.");
             return gl::error(GL_OUT_OF_MEMORY);
@@ -1119,7 +1127,8 @@
     }
 
     const unsigned int spaceNeeded = (static_cast<unsigned int>(count) + 1) * sizeof(unsigned int);
-    if (!mLineLoopIB->reserveBufferSpace(spaceNeeded, GL_UNSIGNED_INT))
+    gl::Error error = mLineLoopIB->reserveBufferSpace(spaceNeeded, GL_UNSIGNED_INT);
+    if (error.isError())
     {
         ERR("Could not reserve enough space in looping index buffer for GL_LINE_LOOP.");
         return gl::error(GL_OUT_OF_MEMORY);
@@ -1127,7 +1136,8 @@
 
     void* mappedMemory = NULL;
     unsigned int offset;
-    if (!mLineLoopIB->mapBuffer(spaceNeeded, &mappedMemory, &offset))
+    error = mLineLoopIB->mapBuffer(spaceNeeded, &mappedMemory, &offset);
+    if (error.isError())
     {
         ERR("Could not map index buffer for GL_LINE_LOOP.");
         return gl::error(GL_OUT_OF_MEMORY);
@@ -1169,7 +1179,8 @@
       default: UNREACHABLE();
     }
 
-    if (!mLineLoopIB->unmapBuffer())
+    error = mLineLoopIB->unmapBuffer();
+    if (error.isError())
     {
         ERR("Could not unmap index buffer for GL_LINE_LOOP.");
         return gl::error(GL_OUT_OF_MEMORY);
@@ -1204,10 +1215,10 @@
     if (!mTriangleFanIB)
     {
         mTriangleFanIB = new StreamingIndexBufferInterface(this);
-        if (!mTriangleFanIB->reserveBufferSpace(INITIAL_INDEX_BUFFER_SIZE, GL_UNSIGNED_INT))
+        gl::Error error = mTriangleFanIB->reserveBufferSpace(INITIAL_INDEX_BUFFER_SIZE, GL_UNSIGNED_INT);
+        if (error.isError())
         {
-            delete mTriangleFanIB;
-            mTriangleFanIB = NULL;
+            SafeDelete(mTriangleFanIB);
 
             ERR("Could not create a scratch index buffer for GL_TRIANGLE_FAN.");
             return gl::error(GL_OUT_OF_MEMORY);
@@ -1226,7 +1237,8 @@
     }
 
     const unsigned int spaceNeeded = (numTris * 3) * sizeof(unsigned int);
-    if (!mTriangleFanIB->reserveBufferSpace(spaceNeeded, GL_UNSIGNED_INT))
+    gl::Error error = mTriangleFanIB->reserveBufferSpace(spaceNeeded, GL_UNSIGNED_INT);
+    if (error.isError())
     {
         ERR("Could not reserve enough space in scratch index buffer for GL_TRIANGLE_FAN.");
         return gl::error(GL_OUT_OF_MEMORY);
@@ -1234,7 +1246,8 @@
 
     void* mappedMemory = NULL;
     unsigned int offset;
-    if (!mTriangleFanIB->mapBuffer(spaceNeeded, &mappedMemory, &offset))
+    error = mTriangleFanIB->mapBuffer(spaceNeeded, &mappedMemory, &offset);
+    if (error.isError())
     {
         ERR("Could not map scratch index buffer for GL_TRIANGLE_FAN.");
         return gl::error(GL_OUT_OF_MEMORY);
@@ -1280,7 +1293,8 @@
       default: UNREACHABLE();
     }
 
-    if (!mTriangleFanIB->unmapBuffer())
+    error = mTriangleFanIB->unmapBuffer();
+    if (error.isError())
     {
         ERR("Could not unmap scratch index buffer for GL_TRIANGLE_FAN.");
         return gl::error(GL_OUT_OF_MEMORY);
@@ -1399,8 +1413,9 @@
         }
     }
 
-    const UniformStorage11 *vertexUniformStorage = UniformStorage11::makeUniformStorage11(&programBinary.getVertexUniformStorage());
-    const UniformStorage11 *fragmentUniformStorage = UniformStorage11::makeUniformStorage11(&programBinary.getFragmentUniformStorage());
+    const ProgramD3D *programD3D = ProgramD3D::makeProgramD3D(programBinary.getImplementation());
+    const UniformStorage11 *vertexUniformStorage = UniformStorage11::makeUniformStorage11(&programD3D->getVertexUniformStorage());
+    const UniformStorage11 *fragmentUniformStorage = UniformStorage11::makeUniformStorage11(&programD3D->getFragmentUniformStorage());
     ASSERT(vertexUniformStorage);
     ASSERT(fragmentUniformStorage);
 
@@ -1528,10 +1543,17 @@
     }
 }
 
-void Renderer11::clear(const gl::ClearParameters &clearParams, gl::Framebuffer *frameBuffer)
+gl::Error Renderer11::clear(const gl::ClearParameters &clearParams, gl::Framebuffer *frameBuffer)
 {
-    mClear->clearFramebuffer(clearParams, frameBuffer);
+    gl::Error error = mClear->clearFramebuffer(clearParams, frameBuffer);
+    if (error.isError())
+    {
+        return error;
+    }
+
     invalidateFramebufferSwizzles(frameBuffer);
+
+    return gl::Error(GL_NO_ERROR);
 }
 
 void Renderer11::markAllStateDirty()
@@ -1545,15 +1567,18 @@
     mDepthStencilInitialized = false;
     mRenderTargetDescInitialized = false;
 
-    for (int i = 0; i < gl::IMPLEMENTATION_MAX_VERTEX_TEXTURE_IMAGE_UNITS; i++)
+    ASSERT(mForceSetVertexSamplerStates.size() == mCurVertexSRVs.size());
+    for (size_t vsamplerId = 0; vsamplerId < mForceSetVertexSamplerStates.size(); ++vsamplerId)
     {
-        mForceSetVertexSamplerStates[i] = true;
-        mCurVertexSRVs[i] = NULL;
+        mForceSetVertexSamplerStates[vsamplerId] = true;
+        mCurVertexSRVs[vsamplerId] = NULL;
     }
-    for (int i = 0; i < gl::MAX_TEXTURE_IMAGE_UNITS; i++)
+
+    ASSERT(mForceSetPixelSamplerStates.size() == mCurPixelSRVs.size());
+    for (size_t fsamplerId = 0; fsamplerId < mForceSetPixelSamplerStates.size(); ++fsamplerId)
     {
-        mForceSetPixelSamplerStates[i] = true;
-        mCurPixelSRVs[i] = NULL;
+        mForceSetPixelSamplerStates[fsamplerId] = true;
+        mCurPixelSRVs[fsamplerId] = NULL;
     }
 
     mForceSetBlendState = true;
@@ -1705,6 +1730,7 @@
 
 void Renderer11::release()
 {
+    releaseShaderCompiler();
     releaseDeviceResources();
 
     SafeRelease(mDxgiFactory);
@@ -1779,25 +1805,6 @@
     return adapterId;
 }
 
-unsigned int Renderer11::getMaxVertexTextureImageUnits() const
-{
-    META_ASSERT(MAX_TEXTURE_IMAGE_UNITS_VTF_SM4 <= gl::IMPLEMENTATION_MAX_VERTEX_TEXTURE_IMAGE_UNITS);
-    switch (mFeatureLevel)
-    {
-      case D3D_FEATURE_LEVEL_11_0:
-      case D3D_FEATURE_LEVEL_10_1:
-      case D3D_FEATURE_LEVEL_10_0:
-        return MAX_TEXTURE_IMAGE_UNITS_VTF_SM4;
-      default: UNREACHABLE();
-        return 0;
-    }
-}
-
-unsigned int Renderer11::getMaxCombinedTextureImageUnits() const
-{
-    return gl::MAX_TEXTURE_IMAGE_UNITS + getMaxVertexTextureImageUnits();
-}
-
 unsigned int Renderer11::getReservedVertexUniformVectors() const
 {
     return 0;   // Driver uniforms are stored in a separate constant buffer
@@ -1808,72 +1815,6 @@
     return 0;   // Driver uniforms are stored in a separate constant buffer
 }
 
-unsigned int Renderer11::getMaxVertexUniformVectors() const
-{
-    META_ASSERT(MAX_VERTEX_UNIFORM_VECTORS_D3D11 <= D3D10_REQ_CONSTANT_BUFFER_ELEMENT_COUNT);
-    ASSERT(mFeatureLevel >= D3D_FEATURE_LEVEL_10_0);
-    return MAX_VERTEX_UNIFORM_VECTORS_D3D11;
-}
-
-unsigned int Renderer11::getMaxFragmentUniformVectors() const
-{
-    META_ASSERT(MAX_FRAGMENT_UNIFORM_VECTORS_D3D11 <= D3D10_REQ_CONSTANT_BUFFER_ELEMENT_COUNT);
-    ASSERT(mFeatureLevel >= D3D_FEATURE_LEVEL_10_0);
-    return MAX_FRAGMENT_UNIFORM_VECTORS_D3D11;
-}
-
-unsigned int Renderer11::getMaxVaryingVectors() const
-{
-    META_ASSERT(gl::IMPLEMENTATION_MAX_VARYING_VECTORS == D3D11_VS_OUTPUT_REGISTER_COUNT);
-    META_ASSERT(D3D11_VS_OUTPUT_REGISTER_COUNT <= D3D11_PS_INPUT_REGISTER_COUNT);
-    META_ASSERT(D3D10_VS_OUTPUT_REGISTER_COUNT <= D3D10_PS_INPUT_REGISTER_COUNT);
-    switch (mFeatureLevel)
-    {
-      case D3D_FEATURE_LEVEL_11_0:
-        return D3D11_VS_OUTPUT_REGISTER_COUNT - getReservedVaryings();
-      case D3D_FEATURE_LEVEL_10_1:
-        return D3D10_1_VS_OUTPUT_REGISTER_COUNT - getReservedVaryings();
-      case D3D_FEATURE_LEVEL_10_0:
-        return D3D10_VS_OUTPUT_REGISTER_COUNT - getReservedVaryings();
-      default: UNREACHABLE();
-        return 0;
-    }
-}
-
-unsigned int Renderer11::getMaxVertexShaderUniformBuffers() const
-{
-    META_ASSERT(gl::IMPLEMENTATION_MAX_VERTEX_SHADER_UNIFORM_BUFFERS >= D3D10_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT &&
-                gl::IMPLEMENTATION_MAX_VERTEX_SHADER_UNIFORM_BUFFERS >= D3D11_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT);
-
-    switch (mFeatureLevel)
-    {
-      case D3D_FEATURE_LEVEL_11_0:
-        return D3D11_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT - getReservedVertexUniformBuffers();
-      case D3D_FEATURE_LEVEL_10_1:
-      case D3D_FEATURE_LEVEL_10_0:
-        return D3D10_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT - getReservedVertexUniformBuffers();
-      default: UNREACHABLE();
-        return 0;
-    }
-}
-
-unsigned int Renderer11::getMaxFragmentShaderUniformBuffers() const
-{
-    META_ASSERT(gl::IMPLEMENTATION_MAX_FRAGMENT_SHADER_UNIFORM_BUFFERS >= D3D10_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT &&
-                gl::IMPLEMENTATION_MAX_FRAGMENT_SHADER_UNIFORM_BUFFERS >= D3D11_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT);
-
-    switch (mFeatureLevel)
-    {
-      case D3D_FEATURE_LEVEL_11_0:
-        return D3D11_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT - getReservedFragmentUniformBuffers();
-      case D3D_FEATURE_LEVEL_10_1:
-      case D3D_FEATURE_LEVEL_10_0:
-        return D3D10_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT - getReservedFragmentUniformBuffers();
-      default: UNREACHABLE();
-        return 0;
-    }
-}
-
 unsigned int Renderer11::getReservedVertexUniformBuffers() const
 {
     // we reserve one buffer for the application uniforms, and one for driver uniforms
@@ -1886,69 +1827,6 @@
     return 2;
 }
 
-unsigned int Renderer11::getReservedVaryings() const
-{
-    // We potentially reserve varyings for gl_Position, dx_Position, gl_FragCoord and gl_PointSize
-    return 4;
-}
-
-
-unsigned int Renderer11::getMaxTransformFeedbackBuffers() const
-{
-    META_ASSERT(gl::IMPLEMENTATION_MAX_TRANSFORM_FEEDBACK_BUFFERS >= D3D11_SO_BUFFER_SLOT_COUNT &&
-                gl::IMPLEMENTATION_MAX_TRANSFORM_FEEDBACK_BUFFERS >= D3D10_SO_BUFFER_SLOT_COUNT);
-
-    switch (mFeatureLevel)
-    {
-      case D3D_FEATURE_LEVEL_11_0:
-        return D3D11_SO_BUFFER_SLOT_COUNT;
-      case D3D_FEATURE_LEVEL_10_1:
-        return D3D10_1_SO_BUFFER_SLOT_COUNT;
-      case D3D_FEATURE_LEVEL_10_0:
-        return D3D10_SO_BUFFER_SLOT_COUNT;
-      default: UNREACHABLE();
-        return 0;
-    }
-}
-
-unsigned int Renderer11::getMaxTransformFeedbackSeparateComponents() const
-{
-    switch (mFeatureLevel)
-    {
-      case D3D_FEATURE_LEVEL_11_0:
-        return getMaxTransformFeedbackInterleavedComponents() / getMaxTransformFeedbackBuffers();
-      case D3D_FEATURE_LEVEL_10_1:
-      case D3D_FEATURE_LEVEL_10_0:
-        // D3D 10 and 10.1 only allow one output per output slot if an output slot other than zero
-        // is used.
-        return 4;
-      default: UNREACHABLE();
-        return 0;
-    }
-}
-
-unsigned int Renderer11::getMaxTransformFeedbackInterleavedComponents() const
-{
-    return (getMaxVaryingVectors() * 4);
-}
-
-unsigned int Renderer11::getMaxUniformBufferSize() const
-{
-    // Each component is a 4-element vector of 4-byte units (floats)
-    const unsigned int bytesPerComponent = 4 * sizeof(float);
-
-    switch (mFeatureLevel)
-    {
-      case D3D_FEATURE_LEVEL_11_0:
-        return D3D11_REQ_CONSTANT_BUFFER_ELEMENT_COUNT * bytesPerComponent;
-      case D3D_FEATURE_LEVEL_10_1:
-      case D3D_FEATURE_LEVEL_10_0:
-        return D3D10_REQ_CONSTANT_BUFFER_ELEMENT_COUNT * bytesPerComponent;
-      default: UNREACHABLE();
-        return 0;
-    }
-}
-
 bool Renderer11::getShareHandleSupport() const
 {
     // We only currently support share handles with BGRA surfaces, because
@@ -1963,24 +1841,6 @@
     return false;
 }
 
-int Renderer11::getMaxRecommendedElementsIndices() const
-{
-    META_ASSERT(D3D11_REQ_DRAWINDEXED_INDEX_COUNT_2_TO_EXP == 32);
-    META_ASSERT(D3D10_REQ_DRAWINDEXED_INDEX_COUNT_2_TO_EXP == 32);
-
-    // D3D11 allows up to 2^32 elements, but we report max signed int for convenience.
-    return std::numeric_limits<GLint>::max();
-}
-
-int Renderer11::getMaxRecommendedElementsVertices() const
-{
-    META_ASSERT(D3D11_REQ_DRAW_VERTEX_COUNT_2_TO_EXP == 32);
-    META_ASSERT(D3D10_REQ_DRAW_VERTEX_COUNT_2_TO_EXP == 32);
-
-    // D3D11 allows up to 2^32 elements, but we report max signed int for convenience.
-    return std::numeric_limits<GLint>::max();
-}
-
 int Renderer11::getMajorShaderModel() const
 {
     switch (mFeatureLevel)
@@ -2013,12 +1873,12 @@
     return 4;
 }
 
-bool Renderer11::copyToRenderTarget(TextureStorageInterface2D *dest, TextureStorageInterface2D *source)
+bool Renderer11::copyToRenderTarget2D(TextureStorage *dest, TextureStorage *source)
 {
     if (source && dest)
     {
-        TextureStorage11_2D *source11 = TextureStorage11_2D::makeTextureStorage11_2D(source->getStorageInstance());
-        TextureStorage11_2D *dest11 = TextureStorage11_2D::makeTextureStorage11_2D(dest->getStorageInstance());
+        TextureStorage11_2D *source11 = TextureStorage11_2D::makeTextureStorage11_2D(source);
+        TextureStorage11_2D *dest11 = TextureStorage11_2D::makeTextureStorage11_2D(dest);
 
         mDeviceContext->CopyResource(dest11->getResource(), source11->getResource());
 
@@ -2030,12 +1890,12 @@
     return false;
 }
 
-bool Renderer11::copyToRenderTarget(TextureStorageInterfaceCube *dest, TextureStorageInterfaceCube *source)
+bool Renderer11::copyToRenderTargetCube(TextureStorage *dest, TextureStorage *source)
 {
     if (source && dest)
     {
-        TextureStorage11_Cube *source11 = TextureStorage11_Cube::makeTextureStorage11_Cube(source->getStorageInstance());
-        TextureStorage11_Cube *dest11 = TextureStorage11_Cube::makeTextureStorage11_Cube(dest->getStorageInstance());
+        TextureStorage11_Cube *source11 = TextureStorage11_Cube::makeTextureStorage11_Cube(source);
+        TextureStorage11_Cube *dest11 = TextureStorage11_Cube::makeTextureStorage11_Cube(dest);
 
         mDeviceContext->CopyResource(dest11->getResource(), source11->getResource());
 
@@ -2047,12 +1907,12 @@
     return false;
 }
 
-bool Renderer11::copyToRenderTarget(TextureStorageInterface3D *dest, TextureStorageInterface3D *source)
+bool Renderer11::copyToRenderTarget3D(TextureStorage *dest, TextureStorage *source)
 {
     if (source && dest)
     {
-        TextureStorage11_3D *source11 = TextureStorage11_3D::makeTextureStorage11_3D(source->getStorageInstance());
-        TextureStorage11_3D *dest11 = TextureStorage11_3D::makeTextureStorage11_3D(dest->getStorageInstance());
+        TextureStorage11_3D *source11 = TextureStorage11_3D::makeTextureStorage11_3D(source);
+        TextureStorage11_3D *dest11 = TextureStorage11_3D::makeTextureStorage11_3D(dest);
 
         mDeviceContext->CopyResource(dest11->getResource(), source11->getResource());
 
@@ -2064,12 +1924,12 @@
     return false;
 }
 
-bool Renderer11::copyToRenderTarget(TextureStorageInterface2DArray *dest, TextureStorageInterface2DArray *source)
+bool Renderer11::copyToRenderTarget2DArray(TextureStorage *dest, TextureStorage *source)
 {
     if (source && dest)
     {
-        TextureStorage11_2DArray *source11 = TextureStorage11_2DArray::makeTextureStorage11_2DArray(source->getStorageInstance());
-        TextureStorage11_2DArray *dest11 = TextureStorage11_2DArray::makeTextureStorage11_2DArray(dest->getStorageInstance());
+        TextureStorage11_2DArray *source11 = TextureStorage11_2DArray::makeTextureStorage11_2DArray(source);
+        TextureStorage11_2DArray *dest11 = TextureStorage11_2DArray::makeTextureStorage11_2DArray(dest);
 
         mDeviceContext->CopyResource(dest11->getResource(), source11->getResource());
 
@@ -2081,8 +1941,8 @@
     return false;
 }
 
-bool Renderer11::copyImage(gl::Framebuffer *framebuffer, const gl::Rectangle &sourceRect, GLenum destFormat,
-                           GLint xoffset, GLint yoffset, TextureStorageInterface2D *storage, GLint level)
+bool Renderer11::copyImage2D(gl::Framebuffer *framebuffer, const gl::Rectangle &sourceRect, GLenum destFormat,
+                             GLint xoffset, GLint yoffset, TextureStorage *storage, GLint level)
 {
     gl::FramebufferAttachment *colorbuffer = framebuffer->getReadColorbuffer();
     if (!colorbuffer)
@@ -2091,7 +1951,7 @@
         return gl::error(GL_OUT_OF_MEMORY, false);
     }
 
-    RenderTarget11 *sourceRenderTarget = RenderTarget11::makeRenderTarget11(colorbuffer->getRenderTarget());
+    RenderTarget11 *sourceRenderTarget = d3d11::GetAttachmentRenderTarget(colorbuffer);
     if (!sourceRenderTarget)
     {
         ERR("Failed to retrieve the render target from the frame buffer.");
@@ -2105,14 +1965,15 @@
         return gl::error(GL_OUT_OF_MEMORY, false);
     }
 
-    TextureStorage11_2D *storage11 = TextureStorage11_2D::makeTextureStorage11_2D(storage->getStorageInstance());
+    TextureStorage11_2D *storage11 = TextureStorage11_2D::makeTextureStorage11_2D(storage);
     if (!storage11)
     {
         ERR("Failed to retrieve the texture storage from the destination.");
         return gl::error(GL_OUT_OF_MEMORY, false);
     }
 
-    RenderTarget11 *destRenderTarget = RenderTarget11::makeRenderTarget11(storage11->getRenderTarget(level));
+    gl::ImageIndex index = gl::ImageIndex::Make2D(level);
+    RenderTarget11 *destRenderTarget = RenderTarget11::makeRenderTarget11(storage11->getRenderTarget(index));
     if (!destRenderTarget)
     {
         ERR("Failed to retrieve the render target from the destination storage.");
@@ -2142,8 +2003,8 @@
     return ret;
 }
 
-bool Renderer11::copyImage(gl::Framebuffer *framebuffer, const gl::Rectangle &sourceRect, GLenum destFormat,
-                           GLint xoffset, GLint yoffset, TextureStorageInterfaceCube *storage, GLenum target, GLint level)
+bool Renderer11::copyImageCube(gl::Framebuffer *framebuffer, const gl::Rectangle &sourceRect, GLenum destFormat,
+                               GLint xoffset, GLint yoffset, TextureStorage *storage, GLenum target, GLint level)
 {
     gl::FramebufferAttachment *colorbuffer = framebuffer->getReadColorbuffer();
     if (!colorbuffer)
@@ -2152,7 +2013,7 @@
         return gl::error(GL_OUT_OF_MEMORY, false);
     }
 
-    RenderTarget11 *sourceRenderTarget = RenderTarget11::makeRenderTarget11(colorbuffer->getRenderTarget());
+    RenderTarget11 *sourceRenderTarget = d3d11::GetAttachmentRenderTarget(colorbuffer);
     if (!sourceRenderTarget)
     {
         ERR("Failed to retrieve the render target from the frame buffer.");
@@ -2166,14 +2027,15 @@
         return gl::error(GL_OUT_OF_MEMORY, false);
     }
 
-    TextureStorage11_Cube *storage11 = TextureStorage11_Cube::makeTextureStorage11_Cube(storage->getStorageInstance());
+    TextureStorage11_Cube *storage11 = TextureStorage11_Cube::makeTextureStorage11_Cube(storage);
     if (!storage11)
     {
         ERR("Failed to retrieve the texture storage from the destination.");
         return gl::error(GL_OUT_OF_MEMORY, false);
     }
 
-    RenderTarget11 *destRenderTarget = RenderTarget11::makeRenderTarget11(storage11->getRenderTargetFace(target, level));
+    gl::ImageIndex index = gl::ImageIndex::MakeCube(target, level);
+    RenderTarget11 *destRenderTarget = RenderTarget11::makeRenderTarget11(storage11->getRenderTarget(index));
     if (!destRenderTarget)
     {
         ERR("Failed to retrieve the render target from the destination storage.");
@@ -2203,8 +2065,8 @@
     return ret;
 }
 
-bool Renderer11::copyImage(gl::Framebuffer *framebuffer, const gl::Rectangle &sourceRect, GLenum destFormat,
-                           GLint xoffset, GLint yoffset, GLint zOffset, TextureStorageInterface3D *storage, GLint level)
+bool Renderer11::copyImage3D(gl::Framebuffer *framebuffer, const gl::Rectangle &sourceRect, GLenum destFormat,
+                             GLint xoffset, GLint yoffset, GLint zOffset, TextureStorage *storage, GLint level)
 {
     gl::FramebufferAttachment *colorbuffer = framebuffer->getReadColorbuffer();
     if (!colorbuffer)
@@ -2213,7 +2075,7 @@
         return gl::error(GL_OUT_OF_MEMORY, false);
     }
 
-    RenderTarget11 *sourceRenderTarget = RenderTarget11::makeRenderTarget11(colorbuffer->getRenderTarget());
+    RenderTarget11 *sourceRenderTarget = d3d11::GetAttachmentRenderTarget(colorbuffer);
     if (!sourceRenderTarget)
     {
         ERR("Failed to retrieve the render target from the frame buffer.");
@@ -2227,14 +2089,15 @@
         return gl::error(GL_OUT_OF_MEMORY, false);
     }
 
-    TextureStorage11_3D *storage11 = TextureStorage11_3D::makeTextureStorage11_3D(storage->getStorageInstance());
+    TextureStorage11_3D *storage11 = TextureStorage11_3D::makeTextureStorage11_3D(storage);
     if (!storage11)
     {
         ERR("Failed to retrieve the texture storage from the destination.");
         return gl::error(GL_OUT_OF_MEMORY, false);
     }
 
-    RenderTarget11 *destRenderTarget = RenderTarget11::makeRenderTarget11(storage11->getRenderTargetLayer(level, zOffset));
+    gl::ImageIndex index = gl::ImageIndex::Make3D(level, zOffset);
+    RenderTarget11 *destRenderTarget = RenderTarget11::makeRenderTarget11(storage11->getRenderTarget(index));
     if (!destRenderTarget)
     {
         ERR("Failed to retrieve the render target from the destination storage.");
@@ -2264,8 +2127,8 @@
     return ret;
 }
 
-bool Renderer11::copyImage(gl::Framebuffer *framebuffer, const gl::Rectangle &sourceRect, GLenum destFormat,
-                           GLint xoffset, GLint yoffset, GLint zOffset, TextureStorageInterface2DArray *storage, GLint level)
+bool Renderer11::copyImage2DArray(gl::Framebuffer *framebuffer, const gl::Rectangle &sourceRect, GLenum destFormat,
+                                  GLint xoffset, GLint yoffset, GLint zOffset, TextureStorage *storage, GLint level)
 {
     gl::FramebufferAttachment *colorbuffer = framebuffer->getReadColorbuffer();
     if (!colorbuffer)
@@ -2274,7 +2137,7 @@
         return gl::error(GL_OUT_OF_MEMORY, false);
     }
 
-    RenderTarget11 *sourceRenderTarget = RenderTarget11::makeRenderTarget11(colorbuffer->getRenderTarget());
+    RenderTarget11 *sourceRenderTarget = d3d11::GetAttachmentRenderTarget(colorbuffer);
     if (!sourceRenderTarget)
     {
         ERR("Failed to retrieve the render target from the frame buffer.");
@@ -2288,7 +2151,7 @@
         return gl::error(GL_OUT_OF_MEMORY, false);
     }
 
-    TextureStorage11_2DArray *storage11 = TextureStorage11_2DArray::makeTextureStorage11_2DArray(storage->getStorageInstance());
+    TextureStorage11_2DArray *storage11 = TextureStorage11_2DArray::makeTextureStorage11_2DArray(storage);
     if (!storage11)
     {
         SafeRelease(source);
@@ -2296,7 +2159,8 @@
         return gl::error(GL_OUT_OF_MEMORY, false);
     }
 
-    RenderTarget11 *destRenderTarget = RenderTarget11::makeRenderTarget11(storage11->getRenderTargetLayer(level, zOffset));
+    gl::ImageIndex index = gl::ImageIndex::Make2DArray(level, zOffset);
+    RenderTarget11 *destRenderTarget = RenderTarget11::makeRenderTarget11(storage11->getRenderTarget(index));
     if (!destRenderTarget)
     {
         SafeRelease(source);
@@ -2377,6 +2241,21 @@
     return renderTarget;
 }
 
+ShaderImpl *Renderer11::createShader(GLenum type)
+{
+    return new ShaderD3D(type, this);
+}
+
+ProgramImpl *Renderer11::createProgram()
+{
+    return new ProgramD3D(this);
+}
+
+void Renderer11::releaseShaderCompiler()
+{
+    ShaderD3D::releaseCompiler();
+}
+
 ShaderExecutable *Renderer11::loadExecutable(const void *function, size_t length, rx::ShaderType type,
                                              const std::vector<gl::LinkedVarying> &transformFeedbackVaryings,
                                              bool separatedOutputBuffers)
@@ -2582,6 +2461,11 @@
     return new Fence11(this);
 }
 
+TransformFeedbackImpl* Renderer11::createTransformFeedback()
+{
+    return new TransformFeedbackD3D();
+}
+
 bool Renderer11::supportsFastCopyBufferToTexture(GLenum internalFormat) const
 {
     ASSERT(getRendererExtensions().pixelBufferObject);
@@ -2628,7 +2512,7 @@
 {
     ASSERT(colorbuffer != NULL);
 
-    RenderTarget11 *renderTarget = RenderTarget11::makeRenderTarget11(colorbuffer->getRenderTarget());
+    RenderTarget11 *renderTarget = d3d11::GetAttachmentRenderTarget(colorbuffer);
     if (renderTarget)
     {
         *subresourceIndex = renderTarget->getSubresourceIndex();
@@ -2673,7 +2557,7 @@
             return gl::error(GL_OUT_OF_MEMORY, false);
         }
 
-        RenderTarget *readRenderTarget = readBuffer->getRenderTarget();
+        RenderTarget *readRenderTarget = GetAttachmentRenderTarget(readBuffer);
 
         for (unsigned int colorAttachment = 0; colorAttachment < gl::IMPLEMENTATION_MAX_DRAW_BUFFERS; colorAttachment++)
         {
@@ -2687,7 +2571,7 @@
                     return gl::error(GL_OUT_OF_MEMORY, false);
                 }
 
-                RenderTarget *drawRenderTarget = drawBuffer->getRenderTarget();
+                RenderTarget *drawRenderTarget = GetAttachmentRenderTarget(drawBuffer);
 
                 if (!blitRenderbufferRect(readRect, drawRect, readRenderTarget, drawRenderTarget, filter, scissor,
                                           blitRenderTarget, false, false))
@@ -2715,8 +2599,9 @@
             return gl::error(GL_OUT_OF_MEMORY, false);
         }
 
-        RenderTarget *readRenderTarget = readBuffer->getDepthStencil();
-        RenderTarget *drawRenderTarget = drawBuffer->getDepthStencil();
+        RenderTarget *readRenderTarget = GetAttachmentRenderTarget(readBuffer);
+        RenderTarget *drawRenderTarget = GetAttachmentRenderTarget(drawBuffer);
+        ASSERT(readRenderTarget && drawRenderTarget);
 
         if (!blitRenderbufferRect(readRect, drawRect, readRenderTarget, drawRenderTarget, filter, scissor,
                                   false, blitDepth, blitStencil))
@@ -2730,8 +2615,8 @@
     return true;
 }
 
-void Renderer11::readPixels(gl::Framebuffer *framebuffer, GLint x, GLint y, GLsizei width, GLsizei height, GLenum format,
-                            GLenum type, GLuint outputPitch, const gl::PixelPackState &pack, void* pixels)
+gl::Error Renderer11::readPixels(gl::Framebuffer *framebuffer, GLint x, GLint y, GLsizei width, GLsizei height, GLenum format,
+                                 GLenum type, GLuint outputPitch, const gl::PixelPackState &pack, uint8_t *pixels)
 {
     ID3D11Texture2D *colorBufferTexture = NULL;
     unsigned int subresourceIndex = 0;
@@ -2746,19 +2631,33 @@
         area.width = width;
         area.height = height;
 
-        if (pack.pixelBuffer.get() != NULL)
+        gl::Buffer *packBuffer = pack.pixelBuffer.get();
+        if (packBuffer != NULL)
         {
-            rx::Buffer11 *packBufferStorage = Buffer11::makeBuffer11(pack.pixelBuffer.get()->getImplementation());
+            rx::Buffer11 *packBufferStorage = Buffer11::makeBuffer11(packBuffer->getImplementation());
             PackPixelsParams packParams(area, format, type, outputPitch, pack, reinterpret_cast<ptrdiff_t>(pixels));
-            packBufferStorage->packPixels(colorBufferTexture, subresourceIndex, packParams);
+
+            gl::Error error = packBufferStorage->packPixels(colorBufferTexture, subresourceIndex, packParams);
+            if (error.isError())
+            {
+                return error;
+            }
+
+            packBuffer->getIndexRangeCache()->clear();
         }
         else
         {
-            readTextureData(colorBufferTexture, subresourceIndex, area, format, type, outputPitch, pack, pixels);
+            gl::Error error = readTextureData(colorBufferTexture, subresourceIndex, area, format, type, outputPitch, pack, pixels);
+            if (error.isError())
+            {
+                return error;
+            }
         }
 
         SafeRelease(colorBufferTexture);
     }
+
+    return gl::Error(GL_NO_ERROR);
 }
 
 Image *Renderer11::createImage()
@@ -2799,28 +2698,23 @@
     return new TextureStorage11_2DArray(this, internalformat, renderTarget, width, height, depth, levels);
 }
 
-Texture2DImpl *Renderer11::createTexture2D()
+TextureImpl *Renderer11::createTexture(GLenum target)
 {
-    return new TextureD3D_2D(this);
+    switch(target)
+    {
+      case GL_TEXTURE_2D: return new TextureD3D_2D(this);
+      case GL_TEXTURE_CUBE_MAP: return new TextureD3D_Cube(this);
+      case GL_TEXTURE_3D: return new TextureD3D_3D(this);
+      case GL_TEXTURE_2D_ARRAY: return new TextureD3D_2DArray(this);
+      default:
+        UNREACHABLE();
+    }
+
+    return NULL;
 }
 
-TextureCubeImpl *Renderer11::createTextureCube()
-{
-    return new TextureD3D_Cube(this);
-}
-
-Texture3DImpl *Renderer11::createTexture3D()
-{
-    return new TextureD3D_3D(this);
-}
-
-Texture2DArrayImpl *Renderer11::createTexture2DArray()
-{
-    return new TextureD3D_2DArray(this);
-}
-
-void Renderer11::readTextureData(ID3D11Texture2D *texture, unsigned int subResource, const gl::Rectangle &area, GLenum format,
-                                 GLenum type, GLuint outputPitch, const gl::PixelPackState &pack, void *pixels)
+gl::Error Renderer11::readTextureData(ID3D11Texture2D *texture, unsigned int subResource, const gl::Rectangle &area, GLenum format,
+                                      GLenum type, GLuint outputPitch, const gl::PixelPackState &pack, uint8_t *pixels)
 {
     ASSERT(area.width >= 0);
     ASSERT(area.height >= 0);
@@ -2845,7 +2739,7 @@
     if (safeArea.width == 0 || safeArea.height == 0)
     {
         // no work to do
-        return;
+        return gl::Error(GL_NO_ERROR);
     }
 
     D3D11_TEXTURE2D_DESC stagingDesc;
@@ -2865,8 +2759,7 @@
     HRESULT result = mDevice->CreateTexture2D(&stagingDesc, NULL, &stagingTex);
     if (FAILED(result))
     {
-        ERR("Failed to create staging texture for readPixels, HRESULT: 0x%X.", result);
-        return;
+        return gl::Error(GL_OUT_OF_MEMORY, "Failed to create internal staging texture for ReadPixels, HRESULT: 0x%X.", result);
     }
 
     ID3D11Texture2D* srcTex = NULL;
@@ -2888,9 +2781,8 @@
         result = mDevice->CreateTexture2D(&resolveDesc, NULL, &srcTex);
         if (FAILED(result))
         {
-            ERR("Failed to create resolve texture for readPixels, HRESULT: 0x%X.", result);
             SafeRelease(stagingTex);
-            return;
+            return gl::Error(GL_OUT_OF_MEMORY, "Failed to create internal resolve texture for ReadPixels, HRESULT: 0x%X.", result);
         }
 
         mDeviceContext->ResolveSubresource(srcTex, 0, texture, subResource, textureDesc.Format);
@@ -2918,9 +2810,11 @@
     packPixels(stagingTex, packParams, pixels);
 
     SafeRelease(stagingTex);
+
+    return gl::Error(GL_NO_ERROR);
 }
 
-void Renderer11::packPixels(ID3D11Texture2D *readTexture, const PackPixelsParams &params, void *pixelsOut)
+void Renderer11::packPixels(ID3D11Texture2D *readTexture, const PackPixelsParams &params, uint8_t *pixelsOut)
 {
     D3D11_TEXTURE2D_DESC textureDesc;
     readTexture->GetDesc(&textureDesc);
@@ -2930,16 +2824,16 @@
     UNUSED_ASSERTION_VARIABLE(hr);
     ASSERT(SUCCEEDED(hr));
 
-    unsigned char *source;
+    uint8_t *source;
     int inputPitch;
     if (params.pack.reverseRowOrder)
     {
-        source = static_cast<unsigned char*>(mapping.pData) + mapping.RowPitch * (params.area.height - 1);
+        source = static_cast<uint8_t*>(mapping.pData) + mapping.RowPitch * (params.area.height - 1);
         inputPitch = -static_cast<int>(mapping.RowPitch);
     }
     else
     {
-        source = static_cast<unsigned char*>(mapping.pData);
+        source = static_cast<uint8_t*>(mapping.pData);
         inputPitch = static_cast<int>(mapping.RowPitch);
     }
 
@@ -2947,7 +2841,7 @@
     const gl::InternalFormat &sourceFormatInfo = gl::GetInternalFormatInfo(dxgiFormatInfo.internalFormat);
     if (sourceFormatInfo.format == params.format && sourceFormatInfo.type == params.type)
     {
-        unsigned char *dest = static_cast<unsigned char*>(pixelsOut) + params.offset;
+        uint8_t *dest = pixelsOut + params.offset;
         for (int y = 0; y < params.area.height; y++)
         {
             memcpy(dest + y * params.outputPitch, source + y * inputPitch, params.area.width * sourceFormatInfo.pixelBytes);
@@ -2968,8 +2862,8 @@
             {
                 for (int x = 0; x < params.area.width; x++)
                 {
-                    void *dest = static_cast<unsigned char*>(pixelsOut) + params.offset + y * params.outputPitch + x * destFormatInfo.pixelBytes;
-                    void *src = static_cast<unsigned char*>(source) + y * inputPitch + x * sourceFormatInfo.pixelBytes;
+                    uint8_t *dest = pixelsOut + params.offset + y * params.outputPitch + x * destFormatInfo.pixelBytes;
+                    const uint8_t *src = source + y * inputPitch + x * sourceFormatInfo.pixelBytes;
 
                     fastCopyFunc(src, dest);
                 }
@@ -2977,7 +2871,7 @@
         }
         else
         {
-            unsigned char temp[16]; // Maximum size of any Color<T> type used.
+            uint8_t temp[16]; // Maximum size of any Color<T> type used.
             META_ASSERT(sizeof(temp) >= sizeof(gl::ColorF)  &&
                         sizeof(temp) >= sizeof(gl::ColorUI) &&
                         sizeof(temp) >= sizeof(gl::ColorI));
@@ -2986,8 +2880,8 @@
             {
                 for (int x = 0; x < params.area.width; x++)
                 {
-                    void *dest = static_cast<unsigned char*>(pixelsOut) + params.offset + y * params.outputPitch + x * destFormatInfo.pixelBytes;
-                    void *src = static_cast<unsigned char*>(source) + y * inputPitch + x * sourceFormatInfo.pixelBytes;
+                    uint8_t *dest = pixelsOut + params.offset + y * params.outputPitch + x * destFormatInfo.pixelBytes;
+                    const uint8_t *src = source + y * inputPitch + x * sourceFormatInfo.pixelBytes;
 
                     // readFunc and writeFunc will be using the same type of color, CopyTexImage
                     // will not allow the copy otherwise.
@@ -3219,7 +3113,9 @@
 void Renderer11::invalidateFBOAttachmentSwizzles(gl::FramebufferAttachment *attachment, int mipLevel)
 {
     ASSERT(attachment->isTexture());
-    TextureStorage *texStorage = attachment->getTextureStorage();
+    gl::Texture *texture = attachment->getTexture();
+
+    TextureStorage *texStorage = texture->getNativeTexture();
     if (texStorage)
     {
         TextureStorage11 *texStorage11 = TextureStorage11::makeTextureStorage11(texStorage);
diff --git a/src/libGLESv2/renderer/d3d/d3d11/Renderer11.h b/src/libGLESv2/renderer/d3d/d3d11/Renderer11.h
index 994518c..19e2747 100644
--- a/src/libGLESv2/renderer/d3d/d3d11/Renderer11.h
+++ b/src/libGLESv2/renderer/d3d/d3d11/Renderer11.h
@@ -72,7 +72,7 @@
                                       int stencilBackRef, bool frontFaceCCW);
 
     virtual void setScissorRectangle(const gl::Rectangle &scissor, bool enabled);
-    virtual bool setViewport(const gl::Rectangle &viewport, float zNear, float zFar, GLenum drawMode, GLenum frontFace,
+    virtual void setViewport(const gl::Rectangle &viewport, float zNear, float zFar, GLenum drawMode, GLenum frontFace,
                              bool ignoreViewport);
 
     virtual bool applyPrimitiveType(GLenum mode, GLsizei count);
@@ -80,16 +80,16 @@
     virtual void applyShaders(gl::ProgramBinary *programBinary, const gl::VertexFormat inputLayout[], const gl::Framebuffer *framebuffer,
                               bool rasterizerDiscard, bool transformFeedbackActive);
     virtual void applyUniforms(const gl::ProgramBinary &programBinary);
-    virtual GLenum applyVertexBuffer(gl::ProgramBinary *programBinary, const gl::VertexAttribute vertexAttributes[], const gl::VertexAttribCurrentValueData currentValues[],
-                                     GLint first, GLsizei count, GLsizei instances);
-    virtual GLenum applyIndexBuffer(const GLvoid *indices, gl::Buffer *elementArrayBuffer, GLsizei count, GLenum mode, GLenum type, TranslatedIndexData *indexInfo);
+    virtual gl::Error applyVertexBuffer(gl::ProgramBinary *programBinary, const gl::VertexAttribute vertexAttributes[], const gl::VertexAttribCurrentValueData currentValues[],
+                                        GLint first, GLsizei count, GLsizei instances);
+    virtual gl::Error applyIndexBuffer(const GLvoid *indices, gl::Buffer *elementArrayBuffer, GLsizei count, GLenum mode, GLenum type, TranslatedIndexData *indexInfo);
     virtual void applyTransformFeedbackBuffers(gl::Buffer *transformFeedbackBuffers[], GLintptr offsets[]);
 
     virtual void drawArrays(GLenum mode, GLsizei count, GLsizei instances, bool transformFeedbackActive);
     virtual void drawElements(GLenum mode, GLsizei count, GLenum type, const GLvoid *indices,
                               gl::Buffer *elementArrayBuffer, const TranslatedIndexData &indexInfo, GLsizei instances);
 
-    virtual void clear(const gl::ClearParameters &clearParams, gl::Framebuffer *frameBuffer);
+    virtual gl::Error clear(const gl::ClearParameters &clearParams, gl::Framebuffer *frameBuffer);
 
     virtual void markAllStateDirty();
 
@@ -103,56 +103,48 @@
     virtual std::string getRendererDescription() const;
     virtual GUID getAdapterIdentifier() const;
 
-    virtual unsigned int getMaxVertexTextureImageUnits() const;
-    virtual unsigned int getMaxCombinedTextureImageUnits() const;
     virtual unsigned int getReservedVertexUniformVectors() const;
     virtual unsigned int getReservedFragmentUniformVectors() const;
-    virtual unsigned int getMaxVertexUniformVectors() const;
-    virtual unsigned int getMaxFragmentUniformVectors() const;
-    virtual unsigned int getMaxVaryingVectors() const;
-    virtual unsigned int getMaxVertexShaderUniformBuffers() const;
-    virtual unsigned int getMaxFragmentShaderUniformBuffers() const;
     virtual unsigned int getReservedVertexUniformBuffers() const;
     virtual unsigned int getReservedFragmentUniformBuffers() const;
-    unsigned int getReservedVaryings() const;
-    virtual unsigned int getMaxTransformFeedbackBuffers() const;
-    virtual unsigned int getMaxTransformFeedbackSeparateComponents() const;
-    virtual unsigned int getMaxTransformFeedbackInterleavedComponents() const;
-    virtual unsigned int getMaxUniformBufferSize() const;
     virtual bool getShareHandleSupport() const;
     virtual bool getPostSubBufferSupport() const;
-    virtual int getMaxRecommendedElementsIndices() const;
-    virtual int getMaxRecommendedElementsVertices() const;
 
     virtual int getMajorShaderModel() const;
     virtual int getMinSwapInterval() const;
     virtual int getMaxSwapInterval() const;
 
     // Pixel operations
-    virtual bool copyToRenderTarget(TextureStorageInterface2D *dest, TextureStorageInterface2D *source);
-    virtual bool copyToRenderTarget(TextureStorageInterfaceCube *dest, TextureStorageInterfaceCube *source);
-    virtual bool copyToRenderTarget(TextureStorageInterface3D *dest, TextureStorageInterface3D *source);
-    virtual bool copyToRenderTarget(TextureStorageInterface2DArray *dest, TextureStorageInterface2DArray *source);
+    virtual bool copyToRenderTarget2D(TextureStorage *dest, TextureStorage *source);
+    virtual bool copyToRenderTargetCube(TextureStorage *dest, TextureStorage *source);
+    virtual bool copyToRenderTarget3D(TextureStorage *dest, TextureStorage *source);
+    virtual bool copyToRenderTarget2DArray(TextureStorage *dest, TextureStorage *source);
 
-    virtual bool copyImage(gl::Framebuffer *framebuffer, const gl::Rectangle &sourceRect, GLenum destFormat,
-                           GLint xoffset, GLint yoffset, TextureStorageInterface2D *storage, GLint level);
-    virtual bool copyImage(gl::Framebuffer *framebuffer, const gl::Rectangle &sourceRect, GLenum destFormat,
-                           GLint xoffset, GLint yoffset, TextureStorageInterfaceCube *storage, GLenum target, GLint level);
-    virtual bool copyImage(gl::Framebuffer *framebuffer, const gl::Rectangle &sourceRect, GLenum destFormat,
-                           GLint xoffset, GLint yoffset, GLint zOffset, TextureStorageInterface3D *storage, GLint level);
-    virtual bool copyImage(gl::Framebuffer *framebuffer, const gl::Rectangle &sourceRect, GLenum destFormat,
-                           GLint xoffset, GLint yoffset, GLint zOffset, TextureStorageInterface2DArray *storage, GLint level);
+    virtual bool copyImage2D(gl::Framebuffer *framebuffer, const gl::Rectangle &sourceRect, GLenum destFormat,
+                             GLint xoffset, GLint yoffset, TextureStorage *storage, GLint level);
+    virtual bool copyImageCube(gl::Framebuffer *framebuffer, const gl::Rectangle &sourceRect, GLenum destFormat,
+                               GLint xoffset, GLint yoffset, TextureStorage *storage, GLenum target, GLint level);
+    virtual bool copyImage3D(gl::Framebuffer *framebuffer, const gl::Rectangle &sourceRect, GLenum destFormat,
+                             GLint xoffset, GLint yoffset, GLint zOffset, TextureStorage *storage, GLint level);
+    virtual bool copyImage2DArray(gl::Framebuffer *framebuffer, const gl::Rectangle &sourceRect, GLenum destFormat,
+                                  GLint xoffset, GLint yoffset, GLint zOffset, TextureStorage *storage, GLint level);
 
     virtual bool blitRect(gl::Framebuffer *readTarget, const gl::Rectangle &readRect, gl::Framebuffer *drawTarget, const gl::Rectangle &drawRect,
                           const gl::Rectangle *scissor, bool blitRenderTarget, bool blitDepth, bool blitStencil, GLenum filter);
-    virtual void readPixels(gl::Framebuffer *framebuffer, GLint x, GLint y, GLsizei width, GLsizei height, GLenum format,
-                            GLenum type, GLuint outputPitch, const gl::PixelPackState &pack, void* pixels);
+
+    virtual gl::Error readPixels(gl::Framebuffer *framebuffer, GLint x, GLint y, GLsizei width, GLsizei height, GLenum format,
+                                 GLenum type, GLuint outputPitch, const gl::PixelPackState &pack, uint8_t *pixels);
 
     // RenderTarget creation
     virtual RenderTarget *createRenderTarget(SwapChain *swapChain, bool depth);
     virtual RenderTarget *createRenderTarget(int width, int height, GLenum format, GLsizei samples);
 
+    // Shader creation
+    virtual ShaderImpl *createShader(GLenum type);
+    virtual ProgramImpl *createProgram();
+
     // Shader operations
+    virtual void releaseShaderCompiler();
     virtual ShaderExecutable *loadExecutable(const void *function, size_t length, rx::ShaderType type,
                                              const std::vector<gl::LinkedVarying> &transformFeedbackVaryings,
                                              bool separatedOutputBuffers);
@@ -171,10 +163,7 @@
     virtual TextureStorage *createTextureStorage2DArray(GLenum internalformat, bool renderTarget, GLsizei width, GLsizei height, GLsizei depth, int levels);
 
     // Texture creation
-    virtual Texture2DImpl *createTexture2D();
-    virtual TextureCubeImpl *createTextureCube();
-    virtual Texture3DImpl *createTexture3D();
-    virtual Texture2DArrayImpl *createTexture2DArray();
+    virtual TextureImpl *createTexture(GLenum target);
 
     // Buffer creation
     virtual BufferImpl *createBuffer();
@@ -188,6 +177,9 @@
     virtual QueryImpl *createQuery(GLenum type);
     virtual FenceImpl *createFence();
 
+    // Transform Feedback creation
+    virtual TransformFeedbackImpl* createTransformFeedback();
+
     // D3D11-renderer specific methods
     ID3D11Device *getDevice() { return mDevice; }
     ID3D11DeviceContext *getDeviceContext() { return mDeviceContext; };
@@ -203,7 +195,7 @@
     bool getRenderTargetResource(gl::FramebufferAttachment *colorbuffer, unsigned int *subresourceIndex, ID3D11Texture2D **resource);
     void unapplyRenderTargets();
     void setOneTimeRenderTarget(ID3D11RenderTargetView *renderTargetView);
-    void packPixels(ID3D11Texture2D *readTexture, const PackPixelsParams &params, void *pixelsOut);
+    void packPixels(ID3D11Texture2D *readTexture, const PackPixelsParams &params, uint8_t *pixelsOut);
 
     virtual bool getLUID(LUID *adapterLuid) const;
     virtual rx::VertexConversionType getVertexConversionType(const gl::VertexFormat &vertexFormat) const;
@@ -217,8 +209,8 @@
     void drawLineLoop(GLsizei count, GLenum type, const GLvoid *indices, int minIndex, gl::Buffer *elementArrayBuffer);
     void drawTriangleFan(GLsizei count, GLenum type, const GLvoid *indices, int minIndex, gl::Buffer *elementArrayBuffer, int instances);
 
-    void readTextureData(ID3D11Texture2D *texture, unsigned int subResource, const gl::Rectangle &area, GLenum format,
-                         GLenum type, GLuint outputPitch, const gl::PixelPackState &pack, void *pixels);
+    gl::Error readTextureData(ID3D11Texture2D *texture, unsigned int subResource, const gl::Rectangle &area, GLenum format,
+                              GLenum type, GLuint outputPitch, const gl::PixelPackState &pack, uint8_t *pixels);
 
     bool blitRenderbufferRect(const gl::Rectangle &readRect, const gl::Rectangle &drawRect, RenderTarget *readRenderTarget,
                               RenderTarget *drawRenderTarget, GLenum filter, const gl::Rectangle *scissor,
@@ -253,15 +245,15 @@
     rx::RenderTarget::Desc mRenderTargetDesc;
 
     // Currently applied sampler states
-    bool mForceSetVertexSamplerStates[gl::IMPLEMENTATION_MAX_VERTEX_TEXTURE_IMAGE_UNITS];
-    gl::SamplerState mCurVertexSamplerStates[gl::IMPLEMENTATION_MAX_VERTEX_TEXTURE_IMAGE_UNITS];
+    std::vector<bool> mForceSetVertexSamplerStates;
+    std::vector<gl::SamplerState> mCurVertexSamplerStates;
 
-    bool mForceSetPixelSamplerStates[gl::MAX_TEXTURE_IMAGE_UNITS];
-    gl::SamplerState mCurPixelSamplerStates[gl::MAX_TEXTURE_IMAGE_UNITS];
+    std::vector<bool> mForceSetPixelSamplerStates;
+    std::vector<gl::SamplerState> mCurPixelSamplerStates;
 
     // Currently applied textures
-    ID3D11ShaderResourceView *mCurVertexSRVs[gl::IMPLEMENTATION_MAX_VERTEX_TEXTURE_IMAGE_UNITS];
-    ID3D11ShaderResourceView *mCurPixelSRVs[gl::MAX_TEXTURE_IMAGE_UNITS];
+    std::vector<ID3D11ShaderResourceView*> mCurVertexSRVs;
+    std::vector<ID3D11ShaderResourceView*> mCurPixelSRVs;
 
     // Currently applied blend state
     bool mForceSetBlendState;
diff --git a/src/libGLESv2/renderer/d3d/d3d11/ShaderExecutable11.cpp b/src/libGLESv2/renderer/d3d/d3d11/ShaderExecutable11.cpp
index 5a7c987..52f3488 100644
--- a/src/libGLESv2/renderer/d3d/d3d11/ShaderExecutable11.cpp
+++ b/src/libGLESv2/renderer/d3d/d3d11/ShaderExecutable11.cpp
@@ -1,4 +1,3 @@
-#include "precompiled.h"
 //
 // Copyright (c) 2012-2014 The ANGLE Project Authors. All rights reserved.
 // Use of this source code is governed by a BSD-style license that can be
@@ -9,7 +8,6 @@
 // executable implementation details.
 
 #include "libGLESv2/renderer/d3d/d3d11/ShaderExecutable11.h"
-
 #include "libGLESv2/renderer/d3d/d3d11/Renderer11.h"
 
 namespace rx
diff --git a/src/libGLESv2/renderer/d3d/d3d11/SwapChain11.cpp b/src/libGLESv2/renderer/d3d/d3d11/SwapChain11.cpp
index f21c30c..5ec132e 100644
--- a/src/libGLESv2/renderer/d3d/d3d11/SwapChain11.cpp
+++ b/src/libGLESv2/renderer/d3d/d3d11/SwapChain11.cpp
@@ -1,4 +1,3 @@
-#include "precompiled.h"
 //
 // Copyright (c) 2012-2014 The ANGLE Project Authors. All rights reserved.
 // Use of this source code is governed by a BSD-style license that can be
@@ -8,10 +7,11 @@
 // SwapChain11.cpp: Implements a back-end specific class for the D3D11 swap chain.
 
 #include "libGLESv2/renderer/d3d/d3d11/SwapChain11.h"
-
 #include "libGLESv2/renderer/d3d/d3d11/renderer11_utils.h"
 #include "libGLESv2/renderer/d3d/d3d11/formatutils11.h"
 #include "libGLESv2/renderer/d3d/d3d11/Renderer11.h"
+
+// Precompiled shaders
 #include "libGLESv2/renderer/d3d/d3d11/shaders/compiled/passthrough2d11vs.h"
 #include "libGLESv2/renderer/d3d/d3d11/shaders/compiled/passthroughrgba2d11ps.h"
 
diff --git a/src/libGLESv2/renderer/d3d/d3d11/TextureStorage11.cpp b/src/libGLESv2/renderer/d3d/d3d11/TextureStorage11.cpp
index fb29c3a..c012637 100644
--- a/src/libGLESv2/renderer/d3d/d3d11/TextureStorage11.cpp
+++ b/src/libGLESv2/renderer/d3d/d3d11/TextureStorage11.cpp
@@ -1,4 +1,3 @@
-#include "precompiled.h"
 //
 // Copyright (c) 2012-2014 The ANGLE Project Authors. All rights reserved.
 // Use of this source code is governed by a BSD-style license that can be
@@ -9,17 +8,18 @@
 // classes TextureStorage11_2D and TextureStorage11_Cube, which act as the interface to the D3D11 texture.
 
 #include "libGLESv2/renderer/d3d/d3d11/TextureStorage11.h"
-
-#include "libGLESv2/renderer/d3d/TextureD3D.h"
 #include "libGLESv2/renderer/d3d/d3d11/Renderer11.h"
 #include "libGLESv2/renderer/d3d/d3d11/RenderTarget11.h"
 #include "libGLESv2/renderer/d3d/d3d11/SwapChain11.h"
 #include "libGLESv2/renderer/d3d/d3d11/renderer11_utils.h"
 #include "libGLESv2/renderer/d3d/d3d11/Blit11.h"
 #include "libGLESv2/renderer/d3d/d3d11/formatutils11.h"
+#include "libGLESv2/renderer/d3d/d3d11/Image11.h"
+#include "libGLESv2/renderer/d3d/TextureD3D.h"
+#include "libGLESv2/main.h"
+#include "libGLESv2/ImageIndex.h"
 
 #include "common/utilities.h"
-#include "libGLESv2/main.h"
 
 namespace rx
 {
@@ -196,7 +196,7 @@
 ID3D11ShaderResourceView *TextureStorage11::getSRV(const gl::SamplerState &samplerState)
 {
     bool swizzleRequired = samplerState.swizzleRequired();
-    bool mipmapping = IsMipmapFiltered(samplerState);
+    bool mipmapping = gl::IsMipmapFiltered(samplerState);
     unsigned int mipLevels = mipmapping ? (samplerState.maxLevel - samplerState.baseLevel) : 1;
 
     // Make sure there's 'mipLevels' mipmap levels below the base level (offset by the top level,  which corresponds to GL level 0)
@@ -342,6 +342,27 @@
     return false;
 }
 
+bool TextureStorage11::copySubresourceLevel(ID3D11Resource* dstTexture, unsigned int dstSubresource,
+                                            int level, int layerTarget, GLint xoffset, GLint yoffset, GLint zoffset,
+                                            GLsizei width, GLsizei height, GLsizei depth)
+{
+    if (dstTexture)
+    {
+        ID3D11Resource *srcTexture = getResource();
+        unsigned int srcSubresource = getSubresourceIndex(level + mTopLevel, layerTarget);
+
+        ASSERT(srcTexture);
+
+        ID3D11DeviceContext *context = mRenderer->getDeviceContext();
+
+        context->CopySubresourceRegion(dstTexture, dstSubresource, xoffset, yoffset, zoffset,
+                                       srcTexture, srcSubresource, NULL);
+        return true;
+    }
+
+    return false;
+}
+
 void TextureStorage11::generateMipmapLayer(RenderTarget11 *source, RenderTarget11 *dest)
 {
     if (source && dest)
@@ -375,14 +396,15 @@
 }
 
 TextureStorage11_2D::TextureStorage11_2D(Renderer *renderer, SwapChain11 *swapchain)
-    : TextureStorage11(renderer, D3D11_BIND_RENDER_TARGET | D3D11_BIND_SHADER_RESOURCE)
+    : TextureStorage11(renderer, D3D11_BIND_RENDER_TARGET | D3D11_BIND_SHADER_RESOURCE),
+      mTexture(swapchain->getOffscreenTexture()),
+      mSwizzleTexture(NULL)
 {
-    mTexture = swapchain->getOffscreenTexture();
     mTexture->AddRef();
-    mSwizzleTexture = NULL;
 
     for (unsigned int i = 0; i < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS; i++)
     {
+        mAssociatedImages[i] = NULL;
         mRenderTarget[i] = NULL;
         mSwizzleRenderTargets[i] = NULL;
     }
@@ -412,16 +434,18 @@
     mSwizzleRenderTargetFormat = formatInfo.swizzleRTVFormat;
 
     mDepthStencilFormat = DXGI_FORMAT_UNKNOWN;
+
+    initializeSerials(1, 1);
 }
 
 TextureStorage11_2D::TextureStorage11_2D(Renderer *renderer, GLenum internalformat, bool renderTarget, GLsizei width, GLsizei height, int levels)
-    : TextureStorage11(renderer, GetTextureBindFlags(internalformat, renderTarget))
+    : TextureStorage11(renderer, GetTextureBindFlags(internalformat, renderTarget)),
+      mTexture(NULL),
+      mSwizzleTexture(NULL)
 {
-    mTexture = NULL;
-    mSwizzleTexture = NULL;
-
     for (unsigned int i = 0; i < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS; i++)
     {
+        mAssociatedImages[i] = NULL;
         mRenderTarget[i] = NULL;
         mSwizzleRenderTargets[i] = NULL;
     }
@@ -480,10 +504,27 @@
             mTextureDepth = 1;
         }
     }
+
+    initializeSerials(getLevelCount(), 1);
 }
 
 TextureStorage11_2D::~TextureStorage11_2D()
 {
+    for (unsigned i = 0; i < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS; i++)
+    {
+        if (mAssociatedImages[i] != NULL)
+        {
+            bool imageAssociationCorrect = mAssociatedImages[i]->isAssociatedStorageValid(this);
+            ASSERT(imageAssociationCorrect);
+
+            if (imageAssociationCorrect)
+            {
+                // We must let the Images recover their data before we delete it from the TextureStorage.
+                mAssociatedImages[i]->recoverFromAssociatedStorage();
+            }
+        }
+    }
+
     SafeRelease(mTexture);
     SafeRelease(mSwizzleTexture);
 
@@ -500,13 +541,80 @@
     return static_cast<TextureStorage11_2D*>(storage);
 }
 
+void TextureStorage11_2D::associateImage(Image11* image, int level, int layerTarget)
+{
+    ASSERT(0 <= level && level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS);
+
+    if (0 <= level && level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS)
+    {
+        mAssociatedImages[level] = image;
+    }
+}
+
+bool TextureStorage11_2D::isAssociatedImageValid(int level, int layerTarget, Image11* expectedImage)
+{
+    if (0 <= level && level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS)
+    {
+        // This validation check should never return false. It means the Image/TextureStorage association is broken.
+        bool retValue = (mAssociatedImages[level] == expectedImage);
+        ASSERT(retValue);
+        return retValue;
+    }
+
+    return false;
+}
+
+// disassociateImage allows an Image to end its association with a Storage.
+void TextureStorage11_2D::disassociateImage(int level, int layerTarget, Image11* expectedImage)
+{
+    ASSERT(0 <= level && level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS);
+
+    if (0 <= level && level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS)
+    {
+        ASSERT(mAssociatedImages[level] == expectedImage);
+
+        if (mAssociatedImages[level] == expectedImage)
+        {
+            mAssociatedImages[level] = NULL;
+        }
+    }
+}
+
+// releaseAssociatedImage prepares the Storage for a new Image association. It lets the old Image recover its data before ending the association.
+void TextureStorage11_2D::releaseAssociatedImage(int level, int layerTarget, Image11* incomingImage)
+{
+    ASSERT(0 <= level && level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS);
+
+    if (0 <= level && level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS)
+    {
+        // No need to let the old Image recover its data, if it is also the incoming Image.
+        if (mAssociatedImages[level] != NULL && mAssociatedImages[level] != incomingImage)
+        {
+            // Ensure that the Image is still associated with this TextureStorage. This should be true.
+            bool imageAssociationCorrect = mAssociatedImages[level]->isAssociatedStorageValid(this);
+            ASSERT(imageAssociationCorrect);
+
+            if (imageAssociationCorrect)
+            {
+                // Force the image to recover from storage before its data is overwritten.
+                // This will reset mAssociatedImages[level] to NULL too.
+                mAssociatedImages[level]->recoverFromAssociatedStorage();
+            }
+        }
+    }
+}
+
 ID3D11Resource *TextureStorage11_2D::getResource() const
 {
     return mTexture;
 }
 
-RenderTarget *TextureStorage11_2D::getRenderTarget(int level)
+RenderTarget *TextureStorage11_2D::getRenderTarget(const gl::ImageIndex &index)
 {
+    ASSERT(!index.hasLayer());
+
+    int level = index.mipIndex;
+
     if (level >= 0 && level < getLevelCount())
     {
         if (!mRenderTarget[level])
@@ -601,14 +709,22 @@
     return SRV;
 }
 
-void TextureStorage11_2D::generateMipmap(int level)
+void TextureStorage11_2D::generateMipmaps()
 {
-    invalidateSwizzleCacheLevel(level);
+    // Base level must already be defined
 
-    RenderTarget11 *source = RenderTarget11::makeRenderTarget11(getRenderTarget(level - 1));
-    RenderTarget11 *dest = RenderTarget11::makeRenderTarget11(getRenderTarget(level));
+    for (int level = 1; level < getLevelCount(); level++)
+    {
+        invalidateSwizzleCacheLevel(level);
 
-    generateMipmapLayer(source, dest);
+        gl::ImageIndex srcIndex = gl::ImageIndex::Make2D(level - 1);
+        gl::ImageIndex destIndex = gl::ImageIndex::Make2D(level);
+
+        RenderTarget11 *source = RenderTarget11::makeRenderTarget11(getRenderTarget(srcIndex));
+        RenderTarget11 *dest = RenderTarget11::makeRenderTarget11(getRenderTarget(destIndex));
+
+        generateMipmapLayer(source, dest);
+    }
 }
 
 ID3D11Resource *TextureStorage11_2D::getSwizzleTexture()
@@ -677,11 +793,6 @@
     }
 }
 
-unsigned int TextureStorage11_2D::getTextureLevelDepth(int mipLevel) const
-{
-    return 1;
-}
-
 TextureStorage11_Cube::TextureStorage11_Cube(Renderer *renderer, GLenum internalformat, bool renderTarget, int size, int levels)
     : TextureStorage11(renderer, GetTextureBindFlags(internalformat, renderTarget))
 {
@@ -693,6 +804,7 @@
         mSwizzleRenderTargets[level] = NULL;
         for (unsigned int face = 0; face < 6; face++)
         {
+            mAssociatedImages[face][level] = NULL;
             mRenderTarget[face][level] = NULL;
         }
     }
@@ -746,10 +858,31 @@
             mTextureDepth = 1;
         }
     }
+
+    initializeSerials(getLevelCount() * 6, 6);
 }
 
+
 TextureStorage11_Cube::~TextureStorage11_Cube()
 {
+    for (unsigned int level = 0; level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS; level++)
+    {
+        for (unsigned int face = 0; face < 6; face++)
+        {
+            if (mAssociatedImages[face][level] != NULL)
+            {
+                bool imageAssociationCorrect = mAssociatedImages[face][level]->isAssociatedStorageValid(this);
+                ASSERT(imageAssociationCorrect);
+
+                if (imageAssociationCorrect)
+                {
+                    // We must let the Images recover their data before we delete it from the TextureStorage.
+                    mAssociatedImages[face][level]->recoverFromAssociatedStorage();
+                }
+            }
+        }
+    }
+
     SafeRelease(mTexture);
     SafeRelease(mSwizzleTexture);
 
@@ -769,16 +902,96 @@
     return static_cast<TextureStorage11_Cube*>(storage);
 }
 
+void TextureStorage11_Cube::associateImage(Image11* image, int level, int layerTarget)
+{
+    ASSERT(0 <= level && level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS);
+    ASSERT(0 <= layerTarget && layerTarget < 6);
+
+    if (0 <= level && level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS)
+    {
+        if (0 <= layerTarget && layerTarget < 6)
+        {
+            mAssociatedImages[layerTarget][level] = image;
+        }
+    }
+}
+
+bool TextureStorage11_Cube::isAssociatedImageValid(int level, int layerTarget, Image11* expectedImage)
+{
+    if (0 <= level && level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS)
+    {
+        if (0 <= layerTarget && layerTarget < 6)
+        {
+            // This validation check should never return false. It means the Image/TextureStorage association is broken.
+            bool retValue = (mAssociatedImages[layerTarget][level] == expectedImage);
+            ASSERT(retValue);
+            return retValue;
+        }
+    }
+
+    return false;
+}
+
+// disassociateImage allows an Image to end its association with a Storage.
+void TextureStorage11_Cube::disassociateImage(int level, int layerTarget, Image11* expectedImage)
+{
+    ASSERT(0 <= level && level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS);
+    ASSERT(0 <= layerTarget && layerTarget < 6);
+
+    if (0 <= level && level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS)
+    {
+        if (0 <= layerTarget && layerTarget < 6)
+        {
+            ASSERT(mAssociatedImages[layerTarget][level] == expectedImage);
+
+            if (mAssociatedImages[layerTarget][level] == expectedImage)
+            {
+                mAssociatedImages[layerTarget][level] = NULL;
+            }
+        }
+    }
+}
+
+// releaseAssociatedImage prepares the Storage for a new Image association. It lets the old Image recover its data before ending the association.
+void TextureStorage11_Cube::releaseAssociatedImage(int level, int layerTarget, Image11* incomingImage)
+{
+    ASSERT(0 <= level && level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS);
+    ASSERT(0 <= layerTarget && layerTarget < 6);
+
+    if ((0 <= level && level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS))
+    {
+        if (0 <= layerTarget && layerTarget < 6)
+        {
+            // No need to let the old Image recover its data, if it is also the incoming Image.
+            if (mAssociatedImages[layerTarget][level] != NULL && mAssociatedImages[layerTarget][level] != incomingImage)
+            {
+                // Ensure that the Image is still associated with this TextureStorage. This should be true.
+                bool imageAssociationCorrect = mAssociatedImages[layerTarget][level]->isAssociatedStorageValid(this);
+                ASSERT(imageAssociationCorrect);
+
+                if (imageAssociationCorrect)
+                {
+                    // Force the image to recover from storage before its data is overwritten.
+                    // This will reset mAssociatedImages[level] to NULL too.
+                    mAssociatedImages[layerTarget][level]->recoverFromAssociatedStorage();
+                }
+            }
+        }
+    }
+}
+
 ID3D11Resource *TextureStorage11_Cube::getResource() const
 {
     return mTexture;
 }
 
-RenderTarget *TextureStorage11_Cube::getRenderTargetFace(GLenum faceTarget, int level)
+RenderTarget *TextureStorage11_Cube::getRenderTarget(const gl::ImageIndex &index)
 {
+    int faceIndex = index.layerIndex;
+    int level = index.mipIndex;
+
     if (level >= 0 && level < getLevelCount())
     {
-        int faceIndex = gl::TextureCubeMap::targetToLayerIndex(faceTarget);
         if (!mRenderTarget[faceIndex][level])
         {
             ID3D11Device *device = mRenderer->getDevice();
@@ -902,14 +1115,25 @@
     return SRV;
 }
 
-void TextureStorage11_Cube::generateMipmap(int faceIndex, int level)
+void TextureStorage11_Cube::generateMipmaps()
 {
-    invalidateSwizzleCacheLevel(level);
+    // Base level must already be defined
 
-    RenderTarget11 *source = RenderTarget11::makeRenderTarget11(getRenderTargetFace(GL_TEXTURE_CUBE_MAP_POSITIVE_X + faceIndex, level - 1));
-    RenderTarget11 *dest = RenderTarget11::makeRenderTarget11(getRenderTargetFace(GL_TEXTURE_CUBE_MAP_POSITIVE_X + faceIndex, level));
+    for (int faceIndex = 0; faceIndex < 6; faceIndex++)
+    {
+        for (int level = 1; level < getLevelCount(); level++)
+        {
+            invalidateSwizzleCacheLevel(level);
 
-    generateMipmapLayer(source, dest);
+            gl::ImageIndex srcIndex = gl::ImageIndex::MakeCube(GL_TEXTURE_CUBE_MAP_POSITIVE_X + faceIndex, level - 1);
+            gl::ImageIndex destIndex = gl::ImageIndex::MakeCube(GL_TEXTURE_CUBE_MAP_POSITIVE_X + faceIndex, level);
+
+            RenderTarget11 *source = RenderTarget11::makeRenderTarget11(getRenderTarget(srcIndex));
+            RenderTarget11 *dest = RenderTarget11::makeRenderTarget11(getRenderTarget(destIndex));
+
+            generateMipmapLayer(source, dest);
+        }
+    }
 }
 
 ID3D11Resource *TextureStorage11_Cube::getSwizzleTexture()
@@ -981,11 +1205,6 @@
     }
 }
 
-unsigned int TextureStorage11_Cube::getTextureLevelDepth(int mipLevel) const
-{
-    return 6;
-}
-
 TextureStorage11_3D::TextureStorage11_3D(Renderer *renderer, GLenum internalformat, bool renderTarget,
                                          GLsizei width, GLsizei height, GLsizei depth, int levels)
     : TextureStorage11(renderer, GetTextureBindFlags(internalformat, renderTarget))
@@ -995,6 +1214,7 @@
 
     for (unsigned int i = 0; i < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS; i++)
     {
+        mAssociatedImages[i] = NULL;
         mLevelRenderTargets[i] = NULL;
         mSwizzleRenderTargets[i] = NULL;
     }
@@ -1051,10 +1271,27 @@
             mTextureDepth = desc.Depth;
         }
     }
+
+    initializeSerials(getLevelCount() * depth, depth);
 }
 
 TextureStorage11_3D::~TextureStorage11_3D()
 {
+    for (unsigned i = 0; i < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS; i++)
+    {
+        if (mAssociatedImages[i] != NULL)
+        {
+            bool imageAssociationCorrect = mAssociatedImages[i]->isAssociatedStorageValid(this);
+            ASSERT(imageAssociationCorrect);
+
+            if (imageAssociationCorrect)
+            {
+                // We must let the Images recover their data before we delete it from the TextureStorage.
+                mAssociatedImages[i]->recoverFromAssociatedStorage();
+            }
+        }
+    }
+
     SafeRelease(mTexture);
     SafeRelease(mSwizzleTexture);
 
@@ -1077,6 +1314,69 @@
     return static_cast<TextureStorage11_3D*>(storage);
 }
 
+void TextureStorage11_3D::associateImage(Image11* image, int level, int layerTarget)
+{
+    ASSERT(0 <= level && level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS);
+
+    if (0 <= level && level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS)
+    {
+        mAssociatedImages[level] = image;
+    }
+}
+
+bool TextureStorage11_3D::isAssociatedImageValid(int level, int layerTarget, Image11* expectedImage)
+{
+    if (0 <= level && level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS)
+    {
+        // This validation check should never return false. It means the Image/TextureStorage association is broken.
+        bool retValue = (mAssociatedImages[level] == expectedImage);
+        ASSERT(retValue);
+        return retValue;
+    }
+
+    return false;
+}
+
+// disassociateImage allows an Image to end its association with a Storage.
+void TextureStorage11_3D::disassociateImage(int level, int layerTarget, Image11* expectedImage)
+{
+    ASSERT(0 <= level && level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS);
+
+    if (0 <= level && level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS)
+    {
+        ASSERT(mAssociatedImages[level] == expectedImage);
+
+        if (mAssociatedImages[level] == expectedImage)
+        {
+            mAssociatedImages[level] = NULL;
+        }
+    }
+}
+
+// releaseAssociatedImage prepares the Storage for a new Image association. It lets the old Image recover its data before ending the association.
+void TextureStorage11_3D::releaseAssociatedImage(int level, int layerTarget, Image11* incomingImage)
+{
+    ASSERT((0 <= level && level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS));
+
+    if (0 <= level && level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS)
+    {
+        // No need to let the old Image recover its data, if it is also the incoming Image.
+        if (mAssociatedImages[level] != NULL && mAssociatedImages[level] != incomingImage)
+        {
+            // Ensure that the Image is still associated with this TextureStorage. This should be true.
+            bool imageAssociationCorrect = mAssociatedImages[level]->isAssociatedStorageValid(this);
+            ASSERT(imageAssociationCorrect);
+
+            if (imageAssociationCorrect)
+            {
+                // Force the image to recover from storage before its data is overwritten.
+                // This will reset mAssociatedImages[level] to NULL too.
+                mAssociatedImages[level]->recoverFromAssociatedStorage();
+            }
+        }
+    }
+}
+
 ID3D11Resource *TextureStorage11_3D::getResource() const
 {
     return mTexture;
@@ -1104,20 +1404,24 @@
     return SRV;
 }
 
-RenderTarget *TextureStorage11_3D::getRenderTarget(int mipLevel)
+RenderTarget *TextureStorage11_3D::getRenderTarget(const gl::ImageIndex &index)
 {
+    int mipLevel = index.mipIndex;
+
     if (mipLevel >= 0 && mipLevel < getLevelCount())
     {
-        if (!mLevelRenderTargets[mipLevel])
-        {
-            ID3D11ShaderResourceView *srv = getSRVLevel(mipLevel);
-            if (!srv)
-            {
-                return NULL;
-            }
+        ASSERT(mRenderTargetFormat != DXGI_FORMAT_UNKNOWN);
 
-            if (mRenderTargetFormat != DXGI_FORMAT_UNKNOWN)
+        if (!index.hasLayer())
+        {
+            if (!mLevelRenderTargets[mipLevel])
             {
+                ID3D11ShaderResourceView *srv = getSRVLevel(mipLevel);
+                if (!srv)
+                {
+                    return NULL;
+                }
+
                 ID3D11Device *device = mRenderer->getDevice();
 
                 D3D11_RENDER_TARGET_VIEW_DESC rtvDesc;
@@ -1142,35 +1446,22 @@
                 // RenderTarget will take ownership of these resources
                 SafeRelease(rtv);
             }
-            else
-            {
-                UNREACHABLE();
-            }
+
+            return mLevelRenderTargets[mipLevel];
         }
-
-        return mLevelRenderTargets[mipLevel];
-    }
-    else
-    {
-        return NULL;
-    }
-}
-
-RenderTarget *TextureStorage11_3D::getRenderTargetLayer(int mipLevel, int layer)
-{
-    if (mipLevel >= 0 && mipLevel < getLevelCount())
-    {
-        LevelLayerKey key(mipLevel, layer);
-        if (mLevelLayerRenderTargets.find(key) == mLevelLayerRenderTargets.end())
+        else
         {
-            ID3D11Device *device = mRenderer->getDevice();
-            HRESULT result;
+            int layer = index.layerIndex;
 
-            // TODO, what kind of SRV is expected here?
-            ID3D11ShaderResourceView *srv = NULL;
-
-            if (mRenderTargetFormat != DXGI_FORMAT_UNKNOWN)
+            LevelLayerKey key(mipLevel, layer);
+            if (mLevelLayerRenderTargets.find(key) == mLevelLayerRenderTargets.end())
             {
+                ID3D11Device *device = mRenderer->getDevice();
+                HRESULT result;
+
+                // TODO, what kind of SRV is expected here?
+                ID3D11ShaderResourceView *srv = NULL;
+
                 D3D11_RENDER_TARGET_VIEW_DESC rtvDesc;
                 rtvDesc.Format = mRenderTargetFormat;
                 rtvDesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE3D;
@@ -1194,28 +1485,30 @@
                 SafeRelease(rtv);
                 SafeRelease(srv);
             }
-            else
-            {
-                UNREACHABLE();
-            }
-        }
 
-        return mLevelLayerRenderTargets[key];
+            return mLevelLayerRenderTargets[key];
+        }
     }
-    else
-    {
-        return NULL;
-    }
+
+    return NULL;
 }
 
-void TextureStorage11_3D::generateMipmap(int level)
+void TextureStorage11_3D::generateMipmaps()
 {
-    invalidateSwizzleCacheLevel(level);
+    // Base level must already be defined
 
-    RenderTarget11 *source = RenderTarget11::makeRenderTarget11(getRenderTarget(level - 1));
-    RenderTarget11 *dest = RenderTarget11::makeRenderTarget11(getRenderTarget(level));
+    for (int level = 1; level < getLevelCount(); level++)
+    {
+        invalidateSwizzleCacheLevel(level);
 
-    generateMipmapLayer(source, dest);
+        gl::ImageIndex srcIndex = gl::ImageIndex::Make3D(level - 1);
+        gl::ImageIndex destIndex = gl::ImageIndex::Make3D(level);
+
+        RenderTarget11 *source = RenderTarget11::makeRenderTarget11(getRenderTarget(srcIndex));
+        RenderTarget11 *dest = RenderTarget11::makeRenderTarget11(getRenderTarget(destIndex));
+
+        generateMipmapLayer(source, dest);
+    }
 }
 
 ID3D11Resource *TextureStorage11_3D::getSwizzleTexture()
@@ -1285,12 +1578,6 @@
     }
 }
 
-unsigned int TextureStorage11_3D::getTextureLevelDepth(int mipLevel) const
-{
-    return std::max(mTextureDepth >> mipLevel, 1U);
-}
-
-
 TextureStorage11_2DArray::TextureStorage11_2DArray(Renderer *renderer, GLenum internalformat, bool renderTarget,
                                                    GLsizei width, GLsizei height, GLsizei depth, int levels)
     : TextureStorage11(renderer, GetTextureBindFlags(internalformat, renderTarget))
@@ -1357,10 +1644,25 @@
             mTextureDepth = desc.ArraySize;
         }
     }
+
+    initializeSerials(getLevelCount() * depth, depth);
 }
 
 TextureStorage11_2DArray::~TextureStorage11_2DArray()
 {
+    for (ImageMap::iterator i = mAssociatedImages.begin(); i != mAssociatedImages.end(); i++)
+    {
+        bool imageAssociationCorrect = i->second->isAssociatedStorageValid(this);
+        ASSERT(imageAssociationCorrect);
+
+        if (imageAssociationCorrect)
+        {
+            // We must let the Images recover their data before we delete it from the TextureStorage.
+            i->second->recoverFromAssociatedStorage();
+        }
+    }
+    mAssociatedImages.clear();
+
     SafeRelease(mTexture);
     SafeRelease(mSwizzleTexture);
 
@@ -1382,6 +1684,66 @@
     return static_cast<TextureStorage11_2DArray*>(storage);
 }
 
+void TextureStorage11_2DArray::associateImage(Image11* image, int level, int layerTarget)
+{
+    ASSERT(0 <= level && level < getLevelCount());
+
+    if (0 <= level && level < getLevelCount())
+    {
+        LevelLayerKey key(level, layerTarget);
+        mAssociatedImages[key] = image;
+    }
+}
+
+bool TextureStorage11_2DArray::isAssociatedImageValid(int level, int layerTarget, Image11* expectedImage)
+{
+    LevelLayerKey key(level, layerTarget);
+
+    // This validation check should never return false. It means the Image/TextureStorage association is broken.
+    bool retValue = (mAssociatedImages.find(key) != mAssociatedImages.end() && (mAssociatedImages[key] == expectedImage));
+    ASSERT(retValue);
+    return retValue;
+}
+
+// disassociateImage allows an Image to end its association with a Storage.
+void TextureStorage11_2DArray::disassociateImage(int level, int layerTarget, Image11* expectedImage)
+{
+    LevelLayerKey key(level, layerTarget);
+
+    bool imageAssociationCorrect = (mAssociatedImages.find(key) != mAssociatedImages.end() && (mAssociatedImages[key] == expectedImage));
+    ASSERT(imageAssociationCorrect);
+
+    if (imageAssociationCorrect)
+    {
+        mAssociatedImages[key] = NULL;
+    }
+}
+
+// releaseAssociatedImage prepares the Storage for a new Image association. It lets the old Image recover its data before ending the association.
+void TextureStorage11_2DArray::releaseAssociatedImage(int level, int layerTarget, Image11* incomingImage)
+{
+    LevelLayerKey key(level, layerTarget);
+
+    ASSERT(mAssociatedImages.find(key) != mAssociatedImages.end());
+
+    if (mAssociatedImages.find(key) != mAssociatedImages.end())
+    {
+        if (mAssociatedImages[key] != NULL && mAssociatedImages[key] != incomingImage)
+        {
+            // Ensure that the Image is still associated with this TextureStorage. This should be true.
+            bool imageAssociationCorrect = mAssociatedImages[key]->isAssociatedStorageValid(this);
+            ASSERT(imageAssociationCorrect);
+
+            if (imageAssociationCorrect)
+            {
+                // Force the image to recover from storage before its data is overwritten.
+                // This will reset mAssociatedImages[level] to NULL too.
+                mAssociatedImages[key]->recoverFromAssociatedStorage();
+            }
+        }
+    }
+}
+
 ID3D11Resource *TextureStorage11_2DArray::getResource() const
 {
     return mTexture;
@@ -1411,8 +1773,13 @@
     return SRV;
 }
 
-RenderTarget *TextureStorage11_2DArray::getRenderTargetLayer(int mipLevel, int layer)
+RenderTarget *TextureStorage11_2DArray::getRenderTarget(const gl::ImageIndex &index)
 {
+    ASSERT(index.hasLayer());
+
+    int mipLevel = index.mipIndex;
+    int layer = index.layerIndex;
+
     if (mipLevel >= 0 && mipLevel < getLevelCount())
     {
         LevelLayerKey key(mipLevel, layer);
@@ -1477,15 +1844,23 @@
     }
 }
 
-void TextureStorage11_2DArray::generateMipmap(int level)
+void TextureStorage11_2DArray::generateMipmaps()
 {
-    invalidateSwizzleCacheLevel(level);
-    for (unsigned int layer = 0; layer < mTextureDepth; layer++)
-    {
-        RenderTarget11 *source = RenderTarget11::makeRenderTarget11(getRenderTargetLayer(level - 1, layer));
-        RenderTarget11 *dest = RenderTarget11::makeRenderTarget11(getRenderTargetLayer(level, layer));
+    // Base level must already be defined
 
-        generateMipmapLayer(source, dest);
+    for (int level = 0; level < getLevelCount(); level++)
+    {
+        invalidateSwizzleCacheLevel(level);
+        for (unsigned int layer = 0; layer < mTextureDepth; layer++)
+        {
+            gl::ImageIndex sourceIndex = gl::ImageIndex::Make2DArray(level - 1, layer);
+            gl::ImageIndex destIndex = gl::ImageIndex::Make2DArray(level, layer);
+
+            RenderTarget11 *source = RenderTarget11::makeRenderTarget11(getRenderTarget(sourceIndex));
+            RenderTarget11 *dest = RenderTarget11::makeRenderTarget11(getRenderTarget(destIndex));
+
+            generateMipmapLayer(source, dest);
+        }
     }
 }
 
@@ -1558,9 +1933,4 @@
     }
 }
 
-unsigned int TextureStorage11_2DArray::getTextureLevelDepth(int mipLevel) const
-{
-    return mTextureDepth;
-}
-
 }
diff --git a/src/libGLESv2/renderer/d3d/d3d11/TextureStorage11.h b/src/libGLESv2/renderer/d3d/d3d11/TextureStorage11.h
index 6be7bac..da06aa6 100644
--- a/src/libGLESv2/renderer/d3d/d3d11/TextureStorage11.h
+++ b/src/libGLESv2/renderer/d3d/d3d11/TextureStorage11.h
@@ -13,6 +13,13 @@
 #include "libGLESv2/Texture.h"
 #include "libGLESv2/renderer/d3d/TextureStorage.h"
 
+#include <map>
+
+namespace gl
+{
+struct ImageIndex;
+}
+
 namespace rx
 {
 class RenderTarget;
@@ -20,6 +27,7 @@
 class Renderer;
 class Renderer11;
 class SwapChain11;
+class Image11;
 
 class TextureStorage11 : public TextureStorage
 {
@@ -34,12 +42,9 @@
 
     virtual ID3D11Resource *getResource() const = 0;
     virtual ID3D11ShaderResourceView *getSRV(const gl::SamplerState &samplerState);
-    virtual RenderTarget *getRenderTarget(int level) { return NULL; }
-    virtual RenderTarget *getRenderTargetFace(GLenum faceTarget, int level) { return NULL; }
-    virtual RenderTarget *getRenderTargetLayer(int mipLevel, int layer) { return NULL; }
+    virtual RenderTarget *getRenderTarget(const gl::ImageIndex &index) = 0;
 
-    virtual void generateMipmap(int level) {};
-    virtual void generateMipmap(int face, int level) {};
+    virtual void generateMipmaps() = 0;
 
     virtual int getTopLevel() const;
     virtual bool isRenderTarget() const;
@@ -55,6 +60,15 @@
                                 int layerTarget, GLint xoffset, GLint yoffset, GLint zoffset,
                                 GLsizei width, GLsizei height, GLsizei depth);
 
+    bool copySubresourceLevel(ID3D11Resource* dstTexture, unsigned int dstSubresource, int level,
+                              int layerTarget, GLint xoffset, GLint yoffset, GLint zoffset,
+                              GLsizei width, GLsizei height, GLsizei depth);
+
+    virtual void associateImage(Image11* image, int level, int layerTarget) = 0;
+    virtual void disassociateImage(int level, int layerTarget, Image11* expectedImage) = 0;
+    virtual bool isAssociatedImageValid(int level, int layerTarget, Image11* expectedImage) = 0;
+    virtual void releaseAssociatedImage(int level, int layerTarget, Image11* incomingImage) = 0;
+
   protected:
     TextureStorage11(Renderer *renderer, UINT bindFlags);
     void generateMipmapLayer(RenderTarget11 *source, RenderTarget11 *dest);
@@ -70,8 +84,6 @@
 
     void verifySwizzleExists(GLenum swizzleRed, GLenum swizzleGreen, GLenum swizzleBlue, GLenum swizzleAlpha);
 
-    virtual unsigned int getTextureLevelDepth(int mipLevel) const = 0;
-
     Renderer11 *mRenderer;
     int mTopLevel;
     unsigned int mMipLevels;
@@ -148,16 +160,19 @@
     static TextureStorage11_2D *makeTextureStorage11_2D(TextureStorage *storage);
 
     virtual ID3D11Resource *getResource() const;
-    virtual RenderTarget *getRenderTarget(int level);
+    virtual RenderTarget *getRenderTarget(const gl::ImageIndex &index);
 
-    virtual void generateMipmap(int level);
+    virtual void generateMipmaps();
+
+    virtual void associateImage(Image11* image, int level, int layerTarget);
+    virtual void disassociateImage(int level, int layerTarget, Image11* expectedImage);
+    virtual bool isAssociatedImageValid(int level, int layerTarget, Image11* expectedImage);
+    virtual void releaseAssociatedImage(int level, int layerTarget, Image11* incomingImage);
 
   protected:
     virtual ID3D11Resource *getSwizzleTexture();
     virtual ID3D11RenderTargetView *getSwizzleRenderTarget(int mipLevel);
 
-    virtual unsigned int getTextureLevelDepth(int mipLevel) const;
-
   private:
     DISALLOW_COPY_AND_ASSIGN(TextureStorage11_2D);
 
@@ -168,6 +183,8 @@
 
     ID3D11Texture2D *mSwizzleTexture;
     ID3D11RenderTargetView *mSwizzleRenderTargets[gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS];
+
+    Image11 *mAssociatedImages[gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS];
 };
 
 class TextureStorage11_Cube : public TextureStorage11
@@ -179,16 +196,19 @@
     static TextureStorage11_Cube *makeTextureStorage11_Cube(TextureStorage *storage);
 
     virtual ID3D11Resource *getResource() const;
-    virtual RenderTarget *getRenderTargetFace(GLenum faceTarget, int level);
+    virtual RenderTarget *getRenderTarget(const gl::ImageIndex &index);
 
-    virtual void generateMipmap(int faceIndex, int level);
+    virtual void generateMipmaps();
+
+    virtual void associateImage(Image11* image, int level, int layerTarget);
+    virtual void disassociateImage(int level, int layerTarget, Image11* expectedImage);
+    virtual bool isAssociatedImageValid(int level, int layerTarget, Image11* expectedImage);
+    virtual void releaseAssociatedImage(int level, int layerTarget, Image11* incomingImage);
 
   protected:
     virtual ID3D11Resource *getSwizzleTexture();
     virtual ID3D11RenderTargetView *getSwizzleRenderTarget(int mipLevel);
 
-    virtual unsigned int getTextureLevelDepth(int mipLevel) const;
-
   private:
     DISALLOW_COPY_AND_ASSIGN(TextureStorage11_Cube);
 
@@ -199,6 +219,8 @@
 
     ID3D11Texture2D *mSwizzleTexture;
     ID3D11RenderTargetView *mSwizzleRenderTargets[gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS];
+
+    Image11 *mAssociatedImages[6][gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS];
 };
 
 class TextureStorage11_3D : public TextureStorage11
@@ -211,17 +233,21 @@
     static TextureStorage11_3D *makeTextureStorage11_3D(TextureStorage *storage);
 
     virtual ID3D11Resource *getResource() const;
-    virtual RenderTarget *getRenderTarget(int mipLevel);
-    virtual RenderTarget *getRenderTargetLayer(int mipLevel, int layer);
 
-    virtual void generateMipmap(int level);
+    // Handles both layer and non-layer RTs
+    virtual RenderTarget *getRenderTarget(const gl::ImageIndex &index);
+
+    virtual void generateMipmaps();
+
+    virtual void associateImage(Image11* image, int level, int layerTarget);
+    virtual void disassociateImage(int level, int layerTarget, Image11* expectedImage);
+    virtual bool isAssociatedImageValid(int level, int layerTarget, Image11* expectedImage);
+    virtual void releaseAssociatedImage(int level, int layerTarget, Image11* incomingImage);
 
   protected:
     virtual ID3D11Resource *getSwizzleTexture();
     virtual ID3D11RenderTargetView *getSwizzleRenderTarget(int mipLevel);
 
-    virtual unsigned int getTextureLevelDepth(int mipLevel) const;
-
   private:
     DISALLOW_COPY_AND_ASSIGN(TextureStorage11_3D);
 
@@ -236,6 +262,8 @@
     ID3D11Texture3D *mTexture;
     ID3D11Texture3D *mSwizzleTexture;
     ID3D11RenderTargetView *mSwizzleRenderTargets[gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS];
+
+    Image11 *mAssociatedImages[gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS];
 };
 
 class TextureStorage11_2DArray : public TextureStorage11
@@ -248,16 +276,19 @@
     static TextureStorage11_2DArray *makeTextureStorage11_2DArray(TextureStorage *storage);
 
     virtual ID3D11Resource *getResource() const;
-    virtual RenderTarget *getRenderTargetLayer(int mipLevel, int layer);
+    virtual RenderTarget *getRenderTarget(const gl::ImageIndex &index);
 
-    virtual void generateMipmap(int level);
+    virtual void generateMipmaps();
+
+    virtual void associateImage(Image11* image, int level, int layerTarget);
+    virtual void disassociateImage(int level, int layerTarget, Image11* expectedImage);
+    virtual bool isAssociatedImageValid(int level, int layerTarget, Image11* expectedImage);
+    virtual void releaseAssociatedImage(int level, int layerTarget, Image11* incomingImage);
 
   protected:
     virtual ID3D11Resource *getSwizzleTexture();
     virtual ID3D11RenderTargetView *getSwizzleRenderTarget(int mipLevel);
 
-    virtual unsigned int getTextureLevelDepth(int mipLevel) const;
-
   private:
     DISALLOW_COPY_AND_ASSIGN(TextureStorage11_2DArray);
 
@@ -271,6 +302,9 @@
 
     ID3D11Texture2D *mSwizzleTexture;
     ID3D11RenderTargetView *mSwizzleRenderTargets[gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS];
+
+    typedef std::map<LevelLayerKey, Image11*> ImageMap;
+    ImageMap mAssociatedImages;
 };
 
 }
diff --git a/src/libGLESv2/renderer/d3d/d3d11/VertexBuffer11.cpp b/src/libGLESv2/renderer/d3d/d3d11/VertexBuffer11.cpp
index fb7e788..9bc5b1d 100644
--- a/src/libGLESv2/renderer/d3d/d3d11/VertexBuffer11.cpp
+++ b/src/libGLESv2/renderer/d3d/d3d11/VertexBuffer11.cpp
@@ -1,4 +1,3 @@
-#include "precompiled.h"
 //
 // 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
@@ -9,11 +8,10 @@
 
 #include "libGLESv2/renderer/d3d/d3d11/VertexBuffer11.h"
 #include "libGLESv2/renderer/d3d/d3d11/Buffer11.h"
-
-#include "libGLESv2/Buffer.h"
 #include "libGLESv2/renderer/d3d/d3d11/Renderer11.h"
-#include "libGLESv2/VertexAttribute.h"
 #include "libGLESv2/renderer/d3d/d3d11/formatutils11.h"
+#include "libGLESv2/Buffer.h"
+#include "libGLESv2/VertexAttribute.h"
 
 namespace rx
 {
@@ -30,7 +28,7 @@
     SafeRelease(mBuffer);
 }
 
-bool VertexBuffer11::initialize(unsigned int size, bool dynamicUsage)
+gl::Error VertexBuffer11::initialize(unsigned int size, bool dynamicUsage)
 {
     SafeRelease(mBuffer);
 
@@ -51,13 +49,14 @@
         HRESULT result = dxDevice->CreateBuffer(&bufferDesc, NULL, &mBuffer);
         if (FAILED(result))
         {
-            return false;
+            return gl::Error(GL_OUT_OF_MEMORY, "Failed to allocate internal vertex buffer of size, %lu.", size);
         }
     }
 
     mBufferSize = size;
     mDynamicUsage = dynamicUsage;
-    return true;
+
+    return gl::Error(GL_NO_ERROR);
 }
 
 VertexBuffer11 *VertexBuffer11::makeVertexBuffer11(VertexBuffer *vetexBuffer)
@@ -66,66 +65,62 @@
     return static_cast<VertexBuffer11*>(vetexBuffer);
 }
 
-bool VertexBuffer11::storeVertexAttributes(const gl::VertexAttribute &attrib, const gl::VertexAttribCurrentValueData &currentValue,
-                                           GLint start, GLsizei count, GLsizei instances, unsigned int offset)
+gl::Error VertexBuffer11::storeVertexAttributes(const gl::VertexAttribute &attrib, const gl::VertexAttribCurrentValueData &currentValue,
+                                                GLint start, GLsizei count, GLsizei instances, unsigned int offset)
 {
-    if (mBuffer)
+    if (!mBuffer)
     {
-        gl::Buffer *buffer = attrib.buffer.get();
-        int inputStride = ComputeVertexAttributeStride(attrib);
-        ID3D11DeviceContext *dxContext = mRenderer->getDeviceContext();
+        return gl::Error(GL_OUT_OF_MEMORY, "Internal vertex buffer is not initialized.");
+    }
 
-        D3D11_MAPPED_SUBRESOURCE mappedResource;
-        HRESULT result = dxContext->Map(mBuffer, 0, D3D11_MAP_WRITE_NO_OVERWRITE, 0, &mappedResource);
-        if (FAILED(result))
+    gl::Buffer *buffer = attrib.buffer.get();
+    int inputStride = ComputeVertexAttributeStride(attrib);
+    ID3D11DeviceContext *dxContext = mRenderer->getDeviceContext();
+
+    D3D11_MAPPED_SUBRESOURCE mappedResource;
+    HRESULT result = dxContext->Map(mBuffer, 0, D3D11_MAP_WRITE_NO_OVERWRITE, 0, &mappedResource);
+    if (FAILED(result))
+    {
+        return gl::Error(GL_OUT_OF_MEMORY, "Failed to map internal vertex buffer, HRESULT: 0x%08x.", result);
+    }
+
+    uint8_t *output = reinterpret_cast<uint8_t*>(mappedResource.pData) + offset;
+
+    const uint8_t *input = NULL;
+    if (attrib.enabled)
+    {
+        if (buffer)
         {
-            ERR("Vertex buffer map failed with error 0x%08x", result);
-            return false;
-        }
-
-        char* output = reinterpret_cast<char*>(mappedResource.pData) + offset;
-
-        const char *input = NULL;
-        if (attrib.enabled)
-        {
-            if (buffer)
-            {
-                Buffer11 *storage = Buffer11::makeBuffer11(buffer->getImplementation());
-                input = static_cast<const char*>(storage->getData()) + static_cast<int>(attrib.offset);
-            }
-            else
-            {
-                input = static_cast<const char*>(attrib.pointer);
-            }
+            Buffer11 *storage = Buffer11::makeBuffer11(buffer->getImplementation());
+            input = static_cast<const uint8_t*>(storage->getData()) + static_cast<int>(attrib.offset);
         }
         else
         {
-            input = reinterpret_cast<const char*>(currentValue.FloatValues);
+            input = static_cast<const uint8_t*>(attrib.pointer);
         }
-
-        if (instances == 0 || attrib.divisor == 0)
-        {
-            input += inputStride * start;
-        }
-
-        gl::VertexFormat vertexFormat(attrib, currentValue.Type);
-        const d3d11::VertexFormat &vertexFormatInfo = d3d11::GetVertexFormatInfo(vertexFormat);
-        ASSERT(vertexFormatInfo.copyFunction != NULL);
-        vertexFormatInfo.copyFunction(input, inputStride, count, output);
-
-        dxContext->Unmap(mBuffer, 0);
-
-        return true;
     }
     else
     {
-        ERR("Vertex buffer not initialized.");
-        return false;
+        input = reinterpret_cast<const uint8_t*>(currentValue.FloatValues);
     }
+
+    if (instances == 0 || attrib.divisor == 0)
+    {
+        input += inputStride * start;
+    }
+
+    gl::VertexFormat vertexFormat(attrib, currentValue.Type);
+    const d3d11::VertexFormat &vertexFormatInfo = d3d11::GetVertexFormatInfo(vertexFormat);
+    ASSERT(vertexFormatInfo.copyFunction != NULL);
+    vertexFormatInfo.copyFunction(input, inputStride, count, output);
+
+    dxContext->Unmap(mBuffer, 0);
+
+    return gl::Error(GL_NO_ERROR);
 }
 
-bool VertexBuffer11::getSpaceRequired(const gl::VertexAttribute &attrib, GLsizei count,
-                                      GLsizei instances, unsigned int *outSpaceRequired) const
+gl::Error VertexBuffer11::getSpaceRequired(const gl::VertexAttribute &attrib, GLsizei count,
+                                           GLsizei instances, unsigned int *outSpaceRequired) const
 {
     unsigned int elementCount = 0;
     if (attrib.enabled)
@@ -150,11 +145,11 @@
             {
                 *outSpaceRequired = elementSize * elementCount;
             }
-            return true;
+            return gl::Error(GL_NO_ERROR);
         }
         else
         {
-            return false;
+            return gl::Error(GL_OUT_OF_MEMORY, "New vertex buffer size would result in an overflow.");
         }
     }
     else
@@ -164,7 +159,7 @@
         {
             *outSpaceRequired = elementSize * 4;
         }
-        return true;
+        return gl::Error(GL_NO_ERROR);
     }
 }
 
@@ -173,7 +168,7 @@
     return mBufferSize;
 }
 
-bool VertexBuffer11::setBufferSize(unsigned int size)
+gl::Error VertexBuffer11::setBufferSize(unsigned int size)
 {
     if (size > mBufferSize)
     {
@@ -181,33 +176,29 @@
     }
     else
     {
-        return true;
+        return gl::Error(GL_NO_ERROR);
     }
 }
 
-bool VertexBuffer11::discard()
+gl::Error VertexBuffer11::discard()
 {
-    if (mBuffer)
+    if (!mBuffer)
     {
-        ID3D11DeviceContext *dxContext = mRenderer->getDeviceContext();
-
-        D3D11_MAPPED_SUBRESOURCE mappedResource;
-        HRESULT result = dxContext->Map(mBuffer, 0, D3D11_MAP_WRITE_DISCARD, 0, &mappedResource);
-        if (FAILED(result))
-        {
-            ERR("Vertex buffer map failed with error 0x%08x", result);
-            return false;
-        }
-
-        dxContext->Unmap(mBuffer, 0);
-
-        return true;
+        return gl::Error(GL_OUT_OF_MEMORY, "Internal vertex buffer is not initialized.");
     }
-    else
+
+    ID3D11DeviceContext *dxContext = mRenderer->getDeviceContext();
+
+    D3D11_MAPPED_SUBRESOURCE mappedResource;
+    HRESULT result = dxContext->Map(mBuffer, 0, D3D11_MAP_WRITE_DISCARD, 0, &mappedResource);
+    if (FAILED(result))
     {
-        ERR("Vertex buffer not initialized.");
-        return false;
+        return gl::Error(GL_OUT_OF_MEMORY, "Failed to map internal buffer for discarding, HRESULT: 0x%08x", result);
     }
+
+    dxContext->Unmap(mBuffer, 0);
+
+    return gl::Error(GL_NO_ERROR);
 }
 
 ID3D11Buffer *VertexBuffer11::getBuffer() const
diff --git a/src/libGLESv2/renderer/d3d/d3d11/VertexBuffer11.h b/src/libGLESv2/renderer/d3d/d3d11/VertexBuffer11.h
index c2a5aa7..0e10da1 100644
--- a/src/libGLESv2/renderer/d3d/d3d11/VertexBuffer11.h
+++ b/src/libGLESv2/renderer/d3d/d3d11/VertexBuffer11.h
@@ -21,19 +21,19 @@
     explicit VertexBuffer11(rx::Renderer11 *const renderer);
     virtual ~VertexBuffer11();
 
-    virtual bool initialize(unsigned int size, bool dynamicUsage);
+    virtual gl::Error initialize(unsigned int size, bool dynamicUsage);
 
     static VertexBuffer11 *makeVertexBuffer11(VertexBuffer *vetexBuffer);
 
-    virtual bool storeVertexAttributes(const gl::VertexAttribute &attrib, const gl::VertexAttribCurrentValueData &currentValue,
-                                       GLint start, GLsizei count, GLsizei instances, unsigned int offset);
+    virtual gl::Error storeVertexAttributes(const gl::VertexAttribute &attrib, const gl::VertexAttribCurrentValueData &currentValue,
+                                            GLint start, GLsizei count, GLsizei instances, unsigned int offset);
 
-    virtual bool getSpaceRequired(const gl::VertexAttribute &attrib, GLsizei count, GLsizei instances,
-                                  unsigned int *outSpaceRequired) const;
+    virtual gl::Error getSpaceRequired(const gl::VertexAttribute &attrib, GLsizei count, GLsizei instances,
+                                       unsigned int *outSpaceRequired) const;
 
     virtual unsigned int getBufferSize() const;
-    virtual bool setBufferSize(unsigned int size);
-    virtual bool discard();
+    virtual gl::Error setBufferSize(unsigned int size);
+    virtual gl::Error discard();
 
     ID3D11Buffer *getBuffer() const;
 
diff --git a/src/libGLESv2/renderer/d3d/d3d11/formatutils11.cpp b/src/libGLESv2/renderer/d3d/d3d11/formatutils11.cpp
index 23e427a..1ea916d 100644
--- a/src/libGLESv2/renderer/d3d/d3d11/formatutils11.cpp
+++ b/src/libGLESv2/renderer/d3d/d3d11/formatutils11.cpp
@@ -1,4 +1,3 @@
-#include "precompiled.h"
 //
 // Copyright (c) 2013-2014 The ANGLE Project Authors. All rights reserved.
 // Use of this source code is governed by a BSD-style license that can be
@@ -123,7 +122,7 @@
 {
     D3D11FastCopyMap map;
 
-    map.insert(std::make_pair(DXGI_FORMAT_B8G8R8A8_UNORM, D3D11FastCopyFormat(GL_RGBA, GL_UNSIGNED_BYTE, CopyBGRAUByteToRGBAUByte)));
+    map.insert(std::make_pair(DXGI_FORMAT_B8G8R8A8_UNORM, D3D11FastCopyFormat(GL_RGBA, GL_UNSIGNED_BYTE, CopyBGRA8ToRGBA8)));
 
     return map;
 }
@@ -658,43 +657,54 @@
 
     // Compute the swizzle formats
     const gl::InternalFormat &formatInfo = gl::GetInternalFormatInfo(internalFormat);
-    if (internalFormat != GL_NONE && (formatInfo.componentCount == 4 || texFormat == DXGI_FORMAT_UNKNOWN ||
-                                      srvFormat == DXGI_FORMAT_UNKNOWN || rtvFormat == DXGI_FORMAT_UNKNOWN))
+    if (internalFormat != GL_NONE && formatInfo.pixelBytes > 0)
     {
-        // Get the maximum sized component
-        unsigned int maxBits = 1;
-        if (formatInfo.compressed)
+        if (formatInfo.componentCount != 4 || texFormat == DXGI_FORMAT_UNKNOWN ||
+            srvFormat == DXGI_FORMAT_UNKNOWN || rtvFormat == DXGI_FORMAT_UNKNOWN)
         {
-            unsigned int compressedBitsPerBlock = formatInfo.pixelBytes * 8;
-            unsigned int blockSize = formatInfo.compressedBlockWidth * formatInfo.compressedBlockHeight;
-            maxBits = std::max(compressedBitsPerBlock / blockSize, maxBits);
+            // Get the maximum sized component
+            unsigned int maxBits = 1;
+            if (formatInfo.compressed)
+            {
+                unsigned int compressedBitsPerBlock = formatInfo.pixelBytes * 8;
+                unsigned int blockSize = formatInfo.compressedBlockWidth * formatInfo.compressedBlockHeight;
+                maxBits = std::max(compressedBitsPerBlock / blockSize, maxBits);
+            }
+            else
+            {
+                maxBits = std::max(maxBits, formatInfo.alphaBits);
+                maxBits = std::max(maxBits, formatInfo.redBits);
+                maxBits = std::max(maxBits, formatInfo.greenBits);
+                maxBits = std::max(maxBits, formatInfo.blueBits);
+                maxBits = std::max(maxBits, formatInfo.luminanceBits);
+                maxBits = std::max(maxBits, formatInfo.depthBits);
+            }
+
+            maxBits = roundUp(maxBits, 8U);
+
+            static const SwizzleInfoMap swizzleMap = BuildSwizzleInfoMap();
+            SwizzleInfoMap::const_iterator swizzleIter = swizzleMap.find(SwizzleSizeType(maxBits, formatInfo.componentType));
+            ASSERT(swizzleIter != swizzleMap.end());
+
+            const SwizzleFormatInfo &swizzleInfo = swizzleIter->second;
+            info.swizzleTexFormat = swizzleInfo.mTexFormat;
+            info.swizzleSRVFormat = swizzleInfo.mSRVFormat;
+            info.swizzleRTVFormat = swizzleInfo.mRTVFormat;
         }
         else
         {
-            maxBits = std::max(maxBits, formatInfo.alphaBits);
-            maxBits = std::max(maxBits, formatInfo.redBits);
-            maxBits = std::max(maxBits, formatInfo.greenBits);
-            maxBits = std::max(maxBits, formatInfo.blueBits);
-            maxBits = std::max(maxBits, formatInfo.luminanceBits);
-            maxBits = std::max(maxBits, formatInfo.depthBits);
+            // The original texture format is suitable for swizzle operations
+            info.swizzleTexFormat = texFormat;
+            info.swizzleSRVFormat = srvFormat;
+            info.swizzleRTVFormat = rtvFormat;
         }
-
-        maxBits = roundUp(maxBits, 8U);
-
-        static const SwizzleInfoMap swizzleMap = BuildSwizzleInfoMap();
-        SwizzleInfoMap::const_iterator swizzleIter = swizzleMap.find(SwizzleSizeType(maxBits, formatInfo.componentType));
-        ASSERT(swizzleIter != swizzleMap.end());
-
-        const SwizzleFormatInfo &swizzleInfo = swizzleIter->second;
-        info.swizzleTexFormat = swizzleInfo.mTexFormat;
-        info.swizzleSRVFormat = swizzleInfo.mSRVFormat;
-        info.swizzleRTVFormat = swizzleInfo.mRTVFormat;
     }
     else
     {
-        info.swizzleTexFormat = texFormat;
-        info.swizzleSRVFormat = srvFormat;
-        info.swizzleRTVFormat = rtvFormat;
+        // Not possible to swizzle with this texture format since it is either unsized or GL_NONE
+        info.swizzleTexFormat = DXGI_FORMAT_UNKNOWN;
+        info.swizzleSRVFormat = DXGI_FORMAT_UNKNOWN;
+        info.swizzleRTVFormat = DXGI_FORMAT_UNKNOWN;
     }
 
     // Check if there is an initialization function for this texture format
@@ -898,148 +908,148 @@
     //
 
     // GL_BYTE -- un-normalized
-    AddVertexFormatInfo(&map, GL_BYTE,           GL_FALSE, 1, VERTEX_CONVERT_GPU,  DXGI_FORMAT_R8_SINT,            &copyVertexData<GLbyte, 1, 0>);
-    AddVertexFormatInfo(&map, GL_BYTE,           GL_FALSE, 2, VERTEX_CONVERT_GPU,  DXGI_FORMAT_R8G8_SINT,          &copyVertexData<GLbyte, 2, 0>);
-    AddVertexFormatInfo(&map, GL_BYTE,           GL_FALSE, 3, VERTEX_CONVERT_BOTH, DXGI_FORMAT_R8G8B8A8_SINT,      &copyVertexData<GLbyte, 3, 1>);
-    AddVertexFormatInfo(&map, GL_BYTE,           GL_FALSE, 4, VERTEX_CONVERT_GPU,  DXGI_FORMAT_R8G8B8A8_SINT,      &copyVertexData<GLbyte, 4, 0>);
+    AddVertexFormatInfo(&map, GL_BYTE,           GL_FALSE, 1, VERTEX_CONVERT_GPU,  DXGI_FORMAT_R8_SINT,            &CopyNativeVertexData<GLbyte, 1, 0>);
+    AddVertexFormatInfo(&map, GL_BYTE,           GL_FALSE, 2, VERTEX_CONVERT_GPU,  DXGI_FORMAT_R8G8_SINT,          &CopyNativeVertexData<GLbyte, 2, 0>);
+    AddVertexFormatInfo(&map, GL_BYTE,           GL_FALSE, 3, VERTEX_CONVERT_BOTH, DXGI_FORMAT_R8G8B8A8_SINT,      &CopyNativeVertexData<GLbyte, 3, 1>);
+    AddVertexFormatInfo(&map, GL_BYTE,           GL_FALSE, 4, VERTEX_CONVERT_GPU,  DXGI_FORMAT_R8G8B8A8_SINT,      &CopyNativeVertexData<GLbyte, 4, 0>);
 
     // GL_BYTE -- normalized
-    AddVertexFormatInfo(&map, GL_BYTE,           GL_TRUE,  1, VERTEX_CONVERT_NONE, DXGI_FORMAT_R8_SNORM,           &copyVertexData<GLbyte, 1, 0>);
-    AddVertexFormatInfo(&map, GL_BYTE,           GL_TRUE,  2, VERTEX_CONVERT_NONE, DXGI_FORMAT_R8G8_SNORM,         &copyVertexData<GLbyte, 2, 0>);
-    AddVertexFormatInfo(&map, GL_BYTE,           GL_TRUE,  3, VERTEX_CONVERT_CPU,  DXGI_FORMAT_R8G8B8A8_SNORM,     &copyVertexData<GLbyte, 3, INT8_MAX>);
-    AddVertexFormatInfo(&map, GL_BYTE,           GL_TRUE,  4, VERTEX_CONVERT_NONE, DXGI_FORMAT_R8G8B8A8_SNORM,     &copyVertexData<GLbyte, 4, 0>);
+    AddVertexFormatInfo(&map, GL_BYTE,           GL_TRUE,  1, VERTEX_CONVERT_NONE, DXGI_FORMAT_R8_SNORM,           &CopyNativeVertexData<GLbyte, 1, 0>);
+    AddVertexFormatInfo(&map, GL_BYTE,           GL_TRUE,  2, VERTEX_CONVERT_NONE, DXGI_FORMAT_R8G8_SNORM,         &CopyNativeVertexData<GLbyte, 2, 0>);
+    AddVertexFormatInfo(&map, GL_BYTE,           GL_TRUE,  3, VERTEX_CONVERT_CPU,  DXGI_FORMAT_R8G8B8A8_SNORM,     &CopyNativeVertexData<GLbyte, 3, INT8_MAX>);
+    AddVertexFormatInfo(&map, GL_BYTE,           GL_TRUE,  4, VERTEX_CONVERT_NONE, DXGI_FORMAT_R8G8B8A8_SNORM,     &CopyNativeVertexData<GLbyte, 4, 0>);
 
     // GL_UNSIGNED_BYTE -- un-normalized
-    AddVertexFormatInfo(&map, GL_UNSIGNED_BYTE,  GL_FALSE, 1, VERTEX_CONVERT_GPU,  DXGI_FORMAT_R8_UINT,            &copyVertexData<GLubyte, 1, 0>);
-    AddVertexFormatInfo(&map, GL_UNSIGNED_BYTE,  GL_FALSE, 2, VERTEX_CONVERT_GPU,  DXGI_FORMAT_R8G8_UINT,          &copyVertexData<GLubyte, 2, 0>);
-    AddVertexFormatInfo(&map, GL_UNSIGNED_BYTE,  GL_FALSE, 3, VERTEX_CONVERT_BOTH, DXGI_FORMAT_R8G8B8A8_UINT,      &copyVertexData<GLubyte, 3, 1>);
-    AddVertexFormatInfo(&map, GL_UNSIGNED_BYTE,  GL_FALSE, 4, VERTEX_CONVERT_GPU,  DXGI_FORMAT_R8G8B8A8_UINT,      &copyVertexData<GLubyte, 4, 0>);
+    AddVertexFormatInfo(&map, GL_UNSIGNED_BYTE,  GL_FALSE, 1, VERTEX_CONVERT_GPU,  DXGI_FORMAT_R8_UINT,            &CopyNativeVertexData<GLubyte, 1, 0>);
+    AddVertexFormatInfo(&map, GL_UNSIGNED_BYTE,  GL_FALSE, 2, VERTEX_CONVERT_GPU,  DXGI_FORMAT_R8G8_UINT,          &CopyNativeVertexData<GLubyte, 2, 0>);
+    AddVertexFormatInfo(&map, GL_UNSIGNED_BYTE,  GL_FALSE, 3, VERTEX_CONVERT_BOTH, DXGI_FORMAT_R8G8B8A8_UINT,      &CopyNativeVertexData<GLubyte, 3, 1>);
+    AddVertexFormatInfo(&map, GL_UNSIGNED_BYTE,  GL_FALSE, 4, VERTEX_CONVERT_GPU,  DXGI_FORMAT_R8G8B8A8_UINT,      &CopyNativeVertexData<GLubyte, 4, 0>);
 
     // GL_UNSIGNED_BYTE -- normalized
-    AddVertexFormatInfo(&map, GL_UNSIGNED_BYTE,  GL_TRUE,  1, VERTEX_CONVERT_NONE, DXGI_FORMAT_R8_UNORM,           &copyVertexData<GLubyte, 1, 0>);
-    AddVertexFormatInfo(&map, GL_UNSIGNED_BYTE,  GL_TRUE,  2, VERTEX_CONVERT_NONE, DXGI_FORMAT_R8G8_UNORM,         &copyVertexData<GLubyte, 2, 0>);
-    AddVertexFormatInfo(&map, GL_UNSIGNED_BYTE,  GL_TRUE,  3, VERTEX_CONVERT_CPU,  DXGI_FORMAT_R8G8B8A8_UNORM,     &copyVertexData<GLubyte, 3, UINT8_MAX>);
-    AddVertexFormatInfo(&map, GL_UNSIGNED_BYTE,  GL_TRUE,  4, VERTEX_CONVERT_NONE, DXGI_FORMAT_R8G8B8A8_UNORM,     &copyVertexData<GLubyte, 4, 0>);
+    AddVertexFormatInfo(&map, GL_UNSIGNED_BYTE,  GL_TRUE,  1, VERTEX_CONVERT_NONE, DXGI_FORMAT_R8_UNORM,           &CopyNativeVertexData<GLubyte, 1, 0>);
+    AddVertexFormatInfo(&map, GL_UNSIGNED_BYTE,  GL_TRUE,  2, VERTEX_CONVERT_NONE, DXGI_FORMAT_R8G8_UNORM,         &CopyNativeVertexData<GLubyte, 2, 0>);
+    AddVertexFormatInfo(&map, GL_UNSIGNED_BYTE,  GL_TRUE,  3, VERTEX_CONVERT_CPU,  DXGI_FORMAT_R8G8B8A8_UNORM,     &CopyNativeVertexData<GLubyte, 3, UINT8_MAX>);
+    AddVertexFormatInfo(&map, GL_UNSIGNED_BYTE,  GL_TRUE,  4, VERTEX_CONVERT_NONE, DXGI_FORMAT_R8G8B8A8_UNORM,     &CopyNativeVertexData<GLubyte, 4, 0>);
 
     // GL_SHORT -- un-normalized
-    AddVertexFormatInfo(&map, GL_SHORT,          GL_FALSE, 1, VERTEX_CONVERT_GPU,  DXGI_FORMAT_R16_SINT,           &copyVertexData<GLshort, 1, 0>);
-    AddVertexFormatInfo(&map, GL_SHORT,          GL_FALSE, 2, VERTEX_CONVERT_GPU,  DXGI_FORMAT_R16G16_SINT,        &copyVertexData<GLshort, 2, 0>);
-    AddVertexFormatInfo(&map, GL_SHORT,          GL_FALSE, 3, VERTEX_CONVERT_BOTH, DXGI_FORMAT_R16G16B16A16_SINT,  &copyVertexData<GLshort, 4, 1>);
-    AddVertexFormatInfo(&map, GL_SHORT,          GL_FALSE, 4, VERTEX_CONVERT_GPU,  DXGI_FORMAT_R16G16B16A16_SINT,  &copyVertexData<GLshort, 4, 0>);
+    AddVertexFormatInfo(&map, GL_SHORT,          GL_FALSE, 1, VERTEX_CONVERT_GPU,  DXGI_FORMAT_R16_SINT,           &CopyNativeVertexData<GLshort, 1, 0>);
+    AddVertexFormatInfo(&map, GL_SHORT,          GL_FALSE, 2, VERTEX_CONVERT_GPU,  DXGI_FORMAT_R16G16_SINT,        &CopyNativeVertexData<GLshort, 2, 0>);
+    AddVertexFormatInfo(&map, GL_SHORT,          GL_FALSE, 3, VERTEX_CONVERT_BOTH, DXGI_FORMAT_R16G16B16A16_SINT,  &CopyNativeVertexData<GLshort, 4, 1>);
+    AddVertexFormatInfo(&map, GL_SHORT,          GL_FALSE, 4, VERTEX_CONVERT_GPU,  DXGI_FORMAT_R16G16B16A16_SINT,  &CopyNativeVertexData<GLshort, 4, 0>);
 
     // GL_SHORT -- normalized
-    AddVertexFormatInfo(&map, GL_SHORT,          GL_TRUE,  1, VERTEX_CONVERT_NONE, DXGI_FORMAT_R16_SNORM,          &copyVertexData<GLshort, 1, 0>);
-    AddVertexFormatInfo(&map, GL_SHORT,          GL_TRUE,  2, VERTEX_CONVERT_NONE, DXGI_FORMAT_R16G16_SNORM,       &copyVertexData<GLshort, 2, 0>);
-    AddVertexFormatInfo(&map, GL_SHORT,          GL_TRUE,  3, VERTEX_CONVERT_CPU,  DXGI_FORMAT_R16G16B16A16_SNORM, &copyVertexData<GLshort, 3, INT16_MAX>);
-    AddVertexFormatInfo(&map, GL_SHORT,          GL_TRUE,  4, VERTEX_CONVERT_NONE, DXGI_FORMAT_R16G16B16A16_SNORM, &copyVertexData<GLshort, 4, 0>);
+    AddVertexFormatInfo(&map, GL_SHORT,          GL_TRUE,  1, VERTEX_CONVERT_NONE, DXGI_FORMAT_R16_SNORM,          &CopyNativeVertexData<GLshort, 1, 0>);
+    AddVertexFormatInfo(&map, GL_SHORT,          GL_TRUE,  2, VERTEX_CONVERT_NONE, DXGI_FORMAT_R16G16_SNORM,       &CopyNativeVertexData<GLshort, 2, 0>);
+    AddVertexFormatInfo(&map, GL_SHORT,          GL_TRUE,  3, VERTEX_CONVERT_CPU,  DXGI_FORMAT_R16G16B16A16_SNORM, &CopyNativeVertexData<GLshort, 3, INT16_MAX>);
+    AddVertexFormatInfo(&map, GL_SHORT,          GL_TRUE,  4, VERTEX_CONVERT_NONE, DXGI_FORMAT_R16G16B16A16_SNORM, &CopyNativeVertexData<GLshort, 4, 0>);
 
     // GL_UNSIGNED_SHORT -- un-normalized
-    AddVertexFormatInfo(&map, GL_UNSIGNED_SHORT, GL_FALSE, 1, VERTEX_CONVERT_GPU,  DXGI_FORMAT_R16_UINT,           &copyVertexData<GLushort, 1, 0>);
-    AddVertexFormatInfo(&map, GL_UNSIGNED_SHORT, GL_FALSE, 2, VERTEX_CONVERT_GPU,  DXGI_FORMAT_R16G16_UINT,        &copyVertexData<GLushort, 2, 0>);
-    AddVertexFormatInfo(&map, GL_UNSIGNED_SHORT, GL_FALSE, 3, VERTEX_CONVERT_BOTH, DXGI_FORMAT_R16G16B16A16_UINT,  &copyVertexData<GLushort, 3, 1>);
-    AddVertexFormatInfo(&map, GL_UNSIGNED_SHORT, GL_FALSE, 4, VERTEX_CONVERT_GPU,  DXGI_FORMAT_R16G16B16A16_UINT,  &copyVertexData<GLushort, 4, 0>);
+    AddVertexFormatInfo(&map, GL_UNSIGNED_SHORT, GL_FALSE, 1, VERTEX_CONVERT_GPU,  DXGI_FORMAT_R16_UINT,           &CopyNativeVertexData<GLushort, 1, 0>);
+    AddVertexFormatInfo(&map, GL_UNSIGNED_SHORT, GL_FALSE, 2, VERTEX_CONVERT_GPU,  DXGI_FORMAT_R16G16_UINT,        &CopyNativeVertexData<GLushort, 2, 0>);
+    AddVertexFormatInfo(&map, GL_UNSIGNED_SHORT, GL_FALSE, 3, VERTEX_CONVERT_BOTH, DXGI_FORMAT_R16G16B16A16_UINT,  &CopyNativeVertexData<GLushort, 3, 1>);
+    AddVertexFormatInfo(&map, GL_UNSIGNED_SHORT, GL_FALSE, 4, VERTEX_CONVERT_GPU,  DXGI_FORMAT_R16G16B16A16_UINT,  &CopyNativeVertexData<GLushort, 4, 0>);
 
     // GL_UNSIGNED_SHORT -- normalized
-    AddVertexFormatInfo(&map, GL_UNSIGNED_SHORT, GL_TRUE,  1, VERTEX_CONVERT_NONE, DXGI_FORMAT_R16_UNORM,          &copyVertexData<GLushort, 1, 0>);
-    AddVertexFormatInfo(&map, GL_UNSIGNED_SHORT, GL_TRUE,  2, VERTEX_CONVERT_NONE, DXGI_FORMAT_R16G16_UNORM,       &copyVertexData<GLushort, 2, 0>);
-    AddVertexFormatInfo(&map, GL_UNSIGNED_SHORT, GL_TRUE,  3, VERTEX_CONVERT_CPU,  DXGI_FORMAT_R16G16B16A16_UNORM, &copyVertexData<GLushort, 3, UINT16_MAX>);
-    AddVertexFormatInfo(&map, GL_UNSIGNED_SHORT, GL_TRUE,  4, VERTEX_CONVERT_NONE, DXGI_FORMAT_R16G16B16A16_UNORM, &copyVertexData<GLushort, 4, 0>);
+    AddVertexFormatInfo(&map, GL_UNSIGNED_SHORT, GL_TRUE,  1, VERTEX_CONVERT_NONE, DXGI_FORMAT_R16_UNORM,          &CopyNativeVertexData<GLushort, 1, 0>);
+    AddVertexFormatInfo(&map, GL_UNSIGNED_SHORT, GL_TRUE,  2, VERTEX_CONVERT_NONE, DXGI_FORMAT_R16G16_UNORM,       &CopyNativeVertexData<GLushort, 2, 0>);
+    AddVertexFormatInfo(&map, GL_UNSIGNED_SHORT, GL_TRUE,  3, VERTEX_CONVERT_CPU,  DXGI_FORMAT_R16G16B16A16_UNORM, &CopyNativeVertexData<GLushort, 3, UINT16_MAX>);
+    AddVertexFormatInfo(&map, GL_UNSIGNED_SHORT, GL_TRUE,  4, VERTEX_CONVERT_NONE, DXGI_FORMAT_R16G16B16A16_UNORM, &CopyNativeVertexData<GLushort, 4, 0>);
 
     // GL_INT -- un-normalized
-    AddVertexFormatInfo(&map, GL_INT,            GL_FALSE, 1, VERTEX_CONVERT_GPU,  DXGI_FORMAT_R32_SINT,           &copyVertexData<GLint, 1, 0>);
-    AddVertexFormatInfo(&map, GL_INT,            GL_FALSE, 2, VERTEX_CONVERT_GPU,  DXGI_FORMAT_R32G32_SINT,        &copyVertexData<GLint, 2, 0>);
-    AddVertexFormatInfo(&map, GL_INT,            GL_FALSE, 3, VERTEX_CONVERT_GPU,  DXGI_FORMAT_R32G32B32_SINT,     &copyVertexData<GLint, 3, 0>);
-    AddVertexFormatInfo(&map, GL_INT,            GL_FALSE, 4, VERTEX_CONVERT_GPU,  DXGI_FORMAT_R32G32B32A32_SINT,  &copyVertexData<GLint, 4, 0>);
+    AddVertexFormatInfo(&map, GL_INT,            GL_FALSE, 1, VERTEX_CONVERT_GPU,  DXGI_FORMAT_R32_SINT,           &CopyNativeVertexData<GLint, 1, 0>);
+    AddVertexFormatInfo(&map, GL_INT,            GL_FALSE, 2, VERTEX_CONVERT_GPU,  DXGI_FORMAT_R32G32_SINT,        &CopyNativeVertexData<GLint, 2, 0>);
+    AddVertexFormatInfo(&map, GL_INT,            GL_FALSE, 3, VERTEX_CONVERT_GPU,  DXGI_FORMAT_R32G32B32_SINT,     &CopyNativeVertexData<GLint, 3, 0>);
+    AddVertexFormatInfo(&map, GL_INT,            GL_FALSE, 4, VERTEX_CONVERT_GPU,  DXGI_FORMAT_R32G32B32A32_SINT,  &CopyNativeVertexData<GLint, 4, 0>);
 
     // GL_INT -- normalized
-    AddVertexFormatInfo(&map, GL_INT,            GL_TRUE,  1, VERTEX_CONVERT_CPU,  DXGI_FORMAT_R32_FLOAT,          &copyToFloatVertexData<GLint, 1, true>);
-    AddVertexFormatInfo(&map, GL_INT,            GL_TRUE,  2, VERTEX_CONVERT_CPU,  DXGI_FORMAT_R32G32_FLOAT,       &copyToFloatVertexData<GLint, 2, true>);
-    AddVertexFormatInfo(&map, GL_INT,            GL_TRUE,  3, VERTEX_CONVERT_CPU,  DXGI_FORMAT_R32G32B32_FLOAT,    &copyToFloatVertexData<GLint, 3, true>);
-    AddVertexFormatInfo(&map, GL_INT,            GL_TRUE,  4, VERTEX_CONVERT_CPU,  DXGI_FORMAT_R32G32B32A32_FLOAT, &copyToFloatVertexData<GLint, 4, true>);
+    AddVertexFormatInfo(&map, GL_INT,            GL_TRUE,  1, VERTEX_CONVERT_CPU,  DXGI_FORMAT_R32_FLOAT,          &CopyTo32FVertexData<GLint, 1, true>);
+    AddVertexFormatInfo(&map, GL_INT,            GL_TRUE,  2, VERTEX_CONVERT_CPU,  DXGI_FORMAT_R32G32_FLOAT,       &CopyTo32FVertexData<GLint, 2, true>);
+    AddVertexFormatInfo(&map, GL_INT,            GL_TRUE,  3, VERTEX_CONVERT_CPU,  DXGI_FORMAT_R32G32B32_FLOAT,    &CopyTo32FVertexData<GLint, 3, true>);
+    AddVertexFormatInfo(&map, GL_INT,            GL_TRUE,  4, VERTEX_CONVERT_CPU,  DXGI_FORMAT_R32G32B32A32_FLOAT, &CopyTo32FVertexData<GLint, 4, true>);
 
     // GL_UNSIGNED_INT -- un-normalized
-    AddVertexFormatInfo(&map, GL_UNSIGNED_INT,   GL_FALSE, 1, VERTEX_CONVERT_GPU,  DXGI_FORMAT_R32_UINT,           &copyVertexData<GLuint, 1, 0>);
-    AddVertexFormatInfo(&map, GL_UNSIGNED_INT,   GL_FALSE, 2, VERTEX_CONVERT_GPU,  DXGI_FORMAT_R32G32_UINT,        &copyVertexData<GLuint, 2, 0>);
-    AddVertexFormatInfo(&map, GL_UNSIGNED_INT,   GL_FALSE, 3, VERTEX_CONVERT_GPU,  DXGI_FORMAT_R32G32B32_UINT,     &copyVertexData<GLuint, 3, 0>);
-    AddVertexFormatInfo(&map, GL_UNSIGNED_INT,   GL_FALSE, 4, VERTEX_CONVERT_GPU,  DXGI_FORMAT_R32G32B32A32_UINT,  &copyVertexData<GLuint, 4, 0>);
+    AddVertexFormatInfo(&map, GL_UNSIGNED_INT,   GL_FALSE, 1, VERTEX_CONVERT_GPU,  DXGI_FORMAT_R32_UINT,           &CopyNativeVertexData<GLuint, 1, 0>);
+    AddVertexFormatInfo(&map, GL_UNSIGNED_INT,   GL_FALSE, 2, VERTEX_CONVERT_GPU,  DXGI_FORMAT_R32G32_UINT,        &CopyNativeVertexData<GLuint, 2, 0>);
+    AddVertexFormatInfo(&map, GL_UNSIGNED_INT,   GL_FALSE, 3, VERTEX_CONVERT_GPU,  DXGI_FORMAT_R32G32B32_UINT,     &CopyNativeVertexData<GLuint, 3, 0>);
+    AddVertexFormatInfo(&map, GL_UNSIGNED_INT,   GL_FALSE, 4, VERTEX_CONVERT_GPU,  DXGI_FORMAT_R32G32B32A32_UINT,  &CopyNativeVertexData<GLuint, 4, 0>);
 
     // GL_UNSIGNED_INT -- normalized
-    AddVertexFormatInfo(&map, GL_UNSIGNED_INT,   GL_TRUE,  1, VERTEX_CONVERT_NONE, DXGI_FORMAT_R32_FLOAT,          &copyToFloatVertexData<GLuint, 1, true>);
-    AddVertexFormatInfo(&map, GL_UNSIGNED_INT,   GL_TRUE,  2, VERTEX_CONVERT_NONE, DXGI_FORMAT_R32G32_FLOAT,       &copyToFloatVertexData<GLuint, 2, true>);
-    AddVertexFormatInfo(&map, GL_UNSIGNED_INT,   GL_TRUE,  3, VERTEX_CONVERT_CPU,  DXGI_FORMAT_R32G32B32_FLOAT,    &copyToFloatVertexData<GLuint, 3, true>);
-    AddVertexFormatInfo(&map, GL_UNSIGNED_INT,   GL_TRUE,  4, VERTEX_CONVERT_NONE, DXGI_FORMAT_R32G32B32A32_FLOAT, &copyToFloatVertexData<GLuint, 4, true>);
+    AddVertexFormatInfo(&map, GL_UNSIGNED_INT,   GL_TRUE,  1, VERTEX_CONVERT_NONE, DXGI_FORMAT_R32_FLOAT,          &CopyTo32FVertexData<GLuint, 1, true>);
+    AddVertexFormatInfo(&map, GL_UNSIGNED_INT,   GL_TRUE,  2, VERTEX_CONVERT_NONE, DXGI_FORMAT_R32G32_FLOAT,       &CopyTo32FVertexData<GLuint, 2, true>);
+    AddVertexFormatInfo(&map, GL_UNSIGNED_INT,   GL_TRUE,  3, VERTEX_CONVERT_CPU,  DXGI_FORMAT_R32G32B32_FLOAT,    &CopyTo32FVertexData<GLuint, 3, true>);
+    AddVertexFormatInfo(&map, GL_UNSIGNED_INT,   GL_TRUE,  4, VERTEX_CONVERT_NONE, DXGI_FORMAT_R32G32B32A32_FLOAT, &CopyTo32FVertexData<GLuint, 4, true>);
 
     // GL_FIXED
-    AddVertexFormatInfo(&map, GL_FIXED,          GL_FALSE, 1, VERTEX_CONVERT_CPU,  DXGI_FORMAT_R32_FLOAT,          &copyFixedVertexData<1>);
-    AddVertexFormatInfo(&map, GL_FIXED,          GL_FALSE, 2, VERTEX_CONVERT_CPU,  DXGI_FORMAT_R32G32_FLOAT,       &copyFixedVertexData<2>);
-    AddVertexFormatInfo(&map, GL_FIXED,          GL_FALSE, 3, VERTEX_CONVERT_CPU,  DXGI_FORMAT_R32G32B32_FLOAT,    &copyFixedVertexData<3>);
-    AddVertexFormatInfo(&map, GL_FIXED,          GL_FALSE, 4, VERTEX_CONVERT_CPU,  DXGI_FORMAT_R32G32B32A32_FLOAT, &copyFixedVertexData<4>);
+    AddVertexFormatInfo(&map, GL_FIXED,          GL_FALSE, 1, VERTEX_CONVERT_CPU,  DXGI_FORMAT_R32_FLOAT,          &Copy32FixedTo32FVertexData<1>);
+    AddVertexFormatInfo(&map, GL_FIXED,          GL_FALSE, 2, VERTEX_CONVERT_CPU,  DXGI_FORMAT_R32G32_FLOAT,       &Copy32FixedTo32FVertexData<2>);
+    AddVertexFormatInfo(&map, GL_FIXED,          GL_FALSE, 3, VERTEX_CONVERT_CPU,  DXGI_FORMAT_R32G32B32_FLOAT,    &Copy32FixedTo32FVertexData<3>);
+    AddVertexFormatInfo(&map, GL_FIXED,          GL_FALSE, 4, VERTEX_CONVERT_CPU,  DXGI_FORMAT_R32G32B32A32_FLOAT, &Copy32FixedTo32FVertexData<4>);
 
     // GL_HALF_FLOAT
-    AddVertexFormatInfo(&map, GL_HALF_FLOAT,     GL_FALSE, 1, VERTEX_CONVERT_NONE, DXGI_FORMAT_R16_FLOAT,          &copyVertexData<GLhalf, 1, 0>);
-    AddVertexFormatInfo(&map, GL_HALF_FLOAT,     GL_FALSE, 2, VERTEX_CONVERT_NONE, DXGI_FORMAT_R16G16_FLOAT,       &copyVertexData<GLhalf, 2, 0>);
-    AddVertexFormatInfo(&map, GL_HALF_FLOAT,     GL_FALSE, 3, VERTEX_CONVERT_CPU,  DXGI_FORMAT_R16G16B16A16_FLOAT, &copyVertexData<GLhalf, 3, gl::Float16One>);
-    AddVertexFormatInfo(&map, GL_HALF_FLOAT,     GL_FALSE, 4, VERTEX_CONVERT_NONE, DXGI_FORMAT_R16G16B16A16_FLOAT, &copyVertexData<GLhalf, 4, 0>);
+    AddVertexFormatInfo(&map, GL_HALF_FLOAT,     GL_FALSE, 1, VERTEX_CONVERT_NONE, DXGI_FORMAT_R16_FLOAT,          &CopyNativeVertexData<GLhalf, 1, 0>);
+    AddVertexFormatInfo(&map, GL_HALF_FLOAT,     GL_FALSE, 2, VERTEX_CONVERT_NONE, DXGI_FORMAT_R16G16_FLOAT,       &CopyNativeVertexData<GLhalf, 2, 0>);
+    AddVertexFormatInfo(&map, GL_HALF_FLOAT,     GL_FALSE, 3, VERTEX_CONVERT_CPU,  DXGI_FORMAT_R16G16B16A16_FLOAT, &CopyNativeVertexData<GLhalf, 3, gl::Float16One>);
+    AddVertexFormatInfo(&map, GL_HALF_FLOAT,     GL_FALSE, 4, VERTEX_CONVERT_NONE, DXGI_FORMAT_R16G16B16A16_FLOAT, &CopyNativeVertexData<GLhalf, 4, 0>);
 
     // GL_FLOAT
-    AddVertexFormatInfo(&map, GL_FLOAT,          GL_FALSE, 1, VERTEX_CONVERT_NONE, DXGI_FORMAT_R32_FLOAT,          &copyVertexData<GLfloat, 1, 0>);
-    AddVertexFormatInfo(&map, GL_FLOAT,          GL_FALSE, 2, VERTEX_CONVERT_NONE, DXGI_FORMAT_R32G32_FLOAT,       &copyVertexData<GLfloat, 2, 0>);
-    AddVertexFormatInfo(&map, GL_FLOAT,          GL_FALSE, 3, VERTEX_CONVERT_NONE, DXGI_FORMAT_R32G32B32_FLOAT,    &copyVertexData<GLfloat, 3, 0>);
-    AddVertexFormatInfo(&map, GL_FLOAT,          GL_FALSE, 4, VERTEX_CONVERT_NONE, DXGI_FORMAT_R32G32B32A32_FLOAT, &copyVertexData<GLfloat, 4, 0>);
+    AddVertexFormatInfo(&map, GL_FLOAT,          GL_FALSE, 1, VERTEX_CONVERT_NONE, DXGI_FORMAT_R32_FLOAT,          &CopyNativeVertexData<GLfloat, 1, 0>);
+    AddVertexFormatInfo(&map, GL_FLOAT,          GL_FALSE, 2, VERTEX_CONVERT_NONE, DXGI_FORMAT_R32G32_FLOAT,       &CopyNativeVertexData<GLfloat, 2, 0>);
+    AddVertexFormatInfo(&map, GL_FLOAT,          GL_FALSE, 3, VERTEX_CONVERT_NONE, DXGI_FORMAT_R32G32B32_FLOAT,    &CopyNativeVertexData<GLfloat, 3, 0>);
+    AddVertexFormatInfo(&map, GL_FLOAT,          GL_FALSE, 4, VERTEX_CONVERT_NONE, DXGI_FORMAT_R32G32B32A32_FLOAT, &CopyNativeVertexData<GLfloat, 4, 0>);
 
     // GL_INT_2_10_10_10_REV
-    AddVertexFormatInfo(&map, GL_INT_2_10_10_10_REV,          GL_FALSE,  4, VERTEX_CONVERT_CPU,  DXGI_FORMAT_R32G32B32A32_FLOAT, &copyPackedVertexData<true, false, true>);
-    AddVertexFormatInfo(&map, GL_INT_2_10_10_10_REV,          GL_TRUE,   4, VERTEX_CONVERT_CPU,  DXGI_FORMAT_R32G32B32A32_FLOAT, &copyPackedVertexData<true, true,  true>);
+    AddVertexFormatInfo(&map, GL_INT_2_10_10_10_REV,          GL_FALSE,  4, VERTEX_CONVERT_CPU,  DXGI_FORMAT_R32G32B32A32_FLOAT, &CopyXYZ10W2ToXYZW32FVertexData<true, false, true>);
+    AddVertexFormatInfo(&map, GL_INT_2_10_10_10_REV,          GL_TRUE,   4, VERTEX_CONVERT_CPU,  DXGI_FORMAT_R32G32B32A32_FLOAT, &CopyXYZ10W2ToXYZW32FVertexData<true, true,  true>);
 
     // GL_UNSIGNED_INT_2_10_10_10_REV
-    AddVertexFormatInfo(&map, GL_UNSIGNED_INT_2_10_10_10_REV, GL_FALSE,  4, VERTEX_CONVERT_CPU,  DXGI_FORMAT_R32G32B32A32_FLOAT, &copyPackedVertexData<false, false, true>);
-    AddVertexFormatInfo(&map, GL_UNSIGNED_INT_2_10_10_10_REV, GL_TRUE,   4, VERTEX_CONVERT_NONE, DXGI_FORMAT_R10G10B10A2_UNORM,  &copyPackedUnsignedVertexData);
+    AddVertexFormatInfo(&map, GL_UNSIGNED_INT_2_10_10_10_REV, GL_FALSE,  4, VERTEX_CONVERT_CPU,  DXGI_FORMAT_R32G32B32A32_FLOAT, &CopyXYZ10W2ToXYZW32FVertexData<false, false, true>);
+    AddVertexFormatInfo(&map, GL_UNSIGNED_INT_2_10_10_10_REV, GL_TRUE,   4, VERTEX_CONVERT_NONE, DXGI_FORMAT_R10G10B10A2_UNORM,  &CopyNativeVertexData<GLuint, 1, 0>);
 
     //
     // Integer Formats
     //
 
     // GL_BYTE
-    AddIntegerVertexFormatInfo(&map, GL_BYTE,           1, VERTEX_CONVERT_NONE,  DXGI_FORMAT_R8_SINT,           &copyVertexData<GLbyte, 1, 0>);
-    AddIntegerVertexFormatInfo(&map, GL_BYTE,           2, VERTEX_CONVERT_NONE,  DXGI_FORMAT_R8G8_SINT,         &copyVertexData<GLbyte, 2, 0>);
-    AddIntegerVertexFormatInfo(&map, GL_BYTE,           3, VERTEX_CONVERT_CPU,   DXGI_FORMAT_R8G8B8A8_SINT,     &copyVertexData<GLbyte, 3, 1>);
-    AddIntegerVertexFormatInfo(&map, GL_BYTE,           4, VERTEX_CONVERT_NONE,  DXGI_FORMAT_R8G8B8A8_SINT,     &copyVertexData<GLbyte, 4, 0>);
+    AddIntegerVertexFormatInfo(&map, GL_BYTE,           1, VERTEX_CONVERT_NONE,  DXGI_FORMAT_R8_SINT,           &CopyNativeVertexData<GLbyte, 1, 0>);
+    AddIntegerVertexFormatInfo(&map, GL_BYTE,           2, VERTEX_CONVERT_NONE,  DXGI_FORMAT_R8G8_SINT,         &CopyNativeVertexData<GLbyte, 2, 0>);
+    AddIntegerVertexFormatInfo(&map, GL_BYTE,           3, VERTEX_CONVERT_CPU,   DXGI_FORMAT_R8G8B8A8_SINT,     &CopyNativeVertexData<GLbyte, 3, 1>);
+    AddIntegerVertexFormatInfo(&map, GL_BYTE,           4, VERTEX_CONVERT_NONE,  DXGI_FORMAT_R8G8B8A8_SINT,     &CopyNativeVertexData<GLbyte, 4, 0>);
 
     // GL_UNSIGNED_BYTE
-    AddIntegerVertexFormatInfo(&map, GL_UNSIGNED_BYTE,  1, VERTEX_CONVERT_NONE,  DXGI_FORMAT_R8_UINT,           &copyVertexData<GLubyte, 1, 0>);
-    AddIntegerVertexFormatInfo(&map, GL_UNSIGNED_BYTE,  2, VERTEX_CONVERT_NONE,  DXGI_FORMAT_R8G8_UINT,         &copyVertexData<GLubyte, 2, 0>);
-    AddIntegerVertexFormatInfo(&map, GL_UNSIGNED_BYTE,  3, VERTEX_CONVERT_CPU,   DXGI_FORMAT_R8G8B8A8_UINT,     &copyVertexData<GLubyte, 3, 1>);
-    AddIntegerVertexFormatInfo(&map, GL_UNSIGNED_BYTE,  4, VERTEX_CONVERT_NONE,  DXGI_FORMAT_R8G8B8A8_UINT,     &copyVertexData<GLubyte, 4, 0>);
+    AddIntegerVertexFormatInfo(&map, GL_UNSIGNED_BYTE,  1, VERTEX_CONVERT_NONE,  DXGI_FORMAT_R8_UINT,           &CopyNativeVertexData<GLubyte, 1, 0>);
+    AddIntegerVertexFormatInfo(&map, GL_UNSIGNED_BYTE,  2, VERTEX_CONVERT_NONE,  DXGI_FORMAT_R8G8_UINT,         &CopyNativeVertexData<GLubyte, 2, 0>);
+    AddIntegerVertexFormatInfo(&map, GL_UNSIGNED_BYTE,  3, VERTEX_CONVERT_CPU,   DXGI_FORMAT_R8G8B8A8_UINT,     &CopyNativeVertexData<GLubyte, 3, 1>);
+    AddIntegerVertexFormatInfo(&map, GL_UNSIGNED_BYTE,  4, VERTEX_CONVERT_NONE,  DXGI_FORMAT_R8G8B8A8_UINT,     &CopyNativeVertexData<GLubyte, 4, 0>);
 
     // GL_SHORT
-    AddIntegerVertexFormatInfo(&map, GL_SHORT,          1, VERTEX_CONVERT_NONE,  DXGI_FORMAT_R16_SINT,          &copyVertexData<GLshort, 1, 0>);
-    AddIntegerVertexFormatInfo(&map, GL_SHORT,          2, VERTEX_CONVERT_NONE,  DXGI_FORMAT_R16G16_SINT,       &copyVertexData<GLshort, 2, 0>);
-    AddIntegerVertexFormatInfo(&map, GL_SHORT,          3, VERTEX_CONVERT_CPU,   DXGI_FORMAT_R16G16B16A16_SINT, &copyVertexData<GLshort, 3, 1>);
-    AddIntegerVertexFormatInfo(&map, GL_SHORT,          4, VERTEX_CONVERT_NONE,  DXGI_FORMAT_R16G16B16A16_SINT, &copyVertexData<GLshort, 4, 0>);
+    AddIntegerVertexFormatInfo(&map, GL_SHORT,          1, VERTEX_CONVERT_NONE,  DXGI_FORMAT_R16_SINT,          &CopyNativeVertexData<GLshort, 1, 0>);
+    AddIntegerVertexFormatInfo(&map, GL_SHORT,          2, VERTEX_CONVERT_NONE,  DXGI_FORMAT_R16G16_SINT,       &CopyNativeVertexData<GLshort, 2, 0>);
+    AddIntegerVertexFormatInfo(&map, GL_SHORT,          3, VERTEX_CONVERT_CPU,   DXGI_FORMAT_R16G16B16A16_SINT, &CopyNativeVertexData<GLshort, 3, 1>);
+    AddIntegerVertexFormatInfo(&map, GL_SHORT,          4, VERTEX_CONVERT_NONE,  DXGI_FORMAT_R16G16B16A16_SINT, &CopyNativeVertexData<GLshort, 4, 0>);
 
     // GL_UNSIGNED_SHORT
-    AddIntegerVertexFormatInfo(&map, GL_UNSIGNED_SHORT, 1, VERTEX_CONVERT_NONE,  DXGI_FORMAT_R16_UINT,          &copyVertexData<GLushort, 1, 0>);
-    AddIntegerVertexFormatInfo(&map, GL_UNSIGNED_SHORT, 2, VERTEX_CONVERT_NONE,  DXGI_FORMAT_R16G16_UINT,       &copyVertexData<GLushort, 2, 0>);
-    AddIntegerVertexFormatInfo(&map, GL_UNSIGNED_SHORT, 3, VERTEX_CONVERT_CPU,   DXGI_FORMAT_R16G16B16A16_UINT, &copyVertexData<GLushort, 3, 1>);
-    AddIntegerVertexFormatInfo(&map, GL_UNSIGNED_SHORT, 4, VERTEX_CONVERT_NONE,  DXGI_FORMAT_R16G16B16A16_UINT, &copyVertexData<GLushort, 4, 0>);
+    AddIntegerVertexFormatInfo(&map, GL_UNSIGNED_SHORT, 1, VERTEX_CONVERT_NONE,  DXGI_FORMAT_R16_UINT,          &CopyNativeVertexData<GLushort, 1, 0>);
+    AddIntegerVertexFormatInfo(&map, GL_UNSIGNED_SHORT, 2, VERTEX_CONVERT_NONE,  DXGI_FORMAT_R16G16_UINT,       &CopyNativeVertexData<GLushort, 2, 0>);
+    AddIntegerVertexFormatInfo(&map, GL_UNSIGNED_SHORT, 3, VERTEX_CONVERT_CPU,   DXGI_FORMAT_R16G16B16A16_UINT, &CopyNativeVertexData<GLushort, 3, 1>);
+    AddIntegerVertexFormatInfo(&map, GL_UNSIGNED_SHORT, 4, VERTEX_CONVERT_NONE,  DXGI_FORMAT_R16G16B16A16_UINT, &CopyNativeVertexData<GLushort, 4, 0>);
 
     // GL_INT
-    AddIntegerVertexFormatInfo(&map, GL_INT,            1, VERTEX_CONVERT_NONE,  DXGI_FORMAT_R32_SINT,          &copyVertexData<GLint, 1, 0>);
-    AddIntegerVertexFormatInfo(&map, GL_INT,            2, VERTEX_CONVERT_NONE,  DXGI_FORMAT_R32G32_SINT,       &copyVertexData<GLint, 2, 0>);
-    AddIntegerVertexFormatInfo(&map, GL_INT,            3, VERTEX_CONVERT_NONE,  DXGI_FORMAT_R32G32B32_SINT,    &copyVertexData<GLint, 3, 0>);
-    AddIntegerVertexFormatInfo(&map, GL_INT,            4, VERTEX_CONVERT_NONE,  DXGI_FORMAT_R32G32B32A32_SINT, &copyVertexData<GLint, 4, 0>);
+    AddIntegerVertexFormatInfo(&map, GL_INT,            1, VERTEX_CONVERT_NONE,  DXGI_FORMAT_R32_SINT,          &CopyNativeVertexData<GLint, 1, 0>);
+    AddIntegerVertexFormatInfo(&map, GL_INT,            2, VERTEX_CONVERT_NONE,  DXGI_FORMAT_R32G32_SINT,       &CopyNativeVertexData<GLint, 2, 0>);
+    AddIntegerVertexFormatInfo(&map, GL_INT,            3, VERTEX_CONVERT_NONE,  DXGI_FORMAT_R32G32B32_SINT,    &CopyNativeVertexData<GLint, 3, 0>);
+    AddIntegerVertexFormatInfo(&map, GL_INT,            4, VERTEX_CONVERT_NONE,  DXGI_FORMAT_R32G32B32A32_SINT, &CopyNativeVertexData<GLint, 4, 0>);
 
     // GL_UNSIGNED_INT
-    AddIntegerVertexFormatInfo(&map, GL_UNSIGNED_INT,   1, VERTEX_CONVERT_NONE,  DXGI_FORMAT_R32_SINT,          &copyVertexData<GLuint, 1, 0>);
-    AddIntegerVertexFormatInfo(&map, GL_UNSIGNED_INT,   2, VERTEX_CONVERT_NONE,  DXGI_FORMAT_R32G32_SINT,       &copyVertexData<GLuint, 2, 0>);
-    AddIntegerVertexFormatInfo(&map, GL_UNSIGNED_INT,   3, VERTEX_CONVERT_NONE,  DXGI_FORMAT_R32G32B32_SINT,    &copyVertexData<GLuint, 3, 0>);
-    AddIntegerVertexFormatInfo(&map, GL_UNSIGNED_INT,   4, VERTEX_CONVERT_NONE,  DXGI_FORMAT_R32G32B32A32_SINT, &copyVertexData<GLuint, 4, 0>);
+    AddIntegerVertexFormatInfo(&map, GL_UNSIGNED_INT,   1, VERTEX_CONVERT_NONE,  DXGI_FORMAT_R32_SINT,          &CopyNativeVertexData<GLuint, 1, 0>);
+    AddIntegerVertexFormatInfo(&map, GL_UNSIGNED_INT,   2, VERTEX_CONVERT_NONE,  DXGI_FORMAT_R32G32_SINT,       &CopyNativeVertexData<GLuint, 2, 0>);
+    AddIntegerVertexFormatInfo(&map, GL_UNSIGNED_INT,   3, VERTEX_CONVERT_NONE,  DXGI_FORMAT_R32G32B32_SINT,    &CopyNativeVertexData<GLuint, 3, 0>);
+    AddIntegerVertexFormatInfo(&map, GL_UNSIGNED_INT,   4, VERTEX_CONVERT_NONE,  DXGI_FORMAT_R32G32B32A32_SINT, &CopyNativeVertexData<GLuint, 4, 0>);
 
     // GL_INT_2_10_10_10_REV
-    AddIntegerVertexFormatInfo(&map, GL_INT_2_10_10_10_REV, 4, VERTEX_CONVERT_CPU, DXGI_FORMAT_R16G16B16A16_SINT, &copyPackedVertexData<true, true, false>);
+    AddIntegerVertexFormatInfo(&map, GL_INT_2_10_10_10_REV, 4, VERTEX_CONVERT_CPU, DXGI_FORMAT_R16G16B16A16_SINT, &CopyXYZ10W2ToXYZW32FVertexData<true, true, false>);
 
     // GL_UNSIGNED_INT_2_10_10_10_REV
-    AddIntegerVertexFormatInfo(&map, GL_UNSIGNED_INT_2_10_10_10_REV, 4, VERTEX_CONVERT_NONE, DXGI_FORMAT_R10G10B10A2_UINT, &copyPackedUnsignedVertexData);
+    AddIntegerVertexFormatInfo(&map, GL_UNSIGNED_INT_2_10_10_10_REV, 4, VERTEX_CONVERT_NONE, DXGI_FORMAT_R10G10B10A2_UINT, &CopyNativeVertexData<GLuint, 1, 0>);
 
     return map;
 }
diff --git a/src/libGLESv2/renderer/d3d/d3d11/formatutils11.h b/src/libGLESv2/renderer/d3d/d3d11/formatutils11.h
index 4b932c5..ea11aaa 100644
--- a/src/libGLESv2/renderer/d3d/d3d11/formatutils11.h
+++ b/src/libGLESv2/renderer/d3d/d3d11/formatutils11.h
@@ -12,6 +12,8 @@
 
 #include "libGLESv2/formatutils.h"
 
+#include <map>
+
 namespace rx
 {
 
diff --git a/src/libGLESv2/renderer/d3d/d3d11/renderer11_utils.cpp b/src/libGLESv2/renderer/d3d/d3d11/renderer11_utils.cpp
index 949140b..b1867fb 100644
--- a/src/libGLESv2/renderer/d3d/d3d11/renderer11_utils.cpp
+++ b/src/libGLESv2/renderer/d3d/d3d11/renderer11_utils.cpp
@@ -1,4 +1,3 @@
-#include "precompiled.h"
 //
 // Copyright (c) 2012-2014 The ANGLE Project Authors. All rights reserved.
 // Use of this source code is governed by a BSD-style license that can be
@@ -10,8 +9,14 @@
 
 #include "libGLESv2/renderer/d3d/d3d11/renderer11_utils.h"
 #include "libGLESv2/renderer/d3d/d3d11/formatutils11.h"
+#include "libGLESv2/renderer/d3d/d3d11/RenderTarget11.h"
+#include "libGLESv2/ProgramBinary.h"
+#include "libGLESv2/Framebuffer.h"
+
 #include "common/debug.h"
 
+#include <algorithm>
+
 namespace rx
 {
 
@@ -390,9 +395,8 @@
       case D3D_FEATURE_LEVEL_11_1:
       case D3D_FEATURE_LEVEL_11_0: return D3D11_SIMULTANEOUS_RENDER_TARGET_COUNT;
 
-        // FIXME(geofflang): Work around NVIDIA driver bug by repacking buffers
       case D3D_FEATURE_LEVEL_10_1:
-      case D3D_FEATURE_LEVEL_10_0: return 1; /* D3D10_SIMULTANEOUS_RENDER_TARGET_COUNT; */
+      case D3D_FEATURE_LEVEL_10_0: return D3D10_SIMULTANEOUS_RENDER_TARGET_COUNT;
 
       case D3D_FEATURE_LEVEL_9_3:  return D3D_FL9_3_SIMULTANEOUS_RENDER_TARGET_COUNT;
       case D3D_FEATURE_LEVEL_9_2:
@@ -493,6 +497,363 @@
     }
 }
 
+static size_t GetMaximumDrawIndexedIndexCount(D3D_FEATURE_LEVEL featureLevel)
+{
+    // D3D11 allows up to 2^32 elements, but we report max signed int for convenience since that's what's
+    // returned from glGetInteger
+    META_ASSERT(D3D11_REQ_DRAWINDEXED_INDEX_COUNT_2_TO_EXP == 32);
+    META_ASSERT(D3D10_REQ_DRAWINDEXED_INDEX_COUNT_2_TO_EXP == 32);
+
+    switch (featureLevel)
+    {
+      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 std::numeric_limits<GLint>::max();
+
+      case D3D_FEATURE_LEVEL_9_3:
+      case D3D_FEATURE_LEVEL_9_2:  return D3D_FL9_2_IA_PRIMITIVE_MAX_COUNT;
+      case D3D_FEATURE_LEVEL_9_1:  return D3D_FL9_1_IA_PRIMITIVE_MAX_COUNT;
+
+      default: UNREACHABLE();      return 0;
+    }
+}
+
+static size_t GetMaximumDrawVertexCount(D3D_FEATURE_LEVEL featureLevel)
+{
+    // D3D11 allows up to 2^32 elements, but we report max signed int for convenience since that's what's
+    // returned from glGetInteger
+    META_ASSERT(D3D11_REQ_DRAW_VERTEX_COUNT_2_TO_EXP == 32);
+    META_ASSERT(D3D10_REQ_DRAW_VERTEX_COUNT_2_TO_EXP == 32);
+
+    switch (featureLevel)
+    {
+      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 std::numeric_limits<GLint>::max();
+
+      case D3D_FEATURE_LEVEL_9_3:
+      case D3D_FEATURE_LEVEL_9_2:  return D3D_FL9_2_IA_PRIMITIVE_MAX_COUNT;
+      case D3D_FEATURE_LEVEL_9_1:  return D3D_FL9_1_IA_PRIMITIVE_MAX_COUNT;
+
+      default: UNREACHABLE();      return 0;
+    }
+}
+
+static size_t GetMaximumVertexInputSlots(D3D_FEATURE_LEVEL featureLevel)
+{
+    switch (featureLevel)
+    {
+      case D3D_FEATURE_LEVEL_11_1:
+      case D3D_FEATURE_LEVEL_11_0: return D3D11_STANDARD_VERTEX_ELEMENT_COUNT;
+
+      case D3D_FEATURE_LEVEL_10_1: return D3D10_1_STANDARD_VERTEX_ELEMENT_COUNT;
+      case D3D_FEATURE_LEVEL_10_0: return D3D10_STANDARD_VERTEX_ELEMENT_COUNT;
+
+      // From http://http://msdn.microsoft.com/en-us/library/windows/desktop/ff476876.aspx "Max Input Slots"
+      case D3D_FEATURE_LEVEL_9_3:
+      case D3D_FEATURE_LEVEL_9_2:
+      case D3D_FEATURE_LEVEL_9_1:  return 16;
+
+      default: UNREACHABLE();      return 0;
+    }
+}
+
+static size_t GetMaximumVertexUniformVectors(D3D_FEATURE_LEVEL featureLevel)
+{
+    // TODO(geofflang): Remove hard-coded limit once the gl-uniform-arrays test can pass
+    switch (featureLevel)
+    {
+      case D3D_FEATURE_LEVEL_11_1:
+      case D3D_FEATURE_LEVEL_11_0: return 1024; // D3D11_REQ_CONSTANT_BUFFER_ELEMENT_COUNT;
+
+      case D3D_FEATURE_LEVEL_10_1:
+      case D3D_FEATURE_LEVEL_10_0: return 1024; // D3D10_REQ_CONSTANT_BUFFER_ELEMENT_COUNT;
+
+      // From http://msdn.microsoft.com/en-us/library/windows/desktop/ff476149.aspx ID3D11DeviceContext::VSSetConstantBuffers
+      case D3D_FEATURE_LEVEL_9_3:
+      case D3D_FEATURE_LEVEL_9_2:
+      case D3D_FEATURE_LEVEL_9_1:  return 255;
+
+      default: UNREACHABLE();      return 0;
+    }
+}
+
+static size_t GetReservedVertexUniformBuffers()
+{
+    // Reserve one buffer for the application uniforms, and one for driver uniforms
+    return 2;
+}
+
+static size_t GetMaximumVertexUniformBlocks(D3D_FEATURE_LEVEL featureLevel)
+{
+    switch (featureLevel)
+    {
+      case D3D_FEATURE_LEVEL_11_1:
+      case D3D_FEATURE_LEVEL_11_0: return D3D11_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT - GetReservedVertexUniformBuffers();
+
+      case D3D_FEATURE_LEVEL_10_1:
+      case D3D_FEATURE_LEVEL_10_0: return D3D10_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT - GetReservedVertexUniformBuffers();
+
+      // Uniform blocks not supported in D3D9 feature levels
+      case D3D_FEATURE_LEVEL_9_3:
+      case D3D_FEATURE_LEVEL_9_2:
+      case D3D_FEATURE_LEVEL_9_1:  return 0;
+
+      default: UNREACHABLE();      return 0;
+    }
+}
+
+static size_t GetReservedVertexOutputVectors()
+{
+    // We potentially reserve varyings for gl_Position, dx_Position, gl_FragCoord and gl_PointSize
+    return 4;
+}
+
+static size_t GetMaximumVertexOutputVectors(D3D_FEATURE_LEVEL featureLevel)
+{
+    META_ASSERT(gl::IMPLEMENTATION_MAX_VARYING_VECTORS == D3D11_VS_OUTPUT_REGISTER_COUNT);
+
+    switch (featureLevel)
+    {
+      case D3D_FEATURE_LEVEL_11_1:
+      case D3D_FEATURE_LEVEL_11_0: return D3D11_VS_OUTPUT_REGISTER_COUNT - GetReservedVertexOutputVectors();
+
+      case D3D_FEATURE_LEVEL_10_1: return D3D10_1_VS_OUTPUT_REGISTER_COUNT - GetReservedVertexOutputVectors();
+      case D3D_FEATURE_LEVEL_10_0: return D3D10_VS_OUTPUT_REGISTER_COUNT - GetReservedVertexOutputVectors();
+
+      // Use D3D9 SM3 and SM2 limits
+      case D3D_FEATURE_LEVEL_9_3:  return 10 - GetReservedVertexOutputVectors();
+      case D3D_FEATURE_LEVEL_9_2:
+      case D3D_FEATURE_LEVEL_9_1:  return 8 - GetReservedVertexOutputVectors();
+
+      default: UNREACHABLE();      return 0;
+    }
+}
+
+static size_t GetMaximumVertexTextureUnits(D3D_FEATURE_LEVEL featureLevel)
+{
+    switch (featureLevel)
+    {
+      case D3D_FEATURE_LEVEL_11_1:
+      case D3D_FEATURE_LEVEL_11_0: return D3D11_COMMONSHADER_SAMPLER_SLOT_COUNT;
+
+      case D3D_FEATURE_LEVEL_10_1:
+      case D3D_FEATURE_LEVEL_10_0: return D3D10_COMMONSHADER_SAMPLER_SLOT_COUNT;
+
+      // Vertex textures not supported in D3D9 feature levels according to
+      // http://msdn.microsoft.com/en-us/library/windows/desktop/ff476149.aspx
+      // ID3D11DeviceContext::VSSetSamplers and ID3D11DeviceContext::VSSetShaderResources
+      case D3D_FEATURE_LEVEL_9_3:
+      case D3D_FEATURE_LEVEL_9_2:
+      case D3D_FEATURE_LEVEL_9_1:  return 0;
+
+      default: UNREACHABLE();      return 0;
+    }
+}
+
+static size_t GetMaximumPixelUniformVectors(D3D_FEATURE_LEVEL featureLevel)
+{
+    // TODO(geofflang): Remove hard-coded limit once the gl-uniform-arrays test can pass
+    switch (featureLevel)
+    {
+      case D3D_FEATURE_LEVEL_11_1:
+      case D3D_FEATURE_LEVEL_11_0: return 1024; // D3D11_REQ_CONSTANT_BUFFER_ELEMENT_COUNT;
+
+      case D3D_FEATURE_LEVEL_10_1:
+      case D3D_FEATURE_LEVEL_10_0: return 1024; // D3D10_REQ_CONSTANT_BUFFER_ELEMENT_COUNT;
+
+      // From http://msdn.microsoft.com/en-us/library/windows/desktop/ff476149.aspx ID3D11DeviceContext::PSSetConstantBuffers
+      case D3D_FEATURE_LEVEL_9_3:
+      case D3D_FEATURE_LEVEL_9_2:
+      case D3D_FEATURE_LEVEL_9_1:  return 32;
+
+      default: UNREACHABLE();      return 0;
+    }
+}
+
+static size_t GetReservedPixelUniformBuffers()
+{
+    // Reserve one buffer for the application uniforms, and one for driver uniforms
+    return 2;
+}
+
+static size_t GetMaximumPixelUniformBlocks(D3D_FEATURE_LEVEL featureLevel)
+{
+    switch (featureLevel)
+    {
+      case D3D_FEATURE_LEVEL_11_1:
+      case D3D_FEATURE_LEVEL_11_0: return D3D11_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT - GetReservedPixelUniformBuffers();
+
+      case D3D_FEATURE_LEVEL_10_1:
+      case D3D_FEATURE_LEVEL_10_0: return D3D10_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT - GetReservedPixelUniformBuffers();
+
+      // Uniform blocks not supported in D3D9 feature levels
+      case D3D_FEATURE_LEVEL_9_3:
+      case D3D_FEATURE_LEVEL_9_2:
+      case D3D_FEATURE_LEVEL_9_1:  return 0;
+
+      default: UNREACHABLE();      return 0;
+    }
+}
+
+static size_t GetMaximumPixelInputVectors(D3D_FEATURE_LEVEL featureLevel)
+{
+    switch (featureLevel)
+    {
+      case D3D_FEATURE_LEVEL_11_1:
+      case D3D_FEATURE_LEVEL_11_0: return D3D11_PS_INPUT_REGISTER_COUNT - GetReservedVertexOutputVectors();
+
+      case D3D_FEATURE_LEVEL_10_1:
+      case D3D_FEATURE_LEVEL_10_0: return D3D10_PS_INPUT_REGISTER_COUNT - GetReservedVertexOutputVectors();
+
+      // Use D3D9 SM3 and SM2 limits
+      case D3D_FEATURE_LEVEL_9_3:  return 10 - GetReservedVertexOutputVectors();
+      case D3D_FEATURE_LEVEL_9_2:
+      case D3D_FEATURE_LEVEL_9_1:  return 8 - GetReservedVertexOutputVectors();
+
+      default: UNREACHABLE();      return 0;
+    }
+}
+
+static size_t GetMaximumPixelTextureUnits(D3D_FEATURE_LEVEL featureLevel)
+{
+    switch (featureLevel)
+    {
+      case D3D_FEATURE_LEVEL_11_1:
+      case D3D_FEATURE_LEVEL_11_0: return D3D11_COMMONSHADER_SAMPLER_SLOT_COUNT;
+
+      case D3D_FEATURE_LEVEL_10_1:
+      case D3D_FEATURE_LEVEL_10_0: return D3D10_COMMONSHADER_SAMPLER_SLOT_COUNT;
+
+      // http://msdn.microsoft.com/en-us/library/windows/desktop/ff476149.aspx ID3D11DeviceContext::PSSetShaderResources
+      case D3D_FEATURE_LEVEL_9_3:
+      case D3D_FEATURE_LEVEL_9_2:
+      case D3D_FEATURE_LEVEL_9_1:  return 16;
+
+      default: UNREACHABLE();      return 0;
+    }
+}
+
+static 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;
+
+      case D3D_FEATURE_LEVEL_10_1:
+      case D3D_FEATURE_LEVEL_10_0: return D3D10_COMMONSHADER_TEXEL_OFFSET_MAX_NEGATIVE;
+
+      // Sampling functions with offsets are not available below shader model 4.0.
+      case D3D_FEATURE_LEVEL_9_3:
+      case D3D_FEATURE_LEVEL_9_2:
+      case D3D_FEATURE_LEVEL_9_1:  return 0;
+
+      default: UNREACHABLE();      return 0;
+    }
+}
+
+static int GetMaximumTexelOffset(D3D_FEATURE_LEVEL featureLevel)
+{
+    switch (featureLevel)
+    {
+      case D3D_FEATURE_LEVEL_11_1:
+      case D3D_FEATURE_LEVEL_11_0: return D3D11_COMMONSHADER_TEXEL_OFFSET_MAX_POSITIVE;
+      case D3D_FEATURE_LEVEL_10_1:
+      case D3D_FEATURE_LEVEL_10_0: return D3D11_COMMONSHADER_TEXEL_OFFSET_MAX_POSITIVE;
+
+      // Sampling functions with offsets are not available below shader model 4.0.
+      case D3D_FEATURE_LEVEL_9_3:
+      case D3D_FEATURE_LEVEL_9_2:
+      case D3D_FEATURE_LEVEL_9_1:  return 0;
+
+      default: UNREACHABLE();      return 0;
+    }
+}
+
+static size_t GetMaximumConstantBufferSize(D3D_FEATURE_LEVEL featureLevel)
+{
+    // Returns a size_t despite the limit being a GLuint64 because size_t is the maximum size of
+    // any buffer that could be allocated.
+
+    const size_t bytesPerComponent = 4 * sizeof(float);
+
+    switch (featureLevel)
+    {
+      case D3D_FEATURE_LEVEL_11_1:
+      case D3D_FEATURE_LEVEL_11_0: return D3D11_REQ_CONSTANT_BUFFER_ELEMENT_COUNT * bytesPerComponent;
+
+      case D3D_FEATURE_LEVEL_10_1:
+      case D3D_FEATURE_LEVEL_10_0: return D3D10_REQ_CONSTANT_BUFFER_ELEMENT_COUNT * bytesPerComponent;
+
+      // Limits from http://msdn.microsoft.com/en-us/library/windows/desktop/ff476501.aspx remarks section
+      case D3D_FEATURE_LEVEL_9_3:
+      case D3D_FEATURE_LEVEL_9_2:
+      case D3D_FEATURE_LEVEL_9_1:  return 4096 * bytesPerComponent;
+
+      default: UNREACHABLE();      return 0;
+    }
+}
+
+static size_t GetMaximumStreamOutputBuffers(D3D_FEATURE_LEVEL featureLevel)
+{
+    switch (featureLevel)
+    {
+      case D3D_FEATURE_LEVEL_11_1:
+      case D3D_FEATURE_LEVEL_11_0: return D3D11_SO_BUFFER_SLOT_COUNT;
+
+      case D3D_FEATURE_LEVEL_10_1: return D3D10_1_SO_BUFFER_SLOT_COUNT;
+      case D3D_FEATURE_LEVEL_10_0: return D3D10_SO_BUFFER_SLOT_COUNT;
+
+      case D3D_FEATURE_LEVEL_9_3:
+      case D3D_FEATURE_LEVEL_9_2:
+      case D3D_FEATURE_LEVEL_9_1:  return 0;
+
+      default: UNREACHABLE();      return 0;
+    }
+}
+
+static size_t GetMaximumStreamOutputInterleavedComponenets(D3D_FEATURE_LEVEL featureLevel)
+{
+    switch (featureLevel)
+    {
+      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 GetMaximumVertexOutputVectors(featureLevel) * 4;
+
+      case D3D_FEATURE_LEVEL_9_3:
+      case D3D_FEATURE_LEVEL_9_2:
+      case D3D_FEATURE_LEVEL_9_1:  return 0;
+
+      default: UNREACHABLE();      return 0;
+    }
+}
+
+static size_t GetMaximumStreamOutputSeparateCompeonents(D3D_FEATURE_LEVEL featureLevel)
+{
+    switch (featureLevel)
+    {
+      case D3D_FEATURE_LEVEL_11_1:
+      case D3D_FEATURE_LEVEL_11_0: return GetMaximumStreamOutputInterleavedComponenets(featureLevel) /
+                                          GetMaximumStreamOutputBuffers(featureLevel);
+
+
+      // D3D 10 and 10.1 only allow one output per output slot if an output slot other than zero is used.
+      case D3D_FEATURE_LEVEL_10_1:
+      case D3D_FEATURE_LEVEL_10_0: return 4;
+
+      case D3D_FEATURE_LEVEL_9_3:
+      case D3D_FEATURE_LEVEL_9_2:
+      case D3D_FEATURE_LEVEL_9_1:  return 0;
+
+      default: UNREACHABLE();      return 0;
+    }
+}
+
 void GenerateCaps(ID3D11Device *device, gl::Caps *caps, gl::TextureCapsMap *textureCapsMap, gl::Extensions *extensions)
 {
     GLuint maxSamples = 0;
@@ -503,6 +864,11 @@
         textureCapsMap->insert(*internalFormat, textureCaps);
 
         maxSamples = std::max(maxSamples, textureCaps.getMaxSamples());
+
+        if (gl::GetInternalFormatInfo(*internalFormat).compressed)
+        {
+            caps->compressedTextureFormats.push_back(*internalFormat);
+        }
     }
 
     D3D_FEATURE_LEVEL featureLevel = device->GetFeatureLevel();
@@ -537,6 +903,54 @@
     caps->minAliasedLineWidth = 1.0f;
     caps->maxAliasedLineWidth = 1.0f;
 
+    // Primitive count limits
+    caps->maxElementsIndices = GetMaximumDrawIndexedIndexCount(featureLevel);
+    caps->maxElementsVertices = GetMaximumDrawVertexCount(featureLevel);
+
+    // Program and shader binary formats (no supported shader binary formats)
+    caps->programBinaryFormats.push_back(GL_PROGRAM_BINARY_ANGLE);
+
+    // We do not wait for server fence objects internally, so report a max timeout of zero.
+    caps->maxServerWaitTimeout = 0;
+
+    // Vertex shader limits
+    caps->maxVertexAttributes = GetMaximumVertexInputSlots(featureLevel);
+    caps->maxVertexUniformComponents = GetMaximumVertexUniformVectors(featureLevel) * 4;
+    caps->maxVertexUniformVectors = GetMaximumVertexUniformVectors(featureLevel);
+    caps->maxVertexUniformBlocks = GetMaximumVertexUniformBlocks(featureLevel);
+    caps->maxVertexOutputComponents = GetMaximumVertexOutputVectors(featureLevel) * 4;
+    caps->maxVertexTextureImageUnits = GetMaximumVertexTextureUnits(featureLevel);
+
+    // Fragment shader limits
+    caps->maxFragmentUniformComponents = GetMaximumPixelUniformVectors(featureLevel) * 4;
+    caps->maxFragmentUniformVectors = GetMaximumPixelUniformVectors(featureLevel);
+    caps->maxFragmentUniformBlocks = GetMaximumPixelUniformBlocks(featureLevel);
+    caps->maxFragmentInputComponents = GetMaximumPixelInputVectors(featureLevel) * 4;
+    caps->maxTextureImageUnits = GetMaximumPixelTextureUnits(featureLevel);
+    caps->minProgramTexelOffset = GetMinimumTexelOffset(featureLevel);
+    caps->maxProgramTexelOffset = GetMaximumTexelOffset(featureLevel);
+
+    // Aggregate shader limits
+    caps->maxUniformBufferBindings = caps->maxVertexUniformBlocks + caps->maxFragmentUniformBlocks;
+    caps->maxUniformBlockSize = GetMaximumConstantBufferSize(featureLevel);
+
+    // Setting a large alignment forces uniform buffers to bind with zero offset
+    caps->uniformBufferOffsetAlignment = static_cast<GLuint>(std::numeric_limits<GLint>::max());
+
+    caps->maxCombinedUniformBlocks = caps->maxVertexUniformBlocks + caps->maxFragmentUniformBlocks;
+    caps->maxCombinedVertexUniformComponents = (static_cast<GLint64>(caps->maxVertexUniformBlocks) * static_cast<GLint64>(caps->maxUniformBlockSize / 4)) +
+                                               static_cast<GLint64>(caps->maxVertexUniformComponents);
+    caps->maxCombinedFragmentUniformComponents = (static_cast<GLint64>(caps->maxFragmentUniformBlocks) * static_cast<GLint64>(caps->maxUniformBlockSize / 4)) +
+                                                 static_cast<GLint64>(caps->maxFragmentUniformComponents);
+    caps->maxVaryingComponents = GetMaximumVertexOutputVectors(featureLevel) * 4;
+    caps->maxVaryingVectors = GetMaximumVertexOutputVectors(featureLevel);
+    caps->maxCombinedTextureImageUnits = caps->maxVertexTextureImageUnits + caps->maxTextureImageUnits;
+
+    // Transform feedback limits
+    caps->maxTransformFeedbackInterleavedComponents = GetMaximumStreamOutputInterleavedComponenets(featureLevel);
+    caps->maxTransformFeedbackSeparateAttributes = GetMaximumStreamOutputBuffers(featureLevel);
+    caps->maxTransformFeedbackSeparateComponents = GetMaximumStreamOutputSeparateCompeonents(featureLevel);
+
     // GL extension support
     extensions->setTextureExtensionSupport(*textureCapsMap);
     extensions->elementIndexUint = true;
@@ -651,6 +1065,12 @@
 #endif
 }
 
+RenderTarget11 *GetAttachmentRenderTarget(gl::FramebufferAttachment *attachment)
+{
+    RenderTarget *renderTarget = rx::GetAttachmentRenderTarget(attachment);
+    return RenderTarget11::makeRenderTarget11(renderTarget);
+}
+
 }
 
 }
diff --git a/src/libGLESv2/renderer/d3d/d3d11/renderer11_utils.h b/src/libGLESv2/renderer/d3d/d3d11/renderer11_utils.h
index 5fbbb8b..4c05eb9 100644
--- a/src/libGLESv2/renderer/d3d/d3d11/renderer11_utils.h
+++ b/src/libGLESv2/renderer/d3d/d3d11/renderer11_utils.h
@@ -13,8 +13,16 @@
 #include "libGLESv2/angletypes.h"
 #include "libGLESv2/Caps.h"
 
+#include <vector>
+
+namespace gl
+{
+class FramebufferAttachment;
+}
+
 namespace rx
 {
+class RenderTarget11;
 
 namespace gl_d3d11
 {
@@ -168,6 +176,8 @@
     context->Unmap(constantBuffer, 0);
 }
 
+RenderTarget11 *GetAttachmentRenderTarget(gl::FramebufferAttachment *attachment);
+
 }
 
 }
diff --git a/src/libGLESv2/renderer/d3d/d3d9/Blit9.cpp b/src/libGLESv2/renderer/d3d/d3d9/Blit9.cpp
index 2d72729..80503d5 100644
--- a/src/libGLESv2/renderer/d3d/d3d9/Blit9.cpp
+++ b/src/libGLESv2/renderer/d3d/d3d9/Blit9.cpp
@@ -1,4 +1,3 @@
-#include "precompiled.h"
 //
 // 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
@@ -8,8 +7,6 @@
 // Blit9.cpp: Surface copy utility class.
 
 #include "libGLESv2/renderer/d3d/d3d9/Blit9.h"
-
-#include "libGLESv2/main.h"
 #include "libGLESv2/renderer/d3d/d3d9/renderer9_utils.h"
 #include "libGLESv2/renderer/d3d/d3d9/formatutils9.h"
 #include "libGLESv2/renderer/d3d/d3d9/TextureStorage9.h"
@@ -17,9 +14,11 @@
 #include "libGLESv2/renderer/d3d/d3d9/Renderer9.h"
 #include "libGLESv2/Framebuffer.h"
 #include "libGLESv2/FramebufferAttachment.h"
+#include "libGLESv2/main.h"
 
 namespace
 {
+// Precompiled shaders
 #include "libGLESv2/renderer/d3d/d3d9/shaders/compiled/standardvs.h"
 #include "libGLESv2/renderer/d3d/d3d9/shaders/compiled/flipyvs.h"
 #include "libGLESv2/renderer/d3d/d3d9/shaders/compiled/passthroughps.h"
@@ -209,7 +208,7 @@
     return true;
 }
 
-bool Blit9::copy(gl::Framebuffer *framebuffer, const RECT &sourceRect, GLenum destFormat, GLint xoffset, GLint yoffset, TextureStorageInterface2D *storage, GLint level)
+bool Blit9::copy2D(gl::Framebuffer *framebuffer, const RECT &sourceRect, GLenum destFormat, GLint xoffset, GLint yoffset, TextureStorage *storage, GLint level)
 {
     RenderTarget9 *renderTarget = NULL;
     IDirect3DSurface9 *source = NULL;
@@ -217,9 +216,9 @@
 
     if (colorbuffer)
     {
-        renderTarget = RenderTarget9::makeRenderTarget9(colorbuffer->getRenderTarget());
+        renderTarget = d3d9::GetAttachmentRenderTarget(colorbuffer);
     }
-    
+
     if (renderTarget)
     {
         source = renderTarget->getSurface();
@@ -231,10 +230,10 @@
         return gl::error(GL_OUT_OF_MEMORY, false);
     }
 
-    TextureStorage9_2D *storage9 = TextureStorage9_2D::makeTextureStorage9_2D(storage->getStorageInstance());
+    TextureStorage9_2D *storage9 = TextureStorage9_2D::makeTextureStorage9_2D(storage);
     IDirect3DSurface9 *destSurface = storage9->getSurfaceLevel(level, true);
     bool result = false;
-        
+
     if (destSurface)
     {
         result = copy(source, sourceRect, destFormat, xoffset, yoffset, destSurface);
@@ -245,7 +244,7 @@
     return result;
 }
 
-bool Blit9::copy(gl::Framebuffer *framebuffer, const RECT &sourceRect, GLenum destFormat, GLint xoffset, GLint yoffset, TextureStorageInterfaceCube *storage, GLenum target, GLint level)
+bool Blit9::copyCube(gl::Framebuffer *framebuffer, const RECT &sourceRect, GLenum destFormat, GLint xoffset, GLint yoffset, TextureStorage *storage, GLenum target, GLint level)
 {
     RenderTarget9 *renderTarget = NULL;
     IDirect3DSurface9 *source = NULL;
@@ -253,9 +252,9 @@
 
     if (colorbuffer)
     {
-        renderTarget = RenderTarget9::makeRenderTarget9(colorbuffer->getRenderTarget());
+        renderTarget = d3d9::GetAttachmentRenderTarget(colorbuffer);
     }
-    
+
     if (renderTarget)
     {
         source = renderTarget->getSurface();
@@ -267,7 +266,7 @@
         return gl::error(GL_OUT_OF_MEMORY, false);
     }
 
-    TextureStorage9_Cube *storage9 = TextureStorage9_Cube::makeTextureStorage9_Cube(storage->getStorageInstance());
+    TextureStorage9_Cube *storage9 = TextureStorage9_Cube::makeTextureStorage9_Cube(storage);
     IDirect3DSurface9 *destSurface = storage9->getCubeMapSurface(target, level, true);
     bool result = false;
 
diff --git a/src/libGLESv2/renderer/d3d/d3d9/Blit9.h b/src/libGLESv2/renderer/d3d/d3d9/Blit9.h
index 3635bca..46a3ee1 100644
--- a/src/libGLESv2/renderer/d3d/d3d9/Blit9.h
+++ b/src/libGLESv2/renderer/d3d/d3d9/Blit9.h
@@ -11,6 +11,8 @@
 
 #include "common/angleutils.h"
 
+#include <GLES2/gl2.h>
+
 namespace gl
 {
 class Framebuffer;
@@ -19,8 +21,7 @@
 namespace rx
 {
 class Renderer9;
-class TextureStorageInterface2D;
-class TextureStorageInterfaceCube;
+class TextureStorage;
 
 class Blit9
 {
@@ -30,8 +31,8 @@
 
     // Copy from source surface to dest surface.
     // sourceRect, xoffset, yoffset are in D3D coordinates (0,0 in upper-left)
-    bool copy(gl::Framebuffer *framebuffer, const RECT &sourceRect, GLenum destFormat, GLint xoffset, GLint yoffset, TextureStorageInterface2D *storage, GLint level);
-    bool copy(gl::Framebuffer *framebuffer, const RECT &sourceRect, GLenum destFormat, GLint xoffset, GLint yoffset, TextureStorageInterfaceCube *storage, GLenum target, GLint level);
+    bool copy2D(gl::Framebuffer *framebuffer, const RECT &sourceRect, GLenum destFormat, GLint xoffset, GLint yoffset, TextureStorage *storage, GLint level);
+    bool copyCube(gl::Framebuffer *framebuffer, const RECT &sourceRect, GLenum destFormat, GLint xoffset, GLint yoffset, TextureStorage *storage, GLenum target, GLint level);
 
     // Copy from source surface to dest surface.
     // sourceRect, xoffset, yoffset are in D3D coordinates (0,0 in upper-left)
diff --git a/src/libGLESv2/renderer/d3d/d3d9/Buffer9.cpp b/src/libGLESv2/renderer/d3d/d3d9/Buffer9.cpp
index 47198d4..c02db51 100644
--- a/src/libGLESv2/renderer/d3d/d3d9/Buffer9.cpp
+++ b/src/libGLESv2/renderer/d3d/d3d9/Buffer9.cpp
@@ -1,4 +1,3 @@
-#include "precompiled.h"
 //
 // Copyright 2014 The ANGLE Project Authors. All rights reserved.
 // Use of this source code is governed by a BSD-style license that can be
@@ -8,8 +7,8 @@
 // Buffer9.cpp Defines the Buffer9 class.
 
 #include "libGLESv2/renderer/d3d/d3d9/Buffer9.h"
-#include "libGLESv2/main.h"
 #include "libGLESv2/renderer/d3d/d3d9/Renderer9.h"
+#include "libGLESv2/main.h"
 
 namespace rx
 {
@@ -31,13 +30,13 @@
     return static_cast<Buffer9*>(buffer);
 }
 
-void Buffer9::setData(const void* data, size_t size, GLenum usage)
+gl::Error Buffer9::setData(const void* data, size_t size, GLenum usage)
 {
     if (size > mMemory.size())
     {
         if (!mMemory.resize(size))
         {
-            return gl::error(GL_OUT_OF_MEMORY);
+            return gl::Error(GL_OUT_OF_MEMORY, "Failed to resize internal buffer.");
         }
     }
 
@@ -47,13 +46,14 @@
         memcpy(mMemory.data(), data, size);
     }
 
-    mIndexRangeCache.clear();
     invalidateStaticData();
 
     if (usage == GL_STATIC_DRAW)
     {
         initializeStaticData();
     }
+
+    return gl::Error(GL_NO_ERROR);
 }
 
 void *Buffer9::getData()
@@ -61,13 +61,13 @@
     return mMemory.data();
 }
 
-void Buffer9::setSubData(const void* data, size_t size, size_t offset)
+gl::Error Buffer9::setSubData(const void* data, size_t size, size_t offset)
 {
     if (offset + size > mMemory.size())
     {
         if (!mMemory.resize(offset + size))
         {
-            return gl::error(GL_OUT_OF_MEMORY);
+            return gl::Error(GL_OUT_OF_MEMORY, "Failed to resize internal buffer.");
         }
     }
 
@@ -77,34 +77,35 @@
         memcpy(mMemory.data() + offset, data, size);
     }
 
-    mIndexRangeCache.invalidateRange(offset, size);
-
     invalidateStaticData();
+
+    return gl::Error(GL_NO_ERROR);
 }
 
-void Buffer9::copySubData(BufferImpl* source, GLintptr sourceOffset, GLintptr destOffset, GLsizeiptr size)
+gl::Error Buffer9::copySubData(BufferImpl* source, GLintptr sourceOffset, GLintptr destOffset, GLsizeiptr size)
 {
     // Note: this method is currently unreachable
     Buffer9* sourceBuffer = makeBuffer9(source);
-    if (sourceBuffer)
-    {
-        memcpy(mMemory.data() + destOffset, sourceBuffer->mMemory.data() + sourceOffset, size);
-    }
+    ASSERT(sourceBuffer);
 
-    mIndexRangeCache.invalidateRange(destOffset, size);
+    memcpy(mMemory.data() + destOffset, sourceBuffer->mMemory.data() + sourceOffset, size);
+
     invalidateStaticData();
+
+    return gl::Error(GL_NO_ERROR);
 }
 
-// We do not suppot buffer mapping in D3D9
-GLvoid* Buffer9::map(size_t offset, size_t length, GLbitfield access)
+// We do not support buffer mapping in D3D9
+gl::Error Buffer9::map(size_t offset, size_t length, GLbitfield access, GLvoid **mapPtr)
 {
     UNREACHABLE();
-    return NULL;
+    return gl::Error(GL_INVALID_OPERATION);
 }
 
-void Buffer9::unmap()
+gl::Error Buffer9::unmap()
 {
     UNREACHABLE();
+    return gl::Error(GL_INVALID_OPERATION);
 }
 
 void Buffer9::markTransformFeedbackUsage()
diff --git a/src/libGLESv2/renderer/d3d/d3d9/Buffer9.h b/src/libGLESv2/renderer/d3d/d3d9/Buffer9.h
index f12ee00..e78182f 100644
--- a/src/libGLESv2/renderer/d3d/d3d9/Buffer9.h
+++ b/src/libGLESv2/renderer/d3d/d3d9/Buffer9.h
@@ -31,12 +31,12 @@
     virtual Renderer* getRenderer();
 
     // BufferImpl implementation
-    virtual void setData(const void* data, size_t size, GLenum usage);
+    virtual gl::Error setData(const void* data, size_t size, GLenum usage);
     virtual void *getData();
-    virtual void setSubData(const void* data, size_t size, size_t offset);
-    virtual void copySubData(BufferImpl* source, GLintptr sourceOffset, GLintptr destOffset, GLsizeiptr size);
-    virtual GLvoid* map(size_t offset, size_t length, GLbitfield access);
-    virtual void unmap();
+    virtual gl::Error setSubData(const void* data, size_t size, size_t offset);
+    virtual gl::Error copySubData(BufferImpl* source, GLintptr sourceOffset, GLintptr destOffset, GLsizeiptr size);
+    virtual gl::Error map(size_t offset, size_t length, GLbitfield access, GLvoid **mapPtr);
+    virtual gl::Error unmap();
     virtual void markTransformFeedbackUsage();
 
   private:
diff --git a/src/libGLESv2/renderer/d3d/d3d9/Fence9.cpp b/src/libGLESv2/renderer/d3d/d3d9/Fence9.cpp
index d2437ca..e352a5f 100644
--- a/src/libGLESv2/renderer/d3d/d3d9/Fence9.cpp
+++ b/src/libGLESv2/renderer/d3d/d3d9/Fence9.cpp
@@ -1,4 +1,3 @@
-#include "precompiled.h"
 //
 // 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
@@ -8,9 +7,9 @@
 // Fence9.cpp: Defines the rx::Fence9 class.
 
 #include "libGLESv2/renderer/d3d/d3d9/Fence9.h"
-#include "libGLESv2/main.h"
 #include "libGLESv2/renderer/d3d/d3d9/renderer9_utils.h"
 #include "libGLESv2/renderer/d3d/d3d9/Renderer9.h"
+#include "libGLESv2/main.h"
 
 namespace rx
 {
diff --git a/src/libGLESv2/renderer/d3d/d3d9/Image9.cpp b/src/libGLESv2/renderer/d3d/d3d9/Image9.cpp
index d2383d6..18383fb 100644
--- a/src/libGLESv2/renderer/d3d/d3d9/Image9.cpp
+++ b/src/libGLESv2/renderer/d3d/d3d9/Image9.cpp
@@ -1,5 +1,3 @@
-
-#include "precompiled.h"
 //
 // 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
@@ -10,17 +8,16 @@
 // the actual underlying surfaces of a Texture.
 
 #include "libGLESv2/renderer/d3d/d3d9/Image9.h"
-
+#include "libGLESv2/renderer/d3d/d3d9/renderer9_utils.h"
+#include "libGLESv2/renderer/d3d/d3d9/formatutils9.h"
+#include "libGLESv2/renderer/d3d/d3d9/Renderer9.h"
+#include "libGLESv2/renderer/d3d/d3d9/RenderTarget9.h"
+#include "libGLESv2/renderer/d3d/d3d9/TextureStorage9.h"
 #include "libGLESv2/main.h"
 #include "libGLESv2/Framebuffer.h"
 #include "libGLESv2/FramebufferAttachment.h"
 #include "libGLESv2/Renderbuffer.h"
-#include "libGLESv2/renderer/d3d/d3d9/Renderer9.h"
-#include "libGLESv2/renderer/d3d/d3d9/RenderTarget9.h"
-#include "libGLESv2/renderer/d3d/d3d9/TextureStorage9.h"
 
-#include "libGLESv2/renderer/d3d/d3d9/renderer9_utils.h"
-#include "libGLESv2/renderer/d3d/d3d9/formatutils9.h"
 
 namespace rx
 {
@@ -273,15 +270,15 @@
     return mSurface;
 }
 
-void Image9::setManagedSurface(TextureStorageInterface2D *storage, int level)
+void Image9::setManagedSurface2D(TextureStorage *storage, int level)
 {
-    TextureStorage9_2D *storage9 = TextureStorage9_2D::makeTextureStorage9_2D(storage->getStorageInstance());
+    TextureStorage9_2D *storage9 = TextureStorage9_2D::makeTextureStorage9_2D(storage);
     setManagedSurface(storage9->getSurfaceLevel(level, false));
 }
 
-void Image9::setManagedSurface(TextureStorageInterfaceCube *storage, int face, int level)
+void Image9::setManagedSurfaceCube(TextureStorage *storage, int face, int level)
 {
-    TextureStorage9_Cube *storage9 = TextureStorage9_Cube::makeTextureStorage9_Cube(storage->getStorageInstance());
+    TextureStorage9_Cube *storage9 = TextureStorage9_Cube::makeTextureStorage9_Cube(storage);
     setManagedSurface(storage9->getCubeMapSurface(GL_TEXTURE_CUBE_MAP_POSITIVE_X + face, level, false));
 }
 
@@ -304,28 +301,28 @@
     }
 }
 
-bool Image9::copyToStorage(TextureStorageInterface2D *storage, int level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height)
+bool Image9::copyToStorage2D(TextureStorage *storage, int level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height)
 {
     ASSERT(getSurface() != NULL);
-    TextureStorage9_2D *storage9 = TextureStorage9_2D::makeTextureStorage9_2D(storage->getStorageInstance());
+    TextureStorage9_2D *storage9 = TextureStorage9_2D::makeTextureStorage9_2D(storage);
     return copyToSurface(storage9->getSurfaceLevel(level, true), xoffset, yoffset, width, height);
 }
 
-bool Image9::copyToStorage(TextureStorageInterfaceCube *storage, int face, int level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height)
+bool Image9::copyToStorageCube(TextureStorage *storage, int face, int level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height)
 {
     ASSERT(getSurface() != NULL);
-    TextureStorage9_Cube *storage9 = TextureStorage9_Cube::makeTextureStorage9_Cube(storage->getStorageInstance());
+    TextureStorage9_Cube *storage9 = TextureStorage9_Cube::makeTextureStorage9_Cube(storage);
     return copyToSurface(storage9->getCubeMapSurface(GL_TEXTURE_CUBE_MAP_POSITIVE_X + face, level, true), xoffset, yoffset, width, height);
 }
 
-bool Image9::copyToStorage(TextureStorageInterface3D *storage, int level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth)
+bool Image9::copyToStorage3D(TextureStorage *storage, int level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth)
 {
     // 3D textures are not supported by the D3D9 backend.
     UNREACHABLE();
     return false;
 }
 
-bool Image9::copyToStorage(TextureStorageInterface2DArray *storage, int level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height)
+bool Image9::copyToStorage2DArray(TextureStorage *storage, int level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height)
 {
     // 2D array textures are not supported by the D3D9 backend.
     UNREACHABLE();
@@ -371,7 +368,7 @@
         }
         else
         {
-            // UpdateSurface: source must be SYSTEMMEM, dest must be DEFAULT pools 
+            // UpdateSurface: source must be SYSTEMMEM, dest must be DEFAULT pools
             HRESULT result = device->UpdateSurface(sourceSurface, &rect, destSurface, &point);
             UNUSED_ASSERTION_VARIABLE(result);
             ASSERT(SUCCEEDED(result));
@@ -465,9 +462,9 @@
 
     if (colorbuffer)
     {
-        renderTarget = RenderTarget9::makeRenderTarget9(colorbuffer->getRenderTarget());
+        renderTarget = d3d9::GetAttachmentRenderTarget(colorbuffer);
     }
-    
+
     if (renderTarget)
     {
         surface = renderTarget->getSurface();
@@ -484,7 +481,7 @@
     IDirect3DSurface9 *renderTargetData = NULL;
     D3DSURFACE_DESC description;
     surface->GetDesc(&description);
-    
+
     HRESULT result = device->CreateOffscreenPlainSurface(description.Width, description.Height, description.Format, D3DPOOL_SYSTEMMEM, &renderTargetData, NULL);
 
     if (FAILED(result))
@@ -520,7 +517,7 @@
 
     D3DLOCKED_RECT destLock = {0};
     result = lock(&destLock, &destRect);
-    
+
     if (FAILED(result))
     {
         ERR("Failed to lock the destination surface (rectangle might be invalid).");
diff --git a/src/libGLESv2/renderer/d3d/d3d9/Image9.h b/src/libGLESv2/renderer/d3d/d3d9/Image9.h
index 2d1536f..08d8ee3 100644
--- a/src/libGLESv2/renderer/d3d/d3d9/Image9.h
+++ b/src/libGLESv2/renderer/d3d/d3d9/Image9.h
@@ -22,8 +22,6 @@
 {
 class Renderer;
 class Renderer9;
-class TextureStorageInterface2D;
-class TextureStorageInterfaceCube;
 
 class Image9 : public ImageD3D
 {
@@ -44,12 +42,12 @@
     virtual bool isDirty() const;
     IDirect3DSurface9 *getSurface();
 
-    virtual void setManagedSurface(TextureStorageInterface2D *storage, int level);
-    virtual void setManagedSurface(TextureStorageInterfaceCube *storage, int face, int level);
-    virtual bool copyToStorage(TextureStorageInterface2D *storage, int level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height);
-    virtual bool copyToStorage(TextureStorageInterfaceCube *storage, int face, int level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height);
-    virtual bool copyToStorage(TextureStorageInterface3D *storage, int level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth);
-    virtual bool copyToStorage(TextureStorageInterface2DArray *storage, int level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height);
+    virtual void setManagedSurface2D(TextureStorage *storage, int level);
+    virtual void setManagedSurfaceCube(TextureStorage *storage, int face, int level);
+    virtual bool copyToStorage2D(TextureStorage *storage, int level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height);
+    virtual bool copyToStorageCube(TextureStorage *storage, int face, int level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height);
+    virtual bool copyToStorage3D(TextureStorage *storage, int level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth);
+    virtual bool copyToStorage2DArray(TextureStorage *storage, int level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height);
 
     virtual void loadData(GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth,
                           GLint unpackAlignment, GLenum type, const void *input);
diff --git a/src/libGLESv2/renderer/d3d/d3d9/IndexBuffer9.cpp b/src/libGLESv2/renderer/d3d/d3d9/IndexBuffer9.cpp
index 472e698..1c51b9e 100644
--- a/src/libGLESv2/renderer/d3d/d3d9/IndexBuffer9.cpp
+++ b/src/libGLESv2/renderer/d3d/d3d9/IndexBuffer9.cpp
@@ -1,4 +1,3 @@
-#include "precompiled.h"
 //
 // 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
@@ -26,7 +25,7 @@
     SafeRelease(mIndexBuffer);
 }
 
-bool IndexBuffer9::initialize(unsigned int bufferSize, GLenum indexType, bool dynamic)
+gl::Error IndexBuffer9::initialize(unsigned int bufferSize, GLenum indexType, bool dynamic)
 {
     SafeRelease(mIndexBuffer);
 
@@ -34,28 +33,17 @@
 
     if (bufferSize > 0)
     {
-        D3DFORMAT format;
+        D3DFORMAT format = D3DFMT_UNKNOWN;
         if (indexType == GL_UNSIGNED_SHORT || indexType == GL_UNSIGNED_BYTE)
         {
             format = D3DFMT_INDEX16;
         }
         else if (indexType == GL_UNSIGNED_INT)
         {
-            if (mRenderer->getRendererExtensions().elementIndexUint)
-            {
-                format = D3DFMT_INDEX32;
-            }
-            else
-            {
-                ERR("Attempted to create a 32-bit index buffer but renderer does not support 32-bit indices.");
-                return false;
-            }
+            ASSERT(mRenderer->getRendererExtensions().elementIndexUint);
+            format = D3DFMT_INDEX32;
         }
-        else
-        {
-            ERR("Invalid index type %u.", indexType);
-            return false;
-        }
+        else UNREACHABLE();
 
         DWORD usageFlags = D3DUSAGE_WRITEONLY;
         if (dynamic)
@@ -66,8 +54,7 @@
         HRESULT result = mRenderer->createIndexBuffer(bufferSize, usageFlags, format, &mIndexBuffer);
         if (FAILED(result))
         {
-            ERR("Failed to create an index buffer of size %u, result: 0x%08x.", mBufferSize, result);
-            return false;
+            return gl::Error(GL_OUT_OF_MEMORY, "Failed to allocate internal index buffer of size, %lu.", bufferSize);
         }
     }
 
@@ -75,7 +62,7 @@
     mIndexType = indexType;
     mDynamic = dynamic;
 
-    return true;
+    return gl::Error(GL_NO_ERROR);
 }
 
 IndexBuffer9 *IndexBuffer9::makeIndexBuffer9(IndexBuffer *indexBuffer)
@@ -84,48 +71,40 @@
     return static_cast<IndexBuffer9*>(indexBuffer);
 }
 
-bool IndexBuffer9::mapBuffer(unsigned int offset, unsigned int size, void** outMappedMemory)
+gl::Error IndexBuffer9::mapBuffer(unsigned int offset, unsigned int size, void** outMappedMemory)
 {
-    if (mIndexBuffer)
+    if (!mIndexBuffer)
     {
-        DWORD lockFlags = mDynamic ? D3DLOCK_NOOVERWRITE : 0;
-
-        void *mapPtr = NULL;
-        HRESULT result = mIndexBuffer->Lock(offset, size, &mapPtr, lockFlags);
-        if (FAILED(result))
-        {
-            ERR("Index buffer lock failed with error 0x%08x", result);
-            return false;
-        }
-
-        *outMappedMemory = mapPtr;
-        return true;
+        return gl::Error(GL_OUT_OF_MEMORY, "Internal index buffer is not initialized.");
     }
-    else
+
+    DWORD lockFlags = mDynamic ? D3DLOCK_NOOVERWRITE : 0;
+
+    void *mapPtr = NULL;
+    HRESULT result = mIndexBuffer->Lock(offset, size, &mapPtr, lockFlags);
+    if (FAILED(result))
     {
-        ERR("Index buffer not initialized.");
-        return false;
+        return gl::Error(GL_OUT_OF_MEMORY, "Failed to lock internal index buffer, HRESULT: 0x%08x.", result);
     }
+
+    *outMappedMemory = mapPtr;
+    return gl::Error(GL_NO_ERROR);
 }
 
-bool IndexBuffer9::unmapBuffer()
+gl::Error IndexBuffer9::unmapBuffer()
 {
-    if (mIndexBuffer)
+    if (!mIndexBuffer)
     {
-        HRESULT result = mIndexBuffer->Unlock();
-        if (FAILED(result))
-        {
-            ERR("Index buffer unlock failed with error 0x%08x", result);
-            return false;
-        }
+        return gl::Error(GL_OUT_OF_MEMORY, "Internal index buffer is not initialized.");
+    }
 
-        return true;
-    }
-    else
+    HRESULT result = mIndexBuffer->Unlock();
+    if (FAILED(result))
     {
-        ERR("Index buffer not initialized.");
-        return false;
+        return gl::Error(GL_OUT_OF_MEMORY, "Failed to unlock internal index buffer, HRESULT: 0x%08x.", result);
     }
+
+    return gl::Error(GL_NO_ERROR);
 }
 
 GLenum IndexBuffer9::getIndexType() const
@@ -138,7 +117,7 @@
     return mBufferSize;
 }
 
-bool IndexBuffer9::setSize(unsigned int bufferSize, GLenum indexType)
+gl::Error IndexBuffer9::setSize(unsigned int bufferSize, GLenum indexType)
 {
     if (bufferSize > mBufferSize || indexType != mIndexType)
     {
@@ -146,38 +125,33 @@
     }
     else
     {
-        return true;
+        return gl::Error(GL_NO_ERROR);
     }
 }
 
-bool IndexBuffer9::discard()
+gl::Error IndexBuffer9::discard()
 {
-    if (mIndexBuffer)
+    if (!mIndexBuffer)
     {
-        void *dummy;
-        HRESULT result;
-
-        result = mIndexBuffer->Lock(0, 1, &dummy, D3DLOCK_DISCARD);
-        if (FAILED(result))
-        {
-            ERR("Discard lock failed with error 0x%08x", result);
-            return false;
-        }
-
-        result = mIndexBuffer->Unlock();
-        if (FAILED(result))
-        {
-            ERR("Discard unlock failed with error 0x%08x", result);
-            return false;
-        }
-
-        return true;
+        return gl::Error(GL_OUT_OF_MEMORY, "Internal index buffer is not initialized.");
     }
-    else
+
+    void *dummy;
+    HRESULT result;
+
+    result = mIndexBuffer->Lock(0, 1, &dummy, D3DLOCK_DISCARD);
+    if (FAILED(result))
     {
-        ERR("Index buffer not initialized.");
-        return false;
+        return gl::Error(GL_OUT_OF_MEMORY, "Failed to lock internal index buffer, HRESULT: 0x%08x.", result);
     }
+
+    result = mIndexBuffer->Unlock();
+    if (FAILED(result))
+    {
+        return gl::Error(GL_OUT_OF_MEMORY, "Failed to unlock internal index buffer, HRESULT: 0x%08x.", result);
+    }
+
+    return gl::Error(GL_NO_ERROR);
 }
 
 D3DFORMAT IndexBuffer9::getIndexFormat() const
@@ -196,4 +170,4 @@
     return mIndexBuffer;
 }
 
-}
\ No newline at end of file
+}
diff --git a/src/libGLESv2/renderer/d3d/d3d9/IndexBuffer9.h b/src/libGLESv2/renderer/d3d/d3d9/IndexBuffer9.h
index cfc20e1..d0970d6 100644
--- a/src/libGLESv2/renderer/d3d/d3d9/IndexBuffer9.h
+++ b/src/libGLESv2/renderer/d3d/d3d9/IndexBuffer9.h
@@ -21,18 +21,18 @@
     explicit IndexBuffer9(Renderer9 *const renderer);
     virtual ~IndexBuffer9();
 
-    virtual bool initialize(unsigned int bufferSize, GLenum indexType, bool dynamic);
+    virtual gl::Error initialize(unsigned int bufferSize, GLenum indexType, bool dynamic);
 
     static IndexBuffer9 *makeIndexBuffer9(IndexBuffer *indexBuffer);
 
-    virtual bool mapBuffer(unsigned int offset, unsigned int size, void** outMappedMemory);
-    virtual bool unmapBuffer();
+    virtual gl::Error mapBuffer(unsigned int offset, unsigned int size, void** outMappedMemory);
+    virtual gl::Error unmapBuffer();
 
     virtual GLenum getIndexType() const;
     virtual unsigned int getBufferSize() const;
-    virtual bool setSize(unsigned int bufferSize, GLenum indexType);
+    virtual gl::Error setSize(unsigned int bufferSize, GLenum indexType);
 
-    virtual bool discard();
+    virtual gl::Error discard();
 
     D3DFORMAT getIndexFormat() const;
     IDirect3DIndexBuffer9 *getBuffer() const;
diff --git a/src/libGLESv2/renderer/d3d/d3d9/Query9.cpp b/src/libGLESv2/renderer/d3d/d3d9/Query9.cpp
index 3c6f1d0..815fc01 100644
--- a/src/libGLESv2/renderer/d3d/d3d9/Query9.cpp
+++ b/src/libGLESv2/renderer/d3d/d3d9/Query9.cpp
@@ -1,4 +1,3 @@
-#include "precompiled.h"
 //
 // 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
@@ -7,19 +6,22 @@
 
 // Query9.cpp: Defines the rx::Query9 class which implements rx::QueryImpl.
 
-
 #include "libGLESv2/renderer/d3d/d3d9/Query9.h"
-#include "libGLESv2/main.h"
 #include "libGLESv2/renderer/d3d/d3d9/renderer9_utils.h"
 #include "libGLESv2/renderer/d3d/d3d9/Renderer9.h"
+#include "libGLESv2/main.h"
+
+#include <GLES2/gl2ext.h>
 
 namespace rx
 {
-
-Query9::Query9(rx::Renderer9 *renderer, GLenum type) : QueryImpl(type)
+Query9::Query9(rx::Renderer9 *renderer, GLenum type)
+    : QueryImpl(type),
+      mResult(GL_FALSE),
+      mQueryFinished(false),
+      mRenderer(renderer),
+      mQuery(NULL)
 {
-    mRenderer = renderer;
-    mQuery = NULL;
 }
 
 Query9::~Query9()
@@ -27,73 +29,91 @@
     SafeRelease(mQuery);
 }
 
-void Query9::begin()
+gl::Error Query9::begin()
 {
     if (mQuery == NULL)
     {
-        if (FAILED(mRenderer->getDevice()->CreateQuery(D3DQUERYTYPE_OCCLUSION, &mQuery)))
+        HRESULT result = mRenderer->getDevice()->CreateQuery(D3DQUERYTYPE_OCCLUSION, &mQuery);
+        if (FAILED(result))
         {
-            return gl::error(GL_OUT_OF_MEMORY);
+            return gl::Error(GL_OUT_OF_MEMORY, "Internal query creation failed, result: 0x%X.", result);
         }
     }
 
     HRESULT result = mQuery->Issue(D3DISSUE_BEGIN);
-    UNUSED_ASSERTION_VARIABLE(result);
     ASSERT(SUCCEEDED(result));
+    if (FAILED(result))
+    {
+        return gl::Error(GL_OUT_OF_MEMORY, "Failed to begin internal query, result: 0x%X.", result);
+    }
+
+    return gl::Error(GL_NO_ERROR);
 }
 
-void Query9::end()
+gl::Error Query9::end()
 {
     ASSERT(mQuery);
 
     HRESULT result = mQuery->Issue(D3DISSUE_END);
-    UNUSED_ASSERTION_VARIABLE(result);
     ASSERT(SUCCEEDED(result));
+    if (FAILED(result))
+    {
+        return gl::Error(GL_OUT_OF_MEMORY, "Failed to end internal query, result: 0x%X.", result);
+    }
 
-    mStatus = GL_FALSE;
+    mQueryFinished = false;
     mResult = GL_FALSE;
+
+    return gl::Error(GL_NO_ERROR);
 }
 
-GLuint Query9::getResult()
+gl::Error Query9::getResult(GLuint *params)
 {
-    if (mQuery != NULL)
+    while (!mQueryFinished)
     {
-        while (!testQuery())
+        gl::Error error = testQuery();
+        if (error.isError())
+        {
+            return error;
+        }
+
+        if (!mQueryFinished)
         {
             Sleep(0);
-            // explicitly check for device loss
-            // some drivers seem to return S_FALSE even if the device is lost
-            // instead of D3DERR_DEVICELOST like they should
-            if (mRenderer->testDeviceLost(true))
-            {
-                return gl::error(GL_OUT_OF_MEMORY, 0);
-            }
         }
     }
 
-    return mResult;
+    ASSERT(mQueryFinished);
+    *params = mResult;
+
+    return gl::Error(GL_NO_ERROR);
 }
 
-GLboolean Query9::isResultAvailable()
+gl::Error Query9::isResultAvailable(GLuint *available)
 {
-    if (mQuery != NULL)
+    gl::Error error = testQuery();
+    if (error.isError())
     {
-        testQuery();
+        return error;
     }
 
-    return mStatus;
+    *available = (mQueryFinished ? GL_TRUE : GL_FALSE);
+
+    return gl::Error(GL_NO_ERROR);
 }
 
-GLboolean Query9::testQuery()
+gl::Error Query9::testQuery()
 {
-    if (mQuery != NULL && mStatus != GL_TRUE)
+    if (!mQueryFinished)
     {
+        ASSERT(mQuery);
+
         DWORD numPixels = 0;
 
         HRESULT hres = mQuery->GetData(&numPixels, sizeof(DWORD), D3DGETDATA_FLUSH);
         if (hres == S_OK)
         {
-            mStatus =  GL_TRUE;
+            mQueryFinished = true;
 
             switch (getType())
             {
@@ -101,25 +121,24 @@
               case GL_ANY_SAMPLES_PASSED_CONSERVATIVE_EXT:
                 mResult = (numPixels > 0) ? GL_TRUE : GL_FALSE;
                 break;
+
               default:
-                ASSERT(false);
+                UNREACHABLE();
+                break;
             }
         }
         else if (d3d9::isDeviceLostError(hres))
         {
             mRenderer->notifyDeviceLost();
-            return gl::error(GL_OUT_OF_MEMORY, GL_TRUE);
+            return gl::Error(GL_OUT_OF_MEMORY, "Failed to test get query result, device is lost.");
         }
-
-        return mStatus;
+        else if (mRenderer->testDeviceLost(true))
+        {
+            return gl::Error(GL_OUT_OF_MEMORY, "Failed to test get query result, device is lost.");
+        }
     }
 
-    return GL_TRUE; // prevent blocking when query is null
-}
-
-bool Query9::isStarted() const
-{
-    return (mQuery != NULL);
+    return gl::Error(GL_NO_ERROR);
 }
 
 }
diff --git a/src/libGLESv2/renderer/d3d/d3d9/Query9.h b/src/libGLESv2/renderer/d3d/d3d9/Query9.h
index 6290623..513e0ba 100644
--- a/src/libGLESv2/renderer/d3d/d3d9/Query9.h
+++ b/src/libGLESv2/renderer/d3d/d3d9/Query9.h
@@ -21,16 +21,18 @@
     Query9(rx::Renderer9 *renderer, GLenum type);
     virtual ~Query9();
 
-    virtual void begin();
-    virtual void end();
-    virtual GLuint getResult();
-    virtual GLboolean isResultAvailable();
-    virtual bool isStarted() const;
+    virtual gl::Error begin();
+    virtual gl::Error end();
+    virtual gl::Error getResult(GLuint *params);
+    virtual gl::Error isResultAvailable(GLuint *available);
 
   private:
     DISALLOW_COPY_AND_ASSIGN(Query9);
 
-    GLboolean testQuery();
+    gl::Error testQuery();
+
+    GLuint mResult;
+    bool mQueryFinished;
 
     rx::Renderer9 *mRenderer;
     IDirect3DQuery9 *mQuery;
diff --git a/src/libGLESv2/renderer/d3d/d3d9/RenderTarget9.cpp b/src/libGLESv2/renderer/d3d/d3d9/RenderTarget9.cpp
index c8b5607..13321ac 100644
--- a/src/libGLESv2/renderer/d3d/d3d9/RenderTarget9.cpp
+++ b/src/libGLESv2/renderer/d3d/d3d9/RenderTarget9.cpp
@@ -1,4 +1,3 @@
-#include "precompiled.h"
 //
 // Copyright (c) 2012-2014 The ANGLE Project Authors. All rights reserved.
 // Use of this source code is governed by a BSD-style license that can be
@@ -10,7 +9,6 @@
 
 #include "libGLESv2/renderer/d3d/d3d9/RenderTarget9.h"
 #include "libGLESv2/renderer/d3d/d3d9/Renderer9.h"
-
 #include "libGLESv2/renderer/d3d/d3d9/renderer9_utils.h"
 #include "libGLESv2/renderer/d3d/d3d9/formatutils9.h"
 #include "libGLESv2/main.h"
diff --git a/src/libGLESv2/renderer/d3d/d3d9/Renderer9.cpp b/src/libGLESv2/renderer/d3d/d3d9/Renderer9.cpp
index 5959fca..dd75048 100644
--- a/src/libGLESv2/renderer/d3d/d3d9/Renderer9.cpp
+++ b/src/libGLESv2/renderer/d3d/d3d9/Renderer9.cpp
@@ -1,4 +1,3 @@
-#include "precompiled.h"
 //
 // Copyright (c) 2012-2014 The ANGLE Project Authors. All rights reserved.
 // Use of this source code is governed by a BSD-style license that can be
@@ -7,17 +6,6 @@
 
 // Renderer9.cpp: Implements a back-end specific class for the D3D9 renderer.
 
-#include "common/utilities.h"
-
-#include "libGLESv2/main.h"
-#include "libGLESv2/Buffer.h"
-#include "libGLESv2/Texture.h"
-#include "libGLESv2/Framebuffer.h"
-#include "libGLESv2/FramebufferAttachment.h"
-#include "libGLESv2/Renderbuffer.h"
-#include "libGLESv2/ProgramBinary.h"
-#include "libGLESv2/renderer/d3d/IndexDataManager.h"
-#include "libGLESv2/renderer/d3d/TextureD3D.h"
 #include "libGLESv2/renderer/d3d/d3d9/Renderer9.h"
 #include "libGLESv2/renderer/d3d/d3d9/renderer9_utils.h"
 #include "libGLESv2/renderer/d3d/d3d9/formatutils9.h"
@@ -33,12 +21,28 @@
 #include "libGLESv2/renderer/d3d/d3d9/Query9.h"
 #include "libGLESv2/renderer/d3d/d3d9/Fence9.h"
 #include "libGLESv2/renderer/d3d/d3d9/VertexArray9.h"
+#include "libGLESv2/renderer/d3d/IndexDataManager.h"
+#include "libGLESv2/renderer/d3d/ProgramD3D.h"
+#include "libGLESv2/renderer/d3d/ShaderD3D.h"
+#include "libGLESv2/renderer/d3d/TextureD3D.h"
+#include "libGLESv2/renderer/d3d/TransformFeedbackD3D.h"
+#include "libGLESv2/main.h"
+#include "libGLESv2/Buffer.h"
+#include "libGLESv2/Texture.h"
+#include "libGLESv2/Framebuffer.h"
+#include "libGLESv2/FramebufferAttachment.h"
+#include "libGLESv2/Renderbuffer.h"
+#include "libGLESv2/ProgramBinary.h"
 #include "libGLESv2/angletypes.h"
 
 #include "libEGL/Display.h"
 
+#include "common/utilities.h"
+
 #include "third_party/trace_event/trace_event.h"
 
+#include <sstream>
+
 // Can also be enabled by defining FORCE_REF_RAST in the project's predefined macros
 #define REF_RAST 0
 
@@ -122,6 +126,7 @@
     mVertexDataManager = NULL;
     mIndexDataManager = NULL;
     mLineLoopIB = NULL;
+    mCountingIB = NULL;
 
     mMaxNullColorbufferLRU = 0;
     for (int i = 0; i < NUM_NULL_COLORBUFFER_CACHE_ENTRIES; i++)
@@ -153,6 +158,7 @@
 
 void Renderer9::release()
 {
+    releaseShaderCompiler();
     releaseDeviceResources();
 
     SafeRelease(mDevice);
@@ -373,6 +379,17 @@
         mDevice->SetRenderState(D3DRS_POINTSIZE_MAX, 0x3F800000);   // 1.0f
     }
 
+    const gl::Caps &rendererCaps = getRendererCaps();
+
+    mForceSetVertexSamplerStates.resize(rendererCaps.maxVertexTextureImageUnits);
+    mCurVertexSamplerStates.resize(rendererCaps.maxVertexTextureImageUnits);
+
+    mForceSetPixelSamplerStates.resize(rendererCaps.maxTextureImageUnits);
+    mCurPixelSamplerStates.resize(rendererCaps.maxTextureImageUnits);
+
+    mCurVertexTextureSerials.resize(rendererCaps.maxVertexTextureImageUnits);
+    mCurPixelTextureSerials.resize(rendererCaps.maxTextureImageUnits);
+
     markAllStateDirty();
 
     mSceneStarted = false;
@@ -600,6 +617,11 @@
     return new Fence9(this);
 }
 
+TransformFeedbackImpl* Renderer9::createTransformFeedback()
+{
+    return new TransformFeedbackD3D();
+}
+
 bool Renderer9::supportsFastCopyBufferToTexture(GLenum internalFormat) const
 {
     // Pixel buffer objects are not supported in D3D9, since D3D9 is ES2-only and PBOs are ES3.
@@ -622,8 +644,8 @@
 
 void Renderer9::setSamplerState(gl::SamplerType type, int index, const gl::SamplerState &samplerState)
 {
-    bool *forceSetSamplers = (type == gl::SAMPLER_PIXEL) ? mForceSetPixelSamplerStates : mForceSetVertexSamplerStates;
-    gl::SamplerState *appliedSamplers = (type == gl::SAMPLER_PIXEL) ? mCurPixelSamplerStates: mCurVertexSamplerStates;
+    std::vector<bool> &forceSetSamplers = (type == gl::SAMPLER_PIXEL) ? mForceSetPixelSamplerStates : mForceSetVertexSamplerStates;
+    std::vector<gl::SamplerState> &appliedSamplers = (type == gl::SAMPLER_PIXEL) ? mCurPixelSamplerStates: mCurVertexSamplerStates;
 
     if (forceSetSamplers[index] || memcmp(&samplerState, &appliedSamplers[index], sizeof(gl::SamplerState)) != 0)
     {
@@ -657,16 +679,16 @@
     unsigned int serial = 0;
     bool forceSetTexture = false;
 
-    unsigned int *appliedSerials = (type == gl::SAMPLER_PIXEL) ? mCurPixelTextureSerials : mCurVertexTextureSerials;
+    std::vector<unsigned int> &appliedSerials = (type == gl::SAMPLER_PIXEL) ? mCurPixelTextureSerials : mCurVertexTextureSerials;
 
     if (texture)
     {
-        TextureImpl* textureImpl = texture->getImplementation();
+        TextureD3D* textureImpl = TextureD3D::makeTextureD3D(texture->getImplementation());
 
-        TextureStorageInterface *texStorage = textureImpl->getNativeTexture();
+        TextureStorage *texStorage = textureImpl->getNativeTexture();
         if (texStorage)
         {
-            TextureStorage9 *storage9 = TextureStorage9::makeTextureStorage9(texStorage->getStorageInstance());
+            TextureStorage9 *storage9 = TextureStorage9::makeTextureStorage9(texStorage);
             d3dTexture = storage9->getBaseTexture();
         }
         // If we get NULL back from getBaseTexture here, something went wrong
@@ -953,7 +975,7 @@
     mForceSetScissor = false;
 }
 
-bool Renderer9::setViewport(const gl::Rectangle &viewport, float zNear, float zFar, GLenum drawMode, GLenum frontFace,
+void Renderer9::setViewport(const gl::Rectangle &viewport, float zNear, float zFar, GLenum drawMode, GLenum frontFace,
                             bool ignoreViewport)
 {
     gl::Rectangle actualViewport = viewport;
@@ -977,11 +999,6 @@
     dxViewport.MinZ = actualZNear;
     dxViewport.MaxZ = actualZFar;
 
-    if (dxViewport.Width <= 0 || dxViewport.Height <= 0)
-    {
-        return false;   // Nothing to render
-    }
-
     float depthFront = !gl::IsTriangleMode(drawMode) ? 0.0f : (frontFace == GL_CCW ? 1.0f : -1.0f);
 
     bool viewportChanged = mForceSetViewport || memcmp(&actualViewport, &mCurViewport, sizeof(gl::Rectangle)) != 0 ||
@@ -1034,7 +1051,6 @@
     }
 
     mForceSetViewport = false;
-    return true;
 }
 
 bool Renderer9::applyPrimitiveType(GLenum mode, GLsizei count)
@@ -1102,7 +1118,7 @@
     }
 
     gl::Renderbuffer *nullRenderbuffer = new gl::Renderbuffer(0, new gl::Colorbuffer(this, width, height, GL_NONE, 0));
-    gl::RenderbufferAttachment *nullbuffer = new gl::RenderbufferAttachment(nullRenderbuffer);
+    gl::RenderbufferAttachment *nullbuffer = new gl::RenderbufferAttachment(GL_NONE, nullRenderbuffer);
 
     // add nullbuffer to the cache
     NullColorbufferCacheEntry *oldest = &mNullColorbufferCache[0];
@@ -1139,16 +1155,16 @@
     }
 
     bool renderTargetChanged = false;
-    unsigned int renderTargetSerial = attachment->getSerial();
+    unsigned int renderTargetSerial = GetAttachmentSerial(attachment);
     if (renderTargetSerial != mAppliedRenderTargetSerial)
     {
         // Apply the render target on the device
         IDirect3DSurface9 *renderTargetSurface = NULL;
 
-        RenderTarget *renderTarget = attachment->getRenderTarget();
+        RenderTarget9 *renderTarget = d3d9::GetAttachmentRenderTarget(attachment);
         if (renderTarget)
         {
-            renderTargetSurface = RenderTarget9::makeRenderTarget9(renderTarget)->getSurface();
+            renderTargetSurface = renderTarget->getSurface();
         }
 
         if (!renderTargetSurface)
@@ -1169,12 +1185,12 @@
     unsigned int stencilbufferSerial = 0;
     if (depthStencil)
     {
-        depthbufferSerial = depthStencil->getSerial();
+        depthbufferSerial = GetAttachmentSerial(depthStencil);
     }
     else if (framebuffer->getStencilbuffer())
     {
         depthStencil = framebuffer->getStencilbuffer();
-        stencilbufferSerial = depthStencil->getSerial();
+        stencilbufferSerial = GetAttachmentSerial(depthStencil);
     }
 
     if (depthbufferSerial != mAppliedDepthbufferSerial ||
@@ -1188,11 +1204,11 @@
         if (depthStencil)
         {
             IDirect3DSurface9 *depthStencilSurface = NULL;
-            RenderTarget *depthStencilRenderTarget = depthStencil->getDepthStencil();
+            rx::RenderTarget9 *depthStencilRenderTarget = d3d9::GetAttachmentRenderTarget(depthStencil);
 
             if (depthStencilRenderTarget)
             {
-                depthStencilSurface = RenderTarget9::makeRenderTarget9(depthStencilRenderTarget)->getSurface();
+                depthStencilSurface = depthStencilRenderTarget->getSurface();
             }
 
             if (!depthStencilSurface)
@@ -1244,39 +1260,40 @@
     return true;
 }
 
-GLenum Renderer9::applyVertexBuffer(gl::ProgramBinary *programBinary, const gl::VertexAttribute vertexAttributes[], const gl::VertexAttribCurrentValueData currentValues[],
-                                    GLint first, GLsizei count, GLsizei instances)
+gl::Error Renderer9::applyVertexBuffer(gl::ProgramBinary *programBinary, const gl::VertexAttribute vertexAttributes[], const gl::VertexAttribCurrentValueData currentValues[],
+                                       GLint first, GLsizei count, GLsizei instances)
 {
     TranslatedAttribute attributes[gl::MAX_VERTEX_ATTRIBS];
-    GLenum err = mVertexDataManager->prepareVertexData(vertexAttributes, currentValues, programBinary, first, count, attributes, instances);
-    if (err != GL_NO_ERROR)
+    gl::Error error = mVertexDataManager->prepareVertexData(vertexAttributes, currentValues, programBinary, first, count, attributes, instances);
+    if (error.isError())
     {
-        return err;
+        return error;
     }
 
     return mVertexDeclarationCache.applyDeclaration(mDevice, attributes, programBinary, instances, &mRepeatDraw);
 }
 
 // Applies the indices and element array bindings to the Direct3D 9 device
-GLenum Renderer9::applyIndexBuffer(const GLvoid *indices, gl::Buffer *elementArrayBuffer, GLsizei count, GLenum mode, GLenum type, TranslatedIndexData *indexInfo)
+gl::Error Renderer9::applyIndexBuffer(const GLvoid *indices, gl::Buffer *elementArrayBuffer, GLsizei count, GLenum mode, GLenum type, TranslatedIndexData *indexInfo)
 {
-    GLenum err = mIndexDataManager->prepareIndexData(type, count, elementArrayBuffer, indices, indexInfo);
-
-    if (err == GL_NO_ERROR)
+    gl::Error error = mIndexDataManager->prepareIndexData(type, count, elementArrayBuffer, indices, indexInfo);
+    if (error.isError())
     {
-        // Directly binding the storage buffer is not supported for d3d9
-        ASSERT(indexInfo->storage == NULL);
-
-        if (indexInfo->serial != mAppliedIBSerial)
-        {
-            IndexBuffer9* indexBuffer = IndexBuffer9::makeIndexBuffer9(indexInfo->indexBuffer);
-
-            mDevice->SetIndices(indexBuffer->getBuffer());
-            mAppliedIBSerial = indexInfo->serial;
-        }
+        return error;
     }
 
-    return err;
+    // Directly binding the storage buffer is not supported for d3d9
+    ASSERT(indexInfo->storage == NULL);
+
+    if (indexInfo->serial != mAppliedIBSerial)
+    {
+        IndexBuffer9* indexBuffer = IndexBuffer9::makeIndexBuffer9(indexInfo->indexBuffer);
+
+        mDevice->SetIndices(indexBuffer->getBuffer());
+        mAppliedIBSerial = indexInfo->serial;
+    }
+
+    return gl::Error(GL_NO_ERROR);
 }
 
 void Renderer9::applyTransformFeedbackBuffers(gl::Buffer *transformFeedbackBuffers[], GLintptr offsets[])
@@ -1296,26 +1313,23 @@
     }
     else if (instances > 0)
     {
-        StaticIndexBufferInterface *countingIB = mIndexDataManager->getCountingIndices(count);
-        if (countingIB)
+        StaticIndexBufferInterface *countingIB = getCountingIB(count);
+        if (!countingIB)
         {
-            if (mAppliedIBSerial != countingIB->getSerial())
-            {
-                IndexBuffer9 *indexBuffer = IndexBuffer9::makeIndexBuffer9(countingIB->getIndexBuffer());
-
-                mDevice->SetIndices(indexBuffer->getBuffer());
-                mAppliedIBSerial = countingIB->getSerial();
-            }
-
-            for (int i = 0; i < mRepeatDraw; i++)
-            {
-                mDevice->DrawIndexedPrimitive(mPrimitiveType, 0, 0, count, 0, mPrimitiveCount);
-            }
+            return;
         }
-        else
+
+        if (mAppliedIBSerial != countingIB->getSerial())
         {
-            ERR("Could not create a counting index buffer for glDrawArraysInstanced.");
-            return gl::error(GL_OUT_OF_MEMORY);
+            IndexBuffer9 *indexBuffer = IndexBuffer9::makeIndexBuffer9(countingIB->getIndexBuffer());
+
+            mDevice->SetIndices(indexBuffer->getBuffer());
+            mAppliedIBSerial = countingIB->getSerial();
+        }
+
+        for (int i = 0; i < mRepeatDraw; i++)
+        {
+            mDevice->DrawIndexedPrimitive(mPrimitiveType, 0, 0, count, 0, mPrimitiveCount);
         }
     }
     else   // Regular case
@@ -1329,20 +1343,22 @@
 {
     startScene();
 
+    int minIndex = static_cast<int>(indexInfo.indexRange.start);
+
     if (mode == GL_POINTS)
     {
-        drawIndexedPoints(count, type, indices, indexInfo.minIndex, elementArrayBuffer);
+        drawIndexedPoints(count, type, indices, minIndex, elementArrayBuffer);
     }
     else if (mode == GL_LINE_LOOP)
     {
-        drawLineLoop(count, type, indices, indexInfo.minIndex, elementArrayBuffer);
+        drawLineLoop(count, type, indices, minIndex, elementArrayBuffer);
     }
     else
     {
         for (int i = 0; i < mRepeatDraw; i++)
         {
-            GLsizei vertexCount = indexInfo.maxIndex - indexInfo.minIndex + 1;
-            mDevice->DrawIndexedPrimitive(mPrimitiveType, -(INT)indexInfo.minIndex, indexInfo.minIndex, vertexCount, indexInfo.startIndex, mPrimitiveCount);
+            GLsizei vertexCount = static_cast<int>(indexInfo.indexRange.length()) + 1;
+            mDevice->DrawIndexedPrimitive(mPrimitiveType, -minIndex, minIndex, vertexCount, indexInfo.startIndex, mPrimitiveCount);
         }
     }
 }
@@ -1365,10 +1381,10 @@
         if (!mLineLoopIB)
         {
             mLineLoopIB = new StreamingIndexBufferInterface(this);
-            if (!mLineLoopIB->reserveBufferSpace(INITIAL_INDEX_BUFFER_SIZE, GL_UNSIGNED_INT))
+            gl::Error error = mLineLoopIB->reserveBufferSpace(INITIAL_INDEX_BUFFER_SIZE, GL_UNSIGNED_INT);
+            if (error.isError())
             {
-                delete mLineLoopIB;
-                mLineLoopIB = NULL;
+                SafeDelete(mLineLoopIB);
 
                 ERR("Could not create a 32-bit looping index buffer for GL_LINE_LOOP.");
                 return gl::error(GL_OUT_OF_MEMORY);
@@ -1384,8 +1400,9 @@
             return gl::error(GL_OUT_OF_MEMORY);
         }
 
-        const unsigned int spaceNeeded = (static_cast<unsigned int>(count) + 1) * sizeof(unsigned int);
-        if (!mLineLoopIB->reserveBufferSpace(spaceNeeded, GL_UNSIGNED_INT))
+        const unsigned int spaceNeeded = (static_cast<unsigned int>(count)+1) * sizeof(unsigned int);
+        gl::Error error = mLineLoopIB->reserveBufferSpace(spaceNeeded, GL_UNSIGNED_INT);
+        if (error.isError())
         {
             ERR("Could not reserve enough space in looping index buffer for GL_LINE_LOOP.");
             return gl::error(GL_OUT_OF_MEMORY);
@@ -1393,7 +1410,8 @@
 
         void* mappedMemory = NULL;
         unsigned int offset = 0;
-        if (!mLineLoopIB->mapBuffer(spaceNeeded, &mappedMemory, &offset))
+        error = mLineLoopIB->mapBuffer(spaceNeeded, &mappedMemory, &offset);
+        if (error.isError())
         {
             ERR("Could not map index buffer for GL_LINE_LOOP.");
             return gl::error(GL_OUT_OF_MEMORY);
@@ -1435,7 +1453,8 @@
           default: UNREACHABLE();
         }
 
-        if (!mLineLoopIB->unmapBuffer())
+        error = mLineLoopIB->unmapBuffer();
+        if (error.isError())
         {
             ERR("Could not unmap index buffer for GL_LINE_LOOP.");
             return gl::error(GL_OUT_OF_MEMORY);
@@ -1446,10 +1465,10 @@
         if (!mLineLoopIB)
         {
             mLineLoopIB = new StreamingIndexBufferInterface(this);
-            if (!mLineLoopIB->reserveBufferSpace(INITIAL_INDEX_BUFFER_SIZE, GL_UNSIGNED_SHORT))
+            gl::Error error = mLineLoopIB->reserveBufferSpace(INITIAL_INDEX_BUFFER_SIZE, GL_UNSIGNED_SHORT);
+            if (error.isError())
             {
-                delete mLineLoopIB;
-                mLineLoopIB = NULL;
+                SafeDelete(mLineLoopIB);
 
                 ERR("Could not create a 16-bit looping index buffer for GL_LINE_LOOP.");
                 return gl::error(GL_OUT_OF_MEMORY);
@@ -1466,7 +1485,8 @@
         }
 
         const unsigned int spaceNeeded = (static_cast<unsigned int>(count) + 1) * sizeof(unsigned short);
-        if (!mLineLoopIB->reserveBufferSpace(spaceNeeded, GL_UNSIGNED_SHORT))
+        gl::Error error = mLineLoopIB->reserveBufferSpace(spaceNeeded, GL_UNSIGNED_SHORT);
+        if (error.isError())
         {
             ERR("Could not reserve enough space in looping index buffer for GL_LINE_LOOP.");
             return gl::error(GL_OUT_OF_MEMORY);
@@ -1474,7 +1494,8 @@
 
         void* mappedMemory = NULL;
         unsigned int offset;
-        if (mLineLoopIB->mapBuffer(spaceNeeded, &mappedMemory, &offset))
+        error = mLineLoopIB->mapBuffer(spaceNeeded, &mappedMemory, &offset);
+        if (error.isError())
         {
             ERR("Could not map index buffer for GL_LINE_LOOP.");
             return gl::error(GL_OUT_OF_MEMORY);
@@ -1516,7 +1537,8 @@
           default: UNREACHABLE();
         }
 
-        if (!mLineLoopIB->unmapBuffer())
+        error = mLineLoopIB->unmapBuffer();
+        if (error.isError())
         {
             ERR("Could not unmap index buffer for GL_LINE_LOOP.");
             return gl::error(GL_OUT_OF_MEMORY);
@@ -1565,6 +1587,84 @@
     }
 }
 
+StaticIndexBufferInterface *Renderer9::getCountingIB(size_t count)
+{
+    // Update the counting index buffer if it is not large enough or has not been created yet.
+    if (count <= 65536)   // 16-bit indices
+    {
+        const unsigned int spaceNeeded = count * sizeof(unsigned short);
+
+        if (!mCountingIB || mCountingIB->getBufferSize() < spaceNeeded)
+        {
+            SafeDelete(mCountingIB);
+            mCountingIB = new StaticIndexBufferInterface(this);
+            mCountingIB->reserveBufferSpace(spaceNeeded, GL_UNSIGNED_SHORT);
+
+            void *mappedMemory = NULL;
+            gl::Error error = mCountingIB->mapBuffer(spaceNeeded, &mappedMemory, NULL);
+            if (error.isError())
+            {
+                ERR("Failed to map counting buffer.");
+                return NULL;
+            }
+
+            unsigned short *data = reinterpret_cast<unsigned short*>(mappedMemory);
+            for (size_t i = 0; i < count; i++)
+            {
+                data[i] = i;
+            }
+
+            error = mCountingIB->unmapBuffer();
+            if (error.isError())
+            {
+                ERR("Failed to unmap counting buffer.");
+                return NULL;
+            }
+        }
+
+        return mCountingIB;
+    }
+    else if (getRendererExtensions().elementIndexUint)
+    {
+        const unsigned int spaceNeeded = count * sizeof(unsigned int);
+
+        if (!mCountingIB || mCountingIB->getBufferSize() < spaceNeeded)
+        {
+            SafeDelete(mCountingIB);
+            mCountingIB = new StaticIndexBufferInterface(this);
+            mCountingIB->reserveBufferSpace(spaceNeeded, GL_UNSIGNED_INT);
+
+            void *mappedMemory = NULL;
+            gl::Error error = mCountingIB->mapBuffer(spaceNeeded, &mappedMemory, NULL);
+            if (error.isError())
+            {
+                ERR("Failed to map counting buffer.");
+                return NULL;
+            }
+
+            unsigned int *data = reinterpret_cast<unsigned int*>(mappedMemory);
+            for (size_t i = 0; i < count; i++)
+            {
+                data[i] = i;
+            }
+
+            error = mCountingIB->unmapBuffer();
+            if (error.isError())
+            {
+                ERR("Failed to unmap counting buffer.");
+                return NULL;
+            }
+        }
+
+        return mCountingIB;
+    }
+    else
+    {
+        ERR("Could not create a counting index buffer for glDrawArraysInstanced.");
+        return gl::error<StaticIndexBufferInterface*>(GL_OUT_OF_MEMORY, NULL);
+    }
+}
+
 void Renderer9::applyShaders(gl::ProgramBinary *programBinary, const gl::VertexFormat inputLayout[], const gl::Framebuffer *framebuffer,
                              bool rasterizerDiscard, bool transformFeedbackActive)
 {
@@ -1702,13 +1802,13 @@
     applyUniformnfv(targetUniform, (GLfloat*)vector);
 }
 
-void Renderer9::clear(const gl::ClearParameters &clearParams, gl::Framebuffer *frameBuffer)
+gl::Error Renderer9::clear(const gl::ClearParameters &clearParams, gl::Framebuffer *frameBuffer)
 {
     if (clearParams.colorClearType != GL_FLOAT)
     {
         // Clearing buffers with non-float values is not supported by Renderer9 and ES 2.0
         UNREACHABLE();
-        return;
+        return gl::Error(GL_INVALID_OPERATION);
     }
 
     bool clearColor = clearParams.clearColor[0];
@@ -1718,7 +1818,7 @@
         {
             // Clearing individual buffers other than buffer zero is not supported by Renderer9 and ES 2.0
             UNREACHABLE();
-            return;
+            return gl::Error(GL_INVALID_OPERATION);
         }
     }
 
@@ -1915,6 +2015,8 @@
 
         mDevice->Clear(0, NULL, dxClearFlags, color, depth, stencil);
     }
+
+    return gl::Error(GL_NO_ERROR);
 }
 
 void Renderer9::markAllStateDirty()
@@ -1931,12 +2033,15 @@
     mForceSetViewport = true;
     mForceSetBlendState = true;
 
-    for (unsigned int i = 0; i < gl::IMPLEMENTATION_MAX_VERTEX_TEXTURE_IMAGE_UNITS; i++)
+    ASSERT(mForceSetVertexSamplerStates.size() == mCurVertexTextureSerials.size());
+    for (unsigned int i = 0; i < mForceSetVertexSamplerStates.size(); i++)
     {
         mForceSetVertexSamplerStates[i] = true;
         mCurVertexTextureSerials[i] = 0;
     }
-    for (unsigned int i = 0; i < gl::MAX_TEXTURE_IMAGE_UNITS; i++)
+
+    ASSERT(mForceSetPixelSamplerStates.size() == mCurPixelTextureSerials.size());
+    for (unsigned int i = 0; i < mForceSetPixelSamplerStates.size(); i++)
     {
         mForceSetPixelSamplerStates[i] = true;
         mCurPixelTextureSerials[i] = 0;
@@ -1968,6 +2073,7 @@
     SafeDelete(mVertexDataManager);
     SafeDelete(mIndexDataManager);
     SafeDelete(mLineLoopIB);
+    SafeDelete(mCountingIB);
 
     for (int i = 0; i < NUM_NULL_COLORBUFFER_CACHE_ENTRIES; i++)
     {
@@ -2178,17 +2284,6 @@
     return mAdapterIdentifier.DeviceIdentifier;
 }
 
-unsigned int Renderer9::getMaxVertexTextureImageUnits() const
-{
-    META_ASSERT(MAX_TEXTURE_IMAGE_UNITS_VTF_SM3 <= gl::IMPLEMENTATION_MAX_VERTEX_TEXTURE_IMAGE_UNITS);
-    return mVertexTextureSupport ? MAX_TEXTURE_IMAGE_UNITS_VTF_SM3 : 0;
-}
-
-unsigned int Renderer9::getMaxCombinedTextureImageUnits() const
-{
-    return gl::MAX_TEXTURE_IMAGE_UNITS + getMaxVertexTextureImageUnits();
-}
-
 unsigned int Renderer9::getReservedVertexUniformVectors() const
 {
     return 2;   // dx_ViewAdjust and dx_DepthRange.
@@ -2199,33 +2294,6 @@
     return 3;   // dx_ViewCoords, dx_DepthFront and dx_DepthRange.
 }
 
-unsigned int Renderer9::getMaxVertexUniformVectors() const
-{
-    return MAX_VERTEX_CONSTANT_VECTORS_D3D9 - getReservedVertexUniformVectors();
-}
-
-unsigned int Renderer9::getMaxFragmentUniformVectors() const
-{
-    const int maxPixelConstantVectors = (getMajorShaderModel() >= 3) ? MAX_PIXEL_CONSTANT_VECTORS_SM3 : MAX_PIXEL_CONSTANT_VECTORS_SM2;
-
-    return maxPixelConstantVectors - getReservedFragmentUniformVectors();
-}
-
-unsigned int Renderer9::getMaxVaryingVectors() const
-{
-    return (getMajorShaderModel() >= 3) ? MAX_VARYING_VECTORS_SM3 : MAX_VARYING_VECTORS_SM2;
-}
-
-unsigned int Renderer9::getMaxVertexShaderUniformBuffers() const
-{
-    return 0;
-}
-
-unsigned int Renderer9::getMaxFragmentShaderUniformBuffers() const
-{
-    return 0;
-}
-
 unsigned int Renderer9::getReservedVertexUniformBuffers() const
 {
     return 0;
@@ -2236,26 +2304,6 @@
     return 0;
 }
 
-unsigned int Renderer9::getMaxTransformFeedbackBuffers() const
-{
-    return 0;
-}
-
-unsigned int Renderer9::getMaxTransformFeedbackSeparateComponents() const
-{
-    return 0;
-}
-
-unsigned int Renderer9::getMaxTransformFeedbackInterleavedComponents() const
-{
-    return 0;
-}
-
-unsigned int Renderer9::getMaxUniformBufferSize() const
-{
-    return 0;
-}
-
 bool Renderer9::getShareHandleSupport() const
 {
     // PIX doesn't seem to support using share handles, so disable them.
@@ -2267,20 +2315,6 @@
     return true;
 }
 
-int Renderer9::getMaxRecommendedElementsIndices() const
-{
-    // ES3 only
-    UNREACHABLE();
-    return 0;
-}
-
-int Renderer9::getMaxRecommendedElementsVertices() const
-{
-    // ES3 only
-    UNREACHABLE();
-    return 0;
-}
-
 int Renderer9::getMajorShaderModel() const
 {
     return D3DSHADER_VERSION_MAJOR(mDeviceCaps.PixelShaderVersion);
@@ -2301,14 +2335,14 @@
     return mMaxSwapInterval;
 }
 
-bool Renderer9::copyToRenderTarget(TextureStorageInterface2D *dest, TextureStorageInterface2D *source)
+bool Renderer9::copyToRenderTarget2D(TextureStorage *dest, TextureStorage *source)
 {
     bool result = false;
 
     if (source && dest)
     {
-        TextureStorage9_2D *source9 = TextureStorage9_2D::makeTextureStorage9_2D(source->getStorageInstance());
-        TextureStorage9_2D *dest9 = TextureStorage9_2D::makeTextureStorage9_2D(dest->getStorageInstance());
+        TextureStorage9_2D *source9 = TextureStorage9_2D::makeTextureStorage9_2D(source);
+        TextureStorage9_2D *dest9 = TextureStorage9_2D::makeTextureStorage9_2D(dest);
 
         int levels = source9->getLevelCount();
         for (int i = 0; i < levels; ++i)
@@ -2331,14 +2365,14 @@
     return result;
 }
 
-bool Renderer9::copyToRenderTarget(TextureStorageInterfaceCube *dest, TextureStorageInterfaceCube *source)
+bool Renderer9::copyToRenderTargetCube(TextureStorage *dest, TextureStorage *source)
 {
     bool result = false;
 
     if (source && dest)
     {
-        TextureStorage9_Cube *source9 = TextureStorage9_Cube::makeTextureStorage9_Cube(source->getStorageInstance());
-        TextureStorage9_Cube *dest9 = TextureStorage9_Cube::makeTextureStorage9_Cube(dest->getStorageInstance());
+        TextureStorage9_Cube *source9 = TextureStorage9_Cube::makeTextureStorage9_Cube(source);
+        TextureStorage9_Cube *dest9 = TextureStorage9_Cube::makeTextureStorage9_Cube(dest);
         int levels = source9->getLevelCount();
         for (int f = 0; f < 6; f++)
         {
@@ -2363,14 +2397,14 @@
     return result;
 }
 
-bool Renderer9::copyToRenderTarget(TextureStorageInterface3D *dest, TextureStorageInterface3D *source)
+bool Renderer9::copyToRenderTarget3D(TextureStorage *dest, TextureStorage *source)
 {
     // 3D textures are not available in the D3D9 backend.
     UNREACHABLE();
     return false;
 }
 
-bool Renderer9::copyToRenderTarget(TextureStorageInterface2DArray *dest, TextureStorageInterface2DArray *source)
+bool Renderer9::copyToRenderTarget2DArray(TextureStorage *dest, TextureStorage *source)
 {
     // 2D array textures are not supported by the D3D9 backend.
     UNREACHABLE();
@@ -2394,8 +2428,8 @@
     return D3DPOOL_DEFAULT;
 }
 
-bool Renderer9::copyImage(gl::Framebuffer *framebuffer, const gl::Rectangle &sourceRect, GLenum destFormat,
-                          GLint xoffset, GLint yoffset, TextureStorageInterface2D *storage, GLint level)
+bool Renderer9::copyImage2D(gl::Framebuffer *framebuffer, const gl::Rectangle &sourceRect, GLenum destFormat,
+                            GLint xoffset, GLint yoffset, TextureStorage *storage, GLint level)
 {
     RECT rect;
     rect.left = sourceRect.x;
@@ -2403,11 +2437,11 @@
     rect.right = sourceRect.x + sourceRect.width;
     rect.bottom = sourceRect.y + sourceRect.height;
 
-    return mBlit->copy(framebuffer, rect, destFormat, xoffset, yoffset, storage, level);
+    return mBlit->copy2D(framebuffer, rect, destFormat, xoffset, yoffset, storage, level);
 }
 
-bool Renderer9::copyImage(gl::Framebuffer *framebuffer, const gl::Rectangle &sourceRect, GLenum destFormat,
-                          GLint xoffset, GLint yoffset, TextureStorageInterfaceCube *storage, GLenum target, GLint level)
+bool Renderer9::copyImageCube(gl::Framebuffer *framebuffer, const gl::Rectangle &sourceRect, GLenum destFormat,
+                              GLint xoffset, GLint yoffset, TextureStorage *storage, GLenum target, GLint level)
 {
     RECT rect;
     rect.left = sourceRect.x;
@@ -2415,19 +2449,19 @@
     rect.right = sourceRect.x + sourceRect.width;
     rect.bottom = sourceRect.y + sourceRect.height;
 
-    return mBlit->copy(framebuffer, rect, destFormat, xoffset, yoffset, storage, target, level);
+    return mBlit->copyCube(framebuffer, rect, destFormat, xoffset, yoffset, storage, target, level);
 }
 
-bool Renderer9::copyImage(gl::Framebuffer *framebuffer, const gl::Rectangle &sourceRect, GLenum destFormat,
-                          GLint xoffset, GLint yoffset, GLint zOffset, TextureStorageInterface3D *storage, GLint level)
+bool Renderer9::copyImage3D(gl::Framebuffer *framebuffer, const gl::Rectangle &sourceRect, GLenum destFormat,
+                            GLint xoffset, GLint yoffset, GLint zOffset, TextureStorage *storage, GLint level)
 {
     // 3D textures are not available in the D3D9 backend.
     UNREACHABLE();
     return false;
 }
 
-bool Renderer9::copyImage(gl::Framebuffer *framebuffer, const gl::Rectangle &sourceRect, GLenum destFormat,
-                          GLint xoffset, GLint yoffset, GLint zOffset, TextureStorageInterface2DArray *storage, GLint level)
+bool Renderer9::copyImage2DArray(gl::Framebuffer *framebuffer, const gl::Rectangle &sourceRect, GLenum destFormat,
+                                 GLint xoffset, GLint yoffset, GLint zOffset, TextureStorage *storage, GLint level)
 {
     // 2D array textures are not available in the D3D9 backend.
     UNREACHABLE();
@@ -2452,11 +2486,11 @@
 
         if (readBuffer)
         {
-            readRenderTarget = RenderTarget9::makeRenderTarget9(readBuffer->getRenderTarget());
+            readRenderTarget = d3d9::GetAttachmentRenderTarget(readBuffer);
         }
         if (drawBuffer)
         {
-            drawRenderTarget = RenderTarget9::makeRenderTarget9(drawBuffer->getRenderTarget());
+            drawRenderTarget = d3d9::GetAttachmentRenderTarget(drawBuffer);
         }
 
         if (readRenderTarget)
@@ -2581,11 +2615,11 @@
 
         if (readBuffer)
         {
-            readDepthStencil = RenderTarget9::makeRenderTarget9(readBuffer->getDepthStencil());
+            readDepthStencil = d3d9::GetAttachmentRenderTarget(readBuffer);
         }
         if (drawBuffer)
         {
-            drawDepthStencil = RenderTarget9::makeRenderTarget9(drawBuffer->getDepthStencil());
+            drawDepthStencil = d3d9::GetAttachmentRenderTarget(drawBuffer);
         }
 
         if (readDepthStencil)
@@ -2618,8 +2652,8 @@
     return true;
 }
 
-void Renderer9::readPixels(gl::Framebuffer *framebuffer, GLint x, GLint y, GLsizei width, GLsizei height, GLenum format,
-                           GLenum type, GLuint outputPitch, const gl::PixelPackState &pack, void* pixels)
+gl::Error Renderer9::readPixels(gl::Framebuffer *framebuffer, GLint x, GLint y, GLsizei width, GLsizei height, GLenum format,
+                                GLenum type, GLuint outputPitch, const gl::PixelPackState &pack, uint8_t *pixels)
 {
     ASSERT(pack.pixelBuffer.get() == NULL);
 
@@ -2629,7 +2663,7 @@
 
     if (colorbuffer)
     {
-        renderTarget = RenderTarget9::makeRenderTarget9(colorbuffer->getRenderTarget());
+        renderTarget = d3d9::GetAttachmentRenderTarget(colorbuffer);
     }
 
     if (renderTarget)
@@ -2640,7 +2674,7 @@
     if (!surface)
     {
         // context must be lost
-        return;
+        return gl::Error(GL_NO_ERROR);
     }
 
     D3DSURFACE_DESC desc;
@@ -2650,7 +2684,7 @@
     {
         UNIMPLEMENTED();   // FIXME: Requires resolve using StretchRect into non-multisampled render target
         SafeRelease(surface);
-        return gl::error(GL_OUT_OF_MEMORY);
+        return gl::Error(GL_OUT_OF_MEMORY, "ReadPixels is unimplemented for multisampled framebuffer attachments.");
     }
 
     HRESULT result;
@@ -2662,7 +2696,7 @@
     {
         // Use the pixels ptr as a shared handle to write directly into client's memory
         result = mDevice->CreateOffscreenPlainSurface(desc.Width, desc.Height, desc.Format,
-                                                      D3DPOOL_SYSTEMMEM, &systemSurface, &pixels);
+                                                      D3DPOOL_SYSTEMMEM, &systemSurface, reinterpret_cast<void**>(&pixels));
         if (FAILED(result))
         {
             // Try again without the shared handle
@@ -2678,7 +2712,7 @@
         {
             ASSERT(result == D3DERR_OUTOFVIDEOMEMORY || result == E_OUTOFMEMORY);
             SafeRelease(surface);
-            return gl::error(GL_OUT_OF_MEMORY);
+            return gl::Error(GL_OUT_OF_MEMORY, "Failed to allocate internal texture for ReadPixels.");
         }
     }
 
@@ -2694,20 +2728,19 @@
         if (d3d9::isDeviceLostError(result))
         {
             notifyDeviceLost();
-            return gl::error(GL_OUT_OF_MEMORY);
         }
         else
         {
             UNREACHABLE();
-            return;
         }
 
+        return gl::Error(GL_OUT_OF_MEMORY, "Failed to read internal render target data.");
     }
 
     if (directToPixels)
     {
         SafeRelease(systemSurface);
-        return;
+        return gl::Error(GL_NO_ERROR);
     }
 
     RECT rect;
@@ -2724,19 +2757,19 @@
         UNREACHABLE();
         SafeRelease(systemSurface);
 
-        return;   // No sensible error to generate
+        return gl::Error(GL_OUT_OF_MEMORY, "Failed to lock internal render target.");
     }
 
-    unsigned char *source;
+    uint8_t *source;
     int inputPitch;
     if (pack.reverseRowOrder)
     {
-        source = ((unsigned char*)lock.pBits) + lock.Pitch * (rect.bottom - rect.top - 1);
+        source = reinterpret_cast<uint8_t*>(lock.pBits) + lock.Pitch * (rect.bottom - rect.top - 1);
         inputPitch = -lock.Pitch;
     }
     else
     {
-        source = (unsigned char*)lock.pBits;
+        source = reinterpret_cast<uint8_t*>(lock.pBits);
         inputPitch = lock.Pitch;
     }
 
@@ -2745,10 +2778,9 @@
     if (sourceFormatInfo.format == format && sourceFormatInfo.type == type)
     {
         // Direct copy possible
-        unsigned char *dest = static_cast<unsigned char*>(pixels);
         for (int y = 0; y < rect.bottom - rect.top; y++)
         {
-            memcpy(dest + y * outputPitch, source + y * inputPitch, (rect.right - rect.left) * sourceFormatInfo.pixelBytes);
+            memcpy(pixels + y * outputPitch, source + y * inputPitch, (rect.right - rect.left) * sourceFormatInfo.pixelBytes);
         }
     }
     else
@@ -2766,8 +2798,8 @@
             {
                 for (int x = 0; x < rect.right - rect.left; x++)
                 {
-                    void *dest = static_cast<unsigned char*>(pixels) + y * outputPitch + x * destFormatInfo.pixelBytes;
-                    void *src = static_cast<unsigned char*>(source) + y * inputPitch + x * sourceFormatInfo.pixelBytes;
+                    uint8_t *dest = pixels + y * outputPitch + x * destFormatInfo.pixelBytes;
+                    const uint8_t *src = source + y * inputPitch + x * sourceFormatInfo.pixelBytes;
 
                     fastCopyFunc(src, dest);
                 }
@@ -2775,18 +2807,18 @@
         }
         else
         {
-            gl::ColorF temp;
+            uint8_t temp[sizeof(gl::ColorF)];
             for (int y = 0; y < rect.bottom - rect.top; y++)
             {
                 for (int x = 0; x < rect.right - rect.left; x++)
                 {
-                    void *dest = reinterpret_cast<unsigned char*>(pixels) + y * outputPitch + x * destFormatInfo.pixelBytes;
-                    void *src = source + y * inputPitch + x * sourceFormatInfo.pixelBytes;
+                    uint8_t *dest = pixels + y * outputPitch + x * destFormatInfo.pixelBytes;
+                    const uint8_t *src = source + y * inputPitch + x * sourceFormatInfo.pixelBytes;
 
                     // readFunc and writeFunc will be using the same type of color, CopyTexImage
                     // will not allow the copy otherwise.
-                    sourceD3DFormatInfo.colorReadFunction(src, &temp);
-                    destFormatTypeInfo.colorWriteFunction(&temp, dest);
+                    sourceD3DFormatInfo.colorReadFunction(src, temp);
+                    destFormatTypeInfo.colorWriteFunction(temp, dest);
                 }
             }
         }
@@ -2794,6 +2826,8 @@
 
     systemSurface->UnlockRect();
     SafeRelease(systemSurface);
+
+    return gl::Error(GL_NO_ERROR);
 }
 
 RenderTarget *Renderer9::createRenderTarget(SwapChain *swapChain, bool depth)
@@ -2820,6 +2854,21 @@
     return renderTarget;
 }
 
+ShaderImpl *Renderer9::createShader(GLenum type)
+{
+    return new ShaderD3D(type, this);
+}
+
+ProgramImpl *Renderer9::createProgram()
+{
+    return new ProgramD3D(this);
+}
+
+void Renderer9::releaseShaderCompiler()
+{
+    ShaderD3D::releaseCompiler();
+}
+
 ShaderExecutable *Renderer9::loadExecutable(const void *function, size_t length, rx::ShaderType type,
                                             const std::vector<gl::LinkedVarying> &transformFeedbackVaryings,
                                             bool separatedOutputBuffers)
@@ -3043,24 +3092,16 @@
     return NULL;
 }
 
-Texture2DImpl *Renderer9::createTexture2D()
+TextureImpl *Renderer9::createTexture(GLenum target)
 {
-    return new TextureD3D_2D(this);
-}
+    switch(target)
+    {
+      case GL_TEXTURE_2D:       return new TextureD3D_2D(this);
+      case GL_TEXTURE_CUBE_MAP: return new TextureD3D_Cube(this);
+      default:                  UNREACHABLE();
+    }
 
-TextureCubeImpl *Renderer9::createTextureCube()
-{
-    return new TextureD3D_Cube(this);
-}
-
-Texture3DImpl *Renderer9::createTexture3D()
-{
-    return new TextureD3D_3D(this);
-}
-
-Texture2DArrayImpl *Renderer9::createTexture2DArray()
-{
-    return new TextureD3D_2DArray(this);
+    return NULL;
 }
 
 bool Renderer9::getLUID(LUID *adapterLuid) const
diff --git a/src/libGLESv2/renderer/d3d/d3d9/Renderer9.h b/src/libGLESv2/renderer/d3d/d3d9/Renderer9.h
index 8d4b2f7..87a3323 100644
--- a/src/libGLESv2/renderer/d3d/d3d9/Renderer9.h
+++ b/src/libGLESv2/renderer/d3d/d3d9/Renderer9.h
@@ -27,6 +27,7 @@
 class VertexDataManager;
 class IndexDataManager;
 class StreamingIndexBufferInterface;
+class StaticIndexBufferInterface;
 struct TranslatedAttribute;
 class Blit9;
 
@@ -72,7 +73,7 @@
                                       int stencilBackRef, bool frontFaceCCW);
 
     virtual void setScissorRectangle(const gl::Rectangle &scissor, bool enabled);
-    virtual bool setViewport(const gl::Rectangle &viewport, float zNear, float zFar, GLenum drawMode, GLenum frontFace,
+    virtual void setViewport(const gl::Rectangle &viewport, float zNear, float zFar, GLenum drawMode, GLenum frontFace,
                              bool ignoreViewport);
 
     virtual bool applyRenderTarget(gl::Framebuffer *frameBuffer);
@@ -80,9 +81,9 @@
                               bool rasterizerDiscard, bool transformFeedbackActive);
     virtual void applyUniforms(const gl::ProgramBinary &programBinary);
     virtual bool applyPrimitiveType(GLenum primitiveType, GLsizei elementCount);
-    virtual GLenum applyVertexBuffer(gl::ProgramBinary *programBinary, const gl::VertexAttribute vertexAttributes[], const gl::VertexAttribCurrentValueData currentValues[],
-                                     GLint first, GLsizei count, GLsizei instances);
-    virtual GLenum applyIndexBuffer(const GLvoid *indices, gl::Buffer *elementArrayBuffer, GLsizei count, GLenum mode, GLenum type, TranslatedIndexData *indexInfo);
+    virtual gl::Error applyVertexBuffer(gl::ProgramBinary *programBinary, const gl::VertexAttribute vertexAttributes[], const gl::VertexAttribCurrentValueData currentValues[],
+                                        GLint first, GLsizei count, GLsizei instances);
+    virtual gl::Error applyIndexBuffer(const GLvoid *indices, gl::Buffer *elementArrayBuffer, GLsizei count, GLenum mode, GLenum type, TranslatedIndexData *indexInfo);
 
     virtual void applyTransformFeedbackBuffers(gl::Buffer *transformFeedbackBuffers[], GLintptr offsets[]);
 
@@ -90,7 +91,7 @@
     virtual void drawElements(GLenum mode, GLsizei count, GLenum type, const GLvoid *indices,
                               gl::Buffer *elementArrayBuffer, const TranslatedIndexData &indexInfo, GLsizei instances);
 
-    virtual void clear(const gl::ClearParameters &clearParams, gl::Framebuffer *frameBuffer);
+    virtual gl::Error clear(const gl::ClearParameters &clearParams, gl::Framebuffer *frameBuffer);
 
     virtual void markAllStateDirty();
 
@@ -105,25 +106,12 @@
     virtual std::string getRendererDescription() const;
     virtual GUID getAdapterIdentifier() const;
 
-    virtual unsigned int getMaxVertexTextureImageUnits() const;
-    virtual unsigned int getMaxCombinedTextureImageUnits() const;
     virtual unsigned int getReservedVertexUniformVectors() const;
     virtual unsigned int getReservedFragmentUniformVectors() const;
-    virtual unsigned int getMaxVertexUniformVectors() const;
-    virtual unsigned int getMaxFragmentUniformVectors() const;
-    virtual unsigned int getMaxVaryingVectors() const;
-    virtual unsigned int getMaxVertexShaderUniformBuffers() const;
-    virtual unsigned int getMaxFragmentShaderUniformBuffers() const;
     virtual unsigned int getReservedVertexUniformBuffers() const;
     virtual unsigned int getReservedFragmentUniformBuffers() const;
-    virtual unsigned int getMaxTransformFeedbackBuffers() const;
-    virtual unsigned int getMaxTransformFeedbackSeparateComponents() const;
-    virtual unsigned int getMaxTransformFeedbackInterleavedComponents() const;
-    virtual unsigned int getMaxUniformBufferSize() const;
     virtual bool getShareHandleSupport() const;
     virtual bool getPostSubBufferSupport() const;
-    virtual int getMaxRecommendedElementsIndices() const;
-    virtual int getMaxRecommendedElementsVertices() const;
 
     virtual int getMajorShaderModel() const;
     DWORD getCapsDeclTypes() const;
@@ -131,30 +119,36 @@
     virtual int getMaxSwapInterval() const;
 
     // Pixel operations
-    virtual bool copyToRenderTarget(TextureStorageInterface2D *dest, TextureStorageInterface2D *source);
-    virtual bool copyToRenderTarget(TextureStorageInterfaceCube *dest, TextureStorageInterfaceCube *source);
-    virtual bool copyToRenderTarget(TextureStorageInterface3D *dest, TextureStorageInterface3D *source);
-    virtual bool copyToRenderTarget(TextureStorageInterface2DArray *dest, TextureStorageInterface2DArray *source);
+    virtual bool copyToRenderTarget2D(TextureStorage *dest, TextureStorage *source);
+    virtual bool copyToRenderTargetCube(TextureStorage *dest, TextureStorage *source);
+    virtual bool copyToRenderTarget3D(TextureStorage *dest, TextureStorage *source);
+    virtual bool copyToRenderTarget2DArray(TextureStorage *dest, TextureStorage *source);
 
-    virtual bool copyImage(gl::Framebuffer *framebuffer, const gl::Rectangle &sourceRect, GLenum destFormat,
-                           GLint xoffset, GLint yoffset, TextureStorageInterface2D *storage, GLint level);
-    virtual bool copyImage(gl::Framebuffer *framebuffer, const gl::Rectangle &sourceRect, GLenum destFormat,
-                           GLint xoffset, GLint yoffset, TextureStorageInterfaceCube *storage, GLenum target, GLint level);
-    virtual bool copyImage(gl::Framebuffer *framebuffer, const gl::Rectangle &sourceRect, GLenum destFormat,
-                           GLint xoffset, GLint yoffset, GLint zOffset, TextureStorageInterface3D *storage, GLint level);
-    virtual bool copyImage(gl::Framebuffer *framebuffer, const gl::Rectangle &sourceRect, GLenum destFormat,
-                           GLint xoffset, GLint yoffset, GLint zOffset, TextureStorageInterface2DArray *storage, GLint level);
+    virtual bool copyImage2D(gl::Framebuffer *framebuffer, const gl::Rectangle &sourceRect, GLenum destFormat,
+                             GLint xoffset, GLint yoffset, TextureStorage *storage, GLint level);
+    virtual bool copyImageCube(gl::Framebuffer *framebuffer, const gl::Rectangle &sourceRect, GLenum destFormat,
+                               GLint xoffset, GLint yoffset, TextureStorage *storage, GLenum target, GLint level);
+    virtual bool copyImage3D(gl::Framebuffer *framebuffer, const gl::Rectangle &sourceRect, GLenum destFormat,
+                             GLint xoffset, GLint yoffset, GLint zOffset, TextureStorage *storage, GLint level);
+    virtual bool copyImage2DArray(gl::Framebuffer *framebuffer, const gl::Rectangle &sourceRect, GLenum destFormat,
+                                  GLint xoffset, GLint yoffset, GLint zOffset, TextureStorage *storage, GLint level);
 
     virtual bool blitRect(gl::Framebuffer *readTarget, const gl::Rectangle &readRect, gl::Framebuffer *drawTarget, const gl::Rectangle &drawRect,
                           const gl::Rectangle *scissor, bool blitRenderTarget, bool blitDepth, bool blitStencil, GLenum filter);
-    virtual void readPixels(gl::Framebuffer *framebuffer, GLint x, GLint y, GLsizei width, GLsizei height, GLenum format,
-                            GLenum type, GLuint outputPitch, const gl::PixelPackState &pack, void* pixels);
+
+    virtual gl::Error readPixels(gl::Framebuffer *framebuffer, GLint x, GLint y, GLsizei width, GLsizei height, GLenum format,
+                                 GLenum type, GLuint outputPitch, const gl::PixelPackState &pack, uint8_t *pixels);
 
     // RenderTarget creation
     virtual RenderTarget *createRenderTarget(SwapChain *swapChain, bool depth);
     virtual RenderTarget *createRenderTarget(int width, int height, GLenum format, GLsizei samples);
 
+    // Shader creation
+    virtual ShaderImpl *createShader(GLenum type);
+    virtual ProgramImpl *createProgram();
+
     // Shader operations
+    virtual void releaseShaderCompiler();
     virtual ShaderExecutable *loadExecutable(const void *function, size_t length, rx::ShaderType type,
                                              const std::vector<gl::LinkedVarying> &transformFeedbackVaryings,
                                              bool separatedOutputBuffers);
@@ -173,10 +167,7 @@
     virtual TextureStorage *createTextureStorage2DArray(GLenum internalformat, bool renderTarget, GLsizei width, GLsizei height, GLsizei depth, int levels);
 
     // Texture creation
-    virtual Texture2DImpl *createTexture2D();
-    virtual TextureCubeImpl *createTextureCube();
-    virtual Texture3DImpl *createTexture3D();
-    virtual Texture2DArrayImpl *createTexture2DArray();
+    virtual TextureImpl *createTexture(GLenum target);
 
     // Buffer creation
     virtual BufferImpl *createBuffer();
@@ -190,6 +181,9 @@
     virtual QueryImpl *createQuery(GLenum type);
     virtual FenceImpl *createFence();
 
+    // Transform Feedback creation
+    virtual TransformFeedbackImpl* createTransformFeedback();
+
     // Buffer-to-texture and Texture-to-buffer copies
     virtual bool supportsFastCopyBufferToTexture(GLenum internalFormat) const;
     virtual bool fastCopyBufferToTexture(const gl::PixelUnpackState &unpack, unsigned int offset, RenderTarget *destRenderTarget,
@@ -218,6 +212,8 @@
     void drawLineLoop(GLsizei count, GLenum type, const GLvoid *indices, int minIndex, gl::Buffer *elementArrayBuffer);
     void drawIndexedPoints(GLsizei count, GLenum type, const GLvoid *indices, int minIndex, gl::Buffer *elementArrayBuffer);
 
+    StaticIndexBufferInterface *getCountingIB(size_t count);
+
     bool copyToRenderTarget(IDirect3DSurface9 *dest, IDirect3DSurface9 *source, bool fromManaged);
     gl::FramebufferAttachment *getNullColorbuffer(gl::FramebufferAttachment *depthbuffer);
 
@@ -299,15 +295,15 @@
     GLuint mCurSampleMask;
 
     // Currently applied sampler states
-    bool mForceSetVertexSamplerStates[gl::IMPLEMENTATION_MAX_VERTEX_TEXTURE_IMAGE_UNITS];
-    gl::SamplerState mCurVertexSamplerStates[gl::IMPLEMENTATION_MAX_VERTEX_TEXTURE_IMAGE_UNITS];
+    std::vector<bool> mForceSetVertexSamplerStates;
+    std::vector<gl::SamplerState> mCurVertexSamplerStates;
 
-    bool mForceSetPixelSamplerStates[gl::MAX_TEXTURE_IMAGE_UNITS];
-    gl::SamplerState mCurPixelSamplerStates[gl::MAX_TEXTURE_IMAGE_UNITS];
+    std::vector<bool> mForceSetPixelSamplerStates;
+    std::vector<gl::SamplerState> mCurPixelSamplerStates;
 
     // Currently applied textures
-    unsigned int mCurVertexTextureSerials[gl::IMPLEMENTATION_MAX_VERTEX_TEXTURE_IMAGE_UNITS];
-    unsigned int mCurPixelTextureSerials[gl::MAX_TEXTURE_IMAGE_UNITS];
+    std::vector<unsigned int> mCurVertexTextureSerials;
+    std::vector<unsigned int> mCurPixelTextureSerials;
 
     unsigned int mAppliedIBSerial;
     IDirect3DVertexShader9 *mAppliedVertexShader;
@@ -328,6 +324,7 @@
 
     IndexDataManager *mIndexDataManager;
     StreamingIndexBufferInterface *mLineLoopIB;
+    StaticIndexBufferInterface *mCountingIB;
 
     enum { NUM_NULL_COLORBUFFER_CACHE_ENTRIES = 12 };
     struct NullColorbufferCacheEntry
diff --git a/src/libGLESv2/renderer/d3d/d3d9/ShaderCache.h b/src/libGLESv2/renderer/d3d/d3d9/ShaderCache.h
index a03528c..2ad3022 100644
--- a/src/libGLESv2/renderer/d3d/d3d9/ShaderCache.h
+++ b/src/libGLESv2/renderer/d3d/d3d9/ShaderCache.h
@@ -12,6 +12,10 @@
 
 #include "common/debug.h"
 
+#include <cstddef>
+#include <unordered_map>
+#include <string>
+
 namespace rx
 {
 template <typename ShaderObject>
diff --git a/src/libGLESv2/renderer/d3d/d3d9/ShaderExecutable9.cpp b/src/libGLESv2/renderer/d3d/d3d9/ShaderExecutable9.cpp
index c10ddbf..bc71204 100644
--- a/src/libGLESv2/renderer/d3d/d3d9/ShaderExecutable9.cpp
+++ b/src/libGLESv2/renderer/d3d/d3d9/ShaderExecutable9.cpp
@@ -1,4 +1,3 @@
-#include "precompiled.h"
 //
 // 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
diff --git a/src/libGLESv2/renderer/d3d/d3d9/SwapChain9.cpp b/src/libGLESv2/renderer/d3d/d3d9/SwapChain9.cpp
index 18b6183..f702b79 100644
--- a/src/libGLESv2/renderer/d3d/d3d9/SwapChain9.cpp
+++ b/src/libGLESv2/renderer/d3d/d3d9/SwapChain9.cpp
@@ -1,4 +1,3 @@
-#include "precompiled.h"
 //
 // Copyright (c) 2012-2014 The ANGLE Project Authors. All rights reserved.
 // Use of this source code is governed by a BSD-style license that can be
diff --git a/src/libGLESv2/renderer/d3d/d3d9/TextureStorage9.cpp b/src/libGLESv2/renderer/d3d/d3d9/TextureStorage9.cpp
index 9065bc6..f44e33d 100644
--- a/src/libGLESv2/renderer/d3d/d3d9/TextureStorage9.cpp
+++ b/src/libGLESv2/renderer/d3d/d3d9/TextureStorage9.cpp
@@ -1,4 +1,3 @@
-#include "precompiled.h"
 //
 // Copyright (c) 2012-2014 The ANGLE Project Authors. All rights reserved.
 // Use of this source code is governed by a BSD-style license that can be
@@ -9,15 +8,15 @@
 // classes TextureStorage9_2D and TextureStorage9_Cube, which act as the interface to the
 // D3D9 texture.
 
-#include "libGLESv2/main.h"
-#include "libGLESv2/renderer/d3d/TextureD3D.h"
-#include "libGLESv2/renderer/d3d/d3d9/Renderer9.h"
 #include "libGLESv2/renderer/d3d/d3d9/TextureStorage9.h"
+#include "libGLESv2/renderer/d3d/d3d9/Renderer9.h"
 #include "libGLESv2/renderer/d3d/d3d9/SwapChain9.h"
 #include "libGLESv2/renderer/d3d/d3d9/RenderTarget9.h"
 #include "libGLESv2/renderer/d3d/d3d9/renderer9_utils.h"
 #include "libGLESv2/renderer/d3d/d3d9/formatutils9.h"
+#include "libGLESv2/renderer/d3d/TextureD3D.h"
 #include "libGLESv2/Texture.h"
+#include "libGLESv2/main.h"
 
 namespace rx
 {
@@ -96,6 +95,7 @@
     mRenderTarget = NULL;
 
     initializeRenderTarget();
+    initializeSerials(1, 1);
 }
 
 TextureStorage9_2D::TextureStorage9_2D(Renderer *renderer, GLenum internalformat, bool renderTarget, GLsizei width, GLsizei height, int levels)
@@ -122,6 +122,7 @@
     }
 
     initializeRenderTarget();
+    initializeSerials(getLevelCount(), 1);
 }
 
 TextureStorage9_2D::~TextureStorage9_2D()
@@ -158,23 +159,28 @@
     return surface;
 }
 
-RenderTarget *TextureStorage9_2D::getRenderTarget(int level)
+RenderTarget *TextureStorage9_2D::getRenderTarget(const gl::ImageIndex &/*index*/)
 {
     return mRenderTarget;
 }
 
-void TextureStorage9_2D::generateMipmap(int level)
+void TextureStorage9_2D::generateMipmaps()
 {
-    IDirect3DSurface9 *upper = getSurfaceLevel(level - 1, false);
-    IDirect3DSurface9 *lower = getSurfaceLevel(level, true);
+    // Base level must already be defined
 
-    if (upper != NULL && lower != NULL)
+    for (int level = 1; level < getLevelCount(); level++)
     {
-        mRenderer->boxFilter(upper, lower);
-    }
+        IDirect3DSurface9 *upper = getSurfaceLevel(level - 1, false);
+        IDirect3DSurface9 *lower = getSurfaceLevel(level, true);
 
-    SafeRelease(upper);
-    SafeRelease(lower);
+        if (upper != NULL && lower != NULL)
+        {
+            mRenderer->boxFilter(upper, lower);
+        }
+
+        SafeRelease(upper);
+        SafeRelease(lower);
+    }
 }
 
 IDirect3DBaseTexture9 *TextureStorage9_2D::getBaseTexture() const
@@ -223,6 +229,7 @@
     }
 
     initializeRenderTarget();
+    initializeSerials(getLevelCount() * 6, 6);
 }
 
 TextureStorage9_Cube::~TextureStorage9_Cube()
@@ -264,23 +271,31 @@
     return surface;
 }
 
-RenderTarget *TextureStorage9_Cube::getRenderTargetFace(GLenum faceTarget, int level)
+RenderTarget *TextureStorage9_Cube::getRenderTarget(const gl::ImageIndex &index)
 {
-    return mRenderTarget[gl::TextureCubeMap::targetToLayerIndex(faceTarget)];
+    return mRenderTarget[index.layerIndex];
 }
 
-void TextureStorage9_Cube::generateMipmap(int faceIndex, int level)
+void TextureStorage9_Cube::generateMipmaps()
 {
-    IDirect3DSurface9 *upper = getCubeMapSurface(GL_TEXTURE_CUBE_MAP_POSITIVE_X + faceIndex, level - 1, false);
-    IDirect3DSurface9 *lower = getCubeMapSurface(GL_TEXTURE_CUBE_MAP_POSITIVE_X + faceIndex, level, true);
+    // Base level must already be defined
 
-    if (upper != NULL && lower != NULL)
+    for (int faceIndex = 0; faceIndex < 6; faceIndex++)
     {
-        mRenderer->boxFilter(upper, lower);
-    }
+        for (int level = 1; level < getLevelCount(); level++)
+        {
+            IDirect3DSurface9 *upper = getCubeMapSurface(GL_TEXTURE_CUBE_MAP_POSITIVE_X + faceIndex, level - 1, false);
+            IDirect3DSurface9 *lower = getCubeMapSurface(GL_TEXTURE_CUBE_MAP_POSITIVE_X + faceIndex, level, true);
 
-    SafeRelease(upper);
-    SafeRelease(lower);
+            if (upper != NULL && lower != NULL)
+            {
+                mRenderer->boxFilter(upper, lower);
+            }
+
+            SafeRelease(upper);
+            SafeRelease(lower);
+        }
+    }
 }
 
 IDirect3DBaseTexture9 *TextureStorage9_Cube::getBaseTexture() const
diff --git a/src/libGLESv2/renderer/d3d/d3d9/TextureStorage9.h b/src/libGLESv2/renderer/d3d/d3d9/TextureStorage9.h
index cc7c155..e698c7d 100644
--- a/src/libGLESv2/renderer/d3d/d3d9/TextureStorage9.h
+++ b/src/libGLESv2/renderer/d3d/d3d9/TextureStorage9.h
@@ -34,11 +34,8 @@
     DWORD getUsage() const;
 
     virtual IDirect3DBaseTexture9 *getBaseTexture() const = 0;
-    virtual RenderTarget *getRenderTarget(int level) { return NULL; }
-    virtual RenderTarget *getRenderTargetFace(GLenum faceTarget, int level) { return NULL; }
-    virtual RenderTarget *getRenderTargetLayer(int mipLevel, int layer) { return NULL; }
-    virtual void generateMipmap(int level) {};
-    virtual void generateMipmap(int face, int level) {};
+    virtual RenderTarget *getRenderTarget(const gl::ImageIndex &index) = 0;
+    virtual void generateMipmaps() = 0;
 
     virtual int getTopLevel() const;
     virtual bool isRenderTarget() const;
@@ -68,9 +65,9 @@
     static TextureStorage9_2D *makeTextureStorage9_2D(TextureStorage *storage);
 
     IDirect3DSurface9 *getSurfaceLevel(int level, bool dirty);
-    virtual RenderTarget *getRenderTarget(int level);
+    virtual RenderTarget *getRenderTarget(const gl::ImageIndex &index);
     virtual IDirect3DBaseTexture9 *getBaseTexture() const;
-    virtual void generateMipmap(int level);
+    virtual void generateMipmaps();
 
   private:
     DISALLOW_COPY_AND_ASSIGN(TextureStorage9_2D);
@@ -90,9 +87,9 @@
     static TextureStorage9_Cube *makeTextureStorage9_Cube(TextureStorage *storage);
 
     IDirect3DSurface9 *getCubeMapSurface(GLenum faceTarget, int level, bool dirty);
-    virtual RenderTarget *getRenderTargetFace(GLenum faceTarget, int level);
+    virtual RenderTarget *getRenderTarget(const gl::ImageIndex &index);
     virtual IDirect3DBaseTexture9 *getBaseTexture() const;
-    virtual void generateMipmap(int faceIndex, int level);
+    virtual void generateMipmaps();
 
   private:
     DISALLOW_COPY_AND_ASSIGN(TextureStorage9_Cube);
diff --git a/src/libGLESv2/renderer/d3d/d3d9/VertexBuffer9.cpp b/src/libGLESv2/renderer/d3d/d3d9/VertexBuffer9.cpp
index 428f193..4cf7779 100644
--- a/src/libGLESv2/renderer/d3d/d3d9/VertexBuffer9.cpp
+++ b/src/libGLESv2/renderer/d3d/d3d9/VertexBuffer9.cpp
@@ -1,4 +1,3 @@
-#include "precompiled.h"
 //
 // 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
@@ -8,12 +7,11 @@
 // VertexBuffer9.cpp: Defines the D3D9 VertexBuffer implementation.
 
 #include "libGLESv2/renderer/d3d/d3d9/VertexBuffer9.h"
+#include "libGLESv2/renderer/d3d/d3d9/Renderer9.h"
+#include "libGLESv2/renderer/d3d/d3d9/formatutils9.h"
 #include "libGLESv2/renderer/vertexconversion.h"
 #include "libGLESv2/renderer/BufferImpl.h"
 #include "libGLESv2/VertexAttribute.h"
-#include "libGLESv2/renderer/d3d/d3d9/Renderer9.h"
-#include "libGLESv2/renderer/d3d/d3d9/formatutils9.h"
-
 #include "libGLESv2/Buffer.h"
 
 namespace rx
@@ -31,7 +29,7 @@
     SafeRelease(mVertexBuffer);
 }
 
-bool VertexBuffer9::initialize(unsigned int size, bool dynamicUsage)
+gl::Error VertexBuffer9::initialize(unsigned int size, bool dynamicUsage)
 {
     SafeRelease(mVertexBuffer);
 
@@ -49,14 +47,13 @@
 
         if (FAILED(result))
         {
-            ERR("Out of memory allocating a vertex buffer of size %lu.", size);
-            return false;
+            return gl::Error(GL_OUT_OF_MEMORY, "Failed to allocate internal vertex buffer of size, %lu.", size);
         }
     }
 
     mBufferSize = size;
     mDynamicUsage = dynamicUsage;
-    return true;
+    return gl::Error(GL_NO_ERROR);
 }
 
 VertexBuffer9 *VertexBuffer9::makeVertexBuffer9(VertexBuffer *vertexBuffer)
@@ -65,84 +62,80 @@
     return static_cast<VertexBuffer9*>(vertexBuffer);
 }
 
-bool VertexBuffer9::storeVertexAttributes(const gl::VertexAttribute &attrib, const gl::VertexAttribCurrentValueData &currentValue,
-                                          GLint start, GLsizei count, GLsizei instances, unsigned int offset)
+gl::Error VertexBuffer9::storeVertexAttributes(const gl::VertexAttribute &attrib, const gl::VertexAttribCurrentValueData &currentValue,
+                                               GLint start, GLsizei count, GLsizei instances, unsigned int offset)
 {
-    if (mVertexBuffer)
+    if (!mVertexBuffer)
     {
-        gl::Buffer *buffer = attrib.buffer.get();
+        return gl::Error(GL_OUT_OF_MEMORY, "Internal vertex buffer is not initialized.");
+    }
 
-        int inputStride = gl::ComputeVertexAttributeStride(attrib);
-        int elementSize = gl::ComputeVertexAttributeTypeSize(attrib);
+    gl::Buffer *buffer = attrib.buffer.get();
 
-        DWORD lockFlags = mDynamicUsage ? D3DLOCK_NOOVERWRITE : 0;
+    int inputStride = gl::ComputeVertexAttributeStride(attrib);
+    int elementSize = gl::ComputeVertexAttributeTypeSize(attrib);
 
-        void *mapPtr = NULL;
+    DWORD lockFlags = mDynamicUsage ? D3DLOCK_NOOVERWRITE : 0;
 
-        unsigned int mapSize;
-        if (!spaceRequired(attrib, count, instances, &mapSize))
+    uint8_t *mapPtr = NULL;
+
+    unsigned int mapSize;
+    gl::Error error = spaceRequired(attrib, count, instances, &mapSize);
+    if (error.isError())
+    {
+        return error;
+    }
+
+    HRESULT result = mVertexBuffer->Lock(offset, mapSize, reinterpret_cast<void**>(&mapPtr), lockFlags);
+    if (FAILED(result))
+    {
+        return gl::Error(GL_OUT_OF_MEMORY, "Failed to lock internal vertex buffer, HRESULT: 0x%08x.", result);
+    }
+
+    const uint8_t *input = NULL;
+    if (attrib.enabled)
+    {
+        if (buffer)
         {
-            return false;
-        }
-
-        HRESULT result = mVertexBuffer->Lock(offset, mapSize, &mapPtr, lockFlags);
-
-        if (FAILED(result))
-        {
-            ERR("Lock failed with error 0x%08x", result);
-            return false;
-        }
-
-        const char *input = NULL;
-        if (attrib.enabled)
-        {
-            if (buffer)
-            {
-                BufferImpl *storage = buffer->getImplementation();
-                input = static_cast<const char*>(storage->getData()) + static_cast<int>(attrib.offset);
-            }
-            else
-            {
-                input = static_cast<const char*>(attrib.pointer);
-            }
+            BufferImpl *storage = buffer->getImplementation();
+            input = static_cast<const uint8_t*>(storage->getData()) + static_cast<int>(attrib.offset);
         }
         else
         {
-            input = reinterpret_cast<const char*>(currentValue.FloatValues);
+            input = static_cast<const uint8_t*>(attrib.pointer);
         }
-
-        if (instances == 0 || attrib.divisor == 0)
-        {
-            input += inputStride * start;
-        }
-
-        gl::VertexFormat vertexFormat(attrib, currentValue.Type);
-        const d3d9::VertexFormat &d3dVertexInfo = d3d9::GetVertexFormatInfo(mRenderer->getCapsDeclTypes(), vertexFormat);
-        bool needsConversion = (d3dVertexInfo.conversionType & VERTEX_CONVERT_CPU) > 0;
-
-        if (!needsConversion && inputStride == elementSize)
-        {
-            size_t copySize = static_cast<size_t>(count) * static_cast<size_t>(inputStride);
-            memcpy(mapPtr, input, copySize);
-        }
-        else
-        {
-            d3dVertexInfo.copyFunction(input, inputStride, count, mapPtr);
-        }
-
-        mVertexBuffer->Unlock();
-
-        return true;
     }
     else
     {
-        ERR("Vertex buffer not initialized.");
-        return false;
+        input = reinterpret_cast<const uint8_t*>(currentValue.FloatValues);
     }
+
+    if (instances == 0 || attrib.divisor == 0)
+    {
+        input += inputStride * start;
+    }
+
+    gl::VertexFormat vertexFormat(attrib, currentValue.Type);
+    const d3d9::VertexFormat &d3dVertexInfo = d3d9::GetVertexFormatInfo(mRenderer->getCapsDeclTypes(), vertexFormat);
+    bool needsConversion = (d3dVertexInfo.conversionType & VERTEX_CONVERT_CPU) > 0;
+
+    if (!needsConversion && inputStride == elementSize)
+    {
+        size_t copySize = static_cast<size_t>(count) * static_cast<size_t>(inputStride);
+        memcpy(mapPtr, input, copySize);
+    }
+    else
+    {
+        d3dVertexInfo.copyFunction(input, inputStride, count, mapPtr);
+    }
+
+    mVertexBuffer->Unlock();
+
+    return gl::Error(GL_NO_ERROR);
 }
 
-bool VertexBuffer9::getSpaceRequired(const gl::VertexAttribute &attrib, GLsizei count, GLsizei instances,
-                                     unsigned int *outSpaceRequired) const
+gl::Error VertexBuffer9::getSpaceRequired(const gl::VertexAttribute &attrib, GLsizei count, GLsizei instances,
+                                          unsigned int *outSpaceRequired) const
 {
     return spaceRequired(attrib, count, instances, outSpaceRequired);
 }
@@ -152,7 +145,7 @@
     return mBufferSize;
 }
 
-bool VertexBuffer9::setBufferSize(unsigned int size)
+gl::Error VertexBuffer9::setBufferSize(unsigned int size)
 {
     if (size > mBufferSize)
     {
@@ -160,38 +153,33 @@
     }
     else
     {
-        return true;
+        return gl::Error(GL_NO_ERROR);
     }
 }
 
-bool VertexBuffer9::discard()
+gl::Error VertexBuffer9::discard()
 {
-    if (mVertexBuffer)
+    if (!mVertexBuffer)
     {
-        void *dummy;
-        HRESULT result;
-
-        result = mVertexBuffer->Lock(0, 1, &dummy, D3DLOCK_DISCARD);
-        if (FAILED(result))
-        {
-            ERR("Discard lock failed with error 0x%08x", result);
-            return false;
-        }
-
-        result = mVertexBuffer->Unlock();
-        if (FAILED(result))
-        {
-            ERR("Discard unlock failed with error 0x%08x", result);
-            return false;
-        }
-
-        return true;
+        return gl::Error(GL_OUT_OF_MEMORY, "Internal vertex buffer is not initialized.");
     }
-    else
+
+    void *dummy;
+    HRESULT result;
+
+    result = mVertexBuffer->Lock(0, 1, &dummy, D3DLOCK_DISCARD);
+    if (FAILED(result))
     {
-        ERR("Vertex buffer not initialized.");
-        return false;
+        return gl::Error(GL_OUT_OF_MEMORY, "Failed to lock internal buffer for discarding, HRESULT: 0x%08x", result);
     }
+
+    result = mVertexBuffer->Unlock();
+    if (FAILED(result))
+    {
+        return gl::Error(GL_OUT_OF_MEMORY, "Failed to unlock internal buffer for discarding, HRESULT: 0x%08x", result);
+    }
+
+    return gl::Error(GL_NO_ERROR);
 }
 
 IDirect3DVertexBuffer9 * VertexBuffer9::getBuffer() const
@@ -199,8 +187,8 @@
     return mVertexBuffer;
 }
 
-bool VertexBuffer9::spaceRequired(const gl::VertexAttribute &attrib, std::size_t count, GLsizei instances,
-                                  unsigned int *outSpaceRequired) const
+gl::Error VertexBuffer9::spaceRequired(const gl::VertexAttribute &attrib, std::size_t count, GLsizei instances,
+                                       unsigned int *outSpaceRequired) const
 {
     gl::VertexFormat vertexFormat(attrib, GL_FLOAT);
     const d3d9::VertexFormat &d3d9VertexInfo = d3d9::GetVertexFormatInfo(mRenderer->getCapsDeclTypes(), vertexFormat);
@@ -224,11 +212,11 @@
             {
                 *outSpaceRequired = d3d9VertexInfo.outputElementSize * elementCount;
             }
-            return true;
+            return gl::Error(GL_NO_ERROR);
         }
         else
         {
-            return false;
+            return gl::Error(GL_OUT_OF_MEMORY, "New vertex buffer size would result in an overflow.");
         }
     }
     else
@@ -238,7 +226,7 @@
         {
             *outSpaceRequired = elementSize * 4;
         }
-        return true;
+        return gl::Error(GL_NO_ERROR);
     }
 }
 
diff --git a/src/libGLESv2/renderer/d3d/d3d9/VertexBuffer9.h b/src/libGLESv2/renderer/d3d/d3d9/VertexBuffer9.h
index 6bde0cd..bdcf4bb 100644
--- a/src/libGLESv2/renderer/d3d/d3d9/VertexBuffer9.h
+++ b/src/libGLESv2/renderer/d3d/d3d9/VertexBuffer9.h
@@ -21,18 +21,18 @@
     explicit VertexBuffer9(rx::Renderer9 *renderer);
     virtual ~VertexBuffer9();
 
-    virtual bool initialize(unsigned int size, bool dynamicUsage);
+    virtual gl::Error initialize(unsigned int size, bool dynamicUsage);
 
     static VertexBuffer9 *makeVertexBuffer9(VertexBuffer *vertexBuffer);
 
-    virtual bool storeVertexAttributes(const gl::VertexAttribute &attrib, const gl::VertexAttribCurrentValueData &currentValue,
-                                       GLint start, GLsizei count, GLsizei instances, unsigned int offset);
+    virtual gl::Error storeVertexAttributes(const gl::VertexAttribute &attrib, const gl::VertexAttribCurrentValueData &currentValue,
+                                            GLint start, GLsizei count, GLsizei instances, unsigned int offset);
 
-    virtual bool getSpaceRequired(const gl::VertexAttribute &attrib, GLsizei count, GLsizei instances, unsigned int *outSpaceRequired) const;
+    virtual gl::Error getSpaceRequired(const gl::VertexAttribute &attrib, GLsizei count, GLsizei instances, unsigned int *outSpaceRequired) const;
 
     virtual unsigned int getBufferSize() const;
-    virtual bool setBufferSize(unsigned int size);
-    virtual bool discard();
+    virtual gl::Error setBufferSize(unsigned int size);
+    virtual gl::Error discard();
 
     IDirect3DVertexBuffer9 *getBuffer() const;
 
@@ -45,8 +45,8 @@
     unsigned int mBufferSize;
     bool mDynamicUsage;
 
-    bool spaceRequired(const gl::VertexAttribute &attrib, std::size_t count, GLsizei instances,
-                       unsigned int *outSpaceRequired) const;
+    gl::Error spaceRequired(const gl::VertexAttribute &attrib, std::size_t count, GLsizei instances,
+                            unsigned int *outSpaceRequired) const;
 };
 
 }
diff --git a/src/libGLESv2/renderer/d3d/d3d9/VertexDeclarationCache.cpp b/src/libGLESv2/renderer/d3d/d3d9/VertexDeclarationCache.cpp
index 8c22ecd..cefd786 100644
--- a/src/libGLESv2/renderer/d3d/d3d9/VertexDeclarationCache.cpp
+++ b/src/libGLESv2/renderer/d3d/d3d9/VertexDeclarationCache.cpp
@@ -1,4 +1,3 @@
-#include "precompiled.h"
 //
 // Copyright (c) 2012 The ANGLE Project Authors. All rights reserved.
 // Use of this source code is governed by a BSD-style license that can be
@@ -7,11 +6,11 @@
 
 // VertexDeclarationCache.cpp: Implements a helper class to construct and cache vertex declarations.
 
+#include "libGLESv2/renderer/d3d/d3d9/VertexDeclarationCache.h"
+#include "libGLESv2/renderer/d3d/d3d9/VertexBuffer9.h"
+#include "libGLESv2/renderer/d3d/d3d9/formatutils9.h"
 #include "libGLESv2/ProgramBinary.h"
 #include "libGLESv2/VertexAttribute.h"
-#include "libGLESv2/renderer/d3d/d3d9/VertexBuffer9.h"
-#include "libGLESv2/renderer/d3d/d3d9/VertexDeclarationCache.h"
-#include "libGLESv2/renderer/d3d/d3d9/formatutils9.h"
 
 namespace rx
 {
@@ -41,13 +40,27 @@
     }
 }
 
-GLenum VertexDeclarationCache::applyDeclaration(IDirect3DDevice9 *device, TranslatedAttribute attributes[], gl::ProgramBinary *programBinary, GLsizei instances, GLsizei *repeatDraw)
+gl::Error VertexDeclarationCache::applyDeclaration(IDirect3DDevice9 *device, TranslatedAttribute attributes[], gl::ProgramBinary *programBinary, GLsizei instances, GLsizei *repeatDraw)
 {
     *repeatDraw = 1;
 
     int indexedAttribute = gl::MAX_VERTEX_ATTRIBS;
     int instancedAttribute = gl::MAX_VERTEX_ATTRIBS;
 
+    if (instances == 0)
+    {
+        for (int i = 0; i < gl::MAX_VERTEX_ATTRIBS; ++i)
+        {
+            if (attributes[i].divisor != 0)
+            {
+                // If a divisor is set, it still applies even if an instanced draw was not used, so treat
+                // as a single-instance draw.
+                instances = 1;
+                break;
+            }
+        }
+    }
+
     if (instances > 0)
     {
         // Find an indexed attribute to be mapped to D3D stream 0
@@ -68,10 +81,9 @@
             }
         }
 
-        if (indexedAttribute == gl::MAX_VERTEX_ATTRIBS)
-        {
-            return GL_INVALID_OPERATION;
-        }
+        // The validation layer checks that there is at least one active attribute with a zero divisor as per
+        // the GL_ANGLE_instanced_arrays spec.
+        ASSERT(indexedAttribute != gl::MAX_VERTEX_ATTRIBS);
     }
 
     D3DCAPS9 caps;
@@ -176,7 +188,7 @@
                 mLastSetVDecl = entry->vertexDeclaration;
             }
 
-            return GL_NO_ERROR;
+            return gl::Error(GL_NO_ERROR);
         }
     }
 
@@ -198,12 +210,17 @@
     }
 
     memcpy(lastCache->cachedElements, elements, (element - elements) * sizeof(D3DVERTEXELEMENT9));
-    device->CreateVertexDeclaration(elements, &lastCache->vertexDeclaration);
+    HRESULT result = device->CreateVertexDeclaration(elements, &lastCache->vertexDeclaration);
+    if (FAILED(result))
+    {
+        return gl::Error(GL_OUT_OF_MEMORY, "Failed to create internal vertex declaration, result: 0x%X.", result);
+    }
+
     device->SetVertexDeclaration(lastCache->vertexDeclaration);
     mLastSetVDecl = lastCache->vertexDeclaration;
     lastCache->lruCount = ++mMaxLru;
 
-    return GL_NO_ERROR;
+    return gl::Error(GL_NO_ERROR);
 }
 
 void VertexDeclarationCache::markStateDirty()
diff --git a/src/libGLESv2/renderer/d3d/d3d9/VertexDeclarationCache.h b/src/libGLESv2/renderer/d3d/d3d9/VertexDeclarationCache.h
index 004e28d..9af36e0 100644
--- a/src/libGLESv2/renderer/d3d/d3d9/VertexDeclarationCache.h
+++ b/src/libGLESv2/renderer/d3d/d3d9/VertexDeclarationCache.h
@@ -9,6 +9,7 @@
 #ifndef LIBGLESV2_RENDERER_VERTEXDECLARATIONCACHE_H_
 #define LIBGLESV2_RENDERER_VERTEXDECLARATIONCACHE_H_
 
+#include "libGLESv2/Error.h"
 #include "libGLESv2/renderer/d3d/VertexDataManager.h"
 
 namespace gl
@@ -25,7 +26,7 @@
     VertexDeclarationCache();
     ~VertexDeclarationCache();
 
-    GLenum applyDeclaration(IDirect3DDevice9 *device, TranslatedAttribute attributes[], gl::ProgramBinary *programBinary, GLsizei instances, GLsizei *repeatDraw);
+    gl::Error applyDeclaration(IDirect3DDevice9 *device, TranslatedAttribute attributes[], gl::ProgramBinary *programBinary, GLsizei instances, GLsizei *repeatDraw);
 
     void markStateDirty();
 
diff --git a/src/libGLESv2/renderer/d3d/d3d9/formatutils9.cpp b/src/libGLESv2/renderer/d3d/d3d9/formatutils9.cpp
index 8e13b2e..f3acaf7 100644
--- a/src/libGLESv2/renderer/d3d/d3d9/formatutils9.cpp
+++ b/src/libGLESv2/renderer/d3d/d3d9/formatutils9.cpp
@@ -1,4 +1,3 @@
-#include "precompiled.h"
 //
 // Copyright (c) 2013-2014 The ANGLE Project Authors. All rights reserved.
 // Use of this source code is governed by a BSD-style license that can be
@@ -46,7 +45,7 @@
 {
     D3D9FastCopyMap map;
 
-    map.insert(std::make_pair(D3DFMT_A8R8G8B8, D3D9FastCopyFormat(GL_RGBA, GL_UNSIGNED_BYTE, CopyBGRAUByteToRGBAUByte)));
+    map.insert(std::make_pair(D3DFMT_A8R8G8B8, D3D9FastCopyFormat(GL_RGBA, GL_UNSIGNED_BYTE, CopyBGRA8ToRGBA8)));
 
     return map;
 }
@@ -223,8 +222,17 @@
     //                       | Internal format                     | Texture format      | Render format        | Load function                           |
     InsertD3D9FormatInfo(&map, GL_NONE,                             D3DFMT_NULL,          D3DFMT_NULL,           UnreachableLoad                          );
 
+    // We choose to downsample the GL_DEPTH_COMPONENT32_OES format to a 24-bit format because D3DFMT_D32 is not widely
+    // supported.  We're allowed to do this because:
+    //  - The ES spec 2.0.25 sec 3.7.1 states that we're allowed to store texture formats with internal format
+    //    resolutions of our own choosing.
+    //  - OES_depth_texture states that downsampling of the depth formats is allowed.
+    //  - ANGLE_depth_texture does not state minimum required resolutions of the depth texture formats it
+    //    introduces.
+    // In ES3 however, there are minimum resolutions for the texture formats and this would not be allowed.
+
     InsertD3D9FormatInfo(&map, GL_DEPTH_COMPONENT16,                D3DFMT_INTZ,          D3DFMT_D24S8,          UnreachableLoad                          );
-    InsertD3D9FormatInfo(&map, GL_DEPTH_COMPONENT32_OES,            D3DFMT_INTZ,          D3DFMT_D32,            UnreachableLoad                          );
+    InsertD3D9FormatInfo(&map, GL_DEPTH_COMPONENT32_OES,            D3DFMT_INTZ,          D3DFMT_D24X8,          UnreachableLoad                          );
     InsertD3D9FormatInfo(&map, GL_DEPTH24_STENCIL8_OES,             D3DFMT_INTZ,          D3DFMT_D24S8,          UnreachableLoad                          );
     InsertD3D9FormatInfo(&map, GL_STENCIL_INDEX8,                   D3DFMT_UNKNOWN,       D3DFMT_D24S8,          UnreachableLoad                          ); // TODO: What's the texture format?
 
diff --git a/src/libGLESv2/renderer/d3d/d3d9/formatutils9.h b/src/libGLESv2/renderer/d3d/d3d9/formatutils9.h
index 61ede28..f26fe43 100644
--- a/src/libGLESv2/renderer/d3d/d3d9/formatutils9.h
+++ b/src/libGLESv2/renderer/d3d/d3d9/formatutils9.h
@@ -12,6 +12,8 @@
 
 #include "libGLESv2/formatutils.h"
 
+#include <map>
+
 namespace rx
 {
 
diff --git a/src/libGLESv2/renderer/d3d/d3d9/renderer9_utils.cpp b/src/libGLESv2/renderer/d3d/d3d9/renderer9_utils.cpp
index a11e73d..d6f950a 100644
--- a/src/libGLESv2/renderer/d3d/d3d9/renderer9_utils.cpp
+++ b/src/libGLESv2/renderer/d3d/d3d9/renderer9_utils.cpp
@@ -1,4 +1,3 @@
-#include "precompiled.h"
 //
 // 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
@@ -11,9 +10,10 @@
 #include "libGLESv2/renderer/d3d/d3d9/renderer9_utils.h"
 #include "libGLESv2/renderer/d3d/d3d9/formatutils9.h"
 #include "libGLESv2/formatutils.h"
-#include "common/mathutil.h"
-#include "libGLESv2/Context.h"
+#include "libGLESv2/Framebuffer.h"
+#include "libGLESv2/renderer/d3d/d3d9/RenderTarget9.h"
 
+#include "common/mathutil.h"
 #include "common/debug.h"
 
 #include "third_party/systeminfo/SystemInfo.h"
@@ -328,6 +328,11 @@
         textureCapsMap->insert(*internalFormat, textureCaps);
 
         maxSamples = std::max(maxSamples, textureCaps.getMaxSamples());
+
+        if (gl::GetInternalFormatInfo(*internalFormat).compressed)
+        {
+            caps->compressedTextureFormats.push_back(*internalFormat);
+        }
     }
 
     // GL core feature limits
@@ -367,6 +372,77 @@
     caps->minAliasedLineWidth = 1.0f;
     caps->maxAliasedLineWidth = 1.0f;
 
+    // Primitive count limits (unused in ES2)
+    caps->maxElementsIndices = 0;
+    caps->maxElementsVertices = 0;
+
+    // Program and shader binary formats (no supported shader binary formats)
+    caps->programBinaryFormats.push_back(GL_PROGRAM_BINARY_ANGLE);
+
+    // WaitSync is ES3-only, set to zero
+    caps->maxServerWaitTimeout = 0;
+
+    // Vertex shader limits
+    caps->maxVertexAttributes = 16;
+
+    const size_t reservedVertexUniformVectors = 2; // dx_ViewAdjust and dx_DepthRange.
+    const size_t MAX_VERTEX_CONSTANT_VECTORS_D3D9 = 256;
+    caps->maxVertexUniformVectors = MAX_VERTEX_CONSTANT_VECTORS_D3D9 - reservedVertexUniformVectors;
+    caps->maxVertexUniformComponents = caps->maxVertexUniformVectors * 4;
+
+    caps->maxVertexUniformBlocks = 0;
+
+    const size_t MAX_VERTEX_OUTPUT_VECTORS_SM3 = 10;
+    const size_t MAX_VERTEX_OUTPUT_VECTORS_SM2 = 8;
+    caps->maxVertexOutputComponents = ((deviceCaps.VertexShaderVersion >= D3DVS_VERSION(3, 0)) ? MAX_VERTEX_OUTPUT_VECTORS_SM3
+                                                                                               : MAX_VERTEX_OUTPUT_VECTORS_SM2) * 4;
+
+    // Only Direct3D 10 ready devices support all the necessary vertex texture formats.
+    // We test this using D3D9 by checking support for the R16F format.
+    if (deviceCaps.VertexShaderVersion >= D3DVS_VERSION(3, 0) &&
+        SUCCEEDED(d3d9->CheckDeviceFormat(adapter, deviceType, currentDisplayMode.Format,
+                                          D3DUSAGE_QUERY_VERTEXTEXTURE, D3DRTYPE_TEXTURE, D3DFMT_R16F)))
+    {
+        const size_t MAX_TEXTURE_IMAGE_UNITS_VTF_SM3 = 4;
+        caps->maxVertexTextureImageUnits = MAX_TEXTURE_IMAGE_UNITS_VTF_SM3;
+    }
+    else
+    {
+        caps->maxVertexTextureImageUnits = 0;
+    }
+
+    // Fragment shader limits
+    const size_t reservedPixelUniformVectors = 3; // dx_ViewCoords, dx_DepthFront and dx_DepthRange.
+
+    const size_t MAX_PIXEL_CONSTANT_VECTORS_SM3 = 224;
+    const size_t MAX_PIXEL_CONSTANT_VECTORS_SM2 = 32;
+    caps->maxFragmentUniformVectors = ((deviceCaps.PixelShaderVersion >= D3DPS_VERSION(3, 0)) ? MAX_PIXEL_CONSTANT_VECTORS_SM3
+                                                                                              : MAX_PIXEL_CONSTANT_VECTORS_SM2) - reservedPixelUniformVectors;
+    caps->maxFragmentUniformComponents = caps->maxFragmentUniformVectors * 4;
+    caps->maxFragmentUniformBlocks = 0;
+    caps->maxFragmentInputComponents = caps->maxVertexOutputComponents;
+    caps->maxTextureImageUnits = 16;
+    caps->minProgramTexelOffset = 0;
+    caps->maxProgramTexelOffset = 0;
+
+    // Aggregate shader limits (unused in ES2)
+    caps->maxUniformBufferBindings = 0;
+    caps->maxUniformBlockSize = 0;
+    caps->uniformBufferOffsetAlignment = 0;
+    caps->maxCombinedUniformBlocks = 0;
+    caps->maxCombinedVertexUniformComponents = 0;
+    caps->maxCombinedFragmentUniformComponents = 0;
+    caps->maxVaryingComponents = 0;
+
+    // Aggregate shader limits
+    caps->maxVaryingVectors = caps->maxVertexOutputComponents / 4;
+    caps->maxCombinedTextureImageUnits = caps->maxVertexTextureImageUnits + caps->maxTextureImageUnits;
+
+    // Transform feedback limits
+    caps->maxTransformFeedbackInterleavedComponents = 0;
+    caps->maxTransformFeedbackSeparateAttributes = 0;
+    caps->maxTransformFeedbackSeparateComponents = 0;
+
     // GL extension support
     extensions->setTextureExtensionSupport(*textureCapsMap);
     extensions->elementIndexUint = deviceCaps.MaxVertexIndex >= (1 << 16);
@@ -457,6 +533,12 @@
     *levelOffset = upsampleCount;
 }
 
+RenderTarget9 *GetAttachmentRenderTarget(gl::FramebufferAttachment *attachment)
+{
+    RenderTarget *renderTarget = rx::GetAttachmentRenderTarget(attachment);
+    return RenderTarget9::makeRenderTarget9(renderTarget);
+}
+
 }
 
 }
diff --git a/src/libGLESv2/renderer/d3d/d3d9/renderer9_utils.h b/src/libGLESv2/renderer/d3d/d3d9/renderer9_utils.h
index 5f19f3b..b0a940e 100644
--- a/src/libGLESv2/renderer/d3d/d3d9/renderer9_utils.h
+++ b/src/libGLESv2/renderer/d3d/d3d9/renderer9_utils.h
@@ -4,7 +4,7 @@
 // found in the LICENSE file.
 //
 
-// renderer9_utils.h: Conversion functions and other utility routines 
+// renderer9_utils.h: Conversion functions and other utility routines
 // specific to the D3D9 renderer
 
 #ifndef LIBGLESV2_RENDERER_RENDERER9_UTILS_H
@@ -13,8 +13,14 @@
 #include "libGLESv2/angletypes.h"
 #include "libGLESv2/Caps.h"
 
+namespace gl
+{
+class FramebufferAttachment;
+}
+
 namespace rx
 {
+class RenderTarget9;
 
 namespace gl_d3d9
 {
@@ -68,6 +74,8 @@
     }
 }
 
+RenderTarget9 *GetAttachmentRenderTarget(gl::FramebufferAttachment *attachment);
+
 }
 
 }
diff --git a/src/libGLESv2/renderer/loadimage.cpp b/src/libGLESv2/renderer/loadimage.cpp
index 4a29460..1986191 100644
--- a/src/libGLESv2/renderer/loadimage.cpp
+++ b/src/libGLESv2/renderer/loadimage.cpp
@@ -1,4 +1,3 @@
-#include "precompiled.h"
 //
 // Copyright (c) 2013-2014 The ANGLE Project Authors. All rights reserved.
 // Use of this source code is governed by a BSD-style license that can be
diff --git a/src/libGLESv2/renderer/loadimageSSE2.cpp b/src/libGLESv2/renderer/loadimageSSE2.cpp
index 9c83894..cc20d94 100644
--- a/src/libGLESv2/renderer/loadimageSSE2.cpp
+++ b/src/libGLESv2/renderer/loadimageSSE2.cpp
@@ -1,4 +1,3 @@
-#include "precompiled.h"
 //
 // 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
diff --git a/src/libGLESv2/renderer/vertexconversion.h b/src/libGLESv2/renderer/vertexconversion.h
index 590b9d4..81ba8a0 100644
--- a/src/libGLESv2/renderer/vertexconversion.h
+++ b/src/libGLESv2/renderer/vertexconversion.h
@@ -10,6 +10,10 @@
 #ifndef LIBGLESV2_VERTEXCONVERSION_H_
 #define LIBGLESV2_VERTEXCONVERSION_H_
 
+#include <limits>
+#include <cstdint>
+#include <cstddef>
+
 namespace rx
 {
 
@@ -154,11 +158,13 @@
     static const bool identity = (WidenRule::initialWidth == WidenRule::finalWidth) && Converter::identity;
     static const std::size_t finalSize = WidenRule::finalWidth * sizeof(OutputType);
 
-    static void convertArray(const InputType *in, std::size_t stride, std::size_t n, OutputType *out)
+    static void convertArray(const uint8_t *input, size_t stride, size_t n, uint8_t *output)
     {
+        OutputType *out = reinterpret_cast<OutputType*>(output);
+
         for (std::size_t i = 0; i < n; i++)
         {
-            const InputType *ein = pointerAddBytes(in, i * stride);
+            const InputType *ein = reinterpret_cast<const InputType*>(input + i * stride);
 
             copyComponent(out, ein, 0, static_cast<OutputType>(DefaultValueRule::zero()));
             copyComponent(out, ein, 1, static_cast<OutputType>(DefaultValueRule::zero()));
@@ -169,19 +175,7 @@
         }
     }
 
-    static void convertArray(const void *in, std::size_t stride, std::size_t n, void *out)
-    {
-        return convertArray(static_cast<const InputType*>(in), stride, n, static_cast<OutputType*>(out));
-    }
-
   private:
-    // Advance the given pointer by a number of bytes (not pointed-to elements).
-    template <class T>
-    static T *pointerAddBytes(T *basePtr, std::size_t numBytes)
-    {
-        return reinterpret_cast<T *>(reinterpret_cast<uintptr_t>(basePtr) + numBytes);
-    }
-
     static void copyComponent(OutputType *out, const InputType *in, std::size_t elementindex, OutputType defaultvalue)
     {
         if (WidenRule::finalWidth > elementindex)
diff --git a/src/libGLESv2/validationES.cpp b/src/libGLESv2/validationES.cpp
index 7688780..9a5fa31 100644
--- a/src/libGLESv2/validationES.cpp
+++ b/src/libGLESv2/validationES.cpp
@@ -1,4 +1,3 @@
-#include "precompiled.h"
 //
 // Copyright (c) 2013-2014 The ANGLE Project Authors. All rights reserved.
 // Use of this source code is governed by a BSD-style license that can be
@@ -20,6 +19,7 @@
 #include "libGLESv2/ProgramBinary.h"
 #include "libGLESv2/TransformFeedback.h"
 #include "libGLESv2/VertexArray.h"
+#include "libGLESv2/renderer/BufferImpl.h"
 
 #include "common/mathutil.h"
 #include "common/utilities.h"
@@ -168,7 +168,7 @@
     return level <= gl::log2(maxDimension);
 }
 
-bool ValidImageSize(const gl::Context *context, GLenum target, GLint level,
+bool ValidImageSize(const Context *context, GLenum target, GLint level,
                     GLsizei width, GLsizei height, GLsizei depth)
 {
     if (level < 0 || width < 0 || height < 0 || depth < 0)
@@ -190,7 +190,7 @@
     return true;
 }
 
-bool ValidCompressedImageSize(const gl::Context *context, GLenum internalFormat, GLsizei width, GLsizei height)
+bool ValidCompressedImageSize(const Context *context, GLenum internalFormat, GLsizei width, GLsizei height)
 {
     const gl::InternalFormat &formatInfo = gl::GetInternalFormatInfo(internalFormat);
     if (!formatInfo.compressed)
@@ -224,7 +224,7 @@
     }
 }
 
-bool ValidProgram(const Context *context, GLuint id)
+bool ValidProgram(Context *context, GLuint id)
 {
     // ES3 spec (section 2.11.1) -- "Commands that accept shader or program object names will generate the
     // error INVALID_VALUE if the provided name is not the name of either a shader or program object and
@@ -237,16 +237,18 @@
     else if (context->getShader(id) != NULL)
     {
         // ID is the wrong type
-        return gl::error(GL_INVALID_OPERATION, false);
+        context->recordError(Error(GL_INVALID_OPERATION));
+        return false;
     }
     else
     {
         // No shader/program object has this ID
-        return gl::error(GL_INVALID_VALUE, false);
+        context->recordError(Error(GL_INVALID_VALUE));
+        return false;
     }
 }
 
-bool ValidateAttachmentTarget(const gl::Context *context, GLenum attachment)
+bool ValidateAttachmentTarget(gl::Context *context, GLenum attachment)
 {
     if (attachment >= GL_COLOR_ATTACHMENT0_EXT && attachment <= GL_COLOR_ATTACHMENT15_EXT)
     {
@@ -254,7 +256,8 @@
 
         if (colorAttachment >= context->getCaps().maxColorAttachments)
         {
-            return gl::error(GL_INVALID_VALUE, false);
+            context->recordError(Error(GL_INVALID_VALUE));
+            return false;
         }
     }
     else
@@ -268,19 +271,21 @@
           case GL_DEPTH_STENCIL_ATTACHMENT:
             if (context->getClientVersion() < 3)
             {
-                return gl::error(GL_INVALID_ENUM, false);
+                context->recordError(Error(GL_INVALID_ENUM));
+                return false;
             }
             break;
 
           default:
-            return gl::error(GL_INVALID_ENUM, false);
+            context->recordError(Error(GL_INVALID_ENUM));
+            return false;
         }
     }
 
     return true;
 }
 
-bool ValidateRenderbufferStorageParameters(const gl::Context *context, GLenum target, GLsizei samples,
+bool ValidateRenderbufferStorageParameters(gl::Context *context, GLenum target, GLsizei samples,
                                            GLenum internalformat, GLsizei width, GLsizei height,
                                            bool angleExtension)
 {
@@ -289,18 +294,21 @@
       case GL_RENDERBUFFER:
         break;
       default:
-        return gl::error(GL_INVALID_ENUM, false);
+        context->recordError(Error(GL_INVALID_ENUM));
+        return false;
     }
 
     if (width < 0 || height < 0 || samples < 0)
     {
-        return gl::error(GL_INVALID_VALUE, false);
+        context->recordError(Error(GL_INVALID_VALUE));
+        return false;
     }
 
     const gl::InternalFormat &formatInfo = gl::GetInternalFormatInfo(internalformat);
     if (!formatInfo.textureSupport(context->getClientVersion(), context->getExtensions()))
     {
-        return gl::error(GL_INVALID_ENUM, false);
+        context->recordError(Error(GL_INVALID_ENUM));
+        return false;
     }
 
     // ANGLE_framebuffer_multisample does not explicitly state that the internal format must be
@@ -309,23 +317,27 @@
     // internal format must be sized and not an integer format if samples is greater than zero.
     if (formatInfo.pixelBytes == 0)
     {
-        return gl::error(GL_INVALID_ENUM, false);
+        context->recordError(Error(GL_INVALID_ENUM));
+        return false;
     }
 
     if ((formatInfo.componentType == GL_UNSIGNED_INT || formatInfo.componentType == GL_INT) && samples > 0)
     {
-        return gl::error(GL_INVALID_OPERATION, false);
+        context->recordError(Error(GL_INVALID_OPERATION));
+        return false;
     }
 
     const TextureCaps &formatCaps = context->getTextureCaps().get(internalformat);
     if (!formatCaps.renderable)
     {
-        return gl::error(GL_INVALID_ENUM, false);
+        context->recordError(Error(GL_INVALID_ENUM));
+        return false;
     }
 
     if (static_cast<GLuint>(std::max(width, height)) > context->getCaps().maxRenderbufferSize)
     {
-        return gl::error(GL_INVALID_VALUE, false);
+        context->recordError(Error(GL_INVALID_VALUE));
+        return false;
     }
 
     // ANGLE_framebuffer_multisample states that the value of samples must be less than or equal
@@ -337,27 +349,31 @@
         ASSERT(context->getExtensions().framebufferMultisample);
         if (static_cast<GLuint>(samples) > context->getExtensions().maxSamples)
         {
-            return gl::error(GL_INVALID_VALUE, false);
+            context->recordError(Error(GL_INVALID_VALUE));
+            return false;
         }
 
         // Check if this specific format supports enough samples
         if (static_cast<GLuint>(samples) > formatCaps.getMaxSamples())
         {
-            return gl::error(GL_OUT_OF_MEMORY, false);
+            context->recordError(Error(GL_OUT_OF_MEMORY));
+            return false;
         }
     }
     else
     {
         if (static_cast<GLuint>(samples) > formatCaps.getMaxSamples())
         {
-            return gl::error(GL_INVALID_VALUE, false);
+            context->recordError(Error(GL_INVALID_VALUE));
+            return false;
         }
     }
 
     GLuint handle = context->getState().getRenderbufferId();
     if (handle == 0)
     {
-        return gl::error(GL_INVALID_OPERATION, false);
+        context->recordError(Error(GL_INVALID_OPERATION));
+        return false;
     }
 
     return true;
@@ -368,7 +384,8 @@
 {
     if (!ValidFramebufferTarget(target))
     {
-        return gl::error(GL_INVALID_ENUM, false);
+        context->recordError(Error(GL_INVALID_ENUM));
+        return false;
     }
 
     gl::Framebuffer *framebuffer = context->getState().getTargetFramebuffer(target);
@@ -376,7 +393,8 @@
 
     if (!framebuffer || (framebufferHandle == 0 && renderbuffer != 0))
     {
-        return gl::error(GL_INVALID_OPERATION, false);
+        context->recordError(Error(GL_INVALID_OPERATION));
+        return false;
     }
 
     if (!ValidateAttachmentTarget(context, attachment))
@@ -392,7 +410,8 @@
     {
         if (!context->getRenderbuffer(renderbuffer))
         {
-            return gl::error(GL_INVALID_OPERATION, false);
+            context->recordError(Error(GL_INVALID_OPERATION));
+            return false;
         }
     }
 
@@ -434,16 +453,19 @@
       case GL_LINEAR:
         if (fromAngleExtension)
         {
-            return gl::error(GL_INVALID_ENUM, false);
+            context->recordError(Error(GL_INVALID_ENUM));
+            return false;
         }
         break;
       default:
-        return gl::error(GL_INVALID_ENUM, false);
+        context->recordError(Error(GL_INVALID_ENUM));
+        return false;
     }
 
     if ((mask & ~(GL_COLOR_BUFFER_BIT | GL_STENCIL_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)) != 0)
     {
-        return gl::error(GL_INVALID_VALUE, false);
+        context->recordError(Error(GL_INVALID_VALUE));
+        return false;
     }
 
     if (mask == 0)
@@ -456,14 +478,16 @@
     if (fromAngleExtension && (srcX1 - srcX0 != dstX1 - dstX0 || srcY1 - srcY0 != dstY1 - dstY0))
     {
         ERR("Scaling and flipping in BlitFramebufferANGLE not supported by this implementation.");
-        return gl::error(GL_INVALID_OPERATION, false);
+        context->recordError(Error(GL_INVALID_OPERATION));
+        return false;
     }
 
     // ES3.0 spec, section 4.3.2 states that linear filtering is only available for the
     // color buffer, leaving only nearest being unfiltered from above
     if ((mask & ~GL_COLOR_BUFFER_BIT) != 0 && filter != GL_NEAREST)
     {
-        return gl::error(GL_INVALID_OPERATION, false);
+        context->recordError(Error(GL_INVALID_OPERATION));
+        return false;
     }
 
     if (context->getState().getReadFramebuffer()->id() == context->getState().getDrawFramebuffer()->id())
@@ -473,7 +497,8 @@
             ERR("Blits with the same source and destination framebuffer are not supported by this "
                 "implementation.");
         }
-        return gl::error(GL_INVALID_OPERATION, false);
+        context->recordError(Error(GL_INVALID_OPERATION));
+        return false;
     }
 
     gl::Framebuffer *readFramebuffer = context->getState().getReadFramebuffer();
@@ -481,12 +506,14 @@
     if (!readFramebuffer || readFramebuffer->completeness() != GL_FRAMEBUFFER_COMPLETE ||
         !drawFramebuffer || drawFramebuffer->completeness() != GL_FRAMEBUFFER_COMPLETE)
     {
-        return gl::error(GL_INVALID_FRAMEBUFFER_OPERATION, false);
+        context->recordError(Error(GL_INVALID_FRAMEBUFFER_OPERATION));
+        return false;
     }
 
     if (drawFramebuffer->getSamples() != 0)
     {
-        return gl::error(GL_INVALID_OPERATION, false);
+        context->recordError(Error(GL_INVALID_OPERATION));
+        return false;
     }
 
     bool sameBounds = srcX0 == dstX0 && srcY0 == dstY0 && srcX1 == dstX1 && srcY1 == dstY1;
@@ -515,29 +542,34 @@
                     if ( (readFormatInfo.componentType == GL_UNSIGNED_NORMALIZED || readFormatInfo.componentType == GL_SIGNED_NORMALIZED) &&
                         !(drawFormatInfo.componentType == GL_UNSIGNED_NORMALIZED || drawFormatInfo.componentType == GL_SIGNED_NORMALIZED))
                     {
-                        return gl::error(GL_INVALID_OPERATION, false);
+                        context->recordError(Error(GL_INVALID_OPERATION));
+                        return false;
                     }
 
                     if (readFormatInfo.componentType == GL_UNSIGNED_INT && drawFormatInfo.componentType != GL_UNSIGNED_INT)
                     {
-                        return gl::error(GL_INVALID_OPERATION, false);
+                        context->recordError(Error(GL_INVALID_OPERATION));
+                        return false;
                     }
 
                     if (readFormatInfo.componentType == GL_INT && drawFormatInfo.componentType != GL_INT)
                     {
-                        return gl::error(GL_INVALID_OPERATION, false);
+                        context->recordError(Error(GL_INVALID_OPERATION));
+                        return false;
                     }
 
                     if (readColorBuffer->getSamples() > 0 && (readInternalFormat != drawInternalFormat || !sameBounds))
                     {
-                        return gl::error(GL_INVALID_OPERATION, false);
+                        context->recordError(Error(GL_INVALID_OPERATION));
+                        return false;
                     }
                 }
             }
 
             if ((readFormatInfo.componentType == GL_INT || readFormatInfo.componentType == GL_UNSIGNED_INT) && filter == GL_LINEAR)
             {
-                return gl::error(GL_INVALID_OPERATION, false);
+                context->recordError(Error(GL_INVALID_OPERATION));
+                return false;
             }
 
             if (fromAngleExtension)
@@ -545,7 +577,8 @@
                 const GLenum readColorbufferType = readFramebuffer->getReadColorbufferType();
                 if (readColorbufferType != GL_TEXTURE_2D && readColorbufferType != GL_RENDERBUFFER)
                 {
-                    return gl::error(GL_INVALID_OPERATION, false);
+                    context->recordError(Error(GL_INVALID_OPERATION));
+                    return false;
                 }
 
                 for (unsigned int colorAttachment = 0; colorAttachment < gl::IMPLEMENTATION_MAX_DRAW_BUFFERS; colorAttachment++)
@@ -557,12 +590,14 @@
 
                         if (attachment->type() != GL_TEXTURE_2D && attachment->type() != GL_RENDERBUFFER)
                         {
-                            return gl::error(GL_INVALID_OPERATION, false);
+                            context->recordError(Error(GL_INVALID_OPERATION));
+                            return false;
                         }
 
                         if (attachment->getActualFormat() != readColorBuffer->getActualFormat())
                         {
-                            return gl::error(GL_INVALID_OPERATION, false);
+                            context->recordError(Error(GL_INVALID_OPERATION));
+                            return false;
                         }
                     }
                 }
@@ -570,7 +605,8 @@
                                                                         srcX0, srcY0, srcX1, srcY1,
                                                                         dstX0, dstY0, dstX1, dstY1))
                 {
-                    return gl::error(GL_INVALID_OPERATION, false);
+                    context->recordError(Error(GL_INVALID_OPERATION));
+                    return false;
                 }
             }
         }
@@ -585,12 +621,14 @@
         {
             if (readDepthBuffer->getActualFormat() != drawDepthBuffer->getActualFormat())
             {
-                return gl::error(GL_INVALID_OPERATION, false);
+                context->recordError(Error(GL_INVALID_OPERATION));
+                return false;
             }
 
             if (readDepthBuffer->getSamples() > 0 && !sameBounds)
             {
-                return gl::error(GL_INVALID_OPERATION, false);
+                context->recordError(Error(GL_INVALID_OPERATION));
+                return false;
             }
 
             if (fromAngleExtension)
@@ -599,12 +637,14 @@
                                   srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1))
                 {
                     ERR("Only whole-buffer depth and stencil blits are supported by this implementation.");
-                    return gl::error(GL_INVALID_OPERATION, false); // only whole-buffer copies are permitted
+                    context->recordError(Error(GL_INVALID_OPERATION)); // only whole-buffer copies are permitted
+                    return false;
                 }
 
                 if (readDepthBuffer->getSamples() != 0 || drawDepthBuffer->getSamples() != 0)
                 {
-                    return gl::error(GL_INVALID_OPERATION, false);
+                    context->recordError(Error(GL_INVALID_OPERATION));
+                    return false;
                 }
             }
         }
@@ -619,12 +659,14 @@
         {
             if (readStencilBuffer->getActualFormat() != drawStencilBuffer->getActualFormat())
             {
-                return gl::error(GL_INVALID_OPERATION, false);
+                context->recordError(Error(GL_INVALID_OPERATION));
+                return false;
             }
 
             if (readStencilBuffer->getSamples() > 0 && !sameBounds)
             {
-                return gl::error(GL_INVALID_OPERATION, false);
+                context->recordError(Error(GL_INVALID_OPERATION));
+                return false;
             }
 
             if (fromAngleExtension)
@@ -633,12 +675,14 @@
                                   srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1))
                 {
                     ERR("Only whole-buffer depth and stencil blits are supported by this implementation.");
-                    return gl::error(GL_INVALID_OPERATION, false); // only whole-buffer copies are permitted
+                    context->recordError(Error(GL_INVALID_OPERATION)); // only whole-buffer copies are permitted
+                    return false;
                 }
 
                 if (readStencilBuffer->getSamples() != 0 || drawStencilBuffer->getSamples() != 0)
                 {
-                    return gl::error(GL_INVALID_OPERATION, false);
+                    context->recordError(Error(GL_INVALID_OPERATION));
+                    return false;
                 }
             }
         }
@@ -647,7 +691,7 @@
     return true;
 }
 
-bool ValidateGetVertexAttribParameters(GLenum pname, int clientVersion)
+bool ValidateGetVertexAttribParameters(Context *context, GLenum pname)
 {
     switch (pname)
     {
@@ -667,10 +711,16 @@
         return true;
 
       case GL_VERTEX_ATTRIB_ARRAY_INTEGER:
-        return ((clientVersion >= 3) ? true : gl::error(GL_INVALID_ENUM, false));
+        if (context->getClientVersion() < 3)
+        {
+            context->recordError(Error(GL_INVALID_ENUM));
+            return false;
+        }
+        return true;
 
       default:
-        return gl::error(GL_INVALID_ENUM, false);
+        context->recordError(Error(GL_INVALID_ENUM));
+        return false;
     }
 }
 
@@ -691,7 +741,8 @@
       case GL_TEXTURE_MAX_LOD:
         if (context->getClientVersion() < 3)
         {
-            return gl::error(GL_INVALID_ENUM, false);
+            context->recordError(Error(GL_INVALID_ENUM));
+            return false;
         }
         break;
 
@@ -710,7 +761,8 @@
           case GL_MIRRORED_REPEAT:
             return true;
           default:
-            return gl::error(GL_INVALID_ENUM, false);
+            context->recordError(Error(GL_INVALID_ENUM));
+            return false;
         }
 
       case GL_TEXTURE_MIN_FILTER:
@@ -724,7 +776,8 @@
           case GL_LINEAR_MIPMAP_LINEAR:
             return true;
           default:
-            return gl::error(GL_INVALID_ENUM, false);
+            context->recordError(Error(GL_INVALID_ENUM));
+            return false;
         }
         break;
 
@@ -735,7 +788,8 @@
           case GL_LINEAR:
             return true;
           default:
-            return gl::error(GL_INVALID_ENUM, false);
+            context->recordError(Error(GL_INVALID_ENUM));
+            return false;
         }
         break;
 
@@ -746,20 +800,23 @@
           case GL_FRAMEBUFFER_ATTACHMENT_ANGLE:
             return true;
           default:
-            return gl::error(GL_INVALID_ENUM, false);
+            context->recordError(Error(GL_INVALID_ENUM));
+            return false;
         }
         break;
 
       case GL_TEXTURE_MAX_ANISOTROPY_EXT:
         if (!context->getExtensions().textureFilterAnisotropic)
         {
-            return gl::error(GL_INVALID_ENUM, false);
+            context->recordError(Error(GL_INVALID_ENUM));
+            return false;
         }
 
         // we assume the parameter passed to this validation method is truncated, not rounded
         if (param < 1)
         {
-            return gl::error(GL_INVALID_VALUE, false);
+            context->recordError(Error(GL_INVALID_VALUE));
+            return false;
         }
         return true;
 
@@ -776,7 +833,8 @@
           case GL_COMPARE_REF_TO_TEXTURE:
             return true;
           default:
-            return gl::error(GL_INVALID_ENUM, false);
+            context->recordError(Error(GL_INVALID_ENUM));
+            return false;
         }
         break;
 
@@ -794,7 +852,8 @@
           case GL_NEVER:
             return true;
           default:
-            return gl::error(GL_INVALID_ENUM, false);
+            context->recordError(Error(GL_INVALID_ENUM));
+            return false;
         }
         break;
 
@@ -812,7 +871,8 @@
           case GL_ONE:
             return true;
           default:
-            return gl::error(GL_INVALID_ENUM, false);
+            context->recordError(Error(GL_INVALID_ENUM));
+            return false;
         }
         break;
 
@@ -820,16 +880,18 @@
       case GL_TEXTURE_MAX_LEVEL:
         if (param < 0)
         {
-            return gl::error(GL_INVALID_VALUE, false);
+            context->recordError(Error(GL_INVALID_VALUE));
+            return false;
         }
         return true;
 
       default:
-        return gl::error(GL_INVALID_ENUM, false);
+        context->recordError(Error(GL_INVALID_ENUM));
+        return false;
     }
 }
 
-bool ValidateSamplerObjectParameter(GLenum pname)
+bool ValidateSamplerObjectParameter(gl::Context *context, GLenum pname)
 {
     switch (pname)
     {
@@ -845,7 +907,8 @@
         return true;
 
       default:
-        return gl::error(GL_INVALID_ENUM, false);
+        context->recordError(Error(GL_INVALID_ENUM));
+        return false;
     }
 }
 
@@ -857,17 +920,20 @@
 
     if (framebuffer->completeness() != GL_FRAMEBUFFER_COMPLETE)
     {
-        return gl::error(GL_INVALID_FRAMEBUFFER_OPERATION, false);
+        context->recordError(Error(GL_INVALID_FRAMEBUFFER_OPERATION));
+        return false;
     }
 
     if (context->getState().getReadFramebuffer()->id() != 0 && framebuffer->getSamples() != 0)
     {
-        return gl::error(GL_INVALID_OPERATION, false);
+        context->recordError(Error(GL_INVALID_OPERATION));
+        return false;
     }
 
     if (!framebuffer->getReadColorbuffer())
     {
-        return gl::error(GL_INVALID_OPERATION, false);
+        context->recordError(Error(GL_INVALID_OPERATION));
+        return false;
     }
 
     GLenum currentInternalFormat, currentFormat, currentType;
@@ -880,7 +946,8 @@
 
     if (!(currentFormat == format && currentType == type) && !validReadFormat)
     {
-        return gl::error(GL_INVALID_OPERATION, false);
+        context->recordError(Error(GL_INVALID_OPERATION));
+        return false;
     }
 
     GLenum sizedInternalFormat = GetSizedInternalFormat(format, type);
@@ -893,7 +960,8 @@
         int requiredSize = outputPitch * height;
         if (requiredSize > *bufSize)
         {
-            return gl::error(GL_INVALID_OPERATION, false);
+            context->recordError(Error(GL_INVALID_OPERATION));
+            return false;
         }
     }
 
@@ -904,12 +972,14 @@
 {
     if (!ValidQueryType(context, target))
     {
-        return gl::error(GL_INVALID_ENUM, false);
+        context->recordError(Error(GL_INVALID_ENUM));
+        return false;
     }
 
     if (id == 0)
     {
-        return gl::error(GL_INVALID_OPERATION, false);
+        context->recordError(Error(GL_INVALID_OPERATION));
+        return false;
     }
 
     // From EXT_occlusion_query_boolean: If BeginQueryEXT is called with an <id>
@@ -929,7 +999,8 @@
     //       no query may be active for either if glBeginQuery targets either.
     if (context->getState().isQueryActive())
     {
-        return gl::error(GL_INVALID_OPERATION, false);
+        context->recordError(Error(GL_INVALID_OPERATION));
+        return false;
     }
 
     Query *queryObject = context->getQuery(id, true, target);
@@ -937,13 +1008,15 @@
     // check that name was obtained with glGenQueries
     if (!queryObject)
     {
-        return gl::error(GL_INVALID_OPERATION, false);
+        context->recordError(Error(GL_INVALID_OPERATION));
+        return false;
     }
 
     // check for type mismatch
     if (queryObject->getType() != target)
     {
-        return gl::error(GL_INVALID_OPERATION, false);
+        context->recordError(Error(GL_INVALID_OPERATION));
+        return false;
     }
 
     return true;
@@ -953,19 +1026,16 @@
 {
     if (!ValidQueryType(context, target))
     {
-        return gl::error(GL_INVALID_ENUM, false);
+        context->recordError(Error(GL_INVALID_ENUM));
+        return false;
     }
 
     const Query *queryObject = context->getState().getActiveQuery(target);
 
     if (queryObject == NULL)
     {
-        return gl::error(GL_INVALID_OPERATION, false);
-    }
-
-    if (!queryObject->isStarted())
-    {
-        return gl::error(GL_INVALID_OPERATION, false);
+        context->recordError(Error(GL_INVALID_OPERATION));
+        return false;
     }
 
     return true;
@@ -976,13 +1046,15 @@
 {
     if (count < 0)
     {
-        return gl::error(GL_INVALID_VALUE, false);
+        context->recordError(Error(GL_INVALID_VALUE));
+        return false;
     }
 
     gl::ProgramBinary *programBinary = context->getState().getCurrentProgramBinary();
     if (!programBinary)
     {
-        return gl::error(GL_INVALID_OPERATION, false);
+        context->recordError(Error(GL_INVALID_OPERATION));
+        return false;
     }
 
     if (location == -1)
@@ -993,7 +1065,8 @@
 
     if (!programBinary->isValidUniformLocation(location))
     {
-        return gl::error(GL_INVALID_OPERATION, false);
+        context->recordError(Error(GL_INVALID_OPERATION));
+        return false;
     }
 
     LinkedUniform *uniform = programBinary->getUniformByLocation(location);
@@ -1001,7 +1074,8 @@
     // attempting to write an array to a non-array uniform is an INVALID_OPERATION
     if (uniform->elementCount() == 1 && count > 1)
     {
-        return gl::error(GL_INVALID_OPERATION, false);
+        context->recordError(Error(GL_INVALID_OPERATION));
+        return false;
     }
 
     *uniformOut = uniform;
@@ -1013,7 +1087,8 @@
     // Check for ES3 uniform entry points
     if (VariableComponentType(uniformType) == GL_UNSIGNED_INT && context->getClientVersion() < 3)
     {
-        return gl::error(GL_INVALID_OPERATION, false);
+        context->recordError(Error(GL_INVALID_OPERATION));
+        return false;
     }
 
     LinkedUniform *uniform = NULL;
@@ -1026,7 +1101,8 @@
     bool samplerUniformCheck = (IsSampler(uniform->type) && uniformType == GL_INT);
     if (!samplerUniformCheck && uniformType != uniform->type && targetBoolType != uniform->type)
     {
-        return gl::error(GL_INVALID_OPERATION, false);
+        context->recordError(Error(GL_INVALID_OPERATION));
+        return false;
     }
 
     return true;
@@ -1040,12 +1116,14 @@
     int cols = VariableColumnCount(matrixType);
     if (rows != cols && context->getClientVersion() < 3)
     {
-        return gl::error(GL_INVALID_OPERATION, false);
+        context->recordError(Error(GL_INVALID_OPERATION));
+        return false;
     }
 
     if (transpose != GL_FALSE && context->getClientVersion() < 3)
     {
-        return gl::error(GL_INVALID_VALUE, false);
+        context->recordError(Error(GL_INVALID_VALUE));
+        return false;
     }
 
     LinkedUniform *uniform = NULL;
@@ -1056,7 +1134,8 @@
 
     if (uniform->type != matrixType)
     {
-        return gl::error(GL_INVALID_OPERATION, false);
+        context->recordError(Error(GL_INVALID_OPERATION));
+        return false;
     }
 
     return true;
@@ -1066,7 +1145,8 @@
 {
     if (!context->getQueryParameterInfo(pname, nativeType, numParams))
     {
-        return gl::error(GL_INVALID_ENUM, false);
+        context->recordError(Error(GL_INVALID_ENUM));
+        return false;
     }
 
     if (pname >= GL_DRAW_BUFFER0 && pname <= GL_DRAW_BUFFER15)
@@ -1075,7 +1155,8 @@
 
         if (colorAttachment >= context->getCaps().maxDrawBuffers)
         {
-            return gl::error(GL_INVALID_OPERATION, false);
+            context->recordError(Error(GL_INVALID_OPERATION));
+            return false;
         }
     }
 
@@ -1085,9 +1166,10 @@
       case GL_TEXTURE_BINDING_CUBE_MAP:
       case GL_TEXTURE_BINDING_3D:
       case GL_TEXTURE_BINDING_2D_ARRAY:
-        if (context->getState().getActiveSampler() >= context->getMaximumCombinedTextureImageUnits())
+        if (context->getState().getActiveSampler() >= context->getCaps().maxCombinedTextureImageUnits)
         {
-            return gl::error(GL_INVALID_OPERATION, false);
+            context->recordError(Error(GL_INVALID_OPERATION));
+            return false;
         }
         break;
 
@@ -1098,13 +1180,15 @@
             ASSERT(framebuffer);
             if (framebuffer->completeness() != GL_FRAMEBUFFER_COMPLETE)
             {
-                return gl::error(GL_INVALID_OPERATION, false);
+                context->recordError(Error(GL_INVALID_OPERATION));
+                return false;
             }
 
             FramebufferAttachment *attachment = framebuffer->getReadColorbuffer();
             if (!attachment)
             {
-                return gl::error(GL_INVALID_OPERATION, false);
+                context->recordError(Error(GL_INVALID_OPERATION));
+                return false;
             }
         }
         break;
@@ -1129,38 +1213,45 @@
 
     if (!ValidTexture2DDestinationTarget(context, target))
     {
-        return gl::error(GL_INVALID_ENUM, false);
+        context->recordError(Error(GL_INVALID_ENUM));
+        return false;
     }
 
     if (level < 0 || xoffset < 0 || yoffset < 0 || zoffset < 0 || width < 0 || height < 0)
     {
-        return gl::error(GL_INVALID_VALUE, false);
+        context->recordError(Error(GL_INVALID_VALUE));
+        return false;
     }
 
     if (std::numeric_limits<GLsizei>::max() - xoffset < width || std::numeric_limits<GLsizei>::max() - yoffset < height)
     {
-        return gl::error(GL_INVALID_VALUE, false);
+        context->recordError(Error(GL_INVALID_VALUE));
+        return false;
     }
 
     if (border != 0)
     {
-        return gl::error(GL_INVALID_VALUE, false);
+        context->recordError(Error(GL_INVALID_VALUE));
+        return false;
     }
 
     if (!ValidMipLevel(context, target, level))
     {
-        return gl::error(GL_INVALID_VALUE, false);
+        context->recordError(Error(GL_INVALID_VALUE));
+        return false;
     }
 
     gl::Framebuffer *framebuffer = context->getState().getReadFramebuffer();
     if (framebuffer->completeness() != GL_FRAMEBUFFER_COMPLETE)
     {
-        return gl::error(GL_INVALID_FRAMEBUFFER_OPERATION, false);
+        context->recordError(Error(GL_INVALID_FRAMEBUFFER_OPERATION));
+        return false;
     }
 
     if (context->getState().getReadFramebuffer()->id() != 0 && framebuffer->getSamples() != 0)
     {
-        return gl::error(GL_INVALID_OPERATION, false);
+        context->recordError(Error(GL_INVALID_OPERATION));
+        return false;
     }
 
     const gl::Caps &caps = context->getCaps();
@@ -1240,24 +1331,28 @@
         break;
 
       default:
-        return gl::error(GL_INVALID_ENUM, false);
+        context->recordError(Error(GL_INVALID_ENUM));
+        return false;
     }
 
     if (!texture)
     {
-        return gl::error(GL_INVALID_OPERATION, false);
+        context->recordError(Error(GL_INVALID_OPERATION));
+        return false;
     }
 
     if (texture->isImmutable() && !isSubImage)
     {
-        return gl::error(GL_INVALID_OPERATION, false);
+        context->recordError(Error(GL_INVALID_OPERATION));
+        return false;
     }
 
     const gl::InternalFormat &formatInfo = gl::GetInternalFormatInfo(internalformat);
 
     if (formatInfo.depthBits > 0)
     {
-        return gl::error(GL_INVALID_OPERATION, false);
+        context->recordError(Error(GL_INVALID_OPERATION));
+        return false;
     }
 
     if (formatInfo.compressed)
@@ -1265,7 +1360,8 @@
         if (((width % formatInfo.compressedBlockWidth) != 0 && width != textureLevelWidth) ||
             ((height % formatInfo.compressedBlockHeight) != 0 && height != textureLevelHeight))
         {
-            return gl::error(GL_INVALID_OPERATION, false);
+            context->recordError(Error(GL_INVALID_OPERATION));
+            return false;
         }
     }
 
@@ -1275,25 +1371,29 @@
             yoffset + height > textureLevelHeight ||
             zoffset >= textureLevelDepth)
         {
-            return gl::error(GL_INVALID_VALUE, false);
+            context->recordError(Error(GL_INVALID_VALUE));
+            return false;
         }
     }
     else
     {
         if (IsCubemapTextureTarget(target) && width != height)
         {
-            return gl::error(GL_INVALID_VALUE, false);
+            context->recordError(Error(GL_INVALID_VALUE));
+            return false;
         }
 
         if (!formatInfo.textureSupport(context->getClientVersion(), context->getExtensions()))
         {
-            return gl::error(GL_INVALID_ENUM, false);
+            context->recordError(Error(GL_INVALID_ENUM));
+            return false;
         }
 
         int maxLevelDimension = (maxDimension >> level);
         if (static_cast<int>(width) > maxLevelDimension || static_cast<int>(height) > maxLevelDimension)
         {
-            return gl::error(GL_INVALID_VALUE, false);
+            context->recordError(Error(GL_INVALID_VALUE));
+            return false;
         }
     }
 
@@ -1301,7 +1401,7 @@
     return true;
 }
 
-static bool ValidateDrawBase(const gl::State &state, GLenum mode, GLsizei count)
+static bool ValidateDrawBase(Context *context, GLenum mode, GLsizei count, GLsizei maxVertex, GLsizei primcount)
 {
     switch (mode)
     {
@@ -1314,18 +1414,23 @@
       case GL_TRIANGLE_FAN:
         break;
       default:
-        return gl::error(GL_INVALID_ENUM, false);
+        context->recordError(Error(GL_INVALID_ENUM));
+        return false;
     }
 
     if (count < 0)
     {
-        return gl::error(GL_INVALID_VALUE, false);
+        context->recordError(Error(GL_INVALID_VALUE));
+        return false;
     }
 
+    const State &state = context->getState();
+
     // Check for mapped buffers
     if (state.hasMappedBuffer(GL_ARRAY_BUFFER))
     {
-        return gl::error(GL_INVALID_OPERATION, false);
+        context->recordError(Error(GL_INVALID_OPERATION));
+        return false;
     }
 
     const gl::DepthStencilState &depthStencilState = state.getDepthStencilState();
@@ -1337,35 +1442,85 @@
         // See Section 6.10 of the WebGL 1.0 spec
         ERR("This ANGLE implementation does not support separate front/back stencil "
             "writemasks, reference values, or stencil mask values.");
-        return gl::error(GL_INVALID_OPERATION, false);
+        context->recordError(Error(GL_INVALID_OPERATION));
+        return false;
     }
 
     const gl::Framebuffer *fbo = state.getDrawFramebuffer();
     if (!fbo || fbo->completeness() != GL_FRAMEBUFFER_COMPLETE)
     {
-        return gl::error(GL_INVALID_FRAMEBUFFER_OPERATION, false);
+        context->recordError(Error(GL_INVALID_FRAMEBUFFER_OPERATION));
+        return false;
     }
 
     if (state.getCurrentProgramId() == 0)
     {
-        return gl::error(GL_INVALID_OPERATION, false);
+        context->recordError(Error(GL_INVALID_OPERATION));
+        return false;
     }
 
     gl::ProgramBinary *programBinary = state.getCurrentProgramBinary();
-    if (!programBinary->validateSamplers(NULL))
+    if (!programBinary->validateSamplers(NULL, context->getCaps()))
     {
-        return gl::error(GL_INVALID_OPERATION, false);
+        context->recordError(Error(GL_INVALID_OPERATION));
+        return false;
+    }
+
+    // Buffer validations
+    const VertexArray *vao = state.getVertexArray();
+    for (int attributeIndex = 0; attributeIndex < MAX_VERTEX_ATTRIBS; attributeIndex++)
+    {
+        const VertexAttribute &attrib = vao->getVertexAttribute(attributeIndex);
+        bool attribActive = (programBinary->getSemanticIndex(attributeIndex) != -1);
+        if (attribActive && attrib.enabled)
+        {
+            gl::Buffer *buffer = attrib.buffer.get();
+
+            if (buffer)
+            {
+                GLint64 attribStride = static_cast<GLint64>(ComputeVertexAttributeStride(attrib));
+                GLint64 maxVertexElement = 0;
+
+                if (attrib.divisor > 0)
+                {
+                    maxVertexElement = static_cast<GLint64>(primcount) / static_cast<GLint64>(attrib.divisor);
+                }
+                else
+                {
+                    maxVertexElement = static_cast<GLint64>(maxVertex);
+                }
+
+                GLint64 attribDataSize = maxVertexElement * attribStride;
+
+                // [OpenGL ES 3.0.2] section 2.9.4 page 40:
+                // We can return INVALID_OPERATION if our vertex attribute does not have
+                // enough backing data.
+                if (attribDataSize > buffer->getSize())
+                {
+                    context->recordError(Error(GL_INVALID_OPERATION));
+                    return false;
+                }
+            }
+            else if (attrib.pointer == NULL)
+            {
+                // This is an application error that would normally result in a crash,
+                // but we catch it and return an error
+                context->recordError(Error(GL_INVALID_OPERATION, "An enabled vertex array has no buffer and no pointer."));
+                return false;
+            }
+        }
     }
 
     // No-op if zero count
     return (count > 0);
 }
 
-bool ValidateDrawArrays(const gl::Context *context, GLenum mode, GLint first, GLsizei count)
+bool ValidateDrawArrays(Context *context, GLenum mode, GLint first, GLsizei count, GLsizei primcount)
 {
     if (first < 0)
     {
-        return gl::error(GL_INVALID_VALUE, false);
+        context->recordError(Error(GL_INVALID_VALUE));
+        return false;
     }
 
     const State &state = context->getState();
@@ -1376,10 +1531,11 @@
         // It is an invalid operation to call DrawArrays or DrawArraysInstanced with a draw mode
         // that does not match the current transform feedback object's draw mode (if transform feedback
         // is active), (3.0.2, section 2.14, pg 86)
-        return gl::error(GL_INVALID_OPERATION, false);
+        context->recordError(Error(GL_INVALID_OPERATION));
+        return false;
     }
 
-    if (!ValidateDrawBase(state, mode, count))
+    if (!ValidateDrawBase(context, mode, count, count, primcount))
     {
         return false;
     }
@@ -1387,14 +1543,15 @@
     return true;
 }
 
-bool ValidateDrawArraysInstanced(const gl::Context *context, GLenum mode, GLint first, GLsizei count, GLsizei primcount)
+bool ValidateDrawArraysInstanced(Context *context, GLenum mode, GLint first, GLsizei count, GLsizei primcount)
 {
     if (primcount < 0)
     {
-        return gl::error(GL_INVALID_VALUE, false);
+        context->recordError(Error(GL_INVALID_VALUE));
+        return false;
     }
 
-    if (!ValidateDrawArrays(context, mode, first, count))
+    if (!ValidateDrawArrays(context, mode, first, count, primcount))
     {
         return false;
     }
@@ -1403,7 +1560,41 @@
     return (primcount > 0);
 }
 
-bool ValidateDrawElements(const gl::Context *context, GLenum mode, GLsizei count, GLenum type, const GLvoid* indices)
+static bool ValidateDrawInstancedANGLE(Context *context)
+{
+    // Verify there is at least one active attribute with a divisor of zero
+    const gl::State& state = context->getState();
+
+    gl::ProgramBinary *programBinary = state.getCurrentProgramBinary();
+
+    const VertexArray *vao = state.getVertexArray();
+    for (int attributeIndex = 0; attributeIndex < MAX_VERTEX_ATTRIBS; attributeIndex++)
+    {
+        const VertexAttribute &attrib = vao->getVertexAttribute(attributeIndex);
+        bool active = (programBinary->getSemanticIndex(attributeIndex) != -1);
+        if (active && attrib.divisor == 0)
+        {
+            return true;
+        }
+    }
+
+    context->recordError(Error(GL_INVALID_OPERATION, "ANGLE_instanced_arrays requires that at least one active attribute"
+                                                     "has a divisor of zero."));
+    return false;
+}
+
+bool ValidateDrawArraysInstancedANGLE(Context *context, GLenum mode, GLint first, GLsizei count, GLsizei primcount)
+{
+    if (!ValidateDrawInstancedANGLE(context))
+    {
+        return false;
+    }
+
+    return ValidateDrawArraysInstanced(context, mode, first, count, primcount);
+}
+
+bool ValidateDrawElements(Context *context, GLenum mode, GLsizei count, GLenum type,
+                          const GLvoid* indices, GLsizei primcount, rx::RangeUI *indexRangeOut)
 {
     switch (type)
     {
@@ -1413,11 +1604,13 @@
       case GL_UNSIGNED_INT:
         if (!context->getExtensions().elementIndexUint)
         {
-            return gl::error(GL_INVALID_ENUM, false);
+            context->recordError(Error(GL_INVALID_ENUM));
+            return false;
         }
         break;
       default:
-        return gl::error(GL_INVALID_ENUM, false);
+        context->recordError(Error(GL_INVALID_ENUM));
+        return false;
     }
 
     const State &state = context->getState();
@@ -1427,22 +1620,73 @@
     {
         // It is an invalid operation to call DrawElements, DrawRangeElements or DrawElementsInstanced
         // while transform feedback is active, (3.0.2, section 2.14, pg 86)
-        return gl::error(GL_INVALID_OPERATION, false);
+        context->recordError(Error(GL_INVALID_OPERATION));
+        return false;
     }
 
     // Check for mapped buffers
     if (state.hasMappedBuffer(GL_ELEMENT_ARRAY_BUFFER))
     {
-        return gl::error(GL_INVALID_OPERATION, false);
+        context->recordError(Error(GL_INVALID_OPERATION));
+        return false;
     }
 
-    gl::VertexArray *vao = state.getVertexArray();
-    if (!indices && !vao->getElementArrayBuffer())
+    const gl::VertexArray *vao = state.getVertexArray();
+    const gl::Buffer *elementArrayBuffer = vao->getElementArrayBuffer();
+    if (!indices && !elementArrayBuffer)
     {
-        return gl::error(GL_INVALID_OPERATION, false);
+        context->recordError(Error(GL_INVALID_OPERATION));
+        return false;
     }
 
-    if (!ValidateDrawBase(state, mode, count))
+    if (elementArrayBuffer)
+    {
+        const gl::Type &typeInfo = gl::GetTypeInfo(type);
+
+        GLint64 offset = reinterpret_cast<GLint64>(indices);
+        GLint64 byteCount = static_cast<GLint64>(typeInfo.bytes) * static_cast<GLint64>(count)+offset;
+
+        // check for integer overflows
+        if (static_cast<GLuint>(count) > (std::numeric_limits<GLuint>::max() / typeInfo.bytes) ||
+            byteCount > static_cast<GLint64>(std::numeric_limits<GLuint>::max()))
+        {
+            context->recordError(Error(GL_OUT_OF_MEMORY));
+            return false;
+        }
+
+        // Check for reading past the end of the bound buffer object
+        if (byteCount > elementArrayBuffer->getSize())
+        {
+            context->recordError(Error(GL_INVALID_OPERATION));
+            return false;
+        }
+    }
+    else if (!indices)
+    {
+        // Catch this programming error here
+        context->recordError(Error(GL_INVALID_OPERATION));
+        return false;
+    }
+
+    // Use max index to validate if our vertex buffers are large enough for the pull.
+    // TODO: offer fast path, with disabled index validation.
+    // TODO: also disable index checking on back-ends that are robust to out-of-range accesses.
+    if (elementArrayBuffer)
+    {
+        unsigned int offset = reinterpret_cast<unsigned int>(indices);
+        if (!elementArrayBuffer->getIndexRangeCache()->findRange(type, offset, count, indexRangeOut, NULL))
+        {
+            const void *dataPointer = elementArrayBuffer->getImplementation()->getData();
+            const uint8_t *offsetPointer = static_cast<const uint8_t *>(dataPointer) + offset;
+            *indexRangeOut = rx::IndexRangeCache::ComputeRange(type, offsetPointer, count);
+        }
+    }
+    else
+    {
+        *indexRangeOut = rx::IndexRangeCache::ComputeRange(type, indices, count);
+    }
+
+    if (!ValidateDrawBase(context, mode, count, static_cast<GLsizei>(indexRangeOut->end), primcount))
     {
         return false;
     }
@@ -1450,15 +1694,18 @@
     return true;
 }
 
-bool ValidateDrawElementsInstanced(const gl::Context *context, GLenum mode, GLsizei count, GLenum type,
-                                   const GLvoid *indices, GLsizei primcount)
+bool ValidateDrawElementsInstanced(Context *context,
+                                   GLenum mode, GLsizei count, GLenum type,
+                                   const GLvoid *indices, GLsizei primcount,
+                                   rx::RangeUI *indexRangeOut)
 {
     if (primcount < 0)
     {
-        return gl::error(GL_INVALID_VALUE, false);
+        context->recordError(Error(GL_INVALID_VALUE));
+        return false;
     }
 
-    if (!ValidateDrawElements(context, mode, count, type, indices))
+    if (!ValidateDrawElements(context, mode, count, type, indices, primcount, indexRangeOut))
     {
         return false;
     }
@@ -1467,12 +1714,24 @@
     return (primcount > 0);
 }
 
-bool ValidateFramebufferTextureBase(const gl::Context *context, GLenum target, GLenum attachment,
+bool ValidateDrawElementsInstancedANGLE(Context *context, GLenum mode, GLsizei count, GLenum type,
+                                        const GLvoid *indices, GLsizei primcount, rx::RangeUI *indexRangeOut)
+{
+    if (!ValidateDrawInstancedANGLE(context))
+    {
+        return false;
+    }
+
+    return ValidateDrawElementsInstanced(context, mode, count, type, indices, primcount, indexRangeOut);
+}
+
+bool ValidateFramebufferTextureBase(Context *context, GLenum target, GLenum attachment,
                                     GLuint texture, GLint level)
 {
     if (!ValidFramebufferTarget(target))
     {
-        return gl::error(GL_INVALID_ENUM, false);
+        context->recordError(Error(GL_INVALID_ENUM));
+        return false;
     }
 
     if (!ValidateAttachmentTarget(context, attachment))
@@ -1486,12 +1745,14 @@
 
         if (tex == NULL)
         {
-            return gl::error(GL_INVALID_OPERATION, false);
+            context->recordError(Error(GL_INVALID_OPERATION));
+            return false;
         }
 
         if (level < 0)
         {
-            return gl::error(GL_INVALID_VALUE, false);
+            context->recordError(Error(GL_INVALID_VALUE));
+            return false;
         }
     }
 
@@ -1500,19 +1761,21 @@
 
     if (framebufferHandle == 0 || !framebuffer)
     {
-        return gl::error(GL_INVALID_OPERATION, false);
+        context->recordError(Error(GL_INVALID_OPERATION));
+        return false;
     }
 
     return true;
 }
 
-bool ValidateFramebufferTexture2D(const gl::Context *context, GLenum target, GLenum attachment,
+bool ValidateFramebufferTexture2D(Context *context, GLenum target, GLenum attachment,
                                   GLenum textarget, GLuint texture, GLint level)
 {
     // Attachments are required to be bound to level 0 in ES2
     if (context->getClientVersion() < 3 && level != 0)
     {
-        return gl::error(GL_INVALID_VALUE, false);
+        context->recordError(Error(GL_INVALID_VALUE));
+        return false;
     }
 
     if (!ValidateFramebufferTextureBase(context, target, attachment, texture, level))
@@ -1533,16 +1796,19 @@
             {
                 if (level > gl::log2(caps.max2DTextureSize))
                 {
-                    return gl::error(GL_INVALID_VALUE, false);
+                    context->recordError(Error(GL_INVALID_VALUE));
+                    return false;
                 }
                 if (tex->getTarget() != GL_TEXTURE_2D)
                 {
-                    return gl::error(GL_INVALID_OPERATION, false);
+                    context->recordError(Error(GL_INVALID_OPERATION));
+                    return false;
                 }
                 gl::Texture2D *tex2d = static_cast<gl::Texture2D *>(tex);
                 if (tex2d->isCompressed(level))
                 {
-                    return gl::error(GL_INVALID_OPERATION, false);
+                    context->recordError(Error(GL_INVALID_OPERATION));
+                    return false;
                 }
             }
             break;
@@ -1556,26 +1822,105 @@
             {
                 if (level > gl::log2(caps.maxCubeMapTextureSize))
                 {
-                    return gl::error(GL_INVALID_VALUE, false);
+                    context->recordError(Error(GL_INVALID_VALUE));
+                    return false;
                 }
                 if (tex->getTarget() != GL_TEXTURE_CUBE_MAP)
                 {
-                    return gl::error(GL_INVALID_OPERATION, false);
+                    context->recordError(Error(GL_INVALID_OPERATION));
+                    return false;
                 }
                 gl::TextureCubeMap *texcube = static_cast<gl::TextureCubeMap *>(tex);
                 if (texcube->isCompressed(textarget, level))
                 {
-                    return gl::error(GL_INVALID_OPERATION, false);
+                    context->recordError(Error(GL_INVALID_OPERATION));
+                    return false;
                 }
             }
             break;
 
           default:
-            return gl::error(GL_INVALID_ENUM, false);
+            context->recordError(Error(GL_INVALID_ENUM));
+            return false;
         }
     }
 
     return true;
 }
 
+bool ValidateGetUniformBase(Context *context, GLuint program, GLint location)
+{
+    if (program == 0)
+    {
+        context->recordError(Error(GL_INVALID_VALUE));
+        return false;
+    }
+
+    gl::Program *programObject = context->getProgram(program);
+
+    if (!programObject || !programObject->isLinked())
+    {
+        context->recordError(Error(GL_INVALID_OPERATION));
+        return false;
+    }
+
+    gl::ProgramBinary *programBinary = programObject->getProgramBinary();
+    if (!programBinary)
+    {
+        context->recordError(Error(GL_INVALID_OPERATION));
+        return false;
+    }
+
+    if (!programBinary->isValidUniformLocation(location))
+    {
+        context->recordError(Error(GL_INVALID_OPERATION));
+        return false;
+    }
+
+    return true;
+}
+
+bool ValidateGetUniformfv(Context *context, GLuint program, GLint location, GLfloat* params)
+{
+    return ValidateGetUniformBase(context, program, location);
+}
+
+bool ValidateGetUniformiv(Context *context, GLuint program, GLint location, GLint* params)
+{
+    return ValidateGetUniformBase(context, program, location);
+}
+
+static bool ValidateSizedGetUniform(Context *context, GLuint program, GLint location, GLsizei bufSize)
+{
+    if (!ValidateGetUniformBase(context, program, location))
+    {
+        return false;
+    }
+
+    gl::Program *programObject = context->getProgram(program);
+    ASSERT(programObject);
+    gl::ProgramBinary *programBinary = programObject->getProgramBinary();
+
+    // sized queries -- ensure the provided buffer is large enough
+    LinkedUniform *uniform = programBinary->getUniformByLocation(location);
+    size_t requiredBytes = VariableExternalSize(uniform->type);
+    if (static_cast<size_t>(bufSize) < requiredBytes)
+    {
+        context->recordError(Error(GL_INVALID_OPERATION));
+        return false;
+    }
+
+    return true;
+}
+
+bool ValidateGetnUniformfvEXT(Context *context, GLuint program, GLint location, GLsizei bufSize, GLfloat* params)
+{
+    return ValidateSizedGetUniform(context, program, location, bufSize);
+}
+
+bool ValidateGetnUniformivEXT(Context *context, GLuint program, GLint location, GLsizei bufSize, GLint* params)
+{
+    return ValidateSizedGetUniform(context, program, location, bufSize);
+}
+
 }
diff --git a/src/libGLESv2/validationES.h b/src/libGLESv2/validationES.h
index 849df36..1fdb633 100644
--- a/src/libGLESv2/validationES.h
+++ b/src/libGLESv2/validationES.h
@@ -9,6 +9,11 @@
 #ifndef LIBGLESV2_VALIDATION_ES_H
 #define LIBGLESV2_VALIDATION_ES_H
 
+#include "common/mathutil.h"
+
+#include <GLES2/gl2.h>
+#include <GLES3/gl3.h>
+
 namespace gl
 {
 
@@ -21,55 +26,67 @@
 bool ValidBufferTarget(const Context *context, GLenum target);
 bool ValidBufferParameter(const Context *context, GLenum pname);
 bool ValidMipLevel(const Context *context, GLenum target, GLint level);
-bool ValidImageSize(const gl::Context *context, GLenum target, GLint level, GLsizei width, GLsizei height, GLsizei depth);
-bool ValidCompressedImageSize(const gl::Context *context, GLenum internalFormat, GLsizei width, GLsizei height);
-bool ValidQueryType(const gl::Context *context, GLenum queryType);
-bool ValidProgram(const gl::Context *context, GLuint id);
+bool ValidImageSize(const Context *context, GLenum target, GLint level, GLsizei width, GLsizei height, GLsizei depth);
+bool ValidCompressedImageSize(const Context *context, GLenum internalFormat, GLsizei width, GLsizei height);
+bool ValidQueryType(const Context *context, GLenum queryType);
+bool ValidProgram(Context *context, GLuint id);
 
-bool ValidateAttachmentTarget(const gl::Context *context, GLenum attachment);
-bool ValidateRenderbufferStorageParameters(const gl::Context *context, GLenum target, GLsizei samples,
+bool ValidateAttachmentTarget(Context *context, GLenum attachment);
+bool ValidateRenderbufferStorageParameters(Context *context, GLenum target, GLsizei samples,
                                            GLenum internalformat, GLsizei width, GLsizei height,
                                            bool angleExtension);
-bool ValidateFramebufferRenderbufferParameters(gl::Context *context, GLenum target, GLenum attachment,
+bool ValidateFramebufferRenderbufferParameters(Context *context, GLenum target, GLenum attachment,
                                                GLenum renderbuffertarget, GLuint renderbuffer);
 
-bool ValidateBlitFramebufferParameters(gl::Context *context, GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1,
+bool ValidateBlitFramebufferParameters(Context *context, GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1,
                                        GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask,
                                        GLenum filter, bool fromAngleExtension);
 
-bool ValidateGetVertexAttribParameters(GLenum pname, int clientVersion);
+bool ValidateGetVertexAttribParameters(Context *context, GLenum pname);
 
-bool ValidateTexParamParameters(gl::Context *context, GLenum pname, GLint param);
+bool ValidateTexParamParameters(Context *context, GLenum pname, GLint param);
 
-bool ValidateSamplerObjectParameter(GLenum pname);
+bool ValidateSamplerObjectParameter(Context *context, GLenum pname);
 
-bool ValidateReadPixelsParameters(gl::Context *context, GLint x, GLint y, GLsizei width, GLsizei height,
+bool ValidateReadPixelsParameters(Context *context, GLint x, GLint y, GLsizei width, GLsizei height,
                                   GLenum format, GLenum type, GLsizei *bufSize, GLvoid *pixels);
 
-bool ValidateBeginQuery(gl::Context *context, GLenum target, GLuint id);
-bool ValidateEndQuery(gl::Context *context, GLenum target);
+bool ValidateBeginQuery(Context *context, GLenum target, GLuint id);
+bool ValidateEndQuery(Context *context, GLenum target);
 
-bool ValidateUniform(gl::Context *context, GLenum uniformType, GLint location, GLsizei count);
-bool ValidateUniformMatrix(gl::Context *context, GLenum matrixType, GLint location, GLsizei count,
+bool ValidateUniform(Context *context, GLenum uniformType, GLint location, GLsizei count);
+bool ValidateUniformMatrix(Context *context, GLenum matrixType, GLint location, GLsizei count,
                            GLboolean transpose);
 
-bool ValidateStateQuery(gl::Context *context, GLenum pname, GLenum *nativeType, unsigned int *numParams);
+bool ValidateStateQuery(Context *context, GLenum pname, GLenum *nativeType, unsigned int *numParams);
 
-bool ValidateCopyTexImageParametersBase(gl::Context* context, GLenum target, GLint level, GLenum internalformat, bool isSubImage,
+bool ValidateCopyTexImageParametersBase(Context* context, GLenum target, GLint level, GLenum internalformat, bool isSubImage,
                                         GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height,
                                         GLint border, GLenum *textureInternalFormatOut);
 
-bool ValidateDrawArrays(const gl::Context *context, GLenum mode, GLint first, GLsizei count);
-bool ValidateDrawArraysInstanced(const gl::Context *context, GLenum mode, GLint first, GLsizei count, GLsizei primcount);
-bool ValidateDrawElements(const gl::Context *context, GLenum mode, GLsizei count, GLenum type, const GLvoid* indices);
-bool ValidateDrawElementsInstanced(const gl::Context *context, GLenum mode, GLsizei count, GLenum type,
-                                   const GLvoid *indices, GLsizei primcount);
+bool ValidateDrawArrays(Context *context, GLenum mode, GLint first, GLsizei count, GLsizei primcount);
+bool ValidateDrawArraysInstanced(Context *context, GLenum mode, GLint first, GLsizei count, GLsizei primcount);
+bool ValidateDrawArraysInstancedANGLE(Context *context, GLenum mode, GLint first, GLsizei count, GLsizei primcount);
 
-bool ValidateFramebufferTextureBase(const gl::Context *context, GLenum target, GLenum attachment,
+bool ValidateDrawElements(Context *context, GLenum mode, GLsizei count, GLenum type,
+                          const GLvoid* indices, GLsizei primcount, rx::RangeUI *indexRangeOut);
+
+bool ValidateDrawElementsInstanced(Context *context, GLenum mode, GLsizei count, GLenum type,
+                                   const GLvoid *indices, GLsizei primcount, rx::RangeUI *indexRangeOut);
+bool ValidateDrawElementsInstancedANGLE(Context *context, GLenum mode, GLsizei count, GLenum type,
+                                        const GLvoid *indices, GLsizei primcount, rx::RangeUI *indexRangeOut);
+
+bool ValidateFramebufferTextureBase(Context *context, GLenum target, GLenum attachment,
                                     GLuint texture, GLint level);
-bool ValidateFramebufferTexture2D(const gl::Context *context, GLenum target, GLenum attachment,
+bool ValidateFramebufferTexture2D(Context *context, GLenum target, GLenum attachment,
                                   GLenum textarget, GLuint texture, GLint level);
 
+bool ValidateGetUniformBase(Context *context, GLuint program, GLint location);
+bool ValidateGetUniformfv(Context *context, GLuint program, GLint location, GLfloat* params);
+bool ValidateGetUniformiv(Context *context, GLuint program, GLint location, GLint* params);
+bool ValidateGetnUniformfvEXT(Context *context, GLuint program, GLint location, GLsizei bufSize, GLfloat* params);
+bool ValidateGetnUniformivEXT(Context *context, GLuint program, GLint location, GLsizei bufSize, GLint* params);
+
 }
 
 #endif // LIBGLESV2_VALIDATION_ES_H
diff --git a/src/libGLESv2/validationES2.cpp b/src/libGLESv2/validationES2.cpp
index 59067f5..f950454 100644
--- a/src/libGLESv2/validationES2.cpp
+++ b/src/libGLESv2/validationES2.cpp
@@ -1,4 +1,3 @@
-#include "precompiled.h"
 //
 // Copyright (c) 2013-2014 The ANGLE Project Authors. All rights reserved.
 // Use of this source code is governed by a BSD-style license that can be
@@ -23,25 +22,28 @@
 namespace gl
 {
 
-static bool validateSubImageParams2D(bool compressed, GLsizei width, GLsizei height,
+static bool ValidateSubImageParams2D(Context *context, bool compressed, GLsizei width, GLsizei height,
                                      GLint xoffset, GLint yoffset, GLint level, GLenum format, GLenum type,
                                      gl::Texture2D *texture)
 {
     if (!texture)
     {
-        return gl::error(GL_INVALID_OPERATION, false);
+        context->recordError(Error(GL_INVALID_OPERATION));
+        return false;
     }
 
     if (compressed != texture->isCompressed(level))
     {
-        return gl::error(GL_INVALID_OPERATION, false);
+        context->recordError(Error(GL_INVALID_OPERATION));
+        return false;
     }
 
     if (format != GL_NONE)
     {
         if (gl::GetFormatTypeInfo(format, type).internalFormat != texture->getInternalFormat(level))
         {
-            return gl::error(GL_INVALID_OPERATION, false);
+            context->recordError(Error(GL_INVALID_OPERATION));
+            return false;
         }
     }
 
@@ -50,38 +52,43 @@
         if ((width % 4 != 0 && width != texture->getWidth(level)) ||
             (height % 4 != 0 && height != texture->getHeight(level)))
         {
-            return gl::error(GL_INVALID_OPERATION, false);
+            context->recordError(Error(GL_INVALID_OPERATION));
+            return false;
         }
     }
 
     if (xoffset + width > texture->getWidth(level) ||
         yoffset + height > texture->getHeight(level))
     {
-        return gl::error(GL_INVALID_VALUE, false);
+        context->recordError(Error(GL_INVALID_VALUE));
+        return false;
     }
 
     return true;
 }
 
-static bool validateSubImageParamsCube(bool compressed, GLsizei width, GLsizei height,
+static bool ValidateSubImageParamsCube(Context *context, bool compressed, GLsizei width, GLsizei height,
                                        GLint xoffset, GLint yoffset, GLenum target, GLint level, GLenum format, GLenum type,
                                        gl::TextureCubeMap *texture)
 {
     if (!texture)
     {
-        return gl::error(GL_INVALID_OPERATION, false);
+        context->recordError(Error(GL_INVALID_OPERATION));
+        return false;
     }
 
     if (compressed != texture->isCompressed(target, level))
     {
-        return gl::error(GL_INVALID_OPERATION, false);
+        context->recordError(Error(GL_INVALID_OPERATION));
+        return false;
     }
 
     if (format != GL_NONE)
     {
         if (gl::GetFormatTypeInfo(format, type).internalFormat != texture->getInternalFormat(target, level))
         {
-            return gl::error(GL_INVALID_OPERATION, false);
+            context->recordError(Error(GL_INVALID_OPERATION));
+            return false;
         }
     }
 
@@ -90,43 +97,49 @@
         if ((width % 4 != 0 && width != texture->getWidth(target, 0)) ||
             (height % 4 != 0 && height != texture->getHeight(target, 0)))
         {
-            return gl::error(GL_INVALID_OPERATION, false);
+            context->recordError(Error(GL_INVALID_OPERATION));
+            return false;
         }
     }
 
     if (xoffset + width > texture->getWidth(target, level) ||
         yoffset + height > texture->getHeight(target, level))
     {
-        return gl::error(GL_INVALID_VALUE, false);
+        context->recordError(Error(GL_INVALID_VALUE));
+        return false;
     }
 
     return true;
 }
 
-bool ValidateES2TexImageParameters(gl::Context *context, GLenum target, GLint level, GLenum internalformat, bool isCompressed, bool isSubImage,
+bool ValidateES2TexImageParameters(Context *context, GLenum target, GLint level, GLenum internalformat, bool isCompressed, bool isSubImage,
                                    GLint xoffset, GLint yoffset, GLsizei width, GLsizei height,
                                    GLint border, GLenum format, GLenum type, const GLvoid *pixels)
 {
     if (!ValidTexture2DDestinationTarget(context, target))
     {
-        return gl::error(GL_INVALID_ENUM, false);
+        context->recordError(Error(GL_INVALID_ENUM));
+        return false;
     }
 
     if (!ValidImageSize(context, target, level, width, height, 1))
     {
-        return gl::error(GL_INVALID_VALUE, false);
+        context->recordError(Error(GL_INVALID_VALUE));
+        return false;
     }
 
     if (level < 0 || xoffset < 0 ||
         std::numeric_limits<GLsizei>::max() - xoffset < width ||
         std::numeric_limits<GLsizei>::max() - yoffset < height)
     {
-        return gl::error(GL_INVALID_VALUE, false);
+        context->recordError(Error(GL_INVALID_VALUE));
+        return false;
     }
 
     if (!isSubImage && !isCompressed && internalformat != format)
     {
-        return gl::error(GL_INVALID_OPERATION, false);
+        context->recordError(Error(GL_INVALID_OPERATION));
+        return false;
     }
 
     const gl::Caps &caps = context->getCaps();
@@ -143,7 +156,8 @@
             if (static_cast<GLuint>(width) > (caps.max2DTextureSize >> level) ||
                 static_cast<GLuint>(height) > (caps.max2DTextureSize >> level))
             {
-                return gl::error(GL_INVALID_VALUE, false);
+                context->recordError(Error(GL_INVALID_VALUE));
+                return false;
             }
 
             gl::Texture2D *tex2d = context->getTexture2D();
@@ -156,7 +170,7 @@
                 texture = tex2d;
             }
 
-            if (isSubImage && !validateSubImageParams2D(isCompressed, width, height, xoffset, yoffset,
+            if (isSubImage && !ValidateSubImageParams2D(context, isCompressed, width, height, xoffset, yoffset,
                                                         level, format, type, tex2d))
             {
                 return false;
@@ -175,13 +189,15 @@
         {
             if (!isSubImage && width != height)
             {
-                return gl::error(GL_INVALID_VALUE, false);
+                context->recordError(Error(GL_INVALID_VALUE));
+                return false;
             }
 
             if (static_cast<GLuint>(width) > (caps.maxCubeMapTextureSize >> level) ||
                 static_cast<GLuint>(height) > (caps.maxCubeMapTextureSize >> level))
             {
-                return gl::error(GL_INVALID_VALUE, false);
+                context->recordError(Error(GL_INVALID_VALUE));
+                return false;
             }
 
             gl::TextureCubeMap *texCube = context->getTextureCubeMap();
@@ -194,7 +210,7 @@
                 texture = texCube;
             }
 
-            if (isSubImage && !validateSubImageParamsCube(isCompressed, width, height, xoffset, yoffset,
+            if (isSubImage && !ValidateSubImageParamsCube(context, isCompressed, width, height, xoffset, yoffset,
                                                           target, level, format, type, texCube))
             {
                 return false;
@@ -203,23 +219,27 @@
         break;
 
       default:
-        return gl::error(GL_INVALID_ENUM, false);
+        context->recordError(Error(GL_INVALID_ENUM));
+        return false;
     }
 
     if (!texture)
     {
-        return gl::error(GL_INVALID_OPERATION, false);
+        context->recordError(Error(GL_INVALID_OPERATION));
+        return false;
     }
 
     if (!isSubImage && texture->isImmutable())
     {
-        return gl::error(GL_INVALID_OPERATION, false);
+        context->recordError(Error(GL_INVALID_OPERATION));
+        return false;
     }
 
     // Verify zero border
     if (border != 0)
     {
-        return gl::error(GL_INVALID_VALUE, false);
+        context->recordError(Error(GL_INVALID_VALUE));
+        return false;
     }
 
     GLenum actualInternalFormat = isSubImage ? textureInternalFormat : internalformat;
@@ -227,7 +247,8 @@
     {
         if (!ValidCompressedImageSize(context, actualInternalFormat, width, height))
         {
-            return gl::error(GL_INVALID_OPERATION, false);
+            context->recordError(Error(GL_INVALID_OPERATION));
+            return false;
         }
 
         switch (actualInternalFormat)
@@ -236,23 +257,27 @@
           case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
             if (!context->getExtensions().textureCompressionDXT1)
             {
-                return gl::error(GL_INVALID_ENUM, false);
+                context->recordError(Error(GL_INVALID_ENUM));
+                return false;
             }
             break;
           case GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE:
             if (!context->getExtensions().textureCompressionDXT1)
             {
-                return gl::error(GL_INVALID_ENUM, false);
+                context->recordError(Error(GL_INVALID_ENUM));
+                return false;
             }
             break;
           case GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE:
-              if (!context->getExtensions().textureCompressionDXT5)
+            if (!context->getExtensions().textureCompressionDXT5)
             {
-                return gl::error(GL_INVALID_ENUM, false);
+                context->recordError(Error(GL_INVALID_ENUM));
+                return false;
             }
             break;
           default:
-            return gl::error(GL_INVALID_ENUM, false);
+            context->recordError(Error(GL_INVALID_ENUM));
+            return false;
         }
     }
     else
@@ -271,7 +296,8 @@
           case GL_FLOAT:
             break;
           default:
-            return gl::error(GL_INVALID_ENUM, false);
+            context->recordError(Error(GL_INVALID_ENUM));
+            return false;
         }
 
         // validate <format> + <type> combinations
@@ -288,15 +314,17 @@
               case GL_FLOAT:
               case GL_HALF_FLOAT_OES:
                 break;
-            default:
-                return gl::error(GL_INVALID_OPERATION, false);
+              default:
+                  context->recordError(Error(GL_INVALID_OPERATION));
+                  return false;
             }
             break;
           case GL_RED:
           case GL_RG:
               if (!context->getExtensions().textureRG)
               {
-                  return gl::error(GL_INVALID_ENUM, false);
+                  context->recordError(Error(GL_INVALID_ENUM));
+                  return false;
               }
               switch (type)
               {
@@ -305,7 +333,8 @@
                 case GL_HALF_FLOAT_OES:
                   break;
                 default:
-                  return gl::error(GL_INVALID_OPERATION, false);
+                  context->recordError(Error(GL_INVALID_OPERATION));
+                  return false;
               }
               break;
           case GL_RGB:
@@ -317,7 +346,8 @@
               case GL_HALF_FLOAT_OES:
                 break;
               default:
-                return gl::error(GL_INVALID_OPERATION, false);
+                context->recordError(Error(GL_INVALID_OPERATION));
+                return false;
             }
             break;
           case GL_RGBA:
@@ -330,7 +360,8 @@
               case GL_HALF_FLOAT_OES:
                 break;
               default:
-                return gl::error(GL_INVALID_OPERATION, false);
+                context->recordError(Error(GL_INVALID_OPERATION));
+                return false;
             }
             break;
           case GL_BGRA_EXT:
@@ -339,21 +370,24 @@
               case GL_UNSIGNED_BYTE:
                 break;
               default:
-                return gl::error(GL_INVALID_OPERATION, false);
+                context->recordError(Error(GL_INVALID_OPERATION));
+                return false;
             }
             break;
           case GL_SRGB_EXT:
           case GL_SRGB_ALPHA_EXT:
             if (!context->getExtensions().sRGB)
             {
-                return gl::error(GL_INVALID_ENUM, false);
+                context->recordError(Error(GL_INVALID_ENUM));
+                return false;
             }
             switch (type)
             {
               case GL_UNSIGNED_BYTE:
                 break;
               default:
-                return gl::error(GL_INVALID_OPERATION, false);
+                context->recordError(Error(GL_INVALID_OPERATION));
+                return false;
             }
             break;
           case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:  // error cases for compressed textures are handled below
@@ -368,7 +402,8 @@
               case GL_UNSIGNED_INT:
                 break;
               default:
-                return gl::error(GL_INVALID_OPERATION, false);
+                context->recordError(Error(GL_INVALID_OPERATION));
+                return false;
             }
             break;
           case GL_DEPTH_STENCIL_OES:
@@ -377,11 +412,13 @@
               case GL_UNSIGNED_INT_24_8_OES:
                 break;
               default:
-                return gl::error(GL_INVALID_OPERATION, false);
+                context->recordError(Error(GL_INVALID_OPERATION));
+                return false;
             }
             break;
           default:
-            return gl::error(GL_INVALID_ENUM, false);
+            context->recordError(Error(GL_INVALID_ENUM));
+            return false;
         }
 
         switch (format)
@@ -390,48 +427,57 @@
           case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
             if (context->getExtensions().textureCompressionDXT1)
             {
-                return gl::error(GL_INVALID_OPERATION, false);
+                context->recordError(Error(GL_INVALID_OPERATION));
+                return false;
             }
             else
             {
-                return gl::error(GL_INVALID_ENUM, false);
+                context->recordError(Error(GL_INVALID_ENUM));
+                return false;
             }
             break;
           case GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE:
             if (context->getExtensions().textureCompressionDXT3)
             {
-                return gl::error(GL_INVALID_OPERATION, false);
+                context->recordError(Error(GL_INVALID_OPERATION));
+                return false;
             }
             else
             {
-                return gl::error(GL_INVALID_ENUM, false);
+                context->recordError(Error(GL_INVALID_ENUM));
+                return false;
             }
             break;
           case GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE:
             if (context->getExtensions().textureCompressionDXT5)
             {
-                return gl::error(GL_INVALID_OPERATION, false);
+                context->recordError(Error(GL_INVALID_OPERATION));
+                return false;
             }
             else
             {
-                return gl::error(GL_INVALID_ENUM, false);
+                context->recordError(Error(GL_INVALID_ENUM));
+                return false;
             }
             break;
           case GL_DEPTH_COMPONENT:
           case GL_DEPTH_STENCIL_OES:
             if (!context->getExtensions().depthTextures)
             {
-                return gl::error(GL_INVALID_VALUE, false);
+                context->recordError(Error(GL_INVALID_VALUE));
+                return false;
             }
             if (target != GL_TEXTURE_2D)
             {
-                return gl::error(GL_INVALID_OPERATION, false);
+                context->recordError(Error(GL_INVALID_OPERATION));
+                return false;
             }
             // OES_depth_texture supports loading depth data and multiple levels,
             // but ANGLE_depth_texture does not
             if (pixels != NULL || level != 0)
             {
-                return gl::error(GL_INVALID_OPERATION, false);
+                context->recordError(Error(GL_INVALID_OPERATION));
+                return false;
             }
             break;
           default:
@@ -442,14 +488,16 @@
         {
             if (!context->getExtensions().textureFloat)
             {
-                return gl::error(GL_INVALID_ENUM, false);
+                context->recordError(Error(GL_INVALID_ENUM));
+                return false;
             }
         }
         else if (type == GL_HALF_FLOAT_OES)
         {
             if (!context->getExtensions().textureHalfFloat)
             {
-                return gl::error(GL_INVALID_ENUM, false);
+                context->recordError(Error(GL_INVALID_ENUM));
+                return false;
             }
         }
     }
@@ -459,7 +507,7 @@
 
 
 
-bool ValidateES2CopyTexImageParameters(gl::Context* context, GLenum target, GLint level, GLenum internalformat, bool isSubImage,
+bool ValidateES2CopyTexImageParameters(Context* context, GLenum target, GLint level, GLenum internalformat, bool isSubImage,
                                        GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height,
                                        GLint border)
 {
@@ -486,7 +534,8 @@
                 colorbufferFormat != GL_RGB5_A1 &&
                 colorbufferFormat != GL_RGBA8_OES)
             {
-                return gl::error(GL_INVALID_OPERATION, false);
+                context->recordError(Error(GL_INVALID_OPERATION));
+                return false;
             }
             break;
           case GL_LUMINANCE:
@@ -498,7 +547,8 @@
                   colorbufferFormat != GL_RGB5_A1 &&
                   colorbufferFormat != GL_RGBA8_OES)
               {
-                  return gl::error(GL_INVALID_OPERATION, false);
+                  context->recordError(Error(GL_INVALID_OPERATION));
+                  return false;
               }
               break;
           case GL_RED_EXT:
@@ -510,7 +560,8 @@
                   colorbufferFormat != GL_RGB5_A1 &&
                   colorbufferFormat != GL_RGBA8_OES)
               {
-                  return gl::error(GL_INVALID_OPERATION, false);
+                  context->recordError(Error(GL_INVALID_OPERATION));
+                  return false;
               }
               break;
           case GL_RG_EXT:
@@ -521,7 +572,8 @@
                   colorbufferFormat != GL_RGB5_A1 &&
                   colorbufferFormat != GL_RGBA8_OES)
               {
-                  return gl::error(GL_INVALID_OPERATION, false);
+                  context->recordError(Error(GL_INVALID_OPERATION));
+                  return false;
               }
               break;
           case GL_RGB:
@@ -531,7 +583,8 @@
                 colorbufferFormat != GL_RGB5_A1 &&
                 colorbufferFormat != GL_RGBA8_OES)
             {
-                return gl::error(GL_INVALID_OPERATION, false);
+                context->recordError(Error(GL_INVALID_OPERATION));
+                return false;
             }
             break;
           case GL_LUMINANCE_ALPHA:
@@ -540,19 +593,23 @@
                 colorbufferFormat != GL_RGB5_A1 &&
                 colorbufferFormat != GL_RGBA8_OES)
             {
-                return gl::error(GL_INVALID_OPERATION, false);
+                context->recordError(Error(GL_INVALID_OPERATION));
+                return false;
             }
             break;
           case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
           case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
           case GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE:
           case GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE:
-            return gl::error(GL_INVALID_OPERATION, false);
+            context->recordError(Error(GL_INVALID_OPERATION));
+            return false;
           case GL_DEPTH_COMPONENT:
           case GL_DEPTH_STENCIL_OES:
-            return gl::error(GL_INVALID_OPERATION, false);
+            context->recordError(Error(GL_INVALID_OPERATION));
+            return false;
           default:
-            return gl::error(GL_INVALID_OPERATION, false);
+            context->recordError(Error(GL_INVALID_OPERATION));
+            return false;
         }
     }
     else
@@ -566,7 +623,8 @@
                 colorbufferFormat != GL_BGRA8_EXT &&
                 colorbufferFormat != GL_RGBA8_OES)
             {
-                return gl::error(GL_INVALID_OPERATION, false);
+                context->recordError(Error(GL_INVALID_OPERATION));
+                return false;
             }
             break;
           case GL_LUMINANCE:
@@ -579,7 +637,8 @@
                   colorbufferFormat != GL_BGRA8_EXT &&
                   colorbufferFormat != GL_RGBA8_OES)
               {
-                  return gl::error(GL_INVALID_OPERATION, false);
+                  context->recordError(Error(GL_INVALID_OPERATION));
+                  return false;
               }
               break;
           case GL_RED_EXT:
@@ -592,7 +651,8 @@
                   colorbufferFormat != GL_BGRA8_EXT &&
                   colorbufferFormat != GL_RGBA8_OES)
               {
-                  return gl::error(GL_INVALID_OPERATION, false);
+                  context->recordError(Error(GL_INVALID_OPERATION));
+                  return false;
               }
               break;
           case GL_RG_EXT:
@@ -604,7 +664,8 @@
                   colorbufferFormat != GL_BGRA8_EXT &&
                   colorbufferFormat != GL_RGBA8_OES)
               {
-                  return gl::error(GL_INVALID_OPERATION, false);
+                  context->recordError(Error(GL_INVALID_OPERATION));
+                  return false;
               }
               break;
           case GL_RGB:
@@ -615,7 +676,8 @@
                 colorbufferFormat != GL_BGRA8_EXT &&
                 colorbufferFormat != GL_RGBA8_OES)
             {
-                return gl::error(GL_INVALID_OPERATION, false);
+                context->recordError(Error(GL_INVALID_OPERATION));
+                return false;
             }
             break;
           case GL_LUMINANCE_ALPHA:
@@ -625,38 +687,45 @@
                 colorbufferFormat != GL_BGRA8_EXT &&
                 colorbufferFormat != GL_RGBA8_OES)
             {
-                return gl::error(GL_INVALID_OPERATION, false);
+                context->recordError(Error(GL_INVALID_OPERATION));
+                return false;
             }
             break;
           case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
           case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
             if (context->getExtensions().textureCompressionDXT1)
             {
-                return gl::error(GL_INVALID_OPERATION, false);
+                context->recordError(Error(GL_INVALID_OPERATION));
+                return false;
             }
             else
             {
-                return gl::error(GL_INVALID_ENUM, false);
+                context->recordError(Error(GL_INVALID_ENUM));
+                return false;
             }
             break;
           case GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE:
             if (context->getExtensions().textureCompressionDXT3)
             {
-                return gl::error(GL_INVALID_OPERATION, false);
+                context->recordError(Error(GL_INVALID_OPERATION));
+                return false;
             }
             else
             {
-                return gl::error(GL_INVALID_ENUM, false);
+                context->recordError(Error(GL_INVALID_ENUM));
+                return false;
             }
             break;
           case GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE:
             if (context->getExtensions().textureCompressionDXT5)
             {
-                return gl::error(GL_INVALID_OPERATION, false);
+                context->recordError(Error(GL_INVALID_OPERATION));
+                return false;
             }
             else
             {
-                return gl::error(GL_INVALID_ENUM, false);
+                context->recordError(Error(GL_INVALID_ENUM));
+                return false;
             }
             break;
           case GL_DEPTH_COMPONENT:
@@ -666,14 +735,17 @@
           case GL_DEPTH24_STENCIL8_OES:
             if (context->getExtensions().depthTextures)
             {
-                return gl::error(GL_INVALID_OPERATION, false);
+                context->recordError(Error(GL_INVALID_OPERATION));
+                return false;
             }
             else
             {
-                return gl::error(GL_INVALID_ENUM, false);
+                context->recordError(Error(GL_INVALID_ENUM));
+                return false;
             }
           default:
-            return gl::error(GL_INVALID_ENUM, false);
+            context->recordError(Error(GL_INVALID_ENUM));
+            return false;
         }
     }
 
@@ -681,33 +753,38 @@
     return (width > 0 && height > 0);
 }
 
-bool ValidateES2TexStorageParameters(gl::Context *context, GLenum target, GLsizei levels, GLenum internalformat,
+bool ValidateES2TexStorageParameters(Context *context, GLenum target, GLsizei levels, GLenum internalformat,
                                      GLsizei width, GLsizei height)
 {
     if (target != GL_TEXTURE_2D && target != GL_TEXTURE_CUBE_MAP)
     {
-        return gl::error(GL_INVALID_ENUM, false);
+        context->recordError(Error(GL_INVALID_ENUM));
+        return false;
     }
 
     if (width < 1 || height < 1 || levels < 1)
     {
-        return gl::error(GL_INVALID_VALUE, false);
+        context->recordError(Error(GL_INVALID_VALUE));
+        return false;
     }
 
     if (target == GL_TEXTURE_CUBE_MAP && width != height)
     {
-        return gl::error(GL_INVALID_VALUE, false);
+        context->recordError(Error(GL_INVALID_VALUE));
+        return false;
     }
 
     if (levels != 1 && levels != gl::log2(std::max(width, height)) + 1)
     {
-        return gl::error(GL_INVALID_OPERATION, false);
+        context->recordError(Error(GL_INVALID_OPERATION));
+        return false;
     }
 
     const gl::InternalFormat &formatInfo = gl::GetInternalFormatInfo(internalformat);
     if (formatInfo.format == GL_NONE || formatInfo.type == GL_NONE)
     {
-        return gl::error(GL_INVALID_ENUM, false);
+        context->recordError(Error(GL_INVALID_ENUM));
+        return false;
     }
 
     const gl::Caps &caps = context->getCaps();
@@ -718,25 +795,29 @@
         if (static_cast<GLuint>(width) > caps.max2DTextureSize ||
             static_cast<GLuint>(height) > caps.max2DTextureSize)
         {
-            return gl::error(GL_INVALID_VALUE, false);
+            context->recordError(Error(GL_INVALID_VALUE));
+            return false;
         }
         break;
       case GL_TEXTURE_CUBE_MAP:
         if (static_cast<GLuint>(width) > caps.maxCubeMapTextureSize ||
             static_cast<GLuint>(height) > caps.maxCubeMapTextureSize)
         {
-            return gl::error(GL_INVALID_VALUE, false);
+            context->recordError(Error(GL_INVALID_VALUE));
+            return false;
         }
         break;
       default:
-        return gl::error(GL_INVALID_ENUM, false);
+        context->recordError(Error(GL_INVALID_ENUM));
+        return false;
     }
 
     if (levels != 1 && !context->getExtensions().textureNPOT)
     {
         if (!gl::isPow2(width) || !gl::isPow2(height))
         {
-            return gl::error(GL_INVALID_OPERATION, false);
+            context->recordError(Error(GL_INVALID_OPERATION));
+            return false;
         }
     }
 
@@ -746,19 +827,22 @@
       case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
         if (!context->getExtensions().textureCompressionDXT1)
         {
-            return gl::error(GL_INVALID_ENUM, false);
+            context->recordError(Error(GL_INVALID_ENUM));
+            return false;
         }
         break;
       case GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE:
         if (!context->getExtensions().textureCompressionDXT3)
         {
-            return gl::error(GL_INVALID_ENUM, false);
+            context->recordError(Error(GL_INVALID_ENUM));
+            return false;
         }
         break;
       case GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE:
         if (!context->getExtensions().textureCompressionDXT5)
         {
-            return gl::error(GL_INVALID_ENUM, false);
+            context->recordError(Error(GL_INVALID_ENUM));
+            return false;
         }
         break;
       case GL_RGBA32F_EXT:
@@ -768,7 +852,8 @@
       case GL_LUMINANCE_ALPHA32F_EXT:
         if (!context->getExtensions().textureFloat)
         {
-            return gl::error(GL_INVALID_ENUM, false);
+            context->recordError(Error(GL_INVALID_ENUM));
+            return false;
         }
         break;
       case GL_RGBA16F_EXT:
@@ -778,7 +863,8 @@
       case GL_LUMINANCE_ALPHA16F_EXT:
         if (!context->getExtensions().textureHalfFloat)
         {
-            return gl::error(GL_INVALID_ENUM, false);
+            context->recordError(Error(GL_INVALID_ENUM));
+            return false;
         }
         break;
       case GL_R8_EXT:
@@ -789,7 +875,8 @@
       case GL_RG32F_EXT:
         if (!context->getExtensions().textureRG)
         {
-            return gl::error(GL_INVALID_ENUM, false);
+            context->recordError(Error(GL_INVALID_ENUM));
+            return false;
         }
         break;
       case GL_DEPTH_COMPONENT16:
@@ -797,16 +884,19 @@
       case GL_DEPTH24_STENCIL8_OES:
         if (!context->getExtensions().depthTextures)
         {
-            return gl::error(GL_INVALID_ENUM, false);
+            context->recordError(Error(GL_INVALID_ENUM));
+            return false;
         }
         if (target != GL_TEXTURE_2D)
         {
-            return gl::error(GL_INVALID_OPERATION, false);
+            context->recordError(Error(GL_INVALID_OPERATION));
+            return false;
         }
         // ANGLE_depth_texture only supports 1-level textures
         if (levels != 1)
         {
-            return gl::error(GL_INVALID_OPERATION, false);
+            context->recordError(Error(GL_INVALID_OPERATION));
+            return false;
         }
         break;
       default:
@@ -828,19 +918,21 @@
 
     if (!texture || texture->id() == 0)
     {
-        return gl::error(GL_INVALID_OPERATION, false);
+        context->recordError(Error(GL_INVALID_OPERATION));
+        return false;
     }
 
     if (texture->isImmutable())
     {
-        return gl::error(GL_INVALID_OPERATION, false);
+        context->recordError(Error(GL_INVALID_OPERATION));
+        return false;
     }
 
     return true;
 }
 
 // check for combinations of format and type that are valid for ReadPixels
-bool ValidES2ReadFormatType(gl::Context *context, GLenum format, GLenum type)
+bool ValidES2ReadFormatType(Context *context, GLenum format, GLenum type)
 {
     switch (format)
     {
diff --git a/src/libGLESv2/validationES2.h b/src/libGLESv2/validationES2.h
index e41e345..53a0b63 100644
--- a/src/libGLESv2/validationES2.h
+++ b/src/libGLESv2/validationES2.h
@@ -9,23 +9,25 @@
 #ifndef LIBGLESV2_VALIDATION_ES2_H
 #define LIBGLESV2_VALIDATION_ES2_H
 
+#include <GLES2/gl2.h>
+
 namespace gl
 {
 
 class Context;
 
-bool ValidateES2TexImageParameters(gl::Context *context, GLenum target, GLint level, GLenum internalformat, bool isCompressed, bool isSubImage,
+bool ValidateES2TexImageParameters(Context *context, GLenum target, GLint level, GLenum internalformat, bool isCompressed, bool isSubImage,
                                    GLint xoffset, GLint yoffset, GLsizei width, GLsizei height,
                                    GLint border, GLenum format, GLenum type, const GLvoid *pixels);
 
-bool ValidateES2CopyTexImageParameters(gl::Context* context, GLenum target, GLint level, GLenum internalformat, bool isSubImage,
+bool ValidateES2CopyTexImageParameters(Context* context, GLenum target, GLint level, GLenum internalformat, bool isSubImage,
                                        GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height,
                                        GLint border);
 
-bool ValidateES2TexStorageParameters(gl::Context *context, GLenum target, GLsizei levels, GLenum internalformat,
+bool ValidateES2TexStorageParameters(Context *context, GLenum target, GLsizei levels, GLenum internalformat,
                                      GLsizei width, GLsizei height);
 
-bool ValidES2ReadFormatType(gl::Context *context, GLenum format, GLenum type);
+bool ValidES2ReadFormatType(Context *context, GLenum format, GLenum type);
 
 }
 
diff --git a/src/libGLESv2/validationES3.cpp b/src/libGLESv2/validationES3.cpp
index 66c41e6..251c6ad 100644
--- a/src/libGLESv2/validationES3.cpp
+++ b/src/libGLESv2/validationES3.cpp
@@ -1,4 +1,3 @@
-#include "precompiled.h"
 //
 // Copyright (c) 2013-2014 The ANGLE Project Authors. All rights reserved.
 // Use of this source code is governed by a BSD-style license that can be
@@ -22,7 +21,6 @@
 namespace gl
 {
 
-// ES3 has a specific set of permutations of internal formats, formats and types which are acceptable.
 struct ES3FormatCombination
 {
     GLenum internalFormat;
@@ -225,7 +223,8 @@
     const gl::InternalFormat &formatInfo = gl::GetInternalFormatInfo(internalFormat);
     if (!formatInfo.textureSupport(context->getClientVersion(), context->getExtensions()))
     {
-        return gl::error(GL_INVALID_ENUM, false);
+        context->recordError(Error(GL_INVALID_ENUM));
+        return false;
     }
 
     // The type and format are valid if any supported internal format has that type and format
@@ -258,7 +257,8 @@
 
     if (!typeSupported || !formatSupported)
     {
-        return gl::error(GL_INVALID_ENUM, false);
+        context->recordError(Error(GL_INVALID_ENUM));
+        return false;
     }
 
     // Check if this is a valid format combination to load texture data
@@ -269,31 +269,35 @@
 
     if (es3FormatSet.find(searchFormat) == es3FormatSet.end())
     {
-        return gl::error(GL_INVALID_OPERATION, false);
+        context->recordError(Error(GL_INVALID_OPERATION));
+        return false;
     }
 
     return true;
 }
 
-bool ValidateES3TexImageParameters(gl::Context *context, GLenum target, GLint level, GLenum internalformat, bool isCompressed, bool isSubImage,
+bool ValidateES3TexImageParameters(Context *context, GLenum target, GLint level, GLenum internalformat, bool isCompressed, bool isSubImage,
                                    GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth,
                                    GLint border, GLenum format, GLenum type, const GLvoid *pixels)
 {
     if (!ValidTexture2DDestinationTarget(context, target))
     {
-        return gl::error(GL_INVALID_ENUM, false);
+        context->recordError(Error(GL_INVALID_ENUM));
+        return false;
     }
 
     // Validate image size
     if (!ValidImageSize(context, target, level, width, height, depth))
     {
-        return gl::error(GL_INVALID_VALUE, false);
+        context->recordError(Error(GL_INVALID_VALUE));
+        return false;
     }
 
     // Verify zero border
     if (border != 0)
     {
-        return gl::error(GL_INVALID_VALUE, false);
+        context->recordError(Error(GL_INVALID_VALUE));
+        return false;
     }
 
     if (xoffset < 0 || yoffset < 0 || zoffset < 0 ||
@@ -301,7 +305,8 @@
         std::numeric_limits<GLsizei>::max() - yoffset < height ||
         std::numeric_limits<GLsizei>::max() - zoffset < depth)
     {
-        return gl::error(GL_INVALID_VALUE, false);
+        context->recordError(Error(GL_INVALID_VALUE));
+        return false;
     }
 
     const gl::Caps &caps = context->getCaps();
@@ -319,7 +324,8 @@
             if (static_cast<GLuint>(width) > (caps.max2DTextureSize >> level) ||
                 static_cast<GLuint>(height) > (caps.max2DTextureSize >> level))
             {
-                return gl::error(GL_INVALID_VALUE, false);
+                context->recordError(Error(GL_INVALID_VALUE));
+                return false;
             }
 
             gl::Texture2D *texture2d = context->getTexture2D();
@@ -344,12 +350,14 @@
         {
             if (!isSubImage && width != height)
             {
-                return gl::error(GL_INVALID_VALUE, false);
+                context->recordError(Error(GL_INVALID_VALUE));
+                return false;
             }
 
             if (static_cast<GLuint>(width) > (caps.maxCubeMapTextureSize >> level))
             {
-                return gl::error(GL_INVALID_VALUE, false);
+                context->recordError(Error(GL_INVALID_VALUE));
+                return false;
             }
 
             gl::TextureCubeMap *textureCube = context->getTextureCubeMap();
@@ -371,7 +379,8 @@
                 static_cast<GLuint>(height) > (caps.max3DTextureSize >> level) ||
                 static_cast<GLuint>(depth) > (caps.max3DTextureSize >> level))
             {
-                return gl::error(GL_INVALID_VALUE, false);
+                context->recordError(Error(GL_INVALID_VALUE));
+                return false;
             }
 
             gl::Texture3D *texture3d = context->getTexture3D();
@@ -393,7 +402,8 @@
                   static_cast<GLuint>(height) > (caps.max2DTextureSize >> level) ||
                   static_cast<GLuint>(depth) > (caps.maxArrayTextureLayers >> level))
               {
-                  return gl::error(GL_INVALID_VALUE, false);
+                  context->recordError(Error(GL_INVALID_VALUE));
+                  return false;
               }
 
               gl::Texture2DArray *texture2darray = context->getTexture2DArray();
@@ -410,17 +420,20 @@
           break;
 
       default:
-        return gl::error(GL_INVALID_ENUM, false);
+        context->recordError(Error(GL_INVALID_ENUM));
+        return false;
     }
 
     if (!texture)
     {
-        return gl::error(GL_INVALID_OPERATION, false);
+        context->recordError(Error(GL_INVALID_OPERATION));
+        return false;
     }
 
     if (texture->isImmutable() && !isSubImage)
     {
-        return gl::error(GL_INVALID_OPERATION, false);
+        context->recordError(Error(GL_INVALID_OPERATION));
+        return false;
     }
 
     // Validate texture formats
@@ -430,17 +443,20 @@
     {
         if (!ValidCompressedImageSize(context, actualInternalFormat, width, height))
         {
-            return gl::error(GL_INVALID_OPERATION, false);
+            context->recordError(Error(GL_INVALID_OPERATION));
+            return false;
         }
 
         if (!actualFormatInfo.compressed)
         {
-            return gl::error(GL_INVALID_ENUM, false);
+            context->recordError(Error(GL_INVALID_ENUM));
+            return false;
         }
 
         if (target == GL_TEXTURE_3D)
         {
-            return gl::error(GL_INVALID_OPERATION, false);
+            context->recordError(Error(GL_INVALID_OPERATION));
+            return false;
         }
     }
     else
@@ -452,7 +468,8 @@
 
         if (target == GL_TEXTURE_3D && (format == GL_DEPTH_COMPONENT || format == GL_DEPTH_STENCIL))
         {
-            return gl::error(GL_INVALID_OPERATION, false);
+            context->recordError(Error(GL_INVALID_OPERATION));
+            return false;
         }
     }
 
@@ -461,7 +478,8 @@
     {
         if (isCompressed != textureCompressed)
         {
-            return gl::error(GL_INVALID_OPERATION, false);
+            context->recordError(Error(GL_INVALID_OPERATION));
+            return false;
         }
 
         if (isCompressed)
@@ -469,7 +487,8 @@
             if ((width % 4 != 0 && width != textureLevelWidth) ||
                 (height % 4 != 0 && height != textureLevelHeight))
             {
-                return gl::error(GL_INVALID_OPERATION, false);
+                context->recordError(Error(GL_INVALID_OPERATION));
+                return false;
             }
         }
 
@@ -480,21 +499,24 @@
 
         if (xoffset < 0 || yoffset < 0 || zoffset < 0)
         {
-            return gl::error(GL_INVALID_VALUE, false);
+            context->recordError(Error(GL_INVALID_VALUE));
+            return false;
         }
 
         if (std::numeric_limits<GLsizei>::max() - xoffset < width ||
             std::numeric_limits<GLsizei>::max() - yoffset < height ||
             std::numeric_limits<GLsizei>::max() - zoffset < depth)
         {
-            return gl::error(GL_INVALID_VALUE, false);
+            context->recordError(Error(GL_INVALID_VALUE));
+            return false;
         }
 
         if (xoffset + width > textureLevelWidth ||
             yoffset + height > textureLevelHeight ||
             zoffset + depth > textureLevelDepth)
         {
-            return gl::error(GL_INVALID_VALUE, false);
+            context->recordError(Error(GL_INVALID_VALUE));
+            return false;
         }
     }
 
@@ -516,7 +538,8 @@
             !rx::IsUnsignedMultiplicationSafe(widthSize * heightSize * depthSize, pixelBytes))
         {
             // Overflow past the end of the buffer
-            return gl::error(GL_INVALID_OPERATION, false);
+            context->recordError(Error(GL_INVALID_OPERATION));
+            return false;
         }
 
         size_t copyBytes = widthSize * heightSize * depthSize * pixelBytes;
@@ -526,7 +549,8 @@
             ((offset + copyBytes) > static_cast<size_t>(pixelUnpackBuffer->getSize())))
         {
             // Overflow past the end of the buffer
-            return gl::error(GL_INVALID_OPERATION, false);
+            context->recordError(Error(GL_INVALID_OPERATION));
+            return false;
         }
 
         // ...data is not evenly divisible into the number of bytes needed to store in memory a datum
@@ -535,13 +559,15 @@
 
         if ((offset % dataBytesPerPixel) != 0)
         {
-            return gl::error(GL_INVALID_OPERATION, false);
+            context->recordError(Error(GL_INVALID_OPERATION));
+            return false;
         }
 
         // ...the buffer object's data store is currently mapped.
         if (pixelUnpackBuffer->isMapped())
         {
-            return gl::error(GL_INVALID_OPERATION, false);
+            context->recordError(Error(GL_INVALID_OPERATION));
+            return false;
         }
     }
 
@@ -832,7 +858,7 @@
     return false;
 }
 
-bool ValidateES3CopyTexImageParameters(gl::Context *context, GLenum target, GLint level, GLenum internalformat,
+bool ValidateES3CopyTexImageParameters(Context *context, GLenum target, GLint level, GLenum internalformat,
                                        bool isSubImage, GLint xoffset, GLint yoffset, GLint zoffset,
                                        GLint x, GLint y, GLsizei width, GLsizei height, GLint border)
 {
@@ -848,12 +874,14 @@
 
     if (framebuffer->completeness() != GL_FRAMEBUFFER_COMPLETE)
     {
-        return gl::error(GL_INVALID_FRAMEBUFFER_OPERATION, false);
+        context->recordError(Error(GL_INVALID_FRAMEBUFFER_OPERATION));
+        return false;
     }
 
     if (context->getState().getReadFramebuffer()->id() != 0 && framebuffer->getSamples() != 0)
     {
-        return gl::error(GL_INVALID_OPERATION, false);
+        context->recordError(Error(GL_INVALID_OPERATION));
+        return false;
     }
 
     gl::FramebufferAttachment *source = framebuffer->getReadColorbuffer();
@@ -864,7 +892,8 @@
         if (!IsValidES3CopyTexImageCombination(textureInternalFormat, colorbufferInternalFormat,
                                                context->getState().getReadFramebuffer()->id()))
         {
-            return gl::error(GL_INVALID_OPERATION, false);
+            context->recordError(Error(GL_INVALID_OPERATION));
+            return false;
         }
     }
     else
@@ -872,7 +901,8 @@
         if (!gl::IsValidES3CopyTexImageCombination(internalformat, colorbufferInternalFormat,
                                                 context->getState().getReadFramebuffer()->id()))
         {
-            return gl::error(GL_INVALID_OPERATION, false);
+            context->recordError(Error(GL_INVALID_OPERATION));
+            return false;
         }
     }
 
@@ -880,17 +910,19 @@
     return (width > 0 && height > 0);
 }
 
-bool ValidateES3TexStorageParameters(gl::Context *context, GLenum target, GLsizei levels, GLenum internalformat,
+bool ValidateES3TexStorageParameters(Context *context, GLenum target, GLsizei levels, GLenum internalformat,
                                      GLsizei width, GLsizei height, GLsizei depth)
 {
     if (width < 1 || height < 1 || depth < 1 || levels < 1)
     {
-        return gl::error(GL_INVALID_VALUE, false);
+        context->recordError(Error(GL_INVALID_VALUE));
+        return false;
     }
 
     if (levels > gl::log2(std::max(std::max(width, height), depth)) + 1)
     {
-        return gl::error(GL_INVALID_OPERATION, false);
+        context->recordError(Error(GL_INVALID_OPERATION));
+        return false;
     }
 
     const gl::Caps &caps = context->getCaps();
@@ -905,7 +937,8 @@
             if (static_cast<GLuint>(width) > caps.max2DTextureSize ||
                 static_cast<GLuint>(height) > caps.max2DTextureSize)
             {
-                return gl::error(GL_INVALID_VALUE, false);
+                context->recordError(Error(GL_INVALID_VALUE));
+                return false;
             }
         }
         break;
@@ -916,12 +949,14 @@
 
             if (width != height)
             {
-                return gl::error(GL_INVALID_VALUE, false);
+                context->recordError(Error(GL_INVALID_VALUE));
+                return false;
             }
 
             if (static_cast<GLuint>(width) > caps.maxCubeMapTextureSize)
             {
-                return gl::error(GL_INVALID_VALUE, false);
+                context->recordError(Error(GL_INVALID_VALUE));
+                return false;
             }
         }
         break;
@@ -934,7 +969,8 @@
                 static_cast<GLuint>(height) > caps.max3DTextureSize ||
                 static_cast<GLuint>(depth) > caps.max3DTextureSize)
             {
-                return gl::error(GL_INVALID_VALUE, false);
+                context->recordError(Error(GL_INVALID_VALUE));
+                return false;
             }
         }
         break;
@@ -947,50 +983,58 @@
                 static_cast<GLuint>(height) > caps.max2DTextureSize ||
                 static_cast<GLuint>(depth) > caps.maxArrayTextureLayers)
             {
-                return gl::error(GL_INVALID_VALUE, false);
+                context->recordError(Error(GL_INVALID_VALUE));
+                return false;
             }
         }
         break;
 
       default:
-        return gl::error(GL_INVALID_ENUM, false);
+        context->recordError(Error(GL_INVALID_ENUM));
+        return false;
     }
 
     if (!texture || texture->id() == 0)
     {
-        return gl::error(GL_INVALID_OPERATION, false);
+        context->recordError(Error(GL_INVALID_OPERATION));
+        return false;
     }
 
     if (texture->isImmutable())
     {
-        return gl::error(GL_INVALID_OPERATION, false);
+        context->recordError(Error(GL_INVALID_OPERATION));
+        return false;
     }
 
     const gl::InternalFormat &formatInfo = gl::GetInternalFormatInfo(internalformat);
     if (!formatInfo.textureSupport(context->getClientVersion(), context->getExtensions()))
     {
-        return gl::error(GL_INVALID_ENUM, false);
+        context->recordError(Error(GL_INVALID_ENUM));
+        return false;
     }
 
     if (formatInfo.pixelBytes == 0)
     {
-        return gl::error(GL_INVALID_ENUM, false);
+        context->recordError(Error(GL_INVALID_ENUM));
+        return false;
     }
 
     return true;
 }
 
-bool ValidateFramebufferTextureLayer(const gl::Context *context, GLenum target, GLenum attachment,
+bool ValidateFramebufferTextureLayer(Context *context, GLenum target, GLenum attachment,
                                      GLuint texture, GLint level, GLint layer)
 {
     if (context->getClientVersion() < 3)
     {
-        return gl::error(GL_INVALID_OPERATION, false);
+        context->recordError(Error(GL_INVALID_OPERATION));
+        return false;
     }
 
     if (layer < 0)
     {
-        return gl::error(GL_INVALID_VALUE, false);
+        context->recordError(Error(GL_INVALID_VALUE));
+        return false;
     }
 
     if (!ValidateFramebufferTextureBase(context, target, attachment, texture, level))
@@ -1010,18 +1054,21 @@
             {
                 if (level > gl::log2(caps.max2DTextureSize))
                 {
-                    return gl::error(GL_INVALID_VALUE, false);
+                    context->recordError(Error(GL_INVALID_VALUE));
+                    return false;
                 }
 
                 if (static_cast<GLuint>(layer) >= caps.maxArrayTextureLayers)
                 {
-                    return gl::error(GL_INVALID_VALUE, false);
+                    context->recordError(Error(GL_INVALID_VALUE));
+                    return false;
                 }
 
                 gl::Texture2DArray *texArray = static_cast<gl::Texture2DArray *>(tex);
                 if (texArray->isCompressed(level))
                 {
-                    return gl::error(GL_INVALID_OPERATION, false);
+                    context->recordError(Error(GL_INVALID_OPERATION));
+                    return false;
                 }
             }
             break;
@@ -1030,31 +1077,35 @@
             {
                 if (level > gl::log2(caps.max3DTextureSize))
                 {
-                    return gl::error(GL_INVALID_VALUE, false);
+                    context->recordError(Error(GL_INVALID_VALUE));
+                    return false;
                 }
 
                 if (static_cast<GLuint>(layer) >= caps.max3DTextureSize)
                 {
-                    return gl::error(GL_INVALID_VALUE, false);
+                    context->recordError(Error(GL_INVALID_VALUE));
+                    return false;
                 }
 
                 gl::Texture3D *tex3d = static_cast<gl::Texture3D *>(tex);
                 if (tex3d->isCompressed(level))
                 {
-                    return gl::error(GL_INVALID_OPERATION, false);
+                    context->recordError(Error(GL_INVALID_OPERATION));
+                    return false;
                 }
             }
             break;
 
           default:
-            return gl::error(GL_INVALID_OPERATION, false);
+            context->recordError(Error(GL_INVALID_OPERATION));
+            return false;
         }
     }
 
     return true;
 }
 
-bool ValidES3ReadFormatType(gl::Context *context, GLenum internalFormat, GLenum format, GLenum type)
+bool ValidES3ReadFormatType(Context *context, GLenum internalFormat, GLenum format, GLenum type)
 {
     const gl::InternalFormat &internalFormatInfo = gl::GetInternalFormatInfo(internalFormat);
 
@@ -1131,7 +1182,7 @@
     return true;
 }
 
-bool ValidateInvalidateFramebufferParameters(gl::Context *context, GLenum target, GLsizei numAttachments,
+bool ValidateInvalidateFramebufferParameters(Context *context, GLenum target, GLsizei numAttachments,
                                              const GLenum* attachments)
 {
     bool defaultFramebuffer = false;
@@ -1146,7 +1197,8 @@
         defaultFramebuffer = context->getState().getReadFramebuffer()->id() == 0;
         break;
       default:
-        return gl::error(GL_INVALID_ENUM, false);
+          context->recordError(Error(GL_INVALID_ENUM));
+          return false;
     }
 
     for (int i = 0; i < numAttachments; ++i)
@@ -1155,12 +1207,14 @@
         {
             if (defaultFramebuffer)
             {
-                return gl::error(GL_INVALID_ENUM, false);
+                context->recordError(Error(GL_INVALID_ENUM));
+                return false;
             }
 
             if (attachments[i] >= GL_COLOR_ATTACHMENT0 + context->getCaps().maxColorAttachments)
             {
-                return gl::error(GL_INVALID_OPERATION, false);
+                context->recordError(Error(GL_INVALID_OPERATION));
+                return false;
             }
         }
         else
@@ -1172,7 +1226,8 @@
               case GL_DEPTH_STENCIL_ATTACHMENT:
                 if (defaultFramebuffer)
                 {
-                    return gl::error(GL_INVALID_ENUM, false);
+                    context->recordError(Error(GL_INVALID_ENUM));
+                    return false;
                 }
                 break;
               case GL_COLOR:
@@ -1180,11 +1235,13 @@
               case GL_STENCIL:
                 if (!defaultFramebuffer)
                 {
-                    return gl::error(GL_INVALID_ENUM, false);
+                    context->recordError(Error(GL_INVALID_ENUM));
+                    return false;
                 }
                 break;
               default:
-                return gl::error(GL_INVALID_ENUM, false);
+                context->recordError(Error(GL_INVALID_ENUM));
+                return false;
             }
         }
     }
@@ -1192,20 +1249,33 @@
     return true;
 }
 
-bool ValidateClearBuffer(const gl::Context *context)
+bool ValidateClearBuffer(Context *context)
 {
     if (context->getClientVersion() < 3)
     {
-        return gl::error(GL_INVALID_OPERATION, false);
+        context->recordError(Error(GL_INVALID_OPERATION));
+        return false;
     }
 
     const gl::Framebuffer *fbo = context->getState().getDrawFramebuffer();
     if (!fbo || fbo->completeness() != GL_FRAMEBUFFER_COMPLETE)
     {
-        return gl::error(GL_INVALID_FRAMEBUFFER_OPERATION, false);
+        context->recordError(Error(GL_INVALID_FRAMEBUFFER_OPERATION));
+        return false;
     }
 
     return true;
 }
 
+bool ValidateGetUniformuiv(Context *context, GLuint program, GLint location, GLuint* params)
+{
+    if (context->getClientVersion() < 3)
+    {
+        context->recordError(Error(GL_INVALID_OPERATION));
+        return false;
+    }
+
+    return ValidateGetUniformBase(context, program, location);
+}
+
 }
diff --git a/src/libGLESv2/validationES3.h b/src/libGLESv2/validationES3.h
index 4d068bd..cafacca 100644
--- a/src/libGLESv2/validationES3.h
+++ b/src/libGLESv2/validationES3.h
@@ -9,31 +9,35 @@
 #ifndef LIBGLESV2_VALIDATION_ES3_H
 #define LIBGLESV2_VALIDATION_ES3_H
 
+#include <GLES3/gl3.h>
+
 namespace gl
 {
 
 class Context;
 
-bool ValidateES3TexImageParameters(gl::Context *context, GLenum target, GLint level, GLenum internalformat, bool isCompressed, bool isSubImage,
+bool ValidateES3TexImageParameters(Context *context, GLenum target, GLint level, GLenum internalformat, bool isCompressed, bool isSubImage,
                                    GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth,
                                    GLint border, GLenum format, GLenum type, const GLvoid *pixels);
 
-bool ValidateES3CopyTexImageParameters(gl::Context *context, GLenum target, GLint level, GLenum internalformat,
+bool ValidateES3CopyTexImageParameters(Context *context, GLenum target, GLint level, GLenum internalformat,
                                        bool isSubImage, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y,
                                        GLsizei width, GLsizei height, GLint border);
 
-bool ValidateES3TexStorageParameters(gl::Context *context, GLenum target, GLsizei levels, GLenum internalformat,
+bool ValidateES3TexStorageParameters(Context *context, GLenum target, GLsizei levels, GLenum internalformat,
                                      GLsizei width, GLsizei height, GLsizei depth);
 
-bool ValidateFramebufferTextureLayer(const gl::Context *context, GLenum target, GLenum attachment,
+bool ValidateFramebufferTextureLayer(Context *context, GLenum target, GLenum attachment,
                                      GLuint texture, GLint level, GLint layer);
 
-bool ValidES3ReadFormatType(gl::Context *context, GLenum internalFormat, GLenum format, GLenum type);
+bool ValidES3ReadFormatType(Context *context, GLenum internalFormat, GLenum format, GLenum type);
 
-bool ValidateInvalidateFramebufferParameters(gl::Context *context, GLenum target, GLsizei numAttachments,
+bool ValidateInvalidateFramebufferParameters(Context *context, GLenum target, GLsizei numAttachments,
                                              const GLenum* attachments);
 
-bool ValidateClearBuffer(const gl::Context *context);
+bool ValidateClearBuffer(Context *context);
+
+bool ValidateGetUniformuiv(Context *context, GLuint program, GLint location, GLuint* params);
 
 }
 
diff --git a/src/preprocessor.target.darwin-arm.mk b/src/preprocessor.target.darwin-arm.mk
index eb16ba7..5a333ac 100644
--- a/src/preprocessor.target.darwin-arm.mk
+++ b/src/preprocessor.target.darwin-arm.mk
@@ -5,7 +5,6 @@
 LOCAL_MODULE_CLASS := STATIC_LIBRARIES
 LOCAL_MODULE := third_party_angle_src_preprocessor_gyp
 LOCAL_MODULE_SUFFIX := .a
-LOCAL_MODULE_TAGS := optional
 LOCAL_MODULE_TARGET_ARCH := $(TARGET_$(GYP_VAR_PREFIX)ARCH)
 gyp_intermediate_dir := $(call local-intermediates-dir,,$(GYP_VAR_PREFIX))
 gyp_shared_intermediate_dir := $(call intermediates-dir-for,GYP,shared,,,$(GYP_VAR_PREFIX))
@@ -40,7 +39,6 @@
 MY_CFLAGS_Debug := \
 	-fstack-protector \
 	--param=ssp-buffer-size=4 \
-	-fno-exceptions \
 	-fno-strict-aliasing \
 	-Wno-unused-parameter \
 	-Wno-missing-field-initializers \
@@ -50,13 +48,13 @@
 	-Wno-unused-local-typedefs \
 	-Wno-format \
 	-fno-tree-sra \
+	-fno-caller-saves \
+	-Wno-psabi \
 	-fno-partial-inlining \
 	-fno-early-inlining \
 	-fno-tree-copy-prop \
 	-fno-tree-loop-optimize \
 	-fno-move-loop-invariants \
-	-fno-caller-saves \
-	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -75,6 +73,7 @@
 	-Wno-sequence-point \
 	-Os \
 	-g \
+	-gdwarf-4 \
 	-fdata-sections \
 	-ffunction-sections \
 	-fomit-frame-pointer \
@@ -98,11 +97,13 @@
 	'-DENABLE_PRINTING=1' \
 	'-DENABLE_MANAGED_USERS=1' \
 	'-DDATA_REDUCTION_FALLBACK_HOST="http://compress.googlezip.net:80/"' \
-	'-DDATA_REDUCTION_DEV_HOST="http://proxy-dev.googlezip.net:80/"' \
+	'-DDATA_REDUCTION_DEV_HOST="https://proxy-dev.googlezip.net:443/"' \
+	'-DDATA_REDUCTION_DEV_FALLBACK_HOST="http://proxy-dev.googlezip.net:80/"' \
 	'-DSPDY_PROXY_AUTH_ORIGIN="https://proxy.googlezip.net:443/"' \
 	'-DDATA_REDUCTION_PROXY_PROBE_URL="http://check.googlezip.net/connect"' \
 	'-DDATA_REDUCTION_PROXY_WARMUP_URL="http://www.gstatic.com/generate_204"' \
 	'-DVIDEO_HOLE=1' \
+	'-DENABLE_LOAD_COMPLETION_HACKS=1' \
 	'-DUSE_OPENSSL=1' \
 	'-DUSE_OPENSSL_CERTS=1' \
 	'-DANDROID' \
@@ -125,6 +126,7 @@
 
 # Flags passed to only C++ (and not C) files.
 LOCAL_CPPFLAGS_Debug := \
+	-fno-exceptions \
 	-fno-rtti \
 	-fno-threadsafe-statics \
 	-fvisibility-inlines-hidden \
@@ -142,7 +144,6 @@
 MY_CFLAGS_Release := \
 	-fstack-protector \
 	--param=ssp-buffer-size=4 \
-	-fno-exceptions \
 	-fno-strict-aliasing \
 	-Wno-unused-parameter \
 	-Wno-missing-field-initializers \
@@ -152,13 +153,13 @@
 	-Wno-unused-local-typedefs \
 	-Wno-format \
 	-fno-tree-sra \
+	-fno-caller-saves \
+	-Wno-psabi \
 	-fno-partial-inlining \
 	-fno-early-inlining \
 	-fno-tree-copy-prop \
 	-fno-tree-loop-optimize \
 	-fno-move-loop-invariants \
-	-fno-caller-saves \
-	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -200,11 +201,13 @@
 	'-DENABLE_PRINTING=1' \
 	'-DENABLE_MANAGED_USERS=1' \
 	'-DDATA_REDUCTION_FALLBACK_HOST="http://compress.googlezip.net:80/"' \
-	'-DDATA_REDUCTION_DEV_HOST="http://proxy-dev.googlezip.net:80/"' \
+	'-DDATA_REDUCTION_DEV_HOST="https://proxy-dev.googlezip.net:443/"' \
+	'-DDATA_REDUCTION_DEV_FALLBACK_HOST="http://proxy-dev.googlezip.net:80/"' \
 	'-DSPDY_PROXY_AUTH_ORIGIN="https://proxy.googlezip.net:443/"' \
 	'-DDATA_REDUCTION_PROXY_PROBE_URL="http://check.googlezip.net/connect"' \
 	'-DDATA_REDUCTION_PROXY_WARMUP_URL="http://www.gstatic.com/generate_204"' \
 	'-DVIDEO_HOLE=1' \
+	'-DENABLE_LOAD_COMPLETION_HACKS=1' \
 	'-DUSE_OPENSSL=1' \
 	'-DUSE_OPENSSL_CERTS=1' \
 	'-DANDROID' \
@@ -227,6 +230,7 @@
 
 # Flags passed to only C++ (and not C) files.
 LOCAL_CPPFLAGS_Release := \
+	-fno-exceptions \
 	-fno-rtti \
 	-fno-threadsafe-statics \
 	-fvisibility-inlines-hidden \
@@ -246,50 +250,6 @@
 LOCAL_ASFLAGS := $(LOCAL_CFLAGS)
 ### Rules for final target.
 
-LOCAL_LDFLAGS_Debug := \
-	-Wl,-z,now \
-	-Wl,-z,relro \
-	-Wl,--fatal-warnings \
-	-Wl,-z,noexecstack \
-	-fPIC \
-	-Wl,-z,relro \
-	-Wl,-z,now \
-	-fuse-ld=gold \
-	-nostdlib \
-	-Wl,--no-undefined \
-	-Wl,--exclude-libs=ALL \
-	-Wl,--icf=safe \
-	-Wl,--warn-shared-textrel \
-	-Wl,-O1 \
-	-Wl,--as-needed
-
-
-LOCAL_LDFLAGS_Release := \
-	-Wl,-z,now \
-	-Wl,-z,relro \
-	-Wl,--fatal-warnings \
-	-Wl,-z,noexecstack \
-	-fPIC \
-	-Wl,-z,relro \
-	-Wl,-z,now \
-	-fuse-ld=gold \
-	-nostdlib \
-	-Wl,--no-undefined \
-	-Wl,--exclude-libs=ALL \
-	-Wl,--icf=safe \
-	-Wl,-O1 \
-	-Wl,--as-needed \
-	-Wl,--gc-sections \
-	-Wl,--warn-shared-textrel
-
-
-LOCAL_LDFLAGS := $(LOCAL_LDFLAGS_$(GYP_CONFIGURATION))
-
-LOCAL_STATIC_LIBRARIES :=
-
-# Enable grouping to fix circular references
-LOCAL_GROUP_STATIC_LIBRARIES := true
-
 LOCAL_SHARED_LIBRARIES := \
 	libstlport \
 	libdl
diff --git a/src/preprocessor.target.darwin-arm64.mk b/src/preprocessor.target.darwin-arm64.mk
index ace2cfd..97caadc 100644
--- a/src/preprocessor.target.darwin-arm64.mk
+++ b/src/preprocessor.target.darwin-arm64.mk
@@ -5,7 +5,6 @@
 LOCAL_MODULE_CLASS := STATIC_LIBRARIES
 LOCAL_MODULE := third_party_angle_src_preprocessor_gyp
 LOCAL_MODULE_SUFFIX := .a
-LOCAL_MODULE_TAGS := optional
 LOCAL_MODULE_TARGET_ARCH := $(TARGET_$(GYP_VAR_PREFIX)ARCH)
 gyp_intermediate_dir := $(call local-intermediates-dir,,$(GYP_VAR_PREFIX))
 gyp_shared_intermediate_dir := $(call intermediates-dir-for,GYP,shared,,,$(GYP_VAR_PREFIX))
@@ -39,7 +38,6 @@
 # Flags passed to both C and C++ files.
 MY_CFLAGS_Debug := \
 	--param=ssp-buffer-size=4 \
-	-fno-exceptions \
 	-fno-strict-aliasing \
 	-Wno-unused-parameter \
 	-Wno-missing-field-initializers \
@@ -65,6 +63,7 @@
 	-Wno-sequence-point \
 	-Os \
 	-g \
+	-gdwarf-4 \
 	-fdata-sections \
 	-ffunction-sections \
 	-funwind-tables
@@ -87,11 +86,13 @@
 	'-DENABLE_PRINTING=1' \
 	'-DENABLE_MANAGED_USERS=1' \
 	'-DDATA_REDUCTION_FALLBACK_HOST="http://compress.googlezip.net:80/"' \
-	'-DDATA_REDUCTION_DEV_HOST="http://proxy-dev.googlezip.net:80/"' \
+	'-DDATA_REDUCTION_DEV_HOST="https://proxy-dev.googlezip.net:443/"' \
+	'-DDATA_REDUCTION_DEV_FALLBACK_HOST="http://proxy-dev.googlezip.net:80/"' \
 	'-DSPDY_PROXY_AUTH_ORIGIN="https://proxy.googlezip.net:443/"' \
 	'-DDATA_REDUCTION_PROXY_PROBE_URL="http://check.googlezip.net/connect"' \
 	'-DDATA_REDUCTION_PROXY_WARMUP_URL="http://www.gstatic.com/generate_204"' \
 	'-DVIDEO_HOLE=1' \
+	'-DENABLE_LOAD_COMPLETION_HACKS=1' \
 	'-DUSE_OPENSSL=1' \
 	'-DUSE_OPENSSL_CERTS=1' \
 	'-DANDROID' \
@@ -114,6 +115,7 @@
 
 # Flags passed to only C++ (and not C) files.
 LOCAL_CPPFLAGS_Debug := \
+	-fno-exceptions \
 	-fno-rtti \
 	-fno-threadsafe-statics \
 	-fvisibility-inlines-hidden \
@@ -129,7 +131,6 @@
 # Flags passed to both C and C++ files.
 MY_CFLAGS_Release := \
 	--param=ssp-buffer-size=4 \
-	-fno-exceptions \
 	-fno-strict-aliasing \
 	-Wno-unused-parameter \
 	-Wno-missing-field-initializers \
@@ -177,11 +178,13 @@
 	'-DENABLE_PRINTING=1' \
 	'-DENABLE_MANAGED_USERS=1' \
 	'-DDATA_REDUCTION_FALLBACK_HOST="http://compress.googlezip.net:80/"' \
-	'-DDATA_REDUCTION_DEV_HOST="http://proxy-dev.googlezip.net:80/"' \
+	'-DDATA_REDUCTION_DEV_HOST="https://proxy-dev.googlezip.net:443/"' \
+	'-DDATA_REDUCTION_DEV_FALLBACK_HOST="http://proxy-dev.googlezip.net:80/"' \
 	'-DSPDY_PROXY_AUTH_ORIGIN="https://proxy.googlezip.net:443/"' \
 	'-DDATA_REDUCTION_PROXY_PROBE_URL="http://check.googlezip.net/connect"' \
 	'-DDATA_REDUCTION_PROXY_WARMUP_URL="http://www.gstatic.com/generate_204"' \
 	'-DVIDEO_HOLE=1' \
+	'-DENABLE_LOAD_COMPLETION_HACKS=1' \
 	'-DUSE_OPENSSL=1' \
 	'-DUSE_OPENSSL_CERTS=1' \
 	'-DANDROID' \
@@ -204,6 +207,7 @@
 
 # Flags passed to only C++ (and not C) files.
 LOCAL_CPPFLAGS_Release := \
+	-fno-exceptions \
 	-fno-rtti \
 	-fno-threadsafe-statics \
 	-fvisibility-inlines-hidden \
@@ -222,42 +226,6 @@
 LOCAL_ASFLAGS := $(LOCAL_CFLAGS)
 ### Rules for final target.
 
-LOCAL_LDFLAGS_Debug := \
-	-Wl,-z,now \
-	-Wl,-z,relro \
-	-Wl,--fatal-warnings \
-	-Wl,-z,noexecstack \
-	-fPIC \
-	-nostdlib \
-	-Wl,--no-undefined \
-	-Wl,--exclude-libs=ALL \
-	-Wl,--warn-shared-textrel \
-	-Wl,-O1 \
-	-Wl,--as-needed
-
-
-LOCAL_LDFLAGS_Release := \
-	-Wl,-z,now \
-	-Wl,-z,relro \
-	-Wl,--fatal-warnings \
-	-Wl,-z,noexecstack \
-	-fPIC \
-	-nostdlib \
-	-Wl,--no-undefined \
-	-Wl,--exclude-libs=ALL \
-	-Wl,-O1 \
-	-Wl,--as-needed \
-	-Wl,--gc-sections \
-	-Wl,--warn-shared-textrel
-
-
-LOCAL_LDFLAGS := $(LOCAL_LDFLAGS_$(GYP_CONFIGURATION))
-
-LOCAL_STATIC_LIBRARIES :=
-
-# Enable grouping to fix circular references
-LOCAL_GROUP_STATIC_LIBRARIES := true
-
 LOCAL_SHARED_LIBRARIES := \
 	libstlport \
 	libdl
diff --git a/src/preprocessor.target.darwin-mips.mk b/src/preprocessor.target.darwin-mips.mk
index c6b1c54..c9c8134 100644
--- a/src/preprocessor.target.darwin-mips.mk
+++ b/src/preprocessor.target.darwin-mips.mk
@@ -5,7 +5,6 @@
 LOCAL_MODULE_CLASS := STATIC_LIBRARIES
 LOCAL_MODULE := third_party_angle_src_preprocessor_gyp
 LOCAL_MODULE_SUFFIX := .a
-LOCAL_MODULE_TAGS := optional
 LOCAL_MODULE_TARGET_ARCH := $(TARGET_$(GYP_VAR_PREFIX)ARCH)
 gyp_intermediate_dir := $(call local-intermediates-dir,,$(GYP_VAR_PREFIX))
 gyp_shared_intermediate_dir := $(call intermediates-dir-for,GYP,shared,,,$(GYP_VAR_PREFIX))
@@ -41,7 +40,6 @@
 	-fstack-protector \
 	--param=ssp-buffer-size=4 \
 	 \
-	-fno-exceptions \
 	-fno-strict-aliasing \
 	-Wno-unused-parameter \
 	-Wno-missing-field-initializers \
@@ -50,8 +48,6 @@
 	-fPIC \
 	-Wno-unused-local-typedefs \
 	-Wno-format \
-	-EL \
-	-mhard-float \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -70,6 +66,7 @@
 	-Wno-sequence-point \
 	-Os \
 	-g \
+	-gdwarf-4 \
 	-fdata-sections \
 	-ffunction-sections \
 	-fomit-frame-pointer \
@@ -93,11 +90,13 @@
 	'-DENABLE_PRINTING=1' \
 	'-DENABLE_MANAGED_USERS=1' \
 	'-DDATA_REDUCTION_FALLBACK_HOST="http://compress.googlezip.net:80/"' \
-	'-DDATA_REDUCTION_DEV_HOST="http://proxy-dev.googlezip.net:80/"' \
+	'-DDATA_REDUCTION_DEV_HOST="https://proxy-dev.googlezip.net:443/"' \
+	'-DDATA_REDUCTION_DEV_FALLBACK_HOST="http://proxy-dev.googlezip.net:80/"' \
 	'-DSPDY_PROXY_AUTH_ORIGIN="https://proxy.googlezip.net:443/"' \
 	'-DDATA_REDUCTION_PROXY_PROBE_URL="http://check.googlezip.net/connect"' \
 	'-DDATA_REDUCTION_PROXY_WARMUP_URL="http://www.gstatic.com/generate_204"' \
 	'-DVIDEO_HOLE=1' \
+	'-DENABLE_LOAD_COMPLETION_HACKS=1' \
 	'-DUSE_OPENSSL=1' \
 	'-DUSE_OPENSSL_CERTS=1' \
 	'-DANDROID' \
@@ -120,6 +119,7 @@
 
 # Flags passed to only C++ (and not C) files.
 LOCAL_CPPFLAGS_Debug := \
+	-fno-exceptions \
 	-fno-rtti \
 	-fno-threadsafe-statics \
 	-fvisibility-inlines-hidden \
@@ -138,7 +138,6 @@
 	-fstack-protector \
 	--param=ssp-buffer-size=4 \
 	 \
-	-fno-exceptions \
 	-fno-strict-aliasing \
 	-Wno-unused-parameter \
 	-Wno-missing-field-initializers \
@@ -147,8 +146,6 @@
 	-fPIC \
 	-Wno-unused-local-typedefs \
 	-Wno-format \
-	-EL \
-	-mhard-float \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -190,11 +187,13 @@
 	'-DENABLE_PRINTING=1' \
 	'-DENABLE_MANAGED_USERS=1' \
 	'-DDATA_REDUCTION_FALLBACK_HOST="http://compress.googlezip.net:80/"' \
-	'-DDATA_REDUCTION_DEV_HOST="http://proxy-dev.googlezip.net:80/"' \
+	'-DDATA_REDUCTION_DEV_HOST="https://proxy-dev.googlezip.net:443/"' \
+	'-DDATA_REDUCTION_DEV_FALLBACK_HOST="http://proxy-dev.googlezip.net:80/"' \
 	'-DSPDY_PROXY_AUTH_ORIGIN="https://proxy.googlezip.net:443/"' \
 	'-DDATA_REDUCTION_PROXY_PROBE_URL="http://check.googlezip.net/connect"' \
 	'-DDATA_REDUCTION_PROXY_WARMUP_URL="http://www.gstatic.com/generate_204"' \
 	'-DVIDEO_HOLE=1' \
+	'-DENABLE_LOAD_COMPLETION_HACKS=1' \
 	'-DUSE_OPENSSL=1' \
 	'-DUSE_OPENSSL_CERTS=1' \
 	'-DANDROID' \
@@ -217,6 +216,7 @@
 
 # Flags passed to only C++ (and not C) files.
 LOCAL_CPPFLAGS_Release := \
+	-fno-exceptions \
 	-fno-rtti \
 	-fno-threadsafe-statics \
 	-fvisibility-inlines-hidden \
@@ -236,46 +236,6 @@
 LOCAL_ASFLAGS := $(LOCAL_CFLAGS)
 ### Rules for final target.
 
-LOCAL_LDFLAGS_Debug := \
-	-Wl,-z,now \
-	-Wl,-z,relro \
-	-Wl,--fatal-warnings \
-	-Wl,-z,noexecstack \
-	-fPIC \
-	-EL \
-	-Wl,--no-keep-memory \
-	-nostdlib \
-	-Wl,--no-undefined \
-	-Wl,--exclude-libs=ALL \
-	-Wl,--warn-shared-textrel \
-	-Wl,-O1 \
-	-Wl,--as-needed
-
-
-LOCAL_LDFLAGS_Release := \
-	-Wl,-z,now \
-	-Wl,-z,relro \
-	-Wl,--fatal-warnings \
-	-Wl,-z,noexecstack \
-	-fPIC \
-	-EL \
-	-Wl,--no-keep-memory \
-	-nostdlib \
-	-Wl,--no-undefined \
-	-Wl,--exclude-libs=ALL \
-	-Wl,-O1 \
-	-Wl,--as-needed \
-	-Wl,--gc-sections \
-	-Wl,--warn-shared-textrel
-
-
-LOCAL_LDFLAGS := $(LOCAL_LDFLAGS_$(GYP_CONFIGURATION))
-
-LOCAL_STATIC_LIBRARIES :=
-
-# Enable grouping to fix circular references
-LOCAL_GROUP_STATIC_LIBRARIES := true
-
 LOCAL_SHARED_LIBRARIES := \
 	libstlport \
 	libdl
diff --git a/src/preprocessor.target.darwin-x86.mk b/src/preprocessor.target.darwin-x86.mk
index 7963a48..6a0af93 100644
--- a/src/preprocessor.target.darwin-x86.mk
+++ b/src/preprocessor.target.darwin-x86.mk
@@ -5,7 +5,6 @@
 LOCAL_MODULE_CLASS := STATIC_LIBRARIES
 LOCAL_MODULE := third_party_angle_src_preprocessor_gyp
 LOCAL_MODULE_SUFFIX := .a
-LOCAL_MODULE_TAGS := optional
 LOCAL_MODULE_TARGET_ARCH := $(TARGET_$(GYP_VAR_PREFIX)ARCH)
 gyp_intermediate_dir := $(call local-intermediates-dir,,$(GYP_VAR_PREFIX))
 gyp_shared_intermediate_dir := $(call intermediates-dir-for,GYP,shared,,,$(GYP_VAR_PREFIX))
@@ -39,7 +38,6 @@
 # Flags passed to both C and C++ files.
 MY_CFLAGS_Debug := \
 	--param=ssp-buffer-size=4 \
-	-fno-exceptions \
 	-fno-strict-aliasing \
 	-Wno-unused-parameter \
 	-Wno-missing-field-initializers \
@@ -70,6 +68,7 @@
 	-Wno-sequence-point \
 	-Os \
 	-g \
+	-gdwarf-4 \
 	-fdata-sections \
 	-ffunction-sections \
 	-fomit-frame-pointer \
@@ -93,11 +92,13 @@
 	'-DENABLE_PRINTING=1' \
 	'-DENABLE_MANAGED_USERS=1' \
 	'-DDATA_REDUCTION_FALLBACK_HOST="http://compress.googlezip.net:80/"' \
-	'-DDATA_REDUCTION_DEV_HOST="http://proxy-dev.googlezip.net:80/"' \
+	'-DDATA_REDUCTION_DEV_HOST="https://proxy-dev.googlezip.net:443/"' \
+	'-DDATA_REDUCTION_DEV_FALLBACK_HOST="http://proxy-dev.googlezip.net:80/"' \
 	'-DSPDY_PROXY_AUTH_ORIGIN="https://proxy.googlezip.net:443/"' \
 	'-DDATA_REDUCTION_PROXY_PROBE_URL="http://check.googlezip.net/connect"' \
 	'-DDATA_REDUCTION_PROXY_WARMUP_URL="http://www.gstatic.com/generate_204"' \
 	'-DVIDEO_HOLE=1' \
+	'-DENABLE_LOAD_COMPLETION_HACKS=1' \
 	'-DUSE_OPENSSL=1' \
 	'-DUSE_OPENSSL_CERTS=1' \
 	'-DANDROID' \
@@ -120,6 +121,7 @@
 
 # Flags passed to only C++ (and not C) files.
 LOCAL_CPPFLAGS_Debug := \
+	-fno-exceptions \
 	-fno-rtti \
 	-fno-threadsafe-statics \
 	-fvisibility-inlines-hidden \
@@ -135,7 +137,6 @@
 # Flags passed to both C and C++ files.
 MY_CFLAGS_Release := \
 	--param=ssp-buffer-size=4 \
-	-fno-exceptions \
 	-fno-strict-aliasing \
 	-Wno-unused-parameter \
 	-Wno-missing-field-initializers \
@@ -189,11 +190,13 @@
 	'-DENABLE_PRINTING=1' \
 	'-DENABLE_MANAGED_USERS=1' \
 	'-DDATA_REDUCTION_FALLBACK_HOST="http://compress.googlezip.net:80/"' \
-	'-DDATA_REDUCTION_DEV_HOST="http://proxy-dev.googlezip.net:80/"' \
+	'-DDATA_REDUCTION_DEV_HOST="https://proxy-dev.googlezip.net:443/"' \
+	'-DDATA_REDUCTION_DEV_FALLBACK_HOST="http://proxy-dev.googlezip.net:80/"' \
 	'-DSPDY_PROXY_AUTH_ORIGIN="https://proxy.googlezip.net:443/"' \
 	'-DDATA_REDUCTION_PROXY_PROBE_URL="http://check.googlezip.net/connect"' \
 	'-DDATA_REDUCTION_PROXY_WARMUP_URL="http://www.gstatic.com/generate_204"' \
 	'-DVIDEO_HOLE=1' \
+	'-DENABLE_LOAD_COMPLETION_HACKS=1' \
 	'-DUSE_OPENSSL=1' \
 	'-DUSE_OPENSSL_CERTS=1' \
 	'-DANDROID' \
@@ -216,6 +219,7 @@
 
 # Flags passed to only C++ (and not C) files.
 LOCAL_CPPFLAGS_Release := \
+	-fno-exceptions \
 	-fno-rtti \
 	-fno-threadsafe-statics \
 	-fvisibility-inlines-hidden \
@@ -234,46 +238,6 @@
 LOCAL_ASFLAGS := $(LOCAL_CFLAGS)
 ### Rules for final target.
 
-LOCAL_LDFLAGS_Debug := \
-	-Wl,-z,now \
-	-Wl,-z,relro \
-	-Wl,--fatal-warnings \
-	-Wl,-z,noexecstack \
-	-fPIC \
-	-m32 \
-	-fuse-ld=gold \
-	-nostdlib \
-	-Wl,--no-undefined \
-	-Wl,--exclude-libs=ALL \
-	-Wl,--warn-shared-textrel \
-	-Wl,-O1 \
-	-Wl,--as-needed
-
-
-LOCAL_LDFLAGS_Release := \
-	-Wl,-z,now \
-	-Wl,-z,relro \
-	-Wl,--fatal-warnings \
-	-Wl,-z,noexecstack \
-	-fPIC \
-	-m32 \
-	-fuse-ld=gold \
-	-nostdlib \
-	-Wl,--no-undefined \
-	-Wl,--exclude-libs=ALL \
-	-Wl,-O1 \
-	-Wl,--as-needed \
-	-Wl,--gc-sections \
-	-Wl,--warn-shared-textrel
-
-
-LOCAL_LDFLAGS := $(LOCAL_LDFLAGS_$(GYP_CONFIGURATION))
-
-LOCAL_STATIC_LIBRARIES :=
-
-# Enable grouping to fix circular references
-LOCAL_GROUP_STATIC_LIBRARIES := true
-
 LOCAL_SHARED_LIBRARIES := \
 	libstlport \
 	libdl
diff --git a/src/preprocessor.target.darwin-x86_64.mk b/src/preprocessor.target.darwin-x86_64.mk
index 8426433..bea6d21 100644
--- a/src/preprocessor.target.darwin-x86_64.mk
+++ b/src/preprocessor.target.darwin-x86_64.mk
@@ -5,7 +5,6 @@
 LOCAL_MODULE_CLASS := STATIC_LIBRARIES
 LOCAL_MODULE := third_party_angle_src_preprocessor_gyp
 LOCAL_MODULE_SUFFIX := .a
-LOCAL_MODULE_TAGS := optional
 LOCAL_MODULE_TARGET_ARCH := $(TARGET_$(GYP_VAR_PREFIX)ARCH)
 gyp_intermediate_dir := $(call local-intermediates-dir,,$(GYP_VAR_PREFIX))
 gyp_shared_intermediate_dir := $(call intermediates-dir-for,GYP,shared,,,$(GYP_VAR_PREFIX))
@@ -40,7 +39,6 @@
 MY_CFLAGS_Debug := \
 	-fstack-protector \
 	--param=ssp-buffer-size=4 \
-	-fno-exceptions \
 	-fno-strict-aliasing \
 	-Wno-unused-parameter \
 	-Wno-missing-field-initializers \
@@ -69,6 +67,7 @@
 	-Wno-sequence-point \
 	-Os \
 	-g \
+	-gdwarf-4 \
 	-fdata-sections \
 	-ffunction-sections \
 	-fomit-frame-pointer \
@@ -92,11 +91,13 @@
 	'-DENABLE_PRINTING=1' \
 	'-DENABLE_MANAGED_USERS=1' \
 	'-DDATA_REDUCTION_FALLBACK_HOST="http://compress.googlezip.net:80/"' \
-	'-DDATA_REDUCTION_DEV_HOST="http://proxy-dev.googlezip.net:80/"' \
+	'-DDATA_REDUCTION_DEV_HOST="https://proxy-dev.googlezip.net:443/"' \
+	'-DDATA_REDUCTION_DEV_FALLBACK_HOST="http://proxy-dev.googlezip.net:80/"' \
 	'-DSPDY_PROXY_AUTH_ORIGIN="https://proxy.googlezip.net:443/"' \
 	'-DDATA_REDUCTION_PROXY_PROBE_URL="http://check.googlezip.net/connect"' \
 	'-DDATA_REDUCTION_PROXY_WARMUP_URL="http://www.gstatic.com/generate_204"' \
 	'-DVIDEO_HOLE=1' \
+	'-DENABLE_LOAD_COMPLETION_HACKS=1' \
 	'-DUSE_OPENSSL=1' \
 	'-DUSE_OPENSSL_CERTS=1' \
 	'-DANDROID' \
@@ -119,6 +120,7 @@
 
 # Flags passed to only C++ (and not C) files.
 LOCAL_CPPFLAGS_Debug := \
+	-fno-exceptions \
 	-fno-rtti \
 	-fno-threadsafe-statics \
 	-fvisibility-inlines-hidden \
@@ -135,7 +137,6 @@
 MY_CFLAGS_Release := \
 	-fstack-protector \
 	--param=ssp-buffer-size=4 \
-	-fno-exceptions \
 	-fno-strict-aliasing \
 	-Wno-unused-parameter \
 	-Wno-missing-field-initializers \
@@ -187,11 +188,13 @@
 	'-DENABLE_PRINTING=1' \
 	'-DENABLE_MANAGED_USERS=1' \
 	'-DDATA_REDUCTION_FALLBACK_HOST="http://compress.googlezip.net:80/"' \
-	'-DDATA_REDUCTION_DEV_HOST="http://proxy-dev.googlezip.net:80/"' \
+	'-DDATA_REDUCTION_DEV_HOST="https://proxy-dev.googlezip.net:443/"' \
+	'-DDATA_REDUCTION_DEV_FALLBACK_HOST="http://proxy-dev.googlezip.net:80/"' \
 	'-DSPDY_PROXY_AUTH_ORIGIN="https://proxy.googlezip.net:443/"' \
 	'-DDATA_REDUCTION_PROXY_PROBE_URL="http://check.googlezip.net/connect"' \
 	'-DDATA_REDUCTION_PROXY_WARMUP_URL="http://www.gstatic.com/generate_204"' \
 	'-DVIDEO_HOLE=1' \
+	'-DENABLE_LOAD_COMPLETION_HACKS=1' \
 	'-DUSE_OPENSSL=1' \
 	'-DUSE_OPENSSL_CERTS=1' \
 	'-DANDROID' \
@@ -214,6 +217,7 @@
 
 # Flags passed to only C++ (and not C) files.
 LOCAL_CPPFLAGS_Release := \
+	-fno-exceptions \
 	-fno-rtti \
 	-fno-threadsafe-statics \
 	-fvisibility-inlines-hidden \
@@ -232,46 +236,6 @@
 LOCAL_ASFLAGS := $(LOCAL_CFLAGS)
 ### Rules for final target.
 
-LOCAL_LDFLAGS_Debug := \
-	-Wl,-z,now \
-	-Wl,-z,relro \
-	-Wl,--fatal-warnings \
-	-Wl,-z,noexecstack \
-	-fPIC \
-	-m64 \
-	-fuse-ld=gold \
-	-nostdlib \
-	-Wl,--no-undefined \
-	-Wl,--exclude-libs=ALL \
-	-Wl,--warn-shared-textrel \
-	-Wl,-O1 \
-	-Wl,--as-needed
-
-
-LOCAL_LDFLAGS_Release := \
-	-Wl,-z,now \
-	-Wl,-z,relro \
-	-Wl,--fatal-warnings \
-	-Wl,-z,noexecstack \
-	-fPIC \
-	-m64 \
-	-fuse-ld=gold \
-	-nostdlib \
-	-Wl,--no-undefined \
-	-Wl,--exclude-libs=ALL \
-	-Wl,-O1 \
-	-Wl,--as-needed \
-	-Wl,--gc-sections \
-	-Wl,--warn-shared-textrel
-
-
-LOCAL_LDFLAGS := $(LOCAL_LDFLAGS_$(GYP_CONFIGURATION))
-
-LOCAL_STATIC_LIBRARIES :=
-
-# Enable grouping to fix circular references
-LOCAL_GROUP_STATIC_LIBRARIES := true
-
 LOCAL_SHARED_LIBRARIES := \
 	libstlport \
 	libdl
diff --git a/src/preprocessor.target.linux-arm.mk b/src/preprocessor.target.linux-arm.mk
index eb16ba7..5a333ac 100644
--- a/src/preprocessor.target.linux-arm.mk
+++ b/src/preprocessor.target.linux-arm.mk
@@ -5,7 +5,6 @@
 LOCAL_MODULE_CLASS := STATIC_LIBRARIES
 LOCAL_MODULE := third_party_angle_src_preprocessor_gyp
 LOCAL_MODULE_SUFFIX := .a
-LOCAL_MODULE_TAGS := optional
 LOCAL_MODULE_TARGET_ARCH := $(TARGET_$(GYP_VAR_PREFIX)ARCH)
 gyp_intermediate_dir := $(call local-intermediates-dir,,$(GYP_VAR_PREFIX))
 gyp_shared_intermediate_dir := $(call intermediates-dir-for,GYP,shared,,,$(GYP_VAR_PREFIX))
@@ -40,7 +39,6 @@
 MY_CFLAGS_Debug := \
 	-fstack-protector \
 	--param=ssp-buffer-size=4 \
-	-fno-exceptions \
 	-fno-strict-aliasing \
 	-Wno-unused-parameter \
 	-Wno-missing-field-initializers \
@@ -50,13 +48,13 @@
 	-Wno-unused-local-typedefs \
 	-Wno-format \
 	-fno-tree-sra \
+	-fno-caller-saves \
+	-Wno-psabi \
 	-fno-partial-inlining \
 	-fno-early-inlining \
 	-fno-tree-copy-prop \
 	-fno-tree-loop-optimize \
 	-fno-move-loop-invariants \
-	-fno-caller-saves \
-	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -75,6 +73,7 @@
 	-Wno-sequence-point \
 	-Os \
 	-g \
+	-gdwarf-4 \
 	-fdata-sections \
 	-ffunction-sections \
 	-fomit-frame-pointer \
@@ -98,11 +97,13 @@
 	'-DENABLE_PRINTING=1' \
 	'-DENABLE_MANAGED_USERS=1' \
 	'-DDATA_REDUCTION_FALLBACK_HOST="http://compress.googlezip.net:80/"' \
-	'-DDATA_REDUCTION_DEV_HOST="http://proxy-dev.googlezip.net:80/"' \
+	'-DDATA_REDUCTION_DEV_HOST="https://proxy-dev.googlezip.net:443/"' \
+	'-DDATA_REDUCTION_DEV_FALLBACK_HOST="http://proxy-dev.googlezip.net:80/"' \
 	'-DSPDY_PROXY_AUTH_ORIGIN="https://proxy.googlezip.net:443/"' \
 	'-DDATA_REDUCTION_PROXY_PROBE_URL="http://check.googlezip.net/connect"' \
 	'-DDATA_REDUCTION_PROXY_WARMUP_URL="http://www.gstatic.com/generate_204"' \
 	'-DVIDEO_HOLE=1' \
+	'-DENABLE_LOAD_COMPLETION_HACKS=1' \
 	'-DUSE_OPENSSL=1' \
 	'-DUSE_OPENSSL_CERTS=1' \
 	'-DANDROID' \
@@ -125,6 +126,7 @@
 
 # Flags passed to only C++ (and not C) files.
 LOCAL_CPPFLAGS_Debug := \
+	-fno-exceptions \
 	-fno-rtti \
 	-fno-threadsafe-statics \
 	-fvisibility-inlines-hidden \
@@ -142,7 +144,6 @@
 MY_CFLAGS_Release := \
 	-fstack-protector \
 	--param=ssp-buffer-size=4 \
-	-fno-exceptions \
 	-fno-strict-aliasing \
 	-Wno-unused-parameter \
 	-Wno-missing-field-initializers \
@@ -152,13 +153,13 @@
 	-Wno-unused-local-typedefs \
 	-Wno-format \
 	-fno-tree-sra \
+	-fno-caller-saves \
+	-Wno-psabi \
 	-fno-partial-inlining \
 	-fno-early-inlining \
 	-fno-tree-copy-prop \
 	-fno-tree-loop-optimize \
 	-fno-move-loop-invariants \
-	-fno-caller-saves \
-	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -200,11 +201,13 @@
 	'-DENABLE_PRINTING=1' \
 	'-DENABLE_MANAGED_USERS=1' \
 	'-DDATA_REDUCTION_FALLBACK_HOST="http://compress.googlezip.net:80/"' \
-	'-DDATA_REDUCTION_DEV_HOST="http://proxy-dev.googlezip.net:80/"' \
+	'-DDATA_REDUCTION_DEV_HOST="https://proxy-dev.googlezip.net:443/"' \
+	'-DDATA_REDUCTION_DEV_FALLBACK_HOST="http://proxy-dev.googlezip.net:80/"' \
 	'-DSPDY_PROXY_AUTH_ORIGIN="https://proxy.googlezip.net:443/"' \
 	'-DDATA_REDUCTION_PROXY_PROBE_URL="http://check.googlezip.net/connect"' \
 	'-DDATA_REDUCTION_PROXY_WARMUP_URL="http://www.gstatic.com/generate_204"' \
 	'-DVIDEO_HOLE=1' \
+	'-DENABLE_LOAD_COMPLETION_HACKS=1' \
 	'-DUSE_OPENSSL=1' \
 	'-DUSE_OPENSSL_CERTS=1' \
 	'-DANDROID' \
@@ -227,6 +230,7 @@
 
 # Flags passed to only C++ (and not C) files.
 LOCAL_CPPFLAGS_Release := \
+	-fno-exceptions \
 	-fno-rtti \
 	-fno-threadsafe-statics \
 	-fvisibility-inlines-hidden \
@@ -246,50 +250,6 @@
 LOCAL_ASFLAGS := $(LOCAL_CFLAGS)
 ### Rules for final target.
 
-LOCAL_LDFLAGS_Debug := \
-	-Wl,-z,now \
-	-Wl,-z,relro \
-	-Wl,--fatal-warnings \
-	-Wl,-z,noexecstack \
-	-fPIC \
-	-Wl,-z,relro \
-	-Wl,-z,now \
-	-fuse-ld=gold \
-	-nostdlib \
-	-Wl,--no-undefined \
-	-Wl,--exclude-libs=ALL \
-	-Wl,--icf=safe \
-	-Wl,--warn-shared-textrel \
-	-Wl,-O1 \
-	-Wl,--as-needed
-
-
-LOCAL_LDFLAGS_Release := \
-	-Wl,-z,now \
-	-Wl,-z,relro \
-	-Wl,--fatal-warnings \
-	-Wl,-z,noexecstack \
-	-fPIC \
-	-Wl,-z,relro \
-	-Wl,-z,now \
-	-fuse-ld=gold \
-	-nostdlib \
-	-Wl,--no-undefined \
-	-Wl,--exclude-libs=ALL \
-	-Wl,--icf=safe \
-	-Wl,-O1 \
-	-Wl,--as-needed \
-	-Wl,--gc-sections \
-	-Wl,--warn-shared-textrel
-
-
-LOCAL_LDFLAGS := $(LOCAL_LDFLAGS_$(GYP_CONFIGURATION))
-
-LOCAL_STATIC_LIBRARIES :=
-
-# Enable grouping to fix circular references
-LOCAL_GROUP_STATIC_LIBRARIES := true
-
 LOCAL_SHARED_LIBRARIES := \
 	libstlport \
 	libdl
diff --git a/src/preprocessor.target.linux-arm64.mk b/src/preprocessor.target.linux-arm64.mk
index ace2cfd..97caadc 100644
--- a/src/preprocessor.target.linux-arm64.mk
+++ b/src/preprocessor.target.linux-arm64.mk
@@ -5,7 +5,6 @@
 LOCAL_MODULE_CLASS := STATIC_LIBRARIES
 LOCAL_MODULE := third_party_angle_src_preprocessor_gyp
 LOCAL_MODULE_SUFFIX := .a
-LOCAL_MODULE_TAGS := optional
 LOCAL_MODULE_TARGET_ARCH := $(TARGET_$(GYP_VAR_PREFIX)ARCH)
 gyp_intermediate_dir := $(call local-intermediates-dir,,$(GYP_VAR_PREFIX))
 gyp_shared_intermediate_dir := $(call intermediates-dir-for,GYP,shared,,,$(GYP_VAR_PREFIX))
@@ -39,7 +38,6 @@
 # Flags passed to both C and C++ files.
 MY_CFLAGS_Debug := \
 	--param=ssp-buffer-size=4 \
-	-fno-exceptions \
 	-fno-strict-aliasing \
 	-Wno-unused-parameter \
 	-Wno-missing-field-initializers \
@@ -65,6 +63,7 @@
 	-Wno-sequence-point \
 	-Os \
 	-g \
+	-gdwarf-4 \
 	-fdata-sections \
 	-ffunction-sections \
 	-funwind-tables
@@ -87,11 +86,13 @@
 	'-DENABLE_PRINTING=1' \
 	'-DENABLE_MANAGED_USERS=1' \
 	'-DDATA_REDUCTION_FALLBACK_HOST="http://compress.googlezip.net:80/"' \
-	'-DDATA_REDUCTION_DEV_HOST="http://proxy-dev.googlezip.net:80/"' \
+	'-DDATA_REDUCTION_DEV_HOST="https://proxy-dev.googlezip.net:443/"' \
+	'-DDATA_REDUCTION_DEV_FALLBACK_HOST="http://proxy-dev.googlezip.net:80/"' \
 	'-DSPDY_PROXY_AUTH_ORIGIN="https://proxy.googlezip.net:443/"' \
 	'-DDATA_REDUCTION_PROXY_PROBE_URL="http://check.googlezip.net/connect"' \
 	'-DDATA_REDUCTION_PROXY_WARMUP_URL="http://www.gstatic.com/generate_204"' \
 	'-DVIDEO_HOLE=1' \
+	'-DENABLE_LOAD_COMPLETION_HACKS=1' \
 	'-DUSE_OPENSSL=1' \
 	'-DUSE_OPENSSL_CERTS=1' \
 	'-DANDROID' \
@@ -114,6 +115,7 @@
 
 # Flags passed to only C++ (and not C) files.
 LOCAL_CPPFLAGS_Debug := \
+	-fno-exceptions \
 	-fno-rtti \
 	-fno-threadsafe-statics \
 	-fvisibility-inlines-hidden \
@@ -129,7 +131,6 @@
 # Flags passed to both C and C++ files.
 MY_CFLAGS_Release := \
 	--param=ssp-buffer-size=4 \
-	-fno-exceptions \
 	-fno-strict-aliasing \
 	-Wno-unused-parameter \
 	-Wno-missing-field-initializers \
@@ -177,11 +178,13 @@
 	'-DENABLE_PRINTING=1' \
 	'-DENABLE_MANAGED_USERS=1' \
 	'-DDATA_REDUCTION_FALLBACK_HOST="http://compress.googlezip.net:80/"' \
-	'-DDATA_REDUCTION_DEV_HOST="http://proxy-dev.googlezip.net:80/"' \
+	'-DDATA_REDUCTION_DEV_HOST="https://proxy-dev.googlezip.net:443/"' \
+	'-DDATA_REDUCTION_DEV_FALLBACK_HOST="http://proxy-dev.googlezip.net:80/"' \
 	'-DSPDY_PROXY_AUTH_ORIGIN="https://proxy.googlezip.net:443/"' \
 	'-DDATA_REDUCTION_PROXY_PROBE_URL="http://check.googlezip.net/connect"' \
 	'-DDATA_REDUCTION_PROXY_WARMUP_URL="http://www.gstatic.com/generate_204"' \
 	'-DVIDEO_HOLE=1' \
+	'-DENABLE_LOAD_COMPLETION_HACKS=1' \
 	'-DUSE_OPENSSL=1' \
 	'-DUSE_OPENSSL_CERTS=1' \
 	'-DANDROID' \
@@ -204,6 +207,7 @@
 
 # Flags passed to only C++ (and not C) files.
 LOCAL_CPPFLAGS_Release := \
+	-fno-exceptions \
 	-fno-rtti \
 	-fno-threadsafe-statics \
 	-fvisibility-inlines-hidden \
@@ -222,42 +226,6 @@
 LOCAL_ASFLAGS := $(LOCAL_CFLAGS)
 ### Rules for final target.
 
-LOCAL_LDFLAGS_Debug := \
-	-Wl,-z,now \
-	-Wl,-z,relro \
-	-Wl,--fatal-warnings \
-	-Wl,-z,noexecstack \
-	-fPIC \
-	-nostdlib \
-	-Wl,--no-undefined \
-	-Wl,--exclude-libs=ALL \
-	-Wl,--warn-shared-textrel \
-	-Wl,-O1 \
-	-Wl,--as-needed
-
-
-LOCAL_LDFLAGS_Release := \
-	-Wl,-z,now \
-	-Wl,-z,relro \
-	-Wl,--fatal-warnings \
-	-Wl,-z,noexecstack \
-	-fPIC \
-	-nostdlib \
-	-Wl,--no-undefined \
-	-Wl,--exclude-libs=ALL \
-	-Wl,-O1 \
-	-Wl,--as-needed \
-	-Wl,--gc-sections \
-	-Wl,--warn-shared-textrel
-
-
-LOCAL_LDFLAGS := $(LOCAL_LDFLAGS_$(GYP_CONFIGURATION))
-
-LOCAL_STATIC_LIBRARIES :=
-
-# Enable grouping to fix circular references
-LOCAL_GROUP_STATIC_LIBRARIES := true
-
 LOCAL_SHARED_LIBRARIES := \
 	libstlport \
 	libdl
diff --git a/src/preprocessor.target.linux-mips.mk b/src/preprocessor.target.linux-mips.mk
index c6b1c54..c9c8134 100644
--- a/src/preprocessor.target.linux-mips.mk
+++ b/src/preprocessor.target.linux-mips.mk
@@ -5,7 +5,6 @@
 LOCAL_MODULE_CLASS := STATIC_LIBRARIES
 LOCAL_MODULE := third_party_angle_src_preprocessor_gyp
 LOCAL_MODULE_SUFFIX := .a
-LOCAL_MODULE_TAGS := optional
 LOCAL_MODULE_TARGET_ARCH := $(TARGET_$(GYP_VAR_PREFIX)ARCH)
 gyp_intermediate_dir := $(call local-intermediates-dir,,$(GYP_VAR_PREFIX))
 gyp_shared_intermediate_dir := $(call intermediates-dir-for,GYP,shared,,,$(GYP_VAR_PREFIX))
@@ -41,7 +40,6 @@
 	-fstack-protector \
 	--param=ssp-buffer-size=4 \
 	 \
-	-fno-exceptions \
 	-fno-strict-aliasing \
 	-Wno-unused-parameter \
 	-Wno-missing-field-initializers \
@@ -50,8 +48,6 @@
 	-fPIC \
 	-Wno-unused-local-typedefs \
 	-Wno-format \
-	-EL \
-	-mhard-float \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -70,6 +66,7 @@
 	-Wno-sequence-point \
 	-Os \
 	-g \
+	-gdwarf-4 \
 	-fdata-sections \
 	-ffunction-sections \
 	-fomit-frame-pointer \
@@ -93,11 +90,13 @@
 	'-DENABLE_PRINTING=1' \
 	'-DENABLE_MANAGED_USERS=1' \
 	'-DDATA_REDUCTION_FALLBACK_HOST="http://compress.googlezip.net:80/"' \
-	'-DDATA_REDUCTION_DEV_HOST="http://proxy-dev.googlezip.net:80/"' \
+	'-DDATA_REDUCTION_DEV_HOST="https://proxy-dev.googlezip.net:443/"' \
+	'-DDATA_REDUCTION_DEV_FALLBACK_HOST="http://proxy-dev.googlezip.net:80/"' \
 	'-DSPDY_PROXY_AUTH_ORIGIN="https://proxy.googlezip.net:443/"' \
 	'-DDATA_REDUCTION_PROXY_PROBE_URL="http://check.googlezip.net/connect"' \
 	'-DDATA_REDUCTION_PROXY_WARMUP_URL="http://www.gstatic.com/generate_204"' \
 	'-DVIDEO_HOLE=1' \
+	'-DENABLE_LOAD_COMPLETION_HACKS=1' \
 	'-DUSE_OPENSSL=1' \
 	'-DUSE_OPENSSL_CERTS=1' \
 	'-DANDROID' \
@@ -120,6 +119,7 @@
 
 # Flags passed to only C++ (and not C) files.
 LOCAL_CPPFLAGS_Debug := \
+	-fno-exceptions \
 	-fno-rtti \
 	-fno-threadsafe-statics \
 	-fvisibility-inlines-hidden \
@@ -138,7 +138,6 @@
 	-fstack-protector \
 	--param=ssp-buffer-size=4 \
 	 \
-	-fno-exceptions \
 	-fno-strict-aliasing \
 	-Wno-unused-parameter \
 	-Wno-missing-field-initializers \
@@ -147,8 +146,6 @@
 	-fPIC \
 	-Wno-unused-local-typedefs \
 	-Wno-format \
-	-EL \
-	-mhard-float \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -190,11 +187,13 @@
 	'-DENABLE_PRINTING=1' \
 	'-DENABLE_MANAGED_USERS=1' \
 	'-DDATA_REDUCTION_FALLBACK_HOST="http://compress.googlezip.net:80/"' \
-	'-DDATA_REDUCTION_DEV_HOST="http://proxy-dev.googlezip.net:80/"' \
+	'-DDATA_REDUCTION_DEV_HOST="https://proxy-dev.googlezip.net:443/"' \
+	'-DDATA_REDUCTION_DEV_FALLBACK_HOST="http://proxy-dev.googlezip.net:80/"' \
 	'-DSPDY_PROXY_AUTH_ORIGIN="https://proxy.googlezip.net:443/"' \
 	'-DDATA_REDUCTION_PROXY_PROBE_URL="http://check.googlezip.net/connect"' \
 	'-DDATA_REDUCTION_PROXY_WARMUP_URL="http://www.gstatic.com/generate_204"' \
 	'-DVIDEO_HOLE=1' \
+	'-DENABLE_LOAD_COMPLETION_HACKS=1' \
 	'-DUSE_OPENSSL=1' \
 	'-DUSE_OPENSSL_CERTS=1' \
 	'-DANDROID' \
@@ -217,6 +216,7 @@
 
 # Flags passed to only C++ (and not C) files.
 LOCAL_CPPFLAGS_Release := \
+	-fno-exceptions \
 	-fno-rtti \
 	-fno-threadsafe-statics \
 	-fvisibility-inlines-hidden \
@@ -236,46 +236,6 @@
 LOCAL_ASFLAGS := $(LOCAL_CFLAGS)
 ### Rules for final target.
 
-LOCAL_LDFLAGS_Debug := \
-	-Wl,-z,now \
-	-Wl,-z,relro \
-	-Wl,--fatal-warnings \
-	-Wl,-z,noexecstack \
-	-fPIC \
-	-EL \
-	-Wl,--no-keep-memory \
-	-nostdlib \
-	-Wl,--no-undefined \
-	-Wl,--exclude-libs=ALL \
-	-Wl,--warn-shared-textrel \
-	-Wl,-O1 \
-	-Wl,--as-needed
-
-
-LOCAL_LDFLAGS_Release := \
-	-Wl,-z,now \
-	-Wl,-z,relro \
-	-Wl,--fatal-warnings \
-	-Wl,-z,noexecstack \
-	-fPIC \
-	-EL \
-	-Wl,--no-keep-memory \
-	-nostdlib \
-	-Wl,--no-undefined \
-	-Wl,--exclude-libs=ALL \
-	-Wl,-O1 \
-	-Wl,--as-needed \
-	-Wl,--gc-sections \
-	-Wl,--warn-shared-textrel
-
-
-LOCAL_LDFLAGS := $(LOCAL_LDFLAGS_$(GYP_CONFIGURATION))
-
-LOCAL_STATIC_LIBRARIES :=
-
-# Enable grouping to fix circular references
-LOCAL_GROUP_STATIC_LIBRARIES := true
-
 LOCAL_SHARED_LIBRARIES := \
 	libstlport \
 	libdl
diff --git a/src/preprocessor.target.linux-x86.mk b/src/preprocessor.target.linux-x86.mk
index 7963a48..6a0af93 100644
--- a/src/preprocessor.target.linux-x86.mk
+++ b/src/preprocessor.target.linux-x86.mk
@@ -5,7 +5,6 @@
 LOCAL_MODULE_CLASS := STATIC_LIBRARIES
 LOCAL_MODULE := third_party_angle_src_preprocessor_gyp
 LOCAL_MODULE_SUFFIX := .a
-LOCAL_MODULE_TAGS := optional
 LOCAL_MODULE_TARGET_ARCH := $(TARGET_$(GYP_VAR_PREFIX)ARCH)
 gyp_intermediate_dir := $(call local-intermediates-dir,,$(GYP_VAR_PREFIX))
 gyp_shared_intermediate_dir := $(call intermediates-dir-for,GYP,shared,,,$(GYP_VAR_PREFIX))
@@ -39,7 +38,6 @@
 # Flags passed to both C and C++ files.
 MY_CFLAGS_Debug := \
 	--param=ssp-buffer-size=4 \
-	-fno-exceptions \
 	-fno-strict-aliasing \
 	-Wno-unused-parameter \
 	-Wno-missing-field-initializers \
@@ -70,6 +68,7 @@
 	-Wno-sequence-point \
 	-Os \
 	-g \
+	-gdwarf-4 \
 	-fdata-sections \
 	-ffunction-sections \
 	-fomit-frame-pointer \
@@ -93,11 +92,13 @@
 	'-DENABLE_PRINTING=1' \
 	'-DENABLE_MANAGED_USERS=1' \
 	'-DDATA_REDUCTION_FALLBACK_HOST="http://compress.googlezip.net:80/"' \
-	'-DDATA_REDUCTION_DEV_HOST="http://proxy-dev.googlezip.net:80/"' \
+	'-DDATA_REDUCTION_DEV_HOST="https://proxy-dev.googlezip.net:443/"' \
+	'-DDATA_REDUCTION_DEV_FALLBACK_HOST="http://proxy-dev.googlezip.net:80/"' \
 	'-DSPDY_PROXY_AUTH_ORIGIN="https://proxy.googlezip.net:443/"' \
 	'-DDATA_REDUCTION_PROXY_PROBE_URL="http://check.googlezip.net/connect"' \
 	'-DDATA_REDUCTION_PROXY_WARMUP_URL="http://www.gstatic.com/generate_204"' \
 	'-DVIDEO_HOLE=1' \
+	'-DENABLE_LOAD_COMPLETION_HACKS=1' \
 	'-DUSE_OPENSSL=1' \
 	'-DUSE_OPENSSL_CERTS=1' \
 	'-DANDROID' \
@@ -120,6 +121,7 @@
 
 # Flags passed to only C++ (and not C) files.
 LOCAL_CPPFLAGS_Debug := \
+	-fno-exceptions \
 	-fno-rtti \
 	-fno-threadsafe-statics \
 	-fvisibility-inlines-hidden \
@@ -135,7 +137,6 @@
 # Flags passed to both C and C++ files.
 MY_CFLAGS_Release := \
 	--param=ssp-buffer-size=4 \
-	-fno-exceptions \
 	-fno-strict-aliasing \
 	-Wno-unused-parameter \
 	-Wno-missing-field-initializers \
@@ -189,11 +190,13 @@
 	'-DENABLE_PRINTING=1' \
 	'-DENABLE_MANAGED_USERS=1' \
 	'-DDATA_REDUCTION_FALLBACK_HOST="http://compress.googlezip.net:80/"' \
-	'-DDATA_REDUCTION_DEV_HOST="http://proxy-dev.googlezip.net:80/"' \
+	'-DDATA_REDUCTION_DEV_HOST="https://proxy-dev.googlezip.net:443/"' \
+	'-DDATA_REDUCTION_DEV_FALLBACK_HOST="http://proxy-dev.googlezip.net:80/"' \
 	'-DSPDY_PROXY_AUTH_ORIGIN="https://proxy.googlezip.net:443/"' \
 	'-DDATA_REDUCTION_PROXY_PROBE_URL="http://check.googlezip.net/connect"' \
 	'-DDATA_REDUCTION_PROXY_WARMUP_URL="http://www.gstatic.com/generate_204"' \
 	'-DVIDEO_HOLE=1' \
+	'-DENABLE_LOAD_COMPLETION_HACKS=1' \
 	'-DUSE_OPENSSL=1' \
 	'-DUSE_OPENSSL_CERTS=1' \
 	'-DANDROID' \
@@ -216,6 +219,7 @@
 
 # Flags passed to only C++ (and not C) files.
 LOCAL_CPPFLAGS_Release := \
+	-fno-exceptions \
 	-fno-rtti \
 	-fno-threadsafe-statics \
 	-fvisibility-inlines-hidden \
@@ -234,46 +238,6 @@
 LOCAL_ASFLAGS := $(LOCAL_CFLAGS)
 ### Rules for final target.
 
-LOCAL_LDFLAGS_Debug := \
-	-Wl,-z,now \
-	-Wl,-z,relro \
-	-Wl,--fatal-warnings \
-	-Wl,-z,noexecstack \
-	-fPIC \
-	-m32 \
-	-fuse-ld=gold \
-	-nostdlib \
-	-Wl,--no-undefined \
-	-Wl,--exclude-libs=ALL \
-	-Wl,--warn-shared-textrel \
-	-Wl,-O1 \
-	-Wl,--as-needed
-
-
-LOCAL_LDFLAGS_Release := \
-	-Wl,-z,now \
-	-Wl,-z,relro \
-	-Wl,--fatal-warnings \
-	-Wl,-z,noexecstack \
-	-fPIC \
-	-m32 \
-	-fuse-ld=gold \
-	-nostdlib \
-	-Wl,--no-undefined \
-	-Wl,--exclude-libs=ALL \
-	-Wl,-O1 \
-	-Wl,--as-needed \
-	-Wl,--gc-sections \
-	-Wl,--warn-shared-textrel
-
-
-LOCAL_LDFLAGS := $(LOCAL_LDFLAGS_$(GYP_CONFIGURATION))
-
-LOCAL_STATIC_LIBRARIES :=
-
-# Enable grouping to fix circular references
-LOCAL_GROUP_STATIC_LIBRARIES := true
-
 LOCAL_SHARED_LIBRARIES := \
 	libstlport \
 	libdl
diff --git a/src/preprocessor.target.linux-x86_64.mk b/src/preprocessor.target.linux-x86_64.mk
index 8426433..bea6d21 100644
--- a/src/preprocessor.target.linux-x86_64.mk
+++ b/src/preprocessor.target.linux-x86_64.mk
@@ -5,7 +5,6 @@
 LOCAL_MODULE_CLASS := STATIC_LIBRARIES
 LOCAL_MODULE := third_party_angle_src_preprocessor_gyp
 LOCAL_MODULE_SUFFIX := .a
-LOCAL_MODULE_TAGS := optional
 LOCAL_MODULE_TARGET_ARCH := $(TARGET_$(GYP_VAR_PREFIX)ARCH)
 gyp_intermediate_dir := $(call local-intermediates-dir,,$(GYP_VAR_PREFIX))
 gyp_shared_intermediate_dir := $(call intermediates-dir-for,GYP,shared,,,$(GYP_VAR_PREFIX))
@@ -40,7 +39,6 @@
 MY_CFLAGS_Debug := \
 	-fstack-protector \
 	--param=ssp-buffer-size=4 \
-	-fno-exceptions \
 	-fno-strict-aliasing \
 	-Wno-unused-parameter \
 	-Wno-missing-field-initializers \
@@ -69,6 +67,7 @@
 	-Wno-sequence-point \
 	-Os \
 	-g \
+	-gdwarf-4 \
 	-fdata-sections \
 	-ffunction-sections \
 	-fomit-frame-pointer \
@@ -92,11 +91,13 @@
 	'-DENABLE_PRINTING=1' \
 	'-DENABLE_MANAGED_USERS=1' \
 	'-DDATA_REDUCTION_FALLBACK_HOST="http://compress.googlezip.net:80/"' \
-	'-DDATA_REDUCTION_DEV_HOST="http://proxy-dev.googlezip.net:80/"' \
+	'-DDATA_REDUCTION_DEV_HOST="https://proxy-dev.googlezip.net:443/"' \
+	'-DDATA_REDUCTION_DEV_FALLBACK_HOST="http://proxy-dev.googlezip.net:80/"' \
 	'-DSPDY_PROXY_AUTH_ORIGIN="https://proxy.googlezip.net:443/"' \
 	'-DDATA_REDUCTION_PROXY_PROBE_URL="http://check.googlezip.net/connect"' \
 	'-DDATA_REDUCTION_PROXY_WARMUP_URL="http://www.gstatic.com/generate_204"' \
 	'-DVIDEO_HOLE=1' \
+	'-DENABLE_LOAD_COMPLETION_HACKS=1' \
 	'-DUSE_OPENSSL=1' \
 	'-DUSE_OPENSSL_CERTS=1' \
 	'-DANDROID' \
@@ -119,6 +120,7 @@
 
 # Flags passed to only C++ (and not C) files.
 LOCAL_CPPFLAGS_Debug := \
+	-fno-exceptions \
 	-fno-rtti \
 	-fno-threadsafe-statics \
 	-fvisibility-inlines-hidden \
@@ -135,7 +137,6 @@
 MY_CFLAGS_Release := \
 	-fstack-protector \
 	--param=ssp-buffer-size=4 \
-	-fno-exceptions \
 	-fno-strict-aliasing \
 	-Wno-unused-parameter \
 	-Wno-missing-field-initializers \
@@ -187,11 +188,13 @@
 	'-DENABLE_PRINTING=1' \
 	'-DENABLE_MANAGED_USERS=1' \
 	'-DDATA_REDUCTION_FALLBACK_HOST="http://compress.googlezip.net:80/"' \
-	'-DDATA_REDUCTION_DEV_HOST="http://proxy-dev.googlezip.net:80/"' \
+	'-DDATA_REDUCTION_DEV_HOST="https://proxy-dev.googlezip.net:443/"' \
+	'-DDATA_REDUCTION_DEV_FALLBACK_HOST="http://proxy-dev.googlezip.net:80/"' \
 	'-DSPDY_PROXY_AUTH_ORIGIN="https://proxy.googlezip.net:443/"' \
 	'-DDATA_REDUCTION_PROXY_PROBE_URL="http://check.googlezip.net/connect"' \
 	'-DDATA_REDUCTION_PROXY_WARMUP_URL="http://www.gstatic.com/generate_204"' \
 	'-DVIDEO_HOLE=1' \
+	'-DENABLE_LOAD_COMPLETION_HACKS=1' \
 	'-DUSE_OPENSSL=1' \
 	'-DUSE_OPENSSL_CERTS=1' \
 	'-DANDROID' \
@@ -214,6 +217,7 @@
 
 # Flags passed to only C++ (and not C) files.
 LOCAL_CPPFLAGS_Release := \
+	-fno-exceptions \
 	-fno-rtti \
 	-fno-threadsafe-statics \
 	-fvisibility-inlines-hidden \
@@ -232,46 +236,6 @@
 LOCAL_ASFLAGS := $(LOCAL_CFLAGS)
 ### Rules for final target.
 
-LOCAL_LDFLAGS_Debug := \
-	-Wl,-z,now \
-	-Wl,-z,relro \
-	-Wl,--fatal-warnings \
-	-Wl,-z,noexecstack \
-	-fPIC \
-	-m64 \
-	-fuse-ld=gold \
-	-nostdlib \
-	-Wl,--no-undefined \
-	-Wl,--exclude-libs=ALL \
-	-Wl,--warn-shared-textrel \
-	-Wl,-O1 \
-	-Wl,--as-needed
-
-
-LOCAL_LDFLAGS_Release := \
-	-Wl,-z,now \
-	-Wl,-z,relro \
-	-Wl,--fatal-warnings \
-	-Wl,-z,noexecstack \
-	-fPIC \
-	-m64 \
-	-fuse-ld=gold \
-	-nostdlib \
-	-Wl,--no-undefined \
-	-Wl,--exclude-libs=ALL \
-	-Wl,-O1 \
-	-Wl,--as-needed \
-	-Wl,--gc-sections \
-	-Wl,--warn-shared-textrel
-
-
-LOCAL_LDFLAGS := $(LOCAL_LDFLAGS_$(GYP_CONFIGURATION))
-
-LOCAL_STATIC_LIBRARIES :=
-
-# Enable grouping to fix circular references
-LOCAL_GROUP_STATIC_LIBRARIES := true
-
 LOCAL_SHARED_LIBRARIES := \
 	libstlport \
 	libdl
diff --git a/src/third_party/compiler/ArrayBoundsClamper.h b/src/third_party/compiler/ArrayBoundsClamper.h
index 7d06a6c..30bb7e3 100644
--- a/src/third_party/compiler/ArrayBoundsClamper.h
+++ b/src/third_party/compiler/ArrayBoundsClamper.h
@@ -27,7 +27,7 @@
 #define THIRD_PARTY_COMPILER_ARRAY_BOUNDS_CLAMPER_H_
 
 #include "compiler/translator/InfoSink.h"
-#include "compiler/translator/intermediate.h"
+#include "compiler/translator/IntermNode.h"
 
 class ArrayBoundsClamper {
 public:
diff --git a/src/translator.target.darwin-arm.mk b/src/translator.target.darwin-arm.mk
index 72e8d0e..4c17803 100644
--- a/src/translator.target.darwin-arm.mk
+++ b/src/translator.target.darwin-arm.mk
@@ -5,7 +5,6 @@
 LOCAL_MODULE_CLASS := STATIC_LIBRARIES
 LOCAL_MODULE := third_party_angle_src_translator_gyp
 LOCAL_MODULE_SUFFIX := .a
-LOCAL_MODULE_TAGS := optional
 LOCAL_MODULE_TARGET_ARCH := $(TARGET_$(GYP_VAR_PREFIX)ARCH)
 gyp_intermediate_dir := $(call local-intermediates-dir,,$(GYP_VAR_PREFIX))
 gyp_shared_intermediate_dir := $(call intermediates-dir-for,GYP,shared,,,$(GYP_VAR_PREFIX))
@@ -31,7 +30,6 @@
 MY_CFLAGS_Debug := \
 	-fstack-protector \
 	--param=ssp-buffer-size=4 \
-	-fno-exceptions \
 	-fno-strict-aliasing \
 	-Wno-unused-parameter \
 	-Wno-missing-field-initializers \
@@ -41,13 +39,13 @@
 	-Wno-unused-local-typedefs \
 	-Wno-format \
 	-fno-tree-sra \
+	-fno-caller-saves \
+	-Wno-psabi \
 	-fno-partial-inlining \
 	-fno-early-inlining \
 	-fno-tree-copy-prop \
 	-fno-tree-loop-optimize \
 	-fno-move-loop-invariants \
-	-fno-caller-saves \
-	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -66,6 +64,7 @@
 	-Wno-sequence-point \
 	-Os \
 	-g \
+	-gdwarf-4 \
 	-fdata-sections \
 	-ffunction-sections \
 	-fomit-frame-pointer \
@@ -89,11 +88,13 @@
 	'-DENABLE_PRINTING=1' \
 	'-DENABLE_MANAGED_USERS=1' \
 	'-DDATA_REDUCTION_FALLBACK_HOST="http://compress.googlezip.net:80/"' \
-	'-DDATA_REDUCTION_DEV_HOST="http://proxy-dev.googlezip.net:80/"' \
+	'-DDATA_REDUCTION_DEV_HOST="https://proxy-dev.googlezip.net:443/"' \
+	'-DDATA_REDUCTION_DEV_FALLBACK_HOST="http://proxy-dev.googlezip.net:80/"' \
 	'-DSPDY_PROXY_AUTH_ORIGIN="https://proxy.googlezip.net:443/"' \
 	'-DDATA_REDUCTION_PROXY_PROBE_URL="http://check.googlezip.net/connect"' \
 	'-DDATA_REDUCTION_PROXY_WARMUP_URL="http://www.gstatic.com/generate_204"' \
 	'-DVIDEO_HOLE=1' \
+	'-DENABLE_LOAD_COMPLETION_HACKS=1' \
 	'-DANGLE_TRANSLATOR_IMPLEMENTATION' \
 	'-DUSE_OPENSSL=1' \
 	'-DUSE_OPENSSL_CERTS=1' \
@@ -119,6 +120,7 @@
 
 # Flags passed to only C++ (and not C) files.
 LOCAL_CPPFLAGS_Debug := \
+	-fno-exceptions \
 	-fno-rtti \
 	-fno-threadsafe-statics \
 	-fvisibility-inlines-hidden \
@@ -136,7 +138,6 @@
 MY_CFLAGS_Release := \
 	-fstack-protector \
 	--param=ssp-buffer-size=4 \
-	-fno-exceptions \
 	-fno-strict-aliasing \
 	-Wno-unused-parameter \
 	-Wno-missing-field-initializers \
@@ -146,13 +147,13 @@
 	-Wno-unused-local-typedefs \
 	-Wno-format \
 	-fno-tree-sra \
+	-fno-caller-saves \
+	-Wno-psabi \
 	-fno-partial-inlining \
 	-fno-early-inlining \
 	-fno-tree-copy-prop \
 	-fno-tree-loop-optimize \
 	-fno-move-loop-invariants \
-	-fno-caller-saves \
-	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -194,11 +195,13 @@
 	'-DENABLE_PRINTING=1' \
 	'-DENABLE_MANAGED_USERS=1' \
 	'-DDATA_REDUCTION_FALLBACK_HOST="http://compress.googlezip.net:80/"' \
-	'-DDATA_REDUCTION_DEV_HOST="http://proxy-dev.googlezip.net:80/"' \
+	'-DDATA_REDUCTION_DEV_HOST="https://proxy-dev.googlezip.net:443/"' \
+	'-DDATA_REDUCTION_DEV_FALLBACK_HOST="http://proxy-dev.googlezip.net:80/"' \
 	'-DSPDY_PROXY_AUTH_ORIGIN="https://proxy.googlezip.net:443/"' \
 	'-DDATA_REDUCTION_PROXY_PROBE_URL="http://check.googlezip.net/connect"' \
 	'-DDATA_REDUCTION_PROXY_WARMUP_URL="http://www.gstatic.com/generate_204"' \
 	'-DVIDEO_HOLE=1' \
+	'-DENABLE_LOAD_COMPLETION_HACKS=1' \
 	'-DANGLE_TRANSLATOR_IMPLEMENTATION' \
 	'-DUSE_OPENSSL=1' \
 	'-DUSE_OPENSSL_CERTS=1' \
@@ -224,6 +227,7 @@
 
 # Flags passed to only C++ (and not C) files.
 LOCAL_CPPFLAGS_Release := \
+	-fno-exceptions \
 	-fno-rtti \
 	-fno-threadsafe-statics \
 	-fvisibility-inlines-hidden \
@@ -243,50 +247,6 @@
 LOCAL_ASFLAGS := $(LOCAL_CFLAGS)
 ### Rules for final target.
 
-LOCAL_LDFLAGS_Debug := \
-	-Wl,-z,now \
-	-Wl,-z,relro \
-	-Wl,--fatal-warnings \
-	-Wl,-z,noexecstack \
-	-fPIC \
-	-Wl,-z,relro \
-	-Wl,-z,now \
-	-fuse-ld=gold \
-	-nostdlib \
-	-Wl,--no-undefined \
-	-Wl,--exclude-libs=ALL \
-	-Wl,--icf=safe \
-	-Wl,--warn-shared-textrel \
-	-Wl,-O1 \
-	-Wl,--as-needed
-
-
-LOCAL_LDFLAGS_Release := \
-	-Wl,-z,now \
-	-Wl,-z,relro \
-	-Wl,--fatal-warnings \
-	-Wl,-z,noexecstack \
-	-fPIC \
-	-Wl,-z,relro \
-	-Wl,-z,now \
-	-fuse-ld=gold \
-	-nostdlib \
-	-Wl,--no-undefined \
-	-Wl,--exclude-libs=ALL \
-	-Wl,--icf=safe \
-	-Wl,-O1 \
-	-Wl,--as-needed \
-	-Wl,--gc-sections \
-	-Wl,--warn-shared-textrel
-
-
-LOCAL_LDFLAGS := $(LOCAL_LDFLAGS_$(GYP_CONFIGURATION))
-
-LOCAL_STATIC_LIBRARIES :=
-
-# Enable grouping to fix circular references
-LOCAL_GROUP_STATIC_LIBRARIES := true
-
 LOCAL_SHARED_LIBRARIES := \
 	libstlport \
 	libdl
diff --git a/src/translator.target.darwin-arm64.mk b/src/translator.target.darwin-arm64.mk
index cbbe258..ff3fb60 100644
--- a/src/translator.target.darwin-arm64.mk
+++ b/src/translator.target.darwin-arm64.mk
@@ -5,7 +5,6 @@
 LOCAL_MODULE_CLASS := STATIC_LIBRARIES
 LOCAL_MODULE := third_party_angle_src_translator_gyp
 LOCAL_MODULE_SUFFIX := .a
-LOCAL_MODULE_TAGS := optional
 LOCAL_MODULE_TARGET_ARCH := $(TARGET_$(GYP_VAR_PREFIX)ARCH)
 gyp_intermediate_dir := $(call local-intermediates-dir,,$(GYP_VAR_PREFIX))
 gyp_shared_intermediate_dir := $(call intermediates-dir-for,GYP,shared,,,$(GYP_VAR_PREFIX))
@@ -30,7 +29,6 @@
 # Flags passed to both C and C++ files.
 MY_CFLAGS_Debug := \
 	--param=ssp-buffer-size=4 \
-	-fno-exceptions \
 	-fno-strict-aliasing \
 	-Wno-unused-parameter \
 	-Wno-missing-field-initializers \
@@ -56,6 +54,7 @@
 	-Wno-sequence-point \
 	-Os \
 	-g \
+	-gdwarf-4 \
 	-fdata-sections \
 	-ffunction-sections \
 	-funwind-tables
@@ -78,11 +77,13 @@
 	'-DENABLE_PRINTING=1' \
 	'-DENABLE_MANAGED_USERS=1' \
 	'-DDATA_REDUCTION_FALLBACK_HOST="http://compress.googlezip.net:80/"' \
-	'-DDATA_REDUCTION_DEV_HOST="http://proxy-dev.googlezip.net:80/"' \
+	'-DDATA_REDUCTION_DEV_HOST="https://proxy-dev.googlezip.net:443/"' \
+	'-DDATA_REDUCTION_DEV_FALLBACK_HOST="http://proxy-dev.googlezip.net:80/"' \
 	'-DSPDY_PROXY_AUTH_ORIGIN="https://proxy.googlezip.net:443/"' \
 	'-DDATA_REDUCTION_PROXY_PROBE_URL="http://check.googlezip.net/connect"' \
 	'-DDATA_REDUCTION_PROXY_WARMUP_URL="http://www.gstatic.com/generate_204"' \
 	'-DVIDEO_HOLE=1' \
+	'-DENABLE_LOAD_COMPLETION_HACKS=1' \
 	'-DANGLE_TRANSLATOR_IMPLEMENTATION' \
 	'-DUSE_OPENSSL=1' \
 	'-DUSE_OPENSSL_CERTS=1' \
@@ -108,6 +109,7 @@
 
 # Flags passed to only C++ (and not C) files.
 LOCAL_CPPFLAGS_Debug := \
+	-fno-exceptions \
 	-fno-rtti \
 	-fno-threadsafe-statics \
 	-fvisibility-inlines-hidden \
@@ -123,7 +125,6 @@
 # Flags passed to both C and C++ files.
 MY_CFLAGS_Release := \
 	--param=ssp-buffer-size=4 \
-	-fno-exceptions \
 	-fno-strict-aliasing \
 	-Wno-unused-parameter \
 	-Wno-missing-field-initializers \
@@ -171,11 +172,13 @@
 	'-DENABLE_PRINTING=1' \
 	'-DENABLE_MANAGED_USERS=1' \
 	'-DDATA_REDUCTION_FALLBACK_HOST="http://compress.googlezip.net:80/"' \
-	'-DDATA_REDUCTION_DEV_HOST="http://proxy-dev.googlezip.net:80/"' \
+	'-DDATA_REDUCTION_DEV_HOST="https://proxy-dev.googlezip.net:443/"' \
+	'-DDATA_REDUCTION_DEV_FALLBACK_HOST="http://proxy-dev.googlezip.net:80/"' \
 	'-DSPDY_PROXY_AUTH_ORIGIN="https://proxy.googlezip.net:443/"' \
 	'-DDATA_REDUCTION_PROXY_PROBE_URL="http://check.googlezip.net/connect"' \
 	'-DDATA_REDUCTION_PROXY_WARMUP_URL="http://www.gstatic.com/generate_204"' \
 	'-DVIDEO_HOLE=1' \
+	'-DENABLE_LOAD_COMPLETION_HACKS=1' \
 	'-DANGLE_TRANSLATOR_IMPLEMENTATION' \
 	'-DUSE_OPENSSL=1' \
 	'-DUSE_OPENSSL_CERTS=1' \
@@ -201,6 +204,7 @@
 
 # Flags passed to only C++ (and not C) files.
 LOCAL_CPPFLAGS_Release := \
+	-fno-exceptions \
 	-fno-rtti \
 	-fno-threadsafe-statics \
 	-fvisibility-inlines-hidden \
@@ -219,42 +223,6 @@
 LOCAL_ASFLAGS := $(LOCAL_CFLAGS)
 ### Rules for final target.
 
-LOCAL_LDFLAGS_Debug := \
-	-Wl,-z,now \
-	-Wl,-z,relro \
-	-Wl,--fatal-warnings \
-	-Wl,-z,noexecstack \
-	-fPIC \
-	-nostdlib \
-	-Wl,--no-undefined \
-	-Wl,--exclude-libs=ALL \
-	-Wl,--warn-shared-textrel \
-	-Wl,-O1 \
-	-Wl,--as-needed
-
-
-LOCAL_LDFLAGS_Release := \
-	-Wl,-z,now \
-	-Wl,-z,relro \
-	-Wl,--fatal-warnings \
-	-Wl,-z,noexecstack \
-	-fPIC \
-	-nostdlib \
-	-Wl,--no-undefined \
-	-Wl,--exclude-libs=ALL \
-	-Wl,-O1 \
-	-Wl,--as-needed \
-	-Wl,--gc-sections \
-	-Wl,--warn-shared-textrel
-
-
-LOCAL_LDFLAGS := $(LOCAL_LDFLAGS_$(GYP_CONFIGURATION))
-
-LOCAL_STATIC_LIBRARIES :=
-
-# Enable grouping to fix circular references
-LOCAL_GROUP_STATIC_LIBRARIES := true
-
 LOCAL_SHARED_LIBRARIES := \
 	libstlport \
 	libdl
diff --git a/src/translator.target.darwin-mips.mk b/src/translator.target.darwin-mips.mk
index 98c8668..2336fd6 100644
--- a/src/translator.target.darwin-mips.mk
+++ b/src/translator.target.darwin-mips.mk
@@ -5,7 +5,6 @@
 LOCAL_MODULE_CLASS := STATIC_LIBRARIES
 LOCAL_MODULE := third_party_angle_src_translator_gyp
 LOCAL_MODULE_SUFFIX := .a
-LOCAL_MODULE_TAGS := optional
 LOCAL_MODULE_TARGET_ARCH := $(TARGET_$(GYP_VAR_PREFIX)ARCH)
 gyp_intermediate_dir := $(call local-intermediates-dir,,$(GYP_VAR_PREFIX))
 gyp_shared_intermediate_dir := $(call intermediates-dir-for,GYP,shared,,,$(GYP_VAR_PREFIX))
@@ -32,7 +31,6 @@
 	-fstack-protector \
 	--param=ssp-buffer-size=4 \
 	 \
-	-fno-exceptions \
 	-fno-strict-aliasing \
 	-Wno-unused-parameter \
 	-Wno-missing-field-initializers \
@@ -41,8 +39,6 @@
 	-fPIC \
 	-Wno-unused-local-typedefs \
 	-Wno-format \
-	-EL \
-	-mhard-float \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -61,6 +57,7 @@
 	-Wno-sequence-point \
 	-Os \
 	-g \
+	-gdwarf-4 \
 	-fdata-sections \
 	-ffunction-sections \
 	-fomit-frame-pointer \
@@ -84,11 +81,13 @@
 	'-DENABLE_PRINTING=1' \
 	'-DENABLE_MANAGED_USERS=1' \
 	'-DDATA_REDUCTION_FALLBACK_HOST="http://compress.googlezip.net:80/"' \
-	'-DDATA_REDUCTION_DEV_HOST="http://proxy-dev.googlezip.net:80/"' \
+	'-DDATA_REDUCTION_DEV_HOST="https://proxy-dev.googlezip.net:443/"' \
+	'-DDATA_REDUCTION_DEV_FALLBACK_HOST="http://proxy-dev.googlezip.net:80/"' \
 	'-DSPDY_PROXY_AUTH_ORIGIN="https://proxy.googlezip.net:443/"' \
 	'-DDATA_REDUCTION_PROXY_PROBE_URL="http://check.googlezip.net/connect"' \
 	'-DDATA_REDUCTION_PROXY_WARMUP_URL="http://www.gstatic.com/generate_204"' \
 	'-DVIDEO_HOLE=1' \
+	'-DENABLE_LOAD_COMPLETION_HACKS=1' \
 	'-DANGLE_TRANSLATOR_IMPLEMENTATION' \
 	'-DUSE_OPENSSL=1' \
 	'-DUSE_OPENSSL_CERTS=1' \
@@ -114,6 +113,7 @@
 
 # Flags passed to only C++ (and not C) files.
 LOCAL_CPPFLAGS_Debug := \
+	-fno-exceptions \
 	-fno-rtti \
 	-fno-threadsafe-statics \
 	-fvisibility-inlines-hidden \
@@ -132,7 +132,6 @@
 	-fstack-protector \
 	--param=ssp-buffer-size=4 \
 	 \
-	-fno-exceptions \
 	-fno-strict-aliasing \
 	-Wno-unused-parameter \
 	-Wno-missing-field-initializers \
@@ -141,8 +140,6 @@
 	-fPIC \
 	-Wno-unused-local-typedefs \
 	-Wno-format \
-	-EL \
-	-mhard-float \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -184,11 +181,13 @@
 	'-DENABLE_PRINTING=1' \
 	'-DENABLE_MANAGED_USERS=1' \
 	'-DDATA_REDUCTION_FALLBACK_HOST="http://compress.googlezip.net:80/"' \
-	'-DDATA_REDUCTION_DEV_HOST="http://proxy-dev.googlezip.net:80/"' \
+	'-DDATA_REDUCTION_DEV_HOST="https://proxy-dev.googlezip.net:443/"' \
+	'-DDATA_REDUCTION_DEV_FALLBACK_HOST="http://proxy-dev.googlezip.net:80/"' \
 	'-DSPDY_PROXY_AUTH_ORIGIN="https://proxy.googlezip.net:443/"' \
 	'-DDATA_REDUCTION_PROXY_PROBE_URL="http://check.googlezip.net/connect"' \
 	'-DDATA_REDUCTION_PROXY_WARMUP_URL="http://www.gstatic.com/generate_204"' \
 	'-DVIDEO_HOLE=1' \
+	'-DENABLE_LOAD_COMPLETION_HACKS=1' \
 	'-DANGLE_TRANSLATOR_IMPLEMENTATION' \
 	'-DUSE_OPENSSL=1' \
 	'-DUSE_OPENSSL_CERTS=1' \
@@ -214,6 +213,7 @@
 
 # Flags passed to only C++ (and not C) files.
 LOCAL_CPPFLAGS_Release := \
+	-fno-exceptions \
 	-fno-rtti \
 	-fno-threadsafe-statics \
 	-fvisibility-inlines-hidden \
@@ -233,46 +233,6 @@
 LOCAL_ASFLAGS := $(LOCAL_CFLAGS)
 ### Rules for final target.
 
-LOCAL_LDFLAGS_Debug := \
-	-Wl,-z,now \
-	-Wl,-z,relro \
-	-Wl,--fatal-warnings \
-	-Wl,-z,noexecstack \
-	-fPIC \
-	-EL \
-	-Wl,--no-keep-memory \
-	-nostdlib \
-	-Wl,--no-undefined \
-	-Wl,--exclude-libs=ALL \
-	-Wl,--warn-shared-textrel \
-	-Wl,-O1 \
-	-Wl,--as-needed
-
-
-LOCAL_LDFLAGS_Release := \
-	-Wl,-z,now \
-	-Wl,-z,relro \
-	-Wl,--fatal-warnings \
-	-Wl,-z,noexecstack \
-	-fPIC \
-	-EL \
-	-Wl,--no-keep-memory \
-	-nostdlib \
-	-Wl,--no-undefined \
-	-Wl,--exclude-libs=ALL \
-	-Wl,-O1 \
-	-Wl,--as-needed \
-	-Wl,--gc-sections \
-	-Wl,--warn-shared-textrel
-
-
-LOCAL_LDFLAGS := $(LOCAL_LDFLAGS_$(GYP_CONFIGURATION))
-
-LOCAL_STATIC_LIBRARIES :=
-
-# Enable grouping to fix circular references
-LOCAL_GROUP_STATIC_LIBRARIES := true
-
 LOCAL_SHARED_LIBRARIES := \
 	libstlport \
 	libdl
diff --git a/src/translator.target.darwin-x86.mk b/src/translator.target.darwin-x86.mk
index 567d931..cc1f7a5 100644
--- a/src/translator.target.darwin-x86.mk
+++ b/src/translator.target.darwin-x86.mk
@@ -5,7 +5,6 @@
 LOCAL_MODULE_CLASS := STATIC_LIBRARIES
 LOCAL_MODULE := third_party_angle_src_translator_gyp
 LOCAL_MODULE_SUFFIX := .a
-LOCAL_MODULE_TAGS := optional
 LOCAL_MODULE_TARGET_ARCH := $(TARGET_$(GYP_VAR_PREFIX)ARCH)
 gyp_intermediate_dir := $(call local-intermediates-dir,,$(GYP_VAR_PREFIX))
 gyp_shared_intermediate_dir := $(call intermediates-dir-for,GYP,shared,,,$(GYP_VAR_PREFIX))
@@ -30,7 +29,6 @@
 # Flags passed to both C and C++ files.
 MY_CFLAGS_Debug := \
 	--param=ssp-buffer-size=4 \
-	-fno-exceptions \
 	-fno-strict-aliasing \
 	-Wno-unused-parameter \
 	-Wno-missing-field-initializers \
@@ -61,6 +59,7 @@
 	-Wno-sequence-point \
 	-Os \
 	-g \
+	-gdwarf-4 \
 	-fdata-sections \
 	-ffunction-sections \
 	-fomit-frame-pointer \
@@ -84,11 +83,13 @@
 	'-DENABLE_PRINTING=1' \
 	'-DENABLE_MANAGED_USERS=1' \
 	'-DDATA_REDUCTION_FALLBACK_HOST="http://compress.googlezip.net:80/"' \
-	'-DDATA_REDUCTION_DEV_HOST="http://proxy-dev.googlezip.net:80/"' \
+	'-DDATA_REDUCTION_DEV_HOST="https://proxy-dev.googlezip.net:443/"' \
+	'-DDATA_REDUCTION_DEV_FALLBACK_HOST="http://proxy-dev.googlezip.net:80/"' \
 	'-DSPDY_PROXY_AUTH_ORIGIN="https://proxy.googlezip.net:443/"' \
 	'-DDATA_REDUCTION_PROXY_PROBE_URL="http://check.googlezip.net/connect"' \
 	'-DDATA_REDUCTION_PROXY_WARMUP_URL="http://www.gstatic.com/generate_204"' \
 	'-DVIDEO_HOLE=1' \
+	'-DENABLE_LOAD_COMPLETION_HACKS=1' \
 	'-DANGLE_TRANSLATOR_IMPLEMENTATION' \
 	'-DUSE_OPENSSL=1' \
 	'-DUSE_OPENSSL_CERTS=1' \
@@ -114,6 +115,7 @@
 
 # Flags passed to only C++ (and not C) files.
 LOCAL_CPPFLAGS_Debug := \
+	-fno-exceptions \
 	-fno-rtti \
 	-fno-threadsafe-statics \
 	-fvisibility-inlines-hidden \
@@ -129,7 +131,6 @@
 # Flags passed to both C and C++ files.
 MY_CFLAGS_Release := \
 	--param=ssp-buffer-size=4 \
-	-fno-exceptions \
 	-fno-strict-aliasing \
 	-Wno-unused-parameter \
 	-Wno-missing-field-initializers \
@@ -183,11 +184,13 @@
 	'-DENABLE_PRINTING=1' \
 	'-DENABLE_MANAGED_USERS=1' \
 	'-DDATA_REDUCTION_FALLBACK_HOST="http://compress.googlezip.net:80/"' \
-	'-DDATA_REDUCTION_DEV_HOST="http://proxy-dev.googlezip.net:80/"' \
+	'-DDATA_REDUCTION_DEV_HOST="https://proxy-dev.googlezip.net:443/"' \
+	'-DDATA_REDUCTION_DEV_FALLBACK_HOST="http://proxy-dev.googlezip.net:80/"' \
 	'-DSPDY_PROXY_AUTH_ORIGIN="https://proxy.googlezip.net:443/"' \
 	'-DDATA_REDUCTION_PROXY_PROBE_URL="http://check.googlezip.net/connect"' \
 	'-DDATA_REDUCTION_PROXY_WARMUP_URL="http://www.gstatic.com/generate_204"' \
 	'-DVIDEO_HOLE=1' \
+	'-DENABLE_LOAD_COMPLETION_HACKS=1' \
 	'-DANGLE_TRANSLATOR_IMPLEMENTATION' \
 	'-DUSE_OPENSSL=1' \
 	'-DUSE_OPENSSL_CERTS=1' \
@@ -213,6 +216,7 @@
 
 # Flags passed to only C++ (and not C) files.
 LOCAL_CPPFLAGS_Release := \
+	-fno-exceptions \
 	-fno-rtti \
 	-fno-threadsafe-statics \
 	-fvisibility-inlines-hidden \
@@ -231,46 +235,6 @@
 LOCAL_ASFLAGS := $(LOCAL_CFLAGS)
 ### Rules for final target.
 
-LOCAL_LDFLAGS_Debug := \
-	-Wl,-z,now \
-	-Wl,-z,relro \
-	-Wl,--fatal-warnings \
-	-Wl,-z,noexecstack \
-	-fPIC \
-	-m32 \
-	-fuse-ld=gold \
-	-nostdlib \
-	-Wl,--no-undefined \
-	-Wl,--exclude-libs=ALL \
-	-Wl,--warn-shared-textrel \
-	-Wl,-O1 \
-	-Wl,--as-needed
-
-
-LOCAL_LDFLAGS_Release := \
-	-Wl,-z,now \
-	-Wl,-z,relro \
-	-Wl,--fatal-warnings \
-	-Wl,-z,noexecstack \
-	-fPIC \
-	-m32 \
-	-fuse-ld=gold \
-	-nostdlib \
-	-Wl,--no-undefined \
-	-Wl,--exclude-libs=ALL \
-	-Wl,-O1 \
-	-Wl,--as-needed \
-	-Wl,--gc-sections \
-	-Wl,--warn-shared-textrel
-
-
-LOCAL_LDFLAGS := $(LOCAL_LDFLAGS_$(GYP_CONFIGURATION))
-
-LOCAL_STATIC_LIBRARIES :=
-
-# Enable grouping to fix circular references
-LOCAL_GROUP_STATIC_LIBRARIES := true
-
 LOCAL_SHARED_LIBRARIES := \
 	libstlport \
 	libdl
diff --git a/src/translator.target.darwin-x86_64.mk b/src/translator.target.darwin-x86_64.mk
index d49dff2..6231b0e 100644
--- a/src/translator.target.darwin-x86_64.mk
+++ b/src/translator.target.darwin-x86_64.mk
@@ -5,7 +5,6 @@
 LOCAL_MODULE_CLASS := STATIC_LIBRARIES
 LOCAL_MODULE := third_party_angle_src_translator_gyp
 LOCAL_MODULE_SUFFIX := .a
-LOCAL_MODULE_TAGS := optional
 LOCAL_MODULE_TARGET_ARCH := $(TARGET_$(GYP_VAR_PREFIX)ARCH)
 gyp_intermediate_dir := $(call local-intermediates-dir,,$(GYP_VAR_PREFIX))
 gyp_shared_intermediate_dir := $(call intermediates-dir-for,GYP,shared,,,$(GYP_VAR_PREFIX))
@@ -31,7 +30,6 @@
 MY_CFLAGS_Debug := \
 	-fstack-protector \
 	--param=ssp-buffer-size=4 \
-	-fno-exceptions \
 	-fno-strict-aliasing \
 	-Wno-unused-parameter \
 	-Wno-missing-field-initializers \
@@ -60,6 +58,7 @@
 	-Wno-sequence-point \
 	-Os \
 	-g \
+	-gdwarf-4 \
 	-fdata-sections \
 	-ffunction-sections \
 	-fomit-frame-pointer \
@@ -83,11 +82,13 @@
 	'-DENABLE_PRINTING=1' \
 	'-DENABLE_MANAGED_USERS=1' \
 	'-DDATA_REDUCTION_FALLBACK_HOST="http://compress.googlezip.net:80/"' \
-	'-DDATA_REDUCTION_DEV_HOST="http://proxy-dev.googlezip.net:80/"' \
+	'-DDATA_REDUCTION_DEV_HOST="https://proxy-dev.googlezip.net:443/"' \
+	'-DDATA_REDUCTION_DEV_FALLBACK_HOST="http://proxy-dev.googlezip.net:80/"' \
 	'-DSPDY_PROXY_AUTH_ORIGIN="https://proxy.googlezip.net:443/"' \
 	'-DDATA_REDUCTION_PROXY_PROBE_URL="http://check.googlezip.net/connect"' \
 	'-DDATA_REDUCTION_PROXY_WARMUP_URL="http://www.gstatic.com/generate_204"' \
 	'-DVIDEO_HOLE=1' \
+	'-DENABLE_LOAD_COMPLETION_HACKS=1' \
 	'-DANGLE_TRANSLATOR_IMPLEMENTATION' \
 	'-DUSE_OPENSSL=1' \
 	'-DUSE_OPENSSL_CERTS=1' \
@@ -113,6 +114,7 @@
 
 # Flags passed to only C++ (and not C) files.
 LOCAL_CPPFLAGS_Debug := \
+	-fno-exceptions \
 	-fno-rtti \
 	-fno-threadsafe-statics \
 	-fvisibility-inlines-hidden \
@@ -129,7 +131,6 @@
 MY_CFLAGS_Release := \
 	-fstack-protector \
 	--param=ssp-buffer-size=4 \
-	-fno-exceptions \
 	-fno-strict-aliasing \
 	-Wno-unused-parameter \
 	-Wno-missing-field-initializers \
@@ -181,11 +182,13 @@
 	'-DENABLE_PRINTING=1' \
 	'-DENABLE_MANAGED_USERS=1' \
 	'-DDATA_REDUCTION_FALLBACK_HOST="http://compress.googlezip.net:80/"' \
-	'-DDATA_REDUCTION_DEV_HOST="http://proxy-dev.googlezip.net:80/"' \
+	'-DDATA_REDUCTION_DEV_HOST="https://proxy-dev.googlezip.net:443/"' \
+	'-DDATA_REDUCTION_DEV_FALLBACK_HOST="http://proxy-dev.googlezip.net:80/"' \
 	'-DSPDY_PROXY_AUTH_ORIGIN="https://proxy.googlezip.net:443/"' \
 	'-DDATA_REDUCTION_PROXY_PROBE_URL="http://check.googlezip.net/connect"' \
 	'-DDATA_REDUCTION_PROXY_WARMUP_URL="http://www.gstatic.com/generate_204"' \
 	'-DVIDEO_HOLE=1' \
+	'-DENABLE_LOAD_COMPLETION_HACKS=1' \
 	'-DANGLE_TRANSLATOR_IMPLEMENTATION' \
 	'-DUSE_OPENSSL=1' \
 	'-DUSE_OPENSSL_CERTS=1' \
@@ -211,6 +214,7 @@
 
 # Flags passed to only C++ (and not C) files.
 LOCAL_CPPFLAGS_Release := \
+	-fno-exceptions \
 	-fno-rtti \
 	-fno-threadsafe-statics \
 	-fvisibility-inlines-hidden \
@@ -229,46 +233,6 @@
 LOCAL_ASFLAGS := $(LOCAL_CFLAGS)
 ### Rules for final target.
 
-LOCAL_LDFLAGS_Debug := \
-	-Wl,-z,now \
-	-Wl,-z,relro \
-	-Wl,--fatal-warnings \
-	-Wl,-z,noexecstack \
-	-fPIC \
-	-m64 \
-	-fuse-ld=gold \
-	-nostdlib \
-	-Wl,--no-undefined \
-	-Wl,--exclude-libs=ALL \
-	-Wl,--warn-shared-textrel \
-	-Wl,-O1 \
-	-Wl,--as-needed
-
-
-LOCAL_LDFLAGS_Release := \
-	-Wl,-z,now \
-	-Wl,-z,relro \
-	-Wl,--fatal-warnings \
-	-Wl,-z,noexecstack \
-	-fPIC \
-	-m64 \
-	-fuse-ld=gold \
-	-nostdlib \
-	-Wl,--no-undefined \
-	-Wl,--exclude-libs=ALL \
-	-Wl,-O1 \
-	-Wl,--as-needed \
-	-Wl,--gc-sections \
-	-Wl,--warn-shared-textrel
-
-
-LOCAL_LDFLAGS := $(LOCAL_LDFLAGS_$(GYP_CONFIGURATION))
-
-LOCAL_STATIC_LIBRARIES :=
-
-# Enable grouping to fix circular references
-LOCAL_GROUP_STATIC_LIBRARIES := true
-
 LOCAL_SHARED_LIBRARIES := \
 	libstlport \
 	libdl
diff --git a/src/translator.target.linux-arm.mk b/src/translator.target.linux-arm.mk
index 72e8d0e..4c17803 100644
--- a/src/translator.target.linux-arm.mk
+++ b/src/translator.target.linux-arm.mk
@@ -5,7 +5,6 @@
 LOCAL_MODULE_CLASS := STATIC_LIBRARIES
 LOCAL_MODULE := third_party_angle_src_translator_gyp
 LOCAL_MODULE_SUFFIX := .a
-LOCAL_MODULE_TAGS := optional
 LOCAL_MODULE_TARGET_ARCH := $(TARGET_$(GYP_VAR_PREFIX)ARCH)
 gyp_intermediate_dir := $(call local-intermediates-dir,,$(GYP_VAR_PREFIX))
 gyp_shared_intermediate_dir := $(call intermediates-dir-for,GYP,shared,,,$(GYP_VAR_PREFIX))
@@ -31,7 +30,6 @@
 MY_CFLAGS_Debug := \
 	-fstack-protector \
 	--param=ssp-buffer-size=4 \
-	-fno-exceptions \
 	-fno-strict-aliasing \
 	-Wno-unused-parameter \
 	-Wno-missing-field-initializers \
@@ -41,13 +39,13 @@
 	-Wno-unused-local-typedefs \
 	-Wno-format \
 	-fno-tree-sra \
+	-fno-caller-saves \
+	-Wno-psabi \
 	-fno-partial-inlining \
 	-fno-early-inlining \
 	-fno-tree-copy-prop \
 	-fno-tree-loop-optimize \
 	-fno-move-loop-invariants \
-	-fno-caller-saves \
-	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -66,6 +64,7 @@
 	-Wno-sequence-point \
 	-Os \
 	-g \
+	-gdwarf-4 \
 	-fdata-sections \
 	-ffunction-sections \
 	-fomit-frame-pointer \
@@ -89,11 +88,13 @@
 	'-DENABLE_PRINTING=1' \
 	'-DENABLE_MANAGED_USERS=1' \
 	'-DDATA_REDUCTION_FALLBACK_HOST="http://compress.googlezip.net:80/"' \
-	'-DDATA_REDUCTION_DEV_HOST="http://proxy-dev.googlezip.net:80/"' \
+	'-DDATA_REDUCTION_DEV_HOST="https://proxy-dev.googlezip.net:443/"' \
+	'-DDATA_REDUCTION_DEV_FALLBACK_HOST="http://proxy-dev.googlezip.net:80/"' \
 	'-DSPDY_PROXY_AUTH_ORIGIN="https://proxy.googlezip.net:443/"' \
 	'-DDATA_REDUCTION_PROXY_PROBE_URL="http://check.googlezip.net/connect"' \
 	'-DDATA_REDUCTION_PROXY_WARMUP_URL="http://www.gstatic.com/generate_204"' \
 	'-DVIDEO_HOLE=1' \
+	'-DENABLE_LOAD_COMPLETION_HACKS=1' \
 	'-DANGLE_TRANSLATOR_IMPLEMENTATION' \
 	'-DUSE_OPENSSL=1' \
 	'-DUSE_OPENSSL_CERTS=1' \
@@ -119,6 +120,7 @@
 
 # Flags passed to only C++ (and not C) files.
 LOCAL_CPPFLAGS_Debug := \
+	-fno-exceptions \
 	-fno-rtti \
 	-fno-threadsafe-statics \
 	-fvisibility-inlines-hidden \
@@ -136,7 +138,6 @@
 MY_CFLAGS_Release := \
 	-fstack-protector \
 	--param=ssp-buffer-size=4 \
-	-fno-exceptions \
 	-fno-strict-aliasing \
 	-Wno-unused-parameter \
 	-Wno-missing-field-initializers \
@@ -146,13 +147,13 @@
 	-Wno-unused-local-typedefs \
 	-Wno-format \
 	-fno-tree-sra \
+	-fno-caller-saves \
+	-Wno-psabi \
 	-fno-partial-inlining \
 	-fno-early-inlining \
 	-fno-tree-copy-prop \
 	-fno-tree-loop-optimize \
 	-fno-move-loop-invariants \
-	-fno-caller-saves \
-	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -194,11 +195,13 @@
 	'-DENABLE_PRINTING=1' \
 	'-DENABLE_MANAGED_USERS=1' \
 	'-DDATA_REDUCTION_FALLBACK_HOST="http://compress.googlezip.net:80/"' \
-	'-DDATA_REDUCTION_DEV_HOST="http://proxy-dev.googlezip.net:80/"' \
+	'-DDATA_REDUCTION_DEV_HOST="https://proxy-dev.googlezip.net:443/"' \
+	'-DDATA_REDUCTION_DEV_FALLBACK_HOST="http://proxy-dev.googlezip.net:80/"' \
 	'-DSPDY_PROXY_AUTH_ORIGIN="https://proxy.googlezip.net:443/"' \
 	'-DDATA_REDUCTION_PROXY_PROBE_URL="http://check.googlezip.net/connect"' \
 	'-DDATA_REDUCTION_PROXY_WARMUP_URL="http://www.gstatic.com/generate_204"' \
 	'-DVIDEO_HOLE=1' \
+	'-DENABLE_LOAD_COMPLETION_HACKS=1' \
 	'-DANGLE_TRANSLATOR_IMPLEMENTATION' \
 	'-DUSE_OPENSSL=1' \
 	'-DUSE_OPENSSL_CERTS=1' \
@@ -224,6 +227,7 @@
 
 # Flags passed to only C++ (and not C) files.
 LOCAL_CPPFLAGS_Release := \
+	-fno-exceptions \
 	-fno-rtti \
 	-fno-threadsafe-statics \
 	-fvisibility-inlines-hidden \
@@ -243,50 +247,6 @@
 LOCAL_ASFLAGS := $(LOCAL_CFLAGS)
 ### Rules for final target.
 
-LOCAL_LDFLAGS_Debug := \
-	-Wl,-z,now \
-	-Wl,-z,relro \
-	-Wl,--fatal-warnings \
-	-Wl,-z,noexecstack \
-	-fPIC \
-	-Wl,-z,relro \
-	-Wl,-z,now \
-	-fuse-ld=gold \
-	-nostdlib \
-	-Wl,--no-undefined \
-	-Wl,--exclude-libs=ALL \
-	-Wl,--icf=safe \
-	-Wl,--warn-shared-textrel \
-	-Wl,-O1 \
-	-Wl,--as-needed
-
-
-LOCAL_LDFLAGS_Release := \
-	-Wl,-z,now \
-	-Wl,-z,relro \
-	-Wl,--fatal-warnings \
-	-Wl,-z,noexecstack \
-	-fPIC \
-	-Wl,-z,relro \
-	-Wl,-z,now \
-	-fuse-ld=gold \
-	-nostdlib \
-	-Wl,--no-undefined \
-	-Wl,--exclude-libs=ALL \
-	-Wl,--icf=safe \
-	-Wl,-O1 \
-	-Wl,--as-needed \
-	-Wl,--gc-sections \
-	-Wl,--warn-shared-textrel
-
-
-LOCAL_LDFLAGS := $(LOCAL_LDFLAGS_$(GYP_CONFIGURATION))
-
-LOCAL_STATIC_LIBRARIES :=
-
-# Enable grouping to fix circular references
-LOCAL_GROUP_STATIC_LIBRARIES := true
-
 LOCAL_SHARED_LIBRARIES := \
 	libstlport \
 	libdl
diff --git a/src/translator.target.linux-arm64.mk b/src/translator.target.linux-arm64.mk
index cbbe258..ff3fb60 100644
--- a/src/translator.target.linux-arm64.mk
+++ b/src/translator.target.linux-arm64.mk
@@ -5,7 +5,6 @@
 LOCAL_MODULE_CLASS := STATIC_LIBRARIES
 LOCAL_MODULE := third_party_angle_src_translator_gyp
 LOCAL_MODULE_SUFFIX := .a
-LOCAL_MODULE_TAGS := optional
 LOCAL_MODULE_TARGET_ARCH := $(TARGET_$(GYP_VAR_PREFIX)ARCH)
 gyp_intermediate_dir := $(call local-intermediates-dir,,$(GYP_VAR_PREFIX))
 gyp_shared_intermediate_dir := $(call intermediates-dir-for,GYP,shared,,,$(GYP_VAR_PREFIX))
@@ -30,7 +29,6 @@
 # Flags passed to both C and C++ files.
 MY_CFLAGS_Debug := \
 	--param=ssp-buffer-size=4 \
-	-fno-exceptions \
 	-fno-strict-aliasing \
 	-Wno-unused-parameter \
 	-Wno-missing-field-initializers \
@@ -56,6 +54,7 @@
 	-Wno-sequence-point \
 	-Os \
 	-g \
+	-gdwarf-4 \
 	-fdata-sections \
 	-ffunction-sections \
 	-funwind-tables
@@ -78,11 +77,13 @@
 	'-DENABLE_PRINTING=1' \
 	'-DENABLE_MANAGED_USERS=1' \
 	'-DDATA_REDUCTION_FALLBACK_HOST="http://compress.googlezip.net:80/"' \
-	'-DDATA_REDUCTION_DEV_HOST="http://proxy-dev.googlezip.net:80/"' \
+	'-DDATA_REDUCTION_DEV_HOST="https://proxy-dev.googlezip.net:443/"' \
+	'-DDATA_REDUCTION_DEV_FALLBACK_HOST="http://proxy-dev.googlezip.net:80/"' \
 	'-DSPDY_PROXY_AUTH_ORIGIN="https://proxy.googlezip.net:443/"' \
 	'-DDATA_REDUCTION_PROXY_PROBE_URL="http://check.googlezip.net/connect"' \
 	'-DDATA_REDUCTION_PROXY_WARMUP_URL="http://www.gstatic.com/generate_204"' \
 	'-DVIDEO_HOLE=1' \
+	'-DENABLE_LOAD_COMPLETION_HACKS=1' \
 	'-DANGLE_TRANSLATOR_IMPLEMENTATION' \
 	'-DUSE_OPENSSL=1' \
 	'-DUSE_OPENSSL_CERTS=1' \
@@ -108,6 +109,7 @@
 
 # Flags passed to only C++ (and not C) files.
 LOCAL_CPPFLAGS_Debug := \
+	-fno-exceptions \
 	-fno-rtti \
 	-fno-threadsafe-statics \
 	-fvisibility-inlines-hidden \
@@ -123,7 +125,6 @@
 # Flags passed to both C and C++ files.
 MY_CFLAGS_Release := \
 	--param=ssp-buffer-size=4 \
-	-fno-exceptions \
 	-fno-strict-aliasing \
 	-Wno-unused-parameter \
 	-Wno-missing-field-initializers \
@@ -171,11 +172,13 @@
 	'-DENABLE_PRINTING=1' \
 	'-DENABLE_MANAGED_USERS=1' \
 	'-DDATA_REDUCTION_FALLBACK_HOST="http://compress.googlezip.net:80/"' \
-	'-DDATA_REDUCTION_DEV_HOST="http://proxy-dev.googlezip.net:80/"' \
+	'-DDATA_REDUCTION_DEV_HOST="https://proxy-dev.googlezip.net:443/"' \
+	'-DDATA_REDUCTION_DEV_FALLBACK_HOST="http://proxy-dev.googlezip.net:80/"' \
 	'-DSPDY_PROXY_AUTH_ORIGIN="https://proxy.googlezip.net:443/"' \
 	'-DDATA_REDUCTION_PROXY_PROBE_URL="http://check.googlezip.net/connect"' \
 	'-DDATA_REDUCTION_PROXY_WARMUP_URL="http://www.gstatic.com/generate_204"' \
 	'-DVIDEO_HOLE=1' \
+	'-DENABLE_LOAD_COMPLETION_HACKS=1' \
 	'-DANGLE_TRANSLATOR_IMPLEMENTATION' \
 	'-DUSE_OPENSSL=1' \
 	'-DUSE_OPENSSL_CERTS=1' \
@@ -201,6 +204,7 @@
 
 # Flags passed to only C++ (and not C) files.
 LOCAL_CPPFLAGS_Release := \
+	-fno-exceptions \
 	-fno-rtti \
 	-fno-threadsafe-statics \
 	-fvisibility-inlines-hidden \
@@ -219,42 +223,6 @@
 LOCAL_ASFLAGS := $(LOCAL_CFLAGS)
 ### Rules for final target.
 
-LOCAL_LDFLAGS_Debug := \
-	-Wl,-z,now \
-	-Wl,-z,relro \
-	-Wl,--fatal-warnings \
-	-Wl,-z,noexecstack \
-	-fPIC \
-	-nostdlib \
-	-Wl,--no-undefined \
-	-Wl,--exclude-libs=ALL \
-	-Wl,--warn-shared-textrel \
-	-Wl,-O1 \
-	-Wl,--as-needed
-
-
-LOCAL_LDFLAGS_Release := \
-	-Wl,-z,now \
-	-Wl,-z,relro \
-	-Wl,--fatal-warnings \
-	-Wl,-z,noexecstack \
-	-fPIC \
-	-nostdlib \
-	-Wl,--no-undefined \
-	-Wl,--exclude-libs=ALL \
-	-Wl,-O1 \
-	-Wl,--as-needed \
-	-Wl,--gc-sections \
-	-Wl,--warn-shared-textrel
-
-
-LOCAL_LDFLAGS := $(LOCAL_LDFLAGS_$(GYP_CONFIGURATION))
-
-LOCAL_STATIC_LIBRARIES :=
-
-# Enable grouping to fix circular references
-LOCAL_GROUP_STATIC_LIBRARIES := true
-
 LOCAL_SHARED_LIBRARIES := \
 	libstlport \
 	libdl
diff --git a/src/translator.target.linux-mips.mk b/src/translator.target.linux-mips.mk
index 98c8668..2336fd6 100644
--- a/src/translator.target.linux-mips.mk
+++ b/src/translator.target.linux-mips.mk
@@ -5,7 +5,6 @@
 LOCAL_MODULE_CLASS := STATIC_LIBRARIES
 LOCAL_MODULE := third_party_angle_src_translator_gyp
 LOCAL_MODULE_SUFFIX := .a
-LOCAL_MODULE_TAGS := optional
 LOCAL_MODULE_TARGET_ARCH := $(TARGET_$(GYP_VAR_PREFIX)ARCH)
 gyp_intermediate_dir := $(call local-intermediates-dir,,$(GYP_VAR_PREFIX))
 gyp_shared_intermediate_dir := $(call intermediates-dir-for,GYP,shared,,,$(GYP_VAR_PREFIX))
@@ -32,7 +31,6 @@
 	-fstack-protector \
 	--param=ssp-buffer-size=4 \
 	 \
-	-fno-exceptions \
 	-fno-strict-aliasing \
 	-Wno-unused-parameter \
 	-Wno-missing-field-initializers \
@@ -41,8 +39,6 @@
 	-fPIC \
 	-Wno-unused-local-typedefs \
 	-Wno-format \
-	-EL \
-	-mhard-float \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -61,6 +57,7 @@
 	-Wno-sequence-point \
 	-Os \
 	-g \
+	-gdwarf-4 \
 	-fdata-sections \
 	-ffunction-sections \
 	-fomit-frame-pointer \
@@ -84,11 +81,13 @@
 	'-DENABLE_PRINTING=1' \
 	'-DENABLE_MANAGED_USERS=1' \
 	'-DDATA_REDUCTION_FALLBACK_HOST="http://compress.googlezip.net:80/"' \
-	'-DDATA_REDUCTION_DEV_HOST="http://proxy-dev.googlezip.net:80/"' \
+	'-DDATA_REDUCTION_DEV_HOST="https://proxy-dev.googlezip.net:443/"' \
+	'-DDATA_REDUCTION_DEV_FALLBACK_HOST="http://proxy-dev.googlezip.net:80/"' \
 	'-DSPDY_PROXY_AUTH_ORIGIN="https://proxy.googlezip.net:443/"' \
 	'-DDATA_REDUCTION_PROXY_PROBE_URL="http://check.googlezip.net/connect"' \
 	'-DDATA_REDUCTION_PROXY_WARMUP_URL="http://www.gstatic.com/generate_204"' \
 	'-DVIDEO_HOLE=1' \
+	'-DENABLE_LOAD_COMPLETION_HACKS=1' \
 	'-DANGLE_TRANSLATOR_IMPLEMENTATION' \
 	'-DUSE_OPENSSL=1' \
 	'-DUSE_OPENSSL_CERTS=1' \
@@ -114,6 +113,7 @@
 
 # Flags passed to only C++ (and not C) files.
 LOCAL_CPPFLAGS_Debug := \
+	-fno-exceptions \
 	-fno-rtti \
 	-fno-threadsafe-statics \
 	-fvisibility-inlines-hidden \
@@ -132,7 +132,6 @@
 	-fstack-protector \
 	--param=ssp-buffer-size=4 \
 	 \
-	-fno-exceptions \
 	-fno-strict-aliasing \
 	-Wno-unused-parameter \
 	-Wno-missing-field-initializers \
@@ -141,8 +140,6 @@
 	-fPIC \
 	-Wno-unused-local-typedefs \
 	-Wno-format \
-	-EL \
-	-mhard-float \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -184,11 +181,13 @@
 	'-DENABLE_PRINTING=1' \
 	'-DENABLE_MANAGED_USERS=1' \
 	'-DDATA_REDUCTION_FALLBACK_HOST="http://compress.googlezip.net:80/"' \
-	'-DDATA_REDUCTION_DEV_HOST="http://proxy-dev.googlezip.net:80/"' \
+	'-DDATA_REDUCTION_DEV_HOST="https://proxy-dev.googlezip.net:443/"' \
+	'-DDATA_REDUCTION_DEV_FALLBACK_HOST="http://proxy-dev.googlezip.net:80/"' \
 	'-DSPDY_PROXY_AUTH_ORIGIN="https://proxy.googlezip.net:443/"' \
 	'-DDATA_REDUCTION_PROXY_PROBE_URL="http://check.googlezip.net/connect"' \
 	'-DDATA_REDUCTION_PROXY_WARMUP_URL="http://www.gstatic.com/generate_204"' \
 	'-DVIDEO_HOLE=1' \
+	'-DENABLE_LOAD_COMPLETION_HACKS=1' \
 	'-DANGLE_TRANSLATOR_IMPLEMENTATION' \
 	'-DUSE_OPENSSL=1' \
 	'-DUSE_OPENSSL_CERTS=1' \
@@ -214,6 +213,7 @@
 
 # Flags passed to only C++ (and not C) files.
 LOCAL_CPPFLAGS_Release := \
+	-fno-exceptions \
 	-fno-rtti \
 	-fno-threadsafe-statics \
 	-fvisibility-inlines-hidden \
@@ -233,46 +233,6 @@
 LOCAL_ASFLAGS := $(LOCAL_CFLAGS)
 ### Rules for final target.
 
-LOCAL_LDFLAGS_Debug := \
-	-Wl,-z,now \
-	-Wl,-z,relro \
-	-Wl,--fatal-warnings \
-	-Wl,-z,noexecstack \
-	-fPIC \
-	-EL \
-	-Wl,--no-keep-memory \
-	-nostdlib \
-	-Wl,--no-undefined \
-	-Wl,--exclude-libs=ALL \
-	-Wl,--warn-shared-textrel \
-	-Wl,-O1 \
-	-Wl,--as-needed
-
-
-LOCAL_LDFLAGS_Release := \
-	-Wl,-z,now \
-	-Wl,-z,relro \
-	-Wl,--fatal-warnings \
-	-Wl,-z,noexecstack \
-	-fPIC \
-	-EL \
-	-Wl,--no-keep-memory \
-	-nostdlib \
-	-Wl,--no-undefined \
-	-Wl,--exclude-libs=ALL \
-	-Wl,-O1 \
-	-Wl,--as-needed \
-	-Wl,--gc-sections \
-	-Wl,--warn-shared-textrel
-
-
-LOCAL_LDFLAGS := $(LOCAL_LDFLAGS_$(GYP_CONFIGURATION))
-
-LOCAL_STATIC_LIBRARIES :=
-
-# Enable grouping to fix circular references
-LOCAL_GROUP_STATIC_LIBRARIES := true
-
 LOCAL_SHARED_LIBRARIES := \
 	libstlport \
 	libdl
diff --git a/src/translator.target.linux-x86.mk b/src/translator.target.linux-x86.mk
index 567d931..cc1f7a5 100644
--- a/src/translator.target.linux-x86.mk
+++ b/src/translator.target.linux-x86.mk
@@ -5,7 +5,6 @@
 LOCAL_MODULE_CLASS := STATIC_LIBRARIES
 LOCAL_MODULE := third_party_angle_src_translator_gyp
 LOCAL_MODULE_SUFFIX := .a
-LOCAL_MODULE_TAGS := optional
 LOCAL_MODULE_TARGET_ARCH := $(TARGET_$(GYP_VAR_PREFIX)ARCH)
 gyp_intermediate_dir := $(call local-intermediates-dir,,$(GYP_VAR_PREFIX))
 gyp_shared_intermediate_dir := $(call intermediates-dir-for,GYP,shared,,,$(GYP_VAR_PREFIX))
@@ -30,7 +29,6 @@
 # Flags passed to both C and C++ files.
 MY_CFLAGS_Debug := \
 	--param=ssp-buffer-size=4 \
-	-fno-exceptions \
 	-fno-strict-aliasing \
 	-Wno-unused-parameter \
 	-Wno-missing-field-initializers \
@@ -61,6 +59,7 @@
 	-Wno-sequence-point \
 	-Os \
 	-g \
+	-gdwarf-4 \
 	-fdata-sections \
 	-ffunction-sections \
 	-fomit-frame-pointer \
@@ -84,11 +83,13 @@
 	'-DENABLE_PRINTING=1' \
 	'-DENABLE_MANAGED_USERS=1' \
 	'-DDATA_REDUCTION_FALLBACK_HOST="http://compress.googlezip.net:80/"' \
-	'-DDATA_REDUCTION_DEV_HOST="http://proxy-dev.googlezip.net:80/"' \
+	'-DDATA_REDUCTION_DEV_HOST="https://proxy-dev.googlezip.net:443/"' \
+	'-DDATA_REDUCTION_DEV_FALLBACK_HOST="http://proxy-dev.googlezip.net:80/"' \
 	'-DSPDY_PROXY_AUTH_ORIGIN="https://proxy.googlezip.net:443/"' \
 	'-DDATA_REDUCTION_PROXY_PROBE_URL="http://check.googlezip.net/connect"' \
 	'-DDATA_REDUCTION_PROXY_WARMUP_URL="http://www.gstatic.com/generate_204"' \
 	'-DVIDEO_HOLE=1' \
+	'-DENABLE_LOAD_COMPLETION_HACKS=1' \
 	'-DANGLE_TRANSLATOR_IMPLEMENTATION' \
 	'-DUSE_OPENSSL=1' \
 	'-DUSE_OPENSSL_CERTS=1' \
@@ -114,6 +115,7 @@
 
 # Flags passed to only C++ (and not C) files.
 LOCAL_CPPFLAGS_Debug := \
+	-fno-exceptions \
 	-fno-rtti \
 	-fno-threadsafe-statics \
 	-fvisibility-inlines-hidden \
@@ -129,7 +131,6 @@
 # Flags passed to both C and C++ files.
 MY_CFLAGS_Release := \
 	--param=ssp-buffer-size=4 \
-	-fno-exceptions \
 	-fno-strict-aliasing \
 	-Wno-unused-parameter \
 	-Wno-missing-field-initializers \
@@ -183,11 +184,13 @@
 	'-DENABLE_PRINTING=1' \
 	'-DENABLE_MANAGED_USERS=1' \
 	'-DDATA_REDUCTION_FALLBACK_HOST="http://compress.googlezip.net:80/"' \
-	'-DDATA_REDUCTION_DEV_HOST="http://proxy-dev.googlezip.net:80/"' \
+	'-DDATA_REDUCTION_DEV_HOST="https://proxy-dev.googlezip.net:443/"' \
+	'-DDATA_REDUCTION_DEV_FALLBACK_HOST="http://proxy-dev.googlezip.net:80/"' \
 	'-DSPDY_PROXY_AUTH_ORIGIN="https://proxy.googlezip.net:443/"' \
 	'-DDATA_REDUCTION_PROXY_PROBE_URL="http://check.googlezip.net/connect"' \
 	'-DDATA_REDUCTION_PROXY_WARMUP_URL="http://www.gstatic.com/generate_204"' \
 	'-DVIDEO_HOLE=1' \
+	'-DENABLE_LOAD_COMPLETION_HACKS=1' \
 	'-DANGLE_TRANSLATOR_IMPLEMENTATION' \
 	'-DUSE_OPENSSL=1' \
 	'-DUSE_OPENSSL_CERTS=1' \
@@ -213,6 +216,7 @@
 
 # Flags passed to only C++ (and not C) files.
 LOCAL_CPPFLAGS_Release := \
+	-fno-exceptions \
 	-fno-rtti \
 	-fno-threadsafe-statics \
 	-fvisibility-inlines-hidden \
@@ -231,46 +235,6 @@
 LOCAL_ASFLAGS := $(LOCAL_CFLAGS)
 ### Rules for final target.
 
-LOCAL_LDFLAGS_Debug := \
-	-Wl,-z,now \
-	-Wl,-z,relro \
-	-Wl,--fatal-warnings \
-	-Wl,-z,noexecstack \
-	-fPIC \
-	-m32 \
-	-fuse-ld=gold \
-	-nostdlib \
-	-Wl,--no-undefined \
-	-Wl,--exclude-libs=ALL \
-	-Wl,--warn-shared-textrel \
-	-Wl,-O1 \
-	-Wl,--as-needed
-
-
-LOCAL_LDFLAGS_Release := \
-	-Wl,-z,now \
-	-Wl,-z,relro \
-	-Wl,--fatal-warnings \
-	-Wl,-z,noexecstack \
-	-fPIC \
-	-m32 \
-	-fuse-ld=gold \
-	-nostdlib \
-	-Wl,--no-undefined \
-	-Wl,--exclude-libs=ALL \
-	-Wl,-O1 \
-	-Wl,--as-needed \
-	-Wl,--gc-sections \
-	-Wl,--warn-shared-textrel
-
-
-LOCAL_LDFLAGS := $(LOCAL_LDFLAGS_$(GYP_CONFIGURATION))
-
-LOCAL_STATIC_LIBRARIES :=
-
-# Enable grouping to fix circular references
-LOCAL_GROUP_STATIC_LIBRARIES := true
-
 LOCAL_SHARED_LIBRARIES := \
 	libstlport \
 	libdl
diff --git a/src/translator.target.linux-x86_64.mk b/src/translator.target.linux-x86_64.mk
index d49dff2..6231b0e 100644
--- a/src/translator.target.linux-x86_64.mk
+++ b/src/translator.target.linux-x86_64.mk
@@ -5,7 +5,6 @@
 LOCAL_MODULE_CLASS := STATIC_LIBRARIES
 LOCAL_MODULE := third_party_angle_src_translator_gyp
 LOCAL_MODULE_SUFFIX := .a
-LOCAL_MODULE_TAGS := optional
 LOCAL_MODULE_TARGET_ARCH := $(TARGET_$(GYP_VAR_PREFIX)ARCH)
 gyp_intermediate_dir := $(call local-intermediates-dir,,$(GYP_VAR_PREFIX))
 gyp_shared_intermediate_dir := $(call intermediates-dir-for,GYP,shared,,,$(GYP_VAR_PREFIX))
@@ -31,7 +30,6 @@
 MY_CFLAGS_Debug := \
 	-fstack-protector \
 	--param=ssp-buffer-size=4 \
-	-fno-exceptions \
 	-fno-strict-aliasing \
 	-Wno-unused-parameter \
 	-Wno-missing-field-initializers \
@@ -60,6 +58,7 @@
 	-Wno-sequence-point \
 	-Os \
 	-g \
+	-gdwarf-4 \
 	-fdata-sections \
 	-ffunction-sections \
 	-fomit-frame-pointer \
@@ -83,11 +82,13 @@
 	'-DENABLE_PRINTING=1' \
 	'-DENABLE_MANAGED_USERS=1' \
 	'-DDATA_REDUCTION_FALLBACK_HOST="http://compress.googlezip.net:80/"' \
-	'-DDATA_REDUCTION_DEV_HOST="http://proxy-dev.googlezip.net:80/"' \
+	'-DDATA_REDUCTION_DEV_HOST="https://proxy-dev.googlezip.net:443/"' \
+	'-DDATA_REDUCTION_DEV_FALLBACK_HOST="http://proxy-dev.googlezip.net:80/"' \
 	'-DSPDY_PROXY_AUTH_ORIGIN="https://proxy.googlezip.net:443/"' \
 	'-DDATA_REDUCTION_PROXY_PROBE_URL="http://check.googlezip.net/connect"' \
 	'-DDATA_REDUCTION_PROXY_WARMUP_URL="http://www.gstatic.com/generate_204"' \
 	'-DVIDEO_HOLE=1' \
+	'-DENABLE_LOAD_COMPLETION_HACKS=1' \
 	'-DANGLE_TRANSLATOR_IMPLEMENTATION' \
 	'-DUSE_OPENSSL=1' \
 	'-DUSE_OPENSSL_CERTS=1' \
@@ -113,6 +114,7 @@
 
 # Flags passed to only C++ (and not C) files.
 LOCAL_CPPFLAGS_Debug := \
+	-fno-exceptions \
 	-fno-rtti \
 	-fno-threadsafe-statics \
 	-fvisibility-inlines-hidden \
@@ -129,7 +131,6 @@
 MY_CFLAGS_Release := \
 	-fstack-protector \
 	--param=ssp-buffer-size=4 \
-	-fno-exceptions \
 	-fno-strict-aliasing \
 	-Wno-unused-parameter \
 	-Wno-missing-field-initializers \
@@ -181,11 +182,13 @@
 	'-DENABLE_PRINTING=1' \
 	'-DENABLE_MANAGED_USERS=1' \
 	'-DDATA_REDUCTION_FALLBACK_HOST="http://compress.googlezip.net:80/"' \
-	'-DDATA_REDUCTION_DEV_HOST="http://proxy-dev.googlezip.net:80/"' \
+	'-DDATA_REDUCTION_DEV_HOST="https://proxy-dev.googlezip.net:443/"' \
+	'-DDATA_REDUCTION_DEV_FALLBACK_HOST="http://proxy-dev.googlezip.net:80/"' \
 	'-DSPDY_PROXY_AUTH_ORIGIN="https://proxy.googlezip.net:443/"' \
 	'-DDATA_REDUCTION_PROXY_PROBE_URL="http://check.googlezip.net/connect"' \
 	'-DDATA_REDUCTION_PROXY_WARMUP_URL="http://www.gstatic.com/generate_204"' \
 	'-DVIDEO_HOLE=1' \
+	'-DENABLE_LOAD_COMPLETION_HACKS=1' \
 	'-DANGLE_TRANSLATOR_IMPLEMENTATION' \
 	'-DUSE_OPENSSL=1' \
 	'-DUSE_OPENSSL_CERTS=1' \
@@ -211,6 +214,7 @@
 
 # Flags passed to only C++ (and not C) files.
 LOCAL_CPPFLAGS_Release := \
+	-fno-exceptions \
 	-fno-rtti \
 	-fno-threadsafe-statics \
 	-fvisibility-inlines-hidden \
@@ -229,46 +233,6 @@
 LOCAL_ASFLAGS := $(LOCAL_CFLAGS)
 ### Rules for final target.
 
-LOCAL_LDFLAGS_Debug := \
-	-Wl,-z,now \
-	-Wl,-z,relro \
-	-Wl,--fatal-warnings \
-	-Wl,-z,noexecstack \
-	-fPIC \
-	-m64 \
-	-fuse-ld=gold \
-	-nostdlib \
-	-Wl,--no-undefined \
-	-Wl,--exclude-libs=ALL \
-	-Wl,--warn-shared-textrel \
-	-Wl,-O1 \
-	-Wl,--as-needed
-
-
-LOCAL_LDFLAGS_Release := \
-	-Wl,-z,now \
-	-Wl,-z,relro \
-	-Wl,--fatal-warnings \
-	-Wl,-z,noexecstack \
-	-fPIC \
-	-m64 \
-	-fuse-ld=gold \
-	-nostdlib \
-	-Wl,--no-undefined \
-	-Wl,--exclude-libs=ALL \
-	-Wl,-O1 \
-	-Wl,--as-needed \
-	-Wl,--gc-sections \
-	-Wl,--warn-shared-textrel
-
-
-LOCAL_LDFLAGS := $(LOCAL_LDFLAGS_$(GYP_CONFIGURATION))
-
-LOCAL_STATIC_LIBRARIES :=
-
-# Enable grouping to fix circular references
-LOCAL_GROUP_STATIC_LIBRARIES := true
-
 LOCAL_SHARED_LIBRARIES := \
 	libstlport \
 	libdl
diff --git a/src/translator_lib.target.darwin-arm.mk b/src/translator_lib.target.darwin-arm.mk
index 6212263..1b8295b 100644
--- a/src/translator_lib.target.darwin-arm.mk
+++ b/src/translator_lib.target.darwin-arm.mk
@@ -5,7 +5,6 @@
 LOCAL_MODULE_CLASS := STATIC_LIBRARIES
 LOCAL_MODULE := third_party_angle_src_translator_lib_gyp
 LOCAL_MODULE_SUFFIX := .a
-LOCAL_MODULE_TAGS := optional
 LOCAL_MODULE_TARGET_ARCH := $(TARGET_$(GYP_VAR_PREFIX)ARCH)
 gyp_intermediate_dir := $(call local-intermediates-dir,,$(GYP_VAR_PREFIX))
 gyp_shared_intermediate_dir := $(call intermediates-dir-for,GYP,shared,,,$(GYP_VAR_PREFIX))
@@ -46,6 +45,7 @@
 	third_party/angle/src/compiler/translator/InitializeVariables.cpp \
 	third_party/angle/src/compiler/translator/IntermTraverse.cpp \
 	third_party/angle/src/compiler/translator/Intermediate.cpp \
+	third_party/angle/src/compiler/translator/IntermNode.cpp \
 	third_party/angle/src/compiler/translator/LoopInfo.cpp \
 	third_party/angle/src/compiler/translator/OutputESSL.cpp \
 	third_party/angle/src/compiler/translator/OutputGLSL.cpp \
@@ -93,7 +93,6 @@
 MY_CFLAGS_Debug := \
 	-fstack-protector \
 	--param=ssp-buffer-size=4 \
-	-fno-exceptions \
 	-fno-strict-aliasing \
 	-Wno-unused-parameter \
 	-Wno-missing-field-initializers \
@@ -103,13 +102,13 @@
 	-Wno-unused-local-typedefs \
 	-Wno-format \
 	-fno-tree-sra \
+	-fno-caller-saves \
+	-Wno-psabi \
 	-fno-partial-inlining \
 	-fno-early-inlining \
 	-fno-tree-copy-prop \
 	-fno-tree-loop-optimize \
 	-fno-move-loop-invariants \
-	-fno-caller-saves \
-	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -128,6 +127,7 @@
 	-Wno-sequence-point \
 	-Os \
 	-g \
+	-gdwarf-4 \
 	-fdata-sections \
 	-ffunction-sections \
 	-fomit-frame-pointer \
@@ -151,11 +151,13 @@
 	'-DENABLE_PRINTING=1' \
 	'-DENABLE_MANAGED_USERS=1' \
 	'-DDATA_REDUCTION_FALLBACK_HOST="http://compress.googlezip.net:80/"' \
-	'-DDATA_REDUCTION_DEV_HOST="http://proxy-dev.googlezip.net:80/"' \
+	'-DDATA_REDUCTION_DEV_HOST="https://proxy-dev.googlezip.net:443/"' \
+	'-DDATA_REDUCTION_DEV_FALLBACK_HOST="http://proxy-dev.googlezip.net:80/"' \
 	'-DSPDY_PROXY_AUTH_ORIGIN="https://proxy.googlezip.net:443/"' \
 	'-DDATA_REDUCTION_PROXY_PROBE_URL="http://check.googlezip.net/connect"' \
 	'-DDATA_REDUCTION_PROXY_WARMUP_URL="http://www.gstatic.com/generate_204"' \
 	'-DVIDEO_HOLE=1' \
+	'-DENABLE_LOAD_COMPLETION_HACKS=1' \
 	'-DANGLE_TRANSLATOR_STATIC' \
 	'-DUSE_OPENSSL=1' \
 	'-DUSE_OPENSSL_CERTS=1' \
@@ -181,6 +183,7 @@
 
 # Flags passed to only C++ (and not C) files.
 LOCAL_CPPFLAGS_Debug := \
+	-fno-exceptions \
 	-fno-rtti \
 	-fno-threadsafe-statics \
 	-fvisibility-inlines-hidden \
@@ -198,7 +201,6 @@
 MY_CFLAGS_Release := \
 	-fstack-protector \
 	--param=ssp-buffer-size=4 \
-	-fno-exceptions \
 	-fno-strict-aliasing \
 	-Wno-unused-parameter \
 	-Wno-missing-field-initializers \
@@ -208,13 +210,13 @@
 	-Wno-unused-local-typedefs \
 	-Wno-format \
 	-fno-tree-sra \
+	-fno-caller-saves \
+	-Wno-psabi \
 	-fno-partial-inlining \
 	-fno-early-inlining \
 	-fno-tree-copy-prop \
 	-fno-tree-loop-optimize \
 	-fno-move-loop-invariants \
-	-fno-caller-saves \
-	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -256,11 +258,13 @@
 	'-DENABLE_PRINTING=1' \
 	'-DENABLE_MANAGED_USERS=1' \
 	'-DDATA_REDUCTION_FALLBACK_HOST="http://compress.googlezip.net:80/"' \
-	'-DDATA_REDUCTION_DEV_HOST="http://proxy-dev.googlezip.net:80/"' \
+	'-DDATA_REDUCTION_DEV_HOST="https://proxy-dev.googlezip.net:443/"' \
+	'-DDATA_REDUCTION_DEV_FALLBACK_HOST="http://proxy-dev.googlezip.net:80/"' \
 	'-DSPDY_PROXY_AUTH_ORIGIN="https://proxy.googlezip.net:443/"' \
 	'-DDATA_REDUCTION_PROXY_PROBE_URL="http://check.googlezip.net/connect"' \
 	'-DDATA_REDUCTION_PROXY_WARMUP_URL="http://www.gstatic.com/generate_204"' \
 	'-DVIDEO_HOLE=1' \
+	'-DENABLE_LOAD_COMPLETION_HACKS=1' \
 	'-DANGLE_TRANSLATOR_STATIC' \
 	'-DUSE_OPENSSL=1' \
 	'-DUSE_OPENSSL_CERTS=1' \
@@ -286,6 +290,7 @@
 
 # Flags passed to only C++ (and not C) files.
 LOCAL_CPPFLAGS_Release := \
+	-fno-exceptions \
 	-fno-rtti \
 	-fno-threadsafe-statics \
 	-fvisibility-inlines-hidden \
@@ -305,50 +310,6 @@
 LOCAL_ASFLAGS := $(LOCAL_CFLAGS)
 ### Rules for final target.
 
-LOCAL_LDFLAGS_Debug := \
-	-Wl,-z,now \
-	-Wl,-z,relro \
-	-Wl,--fatal-warnings \
-	-Wl,-z,noexecstack \
-	-fPIC \
-	-Wl,-z,relro \
-	-Wl,-z,now \
-	-fuse-ld=gold \
-	-nostdlib \
-	-Wl,--no-undefined \
-	-Wl,--exclude-libs=ALL \
-	-Wl,--icf=safe \
-	-Wl,--warn-shared-textrel \
-	-Wl,-O1 \
-	-Wl,--as-needed
-
-
-LOCAL_LDFLAGS_Release := \
-	-Wl,-z,now \
-	-Wl,-z,relro \
-	-Wl,--fatal-warnings \
-	-Wl,-z,noexecstack \
-	-fPIC \
-	-Wl,-z,relro \
-	-Wl,-z,now \
-	-fuse-ld=gold \
-	-nostdlib \
-	-Wl,--no-undefined \
-	-Wl,--exclude-libs=ALL \
-	-Wl,--icf=safe \
-	-Wl,-O1 \
-	-Wl,--as-needed \
-	-Wl,--gc-sections \
-	-Wl,--warn-shared-textrel
-
-
-LOCAL_LDFLAGS := $(LOCAL_LDFLAGS_$(GYP_CONFIGURATION))
-
-LOCAL_STATIC_LIBRARIES :=
-
-# Enable grouping to fix circular references
-LOCAL_GROUP_STATIC_LIBRARIES := true
-
 LOCAL_SHARED_LIBRARIES := \
 	libstlport \
 	libdl
diff --git a/src/translator_lib.target.darwin-arm64.mk b/src/translator_lib.target.darwin-arm64.mk
index bcc8f01..fe67a64 100644
--- a/src/translator_lib.target.darwin-arm64.mk
+++ b/src/translator_lib.target.darwin-arm64.mk
@@ -5,7 +5,6 @@
 LOCAL_MODULE_CLASS := STATIC_LIBRARIES
 LOCAL_MODULE := third_party_angle_src_translator_lib_gyp
 LOCAL_MODULE_SUFFIX := .a
-LOCAL_MODULE_TAGS := optional
 LOCAL_MODULE_TARGET_ARCH := $(TARGET_$(GYP_VAR_PREFIX)ARCH)
 gyp_intermediate_dir := $(call local-intermediates-dir,,$(GYP_VAR_PREFIX))
 gyp_shared_intermediate_dir := $(call intermediates-dir-for,GYP,shared,,,$(GYP_VAR_PREFIX))
@@ -46,6 +45,7 @@
 	third_party/angle/src/compiler/translator/InitializeVariables.cpp \
 	third_party/angle/src/compiler/translator/IntermTraverse.cpp \
 	third_party/angle/src/compiler/translator/Intermediate.cpp \
+	third_party/angle/src/compiler/translator/IntermNode.cpp \
 	third_party/angle/src/compiler/translator/LoopInfo.cpp \
 	third_party/angle/src/compiler/translator/OutputESSL.cpp \
 	third_party/angle/src/compiler/translator/OutputGLSL.cpp \
@@ -92,7 +92,6 @@
 # Flags passed to both C and C++ files.
 MY_CFLAGS_Debug := \
 	--param=ssp-buffer-size=4 \
-	-fno-exceptions \
 	-fno-strict-aliasing \
 	-Wno-unused-parameter \
 	-Wno-missing-field-initializers \
@@ -118,6 +117,7 @@
 	-Wno-sequence-point \
 	-Os \
 	-g \
+	-gdwarf-4 \
 	-fdata-sections \
 	-ffunction-sections \
 	-funwind-tables
@@ -140,11 +140,13 @@
 	'-DENABLE_PRINTING=1' \
 	'-DENABLE_MANAGED_USERS=1' \
 	'-DDATA_REDUCTION_FALLBACK_HOST="http://compress.googlezip.net:80/"' \
-	'-DDATA_REDUCTION_DEV_HOST="http://proxy-dev.googlezip.net:80/"' \
+	'-DDATA_REDUCTION_DEV_HOST="https://proxy-dev.googlezip.net:443/"' \
+	'-DDATA_REDUCTION_DEV_FALLBACK_HOST="http://proxy-dev.googlezip.net:80/"' \
 	'-DSPDY_PROXY_AUTH_ORIGIN="https://proxy.googlezip.net:443/"' \
 	'-DDATA_REDUCTION_PROXY_PROBE_URL="http://check.googlezip.net/connect"' \
 	'-DDATA_REDUCTION_PROXY_WARMUP_URL="http://www.gstatic.com/generate_204"' \
 	'-DVIDEO_HOLE=1' \
+	'-DENABLE_LOAD_COMPLETION_HACKS=1' \
 	'-DANGLE_TRANSLATOR_STATIC' \
 	'-DUSE_OPENSSL=1' \
 	'-DUSE_OPENSSL_CERTS=1' \
@@ -170,6 +172,7 @@
 
 # Flags passed to only C++ (and not C) files.
 LOCAL_CPPFLAGS_Debug := \
+	-fno-exceptions \
 	-fno-rtti \
 	-fno-threadsafe-statics \
 	-fvisibility-inlines-hidden \
@@ -185,7 +188,6 @@
 # Flags passed to both C and C++ files.
 MY_CFLAGS_Release := \
 	--param=ssp-buffer-size=4 \
-	-fno-exceptions \
 	-fno-strict-aliasing \
 	-Wno-unused-parameter \
 	-Wno-missing-field-initializers \
@@ -233,11 +235,13 @@
 	'-DENABLE_PRINTING=1' \
 	'-DENABLE_MANAGED_USERS=1' \
 	'-DDATA_REDUCTION_FALLBACK_HOST="http://compress.googlezip.net:80/"' \
-	'-DDATA_REDUCTION_DEV_HOST="http://proxy-dev.googlezip.net:80/"' \
+	'-DDATA_REDUCTION_DEV_HOST="https://proxy-dev.googlezip.net:443/"' \
+	'-DDATA_REDUCTION_DEV_FALLBACK_HOST="http://proxy-dev.googlezip.net:80/"' \
 	'-DSPDY_PROXY_AUTH_ORIGIN="https://proxy.googlezip.net:443/"' \
 	'-DDATA_REDUCTION_PROXY_PROBE_URL="http://check.googlezip.net/connect"' \
 	'-DDATA_REDUCTION_PROXY_WARMUP_URL="http://www.gstatic.com/generate_204"' \
 	'-DVIDEO_HOLE=1' \
+	'-DENABLE_LOAD_COMPLETION_HACKS=1' \
 	'-DANGLE_TRANSLATOR_STATIC' \
 	'-DUSE_OPENSSL=1' \
 	'-DUSE_OPENSSL_CERTS=1' \
@@ -263,6 +267,7 @@
 
 # Flags passed to only C++ (and not C) files.
 LOCAL_CPPFLAGS_Release := \
+	-fno-exceptions \
 	-fno-rtti \
 	-fno-threadsafe-statics \
 	-fvisibility-inlines-hidden \
@@ -281,42 +286,6 @@
 LOCAL_ASFLAGS := $(LOCAL_CFLAGS)
 ### Rules for final target.
 
-LOCAL_LDFLAGS_Debug := \
-	-Wl,-z,now \
-	-Wl,-z,relro \
-	-Wl,--fatal-warnings \
-	-Wl,-z,noexecstack \
-	-fPIC \
-	-nostdlib \
-	-Wl,--no-undefined \
-	-Wl,--exclude-libs=ALL \
-	-Wl,--warn-shared-textrel \
-	-Wl,-O1 \
-	-Wl,--as-needed
-
-
-LOCAL_LDFLAGS_Release := \
-	-Wl,-z,now \
-	-Wl,-z,relro \
-	-Wl,--fatal-warnings \
-	-Wl,-z,noexecstack \
-	-fPIC \
-	-nostdlib \
-	-Wl,--no-undefined \
-	-Wl,--exclude-libs=ALL \
-	-Wl,-O1 \
-	-Wl,--as-needed \
-	-Wl,--gc-sections \
-	-Wl,--warn-shared-textrel
-
-
-LOCAL_LDFLAGS := $(LOCAL_LDFLAGS_$(GYP_CONFIGURATION))
-
-LOCAL_STATIC_LIBRARIES :=
-
-# Enable grouping to fix circular references
-LOCAL_GROUP_STATIC_LIBRARIES := true
-
 LOCAL_SHARED_LIBRARIES := \
 	libstlport \
 	libdl
diff --git a/src/translator_lib.target.darwin-mips.mk b/src/translator_lib.target.darwin-mips.mk
index 6d10b0b..a8ba23e 100644
--- a/src/translator_lib.target.darwin-mips.mk
+++ b/src/translator_lib.target.darwin-mips.mk
@@ -5,7 +5,6 @@
 LOCAL_MODULE_CLASS := STATIC_LIBRARIES
 LOCAL_MODULE := third_party_angle_src_translator_lib_gyp
 LOCAL_MODULE_SUFFIX := .a
-LOCAL_MODULE_TAGS := optional
 LOCAL_MODULE_TARGET_ARCH := $(TARGET_$(GYP_VAR_PREFIX)ARCH)
 gyp_intermediate_dir := $(call local-intermediates-dir,,$(GYP_VAR_PREFIX))
 gyp_shared_intermediate_dir := $(call intermediates-dir-for,GYP,shared,,,$(GYP_VAR_PREFIX))
@@ -46,6 +45,7 @@
 	third_party/angle/src/compiler/translator/InitializeVariables.cpp \
 	third_party/angle/src/compiler/translator/IntermTraverse.cpp \
 	third_party/angle/src/compiler/translator/Intermediate.cpp \
+	third_party/angle/src/compiler/translator/IntermNode.cpp \
 	third_party/angle/src/compiler/translator/LoopInfo.cpp \
 	third_party/angle/src/compiler/translator/OutputESSL.cpp \
 	third_party/angle/src/compiler/translator/OutputGLSL.cpp \
@@ -94,7 +94,6 @@
 	-fstack-protector \
 	--param=ssp-buffer-size=4 \
 	 \
-	-fno-exceptions \
 	-fno-strict-aliasing \
 	-Wno-unused-parameter \
 	-Wno-missing-field-initializers \
@@ -103,8 +102,6 @@
 	-fPIC \
 	-Wno-unused-local-typedefs \
 	-Wno-format \
-	-EL \
-	-mhard-float \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -123,6 +120,7 @@
 	-Wno-sequence-point \
 	-Os \
 	-g \
+	-gdwarf-4 \
 	-fdata-sections \
 	-ffunction-sections \
 	-fomit-frame-pointer \
@@ -146,11 +144,13 @@
 	'-DENABLE_PRINTING=1' \
 	'-DENABLE_MANAGED_USERS=1' \
 	'-DDATA_REDUCTION_FALLBACK_HOST="http://compress.googlezip.net:80/"' \
-	'-DDATA_REDUCTION_DEV_HOST="http://proxy-dev.googlezip.net:80/"' \
+	'-DDATA_REDUCTION_DEV_HOST="https://proxy-dev.googlezip.net:443/"' \
+	'-DDATA_REDUCTION_DEV_FALLBACK_HOST="http://proxy-dev.googlezip.net:80/"' \
 	'-DSPDY_PROXY_AUTH_ORIGIN="https://proxy.googlezip.net:443/"' \
 	'-DDATA_REDUCTION_PROXY_PROBE_URL="http://check.googlezip.net/connect"' \
 	'-DDATA_REDUCTION_PROXY_WARMUP_URL="http://www.gstatic.com/generate_204"' \
 	'-DVIDEO_HOLE=1' \
+	'-DENABLE_LOAD_COMPLETION_HACKS=1' \
 	'-DANGLE_TRANSLATOR_STATIC' \
 	'-DUSE_OPENSSL=1' \
 	'-DUSE_OPENSSL_CERTS=1' \
@@ -176,6 +176,7 @@
 
 # Flags passed to only C++ (and not C) files.
 LOCAL_CPPFLAGS_Debug := \
+	-fno-exceptions \
 	-fno-rtti \
 	-fno-threadsafe-statics \
 	-fvisibility-inlines-hidden \
@@ -194,7 +195,6 @@
 	-fstack-protector \
 	--param=ssp-buffer-size=4 \
 	 \
-	-fno-exceptions \
 	-fno-strict-aliasing \
 	-Wno-unused-parameter \
 	-Wno-missing-field-initializers \
@@ -203,8 +203,6 @@
 	-fPIC \
 	-Wno-unused-local-typedefs \
 	-Wno-format \
-	-EL \
-	-mhard-float \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -246,11 +244,13 @@
 	'-DENABLE_PRINTING=1' \
 	'-DENABLE_MANAGED_USERS=1' \
 	'-DDATA_REDUCTION_FALLBACK_HOST="http://compress.googlezip.net:80/"' \
-	'-DDATA_REDUCTION_DEV_HOST="http://proxy-dev.googlezip.net:80/"' \
+	'-DDATA_REDUCTION_DEV_HOST="https://proxy-dev.googlezip.net:443/"' \
+	'-DDATA_REDUCTION_DEV_FALLBACK_HOST="http://proxy-dev.googlezip.net:80/"' \
 	'-DSPDY_PROXY_AUTH_ORIGIN="https://proxy.googlezip.net:443/"' \
 	'-DDATA_REDUCTION_PROXY_PROBE_URL="http://check.googlezip.net/connect"' \
 	'-DDATA_REDUCTION_PROXY_WARMUP_URL="http://www.gstatic.com/generate_204"' \
 	'-DVIDEO_HOLE=1' \
+	'-DENABLE_LOAD_COMPLETION_HACKS=1' \
 	'-DANGLE_TRANSLATOR_STATIC' \
 	'-DUSE_OPENSSL=1' \
 	'-DUSE_OPENSSL_CERTS=1' \
@@ -276,6 +276,7 @@
 
 # Flags passed to only C++ (and not C) files.
 LOCAL_CPPFLAGS_Release := \
+	-fno-exceptions \
 	-fno-rtti \
 	-fno-threadsafe-statics \
 	-fvisibility-inlines-hidden \
@@ -295,46 +296,6 @@
 LOCAL_ASFLAGS := $(LOCAL_CFLAGS)
 ### Rules for final target.
 
-LOCAL_LDFLAGS_Debug := \
-	-Wl,-z,now \
-	-Wl,-z,relro \
-	-Wl,--fatal-warnings \
-	-Wl,-z,noexecstack \
-	-fPIC \
-	-EL \
-	-Wl,--no-keep-memory \
-	-nostdlib \
-	-Wl,--no-undefined \
-	-Wl,--exclude-libs=ALL \
-	-Wl,--warn-shared-textrel \
-	-Wl,-O1 \
-	-Wl,--as-needed
-
-
-LOCAL_LDFLAGS_Release := \
-	-Wl,-z,now \
-	-Wl,-z,relro \
-	-Wl,--fatal-warnings \
-	-Wl,-z,noexecstack \
-	-fPIC \
-	-EL \
-	-Wl,--no-keep-memory \
-	-nostdlib \
-	-Wl,--no-undefined \
-	-Wl,--exclude-libs=ALL \
-	-Wl,-O1 \
-	-Wl,--as-needed \
-	-Wl,--gc-sections \
-	-Wl,--warn-shared-textrel
-
-
-LOCAL_LDFLAGS := $(LOCAL_LDFLAGS_$(GYP_CONFIGURATION))
-
-LOCAL_STATIC_LIBRARIES :=
-
-# Enable grouping to fix circular references
-LOCAL_GROUP_STATIC_LIBRARIES := true
-
 LOCAL_SHARED_LIBRARIES := \
 	libstlport \
 	libdl
diff --git a/src/translator_lib.target.darwin-x86.mk b/src/translator_lib.target.darwin-x86.mk
index 3706879..937c6c3 100644
--- a/src/translator_lib.target.darwin-x86.mk
+++ b/src/translator_lib.target.darwin-x86.mk
@@ -5,7 +5,6 @@
 LOCAL_MODULE_CLASS := STATIC_LIBRARIES
 LOCAL_MODULE := third_party_angle_src_translator_lib_gyp
 LOCAL_MODULE_SUFFIX := .a
-LOCAL_MODULE_TAGS := optional
 LOCAL_MODULE_TARGET_ARCH := $(TARGET_$(GYP_VAR_PREFIX)ARCH)
 gyp_intermediate_dir := $(call local-intermediates-dir,,$(GYP_VAR_PREFIX))
 gyp_shared_intermediate_dir := $(call intermediates-dir-for,GYP,shared,,,$(GYP_VAR_PREFIX))
@@ -46,6 +45,7 @@
 	third_party/angle/src/compiler/translator/InitializeVariables.cpp \
 	third_party/angle/src/compiler/translator/IntermTraverse.cpp \
 	third_party/angle/src/compiler/translator/Intermediate.cpp \
+	third_party/angle/src/compiler/translator/IntermNode.cpp \
 	third_party/angle/src/compiler/translator/LoopInfo.cpp \
 	third_party/angle/src/compiler/translator/OutputESSL.cpp \
 	third_party/angle/src/compiler/translator/OutputGLSL.cpp \
@@ -92,7 +92,6 @@
 # Flags passed to both C and C++ files.
 MY_CFLAGS_Debug := \
 	--param=ssp-buffer-size=4 \
-	-fno-exceptions \
 	-fno-strict-aliasing \
 	-Wno-unused-parameter \
 	-Wno-missing-field-initializers \
@@ -123,6 +122,7 @@
 	-Wno-sequence-point \
 	-Os \
 	-g \
+	-gdwarf-4 \
 	-fdata-sections \
 	-ffunction-sections \
 	-fomit-frame-pointer \
@@ -146,11 +146,13 @@
 	'-DENABLE_PRINTING=1' \
 	'-DENABLE_MANAGED_USERS=1' \
 	'-DDATA_REDUCTION_FALLBACK_HOST="http://compress.googlezip.net:80/"' \
-	'-DDATA_REDUCTION_DEV_HOST="http://proxy-dev.googlezip.net:80/"' \
+	'-DDATA_REDUCTION_DEV_HOST="https://proxy-dev.googlezip.net:443/"' \
+	'-DDATA_REDUCTION_DEV_FALLBACK_HOST="http://proxy-dev.googlezip.net:80/"' \
 	'-DSPDY_PROXY_AUTH_ORIGIN="https://proxy.googlezip.net:443/"' \
 	'-DDATA_REDUCTION_PROXY_PROBE_URL="http://check.googlezip.net/connect"' \
 	'-DDATA_REDUCTION_PROXY_WARMUP_URL="http://www.gstatic.com/generate_204"' \
 	'-DVIDEO_HOLE=1' \
+	'-DENABLE_LOAD_COMPLETION_HACKS=1' \
 	'-DANGLE_TRANSLATOR_STATIC' \
 	'-DUSE_OPENSSL=1' \
 	'-DUSE_OPENSSL_CERTS=1' \
@@ -176,6 +178,7 @@
 
 # Flags passed to only C++ (and not C) files.
 LOCAL_CPPFLAGS_Debug := \
+	-fno-exceptions \
 	-fno-rtti \
 	-fno-threadsafe-statics \
 	-fvisibility-inlines-hidden \
@@ -191,7 +194,6 @@
 # Flags passed to both C and C++ files.
 MY_CFLAGS_Release := \
 	--param=ssp-buffer-size=4 \
-	-fno-exceptions \
 	-fno-strict-aliasing \
 	-Wno-unused-parameter \
 	-Wno-missing-field-initializers \
@@ -245,11 +247,13 @@
 	'-DENABLE_PRINTING=1' \
 	'-DENABLE_MANAGED_USERS=1' \
 	'-DDATA_REDUCTION_FALLBACK_HOST="http://compress.googlezip.net:80/"' \
-	'-DDATA_REDUCTION_DEV_HOST="http://proxy-dev.googlezip.net:80/"' \
+	'-DDATA_REDUCTION_DEV_HOST="https://proxy-dev.googlezip.net:443/"' \
+	'-DDATA_REDUCTION_DEV_FALLBACK_HOST="http://proxy-dev.googlezip.net:80/"' \
 	'-DSPDY_PROXY_AUTH_ORIGIN="https://proxy.googlezip.net:443/"' \
 	'-DDATA_REDUCTION_PROXY_PROBE_URL="http://check.googlezip.net/connect"' \
 	'-DDATA_REDUCTION_PROXY_WARMUP_URL="http://www.gstatic.com/generate_204"' \
 	'-DVIDEO_HOLE=1' \
+	'-DENABLE_LOAD_COMPLETION_HACKS=1' \
 	'-DANGLE_TRANSLATOR_STATIC' \
 	'-DUSE_OPENSSL=1' \
 	'-DUSE_OPENSSL_CERTS=1' \
@@ -275,6 +279,7 @@
 
 # Flags passed to only C++ (and not C) files.
 LOCAL_CPPFLAGS_Release := \
+	-fno-exceptions \
 	-fno-rtti \
 	-fno-threadsafe-statics \
 	-fvisibility-inlines-hidden \
@@ -293,46 +298,6 @@
 LOCAL_ASFLAGS := $(LOCAL_CFLAGS)
 ### Rules for final target.
 
-LOCAL_LDFLAGS_Debug := \
-	-Wl,-z,now \
-	-Wl,-z,relro \
-	-Wl,--fatal-warnings \
-	-Wl,-z,noexecstack \
-	-fPIC \
-	-m32 \
-	-fuse-ld=gold \
-	-nostdlib \
-	-Wl,--no-undefined \
-	-Wl,--exclude-libs=ALL \
-	-Wl,--warn-shared-textrel \
-	-Wl,-O1 \
-	-Wl,--as-needed
-
-
-LOCAL_LDFLAGS_Release := \
-	-Wl,-z,now \
-	-Wl,-z,relro \
-	-Wl,--fatal-warnings \
-	-Wl,-z,noexecstack \
-	-fPIC \
-	-m32 \
-	-fuse-ld=gold \
-	-nostdlib \
-	-Wl,--no-undefined \
-	-Wl,--exclude-libs=ALL \
-	-Wl,-O1 \
-	-Wl,--as-needed \
-	-Wl,--gc-sections \
-	-Wl,--warn-shared-textrel
-
-
-LOCAL_LDFLAGS := $(LOCAL_LDFLAGS_$(GYP_CONFIGURATION))
-
-LOCAL_STATIC_LIBRARIES :=
-
-# Enable grouping to fix circular references
-LOCAL_GROUP_STATIC_LIBRARIES := true
-
 LOCAL_SHARED_LIBRARIES := \
 	libstlport \
 	libdl
diff --git a/src/translator_lib.target.darwin-x86_64.mk b/src/translator_lib.target.darwin-x86_64.mk
index 413f480..5d1d2b0 100644
--- a/src/translator_lib.target.darwin-x86_64.mk
+++ b/src/translator_lib.target.darwin-x86_64.mk
@@ -5,7 +5,6 @@
 LOCAL_MODULE_CLASS := STATIC_LIBRARIES
 LOCAL_MODULE := third_party_angle_src_translator_lib_gyp
 LOCAL_MODULE_SUFFIX := .a
-LOCAL_MODULE_TAGS := optional
 LOCAL_MODULE_TARGET_ARCH := $(TARGET_$(GYP_VAR_PREFIX)ARCH)
 gyp_intermediate_dir := $(call local-intermediates-dir,,$(GYP_VAR_PREFIX))
 gyp_shared_intermediate_dir := $(call intermediates-dir-for,GYP,shared,,,$(GYP_VAR_PREFIX))
@@ -46,6 +45,7 @@
 	third_party/angle/src/compiler/translator/InitializeVariables.cpp \
 	third_party/angle/src/compiler/translator/IntermTraverse.cpp \
 	third_party/angle/src/compiler/translator/Intermediate.cpp \
+	third_party/angle/src/compiler/translator/IntermNode.cpp \
 	third_party/angle/src/compiler/translator/LoopInfo.cpp \
 	third_party/angle/src/compiler/translator/OutputESSL.cpp \
 	third_party/angle/src/compiler/translator/OutputGLSL.cpp \
@@ -93,7 +93,6 @@
 MY_CFLAGS_Debug := \
 	-fstack-protector \
 	--param=ssp-buffer-size=4 \
-	-fno-exceptions \
 	-fno-strict-aliasing \
 	-Wno-unused-parameter \
 	-Wno-missing-field-initializers \
@@ -122,6 +121,7 @@
 	-Wno-sequence-point \
 	-Os \
 	-g \
+	-gdwarf-4 \
 	-fdata-sections \
 	-ffunction-sections \
 	-fomit-frame-pointer \
@@ -145,11 +145,13 @@
 	'-DENABLE_PRINTING=1' \
 	'-DENABLE_MANAGED_USERS=1' \
 	'-DDATA_REDUCTION_FALLBACK_HOST="http://compress.googlezip.net:80/"' \
-	'-DDATA_REDUCTION_DEV_HOST="http://proxy-dev.googlezip.net:80/"' \
+	'-DDATA_REDUCTION_DEV_HOST="https://proxy-dev.googlezip.net:443/"' \
+	'-DDATA_REDUCTION_DEV_FALLBACK_HOST="http://proxy-dev.googlezip.net:80/"' \
 	'-DSPDY_PROXY_AUTH_ORIGIN="https://proxy.googlezip.net:443/"' \
 	'-DDATA_REDUCTION_PROXY_PROBE_URL="http://check.googlezip.net/connect"' \
 	'-DDATA_REDUCTION_PROXY_WARMUP_URL="http://www.gstatic.com/generate_204"' \
 	'-DVIDEO_HOLE=1' \
+	'-DENABLE_LOAD_COMPLETION_HACKS=1' \
 	'-DANGLE_TRANSLATOR_STATIC' \
 	'-DUSE_OPENSSL=1' \
 	'-DUSE_OPENSSL_CERTS=1' \
@@ -175,6 +177,7 @@
 
 # Flags passed to only C++ (and not C) files.
 LOCAL_CPPFLAGS_Debug := \
+	-fno-exceptions \
 	-fno-rtti \
 	-fno-threadsafe-statics \
 	-fvisibility-inlines-hidden \
@@ -191,7 +194,6 @@
 MY_CFLAGS_Release := \
 	-fstack-protector \
 	--param=ssp-buffer-size=4 \
-	-fno-exceptions \
 	-fno-strict-aliasing \
 	-Wno-unused-parameter \
 	-Wno-missing-field-initializers \
@@ -243,11 +245,13 @@
 	'-DENABLE_PRINTING=1' \
 	'-DENABLE_MANAGED_USERS=1' \
 	'-DDATA_REDUCTION_FALLBACK_HOST="http://compress.googlezip.net:80/"' \
-	'-DDATA_REDUCTION_DEV_HOST="http://proxy-dev.googlezip.net:80/"' \
+	'-DDATA_REDUCTION_DEV_HOST="https://proxy-dev.googlezip.net:443/"' \
+	'-DDATA_REDUCTION_DEV_FALLBACK_HOST="http://proxy-dev.googlezip.net:80/"' \
 	'-DSPDY_PROXY_AUTH_ORIGIN="https://proxy.googlezip.net:443/"' \
 	'-DDATA_REDUCTION_PROXY_PROBE_URL="http://check.googlezip.net/connect"' \
 	'-DDATA_REDUCTION_PROXY_WARMUP_URL="http://www.gstatic.com/generate_204"' \
 	'-DVIDEO_HOLE=1' \
+	'-DENABLE_LOAD_COMPLETION_HACKS=1' \
 	'-DANGLE_TRANSLATOR_STATIC' \
 	'-DUSE_OPENSSL=1' \
 	'-DUSE_OPENSSL_CERTS=1' \
@@ -273,6 +277,7 @@
 
 # Flags passed to only C++ (and not C) files.
 LOCAL_CPPFLAGS_Release := \
+	-fno-exceptions \
 	-fno-rtti \
 	-fno-threadsafe-statics \
 	-fvisibility-inlines-hidden \
@@ -291,46 +296,6 @@
 LOCAL_ASFLAGS := $(LOCAL_CFLAGS)
 ### Rules for final target.
 
-LOCAL_LDFLAGS_Debug := \
-	-Wl,-z,now \
-	-Wl,-z,relro \
-	-Wl,--fatal-warnings \
-	-Wl,-z,noexecstack \
-	-fPIC \
-	-m64 \
-	-fuse-ld=gold \
-	-nostdlib \
-	-Wl,--no-undefined \
-	-Wl,--exclude-libs=ALL \
-	-Wl,--warn-shared-textrel \
-	-Wl,-O1 \
-	-Wl,--as-needed
-
-
-LOCAL_LDFLAGS_Release := \
-	-Wl,-z,now \
-	-Wl,-z,relro \
-	-Wl,--fatal-warnings \
-	-Wl,-z,noexecstack \
-	-fPIC \
-	-m64 \
-	-fuse-ld=gold \
-	-nostdlib \
-	-Wl,--no-undefined \
-	-Wl,--exclude-libs=ALL \
-	-Wl,-O1 \
-	-Wl,--as-needed \
-	-Wl,--gc-sections \
-	-Wl,--warn-shared-textrel
-
-
-LOCAL_LDFLAGS := $(LOCAL_LDFLAGS_$(GYP_CONFIGURATION))
-
-LOCAL_STATIC_LIBRARIES :=
-
-# Enable grouping to fix circular references
-LOCAL_GROUP_STATIC_LIBRARIES := true
-
 LOCAL_SHARED_LIBRARIES := \
 	libstlport \
 	libdl
diff --git a/src/translator_lib.target.linux-arm.mk b/src/translator_lib.target.linux-arm.mk
index 6212263..1b8295b 100644
--- a/src/translator_lib.target.linux-arm.mk
+++ b/src/translator_lib.target.linux-arm.mk
@@ -5,7 +5,6 @@
 LOCAL_MODULE_CLASS := STATIC_LIBRARIES
 LOCAL_MODULE := third_party_angle_src_translator_lib_gyp
 LOCAL_MODULE_SUFFIX := .a
-LOCAL_MODULE_TAGS := optional
 LOCAL_MODULE_TARGET_ARCH := $(TARGET_$(GYP_VAR_PREFIX)ARCH)
 gyp_intermediate_dir := $(call local-intermediates-dir,,$(GYP_VAR_PREFIX))
 gyp_shared_intermediate_dir := $(call intermediates-dir-for,GYP,shared,,,$(GYP_VAR_PREFIX))
@@ -46,6 +45,7 @@
 	third_party/angle/src/compiler/translator/InitializeVariables.cpp \
 	third_party/angle/src/compiler/translator/IntermTraverse.cpp \
 	third_party/angle/src/compiler/translator/Intermediate.cpp \
+	third_party/angle/src/compiler/translator/IntermNode.cpp \
 	third_party/angle/src/compiler/translator/LoopInfo.cpp \
 	third_party/angle/src/compiler/translator/OutputESSL.cpp \
 	third_party/angle/src/compiler/translator/OutputGLSL.cpp \
@@ -93,7 +93,6 @@
 MY_CFLAGS_Debug := \
 	-fstack-protector \
 	--param=ssp-buffer-size=4 \
-	-fno-exceptions \
 	-fno-strict-aliasing \
 	-Wno-unused-parameter \
 	-Wno-missing-field-initializers \
@@ -103,13 +102,13 @@
 	-Wno-unused-local-typedefs \
 	-Wno-format \
 	-fno-tree-sra \
+	-fno-caller-saves \
+	-Wno-psabi \
 	-fno-partial-inlining \
 	-fno-early-inlining \
 	-fno-tree-copy-prop \
 	-fno-tree-loop-optimize \
 	-fno-move-loop-invariants \
-	-fno-caller-saves \
-	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -128,6 +127,7 @@
 	-Wno-sequence-point \
 	-Os \
 	-g \
+	-gdwarf-4 \
 	-fdata-sections \
 	-ffunction-sections \
 	-fomit-frame-pointer \
@@ -151,11 +151,13 @@
 	'-DENABLE_PRINTING=1' \
 	'-DENABLE_MANAGED_USERS=1' \
 	'-DDATA_REDUCTION_FALLBACK_HOST="http://compress.googlezip.net:80/"' \
-	'-DDATA_REDUCTION_DEV_HOST="http://proxy-dev.googlezip.net:80/"' \
+	'-DDATA_REDUCTION_DEV_HOST="https://proxy-dev.googlezip.net:443/"' \
+	'-DDATA_REDUCTION_DEV_FALLBACK_HOST="http://proxy-dev.googlezip.net:80/"' \
 	'-DSPDY_PROXY_AUTH_ORIGIN="https://proxy.googlezip.net:443/"' \
 	'-DDATA_REDUCTION_PROXY_PROBE_URL="http://check.googlezip.net/connect"' \
 	'-DDATA_REDUCTION_PROXY_WARMUP_URL="http://www.gstatic.com/generate_204"' \
 	'-DVIDEO_HOLE=1' \
+	'-DENABLE_LOAD_COMPLETION_HACKS=1' \
 	'-DANGLE_TRANSLATOR_STATIC' \
 	'-DUSE_OPENSSL=1' \
 	'-DUSE_OPENSSL_CERTS=1' \
@@ -181,6 +183,7 @@
 
 # Flags passed to only C++ (and not C) files.
 LOCAL_CPPFLAGS_Debug := \
+	-fno-exceptions \
 	-fno-rtti \
 	-fno-threadsafe-statics \
 	-fvisibility-inlines-hidden \
@@ -198,7 +201,6 @@
 MY_CFLAGS_Release := \
 	-fstack-protector \
 	--param=ssp-buffer-size=4 \
-	-fno-exceptions \
 	-fno-strict-aliasing \
 	-Wno-unused-parameter \
 	-Wno-missing-field-initializers \
@@ -208,13 +210,13 @@
 	-Wno-unused-local-typedefs \
 	-Wno-format \
 	-fno-tree-sra \
+	-fno-caller-saves \
+	-Wno-psabi \
 	-fno-partial-inlining \
 	-fno-early-inlining \
 	-fno-tree-copy-prop \
 	-fno-tree-loop-optimize \
 	-fno-move-loop-invariants \
-	-fno-caller-saves \
-	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -256,11 +258,13 @@
 	'-DENABLE_PRINTING=1' \
 	'-DENABLE_MANAGED_USERS=1' \
 	'-DDATA_REDUCTION_FALLBACK_HOST="http://compress.googlezip.net:80/"' \
-	'-DDATA_REDUCTION_DEV_HOST="http://proxy-dev.googlezip.net:80/"' \
+	'-DDATA_REDUCTION_DEV_HOST="https://proxy-dev.googlezip.net:443/"' \
+	'-DDATA_REDUCTION_DEV_FALLBACK_HOST="http://proxy-dev.googlezip.net:80/"' \
 	'-DSPDY_PROXY_AUTH_ORIGIN="https://proxy.googlezip.net:443/"' \
 	'-DDATA_REDUCTION_PROXY_PROBE_URL="http://check.googlezip.net/connect"' \
 	'-DDATA_REDUCTION_PROXY_WARMUP_URL="http://www.gstatic.com/generate_204"' \
 	'-DVIDEO_HOLE=1' \
+	'-DENABLE_LOAD_COMPLETION_HACKS=1' \
 	'-DANGLE_TRANSLATOR_STATIC' \
 	'-DUSE_OPENSSL=1' \
 	'-DUSE_OPENSSL_CERTS=1' \
@@ -286,6 +290,7 @@
 
 # Flags passed to only C++ (and not C) files.
 LOCAL_CPPFLAGS_Release := \
+	-fno-exceptions \
 	-fno-rtti \
 	-fno-threadsafe-statics \
 	-fvisibility-inlines-hidden \
@@ -305,50 +310,6 @@
 LOCAL_ASFLAGS := $(LOCAL_CFLAGS)
 ### Rules for final target.
 
-LOCAL_LDFLAGS_Debug := \
-	-Wl,-z,now \
-	-Wl,-z,relro \
-	-Wl,--fatal-warnings \
-	-Wl,-z,noexecstack \
-	-fPIC \
-	-Wl,-z,relro \
-	-Wl,-z,now \
-	-fuse-ld=gold \
-	-nostdlib \
-	-Wl,--no-undefined \
-	-Wl,--exclude-libs=ALL \
-	-Wl,--icf=safe \
-	-Wl,--warn-shared-textrel \
-	-Wl,-O1 \
-	-Wl,--as-needed
-
-
-LOCAL_LDFLAGS_Release := \
-	-Wl,-z,now \
-	-Wl,-z,relro \
-	-Wl,--fatal-warnings \
-	-Wl,-z,noexecstack \
-	-fPIC \
-	-Wl,-z,relro \
-	-Wl,-z,now \
-	-fuse-ld=gold \
-	-nostdlib \
-	-Wl,--no-undefined \
-	-Wl,--exclude-libs=ALL \
-	-Wl,--icf=safe \
-	-Wl,-O1 \
-	-Wl,--as-needed \
-	-Wl,--gc-sections \
-	-Wl,--warn-shared-textrel
-
-
-LOCAL_LDFLAGS := $(LOCAL_LDFLAGS_$(GYP_CONFIGURATION))
-
-LOCAL_STATIC_LIBRARIES :=
-
-# Enable grouping to fix circular references
-LOCAL_GROUP_STATIC_LIBRARIES := true
-
 LOCAL_SHARED_LIBRARIES := \
 	libstlport \
 	libdl
diff --git a/src/translator_lib.target.linux-arm64.mk b/src/translator_lib.target.linux-arm64.mk
index bcc8f01..fe67a64 100644
--- a/src/translator_lib.target.linux-arm64.mk
+++ b/src/translator_lib.target.linux-arm64.mk
@@ -5,7 +5,6 @@
 LOCAL_MODULE_CLASS := STATIC_LIBRARIES
 LOCAL_MODULE := third_party_angle_src_translator_lib_gyp
 LOCAL_MODULE_SUFFIX := .a
-LOCAL_MODULE_TAGS := optional
 LOCAL_MODULE_TARGET_ARCH := $(TARGET_$(GYP_VAR_PREFIX)ARCH)
 gyp_intermediate_dir := $(call local-intermediates-dir,,$(GYP_VAR_PREFIX))
 gyp_shared_intermediate_dir := $(call intermediates-dir-for,GYP,shared,,,$(GYP_VAR_PREFIX))
@@ -46,6 +45,7 @@
 	third_party/angle/src/compiler/translator/InitializeVariables.cpp \
 	third_party/angle/src/compiler/translator/IntermTraverse.cpp \
 	third_party/angle/src/compiler/translator/Intermediate.cpp \
+	third_party/angle/src/compiler/translator/IntermNode.cpp \
 	third_party/angle/src/compiler/translator/LoopInfo.cpp \
 	third_party/angle/src/compiler/translator/OutputESSL.cpp \
 	third_party/angle/src/compiler/translator/OutputGLSL.cpp \
@@ -92,7 +92,6 @@
 # Flags passed to both C and C++ files.
 MY_CFLAGS_Debug := \
 	--param=ssp-buffer-size=4 \
-	-fno-exceptions \
 	-fno-strict-aliasing \
 	-Wno-unused-parameter \
 	-Wno-missing-field-initializers \
@@ -118,6 +117,7 @@
 	-Wno-sequence-point \
 	-Os \
 	-g \
+	-gdwarf-4 \
 	-fdata-sections \
 	-ffunction-sections \
 	-funwind-tables
@@ -140,11 +140,13 @@
 	'-DENABLE_PRINTING=1' \
 	'-DENABLE_MANAGED_USERS=1' \
 	'-DDATA_REDUCTION_FALLBACK_HOST="http://compress.googlezip.net:80/"' \
-	'-DDATA_REDUCTION_DEV_HOST="http://proxy-dev.googlezip.net:80/"' \
+	'-DDATA_REDUCTION_DEV_HOST="https://proxy-dev.googlezip.net:443/"' \
+	'-DDATA_REDUCTION_DEV_FALLBACK_HOST="http://proxy-dev.googlezip.net:80/"' \
 	'-DSPDY_PROXY_AUTH_ORIGIN="https://proxy.googlezip.net:443/"' \
 	'-DDATA_REDUCTION_PROXY_PROBE_URL="http://check.googlezip.net/connect"' \
 	'-DDATA_REDUCTION_PROXY_WARMUP_URL="http://www.gstatic.com/generate_204"' \
 	'-DVIDEO_HOLE=1' \
+	'-DENABLE_LOAD_COMPLETION_HACKS=1' \
 	'-DANGLE_TRANSLATOR_STATIC' \
 	'-DUSE_OPENSSL=1' \
 	'-DUSE_OPENSSL_CERTS=1' \
@@ -170,6 +172,7 @@
 
 # Flags passed to only C++ (and not C) files.
 LOCAL_CPPFLAGS_Debug := \
+	-fno-exceptions \
 	-fno-rtti \
 	-fno-threadsafe-statics \
 	-fvisibility-inlines-hidden \
@@ -185,7 +188,6 @@
 # Flags passed to both C and C++ files.
 MY_CFLAGS_Release := \
 	--param=ssp-buffer-size=4 \
-	-fno-exceptions \
 	-fno-strict-aliasing \
 	-Wno-unused-parameter \
 	-Wno-missing-field-initializers \
@@ -233,11 +235,13 @@
 	'-DENABLE_PRINTING=1' \
 	'-DENABLE_MANAGED_USERS=1' \
 	'-DDATA_REDUCTION_FALLBACK_HOST="http://compress.googlezip.net:80/"' \
-	'-DDATA_REDUCTION_DEV_HOST="http://proxy-dev.googlezip.net:80/"' \
+	'-DDATA_REDUCTION_DEV_HOST="https://proxy-dev.googlezip.net:443/"' \
+	'-DDATA_REDUCTION_DEV_FALLBACK_HOST="http://proxy-dev.googlezip.net:80/"' \
 	'-DSPDY_PROXY_AUTH_ORIGIN="https://proxy.googlezip.net:443/"' \
 	'-DDATA_REDUCTION_PROXY_PROBE_URL="http://check.googlezip.net/connect"' \
 	'-DDATA_REDUCTION_PROXY_WARMUP_URL="http://www.gstatic.com/generate_204"' \
 	'-DVIDEO_HOLE=1' \
+	'-DENABLE_LOAD_COMPLETION_HACKS=1' \
 	'-DANGLE_TRANSLATOR_STATIC' \
 	'-DUSE_OPENSSL=1' \
 	'-DUSE_OPENSSL_CERTS=1' \
@@ -263,6 +267,7 @@
 
 # Flags passed to only C++ (and not C) files.
 LOCAL_CPPFLAGS_Release := \
+	-fno-exceptions \
 	-fno-rtti \
 	-fno-threadsafe-statics \
 	-fvisibility-inlines-hidden \
@@ -281,42 +286,6 @@
 LOCAL_ASFLAGS := $(LOCAL_CFLAGS)
 ### Rules for final target.
 
-LOCAL_LDFLAGS_Debug := \
-	-Wl,-z,now \
-	-Wl,-z,relro \
-	-Wl,--fatal-warnings \
-	-Wl,-z,noexecstack \
-	-fPIC \
-	-nostdlib \
-	-Wl,--no-undefined \
-	-Wl,--exclude-libs=ALL \
-	-Wl,--warn-shared-textrel \
-	-Wl,-O1 \
-	-Wl,--as-needed
-
-
-LOCAL_LDFLAGS_Release := \
-	-Wl,-z,now \
-	-Wl,-z,relro \
-	-Wl,--fatal-warnings \
-	-Wl,-z,noexecstack \
-	-fPIC \
-	-nostdlib \
-	-Wl,--no-undefined \
-	-Wl,--exclude-libs=ALL \
-	-Wl,-O1 \
-	-Wl,--as-needed \
-	-Wl,--gc-sections \
-	-Wl,--warn-shared-textrel
-
-
-LOCAL_LDFLAGS := $(LOCAL_LDFLAGS_$(GYP_CONFIGURATION))
-
-LOCAL_STATIC_LIBRARIES :=
-
-# Enable grouping to fix circular references
-LOCAL_GROUP_STATIC_LIBRARIES := true
-
 LOCAL_SHARED_LIBRARIES := \
 	libstlport \
 	libdl
diff --git a/src/translator_lib.target.linux-mips.mk b/src/translator_lib.target.linux-mips.mk
index 6d10b0b..a8ba23e 100644
--- a/src/translator_lib.target.linux-mips.mk
+++ b/src/translator_lib.target.linux-mips.mk
@@ -5,7 +5,6 @@
 LOCAL_MODULE_CLASS := STATIC_LIBRARIES
 LOCAL_MODULE := third_party_angle_src_translator_lib_gyp
 LOCAL_MODULE_SUFFIX := .a
-LOCAL_MODULE_TAGS := optional
 LOCAL_MODULE_TARGET_ARCH := $(TARGET_$(GYP_VAR_PREFIX)ARCH)
 gyp_intermediate_dir := $(call local-intermediates-dir,,$(GYP_VAR_PREFIX))
 gyp_shared_intermediate_dir := $(call intermediates-dir-for,GYP,shared,,,$(GYP_VAR_PREFIX))
@@ -46,6 +45,7 @@
 	third_party/angle/src/compiler/translator/InitializeVariables.cpp \
 	third_party/angle/src/compiler/translator/IntermTraverse.cpp \
 	third_party/angle/src/compiler/translator/Intermediate.cpp \
+	third_party/angle/src/compiler/translator/IntermNode.cpp \
 	third_party/angle/src/compiler/translator/LoopInfo.cpp \
 	third_party/angle/src/compiler/translator/OutputESSL.cpp \
 	third_party/angle/src/compiler/translator/OutputGLSL.cpp \
@@ -94,7 +94,6 @@
 	-fstack-protector \
 	--param=ssp-buffer-size=4 \
 	 \
-	-fno-exceptions \
 	-fno-strict-aliasing \
 	-Wno-unused-parameter \
 	-Wno-missing-field-initializers \
@@ -103,8 +102,6 @@
 	-fPIC \
 	-Wno-unused-local-typedefs \
 	-Wno-format \
-	-EL \
-	-mhard-float \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -123,6 +120,7 @@
 	-Wno-sequence-point \
 	-Os \
 	-g \
+	-gdwarf-4 \
 	-fdata-sections \
 	-ffunction-sections \
 	-fomit-frame-pointer \
@@ -146,11 +144,13 @@
 	'-DENABLE_PRINTING=1' \
 	'-DENABLE_MANAGED_USERS=1' \
 	'-DDATA_REDUCTION_FALLBACK_HOST="http://compress.googlezip.net:80/"' \
-	'-DDATA_REDUCTION_DEV_HOST="http://proxy-dev.googlezip.net:80/"' \
+	'-DDATA_REDUCTION_DEV_HOST="https://proxy-dev.googlezip.net:443/"' \
+	'-DDATA_REDUCTION_DEV_FALLBACK_HOST="http://proxy-dev.googlezip.net:80/"' \
 	'-DSPDY_PROXY_AUTH_ORIGIN="https://proxy.googlezip.net:443/"' \
 	'-DDATA_REDUCTION_PROXY_PROBE_URL="http://check.googlezip.net/connect"' \
 	'-DDATA_REDUCTION_PROXY_WARMUP_URL="http://www.gstatic.com/generate_204"' \
 	'-DVIDEO_HOLE=1' \
+	'-DENABLE_LOAD_COMPLETION_HACKS=1' \
 	'-DANGLE_TRANSLATOR_STATIC' \
 	'-DUSE_OPENSSL=1' \
 	'-DUSE_OPENSSL_CERTS=1' \
@@ -176,6 +176,7 @@
 
 # Flags passed to only C++ (and not C) files.
 LOCAL_CPPFLAGS_Debug := \
+	-fno-exceptions \
 	-fno-rtti \
 	-fno-threadsafe-statics \
 	-fvisibility-inlines-hidden \
@@ -194,7 +195,6 @@
 	-fstack-protector \
 	--param=ssp-buffer-size=4 \
 	 \
-	-fno-exceptions \
 	-fno-strict-aliasing \
 	-Wno-unused-parameter \
 	-Wno-missing-field-initializers \
@@ -203,8 +203,6 @@
 	-fPIC \
 	-Wno-unused-local-typedefs \
 	-Wno-format \
-	-EL \
-	-mhard-float \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -246,11 +244,13 @@
 	'-DENABLE_PRINTING=1' \
 	'-DENABLE_MANAGED_USERS=1' \
 	'-DDATA_REDUCTION_FALLBACK_HOST="http://compress.googlezip.net:80/"' \
-	'-DDATA_REDUCTION_DEV_HOST="http://proxy-dev.googlezip.net:80/"' \
+	'-DDATA_REDUCTION_DEV_HOST="https://proxy-dev.googlezip.net:443/"' \
+	'-DDATA_REDUCTION_DEV_FALLBACK_HOST="http://proxy-dev.googlezip.net:80/"' \
 	'-DSPDY_PROXY_AUTH_ORIGIN="https://proxy.googlezip.net:443/"' \
 	'-DDATA_REDUCTION_PROXY_PROBE_URL="http://check.googlezip.net/connect"' \
 	'-DDATA_REDUCTION_PROXY_WARMUP_URL="http://www.gstatic.com/generate_204"' \
 	'-DVIDEO_HOLE=1' \
+	'-DENABLE_LOAD_COMPLETION_HACKS=1' \
 	'-DANGLE_TRANSLATOR_STATIC' \
 	'-DUSE_OPENSSL=1' \
 	'-DUSE_OPENSSL_CERTS=1' \
@@ -276,6 +276,7 @@
 
 # Flags passed to only C++ (and not C) files.
 LOCAL_CPPFLAGS_Release := \
+	-fno-exceptions \
 	-fno-rtti \
 	-fno-threadsafe-statics \
 	-fvisibility-inlines-hidden \
@@ -295,46 +296,6 @@
 LOCAL_ASFLAGS := $(LOCAL_CFLAGS)
 ### Rules for final target.
 
-LOCAL_LDFLAGS_Debug := \
-	-Wl,-z,now \
-	-Wl,-z,relro \
-	-Wl,--fatal-warnings \
-	-Wl,-z,noexecstack \
-	-fPIC \
-	-EL \
-	-Wl,--no-keep-memory \
-	-nostdlib \
-	-Wl,--no-undefined \
-	-Wl,--exclude-libs=ALL \
-	-Wl,--warn-shared-textrel \
-	-Wl,-O1 \
-	-Wl,--as-needed
-
-
-LOCAL_LDFLAGS_Release := \
-	-Wl,-z,now \
-	-Wl,-z,relro \
-	-Wl,--fatal-warnings \
-	-Wl,-z,noexecstack \
-	-fPIC \
-	-EL \
-	-Wl,--no-keep-memory \
-	-nostdlib \
-	-Wl,--no-undefined \
-	-Wl,--exclude-libs=ALL \
-	-Wl,-O1 \
-	-Wl,--as-needed \
-	-Wl,--gc-sections \
-	-Wl,--warn-shared-textrel
-
-
-LOCAL_LDFLAGS := $(LOCAL_LDFLAGS_$(GYP_CONFIGURATION))
-
-LOCAL_STATIC_LIBRARIES :=
-
-# Enable grouping to fix circular references
-LOCAL_GROUP_STATIC_LIBRARIES := true
-
 LOCAL_SHARED_LIBRARIES := \
 	libstlport \
 	libdl
diff --git a/src/translator_lib.target.linux-x86.mk b/src/translator_lib.target.linux-x86.mk
index 3706879..937c6c3 100644
--- a/src/translator_lib.target.linux-x86.mk
+++ b/src/translator_lib.target.linux-x86.mk
@@ -5,7 +5,6 @@
 LOCAL_MODULE_CLASS := STATIC_LIBRARIES
 LOCAL_MODULE := third_party_angle_src_translator_lib_gyp
 LOCAL_MODULE_SUFFIX := .a
-LOCAL_MODULE_TAGS := optional
 LOCAL_MODULE_TARGET_ARCH := $(TARGET_$(GYP_VAR_PREFIX)ARCH)
 gyp_intermediate_dir := $(call local-intermediates-dir,,$(GYP_VAR_PREFIX))
 gyp_shared_intermediate_dir := $(call intermediates-dir-for,GYP,shared,,,$(GYP_VAR_PREFIX))
@@ -46,6 +45,7 @@
 	third_party/angle/src/compiler/translator/InitializeVariables.cpp \
 	third_party/angle/src/compiler/translator/IntermTraverse.cpp \
 	third_party/angle/src/compiler/translator/Intermediate.cpp \
+	third_party/angle/src/compiler/translator/IntermNode.cpp \
 	third_party/angle/src/compiler/translator/LoopInfo.cpp \
 	third_party/angle/src/compiler/translator/OutputESSL.cpp \
 	third_party/angle/src/compiler/translator/OutputGLSL.cpp \
@@ -92,7 +92,6 @@
 # Flags passed to both C and C++ files.
 MY_CFLAGS_Debug := \
 	--param=ssp-buffer-size=4 \
-	-fno-exceptions \
 	-fno-strict-aliasing \
 	-Wno-unused-parameter \
 	-Wno-missing-field-initializers \
@@ -123,6 +122,7 @@
 	-Wno-sequence-point \
 	-Os \
 	-g \
+	-gdwarf-4 \
 	-fdata-sections \
 	-ffunction-sections \
 	-fomit-frame-pointer \
@@ -146,11 +146,13 @@
 	'-DENABLE_PRINTING=1' \
 	'-DENABLE_MANAGED_USERS=1' \
 	'-DDATA_REDUCTION_FALLBACK_HOST="http://compress.googlezip.net:80/"' \
-	'-DDATA_REDUCTION_DEV_HOST="http://proxy-dev.googlezip.net:80/"' \
+	'-DDATA_REDUCTION_DEV_HOST="https://proxy-dev.googlezip.net:443/"' \
+	'-DDATA_REDUCTION_DEV_FALLBACK_HOST="http://proxy-dev.googlezip.net:80/"' \
 	'-DSPDY_PROXY_AUTH_ORIGIN="https://proxy.googlezip.net:443/"' \
 	'-DDATA_REDUCTION_PROXY_PROBE_URL="http://check.googlezip.net/connect"' \
 	'-DDATA_REDUCTION_PROXY_WARMUP_URL="http://www.gstatic.com/generate_204"' \
 	'-DVIDEO_HOLE=1' \
+	'-DENABLE_LOAD_COMPLETION_HACKS=1' \
 	'-DANGLE_TRANSLATOR_STATIC' \
 	'-DUSE_OPENSSL=1' \
 	'-DUSE_OPENSSL_CERTS=1' \
@@ -176,6 +178,7 @@
 
 # Flags passed to only C++ (and not C) files.
 LOCAL_CPPFLAGS_Debug := \
+	-fno-exceptions \
 	-fno-rtti \
 	-fno-threadsafe-statics \
 	-fvisibility-inlines-hidden \
@@ -191,7 +194,6 @@
 # Flags passed to both C and C++ files.
 MY_CFLAGS_Release := \
 	--param=ssp-buffer-size=4 \
-	-fno-exceptions \
 	-fno-strict-aliasing \
 	-Wno-unused-parameter \
 	-Wno-missing-field-initializers \
@@ -245,11 +247,13 @@
 	'-DENABLE_PRINTING=1' \
 	'-DENABLE_MANAGED_USERS=1' \
 	'-DDATA_REDUCTION_FALLBACK_HOST="http://compress.googlezip.net:80/"' \
-	'-DDATA_REDUCTION_DEV_HOST="http://proxy-dev.googlezip.net:80/"' \
+	'-DDATA_REDUCTION_DEV_HOST="https://proxy-dev.googlezip.net:443/"' \
+	'-DDATA_REDUCTION_DEV_FALLBACK_HOST="http://proxy-dev.googlezip.net:80/"' \
 	'-DSPDY_PROXY_AUTH_ORIGIN="https://proxy.googlezip.net:443/"' \
 	'-DDATA_REDUCTION_PROXY_PROBE_URL="http://check.googlezip.net/connect"' \
 	'-DDATA_REDUCTION_PROXY_WARMUP_URL="http://www.gstatic.com/generate_204"' \
 	'-DVIDEO_HOLE=1' \
+	'-DENABLE_LOAD_COMPLETION_HACKS=1' \
 	'-DANGLE_TRANSLATOR_STATIC' \
 	'-DUSE_OPENSSL=1' \
 	'-DUSE_OPENSSL_CERTS=1' \
@@ -275,6 +279,7 @@
 
 # Flags passed to only C++ (and not C) files.
 LOCAL_CPPFLAGS_Release := \
+	-fno-exceptions \
 	-fno-rtti \
 	-fno-threadsafe-statics \
 	-fvisibility-inlines-hidden \
@@ -293,46 +298,6 @@
 LOCAL_ASFLAGS := $(LOCAL_CFLAGS)
 ### Rules for final target.
 
-LOCAL_LDFLAGS_Debug := \
-	-Wl,-z,now \
-	-Wl,-z,relro \
-	-Wl,--fatal-warnings \
-	-Wl,-z,noexecstack \
-	-fPIC \
-	-m32 \
-	-fuse-ld=gold \
-	-nostdlib \
-	-Wl,--no-undefined \
-	-Wl,--exclude-libs=ALL \
-	-Wl,--warn-shared-textrel \
-	-Wl,-O1 \
-	-Wl,--as-needed
-
-
-LOCAL_LDFLAGS_Release := \
-	-Wl,-z,now \
-	-Wl,-z,relro \
-	-Wl,--fatal-warnings \
-	-Wl,-z,noexecstack \
-	-fPIC \
-	-m32 \
-	-fuse-ld=gold \
-	-nostdlib \
-	-Wl,--no-undefined \
-	-Wl,--exclude-libs=ALL \
-	-Wl,-O1 \
-	-Wl,--as-needed \
-	-Wl,--gc-sections \
-	-Wl,--warn-shared-textrel
-
-
-LOCAL_LDFLAGS := $(LOCAL_LDFLAGS_$(GYP_CONFIGURATION))
-
-LOCAL_STATIC_LIBRARIES :=
-
-# Enable grouping to fix circular references
-LOCAL_GROUP_STATIC_LIBRARIES := true
-
 LOCAL_SHARED_LIBRARIES := \
 	libstlport \
 	libdl
diff --git a/src/translator_lib.target.linux-x86_64.mk b/src/translator_lib.target.linux-x86_64.mk
index 413f480..5d1d2b0 100644
--- a/src/translator_lib.target.linux-x86_64.mk
+++ b/src/translator_lib.target.linux-x86_64.mk
@@ -5,7 +5,6 @@
 LOCAL_MODULE_CLASS := STATIC_LIBRARIES
 LOCAL_MODULE := third_party_angle_src_translator_lib_gyp
 LOCAL_MODULE_SUFFIX := .a
-LOCAL_MODULE_TAGS := optional
 LOCAL_MODULE_TARGET_ARCH := $(TARGET_$(GYP_VAR_PREFIX)ARCH)
 gyp_intermediate_dir := $(call local-intermediates-dir,,$(GYP_VAR_PREFIX))
 gyp_shared_intermediate_dir := $(call intermediates-dir-for,GYP,shared,,,$(GYP_VAR_PREFIX))
@@ -46,6 +45,7 @@
 	third_party/angle/src/compiler/translator/InitializeVariables.cpp \
 	third_party/angle/src/compiler/translator/IntermTraverse.cpp \
 	third_party/angle/src/compiler/translator/Intermediate.cpp \
+	third_party/angle/src/compiler/translator/IntermNode.cpp \
 	third_party/angle/src/compiler/translator/LoopInfo.cpp \
 	third_party/angle/src/compiler/translator/OutputESSL.cpp \
 	third_party/angle/src/compiler/translator/OutputGLSL.cpp \
@@ -93,7 +93,6 @@
 MY_CFLAGS_Debug := \
 	-fstack-protector \
 	--param=ssp-buffer-size=4 \
-	-fno-exceptions \
 	-fno-strict-aliasing \
 	-Wno-unused-parameter \
 	-Wno-missing-field-initializers \
@@ -122,6 +121,7 @@
 	-Wno-sequence-point \
 	-Os \
 	-g \
+	-gdwarf-4 \
 	-fdata-sections \
 	-ffunction-sections \
 	-fomit-frame-pointer \
@@ -145,11 +145,13 @@
 	'-DENABLE_PRINTING=1' \
 	'-DENABLE_MANAGED_USERS=1' \
 	'-DDATA_REDUCTION_FALLBACK_HOST="http://compress.googlezip.net:80/"' \
-	'-DDATA_REDUCTION_DEV_HOST="http://proxy-dev.googlezip.net:80/"' \
+	'-DDATA_REDUCTION_DEV_HOST="https://proxy-dev.googlezip.net:443/"' \
+	'-DDATA_REDUCTION_DEV_FALLBACK_HOST="http://proxy-dev.googlezip.net:80/"' \
 	'-DSPDY_PROXY_AUTH_ORIGIN="https://proxy.googlezip.net:443/"' \
 	'-DDATA_REDUCTION_PROXY_PROBE_URL="http://check.googlezip.net/connect"' \
 	'-DDATA_REDUCTION_PROXY_WARMUP_URL="http://www.gstatic.com/generate_204"' \
 	'-DVIDEO_HOLE=1' \
+	'-DENABLE_LOAD_COMPLETION_HACKS=1' \
 	'-DANGLE_TRANSLATOR_STATIC' \
 	'-DUSE_OPENSSL=1' \
 	'-DUSE_OPENSSL_CERTS=1' \
@@ -175,6 +177,7 @@
 
 # Flags passed to only C++ (and not C) files.
 LOCAL_CPPFLAGS_Debug := \
+	-fno-exceptions \
 	-fno-rtti \
 	-fno-threadsafe-statics \
 	-fvisibility-inlines-hidden \
@@ -191,7 +194,6 @@
 MY_CFLAGS_Release := \
 	-fstack-protector \
 	--param=ssp-buffer-size=4 \
-	-fno-exceptions \
 	-fno-strict-aliasing \
 	-Wno-unused-parameter \
 	-Wno-missing-field-initializers \
@@ -243,11 +245,13 @@
 	'-DENABLE_PRINTING=1' \
 	'-DENABLE_MANAGED_USERS=1' \
 	'-DDATA_REDUCTION_FALLBACK_HOST="http://compress.googlezip.net:80/"' \
-	'-DDATA_REDUCTION_DEV_HOST="http://proxy-dev.googlezip.net:80/"' \
+	'-DDATA_REDUCTION_DEV_HOST="https://proxy-dev.googlezip.net:443/"' \
+	'-DDATA_REDUCTION_DEV_FALLBACK_HOST="http://proxy-dev.googlezip.net:80/"' \
 	'-DSPDY_PROXY_AUTH_ORIGIN="https://proxy.googlezip.net:443/"' \
 	'-DDATA_REDUCTION_PROXY_PROBE_URL="http://check.googlezip.net/connect"' \
 	'-DDATA_REDUCTION_PROXY_WARMUP_URL="http://www.gstatic.com/generate_204"' \
 	'-DVIDEO_HOLE=1' \
+	'-DENABLE_LOAD_COMPLETION_HACKS=1' \
 	'-DANGLE_TRANSLATOR_STATIC' \
 	'-DUSE_OPENSSL=1' \
 	'-DUSE_OPENSSL_CERTS=1' \
@@ -273,6 +277,7 @@
 
 # Flags passed to only C++ (and not C) files.
 LOCAL_CPPFLAGS_Release := \
+	-fno-exceptions \
 	-fno-rtti \
 	-fno-threadsafe-statics \
 	-fvisibility-inlines-hidden \
@@ -291,46 +296,6 @@
 LOCAL_ASFLAGS := $(LOCAL_CFLAGS)
 ### Rules for final target.
 
-LOCAL_LDFLAGS_Debug := \
-	-Wl,-z,now \
-	-Wl,-z,relro \
-	-Wl,--fatal-warnings \
-	-Wl,-z,noexecstack \
-	-fPIC \
-	-m64 \
-	-fuse-ld=gold \
-	-nostdlib \
-	-Wl,--no-undefined \
-	-Wl,--exclude-libs=ALL \
-	-Wl,--warn-shared-textrel \
-	-Wl,-O1 \
-	-Wl,--as-needed
-
-
-LOCAL_LDFLAGS_Release := \
-	-Wl,-z,now \
-	-Wl,-z,relro \
-	-Wl,--fatal-warnings \
-	-Wl,-z,noexecstack \
-	-fPIC \
-	-m64 \
-	-fuse-ld=gold \
-	-nostdlib \
-	-Wl,--no-undefined \
-	-Wl,--exclude-libs=ALL \
-	-Wl,-O1 \
-	-Wl,--as-needed \
-	-Wl,--gc-sections \
-	-Wl,--warn-shared-textrel
-
-
-LOCAL_LDFLAGS := $(LOCAL_LDFLAGS_$(GYP_CONFIGURATION))
-
-LOCAL_STATIC_LIBRARIES :=
-
-# Enable grouping to fix circular references
-LOCAL_GROUP_STATIC_LIBRARIES := true
-
 LOCAL_SHARED_LIBRARIES := \
 	libstlport \
 	libdl
diff --git a/tests/angle_implementation_unit_tests/TransformFeedback_unittest.cpp b/tests/angle_implementation_unit_tests/TransformFeedback_unittest.cpp
new file mode 100644
index 0000000..3b989c5
--- /dev/null
+++ b/tests/angle_implementation_unit_tests/TransformFeedback_unittest.cpp
@@ -0,0 +1,94 @@
+//
+// 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 "gmock/gmock.h"
+#include "gtest/gtest.h"
+#include "libGLESv2/TransformFeedback.h"
+#include "libGLESv2/renderer/TransformFeedbackImpl.h"
+
+namespace {
+
+class MockTransformFeedbackImpl : public rx::TransformFeedbackImpl
+{
+  public:
+    virtual ~MockTransformFeedbackImpl() { destroy(); }
+
+    MOCK_METHOD1(begin, void(GLenum primitiveMode));
+    MOCK_METHOD0(end, void());
+    MOCK_METHOD0(pause, void());
+    MOCK_METHOD0(resume, void());
+
+    MOCK_METHOD0(destroy, void());
+};
+
+class TransformFeedbackTest : public testing::Test
+{
+  protected:
+    virtual void SetUp()
+    {
+        mImpl = new MockTransformFeedbackImpl;
+        EXPECT_CALL(*mImpl, destroy());
+        mFeedback = new gl::TransformFeedback(mImpl, 1);
+        mFeedback->addRef();
+    }
+
+    virtual void TearDown()
+    {
+        mFeedback->release();
+    }
+
+    MockTransformFeedbackImpl* mImpl;
+    gl::TransformFeedback* mFeedback;
+};
+
+TEST_F(TransformFeedbackTest, DestructionDeletesImpl)
+{
+    MockTransformFeedbackImpl* impl = new MockTransformFeedbackImpl;
+    EXPECT_CALL(*impl, destroy()).Times(1).RetiresOnSaturation();
+
+    gl::TransformFeedback* feedback = new gl::TransformFeedback(impl, 1);
+    feedback->addRef();
+    feedback->release();
+
+    // Only needed because the mock is leaked if bugs are present,
+    // which logs an error, but does not cause the test to fail.
+    // Ordinarily mocks are verified when destroyed.
+    testing::Mock::VerifyAndClear(impl);
+}
+
+TEST_F(TransformFeedbackTest, SideEffectsOfStartAndStop)
+{
+    testing::InSequence seq;
+
+    EXPECT_EQ(GL_FALSE, mFeedback->isStarted());
+    EXPECT_CALL(*mImpl, begin(GL_TRIANGLES));
+    mFeedback->start(GL_TRIANGLES);
+    EXPECT_EQ(GL_TRUE, mFeedback->isStarted());
+    EXPECT_EQ(GL_TRIANGLES, mFeedback->getDrawMode());
+    EXPECT_CALL(*mImpl, end());
+    mFeedback->stop();
+    EXPECT_EQ(GL_FALSE, mFeedback->isStarted());
+}
+
+TEST_F(TransformFeedbackTest, SideEffectsOfPauseAndResume)
+{
+    testing::InSequence seq;
+
+    EXPECT_FALSE(mFeedback->isStarted());
+    EXPECT_CALL(*mImpl, begin(GL_TRIANGLES));
+    mFeedback->start(GL_TRIANGLES);
+    EXPECT_EQ(GL_FALSE, mFeedback->isPaused());
+    EXPECT_CALL(*mImpl, pause());
+    mFeedback->pause();
+    EXPECT_EQ(GL_TRUE, mFeedback->isPaused());
+    EXPECT_CALL(*mImpl, resume());
+    mFeedback->resume();
+    EXPECT_EQ(GL_FALSE, mFeedback->isPaused());
+    EXPECT_CALL(*mImpl, end());
+    mFeedback->stop();
+}
+
+} // namespace
diff --git a/tests/angle_implementation_unit_tests/angle_implementation_unit_tests.gypi b/tests/angle_implementation_unit_tests/angle_implementation_unit_tests.gypi
new file mode 100644
index 0000000..f1da32c
--- /dev/null
+++ b/tests/angle_implementation_unit_tests/angle_implementation_unit_tests.gypi
@@ -0,0 +1,13 @@
+# 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.
+
+{
+    'sources':
+    [
+        '<!@(python <(angle_path)/enumerate_files.py \
+          -dirs <(angle_path)/tests/angle_implementation_unit_tests \
+          -types *.cpp *.h \
+          -excludes <(angle_path)/tests/angle_implementation_unit_tests/angle_implementation_unit_tests_main.cpp)'
+    ],
+}
diff --git a/tests/angle_implementation_unit_tests/angle_implementation_unit_tests_main.cpp b/tests/angle_implementation_unit_tests/angle_implementation_unit_tests_main.cpp
new file mode 100644
index 0000000..ce2bf62
--- /dev/null
+++ b/tests/angle_implementation_unit_tests/angle_implementation_unit_tests_main.cpp
@@ -0,0 +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.
+//
+
+#include "gmock/gmock.h"
+#include "gtest/gtest.h"
+
+int main(int argc, char** argv)
+{
+    testing::InitGoogleMock(&argc, argv);
+    int rt = RUN_ALL_TESTS();
+    return rt;
+}
diff --git a/tests/angle_tests/ANGLETest.cpp b/tests/angle_tests/ANGLETest.cpp
index 4b009de..1bed5e7 100644
--- a/tests/angle_tests/ANGLETest.cpp
+++ b/tests/angle_tests/ANGLETest.cpp
@@ -1,27 +1,18 @@
 #include "ANGLETest.h"
+#include "EGLWindow.h"
+#include "OSWindow.h"
+
+OSWindow *ANGLETest::mOSWindow = NULL;
 
 ANGLETest::ANGLETest()
-    : mTestPlatform(EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE),
-      mClientVersion(2),
-      mWidth(1280),
-      mHeight(720),
-      mRedBits(-1),
-      mGreenBits(-1),
-      mBlueBits(-1),
-      mAlphaBits(-1),
-      mDepthBits(-1),
-      mStencilBits(-1),
-      mMultisample(false)
+    : mEGLWindow(NULL)
 {
+    mEGLWindow = new EGLWindow(1280, 720, 2, EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE);
 }
 
-EGLDisplay ANGLETest::mDisplay = 0;
-EGLNativeWindowType ANGLETest::mNativeWindow = 0;
-EGLNativeDisplayType ANGLETest::mNativeDisplay = 0;
-
 void ANGLETest::SetUp()
 {
-    ReizeWindow(mWidth, mHeight);
+    ResizeWindow(mEGLWindow->getWidth(), mEGLWindow->getHeight());
     if (!createEGLContext())
     {
         FAIL() << "egl context creation failed.";
@@ -31,15 +22,27 @@
 void ANGLETest::TearDown()
 {
     swapBuffers();
+    mOSWindow->messageLoop();
+
     if (!destroyEGLContext())
     {
         FAIL() << "egl context destruction failed.";
     }
+
+    // Check for quit message
+    Event myEvent;
+    while (mOSWindow->popEvent(&myEvent))
+    {
+        if (myEvent.Type == Event::EVENT_CLOSED)
+        {
+            exit(0);
+        }
+    }
 }
 
 void ANGLETest::swapBuffers()
 {
-    eglSwapBuffers(mDisplay, mSurface);
+    mEGLWindow->swap();
 }
 
 void ANGLETest::drawQuad(GLuint program, const std::string& positionAttribName, GLfloat quadDepth)
@@ -98,49 +101,6 @@
     return shader;
 }
 
-GLuint ANGLETest::compileProgram(const std::string &vsSource, const std::string &fsSource)
-{
-    GLuint program = glCreateProgram();
-
-    GLuint vs = compileShader(GL_VERTEX_SHADER, vsSource);
-    GLuint fs = compileShader(GL_FRAGMENT_SHADER, fsSource);
-
-    if (vs == 0 || fs == 0)
-    {
-        glDeleteShader(fs);
-        glDeleteShader(vs);
-        glDeleteProgram(program);
-        return 0;
-    }
-
-    glAttachShader(program, vs);
-    glDeleteShader(vs);
-
-    glAttachShader(program, fs);
-    glDeleteShader(fs);
-
-    glLinkProgram(program);
-
-    GLint linkStatus;
-    glGetProgramiv(program, GL_LINK_STATUS, &linkStatus);
-
-    if (linkStatus == 0)
-    {
-        GLint infoLogLength;
-        glGetProgramiv(program, GL_INFO_LOG_LENGTH, &infoLogLength);
-
-        std::vector<GLchar> infoLog(infoLogLength);
-        glGetProgramInfoLog(program, infoLog.size(), NULL, infoLog.data());
-
-        std::cerr << "program link failed: " << infoLog.data();
-
-        glDeleteProgram(program);
-        return 0;
-    }
-
-    return program;
-}
-
 bool ANGLETest::extensionEnabled(const std::string &extName)
 {
     const char* extString = reinterpret_cast<const char*>(glGetString(GL_EXTENSIONS));
@@ -149,227 +109,113 @@
 
 void ANGLETest::setClientVersion(int clientVersion)
 {
-    mClientVersion = clientVersion;
+    mEGLWindow->setClientVersion(clientVersion);
 }
 
 void ANGLETest::setWindowWidth(int width)
 {
-    mWidth = width;
+    mEGLWindow->setWidth(width);
 }
 
 void ANGLETest::setWindowHeight(int height)
 {
-    mHeight = height;
+    mEGLWindow->setHeight(height);
 }
 
 void ANGLETest::setConfigRedBits(int bits)
 {
-    mRedBits = bits;
+    mEGLWindow->setConfigRedBits(bits);
 }
 
 void ANGLETest::setConfigGreenBits(int bits)
 {
-    mGreenBits = bits;
+    mEGLWindow->setConfigGreenBits(bits);
 }
 
 void ANGLETest::setConfigBlueBits(int bits)
 {
-    mBlueBits = bits;
+    mEGLWindow->setConfigBlueBits(bits);
 }
 
 void ANGLETest::setConfigAlphaBits(int bits)
 {
-    mAlphaBits = bits;
+    mEGLWindow->setConfigAlphaBits(bits);
 }
 
 void ANGLETest::setConfigDepthBits(int bits)
 {
-    mDepthBits = bits;
+    mEGLWindow->setConfigDepthBits(bits);
 }
 
 void ANGLETest::setConfigStencilBits(int bits)
 {
-    mStencilBits = bits;
+    mEGLWindow->setConfigStencilBits(bits);
 }
 
 void ANGLETest::setMultisampleEnabled(bool enabled)
 {
-    mMultisample = enabled;
+    mEGLWindow->setMultisample(enabled);
 }
 
 int ANGLETest::getClientVersion() const
 {
-    return mClientVersion;
+    return mEGLWindow->getClientVersion();
 }
 
 int ANGLETest::getWindowWidth() const
 {
-    return mWidth;
+    return mEGLWindow->getWidth();
 }
 
 int ANGLETest::getWindowHeight() const
 {
-    return mHeight;
-}
-
-int ANGLETest::getConfigRedBits() const
-{
-    return mRedBits;
-}
-
-int ANGLETest::getConfigGreenBits() const
-{
-    return mGreenBits;
-}
-
-int ANGLETest::getConfigBlueBits() const
-{
-    return mBlueBits;
-}
-
-int ANGLETest::getConfigAlphaBits() const
-{
-    return mAlphaBits;
-}
-
-int ANGLETest::getConfigDepthBits() const
-{
-    return mDepthBits;
-}
-
-int ANGLETest::getConfigStencilBits() const
-{
-    return mStencilBits;
+    return mEGLWindow->getHeight();
 }
 
 bool ANGLETest::isMultisampleEnabled() const
 {
-    return mMultisample;
+    return mEGLWindow->isMultisample();
 }
 
 bool ANGLETest::createEGLContext()
 {
-    PFNEGLGETPLATFORMDISPLAYEXTPROC eglGetPlatformDisplayEXT = reinterpret_cast<PFNEGLGETPLATFORMDISPLAYEXTPROC>(eglGetProcAddress("eglGetPlatformDisplayEXT"));
-    if (!eglGetPlatformDisplayEXT)
+    return mEGLWindow->initializeGL(mOSWindow);
+}
+
+bool ANGLETest::destroyEGLContext()
+{
+    mEGLWindow->destroyGL();
+    return true;
+}
+
+bool ANGLETest::InitTestWindow()
+{
+    mOSWindow = CreateOSWindow();
+    if (!mOSWindow->initialize("ANGLE_TEST", 128, 128))
     {
         return false;
     }
 
-    const EGLint displayAttributes[] =
-    {
-        EGL_PLATFORM_ANGLE_TYPE_ANGLE, mTestPlatform,
-        EGL_NONE,
-    };
+    mOSWindow->setVisible(true);
 
-    mDisplay = eglGetPlatformDisplayEXT(EGL_PLATFORM_ANGLE_ANGLE, mNativeDisplay, displayAttributes);
-    if (mDisplay == EGL_NO_DISPLAY)
-    {
-        destroyEGLContext();
-        return false;
-    }
+    return true;
+}
 
-    EGLint majorVersion, minorVersion;
-    if (!eglInitialize(mDisplay, &majorVersion, &minorVersion))
+bool ANGLETest::DestroyTestWindow()
+{
+    if (mOSWindow)
     {
-        destroyEGLContext();
-        return false;
-    }
-
-    eglBindAPI(EGL_OPENGL_ES_API);
-    if (eglGetError() != EGL_SUCCESS)
-    {
-        destroyEGLContext();
-        return false;
-    }
-
-    const EGLint configAttributes[] =
-    {
-        EGL_RED_SIZE,       (mRedBits >= 0)     ? mRedBits     : EGL_DONT_CARE,
-        EGL_GREEN_SIZE,     (mGreenBits >= 0)   ? mGreenBits   : EGL_DONT_CARE,
-        EGL_BLUE_SIZE,      (mBlueBits >= 0)    ? mBlueBits    : EGL_DONT_CARE,
-        EGL_ALPHA_SIZE,     (mAlphaBits >= 0)   ? mAlphaBits   : EGL_DONT_CARE,
-        EGL_DEPTH_SIZE,     (mDepthBits >= 0)   ? mDepthBits   : EGL_DONT_CARE,
-        EGL_STENCIL_SIZE,   (mStencilBits >= 0) ? mStencilBits : EGL_DONT_CARE,
-        EGL_SAMPLE_BUFFERS, mMultisample ? 1 : 0,
-        EGL_NONE
-    };
-
-    EGLint configCount;
-    if (!eglChooseConfig(mDisplay, configAttributes, &mConfig, 1, &configCount) || (configCount != 1))
-    {
-        destroyEGLContext();
-        return false;
-    }
-
-    eglGetConfigAttrib(mDisplay, mConfig, EGL_RED_SIZE, &mRedBits);
-    eglGetConfigAttrib(mDisplay, mConfig, EGL_GREEN_SIZE, &mGreenBits);
-    eglGetConfigAttrib(mDisplay, mConfig, EGL_BLUE_SIZE, &mBlueBits);
-    eglGetConfigAttrib(mDisplay, mConfig, EGL_ALPHA_SIZE, &mBlueBits);
-    eglGetConfigAttrib(mDisplay, mConfig, EGL_DEPTH_SIZE, &mDepthBits);
-    eglGetConfigAttrib(mDisplay, mConfig, EGL_STENCIL_SIZE, &mStencilBits);
-
-    EGLint samples;
-    eglGetConfigAttrib(mDisplay, mConfig, EGL_SAMPLE_BUFFERS, &samples);
-    mMultisample = (samples != 0);
-
-    mSurface = eglCreateWindowSurface(mDisplay, mConfig, mNativeWindow, NULL);
-    if(mSurface == EGL_NO_SURFACE)
-    {
-        eglGetError(); // Clear error
-        mSurface = eglCreateWindowSurface(mDisplay, mConfig, NULL, NULL);
-    }
-
-    if (eglGetError() != EGL_SUCCESS)
-    {
-        destroyEGLContext();
-        return false;
-    }
-
-    EGLint contextAttibutes[] =
-    {
-        EGL_CONTEXT_CLIENT_VERSION, mClientVersion,
-        EGL_NONE
-    };
-    mContext = eglCreateContext(mDisplay, mConfig, NULL, contextAttibutes);
-    if (eglGetError() != EGL_SUCCESS)
-    {
-        destroyEGLContext();
-        return false;
-    }
-
-    eglMakeCurrent(mDisplay, mSurface, mSurface, mContext);
-    if (eglGetError() != EGL_SUCCESS)
-    {
-        destroyEGLContext();
-        return false;
+        mOSWindow->destroy();
+        delete mOSWindow;
+        mOSWindow = NULL;
     }
 
     return true;
 }
 
-bool ANGLETest::destroyEGLContext()
+bool ANGLETest::ResizeWindow(int width, int height)
 {
-    if (mDisplay != EGL_NO_DISPLAY)
-    {
-        eglMakeCurrent(mDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
-
-        if (mSurface != EGL_NO_SURFACE)
-        {
-            eglDestroySurface(mDisplay, mSurface);
-            mSurface = EGL_NO_SURFACE;
-        }
-
-        if (mContext != EGL_NO_CONTEXT)
-        {
-            eglDestroyContext(mDisplay, mContext);
-            mContext = EGL_NO_CONTEXT;
-        }
-
-        eglTerminate(mDisplay);
-        mDisplay = EGL_NO_DISPLAY;
-    }
-
-    return true;
+    return mOSWindow->resize(width, height);
 }
 
 void ANGLETestEnvironment::SetUp()
diff --git a/tests/angle_tests/ANGLETest.h b/tests/angle_tests/ANGLETest.h
index 37ea52b..c3de55c 100644
--- a/tests/angle_tests/ANGLETest.h
+++ b/tests/angle_tests/ANGLETest.h
@@ -12,10 +12,11 @@
 #define GL_GLEXT_PROTOTYPES
 
 #include "angle_gl.h"
-#include <EGL/egl.h>
-#include <EGL/eglext.h>
 #include <algorithm>
 
+#include "shared_utils.h"
+#include "shader_utils.h"
+
 #define EXPECT_GL_ERROR(err) EXPECT_EQ((err), glGetError())
 #define EXPECT_GL_NO_ERROR() EXPECT_GL_ERROR(GL_NO_ERROR)
 
@@ -33,7 +34,8 @@
     EXPECT_EQ((a), pixel[3]); \
 }
 
-#define SHADER_SOURCE(...) #__VA_ARGS__
+class EGLWindow;
+class OSWindow;
 
 class ANGLETest : public testing::Test
 {
@@ -43,7 +45,7 @@
   public:
     static bool InitTestWindow();
     static bool DestroyTestWindow();
-    static bool ReizeWindow(int width, int height);
+    static bool ResizeWindow(int width, int height);
 
   protected:
     virtual void SetUp();
@@ -53,7 +55,6 @@
 
     static void drawQuad(GLuint program, const std::string& positionAttribName, GLfloat quadDepth);
     static GLuint compileShader(GLenum type, const std::string &source);
-    static GLuint compileProgram(const std::string &vsSource, const std::string &fsSource);
     static bool extensionEnabled(const std::string &extName);
 
     void setClientVersion(int clientVersion);
@@ -70,38 +71,15 @@
     int getClientVersion() const;
     int getWindowWidth() const;
     int getWindowHeight() const;
-    int getConfigRedBits() const;
-    int getConfigGreenBits() const;
-    int getConfigBlueBits() const;
-    int getConfigAlphaBits() const;
-    int getConfigDepthBits() const;
-    int getConfigStencilBits() const;
     bool isMultisampleEnabled() const;
 
   private:
     bool createEGLContext();
     bool destroyEGLContext();
 
-    EGLint mTestPlatform;
+    EGLWindow *mEGLWindow;
 
-    int mClientVersion;
-    int mWidth;
-    int mHeight;
-    int mRedBits;
-    int mGreenBits;
-    int mBlueBits;
-    int mAlphaBits;
-    int mDepthBits;
-    int mStencilBits;
-    bool mMultisample;
-
-    EGLConfig mConfig;
-    EGLSurface mSurface;
-    EGLContext mContext;
-
-    static EGLDisplay mDisplay;
-    static EGLNativeWindowType mNativeWindow;
-    static EGLNativeDisplayType mNativeDisplay;
+    static OSWindow *mOSWindow;
 };
 
 class ANGLETestEnvironment : public testing::Environment
diff --git a/tests/angle_tests/BlendMinMaxTest.cpp b/tests/angle_tests/BlendMinMaxTest.cpp
index 9f737f9..c097e29 100644
--- a/tests/angle_tests/BlendMinMaxTest.cpp
+++ b/tests/angle_tests/BlendMinMaxTest.cpp
@@ -88,7 +88,7 @@
             }
         );
 
-        mProgram = compileProgram(testVertexShaderSource, testFragmentShaderSource);
+        mProgram = CompileProgram(testVertexShaderSource, testFragmentShaderSource);
         if (mProgram == 0)
         {
             FAIL() << "shader compilation failed.";
diff --git a/tests/angle_tests/BlitFramebufferANGLETest.cpp b/tests/angle_tests/BlitFramebufferANGLETest.cpp
index b8e9cc5..7b1339f 100644
--- a/tests/angle_tests/BlitFramebufferANGLETest.cpp
+++ b/tests/angle_tests/BlitFramebufferANGLETest.cpp
@@ -92,8 +92,8 @@
             }
         );
 
-        mCheckerProgram = compileProgram(passthroughVS, checkeredFS);
-        mBlueProgram = compileProgram(passthroughVS, blueFS);
+        mCheckerProgram = CompileProgram(passthroughVS, checkeredFS);
+        mBlueProgram = CompileProgram(passthroughVS, blueFS);
         if (mCheckerProgram == 0 || mBlueProgram == 0)
         {
             FAIL() << "shader compilation failed.";
diff --git a/tests/angle_tests/BufferDataTest.cpp b/tests/angle_tests/BufferDataTest.cpp
index 6401b94..c566a85 100644
--- a/tests/angle_tests/BufferDataTest.cpp
+++ b/tests/angle_tests/BufferDataTest.cpp
@@ -48,7 +48,7 @@
         glGenBuffers(1, &mBuffer);
         ASSERT_NE(mBuffer, 0U);
 
-        mProgram = compileProgram(vsSource, fsSource);
+        mProgram = CompileProgram(vsSource, fsSource);
         ASSERT_NE(mProgram, 0U);
 
         mAttribLocation = glGetAttribLocation(mProgram, "in_attrib");
@@ -114,6 +114,19 @@
     delete [] zeroData;
 }
 
+TEST_F(BufferDataTest, NULLResolvedData)
+{
+    glBindBuffer(GL_ARRAY_BUFFER, mBuffer);
+    glBufferData(GL_ARRAY_BUFFER, 128, NULL, GL_DYNAMIC_DRAW);
+
+    glUseProgram(mProgram);
+    glVertexAttribPointer(mAttribLocation, 1, GL_FLOAT, GL_FALSE, 4, NULL);
+    glEnableVertexAttribArray(mAttribLocation);
+    glBindBuffer(GL_ARRAY_BUFFER, 0);
+
+    drawQuad(mProgram, "position", 0.5f);
+}
+
 TEST_F(BufferDataTest, HugeSetDataShouldNotCrash)
 {
     glBindBuffer(GL_ARRAY_BUFFER, mBuffer);
@@ -128,7 +141,7 @@
 
         if (data == NULL)
         {
-            allocSize <<= 1;
+            allocSize >>= 1;
         }
     }
 
@@ -231,7 +244,7 @@
         glGenBuffers(1, &mElementBuffer);
         ASSERT_NE(mElementBuffer, 0U);
 
-        mProgram = compileProgram(vsSource, fsSource);
+        mProgram = CompileProgram(vsSource, fsSource);
         ASSERT_NE(mProgram, 0U);
 
         mAttribLocation = glGetAttribLocation(mProgram, "in_attrib");
diff --git a/tests/angle_tests/ClearTest.cpp b/tests/angle_tests/ClearTest.cpp
index 50af0bf..a8c0476 100644
--- a/tests/angle_tests/ClearTest.cpp
+++ b/tests/angle_tests/ClearTest.cpp
@@ -40,7 +40,7 @@
             }
         );
 
-        mProgram = compileProgram(vertexShaderSource, fragmentShaderSource);
+        mProgram = CompileProgram(vertexShaderSource, fragmentShaderSource);
         if (mProgram == 0)
         {
             FAIL() << "shader compilation failed.";
@@ -137,4 +137,54 @@
     glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT1, GL_TEXTURE_2D, 0, 0);
     glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, textures[1], 0);
     EXPECT_PIXEL_EQ(0, 0, 0, 127, 255, 255);
+
+    glDeleteTextures(2, textures);
+}
+
+TEST_F(ClearTest, BadFBOSerialBug)
+{
+    // First make a simple framebuffer, and clear it to green
+    glBindFramebuffer(GL_FRAMEBUFFER, mFBO);
+
+    GLuint textures[2];
+    glGenTextures(2, &textures[0]);
+
+    glBindTexture(GL_TEXTURE_2D, textures[0]);
+    glTexStorage2D(GL_TEXTURE_2D, 1, GL_RGBA8, getWindowWidth(), getWindowHeight());
+    glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, textures[0], 0);
+
+    GLenum drawBuffers[] = { GL_COLOR_ATTACHMENT0 };
+    glDrawBuffers(1, drawBuffers);
+
+    float clearValues1[] = { 0.0f, 1.0f, 0.0f, 1.0f };
+    glClearBufferfv(GL_COLOR, 0, clearValues1);
+
+    ASSERT_GL_NO_ERROR();
+    EXPECT_PIXEL_EQ(0, 0, 0, 255, 0, 255);
+
+    // Next make a second framebuffer, and draw it to red
+    // (Triggers bad applied render target serial)
+    GLuint fbo2;
+    glGenFramebuffers(1, &fbo2);
+    ASSERT_GL_NO_ERROR();
+
+    glBindFramebuffer(GL_FRAMEBUFFER, fbo2);
+
+    glBindTexture(GL_TEXTURE_2D, textures[1]);
+    glTexStorage2D(GL_TEXTURE_2D, 1, GL_RGBA8, getWindowWidth(), getWindowHeight());
+    glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, textures[1], 0);
+
+    glDrawBuffers(1, drawBuffers);
+
+    drawQuad(mProgram, "position", 0.5f);
+
+    ASSERT_GL_NO_ERROR();
+    EXPECT_PIXEL_EQ(0, 0, 255, 0, 0, 255);
+
+    // Check that the first framebuffer is still green.
+    glBindFramebuffer(GL_FRAMEBUFFER, mFBO);
+    EXPECT_PIXEL_EQ(0, 0, 0, 255, 0, 255);
+
+    glDeleteTextures(2, textures);
+    glDeleteFramebuffers(1, &fbo2);
 }
diff --git a/tests/angle_tests/CompressedTextureTest.cpp b/tests/angle_tests/CompressedTextureTest.cpp
index b7868bd..7d95907 100644
--- a/tests/angle_tests/CompressedTextureTest.cpp
+++ b/tests/angle_tests/CompressedTextureTest.cpp
@@ -44,7 +44,7 @@
             }
         );
 
-        mTextureProgram = compileProgram(vsSource, textureFSSource);
+        mTextureProgram = CompileProgram(vsSource, textureFSSource);
         if (mTextureProgram == 0)
         {
             FAIL() << "shader compilation failed.";
diff --git a/tests/angle_tests/DepthStencilFormatsTest.cpp b/tests/angle_tests/DepthStencilFormatsTest.cpp
new file mode 100644
index 0000000..56d5210
--- /dev/null
+++ b/tests/angle_tests/DepthStencilFormatsTest.cpp
@@ -0,0 +1,96 @@
+#include "ANGLETest.h"
+
+class DepthStencilFormatsTest : public ANGLETest
+{
+protected:
+    DepthStencilFormatsTest()
+    {
+        setWindowWidth(128);
+        setWindowHeight(128);
+        setConfigRedBits(8);
+        setConfigGreenBits(8);
+        setConfigBlueBits(8);
+        setConfigAlphaBits(8);
+        setClientVersion(2);
+    }
+
+    bool checkTexImageFormatSupport(GLenum format, GLenum type)
+    {
+        EXPECT_GL_NO_ERROR();
+
+        GLuint tex = 0;
+        glGenTextures(1, &tex);
+        glBindTexture(GL_TEXTURE_2D, tex);
+        glTexImage2D(GL_TEXTURE_2D, 0, format, 1, 1, 0, format, type, NULL);
+        glDeleteTextures(1, &tex);
+
+        return (glGetError() == GL_NO_ERROR);
+    }
+
+    bool checkTexStorageFormatSupport(GLenum internalFormat)
+    {
+        EXPECT_GL_NO_ERROR();
+
+        GLuint tex = 0;
+        glGenTextures(1, &tex);
+        glBindTexture(GL_TEXTURE_2D, tex);
+        glTexStorage2DEXT(GL_TEXTURE_2D, 1, internalFormat, 1, 1);
+        glDeleteTextures(1, &tex);
+
+        return (glGetError() == GL_NO_ERROR);
+    }
+
+    bool checkRenderbufferFormatSupport(GLenum internalFormat)
+    {
+        EXPECT_GL_NO_ERROR();
+
+        GLuint rb = 0;
+        glGenRenderbuffers(1, &rb);
+        glBindRenderbuffer(GL_RENDERBUFFER, rb);
+        glRenderbufferStorage(GL_RENDERBUFFER, internalFormat, 1, 1);
+        glDeleteRenderbuffers(1, &rb);
+
+        return (glGetError() == GL_NO_ERROR);
+    }
+
+    virtual void SetUp()
+    {
+        ANGLETest::SetUp();
+    }
+
+    virtual void TearDown()
+    {
+        ANGLETest::TearDown();
+    }
+};
+
+TEST_F(DepthStencilFormatsTest, DepthTexture)
+{
+    bool shouldHaveTextureSupport = extensionEnabled("GL_ANGLE_depth_texture");
+    EXPECT_EQ(shouldHaveTextureSupport, checkTexImageFormatSupport(GL_DEPTH_COMPONENT, GL_UNSIGNED_SHORT));
+    EXPECT_EQ(shouldHaveTextureSupport, checkTexImageFormatSupport(GL_DEPTH_COMPONENT, GL_UNSIGNED_INT));
+
+    if (extensionEnabled("GL_EXT_texture_storage"))
+    {
+        EXPECT_EQ(shouldHaveTextureSupport, checkTexStorageFormatSupport(GL_DEPTH_COMPONENT16));
+        EXPECT_EQ(shouldHaveTextureSupport, checkTexStorageFormatSupport(GL_DEPTH_COMPONENT32_OES));
+    }
+}
+
+TEST_F(DepthStencilFormatsTest, PackedDepthStencil)
+{
+    // Expected to fail in D3D9 if GL_OES_packed_depth_stencil is not present.
+    // Expected to fail in D3D11 if GL_OES_packed_depth_stencil or GL_ANGLE_depth_texture is not present.
+
+    bool shouldHaveRenderbufferSupport = extensionEnabled("GL_OES_packed_depth_stencil");
+    EXPECT_EQ(shouldHaveRenderbufferSupport, checkRenderbufferFormatSupport(GL_DEPTH24_STENCIL8_OES));
+
+    bool shouldHaveTextureSupport = extensionEnabled("GL_OES_packed_depth_stencil") &&
+                                    extensionEnabled("GL_ANGLE_depth_texture");
+    EXPECT_EQ(shouldHaveTextureSupport, checkTexImageFormatSupport(GL_DEPTH_STENCIL_OES, GL_UNSIGNED_INT_24_8_OES));
+
+    if (extensionEnabled("GL_EXT_texture_storage"))
+    {
+        EXPECT_EQ(shouldHaveTextureSupport, checkTexStorageFormatSupport(GL_DEPTH24_STENCIL8_OES));
+    }
+}
diff --git a/tests/angle_tests/DrawBuffersTest.cpp b/tests/angle_tests/DrawBuffersTest.cpp
new file mode 100644
index 0000000..fdf2bdb
--- /dev/null
+++ b/tests/angle_tests/DrawBuffersTest.cpp
@@ -0,0 +1,329 @@
+#include "ANGLETest.h"
+
+class DrawBuffersTest : public ANGLETest
+{
+  protected:
+    DrawBuffersTest(int clientVersion)
+    {
+        setWindowWidth(128);
+        setWindowHeight(128);
+        setConfigRedBits(8);
+        setConfigGreenBits(8);
+        setConfigBlueBits(8);
+        setConfigAlphaBits(8);
+        setConfigDepthBits(24);
+        setClientVersion(clientVersion);
+    }
+
+    virtual void SetUp()
+    {
+        ANGLETest::SetUp();
+
+        glGenFramebuffers(1, &mFBO);
+        glBindFramebuffer(GL_FRAMEBUFFER, mFBO);
+
+        glGenTextures(4, mTextures);
+
+        for (size_t texIndex = 0; texIndex < ArraySize(mTextures); texIndex++)
+        {
+            glBindTexture(GL_TEXTURE_2D, mTextures[texIndex]);
+            glTexStorage2DEXT(GL_TEXTURE_2D, 1, GL_RGBA8, getWindowWidth(), getWindowHeight());
+        }
+
+        GLfloat data[] =
+        {
+            -1.0f, 1.0f,
+            -1.0f, -2.0f,
+            2.0f, 1.0f
+        };
+
+        glGenBuffers(1, &mBuffer);
+        glBindBuffer(GL_ARRAY_BUFFER, mBuffer);
+        glBufferData(GL_ARRAY_BUFFER, sizeof(GLfloat) * 6, data, GL_STATIC_DRAW);
+
+        GLint maxDrawBuffers;
+        glGetIntegerv(GL_MAX_DRAW_BUFFERS, &maxDrawBuffers);
+        ASSERT_EQ(maxDrawBuffers, 8);
+
+        ASSERT_GL_NO_ERROR();
+    }
+
+    virtual void TearDown()
+    {
+        glDeleteFramebuffers(1, &mFBO);
+        glDeleteTextures(4, mTextures);
+        glDeleteBuffers(1, &mBuffer);
+
+        ANGLETest::TearDown();
+    }
+
+    void setupMRTProgramESSL3(bool bufferEnabled[8], GLuint *programOut)
+    {
+        const std::string vertexShaderSource =
+            "#version 300 es\n"
+            "in vec4 position;\n"
+            "void main() {\n"
+            "    gl_Position = position;\n"
+            "}\n";
+
+        std::stringstream strstr;
+
+        strstr << "#version 300 es\n"
+                  "precision highp float;\n";
+
+        for (unsigned int index = 0; index < 8; index++)
+        {
+            if (bufferEnabled[index])
+            {
+                strstr << "layout(location = " << index << ") "
+                          "out vec4 value" << index << ";\n";
+            }
+        }
+
+        strstr << "void main()\n"
+                  "{\n";
+
+        for (unsigned int index = 0; index < 8; index++)
+        {
+            if (bufferEnabled[index])
+            {
+                unsigned int r = (index + 1) & 1;
+                unsigned int g = (index + 1) & 2;
+                unsigned int b = (index + 1) & 4;
+
+                strstr << "    value" << index << " = vec4("
+                       << r << ".0, " << g << ".0, "
+                       << b << ".0, 1.0);\n";
+            }
+        }
+
+        strstr << "}\n";
+
+        *programOut = CompileProgram(vertexShaderSource, strstr.str());
+        if (*programOut == 0)
+        {
+            FAIL() << "shader compilation failed.";
+        }
+
+        glUseProgram(*programOut);
+
+        GLint location = glGetAttribLocation(*programOut, "position");
+        ASSERT_NE(location, -1);
+        glBindBuffer(GL_ARRAY_BUFFER, mBuffer);
+        glVertexAttribPointer(location, 2, GL_FLOAT, GL_FALSE, 8, NULL);
+        glEnableVertexAttribArray(location);
+    }
+
+    void setupMRTProgramESSL1(bool bufferEnabled[8], GLuint *programOut)
+    {
+        const std::string vertexShaderSource =
+            "attribute vec4 position;\n"
+            "void main() {\n"
+            "    gl_Position = position;\n"
+            "}\n";
+
+        std::stringstream strstr;
+
+        strstr << "#extension GL_EXT_draw_buffers : enable\n"
+                  "precision highp float;\n"
+                  "void main()\n"
+                  "{\n";
+
+        for (unsigned int index = 0; index < 8; index++)
+        {
+            if (bufferEnabled[index])
+            {
+                unsigned int r = (index + 1) & 1;
+                unsigned int g = (index + 1) & 2;
+                unsigned int b = (index + 1) & 4;
+
+                strstr << "    gl_FragData[" << index << "] = vec4("
+                    << r << ".0, " << g << ".0, "
+                    << b << ".0, 1.0);\n";
+            }
+        }
+
+        strstr << "}\n";
+
+        *programOut = CompileProgram(vertexShaderSource, strstr.str());
+        if (*programOut == 0)
+        {
+            FAIL() << "shader compilation failed.";
+        }
+
+        glUseProgram(*programOut);
+
+        GLint location = glGetAttribLocation(*programOut, "position");
+        ASSERT_NE(location, -1);
+        glBindBuffer(GL_ARRAY_BUFFER, mBuffer);
+        glVertexAttribPointer(location, 2, GL_FLOAT, GL_FALSE, 8, NULL);
+        glEnableVertexAttribArray(location);
+    }
+
+    void setupMRTProgram(bool bufferEnabled[8], GLuint *programOut)
+    {
+        if (getClientVersion() == 3)
+        {
+            setupMRTProgramESSL3(bufferEnabled, programOut);
+        }
+        else
+        {
+            ASSERT_EQ(getClientVersion(), 2);
+            setupMRTProgramESSL1(bufferEnabled, programOut);
+        }
+    }
+
+    void verifyAttachment(unsigned int index, GLuint textureName)
+    {
+        for (unsigned int colorAttachment = 0; colorAttachment < 8; colorAttachment++)
+        {
+            glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0 + colorAttachment, GL_TEXTURE_2D, 0, 0);
+        }
+
+        glBindTexture(GL_TEXTURE_2D, textureName);
+        glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, textureName, 0);
+
+        unsigned int r = (((index + 1) & 1) > 0) ? 255 : 0;
+        unsigned int g = (((index + 1) & 2) > 0) ? 255 : 0;
+        unsigned int b = (((index + 1) & 4) > 0) ? 255 : 0;
+
+        EXPECT_PIXEL_EQ(getWindowWidth() / 2, getWindowHeight() / 2, r, g, b, 255);
+    }
+
+    void gapsTest()
+    {
+        glBindTexture(GL_TEXTURE_2D, mTextures[0]);
+        glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT1, GL_TEXTURE_2D, mTextures[0], 0);
+
+        bool flags[8] = { false, true };
+
+        GLuint program;
+        setupMRTProgram(flags, &program);
+
+        const GLenum bufs[] =
+        {
+            GL_NONE,
+            GL_COLOR_ATTACHMENT1
+        };
+        glUseProgram(program);
+        glDrawBuffersEXT(2, bufs);
+        glDrawArrays(GL_TRIANGLES, 0, 3);
+
+        verifyAttachment(1, mTextures[0]);
+
+        glDeleteProgram(program);
+    }
+
+    void firstAndLastTest()
+    {
+        glBindTexture(GL_TEXTURE_2D, mTextures[0]);
+        glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, mTextures[0], 0);
+
+        glBindTexture(GL_TEXTURE_2D, mTextures[1]);
+        glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT3, GL_TEXTURE_2D, mTextures[1], 0);
+
+        bool flags[8] = { true, false, false, true };
+
+        GLuint program;
+        setupMRTProgram(flags, &program);
+
+        const GLenum bufs[] =
+        {
+            GL_COLOR_ATTACHMENT0,
+            GL_NONE,
+            GL_NONE,
+            GL_COLOR_ATTACHMENT3
+        };
+
+        glUseProgram(program);
+        glDrawBuffersEXT(4, bufs);
+        glDrawArrays(GL_TRIANGLES, 0, 3);
+
+        verifyAttachment(0, mTextures[0]);
+        verifyAttachment(3, mTextures[1]);
+
+        EXPECT_GL_NO_ERROR();
+
+        glDeleteProgram(program);
+    }
+
+    void firstHalfNULLTest()
+    {
+        bool flags[8] = { false };
+        GLenum bufs[8] = { GL_NONE };
+
+        for (unsigned int texIndex = 0; texIndex < 4; texIndex++)
+        {
+            glBindTexture(GL_TEXTURE_2D, mTextures[texIndex]);
+            glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT4 + texIndex, GL_TEXTURE_2D, mTextures[texIndex], 0);
+            flags[texIndex + 4] = true;
+            bufs[texIndex + 4] = GL_COLOR_ATTACHMENT4 + texIndex;
+        }
+
+        GLuint program;
+        setupMRTProgram(flags, &program);
+
+        glUseProgram(program);
+        glDrawBuffersEXT(8, bufs);
+        glDrawArrays(GL_TRIANGLES, 0, 3);
+
+        for (unsigned int texIndex = 0; texIndex < 4; texIndex++)
+        {
+            verifyAttachment(texIndex + 4, mTextures[texIndex]);
+        }
+
+        EXPECT_GL_NO_ERROR();
+
+        glDeleteProgram(program);
+    }
+
+    GLuint mFBO;
+    GLuint mTextures[4];
+    GLuint mBuffer;
+};
+
+class DrawBuffersTestESSL3 : public DrawBuffersTest
+{
+  protected:
+    DrawBuffersTestESSL3()
+        : DrawBuffersTest(3)
+    {}
+};
+
+class DrawBuffersTestESSL1 : public DrawBuffersTest
+{
+  protected:
+    DrawBuffersTestESSL1()
+        : DrawBuffersTest(2)
+    {}
+};
+
+TEST_F(DrawBuffersTestESSL3, Gaps)
+{
+    gapsTest();
+}
+
+TEST_F(DrawBuffersTestESSL1, Gaps)
+{
+    gapsTest();
+}
+
+TEST_F(DrawBuffersTestESSL3, FirstAndLast)
+{
+    firstAndLastTest();
+}
+
+TEST_F(DrawBuffersTestESSL1, FirstAndLast)
+{
+    firstAndLastTest();
+}
+
+TEST_F(DrawBuffersTestESSL3, FirstHalfNULL)
+{
+    firstHalfNULLTest();
+}
+
+TEST_F(DrawBuffersTestESSL1, FirstHalfNULL)
+{
+    firstHalfNULLTest();
+}
diff --git a/tests/angle_tests/GLSLTest.cpp b/tests/angle_tests/GLSLTest.cpp
index 4b03422..dca8ac2 100644
--- a/tests/angle_tests/GLSLTest.cpp
+++ b/tests/angle_tests/GLSLTest.cpp
@@ -27,6 +27,230 @@
         );
     }
 
+    std::string GenerateVaryingType(GLint vectorSize)
+    {
+        char varyingType[10];
+
+        if (vectorSize == 1)
+        {
+            sprintf(varyingType, "float");
+        }
+        else
+        {
+            sprintf(varyingType, "vec%d", vectorSize);
+        }
+
+        return std::string(varyingType);
+    }
+
+    std::string GenerateVectorVaryingDeclaration(GLint vectorSize, GLint arraySize, GLint id)
+    {
+        char buff[100];
+
+        if (arraySize == 1)
+        {
+            sprintf(buff, "varying %s v%d;\n", GenerateVaryingType(vectorSize).c_str(), id);
+        }
+        else
+        {
+            sprintf(buff, "varying %s v%d[%d];\n", GenerateVaryingType(vectorSize).c_str(), id, arraySize);
+        }
+
+        return std::string(buff);
+    }
+
+    std::string GenerateVectorVaryingSettingCode(GLint vectorSize, GLint arraySize, GLint id)
+    {
+        std::string returnString;
+        char buff[100];
+
+        if (arraySize == 1)
+        {
+            sprintf(buff, "\t v%d = %s(1.0);\n", id, GenerateVaryingType(vectorSize).c_str());
+            returnString += buff;
+        }
+        else
+        {
+            for (int i = 0; i < arraySize; i++)
+            {
+                sprintf(buff, "\t v%d[%d] = %s(1.0);\n", id, i, GenerateVaryingType(vectorSize).c_str());
+                returnString += buff;
+            }
+        }
+
+        return returnString;
+    }
+
+    std::string GenerateVectorVaryingUseCode(GLint arraySize, GLint id)
+    {
+        if (arraySize == 1)
+        {
+            char buff[100];
+            sprintf(buff, "v%d + ", id);
+            return std::string(buff);
+        }
+        else
+        {
+            std::string returnString;
+            for (int i = 0; i < arraySize; i++)
+            {
+                char buff[100];
+                sprintf(buff, "v%d[%d] + ", id, i);
+                returnString += buff;
+            }
+            return returnString;
+        }
+    }
+
+    void GenerateGLSLWithVaryings(GLint floatCount, GLint floatArrayCount, GLint vec2Count, GLint vec2ArrayCount, GLint vec3Count, GLint vec3ArrayCount, std::string* fragmentShader, std::string* vertexShader)
+    {
+        // Generate a string declaring the varyings, to share between the fragment shader and the vertex shader.
+        std::string varyingDeclaration;
+
+        unsigned int varyingCount = 0;
+
+        for (GLint i = 0; i < floatCount; i++)
+        {
+            varyingDeclaration += GenerateVectorVaryingDeclaration(1, 1, varyingCount);
+            varyingCount += 1;
+        }
+
+        for (GLint i = 0; i < floatArrayCount; i++)
+        {
+            varyingDeclaration += GenerateVectorVaryingDeclaration(1, 2, varyingCount);
+            varyingCount += 1;
+        }
+
+        for (GLint i = 0; i < vec2Count; i++)
+        {
+            varyingDeclaration += GenerateVectorVaryingDeclaration(2, 1, varyingCount);
+            varyingCount += 1;
+        }
+
+        for (GLint i = 0; i < vec2ArrayCount; i++)
+        {
+            varyingDeclaration += GenerateVectorVaryingDeclaration(2, 2, varyingCount);
+            varyingCount += 1;
+        }
+
+        for (GLint i = 0; i < vec3Count; i++)
+        {
+            varyingDeclaration += GenerateVectorVaryingDeclaration(3, 1, varyingCount);
+            varyingCount += 1;
+        }
+
+        for (GLint i = 0; i < vec3ArrayCount; i++)
+        {
+            varyingDeclaration += GenerateVectorVaryingDeclaration(3, 2, varyingCount);
+            varyingCount += 1;
+        }
+
+        // Generate the vertex shader
+        vertexShader->clear();
+        vertexShader->append(varyingDeclaration);
+        vertexShader->append("\nvoid main()\n{\n");
+
+        unsigned int currentVSVarying = 0;
+
+        for (GLint i = 0; i < floatCount; i++)
+        {
+            vertexShader->append(GenerateVectorVaryingSettingCode(1, 1, currentVSVarying));
+            currentVSVarying += 1;
+        }
+
+        for (GLint i = 0; i < floatArrayCount; i++)
+        {
+            vertexShader->append(GenerateVectorVaryingSettingCode(1, 2, currentVSVarying));
+            currentVSVarying += 1;
+        }
+
+        for (GLint i = 0; i < vec2Count; i++)
+        {
+            vertexShader->append(GenerateVectorVaryingSettingCode(2, 1, currentVSVarying));
+            currentVSVarying += 1;
+        }
+
+        for (GLint i = 0; i < vec2ArrayCount; i++)
+        {
+            vertexShader->append(GenerateVectorVaryingSettingCode(2, 2, currentVSVarying));
+            currentVSVarying += 1;
+        }
+
+        for (GLint i = 0; i < vec3Count; i++)
+        {
+            vertexShader->append(GenerateVectorVaryingSettingCode(3, 1, currentVSVarying));
+            currentVSVarying += 1;
+        }
+
+        for (GLint i = 0; i < vec3ArrayCount; i++)
+        {
+            vertexShader->append(GenerateVectorVaryingSettingCode(3, 2, currentVSVarying));
+            currentVSVarying += 1;
+        }
+
+        vertexShader->append("}\n");
+
+        // Generate the fragment shader
+        fragmentShader->clear();
+        fragmentShader->append("precision highp float;\n");
+        fragmentShader->append(varyingDeclaration);
+        fragmentShader->append("\nvoid main() \n{ \n\tvec4 retColor = vec4(0,0,0,0);\n");
+
+        unsigned int currentFSVarying = 0;
+
+        // Make use of the float varyings
+        fragmentShader->append("\tretColor += vec4(");
+
+        for (GLint i = 0; i < floatCount; i++)
+        {
+            fragmentShader->append(GenerateVectorVaryingUseCode(1, currentFSVarying));
+            currentFSVarying += 1;
+        }
+
+        for (GLint i = 0; i < floatArrayCount; i++)
+        {
+            fragmentShader->append(GenerateVectorVaryingUseCode(2, currentFSVarying));
+            currentFSVarying += 1;
+        }
+
+        fragmentShader->append("0.0, 0.0, 0.0, 0.0);\n");
+
+        // Make use of the vec2 varyings
+        fragmentShader->append("\tretColor += vec4(");
+
+        for (GLint i = 0; i < vec2Count; i++)
+        {
+            fragmentShader->append(GenerateVectorVaryingUseCode(1, currentFSVarying));
+            currentFSVarying += 1;
+        }
+
+        for (GLint i = 0; i < vec2ArrayCount; i++)
+        {
+            fragmentShader->append(GenerateVectorVaryingUseCode(2, currentFSVarying));
+            currentFSVarying += 1;
+        }
+
+        fragmentShader->append("vec2(0.0, 0.0), 0.0, 0.0);\n");
+
+        // Make use of the vec3 varyings
+        fragmentShader->append("\tretColor += vec4(");
+
+        for (GLint i = 0; i < vec3Count; i++)
+        {
+            fragmentShader->append(GenerateVectorVaryingUseCode(1, currentFSVarying));
+            currentFSVarying += 1;
+        }
+
+        for (GLint i = 0; i < vec3ArrayCount; i++)
+        {
+            fragmentShader->append(GenerateVectorVaryingUseCode(2, currentFSVarying));
+            currentFSVarying += 1;
+        }
+
+        fragmentShader->append("vec3(0.0, 0.0, 0.0), 0.0);\n");
+        fragmentShader->append("\tgl_FragColor = retColor;\n}");
+    }
+
     std::string mSimpleVSSource;
 };
 
@@ -48,7 +272,7 @@
         }
     );
 
-    GLuint program = compileProgram(mSimpleVSSource, fragmentShaderSource);
+    GLuint program = CompileProgram(mSimpleVSSource, fragmentShaderSource);
     EXPECT_NE(0u, program);
 }
 TEST_F(GLSLTest, ScopedStructsOrderBug)
@@ -79,7 +303,7 @@
         }
     );
 
-    GLuint program = compileProgram(mSimpleVSSource, fragmentShaderSource);
+    GLuint program = CompileProgram(mSimpleVSSource, fragmentShaderSource);
     EXPECT_NE(0u, program);
 }
 
@@ -111,7 +335,7 @@
         }
     );
 
-    GLuint program = compileProgram(mSimpleVSSource, fragmentShaderSource);
+    GLuint program = CompileProgram(mSimpleVSSource, fragmentShaderSource);
     EXPECT_NE(0u, program);
 }
 
@@ -140,7 +364,7 @@
         }
     );
 
-    GLuint program = compileProgram(vertexShaderSource, fragmentShaderSource);
+    GLuint program = CompileProgram(vertexShaderSource, fragmentShaderSource);
     EXPECT_NE(0u, program);
 }
 
@@ -169,7 +393,7 @@
         "  gl_FragColor = color;\n"
         "}\n";
 
-    GLuint program = compileProgram(vertexShaderSource, fragmentShaderSource);
+    GLuint program = CompileProgram(vertexShaderSource, fragmentShaderSource);
     ASSERT_NE(0u, program);
 
     drawQuad(program, "a_position", 0.5f);
@@ -202,7 +426,7 @@
         "  gl_FragColor = vec4(v, 0.0, 0.0, 1.0);\n"
         "}\n";
 
-    GLuint program = compileProgram(vertexShaderSource, fragmentShaderSource);
+    GLuint program = CompileProgram(vertexShaderSource, fragmentShaderSource);
     EXPECT_NE(0u, program);
 }
 
@@ -222,7 +446,44 @@
         void main() { v_varying = a_position.x; gl_Position = a_position; }
     );
 
-    GLuint program = compileProgram(vertexShaderSource, fragmentShaderSource);
+    GLuint program = CompileProgram(vertexShaderSource, fragmentShaderSource);
+    EXPECT_NE(0u, program);
+}
+
+TEST_F(GLSLTest, FrontFacingAndVarying)
+{
+    const std::string vertexShaderSource = SHADER_SOURCE
+    (
+        attribute vec4 a_position;
+        varying float v_varying;
+        void main()
+        {
+            v_varying = a_position.x;
+            gl_Position = a_position;
+        }
+    );
+
+    const std::string fragmentShaderSource = SHADER_SOURCE
+    (
+        precision mediump float;
+        varying float v_varying;
+        void main()
+        {
+            vec4 c;
+
+            if (gl_FrontFacing)
+            {
+                c = vec4(v_varying, 0, 0, 1.0);
+            }
+            else
+            {
+                c = vec4(0, v_varying, 0, 1.0);
+            }
+            gl_FragColor = c;
+        }
+    );
+
+    GLuint program = CompileProgram(vertexShaderSource, fragmentShaderSource);
     EXPECT_NE(0u, program);
 }
 
@@ -242,7 +503,7 @@
         void main() { v_varying = a_position.x; gl_Position = a_position; }
     );
 
-    GLuint program = compileProgram(vertexShaderSource, fragmentShaderSource);
+    GLuint program = CompileProgram(vertexShaderSource, fragmentShaderSource);
     EXPECT_NE(0u, program);
 }
 
@@ -262,7 +523,7 @@
         void main() { v_varying = a_position.x; gl_Position = a_position; }
     );
 
-    GLuint program = compileProgram(vertexShaderSource, fragmentShaderSource);
+    GLuint program = CompileProgram(vertexShaderSource, fragmentShaderSource);
     EXPECT_NE(0u, program);
 }
 
@@ -283,7 +544,7 @@
         void main() { v_varying = a_position.x; gl_Position = a_position; }
     );
 
-    GLuint program = compileProgram(vertexShaderSource, fragmentShaderSource);
+    GLuint program = CompileProgram(vertexShaderSource, fragmentShaderSource);
     EXPECT_NE(0u, program);
 }
 
@@ -302,6 +563,160 @@
         "varying float v_varying;\n"
         "void main() { v_varying = a_position.x; gl_Position = a_position; }\n";
 
-    GLuint program = compileProgram(vertexShaderSource, fragmentShaderSource);
+    GLuint program = CompileProgram(vertexShaderSource, fragmentShaderSource);
     EXPECT_NE(0u, program);
 }
+
+TEST_F(GLSLTest, MaxVaryingVec3)
+{
+    GLint maxVaryings = 0;
+    glGetIntegerv(GL_MAX_VARYING_VECTORS, &maxVaryings);
+
+    std::string fragmentShaderSource;
+    std::string vertexShaderSource;
+
+    GenerateGLSLWithVaryings(0, 0, 0, 0, maxVaryings, 0, &fragmentShaderSource, &vertexShaderSource);
+
+    GLuint program = CompileProgram(vertexShaderSource, fragmentShaderSource);
+    EXPECT_NE(0u, program);
+}
+
+TEST_F(GLSLTest, MaxVaryingVec3Array)
+{
+    GLint maxVaryings = 0;
+    glGetIntegerv(GL_MAX_VARYING_VECTORS, &maxVaryings);
+
+    std::string fragmentShaderSource;
+    std::string vertexShaderSource;
+
+    GenerateGLSLWithVaryings(0, 0, 0, 0, 0, maxVaryings / 2, &fragmentShaderSource, &vertexShaderSource);
+
+    GLuint program = CompileProgram(vertexShaderSource, fragmentShaderSource);
+    EXPECT_NE(0u, program);
+}
+
+TEST_F(GLSLTest, MaxVaryingVec3AndOneFloat)
+{
+    GLint maxVaryings = 0;
+    glGetIntegerv(GL_MAX_VARYING_VECTORS, &maxVaryings);
+
+    std::string fragmentShaderSource;
+    std::string vertexShaderSource;
+
+    GenerateGLSLWithVaryings(1, 0, 0, 0, maxVaryings, 0, &fragmentShaderSource, &vertexShaderSource);
+
+    GLuint program = CompileProgram(vertexShaderSource, fragmentShaderSource);
+    EXPECT_NE(0u, program);
+}
+
+TEST_F(GLSLTest, MaxVaryingVec3ArrayAndOneFloatArray)
+{
+    GLint maxVaryings = 0;
+    glGetIntegerv(GL_MAX_VARYING_VECTORS, &maxVaryings);
+
+    std::string fragmentShaderSource;
+    std::string vertexShaderSource;
+
+    GenerateGLSLWithVaryings(0, 1, 0, 0, 0, maxVaryings / 2, &fragmentShaderSource, &vertexShaderSource);
+
+    GLuint program = CompileProgram(vertexShaderSource, fragmentShaderSource);
+    EXPECT_NE(0u, program);
+}
+
+TEST_F(GLSLTest, TwiceMaxVaryingVec2)
+{
+    GLint maxVaryings = 0;
+    glGetIntegerv(GL_MAX_VARYING_VECTORS, &maxVaryings);
+
+    std::string fragmentShaderSource;
+    std::string vertexShaderSource;
+
+    GenerateGLSLWithVaryings(0, 0, 2 * maxVaryings, 0, 0, 0, &fragmentShaderSource, &vertexShaderSource);
+
+    GLuint program = CompileProgram(vertexShaderSource, fragmentShaderSource);
+    EXPECT_NE(0u, program);
+}
+
+TEST_F(GLSLTest, MaxVaryingVec2Arrays)
+{
+    GLint maxVaryings = 0;
+    glGetIntegerv(GL_MAX_VARYING_VECTORS, &maxVaryings);
+
+    std::string fragmentShaderSource;
+    std::string vertexShaderSource;
+
+    GenerateGLSLWithVaryings(0, 0, 0, maxVaryings, 0, 0, &fragmentShaderSource, &vertexShaderSource);
+
+    GLuint program = CompileProgram(vertexShaderSource, fragmentShaderSource);
+    EXPECT_NE(0u, program);
+}
+
+TEST_F(GLSLTest, MaxPlusOneVaryingVec3)
+{
+    GLint maxVaryings = 0;
+    glGetIntegerv(GL_MAX_VARYING_VECTORS, &maxVaryings);
+
+    std::string fragmentShaderSource;
+    std::string vertexShaderSource;
+
+    GenerateGLSLWithVaryings(0, 0, 0, 0, maxVaryings + 1, 0, &fragmentShaderSource, &vertexShaderSource);
+
+    GLuint program = CompileProgram(vertexShaderSource, fragmentShaderSource);
+    EXPECT_EQ(0u, program);
+}
+
+TEST_F(GLSLTest, MaxPlusOneVaryingVec3Array)
+{
+    GLint maxVaryings = 0;
+    glGetIntegerv(GL_MAX_VARYING_VECTORS, &maxVaryings);
+
+    std::string fragmentShaderSource;
+    std::string vertexShaderSource;
+
+    GenerateGLSLWithVaryings(0, 0, 0, 0, 0, maxVaryings / 2 + 1, &fragmentShaderSource, &vertexShaderSource);
+
+    GLuint program = CompileProgram(vertexShaderSource, fragmentShaderSource);
+    EXPECT_EQ(0u, program);
+}
+
+TEST_F(GLSLTest, MaxVaryingVec3AndOneVec2)
+{
+    GLint maxVaryings = 0;
+    glGetIntegerv(GL_MAX_VARYING_VECTORS, &maxVaryings);
+
+    std::string fragmentShaderSource;
+    std::string vertexShaderSource;
+
+    GenerateGLSLWithVaryings(0, 0, 1, 0, maxVaryings, 0, &fragmentShaderSource, &vertexShaderSource);
+
+    GLuint program = CompileProgram(vertexShaderSource, fragmentShaderSource);
+    EXPECT_EQ(0u, program);
+}
+
+TEST_F(GLSLTest, MaxPlusOneVaryingVec2)
+{
+    GLint maxVaryings = 0;
+    glGetIntegerv(GL_MAX_VARYING_VECTORS, &maxVaryings);
+
+    std::string fragmentShaderSource;
+    std::string vertexShaderSource;
+
+    GenerateGLSLWithVaryings(0, 0, 2 * maxVaryings + 1, 0, 0, 0, &fragmentShaderSource, &vertexShaderSource);
+
+    GLuint program = CompileProgram(vertexShaderSource, fragmentShaderSource);
+    EXPECT_EQ(0u, program);
+}
+
+TEST_F(GLSLTest, MaxVaryingVec3ArrayAndMaxPlusOneFloatArray)
+{
+    GLint maxVaryings = 0;
+    glGetIntegerv(GL_MAX_VARYING_VECTORS, &maxVaryings);
+
+    std::string fragmentShaderSource;
+    std::string vertexShaderSource;
+
+    GenerateGLSLWithVaryings(0, maxVaryings / 2 + 1, 0, 0, 0, maxVaryings / 2, &fragmentShaderSource, &vertexShaderSource);
+
+    GLuint program = CompileProgram(vertexShaderSource, fragmentShaderSource);
+    EXPECT_EQ(0u, program);
+}
diff --git a/tests/angle_tests/IncompleteTextureTest.cpp b/tests/angle_tests/IncompleteTextureTest.cpp
index 12ab673..eea64f2 100644
--- a/tests/angle_tests/IncompleteTextureTest.cpp
+++ b/tests/angle_tests/IncompleteTextureTest.cpp
@@ -44,7 +44,7 @@
             }
         );
 
-        mProgram = compileProgram(vertexShaderSource, fragmentShaderSource);
+        mProgram = CompileProgram(vertexShaderSource, fragmentShaderSource);
         if (mProgram == 0)
         {
             FAIL() << "shader compilation failed.";
diff --git a/tests/angle_tests/IndexedPointsTest.cpp b/tests/angle_tests/IndexedPointsTest.cpp
index cf88ed0..e5c7c78 100644
--- a/tests/angle_tests/IndexedPointsTest.cpp
+++ b/tests/angle_tests/IndexedPointsTest.cpp
@@ -52,7 +52,7 @@
             }
         );
 
-        mProgram = compileProgram(vertexShaderSource, fragmentShaderSource);
+        mProgram = CompileProgram(vertexShaderSource, fragmentShaderSource);
         if (mProgram == 0)
         {
             FAIL() << "shader compilation failed.";
diff --git a/tests/angle_tests/LineLoopTest.cpp b/tests/angle_tests/LineLoopTest.cpp
index 4dd76a9..53c525c 100644
--- a/tests/angle_tests/LineLoopTest.cpp
+++ b/tests/angle_tests/LineLoopTest.cpp
@@ -40,7 +40,7 @@
             }
         );
 
-        mProgram = compileProgram(vsSource, fsSource);
+        mProgram = CompileProgram(vsSource, fsSource);
         if (mProgram == 0)
         {
             FAIL() << "shader compilation failed.";
diff --git a/tests/angle_tests/MaxTextureSizeTest.cpp b/tests/angle_tests/MaxTextureSizeTest.cpp
index 4dabce2..989be5b 100644
--- a/tests/angle_tests/MaxTextureSizeTest.cpp
+++ b/tests/angle_tests/MaxTextureSizeTest.cpp
@@ -52,8 +52,8 @@
             }
         );
 
-        mTextureProgram = compileProgram(vsSource, textureFSSource);
-        mBlueProgram = compileProgram(vsSource, blueFSSource);
+        mTextureProgram = CompileProgram(vsSource, textureFSSource);
+        mBlueProgram = CompileProgram(vsSource, blueFSSource);
         if (mTextureProgram == 0 || mBlueProgram == 0)
         {
             FAIL() << "shader compilation failed.";
diff --git a/tests/angle_tests/OcclusionQueriesTest.cpp b/tests/angle_tests/OcclusionQueriesTest.cpp
index d56a139..74da8a2 100644
--- a/tests/angle_tests/OcclusionQueriesTest.cpp
+++ b/tests/angle_tests/OcclusionQueriesTest.cpp
@@ -1,5 +1,8 @@
 #include "ANGLETest.h"
 
+// Needed for Sleep()
+#include <Windows.h>
+
 class OcclusionQueriesTest : public ANGLETest
 {
 protected:
@@ -38,7 +41,7 @@
             }
         );
 
-        mProgram = compileProgram(passthroughVS, passthroughPS);
+        mProgram = CompileProgram(passthroughVS, passthroughPS);
         if (mProgram == 0)
         {
             FAIL() << "shader compilation failed.";
diff --git a/tests/angle_tests/PBOExtensionTest.cpp b/tests/angle_tests/PBOExtensionTest.cpp
index a6547e8..7dabc93 100755
--- a/tests/angle_tests/PBOExtensionTest.cpp
+++ b/tests/angle_tests/PBOExtensionTest.cpp
@@ -50,7 +50,7 @@
                 }
             );
 
-            mProgram = compileProgram(vertexShaderSrc, fragmentShaderSrc);
+            mProgram = CompileProgram(vertexShaderSrc, fragmentShaderSrc);
 
             glGenBuffers(1, &mPositionVBO);
             glBindBuffer(GL_ARRAY_BUFFER, mPositionVBO);
diff --git a/tests/angle_tests/ProgramBinaryTest.cpp b/tests/angle_tests/ProgramBinaryTest.cpp
index de2d99d..df144c3 100644
--- a/tests/angle_tests/ProgramBinaryTest.cpp
+++ b/tests/angle_tests/ProgramBinaryTest.cpp
@@ -34,7 +34,7 @@
             }
         );
 
-        mProgram = compileProgram(vertexShaderSource, fragmentShaderSource);
+        mProgram = CompileProgram(vertexShaderSource, fragmentShaderSource);
         if (mProgram == 0)
         {
             FAIL() << "shader compilation failed.";
diff --git a/tests/angle_tests/ReadPixelsTest.cpp b/tests/angle_tests/ReadPixelsTest.cpp
index 3b7325c..a2b3218 100644
--- a/tests/angle_tests/ReadPixelsTest.cpp
+++ b/tests/angle_tests/ReadPixelsTest.cpp
@@ -48,7 +48,7 @@
             }
         );
 
-        mProgram = compileProgram(vertexShaderSrc, fragmentShaderSrc);
+        mProgram = CompileProgram(vertexShaderSrc, fragmentShaderSrc);
 
         glGenTextures(1, &mTexture);
         glBindTexture(GL_TEXTURE_2D, mTexture);
diff --git a/tests/angle_tests/SwizzleTest.cpp b/tests/angle_tests/SwizzleTest.cpp
index 8192f68..e7188c5 100644
--- a/tests/angle_tests/SwizzleTest.cpp
+++ b/tests/angle_tests/SwizzleTest.cpp
@@ -74,7 +74,7 @@
             }
         );
 
-        mProgram = compileProgram(vertexShaderSource, fragmentShaderSource);
+        mProgram = CompileProgram(vertexShaderSource, fragmentShaderSource);
         if (mProgram == 0)
         {
             FAIL() << "shader compilation failed.";
diff --git a/tests/angle_tests/TextureTest.cpp b/tests/angle_tests/TextureTest.cpp
index 8d16b36..6323d8d 100644
--- a/tests/angle_tests/TextureTest.cpp
+++ b/tests/angle_tests/TextureTest.cpp
@@ -68,8 +68,8 @@
             }
         );
 
-        m2DProgram = compileProgram(vertexShaderSource, fragmentShaderSource2D);
-        mCubeProgram = compileProgram(vertexShaderSource, fragmentShaderSourceCube);
+        m2DProgram = CompileProgram(vertexShaderSource, fragmentShaderSource2D);
+        mCubeProgram = CompileProgram(vertexShaderSource, fragmentShaderSourceCube);
         if (m2DProgram == 0 || mCubeProgram == 0)
         {
             FAIL() << "shader compilation failed.";
diff --git a/tests/angle_tests/TransformFeedbackTest.cpp b/tests/angle_tests/TransformFeedbackTest.cpp
new file mode 100644
index 0000000..8bdb4e7
--- /dev/null
+++ b/tests/angle_tests/TransformFeedbackTest.cpp
@@ -0,0 +1,112 @@
+#include "ANGLETest.h"
+
+class TransformFeedbackTest : public ANGLETest
+{
+  protected:
+      TransformFeedbackTest()
+    {
+        setWindowWidth(128);
+        setWindowHeight(128);
+        setConfigRedBits(8);
+        setConfigGreenBits(8);
+        setConfigBlueBits(8);
+        setConfigAlphaBits(8);
+        setClientVersion(3);
+    }
+
+    virtual void SetUp()
+    {
+        ANGLETest::SetUp();
+
+        const std::string vertexShaderSource = SHADER_SOURCE
+        (
+            precision highp float;
+            attribute vec4 position;
+
+            void main()
+            {
+                gl_Position = position;
+            }
+        );
+
+        const std::string fragmentShaderSource = SHADER_SOURCE
+        (
+            precision highp float;
+
+            void main()
+            {
+                gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0);
+            }
+        );
+
+        mProgram = CompileProgram(vertexShaderSource, fragmentShaderSource);
+        if (mProgram == 0)
+        {
+            FAIL() << "shader compilation failed.";
+        }
+
+        glGenBuffers(1, &mTransformFeedbackBuffer);
+        mTransformFeedbackBufferSize = 1 << 24; // ~16MB
+        glBindBuffer(GL_TRANSFORM_FEEDBACK_BUFFER, mTransformFeedbackBuffer);
+        glBufferData(GL_TRANSFORM_FEEDBACK_BUFFER, mTransformFeedbackBufferSize, NULL, GL_STATIC_DRAW);
+
+        ASSERT_GL_NO_ERROR();
+    }
+
+    virtual void TearDown()
+    {
+        glDeleteProgram(mProgram);
+        glDeleteBuffers(1, &mTransformFeedbackBuffer);
+        ANGLETest::TearDown();
+    }
+
+    GLuint mProgram;
+
+    size_t mTransformFeedbackBufferSize;
+    GLuint mTransformFeedbackBuffer;
+};
+
+TEST_F(TransformFeedbackTest, ZeroSizedViewport)
+{
+    // Set the program's transform feedback varyings (just gl_Position)
+    const GLchar* transformFeedbackVaryings[] =
+    {
+        "gl_Position"
+    };
+    glTransformFeedbackVaryings(mProgram, ArraySize(transformFeedbackVaryings), transformFeedbackVaryings, GL_INTERLEAVED_ATTRIBS);
+    glLinkProgram(mProgram);
+
+    // Re-link the program
+    GLint linkStatus;
+    glGetProgramiv(mProgram, GL_LINK_STATUS, &linkStatus);
+    ASSERT_NE(linkStatus, 0);
+
+    glUseProgram(mProgram);
+
+    // Bind the buffer for transform feedback output and start transform feedback
+    glBindBufferBase(GL_TRANSFORM_FEEDBACK_BUFFER, 0, mTransformFeedbackBuffer);
+    glBeginTransformFeedback(GL_TRIANGLES);
+
+    // Create a query to check how many primitives were written
+    GLuint primitivesWrittenQuery = 0;
+    glGenQueries(1, &primitivesWrittenQuery);
+    glBeginQuery(GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN, primitivesWrittenQuery);
+
+    // Set a viewport that would result in no pixels being written to the framebuffer and draw
+    // a quad
+    glViewport(0, 0, 0, 0);
+
+    drawQuad(mProgram, "position", 0.5f);
+
+    // End the query and transform feedkback
+    glEndQuery(GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN);
+    glEndTransformFeedback();
+
+    // Check how many primitives were written and verify that some were written even if
+    // no pixels were rendered
+    GLuint primitivesWritten = 0;
+    glGetQueryObjectuiv(primitivesWrittenQuery, GL_QUERY_RESULT_EXT, &primitivesWritten);
+    EXPECT_GL_NO_ERROR();
+
+    EXPECT_EQ(primitivesWritten, 2);
+}
diff --git a/tests/angle_tests/UniformTest.cpp b/tests/angle_tests/UniformTest.cpp
new file mode 100644
index 0000000..4f76b0e
--- /dev/null
+++ b/tests/angle_tests/UniformTest.cpp
@@ -0,0 +1,74 @@
+#include "ANGLETest.h"
+
+class UniformTest : public ANGLETest
+{
+  protected:
+    UniformTest()
+    {
+        setWindowWidth(128);
+        setWindowHeight(128);
+        setConfigRedBits(8);
+        setConfigGreenBits(8);
+        setConfigBlueBits(8);
+        setConfigAlphaBits(8);
+    }
+
+    virtual void SetUp()
+    {
+        ANGLETest::SetUp();
+
+        const std::string &vertexShader = "void main() { gl_Position = vec4(1); }";
+        const std::string &fragShader =
+            "precision mediump float;\n"
+            "uniform float uniF;\n"
+            "uniform int uniI;\n"
+            "void main() { gl_FragColor = vec4(uniF + float(uniI)); }";
+
+        mProgram = CompileProgram(vertexShader, fragShader);
+        ASSERT_NE(mProgram, 0u);
+
+        mUniformFLocation = glGetUniformLocation(mProgram, "uniF");
+        ASSERT_NE(mUniformFLocation, -1);
+
+        mUniformILocation = glGetUniformLocation(mProgram, "uniI");
+        ASSERT_NE(mUniformILocation, -1);
+
+        ASSERT_GL_NO_ERROR();
+    }
+
+    virtual void TearDown()
+    {
+        glDeleteProgram(mProgram);
+        ANGLETest::TearDown();
+    }
+
+    GLuint mProgram;
+    GLint mUniformFLocation;
+    GLint mUniformILocation;
+};
+
+TEST_F(UniformTest, GetUniformNoCurrentProgram)
+{
+    glUseProgram(mProgram);
+    glUniform1f(mUniformFLocation, 1.0f);
+    glUniform1i(mUniformILocation, 1);
+    glUseProgram(0);
+
+    GLfloat f;
+    glGetnUniformfvEXT(mProgram, mUniformFLocation, 4, &f);
+    ASSERT_GL_NO_ERROR();
+    EXPECT_EQ(1.0f, f);
+
+    glGetUniformfv(mProgram, mUniformFLocation, &f);
+    ASSERT_GL_NO_ERROR();
+    EXPECT_EQ(1.0f, f);
+
+    GLint i;
+    glGetnUniformivEXT(mProgram, mUniformILocation, 4, &i);
+    ASSERT_GL_NO_ERROR();
+    EXPECT_EQ(1, i);
+
+    glGetUniformiv(mProgram, mUniformILocation, &i);
+    ASSERT_GL_NO_ERROR();
+    EXPECT_EQ(1, i);
+}
diff --git a/tests/angle_tests/UnpackAlignmentTest.cpp b/tests/angle_tests/UnpackAlignmentTest.cpp
index 5cf754c..35c7ec2 100644
--- a/tests/angle_tests/UnpackAlignmentTest.cpp
+++ b/tests/angle_tests/UnpackAlignmentTest.cpp
@@ -43,7 +43,7 @@
             }
         );
 
-        mProgram = compileProgram(vertexShaderSource, fragmentShaderSource);
+        mProgram = CompileProgram(vertexShaderSource, fragmentShaderSource);
         if (mProgram == 0)
         {
             FAIL() << "shader compilation failed.";
diff --git a/tests/angle_tests/VertexAttributeTest.cpp b/tests/angle_tests/VertexAttributeTest.cpp
index d8acd22..f84404b 100644
--- a/tests/angle_tests/VertexAttributeTest.cpp
+++ b/tests/angle_tests/VertexAttributeTest.cpp
@@ -86,7 +86,7 @@
             }
         );
 
-        mProgram = compileProgram(testVertexShaderSource, testFragmentShaderSource);
+        mProgram = CompileProgram(testVertexShaderSource, testFragmentShaderSource);
         if (mProgram == 0)
         {
             FAIL() << "shader compilation failed.";
diff --git a/tests/angle_tests/win32/ANGLETest_win32.cpp b/tests/angle_tests/win32/ANGLETest_win32.cpp
deleted file mode 100644
index 0c1762c..0000000
--- a/tests/angle_tests/win32/ANGLETest_win32.cpp
+++ /dev/null
@@ -1,92 +0,0 @@
-#include "ANGLETest.h"
-
-#include <windows.h>
-
-LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
-{
-    switch (message)
-    {
-      case WM_CLOSE:
-        PostQuitMessage(0);
-        return 1;
-
-      default:
-        break;
-    }
-
-    return DefWindowProc(hWnd, message, wParam, lParam);
-}
-
-static const PTCHAR GetTestWindowName()
-{
-    return TEXT("ANGLE_TEST");
-}
-
-bool ANGLETest::InitTestWindow()
-{
-    WNDCLASS sWC;
-    sWC.style = CS_OWNDC;
-    sWC.lpfnWndProc = WndProc;
-    sWC.cbClsExtra = 0;
-    sWC.cbWndExtra = 0;
-    sWC.hInstance = NULL;
-    sWC.hIcon = NULL;
-    sWC.hCursor = LoadCursor(NULL, IDC_ARROW);
-    sWC.lpszMenuName = NULL;
-    sWC.hbrBackground = NULL;
-    sWC.lpszClassName = GetTestWindowName();
-
-    if (!RegisterClass(&sWC))
-    {
-        return false;
-    }
-
-    mNativeWindow = CreateWindow(GetTestWindowName(), NULL, WS_BORDER, 128, 128, 128, 128, NULL, NULL, NULL, NULL);
-
-    SetWindowLong(mNativeWindow, GWL_STYLE, 0);
-    ShowWindow(mNativeWindow, SW_SHOW);
-
-    mNativeDisplay = GetDC(mNativeWindow);
-    if (!mNativeDisplay)
-    {
-        DestroyTestWindow();
-        return false;
-    }
-
-    return true;
-}
-
-bool ANGLETest::DestroyTestWindow()
-{
-    if (mNativeDisplay)
-    {
-        ReleaseDC(mNativeWindow, mNativeDisplay);
-        mNativeDisplay = 0;
-    }
-
-    if (mNativeWindow)
-    {
-        DestroyWindow(mNativeWindow);
-        mNativeWindow = 0;
-    }
-
-    UnregisterClass(GetTestWindowName(), NULL);
-
-    return true;
-}
-
-bool ANGLETest::ReizeWindow(int width, int height)
-{
-    RECT windowRect;
-    if (!GetWindowRect(mNativeWindow, &windowRect))
-    {
-        return false;
-    }
-
-    if (!MoveWindow(mNativeWindow, windowRect.left, windowRect.top, width, height, FALSE))
-    {
-        return false;
-    }
-
-    return true;
-}
diff --git a/tests/compiler_tests/CollectVariables_test.cpp b/tests/compiler_tests/CollectVariables_test.cpp
index 21ad75f..0c3160e 100644
--- a/tests/compiler_tests/CollectVariables_test.cpp
+++ b/tests/compiler_tests/CollectVariables_test.cpp
@@ -164,6 +164,175 @@
     EXPECT_TRUE(field.staticUse);
     EXPECT_GLENUM_EQ(GL_FLOAT, field.type);
     EXPECT_EQ("f", field.name);
-    EXPECT_FALSE(field.isRowMajorMatrix);
+    EXPECT_FALSE(field.isRowMajorLayout);
     EXPECT_TRUE(field.fields.empty());
 }
+
+TEST_F(CollectVertexVariablesTest, SimpleInstancedInterfaceBlock)
+{
+    const std::string &shaderString =
+        "#version 300 es\n"
+        "uniform b {\n"
+        "  float f;\n"
+        "} blockInstance;"
+        "void main() {\n"
+        "   gl_Position = vec4(blockInstance.f, 0.0, 0.0, 1.0);\n"
+        "}\n";
+
+    const char *shaderStrings[] = { shaderString.c_str() };
+    ASSERT_TRUE(mTranslator->compile(shaderStrings, 1, SH_VARIABLES));
+
+    const std::vector<sh::InterfaceBlock> &interfaceBlocks = mTranslator->getInterfaceBlocks();
+    ASSERT_EQ(1u, interfaceBlocks.size());
+
+    const sh::InterfaceBlock &interfaceBlock = interfaceBlocks[0];
+
+    EXPECT_EQ(0u, interfaceBlock.arraySize);
+    EXPECT_FALSE(interfaceBlock.isRowMajorLayout);
+    EXPECT_EQ(sh::BLOCKLAYOUT_SHARED, interfaceBlock.layout);
+    EXPECT_EQ("b", interfaceBlock.name);
+    EXPECT_TRUE(interfaceBlock.staticUse);
+
+    ASSERT_EQ(1u, interfaceBlock.fields.size());
+
+    const sh::InterfaceBlockField &field = interfaceBlock.fields[0];
+
+    EXPECT_GLENUM_EQ(GL_HIGH_FLOAT, field.precision);
+    EXPECT_TRUE(field.staticUse);
+    EXPECT_GLENUM_EQ(GL_FLOAT, field.type);
+    EXPECT_EQ("b.f", field.name);
+    EXPECT_FALSE(field.isRowMajorLayout);
+    EXPECT_TRUE(field.fields.empty());
+}
+
+TEST_F(CollectVertexVariablesTest, StructInterfaceBlock)
+{
+    const std::string &shaderString =
+        "#version 300 es\n"
+        "struct st { float f; };"
+        "uniform b {\n"
+        "  st s;\n"
+        "};"
+        "void main() {\n"
+        "   gl_Position = vec4(s.f, 0.0, 0.0, 1.0);\n"
+        "}\n";
+
+    const char *shaderStrings[] = { shaderString.c_str() };
+    ASSERT_TRUE(mTranslator->compile(shaderStrings, 1, SH_VARIABLES));
+
+    const std::vector<sh::InterfaceBlock> &interfaceBlocks = mTranslator->getInterfaceBlocks();
+    ASSERT_EQ(1u, interfaceBlocks.size());
+
+    const sh::InterfaceBlock &interfaceBlock = interfaceBlocks[0];
+
+    EXPECT_EQ(0u, interfaceBlock.arraySize);
+    EXPECT_FALSE(interfaceBlock.isRowMajorLayout);
+    EXPECT_EQ(sh::BLOCKLAYOUT_SHARED, interfaceBlock.layout);
+    EXPECT_EQ("b", interfaceBlock.name);
+    EXPECT_TRUE(interfaceBlock.staticUse);
+
+    ASSERT_EQ(1u, interfaceBlock.fields.size());
+
+    const sh::InterfaceBlockField &field = interfaceBlock.fields[0];
+
+    EXPECT_TRUE(field.isStruct());
+    EXPECT_TRUE(field.staticUse);
+    EXPECT_EQ("s", field.name);
+    EXPECT_FALSE(field.isRowMajorLayout);
+
+    const sh::ShaderVariable &member = field.fields[0];
+
+    // NOTE: we don't currently mark struct members as statically used or not
+    EXPECT_FALSE(member.isStruct());
+    EXPECT_EQ("f", member.name);
+    EXPECT_GLENUM_EQ(GL_FLOAT, member.type);
+    EXPECT_GLENUM_EQ(GL_HIGH_FLOAT, member.precision);
+}
+
+TEST_F(CollectVertexVariablesTest, StructInstancedInterfaceBlock)
+{
+    const std::string &shaderString =
+        "#version 300 es\n"
+        "struct st { float f; };"
+        "uniform b {\n"
+        "  st s;\n"
+        "} instanceName;"
+        "void main() {\n"
+        "   gl_Position = vec4(instanceName.s.f, 0.0, 0.0, 1.0);\n"
+        "}\n";
+
+    const char *shaderStrings[] = { shaderString.c_str() };
+    ASSERT_TRUE(mTranslator->compile(shaderStrings, 1, SH_VARIABLES));
+
+    const std::vector<sh::InterfaceBlock> &interfaceBlocks = mTranslator->getInterfaceBlocks();
+    ASSERT_EQ(1u, interfaceBlocks.size());
+
+    const sh::InterfaceBlock &interfaceBlock = interfaceBlocks[0];
+
+    EXPECT_EQ(0u, interfaceBlock.arraySize);
+    EXPECT_FALSE(interfaceBlock.isRowMajorLayout);
+    EXPECT_EQ(sh::BLOCKLAYOUT_SHARED, interfaceBlock.layout);
+    EXPECT_EQ("b", interfaceBlock.name);
+    EXPECT_TRUE(interfaceBlock.staticUse);
+
+    ASSERT_EQ(1u, interfaceBlock.fields.size());
+
+    const sh::InterfaceBlockField &field = interfaceBlock.fields[0];
+
+    EXPECT_TRUE(field.isStruct());
+    EXPECT_TRUE(field.staticUse);
+    EXPECT_EQ("b.s", field.name);
+    EXPECT_FALSE(field.isRowMajorLayout);
+
+    const sh::ShaderVariable &member = field.fields[0];
+
+    // NOTE: we don't currently mark struct members as statically used or not
+    EXPECT_FALSE(member.isStruct());
+    EXPECT_EQ("f", member.name);
+    EXPECT_GLENUM_EQ(GL_FLOAT, member.type);
+    EXPECT_GLENUM_EQ(GL_HIGH_FLOAT, member.precision);
+}
+
+TEST_F(CollectVertexVariablesTest, NestedStructRowMajorInterfaceBlock)
+{
+    const std::string &shaderString =
+        "#version 300 es\n"
+        "struct st { mat2 m; };"
+        "layout(row_major) uniform b {\n"
+        "  st s;\n"
+        "};"
+        "void main() {\n"
+        "   gl_Position = vec4(s.m);\n"
+        "}\n";
+
+    const char *shaderStrings[] = { shaderString.c_str() };
+    ASSERT_TRUE(mTranslator->compile(shaderStrings, 1, SH_VARIABLES));
+
+    const std::vector<sh::InterfaceBlock> &interfaceBlocks = mTranslator->getInterfaceBlocks();
+    ASSERT_EQ(1u, interfaceBlocks.size());
+
+    const sh::InterfaceBlock &interfaceBlock = interfaceBlocks[0];
+
+    EXPECT_EQ(0u, interfaceBlock.arraySize);
+    EXPECT_TRUE(interfaceBlock.isRowMajorLayout);
+    EXPECT_EQ(sh::BLOCKLAYOUT_SHARED, interfaceBlock.layout);
+    EXPECT_EQ("b", interfaceBlock.name);
+    EXPECT_TRUE(interfaceBlock.staticUse);
+
+    ASSERT_EQ(1u, interfaceBlock.fields.size());
+
+    const sh::InterfaceBlockField &field = interfaceBlock.fields[0];
+
+    EXPECT_TRUE(field.isStruct());
+    EXPECT_TRUE(field.staticUse);
+    EXPECT_EQ("s", field.name);
+    EXPECT_TRUE(field.isRowMajorLayout);
+
+    const sh::ShaderVariable &member = field.fields[0];
+
+    // NOTE: we don't currently mark struct members as statically used or not
+    EXPECT_FALSE(member.isStruct());
+    EXPECT_EQ("m", member.name);
+    EXPECT_GLENUM_EQ(GL_FLOAT_MAT2, member.type);
+    EXPECT_GLENUM_EQ(GL_HIGH_FLOAT, member.precision);
+}
diff --git a/tests/compiler_tests/ExpressionLimit_test.cpp b/tests/compiler_tests/ExpressionLimit_test.cpp
index 4e804dd..0236064 100644
--- a/tests/compiler_tests/ExpressionLimit_test.cpp
+++ b/tests/compiler_tests/ExpressionLimit_test.cpp
@@ -201,6 +201,7 @@
         GenerateShaderWithLongExpression(
             kMaxExpressionComplexity + 10).c_str(),
         compileOptions & ~SH_LIMIT_EXPRESSION_COMPLEXITY, NULL));
+    ShDestruct(vertexCompiler);
 }
 
 TEST_F(ExpressionLimitTest, UnusedExpressionComplexity)
@@ -229,6 +230,7 @@
         GenerateShaderWithUnusedLongExpression(
             kMaxExpressionComplexity + 10).c_str(),
         compileOptions & ~SH_LIMIT_EXPRESSION_COMPLEXITY, NULL));
+    ShDestruct(vertexCompiler);
 }
 
 TEST_F(ExpressionLimitTest, CallStackDepth)
@@ -257,6 +259,7 @@
         GenerateShaderWithDeepFunctionStack(
             kMaxCallStackDepth + 10).c_str(),
         compileOptions & ~SH_LIMIT_CALL_STACK_DEPTH, NULL));
+    ShDestruct(vertexCompiler);
 }
 
 TEST_F(ExpressionLimitTest, UnusedCallStackDepth)
@@ -285,6 +288,7 @@
         GenerateShaderWithUnusedDeepFunctionStack(
             kMaxCallStackDepth + 10).c_str(),
         compileOptions & ~SH_LIMIT_CALL_STACK_DEPTH, NULL));
+    ShDestruct(vertexCompiler);
 }
 
 TEST_F(ExpressionLimitTest, Recursion)
@@ -502,5 +506,6 @@
     EXPECT_TRUE(CheckShaderCompilation(
         vertexCompiler, shaderWithNoRecursion,
         compileOptions | SH_LIMIT_CALL_STACK_DEPTH, NULL));
+    ShDestruct(vertexCompiler);
 }
 
diff --git a/tests/perf_tests/BufferSubData.cpp b/tests/perf_tests/BufferSubData.cpp
new file mode 100644
index 0000000..01c9a67
--- /dev/null
+++ b/tests/perf_tests/BufferSubData.cpp
@@ -0,0 +1,291 @@
+//
+// 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 "BufferSubData.h"
+
+#include <cassert>
+#include <sstream>
+
+#include "shader_utils.h"
+
+namespace
+{
+
+GLfloat *GetFloatData(GLint componentCount)
+{
+    static GLfloat vertices2[] =
+    {
+        1, 2,
+        0, 0,
+        2, 0,
+    };
+
+    static GLfloat vertices3[] =
+    {
+        1, 2, 1,
+        0, 0, 1,
+        2, 0, 1,
+    };
+
+    static GLfloat vertices4[] =
+    {
+        1, 2, 1, 3,
+        0, 0, 1, 3,
+        2, 0, 1, 3,
+    };
+
+    switch (componentCount)
+    {
+      case 2: return vertices2;
+      case 3: return vertices3;
+      case 4: return vertices4;
+      default: return NULL;
+    }
+}
+
+template <class T>
+GLsizeiptr GetNormalizedData(GLsizeiptr numElements, GLfloat *floatData, std::vector<uint8_t> *data)
+{
+    GLsizeiptr triDataSize = sizeof(T) * numElements;
+    data->resize(triDataSize);
+
+    T *destPtr = reinterpret_cast<T*>(data->data());
+
+    for (GLsizeiptr dataIndex = 0; dataIndex < numElements; dataIndex++)
+    {
+        GLfloat scaled = floatData[dataIndex] * 0.25f;
+        destPtr[dataIndex] = static_cast<T>(scaled * static_cast<GLfloat>(std::numeric_limits<T>::max()));
+    }
+
+    return triDataSize;
+}
+
+template <class T>
+GLsizeiptr GetIntData(GLsizeiptr numElements, GLfloat *floatData, std::vector<uint8_t> *data)
+{
+    GLsizeiptr triDataSize = sizeof(T) * numElements;
+    data->resize(triDataSize);
+
+    T *destPtr = reinterpret_cast<T*>(data->data());
+
+    for (GLsizeiptr dataIndex = 0; dataIndex < numElements; dataIndex++)
+    {
+        destPtr[dataIndex] = static_cast<T>(floatData[dataIndex]);
+    }
+
+    return triDataSize;
+}
+
+GLsizeiptr GetVertexData(GLenum type, GLint componentCount, GLboolean normalized, std::vector<uint8_t> *data)
+{
+    GLsizeiptr triDataSize = 0;
+    GLfloat *floatData = GetFloatData(componentCount);
+
+    if (type == GL_FLOAT)
+    {
+        triDataSize = sizeof(GLfloat) * componentCount * 3;
+        data->resize(triDataSize);
+        memcpy(data->data(), floatData, triDataSize);
+    }
+    else if (normalized == GL_TRUE)
+    {
+        GLsizeiptr numElements = componentCount * 3;
+
+        switch (type)
+        {
+          case GL_BYTE:           triDataSize = GetNormalizedData<GLbyte>(numElements, floatData, data); break;
+          case GL_SHORT:          triDataSize = GetNormalizedData<GLshort>(numElements, floatData, data); break;
+          case GL_INT:            triDataSize = GetNormalizedData<GLint>(numElements, floatData, data); break;
+          case GL_UNSIGNED_BYTE:  triDataSize = GetNormalizedData<GLubyte>(numElements, floatData, data); break;
+          case GL_UNSIGNED_SHORT: triDataSize = GetNormalizedData<GLushort>(numElements, floatData, data); break;
+          case GL_UNSIGNED_INT:   triDataSize = GetNormalizedData<GLuint>(numElements, floatData, data); break;
+          default: assert(0);
+        }
+    }
+    else
+    {
+        GLsizeiptr numElements = componentCount * 3;
+
+        switch (type)
+        {
+          case GL_BYTE:           triDataSize = GetIntData<GLbyte>(numElements, floatData, data); break;
+          case GL_SHORT:          triDataSize = GetIntData<GLshort>(numElements, floatData, data); break;
+          case GL_INT:            triDataSize = GetIntData<GLint>(numElements, floatData, data); break;
+          case GL_UNSIGNED_BYTE:  triDataSize = GetIntData<GLubyte>(numElements, floatData, data); break;
+          case GL_UNSIGNED_SHORT: triDataSize = GetIntData<GLushort>(numElements, floatData, data); break;
+          case GL_UNSIGNED_INT:   triDataSize = GetIntData<GLuint>(numElements, floatData, data); break;
+          default: assert(0);
+        }
+    }
+
+    return triDataSize;
+}
+
+}
+
+std::string BufferSubDataParams::name() const
+{
+    std::stringstream strstr;
+
+    strstr << "BufferSubData - " << BenchmarkParams::name() << " - ";
+
+    if (vertexNormalized)
+    {
+        strstr << "Norm";
+    }
+
+    switch (vertexType)
+    {
+      case GL_FLOAT: strstr << "Float"; break;
+      case GL_INT: strstr << "Int"; break;
+      case GL_BYTE: strstr << "Byte"; break;
+      case GL_SHORT: strstr << "Short"; break;
+      case GL_UNSIGNED_INT: strstr << "UInt"; break;
+      case GL_UNSIGNED_BYTE: strstr << "UByte"; break;
+      case GL_UNSIGNED_SHORT: strstr << "UShort"; break;
+      default: strstr << "UNKNOWN FORMAT (" << vertexType << ")"; break;
+    }
+
+    strstr << vertexComponentCount;
+
+    strstr << " - " << updateSize << "b updates (per " << updatesEveryNFrames << ") - ";
+    strstr << (bufferSize >> 10) << "k buffer - ";
+    strstr << iterations << " updates";
+
+    return strstr.str();
+}
+
+BufferSubDataBenchmark::BufferSubDataBenchmark(const BufferSubDataParams &params)
+    : SimpleBenchmark(params.name(), 1280, 720, 2, params.requestedRenderer),
+      mProgram(0),
+      mBuffer(0),
+      mUpdateData(NULL),
+      mNumTris(0),
+      mParams(params)
+{
+    mDrawIterations = mParams.iterations;
+
+    assert(mParams.vertexComponentCount > 1);
+    assert(mParams.iterations > 0);
+}
+
+bool BufferSubDataBenchmark::initializeBenchmark()
+{
+    const std::string vs = SHADER_SOURCE
+    (
+        attribute vec2 vPosition;
+        uniform float uScale;
+        uniform float uOffset;
+        void main()
+        {
+            gl_Position = vec4(vPosition * vec2(uScale) - vec2(uOffset), 0, 1);
+        }
+    );
+
+    const std::string fs = SHADER_SOURCE
+    (
+        precision mediump float;
+        void main()
+        {
+            gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0);
+        }
+    );
+
+    mProgram = CompileProgram(vs, fs);
+    if (!mProgram)
+    {
+        return false;
+    }
+
+    // Use the program object
+    glUseProgram(mProgram);
+
+    glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
+
+
+    std::vector<uint8_t> zeroData(mParams.bufferSize);
+    memset(zeroData.data(), 0, zeroData.size());
+
+    glGenBuffers(1, &mBuffer);
+    glBindBuffer(GL_ARRAY_BUFFER, mBuffer);
+    glBufferData(GL_ARRAY_BUFFER, mParams.bufferSize, zeroData.data(), GL_DYNAMIC_DRAW);
+
+    glVertexAttribPointer(0, mParams.vertexComponentCount, mParams.vertexType,
+                          mParams.vertexNormalized, 0, 0);
+    glEnableVertexAttribArray(0);
+
+    if (mParams.updateSize > 0)
+    {
+        mUpdateData = new uint8_t[mParams.updateSize];
+    }
+
+    std::vector<uint8_t> data;
+    GLsizei triDataSize = GetVertexData(mParams.vertexType,
+                                        mParams.vertexComponentCount,
+                                        mParams.vertexNormalized, &data);
+
+    mNumTris = mParams.updateSize / triDataSize;
+    for (int i = 0, offset = 0; i < mNumTris; ++i)
+    {
+        memcpy(mUpdateData + offset, data.data(), triDataSize);
+        offset += triDataSize;
+    }
+
+    if (mParams.updateSize == 0)
+    {
+        mNumTris = 1;
+        glBufferSubData(GL_ARRAY_BUFFER, 0, data.size(), data.data());
+    }
+
+    // Set the viewport
+    glViewport(0, 0, getWindow()->getWidth(), getWindow()->getHeight());
+
+    GLfloat scale = 0.5f;
+    GLfloat offset = 0.5f;
+
+    if (mParams.vertexNormalized == GL_TRUE)
+    {
+        scale = 2.0f;
+        offset = 0.5f;
+    }
+
+    glUniform1f(glGetUniformLocation(mProgram, "uScale"), scale);
+    glUniform1f(glGetUniformLocation(mProgram, "uOffset"), offset);
+
+    GLenum glErr = glGetError();
+    if (glErr != GL_NO_ERROR)
+    {
+        return false;
+    }
+
+    return true;
+}
+
+void BufferSubDataBenchmark::destroyBenchmark()
+{
+    glDeleteProgram(mProgram);
+    glDeleteBuffers(1, &mBuffer);
+    delete[] mUpdateData;
+}
+
+void BufferSubDataBenchmark::beginDrawBenchmark()
+{
+    // Clear the color buffer
+    glClear(GL_COLOR_BUFFER_BIT);
+}
+
+void BufferSubDataBenchmark::drawBenchmark()
+{
+    for (unsigned int it = 0; it < mParams.iterations; it++)
+    {
+        if (mParams.updateSize > 0 && ((mNumFrames % mParams.updatesEveryNFrames) == 0))
+        {
+            glBufferSubData(GL_ARRAY_BUFFER, 0, mParams.updateSize, mUpdateData);
+        }
+
+        glDrawArrays(GL_TRIANGLES, 0, 3 * mNumTris);
+    }
+}
diff --git a/tests/perf_tests/BufferSubData.h b/tests/perf_tests/BufferSubData.h
new file mode 100644
index 0000000..6a55fac
--- /dev/null
+++ b/tests/perf_tests/BufferSubData.h
@@ -0,0 +1,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.
+//
+
+#include "SimpleBenchmark.h"
+
+struct BufferSubDataParams : public BenchmarkParams
+{
+    EGLint requestedRenderer;
+    GLenum vertexType;
+    GLint vertexComponentCount;
+    GLboolean vertexNormalized;
+    GLsizeiptr updateSize;
+    GLsizeiptr bufferSize;
+    unsigned int iterations;
+    unsigned int updatesEveryNFrames;
+
+    virtual std::string name() const;
+};
+
+class BufferSubDataBenchmark : public SimpleBenchmark
+{
+  public:
+    BufferSubDataBenchmark(const BufferSubDataParams &params);
+
+    virtual bool initializeBenchmark();
+    virtual void destroyBenchmark();
+    virtual void beginDrawBenchmark();
+    virtual void drawBenchmark();
+
+  private:
+    DISALLOW_COPY_AND_ASSIGN(BufferSubDataBenchmark);
+
+    GLuint mProgram;
+    GLuint mBuffer;
+    uint8_t *mUpdateData;
+    int mNumTris;
+
+    const BufferSubDataParams mParams;
+};
+
diff --git a/tests/perf_tests/SimpleBenchmark.cpp b/tests/perf_tests/SimpleBenchmark.cpp
new file mode 100644
index 0000000..b1e83a3
--- /dev/null
+++ b/tests/perf_tests/SimpleBenchmark.cpp
@@ -0,0 +1,133 @@
+//
+// 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 "SimpleBenchmark.h"
+#include <iostream>
+
+SimpleBenchmark::SimpleBenchmark(const std::string &name, size_t width, size_t height, EGLint glesMajorVersion, EGLint requestedRenderer)
+    : mNumFrames(0),
+      mName(name),
+      mRunning(false),
+      mDrawIterations(10),
+      mRunTimeSeconds(5.0)
+{
+    mOSWindow.reset(CreateOSWindow());
+    mEGLWindow.reset(new EGLWindow(width, height, glesMajorVersion, requestedRenderer));
+    mTimer.reset(CreateTimer());
+}
+
+bool SimpleBenchmark::initialize()
+{
+    std::cout << "========= " << mName << " =========" << std::endl;
+    return initializeBenchmark();
+}
+
+void SimpleBenchmark::destroy()
+{
+    double totalTime = mTimer->getElapsedTime();
+    std::cout << " - total time: " << totalTime << " sec" << std::endl;
+    std::cout << " - frames: " << mNumFrames << std::endl;
+    std::cout << " - average frame time: " << 1000.0 * totalTime / mNumFrames << " msec" << std::endl;
+    std::cout << "=========" << std::endl << std::endl;
+
+    destroyBenchmark();
+}
+
+void SimpleBenchmark::step(float dt, double totalTime)
+{
+    stepBenchmark(dt, totalTime);
+}
+
+void SimpleBenchmark::draw()
+{
+    if (mTimer->getElapsedTime() > mRunTimeSeconds) {
+        mRunning = false;
+        return;
+    }
+
+    ++mNumFrames;
+
+    beginDrawBenchmark();
+
+    for (unsigned int iteration = 0; iteration < mDrawIterations; ++iteration)
+    {
+        drawBenchmark();
+    }
+
+    endDrawBenchmark();
+}
+
+int SimpleBenchmark::run()
+{
+    if (!mOSWindow->initialize(mName, mEGLWindow->getWidth(), mEGLWindow->getHeight()))
+    {
+        return -1;
+    }
+
+    if (!mEGLWindow->initializeGL(mOSWindow.get()))
+    {
+        return -1;
+    }
+
+    mRunning = true;
+    int result = 0;
+
+    if (!initialize())
+    {
+        mRunning = false;
+        result = -1;
+    }
+
+    mTimer->start();
+    double prevTime = 0.0;
+
+    while (mRunning)
+    {
+        double elapsedTime = mTimer->getElapsedTime();
+        double deltaTime = elapsedTime - prevTime;
+
+        step(static_cast<float>(deltaTime), elapsedTime);
+
+        // Clear events that the application did not process from this frame
+        Event event;
+        while (popEvent(&event))
+        {
+            // If the application did not catch a close event, close now
+            if (event.Type == Event::EVENT_CLOSED)
+            {
+                mRunning = false;
+            }
+        }
+
+        if (!mRunning)
+        {
+            break;
+        }
+
+        draw();
+        mEGLWindow->swap();
+
+        mOSWindow->messageLoop();
+
+        prevTime = elapsedTime;
+    }
+
+    destroy();
+    mEGLWindow->destroyGL();
+    mOSWindow->destroy();
+
+    return result;
+}
+
+bool SimpleBenchmark::popEvent(Event *event)
+{
+    return mOSWindow->popEvent(event);
+}
+
+OSWindow *SimpleBenchmark::getWindow()
+{
+    return mOSWindow.get();
+}
\ No newline at end of file
diff --git a/tests/perf_tests/SimpleBenchmark.h b/tests/perf_tests/SimpleBenchmark.h
new file mode 100644
index 0000000..b20b18a
--- /dev/null
+++ b/tests/perf_tests/SimpleBenchmark.h
@@ -0,0 +1,100 @@
+//
+// 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.
+//
+
+#ifndef SAMPLE_UTIL_SIMPLE_BENCHMARK_H
+#define SAMPLE_UTIL_SIMPLE_BENCHMARK_H
+
+#include <memory>
+#include <vector>
+#include <EGL/egl.h>
+#include <EGL/eglext.h>
+#include <string>
+
+#include "shared_utils.h"
+
+#include "OSWindow.h"
+#include "EGLWindow.h"
+#include "Timer.h"
+
+class Event;
+
+class SimpleBenchmark
+{
+  public:
+    SimpleBenchmark(const std::string &name, size_t width, size_t height,
+                    EGLint glesMajorVersion = 2,
+                    EGLint requestedRenderer = EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE);
+
+    virtual ~SimpleBenchmark() { };
+
+    virtual bool initializeBenchmark() { return true; }
+    virtual void destroyBenchmark() { }
+
+    virtual void stepBenchmark(float dt, double totalTime) { }
+
+    virtual void beginDrawBenchmark() { }
+    virtual void drawBenchmark() = 0;
+    virtual void endDrawBenchmark() { }
+
+    int run();
+    bool popEvent(Event *event);
+
+    OSWindow *getWindow();
+
+  protected:
+    unsigned int mDrawIterations;
+    double mRunTimeSeconds;
+    int mNumFrames;
+
+  private:
+    DISALLOW_COPY_AND_ASSIGN(SimpleBenchmark);
+
+    bool initialize();
+    void destroy();
+
+    void step(float dt, double totalTime);
+    void draw();
+
+    std::string mName;
+    bool mRunning;
+
+    std::unique_ptr<EGLWindow> mEGLWindow;
+    std::unique_ptr<OSWindow> mOSWindow;
+    std::unique_ptr<Timer> mTimer;
+};
+
+// Base class
+struct BenchmarkParams
+{
+    EGLint requestedRenderer;
+
+    virtual std::string name() const
+    {
+        switch (requestedRenderer)
+        {
+          case EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE: return "D3D11";
+          case EGL_PLATFORM_ANGLE_TYPE_D3D9_ANGLE: return "D3D9";
+          default: return "Unknown Renderer";
+        }
+    }
+};
+
+template <typename BenchmarkT, typename ParamsT>
+inline int RunBenchmarks(const std::vector<ParamsT> &benchmarks)
+{
+    int result;
+
+    for (size_t benchIndex = 0; benchIndex < benchmarks.size(); benchIndex++)
+    {
+        BenchmarkT benchmark(benchmarks[benchIndex]);
+        result = benchmark.run();
+        if (result != 0) { return result; }
+    }
+
+    return 0;
+}
+
+#endif // SAMPLE_UTIL_SIMPLE_BENCHMARK_H
diff --git a/tests/perf_tests/SimpleBenchmarks.cpp b/tests/perf_tests/SimpleBenchmarks.cpp
new file mode 100644
index 0000000..e598674
--- /dev/null
+++ b/tests/perf_tests/SimpleBenchmarks.cpp
@@ -0,0 +1,103 @@
+//
+// 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 "SimpleBenchmark.h"
+#include "BufferSubData.h"
+#include "TexSubImage.h"
+
+EGLint platforms[] =
+{
+    EGL_PLATFORM_ANGLE_TYPE_D3D9_ANGLE,
+    EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE
+};
+
+GLenum vertexTypes[] = { GL_FLOAT };
+GLint componentCounts[] = { 4 };
+GLboolean vertexNorms[] = { GL_FALSE };
+GLsizeiptr updateSizes[] = { 0, 300 };
+GLsizeiptr bufferSizes[] = { 1024 * 1024 };
+unsigned int iterationCounts[] = { 10 };
+unsigned int updatesEveryNFrames[] = { 1, 4 };
+
+int main(int argc, char **argv)
+{
+    std::vector<BufferSubDataParams> subDataParams;
+
+    for (size_t platIt = 0; platIt < ArraySize(platforms); platIt++)
+    {
+        for (size_t typeIt = 0; typeIt < ArraySize(vertexTypes); typeIt++)
+        {
+            for (size_t compIt = 0; compIt < ArraySize(componentCounts); compIt++)
+            {
+                for (size_t normIt = 0; normIt < ArraySize(vertexNorms); normIt++)
+                {
+                    // No normalized float data
+                    if (vertexTypes[typeIt] == GL_FLOAT && vertexNorms[normIt] == GL_TRUE)
+                    {
+                        continue;
+                    }
+
+                    for (size_t updateIt = 0; updateIt < ArraySize(updateSizes); updateIt++)
+                    {
+                        for (size_t bufszIt = 0; bufszIt < ArraySize(bufferSizes); bufszIt++)
+                        {
+                            for (size_t itIt = 0; itIt < ArraySize(iterationCounts); itIt++)
+                            {
+                                for (size_t nfrIt = 0; nfrIt < ArraySize(updatesEveryNFrames); nfrIt++)
+                                {
+                                    BufferSubDataParams params;
+                                    params.requestedRenderer = platforms[platIt];
+                                    params.vertexType = vertexTypes[typeIt];
+                                    params.vertexComponentCount = componentCounts[compIt];
+                                    params.vertexNormalized = vertexNorms[normIt];
+                                    params.updateSize = updateSizes[updateIt];
+                                    params.bufferSize = bufferSizes[bufszIt];
+                                    params.iterations = iterationCounts[itIt];
+                                    params.updatesEveryNFrames = updatesEveryNFrames[nfrIt];
+
+                                    if (updateSizes[updateIt] == 0)
+                                    {
+                                        if (nfrIt > 0)
+                                        {
+                                            continue;
+                                        }
+                                        else
+                                        {
+                                            params.updatesEveryNFrames = 1;
+                                        }
+                                    }
+
+                                    subDataParams.push_back(params);
+                                }
+                            }
+                        }
+                    }
+                }
+            }
+        }
+    }
+
+    // Enumerates permutations
+    RunBenchmarks<BufferSubDataBenchmark>(subDataParams);
+
+    std::vector<TexSubImageParams> subImageParams;
+
+    for (size_t platIt = 0; platIt < ArraySize(platforms); platIt++)
+    {
+        TexSubImageParams params;
+
+        params.requestedRenderer = platforms[platIt];
+        params.imageWidth = 1024;
+        params.imageHeight = 1024;
+        params.subImageHeight = 64;
+        params.subImageWidth = 64;
+        params.iterations = 10;
+
+        subImageParams.push_back(params);
+    }
+
+    RunBenchmarks<TexSubImageBenchmark>(subImageParams);
+}
diff --git a/tests/perf_tests/TexSubImage.cpp b/tests/perf_tests/TexSubImage.cpp
new file mode 100644
index 0000000..0751f1f
--- /dev/null
+++ b/tests/perf_tests/TexSubImage.cpp
@@ -0,0 +1,194 @@
+//
+// 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 "TexSubImage.h"
+
+#include <sstream>
+#include <cassert>
+
+#include "shader_utils.h"
+
+std::string TexSubImageParams::name() const
+{
+    std::stringstream strstr;
+
+    strstr << "TexSubImage - " << BenchmarkParams::name()
+           << " - " << imageWidth << "x" << imageHeight
+           << " - " << subImageWidth << "x" << subImageHeight << " updates";
+
+    return strstr.str();
+}
+
+TexSubImageBenchmark::TexSubImageBenchmark(const TexSubImageParams &params)
+    : SimpleBenchmark(params.name(), 512, 512, 2, params.requestedRenderer),
+      mParams(params),
+      mProgram(0),
+      mPositionLoc(-1),
+      mTexCoordLoc(-1),
+      mSamplerLoc(-1),
+      mTexture(0),
+      mVertexBuffer(0),
+      mIndexBuffer(0),
+      mPixels(NULL)
+{
+    assert(mParams.iterations > 0);
+    mDrawIterations = mParams.iterations;
+}
+
+GLuint TexSubImageBenchmark::createTexture()
+{
+    // Use tightly packed data
+    glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
+
+    // Generate a texture object
+    GLuint texture;
+    glGenTextures(1, &texture);
+
+    // Bind the texture object
+    glBindTexture(GL_TEXTURE_2D, texture);
+
+    glTexStorage2DEXT(GL_TEXTURE_2D, 1, GL_RGBA8, mParams.imageWidth, mParams.imageHeight);
+
+    // Set the filtering mode
+    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+
+    return texture;
+}
+
+bool TexSubImageBenchmark::initializeBenchmark()
+{
+    const std::string vs = SHADER_SOURCE
+    (
+        attribute vec4 a_position;
+        attribute vec2 a_texCoord;
+        varying vec2 v_texCoord;
+        void main()
+        {
+            gl_Position = a_position;
+            v_texCoord = a_texCoord;
+        }
+    );
+
+    const std::string fs = SHADER_SOURCE
+    (
+        precision mediump float;
+        varying vec2 v_texCoord;
+        uniform sampler2D s_texture;
+        void main()
+        {
+            gl_FragColor = texture2D(s_texture, v_texCoord);
+        }
+    );
+
+    mProgram = CompileProgram(vs, fs);
+    if (!mProgram)
+    {
+        return false;
+    }
+
+    // Get the attribute locations
+    mPositionLoc = glGetAttribLocation(mProgram, "a_position");
+    mTexCoordLoc = glGetAttribLocation(mProgram, "a_texCoord");
+
+    // Get the sampler location
+    mSamplerLoc = glGetUniformLocation(mProgram, "s_texture");
+
+    // Build the vertex buffer
+    GLfloat vertices[] =
+    {
+        -0.5f, 0.5f, 0.0f,  // Position 0
+        0.0f, 0.0f,        // TexCoord 0
+        -0.5f, -0.5f, 0.0f,  // Position 1
+        0.0f, 1.0f,        // TexCoord 1
+        0.5f, -0.5f, 0.0f,  // Position 2
+        1.0f, 1.0f,        // TexCoord 2
+        0.5f, 0.5f, 0.0f,  // Position 3
+        1.0f, 0.0f         // TexCoord 3
+    };
+
+    glGenBuffers(1, &mVertexBuffer);
+    glBindBuffer(GL_ARRAY_BUFFER, mVertexBuffer);
+    glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
+
+    GLushort indices[] = { 0, 1, 2, 0, 2, 3 };
+    glGenBuffers(1, &mIndexBuffer);
+    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, mIndexBuffer);
+    glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices), indices, GL_STATIC_DRAW);
+
+    // Load the texture
+    mTexture = createTexture();
+
+    glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
+
+    mPixels = new GLubyte[mParams.subImageWidth * mParams.subImageHeight * 4];
+
+    // Fill the pixels structure with random data:
+    for (int y = 0; y < mParams.subImageHeight; ++y)
+    {
+        for (int x = 0; x < mParams.subImageWidth; ++x)
+        {
+            int offset = (x + (y * mParams.subImageWidth)) * 4;
+            mPixels[offset + 0] = rand() % 255; // Red
+            mPixels[offset + 1] = rand() % 255; // Green
+            mPixels[offset + 2] = rand() % 255; // Blue
+            mPixels[offset + 3] = 255; // Alpha
+        }
+    }
+
+    return true;
+}
+
+void TexSubImageBenchmark::destroyBenchmark()
+{
+    glDeleteProgram(mProgram);
+    glDeleteBuffers(1, &mVertexBuffer);
+    glDeleteBuffers(1, &mIndexBuffer);
+    glDeleteTextures(1, &mTexture);
+    delete[] mPixels;
+}
+
+void TexSubImageBenchmark::beginDrawBenchmark()
+{
+    // Set the viewport
+    glViewport(0, 0, getWindow()->getWidth(), getWindow()->getHeight());
+
+    // Clear the color buffer
+    glClear(GL_COLOR_BUFFER_BIT);
+
+    // Use the program object
+    glUseProgram(mProgram);
+
+    // Bind the buffers
+    glBindBuffer(GL_ARRAY_BUFFER, mVertexBuffer);
+    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, mIndexBuffer);
+
+    // Load the vertex position
+    glVertexAttribPointer(mPositionLoc, 3, GL_FLOAT, GL_FALSE, 5 * sizeof(GLfloat), 0);
+    // Load the texture coordinate
+    glVertexAttribPointer(mTexCoordLoc, 2, GL_FLOAT, GL_FALSE, 5 * sizeof(GLfloat), (GLvoid*)(3 * sizeof(GLfloat)));
+
+    glEnableVertexAttribArray(mPositionLoc);
+    glEnableVertexAttribArray(mTexCoordLoc);
+
+    // Bind the texture
+    glActiveTexture(GL_TEXTURE0);
+    glBindTexture(GL_TEXTURE_2D, mTexture);
+
+    // Set the texture sampler to texture unit to 0
+    glUniform1i(mSamplerLoc, 0);
+}
+
+void TexSubImageBenchmark::drawBenchmark()
+{
+    glTexSubImage2D(GL_TEXTURE_2D, 0,
+                    rand() % (mParams.imageWidth - mParams.subImageWidth),
+                    rand() % (mParams.imageHeight - mParams.subImageHeight),
+                    mParams.subImageWidth, mParams.subImageHeight,
+                    GL_RGBA, GL_UNSIGNED_BYTE, mPixels);
+
+    glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_SHORT, 0);
+}
diff --git a/tests/perf_tests/TexSubImage.h b/tests/perf_tests/TexSubImage.h
new file mode 100644
index 0000000..259a81e
--- /dev/null
+++ b/tests/perf_tests/TexSubImage.h
@@ -0,0 +1,53 @@
+//
+// 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 "SimpleBenchmark.h"
+
+struct TexSubImageParams : public BenchmarkParams
+{
+    int imageWidth;
+    int imageHeight;
+    int subImageWidth;
+    int subImageHeight;
+    unsigned int iterations;
+
+    virtual std::string name() const;
+};
+
+class TexSubImageBenchmark : public SimpleBenchmark
+{
+  public:
+    TexSubImageBenchmark(const TexSubImageParams &params);
+
+    virtual bool initializeBenchmark();
+    virtual void destroyBenchmark();
+    virtual void beginDrawBenchmark();
+    virtual void drawBenchmark();
+
+  private:
+    GLuint createTexture();
+
+    TexSubImageParams mParams;
+
+    // Handle to a program object
+    GLuint mProgram;
+
+    // Attribute locations
+    GLint mPositionLoc;
+    GLint mTexCoordLoc;
+
+    // Sampler location
+    GLint mSamplerLoc;
+
+    // Texture handle
+    GLuint mTexture;
+
+    // Buffer handle
+    GLuint mVertexBuffer;
+    GLuint mIndexBuffer;
+
+    GLubyte *mPixels;
+};
diff --git a/tests/preprocessor_tests/char_test.cpp b/tests/preprocessor_tests/char_test.cpp
index 6ea5d80..bd1871d 100644
--- a/tests/preprocessor_tests/char_test.cpp
+++ b/tests/preprocessor_tests/char_test.cpp
@@ -41,7 +41,7 @@
 
 TEST_P(CharTest, Identified)
 {
-    std::string str(1, GetParam());
+    std::string str(1, static_cast<char>(GetParam()));
     const char* cstr = str.c_str();
     int length = 1;
 
diff --git a/tests/preprocessor_tests/identifier_test.cpp b/tests/preprocessor_tests/identifier_test.cpp
index f2653b8..6b8f87e 100644
--- a/tests/preprocessor_tests/identifier_test.cpp
+++ b/tests/preprocessor_tests/identifier_test.cpp
@@ -145,17 +145,17 @@
 TEST_F(IdentifierTest, AllLetters)
 {
     std::string str;
-    for (int c = 'a'; c <= 'z'; ++c)
+    for (char c = 'a'; c <= 'z'; ++c)
         str.push_back(c);
 
     str.push_back('_');
 
-    for (int c = 'A'; c <= 'Z'; ++c)
+    for (char c = 'A'; c <= 'Z'; ++c)
         str.push_back(c);
 
     str.push_back('_');
 
-    for (int c = '0'; c <= '9'; ++c)
+    for (char c = '0'; c <= '9'; ++c)
         str.push_back(c);
 
     expectIdentifier(str);
diff --git a/tests/tests.gyp b/tests/tests.gyp
index 17f8dab..5985c34 100644
--- a/tests/tests.gyp
+++ b/tests/tests.gyp
@@ -113,6 +113,33 @@
                 'compiler_tests/compiler_test_main.cpp',
             ],
         },
+
+        {
+            'target_name': 'angle_implementation_unit_tests',
+            'type': 'executable',
+            'dependencies':
+            [
+                '../src/angle.gyp:libGLESv2_static',
+                'gtest',
+                'gmock',
+            ],
+            'include_dirs':
+            [
+                '../include',
+                '../src',
+                'third_party/googletest/include',
+                'third_party/googlemock/include',
+            ],
+            'includes':
+            [
+                '../build/common_defines.gypi',
+                'angle_implementation_unit_tests/angle_implementation_unit_tests.gypi',
+            ],
+            'sources':
+            [
+                'angle_implementation_unit_tests/angle_implementation_unit_tests_main.cpp',
+            ],
+        },
     ],
 
     'conditions':
@@ -130,6 +157,7 @@
                         '../src/angle.gyp:libGLESv2',
                         '../src/angle.gyp:libEGL',
                         'gtest',
+                        '../util/util.gyp:angle_util',
                     ],
                     'include_dirs':
                     [
@@ -163,6 +191,33 @@
                         '<!@(python <(angle_path)/enumerate_files.py standalone_tests -types *.cpp *.h)'
                     ],
                 },
+                {
+                    'target_name': 'angle_perf_tests',
+                    'type': 'executable',
+                    'includes': [ '../build/common_defines.gypi', ],
+                    'dependencies':
+                    [
+                        '../src/angle.gyp:libGLESv2',
+                        '../src/angle.gyp:libEGL',
+                        'gtest',
+                        '../util/util.gyp:angle_util',
+                    ],
+                    'include_dirs':
+                    [
+                        '../include',
+                        'third_party/googletest/include',
+                    ],
+                    'sources':
+                    [
+                        'perf_tests/BufferSubData.cpp',
+                        'perf_tests/BufferSubData.h',
+                        'perf_tests/SimpleBenchmark.cpp',
+                        'perf_tests/SimpleBenchmark.h',
+                        'perf_tests/SimpleBenchmarks.cpp',
+                        'perf_tests/TexSubImage.cpp',
+                        'perf_tests/TexSubImage.h',
+                    ],
+                },
             ],
             'conditions':
             [
@@ -266,6 +321,14 @@
                             [
                                 'CONFORMANCE_TESTS_TYPE=CONFORMANCE_TESTS_ES3',
                             ],
+                            'msvs_settings':
+                            {
+                                'VCCLCompilerTool':
+                                {
+                                    # MSVS has trouble compiling this due to the obj files becoming too large.
+                                    'AdditionalOptions': [ '/bigobj' ],
+                                },
+                            },
                             'actions':
                             [
                                 {
diff --git a/util/EGLWindow.cpp b/util/EGLWindow.cpp
new file mode 100644
index 0000000..6c5e38f
--- /dev/null
+++ b/util/EGLWindow.cpp
@@ -0,0 +1,199 @@
+//
+// 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.
+//
+
+#include <cassert>
+
+#include "EGLWindow.h"
+#include "OSWindow.h"
+
+#ifdef _WIN32
+#include "win32/Win32Timer.h"
+#include "win32/Win32Window.h"
+#else
+#error unsupported OS.
+#endif
+
+EGLWindow::EGLWindow(size_t width, size_t height,
+                     EGLint glesMajorVersion, EGLint requestedRenderer)
+    : mSurface(EGL_NO_SURFACE),
+      mContext(EGL_NO_CONTEXT),
+      mDisplay(EGL_NO_DISPLAY),
+      mClientVersion(glesMajorVersion),
+      mRequestedRenderer(requestedRenderer),
+      mWidth(width),
+      mHeight(height),
+      mRedBits(-1),
+      mGreenBits(-1),
+      mBlueBits(-1),
+      mAlphaBits(-1),
+      mDepthBits(-1),
+      mStencilBits(-1),
+      mMultisample(false),
+      mSwapInterval(-1)
+{
+}
+
+EGLWindow::~EGLWindow()
+{
+    destroyGL();
+}
+
+void EGLWindow::swap()
+{
+    eglSwapBuffers(mDisplay, mSurface);
+}
+
+EGLConfig EGLWindow::getConfig() const
+{
+    return mConfig;
+}
+
+EGLDisplay EGLWindow::getDisplay() const
+{
+    return mDisplay;
+}
+
+EGLSurface EGLWindow::getSurface() const
+{
+    return mSurface;
+}
+
+EGLContext EGLWindow::getContext() const
+{
+    return mContext;
+}
+
+bool EGLWindow::initializeGL(const OSWindow *osWindow)
+{
+    PFNEGLGETPLATFORMDISPLAYEXTPROC eglGetPlatformDisplayEXT = reinterpret_cast<PFNEGLGETPLATFORMDISPLAYEXTPROC>(eglGetProcAddress("eglGetPlatformDisplayEXT"));
+    if (!eglGetPlatformDisplayEXT)
+    {
+        return false;
+    }
+
+    const EGLint displayAttributes[] =
+    {
+        EGL_PLATFORM_ANGLE_TYPE_ANGLE, mRequestedRenderer,
+        EGL_NONE,
+    };
+
+    mDisplay = eglGetPlatformDisplayEXT(EGL_PLATFORM_ANGLE_ANGLE, osWindow->getNativeDisplay(), displayAttributes);
+    if (mDisplay == EGL_NO_DISPLAY)
+    {
+        destroyGL();
+        return false;
+    }
+
+    EGLint majorVersion, minorVersion;
+    if (!eglInitialize(mDisplay, &majorVersion, &minorVersion))
+    {
+        destroyGL();
+        return false;
+    }
+
+    eglBindAPI(EGL_OPENGL_ES_API);
+    if (eglGetError() != EGL_SUCCESS)
+    {
+        destroyGL();
+        return false;
+    }
+
+    const EGLint configAttributes[] =
+    {
+        EGL_RED_SIZE,       (mRedBits >= 0)     ? mRedBits     : EGL_DONT_CARE,
+        EGL_GREEN_SIZE,     (mGreenBits >= 0)   ? mGreenBits   : EGL_DONT_CARE,
+        EGL_BLUE_SIZE,      (mBlueBits >= 0)    ? mBlueBits    : EGL_DONT_CARE,
+        EGL_ALPHA_SIZE,     (mAlphaBits >= 0)   ? mAlphaBits   : EGL_DONT_CARE,
+        EGL_DEPTH_SIZE,     (mDepthBits >= 0)   ? mDepthBits   : EGL_DONT_CARE,
+        EGL_STENCIL_SIZE,   (mStencilBits >= 0) ? mStencilBits : EGL_DONT_CARE,
+        EGL_SAMPLE_BUFFERS, mMultisample ? 1 : 0,
+        EGL_NONE
+    };
+
+    EGLint configCount;
+    if (!eglChooseConfig(mDisplay, configAttributes, &mConfig, 1, &configCount) || (configCount != 1))
+    {
+        destroyGL();
+        return false;
+    }
+
+    eglGetConfigAttrib(mDisplay, mConfig, EGL_RED_SIZE, &mRedBits);
+    eglGetConfigAttrib(mDisplay, mConfig, EGL_GREEN_SIZE, &mGreenBits);
+    eglGetConfigAttrib(mDisplay, mConfig, EGL_BLUE_SIZE, &mBlueBits);
+    eglGetConfigAttrib(mDisplay, mConfig, EGL_ALPHA_SIZE, &mBlueBits);
+    eglGetConfigAttrib(mDisplay, mConfig, EGL_DEPTH_SIZE, &mDepthBits);
+    eglGetConfigAttrib(mDisplay, mConfig, EGL_STENCIL_SIZE, &mStencilBits);
+
+    const EGLint surfaceAttributes[] =
+    {
+        EGL_POST_SUB_BUFFER_SUPPORTED_NV, EGL_TRUE,
+        EGL_NONE, EGL_NONE,
+    };
+
+    mSurface = eglCreateWindowSurface(mDisplay, mConfig, osWindow->getNativeWindow(), surfaceAttributes);
+    if (mSurface == EGL_NO_SURFACE)
+    {
+        eglGetError(); // Clear error and try again
+        mSurface = eglCreateWindowSurface(mDisplay, mConfig, NULL, NULL);
+    }
+
+    if (eglGetError() != EGL_SUCCESS)
+    {
+        destroyGL();
+        return false;
+    }
+
+    EGLint contextAttibutes[] =
+    {
+        EGL_CONTEXT_CLIENT_VERSION, mClientVersion,
+        EGL_NONE
+    };
+
+    mContext = eglCreateContext(mDisplay, mConfig, NULL, contextAttibutes);
+    if (eglGetError() != EGL_SUCCESS)
+    {
+        destroyGL();
+        return false;
+    }
+
+    eglMakeCurrent(mDisplay, mSurface, mSurface, mContext);
+    if (eglGetError() != EGL_SUCCESS)
+    {
+        destroyGL();
+        return false;
+    }
+
+    if (mSwapInterval != -1)
+    {
+        eglSwapInterval(mDisplay, mSwapInterval);
+    }
+
+    return true;
+}
+
+void EGLWindow::destroyGL()
+{
+    if (mSurface != EGL_NO_SURFACE)
+    {
+        assert(mDisplay != EGL_NO_DISPLAY);
+        eglDestroySurface(mDisplay, mSurface);
+        mSurface = EGL_NO_SURFACE;
+    }
+
+    if (mContext != EGL_NO_CONTEXT)
+    {
+        assert(mDisplay != EGL_NO_DISPLAY);
+        eglDestroyContext(mDisplay, mContext);
+        mContext = EGL_NO_CONTEXT;
+    }
+
+    if (mDisplay != EGL_NO_DISPLAY)
+    {
+        eglMakeCurrent(mDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
+        eglTerminate(mDisplay);
+        mDisplay = EGL_NO_DISPLAY;
+    }
+}
diff --git a/util/EGLWindow.h b/util/EGLWindow.h
new file mode 100644
index 0000000..e97522e
--- /dev/null
+++ b/util/EGLWindow.h
@@ -0,0 +1,92 @@
+//
+// 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.
+//
+
+#ifndef UTIL_EGLWINDOW_H_
+#define UTIL_EGLWINDOW_H_
+
+#define GL_GLEXT_PROTOTYPES
+
+#include <GLES3/gl3.h>
+#include <GLES3/gl3ext.h>
+#include <GLES2/gl2.h>
+#include <GLES2/gl2ext.h>
+#include <EGL/egl.h>
+#include <EGL/eglext.h>
+
+#include <string>
+#include <list>
+#include <cstdint>
+#include <memory>
+
+#include "shared_utils.h"
+
+class OSWindow;
+
+class EGLWindow
+{
+  public:
+    EGLWindow(size_t width, size_t height,
+              EGLint glesMajorVersion = 2,
+              EGLint requestedRenderer = EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE);
+
+    ~EGLWindow();
+
+    void setClientVersion(EGLint glesMajorVersion) { mClientVersion = glesMajorVersion; }
+    void setWidth(size_t width) { mWidth = width; }
+    void setHeight(size_t height) { mHeight = height; }
+    void setConfigRedBits(int bits) { mRedBits = bits; }
+    void setConfigGreenBits(int bits) { mGreenBits = bits; }
+    void setConfigBlueBits(int bits) { mBlueBits = bits; }
+    void setConfigAlphaBits(int bits) { mAlphaBits = bits; }
+    void setConfigDepthBits(int bits) { mDepthBits = bits; }
+    void setConfigStencilBits(int bits) { mStencilBits = bits; }
+    void setMultisample(bool multisample) { mMultisample = multisample; }
+    void setSwapInterval(EGLint swapInterval) { mSwapInterval = swapInterval; }
+
+    void swap();
+
+    GLuint getClientVersion() const { return mClientVersion; }
+    EGLConfig getConfig() const;
+    EGLDisplay getDisplay() const;
+    EGLSurface getSurface() const;
+    EGLContext getContext() const;
+    size_t getWidth() const { return mWidth; }
+    size_t getHeight() const { return mHeight; }
+    int getConfigRedBits() const { return mRedBits; }
+    int getConfigGreenBits() const { return mGreenBits; }
+    int getConfigBlueBits() const { return mBlueBits; }
+    int getConfigAlphaBits() const { return mAlphaBits; }
+    int getConfigDepthBits() const { return mDepthBits; }
+    int getConfigStencilBits() const { return mStencilBits; }
+    bool isMultisample() const { return mMultisample; }
+    EGLint getSwapInterval() const { return mSwapInterval; }
+
+    bool initializeGL(const OSWindow *osWindow);
+    void destroyGL();
+
+  private:
+    DISALLOW_COPY_AND_ASSIGN(EGLWindow);
+
+    EGLConfig mConfig;
+    EGLDisplay mDisplay;
+    EGLSurface mSurface;
+    EGLContext mContext;
+
+    GLuint mClientVersion;
+    EGLint mRequestedRenderer;
+    size_t mWidth;
+    size_t mHeight;
+    int mRedBits;
+    int mGreenBits;
+    int mBlueBits;
+    int mAlphaBits;
+    int mDepthBits;
+    int mStencilBits;
+    bool mMultisample;
+    EGLint mSwapInterval;
+};
+
+#endif // UTIL_EGLWINDOW_H_
diff --git a/samples/angle/sample_util/Event.h b/util/Event.h
similarity index 100%
rename from samples/angle/sample_util/Event.h
rename to util/Event.h
diff --git a/samples/angle/sample_util/Window.cpp b/util/OSWindow.cpp
similarity index 75%
rename from samples/angle/sample_util/Window.cpp
rename to util/OSWindow.cpp
index 2a23176..a637a55 100644
--- a/samples/angle/sample_util/Window.cpp
+++ b/util/OSWindow.cpp
@@ -4,25 +4,28 @@
 // found in the LICENSE file.
 //
 
-#include "Window.h"
+#include "OSWindow.h"
 
-Window::Window()
+OSWindow::OSWindow()
     : mWidth(0),
       mHeight(0)
 {
 }
 
-int Window::getWidth() const
+OSWindow::~OSWindow()
+{}
+
+int OSWindow::getWidth() const
 {
     return mWidth;
 }
 
-int Window::getHeight() const
+int OSWindow::getHeight() const
 {
     return mHeight;
 }
 
-bool Window::popEvent(Event *event)
+bool OSWindow::popEvent(Event *event)
 {
     if (mEvents.size() > 0 && event)
     {
@@ -36,7 +39,7 @@
     }
 }
 
-void Window::pushEvent(Event event)
+void OSWindow::pushEvent(Event event)
 {
     switch (event.Type)
     {
diff --git a/samples/angle/sample_util/Window.h b/util/OSWindow.h
similarity index 77%
rename from samples/angle/sample_util/Window.h
rename to util/OSWindow.h
index d0cdf85..7d25a1e 100644
--- a/samples/angle/sample_util/Window.h
+++ b/util/OSWindow.h
@@ -13,17 +13,17 @@
 #include <EGL/eglext.h>
 #include <list>
 
-class Window
+class OSWindow
 {
   public:
-    Window();
+    OSWindow();
+    virtual ~OSWindow();
 
     virtual bool initialize(const std::string &name, size_t width, size_t height) = 0;
     virtual void destroy() = 0;
 
     int getWidth() const;
     int getHeight() const;
-    virtual void setMousePosition(int x, int y) = 0;
 
     virtual EGLNativeWindowType getNativeWindow() const = 0;
     virtual EGLNativeDisplayType getNativeDisplay() const = 0;
@@ -31,13 +31,19 @@
     virtual void messageLoop() = 0;
 
     bool popEvent(Event *event);
-    void pushEvent(Event event);
+    virtual void pushEvent(Event event);
 
-  private:
+    virtual void setMousePosition(int x, int y) = 0;
+    virtual bool resize(int width, int height) = 0;
+    virtual bool setVisible(bool isVisible) = 0;
+
+  protected:
     int mWidth;
     int mHeight;
 
     std::list<Event> mEvents;
 };
 
+OSWindow *CreateOSWindow();
+
 #endif // SAMPLE_UTIL_WINDOW_H
diff --git a/samples/angle/sample_util/Timer.h b/util/Timer.h
similarity index 94%
rename from samples/angle/sample_util/Timer.h
rename to util/Timer.h
index b86cf85..8e7f4d4 100644
--- a/samples/angle/sample_util/Timer.h
+++ b/util/Timer.h
@@ -15,4 +15,6 @@
     virtual double getElapsedTime() const = 0;
 };
 
+Timer *CreateTimer();
+
 #endif // SAMPLE_UTIL_TIMER_H
diff --git a/samples/angle/sample_util/keyboard.h b/util/keyboard.h
similarity index 100%
rename from samples/angle/sample_util/keyboard.h
rename to util/keyboard.h
diff --git a/samples/angle/sample_util/mouse.h b/util/mouse.h
similarity index 100%
rename from samples/angle/sample_util/mouse.h
rename to util/mouse.h
diff --git a/samples/angle/sample_util/path_utils.h b/util/path_utils.h
similarity index 100%
rename from samples/angle/sample_util/path_utils.h
rename to util/path_utils.h
diff --git a/samples/angle/sample_util/shader_utils.cpp b/util/shader_utils.cpp
similarity index 100%
rename from samples/angle/sample_util/shader_utils.cpp
rename to util/shader_utils.cpp
diff --git a/samples/angle/sample_util/shader_utils.h b/util/shader_utils.h
similarity index 100%
rename from samples/angle/sample_util/shader_utils.h
rename to util/shader_utils.h
diff --git a/util/shared_utils.h b/util/shared_utils.h
new file mode 100644
index 0000000..375aff8
--- /dev/null
+++ b/util/shared_utils.h
@@ -0,0 +1,24 @@
+//
+// 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.
+//
+
+#ifndef UTIL_SHARED_UTILS_H
+#define UTIL_SHARED_UTILS_H
+
+#define SHADER_SOURCE(...) #__VA_ARGS__
+
+// A macro to disallow the copy constructor and operator= functions
+// This must be used in the private: declarations for a class
+#define DISALLOW_COPY_AND_ASSIGN(TypeName) \
+    TypeName(const TypeName&);             \
+    void operator=(const TypeName&)
+
+template <typename T, size_t N>
+inline size_t ArraySize(T(&)[N])
+{
+    return N;
+}
+
+#endif // UTIL_SHARED_UTILS_H
diff --git a/util/util.gyp b/util/util.gyp
new file mode 100644
index 0000000..1bd29ff
--- /dev/null
+++ b/util/util.gyp
@@ -0,0 +1,58 @@
+# 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.
+
+{
+    'conditions':
+    [
+        ['OS=="win"',
+        {
+            'targets':
+            [
+                {
+                    'target_name': 'angle_util',
+                    'type': 'static_library',
+                    'includes': [ '../build/common_defines.gypi', ],
+                    'dependencies':
+                    [
+                        '../src/angle.gyp:libEGL',
+                        '../src/angle.gyp:libGLESv2',
+                    ],
+                    'include_dirs':
+                    [
+                        '../include',
+                        '.',
+                    ],
+                    'sources':
+                    [
+                        'keyboard.h',
+                        'mouse.h',
+                        'path_utils.h',
+                        'shader_utils.cpp',
+                        'shader_utils.h',
+                        'shared_utils.h',
+                        'EGLWindow.cpp',
+                        'EGLWindow.h',
+                        'Event.h',
+                        'OSWindow.cpp',
+                        'OSWindow.h',
+                        'Timer.h',
+                        'win32/Win32_path_utils.cpp',
+                        'win32/Win32Timer.cpp',
+                        'win32/Win32Timer.h',
+                        'win32/Win32Window.cpp',
+                        'win32/Win32Window.h',
+                    ],
+                    'msvs_disabled_warnings': [ 4201 ],
+                    'direct_dependent_settings':
+                    {
+                        'include_dirs':
+                        [
+                            '.',
+                        ],
+                    },
+                },
+            ],
+        }],
+    ],
+}
diff --git a/samples/angle/sample_util/win32/Win32Timer.cpp b/util/win32/Win32Timer.cpp
similarity index 94%
rename from samples/angle/sample_util/win32/Win32Timer.cpp
rename to util/win32/Win32Timer.cpp
index c4345bf..1ace360 100644
--- a/samples/angle/sample_util/win32/Win32Timer.cpp
+++ b/util/win32/Win32Timer.cpp
@@ -51,3 +51,8 @@
 
     return static_cast<double>(endTime - mStartTime) / mFrequency;
 }
+
+Timer *CreateTimer()
+{
+    return new Win32Timer();
+}
diff --git a/samples/angle/sample_util/win32/Win32Timer.h b/util/win32/Win32Timer.h
similarity index 100%
rename from samples/angle/sample_util/win32/Win32Timer.h
rename to util/win32/Win32Timer.h
diff --git a/samples/angle/sample_util/win32/Win32Window.cpp b/util/win32/Win32Window.cpp
similarity index 80%
rename from samples/angle/sample_util/win32/Win32Window.cpp
rename to util/win32/Win32Window.cpp
index 93f6a18..ec5a0c0 100644
--- a/samples/angle/sample_util/win32/Win32Window.cpp
+++ b/util/win32/Win32Window.cpp
@@ -137,7 +137,7 @@
         }
     }
 
-    Window *window = (Window*)(LONG_PTR)GetWindowLongPtr(hWnd, GWLP_USERDATA);
+    OSWindow *window = (OSWindow*)(LONG_PTR)GetWindowLongPtr(hWnd, GWLP_USERDATA);
     if (window)
     {
         switch (message)
@@ -362,8 +362,8 @@
 }
 
 Win32Window::Win32Window()
-    : mClassName(),
-      mNativeWindow(0),
+    : mNativeWindow(0),
+      mParentWindow(0),
       mNativeDisplay(0)
 {
 }
@@ -377,38 +377,55 @@
 {
     destroy();
 
-    mClassName = name;
+    mParentClassName = name;
+    mChildClassName = name + "Child";
 
-    WNDCLASSEXA windowClass = { 0 };
-    windowClass.cbSize = sizeof(WNDCLASSEXA);
-    windowClass.style = CS_OWNDC;
-    windowClass.lpfnWndProc = WndProc;
-    windowClass.cbClsExtra = 0;
-    windowClass.cbWndExtra = 0;
-    windowClass.hInstance = GetModuleHandle(NULL);
-    windowClass.hIcon = NULL;
-    windowClass.hCursor = LoadCursorA(NULL, IDC_ARROW);
-    windowClass.hbrBackground = 0;
-    windowClass.lpszMenuName = NULL;
-    windowClass.lpszClassName = mClassName.c_str();
-    if (!RegisterClassExA(&windowClass))
+    WNDCLASSEXA parentWindowClass = { 0 };
+    parentWindowClass.cbSize = sizeof(WNDCLASSEXA);
+    parentWindowClass.style = 0;
+    parentWindowClass.lpfnWndProc = WndProc;
+    parentWindowClass.cbClsExtra = 0;
+    parentWindowClass.cbWndExtra = 0;
+    parentWindowClass.hInstance = GetModuleHandle(NULL);
+    parentWindowClass.hIcon = NULL;
+    parentWindowClass.hCursor = LoadCursorA(NULL, IDC_ARROW);
+    parentWindowClass.hbrBackground = 0;
+    parentWindowClass.lpszMenuName = NULL;
+    parentWindowClass.lpszClassName = mParentClassName.c_str();
+    if (!RegisterClassExA(&parentWindowClass))
     {
         return false;
     }
 
-    DWORD style = WS_VISIBLE | WS_CAPTION | WS_MINIMIZEBOX | WS_THICKFRAME | WS_MAXIMIZEBOX | WS_SYSMENU;
-    DWORD extendedStyle = WS_EX_APPWINDOW;
+    WNDCLASSEXA childWindowClass = { 0 };
+    childWindowClass.cbSize = sizeof(WNDCLASSEXA);
+    childWindowClass.style = CS_OWNDC;
+    childWindowClass.lpfnWndProc = WndProc;
+    childWindowClass.cbClsExtra = 0;
+    childWindowClass.cbWndExtra = 0;
+    childWindowClass.hInstance = GetModuleHandle(NULL);
+    childWindowClass.hIcon = NULL;
+    childWindowClass.hCursor = LoadCursorA(NULL, IDC_ARROW);
+    childWindowClass.hbrBackground = 0;
+    childWindowClass.lpszMenuName = NULL;
+    childWindowClass.lpszClassName = mChildClassName.c_str();
+    if (!RegisterClassExA(&childWindowClass))
+    {
+        return false;
+    }
+
+    DWORD parentStyle = WS_VISIBLE | WS_CAPTION | WS_THICKFRAME | WS_MINIMIZEBOX | WS_MAXIMIZEBOX | WS_SYSMENU;
+    DWORD parentExtendedStyle = WS_EX_APPWINDOW;
 
     RECT sizeRect = { 0, 0, width, height };
-    AdjustWindowRectEx(&sizeRect, style, false, extendedStyle);
+    AdjustWindowRectEx(&sizeRect, parentStyle, FALSE, parentExtendedStyle);
 
-    mNativeWindow = CreateWindowExA(extendedStyle, mClassName.c_str(), name.c_str(), style, CW_USEDEFAULT, CW_USEDEFAULT,
+    mParentWindow = CreateWindowExA(parentExtendedStyle, mParentClassName.c_str(), name.c_str(), parentStyle, CW_USEDEFAULT, CW_USEDEFAULT,
                                     sizeRect.right - sizeRect.left, sizeRect.bottom - sizeRect.top, NULL, NULL,
                                     GetModuleHandle(NULL), this);
 
-    SetWindowLongPtrA(mNativeWindow, GWLP_USERDATA, reinterpret_cast<LONG>(this));
-
-    ShowWindow(mNativeWindow, SW_SHOW);
+    mNativeWindow = CreateWindowExA(0, mChildClassName.c_str(), name.c_str(), WS_VISIBLE | WS_CHILD, 0, 0, width, height,
+                                    mParentWindow, NULL, GetModuleHandle(NULL), this);
 
     mNativeDisplay = GetDC(mNativeWindow);
     if (!mNativeDisplay)
@@ -434,7 +451,14 @@
         mNativeWindow = 0;
     }
 
-    UnregisterClassA(mClassName.c_str(), NULL);
+    if (mParentWindow)
+    {
+        DestroyWindow(mParentWindow);
+        mParentWindow = 0;
+    }
+
+    UnregisterClassA(mParentClassName.c_str(), NULL);
+    UnregisterClassA(mChildClassName.c_str(), NULL);
 }
 
 EGLNativeWindowType Win32Window::getNativeWindow() const
@@ -469,3 +493,62 @@
 
     SetCursorPos(topLeft.x + x, topLeft.y + y);
 }
+
+OSWindow *CreateOSWindow()
+{
+    return new Win32Window();
+}
+
+bool Win32Window::resize(int width, int height)
+{
+    if (width == mWidth && height == mHeight)
+    {
+        return true;
+    }
+
+    RECT windowRect;
+    if (!GetWindowRect(mParentWindow, &windowRect))
+    {
+        return false;
+    }
+
+    RECT clientRect;
+    if (!GetClientRect(mParentWindow, &clientRect))
+    {
+        return false;
+    }
+
+    LONG diffX = (windowRect.right - windowRect.left) - clientRect.right;
+    LONG diffY = (windowRect.bottom - windowRect.top) - clientRect.bottom;
+    if (!MoveWindow(mParentWindow, windowRect.left, windowRect.top, width + diffX, height + diffY, FALSE))
+    {
+        return false;
+    }
+
+    if (!MoveWindow(mNativeWindow, 0, 0, width, height, FALSE))
+    {
+        return false;
+    }
+
+    return true;
+}
+
+bool Win32Window::setVisible(bool isVisible)
+{
+    int flag = (isVisible ? SW_SHOW : SW_HIDE);
+
+    return (ShowWindow(mNativeWindow, flag) == TRUE) &&
+           (ShowWindow(mParentWindow, flag) == TRUE);
+}
+
+void Win32Window::pushEvent(Event event)
+{
+    OSWindow::pushEvent(event);
+
+    switch (event.Type)
+    {
+      case Event::EVENT_RESIZED:
+        MoveWindow(mNativeWindow, 0, 0, mWidth, mHeight, FALSE);
+        break;
+    }
+}
diff --git a/samples/angle/sample_util/win32/Win32Window.h b/util/win32/Win32Window.h
similarity index 72%
rename from samples/angle/sample_util/win32/Win32Window.h
rename to util/win32/Win32Window.h
index 63d8c8d..7510f60 100644
--- a/samples/angle/sample_util/win32/Win32Window.h
+++ b/util/win32/Win32Window.h
@@ -7,11 +7,11 @@
 #ifndef SAMPLE_UTIL_WIN32_WINDOW_H
 #define SAMPLE_UTIL_WIN32_WINDOW_H
 
-#include "Window.h"
+#include "OSWindow.h"
 #include <string>
 #include <windows.h>
 
-class Win32Window : public Window
+class Win32Window : public OSWindow
 {
   public:
     Win32Window();
@@ -25,15 +25,18 @@
 
     void messageLoop();
 
-    bool popEvent(Event *event);
-    void pushEvent(Event event);
+    virtual void pushEvent(Event event);
 
     void setMousePosition(int x, int y);
+    bool resize(int width, int height);
+    bool setVisible(bool isVisible);
 
   private:
-    std::string mClassName;
+    std::string mParentClassName;
+    std::string mChildClassName;
 
     EGLNativeWindowType mNativeWindow;
+    EGLNativeWindowType mParentWindow;
     EGLNativeDisplayType mNativeDisplay;
 };
 
diff --git a/samples/angle/sample_util/win32/Win32_path_utils.cpp b/util/win32/Win32_path_utils.cpp
similarity index 100%
rename from samples/angle/sample_util/win32/Win32_path_utils.cpp
rename to util/win32/Win32_path_utils.cpp